X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Ftpdfview.c;h=e6fee214669f91edc7a8f68fa661d361229ef402;hb=08ed957073b68150244fb7cc40784b68f9126bad;hp=79532672c13154c95ee124869e017bbe64d68fa1;hpb=b58cebfbbe69015d48f646e806d29802114fa98c;p=tpdfview.git diff --git a/src/tpdfview.c b/src/tpdfview.c index 7953267..e6fee21 100644 --- a/src/tpdfview.c +++ b/src/tpdfview.c @@ -36,6 +36,8 @@ #include "tpdfv.h" #include "tpdfv_features.h" +#include "gtk-tpdfv.h" + #if HAVE_LIBGEN_H # include #else /* HAVE_LIBGEN_H */ @@ -44,8 +46,6 @@ #include -#include - #include #include @@ -53,81 +53,13 @@ #include -#include - #include #include -#include - -typedef struct { - char *filename; - - PopplerDocument *doc; - PopplerPage *current_page; - - int current_page_no; - int total_pages; - - double zoom_factor; - - double delta_x; - double delta_y; -} tpdfv_t; - -static tpdfv_t * -tpdfv_new(const char *filename) -{ - GError *err = NULL; - tpdfv_t *pdf; - - /* XXX: error reporting mechanism */ - - pdf = (tpdfv_t *)malloc(sizeof(*pdf)); - if (! pdf) { - fprintf(stderr, "Failed to allocate PDF object: %s.\n", - strerror(errno)); - return NULL; - } - - if (strstr(filename, "://")) - pdf->filename = strdup(filename); - else { - size_t len = strlen("file://") + strlen(filename); - pdf->filename = (char *)malloc(len + 1); - if (pdf->filename) { - *pdf->filename = '\0'; - strncat(pdf->filename, "file://", len); - strncat(pdf->filename, filename, len - strlen("file://")); - } - } - if (! pdf->filename) { - fprintf(stderr, "Failed to allocate string: %s.\n", - strerror(errno)); - return NULL; - } - - pdf->doc = poppler_document_new_from_file(pdf->filename, - /* password = */ NULL, &err); - if (! pdf->doc) { - fprintf(stderr, "Failed to open PDF: %s.\n", err->message); - return NULL; - } - - pdf->current_page_no = 0; - pdf->current_page = poppler_document_get_page(pdf->doc, - pdf->current_page_no); - if (! pdf->current_page) { - fprintf(stderr, "Failed to open first page of the document.\n"); - return NULL; - } - - pdf->total_pages = poppler_document_get_n_pages(pdf->doc); - - pdf->zoom_factor = 1.0; - pdf->delta_x = pdf->delta_y = 0.0; - return pdf; -} /* tpdfv_new */ +/* + * Global variables. + */ +static gtk_tpdfv_screens_t *screens = NULL; static void exit_usage(char *name, int status) @@ -162,16 +94,20 @@ exit_version(void) } /* exit_version */ static void -win_redraw(GtkWidget *widget) +toggle_fullscreen(GtkWindow *win) { - GdkRegion *region; + GdkWindowState state; + + if (! gtk_widget_get_realized(GTK_WIDGET(win))) + return; - region = gdk_drawable_get_clip_region(widget->window); - gdk_window_invalidate_region(widget->window, region, TRUE); - gdk_window_process_updates(widget->window, TRUE); + state = gdk_window_get_state(GTK_WIDGET(win)->window); - gdk_region_destroy(region); -} /* win_redraw */ + if (state & GDK_WINDOW_STATE_FULLSCREEN) + gtk_window_unfullscreen(win); + else + gtk_window_fullscreen(win); +} /* toggle_fullscreen */ static void on_destroy(GtkWidget __attribute__((unused)) *widget, @@ -181,118 +117,102 @@ on_destroy(GtkWidget __attribute__((unused)) *widget, } /* on_destroy */ static gboolean -on_expose(GtkWidget *widget, GdkEventExpose __attribute__((unused)) *event, - gpointer data) -{ - cairo_t *cr; - - tpdfv_t *pdf = (tpdfv_t *)data; - assert(data); - - cr = gdk_cairo_create(widget->window); - - /* zoom */ - cairo_scale(cr, pdf->zoom_factor, pdf->zoom_factor); - cairo_translate(cr, pdf->delta_x, pdf->delta_y); - - poppler_page_render(pdf->current_page, cr); - cairo_destroy(cr); - return FALSE; -} /* on_expose */ - -static gboolean -key_press(GtkWidget __attribute__((unused)) *widget, - GdkEventKey *event, gpointer data) +key_press(GtkWidget *window, GdkEventKey *event, gpointer data) { - tpdfv_t *pdf = (tpdfv_t *)data; - - int old_page_no; - _Bool do_redraw = 0; + GtkWidget *tpdfv; - assert(data); - - old_page_no = pdf->current_page_no; + tpdfv = (GtkWidget *)data; + assert(tpdfv); switch (event->keyval) { case GDK_q: gtk_main_quit(); break; + case GDK_r: + gtk_tpdfv_reload(tpdfv); + break; + + case GDK_F: + toggle_fullscreen(GTK_WINDOW(window)); + break; + /* navigation */ case GDK_Page_Up: - if (pdf->current_page_no) { - --pdf->current_page_no; - } + gtk_tpdfv_page_up(tpdfv); break; case GDK_Page_Down: /* fall through */ case GDK_space: - if (pdf->current_page_no < pdf->total_pages - 1) { - ++pdf->current_page_no; - } + gtk_tpdfv_page_down(tpdfv); break; case GDK_Home: - pdf->current_page_no = 0; + gtk_tpdfv_first_page(tpdfv); break; case GDK_End: - pdf->current_page_no = pdf->total_pages - 1; + gtk_tpdfv_last_page(tpdfv); break; /* zoom */ case GDK_plus: - pdf->zoom_factor *= 1.2; - do_redraw = 1; + gtk_tpdfv_zoom_in(tpdfv); break; case GDK_minus: - if (pdf->zoom_factor > DBL_EPSILON * 2.0) { - pdf->zoom_factor *= 1.0 / 1.2; - do_redraw = 1; - } + gtk_tpdfv_zoom_out(tpdfv); break; case GDK_1: - pdf->zoom_factor = 1.0; - do_redraw = 1; + gtk_tpdfv_zoom_1(tpdfv); + break; + case GDK_w: + gtk_tpdfv_zoom_width(tpdfv); + break; + case GDK_h: + gtk_tpdfv_zoom_height(tpdfv); + break; + case GDK_z: + gtk_tpdfv_zoom_fit(tpdfv); break; /* scrolling */ case GDK_Up: - pdf->delta_y += 10.0; - do_redraw = 1; + gtk_tpdfv_scroll_up(tpdfv); break; case GDK_Down: - pdf->delta_y -= 10.0; - do_redraw = 1; + gtk_tpdfv_scroll_down(tpdfv); break; case GDK_Left: - pdf->delta_x += 10.0; - do_redraw = 1; + gtk_tpdfv_scroll_left(tpdfv); break; case GDK_Right: - pdf->delta_x -= 10.0; - do_redraw = 1; + gtk_tpdfv_scroll_right(tpdfv); break; - } - if (old_page_no != pdf->current_page_no) { - pdf->current_page = poppler_document_get_page(pdf->doc, - pdf->current_page_no); - if (! pdf->current_page) - fprintf(stderr, "Failed to open page %i of the document.\n", - pdf->current_page_no + 1); - else - do_redraw = 1; - } + /* screen management */ + case GDK_M: + { + gint n_screens = gtk_tpdfv_screens_number(screens); + gint screen = gtk_tpdfv_screens_window_get(screens, + GTK_WINDOW(window)); - if (do_redraw) - win_redraw(widget); + gtk_tpdfv_screens_window_set(screens, + GTK_WINDOW(window), (screen + 1) % n_screens); + } + break; + } return FALSE; } /* key_press */ int main(int argc, char **argv) { - GtkWidget *win = NULL; - tpdfv_t *pdf = NULL; + GtkWidget *win = NULL; + GtkWidget *tpdfv = NULL; + + char win_title[1024]; + + GdkColor bg_color; + + char *filename; gtk_init(&argc, &argv); @@ -319,21 +239,40 @@ main(int argc, char **argv) exit_usage(argv[0], 1); } - pdf = tpdfv_new(/* filename = */ argv[optind]); - if (! pdf) + filename = argv[optind]; + + tpdfv = gtk_tpdfv_new(filename); + if (! tpdfv) return 1; win = gtk_window_new(GTK_WINDOW_TOPLEVEL); + if (! win) + return 1; + + screens = gtk_tpdfv_screens_init(/* display = */ NULL); + if (! screens) + return 1; + + snprintf(win_title, sizeof(win_title), "tpdfview: %s", + basename(filename)); + gtk_window_set_title(GTK_WINDOW(win), win_title); + + gtk_container_add(GTK_CONTAINER(win), tpdfv); + g_signal_connect(G_OBJECT(win), "destroy", G_CALLBACK(on_destroy), NULL); - g_signal_connect(G_OBJECT(win), "expose-event", - G_CALLBACK(on_expose), pdf); g_signal_connect(G_OBJECT(win), "key-press-event", - G_CALLBACK(key_press), pdf); - gtk_widget_set_app_paintable(win, TRUE); + G_CALLBACK(key_press), tpdfv); + + /* TODO: use resource file */ + gdk_color_parse("#000000", &bg_color); + gtk_widget_modify_bg(tpdfv, GTK_STATE_NORMAL, &bg_color); + gtk_widget_show_all(win); gtk_main(); + + gtk_tpdfv_screens_destroy(screens); return 0; } /* main */