source: proiecte/PPPP/gdm/gui/user-switch-applet/applet.c @ 134

Last change on this file since 134 was 134, checked in by (none), 14 years ago

gdm sources with the modifications for webcam

File size: 56.8 KB
Line 
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2004-2005 James M. Cape <jcape@ignore-your.tv>.
4 * Copyright (C) 2008      Red Hat, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU 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  02111-1307  USA
19 */
20
21#include "config.h"
22
23#include <string.h>
24#include <unistd.h>
25#include <sys/types.h>
26
27#include <glib/gi18n.h>
28#include <gdk/gdkkeysyms.h>
29#include <gtk/gtk.h>
30
31#include <gconf/gconf.h>
32#include <gconf/gconf-client.h>
33
34#include <glade/glade-xml.h>
35#include <dbus/dbus-glib.h>
36
37#include <bonobo/bonobo-main.h>
38#include <bonobo/bonobo-ui-util.h>
39
40#include <panel-applet.h>
41#include <panel-applet-gconf.h>
42
43#include "gdm-user-manager.h"
44#include "gdm-entry-menu-item.h"
45
46#define LOCKDOWN_DIR    "/desktop/gnome/lockdown"
47#define LOCKDOWN_KEY    LOCKDOWN_DIR "/disable_user_switching"
48
49typedef enum {
50        GSM_PRESENCE_STATUS_AVAILABLE = 0,
51        GSM_PRESENCE_STATUS_INVISIBLE,
52        GSM_PRESENCE_STATUS_BUSY,
53        GSM_PRESENCE_STATUS_IDLE,
54} GsmPresenceStatus;
55
56typedef struct _GdmAppletData
57{
58        PanelApplet    *applet;
59
60        GConfClient    *client;
61        GdmUserManager *manager;
62        GdmUser        *user;
63
64        GtkWidget      *menubar;
65        GtkWidget      *menuitem;
66        GtkWidget      *menu;
67#ifdef BUILD_PRESENSE_STUFF
68        GtkWidget      *user_item;
69#endif
70        GtkWidget      *control_panel_item;
71        GtkWidget      *account_item;
72        GtkWidget      *lock_screen_item;
73        GtkWidget      *login_screen_item;
74        GtkWidget      *quit_session_item;
75
76        gboolean        has_other_users;
77
78        guint           client_notify_lockdown_id;
79
80        guint           current_status;
81        guint           user_icon_changed_id;
82        guint           user_notify_id;
83        gint8           pixel_size;
84        gint            panel_size;
85        GtkIconSize     icon_size;
86#ifdef BUILD_PRESENSE_STUFF
87        DBusGProxy     *presence_proxy;
88#endif
89} GdmAppletData;
90
91typedef struct _SelectorResponseData
92{
93        GdmAppletData  *adata;
94        GtkRadioButton *radio;
95} SelectorResponseData;
96
97static void reset_icon   (GdmAppletData *adata);
98static void update_label (GdmAppletData *adata);
99
100static gboolean applet_factory (PanelApplet   *applet,
101                                const char    *iid,
102                                gpointer       data);
103
104PANEL_APPLET_BONOBO_FACTORY ("OAFIID:GNOME_FastUserSwitchApplet_Factory",
105                             PANEL_TYPE_APPLET,
106                             "gdm-user-switch-applet", "0",
107                             (PanelAppletFactoryCallback)applet_factory,
108                             NULL)
109
110static void
111about_me_cb (BonoboUIComponent *ui_container,
112             gpointer           data,
113             const char        *cname)
114{
115        GError *err;
116
117        err = NULL;
118        if (! g_spawn_command_line_async ("gnome-about-me", &err)) {
119                g_critical ("Could not run `gnome-about-me': %s",
120                            err->message);
121                g_error_free (err);
122                bonobo_ui_component_set_prop (ui_container,
123                                              "/commands/GdmAboutMe",
124                                              "hidden", "1",
125                                              NULL);
126        }
127}
128
129/*
130 * gnome-panel/applets/wncklet/window-menu.c:window_filter_button_press()
131 *
132 * Copyright (C) 2005 James M. Cape.
133 * Copyright (C) 2003 Sun Microsystems, Inc.
134 * Copyright (C) 2001 Free Software Foundation, Inc.
135 * Copyright (C) 2000 Helix Code, Inc.
136 */
137static gboolean
138menubar_button_press_event_cb (GtkWidget      *menubar,
139                               GdkEventButton *event,
140                               GdmAppletData  *adata)
141{
142        if (event->button != 1) {
143                g_signal_stop_emission_by_name (menubar, "button-press-event");
144                /* Reset the login window item */
145        }
146
147        return FALSE;
148}
149
150static void
151about_cb (BonoboUIComponent *ui_container,
152          gpointer           data,
153          const char        *cname)
154{
155        static const char *authors[] = {
156                "James M. Cape <jcape@ignore-your.tv>",
157                "Thomas Thurman <thomas@thurman.org.uk>",
158                "William Jon McCann <jmccann@redhat.com>",
159                NULL
160        };
161        static char *license[] = {
162                N_("The User Switch Applet is free software; you can redistribute it and/or modify "
163                   "it under the terms of the GNU General Public License as published by "
164                   "the Free Software Foundation; either version 2 of the License, or "
165                   "(at your option) any later version."),
166                N_("This program is distributed in the hope that it will be useful, "
167                   "but WITHOUT ANY WARRANTY; without even the implied warranty of "
168                   "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the "
169                   "GNU General Public License for more details."),
170                N_("You should have received a copy of the GNU General Public License "
171                   "along with this program; if not, write to the Free Software "
172                   "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA "),
173                NULL
174        };
175        char *license_i18n;
176
177        license_i18n = g_strconcat (_(license[0]), "\n\n", _(license[1]), "\n\n", _(license[2]), NULL); 
178
179        gtk_show_about_dialog (NULL,
180                               "version", VERSION,
181                               "copyright", "Copyright \xc2\xa9 2004-2005 James M. Cape.\n"
182                               "Copyright \xc2\xa9 2006 Thomas Thurman.\n"
183                               "Copyright \xc2\xa9 2008 Red Hat, Inc.",
184                               "comments", _("A menu to quickly switch between users."),
185                               "authors", authors,
186                               "license", license_i18n,
187                               "wrap-license", TRUE,
188                               "translator-credits", _("translator-credits"),
189                               "logo-icon-name", "stock_people",
190                               NULL);
191
192        g_free (license_i18n);
193}
194
195
196static void
197admin_cb (BonoboUIComponent *ui_container,
198          gpointer           data,
199          const char        *cname)
200{
201#ifdef USERS_ADMIN
202        char   **args;
203        gboolean res;
204        GError  *err;
205
206        err = NULL;
207        if (!g_shell_parse_argv (USERS_ADMIN, NULL, &args, &err)) {
208                g_critical ("Could not parse users and groups management command line `%s': %s",
209                            USERS_ADMIN, err->message);
210                return;
211        }
212
213        res = g_spawn_async (g_get_home_dir (),
214                             args,
215                             NULL,
216                             (G_SPAWN_STDOUT_TO_DEV_NULL |
217                              G_SPAWN_STDERR_TO_DEV_NULL |
218                              G_SPAWN_SEARCH_PATH),
219                             NULL,
220                             NULL,
221                             NULL,
222                             &err);
223        if (! res) {
224                g_critical ("Could not run `%s' to manage users and groups: %s",
225                            USERS_ADMIN, err->message);
226                g_error_free (err);
227        }
228        g_strfreev (args);
229#endif /* USERS_ADMIN */
230}
231
232static void
233set_menuitem_icon (BonoboUIComponent *component,
234                   const char        *item_path,
235                   GtkIconTheme      *theme,
236                   const char        *icon_name,
237                   gint               icon_size)
238{
239        GdkPixbuf *pixbuf;
240        int        width;
241        int        height;
242
243        pixbuf = gtk_icon_theme_load_icon (theme, icon_name, icon_size, 0, NULL);
244        if (pixbuf == NULL) {
245                return;
246        }
247
248        width = gdk_pixbuf_get_width (pixbuf);
249        height = gdk_pixbuf_get_height (pixbuf);
250        if (width > icon_size + 4 || height > icon_size + 4) {
251                GdkPixbuf *tmp;
252                if (height > width) {
253                        width *= (gdouble) icon_size / (gdouble) height;
254                        height = icon_size;
255                } else {
256                        height *= (gdouble) icon_size / (gdouble) width;
257                        width = icon_size;
258                }
259                tmp = gdk_pixbuf_scale_simple (pixbuf, width, height, GDK_INTERP_BILINEAR);
260                g_object_unref (pixbuf);
261                pixbuf = tmp;
262        }
263
264        bonobo_ui_util_set_pixbuf (component, item_path, pixbuf, NULL);
265        g_object_unref (pixbuf);
266}
267
268static void
269applet_style_set_cb (GtkWidget *widget,
270                     GtkStyle  *old_style,
271                     gpointer   data)
272{
273        BonoboUIComponent *component;
274        GdkScreen         *screen;
275        GtkIconTheme      *theme;
276        int                width;
277        int                height;
278        int                icon_size;
279
280        if (gtk_widget_has_screen (widget)) {
281                screen = gtk_widget_get_screen (widget);
282        } else {
283                screen = gdk_screen_get_default ();
284        }
285
286        if (gtk_icon_size_lookup_for_settings (gtk_settings_get_for_screen (screen),
287                                               GTK_ICON_SIZE_MENU, &width, &height)) {
288                icon_size = MAX (width, height);
289        } else {
290                icon_size = 16;
291        }
292
293        theme = gtk_icon_theme_get_for_screen (screen);
294        component = panel_applet_get_popup_component (PANEL_APPLET (widget));
295
296        set_menuitem_icon (component,
297                           "/commands/GdmAboutMe",
298                           theme,
299                           "user-info",
300                           icon_size);
301        set_menuitem_icon (component,
302                           "/commands/GdmUsersGroupsAdmin",
303                           theme,
304                           "stock_people",
305                           icon_size);
306}
307
308static void
309applet_change_background_cb (PanelApplet               *applet,
310                             PanelAppletBackgroundType  type,
311                             GdkColor                  *color,
312                             GdkPixmap                 *pixmap,
313                             GdmAppletData             *adata)
314{
315        GtkRcStyle *rc_style;
316        GtkStyle   *style;
317
318        gtk_widget_set_style (adata->menubar, NULL);
319        rc_style = gtk_rc_style_new ();
320        gtk_widget_modify_style (GTK_WIDGET (adata->menubar), rc_style);
321        g_object_unref (rc_style);
322
323        switch (type) {
324        case PANEL_NO_BACKGROUND:
325                break;
326        case PANEL_COLOR_BACKGROUND:
327                gtk_widget_modify_bg (adata->menubar, GTK_STATE_NORMAL, color);
328                break;
329        case PANEL_PIXMAP_BACKGROUND:
330                style = gtk_style_copy (adata->menubar->style);
331                if (style->bg_pixmap[GTK_STATE_NORMAL]) {
332                        g_object_unref (style->bg_pixmap[GTK_STATE_NORMAL]);
333                }
334
335                style->bg_pixmap[GTK_STATE_NORMAL] = g_object_ref (pixmap);
336                gtk_widget_set_style (adata->menubar, style);
337                g_object_unref (style);
338                break;
339        }
340}
341
342/*
343 * gnome-panel/applets/wncklet/window-menu.c:window_menu_key_press_event()
344 *
345 * Copyright (C) 2003 Sun Microsystems, Inc.
346 * Copyright (C) 2001 Free Software Foundation, Inc.
347 * Copyright (C) 2000 Helix Code, Inc.
348 */
349static gboolean
350applet_key_press_event_cb (GtkWidget     *widget,
351                           GdkEventKey   *event,
352                           GdmAppletData *adata)
353{
354        GtkMenuShell *menu_shell;
355
356        switch (event->keyval) {
357        case GDK_KP_Enter:
358        case GDK_ISO_Enter:
359        case GDK_3270_Enter:
360        case GDK_Return:
361        case GDK_space:
362        case GDK_KP_Space:
363                menu_shell = GTK_MENU_SHELL (adata->menubar);
364                /*
365                 * We need to call _gtk_menu_shell_activate() here as is done in
366                 * window_key_press_handler in gtkmenubar.c which pops up menu
367                 * when F10 is pressed.
368                 *
369                 * As that function is private its code is replicated here.
370                 */
371                if (!menu_shell->active) {
372                        gtk_grab_add (GTK_WIDGET (menu_shell));
373                        menu_shell->have_grab = TRUE;
374                        menu_shell->active = TRUE;
375                }
376
377                gtk_menu_shell_select_first (menu_shell, FALSE);
378                return TRUE;
379        default:
380                break;
381        }
382
383        return FALSE;
384}
385
386static void
387set_item_text_angle_and_alignment (GtkWidget *item,
388                                   double     text_angle,
389                                   float      xalign,
390                                   float      yalign)
391{
392        GtkWidget *label;
393
394        label = GTK_BIN (item)->child;
395
396        gtk_label_set_angle (GTK_LABEL (label), text_angle);
397
398        gtk_misc_set_alignment (GTK_MISC (label), xalign, yalign);
399}
400
401/*
402 * gnome-panel/applets/wncklet/window-menu.c:window_menu_size_allocate()
403 *
404 * Copyright (C) 2003 Sun Microsystems, Inc.
405 * Copyright (C) 2001 Free Software Foundation, Inc.
406 * Copyright (C) 2000 Helix Code, Inc.
407 */
408static void
409applet_size_allocate_cb (GtkWidget     *widget,
410                         GtkAllocation *allocation,
411                         GdmAppletData *adata)
412{
413        GList            *children;
414        GtkWidget        *top_item;
415        PanelAppletOrient orient;
416        gint              pixel_size;
417        gdouble           text_angle;
418        GtkPackDirection  pack_direction;
419        float             text_xalign;
420        float             text_yalign;
421
422        pack_direction = GTK_PACK_DIRECTION_LTR;
423        text_angle = 0.0;
424        text_xalign = 0.0;
425        text_yalign = 0.5;
426
427        children = gtk_container_get_children (GTK_CONTAINER (adata->menubar));
428        top_item = GTK_WIDGET (children->data);
429        g_list_free (children);
430
431        orient = panel_applet_get_orient (PANEL_APPLET (widget));
432
433        switch (orient) {
434        case PANEL_APPLET_ORIENT_UP:
435        case PANEL_APPLET_ORIENT_DOWN:
436                gtk_widget_set_size_request (top_item, -1, allocation->height);
437                pixel_size = allocation->height - top_item->style->ythickness * 2;
438                break;
439        case PANEL_APPLET_ORIENT_LEFT:
440                gtk_widget_set_size_request (top_item, allocation->width, -1);
441                pixel_size = allocation->width - top_item->style->xthickness * 2;
442                pack_direction = GTK_PACK_DIRECTION_TTB;
443                text_angle = 270.0;
444                text_xalign = 0.5;
445                text_yalign = 0.0;
446                break;
447        case PANEL_APPLET_ORIENT_RIGHT:
448                gtk_widget_set_size_request (top_item, allocation->width, -1);
449                pixel_size = allocation->width - top_item->style->xthickness * 2;
450                pack_direction = GTK_PACK_DIRECTION_BTT;
451                text_angle = 90.0;
452                text_xalign = 0.5;
453                text_yalign = 0.0;
454                break;
455        default:
456                g_assert_not_reached ();
457                break;
458        }
459
460        gtk_menu_bar_set_pack_direction (GTK_MENU_BAR (adata->menubar),
461                                         pack_direction);
462        gtk_menu_bar_set_child_pack_direction (GTK_MENU_BAR (adata->menubar),
463                                               pack_direction);
464
465        set_item_text_angle_and_alignment (adata->menuitem,
466                                           text_angle,
467                                           text_xalign,
468                                           text_yalign);
469
470        if (adata->panel_size != pixel_size) {
471                adata->panel_size = pixel_size;
472                reset_icon (adata);
473        }
474}
475
476
477static void
478gdm_applet_data_free (GdmAppletData *adata)
479{
480        gconf_client_notify_remove (adata->client, adata->client_notify_lockdown_id);
481
482        g_signal_handler_disconnect (adata->user, adata->user_notify_id);
483        g_signal_handler_disconnect (adata->user, adata->user_icon_changed_id);
484
485#ifdef BUILD_PRESENSE_STUFF
486        if (adata->presence_proxy != NULL) {
487                g_object_unref (adata->presence_proxy);
488        }
489#endif
490
491        if (adata->user != NULL) {
492                g_object_unref (adata->user);
493        }
494        g_object_unref (adata->client);
495        g_object_unref (adata->manager);
496
497        g_free (adata);
498}
499
500
501/*
502 * gnome-panel/applets/wncklet/window-menu.c:window_menu_on_expose()
503 *
504 * Copyright (C) 2003 Sun Microsystems, Inc.
505 * Copyright (C) 2001 Free Software Foundation, Inc.
506 * Copyright (C) 2000 Helix Code, Inc.
507 */
508static gboolean
509menubar_expose_event_cb (GtkWidget      *widget,
510                         GdkEventExpose *event,
511                         GdmAppletData  *adata)
512{
513        if (GTK_WIDGET_HAS_FOCUS (adata->applet))
514                gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget),
515                                 NULL, widget, "menu-applet", 0, 0, -1, -1);
516
517        return FALSE;
518}
519
520static void
521menu_style_set_cb (GtkWidget     *menu,
522                   GtkStyle      *old_style,
523                   GdmAppletData *adata)
524{
525        GtkSettings *settings;
526        int          width;
527        int          height;
528
529        adata->icon_size = gtk_icon_size_from_name ("panel-menu");
530
531        if (adata->icon_size == GTK_ICON_SIZE_INVALID) {
532                adata->icon_size = gtk_icon_size_register ("panel-menu", 24, 24);
533        }
534
535        if (gtk_widget_has_screen (menu)) {
536                settings = gtk_settings_get_for_screen (gtk_widget_get_screen (menu));
537        } else {
538                settings = gtk_settings_get_default ();
539        }
540
541        if (!gtk_icon_size_lookup_for_settings (settings, adata->icon_size,
542                                                &width, &height)) {
543                adata->pixel_size = -1;
544        } else {
545                adata->pixel_size = MAX (width, height);
546        }
547}
548
549static void
550menuitem_style_set_cb (GtkWidget     *menuitem,
551                       GtkStyle      *old_style,
552                       GdmAppletData *adata)
553{
554        GtkWidget *image;
555
556        if (GDM_IS_ENTRY_MENU_ITEM (menuitem)) {
557        } else {
558                const char *icon_name;
559
560                if (menuitem == adata->login_screen_item) {
561                        icon_name = "system-users";
562                } else if (menuitem == adata->lock_screen_item) {
563                        icon_name = "system-lock-screen";
564                } else if (menuitem == adata->quit_session_item) {
565                        icon_name = "system-log-out";
566                } else if (menuitem == adata->account_item) {
567                        icon_name = "user-info";
568                } else if (menuitem == adata->control_panel_item) {
569                        icon_name = "preferences-desktop";
570                } else {
571                        icon_name = GTK_STOCK_MISSING_IMAGE;
572                }
573
574                image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (menuitem));
575                gtk_image_set_pixel_size (GTK_IMAGE (image), adata->pixel_size);
576                gtk_image_set_from_icon_name (GTK_IMAGE (image), icon_name,
577                                              adata->icon_size);
578        }
579}
580
581static void
582user_notify_display_name_cb (GObject       *object,
583                             GParamSpec    *pspec,
584                             GdmAppletData *adata)
585{
586        update_label (adata);
587}
588
589/* Called every time the menu is displayed (and also for some reason
590 * immediately it's created, which does no harm). All we have to do
591 * here is kick off a request to GDM to let us know which users are
592 * logged in, so we can display check marks next to their names.
593 */
594static gboolean
595menu_expose_cb (GtkWidget *menu,
596                gpointer   data)
597{
598
599        return FALSE;
600}
601
602static void
603maybe_lock_screen (GdmAppletData *adata)
604{
605        char      *args[3];
606        GError    *err;
607        GdkScreen *screen;
608        gboolean   use_gscreensaver = TRUE;
609        gboolean   res;
610
611        g_debug ("Attempting to lock screen");
612
613        args[0] = g_find_program_in_path ("gnome-screensaver-command");
614        if (args[0] == NULL) {
615                args[0] = g_find_program_in_path ("xscreensaver-command");
616                use_gscreensaver = FALSE;
617        }
618
619        if (args[0] == NULL) {
620                return;
621        }
622
623        if (use_gscreensaver) {
624                args[1] = "--lock";
625        } else {
626                args[1] = "-lock";
627        }
628        args[2] = NULL;
629
630        if (gtk_widget_has_screen (GTK_WIDGET (adata->applet))) {
631                screen = gtk_widget_get_screen (GTK_WIDGET (adata->applet));
632        } else {
633                screen = gdk_screen_get_default ();
634        }
635
636        err = NULL;
637        res = gdk_spawn_on_screen (screen,
638                                   g_get_home_dir (),
639                                   args,
640                                   NULL,
641                                   0,
642                                   NULL,
643                                   NULL,
644                                   NULL,
645                                   &err);
646        if (! res) {
647                g_warning (_("Can't lock screen: %s"), err->message);
648                g_error_free (err);
649        }
650
651        if (use_gscreensaver) {
652                args[1] = "--throttle";
653        } else {
654                args[1] = "-throttle";
655        }
656
657        err = NULL;
658        res = gdk_spawn_on_screen (screen,
659                                   g_get_home_dir (),
660                                   args,
661                                   NULL,
662                                   (G_SPAWN_STDERR_TO_DEV_NULL
663                                   | G_SPAWN_STDOUT_TO_DEV_NULL),
664                                   NULL,
665                                   NULL,
666                                   NULL,
667                                   &err);
668        if (! res) {
669                g_warning (_("Can't temporarily set screensaver to blank screen: %s"),
670                           err->message);
671                g_error_free (err);
672        }
673
674        g_free (args[0]);
675}
676
677static void
678do_switch (GdmAppletData *adata,
679           GdmUser       *user)
680{
681        guint num_sessions;
682
683        g_debug ("Do user switch");
684
685        if (user == NULL) {
686                gdm_user_manager_goto_login_session (adata->manager);
687                goto out;
688        }
689
690        num_sessions = gdm_user_get_num_sessions (user);
691        if (num_sessions > 0) {
692                gdm_user_manager_activate_user_session (adata->manager, user);
693        } else {
694                gdm_user_manager_goto_login_session (adata->manager);
695        }
696 out:
697        maybe_lock_screen (adata);
698}
699
700static void
701update_switch_user (GdmAppletData *adata)
702{
703        GSList *users;
704
705        users = gdm_user_manager_list_users (adata->manager);
706        adata->has_other_users = FALSE;
707        if (users != NULL) {
708                adata->has_other_users = (g_slist_length (users) > 1);
709        }
710        g_slist_free (users);
711
712        if (adata->has_other_users) {
713                gtk_widget_show (adata->login_screen_item);
714        } else {
715
716                gtk_widget_hide (adata->login_screen_item);
717        }
718}
719
720static void
721on_manager_user_added (GdmUserManager *manager,
722                       GdmUser        *user,
723                       GdmAppletData  *adata)
724{
725        update_switch_user (adata);
726}
727
728static void
729on_manager_user_removed (GdmUserManager *manager,
730                         GdmUser        *user,
731                         GdmAppletData  *adata)
732{
733        update_switch_user (adata);
734}
735
736static void
737on_manager_users_loaded (GdmUserManager *manager,
738                         GdmAppletData  *adata)
739{
740        update_switch_user (adata);
741}
742
743#ifdef BUILD_PRESENSE_STUFF
744static void
745on_user_item_activate (GtkMenuItem   *item,
746                       GdmAppletData *adata)
747{
748        g_signal_stop_emission_by_name (item, "activate");
749}
750#endif
751
752static void
753on_control_panel_activate (GtkMenuItem   *item,
754                           GdmAppletData *adata)
755{
756        char      *args[2];
757        GError    *error;
758        GdkScreen *screen;
759        gboolean   res;
760
761        args[0] = g_find_program_in_path ("gnome-control-center");
762        if (args[0] == NULL) {
763                return;
764        }
765        args[1] = NULL;
766
767        if (gtk_widget_has_screen (GTK_WIDGET (adata->applet))) {
768                screen = gtk_widget_get_screen (GTK_WIDGET (adata->applet));
769        } else {
770                screen = gdk_screen_get_default ();
771        }
772
773        error = NULL;
774        res = gdk_spawn_on_screen (screen,
775                                   g_get_home_dir (),
776                                   args,
777                                   NULL,
778                                   0,
779                                   NULL,
780                                   NULL,
781                                   NULL,
782                                   &error);
783        if (! res) {
784                g_warning (_("Can't lock screen: %s"), error->message);
785                g_error_free (error);
786        }
787
788        g_free (args[0]);
789}
790
791static void
792on_account_activate (GtkMenuItem   *item,
793                     GdmAppletData *adata)
794{
795        char      *args[2];
796        GError    *error;
797        GdkScreen *screen;
798        gboolean   res;
799
800        args[0] = g_find_program_in_path ("gnome-about-me");
801        if (args[0] == NULL) {
802                return;
803        }
804        args[1] = NULL;
805
806        if (gtk_widget_has_screen (GTK_WIDGET (adata->applet))) {
807                screen = gtk_widget_get_screen (GTK_WIDGET (adata->applet));
808        } else {
809                screen = gdk_screen_get_default ();
810        }
811
812        error = NULL;
813        res = gdk_spawn_on_screen (screen,
814                                   g_get_home_dir (),
815                                   args,
816                                   NULL,
817                                   0,
818                                   NULL,
819                                   NULL,
820                                   NULL,
821                                   &error);
822        if (! res) {
823                g_warning (_("Can't lock screen: %s"), error->message);
824                g_error_free (error);
825        }
826
827        g_free (args[0]);
828}
829
830static void
831on_lock_screen_activate (GtkMenuItem   *item,
832                         GdmAppletData *adata)
833{
834        maybe_lock_screen (adata);
835}
836
837static void
838on_login_screen_activate (GtkMenuItem   *item,
839                          GdmAppletData *adata)
840{
841        GdmUser *user;
842
843        user = NULL;
844
845        do_switch (adata, user);
846}
847
848static void
849on_quit_session_activate (GtkMenuItem   *item,
850                          GdmAppletData *adata)
851{
852        char      *args[3];
853        GError    *error;
854        GdkScreen *screen;
855        gboolean   res;
856
857        args[0] = g_find_program_in_path ("gnome-session-save");
858        if (args[0] == NULL) {
859                return;
860        }
861
862        args[1] = "--logout-dialog";
863        args[2] = NULL;
864
865        if (gtk_widget_has_screen (GTK_WIDGET (adata->applet))) {
866                screen = gtk_widget_get_screen (GTK_WIDGET (adata->applet));
867        } else {
868                screen = gdk_screen_get_default ();
869        }
870
871        error = NULL;
872        res = gdk_spawn_on_screen (screen,
873                                   g_get_home_dir (),
874                                   args,
875                                   NULL,
876                                   0,
877                                   NULL,
878                                   NULL,
879                                   NULL,
880                                   &error);
881        if (! res) {
882                g_warning (_("Can't logout: %s"), error->message);
883                g_error_free (error);
884        }
885
886        g_free (args[0]);
887}
888
889#ifdef BUILD_PRESENSE_STUFF
890static gboolean
891on_menu_key_press_event (GtkWidget     *widget,
892                         GdkEventKey   *event,
893                         GdmAppletData *adata)
894{
895        GtkWidget *entry;
896
897        entry = gdm_entry_menu_item_get_entry (GDM_ENTRY_MENU_ITEM (adata->user_item));
898
899        if (GTK_WIDGET_HAS_FOCUS (entry)) {
900                gtk_widget_event (entry, (GdkEvent *)event);
901                return TRUE;
902        } else {
903                return FALSE;
904        }
905}
906
907static void
908save_status (GdmAppletData *adata,
909             guint          status)
910{
911        if (adata->current_status != status) {
912                GError *error;
913
914                adata->current_status = status;
915
916                g_debug ("Saving status: %u", status);
917                error = NULL;
918                dbus_g_proxy_call (adata->presence_proxy,
919                                   "SetStatus",
920                                   &error,
921                                   G_TYPE_UINT, status,
922                                   G_TYPE_INVALID,
923                                   G_TYPE_INVALID);
924
925                if (error != NULL) {
926                        g_warning ("Couldn't save presence status: %s", error->message);
927                        g_error_free (error);
928                }
929        }
930}
931
932static void
933on_status_available_activate (GtkWidget     *widget,
934                              GdmAppletData *adata)
935{
936
937        if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget))) {
938                save_status (adata, GSM_PRESENCE_STATUS_AVAILABLE);
939        }
940}
941
942static void
943on_status_busy_activate (GtkWidget     *widget,
944                         GdmAppletData *adata)
945{
946         if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget))) {
947                 save_status (adata, GSM_PRESENCE_STATUS_BUSY);
948         }
949}
950
951static void
952on_status_invisible_activate (GtkWidget     *widget,
953                              GdmAppletData *adata)
954{
955         if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget))) {
956                 save_status (adata, GSM_PRESENCE_STATUS_INVISIBLE);
957         }
958}
959
960static struct {
961        char      *icon_name;
962        char      *display_name;
963        void      *menu_callback;
964        GtkWidget *widget;
965} statuses[] = {
966        { "user-online", N_("Available"), on_status_available_activate, NULL },
967        { "user-invisible", N_("Invisible"), on_status_invisible_activate, NULL },
968        { "user-busy", N_("Busy"), on_status_busy_activate, NULL },
969        { "user-away", N_("Away"), NULL, NULL },
970};
971#endif
972
973static void
974update_label (GdmAppletData *adata)
975{
976        GtkWidget *label;
977        char      *markup;
978
979        label = gtk_bin_get_child (GTK_BIN (adata->menuitem));
980
981#ifdef BUILD_PRESENSE_STUFF
982        markup = g_strdup_printf ("<b>%s</b> <small>(%s)</small>",
983                                  gdm_user_get_display_name (GDM_USER (adata->user)),
984                                  _(statuses[adata->current_status].display_name));
985#else
986        markup = g_strdup_printf ("<b>%s</b>",
987                                  gdm_user_get_display_name (GDM_USER (adata->user)));
988#endif
989        gtk_label_set_markup (GTK_LABEL (label), markup);
990        g_free (markup);
991}
992
993#ifdef BUILD_PRESENSE_STUFF
994static void
995save_status_text (GdmAppletData *adata)
996{
997        GtkWidget     *entry;
998        GtkTextBuffer *buffer;
999        char          *escaped_text;
1000        char          *text;
1001        GtkTextIter    start, end;
1002
1003        entry = gdm_entry_menu_item_get_entry (GDM_ENTRY_MENU_ITEM (adata->user_item));
1004        buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (entry));
1005        gtk_text_buffer_get_bounds (buffer, &start, &end);
1006        text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
1007        escaped_text = g_markup_escape_text (text, -1);
1008
1009        if (escaped_text != NULL) {
1010                GError *error;
1011
1012                error = NULL;
1013                dbus_g_proxy_call (adata->presence_proxy,
1014                                   "SetStatusText",
1015                                   &error,
1016                                   G_TYPE_STRING, escaped_text,
1017                                   G_TYPE_INVALID,
1018                                   G_TYPE_INVALID);
1019
1020                if (error != NULL) {
1021                        g_warning ("Couldn't set presence status text: %s", error->message);
1022                        g_error_free (error);
1023                }
1024        }
1025
1026        g_free (text);
1027        g_free (escaped_text);
1028}
1029
1030static void
1031on_user_item_deselect (GtkWidget     *item,
1032                       GdmAppletData *adata)
1033{
1034        save_status_text (adata);
1035}
1036#endif
1037
1038static void
1039create_sub_menu (GdmAppletData *adata)
1040{
1041        GtkWidget *item;
1042#ifdef BUILD_PRESENSE_STUFF
1043        int        i;
1044        GSList    *radio_group;
1045#endif
1046
1047        adata->menu = gtk_menu_new ();
1048#ifdef BUILD_PRESENSE_STUFF
1049        g_signal_connect (adata->menu,
1050                          "key-press-event",
1051                          G_CALLBACK (on_menu_key_press_event),
1052                          adata);
1053#endif
1054        gtk_menu_item_set_submenu (GTK_MENU_ITEM (adata->menuitem), adata->menu);
1055        g_signal_connect (adata->menu, "style-set",
1056                          G_CALLBACK (menu_style_set_cb), adata);
1057        g_signal_connect (adata->menu, "show",
1058                          G_CALLBACK (menu_expose_cb), adata);
1059        gtk_widget_show (adata->menu);
1060
1061        g_signal_connect (adata->manager,
1062                          "users-loaded",
1063                          G_CALLBACK (on_manager_users_loaded),
1064                          adata);
1065        g_signal_connect (adata->manager,
1066                          "user-added",
1067                          G_CALLBACK (on_manager_user_added),
1068                          adata);
1069        g_signal_connect (adata->manager,
1070                          "user-removed",
1071                          G_CALLBACK (on_manager_user_added),
1072                          adata);
1073
1074#ifdef BUILD_PRESENSE_STUFF
1075        adata->user_item = gdm_entry_menu_item_new ();
1076        gtk_menu_shell_append (GTK_MENU_SHELL (adata->menu),
1077                               adata->user_item);
1078        gtk_widget_show (adata->user_item);
1079        g_signal_connect (adata->user_item, "activate",
1080                          G_CALLBACK (on_user_item_activate), adata);
1081        g_signal_connect (adata->user_item,
1082                          "deselect",
1083                          G_CALLBACK (on_user_item_deselect),
1084                          adata);
1085
1086        item = gtk_separator_menu_item_new ();
1087        gtk_menu_shell_append (GTK_MENU_SHELL (adata->menu), item);
1088        gtk_widget_show (item);
1089
1090        radio_group = NULL;
1091        for (i = 0; i < G_N_ELEMENTS (statuses); i++) {
1092                GtkWidget *hbox;
1093                GtkWidget *label;
1094                GtkWidget *image;
1095                GtkWidget *item;
1096
1097                if (statuses[i].menu_callback == NULL) {
1098                        continue;
1099                }
1100
1101                item = gtk_radio_menu_item_new (radio_group);
1102                radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item));
1103                hbox = gtk_hbox_new (FALSE, 3);
1104                label = gtk_label_new (_(statuses[i].display_name));
1105                gtk_label_set_justify (GTK_LABEL(label), GTK_JUSTIFY_LEFT);
1106                gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1107                gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
1108                gtk_widget_show (label);
1109                image = gtk_image_new_from_icon_name (statuses[i].icon_name, GTK_ICON_SIZE_MENU);
1110                gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, TRUE, 0);
1111                gtk_widget_show (image);
1112                gtk_widget_show (hbox);
1113                gtk_container_add (GTK_CONTAINER (item), hbox);
1114
1115                gtk_menu_shell_append (GTK_MENU_SHELL (adata->menu),
1116                                       item);
1117                g_signal_connect (item, "activate",
1118                                  G_CALLBACK (statuses[i].menu_callback), adata);
1119                gtk_widget_show (item);
1120
1121                statuses[i].widget = item;
1122        }
1123
1124        item = gtk_separator_menu_item_new ();
1125        gtk_menu_shell_append (GTK_MENU_SHELL (adata->menu), item);
1126        gtk_widget_show (item);
1127#endif
1128
1129        adata->account_item = gtk_image_menu_item_new_with_label (_("Account Information..."));
1130        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (adata->account_item),
1131                                       gtk_image_new ());
1132        gtk_menu_shell_append (GTK_MENU_SHELL (adata->menu),
1133                               adata->account_item);
1134        g_signal_connect (adata->account_item, "style-set",
1135                          G_CALLBACK (menuitem_style_set_cb), adata);
1136        g_signal_connect (adata->account_item, "activate",
1137                          G_CALLBACK (on_account_activate), adata);
1138        gtk_widget_show (adata->account_item);
1139
1140
1141        adata->control_panel_item = gtk_image_menu_item_new_with_label (_("System Preferences..."));
1142        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (adata->control_panel_item),
1143                                       gtk_image_new ());
1144        gtk_menu_shell_append (GTK_MENU_SHELL (adata->menu),
1145                               adata->control_panel_item);
1146        g_signal_connect (adata->control_panel_item, "style-set",
1147                          G_CALLBACK (menuitem_style_set_cb), adata);
1148        g_signal_connect (adata->control_panel_item, "activate",
1149                          G_CALLBACK (on_control_panel_activate), adata);
1150        gtk_widget_show (adata->control_panel_item);
1151
1152
1153        item = gtk_separator_menu_item_new ();
1154        gtk_menu_shell_append (GTK_MENU_SHELL (adata->menu), item);
1155        gtk_widget_show (item);
1156
1157        adata->lock_screen_item = gtk_image_menu_item_new_with_label (_("Lock Screen"));
1158        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (adata->lock_screen_item),
1159                                       gtk_image_new ());
1160        gtk_menu_shell_append (GTK_MENU_SHELL (adata->menu),
1161                               adata->lock_screen_item);
1162        g_signal_connect (adata->lock_screen_item, "style-set",
1163                          G_CALLBACK (menuitem_style_set_cb), adata);
1164        g_signal_connect (adata->lock_screen_item, "activate",
1165                          G_CALLBACK (on_lock_screen_activate), adata);
1166        gtk_widget_show (adata->lock_screen_item);
1167
1168        adata->login_screen_item = gtk_image_menu_item_new_with_label (_("Switch User"));
1169        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (adata->login_screen_item),
1170                                       gtk_image_new ());
1171        gtk_menu_shell_append (GTK_MENU_SHELL (adata->menu),
1172                               adata->login_screen_item);
1173        g_signal_connect (adata->login_screen_item, "style-set",
1174                          G_CALLBACK (menuitem_style_set_cb), adata);
1175        g_signal_connect (adata->login_screen_item, "activate",
1176                          G_CALLBACK (on_login_screen_activate), adata);
1177        /* Only show switch user if there are other users */
1178
1179        adata->quit_session_item = gtk_image_menu_item_new_with_label (_("Quit..."));
1180        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (adata->quit_session_item),
1181                                       gtk_image_new ());
1182        gtk_menu_shell_append (GTK_MENU_SHELL (adata->menu),
1183                               adata->quit_session_item);
1184        g_signal_connect (adata->quit_session_item, "style-set",
1185                          G_CALLBACK (menuitem_style_set_cb), adata);
1186        g_signal_connect (adata->quit_session_item, "activate",
1187                          G_CALLBACK (on_quit_session_activate), adata);
1188        gtk_widget_show (adata->quit_session_item);
1189}
1190
1191static void
1192destroy_sub_menu (GdmAppletData *adata)
1193{
1194        gtk_menu_item_set_submenu (GTK_MENU_ITEM (adata->menuitem), NULL);
1195
1196        g_signal_handlers_disconnect_by_func (adata->manager,
1197                                              G_CALLBACK (on_manager_user_added),
1198                                              adata);
1199        g_signal_handlers_disconnect_by_func (adata->manager,
1200                                              G_CALLBACK (on_manager_user_removed),
1201                                              adata);
1202}
1203
1204static void
1205set_menu_visibility (GdmAppletData *adata,
1206                     gboolean       visible)
1207{
1208
1209        if (visible) {
1210                create_sub_menu (adata);
1211        } else {
1212                destroy_sub_menu (adata);
1213        }
1214}
1215
1216static void
1217client_notify_lockdown_func (GConfClient   *client,
1218                             guint          cnxn_id,
1219                             GConfEntry    *entry,
1220                             GdmAppletData *adata)
1221{
1222        GConfValue *value;
1223        const char *key;
1224
1225        value = gconf_entry_get_value (entry);
1226        key = gconf_entry_get_key (entry);
1227
1228        if (value == NULL || key == NULL) {
1229                return;
1230        }
1231
1232        if (strcmp (key, LOCKDOWN_KEY) == 0) {
1233                if (gconf_value_get_bool (value)) {
1234                        set_menu_visibility (adata, FALSE);
1235                } else {
1236                        set_menu_visibility (adata, TRUE);
1237                }
1238        }
1239}
1240
1241static void
1242reset_icon (GdmAppletData *adata)
1243{
1244        GdkPixbuf *pixbuf;
1245        GtkWidget *image;
1246
1247        if (adata->user == NULL || !gtk_widget_has_screen (GTK_WIDGET (adata->menuitem))) {
1248                return;
1249        }
1250
1251#ifdef BUILD_PRESENSE_STUFF
1252        if (adata->user_item != NULL) {
1253                image = gdm_entry_menu_item_get_image (GDM_ENTRY_MENU_ITEM (adata->user_item));
1254                pixbuf = gdm_user_render_icon (adata->user, adata->panel_size * 3);
1255                if (pixbuf == NULL) {
1256                        return;
1257                }
1258
1259                gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
1260                g_object_unref (pixbuf);
1261        }
1262#else
1263        pixbuf = gdm_user_render_icon (adata->user, adata->panel_size);
1264
1265        if (pixbuf == NULL) {
1266                return;
1267        }
1268
1269        image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (adata->menuitem));
1270        gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
1271        g_object_unref (pixbuf);
1272#endif
1273}
1274
1275static void
1276on_user_icon_changed (GdmUser         *user,
1277                      GdmAppletData   *adata)
1278{
1279        g_debug ("User icon changed");
1280        reset_icon (adata);
1281}
1282
1283static void
1284setup_current_user (GdmAppletData *adata)
1285{
1286        const char *name;
1287        GtkWidget  *label;
1288
1289        adata->user = gdm_user_manager_get_user_by_uid (adata->manager, getuid ());
1290        if (adata->user != NULL) {
1291                g_object_ref (adata->user);
1292                name = gdm_user_get_real_name (adata->user);
1293        } else {
1294                name = _("Unknown");
1295        }
1296
1297        adata->menuitem = gtk_image_menu_item_new_with_label (name);
1298#ifndef BUILD_PRESENSE_STUFF
1299        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (adata->menuitem),
1300                                       gtk_image_new ());
1301#endif
1302        label = GTK_BIN (adata->menuitem)->child;
1303        gtk_menu_shell_append (GTK_MENU_SHELL (adata->menubar), adata->menuitem);
1304        gtk_widget_show (adata->menuitem);
1305
1306        update_label (adata);
1307
1308        if (adata->user != NULL) {
1309                reset_icon (adata);
1310
1311                adata->user_icon_changed_id =
1312                        g_signal_connect (adata->user,
1313                                          "icon-changed",
1314                                          G_CALLBACK (on_user_icon_changed),
1315                                          adata);
1316                adata->user_notify_id =
1317                        g_signal_connect (adata->user,
1318                                         "notify::display-name",
1319                                         G_CALLBACK (user_notify_display_name_cb),
1320                                         adata);
1321        }
1322}
1323
1324#ifdef BUILD_PRESENSE_STUFF
1325static void
1326set_status (GdmAppletData *adata,
1327            guint status)
1328{
1329        int i;
1330
1331        g_debug ("Setting current status: %u", status);
1332        adata->current_status = status;
1333        for (i = 0; i < G_N_ELEMENTS (statuses); i++) {
1334                if (statuses[i].widget == NULL) {
1335                        continue;
1336                }
1337                if (i == status) {
1338                        gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (statuses[i].widget),
1339                                                        TRUE);
1340                }
1341        }
1342
1343        update_label (adata);
1344}
1345
1346static void
1347on_presence_status_changed (DBusGProxy    *presence_proxy,
1348                            guint          status,
1349                            GdmAppletData *adata)
1350{
1351        g_debug ("Status changed: %u", status);
1352
1353        set_status (adata, status);
1354}
1355
1356static void
1357set_status_text (GdmAppletData *adata,
1358                 const char    *status_text)
1359{
1360        GtkWidget     *entry;
1361        GtkTextBuffer *buffer;
1362
1363        g_debug ("Status text changed: %s", status_text);
1364
1365        entry = gdm_entry_menu_item_get_entry (GDM_ENTRY_MENU_ITEM (adata->user_item));
1366        buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (entry));
1367        gtk_text_buffer_set_text (buffer, status_text, -1);
1368}
1369
1370static void
1371on_presence_status_text_changed (DBusGProxy    *presence_proxy,
1372                                 const char    *status_text,
1373                                 GdmAppletData *adata)
1374{
1375        set_status_text (adata, status_text);
1376}
1377#endif
1378
1379static gboolean
1380fill_applet (PanelApplet *applet)
1381{
1382        static const BonoboUIVerb menu_verbs[] = {
1383                BONOBO_UI_VERB ("GdmAboutMe", about_me_cb),
1384                BONOBO_UI_VERB ("GdmUsersGroupsAdmin", admin_cb),
1385                BONOBO_UI_VERB ("GdmAbout", about_cb),
1386                BONOBO_UI_VERB_END
1387        };
1388        static gboolean    first_time = FALSE;
1389        char              *tmp;
1390        BonoboUIComponent *popup_component;
1391        GdmAppletData     *adata;
1392        GError            *error;
1393        DBusGConnection   *bus;
1394
1395        if (!first_time) {
1396                first_time = TRUE;
1397
1398                /* Do this here so it's only done once. */
1399                gtk_rc_parse_string ("style \"gdm-user-switch-menubar-style\"\n"
1400                                     "{\n"
1401                                     "GtkMenuBar::shadow-type = none\n"
1402                                     "GtkMenuBar::internal-padding = 0\n"
1403                                     "}\n"
1404                                     "style \"gdm-user-switch-applet-style\"\n"
1405                                     "{\n"
1406                                     "GtkWidget::focus-line-width = 0\n"
1407                                     "GtkWidget::focus-padding = 0\n"
1408                                     "}\n"
1409                                     "widget \"*.gdm-user-switch-menubar\" style \"gdm-user-switch-menubar-style\"\n"
1410                                     "widget \"*.gdm-user-switch-applet\" style \"gdm-user-switch-applet-style\"\n");
1411                gtk_window_set_default_icon_name ("stock_people");
1412                g_set_application_name (_("User Switch Applet"));
1413        }
1414
1415        adata = g_new0 (GdmAppletData, 1);
1416        adata->applet = applet;
1417        adata->panel_size = 24;
1418
1419        adata->client = gconf_client_get_default ();
1420
1421        gtk_widget_set_tooltip_text (GTK_WIDGET (applet), _("Change account settings and status"));
1422        gtk_container_set_border_width (GTK_CONTAINER (applet), 0);
1423        gtk_widget_set_name (GTK_WIDGET (applet), "gdm-user-switch-applet");
1424        panel_applet_set_flags (applet, PANEL_APPLET_EXPAND_MINOR);
1425        panel_applet_setup_menu_from_file (applet, NULL,
1426                                           DATADIR "/gnome-2.0/ui/GNOME_FastUserSwitchApplet.xml",
1427                                           NULL, menu_verbs, adata);
1428
1429        popup_component = panel_applet_get_popup_component (applet);
1430
1431        /* Hide the admin context menu items if locked down or no cmd-line */
1432        if (gconf_client_get_bool (adata->client,
1433                                   "/desktop/gnome/lockdown/inhibit_command_line",
1434                                   NULL) ||
1435            panel_applet_get_locked_down (applet)) {
1436                bonobo_ui_component_set_prop (popup_component,
1437                                              "/popups/button3/GdmSeparator",
1438                                              "hidden", "1", NULL);
1439                bonobo_ui_component_set_prop (popup_component,
1440                                              "/commands/GdmUsersGroupsAdmin",
1441                                              "hidden", "1", NULL);
1442        } else {
1443#ifndef USERS_ADMIN
1444#  ifdef GDM_SETUP
1445                bonobo_ui_component_set_prop (popup_component,
1446                                              "/popups/button3/GdmSeparator",
1447                                              "hidden", "1",
1448                                              NULL);
1449#  endif /* !GDM_SETUP */
1450                bonobo_ui_component_set_prop (popup_component,
1451                                              "/commands/GdmUsersGroupsAdmin",
1452                                              "hidden", "1",
1453                                              NULL);
1454#endif /* !USERS_ADMIN */
1455        }
1456
1457        /* Hide the gdmphotosetup item if it can't be found in the path. */
1458        tmp = g_find_program_in_path ("gnome-about-me");
1459        if (!tmp) {
1460                bonobo_ui_component_set_prop (popup_component,
1461                                              "/commands/GdmAboutMe",
1462                                              "hidden", "1",
1463                                              NULL);
1464        } else {
1465                g_free (tmp);
1466        }
1467
1468        g_signal_connect (adata->applet,
1469                          "style-set",
1470                          G_CALLBACK (applet_style_set_cb), adata);
1471        g_signal_connect (applet,
1472                          "change-background",
1473                          G_CALLBACK (applet_change_background_cb), adata);
1474        g_signal_connect (applet,
1475                          "size-allocate",
1476                          G_CALLBACK (applet_size_allocate_cb), adata);
1477        g_signal_connect (applet,
1478                          "key-press-event",
1479                          G_CALLBACK (applet_key_press_event_cb), adata);
1480        g_signal_connect_after (applet,
1481                                "focus-in-event",
1482                                G_CALLBACK (gtk_widget_queue_draw), NULL);
1483        g_signal_connect_after (applet,
1484                                "focus-out-event",
1485                                G_CALLBACK (gtk_widget_queue_draw), NULL);
1486        g_object_set_data_full (G_OBJECT (applet),
1487                                "gdm-applet-data",
1488                                adata,
1489                                (GDestroyNotify) gdm_applet_data_free);
1490
1491        adata->menubar = gtk_menu_bar_new ();
1492        gtk_widget_set_name (adata->menubar, "gdm-user-switch-menubar");
1493        GTK_WIDGET_SET_FLAGS (adata->menubar,
1494                              GTK_WIDGET_FLAGS (adata->menubar) | GTK_CAN_FOCUS);
1495        g_signal_connect (adata->menubar, "button-press-event",
1496                          G_CALLBACK (menubar_button_press_event_cb), adata);
1497        g_signal_connect_after (adata->menubar, "expose-event",
1498                                G_CALLBACK (menubar_expose_event_cb), adata);
1499        gtk_container_add (GTK_CONTAINER (applet), adata->menubar);
1500        gtk_widget_show (adata->menubar);
1501
1502        adata->manager = gdm_user_manager_ref_default ();
1503        setup_current_user (adata);
1504
1505        adata->client_notify_lockdown_id = gconf_client_notify_add (adata->client,
1506                                                                    LOCKDOWN_KEY,
1507                                                                    (GConfClientNotifyFunc)client_notify_lockdown_func,
1508                                                                    adata,
1509                                                                    NULL,
1510                                                                    NULL);
1511
1512        if (gconf_client_get_bool (adata->client, LOCKDOWN_KEY, NULL)) {
1513                set_menu_visibility (adata, FALSE);
1514        } else {
1515                set_menu_visibility (adata, TRUE);
1516        }
1517
1518        error = NULL;
1519        bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
1520        if (bus == NULL) {
1521                g_warning ("Unable to get session bus: %s", error->message);
1522                g_error_free (error);
1523                goto done;
1524        }
1525
1526#ifdef BUILD_PRESENSE_STUFF
1527        adata->presence_proxy = dbus_g_proxy_new_for_name (bus,
1528                                                          "org.gnome.SessionManager",
1529                                                          "/org/gnome/SessionManager/Presence",
1530                                                          "org.gnome.SessionManager.Presence");
1531        if (adata->presence_proxy != NULL) {
1532                DBusGProxy *proxy;
1533
1534                dbus_g_proxy_add_signal (adata->presence_proxy,
1535                                         "StatusChanged",
1536                                         G_TYPE_UINT,
1537                                         G_TYPE_INVALID);
1538                dbus_g_proxy_connect_signal (adata->presence_proxy,
1539                                             "StatusChanged",
1540                                             G_CALLBACK (on_presence_status_changed),
1541                                             adata,
1542                                             NULL);
1543                dbus_g_proxy_add_signal (adata->presence_proxy,
1544                                         "StatusTextChanged",
1545                                         G_TYPE_STRING,
1546                                         G_TYPE_INVALID);
1547                dbus_g_proxy_connect_signal (adata->presence_proxy,
1548                                             "StatusTextChanged",
1549                                             G_CALLBACK (on_presence_status_text_changed),
1550                                             adata,
1551                                             NULL);
1552
1553
1554                proxy = dbus_g_proxy_new_from_proxy (adata->presence_proxy,
1555                                                     "org.freedesktop.DBus.Properties",
1556                                                     "/org/gnome/SessionManager/Presence");
1557                if (proxy != NULL) {
1558                        guint       status;
1559                        const char *status_text;
1560                        GValue      value = { 0, };
1561
1562                        status = 0;
1563                        status_text = NULL;
1564
1565                        error = NULL;
1566                        dbus_g_proxy_call (proxy,
1567                                           "Get",
1568                                           &error,
1569                                           G_TYPE_STRING, "org.gnome.SessionManager.Presence",
1570                                           G_TYPE_STRING, "status",
1571                                           G_TYPE_INVALID,
1572                                           G_TYPE_VALUE, &value,
1573                                           G_TYPE_INVALID);
1574
1575                        if (error != NULL) {
1576                                g_warning ("Couldn't get presence status: %s", error->message);
1577                                g_error_free (error);
1578                        } else {
1579                                status = g_value_get_uint (&value);
1580                        }
1581
1582                        g_value_unset (&value);
1583
1584                        error = NULL;
1585                        dbus_g_proxy_call (proxy,
1586                                           "Get",
1587                                           &error,
1588                                           G_TYPE_STRING, "org.gnome.SessionManager.Presence",
1589                                           G_TYPE_STRING, "status-text",
1590                                           G_TYPE_INVALID,
1591                                           G_TYPE_VALUE, &value,
1592                                           G_TYPE_INVALID);
1593
1594                        if (error != NULL) {
1595                                g_warning ("Couldn't get presence status text: %s", error->message);
1596                                g_error_free (error);
1597                        } else {
1598                                status_text = g_value_get_string (&value);
1599                        }
1600
1601                        set_status (adata, status);
1602                        set_status_text (adata, status_text);
1603                }
1604        } else {
1605                g_warning ("Failed to get session presence proxy");
1606        }
1607#endif
1608
1609 done:
1610        gtk_widget_show (GTK_WIDGET (adata->applet));
1611
1612        return TRUE;
1613}
1614
1615static gboolean
1616applet_factory (PanelApplet   *applet,
1617                const char    *iid,
1618                gpointer       data)
1619{
1620        gboolean ret;
1621        ret = FALSE;
1622        if (strcmp (iid, "OAFIID:GNOME_FastUserSwitchApplet") == 0) {
1623                ret = fill_applet (applet);
1624        }
1625        return ret;
1626}
Note: See TracBrowser for help on using the repository browser.