Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 246170
Collapse All | Expand All

(-)b/gnome-panel/panel-gdm.c (+417 lines)
Line 0 Link Here
1
/*
2
 * gdm-protocol.c: GDM logout action protocol implementation
3
 *
4
 * Copyright (C) 2005 Raffaele Sandrini
5
 * Copyright (C) 2005 Red Hat, Inc.
6
 * Copyright (C) 2002, 2003 George Lebl
7
 * Copyright (C) 2001 Queen of England,
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License as
11
 * published by the Free Software Foundation; either version 2 of the
12
 * License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful, but
15
 * WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22
 * 02111-1307, USA.
23
 *
24
 * Authors:
25
 *      Raffaele Sandrini <rasa@gmx.ch>
26
 *      George Lebl <jirka@5z.com>
27
 *      Mark McLoughlin <mark@skynet.ie>
28
 */
29
30
#include <config.h>
31
32
#include "panel-gdm.h"
33
34
#include <string.h>
35
#include <errno.h>
36
#include <unistd.h>
37
#include <time.h>
38
#include <sys/socket.h>
39
#include <sys/un.h>
40
41
#include <X11/Xauth.h>
42
#include <gdk/gdk.h>
43
44
#define GDM_PROTOCOL_UPDATE_INTERVAL 1 /* seconds */
45
46
#define GDM_PROTOCOL_SOCKET_PATH "/var/run/gdm_socket"
47
48
#define GDM_PROTOCOL_MSG_CLOSE         "CLOSE"
49
#define GDM_PROTOCOL_MSG_VERSION       "VERSION"
50
#define GDM_PROTOCOL_MSG_AUTHENTICATE  "AUTH_LOCAL"
51
#define GDM_PROTOCOL_MSG_QUERY_ACTION  "QUERY_LOGOUT_ACTION"
52
#define GDM_PROTOCOL_MSG_SET_ACTION    "SET_SAFE_LOGOUT_ACTION"
53
#define GDM_PROTOCOL_MSG_FLEXI_XSERVER "FLEXI_XSERVER"
54
55
#define GDM_ACTION_STR_NONE     "NONE"
56
#define GDM_ACTION_STR_SHUTDOWN "HALT"
57
#define GDM_ACTION_STR_REBOOT   "REBOOT"
58
#define GDM_ACTION_STR_SUSPEND  "SUSPEND"
59
60
typedef struct {
61
        int fd;
62
	char *auth_cookie;
63
64
        GdmLogoutAction available_actions;
65
        GdmLogoutAction current_actions;
66
67
        time_t last_update;
68
} GdmProtocolData;
69
70
static GdmProtocolData gdm_protocol_data = {
71
        0,
72
        NULL,
73
        GDM_LOGOUT_ACTION_NONE,
74
        GDM_LOGOUT_ACTION_NONE,
75
        0
76
};
77
78
static char *
79
gdm_send_protocol_msg (GdmProtocolData *data,
80
                       const char      *msg)
81
{
82
        GString *retval;
83
        char     buf[256];
84
        char    *p;
85
        int      len;
86
87
        p = g_strconcat (msg, "\n", NULL);
88
        if (write (data->fd, p, strlen (p)) < 0) {
89
                g_free (p);
90
91
                g_warning ("Failed to send message to GDM: %s",
92
                           g_strerror (errno));
93
                return NULL;
94
        }
95
        g_free (p);
96
97
        p = NULL;
98
        retval = NULL;
99
        while ((len = read (data->fd, buf, sizeof (buf) - 1)) > 0) {
100
                buf[len] = '\0';
101
102
                if (!retval)
103
                        retval = g_string_new (buf);
104
                else
105
                        retval = g_string_append (retval, buf);
106
107
                if ((p = strchr (retval->str, '\n')))
108
                        break;
109
        }
110
111
        if (p) *p = '\0';
112
113
        return retval ? g_string_free (retval, FALSE) : NULL;
114
}
115
116
static char *
117
get_display_number (void)
118
{
119
        const char *display_name;
120
        char       *retval;
121
        char       *p;
122
123
        display_name = gdk_display_get_name (gdk_display_get_default ());
124
125
        p = strchr (display_name, ':');
126
        if (!p)
127
                return g_strdup ("0");
128
129
        while (*p == ':') p++;
130
131
        retval = g_strdup (p);
132
133
        p = strchr (retval, '.');
134
        if (p != NULL)
135
                *p = '\0';
136
137
        return retval;
138
}
139
140
static gboolean
141
gdm_authenticate_connection (GdmProtocolData *data)
142
{
143
#define GDM_MIT_MAGIC_COOKIE_LEN 16
144
145
        const char *xau_path;
146
        FILE       *f;
147
        Xauth      *xau;
148
        char       *display_number;
149
        gboolean    retval;
150
151
        if (data->auth_cookie) {
152
                char *msg;
153
                char *response;
154
155
                msg = g_strdup_printf (GDM_PROTOCOL_MSG_AUTHENTICATE " %s",
156
                                       data->auth_cookie);
157
                response = gdm_send_protocol_msg (data, msg);
158
                g_free (msg);
159
160
                if (response && !strcmp (response, "OK")) {
161
                        g_free (response);
162
                        return TRUE;
163
                } else {
164
                        g_free (response);
165
                        g_free (data->auth_cookie);
166
                        data->auth_cookie = NULL;
167
                }
168
        }
169
170
        if (!(xau_path = XauFileName ()))
171
                return FALSE;
172
173
        if (!(f = fopen (xau_path, "r")))
174
                return FALSE;
175
176
        retval = FALSE;
177
        display_number = get_display_number ();
178
179
        while ((xau = XauReadAuth (f))) {
180
                char  buffer[40]; /* 2*16 == 32, so 40 is enough */
181
                char *msg;
182
                char *response;
183
                int   i;
184
185
                if (xau->family != FamilyLocal ||
186
                    strncmp (xau->number, display_number, xau->number_length) ||
187
                    strncmp (xau->name, "MIT-MAGIC-COOKIE-1", xau->name_length) ||
188
                    xau->data_length != GDM_MIT_MAGIC_COOKIE_LEN) {
189
                        XauDisposeAuth (xau);
190
                        continue;
191
                }
192
193
                for (i = 0; i < GDM_MIT_MAGIC_COOKIE_LEN; i++)
194
                        g_snprintf (buffer + 2*i, 3, "%02x", (guint)(guchar)xau->data[i]);
195
196
                XauDisposeAuth (xau);
197
198
                msg = g_strdup_printf (GDM_PROTOCOL_MSG_AUTHENTICATE " %s", buffer);
199
                response = gdm_send_protocol_msg (data, msg);
200
                g_free (msg);
201
202
                if (response && !strcmp (response, "OK")) {
203
			data->auth_cookie = g_strdup (buffer);
204
                        g_free (response);
205
                        retval = TRUE;
206
                        break;
207
                }
208
209
                g_free (response);
210
        }
211
212
        g_free (display_number);
213
214
        fclose (f);
215
216
        return retval;
217
218
#undef GDM_MIT_MAGIC_COOKIE_LEN
219
}
220
221
static void
222
gdm_shutdown_protocol_connection (GdmProtocolData *data)
223
{
224
        if (data->fd)
225
                close (data->fd);
226
        data->fd = 0;
227
}
228
229
static gboolean
230
gdm_init_protocol_connection (GdmProtocolData *data)
231
{
232
        struct sockaddr_un  addr;
233
        char               *response;
234
235
        g_assert (data->fd <= 0);
236
237
        data->fd = socket (AF_UNIX, SOCK_STREAM, 0);
238
        if (data->fd < 0) {
239
                g_warning ("Failed to create GDM socket: %s",
240
                           g_strerror (errno));
241
		gdm_shutdown_protocol_connection (data);
242
                return FALSE;
243
        }
244
245
	if (g_file_test (GDM_PROTOCOL_SOCKET_PATH, G_FILE_TEST_EXISTS))
246
	  strcpy (addr.sun_path, GDM_PROTOCOL_SOCKET_PATH);
247
	else
248
	  strcpy (addr.sun_path, "/tmp/.gdm_socket");
249
250
	addr.sun_family = AF_UNIX;
251
252
        if (connect (data->fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) {
253
                g_warning ("Failed to establish a connection with GDM: %s",
254
                           g_strerror (errno));
255
		gdm_shutdown_protocol_connection (data);
256
                return FALSE;
257
        }
258
259
        response = gdm_send_protocol_msg (data, GDM_PROTOCOL_MSG_VERSION);
260
        if (!response || strncmp (response, "GDM ", strlen ("GDM ") != 0)) {
261
                g_free (response);
262
263
                g_warning ("Failed to get protocol version from GDM");
264
		gdm_shutdown_protocol_connection (data);
265
266
                return FALSE;
267
        }
268
	g_free (response);
269
270
        if (!gdm_authenticate_connection (data)) {
271
                g_warning ("Failed to authenticate with GDM");
272
		gdm_shutdown_protocol_connection (data);
273
                return FALSE;
274
        }
275
276
        return TRUE;
277
}
278
279
static void
280
gdm_parse_query_response (GdmProtocolData *data,
281
                          const char      *response)
282
{
283
        char **actions;
284
        int    i;
285
286
        data->available_actions = GDM_LOGOUT_ACTION_NONE;
287
        data->current_actions   = GDM_LOGOUT_ACTION_NONE;
288
289
        if (strncmp (response, "OK ", 3) != 0)
290
                return;
291
292
        response += 3;
293
294
        actions = g_strsplit (response, ";", -1);
295
        for (i = 0; actions[i]; i++) {
296
                GdmLogoutAction  action = GDM_LOGOUT_ACTION_NONE;
297
                gboolean         selected = FALSE;
298
                char            *str = actions [i];
299
                int              len;
300
301
                len = strlen (str);
302
                if (!len)
303
                        continue;
304
305
                if (str[len - 1] == '!') {
306
                        selected = TRUE;
307
                        str[len - 1] = '\0';
308
                }
309
310
                if (!strcmp (str, GDM_ACTION_STR_SHUTDOWN))
311
                        action = GDM_LOGOUT_ACTION_SHUTDOWN;
312
                else if (!strcmp (str, GDM_ACTION_STR_REBOOT))
313
                        action = GDM_LOGOUT_ACTION_REBOOT;
314
                else if (!strcmp (str, GDM_ACTION_STR_SUSPEND))
315
                        action = GDM_LOGOUT_ACTION_SUSPEND;
316
317
                data->available_actions |= action;
318
                if (selected)
319
                        data->current_actions |= action;
320
        }
321
322
        g_strfreev (actions);
323
}
324
325
static void
326
gdm_update_logout_actions (GdmProtocolData *data)
327
{
328
        time_t  current_time;
329
        char   *response;
330
331
        current_time = time (NULL);
332
        if (current_time <= (data->last_update + GDM_PROTOCOL_UPDATE_INTERVAL))
333
                return;
334
335
        data->last_update = current_time;
336
337
        if (!gdm_init_protocol_connection (data))
338
                return;
339
340
        if ((response = gdm_send_protocol_msg (data, GDM_PROTOCOL_MSG_QUERY_ACTION))) {
341
                gdm_parse_query_response (data, response);
342
                g_free (response);
343
        }
344
345
        gdm_shutdown_protocol_connection (data);
346
}
347
348
gboolean
349
gdm_supports_logout_action (GdmLogoutAction action)
350
{
351
        gdm_update_logout_actions (&gdm_protocol_data);
352
353
        return (gdm_protocol_data.available_actions & action) != 0;
354
}
355
356
GdmLogoutAction
357
gdm_get_logout_action (void)
358
{
359
        gdm_update_logout_actions (&gdm_protocol_data);
360
361
        return gdm_protocol_data.current_actions;
362
}
363
364
void
365
gdm_set_logout_action (GdmLogoutAction action)
366
{
367
	char *action_str = NULL;
368
        char *msg;
369
        char *response;
370
371
        if (!gdm_init_protocol_connection (&gdm_protocol_data))
372
                return;
373
374
        switch (action) {
375
        case GDM_LOGOUT_ACTION_NONE:
376
                action_str = GDM_ACTION_STR_NONE;
377
                break;
378
        case GDM_LOGOUT_ACTION_SHUTDOWN:
379
                action_str = GDM_ACTION_STR_SHUTDOWN;
380
                break;
381
        case GDM_LOGOUT_ACTION_REBOOT:
382
                action_str = GDM_ACTION_STR_REBOOT;
383
                break;
384
        case GDM_LOGOUT_ACTION_SUSPEND:
385
                action_str = GDM_ACTION_STR_SUSPEND;
386
                break;
387
        }
388
389
        msg = g_strdup_printf (GDM_PROTOCOL_MSG_SET_ACTION " %s", action_str);
390
391
        response = gdm_send_protocol_msg (&gdm_protocol_data, msg);
392
393
        g_free (msg);
394
        g_free (response);
395
396
	gdm_protocol_data.last_update = 0;
397
398
        gdm_shutdown_protocol_connection (&gdm_protocol_data);
399
}
400
401
void
402
gdm_new_login (void)
403
{
404
        char *response;
405
406
        if (!gdm_init_protocol_connection (&gdm_protocol_data))
407
                return;
408
409
        response = gdm_send_protocol_msg (&gdm_protocol_data,
410
					  GDM_PROTOCOL_MSG_FLEXI_XSERVER);
411
412
        g_free (response);
413
414
	gdm_protocol_data.last_update = 0;
415
416
        gdm_shutdown_protocol_connection (&gdm_protocol_data);
417
}
(-)b/gnome-panel/panel-logout.c (+402 lines)
Line 0 Link Here
1
/*
2
 * panel-logout.c:
3
 *
4
 * Copyright (C) 2006 Vincent Untz
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License as
8
 * published by the Free Software Foundation; either version 2 of the
9
 * License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19
 * 02111-1307, USA.
20
 *
21
 * Authors:
22
 *	Vincent Untz <vuntz@gnome.org>
23
 */
24
25
26
#include <config.h>
27
28
#include <string.h>
29
30
#include <glib/gi18n.h>
31
#include <gtk/gtkimage.h>
32
#include <gtk/gtklabel.h>
33
#include <gtk/gtkstock.h>
34
35
#include <libpanel-util/panel-power-manager.h>
36
37
#include "panel-logout.h"
38
#include "panel-gdm.h"
39
#include "panel-session.h"
40
#include "panel-icon-names.h"
41
42
#define PANEL_LOGOUT_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_LOGOUT_DIALOG, PanelLogoutDialogPrivate))
43
44
#define AUTOMATIC_ACTION_TIMEOUT 60
45
46
enum {
47
	PANEL_LOGOUT_RESPONSE_LOGOUT,
48
	PANEL_LOGOUT_RESPONSE_SWITCH_USER,
49
	PANEL_LOGOUT_RESPONSE_SHUTDOWN,
50
	PANEL_LOGOUT_RESPONSE_REBOOT,
51
	PANEL_LOGOUT_RESPONSE_STD,
52
	PANEL_LOGOUT_RESPONSE_STR
53
};
54
55
struct _PanelLogoutDialogPrivate {
56
	PanelLogoutDialogType type;
57
58
	PanelPowerManager    *power_manager;
59
60
	int                   timeout;
61
	unsigned int          timeout_id;
62
63
	unsigned int          default_response;
64
};
65
66
static PanelLogoutDialog *current_dialog = NULL;
67
68
static void panel_logout_destroy (PanelLogoutDialog *logout_dialog,
69
				  gpointer           data);
70
static void panel_logout_response (PanelLogoutDialog *logout_dialog,
71
				   guint              response_id,
72
				   gpointer           data);
73
74
enum {
75
  PROP_0,
76
  PROP_MESSAGE_TYPE
77
};
78
G_DEFINE_TYPE (PanelLogoutDialog, panel_logout, GTK_TYPE_MESSAGE_DIALOG);
79
80
static void
81
panel_logout_set_property (GObject      *object,
82
			   guint         prop_id,
83
			   const GValue *value,
84
			   GParamSpec   *pspec)
85
{
86
	switch (prop_id) {
87
	case PROP_MESSAGE_TYPE:
88
		break;
89
	default:
90
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
91
		break;
92
	}
93
}
94
95
static void
96
panel_logout_get_property (GObject     *object,
97
			   guint        prop_id,
98
			   GValue      *value,
99
			   GParamSpec  *pspec)
100
{
101
	switch (prop_id) {
102
	case PROP_MESSAGE_TYPE:
103
		g_value_set_enum (value, GTK_MESSAGE_WARNING);
104
		break;
105
	default:
106
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
107
		break;
108
	}
109
}
110
111
static void
112
panel_logout_class_init (PanelLogoutDialogClass *klass)
113
{
114
	GObjectClass *gobject_class;
115
116
	gobject_class = G_OBJECT_CLASS (klass);
117
118
	/* This is a workaround to avoid a stupid crash: libgnomeui
119
	 * listens for the "show" signal on all GtkMessageDialog and
120
	 * gets the "message-type" of the dialogs. We will crash when
121
	 * it accesses this property if we don't override it since we
122
	 * didn't define it. */
123
	gobject_class->set_property = panel_logout_set_property;
124
	gobject_class->get_property = panel_logout_get_property;
125
126
	g_object_class_override_property (gobject_class,
127
					  PROP_MESSAGE_TYPE,
128
					  "message-type");
129
130
	g_type_class_add_private (klass, sizeof (PanelLogoutDialogPrivate));
131
}
132
133
static void
134
panel_logout_init (PanelLogoutDialog *logout_dialog)
135
{
136
	logout_dialog->priv = PANEL_LOGOUT_DIALOG_GET_PRIVATE (logout_dialog);
137
138
	logout_dialog->priv->timeout_id = 0;
139
	logout_dialog->priv->timeout    = 0;
140
	logout_dialog->priv->default_response = GTK_RESPONSE_CANCEL;
141
142
	/* FIXME: we should most probably use gtk_window_set_transient_for(PANEL) */
143
	gtk_window_set_skip_taskbar_hint (GTK_WINDOW (logout_dialog), TRUE);
144
	gtk_window_set_keep_above (GTK_WINDOW (logout_dialog), TRUE);
145
	gtk_window_stick (GTK_WINDOW (logout_dialog));
146
	gtk_window_set_position (GTK_WINDOW (logout_dialog),
147
				 GTK_WIN_POS_CENTER_ALWAYS);
148
149
	logout_dialog->priv->power_manager = panel_power_manager_get ();
150
151
	g_signal_connect (logout_dialog, "destroy",
152
			  G_CALLBACK (panel_logout_destroy), NULL);
153
	g_signal_connect (logout_dialog, "response",
154
			  G_CALLBACK (panel_logout_response), NULL);
155
}
156
157
static void
158
panel_logout_destroy (PanelLogoutDialog *logout_dialog,
159
		      gpointer           data)
160
{
161
	if (logout_dialog->priv->timeout_id != 0)
162
		g_source_remove (logout_dialog->priv->timeout_id);
163
	logout_dialog->priv->timeout_id = 0;
164
165
	g_object_unref (logout_dialog->priv->power_manager);
166
	logout_dialog->priv->power_manager = NULL;
167
168
	current_dialog = NULL;
169
}
170
171
static void
172
panel_logout_response (PanelLogoutDialog *logout_dialog,
173
		       guint      response_id,
174
		       gpointer   data)
175
{
176
	PanelPowerManager *power_manager;
177
178
	power_manager = g_object_ref (logout_dialog->priv->power_manager);
179
	gtk_widget_destroy (GTK_WIDGET (logout_dialog));
180
181
	switch (response_id) {
182
	case GTK_RESPONSE_CANCEL:
183
		break;
184
	case PANEL_LOGOUT_RESPONSE_LOGOUT:
185
		gdm_set_logout_action (GDM_LOGOUT_ACTION_NONE);
186
		panel_session_request_logout ();
187
		break;
188
	case PANEL_LOGOUT_RESPONSE_SWITCH_USER:
189
		gdm_new_login ();
190
		break;
191
	case PANEL_LOGOUT_RESPONSE_SHUTDOWN:
192
		gdm_set_logout_action (GDM_LOGOUT_ACTION_SHUTDOWN);
193
		panel_session_request_logout ();
194
		break;
195
	case PANEL_LOGOUT_RESPONSE_REBOOT:
196
		gdm_set_logout_action (GDM_LOGOUT_ACTION_REBOOT);
197
		panel_session_request_logout ();
198
		break;
199
	case PANEL_LOGOUT_RESPONSE_STD:
200
		if (panel_power_manager_can_hibernate (power_manager))
201
			panel_power_manager_attempt_hibernate (power_manager);
202
		break;
203
	case PANEL_LOGOUT_RESPONSE_STR:
204
		if (panel_power_manager_can_suspend (power_manager))
205
			panel_power_manager_attempt_suspend (power_manager);
206
		break;
207
	case GTK_RESPONSE_NONE:
208
	case GTK_RESPONSE_DELETE_EVENT:
209
		break;
210
	default:
211
		g_assert_not_reached ();
212
	}
213
	g_object_unref (power_manager);
214
}
215
216
static gboolean
217
panel_logout_timeout (gpointer data)
218
{
219
	PanelLogoutDialog *logout_dialog;
220
	char              *secondary_text;
221
	char              *name;
222
	int                seconds_to_show;
223
224
	logout_dialog = (PanelLogoutDialog *) data;
225
226
	if (!logout_dialog->priv->timeout) {
227
		gtk_dialog_response (GTK_DIALOG (logout_dialog),
228
				     logout_dialog->priv->default_response);
229
230
		return FALSE;
231
	}
232
233
	if (logout_dialog->priv->timeout <= 30)
234
		seconds_to_show = logout_dialog->priv->timeout;
235
	else {
236
		seconds_to_show = (logout_dialog->priv->timeout/10) * 10;
237
		if (logout_dialog->priv->timeout % 10)
238
			seconds_to_show += 10;
239
	}
240
241
	switch (logout_dialog->priv->type) {
242
	case PANEL_LOGOUT_DIALOG_LOGOUT:
243
		secondary_text = ngettext ("You are currently logged in as "
244
					   "\"%s\".\n"
245
					   "You will be automatically logged "
246
					   "out in %d second.",
247
					   "You are currently logged in as "
248
					   "\"%s\".\n"
249
					   "You will be automatically logged "
250
					   "out in %d seconds.",
251
					   seconds_to_show);
252
		break;
253
	case PANEL_LOGOUT_DIALOG_SHUTDOWN:
254
		secondary_text = ngettext ("You are currently logged in as "
255
					   "\"%s\".\n"
256
					   "This system will be automatically "
257
					   "shut down in %d second.",
258
					   "You are currently logged in as "
259
					   "\"%s\".\n"
260
					   "This system will be automatically "
261
					   "shut down in %d seconds.",
262
					   seconds_to_show);
263
		break;
264
	default:
265
		g_assert_not_reached ();
266
	}
267
268
	name = g_locale_to_utf8 (g_get_real_name (), -1, NULL, NULL, NULL);
269
	if (!name || name[0] == '\0' || strcmp (name, "Unknown") == 0)
270
		name = g_locale_to_utf8 (g_get_user_name (), -1 , NULL, NULL, NULL);
271
272
	if (!name)
273
		name = g_strdup (g_get_user_name ());
274
275
	gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (logout_dialog),
276
						  secondary_text,
277
						  name,
278
						  seconds_to_show,
279
						  NULL);
280
281
	logout_dialog->priv->timeout--;
282
283
	g_free (name);
284
285
	return TRUE;
286
}
287
288
static void
289
panel_logout_set_timeout (PanelLogoutDialog *logout_dialog)
290
{
291
	logout_dialog->priv->timeout = AUTOMATIC_ACTION_TIMEOUT;
292
293
	/* Sets the secondary text */
294
	panel_logout_timeout (logout_dialog);
295
296
	if (logout_dialog->priv->timeout_id != 0)
297
		g_source_remove (logout_dialog->priv->timeout_id);
298
299
	logout_dialog->priv->timeout_id = g_timeout_add (1000,
300
							 panel_logout_timeout,
301
							 logout_dialog);
302
}
303
304
void
305
panel_logout_new (PanelLogoutDialogType  type,
306
		  GdkScreen             *screen,
307
		  guint32                activate_time)
308
{
309
	PanelLogoutDialog *logout_dialog;
310
	char              *icon_name;
311
	char              *primary_text;
312
313
	if (current_dialog != NULL) {
314
		if (current_dialog->priv->type == type) {
315
			gtk_window_set_screen (GTK_WINDOW (current_dialog),
316
					       screen);
317
			gtk_window_present_with_time (GTK_WINDOW (current_dialog),
318
						      activate_time);
319
			panel_logout_set_timeout (current_dialog);
320
			//FIXME center the dialog on screen, and reset sticky and above_all?
321
			return;
322
		} else {
323
			gtk_widget_destroy (GTK_WIDGET (current_dialog));
324
		}
325
	}
326
327
	logout_dialog = g_object_new (PANEL_TYPE_LOGOUT_DIALOG, NULL);
328
	current_dialog = logout_dialog;
329
330
	gtk_window_set_title (GTK_WINDOW (logout_dialog), "");
331
332
	logout_dialog->priv->type = type;
333
334
	icon_name    = NULL;
335
	primary_text = NULL;
336
337
	switch (type) {
338
	case PANEL_LOGOUT_DIALOG_LOGOUT:
339
		icon_name      = PANEL_ICON_LOGOUT;
340
		primary_text   = _("Log out of this system now?");
341
		// FIXME need to verify that this response can be used
342
		logout_dialog->priv->default_response = PANEL_LOGOUT_DIALOG_LOGOUT;
343
344
		//FIXME is gdm running?
345
		gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
346
				       _("_Switch User"),
347
				       PANEL_LOGOUT_RESPONSE_SWITCH_USER);
348
		gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
349
				       GTK_STOCK_CANCEL,
350
				       GTK_RESPONSE_CANCEL);
351
		gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
352
				       _("_Log Out"),
353
				       PANEL_LOGOUT_RESPONSE_LOGOUT);
354
		break;
355
	case PANEL_LOGOUT_DIALOG_SHUTDOWN:
356
		icon_name      = PANEL_ICON_SHUTDOWN;
357
		primary_text   = _("Shut down this system now?");
358
359
		logout_dialog->priv->default_response = PANEL_LOGOUT_RESPONSE_SHUTDOWN;
360
		if (panel_power_manager_can_suspend (logout_dialog->priv->power_manager))
361
			gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
362
					       _("S_uspend"),
363
					       PANEL_LOGOUT_RESPONSE_STR);
364
365
		if (panel_power_manager_can_hibernate (logout_dialog->priv->power_manager))
366
			gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
367
					       _("_Hibernate"),
368
					       PANEL_LOGOUT_RESPONSE_STD);
369
370
		if (gdm_supports_logout_action (GDM_LOGOUT_ACTION_REBOOT))
371
			gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
372
					       _("_Restart"),
373
					       PANEL_LOGOUT_RESPONSE_REBOOT);
374
375
		gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
376
				       GTK_STOCK_CANCEL,
377
				       GTK_RESPONSE_CANCEL);
378
379
		if (gdm_supports_logout_action (GDM_LOGOUT_ACTION_SHUTDOWN))
380
			gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
381
					       _("_Shut Down"),
382
					       PANEL_LOGOUT_RESPONSE_SHUTDOWN);
383
		break;
384
	default:
385
		g_assert_not_reached ();
386
	}
387
388
	gtk_image_set_from_icon_name (GTK_IMAGE (GTK_MESSAGE_DIALOG (logout_dialog)->image),
389
				      icon_name, GTK_ICON_SIZE_DIALOG);
390
391
	gtk_label_set_text (GTK_LABEL (GTK_MESSAGE_DIALOG (logout_dialog)->label),
392
			    primary_text);
393
394
	gtk_dialog_set_default_response (GTK_DIALOG (logout_dialog),
395
					 logout_dialog->priv->default_response);
396
397
	panel_logout_set_timeout (logout_dialog);
398
399
	gtk_window_set_screen (GTK_WINDOW (logout_dialog), screen);
400
	gtk_widget_show (GTK_WIDGET (logout_dialog));
401
	gdk_window_focus (GTK_WIDGET (current_dialog)->window, activate_time);
402
}
(-)b/gnome-panel/panel-gdm.h (+52 lines)
Line 0 Link Here
1
/*
2
 * gdm-logout-action.h: GDM logout action protocol implementation
3
 *
4
 * Copyright (C) 2005 Raffaele Sandrini
5
 * Copyright (C) 2005 Red Hat, Inc.
6
 * Copyright (C) 2002, 2003 George Lebl
7
 * Copyright (C) 2001 Queen of England,
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License as
11
 * published by the Free Software Foundation; either version 2 of the
12
 * License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful, but
15
 * WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22
 * 02111-1307, USA.
23
 *
24
 * Authors:
25
 *      Raffaele Sandrini <rasa@gmx.ch>
26
 *      George Lebl <jirka@5z.com>
27
 *      Mark McLoughlin <mark@skynet.ie>
28
 */
29
30
#ifndef __GDM_LOGOUT_ACTION_H__
31
#define __GDM_LOGOUT_ACTION_H__
32
33
#include <glib.h>
34
35
G_BEGIN_DECLS
36
37
typedef enum {
38
        GDM_LOGOUT_ACTION_NONE     = 0,
39
        GDM_LOGOUT_ACTION_SHUTDOWN = 1 << 0,
40
        GDM_LOGOUT_ACTION_REBOOT   = 1 << 1,
41
        GDM_LOGOUT_ACTION_SUSPEND  = 1 << 2
42
} GdmLogoutAction;
43
44
gboolean gdm_supports_logout_action (GdmLogoutAction action);
45
46
void            gdm_set_logout_action (GdmLogoutAction action);
47
GdmLogoutAction gdm_get_logout_action (void);
48
void            gdm_new_login         (void);
49
50
G_END_DECLS
51
52
#endif /* __GDM_LOGOUT_ACTION_H__ */
(-)b/gnome-panel/panel-logout.h (+66 lines)
Line 0 Link Here
1
/*
2
 * panel-logout.h:
3
 *
4
 * Copyright (C) 2006 Vincent Untz
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License as
8
 * published by the Free Software Foundation; either version 2 of the
9
 * License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19
 * 02111-1307, USA.
20
 *
21
 * Authors:
22
 *	Vincent Untz <vuntz@gnome.org>
23
 */
24
25
#ifndef PANEL_LOGOUT_H
26
#define PANEL_LOGOUT_H
27
28
#include "gtk/gtkmessagedialog.h"
29
30
G_BEGIN_DECLS
31
32
typedef enum {
33
	PANEL_LOGOUT_DIALOG_LOGOUT,
34
	PANEL_LOGOUT_DIALOG_SHUTDOWN
35
} PanelLogoutDialogType;
36
37
#define PANEL_TYPE_LOGOUT_DIALOG         (panel_logout_get_type ())
38
#define PANEL_LOGOUT_DIALOG(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), PANEL_TYPE_LOGOUT_DIALOG, PanelLogoutDialog))
39
#define PANEL_LOGOUT_DIALOG_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), PANEL_TYPE_LOGOUT_DIALOG, PanelLogoutDialogClass))
40
#define PANEL_IS_LOGOUT_DIALOG(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), PANEL_TYPE_LOGOUT_DIALOG))
41
#define PANEL_IS_LOGOUT_DIALOG_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), PANEL_TYPE_LOGOUT_DIALOG))
42
#define PANEL_LOGOUT_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), PANEL_TYPE_LOGOUT_DIALOG, PanelLogoutDialogClass))
43
44
typedef struct _PanelLogoutDialog        PanelLogoutDialog;
45
typedef struct _PanelLogoutDialogClass   PanelLogoutDialogClass;
46
typedef struct _PanelLogoutDialogPrivate PanelLogoutDialogPrivate;
47
48
struct _PanelLogoutDialog {
49
	GtkMessageDialog          parent;
50
51
	PanelLogoutDialogPrivate *priv;
52
};
53
54
struct _PanelLogoutDialogClass {
55
	GtkMessageDialogClass   parent_class;
56
};
57
58
GType  panel_logout_get_type          (void) G_GNUC_CONST;
59
60
void panel_logout_new (PanelLogoutDialogType  type,
61
		       GdkScreen             *screen,
62
		       guint32                activate_time);
63
64
G_END_DECLS
65
66
#endif /* PANEL_LOGOUT_H */
(-)b/gnome-panel/panel-session.c (+28 lines)
Lines 32-37 Link Here
32
#include "panel-profile.h"
32
#include "panel-profile.h"
33
#include "panel-shell.h"
33
#include "panel-shell.h"
34
34
35
void
36
panel_session_request_logout (void)
37
{
38
	GnomeClient *client;
39
	static int   recursion_guard = 0;
40
41
	if (recursion_guard)
42
		return;
43
44
	recursion_guard++;
45
46
	if (!(client = gnome_master_client ()))
47
		return;
48
49
	/* Only request a Global save. We only want a Local
50
	 * save if the user selects 'Save current setup'
51
	 * from the dialog.
52
	 */
53
	gnome_client_request_save (client,
54
				   GNOME_SAVE_GLOBAL,
55
				   TRUE,
56
				   GNOME_INTERACT_ANY,
57
				   TRUE, /* do not use the gnome-session gui */
58
				   TRUE);
59
60
	recursion_guard--;
61
}
62
35
static void
63
static void
36
panel_session_handle_die_request (GnomeClient *client)
64
panel_session_handle_die_request (GnomeClient *client)
37
{
65
{
(-)b/gnome-panel/panel-session.h (+1 lines)
Lines 29-34 G_BEGIN_DECLS Link Here
29
29
30
void panel_session_init           (void);
30
void panel_session_init           (void);
31
void panel_session_do_not_restart (void);
31
void panel_session_do_not_restart (void);
32
void panel_session_request_logout (void);
32
33
33
G_END_DECLS
34
G_END_DECLS
34
35
(-)b/gnome-panel/Makefile.am (+4 lines)
Lines 97-102 panel_sources = \ Link Here
97
	panel-force-quit.c	\
97
	panel-force-quit.c	\
98
	panel-lockdown.c	\
98
	panel-lockdown.c	\
99
	panel-addto.c		\
99
	panel-addto.c		\
100
	panel-logout.c		\
101
	panel-gdm.c		\
100
	panel-ditem-editor.c	\
102
	panel-ditem-editor.c	\
101
	$(NULL)
103
	$(NULL)
102
104
Lines 143-148 panel_headers = \ Link Here
143
	panel-force-quit.h	\
145
	panel-force-quit.h	\
144
	panel-lockdown.h	\
146
	panel-lockdown.h	\
145
	panel-addto.h		\
147
	panel-addto.h		\
148
	panel-logout.h		\
149
	panel-gdm.h		\
146
	panel-ditem-editor.h	\
150
	panel-ditem-editor.h	\
147
	panel-icon-names.h	\
151
	panel-icon-names.h	\
148
	$(NULL)
152
	$(NULL)
(-)b/gnome-panel/libpanel-util/panel-session-manager.c (+23 lines)
Lines 23-32 Link Here
23
 */
23
 */
24
24
25
#include <dbus/dbus-glib.h>
25
#include <dbus/dbus-glib.h>
26
#include <gtk/gtk.h>
26
27
27
#include "panel-cleanup.h"
28
#include "panel-cleanup.h"
28
#include "panel-dbus-service.h"
29
#include "panel-dbus-service.h"
29
30
31
#include "panel-logout.h"
32
#include "panel-session.h"
30
#include "panel-session-manager.h"
33
#include "panel-session-manager.h"
31
34
32
static GObject *panel_session_manager_constructor (GType                  type,
35
static GObject *panel_session_manager_constructor (GType                  type,
Lines 96-101 panel_session_manager_request_logout (Pa Link Here
96
		g_warning ("Could not connect to session manager: %s",
99
		g_warning ("Could not connect to session manager: %s",
97
			   error->message);
100
			   error->message);
98
		g_error_free (error);
101
		g_error_free (error);
102
103
		/* Fall back to the old way */
104
		switch (mode) {
105
		case PANEL_SESSION_MANAGER_LOGOUT_MODE_NORMAL:
106
			panel_logout_new (PANEL_LOGOUT_DIALOG_LOGOUT,
107
					  gdk_screen_get_default (),
108
					  gtk_get_current_event_time ());
109
			break;
110
		case PANEL_SESSION_MANAGER_LOGOUT_MODE_NO_CONFIRMATION:
111
			panel_session_request_logout ();
112
			break;
113
		default:
114
			g_warning ("Invalid mode requested for logout");
115
		}
99
		return;
116
		return;
100
	}
117
	}
101
118
Lines 126-131 panel_session_manager_request_shutdown ( Link Here
126
		g_warning ("Could not connect to session manager: %s",
143
		g_warning ("Could not connect to session manager: %s",
127
			   error->message);
144
			   error->message);
128
		g_error_free (error);
145
		g_error_free (error);
146
147
		/* Fall back to the old way */
148
		panel_logout_new (PANEL_LOGOUT_DIALOG_SHUTDOWN,
149
				  gdk_screen_get_default (),
150
				  gtk_get_current_event_time ());
151
129
		return;
152
		return;
130
	}
153
	}
131
154

Return to bug 246170