summaryrefslogtreecommitdiff
path: root/src/eggsmclient-xsmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/eggsmclient-xsmp.c')
-rw-r--r--src/eggsmclient-xsmp.c1977
1 files changed, 989 insertions, 988 deletions
diff --git a/src/eggsmclient-xsmp.c b/src/eggsmclient-xsmp.c
index 9cf343b..5cade1f 100644
--- a/src/eggsmclient-xsmp.c
+++ b/src/eggsmclient-xsmp.c
@@ -56,108 +56,109 @@ typedef struct _EggSMClientXSMPClass EggSMClientXSMPClass;
*/
typedef enum
{
- XSMP_STATE_IDLE,
- XSMP_STATE_SAVE_YOURSELF,
- XSMP_STATE_INTERACT_REQUEST,
- XSMP_STATE_INTERACT,
- XSMP_STATE_SAVE_YOURSELF_DONE,
- XSMP_STATE_SHUTDOWN_CANCELLED,
- XSMP_STATE_CONNECTION_CLOSED
+ XSMP_STATE_IDLE,
+ XSMP_STATE_SAVE_YOURSELF,
+ XSMP_STATE_INTERACT_REQUEST,
+ XSMP_STATE_INTERACT,
+ XSMP_STATE_SAVE_YOURSELF_DONE,
+ XSMP_STATE_SHUTDOWN_CANCELLED,
+ XSMP_STATE_CONNECTION_CLOSED
} EggSMClientXSMPState;
-static const char *state_names[] = {
- "idle",
- "save-yourself",
- "interact-request",
- "interact",
- "save-yourself-done",
- "shutdown-cancelled",
- "connection-closed"
+static const char *state_names[] =
+{
+ "idle",
+ "save-yourself",
+ "interact-request",
+ "interact",
+ "save-yourself-done",
+ "shutdown-cancelled",
+ "connection-closed"
};
#define EGG_SM_CLIENT_XSMP_STATE(xsmp) (state_names[(xsmp)->state])
struct _EggSMClientXSMP
{
- EggSMClient parent;
+ EggSMClient parent;
- SmcConn connection;
- char *client_id;
+ SmcConn connection;
+ char *client_id;
- EggSMClientXSMPState state;
- char **restart_command;
- gboolean set_restart_command;
- int restart_style;
- char **discard_command;
- gboolean set_discard_command;
+ EggSMClientXSMPState state;
+ char **restart_command;
+ gboolean set_restart_command;
+ int restart_style;
+ char **discard_command;
+ gboolean set_discard_command;
- guint idle;
+ guint idle;
- /* Current SaveYourself state */
- guint expecting_initial_save_yourself : 1;
- guint need_save_state : 1;
- guint need_quit_requested : 1;
- guint interact_errors : 1;
- guint shutting_down : 1;
+ /* Current SaveYourself state */
+ guint expecting_initial_save_yourself : 1;
+ guint need_save_state : 1;
+ guint need_quit_requested : 1;
+ guint interact_errors : 1;
+ guint shutting_down : 1;
- /* Todo list */
- guint waiting_to_set_initial_properties : 1;
- guint waiting_to_emit_quit : 1;
- guint waiting_to_emit_quit_cancelled : 1;
- guint waiting_to_save_myself : 1;
+ /* Todo list */
+ guint waiting_to_set_initial_properties : 1;
+ guint waiting_to_emit_quit : 1;
+ guint waiting_to_emit_quit_cancelled : 1;
+ guint waiting_to_save_myself : 1;
};
struct _EggSMClientXSMPClass
{
- EggSMClientClass parent_class;
+ EggSMClientClass parent_class;
};
static void sm_client_xsmp_startup (EggSMClient *client,
- const char *client_id);
+ const char *client_id);
static void sm_client_xsmp_set_restart_command (EggSMClient *client,
- int argc,
- const char **argv);
+ int argc,
+ const char **argv);
static void sm_client_xsmp_set_discard_command (EggSMClient *client,
- int argc,
- const char **argv);
+ int argc,
+ const char **argv);
static void sm_client_xsmp_will_quit (EggSMClient *client,
- gboolean will_quit);
+ gboolean will_quit);
static gboolean sm_client_xsmp_end_session (EggSMClient *client,
- EggSMClientEndStyle style,
- gboolean request_confirmation);
+ EggSMClientEndStyle style,
+ gboolean request_confirmation);
static void xsmp_save_yourself (SmcConn smc_conn,
- SmPointer client_data,
- int save_style,
- Bool shutdown,
- int interact_style,
- Bool fast);
+ SmPointer client_data,
+ int save_style,
+ Bool shutdown,
+ int interact_style,
+ Bool fast);
static void xsmp_die (SmcConn smc_conn,
- SmPointer client_data);
+ SmPointer client_data);
static void xsmp_save_complete (SmcConn smc_conn,
- SmPointer client_data);
+ SmPointer client_data);
static void xsmp_shutdown_cancelled (SmcConn smc_conn,
- SmPointer client_data);
+ SmPointer client_data);
static void xsmp_interact (SmcConn smc_conn,
- SmPointer client_data);
+ SmPointer client_data);
static SmProp *array_prop (const char *name,
- ...);
+ ...);
static SmProp *ptrarray_prop (const char *name,
- GPtrArray *values);
+ GPtrArray *values);
static SmProp *string_prop (const char *name,
- const char *value);
+ const char *value);
static SmProp *card8_prop (const char *name,
- unsigned char value);
+ unsigned char value);
static void set_properties (EggSMClientXSMP *xsmp, ...);
static void delete_properties (EggSMClientXSMP *xsmp, ...);
static GPtrArray *generate_command (char **argv,
- const char *client_id,
- const char *state_file);
+ const char *client_id,
+ const char *state_file);
static void save_state (EggSMClientXSMP *xsmp);
static void do_save_yourself (EggSMClientXSMP *xsmp);
@@ -166,129 +167,129 @@ static void update_pending_events (EggSMClientXSMP *xsmp);
static void ice_init (void);
static gboolean process_ice_messages (IceConn ice_conn);
static void smc_error_handler (SmcConn smc_conn,
- Bool swap,
- int offending_minor_opcode,
- unsigned long offending_sequence,
- int error_class,
- int severity,
- SmPointer values);
+ Bool swap,
+ int offending_minor_opcode,
+ unsigned long offending_sequence,
+ int error_class,
+ int severity,
+ SmPointer values);
G_DEFINE_TYPE (EggSMClientXSMP, egg_sm_client_xsmp, EGG_TYPE_SM_CLIENT)
static void
egg_sm_client_xsmp_init (EggSMClientXSMP *xsmp)
{
- xsmp->state = XSMP_STATE_CONNECTION_CLOSED;
- xsmp->connection = NULL;
- xsmp->restart_style = SmRestartIfRunning;
+ xsmp->state = XSMP_STATE_CONNECTION_CLOSED;
+ xsmp->connection = NULL;
+ xsmp->restart_style = SmRestartIfRunning;
}
static void
egg_sm_client_xsmp_class_init (EggSMClientXSMPClass *klass)
{
- EggSMClientClass *sm_client_class = EGG_SM_CLIENT_CLASS (klass);
+ EggSMClientClass *sm_client_class = EGG_SM_CLIENT_CLASS (klass);
- sm_client_class->startup = sm_client_xsmp_startup;
- sm_client_class->set_restart_command = sm_client_xsmp_set_restart_command;
- sm_client_class->set_discard_command = sm_client_xsmp_set_discard_command;
- sm_client_class->will_quit = sm_client_xsmp_will_quit;
- sm_client_class->end_session = sm_client_xsmp_end_session;
+ sm_client_class->startup = sm_client_xsmp_startup;
+ sm_client_class->set_restart_command = sm_client_xsmp_set_restart_command;
+ sm_client_class->set_discard_command = sm_client_xsmp_set_discard_command;
+ sm_client_class->will_quit = sm_client_xsmp_will_quit;
+ sm_client_class->end_session = sm_client_xsmp_end_session;
}
EggSMClient *
egg_sm_client_xsmp_new (void)
{
- if (!g_getenv ("SESSION_MANAGER"))
- return NULL;
+ if (!g_getenv ("SESSION_MANAGER"))
+ return NULL;
- return g_object_new (EGG_TYPE_SM_CLIENT_XSMP, NULL);
+ return g_object_new (EGG_TYPE_SM_CLIENT_XSMP, NULL);
}
static gboolean
sm_client_xsmp_set_initial_properties (gpointer user_data)
{
- EggSMClientXSMP *xsmp = user_data;
- EggDesktopFile *desktop_file;
- GPtrArray *clone, *restart;
- char pid_str[64];
-
- if (xsmp->idle)
- {
- g_source_remove (xsmp->idle);
- xsmp->idle = 0;
- }
- xsmp->waiting_to_set_initial_properties = FALSE;
-
- if (egg_sm_client_get_mode () == EGG_SM_CLIENT_MODE_NO_RESTART)
- xsmp->restart_style = SmRestartNever;
-
- /* Parse info out of desktop file */
- desktop_file = egg_get_desktop_file ();
- if (desktop_file)
- {
- GError *err = NULL;
- char *cmdline, **argv;
- int argc;
-
- if (xsmp->restart_style == SmRestartIfRunning)
+ EggSMClientXSMP *xsmp = user_data;
+ EggDesktopFile *desktop_file;
+ GPtrArray *clone, *restart;
+ char pid_str[64];
+
+ if (xsmp->idle)
{
- if (egg_desktop_file_get_boolean (desktop_file,
- "X-MATE-AutoRestart", NULL))
- xsmp->restart_style = SmRestartImmediately;
+ g_source_remove (xsmp->idle);
+ xsmp->idle = 0;
}
+ xsmp->waiting_to_set_initial_properties = FALSE;
+
+ if (egg_sm_client_get_mode () == EGG_SM_CLIENT_MODE_NO_RESTART)
+ xsmp->restart_style = SmRestartNever;
- if (!xsmp->set_restart_command)
+ /* Parse info out of desktop file */
+ desktop_file = egg_get_desktop_file ();
+ if (desktop_file)
{
- cmdline = egg_desktop_file_parse_exec (desktop_file, NULL, &err);
- if (cmdline && g_shell_parse_argv (cmdline, &argc, &argv, &err))
- {
- egg_sm_client_set_restart_command (EGG_SM_CLIENT (xsmp),
- argc, (const char **)argv);
- g_strfreev (argv);
- }
- else
- {
- g_warning ("Could not parse Exec line in desktop file: %s",
- err->message);
- g_error_free (err);
- }
- g_free (cmdline);
+ GError *err = NULL;
+ char *cmdline, **argv;
+ int argc;
+
+ if (xsmp->restart_style == SmRestartIfRunning)
+ {
+ if (egg_desktop_file_get_boolean (desktop_file,
+ "X-MATE-AutoRestart", NULL))
+ xsmp->restart_style = SmRestartImmediately;
+ }
+
+ if (!xsmp->set_restart_command)
+ {
+ cmdline = egg_desktop_file_parse_exec (desktop_file, NULL, &err);
+ if (cmdline && g_shell_parse_argv (cmdline, &argc, &argv, &err))
+ {
+ egg_sm_client_set_restart_command (EGG_SM_CLIENT (xsmp),
+ argc, (const char **)argv);
+ g_strfreev (argv);
+ }
+ else
+ {
+ g_warning ("Could not parse Exec line in desktop file: %s",
+ err->message);
+ g_error_free (err);
+ }
+ g_free (cmdline);
+ }
}
- }
-
- if (!xsmp->set_restart_command)
- xsmp->restart_command = g_strsplit (g_get_prgname (), " ", -1);
-
- clone = generate_command (xsmp->restart_command, NULL, NULL);
- restart = generate_command (xsmp->restart_command, xsmp->client_id, NULL);
-
- g_debug ("Setting initial properties");
-
- /* Program, CloneCommand, RestartCommand, and UserID are required.
- * ProcessID isn't required, but the SM may be able to do something
- * useful with it.
- */
- g_snprintf (pid_str, sizeof (pid_str), "%lu", (gulong) getpid ());
- set_properties (xsmp,
- string_prop (SmProgram, g_get_prgname ()),
- ptrarray_prop (SmCloneCommand, clone),
- ptrarray_prop (SmRestartCommand, restart),
- string_prop (SmUserID, g_get_user_name ()),
- string_prop (SmProcessID, pid_str),
- card8_prop (SmRestartStyleHint, xsmp->restart_style),
- NULL);
- g_ptr_array_free (clone, TRUE);
- g_ptr_array_free (restart, TRUE);
-
- if (desktop_file)
- {
- set_properties (xsmp,
- string_prop ("_GSM_DesktopFile", egg_desktop_file_get_source (desktop_file)),
- NULL);
- }
-
- update_pending_events (xsmp);
- return FALSE;
+
+ if (!xsmp->set_restart_command)
+ xsmp->restart_command = g_strsplit (g_get_prgname (), " ", -1);
+
+ clone = generate_command (xsmp->restart_command, NULL, NULL);
+ restart = generate_command (xsmp->restart_command, xsmp->client_id, NULL);
+
+ g_debug ("Setting initial properties");
+
+ /* Program, CloneCommand, RestartCommand, and UserID are required.
+ * ProcessID isn't required, but the SM may be able to do something
+ * useful with it.
+ */
+ g_snprintf (pid_str, sizeof (pid_str), "%lu", (gulong) getpid ());
+ set_properties (xsmp,
+ string_prop (SmProgram, g_get_prgname ()),
+ ptrarray_prop (SmCloneCommand, clone),
+ ptrarray_prop (SmRestartCommand, restart),
+ string_prop (SmUserID, g_get_user_name ()),
+ string_prop (SmProcessID, pid_str),
+ card8_prop (SmRestartStyleHint, xsmp->restart_style),
+ NULL);
+ g_ptr_array_free (clone, TRUE);
+ g_ptr_array_free (restart, TRUE);
+
+ if (desktop_file)
+ {
+ set_properties (xsmp,
+ string_prop ("_GSM_DesktopFile", egg_desktop_file_get_source (desktop_file)),
+ NULL);
+ }
+
+ update_pending_events (xsmp);
+ return FALSE;
}
/* This gets called from two different places: xsmp_die() (when the
@@ -298,771 +299,771 @@ sm_client_xsmp_set_initial_properties (gpointer user_data)
static void
sm_client_xsmp_disconnect (EggSMClientXSMP *xsmp)
{
- SmcConn connection;
+ SmcConn connection;
- if (!xsmp->connection)
- return;
+ if (!xsmp->connection)
+ return;
- g_debug ("Disconnecting");
+ g_debug ("Disconnecting");
- connection = xsmp->connection;
- xsmp->connection = NULL;
- SmcCloseConnection (connection, 0, NULL);
- xsmp->state = XSMP_STATE_CONNECTION_CLOSED;
+ connection = xsmp->connection;
+ xsmp->connection = NULL;
+ SmcCloseConnection (connection, 0, NULL);
+ xsmp->state = XSMP_STATE_CONNECTION_CLOSED;
- xsmp->waiting_to_save_myself = FALSE;
- update_pending_events (xsmp);
+ xsmp->waiting_to_save_myself = FALSE;
+ update_pending_events (xsmp);
}
static void
sm_client_xsmp_startup (EggSMClient *client,
- const char *client_id)
+ const char *client_id)
{
- EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
- SmcCallbacks callbacks;
- char *ret_client_id;
- char error_string_ret[256];
-
- xsmp->client_id = g_strdup (client_id);
-
- ice_init ();
- SmcSetErrorHandler (smc_error_handler);
-
- callbacks.save_yourself.callback = xsmp_save_yourself;
- callbacks.die.callback = xsmp_die;
- callbacks.save_complete.callback = xsmp_save_complete;
- callbacks.shutdown_cancelled.callback = xsmp_shutdown_cancelled;
-
- callbacks.save_yourself.client_data = xsmp;
- callbacks.die.client_data = xsmp;
- callbacks.save_complete.client_data = xsmp;
- callbacks.shutdown_cancelled.client_data = xsmp;
-
- client_id = NULL;
- error_string_ret[0] = '\0';
- xsmp->connection =
- SmcOpenConnection (NULL, xsmp, SmProtoMajor, SmProtoMinor,
- SmcSaveYourselfProcMask | SmcDieProcMask |
- SmcSaveCompleteProcMask |
- SmcShutdownCancelledProcMask,
- &callbacks,
- xsmp->client_id, &ret_client_id,
- sizeof (error_string_ret), error_string_ret);
-
- if (!xsmp->connection)
- {
- g_warning ("Failed to connect to the session manager: %s\n",
- error_string_ret[0] ?
- error_string_ret : "no error message given");
- xsmp->state = XSMP_STATE_CONNECTION_CLOSED;
- return;
- }
-
- /* We expect a pointless initial SaveYourself if either (a) we
- * didn't have an initial client ID, or (b) we DID have an initial
- * client ID, but the server rejected it and gave us a new one.
- */
- if (!xsmp->client_id ||
- (ret_client_id && strcmp (xsmp->client_id, ret_client_id) != 0))
- xsmp->expecting_initial_save_yourself = TRUE;
-
- if (ret_client_id)
- {
- g_free (xsmp->client_id);
- xsmp->client_id = g_strdup (ret_client_id);
- free (ret_client_id);
-
- gdk_threads_enter ();
- gdk_set_sm_client_id (xsmp->client_id);
- gdk_threads_leave ();
-
- g_debug ("Got client ID \"%s\"", xsmp->client_id);
- }
-
- xsmp->state = XSMP_STATE_IDLE;
-
- /* Do not set the initial properties until we reach the main loop,
- * so that the application has a chance to call
- * egg_set_desktop_file(). (This may also help the session manager
- * have a better idea of when the application is fully up and
- * running.)
- */
- xsmp->waiting_to_set_initial_properties = TRUE;
- xsmp->idle = g_idle_add (sm_client_xsmp_set_initial_properties, client);
+ EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
+ SmcCallbacks callbacks;
+ char *ret_client_id;
+ char error_string_ret[256];
+
+ xsmp->client_id = g_strdup (client_id);
+
+ ice_init ();
+ SmcSetErrorHandler (smc_error_handler);
+
+ callbacks.save_yourself.callback = xsmp_save_yourself;
+ callbacks.die.callback = xsmp_die;
+ callbacks.save_complete.callback = xsmp_save_complete;
+ callbacks.shutdown_cancelled.callback = xsmp_shutdown_cancelled;
+
+ callbacks.save_yourself.client_data = xsmp;
+ callbacks.die.client_data = xsmp;
+ callbacks.save_complete.client_data = xsmp;
+ callbacks.shutdown_cancelled.client_data = xsmp;
+
+ client_id = NULL;
+ error_string_ret[0] = '\0';
+ xsmp->connection =
+ SmcOpenConnection (NULL, xsmp, SmProtoMajor, SmProtoMinor,
+ SmcSaveYourselfProcMask | SmcDieProcMask |
+ SmcSaveCompleteProcMask |
+ SmcShutdownCancelledProcMask,
+ &callbacks,
+ xsmp->client_id, &ret_client_id,
+ sizeof (error_string_ret), error_string_ret);
+
+ if (!xsmp->connection)
+ {
+ g_warning ("Failed to connect to the session manager: %s\n",
+ error_string_ret[0] ?
+ error_string_ret : "no error message given");
+ xsmp->state = XSMP_STATE_CONNECTION_CLOSED;
+ return;
+ }
+
+ /* We expect a pointless initial SaveYourself if either (a) we
+ * didn't have an initial client ID, or (b) we DID have an initial
+ * client ID, but the server rejected it and gave us a new one.
+ */
+ if (!xsmp->client_id ||
+ (ret_client_id && strcmp (xsmp->client_id, ret_client_id) != 0))
+ xsmp->expecting_initial_save_yourself = TRUE;
+
+ if (ret_client_id)
+ {
+ g_free (xsmp->client_id);
+ xsmp->client_id = g_strdup (ret_client_id);
+ free (ret_client_id);
+
+ gdk_threads_enter ();
+ gdk_set_sm_client_id (xsmp->client_id);
+ gdk_threads_leave ();
+
+ g_debug ("Got client ID \"%s\"", xsmp->client_id);
+ }
+
+ xsmp->state = XSMP_STATE_IDLE;
+
+ /* Do not set the initial properties until we reach the main loop,
+ * so that the application has a chance to call
+ * egg_set_desktop_file(). (This may also help the session manager
+ * have a better idea of when the application is fully up and
+ * running.)
+ */
+ xsmp->waiting_to_set_initial_properties = TRUE;
+ xsmp->idle = g_idle_add (sm_client_xsmp_set_initial_properties, client);
}
static void
sm_client_xsmp_set_restart_command (EggSMClient *client,
- int argc,
- const char **argv)
+ int argc,
+ const char **argv)
{
- EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
- int i;
+ EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
+ int i;
- g_strfreev (xsmp->restart_command);
+ g_strfreev (xsmp->restart_command);
- xsmp->restart_command = g_new (char *, argc + 1);
- for (i = 0; i < argc; i++)
- xsmp->restart_command[i] = g_strdup (argv[i]);
- xsmp->restart_command[i] = NULL;
+ xsmp->restart_command = g_new (char *, argc + 1);
+ for (i = 0; i < argc; i++)
+ xsmp->restart_command[i] = g_strdup (argv[i]);
+ xsmp->restart_command[i] = NULL;
- xsmp->set_restart_command = TRUE;
+ xsmp->set_restart_command = TRUE;
}
static void
sm_client_xsmp_set_discard_command (EggSMClient *client,
- int argc,
- const char **argv)
+ int argc,
+ const char **argv)
{
- EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
- int i;
+ EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
+ int i;
- g_strfreev (xsmp->discard_command);
+ g_strfreev (xsmp->discard_command);
- xsmp->discard_command = g_new (char *, argc + 1);
- for (i = 0; i < argc; i++)
- xsmp->discard_command[i] = g_strdup (argv[i]);
- xsmp->discard_command[i] = NULL;
+ xsmp->discard_command = g_new (char *, argc + 1);
+ for (i = 0; i < argc; i++)
+ xsmp->discard_command[i] = g_strdup (argv[i]);
+ xsmp->discard_command[i] = NULL;
- xsmp->set_discard_command = TRUE;
+ xsmp->set_discard_command = TRUE;
}
static void
sm_client_xsmp_will_quit (EggSMClient *client,
- gboolean will_quit)
+ gboolean will_quit)
{
- EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
-
- if (xsmp->state == XSMP_STATE_CONNECTION_CLOSED)
- {
- /* The session manager has already exited! Schedule a quit
- * signal.
- */
- xsmp->waiting_to_emit_quit = TRUE;
- update_pending_events (xsmp);
- return;
- }
- else if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED)
- {
- /* We received a ShutdownCancelled message while the application
- * was interacting; Schedule a quit_cancelled signal.
- */
- xsmp->waiting_to_emit_quit_cancelled = TRUE;
- update_pending_events (xsmp);
- return;
- }
-
- g_return_if_fail (xsmp->state == XSMP_STATE_INTERACT);
-
- g_debug ("Sending InteractDone(%s)", will_quit ? "False" : "True");
- SmcInteractDone (xsmp->connection, !will_quit);
-
- if (will_quit && xsmp->need_save_state)
- save_state (xsmp);
-
- g_debug ("Sending SaveYourselfDone(%s)", will_quit ? "True" : "False");
- SmcSaveYourselfDone (xsmp->connection, will_quit);
- xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
+ EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
+
+ if (xsmp->state == XSMP_STATE_CONNECTION_CLOSED)
+ {
+ /* The session manager has already exited! Schedule a quit
+ * signal.
+ */
+ xsmp->waiting_to_emit_quit = TRUE;
+ update_pending_events (xsmp);
+ return;
+ }
+ else if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED)
+ {
+ /* We received a ShutdownCancelled message while the application
+ * was interacting; Schedule a quit_cancelled signal.
+ */
+ xsmp->waiting_to_emit_quit_cancelled = TRUE;
+ update_pending_events (xsmp);
+ return;
+ }
+
+ g_return_if_fail (xsmp->state == XSMP_STATE_INTERACT);
+
+ g_debug ("Sending InteractDone(%s)", will_quit ? "False" : "True");
+ SmcInteractDone (xsmp->connection, !will_quit);
+
+ if (will_quit && xsmp->need_save_state)
+ save_state (xsmp);
+
+ g_debug ("Sending SaveYourselfDone(%s)", will_quit ? "True" : "False");
+ SmcSaveYourselfDone (xsmp->connection, will_quit);
+ xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
}
static gboolean
sm_client_xsmp_end_session (EggSMClient *client,
- EggSMClientEndStyle style,
- gboolean request_confirmation)
+ EggSMClientEndStyle style,
+ gboolean request_confirmation)
{
- EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
- int save_type;
-
- /* To end the session via XSMP, we have to send a
- * SaveYourselfRequest. We aren't allowed to do that if anything
- * else is going on, but we don't want to expose this fact to the
- * application. So we do our best to patch things up here...
- *
- * In the worst case, this method might block for some length of
- * time in process_ice_messages, but the only time that code path is
- * honestly likely to get hit is if the application tries to end the
- * session as the very first thing it does, in which case it
- * probably won't actually block anyway. It's not worth gunking up
- * the API to try to deal nicely with the other 0.01% of cases where
- * this happens.
- */
-
- while (xsmp->state != XSMP_STATE_IDLE ||
- xsmp->expecting_initial_save_yourself)
- {
- /* If we're already shutting down, we don't need to do anything. */
- if (xsmp->shutting_down)
- return TRUE;
-
- switch (xsmp->state)
+ EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
+ int save_type;
+
+ /* To end the session via XSMP, we have to send a
+ * SaveYourselfRequest. We aren't allowed to do that if anything
+ * else is going on, but we don't want to expose this fact to the
+ * application. So we do our best to patch things up here...
+ *
+ * In the worst case, this method might block for some length of
+ * time in process_ice_messages, but the only time that code path is
+ * honestly likely to get hit is if the application tries to end the
+ * session as the very first thing it does, in which case it
+ * probably won't actually block anyway. It's not worth gunking up
+ * the API to try to deal nicely with the other 0.01% of cases where
+ * this happens.
+ */
+
+ while (xsmp->state != XSMP_STATE_IDLE ||
+ xsmp->expecting_initial_save_yourself)
{
- case XSMP_STATE_CONNECTION_CLOSED:
- return FALSE;
-
- case XSMP_STATE_SAVE_YOURSELF:
- /* Trying to log out from the save_state callback? Whatever.
- * Abort the save_state.
- */
- SmcSaveYourselfDone (xsmp->connection, FALSE);
- xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
- break;
-
- case XSMP_STATE_INTERACT_REQUEST:
- case XSMP_STATE_INTERACT:
- case XSMP_STATE_SHUTDOWN_CANCELLED:
- /* Already in a shutdown-related state, just ignore
- * the new shutdown request...
- */
- return TRUE;
-
- case XSMP_STATE_IDLE:
- if (xsmp->waiting_to_set_initial_properties)
- sm_client_xsmp_set_initial_properties (xsmp);
-
- if (!xsmp->expecting_initial_save_yourself)
- break;
- /* else fall through */
-
- case XSMP_STATE_SAVE_YOURSELF_DONE:
- /* We need to wait for some response from the server.*/
- process_ice_messages (SmcGetIceConnection (xsmp->connection));
- break;
+ /* If we're already shutting down, we don't need to do anything. */
+ if (xsmp->shutting_down)
+ return TRUE;
- default:
- /* Hm... shouldn't happen */
- return FALSE;
+ switch (xsmp->state)
+ {
+ case XSMP_STATE_CONNECTION_CLOSED:
+ return FALSE;
+
+ case XSMP_STATE_SAVE_YOURSELF:
+ /* Trying to log out from the save_state callback? Whatever.
+ * Abort the save_state.
+ */
+ SmcSaveYourselfDone (xsmp->connection, FALSE);
+ xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
+ break;
+
+ case XSMP_STATE_INTERACT_REQUEST:
+ case XSMP_STATE_INTERACT:
+ case XSMP_STATE_SHUTDOWN_CANCELLED:
+ /* Already in a shutdown-related state, just ignore
+ * the new shutdown request...
+ */
+ return TRUE;
+
+ case XSMP_STATE_IDLE:
+ if (xsmp->waiting_to_set_initial_properties)
+ sm_client_xsmp_set_initial_properties (xsmp);
+
+ if (!xsmp->expecting_initial_save_yourself)
+ break;
+ /* else fall through */
+
+ case XSMP_STATE_SAVE_YOURSELF_DONE:
+ /* We need to wait for some response from the server.*/
+ process_ice_messages (SmcGetIceConnection (xsmp->connection));
+ break;
+
+ default:
+ /* Hm... shouldn't happen */
+ return FALSE;
+ }
}
- }
-
- /* xfce4-session will do the wrong thing if we pass SmSaveGlobal and
- * the user chooses to save the session. But mate-session will do
- * the wrong thing if we pass SmSaveBoth and the user chooses NOT to
- * save the session... Sigh.
- */
- if (!strcmp (SmcVendor (xsmp->connection), "xfce4-session"))
- save_type = SmSaveBoth;
- else
- save_type = SmSaveGlobal;
-
- g_debug ("Sending SaveYourselfRequest(SmSaveGlobal, Shutdown, SmInteractStyleAny, %sFast)", request_confirmation ? "!" : "");
- SmcRequestSaveYourself (xsmp->connection,
- save_type,
- True, /* shutdown */
- SmInteractStyleAny,
- !request_confirmation, /* fast */
- True /* global */);
- return TRUE;
+
+ /* xfce4-session will do the wrong thing if we pass SmSaveGlobal and
+ * the user chooses to save the session. But mate-session will do
+ * the wrong thing if we pass SmSaveBoth and the user chooses NOT to
+ * save the session... Sigh.
+ */
+ if (!strcmp (SmcVendor (xsmp->connection), "xfce4-session"))
+ save_type = SmSaveBoth;
+ else
+ save_type = SmSaveGlobal;
+
+ g_debug ("Sending SaveYourselfRequest(SmSaveGlobal, Shutdown, SmInteractStyleAny, %sFast)", request_confirmation ? "!" : "");
+ SmcRequestSaveYourself (xsmp->connection,
+ save_type,
+ True, /* shutdown */
+ SmInteractStyleAny,
+ !request_confirmation, /* fast */
+ True /* global */);
+ return TRUE;
}
static gboolean
idle_do_pending_events (gpointer data)
{
- EggSMClientXSMP *xsmp = data;
- EggSMClient *client = data;
-
- gdk_threads_enter ();
-
- xsmp->idle = 0;
-
- if (xsmp->waiting_to_emit_quit)
- {
- xsmp->waiting_to_emit_quit = FALSE;
- egg_sm_client_quit (client);
- goto out;
- }
-
- if (xsmp->waiting_to_emit_quit_cancelled)
- {
- xsmp->waiting_to_emit_quit_cancelled = FALSE;
- egg_sm_client_quit_cancelled (client);
- xsmp->state = XSMP_STATE_IDLE;
- }
-
- if (xsmp->waiting_to_save_myself)
- {
- xsmp->waiting_to_save_myself = FALSE;
- do_save_yourself (xsmp);
- }
-
- out:
- gdk_threads_leave ();
- return FALSE;
+ EggSMClientXSMP *xsmp = data;
+ EggSMClient *client = data;
+
+ gdk_threads_enter ();
+
+ xsmp->idle = 0;
+
+ if (xsmp->waiting_to_emit_quit)
+ {
+ xsmp->waiting_to_emit_quit = FALSE;
+ egg_sm_client_quit (client);
+ goto out;
+ }
+
+ if (xsmp->waiting_to_emit_quit_cancelled)
+ {
+ xsmp->waiting_to_emit_quit_cancelled = FALSE;
+ egg_sm_client_quit_cancelled (client);
+ xsmp->state = XSMP_STATE_IDLE;
+ }
+
+ if (xsmp->waiting_to_save_myself)
+ {
+ xsmp->waiting_to_save_myself = FALSE;
+ do_save_yourself (xsmp);
+ }
+
+out:
+ gdk_threads_leave ();
+ return FALSE;
}
static void
update_pending_events (EggSMClientXSMP *xsmp)
{
- gboolean want_idle =
- xsmp->waiting_to_emit_quit ||
- xsmp->waiting_to_emit_quit_cancelled ||
- xsmp->waiting_to_save_myself;
-
- if (want_idle)
- {
- if (xsmp->idle == 0)
- xsmp->idle = g_idle_add (idle_do_pending_events, xsmp);
- }
- else
- {
- if (xsmp->idle != 0)
- g_source_remove (xsmp->idle);
- xsmp->idle = 0;
- }
+ gboolean want_idle =
+ xsmp->waiting_to_emit_quit ||
+ xsmp->waiting_to_emit_quit_cancelled ||
+ xsmp->waiting_to_save_myself;
+
+ if (want_idle)
+ {
+ if (xsmp->idle == 0)
+ xsmp->idle = g_idle_add (idle_do_pending_events, xsmp);
+ }
+ else
+ {
+ if (xsmp->idle != 0)
+ g_source_remove (xsmp->idle);
+ xsmp->idle = 0;
+ }
}
static void
fix_broken_state (EggSMClientXSMP *xsmp, const char *message,
- gboolean send_interact_done,
- gboolean send_save_yourself_done)
+ gboolean send_interact_done,
+ gboolean send_save_yourself_done)
{
- g_warning ("Received XSMP %s message in state %s: client or server error",
- message, EGG_SM_CLIENT_XSMP_STATE (xsmp));
+ g_warning ("Received XSMP %s message in state %s: client or server error",
+ message, EGG_SM_CLIENT_XSMP_STATE (xsmp));
- /* Forget any pending SaveYourself plans we had */
- xsmp->waiting_to_save_myself = FALSE;
- update_pending_events (xsmp);
+ /* Forget any pending SaveYourself plans we had */
+ xsmp->waiting_to_save_myself = FALSE;
+ update_pending_events (xsmp);
- if (send_interact_done)
- SmcInteractDone (xsmp->connection, False);
- if (send_save_yourself_done)
- SmcSaveYourselfDone (xsmp->connection, True);
+ if (send_interact_done)
+ SmcInteractDone (xsmp->connection, False);
+ if (send_save_yourself_done)
+ SmcSaveYourselfDone (xsmp->connection, True);
- xsmp->state = send_save_yourself_done ? XSMP_STATE_SAVE_YOURSELF_DONE : XSMP_STATE_IDLE;
+ xsmp->state = send_save_yourself_done ? XSMP_STATE_SAVE_YOURSELF_DONE : XSMP_STATE_IDLE;
}
/* SM callbacks */
static void
xsmp_save_yourself (SmcConn smc_conn,
- SmPointer client_data,
- int save_type,
- Bool shutdown,
- int interact_style,
- Bool fast)
+ SmPointer client_data,
+ int save_type,
+ Bool shutdown,
+ int interact_style,
+ Bool fast)
{
- EggSMClientXSMP *xsmp = client_data;
- gboolean wants_quit_requested;
-
- g_debug ("Received SaveYourself(%s, %s, %s, %s) in state %s",
- save_type == SmSaveLocal ? "SmSaveLocal" :
- save_type == SmSaveGlobal ? "SmSaveGlobal" : "SmSaveBoth",
- shutdown ? "Shutdown" : "!Shutdown",
- interact_style == SmInteractStyleAny ? "SmInteractStyleAny" :
- interact_style == SmInteractStyleErrors ? "SmInteractStyleErrors" :
- "SmInteractStyleNone", fast ? "Fast" : "!Fast",
- EGG_SM_CLIENT_XSMP_STATE (xsmp));
-
- if (xsmp->state != XSMP_STATE_IDLE &&
- xsmp->state != XSMP_STATE_SHUTDOWN_CANCELLED)
- {
- fix_broken_state (xsmp, "SaveYourself", FALSE, TRUE);
- return;
- }
-
- if (xsmp->waiting_to_set_initial_properties)
- sm_client_xsmp_set_initial_properties (xsmp);
-
- /* If this is the initial SaveYourself, ignore it; we've already set
- * properties and there's no reason to actually save state too.
- */
- if (xsmp->expecting_initial_save_yourself)
- {
- xsmp->expecting_initial_save_yourself = FALSE;
-
- if (save_type == SmSaveLocal &&
- interact_style == SmInteractStyleNone &&
- !shutdown && !fast)
+ EggSMClientXSMP *xsmp = client_data;
+ gboolean wants_quit_requested;
+
+ g_debug ("Received SaveYourself(%s, %s, %s, %s) in state %s",
+ save_type == SmSaveLocal ? "SmSaveLocal" :
+ save_type == SmSaveGlobal ? "SmSaveGlobal" : "SmSaveBoth",
+ shutdown ? "Shutdown" : "!Shutdown",
+ interact_style == SmInteractStyleAny ? "SmInteractStyleAny" :
+ interact_style == SmInteractStyleErrors ? "SmInteractStyleErrors" :
+ "SmInteractStyleNone", fast ? "Fast" : "!Fast",
+ EGG_SM_CLIENT_XSMP_STATE (xsmp));
+
+ if (xsmp->state != XSMP_STATE_IDLE &&
+ xsmp->state != XSMP_STATE_SHUTDOWN_CANCELLED)
+ {
+ fix_broken_state (xsmp, "SaveYourself", FALSE, TRUE);
+ return;
+ }
+
+ if (xsmp->waiting_to_set_initial_properties)
+ sm_client_xsmp_set_initial_properties (xsmp);
+
+ /* If this is the initial SaveYourself, ignore it; we've already set
+ * properties and there's no reason to actually save state too.
+ */
+ if (xsmp->expecting_initial_save_yourself)
{
- g_debug ("Sending SaveYourselfDone(True) for initial SaveYourself");
- SmcSaveYourselfDone (xsmp->connection, True);
- /* As explained in the comment at the end of
- * do_save_yourself(), SAVE_YOURSELF_DONE is the correct
- * state here, not IDLE.
- */
- xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
- return;
+ xsmp->expecting_initial_save_yourself = FALSE;
+
+ if (save_type == SmSaveLocal &&
+ interact_style == SmInteractStyleNone &&
+ !shutdown && !fast)
+ {
+ g_debug ("Sending SaveYourselfDone(True) for initial SaveYourself");
+ SmcSaveYourselfDone (xsmp->connection, True);
+ /* As explained in the comment at the end of
+ * do_save_yourself(), SAVE_YOURSELF_DONE is the correct
+ * state here, not IDLE.
+ */
+ xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
+ return;
+ }
+ else
+ g_warning ("First SaveYourself was not the expected one!");
}
- else
- g_warning ("First SaveYourself was not the expected one!");
- }
-
- /* Even ignoring the "fast" flag completely, there are still 18
- * different combinations of save_type, shutdown and interact_style.
- * We interpret them as follows:
- *
- * Type Shutdown Interact Interpretation
- * G F A/E/N do nothing (1)
- * G T N do nothing (1)*
- * G T A/E quit_requested (2)
- * L/B F A/E/N save_state (3)
- * L/B T N save_state (3)*
- * L/B T A/E quit_requested, then save_state (4)
- *
- * 1. Do nothing, because the SM asked us to do something
- * uninteresting (save open files, but then don't quit
- * afterward) or rude (save open files without asking the user
- * for confirmation).
- *
- * 2. Request interaction and then emit ::quit_requested. This
- * perhaps isn't quite correct for the SmInteractStyleErrors
- * case, but we don't care.
- *
- * 3. Emit ::save_state. The SmSaveBoth SaveYourselfs in these
- * rows essentially get demoted to SmSaveLocal, because their
- * Global halves correspond to "do nothing".
- *
- * 4. Request interaction, emit ::quit_requested, and then emit
- * ::save_state after interacting. This is the SmSaveBoth
- * equivalent of #2, but we also promote SmSaveLocal shutdown
- * SaveYourselfs to SmSaveBoth here, because we want to give
- * the user a chance to save open files before quitting.
- *
- * (* It would be nice if we could do something useful when the
- * session manager sends a SaveYourself with shutdown True and
- * SmInteractStyleNone. But we can't, so we just pretend it didn't
- * even tell us it was shutting down. The docs for ::quit mention
- * that it might not always be preceded by ::quit_requested.)
- */
-
- /* As an optimization, we don't actually request interaction and
- * emit ::quit_requested if the application isn't listening to the
- * signal.
- */
- wants_quit_requested = g_signal_has_handler_pending (xsmp, g_signal_lookup ("quit_requested", EGG_TYPE_SM_CLIENT), 0, FALSE);
-
- xsmp->need_save_state = (save_type != SmSaveGlobal);
- xsmp->need_quit_requested = (shutdown && wants_quit_requested &&
- interact_style != SmInteractStyleNone);
- xsmp->interact_errors = (interact_style == SmInteractStyleErrors);
-
- xsmp->shutting_down = shutdown;
-
- do_save_yourself (xsmp);
+
+ /* Even ignoring the "fast" flag completely, there are still 18
+ * different combinations of save_type, shutdown and interact_style.
+ * We interpret them as follows:
+ *
+ * Type Shutdown Interact Interpretation
+ * G F A/E/N do nothing (1)
+ * G T N do nothing (1)*
+ * G T A/E quit_requested (2)
+ * L/B F A/E/N save_state (3)
+ * L/B T N save_state (3)*
+ * L/B T A/E quit_requested, then save_state (4)
+ *
+ * 1. Do nothing, because the SM asked us to do something
+ * uninteresting (save open files, but then don't quit
+ * afterward) or rude (save open files without asking the user
+ * for confirmation).
+ *
+ * 2. Request interaction and then emit ::quit_requested. This
+ * perhaps isn't quite correct for the SmInteractStyleErrors
+ * case, but we don't care.
+ *
+ * 3. Emit ::save_state. The SmSaveBoth SaveYourselfs in these
+ * rows essentially get demoted to SmSaveLocal, because their
+ * Global halves correspond to "do nothing".
+ *
+ * 4. Request interaction, emit ::quit_requested, and then emit
+ * ::save_state after interacting. This is the SmSaveBoth
+ * equivalent of #2, but we also promote SmSaveLocal shutdown
+ * SaveYourselfs to SmSaveBoth here, because we want to give
+ * the user a chance to save open files before quitting.
+ *
+ * (* It would be nice if we could do something useful when the
+ * session manager sends a SaveYourself with shutdown True and
+ * SmInteractStyleNone. But we can't, so we just pretend it didn't
+ * even tell us it was shutting down. The docs for ::quit mention
+ * that it might not always be preceded by ::quit_requested.)
+ */
+
+ /* As an optimization, we don't actually request interaction and
+ * emit ::quit_requested if the application isn't listening to the
+ * signal.
+ */
+ wants_quit_requested = g_signal_has_handler_pending (xsmp, g_signal_lookup ("quit_requested", EGG_TYPE_SM_CLIENT), 0, FALSE);
+
+ xsmp->need_save_state = (save_type != SmSaveGlobal);
+ xsmp->need_quit_requested = (shutdown && wants_quit_requested &&
+ interact_style != SmInteractStyleNone);
+ xsmp->interact_errors = (interact_style == SmInteractStyleErrors);
+
+ xsmp->shutting_down = shutdown;
+
+ do_save_yourself (xsmp);
}
static void
do_save_yourself (EggSMClientXSMP *xsmp)
{
- if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED)
- {
- /* The SM cancelled a previous SaveYourself, but we haven't yet
- * had a chance to tell the application, so we can't start
- * processing this SaveYourself yet.
- */
- xsmp->waiting_to_save_myself = TRUE;
- update_pending_events (xsmp);
- return;
- }
-
- if (xsmp->need_quit_requested)
- {
- xsmp->state = XSMP_STATE_INTERACT_REQUEST;
-
- g_debug ("Sending InteractRequest(%s)",
- xsmp->interact_errors ? "Error" : "Normal");
- SmcInteractRequest (xsmp->connection,
- xsmp->interact_errors ? SmDialogError : SmDialogNormal,
- xsmp_interact,
- xsmp);
- return;
- }
-
- if (xsmp->need_save_state)
- {
- save_state (xsmp);
-
- /* Though unlikely, the client could have been disconnected
- * while the application was saving its state.
- */
- if (!xsmp->connection)
- return;
- }
-
- g_debug ("Sending SaveYourselfDone(True)");
- SmcSaveYourselfDone (xsmp->connection, True);
-
- /* The client state diagram in the XSMP spec says that after a
- * non-shutdown SaveYourself, we go directly back to "idle". But
- * everything else in both the XSMP spec and the libSM docs
- * disagrees.
- */
- xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
+ if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED)
+ {
+ /* The SM cancelled a previous SaveYourself, but we haven't yet
+ * had a chance to tell the application, so we can't start
+ * processing this SaveYourself yet.
+ */
+ xsmp->waiting_to_save_myself = TRUE;
+ update_pending_events (xsmp);
+ return;
+ }
+
+ if (xsmp->need_quit_requested)
+ {
+ xsmp->state = XSMP_STATE_INTERACT_REQUEST;
+
+ g_debug ("Sending InteractRequest(%s)",
+ xsmp->interact_errors ? "Error" : "Normal");
+ SmcInteractRequest (xsmp->connection,
+ xsmp->interact_errors ? SmDialogError : SmDialogNormal,
+ xsmp_interact,
+ xsmp);
+ return;
+ }
+
+ if (xsmp->need_save_state)
+ {
+ save_state (xsmp);
+
+ /* Though unlikely, the client could have been disconnected
+ * while the application was saving its state.
+ */
+ if (!xsmp->connection)
+ return;
+ }
+
+ g_debug ("Sending SaveYourselfDone(True)");
+ SmcSaveYourselfDone (xsmp->connection, True);
+
+ /* The client state diagram in the XSMP spec says that after a
+ * non-shutdown SaveYourself, we go directly back to "idle". But
+ * everything else in both the XSMP spec and the libSM docs
+ * disagrees.
+ */
+ xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
}
static void
save_state (EggSMClientXSMP *xsmp)
{
- GKeyFile *state_file;
- char *state_file_path, *data;
- EggDesktopFile *desktop_file;
- GPtrArray *restart, *discard;
- int offset, fd;
-
- /* We set xsmp->state before emitting save_state, but our caller is
- * responsible for setting it back afterward.
- */
- xsmp->state = XSMP_STATE_SAVE_YOURSELF;
-
- state_file = egg_sm_client_save_state ((EggSMClient *)xsmp);
- if (!state_file)
- {
- restart = generate_command (xsmp->restart_command, xsmp->client_id, NULL);
- set_properties (xsmp,
- ptrarray_prop (SmRestartCommand, restart),
- NULL);
- g_ptr_array_free (restart, TRUE);
-
- if (xsmp->set_discard_command)
- {
- discard = generate_command (xsmp->discard_command, NULL, NULL);
- set_properties (xsmp,
- ptrarray_prop (SmDiscardCommand, discard),
- NULL);
- g_ptr_array_free (discard, TRUE);
- }
- else
- delete_properties (xsmp, SmDiscardCommand, NULL);
-
- return;
- }
-
- desktop_file = egg_get_desktop_file ();
- if (desktop_file)
- {
- GKeyFile *merged_file;
- char *desktop_file_path;
-
- merged_file = g_key_file_new ();
- desktop_file_path =
- g_filename_from_uri (egg_desktop_file_get_source (desktop_file),
- NULL, NULL);
- if (desktop_file_path &&
- g_key_file_load_from_file (merged_file, desktop_file_path,
- G_KEY_FILE_KEEP_COMMENTS |
- G_KEY_FILE_KEEP_TRANSLATIONS, NULL))
+ GKeyFile *state_file;
+ char *state_file_path, *data;
+ EggDesktopFile *desktop_file;
+ GPtrArray *restart, *discard;
+ int offset, fd;
+
+ /* We set xsmp->state before emitting save_state, but our caller is
+ * responsible for setting it back afterward.
+ */
+ xsmp->state = XSMP_STATE_SAVE_YOURSELF;
+
+ state_file = egg_sm_client_save_state ((EggSMClient *)xsmp);
+ if (!state_file)
{
- guint g, k, i;
- char **groups, **keys, *value, *exec;
-
- groups = g_key_file_get_groups (state_file, NULL);
- for (g = 0; groups[g]; g++)
- {
- keys = g_key_file_get_keys (state_file, groups[g], NULL, NULL);
- for (k = 0; keys[k]; k++)
+ restart = generate_command (xsmp->restart_command, xsmp->client_id, NULL);
+ set_properties (xsmp,
+ ptrarray_prop (SmRestartCommand, restart),
+ NULL);
+ g_ptr_array_free (restart, TRUE);
+
+ if (xsmp->set_discard_command)
{
- value = g_key_file_get_value (state_file, groups[g],
- keys[k], NULL);
- if (value)
- {
- g_key_file_set_value (merged_file, groups[g],
- keys[k], value);
- g_free (value);
- }
+ discard = generate_command (xsmp->discard_command, NULL, NULL);
+ set_properties (xsmp,
+ ptrarray_prop (SmDiscardCommand, discard),
+ NULL);
+ g_ptr_array_free (discard, TRUE);
}
- g_strfreev (keys);
- }
- g_strfreev (groups);
-
- g_key_file_free (state_file);
- state_file = merged_file;
-
- /* Update Exec key using "--sm-client-state-file %k" */
- restart = generate_command (xsmp->restart_command,
- NULL, "%k");
- for (i = 0; i < restart->len; i++)
- restart->pdata[i] = g_shell_quote (restart->pdata[i]);
- g_ptr_array_add (restart, NULL);
- exec = g_strjoinv (" ", (char **)restart->pdata);
- g_strfreev ((char **)restart->pdata);
- g_ptr_array_free (restart, FALSE);
-
- g_key_file_set_string (state_file, EGG_DESKTOP_FILE_GROUP,
- EGG_DESKTOP_FILE_KEY_EXEC,
- exec);
- g_free (exec);
+ else
+ delete_properties (xsmp, SmDiscardCommand, NULL);
+
+ return;
}
- else
- desktop_file = NULL;
-
- g_free (desktop_file_path);
- }
-
- /* Now write state_file to disk. (We can't use mktemp(), because
- * that requires the filename to end with "XXXXXX", and we want
- * it to end with ".desktop".)
- */
-
- data = g_key_file_to_data (state_file, NULL, NULL);
- g_key_file_free (state_file);
-
- offset = 0;
- while (1)
- {
- state_file_path = g_strdup_printf ("%s%csession-state%c%s-%ld.%s",
- g_get_user_config_dir (),
- G_DIR_SEPARATOR, G_DIR_SEPARATOR,
- g_get_prgname (),
- (long)time (NULL) + offset,
- desktop_file ? "desktop" : "state");
-
- fd = open (state_file_path, O_WRONLY | O_CREAT | O_EXCL, 0644);
- if (fd == -1)
+
+ desktop_file = egg_get_desktop_file ();
+ if (desktop_file)
{
- if (errno == EEXIST)
- {
- offset++;
- g_free (state_file_path);
- continue;
- }
- else if (errno == ENOTDIR || errno == ENOENT)
- {
- char *sep = strrchr (state_file_path, G_DIR_SEPARATOR);
-
- *sep = '\0';
- if (g_mkdir_with_parents (state_file_path, 0755) != 0)
+ GKeyFile *merged_file;
+ char *desktop_file_path;
+
+ merged_file = g_key_file_new ();
+ desktop_file_path =
+ g_filename_from_uri (egg_desktop_file_get_source (desktop_file),
+ NULL, NULL);
+ if (desktop_file_path &&
+ g_key_file_load_from_file (merged_file, desktop_file_path,
+ G_KEY_FILE_KEEP_COMMENTS |
+ G_KEY_FILE_KEEP_TRANSLATIONS, NULL))
{
- g_warning ("Could not create directory '%s'",
- state_file_path);
- g_free (state_file_path);
- state_file_path = NULL;
- break;
+ guint g, k, i;
+ char **groups, **keys, *value, *exec;
+
+ groups = g_key_file_get_groups (state_file, NULL);
+ for (g = 0; groups[g]; g++)
+ {
+ keys = g_key_file_get_keys (state_file, groups[g], NULL, NULL);
+ for (k = 0; keys[k]; k++)
+ {
+ value = g_key_file_get_value (state_file, groups[g],
+ keys[k], NULL);
+ if (value)
+ {
+ g_key_file_set_value (merged_file, groups[g],
+ keys[k], value);
+ g_free (value);
+ }
+ }
+ g_strfreev (keys);
+ }
+ g_strfreev (groups);
+
+ g_key_file_free (state_file);
+ state_file = merged_file;
+
+ /* Update Exec key using "--sm-client-state-file %k" */
+ restart = generate_command (xsmp->restart_command,
+ NULL, "%k");
+ for (i = 0; i < restart->len; i++)
+ restart->pdata[i] = g_shell_quote (restart->pdata[i]);
+ g_ptr_array_add (restart, NULL);
+ exec = g_strjoinv (" ", (char **)restart->pdata);
+ g_strfreev ((char **)restart->pdata);
+ g_ptr_array_free (restart, FALSE);
+
+ g_key_file_set_string (state_file, EGG_DESKTOP_FILE_GROUP,
+ EGG_DESKTOP_FILE_KEY_EXEC,
+ exec);
+ g_free (exec);
}
+ else
+ desktop_file = NULL;
+
+ g_free (desktop_file_path);
+ }
- continue;
- }
+ /* Now write state_file to disk. (We can't use mktemp(), because
+ * that requires the filename to end with "XXXXXX", and we want
+ * it to end with ".desktop".)
+ */
- g_warning ("Could not create file '%s': %s",
- state_file_path, g_strerror (errno));
- g_free (state_file_path);
- state_file_path = NULL;
- break;
+ data = g_key_file_to_data (state_file, NULL, NULL);
+ g_key_file_free (state_file);
+
+ offset = 0;
+ while (1)
+ {
+ state_file_path = g_strdup_printf ("%s%csession-state%c%s-%ld.%s",
+ g_get_user_config_dir (),
+ G_DIR_SEPARATOR, G_DIR_SEPARATOR,
+ g_get_prgname (),
+ (long)time (NULL) + offset,
+ desktop_file ? "desktop" : "state");
+
+ fd = open (state_file_path, O_WRONLY | O_CREAT | O_EXCL, 0644);
+ if (fd == -1)
+ {
+ if (errno == EEXIST)
+ {
+ offset++;
+ g_free (state_file_path);
+ continue;
+ }
+ else if (errno == ENOTDIR || errno == ENOENT)
+ {
+ char *sep = strrchr (state_file_path, G_DIR_SEPARATOR);
+
+ *sep = '\0';
+ if (g_mkdir_with_parents (state_file_path, 0755) != 0)
+ {
+ g_warning ("Could not create directory '%s'",
+ state_file_path);
+ g_free (state_file_path);
+ state_file_path = NULL;
+ break;
+ }
+
+ continue;
+ }
+
+ g_warning ("Could not create file '%s': %s",
+ state_file_path, g_strerror (errno));
+ g_free (state_file_path);
+ state_file_path = NULL;
+ break;
+ }
+
+ close (fd);
+ g_file_set_contents (state_file_path, data, -1, NULL);
+ break;
}
+ g_free (data);
+
+ restart = generate_command (xsmp->restart_command, xsmp->client_id,
+ state_file_path);
+ set_properties (xsmp,
+ ptrarray_prop (SmRestartCommand, restart),
+ NULL);
+ g_ptr_array_free (restart, TRUE);
- close (fd);
- g_file_set_contents (state_file_path, data, -1, NULL);
- break;
- }
- g_free (data);
-
- restart = generate_command (xsmp->restart_command, xsmp->client_id,
- state_file_path);
- set_properties (xsmp,
- ptrarray_prop (SmRestartCommand, restart),
- NULL);
- g_ptr_array_free (restart, TRUE);
-
- if (state_file_path)
- {
- set_properties (xsmp,
- array_prop (SmDiscardCommand,
- "/bin/rm", "-rf", state_file_path,
- NULL),
- NULL);
- g_free (state_file_path);
- }
+ if (state_file_path)
+ {
+ set_properties (xsmp,
+ array_prop (SmDiscardCommand,
+ "/bin/rm", "-rf", state_file_path,
+ NULL),
+ NULL);
+ g_free (state_file_path);
+ }
}
static void
xsmp_interact (SmcConn smc_conn,
- SmPointer client_data)
+ SmPointer client_data)
{
- EggSMClientXSMP *xsmp = client_data;
- EggSMClient *client = client_data;
+ EggSMClientXSMP *xsmp = client_data;
+ EggSMClient *client = client_data;
- g_debug ("Received Interact message in state %s",
- EGG_SM_CLIENT_XSMP_STATE (xsmp));
+ g_debug ("Received Interact message in state %s",
+ EGG_SM_CLIENT_XSMP_STATE (xsmp));
- if (xsmp->state != XSMP_STATE_INTERACT_REQUEST)
- {
- fix_broken_state (xsmp, "Interact", TRUE, TRUE);
- return;
- }
+ if (xsmp->state != XSMP_STATE_INTERACT_REQUEST)
+ {
+ fix_broken_state (xsmp, "Interact", TRUE, TRUE);
+ return;
+ }
- xsmp->state = XSMP_STATE_INTERACT;
- egg_sm_client_quit_requested (client);
+ xsmp->state = XSMP_STATE_INTERACT;
+ egg_sm_client_quit_requested (client);
}
static void
xsmp_die (SmcConn smc_conn,
- SmPointer client_data)
+ SmPointer client_data)
{
- EggSMClientXSMP *xsmp = client_data;
- EggSMClient *client = client_data;
+ EggSMClientXSMP *xsmp = client_data;
+ EggSMClient *client = client_data;
- g_debug ("Received Die message in state %s",
- EGG_SM_CLIENT_XSMP_STATE (xsmp));
+ g_debug ("Received Die message in state %s",
+ EGG_SM_CLIENT_XSMP_STATE (xsmp));
- sm_client_xsmp_disconnect (xsmp);
- egg_sm_client_quit (client);
+ sm_client_xsmp_disconnect (xsmp);
+ egg_sm_client_quit (client);
}
static void
xsmp_save_complete (SmcConn smc_conn,
- SmPointer client_data)
+ SmPointer client_data)
{
- EggSMClientXSMP *xsmp = client_data;
+ EggSMClientXSMP *xsmp = client_data;
- g_debug ("Received SaveComplete message in state %s",
- EGG_SM_CLIENT_XSMP_STATE (xsmp));
+ g_debug ("Received SaveComplete message in state %s",
+ EGG_SM_CLIENT_XSMP_STATE (xsmp));
- if (xsmp->state == XSMP_STATE_SAVE_YOURSELF_DONE)
- xsmp->state = XSMP_STATE_IDLE;
- else
- fix_broken_state (xsmp, "SaveComplete", FALSE, FALSE);
+ if (xsmp->state == XSMP_STATE_SAVE_YOURSELF_DONE)
+ xsmp->state = XSMP_STATE_IDLE;
+ else
+ fix_broken_state (xsmp, "SaveComplete", FALSE, FALSE);
}
static void
xsmp_shutdown_cancelled (SmcConn smc_conn,
- SmPointer client_data)
+ SmPointer client_data)
{
- EggSMClientXSMP *xsmp = client_data;
- EggSMClient *client = client_data;
-
- g_debug ("Received ShutdownCancelled message in state %s",
- EGG_SM_CLIENT_XSMP_STATE (xsmp));
-
- xsmp->shutting_down = FALSE;
-
- if (xsmp->state == XSMP_STATE_SAVE_YOURSELF_DONE)
- {
- /* We've finished interacting and now the SM has agreed to
- * cancel the shutdown.
- */
- xsmp->state = XSMP_STATE_IDLE;
- egg_sm_client_quit_cancelled (client);
- }
- else if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED)
- {
- /* Hm... ok, so we got a shutdown SaveYourself, which got
- * cancelled, but the application was still interacting, so we
- * didn't tell it yet, and then *another* SaveYourself arrived,
- * which we must still be waiting to tell the app about, except
- * that now that SaveYourself has been cancelled too! Dizzy yet?
- */
- xsmp->waiting_to_save_myself = FALSE;
- update_pending_events (xsmp);
- }
- else
- {
- g_debug ("Sending SaveYourselfDone(False)");
- SmcSaveYourselfDone (xsmp->connection, False);
-
- if (xsmp->state == XSMP_STATE_INTERACT)
+ EggSMClientXSMP *xsmp = client_data;
+ EggSMClient *client = client_data;
+
+ g_debug ("Received ShutdownCancelled message in state %s",
+ EGG_SM_CLIENT_XSMP_STATE (xsmp));
+
+ xsmp->shutting_down = FALSE;
+
+ if (xsmp->state == XSMP_STATE_SAVE_YOURSELF_DONE)
+ {
+ /* We've finished interacting and now the SM has agreed to
+ * cancel the shutdown.
+ */
+ xsmp->state = XSMP_STATE_IDLE;
+ egg_sm_client_quit_cancelled (client);
+ }
+ else if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED)
{
- /* The application is currently interacting, so we can't
- * tell it about the cancellation yet; we will wait until
- * after it calls egg_sm_client_will_quit().
- */
- xsmp->state = XSMP_STATE_SHUTDOWN_CANCELLED;
+ /* Hm... ok, so we got a shutdown SaveYourself, which got
+ * cancelled, but the application was still interacting, so we
+ * didn't tell it yet, and then *another* SaveYourself arrived,
+ * which we must still be waiting to tell the app about, except
+ * that now that SaveYourself has been cancelled too! Dizzy yet?
+ */
+ xsmp->waiting_to_save_myself = FALSE;
+ update_pending_events (xsmp);
}
- else
+ else
{
- /* The shutdown was cancelled before the application got a
- * chance to interact.
- */
- xsmp->state = XSMP_STATE_IDLE;
+ g_debug ("Sending SaveYourselfDone(False)");
+ SmcSaveYourselfDone (xsmp->connection, False);
+
+ if (xsmp->state == XSMP_STATE_INTERACT)
+ {
+ /* The application is currently interacting, so we can't
+ * tell it about the cancellation yet; we will wait until
+ * after it calls egg_sm_client_will_quit().
+ */
+ xsmp->state = XSMP_STATE_SHUTDOWN_CANCELLED;
+ }
+ else
+ {
+ /* The shutdown was cancelled before the application got a
+ * chance to interact.
+ */
+ xsmp->state = XSMP_STATE_IDLE;
+ }
}
- }
}
/* Utilities */
@@ -1077,30 +1078,30 @@ xsmp_shutdown_cancelled (SmcConn smc_conn,
*/
static GPtrArray *
generate_command (char **argv, const char *client_id,
- const char *state_file)
+ const char *state_file)
{
- GPtrArray *cmd;
- int i;
+ GPtrArray *cmd;
+ int i;
- cmd = g_ptr_array_new ();
- g_ptr_array_add (cmd, argv[0]);
+ cmd = g_ptr_array_new ();
+ g_ptr_array_add (cmd, argv[0]);
- if (client_id)
- {
- g_ptr_array_add (cmd, (char *)"--sm-client-id");
- g_ptr_array_add (cmd, (char *)client_id);
- }
+ if (client_id)
+ {
+ g_ptr_array_add (cmd, (char *)"--sm-client-id");
+ g_ptr_array_add (cmd, (char *)client_id);
+ }
- if (state_file)
- {
- g_ptr_array_add (cmd, (char *)"--sm-client-state-file");
- g_ptr_array_add (cmd, (char *)state_file);
- }
+ if (state_file)
+ {
+ g_ptr_array_add (cmd, (char *)"--sm-client-state-file");
+ g_ptr_array_add (cmd, (char *)state_file);
+ }
- for (i = 1; argv[i]; i++)
- g_ptr_array_add (cmd, argv[i]);
+ for (i = 1; argv[i]; i++)
+ g_ptr_array_add (cmd, argv[i]);
- return cmd;
+ return cmd;
}
/* Takes a NULL-terminated list of SmProp * values, created by
@@ -1110,55 +1111,55 @@ generate_command (char **argv, const char *client_id,
static void
set_properties (EggSMClientXSMP *xsmp, ...)
{
- GPtrArray *props;
- SmProp *prop;
- va_list ap;
- guint i;
-
- props = g_ptr_array_new ();
-
- va_start (ap, xsmp);
- while ((prop = va_arg (ap, SmProp *)))
- g_ptr_array_add (props, prop);
- va_end (ap);
-
- if (xsmp->connection)
- {
- SmcSetProperties (xsmp->connection, props->len,
- (SmProp **)props->pdata);
- }
-
- for (i = 0; i < props->len; i++)
- {
- prop = props->pdata[i];
- g_free (prop->vals);
- g_free (prop);
- }
- g_ptr_array_free (props, TRUE);
+ GPtrArray *props;
+ SmProp *prop;
+ va_list ap;
+ guint i;
+
+ props = g_ptr_array_new ();
+
+ va_start (ap, xsmp);
+ while ((prop = va_arg (ap, SmProp *)))
+ g_ptr_array_add (props, prop);
+ va_end (ap);
+
+ if (xsmp->connection)
+ {
+ SmcSetProperties (xsmp->connection, props->len,
+ (SmProp **)props->pdata);
+ }
+
+ for (i = 0; i < props->len; i++)
+ {
+ prop = props->pdata[i];
+ g_free (prop->vals);
+ g_free (prop);
+ }
+ g_ptr_array_free (props, TRUE);
}
/* Takes a NULL-terminated list of property names and deletes them. */
static void
delete_properties (EggSMClientXSMP *xsmp, ...)
{
- GPtrArray *props;
- char *prop;
- va_list ap;
+ GPtrArray *props;
+ char *prop;
+ va_list ap;
- if (!xsmp->connection)
- return;
+ if (!xsmp->connection)
+ return;
- props = g_ptr_array_new ();
+ props = g_ptr_array_new ();
- va_start (ap, xsmp);
- while ((prop = va_arg (ap, char *)))
- g_ptr_array_add (props, prop);
- va_end (ap);
+ va_start (ap, xsmp);
+ while ((prop = va_arg (ap, char *)))
+ g_ptr_array_add (props, prop);
+ va_end (ap);
- SmcDeleteProperties (xsmp->connection, props->len,
- (char **)props->pdata);
+ SmcDeleteProperties (xsmp->connection, props->len,
+ (char **)props->pdata);
- g_ptr_array_free (props, TRUE);
+ g_ptr_array_free (props, TRUE);
}
/* Takes an array of strings and creates a LISTofARRAY8 property. The
@@ -1166,34 +1167,34 @@ delete_properties (EggSMClientXSMP *xsmp, ...)
* until you're done with the SmProp.
*/
static SmProp *
-array_prop (const char *name, ...)
+array_prop (const char *name, ...)
{
- SmProp *prop;
- SmPropValue pv;
- GArray *vals;
- char *value;
- va_list ap;
+ SmProp *prop;
+ SmPropValue pv;
+ GArray *vals;
+ char *value;
+ va_list ap;
- prop = g_new (SmProp, 1);
- prop->name = (char *)name;
- prop->type = (char *)SmLISTofARRAY8;
+ prop = g_new (SmProp, 1);
+ prop->name = (char *)name;
+ prop->type = (char *)SmLISTofARRAY8;
- vals = g_array_new (FALSE, FALSE, sizeof (SmPropValue));
+ vals = g_array_new (FALSE, FALSE, sizeof (SmPropValue));
- va_start (ap, name);
- while ((value = va_arg (ap, char *)))
- {
- pv.length = strlen (value);
- pv.value = value;
- g_array_append_val (vals, pv);
- }
+ va_start (ap, name);
+ while ((value = va_arg (ap, char *)))
+ {
+ pv.length = strlen (value);
+ pv.value = value;
+ g_array_append_val (vals, pv);
+ }
- prop->num_vals = vals->len;
- prop->vals = (SmPropValue *)vals->data;
+ prop->num_vals = vals->len;
+ prop->vals = (SmPropValue *)vals->data;
- g_array_free (vals, FALSE);
+ g_array_free (vals, FALSE);
- return prop;
+ return prop;
}
/* Takes a GPtrArray of strings and creates a LISTofARRAY8 property.
@@ -1203,30 +1204,30 @@ array_prop (const char *name, ...)
static SmProp *
ptrarray_prop (const char *name, GPtrArray *values)
{
- SmProp *prop;
- SmPropValue pv;
- GArray *vals;
- guint i;
+ SmProp *prop;
+ SmPropValue pv;
+ GArray *vals;
+ guint i;
- prop = g_new (SmProp, 1);
- prop->name = (char *)name;
- prop->type = (char *)SmLISTofARRAY8;
+ prop = g_new (SmProp, 1);
+ prop->name = (char *)name;
+ prop->type = (char *)SmLISTofARRAY8;
- vals = g_array_new (FALSE, FALSE, sizeof (SmPropValue));
+ vals = g_array_new (FALSE, FALSE, sizeof (SmPropValue));
- for (i = 0; i < values->len; i++)
- {
- pv.length = strlen (values->pdata[i]);
- pv.value = values->pdata[i];
- g_array_append_val (vals, pv);
- }
+ for (i = 0; i < values->len; i++)
+ {
+ pv.length = strlen (values->pdata[i]);
+ pv.value = values->pdata[i];
+ g_array_append_val (vals, pv);
+ }
- prop->num_vals = vals->len;
- prop->vals = (SmPropValue *)vals->data;
+ prop->num_vals = vals->len;
+ prop->vals = (SmPropValue *)vals->data;
- g_array_free (vals, FALSE);
+ g_array_free (vals, FALSE);
- return prop;
+ return prop;
}
/* Takes a string and creates an ARRAY8 property. The string is
@@ -1236,46 +1237,46 @@ ptrarray_prop (const char *name, GPtrArray *values)
static SmProp *
string_prop (const char *name, const char *value)
{
- SmProp *prop;
+ SmProp *prop;
- prop = g_new (SmProp, 1);
- prop->name = (char *)name;
- prop->type = (char *)SmARRAY8;
+ prop = g_new (SmProp, 1);
+ prop->name = (char *)name;
+ prop->type = (char *)SmARRAY8;
- prop->num_vals = 1;
- prop->vals = g_new (SmPropValue, 1);
+ prop->num_vals = 1;
+ prop->vals = g_new (SmPropValue, 1);
- prop->vals[0].length = strlen (value);
- prop->vals[0].value = (char *)value;
+ prop->vals[0].length = strlen (value);
+ prop->vals[0].value = (char *)value;
- return prop;
+ return prop;
}
/* Takes a char and creates a CARD8 property. */
static SmProp *
card8_prop (const char *name, unsigned char value)
{
- SmProp *prop;
- char *card8val;
+ SmProp *prop;
+ char *card8val;
- /* To avoid having to allocate and free prop->vals[0], we cheat and
- * make vals a 2-element-long array and then use the second element
- * to store value.
- */
+ /* To avoid having to allocate and free prop->vals[0], we cheat and
+ * make vals a 2-element-long array and then use the second element
+ * to store value.
+ */
- prop = g_new (SmProp, 1);
- prop->name = (char *)name;
- prop->type = (char *)SmCARD8;
+ prop = g_new (SmProp, 1);
+ prop->name = (char *)name;
+ prop->type = (char *)SmCARD8;
- prop->num_vals = 1;
- prop->vals = g_new (SmPropValue, 2);
- card8val = (char *)(&prop->vals[1]);
- card8val[0] = value;
+ prop->num_vals = 1;
+ prop->vals = g_new (SmPropValue, 2);
+ card8val = (char *)(&prop->vals[1]);
+ card8val[0] = value;
- prop->vals[0].length = 1;
- prop->vals[0].value = card8val;
+ prop->vals[0].length = 1;
+ prop->vals[0].value = card8val;
- return prop;
+ return prop;
}
/* ICE code. This makes no effort to play nice with anyone else trying
@@ -1292,105 +1293,105 @@ card8_prop (const char *name, unsigned char value)
#include <fcntl.h>
static void ice_error_handler (IceConn ice_conn,
- Bool swap,
- int offending_minor_opcode,
- unsigned long offending_sequence,
- int error_class,
- int severity,
- IcePointer values);
+ Bool swap,
+ int offending_minor_opcode,
+ unsigned long offending_sequence,
+ int error_class,
+ int severity,
+ IcePointer values);
static void ice_io_error_handler (IceConn ice_conn);
static void ice_connection_watch (IceConn ice_conn,
- IcePointer client_data,
- Bool opening,
- IcePointer *watch_data);
+ IcePointer client_data,
+ Bool opening,
+ IcePointer *watch_data);
static void
ice_init (void)
{
- IceSetIOErrorHandler (ice_io_error_handler);
- IceSetErrorHandler (ice_error_handler);
- IceAddConnectionWatch (ice_connection_watch, NULL);
+ IceSetIOErrorHandler (ice_io_error_handler);
+ IceSetErrorHandler (ice_error_handler);
+ IceAddConnectionWatch (ice_connection_watch, NULL);
}
static gboolean
process_ice_messages (IceConn ice_conn)
{
- IceProcessMessagesStatus status;
+ IceProcessMessagesStatus status;
- gdk_threads_enter ();
- status = IceProcessMessages (ice_conn, NULL, NULL);
- gdk_threads_leave ();
+ gdk_threads_enter ();
+ status = IceProcessMessages (ice_conn, NULL, NULL);
+ gdk_threads_leave ();
- switch (status)
- {
- case IceProcessMessagesSuccess:
- return TRUE;
+ switch (status)
+ {
+ case IceProcessMessagesSuccess:
+ return TRUE;
- case IceProcessMessagesIOError:
- sm_client_xsmp_disconnect (IceGetConnectionContext (ice_conn));
- return FALSE;
+ case IceProcessMessagesIOError:
+ sm_client_xsmp_disconnect (IceGetConnectionContext (ice_conn));
+ return FALSE;
- case IceProcessMessagesConnectionClosed:
- return FALSE;
+ case IceProcessMessagesConnectionClosed:
+ return FALSE;
- default:
- g_assert_not_reached ();
- }
+ default:
+ g_assert_not_reached ();
+ }
}
static gboolean
ice_iochannel_watch (GIOChannel *channel,
- GIOCondition condition,
- gpointer client_data)
+ GIOCondition condition,
+ gpointer client_data)
{
- return process_ice_messages (client_data);
+ return process_ice_messages (client_data);
}
static void
ice_connection_watch (IceConn ice_conn,
- IcePointer client_data,
- Bool opening,
- IcePointer *watch_data)
+ IcePointer client_data,
+ Bool opening,
+ IcePointer *watch_data)
{
- guint watch_id;
-
- if (opening)
- {
- GIOChannel *channel;
- int fd = IceConnectionNumber (ice_conn);
-
- fcntl (fd, F_SETFD, fcntl (fd, F_GETFD, 0) | FD_CLOEXEC);
- channel = g_io_channel_unix_new (fd);
- watch_id = g_io_add_watch (channel, G_IO_IN | G_IO_ERR,
- ice_iochannel_watch, ice_conn);
- g_io_channel_unref (channel);
-
- *watch_data = GUINT_TO_POINTER (watch_id);
- }
- else
- {
- watch_id = GPOINTER_TO_UINT (*watch_data);
- g_source_remove (watch_id);
- }
+ guint watch_id;
+
+ if (opening)
+ {
+ GIOChannel *channel;
+ int fd = IceConnectionNumber (ice_conn);
+
+ fcntl (fd, F_SETFD, fcntl (fd, F_GETFD, 0) | FD_CLOEXEC);
+ channel = g_io_channel_unix_new (fd);
+ watch_id = g_io_add_watch (channel, G_IO_IN | G_IO_ERR,
+ ice_iochannel_watch, ice_conn);
+ g_io_channel_unref (channel);
+
+ *watch_data = GUINT_TO_POINTER (watch_id);
+ }
+ else
+ {
+ watch_id = GPOINTER_TO_UINT (*watch_data);
+ g_source_remove (watch_id);
+ }
}
static void
ice_error_handler (IceConn ice_conn,
- Bool swap,
- int offending_minor_opcode,
- unsigned long offending_sequence,
- int error_class,
- int severity,
- IcePointer values)
+ Bool swap,
+ int offending_minor_opcode,
+ unsigned long offending_sequence,
+ int error_class,
+ int severity,
+ IcePointer values)
{
- /* Do nothing */
-}
+ /* Do nothing */
+}
static void
ice_io_error_handler (IceConn ice_conn)
{
- /* Do nothing */
-}
+ /* Do nothing */
+}
static void
smc_error_handler (SmcConn smc_conn,
@@ -1401,5 +1402,5 @@ smc_error_handler (SmcConn smc_conn,
int severity,
SmPointer values)
{
- /* Do nothing */
+ /* Do nothing */
}