gnome-session r4731 - in branches/dbus_based: . gnome-session
- From: mccann svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-session r4731 - in branches/dbus_based: . gnome-session
- Date: Thu, 12 Jun 2008 21:23:31 +0000 (UTC)
Author: mccann
Date: Thu Jun 12 21:23:31 2008
New Revision: 4731
URL: http://svn.gnome.org/viewvc/gnome-session?rev=4731&view=rev
Log:
2008-06-12 William Jon McCann <jmccann redhat com>
* gnome-session/gsm-client-store.c (gsm_client_store_size),
(gsm_client_store_lookup), (_has_client_id),
(gsm_client_store_add), (gsm_client_store_set_locked),
(gsm_client_store_set_property), (gsm_client_store_get_property),
(gsm_client_store_class_init):
* gnome-session/gsm-client-store.h:
* gnome-session/gsm-client.c (gsm_client_set_status),
(gsm_client_set_client_id), (gsm_client_set_property),
(gsm_client_get_property), (_boolean_handled_accumulator),
(gsm_client_class_init), (gsm_client_get_client_id),
(gsm_client_stop), (gsm_client_manage_request),
(gsm_client_logout_request):
* gnome-session/gsm-client.h:
* gnome-session/gsm-manager.c (_find_by_client_id),
(app_condition_changed), (on_store_client_added),
(gsm_manager_set_client_store), (_stop_client), (manager_shutdown),
(_shutdown_client), (initiate_shutdown):
* gnome-session/gsm-marshal.list:
* gnome-session/gsm-xsmp-client.c (client_iochannel_watch),
(client_protocol_timeout), (find_property), (set_description),
(setup_connection), (gsm_xsmp_client_constructor),
(gsm_xsmp_client_init), (delete_property), (debug_print_property),
(set_properties_callback), (delete_properties_callback),
(get_properties_callback), (prop_to_command),
(xsmp_get_restart_command), (xsmp_get_discard_command),
(xsmp_get_autorestart), (xsmp_restart), (do_save_yourself),
(xsmp_save_yourself), (xsmp_save_yourself_phase2), (xsmp_interact),
(xsmp_shutdown_cancelled), (xsmp_stop),
(gsm_client_set_ice_connection), (gsm_xsmp_client_set_property),
(gsm_xsmp_client_get_property), (gsm_xsmp_client_finalize),
(gsm_xsmp_client_class_init), (gsm_xsmp_client_new),
(register_client_callback), (save_yourself_request_callback),
(save_yourself_phase2_request_callback),
(interact_request_callback), (interact_done_callback),
(save_yourself_done_callback), (close_connection_callback),
(gsm_xsmp_client_connect):
* gnome-session/gsm-xsmp-client.h:
* gnome-session/gsm-xsmp-server.c (accept_ice_connection):
Give the code another whacking.
Modified:
branches/dbus_based/ChangeLog
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
branches/dbus_based/gnome-session/gsm-client.h
branches/dbus_based/gnome-session/gsm-manager.c
branches/dbus_based/gnome-session/gsm-marshal.list
branches/dbus_based/gnome-session/gsm-xsmp-client.c
branches/dbus_based/gnome-session/gsm-xsmp-client.h
branches/dbus_based/gnome-session/gsm-xsmp-server.c
Modified: branches/dbus_based/gnome-session/gsm-client-store.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-client-store.c (original)
+++ branches/dbus_based/gnome-session/gsm-client-store.c Thu Jun 12 21:23:31 2008
@@ -38,6 +38,7 @@
struct GsmClientStorePrivate
{
GHashTable *clients;
+ gboolean locked;
};
enum {
@@ -46,11 +47,16 @@
LAST_SIGNAL
};
+enum {
+ PROP_0,
+ PROP_LOCKED,
+};
+
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);
+static void gsm_client_store_finalize (GObject *object);
G_DEFINE_TYPE (GsmClientStore, gsm_client_store, G_TYPE_OBJECT)
@@ -65,6 +71,12 @@
return ret;
}
+guint
+gsm_client_store_size (GsmClientStore *store)
+{
+ return g_hash_table_size (store->priv->clients);
+}
+
void
gsm_client_store_clear (GsmClientStore *store)
{
@@ -125,6 +137,21 @@
return client;
}
+GsmClient *
+gsm_client_store_lookup (GsmClientStore *store,
+ const char *id)
+{
+ GsmClient *client;
+
+ g_return_val_if_fail (store != NULL, NULL);
+ g_return_val_if_fail (id != NULL, NULL);
+
+ client = g_hash_table_lookup (store->priv->clients,
+ id);
+
+ return client;
+}
+
guint
gsm_client_store_foreach_remove (GsmClientStore *store,
GsmClientStoreFunc func,
@@ -142,22 +169,95 @@
return ret;
}
-void
+static gboolean
+_has_client_id (const char *id,
+ GsmClient *client,
+ gpointer user_data)
+{
+ const char *sm_id_a;
+ const char *sm_id_b;
+
+ sm_id_a = user_data;
+ sm_id_b = gsm_client_get_client_id (client);
+ if (sm_id_b == NULL) {
+ return FALSE;
+ }
+ return (strcmp (sm_id_a, sm_id_b) == 0);
+}
+
+gboolean
gsm_client_store_add (GsmClientStore *store,
GsmClient *client)
{
- char *id;
+ const char *id;
- g_return_if_fail (store != NULL);
- g_return_if_fail (client != NULL);
+ g_return_val_if_fail (store != NULL, FALSE);
+ g_return_val_if_fail (client != NULL, FALSE);
id = gsm_client_get_id (client);
+ /* If we're shutting down, we don't accept any new session
+ clients. */
+ if (store->priv->locked) {
+ return FALSE;
+ }
+
g_debug ("GsmClientStore: Adding client %s to store", id);
g_hash_table_insert (store->priv->clients,
- id,
+ g_strdup (id),
g_object_ref (client));
+
+ return TRUE;
+}
+
+static void
+gsm_client_store_set_locked (GsmClientStore *store,
+ gboolean locked)
+{
+ g_return_if_fail (GSM_IS_CLIENT_STORE (store));
+
+ store->priv->locked = locked;
+}
+
+static void
+gsm_client_store_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GsmClientStore *self;
+
+ self = GSM_CLIENT_STORE (object);
+
+ switch (prop_id) {
+ case PROP_LOCKED:
+ gsm_client_store_set_locked (self, g_value_get_boolean (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gsm_client_store_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GsmClientStore *self;
+
+ self = GSM_CLIENT_STORE (object);
+
+ switch (prop_id) {
+ case PROP_LOCKED:
+ g_value_set_boolean (value, self->priv->locked);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
}
static void
@@ -165,6 +265,8 @@
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->get_property = gsm_client_store_get_property;
+ object_class->set_property = gsm_client_store_set_property;
object_class->finalize = gsm_client_store_finalize;
signals [CLIENT_ADDED] =
@@ -187,6 +289,13 @@
g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE,
1, G_TYPE_STRING);
+ g_object_class_install_property (object_class,
+ PROP_LOCKED,
+ g_param_spec_boolean ("locked",
+ NULL,
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
g_type_class_add_private (klass, sizeof (GsmClientStorePrivate));
}
Modified: branches/dbus_based/gnome-session/gsm-client-store.h
==============================================================================
--- branches/dbus_based/gnome-session/gsm-client-store.h (original)
+++ branches/dbus_based/gnome-session/gsm-client-store.h Thu Jun 12 21:23:31 2008
@@ -49,7 +49,7 @@
void (* client_added) (GsmClientStore *client_store,
const char *id);
void (* client_removed) (GsmClientStore *client_store,
- const char *id);
+ const char *id);
} GsmClientStoreClass;
typedef enum
@@ -68,7 +68,8 @@
GsmClientStore * gsm_client_store_new (void);
-void gsm_client_store_add (GsmClientStore *store,
+guint gsm_client_store_size (GsmClientStore *store);
+gboolean gsm_client_store_add (GsmClientStore *store,
GsmClient *client);
void gsm_client_store_clear (GsmClientStore *store);
gboolean gsm_client_store_remove (GsmClientStore *store,
@@ -82,6 +83,8 @@
GsmClient * gsm_client_store_find (GsmClientStore *store,
GsmClientStoreFunc predicate,
gpointer user_data);
+GsmClient * gsm_client_store_lookup (GsmClientStore *store,
+ const char *id);
G_END_DECLS
Modified: branches/dbus_based/gnome-session/gsm-client.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-client.c (original)
+++ branches/dbus_based/gnome-session/gsm-client.c Thu Jun 12 21:23:31 2008
@@ -32,17 +32,27 @@
struct GsmClientPrivate
{
char *id;
+ char *client_id;
+ int status;
};
enum {
+ PROP_0,
+ PROP_ID,
+ PROP_CLIENT_ID,
+ PROP_STATUS,
+};
+
+enum {
+ MANAGE_REQUEST,
+ LOGOUT_REQUEST,
+
SAVED_STATE,
REQUEST_PHASE2,
REQUEST_INTERACTION,
INTERACTION_DONE,
SAVE_YOURSELF_DONE,
DISCONNECTED,
- REGISTER_CLIENT,
- REQUEST_LOGOUT,
LAST_SIGNAL
};
@@ -108,14 +118,122 @@
g_free (client->priv->id);
}
+void
+gsm_client_set_status (GsmClient *client,
+ int status)
+{
+ g_return_if_fail (GSM_IS_CLIENT (client));
+ if (client->priv->status != status) {
+ client->priv->status = status;
+ g_object_notify (G_OBJECT (client), "status");
+ }
+}
+
+static void
+gsm_client_set_client_id (GsmClient *client,
+ const char *client_id)
+{
+ g_return_if_fail (GSM_IS_CLIENT (client));
+
+ g_free (client->priv->client_id);
+
+ client->priv->client_id = g_strdup (client_id);
+ g_object_notify (G_OBJECT (client), "client-id");
+}
+
+static void
+gsm_client_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GsmClient *self;
+
+ self = GSM_CLIENT (object);
+
+ switch (prop_id) {
+ case PROP_CLIENT_ID:
+ gsm_client_set_client_id (self, g_value_get_string (value));
+ break;
+ case PROP_STATUS:
+ gsm_client_set_status (self, g_value_get_int (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gsm_client_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GsmClient *self;
+
+ self = GSM_CLIENT (object);
+
+ switch (prop_id) {
+ case PROP_CLIENT_ID:
+ g_value_set_string (value, self->priv->client_id);
+ break;
+ case PROP_STATUS:
+ g_value_set_int (value, self->priv->status);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static gboolean
+_boolean_handled_accumulator (GSignalInvocationHint *ihint,
+ GValue *return_accu,
+ const GValue *handler_return,
+ gpointer dummy)
+{
+ gboolean continue_emission;
+ gboolean signal_handled;
+
+ signal_handled = g_value_get_boolean (handler_return);
+ g_value_set_boolean (return_accu, signal_handled);
+ continue_emission = !signal_handled;
+
+ return continue_emission;
+}
+
static void
gsm_client_class_init (GsmClientClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->get_property = gsm_client_get_property;
+ object_class->set_property = gsm_client_set_property;
object_class->constructor = gsm_client_constructor;
object_class->finalize = gsm_client_finalize;
+ signals[MANAGE_REQUEST] =
+ g_signal_new ("manage-request",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsmClientClass, manage_request),
+ _boolean_handled_accumulator,
+ NULL,
+ gsm_marshal_BOOLEAN__POINTER,
+ G_TYPE_BOOLEAN,
+ 1, G_TYPE_POINTER);
+ signals[LOGOUT_REQUEST] =
+ g_signal_new ("logout-request",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsmClientClass, logout_request),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE,
+ 1, G_TYPE_BOOLEAN);
+
signals[SAVED_STATE] =
g_signal_new ("saved_state",
G_OBJECT_CLASS_TYPE (object_class),
@@ -175,24 +293,23 @@
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_object_class_install_property (object_class,
+ PROP_CLIENT_ID,
+ g_param_spec_string ("client-id",
+ "client-id",
+ "client-id",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+ g_object_class_install_property (object_class,
+ PROP_STATUS,
+ g_param_spec_uint ("status",
+ "status",
+ "status",
+ 0,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
g_type_class_add_private (klass, sizeof (GsmClientPrivate));
}
@@ -211,23 +328,7 @@
{
g_return_val_if_fail (GSM_IS_CLIENT (client), NULL);
- 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);
-
- 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);
-
- return GSM_CLIENT_GET_CLASS (client)->get_desktop_file (client);
+ return client->priv->client_id;
}
char *
@@ -302,11 +403,11 @@
}
void
-gsm_client_die (GsmClient *client)
+gsm_client_stop (GsmClient *client)
{
g_return_if_fail (GSM_IS_CLIENT (client));
- GSM_CLIENT_GET_CLASS (client)->die (client);
+ GSM_CLIENT_GET_CLASS (client)->stop (client);
}
void
@@ -345,17 +446,22 @@
g_signal_emit (client, signals[DISCONNECTED], 0);
}
-void
-gsm_client_register_client (GsmClient *client,
- const char *previous_id,
- char **id)
+
+gboolean
+gsm_client_manage_request (GsmClient *client,
+ char **client_idp)
{
- g_signal_emit (client, signals[REGISTER_CLIENT], 0, previous_id, id);
+ gboolean res;
+
+ res = FALSE;
+ g_signal_emit (client, signals[MANAGE_REQUEST], 0, client_idp, &res);
+
+ return res;
}
void
-gsm_client_request_logout (GsmClient *client,
- gboolean prompt)
+gsm_client_logout_request (GsmClient *client,
+ gboolean prompt)
{
- g_signal_emit (client, signals[REQUEST_LOGOUT], 0, prompt);
+ g_signal_emit (client, signals[LOGOUT_REQUEST], 0, prompt);
}
Modified: branches/dbus_based/gnome-session/gsm-client.h
==============================================================================
--- branches/dbus_based/gnome-session/gsm-client.h (original)
+++ branches/dbus_based/gnome-session/gsm-client.h Thu Jun 12 21:23:31 2008
@@ -38,6 +38,13 @@
typedef struct GsmClientPrivate GsmClientPrivate;
+typedef enum {
+ GSM_CLIENT_UNMANAGED = 0,
+ GSM_CLIENT_MANAGED,
+ GSM_CLIENT_FINISHED,
+ GSM_CLIENT_FAILED,
+} GsmClientStatus;
+
struct _GsmClient
{
GObject parent;
@@ -49,11 +56,11 @@
GObjectClass parent_class;
/* signals */
- void (*register_client) (GsmClient *client,
- const char *previous_id,
- char **id);
- void (*request_logout) (GsmClient *client,
- gboolean prompt);
+ gboolean (*manage_request) (GsmClient *client,
+ char **client_id);
+ gboolean (*logout_request) (GsmClient *client,
+ gboolean prompt);
+
void (*saved_state) (GsmClient *client);
@@ -68,9 +75,9 @@
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);
+ void (*stop) (GsmClient *client);
+
+
char * (*get_restart_command) (GsmClient *client);
char * (*get_discard_command) (GsmClient *client);
gboolean (*get_autorestart) (GsmClient *client);
@@ -82,46 +89,52 @@
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);
+const char *gsm_client_get_id (GsmClient *client);
+const char *gsm_client_get_client_id (GsmClient *client);
+int gsm_client_get_status (GsmClient *client);
+void gsm_client_set_status (GsmClient *client,
+ int status);
+
+gboolean gsm_client_manage (GsmClient *client,
+ const char *client_id);
+void gsm_client_stop (GsmClient *client);
-pid_t gsm_client_get_pid (GsmClient *client);
-char *gsm_client_get_desktop_file (GsmClient *client);
-char *gsm_client_get_restart_command (GsmClient *client);
-char *gsm_client_get_discard_command (GsmClient *client);
-gboolean gsm_client_get_autorestart (GsmClient *client);
-
-void gsm_client_save_state (GsmClient *client);
-
-void gsm_client_restart (GsmClient *client,
- GError **error);
-void gsm_client_save_yourself (GsmClient *client,
- gboolean save_state);
-void gsm_client_save_yourself_phase2 (GsmClient *client);
-void gsm_client_interact (GsmClient *client);
-void gsm_client_shutdown_cancelled (GsmClient *client);
-void gsm_client_die (GsmClient *client);
-/* protected */
-void gsm_client_saved_state (GsmClient *client);
-void gsm_client_request_phase2 (GsmClient *client);
-void gsm_client_request_interaction (GsmClient *client);
-void gsm_client_interaction_done (GsmClient *client,
- 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 *gsm_client_get_restart_command (GsmClient *client);
+char *gsm_client_get_discard_command (GsmClient *client);
+gboolean gsm_client_get_autorestart (GsmClient *client);
+
+void gsm_client_save_state (GsmClient *client);
+
+void gsm_client_restart (GsmClient *client,
+ GError **error);
+void gsm_client_save_yourself (GsmClient *client,
+ gboolean save_state);
+void gsm_client_save_yourself_phase2 (GsmClient *client);
+void gsm_client_interact (GsmClient *client);
+void gsm_client_shutdown_cancelled (GsmClient *client);
+
+/* protected */
+gboolean gsm_client_manage_request (GsmClient *client,
char **id);
-void gsm_client_request_logout (GsmClient *client,
+void gsm_client_logout_request (GsmClient *client,
gboolean prompt);
+
+void gsm_client_saved_state (GsmClient *client);
+void gsm_client_request_phase2 (GsmClient *client);
+void gsm_client_request_interaction (GsmClient *client);
+void gsm_client_interaction_done (GsmClient *client,
+ gboolean cancel_shutdown);
+void gsm_client_save_yourself_done (GsmClient *client);
+void gsm_client_disconnected (GsmClient *client);
+
+
G_END_DECLS
#endif /* __GSM_CLIENT_H__ */
Modified: branches/dbus_based/gnome-session/gsm-manager.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-manager.c (original)
+++ branches/dbus_based/gnome-session/gsm-manager.c Thu Jun 12 21:23:31 2008
@@ -78,8 +78,6 @@
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
@@ -141,24 +139,31 @@
return ret;
}
+static gboolean
+_find_by_client_id (const char *id,
+ GsmClient *client,
+ const char *client_id_a)
+{
+ const char *client_id_b;
+
+ client_id_b = gsm_client_get_client_id (client);
+ if (client_id_b == NULL) {
+ return FALSE;
+ }
+
+ return (strcmp (client_id_a, client_id_b) == 0);
+}
+
static void
app_condition_changed (GsmApp *app,
gboolean condition,
GsmManager *manager)
{
- GsmClient *client;
- GSList *cl;
-
- client = NULL;
+ GsmClient *client;
- /* 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;
- }
- }
+ client = gsm_client_store_find (manager->priv->store,
+ (GsmClientStoreFunc)_find_by_client_id,
+ app->client_id);
if (condition) {
GError *error = NULL;
@@ -178,7 +183,11 @@
* 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);
+
+ /* FIXME: this should probably do gsm_app_stop
+ */
+
+ gsm_client_stop (client);
app->pid = -1;
}
}
@@ -412,6 +421,14 @@
}
static void
+on_store_client_added (GsmClientStore *store,
+ const char *id,
+ GsmManager *manager)
+{
+ g_debug ("GsmManager: Client added: %s", id);
+}
+
+static void
gsm_manager_set_client_store (GsmManager *manager,
GsmClientStore *store)
{
@@ -422,10 +439,21 @@
}
if (manager->priv->store != NULL) {
+ g_signal_handlers_disconnect_by_func (manager->priv->store,
+ on_store_client_added,
+ manager);
+
g_object_unref (manager->priv->store);
}
manager->priv->store = store;
+
+ if (manager->priv->store != NULL) {
+ g_signal_connect (manager->priv->store,
+ "client-added",
+ G_CALLBACK (on_store_client_added),
+ manager);
+ }
}
static void
@@ -945,18 +973,26 @@
return TRUE;
}
+static gboolean
+_stop_client (const char *id,
+ GsmClient *client,
+ gpointer data)
+{
+ gsm_client_stop (client);
+
+ return FALSE;
+}
+
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);
- }
+ gsm_client_store_foreach (manager->priv->store,
+ (GsmClientStoreFunc)_stop_client,
+ NULL);
switch (manager->priv->logout_response_id) {
case GSM_LOGOUT_RESPONSE_SHUTDOWN:
@@ -971,24 +1007,30 @@
}
}
+static gboolean
+_shutdown_client (const char *id,
+ GsmClient *client,
+ GsmManager *manager)
+{
+ manager->priv->shutdown_clients = g_slist_prepend (manager->priv->shutdown_clients, client);
+
+ gsm_client_save_yourself (client, FALSE);
+
+ return FALSE;
+}
+
static void
initiate_shutdown (GsmManager *manager)
{
- GSList *cl;
-
manager->priv->phase = GSM_MANAGER_PHASE_SHUTDOWN;
- if (manager->priv->clients == NULL) {
+ if (gsm_client_store_size (manager->priv->store) == 0) {
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);
- }
+ gsm_client_store_foreach (manager->priv->store,
+ (GsmClientStoreFunc)_shutdown_client,
+ NULL);
}
static void
Modified: branches/dbus_based/gnome-session/gsm-marshal.list
==============================================================================
--- branches/dbus_based/gnome-session/gsm-marshal.list (original)
+++ branches/dbus_based/gnome-session/gsm-marshal.list Thu Jun 12 21:23:31 2008
@@ -1 +1 @@
-STRING:STRING
+BOOLEAN:POINTER
Modified: branches/dbus_based/gnome-session/gsm-xsmp-client.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-xsmp-client.c (original)
+++ branches/dbus_based/gnome-session/gsm-xsmp-client.c Thu Jun 12 21:23:31 2008
@@ -35,134 +35,49 @@
/* FIXME */
#define GsmDesktopFile "_Gsm_DesktopFile"
-static gboolean client_iochannel_watch (GIOChannel *channel,
- GIOCondition condition,
- gpointer data);
-static gboolean client_protocol_timeout (gpointer data);
-
-static void set_description (GsmXSMPClient *xsmp);
-
-static const char *xsmp_get_client_id (GsmClient *client);
-static pid_t xsmp_get_pid (GsmClient *client);
-static char *xsmp_get_desktop_file (GsmClient *client);
-static char *xsmp_get_restart_command (GsmClient *client);
-static char *xsmp_get_discard_command (GsmClient *client);
-static gboolean xsmp_get_autorestart (GsmClient *client);
-
-static void xsmp_finalize (GObject *object);
-static void xsmp_restart (GsmClient *client,
- GError **error);
-static void xsmp_save_yourself (GsmClient *client,
- 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);
+#define GSM_XSMP_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_XSMP_CLIENT, GsmXSMPClientPrivate))
-G_DEFINE_TYPE (GsmXSMPClient, gsm_xsmp_client, GSM_TYPE_CLIENT)
-
-static void
-gsm_xsmp_client_init (GsmXSMPClient *xsmp)
-{
- ;
-}
-
-static void
-gsm_xsmp_client_class_init (GsmXSMPClientClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GsmClientClass *client_class = GSM_CLIENT_CLASS (klass);
-
- 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->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;
-}
-
-GsmXSMPClient *
-gsm_xsmp_client_new (IceConn ice_conn)
-{
- GsmXSMPClient *xsmp;
- GIOChannel *channel;
- int fd;
-
- 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;
-
- 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);
-
- xsmp->protocol_timeout = g_timeout_add (5000, client_protocol_timeout, xsmp);
-
- set_description (xsmp);
- g_debug ("New client '%s'", xsmp->description);
-
- return xsmp;
-}
-
-static void
-xsmp_finalize (GObject *object)
+struct GsmXSMPClientPrivate
{
- GsmXSMPClient *xsmp = (GsmXSMPClient *) object;
- g_debug ("xsmp_finalize (%s)", xsmp->description);
+ SmsConn conn;
+ IceConn ice_connection;
- if (xsmp->watch_id) {
- g_source_remove (xsmp->watch_id);
- }
+ guint watch_id;
+ guint protocol_timeout;
- if (xsmp->conn) {
- SmsCleanUp (xsmp->conn);
- } else {
- IceCloseConnection (xsmp->ice_conn);
- }
+ int current_save_yourself;
+ int next_save_yourself;
+ char *id;
+ char *description;
+ GPtrArray *props;
+};
- if (xsmp->protocol_timeout)
- g_source_remove (xsmp->protocol_timeout);
+enum {
+ PROP_0,
+ PROP_ICE_CONNECTION,
+};
- G_OBJECT_CLASS (gsm_xsmp_client_parent_class)->finalize (object);
-}
+G_DEFINE_TYPE (GsmXSMPClient, gsm_xsmp_client, GSM_TYPE_CLIENT)
static gboolean
-client_iochannel_watch (GIOChannel *channel,
- GIOCondition condition,
- gpointer data)
+client_iochannel_watch (GIOChannel *channel,
+ GIOCondition condition,
+ GsmXSMPClient *client)
{
- GsmClient *client = data;
- GsmXSMPClient *xsmp = data;
- switch (IceProcessMessages (xsmp->ice_conn, NULL, NULL)) {
+ switch (IceProcessMessages (client->priv->ice_connection, NULL, NULL)) {
case IceProcessMessagesSuccess:
return TRUE;
case IceProcessMessagesIOError:
- g_debug ("IceProcessMessagesIOError on '%s'", xsmp->description);
- gsm_client_disconnected (client);
+ g_debug ("IceProcessMessagesIOError on '%s'", client->priv->description);
+ gsm_client_disconnected (GSM_CLIENT (client));
return FALSE;
case IceProcessMessagesConnectionClosed:
g_debug ("IceProcessMessagesConnectionClosed on '%s'",
- xsmp->description);
+ client->priv->description);
return FALSE;
default:
@@ -174,319 +89,146 @@
* the XSMP protocol setup.
*/
static gboolean
-client_protocol_timeout (gpointer data)
+client_protocol_timeout (GsmXSMPClient *client)
{
- 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);
-
- return FALSE;
-}
-
-static Status
-register_client_callback (SmsConn conn,
- SmPointer manager_data,
- char *previous_id)
-{
- 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;
+ client->priv->description,
+ IceConnectionStatus (client->priv->ice_connection));
- free (previous_id);
- }
+ gsm_client_disconnected (GSM_CLIENT (client));
- return TRUE;
+ return FALSE;
}
-static void
-do_save_yourself (GsmXSMPClient *xsmp, int save_type)
+static SmProp *
+find_property (GsmXSMPClient *client,
+ const char *name,
+ int *index)
{
- 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;
+ SmProp *prop;
+ int i;
- switch (save_type) {
- case SmSaveLocal:
- /* Save state */
- SmsSaveYourself (xsmp->conn, SmSaveLocal, FALSE,
- SmInteractStyleNone, FALSE);
- break;
+ for (i = 0; i < client->priv->props->len; i++) {
+ prop = client->priv->props->pdata[i];
- default:
- /* Logout */
- SmsSaveYourself (xsmp->conn, save_type, TRUE,
- SmInteractStyleAny, FALSE);
- break;
+ if (!strcmp (prop->name, name)) {
+ if (index) {
+ *index = i;
+ }
+ return prop;
}
}
+
+ return NULL;
}
static void
-save_yourself_request_callback (SmsConn conn,
- SmPointer manager_data,
- int save_type,
- Bool shutdown,
- int interact_style,
- Bool fast,
- Bool global)
+set_description (GsmXSMPClient *client)
{
- 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");
+ SmProp *prop;
+ const char *id;
- /* 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).
- */
+ prop = find_property (client, SmProgram, NULL);
+ id = gsm_client_get_client_id (GSM_CLIENT (client));
- 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);
+ g_free (client->priv->description);
+ if (prop) {
+ client->priv->description = g_strdup_printf ("%p [%.*s %s]",
+ client,
+ prop->vals[0].length,
+ (char *)prop->vals[0].value,
+ id);
+ } else if (id != NULL) {
+ client->priv->description = g_strdup_printf ("%p [%s]", client, id);
} else {
- g_debug (" ignoring");
+ client->priv->description = g_strdup_printf ("%p", client);
}
}
static void
-xsmp_restart (GsmClient *client, GError **error)
-{
- char *restart_cmd = gsm_client_get_restart_command (client);
-
- g_spawn_command_line_async (restart_cmd, error);
-
- g_free (restart_cmd);
-}
-
-static void
-xsmp_save_yourself (GsmClient *client, gboolean save_state)
-{
- GsmXSMPClient *xsmp = (GsmXSMPClient *)client;
-
- g_debug ("xsmp_save_yourself ('%s', %s)", xsmp->description,
- save_state ? "True" : "False");
-
- do_save_yourself (xsmp, save_state ? SmSaveBoth : SmSaveGlobal);
-}
-
-static void
-save_yourself_phase2_request_callback (SmsConn conn,
- SmPointer manager_data)
-{
- GsmClient *client = manager_data;
- GsmXSMPClient *xsmp = manager_data;
-
- 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);
-}
-
-static void
-xsmp_save_yourself_phase2 (GsmClient *client)
-{
- GsmXSMPClient *xsmp = (GsmXSMPClient *)client;
-
- g_debug ("xsmp_save_yourself_phase2 ('%s')", xsmp->description);
-
- SmsSaveYourselfPhase2 (xsmp->conn);
-}
-
-static void
-interact_request_callback (SmsConn conn,
- SmPointer manager_data,
- int dialog_type)
+setup_connection (GsmXSMPClient *client)
{
- GsmClient *client = manager_data;
- GsmXSMPClient *xsmp = manager_data;
+ GIOChannel *channel;
+ int fd;
- g_debug ("Client '%s' received InteractRequest(%s)", xsmp->description,
- dialog_type == SmInteractStyleAny ? "Any" : "Errors");
-
- gsm_client_request_interaction (client);
-}
-
-static void
-xsmp_interact (GsmClient *client)
-{
- GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
+ fd = IceConnectionNumber (client->priv->ice_connection);
+ fcntl (fd, F_SETFD, fcntl (fd, F_GETFD, 0) | FD_CLOEXEC);
+ channel = g_io_channel_unix_new (fd);
+ client->priv->watch_id = g_io_add_watch (channel,
+ G_IO_IN | G_IO_ERR,
+ (GIOFunc)client_iochannel_watch,
+ client);
+ g_io_channel_unref (channel);
- g_debug ("xsmp_interact ('%s')", xsmp->description);
+ client->priv->protocol_timeout = g_timeout_add (5000,
+ (GSourceFunc)client_protocol_timeout,
+ client);
- SmsInteract (xsmp->conn);
+ set_description (client);
+ g_debug ("New client '%s'", client->priv->description);
}
-static void
-interact_done_callback (SmsConn conn,
- SmPointer manager_data,
- Bool cancel_shutdown)
+static GObject *
+gsm_xsmp_client_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
{
- GsmClient *client = manager_data;
- GsmXSMPClient *xsmp = manager_data;
+ GsmXSMPClient *client;
- g_debug ("Client '%s' received InteractDone(cancel_shutdown = %s)",
- xsmp->description, cancel_shutdown ? "True" : "False");
+ client = GSM_XSMP_CLIENT (G_OBJECT_CLASS (gsm_xsmp_client_parent_class)->constructor (type,
+ n_construct_properties,
+ construct_properties));
+ setup_connection (client);
- gsm_client_interaction_done (client, cancel_shutdown);
+ return G_OBJECT (client);
}
static void
-xsmp_shutdown_cancelled (GsmClient *client)
+gsm_xsmp_client_init (GsmXSMPClient *client)
{
- GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
+ client->priv = GSM_XSMP_CLIENT_GET_PRIVATE (client);
- g_debug ("xsmp_shutdown_cancelled ('%s')", xsmp->description);
-
- SmsShutdownCancelled (xsmp->conn);
+ client->priv->props = g_ptr_array_new ();
+ client->priv->current_save_yourself = -1;
+ client->priv->next_save_yourself = -1;
}
-static void
-xsmp_die (GsmClient *client)
-{
- GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
-
- g_debug ("xsmp_die ('%s')", xsmp->description);
-
- SmsDie (xsmp->conn);
-}
static void
-save_yourself_done_callback (SmsConn conn,
- SmPointer manager_data,
- Bool success)
+delete_property (GsmXSMPClient *client,
+ const char *name)
{
- GsmClient *client = manager_data;
- GsmXSMPClient *xsmp = manager_data;
-
- 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;
+ int index;
+ SmProp *prop;
- xsmp->next_save_yourself = -1;
- do_save_yourself (xsmp, save_type);
+ prop = find_property (client, name, &index);
+ if (!prop) {
+ return;
}
-}
-
-static void
-close_connection_callback (SmsConn conn,
- 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]);
+#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 (GSM_CLIENT (client));
}
- SmFreeReasons (count, reason_msgs);
+#endif
- gsm_client_disconnected (client);
+ g_ptr_array_remove_index_fast (client->priv->props, index);
+ SmFreeProperty (prop);
}
+
static void
debug_print_property (SmProp *prop)
{
GString *tmp;
- int i;
+ int i;
switch (prop->type[0]) {
case 'C': /* CARD8 */
@@ -513,53 +255,6 @@
}
}
-static SmProp *
-find_property (GsmXSMPClient *client, const char *name, int *index)
-{
- SmProp *prop;
- int 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;
- }
- }
-
- return NULL;
-}
-
-static void
-delete_property (GsmXSMPClient *client, const char *name)
-{
- int index;
- SmProp *prop;
-
- 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);
- }
-#endif
-
- g_ptr_array_remove_index_fast (client->props, index);
- SmFreeProperty (prop);
-}
static void
set_properties_callback (SmsConn conn,
@@ -568,13 +263,13 @@
SmProp **props)
{
GsmXSMPClient *client = manager_data;
- int i;
+ int i;
- g_debug ("Set properties from client '%s'", client->description);
+ g_debug ("Set properties from client '%s'", client->priv->description);
for (i = 0; i < num_props; i++) {
delete_property (client, props[i]->name);
- g_ptr_array_add (client->props, props[i]);
+ g_ptr_array_add (client->priv->props, props[i]);
debug_print_property (props[i]);
@@ -595,7 +290,7 @@
GsmXSMPClient *client = manager_data;
int i;
- g_debug ("Delete properties from '%s'", client->description);
+ g_debug ("Delete properties from '%s'", client->priv->description);
for (i = 0; i < num_props; i++) {
delete_property (client, prop_names[i]);
@@ -612,47 +307,11 @@
{
GsmXSMPClient *client = manager_data;
- g_debug ("Get properties request from '%s'", client->description);
-
- SmsReturnProperties (conn, client->props->len,
- (SmProp **)client->props->pdata);
-}
-
-static const char *
-xsmp_get_client_id (GsmClient *client)
-{
- GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
-
- return xsmp->id;
-}
-
-static pid_t
-xsmp_get_pid (GsmClient *client)
-{
- 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;
- }
+ g_debug ("Get properties request from '%s'", client->priv->description);
- /* 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)
-{
- GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
- SmProp *prop = find_property (xsmp, GsmDesktopFile, NULL);
-
- if (!prop || strcmp (prop->type, SmARRAY8) != 0) {
- return NULL;
- }
-
- return g_strndup (prop->vals[0].value, prop->vals[0].length);
+ SmsReturnProperties (conn,
+ client->priv->props->len,
+ (SmProp **)client->priv->props->pdata);
}
static char *
@@ -679,7 +338,9 @@
}
if (!need_quotes) {
- g_string_append_printf (str, "%.*s", prop->vals[i].length,
+ g_string_append_printf (str,
+ "%.*s",
+ prop->vals[i].length,
(char *)prop->vals[i].value);
} else {
g_string_append_c (str, '\'');
@@ -701,8 +362,9 @@
static char *
xsmp_get_restart_command (GsmClient *client)
{
- GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
- SmProp *prop = find_property (xsmp, SmRestartCommand, NULL);
+ SmProp *prop;
+
+ prop = find_property (GSM_XSMP_CLIENT (client), SmRestartCommand, NULL);
if (!prop || strcmp (prop->type, SmLISTofARRAY8) != 0) {
return NULL;
@@ -714,8 +376,9 @@
static char *
xsmp_get_discard_command (GsmClient *client)
{
- GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
- SmProp *prop = find_property (xsmp, SmDiscardCommand, NULL);
+ SmProp *prop;
+
+ prop = find_property (GSM_XSMP_CLIENT (client), SmDiscardCommand, NULL);
if (!prop || strcmp (prop->type, SmLISTofARRAY8) != 0) {
return NULL;
@@ -727,8 +390,9 @@
static gboolean
xsmp_get_autorestart (GsmClient *client)
{
- GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
- SmProp *prop = find_property (xsmp, SmRestartStyleHint, NULL);
+ SmProp *prop;
+
+ prop = find_property (GSM_XSMP_CLIENT (client), SmRestartStyleHint, NULL);
if (!prop || strcmp (prop->type, SmCARD8) != 0) {
return FALSE;
@@ -738,21 +402,436 @@
}
static void
-set_description (GsmXSMPClient *client)
+xsmp_restart (GsmClient *client,
+ GError **error)
{
- SmProp *prop = find_property (client, SmProgram, NULL);
+ char *restart_cmd;
- 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);
+ restart_cmd = gsm_client_get_restart_command (client);
+
+ g_spawn_command_line_async (restart_cmd, error);
+
+ g_free (restart_cmd);
+}
+
+static void
+do_save_yourself (GsmXSMPClient *client,
+ int save_type)
+{
+ if (client->priv->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'",
+ client->priv->description);
+ } else if (client->priv->current_save_yourself != -1) {
+ g_debug (" queuing new SaveYourself for '%s'",
+ client->priv->description);
+ client->priv->next_save_yourself = save_type;
+ } else {
+ client->priv->current_save_yourself = save_type;
+
+ switch (save_type) {
+ case SmSaveLocal:
+ /* Save state */
+ SmsSaveYourself (client->priv->conn,
+ SmSaveLocal,
+ FALSE,
+ SmInteractStyleNone,
+ FALSE);
+ break;
+
+ default:
+ /* Logout */
+ SmsSaveYourself (client->priv->conn,
+ save_type,
+ TRUE,
+ SmInteractStyleAny,
+ FALSE);
+ break;
+ }
+ }
+}
+
+static void
+xsmp_save_yourself (GsmClient *client,
+ gboolean save_state)
+{
+ GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
+
+ g_debug ("xsmp_save_yourself ('%s', %s)",
+ xsmp->priv->description,
+ save_state ? "True" : "False");
+
+ do_save_yourself (xsmp, save_state ? SmSaveBoth : SmSaveGlobal);
+}
+
+static void
+xsmp_save_yourself_phase2 (GsmClient *client)
+{
+ GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
+
+ g_debug ("xsmp_save_yourself_phase2 ('%s')", xsmp->priv->description);
+
+ SmsSaveYourselfPhase2 (xsmp->priv->conn);
+}
+
+static void
+xsmp_interact (GsmClient *client)
+{
+ GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
+
+ g_debug ("xsmp_interact ('%s')", xsmp->priv->description);
+
+ SmsInteract (xsmp->priv->conn);
+}
+
+
+static void
+xsmp_shutdown_cancelled (GsmClient *client)
+{
+ GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
+
+ g_debug ("xsmp_shutdown_cancelled ('%s')", xsmp->priv->description);
+
+ SmsShutdownCancelled (xsmp->priv->conn);
+}
+
+static void
+xsmp_stop (GsmClient *client)
+{
+ GsmXSMPClient *xsmp = (GsmXSMPClient *) client;
+
+ g_debug ("xsmp_die ('%s')", xsmp->priv->description);
+
+ SmsDie (xsmp->priv->conn);
+}
+
+static void
+gsm_client_set_ice_connection (GsmXSMPClient *client,
+ gpointer conn)
+{
+ client->priv->ice_connection = conn;
+}
+
+static void
+gsm_xsmp_client_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GsmXSMPClient *self;
+
+ self = GSM_XSMP_CLIENT (object);
+
+ switch (prop_id) {
+ case PROP_ICE_CONNECTION:
+ gsm_client_set_ice_connection (self, g_value_get_pointer (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gsm_xsmp_client_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GsmXSMPClient *self;
+
+ self = GSM_XSMP_CLIENT (object);
+
+ switch (prop_id) {
+ case PROP_ICE_CONNECTION:
+ g_value_set_pointer (value, self->priv->ice_connection);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gsm_xsmp_client_finalize (GObject *object)
+{
+ GsmXSMPClient *client = (GsmXSMPClient *) object;
+
+ g_debug ("xsmp_finalize (%s)", client->priv->description);
+
+ if (client->priv->watch_id) {
+ g_source_remove (client->priv->watch_id);
+ }
+
+ if (client->priv->conn) {
+ SmsCleanUp (client->priv->conn);
+ } else {
+ IceCloseConnection (client->priv->ice_connection);
+ }
+
+ if (client->priv->protocol_timeout) {
+ g_source_remove (client->priv->protocol_timeout);
+ }
+
+ G_OBJECT_CLASS (gsm_xsmp_client_parent_class)->finalize (object);
+}
+
+static void
+gsm_xsmp_client_class_init (GsmXSMPClientClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GsmClientClass *client_class = GSM_CLIENT_CLASS (klass);
+
+ object_class->finalize = gsm_xsmp_client_finalize;
+ object_class->constructor = gsm_xsmp_client_constructor;
+ object_class->get_property = gsm_xsmp_client_get_property;
+ object_class->set_property = gsm_xsmp_client_set_property;
+
+ g_object_class_install_property (object_class,
+ PROP_ICE_CONNECTION,
+ g_param_spec_pointer ("ice-connection",
+ "ice-connection",
+ "ice-connection",
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ 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->stop = xsmp_stop;
+ 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;
+}
+
+GsmClient *
+gsm_xsmp_client_new (IceConn ice_conn)
+{
+ GsmXSMPClient *xsmp;
+
+ xsmp = g_object_new (GSM_TYPE_XSMP_CLIENT,
+ "ice-connection", ice_conn,
+ NULL);
+
+ return GSM_CLIENT (xsmp);
+}
+
+static Status
+register_client_callback (SmsConn conn,
+ SmPointer manager_data,
+ char *previous_id)
+{
+ GsmXSMPClient *client = manager_data;
+ gboolean handled;
+ char *id;
+
+ g_debug ("Client '%s' received RegisterClient(%s)",
+ client->priv->description,
+ previous_id ? previous_id : "NULL");
+
+
+ /* There are three cases:
+ * 1. id is NULL - we'll use a new one
+ * 2. id is known - we'll use known one
+ * 3. id is unknown - this is an error
+ */
+ id = g_strdup (previous_id);
+ handled = gsm_client_manage_request (GSM_CLIENT (client), &id);
+ if (! handled) {
+ g_debug (" RegisterClient not handled!");
+ g_free (id);
+ free (previous_id);
+ return FALSE;
+ }
+
+ if (id == NULL) {
+ g_debug (" rejected: invalid previous_id");
+ free (previous_id);
+ return FALSE;
+ }
+
+ g_object_set (client, "client-id", id, NULL);
+
+ set_description (client);
+
+ g_debug ("Sending RegisterClientReply to '%s'", client->priv->description);
+
+ SmsRegisterClientReply (conn, id);
+
+ if (previous_id == NULL) {
+ /* Send the initial SaveYourself. */
+ g_debug ("Sending initial SaveYourself");
+ SmsSaveYourself (conn, SmSaveLocal, False, SmInteractStyleNone, False);
+ client->priv->current_save_yourself = SmSaveLocal;
+
+ free (previous_id);
+ }
+
+ gsm_client_set_status (GSM_CLIENT (client), GSM_CLIENT_MANAGED);
+
+ return TRUE;
+}
+
+
+static void
+save_yourself_request_callback (SmsConn conn,
+ SmPointer manager_data,
+ int save_type,
+ Bool shutdown,
+ int interact_style,
+ Bool fast,
+ Bool global)
+{
+ GsmXSMPClient *client = manager_data;
+
+ g_debug ("Client '%s' received SaveYourselfRequest(%s, %s, %s, %s, %s)",
+ client->priv->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_logout_request (GSM_CLIENT (client),
+ !fast);
+ } else if (!shutdown && !global) {
+ g_debug (" initiating checkpoint");
+ do_save_yourself (client, SmSaveLocal);
+ } else {
+ g_debug (" ignoring");
+ }
+}
+
+static void
+save_yourself_phase2_request_callback (SmsConn conn,
+ SmPointer manager_data)
+{
+ GsmXSMPClient *client = manager_data;
+
+ g_debug ("Client '%s' received SaveYourselfPhase2Request",
+ client->priv->description);
+
+ if (client->priv->current_save_yourself == SmSaveLocal) {
+ /* WTF? Anyway, if it's checkpointing, it doesn't have to wait
+ * for anyone else.
+ */
+ SmsSaveYourselfPhase2 (client->priv->conn);
+ } else {
+ gsm_client_request_phase2 (GSM_CLIENT (client));
+ }
+}
+
+static void
+interact_request_callback (SmsConn conn,
+ SmPointer manager_data,
+ int dialog_type)
+{
+ GsmXSMPClient *client = manager_data;
+
+ g_debug ("Client '%s' received InteractRequest(%s)",
+ client->priv->description,
+ dialog_type == SmInteractStyleAny ? "Any" : "Errors");
+
+ gsm_client_request_interaction (GSM_CLIENT (client));
+}
+
+static void
+interact_done_callback (SmsConn conn,
+ SmPointer manager_data,
+ Bool cancel_shutdown)
+{
+ GsmXSMPClient *client = manager_data;
+
+ g_debug ("Client '%s' received InteractDone(cancel_shutdown = %s)",
+ client->priv->description,
+ cancel_shutdown ? "True" : "False");
+
+ gsm_client_interaction_done (GSM_CLIENT (client), cancel_shutdown);
+}
+
+static void
+save_yourself_done_callback (SmsConn conn,
+ SmPointer manager_data,
+ Bool success)
+{
+ GsmXSMPClient *client = manager_data;
+
+ g_debug ("Client '%s' received SaveYourselfDone(success = %s)",
+ client->priv->description,
+ success ? "True" : "False");
+
+ if (client->priv->current_save_yourself == SmSaveLocal) {
+ client->priv->current_save_yourself = -1;
+ SmsSaveComplete (client->priv->conn);
+ gsm_client_saved_state (GSM_CLIENT (client));
} else {
- client->description = g_strdup_printf ("%p", client);
+ client->priv->current_save_yourself = -1;
+ gsm_client_save_yourself_done (GSM_CLIENT (client));
+ }
+
+ if (client->priv->next_save_yourself) {
+ int save_type = client->priv->next_save_yourself;
+
+ client->priv->next_save_yourself = -1;
+ do_save_yourself (client, save_type);
+ }
+}
+
+static void
+close_connection_callback (SmsConn conn,
+ SmPointer manager_data,
+ int count,
+ char **reason_msgs)
+{
+ GsmXSMPClient *client = manager_data;
+ int i;
+
+ g_debug ("Client '%s' received CloseConnection", client->priv->description);
+ for (i = 0; i < count; i++) {
+ g_debug (" close reason: '%s'", reason_msgs[i]);
}
+ SmFreeReasons (count, reason_msgs);
+
+ gsm_client_disconnected (GSM_CLIENT (client));
}
void
@@ -761,14 +840,14 @@
unsigned long *mask_ret,
SmsCallbacks *callbacks_ret)
{
- client->conn = conn;
+ client->priv->conn = conn;
- if (client->protocol_timeout) {
- g_source_remove (client->protocol_timeout);
- client->protocol_timeout = 0;
+ if (client->priv->protocol_timeout) {
+ g_source_remove (client->priv->protocol_timeout);
+ client->priv->protocol_timeout = 0;
}
- g_debug ("Initializing client %s", client->description);
+ g_debug ("Initializing client %s", client->priv->description);
*mask_ret = 0;
Modified: branches/dbus_based/gnome-session/gsm-xsmp-client.h
==============================================================================
--- branches/dbus_based/gnome-session/gsm-xsmp-client.h (original)
+++ branches/dbus_based/gnome-session/gsm-xsmp-client.h Thu Jun 12 21:23:31 2008
@@ -37,32 +37,22 @@
typedef struct _GsmXSMPClient GsmXSMPClient;
typedef struct _GsmXSMPClientClass GsmXSMPClientClass;
+typedef struct GsmXSMPClientPrivate GsmXSMPClientPrivate;
+
struct _GsmXSMPClient
{
- GsmClient parent;
-
- SmsConn conn;
- IceConn ice_conn;
-
- guint watch_id;
- guint protocol_timeout;
-
- int current_save_yourself;
- int next_save_yourself;
- char *id;
- char *description;
- GPtrArray *props;
+ GsmClient parent;
+ GsmXSMPClientPrivate *priv;
};
struct _GsmXSMPClientClass
{
GsmClientClass parent_class;
-
};
GType gsm_xsmp_client_get_type (void) G_GNUC_CONST;
-GsmXSMPClient *gsm_xsmp_client_new (IceConn ice_conn);
+GsmClient *gsm_xsmp_client_new (IceConn ice_conn);
void gsm_xsmp_client_connect (GsmXSMPClient *client,
SmsConn conn,
Modified: branches/dbus_based/gnome-session/gsm-xsmp-server.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-xsmp-server.c (original)
+++ branches/dbus_based/gnome-session/gsm-xsmp-server.c Thu Jun 12 21:23:31 2008
@@ -105,7 +105,7 @@
IceListenObj listener;
IceConn ice_conn;
IceAcceptStatus status;
- GsmXSMPClient *client;
+ GsmClient *client;
GsmXsmpServer *server;
listener = data->listener;
@@ -122,6 +122,8 @@
client = gsm_xsmp_client_new (ice_conn);
ice_conn->context = client;
+ gsm_client_store_add (server->priv->client_store, client);
+
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]