]> www.fi.muni.cz Git - evince.git/blob - shell/ev-application.c
[shell] Fix build with dbus disabled
[evince.git] / shell / ev-application.c
1 /* this file is part of evince, a gnome document viewer
2  *
3  *  Copyright (C) 2004 Martin Kretzschmar
4  *  Copyright © 2010 Christian Persch
5  *
6  *  Author:
7  *    Martin Kretzschmar <martink@gnome.org>
8  *
9  * Evince is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Evince is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22  */
23
24
25 #include <config.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include <glib.h>
30 #include <glib/gi18n.h>
31 #include <glib/gstdio.h>
32 #include <gtk/gtk.h>
33 #ifdef GDK_WINDOWING_X11
34 #include <gdk/gdkx.h>
35 #endif
36 #include <unistd.h>
37
38 #include "totem-scrsaver.h"
39
40 #ifdef WITH_SMCLIENT
41 #include "eggsmclient.h"
42 #endif
43
44 #include "ev-application.h"
45 #include "ev-file-helpers.h"
46 #include "ev-stock-icons.h"
47
48 #ifdef ENABLE_DBUS
49 #include "ev-media-player-keys.h"
50 #endif /* ENABLE_DBUS */
51
52 #ifdef ENABLE_DBUS
53 #endif
54
55 struct _EvApplication {
56         GObject base_instance;
57
58         gchar *uri;
59
60         gchar *dot_dir;
61         gchar *data_dir;
62
63 #ifdef ENABLE_DBUS
64         GDBusConnection *connection;
65         guint registration_id;
66         EvMediaPlayerKeys *keys;
67 #endif
68
69         TotemScrsaver *scr_saver;
70
71 #ifdef WITH_SMCLIENT
72         EggSMClient *smclient;
73 #endif
74
75         gchar *filechooser_open_uri;
76         gchar *filechooser_save_uri;
77 };
78
79 struct _EvApplicationClass {
80         GObjectClass base_class;
81 };
82
83 static EvApplication *instance;
84
85 G_DEFINE_TYPE (EvApplication, ev_application, G_TYPE_OBJECT);
86
87 #ifdef ENABLE_DBUS
88 #define APPLICATION_DBUS_OBJECT_PATH "/org/gnome/evince/Evince"
89 #define APPLICATION_DBUS_INTERFACE   "org.gnome.evince.Application"
90 #endif
91
92 static const gchar *userdir = NULL;
93
94 /**
95  * ev_application_get_instance:
96  *
97  * Checks for #EvApplication instance, if it doesn't exist it does create it.
98  *
99  * Returns: an instance of the #EvApplication data.
100  */
101 EvApplication *
102 ev_application_get_instance (void)
103 {
104         if (!instance) {
105                 instance = EV_APPLICATION (g_object_new (EV_TYPE_APPLICATION, NULL));
106         }
107
108         return instance;
109 }
110
111 /* Session */
112 gboolean
113 ev_application_load_session (EvApplication *application)
114 {
115         GKeyFile *state_file;
116         gchar    *uri;
117
118 #ifdef WITH_SMCLIENT
119         if (egg_sm_client_is_resumed (application->smclient)) {
120                 state_file = egg_sm_client_get_state_file (application->smclient);
121                 if (!state_file)
122                         return FALSE;
123         } else
124 #endif /* WITH_SMCLIENT */
125                 return FALSE;
126
127         uri = g_key_file_get_string (state_file, "Evince", "uri", NULL);
128         if (!uri)
129                 return FALSE;
130
131         ev_application_open_uri_at_dest (application, uri,
132                                          gdk_screen_get_default (),
133                                          NULL, 0, NULL,
134                                          GDK_CURRENT_TIME);
135         g_free (uri);
136         g_key_file_free (state_file);
137
138         return TRUE;
139 }
140
141 #ifdef WITH_SMCLIENT
142
143 static void
144 smclient_save_state_cb (EggSMClient   *client,
145                         GKeyFile      *state_file,
146                         EvApplication *application)
147 {
148         if (!application->uri)
149                 return;
150
151         g_key_file_set_string (state_file, "Evince", "uri", application->uri);
152 }
153
154 static void
155 smclient_quit_cb (EggSMClient   *client,
156                   EvApplication *application)
157 {
158         ev_application_shutdown (application);
159 }
160 #endif /* WITH_SMCLIENT */
161
162 static void
163 ev_application_init_session (EvApplication *application)
164 {
165 #ifdef WITH_SMCLIENT
166         application->smclient = egg_sm_client_get ();
167         g_signal_connect (application->smclient, "save_state",
168                           G_CALLBACK (smclient_save_state_cb),
169                           application);
170         g_signal_connect (application->smclient, "quit",
171                           G_CALLBACK (smclient_quit_cb),
172                           application);
173 #endif
174 }
175
176 /**
177  * ev_display_open_if_needed:
178  * @name: the name of the display to be open if it's needed.
179  *
180  * Search among all the open displays if any of them have the same name as the
181  * passed name. If the display isn't found it tries the open it.
182  *
183  * Returns: a #GdkDisplay of the display with the passed name.
184  */
185 static GdkDisplay *
186 ev_display_open_if_needed (const gchar *name)
187 {
188         GSList     *displays;
189         GSList     *l;
190         GdkDisplay *display = NULL;
191
192         displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
193
194         for (l = displays; l != NULL; l = l->next) {
195                 const gchar *display_name = gdk_display_get_name ((GdkDisplay *) l->data);
196
197                 if (g_ascii_strcasecmp (display_name, name) == 0) {
198                         display = l->data;
199                         break;
200                 }
201         }
202
203         g_slist_free (displays);
204
205         return display != NULL ? display : gdk_display_open (name);
206 }
207
208 static void
209 child_setup (gpointer user_data)
210 {
211         gchar *startup_id;
212
213         startup_id = g_strdup_printf ("_TIME%lu",
214                                       (unsigned long)GPOINTER_TO_INT (user_data));
215         g_setenv ("DESKTOP_STARTUP_ID", startup_id, TRUE);
216         g_free (startup_id);
217 }
218
219 static void
220 ev_spawn (const char     *uri,
221           GdkScreen      *screen,
222           EvLinkDest     *dest,
223           EvWindowRunMode mode,
224           const gchar    *search_string,
225           guint           timestamp)
226 {
227         gchar   *argv[6];
228         guint    arg = 0;
229         gint     i;
230         gboolean res;
231         GError  *error = NULL;
232
233 #ifdef G_OS_WIN32
234 {
235         gchar *dir;
236
237         dir = g_win32_get_package_installation_directory_of_module (NULL);
238         argv[arg++] = g_build_filename (dir, "bin", "evince", NULL);
239         g_free (dir);
240 }
241 #else
242         argv[arg++] = g_build_filename (BINDIR, "evince", NULL);
243 #endif
244
245         /* Page label */
246         if (dest) {
247                 const gchar *page_label;
248
249                 page_label = ev_link_dest_get_page_label (dest);
250                 if (page_label)
251                         argv[arg++] = g_strdup_printf ("--page-label=%s", page_label);
252                 else
253                         argv[arg++] = g_strdup_printf ("--page-label=%d",
254                                                        ev_link_dest_get_page (dest));
255         }
256
257         /* Find string */
258         if (search_string) {
259                 argv[arg++] = g_strdup_printf ("--find=%s", search_string);
260         }
261
262         /* Mode */
263         switch (mode) {
264         case EV_WINDOW_MODE_FULLSCREEN:
265                 argv[arg++] = g_strdup ("-f");
266                 break;
267         case EV_WINDOW_MODE_PRESENTATION:
268                 argv[arg++] = g_strdup ("-s");
269                 break;
270         default:
271                 break;
272         }
273
274         argv[arg++] = (gchar *)uri;
275         argv[arg] = NULL;
276
277         res = gdk_spawn_on_screen (screen, NULL /* wd */, argv, NULL /* env */,
278                                    0,
279                                    child_setup,
280                                    GINT_TO_POINTER(timestamp),
281                                    NULL, &error);
282         if (!res) {
283                 g_warning ("Error launching evince %s: %s\n", uri, error->message);
284                 g_error_free (error);
285         }
286
287         for (i = 0; i < arg - 1; i++) {
288                 g_free (argv[i]);
289         }
290 }
291
292 static GList *
293 ev_application_get_windows (EvApplication *application)
294 {
295         GList *l, *toplevels;
296         GList *windows = NULL;
297
298         toplevels = gtk_window_list_toplevels ();
299
300         for (l = toplevels; l != NULL; l = l->next) {
301                 if (EV_IS_WINDOW (l->data)) {
302                         windows = g_list_append (windows, l->data);
303                 }
304         }
305
306         g_list_free (toplevels);
307
308         return windows;
309 }
310
311 static EvWindow *
312 ev_application_get_empty_window (EvApplication *application,
313                                  GdkScreen     *screen)
314 {
315         EvWindow *empty_window = NULL;
316         GList    *windows = ev_application_get_windows (application);
317         GList    *l;
318
319         for (l = windows; l != NULL; l = l->next) {
320                 EvWindow *window = EV_WINDOW (l->data);
321
322                 if (ev_window_is_empty (window) &&
323                     gtk_window_get_screen (GTK_WINDOW (window)) == screen) {
324                         empty_window = window;
325                         break;
326                 }
327         }
328
329         g_list_free (windows);
330
331         return empty_window;
332 }
333
334
335 #ifdef ENABLE_DBUS
336 /*
337  * ev_application_register_uri:
338  * @application:
339  * @uri:
340  * @screen:
341  * @dest:
342  * @mode:
343  * @search_string:
344  * @timestamp:
345  *
346  * Registers @uri with evince-daemon.
347  *
348  * Returns: %TRUE to continue by opening @uri in this instance,
349  *   or %FALSE if the request was forwarded to an existing evince
350  *   instance for @uri
351  */
352 static gboolean
353 ev_application_register_uri (EvApplication *application,
354                              const gchar   *uri,
355                              GdkScreen      *screen,
356                              EvLinkDest     *dest,
357                              EvWindowRunMode mode,
358                              const gchar    *search_string,
359                              guint          timestamp)
360 {
361         GVariant *value, *value2;
362         const gchar *owner;
363         GVariantBuilder builder;
364         GError *error = NULL;
365
366         if (!application->connection)
367                 return TRUE;
368
369         /* FIXME: Don't make sync dbus calls, they block the UI! */
370         value = g_dbus_connection_call_sync
371                    (application->connection,
372                     "org.gnome.evince.Daemon",
373                     "/org/gnome/evince/Daemon",
374                     "org.gnome.evince.Daemon",
375                     "RegisterDocument",
376                     g_variant_new ("(s)", uri),
377                     G_DBUS_CALL_FLAGS_NONE,
378                     -1,
379                     NULL,
380                     &error);
381         if (value == NULL) {
382                 g_warning ("Error registering document: %s\n", error->message);
383                 g_error_free (error);
384                 return TRUE;
385         }
386
387         g_variant_get (value, "(&s)", &owner);
388
389         /* This means that the document wasn't already registered; go
390          * ahead with opening it.
391          */
392         if (owner[0] == '\0') {
393                 g_variant_unref (value);
394                 return TRUE;
395         }
396
397         /* Already registered */
398         g_variant_builder_init (&builder, G_VARIANT_TYPE ("(sa{sv}u)"));
399         g_variant_builder_add (&builder, "s", uri);
400
401         g_variant_builder_open (&builder, G_VARIANT_TYPE ("a{sv}"));
402         g_variant_builder_add (&builder, "{sv}",
403                                "display",
404                                g_variant_new_string (gdk_display_get_name (gdk_screen_get_display (screen))));
405         g_variant_builder_add (&builder, "{sv}",
406                                "screen",
407                                g_variant_new_int32 (gdk_screen_get_number (screen)));
408         if (dest) {
409                 g_variant_builder_add (&builder, "{sv}",
410                                        "page-label",
411                                        g_variant_new_string (ev_link_dest_get_page_label (dest)));
412         }
413         if (search_string) {
414                 g_variant_builder_add (&builder, "{sv}",
415                                        "find-string",
416                                        g_variant_new_string (search_string));
417         }
418         if (mode != EV_WINDOW_MODE_NORMAL) {
419                 g_variant_builder_add (&builder, "{sv}",
420                                        "mode",
421                                        g_variant_new_uint32 (mode));
422         }
423         g_variant_builder_close (&builder);
424
425         g_variant_builder_add (&builder, "u", timestamp);
426
427         value2 = g_dbus_connection_call_sync
428                     (application->connection,
429                      owner,
430                      APPLICATION_DBUS_OBJECT_PATH,
431                      APPLICATION_DBUS_INTERFACE,
432                      "OpenURI",
433                      g_variant_builder_end (&builder),
434                      G_DBUS_CALL_FLAGS_NONE,
435                      -1,
436                      NULL,
437                      &error);
438         if (value2 == NULL) {
439                 g_warning ("Failed to OpenURI: %s", error->message);
440                 g_error_free (error);
441                 return FALSE;
442         }
443
444         g_variant_unref (value);
445         g_variant_unref (value2);
446
447         /* Do not continue opening this document */
448         return FALSE;
449 }
450
451 static void
452 ev_application_unregister_uri (EvApplication *application,
453                                const gchar   *uri)
454 {
455         GVariant *value;
456         GError *error = NULL;
457
458         if (!application->connection)
459                 return;
460
461         /* FIXME: Don't make sync dbus calls, they block the UI! */
462         value = g_dbus_connection_call_sync
463                    (application->connection,
464                     "org.gnome.evince.Daemon",
465                     "/org/gnome/evince/Daemon",
466                     "org.gnome.evince.Daemon",
467                     "UnregisterDocument",
468                     g_variant_new ("(s)", uri),
469                     G_DBUS_CALL_FLAGS_NO_AUTO_START,
470                     -1,
471                     NULL,
472                     &error);
473         if (value == NULL) {
474                 g_warning ("Error unregistering document: %s\n", error->message);
475                 g_error_free (error);
476         } else {
477                 g_variant_unref (value);
478         }
479 }
480 #endif /* ENABLE_DBUS */
481
482 static void
483 ev_application_open_uri_in_window (EvApplication  *application,
484                                    const char     *uri,
485                                    EvWindow       *ev_window,
486                                    GdkScreen      *screen,
487                                    EvLinkDest     *dest,
488                                    EvWindowRunMode mode,
489                                    const gchar    *search_string,
490                                    guint           timestamp)
491 {
492 #ifdef GDK_WINDOWING_X11
493         GdkWindow *gdk_window;
494 #endif
495
496         if (screen) {
497                 ev_stock_icons_set_screen (screen);
498                 gtk_window_set_screen (GTK_WINDOW (ev_window), screen);
499         }
500
501         /* We need to load uri before showing the window, so
502            we can restore window size without flickering */
503         ev_window_open_uri (ev_window, uri, dest, mode, search_string);
504
505         if (!gtk_widget_get_realized (GTK_WIDGET (ev_window)))
506                 gtk_widget_realize (GTK_WIDGET (ev_window));
507
508 #ifdef GDK_WINDOWING_X11
509         gdk_window = gtk_widget_get_window (GTK_WIDGET (ev_window));
510
511         if (timestamp <= 0)
512                 timestamp = gdk_x11_get_server_time (gdk_window);
513         gdk_x11_window_set_user_time (gdk_window, timestamp);
514
515         gtk_window_present (GTK_WINDOW (ev_window));
516 #else
517         gtk_window_present_with_time (GTK_WINDOW (ev_window), timestamp);
518 #endif /* GDK_WINDOWING_X11 */
519 }
520
521 /**
522  * ev_application_open_uri_at_dest:
523  * @application: The instance of the application.
524  * @uri: The uri to be opened.
525  * @screen: Thee screen where the link will be shown.
526  * @dest: The #EvLinkDest of the document.
527  * @mode: The run mode of the window.
528  * @timestamp: Current time value.
529  */
530 void
531 ev_application_open_uri_at_dest (EvApplication  *application,
532                                  const char     *uri,
533                                  GdkScreen      *screen,
534                                  EvLinkDest     *dest,
535                                  EvWindowRunMode mode,
536                                  const gchar    *search_string,
537                                  guint           timestamp)
538 {
539         EvWindow *ev_window;
540
541         g_return_if_fail (uri != NULL);
542
543         if (application->uri && strcmp (application->uri, uri) != 0) {
544                 /* spawn a new evince process */
545                 ev_spawn (uri, screen, dest, mode, search_string, timestamp);
546                 return;
547         } else {
548 #ifdef ENABLE_DBUS
549                 gboolean    ret;
550
551                 /* Register the uri or send OpenURI to
552                  * remote instance if already registered
553                  */
554                 ret = ev_application_register_uri (application, uri, screen, dest, mode, search_string, timestamp);
555                 if (!ret)
556                         return;
557 #endif /* ENABLE_DBUS */
558
559                 ev_window = ev_application_get_empty_window (application, screen);
560                 if (!ev_window)
561                         ev_window = EV_WINDOW (ev_window_new ());
562         }
563
564         application->uri = g_strdup (uri);
565
566         ev_application_open_uri_in_window (application, uri, ev_window,
567                                            screen, dest, mode,
568                                            search_string,
569                                            timestamp);
570 }
571
572 /**
573  * ev_application_open_window:
574  * @application: The instance of the application.
575  * @timestamp: Current time value.
576  *
577  * Creates a new window
578  */
579 void
580 ev_application_open_window (EvApplication *application,
581                             GdkScreen     *screen,
582                             guint32        timestamp)
583 {
584         GtkWidget *new_window = ev_window_new ();
585 #ifdef GDK_WINDOWING_X11
586         GdkWindow *gdk_window;
587 #endif
588
589         if (screen) {
590                 ev_stock_icons_set_screen (screen);
591                 gtk_window_set_screen (GTK_WINDOW (new_window), screen);
592         }
593
594         if (!gtk_widget_get_realized (new_window))
595                 gtk_widget_realize (new_window);
596
597 #ifdef GDK_WINDOWING_X11
598         gdk_window = gtk_widget_get_window (GTK_WIDGET (new_window));
599
600         if (timestamp <= 0)
601                 timestamp = gdk_x11_get_server_time (gdk_window);
602         gdk_x11_window_set_user_time (gdk_window, timestamp);
603
604         gtk_window_present (GTK_WINDOW (new_window));
605 #else
606         gtk_window_present_with_time (GTK_WINDOW (new_window), timestamp);
607 #endif /* GDK_WINDOWING_X11 */
608 }
609
610 static void
611 method_call_cb (GDBusConnection       *connection,
612                 const gchar           *sender,
613                 const gchar           *object_path,
614                 const gchar           *interface_name,
615                 const gchar           *method_name,
616                 GVariant              *parameters,
617                 GDBusMethodInvocation *invocation,
618                 gpointer               user_data)
619 {
620         EvApplication   *application = EV_APPLICATION (user_data);
621         GList           *windows, *l;
622         const gchar     *uri;
623         guint            timestamp;
624         GVariantIter    *iter;
625         const gchar     *key;
626         GVariant        *value;
627         GdkDisplay      *display = NULL;
628         int              screen_number = 0;
629         EvLinkDest      *dest = NULL;
630         EvWindowRunMode  mode = EV_WINDOW_MODE_NORMAL;
631         const gchar     *search_string = NULL;
632         GdkScreen       *screen = NULL;
633
634         if (g_strcmp0 (method_name, "OpenURI") != 0)
635                 return;
636
637         g_variant_get (parameters, "(&sa{sv}u)", &uri, &iter, &timestamp);
638
639         /* FIXME: we don't need uri anymore,
640          * maybe this method should be renamed
641          * as reload, refresh or something like that
642          */
643         if (g_strcmp0 (application->uri, uri) != 0) {
644                 g_dbus_method_invocation_return_error (invocation,
645                                                        G_DBUS_ERROR,
646                                                        G_DBUS_ERROR_INVALID_ARGS,
647                                                        "Unexpected URI \"%s\"",
648                                                        uri);
649                 g_variant_iter_free (iter);
650                 return;
651         }
652
653         while (g_variant_iter_loop (iter, "{&sv}", &key, &value)) {
654                 if (strcmp (key, "display") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
655                         display = ev_display_open_if_needed (g_variant_get_string (value, NULL));
656                 } else if (strcmp (key, "screen") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
657                         screen_number = g_variant_get_int32 (value);
658                 } else if (strcmp (key, "mode") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_UINT32) {
659                         mode = g_variant_get_uint32 (value);
660                 } else if (strcmp (key, "page-label") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
661                         dest = ev_link_dest_new_page_label (g_variant_get_string (value, NULL));
662                 } else if (strcmp (key, "find-string") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
663                         search_string = g_variant_get_string (value, NULL);
664                 }
665         }
666         g_variant_iter_free (iter);
667
668         if (display != NULL &&
669             screen_number >= 0 &&
670             screen_number < gdk_display_get_n_screens (display))
671                 screen = gdk_display_get_screen (display, screen_number);
672         else
673                 screen = gdk_screen_get_default ();
674
675         windows = ev_application_get_windows (application);
676         for (l = windows; l != NULL; l = g_list_next (l)) {
677                 EvWindow *ev_window = EV_WINDOW (l->data);
678
679                 ev_application_open_uri_in_window (application, uri, ev_window,
680                                                    screen, dest, mode,
681                                                    search_string,
682                                                    timestamp);
683         }
684         g_list_free (windows);
685
686         if (dest)
687                 g_object_unref (dest);
688
689         g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
690 }
691
692 void
693 ev_application_open_uri_list (EvApplication *application,
694                               GSList        *uri_list,
695                               GdkScreen     *screen,
696                               guint          timestamp)
697 {
698         GSList *l;
699
700         for (l = uri_list; l != NULL; l = l->next) {
701                 ev_application_open_uri_at_dest (application, (char *)l->data,
702                                                  screen, NULL, 0, NULL,
703                                                  timestamp);
704         }
705 }
706
707 static void
708 ev_application_accel_map_save (EvApplication *application)
709 {
710         gchar *accel_map_file;
711         gchar *tmp_filename;
712         gint   fd;
713
714         if (userdir) {
715                 accel_map_file = g_build_filename (userdir, "accels",
716                                                    "evince", NULL);
717         } else {
718                 accel_map_file = g_build_filename (g_get_home_dir (),
719                                                    ".gnome2", "accels",
720                                                    "evince", NULL);
721         }
722
723         tmp_filename = g_strdup_printf ("%s.XXXXXX", accel_map_file);
724
725         fd = g_mkstemp (tmp_filename);
726         if (fd == -1) {
727                 g_free (accel_map_file);
728                 g_free (tmp_filename);
729
730                 return;
731         }
732         gtk_accel_map_save_fd (fd);
733         close (fd);
734
735         if (g_rename (tmp_filename, accel_map_file) == -1) {
736                 /* FIXME: win32? */
737                 g_unlink (tmp_filename);
738         }
739
740         g_free (accel_map_file);
741         g_free (tmp_filename);
742 }
743
744 static void
745 ev_application_accel_map_load (EvApplication *application)
746 {
747         gchar *accel_map_file;
748
749         if (userdir) {
750                 accel_map_file = g_build_filename (userdir, "accels",
751                                                    "evince", NULL);
752         } else {
753                 accel_map_file = g_build_filename (g_get_home_dir (),
754                                                    ".gnome2", "accels",
755                                                    "evince", NULL);
756         }
757
758         gtk_accel_map_load (accel_map_file);
759         g_free (accel_map_file);
760 }
761
762 void
763 ev_application_shutdown (EvApplication *application)
764 {
765         if (application->uri) {
766 #ifdef ENABLE_DBUS
767                 ev_application_unregister_uri (application,
768                                                application->uri);
769 #endif
770                 g_free (application->uri);
771                 application->uri = NULL;
772         }
773
774         ev_application_accel_map_save (application);
775
776         g_object_unref (application->scr_saver);
777         application->scr_saver = NULL;
778
779 #ifdef ENABLE_DBUS
780         if (application->keys) {
781                 g_object_unref (application->keys);
782                 application->keys = NULL;
783         }
784         if (application->registration_id != 0) {
785                 g_dbus_connection_unregister_object (application->connection,
786                                                      application->registration_id);
787                 application->registration_id = 0;
788         }
789         if (application->connection != NULL) {
790                 g_object_unref (application->connection);
791                 application->connection = NULL;
792         }
793 #endif /* ENABLE_DBUS */
794         
795         g_free (application->dot_dir);
796         application->dot_dir = NULL;
797         g_free (application->data_dir);
798         application->data_dir = NULL;
799         g_free (application->filechooser_open_uri);
800         application->filechooser_open_uri = NULL;
801         g_free (application->filechooser_save_uri);
802         application->filechooser_save_uri = NULL;
803
804         g_object_unref (application);
805         instance = NULL;
806         
807         gtk_main_quit ();
808 }
809
810 static void
811 ev_application_class_init (EvApplicationClass *ev_application_class)
812 {
813 }
814
815 static void
816 ev_application_init (EvApplication *ev_application)
817 {
818         GError *error = NULL;
819
820         userdir = g_getenv ("GNOME22_USER_DIR");
821         if (userdir)
822                 ev_application->dot_dir = g_build_filename (userdir, "evince", NULL);
823         else
824                 ev_application->dot_dir = g_build_filename (g_get_home_dir (),
825                                                             ".gnome2",
826                                                             "evince",
827                                                             NULL);
828
829 #ifdef G_OS_WIN32
830 {
831         gchar *dir;
832
833         dir = g_win32_get_package_installation_directory_of_module (NULL);
834         ev_application->data_dir = g_build_filename (dir, "share", "evince", NULL);
835         g_free (dir);
836 }
837 #else
838         ev_application->data_dir = g_strdup (DATADIR);
839 #endif
840
841         ev_application_init_session (ev_application);
842
843         ev_application_accel_map_load (ev_application);
844
845 #ifdef ENABLE_DBUS
846 {
847         static const char introspection_xml[] =
848                 "<node>"
849                   "<interface name='org.gnome.evince.Daemon'>"
850                     "<method name='OpenURI'>"
851                       "<arg type='s' name='uri' direction='in'/>"
852                       "<arg type='a{sv}' name='args' direction='in'/>"
853                       "<arg type='u' name='timestamp' direction='in'/>"
854                     "</method>"
855                   "</interface>"
856                 "</node>";
857
858         static const GDBusInterfaceVTable interface_vtable = {
859                 method_call_cb,
860                 NULL,
861                 NULL
862         };
863
864         GDBusNodeInfo *introspection_data;
865
866         ev_application->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
867         if (ev_application->connection != NULL) {
868                 introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
869                 g_assert (introspection_data != NULL);
870
871
872                 ev_application->registration_id =
873                     g_dbus_connection_register_object (ev_application->connection,
874                                                        APPLICATION_DBUS_OBJECT_PATH,
875                                                        introspection_data->interfaces[0],
876                                                        &interface_vtable,
877                                                        ev_application, NULL,
878                                                        &error);
879                 if (ev_application->registration_id == 0) {
880                         g_printerr ("Failed to register bus object: %s\n", error->message);
881                         g_error_free (error);
882                 }
883                 
884         } else {
885                 g_printerr ("Failed to get bus connection: %s\n", error->message);
886                 g_error_free (error);
887         }
888
889         ev_application->keys = ev_media_player_keys_new ();
890
891         ev_application->scr_saver = totem_scrsaver_new ();
892 }
893 #else
894         ev_application->scr_saver = totem_scrsaver_new ();
895 #endif /* ENABLE_DBUS */
896 }
897
898 gboolean
899 ev_application_has_window (EvApplication *application)
900 {
901         GList   *windows = ev_application_get_windows (application);
902         gboolean retval = windows != NULL;
903
904         g_list_free (windows);
905
906         return retval;
907 }
908
909 const gchar *
910 ev_application_get_uri (EvApplication *application)
911 {
912         return application->uri;
913 }
914
915 /**
916  * ev_application_get_media_keys:
917  * @application: The instance of the application.
918  *
919  * It gives you access to the media player keys handler object.
920  *
921  * Returns: A #EvMediaPlayerKeys.
922  */
923 GObject *
924 ev_application_get_media_keys (EvApplication *application)
925 {
926 #ifdef ENABLE_DBUS
927         return G_OBJECT (application->keys);
928 #else
929         return NULL;
930 #endif /* ENABLE_DBUS */
931 }
932
933 void
934 ev_application_set_filechooser_uri (EvApplication       *application,
935                                     GtkFileChooserAction action,
936                                     const gchar         *uri)
937 {
938         if (action == GTK_FILE_CHOOSER_ACTION_OPEN) {
939                 g_free (application->filechooser_open_uri);
940                 application->filechooser_open_uri = g_strdup (uri);
941         } else if (action == GTK_FILE_CHOOSER_ACTION_SAVE) {
942                 g_free (application->filechooser_save_uri);
943                 application->filechooser_save_uri = g_strdup (uri);
944         }
945 }
946
947 const gchar *
948 ev_application_get_filechooser_uri (EvApplication       *application,
949                                     GtkFileChooserAction action)
950 {
951         if (action == GTK_FILE_CHOOSER_ACTION_OPEN) {
952                 if (application->filechooser_open_uri)
953                         return application->filechooser_open_uri;
954         } else if (action == GTK_FILE_CHOOSER_ACTION_SAVE) {
955                 if (application->filechooser_save_uri)
956                         return application->filechooser_save_uri;
957         }
958
959         return NULL;
960 }
961
962 void
963 ev_application_screensaver_enable (EvApplication *application)
964 {
965         totem_scrsaver_enable (application->scr_saver);
966 }
967
968 void
969 ev_application_screensaver_disable (EvApplication *application)
970 {
971         totem_scrsaver_disable (application->scr_saver);
972 }
973
974 const gchar *
975 ev_application_get_dot_dir (EvApplication *application,
976                             gboolean create)
977 {
978         if (create)
979                 g_mkdir_with_parents (application->dot_dir, 0700);
980
981         return application->dot_dir;
982 }
983
984 const gchar *
985 ev_application_get_data_dir (EvApplication   *application)
986 {
987         return application->data_dir;
988 }