summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCosimo Cecchi <cosimoc@gnome.org>2010-12-20 18:39:24 +0100
committerCosimo Cecchi <cosimoc@gnome.org>2010-12-20 19:07:49 +0100
commitf42d5aa97de09de7052fa80abda62fabe17dfb13 (patch)
tree63d45cfab65c6c4c6ae9c578822b9b5b5202593f
parentee06a67a632476b9758cc00eaa573e12cc3cfc91 (diff)
downloadnautilus-f42d5aa97de09de7052fa80abda62fabe17dfb13.tar.gz
smclient: remove XSMP support
EggSmClient is not well-maintained, and it doesn't seem like it will ever hit GTK+, and the overall implementation seems to be poorly tested and buggy. Moreover, moving to 3.0 with nautilus being an application, it makes less sense to have it save opened windows state, as it might not be always running at all.
-rw-r--r--cut-n-paste-code/libegg/Makefile.am17
-rw-r--r--cut-n-paste-code/libegg/eggdesktopfile.c1475
-rw-r--r--cut-n-paste-code/libegg/eggdesktopfile.h159
-rw-r--r--cut-n-paste-code/libegg/eggsmclient-private.h53
-rw-r--r--cut-n-paste-code/libegg/eggsmclient-xsmp.c1370
-rw-r--r--cut-n-paste-code/libegg/eggsmclient.c609
-rw-r--r--cut-n-paste-code/libegg/eggsmclient.h117
-rw-r--r--po/POTFILES.in2
-rw-r--r--src/Makefile.am2
-rw-r--r--src/nautilus-application-smclient.c459
-rw-r--r--src/nautilus-application-smclient.h33
-rw-r--r--src/nautilus-application.c14
-rw-r--r--src/nautilus-application.h2
-rw-r--r--src/nautilus-main.c5
14 files changed, 1 insertions, 4316 deletions
diff --git a/cut-n-paste-code/libegg/Makefile.am b/cut-n-paste-code/libegg/Makefile.am
index ea39f639e..fff263f4b 100644
--- a/cut-n-paste-code/libegg/Makefile.am
+++ b/cut-n-paste-code/libegg/Makefile.am
@@ -9,38 +9,23 @@ EGG_TREE_DND_FILES = \
eggtreemultidnd.h \
$(NULL)
-EGG_SMCLIENT_FILES = \
- eggdesktopfile.c \
- eggdesktopfile.h \
- eggsmclient.c \
- eggsmclient.h \
- eggsmclient-private.h \
- eggsmclient-xsmp.c \
- $(NULL)
-
libegg_la_SOURCES = \
$(EGG_TREE_DND_FILES) \
- $(EGG_SMCLIENT_FILES) \
$(NULL)
libegg_la_CFLAGS = \
- -DEGG_SM_CLIENT_BACKEND_XSMP \
- -DG_LOG_DOMAIN=\""EggSMClient"\" \
$(BASE_CFLAGS) \
$(WARNING_CFLAGS) \
$(DISABLE_DEPRECATED)
libegg_la_LIBADD = \
- $(LIBEGG_LIBS) \
- -lSM -lICE
+ $(BASE_LIBS)
EXTRA_DIST = \
update-from-egg.sh \
$(NULL)
EGG_TREE_DND_DIR = $(srcdir)/../../../libegg/libegg/treeviewutils
-EGG_SMCLIENT_DIR = $(srcdir)/../../../libegg/libegg/smclient
regenerate-built-sources:
EGGFILES="$(EGG_TREE_DND_FILES)" EGGDIR="$(EGG_TREE_DND_DIR)" $(srcdir)/update-from-egg.sh
- EGGFILES="$(EGG_SMCLIENT_FILES)" EGGDIR="$(EGG_SMCLIENT_DIR)" $(srcdir)/update-from-egg.sh
diff --git a/cut-n-paste-code/libegg/eggdesktopfile.c b/cut-n-paste-code/libegg/eggdesktopfile.c
deleted file mode 100644
index 5578a62ac..000000000
--- a/cut-n-paste-code/libegg/eggdesktopfile.c
+++ /dev/null
@@ -1,1475 +0,0 @@
-/* eggdesktopfile.c - Freedesktop.Org Desktop Files
- * Copyright (C) 2007 Novell, Inc.
- *
- * Based on gnome-desktop-item.c
- * Copyright (C) 1999, 2000 Red Hat Inc.
- * Copyright (C) 2001 George Lebl
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place -
- * Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "eggdesktopfile.h"
-
-#include <string.h>
-#include <unistd.h>
-
-#include <glib/gi18n.h>
-#include <gdk/gdkx.h>
-#include <gtk/gtk.h>
-
-struct EggDesktopFile {
- GKeyFile *key_file;
- char *source;
-
- char *name, *icon;
- EggDesktopFileType type;
- char document_code;
-};
-
-/**
- * egg_desktop_file_new:
- * @desktop_file_path: path to a Freedesktop-style Desktop file
- * @error: error pointer
- *
- * Creates a new #EggDesktopFile for @desktop_file.
- *
- * Return value: the new #EggDesktopFile, or %NULL on error.
- **/
-EggDesktopFile *
-egg_desktop_file_new (const char *desktop_file_path, GError **error)
-{
- GKeyFile *key_file;
-
- key_file = g_key_file_new ();
- if (!g_key_file_load_from_file (key_file, desktop_file_path, 0, error))
- {
- g_key_file_free (key_file);
- return NULL;
- }
-
- return egg_desktop_file_new_from_key_file (key_file, desktop_file_path,
- error);
-}
-
-/**
- * egg_desktop_file_new_from_data_dirs:
- * @desktop_file_path: relative path to a Freedesktop-style Desktop file
- * @error: error pointer
- *
- * Looks for @desktop_file_path in the paths returned from
- * g_get_user_data_dir() and g_get_system_data_dirs(), and creates
- * a new #EggDesktopFile from it.
- *
- * Return value: the new #EggDesktopFile, or %NULL on error.
- **/
-EggDesktopFile *
-egg_desktop_file_new_from_data_dirs (const char *desktop_file_path,
- GError **error)
-{
- EggDesktopFile *desktop_file;
- GKeyFile *key_file;
- char *full_path;
-
- key_file = g_key_file_new ();
- if (!g_key_file_load_from_data_dirs (key_file, desktop_file_path,
- &full_path, 0, error))
- {
- g_key_file_free (key_file);
- return NULL;
- }
-
- desktop_file = egg_desktop_file_new_from_key_file (key_file,
- full_path,
- error);
- g_free (full_path);
- return desktop_file;
-}
-
-/**
- * egg_desktop_file_new_from_dirs:
- * @desktop_file_path: relative path to a Freedesktop-style Desktop file
- * @search_dirs: NULL-terminated array of directories to search
- * @error: error pointer
- *
- * Looks for @desktop_file_path in the paths returned from
- * g_get_user_data_dir() and g_get_system_data_dirs(), and creates
- * a new #EggDesktopFile from it.
- *
- * Return value: the new #EggDesktopFile, or %NULL on error.
- **/
-EggDesktopFile *
-egg_desktop_file_new_from_dirs (const char *desktop_file_path,
- const char **search_dirs,
- GError **error)
-{
- EggDesktopFile *desktop_file;
- GKeyFile *key_file;
- char *full_path;
-
- key_file = g_key_file_new ();
- if (!g_key_file_load_from_dirs (key_file, desktop_file_path, search_dirs,
- &full_path, 0, error))
- {
- g_key_file_free (key_file);
- return NULL;
- }
-
- desktop_file = egg_desktop_file_new_from_key_file (key_file,
- full_path,
- error);
- g_free (full_path);
- return desktop_file;
-}
-
-/**
- * egg_desktop_file_new_from_key_file:
- * @key_file: a #GKeyFile representing a desktop file
- * @source: the path or URI that @key_file was loaded from, or %NULL
- * @error: error pointer
- *
- * Creates a new #EggDesktopFile for @key_file. Assumes ownership of
- * @key_file (on success or failure); you should consider @key_file to
- * be freed after calling this function.
- *
- * Return value: the new #EggDesktopFile, or %NULL on error.
- **/
-EggDesktopFile *
-egg_desktop_file_new_from_key_file (GKeyFile *key_file,
- const char *source,
- GError **error)
-{
- EggDesktopFile *desktop_file;
- char *version, *type;
-
- if (!g_key_file_has_group (key_file, EGG_DESKTOP_FILE_GROUP))
- {
- g_set_error (error, EGG_DESKTOP_FILE_ERROR,
- EGG_DESKTOP_FILE_ERROR_INVALID,
- _("File is not a valid .desktop file"));
- g_key_file_free (key_file);
- return NULL;
- }
-
- version = g_key_file_get_value (key_file, EGG_DESKTOP_FILE_GROUP,
- EGG_DESKTOP_FILE_KEY_VERSION,
- NULL);
- if (version)
- {
- double version_num;
- char *end;
-
- version_num = g_ascii_strtod (version, &end);
- if (*end)
- {
- g_warning ("Invalid Version string '%s' in %s",
- version, source ? source : "(unknown)");
- }
- else if (version_num > 1.0)
- {
- g_set_error (error, EGG_DESKTOP_FILE_ERROR,
- EGG_DESKTOP_FILE_ERROR_INVALID,
- _("Unrecognized desktop file Version '%s'"), version);
- g_free (version);
- g_key_file_free (key_file);
- return NULL;
- }
- g_free (version);
- }
-
- desktop_file = g_new0 (EggDesktopFile, 1);
- desktop_file->key_file = key_file;
-
- if (g_path_is_absolute (source))
- desktop_file->source = g_filename_to_uri (source, NULL, NULL);
- else
- desktop_file->source = g_strdup (source);
-
- desktop_file->name = g_key_file_get_string (key_file, EGG_DESKTOP_FILE_GROUP,
- EGG_DESKTOP_FILE_KEY_NAME, error);
- if (!desktop_file->name)
- {
- egg_desktop_file_free (desktop_file);
- return NULL;
- }
-
- type = g_key_file_get_string (key_file, EGG_DESKTOP_FILE_GROUP,
- EGG_DESKTOP_FILE_KEY_TYPE, error);
- if (!type)
- {
- egg_desktop_file_free (desktop_file);
- return NULL;
- }
-
- if (!strcmp (type, "Application"))
- {
- char *exec, *p;
-
- desktop_file->type = EGG_DESKTOP_FILE_TYPE_APPLICATION;
-
- exec = g_key_file_get_string (key_file,
- EGG_DESKTOP_FILE_GROUP,
- EGG_DESKTOP_FILE_KEY_EXEC,
- error);
- if (!exec)
- {
- egg_desktop_file_free (desktop_file);
- g_free (type);
- return NULL;
- }
-
- /* See if it takes paths or URIs or neither */
- for (p = exec; *p; p++)
- {
- if (*p == '%')
- {
- if (p[1] == '\0' || strchr ("FfUu", p[1]))
- {
- desktop_file->document_code = p[1];
- break;
- }
- p++;
- }
- }
-
- g_free (exec);
- }
- else if (!strcmp (type, "Link"))
- {
- char *url;
-
- desktop_file->type = EGG_DESKTOP_FILE_TYPE_LINK;
-
- url = g_key_file_get_string (key_file,
- EGG_DESKTOP_FILE_GROUP,
- EGG_DESKTOP_FILE_KEY_URL,
- error);
- if (!url)
- {
- egg_desktop_file_free (desktop_file);
- g_free (type);
- return NULL;
- }
- g_free (url);
- }
- else if (!strcmp (type, "Directory"))
- desktop_file->type = EGG_DESKTOP_FILE_TYPE_DIRECTORY;
- else
- desktop_file->type = EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED;
-
- g_free (type);
-
- /* Check the Icon key */
- desktop_file->icon = g_key_file_get_string (key_file,
- EGG_DESKTOP_FILE_GROUP,
- EGG_DESKTOP_FILE_KEY_ICON,
- NULL);
- if (desktop_file->icon && !g_path_is_absolute (desktop_file->icon))
- {
- char *ext;
-
- /* Lots of .desktop files still get this wrong */
- ext = strrchr (desktop_file->icon, '.');
- if (ext && (!strcmp (ext, ".png") ||
- !strcmp (ext, ".xpm") ||
- !strcmp (ext, ".svg")))
- {
- g_warning ("Desktop file '%s' has malformed Icon key '%s'"
- "(should not include extension)",
- source ? source : "(unknown)",
- desktop_file->icon);
- *ext = '\0';
- }
- }
-
- return desktop_file;
-}
-
-/**
- * egg_desktop_file_free:
- * @desktop_file: an #EggDesktopFile
- *
- * Frees @desktop_file.
- **/
-void
-egg_desktop_file_free (EggDesktopFile *desktop_file)
-{
- g_key_file_free (desktop_file->key_file);
- g_free (desktop_file->source);
- g_free (desktop_file->name);
- g_free (desktop_file->icon);
- g_free (desktop_file);
-}
-
-/**
- * egg_desktop_file_get_source:
- * @desktop_file: an #EggDesktopFile
- *
- * Gets the URI that @desktop_file was loaded from.
- *
- * Return value: @desktop_file's source URI
- **/
-const char *
-egg_desktop_file_get_source (EggDesktopFile *desktop_file)
-{
- return desktop_file->source;
-}
-
-/**
- * egg_desktop_file_get_desktop_file_type:
- * @desktop_file: an #EggDesktopFile
- *
- * Gets the desktop file type of @desktop_file.
- *
- * Return value: @desktop_file's type
- **/
-EggDesktopFileType
-egg_desktop_file_get_desktop_file_type (EggDesktopFile *desktop_file)
-{
- return desktop_file->type;
-}
-
-/**
- * egg_desktop_file_get_name:
- * @desktop_file: an #EggDesktopFile
- *
- * Gets the (localized) value of @desktop_file's "Name" key.
- *
- * Return value: the application/link name
- **/
-const char *
-egg_desktop_file_get_name (EggDesktopFile *desktop_file)
-{
- return desktop_file->name;
-}
-
-/**
- * egg_desktop_file_get_icon:
- * @desktop_file: an #EggDesktopFile
- *
- * Gets the value of @desktop_file's "Icon" key.
- *
- * If the icon string is a full path (that is, if g_path_is_absolute()
- * returns %TRUE when called on it), it points to a file containing an
- * unthemed icon. If the icon string is not a full path, it is the
- * name of a themed icon, which can be looked up with %GtkIconTheme,
- * or passed directly to a theme-aware widget like %GtkImage or
- * %GtkCellRendererPixbuf.
- *
- * Return value: the icon path or name
- **/
-const char *
-egg_desktop_file_get_icon (EggDesktopFile *desktop_file)
-{
- return desktop_file->icon;
-}
-
-gboolean
-egg_desktop_file_has_key (EggDesktopFile *desktop_file,
- const char *key,
- GError **error)
-{
- return g_key_file_has_key (desktop_file->key_file,
- EGG_DESKTOP_FILE_GROUP, key,
- error);
-}
-
-char *
-egg_desktop_file_get_string (EggDesktopFile *desktop_file,
- const char *key,
- GError **error)
-{
- return g_key_file_get_string (desktop_file->key_file,
- EGG_DESKTOP_FILE_GROUP, key,
- error);
-}
-
-char *
-egg_desktop_file_get_locale_string (EggDesktopFile *desktop_file,
- const char *key,
- const char *locale,
- GError **error)
-{
- return g_key_file_get_locale_string (desktop_file->key_file,
- EGG_DESKTOP_FILE_GROUP, key, locale,
- error);
-}
-
-gboolean
-egg_desktop_file_get_boolean (EggDesktopFile *desktop_file,
- const char *key,
- GError **error)
-{
- return g_key_file_get_boolean (desktop_file->key_file,
- EGG_DESKTOP_FILE_GROUP, key,
- error);
-}
-
-double
-egg_desktop_file_get_numeric (EggDesktopFile *desktop_file,
- const char *key,
- GError **error)
-{
- return g_key_file_get_double (desktop_file->key_file,
- EGG_DESKTOP_FILE_GROUP, key,
- error);
-}
-
-char **
-egg_desktop_file_get_string_list (EggDesktopFile *desktop_file,
- const char *key,
- gsize *length,
- GError **error)
-{
- return g_key_file_get_string_list (desktop_file->key_file,
- EGG_DESKTOP_FILE_GROUP, key, length,
- error);
-}
-
-char **
-egg_desktop_file_get_locale_string_list (EggDesktopFile *desktop_file,
- const char *key,
- const char *locale,
- gsize *length,
- GError **error)
-{
- return g_key_file_get_locale_string_list (desktop_file->key_file,
- EGG_DESKTOP_FILE_GROUP, key,
- locale, length,
- error);
-}
-
-/**
- * egg_desktop_file_can_launch:
- * @desktop_file: an #EggDesktopFile
- * @desktop_environment: the name of the running desktop environment,
- * or %NULL
- *
- * Tests if @desktop_file can/should be launched in the current
- * environment. If @desktop_environment is non-%NULL, @desktop_file's
- * "OnlyShowIn" and "NotShowIn" keys are checked to make sure that
- * this desktop_file is appropriate for the named environment.
- *
- * Furthermore, if @desktop_file has type
- * %EGG_DESKTOP_FILE_TYPE_APPLICATION, its "TryExec" key (if any) is
- * also checked, to make sure the binary it points to exists.
- *
- * egg_desktop_file_can_launch() does NOT check the value of the
- * "Hidden" key.
- *
- * Return value: %TRUE if @desktop_file can be launched
- **/
-gboolean
-egg_desktop_file_can_launch (EggDesktopFile *desktop_file,
- const char *desktop_environment)
-{
- char *try_exec, *found_program;
- char **only_show_in, **not_show_in;
- gboolean found;
- int i;
-
- if (desktop_file->type != EGG_DESKTOP_FILE_TYPE_APPLICATION &&
- desktop_file->type != EGG_DESKTOP_FILE_TYPE_LINK)
- return FALSE;
-
- if (desktop_environment)
- {
- only_show_in = g_key_file_get_string_list (desktop_file->key_file,
- EGG_DESKTOP_FILE_GROUP,
- EGG_DESKTOP_FILE_KEY_ONLY_SHOW_IN,
- NULL, NULL);
- if (only_show_in)
- {
- for (i = 0, found = FALSE; only_show_in[i] && !found; i++)
- {
- if (!strcmp (only_show_in[i], desktop_environment))
- found = TRUE;
- }
-
- g_strfreev (only_show_in);
-
- if (!found)
- return FALSE;
- }
-
- not_show_in = g_key_file_get_string_list (desktop_file->key_file,
- EGG_DESKTOP_FILE_GROUP,
- EGG_DESKTOP_FILE_KEY_NOT_SHOW_IN,
- NULL, NULL);
- if (not_show_in)
- {
- for (i = 0, found = FALSE; not_show_in[i] && !found; i++)
- {
- if (!strcmp (not_show_in[i], desktop_environment))
- found = TRUE;
- }
-
- g_strfreev (not_show_in);
-
- if (found)
- return FALSE;
- }
- }
-
- if (desktop_file->type == EGG_DESKTOP_FILE_TYPE_APPLICATION)
- {
- try_exec = g_key_file_get_string (desktop_file->key_file,
- EGG_DESKTOP_FILE_GROUP,
- EGG_DESKTOP_FILE_KEY_TRY_EXEC,
- NULL);
- if (try_exec)
- {
- found_program = g_find_program_in_path (try_exec);
- g_free (try_exec);
-
- if (!found_program)
- return FALSE;
- g_free (found_program);
- }
- }
-
- return TRUE;
-}
-
-/**
- * egg_desktop_file_accepts_documents:
- * @desktop_file: an #EggDesktopFile
- *
- * Tests if @desktop_file represents an application that can accept
- * documents on the command line.
- *
- * Return value: %TRUE or %FALSE
- **/
-gboolean
-egg_desktop_file_accepts_documents (EggDesktopFile *desktop_file)
-{
- return desktop_file->document_code != 0;
-}
-
-/**
- * egg_desktop_file_accepts_multiple:
- * @desktop_file: an #EggDesktopFile
- *
- * Tests if @desktop_file can accept multiple documents at once.
- *
- * If this returns %FALSE, you can still pass multiple documents to
- * egg_desktop_file_launch(), but that will result in multiple copies
- * of the application being launched. See egg_desktop_file_launch()
- * for more details.
- *
- * Return value: %TRUE or %FALSE
- **/
-gboolean
-egg_desktop_file_accepts_multiple (EggDesktopFile *desktop_file)
-{
- return (desktop_file->document_code == 'F' ||
- desktop_file->document_code == 'U');
-}
-
-/**
- * egg_desktop_file_accepts_uris:
- * @desktop_file: an #EggDesktopFile
- *
- * Tests if @desktop_file can accept (non-"file:") URIs as documents to
- * open.
- *
- * Return value: %TRUE or %FALSE
- **/
-gboolean
-egg_desktop_file_accepts_uris (EggDesktopFile *desktop_file)
-{
- return (desktop_file->document_code == 'U' ||
- desktop_file->document_code == 'u');
-}
-
-static void
-append_quoted_word (GString *str,
- const char *s,
- gboolean in_single_quotes,
- gboolean in_double_quotes)
-{
- const char *p;
-
- if (!in_single_quotes && !in_double_quotes)
- g_string_append_c (str, '\'');
- else if (!in_single_quotes && in_double_quotes)
- g_string_append (str, "\"'");
-
- if (!strchr (s, '\''))
- g_string_append (str, s);
- else
- {
- for (p = s; *p != '\0'; p++)
- {
- if (*p == '\'')
- g_string_append (str, "'\\''");
- else
- g_string_append_c (str, *p);
- }
- }
-
- if (!in_single_quotes && !in_double_quotes)
- g_string_append_c (str, '\'');
- else if (!in_single_quotes && in_double_quotes)
- g_string_append (str, "'\"");
-}
-
-static void
-do_percent_subst (EggDesktopFile *desktop_file,
- char code,
- GString *str,
- GSList **documents,
- gboolean in_single_quotes,
- gboolean in_double_quotes)
-{
- GSList *d;
- char *doc;
-
- switch (code)
- {
- case '%':
- g_string_append_c (str, '%');
- break;
-
- case 'F':
- case 'U':
- for (d = *documents; d; d = d->next)
- {
- doc = d->data;
- g_string_append (str, " ");
- append_quoted_word (str, doc, in_single_quotes, in_double_quotes);
- }
- *documents = NULL;
- break;
-
- case 'f':
- case 'u':
- if (*documents)
- {
- doc = (*documents)->data;
- g_string_append (str, " ");
- append_quoted_word (str, doc, in_single_quotes, in_double_quotes);
- *documents = (*documents)->next;
- }
- break;
-
- case 'i':
- if (desktop_file->icon)
- {
- g_string_append (str, "--icon ");
- append_quoted_word (str, desktop_file->icon,
- in_single_quotes, in_double_quotes);
- }
- break;
-
- case 'c':
- if (desktop_file->name)
- {
- append_quoted_word (str, desktop_file->name,
- in_single_quotes, in_double_quotes);
- }
- break;
-
- case 'k':
- if (desktop_file->source)
- {
- append_quoted_word (str, desktop_file->source,
- in_single_quotes, in_double_quotes);
- }
- break;
-
- case 'D':
- case 'N':
- case 'd':
- case 'n':
- case 'v':
- case 'm':
- /* Deprecated; skip */
- break;
-
- default:
- g_warning ("Unrecognized %%-code '%%%c' in Exec", code);
- break;
- }
-}
-
-static char *
-parse_exec (EggDesktopFile *desktop_file,
- GSList **documents,
- GError **error)
-{
- char *exec, *p, *command;
- gboolean escape, single_quot, double_quot;
- GString *gs;
-
- exec = g_key_file_get_string (desktop_file->key_file,
- EGG_DESKTOP_FILE_GROUP,
- EGG_DESKTOP_FILE_KEY_EXEC,
- error);
- if (!exec)
- return NULL;
-
- /* Build the command */
- gs = g_string_new (NULL);
- escape = single_quot = double_quot = FALSE;
-
- for (p = exec; *p != '\0'; p++)
- {
- if (escape)
- {
- escape = FALSE;
- g_string_append_c (gs, *p);
- }
- else if (*p == '\\')
- {
- if (!single_quot)
- escape = TRUE;
- g_string_append_c (gs, *p);
- }
- else if (*p == '\'')
- {
- g_string_append_c (gs, *p);
- if (!single_quot && !double_quot)
- single_quot = TRUE;
- else if (single_quot)
- single_quot = FALSE;
- }
- else if (*p == '"')
- {
- g_string_append_c (gs, *p);
- if (!single_quot && !double_quot)
- double_quot = TRUE;
- else if (double_quot)
- double_quot = FALSE;
- }
- else if (*p == '%' && p[1])
- {
- do_percent_subst (desktop_file, p[1], gs, documents,
- single_quot, double_quot);
- p++;
- }
- else
- g_string_append_c (gs, *p);
- }
-
- g_free (exec);
- command = g_string_free (gs, FALSE);
-
- /* Prepend "xdg-terminal " if needed (FIXME: use gvfs) */
- if (g_key_file_has_key (desktop_file->key_file,
- EGG_DESKTOP_FILE_GROUP,
- EGG_DESKTOP_FILE_KEY_TERMINAL,
- NULL))
- {
- GError *terminal_error = NULL;
- gboolean use_terminal =
- g_key_file_get_boolean (desktop_file->key_file,
- EGG_DESKTOP_FILE_GROUP,
- EGG_DESKTOP_FILE_KEY_TERMINAL,
- &terminal_error);
- if (terminal_error)
- {
- g_free (command);
- g_propagate_error (error, terminal_error);
- return NULL;
- }
-
- if (use_terminal)
- {
- gs = g_string_new ("xdg-terminal ");
- append_quoted_word (gs, command, FALSE, FALSE);
- g_free (command);
- command = g_string_free (gs, FALSE);
- }
- }
-
- return command;
-}
-
-static GSList *
-translate_document_list (EggDesktopFile *desktop_file, GSList *documents)
-{
- gboolean accepts_uris = egg_desktop_file_accepts_uris (desktop_file);
- GSList *ret, *d;
-
- for (d = documents, ret = NULL; d; d = d->next)
- {
- const char *document = d->data;
- gboolean is_uri = !g_path_is_absolute (document);
- char *translated;
-
- if (accepts_uris)
- {
- if (is_uri)
- translated = g_strdup (document);
- else
- translated = g_filename_to_uri (document, NULL, NULL);
- }
- else
- {
- if (is_uri)
- translated = g_filename_from_uri (document, NULL, NULL);
- else
- translated = g_strdup (document);
- }
-
- if (translated)
- ret = g_slist_prepend (ret, translated);
- }
-
- return g_slist_reverse (ret);
-}
-
-static void
-free_document_list (GSList *documents)
-{
- GSList *d;
-
- for (d = documents; d; d = d->next)
- g_free (d->data);
- g_slist_free (documents);
-}
-
-/**
- * egg_desktop_file_parse_exec:
- * @desktop_file: a #EggDesktopFile
- * @documents: a list of document paths or URIs
- * @error: error pointer
- *
- * Parses @desktop_file's Exec key, inserting @documents into it, and
- * returns the result.
- *
- * If @documents contains non-file: URIs and @desktop_file does not
- * accept URIs, those URIs will be ignored. Likewise, if @documents
- * contains more elements than @desktop_file accepts, the extra
- * documents will be ignored.
- *
- * Return value: the parsed Exec string
- **/
-char *
-egg_desktop_file_parse_exec (EggDesktopFile *desktop_file,
- GSList *documents,
- GError **error)
-{
- GSList *translated, *docs;
- char *command;
-
- docs = translated = translate_document_list (desktop_file, documents);
- command = parse_exec (desktop_file, &docs, error);
- free_document_list (translated);
-
- return command;
-}
-
-static gboolean
-parse_link (EggDesktopFile *desktop_file,
- EggDesktopFile **app_desktop_file,
- GSList **documents,
- GError **error)
-{
- char *url;
- GKeyFile *key_file;
-
- url = g_key_file_get_string (desktop_file->key_file,
- EGG_DESKTOP_FILE_GROUP,
- EGG_DESKTOP_FILE_KEY_URL,
- error);
- if (!url)
- return FALSE;
- *documents = g_slist_prepend (NULL, url);
-
- /* FIXME: use gvfs */
- key_file = g_key_file_new ();
- g_key_file_set_string (key_file, EGG_DESKTOP_FILE_GROUP,
- EGG_DESKTOP_FILE_KEY_NAME,
- "xdg-open");
- g_key_file_set_string (key_file, EGG_DESKTOP_FILE_GROUP,
- EGG_DESKTOP_FILE_KEY_TYPE,
- "Application");
- g_key_file_set_string (key_file, EGG_DESKTOP_FILE_GROUP,
- EGG_DESKTOP_FILE_KEY_EXEC,
- "xdg-open %u");
- *app_desktop_file = egg_desktop_file_new_from_key_file (key_file, NULL, NULL);
- return TRUE;
-}
-
-#if GTK_CHECK_VERSION (2, 12, 0)
-static char *
-start_startup_notification (GdkDisplay *display,
- EggDesktopFile *desktop_file,
- const char *argv0,
- int screen,
- int workspace,
- guint32 launch_time)
-{
- static int sequence = 0;
- char *startup_id;
- char *description, *wmclass;
- char *screen_str, *workspace_str;
-
- if (g_key_file_has_key (desktop_file->key_file,
- EGG_DESKTOP_FILE_GROUP,
- EGG_DESKTOP_FILE_KEY_STARTUP_NOTIFY,
- NULL))
- {
- if (!g_key_file_get_boolean (desktop_file->key_file,
- EGG_DESKTOP_FILE_GROUP,
- EGG_DESKTOP_FILE_KEY_STARTUP_NOTIFY,
- NULL))
- return NULL;
- wmclass = NULL;
- }
- else
- {
- wmclass = g_key_file_get_string (desktop_file->key_file,
- EGG_DESKTOP_FILE_GROUP,
- EGG_DESKTOP_FILE_KEY_STARTUP_WM_CLASS,
- NULL);
- if (!wmclass)
- return NULL;
- }
-
- if (launch_time == (guint32)-1)
- launch_time = gdk_x11_display_get_user_time (display);
- startup_id = g_strdup_printf ("%s-%lu-%s-%s-%d_TIME%lu",
- g_get_prgname (),
- (unsigned long)getpid (),
- g_get_host_name (),
- argv0,
- sequence++,
- (unsigned long)launch_time);
-
- description = g_strdup_printf (_("Starting %s"), desktop_file->name);
- screen_str = g_strdup_printf ("%d", screen);
- workspace_str = workspace == -1 ? NULL : g_strdup_printf ("%d", workspace);
-
- gdk_x11_display_broadcast_startup_message (display, "new",
- "ID", startup_id,
- "NAME", desktop_file->name,
- "SCREEN", screen_str,
- "BIN", argv0,
- "ICON", desktop_file->icon,
- "DESKTOP", workspace_str,
- "DESCRIPTION", description,
- "WMCLASS", wmclass,
- NULL);
-
- g_free (description);
- g_free (wmclass);
- g_free (screen_str);
- g_free (workspace_str);
-
- return startup_id;
-}
-
-static void
-end_startup_notification (GdkDisplay *display,
- const char *startup_id)
-{
- gdk_x11_display_broadcast_startup_message (display, "remove",
- "ID", startup_id,
- NULL);
-}
-
-#define EGG_DESKTOP_FILE_SN_TIMEOUT_LENGTH (30 /* seconds */ * 1000)
-
-typedef struct {
- GdkDisplay *display;
- char *startup_id;
-} StartupNotificationData;
-
-static gboolean
-startup_notification_timeout (gpointer data)
-{
- StartupNotificationData *sn_data = data;
-
- end_startup_notification (sn_data->display, sn_data->startup_id);
- g_object_unref (sn_data->display);
- g_free (sn_data->startup_id);
- g_free (sn_data);
-
- return FALSE;
-}
-
-static void
-set_startup_notification_timeout (GdkDisplay *display,
- const char *startup_id)
-{
- StartupNotificationData *sn_data;
-
- sn_data = g_new (StartupNotificationData, 1);
- sn_data->display = g_object_ref (display);
- sn_data->startup_id = g_strdup (startup_id);
-
- g_timeout_add (EGG_DESKTOP_FILE_SN_TIMEOUT_LENGTH,
- startup_notification_timeout, sn_data);
-}
-#endif /* GTK 2.12 */
-
-static GPtrArray *
-array_putenv (GPtrArray *env, char *variable)
-{
- int i, keylen;
-
- if (!env)
- {
- char **envp;
-
- env = g_ptr_array_new ();
-
- envp = g_listenv ();
- for (i = 0; envp[i]; i++)
- {
- const char *value;
-
- value = g_getenv (envp[i]);
- g_ptr_array_add (env, g_strdup_printf ("%s=%s", envp[i],
- value ? value : ""));
- }
- g_strfreev (envp);
- }
-
- keylen = strcspn (variable, "=");
-
- /* Remove old value of key */
- for (i = 0; i < env->len; i++)
- {
- char *envvar = env->pdata[i];
-
- if (!strncmp (envvar, variable, keylen) && envvar[keylen] == '=')
- {
- g_free (envvar);
- g_ptr_array_remove_index_fast (env, i);
- break;
- }
- }
-
- /* Add new value */
- g_ptr_array_add (env, g_strdup (variable));
-
- return env;
-}
-
-static gboolean
-egg_desktop_file_launchv (EggDesktopFile *desktop_file,
- GSList *documents, va_list args,
- GError **error)
-{
- EggDesktopFileLaunchOption option;
- GSList *translated_documents = NULL, *docs;
- char *command, **argv;
- int argc, i, screen_num;
- gboolean success, current_success;
- GdkDisplay *display;
- char *startup_id;
-
- GPtrArray *env = NULL;
- char **variables = NULL;
- GdkScreen *screen = NULL;
- int workspace = -1;
- const char *directory = NULL;
- guint32 launch_time = (guint32)-1;
- GSpawnFlags flags = G_SPAWN_SEARCH_PATH;
- GSpawnChildSetupFunc setup_func = NULL;
- gpointer setup_data = NULL;
-
- GPid *ret_pid = NULL;
- int *ret_stdin = NULL, *ret_stdout = NULL, *ret_stderr = NULL;
- char **ret_startup_id = NULL;
-
- if (documents && desktop_file->document_code == 0)
- {
- g_set_error (error, EGG_DESKTOP_FILE_ERROR,
- EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE,
- _("Application does not accept documents on command line"));
- return FALSE;
- }
-
- /* Read the options: technically it's incorrect for the caller to
- * NULL-terminate the list of options (rather than 0-terminating
- * it), but NULL-terminating lets us use G_GNUC_NULL_TERMINATED,
- * it's more consistent with other glib/gtk methods, and it will
- * work as long as sizeof (int) <= sizeof (NULL), and NULL is
- * represented as 0. (Which is true everywhere we care about.)
- */
- while ((option = va_arg (args, EggDesktopFileLaunchOption)))
- {
- switch (option)
- {
- case EGG_DESKTOP_FILE_LAUNCH_CLEARENV:
- if (env)
- g_ptr_array_free (env, TRUE);
- env = g_ptr_array_new ();
- break;
- case EGG_DESKTOP_FILE_LAUNCH_PUTENV:
- variables = va_arg (args, char **);
- for (i = 0; variables[i]; i++)
- env = array_putenv (env, variables[i]);
- break;
-
- case EGG_DESKTOP_FILE_LAUNCH_SCREEN:
- screen = va_arg (args, GdkScreen *);
- break;
- case EGG_DESKTOP_FILE_LAUNCH_WORKSPACE:
- workspace = va_arg (args, int);
- break;
-
- case EGG_DESKTOP_FILE_LAUNCH_DIRECTORY:
- directory = va_arg (args, const char *);
- break;
- case EGG_DESKTOP_FILE_LAUNCH_TIME:
- launch_time = va_arg (args, guint32);
- break;
- case EGG_DESKTOP_FILE_LAUNCH_FLAGS:
- flags |= va_arg (args, GSpawnFlags);
- /* Make sure they didn't set any flags that don't make sense. */
- flags &= ~G_SPAWN_FILE_AND_ARGV_ZERO;
- break;
- case EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC:
- setup_func = va_arg (args, GSpawnChildSetupFunc);
- setup_data = va_arg (args, gpointer);
- break;
-
- case EGG_DESKTOP_FILE_LAUNCH_RETURN_PID:
- ret_pid = va_arg (args, GPid *);
- break;
- case EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE:
- ret_stdin = va_arg (args, int *);
- break;
- case EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE:
- ret_stdout = va_arg (args, int *);
- break;
- case EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE:
- ret_stderr = va_arg (args, int *);
- break;
- case EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID:
- ret_startup_id = va_arg (args, char **);
- break;
-
- default:
- g_set_error (error, EGG_DESKTOP_FILE_ERROR,
- EGG_DESKTOP_FILE_ERROR_UNRECOGNIZED_OPTION,
- _("Unrecognized launch option: %d"),
- GPOINTER_TO_INT (option));
- success = FALSE;
- goto out;
- }
- }
-
- if (screen)
- {
- char *display_name = gdk_screen_make_display_name (screen);
- char *display_env = g_strdup_printf ("DISPLAY=%s", display_name);
- env = array_putenv (env, display_env);
- g_free (display_name);
- g_free (display_env);
-
- display = gdk_screen_get_display (screen);
- }
- else
- {
- display = gdk_display_get_default ();
- screen = gdk_display_get_default_screen (display);
- }
- screen_num = gdk_screen_get_number (screen);
-
- translated_documents = translate_document_list (desktop_file, documents);
- docs = translated_documents;
-
- success = FALSE;
-
- do
- {
- command = parse_exec (desktop_file, &docs, error);
- if (!command)
- goto out;
-
- if (!g_shell_parse_argv (command, &argc, &argv, error))
- {
- g_free (command);
- goto out;
- }
- g_free (command);
-
-#if GTK_CHECK_VERSION (2, 12, 0)
- startup_id = start_startup_notification (display, desktop_file,
- argv[0], screen_num,
- workspace, launch_time);
- if (startup_id)
- {
- char *startup_id_env = g_strdup_printf ("DESKTOP_STARTUP_ID=%s",
- startup_id);
- env = array_putenv (env, startup_id_env);
- g_free (startup_id_env);
- }
-#else
- startup_id = NULL;
-#endif /* GTK 2.12 */
-
- if (env != NULL)
- g_ptr_array_add (env, NULL);
-
- current_success =
- g_spawn_async_with_pipes (directory,
- argv,
- env ? (char **)(env->pdata) : NULL,
- flags,
- setup_func, setup_data,
- ret_pid,
- ret_stdin, ret_stdout, ret_stderr,
- error);
- g_strfreev (argv);
-
- if (startup_id)
- {
-#if GTK_CHECK_VERSION (2, 12, 0)
- if (current_success)
- {
- set_startup_notification_timeout (display, startup_id);
-
- if (ret_startup_id)
- *ret_startup_id = startup_id;
- else
- g_free (startup_id);
- }
- else
-#endif /* GTK 2.12 */
- g_free (startup_id);
- }
- else if (ret_startup_id)
- *ret_startup_id = NULL;
-
- if (current_success)
- {
- /* If we successfully launch any instances of the app, make
- * sure we return TRUE and don't set @error.
- */
- success = TRUE;
- error = NULL;
-
- /* Also, only set the output params on the first one */
- ret_pid = NULL;
- ret_stdin = ret_stdout = ret_stderr = NULL;
- ret_startup_id = NULL;
- }
- }
- while (docs && current_success);
-
- out:
- if (env)
- {
- g_strfreev ((char **)env->pdata);
- g_ptr_array_free (env, FALSE);
- }
- free_document_list (translated_documents);
-
- return success;
-}
-
-/**
- * egg_desktop_file_launch:
- * @desktop_file: an #EggDesktopFile
- * @documents: a list of URIs or paths to documents to open
- * @error: error pointer
- * @...: additional options
- *
- * Launches @desktop_file with the given arguments. Additional options
- * can be specified as follows:
- *
- * %EGG_DESKTOP_FILE_LAUNCH_CLEARENV: (no arguments)
- * clears the environment in the child process
- * %EGG_DESKTOP_FILE_LAUNCH_PUTENV: (char **variables)
- * adds the NAME=VALUE strings in the given %NULL-terminated
- * array to the child process's environment
- * %EGG_DESKTOP_FILE_LAUNCH_SCREEN: (GdkScreen *screen)
- * causes the application to be launched on the given screen
- * %EGG_DESKTOP_FILE_LAUNCH_WORKSPACE: (int workspace)
- * causes the application to be launched on the given workspace
- * %EGG_DESKTOP_FILE_LAUNCH_DIRECTORY: (char *dir)
- * causes the application to be launched in the given directory
- * %EGG_DESKTOP_FILE_LAUNCH_TIME: (guint32 launch_time)
- * sets the "launch time" for the application. If the user
- * interacts with another window after @launch_time but before
- * the launched application creates its first window, the window
- * manager may choose to not give focus to the new application.
- * Passing 0 for @launch_time will explicitly request that the
- * application not receive focus.
- * %EGG_DESKTOP_FILE_LAUNCH_FLAGS (GSpawnFlags flags)
- * Sets additional #GSpawnFlags to use. See g_spawn_async() for
- * more details.
- * %EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC (GSpawnChildSetupFunc, gpointer)
- * Sets the child setup callback and the data to pass to it.
- * (See g_spawn_async() for more details.)
- *
- * %EGG_DESKTOP_FILE_LAUNCH_RETURN_PID (GPid **pid)
- * On a successful launch, sets *@pid to the PID of the launched
- * application.
- * %EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID (char **startup_id)
- * On a successful launch, sets *@startup_id to the Startup
- * Notification "startup id" of the launched application.
- * %EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE (int *fd)
- * On a successful launch, sets *@fd to the file descriptor of
- * a pipe connected to the application's stdin.
- * %EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE (int *fd)
- * On a successful launch, sets *@fd to the file descriptor of
- * a pipe connected to the application's stdout.
- * %EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE (int *fd)
- * On a successful launch, sets *@fd to the file descriptor of
- * a pipe connected to the application's stderr.
- *
- * The options should be terminated with a single %NULL.
- *
- * If @documents contains multiple documents, but
- * egg_desktop_file_accepts_multiple() returns %FALSE for
- * @desktop_file, then egg_desktop_file_launch() will actually launch
- * multiple instances of the application. In that case, the return
- * value (as well as any values passed via
- * %EGG_DESKTOP_FILE_LAUNCH_RETURN_PID, etc) will only reflect the
- * first instance of the application that was launched (but the
- * %EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC will be called for each
- * instance).
- *
- * Return value: %TRUE if the application was successfully launched.
- **/
-gboolean
-egg_desktop_file_launch (EggDesktopFile *desktop_file,
- GSList *documents, GError **error,
- ...)
-{
- va_list args;
- gboolean success;
- EggDesktopFile *app_desktop_file;
-
- switch (desktop_file->type)
- {
- case EGG_DESKTOP_FILE_TYPE_APPLICATION:
- va_start (args, error);
- success = egg_desktop_file_launchv (desktop_file, documents,
- args, error);
- va_end (args);
- break;
-
- case EGG_DESKTOP_FILE_TYPE_LINK:
- if (documents)
- {
- g_set_error (error, EGG_DESKTOP_FILE_ERROR,
- EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE,
- _("Can't pass document URIs to a 'Type=Link' desktop entry"));
- return FALSE;
- }
-
- if (!parse_link (desktop_file, &app_desktop_file, &documents, error))
- return FALSE;
-
- va_start (args, error);
- success = egg_desktop_file_launchv (app_desktop_file, documents,
- args, error);
- va_end (args);
-
- egg_desktop_file_free (app_desktop_file);
- free_document_list (documents);
- break;
-
- default:
- g_set_error (error, EGG_DESKTOP_FILE_ERROR,
- EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE,
- _("Not a launchable item"));
- success = FALSE;
- break;
- }
-
- return success;
-}
-
-
-GQuark
-egg_desktop_file_error_quark (void)
-{
- return g_quark_from_static_string ("egg-desktop_file-error-quark");
-}
-
-
-G_LOCK_DEFINE_STATIC (egg_desktop_file);
-static EggDesktopFile *egg_desktop_file;
-
-/**
- * egg_set_desktop_file:
- * @desktop_file_path: path to the application's desktop file
- *
- * Creates an #EggDesktopFile for the application from the data at
- * @desktop_file_path. This will also call g_set_application_name()
- * with the localized application name from the desktop file, and
- * gtk_window_set_default_icon_name() or
- * gtk_window_set_default_icon_from_file() with the application's
- * icon. Other code may use additional information from the desktop
- * file.
- *
- * Note that for thread safety reasons, this function can only
- * be called once.
- **/
-void
-egg_set_desktop_file (const char *desktop_file_path)
-{
- GError *error = NULL;
-
- G_LOCK (egg_desktop_file);
- if (egg_desktop_file)
- egg_desktop_file_free (egg_desktop_file);
-
- egg_desktop_file = egg_desktop_file_new (desktop_file_path, &error);
- if (error)
- {
- g_warning ("Could not load desktop file '%s': %s",
- desktop_file_path, error->message);
- g_error_free (error);
- }
-
- /* Set localized application name and default window icon */
- if (egg_desktop_file->name)
- g_set_application_name (egg_desktop_file->name);
- if (egg_desktop_file->icon)
- {
- if (g_path_is_absolute (egg_desktop_file->icon))
- gtk_window_set_default_icon_from_file (egg_desktop_file->icon, NULL);
- else
- gtk_window_set_default_icon_name (egg_desktop_file->icon);
- }
-
- G_UNLOCK (egg_desktop_file);
-}
-
-/**
- * egg_get_desktop_file:
- *
- * Gets the application's #EggDesktopFile, as set by
- * egg_set_desktop_file().
- *
- * Return value: the #EggDesktopFile, or %NULL if it hasn't been set.
- **/
-EggDesktopFile *
-egg_get_desktop_file (void)
-{
- EggDesktopFile *retval;
-
- G_LOCK (egg_desktop_file);
- retval = egg_desktop_file;
- G_UNLOCK (egg_desktop_file);
-
- return retval;
-}
diff --git a/cut-n-paste-code/libegg/eggdesktopfile.h b/cut-n-paste-code/libegg/eggdesktopfile.h
deleted file mode 100644
index f8a3d3e03..000000000
--- a/cut-n-paste-code/libegg/eggdesktopfile.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/* eggdesktopfile.h - Freedesktop.Org Desktop Files
- * Copyright (C) 2007 Novell, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place -
- * Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __EGG_DESKTOP_FILE_H__
-#define __EGG_DESKTOP_FILE_H__
-
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-typedef struct EggDesktopFile EggDesktopFile;
-
-typedef enum {
- EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED,
-
- EGG_DESKTOP_FILE_TYPE_APPLICATION,
- EGG_DESKTOP_FILE_TYPE_LINK,
- EGG_DESKTOP_FILE_TYPE_DIRECTORY
-} EggDesktopFileType;
-
-EggDesktopFile *egg_desktop_file_new (const char *desktop_file_path,
- GError **error);
-
-EggDesktopFile *egg_desktop_file_new_from_data_dirs (const char *desktop_file_path,
- GError **error);
-EggDesktopFile *egg_desktop_file_new_from_dirs (const char *desktop_file_path,
- const char **search_dirs,
- GError **error);
-EggDesktopFile *egg_desktop_file_new_from_key_file (GKeyFile *key_file,
- const char *source,
- GError **error);
-
-void egg_desktop_file_free (EggDesktopFile *desktop_file);
-
-const char *egg_desktop_file_get_source (EggDesktopFile *desktop_file);
-
-EggDesktopFileType egg_desktop_file_get_desktop_file_type (EggDesktopFile *desktop_file);
-
-const char *egg_desktop_file_get_name (EggDesktopFile *desktop_file);
-const char *egg_desktop_file_get_icon (EggDesktopFile *desktop_file);
-
-gboolean egg_desktop_file_can_launch (EggDesktopFile *desktop_file,
- const char *desktop_environment);
-
-gboolean egg_desktop_file_accepts_documents (EggDesktopFile *desktop_file);
-gboolean egg_desktop_file_accepts_multiple (EggDesktopFile *desktop_file);
-gboolean egg_desktop_file_accepts_uris (EggDesktopFile *desktop_file);
-
-char *egg_desktop_file_parse_exec (EggDesktopFile *desktop_file,
- GSList *documents,
- GError **error);
-
-gboolean egg_desktop_file_launch (EggDesktopFile *desktop_file,
- GSList *documents,
- GError **error,
- ...) G_GNUC_NULL_TERMINATED;
-
-typedef enum {
- EGG_DESKTOP_FILE_LAUNCH_CLEARENV = 1,
- EGG_DESKTOP_FILE_LAUNCH_PUTENV,
- EGG_DESKTOP_FILE_LAUNCH_SCREEN,
- EGG_DESKTOP_FILE_LAUNCH_WORKSPACE,
- EGG_DESKTOP_FILE_LAUNCH_DIRECTORY,
- EGG_DESKTOP_FILE_LAUNCH_TIME,
- EGG_DESKTOP_FILE_LAUNCH_FLAGS,
- EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC,
- EGG_DESKTOP_FILE_LAUNCH_RETURN_PID,
- EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE,
- EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE,
- EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE,
- EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID
-} EggDesktopFileLaunchOption;
-
-/* Standard Keys */
-#define EGG_DESKTOP_FILE_GROUP "Desktop Entry"
-
-#define EGG_DESKTOP_FILE_KEY_TYPE "Type"
-#define EGG_DESKTOP_FILE_KEY_VERSION "Version"
-#define EGG_DESKTOP_FILE_KEY_NAME "Name"
-#define EGG_DESKTOP_FILE_KEY_GENERIC_NAME "GenericName"
-#define EGG_DESKTOP_FILE_KEY_NO_DISPLAY "NoDisplay"
-#define EGG_DESKTOP_FILE_KEY_COMMENT "Comment"
-#define EGG_DESKTOP_FILE_KEY_ICON "Icon"
-#define EGG_DESKTOP_FILE_KEY_HIDDEN "Hidden"
-#define EGG_DESKTOP_FILE_KEY_ONLY_SHOW_IN "OnlyShowIn"
-#define EGG_DESKTOP_FILE_KEY_NOT_SHOW_IN "NotShowIn"
-#define EGG_DESKTOP_FILE_KEY_TRY_EXEC "TryExec"
-#define EGG_DESKTOP_FILE_KEY_EXEC "Exec"
-#define EGG_DESKTOP_FILE_KEY_PATH "Path"
-#define EGG_DESKTOP_FILE_KEY_TERMINAL "Terminal"
-#define EGG_DESKTOP_FILE_KEY_MIME_TYPE "MimeType"
-#define EGG_DESKTOP_FILE_KEY_CATEGORIES "Categories"
-#define EGG_DESKTOP_FILE_KEY_STARTUP_NOTIFY "StartupNotify"
-#define EGG_DESKTOP_FILE_KEY_STARTUP_WM_CLASS "StartupWMClass"
-#define EGG_DESKTOP_FILE_KEY_URL "URL"
-
-/* Accessors */
-gboolean egg_desktop_file_has_key (EggDesktopFile *desktop_file,
- const char *key,
- GError **error);
-char *egg_desktop_file_get_string (EggDesktopFile *desktop_file,
- const char *key,
- GError **error) G_GNUC_MALLOC;
-char *egg_desktop_file_get_locale_string (EggDesktopFile *desktop_file,
- const char *key,
- const char *locale,
- GError **error) G_GNUC_MALLOC;
-gboolean egg_desktop_file_get_boolean (EggDesktopFile *desktop_file,
- const char *key,
- GError **error);
-double egg_desktop_file_get_numeric (EggDesktopFile *desktop_file,
- const char *key,
- GError **error);
-char **egg_desktop_file_get_string_list (EggDesktopFile *desktop_file,
- const char *key,
- gsize *length,
- GError **error) G_GNUC_MALLOC;
-char **egg_desktop_file_get_locale_string_list (EggDesktopFile *desktop_file,
- const char *key,
- const char *locale,
- gsize *length,
- GError **error) G_GNUC_MALLOC;
-
-
-/* Errors */
-#define EGG_DESKTOP_FILE_ERROR egg_desktop_file_error_quark()
-
-GQuark egg_desktop_file_error_quark (void);
-
-typedef enum {
- EGG_DESKTOP_FILE_ERROR_INVALID,
- EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE,
- EGG_DESKTOP_FILE_ERROR_UNRECOGNIZED_OPTION
-} EggDesktopFileError;
-
-/* Global application desktop file */
-void egg_set_desktop_file (const char *desktop_file_path);
-EggDesktopFile *egg_get_desktop_file (void);
-
-
-G_END_DECLS
-
-#endif /* __EGG_DESKTOP_FILE_H__ */
diff --git a/cut-n-paste-code/libegg/eggsmclient-private.h b/cut-n-paste-code/libegg/eggsmclient-private.h
deleted file mode 100644
index ccb10bfc3..000000000
--- a/cut-n-paste-code/libegg/eggsmclient-private.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* eggsmclient-private.h
- * Copyright (C) 2007 Novell, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __EGG_SM_CLIENT_PRIVATE_H__
-#define __EGG_SM_CLIENT_PRIVATE_H__
-
-#include <gdkconfig.h>
-#include "eggsmclient.h"
-
-G_BEGIN_DECLS
-
-GKeyFile *egg_sm_client_save_state (EggSMClient *client);
-void egg_sm_client_quit_requested (EggSMClient *client);
-void egg_sm_client_quit_cancelled (EggSMClient *client);
-void egg_sm_client_quit (EggSMClient *client);
-
-#if defined (GDK_WINDOWING_X11)
-# ifdef EGG_SM_CLIENT_BACKEND_XSMP
-GType egg_sm_client_xsmp_get_type (void);
-EggSMClient *egg_sm_client_xsmp_new (void);
-# endif
-# ifdef EGG_SM_CLIENT_BACKEND_DBUS
-GType egg_sm_client_dbus_get_type (void);
-EggSMClient *egg_sm_client_dbus_new (void);
-# endif
-#elif defined (GDK_WINDOWING_WIN32)
-GType egg_sm_client_win32_get_type (void);
-EggSMClient *egg_sm_client_win32_new (void);
-#elif defined (GDK_WINDOWING_QUARTZ)
-GType egg_sm_client_osx_get_type (void);
-EggSMClient *egg_sm_client_osx_new (void);
-#endif
-
-G_END_DECLS
-
-
-#endif /* __EGG_SM_CLIENT_PRIVATE_H__ */
diff --git a/cut-n-paste-code/libegg/eggsmclient-xsmp.c b/cut-n-paste-code/libegg/eggsmclient-xsmp.c
deleted file mode 100644
index 1a56156ce..000000000
--- a/cut-n-paste-code/libegg/eggsmclient-xsmp.c
+++ /dev/null
@@ -1,1370 +0,0 @@
-/*
- * Copyright (C) 2007 Novell, Inc.
- *
- * Inspired by various other pieces of code including GsmClient (C)
- * 2001 Havoc Pennington, GnomeClient (C) 1998 Carsten Schaar, and twm
- * session code (C) 1998 The Open Group.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "eggsmclient.h"
-#include "eggsmclient-private.h"
-
-#include "eggdesktopfile.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <X11/SM/SMlib.h>
-
-#include <gdk/gdk.h>
-
-#define EGG_TYPE_SM_CLIENT_XSMP (egg_sm_client_xsmp_get_type ())
-#define EGG_SM_CLIENT_XSMP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_SM_CLIENT_XSMP, EggSMClientXSMP))
-#define EGG_SM_CLIENT_XSMP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_SM_CLIENT_XSMP, EggSMClientXSMPClass))
-#define EGG_IS_SM_CLIENT_XSMP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_SM_CLIENT_XSMP))
-#define EGG_IS_SM_CLIENT_XSMP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_SM_CLIENT_XSMP))
-#define EGG_SM_CLIENT_XSMP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_SM_CLIENT_XSMP, EggSMClientXSMPClass))
-
-typedef struct _EggSMClientXSMP EggSMClientXSMP;
-typedef struct _EggSMClientXSMPClass EggSMClientXSMPClass;
-
-/* These mostly correspond to the similarly-named states in section
- * 9.1 of the XSMP spec. Some of the states there aren't represented
- * here, because we don't need them. SHUTDOWN_CANCELLED is slightly
- * different from the spec; we use it when the client is IDLE after a
- * ShutdownCancelled message, but the application is still interacting
- * and doesn't know the shutdown has been cancelled yet.
- */
-typedef enum
-{
- XSMP_STATE_IDLE,
- XSMP_STATE_SAVE_YOURSELF,
- XSMP_STATE_INTERACT_REQUEST,
- XSMP_STATE_INTERACT,
- XSMP_STATE_SAVE_YOURSELF_DONE,
- XSMP_STATE_SHUTDOWN_CANCELLED,
- XSMP_STATE_CONNECTION_CLOSED
-} EggSMClientXSMPState;
-
-static const char *state_names[] = {
- "idle",
- "save-yourself",
- "interact-request",
- "interact",
- "save-yourself-done",
- "shutdown-cancelled",
- "connection-closed"
-};
-
-#define EGG_SM_CLIENT_XSMP_STATE(xsmp) (state_names[(xsmp)->state])
-
-struct _EggSMClientXSMP
-{
- EggSMClient parent;
-
- SmcConn connection;
- char *client_id;
-
- EggSMClientXSMPState state;
- char **restart_command;
- gboolean set_restart_command;
- int restart_style;
-
- guint idle;
-
- /* Current SaveYourself state */
- guint expecting_initial_save_yourself : 1;
- guint need_save_state : 1;
- guint need_quit_requested : 1;
- guint interact_errors : 1;
- guint shutting_down : 1;
-
- /* Todo list */
- guint waiting_to_set_initial_properties : 1;
- guint waiting_to_emit_quit : 1;
- guint waiting_to_emit_quit_cancelled : 1;
- guint waiting_to_save_myself : 1;
-
-};
-
-struct _EggSMClientXSMPClass
-{
- EggSMClientClass parent_class;
-
-};
-
-static void sm_client_xsmp_startup (EggSMClient *client,
- const char *client_id);
-static void sm_client_xsmp_set_restart_command (EggSMClient *client,
- int argc,
- const char **argv);
-static void sm_client_xsmp_will_quit (EggSMClient *client,
- gboolean will_quit);
-static gboolean sm_client_xsmp_end_session (EggSMClient *client,
- EggSMClientEndStyle style,
- gboolean request_confirmation);
-
-static void xsmp_save_yourself (SmcConn smc_conn,
- SmPointer client_data,
- int save_style,
- Bool shutdown,
- int interact_style,
- Bool fast);
-static void xsmp_die (SmcConn smc_conn,
- SmPointer client_data);
-static void xsmp_save_complete (SmcConn smc_conn,
- SmPointer client_data);
-static void xsmp_shutdown_cancelled (SmcConn smc_conn,
- SmPointer client_data);
-static void xsmp_interact (SmcConn smc_conn,
- SmPointer client_data);
-
-static SmProp *array_prop (const char *name,
- ...);
-static SmProp *ptrarray_prop (const char *name,
- GPtrArray *values);
-static SmProp *string_prop (const char *name,
- const char *value);
-static SmProp *card8_prop (const char *name,
- unsigned char value);
-
-static void set_properties (EggSMClientXSMP *xsmp, ...);
-static void delete_properties (EggSMClientXSMP *xsmp, ...);
-
-static GPtrArray *generate_command (char **restart_command,
- const char *client_id,
- const char *state_file);
-
-static void save_state (EggSMClientXSMP *xsmp);
-static void do_save_yourself (EggSMClientXSMP *xsmp);
-static void update_pending_events (EggSMClientXSMP *xsmp);
-
-static void ice_init (void);
-static gboolean process_ice_messages (IceConn ice_conn);
-static void smc_error_handler (SmcConn smc_conn,
- Bool swap,
- int offending_minor_opcode,
- unsigned long offending_sequence,
- int error_class,
- int severity,
- SmPointer values);
-
-G_DEFINE_TYPE (EggSMClientXSMP, egg_sm_client_xsmp, EGG_TYPE_SM_CLIENT)
-
-static void
-egg_sm_client_xsmp_init (EggSMClientXSMP *xsmp)
-{
- xsmp->state = XSMP_STATE_CONNECTION_CLOSED;
- xsmp->connection = NULL;
- xsmp->restart_style = SmRestartIfRunning;
-}
-
-static void
-egg_sm_client_xsmp_class_init (EggSMClientXSMPClass *klass)
-{
- EggSMClientClass *sm_client_class = EGG_SM_CLIENT_CLASS (klass);
-
- sm_client_class->startup = sm_client_xsmp_startup;
- sm_client_class->set_restart_command = sm_client_xsmp_set_restart_command;
- sm_client_class->will_quit = sm_client_xsmp_will_quit;
- sm_client_class->end_session = sm_client_xsmp_end_session;
-}
-
-EggSMClient *
-egg_sm_client_xsmp_new (void)
-{
- if (!g_getenv ("SESSION_MANAGER"))
- return NULL;
-
- return g_object_new (EGG_TYPE_SM_CLIENT_XSMP, NULL);
-}
-
-static gboolean
-sm_client_xsmp_set_initial_properties (gpointer user_data)
-{
- EggSMClientXSMP *xsmp = user_data;
- EggDesktopFile *desktop_file;
- GPtrArray *clone, *restart;
- char pid_str[64];
-
- if (xsmp->idle)
- {
- g_source_remove (xsmp->idle);
- xsmp->idle = 0;
- }
- xsmp->waiting_to_set_initial_properties = FALSE;
-
- if (egg_sm_client_get_mode () == EGG_SM_CLIENT_MODE_NO_RESTART)
- xsmp->restart_style = SmRestartNever;
-
- /* Parse info out of desktop file */
- desktop_file = egg_get_desktop_file ();
- if (desktop_file)
- {
- GError *err = NULL;
- char *cmdline, **argv;
- int argc;
-
- if (xsmp->restart_style == SmRestartIfRunning)
- {
- if (egg_desktop_file_get_boolean (desktop_file,
- "X-GNOME-AutoRestart", NULL))
- xsmp->restart_style = SmRestartImmediately;
- }
-
- if (!xsmp->set_restart_command)
- {
- cmdline = egg_desktop_file_parse_exec (desktop_file, NULL, &err);
- if (cmdline && g_shell_parse_argv (cmdline, &argc, &argv, &err))
- {
- egg_sm_client_set_restart_command (EGG_SM_CLIENT (xsmp),
- argc, (const char **)argv);
- g_strfreev (argv);
- }
- else
- {
- g_warning ("Could not parse Exec line in desktop file: %s",
- err->message);
- g_error_free (err);
- }
- g_free (cmdline);
- }
- }
-
- if (!xsmp->set_restart_command)
- xsmp->restart_command = g_strsplit (g_get_prgname (), " ", -1);
-
- clone = generate_command (xsmp->restart_command, NULL, NULL);
- restart = generate_command (xsmp->restart_command, xsmp->client_id, NULL);
-
- g_debug ("Setting initial properties");
-
- /* Program, CloneCommand, RestartCommand, and UserID are required.
- * ProcessID isn't required, but the SM may be able to do something
- * useful with it.
- */
- g_snprintf (pid_str, sizeof (pid_str), "%lu", (gulong) getpid ());
- set_properties (xsmp,
- string_prop (SmProgram, g_get_prgname ()),
- ptrarray_prop (SmCloneCommand, clone),
- ptrarray_prop (SmRestartCommand, restart),
- string_prop (SmUserID, g_get_user_name ()),
- string_prop (SmProcessID, pid_str),
- card8_prop (SmRestartStyleHint, xsmp->restart_style),
- NULL);
- g_ptr_array_free (clone, TRUE);
- g_ptr_array_free (restart, TRUE);
-
- if (desktop_file)
- {
- set_properties (xsmp,
- string_prop ("_GSM_DesktopFile", egg_desktop_file_get_source (desktop_file)),
- NULL);
- }
-
- update_pending_events (xsmp);
- return FALSE;
-}
-
-/* This gets called from two different places: xsmp_die() (when the
- * server asks us to disconnect) and process_ice_messages() (when the
- * server disconnects unexpectedly).
- */
-static void
-sm_client_xsmp_disconnect (EggSMClientXSMP *xsmp)
-{
- SmcConn connection;
-
- if (!xsmp->connection)
- return;
-
- g_debug ("Disconnecting");
-
- connection = xsmp->connection;
- xsmp->connection = NULL;
- SmcCloseConnection (connection, 0, NULL);
- xsmp->state = XSMP_STATE_CONNECTION_CLOSED;
-
- xsmp->waiting_to_save_myself = FALSE;
- update_pending_events (xsmp);
-}
-
-static void
-sm_client_xsmp_startup (EggSMClient *client,
- const char *client_id)
-{
- EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
- SmcCallbacks callbacks;
- char *ret_client_id;
- char error_string_ret[256];
-
- xsmp->client_id = g_strdup (client_id);
-
- ice_init ();
- SmcSetErrorHandler (smc_error_handler);
-
- callbacks.save_yourself.callback = xsmp_save_yourself;
- callbacks.die.callback = xsmp_die;
- callbacks.save_complete.callback = xsmp_save_complete;
- callbacks.shutdown_cancelled.callback = xsmp_shutdown_cancelled;
-
- callbacks.save_yourself.client_data = xsmp;
- callbacks.die.client_data = xsmp;
- callbacks.save_complete.client_data = xsmp;
- callbacks.shutdown_cancelled.client_data = xsmp;
-
- client_id = NULL;
- error_string_ret[0] = '\0';
- xsmp->connection =
- SmcOpenConnection (NULL, xsmp, SmProtoMajor, SmProtoMinor,
- SmcSaveYourselfProcMask | SmcDieProcMask |
- SmcSaveCompleteProcMask |
- SmcShutdownCancelledProcMask,
- &callbacks,
- xsmp->client_id, &ret_client_id,
- sizeof (error_string_ret), error_string_ret);
-
- if (!xsmp->connection)
- {
- g_warning ("Failed to connect to the session manager: %s\n",
- error_string_ret[0] ?
- error_string_ret : "no error message given");
- xsmp->state = XSMP_STATE_CONNECTION_CLOSED;
- return;
- }
-
- /* We expect a pointless initial SaveYourself if either (a) we
- * didn't have an initial client ID, or (b) we DID have an initial
- * client ID, but the server rejected it and gave us a new one.
- */
- if (!xsmp->client_id ||
- (ret_client_id && strcmp (xsmp->client_id, ret_client_id) != 0))
- xsmp->expecting_initial_save_yourself = TRUE;
-
- if (ret_client_id)
- {
- g_free (xsmp->client_id);
- xsmp->client_id = g_strdup (ret_client_id);
- free (ret_client_id);
-
- gdk_threads_enter ();
- gdk_set_sm_client_id (xsmp->client_id);
- gdk_threads_leave ();
-
- g_debug ("Got client ID \"%s\"", xsmp->client_id);
- }
-
- xsmp->state = XSMP_STATE_IDLE;
-
- /* Do not set the initial properties until we reach the main loop,
- * so that the application has a chance to call
- * egg_set_desktop_file(). (This may also help the session manager
- * have a better idea of when the application is fully up and
- * running.)
- */
- xsmp->waiting_to_set_initial_properties = TRUE;
- xsmp->idle = g_idle_add (sm_client_xsmp_set_initial_properties, client);
-}
-
-static void
-sm_client_xsmp_set_restart_command (EggSMClient *client,
- int argc,
- const char **argv)
-{
- EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
- int i;
-
- g_strfreev (xsmp->restart_command);
-
- xsmp->restart_command = g_new (char *, argc + 1);
- for (i = 0; i < argc; i++)
- xsmp->restart_command[i] = g_strdup (argv[i]);
- xsmp->restart_command[i] = NULL;
-
- xsmp->set_restart_command = TRUE;
-}
-
-static void
-sm_client_xsmp_will_quit (EggSMClient *client,
- gboolean will_quit)
-{
- EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
-
- if (xsmp->state == XSMP_STATE_CONNECTION_CLOSED)
- {
- /* The session manager has already exited! Schedule a quit
- * signal.
- */
- xsmp->waiting_to_emit_quit = TRUE;
- update_pending_events (xsmp);
- return;
- }
- else if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED)
- {
- /* We received a ShutdownCancelled message while the application
- * was interacting; Schedule a quit_cancelled signal.
- */
- xsmp->waiting_to_emit_quit_cancelled = TRUE;
- update_pending_events (xsmp);
- return;
- }
-
- g_return_if_fail (xsmp->state == XSMP_STATE_INTERACT);
-
- g_debug ("Sending InteractDone(%s)", will_quit ? "False" : "True");
- SmcInteractDone (xsmp->connection, !will_quit);
-
- if (will_quit && xsmp->need_save_state)
- save_state (xsmp);
-
- g_debug ("Sending SaveYourselfDone(%s)", will_quit ? "True" : "False");
- SmcSaveYourselfDone (xsmp->connection, will_quit);
- xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
-}
-
-static gboolean
-sm_client_xsmp_end_session (EggSMClient *client,
- EggSMClientEndStyle style,
- gboolean request_confirmation)
-{
- EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
- int save_type;
-
- /* To end the session via XSMP, we have to send a
- * SaveYourselfRequest. We aren't allowed to do that if anything
- * else is going on, but we don't want to expose this fact to the
- * application. So we do our best to patch things up here...
- *
- * In the worst case, this method might block for some length of
- * time in process_ice_messages, but the only time that code path is
- * honestly likely to get hit is if the application tries to end the
- * session as the very first thing it does, in which case it
- * probably won't actually block anyway. It's not worth gunking up
- * the API to try to deal nicely with the other 0.01% of cases where
- * this happens.
- */
-
- while (xsmp->state != XSMP_STATE_IDLE ||
- xsmp->expecting_initial_save_yourself)
- {
- /* If we're already shutting down, we don't need to do anything. */
- if (xsmp->shutting_down)
- return TRUE;
-
- switch (xsmp->state)
- {
- case XSMP_STATE_CONNECTION_CLOSED:
- return FALSE;
-
- case XSMP_STATE_SAVE_YOURSELF:
- /* Trying to log out from the save_state callback? Whatever.
- * Abort the save_state.
- */
- SmcSaveYourselfDone (xsmp->connection, FALSE);
- xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
- break;
-
- case XSMP_STATE_INTERACT_REQUEST:
- case XSMP_STATE_INTERACT:
- case XSMP_STATE_SHUTDOWN_CANCELLED:
- /* Already in a shutdown-related state, just ignore
- * the new shutdown request...
- */
- return TRUE;
-
- case XSMP_STATE_IDLE:
- if (xsmp->waiting_to_set_initial_properties)
- sm_client_xsmp_set_initial_properties (xsmp);
-
- if (!xsmp->expecting_initial_save_yourself)
- break;
- /* else fall through */
-
- case XSMP_STATE_SAVE_YOURSELF_DONE:
- /* We need to wait for some response from the server.*/
- process_ice_messages (SmcGetIceConnection (xsmp->connection));
- break;
-
- default:
- /* Hm... shouldn't happen */
- return FALSE;
- }
- }
-
- /* xfce4-session will do the wrong thing if we pass SmSaveGlobal and
- * the user chooses to save the session. But gnome-session will do
- * the wrong thing if we pass SmSaveBoth and the user chooses NOT to
- * save the session... Sigh.
- */
- if (!strcmp (SmcVendor (xsmp->connection), "xfce4-session"))
- save_type = SmSaveBoth;
- else
- save_type = SmSaveGlobal;
-
- g_debug ("Sending SaveYourselfRequest(SmSaveGlobal, Shutdown, SmInteractStyleAny, %sFast)", request_confirmation ? "!" : "");
- SmcRequestSaveYourself (xsmp->connection,
- save_type,
- True, /* shutdown */
- SmInteractStyleAny,
- !request_confirmation, /* fast */
- True /* global */);
- return TRUE;
-}
-
-static gboolean
-idle_do_pending_events (gpointer data)
-{
- EggSMClientXSMP *xsmp = data;
- EggSMClient *client = data;
-
- gdk_threads_enter ();
-
- xsmp->idle = 0;
-
- if (xsmp->waiting_to_emit_quit)
- {
- xsmp->waiting_to_emit_quit = FALSE;
- egg_sm_client_quit (client);
- goto out;
- }
-
- if (xsmp->waiting_to_emit_quit_cancelled)
- {
- xsmp->waiting_to_emit_quit_cancelled = FALSE;
- egg_sm_client_quit_cancelled (client);
- xsmp->state = XSMP_STATE_IDLE;
- }
-
- if (xsmp->waiting_to_save_myself)
- {
- xsmp->waiting_to_save_myself = FALSE;
- do_save_yourself (xsmp);
- }
-
- out:
- gdk_threads_leave ();
- return FALSE;
-}
-
-static void
-update_pending_events (EggSMClientXSMP *xsmp)
-{
- gboolean want_idle =
- xsmp->waiting_to_emit_quit ||
- xsmp->waiting_to_emit_quit_cancelled ||
- xsmp->waiting_to_save_myself;
-
- if (want_idle)
- {
- if (xsmp->idle == 0)
- xsmp->idle = g_idle_add (idle_do_pending_events, xsmp);
- }
- else
- {
- if (xsmp->idle != 0)
- g_source_remove (xsmp->idle);
- xsmp->idle = 0;
- }
-}
-
-static void
-fix_broken_state (EggSMClientXSMP *xsmp, const char *message,
- gboolean send_interact_done,
- gboolean send_save_yourself_done)
-{
- g_warning ("Received XSMP %s message in state %s: client or server error",
- message, EGG_SM_CLIENT_XSMP_STATE (xsmp));
-
- /* Forget any pending SaveYourself plans we had */
- xsmp->waiting_to_save_myself = FALSE;
- update_pending_events (xsmp);
-
- if (send_interact_done)
- SmcInteractDone (xsmp->connection, False);
- if (send_save_yourself_done)
- SmcSaveYourselfDone (xsmp->connection, True);
-
- xsmp->state = send_save_yourself_done ? XSMP_STATE_SAVE_YOURSELF_DONE : XSMP_STATE_IDLE;
-}
-
-/* SM callbacks */
-
-static void
-xsmp_save_yourself (SmcConn smc_conn,
- SmPointer client_data,
- int save_type,
- Bool shutdown,
- int interact_style,
- Bool fast)
-{
- EggSMClientXSMP *xsmp = client_data;
- gboolean wants_quit_requested;
-
- g_debug ("Received SaveYourself(%s, %s, %s, %s) in state %s",
- save_type == SmSaveLocal ? "SmSaveLocal" :
- save_type == SmSaveGlobal ? "SmSaveGlobal" : "SmSaveBoth",
- shutdown ? "Shutdown" : "!Shutdown",
- interact_style == SmInteractStyleAny ? "SmInteractStyleAny" :
- interact_style == SmInteractStyleErrors ? "SmInteractStyleErrors" :
- "SmInteractStyleNone", fast ? "Fast" : "!Fast",
- EGG_SM_CLIENT_XSMP_STATE (xsmp));
-
- if (xsmp->state != XSMP_STATE_IDLE &&
- xsmp->state != XSMP_STATE_SHUTDOWN_CANCELLED)
- {
- fix_broken_state (xsmp, "SaveYourself", FALSE, TRUE);
- return;
- }
-
- if (xsmp->waiting_to_set_initial_properties)
- sm_client_xsmp_set_initial_properties (xsmp);
-
- /* If this is the initial SaveYourself, ignore it; we've already set
- * properties and there's no reason to actually save state too.
- */
- if (xsmp->expecting_initial_save_yourself)
- {
- xsmp->expecting_initial_save_yourself = FALSE;
-
- if (save_type == SmSaveLocal &&
- interact_style == SmInteractStyleNone &&
- !shutdown && !fast)
- {
- g_debug ("Sending SaveYourselfDone(True) for initial SaveYourself");
- SmcSaveYourselfDone (xsmp->connection, True);
- /* As explained in the comment at the end of
- * do_save_yourself(), SAVE_YOURSELF_DONE is the correct
- * state here, not IDLE.
- */
- xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
- return;
- }
- else
- g_warning ("First SaveYourself was not the expected one!");
- }
-
- /* Even ignoring the "fast" flag completely, there are still 18
- * different combinations of save_type, shutdown and interact_style.
- * We interpret them as follows:
- *
- * Type Shutdown Interact Interpretation
- * G F A/E/N do nothing (1)
- * G T N do nothing (1)*
- * G T A/E quit_requested (2)
- * L/B F A/E/N save_state (3)
- * L/B T N save_state (3)*
- * L/B T A/E quit_requested, then save_state (4)
- *
- * 1. Do nothing, because the SM asked us to do something
- * uninteresting (save open files, but then don't quit
- * afterward) or rude (save open files without asking the user
- * for confirmation).
- *
- * 2. Request interaction and then emit ::quit_requested. This
- * perhaps isn't quite correct for the SmInteractStyleErrors
- * case, but we don't care.
- *
- * 3. Emit ::save_state. The SmSaveBoth SaveYourselfs in these
- * rows essentially get demoted to SmSaveLocal, because their
- * Global halves correspond to "do nothing".
- *
- * 4. Request interaction, emit ::quit_requested, and then emit
- * ::save_state after interacting. This is the SmSaveBoth
- * equivalent of #2, but we also promote SmSaveLocal shutdown
- * SaveYourselfs to SmSaveBoth here, because we want to give
- * the user a chance to save open files before quitting.
- *
- * (* It would be nice if we could do something useful when the
- * session manager sends a SaveYourself with shutdown True and
- * SmInteractStyleNone. But we can't, so we just pretend it didn't
- * even tell us it was shutting down. The docs for ::quit mention
- * that it might not always be preceded by ::quit_requested.)
- */
-
- /* As an optimization, we don't actually request interaction and
- * emit ::quit_requested if the application isn't listening to the
- * signal.
- */
- wants_quit_requested = g_signal_has_handler_pending (xsmp, g_signal_lookup ("quit_requested", EGG_TYPE_SM_CLIENT), 0, FALSE);
-
- xsmp->need_save_state = (save_type != SmSaveGlobal);
- xsmp->need_quit_requested = (shutdown && wants_quit_requested &&
- interact_style != SmInteractStyleNone);
- xsmp->interact_errors = (interact_style == SmInteractStyleErrors);
-
- xsmp->shutting_down = shutdown;
-
- do_save_yourself (xsmp);
-}
-
-static void
-do_save_yourself (EggSMClientXSMP *xsmp)
-{
- if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED)
- {
- /* The SM cancelled a previous SaveYourself, but we haven't yet
- * had a chance to tell the application, so we can't start
- * processing this SaveYourself yet.
- */
- xsmp->waiting_to_save_myself = TRUE;
- update_pending_events (xsmp);
- return;
- }
-
- if (xsmp->need_quit_requested)
- {
- xsmp->state = XSMP_STATE_INTERACT_REQUEST;
-
- g_debug ("Sending InteractRequest(%s)",
- xsmp->interact_errors ? "Error" : "Normal");
- SmcInteractRequest (xsmp->connection,
- xsmp->interact_errors ? SmDialogError : SmDialogNormal,
- xsmp_interact,
- xsmp);
- return;
- }
-
- if (xsmp->need_save_state)
- {
- save_state (xsmp);
-
- /* Though unlikely, the client could have been disconnected
- * while the application was saving its state.
- */
- if (!xsmp->connection)
- return;
- }
-
- g_debug ("Sending SaveYourselfDone(True)");
- SmcSaveYourselfDone (xsmp->connection, True);
-
- /* The client state diagram in the XSMP spec says that after a
- * non-shutdown SaveYourself, we go directly back to "idle". But
- * everything else in both the XSMP spec and the libSM docs
- * disagrees.
- */
- xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
-}
-
-static void
-save_state (EggSMClientXSMP *xsmp)
-{
- GKeyFile *state_file;
- char *state_file_path, *data;
- EggDesktopFile *desktop_file;
- GPtrArray *restart;
- int offset, fd;
-
- /* We set xsmp->state before emitting save_state, but our caller is
- * responsible for setting it back afterward.
- */
- xsmp->state = XSMP_STATE_SAVE_YOURSELF;
-
- state_file = egg_sm_client_save_state ((EggSMClient *)xsmp);
- if (!state_file)
- {
- restart = generate_command (xsmp->restart_command, xsmp->client_id, NULL);
- set_properties (xsmp,
- ptrarray_prop (SmRestartCommand, restart),
- NULL);
- g_ptr_array_free (restart, TRUE);
- delete_properties (xsmp, SmDiscardCommand, NULL);
- return;
- }
-
- desktop_file = egg_get_desktop_file ();
- if (desktop_file)
- {
- GKeyFile *merged_file;
- char *desktop_file_path;
-
- merged_file = g_key_file_new ();
- desktop_file_path =
- g_filename_from_uri (egg_desktop_file_get_source (desktop_file),
- NULL, NULL);
- if (desktop_file_path &&
- g_key_file_load_from_file (merged_file, desktop_file_path,
- G_KEY_FILE_KEEP_COMMENTS |
- G_KEY_FILE_KEEP_TRANSLATIONS, NULL))
- {
- guint g, k, i;
- char **groups, **keys, *value, *exec;
-
- groups = g_key_file_get_groups (state_file, NULL);
- for (g = 0; groups[g]; g++)
- {
- keys = g_key_file_get_keys (state_file, groups[g], NULL, NULL);
- for (k = 0; keys[k]; k++)
- {
- value = g_key_file_get_value (state_file, groups[g],
- keys[k], NULL);
- if (value)
- {
- g_key_file_set_value (merged_file, groups[g],
- keys[k], value);
- g_free (value);
- }
- }
- g_strfreev (keys);
- }
- g_strfreev (groups);
-
- g_key_file_free (state_file);
- state_file = merged_file;
-
- /* Update Exec key using "--sm-client-state-file %k" */
- restart = generate_command (xsmp->restart_command,
- NULL, "%k");
- for (i = 0; i < restart->len; i++)
- restart->pdata[i] = g_shell_quote (restart->pdata[i]);
- g_ptr_array_add (restart, NULL);
- exec = g_strjoinv (" ", (char **)restart->pdata);
- g_strfreev ((char **)restart->pdata);
- g_ptr_array_free (restart, FALSE);
-
- g_key_file_set_string (state_file, EGG_DESKTOP_FILE_GROUP,
- EGG_DESKTOP_FILE_KEY_EXEC,
- exec);
- g_free (exec);
- }
- else
- desktop_file = NULL;
-
- g_free (desktop_file_path);
- }
-
- /* Now write state_file to disk. (We can't use mktemp(), because
- * that requires the filename to end with "XXXXXX", and we want
- * it to end with ".desktop".)
- */
-
- data = g_key_file_to_data (state_file, NULL, NULL);
- g_key_file_free (state_file);
-
- offset = 0;
- while (1)
- {
- state_file_path = g_strdup_printf ("%s%csession-state%c%s-%ld.%s",
- g_get_user_config_dir (),
- G_DIR_SEPARATOR, G_DIR_SEPARATOR,
- g_get_prgname (),
- (long)time (NULL) + offset,
- desktop_file ? "desktop" : "state");
-
- fd = open (state_file_path, O_WRONLY | O_CREAT | O_EXCL, 0644);
- if (fd == -1)
- {
- if (errno == EEXIST)
- {
- offset++;
- g_free (state_file_path);
- continue;
- }
- else if (errno == ENOTDIR || errno == ENOENT)
- {
- char *sep = strrchr (state_file_path, G_DIR_SEPARATOR);
-
- *sep = '\0';
- if (g_mkdir_with_parents (state_file_path, 0755) != 0)
- {
- g_warning ("Could not create directory '%s'",
- state_file_path);
- g_free (state_file_path);
- state_file_path = NULL;
- break;
- }
-
- continue;
- }
-
- g_warning ("Could not create file '%s': %s",
- state_file_path, g_strerror (errno));
- g_free (state_file_path);
- state_file_path = NULL;
- break;
- }
-
- close (fd);
- g_file_set_contents (state_file_path, data, -1, NULL);
- break;
- }
- g_free (data);
-
- restart = generate_command (xsmp->restart_command, xsmp->client_id,
- state_file_path);
- set_properties (xsmp,
- ptrarray_prop (SmRestartCommand, restart),
- NULL);
- g_ptr_array_free (restart, TRUE);
-
- if (state_file_path)
- {
- set_properties (xsmp,
- array_prop (SmDiscardCommand,
- "/bin/rm", "-rf", state_file_path,
- NULL),
- NULL);
- g_free (state_file_path);
- }
-}
-
-static void
-xsmp_interact (SmcConn smc_conn,
- SmPointer client_data)
-{
- EggSMClientXSMP *xsmp = client_data;
- EggSMClient *client = client_data;
-
- g_debug ("Received Interact message in state %s",
- EGG_SM_CLIENT_XSMP_STATE (xsmp));
-
- if (xsmp->state != XSMP_STATE_INTERACT_REQUEST)
- {
- fix_broken_state (xsmp, "Interact", TRUE, TRUE);
- return;
- }
-
- xsmp->state = XSMP_STATE_INTERACT;
- egg_sm_client_quit_requested (client);
-}
-
-static void
-xsmp_die (SmcConn smc_conn,
- SmPointer client_data)
-{
- EggSMClientXSMP *xsmp = client_data;
- EggSMClient *client = client_data;
-
- g_debug ("Received Die message in state %s",
- EGG_SM_CLIENT_XSMP_STATE (xsmp));
-
- sm_client_xsmp_disconnect (xsmp);
- egg_sm_client_quit (client);
-}
-
-static void
-xsmp_save_complete (SmcConn smc_conn,
- SmPointer client_data)
-{
- EggSMClientXSMP *xsmp = client_data;
-
- g_debug ("Received SaveComplete message in state %s",
- EGG_SM_CLIENT_XSMP_STATE (xsmp));
-
- if (xsmp->state == XSMP_STATE_SAVE_YOURSELF_DONE)
- xsmp->state = XSMP_STATE_IDLE;
- else
- fix_broken_state (xsmp, "SaveComplete", FALSE, FALSE);
-}
-
-static void
-xsmp_shutdown_cancelled (SmcConn smc_conn,
- SmPointer client_data)
-{
- EggSMClientXSMP *xsmp = client_data;
- EggSMClient *client = client_data;
-
- g_debug ("Received ShutdownCancelled message in state %s",
- EGG_SM_CLIENT_XSMP_STATE (xsmp));
-
- xsmp->shutting_down = FALSE;
-
- if (xsmp->state == XSMP_STATE_SAVE_YOURSELF_DONE)
- {
- /* We've finished interacting and now the SM has agreed to
- * cancel the shutdown.
- */
- xsmp->state = XSMP_STATE_IDLE;
- egg_sm_client_quit_cancelled (client);
- }
- else if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED)
- {
- /* Hm... ok, so we got a shutdown SaveYourself, which got
- * cancelled, but the application was still interacting, so we
- * didn't tell it yet, and then *another* SaveYourself arrived,
- * which we must still be waiting to tell the app about, except
- * that now that SaveYourself has been cancelled too! Dizzy yet?
- */
- xsmp->waiting_to_save_myself = FALSE;
- update_pending_events (xsmp);
- }
- else
- {
- g_debug ("Sending SaveYourselfDone(False)");
- SmcSaveYourselfDone (xsmp->connection, False);
-
- if (xsmp->state == XSMP_STATE_INTERACT)
- {
- /* The application is currently interacting, so we can't
- * tell it about the cancellation yet; we will wait until
- * after it calls egg_sm_client_will_quit().
- */
- xsmp->state = XSMP_STATE_SHUTDOWN_CANCELLED;
- }
- else
- {
- /* The shutdown was cancelled before the application got a
- * chance to interact.
- */
- xsmp->state = XSMP_STATE_IDLE;
- }
- }
-}
-
-/* Utilities */
-
-/* Create a restart/clone/Exec command based on @restart_command.
- * If @client_id is non-%NULL, add "--sm-client-id @client_id".
- * If @state_file is non-%NULL, add "--sm-client-state-file @state_file".
- *
- * None of the input strings are g_strdup()ed; the caller must keep
- * them around until it is done with the returned GPtrArray, and must
- * then free the array, but not its contents.
- */
-static GPtrArray *
-generate_command (char **restart_command, const char *client_id,
- const char *state_file)
-{
- GPtrArray *cmd;
- int i;
-
- cmd = g_ptr_array_new ();
- g_ptr_array_add (cmd, restart_command[0]);
-
- if (client_id)
- {
- g_ptr_array_add (cmd, "--sm-client-id");
- g_ptr_array_add (cmd, (char *)client_id);
- }
-
- if (state_file)
- {
- g_ptr_array_add (cmd, "--sm-client-state-file");
- g_ptr_array_add (cmd, (char *)state_file);
- }
-
- for (i = 1; restart_command[i]; i++)
- g_ptr_array_add (cmd, restart_command[i]);
-
- return cmd;
-}
-
-/* Takes a NULL-terminated list of SmProp * values, created by
- * array_prop, ptrarray_prop, string_prop, card8_prop, sets them, and
- * frees them.
- */
-static void
-set_properties (EggSMClientXSMP *xsmp, ...)
-{
- GPtrArray *props;
- SmProp *prop;
- va_list ap;
- guint i;
-
- props = g_ptr_array_new ();
-
- va_start (ap, xsmp);
- while ((prop = va_arg (ap, SmProp *)))
- g_ptr_array_add (props, prop);
- va_end (ap);
-
- if (xsmp->connection)
- {
- SmcSetProperties (xsmp->connection, props->len,
- (SmProp **)props->pdata);
- }
-
- for (i = 0; i < props->len; i++)
- {
- prop = props->pdata[i];
- g_free (prop->vals);
- g_free (prop);
- }
- g_ptr_array_free (props, TRUE);
-}
-
-/* Takes a NULL-terminated list of property names and deletes them. */
-static void
-delete_properties (EggSMClientXSMP *xsmp, ...)
-{
- GPtrArray *props;
- char *prop;
- va_list ap;
-
- if (!xsmp->connection)
- return;
-
- props = g_ptr_array_new ();
-
- va_start (ap, xsmp);
- while ((prop = va_arg (ap, char *)))
- g_ptr_array_add (props, prop);
- va_end (ap);
-
- SmcDeleteProperties (xsmp->connection, props->len,
- (char **)props->pdata);
-
- g_ptr_array_free (props, TRUE);
-}
-
-/* Takes an array of strings and creates a LISTofARRAY8 property. The
- * strings are neither dupped nor freed; they need to remain valid
- * until you're done with the SmProp.
- */
-static SmProp *
-array_prop (const char *name, ...)
-{
- SmProp *prop;
- SmPropValue pv;
- GArray *vals;
- char *value;
- va_list ap;
-
- prop = g_new (SmProp, 1);
- prop->name = (char *)name;
- prop->type = SmLISTofARRAY8;
-
- vals = g_array_new (FALSE, FALSE, sizeof (SmPropValue));
-
- va_start (ap, name);
- while ((value = va_arg (ap, char *)))
- {
- pv.length = strlen (value);
- pv.value = value;
- g_array_append_val (vals, pv);
- }
-
- prop->num_vals = vals->len;
- prop->vals = (SmPropValue *)vals->data;
-
- g_array_free (vals, FALSE);
-
- return prop;
-}
-
-/* Takes a GPtrArray of strings and creates a LISTofARRAY8 property.
- * The array contents are neither dupped nor freed; they need to
- * remain valid until you're done with the SmProp.
- */
-static SmProp *
-ptrarray_prop (const char *name, GPtrArray *values)
-{
- SmProp *prop;
- SmPropValue pv;
- GArray *vals;
- guint i;
-
- prop = g_new (SmProp, 1);
- prop->name = (char *)name;
- prop->type = SmLISTofARRAY8;
-
- vals = g_array_new (FALSE, FALSE, sizeof (SmPropValue));
-
- for (i = 0; i < values->len; i++)
- {
- pv.length = strlen (values->pdata[i]);
- pv.value = values->pdata[i];
- g_array_append_val (vals, pv);
- }
-
- prop->num_vals = vals->len;
- prop->vals = (SmPropValue *)vals->data;
-
- g_array_free (vals, FALSE);
-
- return prop;
-}
-
-/* Takes a string and creates an ARRAY8 property. The string is
- * neither dupped nor freed; it needs to remain valid until you're
- * done with the SmProp.
- */
-static SmProp *
-string_prop (const char *name, const char *value)
-{
- SmProp *prop;
-
- prop = g_new (SmProp, 1);
- prop->name = (char *)name;
- prop->type = SmARRAY8;
-
- prop->num_vals = 1;
- prop->vals = g_new (SmPropValue, 1);
-
- prop->vals[0].length = strlen (value);
- prop->vals[0].value = (char *)value;
-
- return prop;
-}
-
-/* Takes a char and creates a CARD8 property. */
-static SmProp *
-card8_prop (const char *name, unsigned char value)
-{
- SmProp *prop;
- char *card8val;
-
- /* To avoid having to allocate and free prop->vals[0], we cheat and
- * make vals a 2-element-long array and then use the second element
- * to store value.
- */
-
- prop = g_new (SmProp, 1);
- prop->name = (char *)name;
- prop->type = SmCARD8;
-
- prop->num_vals = 1;
- prop->vals = g_new (SmPropValue, 2);
- card8val = (char *)(&prop->vals[1]);
- card8val[0] = value;
-
- prop->vals[0].length = 1;
- prop->vals[0].value = card8val;
-
- return prop;
-}
-
-/* ICE code. This makes no effort to play nice with anyone else trying
- * to use libICE. Fortunately, no one uses libICE for anything other
- * than SM. (DCOP uses ICE, but it has its own private copy of
- * libICE.)
- *
- * When this moves to gtk, it will need to be cleverer, to avoid
- * tripping over old apps that use GnomeClient or that use libSM
- * directly.
- */
-
-#include <X11/ICE/ICElib.h>
-#include <fcntl.h>
-
-static void ice_error_handler (IceConn ice_conn,
- Bool swap,
- int offending_minor_opcode,
- unsigned long offending_sequence,
- int error_class,
- int severity,
- IcePointer values);
-static void ice_io_error_handler (IceConn ice_conn);
-static void ice_connection_watch (IceConn ice_conn,
- IcePointer client_data,
- Bool opening,
- IcePointer *watch_data);
-
-static void
-ice_init (void)
-{
- IceSetIOErrorHandler (ice_io_error_handler);
- IceSetErrorHandler (ice_error_handler);
- IceAddConnectionWatch (ice_connection_watch, NULL);
-}
-
-static gboolean
-process_ice_messages (IceConn ice_conn)
-{
- IceProcessMessagesStatus status;
-
- gdk_threads_enter ();
- status = IceProcessMessages (ice_conn, NULL, NULL);
- gdk_threads_leave ();
-
- switch (status)
- {
- case IceProcessMessagesSuccess:
- return TRUE;
-
- case IceProcessMessagesIOError:
- sm_client_xsmp_disconnect (IceGetConnectionContext (ice_conn));
- return FALSE;
-
- case IceProcessMessagesConnectionClosed:
- return FALSE;
-
- default:
- g_assert_not_reached ();
- }
-}
-
-static gboolean
-ice_iochannel_watch (GIOChannel *channel,
- GIOCondition condition,
- gpointer client_data)
-{
- return process_ice_messages (client_data);
-}
-
-static void
-ice_connection_watch (IceConn ice_conn,
- IcePointer client_data,
- Bool opening,
- IcePointer *watch_data)
-{
- guint watch_id;
-
- if (opening)
- {
- GIOChannel *channel;
- int fd = IceConnectionNumber (ice_conn);
-
- fcntl (fd, F_SETFD, fcntl (fd, F_GETFD, 0) | FD_CLOEXEC);
- channel = g_io_channel_unix_new (fd);
- watch_id = g_io_add_watch (channel, G_IO_IN | G_IO_ERR,
- ice_iochannel_watch, ice_conn);
- g_io_channel_unref (channel);
-
- *watch_data = GUINT_TO_POINTER (watch_id);
- }
- else
- {
- watch_id = GPOINTER_TO_UINT (*watch_data);
- g_source_remove (watch_id);
- }
-}
-
-static void
-ice_error_handler (IceConn ice_conn,
- Bool swap,
- int offending_minor_opcode,
- unsigned long offending_sequence,
- int error_class,
- int severity,
- IcePointer values)
-{
- /* Do nothing */
-}
-
-static void
-ice_io_error_handler (IceConn ice_conn)
-{
- /* Do nothing */
-}
-
-static void
-smc_error_handler (SmcConn smc_conn,
- Bool swap,
- int offending_minor_opcode,
- unsigned long offending_sequence,
- int error_class,
- int severity,
- SmPointer values)
-{
- /* Do nothing */
-}
diff --git a/cut-n-paste-code/libegg/eggsmclient.c b/cut-n-paste-code/libegg/eggsmclient.c
deleted file mode 100644
index acb3d9337..000000000
--- a/cut-n-paste-code/libegg/eggsmclient.c
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
- * Copyright (C) 2007 Novell, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <glib/gi18n.h>
-
-#include "eggsmclient.h"
-#include "eggsmclient-private.h"
-
-static void egg_sm_client_debug_handler (const char *log_domain,
- GLogLevelFlags log_level,
- const char *message,
- gpointer user_data);
-
-enum {
- SAVE_STATE,
- QUIT_REQUESTED,
- QUIT_CANCELLED,
- QUIT,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL];
-
-struct _EggSMClientPrivate {
- GKeyFile *state_file;
-};
-
-#define EGG_SM_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EGG_TYPE_SM_CLIENT, EggSMClientPrivate))
-
-G_DEFINE_TYPE (EggSMClient, egg_sm_client, G_TYPE_OBJECT)
-
-static EggSMClient *global_client;
-static EggSMClientMode global_client_mode = EGG_SM_CLIENT_MODE_NORMAL;
-
-static void
-egg_sm_client_init (EggSMClient *client)
-{
- ;
-}
-
-static void
-egg_sm_client_class_init (EggSMClientClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- g_type_class_add_private (klass, sizeof (EggSMClientPrivate));
-
- /**
- * EggSMClient::save_state:
- * @client: the client
- * @state_file: a #GKeyFile to save state information into
- *
- * Emitted when the session manager has requested that the
- * application save information about its current state. The
- * application should save its state into @state_file, and then the
- * session manager may then restart the application in a future
- * session and tell it to initialize itself from that state.
- *
- * You should not save any data into @state_file's "start group"
- * (ie, the %NULL group). Instead, applications should save their
- * data into groups with names that start with the application name,
- * and libraries that connect to this signal should save their data
- * into groups with names that start with the library name.
- *
- * Alternatively, rather than (or in addition to) using @state_file,
- * the application can save its state by calling
- * egg_sm_client_set_restart_command() during the processing of this
- * signal (eg, to include a list of files to open).
- **/
- signals[SAVE_STATE] =
- g_signal_new ("save_state",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EggSMClientClass, save_state),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE,
- 1, G_TYPE_POINTER);
-
- /**
- * EggSMClient::quit_requested:
- * @client: the client
- *
- * Emitted when the session manager requests that the application
- * exit (generally because the user is logging out). The application
- * should decide whether or not it is willing to quit (perhaps after
- * asking the user what to do with documents that have unsaved
- * changes) and then call egg_sm_client_will_quit(), passing %TRUE
- * or %FALSE to give its answer to the session manager. (It does not
- * need to give an answer before returning from the signal handler;
- * it can interact with the user asynchronously and then give its
- * answer later on.) If the application does not connect to this
- * signal, then #EggSMClient will automatically return %TRUE on its
- * behalf.
- *
- * The application should not save its session state as part of
- * handling this signal; if the user has requested that the session
- * be saved when logging out, then ::save_state will be emitted
- * separately.
- *
- * If the application agrees to quit, it should then wait for either
- * the ::quit_cancelled or ::quit signals to be emitted.
- **/
- signals[QUIT_REQUESTED] =
- g_signal_new ("quit_requested",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EggSMClientClass, quit_requested),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-
- /**
- * EggSMClient::quit_cancelled:
- * @client: the client
- *
- * Emitted when the session manager decides to cancel a logout after
- * the application has already agreed to quit. After receiving this
- * signal, the application can go back to what it was doing before
- * receiving the ::quit_requested signal.
- **/
- signals[QUIT_CANCELLED] =
- g_signal_new ("quit_cancelled",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EggSMClientClass, quit_cancelled),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-
- /**
- * EggSMClient::quit:
- * @client: the client
- *
- * Emitted when the session manager wants the application to quit
- * (generally because the user is logging out). The application
- * should exit as soon as possible after receiving this signal; if
- * it does not, the session manager may choose to forcibly kill it.
- *
- * Normally a GUI application would only be sent a ::quit if it
- * agreed to quit in response to a ::quit_requested signal. However,
- * this is not guaranteed; in some situations the session manager
- * may decide to end the session without giving applications a
- * chance to object.
- **/
- signals[QUIT] =
- g_signal_new ("quit",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EggSMClientClass, quit),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-}
-
-static gboolean sm_client_disable = FALSE;
-static char *sm_client_state_file = NULL;
-static char *sm_client_id = NULL;
-static char *sm_config_prefix = NULL;
-
-static gboolean
-sm_client_post_parse_func (GOptionContext *context,
- GOptionGroup *group,
- gpointer data,
- GError **error)
-{
- EggSMClient *client;
-
- if (sm_client_id == NULL)
- {
- const gchar *desktop_autostart_id;
-
- desktop_autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID");
-
- if (desktop_autostart_id != NULL)
- sm_client_id = g_strdup (desktop_autostart_id);
- }
-
- /* Unset DESKTOP_AUTOSTART_ID in order to avoid child processes to
- * use the same client id. */
- g_unsetenv ("DESKTOP_AUTOSTART_ID");
-
- if (global_client_mode != EGG_SM_CLIENT_MODE_DISABLED)
- {
- client = egg_sm_client_get ();
-
- if (EGG_SM_CLIENT_GET_CLASS (client)->startup)
- EGG_SM_CLIENT_GET_CLASS (client)->startup (client, sm_client_id);
- }
-
- return TRUE;
-}
-
-/**
- * egg_sm_client_get_option_group:
- *
- * Creates a %GOptionGroup containing the session-management-related
- * options. You should add this group to the application's
- * %GOptionContext if you want to use #EggSMClient.
- *
- * Return value: the %GOptionGroup
- **/
-GOptionGroup *
-egg_sm_client_get_option_group (void)
-{
- const GOptionEntry entries[] = {
- { "sm-client-disable", 0, 0,
- G_OPTION_ARG_NONE, &sm_client_disable,
- N_("Disable connection to session manager"), NULL },
- { "sm-client-state-file", 0, 0,
- G_OPTION_ARG_FILENAME, &sm_client_state_file,
- N_("Specify file containing saved configuration"), N_("FILE") },
- { "sm-client-id", 0, 0,
- G_OPTION_ARG_STRING, &sm_client_id,
- N_("Specify session management ID"), N_("ID") },
- /* GnomeClient compatibility option */
- { "sm-disable", 0, G_OPTION_FLAG_HIDDEN,
- G_OPTION_ARG_NONE, &sm_client_disable,
- NULL, NULL },
- /* GnomeClient compatibility option. This is a dummy option that only
- * exists so that sessions saved by apps with GnomeClient can be restored
- * later when they've switched to EggSMClient. See bug #575308.
- */
- { "sm-config-prefix", 0, G_OPTION_FLAG_HIDDEN,
- G_OPTION_ARG_STRING, &sm_config_prefix,
- NULL, NULL },
- { NULL }
- };
- GOptionGroup *group;
-
- /* Use our own debug handler for the "EggSMClient" domain. */
- g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,
- egg_sm_client_debug_handler, NULL);
-
- group = g_option_group_new ("sm-client",
- _("Session management options:"),
- _("Show session management options"),
- NULL, NULL);
- g_option_group_add_entries (group, entries);
- g_option_group_set_parse_hooks (group, NULL, sm_client_post_parse_func);
-
- return group;
-}
-
-/**
- * egg_sm_client_set_mode:
- * @mode: an #EggSMClient mode
- *
- * Sets the "mode" of #EggSMClient as follows:
- *
- * %EGG_SM_CLIENT_MODE_DISABLED: Session management is completely
- * disabled, until the mode is changed again. The application will
- * not even connect to the session manager. (egg_sm_client_get()
- * will still return an #EggSMClient object.)
- *
- * %EGG_SM_CLIENT_MODE_NO_RESTART: The application will connect to
- * the session manager (and thus will receive notification when the
- * user is logging out, etc), but will request to not be
- * automatically restarted with saved state in future sessions.
- *
- * %EGG_SM_CLIENT_MODE_NORMAL: The default. #EggSMCLient will
- * function normally.
- *
- * This must be called before the application's main loop begins and
- * before any call to egg_sm_client_get(), unless the mode was set
- * earlier to %EGG_SM_CLIENT_MODE_DISABLED and this call enables
- * session management. Note that option parsing will call
- * egg_sm_client_get().
- **/
-void
-egg_sm_client_set_mode (EggSMClientMode mode)
-{
- EggSMClientMode old_mode = global_client_mode;
-
- g_return_if_fail (global_client == NULL || global_client_mode == EGG_SM_CLIENT_MODE_DISABLED);
- g_return_if_fail (!(global_client != NULL && mode == EGG_SM_CLIENT_MODE_DISABLED));
-
- global_client_mode = mode;
-
- if (global_client != NULL && old_mode == EGG_SM_CLIENT_MODE_DISABLED)
- {
- if (EGG_SM_CLIENT_GET_CLASS (global_client)->startup)
- EGG_SM_CLIENT_GET_CLASS (global_client)->startup (global_client, sm_client_id);
- }
-}
-
-/**
- * egg_sm_client_get_mode:
- *
- * Gets the global #EggSMClientMode. See egg_sm_client_set_mode()
- * for details.
- *
- * Return value: the global #EggSMClientMode
- **/
-EggSMClientMode
-egg_sm_client_get_mode (void)
-{
- return global_client_mode;
-}
-
-/**
- * egg_sm_client_get:
- *
- * Returns the master #EggSMClient for the application.
- *
- * On platforms that support saved sessions (ie, POSIX/X11), the
- * application will only request to be restarted by the session
- * manager if you call egg_set_desktop_file() to set an application
- * desktop file. In particular, if the desktop file contains the key
- * "X
- *
- * Return value: the master #EggSMClient.
- **/
-EggSMClient *
-egg_sm_client_get (void)
-{
- if (!global_client)
- {
- if (!sm_client_disable)
- {
-#if defined (GDK_WINDOWING_WIN32)
- global_client = egg_sm_client_win32_new ();
-#elif defined (GDK_WINDOWING_QUARTZ)
- global_client = egg_sm_client_osx_new ();
-#else
- /* If both D-Bus and XSMP are compiled in, try XSMP first
- * (since it supports state saving) and fall back to D-Bus
- * if XSMP isn't available.
- */
-# ifdef EGG_SM_CLIENT_BACKEND_XSMP
- global_client = egg_sm_client_xsmp_new ();
-# endif
-# ifdef EGG_SM_CLIENT_BACKEND_DBUS
- if (!global_client)
- global_client = egg_sm_client_dbus_new ();
-# endif
-#endif
- }
-
- /* Fallback: create a dummy client, so that callers don't have
- * to worry about a %NULL return value.
- */
- if (!global_client)
- global_client = g_object_new (EGG_TYPE_SM_CLIENT, NULL);
- }
-
- return global_client;
-}
-
-/**
- * egg_sm_client_is_resumed:
- * @client: the client
- *
- * Checks whether or not the current session has been resumed from
- * a previous saved session. If so, the application should call
- * egg_sm_client_get_state_file() and restore its state from the
- * returned #GKeyFile.
- *
- * Return value: %TRUE if the session has been resumed
- **/
-gboolean
-egg_sm_client_is_resumed (EggSMClient *client)
-{
- g_return_val_if_fail (client == global_client, FALSE);
-
- return sm_client_state_file != NULL;
-}
-
-/**
- * egg_sm_client_get_state_file:
- * @client: the client
- *
- * If the application was resumed by the session manager, this will
- * return the #GKeyFile containing its state from the previous
- * session.
- *
- * Note that other libraries and #EggSMClient itself may also store
- * state in the key file, so if you call egg_sm_client_get_groups(),
- * on it, the return value will likely include groups that you did not
- * put there yourself. (It is also not guaranteed that the first
- * group created by the application will still be the "start group"
- * when it is resumed.)
- *
- * Return value: the #GKeyFile containing the application's earlier
- * state, or %NULL on error. You should not free this key file; it
- * is owned by @client.
- **/
-GKeyFile *
-egg_sm_client_get_state_file (EggSMClient *client)
-{
- EggSMClientPrivate *priv = EGG_SM_CLIENT_GET_PRIVATE (client);
- char *state_file_path;
- GError *err = NULL;
-
- g_return_val_if_fail (client == global_client, NULL);
-
- if (!sm_client_state_file)
- return NULL;
- if (priv->state_file)
- return priv->state_file;
-
- if (!strncmp (sm_client_state_file, "file://", 7))
- state_file_path = g_filename_from_uri (sm_client_state_file, NULL, NULL);
- else
- state_file_path = g_strdup (sm_client_state_file);
-
- priv->state_file = g_key_file_new ();
- if (!g_key_file_load_from_file (priv->state_file, state_file_path, 0, &err))
- {
- g_warning ("Could not load SM state file '%s': %s",
- sm_client_state_file, err->message);
- g_clear_error (&err);
- g_key_file_free (priv->state_file);
- priv->state_file = NULL;
- }
-
- g_free (state_file_path);
- return priv->state_file;
-}
-
-/**
- * egg_sm_client_set_restart_command:
- * @client: the client
- * @argc: the length of @argv
- * @argv: argument vector
- *
- * Sets the command used to restart @client if it does not have a
- * .desktop file that can be used to find its restart command.
- *
- * This can also be used when handling the ::save_state signal, to
- * save the current state via an updated command line. (Eg, providing
- * a list of filenames to open when the application is resumed.)
- **/
-void
-egg_sm_client_set_restart_command (EggSMClient *client,
- int argc,
- const char **argv)
-{
- g_return_if_fail (EGG_IS_SM_CLIENT (client));
-
- if (EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command)
- EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command (client, argc, argv);
-}
-
-/**
- * egg_sm_client_will_quit:
- * @client: the client
- * @will_quit: whether or not the application is willing to quit
- *
- * This MUST be called in response to the ::quit_requested signal, to
- * indicate whether or not the application is willing to quit. The
- * application may call it either directly from the signal handler, or
- * at some later point (eg, after asynchronously interacting with the
- * user).
- *
- * If the application does not connect to ::quit_requested,
- * #EggSMClient will call this method on its behalf (passing %TRUE
- * for @will_quit).
- *
- * After calling this method, the application should wait to receive
- * either ::quit_cancelled or ::quit.
- **/
-void
-egg_sm_client_will_quit (EggSMClient *client,
- gboolean will_quit)
-{
- g_return_if_fail (EGG_IS_SM_CLIENT (client));
-
- if (EGG_SM_CLIENT_GET_CLASS (client)->will_quit)
- EGG_SM_CLIENT_GET_CLASS (client)->will_quit (client, will_quit);
-}
-
-/**
- * egg_sm_client_end_session:
- * @style: a hint at how to end the session
- * @request_confirmation: whether or not the user should get a chance
- * to confirm the action
- *
- * Requests that the session manager end the current session. @style
- * indicates how the session should be ended, and
- * @request_confirmation indicates whether or not the user should be
- * given a chance to confirm the logout/reboot/shutdown. Both of these
- * flags are merely hints though; the session manager may choose to
- * ignore them.
- *
- * Return value: %TRUE if the request was sent; %FALSE if it could not
- * be (eg, because it could not connect to the session manager).
- **/
-gboolean
-egg_sm_client_end_session (EggSMClientEndStyle style,
- gboolean request_confirmation)
-{
- EggSMClient *client = egg_sm_client_get ();
-
- g_return_val_if_fail (EGG_IS_SM_CLIENT (client), FALSE);
-
- if (EGG_SM_CLIENT_GET_CLASS (client)->end_session)
- {
- return EGG_SM_CLIENT_GET_CLASS (client)->end_session (client, style,
- request_confirmation);
- }
- else
- return FALSE;
-}
-
-/* Signal-emitting callbacks from platform-specific code */
-
-GKeyFile *
-egg_sm_client_save_state (EggSMClient *client)
-{
- GKeyFile *state_file;
- char *group;
-
- g_return_val_if_fail (client == global_client, NULL);
-
- state_file = g_key_file_new ();
-
- g_debug ("Emitting save_state");
- g_signal_emit (client, signals[SAVE_STATE], 0, state_file);
- g_debug ("Done emitting save_state");
-
- group = g_key_file_get_start_group (state_file);
- if (group)
- {
- g_free (group);
- return state_file;
- }
- else
- {
- g_key_file_free (state_file);
- return NULL;
- }
-}
-
-void
-egg_sm_client_quit_requested (EggSMClient *client)
-{
- g_return_if_fail (client == global_client);
-
- if (!g_signal_has_handler_pending (client, signals[QUIT_REQUESTED], 0, FALSE))
- {
- g_debug ("Not emitting quit_requested because no one is listening");
- egg_sm_client_will_quit (client, TRUE);
- return;
- }
-
- g_debug ("Emitting quit_requested");
- g_signal_emit (client, signals[QUIT_REQUESTED], 0);
- g_debug ("Done emitting quit_requested");
-}
-
-void
-egg_sm_client_quit_cancelled (EggSMClient *client)
-{
- g_return_if_fail (client == global_client);
-
- g_debug ("Emitting quit_cancelled");
- g_signal_emit (client, signals[QUIT_CANCELLED], 0);
- g_debug ("Done emitting quit_cancelled");
-}
-
-void
-egg_sm_client_quit (EggSMClient *client)
-{
- g_return_if_fail (client == global_client);
-
- g_debug ("Emitting quit");
- g_signal_emit (client, signals[QUIT], 0);
- g_debug ("Done emitting quit");
-
- /* FIXME: should we just call gtk_main_quit() here? */
-}
-
-static void
-egg_sm_client_debug_handler (const char *log_domain,
- GLogLevelFlags log_level,
- const char *message,
- gpointer user_data)
-{
- static int debug = -1;
-
- if (debug < 0)
- debug = (g_getenv ("EGG_SM_CLIENT_DEBUG") != NULL);
-
- if (debug)
- g_log_default_handler (log_domain, log_level, message, NULL);
-}
diff --git a/cut-n-paste-code/libegg/eggsmclient.h b/cut-n-paste-code/libegg/eggsmclient.h
deleted file mode 100644
index e620b754a..000000000
--- a/cut-n-paste-code/libegg/eggsmclient.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/* eggsmclient.h
- * Copyright (C) 2007 Novell, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __EGG_SM_CLIENT_H__
-#define __EGG_SM_CLIENT_H__
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define EGG_TYPE_SM_CLIENT (egg_sm_client_get_type ())
-#define EGG_SM_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_SM_CLIENT, EggSMClient))
-#define EGG_SM_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_SM_CLIENT, EggSMClientClass))
-#define EGG_IS_SM_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_SM_CLIENT))
-#define EGG_IS_SM_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_SM_CLIENT))
-#define EGG_SM_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_SM_CLIENT, EggSMClientClass))
-
-typedef struct _EggSMClient EggSMClient;
-typedef struct _EggSMClientClass EggSMClientClass;
-typedef struct _EggSMClientPrivate EggSMClientPrivate;
-
-typedef enum {
- EGG_SM_CLIENT_END_SESSION_DEFAULT,
- EGG_SM_CLIENT_LOGOUT,
- EGG_SM_CLIENT_REBOOT,
- EGG_SM_CLIENT_SHUTDOWN
-} EggSMClientEndStyle;
-
-typedef enum {
- EGG_SM_CLIENT_MODE_DISABLED,
- EGG_SM_CLIENT_MODE_NO_RESTART,
- EGG_SM_CLIENT_MODE_NORMAL
-} EggSMClientMode;
-
-struct _EggSMClient
-{
- GObject parent;
-
-};
-
-struct _EggSMClientClass
-{
- GObjectClass parent_class;
-
- /* signals */
- void (*save_state) (EggSMClient *client,
- GKeyFile *state_file);
-
- void (*quit_requested) (EggSMClient *client);
- void (*quit_cancelled) (EggSMClient *client);
- void (*quit) (EggSMClient *client);
-
- /* virtual methods */
- void (*startup) (EggSMClient *client,
- const char *client_id);
- void (*set_restart_command) (EggSMClient *client,
- int argc,
- const char **argv);
- void (*will_quit) (EggSMClient *client,
- gboolean will_quit);
- gboolean (*end_session) (EggSMClient *client,
- EggSMClientEndStyle style,
- gboolean request_confirmation);
-
- /* Padding for future expansion */
- void (*_egg_reserved1) (void);
- void (*_egg_reserved2) (void);
- void (*_egg_reserved3) (void);
- void (*_egg_reserved4) (void);
-};
-
-GType egg_sm_client_get_type (void) G_GNUC_CONST;
-
-GOptionGroup *egg_sm_client_get_option_group (void);
-
-/* Initialization */
-void egg_sm_client_set_mode (EggSMClientMode mode);
-EggSMClientMode egg_sm_client_get_mode (void);
-EggSMClient *egg_sm_client_get (void);
-
-/* Resuming a saved session */
-gboolean egg_sm_client_is_resumed (EggSMClient *client);
-GKeyFile *egg_sm_client_get_state_file (EggSMClient *client);
-
-/* Alternate means of saving state */
-void egg_sm_client_set_restart_command (EggSMClient *client,
- int argc,
- const char **argv);
-
-/* Handling "quit_requested" signal */
-void egg_sm_client_will_quit (EggSMClient *client,
- gboolean will_quit);
-
-/* Initiate a logout/reboot/shutdown */
-gboolean egg_sm_client_end_session (EggSMClientEndStyle style,
- gboolean request_confirmation);
-
-G_END_DECLS
-
-
-#endif /* __EGG_SM_CLIENT_H__ */
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 096b04afb..1da007526 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,8 +1,6 @@
# List of source files containing translatable strings.
# Please keep this file sorted alphabetically.
[encoding: UTF-8]
-cut-n-paste-code/libegg/eggdesktopfile.c
-cut-n-paste-code/libegg/eggsmclient.c
data/nautilus.xml.in
eel/eel-canvas.c
eel/eel-editable-label.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 425460432..baba538d0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -64,8 +64,6 @@ nautilus_SOURCES = \
nautilus-actions.h \
nautilus-application.c \
nautilus-application.h \
- nautilus-application-smclient.c \
- nautilus-application-smclient.h \
nautilus-bookmark-list.c \
nautilus-bookmark-list.h \
nautilus-bookmarks-window.c \
diff --git a/src/nautilus-application-smclient.c b/src/nautilus-application-smclient.c
deleted file mode 100644
index c5baa0fec..000000000
--- a/src/nautilus-application-smclient.c
+++ /dev/null
@@ -1,459 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/*
- * nautilus-application-smclient: a little module for session handling.
- *
- * Copyright (C) 2000 Red Hat, Inc.
- * Copyright (C) 2010 Cosimo Cecchi <cosimoc@gnome.org>
- *
- * Nautilus is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * Nautilus is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "nautilus-application-smclient.h"
-
-#include "nautilus-navigation-window.h"
-#include "nautilus-window-private.h"
-#include "nautilus-window-slot.h"
-
-#include <eel/eel-gtk-extensions.h>
-#include <eel/eel-vfs-extensions.h>
-#include <libxml/xmlsave.h>
-
-#define DEBUG_FLAG NAUTILUS_DEBUG_SMCLIENT
-#include <libnautilus-private/nautilus-debug.h>
-
-static char *
-nautilus_application_get_session_data (NautilusApplication *self)
-{
- xmlDocPtr doc;
- xmlNodePtr root_node, history_node;
- GList *l, *window_list;
- char *data;
- unsigned n_processed;
- xmlSaveCtxtPtr ctx;
- xmlBufferPtr buffer;
-
- doc = xmlNewDoc ("1.0");
-
- root_node = xmlNewNode (NULL, "session");
- xmlDocSetRootElement (doc, root_node);
-
- history_node = xmlNewChild (root_node, NULL, "history", NULL);
-
- n_processed = 0;
- for (l = nautilus_get_history_list (); l != NULL; l = l->next) {
- NautilusBookmark *bookmark;
- xmlNodePtr bookmark_node;
- GIcon *icon;
- char *tmp;
-
- bookmark = l->data;
-
- bookmark_node = xmlNewChild (history_node, NULL, "bookmark", NULL);
-
- tmp = nautilus_bookmark_get_name (bookmark);
- xmlNewProp (bookmark_node, "name", tmp);
- g_free (tmp);
-
- icon = nautilus_bookmark_get_icon (bookmark);
- tmp = g_icon_to_string (icon);
- g_object_unref (icon);
- if (tmp) {
- xmlNewProp (bookmark_node, "icon", tmp);
- g_free (tmp);
- }
-
- tmp = nautilus_bookmark_get_uri (bookmark);
- xmlNewProp (bookmark_node, "uri", tmp);
-
- DEBUG ("Saving history information for uri %s", tmp);
-
- g_free (tmp);
-
- if (nautilus_bookmark_get_has_custom_name (bookmark)) {
- xmlNewProp (bookmark_node, "has_custom_name", "TRUE");
- }
-
- if (++n_processed > 50) { /* prevent history list from growing arbitrarily large. */
- break;
- }
- }
-
- window_list = gtk_application_get_windows (GTK_APPLICATION (self));
-
- for (l = window_list; l != NULL; l = l->next) {
- xmlNodePtr win_node, slot_node;
- NautilusWindow *window;
- NautilusWindowSlot *slot, *active_slot;
- GList *slots, *m;
- char *tmp;
-
- window = l->data;
-
- slots = nautilus_window_get_slots (window);
- active_slot = nautilus_window_get_active_slot (window);
-
- /* store one slot as window location. Otherwise
- * older Nautilus versions will bail when reading the file. */
- tmp = nautilus_window_slot_get_location_uri (active_slot);
-
- if (eel_uri_is_desktop (tmp)) {
- g_list_free (slots);
- g_free (tmp);
- continue;
- }
-
- DEBUG ("Saving opened window for uri %s", tmp);
- win_node = xmlNewChild (root_node, NULL, "window", NULL);
-
- xmlNewProp (win_node, "location", tmp);
- g_free (tmp);
-
- xmlNewProp (win_node, "type", NAUTILUS_IS_NAVIGATION_WINDOW (window) ? "navigation" : "spatial");
-
- if (NAUTILUS_IS_NAVIGATION_WINDOW (window)) { /* spatial windows store their state as file metadata */
- GdkWindow *gdk_window;
-
- tmp = eel_gtk_window_get_geometry_string (GTK_WINDOW (window));
- xmlNewProp (win_node, "geometry", tmp);
- g_free (tmp);
-
- gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
-
- if (gdk_window &&
- gdk_window_get_state (gdk_window) & GDK_WINDOW_STATE_MAXIMIZED) {
- xmlNewProp (win_node, "maximized", "TRUE");
- }
-
- if (gdk_window &&
- gdk_window_get_state (gdk_window) & GDK_WINDOW_STATE_STICKY) {
- xmlNewProp (win_node, "sticky", "TRUE");
- }
-
- if (gdk_window &&
- gdk_window_get_state (gdk_window) & GDK_WINDOW_STATE_ABOVE) {
- xmlNewProp (win_node, "keep-above", "TRUE");
- }
- }
-
- for (m = slots; m != NULL; m = m->next) {
- slot = NAUTILUS_WINDOW_SLOT (m->data);
-
- slot_node = xmlNewChild (win_node, NULL, "slot", NULL);
-
- tmp = nautilus_window_slot_get_location_uri (slot);
- xmlNewProp (slot_node, "location", tmp);
- g_free (tmp);
-
- if (slot == active_slot) {
- xmlNewProp (slot_node, "active", "TRUE");
- }
- }
-
- g_list_free (slots);
- }
-
- buffer = xmlBufferCreate ();
- xmlIndentTreeOutput = 1;
- ctx = xmlSaveToBuffer (buffer, "UTF-8", XML_SAVE_FORMAT);
- if (xmlSaveDoc (ctx, doc) < 0 ||
- xmlSaveFlush (ctx) < 0) {
- DEBUG ("Failed to save session");
- }
-
- xmlSaveClose(ctx);
- data = g_strndup (buffer->content, buffer->use);
- xmlBufferFree (buffer);
-
- xmlFreeDoc (doc);
-
- return data;
-}
-
-static void
-smclient_save_state_cb (EggSMClient *client,
- GKeyFile *state_file,
- NautilusApplication *application)
-{
- char *data;
-
- DEBUG ("Received SaveState signal from the SMClient");
-
- data = nautilus_application_get_session_data (application);
-
- if (data != NULL) {
- g_key_file_set_string (state_file,
- "Nautilus",
- "documents",
- data);
- }
-
- g_free (data);
-}
-
-static void
-smclient_quit_cb (EggSMClient *client,
- NautilusApplication *application)
-{
- DEBUG ("Received Quit signal from the SMClient");
-
- nautilus_application_quit (application);
-}
-
-static void
-nautilus_application_smclient_initialize (NautilusApplication *self)
-{
- egg_sm_client_set_mode (EGG_SM_CLIENT_MODE_NORMAL);
-
- g_signal_connect (self->smclient, "save_state",
- G_CALLBACK (smclient_save_state_cb),
- self);
- g_signal_connect (self->smclient, "quit",
- G_CALLBACK (smclient_quit_cb),
- self);
-
- /* TODO: Should connect to quit_requested and block logout on active transfer? */
-}
-
-void
-nautilus_application_smclient_load (NautilusApplication *application,
- gboolean *no_default_window)
-{
- xmlDocPtr doc;
- gboolean bail;
- xmlNodePtr root_node;
- GKeyFile *state_file;
- char *data;
-
- DEBUG ("Loading session data");
-
- nautilus_application_smclient_initialize (application);
-
- if (!egg_sm_client_is_resumed (application->smclient)) {
- DEBUG ("SMClient not resumed");
- return;
- }
-
- state_file = egg_sm_client_get_state_file (application->smclient);
- if (!state_file) {
- DEBUG ("No SMClient state file");
- return;
- }
-
- data = g_key_file_get_string (state_file,
- "Nautilus",
- "documents",
- NULL);
- if (data == NULL) {
- DEBUG ("No SMClient session data");
- return;
- }
-
- *no_default_window = TRUE;
- bail = TRUE;
-
- doc = xmlReadMemory (data, strlen (data), NULL, "UTF-8", 0);
- if (doc != NULL && (root_node = xmlDocGetRootElement (doc)) != NULL) {
- xmlNodePtr node;
-
- bail = FALSE;
-
- for (node = root_node->children; node != NULL; node = node->next) {
-
- if (!strcmp (node->name, "text")) {
- continue;
- } else if (!strcmp (node->name, "history")) {
- xmlNodePtr bookmark_node;
- gboolean emit_change;
-
- emit_change = FALSE;
-
- for (bookmark_node = node->children; bookmark_node != NULL; bookmark_node = bookmark_node->next) {
- if (!strcmp (bookmark_node->name, "text")) {
- continue;
- } else if (!strcmp (bookmark_node->name, "bookmark")) {
- xmlChar *name, *icon_str, *uri;
- gboolean has_custom_name;
- GIcon *icon;
- GFile *location;
-
- uri = xmlGetProp (bookmark_node, "uri");
- name = xmlGetProp (bookmark_node, "name");
- has_custom_name = xmlHasProp (bookmark_node, "has_custom_name") ? TRUE : FALSE;
- icon_str = xmlGetProp (bookmark_node, "icon");
- icon = NULL;
- if (icon_str) {
- icon = g_icon_new_for_string (icon_str, NULL);
- }
- location = g_file_new_for_uri (uri);
-
- DEBUG ("Adding %s to the history list", name);
-
- emit_change |= nautilus_add_to_history_list_no_notify (location, name, has_custom_name, icon);
-
- g_object_unref (location);
-
- if (icon) {
- g_object_unref (icon);
- }
- xmlFree (name);
- xmlFree (uri);
- xmlFree (icon_str);
- } else {
- DEBUG ("Unexpected bookmark node %s while parsing session data", bookmark_node->name);
- bail = TRUE;
- continue;
- }
- }
-
- if (emit_change) {
- nautilus_send_history_list_changed ();
- }
- } else if (!strcmp (node->name, "window")) {
- NautilusWindow *window;
- xmlChar *type, *location_uri, *slot_uri;
- xmlNodePtr slot_node;
- GFile *location;
- int i;
-
- type = xmlGetProp (node, "type");
- if (type == NULL) {
- DEBUG ("Empty type node while parsing session data");
- bail = TRUE;
- continue;
- }
-
- location_uri = xmlGetProp (node, "location");
- if (location_uri == NULL) {
- DEBUG ("Empty location node while parsing session data");
- bail = TRUE;
- xmlFree (type);
- continue;
- }
-
- if (!strcmp (type, "navigation")) {
- xmlChar *geometry;
-
- window = nautilus_application_create_navigation_window (application, NULL, gdk_screen_get_default ());
-
- geometry = xmlGetProp (node, "geometry");
- if (geometry != NULL) {
- eel_gtk_window_set_initial_geometry_from_string
- (GTK_WINDOW (window),
- geometry,
- NAUTILUS_NAVIGATION_WINDOW_MIN_WIDTH,
- NAUTILUS_NAVIGATION_WINDOW_MIN_HEIGHT,
- FALSE);
- }
- xmlFree (geometry);
-
- if (xmlHasProp (node, "maximized")) {
- gtk_window_maximize (GTK_WINDOW (window));
- } else {
- gtk_window_unmaximize (GTK_WINDOW (window));
- }
-
- if (xmlHasProp (node, "sticky")) {
- gtk_window_stick (GTK_WINDOW (window));
- } else {
- gtk_window_unstick (GTK_WINDOW (window));
- }
-
- if (xmlHasProp (node, "keep-above")) {
- gtk_window_set_keep_above (GTK_WINDOW (window), TRUE);
- } else {
- gtk_window_set_keep_above (GTK_WINDOW (window), FALSE);
- }
-
- for (i = 0, slot_node = node->children; slot_node != NULL; slot_node = slot_node->next) {
- if (!strcmp (slot_node->name, "slot")) {
- slot_uri = xmlGetProp (slot_node, "location");
- if (slot_uri != NULL) {
- NautilusWindowSlot *slot;
-
- if (i == 0) {
- slot = window->details->active_pane->active_slot;
- } else {
- slot = nautilus_window_open_slot (window->details->active_pane, NAUTILUS_WINDOW_OPEN_SLOT_APPEND);
- }
-
- DEBUG ("Resuming navigation window slot for uri %s", slot_uri);
-
- location = g_file_new_for_uri (slot_uri);
- nautilus_window_slot_open_location (slot, location, FALSE);
-
- if (xmlHasProp (slot_node, "active")) {
- nautilus_window_set_active_slot (slot->pane->window, slot);
- }
-
- i++;
- }
- xmlFree (slot_uri);
- }
- }
-
- if (i == 0) {
- /* This may be an old session file */
- location = g_file_new_for_uri (location_uri);
- nautilus_window_slot_open_location (window->details->active_pane->active_slot, location, FALSE);
- g_object_unref (location);
- }
- } else if (!strcmp (type, "spatial")) {
- DEBUG ("Resuming spatial window for uri %s", location_uri);
-
- location = g_file_new_for_uri (location_uri);
- window = nautilus_application_get_spatial_window (application, NULL, NULL,
- location, gdk_screen_get_default (),
- NULL);
-
- nautilus_window_go_to (window, location);
-
- g_object_unref (location);
- } else {
- DEBUG ("Unknown window type \"%s\" while parsing session data", type);
- bail = TRUE;
- }
-
- xmlFree (type);
- xmlFree (location_uri);
- } else {
- DEBUG ("Unexpected node %s while parsing session data", node->name);
- bail = TRUE;
- continue;
- }
- }
- }
-
- if (doc != NULL) {
- xmlFreeDoc (doc);
- }
-
- g_free (data);
-
- if (bail) {
- DEBUG ("Failed to load session");
- }
-}
-
-void
-nautilus_application_smclient_startup (NautilusApplication *self)
-{
- g_assert (self->smclient == NULL);
-
- DEBUG ("Starting up SMClient");
-
- egg_sm_client_set_mode (EGG_SM_CLIENT_MODE_DISABLED);
- self->smclient = egg_sm_client_get ();
-}
diff --git a/src/nautilus-application-smclient.h b/src/nautilus-application-smclient.h
deleted file mode 100644
index e71a19b62..000000000
--- a/src/nautilus-application-smclient.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/*
- * nautilus-application-smclient: a little module for session handling.
- *
- * Copyright (C) 2000 Red Hat, Inc.
- * Copyright (C) 2010 Cosimo Cecchi <cosimoc@gnome.org>
- *
- * Nautilus is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * Nautilus is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __NAUTILUS_APPLICATION_SMCLIENT_H__
-#define __NAUTILUS_APPLICATION_SMCLIENT_H__
-
-#include "nautilus-application.h"
-
-void nautilus_application_smclient_startup (NautilusApplication *self);
-void nautilus_application_smclient_load (NautilusApplication *self,
- gboolean *no_default_window);
-
-#endif /* __NAUTILUS_APPLICATION_SMCLIENT_H__ */
diff --git a/src/nautilus-application.c b/src/nautilus-application.c
index e68ecc6a5..5035b6170 100644
--- a/src/nautilus-application.c
+++ b/src/nautilus-application.c
@@ -37,7 +37,6 @@
#include "file-manager/fm-empty-view.h"
#endif /* ENABLE_EMPTY_VIEW */
-#include "nautilus-application-smclient.h"
#include "nautilus-desktop-window.h"
#include "nautilus-image-properties-page.h"
#include "nautilus-navigation-window.h"
@@ -1334,15 +1333,8 @@ nautilus_application_command_line (GApplication *app,
g_option_context_add_main_entries (context, options, NULL);
g_option_context_add_group (context, gtk_get_option_group (TRUE));
- if (!self->initialized) {
- g_option_context_add_group (context, egg_sm_client_get_option_group ());
- }
-
argv = g_application_command_line_get_arguments (command_line, &argc);
- /* we need to do this here, as parsing the EggSMClient option context,
- * unsets this variable.
- */
autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID");
if (autostart_id != NULL && *autostart_id != '\0') {
autostart_mode = TRUE;
@@ -1451,9 +1443,6 @@ nautilus_application_command_line (GApplication *app,
g_signal_connect (gtk_accel_map_get (), "changed",
G_CALLBACK (queue_accel_map_save_callback), NULL);
- /* Initialize SMClient and load session info if availible */
- nautilus_application_smclient_load (self, &no_default_window);
-
self->initialized = TRUE;
}
@@ -1536,9 +1525,6 @@ nautilus_application_startup (GApplication *app)
/* create an undo manager */
self->undo_manager = nautilus_undo_manager_new ();
- /* initialize the session manager client */
- nautilus_application_smclient_startup (self);
-
/* Initialize preferences. This is needed to create the
* global GSettings objects.
*/
diff --git a/src/nautilus-application.h b/src/nautilus-application.h
index 59d0d67b7..ea6cd60a9 100644
--- a/src/nautilus-application.h
+++ b/src/nautilus-application.h
@@ -28,7 +28,6 @@
#include <gio/gio.h>
#include <gtk/gtk.h>
-#include <libegg/eggsmclient.h>
#include <libnautilus-private/nautilus-undo-manager.h>
#define NAUTILUS_DESKTOP_ICON_VIEW_IID "OAFIID:Nautilus_File_Manager_Desktop_Icon_View"
@@ -58,7 +57,6 @@ typedef struct _NautilusSpatialWindow NautilusSpatialWindow;
typedef struct {
GtkApplication parent;
- EggSMClient *smclient;
NautilusUndoManager *undo_manager;
GVolumeMonitor *volume_monitor;
GDBusProxy *proxy;
diff --git a/src/nautilus-main.c b/src/nautilus-main.c
index f356f55d5..6b0dd50c2 100644
--- a/src/nautilus-main.c
+++ b/src/nautilus-main.c
@@ -34,7 +34,6 @@
#include <libnautilus-private/nautilus-debug.h>
#include <eel/eel-debug.h>
-#include <libegg/eggdesktopfile.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
@@ -93,10 +92,6 @@ main (int argc, char *argv[])
g_set_prgname ("nautilus");
- if (g_file_test (DATADIR "/applications/nautilus.desktop", G_FILE_TEST_EXISTS)) {
- egg_set_desktop_file (DATADIR "/applications/nautilus.desktop");
- }
-
#ifdef HAVE_EXEMPI
xmp_init();
#endif