diff options
-rw-r--r-- | po/POTFILES.in | 3 | ||||
-rw-r--r-- | src/Makefile.am | 6 | ||||
-rw-r--r-- | src/device-menu-mgr.c | 461 | ||||
-rw-r--r-- | src/device-menu-mgr.h | 53 | ||||
-rw-r--r-- | src/session-menu-mgr.c | 889 | ||||
-rw-r--r-- | src/session-menu-mgr.h | 53 | ||||
-rw-r--r-- | src/session-service.c | 6 | ||||
-rw-r--r-- | src/user-menu-mgr.c | 496 | ||||
-rw-r--r-- | src/user-menu-mgr.h | 55 |
9 files changed, 947 insertions, 1075 deletions
diff --git a/po/POTFILES.in b/po/POTFILES.in index 03a259c..1023f4c 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -8,6 +8,5 @@ src/dialog.c src/indicator-session.c src/session-service.c src/apt-watcher.c -src/device-menu-mgr.c -src/user-menu-mgr.c +src/session-menu-mgr.c src/udev-mgr.c diff --git a/src/Makefile.am b/src/Makefile.am index 209b72d..9391d86 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -135,10 +135,8 @@ indicator_session_service_SOURCES = \ settings-helper.c \ users-service-dbus.h \ users-service-dbus.c \ - user-menu-mgr.h \ - user-menu-mgr.c \ - device-menu-mgr.h \ - device-menu-mgr.c + session-menu-mgr.h \ + session-menu-mgr.c indicator_session_service_CFLAGS = \ $(SESSIONSERVICE_CFLAGS) \ diff --git a/src/device-menu-mgr.c b/src/device-menu-mgr.c deleted file mode 100644 index ccf4107..0000000 --- a/src/device-menu-mgr.c +++ /dev/null @@ -1,461 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran <conor.curran@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include <config.h> - -#include <glib.h> -#include <gio/gio.h> - -#include <libdbusmenu-glib/client.h> -#include <libdbusmenu-gtk/menuitem.h> - -#include "dbus-upower.h" -#include "device-menu-mgr.h" -#include "settings-helper.h" -#include "dbus-shared-names.h" -#include "lock-helper.h" - -#define UP_ADDRESS "org.freedesktop.UPower" -#define UP_OBJECT "/org/freedesktop/UPower" -#define UP_INTERFACE "org.freedesktop.UPower" - -#define EXTRA_LAUNCHER_DIR "/usr/share/indicators/session/applications" - -struct _DeviceMenuMgr -{ - GObject parent_instance; - DbusmenuMenuitem * parent_mi; - SessionDbus* session_dbus_interface; - - GSettings *lockdown_settings; - GSettings * keybinding_settings; - - DbusmenuMenuitem * hibernate_mi; - DbusmenuMenuitem * suspend_mi; - DbusmenuMenuitem * lock_mi; - - gboolean can_hibernate; - gboolean can_suspend; - gboolean allow_hibernate; - gboolean allow_suspend; - - IndicatorSessionUPower * upower_proxy; - GCancellable * cancellable; -}; - -static void setup_up (DeviceMenuMgr* self); -static void device_menu_mgr_rebuild_items (DeviceMenuMgr *self); -static void screensaver_keybinding_changed (GSettings*, const gchar*, gpointer); - -G_DEFINE_TYPE (DeviceMenuMgr, device_menu_mgr, G_TYPE_OBJECT); - -static void -device_menu_mgr_init (DeviceMenuMgr *self) -{ - self->can_hibernate = TRUE; - self->can_suspend = TRUE; - self->allow_hibernate = TRUE; - self->allow_suspend = TRUE; - - self->lockdown_settings = g_settings_new (LOCKDOWN_SCHEMA); - g_signal_connect_swapped (self->lockdown_settings, "changed::" LOCKDOWN_KEY_USER, G_CALLBACK(device_menu_mgr_rebuild_items), self); - g_signal_connect_swapped (self->lockdown_settings, "changed::" LOCKDOWN_KEY_SCREENSAVER, G_CALLBACK(device_menu_mgr_rebuild_items), self); - - self->keybinding_settings = g_settings_new (KEYBINDING_SCHEMA); - g_signal_connect (self->keybinding_settings, "changed::" KEY_LOCK_SCREEN, G_CALLBACK(screensaver_keybinding_changed), self); - - setup_up(self); - g_idle_add(lock_screen_setup, NULL); -} - -static void -device_menu_mgr_dispose (GObject *object) -{ - DeviceMenuMgr * self = DEVICE_MENU_MGR (object); - g_clear_object (&self->lockdown_settings); - g_clear_object (&self->keybinding_settings); - g_clear_object (&self->upower_proxy); - g_clear_object (&self->cancellable); - - G_OBJECT_CLASS (device_menu_mgr_parent_class)->finalize (object); -} - -static void -device_menu_mgr_finalize (GObject *object) -{ - G_OBJECT_CLASS (device_menu_mgr_parent_class)->finalize (object); -} - -static void -device_menu_mgr_class_init (DeviceMenuMgrClass *klass) -{ - GObjectClass* object_class = G_OBJECT_CLASS (klass); - object_class->dispose = device_menu_mgr_dispose; - object_class->finalize = device_menu_mgr_finalize; -} - -/*** -**** -***/ - -static void -update_screensaver_shortcut (DbusmenuMenuitem * menuitem, GSettings * settings) -{ - if (menuitem != NULL) - { - gchar * val = g_settings_get_string (settings, KEY_LOCK_SCREEN); - g_debug ("Keybinding changed to: %s", val); - dbusmenu_menuitem_property_set_shortcut_string (menuitem, val); - g_free (val); - } -} - -static void -screensaver_keybinding_changed (GSettings * settings, - const gchar * key G_GNUC_UNUSED, - gpointer userdata) -{ - update_screensaver_shortcut (DEVICE_MENU_MGR(userdata)->lock_mi, settings); -} - - -static void -machine_sleep_from_suspend (DbusmenuMenuitem * mi G_GNUC_UNUSED, - guint timestamp G_GNUC_UNUSED, - gpointer userdata) -{ - GError * error = NULL; - DeviceMenuMgr * mgr = DEVICE_MENU_MGR (userdata); - - indicator_session_upower_call_suspend_sync (mgr->upower_proxy, mgr->cancellable, &error); - if (error != NULL) - { - g_warning ("%s: %s", G_STRFUNC, error->message); - g_clear_error (&error); - } -} - -static void -machine_sleep_from_hibernate (DbusmenuMenuitem * mi G_GNUC_UNUSED, - guint timestamp G_GNUC_UNUSED, - gpointer userdata) -{ - GError * error = NULL; - DeviceMenuMgr * mgr = DEVICE_MENU_MGR (userdata); - - indicator_session_upower_call_hibernate_sync (mgr->upower_proxy, mgr->cancellable, &error); - if (error != NULL) - { - g_warning ("%s: %s", G_STRFUNC, error->message); - g_clear_error (&error); - } -} - -/*** -**** -***/ - -/* When allow-suspend changes, rebuild the menus */ -static void -allowed_suspend_cb (GObject * source, GAsyncResult * res, gpointer userdata) -{ - gboolean allowed; - GError * error = NULL; - DeviceMenuMgr * mgr = DEVICE_MENU_MGR (userdata); - - indicator_session_upower_call_suspend_allowed_finish (mgr->upower_proxy, &allowed, res, &error); - if (error != NULL) - { - g_warning ("%s: %s", G_STRFUNC, error->message); - g_error_free (error); - } - else if (mgr->allow_suspend != allowed) - { - mgr->allow_suspend = allowed; - device_menu_mgr_rebuild_items (mgr); - } -} - -/* When allow-hibernate changes, rebuild the menus */ -static void -allowed_hibernate_cb (GObject * source, GAsyncResult * res, gpointer userdata) -{ - gboolean allowed; - GError * error = NULL; - DeviceMenuMgr * mgr = DEVICE_MENU_MGR (userdata); - - indicator_session_upower_call_hibernate_allowed_finish (mgr->upower_proxy, &allowed, res, &error); - if (error != NULL) - { - g_warning ("%s: %s", G_STRFUNC, error->message); - g_error_free (error); - } - else if (mgr->allow_hibernate != allowed) - { - mgr->allow_hibernate = allowed; - device_menu_mgr_rebuild_items (mgr); - } -} - - -static void -on_upower_properties_changed (IndicatorSessionUPower * upower_proxy, DeviceMenuMgr * mgr) -{ - gboolean b; - gboolean refresh = FALSE; - - /* suspend */ - b = indicator_session_upower_get_can_suspend (upower_proxy); - if (mgr->can_suspend != b) - { - mgr->can_suspend = b; - refresh = TRUE; - } - - /* hibernate */ - b = indicator_session_upower_get_can_hibernate (upower_proxy); - if (mgr->can_hibernate != b) - { - mgr->can_hibernate = b; - refresh = TRUE; - } - - if (refresh) - { - device_menu_mgr_rebuild_items (mgr); - } -} - -/* This function goes through and sets up what we need for DKp checking. - We're even setting up the calls for the props we need */ -static void -setup_up (DeviceMenuMgr* self) -{ - self->cancellable = g_cancellable_new (); - - GError * error = NULL; - self->upower_proxy = indicator_session_upower_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - 0, - UP_ADDRESS, - UP_OBJECT, - NULL, - &error); - if (error != NULL) - { - g_warning ("Error creating cups notify handler: %s", error->message); - g_error_free (error); - } - else - { - /* Check to see if these are getting blocked by PolicyKit */ - indicator_session_upower_call_suspend_allowed (self->upower_proxy, self->cancellable, allowed_suspend_cb, self); - indicator_session_upower_call_hibernate_allowed (self->upower_proxy, self->cancellable, allowed_hibernate_cb, self); - - g_signal_connect (self->upower_proxy, "changed", G_CALLBACK(on_upower_properties_changed), self); - - /* trigger an initial "changed" event */ - on_upower_properties_changed (self->upower_proxy, self); - } - - -} - -static void -spawn_command_line_async (const char * fmt, ...) -{ - va_list marker; - va_start (marker, fmt); - gchar * cmd = g_strdup_vprintf (fmt, marker); - va_end (marker); - - GError * error = NULL; - if (!g_spawn_command_line_async (cmd, &error)) - { - g_warning ("Unable to show \"%s\": %s", cmd, error->message); - } - - g_clear_error (&error); - g_free (cmd); -} - - -/* This is the function to show a dialog on actions that - can destroy data. Currently it just calls the GTK version - but it seems that in the future it should figure out - what's going on and something better. */ -static void -show_dialog (DbusmenuMenuitem * mi, guint timestamp, gchar * type) -{ -#ifdef HAVE_GTKLOGOUTHELPER - gchar * helper = g_build_filename(LIBEXECDIR, "gtk-logout-helper", NULL); -#else - gchar * helper = g_build_filename("gnome-session-quit", NULL); -#endif /* HAVE_GTKLOGOUTHELPER */ - spawn_command_line_async ("%s --%s", helper, type); - g_free (helper); -} - -static void -device_menu_mgr_build_static_items (DeviceMenuMgr* self, gboolean greeter_mode) -{ - const char * name; - DbusmenuMenuitem * mi; - DbusmenuMenuitem * logout_mi = NULL; - DbusmenuMenuitem * shutdown_mi = NULL; - - /*** - **** Admin items - ***/ - - name = _("About This Computer"); - mi = dbusmenu_menuitem_new (); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); - dbusmenu_menuitem_child_append (self->parent_mi, mi); -g_message ("appending About This Computer to %p", self->parent_mi); - - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(spawn_command_line_async), "gnome-control-center info"); - - name = _("Ubuntu Help"); - mi = dbusmenu_menuitem_new (); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); - dbusmenu_menuitem_child_append (self->parent_mi, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(spawn_command_line_async), "yelp"); - - if (!greeter_mode) - { - mi = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); - dbusmenu_menuitem_child_append (self->parent_mi, mi); - - name = _("System Settings…"); - mi = dbusmenu_menuitem_new (); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); - dbusmenu_menuitem_child_append (self->parent_mi, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(spawn_command_line_async), "gnome-control-center"); - } - - /*** - **** Account-switching items - ***/ - - /* TODO: FIXME */ - - const gboolean can_lockscreen = !g_settings_get_boolean (self->lockdown_settings, LOCKDOWN_KEY_SCREENSAVER); - if (can_lockscreen) - { - name = _("Lock Screen"); - self->lock_mi = mi = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); - update_screensaver_shortcut (mi, self->keybinding_settings); - dbusmenu_menuitem_child_append (self->parent_mi, mi); - g_signal_connect (G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(lock_screen), NULL); - } - - /*** - **** Session Items - ***/ - - mi = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); - dbusmenu_menuitem_child_append (self->parent_mi, mi); - - if (!greeter_mode) - { - name = supress_confirmations() ? _("Log Out") : _("Log Out\342\200\246"); - logout_mi = mi = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); - dbusmenu_menuitem_property_set_bool (mi, DBUSMENU_MENUITEM_PROP_VISIBLE, show_logout()); - dbusmenu_menuitem_child_append(self->parent_mi, mi); - g_signal_connect (G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(show_dialog), "logout"); - } - - if (self->can_suspend && self->allow_suspend) - { - name = _("Suspend"); - self->suspend_mi = mi = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); - dbusmenu_menuitem_child_append (self->parent_mi, mi); - g_signal_connect (G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(machine_sleep_from_suspend), self); - } - - if (self->can_hibernate && self->allow_hibernate) - { - name = _("Hibernate"); - self->hibernate_mi = mi = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); - dbusmenu_menuitem_child_append(self->parent_mi, mi); - g_signal_connect (G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(machine_sleep_from_hibernate), self); - } - - name = _("Restart"); - mi = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); - dbusmenu_menuitem_child_append (self->parent_mi, mi); - /* FIXME: not implemented */ - - name = supress_confirmations() ? _("Shut Down") : _("Shut Down\342\200\246"); - shutdown_mi = mi = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); - dbusmenu_menuitem_property_set_bool (mi, DBUSMENU_MENUITEM_PROP_VISIBLE, show_shutdown()); - dbusmenu_menuitem_child_append (self->parent_mi, mi); - g_signal_connect (G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, -#ifdef HAVE_GTKLOGOUTHELPER - G_CALLBACK(show_dialog), "shutdown"); -#else - G_CALLBACK(show_dialog), "power-off"); -#endif /* HAVE_GTKLOGOUTHELPER */ - - RestartShutdownLogoutMenuItems * restart_shutdown_logout_mi = g_new0 (RestartShutdownLogoutMenuItems, 1); - restart_shutdown_logout_mi->logout_mi = logout_mi; - restart_shutdown_logout_mi->shutdown_mi = shutdown_mi; - - update_menu_entries(restart_shutdown_logout_mi); -} - -static void -device_menu_mgr_rebuild_items (DeviceMenuMgr* self) -{ - dbusmenu_menuitem_property_set_bool (self->hibernate_mi, - DBUSMENU_MENUITEM_PROP_VISIBLE, - self->can_hibernate && self->allow_hibernate); - dbusmenu_menuitem_property_set_bool (self->suspend_mi, - DBUSMENU_MENUITEM_PROP_VISIBLE, - self->can_suspend && self->allow_suspend); -} - -/* - * Clean Entry Point - */ -DeviceMenuMgr* device_menu_mgr_new (DbusmenuMenuitem * parent_mi, - SessionDbus * session_dbus, - gboolean greeter_mode) -{ - DeviceMenuMgr* device_mgr = g_object_new (DEVICE_TYPE_MENU_MGR, NULL); - device_mgr->parent_mi = parent_mi; - device_mgr->session_dbus_interface = session_dbus; - device_menu_mgr_build_static_items (device_mgr, greeter_mode); - return device_mgr; -} diff --git a/src/device-menu-mgr.h b/src/device-menu-mgr.h deleted file mode 100644 index af84614..0000000 --- a/src/device-menu-mgr.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran <conor.curran@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - - -#ifndef _DEVICE_MENU_MGR_H_ -#define _DEVICE_MENU_MGR_H_ - -#include <glib-object.h> - -#include "session-dbus.h" - -G_BEGIN_DECLS - -#define DEVICE_TYPE_MENU_MGR (device_menu_mgr_get_type ()) -#define DEVICE_MENU_MGR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DEVICE_TYPE_MENU_MGR, DeviceMenuMgr)) -#define DEVICE_MENU_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DEVICE_TYPE_MENU_MGR, DeviceMenuMgrClass)) -#define DEVICE_IS_MENU_MGR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DEVICE_TYPE_MENU_MGR)) -#define DEVICE_IS_MENU_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DEVICE_TYPE_MENU_MGR)) -#define DEVICE_MENU_MGR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DEVICE_TYPE_MENU_MGR, DeviceMenuMgrClass)) - -typedef struct _DeviceMenuMgrClass DeviceMenuMgrClass; -typedef struct _DeviceMenuMgr DeviceMenuMgr; - -struct _DeviceMenuMgrClass -{ - GObjectClass parent_class; -}; - -GType device_menu_mgr_get_type (void) G_GNUC_CONST; - -DeviceMenuMgr* device_menu_mgr_new (DbusmenuMenuitem * parent_mi, - SessionDbus * session_dbus, - gboolean greeter_mode); - -G_END_DECLS - -#endif /* _DEVICE_MENU_MGR_H_ */ diff --git a/src/session-menu-mgr.c b/src/session-menu-mgr.c new file mode 100644 index 0000000..0fdaeb5 --- /dev/null +++ b/src/session-menu-mgr.c @@ -0,0 +1,889 @@ +/* +Copyright 2011 Canonical Ltd. + +Authors: + Conor Curran <conor.curran@canonical.com> + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <config.h> + +#include <glib.h> +#include <gio/gio.h> + +#include <libdbusmenu-glib/client.h> +#include <libdbusmenu-gtk/menuitem.h> + +#include "dbus-shared-names.h" +#include "dbus-upower.h" +#include "lock-helper.h" +#include "session-menu-mgr.h" +#include "settings-helper.h" +#include "users-service-dbus.h" + +#define UP_ADDRESS "org.freedesktop.UPower" +#define UP_OBJECT "/org/freedesktop/UPower" +#define UP_INTERFACE "org.freedesktop.UPower" + +#define EXTRA_LAUNCHER_DIR "/usr/share/indicators/session/applications" + +struct _SessionMenuMgr +{ + GObject parent_instance; + DbusmenuMenuitem * parent_mi; + SessionDbus* session_dbus_interface; + + GSettings *lockdown_settings; + GSettings * keybinding_settings; + + DbusmenuMenuitem * hibernate_mi; + DbusmenuMenuitem * suspend_mi; + DbusmenuMenuitem * lock_mi; + + gboolean can_hibernate; + gboolean can_suspend; + gboolean allow_hibernate; + gboolean allow_suspend; + + IndicatorSessionUPower * upower_proxy; + GCancellable * cancellable; + + UsersServiceDbus* users_dbus_interface; + DbusmenuMenuitem * guest_mi; + gboolean greeter_mode; +}; + +static void setup_up (SessionMenuMgr* self); +static void session_menu_mgr_rebuild_items (SessionMenuMgr *self); +static void screensaver_keybinding_changed (GSettings*, const gchar*, gpointer); + +static void activate_new_session (DbusmenuMenuitem * mi, + guint timestamp, + gpointer user_data); +static void activate_user_session (DbusmenuMenuitem *mi, + guint timestamp, + gpointer user_data); +static void activate_user_accounts (DbusmenuMenuitem *mi, + guint timestamp, + gpointer user_data); +static gint compare_users_by_username (gconstpointer a, + gconstpointer b); +static void activate_user_accounts (DbusmenuMenuitem *mi, + guint timestamp, + gpointer user_data); +static void menu_mgr_rebuild_users (SessionMenuMgr *self); +static void on_user_list_changed (UsersServiceDbus *service, + SessionMenuMgr * umm); + +static void on_guest_logged_in_changed (UsersServiceDbus * users_dbus, + SessionMenuMgr * self); + +static void on_user_logged_in_changed (UsersServiceDbus * users_dbus, + AccountsUser * user, + SessionMenuMgr * self); +static gboolean is_this_guest_session (void); +static void activate_guest_session (DbusmenuMenuitem * mi, + guint timestamp, + gpointer user_data); + + + +G_DEFINE_TYPE (SessionMenuMgr, session_menu_mgr, G_TYPE_OBJECT); + +static void +session_menu_mgr_init (SessionMenuMgr *self) +{ + self->can_hibernate = TRUE; + self->can_suspend = TRUE; + self->allow_hibernate = TRUE; + self->allow_suspend = TRUE; + + self->lockdown_settings = g_settings_new (LOCKDOWN_SCHEMA); + g_signal_connect_swapped (self->lockdown_settings, "changed::" LOCKDOWN_KEY_USER, G_CALLBACK(session_menu_mgr_rebuild_items), self); + g_signal_connect_swapped (self->lockdown_settings, "changed::" LOCKDOWN_KEY_SCREENSAVER, G_CALLBACK(session_menu_mgr_rebuild_items), self); + + self->keybinding_settings = g_settings_new (KEYBINDING_SCHEMA); + g_signal_connect (self->keybinding_settings, "changed::" KEY_LOCK_SCREEN, G_CALLBACK(screensaver_keybinding_changed), self); + + setup_up(self); + + /* users */ + self->users_dbus_interface = g_object_new (USERS_SERVICE_DBUS_TYPE, NULL); + g_signal_connect (self->users_dbus_interface, "user-list-changed", + G_CALLBACK (on_user_list_changed), self); + g_signal_connect (self->users_dbus_interface, "user-logged-in-changed", + G_CALLBACK(on_user_logged_in_changed), self); + g_signal_connect (self->users_dbus_interface, "guest-logged-in-changed", + G_CALLBACK(on_guest_logged_in_changed), self); + + g_idle_add(lock_screen_setup, NULL); +} + +static void +session_menu_mgr_dispose (GObject *object) +{ + SessionMenuMgr * self = SESSION_MENU_MGR (object); + g_clear_object (&self->lockdown_settings); + g_clear_object (&self->keybinding_settings); + g_clear_object (&self->upower_proxy); + g_clear_object (&self->cancellable); + g_clear_object (&self->users_dbus_interface); + + G_OBJECT_CLASS (session_menu_mgr_parent_class)->finalize (object); +} + +static void +session_menu_mgr_finalize (GObject *object) +{ + G_OBJECT_CLASS (session_menu_mgr_parent_class)->finalize (object); +} + +static void +session_menu_mgr_class_init (SessionMenuMgrClass *klass) +{ + GObjectClass* object_class = G_OBJECT_CLASS (klass); + object_class->dispose = session_menu_mgr_dispose; + object_class->finalize = session_menu_mgr_finalize; +} + +/*** +**** +***/ + +static void +update_screensaver_shortcut (DbusmenuMenuitem * menuitem, GSettings * settings) +{ + if (menuitem != NULL) + { + gchar * val = g_settings_get_string (settings, KEY_LOCK_SCREEN); + g_debug ("Keybinding changed to: %s", val); + dbusmenu_menuitem_property_set_shortcut_string (menuitem, val); + g_free (val); + } +} + +static void +screensaver_keybinding_changed (GSettings * settings, + const gchar * key G_GNUC_UNUSED, + gpointer userdata) +{ + update_screensaver_shortcut (SESSION_MENU_MGR(userdata)->lock_mi, settings); +} + + +static void +machine_sleep_from_suspend (DbusmenuMenuitem * mi G_GNUC_UNUSED, + guint timestamp G_GNUC_UNUSED, + gpointer userdata) +{ + GError * error = NULL; + SessionMenuMgr * mgr = SESSION_MENU_MGR (userdata); + + indicator_session_upower_call_suspend_sync (mgr->upower_proxy, mgr->cancellable, &error); + if (error != NULL) + { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_clear_error (&error); + } +} + +static void +machine_sleep_from_hibernate (DbusmenuMenuitem * mi G_GNUC_UNUSED, + guint timestamp G_GNUC_UNUSED, + gpointer userdata) +{ + GError * error = NULL; + SessionMenuMgr * mgr = SESSION_MENU_MGR (userdata); + + indicator_session_upower_call_hibernate_sync (mgr->upower_proxy, mgr->cancellable, &error); + if (error != NULL) + { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_clear_error (&error); + } +} + +/*** +**** +***/ + +/* When allow-suspend changes, rebuild the menus */ +static void +allowed_suspend_cb (GObject * source, GAsyncResult * res, gpointer userdata) +{ + gboolean allowed; + GError * error = NULL; + SessionMenuMgr * mgr = SESSION_MENU_MGR (userdata); + + indicator_session_upower_call_suspend_allowed_finish (mgr->upower_proxy, &allowed, res, &error); + if (error != NULL) + { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_error_free (error); + } + else if (mgr->allow_suspend != allowed) + { + mgr->allow_suspend = allowed; + session_menu_mgr_rebuild_items (mgr); + } +} + +/* When allow-hibernate changes, rebuild the menus */ +static void +allowed_hibernate_cb (GObject * source, GAsyncResult * res, gpointer userdata) +{ + gboolean allowed; + GError * error = NULL; + SessionMenuMgr * mgr = SESSION_MENU_MGR (userdata); + + indicator_session_upower_call_hibernate_allowed_finish (mgr->upower_proxy, &allowed, res, &error); + if (error != NULL) + { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_error_free (error); + } + else if (mgr->allow_hibernate != allowed) + { + mgr->allow_hibernate = allowed; + session_menu_mgr_rebuild_items (mgr); + } +} + + +static void +on_upower_properties_changed (IndicatorSessionUPower * upower_proxy, SessionMenuMgr * mgr) +{ + gboolean b; + gboolean refresh = FALSE; + + /* suspend */ + b = indicator_session_upower_get_can_suspend (upower_proxy); + if (mgr->can_suspend != b) + { + mgr->can_suspend = b; + refresh = TRUE; + } + + /* hibernate */ + b = indicator_session_upower_get_can_hibernate (upower_proxy); + if (mgr->can_hibernate != b) + { + mgr->can_hibernate = b; + refresh = TRUE; + } + + if (refresh) + { + session_menu_mgr_rebuild_items (mgr); + } +} + +/* This function goes through and sets up what we need for DKp checking. + We're even setting up the calls for the props we need */ +static void +setup_up (SessionMenuMgr* self) +{ + self->cancellable = g_cancellable_new (); + + GError * error = NULL; + self->upower_proxy = indicator_session_upower_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + 0, + UP_ADDRESS, + UP_OBJECT, + NULL, + &error); + if (error != NULL) + { + g_warning ("Error creating cups notify handler: %s", error->message); + g_error_free (error); + } + else + { + /* Check to see if these are getting blocked by PolicyKit */ + indicator_session_upower_call_suspend_allowed (self->upower_proxy, self->cancellable, allowed_suspend_cb, self); + indicator_session_upower_call_hibernate_allowed (self->upower_proxy, self->cancellable, allowed_hibernate_cb, self); + + g_signal_connect (self->upower_proxy, "changed", G_CALLBACK(on_upower_properties_changed), self); + + /* trigger an initial "changed" event */ + on_upower_properties_changed (self->upower_proxy, self); + } + + +} + +static void +spawn_command_line_async (const char * fmt, ...) +{ + va_list marker; + va_start (marker, fmt); + gchar * cmd = g_strdup_vprintf (fmt, marker); + va_end (marker); + + GError * error = NULL; + if (!g_spawn_command_line_async (cmd, &error)) + { + g_warning ("Unable to show \"%s\": %s", cmd, error->message); + } + + g_clear_error (&error); + g_free (cmd); +} + + +/* This is the function to show a dialog on actions that + can destroy data. Currently it just calls the GTK version + but it seems that in the future it should figure out + what's going on and something better. */ +static void +show_dialog (DbusmenuMenuitem * mi, guint timestamp, gchar * type) +{ +#ifdef HAVE_GTKLOGOUTHELPER + gchar * helper = g_build_filename(LIBEXECDIR, "gtk-logout-helper", NULL); +#else + gchar * helper = g_build_filename("gnome-session-quit", NULL); +#endif /* HAVE_GTKLOGOUTHELPER */ + spawn_command_line_async ("%s --%s", helper, type); + g_free (helper); +} + +static void +session_menu_mgr_build_static_items (SessionMenuMgr* self, gboolean greeter_mode) +{ + const char * name; + DbusmenuMenuitem * mi; + DbusmenuMenuitem * logout_mi = NULL; + DbusmenuMenuitem * shutdown_mi = NULL; + + /*** + **** Admin items + ***/ + + name = _("About This Computer"); + mi = dbusmenu_menuitem_new (); + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); + dbusmenu_menuitem_child_append (self->parent_mi, mi); + + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(spawn_command_line_async), "gnome-control-center info"); + + name = _("Ubuntu Help"); + mi = dbusmenu_menuitem_new (); + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); + dbusmenu_menuitem_child_append (self->parent_mi, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(spawn_command_line_async), "yelp"); + + if (!greeter_mode) + { + mi = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); + dbusmenu_menuitem_child_append (self->parent_mi, mi); + + name = _("System Settings…"); + mi = dbusmenu_menuitem_new (); + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); + dbusmenu_menuitem_child_append (self->parent_mi, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(spawn_command_line_async), "gnome-control-center"); + } + + mi = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); + dbusmenu_menuitem_child_append (self->parent_mi, mi); + + /*** + **** Account-switching items + ***/ + + /* TODO: FIXME */ + + const gboolean can_lockscreen = !g_settings_get_boolean (self->lockdown_settings, LOCKDOWN_KEY_SCREENSAVER); + if (can_lockscreen) + { + name = _("Lock Screen"); + self->lock_mi = mi = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); + update_screensaver_shortcut (mi, self->keybinding_settings); + dbusmenu_menuitem_child_append (self->parent_mi, mi); + g_signal_connect (G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(lock_screen), NULL); + } + + /*** + **** Session Items + ***/ + + mi = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); + dbusmenu_menuitem_child_append (self->parent_mi, mi); + + if (!greeter_mode) + { + name = supress_confirmations() ? _("Log Out") : _("Log Out\342\200\246"); + logout_mi = mi = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); + dbusmenu_menuitem_property_set_bool (mi, DBUSMENU_MENUITEM_PROP_VISIBLE, show_logout()); + dbusmenu_menuitem_child_append(self->parent_mi, mi); + g_signal_connect (G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(show_dialog), "logout"); + } + + if (self->can_suspend && self->allow_suspend) + { + name = _("Suspend"); + self->suspend_mi = mi = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); + dbusmenu_menuitem_child_append (self->parent_mi, mi); + g_signal_connect (G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(machine_sleep_from_suspend), self); + } + + if (self->can_hibernate && self->allow_hibernate) + { + name = _("Hibernate"); + self->hibernate_mi = mi = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); + dbusmenu_menuitem_child_append(self->parent_mi, mi); + g_signal_connect (G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(machine_sleep_from_hibernate), self); + } + + name = _("Restart"); + mi = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); + dbusmenu_menuitem_child_append (self->parent_mi, mi); + /* FIXME: not implemented */ + + name = supress_confirmations() ? _("Shut Down") : _("Shut Down\342\200\246"); + shutdown_mi = mi = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); + dbusmenu_menuitem_property_set_bool (mi, DBUSMENU_MENUITEM_PROP_VISIBLE, show_shutdown()); + dbusmenu_menuitem_child_append (self->parent_mi, mi); + g_signal_connect (G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, +#ifdef HAVE_GTKLOGOUTHELPER + G_CALLBACK(show_dialog), "shutdown"); +#else + G_CALLBACK(show_dialog), "power-off"); +#endif /* HAVE_GTKLOGOUTHELPER */ + + RestartShutdownLogoutMenuItems * restart_shutdown_logout_mi = g_new0 (RestartShutdownLogoutMenuItems, 1); + restart_shutdown_logout_mi->logout_mi = logout_mi; + restart_shutdown_logout_mi->shutdown_mi = shutdown_mi; + + update_menu_entries(restart_shutdown_logout_mi); +} + +static void +session_menu_mgr_rebuild_items (SessionMenuMgr* self) +{ + dbusmenu_menuitem_property_set_bool (self->hibernate_mi, + DBUSMENU_MENUITEM_PROP_VISIBLE, + self->can_hibernate && self->allow_hibernate); + dbusmenu_menuitem_property_set_bool (self->suspend_mi, + DBUSMENU_MENUITEM_PROP_VISIBLE, + self->can_suspend && self->allow_suspend); +} + +/*** +**** User Menu +***/ + +struct ActivateUserSessionData +{ + SessionMenuMgr * menu_mgr; + AccountsUser * user; +}; + +/*** +**** +***/ + +static GQuark +get_menuitem_quark (void) +{ + static GQuark q = 0; + + if (G_UNLIKELY(!q)) + { + q = g_quark_from_static_string ("menuitem"); + } + + return q; +} + +static DbusmenuMenuitem* +user_get_menuitem (AccountsUser * user) +{ + return g_object_get_qdata (G_OBJECT(user), get_menuitem_quark()); +} + +static void +user_set_menuitem (AccountsUser * user, DbusmenuMenuitem * mi) +{ + g_message ("%s %s() associating user %s with mi %p", G_STRLOC, G_STRFUNC, accounts_user_get_user_name(user), mi); + g_object_set_qdata_full (G_OBJECT(user), get_menuitem_quark(), g_object_ref(G_OBJECT(mi)), g_object_unref); +} + +static GQuark +get_name_collision_quark (void) +{ + static GQuark q = 0; + + if (G_UNLIKELY(!q)) + { + q = g_quark_from_static_string ("name-collision"); + } + + return q; +} + +static gboolean +get_user_name_collision (AccountsUser * user) +{ + return g_object_get_qdata (G_OBJECT(user), get_name_collision_quark()) != NULL; +} + +static void +set_user_name_collision (AccountsUser * user, gboolean b) +{ + g_object_set_qdata (G_OBJECT(user), get_name_collision_quark(), GINT_TO_POINTER(b)); +} + +/*** +**** +***/ + +static void +update_menuitem_icon (DbusmenuMenuitem * mi, AccountsUser * user) +{ + const gchar * str = accounts_user_get_icon_file (user); + + if (!str || !*str) + { + str = USER_ITEM_ICON_DEFAULT; + } + + dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_ICON, str); +} + +static void +on_user_icon_file_changed (AccountsUser * user, GParamSpec * pspec, DbusmenuMenuitem * mi) +{ + update_menuitem_icon (mi, user); +} + +static DbusmenuMenuitem* +create_user_menuitem (SessionMenuMgr * menu_mgr, AccountsUser * user) +{ + DbusmenuMenuitem * mi = dbusmenu_menuitem_new (); + dbusmenu_menuitem_property_set (mi, + DBUSMENU_MENUITEM_PROP_TYPE, + USER_ITEM_TYPE); + + /* set the name property */ + const gchar * const real_name = accounts_user_get_real_name (user); + const gchar * const user_name = accounts_user_get_user_name (user); + char * str = get_user_name_collision (user) + ? g_strdup_printf ("%s (%s)", real_name, user_name) + : g_strdup (real_name); + dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, str); + g_free (str); + + /* set the logged-in property */ + const gboolean is_logged_in = users_service_dbus_is_user_logged_in (menu_mgr->users_dbus_interface, user); + dbusmenu_menuitem_property_set_bool (mi, + USER_ITEM_PROP_LOGGED_IN, + is_logged_in); + + /* set the icon property */ + update_menuitem_icon (mi, user); + g_signal_connect (user, "notify::icon-file", G_CALLBACK(on_user_icon_file_changed), mi); + + /* set the is-current-user property */ + dbusmenu_menuitem_property_set_bool (mi, + USER_ITEM_PROP_IS_CURRENT_USER, + !g_strcmp0 (user_name, g_get_user_name())); + + /* set the activate callback */ + struct ActivateUserSessionData * data = g_new (struct ActivateUserSessionData, 1); + data->user = user; + data->menu_mgr = menu_mgr; + g_signal_connect_data (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK (activate_user_session), + data, (GClosureNotify)g_free, + 0); + + /* give this AccountsUser a hook back to this menuitem */ + user_set_menuitem (user, mi); + + /* done */ + return mi; +} + +static void +on_guest_logged_in_changed (UsersServiceDbus * users_service_dbus, + SessionMenuMgr * self) +{ + if (self->guest_mi != NULL) + { + const gboolean b = users_service_dbus_is_guest_logged_in (users_service_dbus); + dbusmenu_menuitem_property_set_bool (self->guest_mi, USER_ITEM_PROP_LOGGED_IN, b); + } +} + +/* When a user's login state changes, + update the corresponding menuitem's LOGGED_IN property */ +static void +on_user_logged_in_changed (UsersServiceDbus * users_service_dbus, + AccountsUser * user, + SessionMenuMgr * self) +{ + DbusmenuMenuitem * mi = user_get_menuitem (user); + + if (mi != NULL) + { + const gboolean b = users_service_dbus_is_user_logged_in (users_service_dbus, user); + dbusmenu_menuitem_property_set_bool (mi, USER_ITEM_PROP_LOGGED_IN, b); + } +} + +/* Builds up the menu for us */ +static void +menu_mgr_rebuild_users (SessionMenuMgr *self) +{ + GList *u; + gboolean can_activate; + + /* Check to see which menu items we're allowed to have */ + can_activate = users_service_dbus_can_activate_session (self->users_dbus_interface) && + !g_settings_get_boolean (self->lockdown_settings, LOCKDOWN_KEY_USER); + + /* Remove the old menu items if that makes sense */ +#warning FIXME +#if 0 + GList * children = dbusmenu_menuitem_take_children (self->root_item); + g_list_foreach (children, (GFunc)g_object_unref, NULL); + g_list_free (children); +#endif + + /* Set to NULL in case we don't end up building one */ + self->guest_mi = NULL; + + /* Build all of the user switching items */ + if (can_activate) + { + /* TODO: This needs to be updated once the ability to query guest session support is available */ + GList * users = users_service_dbus_get_user_list (self->users_dbus_interface); + const gboolean guest_enabled = users_service_dbus_guest_session_enabled (self->users_dbus_interface); + + /* TODO we should really return here if the menu is not going to be shown. */ + + DbusmenuMenuitem * switch_menuitem = dbusmenu_menuitem_new (); +/* + dbusmenu_menuitem_property_set (switch_menuitem, + DBUSMENU_MENUITEM_PROP_TYPE, + MENU_SWITCH_TYPE); +*/ + dbusmenu_menuitem_property_set (switch_menuitem, + USER_ITEM_PROP_NAME, + _("Switch User Account…")); + dbusmenu_menuitem_child_append (self->parent_mi, switch_menuitem); +g_message ("appending Switch button to %p", self->parent_mi); + g_signal_connect (G_OBJECT (switch_menuitem), + DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK (activate_new_session), + self); + + if ( !is_this_guest_session () && guest_enabled) + { + self->guest_mi = dbusmenu_menuitem_new (); + dbusmenu_menuitem_property_set (self->guest_mi, + DBUSMENU_MENUITEM_PROP_TYPE, + USER_ITEM_TYPE); + dbusmenu_menuitem_property_set (self->guest_mi, + USER_ITEM_PROP_NAME, + _("Guest Session")); + on_guest_logged_in_changed (self->users_dbus_interface, self); + dbusmenu_menuitem_child_append (self->parent_mi, self->guest_mi); + g_signal_connect (G_OBJECT (self->guest_mi), + DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK (activate_guest_session), + self); + } + else{ + session_dbus_set_users_real_name (self->session_dbus_interface, + _("Guest")); + } + + + + users = g_list_sort (users, compare_users_by_username); + + for (u = users; u != NULL; u = g_list_next (u)) + { + AccountsUser * user = u->data; + + DbusmenuMenuitem * mi = create_user_menuitem (self, user); + dbusmenu_menuitem_child_append (self->parent_mi, mi); + + const char * const user_name = accounts_user_get_user_name (user); + if (!g_strcmp0 (user_name, g_get_user_name())) + { + const char * const real_name = accounts_user_get_real_name (user); + session_dbus_set_users_real_name (self->session_dbus_interface, real_name); + } + } + + g_list_free(users); + } + + // Add the user accounts and separator + DbusmenuMenuitem * separator1 = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set (separator1, + DBUSMENU_MENUITEM_PROP_TYPE, + DBUSMENU_CLIENT_TYPES_SEPARATOR); + dbusmenu_menuitem_child_append (self->parent_mi, separator1); + + DbusmenuMenuitem * user_accounts_item = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set (user_accounts_item, + DBUSMENU_MENUITEM_PROP_TYPE, + DBUSMENU_CLIENT_TYPES_DEFAULT); + dbusmenu_menuitem_property_set (user_accounts_item, + DBUSMENU_MENUITEM_PROP_LABEL, + _("User Accounts…")); + + g_signal_connect (G_OBJECT (user_accounts_item), + DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK (activate_user_accounts), + NULL); + + dbusmenu_menuitem_child_append (self->parent_mi, user_accounts_item); + + +} + +/* Check to see if the lockdown key is protecting from + locking the screen. If not, lock it. */ +static void +lock_if_possible (SessionMenuMgr * menu_mgr) +{ + if (!g_settings_get_boolean (menu_mgr->lockdown_settings, LOCKDOWN_KEY_SCREENSAVER)) + { + lock_screen(NULL, 0, NULL); + } +} + +/* Starts a new generic session */ +static void +activate_new_session (DbusmenuMenuitem * mi, guint timestamp, gpointer user_data) +{ + SessionMenuMgr * menu_mgr = SESSION_MENU_MGR (user_data); + g_return_if_fail (menu_mgr != NULL); + + lock_if_possible (menu_mgr); + users_service_dbus_show_greeter (menu_mgr->users_dbus_interface); +} + +/* Activates a session for a particular user. */ +static void +activate_user_session (DbusmenuMenuitem *mi, guint timestamp, gpointer user_data) +{ + struct ActivateUserSessionData * data = user_data; + + lock_if_possible (data->menu_mgr); + users_service_dbus_activate_user_session (data->menu_mgr->users_dbus_interface, data->user); +} + +/* Comparison function to look into the UserData struct + to compare by using the username value */ +static gint +compare_users_by_username (gconstpointer ga, gconstpointer gb) +{ + AccountsUser * a = ACCOUNTS_USER(ga); + AccountsUser * b = ACCOUNTS_USER(gb); + + const int ret = g_strcmp0 (accounts_user_get_real_name (a), + accounts_user_get_real_name (b)); + + if (!ret) /* names are the same, so both have a name collision */ + { + set_user_name_collision (a, TRUE); + set_user_name_collision (b, TRUE); + } + + return ret; +} + +static void +activate_user_accounts (DbusmenuMenuitem *mi, + guint timestamp, + gpointer user_data) +{ + GError * error = NULL; + if (!g_spawn_command_line_async("gnome-control-center user-accounts", &error)) + { + g_warning("Unable to show control centre: %s", error->message); + g_error_free(error); + } +} + +/* Signal called when a user is added. + It updates the count and rebuilds the menu */ +static void +on_user_list_changed (UsersServiceDbus * service G_GNUC_UNUSED, + SessionMenuMgr * menu_mgr) +{ + g_return_if_fail (IS_SESSION_MENU_MGR(menu_mgr)); + + menu_mgr_rebuild_users (menu_mgr); +} + + +/* Checks to see if we should show the guest session item. + System users shouldn't have guest account shown. + Mostly this would be the case of the guest user itself. */ +static gboolean +is_this_guest_session (void) +{ + return geteuid() < 500; +} + +/* Called when someone clicks on the guest session item. */ +static void +activate_guest_session (DbusmenuMenuitem * mi, guint timestamp, gpointer user_data) +{ + SessionMenuMgr * menu_mgr = SESSION_MENU_MGR (user_data); + g_return_if_fail (menu_mgr != NULL); + + lock_if_possible (menu_mgr); + users_service_dbus_activate_guest_session (menu_mgr->users_dbus_interface); +} + +/*** +**** +***/ + +SessionMenuMgr* session_menu_mgr_new (DbusmenuMenuitem * parent_mi, + SessionDbus * session_dbus, + gboolean greeter_mode) +{ + SessionMenuMgr* menu_mgr = g_object_new (SESSION_TYPE_MENU_MGR, NULL); + menu_mgr->parent_mi = parent_mi; + menu_mgr->greeter_mode = greeter_mode; + menu_mgr->session_dbus_interface = session_dbus; + session_menu_mgr_build_static_items (menu_mgr, greeter_mode); + menu_mgr_rebuild_users (menu_mgr); + return menu_mgr; +} diff --git a/src/session-menu-mgr.h b/src/session-menu-mgr.h new file mode 100644 index 0000000..0fa7baa --- /dev/null +++ b/src/session-menu-mgr.h @@ -0,0 +1,53 @@ +/* +Copyright 2011 Canonical Ltd. + +Authors: + Conor Curran <conor.curran@canonical.com> + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + + +#ifndef _SESSION_MENU_MGR_H_ +#define _SESSION_MENU_MGR_H_ + +#include <glib-object.h> + +#include "session-dbus.h" + +G_BEGIN_DECLS + +#define SESSION_TYPE_MENU_MGR (session_menu_mgr_get_type ()) +#define SESSION_MENU_MGR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SESSION_TYPE_MENU_MGR, SessionMenuMgr)) +#define SESSION_MENU_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SESSION_TYPE_MENU_MGR, SessionMenuMgrClass)) +#define IS_SESSION_MENU_MGR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SESSION_TYPE_MENU_MGR)) +#define IS_SESSION_MENU_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SESSION_TYPE_MENU_MGR)) +#define SESSION_MENU_MGR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SESSION_TYPE_MENU_MGR, SessionMenuMgrClass)) + +typedef struct _SessionMenuMgrClass SessionMenuMgrClass; +typedef struct _SessionMenuMgr SessionMenuMgr; + +struct _SessionMenuMgrClass +{ + GObjectClass parent_class; +}; + +GType session_menu_mgr_get_type (void) G_GNUC_CONST; + +SessionMenuMgr* session_menu_mgr_new (DbusmenuMenuitem * parent_mi, + SessionDbus * session_dbus, + gboolean greeter_mode); + +G_END_DECLS + +#endif /* _SESSION_MENU_MGR_H_ */ diff --git a/src/session-service.c b/src/session-service.c index ece3a1d..598fcce 100644 --- a/src/session-service.c +++ b/src/session-service.c @@ -44,9 +44,8 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include "dbus-shared-names.h" #include "users-service-dbus.h" -#include "user-menu-mgr.h" -#include "device-menu-mgr.h" #include "session-dbus.h" +#include "session-menu-mgr.h" //static UsersServiceDbus *dbus_interface = NULL; static SessionDbus *session_dbus = NULL; @@ -99,8 +98,7 @@ main (int argc, char ** argv) greeter_mode = get_greeter_mode(); DbusmenuMenuitem * root_item = dbusmenu_menuitem_new (); - device_menu_mgr_new (root_item, session_dbus, greeter_mode); - user_menu_mgr_new (root_item, session_dbus, greeter_mode); + session_menu_mgr_new (root_item, session_dbus, greeter_mode); DbusmenuServer* server = dbusmenu_server_new (INDICATOR_SESSION_DBUS_OBJECT); dbusmenu_server_set_root (server, root_item); diff --git a/src/user-menu-mgr.c b/src/user-menu-mgr.c deleted file mode 100644 index cde3899..0000000 --- a/src/user-menu-mgr.c +++ /dev/null @@ -1,496 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran <conor.curran@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include <libdbusmenu-glib/client.h> -#include "user-menu-mgr.h" -#include "settings-helper.h" -#include "dbus-shared-names.h" -#include "lock-helper.h" -#include "users-service-dbus.h" - -struct ActivateUserSessionData -{ - UserMenuMgr * menu_mgr; - AccountsUser * user; -}; - -struct _UserMenuMgr -{ - GObject parent_instance; - UsersServiceDbus* users_dbus_interface; - DbusmenuMenuitem* parent_mi; - DbusmenuMenuitem * guest_mi; - SessionDbus* session_dbus_interface; - GSettings * lockdown_settings; - gboolean greeter_mode; -}; - -static void activate_new_session (DbusmenuMenuitem * mi, - guint timestamp, - gpointer user_data); -static void activate_user_session (DbusmenuMenuitem *mi, - guint timestamp, - gpointer user_data); -static void activate_user_accounts (DbusmenuMenuitem *mi, - guint timestamp, - gpointer user_data); -static gint compare_users_by_username (gconstpointer a, - gconstpointer b); -static void activate_user_accounts (DbusmenuMenuitem *mi, - guint timestamp, - gpointer user_data); -static void user_menu_mgr_rebuild_items (UserMenuMgr *self); -static void on_user_list_changed (UsersServiceDbus *service, - UserMenuMgr * umm); - -static void on_guest_logged_in_changed (UsersServiceDbus * users_dbus, - UserMenuMgr * self); - -static void on_user_logged_in_changed (UsersServiceDbus * users_dbus, - AccountsUser * user, - UserMenuMgr * self); -static gboolean is_this_guest_session (void); -static void activate_guest_session (DbusmenuMenuitem * mi, - guint timestamp, - gpointer user_data); - - -G_DEFINE_TYPE (UserMenuMgr, user_menu_mgr, G_TYPE_OBJECT); - -/*** -**** -***/ - -static void -user_menu_mgr_init (UserMenuMgr *self) -{ - self->lockdown_settings = g_settings_new (LOCKDOWN_SCHEMA); - self->users_dbus_interface = g_object_new (USERS_SERVICE_DBUS_TYPE, NULL); - g_signal_connect (self->users_dbus_interface, "user-list-changed", - G_CALLBACK (on_user_list_changed), self); - g_signal_connect (self->users_dbus_interface, "user-logged-in-changed", - G_CALLBACK(on_user_logged_in_changed), self); - g_signal_connect (self->users_dbus_interface, "guest-logged-in-changed", - G_CALLBACK(on_guest_logged_in_changed), self); -} - -static void -user_menu_mgr_dispose (GObject *object) -{ - UserMenuMgr * menu_mgr = USER_MENU_MGR(object); - - g_clear_object (&menu_mgr->users_dbus_interface); - g_clear_object (&menu_mgr->lockdown_settings); -} - -static void -user_menu_mgr_finalize (GObject *object) -{ - /* TODO: Add deinitalization code here */ - G_OBJECT_CLASS (user_menu_mgr_parent_class)->finalize (object); -} - -static void -user_menu_mgr_class_init (UserMenuMgrClass *klass) -{ - GObjectClass* object_class = G_OBJECT_CLASS (klass); - object_class->dispose = user_menu_mgr_dispose; - object_class->finalize = user_menu_mgr_finalize; -} - -/*** -**** -***/ - -static GQuark -get_menuitem_quark (void) -{ - static GQuark q = 0; - - if (G_UNLIKELY(!q)) - { - q = g_quark_from_static_string ("menuitem"); - } - - return q; -} - -static DbusmenuMenuitem* -user_get_menuitem (AccountsUser * user) -{ - return g_object_get_qdata (G_OBJECT(user), get_menuitem_quark()); -} - -static void -user_set_menuitem (AccountsUser * user, DbusmenuMenuitem * mi) -{ - g_message ("%s %s() associating user %s with mi %p", G_STRLOC, G_STRFUNC, accounts_user_get_user_name(user), mi); - g_object_set_qdata_full (G_OBJECT(user), get_menuitem_quark(), g_object_ref(G_OBJECT(mi)), g_object_unref); -} - -static GQuark -get_name_collision_quark (void) -{ - static GQuark q = 0; - - if (G_UNLIKELY(!q)) - { - q = g_quark_from_static_string ("name-collision"); - } - - return q; -} - -static gboolean -get_user_name_collision (AccountsUser * user) -{ - return g_object_get_qdata (G_OBJECT(user), get_name_collision_quark()) != NULL; -} - -static void -set_user_name_collision (AccountsUser * user, gboolean b) -{ - g_object_set_qdata (G_OBJECT(user), get_name_collision_quark(), GINT_TO_POINTER(b)); -} - -/*** -**** -***/ - -static void -update_menuitem_icon (DbusmenuMenuitem * mi, AccountsUser * user) -{ - const gchar * str = accounts_user_get_icon_file (user); - - if (!str || !*str) - { - str = USER_ITEM_ICON_DEFAULT; - } - - dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_ICON, str); -} - -static void -on_user_icon_file_changed (AccountsUser * user, GParamSpec * pspec, DbusmenuMenuitem * mi) -{ - update_menuitem_icon (mi, user); -} - -static DbusmenuMenuitem* -create_user_menuitem (UserMenuMgr * menu_mgr, AccountsUser * user) -{ - DbusmenuMenuitem * mi = dbusmenu_menuitem_new (); - dbusmenu_menuitem_property_set (mi, - DBUSMENU_MENUITEM_PROP_TYPE, - USER_ITEM_TYPE); - - /* set the name property */ - const gchar * const real_name = accounts_user_get_real_name (user); - const gchar * const user_name = accounts_user_get_user_name (user); - char * str = get_user_name_collision (user) - ? g_strdup_printf ("%s (%s)", real_name, user_name) - : g_strdup (real_name); - dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, str); - g_free (str); - - /* set the logged-in property */ - const gboolean is_logged_in = users_service_dbus_is_user_logged_in (menu_mgr->users_dbus_interface, user); - dbusmenu_menuitem_property_set_bool (mi, - USER_ITEM_PROP_LOGGED_IN, - is_logged_in); - - /* set the icon property */ - update_menuitem_icon (mi, user); - g_signal_connect (user, "notify::icon-file", G_CALLBACK(on_user_icon_file_changed), mi); - - /* set the is-current-user property */ - dbusmenu_menuitem_property_set_bool (mi, - USER_ITEM_PROP_IS_CURRENT_USER, - !g_strcmp0 (user_name, g_get_user_name())); - - /* set the activate callback */ - struct ActivateUserSessionData * data = g_new (struct ActivateUserSessionData, 1); - data->user = user; - data->menu_mgr = menu_mgr; - g_signal_connect_data (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (activate_user_session), - data, (GClosureNotify)g_free, - 0); - - /* give this AccountsUser a hook back to this menuitem */ - user_set_menuitem (user, mi); - - /* done */ - return mi; -} - -static void -on_guest_logged_in_changed (UsersServiceDbus * users_service_dbus, - UserMenuMgr * self) -{ - if (self->guest_mi != NULL) - { - const gboolean b = users_service_dbus_is_guest_logged_in (users_service_dbus); - dbusmenu_menuitem_property_set_bool (self->guest_mi, USER_ITEM_PROP_LOGGED_IN, b); - } -} - -/* When a user's login state changes, - update the corresponding menuitem's LOGGED_IN property */ -static void -on_user_logged_in_changed (UsersServiceDbus * users_service_dbus, - AccountsUser * user, - UserMenuMgr * self) -{ - DbusmenuMenuitem * mi = user_get_menuitem (user); - - if (mi != NULL) - { - const gboolean b = users_service_dbus_is_user_logged_in (users_service_dbus, user); - dbusmenu_menuitem_property_set_bool (mi, USER_ITEM_PROP_LOGGED_IN, b); - } -} - -/* Builds up the menu for us */ -static void -user_menu_mgr_rebuild_items (UserMenuMgr *self) -{ - GList *u; - gboolean can_activate; - - /* Check to see which menu items we're allowed to have */ - can_activate = users_service_dbus_can_activate_session (self->users_dbus_interface) && - !g_settings_get_boolean (self->lockdown_settings, LOCKDOWN_KEY_USER); - - /* Remove the old menu items if that makes sense */ -#warning FIXME -#if 0 - GList * children = dbusmenu_menuitem_take_children (self->root_item); - g_list_foreach (children, (GFunc)g_object_unref, NULL); - g_list_free (children); -#endif - - /* Set to NULL in case we don't end up building one */ - self->guest_mi = NULL; - - /* Build all of the user switching items */ - if (can_activate) - { - /* TODO: This needs to be updated once the ability to query guest session support is available */ - GList * users = users_service_dbus_get_user_list (self->users_dbus_interface); - const gboolean guest_enabled = users_service_dbus_guest_session_enabled (self->users_dbus_interface); - - /* TODO we should really return here if the menu is not going to be shown. */ - - DbusmenuMenuitem * switch_menuitem = dbusmenu_menuitem_new (); -/* - dbusmenu_menuitem_property_set (switch_menuitem, - DBUSMENU_MENUITEM_PROP_TYPE, - MENU_SWITCH_TYPE); -*/ - dbusmenu_menuitem_property_set (switch_menuitem, - USER_ITEM_PROP_NAME, - _("Switch User Account…")); - dbusmenu_menuitem_child_append (self->parent_mi, switch_menuitem); -g_message ("appending Switch button to %p", self->parent_mi); - g_signal_connect (G_OBJECT (switch_menuitem), - DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (activate_new_session), - self); - - if ( !is_this_guest_session () && guest_enabled) - { - self->guest_mi = dbusmenu_menuitem_new (); - dbusmenu_menuitem_property_set (self->guest_mi, - DBUSMENU_MENUITEM_PROP_TYPE, - USER_ITEM_TYPE); - dbusmenu_menuitem_property_set (self->guest_mi, - USER_ITEM_PROP_NAME, - _("Guest Session")); - on_guest_logged_in_changed (self->users_dbus_interface, self); - dbusmenu_menuitem_child_append (self->parent_mi, self->guest_mi); - g_signal_connect (G_OBJECT (self->guest_mi), - DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (activate_guest_session), - self); - } - else{ - session_dbus_set_users_real_name (self->session_dbus_interface, - _("Guest")); - } - - - - users = g_list_sort (users, compare_users_by_username); - - for (u = users; u != NULL; u = g_list_next (u)) - { - AccountsUser * user = u->data; - - DbusmenuMenuitem * mi = create_user_menuitem (self, user); - dbusmenu_menuitem_child_append (self->parent_mi, mi); - - const char * const user_name = accounts_user_get_user_name (user); - if (!g_strcmp0 (user_name, g_get_user_name())) - { - const char * const real_name = accounts_user_get_real_name (user); - session_dbus_set_users_real_name (self->session_dbus_interface, real_name); - } - } - - g_list_free(users); - } - - // Add the user accounts and separator - DbusmenuMenuitem * separator1 = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (separator1, - DBUSMENU_MENUITEM_PROP_TYPE, - DBUSMENU_CLIENT_TYPES_SEPARATOR); - dbusmenu_menuitem_child_append (self->parent_mi, separator1); - - DbusmenuMenuitem * user_accounts_item = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (user_accounts_item, - DBUSMENU_MENUITEM_PROP_TYPE, - DBUSMENU_CLIENT_TYPES_DEFAULT); - dbusmenu_menuitem_property_set (user_accounts_item, - DBUSMENU_MENUITEM_PROP_LABEL, - _("User Accounts…")); - - g_signal_connect (G_OBJECT (user_accounts_item), - DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (activate_user_accounts), - NULL); - - dbusmenu_menuitem_child_append (self->parent_mi, user_accounts_item); - - -} - -/* Check to see if the lockdown key is protecting from - locking the screen. If not, lock it. */ -static void -lock_if_possible (UserMenuMgr * menu_mgr) -{ - if (!g_settings_get_boolean (menu_mgr->lockdown_settings, LOCKDOWN_KEY_SCREENSAVER)) - { - lock_screen(NULL, 0, NULL); - } -} - -/* Starts a new generic session */ -static void -activate_new_session (DbusmenuMenuitem * mi, guint timestamp, gpointer user_data) -{ - UserMenuMgr * menu_mgr = USER_MENU_MGR (user_data); - g_return_if_fail (menu_mgr != NULL); - - lock_if_possible (menu_mgr); - users_service_dbus_show_greeter (menu_mgr->users_dbus_interface); -} - -/* Activates a session for a particular user. */ -static void -activate_user_session (DbusmenuMenuitem *mi, guint timestamp, gpointer user_data) -{ - struct ActivateUserSessionData * data = user_data; - - lock_if_possible (data->menu_mgr); - users_service_dbus_activate_user_session (data->menu_mgr->users_dbus_interface, data->user); -} - -/* Comparison function to look into the UserData struct - to compare by using the username value */ -static gint -compare_users_by_username (gconstpointer ga, gconstpointer gb) -{ - AccountsUser * a = ACCOUNTS_USER(ga); - AccountsUser * b = ACCOUNTS_USER(gb); - - const int ret = g_strcmp0 (accounts_user_get_real_name (a), - accounts_user_get_real_name (b)); - - if (!ret) /* names are the same, so both have a name collision */ - { - set_user_name_collision (a, TRUE); - set_user_name_collision (b, TRUE); - } - - return ret; -} - -static void -activate_user_accounts (DbusmenuMenuitem *mi, - guint timestamp, - gpointer user_data) -{ - GError * error = NULL; - if (!g_spawn_command_line_async("gnome-control-center user-accounts", &error)) - { - g_warning("Unable to show control centre: %s", error->message); - g_error_free(error); - } -} - -/* Signal called when a user is added. - It updates the count and rebuilds the menu */ -static void -on_user_list_changed (UsersServiceDbus * service G_GNUC_UNUSED, - UserMenuMgr * user_mgr) -{ - g_return_if_fail (USER_IS_MENU_MGR(user_mgr)); - - user_menu_mgr_rebuild_items (user_mgr); -} - - -/* Checks to see if we should show the guest session item. - System users shouldn't have guest account shown. - Mostly this would be the case of the guest user itself. */ -static gboolean -is_this_guest_session (void) -{ - return geteuid() < 500; -} - -/* Called when someone clicks on the guest session item. */ -static void -activate_guest_session (DbusmenuMenuitem * mi, guint timestamp, gpointer user_data) -{ - UserMenuMgr * menu_mgr = USER_MENU_MGR (user_data); - g_return_if_fail (menu_mgr != NULL); - - lock_if_possible (menu_mgr); - users_service_dbus_activate_guest_session (menu_mgr->users_dbus_interface); -} - - -/* - * Clean Entry Point - */ -UserMenuMgr* user_menu_mgr_new (DbusmenuMenuitem * parent_mi, - SessionDbus * session_dbus, - gboolean greeter_mode) -{ - UserMenuMgr* user_mgr = g_object_new (USER_TYPE_MENU_MGR, NULL); - user_mgr->parent_mi = parent_mi; - user_mgr->greeter_mode = greeter_mode; - user_mgr->session_dbus_interface = session_dbus; - user_menu_mgr_rebuild_items (user_mgr); - return user_mgr; -} diff --git a/src/user-menu-mgr.h b/src/user-menu-mgr.h deleted file mode 100644 index 4b0fd3f..0000000 --- a/src/user-menu-mgr.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran <conor.curran@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - - -#ifndef _USER_MENU_MGR_H_ -#define _USER_MENU_MGR_H_ - - -#include <glib-object.h> -#include <libdbusmenu-gtk/menuitem.h> - -#include "session-dbus.h" - -G_BEGIN_DECLS - -#define USER_TYPE_MENU_MGR (user_menu_mgr_get_type ()) -#define USER_MENU_MGR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), USER_TYPE_MENU_MGR, UserMenuMgr)) -#define USER_MENU_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), USER_TYPE_MENU_MGR, UserMenuMgrClass)) -#define USER_IS_MENU_MGR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), USER_TYPE_MENU_MGR)) -#define USER_IS_MENU_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), USER_TYPE_MENU_MGR)) -#define USER_MENU_MGR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), USER_TYPE_MENU_MGR, UserMenuMgrClass)) - -typedef struct _UserMenuMgrClass UserMenuMgrClass; -typedef struct _UserMenuMgr UserMenuMgr; - -struct _UserMenuMgrClass -{ - GObjectClass parent_class; -}; - -GType user_menu_mgr_get_type (void) G_GNUC_CONST; - -UserMenuMgr* user_menu_mgr_new (DbusmenuMenuitem * parent, - SessionDbus * session_dbus, - gboolean greeter_mode); - -G_END_DECLS - -#endif /* _USER_MENU_MGR_H_ */ |