gnome-session r4728 - in branches/dbus_based: . gnome-session
- From: mccann svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-session r4728 - in branches/dbus_based: . gnome-session
- Date: Wed, 11 Jun 2008 19:10:15 +0000 (UTC)
Author: mccann
Date: Wed Jun 11 19:10:15 2008
New Revision: 4728
URL: http://svn.gnome.org/viewvc/gnome-session?rev=4728&view=rev
Log:
2008-06-11 William Jon McCann <jmccann redhat com>
* gnome-session/Makefile.am:
* gnome-session/app-autostart.c:
* gnome-session/app-autostart.h:
* gnome-session/app-resumed.c:
* gnome-session/app-resumed.h:
* gnome-session/app.c:
* gnome-session/app.h:
* gnome-session/client-xsmp.c:
* gnome-session/client-xsmp.h:
* gnome-session/client.c:
* gnome-session/client.h:
* gnome-session/dbus.c:
* gnome-session/dbus.h:
* gnome-session/gconf.c (gsm_gconf_check):
* gnome-session/gsm-app.c (set_property), (get_property),
(dispose), (get_basename), (gsm_app_get_phase),
(gsm_app_is_disabled), (gsm_app_provides), (app_exited), (launch):
* gnome-session/gsm-app.h:
* gnome-session/gsm-autostart-app.c (gsm_autostart_app_init),
(gsm_autostart_app_class_init), (gsm_autostart_app_dispose),
(gsm_autostart_app_new), (unless_exists_condition_cb),
(if_exists_condition_cb), (gconf_condition_cb), (is_disabled):
* gnome-session/gsm-autostart-app.h:
* gnome-session/gsm-client-store.c (gsm_client_store_error_quark),
(gsm_client_store_clear), (remove_client),
(gsm_client_store_remove), (gsm_client_store_foreach),
(gsm_client_store_find), (gsm_client_store_foreach_remove),
(gsm_client_store_add), (gsm_client_store_class_init),
(client_unref), (gsm_client_store_init),
(gsm_client_store_finalize), (gsm_client_store_new):
* gnome-session/gsm-client-store.h:
* gnome-session/gsm-client.c (get_next_client_serial),
(gsm_client_constructor), (gsm_client_init), (gsm_client_finalize),
(gsm_client_class_init), (gsm_client_get_id),
(gsm_client_register_client), (gsm_client_request_logout):
* gnome-session/gsm-client.h:
* gnome-session/gsm-manager.c (gsm_manager_error_quark),
(app_condition_changed), (end_phase), (app_registered),
(phase_timeout), (start_phase), (gsm_manager_start),
(remove_client_for_connection), (remove_clients_for_connection),
(bus_name_owner_changed), (register_manager),
(gsm_manager_set_failsafe), (gsm_manager_set_client_store),
(gsm_manager_set_property), (gsm_manager_get_property),
(append_app), (append_default_apps), (append_autostart_apps),
(append_legacy_session_apps), (append_saved_session_apps),
(append_required_apps), (load_apps), (gsm_manager_constructor),
(gsm_manager_class_init), (gsm_manager_init),
(gsm_manager_finalize), (gsm_manager_new), (gsm_manager_setenv),
(gsm_manager_initialization_error), (manager_shutdown),
(initiate_shutdown), (logout_dialog_response),
(gsm_manager_initiate_shutdown), (gsm_manager_shutdown),
(gsm_manager_logout), (manager_set_name), (gsm_manager_set_name):
* gnome-session/gsm-manager.h:
* gnome-session/gsm-marshal.list:
* gnome-session/gsm-resumed-app.c (gsm_resumed_app_init),
(gsm_resumed_app_class_init),
(gsm_resumed_app_new_from_legacy_session),
(gsm_resumed_app_new_from_session), (get_basename), (launch):
* gnome-session/gsm-resumed-app.h:
* gnome-session/gsm-xsmp-client.c (gsm_xsmp_client_init),
(gsm_xsmp_client_class_init), (gsm_xsmp_client_new),
(xsmp_finalize), (client_iochannel_watch),
(client_protocol_timeout), (register_client_callback),
(do_save_yourself), (save_yourself_request_callback),
(xsmp_save_yourself), (save_yourself_phase2_request_callback),
(xsmp_save_yourself_phase2), (interact_request_callback),
(xsmp_interact), (interact_done_callback),
(xsmp_shutdown_cancelled), (xsmp_die),
(save_yourself_done_callback), (close_connection_callback),
(debug_print_property), (find_property), (delete_property),
(set_properties_callback), (delete_properties_callback),
(get_properties_callback), (xsmp_get_client_id), (xsmp_get_pid),
(xsmp_get_desktop_file), (prop_to_command),
(xsmp_get_restart_command), (xsmp_get_discard_command),
(xsmp_get_autorestart), (set_description),
(gsm_xsmp_client_connect):
* gnome-session/gsm-xsmp-client.h:
* gnome-session/gsm-xsmp-server.c (accept_ice_connection),
(gsm_xsmp_server_start), (gsm_xsmp_server_set_client_store),
(gsm_xsmp_server_set_property), (gsm_xsmp_server_get_property),
(accept_xsmp_connection), (ice_error_handler),
(ice_io_error_handler), (sms_error_handler), (auth_entry_new),
(update_iceauthority), (setup_listener),
(gsm_xsmp_server_constructor), (gsm_xsmp_server_class_init),
(gsm_xsmp_server_init), (gsm_xsmp_server_finalize),
(gsm_xsmp_server_new):
* gnome-session/gsm-xsmp-server.h:
* gnome-session/gsm.h:
* gnome-session/logout-dialog.c (gsm_logout_dialog_timeout),
(gsm_get_logout_dialog):
* gnome-session/logout-dialog.h:
* gnome-session/main.c (gsm_dbus_init), (gsm_dbus_check), (main):
* gnome-session/org.gnome.SessionManagement.xml:
* gnome-session/session.c:
* gnome-session/session.h:
* gnome-session/util.c (gsm_util_init_error),
(gsm_util_generate_client_id):
* gnome-session/util.h:
* gnome-session/xsmp.c:
* gnome-session/xsmp.h:
First crack at new new gnome-session based around D-Bus.
XSMP still provided but more as a legacy feature. Not quite
operational yet. See bug #535829 for more info.
Added:
branches/dbus_based/gnome-session/gsm-app.c
- copied, changed from r4726, /trunk/gnome-session/app.c
branches/dbus_based/gnome-session/gsm-app.h
- copied, changed from r4726, /trunk/gnome-session/app.h
branches/dbus_based/gnome-session/gsm-autostart-app.c
- copied, changed from r4726, /trunk/gnome-session/app-autostart.c
branches/dbus_based/gnome-session/gsm-autostart-app.h
- copied, changed from r4726, /trunk/gnome-session/app-autostart.h
branches/dbus_based/gnome-session/gsm-client-store.c
branches/dbus_based/gnome-session/gsm-client-store.h
branches/dbus_based/gnome-session/gsm-client.c
- copied, changed from r4726, /trunk/gnome-session/client.c
branches/dbus_based/gnome-session/gsm-client.h
- copied, changed from r4726, /trunk/gnome-session/client.h
branches/dbus_based/gnome-session/gsm-manager.c
branches/dbus_based/gnome-session/gsm-manager.h
branches/dbus_based/gnome-session/gsm-manager.xml
- copied unchanged from r4726, /trunk/gnome-session/org.gnome.SessionManagement.xml
branches/dbus_based/gnome-session/gsm-marshal.list
branches/dbus_based/gnome-session/gsm-resumed-app.c
- copied, changed from r4726, /trunk/gnome-session/app-resumed.c
branches/dbus_based/gnome-session/gsm-resumed-app.h
- copied, changed from r4726, /trunk/gnome-session/app-resumed.h
branches/dbus_based/gnome-session/gsm-xsmp-client.c
- copied, changed from r4726, /trunk/gnome-session/client-xsmp.c
branches/dbus_based/gnome-session/gsm-xsmp-client.h
- copied, changed from r4726, /trunk/gnome-session/client-xsmp.h
branches/dbus_based/gnome-session/gsm-xsmp-server.c
branches/dbus_based/gnome-session/gsm-xsmp-server.h
Removed:
branches/dbus_based/gnome-session/app-autostart.c
branches/dbus_based/gnome-session/app-autostart.h
branches/dbus_based/gnome-session/app-resumed.c
branches/dbus_based/gnome-session/app-resumed.h
branches/dbus_based/gnome-session/app.c
branches/dbus_based/gnome-session/app.h
branches/dbus_based/gnome-session/client-xsmp.c
branches/dbus_based/gnome-session/client-xsmp.h
branches/dbus_based/gnome-session/client.c
branches/dbus_based/gnome-session/client.h
branches/dbus_based/gnome-session/dbus.c
branches/dbus_based/gnome-session/dbus.h
branches/dbus_based/gnome-session/gsm.h
branches/dbus_based/gnome-session/org.gnome.SessionManagement.xml
branches/dbus_based/gnome-session/session.c
branches/dbus_based/gnome-session/session.h
branches/dbus_based/gnome-session/xsmp.c
branches/dbus_based/gnome-session/xsmp.h
Modified:
branches/dbus_based/ChangeLog
branches/dbus_based/gnome-session/Makefile.am
branches/dbus_based/gnome-session/gconf.c
branches/dbus_based/gnome-session/logout-dialog.c
branches/dbus_based/gnome-session/logout-dialog.h
branches/dbus_based/gnome-session/main.c
branches/dbus_based/gnome-session/util.c
branches/dbus_based/gnome-session/util.h
Modified: branches/dbus_based/gnome-session/Makefile.am
==============================================================================
--- branches/dbus_based/gnome-session/Makefile.am (original)
+++ branches/dbus_based/gnome-session/Makefile.am Wed Jun 11 19:10:15 2008
@@ -13,7 +13,7 @@
-DDATA_DIR=\""$(datadir)/gnome-session"\" \
-DDBUS_LAUNCH=\"dbus-launch\" \
-DGCONF_SANITY_CHECK=\""$(GCONF_SANITY_CHECK)"\" \
- -DGCONFTOOL_CMD=\"$(GCONFTOOL)\"
+ -DGCONFTOOL_CMD=\"$(GCONFTOOL)\"
gnome_session_LDADD = \
-lSM -lICE \
@@ -24,32 +24,33 @@
$(GCONF_LIBS)
gnome_session_SOURCES = \
- app-autostart.c \
- app-autostart.h \
- app-resumed.c \
- app-resumed.h \
- app.c \
- app.h \
- client-xsmp.c \
- client-xsmp.h \
- client.c \
- client.h \
- dbus.c \
- dbus.h \
+ gsm-autostart-app.h \
+ gsm-autostart-app.c \
+ gsm-resumed-app.h \
+ gsm-resumed-app.c \
+ gsm-app.h \
+ gsm-app.c \
+ gsm-xsmp-client.h \
+ gsm-xsmp-client.c \
+ gsm-client.c \
+ gsm-client.h \
+ gsm-marshal.h \
+ gsm-marshal.c \
gconf.c \
gconf.h \
gdm.h \
gdm.c \
- gsm.h \
logout-dialog.h \
logout-dialog.c \
main.c \
power-manager.h \
power-manager.c \
- session.c \
- session.h \
- xsmp.c \
- xsmp.h
+ gsm-client-store.h \
+ gsm-client-store.c \
+ gsm-manager.c \
+ gsm-manager.h \
+ gsm-xsmp-server.c \
+ gsm-xsmp-server.h
libgsmutil_la_LIBADD = \
$(GNOME_SESSION_LIBS)
@@ -58,14 +59,25 @@
util.c \
util.h
-dbus.o dbus.lo: dbus-glue.h
-
-dbus-glue.h: org.gnome.SessionManagement.xml
- dbus-binding-tool --mode=glib-server --prefix=gsm_dbus_server $^ > $@
+gsm-marshal.c: gsm-marshal.list
+ echo "#include \"gsm-marshal.h\"" > $@ && \
+ @GLIB_GENMARSHAL@ $< --prefix=gsm_marshal --body >> $@
+
+gsm-marshal.h: gsm-marshal.list
+ @GLIB_GENMARSHAL@ $< --prefix=gsm_marshal --header > $@
+
+gsm-manager-glue.h: gsm-manager.xml Makefile.am
+ dbus-binding-tool --prefix=gsm_manager --mode=glib-server --output=gsm-manager-glue.h $(srcdir)/gsm-manager.xml
+
+BUILT_SOURCES = \
+ gsm-marshal.c \
+ gsm-marshal.h \
+ gsm-manager-glue.h
CLEANFILES = \
- dbus-glue.h
+ $(BUILT_SOURCES)
EXTRA_DIST = \
README \
- org.gnome.SessionManagement.xml
+ gsm-marshal.list \
+ gsm-manager.xml
Modified: branches/dbus_based/gnome-session/gconf.c
==============================================================================
--- branches/dbus_based/gnome-session/gconf.c (original)
+++ branches/dbus_based/gnome-session/gconf.c Wed Jun 11 19:10:15 2008
@@ -29,7 +29,6 @@
#include <sys/wait.h>
#include "gconf.h"
-#include "gsm.h"
#include "util.h"
static pid_t gsc_pid;
@@ -106,10 +105,10 @@
if (!WIFEXITED (status) || WEXITSTATUS (status) != 0)
{
/* FIXME: capture gconf-sanity-check's stderr */
- gsm_initialization_error (TRUE,
- _("There is a problem with the configuration server.\n"
- "(%s exited with status %d)"),
- GCONF_SANITY_CHECK, status);
+ gsm_util_init_error (TRUE,
+ _("There is a problem with the configuration server.\n"
+ "(%s exited with status %d)"),
+ GCONF_SANITY_CHECK, status);
}
}
Copied: branches/dbus_based/gnome-session/gsm-app.c (from r4726, /trunk/gnome-session/app.c)
==============================================================================
--- /trunk/gnome-session/app.c (original)
+++ branches/dbus_based/gnome-session/gsm-app.c Wed Jun 11 19:10:15 2008
@@ -1,4 +1,5 @@
-/* app.c
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
* Copyright (C) 2007 Novell, Inc.
*
* This program is free software; you can redistribute it and/or
@@ -25,29 +26,27 @@
#include <string.h>
#include <sys/wait.h>
-#include "app.h"
+#include "gsm-app.h"
enum {
- EXITED,
- REGISTERED,
- LAST_SIGNAL
+ EXITED,
+ REGISTERED,
+ LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
enum {
- PROP_0,
-
- PROP_DESKTOP_FILE,
- PROP_CLIENT_ID,
-
- LAST_PROP
+ PROP_0,
+ PROP_DESKTOP_FILE,
+ PROP_CLIENT_ID,
+ LAST_PROP
};
static void set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec);
+ const GValue *value, GParamSpec *pspec);
static void get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec);
+ GValue *value, GParamSpec *pspec);
static void dispose (GObject *object);
static const char *get_basename (GsmApp *app);
@@ -58,164 +57,163 @@
static void
gsm_app_init (GsmApp *app)
{
- app->pid = -1;
+ app->pid = -1;
}
static void
gsm_app_class_init (GsmAppClass *app_class)
{
- GObjectClass *object_class = G_OBJECT_CLASS (app_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (app_class);
- object_class->set_property = set_property;
- object_class->get_property = get_property;
- object_class->dispose = dispose;
-
- app_class->get_basename = get_basename;
- app_class->launch = launch;
-
- g_object_class_install_property (object_class,
- PROP_DESKTOP_FILE,
- g_param_spec_string ("desktop-file",
- "Desktop file",
- "Freedesktop .desktop file",
- NULL,
- G_PARAM_READWRITE));
- g_object_class_install_property (object_class,
- PROP_CLIENT_ID,
- g_param_spec_string ("client-id",
- "Client ID",
- "Session management client ID",
- NULL,
- G_PARAM_READWRITE));
-
- signals[EXITED] =
- g_signal_new ("exited",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GsmAppClass, exited),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-
- signals[REGISTERED] =
- g_signal_new ("registered",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GsmAppClass, registered),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+ object_class->dispose = dispose;
+
+ app_class->get_basename = get_basename;
+ app_class->launch = launch;
+
+ g_object_class_install_property (object_class,
+ PROP_DESKTOP_FILE,
+ g_param_spec_string ("desktop-file",
+ "Desktop file",
+ "Freedesktop .desktop file",
+ NULL,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_CLIENT_ID,
+ g_param_spec_string ("client-id",
+ "Client ID",
+ "Session management client ID",
+ NULL,
+ G_PARAM_READWRITE));
+
+ signals[EXITED] =
+ g_signal_new ("exited",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsmAppClass, exited),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ signals[REGISTERED] =
+ g_signal_new ("registered",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsmAppClass, registered),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
}
static void
-set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
-{
- GsmApp *app = GSM_APP (object);
- const char *desktop_file;
- char *phase;
- GError *error = NULL;
-
- switch (prop_id)
- {
- case PROP_DESKTOP_FILE:
- if (app->desktop_file)
- egg_desktop_file_free (app->desktop_file);
- desktop_file = g_value_get_string (value);
- if (!desktop_file)
- {
- app->desktop_file = NULL;
- break;
- }
-
- app->desktop_file = egg_desktop_file_new (desktop_file, &error);
- if (!app->desktop_file)
- {
- g_warning ("Could not parse desktop file %s: %s",
- desktop_file, error->message);
- g_error_free (error);
- break;
- }
-
- phase = egg_desktop_file_get_string (app->desktop_file,
- "X-GNOME-Autostart-Phase", NULL);
- if (phase)
- {
- if (!strcmp (phase, "Initialization"))
- app->phase = GSM_SESSION_PHASE_INITIALIZATION;
- else if (!strcmp (phase, "WindowManager"))
- app->phase = GSM_SESSION_PHASE_WINDOW_MANAGER;
- else if (!strcmp (phase, "Panel"))
- app->phase = GSM_SESSION_PHASE_PANEL;
- else if (!strcmp (phase, "Desktop"))
- app->phase = GSM_SESSION_PHASE_DESKTOP;
- else
- app->phase = GSM_SESSION_PHASE_APPLICATION;
-
- g_free (phase);
- }
- else
- app->phase = GSM_SESSION_PHASE_APPLICATION;
- break;
-
- case PROP_CLIENT_ID:
- g_free (app->client_id);
- app->client_id = g_value_dup_string (value);
- break;
-
- default:
- break;
- }
+set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GsmApp *app = GSM_APP (object);
+ const char *desktop_file;
+ char *phase;
+ GError *error = NULL;
+
+ switch (prop_id) {
+ case PROP_DESKTOP_FILE:
+ if (app->desktop_file) {
+ egg_desktop_file_free (app->desktop_file);
+ }
+ desktop_file = g_value_get_string (value);
+ if (!desktop_file) {
+ app->desktop_file = NULL;
+ break;
+ }
+
+ app->desktop_file = egg_desktop_file_new (desktop_file, &error);
+ if (!app->desktop_file) {
+ g_warning ("Could not parse desktop file %s: %s",
+ desktop_file, error->message);
+ g_error_free (error);
+ break;
+ }
+
+ phase = egg_desktop_file_get_string (app->desktop_file,
+ "X-GNOME-Autostart-Phase", NULL);
+ if (phase) {
+ if (!strcmp (phase, "Initialization")) {
+ app->phase = GSM_MANAGER_PHASE_INITIALIZATION;
+ } else if (!strcmp (phase, "WindowManager")) {
+ app->phase = GSM_MANAGER_PHASE_WINDOW_MANAGER;
+ } else if (!strcmp (phase, "Panel")) {
+ app->phase = GSM_MANAGER_PHASE_PANEL;
+ } else if (!strcmp (phase, "Desktop")) {
+ app->phase = GSM_MANAGER_PHASE_DESKTOP;
+ } else {
+ app->phase = GSM_MANAGER_PHASE_APPLICATION;
+ }
+
+ g_free (phase);
+ } else {
+ app->phase = GSM_MANAGER_PHASE_APPLICATION;
+ }
+ break;
+
+ case PROP_CLIENT_ID:
+ g_free (app->client_id);
+ app->client_id = g_value_dup_string (value);
+ break;
+
+ default:
+ break;
+ }
}
static void
-get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
-{
- GsmApp *app = GSM_APP (object);
-
- switch (prop_id)
- {
- case PROP_DESKTOP_FILE:
- if (app->desktop_file)
- g_value_set_string (value, egg_desktop_file_get_source (app->desktop_file));
- else
- g_value_set_string (value, NULL);
- break;
-
- case PROP_CLIENT_ID:
- g_value_set_string (value, app->client_id);
- break;
-
- default:
- break;
- }
+get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GsmApp *app = GSM_APP (object);
+
+ switch (prop_id) {
+ case PROP_DESKTOP_FILE:
+ if (app->desktop_file) {
+ g_value_set_string (value, egg_desktop_file_get_source (app->desktop_file));
+ } else {
+ g_value_set_string (value, NULL);
+ }
+ break;
+
+ case PROP_CLIENT_ID:
+ g_value_set_string (value, app->client_id);
+ break;
+
+ default:
+ break;
+ }
}
static void
dispose(GObject *object)
{
- GsmApp *app = GSM_APP (object);
+ GsmApp *app = GSM_APP (object);
- if (app->desktop_file)
- {
- egg_desktop_file_free (app->desktop_file);
- app->desktop_file = NULL;
- }
-
- if (app->startup_id)
- {
- g_free (app->startup_id);
- app->startup_id = NULL;
- }
-
- if (app->client_id)
- {
- g_free (app->client_id);
- app->client_id = NULL;
- }
+ if (app->desktop_file) {
+ egg_desktop_file_free (app->desktop_file);
+ app->desktop_file = NULL;
+ }
+
+ if (app->startup_id) {
+ g_free (app->startup_id);
+ app->startup_id = NULL;
+ }
+
+ if (app->client_id) {
+ g_free (app->client_id);
+ app->client_id = NULL;
+ }
}
/**
@@ -230,24 +228,25 @@
const char *
gsm_app_get_basename (GsmApp *app)
{
- return GSM_APP_GET_CLASS (app)->get_basename (app);
+ return GSM_APP_GET_CLASS (app)->get_basename (app);
}
static const char *
get_basename (GsmApp *app)
{
- const char *location, *slash;
+ const char *location, *slash;
- if (!app->desktop_file)
- return NULL;
+ if (!app->desktop_file)
+ return NULL;
- location = egg_desktop_file_get_source (app->desktop_file);
+ location = egg_desktop_file_get_source (app->desktop_file);
- slash = strrchr (location, '/');
- if (slash)
- return slash + 1;
- else
- return location;
+ slash = strrchr (location, '/');
+ if (slash) {
+ return slash + 1;
+ } else {
+ return location;
+ }
}
/**
@@ -258,12 +257,12 @@
*
* Return value: @app's startup phase
**/
-GsmSessionPhase
+GsmManagerPhase
gsm_app_get_phase (GsmApp *app)
{
- g_return_val_if_fail (GSM_IS_APP (app), GSM_SESSION_PHASE_APPLICATION);
+ g_return_val_if_fail (GSM_IS_APP (app), GSM_MANAGER_PHASE_APPLICATION);
- return app->phase;
+ return app->phase;
}
/**
@@ -277,92 +276,95 @@
gboolean
gsm_app_is_disabled (GsmApp *app)
{
- g_return_val_if_fail (GSM_IS_APP (app), FALSE);
+ g_return_val_if_fail (GSM_IS_APP (app), FALSE);
- if (GSM_APP_GET_CLASS (app)->is_disabled)
- return GSM_APP_GET_CLASS (app)->is_disabled (app);
- else
- return FALSE;
+ if (GSM_APP_GET_CLASS (app)->is_disabled) {
+ return GSM_APP_GET_CLASS (app)->is_disabled (app);
+ } else {
+ return FALSE;
+ }
}
gboolean
gsm_app_provides (GsmApp *app, const char *service)
{
- char **provides;
- gsize len, i;
+ char **provides;
+ gsize len, i;
- g_return_val_if_fail (GSM_IS_APP (app), FALSE);
+ g_return_val_if_fail (GSM_IS_APP (app), FALSE);
- if (!app->desktop_file)
- return FALSE;
+ if (!app->desktop_file) {
+ return FALSE;
+ }
+
+ provides = egg_desktop_file_get_string_list (app->desktop_file,
+ "X-GNOME-Provides",
+ &len, NULL);
+ if (!provides) {
+ return FALSE;
+ }
+
+ for (i = 0; i < len; i++) {
+ if (!strcmp (provides[i], service)) {
+ g_strfreev (provides);
+ return TRUE;
+ }
+ }
- provides = egg_desktop_file_get_string_list (app->desktop_file,
- "X-GNOME-Provides",
- &len, NULL);
- if (!provides)
- return FALSE;
-
- for (i = 0; i < len; i++)
- {
- if (!strcmp (provides[i], service))
- {
- g_strfreev (provides);
- return TRUE;
- }
- }
-
- g_strfreev (provides);
- return FALSE;
+ g_strfreev (provides);
+ return FALSE;
}
-static void
+static void
app_exited (GPid pid, gint status, gpointer data)
{
- if (WIFEXITED (status))
- g_signal_emit (GSM_APP (data), signals[EXITED], 0);
+ if (WIFEXITED (status)) {
+ g_signal_emit (GSM_APP (data), signals[EXITED], 0);
+ }
}
static pid_t
launch (GsmApp *app,
- GError **err)
+ GError **err)
{
- char *env[2] = { NULL, NULL };
- gboolean success;
+ char *env[2] = { NULL, NULL };
+ gboolean success;
- g_return_val_if_fail (app->desktop_file != NULL, (pid_t)-1);
+ g_return_val_if_fail (app->desktop_file != NULL, (pid_t)-1);
- if (egg_desktop_file_get_boolean (app->desktop_file,
- "X-GNOME-Autostart-Notify", NULL) ||
- egg_desktop_file_get_boolean (app->desktop_file,
- "AutostartNotify", NULL))
- env[0] = g_strdup_printf ("DESKTOP_AUTOSTART_ID=%s", app->client_id);
+ if (egg_desktop_file_get_boolean (app->desktop_file,
+ "X-GNOME-Autostart-Notify", NULL) ||
+ egg_desktop_file_get_boolean (app->desktop_file,
+ "AutostartNotify", NULL)) {
+ env[0] = g_strdup_printf ("DESKTOP_AUTOSTART_ID=%s", app->client_id);
+ }
#if 0
- g_debug ("launching %s with client_id %s\n",
- gsm_app_get_basename (app), app->client_id);
+ g_debug ("launching %s with client_id %s\n",
+ gsm_app_get_basename (app), app->client_id);
#endif
- success =
- egg_desktop_file_launch (app->desktop_file, NULL, err,
- EGG_DESKTOP_FILE_LAUNCH_PUTENV, env,
- EGG_DESKTOP_FILE_LAUNCH_FLAGS, G_SPAWN_DO_NOT_REAP_CHILD,
- EGG_DESKTOP_FILE_LAUNCH_RETURN_PID, &app->pid,
- EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID, &app->startup_id,
- NULL);
-
- g_free (env[0]);
-
- if (success)
- {
- /* In case the app belongs to Initialization phase, we monitor
- * if it exits to emit proper "exited" signal to session. */
- if (app->phase == GSM_SESSION_PHASE_INITIALIZATION)
- g_child_watch_add ((GPid) app->pid, app_exited, app);
-
- return app->pid;
- }
- else
- return (pid_t) -1;
+ success =
+ egg_desktop_file_launch (app->desktop_file, NULL, err,
+ EGG_DESKTOP_FILE_LAUNCH_PUTENV, env,
+ EGG_DESKTOP_FILE_LAUNCH_FLAGS, G_SPAWN_DO_NOT_REAP_CHILD,
+ EGG_DESKTOP_FILE_LAUNCH_RETURN_PID, &app->pid,
+ EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID, &app->startup_id,
+ NULL);
+
+ g_free (env[0]);
+
+ if (success) {
+ /* In case the app belongs to Initialization phase, we monitor
+ * if it exits to emit proper "exited" signal to session. */
+ if (app->phase == GSM_MANAGER_PHASE_INITIALIZATION) {
+ g_child_watch_add ((GPid) app->pid, app_exited, app);
+ }
+
+ return app->pid;
+ } else {
+ return (pid_t) -1;
+ }
}
/**
@@ -377,7 +379,7 @@
pid_t
gsm_app_launch (GsmApp *app, GError **err)
{
- return GSM_APP_GET_CLASS (app)->launch (app, err);
+ return GSM_APP_GET_CLASS (app)->launch (app, err);
}
/**
@@ -389,8 +391,8 @@
void
gsm_app_registered (GsmApp *app)
{
- g_return_if_fail (GSM_IS_APP (app));
+ g_return_if_fail (GSM_IS_APP (app));
- g_signal_emit (app, signals[REGISTERED], 0);
+ g_signal_emit (app, signals[REGISTERED], 0);
}
Copied: branches/dbus_based/gnome-session/gsm-app.h (from r4726, /trunk/gnome-session/app.h)
==============================================================================
--- /trunk/gnome-session/app.h (original)
+++ branches/dbus_based/gnome-session/gsm-app.h Wed Jun 11 19:10:15 2008
@@ -1,6 +1,21 @@
-/* gsmapp.h
- * Copyright (C) 2006 Novell, Inc.
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
+ * Copyright (C) 2007 Novell, Inc.
+ *
+ * This program 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.
+ *
+ * This program 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 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 __GSM_APP_H__
@@ -10,7 +25,9 @@
#include <sys/types.h>
#include "eggdesktopfile.h"
-#include "session.h"
+
+#include "gsm-manager.h"
+#include "gsm-client.h"
G_BEGIN_DECLS
@@ -27,43 +44,44 @@
struct _GsmApp
{
- GObject parent;
+ GObject parent;
- EggDesktopFile *desktop_file;
- GsmSessionPhase phase;
+ EggDesktopFile *desktop_file;
+ GsmManagerPhase phase;
- pid_t pid;
- char *startup_id, *client_id;
+ pid_t pid;
+ char *startup_id;
+ char *client_id;
};
struct _GsmAppClass
{
- GObjectClass parent_class;
+ GObjectClass parent_class;
- /* signals */
- void (*exited) (GsmApp *app, int status);
- void (*registered) (GsmApp *app);
-
- /* virtual methods */
- const char *(*get_basename) (GsmApp *app);
- gboolean (*is_disabled) (GsmApp *app);
- pid_t (*launch) (GsmApp *app, GError **err);
- void (*set_client) (GsmApp *app, GsmClient *client);
+ /* signals */
+ void (*exited) (GsmApp *app, int status);
+ void (*registered) (GsmApp *app);
+
+ /* virtual methods */
+ const char *(*get_basename) (GsmApp *app);
+ gboolean (*is_disabled) (GsmApp *app);
+ pid_t (*launch) (GsmApp *app, GError **err);
+ void (*set_client) (GsmApp *app, GsmClient *client);
};
GType gsm_app_get_type (void) G_GNUC_CONST;
const char *gsm_app_get_basename (GsmApp *app);
-GsmSessionPhase gsm_app_get_phase (GsmApp *app);
+GsmManagerPhase gsm_app_get_phase (GsmApp *app);
gboolean gsm_app_provides (GsmApp *app,
- const char *service);
+ const char *service);
gboolean gsm_app_is_disabled (GsmApp *app);
pid_t gsm_app_launch (GsmApp *app,
- GError **err);
+ GError **err);
void gsm_app_set_client (GsmApp *app,
- GsmClient *client);
+ GsmClient *client);
-void gsm_app_registered (GsmApp *app);
+void gsm_app_registered (GsmApp *app);
G_END_DECLS
Copied: branches/dbus_based/gnome-session/gsm-autostart-app.c (from r4726, /trunk/gnome-session/app-autostart.c)
==============================================================================
--- /trunk/gnome-session/app-autostart.c (original)
+++ branches/dbus_based/gnome-session/gsm-autostart-app.c Wed Jun 11 19:10:15 2008
@@ -1,4 +1,5 @@
-/* app-autostart.c
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
* Copyright (C) 2007 Novell, Inc.
*
* This program is free software; you can redistribute it and/or
@@ -25,91 +26,90 @@
#include <string.h>
#include <gio/gio.h>
-#include "app-autostart.h"
+#include "gsm-autostart-app.h"
#include "gconf.h"
-enum {
- CONDITION_CHANGED,
- LAST_SIGNAL
+struct _GsmAutostartAppPrivate {
+ GFileMonitor *monitor;
+ gboolean condition;
};
-struct _GsmAppAutostartPrivate {
- GFileMonitor *monitor;
- gboolean condition;
+enum {
+ CONDITION_CHANGED,
+ LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
-static void gsm_app_autostart_dispose (GObject *object);
-
-static gboolean is_disabled (GsmApp *app);
+static void gsm_autostart_app_dispose (GObject *object);
+static gboolean is_disabled (GsmApp *app);
-#define GSM_APP_AUTOSTART_GET_PRIVATE(object) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSM_TYPE_APP_AUTOSTART, GsmAppAutostartPrivate))
+#define GSM_AUTOSTART_APP_GET_PRIVATE(object) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSM_TYPE_AUTOSTART_APP, GsmAutostartAppPrivate))
-G_DEFINE_TYPE (GsmAppAutostart, gsm_app_autostart, GSM_TYPE_APP)
+G_DEFINE_TYPE (GsmAutostartApp, gsm_autostart_app, GSM_TYPE_APP)
static void
-gsm_app_autostart_init (GsmAppAutostart *app)
+gsm_autostart_app_init (GsmAutostartApp *app)
{
- app->priv = GSM_APP_AUTOSTART_GET_PRIVATE (app);
+ app->priv = GSM_AUTOSTART_APP_GET_PRIVATE (app);
- app->priv->monitor = NULL;
- app->priv->condition = FALSE;
+ app->priv->monitor = NULL;
+ app->priv->condition = FALSE;
}
static void
-gsm_app_autostart_class_init (GsmAppAutostartClass *klass)
+gsm_autostart_app_class_init (GsmAutostartAppClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GsmAppClass *app_class = GSM_APP_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GsmAppClass *app_class = GSM_APP_CLASS (klass);
- object_class->dispose = gsm_app_autostart_dispose;
+ object_class->dispose = gsm_autostart_app_dispose;
- app_class->is_disabled = is_disabled;
+ app_class->is_disabled = is_disabled;
- signals[CONDITION_CHANGED] =
- g_signal_new ("condition-changed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GsmAppAutostartClass, condition_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__BOOLEAN,
- G_TYPE_NONE,
- 1,
- G_TYPE_BOOLEAN);
+ signals[CONDITION_CHANGED] =
+ g_signal_new ("condition-changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsmAutostartAppClass, condition_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_BOOLEAN);
- g_type_class_add_private (object_class, sizeof (GsmAppAutostartPrivate));
+ g_type_class_add_private (object_class, sizeof (GsmAutostartAppPrivate));
}
static void
-gsm_app_autostart_dispose (GObject *object)
+gsm_autostart_app_dispose (GObject *object)
{
- GsmAppAutostartPrivate *priv;
+ GsmAutostartAppPrivate *priv;
- priv = GSM_APP_AUTOSTART (object)->priv;
+ priv = GSM_AUTOSTART_APP (object)->priv;
- if (priv->monitor)
- g_file_monitor_cancel (priv->monitor);
+ if (priv->monitor) {
+ g_file_monitor_cancel (priv->monitor);
+ }
}
GsmApp *
-gsm_app_autostart_new (const char *desktop_file,
- const char *client_id)
+gsm_autostart_app_new (const char *desktop_file,
+ const char *client_id)
{
- GsmApp *app;
+ GsmApp *app;
- app = g_object_new (GSM_TYPE_APP_AUTOSTART,
- "desktop-file", desktop_file,
- "client-id", client_id,
- NULL);
- if (!app->desktop_file)
- {
- g_object_unref (app);
- app = NULL;
- }
+ app = g_object_new (GSM_TYPE_AUTOSTART_APP,
+ "desktop-file", desktop_file,
+ "client-id", client_id,
+ NULL);
+ if (!app->desktop_file) {
+ g_object_unref (app);
+ app = NULL;
+ }
- return app;
+ return app;
}
static void
@@ -119,27 +119,26 @@
GFileMonitorEvent event,
GsmApp *app)
{
- GsmAppAutostartPrivate *priv;
- gboolean condition = FALSE;
+ GsmAutostartAppPrivate *priv;
+ gboolean condition = FALSE;
- priv = GSM_APP_AUTOSTART (app)->priv;
+ priv = GSM_AUTOSTART_APP (app)->priv;
- switch (event) {
- case G_FILE_MONITOR_EVENT_DELETED:
- condition = TRUE;
- break;
-
- default:
- /* Ignore any other monitor event */
- return;
- }
-
- /* Emit only if the condition actually changed */
- if (condition != priv->condition)
- {
- priv->condition = condition;
- g_signal_emit (app, signals[CONDITION_CHANGED], 0, condition);
- }
+ switch (event) {
+ case G_FILE_MONITOR_EVENT_DELETED:
+ condition = TRUE;
+ break;
+
+ default:
+ /* Ignore any other monitor event */
+ return;
+ }
+
+ /* Emit only if the condition actually changed */
+ if (condition != priv->condition) {
+ priv->condition = condition;
+ g_signal_emit (app, signals[CONDITION_CHANGED], 0, condition);
+ }
}
static void
@@ -149,27 +148,26 @@
GFileMonitorEvent event,
GsmApp *app)
{
- GsmAppAutostartPrivate *priv;
- gboolean condition = FALSE;
+ GsmAutostartAppPrivate *priv;
+ gboolean condition = FALSE;
- priv = GSM_APP_AUTOSTART (app)->priv;
+ priv = GSM_AUTOSTART_APP (app)->priv;
- switch (event) {
- case G_FILE_MONITOR_EVENT_CREATED:
- condition = TRUE;
- break;
-
- default:
- /* Ignore any other monitor event */
- return;
- }
-
- /* Emit only if the condition actually changed */
- if (condition != priv->condition)
- {
- priv->condition = condition;
- g_signal_emit (app, signals[CONDITION_CHANGED], 0, condition);
- }
+ switch (event) {
+ case G_FILE_MONITOR_EVENT_CREATED:
+ condition = TRUE;
+ break;
+
+ default:
+ /* Ignore any other monitor event */
+ return;
+ }
+
+ /* Emit only if the condition actually changed */
+ if (condition != priv->condition) {
+ priv->condition = condition;
+ g_signal_emit (app, signals[CONDITION_CHANGED], 0, condition);
+ }
}
static void
@@ -178,182 +176,167 @@
GConfEntry *entry,
gpointer user_data)
{
- GsmApp *app;
- GsmAppAutostartPrivate *priv;
- gboolean condition = FALSE;
+ GsmApp *app;
+ GsmAutostartAppPrivate *priv;
+ gboolean condition = FALSE;
- g_return_if_fail (GSM_IS_APP (user_data));
+ g_return_if_fail (GSM_IS_APP (user_data));
- app = GSM_APP (user_data);
+ app = GSM_APP (user_data);
- priv = GSM_APP_AUTOSTART (app)->priv;
+ priv = GSM_AUTOSTART_APP (app)->priv;
- if (entry->value != NULL && entry->value->type == GCONF_VALUE_BOOL)
- condition = gconf_value_get_bool (entry->value);
+ if (entry->value != NULL && entry->value->type == GCONF_VALUE_BOOL) {
+ condition = gconf_value_get_bool (entry->value);
+ }
- /* Emit only if the condition actually changed */
- if (condition != priv->condition)
- {
- priv->condition = condition;
- g_signal_emit (app, signals[CONDITION_CHANGED], 0, condition);
- }
+ /* Emit only if the condition actually changed */
+ if (condition != priv->condition) {
+ priv->condition = condition;
+ g_signal_emit (app, signals[CONDITION_CHANGED], 0, condition);
+ }
}
static gboolean
is_disabled (GsmApp *app)
{
- GsmAppAutostartPrivate *priv;
- char *condition;
- gboolean autorestart = FALSE;
-
- priv = GSM_APP_AUTOSTART (app)->priv;
-
- if (egg_desktop_file_has_key (app->desktop_file,
- "X-GNOME-AutoRestart", NULL))
- {
- autorestart =
- egg_desktop_file_get_boolean (app->desktop_file,
- "X-GNOME-AutoRestart", NULL);
- }
-
- /* X-GNOME-Autostart-enabled key, used by old gnome-session */
- if (egg_desktop_file_has_key (app->desktop_file,
- "X-GNOME-Autostart-enabled", NULL) &&
- !egg_desktop_file_get_boolean (app->desktop_file,
- "X-GNOME-Autostart-enabled", NULL))
- {
- g_debug ("app %s is disabled by X-GNOME-Autostart-enabled",
- gsm_app_get_basename (app));
- return TRUE;
- }
-
- /* Hidden key, used by autostart spec */
- if (egg_desktop_file_get_boolean (app->desktop_file,
- EGG_DESKTOP_FILE_KEY_HIDDEN, NULL))
- {
- g_debug ("app %s is disabled by Hidden",
- gsm_app_get_basename (app));
- return TRUE;
- }
-
- /* Check OnlyShowIn/NotShowIn/TryExec */
- if (!egg_desktop_file_can_launch (app->desktop_file, "GNOME"))
- {
- g_debug ("app %s not installed or not for GNOME",
- gsm_app_get_basename (app));
- return TRUE;
- }
-
- /* Check AutostartCondition */
- condition = egg_desktop_file_get_string (app->desktop_file,
- "AutostartCondition",
- NULL);
-
- if (condition)
- {
- gboolean disabled;
- char *space, *key;
- int len;
-
- space = condition + strcspn (condition, " ");
- len = space - condition;
- key = space;
- while (isspace ((unsigned char)*key))
- key++;
-
- if (!g_ascii_strncasecmp (condition, "if-exists", len) && key)
- {
- char *file_path = g_build_filename (g_get_user_config_dir (), key, NULL);
-
- disabled = !g_file_test (file_path, G_FILE_TEST_EXISTS);
-
- if (autorestart)
- {
- GFile *file = g_file_new_for_path (file_path);
-
- priv->monitor = g_file_monitor_file (file, 0, NULL, NULL);
-
- g_signal_connect (priv->monitor, "changed",
- G_CALLBACK (if_exists_condition_cb),
- app);
-
- g_object_unref (file);
- }
-
- g_free (file_path);
- }
- else if (!g_ascii_strncasecmp (condition, "unless-exists", len) && key)
- {
- char *file_path = g_build_filename (g_get_user_config_dir (), key, NULL);
-
- disabled = g_file_test (file_path, G_FILE_TEST_EXISTS);
-
- if (autorestart)
- {
- GFile *file = g_file_new_for_path (file_path);
-
- priv->monitor = g_file_monitor_file (file, 0, NULL, NULL);
-
- g_signal_connect (priv->monitor, "changed",
- G_CALLBACK (unless_exists_condition_cb),
- app);
-
- g_object_unref (file);
- }
-
- g_free (file_path);
- }
- else if (!g_ascii_strncasecmp (condition, "GNOME", len))
- {
- if (key)
- {
- GConfClient *client;
-
- client = gsm_gconf_get_client ();
-
- g_assert (GCONF_IS_CLIENT (client));
-
- disabled = !gconf_client_get_bool (client, key, NULL);
-
- if (autorestart)
- {
- gchar *dir;
-
- dir = g_path_get_dirname (key);
-
- /* Add key dir in order to be able to keep track
- * of changed in the key later */
- gconf_client_add_dir (client, dir,
- GCONF_CLIENT_PRELOAD_RECURSIVE, NULL);
-
- g_free (dir);
-
- gconf_client_notify_add (client,
- key,
- gconf_condition_cb,
- app, NULL, NULL);
+ GsmAutostartAppPrivate *priv;
+ char *condition;
+ gboolean autorestart = FALSE;
+
+ priv = GSM_AUTOSTART_APP (app)->priv;
+
+ if (egg_desktop_file_has_key (app->desktop_file,
+ "X-GNOME-AutoRestart", NULL)) {
+ autorestart = egg_desktop_file_get_boolean (app->desktop_file,
+ "X-GNOME-AutoRestart", NULL);
+ }
+
+ /* X-GNOME-Autostart-enabled key, used by old gnome-session */
+ if (egg_desktop_file_has_key (app->desktop_file,
+ "X-GNOME-Autostart-enabled", NULL) &&
+ !egg_desktop_file_get_boolean (app->desktop_file,
+ "X-GNOME-Autostart-enabled", NULL)) {
+ g_debug ("app %s is disabled by X-GNOME-Autostart-enabled",
+ gsm_app_get_basename (app));
+ return TRUE;
+ }
+
+ /* Hidden key, used by autostart spec */
+ if (egg_desktop_file_get_boolean (app->desktop_file,
+ EGG_DESKTOP_FILE_KEY_HIDDEN, NULL)) {
+ g_debug ("app %s is disabled by Hidden",
+ gsm_app_get_basename (app));
+ return TRUE;
+ }
+
+ /* Check OnlyShowIn/NotShowIn/TryExec */
+ if (!egg_desktop_file_can_launch (app->desktop_file, "GNOME")) {
+ g_debug ("app %s not installed or not for GNOME",
+ gsm_app_get_basename (app));
+ return TRUE;
+ }
+
+ /* Check AutostartCondition */
+ condition = egg_desktop_file_get_string (app->desktop_file,
+ "AutostartCondition",
+ NULL);
+
+ if (condition) {
+ gboolean disabled;
+ char *space, *key;
+ int len;
+
+ space = condition + strcspn (condition, " ");
+ len = space - condition;
+ key = space;
+ while (isspace ((unsigned char)*key)) {
+ key++;
+ }
+
+ if (!g_ascii_strncasecmp (condition, "if-exists", len) && key) {
+ char *file_path = g_build_filename (g_get_user_config_dir (), key, NULL);
+
+ disabled = !g_file_test (file_path, G_FILE_TEST_EXISTS);
+
+ if (autorestart) {
+ GFile *file = g_file_new_for_path (file_path);
+
+ priv->monitor = g_file_monitor_file (file, 0, NULL, NULL);
+
+ g_signal_connect (priv->monitor, "changed",
+ G_CALLBACK (if_exists_condition_cb),
+ app);
+
+ g_object_unref (file);
+ }
+
+ g_free (file_path);
+ } else if (!g_ascii_strncasecmp (condition, "unless-exists", len) && key) {
+ char *file_path = g_build_filename (g_get_user_config_dir (), key, NULL);
+
+ disabled = g_file_test (file_path, G_FILE_TEST_EXISTS);
+
+ if (autorestart) {
+ GFile *file = g_file_new_for_path (file_path);
+
+ priv->monitor = g_file_monitor_file (file, 0, NULL, NULL);
+
+ g_signal_connect (priv->monitor, "changed",
+ G_CALLBACK (unless_exists_condition_cb),
+ app);
+
+ g_object_unref (file);
+ }
+
+ g_free (file_path);
+ } else if (!g_ascii_strncasecmp (condition, "GNOME", len)) {
+ if (key) {
+ GConfClient *client;
+
+ client = gsm_gconf_get_client ();
+
+ g_assert (GCONF_IS_CLIENT (client));
+
+ disabled = !gconf_client_get_bool (client, key, NULL);
+
+ if (autorestart) {
+ gchar *dir;
+
+ dir = g_path_get_dirname (key);
+
+ /* Add key dir in order to be able to keep track
+ * of changed in the key later */
+ gconf_client_add_dir (client, dir,
+ GCONF_CLIENT_PRELOAD_RECURSIVE, NULL);
+
+ g_free (dir);
+
+ gconf_client_notify_add (client,
+ key,
+ gconf_condition_cb,
+ app, NULL, NULL);
+ }
+ } else {
+ disabled = FALSE;
+ }
+ } else {
+ disabled = TRUE;
+ }
+
+ g_free (condition);
+
+ /* Set initial condition */
+ priv->condition = !disabled;
+
+ if (disabled) {
+ g_debug ("app %s is disabled by AutostartCondition",
+ gsm_app_get_basename (app));
+ return TRUE;
}
- }
- else
- disabled = FALSE;
- }
- else
- disabled = TRUE;
-
- g_free (condition);
-
- /* Set initial condition */
- priv->condition = !disabled;
-
- if (disabled)
- {
- g_debug ("app %s is disabled by AutostartCondition",
- gsm_app_get_basename (app));
- return TRUE;
- }
- }
+ }
- priv->condition = TRUE;
+ priv->condition = TRUE;
- return FALSE;
+ return FALSE;
}
Copied: branches/dbus_based/gnome-session/gsm-autostart-app.h (from r4726, /trunk/gnome-session/app-autostart.h)
==============================================================================
--- /trunk/gnome-session/app-autostart.h (original)
+++ branches/dbus_based/gnome-session/gsm-autostart-app.h Wed Jun 11 19:10:15 2008
@@ -1,4 +1,5 @@
-/* app-autostart.h
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
* Copyright (C) 2007 Novell, Inc.
*
* This program is free software; you can redistribute it and/or
@@ -17,46 +18,47 @@
* 02111-1307, USA.
*/
-#ifndef __GSM_APP_AUTOSTART_H__
-#define __GSM_APP_AUTOSTART_H__
+#ifndef __GSM_AUTOSTART_APP_H__
+#define __GSM_AUTOSTART_APP_H__
-#include "app.h"
+#include "gsm-app.h"
#include <X11/SM/SMlib.h>
G_BEGIN_DECLS
-#define GSM_TYPE_APP_AUTOSTART (gsm_app_autostart_get_type ())
-#define GSM_APP_AUTOSTART(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSM_TYPE_APP_AUTOSTART, GsmAppAutostart))
-#define GSM_APP_AUTOSTART_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSM_TYPE_APP_AUTOSTART, GsmAppAutostartClass))
-#define GSM_IS_APP_AUTOSTART(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSM_TYPE_APP_AUTOSTART))
-#define GSM_IS_APP_AUTOSTART_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSM_TYPE_APP_AUTOSTART))
-#define GSM_APP_AUTOSTART_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSM_TYPE_APP_AUTOSTART, GsmAppAutostartClass))
-
-typedef struct _GsmAppAutostart GsmAppAutostart;
-typedef struct _GsmAppAutostartClass GsmAppAutostartClass;
-typedef struct _GsmAppAutostartPrivate GsmAppAutostartPrivate;
+#define GSM_TYPE_AUTOSTART_APP (gsm_autostart_app_get_type ())
+#define GSM_AUTOSTART_APP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSM_TYPE_AUTOSTART_APP, GsmAutostartApp))
+#define GSM_AUTOSTART_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSM_TYPE_AUTOSTART_APP, GsmAutostartAppClass))
+#define GSM_IS_AUTOSTART_APP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSM_TYPE_AUTOSTART_APP))
+#define GSM_IS_AUTOSTART_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSM_TYPE_AUTOSTART_APP))
+#define GSM_AUTOSTART_APP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSM_TYPE_AUTOSTART_APP, GsmAutostartAppClass))
+
+typedef struct _GsmAutostartApp GsmAutostartApp;
+typedef struct _GsmAutostartAppClass GsmAutostartAppClass;
+typedef struct _GsmAutostartAppPrivate GsmAutostartAppPrivate;
-struct _GsmAppAutostart
+struct _GsmAutostartApp
{
- GsmApp parent;
+ GsmApp parent;
- GsmAppAutostartPrivate *priv;
+ GsmAutostartAppPrivate *priv;
};
-struct _GsmAppAutostartClass
+struct _GsmAutostartAppClass
{
- GsmAppClass parent_class;
+ GsmAppClass parent_class;
- /* signals */
- void (*condition_changed) (GsmApp *app, gboolean condition);
+ /* signals */
+ void (*condition_changed) (GsmApp *app,
+ gboolean condition);
};
-GType gsm_app_autostart_get_type (void) G_GNUC_CONST;
+GType gsm_autostart_app_get_type (void) G_GNUC_CONST;
-GsmApp *gsm_app_autostart_new (const char *desktop_file,
- const char *client_id);
+GsmApp *gsm_autostart_app_new (const char *desktop_file,
+ const char *client_id);
G_END_DECLS
-#endif /* __GSM_APP_AUTOSTART_H__ */
+#endif /* __GSM_AUTOSTART_APP_H__ */
Added: branches/dbus_based/gnome-session/gsm-client-store.c
==============================================================================
--- (empty file)
+++ branches/dbus_based/gnome-session/gsm-client-store.c Wed Jun 11 19:10:15 2008
@@ -0,0 +1,239 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 William Jon McCann <mccann jhu edu>
+ *
+ * This program 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.
+ *
+ * This program 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 "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+
+#include "gsm-client-store.h"
+#include "gsm-client.h"
+
+#define GSM_CLIENT_STORE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_CLIENT_STORE, GsmClientStorePrivate))
+
+struct GsmClientStorePrivate
+{
+ GHashTable *clients;
+};
+
+enum {
+ CLIENT_ADDED,
+ CLIENT_REMOVED,
+ LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0, };
+
+static void gsm_client_store_class_init (GsmClientStoreClass *klass);
+static void gsm_client_store_init (GsmClientStore *client_store);
+static void gsm_client_store_finalize (GObject *object);
+
+G_DEFINE_TYPE (GsmClientStore, gsm_client_store, G_TYPE_OBJECT)
+
+GQuark
+gsm_client_store_error_quark (void)
+{
+ static GQuark ret = 0;
+ if (ret == 0) {
+ ret = g_quark_from_static_string ("gsm_client_store_error");
+ }
+
+ return ret;
+}
+
+void
+gsm_client_store_clear (GsmClientStore *store)
+{
+ g_return_if_fail (store != NULL);
+ g_debug ("GsmClientStore: Clearing client store");
+ g_hash_table_remove_all (store->priv->clients);
+}
+
+static gboolean
+remove_client (char *id,
+ GsmClient *client,
+ GsmClient *client_to_remove)
+{
+ if (client == client_to_remove) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gboolean
+gsm_client_store_remove (GsmClientStore *store,
+ GsmClient *client)
+{
+ g_return_val_if_fail (store != NULL, FALSE);
+
+ gsm_client_store_foreach_remove (store,
+ (GsmClientStoreFunc)remove_client,
+ client);
+ return FALSE;
+}
+
+void
+gsm_client_store_foreach (GsmClientStore *store,
+ GsmClientStoreFunc func,
+ gpointer user_data)
+{
+ g_return_if_fail (store != NULL);
+ g_return_if_fail (func != NULL);
+
+ g_hash_table_find (store->priv->clients,
+ (GHRFunc)func,
+ user_data);
+}
+
+GsmClient *
+gsm_client_store_find (GsmClientStore *store,
+ GsmClientStoreFunc predicate,
+ gpointer user_data)
+{
+ GsmClient *client;
+
+ g_return_val_if_fail (store != NULL, NULL);
+ g_return_val_if_fail (predicate != NULL, NULL);
+
+ client = g_hash_table_find (store->priv->clients,
+ (GHRFunc)predicate,
+ user_data);
+ return client;
+}
+
+guint
+gsm_client_store_foreach_remove (GsmClientStore *store,
+ GsmClientStoreFunc func,
+ gpointer user_data)
+{
+ guint ret;
+
+ g_return_val_if_fail (store != NULL, 0);
+ g_return_val_if_fail (func != NULL, 0);
+
+ ret = g_hash_table_foreach_remove (store->priv->clients,
+ (GHRFunc)func,
+ user_data);
+
+ return ret;
+}
+
+void
+gsm_client_store_add (GsmClientStore *store,
+ GsmClient *client)
+{
+ char *id;
+
+ g_return_if_fail (store != NULL);
+ g_return_if_fail (client != NULL);
+
+ id = gsm_client_get_id (client);
+
+ g_debug ("GsmClientStore: Adding client %s to store", id);
+
+ g_hash_table_insert (store->priv->clients,
+ id,
+ g_object_ref (client));
+}
+
+static void
+gsm_client_store_class_init (GsmClientStoreClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = gsm_client_store_finalize;
+
+ signals [CLIENT_ADDED] =
+ g_signal_new ("client-added",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsmClientStoreClass, client_added),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1, G_TYPE_STRING);
+ signals [CLIENT_REMOVED] =
+ g_signal_new ("client-removed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsmClientStoreClass, client_removed),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1, G_TYPE_STRING);
+
+ g_type_class_add_private (klass, sizeof (GsmClientStorePrivate));
+}
+
+static void
+client_unref (GsmClient *client)
+{
+ g_debug ("GsmClientStore: Unreffing client: %p", client);
+ g_object_unref (client);
+}
+
+static void
+gsm_client_store_init (GsmClientStore *store)
+{
+
+ store->priv = GSM_CLIENT_STORE_GET_PRIVATE (store);
+
+ store->priv->clients = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ (GDestroyNotify) client_unref);
+}
+
+static void
+gsm_client_store_finalize (GObject *object)
+{
+ GsmClientStore *store;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GSM_IS_CLIENT_STORE (object));
+
+ store = GSM_CLIENT_STORE (object);
+
+ g_return_if_fail (store->priv != NULL);
+
+ g_hash_table_destroy (store->priv->clients);
+
+ G_OBJECT_CLASS (gsm_client_store_parent_class)->finalize (object);
+}
+
+GsmClientStore *
+gsm_client_store_new (void)
+{
+ GObject *object;
+
+ object = g_object_new (GSM_TYPE_CLIENT_STORE,
+ NULL);
+
+ return GSM_CLIENT_STORE (object);
+}
Added: branches/dbus_based/gnome-session/gsm-client-store.h
==============================================================================
--- (empty file)
+++ branches/dbus_based/gnome-session/gsm-client-store.h Wed Jun 11 19:10:15 2008
@@ -0,0 +1,89 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 William Jon McCann <mccann jhu edu>
+ *
+ * This program 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.
+ *
+ * This program 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 __GSM_DISPLAY_STORE_H
+#define __GSM_DISPLAY_STORE_H
+
+#include <glib-object.h>
+#include "gsm-client.h"
+
+G_BEGIN_DECLS
+
+#define GSM_TYPE_CLIENT_STORE (gsm_client_store_get_type ())
+#define GSM_CLIENT_STORE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSM_TYPE_CLIENT_STORE, GsmClientStore))
+#define GSM_CLIENT_STORE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSM_TYPE_CLIENT_STORE, GsmClientStoreClass))
+#define GSM_IS_CLIENT_STORE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSM_TYPE_CLIENT_STORE))
+#define GSM_IS_CLIENT_STORE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSM_TYPE_CLIENT_STORE))
+#define GSM_CLIENT_STORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSM_TYPE_CLIENT_STORE, GsmClientStoreClass))
+
+typedef struct GsmClientStorePrivate GsmClientStorePrivate;
+
+typedef struct
+{
+ GObject parent;
+ GsmClientStorePrivate *priv;
+} GsmClientStore;
+
+typedef struct
+{
+ GObjectClass parent_class;
+
+ void (* client_added) (GsmClientStore *client_store,
+ const char *id);
+ void (* client_removed) (GsmClientStore *client_store,
+ const char *id);
+} GsmClientStoreClass;
+
+typedef enum
+{
+ GSM_CLIENT_STORE_ERROR_GENERAL
+} GsmClientStoreError;
+
+#define GSM_CLIENT_STORE_ERROR gsm_client_store_error_quark ()
+
+typedef gboolean (*GsmClientStoreFunc) (const char *id,
+ GsmClient *client,
+ gpointer user_data);
+
+GQuark gsm_client_store_error_quark (void);
+GType gsm_client_store_get_type (void);
+
+GsmClientStore * gsm_client_store_new (void);
+
+void gsm_client_store_add (GsmClientStore *store,
+ GsmClient *client);
+void gsm_client_store_clear (GsmClientStore *store);
+gboolean gsm_client_store_remove (GsmClientStore *store,
+ GsmClient *client);
+void gsm_client_store_foreach (GsmClientStore *store,
+ GsmClientStoreFunc func,
+ gpointer user_data);
+guint gsm_client_store_foreach_remove (GsmClientStore *store,
+ GsmClientStoreFunc func,
+ gpointer user_data);
+GsmClient * gsm_client_store_find (GsmClientStore *store,
+ GsmClientStoreFunc predicate,
+ gpointer user_data);
+
+
+G_END_DECLS
+
+#endif /* __GSM_CLIENT_STORE_H */
Copied: branches/dbus_based/gnome-session/gsm-client.c (from r4726, /trunk/gnome-session/client.c)
==============================================================================
--- /trunk/gnome-session/client.c (original)
+++ branches/dbus_based/gnome-session/gsm-client.c Wed Jun 11 19:10:15 2008
@@ -1,4 +1,5 @@
-/* client.c
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
* Copyright (C) 2007 Novell, Inc.
*
* This program is free software; you can redistribute it and/or
@@ -21,231 +22,340 @@
#include "config.h"
#endif
-#include "client.h"
+#include "gsm-marshal.h"
+#include "gsm-client.h"
+
+static guint32 client_serial = 1;
+
+#define GSM_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_CLIENT, GsmClientPrivate))
+
+struct GsmClientPrivate
+{
+ char *id;
+};
enum {
- SAVED_STATE,
- REQUEST_PHASE2,
- REQUEST_INTERACTION,
- INTERACTION_DONE,
- SAVE_YOURSELF_DONE,
- DISCONNECTED,
- LAST_SIGNAL
+ SAVED_STATE,
+ REQUEST_PHASE2,
+ REQUEST_INTERACTION,
+ INTERACTION_DONE,
+ SAVE_YOURSELF_DONE,
+ DISCONNECTED,
+ REGISTER_CLIENT,
+ REQUEST_LOGOUT,
+ LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (GsmClient, gsm_client, G_TYPE_OBJECT)
+static guint32
+get_next_client_serial (void)
+{
+ guint32 serial;
+
+ serial = client_serial++;
+
+ if ((gint32)client_serial < 0) {
+ client_serial = 1;
+ }
+
+ return serial;
+}
+
+static GObject *
+gsm_client_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
+{
+ GsmClient *client;
+
+ client = GSM_CLIENT (G_OBJECT_CLASS (gsm_client_parent_class)->constructor (type,
+ n_construct_properties,
+ construct_properties));
+
+ g_free (client->priv->id);
+ client->priv->id = g_strdup_printf ("/org/gnome/SessionManager/Client%u", get_next_client_serial ());
+
+#if 0
+ res = register_client (client);
+ if (! res) {
+ g_warning ("Unable to register client with session bus");
+ }
+#endif
+ return G_OBJECT (client);
+}
+
static void
gsm_client_init (GsmClient *client)
{
- ;
+ client->priv = GSM_CLIENT_GET_PRIVATE (client);
+}
+
+static void
+gsm_client_finalize (GObject *object)
+{
+ GsmClient *client;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GSM_IS_CLIENT (object));
+
+ client = GSM_CLIENT (object);
+
+ g_return_if_fail (client->priv != NULL);
+
+ g_free (client->priv->id);
}
static void
gsm_client_class_init (GsmClientClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructor = gsm_client_constructor;
+ object_class->finalize = gsm_client_finalize;
+
+ signals[SAVED_STATE] =
+ g_signal_new ("saved_state",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsmClientClass, saved_state),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ signals[REQUEST_PHASE2] =
+ g_signal_new ("request_phase2",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsmClientClass, request_phase2),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ signals[REQUEST_INTERACTION] =
+ g_signal_new ("request_interaction",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsmClientClass, request_interaction),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ signals[INTERACTION_DONE] =
+ g_signal_new ("interaction_done",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsmClientClass, interaction_done),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE,
+ 1, G_TYPE_BOOLEAN);
+
+ signals[SAVE_YOURSELF_DONE] =
+ g_signal_new ("save_yourself_done",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsmClientClass, save_yourself_done),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ signals[DISCONNECTED] =
+ g_signal_new ("disconnected",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsmClientClass, disconnected),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+ signals[REGISTER_CLIENT] =
+ g_signal_new ("register-client",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsmClientClass, register_client),
+ NULL, NULL,
+ gsm_marshal_STRING__STRING,
+ G_TYPE_STRING,
+ 1, G_TYPE_STRING);
+ signals[REQUEST_LOGOUT] =
+ g_signal_new ("request-logout",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsmClientClass, request_logout),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE,
+ 0);
+
+ g_type_class_add_private (klass, sizeof (GsmClientPrivate));
+}
- signals[SAVED_STATE] =
- g_signal_new ("saved_state",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GsmClientClass, saved_state),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-
- signals[REQUEST_PHASE2] =
- g_signal_new ("request_phase2",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GsmClientClass, request_phase2),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-
- signals[REQUEST_INTERACTION] =
- g_signal_new ("request_interaction",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GsmClientClass, request_interaction),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-
- signals[INTERACTION_DONE] =
- g_signal_new ("interaction_done",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GsmClientClass, interaction_done),
- NULL, NULL,
- g_cclosure_marshal_VOID__BOOLEAN,
- G_TYPE_NONE,
- 1, G_TYPE_BOOLEAN);
-
- signals[SAVE_YOURSELF_DONE] =
- g_signal_new ("save_yourself_done",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GsmClientClass, save_yourself_done),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-
- signals[DISCONNECTED] =
- g_signal_new ("disconnected",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GsmClientClass, disconnected),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
+const char *
+gsm_client_get_id (GsmClient *client)
+{
+ g_return_val_if_fail (GSM_IS_CLIENT (client), NULL);
+ return client->priv->id;
}
+
const char *
gsm_client_get_client_id (GsmClient *client)
{
- g_return_val_if_fail (GSM_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (GSM_IS_CLIENT (client), NULL);
- return GSM_CLIENT_GET_CLASS (client)->get_client_id (client);
+ return GSM_CLIENT_GET_CLASS (client)->get_client_id (client);
}
pid_t
gsm_client_get_pid (GsmClient *client)
{
- g_return_val_if_fail (GSM_IS_CLIENT (client), -1);
+ g_return_val_if_fail (GSM_IS_CLIENT (client), -1);
- return GSM_CLIENT_GET_CLASS (client)->get_pid (client);
+ return GSM_CLIENT_GET_CLASS (client)->get_pid (client);
}
char *
gsm_client_get_desktop_file (GsmClient *client)
{
- g_return_val_if_fail (GSM_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (GSM_IS_CLIENT (client), NULL);
- return GSM_CLIENT_GET_CLASS (client)->get_desktop_file (client);
+ return GSM_CLIENT_GET_CLASS (client)->get_desktop_file (client);
}
char *
gsm_client_get_restart_command (GsmClient *client)
{
- g_return_val_if_fail (GSM_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (GSM_IS_CLIENT (client), NULL);
- return GSM_CLIENT_GET_CLASS (client)->get_restart_command (client);
+ return GSM_CLIENT_GET_CLASS (client)->get_restart_command (client);
}
char *
gsm_client_get_discard_command (GsmClient *client)
{
- g_return_val_if_fail (GSM_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (GSM_IS_CLIENT (client), NULL);
- return GSM_CLIENT_GET_CLASS (client)->get_discard_command (client);
+ return GSM_CLIENT_GET_CLASS (client)->get_discard_command (client);
}
gboolean
gsm_client_get_autorestart (GsmClient *client)
{
- g_return_val_if_fail (GSM_IS_CLIENT (client), FALSE);
+ g_return_val_if_fail (GSM_IS_CLIENT (client), FALSE);
- return GSM_CLIENT_GET_CLASS (client)->get_autorestart (client);
+ return GSM_CLIENT_GET_CLASS (client)->get_autorestart (client);
}
void
gsm_client_save_state (GsmClient *client)
{
- g_return_if_fail (GSM_IS_CLIENT (client));
+ g_return_if_fail (GSM_IS_CLIENT (client));
}
void
gsm_client_restart (GsmClient *client, GError **error)
{
- g_return_if_fail (GSM_IS_CLIENT (client));
+ g_return_if_fail (GSM_IS_CLIENT (client));
- GSM_CLIENT_GET_CLASS (client)->restart (client, error);
+ GSM_CLIENT_GET_CLASS (client)->restart (client, error);
}
void
gsm_client_save_yourself (GsmClient *client,
- gboolean save_state)
+ gboolean save_state)
{
- g_return_if_fail (GSM_IS_CLIENT (client));
+ g_return_if_fail (GSM_IS_CLIENT (client));
- GSM_CLIENT_GET_CLASS (client)->save_yourself (client, save_state);
+ GSM_CLIENT_GET_CLASS (client)->save_yourself (client, save_state);
}
void
gsm_client_save_yourself_phase2 (GsmClient *client)
{
- g_return_if_fail (GSM_IS_CLIENT (client));
+ g_return_if_fail (GSM_IS_CLIENT (client));
- GSM_CLIENT_GET_CLASS (client)->save_yourself_phase2 (client);
+ GSM_CLIENT_GET_CLASS (client)->save_yourself_phase2 (client);
}
void
gsm_client_interact (GsmClient *client)
{
- g_return_if_fail (GSM_IS_CLIENT (client));
+ g_return_if_fail (GSM_IS_CLIENT (client));
- GSM_CLIENT_GET_CLASS (client)->interact (client);
+ GSM_CLIENT_GET_CLASS (client)->interact (client);
}
void
gsm_client_shutdown_cancelled (GsmClient *client)
{
- g_return_if_fail (GSM_IS_CLIENT (client));
+ g_return_if_fail (GSM_IS_CLIENT (client));
- GSM_CLIENT_GET_CLASS (client)->shutdown_cancelled (client);
+ GSM_CLIENT_GET_CLASS (client)->shutdown_cancelled (client);
}
void
gsm_client_die (GsmClient *client)
{
- g_return_if_fail (GSM_IS_CLIENT (client));
+ g_return_if_fail (GSM_IS_CLIENT (client));
- GSM_CLIENT_GET_CLASS (client)->die (client);
+ GSM_CLIENT_GET_CLASS (client)->die (client);
}
void
gsm_client_saved_state (GsmClient *client)
{
- g_signal_emit (client, signals[SAVED_STATE], 0);
+ g_signal_emit (client, signals[SAVED_STATE], 0);
}
void
gsm_client_request_phase2 (GsmClient *client)
{
- g_signal_emit (client, signals[REQUEST_PHASE2], 0);
+ g_signal_emit (client, signals[REQUEST_PHASE2], 0);
}
void
gsm_client_request_interaction (GsmClient *client)
{
- g_signal_emit (client, signals[REQUEST_INTERACTION], 0);
+ g_signal_emit (client, signals[REQUEST_INTERACTION], 0);
}
void
gsm_client_interaction_done (GsmClient *client, gboolean cancel_shutdown)
{
- g_signal_emit (client, signals[INTERACTION_DONE], 0, cancel_shutdown);
+ g_signal_emit (client, signals[INTERACTION_DONE], 0, cancel_shutdown);
}
void
gsm_client_save_yourself_done (GsmClient *client)
{
- g_signal_emit (client, signals[SAVE_YOURSELF_DONE], 0);
+ g_signal_emit (client, signals[SAVE_YOURSELF_DONE], 0);
}
void
gsm_client_disconnected (GsmClient *client)
{
- g_signal_emit (client, signals[DISCONNECTED], 0);
+ g_signal_emit (client, signals[DISCONNECTED], 0);
+}
+
+void
+gsm_client_register_client (GsmClient *client,
+ const char *previous_id,
+ char **id)
+{
+ g_signal_emit (client, signals[REGISTER_CLIENT], 0, previous_id, id);
}
+void
+gsm_client_request_logout (GsmClient *client,
+ gboolean prompt)
+{
+ g_signal_emit (client, signals[REQUEST_LOGOUT], 0, prompt);
+}
Copied: branches/dbus_based/gnome-session/gsm-client.h (from r4726, /trunk/gnome-session/client.h)
==============================================================================
--- /trunk/gnome-session/client.h (original)
+++ branches/dbus_based/gnome-session/gsm-client.h Wed Jun 11 19:10:15 2008
@@ -1,4 +1,5 @@
-/* client.h
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
* Copyright (C) 2007 Novell, Inc.
*
* This program is free software; you can redistribute it and/or
@@ -35,49 +36,58 @@
typedef struct _GsmClient GsmClient;
typedef struct _GsmClientClass GsmClientClass;
+typedef struct GsmClientPrivate GsmClientPrivate;
+
struct _GsmClient
{
- GObject parent;
-
+ GObject parent;
+ GsmClientPrivate *priv;
};
struct _GsmClientClass
{
- GObjectClass parent_class;
+ GObjectClass parent_class;
- /* signals */
- void (*saved_state) (GsmClient *client);
-
- void (*request_phase2) (GsmClient *client);
-
- void (*request_interaction) (GsmClient *client);
- void (*interaction_done) (GsmClient *client,
- gboolean cancel_shutdown);
-
- void (*save_yourself_done) (GsmClient *client);
-
- void (*disconnected) (GsmClient *client);
-
- /* virtual methods */
- const char * (*get_client_id) (GsmClient *client);
- pid_t (*get_pid) (GsmClient *client);
- char * (*get_desktop_file) (GsmClient *client);
- char * (*get_restart_command) (GsmClient *client);
- char * (*get_discard_command) (GsmClient *client);
- gboolean (*get_autorestart) (GsmClient *client);
-
- void (*restart) (GsmClient *client,
- GError **error);
- void (*save_yourself) (GsmClient *client,
- gboolean save_state);
- void (*save_yourself_phase2) (GsmClient *client);
- void (*interact) (GsmClient *client);
- void (*shutdown_cancelled) (GsmClient *client);
- void (*die) (GsmClient *client);
+ /* signals */
+ void (*register_client) (GsmClient *client,
+ const char *previous_id,
+ char **id);
+ void (*request_logout) (GsmClient *client,
+ gboolean prompt);
+
+ void (*saved_state) (GsmClient *client);
+
+ void (*request_phase2) (GsmClient *client);
+
+ void (*request_interaction) (GsmClient *client);
+ void (*interaction_done) (GsmClient *client,
+ gboolean cancel_shutdown);
+
+ void (*save_yourself_done) (GsmClient *client);
+
+ void (*disconnected) (GsmClient *client);
+
+ /* virtual methods */
+ const char * (*get_client_id) (GsmClient *client);
+ pid_t (*get_pid) (GsmClient *client);
+ char * (*get_desktop_file) (GsmClient *client);
+ char * (*get_restart_command) (GsmClient *client);
+ char * (*get_discard_command) (GsmClient *client);
+ gboolean (*get_autorestart) (GsmClient *client);
+
+ void (*restart) (GsmClient *client,
+ GError **error);
+ void (*save_yourself) (GsmClient *client,
+ gboolean save_state);
+ void (*save_yourself_phase2) (GsmClient *client);
+ void (*interact) (GsmClient *client);
+ void (*shutdown_cancelled) (GsmClient *client);
+ void (*die) (GsmClient *client);
};
GType gsm_client_get_type (void) G_GNUC_CONST;
+const char *gsm_client_get_id (GsmClient *client);
const char *gsm_client_get_client_id (GsmClient *client);
pid_t gsm_client_get_pid (GsmClient *client);
@@ -91,7 +101,7 @@
void gsm_client_restart (GsmClient *client,
GError **error);
void gsm_client_save_yourself (GsmClient *client,
- gboolean save_state);
+ gboolean save_state);
void gsm_client_save_yourself_phase2 (GsmClient *client);
void gsm_client_interact (GsmClient *client);
void gsm_client_shutdown_cancelled (GsmClient *client);
@@ -102,10 +112,16 @@
void gsm_client_request_phase2 (GsmClient *client);
void gsm_client_request_interaction (GsmClient *client);
void gsm_client_interaction_done (GsmClient *client,
- gboolean cancel_shutdown);
+ gboolean cancel_shutdown);
void gsm_client_save_yourself_done (GsmClient *client);
void gsm_client_disconnected (GsmClient *client);
+void gsm_client_register_client (GsmClient *client,
+ const char *previous_id,
+ char **id);
+void gsm_client_request_logout (GsmClient *client,
+ gboolean prompt);
+
G_END_DECLS
#endif /* __GSM_CLIENT_H__ */
Added: branches/dbus_based/gnome-session/gsm-manager.c
==============================================================================
--- (empty file)
+++ branches/dbus_based/gnome-session/gsm-manager.c Wed Jun 11 19:10:15 2008
@@ -0,0 +1,1168 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Novell, Inc.
+ * Copyright (C) 2008 William Jon McCann <jmccann redhat com>
+ *
+ * This program 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.
+ *
+ * This program 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 "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <glib-object.h>
+#define DBUS_API_SUBJECT_TO_CHANGE
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <gtk/gtk.h> /* for logout dialog */
+#include <gconf/gconf-client.h>
+
+#include "gsm-manager.h"
+#include "gsm-manager-glue.h"
+
+#include "gsm-autostart-app.h"
+#include "gsm-resumed-app.h"
+#include "util.h"
+#include "gdm.h"
+#include "logout-dialog.h"
+#include "power-manager.h"
+
+#define GSM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_MANAGER, GsmManagerPrivate))
+
+#define GSM_DBUS_PATH "/org/gnome/SessionManager"
+#define GSM_MANAGER_DBUS_PATH GSM_DBUS_PATH
+#define GSM_MANAGER_DBUS_NAME "org.gnome.DisplayManager"
+
+#define GSM_MANAGER_PHASE_TIMEOUT 10 /* seconds */
+
+#define GSM_GCONF_DEFAULT_SESSION_KEY "/desktop/gnome/session/default-session"
+#define GSM_GCONF_REQUIRED_COMPONENTS_DIRECTORY "/desktop/gnome/session/required-components"
+
+
+struct GsmManagerPrivate
+{
+ gboolean failsafe;
+ GsmClientStore *store;
+
+ /* Startup/resumed apps */
+ GSList *apps;
+ GHashTable *apps_by_name;
+
+ /* Current status */
+ char *name;
+ GsmManagerPhase phase;
+ guint timeout_id;
+ GSList *pending_apps;
+
+ /* SM clients */
+ GSList *clients;
+
+ /* When shutdown starts, all clients are put into shutdown_clients.
+ * If they request phase2, they are moved from shutdown_clients to
+ * phase2_clients. If they request interaction, they are appended
+ * to interact_clients (the first client in interact_clients is
+ * the one currently interacting). If they report that they're done,
+ * they're removed from shutdown_clients/phase2_clients.
+ *
+ * Once shutdown_clients is empty, phase2 starts. Once phase2_clients
+ * is empty, shutdown is complete.
+ */
+ GSList *shutdown_clients;
+ GSList *interact_clients;
+ GSList *phase2_clients;
+
+ /* List of clients which were disconnected due to disabled condition
+ * and shouldn't be automatically restarted */
+ GSList *condition_clients;
+
+ int logout_response_id;
+
+ DBusGProxy *bus_proxy;
+ DBusGConnection *connection;
+};
+
+enum {
+ PROP_0,
+ PROP_CLIENT_STORE,
+ PROP_FAILSAFE,
+};
+
+enum {
+ PHASE_CHANGED,
+ SESSION_RUNNING,
+ SESSION_OVER,
+ CLIENT_ADDED,
+ CLIENT_REMOVED,
+ LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0, };
+
+static void gsm_manager_class_init (GsmManagerClass *klass);
+static void gsm_manager_init (GsmManager *manager);
+static void gsm_manager_finalize (GObject *object);
+
+static gpointer manager_object = NULL;
+
+G_DEFINE_TYPE (GsmManager, gsm_manager, G_TYPE_OBJECT)
+
+GQuark
+gsm_manager_error_quark (void)
+{
+ static GQuark ret = 0;
+ if (ret == 0) {
+ ret = g_quark_from_static_string ("gsm_manager_error");
+ }
+
+ return ret;
+}
+
+static void
+app_condition_changed (GsmApp *app,
+ gboolean condition,
+ GsmManager *manager)
+{
+ GsmClient *client;
+ GSList *cl;
+
+ client = NULL;
+
+ /* Check for an existing session client for this app */
+ for (cl = manager->priv->clients; cl; cl = cl->next) {
+ GsmClient *c = GSM_CLIENT (cl->data);
+
+ if (!strcmp (app->client_id, gsm_client_get_id (c))) {
+ client = c;
+ }
+ }
+
+ if (condition) {
+ GError *error = NULL;
+
+ if (app->pid <= 0 && client == NULL) {
+ gsm_app_launch (app, &error);
+ }
+
+ if (error != NULL) {
+ g_warning ("Not able to launch autostart app from its condition: %s",
+ error->message);
+
+ g_error_free (error);
+ }
+ } else {
+ /* Kill client in case condition if false and make sure it won't
+ * be automatically restarted by adding the client to
+ * condition_clients */
+ manager->priv->condition_clients = g_slist_prepend (manager->priv->condition_clients, client);
+ gsm_client_die (client);
+ app->pid = -1;
+ }
+}
+
+static void start_phase (GsmManager *manager);
+
+static void
+end_phase (GsmManager *manager)
+{
+ g_slist_free (manager->priv->pending_apps);
+ manager->priv->pending_apps = NULL;
+
+ g_debug ("ending phase %d\n", manager->priv->phase);
+
+ manager->priv->phase++;
+
+ if (manager->priv->phase < GSM_MANAGER_PHASE_RUNNING) {
+ start_phase (manager);
+ }
+
+ if (manager->priv->phase == GSM_MANAGER_PHASE_RUNNING) {
+ g_signal_emit (manager, signals[SESSION_RUNNING], 0);
+ }
+}
+
+static void
+app_registered (GsmApp *app,
+ GsmManager *manager)
+{
+ manager->priv->pending_apps = g_slist_remove (manager->priv->pending_apps, app);
+ g_signal_handlers_disconnect_by_func (app, app_registered, manager);
+
+ if (manager->priv->pending_apps == NULL) {
+ if (manager->priv->timeout_id > 0) {
+ g_source_remove (manager->priv->timeout_id);
+ manager->priv->timeout_id = 0;
+ }
+
+ end_phase (manager);
+ }
+}
+
+static gboolean
+phase_timeout (GsmManager *manager)
+{
+ GSList *a;
+
+ manager->priv->timeout_id = 0;
+
+ for (a = manager->priv->pending_apps; a; a = a->next) {
+ g_warning ("Application '%s' failed to register before timeout",
+ gsm_app_get_basename (a->data));
+ g_signal_handlers_disconnect_by_func (a->data, app_registered, manager);
+ /* FIXME: what if the app was filling in a required slot? */
+ }
+
+ end_phase (manager);
+ return FALSE;
+}
+
+static void
+start_phase (GsmManager *manager)
+{
+ GsmApp *app;
+ GSList *a;
+ GError *err = NULL;
+
+ g_debug ("starting phase %d\n", manager->priv->phase);
+
+ g_slist_free (manager->priv->pending_apps);
+ manager->priv->pending_apps = NULL;
+
+ for (a = manager->priv->apps; a; a = a->next) {
+ app = a->data;
+
+ if (gsm_app_get_phase (app) != manager->priv->phase) {
+ continue;
+ }
+
+ /* Keep track of app autostart condition in order to react
+ * accordingly in the future. */
+ g_signal_connect (app,
+ "condition-changed",
+ G_CALLBACK (app_condition_changed),
+ manager);
+
+ if (gsm_app_is_disabled (app)) {
+ continue;
+ }
+
+ if (gsm_app_launch (app, &err) > 0) {
+ if (manager->priv->phase == GSM_MANAGER_PHASE_INITIALIZATION) {
+ /* Applications from Initialization phase are considered
+ * registered when they exit normally. This is because
+ * they are expected to just do "something" and exit */
+ g_signal_connect (app,
+ "exited",
+ G_CALLBACK (app_registered),
+ manager);
+ }
+
+ if (manager->priv->phase < GSM_MANAGER_PHASE_APPLICATION) {
+ g_signal_connect (app,
+ "registered",
+ G_CALLBACK (app_registered),
+ manager);
+
+ manager->priv->pending_apps = g_slist_prepend (manager->priv->pending_apps, app);
+ }
+ } else if (err != NULL) {
+ g_warning ("Could not launch application '%s': %s",
+ gsm_app_get_basename (app),
+ err->message);
+ g_error_free (err);
+ err = NULL;
+ }
+ }
+
+ if (manager->priv->pending_apps != NULL) {
+ if (manager->priv->phase < GSM_MANAGER_PHASE_APPLICATION) {
+ manager->priv->timeout_id = g_timeout_add_seconds (GSM_MANAGER_PHASE_TIMEOUT,
+ (GSourceFunc)phase_timeout,
+ manager);
+ }
+ } else {
+ end_phase (manager);
+ }
+}
+
+void
+gsm_manager_start (GsmManager *manager)
+{
+ g_debug ("GsmManager: GSM starting to manage");
+
+ manager->priv->phase = GSM_MANAGER_PHASE_INITIALIZATION;
+
+ start_phase (manager);
+}
+
+typedef struct {
+ const char *service_name;
+ GsmManager *manager;
+} RemoveClientData;
+
+static gboolean
+remove_client_for_connection (char *id,
+ GsmClient *client,
+ RemoveClientData *data)
+{
+ g_assert (client != NULL);
+ g_assert (data->service_name != NULL);
+
+ /* FIXME: compare service name to that of client */
+#if 0
+ if (strcmp (info->service_name, data->service_name) == 0) {
+
+ return TRUE;
+ }
+#endif
+
+ return FALSE;
+}
+
+static void
+remove_clients_for_connection (GsmManager *manager,
+ const char *service_name)
+{
+ RemoveClientData data;
+
+ data.service_name = service_name;
+ data.manager = manager;
+
+ /* FIXME */
+}
+
+static void
+bus_name_owner_changed (DBusGProxy *bus_proxy,
+ const char *service_name,
+ const char *old_service_name,
+ const char *new_service_name,
+ GsmManager *manager)
+{
+ if (strlen (new_service_name) == 0) {
+ remove_clients_for_connection (manager, old_service_name);
+ }
+}
+
+static gboolean
+register_manager (GsmManager *manager)
+{
+ GError *error = NULL;
+
+ error = NULL;
+ manager->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (manager->priv->connection == NULL) {
+ if (error != NULL) {
+ g_critical ("error getting system bus: %s", error->message);
+ g_error_free (error);
+ }
+ exit (1);
+ }
+
+ manager->priv->bus_proxy = dbus_g_proxy_new_for_name (manager->priv->connection,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS);
+ dbus_g_proxy_add_signal (manager->priv->bus_proxy,
+ "NameOwnerChanged",
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (manager->priv->bus_proxy,
+ "NameOwnerChanged",
+ G_CALLBACK (bus_name_owner_changed),
+ manager,
+ NULL);
+
+ dbus_g_connection_register_g_object (manager->priv->connection, GSM_MANAGER_DBUS_PATH, G_OBJECT (manager));
+
+ return TRUE;
+}
+
+static void
+gsm_manager_set_failsafe (GsmManager *manager,
+ gboolean enabled)
+{
+ g_return_if_fail (GSM_IS_MANAGER (manager));
+
+ manager->priv->failsafe = enabled;
+}
+
+static void
+gsm_manager_set_client_store (GsmManager *manager,
+ GsmClientStore *store)
+{
+ g_return_if_fail (GSM_IS_MANAGER (manager));
+
+ if (store != NULL) {
+ g_object_ref (store);
+ }
+
+ if (manager->priv->store != NULL) {
+ g_object_unref (manager->priv->store);
+ }
+
+ manager->priv->store = store;
+}
+
+static void
+gsm_manager_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GsmManager *self;
+
+ self = GSM_MANAGER (object);
+
+ switch (prop_id) {
+ case PROP_FAILSAFE:
+ gsm_manager_set_failsafe (self, g_value_get_boolean (value));
+ break;
+ case PROP_CLIENT_STORE:
+ gsm_manager_set_client_store (self, g_value_get_object (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gsm_manager_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GsmManager *self;
+
+ self = GSM_MANAGER (object);
+
+ switch (prop_id) {
+ case PROP_FAILSAFE:
+ g_value_set_boolean (value, self->priv->failsafe);
+ break;
+ case PROP_CLIENT_STORE:
+ g_value_set_object (value, self->priv->store);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+append_app (GsmManager *manager,
+ GsmApp *app)
+{
+ const char *basename;
+ GsmApp *dup;
+
+ basename = gsm_app_get_basename (app);
+ if (basename == NULL) {
+ g_object_unref (app);
+ return;
+ }
+
+ dup = g_hash_table_lookup (manager->priv->apps_by_name, basename);
+ if (dup != NULL) {
+ /* FIXME */
+ g_object_unref (app);
+ return;
+ }
+
+ manager->priv->apps = g_slist_append (manager->priv->apps, app);
+ g_hash_table_insert (manager->priv->apps_by_name, g_strdup (basename), app);
+}
+
+static void
+append_default_apps (GsmManager *manager,
+ char **autostart_dirs)
+{
+ GSList *default_apps;
+ GSList *a;
+ char **app_dirs;
+ GConfClient *client;
+
+ g_debug ("append_default_apps ()");
+
+ app_dirs = gsm_util_get_app_dirs ();
+
+ client = gconf_client_get_default ();
+ default_apps = gconf_client_get_list (client,
+ GSM_GCONF_DEFAULT_SESSION_KEY,
+ GCONF_VALUE_STRING,
+ NULL);
+ g_object_unref (client);
+
+ for (a = default_apps; a; a = a->next) {
+ GKeyFile *key_file;
+ char *app_path = NULL;
+ char *desktop_file;
+
+ key_file = g_key_file_new ();
+
+ if (a->data == NULL) {
+ continue;
+ }
+
+ desktop_file = g_strdup_printf ("%s.desktop", (char *) a->data);
+
+ g_debug ("Look for: %s", desktop_file);
+
+ g_key_file_load_from_dirs (key_file,
+ desktop_file,
+ (const gchar**) app_dirs,
+ &app_path,
+ G_KEY_FILE_NONE,
+ NULL);
+
+ if (app_path == NULL) {
+ g_key_file_load_from_dirs (key_file,
+ desktop_file,
+ (const gchar**) autostart_dirs,
+ &app_path,
+ G_KEY_FILE_NONE,
+ NULL);
+ }
+
+ if (app_path != NULL) {
+ GsmApp *app;
+ char *client_id;
+
+ g_debug ("Found in: %s", app_path);
+
+ client_id = gsm_util_generate_client_id ();
+ app = gsm_autostart_app_new (app_path, client_id);
+ g_free (client_id);
+ g_free (app_path);
+
+ if (app != NULL) {
+ g_debug ("read %s\n", desktop_file);
+ append_app (manager, app);
+ } else {
+ g_warning ("could not read %s\n", desktop_file);
+ }
+ }
+
+ g_free (desktop_file);
+ g_key_file_free (key_file);
+ }
+
+ g_slist_foreach (default_apps, (GFunc) g_free, NULL);
+ g_slist_free (default_apps);
+ g_strfreev (app_dirs);
+}
+
+static void
+append_autostart_apps (GsmManager *manager,
+ const char *path)
+{
+ GDir *dir;
+ const char *name;
+
+ g_debug ("append_autostart_apps (%s)", path);
+
+ dir = g_dir_open (path, 0, NULL);
+ if (dir == NULL) {
+ return;
+ }
+
+ while ((name = g_dir_read_name (dir))) {
+ GsmApp *app;
+ char *desktop_file;
+ char *client_id;
+
+ if (!g_str_has_suffix (name, ".desktop")) {
+ continue;
+ }
+
+ desktop_file = g_build_filename (path, name, NULL);
+
+ client_id = gsm_util_generate_client_id ();
+ app = gsm_autostart_app_new (desktop_file, client_id);
+ if (app != NULL) {
+ g_debug ("read %s\n", desktop_file);
+ append_app (manager, app);
+ } else {
+ g_warning ("could not read %s\n", desktop_file);
+ }
+
+ g_free (desktop_file);
+ g_free (client_id);
+ }
+
+ g_dir_close (dir);
+}
+
+/* FIXME: need to make sure this only happens once */
+static void
+append_legacy_session_apps (GsmManager *manager,
+ const char *session_filename)
+{
+ GKeyFile *saved;
+ int num_clients, i;
+
+ saved = g_key_file_new ();
+ if (!g_key_file_load_from_file (saved, session_filename, 0, NULL)) {
+ /* FIXME: error handling? */
+ g_key_file_free (saved);
+ return;
+ }
+
+ num_clients = g_key_file_get_integer (saved, "Default", "num_clients", NULL);
+ for (i = 0; i < num_clients; i++) {
+ GsmApp *app = gsm_resumed_app_new_from_legacy_session (saved, i);
+ if (app != NULL) {
+ append_app (manager, app);
+ }
+ }
+
+ g_key_file_free (saved);
+}
+
+static void
+append_saved_session_apps (GsmManager *manager)
+{
+ char *session_filename;
+
+ /* try resuming from the old gnome-session's files */
+ session_filename = g_build_filename (g_get_home_dir (),
+ ".gnome2",
+ "session",
+ NULL);
+ if (g_file_test (session_filename, G_FILE_TEST_EXISTS)) {
+ append_legacy_session_apps (manager, session_filename);
+ g_free (session_filename);
+ return;
+ }
+
+ g_free (session_filename);
+}
+
+static void
+append_required_apps (GsmManager *manager)
+{
+ GSList *required_components;
+ GSList *r;
+ GsmApp *app;
+ gboolean found;
+ GConfClient *client;
+
+ client = gconf_client_get_default ();
+ required_components = gconf_client_all_entries (client,
+ GSM_GCONF_REQUIRED_COMPONENTS_DIRECTORY,
+ NULL);
+ g_object_unref (client);
+
+ for (r = required_components; r; r = r->next) {
+ GSList *a;
+ GConfEntry *entry;
+ const char *default_provider;
+ const char *service;
+
+ entry = (GConfEntry *) r->data;
+
+ service = strrchr (entry->key, '/');
+ if (service == NULL) {
+ continue;
+ }
+ service++;
+
+ default_provider = gconf_value_get_string (entry->value);
+ if (default_provider == NULL) {
+ continue;
+ }
+
+ for (a = manager->priv->apps, found = FALSE; a; a = a->next) {
+ app = a->data;
+
+ if (gsm_app_provides (app, service)) {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (!found) {
+ char *client_id;
+
+ client_id = gsm_util_generate_client_id ();
+ app = gsm_autostart_app_new (default_provider, client_id);
+ g_free (client_id);
+ if (app)
+ append_app (manager, app);
+ /* FIXME: else error */
+ }
+
+ gconf_entry_free (entry);
+ }
+
+ g_slist_free (required_components);
+}
+
+static void
+load_apps (GsmManager *manager)
+{
+ char **autostart_dirs;
+ int i;
+
+ autostart_dirs = gsm_util_get_autostart_dirs ();
+
+ append_default_apps (manager, autostart_dirs);
+
+ if (manager->priv->failsafe) {
+ goto out;
+ }
+
+ for (i = 0; autostart_dirs[i]; i++) {
+ append_autostart_apps (manager, autostart_dirs[i]);
+ }
+
+ append_saved_session_apps (manager);
+
+ /* We don't do this in the failsafe case, because the default
+ * session should include all requirements anyway. */
+ append_required_apps (manager);
+
+ out:
+ g_strfreev (autostart_dirs);
+}
+
+static GObject *
+gsm_manager_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
+{
+ GsmManager *manager;
+
+ manager = GSM_MANAGER (G_OBJECT_CLASS (gsm_manager_parent_class)->constructor (type,
+ n_construct_properties,
+ construct_properties));
+ load_apps (manager);
+
+ return G_OBJECT (manager);
+}
+
+static void
+gsm_manager_class_init (GsmManagerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = gsm_manager_get_property;
+ object_class->set_property = gsm_manager_set_property;
+ object_class->constructor = gsm_manager_constructor;
+ object_class->finalize = gsm_manager_finalize;
+
+ signals [PHASE_CHANGED] =
+ g_signal_new ("phase-changed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsmManagerClass, phase_changed),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1, G_TYPE_STRING);
+
+ signals [SESSION_RUNNING] =
+ g_signal_new ("session-running",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsmManagerClass, session_running),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ signals [SESSION_OVER] =
+ g_signal_new ("session-over",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsmManagerClass, session_over),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ signals [CLIENT_ADDED] =
+ g_signal_new ("client-added",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsmManagerClass, client_added),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1, G_TYPE_STRING);
+ signals [CLIENT_REMOVED] =
+ g_signal_new ("client-removed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsmManagerClass, client_removed),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1, G_TYPE_STRING);
+
+ g_object_class_install_property (object_class,
+ PROP_FAILSAFE,
+ g_param_spec_boolean ("failsafe",
+ NULL,
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+ g_object_class_install_property (object_class,
+ PROP_FAILSAFE,
+ g_param_spec_object ("client-store",
+ NULL,
+ NULL,
+ GSM_TYPE_CLIENT_STORE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ g_type_class_add_private (klass, sizeof (GsmManagerPrivate));
+
+ dbus_g_object_type_install_info (GSM_TYPE_MANAGER, &dbus_glib_gsm_manager_object_info);
+}
+
+static void
+gsm_manager_init (GsmManager *manager)
+{
+
+ manager->priv = GSM_MANAGER_GET_PRIVATE (manager);
+
+ manager->priv->apps_by_name = g_hash_table_new (g_str_hash, g_str_equal);
+
+ manager->priv->logout_response_id = GTK_RESPONSE_NONE;
+}
+
+static void
+gsm_manager_finalize (GObject *object)
+{
+ GsmManager *manager;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GSM_IS_MANAGER (object));
+
+ manager = GSM_MANAGER (object);
+
+ g_return_if_fail (manager->priv != NULL);
+
+ if (manager->priv->store != NULL) {
+ g_object_unref (manager->priv->store);
+ }
+
+ /* FIXME */
+
+ G_OBJECT_CLASS (gsm_manager_parent_class)->finalize (object);
+}
+
+GsmManager *
+gsm_manager_new (GsmClientStore *store,
+ gboolean failsafe)
+{
+ if (manager_object != NULL) {
+ g_object_ref (manager_object);
+ } else {
+ gboolean res;
+
+ manager_object = g_object_new (GSM_TYPE_MANAGER,
+ "client-store", store,
+ "failsafe", failsafe,
+ NULL);
+
+ g_object_add_weak_pointer (manager_object,
+ (gpointer *) &manager_object);
+ res = register_manager (manager_object);
+ if (! res) {
+ g_object_unref (manager_object);
+ return NULL;
+ }
+ }
+
+ return GSM_MANAGER (manager_object);
+}
+
+gboolean
+gsm_manager_setenv (GsmManager *manager,
+ const char *variable,
+ const char *value,
+ GError **error)
+{
+ if (manager->priv->phase > GSM_MANAGER_PHASE_INITIALIZATION) {
+ g_set_error (error,
+ GSM_MANAGER_ERROR,
+ GSM_MANAGER_ERROR_NOT_IN_INITIALIZATION,
+ "Setenv interface is only available during the Initialization phase");
+ return FALSE;
+ }
+
+ g_setenv (variable, value, TRUE);
+
+ return TRUE;
+}
+
+gboolean
+gsm_manager_initialization_error (GsmManager *manager,
+ const char *message,
+ gboolean fatal,
+ GError **error)
+{
+ if (manager->priv->phase > GSM_MANAGER_PHASE_INITIALIZATION) {
+ g_set_error (error,
+ GSM_MANAGER_ERROR,
+ GSM_MANAGER_ERROR_NOT_IN_INITIALIZATION,
+ "InitializationError interface is only available during the Initialization phase");
+ return FALSE;
+ }
+
+ gsm_util_init_error (fatal, "%s", message);
+
+ return TRUE;
+}
+
+static void
+manager_shutdown (GsmManager *manager)
+{
+ GSList *cl;
+
+ /* Emit session over signal */
+ g_signal_emit (manager, signals[SESSION_OVER], 0);
+
+ /* FIXME: do this in reverse phase order */
+ for (cl = manager->priv->clients; cl; cl = cl->next) {
+ gsm_client_die (cl->data);
+ }
+
+ switch (manager->priv->logout_response_id) {
+ case GSM_LOGOUT_RESPONSE_SHUTDOWN:
+ gdm_set_logout_action (GDM_LOGOUT_ACTION_SHUTDOWN);
+ break;
+ case GSM_LOGOUT_RESPONSE_REBOOT:
+ gdm_set_logout_action (GDM_LOGOUT_ACTION_REBOOT);
+ break;
+ default:
+ gtk_main_quit ();
+ break;
+ }
+}
+
+static void
+initiate_shutdown (GsmManager *manager)
+{
+ GSList *cl;
+
+ manager->priv->phase = GSM_MANAGER_PHASE_SHUTDOWN;
+
+ if (manager->priv->clients == NULL) {
+ manager_shutdown (manager);
+ }
+
+ for (cl = manager->priv->clients; cl; cl = cl->next) {
+ GsmClient *client = GSM_CLIENT (cl->data);
+
+ manager->priv->shutdown_clients = g_slist_prepend (manager->priv->shutdown_clients, client);
+
+ gsm_client_save_yourself (client, FALSE);
+ }
+}
+
+static void
+logout_dialog_response (GsmLogoutDialog *logout_dialog,
+ guint response_id,
+ GsmManager *manager)
+{
+ GsmPowerManager *power_manager;
+
+ gtk_widget_destroy (GTK_WIDGET (logout_dialog));
+
+ /* In case of dialog cancel, switch user, hibernate and suspend, we just
+ * perform the respective action and return, without shutting down the
+ * session. */
+ switch (response_id) {
+ case GTK_RESPONSE_CANCEL:
+ case GTK_RESPONSE_NONE:
+ case GTK_RESPONSE_DELETE_EVENT:
+ return;
+
+ case GSM_LOGOUT_RESPONSE_SWITCH_USER:
+ gdm_new_login ();
+ return;
+
+ case GSM_LOGOUT_RESPONSE_STD:
+ power_manager = gsm_get_power_manager ();
+
+ if (gsm_power_manager_can_hibernate (power_manager)) {
+ gsm_power_manager_attempt_hibernate (power_manager);
+ }
+
+ g_object_unref (power_manager);
+
+ return;
+
+ case GSM_LOGOUT_RESPONSE_STR:
+ power_manager = gsm_get_power_manager ();
+
+ if (gsm_power_manager_can_suspend (power_manager)) {
+ gsm_power_manager_attempt_suspend (power_manager);
+ }
+
+ g_object_unref (power_manager);
+
+ return;
+
+ default:
+ break;
+ }
+
+ manager->priv->logout_response_id = response_id;
+
+ initiate_shutdown (manager);
+}
+
+static void
+gsm_manager_initiate_shutdown (GsmManager *manager,
+ gboolean show_confirmation,
+ GsmManagerLogoutType logout_type)
+{
+ gboolean logout_prompt;
+ GConfClient *client;
+
+ if (manager->priv->phase == GSM_MANAGER_PHASE_SHUTDOWN) {
+ /* Already shutting down, nothing more to do */
+ return;
+ }
+
+ client = gconf_client_get_default ();
+ logout_prompt = gconf_client_get_bool (client,
+ "/apps/gnome-session/options/logout_prompt",
+ NULL);
+ g_object_unref (client);
+
+ /* Global settings overides input parameter in order to disable confirmation
+ * dialog accordingly. If we're shutting down, we always show the confirmation
+ * dialog */
+ logout_prompt = (logout_prompt && show_confirmation) ||
+ (logout_type == GSM_MANAGER_LOGOUT_TYPE_SHUTDOWN);
+
+ if (logout_prompt) {
+ GtkWidget *logout_dialog;
+
+ logout_dialog = gsm_get_logout_dialog (logout_type,
+ gdk_screen_get_default (),
+ gtk_get_current_event_time ());
+
+ g_signal_connect (G_OBJECT (logout_dialog),
+ "response",
+ G_CALLBACK (logout_dialog_response),
+ manager);
+
+ gtk_widget_show (logout_dialog);
+
+ return;
+ }
+
+ initiate_shutdown (manager);
+}
+
+gboolean
+gsm_manager_shutdown (GsmManager *manager,
+ GError **error)
+{
+ if (manager->priv->phase != GSM_MANAGER_PHASE_RUNNING) {
+ g_set_error (error,
+ GSM_MANAGER_ERROR,
+ GSM_MANAGER_ERROR_NOT_IN_RUNNING,
+ "Logout interface is only available during the Running phase");
+ return FALSE;
+ }
+
+ gsm_manager_initiate_shutdown (manager,
+ TRUE,
+ GSM_MANAGER_LOGOUT_TYPE_SHUTDOWN);
+
+ return TRUE;
+}
+
+gboolean
+gsm_manager_logout (GsmManager *manager,
+ gint logout_mode,
+ GError **error)
+{
+ if (manager->priv->phase != GSM_MANAGER_PHASE_RUNNING) {
+ g_set_error (error,
+ GSM_MANAGER_ERROR,
+ GSM_MANAGER_ERROR_NOT_IN_RUNNING,
+ "Shutdown interface is only available during the Running phase");
+ return FALSE;
+ }
+
+ switch (logout_mode) {
+ case GSM_MANAGER_LOGOUT_MODE_NORMAL:
+ gsm_manager_initiate_shutdown (manager, TRUE, GSM_MANAGER_LOGOUT_TYPE_LOGOUT);
+ break;
+
+ case GSM_MANAGER_LOGOUT_MODE_NO_CONFIRMATION:
+ gsm_manager_initiate_shutdown (manager, FALSE, GSM_MANAGER_LOGOUT_TYPE_LOGOUT);
+ break;
+
+ case GSM_MANAGER_LOGOUT_MODE_FORCE:
+ /* FIXME: Implement when session state saving is ready */
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ return TRUE;
+}
+
+static void
+manager_set_name (GsmManager *manager,
+ const char *name)
+{
+ g_free (manager->priv->name);
+ manager->priv->name = g_strdup (name);
+}
+
+gboolean
+gsm_manager_set_name (GsmManager *manager,
+ const char *session_name,
+ GError **error)
+{
+ if (manager->priv->phase != GSM_MANAGER_PHASE_RUNNING) {
+ g_set_error (error,
+ GSM_MANAGER_ERROR,
+ GSM_MANAGER_ERROR_NOT_IN_RUNNING,
+ "SetName interface is only available during the Running phase");
+ return FALSE;
+ }
+
+ manager_set_name (manager, session_name);
+
+ return TRUE;
+}
Added: branches/dbus_based/gnome-session/gsm-manager.h
==============================================================================
--- (empty file)
+++ branches/dbus_based/gnome-session/gsm-manager.h Wed Jun 11 19:10:15 2008
@@ -0,0 +1,128 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 William Jon McCann <jmccann redhat com>
+ *
+ * This program 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.
+ *
+ * This program 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 __GSM_MANAGER_H
+#define __GSM_MANAGER_H
+
+#include <glib-object.h>
+
+#include "gsm-client-store.h"
+
+G_BEGIN_DECLS
+
+#define GSM_TYPE_MANAGER (gsm_manager_get_type ())
+#define GSM_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSM_TYPE_MANAGER, GsmManager))
+#define GSM_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSM_TYPE_MANAGER, GsmManagerClass))
+#define GSM_IS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSM_TYPE_MANAGER))
+#define GSM_IS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSM_TYPE_MANAGER))
+#define GSM_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSM_TYPE_MANAGER, GsmManagerClass))
+
+typedef struct GsmManagerPrivate GsmManagerPrivate;
+
+typedef struct
+{
+ GObject parent;
+ GsmManagerPrivate *priv;
+} GsmManager;
+
+typedef struct
+{
+ GObjectClass parent_class;
+
+ void (* session_running) (GsmManager *manager);
+ void (* session_over) (GsmManager *manager);
+
+ void (* phase_changed) (GsmManager *manager,
+ const char *phase);
+
+ void (* client_added) (GsmManager *manager,
+ const char *id);
+ void (* client_removed) (GsmManager *manager,
+ const char *id);
+} GsmManagerClass;
+
+typedef enum {
+ /* gsm's own startup/initialization phase */
+ GSM_MANAGER_PHASE_STARTUP,
+ /* xrandr setup, gnome-settings-daemon, etc */
+ GSM_MANAGER_PHASE_INITIALIZATION,
+ /* window/compositing managers */
+ GSM_MANAGER_PHASE_WINDOW_MANAGER,
+ /* apps that will create _NET_WM_WINDOW_TYPE_PANEL windows */
+ GSM_MANAGER_PHASE_PANEL,
+ /* apps that will create _NET_WM_WINDOW_TYPE_DESKTOP windows */
+ GSM_MANAGER_PHASE_DESKTOP,
+ /* everything else */
+ GSM_MANAGER_PHASE_APPLICATION,
+ /* done launching */
+ GSM_MANAGER_PHASE_RUNNING,
+ /* shutting down */
+ GSM_MANAGER_PHASE_SHUTDOWN
+} GsmManagerPhase;
+
+typedef enum
+{
+ GSM_MANAGER_ERROR_GENERAL,
+ GSM_MANAGER_ERROR_NOT_IN_INITIALIZATION,
+ GSM_MANAGER_ERROR_NOT_IN_RUNNING,
+} GsmManagerError;
+
+#define GSM_MANAGER_ERROR gsm_manager_error_quark ()
+
+typedef enum {
+ GSM_MANAGER_LOGOUT_TYPE_LOGOUT,
+ GSM_MANAGER_LOGOUT_TYPE_SHUTDOWN
+} GsmManagerLogoutType;
+
+typedef enum {
+ GSM_MANAGER_LOGOUT_MODE_NORMAL,
+ GSM_MANAGER_LOGOUT_MODE_NO_CONFIRMATION,
+ GSM_MANAGER_LOGOUT_MODE_FORCE
+} GsmManagerLogoutMode;
+
+GQuark gsm_manager_error_quark (void);
+GType gsm_manager_get_type (void);
+
+GsmManager * gsm_manager_new (GsmClientStore *store,
+ gboolean failsafe);
+
+void gsm_manager_start (GsmManager *manager);
+
+gboolean gsm_manager_setenv (GsmManager *manager,
+ const char *variable,
+ const char *value,
+ GError **error);
+gboolean gsm_manager_initialization_error (GsmManager *manager,
+ const char *message,
+ gboolean fatal,
+ GError **error);
+gboolean gsm_manager_shutdown (GsmManager *manager,
+ GError **error);
+gboolean gsm_manager_logout (GsmManager *manager,
+ int logout_mode,
+ GError **error);
+gboolean gsm_manager_set_name (GsmManager *manager,
+ const char *session_name,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* __GSM_MANAGER_H */
Added: branches/dbus_based/gnome-session/gsm-marshal.list
==============================================================================
--- (empty file)
+++ branches/dbus_based/gnome-session/gsm-marshal.list Wed Jun 11 19:10:15 2008
@@ -0,0 +1 @@
+STRING:STRING
Copied: branches/dbus_based/gnome-session/gsm-resumed-app.c (from r4726, /trunk/gnome-session/app-resumed.c)
==============================================================================
--- /trunk/gnome-session/app-resumed.c (original)
+++ branches/dbus_based/gnome-session/gsm-resumed-app.c Wed Jun 11 19:10:15 2008
@@ -1,4 +1,5 @@
-/* app-resumed.c
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
* Copyright (C) 2007 Novell, Inc.
*
* This program is free software; you can redistribute it and/or
@@ -23,30 +24,30 @@
#include <X11/SM/SMlib.h>
-#include "app-resumed.h"
+#include "gsm-resumed-app.h"
static const char *get_basename (GsmApp *app);
static pid_t launch (GsmApp *app, GError **error);
-G_DEFINE_TYPE (GsmAppResumed, gsm_app_resumed, GSM_TYPE_APP)
+G_DEFINE_TYPE (GsmResumedApp, gsm_resumed_app, GSM_TYPE_APP)
static void
-gsm_app_resumed_init (GsmAppResumed *app)
+gsm_resumed_app_init (GsmResumedApp *app)
{
- ;
+ ;
}
static void
-gsm_app_resumed_class_init (GsmAppResumedClass *klass)
+gsm_resumed_app_class_init (GsmResumedAppClass *klass)
{
- GsmAppClass *app_class = GSM_APP_CLASS (klass);
+ GsmAppClass *app_class = GSM_APP_CLASS (klass);
- app_class->get_basename = get_basename;
- app_class->launch = launch;
+ app_class->get_basename = get_basename;
+ app_class->launch = launch;
}
/**
- * gsm_app_resumed_new_from_legacy_session:
+ * gsm_resumed_app_new_from_legacy_session:
* @session_file: a session file (eg, ~/.gnome2/session) from the old
* gnome-session
* @n: the number of the client in @session_file to read
@@ -58,52 +59,53 @@
* @session_file is not actually a saved XSMP client.
**/
GsmApp *
-gsm_app_resumed_new_from_legacy_session (GKeyFile *session_file, int n)
+gsm_resumed_app_new_from_legacy_session (GKeyFile *session_file, int n)
{
- GsmAppResumed *app;
- char *key, *id, *val;
+ GsmResumedApp *app;
+ char *key, *id, *val;
- key = g_strdup_printf ("%d,id", n);
- id = g_key_file_get_string (session_file, "Default", key, NULL);
- g_free (key);
-
- if (!id)
- {
- /* Not actually a saved app, just a redundantly-specified
- * autostart app; ignore.
- */
- return NULL;
- }
-
- app = g_object_new (GSM_TYPE_APP_RESUMED,
- "client-id", id,
- NULL);
-
- key = g_strdup_printf ("%d," SmProgram, n);
- val = g_key_file_get_string (session_file, "Default", key, NULL);
- g_free (key);
-
- if (val)
- app->program = val;
-
- key = g_strdup_printf ("%d," SmRestartCommand, n);
- val = g_key_file_get_string (session_file, "Default", key, NULL);
- g_free (key);
-
- if (val)
- app->restart_command = val;
-
- /* We ignore the discard_command on apps resumed from the legacy
- * session, so that the legacy session will still work if the user
- * reverts back to the old gnome-session.
- */
- app->discard_on_resume = FALSE;
+ key = g_strdup_printf ("%d,id", n);
+ id = g_key_file_get_string (session_file, "Default", key, NULL);
+ g_free (key);
+
+ if (!id) {
+ /* Not actually a saved app, just a redundantly-specified
+ * autostart app; ignore.
+ */
+ return NULL;
+ }
+
+ app = g_object_new (GSM_TYPE_RESUMED_APP,
+ "client-id", id,
+ NULL);
+
+ key = g_strdup_printf ("%d," SmProgram, n);
+ val = g_key_file_get_string (session_file, "Default", key, NULL);
+ g_free (key);
+
+ if (val) {
+ app->program = val;
+ }
+
+ key = g_strdup_printf ("%d," SmRestartCommand, n);
+ val = g_key_file_get_string (session_file, "Default", key, NULL);
+ g_free (key);
+
+ if (val) {
+ app->restart_command = val;
+ }
+
+ /* We ignore the discard_command on apps resumed from the legacy
+ * session, so that the legacy session will still work if the user
+ * reverts back to the old gnome-session.
+ */
+ app->discard_on_resume = FALSE;
- return (GsmApp *) app;
+ return (GsmApp *) app;
}
/**
- * gsm_app_resumed_new_from_session:
+ * gsm_resumed_app_new_from_session:
* @session_file: a session file
* @group: the group containing the client to read
* @discard: whether or not the app's state should be discarded after
@@ -116,87 +118,88 @@
**/
#if 0
GsmApp *
-gsm_app_resumed_new_from_session (GKeyFile *session_file, const char *group,
- gboolean discard)
+gsm_resumed_app_new_from_session (GKeyFile *session_file, const char *group,
+ gboolean discard)
{
- GsmAppResumed *app;
- char *desktop_file, *client_id, *val;
+ GsmResumedApp *app;
+ char *desktop_file, *client_id, *val;
- desktop_file = g_key_file_get_string (session_file, group,
- "_GSM_DesktopFile", NULL);
- client_id = g_key_file_get_string (session_file, group, "id", NULL);
-
- app = g_object_new (GSM_TYPE_APP_RESUMED,
- "desktop-file", desktop_file,
- "client-id", client_id,
- NULL);
- g_free (desktop_file);
- g_free (client_id);
-
- /* Replace Exec key with RestartCommand */
- val = g_key_file_get_string (session_file, group,
- SmRestartCommand, NULL);
- gsm_app_set_exec (app, val);
- g_free (val);
-
- /* Use Program for the name if there's no localized name */
- if (!gsm_app_get_name (app))
- {
- val = g_key_file_get_string (session_file, group,
- SmProgram, NULL);
- gsm_app_set_name (app, val);
- g_free (val);
- }
-
- app->discard_command = g_key_file_get_string (session_file, group,
- SmDiscardCommand, NULL);
- app->discard_on_resume = discard;
-
- /* FIXME: if discard_on_resume is set, then the app needs to find
- * out if it has been matched up with a GsmClient, so it can run its
- * discard command later. (It can't actually run the discard command
- * right away when the client connects, because the client might not
- * have actually read in its old state at that point. So it's
- * probably best to not run the discard command until after the
- * client quits.
- */
- return (GsmApp *)app;
+ desktop_file = g_key_file_get_string (session_file, group,
+ "_GSM_DesktopFile", NULL);
+ client_id = g_key_file_get_string (session_file, group, "id", NULL);
+
+ app = g_object_new (GSM_TYPE_RESUMED_APP,
+ "desktop-file", desktop_file,
+ "client-id", client_id,
+ NULL);
+ g_free (desktop_file);
+ g_free (client_id);
+
+ /* Replace Exec key with RestartCommand */
+ val = g_key_file_get_string (session_file, group,
+ SmRestartCommand, NULL);
+ gsm_app_set_exec (app, val);
+ g_free (val);
+
+ /* Use Program for the name if there's no localized name */
+ if (!gsm_app_get_name (app)) {
+ val = g_key_file_get_string (session_file, group,
+ SmProgram, NULL);
+ gsm_app_set_name (app, val);
+ g_free (val);
+ }
+
+ app->discard_command = g_key_file_get_string (session_file, group,
+ SmDiscardCommand, NULL);
+ app->discard_on_resume = discard;
+
+ /* FIXME: if discard_on_resume is set, then the app needs to find
+ * out if it has been matched up with a GsmClient, so it can run its
+ * discard command later. (It can't actually run the discard command
+ * right away when the client connects, because the client might not
+ * have actually read in its old state at that point. So it's
+ * probably best to not run the discard command until after the
+ * client quits.
+ */
+ return (GsmApp *)app;
}
#endif
static const char *
get_basename (GsmApp *app)
{
- return GSM_APP_RESUMED (app)->program;
+ return GSM_RESUMED_APP (app)->program;
}
static pid_t
launch (GsmApp *app, GError **err)
{
- const char *restart_command = GSM_APP_RESUMED (app)->restart_command;
- int argc;
- char **argv;
- gboolean success;
- pid_t pid;
-
- if (!restart_command)
- return (pid_t)-1;
-
- if (!g_shell_parse_argv (restart_command, &argc, &argv, err))
- return (pid_t)-1;
-
- /* In theory, we should set up the environment according to
- * SmEnvironment, and the current directory according to
- * SmCurrentDirectory. However, ksmserver doesn't support either of
- * those properties, so apps that want to be portable can't depend
- * on them working anyway. Also, no one ever uses them. So we just
- * ignore them.
- */
-
- success = g_spawn_async (NULL, argv, NULL,
- G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
- NULL, NULL, &pid, err);
- g_strfreev (argv);
+ const char *restart_command = GSM_RESUMED_APP (app)->restart_command;
+ int argc;
+ char **argv;
+ gboolean success;
+ pid_t pid;
+
+ if (!restart_command) {
+ return (pid_t)-1;
+ }
+
+ if (!g_shell_parse_argv (restart_command, &argc, &argv, err)) {
+ return (pid_t)-1;
+ }
+
+ /* In theory, we should set up the environment according to
+ * SmEnvironment, and the current directory according to
+ * SmCurrentDirectory. However, ksmserver doesn't support either of
+ * those properties, so apps that want to be portable can't depend
+ * on them working anyway. Also, no one ever uses them. So we just
+ * ignore them.
+ */
+
+ success = g_spawn_async (NULL, argv, NULL,
+ G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
+ NULL, NULL, &pid, err);
+ g_strfreev (argv);
- return success ? pid : (pid_t)-1;
+ return success ? pid : (pid_t)-1;
}
Copied: branches/dbus_based/gnome-session/gsm-resumed-app.h (from r4726, /trunk/gnome-session/app-resumed.h)
==============================================================================
--- /trunk/gnome-session/app-resumed.h (original)
+++ branches/dbus_based/gnome-session/gsm-resumed-app.h Wed Jun 11 19:10:15 2008
@@ -1,54 +1,71 @@
-/* app-sm.h
- * Copyright (C) 2006 Novell, Inc.
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
+ * Copyright (C) 2007 Novell, Inc.
+ *
+ * This program 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.
+ *
+ * This program 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 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 __GSM_APP_RESUMED_H__
-#define __GSM_APP_RESUMED_H__
+#ifndef __GSM_RESUMED_APP_H__
+#define __GSM_RESUMED_APP_H__
-#include "app.h"
+#include "gsm-app.h"
G_BEGIN_DECLS
-#define GSM_TYPE_APP_RESUMED (gsm_app_resumed_get_type ())
-#define GSM_APP_RESUMED(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSM_TYPE_APP_RESUMED, GsmAppResumed))
-#define GSM_APP_RESUMED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSM_TYPE_APP_RESUMED, GsmAppResumedClass))
-#define GSM_IS_APP_RESUMED(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSM_TYPE_APP_RESUMED))
-#define GSM_IS_APP_RESUMED_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSM_TYPE_APP_RESUMED))
-#define GSM_APP_RESUMED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSM_TYPE_APP_RESUMED, GsmAppResumedClass))
-
-typedef struct _GsmAppResumed GsmAppResumed;
-typedef struct _GsmAppResumedClass GsmAppResumedClass;
-typedef struct _GsmAppResumedPrivate GsmAppResumedPrivate;
+#define GSM_TYPE_RESUMED_APP (gsm_resumed_app_get_type ())
+#define GSM_RESUMED_APP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSM_TYPE_RESUMED_APP, GsmResumedApp))
+#define GSM_RESUMED_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSM_TYPE_RESUMED_APP, GsmResumedAppClass))
+#define GSM_IS_RESUMED_APP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSM_TYPE_RESUMED_APP))
+#define GSM_IS_RESUMED_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSM_TYPE_RESUMED_APP))
+#define GSM_RESUMED_APP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSM_TYPE_RESUMED_APP, GsmResumedAppClass))
+
+typedef struct _GsmResumedApp GsmResumedApp;
+typedef struct _GsmResumedAppClass GsmResumedAppClass;
+typedef struct _GsmResumedAppPrivate GsmResumedAppPrivate;
-struct _GsmAppResumed
+struct _GsmResumedApp
{
- GsmApp parent;
+ GsmApp parent;
- char *program, *restart_command, *discard_command;
- gboolean discard_on_resume;
+ char *program;
+ char *restart_command;
+ char *discard_command;
+ gboolean discard_on_resume;
};
-struct _GsmAppResumedClass
+struct _GsmResumedAppClass
{
- GsmAppClass parent_class;
+ GsmAppClass parent_class;
- /* signals */
+ /* signals */
- /* virtual methods */
+ /* virtual methods */
};
-GType gsm_app_resumed_get_type (void) G_GNUC_CONST;
+GType gsm_resumed_app_get_type (void) G_GNUC_CONST;
-GsmApp *gsm_app_resumed_new_from_session (GKeyFile *session_file,
- const char *group,
- gboolean discard);
+GsmApp *gsm_resumed_app_new_from_session (GKeyFile *session_file,
+ const char *group,
+ gboolean discard);
-GsmApp *gsm_app_resumed_new_from_legacy_session (GKeyFile *session_file,
- int n);
+GsmApp *gsm_resumed_app_new_from_legacy_session (GKeyFile *session_file,
+ int n);
G_END_DECLS
-#endif /* __GSM_APP_RESUMED_H__ */
+#endif /* __GSM_RESUMED_APP_H__ */
Copied: branches/dbus_based/gnome-session/gsm-xsmp-client.c (from r4726, /trunk/gnome-session/client-xsmp.c)
==============================================================================
--- /trunk/gnome-session/client-xsmp.c (original)
+++ branches/dbus_based/gnome-session/gsm-xsmp-client.c Wed Jun 11 19:10:15 2008
@@ -1,4 +1,5 @@
-/* client-xsmp.c
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
* Copyright (C) 2007 Novell, Inc.
*
* This program is free software; you can redistribute it and/or
@@ -27,18 +28,19 @@
#include <time.h>
#include <unistd.h>
-#include "client-xsmp.h"
-#include "session.h"
+#include "gsm-xsmp-client.h"
+
+#include "gsm-manager.h"
/* FIXME */
#define GsmDesktopFile "_Gsm_DesktopFile"
static gboolean client_iochannel_watch (GIOChannel *channel,
- GIOCondition condition,
- gpointer data);
+ GIOCondition condition,
+ gpointer data);
static gboolean client_protocol_timeout (gpointer data);
-static void set_description (GsmClientXSMP *xsmp);
+static void set_description (GsmXSMPClient *xsmp);
static const char *xsmp_get_client_id (GsmClient *client);
static pid_t xsmp_get_pid (GsmClient *client);
@@ -51,120 +53,121 @@
static void xsmp_restart (GsmClient *client,
GError **error);
static void xsmp_save_yourself (GsmClient *client,
- gboolean save_state);
+ gboolean save_state);
static void xsmp_save_yourself_phase2 (GsmClient *client);
static void xsmp_interact (GsmClient *client);
static void xsmp_shutdown_cancelled (GsmClient *client);
static void xsmp_die (GsmClient *client);
-G_DEFINE_TYPE (GsmClientXSMP, gsm_client_xsmp, GSM_TYPE_CLIENT)
+G_DEFINE_TYPE (GsmXSMPClient, gsm_xsmp_client, GSM_TYPE_CLIENT)
static void
-gsm_client_xsmp_init (GsmClientXSMP *xsmp)
+gsm_xsmp_client_init (GsmXSMPClient *xsmp)
{
- ;
+ ;
}
static void
-gsm_client_xsmp_class_init (GsmClientXSMPClass *klass)
+gsm_xsmp_client_class_init (GsmXSMPClientClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GsmClientClass *client_class = GSM_CLIENT_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GsmClientClass *client_class = GSM_CLIENT_CLASS (klass);
- object_class->finalize = xsmp_finalize;
+ object_class->finalize = xsmp_finalize;
- client_class->get_client_id = xsmp_get_client_id;
- client_class->get_pid = xsmp_get_pid;
- client_class->get_desktop_file = xsmp_get_desktop_file;
- client_class->get_restart_command = xsmp_get_restart_command;
- client_class->get_discard_command = xsmp_get_discard_command;
- client_class->get_autorestart = xsmp_get_autorestart;
+ client_class->get_client_id = xsmp_get_client_id;
+ client_class->get_pid = xsmp_get_pid;
+ client_class->get_desktop_file = xsmp_get_desktop_file;
+ client_class->get_restart_command = xsmp_get_restart_command;
+ client_class->get_discard_command = xsmp_get_discard_command;
+ client_class->get_autorestart = xsmp_get_autorestart;
- client_class->restart = xsmp_restart;
- client_class->save_yourself = xsmp_save_yourself;
- client_class->save_yourself_phase2 = xsmp_save_yourself_phase2;
- client_class->interact = xsmp_interact;
- client_class->shutdown_cancelled = xsmp_shutdown_cancelled;
- client_class->die = xsmp_die;
+ client_class->restart = xsmp_restart;
+ client_class->save_yourself = xsmp_save_yourself;
+ client_class->save_yourself_phase2 = xsmp_save_yourself_phase2;
+ client_class->interact = xsmp_interact;
+ client_class->shutdown_cancelled = xsmp_shutdown_cancelled;
+ client_class->die = xsmp_die;
}
-GsmClientXSMP *
-gsm_client_xsmp_new (IceConn ice_conn)
+GsmXSMPClient *
+gsm_xsmp_client_new (IceConn ice_conn)
{
- GsmClientXSMP *xsmp;
- GIOChannel *channel;
- int fd;
+ GsmXSMPClient *xsmp;
+ GIOChannel *channel;
+ int fd;
- xsmp = g_object_new (GSM_TYPE_CLIENT_XSMP, NULL);
- xsmp->props = g_ptr_array_new ();
+ xsmp = g_object_new (GSM_TYPE_XSMP_CLIENT, NULL);
+ xsmp->props = g_ptr_array_new ();
- xsmp->ice_conn = ice_conn;
- xsmp->current_save_yourself = -1;
- xsmp->next_save_yourself = -1;
+ xsmp->ice_conn = ice_conn;
+ xsmp->current_save_yourself = -1;
+ xsmp->next_save_yourself = -1;
- fd = IceConnectionNumber (ice_conn);
- fcntl (fd, F_SETFD, fcntl (fd, F_GETFD, 0) | FD_CLOEXEC);
+ fd = IceConnectionNumber (ice_conn);
+ fcntl (fd, F_SETFD, fcntl (fd, F_GETFD, 0) | FD_CLOEXEC);
- channel = g_io_channel_unix_new (fd);
- xsmp->watch_id = g_io_add_watch (channel, G_IO_IN | G_IO_ERR,
- client_iochannel_watch, xsmp);
- g_io_channel_unref (channel);
+ channel = g_io_channel_unix_new (fd);
+ xsmp->watch_id = g_io_add_watch (channel, G_IO_IN | G_IO_ERR,
+ client_iochannel_watch, xsmp);
+ g_io_channel_unref (channel);
- xsmp->protocol_timeout = g_timeout_add (5000, client_protocol_timeout, xsmp);
+ xsmp->protocol_timeout = g_timeout_add (5000, client_protocol_timeout, xsmp);
- set_description (xsmp);
- g_debug ("New client '%s'", xsmp->description);
+ set_description (xsmp);
+ g_debug ("New client '%s'", xsmp->description);
- return xsmp;
+ return xsmp;
}
static void
xsmp_finalize (GObject *object)
{
- GsmClientXSMP *xsmp = (GsmClientXSMP *) object;
+ GsmXSMPClient *xsmp = (GsmXSMPClient *) object;
- g_debug ("xsmp_finalize (%s)", xsmp->description);
+ g_debug ("xsmp_finalize (%s)", xsmp->description);
- if (xsmp->watch_id)
- g_source_remove (xsmp->watch_id);
+ if (xsmp->watch_id) {
+ g_source_remove (xsmp->watch_id);
+ }
- if (xsmp->conn)
- SmsCleanUp (xsmp->conn);
- else
- IceCloseConnection (xsmp->ice_conn);
+ if (xsmp->conn) {
+ SmsCleanUp (xsmp->conn);
+ } else {
+ IceCloseConnection (xsmp->ice_conn);
+ }
- if (xsmp->protocol_timeout)
- g_source_remove (xsmp->protocol_timeout);
+ if (xsmp->protocol_timeout)
+ g_source_remove (xsmp->protocol_timeout);
- G_OBJECT_CLASS (gsm_client_xsmp_parent_class)->finalize (object);
+ G_OBJECT_CLASS (gsm_xsmp_client_parent_class)->finalize (object);
}
static gboolean
client_iochannel_watch (GIOChannel *channel,
- GIOCondition condition,
- gpointer data)
+ GIOCondition condition,
+ gpointer data)
{
- GsmClient *client = data;
- GsmClientXSMP *xsmp = data;
+ GsmClient *client = data;
+ GsmXSMPClient *xsmp = data;
- switch (IceProcessMessages (xsmp->ice_conn, NULL, NULL))
- {
- case IceProcessMessagesSuccess:
- return TRUE;
-
- case IceProcessMessagesIOError:
- g_debug ("IceProcessMessagesIOError on '%s'", xsmp->description);
- gsm_client_disconnected (client);
- return FALSE;
-
- case IceProcessMessagesConnectionClosed:
- g_debug ("IceProcessMessagesConnectionClosed on '%s'",
- xsmp->description);
- return FALSE;
-
- default:
- g_assert_not_reached ();
- }
+ switch (IceProcessMessages (xsmp->ice_conn, NULL, NULL)) {
+ case IceProcessMessagesSuccess:
+ return TRUE;
+
+ case IceProcessMessagesIOError:
+ g_debug ("IceProcessMessagesIOError on '%s'", xsmp->description);
+ gsm_client_disconnected (client);
+ return FALSE;
+
+ case IceProcessMessagesConnectionClosed:
+ g_debug ("IceProcessMessagesConnectionClosed on '%s'",
+ xsmp->description);
+ return FALSE;
+
+ default:
+ g_assert_not_reached ();
+ }
}
/* Called if too much time passes between the initial connection and
@@ -173,96 +176,90 @@
static gboolean
client_protocol_timeout (gpointer data)
{
- GsmClient *client = data;
- GsmClientXSMP *xsmp = data;
+ GsmClient *client = data;
+ GsmXSMPClient *xsmp = data;
- g_debug ("client_protocol_timeout for client '%s' in ICE status %d",
- xsmp->description, IceConnectionStatus (xsmp->ice_conn));
- gsm_client_disconnected (client);
+ g_debug ("client_protocol_timeout for client '%s' in ICE status %d",
+ xsmp->description, IceConnectionStatus (xsmp->ice_conn));
+ gsm_client_disconnected (client);
- return FALSE;
+ return FALSE;
}
static Status
register_client_callback (SmsConn conn,
- SmPointer manager_data,
- char *previous_id)
+ SmPointer manager_data,
+ char *previous_id)
{
- GsmClient *client = manager_data;
- GsmClientXSMP *xsmp = manager_data;
- char *id;
-
- g_debug ("Client '%s' received RegisterClient(%s)",
- xsmp->description,
- previous_id ? previous_id : "NULL");
-
- id = gsm_session_register_client (global_session, client, previous_id);
-
- if (id == NULL)
- {
- g_debug (" rejected: invalid previous_id");
- free (previous_id);
- return FALSE;
- }
-
- xsmp->id = id;
-
- set_description (xsmp);
-
- g_debug ("Sending RegisterClientReply to '%s'", xsmp->description);
-
- SmsRegisterClientReply (conn, xsmp->id);
-
- if (!previous_id)
- {
- /* Send the initial SaveYourself. */
- g_debug ("Sending initial SaveYourself");
- SmsSaveYourself (conn, SmSaveLocal, False, SmInteractStyleNone, False);
- xsmp->current_save_yourself = SmSaveLocal;
-
- free (previous_id);
- }
-
- return TRUE;
-}
-
-static void
-do_save_yourself (GsmClientXSMP *xsmp, int save_type)
-{
- if (xsmp->next_save_yourself != -1)
- {
- /* Either we're currently doing a shutdown and there's a checkpoint
- * queued after it, or vice versa. Either way, the new SaveYourself
- * is redundant.
- */
- g_debug (" skipping redundant SaveYourself for '%s'",
- xsmp->description);
- }
- else if (xsmp->current_save_yourself != -1)
- {
- g_debug (" queuing new SaveYourself for '%s'",
- xsmp->description);
- xsmp->next_save_yourself = save_type;
- }
- else
- {
- xsmp->current_save_yourself = save_type;
-
- switch (save_type)
- {
- case SmSaveLocal:
- /* Save state */
- SmsSaveYourself (xsmp->conn, SmSaveLocal, FALSE,
- SmInteractStyleNone, FALSE);
- break;
-
- default:
- /* Logout */
- SmsSaveYourself (xsmp->conn, save_type, TRUE,
- SmInteractStyleAny, FALSE);
- break;
- }
- }
+ GsmClient *client = manager_data;
+ GsmXSMPClient *xsmp = manager_data;
+ char *id;
+
+ g_debug ("Client '%s' received RegisterClient(%s)",
+ xsmp->description,
+ previous_id ? previous_id : "NULL");
+
+ id = NULL;
+ gsm_client_register_client (client, previous_id, &id);
+
+ if (id == NULL) {
+ g_debug (" rejected: invalid previous_id");
+ free (previous_id);
+ return FALSE;
+ }
+
+ xsmp->id = id;
+
+ set_description (xsmp);
+
+ g_debug ("Sending RegisterClientReply to '%s'", xsmp->description);
+
+ SmsRegisterClientReply (conn, xsmp->id);
+
+ if (!previous_id) {
+ /* Send the initial SaveYourself. */
+ g_debug ("Sending initial SaveYourself");
+ SmsSaveYourself (conn, SmSaveLocal, False, SmInteractStyleNone, False);
+ xsmp->current_save_yourself = SmSaveLocal;
+
+ free (previous_id);
+ }
+
+ return TRUE;
+}
+
+static void
+do_save_yourself (GsmXSMPClient *xsmp, int save_type)
+{
+ if (xsmp->next_save_yourself != -1) {
+ /* Either we're currently doing a shutdown and there's a checkpoint
+ * queued after it, or vice versa. Either way, the new SaveYourself
+ * is redundant.
+ */
+ g_debug (" skipping redundant SaveYourself for '%s'",
+ xsmp->description);
+ }
+ else if (xsmp->current_save_yourself != -1) {
+ g_debug (" queuing new SaveYourself for '%s'",
+ xsmp->description);
+ xsmp->next_save_yourself = save_type;
+ } else {
+ xsmp->current_save_yourself = save_type;
+
+ switch (save_type) {
+ case SmSaveLocal:
+ /* Save state */
+ SmsSaveYourself (xsmp->conn, SmSaveLocal, FALSE,
+ SmInteractStyleNone, FALSE);
+ break;
+
+ default:
+ /* Logout */
+ SmsSaveYourself (xsmp->conn, save_type, TRUE,
+ SmInteractStyleAny, FALSE);
+ break;
+ }
+ }
}
static void
@@ -274,114 +271,110 @@
Bool fast,
Bool global)
{
- GsmClientXSMP *xsmp = manager_data;
+ GsmXSMPClient *xsmp = manager_data;
- g_debug ("Client '%s' received SaveYourselfRequest(%s, %s, %s, %s, %s)",
- xsmp->description,
- save_type == SmSaveLocal ? "SmSaveLocal" :
- save_type == SmSaveGlobal ? "SmSaveGlobal" : "SmSaveBoth",
- shutdown ? "Shutdown" : "!Shutdown",
- interact_style == SmInteractStyleAny ? "SmInteractStyleAny" :
- interact_style == SmInteractStyleErrors ? "SmInteractStyleErrors" :
- "SmInteractStyleNone", fast ? "Fast" : "!Fast",
- global ? "Global" : "!Global");
-
- /* Examining the g_debug above, you can see that there are a total
- * of 72 different combinations of options that this could have been
- * called with. However, most of them are stupid.
- *
- * If @shutdown and @global are both TRUE, that means the caller is
- * requesting that a logout message be sent to all clients, so we do
- * that. We use @fast to decide whether or not to show a
- * confirmation dialog. (This isn't really what @fast is for, but
- * the old gnome-session and ksmserver both interpret it that way,
- * so we do too.) We ignore @save_type because we pick the correct
- * save_type ourselves later based on user prefs, dialog choices,
- * etc, and we ignore @interact_style, because clients have not used
- * it correctly consistently enough to make it worth honoring.
- *
- * If @shutdown is TRUE and @global is FALSE, the caller is
- * confused, so we ignore the request.
- *
- * If @shutdown is FALSE and @save_type is SmSaveGlobal or
- * SmSaveBoth, then the client wants us to ask some or all open
- * applications to save open files to disk, but NOT quit. This is
- * silly and so we ignore the request.
- *
- * If @shutdown is FALSE and @save_type is SmSaveLocal, then the
- * client wants us to ask some or all open applications to update
- * their current saved state, but not log out. At the moment, the
- * code only supports this for the !global case (ie, a client
- * requesting that it be allowed to update *its own* saved state,
- * but not having everyone else update their saved state).
- */
-
- if (shutdown && global)
- {
- g_debug (" initiating shutdown");
- gsm_session_initiate_shutdown (global_session,
- !fast,
- GSM_SESSION_LOGOUT_TYPE_LOGOUT);
- }
- else if (!shutdown && !global)
- {
- g_debug (" initiating checkpoint");
- do_save_yourself (xsmp, SmSaveLocal);
- }
- else
- g_debug (" ignoring");
+ g_debug ("Client '%s' received SaveYourselfRequest(%s, %s, %s, %s, %s)",
+ xsmp->description,
+ save_type == SmSaveLocal ? "SmSaveLocal" :
+ save_type == SmSaveGlobal ? "SmSaveGlobal" : "SmSaveBoth",
+ shutdown ? "Shutdown" : "!Shutdown",
+ interact_style == SmInteractStyleAny ? "SmInteractStyleAny" :
+ interact_style == SmInteractStyleErrors ? "SmInteractStyleErrors" :
+ "SmInteractStyleNone", fast ? "Fast" : "!Fast",
+ global ? "Global" : "!Global");
+
+ /* Examining the g_debug above, you can see that there are a total
+ * of 72 different combinations of options that this could have been
+ * called with. However, most of them are stupid.
+ *
+ * If @shutdown and @global are both TRUE, that means the caller is
+ * requesting that a logout message be sent to all clients, so we do
+ * that. We use @fast to decide whether or not to show a
+ * confirmation dialog. (This isn't really what @fast is for, but
+ * the old gnome-session and ksmserver both interpret it that way,
+ * so we do too.) We ignore @save_type because we pick the correct
+ * save_type ourselves later based on user prefs, dialog choices,
+ * etc, and we ignore @interact_style, because clients have not used
+ * it correctly consistently enough to make it worth honoring.
+ *
+ * If @shutdown is TRUE and @global is FALSE, the caller is
+ * confused, so we ignore the request.
+ *
+ * If @shutdown is FALSE and @save_type is SmSaveGlobal or
+ * SmSaveBoth, then the client wants us to ask some or all open
+ * applications to save open files to disk, but NOT quit. This is
+ * silly and so we ignore the request.
+ *
+ * If @shutdown is FALSE and @save_type is SmSaveLocal, then the
+ * client wants us to ask some or all open applications to update
+ * their current saved state, but not log out. At the moment, the
+ * code only supports this for the !global case (ie, a client
+ * requesting that it be allowed to update *its own* saved state,
+ * but not having everyone else update their saved state).
+ */
+
+ if (shutdown && global) {
+ g_debug (" initiating shutdown");
+ gsm_client_request_logout (GSM_CLIENT (xsmp),
+ !fast);
+ } else if (!shutdown && !global) {
+ g_debug (" initiating checkpoint");
+ do_save_yourself (xsmp, SmSaveLocal);
+ } else {
+ g_debug (" ignoring");
+ }
}
-static void
+static void
xsmp_restart (GsmClient *client, GError **error)
{
- char *restart_cmd = gsm_client_get_restart_command (client);
+ char *restart_cmd = gsm_client_get_restart_command (client);
- g_spawn_command_line_async (restart_cmd, error);
+ g_spawn_command_line_async (restart_cmd, error);
- g_free (restart_cmd);
+ g_free (restart_cmd);
}
static void
xsmp_save_yourself (GsmClient *client, gboolean save_state)
{
- GsmClientXSMP *xsmp = (GsmClientXSMP *)client;
+ GsmXSMPClient *xsmp = (GsmXSMPClient *)client;
- g_debug ("xsmp_save_yourself ('%s', %s)", xsmp->description,
- save_state ? "True" : "False");
+ g_debug ("xsmp_save_yourself ('%s', %s)", xsmp->description,
+ save_state ? "True" : "False");
- do_save_yourself (xsmp, save_state ? SmSaveBoth : SmSaveGlobal);
+ do_save_yourself (xsmp, save_state ? SmSaveBoth : SmSaveGlobal);
}
static void
save_yourself_phase2_request_callback (SmsConn conn,
SmPointer manager_data)
{
- GsmClient *client = manager_data;
- GsmClientXSMP *xsmp = manager_data;
+ GsmClient *client = manager_data;
+ GsmXSMPClient *xsmp = manager_data;
- g_debug ("Client '%s' received SaveYourselfPhase2Request",
- xsmp->description);
+ g_debug ("Client '%s' received SaveYourselfPhase2Request",
+ xsmp->description);
- if (xsmp->current_save_yourself == SmSaveLocal)
- {
- /* WTF? Anyway, if it's checkpointing, it doesn't have to wait
- * for anyone else.
- */
- SmsSaveYourselfPhase2 (xsmp->conn);
- }
- else
- gsm_client_request_phase2 (client);
+ if (xsmp->current_save_yourself == SmSaveLocal)
+ {
+ /* WTF? Anyway, if it's checkpointing, it doesn't have to wait
+ * for anyone else.
+ */
+ SmsSaveYourselfPhase2 (xsmp->conn);
+ }
+ else
+ gsm_client_request_phase2 (client);
}
static void
xsmp_save_yourself_phase2 (GsmClient *client)
{
- GsmClientXSMP *xsmp = (GsmClientXSMP *)client;
+ GsmXSMPClient *xsmp = (GsmXSMPClient *)client;
- g_debug ("xsmp_save_yourself_phase2 ('%s')", xsmp->description);
+ g_debug ("xsmp_save_yourself_phase2 ('%s')", xsmp->description);
- SmsSaveYourselfPhase2 (xsmp->conn);
+ SmsSaveYourselfPhase2 (xsmp->conn);
}
static void
@@ -389,23 +382,23 @@
SmPointer manager_data,
int dialog_type)
{
- GsmClient *client = manager_data;
- GsmClientXSMP *xsmp = manager_data;
+ GsmClient *client = manager_data;
+ GsmXSMPClient *xsmp = manager_data;
- g_debug ("Client '%s' received InteractRequest(%s)", xsmp->description,
- dialog_type == SmInteractStyleAny ? "Any" : "Errors");
+ g_debug ("Client '%s' received InteractRequest(%s)", xsmp->description,
+ dialog_type == SmInteractStyleAny ? "Any" : "Errors");
- gsm_client_request_interaction (client);
+ gsm_client_request_interaction (client);
}
static void
xsmp_interact (GsmClient *client)
{
- GsmClientXSMP *xsmp = (GsmClientXSMP *) client;
+ GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
- g_debug ("xsmp_interact ('%s')", xsmp->description);
+ g_debug ("xsmp_interact ('%s')", xsmp->description);
- SmsInteract (xsmp->conn);
+ SmsInteract (xsmp->conn);
}
static void
@@ -413,163 +406,159 @@
SmPointer manager_data,
Bool cancel_shutdown)
{
- GsmClient *client = manager_data;
- GsmClientXSMP *xsmp = manager_data;
+ GsmClient *client = manager_data;
+ GsmXSMPClient *xsmp = manager_data;
- g_debug ("Client '%s' received InteractDone(cancel_shutdown = %s)",
- xsmp->description, cancel_shutdown ? "True" : "False");
+ g_debug ("Client '%s' received InteractDone(cancel_shutdown = %s)",
+ xsmp->description, cancel_shutdown ? "True" : "False");
- gsm_client_interaction_done (client, cancel_shutdown);
+ gsm_client_interaction_done (client, cancel_shutdown);
}
static void
xsmp_shutdown_cancelled (GsmClient *client)
{
- GsmClientXSMP *xsmp = (GsmClientXSMP *) client;
+ GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
- g_debug ("xsmp_shutdown_cancelled ('%s')", xsmp->description);
+ g_debug ("xsmp_shutdown_cancelled ('%s')", xsmp->description);
- SmsShutdownCancelled (xsmp->conn);
+ SmsShutdownCancelled (xsmp->conn);
}
static void
xsmp_die (GsmClient *client)
{
- GsmClientXSMP *xsmp = (GsmClientXSMP *) client;
+ GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
- g_debug ("xsmp_die ('%s')", xsmp->description);
+ g_debug ("xsmp_die ('%s')", xsmp->description);
- SmsDie (xsmp->conn);
+ SmsDie (xsmp->conn);
}
static void
save_yourself_done_callback (SmsConn conn,
- SmPointer manager_data,
- Bool success)
+ SmPointer manager_data,
+ Bool success)
{
- GsmClient *client = manager_data;
- GsmClientXSMP *xsmp = manager_data;
+ GsmClient *client = manager_data;
+ GsmXSMPClient *xsmp = manager_data;
- g_debug ("Client '%s' received SaveYourselfDone(success = %s)",
- xsmp->description, success ? "True" : "False");
+ g_debug ("Client '%s' received SaveYourselfDone(success = %s)",
+ xsmp->description, success ? "True" : "False");
- if (xsmp->current_save_yourself == SmSaveLocal)
- {
- xsmp->current_save_yourself = -1;
- SmsSaveComplete (xsmp->conn);
- gsm_client_saved_state (client);
- }
- else
- {
- xsmp->current_save_yourself = -1;
- gsm_client_save_yourself_done (client);
- }
-
- if (xsmp->next_save_yourself)
- {
- int save_type = xsmp->next_save_yourself;
-
- xsmp->next_save_yourself = -1;
- do_save_yourself (xsmp, save_type);
- }
+ if (xsmp->current_save_yourself == SmSaveLocal) {
+ xsmp->current_save_yourself = -1;
+ SmsSaveComplete (xsmp->conn);
+ gsm_client_saved_state (client);
+ } else {
+ xsmp->current_save_yourself = -1;
+ gsm_client_save_yourself_done (client);
+ }
+
+ if (xsmp->next_save_yourself) {
+ int save_type = xsmp->next_save_yourself;
+
+ xsmp->next_save_yourself = -1;
+ do_save_yourself (xsmp, save_type);
+ }
}
static void
close_connection_callback (SmsConn conn,
- SmPointer manager_data,
- int count,
- char **reason_msgs)
-{
- GsmClient *client = manager_data;
- GsmClientXSMP *xsmp = manager_data;
- int i;
-
- g_debug ("Client '%s' received CloseConnection", xsmp->description);
- for (i = 0; i < count; i++)
- g_debug (" close reason: '%s'", reason_msgs[i]);
- SmFreeReasons (count, reason_msgs);
+ SmPointer manager_data,
+ int count,
+ char **reason_msgs)
+{
+ GsmClient *client = manager_data;
+ GsmXSMPClient *xsmp = manager_data;
+ int i;
+
+ g_debug ("Client '%s' received CloseConnection", xsmp->description);
+ for (i = 0; i < count; i++) {
+ g_debug (" close reason: '%s'", reason_msgs[i]);
+ }
+ SmFreeReasons (count, reason_msgs);
- gsm_client_disconnected (client);
+ gsm_client_disconnected (client);
}
static void
debug_print_property (SmProp *prop)
{
- GString *tmp;
- int i;
+ GString *tmp;
+ int i;
- switch (prop->type[0])
- {
- case 'C': /* CARD8 */
- g_debug (" %s = %d", prop->name, *(unsigned char *)prop->vals[0].value);
- break;
-
- case 'A': /* ARRAY8 */
- g_debug (" %s = '%s'", prop->name, (char *)prop->vals[0].value);
- break;
-
- case 'L': /* LISTofARRAY8 */
- tmp = g_string_new (NULL);
- for (i = 0; i < prop->num_vals; i++)
- {
- g_string_append_printf (tmp, "'%.*s' ", prop->vals[i].length,
- (char *)prop->vals[i].value);
- }
- g_debug (" %s = %s", prop->name, tmp->str);
- g_string_free (tmp, TRUE);
- break;
-
- default:
- g_debug (" %s = ??? (%s)", prop->name, prop->type);
- break;
- }
+ switch (prop->type[0]) {
+ case 'C': /* CARD8 */
+ g_debug (" %s = %d", prop->name, *(unsigned char *)prop->vals[0].value);
+ break;
+
+ case 'A': /* ARRAY8 */
+ g_debug (" %s = '%s'", prop->name, (char *)prop->vals[0].value);
+ break;
+
+ case 'L': /* LISTofARRAY8 */
+ tmp = g_string_new (NULL);
+ for (i = 0; i < prop->num_vals; i++) {
+ g_string_append_printf (tmp, "'%.*s' ", prop->vals[i].length,
+ (char *)prop->vals[i].value);
+ }
+ g_debug (" %s = %s", prop->name, tmp->str);
+ g_string_free (tmp, TRUE);
+ break;
+
+ default:
+ g_debug (" %s = ??? (%s)", prop->name, prop->type);
+ break;
+ }
}
static SmProp *
-find_property (GsmClientXSMP *client, const char *name, int *index)
+find_property (GsmXSMPClient *client, const char *name, int *index)
{
- SmProp *prop;
- int i;
+ SmProp *prop;
+ int i;
- for (i = 0; i < client->props->len; i++)
- {
- prop = client->props->pdata[i];
+ for (i = 0; i < client->props->len; i++) {
+ prop = client->props->pdata[i];
- if (!strcmp (prop->name, name))
- {
- if (index)
- *index = i;
- return prop;
- }
- }
+ if (!strcmp (prop->name, name)) {
+ if (index) {
+ *index = i;
+ }
+ return prop;
+ }
+ }
- return NULL;
+ return NULL;
}
static void
-delete_property (GsmClientXSMP *client, const char *name)
+delete_property (GsmXSMPClient *client, const char *name)
{
- int index;
- SmProp *prop;
+ int index;
+ SmProp *prop;
- prop = find_property (client, name, &index);
- if (!prop)
- return;
+ prop = find_property (client, name, &index);
+ if (!prop) {
+ return;
+ }
#if 0
- /* This is wrong anyway; we can't unconditionally run the current
- * discard command; if this client corresponds to a GsmAppResumed,
- * and the current discard command is identical to the app's
- * discard_command, then we don't run the discard command now,
- * because that would delete a saved state we may want to resume
- * again later.
- */
- if (!strcmp (name, SmDiscardCommand))
- gsm_client_run_discard (client);
+ /* This is wrong anyway; we can't unconditionally run the current
+ * discard command; if this client corresponds to a GsmAppResumed,
+ * and the current discard command is identical to the app's
+ * discard_command, then we don't run the discard command now,
+ * because that would delete a saved state we may want to resume
+ * again later.
+ */
+ if (!strcmp (name, SmDiscardCommand)) {
+ gsm_client_run_discard (client);
+ }
#endif
- g_ptr_array_remove_index_fast (client->props, index);
- SmFreeProperty (prop);
+ g_ptr_array_remove_index_fast (client->props, index);
+ SmFreeProperty (prop);
}
static void
@@ -578,23 +567,22 @@
int num_props,
SmProp **props)
{
- GsmClientXSMP *client = manager_data;
- int i;
+ GsmXSMPClient *client = manager_data;
+ int i;
- g_debug ("Set properties from client '%s'", client->description);
+ g_debug ("Set properties from client '%s'", client->description);
- for (i = 0; i < num_props; i++)
- {
- delete_property (client, props[i]->name);
- g_ptr_array_add (client->props, props[i]);
+ for (i = 0; i < num_props; i++) {
+ delete_property (client, props[i]->name);
+ g_ptr_array_add (client->props, props[i]);
- debug_print_property (props[i]);
+ debug_print_property (props[i]);
- if (!strcmp (props[i]->name, SmProgram))
- set_description (client);
- }
+ if (!strcmp (props[i]->name, SmProgram))
+ set_description (client);
+ }
- free (props);
+ free (props);
}
@@ -604,224 +592,223 @@
int num_props,
char **prop_names)
{
- GsmClientXSMP *client = manager_data;
- int i;
+ GsmXSMPClient *client = manager_data;
+ int i;
- g_debug ("Delete properties from '%s'", client->description);
+ g_debug ("Delete properties from '%s'", client->description);
- for (i = 0; i < num_props; i++)
- {
- delete_property (client, prop_names[i]);
+ for (i = 0; i < num_props; i++) {
+ delete_property (client, prop_names[i]);
- g_debug (" %s", prop_names[i]);
- }
+ g_debug (" %s", prop_names[i]);
+ }
- free (prop_names);
+ free (prop_names);
}
static void
get_properties_callback (SmsConn conn,
SmPointer manager_data)
{
- GsmClientXSMP *client = manager_data;
+ GsmXSMPClient *client = manager_data;
- g_debug ("Get properties request from '%s'", client->description);
+ g_debug ("Get properties request from '%s'", client->description);
- SmsReturnProperties (conn, client->props->len,
- (SmProp **)client->props->pdata);
+ SmsReturnProperties (conn, client->props->len,
+ (SmProp **)client->props->pdata);
}
static const char *
xsmp_get_client_id (GsmClient *client)
{
- GsmClientXSMP *xsmp = (GsmClientXSMP *) client;
+ GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
- return xsmp->id;
+ return xsmp->id;
}
static pid_t
xsmp_get_pid (GsmClient *client)
{
- GsmClientXSMP *xsmp = (GsmClientXSMP *) client;
- SmProp *prop = find_property (xsmp, SmProcessID, NULL);
- char buf[32];
-
- if (!prop || strcmp (prop->type, SmARRAY8) != 0)
- return (pid_t)-1;
-
- /* prop->vals[0].value might not be '\0'-terminated... */
- g_strlcpy (buf, prop->vals[0].value, MIN (prop->vals[0].length, sizeof (buf)));
- return (pid_t)strtoul (buf, NULL, 10);
+ GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
+ SmProp *prop = find_property (xsmp, SmProcessID, NULL);
+ char buf[32];
+
+ if (!prop || strcmp (prop->type, SmARRAY8) != 0) {
+ return (pid_t)-1;
+ }
+
+ /* prop->vals[0].value might not be '\0'-terminated... */
+ g_strlcpy (buf, prop->vals[0].value, MIN (prop->vals[0].length, sizeof (buf)));
+ return (pid_t)strtoul (buf, NULL, 10);
}
static char *
xsmp_get_desktop_file (GsmClient *client)
{
- GsmClientXSMP *xsmp = (GsmClientXSMP *) client;
- SmProp *prop = find_property (xsmp, GsmDesktopFile, NULL);
+ GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
+ SmProp *prop = find_property (xsmp, GsmDesktopFile, NULL);
- if (!prop || strcmp (prop->type, SmARRAY8) != 0)
- return NULL;
+ if (!prop || strcmp (prop->type, SmARRAY8) != 0) {
+ return NULL;
+ }
- return g_strndup (prop->vals[0].value, prop->vals[0].length);
+ return g_strndup (prop->vals[0].value, prop->vals[0].length);
}
static char *
prop_to_command (SmProp *prop)
{
- GString *str;
- int i, j;
- gboolean need_quotes;
-
- str = g_string_new (NULL);
- for (i = 0; i < prop->num_vals; i++)
- {
- char *val = prop->vals[i].value;
-
- need_quotes = FALSE;
- for (j = 0; j < prop->vals[i].length; j++)
- {
- if (!g_ascii_isalnum (val[j]) && !strchr ("-_=:./", val[j]))
- {
- need_quotes = TRUE;
- break;
- }
- }
-
- if (i > 0)
- g_string_append_c (str, ' ');
-
- if (!need_quotes)
- {
- g_string_append_printf (str, "%.*s", prop->vals[i].length,
- (char *)prop->vals[i].value);
- }
- else
- {
- g_string_append_c (str, '\'');
- while (val < (char *)prop->vals[i].value + prop->vals[i].length)
- {
- if (*val == '\'')
- g_string_append (str, "'\''");
- else
- g_string_append_c (str, *val);
- val++;
- }
- g_string_append_c (str, '\'');
- }
- }
+ GString *str;
+ int i, j;
+ gboolean need_quotes;
+
+ str = g_string_new (NULL);
+ for (i = 0; i < prop->num_vals; i++) {
+ char *val = prop->vals[i].value;
+
+ need_quotes = FALSE;
+ for (j = 0; j < prop->vals[i].length; j++) {
+ if (!g_ascii_isalnum (val[j]) && !strchr ("-_=:./", val[j])) {
+ need_quotes = TRUE;
+ break;
+ }
+ }
+
+ if (i > 0) {
+ g_string_append_c (str, ' ');
+ }
+
+ if (!need_quotes) {
+ g_string_append_printf (str, "%.*s", prop->vals[i].length,
+ (char *)prop->vals[i].value);
+ } else {
+ g_string_append_c (str, '\'');
+ while (val < (char *)prop->vals[i].value + prop->vals[i].length) {
+ if (*val == '\'') {
+ g_string_append (str, "'\''");
+ } else {
+ g_string_append_c (str, *val);
+ }
+ val++;
+ }
+ g_string_append_c (str, '\'');
+ }
+ }
- return g_string_free (str, FALSE);
+ return g_string_free (str, FALSE);
}
static char *
xsmp_get_restart_command (GsmClient *client)
{
- GsmClientXSMP *xsmp = (GsmClientXSMP *) client;
- SmProp *prop = find_property (xsmp, SmRestartCommand, NULL);
+ GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
+ SmProp *prop = find_property (xsmp, SmRestartCommand, NULL);
- if (!prop || strcmp (prop->type, SmLISTofARRAY8) != 0)
- return NULL;
+ if (!prop || strcmp (prop->type, SmLISTofARRAY8) != 0) {
+ return NULL;
+ }
- return prop_to_command (prop);
+ return prop_to_command (prop);
}
static char *
xsmp_get_discard_command (GsmClient *client)
{
- GsmClientXSMP *xsmp = (GsmClientXSMP *) client;
- SmProp *prop = find_property (xsmp, SmDiscardCommand, NULL);
+ GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
+ SmProp *prop = find_property (xsmp, SmDiscardCommand, NULL);
- if (!prop || strcmp (prop->type, SmLISTofARRAY8) != 0)
- return NULL;
+ if (!prop || strcmp (prop->type, SmLISTofARRAY8) != 0) {
+ return NULL;
+ }
- return prop_to_command (prop);
+ return prop_to_command (prop);
}
static gboolean
xsmp_get_autorestart (GsmClient *client)
{
- GsmClientXSMP *xsmp = (GsmClientXSMP *) client;
- SmProp *prop = find_property (xsmp, SmRestartStyleHint, NULL);
+ GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
+ SmProp *prop = find_property (xsmp, SmRestartStyleHint, NULL);
- if (!prop || strcmp (prop->type, SmCARD8) != 0)
- return FALSE;
+ if (!prop || strcmp (prop->type, SmCARD8) != 0) {
+ return FALSE;
+ }
- return ((unsigned char *)prop->vals[0].value)[0] == SmRestartImmediately;
+ return ((unsigned char *)prop->vals[0].value)[0] == SmRestartImmediately;
}
static void
-set_description (GsmClientXSMP *client)
+set_description (GsmXSMPClient *client)
{
- SmProp *prop = find_property (client, SmProgram, NULL);
+ SmProp *prop = find_property (client, SmProgram, NULL);
- g_free (client->description);
- if (prop)
- {
- client->description = g_strdup_printf ("%p [%.*s %s]", client,
- prop->vals[0].length,
- (char *)prop->vals[0].value,
- client->id);
- }
- else if (client->id)
- client->description = g_strdup_printf ("%p [%s]", client, client->id);
- else
- client->description = g_strdup_printf ("%p", client);
+ g_free (client->description);
+ if (prop) {
+ client->description = g_strdup_printf ("%p [%.*s %s]", client,
+ prop->vals[0].length,
+ (char *)prop->vals[0].value,
+ client->id);
+ } else if (client->id) {
+ client->description = g_strdup_printf ("%p [%s]", client, client->id);
+ } else {
+ client->description = g_strdup_printf ("%p", client);
+ }
}
void
-gsm_client_xsmp_connect (GsmClientXSMP *client, SmsConn conn,
- unsigned long *mask_ret, SmsCallbacks *callbacks_ret)
+gsm_xsmp_client_connect (GsmXSMPClient *client,
+ SmsConn conn,
+ unsigned long *mask_ret,
+ SmsCallbacks *callbacks_ret)
{
- client->conn = conn;
+ client->conn = conn;
- if (client->protocol_timeout)
- {
- g_source_remove (client->protocol_timeout);
- client->protocol_timeout = 0;
- }
+ if (client->protocol_timeout) {
+ g_source_remove (client->protocol_timeout);
+ client->protocol_timeout = 0;
+ }
- g_debug ("Initializing client %s", client->description);
+ g_debug ("Initializing client %s", client->description);
- *mask_ret = 0;
+ *mask_ret = 0;
- *mask_ret |= SmsRegisterClientProcMask;
- callbacks_ret->register_client.callback = register_client_callback;
- callbacks_ret->register_client.manager_data = client;
+ *mask_ret |= SmsRegisterClientProcMask;
+ callbacks_ret->register_client.callback = register_client_callback;
+ callbacks_ret->register_client.manager_data = client;
- *mask_ret |= SmsInteractRequestProcMask;
- callbacks_ret->interact_request.callback = interact_request_callback;
- callbacks_ret->interact_request.manager_data = client;
+ *mask_ret |= SmsInteractRequestProcMask;
+ callbacks_ret->interact_request.callback = interact_request_callback;
+ callbacks_ret->interact_request.manager_data = client;
- *mask_ret |= SmsInteractDoneProcMask;
- callbacks_ret->interact_done.callback = interact_done_callback;
- callbacks_ret->interact_done.manager_data = client;
+ *mask_ret |= SmsInteractDoneProcMask;
+ callbacks_ret->interact_done.callback = interact_done_callback;
+ callbacks_ret->interact_done.manager_data = client;
- *mask_ret |= SmsSaveYourselfRequestProcMask;
- callbacks_ret->save_yourself_request.callback = save_yourself_request_callback;
- callbacks_ret->save_yourself_request.manager_data = client;
+ *mask_ret |= SmsSaveYourselfRequestProcMask;
+ callbacks_ret->save_yourself_request.callback = save_yourself_request_callback;
+ callbacks_ret->save_yourself_request.manager_data = client;
- *mask_ret |= SmsSaveYourselfP2RequestProcMask;
- callbacks_ret->save_yourself_phase2_request.callback = save_yourself_phase2_request_callback;
- callbacks_ret->save_yourself_phase2_request.manager_data = client;
+ *mask_ret |= SmsSaveYourselfP2RequestProcMask;
+ callbacks_ret->save_yourself_phase2_request.callback = save_yourself_phase2_request_callback;
+ callbacks_ret->save_yourself_phase2_request.manager_data = client;
- *mask_ret |= SmsSaveYourselfDoneProcMask;
- callbacks_ret->save_yourself_done.callback = save_yourself_done_callback;
- callbacks_ret->save_yourself_done.manager_data = client;
+ *mask_ret |= SmsSaveYourselfDoneProcMask;
+ callbacks_ret->save_yourself_done.callback = save_yourself_done_callback;
+ callbacks_ret->save_yourself_done.manager_data = client;
- *mask_ret |= SmsCloseConnectionProcMask;
- callbacks_ret->close_connection.callback = close_connection_callback;
- callbacks_ret->close_connection.manager_data = client;
+ *mask_ret |= SmsCloseConnectionProcMask;
+ callbacks_ret->close_connection.callback = close_connection_callback;
+ callbacks_ret->close_connection.manager_data = client;
- *mask_ret |= SmsSetPropertiesProcMask;
- callbacks_ret->set_properties.callback = set_properties_callback;
- callbacks_ret->set_properties.manager_data = client;
+ *mask_ret |= SmsSetPropertiesProcMask;
+ callbacks_ret->set_properties.callback = set_properties_callback;
+ callbacks_ret->set_properties.manager_data = client;
- *mask_ret |= SmsDeletePropertiesProcMask;
- callbacks_ret->delete_properties.callback = delete_properties_callback;
- callbacks_ret->delete_properties.manager_data = client;
+ *mask_ret |= SmsDeletePropertiesProcMask;
+ callbacks_ret->delete_properties.callback = delete_properties_callback;
+ callbacks_ret->delete_properties.manager_data = client;
- *mask_ret |= SmsGetPropertiesProcMask;
- callbacks_ret->get_properties.callback = get_properties_callback;
- callbacks_ret->get_properties.manager_data = client;
+ *mask_ret |= SmsGetPropertiesProcMask;
+ callbacks_ret->get_properties.callback = get_properties_callback;
+ callbacks_ret->get_properties.manager_data = client;
}
Copied: branches/dbus_based/gnome-session/gsm-xsmp-client.h (from r4726, /trunk/gnome-session/client-xsmp.h)
==============================================================================
--- /trunk/gnome-session/client-xsmp.h (original)
+++ branches/dbus_based/gnome-session/gsm-xsmp-client.h Wed Jun 11 19:10:15 2008
@@ -1,4 +1,5 @@
-/* client-xsmp.h
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
* Copyright (C) 2007 Novell, Inc.
*
* This program is free software; you can redistribute it and/or
@@ -20,51 +21,54 @@
#ifndef __GSM_CLIENT_XSMP_H__
#define __GSM_CLIENT_XSMP_H__
-#include "client.h"
+#include "gsm-client.h"
#include <X11/SM/SMlib.h>
G_BEGIN_DECLS
-#define GSM_TYPE_CLIENT_XSMP (gsm_client_xsmp_get_type ())
-#define GSM_CLIENT_XSMP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSM_TYPE_CLIENT_XSMP, GsmClientXSMP))
-#define GSM_CLIENT_XSMP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSM_TYPE_CLIENT_XSMP, GsmClientXSMPClass))
-#define GSM_IS_CLIENT_XSMP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSM_TYPE_CLIENT_XSMP))
-#define GSM_IS_CLIENT_XSMP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSM_TYPE_CLIENT_XSMP))
-#define GSM_CLIENT_XSMP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSM_TYPE_CLIENT_XSMP, GsmClientXSMPClass))
+#define GSM_TYPE_XSMP_CLIENT (gsm_xsmp_client_get_type ())
+#define GSM_XSMP_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSM_TYPE_XSMP_CLIENT, GsmXSMPClient))
+#define GSM_XSMP_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSM_TYPE_XSMP_CLIENT, GsmXSMPClientClass))
+#define GSM_IS_XSMP_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSM_TYPE_XSMP_CLIENT))
+#define GSM_IS_XSMP_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSM_TYPE_XSMP_CLIENT))
+#define GSM_XSMP_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSM_TYPE_XSMP_CLIENT, GsmXSMPClientClass))
-typedef struct _GsmClientXSMP GsmClientXSMP;
-typedef struct _GsmClientXSMPClass GsmClientXSMPClass;
+typedef struct _GsmXSMPClient GsmXSMPClient;
+typedef struct _GsmXSMPClientClass GsmXSMPClientClass;
-struct _GsmClientXSMP
+struct _GsmXSMPClient
{
- GsmClient parent;
+ GsmClient parent;
- SmsConn conn;
- IceConn ice_conn;
+ SmsConn conn;
+ IceConn ice_conn;
- guint watch_id, protocol_timeout;
+ guint watch_id;
+ guint protocol_timeout;
- int current_save_yourself, next_save_yourself;
- char *id, *description;
- GPtrArray *props;
+ int current_save_yourself;
+ int next_save_yourself;
+ char *id;
+ char *description;
+ GPtrArray *props;
};
-struct _GsmClientXSMPClass
+struct _GsmXSMPClientClass
{
- GsmClientClass parent_class;
+ GsmClientClass parent_class;
};
-GType gsm_client_xsmp_get_type (void) G_GNUC_CONST;
+GType gsm_xsmp_client_get_type (void) G_GNUC_CONST;
-GsmClientXSMP *gsm_client_xsmp_new (IceConn ice_conn);
+GsmXSMPClient *gsm_xsmp_client_new (IceConn ice_conn);
-void gsm_client_xsmp_connect (GsmClientXSMP *client,
- SmsConn conn,
- unsigned long *mask_ret,
- SmsCallbacks *callbacks_ret);
+void gsm_xsmp_client_connect (GsmXSMPClient *client,
+ SmsConn conn,
+ unsigned long *mask_ret,
+ SmsCallbacks *callbacks_ret);
G_END_DECLS
-#endif /* __GSM_CLIENT_XSMP_H__ */
+#endif /* __GSM_XSMP_CLIENT_H__ */
Added: branches/dbus_based/gnome-session/gsm-xsmp-server.c
==============================================================================
--- (empty file)
+++ branches/dbus_based/gnome-session/gsm-xsmp-server.c Wed Jun 11 19:10:15 2008
@@ -0,0 +1,625 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Novell, Inc.
+ * Copyright (C) 2008 William Jon McCann <jmccann redhat com>
+ *
+ * This program 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.
+ *
+ * This program 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 "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+
+#include <X11/ICE/ICElib.h>
+#include <X11/ICE/ICEutil.h>
+#include <X11/ICE/ICEconn.h>
+#include <X11/SM/SMlib.h>
+
+#ifdef HAVE_X11_XTRANS_XTRANS_H
+/* Get the proto for _IceTransNoListen */
+#define ICE_t
+#define TRANS_SERVER
+#include <X11/Xtrans/Xtrans.h>
+#undef ICE_t
+#undef TRANS_SERVER
+#endif /* HAVE_X11_XTRANS_XTRANS_H */
+
+#include "gsm-xsmp-server.h"
+#include "gsm-xsmp-client.h"
+#include "util.h"
+
+/* ICEauthority stuff */
+/* Various magic numbers stolen from iceauth.c */
+#define GSM_ICE_AUTH_RETRIES 10
+#define GSM_ICE_AUTH_INTERVAL 2 /* 2 seconds */
+#define GSM_ICE_AUTH_LOCK_TIMEOUT 600 /* 10 minutes */
+
+#define GSM_ICE_MAGIC_COOKIE_AUTH_NAME "MIT-MAGIC-COOKIE-1"
+#define GSM_ICE_MAGIC_COOKIE_LEN 16
+
+#define GSM_XSMP_SERVER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_XSMP_SERVER, GsmXsmpServerPrivate))
+
+struct GsmXsmpServerPrivate
+{
+ GsmClientStore *client_store;
+
+ IceListenObj *xsmp_sockets;
+ int num_xsmp_sockets;
+ int num_local_xsmp_sockets;
+
+};
+
+enum {
+ PROP_0,
+ PROP_CLIENT_STORE,
+};
+
+static void gsm_xsmp_server_class_init (GsmXsmpServerClass *klass);
+static void gsm_xsmp_server_init (GsmXsmpServer *xsmp_server);
+static void gsm_xsmp_server_finalize (GObject *object);
+
+static gpointer xsmp_server_object = NULL;
+
+G_DEFINE_TYPE (GsmXsmpServer, gsm_xsmp_server, G_TYPE_OBJECT)
+
+typedef struct {
+ GsmXsmpServer *server;
+ IceListenObj listener;
+} GsmIceConnectionData;
+
+/* This is called (by glib via xsmp->ice_connection_watch) when a
+ * connection is first received on the ICE listening socket. (We
+ * expect that the client will then initiate XSMP on the connection;
+ * if it does not, GsmXSMPClient will eventually time out and close
+ * the connection.)
+ *
+ * FIXME: it would probably make more sense to not create a
+ * GsmXSMPClient object until accept_xsmp_connection, below (and to do
+ * the timing-out here in xsmp.c).
+ */
+static gboolean
+accept_ice_connection (GIOChannel *source,
+ GIOCondition condition,
+ GsmIceConnectionData *data)
+{
+ IceListenObj listener;
+ IceConn ice_conn;
+ IceAcceptStatus status;
+ GsmXSMPClient *client;
+ GsmXsmpServer *server;
+
+ listener = data->listener;
+ server = data->server;
+
+ g_debug ("accept_ice_connection()");
+
+ ice_conn = IceAcceptConnection (listener, &status);
+ if (status != IceAcceptSuccess) {
+ g_debug ("IceAcceptConnection returned %d", status);
+ return TRUE;
+ }
+
+ client = gsm_xsmp_client_new (ice_conn);
+ ice_conn->context = client;
+
+ return TRUE;
+}
+
+void
+gsm_xsmp_server_start (GsmXsmpServer *server)
+{
+ GIOChannel *channel;
+ int i;
+
+ for (i = 0; i < server->priv->num_local_xsmp_sockets; i++) {
+ GsmIceConnectionData *data;
+
+ data = g_new0 (GsmIceConnectionData, 1);
+ data->server = server;
+ data->listener = server->priv->xsmp_sockets[i];
+
+ channel = g_io_channel_unix_new (IceGetListenConnectionNumber (server->priv->xsmp_sockets[i]));
+ g_io_add_watch_full (channel,
+ G_PRIORITY_DEFAULT,
+ G_IO_IN | G_IO_HUP | G_IO_ERR,
+ (GIOFunc)accept_ice_connection,
+ data,
+ (GDestroyNotify)g_free);
+ g_io_channel_unref (channel);
+ }
+}
+
+static void
+gsm_xsmp_server_set_client_store (GsmXsmpServer *xsmp_server,
+ GsmClientStore *store)
+{
+ g_return_if_fail (GSM_IS_XSMP_SERVER (xsmp_server));
+
+ if (store != NULL) {
+ g_object_ref (store);
+ }
+
+ if (xsmp_server->priv->client_store != NULL) {
+ g_object_unref (xsmp_server->priv->client_store);
+ }
+
+ xsmp_server->priv->client_store = store;
+}
+
+static void
+gsm_xsmp_server_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GsmXsmpServer *self;
+
+ self = GSM_XSMP_SERVER (object);
+
+ switch (prop_id) {
+ case PROP_CLIENT_STORE:
+ gsm_xsmp_server_set_client_store (self, g_value_get_object (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gsm_xsmp_server_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GsmXsmpServer *self;
+
+ self = GSM_XSMP_SERVER (object);
+
+ switch (prop_id) {
+ case PROP_CLIENT_STORE:
+ g_value_set_object (value, self->priv->client_store);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/* This is called (by libSM) when XSMP is initiated on an ICE
+ * connection that was already accepted by accept_ice_connection.
+ */
+static Status
+accept_xsmp_connection (SmsConn sms_conn,
+ GsmXsmpServer *server,
+ unsigned long *mask_ret,
+ SmsCallbacks *callbacks_ret,
+ char **failure_reason_ret)
+{
+ IceConn ice_conn;
+ GsmXSMPClient *client;
+
+ /* FIXME: what about during shutdown but before gsm_xsmp_shutdown? */
+ if (server->priv->xsmp_sockets == NULL) {
+ g_debug ("In shutdown, rejecting new client");
+
+ *failure_reason_ret = strdup (_("Refusing new client connection because the session is currently being shut down\n"));
+ return FALSE;
+ }
+
+ ice_conn = SmsGetIceConnection (sms_conn);
+ client = ice_conn->context;
+
+ g_return_val_if_fail (client != NULL, TRUE);
+
+ gsm_xsmp_client_connect (client, sms_conn, mask_ret, callbacks_ret);
+
+ return TRUE;
+}
+
+static void
+ice_error_handler (IceConn conn,
+ Bool swap,
+ int offending_minor_opcode,
+ unsigned long offending_sequence,
+ int error_class,
+ int severity,
+ IcePointer values)
+{
+ g_debug ("ice_error_handler (%p, %s, %d, %lx, %d, %d)",
+ conn, swap ? "TRUE" : "FALSE", offending_minor_opcode,
+ offending_sequence, error_class, severity);
+
+ if (severity == IceCanContinue) {
+ return;
+ }
+
+ /* FIXME: the ICElib docs are completely vague about what we're
+ * supposed to do in this case. Need to verify that calling
+ * IceCloseConnection() here is guaranteed to cause neither
+ * free-memory-reads nor leaks.
+ */
+ IceCloseConnection (conn);
+}
+
+static void
+ice_io_error_handler (IceConn conn)
+{
+ g_debug ("ice_io_error_handler (%p)", conn);
+
+ /* We don't need to do anything here; the next call to
+ * IceProcessMessages() for this connection will receive
+ * IceProcessMessagesIOError and we can handle the error there.
+ */
+}
+
+static void
+sms_error_handler (SmsConn conn,
+ Bool swap,
+ int offending_minor_opcode,
+ unsigned long offending_sequence_num,
+ int error_class,
+ int severity,
+ IcePointer values)
+{
+ g_debug ("sms_error_handler (%p, %s, %d, %lx, %d, %d)",
+ conn, swap ? "TRUE" : "FALSE", offending_minor_opcode,
+ offending_sequence_num, error_class, severity);
+
+ /* We don't need to do anything here; if the connection needs to be
+ * closed, libSM will do that itself.
+ */
+}
+
+static IceAuthFileEntry *
+auth_entry_new (const char *protocol,
+ const char *network_id)
+{
+ IceAuthFileEntry *file_entry;
+ IceAuthDataEntry data_entry;
+
+ file_entry = malloc (sizeof (IceAuthFileEntry));
+
+ file_entry->protocol_name = strdup (protocol);
+ file_entry->protocol_data = NULL;
+ file_entry->protocol_data_length = 0;
+ file_entry->network_id = strdup (network_id);
+ file_entry->auth_name = strdup (GSM_ICE_MAGIC_COOKIE_AUTH_NAME);
+ file_entry->auth_data = IceGenerateMagicCookie (GSM_ICE_MAGIC_COOKIE_LEN);
+ file_entry->auth_data_length = GSM_ICE_MAGIC_COOKIE_LEN;
+
+ /* Also create an in-memory copy, which is what the server will
+ * actually use for checking client auth.
+ */
+ data_entry.protocol_name = file_entry->protocol_name;
+ data_entry.network_id = file_entry->network_id;
+ data_entry.auth_name = file_entry->auth_name;
+ data_entry.auth_data = file_entry->auth_data;
+ data_entry.auth_data_length = file_entry->auth_data_length;
+ IceSetPaAuthData (1, &data_entry);
+
+ return file_entry;
+}
+
+static gboolean
+update_iceauthority (GsmXsmpServer *server,
+ gboolean adding)
+{
+ char *filename;
+ char **our_network_ids;
+ FILE *fp;
+ IceAuthFileEntry *auth_entry;
+ GSList *entries;
+ GSList *e;
+ int i;
+ gboolean ok = FALSE;
+
+ filename = IceAuthFileName ();
+ if (IceLockAuthFile (filename,
+ GSM_ICE_AUTH_RETRIES,
+ GSM_ICE_AUTH_INTERVAL,
+ GSM_ICE_AUTH_LOCK_TIMEOUT) != IceAuthLockSuccess) {
+ return FALSE;
+ }
+
+ our_network_ids = g_malloc (server->priv->num_local_xsmp_sockets * sizeof (char *));
+ for (i = 0; i < server->priv->num_local_xsmp_sockets; i++) {
+ our_network_ids[i] = IceGetListenConnectionString (server->priv->xsmp_sockets[i]);
+ }
+
+ entries = NULL;
+
+ fp = fopen (filename, "r+");
+ if (fp != NULL) {
+ while ((auth_entry = IceReadAuthFileEntry (fp)) != NULL) {
+ /* Skip/delete entries with no network ID (invalid), or with
+ * our network ID; if we're starting up, an entry with our
+ * ID must be a stale entry left behind by an old process,
+ * and if we're shutting down, it won't be valid in the
+ * future, so either way we want to remove it from the list.
+ */
+ if (!auth_entry->network_id) {
+ IceFreeAuthFileEntry (auth_entry);
+ continue;
+ }
+
+ for (i = 0; i < server->priv->num_local_xsmp_sockets; i++) {
+ if (!strcmp (auth_entry->network_id, our_network_ids[i])) {
+ IceFreeAuthFileEntry (auth_entry);
+ break;
+ }
+ }
+ if (i != server->priv->num_local_xsmp_sockets) {
+ continue;
+ }
+
+ entries = g_slist_prepend (entries, auth_entry);
+ }
+
+ rewind (fp);
+ } else {
+ int fd;
+
+ if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
+ g_warning ("Unable to read ICE authority file: %s", filename);
+ goto cleanup;
+ }
+
+ fd = open (filename, O_CREAT | O_WRONLY, 0600);
+ fp = fdopen (fd, "w");
+ if (!fp) {
+ g_warning ("Unable to write to ICE authority file: %s", filename);
+ if (fd != -1) {
+ close (fd);
+ }
+ goto cleanup;
+ }
+ }
+
+ if (adding) {
+ for (i = 0; i < server->priv->num_local_xsmp_sockets; i++) {
+ entries = g_slist_append (entries,
+ auth_entry_new ("ICE", our_network_ids[i]));
+ entries = g_slist_prepend (entries,
+ auth_entry_new ("XSMP", our_network_ids[i]));
+ }
+ }
+
+ for (e = entries; e; e = e->next) {
+ IceAuthFileEntry *auth_entry = e->data;
+ IceWriteAuthFileEntry (fp, auth_entry);
+ IceFreeAuthFileEntry (auth_entry);
+ }
+ g_slist_free (entries);
+
+ fclose (fp);
+ ok = TRUE;
+
+ cleanup:
+ IceUnlockAuthFile (filename);
+ for (i = 0; i < server->priv->num_local_xsmp_sockets; i++) {
+ free (our_network_ids[i]);
+ }
+ g_free (our_network_ids);
+
+ return ok;
+}
+
+
+static void
+setup_listener (GsmXsmpServer *server)
+{
+ char error[256];
+ mode_t saved_umask;
+ char *network_id_list;
+ int i;
+ int res;
+
+ /* Set up sane error handlers */
+ IceSetErrorHandler (ice_error_handler);
+ IceSetIOErrorHandler (ice_io_error_handler);
+ SmsSetErrorHandler (sms_error_handler);
+
+ /* Initialize libSM; we pass NULL for hostBasedAuthProc to disable
+ * host-based authentication.
+ */
+ res = SmsInitialize (PACKAGE,
+ VERSION,
+ (SmsNewClientProc)accept_xsmp_connection,
+ server,
+ NULL,
+ sizeof (error),
+ error);
+ if (! res) {
+ gsm_util_init_error (TRUE, "Could not initialize libSM: %s", error);
+ }
+
+#ifdef HAVE_X11_XTRANS_XTRANS_H
+ /* By default, IceListenForConnections will open one socket for each
+ * transport type known to X. We don't want connections from remote
+ * hosts, so for security reasons it would be best if ICE didn't
+ * even open any non-local sockets. So we use an internal ICElib
+ * method to disable them here. Unfortunately, there is no way to
+ * ask X what transport types it knows about, so we're forced to
+ * guess.
+ */
+ _IceTransNoListen ("tcp");
+#endif
+
+ /* Create the XSMP socket. Older versions of IceListenForConnections
+ * have a bug which causes the umask to be set to 0 on certain types
+ * of failures. Probably not an issue on any modern systems, but
+ * we'll play it safe.
+ */
+ saved_umask = umask (0);
+ umask (saved_umask);
+ res = IceListenForConnections (&server->priv->num_xsmp_sockets,
+ &server->priv->xsmp_sockets,
+ sizeof (error),
+ error);
+ if (! res) {
+ gsm_util_init_error (TRUE, _("Could not create ICE listening socket: %s"), error);
+ }
+
+ umask (saved_umask);
+
+ /* Find the local sockets in the returned socket list and move them
+ * to the start of the list.
+ */
+ for (i = server->priv->num_local_xsmp_sockets = 0; i < server->priv->num_xsmp_sockets; i++) {
+ char *id = IceGetListenConnectionString (server->priv->xsmp_sockets[i]);
+
+ if (!strncmp (id, "local/", sizeof ("local/") - 1) ||
+ !strncmp (id, "unix/", sizeof ("unix/") - 1)) {
+ if (i > server->priv->num_local_xsmp_sockets) {
+ IceListenObj tmp;
+ tmp = server->priv->xsmp_sockets[i];
+ server->priv->xsmp_sockets[i] = server->priv->xsmp_sockets[server->priv->num_local_xsmp_sockets];
+ server->priv->xsmp_sockets[server->priv->num_local_xsmp_sockets] = tmp;
+ }
+ server->priv->num_local_xsmp_sockets++;
+ }
+ free (id);
+ }
+
+ if (server->priv->num_local_xsmp_sockets == 0) {
+ gsm_util_init_error (TRUE, "IceListenForConnections did not return a local listener!");
+ }
+
+#ifdef HAVE_X11_XTRANS_XTRANS_H
+ if (server->priv->num_local_xsmp_sockets != server->priv->num_xsmp_sockets) {
+ /* Xtrans was apparently compiled with support for some
+ * non-local transport besides TCP (which we disabled above); we
+ * won't create IO watches on those extra sockets, so
+ * connections to them will never be noticed, but they're still
+ * there, which is inelegant.
+ *
+ * If the g_warning below is triggering for you and you want to
+ * stop it, the fix is to add additional _IceTransNoListen()
+ * calls above.
+ */
+ network_id_list = IceComposeNetworkIdList (server->priv->num_xsmp_sockets - server->priv->num_local_xsmp_sockets,
+ server->priv->xsmp_sockets + server->priv->num_local_xsmp_sockets);
+ g_warning ("IceListenForConnections returned %d non-local listeners: %s",
+ server->priv->num_xsmp_sockets - server->priv->num_local_xsmp_sockets,
+ network_id_list);
+ free (network_id_list);
+ }
+#endif
+
+ /* Update .ICEauthority with new auth entries for our socket */
+ if (!update_iceauthority (server, TRUE)) {
+ /* FIXME: is this really fatal? Hm... */
+ gsm_util_init_error (TRUE,
+ "Could not update ICEauthority file %s",
+ IceAuthFileName ());
+ }
+
+ network_id_list = IceComposeNetworkIdList (server->priv->num_local_xsmp_sockets,
+ server->priv->xsmp_sockets);
+
+ g_setenv ("SESSION_MANAGER", network_id_list, TRUE);
+ g_debug ("SESSION_MANAGER=%s\n", network_id_list);
+ free (network_id_list);
+}
+
+static GObject *
+gsm_xsmp_server_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
+{
+ GsmXsmpServer *xsmp_server;
+
+ xsmp_server = GSM_XSMP_SERVER (G_OBJECT_CLASS (gsm_xsmp_server_parent_class)->constructor (type,
+ n_construct_properties,
+ construct_properties));
+ setup_listener (xsmp_server);
+
+ return G_OBJECT (xsmp_server);
+}
+
+static void
+gsm_xsmp_server_class_init (GsmXsmpServerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = gsm_xsmp_server_get_property;
+ object_class->set_property = gsm_xsmp_server_set_property;
+ object_class->constructor = gsm_xsmp_server_constructor;
+ object_class->finalize = gsm_xsmp_server_finalize;
+
+ g_object_class_install_property (object_class,
+ PROP_CLIENT_STORE,
+ g_param_spec_object ("client-store",
+ NULL,
+ NULL,
+ GSM_TYPE_CLIENT_STORE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ g_type_class_add_private (klass, sizeof (GsmXsmpServerPrivate));
+}
+
+static void
+gsm_xsmp_server_init (GsmXsmpServer *xsmp_server)
+{
+ xsmp_server->priv = GSM_XSMP_SERVER_GET_PRIVATE (xsmp_server);
+
+}
+
+static void
+gsm_xsmp_server_finalize (GObject *object)
+{
+ GsmXsmpServer *xsmp_server;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GSM_IS_XSMP_SERVER (object));
+
+ xsmp_server = GSM_XSMP_SERVER (object);
+
+ g_return_if_fail (xsmp_server->priv != NULL);
+
+ if (xsmp_server->priv->client_store != NULL) {
+ g_object_unref (xsmp_server->priv->client_store);
+ }
+
+ /* FIXME */
+
+ G_OBJECT_CLASS (gsm_xsmp_server_parent_class)->finalize (object);
+}
+
+GsmXsmpServer *
+gsm_xsmp_server_new (GsmClientStore *store)
+{
+ if (xsmp_server_object != NULL) {
+ g_object_ref (xsmp_server_object);
+ } else {
+ xsmp_server_object = g_object_new (GSM_TYPE_XSMP_SERVER,
+ "client-store", store,
+ NULL);
+
+ g_object_add_weak_pointer (xsmp_server_object,
+ (gpointer *) &xsmp_server_object);
+ }
+
+ return GSM_XSMP_SERVER (xsmp_server_object);
+}
Added: branches/dbus_based/gnome-session/gsm-xsmp-server.h
==============================================================================
--- (empty file)
+++ branches/dbus_based/gnome-session/gsm-xsmp-server.h Wed Jun 11 19:10:15 2008
@@ -0,0 +1,58 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 William Jon McCann <jmccann redhat com>
+ *
+ * This program 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.
+ *
+ * This program 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 __GSM_XSMP_SERVER_H
+#define __GSM_XSMP_SERVER_H
+
+#include <glib-object.h>
+
+#include "gsm-client-store.h"
+
+G_BEGIN_DECLS
+
+#define GSM_TYPE_XSMP_SERVER (gsm_xsmp_server_get_type ())
+#define GSM_XSMP_SERVER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSM_TYPE_XSMP_SERVER, GsmXsmpServer))
+#define GSM_XSMP_SERVER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSM_TYPE_XSMP_SERVER, GsmXsmpServerClass))
+#define GSM_IS_XSMP_SERVER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSM_TYPE_XSMP_SERVER))
+#define GSM_IS_XSMP_SERVER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSM_TYPE_XSMP_SERVER))
+#define GSM_XSMP_SERVER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSM_TYPE_XSMP_SERVER, GsmXsmpServerClass))
+
+typedef struct GsmXsmpServerPrivate GsmXsmpServerPrivate;
+
+typedef struct
+{
+ GObject parent;
+ GsmXsmpServerPrivate *priv;
+} GsmXsmpServer;
+
+typedef struct
+{
+ GObjectClass parent_class;
+} GsmXsmpServerClass;
+
+GType gsm_xsmp_server_get_type (void);
+
+GsmXsmpServer * gsm_xsmp_server_new (GsmClientStore *store);
+void gsm_xsmp_server_start (GsmXsmpServer *server);
+
+G_END_DECLS
+
+#endif /* __GSM_XSMP_SERVER_H */
Modified: branches/dbus_based/gnome-session/logout-dialog.c
==============================================================================
--- branches/dbus_based/gnome-session/logout-dialog.c (original)
+++ branches/dbus_based/gnome-session/logout-dialog.c Wed Jun 11 19:10:15 2008
@@ -29,8 +29,6 @@
#include <gtk/gtklabel.h>
#include <gtk/gtkstock.h>
-#include "gsm.h"
-#include "session.h"
#include "logout-dialog.h"
#include "power-manager.h"
#include "gdm.h"
@@ -45,7 +43,7 @@
struct _GsmLogoutDialogPrivate
{
- GsmSessionLogoutType type;
+ GsmDialogLogoutType type;
GsmPowerManager *power_manager;
@@ -210,7 +208,7 @@
switch (logout_dialog->priv->type)
{
- case GSM_SESSION_LOGOUT_TYPE_LOGOUT:
+ case GSM_DIALOG_LOGOUT_TYPE_LOGOUT:
secondary_text = ngettext ("You are currently logged in as "
"\"%s\".\n"
"You will be automatically logged "
@@ -222,7 +220,7 @@
seconds_to_show);
break;
- case GSM_SESSION_LOGOUT_TYPE_SHUTDOWN:
+ case GSM_DIALOG_LOGOUT_TYPE_SHUTDOWN:
secondary_text = ngettext ("You are currently logged in as "
"\"%s\".\n"
"This system will be automatically "
@@ -271,7 +269,7 @@
}
GtkWidget *
-gsm_get_logout_dialog (GsmSessionLogoutType type,
+gsm_get_logout_dialog (GsmDialogLogoutType type,
GdkScreen *screen,
guint32 activate_time)
{
@@ -297,7 +295,7 @@
switch (type)
{
- case GSM_SESSION_LOGOUT_TYPE_LOGOUT:
+ case GSM_DIALOG_LOGOUT_TYPE_LOGOUT:
icon_name = GSM_ICON_LOGOUT;
primary_text = N_("Log out of this system now?");
@@ -318,7 +316,7 @@
GSM_LOGOUT_RESPONSE_LOGOUT);
break;
- case GSM_SESSION_LOGOUT_TYPE_SHUTDOWN:
+ case GSM_DIALOG_LOGOUT_TYPE_SHUTDOWN:
icon_name = GSM_ICON_SHUTDOWN;
primary_text = N_("Shut down this system now?");
Modified: branches/dbus_based/gnome-session/logout-dialog.h
==============================================================================
--- branches/dbus_based/gnome-session/logout-dialog.h (original)
+++ branches/dbus_based/gnome-session/logout-dialog.h Wed Jun 11 19:10:15 2008
@@ -60,11 +60,16 @@
GtkMessageDialogClass parent_class;
};
-GType gsm_logout_dialog_get_type (void) G_GNUC_CONST;
+typedef enum {
+ GSM_DIALOG_LOGOUT_TYPE_LOGOUT,
+ GSM_DIALOG_LOGOUT_TYPE_SHUTDOWN
+} GsmDialogLogoutType;
-GtkWidget *gsm_get_logout_dialog (GsmSessionLogoutType type,
- GdkScreen *screen,
- guint32 activate_time);
+GType gsm_logout_dialog_get_type (void) G_GNUC_CONST;
+
+GtkWidget *gsm_get_logout_dialog (GsmDialogLogoutType type,
+ GdkScreen *screen,
+ guint32 activate_time);
G_END_DECLS
Modified: branches/dbus_based/gnome-session/main.c
==============================================================================
--- branches/dbus_based/gnome-session/main.c (original)
+++ branches/dbus_based/gnome-session/main.c Wed Jun 11 19:10:15 2008
@@ -1,8 +1,21 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * main.c: gnome-session startup
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2006 Novell, Inc.
+ *
+ * This program 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.
+ *
+ * This program 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 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.
*/
#ifdef HAVE_CONFIG_H
@@ -18,129 +31,155 @@
#include <gtk/gtkmain.h>
#include <gtk/gtkmessagedialog.h>
-#include "dbus.h"
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-bindings.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
#include "gconf.h"
-#include "gsm.h"
-#include "session.h"
#include "util.h"
-#include "xsmp.h"
-
-GsmSession *global_session;
+#include "gsm-manager.h"
+#include "gsm-xsmp-server.h"
+#include "gsm-client-store.h"
-static gboolean failsafe;
+static DBusGConnection *connection = NULL;
+static gboolean failsafe;
static GOptionEntry entries[] = {
- { "failsafe", 'f', 0, G_OPTION_ARG_NONE, &failsafe,
- N_("Do not load user-specified applications"),
- NULL },
- { NULL, 0, 0, 0, NULL, NULL, NULL }
+ { "failsafe", 'f', 0, G_OPTION_ARG_NONE, &failsafe,
+ N_("Do not load user-specified applications"),
+ NULL },
+ { NULL, 0, 0, 0, NULL, NULL, NULL }
};
-/**
- * gsm_initialization_error:
- * @fatal: whether or not the error is fatal to the login session
- * @format: printf-style error message format
- * @...: error message args
- *
- * Displays the error message to the user. If @fatal is %TRUE, gsm
- * will exit after displaying the message.
- *
- * This should be called for major errors that occur before the
- * session is up and running. (Notably, it positions the dialog box
- * itself, since no window manager will be running yet.)
- **/
-void
-gsm_initialization_error (gboolean fatal, const char *format, ...)
+static void
+gsm_dbus_init (void)
+{
+ char *argv[3];
+ char *output, **vars;
+ int status, i;
+ GError *error;
+
+ /* Check whether there is a dbus-daemon session instance currently
+ * running (not spawned by us).
+ */
+ if (g_getenv ("DBUS_SESSION_BUS_ADDRESS")) {
+ g_warning ("dbus-daemon is already running: processes launched by "
+ "D-Bus won't have access to $SESSION_MANAGER!");
+ return;
+ }
+
+ argv[0] = DBUS_LAUNCH;
+ argv[1] = "--exit-with-session";
+ argv[2] = NULL;
+
+ /* dbus-launch exits pretty quickly, but if necessary, we could
+ * make this async. (It's a little annoying since the main loop isn't
+ * running yet...)
+ */
+ error = NULL;
+ g_spawn_sync (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL,
+ &output, NULL, &status, &error);
+ if (error) {
+ gsm_util_init_error (TRUE, "Could not start dbus-daemon: %s",
+ error->message);
+ /* not reached */
+ }
+
+ vars = g_strsplit (output, "\n", 0);
+ for (i = 0; vars[i]; i++) {
+ putenv (vars[i]);
+ }
+
+ /* Can't free the putenv'ed strings */
+ g_free (vars);
+ g_free (output);
+}
+
+static void
+gsm_dbus_check (void)
{
- GtkWidget *dialog;
- char *msg;
- va_list args;
-
- va_start (args, format);
- msg = g_strdup_vprintf (format, args);
- va_end (args);
-
- /* If option parsing failed, Gtk won't have been initialized... */
- if (!gdk_display_get_default ())
- {
- if (!gtk_init_check (NULL, NULL))
- {
- /* Oh well, no X for you! */
- g_printerr (_("Unable to start login session (and unable connect to the X server)"));
- g_printerr (msg);
- exit (1);
- }
- }
-
- dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE, "%s", msg);
-
- g_free (msg);
-
- gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
- gtk_dialog_run (GTK_DIALOG (dialog));
+ GError *error = NULL;
- gtk_widget_destroy (dialog);
+ connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+ if (!connection) {
+ gsm_util_init_error (TRUE, "Could not start D-Bus: %s",
+ error->message);
+ /* not reached */
+ }
- gtk_main_quit ();
+ dbus_connection_set_exit_on_disconnect (dbus_g_connection_get_connection (connection), FALSE);
}
int
main (int argc, char **argv)
{
- struct sigaction sa;
- GError *err = NULL;
- char *display_str;
-
- bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR);
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
- textdomain (GETTEXT_PACKAGE);
-
- sa.sa_handler = SIG_IGN;
- sa.sa_flags = 0;
- sigemptyset (&sa.sa_mask);
- sigaction (SIGPIPE, &sa, 0);
-
- gtk_init_with_args (&argc, &argv,
- (char *) _(" - the GNOME session manager"),
- entries, GETTEXT_PACKAGE,
- &err);
- if (err)
- gsm_initialization_error (TRUE, "%s", err->message);
-
- /* Set DISPLAY explicitly for all our children, in case --display
- * was specified on the command line.
- */
- display_str = gdk_get_display ();
- g_setenv ("DISPLAY", display_str, TRUE);
- g_free (display_str);
-
- /* Start up gconfd and dbus-daemon (in parallel) if they're not
- * already running. This requires us to initialize XSMP too, because
- * we want $SESSION_MANAGER to be set before launching dbus-daemon.
- */
- gsm_gconf_init ();
- gsm_xsmp_init ();
- gsm_dbus_init ();
-
- /* Now make sure they succeeded. (They'll call
- * gsm_initialization_error() if they failed.)
- */
- gsm_gconf_check ();
- gsm_dbus_check ();
-
- global_session = gsm_session_new (failsafe);
-
- gsm_xsmp_run ();
- gsm_dbus_run ();
-
- gsm_session_start (global_session);
-
- gtk_main ();
-
- gsm_xsmp_shutdown ();
- gsm_gconf_shutdown ();
- gsm_dbus_shutdown ();
+ struct sigaction sa;
+ GError *error;
+ char *display_str;
+ GsmManager *manager;
+ GsmClientStore *store;
+ GsmXsmpServer *xsmp_server;
+
+ bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ sa.sa_handler = SIG_IGN;
+ sa.sa_flags = 0;
+ sigemptyset (&sa.sa_mask);
+ sigaction (SIGPIPE, &sa, 0);
+
+ error = NULL;
+ gtk_init_with_args (&argc, &argv,
+ (char *) _(" - the GNOME session manager"),
+ entries, GETTEXT_PACKAGE,
+ &error);
+ if (error != NULL) {
+ gsm_util_init_error (TRUE, "%s", error->message);
+ }
+
+ /* Set DISPLAY explicitly for all our children, in case --display
+ * was specified on the command line.
+ */
+ display_str = gdk_get_display ();
+ g_setenv ("DISPLAY", display_str, TRUE);
+ g_free (display_str);
+
+ store = gsm_client_store_new ();
+
+ /* Start up gconfd and dbus-daemon (in parallel) if they're not
+ * already running. This requires us to initialize XSMP too, because
+ * we want $SESSION_MANAGER to be set before launching dbus-daemon.
+ */
+ gsm_gconf_init ();
+
+ xsmp_server = gsm_xsmp_server_new (store);
+
+ gsm_dbus_init ();
+
+ /* Now make sure they succeeded. (They'll call
+ * gsm_util_init_error() if they failed.)
+ */
+ gsm_gconf_check ();
+ gsm_dbus_check ();
+
+ manager = gsm_manager_new (store, failsafe);
+
+ gsm_xsmp_server_start (xsmp_server);
+ gsm_manager_start (manager);
+
+ gtk_main ();
+
+ if (xsmp_server != NULL) {
+ g_object_unref (xsmp_server);
+ }
+
+ gsm_gconf_shutdown ();
+
+ if (manager != NULL) {
+ g_object_unref (manager);
+ }
- return 0;
+ return 0;
}
Modified: branches/dbus_based/gnome-session/util.c
==============================================================================
--- branches/dbus_based/gnome-session/util.c (original)
+++ branches/dbus_based/gnome-session/util.c Wed Jun 11 19:10:15 2008
@@ -109,3 +109,108 @@
return TRUE;
}
+
+/**
+ * gsm_util_init_error:
+ * @fatal: whether or not the error is fatal to the login session
+ * @format: printf-style error message format
+ * @...: error message args
+ *
+ * Displays the error message to the user. If @fatal is %TRUE, gsm
+ * will exit after displaying the message.
+ *
+ * This should be called for major errors that occur before the
+ * session is up and running. (Notably, it positions the dialog box
+ * itself, since no window manager will be running yet.)
+ **/
+void
+gsm_util_init_error (gboolean fatal, const char *format, ...)
+{
+ GtkWidget *dialog;
+ char *msg;
+ va_list args;
+
+ va_start (args, format);
+ msg = g_strdup_vprintf (format, args);
+ va_end (args);
+
+ /* If option parsing failed, Gtk won't have been initialized... */
+ if (!gdk_display_get_default ())
+ {
+ if (!gtk_init_check (NULL, NULL))
+ {
+ /* Oh well, no X for you! */
+ g_printerr (_("Unable to start login session (and unable connect to the X server)"));
+ g_printerr (msg);
+ exit (1);
+ }
+ }
+
+ dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE, "%s", msg);
+
+ g_free (msg);
+
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+
+ gtk_widget_destroy (dialog);
+
+ gtk_main_quit ();
+}
+
+/**
+ * gsm_util_generate_client_id:
+ *
+ * Generates a new SM client ID.
+ *
+ * Return value: an SM client ID.
+ **/
+char *
+gsm_util_generate_client_id (void)
+{
+ static int sequence = -1;
+ static guint rand1 = 0, rand2 = 0;
+ static pid_t pid = 0;
+ struct timeval tv;
+
+ /* The XSMP spec defines the ID as:
+ *
+ * Version: "1"
+ * Address type and address:
+ * "1" + an IPv4 address as 8 hex digits
+ * "2" + a DECNET address as 12 hex digits
+ * "6" + an IPv6 address as 32 hex digits
+ * Time stamp: milliseconds since UNIX epoch as 13 decimal digits
+ * Process-ID type and process-ID:
+ * "1" + POSIX PID as 10 decimal digits
+ * Sequence number as 4 decimal digits
+ *
+ * XSMP client IDs are supposed to be globally unique: if
+ * SmsGenerateClientID() is unable to determine a network
+ * address for the machine, it gives up and returns %NULL.
+ * GNOME and KDE have traditionally used a fourth address
+ * format in this case:
+ * "0" + 16 random hex digits
+ *
+ * We don't even bother trying SmsGenerateClientID(), since the
+ * user's IP address is probably "192.168.1.*" anyway, so a random
+ * number is actually more likely to be globally unique.
+ */
+
+ if (!rand1)
+ {
+ rand1 = g_random_int ();
+ rand2 = g_random_int ();
+ pid = getpid ();
+ }
+
+ sequence = (sequence + 1) % 10000;
+ gettimeofday (&tv, NULL);
+ return g_strdup_printf ("10%.04x%.04x%.10lu%.3u%.10lu%.4d",
+ rand1, rand2,
+ (unsigned long) tv.tv_sec,
+ (unsigned) tv.tv_usec,
+ (unsigned long) pid,
+ sequence);
+}
Modified: branches/dbus_based/gnome-session/util.h
==============================================================================
--- branches/dbus_based/gnome-session/util.h (original)
+++ branches/dbus_based/gnome-session/util.h Wed Jun 11 19:10:15 2008
@@ -17,7 +17,7 @@
* 02111-1307, USA.
*/
-#ifndef __GSM_UTIL_H__
+#ifndef __GSM_UTIL_H__
#define __GSM_UTIL_H__
G_BEGIN_DECLS
@@ -28,6 +28,10 @@
gboolean gsm_util_text_is_blank (const char *str);
+void gsm_util_init_error (gboolean fatal,
+ const char *format, ...);
+char * gsm_util_generate_client_id (void);
+
G_END_DECLS
#endif /* __GSM_UTIL_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]