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