--- gnome-panel-2.16.0/gnome-panel/panel-gdm.c.org	2006-10-27 21:13:28.000000000 +0100
+++ gnome-panel-2.16.0/gnome-panel/panel-gdm.c	2006-10-29 17:02:07.000000000 +0000
@@ -45,17 +45,20 @@
 
 #define GDM_PROTOCOL_SOCKET_PATH "/tmp/.gdm_socket"
 
-#define GDM_PROTOCOL_MSG_CLOSE         "CLOSE"
-#define GDM_PROTOCOL_MSG_VERSION       "VERSION"
-#define GDM_PROTOCOL_MSG_AUTHENTICATE  "AUTH_LOCAL"
-#define GDM_PROTOCOL_MSG_QUERY_ACTION  "QUERY_LOGOUT_ACTION"
-#define GDM_PROTOCOL_MSG_SET_ACTION    "SET_SAFE_LOGOUT_ACTION"
-#define GDM_PROTOCOL_MSG_FLEXI_XSERVER "FLEXI_XSERVER"
-
-#define GDM_ACTION_STR_NONE     "NONE"
-#define GDM_ACTION_STR_SHUTDOWN "HALT"
-#define GDM_ACTION_STR_REBOOT   "REBOOT"
-#define GDM_ACTION_STR_SUSPEND  "SUSPEND"
+#define GDM_PROTOCOL_MSG_CLOSE                     "CLOSE"
+#define GDM_PROTOCOL_MSG_VERSION                   "VERSION"
+#define GDM_PROTOCOL_MSG_AUTHENTICATE              "AUTH_LOCAL"
+#define GDM_PROTOCOL_MSG_QUERY_ACTION              "QUERY_LOGOUT_ACTION"
+#define GDM_PROTOCOL_MSG_CUSTOM_CMD_LABELS         "QUERY_CUSTOM_CMD_LABELS"
+#define GDM_PROTOCOL_MSG_CUSTOM_CMD_RESTART_STATUS "QUERY_CUSTOM_CMD_NO_RESTART_STATUS"
+#define GDM_PROTOCOL_MSG_SET_ACTION                "SET_SAFE_LOGOUT_ACTION"
+#define GDM_PROTOCOL_MSG_FLEXI_XSERVER             "FLEXI_XSERVER"
+
+#define GDM_ACTION_STR_NONE                "NONE"
+#define GDM_ACTION_STR_SHUTDOWN            "HALT"
+#define GDM_ACTION_STR_REBOOT              "REBOOT"
+#define GDM_ACTION_STR_SUSPEND             "SUSPEND"
+#define GDM_ACTION_STR_CUSTOM_CMD_TEMPLATE "CUSTOM_CMD"
 
 typedef struct {
         int fd;
@@ -63,15 +66,22 @@
 
         GdmLogoutAction available_actions;
         GdmLogoutAction current_actions;
-
+    
         time_t last_update;
+
+        unsigned long no_restart_status;
+        char **custom_cmd_labels;
+
 } GdmProtocolData;
 
 static GdmProtocolData gdm_protocol_data = {
         0,
+	0,
         GDM_LOGOUT_ACTION_NONE,
         GDM_LOGOUT_ACTION_NONE,
-        0
+        0,
+	0,
+	0
 };
 
 static char *
@@ -275,11 +285,11 @@
                           const char      *response)
 {
         char **actions;
-        int    i;
+        int    i, cmd_index;
 
         data->available_actions = GDM_LOGOUT_ACTION_NONE;
-        data->current_actions   = GDM_LOGOUT_ACTION_NONE;
-          
+        data->current_actions   = GDM_LOGOUT_ACTION_NONE;         
+	
         if (strncmp (response, "OK ", 3) != 0)
                 return;
 
@@ -307,7 +317,12 @@
                         action = GDM_LOGOUT_ACTION_REBOOT;
                 else if (!strcmp (str, GDM_ACTION_STR_SUSPEND))
                         action = GDM_LOGOUT_ACTION_SUSPEND;
-
+		else if (!strncmp (str, GDM_ACTION_STR_CUSTOM_CMD_TEMPLATE,
+				   strlen (GDM_ACTION_STR_CUSTOM_CMD_TEMPLATE))) {
+ 		        if (sscanf (str, GDM_ACTION_STR_CUSTOM_CMD_TEMPLATE  "%d", &cmd_index) == 1) {		    
+				action = (GDM_LOGOUT_ACTION_CUSTOM_CMD_FIRST << cmd_index);
+			}
+		}		
                 data->available_actions |= action;
                 if (selected)
                         data->current_actions |= action;
@@ -317,6 +332,35 @@
 }
 
 static void
+gdm_parse_custom_cmd_labels (GdmProtocolData *data,
+			     const char      *response)
+{
+	g_strfreev (data->custom_cmd_labels);
+	if (strncmp (response, "OK ", 3) != 0)
+		return;
+ 
+	response += 3;
+	
+	data->custom_cmd_labels = g_strsplit (response, ";", -1);
+
+}
+
+static void
+gdm_parse_custom_cmd_no_restart (GdmProtocolData *data,
+				 const char      *response)
+{
+	data->no_restart_status = 0;
+	if (strncmp (response, "OK ", 3) != 0)
+                return;
+	
+	response += 3;
+	
+	if (sscanf (response, "%ld", &data->no_restart_status) != 1)
+	        data->no_restart_status = 0;
+
+}
+
+static void
 gdm_update_logout_actions (GdmProtocolData *data)
 {
         time_t  current_time;
@@ -336,6 +380,16 @@
                 g_free (response);
         }
 
+	if ((response = gdm_send_protocol_msg (data, GDM_PROTOCOL_MSG_CUSTOM_CMD_LABELS))) {
+                gdm_parse_custom_cmd_labels (data, response);
+                g_free (response);
+        }
+
+	if ((response = gdm_send_protocol_msg (data, GDM_PROTOCOL_MSG_CUSTOM_CMD_RESTART_STATUS))) {
+                gdm_parse_custom_cmd_no_restart (data, response);
+                g_free (response);
+        }
+
         gdm_shutdown_protocol_connection (data);
 }
 
@@ -361,6 +415,7 @@
 	char *action_str = NULL;
         char *msg;
         char *response;
+	int i;
 
         if (!gdm_init_protocol_connection (&gdm_protocol_data))
                 return;
@@ -378,6 +433,13 @@
         case GDM_LOGOUT_ACTION_SUSPEND:
                 action_str = GDM_ACTION_STR_SUSPEND;
                 break;
+	default:
+	       for(i = 0; i < GDM_LOGOUT_ACTION_CUSTOM_CMD_MAX; i++) {
+		       if(action & (GDM_LOGOUT_ACTION_CUSTOM_CMD_FIRST << i)) {
+			       action_str = g_strdup_printf("%s%d", GDM_ACTION_STR_CUSTOM_CMD_TEMPLATE, i);
+			       break;
+		       }
+	       }	    	    
         }
 
         msg = g_strdup_printf (GDM_PROTOCOL_MSG_SET_ACTION " %s", action_str);
@@ -409,3 +471,20 @@
 
         gdm_shutdown_protocol_connection (&gdm_protocol_data);
 }
+
+const gchar *
+gdm_get_custom_cmd_label (gint cmd_index)
+{
+        if(gdm_protocol_data.custom_cmd_labels && gdm_protocol_data.custom_cmd_labels[cmd_index]) {
+		if (strcmp (gdm_protocol_data.custom_cmd_labels[cmd_index], "(null)"))
+			return gdm_protocol_data.custom_cmd_labels[cmd_index];
+	}
+	
+	return g_strdup_printf ("Custom_%d", cmd_index);
+}
+
+gboolean
+gdm_get_custom_cmd_no_restart_status (gint cmd_index)
+{    
+        return ((gboolean)(gdm_protocol_data.no_restart_status & (1 << cmd_index)));
+}
--- gnome-panel-2.16.0/gnome-panel/panel-gdm.h.org	2006-10-28 19:57:05.000000000 +0100
+++ gnome-panel-2.16.0/gnome-panel/panel-gdm.h	2006-10-29 17:00:52.000000000 +0000
@@ -34,11 +34,20 @@
 
 G_BEGIN_DECLS
 
+/* This macro should be in sync (have the same value) with the corresponding one in daemon/gdm.h
+   If it doesn't then worst case scenario we will miss out some of the commands,
+   best case we will search over the nope existant range of commands */   
+#define GDM_LOGOUT_ACTION_CUSTOM_CMD_MAX 10 
+
+/* Values between GDM_LOGOUT_ACTION_CUSTOM_CMD_FIRST and 
+   GDM_LOGOUT_ACTION_CUSTOM_CMD_LAST are reserved and should not be used */
 typedef enum {
-        GDM_LOGOUT_ACTION_NONE     = 0,
-        GDM_LOGOUT_ACTION_SHUTDOWN = 1 << 0,
-        GDM_LOGOUT_ACTION_REBOOT   = 1 << 1,
-        GDM_LOGOUT_ACTION_SUSPEND  = 1 << 2
+        GDM_LOGOUT_ACTION_NONE             = 0,
+        GDM_LOGOUT_ACTION_SHUTDOWN         = 1 << 0,
+        GDM_LOGOUT_ACTION_REBOOT           = 1 << 1,
+        GDM_LOGOUT_ACTION_SUSPEND          = 1 << 2,
+	GDM_LOGOUT_ACTION_CUSTOM_CMD_FIRST = 1 << 3,
+	GDM_LOGOUT_ACTION_CUSTOM_CMD_LAST  = 1 << (2 + GDM_LOGOUT_ACTION_CUSTOM_CMD_MAX)
 } GdmLogoutAction;
 
 gboolean gdm_supports_logout_action (GdmLogoutAction action);
@@ -47,6 +56,9 @@
 GdmLogoutAction gdm_get_logout_action (void);
 void            gdm_new_login         (void);
 
+const gchar *   gdm_get_custom_cmd_label (gint cmd_index);
+gboolean        gdm_get_custom_cmd_no_restart_status (gint cmd_index);
+
 G_END_DECLS
 
 #endif /* __GDM_LOGOUT_ACTION_H__ */
--- gnome-panel-2.16.0/gnome-panel/panel-logout.c.org	2006-10-28 23:11:57.000000000 +0100
+++ gnome-panel-2.16.0/gnome-panel/panel-logout.c	2006-10-29 16:50:40.000000000 +0000
@@ -39,13 +39,17 @@
 
 #define AUTOMATIC_ACTION_TIMEOUT 60
 
+/* Values between PANEL_LOGOUT_RESPONSE_CUSTOM_CMD_FIRST and
+   PANEL_LOGOUT_RESPONSE_CUSTOM_CMD_LAST are reserved and should not be used */
 enum {
 	PANEL_LOGOUT_RESPONSE_LOGOUT,
 	PANEL_LOGOUT_RESPONSE_SWITCH_USER,
 	PANEL_LOGOUT_RESPONSE_SHUTDOWN,
 	PANEL_LOGOUT_RESPONSE_REBOOT,
 	PANEL_LOGOUT_RESPONSE_STD,
-	PANEL_LOGOUT_RESPONSE_STR
+	PANEL_LOGOUT_RESPONSE_STR,
+	PANEL_LOGOUT_RESPONSE_CUSTOM_CMD_FIRST,
+	PANEL_LOGOUT_RESPONSE_CUSTOM_CMD_LAST = PANEL_LOGOUT_RESPONSE_CUSTOM_CMD_FIRST + GDM_LOGOUT_ACTION_CUSTOM_CMD_MAX - 1
 };
 
 struct _PanelLogoutDialogPrivate {
@@ -168,6 +172,8 @@
 		       gpointer   data)
 {
 	PanelPowerManager *power_manager;
+	int i;
+	gboolean is_valid_cmd = FALSE;
 
 	power_manager = g_object_ref (logout_dialog->priv->power_manager);
 	gtk_widget_destroy (GTK_WIDGET (logout_dialog));
@@ -202,7 +208,20 @@
 	case GTK_RESPONSE_DELETE_EVENT:
 		break;
 	default:
+	    {		
+		for(i = 0; i < GDM_LOGOUT_ACTION_CUSTOM_CMD_MAX; i++) {
+			if (response_id == (PANEL_LOGOUT_RESPONSE_CUSTOM_CMD_FIRST + i)) {
+				gdm_set_logout_action (GDM_LOGOUT_ACTION_CUSTOM_CMD_FIRST << i);
+				panel_session_request_logout ();
+				is_valid_cmd = TRUE;
+				break;
+			}
+		}
+		if (is_valid_cmd)
+			break;
+		
 		g_assert_not_reached ();
+	    }
 	}
 	g_object_unref (power_manager);
 }
@@ -309,12 +328,23 @@
 	icon_name    = NULL;
 	primary_text = NULL;
 
+	int i;
+
 	switch (type) {
 	case PANEL_LOGOUT_DIALOG_LOGOUT:
 		icon_name      = "gnome-logout";
 		primary_text   = _("Log out of this system now?");
 		// FIXME need to verify that this response can be used
 		logout_dialog->priv->default_response = PANEL_LOGOUT_DIALOG_LOGOUT;
+       
+		for(i = 0; i < GDM_LOGOUT_ACTION_CUSTOM_CMD_MAX; i++) {
+			if(gdm_supports_logout_action (GDM_LOGOUT_ACTION_CUSTOM_CMD_FIRST << i) && 
+			   gdm_get_custom_cmd_no_restart_status (i)) {
+				gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
+						       gdm_get_custom_cmd_label (i),
+						       PANEL_LOGOUT_RESPONSE_CUSTOM_CMD_FIRST + i);
+			}
+		}
 
 		//FIXME is gdm running?
 		gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
@@ -331,6 +361,15 @@
 		icon_name      = "gnome-shutdown";
 		primary_text   = _("Shut down this system now?");
 
+		for(i = 0; i < GDM_LOGOUT_ACTION_CUSTOM_CMD_MAX; i++) {
+			if(gdm_supports_logout_action (GDM_LOGOUT_ACTION_CUSTOM_CMD_FIRST << i) && 
+			   !gdm_get_custom_cmd_no_restart_status (i)) {
+				gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
+						       gdm_get_custom_cmd_label (i),
+						       PANEL_LOGOUT_RESPONSE_CUSTOM_CMD_FIRST + i);
+			}
+		}
+
 		logout_dialog->priv->default_response = PANEL_LOGOUT_RESPONSE_SHUTDOWN;
 		if (panel_power_manager_can_suspend (logout_dialog->priv->power_manager))
 			gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
@@ -342,7 +381,7 @@
 					       _("_Hibernate"),
 					       PANEL_LOGOUT_RESPONSE_STD);
 
-		//FIXME see previous FIXME
+		//FIXME see previous FIXME	
 		gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
 				       _("_Restart"),
 				       PANEL_LOGOUT_RESPONSE_REBOOT);
--- gnome-panel-2.16.0/ChangeLog.org	2006-10-29 16:54:39.000000000 +0000
+++ gnome-panel-2.16.0/ChangeLog	2006-10-29 16:58:47.000000000 +0000
@@ -0,0 +1,9 @@
+2006-10-29  Lukasz Zalewski <lukas@dcs.qmul.ac.uk>
+
+	* gnome-panel/panel-gdm.[hc]
+	* gnome-panel/panel-logout.c
+
+	Added and modified variables/functions to 
+	accomodate gdm's new custom command functionality
+	Enhancement request #358114
+	
