]> www.fi.muni.cz Git - evince.git/blob - shell/ev-application.c
[shell] Remove DBUS conditionals from TotemScrsaver
[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 /*
336  * ev_application_register_uri:
337  * @application:
338  * @uri:
339  * @screen:
340  * @dest:
341  * @mode:
342  * @search_string:
343  * @timestamp:
344  *
345  * Registers @uri with evince-daemon.
346  *
347  * Returns: %TRUE to continue by opening @uri in this instance,
348  *   or %FALSE if the request was forwarded to an existing evince
349  *   instance for @uri
350  */
351 static gboolean
352 ev_application_register_uri (EvApplication *application,
353                              const gchar   *uri,
354                              GdkScreen      *screen,
355                              EvLinkDest     *dest,
356                              EvWindowRunMode mode,
357                              const gchar    *search_string,
358                              guint          timestamp)
359 {
360         GVariant *value, *value2;
361         const gchar *owner;
362         GVariantBuilder builder;
363         GError *error = NULL;
364
365         if (!application->connection)
366                 return TRUE;
367
368         /* FIXME: Don't make sync dbus calls, they block the UI! */
369         value = g_dbus_connection_call_sync
370                    (application->connection,
371                     "org.gnome.evince.Daemon",
372                     "/org/gnome/evince/Daemon",
373                     "org.gnome.evince.Daemon",
374                     "RegisterDocument",
375                     g_variant_new ("(s)", uri),
376                     G_DBUS_CALL_FLAGS_NONE,
377                     -1,
378                     NULL,
379                     &error);
380         if (value == NULL) {
381                 g_warning ("Error registering document: %s\n", error->message);
382                 g_error_free (error);
383                 return TRUE;
384         }
385
386         g_variant_get (value, "(&s)", &owner);
387
388         /* This means that the document wasn't already registered; go
389          * ahead with opening it.
390          */
391         if (owner[0] == '\0') {
392                 g_variant_unref (value);
393                 return TRUE;
394         }
395
396         /* Already registered */
397         g_variant_builder_init (&builder, G_VARIANT_TYPE ("(sa{sv}u)"));
398         g_variant_builder_add (&builder, "s", uri);
399
400         g_variant_builder_open (&builder, G_VARIANT_TYPE ("a{sv}"));
401         g_variant_builder_add (&builder, "{sv}",
402                                "display",
403                                g_variant_new_string (gdk_display_get_name (gdk_screen_get_display (screen))));
404         g_variant_builder_add (&builder, "{sv}",
405                                "screen",
406                                g_variant_new_int32 (gdk_screen_get_number (screen)));
407         if (dest) {
408                 g_variant_builder_add (&builder, "{sv}",
409                                        "page-label",
410                                        g_variant_new_string (ev_link_dest_get_page_label (dest)));
411         }
412         if (search_string) {
413                 g_variant_builder_add (&builder, "{sv}",
414                                        "find-string",
415                                        g_variant_new_string (search_string));
416         }
417         if (mode != EV_WINDOW_MODE_NORMAL) {
418                 g_variant_builder_add (&builder, "{sv}",
419                                        "mode",
420                                        g_variant_new_uint32 (mode));
421         }
422         g_variant_builder_close (&builder);
423
424         g_variant_builder_add (&builder, "u", timestamp);
425
426         value2 = g_dbus_connection_call_sync
427                     (application->connection,
428                      owner,
429                      APPLICATION_DBUS_OBJECT_PATH,
430                      APPLICATION_DBUS_INTERFACE,
431                      "OpenURI",
432                      g_variant_builder_end (&builder),
433                      G_DBUS_CALL_FLAGS_NONE,
434                      -1,
435                      NULL,
436                      &error);
437         if (value2 == NULL) {
438                 g_warning ("Failed to OpenURI: %s", error->message);
439                 g_error_free (error);
440                 return FALSE;
441         }
442
443         g_variant_unref (value);
444         g_variant_unref (value2);
445
446         /* Do not continue opening this document */
447         return FALSE;
448 }
449
450 static void
451 ev_application_unregister_uri (EvApplication *application,
452                                const gchar   *uri)
453 {
454         GVariant *value;
455         GError *error = NULL;
456
457         if (!application->connection)
458                 return;
459
460         /* FIXME: Don't make sync dbus calls, they block the UI! */
461         value = g_dbus_connection_call_sync
462                    (application->connection,
463                     "org.gnome.evince.Daemon",
464                     "/org/gnome/evince/Daemon",
465                     "org.gnome.evince.Daemon",
466                     "UnregisterDocument",
467                     g_variant_new ("(s)", uri),
468                     G_DBUS_CALL_FLAGS_NO_AUTO_START,
469                     -1,
470                     NULL,
471                     &error);
472         if (value == NULL) {
473                 g_warning ("Error unregistering document: %s\n", error->message);
474                 g_error_free (error);
475         } else {
476                 g_variant_unref (value);
477         }
478 }
479 #endif /* ENABLE_DBUS */
480
481 static void
482 ev_application_open_uri_in_window (EvApplication  *application,
483                                    const char     *uri,
484                                    EvWindow       *ev_window,
485                                    GdkScreen      *screen,
486                                    EvLinkDest     *dest,
487                                    EvWindowRunMode mode,
488                                    const gchar    *search_string,
489                                    guint           timestamp)
490 {
491 #ifdef GDK_WINDOWING_X11
492         GdkWindow *gdk_window;
493 #endif
494
495         if (screen) {
496                 ev_stock_icons_set_screen (screen);
497                 gtk_window_set_screen (GTK_WINDOW (ev_window), screen);
498         }
499
500         /* We need to load uri before showing the window, so
501            we can restore window size without flickering */
502         ev_window_open_uri (ev_window, uri, dest, mode, search_string);
503
504         if (!gtk_widget_get_realized (GTK_WIDGET (ev_window)))
505                 gtk_widget_realize (GTK_WIDGET (ev_window));
506
507 #ifdef GDK_WINDOWING_X11
508         gdk_window = gtk_widget_get_window (GTK_WIDGET (ev_window));
509
510         if (timestamp <= 0)
511                 timestamp = gdk_x11_get_server_time (gdk_window);
512         gdk_x11_window_set_user_time (gdk_window, timestamp);
513
514         gtk_window_present (GTK_WINDOW (ev_window));
515 #else
516         gtk_window_present_with_time (GTK_WINDOW (ev_window), timestamp);
517 #endif /* GDK_WINDOWING_X11 */
518 }
519
520 /**
521  * ev_application_open_uri_at_dest:
522  * @application: The instance of the application.
523  * @uri: The uri to be opened.
524  * @screen: Thee screen where the link will be shown.
525  * @dest: The #EvLinkDest of the document.
526  * @mode: The run mode of the window.
527  * @timestamp: Current time value.
528  */
529 void
530 ev_application_open_uri_at_dest (EvApplication  *application,
531                                  const char     *uri,
532                                  GdkScreen      *screen,
533                                  EvLinkDest     *dest,
534                                  EvWindowRunMode mode,
535                                  const gchar    *search_string,
536                                  guint           timestamp)
537 {
538         EvWindow *ev_window;
539
540         g_return_if_fail (uri != NULL);
541
542         if (application->uri && strcmp (application->uri, uri) != 0) {
543                 /* spawn a new evince process */
544                 ev_spawn (uri, screen, dest, mode, search_string, timestamp);
545                 return;
546         } else {
547 #ifdef ENABLE_DBUS
548                 gboolean    ret;
549
550                 /* Register the uri or send OpenURI to
551                  * remote instance if already registered
552                  */
553                 ret = ev_application_register_uri (application, uri, screen, dest, mode, search_string, timestamp);
554                 if (!ret)
555                         return;
556 #endif /* ENABLE_DBUS */
557
558                 ev_window = ev_application_get_empty_window (application, screen);
559                 if (!ev_window)
560                         ev_window = EV_WINDOW (ev_window_new ());
561         }
562
563         application->uri = g_strdup (uri);
564
565         ev_application_open_uri_in_window (application, uri, ev_window,
566                                            screen, dest, mode,
567                                            search_string,
568                                            timestamp);
569 }
570
571 /**
572  * ev_application_open_window:
573  * @application: The instance of the application.
574  * @timestamp: Current time value.
575  *
576  * Creates a new window
577  */
578 void
579 ev_application_open_window (EvApplication *application,
580                             GdkScreen     *screen,
581                             guint32        timestamp)
582 {
583         GtkWidget *new_window = ev_window_new ();
584 #ifdef GDK_WINDOWING_X11
585         GdkWindow *gdk_window;
586 #endif
587
588         if (screen) {
589                 ev_stock_icons_set_screen (screen);
590                 gtk_window_set_screen (GTK_WINDOW (new_window), screen);
591         }
592
593         if (!gtk_widget_get_realized (new_window))
594                 gtk_widget_realize (new_window);
595
596 #ifdef GDK_WINDOWING_X11
597         gdk_window = gtk_widget_get_window (GTK_WIDGET (new_window));
598
599         if (timestamp <= 0)
600                 timestamp = gdk_x11_get_server_time (gdk_window);
601         gdk_x11_window_set_user_time (gdk_window, timestamp);
602
603         gtk_window_present (GTK_WINDOW (new_window));
604 #else
605         gtk_window_present_with_time (GTK_WINDOW (new_window), timestamp);
606 #endif /* GDK_WINDOWING_X11 */
607 }
608
609 static void
610 method_call_cb (GDBusConnection       *connection,
611                 const gchar           *sender,
612                 const gchar           *object_path,
613                 const gchar           *interface_name,
614                 const gchar           *method_name,
615                 GVariant              *parameters,
616                 GDBusMethodInvocation *invocation,
617                 gpointer               user_data)
618 {
619         EvApplication   *application = EV_APPLICATION (user_data);
620         GList           *windows, *l;
621         const gchar     *uri;
622         guint            timestamp;
623         GVariantIter    *iter;
624         const gchar     *key;
625         GVariant        *value;
626         GdkDisplay      *display = NULL;
627         int              screen_number = 0;
628         EvLinkDest      *dest = NULL;
629         EvWindowRunMode  mode = EV_WINDOW_MODE_NORMAL;
630         const gchar     *search_string = NULL;
631         GdkScreen       *screen = NULL;
632
633         if (g_strcmp0 (method_name, "OpenURI") != 0)
634                 return;
635
636         g_variant_get (parameters, "(&sa{sv}u)", &uri, &iter, &timestamp);
637
638         /* FIXME: we don't need uri anymore,
639          * maybe this method should be renamed
640          * as reload, refresh or something like that
641          */
642         if (g_strcmp0 (application->uri, uri) != 0) {
643                 g_dbus_method_invocation_return_error (invocation,
644                                                        G_DBUS_ERROR,
645                                                        G_DBUS_ERROR_INVALID_ARGS,
646                                                        "Unexpected URI \"%s\"",
647                                                        uri);
648                 g_variant_iter_free (iter);
649                 return;
650         }
651
652         while (g_variant_iter_loop (iter, "{&sv}", &key, &value)) {
653                 if (strcmp (key, "display") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
654                         display = ev_display_open_if_needed (g_variant_get_string (value, NULL));
655                 } else if (strcmp (key, "screen") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
656                         screen_number = g_variant_get_int32 (value);
657                 } else if (strcmp (key, "mode") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_UINT32) {
658                         mode = g_variant_get_uint32 (value);
659                 } else if (strcmp (key, "page-label") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
660                         dest = ev_link_dest_new_page_label (g_variant_get_string (value, NULL));
661                 } else if (strcmp (key, "find-string") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
662                         search_string = g_variant_get_string (value, NULL);
663                 }
664         }
665         g_variant_iter_free (iter);
666
667         if (display != NULL &&
668             screen_number >= 0 &&
669             screen_number < gdk_display_get_n_screens (display))
670                 screen = gdk_display_get_screen (display, screen_number);
671         else
672                 screen = gdk_screen_get_default ();
673
674         windows = ev_application_get_windows (application);
675         for (l = windows; l != NULL; l = g_list_next (l)) {
676                 EvWindow *ev_window = EV_WINDOW (l->data);
677
678                 ev_application_open_uri_in_window (application, uri, ev_window,
679                                                    screen, dest, mode,
680                                                    search_string,
681                                                    timestamp);
682         }
683         g_list_free (windows);
684
685         if (dest)
686                 g_object_unref (dest);
687
688         g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
689 }
690
691 void
692 ev_application_open_uri_list (EvApplication *application,
693                               GSList        *uri_list,
694                               GdkScreen     *screen,
695                               guint          timestamp)
696 {
697         GSList *l;
698
699         for (l = uri_list; l != NULL; l = l->next) {
700                 ev_application_open_uri_at_dest (application, (char *)l->data,
701                                                  screen, NULL, 0, NULL,
702                                                  timestamp);
703         }
704 }
705
706 static void
707 ev_application_accel_map_save (EvApplication *application)
708 {
709         gchar *accel_map_file;
710         gchar *tmp_filename;
711         gint   fd;
712
713         if (userdir) {
714                 accel_map_file = g_build_filename (userdir, "accels",
715                                                    "evince", NULL);
716         } else {
717                 accel_map_file = g_build_filename (g_get_home_dir (),
718                                                    ".gnome2", "accels",
719                                                    "evince", NULL);
720         }
721
722         tmp_filename = g_strdup_printf ("%s.XXXXXX", accel_map_file);
723
724         fd = g_mkstemp (tmp_filename);
725         if (fd == -1) {
726                 g_free (accel_map_file);
727                 g_free (tmp_filename);
728
729                 return;
730         }
731         gtk_accel_map_save_fd (fd);
732         close (fd);
733
734         if (g_rename (tmp_filename, accel_map_file) == -1) {
735                 /* FIXME: win32? */
736                 g_unlink (tmp_filename);
737         }
738
739         g_free (accel_map_file);
740         g_free (tmp_filename);
741 }
742
743 static void
744 ev_application_accel_map_load (EvApplication *application)
745 {
746         gchar *accel_map_file;
747
748         if (userdir) {
749                 accel_map_file = g_build_filename (userdir, "accels",
750                                                    "evince", NULL);
751         } else {
752                 accel_map_file = g_build_filename (g_get_home_dir (),
753                                                    ".gnome2", "accels",
754                                                    "evince", NULL);
755         }
756
757         gtk_accel_map_load (accel_map_file);
758         g_free (accel_map_file);
759 }
760
761 void
762 ev_application_shutdown (EvApplication *application)
763 {
764         if (application->uri) {
765 #ifdef ENABLE_DBUS
766                 ev_application_unregister_uri (application,
767                                                application->uri);
768 #endif
769                 g_free (application->uri);
770                 application->uri = NULL;
771         }
772
773         ev_application_accel_map_save (application);
774
775         g_object_unref (application->scr_saver);
776         application->scr_saver = NULL;
777
778 #ifdef ENABLE_DBUS
779         if (application->keys) {
780                 g_object_unref (application->keys);
781                 application->keys = NULL;
782         }
783         if (application->registration_id != 0) {
784                 g_dbus_connection_unregister_object (application->connection,
785                                                      application->registration_id);
786                 application->registration_id = 0;
787         }
788         if (application->connection != NULL) {
789                 g_object_unref (application->connection);
790                 application->connection = NULL;
791         }
792 #endif /* ENABLE_DBUS */
793         
794         g_free (application->dot_dir);
795         application->dot_dir = NULL;
796         g_free (application->data_dir);
797         application->data_dir = NULL;
798         g_free (application->filechooser_open_uri);
799         application->filechooser_open_uri = NULL;
800         g_free (application->filechooser_save_uri);
801         application->filechooser_save_uri = NULL;
802
803         g_object_unref (application);
804         instance = NULL;
805         
806         gtk_main_quit ();
807 }
808
809 static void
810 ev_application_class_init (EvApplicationClass *ev_application_class)
811 {
812 }
813
814 static void
815 ev_application_init (EvApplication *ev_application)
816 {
817         GError *error = NULL;
818
819         userdir = g_getenv ("GNOME22_USER_DIR");
820         if (userdir)
821                 ev_application->dot_dir = g_build_filename (userdir, "evince", NULL);
822         else
823                 ev_application->dot_dir = g_build_filename (g_get_home_dir (),
824                                                             ".gnome2",
825                                                             "evince",
826                                                             NULL);
827
828 #ifdef G_OS_WIN32
829 {
830         gchar *dir;
831
832         dir = g_win32_get_package_installation_directory_of_module (NULL);
833         ev_application->data_dir = g_build_filename (dir, "share", "evince", NULL);
834         g_free (dir);
835 }
836 #else
837         ev_application->data_dir = g_strdup (DATADIR);
838 #endif
839
840         ev_application_init_session (ev_application);
841
842         ev_application_accel_map_load (ev_application);
843
844 #ifdef ENABLE_DBUS
845 {
846         static const char introspection_xml[] =
847                 "<node>"
848                   "<interface name='org.gnome.evince.Daemon'>"
849                     "<method name='OpenURI'>"
850                       "<arg type='s' name='uri' direction='in'/>"
851                       "<arg type='a{sv}' name='args' direction='in'/>"
852                       "<arg type='u' name='timestamp' direction='in'/>"
853                     "</method>"
854                   "</interface>"
855                 "</node>";
856
857         static const GDBusInterfaceVTable interface_vtable = {
858                 method_call_cb,
859                 NULL,
860                 NULL
861         };
862
863         GDBusNodeInfo *introspection_data;
864
865         ev_application->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
866         if (ev_application->connection != NULL) {
867                 introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
868                 g_assert (introspection_data != NULL);
869
870
871                 ev_application->registration_id =
872                     g_dbus_connection_register_object (ev_application->connection,
873                                                        APPLICATION_DBUS_OBJECT_PATH,
874                                                        APPLICATION_DBUS_INTERFACE,
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 (ev_application->connection);
890
891         ev_application->scr_saver = totem_scrsaver_new (ev_application->connection);
892 }
893 #else
894         ev_application->scr_saver = totem_scrsaver_new (NULL);
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 }