]> git.pld-linux.org Git - packages/gnome-panel.git/blob - gnome-panel-logout.patch
- BR: docbook-dtd412-xml, rpm-pythonprov
[packages/gnome-panel.git] / gnome-panel-logout.patch
1 ---
2  Allow gnome-panel to fall back to old style logout if gnome-session 2.24
3  isn't present.
4
5  gnome-panel/Makefile.am                           |    4 
6  gnome-panel/libpanel-util/panel-session-manager.c |   23 +
7  gnome-panel/panel-gdm.c                           |  417 ++++++++++++++++++++++
8  gnome-panel/panel-gdm.h                           |   52 ++
9  gnome-panel/panel-logout.c                        |  402 +++++++++++++++++++++
10  gnome-panel/panel-logout.h                        |   66 +++
11  gnome-panel/panel-session.c                       |   28 +
12  gnome-panel/panel-session.h                       |    1 
13  8 files changed, 993 insertions(+)
14
15 Index: b/gnome-panel/panel-gdm.c
16 ===================================================================
17 --- /dev/null
18 +++ b/gnome-panel/panel-gdm.c
19 @@ -0,0 +1,417 @@
20 +/*
21 + * gdm-protocol.c: GDM logout action protocol implementation
22 + *
23 + * Copyright (C) 2005 Raffaele Sandrini
24 + * Copyright (C) 2005 Red Hat, Inc.
25 + * Copyright (C) 2002, 2003 George Lebl
26 + * Copyright (C) 2001 Queen of England,
27 + *
28 + * This program is free software; you can redistribute it and/or
29 + * modify it under the terms of the GNU General Public License as
30 + * published by the Free Software Foundation; either version 2 of the
31 + * License, or (at your option) any later version.
32 + *
33 + * This program is distributed in the hope that it will be useful, but
34 + * WITHOUT ANY WARRANTY; without even the implied warranty of
35 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
36 + * General Public License for more details.
37 + *
38 + * You should have received a copy of the GNU General Public License
39 + * along with this program; if not, write to the Free Software
40 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
41 + * 02111-1307, USA.
42 + *
43 + * Authors:
44 + *      Raffaele Sandrini <rasa@gmx.ch>
45 + *      George Lebl <jirka@5z.com>
46 + *      Mark McLoughlin <mark@skynet.ie>
47 + */
48 +
49 +#include <config.h>
50 +
51 +#include "panel-gdm.h"
52 +
53 +#include <string.h>
54 +#include <errno.h>
55 +#include <unistd.h>
56 +#include <time.h>
57 +#include <sys/socket.h>
58 +#include <sys/un.h>
59 +
60 +#include <X11/Xauth.h>
61 +#include <gdk/gdk.h>
62 +
63 +#define GDM_PROTOCOL_UPDATE_INTERVAL 1 /* seconds */
64 +
65 +#define GDM_PROTOCOL_SOCKET_PATH "/var/run/gdm_socket"
66 +
67 +#define GDM_PROTOCOL_MSG_CLOSE         "CLOSE"
68 +#define GDM_PROTOCOL_MSG_VERSION       "VERSION"
69 +#define GDM_PROTOCOL_MSG_AUTHENTICATE  "AUTH_LOCAL"
70 +#define GDM_PROTOCOL_MSG_QUERY_ACTION  "QUERY_LOGOUT_ACTION"
71 +#define GDM_PROTOCOL_MSG_SET_ACTION    "SET_SAFE_LOGOUT_ACTION"
72 +#define GDM_PROTOCOL_MSG_FLEXI_XSERVER "FLEXI_XSERVER"
73 +
74 +#define GDM_ACTION_STR_NONE     "NONE"
75 +#define GDM_ACTION_STR_SHUTDOWN "HALT"
76 +#define GDM_ACTION_STR_REBOOT   "REBOOT"
77 +#define GDM_ACTION_STR_SUSPEND  "SUSPEND"
78 +
79 +typedef struct {
80 +        int fd;
81 +       char *auth_cookie;
82 +
83 +        GdmLogoutAction available_actions;
84 +        GdmLogoutAction current_actions;
85 +
86 +        time_t last_update;
87 +} GdmProtocolData;
88 +
89 +static GdmProtocolData gdm_protocol_data = {
90 +        0,
91 +        NULL,
92 +        GDM_LOGOUT_ACTION_NONE,
93 +        GDM_LOGOUT_ACTION_NONE,
94 +        0
95 +};
96 +
97 +static char *
98 +gdm_send_protocol_msg (GdmProtocolData *data,
99 +                       const char      *msg)
100 +{
101 +        GString *retval;
102 +        char     buf[256];
103 +        char    *p;
104 +        int      len;
105 +
106 +        p = g_strconcat (msg, "\n", NULL);
107 +        if (write (data->fd, p, strlen (p)) < 0) {
108 +                g_free (p);
109 +
110 +                g_warning ("Failed to send message to GDM: %s",
111 +                           g_strerror (errno));
112 +                return NULL;
113 +        }
114 +        g_free (p);
115 +
116 +        p = NULL;
117 +        retval = NULL;
118 +        while ((len = read (data->fd, buf, sizeof (buf) - 1)) > 0) {
119 +                buf[len] = '\0';
120 +
121 +                if (!retval)
122 +                        retval = g_string_new (buf);
123 +                else
124 +                        retval = g_string_append (retval, buf);
125 +
126 +                if ((p = strchr (retval->str, '\n')))
127 +                        break;
128 +        }
129 +
130 +        if (p) *p = '\0';
131 +
132 +        return retval ? g_string_free (retval, FALSE) : NULL;
133 +}
134 +
135 +static char *
136 +get_display_number (void)
137 +{
138 +        const char *display_name;
139 +        char       *retval;
140 +        char       *p;
141 +
142 +        display_name = gdk_display_get_name (gdk_display_get_default ());
143 +
144 +        p = strchr (display_name, ':');
145 +        if (!p)
146 +                return g_strdup ("0");
147 +
148 +        while (*p == ':') p++;
149 +
150 +        retval = g_strdup (p);
151 +
152 +        p = strchr (retval, '.');
153 +        if (p != NULL)
154 +                *p = '\0';
155 +
156 +        return retval;
157 +}
158 +
159 +static gboolean
160 +gdm_authenticate_connection (GdmProtocolData *data)
161 +{
162 +#define GDM_MIT_MAGIC_COOKIE_LEN 16
163 +
164 +        const char *xau_path;
165 +        FILE       *f;
166 +        Xauth      *xau;
167 +        char       *display_number;
168 +        gboolean    retval;
169 +
170 +        if (data->auth_cookie) {
171 +                char *msg;
172 +                char *response;
173 +
174 +                msg = g_strdup_printf (GDM_PROTOCOL_MSG_AUTHENTICATE " %s",
175 +                                       data->auth_cookie);
176 +                response = gdm_send_protocol_msg (data, msg);
177 +                g_free (msg);
178 +
179 +                if (response && !strcmp (response, "OK")) {
180 +                        g_free (response);
181 +                        return TRUE;
182 +                } else {
183 +                        g_free (response);
184 +                        g_free (data->auth_cookie);
185 +                        data->auth_cookie = NULL;
186 +                }
187 +        }
188 +
189 +        if (!(xau_path = XauFileName ()))
190 +                return FALSE;
191 +
192 +        if (!(f = fopen (xau_path, "r")))
193 +                return FALSE;
194 +
195 +        retval = FALSE;
196 +        display_number = get_display_number ();
197 +
198 +        while ((xau = XauReadAuth (f))) {
199 +                char  buffer[40]; /* 2*16 == 32, so 40 is enough */
200 +                char *msg;
201 +                char *response;
202 +                int   i;
203 +
204 +                if (xau->family != FamilyLocal ||
205 +                    strncmp (xau->number, display_number, xau->number_length) ||
206 +                    strncmp (xau->name, "MIT-MAGIC-COOKIE-1", xau->name_length) ||
207 +                    xau->data_length != GDM_MIT_MAGIC_COOKIE_LEN) {
208 +                        XauDisposeAuth (xau);
209 +                        continue;
210 +                }
211 +
212 +                for (i = 0; i < GDM_MIT_MAGIC_COOKIE_LEN; i++)
213 +                        g_snprintf (buffer + 2*i, 3, "%02x", (guint)(guchar)xau->data[i]);
214 +
215 +                XauDisposeAuth (xau);
216 +
217 +                msg = g_strdup_printf (GDM_PROTOCOL_MSG_AUTHENTICATE " %s", buffer);
218 +                response = gdm_send_protocol_msg (data, msg);
219 +                g_free (msg);
220 +
221 +                if (response && !strcmp (response, "OK")) {
222 +                       data->auth_cookie = g_strdup (buffer);
223 +                        g_free (response);
224 +                        retval = TRUE;
225 +                        break;
226 +                }
227 +
228 +                g_free (response);
229 +        }
230 +
231 +        g_free (display_number);
232 +
233 +        fclose (f);
234 +
235 +        return retval;
236 +
237 +#undef GDM_MIT_MAGIC_COOKIE_LEN
238 +}
239 +
240 +static void
241 +gdm_shutdown_protocol_connection (GdmProtocolData *data)
242 +{
243 +        if (data->fd)
244 +                close (data->fd);
245 +        data->fd = 0;
246 +}
247 +
248 +static gboolean
249 +gdm_init_protocol_connection (GdmProtocolData *data)
250 +{
251 +        struct sockaddr_un  addr;
252 +        char               *response;
253 +
254 +        g_assert (data->fd <= 0);
255 +
256 +        data->fd = socket (AF_UNIX, SOCK_STREAM, 0);
257 +        if (data->fd < 0) {
258 +                g_warning ("Failed to create GDM socket: %s",
259 +                           g_strerror (errno));
260 +               gdm_shutdown_protocol_connection (data);
261 +                return FALSE;
262 +        }
263 +
264 +       if (g_file_test (GDM_PROTOCOL_SOCKET_PATH, G_FILE_TEST_EXISTS))
265 +         strcpy (addr.sun_path, GDM_PROTOCOL_SOCKET_PATH);
266 +       else
267 +         strcpy (addr.sun_path, "/tmp/.gdm_socket");
268 +
269 +       addr.sun_family = AF_UNIX;
270 +
271 +        if (connect (data->fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) {
272 +                g_warning ("Failed to establish a connection with GDM: %s",
273 +                           g_strerror (errno));
274 +               gdm_shutdown_protocol_connection (data);
275 +                return FALSE;
276 +        }
277 +
278 +        response = gdm_send_protocol_msg (data, GDM_PROTOCOL_MSG_VERSION);
279 +        if (!response || strncmp (response, "GDM ", strlen ("GDM ") != 0)) {
280 +                g_free (response);
281 +
282 +                g_warning ("Failed to get protocol version from GDM");
283 +               gdm_shutdown_protocol_connection (data);
284 +
285 +                return FALSE;
286 +        }
287 +       g_free (response);
288 +
289 +        if (!gdm_authenticate_connection (data)) {
290 +                g_warning ("Failed to authenticate with GDM");
291 +               gdm_shutdown_protocol_connection (data);
292 +                return FALSE;
293 +        }
294 +
295 +        return TRUE;
296 +}
297 +
298 +static void
299 +gdm_parse_query_response (GdmProtocolData *data,
300 +                          const char      *response)
301 +{
302 +        char **actions;
303 +        int    i;
304 +
305 +        data->available_actions = GDM_LOGOUT_ACTION_NONE;
306 +        data->current_actions   = GDM_LOGOUT_ACTION_NONE;
307 +
308 +        if (strncmp (response, "OK ", 3) != 0)
309 +                return;
310 +
311 +        response += 3;
312 +
313 +        actions = g_strsplit (response, ";", -1);
314 +        for (i = 0; actions[i]; i++) {
315 +                GdmLogoutAction  action = GDM_LOGOUT_ACTION_NONE;
316 +                gboolean         selected = FALSE;
317 +                char            *str = actions [i];
318 +                int              len;
319 +
320 +                len = strlen (str);
321 +                if (!len)
322 +                        continue;
323 +
324 +                if (str[len - 1] == '!') {
325 +                        selected = TRUE;
326 +                        str[len - 1] = '\0';
327 +                }
328 +
329 +                if (!strcmp (str, GDM_ACTION_STR_SHUTDOWN))
330 +                        action = GDM_LOGOUT_ACTION_SHUTDOWN;
331 +                else if (!strcmp (str, GDM_ACTION_STR_REBOOT))
332 +                        action = GDM_LOGOUT_ACTION_REBOOT;
333 +                else if (!strcmp (str, GDM_ACTION_STR_SUSPEND))
334 +                        action = GDM_LOGOUT_ACTION_SUSPEND;
335 +
336 +                data->available_actions |= action;
337 +                if (selected)
338 +                        data->current_actions |= action;
339 +        }
340 +
341 +        g_strfreev (actions);
342 +}
343 +
344 +static void
345 +gdm_update_logout_actions (GdmProtocolData *data)
346 +{
347 +        time_t  current_time;
348 +        char   *response;
349 +
350 +        current_time = time (NULL);
351 +        if (current_time <= (data->last_update + GDM_PROTOCOL_UPDATE_INTERVAL))
352 +                return;
353 +
354 +        data->last_update = current_time;
355 +
356 +        if (!gdm_init_protocol_connection (data))
357 +                return;
358 +
359 +        if ((response = gdm_send_protocol_msg (data, GDM_PROTOCOL_MSG_QUERY_ACTION))) {
360 +                gdm_parse_query_response (data, response);
361 +                g_free (response);
362 +        }
363 +
364 +        gdm_shutdown_protocol_connection (data);
365 +}
366 +
367 +gboolean
368 +gdm_supports_logout_action (GdmLogoutAction action)
369 +{
370 +        gdm_update_logout_actions (&gdm_protocol_data);
371 +
372 +        return (gdm_protocol_data.available_actions & action) != 0;
373 +}
374 +
375 +GdmLogoutAction
376 +gdm_get_logout_action (void)
377 +{
378 +        gdm_update_logout_actions (&gdm_protocol_data);
379 +
380 +        return gdm_protocol_data.current_actions;
381 +}
382 +
383 +void
384 +gdm_set_logout_action (GdmLogoutAction action)
385 +{
386 +       char *action_str = NULL;
387 +        char *msg;
388 +        char *response;
389 +
390 +        if (!gdm_init_protocol_connection (&gdm_protocol_data))
391 +                return;
392 +
393 +        switch (action) {
394 +        case GDM_LOGOUT_ACTION_NONE:
395 +                action_str = GDM_ACTION_STR_NONE;
396 +                break;
397 +        case GDM_LOGOUT_ACTION_SHUTDOWN:
398 +                action_str = GDM_ACTION_STR_SHUTDOWN;
399 +                break;
400 +        case GDM_LOGOUT_ACTION_REBOOT:
401 +                action_str = GDM_ACTION_STR_REBOOT;
402 +                break;
403 +        case GDM_LOGOUT_ACTION_SUSPEND:
404 +                action_str = GDM_ACTION_STR_SUSPEND;
405 +                break;
406 +        }
407 +
408 +        msg = g_strdup_printf (GDM_PROTOCOL_MSG_SET_ACTION " %s", action_str);
409 +
410 +        response = gdm_send_protocol_msg (&gdm_protocol_data, msg);
411 +
412 +        g_free (msg);
413 +        g_free (response);
414 +
415 +       gdm_protocol_data.last_update = 0;
416 +
417 +        gdm_shutdown_protocol_connection (&gdm_protocol_data);
418 +}
419 +
420 +void
421 +gdm_new_login (void)
422 +{
423 +        char *response;
424 +
425 +        if (!gdm_init_protocol_connection (&gdm_protocol_data))
426 +                return;
427 +
428 +        response = gdm_send_protocol_msg (&gdm_protocol_data,
429 +                                         GDM_PROTOCOL_MSG_FLEXI_XSERVER);
430 +
431 +        g_free (response);
432 +
433 +       gdm_protocol_data.last_update = 0;
434 +
435 +        gdm_shutdown_protocol_connection (&gdm_protocol_data);
436 +}
437 Index: b/gnome-panel/panel-logout.c
438 ===================================================================
439 --- /dev/null
440 +++ b/gnome-panel/panel-logout.c
441 @@ -0,0 +1,402 @@
442 +/*
443 + * panel-logout.c:
444 + *
445 + * Copyright (C) 2006 Vincent Untz
446 + *
447 + * This program is free software; you can redistribute it and/or
448 + * modify it under the terms of the GNU General Public License as
449 + * published by the Free Software Foundation; either version 2 of the
450 + * License, or (at your option) any later version.
451 + *
452 + * This program is distributed in the hope that it will be useful, but
453 + * WITHOUT ANY WARRANTY; without even the implied warranty of
454 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
455 + * General Public License for more details.
456 + *
457 + * You should have received a copy of the GNU General Public License
458 + * along with this program; if not, write to the Free Software
459 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
460 + * 02111-1307, USA.
461 + *
462 + * Authors:
463 + *     Vincent Untz <vuntz@gnome.org>
464 + */
465 +
466 +
467 +#include <config.h>
468 +
469 +#include <string.h>
470 +
471 +#include <glib/gi18n.h>
472 +#include <gtk/gtkimage.h>
473 +#include <gtk/gtklabel.h>
474 +#include <gtk/gtkstock.h>
475 +
476 +#include <libpanel-util/panel-power-manager.h>
477 +
478 +#include "panel-logout.h"
479 +#include "panel-gdm.h"
480 +#include "panel-session.h"
481 +#include "panel-icon-names.h"
482 +
483 +#define PANEL_LOGOUT_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_LOGOUT_DIALOG, PanelLogoutDialogPrivate))
484 +
485 +#define AUTOMATIC_ACTION_TIMEOUT 60
486 +
487 +enum {
488 +       PANEL_LOGOUT_RESPONSE_LOGOUT,
489 +       PANEL_LOGOUT_RESPONSE_SWITCH_USER,
490 +       PANEL_LOGOUT_RESPONSE_SHUTDOWN,
491 +       PANEL_LOGOUT_RESPONSE_REBOOT,
492 +       PANEL_LOGOUT_RESPONSE_STD,
493 +       PANEL_LOGOUT_RESPONSE_STR
494 +};
495 +
496 +struct _PanelLogoutDialogPrivate {
497 +       PanelLogoutDialogType type;
498 +
499 +       PanelPowerManager    *power_manager;
500 +
501 +       int                   timeout;
502 +       unsigned int          timeout_id;
503 +
504 +       unsigned int          default_response;
505 +};
506 +
507 +static PanelLogoutDialog *current_dialog = NULL;
508 +
509 +static void panel_logout_destroy (PanelLogoutDialog *logout_dialog,
510 +                                 gpointer           data);
511 +static void panel_logout_response (PanelLogoutDialog *logout_dialog,
512 +                                  guint              response_id,
513 +                                  gpointer           data);
514 +
515 +enum {
516 +  PROP_0,
517 +  PROP_MESSAGE_TYPE
518 +};
519 +G_DEFINE_TYPE (PanelLogoutDialog, panel_logout, GTK_TYPE_MESSAGE_DIALOG);
520 +
521 +static void
522 +panel_logout_set_property (GObject      *object,
523 +                          guint         prop_id,
524 +                          const GValue *value,
525 +                          GParamSpec   *pspec)
526 +{
527 +       switch (prop_id) {
528 +       case PROP_MESSAGE_TYPE:
529 +               break;
530 +       default:
531 +               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
532 +               break;
533 +       }
534 +}
535 +
536 +static void
537 +panel_logout_get_property (GObject     *object,
538 +                          guint        prop_id,
539 +                          GValue      *value,
540 +                          GParamSpec  *pspec)
541 +{
542 +       switch (prop_id) {
543 +       case PROP_MESSAGE_TYPE:
544 +               g_value_set_enum (value, GTK_MESSAGE_WARNING);
545 +               break;
546 +       default:
547 +               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
548 +               break;
549 +       }
550 +}
551 +
552 +static void
553 +panel_logout_class_init (PanelLogoutDialogClass *klass)
554 +{
555 +       GObjectClass *gobject_class;
556 +
557 +       gobject_class = G_OBJECT_CLASS (klass);
558 +
559 +       /* This is a workaround to avoid a stupid crash: libgnomeui
560 +        * listens for the "show" signal on all GtkMessageDialog and
561 +        * gets the "message-type" of the dialogs. We will crash when
562 +        * it accesses this property if we don't override it since we
563 +        * didn't define it. */
564 +       gobject_class->set_property = panel_logout_set_property;
565 +       gobject_class->get_property = panel_logout_get_property;
566 +
567 +       g_object_class_override_property (gobject_class,
568 +                                         PROP_MESSAGE_TYPE,
569 +                                         "message-type");
570 +
571 +       g_type_class_add_private (klass, sizeof (PanelLogoutDialogPrivate));
572 +}
573 +
574 +static void
575 +panel_logout_init (PanelLogoutDialog *logout_dialog)
576 +{
577 +       logout_dialog->priv = PANEL_LOGOUT_DIALOG_GET_PRIVATE (logout_dialog);
578 +
579 +       logout_dialog->priv->timeout_id = 0;
580 +       logout_dialog->priv->timeout    = 0;
581 +       logout_dialog->priv->default_response = GTK_RESPONSE_CANCEL;
582 +
583 +       /* FIXME: we should most probably use gtk_window_set_transient_for(PANEL) */
584 +       gtk_window_set_skip_taskbar_hint (GTK_WINDOW (logout_dialog), TRUE);
585 +       gtk_window_set_keep_above (GTK_WINDOW (logout_dialog), TRUE);
586 +       gtk_window_stick (GTK_WINDOW (logout_dialog));
587 +       gtk_window_set_position (GTK_WINDOW (logout_dialog),
588 +                                GTK_WIN_POS_CENTER_ALWAYS);
589 +
590 +       logout_dialog->priv->power_manager = panel_power_manager_get ();
591 +
592 +       g_signal_connect (logout_dialog, "destroy",
593 +                         G_CALLBACK (panel_logout_destroy), NULL);
594 +       g_signal_connect (logout_dialog, "response",
595 +                         G_CALLBACK (panel_logout_response), NULL);
596 +}
597 +
598 +static void
599 +panel_logout_destroy (PanelLogoutDialog *logout_dialog,
600 +                     gpointer           data)
601 +{
602 +       if (logout_dialog->priv->timeout_id != 0)
603 +               g_source_remove (logout_dialog->priv->timeout_id);
604 +       logout_dialog->priv->timeout_id = 0;
605 +
606 +       g_object_unref (logout_dialog->priv->power_manager);
607 +       logout_dialog->priv->power_manager = NULL;
608 +
609 +       current_dialog = NULL;
610 +}
611 +
612 +static void
613 +panel_logout_response (PanelLogoutDialog *logout_dialog,
614 +                      guint      response_id,
615 +                      gpointer   data)
616 +{
617 +       PanelPowerManager *power_manager;
618 +
619 +       power_manager = g_object_ref (logout_dialog->priv->power_manager);
620 +       gtk_widget_destroy (GTK_WIDGET (logout_dialog));
621 +
622 +       switch (response_id) {
623 +       case GTK_RESPONSE_CANCEL:
624 +               break;
625 +       case PANEL_LOGOUT_RESPONSE_LOGOUT:
626 +               gdm_set_logout_action (GDM_LOGOUT_ACTION_NONE);
627 +               panel_session_request_logout ();
628 +               break;
629 +       case PANEL_LOGOUT_RESPONSE_SWITCH_USER:
630 +               gdm_new_login ();
631 +               break;
632 +       case PANEL_LOGOUT_RESPONSE_SHUTDOWN:
633 +               gdm_set_logout_action (GDM_LOGOUT_ACTION_SHUTDOWN);
634 +               panel_session_request_logout ();
635 +               break;
636 +       case PANEL_LOGOUT_RESPONSE_REBOOT:
637 +               gdm_set_logout_action (GDM_LOGOUT_ACTION_REBOOT);
638 +               panel_session_request_logout ();
639 +               break;
640 +       case PANEL_LOGOUT_RESPONSE_STD:
641 +               if (panel_power_manager_can_hibernate (power_manager))
642 +                       panel_power_manager_attempt_hibernate (power_manager);
643 +               break;
644 +       case PANEL_LOGOUT_RESPONSE_STR:
645 +               if (panel_power_manager_can_suspend (power_manager))
646 +                       panel_power_manager_attempt_suspend (power_manager);
647 +               break;
648 +       case GTK_RESPONSE_NONE:
649 +       case GTK_RESPONSE_DELETE_EVENT:
650 +               break;
651 +       default:
652 +               g_assert_not_reached ();
653 +       }
654 +       g_object_unref (power_manager);
655 +}
656 +
657 +static gboolean
658 +panel_logout_timeout (gpointer data)
659 +{
660 +       PanelLogoutDialog *logout_dialog;
661 +       char              *secondary_text;
662 +       char              *name;
663 +       int                seconds_to_show;
664 +
665 +       logout_dialog = (PanelLogoutDialog *) data;
666 +
667 +       if (!logout_dialog->priv->timeout) {
668 +               gtk_dialog_response (GTK_DIALOG (logout_dialog),
669 +                                    logout_dialog->priv->default_response);
670 +
671 +               return FALSE;
672 +       }
673 +
674 +       if (logout_dialog->priv->timeout <= 30)
675 +               seconds_to_show = logout_dialog->priv->timeout;
676 +       else {
677 +               seconds_to_show = (logout_dialog->priv->timeout/10) * 10;
678 +               if (logout_dialog->priv->timeout % 10)
679 +                       seconds_to_show += 10;
680 +       }
681 +
682 +       switch (logout_dialog->priv->type) {
683 +       case PANEL_LOGOUT_DIALOG_LOGOUT:
684 +               secondary_text = ngettext ("You are currently logged in as "
685 +                                          "\"%s\".\n"
686 +                                          "You will be automatically logged "
687 +                                          "out in %d second.",
688 +                                          "You are currently logged in as "
689 +                                          "\"%s\".\n"
690 +                                          "You will be automatically logged "
691 +                                          "out in %d seconds.",
692 +                                          seconds_to_show);
693 +               break;
694 +       case PANEL_LOGOUT_DIALOG_SHUTDOWN:
695 +               secondary_text = ngettext ("You are currently logged in as "
696 +                                          "\"%s\".\n"
697 +                                          "This system will be automatically "
698 +                                          "shut down in %d second.",
699 +                                          "You are currently logged in as "
700 +                                          "\"%s\".\n"
701 +                                          "This system will be automatically "
702 +                                          "shut down in %d seconds.",
703 +                                          seconds_to_show);
704 +               break;
705 +       default:
706 +               g_assert_not_reached ();
707 +       }
708 +
709 +       name = g_locale_to_utf8 (g_get_real_name (), -1, NULL, NULL, NULL);
710 +       if (!name || name[0] == '\0' || strcmp (name, "Unknown") == 0)
711 +               name = g_locale_to_utf8 (g_get_user_name (), -1 , NULL, NULL, NULL);
712 +
713 +       if (!name)
714 +               name = g_strdup (g_get_user_name ());
715 +
716 +       gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (logout_dialog),
717 +                                                 secondary_text,
718 +                                                 name,
719 +                                                 seconds_to_show,
720 +                                                 NULL);
721 +
722 +       logout_dialog->priv->timeout--;
723 +
724 +       g_free (name);
725 +
726 +       return TRUE;
727 +}
728 +
729 +static void
730 +panel_logout_set_timeout (PanelLogoutDialog *logout_dialog)
731 +{
732 +       logout_dialog->priv->timeout = AUTOMATIC_ACTION_TIMEOUT;
733 +
734 +       /* Sets the secondary text */
735 +       panel_logout_timeout (logout_dialog);
736 +
737 +       if (logout_dialog->priv->timeout_id != 0)
738 +               g_source_remove (logout_dialog->priv->timeout_id);
739 +
740 +       logout_dialog->priv->timeout_id = g_timeout_add (1000,
741 +                                                        panel_logout_timeout,
742 +                                                        logout_dialog);
743 +}
744 +
745 +void
746 +panel_logout_new (PanelLogoutDialogType  type,
747 +                 GdkScreen             *screen,
748 +                 guint32                activate_time)
749 +{
750 +       PanelLogoutDialog *logout_dialog;
751 +       char              *icon_name;
752 +       char              *primary_text;
753 +
754 +       if (current_dialog != NULL) {
755 +               if (current_dialog->priv->type == type) {
756 +                       gtk_window_set_screen (GTK_WINDOW (current_dialog),
757 +                                              screen);
758 +                       gtk_window_present_with_time (GTK_WINDOW (current_dialog),
759 +                                                     activate_time);
760 +                       panel_logout_set_timeout (current_dialog);
761 +                       //FIXME center the dialog on screen, and reset sticky and above_all?
762 +                       return;
763 +               } else {
764 +                       gtk_widget_destroy (GTK_WIDGET (current_dialog));
765 +               }
766 +       }
767 +
768 +       logout_dialog = g_object_new (PANEL_TYPE_LOGOUT_DIALOG, NULL);
769 +       current_dialog = logout_dialog;
770 +
771 +       gtk_window_set_title (GTK_WINDOW (logout_dialog), "");
772 +
773 +       logout_dialog->priv->type = type;
774 +
775 +       icon_name    = NULL;
776 +       primary_text = NULL;
777 +
778 +       switch (type) {
779 +       case PANEL_LOGOUT_DIALOG_LOGOUT:
780 +               icon_name      = PANEL_ICON_LOGOUT;
781 +               primary_text   = _("Log out of this system now?");
782 +               // FIXME need to verify that this response can be used
783 +               logout_dialog->priv->default_response = PANEL_LOGOUT_DIALOG_LOGOUT;
784 +
785 +               //FIXME is gdm running?
786 +               gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
787 +                                      _("_Switch User"),
788 +                                      PANEL_LOGOUT_RESPONSE_SWITCH_USER);
789 +               gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
790 +                                      GTK_STOCK_CANCEL,
791 +                                      GTK_RESPONSE_CANCEL);
792 +               gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
793 +                                      _("_Log Out"),
794 +                                      PANEL_LOGOUT_RESPONSE_LOGOUT);
795 +               break;
796 +       case PANEL_LOGOUT_DIALOG_SHUTDOWN:
797 +               icon_name      = PANEL_ICON_SHUTDOWN;
798 +               primary_text   = _("Shut down this system now?");
799 +
800 +               logout_dialog->priv->default_response = PANEL_LOGOUT_RESPONSE_SHUTDOWN;
801 +               if (panel_power_manager_can_suspend (logout_dialog->priv->power_manager))
802 +                       gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
803 +                                              _("S_uspend"),
804 +                                              PANEL_LOGOUT_RESPONSE_STR);
805 +
806 +               if (panel_power_manager_can_hibernate (logout_dialog->priv->power_manager))
807 +                       gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
808 +                                              _("_Hibernate"),
809 +                                              PANEL_LOGOUT_RESPONSE_STD);
810 +
811 +               if (gdm_supports_logout_action (GDM_LOGOUT_ACTION_REBOOT))
812 +                       gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
813 +                                              _("_Restart"),
814 +                                              PANEL_LOGOUT_RESPONSE_REBOOT);
815 +
816 +               gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
817 +                                      GTK_STOCK_CANCEL,
818 +                                      GTK_RESPONSE_CANCEL);
819 +
820 +               if (gdm_supports_logout_action (GDM_LOGOUT_ACTION_SHUTDOWN))
821 +                       gtk_dialog_add_button (GTK_DIALOG (logout_dialog),
822 +                                              _("_Shut Down"),
823 +                                              PANEL_LOGOUT_RESPONSE_SHUTDOWN);
824 +               break;
825 +       default:
826 +               g_assert_not_reached ();
827 +       }
828 +
829 +       gtk_image_set_from_icon_name (GTK_IMAGE (GTK_MESSAGE_DIALOG (logout_dialog)->image),
830 +                                     icon_name, GTK_ICON_SIZE_DIALOG);
831 +
832 +       gtk_label_set_text (GTK_LABEL (GTK_MESSAGE_DIALOG (logout_dialog)->label),
833 +                           primary_text);
834 +
835 +       gtk_dialog_set_default_response (GTK_DIALOG (logout_dialog),
836 +                                        logout_dialog->priv->default_response);
837 +
838 +       panel_logout_set_timeout (logout_dialog);
839 +
840 +       gtk_window_set_screen (GTK_WINDOW (logout_dialog), screen);
841 +       gtk_widget_show (GTK_WIDGET (logout_dialog));
842 +       gdk_window_focus (GTK_WIDGET (current_dialog)->window, activate_time);
843 +}
844 Index: b/gnome-panel/panel-gdm.h
845 ===================================================================
846 --- /dev/null
847 +++ b/gnome-panel/panel-gdm.h
848 @@ -0,0 +1,52 @@
849 +/*
850 + * gdm-logout-action.h: GDM logout action protocol implementation
851 + *
852 + * Copyright (C) 2005 Raffaele Sandrini
853 + * Copyright (C) 2005 Red Hat, Inc.
854 + * Copyright (C) 2002, 2003 George Lebl
855 + * Copyright (C) 2001 Queen of England,
856 + *
857 + * This program is free software; you can redistribute it and/or
858 + * modify it under the terms of the GNU General Public License as
859 + * published by the Free Software Foundation; either version 2 of the
860 + * License, or (at your option) any later version.
861 + *
862 + * This program is distributed in the hope that it will be useful, but
863 + * WITHOUT ANY WARRANTY; without even the implied warranty of
864 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
865 + * General Public License for more details.
866 + *
867 + * You should have received a copy of the GNU General Public License
868 + * along with this program; if not, write to the Free Software
869 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
870 + * 02111-1307, USA.
871 + *
872 + * Authors:
873 + *      Raffaele Sandrini <rasa@gmx.ch>
874 + *      George Lebl <jirka@5z.com>
875 + *      Mark McLoughlin <mark@skynet.ie>
876 + */
877 +
878 +#ifndef __GDM_LOGOUT_ACTION_H__
879 +#define __GDM_LOGOUT_ACTION_H__
880 +
881 +#include <glib.h>
882 +
883 +G_BEGIN_DECLS
884 +
885 +typedef enum {
886 +        GDM_LOGOUT_ACTION_NONE     = 0,
887 +        GDM_LOGOUT_ACTION_SHUTDOWN = 1 << 0,
888 +        GDM_LOGOUT_ACTION_REBOOT   = 1 << 1,
889 +        GDM_LOGOUT_ACTION_SUSPEND  = 1 << 2
890 +} GdmLogoutAction;
891 +
892 +gboolean gdm_supports_logout_action (GdmLogoutAction action);
893 +
894 +void            gdm_set_logout_action (GdmLogoutAction action);
895 +GdmLogoutAction gdm_get_logout_action (void);
896 +void            gdm_new_login         (void);
897 +
898 +G_END_DECLS
899 +
900 +#endif /* __GDM_LOGOUT_ACTION_H__ */
901 Index: b/gnome-panel/panel-logout.h
902 ===================================================================
903 --- /dev/null
904 +++ b/gnome-panel/panel-logout.h
905 @@ -0,0 +1,66 @@
906 +/*
907 + * panel-logout.h:
908 + *
909 + * Copyright (C) 2006 Vincent Untz
910 + *
911 + * This program is free software; you can redistribute it and/or
912 + * modify it under the terms of the GNU General Public License as
913 + * published by the Free Software Foundation; either version 2 of the
914 + * License, or (at your option) any later version.
915 + *
916 + * This program is distributed in the hope that it will be useful, but
917 + * WITHOUT ANY WARRANTY; without even the implied warranty of
918 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
919 + * General Public License for more details.
920 + *
921 + * You should have received a copy of the GNU General Public License
922 + * along with this program; if not, write to the Free Software
923 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
924 + * 02111-1307, USA.
925 + *
926 + * Authors:
927 + *     Vincent Untz <vuntz@gnome.org>
928 + */
929 +
930 +#ifndef PANEL_LOGOUT_H
931 +#define PANEL_LOGOUT_H
932 +
933 +#include "gtk/gtkmessagedialog.h"
934 +
935 +G_BEGIN_DECLS
936 +
937 +typedef enum {
938 +       PANEL_LOGOUT_DIALOG_LOGOUT,
939 +       PANEL_LOGOUT_DIALOG_SHUTDOWN
940 +} PanelLogoutDialogType;
941 +
942 +#define PANEL_TYPE_LOGOUT_DIALOG         (panel_logout_get_type ())
943 +#define PANEL_LOGOUT_DIALOG(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), PANEL_TYPE_LOGOUT_DIALOG, PanelLogoutDialog))
944 +#define PANEL_LOGOUT_DIALOG_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), PANEL_TYPE_LOGOUT_DIALOG, PanelLogoutDialogClass))
945 +#define PANEL_IS_LOGOUT_DIALOG(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), PANEL_TYPE_LOGOUT_DIALOG))
946 +#define PANEL_IS_LOGOUT_DIALOG_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), PANEL_TYPE_LOGOUT_DIALOG))
947 +#define PANEL_LOGOUT_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), PANEL_TYPE_LOGOUT_DIALOG, PanelLogoutDialogClass))
948 +
949 +typedef struct _PanelLogoutDialog        PanelLogoutDialog;
950 +typedef struct _PanelLogoutDialogClass   PanelLogoutDialogClass;
951 +typedef struct _PanelLogoutDialogPrivate PanelLogoutDialogPrivate;
952 +
953 +struct _PanelLogoutDialog {
954 +       GtkMessageDialog          parent;
955 +
956 +       PanelLogoutDialogPrivate *priv;
957 +};
958 +
959 +struct _PanelLogoutDialogClass {
960 +       GtkMessageDialogClass   parent_class;
961 +};
962 +
963 +GType  panel_logout_get_type          (void) G_GNUC_CONST;
964 +
965 +void panel_logout_new (PanelLogoutDialogType  type,
966 +                      GdkScreen             *screen,
967 +                      guint32                activate_time);
968 +
969 +G_END_DECLS
970 +
971 +#endif /* PANEL_LOGOUT_H */
972 Index: b/gnome-panel/panel-session.c
973 ===================================================================
974 --- a/gnome-panel/panel-session.c
975 +++ b/gnome-panel/panel-session.c
976 @@ -32,6 +32,34 @@
977  #include "panel-profile.h"
978  #include "panel-shell.h"
979  
980 +void
981 +panel_session_request_logout (void)
982 +{
983 +       GnomeClient *client;
984 +       static int   recursion_guard = 0;
985 +
986 +       if (recursion_guard)
987 +               return;
988 +
989 +       recursion_guard++;
990 +
991 +       if (!(client = gnome_master_client ()))
992 +               return;
993 +
994 +       /* Only request a Global save. We only want a Local
995 +        * save if the user selects 'Save current setup'
996 +        * from the dialog.
997 +        */
998 +       gnome_client_request_save (client,
999 +                                  GNOME_SAVE_GLOBAL,
1000 +                                  TRUE,
1001 +                                  GNOME_INTERACT_ANY,
1002 +                                  TRUE, /* do not use the gnome-session gui */
1003 +                                  TRUE);
1004 +
1005 +       recursion_guard--;
1006 +}
1007 +
1008  static void
1009  panel_session_handle_die_request (GnomeClient *client)
1010  {
1011 Index: b/gnome-panel/panel-session.h
1012 ===================================================================
1013 --- a/gnome-panel/panel-session.h
1014 +++ b/gnome-panel/panel-session.h
1015 @@ -29,6 +29,7 @@ G_BEGIN_DECLS
1016  
1017  void panel_session_init           (void);
1018  void panel_session_do_not_restart (void);
1019 +void panel_session_request_logout (void);
1020  
1021  G_END_DECLS
1022  
1023 Index: b/gnome-panel/Makefile.am
1024 ===================================================================
1025 --- a/gnome-panel/Makefile.am
1026 +++ b/gnome-panel/Makefile.am
1027 @@ -97,6 +97,8 @@ panel_sources =                       \
1028         panel-force-quit.c      \
1029         panel-lockdown.c        \
1030         panel-addto.c           \
1031 +       panel-logout.c          \
1032 +       panel-gdm.c             \
1033         panel-ditem-editor.c    \
1034         $(NULL)
1035  
1036 @@ -143,6 +145,8 @@ panel_headers =                     \
1037         panel-force-quit.h      \
1038         panel-lockdown.h        \
1039         panel-addto.h           \
1040 +       panel-logout.h          \
1041 +       panel-gdm.h             \
1042         panel-ditem-editor.h    \
1043         panel-icon-names.h      \
1044         $(NULL)
1045 Index: b/gnome-panel/libpanel-util/panel-session-manager.c
1046 ===================================================================
1047 --- a/gnome-panel/libpanel-util/panel-session-manager.c
1048 +++ b/gnome-panel/libpanel-util/panel-session-manager.c
1049 @@ -23,10 +23,13 @@
1050   */
1051  
1052  #include <dbus/dbus-glib.h>
1053 +#include <gtk/gtk.h>
1054  
1055  #include "panel-cleanup.h"
1056  #include "panel-dbus-service.h"
1057  
1058 +#include "panel-logout.h"
1059 +#include "panel-session.h"
1060  #include "panel-session-manager.h"
1061  
1062  static GObject *panel_session_manager_constructor (GType                  type,
1063 @@ -96,6 +99,20 @@ panel_session_manager_request_logout (Pa
1064                 g_warning ("Could not connect to session manager: %s",
1065                            error->message);
1066                 g_error_free (error);
1067 +
1068 +               /* Fall back to the old way */
1069 +               switch (mode) {
1070 +               case PANEL_SESSION_MANAGER_LOGOUT_MODE_NORMAL:
1071 +                       panel_logout_new (PANEL_LOGOUT_DIALOG_LOGOUT,
1072 +                                         gdk_screen_get_default (),
1073 +                                         gtk_get_current_event_time ());
1074 +                       break;
1075 +               case PANEL_SESSION_MANAGER_LOGOUT_MODE_NO_CONFIRMATION:
1076 +                       panel_session_request_logout ();
1077 +                       break;
1078 +               default:
1079 +                       g_warning ("Invalid mode requested for logout");
1080 +               }
1081                 return;
1082         }
1083  
1084 @@ -126,6 +143,12 @@ panel_session_manager_request_shutdown (
1085                 g_warning ("Could not connect to session manager: %s",
1086                            error->message);
1087                 g_error_free (error);
1088 +
1089 +               /* Fall back to the old way */
1090 +               panel_logout_new (PANEL_LOGOUT_DIALOG_SHUTDOWN,
1091 +                                 gdk_screen_get_default (),
1092 +                                 gtk_get_current_event_time ());
1093 +
1094                 return;
1095         }
1096  
This page took 0.132722 seconds and 3 git commands to generate.