X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;ds=sidebyside;f=shell%2Fev-application.c;h=600880a1e6ad86dd2d8eff036493fcfcc07505da;hb=d7f24a354ba037541b40f562c02cccf67c3bf59c;hp=dadc4663ce76366875cad88f81de87435008ad2d;hpb=2514100774c5d1e1fa013daccfe92897c727e640;p=evince.git
diff --git a/shell/ev-application.c b/shell/ev-application.c
index dadc4663..600880a1 100644
--- a/shell/ev-application.c
+++ b/shell/ev-application.c
@@ -49,9 +49,6 @@
#include "ev-media-player-keys.h"
#endif /* ENABLE_DBUS */
-#ifdef ENABLE_DBUS
-#endif
-
struct _EvApplication {
GObject base_instance;
@@ -64,6 +61,7 @@ struct _EvApplication {
GDBusConnection *connection;
guint registration_id;
EvMediaPlayerKeys *keys;
+ gboolean doc_registered;
#endif
TotemScrsaver *scr_saver;
@@ -87,9 +85,27 @@ G_DEFINE_TYPE (EvApplication, ev_application, G_TYPE_OBJECT);
#ifdef ENABLE_DBUS
#define APPLICATION_DBUS_OBJECT_PATH "/org/gnome/evince/Evince"
#define APPLICATION_DBUS_INTERFACE "org.gnome.evince.Application"
+
+#define EVINCE_DAEMON_SERVICE "org.gnome.evince.Daemon"
+#define EVINCE_DAEMON_OBJECT_PATH "/org/gnome/evince/Daemon"
+#define EVINCE_DAEMON_INTERFACE "org.gnome.evince.Daemon"
#endif
-static const gchar *userdir = NULL;
+static void _ev_application_open_uri_at_dest (EvApplication *application,
+ const gchar *uri,
+ GdkScreen *screen,
+ EvLinkDest *dest,
+ EvWindowRunMode mode,
+ const gchar *search_string,
+ guint timestamp);
+static void ev_application_open_uri_in_window (EvApplication *application,
+ const char *uri,
+ EvWindow *ev_window,
+ GdkScreen *screen,
+ EvLinkDest *dest,
+ EvWindowRunMode mode,
+ const gchar *search_string,
+ guint timestamp);
/**
* ev_application_get_instance:
@@ -205,17 +221,6 @@ ev_display_open_if_needed (const gchar *name)
return display != NULL ? display : gdk_display_open (name);
}
-static void
-child_setup (gpointer user_data)
-{
- gchar *startup_id;
-
- startup_id = g_strdup_printf ("_TIME%lu",
- (unsigned long)GPOINTER_TO_INT (user_data));
- g_setenv ("DESKTOP_STARTUP_ID", startup_id, TRUE);
- g_free (startup_id);
-}
-
static void
ev_spawn (const char *uri,
GdkScreen *screen,
@@ -224,69 +229,91 @@ ev_spawn (const char *uri,
const gchar *search_string,
guint timestamp)
{
- gchar *argv[6];
- guint arg = 0;
- gint i;
- gboolean res;
+ GString *cmd;
+ gchar *path, *cmdline;
+ GAppInfo *app;
+ GdkAppLaunchContext *ctx;
GError *error = NULL;
+ cmd = g_string_new (NULL);
+
#ifdef G_OS_WIN32
{
gchar *dir;
dir = g_win32_get_package_installation_directory_of_module (NULL);
- argv[arg++] = g_build_filename (dir, "bin", "evince", NULL);
+ path = g_build_filename (dir, "bin", "evince", NULL);
+
g_free (dir);
}
#else
- argv[arg++] = g_build_filename (BINDIR, "evince", NULL);
+ path = g_build_filename (BINDIR, "evince", NULL);
#endif
+ g_string_append_printf (cmd, " %s", path);
+ g_free (path);
+
/* Page label */
if (dest) {
const gchar *page_label;
page_label = ev_link_dest_get_page_label (dest);
+
if (page_label)
- argv[arg++] = g_strdup_printf ("--page-label=%s", page_label);
+ g_string_append_printf (cmd, " --page-label=%s", page_label);
else
- argv[arg++] = g_strdup_printf ("--page-label=%d",
- ev_link_dest_get_page (dest));
+ g_string_append_printf (cmd, " --page-label=%d",
+ ev_link_dest_get_page (dest));
}
/* Find string */
if (search_string) {
- argv[arg++] = g_strdup_printf ("--find=%s", search_string);
+ g_string_append_printf (cmd, " --find=%s", search_string);
}
/* Mode */
switch (mode) {
case EV_WINDOW_MODE_FULLSCREEN:
- argv[arg++] = g_strdup ("-f");
+ g_string_append (cmd, " -f");
break;
case EV_WINDOW_MODE_PRESENTATION:
- argv[arg++] = g_strdup ("-s");
+ g_string_append (cmd, " -s");
break;
default:
break;
}
- argv[arg++] = (gchar *)uri;
- argv[arg] = NULL;
+ cmdline = g_string_free (cmd, FALSE);
+ app = g_app_info_create_from_commandline (cmdline, NULL, 0, &error);
+
+ if (app != NULL) {
+ GList uri_list;
+
+ ctx = gdk_display_get_app_launch_context (gdk_screen_get_display (screen));
+ gdk_app_launch_context_set_screen (ctx, screen);
+ gdk_app_launch_context_set_timestamp (ctx, timestamp);
+
+ /* Some URIs can be changed when passed through a GFile
+ * (for instance unsupported uris with strange formats like mailto:),
+ * so if you have a textual uri you want to pass in as argument,
+ * consider using g_app_info_launch_uris() instead.
+ * See https://bugzilla.gnome.org/show_bug.cgi?id=644604
+ */
+ uri_list.data = (gchar *)uri;
+ uri_list.prev = uri_list.next = NULL;
+ g_app_info_launch_uris (app, &uri_list,
+ G_APP_LAUNCH_CONTEXT (ctx), &error);
+
+ g_object_unref (app);
+ g_object_unref (ctx);
+ }
- res = gdk_spawn_on_screen (screen, NULL /* wd */, argv, NULL /* env */,
- 0,
- child_setup,
- GINT_TO_POINTER(timestamp),
- NULL, &error);
- if (!res) {
+ if (error != NULL) {
g_warning ("Error launching evince %s: %s\n", uri, error->message);
g_error_free (error);
}
- for (i = 0; i < arg - 1; i++) {
- g_free (argv[i]);
- }
+ g_free (cmdline);
}
static GList *
@@ -333,119 +360,222 @@ ev_application_get_empty_window (EvApplication *application,
#ifdef ENABLE_DBUS
-/*
- * ev_application_register_uri:
- * @application:
- * @uri:
- * @screen:
- * @dest:
- * @mode:
- * @search_string:
- * @timestamp:
- *
- * Registers @uri with evince-daemon.
- *
- * Returns: %TRUE to continue by opening @uri in this instance,
- * or %FALSE if the request was forwarded to an existing evince
- * instance for @uri
- */
-static gboolean
-ev_application_register_uri (EvApplication *application,
- const gchar *uri,
- GdkScreen *screen,
- EvLinkDest *dest,
- EvWindowRunMode mode,
- const gchar *search_string,
- guint timestamp)
+typedef struct {
+ gchar *uri;
+ GdkScreen *screen;
+ EvLinkDest *dest;
+ EvWindowRunMode mode;
+ gchar *search_string;
+ guint timestamp;
+} EvRegisterDocData;
+
+static void
+ev_register_doc_data_free (EvRegisterDocData *data)
{
- GVariant *value, *value2;
- const gchar *owner;
- GVariantBuilder builder;
- GError *error = NULL;
+ if (!data)
+ return;
- if (!application->connection)
- return TRUE;
-
- /* FIXME: Don't make sync dbus calls, they block the UI! */
- value = g_dbus_connection_call_sync
- (application->connection,
- "org.gnome.evince.Daemon",
- "/org/gnome/evince/Daemon",
- "org.gnome.evince.Daemon",
- "RegisterDocument",
- g_variant_new ("(s)", uri),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- &error);
- if (value == NULL) {
+ g_free (data->uri);
+ if (data->search_string)
+ g_free (data->search_string);
+ if (data->dest)
+ g_object_unref (data->dest);
+
+ g_free (data);
+}
+
+static void
+on_reload_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GDBusConnection *connection = G_DBUS_CONNECTION (source_object);
+ GVariant *value;
+ GError *error = NULL;
+
+ value = g_dbus_connection_call_finish (connection, res, &error);
+ if (!value) {
+ g_warning ("Failed to Reload: %s", error->message);
+ g_error_free (error);
+ }
+ g_variant_unref (value);
+
+ /* We did not open a window, so manually clear the startup
+ * notification. */
+ gdk_notify_startup_complete ();
+
+ ev_application_shutdown (EV_APP);
+}
+
+static void
+on_register_uri_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GDBusConnection *connection = G_DBUS_CONNECTION (source_object);
+ EvRegisterDocData *data = (EvRegisterDocData *)user_data;
+ EvApplication *application = EV_APP;
+ GVariant *value;
+ const gchar *owner;
+ GVariantBuilder builder;
+ GError *error = NULL;
+
+ value = g_dbus_connection_call_finish (connection, res, &error);
+ if (!value) {
g_warning ("Error registering document: %s\n", error->message);
g_error_free (error);
- return TRUE;
+
+ _ev_application_open_uri_at_dest (application,
+ data->uri,
+ data->screen,
+ data->dest,
+ data->mode,
+ data->search_string,
+ data->timestamp);
+ ev_register_doc_data_free (data);
+
+ return;
}
- g_variant_get (value, "(&s)", &owner);
+ g_variant_get (value, "(&s)", &owner);
- /* This means that the document wasn't already registered; go
+ /* This means that the document wasn't already registered; go
* ahead with opening it.
*/
if (owner[0] == '\0') {
g_variant_unref (value);
- return TRUE;
- }
- /* Already registered */
- g_variant_builder_init (&builder, G_VARIANT_TYPE ("(sa{sv}u)"));
- g_variant_builder_add (&builder, "s", uri);
+ application->doc_registered = TRUE;
+
+ _ev_application_open_uri_at_dest (application,
+ data->uri,
+ data->screen,
+ data->dest,
+ data->mode,
+ data->search_string,
+ data->timestamp);
+ ev_register_doc_data_free (data);
+
+ return;
+ }
+ /* Already registered */
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("(a{sv}u)"));
g_variant_builder_open (&builder, G_VARIANT_TYPE ("a{sv}"));
g_variant_builder_add (&builder, "{sv}",
"display",
- g_variant_new_string (gdk_display_get_name (gdk_screen_get_display (screen))));
+ g_variant_new_string (gdk_display_get_name (gdk_screen_get_display (data->screen))));
g_variant_builder_add (&builder, "{sv}",
"screen",
- g_variant_new_int32 (gdk_screen_get_number (screen)));
- if (dest) {
- g_variant_builder_add (&builder, "{sv}",
- "page-label",
- g_variant_new_string (ev_link_dest_get_page_label (dest)));
+ g_variant_new_int32 (gdk_screen_get_number (data->screen)));
+ if (data->dest) {
+ const gchar *page_label = ev_link_dest_get_page_label (data->dest);
+
+ if (page_label) {
+ g_variant_builder_add (&builder, "{sv}",
+ "page-label",
+ g_variant_new_string (page_label));
+ } else {
+ g_variant_builder_add (&builder, "{sv}",
+ "page-index",
+ g_variant_new_uint32 (ev_link_dest_get_page (data->dest)));
+ }
}
- if (search_string) {
+ if (data->search_string) {
g_variant_builder_add (&builder, "{sv}",
"find-string",
- g_variant_new_string (search_string));
+ g_variant_new_string (data->search_string));
}
- if (mode != EV_WINDOW_MODE_NORMAL) {
+ if (data->mode != EV_WINDOW_MODE_NORMAL) {
g_variant_builder_add (&builder, "{sv}",
"mode",
- g_variant_new_uint32 (mode));
+ g_variant_new_uint32 (data->mode));
}
g_variant_builder_close (&builder);
- g_variant_builder_add (&builder, "u", timestamp);
-
- value2 = g_dbus_connection_call_sync
- (application->connection,
- owner,
- APPLICATION_DBUS_OBJECT_PATH,
- APPLICATION_DBUS_INTERFACE,
- "OpenURI",
- g_variant_builder_end (&builder),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- &error);
- if (value2 == NULL) {
- g_warning ("Failed to OpenURI: %s", error->message);
- g_error_free (error);
- return FALSE;
- }
-
+ g_variant_builder_add (&builder, "u", data->timestamp);
+
+ g_dbus_connection_call (connection,
+ owner,
+ APPLICATION_DBUS_OBJECT_PATH,
+ APPLICATION_DBUS_INTERFACE,
+ "Reload",
+ g_variant_builder_end (&builder),
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ on_reload_cb,
+ NULL);
g_variant_unref (value);
- g_variant_unref (value2);
+ ev_register_doc_data_free (data);
+}
- /* Do not continue opening this document */
- return FALSE;
+/*
+ * ev_application_register_uri:
+ * @application:
+ * @uri:
+ * @screen:
+ * @dest:
+ * @mode:
+ * @search_string:
+ * @timestamp:
+ *
+ * Registers @uri with evince-daemon.
+ *
+ */
+static void
+ev_application_register_uri (EvApplication *application,
+ const gchar *uri,
+ GdkScreen *screen,
+ EvLinkDest *dest,
+ EvWindowRunMode mode,
+ const gchar *search_string,
+ guint timestamp)
+{
+ EvRegisterDocData *data;
+
+ if (!application->connection)
+ return;
+
+ if (application->doc_registered) {
+ /* Already registered, reload */
+ GList *windows, *l;
+
+ windows = ev_application_get_windows (application);
+ for (l = windows; l != NULL; l = g_list_next (l)) {
+ EvWindow *ev_window = EV_WINDOW (l->data);
+
+ ev_application_open_uri_in_window (application, uri, ev_window,
+ screen, dest, mode,
+ search_string,
+ timestamp);
+ }
+ g_list_free (windows);
+
+ return;
+ }
+
+ data = g_new (EvRegisterDocData, 1);
+ data->uri = g_strdup (uri);
+ data->screen = screen;
+ data->dest = dest ? g_object_ref (dest) : NULL;
+ data->mode = mode;
+ data->search_string = search_string ? g_strdup (search_string) : NULL;
+ data->timestamp = timestamp;
+
+ g_dbus_connection_call (application->connection,
+ EVINCE_DAEMON_SERVICE,
+ EVINCE_DAEMON_OBJECT_PATH,
+ EVINCE_DAEMON_INTERFACE,
+ "RegisterDocument",
+ g_variant_new ("(s)", uri),
+ G_VARIANT_TYPE ("(s)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ on_register_uri_cb,
+ data);
}
static void
@@ -453,23 +583,26 @@ ev_application_unregister_uri (EvApplication *application,
const gchar *uri)
{
GVariant *value;
- GError *error = NULL;
+ GError *error = NULL;
- if (!application->connection)
+ if (!application->doc_registered)
return;
- /* FIXME: Don't make sync dbus calls, they block the UI! */
- value = g_dbus_connection_call_sync
- (application->connection,
- "org.gnome.evince.Daemon",
- "/org/gnome/evince/Daemon",
- "org.gnome.evince.Daemon",
- "UnregisterDocument",
- g_variant_new ("(s)", uri),
- G_DBUS_CALL_FLAGS_NO_AUTO_START,
- -1,
- NULL,
- &error);
+ /* This is called from ev_application_shutdown(),
+ * so it's safe to use the sync api
+ */
+ value = g_dbus_connection_call_sync (
+ application->connection,
+ EVINCE_DAEMON_SERVICE,
+ EVINCE_DAEMON_OBJECT_PATH,
+ EVINCE_DAEMON_INTERFACE,
+ "UnregisterDocument",
+ g_variant_new ("(s)", uri),
+ NULL,
+ G_DBUS_CALL_FLAGS_NO_AUTO_START,
+ -1,
+ NULL,
+ &error);
if (value == NULL) {
g_warning ("Error unregistering document: %s\n", error->message);
g_error_free (error);
@@ -518,6 +651,27 @@ ev_application_open_uri_in_window (EvApplication *application,
#endif /* GDK_WINDOWING_X11 */
}
+static void
+_ev_application_open_uri_at_dest (EvApplication *application,
+ const gchar *uri,
+ GdkScreen *screen,
+ EvLinkDest *dest,
+ EvWindowRunMode mode,
+ const gchar *search_string,
+ guint timestamp)
+{
+ EvWindow *ev_window;
+
+ ev_window = ev_application_get_empty_window (application, screen);
+ if (!ev_window)
+ ev_window = EV_WINDOW (ev_window_new ());
+
+ ev_application_open_uri_in_window (application, uri, ev_window,
+ screen, dest, mode,
+ search_string,
+ timestamp);
+}
+
/**
* ev_application_open_uri_at_dest:
* @application: The instance of the application.
@@ -536,37 +690,24 @@ ev_application_open_uri_at_dest (EvApplication *application,
const gchar *search_string,
guint timestamp)
{
- EvWindow *ev_window;
-
g_return_if_fail (uri != NULL);
if (application->uri && strcmp (application->uri, uri) != 0) {
/* spawn a new evince process */
ev_spawn (uri, screen, dest, mode, search_string, timestamp);
return;
- } else {
-#ifdef ENABLE_DBUS
- gboolean ret;
-
- /* Register the uri or send OpenURI to
- * remote instance if already registered
- */
- ret = ev_application_register_uri (application, uri, screen, dest, mode, search_string, timestamp);
- if (!ret)
- return;
-#endif /* ENABLE_DBUS */
-
- ev_window = ev_application_get_empty_window (application, screen);
- if (!ev_window)
- ev_window = EV_WINDOW (ev_window_new ());
+ } else if (!application->uri) {
+ application->uri = g_strdup (uri);
}
- application->uri = g_strdup (uri);
-
- ev_application_open_uri_in_window (application, uri, ev_window,
- screen, dest, mode,
- search_string,
- timestamp);
+#ifdef ENABLE_DBUS
+ /* Register the uri or send Reload to
+ * remote instance if already registered
+ */
+ ev_application_register_uri (application, uri, screen, dest, mode, search_string, timestamp);
+#else
+ _ev_application_open_uri_at_dest (application, uri, screen, dest, mode, search_string, timestamp);
+#endif /* ENABLE_DBUS */
}
/**
@@ -607,6 +748,7 @@ ev_application_open_window (EvApplication *application,
#endif /* GDK_WINDOWING_X11 */
}
+#ifdef ENABLE_DBUS
static void
method_call_cb (GDBusConnection *connection,
const gchar *sender,
@@ -619,7 +761,6 @@ method_call_cb (GDBusConnection *connection,
{
EvApplication *application = EV_APPLICATION (user_data);
GList *windows, *l;
- const gchar *uri;
guint timestamp;
GVariantIter *iter;
const gchar *key;
@@ -631,64 +772,92 @@ method_call_cb (GDBusConnection *connection,
const gchar *search_string = NULL;
GdkScreen *screen = NULL;
- if (g_strcmp0 (method_name, "OpenURI") != 0)
- return;
+ if (g_strcmp0 (method_name, "Reload") == 0) {
+ g_variant_get (parameters, "(a{sv}u)", &iter, ×tamp);
+
+ while (g_variant_iter_loop (iter, "{&sv}", &key, &value)) {
+ if (strcmp (key, "display") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
+ display = ev_display_open_if_needed (g_variant_get_string (value, NULL));
+ } else if (strcmp (key, "screen") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_INT32) {
+ screen_number = g_variant_get_int32 (value);
+ } else if (strcmp (key, "mode") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_UINT32) {
+ mode = g_variant_get_uint32 (value);
+ } else if (strcmp (key, "page-label") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
+ dest = ev_link_dest_new_page_label (g_variant_get_string (value, NULL));
+ } else if (strcmp (key, "page-index") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_UINT32) {
+ dest = ev_link_dest_new_page (g_variant_get_uint32 (value));
+ } else if (strcmp (key, "find-string") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
+ search_string = g_variant_get_string (value, NULL);
+ }
+ }
+ g_variant_iter_free (iter);
- g_variant_get (parameters, "(&sa{sv}u)", &uri, &iter, ×tamp);
+ if (display != NULL &&
+ screen_number >= 0 &&
+ screen_number < gdk_display_get_n_screens (display))
+ screen = gdk_display_get_screen (display, screen_number);
+ else
+ screen = gdk_screen_get_default ();
- /* FIXME: we don't need uri anymore,
- * maybe this method should be renamed
- * as reload, refresh or something like that
- */
- if (g_strcmp0 (application->uri, uri) != 0) {
- g_dbus_method_invocation_return_error (invocation,
- G_DBUS_ERROR,
- G_DBUS_ERROR_INVALID_ARGS,
- "Unexpected URI \"%s\"",
- uri);
- g_variant_iter_free (iter);
- return;
- }
+ windows = ev_application_get_windows (application);
+ for (l = windows; l != NULL; l = g_list_next (l)) {
+ EvWindow *ev_window = EV_WINDOW (l->data);
- while (g_variant_iter_loop (iter, "{&sv}", &key, &value)) {
- if (strcmp (key, "display") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
- display = ev_display_open_if_needed (g_variant_get_string (value, NULL));
- } else if (strcmp (key, "screen") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
- screen_number = g_variant_get_int32 (value);
- } else if (strcmp (key, "mode") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_UINT32) {
- mode = g_variant_get_uint32 (value);
- } else if (strcmp (key, "page-label") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
- dest = ev_link_dest_new_page_label (g_variant_get_string (value, NULL));
- } else if (strcmp (key, "find-string") == 0 && g_variant_classify (value) == G_VARIANT_CLASS_STRING) {
- search_string = g_variant_get_string (value, NULL);
- }
- }
- g_variant_iter_free (iter);
-
- if (display != NULL &&
- screen_number >= 0 &&
- screen_number < gdk_display_get_n_screens (display))
- screen = gdk_display_get_screen (display, screen_number);
- else
- screen = gdk_screen_get_default ();
-
- windows = ev_application_get_windows (application);
- for (l = windows; l != NULL; l = g_list_next (l)) {
- EvWindow *ev_window = EV_WINDOW (l->data);
-
- ev_application_open_uri_in_window (application, uri, ev_window,
- screen, dest, mode,
- search_string,
- timestamp);
- }
- g_list_free (windows);
+ ev_application_open_uri_in_window (application, application->uri,
+ ev_window,
+ screen, dest, mode,
+ search_string,
+ timestamp);
+ }
+ g_list_free (windows);
+
+ if (dest)
+ g_object_unref (dest);
+
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
+ } else if (g_strcmp0 (method_name, "GetWindowList") == 0) {
+ GList *windows = ev_application_get_windows (application);
+ GVariantBuilder builder;
+ GList *l;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("(ao)"));
+ g_variant_builder_open (&builder, G_VARIANT_TYPE ("ao"));
+
+ for (l = windows; l; l = g_list_next (l)) {
+ EvWindow *window = (EvWindow *)l->data;
+
+ g_variant_builder_add (&builder, "o", ev_window_get_dbus_object_path (window));
+ }
- if (dest)
- g_object_unref (dest);
+ g_variant_builder_close (&builder);
+ g_list_free (windows);
- g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
+ g_dbus_method_invocation_return_value (invocation, g_variant_builder_end (&builder));
+ }
}
+static const char introspection_xml[] =
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ "";
+
+static const GDBusInterfaceVTable interface_vtable = {
+ method_call_cb,
+ NULL,
+ NULL
+};
+
+static GDBusNodeInfo *introspection_data;
+#endif /* ENABLE_DBUS */
+
void
ev_application_open_uri_list (EvApplication *application,
GSList *uri_list,
@@ -711,15 +880,7 @@ ev_application_accel_map_save (EvApplication *application)
gchar *tmp_filename;
gint fd;
- if (userdir) {
- accel_map_file = g_build_filename (userdir, "accels",
- "evince", NULL);
- } else {
- accel_map_file = g_build_filename (g_get_home_dir (),
- ".gnome2", "accels",
- "evince", NULL);
- }
-
+ accel_map_file = g_build_filename (application->dot_dir, "accels", NULL);
tmp_filename = g_strdup_printf ("%s.XXXXXX", accel_map_file);
fd = g_mkstemp (tmp_filename);
@@ -732,6 +893,7 @@ ev_application_accel_map_save (EvApplication *application)
gtk_accel_map_save_fd (fd);
close (fd);
+ g_mkdir_with_parents (application->dot_dir, 0700);
if (g_rename (tmp_filename, accel_map_file) == -1) {
/* FIXME: win32? */
g_unlink (tmp_filename);
@@ -746,19 +908,107 @@ ev_application_accel_map_load (EvApplication *application)
{
gchar *accel_map_file;
- if (userdir) {
- accel_map_file = g_build_filename (userdir, "accels",
- "evince", NULL);
- } else {
- accel_map_file = g_build_filename (g_get_home_dir (),
- ".gnome2", "accels",
- "evince", NULL);
- }
-
+ accel_map_file = g_build_filename (application->dot_dir, "accels", NULL);
gtk_accel_map_load (accel_map_file);
g_free (accel_map_file);
}
+static void
+ev_application_migrate_config_dir (EvApplication *application)
+{
+ const gchar *userdir;
+ gchar *old_dot_dir;
+ gchar *old_accels;
+ GError *error;
+ gint i;
+ gboolean dir_created = FALSE;
+ static const gchar *config_files[] = {
+ "evince_toolbar.xml",
+ "print-settings",
+ NULL
+ };
+
+ userdir = g_getenv ("GNOME22_USER_DIR");
+ if (userdir) {
+ old_dot_dir = g_build_filename (userdir, "evince", NULL);
+ old_accels = g_build_filename (userdir, "accels", "evince", NULL);
+ } else {
+ old_dot_dir = g_build_filename (g_get_home_dir (),
+ ".gnome2",
+ "evince",
+ NULL);
+ old_accels = g_build_filename (g_get_home_dir (),
+ ".gnome2", "accels",
+ "evince", NULL);
+ }
+
+ if (g_file_test (old_dot_dir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
+ for (i = 0; config_files[i]; i++) {
+ gchar *old_filename;
+ gchar *new_filename;
+ GFile *old_file;
+ GFile *new_file;
+
+ old_filename = g_build_filename (old_dot_dir, config_files[i], NULL);
+ if (!g_file_test (old_filename, G_FILE_TEST_EXISTS)) {
+ g_free (old_filename);
+ continue;
+ }
+
+ if (!dir_created) {
+ g_mkdir_with_parents (application->dot_dir, 0700);
+ dir_created = TRUE;
+ }
+
+ new_filename = g_build_filename (application->dot_dir, config_files[i], NULL);
+ old_file = g_file_new_for_path (old_filename);
+ new_file = g_file_new_for_path (new_filename);
+
+ error = NULL;
+ g_file_move (old_file, new_file, 0, NULL, NULL, NULL, &error);
+ if (error) {
+ g_warning ("Error migrating config file %s: %s\n",
+ old_filename, error->message);
+ g_error_free (error);
+ }
+
+ g_free (old_filename);
+ g_free (new_filename);
+ g_object_unref (old_file);
+ g_object_unref (new_file);
+ }
+ }
+
+ g_free (old_dot_dir);
+
+ if (g_file_test (old_accels, G_FILE_TEST_EXISTS)) {
+ gchar *new_accels;
+ GFile *old_accels_file;
+ GFile *new_accels_file;
+
+ if (!dir_created)
+ g_mkdir_with_parents (application->dot_dir, 0700);
+
+ new_accels = g_build_filename (application->dot_dir, "accels", NULL);
+ old_accels_file = g_file_new_for_path (old_accels);
+ new_accels_file = g_file_new_for_path (new_accels);
+
+ error = NULL;
+ g_file_move (old_accels_file, new_accels_file, 0, NULL, NULL, NULL, &error);
+ if (error) {
+ g_warning ("Error migrating accelerator specifications file %s: %s\n",
+ old_accels, error->message);
+ g_error_free (error);
+ }
+
+ g_free (new_accels);
+ g_object_unref (old_accels_file);
+ g_object_unref (new_accels_file);
+ }
+
+ g_free (old_accels);
+}
+
void
ev_application_shutdown (EvApplication *application)
{
@@ -790,6 +1040,10 @@ ev_application_shutdown (EvApplication *application)
g_object_unref (application->connection);
application->connection = NULL;
}
+ if (introspection_data) {
+ g_dbus_node_info_ref (introspection_data);
+ introspection_data = NULL;
+ }
#endif /* ENABLE_DBUS */
g_free (application->dot_dir);
@@ -817,14 +1071,10 @@ ev_application_init (EvApplication *ev_application)
{
GError *error = NULL;
- userdir = g_getenv ("GNOME22_USER_DIR");
- if (userdir)
- ev_application->dot_dir = g_build_filename (userdir, "evince", NULL);
- else
- ev_application->dot_dir = g_build_filename (g_get_home_dir (),
- ".gnome2",
- "evince",
- NULL);
+ ev_application->dot_dir = g_build_filename (g_get_user_config_dir (),
+ "evince", NULL);
+ if (!g_file_test (ev_application->dot_dir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
+ ev_application_migrate_config_dir (ev_application);
#ifdef G_OS_WIN32
{
@@ -835,7 +1085,7 @@ ev_application_init (EvApplication *ev_application)
g_free (dir);
}
#else
- ev_application->data_dir = g_strdup (DATADIR);
+ ev_application->data_dir = g_strdup (EVINCEDATADIR);
#endif
ev_application_init_session (ev_application);
@@ -843,32 +1093,11 @@ ev_application_init (EvApplication *ev_application)
ev_application_accel_map_load (ev_application);
#ifdef ENABLE_DBUS
-{
- static const char introspection_xml[] =
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- "";
-
- static const GDBusInterfaceVTable interface_vtable = {
- method_call_cb,
- NULL,
- NULL
- };
-
- GDBusNodeInfo *introspection_data;
-
ev_application->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
if (ev_application->connection != NULL) {
introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
g_assert (introspection_data != NULL);
-
ev_application->registration_id =
g_dbus_connection_register_object (ev_application->connection,
APPLICATION_DBUS_OBJECT_PATH,
@@ -880,28 +1109,62 @@ ev_application_init (EvApplication *ev_application)
g_printerr ("Failed to register bus object: %s\n", error->message);
g_error_free (error);
}
-
} else {
g_printerr ("Failed to get bus connection: %s\n", error->message);
g_error_free (error);
}
- ev_application->keys = ev_media_player_keys_new (ev_application->connection);
+ ev_application->keys = ev_media_player_keys_new ();
+#endif /* ENABLE_DBUS */
ev_application->scr_saver = totem_scrsaver_new ();
+ g_object_set (ev_application->scr_saver,
+ "reason", _("Running in presentation mode"),
+ NULL);
}
+
+GDBusConnection *
+ev_application_get_dbus_connection (EvApplication *application)
+{
+#ifdef ENABLE_DBUS
+ return application->connection;
#else
- ev_application->scr_saver = totem_scrsaver_new (NULL);
-#endif /* ENABLE_DBUS */
+ return NULL;
+#endif
}
gboolean
ev_application_has_window (EvApplication *application)
{
- GList *windows = ev_application_get_windows (application);
- gboolean retval = windows != NULL;
+ GList *l, *toplevels;
+ gboolean retval = FALSE;
- g_list_free (windows);
+ toplevels = gtk_window_list_toplevels ();
+
+ for (l = toplevels; l != NULL && !retval; l = l->next) {
+ if (EV_IS_WINDOW (l->data))
+ retval = TRUE;
+ }
+
+ g_list_free (toplevels);
+
+ return retval;
+}
+
+guint
+ev_application_get_n_windows (EvApplication *application)
+{
+ GList *l, *toplevels;
+ guint retval = 0;
+
+ toplevels = gtk_window_list_toplevels ();
+
+ for (l = toplevels; l != NULL; l = l->next) {
+ if (EV_IS_WINDOW (l->data))
+ retval++;
+ }
+
+ g_list_free (toplevels);
return retval;
}