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 static void
60 exit_usage(char *name, int status)
61 {
62 printf(
63 "Usage: %s [<options>] <filename>\n"
65 "\nA tiny PDF viewer.\n"
67 "\nOptions:\n"
68 " -h display this help and exit\n"
69 " -V display the version number and copyright\n"
71 "\ntpdfview "TPDFV_VERSION_STRING TPDFV_VERSION_EXTRA", "PACKAGE_URL"\n"
72 "Copyright (C) 2011 "PACKAGE_MAINTAINER"\n",
73 basename(name));
74 exit(status);
75 } /* exit_usage */
77 static void
78 exit_version(void)
79 {
80 printf("tpdfview version "TPDFV_VERSION_STRING TPDFV_VERSION_EXTRA", "
81 "built "BUILD_DATE"\n"
82 "Copyright (C) 2011 "PACKAGE_MAINTAINER"\n"
84 "\nThis is free software under the terms of the BSD license, see "
85 "the source for\ncopying conditions. There is NO WARRANTY; not "
86 "even for MERCHANTABILITY or\nFITNESS FOR A PARTICULAR "
87 "PURPOSE.\n");
88 exit(0);
89 } /* exit_version */
91 static void
92 toggle_fullscreen(GtkWindow *win)
93 {
94 GdkWindowState state;
96 if (! gtk_widget_get_realized(GTK_WIDGET(win)))
97 return;
99 state = gdk_window_get_state(GTK_WIDGET(win)->window);
101 if (state & GDK_WINDOW_STATE_FULLSCREEN)
102 gtk_window_unfullscreen(win);
103 else
104 gtk_window_fullscreen(win);
105 } /* toggle_fullscreen */
107 static void
108 on_destroy(GtkWidget __attribute__((unused)) *widget,
109 gpointer __attribute__((unused)) data)
110 {
111 gtk_main_quit();
112 } /* on_destroy */
114 static gboolean
115 key_press(GtkWidget *window, GdkEventKey *event, gpointer data)
116 {
117 GtkWidget *tpdfv;
119 tpdfv = (GtkWidget *)data;
120 assert(tpdfv);
122 switch (event->keyval) {
123 case GDK_q:
124 gtk_main_quit();
125 break;
127 case GDK_r:
128 gtk_tpdfv_reload(tpdfv);
129 break;
131 case GDK_F:
132 toggle_fullscreen(GTK_WINDOW(window));
133 break;
135 /* navigation */
136 case GDK_Page_Up:
137 gtk_tpdfv_page_up(tpdfv);
138 break;
139 case GDK_Page_Down:
140 /* fall through */
141 case GDK_space:
142 gtk_tpdfv_page_down(tpdfv);
143 break;
144 case GDK_Home:
145 gtk_tpdfv_first_page(tpdfv);
146 break;
147 case GDK_End:
148 gtk_tpdfv_last_page(tpdfv);
149 break;
151 /* zoom */
152 case GDK_plus:
153 gtk_tpdfv_zoom_in(tpdfv);
154 break;
155 case GDK_minus:
156 gtk_tpdfv_zoom_out(tpdfv);
157 break;
158 case GDK_1:
159 gtk_tpdfv_zoom_1(tpdfv);
160 break;
161 case GDK_w:
162 gtk_tpdfv_zoom_width(tpdfv);
163 break;
164 case GDK_h:
165 gtk_tpdfv_zoom_height(tpdfv);
166 break;
167 case GDK_z:
168 gtk_tpdfv_zoom_fit(tpdfv);
169 break;
171 /* scrolling */
172 case GDK_Up:
173 gtk_tpdfv_scroll_up(tpdfv);
174 break;
175 case GDK_Down:
176 gtk_tpdfv_scroll_down(tpdfv);
177 break;
178 case GDK_Left:
179 gtk_tpdfv_scroll_left(tpdfv);
180 break;
181 case GDK_Right:
182 gtk_tpdfv_scroll_right(tpdfv);
183 break;
184 }
185 return FALSE;
186 } /* key_press */
188 int
189 main(int argc, char **argv)
190 {
191 gtk_tpdfv_screens_t *screens;
193 GtkWidget *win = NULL;
194 GtkWidget *tpdfv = NULL;
196 char win_title[1024];
198 GdkColor bg_color;
200 char *filename;
202 gtk_init(&argc, &argv);
204 while (42) {
205 int opt = getopt(argc, argv, "hV");
207 if (-1 == opt)
208 break;
210 switch (opt) {
211 case 'h':
212 exit_usage(argv[0], 0);
213 break;
214 case 'V':
215 exit_version();
216 break;
217 default:
218 exit_usage(argv[0], 1);
219 }
220 }
222 if (argc - optind != 1) {
223 fprintf(stderr, "%s: missing filename\n", argv[0]);
224 exit_usage(argv[0], 1);
225 }
227 filename = argv[optind];
229 tpdfv = gtk_tpdfv_new(filename);
230 if (! tpdfv)
231 return 1;
233 win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
234 if (! win)
235 return 1;
237 screens = gtk_tpdfv_screens_init(/* display = */ NULL);
238 if (! screens)
239 return 1;
241 snprintf(win_title, sizeof(win_title), "tpdfview: %s",
242 basename(filename));
243 gtk_window_set_title(GTK_WINDOW(win), win_title);
245 gtk_container_add(GTK_CONTAINER(win), tpdfv);
247 g_signal_connect(G_OBJECT(win), "destroy",
248 G_CALLBACK(on_destroy), NULL);
249 g_signal_connect(G_OBJECT(win), "key-press-event",
250 G_CALLBACK(key_press), tpdfv);
252 /* TODO: use resource file */
253 gdk_color_parse("#000000", &bg_color);
254 gtk_widget_modify_bg(tpdfv, GTK_STATE_NORMAL, &bg_color);
256 gtk_widget_show_all(win);
258 gtk_main();
260 gtk_tpdfv_screens_destroy(screens);
261 return 0;
262 } /* main */
264 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */