]> www.fi.muni.cz Git - evince.git/blob - shell/main.c
64b86dfa05c99826021289017183c736ece12df4
[evince.git] / shell / main.c
1 /*
2  *  Copyright (C) 2004 Marco Pesenti Gritti
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2, or (at your option)
7  *  any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  *
18  */
19
20 #include "config.h"
21
22 #include "ev-application.h"
23 #include "ev-metadata-manager.h"
24
25 #include <glib/gi18n.h>
26 #include <gdk/gdkx.h>
27 #include <gtk/gtkmain.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #if WITH_GNOME
32 #include <libgnome/gnome-program.h>
33 #include <libgnomeui/gnome-ui-init.h>
34 #include <libgnomeui/gnome-app-helper.h>
35 #include <libgnomeui/gnome-authentication-manager.h>
36 #endif
37
38 #include <libgnomevfs/gnome-vfs-init.h>
39 #include <libgnomevfs/gnome-vfs-utils.h>
40
41 #ifdef ENABLE_DBUS
42 #include <dbus/dbus-glib-bindings.h>
43 #endif
44
45 #include "ev-stock-icons.h"
46 #include "ev-job-queue.h"
47 #include "ev-file-helpers.h"
48
49 static gchar   *ev_page_label;
50 static gboolean preview_mode = FALSE;
51 static gboolean fullscren_mode = FALSE;
52 static gboolean presentation_mode = FALSE;
53 static gboolean unlink_temp_file = FALSE;
54 static const char **file_arguments = NULL;
55
56 static const GOptionEntry goption_options[] =
57 {
58         { "page-label", 'p', 0, G_OPTION_ARG_STRING, &ev_page_label, N_("The page of the document to display."), N_("PAGE")},
59         { "fullscreen", 'f', 0, G_OPTION_ARG_NONE, &fullscren_mode, N_("Run evince in fullscreen mode"), NULL },
60         { "presentation", 's', 0, G_OPTION_ARG_NONE, &presentation_mode, N_("Run evince in presentation mode"), NULL },
61         { "preview", 'w', 0, G_OPTION_ARG_NONE, &preview_mode, N_("Run evince as a previewer"), NULL },
62         { "unlink-tempfile", 'u', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &unlink_temp_file, NULL, NULL },
63         { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &file_arguments, NULL, N_("[FILE...]") },
64         { NULL }
65 };
66
67 static void
68 value_free (GValue *value)
69 {
70         g_value_unset (value);
71         g_free (value);
72 }
73
74 /**
75  * arguments_parse:
76  *
77  * Parses the arguments and creates a #GHashTable with this data.
78  *
79  *  key                 ->  value
80  *
81  *  dislay              ->  display at the default screen.
82  *  screen              ->  screen number.
83  *  page-label          ->  only if the page label argument has been passed,
84  *                          the page of the document to display.
85  *  mode                ->  only if the view mode is one of the availables,
86  *                          the view mode.
87  *  unlink-temp-file    ->  only if the view mode is preview mode and
88  *                          unlink-temp-file has been passed, unlink-temp-file.
89  *
90  * Returns: a pointer into #GHashTable with data from the arguments.
91  */
92 static GHashTable *
93 arguments_parse (void)
94 {
95         GHashTable      *args;
96         GValue          *value;
97         EvWindowRunMode  mode;
98         GdkScreen       *screen;
99         GdkDisplay      *display;
100         const gchar     *display_name;
101         gint             screen_number;
102
103         args = g_hash_table_new_full (g_str_hash,
104                                       g_str_equal,
105                                       (GDestroyNotify)g_free,
106                                       (GDestroyNotify)value_free);
107         
108         screen = gdk_screen_get_default ();
109         display = gdk_screen_get_display (screen);
110
111         display_name = gdk_display_get_name (display);
112         screen_number = gdk_screen_get_number (screen);
113
114         value = g_new0 (GValue, 1);
115         g_value_init (value, G_TYPE_STRING);
116         g_value_set_string (value, display_name);
117         g_hash_table_insert (args, g_strdup ("display"), value);
118
119         value = g_new0 (GValue, 1);
120         g_value_init (value, G_TYPE_INT);
121         g_value_set_int (value, screen_number);
122         g_hash_table_insert (args, g_strdup ("screen"), value);
123
124         if (ev_page_label) {
125                 value = g_new0 (GValue, 1);
126                 g_value_init (value, G_TYPE_STRING);
127                 g_value_set_string (value, ev_page_label);
128
129                 g_hash_table_insert (args, g_strdup ("page-label"), value);
130         }
131
132         if (fullscren_mode)
133                 mode = EV_WINDOW_MODE_FULLSCREEN;
134         else if (presentation_mode)
135                 mode = EV_WINDOW_MODE_PRESENTATION;
136         else if (preview_mode)
137                 mode = EV_WINDOW_MODE_PREVIEW;
138         else
139                 return args;
140
141         value = g_new0 (GValue, 1);
142         g_value_init (value, G_TYPE_UINT);
143         g_value_set_uint (value, mode);
144
145         g_hash_table_insert (args, g_strdup ("mode"), value);
146
147         if (mode == EV_WINDOW_MODE_PREVIEW && unlink_temp_file) {
148                 value = g_new0 (GValue, 1);
149                 g_value_init (value, G_TYPE_BOOLEAN);
150                 g_value_set_boolean (value, unlink_temp_file);
151
152                 g_hash_table_insert (args,
153                                      g_strdup ("unlink-temp-file"),
154                                      value);
155         }
156
157         return args;
158 }
159
160 static void
161 load_files (const char **files,
162             GHashTable  *args)
163 {
164         int i;
165
166         if (!files) {
167                 ev_application_open_window (EV_APP, args, GDK_CURRENT_TIME, NULL);
168                 return;
169         }
170
171         for (i = 0; files[i]; i++) {
172                 char   *uri;
173                 char   *label;
174                 GValue *old = NULL;
175
176                 uri = gnome_vfs_make_uri_from_shell_arg (files[i]);
177                 
178                 label = strchr (uri, GNOME_VFS_URI_MAGIC_CHR);
179
180                 if (label) {
181                         GValue *new;
182
183                         *label = 0; label++;
184                         
185                         old = g_hash_table_lookup (args, "page-label");
186                         
187                         new = g_new0 (GValue, 1);
188                         g_value_init (new, G_TYPE_STRING);
189                         g_value_set_string (new, label);
190
191                         g_hash_table_insert (args, g_strdup ("page-label"), new);
192
193                 }
194
195                 ev_application_open_uri (EV_APP, uri, args,
196                                          GDK_CURRENT_TIME, NULL);
197
198                 if (old)
199                         g_hash_table_insert (args, g_strdup ("page-label"), old);
200                 
201                 g_free (uri);
202         }
203 }
204
205 #ifdef ENABLE_DBUS
206 static gboolean
207 load_files_remote (const char **files,
208                    GHashTable  *args)
209 {
210         int i;
211         GError *error = NULL;
212         DBusGConnection *connection;
213         gboolean result = FALSE;
214         DBusGProxy *remote_object;
215         GdkDisplay *display;
216         guint32 timestamp;
217
218         display = gdk_display_get_default ();
219         timestamp = gdk_x11_display_get_user_time (display);
220         connection = dbus_g_bus_get (DBUS_BUS_STARTER, &error);
221
222         if (connection == NULL) {
223                 g_warning (error->message);
224                 g_error_free (error);   
225
226                 return FALSE;
227         }
228
229         remote_object = dbus_g_proxy_new_for_name (connection,
230                                                    "org.gnome.evince.ApplicationService",
231                                                    "/org/gnome/evince/Evince",
232                                                    "org.gnome.evince.Application");
233         if (!files) {
234                 if (!dbus_g_proxy_call (remote_object, "OpenWindow", &error,
235                                         dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), args,
236                                         G_TYPE_UINT, timestamp,
237                                         G_TYPE_INVALID,
238                                         G_TYPE_INVALID)) {
239                         g_warning (error->message);
240                         g_clear_error (&error);
241                         g_object_unref (remote_object);
242                         dbus_g_connection_unref (connection);
243                         return FALSE;
244                 }
245
246                 g_object_unref (remote_object);
247                 dbus_g_connection_unref (connection);
248                 
249                 return TRUE;
250         }
251
252         for (i = 0; files[i]; i++) {
253                 const char *page_label;
254                 char *uri;
255
256                 uri = gnome_vfs_make_uri_from_shell_arg (files[i]);
257                 page_label = ev_page_label ? ev_page_label : "";
258
259                 if (!dbus_g_proxy_call (remote_object, "OpenURI", &error,
260                                         G_TYPE_STRING, uri,
261                                         dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), args,
262                                         G_TYPE_UINT, timestamp,
263                                         G_TYPE_INVALID,
264                                         G_TYPE_INVALID)) {
265                         g_warning (error->message);
266                         g_clear_error (&error);
267                         g_free (uri);
268                         continue;
269                 }
270
271                 g_free (uri);
272                 result = TRUE;
273         }
274
275         g_object_unref (remote_object);
276         dbus_g_connection_unref (connection);
277
278         gdk_notify_startup_complete ();
279
280         return result;
281 }
282 #endif /* ENABLE_DBUS */
283
284 int
285 main (int argc, char *argv[])
286 {
287         gboolean enable_metadata = FALSE;
288         GOptionContext *context;
289         GHashTable *args;
290 #if WITH_GNOME
291         GnomeProgram *program;
292 #else
293         GError *error = NULL;
294 #endif
295
296         context = g_option_context_new (_("GNOME Document Viewer"));
297
298 #ifdef ENABLE_NLS
299         /* Initialize the i18n stuff */
300         bindtextdomain(GETTEXT_PACKAGE, GNOMELOCALEDIR);
301         bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
302         textdomain(GETTEXT_PACKAGE);
303         g_option_context_add_main_entries (context, goption_options, GETTEXT_PACKAGE);
304 #else
305         g_option_context_add_main_entries (context, goption_options, NULL);
306 #endif
307
308 #if WITH_GNOME
309         program = gnome_program_init (PACKAGE, VERSION,
310                                       LIBGNOMEUI_MODULE, argc, argv,
311                                       GNOME_PARAM_GOPTION_CONTEXT, context,
312                                       GNOME_PARAM_HUMAN_READABLE_NAME, _("Evince"),
313                                       GNOME_PARAM_APP_DATADIR, GNOMEDATADIR,
314                                       NULL);
315 #else
316         g_option_context_add_group (context, gtk_get_option_group (TRUE));
317         if (!g_option_context_parse (context, &argc, &argv, &error)) {
318                 g_warning ("Cannot parse arguments: %s", error->message);
319                 g_error_free (error);
320                 return 1;
321         }
322         g_option_context_free (context);
323         
324         gnome_vfs_init ();
325 #endif
326
327         args = arguments_parse ();
328
329 #ifdef ENABLE_DBUS
330         if (!ev_application_register_service (EV_APP)) {
331                 if (load_files_remote (file_arguments, args)) {
332                         g_hash_table_destroy (args);
333 #if WITH_GNOME
334                         g_object_unref (program);
335 #endif
336                         return 0;
337                 }
338         } else {
339                 enable_metadata = TRUE;
340         }
341 #endif
342
343 #if WITH_GNOME  
344         gnome_authentication_manager_init ();
345 #endif
346
347         if (enable_metadata) {
348                 ev_metadata_manager_init ();
349         }
350
351         ev_job_queue_init ();
352         g_set_application_name (_("Evince Document Viewer"));
353
354         ev_file_helpers_init ();
355         ev_stock_icons_init ();
356         gtk_window_set_default_icon_name ("evince");
357
358         load_files (file_arguments, args);
359         g_hash_table_destroy (args);
360
361         gtk_main ();
362
363 #if WITH_GNOME
364         gnome_accelerators_sync ();
365 #endif
366
367         ev_file_helpers_shutdown ();
368
369         if (enable_metadata) {
370                 ev_metadata_manager_shutdown ();
371         }
372
373 #if WITH_GNOME
374         g_object_unref (program);
375 #endif
376         
377         return 0;
378 }