+#ifdef HAVE_LIBSM
+static void
+sc_client_set_value (MainWindow *client,
+ gchar *name,
+ char *type,
+ int num_vals,
+ SmPropValue *vals)
+{
+ SmProp *proplist[1];
+ SmProp prop;
+
+ prop.name = name;
+ prop.type = type;
+ prop.num_vals = num_vals;
+ prop.vals = vals;
+
+ proplist[0]= ∝
+ SmcSetProperties ((SmcConn) client->smc_conn, 1, proplist);
+}
+
+static void sc_die_callback (SmcConn smc_conn, SmPointer client_data)
+{
+ clean_quit(NULL);
+}
+
+static void sc_save_complete_callback(SmcConn smc_conn, SmPointer client_data)
+{
+}
+
+static void sc_shutdown_cancelled_callback (SmcConn smc_conn, SmPointer client_data)
+{
+ MainWindow *mainwin = (MainWindow *)client_data;
+ SmcSaveYourselfDone ((SmcConn) mainwin->smc_conn, TRUE);
+}
+
+static void sc_save_yourself_callback (SmcConn smc_conn,
+ SmPointer client_data,
+ int save_style,
+ gboolean shutdown,
+ int interact_style,
+ gboolean fast) {
+
+ MainWindow *mainwin = (MainWindow *)client_data;
+ SmcSaveYourselfDone ((SmcConn) mainwin->smc_conn, TRUE);
+}
+
+static IceIOErrorHandler sc_ice_installed_handler;
+
+static void sc_ice_io_error_handler (IceConn connection)
+{
+ if (sc_ice_installed_handler)
+ (*sc_ice_installed_handler) (connection);
+}
+static gboolean sc_process_ice_messages (GIOChannel *source,
+ GIOCondition condition,
+ gpointer data)
+{
+ IceConn connection = (IceConn) data;
+ IceProcessMessagesStatus status;
+
+ status = IceProcessMessages (connection, NULL, NULL);
+
+ if (status == IceProcessMessagesIOError) {
+ IcePointer context = IceGetConnectionContext (connection);
+
+ if (context && GTK_IS_OBJECT (context)) {
+ guint disconnect_id = g_signal_lookup ("disconnect", G_OBJECT_TYPE (context));
+
+ if (disconnect_id > 0)
+ g_signal_emit (context, disconnect_id, 0);
+ } else {
+ IceSetShutdownNegotiation (connection, False);
+ IceCloseConnection (connection);
+ }
+ }
+
+ return TRUE;
+}
+
+static void new_ice_connection (IceConn connection, IcePointer client_data, Bool opening,
+ IcePointer *watch_data)
+{
+ guint input_id;
+
+ if (opening) {
+ GIOChannel *channel;
+ /* Make sure we don't pass on these file descriptors to any
+ exec'ed children */
+ fcntl(IceConnectionNumber(connection),F_SETFD,
+ fcntl(IceConnectionNumber(connection),F_GETFD,0) | FD_CLOEXEC);
+
+ channel = g_io_channel_unix_new (IceConnectionNumber (connection));
+ input_id = g_io_add_watch (channel,
+ G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI,
+ sc_process_ice_messages,
+ connection);
+ g_io_channel_unref (channel);
+
+ *watch_data = (IcePointer) GUINT_TO_POINTER (input_id);
+ } else {
+ input_id = GPOINTER_TO_UINT ((gpointer) *watch_data);
+ g_source_remove (input_id);
+ }
+}
+
+static void sc_session_manager_connect(MainWindow *mainwin)
+{
+ static gboolean connected = FALSE;
+ SmcCallbacks callbacks;
+ gchar *client_id;
+ IceIOErrorHandler default_handler;
+
+ if (connected)
+ return;
+ connected = TRUE;
+
+
+ sc_ice_installed_handler = IceSetIOErrorHandler (NULL);
+ default_handler = IceSetIOErrorHandler (sc_ice_io_error_handler);
+
+ if (sc_ice_installed_handler == default_handler)
+ sc_ice_installed_handler = NULL;
+
+ IceAddConnectionWatch (new_ice_connection, NULL);
+
+
+ callbacks.save_yourself.callback = sc_save_yourself_callback;
+ callbacks.die.callback = sc_die_callback;
+ callbacks.save_complete.callback = sc_save_complete_callback;
+ callbacks.shutdown_cancelled.callback = sc_shutdown_cancelled_callback;
+
+ callbacks.save_yourself.client_data =
+ callbacks.die.client_data =
+ callbacks.save_complete.client_data =
+ callbacks.shutdown_cancelled.client_data = (SmPointer) mainwin;
+ if (g_getenv ("SESSION_MANAGER")) {
+ gchar error_string_ret[256] = "";
+
+ mainwin->smc_conn= (gpointer)
+ SmcOpenConnection (NULL, mainwin,
+ SmProtoMajor, SmProtoMinor,
+ SmcSaveYourselfProcMask | SmcDieProcMask |
+ SmcSaveCompleteProcMask |
+ SmcShutdownCancelledProcMask,
+ &callbacks,
+ NULL, &client_id,
+ 256, error_string_ret);
+
+ if (error_string_ret[0])
+ g_warning ("While connecting to session manager:\n%s.",
+ error_string_ret);
+ else {
+ SmPropValue *vals;
+ vals = g_new (SmPropValue, 1);
+ vals[0].length = strlen(argv0);
+ vals[0].value = argv0;
+ sc_client_set_value (mainwin, SmCloneCommand, SmLISTofARRAY8, 1, vals);
+ sc_client_set_value (mainwin, SmRestartCommand, SmLISTofARRAY8, 1, vals);
+ sc_client_set_value (mainwin, SmProgram, SmARRAY8, 1, vals);
+
+ vals[0].length = strlen(g_get_user_name()?g_get_user_name():"");
+ vals[0].value = g_strdup(g_get_user_name()?g_get_user_name():"");
+ sc_client_set_value (mainwin, SmUserID, SmARRAY8, 1, vals);
+ }
+ }
+}
+#endif
+