+static void
+removed_from_session (GnomeClient *client, EvApplication *application)
+{
+ ev_application_shutdown (application);
+}
+
+static gint
+save_session (GnomeClient *client, gint phase, GnomeSaveStyle save_style, gint shutdown,
+ GnomeInteractStyle interact_style, gint fast, EvApplication *application)
+{
+ GList *windows, *l;
+ char **restart_argv;
+ int argc = 0, k;
+
+ windows = ev_application_get_windows (application);
+ restart_argv = g_new (char *, g_list_length (windows) + 1);
+ restart_argv[argc++] = g_strdup ("evince");
+
+ for (l = windows; l != NULL; l = l->next) {
+ EvWindow *window = EV_WINDOW (l->data);
+ restart_argv[argc++] = g_strdup (ev_window_get_uri (window));
+ }
+
+ gnome_client_set_restart_command (client, argc, restart_argv);
+
+ for (k = 0; k < argc; k++) {
+ g_free (restart_argv[k]);
+ }
+
+ g_list_free (windows);
+ g_free (restart_argv);
+
+ return TRUE;
+}
+
+static void
+init_session (EvApplication *application)
+{
+ GnomeClient *client;
+
+ client = gnome_master_client ();
+
+ g_signal_connect (client, "save_yourself",
+ G_CALLBACK (save_session), application);
+ g_signal_connect (client, "die",
+ G_CALLBACK (removed_from_session), application);
+}
+
+static GdkDisplay *
+ev_display_open_if_needed (const gchar *name)
+{
+ GSList *displays;
+ GSList *l;
+ GdkDisplay *display = NULL;
+
+ displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
+
+ for (l = displays; l != NULL; l = l->next) {
+ const gchar *display_name = gdk_display_get_name ((GdkDisplay *) l->data);
+
+ if (g_ascii_strcasecmp (display_name, name) == 0) {
+ display = l->data;
+ break;
+ }
+ }
+
+ g_slist_free (displays);
+
+ return display != NULL ? display : gdk_display_open (name);
+}
+
+static GdkScreen *
+get_screen_from_args (GHashTable *args)
+{
+ GValue *value = NULL;
+ GdkDisplay *display = NULL;
+ GdkScreen *screen = NULL;
+
+ g_assert (args != NULL);
+
+ value = g_hash_table_lookup (args, "display");
+ if (value) {
+ const gchar *display_name;
+
+ display_name = g_value_get_string (value);
+ display = ev_display_open_if_needed (display_name);
+ }
+
+ value = g_hash_table_lookup (args, "screen");
+ if (value) {
+ gint screen_number;
+
+ screen_number = g_value_get_int (value);
+ screen = gdk_display_get_screen (display, screen_number);
+ }
+
+ return screen;
+}
+
+static EvWindowRunMode
+get_window_run_mode_from_args (GHashTable *args)
+{
+ EvWindowRunMode mode = EV_WINDOW_MODE_NORMAL;
+ GValue *value = NULL;
+
+ g_assert (args != NULL);
+
+ value = g_hash_table_lookup (args, "mode");
+ if (value) {
+ mode = g_value_get_uint (value);
+ }
+
+ return mode;
+}
+
+static EvLinkDest *
+get_destination_from_args (GHashTable *args)
+{
+ EvLinkDest *dest = NULL;
+ GValue *value = NULL;
+
+ g_assert (args != NULL);
+
+ value = g_hash_table_lookup (args, "page-label");
+ if (value) {
+ const gchar *page_label;
+
+ page_label = g_value_get_string (value);
+ dest = ev_link_dest_new_page_label (page_label);
+ }
+
+ return dest;
+}
+
+static gboolean
+get_unlink_temp_file_from_args (GHashTable *args)
+{
+ gboolean unlink_temp_file = FALSE;
+ GValue *value = NULL;
+
+ g_assert (args != NULL);
+
+ value = g_hash_table_lookup (args, "unlink-temp-file");
+ if (value) {
+ unlink_temp_file = g_value_get_boolean (value);
+ }
+
+ return unlink_temp_file;
+}
+
+gboolean
+ev_application_open_window (EvApplication *application,
+ GHashTable *args,
+ guint32 timestamp,
+ GError **error)