summaryrefslogtreecommitdiff
path: root/platform/gl/gl-main.c
diff options
context:
space:
mode:
Diffstat (limited to 'platform/gl/gl-main.c')
-rw-r--r--platform/gl/gl-main.c357
1 files changed, 198 insertions, 159 deletions
diff --git a/platform/gl/gl-main.c b/platform/gl/gl-main.c
index 5fc8d9b2..58b19d87 100644
--- a/platform/gl/gl-main.c
+++ b/platform/gl/gl-main.c
@@ -27,22 +27,15 @@ enum
DEFAULT_UI_LINEHEIGHT = 18,
};
-#define DEFAULT_WINDOW_W (612 * currentzoom / 72)
-#define DEFAULT_WINDOW_H (792 * currentzoom / 72)
-
struct ui ui;
fz_context *ctx = NULL;
-GLFWwindow *window = NULL;
/* OpenGL capabilities */
static int has_ARB_texture_non_power_of_two = 1;
static GLint max_texture_size = 8192;
-static int ui_needs_update = 0;
-
static void ui_begin(void)
{
- ui_needs_update = 0;
ui.hot = NULL;
}
@@ -50,8 +43,6 @@ static void ui_end(void)
{
if (!ui.down && !ui.middle && !ui.right)
ui.active = NULL;
- if (ui_needs_update)
- glfwPostEmptyEvent();
}
static void open_browser(const char *uri)
@@ -159,7 +150,6 @@ static float layout_em = DEFAULT_LAYOUT_EM;
static char *layout_css = NULL;
static int layout_use_doc_css = 1;
-static const char *fix_title = "MuPDFGL";
static const char *title = "MuPDF/GL";
static fz_document *doc = NULL;
static fz_page *page = NULL;
@@ -177,7 +167,6 @@ static int canvas_y = 0, canvas_h = 100;
static struct texture annot_tex[256];
static int annot_count = 0;
-static int screen_w = 1280, screen_h = 720;
static int window_w = 1, window_h = 1;
static int oldinvert = 0, currentinvert = 0;
@@ -185,6 +174,7 @@ static int oldpage = 0, currentpage = 0;
static float oldzoom = DEFRES, currentzoom = DEFRES;
static float oldrotate = 0, currentrotate = 0;
static fz_matrix page_ctm, page_inv_ctm;
+static int loaded = 0;
static int isfullscreen = 0;
static int showoutline = 0;
@@ -192,6 +182,7 @@ static int showlinks = 0;
static int showsearch = 0;
static int showinfo = 0;
static int showhelp = 0;
+static int doquit = 0;
struct mark
{
@@ -233,7 +224,8 @@ static void update_title(void)
sprintf(buf, "...%s - %d / %d", title + n - 50, currentpage + 1, fz_count_pages(ctx, doc));
else
sprintf(buf, "%s - %d / %d", title, currentpage + 1, fz_count_pages(ctx, doc));
- glfwSetWindowTitle(window, buf);
+ glutSetWindowTitle(buf);
+ glutSetIconTitle(buf);
}
void texture_from_pixmap(struct texture *tex, fz_pixmap *pix)
@@ -272,10 +264,10 @@ void texture_from_pixmap(struct texture *tex, fz_pixmap *pix)
}
}
-void render_page(void)
+void load_page(void)
{
- fz_annot *annot;
- fz_pixmap *pix;
+ fz_rect rect;
+ fz_irect irect;
fz_scale(&page_ctm, currentzoom / 72, currentzoom / 72);
fz_pre_rotate(&page_ctm, -currentrotate);
@@ -285,16 +277,35 @@ void render_page(void)
page = fz_load_page(ctx, doc, currentpage);
+ /* compute bounds here for initial window size */
+ fz_bound_page(ctx, page, &rect);
+ fz_transform_rect(&rect, &page_ctm);
+ fz_round_rect(&irect, &rect);
+ page_tex.w = irect.x1 - irect.x0;
+ page_tex.h = irect.y1 - irect.y0;
+
fz_drop_link(ctx, links);
links = NULL;
links = fz_load_links(ctx, page);
+ loaded = 1;
+}
+
+void render_page(void)
+{
+ fz_annot *annot;
+ fz_pixmap *pix;
+
+ if (!loaded)
+ load_page();
+
pix = fz_new_pixmap_from_page_contents(ctx, page, &page_ctm, fz_device_rgb(ctx), 0);
if (currentinvert)
{
fz_invert_pixmap(ctx, pix);
fz_gamma_pixmap(ctx, pix, 1 / 1.4f);
}
+
texture_from_pixmap(&page_tex, pix);
fz_drop_pixmap(ctx, pix);
@@ -310,6 +321,8 @@ void render_page(void)
break;
}
}
+
+ loaded = 0;
}
static struct mark save_mark()
@@ -420,7 +433,7 @@ static void do_copy_region(fz_rect *screen_sel, int xofs, int yofs)
#else
buf = fz_new_buffer_from_page(ctx, page, &page_sel, 0, NULL);
#endif
- glfwSetClipboardString(window, fz_string_from_buffer(ctx, buf));
+ ui_set_clipboard(fz_string_from_buffer(ctx, buf));
fz_drop_buffer(ctx, buf);
}
@@ -527,7 +540,7 @@ static int do_outline_imp(fz_outline *node, int end, int x0, int x1, int x, int
{
ui.active = node;
jump_to_page_xy(p, node->x, node->y);
- ui_needs_update = 1; /* we changed the current page, so force a redraw */
+ glutPostRedisplay(); /* we changed the current page, so force a redraw */
}
}
@@ -649,7 +662,7 @@ static void do_links(fz_link *link, int xofs, int yofs)
jump_to_page_xy(p, link_x, link_y);
else
fz_warn(ctx, "cannot find link destination '%s'", link->uri);
- ui_needs_update = 1;
+ glutPostRedisplay(); /* we changed the current page, so force a redraw */
}
}
}
@@ -692,7 +705,7 @@ static void do_page_selection(int x0, int y0, int x1, int y1)
if (ui.active == &sel && !ui.right)
{
do_copy_region(&sel, x0, y0);
- ui_needs_update = 1;
+ glutPostRedisplay();
}
}
@@ -748,7 +761,7 @@ static void do_forms(float xofs, float yofs)
ui.active = &do_forms_tag;
pdf_update_page(ctx, (pdf_page*)page);
render_page();
- ui_needs_update = 1;
+ glutPostRedisplay();
}
}
else if (ui.active == &do_forms_tag && !ui.down)
@@ -761,43 +774,48 @@ static void do_forms(float xofs, float yofs)
{
pdf_update_page(ctx, (pdf_page*)page);
render_page();
- ui_needs_update = 1;
+ glutPostRedisplay();
}
}
}
static void toggle_fullscreen(void)
{
- GLFWmonitor *monitor = glfwGetPrimaryMonitor();
static int win_x = 0, win_y = 0;
static int win_w = 100, win_h = 100;
- static int win_rr = 60;
if (!isfullscreen)
{
- const GLFWvidmode *mode = glfwGetVideoMode(monitor);
- glfwGetWindowPos(window, &win_x, &win_y);
- glfwGetWindowSize(window, &win_w, &win_h);
- win_rr = mode->refreshRate;
- glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
+ win_w = glutGet(GLUT_WINDOW_WIDTH);
+ win_h = glutGet(GLUT_WINDOW_HEIGHT);
+ win_x = glutGet(GLUT_WINDOW_X);
+ win_y = glutGet(GLUT_WINDOW_Y);
+ glutFullScreen();
isfullscreen = 1;
}
else
{
- glfwSetWindowMonitor(window, NULL, win_x, win_y, win_w, win_h, win_rr);
+ glutPositionWindow(win_x, win_y);
+ glutReshapeWindow(win_w, win_h);
isfullscreen = 0;
}
}
static void shrinkwrap(void)
{
- int w = fz_mini(page_tex.w + canvas_x, screen_w - SCREEN_FURNITURE_W);
- int h = fz_mini(page_tex.h + canvas_y, screen_h - SCREEN_FURNITURE_H);
+ int screen_w = glutGet(GLUT_SCREEN_WIDTH) - SCREEN_FURNITURE_W;
+ int screen_h = glutGet(GLUT_SCREEN_HEIGHT) - SCREEN_FURNITURE_H;
+ int w = page_tex.w + canvas_x;
+ int h = page_tex.h + canvas_y;
+ if (screen_w > 0 && w > screen_w)
+ w = screen_w;
+ if (screen_h > 0 && h > screen_h)
+ h = screen_h;
if (isfullscreen)
toggle_fullscreen();
- glfwSetWindowSize(window, w, h);
+ glutReshapeWindow(w, h);
}
-static void reload(void)
+static void load_document(void)
{
fz_drop_outline(ctx, outline);
fz_drop_document(ctx, doc);
@@ -834,7 +852,11 @@ static void reload(void)
anchor = NULL;
currentpage = fz_clampi(currentpage, 0, fz_count_pages(ctx, doc) - 1);
+}
+static void reload(void)
+{
+ load_document();
render_page();
update_title();
}
@@ -925,18 +947,18 @@ static void smart_move_forward(void)
static void quit(void)
{
- glfwSetWindowShouldClose(window, 1);
+ doquit = 1;
}
static void do_app(void)
{
- if (ui.key == KEY_F4 && ui.mod == GLFW_MOD_ALT)
+ if (ui.key == KEY_F4 && ui.mod == GLUT_ACTIVE_ALT)
quit();
if (ui.down || ui.middle || ui.right || ui.key)
showinfo = showhelp = 0;
- if (!ui.focus && ui.key)
+ if (!ui.focus && ui.key && ui.plain)
{
switch (ui.key)
{
@@ -1023,6 +1045,7 @@ static void do_app(void)
if (search_needle)
search_active = 1;
}
+ glutPostRedisplay();
break;
case 'n':
search_dir = 1;
@@ -1036,6 +1059,7 @@ static void do_app(void)
if (search_needle)
search_active = 1;
}
+ glutPostRedisplay();
break;
}
@@ -1052,8 +1076,6 @@ static void do_app(void)
if (search_hit_page != currentpage)
search_hit_page = -1; /* clear highlights when navigating */
- ui_needs_update = 1;
-
ui.key = 0; /* we ate the key event, so zap it */
}
}
@@ -1282,16 +1304,16 @@ static void run_main_loop(void)
if (search_active)
{
- float start_time = glfwGetTime();
+ int start_time = glutGet(GLUT_ELAPSED_TIME);
if (ui.key == KEY_ESCAPE)
search_active = 0;
/* ignore events during search */
- ui.key = ui.mod = 0;
+ ui.key = ui.mod = ui.plain = 0;
ui.down = ui.middle = ui.right = 0;
- while (glfwGetTime() < start_time + 0.2f)
+ while (glutGet(GLUT_ELAPSED_TIME) < start_time + 200)
{
search_hit_count = fz_search_page_number(ctx, doc, search_page, search_needle,
search_hit_bbox, nelem(search_hit_bbox));
@@ -1315,7 +1337,7 @@ static void run_main_loop(void)
/* keep searching later */
if (search_active)
- ui_needs_update = 1;
+ glutPostRedisplay();
}
do_app();
@@ -1340,6 +1362,7 @@ static void run_main_loop(void)
{
ui.focus = NULL;
showsearch = 0;
+ glutPostRedisplay();
}
else if (state == 1)
{
@@ -1357,8 +1380,8 @@ static void run_main_loop(void)
search_active = 1;
search_page = currentpage;
}
+ glutPostRedisplay();
}
- ui_needs_update = 1;
}
if (search_active)
@@ -1370,117 +1393,141 @@ static void run_main_loop(void)
ui_end();
- glfwSwapBuffers(window);
+ glutSwapBuffers();
ogl_assert(ctx, "swap buffers");
}
-static void on_char(GLFWwindow *window, unsigned int key, int mod)
+static void on_keyboard_ext(int key, int x, int y)
{
ui.key = key;
- ui.mod = mod;
+ ui.mod = glutGetModifiers();
+ ui.plain = !(ui.mod & ~GLUT_ACTIVE_SHIFT);
run_main_loop();
- ui.key = ui.mod = 0;
+ ui.key = ui.mod = ui.plain = 0;
}
-static void on_key(GLFWwindow *window, int special, int scan, int action, int mod)
+#if GLUT_API_VERSION < 5
+static void on_keyboard(unsigned char key, int x, int y)
{
- if (action == GLFW_PRESS || action == GLFW_REPEAT)
+ on_keyboard_ext(key, x, y);
+}
+#endif
+
+static void on_special(int key, int x, int y)
+{
+ ui.key = 0;
+
+ switch (key)
{
- ui.key = 0;
- switch (special)
- {
-#ifndef GLFW_MUPDF_FIXES
- /* regular control characters: ^A, ^B, etc. */
- default:
- if (special >= 'A' && special <= 'Z' && mod == GLFW_MOD_CONTROL)
- ui.key = KEY_CTL_A + special - 'A';
- break;
+ case GLUT_KEY_INSERT: ui.key = KEY_INSERT; break;
+ case GLUT_KEY_DELETE: ui.key = KEY_DELETE; break;
+ case GLUT_KEY_RIGHT: ui.key = KEY_RIGHT; break;
+ case GLUT_KEY_LEFT: ui.key = KEY_LEFT; break;
+ case GLUT_KEY_DOWN: ui.key = KEY_DOWN; break;
+ case GLUT_KEY_UP: ui.key = KEY_UP; break;
+ case GLUT_KEY_PAGE_UP: ui.key = KEY_PAGE_UP; break;
+ case GLUT_KEY_PAGE_DOWN: ui.key = KEY_PAGE_DOWN; break;
+ case GLUT_KEY_HOME: ui.key = KEY_HOME; break;
+ case GLUT_KEY_END: ui.key = KEY_END; break;
+ case GLUT_KEY_F1: ui.key = KEY_F1; break;
+ case GLUT_KEY_F2: ui.key = KEY_F2; break;
+ case GLUT_KEY_F3: ui.key = KEY_F3; break;
+ case GLUT_KEY_F4: ui.key = KEY_F4; break;
+ case GLUT_KEY_F5: ui.key = KEY_F5; break;
+ case GLUT_KEY_F6: ui.key = KEY_F6; break;
+ case GLUT_KEY_F7: ui.key = KEY_F7; break;
+ case GLUT_KEY_F8: ui.key = KEY_F8; break;
+ case GLUT_KEY_F9: ui.key = KEY_F9; break;
+ case GLUT_KEY_F10: ui.key = KEY_F10; break;
+ case GLUT_KEY_F11: ui.key = KEY_F11; break;
+ case GLUT_KEY_F12: ui.key = KEY_F12; break;
+ }
- /* regular control characters: escape, enter, backspace, tab */
- case GLFW_KEY_ESCAPE: ui.key = KEY_ESCAPE; break;
- case GLFW_KEY_ENTER: ui.key = KEY_ENTER; break;
- case GLFW_KEY_BACKSPACE: ui.key = KEY_BACKSPACE; break;
- case GLFW_KEY_TAB: ui.key = KEY_TAB; break;
-#endif
- case GLFW_KEY_INSERT: ui.key = KEY_INSERT; break;
- case GLFW_KEY_DELETE: ui.key = KEY_DELETE; break;
- case GLFW_KEY_RIGHT: ui.key = KEY_RIGHT; break;
- case GLFW_KEY_LEFT: ui.key = KEY_LEFT; break;
- case GLFW_KEY_DOWN: ui.key = KEY_DOWN; break;
- case GLFW_KEY_UP: ui.key = KEY_UP; break;
- case GLFW_KEY_PAGE_UP: ui.key = KEY_PAGE_UP; break;
- case GLFW_KEY_PAGE_DOWN: ui.key = KEY_PAGE_DOWN; break;
- case GLFW_KEY_HOME: ui.key = KEY_HOME; break;
- case GLFW_KEY_END: ui.key = KEY_END; break;
- case GLFW_KEY_F1: ui.key = KEY_F1; break;
- case GLFW_KEY_F2: ui.key = KEY_F2; break;
- case GLFW_KEY_F3: ui.key = KEY_F3; break;
- case GLFW_KEY_F4: ui.key = KEY_F4; break;
- case GLFW_KEY_F5: ui.key = KEY_F5; break;
- case GLFW_KEY_F6: ui.key = KEY_F6; break;
- case GLFW_KEY_F7: ui.key = KEY_F7; break;
- case GLFW_KEY_F8: ui.key = KEY_F8; break;
- case GLFW_KEY_F9: ui.key = KEY_F9; break;
- case GLFW_KEY_F10: ui.key = KEY_F10; break;
- case GLFW_KEY_F11: ui.key = KEY_F11; break;
- case GLFW_KEY_F12: ui.key = KEY_F12; break;
- }
- if (ui.key)
- {
- ui.mod = mod;
- run_main_loop();
- ui.key = ui.mod = 0;
- }
+ if (ui.key)
+ {
+ ui.mod = glutGetModifiers();
+ ui.plain = !(ui.mod & ~GLUT_ACTIVE_SHIFT);
+ run_main_loop();
+ ui.key = ui.mod = ui.plain = 0;
}
}
-static void on_mouse_button(GLFWwindow *window, int button, int action, int mod)
+static void on_mouse(int button, int action, int x, int y)
{
+ ui.x = x;
+ ui.y = y;
switch (button)
{
- case GLFW_MOUSE_BUTTON_LEFT: ui.down = (action == GLFW_PRESS); break;
- case GLFW_MOUSE_BUTTON_MIDDLE: ui.middle = (action == GLFW_PRESS); break;
- case GLFW_MOUSE_BUTTON_RIGHT: ui.right = (action == GLFW_PRESS); break;
+ case GLUT_LEFT_BUTTON: ui.down = (action == GLUT_DOWN); break;
+ case GLUT_MIDDLE_BUTTON: ui.middle = (action == GLUT_DOWN); break;
+ case GLUT_RIGHT_BUTTON: ui.right = (action == GLUT_DOWN); break;
}
-
run_main_loop();
}
-static void on_mouse_motion(GLFWwindow *window, double x, double y)
+static void on_motion(int x, int y)
{
ui.x = x;
ui.y = y;
- ui_needs_update = 1;
+ glutPostRedisplay();
}
-static void on_scroll(GLFWwindow *window, double x, double y)
+static void on_wheel(int wheel, int direction, int x, int y)
{
- ui.scroll_x = x;
- ui.scroll_y = y;
+ ui.scroll_x = wheel == 1 ? direction * 10 : 0;
+ ui.scroll_y = wheel == 0 ? direction * 10 : 0;
run_main_loop();
ui.scroll_x = ui.scroll_y = 0;
}
-static void on_reshape(GLFWwindow *window, int w, int h)
+static void on_reshape(int w, int h)
{
showinfo = 0;
+ showhelp = 0;
window_w = w;
window_h = h;
- ui_needs_update = 1;
}
-static void on_display(GLFWwindow *window)
+static void on_display(void)
{
- ui_needs_update = 1;
+ run_main_loop();
}
-static void on_error(int error, const char *msg)
+static void on_error(const char *fmt, va_list ap)
{
#ifdef _WIN32
- MessageBoxA(NULL, msg, "MuPDF GLFW Error", MB_ICONERROR);
+ char buf[1000];
+ fz_vsnprintf(buf, sizeof buf, fmt, ap);
+ MessageBoxA(NULL, buf, "MuPDF GLUT Error", MB_ICONERROR);
#else
- fprintf(stderr, "gl error %d: %s\n", error, msg);
+ fprintf(stderr, "GLUT error: ");
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+#endif
+}
+
+static void on_warning(const char *fmt, va_list ap)
+{
+ fprintf(stderr, "GLUT warning: ");
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+}
+
+// TODO: use native win32/x11 to get/set clipboard
+void ui_set_clipboard(const char *buf)
+{
+#if GLUT_API_VERSION >= 5
+ glutSetClipboard(GLUT_CLIPBOARD, buf);
+#endif
+}
+
+const char *ui_get_clipboard(void)
+{
+#if GLUT_API_VERSION >= 5
+ return glutGetClipboard(GLUT_CLIPBOARD);
+#else
+ return NULL;
#endif
}
@@ -1505,9 +1552,9 @@ int main_utf8(int argc, char **argv)
int main(int argc, char **argv)
#endif
{
- const GLFWvidmode *video_mode;
int c;
+ glutInit(&argc, argv);
while ((c = fz_getopt(argc, argv, "p:r:IW:H:S:U:X")) != -1)
{
switch (c)
@@ -1550,30 +1597,7 @@ int main(int argc, char **argv)
else
title = filename;
- memset(&ui, 0, sizeof ui);
-
- search_input.p = search_input.text;
- search_input.q = search_input.p;
- search_input.end = search_input.p;
-
- glfwSetErrorCallback(on_error);
-
- if (!glfwInit()) {
- fprintf(stderr, "cannot initialize glfw\n");
- exit(1);
- }
-
- video_mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
- screen_w = video_mode->width;
- screen_h = video_mode->height;
-
- window = glfwCreateWindow(DEFAULT_WINDOW_W, DEFAULT_WINDOW_H, fix_title, NULL, NULL);
- if (!window) {
- fprintf(stderr, "cannot create glfw window\n");
- exit(1);
- }
-
- glfwMakeContextCurrent(window);
+ /* Init MuPDF */
ctx = fz_new_context(NULL, NULL, 0);
fz_register_document_handlers(ctx);
@@ -1587,7 +1611,39 @@ int main(int argc, char **argv)
fz_set_use_document_css(ctx, layout_use_doc_css);
- has_ARB_texture_non_power_of_two = glfwExtensionSupported("GL_ARB_texture_non_power_of_two");
+ load_document();
+ load_page();
+
+ /* Init IMGUI */
+
+ memset(&ui, 0, sizeof ui);
+
+ search_input.p = search_input.text;
+ search_input.q = search_input.p;
+ search_input.end = search_input.p;
+
+ /* Init GLUT */
+
+ glutInitErrorFunc(on_error);
+ glutInitWarningFunc(on_warning);
+ glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
+ glutInitWindowSize(page_tex.w, page_tex.h);
+ glutCreateWindow(title);
+
+ glutReshapeFunc(on_reshape);
+ glutDisplayFunc(on_display);
+#if GLUT_API_VERSION >= 5
+ glutKeyboardExtFunc(on_keyboard_ext);
+#else
+ glutKeyboardFunc(on_keyboard);
+#endif
+ glutSpecialFunc(on_special);
+ glutMouseFunc(on_mouse);
+ glutMotionFunc(on_motion);
+ glutPassiveMotionFunc(on_motion);
+ glutMouseWheelFunc(on_wheel);
+
+ has_ARB_texture_non_power_of_two = glutExtensionSupported("GL_ARB_texture_non_power_of_two");
if (!has_ARB_texture_non_power_of_two)
fz_warn(ctx, "OpenGL implementation does not support non-power of two texture sizes");
@@ -1599,31 +1655,16 @@ int main(int argc, char **argv)
ui_init_fonts(ctx, ui.fontsize);
- reload();
-
- shrinkwrap();
-
- glfwSetFramebufferSizeCallback(window, on_reshape);
- glfwSetCursorPosCallback(window, on_mouse_motion);
- glfwSetMouseButtonCallback(window, on_mouse_button);
- glfwSetScrollCallback(window, on_scroll);
- glfwSetCharModsCallback(window, on_char);
- glfwSetKeyCallback(window, on_key);
- glfwSetWindowRefreshCallback(window, on_display);
-
- glfwGetFramebufferSize(window, &window_w, &window_h);
-
- ui_needs_update = 1;
+ render_page();
+ update_title();
- while (!glfwWindowShouldClose(window))
- {
- glfwWaitEvents();
- if (ui_needs_update)
- run_main_loop();
- }
+ while (!doquit)
+ glutMainLoopEvent();
ui_finish_fonts(ctx);
+ glutExit();
+
#ifndef NDEBUG
if (fz_atoi(getenv("FZ_DEBUG_STORE")))
fz_debug_store(ctx);
@@ -1635,8 +1676,6 @@ int main(int argc, char **argv)
fz_drop_document(ctx, doc);
fz_drop_context(ctx);
- glfwTerminate();
-
return 0;
}