--- ./libxfcegui4/session-client.c.orig 2008-10-23 10:20:45.000000000 +0300 +++ ./libxfcegui4/session-client.c 2009-05-18 21:33:32.000000000 +0300 @@ -366,7 +366,7 @@ } } else if ((session_client->interact_style != SESSION_INTERACT_NONE) - && (session_client->interact)) + && (session_client->interact_2 || session_client->interact)) { Status status; status = @@ -385,7 +385,7 @@ } else if ((session_client->current_state == SESSION_CLIENT_SAVING_PHASE_2) && (session_client->interact_style != SESSION_INTERACT_NONE) - && (session_client->interact)) + && (session_client->interact_2 || session_client->interact)) /* We go to interact only if 1) we're allowed to do so and 2) the client needs it, ie it has set a hook for interact */ { Status status; @@ -408,6 +408,7 @@ || (session_client->current_state == SESSION_CLIENT_DONE_WITH_INTERACT)) { + set_clone_restart_commands (session_client); SmcSaveYourselfDone ((SmcConn) session_client->session_connection, True); @@ -468,7 +469,6 @@ } } - set_clone_restart_commands (session_client); TRACE ("save_yourself - SESSION_CLIENT_SAVING_PHASE_1"); session_client->current_state = SESSION_CLIENT_SAVING_PHASE_1; switch (interact_style) @@ -547,9 +547,15 @@ interact (SmcConn smc_conn, SmPointer client_data) { SessionClient *session_client = (SessionClient *) client_data; + gboolean cancel = FALSE; TRACE ("entering interact"); - if (session_client->interact) + if (session_client->interact_2) + { + cancel = (*session_client->interact_2) (session_client->data, + session_client->interact_style); + } + else if (session_client->interact) { (*session_client->interact) (session_client->data, session_client->interact_style); @@ -558,173 +564,140 @@ TRACE ("interact - SESSION_CLIENT_DONE_WITH_INTERACT"); session_client->current_state = SESSION_CLIENT_DONE_WITH_INTERACT; - SmcInteractDone ((SmcConn) session_client->session_connection, False); + SmcInteractDone ((SmcConn) session_client->session_connection, cancel); save_yourself_possibly_done (session_client); } static void -set_clone_restart_commands (SessionClient * session_client) +set_property_from_command (SessionClient * session_client, char *command, + gchar **ptr, gint add_sm_id, gboolean add_display) { SmProp prop, *props[1]; - gchar **ptr, **args; + gchar **args; gint i = 0; gint argc; SmPropValue *vals; + gchar *display_name; - if ((ptr = session_client->restart_command)) - { - gboolean have_sm_id = FALSE; + if (!ptr) + return; - /* Restart */ - ptr = session_client->restart_command; - args = ptr; - i = 0; - for (argc = 0; *ptr; ptr++) - { - if (!g_ascii_strncasecmp (*ptr, SM_ID_ARG, strlen (SM_ID_ARG))) - { - have_sm_id = TRUE; - } - argc++; - } - if (!have_sm_id) + args = ptr; + for (argc = 0; *args; args++) + { + if (!g_ascii_strncasecmp (*args, SM_ID_ARG, strlen (SM_ID_ARG))) { - argc += 2; + add_sm_id = FALSE; } - vals = g_new (SmPropValue, argc); - ptr = args; - while (*ptr) + else if (!g_ascii_strncasecmp (*args, DPY_ARG, strlen (DPY_ARG))) { - vals[i].length = strlen (*ptr); - vals[i++].value = *ptr++; + add_display = FALSE; } - if (!have_sm_id) - { - vals[i].length = strlen (SM_ID_ARG); - vals[i++].value = SM_ID_ARG; - vals[i].length = strlen (session_client->given_client_id); - vals[i++].value = session_client->given_client_id; - } - prop.name = SmRestartCommand; - prop.type = SmLISTofARRAY8; - prop.vals = vals; - prop.num_vals = argc; + argc++; + } - props[0] = ∝ - SmcSetProperties ((SmcConn) session_client->session_connection, 1, - props); - g_free (vals); + if (add_sm_id) + { + argc += 2; } + if (add_display) + { + GdkDisplay *dpy = gdk_display_get_default(); - /* Clone */ - if ((ptr = - session_client->clone_command ? session_client-> - clone_command : session_client->restart_command)) - { - args = ptr; - for (argc = 0; *ptr; ptr++) - argc++; - vals = g_new (SmPropValue, argc); - ptr = args; - i = 0; - while (*ptr) + if (dpy != NULL) + { + display_name = (gchar *)gdk_display_get_name(dpy); + argc += 2; + } + else { - vals[i].length = strlen (*ptr); - vals[i++].value = *ptr++; + add_display = FALSE; } + } - prop.name = SmCloneCommand; - prop.type = SmLISTofARRAY8; - prop.vals = vals; - prop.num_vals = argc; - - props[0] = ∝ - SmcSetProperties ((SmcConn) session_client->session_connection, 1, - props); - g_free (vals); + vals = g_new (SmPropValue, argc); + i = 0; + while (*ptr) + { + vals[i].length = strlen (*ptr); + vals[i++].value = *ptr; + ptr++; } - /* Resign */ - if ((ptr = session_client->resign_command)) + if (add_sm_id) { - args = ptr; - for (argc = 0; *ptr; ptr++) - argc++; - vals = g_new (SmPropValue, argc); - ptr = args; - i = 0; - while (*ptr) - { - vals[i].length = strlen (*ptr); - vals[i++].value = *ptr++; - } + vals[i].length = strlen (SM_ID_ARG); + vals[i++].value = SM_ID_ARG; + vals[i].length = strlen (session_client->given_client_id); + vals[i++].value = session_client->given_client_id; + } + if (add_display) + { + vals[i].length = strlen (DPY_ARG); + vals[i++].value = DPY_ARG; + vals[i].length = strlen (display_name); + vals[i++].value = display_name; + } + + prop.name = command; + prop.type = SmLISTofARRAY8; + prop.vals = vals; + prop.num_vals = argc; - prop.name = SmResignCommand; - prop.type = SmLISTofARRAY8; - prop.vals = vals; - prop.num_vals = argc; + props[0] = ∝ + SmcSetProperties ((SmcConn) session_client->session_connection, 1, props); + g_free (vals); +} - props[0] = ∝ - SmcSetProperties ((SmcConn) session_client->session_connection, 1, - props); - g_free (prop.vals); - } +static void +set_clone_restart_commands (SessionClient * session_client) +{ + /* Restart */ + set_property_from_command (session_client, SmRestartCommand, + session_client->restart_command, TRUE, TRUE); - /* Discard */ - if ((ptr = session_client->discard_command)) - { - args = ptr; - for (argc = 0; *ptr; ptr++) - argc++; - vals = g_new (SmPropValue, argc); - ptr = args; - i = 0; - while (*ptr) - { - vals[i].length = strlen (*ptr); - vals[i++].value = *ptr++; - } + /* Clone */ + set_property_from_command (session_client, SmCloneCommand, + session_client->clone_command ? + session_client->clone_command : + session_client->restart_command, FALSE, TRUE); - prop.name = SmDiscardCommand; - prop.type = SmLISTofARRAY8; - prop.vals = vals; - prop.num_vals = argc; + /* Resign */ + set_property_from_command (session_client, SmResignCommand, + session_client->resign_command, FALSE, FALSE); - props[0] = ∝ - SmcSetProperties ((SmcConn) session_client->session_connection, 1, - props); - g_free (prop.vals); - } + /* Discard */ + set_property_from_command (session_client, SmDiscardCommand, + session_client->discard_command, FALSE, FALSE); /* Shutdown */ - if ((ptr = session_client->shutdown_command)) - { - args = ptr; - for (argc = 0; *ptr; ptr++) - argc++; - vals = g_new (SmPropValue, argc); - ptr = args; - i = 0; - while (*ptr) - { - vals[i].length = strlen (*ptr); - vals[i++].value = *ptr++; - } - - prop.name = SmShutdownCommand; - prop.type = SmLISTofARRAY8; - prop.vals = vals; - prop.num_vals = argc; + set_property_from_command (session_client, SmShutdownCommand, + session_client->shutdown_command, FALSE, FALSE); +} +#endif - props[0] = ∝ - SmcSetProperties ((SmcConn) session_client->session_connection, 1, - props); - g_free (prop.vals); +static gchar** safe_strvdup(gchar ** const source) +{ + int count; + int i; + gchar** result; + + if (source == NULL) { + return NULL; } + + count = g_strv_length((gchar **)source); + result = g_new0(gchar*, count + 1); + + for (i = 0; i < count; ++i) { + result[i] = g_strdup(source[i]); + } + + result[count] = NULL; + return result; } -#endif SessionClient * client_session_new_full (gpointer data, SessionRestartStyle restart_style, @@ -759,15 +732,16 @@ { session_client->current_directory = g_strdup (g_get_home_dir ()); } - session_client->clone_command = clone_command; - session_client->resign_command = resign_command; - session_client->restart_command = restart_command; - session_client->discard_command = discard_command; - session_client->shutdown_command = shutdown_command; + session_client->clone_command = safe_strvdup (clone_command); + session_client->resign_command = safe_strvdup (resign_command); + session_client->restart_command = safe_strvdup (restart_command); + session_client->discard_command = safe_strvdup (discard_command); + session_client->shutdown_command = safe_strvdup (shutdown_command); session_client->shutdown = FALSE; session_client->save_phase_2 = NULL; session_client->interact = NULL; + session_client->interact_2 = NULL; session_client->shutdown_cancelled = NULL; session_client->save_complete = NULL; session_client->die = NULL; @@ -781,10 +755,9 @@ SessionRestartStyle restart_style, gchar priority) { SessionClient *session_client; - gchar **array; + gchar **array, **args; gchar *client_id = NULL; - gboolean next_is_client_id = FALSE, had_display = FALSE; - GdkDisplay *dpy = gdk_display_get_default(); + gboolean next_is_client_id = FALSE; int i; if (argv == NULL) @@ -795,39 +768,31 @@ } else { - array = g_new (gchar *, argc + 3); - i = 0; + array = args = g_new (gchar *, argc + 1); - while (i < argc) + for (i = 0; i < argc; i++) { - array[i] = argv[i]; if (next_is_client_id) { client_id = argv[i]; next_is_client_id = FALSE; } - if (!g_ascii_strncasecmp (argv[i], SM_ID_ARG, strlen (SM_ID_ARG))) + else if (!g_ascii_strncasecmp (argv[i], SM_ID_ARG, strlen (SM_ID_ARG))) { next_is_client_id = TRUE; } - else if (!g_ascii_strncasecmp (argv[i], DPY_ARG, strlen (DPY_ARG))) + else { - had_display = TRUE; + *args++ = argv[i]; } - i++; } - if ((!had_display) && (dpy != NULL)) - { - array[i++] = "--display"; - array[i++] = (gchar *)gdk_display_get_name(dpy); - } - - array[i] = NULL; + *args = NULL; } session_client = client_session_new_full (data, restart_style, priority, client_id, - NULL, NULL, array, array, NULL, NULL, NULL); + NULL, NULL, array, NULL, NULL, NULL, NULL); + g_free (array); return session_client; } @@ -837,7 +802,9 @@ /* session_client->data; */ /* session_client->session_connection; */ - if (session_client->current_state != SESSION_CLIENT_DISCONNECTED) { + if (session_client->session_connection != NULL && + session_client->current_state != SESSION_CLIENT_DISCONNECTED) + { disconnect(session_client); } @@ -854,27 +821,6 @@ g_free(session_client); } -static gchar** safe_strvdup(gchar ** const source) -{ - int count; - int i; - gchar** result; - - if (source == NULL) { - return NULL; - } - - count = g_strv_length((gchar **)source); - result = g_new0(gchar*, count + 1); - - for (i = 0; i < count; ++i) { - result[i] = g_strdup(source[i]); - } - - result[count] = NULL; - return result; -} - void client_session_set_save_phase_2_callback(SessionClient * session_client, save_phase_2_callback value) { session_client->save_phase_2 = value; @@ -885,6 +831,11 @@ session_client->interact = value; } +void client_session_set_interact_2_callback(SessionClient * session_client, interact_2_callback value) +{ + session_client->interact_2 = value; +} + void client_session_set_shutdown_cancelled_callback(SessionClient * session_client, shutdown_cancelled_callback value) { session_client->shutdown_cancelled = value; @@ -954,7 +905,10 @@ #endif /* HAVE_LIBSM */ } -/* void client_session_set_interact_style(SessionClient * session_client, SessionInteractStyle value) */ +void client_session_set_interact_style(SessionClient * session_client, SessionInteractStyle value) +{ + session_client->interact_style = value; +} void client_session_set_priority(SessionClient * session_client, gchar value) { @@ -1053,84 +1007,46 @@ #endif /* HAVE_LIBSM */ } -void client_session_set_clone_command(SessionClient * session_client, gchar** const value) +static gchar **copy_command(gchar **command, gchar** const value) { - if (session_client->clone_command == value) { - return; - } - - if (session_client->clone_command != NULL) { - g_strfreev(session_client->clone_command); - session_client->clone_command = NULL; - } + if (command != value) + { + if (command != NULL) { + g_strfreev(command); + command = NULL; + } - if (value != NULL) { - session_client->clone_command = safe_strvdup(value); + if (value != NULL) { + command = safe_strvdup(value); + } } + + return command; } -void client_session_set_resign_command(SessionClient * session_client, gchar** const value) +void client_session_set_clone_command(SessionClient * session_client, gchar** const value) { - if (session_client->resign_command == value) { - return; - } - - if (session_client->resign_command != NULL) { - g_strfreev(session_client->resign_command); - session_client->resign_command = NULL; - } + session_client->clone_command = copy_command(session_client->clone_command, value); +} - if (value != NULL) { - session_client->resign_command = safe_strvdup(value); - } +void client_session_set_resign_command(SessionClient * session_client, gchar** const value) +{ + session_client->resign_command = copy_command(session_client->resign_command, value); } void client_session_set_restart_command(SessionClient * session_client, gchar** const value) { - if (session_client->restart_command == value) { - return; - } - - if (session_client->restart_command != NULL) { - g_strfreev(session_client->restart_command); - session_client->restart_command = NULL; - } - - if (value != NULL) { - session_client->restart_command = safe_strvdup(value); - } + session_client->restart_command = copy_command(session_client->restart_command, value); } void client_session_set_discard_command(SessionClient * session_client, gchar** const value) { - if (session_client->discard_command == value) { - return; - } - - if (session_client->discard_command != NULL) { - g_strfreev(session_client->discard_command); - session_client->discard_command = NULL; - } - - if (value != NULL) { - session_client->discard_command = safe_strvdup(value); - } + session_client->discard_command = copy_command(session_client->discard_command, value); } void client_session_set_shutdown_command(SessionClient * session_client, gchar** const value) { - if (session_client->shutdown_command == value) { - return; - } - - if (session_client->shutdown_command != NULL) { - g_strfreev(session_client->shutdown_command); - session_client->shutdown_command = NULL; - } - - if (value != NULL) { - session_client->shutdown_command = safe_strvdup(value); - } + session_client->shutdown_command = copy_command(session_client->shutdown_command, value); } save_phase_2_callback client_session_get_save_phase_2_callback(SessionClient * session_client) @@ -1143,6 +1059,11 @@ return session_client->interact; } +interact_2_callback client_session_get_interact_2_callback(SessionClient * session_client) +{ + return session_client->interact_2; +} + shutdown_cancelled_callback client_session_get_shutdown_cancelled_callback(SessionClient * session_client) { return session_client->shutdown_cancelled; --- ./libxfcegui4/session-client.h.orig 2008-10-23 10:20:45.000000000 +0300 +++ ./libxfcegui4/session-client.h 2009-05-17 13:53:43.000000000 +0300 @@ -62,6 +62,8 @@ typedef void (*save_phase_2_callback) (gpointer client_data); typedef void (*interact_callback) (gpointer client_data, SessionInteractStyle interact_style); +typedef gboolean (*interact_2_callback) (gpointer client_data, + SessionInteractStyle interact_style); typedef void (*shutdown_cancelled_callback) (gpointer client_data); typedef void (*save_complete_callback) (gpointer client_data); typedef void (*die_callback) (gpointer client_data); @@ -101,6 +103,10 @@ /* Private */ gboolean shutdown; + + /* Extended */ + + interact_2_callback interact_2; } SessionClient; @@ -126,12 +132,14 @@ void client_session_set_save_phase_2_callback(SessionClient * session_client, save_phase_2_callback value); void client_session_set_interact_callback(SessionClient * session_client, interact_callback value); +void client_session_set_interact_2_callback(SessionClient * session_client, interact_2_callback value); void client_session_set_shutdown_cancelled_callback(SessionClient * session_client, shutdown_cancelled_callback value); void client_session_set_save_complete_callback(SessionClient * session_client, save_complete_callback value); void client_session_set_die_callback(SessionClient * session_client, die_callback value); void client_session_set_save_yourself_callback(SessionClient * session_client, save_yourself_callback value); void client_session_set_data(SessionClient * session_client, gpointer value); void client_session_set_restart_style(SessionClient * session_client, SessionRestartStyle value); +void client_session_set_interact_style(SessionClient * session_client, SessionInteractStyle value); void client_session_set_priority(SessionClient * session_client, gchar value); void client_session_set_client_id(SessionClient * session_client, gchar const* value); void client_session_set_current_directory(SessionClient * session_client, gchar const* value); @@ -143,6 +151,7 @@ void client_session_set_shutdown_command(SessionClient * session_client, gchar** const value); save_phase_2_callback client_session_get_save_phase_2_callback(SessionClient * session_client); interact_callback client_session_get_interact_callback(SessionClient * session_client); +interact_2_callback client_session_get_interact_2_callback(SessionClient * session_client); shutdown_cancelled_callback client_session_get_shutdown_cancelled_callback(SessionClient * session_client); save_complete_callback client_session_get_save_complete_callback(SessionClient * session_client); die_callback client_session_get_die_callback(SessionClient * session_client);