Code

gtk-tpdfv-screen, tpdfview: Implemented "move window to next screen".
[tpdfview.git] / src / tpdfview.c
1 /*
2  * tpdfview - src/tpdfview.c
3  * Copyright (C) 2011 Sebastian 'tokkee' Harl <sh@tokkee.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
28 /*
29  * A tiny PDF viewer.
30  */
32 #if HAVE_CONFIG_H
33 #       include "config.h"
34 #endif /* HAVE_CONFIG_H */
36 #include "tpdfv.h"
37 #include "tpdfv_features.h"
39 #include "gtk-tpdfv.h"
41 #if HAVE_LIBGEN_H
42 #       include <libgen.h>
43 #else /* HAVE_LIBGEN_H */
44 #       define basename(path) (path)
45 #endif /* ! HAVE_LIBGEN_H */
47 #include <assert.h>
49 #include <stdio.h>
50 #include <stdlib.h>
52 #include <string.h>
54 #include <unistd.h>
56 #include <gtk/gtk.h>
57 #include <gdk/gdkkeysyms.h>
59 /*
60  * Global variables.
61  */
62 static gtk_tpdfv_screens_t *screens = NULL;
64 static void
65 exit_usage(char *name, int status)
66 {
67         printf(
68 "Usage: %s [<options>] <filename>\n"
70 "\nA tiny PDF viewer.\n"
72 "\nOptions:\n"
73 "  -h    display this help and exit\n"
74 "  -V    display the version number and copyright\n"
76 "\ntpdfview "TPDFV_VERSION_STRING TPDFV_VERSION_EXTRA", "PACKAGE_URL"\n"
77 "Copyright (C) 2011 "PACKAGE_MAINTAINER"\n",
78 basename(name));
79         exit(status);
80 } /* exit_usage */
82 static void
83 exit_version(void)
84 {
85         printf("tpdfview version "TPDFV_VERSION_STRING TPDFV_VERSION_EXTRA", "
86                         "built "BUILD_DATE"\n"
87                         "Copyright (C) 2011 "PACKAGE_MAINTAINER"\n"
89                         "\nThis is free software under the terms of the BSD license, see "
90                         "the source for\ncopying conditions. There is NO WARRANTY; not "
91                         "even for MERCHANTABILITY or\nFITNESS FOR A PARTICULAR "
92                         "PURPOSE.\n");
93         exit(0);
94 } /* exit_version */
96 static void
97 toggle_fullscreen(GtkWindow *win)
98 {
99         GdkWindowState state;
101         if (! gtk_widget_get_realized(GTK_WIDGET(win)))
102                 return;
104         state = gdk_window_get_state(GTK_WIDGET(win)->window);
106         if (state & GDK_WINDOW_STATE_FULLSCREEN)
107                 gtk_window_unfullscreen(win);
108         else
109                 gtk_window_fullscreen(win);
110 } /* toggle_fullscreen */
112 static void
113 on_destroy(GtkWidget __attribute__((unused)) *widget,
114                 gpointer __attribute__((unused)) data)
116         gtk_main_quit();
117 } /* on_destroy */
119 static gboolean
120 key_press(GtkWidget *window, GdkEventKey *event, gpointer data)
122         GtkWidget *tpdfv;
124         tpdfv = (GtkWidget *)data;
125         assert(tpdfv);
127         switch (event->keyval) {
128                 case GDK_q:
129                         gtk_main_quit();
130                         break;
132                 case GDK_r:
133                         gtk_tpdfv_reload(tpdfv);
134                         break;
136                 case GDK_F:
137                         toggle_fullscreen(GTK_WINDOW(window));
138                         break;
140                 /* navigation */
141                 case GDK_Page_Up:
142                         gtk_tpdfv_page_up(tpdfv);
143                         break;
144                 case GDK_Page_Down:
145                         /* fall through */
146                 case GDK_space:
147                         gtk_tpdfv_page_down(tpdfv);
148                         break;
149                 case GDK_Home:
150                         gtk_tpdfv_first_page(tpdfv);
151                         break;
152                 case GDK_End:
153                         gtk_tpdfv_last_page(tpdfv);
154                         break;
156                 /* zoom */
157                 case GDK_plus:
158                         gtk_tpdfv_zoom_in(tpdfv);
159                         break;
160                 case GDK_minus:
161                         gtk_tpdfv_zoom_out(tpdfv);
162                         break;
163                 case GDK_1:
164                         gtk_tpdfv_zoom_1(tpdfv);
165                         break;
166                 case GDK_w:
167                         gtk_tpdfv_zoom_width(tpdfv);
168                         break;
169                 case GDK_h:
170                         gtk_tpdfv_zoom_height(tpdfv);
171                         break;
172                 case GDK_z:
173                         gtk_tpdfv_zoom_fit(tpdfv);
174                         break;
176                 /* scrolling */
177                 case GDK_Up:
178                         gtk_tpdfv_scroll_up(tpdfv);
179                         break;
180                 case GDK_Down:
181                         gtk_tpdfv_scroll_down(tpdfv);
182                         break;
183                 case GDK_Left:
184                         gtk_tpdfv_scroll_left(tpdfv);
185                         break;
186                 case GDK_Right:
187                         gtk_tpdfv_scroll_right(tpdfv);
188                         break;
190                 /* screen management */
191                 case GDK_M:
192                         {
193                                 gint n_screens = gtk_tpdfv_screens_number(screens);
194                                 gint screen = gtk_tpdfv_screens_window_get(screens,
195                                                 GTK_WINDOW(window));
197                                 gtk_tpdfv_screens_window_set(screens,
198                                                 GTK_WINDOW(window), (screen + 1) % n_screens);
199                         }
200                         break;
201         }
202         return FALSE;
203 } /* key_press */
205 int
206 main(int argc, char **argv)
208         GtkWidget *win   = NULL;
209         GtkWidget *tpdfv = NULL;
211         char win_title[1024];
213         GdkColor bg_color;
215         char *filename;
217         gtk_init(&argc, &argv);
219         while (42) {
220                 int opt = getopt(argc, argv, "hV");
222                 if (-1 == opt)
223                         break;
225                 switch (opt) {
226                         case 'h':
227                                 exit_usage(argv[0], 0);
228                                 break;
229                         case 'V':
230                                 exit_version();
231                                 break;
232                         default:
233                                 exit_usage(argv[0], 1);
234                 }
235         }
237         if (argc - optind != 1) {
238                 fprintf(stderr, "%s: missing filename\n", argv[0]);
239                 exit_usage(argv[0], 1);
240         }
242         filename = argv[optind];
244         tpdfv = gtk_tpdfv_new(filename);
245         if (! tpdfv)
246                 return 1;
248         win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
249         if (! win)
250                 return 1;
252         screens = gtk_tpdfv_screens_init(/* display = */ NULL);
253         if (! screens)
254                 return 1;
256         snprintf(win_title, sizeof(win_title), "tpdfview: %s",
257                         basename(filename));
258         gtk_window_set_title(GTK_WINDOW(win), win_title);
260         gtk_container_add(GTK_CONTAINER(win), tpdfv);
262         g_signal_connect(G_OBJECT(win), "destroy",
263                         G_CALLBACK(on_destroy), NULL);
264         g_signal_connect(G_OBJECT(win), "key-press-event",
265                         G_CALLBACK(key_press), tpdfv);
267         /* TODO: use resource file */
268         gdk_color_parse("#000000", &bg_color);
269         gtk_widget_modify_bg(tpdfv, GTK_STATE_NORMAL, &bg_color);
271         gtk_widget_show_all(win);
273         gtk_main();
275         gtk_tpdfv_screens_destroy(screens);
276         return 0;
277 } /* main */
279 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */