Index: gnome-session-2.19.4/gnome-session/gdm-logout-action.c =================================================================== --- gnome-session-2.19.4.orig/gnome-session/gdm-logout-action.c +++ gnome-session-2.19.4/gnome-session/gdm-logout-action.c @@ -56,6 +56,8 @@ #define GDM_ACTION_STR_REBOOT "REBOOT" #define GDM_ACTION_STR_SUSPEND "SUSPEND" +#define KDM_PROTOCOL_MSG_QUERY_ACTION "caps" + typedef struct { int fd; char *auth_cookie; @@ -64,6 +66,8 @@ typedef struct { GdmLogoutAction current_actions; time_t last_update; + + guint is_kdm : 1; } GdmProtocolData; static GdmProtocolData gdm_protocol_data = { @@ -71,11 +75,12 @@ static GdmProtocolData gdm_protocol_data NULL, GDM_LOGOUT_ACTION_NONE, GDM_LOGOUT_ACTION_NONE, - 0 + 0, + FALSE }; static char * -gdm_send_protocol_msg (GdmProtocolData *data, +dm_send_protocol_msg (GdmProtocolData *data, const char *msg) { GString *retval; @@ -87,7 +92,7 @@ gdm_send_protocol_msg (GdmProtocolData * if (write (data->fd, p, strlen (p)) < 0) { g_free (p); - g_warning ("Failed to send message to GDM: %s", + g_warning ("Failed to send message to display manager: %s", g_strerror (errno)); return NULL; } @@ -153,7 +158,7 @@ gdm_authenticate_connection (GdmProtocol msg = g_strdup_printf (GDM_PROTOCOL_MSG_AUTHENTICATE " %s", data->auth_cookie); - response = gdm_send_protocol_msg (data, msg); + response = dm_send_protocol_msg (data, msg); g_free (msg); if (response && !strcmp (response, "OK")) { @@ -195,7 +200,7 @@ gdm_authenticate_connection (GdmProtocol XauDisposeAuth (xau); msg = g_strdup_printf (GDM_PROTOCOL_MSG_AUTHENTICATE " %s", buffer); - response = gdm_send_protocol_msg (data, msg); + response = dm_send_protocol_msg (data, msg); g_free (msg); if (response && !strcmp (response, "OK")) { @@ -218,7 +223,7 @@ gdm_authenticate_connection (GdmProtocol } static void -gdm_shutdown_protocol_connection (GdmProtocolData *data) +dm_shutdown_protocol_connection (GdmProtocolData *data) { if (data->fd) close (data->fd); @@ -226,7 +231,7 @@ gdm_shutdown_protocol_connection (GdmPro } static gboolean -gdm_init_protocol_connection (GdmProtocolData *data) +dm_init_protocol_connection (GdmProtocolData *data) { struct sockaddr_un addr; char *response; @@ -237,7 +242,7 @@ gdm_init_protocol_connection (GdmProtoco if (data->fd < 0) { g_warning ("Failed to create GDM socket: %s", g_strerror (errno)); - gdm_shutdown_protocol_connection (data); + dm_shutdown_protocol_connection (data); return FALSE; } @@ -251,16 +256,16 @@ gdm_init_protocol_connection (GdmProtoco if (connect (data->fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) { g_warning ("Failed to establish a connection with GDM: %s", g_strerror (errno)); - gdm_shutdown_protocol_connection (data); + dm_shutdown_protocol_connection (data); return FALSE; } - response = gdm_send_protocol_msg (data, GDM_PROTOCOL_MSG_VERSION); + response = dm_send_protocol_msg (data, GDM_PROTOCOL_MSG_VERSION); if (!response || strncmp (response, "GDM ", strlen ("GDM ") != 0)) { g_free (response); g_warning ("Failed to get protocol version from GDM"); - gdm_shutdown_protocol_connection (data); + dm_shutdown_protocol_connection (data); return FALSE; } @@ -268,7 +273,7 @@ gdm_init_protocol_connection (GdmProtoco if (!gdm_authenticate_connection (data)) { g_warning ("Failed to authenticate with GDM"); - gdm_shutdown_protocol_connection (data); + dm_shutdown_protocol_connection (data); return FALSE; } @@ -322,7 +327,21 @@ gdm_parse_query_response (GdmProtocolDat } static void -gdm_update_logout_actions (GdmProtocolData *data) +kdm_parse_query_response (GdmProtocolData *data, + const char *response) +{ + data->available_actions = GDM_LOGOUT_ACTION_NONE; + data->current_actions = GDM_LOGOUT_ACTION_NONE; + + if (!response) + return; + + if (strstr (response, "\tshutdown")) + data->available_actions |= GDM_LOGOUT_ACTION_SHUTDOWN | GDM_LOGOUT_ACTION_REBOOT; +} + +static void +dm_update_logout_actions (GdmProtocolData *data) { time_t current_time; char *response; @@ -333,21 +352,30 @@ gdm_update_logout_actions (GdmProtocolDa data->last_update = current_time; - if (!gdm_init_protocol_connection (data)) + if (!dm_init_protocol_connection (data)) return; - - if ((response = gdm_send_protocol_msg (data, GDM_PROTOCOL_MSG_QUERY_ACTION))) { - gdm_parse_query_response (data, response); - g_free (response); - } - gdm_shutdown_protocol_connection (data); + if (data->is_kdm) { + /* KDM */ + if ((response = dm_send_protocol_msg (data, KDM_PROTOCOL_MSG_QUERY_ACTION))) { + kdm_parse_query_response (data, response); + g_free (response); + } + } else { + /* GDM */ + if ((response = dm_send_protocol_msg (data, GDM_PROTOCOL_MSG_QUERY_ACTION))) { + gdm_parse_query_response (data, response); + g_free (response); + } + } + + dm_shutdown_protocol_connection (data); } gboolean gdm_supports_logout_action (GdmLogoutAction action) { - gdm_update_logout_actions (&gdm_protocol_data); + dm_update_logout_actions (&gdm_protocol_data); return (gdm_protocol_data.available_actions & action) != 0; } @@ -355,20 +383,15 @@ gdm_supports_logout_action (GdmLogoutAct GdmLogoutAction gdm_get_logout_action (void) { - gdm_update_logout_actions (&gdm_protocol_data); + dm_update_logout_actions (&gdm_protocol_data); return gdm_protocol_data.current_actions; } -void -gdm_set_logout_action (GdmLogoutAction action) +static char * +gdm_logout_action_msg (GdmLogoutAction action) { char *action_str = NULL; - char *msg; - char *response; - - if (!gdm_init_protocol_connection (&gdm_protocol_data)) - return; switch (action) { case GDM_LOGOUT_ACTION_NONE: @@ -385,14 +408,48 @@ gdm_set_logout_action (GdmLogoutAction a break; } - msg = g_strdup_printf (GDM_PROTOCOL_MSG_SET_ACTION " %s", action_str); + return g_strdup_printf (GDM_PROTOCOL_MSG_SET_ACTION " %s", action_str); +} + +static char * +kdm_logout_action_msg (GdmLogoutAction action) +{ + char *msg = NULL; + + if (action == GDM_LOGOUT_ACTION_SHUTDOWN) + msg = g_strdup ("shutdown\thalt\task"); + else if (action == GDM_LOGOUT_ACTION_REBOOT) + msg = g_strdup ("shutdown\treboot\task"); + + return msg; +} + +void +gdm_set_logout_action (GdmLogoutAction action) +{ + char *action_str = NULL; + char *msg; + char *response; + + if (!dm_init_protocol_connection (&gdm_protocol_data)) + return; + + if (gdm_protocol_data.is_kdm) + msg = kdm_logout_action_msg (action); + else + msg = gdm_logout_action_msg (action); + + if (!msg) { + dm_shutdown_protocol_connection (&gdm_protocol_data); + return; + } - response = gdm_send_protocol_msg (&gdm_protocol_data, msg); + response = dm_send_protocol_msg (&gdm_protocol_data, msg); g_free (msg); g_free (response); gdm_protocol_data.last_update = 0; - gdm_shutdown_protocol_connection (&gdm_protocol_data); + dm_shutdown_protocol_connection (&gdm_protocol_data); }