From f181ac9b4f685811eb03596be28ac01b428edcbc Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sat, 2 Jun 2012 17:40:07 -0500 Subject: Add gcda/gcno to CLEANFILES s.t. 'make clean' will cover them --- src/Makefile.am | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/Makefile.am') diff --git a/src/Makefile.am b/src/Makefile.am index b29e8d4..76c9c03 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,4 @@ - +CLEANFILES = EXTRA_DIST = libexec_PROGRAMS = \ @@ -13,6 +13,8 @@ endif # Indicator Stuff ################### +CLEANFILES += .libs/*.gcda .libs/*.gcno *.gcda *.gcno + sessionlibdir = $(INDICATORDIR) sessionlib_LTLIBRARIES = libsession.la libsession_la_SOURCES = \ @@ -204,5 +206,4 @@ EXTRA_DIST += \ accounts-service.xml \ accounts-service-user.xml -CLEANFILES = \ - $(BUILT_SOURCES) +CLEANFILES += $(BUILT_SOURCES) -- cgit v1.2.3 From 09ed92a81c950f6b2221652281c04c1c85e68177 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 4 Jun 2012 17:19:23 -0500 Subject: remove the software updates menuitem; it's no longer in the spec --- configure.ac | 13 --- src/Makefile.am | 10 -- src/apt-watcher.c | 287 -------------------------------------------------- src/apt-watcher.h | 55 ---------- src/device-menu-mgr.c | 38 ++----- 5 files changed, 7 insertions(+), 396 deletions(-) delete mode 100644 src/apt-watcher.c delete mode 100644 src/apt-watcher.h (limited to 'src/Makefile.am') diff --git a/configure.ac b/configure.ac index 84c5c2e..f17db0b 100644 --- a/configure.ac +++ b/configure.ac @@ -83,18 +83,6 @@ AM_CONDITIONAL(BUILD_GTKLOGOUTHELPER, test x${have_gtklogouthelper} = xyes) AC_SUBST(GTKLOGOUTHELPER_CFLAGS) AC_SUBST(GTKLOGOUTHELPER_LIBS) -########################### -# APT support -########################### -AC_ARG_ENABLE([apt], - AC_HELP_STRING([--disable-apt], [disable APT support]),, - [enable_apt=yes]) -AM_CONDITIONAL([BUILD_APT], [test "x$enable_apt" != "xno"]) - -if test "x$enable_apt" != "xno"; then - AC_DEFINE(HAVE_APT, 1, [Define to 1 to enable APT support]) -fi - ########################### # Check to see if we're local ########################### @@ -240,7 +228,6 @@ SUS Indicator Configuration: Prefix: $prefix Indicator Dir: $INDICATORDIR Logout Helper: $have_gtklogouthelper - APT support: $enable_apt Unit Tests: $enable_tests Coverage reporting: $use_gcov ]) diff --git a/src/Makefile.am b/src/Makefile.am index 76c9c03..fd3480f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -116,16 +116,6 @@ indicator_session_service_SOURCES = \ device-menu-mgr.c \ sane-rules.h -if BUILD_APT -indicator_session_service_SOURCES += \ - apt-watcher.h \ - apt-watcher.c -else -EXTRA_DIST += \ - apt-watcher.h \ - apt-watcher.c -endif - if HAS_GUDEV indicator_session_service_SOURCES += \ udev-mgr.h \ diff --git a/src/apt-watcher.c b/src/apt-watcher.c deleted file mode 100644 index 092942f..0000000 --- a/src/apt-watcher.c +++ /dev/null @@ -1,287 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -// Conor - 6/2/2012 -// Please pull in packagekit's client lib -// using apt-get install --no-install-recommends libpackagekit-glib2-dev -// make sure you don't install package-kit -#define I_KNOW_THE_PACKAGEKIT_GLIB2_API_IS_SUBJECT_TO_CHANGE - -#include -#include -#include "apt-watcher.h" -#include "dbus-shared-names.h" - -static guint watcher_id; - -struct _AptWatcher -{ - GObject parent_instance; - SessionDbus* session_dbus_interface; - DbusmenuMenuitem* apt_item; - AptState current_state; - GCancellable * proxy_cancel; - GDBusProxy * proxy; -}; - -G_DEFINE_TYPE (AptWatcher, apt_watcher, G_TYPE_OBJECT); - - -static void -get_updates_complete (GObject *source_object, - GAsyncResult *res, - gpointer user_data) -{ - g_return_if_fail (APT_IS_WATCHER (user_data)); - AptWatcher* self = APT_WATCHER (user_data); - - PkResults *results; - PkRestartEnum restart_required; - GError *error = NULL; - results = pk_client_generic_finish (PK_CLIENT(source_object), res, &error); - - if (error != NULL){ - g_warning ("Unable to query for updates - error - %s", error->message); - return; - } - - GPtrArray *packages; - packages = pk_results_get_package_array (results); - - const gchar* disposition; - disposition = dbusmenu_menuitem_property_get (self->apt_item, - DBUSMENU_MENUITEM_PROP_DISPOSITION); - gboolean do_update; - do_update = g_strcmp0 (disposition, DBUSMENU_MENUITEM_DISPOSITION_ALERT) != 0; - - if (packages->len > 0){ - g_print ("Apparently we have updates available - change dbmitem %i", do_update); - if (do_update) - dbusmenu_menuitem_property_set (self->apt_item, - DBUSMENU_MENUITEM_PROP_LABEL, - _("Updates Available…")); - } - else{ - g_print ("No updates available - change dbmitem - %i", do_update); - if (do_update) - dbusmenu_menuitem_property_set (self->apt_item, - DBUSMENU_MENUITEM_PROP_LABEL, - _("Software Up to Date")); - } - - /* check if there was a restart required info in the signal */ - restart_required = pk_results_get_require_restart_worst (results); - if (restart_required == PK_RESTART_ENUM_SYSTEM || - restart_required == PK_RESTART_ENUM_SECURITY_SYSTEM) { - dbusmenu_menuitem_property_set (self->apt_item, - DBUSMENU_MENUITEM_PROP_LABEL, - _("Restart to Complete Updates…")); - dbusmenu_menuitem_property_set (self->apt_item, - DBUSMENU_MENUITEM_PROP_DISPOSITION, - DBUSMENU_MENUITEM_DISPOSITION_ALERT); - session_dbus_restart_required (self->session_dbus_interface); - } - - g_ptr_array_unref (packages); - g_object_unref (results); - g_object_unref (source_object); -} - -static void -apt_watcher_check_for_updates (AptWatcher* self) -{ - PkClient* client; - client = pk_client_new (); - - pk_client_get_updates_async (client, - PK_FILTER_ENUM_NONE, - NULL, NULL, NULL, - (GAsyncReadyCallback)get_updates_complete, - self); -} - -static void apt_watcher_signal_cb ( GDBusProxy* proxy, - gchar* sender_name, - gchar* signal_name, - GVariant* parameters, - gpointer user_data) -{ - g_return_if_fail (APT_IS_WATCHER (user_data)); - AptWatcher* self = APT_WATCHER (user_data); - - g_debug ("apt-watcher-signal cb signal name - %s", signal_name); - if (g_strcmp0(signal_name, "UpdatesChanged") == 0){ - g_debug ("updates changed signal received"); - apt_watcher_check_for_updates (self); - } -} - -static void -apt_watcher_on_name_appeared (GDBusConnection *connection, - const gchar *name, - const gchar *name_owner, - gpointer user_data) -{ - g_return_if_fail (APT_IS_WATCHER (user_data)); - // AptWatcher* watcher = APT_WATCHER (user_data); - - g_print ("Name %s on %s is owned by %s\n", - name, - "the system bus", - name_owner); -} - - -static void -apt_watcher_on_name_vanished (GDBusConnection *connection, - const gchar *name, - gpointer user_data) -{ - g_debug ("Name %s does not exist or has just vanished", - name); - g_return_if_fail (APT_IS_WATCHER (user_data)); -} - -static void -fetch_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data) -{ - GError * error = NULL; - - AptWatcher* self = APT_WATCHER(user_data); - g_return_if_fail(self != NULL); - - GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish (res, &error); - - if (self->proxy_cancel != NULL) { - g_object_unref (self->proxy_cancel); - self->proxy_cancel = NULL; - } - - if (error != NULL) { - g_warning("Could not grab DBus proxy for %s: %s", - "org.debian.apt", error->message); - g_error_free(error); - return; - } - - self->proxy = proxy; - // Set up the watch. - watcher_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM, - "org.freedesktop.PackageKit", - G_BUS_NAME_WATCHER_FLAGS_NONE, - apt_watcher_on_name_appeared, - apt_watcher_on_name_vanished, - self, - NULL); - g_signal_connect (self->proxy, - "g-signal", - G_CALLBACK(apt_watcher_signal_cb), - self); -} - -static gboolean -apt_watcher_start_apt_interaction (gpointer data) -{ - g_return_val_if_fail (APT_IS_WATCHER (data), FALSE); - AptWatcher* self = APT_WATCHER (data); - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.freedesktop.PackageKit", - "/org/freedesktop/PackageKit", - "org.freedesktop.PackageKit", - self->proxy_cancel, - fetch_proxy_cb, - self); - apt_watcher_check_for_updates (self); - return FALSE; -} - - -static void -apt_watcher_show_apt_dialog (DbusmenuMenuitem * mi, - guint timestamp, - gpointer userdata) -{ - GError * error = NULL; - g_return_if_fail (APT_IS_WATCHER (userdata)); - AptWatcher* self = APT_WATCHER (userdata); - const gchar* disposition = NULL; - disposition = dbusmenu_menuitem_property_get (self->apt_item, - DBUSMENU_MENUITEM_PROP_DISPOSITION); - - if (g_strcmp0 (disposition, DBUSMENU_MENUITEM_DISPOSITION_ALERT) == 0){ - gchar * helper = g_build_filename (LIBEXECDIR, "gtk-logout-helper", NULL); - gchar * dialog_line = g_strdup_printf ("%s --%s", helper, "restart"); - g_free(helper); - if (!g_spawn_command_line_async(dialog_line, &error)) { - g_warning("Unable to show dialog: %s", error->message); - g_error_free(error); - } - g_free(dialog_line); - } - else{ - if (!g_spawn_command_line_async("update-manager", &error)) - { - g_warning("Unable to show update-manager: %s", error->message); - g_error_free(error); - } - } -} - -static void -apt_watcher_init (AptWatcher *self) -{ - self->current_state = UP_TO_DATE; - g_timeout_add_seconds (60, - apt_watcher_start_apt_interaction, - self); -} - -static void -apt_watcher_finalize (GObject *object) -{ - g_bus_unwatch_name (watcher_id); - AptWatcher* self = APT_WATCHER (object); - - if (self->proxy != NULL) - g_object_unref (self->proxy); - - G_OBJECT_CLASS (apt_watcher_parent_class)->finalize (object); -} - -static void -apt_watcher_class_init (AptWatcherClass *klass) -{ - GObjectClass* object_class = G_OBJECT_CLASS (klass); - object_class->finalize = apt_watcher_finalize; -} - -AptWatcher* apt_watcher_new (SessionDbus* session_dbus, - DbusmenuMenuitem* item) -{ - AptWatcher* watcher = g_object_new (APT_TYPE_WATCHER, NULL); - watcher->session_dbus_interface = session_dbus; - watcher->apt_item = item; - g_signal_connect (G_OBJECT(watcher->apt_item), - DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(apt_watcher_show_apt_dialog), watcher); - return watcher; -} - diff --git a/src/apt-watcher.h b/src/apt-watcher.h deleted file mode 100644 index c571502..0000000 --- a/src/apt-watcher.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -#ifndef _APT_WATCHER_H_ -#define _APT_WATCHER_H_ - -#include - -#include - -#include -#include - -#include "session-dbus.h" - -G_BEGIN_DECLS - -#define APT_TYPE_WATCHER (apt_watcher_get_type ()) -#define APT_WATCHER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), APT_TYPE_WATCHER, AptWatcher)) -#define APT_WATCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), APT_TYPE_WATCHER, AptWatcherClass)) -#define APT_IS_WATCHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), APT_TYPE_WATCHER)) -#define APT_IS_WATCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), APT_TYPE_WATCHER)) -#define APT_WATCHER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), APT_TYPE_WATCHER, AptWatcherClass)) - -typedef struct _AptWatcherClass AptWatcherClass; -typedef struct _AptWatcher AptWatcher; - -struct _AptWatcherClass -{ - GObjectClass parent_class; -}; - -GType apt_watcher_get_type (void) G_GNUC_CONST; - -AptWatcher* apt_watcher_new (SessionDbus* session_dbus, - DbusmenuMenuitem* apt_item); -G_END_DECLS - -#endif /* _APT_WATCHER_H_ */ diff --git a/src/device-menu-mgr.c b/src/device-menu-mgr.c index 654e967..81182b9 100644 --- a/src/device-menu-mgr.c +++ b/src/device-menu-mgr.c @@ -18,7 +18,12 @@ with this program. If not, see . */ #include + +#include +#include + #include +#include #include "device-menu-mgr.h" #include "settings-helper.h" @@ -27,10 +32,6 @@ with this program. If not, see . #include "lock-helper.h" #include "upower-client.h" -#ifdef HAVE_APT -#include "apt-watcher.h" -#endif /* HAVE_APT */ - #ifdef HAS_GUDEV #include "udev-mgr.h" #endif /* HAS_GUDEV */ @@ -43,12 +44,9 @@ with this program. If not, see . struct _DeviceMenuMgr { - GObject parent_instance; + GObject parent_instance; DbusmenuMenuitem* root_item; SessionDbus* session_dbus_interface; -#ifdef HAVE_APT - AptWatcher* apt_watcher; -#endif /* HAVE_APT */ #ifdef HAS_GUDEV UdevMgr* udev_mgr; #endif /* HAS_GUDEV */ @@ -58,9 +56,6 @@ static GSettings *lockdown_settings = NULL; static GSettings *keybinding_settings = NULL; static DbusmenuMenuitem *lock_menuitem = NULL; static DbusmenuMenuitem *system_settings_menuitem = NULL; -#ifdef HAVE_APT -static DbusmenuMenuitem *software_updates_menuitem = NULL; -#endif /* HAVE_APT */ static DBusGProxyCall * suspend_call = NULL; static DBusGProxyCall * hibernate_call = NULL; @@ -101,9 +96,6 @@ G_DEFINE_TYPE (DeviceMenuMgr, device_menu_mgr, G_TYPE_OBJECT); static void device_menu_mgr_init (DeviceMenuMgr *self) { -#ifdef HAVE_APT - self->apt_watcher = NULL; -#endif /* HAVE_APT */ self->root_item = dbusmenu_menuitem_new (); setup_up(self); g_idle_add(lock_screen_setup, NULL); @@ -441,21 +433,11 @@ device_menu_mgr_build_settings_items (DeviceMenuMgr* self) system_settings_menuitem, 0); -#ifdef HAVE_APT - software_updates_menuitem = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (software_updates_menuitem, - DBUSMENU_MENUITEM_PROP_LABEL, - _("Software Up to Date")); - dbusmenu_menuitem_child_add_position(self->root_item, - software_updates_menuitem, - 1); -#endif /* HAVE_APT */ - DbusmenuMenuitem * separator1 = dbusmenu_menuitem_new(); dbusmenu_menuitem_property_set (separator1, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); - dbusmenu_menuitem_child_add_position (self->root_item, separator1, 2); + dbusmenu_menuitem_child_add_position (self->root_item, separator1, 1); } static void @@ -644,11 +626,5 @@ DeviceMenuMgr* device_menu_mgr_new (SessionDbus* session_dbus, gboolean greeter_ DeviceMenuMgr* device_mgr = g_object_new (DEVICE_TYPE_MENU_MGR, NULL); device_mgr->session_dbus_interface = session_dbus; device_menu_mgr_build_static_items (device_mgr, greeter_mode); -#ifdef HAVE_APT - if (software_updates_menuitem != NULL) { - device_mgr->apt_watcher = apt_watcher_new (session_dbus, - software_updates_menuitem); - } -#endif /* HAVE_APT */ return device_mgr; } -- cgit v1.2.3 From fb89365ff1f8be1b407d1e0519c3d28744692011 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 4 Jun 2012 19:11:25 -0500 Subject: remove our udev dependency now that we no longer use it to look at devices --- configure.ac | 3 - src/Makefile.am | 17 +- src/device-menu-mgr.c | 11 - src/sane-rules.h | 778 -------------------------------------------------- src/udev-mgr.c | 546 ----------------------------------- src/udev-mgr.h | 58 ---- 6 files changed, 2 insertions(+), 1411 deletions(-) delete mode 100644 src/sane-rules.h delete mode 100644 src/udev-mgr.c delete mode 100644 src/udev-mgr.h (limited to 'src/Makefile.am') diff --git a/configure.ac b/configure.ac index f17db0b..8d2d901 100644 --- a/configure.ac +++ b/configure.ac @@ -52,7 +52,6 @@ PKG_CHECK_MODULES(SESSIONSERVICE, dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VE AC_SUBST(SESSIONERVICE_CFLAGS) AC_SUBST(SESSIONERVICE_LIBS) -PKG_CHECK_MODULES(GUDEV, gudev-1.0, has_gudev=true, has_gudev=false) AC_SUBST(GUDEV_CFLAGS) AC_SUBST(GUDEV_LIBS) @@ -188,8 +187,6 @@ AC_SUBST(COVERAGE_LDFLAGS) # Files ########################### -AM_CONDITIONAL([HAS_GUDEV], [test "x$has_gudev" = "xtrue"]) - AC_CONFIG_FILES([ Makefile src/Makefile diff --git a/src/Makefile.am b/src/Makefile.am index fd3480f..d99c2df 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -113,18 +113,7 @@ indicator_session_service_SOURCES = \ user-menu-mgr.h \ user-menu-mgr.c \ device-menu-mgr.h \ - device-menu-mgr.c \ - sane-rules.h - -if HAS_GUDEV -indicator_session_service_SOURCES += \ - udev-mgr.h \ - udev-mgr.c -else -EXTRA_DIST += \ - udev-mgr.h \ - udev-mgr.c -endif + device-menu-mgr.c indicator_session_service_CFLAGS = \ $(SESSIONSERVICE_CFLAGS) \ @@ -132,12 +121,10 @@ indicator_session_service_CFLAGS = \ -DLIBEXECDIR=\"$(libexecdir)\" \ -Wall -Werror \ -DG_LOG_DOMAIN=\"Indicator-Session\" \ - $(GUDEV_CFLAGS) \ $(COVERAGE_CFLAGS) indicator_session_service_LDADD = \ $(SESSIONSERVICE_LIBS) \ - $(GCONF_LIBS) \ - $(GUDEV_LIBS) + $(GCONF_LIBS) indicator_session_service_LDFLAGS = \ $(COVERAGE_LDFLAGS) diff --git a/src/device-menu-mgr.c b/src/device-menu-mgr.c index 81182b9..5a31716 100644 --- a/src/device-menu-mgr.c +++ b/src/device-menu-mgr.c @@ -32,10 +32,6 @@ with this program. If not, see . #include "lock-helper.h" #include "upower-client.h" -#ifdef HAS_GUDEV -#include "udev-mgr.h" -#endif /* HAS_GUDEV */ - #define UP_ADDRESS "org.freedesktop.UPower" #define UP_OBJECT "/org/freedesktop/UPower" #define UP_INTERFACE "org.freedesktop.UPower" @@ -47,9 +43,6 @@ struct _DeviceMenuMgr GObject parent_instance; DbusmenuMenuitem* root_item; SessionDbus* session_dbus_interface; -#ifdef HAS_GUDEV - UdevMgr* udev_mgr; -#endif /* HAS_GUDEV */ }; static GSettings *lockdown_settings = NULL; @@ -579,10 +572,6 @@ device_menu_mgr_build_static_items (DeviceMenuMgr* self, gboolean greeter_mode) restart_shutdown_logout_mi->shutdown_mi = shutdown_mi; update_menu_entries(restart_shutdown_logout_mi); -#ifdef HAS_GUDEV - // Time to create the udev mgr and hand it the static relevant items. - self->udev_mgr = udev_mgr_new (scanners_menuitem, webcam_menuitem); -#endif } static void diff --git a/src/sane-rules.h b/src/sane-rules.h deleted file mode 100644 index 0b72e52..0000000 --- a/src/sane-rules.h +++ /dev/null @@ -1,778 +0,0 @@ -void populate_scsi_scanners (GHashTable* scanners) -{ - GList* epson = NULL; - epson = g_list_append (epson, g_strdup ("GT-9700")); - epson = g_list_append (epson, g_strdup ("GT-9800")); - epson = g_list_append (epson, g_strdup ("Perfection1200")); - epson = g_list_append (epson, g_strdup ("Perfection636")); - epson = g_list_append (epson, g_strdup ("SCANNER GT-7000")); - g_hash_table_insert (scanners, - g_strdup("EPSON"), - epson); - - - GList* hp = NULL; - hp = g_list_append (hp, g_strdup ("C1130A")); - hp = g_list_append (hp, g_strdup ("C1750A")); - hp = g_list_append (hp, g_strdup ("C1790A")); - hp = g_list_append (hp, g_strdup ("C2500A")); - hp = g_list_append (hp, g_strdup ("C2520A")); - hp = g_list_append (hp, g_strdup ("C5110A")); - hp = g_list_append (hp, g_strdup ("C6270A")); - hp = g_list_append (hp, g_strdup ("C7670A")); - g_hash_table_insert (scanners, - g_strdup("HP"), - hp); -} - - - -void populate_usb_scanners (GHashTable* scanners) -{ - GList* hp = NULL; - - hp = g_list_append (hp, g_strdup ("0101")); - hp = g_list_append (hp, g_strdup ("0105")); - hp = g_list_append (hp, g_strdup ("0201")); - hp = g_list_append (hp, g_strdup ("0205")); - hp = g_list_append (hp, g_strdup ("0305")); - hp = g_list_append (hp, g_strdup ("0401")); - hp = g_list_append (hp, g_strdup ("0405")); - hp = g_list_append (hp, g_strdup ("0505")); - hp = g_list_append (hp, g_strdup ("0601")); - hp = g_list_append (hp, g_strdup ("0605")); - hp = g_list_append (hp, g_strdup ("0701")); - hp = g_list_append (hp, g_strdup ("0705")); - hp = g_list_append (hp, g_strdup ("0801")); - hp = g_list_append (hp, g_strdup ("0805")); - hp = g_list_append (hp, g_strdup ("0901")); - hp = g_list_append (hp, g_strdup ("0a01")); - hp = g_list_append (hp, g_strdup ("0b01")); - hp = g_list_append (hp, g_strdup ("1005")); - hp = g_list_append (hp, g_strdup ("1105")); - hp = g_list_append (hp, g_strdup ("1205")); - hp = g_list_append (hp, g_strdup ("1305")); - hp = g_list_append (hp, g_strdup ("1405")); - hp = g_list_append (hp, g_strdup ("1705")); - hp = g_list_append (hp, g_strdup ("1805")); - hp = g_list_append (hp, g_strdup ("2005")); - hp = g_list_append (hp, g_strdup ("2205")); - hp = g_list_append (hp, g_strdup ("2305")); - hp = g_list_append (hp, g_strdup ("2405")); - hp = g_list_append (hp, g_strdup ("2605")); - hp = g_list_append (hp, g_strdup ("2805")); - hp = g_list_append (hp, g_strdup ("3805")); - hp = g_list_append (hp, g_strdup ("3905")); - hp = g_list_append (hp, g_strdup ("3B17")); - hp = g_list_append (hp, g_strdup ("4105")); - hp = g_list_append (hp, g_strdup ("4205")); - hp = g_list_append (hp, g_strdup ("4305")); - hp = g_list_append (hp, g_strdup ("4505")); - hp = g_list_append (hp, g_strdup ("4605")); - hp = g_list_append (hp, g_strdup ("5617")); - hp = g_list_append (hp, g_strdup ("5717")); - - g_hash_table_insert (scanners, - g_strdup("03f0"), - hp); - - GList* mustek_2 = NULL; - mustek_2 = g_list_append (mustek_2, g_strdup ("1000")); - mustek_2 = g_list_append (mustek_2, g_strdup ("1001")); - g_hash_table_insert (scanners, - g_strdup("0400"), - mustek_2); - - GList* kodak = NULL; - kodak = g_list_append (kodak, g_strdup ("6001")); - kodak = g_list_append (kodak, g_strdup ("6002")); - kodak = g_list_append (kodak, g_strdup ("6003")); - kodak = g_list_append (kodak, g_strdup ("6004")); - kodak = g_list_append (kodak, g_strdup ("6005")); - g_hash_table_insert (scanners, - g_strdup("040a"), - kodak); - - GList* creative = NULL; - - creative = g_list_append (creative, g_strdup ("4007")); - - g_hash_table_insert (scanners, - g_strdup("041e"), - creative); - - GList* lexmark = NULL; - - lexmark = g_list_append (lexmark, g_strdup("002d")); - lexmark = g_list_append (lexmark, g_strdup("0060")); - lexmark = g_list_append (lexmark, g_strdup("007c")); - lexmark = g_list_append (lexmark, g_strdup("007d")); - - g_hash_table_insert (scanners, - g_strdup("043d"), - lexmark); - - - GList* genius = NULL; - genius = g_list_append (genius, g_strdup("2004")); - genius = g_list_append (genius, g_strdup("2007")); - genius = g_list_append (genius, g_strdup("2008")); - genius = g_list_append (genius, g_strdup("2009")); - genius = g_list_append (genius, g_strdup("2011")); - genius = g_list_append (genius, g_strdup("2013")); - genius = g_list_append (genius, g_strdup("2014")); - genius = g_list_append (genius, g_strdup("2015")); - genius = g_list_append (genius, g_strdup("2016")); - genius = g_list_append (genius, g_strdup("2017")); - genius = g_list_append (genius, g_strdup("201a")); - genius = g_list_append (genius, g_strdup("201b")); - genius = g_list_append (genius, g_strdup("201d")); - genius = g_list_append (genius, g_strdup("201e")); - genius = g_list_append (genius, g_strdup("201f")); - genius = g_list_append (genius, g_strdup("20c1")); - g_hash_table_insert (scanners, - g_strdup("0458"), - genius); - - GList* medion = NULL; - medion = g_list_append (medion, g_strdup("0377")); - g_hash_table_insert (scanners, - g_strdup("0461"), - medion); - - GList* trust = NULL; - trust = g_list_append (trust, g_strdup("1000")); - trust = g_list_append (trust, g_strdup("1002")); - g_hash_table_insert (scanners, - g_strdup("047b"), - trust); - - GList* kyocera = NULL; - kyocera = g_list_append (kyocera, g_strdup("0335")); - g_hash_table_insert (scanners, - g_strdup("0482"), - kyocera); - - GList* compaq = NULL; - compaq = g_list_append (compaq, g_strdup("001a")); - g_hash_table_insert (scanners, - g_strdup("049f"), - compaq); - GList* benq = NULL; - benq = g_list_append (benq, g_strdup("1a20")); - benq = g_list_append (benq, g_strdup("1a2a")); - benq = g_list_append (benq, g_strdup("2022")); - benq = g_list_append (benq, g_strdup("2040")); - benq = g_list_append (benq, g_strdup("2060")); - benq = g_list_append (benq, g_strdup("207e")); - benq = g_list_append (benq, g_strdup("20b0")); - benq = g_list_append (benq, g_strdup("20be")); - benq = g_list_append (benq, g_strdup("20c0")); - benq = g_list_append (benq, g_strdup("20de")); - benq = g_list_append (benq, g_strdup("20f8")); - benq = g_list_append (benq, g_strdup("20fc")); - benq = g_list_append (benq, g_strdup("20fe")); - benq = g_list_append (benq, g_strdup("2137")); - benq = g_list_append (benq, g_strdup("2211")); - g_hash_table_insert (scanners, - g_strdup("04a5"), - benq); - - GList* visioneer = NULL; - visioneer = g_list_append (visioneer, g_strdup("0229")); - visioneer = g_list_append (visioneer, g_strdup("0390")); - visioneer = g_list_append (visioneer, g_strdup("0420")); - visioneer = g_list_append (visioneer, g_strdup("0421")); - visioneer = g_list_append (visioneer, g_strdup("0422")); - visioneer = g_list_append (visioneer, g_strdup("0423")); - visioneer = g_list_append (visioneer, g_strdup("0424")); - visioneer = g_list_append (visioneer, g_strdup("0426")); - visioneer = g_list_append (visioneer, g_strdup("0427")); - visioneer = g_list_append (visioneer, g_strdup("0444")); - visioneer = g_list_append (visioneer, g_strdup("0446")); - visioneer = g_list_append (visioneer, g_strdup("0447")); - visioneer = g_list_append (visioneer, g_strdup("0448")); - visioneer = g_list_append (visioneer, g_strdup("0449")); - visioneer = g_list_append (visioneer, g_strdup("044c")); - visioneer = g_list_append (visioneer, g_strdup("0474")); - visioneer = g_list_append (visioneer, g_strdup("0475")); - visioneer = g_list_append (visioneer, g_strdup("0477")); - visioneer = g_list_append (visioneer, g_strdup("0478")); - visioneer = g_list_append (visioneer, g_strdup("0479")); - visioneer = g_list_append (visioneer, g_strdup("047a")); - visioneer = g_list_append (visioneer, g_strdup("047b")); - visioneer = g_list_append (visioneer, g_strdup("047c")); - visioneer = g_list_append (visioneer, g_strdup("048c")); - visioneer = g_list_append (visioneer, g_strdup("048d")); - visioneer = g_list_append (visioneer, g_strdup("048e")); - visioneer = g_list_append (visioneer, g_strdup("048f")); - visioneer = g_list_append (visioneer, g_strdup("0490")); - visioneer = g_list_append (visioneer, g_strdup("0491")); - visioneer = g_list_append (visioneer, g_strdup("0492")); - visioneer = g_list_append (visioneer, g_strdup("0493")); - visioneer = g_list_append (visioneer, g_strdup("0494")); - visioneer = g_list_append (visioneer, g_strdup("0495")); - visioneer = g_list_append (visioneer, g_strdup("0497")); - visioneer = g_list_append (visioneer, g_strdup("0498")); - visioneer = g_list_append (visioneer, g_strdup("0499")); - visioneer = g_list_append (visioneer, g_strdup("049a")); - visioneer = g_list_append (visioneer, g_strdup("049b")); - visioneer = g_list_append (visioneer, g_strdup("049c")); - visioneer = g_list_append (visioneer, g_strdup("049d")); - visioneer = g_list_append (visioneer, g_strdup("04a7")); - visioneer = g_list_append (visioneer, g_strdup("04ac")); - g_hash_table_insert (scanners, - g_strdup("04a7"), - visioneer); - GList* canon = NULL; - canon = g_list_append (canon, g_strdup("1601")); - canon = g_list_append (canon, g_strdup("1602")); - canon = g_list_append (canon, g_strdup("1603")); - canon = g_list_append (canon, g_strdup("1604")); - canon = g_list_append (canon, g_strdup("1606")); - canon = g_list_append (canon, g_strdup("1607")); - canon = g_list_append (canon, g_strdup("1608")); - canon = g_list_append (canon, g_strdup("1609")); - canon = g_list_append (canon, g_strdup("160a")); - canon = g_list_append (canon, g_strdup("160b")); - canon = g_list_append (canon, g_strdup("1706")); - canon = g_list_append (canon, g_strdup("1707")); - canon = g_list_append (canon, g_strdup("1708")); - canon = g_list_append (canon, g_strdup("1709")); - canon = g_list_append (canon, g_strdup("170a")); - canon = g_list_append (canon, g_strdup("170b")); - canon = g_list_append (canon, g_strdup("170c")); - canon = g_list_append (canon, g_strdup("170d")); - canon = g_list_append (canon, g_strdup("170e")); - canon = g_list_append (canon, g_strdup("1712")); - canon = g_list_append (canon, g_strdup("1713")); - canon = g_list_append (canon, g_strdup("1714")); - canon = g_list_append (canon, g_strdup("1715")); - canon = g_list_append (canon, g_strdup("1716")); - canon = g_list_append (canon, g_strdup("1717")); - canon = g_list_append (canon, g_strdup("1718")); - canon = g_list_append (canon, g_strdup("1719")); - canon = g_list_append (canon, g_strdup("171a")); - canon = g_list_append (canon, g_strdup("171b")); - canon = g_list_append (canon, g_strdup("171c")); - canon = g_list_append (canon, g_strdup("1721")); - canon = g_list_append (canon, g_strdup("1722")); - canon = g_list_append (canon, g_strdup("1723")); - canon = g_list_append (canon, g_strdup("1724")); - canon = g_list_append (canon, g_strdup("1725")); - canon = g_list_append (canon, g_strdup("1726")); - canon = g_list_append (canon, g_strdup("1727")); - canon = g_list_append (canon, g_strdup("1728")); - canon = g_list_append (canon, g_strdup("1729")); - canon = g_list_append (canon, g_strdup("172b")); - canon = g_list_append (canon, g_strdup("172c")); - canon = g_list_append (canon, g_strdup("172d")); - canon = g_list_append (canon, g_strdup("172e")); - canon = g_list_append (canon, g_strdup("172f")); - canon = g_list_append (canon, g_strdup("1730")); - canon = g_list_append (canon, g_strdup("1731")); - canon = g_list_append (canon, g_strdup("1732")); - canon = g_list_append (canon, g_strdup("1733")); - canon = g_list_append (canon, g_strdup("1734")); - canon = g_list_append (canon, g_strdup("1735")); - canon = g_list_append (canon, g_strdup("1736")); - canon = g_list_append (canon, g_strdup("173a")); - canon = g_list_append (canon, g_strdup("173b")); - canon = g_list_append (canon, g_strdup("173c")); - canon = g_list_append (canon, g_strdup("173d")); - canon = g_list_append (canon, g_strdup("173e")); - canon = g_list_append (canon, g_strdup("173f")); - canon = g_list_append (canon, g_strdup("1740")); - canon = g_list_append (canon, g_strdup("1741")); - canon = g_list_append (canon, g_strdup("1742")); - canon = g_list_append (canon, g_strdup("1901")); - canon = g_list_append (canon, g_strdup("1904")); - canon = g_list_append (canon, g_strdup("1905")); - canon = g_list_append (canon, g_strdup("1909")); - canon = g_list_append (canon, g_strdup("190a")); - canon = g_list_append (canon, g_strdup("2204")); - canon = g_list_append (canon, g_strdup("2206")); - canon = g_list_append (canon, g_strdup("2207")); - canon = g_list_append (canon, g_strdup("2208")); - canon = g_list_append (canon, g_strdup("220d")); - canon = g_list_append (canon, g_strdup("220e")); - canon = g_list_append (canon, g_strdup("2213")); - canon = g_list_append (canon, g_strdup("221c")); - canon = g_list_append (canon, g_strdup("2220")); - canon = g_list_append (canon, g_strdup("2222")); - canon = g_list_append (canon, g_strdup("262f")); - canon = g_list_append (canon, g_strdup("2630")); - canon = g_list_append (canon, g_strdup("263c")); - canon = g_list_append (canon, g_strdup("263d")); - canon = g_list_append (canon, g_strdup("263e")); - canon = g_list_append (canon, g_strdup("263f")); - canon = g_list_append (canon, g_strdup("264c")); - canon = g_list_append (canon, g_strdup("264d")); - canon = g_list_append (canon, g_strdup("264e")); - canon = g_list_append (canon, g_strdup("264f")); - canon = g_list_append (canon, g_strdup("2659")); - canon = g_list_append (canon, g_strdup("265d")); - canon = g_list_append (canon, g_strdup("265e")); - canon = g_list_append (canon, g_strdup("265f")); - canon = g_list_append (canon, g_strdup("2660")); - canon = g_list_append (canon, g_strdup("2684")); - canon = g_list_append (canon, g_strdup("2686")); - canon = g_list_append (canon, g_strdup("26a3")); - canon = g_list_append (canon, g_strdup("26b0")); - canon = g_list_append (canon, g_strdup("26b4")); - canon = g_list_append (canon, g_strdup("26b5")); - canon = g_list_append (canon, g_strdup("26ec")); - canon = g_list_append (canon, g_strdup("26ed")); - canon = g_list_append (canon, g_strdup("26ee")); - g_hash_table_insert (scanners, - g_strdup("04a9"), - canon); - - GList* nikon = NULL; - nikon = g_list_append (nikon, g_strdup ("4000")); - nikon = g_list_append (nikon, g_strdup ("4001")); - nikon = g_list_append (nikon, g_strdup ("4002")); - g_hash_table_insert (scanners, - g_strdup("04b0"), - nikon); - - GList* epson = NULL; - - // for testing (its a printer not a scanner!) - //epson = g_list_append (epson, g_strdup ("0001")); - - epson = g_list_append (epson, g_strdup("0101")); - epson = g_list_append (epson, g_strdup("0103")); - epson = g_list_append (epson, g_strdup("0104")); - epson = g_list_append (epson, g_strdup("0105")); - epson = g_list_append (epson, g_strdup("0106")); - epson = g_list_append (epson, g_strdup("0107")); - epson = g_list_append (epson, g_strdup("0109")); - epson = g_list_append (epson, g_strdup("010a")); - epson = g_list_append (epson, g_strdup("010b")); - epson = g_list_append (epson, g_strdup("010c")); - epson = g_list_append (epson, g_strdup("010e")); - epson = g_list_append (epson, g_strdup("010f")); - epson = g_list_append (epson, g_strdup("0110")); - epson = g_list_append (epson, g_strdup("0112")); - epson = g_list_append (epson, g_strdup("0114")); - epson = g_list_append (epson, g_strdup("011b")); - epson = g_list_append (epson, g_strdup("011c")); - epson = g_list_append (epson, g_strdup("011d")); - epson = g_list_append (epson, g_strdup("011e")); - epson = g_list_append (epson, g_strdup("011f")); - epson = g_list_append (epson, g_strdup("0120")); - epson = g_list_append (epson, g_strdup("0121")); - epson = g_list_append (epson, g_strdup("0122")); - epson = g_list_append (epson, g_strdup("0126")); - epson = g_list_append (epson, g_strdup("0128")); - epson = g_list_append (epson, g_strdup("0129")); - epson = g_list_append (epson, g_strdup("012a")); - epson = g_list_append (epson, g_strdup("012b")); - epson = g_list_append (epson, g_strdup("012c")); - epson = g_list_append (epson, g_strdup("0135")); - epson = g_list_append (epson, g_strdup("0801")); - epson = g_list_append (epson, g_strdup("0802")); - epson = g_list_append (epson, g_strdup("0805")); - epson = g_list_append (epson, g_strdup("0806")); - epson = g_list_append (epson, g_strdup("0807")); - epson = g_list_append (epson, g_strdup("0808")); - epson = g_list_append (epson, g_strdup("080c")); - epson = g_list_append (epson, g_strdup("080d")); - epson = g_list_append (epson, g_strdup("080e")); - epson = g_list_append (epson, g_strdup("080f")); - epson = g_list_append (epson, g_strdup("0810")); - epson = g_list_append (epson, g_strdup("0811")); - epson = g_list_append (epson, g_strdup("0813")); - epson = g_list_append (epson, g_strdup("0814")); - epson = g_list_append (epson, g_strdup("0815")); - epson = g_list_append (epson, g_strdup("0817")); - epson = g_list_append (epson, g_strdup("0818")); - epson = g_list_append (epson, g_strdup("0819")); - epson = g_list_append (epson, g_strdup("081a")); - epson = g_list_append (epson, g_strdup("081c")); - epson = g_list_append (epson, g_strdup("081d")); - epson = g_list_append (epson, g_strdup("081f")); - epson = g_list_append (epson, g_strdup("0820")); - epson = g_list_append (epson, g_strdup("0827")); - epson = g_list_append (epson, g_strdup("0828")); - epson = g_list_append (epson, g_strdup("0829")); - epson = g_list_append (epson, g_strdup("082a")); - epson = g_list_append (epson, g_strdup("082b")); - epson = g_list_append (epson, g_strdup("082e")); - epson = g_list_append (epson, g_strdup("082f")); - epson = g_list_append (epson, g_strdup("0830")); - epson = g_list_append (epson, g_strdup("0833")); - epson = g_list_append (epson, g_strdup("0834")); - epson = g_list_append (epson, g_strdup("0835")); - epson = g_list_append (epson, g_strdup("0836")); - epson = g_list_append (epson, g_strdup("0837")); - epson = g_list_append (epson, g_strdup("0838")); - epson = g_list_append (epson, g_strdup("0839")); - epson = g_list_append (epson, g_strdup("083a")); - epson = g_list_append (epson, g_strdup("083c")); - epson = g_list_append (epson, g_strdup("0841")); - epson = g_list_append (epson, g_strdup("0843")); - epson = g_list_append (epson, g_strdup("0844")); - epson = g_list_append (epson, g_strdup("0846")); - epson = g_list_append (epson, g_strdup("0847")); - epson = g_list_append (epson, g_strdup("0848")); - epson = g_list_append (epson, g_strdup("0849")); - epson = g_list_append (epson, g_strdup("084a")); - epson = g_list_append (epson, g_strdup("084c")); - epson = g_list_append (epson, g_strdup("084d")); - epson = g_list_append (epson, g_strdup("084f")); - epson = g_list_append (epson, g_strdup("0851")); - epson = g_list_append (epson, g_strdup("0854")); - epson = g_list_append (epson, g_strdup("0856")); - g_hash_table_insert (scanners, - g_strdup("04b8"), - epson); - - GList* fujitsu = NULL; - fujitsu = g_list_append (fujitsu, g_strdup ("1029")); - fujitsu = g_list_append (fujitsu, g_strdup ("1041")); - fujitsu = g_list_append (fujitsu, g_strdup ("1042")); - fujitsu = g_list_append (fujitsu, g_strdup ("1078")); - fujitsu = g_list_append (fujitsu, g_strdup ("1095")); - fujitsu = g_list_append (fujitsu, g_strdup ("1096")); - fujitsu = g_list_append (fujitsu, g_strdup ("1097")); - fujitsu = g_list_append (fujitsu, g_strdup ("10ad")); - fujitsu = g_list_append (fujitsu, g_strdup ("10ae")); - fujitsu = g_list_append (fujitsu, g_strdup ("10af")); - fujitsu = g_list_append (fujitsu, g_strdup ("10c7")); - fujitsu = g_list_append (fujitsu, g_strdup ("10cf")); - fujitsu = g_list_append (fujitsu, g_strdup ("10e0")); - fujitsu = g_list_append (fujitsu, g_strdup ("10e1")); - fujitsu = g_list_append (fujitsu, g_strdup ("10e2")); - fujitsu = g_list_append (fujitsu, g_strdup ("10e6")); - fujitsu = g_list_append (fujitsu, g_strdup ("10e7")); - fujitsu = g_list_append (fujitsu, g_strdup ("10ef")); - fujitsu = g_list_append (fujitsu, g_strdup ("10f2")); - fujitsu = g_list_append (fujitsu, g_strdup ("10fe")); - fujitsu = g_list_append (fujitsu, g_strdup ("1135")); - fujitsu = g_list_append (fujitsu, g_strdup ("114a")); - fujitsu = g_list_append (fujitsu, g_strdup ("114d")); - fujitsu = g_list_append (fujitsu, g_strdup ("114e")); - fujitsu = g_list_append (fujitsu, g_strdup ("114f")); - fujitsu = g_list_append (fujitsu, g_strdup ("1150")); - fujitsu = g_list_append (fujitsu, g_strdup ("1155")); - fujitsu = g_list_append (fujitsu, g_strdup ("1156")); - fujitsu = g_list_append (fujitsu, g_strdup ("116f")); - fujitsu = g_list_append (fujitsu, g_strdup ("1174")); - fujitsu = g_list_append (fujitsu, g_strdup ("1175")); - fujitsu = g_list_append (fujitsu, g_strdup ("1176")); - fujitsu = g_list_append (fujitsu, g_strdup ("1177")); - fujitsu = g_list_append (fujitsu, g_strdup ("1178")); - fujitsu = g_list_append (fujitsu, g_strdup ("117f")); - fujitsu = g_list_append (fujitsu, g_strdup ("119d")); - fujitsu = g_list_append (fujitsu, g_strdup ("119e")); - fujitsu = g_list_append (fujitsu, g_strdup ("119f")); - fujitsu = g_list_append (fujitsu, g_strdup ("11a0")); - fujitsu = g_list_append (fujitsu, g_strdup ("11a2")); - fujitsu = g_list_append (fujitsu, g_strdup ("11ed")); - fujitsu = g_list_append (fujitsu, g_strdup ("11ee")); - fujitsu = g_list_append (fujitsu, g_strdup ("11ef")); - fujitsu = g_list_append (fujitsu, g_strdup ("11f1")); - fujitsu = g_list_append (fujitsu, g_strdup ("11f2")); - fujitsu = g_list_append (fujitsu, g_strdup ("11f3")); - fujitsu = g_list_append (fujitsu, g_strdup ("11f4")); - fujitsu = g_list_append (fujitsu, g_strdup ("11fc")); - g_hash_table_insert (scanners, - g_strdup("04c5"), - fujitsu); - GList* konica = NULL; - konica = g_list_append (konica, g_strdup ("0722")); - g_hash_table_insert (scanners, - g_strdup("04c8"), - konica); - GList* panasonic = NULL; - panasonic = g_list_append (panasonic, g_strdup ("1000")); - panasonic = g_list_append (panasonic, g_strdup ("1001")); - panasonic = g_list_append (panasonic, g_strdup ("1006")); - panasonic = g_list_append (panasonic, g_strdup ("1007")); - panasonic = g_list_append (panasonic, g_strdup ("1009")); - panasonic = g_list_append (panasonic, g_strdup ("100a")); - panasonic = g_list_append (panasonic, g_strdup ("100f")); - panasonic = g_list_append (panasonic, g_strdup ("1010")); - g_hash_table_insert (scanners, - g_strdup("04da"), - panasonic); - - GList* samsung = NULL; - - samsung = g_list_append (samsung, g_strdup ("341b")); - samsung = g_list_append (samsung, g_strdup ("341f")); - samsung = g_list_append (samsung, g_strdup ("3426")); - samsung = g_list_append (samsung, g_strdup ("342a")); - samsung = g_list_append (samsung, g_strdup ("342b")); - samsung = g_list_append (samsung, g_strdup ("342c")); - samsung = g_list_append (samsung, g_strdup ("3433")); - samsung = g_list_append (samsung, g_strdup ("3434")); - samsung = g_list_append (samsung, g_strdup ("343c")); - samsung = g_list_append (samsung, g_strdup ("3434")); - g_hash_table_insert (scanners, - g_strdup("04e8"), - samsung); - - GList* pentax = NULL; - pentax = g_list_append (pentax, g_strdup ("2038")); - g_hash_table_insert (scanners, - g_strdup("04f9"), - pentax); - - GList* apitek = NULL; - apitek = g_list_append (apitek, g_strdup ("0202")); - g_hash_table_insert (scanners, - g_strdup("0553"), - apitek); - - GList* mustek = NULL; - mustek = g_list_append (mustek, g_strdup ("0001")); - mustek = g_list_append (mustek, g_strdup ("0002")); - mustek = g_list_append (mustek, g_strdup ("0006")); - mustek = g_list_append (mustek, g_strdup ("0008")); - mustek = g_list_append (mustek, g_strdup ("0010")); - mustek = g_list_append (mustek, g_strdup ("0210")); - mustek = g_list_append (mustek, g_strdup ("0218")); - mustek = g_list_append (mustek, g_strdup ("0219")); - mustek = g_list_append (mustek, g_strdup ("021a")); - mustek = g_list_append (mustek, g_strdup ("021b")); - mustek = g_list_append (mustek, g_strdup ("021c")); - mustek = g_list_append (mustek, g_strdup ("021d")); - mustek = g_list_append (mustek, g_strdup ("021e")); - mustek = g_list_append (mustek, g_strdup ("021f")); - mustek = g_list_append (mustek, g_strdup ("0409")); - g_hash_table_insert (scanners, - g_strdup("055f"), - mustek); - GList* artec = NULL; - artec = g_list_append (artec, g_strdup ("4002")); - artec = g_list_append (artec, g_strdup ("4003")); - artec = g_list_append (artec, g_strdup ("4004")); - artec = g_list_append (artec, g_strdup ("4005")); - artec = g_list_append (artec, g_strdup ("4006")); - artec = g_list_append (artec, g_strdup ("4007")); - artec = g_list_append (artec, g_strdup ("4009")); - artec = g_list_append (artec, g_strdup ("4010")); - artec = g_list_append (artec, g_strdup ("4011")); - g_hash_table_insert (scanners, - g_strdup("05d8"), - artec); - - GList* microtek = NULL; - microtek = g_list_append (microtek, g_strdup ("0099")); - microtek = g_list_append (microtek, g_strdup ("009a")); - microtek = g_list_append (microtek, g_strdup ("00a3")); - microtek = g_list_append (microtek, g_strdup ("00b6")); - microtek = g_list_append (microtek, g_strdup ("30cf")); - microtek = g_list_append (microtek, g_strdup ("30d4")); - microtek = g_list_append (microtek, g_strdup ("40b3")); - microtek = g_list_append (microtek, g_strdup ("40b8")); - microtek = g_list_append (microtek, g_strdup ("40ca")); - microtek = g_list_append (microtek, g_strdup ("40cb")); - microtek = g_list_append (microtek, g_strdup ("40dd")); - microtek = g_list_append (microtek, g_strdup ("40ff")); - microtek = g_list_append (microtek, g_strdup ("80a3")); - g_hash_table_insert (scanners, - g_strdup("05da"), - microtek); - - GList* avision = NULL; - avision = g_list_append (avision, g_strdup ("0268")); - avision = g_list_append (avision, g_strdup ("026a")); - avision = g_list_append (avision, g_strdup ("0a13")); - avision = g_list_append (avision, g_strdup ("0a15")); - avision = g_list_append (avision, g_strdup ("0a16")); - avision = g_list_append (avision, g_strdup ("0a18")); - avision = g_list_append (avision, g_strdup ("0a19")); - avision = g_list_append (avision, g_strdup ("0a23")); - avision = g_list_append (avision, g_strdup ("0a24")); - avision = g_list_append (avision, g_strdup ("0a25")); - avision = g_list_append (avision, g_strdup ("0a27")); - avision = g_list_append (avision, g_strdup ("0a2a")); - avision = g_list_append (avision, g_strdup ("0a2b")); - avision = g_list_append (avision, g_strdup ("0a2c")); - avision = g_list_append (avision, g_strdup ("0a2d")); - avision = g_list_append (avision, g_strdup ("0a2e")); - avision = g_list_append (avision, g_strdup ("0a2f")); - avision = g_list_append (avision, g_strdup ("0a33")); - avision = g_list_append (avision, g_strdup ("0a3a")); - avision = g_list_append (avision, g_strdup ("0a3c")); - avision = g_list_append (avision, g_strdup ("0a40")); - avision = g_list_append (avision, g_strdup ("0a41")); - avision = g_list_append (avision, g_strdup ("0a45")); - avision = g_list_append (avision, g_strdup ("0a4d")); - avision = g_list_append (avision, g_strdup ("0a4e")); - avision = g_list_append (avision, g_strdup ("0a4f")); - avision = g_list_append (avision, g_strdup ("0a5e")); - avision = g_list_append (avision, g_strdup ("0a61")); - avision = g_list_append (avision, g_strdup ("0a65")); - avision = g_list_append (avision, g_strdup ("0a66")); - avision = g_list_append (avision, g_strdup ("0a68")); - avision = g_list_append (avision, g_strdup ("0a82")); - avision = g_list_append (avision, g_strdup ("0a84")); - avision = g_list_append (avision, g_strdup ("0a93")); - avision = g_list_append (avision, g_strdup ("0a94")); - avision = g_list_append (avision, g_strdup ("0aa1")); - avision = g_list_append (avision, g_strdup ("1a35")); - g_hash_table_insert (scanners, - g_strdup("0638"), - avision); - GList* minolta = NULL; - minolta = g_list_append (minolta, g_strdup ("4004")); - minolta = g_list_append (minolta, g_strdup ("400d")); - minolta = g_list_append (minolta, g_strdup ("400e")); - g_hash_table_insert (scanners, - g_strdup("0686"), - minolta); - - GList* agfa = NULL; - agfa = g_list_append (agfa, g_strdup ("0001")); - agfa = g_list_append (agfa, g_strdup ("0002")); - agfa = g_list_append (agfa, g_strdup ("0100")); - agfa = g_list_append (agfa, g_strdup ("2061")); - agfa = g_list_append (agfa, g_strdup ("208d")); - agfa = g_list_append (agfa, g_strdup ("208f")); - agfa = g_list_append (agfa, g_strdup ("2091")); - agfa = g_list_append (agfa, g_strdup ("2093")); - agfa = g_list_append (agfa, g_strdup ("2095")); - agfa = g_list_append (agfa, g_strdup ("2097")); - agfa = g_list_append (agfa, g_strdup ("20fd")); - agfa = g_list_append (agfa, g_strdup ("20ff")); - g_hash_table_insert (scanners, - g_strdup("06bd"), - minolta); - - GList* umax_2 = NULL; - umax_2 = g_list_append (umax_2, g_strdup ("0020")); - g_hash_table_insert (scanners, - g_strdup("06dc"), - umax_2); - - GList* plustek = NULL; - - plustek = g_list_append (plustek, g_strdup ("0001")); - plustek = g_list_append (plustek, g_strdup ("0010")); - plustek = g_list_append (plustek, g_strdup ("0011")); - plustek = g_list_append (plustek, g_strdup ("0013")); - plustek = g_list_append (plustek, g_strdup ("0015")); - plustek = g_list_append (plustek, g_strdup ("0017")); - plustek = g_list_append (plustek, g_strdup ("0400")); - plustek = g_list_append (plustek, g_strdup ("0401")); - plustek = g_list_append (plustek, g_strdup ("0402")); - plustek = g_list_append (plustek, g_strdup ("0403")); - plustek = g_list_append (plustek, g_strdup ("040b")); - plustek = g_list_append (plustek, g_strdup ("040e")); - plustek = g_list_append (plustek, g_strdup ("0412")); - plustek = g_list_append (plustek, g_strdup ("0413")); - plustek = g_list_append (plustek, g_strdup ("0422")); - plustek = g_list_append (plustek, g_strdup ("0454")); - plustek = g_list_append (plustek, g_strdup ("045f")); - plustek = g_list_append (plustek, g_strdup ("0462")); - plustek = g_list_append (plustek, g_strdup ("0900")); - g_hash_table_insert (scanners, - g_strdup("07b3"), - plustek); - - GList* corex = NULL; - corex = g_list_append (corex, g_strdup ("0002")); - corex = g_list_append (corex, g_strdup ("0005")); - g_hash_table_insert (scanners, - g_strdup("08f0"), - corex); - - GList* xerox = NULL; - xerox = g_list_append (xerox, g_strdup ("3d5d")); - xerox = g_list_append (xerox, g_strdup ("3da4")); - xerox = g_list_append (xerox, g_strdup ("420c")); - xerox = g_list_append (xerox, g_strdup ("4265")); - xerox = g_list_append (xerox, g_strdup ("4293")); - xerox = g_list_append (xerox, g_strdup ("4294")); - g_hash_table_insert (scanners, - g_strdup("0924"), - xerox); - - GList* pentax_2 = NULL; - pentax_2 = g_list_append (pentax_2, g_strdup ("3210")); - g_hash_table_insert (scanners, - g_strdup("0a17"), - pentax_2); - - GList* portable = NULL; - portable = g_list_append (portable, g_strdup ("1000")); - g_hash_table_insert (scanners, - g_strdup("0a53"), - portable); - - GList* syscan = NULL; - syscan = g_list_append (syscan, g_strdup ("4600")); - syscan = g_list_append (syscan, g_strdup ("4802")); - syscan = g_list_append (syscan, g_strdup ("4803")); - syscan = g_list_append (syscan, g_strdup ("480c")); - syscan = g_list_append (syscan, g_strdup ("4810")); - syscan = g_list_append (syscan, g_strdup ("6620")); - g_hash_table_insert (scanners, - g_strdup("0a82"), - syscan); - - GList* canon_2 = NULL; - canon_2 = g_list_append (canon_2, g_strdup ("160c")); - canon_2 = g_list_append (canon_2, g_strdup ("160f")); - canon_2 = g_list_append (canon_2, g_strdup ("1614")); - canon_2 = g_list_append (canon_2, g_strdup ("1617")); - canon_2 = g_list_append (canon_2, g_strdup ("1618")); - canon_2 = g_list_append (canon_2, g_strdup ("161a")); - canon_2 = g_list_append (canon_2, g_strdup ("161b")); - canon_2 = g_list_append (canon_2, g_strdup ("161d")); - canon_2 = g_list_append (canon_2, g_strdup ("1620")); - canon_2 = g_list_append (canon_2, g_strdup ("1622")); - canon_2 = g_list_append (canon_2, g_strdup ("1623")); - canon_2 = g_list_append (canon_2, g_strdup ("1624")); - canon_2 = g_list_append (canon_2, g_strdup ("1626")); - canon_2 = g_list_append (canon_2, g_strdup ("162b")); - canon_2 = g_list_append (canon_2, g_strdup ("1638")); - canon_2 = g_list_append (canon_2, g_strdup ("1639")); - g_hash_table_insert (scanners, - g_strdup("1083"), - canon_2); - - GList* digital = NULL; - digital = g_list_append (digital, g_strdup ("0001")); - g_hash_table_insert (scanners, - g_strdup("1183"), - digital); - - GList* konica_2 = NULL; - konica_2 = g_list_append (konica_2, g_strdup ("2089")); - g_hash_table_insert (scanners, - g_strdup("132b"), - konica_2); - - GList* umax = NULL; - umax = g_list_append (umax, g_strdup ("0010")); - umax = g_list_append (umax, g_strdup ("0030")); - umax = g_list_append (umax, g_strdup ("0050")); - umax = g_list_append (umax, g_strdup ("0060")); - umax = g_list_append (umax, g_strdup ("0070")); - umax = g_list_append (umax, g_strdup ("0130")); - umax = g_list_append (umax, g_strdup ("0160")); - umax = g_list_append (umax, g_strdup ("0230")); - g_hash_table_insert (scanners, - g_strdup("1606"), - umax); - - GList* docketport = NULL; - docketport = g_list_append (docketport, g_strdup ("4810")); - g_hash_table_insert (scanners, - g_strdup("1dcc"), - docketport); - - GList* dell = NULL; - dell = g_list_append (dell, g_strdup ("5105")); - dell = g_list_append (dell, g_strdup ("5124")); - dell = g_list_append (dell, g_strdup ("5250")); - g_hash_table_insert (scanners, - g_strdup("413c"), - dell); -} diff --git a/src/udev-mgr.c b/src/udev-mgr.c deleted file mode 100644 index 5f197d6..0000000 --- a/src/udev-mgr.c +++ /dev/null @@ -1,546 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -#include - -#include - -#include "udev-mgr.h" -#include "sane-rules.h" - -static void udevice_mgr_device_list_iterator (gpointer data, - gpointer userdata); -static void udev_mgr_uevent_cb (GUdevClient *client, - gchar *action, - GUdevDevice *device, - gpointer user_data); -static void udev_mgr_update_menuitems (UdevMgr* self); -static void udev_mgr_check_if_usb_device_is_supported (UdevMgr* self, - GUdevDevice *device, - UdevMgrDeviceAction action); -static void udev_mgr_handle_webcam (UdevMgr* self, - GUdevDevice* device, - UdevMgrDeviceAction action); -static void udev_mgr_handle_scsi_device (UdevMgr* self, - GUdevDevice* device, - UdevMgrDeviceAction action); - -static void udev_mgr_cleanup_lists(gpointer data, gpointer self); -static void udev_mgr_cleanup_entries(gpointer data, gpointer self); - - -static void debug_device (UdevMgr* self, - GUdevDevice* device, - UdevMgrDeviceAction action); - -static gchar* format_device_name (UdevMgr* self, - const gchar* brand, - const gchar* generic, - const gchar* branded) G_GNUC_WARN_UNUSED_RESULT; -struct _UdevMgr -{ - GObject parent_instance; - DbusmenuMenuitem* scanner_item; - DbusmenuMenuitem* webcam_item; - GUdevClient* client; - GHashTable* supported_usb_scanners; - GHashTable* supported_scsi_scanners; - GHashTable* scanners_present; - GHashTable* webcams_present; -}; - -const char *subsystems[3] = {"usb", "scsi", "video4linux"}; -const gchar* usb_subsystem = "usb"; -const gchar* scsi_subsystem = "scsi"; -const gchar* video4linux_subsystem = "video4linux"; - - -G_DEFINE_TYPE (UdevMgr, udev_mgr, G_TYPE_OBJECT); - -static void -udev_mgr_init (UdevMgr* self) -{ - self->client = NULL; - self->supported_usb_scanners = NULL; - self->scanners_present = NULL; - self->webcams_present = NULL; - self->client = g_udev_client_new (subsystems); - self->supported_usb_scanners = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - (GDestroyNotify)udev_mgr_cleanup_lists); - self->supported_scsi_scanners = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - (GDestroyNotify)udev_mgr_cleanup_lists); - self->scanners_present = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_free); - self->webcams_present = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_free); - - // load into memory all supported scanners ... - populate_usb_scanners (self->supported_usb_scanners); - populate_scsi_scanners (self->supported_scsi_scanners); - g_signal_connect (G_OBJECT (self->client), - "uevent", - G_CALLBACK (udev_mgr_uevent_cb), - self); -} - -static void -udev_mgr_cleanup_lists(gpointer data, gpointer self) -{ - GList* scanners = (GList*)data; - g_list_foreach (scanners, udev_mgr_cleanup_entries, NULL); - g_list_free(scanners); -} - -static void -udev_mgr_cleanup_entries(gpointer data, gpointer self) -{ - gchar* entry = (gchar*)data; - g_free(entry); -} - -static void -udev_mgr_finalize (GObject *object) -{ - UdevMgr* self = UDEV_MGR (object); - g_hash_table_destroy (self->supported_scsi_scanners); - g_hash_table_destroy (self->supported_usb_scanners); - g_hash_table_destroy (self->scanners_present); - g_hash_table_destroy (self->webcams_present); - G_OBJECT_CLASS (udev_mgr_parent_class)->finalize (object); -} - -static void -udev_mgr_class_init (UdevMgrClass *klass) -{ - GObjectClass* object_class = G_OBJECT_CLASS (klass); - object_class->finalize = udev_mgr_finalize; -} - -static void -udevice_mgr_device_list_iterator (gpointer data, gpointer userdata) -{ - g_return_if_fail (G_UDEV_IS_DEVICE (data)); - g_return_if_fail (UDEV_IS_MGR (userdata)); - - UdevMgr* self = UDEV_MGR (userdata); - - GUdevDevice* device = G_UDEV_DEVICE (data); - - const gchar* subsystem = NULL; - subsystem = g_udev_device_get_subsystem (device); - - if (g_strcmp0 (subsystem, "usb") == 0){ - udev_mgr_check_if_usb_device_is_supported (self, device, ADD); - } - else if (g_strcmp0 (subsystem, "video4linux") == 0){ - udev_mgr_handle_webcam (self, device, ADD); - } - else if (g_strcmp0 (subsystem, "scsi") == 0){ - udev_mgr_handle_scsi_device (self, device, ADD); - } - - g_object_unref (device); -} - - -static void udev_mgr_update_menuitems (UdevMgr* self) -{ - dbusmenu_menuitem_property_set_bool (self->scanner_item, - DBUSMENU_MENUITEM_PROP_VISIBLE, - g_hash_table_size (self->scanners_present) > 0); - - dbusmenu_menuitem_property_set_bool (self->webcam_item, - DBUSMENU_MENUITEM_PROP_VISIBLE, - g_hash_table_size (self->webcams_present) > 0); - -} - -static void udev_mgr_uevent_cb (GUdevClient *client, - gchar *action, - GUdevDevice *device, - gpointer user_data) -{ - g_return_if_fail (UDEV_IS_MGR (user_data)); - UdevMgr* self = UDEV_MGR (user_data); - g_return_if_fail (device != NULL); - - g_debug ("just received a UEVENT with an action : %s", action); - - UdevMgrDeviceAction udev_mgr_action = ADD; - - if (g_strcmp0 (action, "remove") == 0){ - udev_mgr_action = REMOVE; - } - - const gchar* subsystem = NULL; - subsystem = g_udev_device_get_subsystem (device); - - if (g_strcmp0 (subsystem, "usb") == 0){ - udev_mgr_check_if_usb_device_is_supported (self, - device, - udev_mgr_action); - } - else if (g_strcmp0 (subsystem, "video4linux") == 0){ - udev_mgr_handle_webcam (self, device, udev_mgr_action); - } - else if (g_strcmp0 (subsystem, "scsi") == 0){ - udev_mgr_handle_scsi_device (self, device, udev_mgr_action); - } -} - - -static void -udev_mgr_handle_webcam (UdevMgr* self, - GUdevDevice* device, - UdevMgrDeviceAction action) -{ - if (FALSE) - debug_device (self, device, action); - - const gchar* vendor; - const gchar* product; - - vendor = g_udev_device_get_property (device, "ID_VENDOR_ID"); - product = g_udev_device_get_property (device, "ID_MODEL_ID"); - - if (!vendor || !product) { - return; - } - - if (action == REMOVE){ - if (g_hash_table_lookup (self->webcams_present, product) == NULL){ - g_warning ("Got a remove event on a webcam device but we don't have that device in our webcam cache"); - return; - } - g_hash_table_remove (self->webcams_present, - product); - dbusmenu_menuitem_property_set (self->webcam_item, - DBUSMENU_MENUITEM_PROP_LABEL, - _("Webcam")); - } - else { - if (g_hash_table_lookup (self->webcams_present, product) != NULL){ - g_warning ("Got an ADD event on a webcam device but we already have that device in our webcam cache"); - return; - } - - const gchar* manufacturer = NULL; - manufacturer = g_udev_device_get_property (device, "ID_VENDOR"); - - if (manufacturer != NULL){ - gchar * label = format_device_name(self, manufacturer, _("Webcam"), _("%s Webcam")); - dbusmenu_menuitem_property_set (self->webcam_item, - DBUSMENU_MENUITEM_PROP_LABEL, - label); - g_free(label); - } - - g_hash_table_insert (self->webcams_present, - g_strdup (product), - g_strdup (vendor)); - } - udev_mgr_update_menuitems (self); -} - -static void -debug_device (UdevMgr* self, - GUdevDevice* device, - UdevMgrDeviceAction action) -{ - const gchar* vendor; - const gchar* product; - const gchar* number; - const gchar* name; - const gchar* manufacturer; - - vendor = g_udev_device_get_property (device, "ID_VENDOR_ID"); - manufacturer = g_udev_device_get_property (device, "ID_VENDOR"); - product = g_udev_device_get_property (device, "ID_MODEL_ID"); - number = g_udev_device_get_number (device); - name = g_udev_device_get_name (device); - - g_debug ("%s device vendor id %s , product id of %s , number of %s and name of %s", - g_strdup(manufacturer), - g_strdup(vendor), - g_strdup(product), - g_strdup(number), - g_strdup(name)); - - /*const gchar *const *list; - const gchar *const *iter; - char propstr[500]; - guint32 namelen = 0, i; - - list = g_udev_device_get_property_keys(device); - - for (iter = list; iter && *iter; iter++) { - if (strlen(*iter) > namelen) - namelen = strlen(*iter); - } - namelen++; - - for (iter = list; iter && *iter; iter++) { - strcpy(propstr, *iter); - strcat(propstr, ":"); - for (i = 0; i < namelen - strlen(*iter); i++) - strcat(propstr, " "); - strcat(propstr, g_udev_device_get_property(device, *iter)); - g_debug("%s", propstr); - }*/ -} -// TODO SCSI is not dynamic right ? -// i.e. just need to handle startup scan. -static void udev_mgr_handle_scsi_device (UdevMgr* self, - GUdevDevice* device, - UdevMgrDeviceAction action) -{ - const gchar* type = NULL; - type = g_udev_device_get_property (device, "TYPE"); - - if (!type) { - return; - } - - // apparently anything thats type 6 and SCSI is a Scanner - if (g_strcmp0 (type, "6") == 0 && action == ADD){ - - const gchar* manufacturer = NULL; - manufacturer = g_udev_device_get_property (device, "ID_VENDOR"); - - if (manufacturer != NULL){ - gchar * label = format_device_name(self, manufacturer, _("Scanner"), _("%s Scanner")); - dbusmenu_menuitem_property_set (self->scanner_item, - DBUSMENU_MENUITEM_PROP_LABEL, - label); - g_free(label); - } - - gchar* random_scanner_name = g_strdup_printf("%p--scanner", self); - g_hash_table_insert (self->scanners_present, - random_scanner_name, - g_strdup("Scanner")); - udev_mgr_update_menuitems (self); - return; - } - - // We only care about type 3 for the special cases below - if (g_strcmp0 (type, "3") != 0){ - return; - } - - const gchar* vendor = NULL; - vendor = g_udev_device_get_property (device, "VENDOR"); - - if (vendor == NULL) - return; - - GList* vendor_list = NULL; - vendor_list = g_hash_table_lookup (self->supported_scsi_scanners, - (gpointer)vendor); - if (vendor_list == NULL) - return; - - const gchar* model_id = NULL; - model_id = g_udev_device_get_property (device, "MODEL"); - - if (model_id == NULL) - return; - - GList* model_entry = NULL; - model_entry = g_list_find_custom (vendor_list, - model_id, - (GCompareFunc)g_strcmp0); - - if (model_entry != NULL){ - if (action == REMOVE){ - if (g_hash_table_lookup (self->scanners_present, g_strdup(vendor)) == NULL){ - g_warning ("Got an REMOVE event on a scanner device but we dont have that device in our scanners cache"); - } - else{ - g_hash_table_remove (self->scanners_present, vendor); - dbusmenu_menuitem_property_set (self->scanner_item, - DBUSMENU_MENUITEM_PROP_LABEL, - _("Scanner")); - - } - } - else{ - if (g_hash_table_lookup (self->scanners_present, g_strdup(vendor)) != NULL){ - g_warning ("Got an ADD event on a scanner device but we already have that device in our scanners cache"); - } - else{ - const gchar* manufacturer = NULL; - manufacturer = g_udev_device_get_property (device, "ID_VENDOR"); - - if (manufacturer != NULL){ - gchar * label = format_device_name(self, manufacturer, _("Scanner"), _("%s Scanner")); - dbusmenu_menuitem_property_set (self->scanner_item, - DBUSMENU_MENUITEM_PROP_LABEL, - label); - g_free(label); - } - g_hash_table_insert (self->scanners_present, - g_strdup(vendor), - g_strdup(model_id)); - } - } - udev_mgr_update_menuitems (self); - } -} - -static void -udev_mgr_check_if_usb_device_is_supported (UdevMgr* self, - GUdevDevice *device, - UdevMgrDeviceAction action) -{ - const gchar* vendor = NULL; - //debug_device (self, device, action); - - vendor = g_udev_device_get_property (device, "ID_VENDOR_ID"); - - if (vendor == NULL) - return; - - //g_debug ("vendor = %s", vendor); - - GList* vendor_list = NULL; - vendor_list = g_hash_table_lookup (self->supported_usb_scanners, - (gpointer)vendor); - if (vendor_list == NULL) - return; - - const gchar* model_id = NULL; - model_id = g_udev_device_get_property (device, "ID_MODEL_ID"); - - if (model_id == NULL) - return; - - GList* model_entry = NULL; - model_entry = g_list_find_custom(vendor_list, model_id, (GCompareFunc)g_strcmp0); - - if (model_entry != NULL){ - if (action == REMOVE){ - if (g_hash_table_lookup (self->scanners_present, g_strdup(vendor)) == NULL){ - g_warning ("Got an REMOVE event on a scanner device but we dont have that device in our scanners cache"); - } - else{ - g_hash_table_remove (self->scanners_present, vendor); - dbusmenu_menuitem_property_set (self->scanner_item, - DBUSMENU_MENUITEM_PROP_LABEL, - _("Scanner")); - } - } - else{ - if (g_hash_table_lookup (self->scanners_present, g_strdup(vendor)) != NULL){ - g_warning ("Got an ADD event on a scanner device but we already have that device in our scanners cache"); - } - else{ - const gchar* manufacturer = NULL; - - manufacturer = g_udev_device_get_property (device, "ID_VENDOR"); - if (manufacturer != NULL){ - gchar * label = format_device_name(self, manufacturer, _("Scanner"), _("%s Scanner")); - dbusmenu_menuitem_property_set (self->scanner_item, - DBUSMENU_MENUITEM_PROP_LABEL, - label); - g_free(label); - } - - g_hash_table_insert (self->scanners_present, - g_strdup(vendor), - g_strdup(model_id)); - } - } - udev_mgr_update_menuitems (self); - } -} - -UdevMgr* udev_mgr_new (DbusmenuMenuitem* scanner, - DbusmenuMenuitem* webcam) -{ - UdevMgr* mgr = g_object_new (UDEV_TYPE_MGR, NULL); - mgr->scanner_item = scanner; - mgr->webcam_item = webcam; - - // Check for USB devices - GList* usb_devices_available = NULL; - usb_devices_available = g_udev_client_query_by_subsystem (mgr->client, - usb_subsystem); - if (usb_devices_available != NULL){ - g_list_foreach (usb_devices_available, - udevice_mgr_device_list_iterator, - mgr); - - g_list_free (usb_devices_available); - } - // Check for webcams - GList* video_devices_available = NULL; - video_devices_available = g_udev_client_query_by_subsystem (mgr->client, - video4linux_subsystem); - if (video_devices_available != NULL){ - g_list_foreach (video_devices_available, - udevice_mgr_device_list_iterator, - mgr); - - g_list_free (video_devices_available); - } - // Check for SCSI devices - GList* scsi_devices_available = NULL; - scsi_devices_available = g_udev_client_query_by_subsystem (mgr->client, - scsi_subsystem); - if (scsi_devices_available != NULL){ - g_list_foreach (scsi_devices_available, - udevice_mgr_device_list_iterator, - mgr); - g_list_free (scsi_devices_available); - } - return mgr; -} - -static gchar* format_device_name (UdevMgr* self, - const gchar* brand, - const gchar* generic, - const gchar* branded) -{ - // We don't want to accommodate long names - if (strlen(brand) > 7) - return g_strdup(generic); - - gint i = 0; - - // If it contains something other than an alphabetic entry ignore it. - for(i = 0; i < sizeof(brand); i++){ - if ( !g_ascii_isalpha (brand[i]) ) - return g_strdup(generic); - } - - gchar* lowered = g_ascii_strdown (brand, -1); - lowered[0] = g_ascii_toupper (lowered[0]); - gchar* label = g_strdup_printf(branded, lowered); - g_free (lowered); - return label; -} diff --git a/src/udev-mgr.h b/src/udev-mgr.h deleted file mode 100644 index 2e57cff..0000000 --- a/src/udev-mgr.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -#ifndef _UDEV_MGR_H_ -#define _UDEV_MGR_H_ - -#include -#include - -#include -#include - -G_BEGIN_DECLS - -#define UDEV_TYPE_MGR (udev_mgr_get_type ()) -#define UDEV_MGR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UDEV_TYPE_MGR, UdevMgr)) -#define UDEV_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UDEV_TYPE_MGR, UdevMgrClass)) -#define UDEV_IS_MGR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UDEV_TYPE_MGR)) -#define UDEV_IS_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UDEV_TYPE_MGR)) -#define UDEV_MGR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UDEV_TYPE_MGR, UdevMgrClass)) - -typedef struct _UdevMgrClass UdevMgrClass; -typedef struct _UdevMgr UdevMgr; - -struct _UdevMgrClass -{ - GObjectClass parent_class; -}; - - -GType udev_mgr_get_type (void) G_GNUC_CONST; -UdevMgr* udev_mgr_new (DbusmenuMenuitem* scanner_item, - DbusmenuMenuitem* webcam_item); - -typedef enum { - ADD, - REMOVE -}UdevMgrDeviceAction; - -G_END_DECLS - -#endif /* _UDEV_MGR_H_ */ -- cgit v1.2.3 From d2b044691c8c13c5b6f66ffdea492be9451053c4 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 4 Jun 2012 19:22:36 -0500 Subject: remove now-unused file accounts-service-user.xml --- src/Makefile.am | 13 +- src/accounts-service-user.xml | 689 ------------------------------------------ 2 files changed, 2 insertions(+), 700 deletions(-) delete mode 100644 src/accounts-service-user.xml (limited to 'src/Makefile.am') diff --git a/src/Makefile.am b/src/Makefile.am index d99c2df..c2bf65d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,8 +24,7 @@ libsession_la_SOURCES = \ dbusmenu-shared.h \ user-widget.c \ user-widget.h \ - accounts-service-client.h \ - accounts-service-user-client.h + accounts-service-client.h libsession_la_CFLAGS = \ $(APPLET_CFLAGS) \ $(COVERAGE_CFLAGS) \ @@ -71,13 +70,6 @@ accounts-service-client.h: $(srcdir)/accounts-service.xml --output=accounts-service-client.h \ $(srcdir)/accounts-service.xml -accounts-service-user-client.h: $(srcdir)/accounts-service-user.xml - dbus-binding-tool \ - --prefix=_accounts_service_user_client \ - --mode=glib-client \ - --output=accounts-service-user-client.h \ - $(srcdir)/accounts-service-user.xml - upower-client.h: $(srcdir)/upower.xml dbus-binding-tool \ --prefix=_upower_client \ @@ -170,8 +162,7 @@ BUILT_SOURCES = \ gen-session-dbus.xml.c \ gen-session-dbus.xml.h \ upower-client.h \ - accounts-service-client.h \ - accounts-service-user-client.h + accounts-service-client.h EXTRA_DIST += \ org.freedesktop.ConsoleKit.Manager.xml \ diff --git a/src/accounts-service-user.xml b/src/accounts-service-user.xml deleted file mode 100644 index bd4cb21..0000000 --- a/src/accounts-service-user.xml +++ /dev/null @@ -1,689 +0,0 @@ - - - - - - - - - - The new username. - - - - - - - Sets the users username. Note that it is usually not allowed - to have multiple users with the same username. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.user-administration - To change the username of any user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new name, typically in the form "Firstname Lastname". - - - - - - - Sets the users real name. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.change-own-user-data - To change his own name - - - org.freedesktop.accounts.user-administration - To change the name of another user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new email address. - - - - - - - Sets the users email address. - - - Note that setting an email address in the AccountsService is - not the same as configuring a mail client. Mail clients might - default to email address that is configured here, though. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.change-own-user-data - To change his own email address - - - org.freedesktop.accounts.user-administration - To change the email address of another user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new language, as a locale specification like "de_DE.UTF-8". - - - - - - - Sets the users language. - - - The expectation is that display managers will start the - users session with this locale. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.change-own-user-data - To change his own language - - - org.freedesktop.accounts.user-administration - To change the language of another user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new location as a freeform string. - - - - - - - Sets the users location. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.change-own-user-data - To change his own location - - - org.freedesktop.accounts.user-administration - To change the location of another user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new homedir as an absolute path. - - - - - - - Sets the users home directory. - - - Note that changing the users home directory moves all the content - from the old location to the new one, and is potentially an - expensive operation. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.user-administration - To change the home directory of a user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new user shell. - - - - - - - Sets the users shell. - - - Note that setting the shell to a non-allowed program may - prevent the user from logging in. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.user-administration - To change the shell of a user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The absolute filename of a png file to use as the users icon. - - - - - - - Sets the users icon. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.change-own-user-data - To change his own icon - - - org.freedesktop.accounts.user-administration - To change the icon of another user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - Whether to lock or unlock the users account. - - - - - - - Locks or unlocks a users account. - - - Locking an account prevents the user from logging in. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.user-administration - To lock or unlock user accounts - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new account type, encoded as an integer: - - - 0 - Standard user - - - 1 - Administrator - - - 2 - Supervised user - - - - - - - - - Changes the users account type. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.user-administration - To change an account type - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new password mode, encoded as an integer: - - - 0 - Regular password - - - 1 - Password must be set at next login - - - 2 - No password - - - - - - - - - Changes the users password mode. - - - Note that changing the password mode has the side-effect of - unlocking the account. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.user-administration - To change a users password mode - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The crypted password. - - - - - - - The password hint. - - - - - - - Sets a new password for this user. - - - Note that setting a password has the side-effect of - unlocking the account. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.user-administration - To change the password of a user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - Whether to enable automatic login for this user. - - - - - - - Enables or disables automatic login for a user. - - - Note that usually only one user can have automatic login - enabled, so turning it on for a user will disable it for - the previously configured autologin user. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.set-login-option - To change the login screen configuration - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - The uid of the user. - - - - - - - - - - The username of the user. - - - - - - - - - - The users real name. - - - - - - - - - - The users account type, encoded as an integer: - - - 0 - Standard user - - - 1 - Administrator - - - 2 - Supervised user - - - - - - - - - - - - The users home directory. - - - - - - - - - - The users shell. - - - - - - - - - - The email address. - - - - - - - - - - The users language, as a locale specification like "de_DE.UTF-8". - - - - - - - - - - The users location. - - - - - - - - - - How often the user has logged in. - - - - - - - - - - The filename of a png file containing the users icon. - - - - - - - - - - Whether the users account is locked. - - - - - - - - - - The password mode for the user account, encoded as an integer: - - - 0 - Regular password - - - 1 - Password must be set at next login - - - 2 - No password - - - - - - - - - - - - The password hint for the user. - - - - - - - - - - Whether automatic login is enabled for the user. - - - - - - - - - - Emitted when the user is changed. - - - - - - - -- cgit v1.2.3 From d95d729276b77016d07a04f75efdb5ba7b352b96 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sat, 9 Jun 2012 10:45:38 -0500 Subject: use gdbus-codegen for the UPower dbus interaction --- src/Makefile.am | 19 +++-- src/device-menu-mgr.c | 216 ++++++++++++++++++++------------------------------ 2 files changed, 99 insertions(+), 136 deletions(-) (limited to 'src/Makefile.am') diff --git a/src/Makefile.am b/src/Makefile.am index c2bf65d..cfe083c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -70,12 +70,16 @@ accounts-service-client.h: $(srcdir)/accounts-service.xml --output=accounts-service-client.h \ $(srcdir)/accounts-service.xml -upower-client.h: $(srcdir)/upower.xml - dbus-binding-tool \ - --prefix=_upower_client \ - --mode=glib-client \ - --output=upower-client.h \ - $(srcdir)/upower.xml +dbus_upower_sources = \ + dbus-upower.c \ + dbus-upower.h + +$(dbus_upower_sources): upower.xml + gdbus-codegen \ + --interface-prefix org.freedesktop \ + --c-namespace IndicatorSession \ + --generate-c-code dbus-upower \ + $^ gen-%.xml.c: %.xml @echo "Building $@ from $<" @@ -92,6 +96,7 @@ gen-%.xml.h: %.xml ################# indicator_session_service_SOURCES = \ + $(dbus_upower_sources) \ lock-helper.c \ lock-helper.h \ session-service.c \ @@ -155,13 +160,13 @@ endif ############### BUILT_SOURCES = \ + $(dbus_upower_sources) \ consolekit-manager-client.h \ consolekit-seat-client.h \ consolekit-session-client.h \ display-manager-client.h \ gen-session-dbus.xml.c \ gen-session-dbus.xml.h \ - upower-client.h \ accounts-service-client.h EXTRA_DIST += \ diff --git a/src/device-menu-mgr.c b/src/device-menu-mgr.c index 73b6ed2..9cfb913 100644 --- a/src/device-menu-mgr.c +++ b/src/device-menu-mgr.c @@ -25,12 +25,12 @@ with this program. If not, see . #include #include +#include "dbus-upower.h" #include "device-menu-mgr.h" #include "settings-helper.h" #include "dbus-shared-names.h" #include "dbusmenu-shared.h" #include "lock-helper.h" -#include "upower-client.h" #define UP_ADDRESS "org.freedesktop.UPower" #define UP_OBJECT "/org/freedesktop/UPower" @@ -51,16 +51,13 @@ struct _DeviceMenuMgr DbusmenuMenuitem * suspend_mi; DbusmenuMenuitem * lock_mi; - DBusGProxy * up_main_proxy; - DBusGProxy * up_prop_proxy; - gboolean can_hibernate; gboolean can_suspend; gboolean allow_hibernate; gboolean allow_suspend; - DBusGProxyCall * suspend_call; - DBusGProxyCall * hibernate_call; + IndicatorSessionUPower * upower_proxy; + GCancellable * cancellable; }; static void setup_up (DeviceMenuMgr* self); @@ -96,8 +93,8 @@ 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->up_main_proxy); - g_clear_object (&self->up_prop_proxy); + g_clear_object (&self->upower_proxy); + g_clear_object (&self->cancellable); G_OBJECT_CLASS (device_menu_mgr_parent_class)->finalize (object); } @@ -141,28 +138,20 @@ screensaver_keybinding_changed (GSettings * settings, } -/* Let's put this machine to sleep with some hints on how it should sleep. */ -static void -machine_sleep_with_context (DeviceMenuMgr* self, const gchar* type) -{ - if (self->up_main_proxy == NULL) - { - g_warning("Cannot %s because no upower proxy", type); - } - else - { - dbus_g_proxy_begin_call (self->up_main_proxy, type, - NULL, NULL, NULL, - G_TYPE_INVALID); - } -} - static void machine_sleep_from_suspend (DbusmenuMenuitem * mi G_GNUC_UNUSED, guint timestamp G_GNUC_UNUSED, gpointer userdata) { - machine_sleep_with_context (DEVICE_MENU_MGR(userdata), "Suspend"); + 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 @@ -170,120 +159,90 @@ machine_sleep_from_hibernate (DbusmenuMenuitem * mi G_GNUC_UNUSED, guint timestamp G_GNUC_UNUSED, gpointer userdata) { - machine_sleep_with_context (DEVICE_MENU_MGR(userdata), "Hibernate"); + 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 -rebuild_if_flag_changed (DeviceMenuMgr * mgr, GError * error, gboolean * setme, gboolean value) +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 ("Unable to get information on what's allowed from UPower: %s", error->message); + g_warning ("%s: %s", G_STRFUNC, error->message); + g_error_free (error); } - else if (*setme != value) + else if (mgr->allow_suspend != allowed) { - *setme = value; + mgr->allow_suspend = allowed; device_menu_mgr_rebuild_items (mgr); } } -/* When allow-suspend changes, rebuild the menus */ -static void -allowed_suspend_cb (DBusGProxy * proxy G_GNUC_UNUSED, - gboolean allow_suspend, - GError * error, - gpointer userdata) -{ - DeviceMenuMgr * mgr = DEVICE_MENU_MGR (userdata); - rebuild_if_flag_changed (mgr, error, &mgr->allow_suspend, allow_suspend); -} - /* When allow-hibernate changes, rebuild the menus */ static void -allowed_hibernate_cb (DBusGProxy * proxy G_GNUC_UNUSED, - gboolean allow_hibernate, - GError * error, - gpointer userdata) +allowed_hibernate_cb (GObject * source, GAsyncResult * res, gpointer userdata) { - DeviceMenuMgr * mgr = DEVICE_MENU_MGR (userdata); - rebuild_if_flag_changed (mgr, error, &mgr->allow_hibernate, allow_hibernate); -} - - -static void -rebuild_if_flag_changed_from_proxy_call (DeviceMenuMgr * mgr, gboolean * setme, DBusGProxy * proxy, DBusGProxyCall * call) -{ - GValue value = {0}; + gboolean allowed; GError * error = NULL; + DeviceMenuMgr * mgr = DEVICE_MENU_MGR (userdata); - dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_VALUE, &value, G_TYPE_INVALID); - rebuild_if_flag_changed (mgr, error, setme, g_value_get_boolean (&value)); - - g_clear_error (&error); - g_value_unset (&value); + 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); + } } -/* When can-suspend changes, rebuild the menus */ -static void -suspend_prop_cb (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata) -{ - DeviceMenuMgr* self = DEVICE_MENU_MGR (userdata); - self->suspend_call = NULL; - rebuild_if_flag_changed_from_proxy_call (self, &self->can_suspend, proxy, call); -} -/* When can-hibernate changes, rebuild the menus */ static void -hibernate_prop_cb (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata) +on_upower_properties_changed (IndicatorSessionUPower * upower_proxy, DeviceMenuMgr * mgr) { - DeviceMenuMgr* self = DEVICE_MENU_MGR (userdata); - self->hibernate_call = NULL; - rebuild_if_flag_changed_from_proxy_call (self, &self->can_hibernate, proxy, call); -} + gboolean b; + gboolean refresh = FALSE; -/* A signal that we need to recheck to ensure we can still hibernate and/or suspend */ -static void -up_changed_cb (DBusGProxy * proxy, gpointer user_data) -{ - DeviceMenuMgr * self = DEVICE_MENU_MGR(user_data); + /* suspend */ + b = indicator_session_upower_get_can_suspend (upower_proxy); + if (mgr->can_suspend != b) + { + mgr->can_suspend = b; + refresh = TRUE; + } - if (self->suspend_call == NULL) + /* hibernate */ + b = indicator_session_upower_get_can_hibernate (upower_proxy); + if (mgr->can_hibernate != b) { - /* start async call to see if we can hibernate */ - self->suspend_call = dbus_g_proxy_begin_call (self->up_prop_proxy, - "Get", - suspend_prop_cb, - user_data, - NULL, - G_TYPE_STRING, - UP_INTERFACE, - G_TYPE_STRING, - "CanSuspend", - G_TYPE_INVALID, - G_TYPE_VALUE, - G_TYPE_INVALID); + mgr->can_hibernate = b; + refresh = TRUE; } - if (self->hibernate_call == NULL) - { - /* start async call to see if we can suspend */ - self->hibernate_call = dbus_g_proxy_begin_call (self->up_prop_proxy, - "Get", - hibernate_prop_cb, - user_data, - NULL, - G_TYPE_STRING, - UP_INTERFACE, - G_TYPE_STRING, - "CanHibernate", - G_TYPE_INVALID, - G_TYPE_VALUE, - G_TYPE_INVALID); - } + if (refresh) + { + device_menu_mgr_rebuild_items (mgr); + } } /* This function goes through and sets up what we need for DKp checking. @@ -291,34 +250,33 @@ up_changed_cb (DBusGProxy * proxy, gpointer user_data) static void setup_up (DeviceMenuMgr* self) { - DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL); - g_return_if_fail (bus != NULL); + self->cancellable = g_cancellable_new (); - if (self->up_main_proxy == NULL) + 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) { - self->up_main_proxy = dbus_g_proxy_new_for_name (bus, - UP_ADDRESS, - UP_OBJECT, - UP_INTERFACE); + g_warning ("Error creating cups notify handler: %s", error->message); + g_error_free (error); } - - if (self->up_prop_proxy == NULL) + else { - self->up_prop_proxy = dbus_g_proxy_new_for_name(bus, - UP_ADDRESS, - UP_OBJECT, - DBUS_INTERFACE_PROPERTIES); - /* Connect to changed signal */ - dbus_g_proxy_add_signal(self->up_main_proxy, "Changed", G_TYPE_INVALID); - dbus_g_proxy_connect_signal(self->up_main_proxy, "Changed", G_CALLBACK(up_changed_cb), self, NULL); + /* 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); } - /* Force an original "changed" event */ - up_changed_cb(self->up_main_proxy, self); - /* Check to see if these are getting blocked by PolicyKit */ - org_freedesktop_UPower_suspend_allowed_async(self->up_main_proxy, allowed_suspend_cb, self); - org_freedesktop_UPower_hibernate_allowed_async(self->up_main_proxy, allowed_hibernate_cb, self); } static void -- cgit v1.2.3 From 192be127691af87a88f4ac15d4fe3dd9296499b0 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 12 Jun 2012 00:39:31 -0500 Subject: use GDBus in users-service-dbus.c... major rewrite here. --- src/Makefile.am | 130 +-- src/accounts-service.xml | 194 ----- src/dialog.c | 47 +- src/display-manager.xml | 14 +- src/gtk-logout-helper.c | 2 +- src/lock-helper.c | 83 +- src/org.freedesktop.Accounts.User.xml | 744 ++++++++++++++++ src/org.freedesktop.Accounts.xml | 194 +++++ src/org.freedesktop.ConsoleKit.Seat.xml | 2 +- src/session-service.c | 10 - src/settings-helper.c | 3 - src/settings-helper.h | 3 - src/upower.xml | 2 +- src/user-menu-mgr.c | 206 +++-- src/users-service-dbus.c | 1417 +++++++++++++++---------------- src/users-service-dbus.h | 94 +- 16 files changed, 2027 insertions(+), 1118 deletions(-) delete mode 100644 src/accounts-service.xml create mode 100644 src/org.freedesktop.Accounts.User.xml create mode 100644 src/org.freedesktop.Accounts.xml (limited to 'src/Makefile.am') diff --git a/src/Makefile.am b/src/Makefile.am index cfe083c..55262a1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,53 +23,77 @@ libsession_la_SOURCES = \ dbus-shared-names.h \ dbusmenu-shared.h \ user-widget.c \ - user-widget.h \ - accounts-service-client.h + user-widget.h libsession_la_CFLAGS = \ $(APPLET_CFLAGS) \ $(COVERAGE_CFLAGS) \ - -Wall -Werror \ + -Wall -Wunused \ -DG_LOG_DOMAIN=\"Indicator-Session\" libsession_la_LIBADD = $(APPLET_LIBS) libsession_la_LDFLAGS = \ $(COVERAGE_LDFLAGS) \ -module -avoid-version -consolekit-manager-client.h: $(srcdir)/org.freedesktop.ConsoleKit.Manager.xml - dbus-binding-tool \ - --prefix=_consolekit_manager_client \ - --mode=glib-client \ - --output=consolekit-manager-client.h \ - $(srcdir)/org.freedesktop.ConsoleKit.Manager.xml - -consolekit-seat-client.h: $(srcdir)/org.freedesktop.ConsoleKit.Seat.xml - dbus-binding-tool \ - --prefix=_consolekit_seat_client \ - --mode=glib-client \ - --output=consolekit-seat-client.h \ - $(srcdir)/org.freedesktop.ConsoleKit.Seat.xml - -consolekit-session-client.h: $(srcdir)/org.freedesktop.ConsoleKit.Session.xml - dbus-binding-tool \ - --prefix=_consolekit_session_client \ - --mode=glib-client \ - --output=consolekit-session-client.h \ - $(srcdir)/org.freedesktop.ConsoleKit.Session.xml - -display-manager-client.h: $(srcdir)/display-manager.xml - dbus-binding-tool \ - --prefix=_gdm_local_display_factory_client \ - --mode=glib-client \ - --output=display-manager-client.h \ - $(srcdir)/display-manager.xml - -accounts-service-client.h: $(srcdir)/accounts-service.xml - dbus-binding-tool \ - --prefix=_accounts_service_client \ - --mode=glib-client \ - --output=accounts-service-client.h \ - $(srcdir)/accounts-service.xml +dbus_display_manager_sources = \ + dbus-display-manager.c \ + dbus-display-manager.h +$(dbus_display_manager_sources): display-manager.xml + gdbus-codegen \ + --interface-prefix org.freedesktop \ + --generate-c-code dbus-display-manager \ + $^ + +dbus_consolekit_manager_sources = \ + dbus-consolekit-manager.c \ + dbus-consolekit-manager.h + +$(dbus_consolekit_manager_sources): org.freedesktop.ConsoleKit.Manager.xml + gdbus-codegen \ + --interface-prefix org.freedesktop \ + --generate-c-code dbus-consolekit-manager \ + $^ + +dbus_consolekit_seat_sources = \ + dbus-consolekit-seat.c \ + dbus-consolekit-seat.h + +$(dbus_consolekit_seat_sources): org.freedesktop.ConsoleKit.Seat.xml + gdbus-codegen \ + --interface-prefix org.freedesktop \ + --generate-c-code dbus-consolekit-seat \ + $^ + +dbus_consolekit_session_sources = \ + dbus-consolekit-session.c \ + dbus-consolekit-session.h + +$(dbus_consolekit_session_sources): org.freedesktop.ConsoleKit.Session.xml + gdbus-codegen \ + --interface-prefix org.freedesktop \ + --generate-c-code dbus-consolekit-session \ + $^ + +dbus_accounts_sources = \ + dbus-accounts.c \ + dbus-accounts.h + +$(dbus_accounts_sources): org.freedesktop.Accounts.xml + gdbus-codegen \ + --interface-prefix org.freedesktop \ + --generate-c-code dbus-accounts \ + $^ + +dbus_user_sources = \ + dbus-user.c \ + dbus-user.h + +$(dbus_user_sources): org.freedesktop.Accounts.User.xml + gdbus-codegen \ + --interface-prefix org.freedesktop \ + --generate-c-code dbus-user \ + $^ + dbus_upower_sources = \ dbus-upower.c \ dbus-upower.h @@ -96,7 +120,13 @@ gen-%.xml.h: %.xml ################# indicator_session_service_SOURCES = \ + $(dbus_accounts_sources) \ + $(dbus_consolekit_manager_sources) \ + $(dbus_consolekit_seat_sources) \ + $(dbus_consolekit_session_sources) \ + $(dbus_display_manager_sources) \ $(dbus_upower_sources) \ + $(dbus_user_sources) \ lock-helper.c \ lock-helper.h \ session-service.c \ @@ -116,7 +146,7 @@ indicator_session_service_CFLAGS = \ $(SESSIONSERVICE_CFLAGS) \ $(GCONF_CFLAGS) \ -DLIBEXECDIR=\"$(libexecdir)\" \ - -Wall -Werror \ + -Wall \ -DG_LOG_DOMAIN=\"Indicator-Session\" \ $(COVERAGE_CFLAGS) indicator_session_service_LDADD = \ @@ -131,6 +161,7 @@ indicator_session_service_LDFLAGS = \ if BUILD_GTKLOGOUTHELPER gtk_logout_helper_SOURCES = \ + $(dbus_consolekit_manager_sources) \ gtk-logout-helper.c \ settings-helper.c \ settings-helper.h \ @@ -142,7 +173,7 @@ gtk_logout_helper_CFLAGS = \ $(GTKLOGOUTHELPER_CFLAGS) \ $(GCONF_CFLAGS) \ $(COVERAGE_CFLAGS) \ - -Wall -Werror \ + -Wall \ -DINDICATOR_ICONS_DIR="\"$(INDICATORICONSDIR)\"" gtk_logout_helper_LDADD = \ @@ -160,23 +191,24 @@ endif ############### BUILT_SOURCES = \ + $(dbus_accounts_sources) \ + $(dbus_consolekit_manager_sources) \ + $(dbus_consolekit_seat_sources) \ + $(dbus_consolekit_session_sources) \ + $(dbus_display_manager_sources) \ $(dbus_upower_sources) \ - consolekit-manager-client.h \ - consolekit-seat-client.h \ - consolekit-session-client.h \ - display-manager-client.h \ + $(dbus_user_sources) \ gen-session-dbus.xml.c \ - gen-session-dbus.xml.h \ - accounts-service-client.h + gen-session-dbus.xml.h EXTRA_DIST += \ + display-manager.xml \ + org.freedesktop.Accounts.User.xml \ + org.freedesktop.Accounts.xml \ org.freedesktop.ConsoleKit.Manager.xml \ org.freedesktop.ConsoleKit.Seat.xml \ org.freedesktop.ConsoleKit.Session.xml \ - display-manager.xml \ session-dbus.xml \ - upower.xml \ - accounts-service.xml \ - accounts-service-user.xml + upower.xml CLEANFILES += $(BUILT_SOURCES) diff --git a/src/accounts-service.xml b/src/accounts-service.xml deleted file mode 100644 index 9c19761..0000000 --- a/src/accounts-service.xml +++ /dev/null @@ -1,194 +0,0 @@ - - - - - - - - - - Object paths of cached users - - - - - - Lists users which have logged into the system locally before. - This is not meant to return an exhaustive list of all users. - It is possible for FindUserByName() - to return a user that's not on the list. - - - - - - - - - The uid to look up - - - Object path of user - - - - - - Finds a user by uid. - - - - if no user with the given uid exists - - - - - - - - The username to look up - - - Object path of user - - - - - - Finds a user by its username. - - - - if no user with the given username exists - - - - - - - - The username for the new user - - - - The real name for the new user - - - Object path of the new user - - - - The account type, encoded as an integer - - - - - - Creates a new user account. - - - The accountType argument can take the following values: - - - - 0 - Standard user - - - 1 - Administrator - - - 2 - Supervised user - - - - - The caller needs the org.freedesktop.accounts.user-administration PolicyKit authorization. - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - The uid to delete - - - Whether to remove the users files - - - - - - Deletes a user account. - - - - The caller needs the org.freedesktop.accounts.user-administration PolicyKit authorization. - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - Object path of the user that was added. - - - - - Emitted when a user is added. - - - - - - - - Object path of the user that was deleted. - - - - - Emitted when a user is deleted. - - - - - - - - Object path of the user that was changed. - - - - - Emitted when a user is changed. - - - - - - - - - - The version of the running daemon. - - - - - - - diff --git a/src/dialog.c b/src/dialog.c index 4b139ca..5686a95 100644 --- a/src/dialog.c +++ b/src/dialog.c @@ -26,7 +26,7 @@ with this program. If not, see . #include -#include "consolekit-manager-client.h" +#include "dbus-consolekit-manager.h" #include "dialog.h" /* Strings */ @@ -137,30 +137,31 @@ check_restart_required (void) static gboolean ck_check_allowed (LogoutDialogType type) { - DBusGConnection * system_bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL); - g_return_val_if_fail(system_bus != NULL, TRUE); - - DBusGProxy * ck_proxy = dbus_g_proxy_new_for_name (system_bus, - "org.freedesktop.ConsoleKit", - "/org/freedesktop/ConsoleKit/Manager", - "org.freedesktop.ConsoleKit.Manager"); - g_return_val_if_fail(ck_proxy != NULL, TRUE); - - gboolean retval = TRUE; - switch (type) { - case LOGOUT_DIALOG_TYPE_RESTART: - org_freedesktop_ConsoleKit_Manager_can_restart(ck_proxy, &retval, NULL); - break; - case LOGOUT_DIALOG_TYPE_SHUTDOWN: - org_freedesktop_ConsoleKit_Manager_can_stop(ck_proxy, &retval, NULL); - break; - default: - break; - } + gboolean allowed = TRUE; + + ConsoleKitManager * ck_proxy = console_kit_manager_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.ConsoleKit", + "/org/freedesktop/ConsoleKit/Manager", + NULL, + NULL); + if (ck_proxy != NULL) + { + switch (type) { + case LOGOUT_DIALOG_TYPE_RESTART: + console_kit_manager_call_can_restart_sync (ck_proxy, &allowed, NULL, NULL); + break; + case LOGOUT_DIALOG_TYPE_SHUTDOWN: + console_kit_manager_call_can_stop_sync (ck_proxy, &allowed, NULL, NULL); + break; + default: + break; + } - g_object_unref(ck_proxy); + g_object_unref(ck_proxy); + } - return retval; + return allowed; } LogoutDialog * diff --git a/src/display-manager.xml b/src/display-manager.xml index 92f5e05..07b5f29 100644 --- a/src/display-manager.xml +++ b/src/display-manager.xml @@ -1,20 +1,30 @@ + + + + + + + - + - + + + + diff --git a/src/gtk-logout-helper.c b/src/gtk-logout-helper.c index f5c11ba..8b8ff8f 100644 --- a/src/gtk-logout-helper.c +++ b/src/gtk-logout-helper.c @@ -24,8 +24,8 @@ with this program. If not, see . #include #include #include -#include #include +#include #include "dialog.h" #include "settings-helper.h" diff --git a/src/lock-helper.c b/src/lock-helper.c index 8eae674..11bcbd1 100644 --- a/src/lock-helper.c +++ b/src/lock-helper.c @@ -21,13 +21,13 @@ with this program. If not, see . #include #include -#include #include "lock-helper.h" #define SCREENSAVER_SCHEMA "org.gnome.desktop.screensaver" #define SCREENSAVER_LOCK_ENABLED_KEY "lock-enabled" -static DBusGProxy * gss_proxy = NULL; +static GDBusProxy * gss_proxy = NULL; + static GMainLoop * gss_mainloop = NULL; static gboolean is_guest = FALSE; @@ -52,16 +52,29 @@ will_lock_screen (void) return g_settings_get_boolean (settings, SCREENSAVER_LOCK_ENABLED_KEY); } -/* When the screensave go active, if we've got a mainloop - running we should quit it. */ +/* When the screensave goes active, + if we've got a mainloop running we should quit it. */ static void -gss_active_changed (DBusGProxy * proxy, gboolean active, gpointer data) +on_gss_signal (GDBusProxy *proxy, + gchar *sender_name, + gchar *signal_name, + GVariant *parameters, + gpointer user_data) { - if (active && gss_mainloop != NULL) { - g_main_loop_quit(gss_mainloop); + g_debug ("%s sender_name: %s", G_STRLOC, sender_name); + g_debug ("%s signal_name: %s", G_STRLOC, signal_name); + + if (!g_strcmp0 (signal_name, "ActiveChanged")) + { + gboolean active = FALSE; + g_variant_get_child (parameters, 0, "b", &active); + g_debug ("%s active: %i", G_STRLOC, active); + + if (active && gss_mainloop != NULL) + { + g_main_loop_quit(gss_mainloop); + } } - - return; } static gboolean @@ -72,7 +85,7 @@ get_greeter_mode (void) return (g_strcmp0(var, "1") == 0); } -/* Build the gss proxy and set up it's signals */ +/* Build the gss proxy and set up its signals */ void build_gss_proxy (void) { @@ -80,17 +93,23 @@ build_gss_proxy (void) if (get_greeter_mode ()) return; /* Don't start/lock the screensaver from the login screen */ - DBusGConnection * session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); - g_return_if_fail(session_bus != NULL); - - gss_proxy = dbus_g_proxy_new_for_name(session_bus, - "org.gnome.ScreenSaver", - "/", - "org.gnome.ScreenSaver"); - g_return_if_fail(gss_proxy != NULL); - - dbus_g_proxy_add_signal(gss_proxy, "ActiveChanged", G_TYPE_BOOLEAN, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(gss_proxy, "ActiveChanged", G_CALLBACK(gss_active_changed), NULL, NULL); + + GError * error = NULL; + gss_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.gnome.ScreenSaver", + "/", + "org.gnome.ScreenSaver", + NULL, + &error); + if (error != NULL) { + g_message ("Unable to get ScreenSaver proxy: %s", error->message); + g_error_free (error); + } + + g_return_if_fail (gss_proxy != NULL); + g_signal_connect (gss_proxy, "g-signal", G_CALLBACK(on_gss_signal), NULL); } return; @@ -113,8 +132,8 @@ activate_timeout (gpointer data) return FALSE; } -/* A fun little function to actually lock the screen. If, - that's what you want, let's do it! */ +/* A fun little function to actually lock the screen. + If that's what you want, let's do it! */ void lock_screen (DbusmenuMenuitem * mi, guint timestamp, gpointer data) { @@ -123,11 +142,19 @@ lock_screen (DbusmenuMenuitem * mi, guint timestamp, gpointer data) build_gss_proxy(); g_return_if_fail(gss_proxy != NULL); - dbus_g_proxy_call_no_reply(gss_proxy, - "Lock", - G_TYPE_INVALID, - G_TYPE_INVALID); - + GError * error = NULL; + GVariant * ret = g_dbus_proxy_call_sync (gss_proxy, + "Lock", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_variant_unref (ret); + if (error != NULL) { + g_warning ("Unable to lock: %s", error->message); + g_error_free (error); + } if (gss_mainloop == NULL) { gss_mainloop = g_main_loop_new(NULL, FALSE); } diff --git a/src/org.freedesktop.Accounts.User.xml b/src/org.freedesktop.Accounts.User.xml new file mode 100644 index 0000000..53f54d4 --- /dev/null +++ b/src/org.freedesktop.Accounts.User.xml @@ -0,0 +1,744 @@ + + + + + + + + + + + The new username. + + + + + + + Sets the users username. Note that it is usually not allowed + to have multiple users with the same username. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change the username of any user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new name, typically in the form "Firstname Lastname". + + + + + + + Sets the users real name. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own name + + + org.freedesktop.accounts.user-administration + To change the name of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new email address. + + + + + + + Sets the users email address. + + + Note that setting an email address in the AccountsService is + not the same as configuring a mail client. Mail clients might + default to email address that is configured here, though. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own email address + + + org.freedesktop.accounts.user-administration + To change the email address of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new language, as a locale specification like "de_DE.UTF-8". + + + + + + + Sets the users language. + + + The expectation is that display managers will start the + users session with this locale. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own language + + + org.freedesktop.accounts.user-administration + To change the language of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + + The new xsession to start (e.g. "gnome") + + + + + + + Sets the users x session. + + + The expectation is that display managers will log the user in to this + specified session, if available. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own language + + + org.freedesktop.accounts.user-administration + To change the language of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new location as a freeform string. + + + + + + + Sets the users location. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own location + + + org.freedesktop.accounts.user-administration + To change the location of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new homedir as an absolute path. + + + + + + + Sets the users home directory. + + + Note that changing the users home directory moves all the content + from the old location to the new one, and is potentially an + expensive operation. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change the home directory of a user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new user shell. + + + + + + + Sets the users shell. + + + Note that setting the shell to a non-allowed program may + prevent the user from logging in. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change the shell of a user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The absolute filename of a png file to use as the users icon. + + + + + + + Sets the users icon. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own icon + + + org.freedesktop.accounts.user-administration + To change the icon of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + Whether to lock or unlock the users account. + + + + + + + Locks or unlocks a users account. + + + Locking an account prevents the user from logging in. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To lock or unlock user accounts + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new account type, encoded as an integer: + + + 0 + Standard user + + + 1 + Administrator + + + + + + + + + Changes the users account type. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change an account type + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new password mode, encoded as an integer: + + + 0 + Regular password + + + 1 + Password must be set at next login + + + 2 + No password + + + + + + + + + Changes the users password mode. + + + Note that changing the password mode has the side-effect of + unlocking the account. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change a users password mode + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The crypted password. + + + + + + + The password hint. + + + + + + + Sets a new password for this user. + + + Note that setting a password has the side-effect of + unlocking the account. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change the password of a user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + Whether to enable automatic login for this user. + + + + + + + Enables or disables automatic login for a user. + + + Note that usually only one user can have automatic login + enabled, so turning it on for a user will disable it for + the previously configured autologin user. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.set-login-option + To change the login screen configuration + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + The uid of the user. + + + + + + + + + + The username of the user. + + + + + + + + + + The users real name. + + + + + + + + + + The users account type, encoded as an integer: + + + 0 + Standard user + + + 1 + Administrator + + + + + + + + + + + + The users home directory. + + + + + + + + + + The users shell. + + + + + + + + + + The email address. + + + + + + + + + + The users language, as a locale specification like "de_DE.UTF-8". + + + + + + + + + + The users x session. + + + + + + + + + + The users location. + + + + + + + + + + How often the user has logged in. + + + + + + + + + + The filename of a png file containing the users icon. + + + + + + + + + + Whether the users account is locked. + + + + + + + + + + The password mode for the user account, encoded as an integer: + + + 0 + Regular password + + + 1 + Password must be set at next login + + + 2 + No password + + + + + + + + + + + + The password hint for the user. + + + + + + + + + + Whether automatic login is enabled for the user. + + + + + + + + + + Whether this is a 'system' account, like 'root' or 'nobody'. + System accounts should normally not appear in lists of + users, and ListCachedUsers will not include such accounts. + + + + + + + + + + Emitted when the user is changed. + + + + + + + diff --git a/src/org.freedesktop.Accounts.xml b/src/org.freedesktop.Accounts.xml new file mode 100644 index 0000000..9c19761 --- /dev/null +++ b/src/org.freedesktop.Accounts.xml @@ -0,0 +1,194 @@ + + + + + + + + + + Object paths of cached users + + + + + + Lists users which have logged into the system locally before. + This is not meant to return an exhaustive list of all users. + It is possible for FindUserByName() + to return a user that's not on the list. + + + + + + + + + The uid to look up + + + Object path of user + + + + + + Finds a user by uid. + + + + if no user with the given uid exists + + + + + + + + The username to look up + + + Object path of user + + + + + + Finds a user by its username. + + + + if no user with the given username exists + + + + + + + + The username for the new user + + + + The real name for the new user + + + Object path of the new user + + + + The account type, encoded as an integer + + + + + + Creates a new user account. + + + The accountType argument can take the following values: + + + + 0 + Standard user + + + 1 + Administrator + + + 2 + Supervised user + + + + + The caller needs the org.freedesktop.accounts.user-administration PolicyKit authorization. + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + The uid to delete + + + Whether to remove the users files + + + + + + Deletes a user account. + + + + The caller needs the org.freedesktop.accounts.user-administration PolicyKit authorization. + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + Object path of the user that was added. + + + + + Emitted when a user is added. + + + + + + + + Object path of the user that was deleted. + + + + + Emitted when a user is deleted. + + + + + + + + Object path of the user that was changed. + + + + + Emitted when a user is changed. + + + + + + + + + + The version of the running daemon. + + + + + + + diff --git a/src/org.freedesktop.ConsoleKit.Seat.xml b/src/org.freedesktop.ConsoleKit.Seat.xml index d95990b..58c2ce7 100644 --- a/src/org.freedesktop.ConsoleKit.Seat.xml +++ b/src/org.freedesktop.ConsoleKit.Seat.xml @@ -101,7 +101,7 @@ seat at a time. - + Session ID diff --git a/src/session-service.c b/src/session-service.c index 1dd1e14..6a07f29 100644 --- a/src/session-service.c +++ b/src/session-service.c @@ -32,9 +32,6 @@ with this program. If not, see . #include #include -#include -#include - #include #include #include @@ -51,13 +48,6 @@ with this program. If not, see . #include "device-menu-mgr.h" #include "session-dbus.h" -typedef struct _ActivateData ActivateData; -struct _ActivateData -{ - UsersServiceDbus *service; - UserData *user; -}; - //static UsersServiceDbus *dbus_interface = NULL; static SessionDbus *session_dbus = NULL; static GMainLoop * mainloop = NULL; diff --git a/src/settings-helper.c b/src/settings-helper.c index 007f83f..6a09498 100644 --- a/src/settings-helper.c +++ b/src/settings-helper.c @@ -22,9 +22,6 @@ with this program. If not, see . #include #include -#include -#include - #include #include diff --git a/src/settings-helper.h b/src/settings-helper.h index ea0c99f..f50c4d8 100644 --- a/src/settings-helper.h +++ b/src/settings-helper.h @@ -25,9 +25,6 @@ with this program. If not, see . #include -#include -#include - #include #include diff --git a/src/upower.xml b/src/upower.xml index a4066ff..18d5fbd 100644 --- a/src/upower.xml +++ b/src/upower.xml @@ -86,7 +86,7 @@ method return sender=:1.386 -> dest=:1.451 reply_serial=2 - + Object path of device that was changed. diff --git a/src/user-menu-mgr.c b/src/user-menu-mgr.c index 00ad8a2..f44f888 100644 --- a/src/user-menu-mgr.c +++ b/src/user-menu-mgr.c @@ -28,7 +28,7 @@ with this program. If not, see . struct ActivateUserSessionData { UserMenuMgr * menu_mgr; - UserData * user; + AccountsUser * user; }; struct _UserMenuMgr @@ -36,6 +36,7 @@ struct _UserMenuMgr GObject parent_instance; UsersServiceDbus* users_dbus_interface; DbusmenuMenuitem* root_item; + DbusmenuMenuitem * guest_mi; SessionDbus* session_dbus_interface; GSettings * lockdown_settings; gboolean greeter_mode; @@ -59,6 +60,13 @@ static void user_menu_mgr_rebuild_items (UserMenuMgr *self); static void user_change (UsersServiceDbus *service, const gchar *user_id, gpointer user_data); + +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, @@ -67,6 +75,9 @@ static void activate_guest_session (DbusmenuMenuitem * mi, G_DEFINE_TYPE (UserMenuMgr, user_menu_mgr, G_TYPE_OBJECT); +/*** +**** +***/ static void user_menu_mgr_init (UserMenuMgr *self) @@ -74,14 +85,14 @@ 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); self->root_item = dbusmenu_menuitem_new (); - g_signal_connect (G_OBJECT (self->users_dbus_interface), - "user-added", - G_CALLBACK (user_change), - self); - g_signal_connect (G_OBJECT (self->users_dbus_interface), - "user-deleted", - G_CALLBACK (user_change), - self); + g_signal_connect (self->users_dbus_interface, "user-added", + G_CALLBACK (user_change), self); + g_signal_connect (self->users_dbus_interface, "user-deleted", + G_CALLBACK (user_change), 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 @@ -108,8 +119,67 @@ user_menu_mgr_class_init (UserMenuMgrClass *klass) 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 DbusmenuMenuitem* -create_user_menuitem (UserMenuMgr * menu_mgr, UserData * user) +create_user_menuitem (UserMenuMgr * menu_mgr, AccountsUser * user) { DbusmenuMenuitem * mi = dbusmenu_menuitem_new (); dbusmenu_menuitem_property_set (mi, @@ -117,27 +187,30 @@ create_user_menuitem (UserMenuMgr * menu_mgr, UserData * user) USER_ITEM_TYPE); /* set the name property */ - char * str = user->real_name_conflict - ? g_strdup_printf ("%s (%s)", user->real_name, user->user_name) - : g_strdup (user->real_name); + 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, - user->sessions != NULL); + is_logged_in); /* set the icon property */ - str = user->icon_file; - if (!str || !*str) - str = USER_ITEM_ICON_DEFAULT; - dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_ICON, str); + const gchar * icon_str = accounts_user_get_icon_file (user); + if (!icon_str || !*icon_str) + icon_str = USER_ITEM_ICON_DEFAULT; + dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_ICON, icon_str); /* set the is-current-user property */ dbusmenu_menuitem_property_set_bool (mi, USER_ITEM_PROP_IS_CURRENT_USER, - !g_strcmp0 (user->user_name, g_get_user_name())); + !g_strcmp0 (user_name, g_get_user_name())); /* set the activate callback */ struct ActivateUserSessionData * data = g_new (struct ActivateUserSessionData, 1); @@ -148,10 +221,42 @@ create_user_menuitem (UserMenuMgr * menu_mgr, UserData * user) 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); +g_message ("%s %s() user %s corresponds to mi %p", G_STRLOC, G_STRFUNC, accounts_user_get_user_name(user), mi); + + if (mi != NULL) + { + const gboolean b = users_service_dbus_is_user_logged_in (users_service_dbus, user); +g_message ("setting %p USER_ITEM_PROP_LOGGED_IN to %d", mi, (int)b); + 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) @@ -169,8 +274,8 @@ user_menu_mgr_rebuild_items (UserMenuMgr *self) g_list_foreach (children, (GFunc)g_object_unref, NULL); g_list_free (children); - /* Set to NULL just incase we don't end up building one */ - users_service_dbus_set_guest_item(self->users_dbus_interface, NULL); + /* 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) @@ -201,24 +306,19 @@ user_menu_mgr_rebuild_items (UserMenuMgr *self) if ( !is_this_guest_session () && guest_enabled) { - DbusmenuMenuitem *guest_mi = NULL; - guest_mi = dbusmenu_menuitem_new (); - dbusmenu_menuitem_property_set (guest_mi, + self->guest_mi = dbusmenu_menuitem_new (); + dbusmenu_menuitem_property_set (self->guest_mi, DBUSMENU_MENUITEM_PROP_TYPE, USER_ITEM_TYPE); - dbusmenu_menuitem_property_set (guest_mi, + dbusmenu_menuitem_property_set (self->guest_mi, USER_ITEM_PROP_NAME, _("Guest Session")); - dbusmenu_menuitem_property_set_bool (guest_mi, - USER_ITEM_PROP_LOGGED_IN, - FALSE); - dbusmenu_menuitem_child_append (self->root_item, guest_mi); - g_signal_connect (G_OBJECT (guest_mi), + on_guest_logged_in_changed (self->users_dbus_interface, self); + dbusmenu_menuitem_child_append (self->root_item, self->guest_mi); + g_signal_connect (G_OBJECT (self->guest_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (activate_guest_session), self); - users_service_dbus_set_guest_item (self->users_dbus_interface, - guest_mi); } else{ session_dbus_set_users_real_name (self->session_dbus_interface, @@ -231,14 +331,16 @@ user_menu_mgr_rebuild_items (UserMenuMgr *self) for (u = users; u != NULL; u = g_list_next (u)) { - UserData * user = u->data; + AccountsUser * user = u->data; DbusmenuMenuitem * mi = create_user_menuitem (self, user); dbusmenu_menuitem_child_append (self->root_item, mi); - if (!g_strcmp0 (user->user_name, g_get_user_name())) + const char * const user_name = accounts_user_get_user_name (user); + if (!g_strcmp0 (user_name, g_get_user_name())) { - session_dbus_set_users_real_name (self->session_dbus_interface, user->real_name); + const char * const real_name = accounts_user_get_real_name (user); + session_dbus_set_users_real_name (self->session_dbus_interface, real_name); } } @@ -305,20 +407,21 @@ activate_user_session (DbusmenuMenuitem *mi, guint timestamp, gpointer user_data /* Comparison function to look into the UserData struct to compare by using the username value */ static gint -compare_users_by_username (gconstpointer a, gconstpointer b) +compare_users_by_username (gconstpointer ga, gconstpointer gb) { - UserData *user1 = (UserData *)a; - UserData *user2 = (UserData *)b; + AccountsUser * a = ACCOUNTS_USER(ga); + AccountsUser * b = ACCOUNTS_USER(gb); - gint retval = g_strcmp0 (user1->real_name, user2->real_name); + const int ret = g_strcmp0 (accounts_user_get_real_name (a), + accounts_user_get_real_name (b)); - /* If they're the same, they're both in conflict. */ - if (retval == 0) { - user1->real_name_conflict = TRUE; - user2->real_name_conflict = TRUE; - } + 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 retval; + return ret; } static void @@ -334,15 +437,16 @@ activate_user_accounts (DbusmenuMenuitem *mi, } } -/* Signal called when a user is added. It updates the count and - rebuilds the menu */ +/* Signal called when a user is added. + It updates the count and rebuilds the menu */ static void -user_change (UsersServiceDbus *service, - const gchar *user_id, +user_change (UsersServiceDbus *service G_GNUC_UNUSED, + const gchar *user_id G_GNUC_UNUSED, gpointer user_data) { - g_return_if_fail (USER_IS_MENU_MGR (user_data)); - UserMenuMgr* user_mgr = USER_MENU_MGR(user_data); + UserMenuMgr* user_mgr = USER_MENU_MGR (user_data); + g_return_if_fail (user_mgr != NULL); + user_menu_mgr_rebuild_items (user_mgr); } diff --git a/src/users-service-dbus.c b/src/users-service-dbus.c index e6d094c..382c2dc 100644 --- a/src/users-service-dbus.c +++ b/src/users-service-dbus.c @@ -4,6 +4,7 @@ * * Authors: * Cody Russell + * Charles Kerr * * 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 @@ -19,946 +20,938 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include +#include + #include -#include +#include -#include -#include -#include +#include /* getpwuid() */ #include "dbus-shared-names.h" -#include "display-manager-client.h" +#include "dbus-accounts.h" +#include "dbus-consolekit-manager.h" +#include "dbus-consolekit-seat.h" +#include "dbus-consolekit-session.h" +#include "dbus-display-manager.h" +#include "dbus-user.h" #include "users-service-dbus.h" -#include "accounts-service-client.h" -#include "consolekit-manager-client.h" -#include "consolekit-session-client.h" -#include "consolekit-seat-client.h" #define CK_ADDR "org.freedesktop.ConsoleKit" #define CK_SESSION_IFACE "org.freedesktop.ConsoleKit.Session" +/** +*** +**/ -static void users_service_dbus_class_init (UsersServiceDbusClass *klass); -static void users_service_dbus_init (UsersServiceDbus *self); -static void users_service_dbus_dispose (GObject *object); -static void users_service_dbus_finalize (GObject *object); -static void create_display_manager_proxy (UsersServiceDbus *self); -static void create_accounts_service_proxy (UsersServiceDbus *self); -static void create_seat_proxy (UsersServiceDbus *self); -static void create_ck_proxy (UsersServiceDbus *self); -static void create_cksession_proxy (UsersServiceDbus *self); -static gchar *get_seat (UsersServiceDbus *service); -static void user_added (DBusGProxy *proxy, - const gchar *user_id, - gpointer user_data); -static void user_deleted (DBusGProxy *proxy, - const gchar *user_id, - gpointer user_data); -static void user_changed (DBusGProxy *proxy, - gpointer user_data); -static void seat_proxy_session_added (DBusGProxy *seat_proxy, - const gchar *session_id, - UsersServiceDbus *service); -static void seat_proxy_session_removed (DBusGProxy *seat_proxy, - const gchar *session_id, - UsersServiceDbus *service); -static void sync_users (UsersServiceDbus *self); -static gboolean do_add_session (UsersServiceDbus *service, - UserData *user, - const gchar *ssid); -static gchar * get_seat_internal (DBusGProxy *proxy); - -/* Private */ -typedef struct _UsersServiceDbusPrivate UsersServiceDbusPrivate; +static void init_users (UsersServiceDbus * self); -struct _UsersServiceDbusPrivate -{ - GHashTable *users; - gint count; - gchar *seat; - gchar *ssid; +static gchar* get_seat (UsersServiceDbus * service); - DBusGConnection *system_bus; +static void on_user_added (Accounts * o, + const gchar * user_object_path, + UsersServiceDbus * service); - DBusGProxy *accounts_service_proxy; - DBusGProxy *display_manager_proxy; - DBusGProxy *display_manager_props_proxy; - DBusGProxy *ck_proxy; - DBusGProxy *seat_proxy; - DBusGProxy *session_proxy; +static void on_user_deleted (Accounts * o, + const gchar * user_object_path, + UsersServiceDbus * service); - GHashTable *exclusions; - GHashTable *sessions; +static void on_session_added (ConsoleKitSeat * seat, + const gchar * ssid, + UsersServiceDbus * service); - DbusmenuMenuitem * guest_item; - gchar * guest_session_id; - gboolean guest_session_enabled; -}; - -#define USERS_SERVICE_DBUS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), USERS_SERVICE_DBUS_TYPE, UsersServiceDbusPrivate)) - -/* Signals */ -enum { - USER_ADDED, - USER_DELETED, - LAST_SIGNAL -}; +static void on_session_removed (ConsoleKitSeat * seat, + const gchar * ssid, + UsersServiceDbus * service); -static guint signals[LAST_SIGNAL] = { 0 }; +static void on_session_list (ConsoleKitSeat * seat, + GAsyncResult * result, + UsersServiceDbus * service); -/* GObject Boilerplate */ -G_DEFINE_TYPE (UsersServiceDbus, users_service_dbus, G_TYPE_OBJECT); +/*** +**** Priv Struct +***/ -static void -users_service_dbus_class_init (UsersServiceDbusClass *klass) +struct _UsersServiceDbusPrivate { - GObjectClass *object_class = G_OBJECT_CLASS (klass); + gchar * seat; + gchar * guest_ssid; - g_type_class_add_private (object_class, sizeof (UsersServiceDbusPrivate)); + /* ssid -> AccountsUser lookup */ + GHashTable * sessions; - object_class->dispose = users_service_dbus_dispose; - object_class->finalize = users_service_dbus_finalize; + /* user object path -> AccountsUser lookup */ + GHashTable * users; - signals[USER_ADDED] = g_signal_new ("user-added", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (UsersServiceDbusClass, user_added), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); + GCancellable * cancellable; + ConsoleKitSeat * seat_proxy; + ConsoleKitManager * ck_manager_proxy; + Accounts * accounts_proxy; + DisplayManagerSeat * display_proxy; +}; - signals[USER_DELETED] = g_signal_new ("user-deleted", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (UsersServiceDbusClass, user_deleted), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); -} +/*** +**** GObject +***/ -static void -users_service_dbus_init (UsersServiceDbus *self) +enum { - GError *error = NULL; - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - - priv->users = NULL; - priv->count = 0; - priv->guest_item = NULL; - priv->guest_session_id = NULL; - - priv->guest_session_enabled = FALSE; - - /* Get the system bus */ - priv->system_bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - if (error != NULL) - { - g_error ("Unable to get system bus"); - g_error_free(error); - - return; - } - - priv->sessions = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_free); + USER_ADDED, + USER_DELETED, + USER_LOGGED_IN_CHANGED, + GUEST_LOGGED_IN_CHANGED, + N_SIGNALS +}; - priv->users = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - NULL); +static guint signals[N_SIGNALS] = { 0 }; - create_ck_proxy (self); - create_seat_proxy (self); - create_display_manager_proxy (self); - create_accounts_service_proxy (self); -} +G_DEFINE_TYPE (UsersServiceDbus, users_service_dbus, G_TYPE_OBJECT); static void users_service_dbus_dispose (GObject *object) { - G_OBJECT_CLASS (users_service_dbus_parent_class)->dispose (object); -} - -static void -users_service_dbus_finalize (GObject *object) -{ - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (object); - - if (priv->guest_session_id != NULL) { - g_free(priv->guest_session_id); - priv->guest_session_id = NULL; - } - - G_OBJECT_CLASS (users_service_dbus_parent_class)->finalize (object); -} + UsersServiceDbusPrivate * priv = USERS_SERVICE_DBUS(object)->priv; + g_clear_object (&priv->accounts_proxy); + g_clear_object (&priv->display_proxy); + g_clear_object (&priv->seat_proxy); + g_clear_object (&priv->ck_manager_proxy); -static void -create_display_manager_proxy (UsersServiceDbus *self) -{ - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - GError *error = NULL; - const gchar *seat = NULL; - - seat = g_getenv ("XDG_SEAT_PATH"); - g_debug ("CREATING DM PROXIES WITH %s", seat); - priv->display_manager_proxy = dbus_g_proxy_new_for_name (priv->system_bus, - "org.freedesktop.DisplayManager", - seat, - "org.freedesktop.DisplayManager.Seat"); - - priv->display_manager_props_proxy = dbus_g_proxy_new_for_name (priv->system_bus, - "org.freedesktop.DisplayManager", - seat, - "org.freedesktop.DBus.Properties"); - - - if (!priv->display_manager_proxy) + if (priv->cancellable != NULL) { - g_warning ("Failed to get DisplayManager seat proxy."); - return; + g_cancellable_cancel (priv->cancellable); + g_clear_object (&priv->cancellable); } - if (!priv->display_manager_props_proxy) - { - g_warning ("Failed to get DisplayManager Properties seat proxy."); - return; - } - - GValue has_guest_session = {0}; - g_value_init (&has_guest_session, G_TYPE_BOOLEAN); - if (!dbus_g_proxy_call (priv->display_manager_props_proxy, - "Get", - &error, - G_TYPE_STRING, - "org.freedesktop.DisplayManager.Seat", - G_TYPE_STRING, - "HasGuestAccount", - G_TYPE_INVALID, - G_TYPE_VALUE, - &has_guest_session, - G_TYPE_INVALID)) + + if (priv->users != NULL) { - g_warning ("Failed to get the HasGuestSession property from the DisplayManager Properties seat proxy. error: %s", error->message); - g_error_free (error); - return; + g_hash_table_destroy (priv->users); + priv->users = NULL; } - g_debug ("Does seat have a guest account = %i", g_value_get_boolean (&has_guest_session)); - priv->guest_session_enabled = g_value_get_boolean (&has_guest_session); -} -static void -create_accounts_service_proxy (UsersServiceDbus *self) -{ - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - GPtrArray *users = g_ptr_array_new (); - GError *error = NULL; - - priv->accounts_service_proxy = dbus_g_proxy_new_for_name (priv->system_bus, - "org.freedesktop.Accounts", - "/org/freedesktop/Accounts", - "org.freedesktop.Accounts"); - - dbus_g_proxy_add_signal (priv->accounts_service_proxy, - "UserAdded", - DBUS_TYPE_G_OBJECT_PATH, - G_TYPE_INVALID); - - dbus_g_proxy_add_signal (priv->accounts_service_proxy, - "UserChanged", - DBUS_TYPE_G_OBJECT_PATH, - G_TYPE_INVALID); - - dbus_g_proxy_add_signal (priv->accounts_service_proxy, - "UserDeleted", - DBUS_TYPE_G_OBJECT_PATH, - G_TYPE_INVALID); - - dbus_g_proxy_connect_signal (priv->accounts_service_proxy, - "UserAdded", - G_CALLBACK (user_added), - self, - NULL); - - dbus_g_proxy_connect_signal (priv->accounts_service_proxy, - "UserDeleted", - G_CALLBACK (user_deleted), - self, - NULL); - - if (!org_freedesktop_Accounts_list_cached_users (priv->accounts_service_proxy, - &users, - &error)) + if (priv->sessions != NULL) { - g_warning ("failed to retrieve user count: %s", error->message); - g_error_free (error); - - return; + g_hash_table_destroy (priv->sessions); + priv->sessions = NULL; } - priv->count = users->len; - g_ptr_array_free (users, TRUE); - sync_users (self); + G_OBJECT_CLASS (users_service_dbus_parent_class)->dispose (object); } static void -create_ck_proxy (UsersServiceDbus *self) +users_service_dbus_finalize (GObject *object) { - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); + UsersServiceDbusPrivate * priv = USERS_SERVICE_DBUS(object)->priv; - priv->ck_proxy = dbus_g_proxy_new_for_name (priv->system_bus, - "org.freedesktop.ConsoleKit", - "/org/freedesktop/ConsoleKit/Manager", - "org.freedesktop.ConsoleKit.Manager"); + g_free (priv->guest_ssid); + g_free (priv->seat); - if (!priv->ck_proxy) - { - g_warning ("Failed to get ConsoleKit proxy."); - return; - } + G_OBJECT_CLASS (users_service_dbus_parent_class)->finalize (object); } -/* Get the initial sessions when starting up */ -static void -get_cksessions_cb (DBusGProxy *proxy, GPtrArray * sessions, GError * error, gpointer userdata) +static void +users_service_dbus_class_init (UsersServiceDbusClass *klass) { - if (error != NULL) { - g_warning("Unable to get initial sessions: %s", error->message); - return; - } + GObjectClass *object_class = G_OBJECT_CLASS (klass); - /* If there's no error we should at least get an - array of zero entries */ - g_return_if_fail(sessions != NULL); - g_debug("Got %d initial sessions", sessions->len); + g_type_class_add_private (object_class, sizeof (UsersServiceDbusPrivate)); - int i; - for (i = 0; i < sessions->len; i++) { - seat_proxy_session_added(proxy, g_ptr_array_index(sessions, i), USERS_SERVICE_DBUS(userdata)); - } + object_class->dispose = users_service_dbus_dispose; + object_class->finalize = users_service_dbus_finalize; - return; + signals[USER_ADDED] = g_signal_new ( + "user-added", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (UsersServiceDbusClass, user_added), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + signals[USER_DELETED] = g_signal_new ( + "user-deleted", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (UsersServiceDbusClass, user_deleted), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + signals[USER_LOGGED_IN_CHANGED] = g_signal_new ( + "user-logged-in-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (UsersServiceDbusClass, user_logged_in_changed), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + signals[GUEST_LOGGED_IN_CHANGED] = g_signal_new ( + "guest-logged-in-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (UsersServiceDbusClass, guest_logged_in_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } static void -create_seat_proxy (UsersServiceDbus *self) +users_service_dbus_init (UsersServiceDbus *self) { - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - GError *error = NULL; + GError * error = NULL; + + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + USERS_SERVICE_DBUS_TYPE, + UsersServiceDbusPrivate); + + UsersServiceDbusPrivate * p = self->priv; - priv->seat = get_seat (self); - if (priv->seat == NULL) + p->cancellable = g_cancellable_new (); + + /* ssid -> AccountsUser */ + p->sessions = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + g_object_unref); + + /* user object path -> AccountsUser */ + p->users = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + g_object_unref); + + /** + *** create the consolekit manager proxy... + **/ + + p->ck_manager_proxy = console_kit_manager_proxy_new_for_bus_sync ( + G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.ConsoleKit", + "/org/freedesktop/ConsoleKit/Manager", + NULL, + &error); + if (error != NULL) { - return; + g_warning ("%s: %s", G_STRLOC, error->message); + g_clear_error (&error); } - priv->seat_proxy = dbus_g_proxy_new_for_name_owner (priv->system_bus, - "org.freedesktop.ConsoleKit", - priv->seat, - "org.freedesktop.ConsoleKit.Seat", - &error); + p->seat = get_seat (self); - if (!priv->seat_proxy) + /** + *** create the consolekit seat proxy... + **/ + + if (p->seat != NULL) { + ConsoleKitSeat * proxy = console_kit_seat_proxy_new_for_bus_sync ( + G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.ConsoleKit", + p->seat, + NULL, + &error); + if (error != NULL) { g_warning ("Failed to connect to the ConsoleKit seat: %s", error->message); - g_error_free (error); + g_clear_error (&error); } + else + { + g_signal_connect (proxy, "session-added", + G_CALLBACK (on_session_added), self); + g_signal_connect (proxy, "session-removed", + G_CALLBACK (on_session_removed), self); + console_kit_seat_call_get_sessions (proxy, p->cancellable, + (GAsyncReadyCallback)on_session_list, self); + p->seat_proxy = proxy; + } + } - return; + /** + *** create the accounts manager proxy... + **/ + + Accounts * proxy = accounts_proxy_new_for_bus_sync ( + G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.Accounts", + "/org/freedesktop/Accounts", + NULL, + &error); + if (error != NULL) + { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_clear_error (&error); } + else + { + g_signal_connect (proxy, "user-added", G_CALLBACK(on_user_added), self); + g_signal_connect (proxy, "user-deleted", G_CALLBACK(on_user_deleted), self); + p->accounts_proxy = proxy; + init_users (self); + } +} - dbus_g_proxy_add_signal (priv->seat_proxy, - "SessionAdded", - DBUS_TYPE_G_OBJECT_PATH, - G_TYPE_INVALID); - dbus_g_proxy_add_signal (priv->seat_proxy, - "SessionRemoved", - DBUS_TYPE_G_OBJECT_PATH, - G_TYPE_INVALID); +/*** +**** +***/ - dbus_g_proxy_connect_signal (priv->seat_proxy, - "SessionAdded", - G_CALLBACK (seat_proxy_session_added), - self, - NULL); - dbus_g_proxy_connect_signal (priv->seat_proxy, - "SessionRemoved", - G_CALLBACK (seat_proxy_session_removed), - self, - NULL); +static void +emit_user_added (UsersServiceDbus * self, AccountsUser * user) +{ + g_signal_emit (self, signals[USER_ADDED], 0, user); +} - org_freedesktop_ConsoleKit_Seat_get_sessions_async (priv->seat_proxy, get_cksessions_cb, self); +static void +emit_user_deleted (UsersServiceDbus * self, AccountsUser * user) +{ + g_signal_emit (self, signals[USER_DELETED], 0, user); +} - return; +static void +emit_user_login_changed (UsersServiceDbus * self, AccountsUser * user) +{ + g_signal_emit (self, signals[USER_LOGGED_IN_CHANGED], 0, user); } static void -create_cksession_proxy (UsersServiceDbus *service) +emit_guest_login_changed (UsersServiceDbus * self) { - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service); + g_signal_emit (self, signals[GUEST_LOGGED_IN_CHANGED], 0); +} - priv->session_proxy = dbus_g_proxy_new_for_name (priv->system_bus, - CK_ADDR, - priv->ssid, - CK_SESSION_IFACE); +/*** +**** +***/ - if (!priv->session_proxy) +static ConsoleKitSession* +create_consolekit_session_proxy (const char * ssid) +{ + GError * error = NULL; + + ConsoleKitSession * p = console_kit_session_proxy_new_for_bus_sync ( + G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + CK_ADDR, + ssid, + NULL, + &error); + + if (error != NULL) { - g_warning ("Failed to get ConsoleKit session proxy"); - return; + g_warning ("%s: %s", G_STRLOC, error->message); + g_error_free (error); } + + return p; } static gchar * -get_seat (UsersServiceDbus *service) +get_seat_from_session_proxy (ConsoleKitSession * session_proxy) { - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service); - GError *error = NULL; - gchar *ssid = NULL; - gchar *seat; - - if (!dbus_g_proxy_call (priv->ck_proxy, - "GetCurrentSession", - &error, - G_TYPE_INVALID, - DBUS_TYPE_G_OBJECT_PATH, - &ssid, - G_TYPE_INVALID)) - { - if (error) - { - g_debug ("Failed to call GetCurrentSession: %s", error->message); - g_error_free (error); - } - - if (ssid) - g_free (ssid); + gchar * seat = NULL; - return NULL; + GError * error = NULL; + console_kit_session_call_get_seat_id_sync (session_proxy, + &seat, + NULL, + &error); + if (error != NULL) + { + g_debug ("%s: %s", G_STRLOC, error->message); + g_error_free (error); } - priv->ssid = ssid; - create_cksession_proxy (service); - - seat = get_seat_internal (priv->session_proxy); - return seat; } static gchar * -get_seat_internal (DBusGProxy *proxy) +get_seat (UsersServiceDbus *service) { - GError *error = NULL; - gchar *seat = NULL; + gchar * seat = NULL; + gchar * ssid = NULL; + GError * error = NULL; + UsersServiceDbusPrivate * priv = service->priv; + + console_kit_manager_call_get_current_session_sync (priv->ck_manager_proxy, + &ssid, + NULL, + &error); - if (!org_freedesktop_ConsoleKit_Session_get_seat_id (proxy, &seat, &error)) + if (error != NULL) { - if (error) - { - g_debug ("Failed to call GetSeatId: %s", error->message); + g_debug ("%s: %s", G_STRLOC, error->message); + g_error_free (error); + } + else + { + ConsoleKitSession * session = create_consolekit_session_proxy (ssid); - return NULL; + if (session != NULL) + { + seat = get_seat_from_session_proxy (session); + g_object_unref (session); } } return seat; } -static gboolean -get_unix_user (UsersServiceDbus *service, - const gchar *session_id, - uid_t *uidp) -{ - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service); - GError *error = NULL; - guint uid; - DBusGProxy *session_proxy; - - g_debug("Building session proxy for: %s", session_id); - session_proxy = dbus_g_proxy_new_for_name_owner(priv->system_bus, - CK_ADDR, - session_id, - CK_SESSION_IFACE, - &error); - - if (error != NULL) { - g_warning("Unable to get CK Session proxy: %s", error->message); - g_error_free(error); - return FALSE; - } - - if (!org_freedesktop_ConsoleKit_Session_get_unix_user(session_proxy, &uid, &error)) +/* lazy-create the display manager proxy */ +static DisplayManagerSeat * +get_display_proxy (UsersServiceDbus * self) +{ + UsersServiceDbusPrivate * priv = self->priv; + + if (priv->display_proxy == NULL) { - if (error) + const gchar * const seat = g_getenv ("XDG_SEAT_PATH"); + g_debug ("%s lazy-creating the DisplayManager proxy for seat %s", G_STRLOC, seat); + + GError * error = NULL; + DisplayManagerSeat * p = display_manager_seat_proxy_new_for_bus_sync ( + G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.DisplayManager", + seat, + NULL, + &error); + + if (error == NULL) + { + priv->display_proxy = p; + } + else { - g_warning ("Failed to call GetUnixUser: %s", error->message); + g_warning ("%s: %s", G_STRLOC, error->message); g_error_free (error); } + } + + return priv->display_proxy; +} - g_object_unref(session_proxy); - return FALSE; +/*** +**** AccountsUser add-ons for tracking sessions +***/ + +static GHashTable* +user_get_sessions_hashset (AccountsUser * user) +{ + static GQuark q = 0; + + if (G_UNLIKELY(!q)) + { + q = g_quark_from_static_string ("sessions"); } - if (uidp != NULL) + GObject * o = G_OBJECT (user); + GHashTable * h = g_object_get_qdata (o, q); + if (h == NULL) { - *uidp = (uid_t)uid; + h = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + g_object_set_qdata_full (o, q, h, (GDestroyNotify)g_hash_table_destroy); } - g_object_unref(session_proxy); - return TRUE; + return h; } -static gboolean -do_add_session (UsersServiceDbus *service, - UserData *user, - const gchar *ssid) -{ - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service); - GError *error = NULL; - gchar *seat = NULL; - gchar *xdisplay = NULL; - DBusGProxy * session_proxy; - GList *l; - - session_proxy = dbus_g_proxy_new_for_name_owner(priv->system_bus, - CK_ADDR, - ssid, - CK_SESSION_IFACE, - &error); - - if (error != NULL) { - g_warning("Unable to get CK Session proxy: %s", error->message); - g_error_free(error); - return FALSE; - } - - seat = get_seat_internal (session_proxy); - - if (!seat || !priv->seat || strcmp (seat, priv->seat) != 0) { - g_object_unref(session_proxy); - return FALSE; - } - - if (!org_freedesktop_ConsoleKit_Session_get_x11_display (session_proxy, &xdisplay, &error)) +static void +user_add_session (AccountsUser * user, const char * ssid) +{ + g_hash_table_add (user_get_sessions_hashset(user), g_strdup(ssid)); +} + +static void +user_remove_session (AccountsUser * user, const char * ssid) +{ + g_hash_table_remove (user_get_sessions_hashset(user), ssid); +} + +static guint +user_count_sessions (AccountsUser * user) +{ + return g_hash_table_size (user_get_sessions_hashset(user)); +} + +/*** +**** Users +***/ + +/* adds this user session to the user's and service's session tables */ +static void +add_user_session (UsersServiceDbus * service, + AccountsUser * user, + const gchar * ssid) +{ + ConsoleKitSession * session_proxy = create_consolekit_session_proxy (ssid); + if (session_proxy != NULL) { - if (error) + UsersServiceDbusPrivate * priv = service->priv; + gchar * seat = get_seat_from_session_proxy (session_proxy); + + /* is this session in our seat? */ + if (seat && priv->seat && !g_strcmp0 (seat, priv->seat)) { - g_debug ("Failed to call GetX11Display: %s", error->message); - g_error_free (error); + /* does this session have a display? */ + gchar * display = NULL; + console_kit_session_call_get_x11_display_sync (session_proxy, + &display, + NULL, NULL); + const gboolean has_display = display && *display; + g_free (display); + + if (has_display) + { + const gchar * username = accounts_user_get_user_name (user); + g_debug ("%s adding %s's session '%s' to our tables", + G_STRLOC, username, ssid); + + g_hash_table_insert (priv->sessions, + g_strdup (ssid), + g_object_ref (user)); + + user_add_session (user, ssid); + } } - g_object_unref(session_proxy); - return FALSE; + g_free (seat); + g_object_unref (session_proxy); } +} - g_object_unref(session_proxy); +/* calls add_user_session() for each of this user's sessions */ +static void +add_user (UsersServiceDbus *self, AccountsUser * user) +{ + const guint64 uid = accounts_user_get_uid (user); + const char * username = accounts_user_get_user_name (user); + g_debug ("%s adding %s (%i)", G_STRLOC, username, (int)uid); + + GError * error = NULL; + gchar ** sessions = NULL; + console_kit_manager_call_get_sessions_for_unix_user_sync ( + self->priv->ck_manager_proxy, + uid, + &sessions, + NULL, + &error); - if (!xdisplay || xdisplay[0] == '\0') - return FALSE; + if (error != NULL) + { + g_debug ("%s: %s", G_STRLOC, error->message); + g_error_free (error); + } + else if (sessions != NULL) + { + int i; - g_hash_table_insert (priv->sessions, - g_strdup (ssid), - g_strdup (user->user_name)); + for (i=0; sessions[i]; i++) + { + const char * const ssid = sessions[i]; + g_debug ("%s adding %s's session %s", G_STRLOC, username, ssid); + add_user_session (self, user, ssid); + } - l = g_list_find_custom (user->sessions, ssid, (GCompareFunc)g_strcmp0); - if (l == NULL) - { - g_debug ("Adding session %s", ssid); + g_strfreev (sessions); + } +} - user->sessions = g_list_prepend (user->sessions, g_strdup (ssid)); +static void +add_user_from_object_path (UsersServiceDbus * self, + const char * user_object_path) +{ + GError * error = NULL; + AccountsUser * user = accounts_user_proxy_new_for_bus_sync ( + G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.Accounts", + user_object_path, + NULL, + &error); - if (user->menuitem != NULL) { - dbusmenu_menuitem_property_set_bool(user->menuitem, USER_ITEM_PROP_LOGGED_IN, TRUE); - } + if (error != NULL) + { + g_warning ("%s: %s", G_STRLOC, error->message); + g_clear_error (&error); } else { - g_debug ("User %s already has session %s", user->user_name, ssid); + g_debug ("%s adding user %s from object path %s", G_STRLOC, + accounts_user_get_user_name(user), + user_object_path); + g_hash_table_insert (self->priv->users, g_strdup(user_object_path), user); + add_user (self, user); } - - return TRUE; } + +/* calls add_user_from_object_path() on a list of user object paths */ static void -add_sessions_for_user (UsersServiceDbus *self, - UserData *user) +init_users (UsersServiceDbus *self) { - g_return_if_fail (IS_USERS_SERVICE_DBUS(self)); + g_return_if_fail(IS_USERS_SERVICE_DBUS(self)); - g_debug ("!!!!!!!!!! - add_sessions_for_user %i %s", - (int)user->uid, user->user_name); + GError * error = NULL; + char ** object_paths = NULL; + UsersServiceDbusPrivate * priv = self->priv; + g_debug ("%s bootstrapping the user list", G_STRLOC); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - GError *error; - GPtrArray *sessions; - int i; + accounts_call_list_cached_users_sync (priv->accounts_proxy, + &object_paths, + NULL, + &error); - error = NULL; - if (!org_freedesktop_ConsoleKit_Manager_get_sessions_for_unix_user(priv->ck_proxy, user->uid, &sessions, &error)) + if (error != NULL) { - g_debug ("Failed to call GetSessionsForUnixUser: %s", error->message); - g_error_free (error); - - return; + g_warning ("%s: %s", G_STRFUNC, error->message); + g_clear_error (&error); } - - for (i = 0; i < sessions->len; i++) + else if (object_paths != NULL) { - char *ssid; + gint i; - ssid = g_ptr_array_index (sessions, i); - do_add_session (self, user, ssid); + for (i=0; object_paths[i] != NULL; ++i) + { + add_user_from_object_path (self, object_paths[i]); + } + + g_strfreev (object_paths); } - g_ptr_array_foreach (sessions, (GFunc)g_free, NULL); - g_ptr_array_free (sessions, TRUE); + g_debug ("%s finished bootstrapping the user list", G_STRLOC); } +static void +on_user_added (Accounts * o G_GNUC_UNUSED, + const gchar * user_path, + UsersServiceDbus * service) +{ + add_user_from_object_path (service, user_path); + + AccountsUser * user = g_hash_table_lookup (service->priv->users, user_path); + emit_user_added (service, user); +} static void -seat_proxy_session_added (DBusGProxy *seat_proxy, - const gchar *session_id, - UsersServiceDbus *service) +on_user_deleted (Accounts * o G_GNUC_UNUSED, + const gchar * user_path, + UsersServiceDbus * service) { - g_return_if_fail(IS_USERS_SERVICE_DBUS(service)); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service); - uid_t uid; - struct passwd *pwent; - UserData *user; + AccountsUser * user = g_hash_table_lookup (service->priv->users, user_path); - if (!get_unix_user (service, session_id, &uid)) + if (user != NULL) { - g_warning ("Failed to lookup user for session"); - return; + GObject * o = g_object_ref (G_OBJECT(user)); + g_hash_table_remove (service->priv->users, user_path); + emit_user_deleted (service, user); + g_object_unref (o); } +} - errno = 0; - pwent = getpwuid (uid); - if (!pwent) - { - g_warning ("Failed to lookup user id %d: %s", (int)uid, g_strerror (errno)); - return; - } +static AccountsUser * +find_user_from_username (UsersServiceDbus * self, + const gchar * username) +{ + AccountsUser * match = NULL; - /* We need to special case guest here because it doesn't - show up in the GDM user tables. */ - if (g_strcmp0("guest", pwent->pw_name) == 0) { - if (priv->guest_item != NULL) { - dbusmenu_menuitem_property_set_bool(priv->guest_item, USER_ITEM_PROP_LOGGED_IN, TRUE); - } - priv->guest_session_id = g_strdup(session_id); - g_debug("Found guest session: %s", priv->guest_session_id); - return; - } + g_return_val_if_fail (IS_USERS_SERVICE_DBUS(self), match); - user = users_service_dbus_get_user_by_username (service, pwent->pw_name); - if (!user) - return; + gpointer user; + GHashTableIter iter; + g_hash_table_iter_init (&iter, self->priv->users); + while (!match && g_hash_table_iter_next (&iter, NULL, &user)) + { + if (!g_strcmp0 (username, accounts_user_get_user_name (user))) + { + match = user; + } + } - do_add_session (service, user, session_id); + return match; } +/*** +**** Sessions +***/ + static void -seat_proxy_session_removed (DBusGProxy *seat_proxy, - const gchar *session_id, - UsersServiceDbus *service) -{ - g_return_if_fail(IS_USERS_SERVICE_DBUS(service)); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service); - UserData *user; - gchar *username; - GList *l; - - username = g_hash_table_lookup (priv->sessions, session_id); - if (!username) { - if (g_strcmp0(session_id, priv->guest_session_id) == 0) { - g_debug("Removing guest session: %s", priv->guest_session_id); - if (priv->guest_item != NULL) { - dbusmenu_menuitem_property_set_bool(priv->guest_item, USER_ITEM_PROP_LOGGED_IN, FALSE); - } - g_free(priv->guest_session_id); - priv->guest_session_id = NULL; - } - return; - } +on_session_removed (ConsoleKitSeat * seat_proxy, + const gchar * ssid, + UsersServiceDbus * service) +{ + g_return_if_fail (IS_USERS_SERVICE_DBUS (service)); - user = users_service_dbus_get_user_by_username (service, username); - if (!user) - return; + UsersServiceDbusPrivate * priv = service->priv; + g_debug ("%s %s() session removed %s", G_STRLOC, G_STRFUNC, ssid); - l = g_list_find_custom (user->sessions, - session_id, - (GCompareFunc)g_strcmp0); - if (l) + if (!g_strcmp0 (ssid, priv->guest_ssid)) { - g_debug ("Removing session %s", session_id); - - g_free (l->data); - user->sessions = g_list_delete_link (user->sessions, l); - if (user->menuitem != NULL && user->sessions == NULL) { - dbusmenu_menuitem_property_set_bool(user->menuitem, USER_ITEM_PROP_LOGGED_IN, FALSE); - } + g_debug ("%s removing guest session %s", G_STRLOC, ssid); + g_clear_pointer (&priv->guest_ssid, g_free); + emit_guest_login_changed (service); } else { - g_debug ("Session not found: %s", session_id); + AccountsUser * user = g_hash_table_lookup (priv->sessions, ssid); + if (user == NULL) + { + g_debug ("%s we're not tracking ssid %s", G_STRLOC, ssid); + } + else + { + GObject * o = g_object_ref (G_OBJECT(user)); + g_hash_table_remove (service->priv->users, ssid); + user_remove_session (user, ssid); + emit_user_login_changed (service, user); + g_object_unref (o); + } } } -static void -sync_users (UsersServiceDbus *self) +static gchar* +get_unix_username_from_ssid (UsersServiceDbus * self, + const gchar * ssid) { - g_return_if_fail(IS_USERS_SERVICE_DBUS(self)); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - - GPtrArray *users = NULL; - GError *error = NULL; - gint i; - - users = g_ptr_array_new (); - - if (!org_freedesktop_Accounts_list_cached_users (priv->accounts_service_proxy, - &users, - &error)) - { - g_warning ("failed to retrieve user list: %s", error->message); - g_error_free (error); + gchar * username = NULL; - return; - } - - for (i = 0; i < users->len; i++) + ConsoleKitSession * session_proxy = create_consolekit_session_proxy (ssid); + if (session_proxy != NULL) { - gchar *id; - DBusGProxy *proxy; - UserData *user; - GError *error = NULL; - - id = g_ptr_array_index (users, i); - - proxy = dbus_g_proxy_new_for_name (priv->system_bus, - "org.freedesktop.Accounts", - id, - "org.freedesktop.DBus.Properties"); - - GHashTable *properties; - if (!dbus_g_proxy_call (proxy, "GetAll", &error, - G_TYPE_STRING, "org.freedesktop.Accounts.User", G_TYPE_INVALID, - dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &properties, G_TYPE_INVALID)) - { - g_warning ("unable to retrieve user info: %s", error->message); - g_error_free (error); - - continue; - } - - user = g_hash_table_lookup (priv->users, id); - // Double check we havent processed this user already - if (user != NULL) + guint uid = 0; + GError * error = NULL; + console_kit_session_call_get_unix_user_sync (session_proxy, + &uid, + NULL, &error); + if (error != NULL) { - g_free(user->user_name); - g_free(user->real_name); - g_free(user->icon_file); - user->real_name_conflict = FALSE; - //continue; + g_warning ("%s: %s", G_STRLOC, error->message); + g_clear_error (&error); } else - { - user = g_new0 (UserData, 1); + { + errno = 0; + const struct passwd * pwent = getpwuid (uid); + if (pwent == NULL) + { + g_warning ("Failed to lookup user id %d: %s", (int)uid, g_strerror(errno)); + } + else + { + username = g_strdup (pwent->pw_name); + } } - // Can't subscribe to the Changed signal on each individual user path - // for some reason. - dbus_g_proxy_add_signal (proxy, - "Changed", - G_TYPE_INVALID); - - dbus_g_proxy_connect_signal (proxy, "Changed", - G_CALLBACK(user_changed), - self, - NULL); - user->uid = g_value_get_uint64 (g_hash_table_lookup (properties, "Uid")); - user->user_name = g_strdup (g_value_get_string (g_hash_table_lookup (properties, "UserName"))); - user->real_name = g_strdup (g_value_get_string (g_hash_table_lookup (properties, "RealName"))); - user->icon_file = g_strdup (g_value_get_string (g_hash_table_lookup (properties, "IconFile"))); - user->real_name_conflict = FALSE; - user->menuitem = NULL; - - g_hash_table_unref (properties); - - g_hash_table_insert (priv->users, - g_strdup (id), - user); - - add_sessions_for_user (self, user); + + g_object_unref (session_proxy); } - g_ptr_array_free (users, TRUE); + return username; } -static void -user_changed (DBusGProxy *proxy, - gpointer user_data) +static gboolean +is_guest_username (const char * username) { - g_debug ("JUST RESYNCED THE USERS FROM A USER CHANGE"); - UsersServiceDbus *service = (UsersServiceDbus *)user_data; - sync_users (service); + if (!g_strcmp0 (username, "guest")) + return TRUE; + + if ((strlen(username)==12) && !memcmp(username,"guest-",6)) + return TRUE; + + return FALSE; } +/* If the new session belongs to 'guest', update our guest_ssid. + Otherwise, call add_user_session() to update our session tables */ static void -user_added (DBusGProxy *proxy, - const gchar *user_id, - gpointer user_data) +on_session_added (ConsoleKitSeat * seat_proxy G_GNUC_UNUSED, + const gchar * ssid, + UsersServiceDbus * service) { - UsersServiceDbus *service = (UsersServiceDbus *)user_data; - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service); - priv->count++; - sync_users (service); - g_signal_emit (service, - signals[USER_ADDED], - 0, - user_id); -} + g_return_if_fail (IS_USERS_SERVICE_DBUS(service)); -static void -user_deleted (DBusGProxy *proxy, - const gchar *user_id, - gpointer user_data) -{ - UsersServiceDbus *service = (UsersServiceDbus *)user_data; - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service); + gchar * username = get_unix_username_from_ssid (service, ssid); + g_debug ("%s %s() username %s has new session %s", G_STRLOC, G_STRFUNC, username, ssid); - priv->count--; - g_hash_table_remove (priv->users, user_id); + if (is_guest_username (username)) + { + /* handle guest as a special case -- it's not in the GDM + user tables and there isn't be an AccountsUser for it */ + g_debug("Found guest session: %s", ssid); + g_free (service->priv->guest_ssid); + service->priv->guest_ssid = g_strdup (ssid); + emit_guest_login_changed (service); + } + else + { + AccountsUser * user = find_user_from_username (service, username); + + if (user != NULL) + { + add_user_session (service, user, ssid); + emit_user_login_changed (service, user); + } + } - g_signal_emit (service, - signals[USER_DELETED], - 0, - user_id); - + g_free (username); } -UserData * -users_service_dbus_get_user_by_username (UsersServiceDbus *self, - const gchar *username) +/* Receives a list of sessions and calls on_session_added() for each of them */ +static void +on_session_list (ConsoleKitSeat * seat_proxy, + GAsyncResult * result, + UsersServiceDbus * self) { - GHashTableIter iter; - gpointer value; + GError * error = NULL; + gchar ** sessions = NULL; + g_debug ("%s bootstrapping the session list", G_STRLOC); - g_return_val_if_fail(IS_USERS_SERVICE_DBUS(self), NULL); + console_kit_seat_call_get_sessions_finish (seat_proxy, + &sessions, + result, + &error); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - - g_hash_table_iter_init (&iter, priv->users); - while (g_hash_table_iter_next (&iter, NULL, &value)) + if (error != NULL) { - UserData *user = value; - if (strcmp (user->user_name, username) == 0) - return user; + g_debug ("%s: %s", G_STRLOC, error->message); + g_error_free (error); + } + else if (sessions != NULL) + { + int i; + + for (i=0; sessions[i]; i++) + { + g_debug ("%s adding initial session '%s'", G_STRLOC, sessions[i]); + on_session_added (seat_proxy, sessions[i], self); + } + + g_strfreev (sessions); } - return NULL; + g_debug ("%s done bootstrapping the session list", G_STRLOC); } +/*** +**** Public API +***/ + +/** + * users_service_dbus_get_user_list: + * + * Returns: (transfer container): a list of AccountsUser objects + */ GList * -users_service_dbus_get_user_list (UsersServiceDbus *self) +users_service_dbus_get_user_list (UsersServiceDbus * self) { g_return_val_if_fail(IS_USERS_SERVICE_DBUS(self), NULL); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); + return g_hash_table_get_values (self->priv->users); +} - return g_hash_table_get_values (priv->users); +/** + * users_service_dbus_show_greeter: + * + * Ask the Display Mnaager to switch to the greeter screen. + */ +void +users_service_dbus_show_greeter (UsersServiceDbus * self) +{ + g_return_if_fail (IS_USERS_SERVICE_DBUS(self)); + + display_manager_seat_call_switch_to_greeter_sync (get_display_proxy(self), + NULL, + NULL); } -gboolean -users_service_dbus_show_greeter (UsersServiceDbus *self) +/** + * users_service_dbus_activate_guest_session: + * + * Activates the guest account. + */ +void +users_service_dbus_activate_guest_session (UsersServiceDbus * self) { - g_return_val_if_fail(IS_USERS_SERVICE_DBUS(self), FALSE); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - return org_freedesktop_DisplayManager_Seat_switch_to_greeter(priv->display_manager_proxy, NULL); + g_return_if_fail(IS_USERS_SERVICE_DBUS(self)); + + display_manager_seat_call_switch_to_guest_sync (get_display_proxy(self), + "", + NULL, + NULL); } -/* Activates the guest account if it can. */ -gboolean -users_service_dbus_activate_guest_session (UsersServiceDbus *self) +/** + * users_service_dbus_activate_user_session: + * + * Activates a specific user. + */ +void +users_service_dbus_activate_user_session (UsersServiceDbus * self, + AccountsUser * user) { - g_return_val_if_fail(IS_USERS_SERVICE_DBUS(self), FALSE); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - return org_freedesktop_DisplayManager_Seat_switch_to_guest(priv->display_manager_proxy, "", NULL); + g_return_if_fail (IS_USERS_SERVICE_DBUS(self)); + + const char * const username = accounts_user_get_user_name (user); + display_manager_seat_call_switch_to_user_sync (get_display_proxy(self), + username, + "", + NULL, + NULL); } -/* Activates a specific user */ +/** + * users_service_dbus_guest_session_enabled: + * + * Tells whether or not guest sessions are allowed. + */ gboolean -users_service_dbus_activate_user_session (UsersServiceDbus *self, - UserData *user) +users_service_dbus_guest_session_enabled (UsersServiceDbus * self) { - g_return_val_if_fail(IS_USERS_SERVICE_DBUS(self), FALSE); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - return org_freedesktop_DisplayManager_Seat_switch_to_user(priv->display_manager_proxy, user->user_name, "", NULL); + g_return_val_if_fail(IS_USERS_SERVICE_DBUS(self), FALSE); + + return display_manager_seat_get_has_guest_account (get_display_proxy(self)); } gboolean -users_service_dbus_can_activate_session (UsersServiceDbus *self) +users_service_dbus_can_activate_session (UsersServiceDbus * self) { - g_return_val_if_fail(IS_USERS_SERVICE_DBUS(self), FALSE); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); gboolean can_activate = FALSE; - GError *error = NULL; - if (!priv->seat_proxy) - { - create_seat_proxy (self); - } + g_return_val_if_fail (IS_USERS_SERVICE_DBUS(self), can_activate); - if (!priv->seat || priv->seat[0] == '\0') - { - return FALSE; - } - - if (!dbus_g_proxy_call (priv->seat_proxy, - "CanActivateSessions", - &error, - G_TYPE_INVALID, - G_TYPE_BOOLEAN, &can_activate, - G_TYPE_INVALID)) + GError * error = NULL; + console_kit_seat_call_can_activate_sessions_sync (self->priv->seat_proxy, + &can_activate, + NULL, + &error); + if (error != NULL) { - if (error != NULL){ - g_warning ("Failed to determine if seat can activate sessions: %s", - error->message); - g_error_free (error); - } - return FALSE; + g_warning ("%s: %s", G_STRLOC, error->message); + g_error_free (error); } return can_activate; } -/* Sets the menu item that represents the guest account */ -void -users_service_dbus_set_guest_item (UsersServiceDbus * self, DbusmenuMenuitem * mi) +gboolean +users_service_dbus_is_guest_logged_in (UsersServiceDbus * self) { - g_return_if_fail(IS_USERS_SERVICE_DBUS(self)); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - priv->guest_item = mi; - - if (priv->guest_session_id != NULL) { - dbusmenu_menuitem_property_set_bool(priv->guest_item, USER_ITEM_PROP_LOGGED_IN, TRUE); - } + g_return_val_if_fail (IS_USERS_SERVICE_DBUS(self), FALSE); - return; + return self->priv->guest_ssid != NULL; } -gboolean users_service_dbus_guest_session_enabled (UsersServiceDbus * self) +gboolean +users_service_dbus_is_user_logged_in (UsersServiceDbus * self, + AccountsUser * user) { - g_return_val_if_fail(IS_USERS_SERVICE_DBUS(self), FALSE); - UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); - - return priv->guest_session_enabled; -} + g_return_val_if_fail (IS_USERS_SERVICE_DBUS(self), FALSE); + g_return_val_if_fail (IS_ACCOUNTS_USER(user), FALSE); + return user_count_sessions (user) > 0; +} diff --git a/src/users-service-dbus.h b/src/users-service-dbus.h index 66f3b9d..bc153df 100644 --- a/src/users-service-dbus.h +++ b/src/users-service-dbus.h @@ -3,6 +3,7 @@ * * Authors: * Cody Russell + * Charles Kerr * * 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 @@ -22,62 +23,75 @@ #include #include -#include + +#include "dbus-user.h" /* for AccountsUser */ G_BEGIN_DECLS -#define USERS_SERVICE_DBUS_TYPE (users_service_dbus_get_type ()) -#define USERS_SERVICE_DBUS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), USERS_SERVICE_DBUS_TYPE, UsersServiceDbus)) -#define USERS_SERVICE_DBUS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), USERS_SERVICE_DBUS_TYPE, UsersServiceDbusClass)) -#define IS_USERS_SERVICE_DBUS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), USERS_SERVICE_DBUS_TYPE)) -#define IS_USERS_SERVICE_DBUS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), USERS_SERVICE_DBUS_TYPE)) -#define USERS_SERVICE_DBUS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), USERS_SERVICE_DBUS_TYPE, UsersServiceDbusClass)) +#define USERS_SERVICE_DBUS_TYPE (users_service_dbus_get_type ()) +#define USERS_SERVICE_DBUS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), USERS_SERVICE_DBUS_TYPE, UsersServiceDbus)) +#define IS_USERS_SERVICE_DBUS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), USERS_SERVICE_DBUS_TYPE)) -typedef struct _UsersServiceDbus UsersServiceDbus; -typedef struct _UsersServiceDbusClass UsersServiceDbusClass; -typedef struct _UserData UserData; +typedef struct _UsersServiceDbus UsersServiceDbus; +typedef struct _UsersServiceDbusClass UsersServiceDbusClass; +typedef struct _UsersServiceDbusPrivate UsersServiceDbusPrivate; -struct _UserData +/** + * A class which interacts with multiple DBus services to track + * info which is useful to the interactor's user menu: + * + * 1. A list of users to add to the user menu. + * + * Each user is an AccountsUser object, which is a GDBusProxy + * to an org.freedesktop.Accounts.User object. + * + * We initially build this list by calling org.freedesktop.Accounts' + * GetCachedUsers method. We also monitor o.f.Accounts' UserAdded + * and UserDeleted and update the list accordingly. + * + * 2. Track which users currently have X sessions. + * This is used for the menuitems' USER_ITEM_PROP_LOGGED_IN property. + * + * We initially build this list by calling org.freedesktop.ConsoleKit.Seat's + * GetDevices method. We also monitor the seat for SessionAdded and + * SessionRemoved and update the list accordingly. + * + * 3. Provide an API for user switching and guest sessions. + * These are typically pass-through functions to GDBusProxies. + * + */ +struct _UsersServiceDbus { - gint64 uid; - gchar *user_name; - gchar *real_name; - gchar *icon_file; - - GList *sessions; - - /* Whether the real name here conflicts with another in the system */ - gboolean real_name_conflict; - /* The menuitem representing this user if there is one. */ - DbusmenuMenuitem * menuitem; -}; - -struct _UsersServiceDbus { + /*< private >*/ GObject parent; + UsersServiceDbusPrivate * priv; }; -struct _UsersServiceDbusClass { +struct _UsersServiceDbusClass +{ GObjectClass parent_class; /* Signals */ - void (* user_added) (UsersServiceDbus *self, const gchar *user_id, gpointer user_data); - void (* user_deleted) (UsersServiceDbus *self, const gchar *user_id, gpointer user_data); + void (* user_added) (UsersServiceDbus*, AccountsUser*, gpointer); + void (* user_deleted) (UsersServiceDbus*, AccountsUser*, gpointer); + void (* user_logged_in_changed) (UsersServiceDbus*, AccountsUser*, gpointer); + void (* guest_logged_in_changed) (UsersServiceDbus*, gpointer); }; -GType users_service_dbus_get_type (void) G_GNUC_CONST; +GType users_service_dbus_get_type (void) G_GNUC_CONST; + +GList * users_service_dbus_get_user_list (UsersServiceDbus * self); -UserData *users_service_dbus_get_user_by_username (UsersServiceDbus *self, - const gchar *username); -GList *users_service_dbus_get_user_list (UsersServiceDbus *self); -gboolean users_service_dbus_show_greeter (UsersServiceDbus *self); -gboolean users_service_dbus_can_activate_session (UsersServiceDbus *self); -gboolean users_service_dbus_activate_user_session (UsersServiceDbus *self, - UserData *user); -gboolean users_service_dbus_activate_guest_session (UsersServiceDbus *self); -void users_service_dbus_set_guest_item (UsersServiceDbus * self, - DbusmenuMenuitem * mi); +gboolean users_service_dbus_is_guest_logged_in (UsersServiceDbus * self); +gboolean users_service_dbus_is_user_logged_in (UsersServiceDbus * self, + AccountsUser * user); -gboolean users_service_dbus_guest_session_enabled (UsersServiceDbus * self); +void users_service_dbus_show_greeter (UsersServiceDbus * self); +gboolean users_service_dbus_guest_session_enabled (UsersServiceDbus * self); +gboolean users_service_dbus_can_activate_session (UsersServiceDbus * self); +void users_service_dbus_activate_guest_session (UsersServiceDbus * self); +void users_service_dbus_activate_user_session (UsersServiceDbus * self, + AccountsUser * user); G_END_DECLS -- cgit v1.2.3 From 41c4ab35750809c59c60cf3a3e1c3deb8449c9b5 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 14 Jun 2012 14:06:34 -0500 Subject: remove the use-username-in-switch-item property; it's no longer spec'ed --- .../com.canonical.indicator.session.gschema.xml.in | 6 - src/Makefile.am | 2 - src/dbusmenu-shared.h | 4 - src/device-menu-mgr.c | 1 - src/indicator-session.c | 133 --------------------- src/session-service.c | 1 - src/settings-helper.h | 1 - src/user-menu-mgr.c | 7 +- 8 files changed, 4 insertions(+), 151 deletions(-) delete mode 100644 src/dbusmenu-shared.h (limited to 'src/Makefile.am') diff --git a/data/com.canonical.indicator.session.gschema.xml.in b/data/com.canonical.indicator.session.gschema.xml.in index c26d8c1..ec8e954 100644 --- a/data/com.canonical.indicator.session.gschema.xml.in +++ b/data/com.canonical.indicator.session.gschema.xml.in @@ -25,12 +25,6 @@ Determine the visibility of the User's real name on the panel Allow for the Removal of the users name from the panel - - false - Determine what string to use for the user's name in the switch menuitem. - The switch menuitem as part of the user menu should be default have the label 'Switch User Account'. - This settings gives the user the potential to have the label read 'Switch from $username' - diff --git a/src/Makefile.am b/src/Makefile.am index 55262a1..209b72d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -21,7 +21,6 @@ libsession_la_SOURCES = \ indicator-session.c \ gen-session-dbus.xml.h \ dbus-shared-names.h \ - dbusmenu-shared.h \ user-widget.c \ user-widget.h libsession_la_CFLAGS = \ @@ -133,7 +132,6 @@ indicator_session_service_SOURCES = \ session-dbus.c \ session-dbus.h \ gen-session-dbus.xml.c \ - dbusmenu-shared.h \ settings-helper.c \ users-service-dbus.h \ users-service-dbus.c \ diff --git a/src/dbusmenu-shared.h b/src/dbusmenu-shared.h deleted file mode 100644 index 1ef179b..0000000 --- a/src/dbusmenu-shared.h +++ /dev/null @@ -1,4 +0,0 @@ - -#define MENU_SWITCH_TYPE "x-canonical-switch-from" -#define MENU_SWITCH_USER "x-canonical-switch-username" - diff --git a/src/device-menu-mgr.c b/src/device-menu-mgr.c index 9cfb913..23a8dc0 100644 --- a/src/device-menu-mgr.c +++ b/src/device-menu-mgr.c @@ -29,7 +29,6 @@ with this program. If not, see . #include "device-menu-mgr.h" #include "settings-helper.h" #include "dbus-shared-names.h" -#include "dbusmenu-shared.h" #include "lock-helper.h" #define UP_ADDRESS "org.freedesktop.UPower" diff --git a/src/indicator-session.c b/src/indicator-session.c index 94ab18b..54fdab6 100644 --- a/src/indicator-session.c +++ b/src/indicator-session.c @@ -39,7 +39,6 @@ with this program. If not, see . #include #include "dbus-shared-names.h" -#include "dbusmenu-shared.h" #include "user-widget.h" #define INDICATOR_SESSION_TYPE (indicator_session_get_type ()) @@ -75,10 +74,6 @@ INDICATOR_SET_VERSION INDICATOR_SET_TYPE(INDICATOR_SESSION_TYPE) /* Prototypes */ -static gboolean build_menu_switch (DbusmenuMenuitem * newitem, - DbusmenuMenuitem * parent, - DbusmenuClient * client, - gpointer user_data); static gboolean new_user_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, @@ -152,10 +147,6 @@ indicator_session_init (IndicatorSession *self) dbusmenu_client_add_type_handler (menu_client, RESTART_ITEM_TYPE, build_restart_item); - dbusmenu_client_add_type_handler_full (menu_client, - MENU_SWITCH_TYPE, - build_menu_switch, - self, NULL); dbusmenu_gtkclient_set_accel_group (DBUSMENU_GTKCLIENT(menu_client), gtk_accel_group_new()); } @@ -354,83 +345,6 @@ receive_signal (GDBusProxy * proxy, -static void -switch_property_change (DbusmenuMenuitem * item, - const gchar * property, - GVariant * variant, - gpointer user_data) -{ - if (g_strcmp0 (property, MENU_SWITCH_USER) != 0) { - return; - } - - GtkMenuItem * gmi = dbusmenu_gtkclient_menuitem_get(DBUSMENU_GTKCLIENT(user_data), item); - gchar * finalstring = NULL; - gboolean set_ellipsize = FALSE; - gboolean no_name_in_lang = FALSE; - - const gchar * translate = C_("session_menu:switchfrom", "1"); - if (g_strcmp0(translate, "1") != 0) { - no_name_in_lang = TRUE; - } - - GSettings* settings = g_settings_new ("com.canonical.indicator.session"); - gboolean use_username = g_settings_get_boolean (settings, - "use-username-in-switch-item"); - g_object_unref (settings); - - if (variant == NULL || g_variant_get_string(variant, NULL) == NULL || - g_variant_get_string(variant, NULL)[0] == '\0' || no_name_in_lang - || use_username == FALSE) { - finalstring = _("Switch User Account…"); - set_ellipsize = FALSE; - } - - if (finalstring == NULL) { - const gchar * username = g_variant_get_string(variant, NULL); - GtkStyle * style = gtk_widget_get_style(GTK_WIDGET(gmi)); - - PangoLayout * layout = pango_layout_new(gtk_widget_get_pango_context(GTK_WIDGET(gmi))); - pango_layout_set_text (layout, username, -1); - pango_layout_set_font_description(layout, style->font_desc); - - gint width; - pango_layout_get_pixel_size(layout, &width, NULL); - g_object_unref(layout); - g_debug("Username width %dpx", width); - - gint point = pango_font_description_get_size(style->font_desc); - g_debug("Font size %f pt", (gfloat)point / PANGO_SCALE); - - gdouble dpi = gdk_screen_get_resolution(gdk_screen_get_default()); - g_debug("Screen DPI %f", dpi); - - gdouble pixels_per_em = ((point * dpi) / 72.0f) / PANGO_SCALE; - gdouble ems = width / pixels_per_em; - g_debug("Username width %fem", ems); - - finalstring = g_strdup_printf(_("Switch From %s…"), username); - if (ems >= 20.0f) { - set_ellipsize = TRUE; - } else { - set_ellipsize = FALSE; - } - - } - gtk_menu_item_set_label(gmi, finalstring); - - GtkLabel * label = GTK_LABEL(gtk_bin_get_child(GTK_BIN(gmi))); - if (label != NULL) { - if (set_ellipsize) { - gtk_label_set_ellipsize(label, PANGO_ELLIPSIZE_END); - } else { - gtk_label_set_ellipsize(label, PANGO_ELLIPSIZE_NONE); - } - } - return; -} - -static const gchar * dbusmenu_item_data = "dbusmenu-item"; static void restart_property_change (DbusmenuMenuitem * item, @@ -487,53 +401,6 @@ build_restart_item (DbusmenuMenuitem * newitem, return TRUE; } -static void -switch_style_set (GtkWidget * widget, - GtkStyle * prev_style, - gpointer user_data) -{ - DbusmenuGtkClient * client = DBUSMENU_GTKCLIENT(user_data); - DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(g_object_get_data(G_OBJECT(widget), - dbusmenu_item_data)); - - switch_property_change (mi, - MENU_SWITCH_USER, - dbusmenu_menuitem_property_get_variant(mi, MENU_SWITCH_USER), - client); - return; -} - -static gboolean -build_menu_switch (DbusmenuMenuitem * newitem, - DbusmenuMenuitem * parent, - DbusmenuClient * client, - gpointer user_data) -{ - GtkMenuItem * gmi = GTK_MENU_ITEM(gtk_menu_item_new()); - if (gmi == NULL) { - return FALSE; - } - - g_object_set_data(G_OBJECT(gmi), dbusmenu_item_data, newitem); - - dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, gmi, parent); - - g_signal_connect (G_OBJECT(newitem), - DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, - G_CALLBACK(switch_property_change), - client); - g_signal_connect (G_OBJECT(gmi), - "style-set", - G_CALLBACK(switch_style_set), - client); - - switch_property_change (newitem, - MENU_SWITCH_USER, - dbusmenu_menuitem_property_get_variant(newitem, MENU_SWITCH_USER), client); - - return TRUE; -} - static void indicator_session_update_users_label (IndicatorSession * self, const gchar * name) diff --git a/src/session-service.c b/src/session-service.c index 52018db..508887f 100644 --- a/src/session-service.c +++ b/src/session-service.c @@ -43,7 +43,6 @@ with this program. If not, see . #include #include "dbus-shared-names.h" -#include "dbusmenu-shared.h" #include "users-service-dbus.h" #include "user-menu-mgr.h" #include "device-menu-mgr.h" diff --git a/src/settings-helper.h b/src/settings-helper.h index 29372f3..17304af 100644 --- a/src/settings-helper.h +++ b/src/settings-helper.h @@ -34,7 +34,6 @@ with this program. If not, see . #define RESTART_KEY "suppress-restart-menuitem" #define SHUTDOWN_KEY "suppress-shutdown-menuitem" #define SHOW_USER_MENU "user-show-menu" -#define USER_USERNAME_IN_SWITCH_ITEM "use-username-in-switch-item" #define LOCKDOWN_SCHEMA "org.gnome.desktop.lockdown" #define LOCKDOWN_KEY_USER "disable-user-switching" diff --git a/src/user-menu-mgr.c b/src/user-menu-mgr.c index 2fe042a..37aca14 100644 --- a/src/user-menu-mgr.c +++ b/src/user-menu-mgr.c @@ -21,7 +21,6 @@ with this program. If not, see . #include "user-menu-mgr.h" #include "settings-helper.h" #include "dbus-shared-names.h" -#include "dbusmenu-shared.h" #include "lock-helper.h" #include "users-service-dbus.h" @@ -299,12 +298,14 @@ user_menu_mgr_rebuild_items (UserMenuMgr *self) /* 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, - MENU_SWITCH_USER, - g_get_user_name()); + USER_ITEM_PROP_NAME, + _("Switch User Account…")); dbusmenu_menuitem_child_append (self->root_item, switch_menuitem); g_signal_connect (G_OBJECT (switch_menuitem), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, -- cgit v1.2.3 From 8cb934f213894b998bc3c471f5636fa9f0ae1dd4 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 15 Jun 2012 08:20:45 -0500 Subject: a step in merging the two menus: merge the DeviceMenuMgr and UserMenuMgr classes into a single SessionMenuMgr class --- po/POTFILES.in | 3 +- src/Makefile.am | 6 +- src/device-menu-mgr.c | 461 ------------------------- src/device-menu-mgr.h | 53 --- src/session-menu-mgr.c | 889 +++++++++++++++++++++++++++++++++++++++++++++++++ src/session-menu-mgr.h | 53 +++ src/session-service.c | 6 +- src/user-menu-mgr.c | 496 --------------------------- src/user-menu-mgr.h | 55 --- 9 files changed, 947 insertions(+), 1075 deletions(-) delete mode 100644 src/device-menu-mgr.c delete mode 100644 src/device-menu-mgr.h create mode 100644 src/session-menu-mgr.c create mode 100644 src/session-menu-mgr.h delete mode 100644 src/user-menu-mgr.c delete mode 100644 src/user-menu-mgr.h (limited to 'src/Makefile.am') 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 - -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 . -*/ - -#include - -#include -#include - -#include -#include - -#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 - -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 . -*/ - - -#ifndef _DEVICE_MENU_MGR_H_ -#define _DEVICE_MENU_MGR_H_ - -#include - -#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 + +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 . +*/ + +#include + +#include +#include + +#include +#include + +#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 + +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 . +*/ + + +#ifndef _SESSION_MENU_MGR_H_ +#define _SESSION_MENU_MGR_H_ + +#include + +#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 . #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 - -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 . -*/ - -#include -#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 - -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 . -*/ - - -#ifndef _USER_MENU_MGR_H_ -#define _USER_MENU_MGR_H_ - - -#include -#include - -#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_ */ -- cgit v1.2.3 From 63b800e6036bc9d5096d8f7b7db42a814b8a2bed Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sun, 17 Jun 2012 14:03:25 -0500 Subject: a step in merging the two menus: consolidate & clean up the code in session-menu-mgr --- src/Makefile.am | 4 +- src/gtk-logout-helper.c | 1 + src/lock-helper.c | 184 ------- src/lock-helper.h | 31 -- src/session-menu-mgr.c | 1259 ++++++++++++++++++++++++++--------------------- src/session-menu-mgr.h | 4 +- src/settings-helper.c | 133 +---- src/settings-helper.h | 24 - 8 files changed, 716 insertions(+), 924 deletions(-) delete mode 100644 src/lock-helper.c delete mode 100644 src/lock-helper.h (limited to 'src/Makefile.am') diff --git a/src/Makefile.am b/src/Makefile.am index 9391d86..24f2ee8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -100,8 +100,8 @@ dbus_upower_sources = \ $(dbus_upower_sources): upower.xml gdbus-codegen \ --interface-prefix org.freedesktop \ - --c-namespace IndicatorSession \ --generate-c-code dbus-upower \ + --c-namespace DBus \ $^ gen-%.xml.c: %.xml @@ -126,8 +126,6 @@ indicator_session_service_SOURCES = \ $(dbus_display_manager_sources) \ $(dbus_upower_sources) \ $(dbus_user_sources) \ - lock-helper.c \ - lock-helper.h \ session-service.c \ session-dbus.c \ session-dbus.h \ diff --git a/src/gtk-logout-helper.c b/src/gtk-logout-helper.c index 4f23ba2..360dd0f 100644 --- a/src/gtk-logout-helper.c +++ b/src/gtk-logout-helper.c @@ -24,6 +24,7 @@ with this program. If not, see . #include #include #include +#include /* textdomain(), bindtextdomain() */ #include #include #include "dialog.h" diff --git a/src/lock-helper.c b/src/lock-helper.c deleted file mode 100644 index 11bcbd1..0000000 --- a/src/lock-helper.c +++ /dev/null @@ -1,184 +0,0 @@ -/* -A small helper for locking the screen. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould - -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 . -*/ - -#include -#include -#include "lock-helper.h" - -#define SCREENSAVER_SCHEMA "org.gnome.desktop.screensaver" -#define SCREENSAVER_LOCK_ENABLED_KEY "lock-enabled" - -static GDBusProxy * gss_proxy = NULL; - -static GMainLoop * gss_mainloop = NULL; - -static gboolean is_guest = FALSE; - -static GSettings * settings = NULL; - -void build_gss_proxy (void); - -/* This is our logic on whether the screen should be locked - or not. It effects everything else. */ -gboolean -will_lock_screen (void) -{ - if (is_guest) { - return FALSE; - } - - if (settings == NULL) { - settings = g_settings_new (SCREENSAVER_SCHEMA); - } - - return g_settings_get_boolean (settings, SCREENSAVER_LOCK_ENABLED_KEY); -} - -/* When the screensave goes active, - if we've got a mainloop running we should quit it. */ -static void -on_gss_signal (GDBusProxy *proxy, - gchar *sender_name, - gchar *signal_name, - GVariant *parameters, - gpointer user_data) -{ - g_debug ("%s sender_name: %s", G_STRLOC, sender_name); - g_debug ("%s signal_name: %s", G_STRLOC, signal_name); - - if (!g_strcmp0 (signal_name, "ActiveChanged")) - { - gboolean active = FALSE; - g_variant_get_child (parameters, 0, "b", &active); - g_debug ("%s active: %i", G_STRLOC, active); - - if (active && gss_mainloop != NULL) - { - g_main_loop_quit(gss_mainloop); - } - } -} - -static gboolean -get_greeter_mode (void) -{ - const gchar *var; - var = g_getenv("INDICATOR_GREETER_MODE"); - return (g_strcmp0(var, "1") == 0); -} - -/* Build the gss proxy and set up its signals */ -void -build_gss_proxy (void) -{ - if (gss_proxy == NULL) { - if (get_greeter_mode ()) - return; /* Don't start/lock the screensaver from the login screen */ - - - GError * error = NULL; - gss_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.ScreenSaver", - "/", - "org.gnome.ScreenSaver", - NULL, - &error); - if (error != NULL) { - g_message ("Unable to get ScreenSaver proxy: %s", error->message); - g_error_free (error); - } - - g_return_if_fail (gss_proxy != NULL); - g_signal_connect (gss_proxy, "g-signal", G_CALLBACK(on_gss_signal), NULL); - } - - return; -} - -/* This is a timeout, we only want to wait for the screen to - lock for a little bit, but not forever. */ -static gboolean -activate_timeout (gpointer data) -{ - /* Clear the ID for the timeout */ - guint * address = (guint *)data; - *address = 0; - - /* Quit the mainloop */ - if (gss_mainloop != NULL) { - g_main_loop_quit(gss_mainloop); - } - - return FALSE; -} - -/* A fun little function to actually lock the screen. - If that's what you want, let's do it! */ -void -lock_screen (DbusmenuMenuitem * mi, guint timestamp, gpointer data) -{ - g_debug("Lock Screen"); - - build_gss_proxy(); - g_return_if_fail(gss_proxy != NULL); - - GError * error = NULL; - GVariant * ret = g_dbus_proxy_call_sync (gss_proxy, - "Lock", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - g_variant_unref (ret); - if (error != NULL) { - g_warning ("Unable to lock: %s", error->message); - g_error_free (error); - } - if (gss_mainloop == NULL) { - gss_mainloop = g_main_loop_new(NULL, FALSE); - } - - guint timer = g_timeout_add_seconds(1, activate_timeout, &timer); - - g_main_loop_run(gss_mainloop); - - if (timer != 0) { - g_source_remove(timer); - } - - return; -} - -/* Do what it takes to make the lock screen function work - and be happy. */ -gboolean -lock_screen_setup (gpointer data) -{ - if (!g_strcmp0(g_get_user_name(), "guest")) { - is_guest = TRUE; - } - - return FALSE; -} - diff --git a/src/lock-helper.h b/src/lock-helper.h deleted file mode 100644 index e2d5106..0000000 --- a/src/lock-helper.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -A small helper for locking the screen. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould - -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 . -*/ - -#ifndef LOCK_HELPER_H__ -#define LOCK_HELPER_H__ - -#include - -gboolean will_lock_screen (void); -void lock_screen (DbusmenuMenuitem * mi, guint timestamp, gpointer data); -gboolean lock_screen_setup (gpointer data); - -#endif /* LOCK_HELPER_H__ */ diff --git a/src/session-menu-mgr.c b/src/session-menu-mgr.c index 0fdaeb5..c6de0b1 100644 --- a/src/session-menu-mgr.c +++ b/src/session-menu-mgr.c @@ -3,6 +3,7 @@ Copyright 2011 Canonical Ltd. Authors: Conor Curran + Charles Kerr 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 @@ -19,126 +20,182 @@ with this program. If not, see . #include +#include +#include + #include -#include +#include #include #include #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 UPOWER_ADDRESS "org.freedesktop.UPower" +#define UPOWER_PATH "/org/freedesktop/UPower" + +#define CMD_HELP "yelp" +#define CMD_INFO "gnome-control-center info" +#define CMD_SYSTEM_SETTINGS "gnome-control-center" +#ifdef HAVE_GTKLOGOUTHELPER + #define CMD_LOGOUT LIBEXECDIR"/gtk-logout-helper --logout" + #define CMD_SHUTDOWN LIBEXECDIR"/gtk-logout-helper --shutdown" + #define CMD_RESTART LIBEXECDIR"/gtk-logout-helper --restart" +#else + #define CMD_LOGOUT "gnome-session-quit --logout" + #define CMD_SHUTDOWN "gnome-session-quit --power-off" + #define CMD_RESTART CMD_SHUTDOWN /* hmm, no gnome-session-quit --restart? */ +#endif -#define EXTRA_LAUNCHER_DIR "/usr/share/indicators/session/applications" +/** + * Which switch menuitem to show -- based on lockdown settings, + * greeter mode, number of users in the system, and so on. + * See get_switcher_mode() + */ +typedef enum +{ + SWITCHER_MODE_SCREENSAVER, + SWITCHER_MODE_LOCK, + SWITCHER_MODE_SWITCH, + SWITCHER_MODE_SWITCH_OR_LOCK +} +SwitcherMode; + +typedef struct +{ + SessionMenuMgr * mgr; + AccountsUser * user; +} +ActivateUserSessionData; struct _SessionMenuMgr { GObject parent_instance; + DbusmenuMenuitem * parent_mi; - SessionDbus* session_dbus_interface; + DbusmenuMenuitem * lock_mi; + DbusmenuMenuitem * lock_switch_mi; + DbusmenuMenuitem * guest_mi; + DbusmenuMenuitem * logout_mi; + DbusmenuMenuitem * suspend_mi; + DbusmenuMenuitem * hibernate_mi; + DbusmenuMenuitem * restart_mi; + DbusmenuMenuitem * shutdown_mi; - GSettings *lockdown_settings; - GSettings * keybinding_settings; + GSList * user_menuitems; + gint user_menuitem_index; - DbusmenuMenuitem * hibernate_mi; - DbusmenuMenuitem * suspend_mi; - DbusmenuMenuitem * lock_mi; + GSettings * lockdown_settings; + GSettings * indicator_settings; + GSettings * keybinding_settings; gboolean can_hibernate; gboolean can_suspend; gboolean allow_hibernate; gboolean allow_suspend; + gboolean greeter_mode; - IndicatorSessionUPower * upower_proxy; GCancellable * cancellable; - - UsersServiceDbus* users_dbus_interface; - DbusmenuMenuitem * guest_mi; - gboolean greeter_mode; + DBusUPower * upower_proxy; + SessionDbus * session_dbus; + UsersServiceDbus * users_dbus_facade; }; -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); - +static SwitcherMode get_switcher_mode (SessionMenuMgr *); +static void init_upower_proxy (SessionMenuMgr *); +static void update_screensaver_shortcut (SessionMenuMgr *); +static void update_user_menuitems (SessionMenuMgr *); +static void update_session_menuitems (SessionMenuMgr *); +static void update_confirmation_labels (SessionMenuMgr *); -G_DEFINE_TYPE (SessionMenuMgr, session_menu_mgr, G_TYPE_OBJECT); +static void action_func_lock (SessionMenuMgr *); +static void action_func_suspend (SessionMenuMgr *); +static void action_func_hibernate (SessionMenuMgr *); +static void action_func_switch_to_lockscreen (SessionMenuMgr *); +static void action_func_switch_to_greeter (SessionMenuMgr *); +static void action_func_switch_to_guest (SessionMenuMgr *); +static void action_func_switch_to_user (ActivateUserSessionData *); +static void action_func_spawn_async (const char * fmt, ...); -static void -session_menu_mgr_init (SessionMenuMgr *self) -{ - self->can_hibernate = TRUE; - self->can_suspend = TRUE; - self->allow_hibernate = TRUE; - self->allow_suspend = TRUE; +static gboolean is_this_guest_session (void); +static gboolean is_this_live_session (void); - 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); +static void on_guest_logged_in_changed (UsersServiceDbus *, + SessionMenuMgr *); - self->keybinding_settings = g_settings_new (KEYBINDING_SCHEMA); - g_signal_connect (self->keybinding_settings, "changed::" KEY_LOCK_SCREEN, G_CALLBACK(screensaver_keybinding_changed), self); +static void on_user_logged_in_changed (UsersServiceDbus *, + AccountsUser *, + SessionMenuMgr *); - setup_up(self); +/** +*** GObject init / dispose / finalize +**/ - /* 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_DEFINE_TYPE (SessionMenuMgr, session_menu_mgr, G_TYPE_OBJECT); - g_idle_add(lock_screen_setup, NULL); +static void +session_menu_mgr_init (SessionMenuMgr *mgr) +{ + mgr->can_hibernate = TRUE; + mgr->can_suspend = TRUE; + mgr->allow_hibernate = TRUE; + mgr->allow_suspend = TRUE; + + /* Lockdown settings */ + GSettings * s = g_settings_new ("org.gnome.desktop.lockdown"); + g_signal_connect_swapped (s, "changed", + G_CALLBACK(update_session_menuitems), mgr); + g_signal_connect_swapped (s, "changed::disable-lock-screen", + G_CALLBACK(update_user_menuitems), mgr); + g_signal_connect_swapped (s, "changed::disable-user-switching", + G_CALLBACK(update_user_menuitems), mgr); + mgr->lockdown_settings = s; + + /* Indicator settings */ + s = g_settings_new ("com.canonical.indicator.session"); + g_signal_connect_swapped (s, "changed::suppress-logout-restart-shutdown", + G_CALLBACK(update_confirmation_labels), mgr); + g_signal_connect (s, "changed", G_CALLBACK(update_session_menuitems), mgr); + mgr->indicator_settings = s; + + /* Keybinding settings */ + s = g_settings_new ("org.gnome.settings-daemon.plugins.media-keys"); + g_signal_connect_swapped (s, "changed::screensaver", + G_CALLBACK(update_screensaver_shortcut), mgr); + mgr->keybinding_settings = s; + + /* listen for users who appear or log in or log out */ + mgr->users_dbus_facade = g_object_new (USERS_SERVICE_DBUS_TYPE, NULL); + g_signal_connect_swapped (mgr->users_dbus_facade, "user-list-changed", + G_CALLBACK (update_user_menuitems), mgr); + g_signal_connect (mgr->users_dbus_facade, "user-logged-in-changed", + G_CALLBACK(on_user_logged_in_changed), mgr); + g_signal_connect (mgr->users_dbus_facade, "guest-logged-in-changed", + G_CALLBACK(on_guest_logged_in_changed), mgr); + + init_upower_proxy (mgr); } 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); + SessionMenuMgr * mgr = SESSION_MENU_MGR (object); + + if (mgr->cancellable != NULL) + { + g_cancellable_cancel (mgr->cancellable); + g_clear_object (&mgr->cancellable); + } + + g_clear_object (&mgr->indicator_settings); + g_clear_object (&mgr->lockdown_settings); + g_clear_object (&mgr->keybinding_settings); + g_clear_object (&mgr->upower_proxy); + g_clear_object (&mgr->users_dbus_facade); G_OBJECT_CLASS (session_menu_mgr_parent_class)->finalize (object); } @@ -158,117 +215,68 @@ session_menu_mgr_class_init (SessionMenuMgrClass *klass) } /*** -**** +**** Menuitem Helpers ***/ -static void -update_screensaver_shortcut (DbusmenuMenuitem * menuitem, GSettings * settings) +static inline void +mi_set_label (DbusmenuMenuitem * mi, const char * str) { - 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); - } + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, str); } -static void -screensaver_keybinding_changed (GSettings * settings, - const gchar * key G_GNUC_UNUSED, - gpointer userdata) +static inline void +mi_set_type (DbusmenuMenuitem * mi, const char * str) { - update_screensaver_shortcut (SESSION_MENU_MGR(userdata)->lock_mi, settings); + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_TYPE, str); } - -static void -machine_sleep_from_suspend (DbusmenuMenuitem * mi G_GNUC_UNUSED, - guint timestamp G_GNUC_UNUSED, - gpointer userdata) +static inline void +mi_set_visible (DbusmenuMenuitem * mi, gboolean b) { - 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); - } + dbusmenu_menuitem_property_set_bool (mi, DBUSMENU_MENUITEM_PROP_VISIBLE, b); } -static void -machine_sleep_from_hibernate (DbusmenuMenuitem * mi G_GNUC_UNUSED, - guint timestamp G_GNUC_UNUSED, - gpointer userdata) +static inline void +mi_set_logged_in (DbusmenuMenuitem * mi, gboolean b) { - 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); - } + dbusmenu_menuitem_property_set_bool (mi, USER_ITEM_PROP_LOGGED_IN, b); } -/*** -**** -***/ - -/* When allow-suspend changes, rebuild the menus */ -static void -allowed_suspend_cb (GObject * source, GAsyncResult * res, gpointer userdata) +static DbusmenuMenuitem* +mi_new_separator (void) { - 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); - } + DbusmenuMenuitem * mi = dbusmenu_menuitem_new (); + mi_set_type (mi, DBUSMENU_CLIENT_TYPES_SEPARATOR); + return mi; } -/* When allow-hibernate changes, rebuild the menus */ -static void -allowed_hibernate_cb (GObject * source, GAsyncResult * res, gpointer userdata) +static DbusmenuMenuitem* +mi_new (const char * label) { - 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); - } + DbusmenuMenuitem * mi = dbusmenu_menuitem_new (); + mi_set_label (mi, label); + return mi; } +/*** +**** UPower Proxy: +**** +**** 1. While bootstrapping, we invoke the AllowSuspend and AllowHibernate +**** methods to find out whether or not those functions are allowed. +**** 2. While bootstrapping, we get the CanSuspend and CanHibernate properties +**** and also listen for property changes. +**** 3. These four values are used to set suspend and hibernate's visibility +**** +***/ static void -on_upower_properties_changed (IndicatorSessionUPower * upower_proxy, SessionMenuMgr * mgr) +on_upower_properties_changed (SessionMenuMgr * mgr) { gboolean b; gboolean refresh = FALSE; /* suspend */ - b = indicator_session_upower_get_can_suspend (upower_proxy); + b = dbus_upower_get_can_suspend (mgr->upower_proxy); if (mgr->can_suspend != b) { mgr->can_suspend = b; @@ -276,7 +284,7 @@ on_upower_properties_changed (IndicatorSessionUPower * upower_proxy, SessionMenu } /* hibernate */ - b = indicator_session_upower_get_can_hibernate (upower_proxy); + b = dbus_upower_get_can_hibernate (mgr->upower_proxy); if (mgr->can_hibernate != b) { mgr->can_hibernate = b; @@ -285,230 +293,185 @@ on_upower_properties_changed (IndicatorSessionUPower * upower_proxy, SessionMenu if (refresh) { - session_menu_mgr_rebuild_items (mgr); + update_session_menuitems (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) +init_upower_proxy (SessionMenuMgr * mgr) { - self->cancellable = g_cancellable_new (); + mgr->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); + mgr->upower_proxy = dbus_upower_proxy_new_for_bus_sync ( + G_BUS_TYPE_SYSTEM, + 0, + UPOWER_ADDRESS, + UPOWER_PATH, + NULL, + &error); if (error != NULL) { - g_warning ("Error creating cups notify handler: %s", error->message); - g_error_free (error); + g_warning ("Error creating upower proxy: %s", error->message); + g_clear_error (&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); + dbus_upower_call_suspend_allowed_sync (mgr->upower_proxy, + &mgr->allow_suspend, + NULL, + &error); + if (error != NULL) + { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_clear_error (&error); + } + + dbus_upower_call_hibernate_allowed_sync (mgr->upower_proxy, + &mgr->allow_hibernate, + NULL, + &error); + if (error != NULL) + { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_clear_error (&error); + } + + on_upower_properties_changed (mgr); + g_signal_connect_swapped (mgr->upower_proxy, "changed", + G_CALLBACK(on_upower_properties_changed), mgr); } - - g_clear_error (&error); - g_free (cmd); } +/*** +**** Admin Menuitems +***/ -/* 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); -} +#define DEBUG_SHOW_ALL 1 static void -session_menu_mgr_build_static_items (SessionMenuMgr* self, gboolean greeter_mode) +build_admin_menuitems (SessionMenuMgr * mgr) { - const char * name; DbusmenuMenuitem * mi; - DbusmenuMenuitem * logout_mi = NULL; - DbusmenuMenuitem * shutdown_mi = NULL; - - /*** - **** Admin items - ***/ + const gboolean show_settings = DEBUG_SHOW_ALL || !mgr->greeter_mode; - 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); + mi = mi_new (_("About This Computer")); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(action_func_spawn_async), CMD_INFO); + mi = mi_new (_("Ubuntu Help")); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(spawn_command_line_async), "gnome-control-center info"); + G_CALLBACK(action_func_spawn_async), CMD_HELP); + + mi = mi_new_separator (); + mi_set_visible (mi, show_settings); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); - 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); + mi = mi_new (_("System Settings\342\200\246")); + mi_set_visible (mi, show_settings); + dbusmenu_menuitem_child_append (mgr->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"); - } + G_CALLBACK(action_func_spawn_async), + CMD_SYSTEM_SETTINGS); - 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); + mi = mi_new_separator (); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); +} - /*** - **** Account-switching items - ***/ +/*** +**** Session Menuitems +***/ - /* TODO: FIXME */ +static void +update_session_menuitems (SessionMenuMgr * mgr) +{ + gboolean v; + GSettings * s = mgr->indicator_settings; - 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); - } + v = !mgr->greeter_mode + && !is_this_live_session() + && !g_settings_get_boolean (mgr->lockdown_settings, "disable-logout") + && !g_settings_get_boolean (s, "suppress-logout-menuitem"); + mi_set_visible (mgr->logout_mi, v); - /*** - **** Session Items - ***/ + v = mgr->can_suspend + && mgr->allow_suspend; + mi_set_visible (mgr->suspend_mi, v); - 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); + v = mgr->can_hibernate + && mgr->allow_hibernate; + mi_set_visible (mgr->hibernate_mi, v); - 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"); - } + v = !g_settings_get_boolean (s, "suppress-restart-menuitem"); + mi_set_visible (mgr->restart_mi, v); - 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); - } + v = !g_settings_get_boolean (s, "suppress-shutdown-menuitem"); + mi_set_visible (mgr->shutdown_mi, v); +} - 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); - } +/* if confirmation is enabled, + add ellipsis to the labels of items whose actions need confirmation */ +static void +update_confirmation_labels (SessionMenuMgr * mgr) +{ + const gboolean confirm_needed = !g_settings_get_boolean ( + mgr->indicator_settings, + "suppress-logout-restart-shutdown"); - 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 */ + mi_set_label (mgr->logout_mi, confirm_needed ? _("Log Out\342\200\246") + : _("Log Out")); - 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; + mi_set_label (mgr->shutdown_mi, confirm_needed ? _("Switch Off\342\200\246") + : _("Switch Off")); - update_menu_entries(restart_shutdown_logout_mi); + dbusmenu_menuitem_property_set (mgr->restart_mi, RESTART_ITEM_LABEL, + confirm_needed ? _("Restart\342\200\246") + : _("Restart")); } static void -session_menu_mgr_rebuild_items (SessionMenuMgr* self) +build_session_menuitems (SessionMenuMgr* mgr) { - 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); -} + DbusmenuMenuitem * mi; -/*** -**** User Menu -***/ + mi = mi_new_separator (); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); -struct ActivateUserSessionData -{ - SessionMenuMgr * menu_mgr; - AccountsUser * user; -}; + mi = mgr->logout_mi = mi_new (_("Log Out\342\200\246")); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(action_func_spawn_async), CMD_LOGOUT); -/*** -**** -***/ + mi = mgr->suspend_mi = mi_new ("Suspend"); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(action_func_suspend), mgr); + + mi = mgr->hibernate_mi = mi_new (_("Hibernate")); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(action_func_hibernate), mgr); + + mi = mgr->restart_mi = mi_new (_("Restart\342\200\246")); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(action_func_spawn_async), CMD_RESTART); + + mi = mgr->shutdown_mi = mi_new (_("Switch Off\342\200\246")); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(action_func_spawn_async), CMD_SHUTDOWN); + + update_confirmation_labels (mgr); +} + +/**** +***** User Menuitems +****/ + +/* Local Extensions to AccountsUser */ static GQuark get_menuitem_quark (void) @@ -532,12 +495,14 @@ user_get_menuitem (AccountsUser * user) 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); + 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) +get_collision_quark (void) { static GQuark q = 0; @@ -550,15 +515,15 @@ get_name_collision_quark (void) } static gboolean -get_user_name_collision (AccountsUser * user) +user_has_name_collision (AccountsUser * u) { - return g_object_get_qdata (G_OBJECT(user), get_name_collision_quark()) != NULL; + return g_object_get_qdata (G_OBJECT(u), get_collision_quark()) != NULL; } static void -set_user_name_collision (AccountsUser * user, gboolean b) +user_set_name_collision (AccountsUser * u, gboolean b) { - g_object_set_qdata (G_OBJECT(user), get_name_collision_quark(), GINT_TO_POINTER(b)); + g_object_set_qdata (G_OBJECT(u), get_collision_quark(), GINT_TO_POINTER(b)); } /*** @@ -566,7 +531,42 @@ set_user_name_collision (AccountsUser * user, gboolean b) ***/ static void -update_menuitem_icon (DbusmenuMenuitem * mi, AccountsUser * user) +on_guest_logged_in_changed (UsersServiceDbus * usd, + SessionMenuMgr * mgr) +{ + mi_set_logged_in (mgr->guest_mi, + users_service_dbus_is_guest_logged_in (usd)); +} + +/* When a user's login state changes, + update the corresponding menuitem's LOGGED_IN property */ +static void +on_user_logged_in_changed (UsersServiceDbus * usd, + AccountsUser * user, + SessionMenuMgr * mgr) +{ + DbusmenuMenuitem * mi = user_get_menuitem (user); + + if (mi != NULL) + { + mi_set_logged_in (mi, users_service_dbus_is_user_logged_in (usd, user)); + } +} + +static void +update_screensaver_shortcut (SessionMenuMgr * mgr) +{ + gchar * s = g_settings_get_string (mgr->keybinding_settings, "screensaver"); + g_debug ("Keybinding changed to: %s", s); + dbusmenu_menuitem_property_set_shortcut_string (mgr->lock_mi, s); + dbusmenu_menuitem_property_set_shortcut_string (mgr->lock_switch_mi, s); + g_free (s); +} + +static void +on_user_icon_file_changed (AccountsUser * user, + GParamSpec * pspec G_GNUC_UNUSED, + DbusmenuMenuitem * mi) { const gchar * str = accounts_user_get_icon_file (user); @@ -578,299 +578,439 @@ update_menuitem_icon (DbusmenuMenuitem * mi, AccountsUser * user) dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_ICON, str); } +typedef struct +{ + AccountsUser * user; + gulong handler_id; +} +UserChangeListenerData; + +/* when the menuitem is destroyed, + it should stop listening for changes to the UserAccount properties :) */ static void -on_user_icon_file_changed (AccountsUser * user, GParamSpec * pspec, DbusmenuMenuitem * mi) +on_user_menuitem_destroyed (UserChangeListenerData * data) { - update_menuitem_icon (mi, user); + g_signal_handler_disconnect (data->user, data->handler_id); + g_free (data); } static DbusmenuMenuitem* -create_user_menuitem (SessionMenuMgr * menu_mgr, AccountsUser * user) +user_menuitem_new (AccountsUser * user, SessionMenuMgr * mgr) { DbusmenuMenuitem * mi = dbusmenu_menuitem_new (); - dbusmenu_menuitem_property_set (mi, - DBUSMENU_MENUITEM_PROP_TYPE, - USER_ITEM_TYPE); + mi_set_type (mi, 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); + GString * gstr = g_string_new (accounts_user_get_real_name (user)); + if (user_has_name_collision (user)) + { + g_string_append_printf (gstr, " (%s)", accounts_user_get_user_name(user)); + } + dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, gstr->str); + g_string_free (gstr, TRUE); /* 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); + mi_set_logged_in (mi, + users_service_dbus_is_user_logged_in (mgr->users_dbus_facade, user)); - /* 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 icon property & listen for changes */ + UserChangeListenerData * cd = g_new0 (UserChangeListenerData, 1); + cd->user = user; + cd->handler_id = g_signal_connect (user, "notify::icon-file", + G_CALLBACK(on_user_icon_file_changed), mi); + g_object_weak_ref (G_OBJECT(mi), (GWeakNotify)on_user_menuitem_destroyed, cd); + on_user_icon_file_changed (user, NULL, mi); /* set the is-current-user property */ + const gboolean is_current_user = + !g_strcmp0 (g_get_user_name(), accounts_user_get_user_name(user)); dbusmenu_menuitem_property_set_bool (mi, USER_ITEM_PROP_IS_CURRENT_USER, - !g_strcmp0 (user_name, g_get_user_name())); + is_current_user); /* set the activate callback */ - struct ActivateUserSessionData * data = g_new (struct ActivateUserSessionData, 1); + ActivateUserSessionData * data = g_new (ActivateUserSessionData, 1); data->user = user; - data->menu_mgr = menu_mgr; + data->mgr = mgr; g_signal_connect_data (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (activate_user_session), + G_CALLBACK (action_func_switch_to_user), data, (GClosureNotify)g_free, - 0); + G_CONNECT_SWAPPED); /* 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) +/* for sorting AccountsUsers from most to least frequently used */ +static gint +compare_users_by_login_frequency (gconstpointer a, gconstpointer b) { - 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); - } + const guint64 a_freq = accounts_user_get_login_frequency (ACCOUNTS_USER(a)); + const guint64 b_freq = accounts_user_get_login_frequency (ACCOUNTS_USER(b)); + if (a_freq > b_freq) return -1; + if (a_freq < b_freq) return 1; + return 0; } -/* 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) +/* for sorting AccountsUsers by name */ +static gint +compare_users_by_username (gconstpointer ga, gconstpointer gb) { - DbusmenuMenuitem * mi = user_get_menuitem (user); + AccountsUser * a = ACCOUNTS_USER(ga); + AccountsUser * b = ACCOUNTS_USER(gb); - if (mi != NULL) + 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 */ { - 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); + user_set_name_collision (a, TRUE); + user_set_name_collision (b, TRUE); } + + return ret; } -/* Builds up the menu for us */ -static void -menu_mgr_rebuild_users (SessionMenuMgr *self) +static gboolean +is_user_switching_allowed (SessionMenuMgr * mgr) { - GList *u; - gboolean can_activate; + /* maybe it's locked down */ + if (g_settings_get_boolean (mgr->lockdown_settings, "disable-user-switching")) + return FALSE; - /* 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); + /* maybe the seat doesn't support activation */ + if (!users_service_dbus_can_activate_session (mgr->users_dbus_facade)) + return FALSE; - /* 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 + return TRUE; +} - /* 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) +static void +build_user_menuitems (SessionMenuMgr * mgr) +{ + DbusmenuMenuitem * mi; + GSList * items = NULL; + gint pos = mgr->user_menuitem_index; + const char * current_real_name = NULL; + + /** + *** Start Screen Saver + *** Switch Account... + *** Lock + *** Lock / Switch Account... + **/ + + const gboolean show_all = DEBUG_SHOW_ALL; + const SwitcherMode mode = get_switcher_mode (mgr); + + mi = mi_new (_("Start Screen Saver")); + mi_set_visible (mi, show_all || (mode == SWITCHER_MODE_SCREENSAVER)); + dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); + items = g_slist_prepend (items, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK (action_func_lock), mgr); + + mi = mi_new (_("Switch User Account\342\200\246")); + mi_set_visible (mi, show_all || (mode == SWITCHER_MODE_SWITCH)); + dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); + items = g_slist_prepend (items, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK (action_func_switch_to_greeter), mgr); + + mi = mgr->lock_mi = mi_new (_("Lock")); + mi_set_visible (mi, show_all || (mode == SWITCHER_MODE_LOCK)); + dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); + items = g_slist_prepend (items, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK (action_func_switch_to_lockscreen), mgr); + + mi = mgr->lock_switch_mi = mi_new (_("Lock/Switch Account\342\200\246")); + mi_set_visible (mi, show_all || (mode == SWITCHER_MODE_SWITCH_OR_LOCK)); + dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); + items = g_slist_prepend (items, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK (action_func_switch_to_lockscreen), mgr); + + const gboolean guest_allowed = + users_service_dbus_guest_session_enabled (mgr->users_dbus_facade); + const gboolean is_guest = is_this_guest_session(); + mi = mi_new (_("Guest Session")); + mi_set_type (mi, USER_ITEM_TYPE); + mi_set_visible (mi, guest_allowed && !is_guest); + dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); + on_guest_logged_in_changed (mgr->users_dbus_facade, mgr); + items = g_slist_prepend (items, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK (action_func_switch_to_guest), mgr); + mgr->guest_mi = mi; + if (guest_allowed && is_guest) { - 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")); + current_real_name = _("Guest"); } - - - - users = g_list_sort (users, compare_users_by_username); + + /*** + **** Users + ***/ - for (u = users; u != NULL; u = g_list_next (u)) - { - AccountsUser * user = u->data; + /* if we can switch to another user account, show them here */ + if (is_user_switching_allowed (mgr)) + { + GList * users = users_service_dbus_get_user_list (mgr->users_dbus_facade); + + /* pick the most frequently used accounts */ + const int MAX_USERS = 12; /* this limit comes from the spec */ + if (g_list_length(users) > MAX_USERS) + { + users = g_list_sort (users, compare_users_by_login_frequency); + GList * last = g_list_nth (users, MAX_USERS-1); + GList * remainder = last->next; + last->next = NULL; + remainder->prev = NULL; + g_list_free (remainder); + } + + /* Sort the users by name for display */ + users = g_list_sort (users, compare_users_by_username); + + /* Create menuitems for them */ + int i; + GList * u; + const char * const username = g_get_user_name(); + for (i=0, u=users; inext, i++) + { + AccountsUser * user = u->data; + DbusmenuMenuitem * mi = user_menuitem_new (user, mgr); + dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); + items = g_slist_prepend (items, mi); + + if (!g_strcmp0 (username, accounts_user_get_user_name(user))) + { + current_real_name = accounts_user_get_real_name (user); + } + } + g_list_free(users); + } - DbusmenuMenuitem * mi = create_user_menuitem (self, user); - dbusmenu_menuitem_child_append (self->parent_mi, mi); + /* separator */ + mi = mi_new_separator (); + dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); + items = g_slist_prepend (items, 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); - } - } + if (current_real_name != NULL) + { + session_dbus_set_users_real_name (mgr->session_dbus, + current_real_name); + } - g_list_free(users); - } + update_screensaver_shortcut (mgr); + mgr->user_menuitems = items; +} - // 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); +static void +update_user_menuitems (SessionMenuMgr * mgr) +{ + /* remove any previous user menuitems */ + GSList * l; + for (l=mgr->user_menuitems; l!=NULL; l=l->next) + { + dbusmenu_menuitem_child_delete (mgr->parent_mi, l->data); + } + g_slist_free (mgr->user_menuitems); + mgr->user_menuitems = NULL; - 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…")); + /* add fresh user menuitems */ + build_user_menuitems (mgr); +} - 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); +/*** +**** +***/ +static void +action_func_spawn_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); } -/* Check to see if the lockdown key is protecting from - locking the screen. If not, lock it. */ +/* Calling "Lock" locks the screen & goes to black. + Calling "SimulateUserActivity" afterwards shows the Lock Screen. */ static void -lock_if_possible (SessionMenuMgr * menu_mgr) +lock_helper (SessionMenuMgr * mgr, gboolean show_lock_screen) { - if (!g_settings_get_boolean (menu_mgr->lockdown_settings, LOCKDOWN_KEY_SCREENSAVER)) + if (!g_settings_get_boolean (mgr->lockdown_settings, "disable-lock-screen")) { - lock_screen(NULL, 0, NULL); + GError * error = NULL; + GDBusProxy * proxy = g_dbus_proxy_new_for_bus_sync ( + G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.gnome.ScreenSaver", + "/org/gnome/ScreenSaver", + "org.gnome.ScreenSaver", + NULL, + &error); + + if (error == NULL) + { + g_dbus_proxy_call_sync (proxy, "Lock", + NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, + &error); + } + + if ((error == NULL) && show_lock_screen) + { + g_dbus_proxy_call_sync (proxy, "SimulateUserActivity", + NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, + &error); + } + + if (error != NULL) + { + g_warning ("Error locking screen: %s", error->message); + } + + g_clear_object (&proxy); + g_clear_error (&error); } } -/* Starts a new generic session */ static void -activate_new_session (DbusmenuMenuitem * mi, guint timestamp, gpointer user_data) +action_func_lock (SessionMenuMgr * mgr) { - SessionMenuMgr * menu_mgr = SESSION_MENU_MGR (user_data); - g_return_if_fail (menu_mgr != NULL); + lock_helper (mgr, FALSE); +} - lock_if_possible (menu_mgr); - users_service_dbus_show_greeter (menu_mgr->users_dbus_interface); +static void +action_func_switch_to_lockscreen (SessionMenuMgr * mgr) +{ + lock_helper (mgr, TRUE); } -/* Activates a session for a particular user. */ static void -activate_user_session (DbusmenuMenuitem *mi, guint timestamp, gpointer user_data) +action_func_switch_to_greeter (SessionMenuMgr * mgr) { - struct ActivateUserSessionData * data = user_data; + action_func_lock (mgr); + users_service_dbus_show_greeter (mgr->users_dbus_facade); +} - lock_if_possible (data->menu_mgr); - users_service_dbus_activate_user_session (data->menu_mgr->users_dbus_interface, data->user); +static void +action_func_switch_to_user (ActivateUserSessionData * data) +{ + action_func_lock (data->mgr); + users_service_dbus_activate_user_session (data->mgr->users_dbus_facade, + 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) +static void +action_func_switch_to_guest (SessionMenuMgr * mgr) { - AccountsUser * a = ACCOUNTS_USER(ga); - AccountsUser * b = ACCOUNTS_USER(gb); + action_func_lock (mgr); + users_service_dbus_activate_guest_session (mgr->users_dbus_facade); +} - const int ret = g_strcmp0 (accounts_user_get_real_name (a), - accounts_user_get_real_name (b)); +static void +action_func_suspend (SessionMenuMgr * mgr) +{ + GError * error = NULL; - if (!ret) /* names are the same, so both have a name collision */ + dbus_upower_call_suspend_sync (mgr->upower_proxy, + mgr->cancellable, + &error); + + if (error != NULL) { - set_user_name_collision (a, TRUE); - set_user_name_collision (b, TRUE); + g_warning ("%s: %s", G_STRFUNC, error->message); + g_clear_error (&error); } - - return ret; } static void -activate_user_accounts (DbusmenuMenuitem *mi, - guint timestamp, - gpointer user_data) +action_func_hibernate (SessionMenuMgr * mgr) { 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)); + dbus_upower_call_hibernate_sync (mgr->upower_proxy, + mgr->cancellable, + &error); - menu_mgr_rebuild_users (menu_mgr); + if (error != NULL) + { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_clear_error (&error); + } } +/*** +**** +***/ -/* 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) +static gboolean +is_this_live_session (void) +{ + const struct passwd * const pw = getpwuid (geteuid()); + return (pw->pw_uid==999) && !g_strcmp0("ubuntu",pw->pw_name); +} + +static SwitcherMode +get_switcher_mode (SessionMenuMgr * mgr) { - SessionMenuMgr * menu_mgr = SESSION_MENU_MGR (user_data); - g_return_if_fail (menu_mgr != NULL); + SwitcherMode mode; + + const gboolean can_lock = !g_settings_get_boolean (mgr->lockdown_settings, + "disable-lock-screen"); + const gboolean can_switch = is_user_switching_allowed (mgr); + + if (!can_lock && !can_switch) /* hmm, quite an extreme lockdown */ + { + mode = SWITCHER_MODE_SCREENSAVER; + } + else if (is_this_live_session()) /* live sessions can't lock or switch */ + { + mode = SWITCHER_MODE_SCREENSAVER; + } + else if (!can_switch) /* switching's locked down */ + { + mode = SWITCHER_MODE_LOCK; + } + else if (is_this_guest_session ()) /* guest sessions can't lock */ + { + mode = SWITCHER_MODE_SWITCH; + } + else + { + GList * l = users_service_dbus_get_user_list (mgr->users_dbus_facade); + const size_t user_count = g_list_length (l); + g_list_free (l); - lock_if_possible (menu_mgr); - users_service_dbus_activate_guest_session (menu_mgr->users_dbus_interface); + mode = user_count < 2 + ? SWITCHER_MODE_LOCK /* you can't switch if no other users */ + : SWITCHER_MODE_SWITCH_OR_LOCK; + } + + return mode; } + /*** **** ***/ @@ -879,11 +1019,14 @@ 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; + SessionMenuMgr* mgr = g_object_new (SESSION_TYPE_MENU_MGR, NULL); + mgr->parent_mi = parent_mi; + mgr->greeter_mode = greeter_mode; + mgr->session_dbus = session_dbus; + build_admin_menuitems (mgr); + const guint n = g_list_length (dbusmenu_menuitem_get_children (parent_mi)); + mgr->user_menuitem_index = n; + build_user_menuitems (mgr); + build_session_menuitems (mgr); + return mgr; } diff --git a/src/session-menu-mgr.h b/src/session-menu-mgr.h index 0fa7baa..21d5356 100644 --- a/src/session-menu-mgr.h +++ b/src/session-menu-mgr.h @@ -45,8 +45,8 @@ struct _SessionMenuMgrClass GType session_menu_mgr_get_type (void) G_GNUC_CONST; SessionMenuMgr* session_menu_mgr_new (DbusmenuMenuitem * parent_mi, - SessionDbus * session_dbus, - gboolean greeter_mode); + SessionDbus * session_dbus, + gboolean greeter_mode); G_END_DECLS diff --git a/src/settings-helper.c b/src/settings-helper.c index d8e858f..0ab188a 100644 --- a/src/settings-helper.c +++ b/src/settings-helper.c @@ -20,138 +20,27 @@ with this program. If not, see . */ #include -#include - -#include -#include #include "dbus-shared-names.h" #include "settings-helper.h" static GSettings* settings = NULL; -static guint confirmation_notify = 0; -static guint logout_notify = 0; -static guint restart_notify = 0; -static guint shutdown_notify = 0; - static gboolean -build_settings (void) { - if (settings == NULL) { - settings = g_settings_new (SESSION_SCHEMA); - } - if (settings == NULL) { - return FALSE; - } - return TRUE; -} - -gboolean -supress_confirmations (void) { - gboolean settings_built = build_settings(); - g_return_val_if_fail(settings_built, FALSE); - return g_settings_get_boolean (settings, SUPPRESS_KEY) ; -} +build_settings (void) +{ + if (G_UNLIKELY(settings == NULL)) + { + settings = g_settings_new (SESSION_SCHEMA); + } -gboolean -show_logout (void) { - gboolean settings_built = build_settings(); - g_return_val_if_fail(settings_built, TRUE); - return !g_settings_get_boolean (settings, LOGOUT_KEY) ; + return settings != NULL; } gboolean -show_restart (void) { - gboolean settings_built = build_settings(); - g_return_val_if_fail(settings_built, TRUE); - return !g_settings_get_boolean (settings, RESTART_KEY) ; -} - -gboolean -show_shutdown (void) { - gboolean settings_built = build_settings(); - g_return_val_if_fail(settings_built, TRUE); - return !g_settings_get_boolean (settings, SHUTDOWN_KEY) ; -} - -static void update_menu_entries_callback (GSettings * settings, const gchar * key, gpointer data) { - RestartShutdownLogoutMenuItems * restart_shutdown_logout_mi = (RestartShutdownLogoutMenuItems*) data; - - if(g_strcmp0 (key, SUPPRESS_KEY) == 0) { - if (g_settings_get_boolean (settings, key)) { - dbusmenu_menuitem_property_set(restart_shutdown_logout_mi->logout_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Log Out")); - dbusmenu_menuitem_property_set(restart_shutdown_logout_mi->restart_mi, RESTART_ITEM_LABEL, _("Restart")); - dbusmenu_menuitem_property_set(restart_shutdown_logout_mi->shutdown_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Shut Down")); - } else { - dbusmenu_menuitem_property_set(restart_shutdown_logout_mi->logout_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Log Out…")); - dbusmenu_menuitem_property_set(restart_shutdown_logout_mi->restart_mi, RESTART_ITEM_LABEL, _("Restart…")); - dbusmenu_menuitem_property_set(restart_shutdown_logout_mi->shutdown_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Shut Down…")); - } - } -} - -static void -update_logout_callback (GSettings * settings, const gchar * key, gpointer data) { - DbusmenuMenuitem * mi = (DbusmenuMenuitem*) data; +supress_confirmations (void) +{ + g_return_val_if_fail (build_settings(), FALSE); - if(g_strcmp0 (key, LOGOUT_KEY) == 0) { - dbusmenu_menuitem_property_set_bool(mi, DBUSMENU_MENUITEM_PROP_VISIBLE, !g_settings_get_boolean(settings, key)); - } + return g_settings_get_boolean (settings, SUPPRESS_KEY) ; } - -static void -update_restart_callback (GSettings * settings, const gchar * key, gpointer data) { - DbusmenuMenuitem * mi = (DbusmenuMenuitem*) data; - - if(g_strcmp0 (key, RESTART_KEY) == 0) { - dbusmenu_menuitem_property_set_bool(mi, DBUSMENU_MENUITEM_PROP_VISIBLE, !g_settings_get_boolean(settings, key)); - } -} - -static void -update_shutdown_callback (GSettings * settings, const gchar * key, gpointer data) { - DbusmenuMenuitem * mi = (DbusmenuMenuitem*) data; - - if(g_strcmp0 (key, SHUTDOWN_KEY) == 0) { - dbusmenu_menuitem_property_set_bool(mi, DBUSMENU_MENUITEM_PROP_VISIBLE, !g_settings_get_boolean(settings, key)); - } -} - -void -update_menu_entries(RestartShutdownLogoutMenuItems * restart_shutdown_logout_mi) { - /* If we don't have a client, build one. */ - gboolean settings_built = build_settings(); - g_return_if_fail(settings_built); - - if (confirmation_notify != 0) { - g_signal_handler_disconnect (settings, confirmation_notify); - confirmation_notify = 0; - } - - if (logout_notify != 0) { - g_signal_handler_disconnect (settings, logout_notify); - logout_notify = 0; - } - - if (restart_notify != 0) { - g_signal_handler_disconnect (settings, restart_notify); - restart_notify = 0; - } - - if (shutdown_notify != 0) { - g_signal_handler_disconnect (settings, shutdown_notify); - shutdown_notify = 0; - } - - confirmation_notify = g_signal_connect (settings, "changed::" SUPPRESS_KEY, - G_CALLBACK(update_menu_entries_callback), restart_shutdown_logout_mi); - logout_notify = g_signal_connect (settings, "changed::" LOGOUT_KEY, - G_CALLBACK(update_logout_callback), restart_shutdown_logout_mi->logout_mi); - restart_notify = g_signal_connect (settings, "changed::" RESTART_KEY, - G_CALLBACK(update_restart_callback), restart_shutdown_logout_mi->restart_mi); - shutdown_notify = g_signal_connect (settings, "changed::" SHUTDOWN_KEY, - G_CALLBACK(update_shutdown_callback), restart_shutdown_logout_mi->shutdown_mi); - - return; -} - diff --git a/src/settings-helper.h b/src/settings-helper.h index 17304af..8c4b2e8 100644 --- a/src/settings-helper.h +++ b/src/settings-helper.h @@ -23,11 +23,6 @@ with this program. If not, see . #ifndef __GCONF_HELPER_H__ #define __GCONF_HELPER_H__ -#include - -#include -#include - #define SESSION_SCHEMA "com.canonical.indicator.session" #define SUPPRESS_KEY "suppress-logout-restart-shutdown" #define LOGOUT_KEY "suppress-logout-menuitem" @@ -35,25 +30,6 @@ with this program. If not, see . #define SHUTDOWN_KEY "suppress-shutdown-menuitem" #define SHOW_USER_MENU "user-show-menu" -#define LOCKDOWN_SCHEMA "org.gnome.desktop.lockdown" -#define LOCKDOWN_KEY_USER "disable-user-switching" -#define LOCKDOWN_KEY_SCREENSAVER "disable-lock-screen" -#define KEYBINDING_SCHEMA "org.gnome.settings-daemon.plugins.media-keys" -#define KEY_LOCK_SCREEN "screensaver" - -typedef struct _RestartShutdownLogoutMenuItems -{ - DbusmenuMenuitem * logout_mi; - DbusmenuMenuitem * restart_mi; - DbusmenuMenuitem * shutdown_mi; -} -RestartShutdownLogoutMenuItems; - -void update_menu_entries(RestartShutdownLogoutMenuItems*); gboolean supress_confirmations (void); -gboolean show_logout (void); -gboolean show_restart (void); -gboolean show_shutdown (void); - #endif /* __GCONF_HELPER__ */ -- cgit v1.2.3 From c9e0ebffe5cb3787c5437bd6ad8482ed8a432ddb Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 18 Jun 2012 12:35:05 -0500 Subject: clearing house: the remainder of bugfixes & readability changes --- src/Makefile.am | 5 +- src/dbus-shared-names.h | 69 ------ src/gtk-logout-helper.c | 35 +-- src/indicator-session.c | 83 ++++--- src/session-dbus.c | 5 +- src/session-menu-mgr.c | 546 +++++++++++++++++++++++++++++------------------ src/session-service.c | 68 +++--- src/settings-helper.c | 46 ---- src/settings-helper.h | 35 --- src/shared-names.h | 57 +++++ src/users-service-dbus.c | 10 +- 11 files changed, 489 insertions(+), 470 deletions(-) delete mode 100644 src/dbus-shared-names.h delete mode 100644 src/settings-helper.c delete mode 100644 src/settings-helper.h create mode 100644 src/shared-names.h (limited to 'src/Makefile.am') diff --git a/src/Makefile.am b/src/Makefile.am index 24f2ee8..7bc6306 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,7 +20,7 @@ sessionlib_LTLIBRARIES = libsession.la libsession_la_SOURCES = \ indicator-session.c \ gen-session-dbus.xml.h \ - dbus-shared-names.h \ + shared-names.h \ user-widget.c \ user-widget.h libsession_la_CFLAGS = \ @@ -130,7 +130,6 @@ indicator_session_service_SOURCES = \ session-dbus.c \ session-dbus.h \ gen-session-dbus.xml.c \ - settings-helper.c \ users-service-dbus.h \ users-service-dbus.c \ session-menu-mgr.h \ @@ -157,8 +156,6 @@ if BUILD_GTKLOGOUTHELPER gtk_logout_helper_SOURCES = \ $(dbus_consolekit_manager_sources) \ gtk-logout-helper.c \ - settings-helper.c \ - settings-helper.h \ dialog.c \ dialog.h diff --git a/src/dbus-shared-names.h b/src/dbus-shared-names.h deleted file mode 100644 index 876735a..0000000 --- a/src/dbus-shared-names.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould - -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 . -*/ - -#ifndef __DBUS_SHARED_NAMES_H__ -#define __DBUS_SHARED_NAMES_H__ - -typedef enum { - UP_TO_DATE, - CHECKING_FOR_UPDATES, - UPDATES_AVAILABLE, - UPGRADE_IN_PROGRESS, - FINISHED, - RESTART_NEEDED, - DONT_KNOW -}AptState; - -typedef enum { - SIMULATION, - REAL -}TransactionType; - -//#define INDICATOR_USERS_DBUS_NAME INDICATOR_SESSION_DBUS_NAME -//#define INDICATOR_USERS_DBUS_OBJECT "/com/canonical/indicator/users/menu" -//#define INDICATOR_USERS_SERVICE_DBUS_OBJECT "/org/gnome/DisplayManager/UserManager" -//#define INDICATOR_USERS_SERVICE_DBUS_INTERFACE "org.gnome.DisplayManager.UserManager" - -#define INDICATOR_SESSION_DBUS_NAME "com.canonical.indicator.session" -#define INDICATOR_SESSION_DBUS_OBJECT "/com/canonical/indicator/session/menu" -#define INDICATOR_SESSION_DBUS_VERSION 0 - -#define INDICATOR_SESSION_SERVICE_DBUS_OBJECT "/com/canonical/indicator/session/service" -#define INDICATOR_SESSION_SERVICE_DBUS_IFACE "com.canonical.indicator.session.service" - -#define USER_ITEM_TYPE "x-canonical-user-item" -#define USER_ITEM_PROP_NAME "user-item-name" -#define USER_ITEM_PROP_LOGGED_IN "user-item-logged-in" -#define USER_ITEM_PROP_IS_CURRENT_USER "user-item-is-current-user" -#define USER_ITEM_PROP_ICON "user-item-icon-path" -#define USER_ITEM_ICON_DEFAULT "avatar-default" - -#define RESTART_ITEM_TYPE "x-canonical-restart-item" -#define RESTART_ITEM_LABEL "restart-label" -#define RESTART_ITEM_ICON "restart-icon" - -#define ICON_DEFAULT "system-devices-panel" -#define ICON_RESTART "system-devices-panel-alert" -#define GREETER_ICON_DEFAULT "system-shutdown-panel" -#define GREETER_ICON_RESTART "system-shutdown-panel-restart" - -#endif /* __DBUS_SHARED_NAMES_H__ */ diff --git a/src/gtk-logout-helper.c b/src/gtk-logout-helper.c index 360dd0f..b311701 100644 --- a/src/gtk-logout-helper.c +++ b/src/gtk-logout-helper.c @@ -8,16 +8,16 @@ Authors: Ted Gould Christoph Korn -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 +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 +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 +You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -28,7 +28,7 @@ with this program. If not, see . #include #include #include "dialog.h" -#include "settings-helper.h" +#include "shared-names.h" static void consolekit_fallback (LogoutDialogType action) @@ -91,7 +91,7 @@ session_action (LogoutDialogType action) GError * error = NULL; gboolean res = FALSE; - sbus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); + sbus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); if (sbus == NULL) { g_warning("Unable to get DBus session bus."); return; @@ -113,15 +113,15 @@ session_action (LogoutDialogType action) if (action == LOGOUT_DIALOG_TYPE_LOG_OUT) { g_debug("Asking Session manager to 'Logout'"); - res = dbus_g_proxy_call_with_timeout (sm_proxy, "Logout", INT_MAX, &error, + res = dbus_g_proxy_call_with_timeout (sm_proxy, "Logout", INT_MAX, &error, G_TYPE_UINT, 1, G_TYPE_INVALID, G_TYPE_INVALID); } else if (action == LOGOUT_DIALOG_TYPE_SHUTDOWN) { g_debug("Asking Session manager to 'RequestShutdown'"); - res = dbus_g_proxy_call_with_timeout (sm_proxy, "RequestShutdown", INT_MAX, &error, + res = dbus_g_proxy_call_with_timeout (sm_proxy, "RequestShutdown", INT_MAX, &error, G_TYPE_INVALID, G_TYPE_INVALID); } else if (action == LOGOUT_DIALOG_TYPE_RESTART) { g_debug("Asking Session manager to 'RequestReboot'"); - res = dbus_g_proxy_call_with_timeout (sm_proxy, "RequestReboot", INT_MAX, &error, + res = dbus_g_proxy_call_with_timeout (sm_proxy, "RequestReboot", INT_MAX, &error, G_TYPE_INVALID, G_TYPE_INVALID); } else { g_warning ("Unknown session action"); @@ -177,6 +177,17 @@ static GOptionEntry options[] = { {NULL} }; +static gboolean +suppress_confirmations (void) +{ + GSettings * s = g_settings_new (SESSION_SCHEMA); + const gboolean suppress = g_settings_get_boolean (s, SUPPRESS_KEY); + g_clear_object (&s); + return suppress; +} + + + int main (int argc, char * argv[]) { @@ -205,7 +216,7 @@ main (int argc, char * argv[]) INDICATOR_ICONS_DIR); GtkWidget * dialog = NULL; - if (!supress_confirmations()) { + if (!suppress_confirmations()) { g_debug("Showing dialog to ask for user confirmation"); dialog = GTK_WIDGET(logout_dialog_new(type)); } diff --git a/src/indicator-session.c b/src/indicator-session.c index d6c2599..53ff87e 100644 --- a/src/indicator-session.c +++ b/src/indicator-session.c @@ -1,23 +1,23 @@ /* A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. +into the gnome-panel using its applet interface. Copyright 2009 Canonical Ltd. Authors: Ted Gould Conor Curran - -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 + +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 +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 +You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -38,7 +38,7 @@ with this program. If not, see . #include #include -#include "dbus-shared-names.h" +#include "shared-names.h" #include "user-widget.h" #define INDICATOR_SESSION_TYPE (indicator_session_get_type ()) @@ -97,10 +97,10 @@ static void indicator_session_finalize (GObject *object); static GList* indicator_session_get_entries (IndicatorObject* obj); static guint indicator_session_get_location (IndicatorObject * io, IndicatorObjectEntry * entry); - + G_DEFINE_TYPE (IndicatorSession, indicator_session, INDICATOR_OBJECT_TYPE); -static void +static void indicator_session_class_init (IndicatorSessionClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); @@ -139,12 +139,12 @@ indicator_session_init (IndicatorSession *self) g_settings_bind (self->settings, "show-real-name-on-panel", self->entry.label, "visible", G_SETTINGS_BIND_GET); - + gtk_widget_show (GTK_WIDGET(self->entry.menu)); gtk_widget_show (GTK_WIDGET(self->entry.image)); g_object_ref_sink (self->entry.menu); g_object_ref_sink (self->entry.image); - + // set up the handlers DbusmenuClient * menu_client = DBUSMENU_CLIENT(dbusmenu_gtkmenu_get_client(DBUSMENU_GTKMENU(self->entry.menu))); dbusmenu_client_add_type_handler (menu_client, @@ -198,7 +198,7 @@ static guint indicator_session_get_location (IndicatorObject * io, IndicatorObjectEntry * entry) { - return 0; + return 0; } /* callback for the service manager state of being */ @@ -218,10 +218,10 @@ service_connection_cb (IndicatorServiceManager * sm, gboolean connected, gpointe -1, NULL, user_real_name_get_cb, - user_data); + user_data); return; } - + self->service_proxy_cancel = g_cancellable_new(); g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, @@ -232,7 +232,7 @@ service_connection_cb (IndicatorServiceManager * sm, gboolean connected, gpointe self->service_proxy_cancel, service_proxy_cb, self); - } + } return; } @@ -260,7 +260,7 @@ service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data) self->service_proxy = proxy; g_signal_connect(proxy, "g-signal", G_CALLBACK(receive_signal), self); - + // Fetch the user's real name for the user entry label g_dbus_proxy_call (self->service_proxy, "GetUserRealName", @@ -277,17 +277,13 @@ service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data) static gboolean new_user_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, - DbusmenuClient * client, - gpointer user_data) + DbusmenuClient * client, + gpointer user_data) { - - - GtkWidget* user_item = NULL; - - g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); - g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); + g_return_val_if_fail (DBUSMENU_IS_MENUITEM(newitem), FALSE); + g_return_val_if_fail (DBUSMENU_IS_GTKCLIENT(client), FALSE); - user_item = user_widget_new(newitem); + GtkWidget * user_item = user_widget_new (newitem); GtkMenuItem *user_widget = GTK_MENU_ITEM(user_item); @@ -308,22 +304,23 @@ new_user_item (DbusmenuMenuitem * newitem, static void user_real_name_get_cb (GObject * obj, GAsyncResult * res, gpointer user_data) { - IndicatorSession * self = INDICATOR_SESSION(user_data); - GError * error = NULL; - GVariant * result; + IndicatorSession * self = INDICATOR_SESSION(user_data); - result = g_dbus_proxy_call_finish(self->service_proxy, res, &error); + GError * error = NULL; + GVariant * result = g_dbus_proxy_call_finish(self->service_proxy, res, &error); - if (error != NULL) { - g_warning ("unable to complete real name dbus query"); - g_error_free (error); - return; - } - - const gchar* username = NULL; - g_variant_get (result, "(&s)", &username); - indicator_session_update_users_label (self, username); - return; + if (error != NULL) + { + g_warning ("Unable to complete real name dbus query: %s", error->message); + g_clear_error (&error); + } + else + { + const gchar * username = NULL; + g_variant_get (result, "(&s)", &username); + indicator_session_update_users_label (self, username); + g_variant_unref (result); + } } /* Receives all signals from the service, routed to the appropriate functions */ @@ -409,8 +406,8 @@ build_restart_item (DbusmenuMenuitem * newitem, } static void -indicator_session_update_users_label (IndicatorSession * self, +indicator_session_update_users_label (IndicatorSession * self, const gchar * name) -{ +{ gtk_label_set_text (self->entry.label, name ? name : ""); } diff --git a/src/session-dbus.c b/src/session-dbus.c index 4b9d45f..4ece444 100644 --- a/src/session-dbus.c +++ b/src/session-dbus.c @@ -235,11 +235,8 @@ session_dbus_set_users_real_name (SessionDbus * session, const gchar * name) { SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(session); GError * error = NULL; - if (priv->name != NULL) { - g_free(priv->name); - priv->name = NULL; - } + g_free (priv->name); priv->name = g_strdup(name); if (priv->bus != NULL) { diff --git a/src/session-menu-mgr.c b/src/session-menu-mgr.c index c6de0b1..752a6a6 100644 --- a/src/session-menu-mgr.c +++ b/src/session-menu-mgr.c @@ -2,26 +2,26 @@ Copyright 2011 Canonical Ltd. Authors: - Conor Curran Charles Kerr + Conor Curran -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 +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 +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 +You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include -#include +#include /* geteuid(), getpwuid() */ #include #include @@ -29,11 +29,13 @@ with this program. If not, see . #include #include -#include "dbus-shared-names.h" #include "dbus-upower.h" #include "session-menu-mgr.h" +#include "shared-names.h" #include "users-service-dbus.h" +#define DEBUG_SHOW_ALL FALSE + #define UPOWER_ADDRESS "org.freedesktop.UPower" #define UPOWER_PATH "/org/freedesktop/UPower" @@ -41,13 +43,15 @@ with this program. If not, see . #define CMD_INFO "gnome-control-center info" #define CMD_SYSTEM_SETTINGS "gnome-control-center" #ifdef HAVE_GTKLOGOUTHELPER + #define HAVE_RESTART_CMD TRUE + #define CMD_RESTART LIBEXECDIR"/gtk-logout-helper --restart" #define CMD_LOGOUT LIBEXECDIR"/gtk-logout-helper --logout" #define CMD_SHUTDOWN LIBEXECDIR"/gtk-logout-helper --shutdown" - #define CMD_RESTART LIBEXECDIR"/gtk-logout-helper --restart" #else + #define HAVE_RESTART_CMD FALSE /* hmm, no gnome-session-quit --restart? */ + #define CMD_RESTART "" #define CMD_LOGOUT "gnome-session-quit --logout" #define CMD_SHUTDOWN "gnome-session-quit --power-off" - #define CMD_RESTART CMD_SHUTDOWN /* hmm, no gnome-session-quit --restart? */ #endif /** @@ -64,18 +68,23 @@ typedef enum } SwitcherMode; -typedef struct -{ - SessionMenuMgr * mgr; - AccountsUser * user; -} -ActivateUserSessionData; - +/** + * Creates and manages the menumodel and associated actions for the + * session menu described at . + * + * This is a pretty straightforward class: it creates the menumodel + * and listens for events that can affect the model's properties. + * + * Simple event sources, such as GSettings and a UPower DBus proxy, + * are handled here. More involved event sources are delegated to + * UsersServiceDBus facade class. + */ struct _SessionMenuMgr { GObject parent_instance; DbusmenuMenuitem * parent_mi; + DbusmenuMenuitem * screensaver_mi; DbusmenuMenuitem * lock_mi; DbusmenuMenuitem * lock_switch_mi; DbusmenuMenuitem * guest_mi; @@ -92,19 +101,22 @@ struct _SessionMenuMgr GSettings * indicator_settings; GSettings * keybinding_settings; + /* cached settings taken from the upower proxy */ gboolean can_hibernate; gboolean can_suspend; gboolean allow_hibernate; gboolean allow_suspend; + gboolean greeter_mode; GCancellable * cancellable; DBusUPower * upower_proxy; - SessionDbus * session_dbus; + SessionDbus * session_dbus; UsersServiceDbus * users_dbus_facade; }; static SwitcherMode get_switcher_mode (SessionMenuMgr *); + static void init_upower_proxy (SessionMenuMgr *); static void update_screensaver_shortcut (SessionMenuMgr *); @@ -118,21 +130,21 @@ static void action_func_hibernate (SessionMenuMgr *); static void action_func_switch_to_lockscreen (SessionMenuMgr *); static void action_func_switch_to_greeter (SessionMenuMgr *); static void action_func_switch_to_guest (SessionMenuMgr *); -static void action_func_switch_to_user (ActivateUserSessionData *); +static void action_func_switch_to_user (AccountsUser *); static void action_func_spawn_async (const char * fmt, ...); -static gboolean is_this_guest_session (void); -static gboolean is_this_live_session (void); +static gboolean is_this_guest_session (void); +static gboolean is_this_live_session (void); -static void on_guest_logged_in_changed (UsersServiceDbus *, - SessionMenuMgr *); +static void on_guest_logged_in_changed (UsersServiceDbus *, + SessionMenuMgr *); -static void on_user_logged_in_changed (UsersServiceDbus *, - AccountsUser *, - SessionMenuMgr *); +static void on_user_logged_in_changed (UsersServiceDbus *, + AccountsUser *, + SessionMenuMgr *); /** -*** GObject init / dispose / finalize +*** GObject init / dispose **/ G_DEFINE_TYPE (SessionMenuMgr, session_menu_mgr, G_TYPE_OBJECT); @@ -140,14 +152,9 @@ G_DEFINE_TYPE (SessionMenuMgr, session_menu_mgr, G_TYPE_OBJECT); static void session_menu_mgr_init (SessionMenuMgr *mgr) { - mgr->can_hibernate = TRUE; - mgr->can_suspend = TRUE; - mgr->allow_hibernate = TRUE; - mgr->allow_suspend = TRUE; - /* Lockdown settings */ GSettings * s = g_settings_new ("org.gnome.desktop.lockdown"); - g_signal_connect_swapped (s, "changed", + g_signal_connect_swapped (s, "changed::disable-log-out", G_CALLBACK(update_session_menuitems), mgr); g_signal_connect_swapped (s, "changed::disable-lock-screen", G_CALLBACK(update_user_menuitems), mgr); @@ -159,7 +166,12 @@ session_menu_mgr_init (SessionMenuMgr *mgr) s = g_settings_new ("com.canonical.indicator.session"); g_signal_connect_swapped (s, "changed::suppress-logout-restart-shutdown", G_CALLBACK(update_confirmation_labels), mgr); - g_signal_connect (s, "changed", G_CALLBACK(update_session_menuitems), mgr); + g_signal_connect_swapped (s, "changed::suppress-logout-menuitem", + G_CALLBACK(update_session_menuitems), mgr); + g_signal_connect_swapped (s, "changed::suppress-restart-menuitem", + G_CALLBACK(update_session_menuitems), mgr); + g_signal_connect_swapped (s, "changed::suppress-shutdown-menuitem", + G_CALLBACK(update_session_menuitems), mgr); mgr->indicator_settings = s; /* Keybinding settings */ @@ -168,7 +180,7 @@ session_menu_mgr_init (SessionMenuMgr *mgr) G_CALLBACK(update_screensaver_shortcut), mgr); mgr->keybinding_settings = s; - /* listen for users who appear or log in or log out */ + /* listen for user events */ mgr->users_dbus_facade = g_object_new (USERS_SERVICE_DBUS_TYPE, NULL); g_signal_connect_swapped (mgr->users_dbus_facade, "user-list-changed", G_CALLBACK (update_user_menuitems), mgr); @@ -177,7 +189,7 @@ session_menu_mgr_init (SessionMenuMgr *mgr) g_signal_connect (mgr->users_dbus_facade, "guest-logged-in-changed", G_CALLBACK(on_guest_logged_in_changed), mgr); - init_upower_proxy (mgr); + init_upower_proxy (mgr); } static void @@ -197,13 +209,7 @@ session_menu_mgr_dispose (GObject *object) g_clear_object (&mgr->upower_proxy); g_clear_object (&mgr->users_dbus_facade); - 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); + G_OBJECT_CLASS (session_menu_mgr_parent_class)->dispose (object); } static void @@ -211,61 +217,16 @@ 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; -} - -/*** -**** Menuitem Helpers -***/ - -static inline void -mi_set_label (DbusmenuMenuitem * mi, const char * str) -{ - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, str); -} - -static inline void -mi_set_type (DbusmenuMenuitem * mi, const char * str) -{ - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_TYPE, str); -} - -static inline void -mi_set_visible (DbusmenuMenuitem * mi, gboolean b) -{ - dbusmenu_menuitem_property_set_bool (mi, DBUSMENU_MENUITEM_PROP_VISIBLE, b); -} - -static inline void -mi_set_logged_in (DbusmenuMenuitem * mi, gboolean b) -{ - dbusmenu_menuitem_property_set_bool (mi, USER_ITEM_PROP_LOGGED_IN, b); -} - -static DbusmenuMenuitem* -mi_new_separator (void) -{ - DbusmenuMenuitem * mi = dbusmenu_menuitem_new (); - mi_set_type (mi, DBUSMENU_CLIENT_TYPES_SEPARATOR); - return mi; -} - -static DbusmenuMenuitem* -mi_new (const char * label) -{ - DbusmenuMenuitem * mi = dbusmenu_menuitem_new (); - mi_set_label (mi, label); - return mi; } /*** **** UPower Proxy: **** **** 1. While bootstrapping, we invoke the AllowSuspend and AllowHibernate -**** methods to find out whether or not those functions are allowed. +**** methods to find out whether or not those features are allowed. **** 2. While bootstrapping, we get the CanSuspend and CanHibernate properties **** and also listen for property changes. -**** 3. These four values are used to set suspend and hibernate's visibility +**** 3. These four values are used to set suspend and hibernate's visibility. **** ***/ @@ -273,14 +234,14 @@ static void on_upower_properties_changed (SessionMenuMgr * mgr) { gboolean b; - gboolean refresh = FALSE; + gboolean need_refresh = FALSE; /* suspend */ b = dbus_upower_get_can_suspend (mgr->upower_proxy); if (mgr->can_suspend != b) { mgr->can_suspend = b; - refresh = TRUE; + need_refresh = TRUE; } /* hibernate */ @@ -288,10 +249,10 @@ on_upower_properties_changed (SessionMenuMgr * mgr) if (mgr->can_hibernate != b) { mgr->can_hibernate = b; - refresh = TRUE; + need_refresh = TRUE; } - if (refresh) + if (need_refresh) { update_session_menuitems (mgr); } @@ -300,6 +261,12 @@ on_upower_properties_changed (SessionMenuMgr * mgr) static void init_upower_proxy (SessionMenuMgr * mgr) { + /* default values */ + mgr->can_suspend = TRUE; + mgr->can_hibernate = TRUE; + mgr->allow_suspend = TRUE; + mgr->allow_hibernate = TRUE; + mgr->cancellable = g_cancellable_new (); GError * error = NULL; @@ -344,44 +311,92 @@ init_upower_proxy (SessionMenuMgr * mgr) } /*** -**** Admin Menuitems +**** Menuitem Helpers ***/ -#define DEBUG_SHOW_ALL 1 +static inline void +mi_set_label (DbusmenuMenuitem * mi, const char * str) +{ + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, str); +} -static void -build_admin_menuitems (SessionMenuMgr * mgr) +static inline void +mi_set_type (DbusmenuMenuitem * mi, const char * str) { - DbusmenuMenuitem * mi; - const gboolean show_settings = DEBUG_SHOW_ALL || !mgr->greeter_mode; + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_TYPE, str); +} - mi = mi_new (_("About This Computer")); - dbusmenu_menuitem_child_append (mgr->parent_mi, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(action_func_spawn_async), CMD_INFO); +static inline void +mi_set_visible (DbusmenuMenuitem * mi, gboolean b) +{ + dbusmenu_menuitem_property_set_bool (mi, DBUSMENU_MENUITEM_PROP_VISIBLE, + b || DEBUG_SHOW_ALL); +} - mi = mi_new (_("Ubuntu Help")); - dbusmenu_menuitem_child_append (mgr->parent_mi, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(action_func_spawn_async), CMD_HELP); +static inline void +mi_set_logged_in (DbusmenuMenuitem * mi, gboolean b) +{ + dbusmenu_menuitem_property_set_bool (mi, USER_ITEM_PROP_LOGGED_IN, b); +} - mi = mi_new_separator (); - mi_set_visible (mi, show_settings); - dbusmenu_menuitem_child_append (mgr->parent_mi, mi); +static DbusmenuMenuitem* +mi_new_separator (void) +{ + DbusmenuMenuitem * mi = dbusmenu_menuitem_new (); + mi_set_type (mi, DBUSMENU_CLIENT_TYPES_SEPARATOR); + return mi; +} - mi = mi_new (_("System Settings\342\200\246")); - mi_set_visible (mi, show_settings); - dbusmenu_menuitem_child_append (mgr->parent_mi, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(action_func_spawn_async), - CMD_SYSTEM_SETTINGS); +static DbusmenuMenuitem* +mi_new (const char * label) +{ + DbusmenuMenuitem * mi = dbusmenu_menuitem_new (); + mi_set_label (mi, label); + return mi; +} - mi = mi_new_separator (); - dbusmenu_menuitem_child_append (mgr->parent_mi, mi); +/*** +**** Admin Menuitems +**** +***/ + +static void +build_admin_menuitems (SessionMenuMgr * mgr) +{ + if (!mgr->greeter_mode) + { + DbusmenuMenuitem * mi; + const gboolean show_settings = !mgr->greeter_mode; + + mi = mi_new (_("About This Computer")); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(action_func_spawn_async), CMD_INFO); + + mi = mi_new (_("Ubuntu Help")); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(action_func_spawn_async), CMD_HELP); + + mi = mi_new_separator (); + mi_set_visible (mi, show_settings); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); + + mi = mi_new (_("System Settings")); + mi_set_visible (mi, show_settings); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(action_func_spawn_async), + CMD_SYSTEM_SETTINGS); + + mi = mi_new_separator (); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); + } } /*** **** Session Menuitems +**** ***/ static void @@ -392,7 +407,7 @@ update_session_menuitems (SessionMenuMgr * mgr) v = !mgr->greeter_mode && !is_this_live_session() - && !g_settings_get_boolean (mgr->lockdown_settings, "disable-logout") + && !g_settings_get_boolean (mgr->lockdown_settings, "disable-log-out") && !g_settings_get_boolean (s, "suppress-logout-menuitem"); mi_set_visible (mgr->logout_mi, v); @@ -404,15 +419,20 @@ update_session_menuitems (SessionMenuMgr * mgr) && mgr->allow_hibernate; mi_set_visible (mgr->hibernate_mi, v); - v = !g_settings_get_boolean (s, "suppress-restart-menuitem"); + v = HAVE_RESTART_CMD + && !g_settings_get_boolean (s, "suppress-restart-menuitem"); mi_set_visible (mgr->restart_mi, v); v = !g_settings_get_boolean (s, "suppress-shutdown-menuitem"); mi_set_visible (mgr->shutdown_mi, v); } -/* if confirmation is enabled, - add ellipsis to the labels of items whose actions need confirmation */ +/* Update the ellipses when the confirmation setting changes. + * + * : + * "Label the menu item with a trailing ellipsis ("...") only if the + * command requires further input from the user before it can be performed." + */ static void update_confirmation_labels (SessionMenuMgr * mgr) { @@ -436,9 +456,6 @@ build_session_menuitems (SessionMenuMgr* mgr) { DbusmenuMenuitem * mi; - mi = mi_new_separator (); - dbusmenu_menuitem_child_append (mgr->parent_mi, mi); - mi = mgr->logout_mi = mi_new (_("Log Out\342\200\246")); dbusmenu_menuitem_child_append (mgr->parent_mi, mi); g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, @@ -454,24 +471,28 @@ build_session_menuitems (SessionMenuMgr* mgr) g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(action_func_hibernate), mgr); - mi = mgr->restart_mi = mi_new (_("Restart\342\200\246")); + mi = mgr->restart_mi = dbusmenu_menuitem_new (); + mi_set_type (mi, RESTART_ITEM_TYPE); + dbusmenu_menuitem_property_set (mi, RESTART_ITEM_LABEL, _("Restart\342\200\246")); dbusmenu_menuitem_child_append (mgr->parent_mi, mi); g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(action_func_spawn_async), CMD_RESTART); - + mi = mgr->shutdown_mi = mi_new (_("Switch Off\342\200\246")); dbusmenu_menuitem_child_append (mgr->parent_mi, mi); g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(action_func_spawn_async), CMD_SHUTDOWN); update_confirmation_labels (mgr); + update_session_menuitems (mgr); } /**** ***** User Menuitems +***** https://wiki.ubuntu.com/SystemMenu#Account-switching_items ****/ -/* Local Extensions to AccountsUser */ +/* Local extensions to AccountsUser */ static GQuark get_menuitem_quark (void) @@ -492,15 +513,49 @@ user_get_menuitem (AccountsUser * user) return g_object_get_qdata (G_OBJECT(user), get_menuitem_quark()); } +static void +user_clear_menuitem (AccountsUser * user) +{ + g_object_steal_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); + g_object_set_qdata (G_OBJECT(user), get_menuitem_quark(), mi); + + g_object_weak_ref (G_OBJECT(mi), (GWeakNotify)user_clear_menuitem, user); } +/***/ + +static GQuark +get_mgr_quark (void) +{ + static GQuark q = 0; + + if (G_UNLIKELY(!q)) + { + q = g_quark_from_static_string ("session-menu-mgr"); + } + + return q; +} + +static SessionMenuMgr* +user_get_mgr (AccountsUser * user) +{ + return g_object_get_qdata (G_OBJECT(user), get_mgr_quark()); +} + +static void +user_set_mgr (AccountsUser * user, SessionMenuMgr * mgr) +{ + g_object_set_qdata (G_OBJECT(user), get_mgr_quark(), mgr); +} + +/***/ + static GQuark get_collision_quark (void) { @@ -534,8 +589,11 @@ static void on_guest_logged_in_changed (UsersServiceDbus * usd, SessionMenuMgr * mgr) { - mi_set_logged_in (mgr->guest_mi, - users_service_dbus_is_guest_logged_in (usd)); + if (mgr->guest_mi != NULL) + { + mi_set_logged_in (mgr->guest_mi, + users_service_dbus_is_guest_logged_in (usd)); + } } /* When a user's login state changes, @@ -557,19 +615,31 @@ static void update_screensaver_shortcut (SessionMenuMgr * mgr) { gchar * s = g_settings_get_string (mgr->keybinding_settings, "screensaver"); - g_debug ("Keybinding changed to: %s", s); - dbusmenu_menuitem_property_set_shortcut_string (mgr->lock_mi, s); - dbusmenu_menuitem_property_set_shortcut_string (mgr->lock_switch_mi, s); + g_debug ("%s Screensaver shortcut changed to: '%s'", G_STRLOC, s); + + if (mgr->lock_mi != NULL) + { + dbusmenu_menuitem_property_set_shortcut_string (mgr->lock_mi, s); + } + + if (mgr->lock_switch_mi != NULL) + { + dbusmenu_menuitem_property_set_shortcut_string (mgr->lock_switch_mi, s); + } + + if (mgr->screensaver_mi != NULL) + { + dbusmenu_menuitem_property_set_shortcut_string (mgr->screensaver_mi, s); + } + g_free (s); } static void -on_user_icon_file_changed (AccountsUser * user, - GParamSpec * pspec G_GNUC_UNUSED, - DbusmenuMenuitem * mi) +update_user_menuitem_icon (DbusmenuMenuitem * mi, AccountsUser * user) { const gchar * str = accounts_user_get_icon_file (user); - + if (!str || !*str) { str = USER_ITEM_ICON_DEFAULT; @@ -578,19 +648,62 @@ on_user_icon_file_changed (AccountsUser * user, dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_ICON, str); } +static void +update_user_menuitem_name (DbusmenuMenuitem * mi, AccountsUser * user) +{ + GString * gstr = g_string_new (accounts_user_get_real_name (user)); + + if (user_has_name_collision (user)) + { + g_string_append_printf (gstr, " (%s)", accounts_user_get_user_name(user)); + } + + dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, gstr->str); + g_string_free (gstr, TRUE); +} + +static void +on_user_property_changed (AccountsUser * user, + GParamSpec * pspec, + DbusmenuMenuitem * mi) +{ + static const char * interned_icon_file = NULL; + static const char * interned_real_name = NULL; + static const char * interned_user_name = NULL; + + if (G_UNLIKELY (interned_icon_file == NULL)) + { + interned_icon_file = g_intern_static_string ("icon-file"); + interned_user_name = g_intern_static_string ("user-name"); + interned_real_name = g_intern_static_string ("real-name"); + } + + if (pspec->name == interned_icon_file) + { + update_user_menuitem_icon (mi, user); + } + else if ((pspec->name == interned_real_name) + || (pspec->name == interned_user_name)) + { + /* name changing can affect other menuitems too by invalidating + the sort order or name collision flags... so let's rebuild */ + update_user_menuitems (user_get_mgr (user)); + } +} + typedef struct { - AccountsUser * user; + gpointer instance; gulong handler_id; } -UserChangeListenerData; +SignalHandlerData; -/* when the menuitem is destroyed, - it should stop listening for changes to the UserAccount properties :) */ +/* when a user menuitem is destroyed, + it should stop listening for its UserAccount's property changes */ static void -on_user_menuitem_destroyed (UserChangeListenerData * data) +on_user_menuitem_destroyed (SignalHandlerData * data) { - g_signal_handler_disconnect (data->user, data->handler_id); + g_signal_handler_disconnect (data->instance, data->handler_id); g_free (data); } @@ -600,27 +713,20 @@ user_menuitem_new (AccountsUser * user, SessionMenuMgr * mgr) DbusmenuMenuitem * mi = dbusmenu_menuitem_new (); mi_set_type (mi, USER_ITEM_TYPE); - /* set the name property */ - GString * gstr = g_string_new (accounts_user_get_real_name (user)); - if (user_has_name_collision (user)) - { - g_string_append_printf (gstr, " (%s)", accounts_user_get_user_name(user)); - } - dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, gstr->str); - g_string_free (gstr, TRUE); + /* set the name & icon and listen for property changes */ + update_user_menuitem_name (mi, user); + update_user_menuitem_icon (mi, user); + SignalHandlerData * hd = g_new0 (SignalHandlerData, 1); + hd->instance = user; + hd->handler_id = g_signal_connect (user, "notify", + G_CALLBACK(on_user_property_changed), mi); + g_object_weak_ref (G_OBJECT(mi), (GWeakNotify)on_user_menuitem_destroyed, hd); + /* set the logged-in property */ mi_set_logged_in (mi, users_service_dbus_is_user_logged_in (mgr->users_dbus_facade, user)); - /* set the icon property & listen for changes */ - UserChangeListenerData * cd = g_new0 (UserChangeListenerData, 1); - cd->user = user; - cd->handler_id = g_signal_connect (user, "notify::icon-file", - G_CALLBACK(on_user_icon_file_changed), mi); - g_object_weak_ref (G_OBJECT(mi), (GWeakNotify)on_user_menuitem_destroyed, cd); - on_user_icon_file_changed (user, NULL, mi); - /* set the is-current-user property */ const gboolean is_current_user = !g_strcmp0 (g_get_user_name(), accounts_user_get_user_name(user)); @@ -628,17 +734,13 @@ user_menuitem_new (AccountsUser * user, SessionMenuMgr * mgr) USER_ITEM_PROP_IS_CURRENT_USER, is_current_user); - /* set the activate callback */ - ActivateUserSessionData * data = g_new (ActivateUserSessionData, 1); - data->user = user; - data->mgr = mgr; - g_signal_connect_data (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (action_func_switch_to_user), - data, (GClosureNotify)g_free, - G_CONNECT_SWAPPED); + /* set the switch-to-user action */ + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK (action_func_switch_to_user), user); /* give this AccountsUser a hook back to this menuitem */ user_set_menuitem (user, mi); + user_set_mgr (user, mgr); return mi; } @@ -654,7 +756,7 @@ compare_users_by_login_frequency (gconstpointer a, gconstpointer b) return 0; } -/* for sorting AccountsUsers by name */ +/* for sorting AccountsUsers alphabetically */ static gint compare_users_by_username (gconstpointer ga, gconstpointer gb) { @@ -690,6 +792,8 @@ is_user_switching_allowed (SessionMenuMgr * mgr) static void build_user_menuitems (SessionMenuMgr * mgr) { + g_return_if_fail (!mgr->greeter_mode); + DbusmenuMenuitem * mi; GSList * items = NULL; gint pos = mgr->user_menuitem_index; @@ -702,63 +806,78 @@ build_user_menuitems (SessionMenuMgr * mgr) *** Lock / Switch Account... **/ - const gboolean show_all = DEBUG_SHOW_ALL; const SwitcherMode mode = get_switcher_mode (mgr); - mi = mi_new (_("Start Screen Saver")); - mi_set_visible (mi, show_all || (mode == SWITCHER_MODE_SCREENSAVER)); + mi = mgr->screensaver_mi = mi_new (_("Start Screen Saver")); + mi_set_visible (mi, mode == SWITCHER_MODE_SCREENSAVER); dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); items = g_slist_prepend (items, mi); g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (action_func_lock), mgr); mi = mi_new (_("Switch User Account\342\200\246")); - mi_set_visible (mi, show_all || (mode == SWITCHER_MODE_SWITCH)); + mi_set_visible (mi, mode == SWITCHER_MODE_SWITCH); dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); items = g_slist_prepend (items, mi); g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (action_func_switch_to_greeter), mgr); mi = mgr->lock_mi = mi_new (_("Lock")); - mi_set_visible (mi, show_all || (mode == SWITCHER_MODE_LOCK)); + mi_set_visible (mi, mode == SWITCHER_MODE_LOCK); dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); items = g_slist_prepend (items, mi); g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (action_func_switch_to_lockscreen), mgr); mi = mgr->lock_switch_mi = mi_new (_("Lock/Switch Account\342\200\246")); - mi_set_visible (mi, show_all || (mode == SWITCHER_MODE_SWITCH_OR_LOCK)); + mi_set_visible (mi, mode == SWITCHER_MODE_SWITCH_OR_LOCK); dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); items = g_slist_prepend (items, mi); g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (action_func_switch_to_lockscreen), mgr); - const gboolean guest_allowed = - users_service_dbus_guest_session_enabled (mgr->users_dbus_facade); - const gboolean is_guest = is_this_guest_session(); - mi = mi_new (_("Guest Session")); + const gboolean is_guest = is_this_guest_session (); + const gboolean guest_allowed = users_service_dbus_guest_session_enabled (mgr->users_dbus_facade); + mi = mgr->guest_mi = dbusmenu_menuitem_new (); mi_set_type (mi, USER_ITEM_TYPE); - mi_set_visible (mi, guest_allowed && !is_guest); + mi_set_visible (mi, !is_guest && guest_allowed); + dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, _("Guest Session")); dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); on_guest_logged_in_changed (mgr->users_dbus_facade, mgr); items = g_slist_prepend (items, mi); g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (action_func_switch_to_guest), mgr); - mgr->guest_mi = mi; + if (guest_allowed && is_guest) { current_real_name = _("Guest"); } - + /*** **** Users ***/ /* if we can switch to another user account, show them here */ - if (is_user_switching_allowed (mgr)) + const char * const username = g_get_user_name(); + GList * users = users_service_dbus_get_user_list (mgr->users_dbus_facade); + + /* since we're building (or rebuilding) from scratch, + clear the name collision flags */ + GList * u; + for (u=users; u!=NULL; u=u->next) { - GList * users = users_service_dbus_get_user_list (mgr->users_dbus_facade); + AccountsUser * user = ACCOUNTS_USER(u->data); + + user_set_name_collision (user, FALSE); + + if (!g_strcmp0 (username, accounts_user_get_user_name(user))) + { + current_real_name = accounts_user_get_real_name (user); + } + } + if (is_user_switching_allowed (mgr)) + { /* pick the most frequently used accounts */ const int MAX_USERS = 12; /* this limit comes from the spec */ if (g_list_length(users) > MAX_USERS) @@ -776,21 +895,14 @@ build_user_menuitems (SessionMenuMgr * mgr) /* Create menuitems for them */ int i; - GList * u; - const char * const username = g_get_user_name(); for (i=0, u=users; inext, i++) { AccountsUser * user = u->data; DbusmenuMenuitem * mi = user_menuitem_new (user, mgr); dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); items = g_slist_prepend (items, mi); - - if (!g_strcmp0 (username, accounts_user_get_user_name(user))) - { - current_real_name = accounts_user_get_real_name (user); - } } - g_list_free(users); + g_list_free (users); } /* separator */ @@ -821,11 +933,14 @@ update_user_menuitems (SessionMenuMgr * mgr) mgr->user_menuitems = NULL; /* add fresh user menuitems */ - build_user_menuitems (mgr); + if (!mgr->greeter_mode) + { + build_user_menuitems (mgr); + } } /*** -**** +**** Actions! ***/ static void @@ -835,14 +950,15 @@ action_func_spawn_async (const char * fmt, ...) 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)) + + GError * error = NULL; + g_spawn_command_line_async (cmd, &error); + if (error != NULL) { - g_warning ("Unable to show \"%s\": %s", cmd, error->message); + g_warning ("Unable to execute \"%s\": %s", cmd, error->message); + g_clear_error (&error); } - g_clear_error (&error); g_free (cmd); } @@ -908,11 +1024,12 @@ action_func_switch_to_greeter (SessionMenuMgr * mgr) } static void -action_func_switch_to_user (ActivateUserSessionData * data) +action_func_switch_to_user (AccountsUser * user) { - action_func_lock (data->mgr); - users_service_dbus_activate_user_session (data->mgr->users_dbus_facade, - data->user); + SessionMenuMgr * mgr = user_get_mgr (user); + g_return_if_fail (mgr != NULL); + action_func_lock (mgr); + users_service_dbus_activate_user_session (mgr->users_dbus_facade, user); } static void @@ -961,6 +1078,8 @@ action_func_hibernate (SessionMenuMgr * mgr) static gboolean is_this_guest_session (void) { + /* FIXME: this test has been here awhile and seems to work, + but seems brittle to me */ return geteuid() < 500; } @@ -996,15 +1115,16 @@ get_switcher_mode (SessionMenuMgr * mgr) { mode = SWITCHER_MODE_SWITCH; } - else + else /* both locking & switching are allowed */ { GList * l = users_service_dbus_get_user_list (mgr->users_dbus_facade); const size_t user_count = g_list_length (l); g_list_free (l); - mode = user_count < 2 - ? SWITCHER_MODE_LOCK /* you can't switch if no other users */ - : SWITCHER_MODE_SWITCH_OR_LOCK; + /* only show switch mode if we have users to switch to */ + mode = user_count > (is_this_guest_session() ? 0 : 1) + ? SWITCHER_MODE_SWITCH_OR_LOCK + : SWITCHER_MODE_LOCK; } return mode; @@ -1026,7 +1146,7 @@ SessionMenuMgr* session_menu_mgr_new (DbusmenuMenuitem * parent_mi, build_admin_menuitems (mgr); const guint n = g_list_length (dbusmenu_menuitem_get_children (parent_mi)); mgr->user_menuitem_index = n; - build_user_menuitems (mgr); + update_user_menuitems (mgr); build_session_menuitems (mgr); return mgr; } diff --git a/src/session-service.c b/src/session-service.c index 598fcce..2349684 100644 --- a/src/session-service.c +++ b/src/session-service.c @@ -11,16 +11,16 @@ Authors: Conor Curran Charles Kerr -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 +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 +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 +You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -42,34 +42,31 @@ with this program. If not, see . #include -#include "dbus-shared-names.h" -#include "users-service-dbus.h" #include "session-dbus.h" #include "session-menu-mgr.h" +#include "shared-names.h" +#include "users-service-dbus.h" -//static UsersServiceDbus *dbus_interface = NULL; -static SessionDbus *session_dbus = NULL; +static SessionDbus * session_dbus = NULL; static GMainLoop * mainloop = NULL; -/* When the service interface starts to shutdown, we - should follow it. */ +/* When the service interface starts to shutdown, + we should follow it. */ void service_shutdown (IndicatorService * service, gpointer user_data) { - if (mainloop != NULL) { - g_debug("Service shutdown"); - g_main_loop_quit(mainloop); - } - return; + if (mainloop != NULL) + { + g_debug ("Service shutdown"); + g_main_loop_quit (mainloop); + } } -static gboolean -get_greeter_mode (void) +static inline gboolean +is_greeter_mode (void) { - const gchar *var; - var = g_getenv("INDICATOR_GREETER_MODE"); - return (g_strcmp0(var, "1") == 0); + return !g_strcmp0 (g_getenv ("INDICATOR_GREETER_MODE"), "1"); } /* Main, is well, main. It brings everything up and throws @@ -77,34 +74,29 @@ get_greeter_mode (void) int main (int argc, char ** argv) { - gboolean greeter_mode; - g_type_init(); - /* Setting up i18n and gettext. Apparently, we need - all of these. */ - setlocale (LC_ALL, ""); - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - textdomain (GETTEXT_PACKAGE); + /* Setting up i18n and gettext. + Apparently we need all of these. */ + setlocale (LC_ALL, ""); + bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); + textdomain (GETTEXT_PACKAGE); - IndicatorService * service = indicator_service_new_version (INDICATOR_SESSION_DBUS_NAME, - INDICATOR_SESSION_DBUS_VERSION); - g_signal_connect (G_OBJECT(service), - INDICATOR_SERVICE_SIGNAL_SHUTDOWN, + IndicatorService * service = indicator_service_new_version (INDICATOR_SESSION_DBUS_NAME, + INDICATOR_SESSION_DBUS_VERSION); + g_signal_connect (G_OBJECT(service), INDICATOR_SERVICE_SIGNAL_SHUTDOWN, G_CALLBACK(service_shutdown), NULL); - session_dbus = session_dbus_new(); - - greeter_mode = get_greeter_mode(); + session_dbus = session_dbus_new(); DbusmenuMenuitem * root_item = dbusmenu_menuitem_new (); - session_menu_mgr_new (root_item, session_dbus, greeter_mode); + session_menu_mgr_new (root_item, session_dbus, is_greeter_mode()); DbusmenuServer* server = dbusmenu_server_new (INDICATOR_SESSION_DBUS_OBJECT); dbusmenu_server_set_root (server, root_item); mainloop = g_main_loop_new(NULL, FALSE); g_main_loop_run(mainloop); - + return 0; } diff --git a/src/settings-helper.c b/src/settings-helper.c deleted file mode 100644 index 0ab188a..0000000 --- a/src/settings-helper.c +++ /dev/null @@ -1,46 +0,0 @@ -/* -A small wrapper utility for connecting to GSettings. - -Copyright 2009 Canonical Ltd. - -Authors: - Christoph Korn - -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 . -*/ - -#include - -#include "dbus-shared-names.h" -#include "settings-helper.h" - -static GSettings* settings = NULL; - -static gboolean -build_settings (void) -{ - if (G_UNLIKELY(settings == NULL)) - { - settings = g_settings_new (SESSION_SCHEMA); - } - - return settings != NULL; -} - -gboolean -supress_confirmations (void) -{ - g_return_val_if_fail (build_settings(), FALSE); - - return g_settings_get_boolean (settings, SUPPRESS_KEY) ; -} diff --git a/src/settings-helper.h b/src/settings-helper.h deleted file mode 100644 index 8c4b2e8..0000000 --- a/src/settings-helper.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -A small wrapper utility for connecting to GSettings. - -Copyright 2009 Canonical Ltd. - -Authors: - Christoph Korn - -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 . -*/ - - -#ifndef __GCONF_HELPER_H__ -#define __GCONF_HELPER_H__ - -#define SESSION_SCHEMA "com.canonical.indicator.session" -#define SUPPRESS_KEY "suppress-logout-restart-shutdown" -#define LOGOUT_KEY "suppress-logout-menuitem" -#define RESTART_KEY "suppress-restart-menuitem" -#define SHUTDOWN_KEY "suppress-shutdown-menuitem" -#define SHOW_USER_MENU "user-show-menu" - -gboolean supress_confirmations (void); - -#endif /* __GCONF_HELPER__ */ diff --git a/src/shared-names.h b/src/shared-names.h new file mode 100644 index 0000000..dcda182 --- /dev/null +++ b/src/shared-names.h @@ -0,0 +1,57 @@ +/* +A small wrapper utility to load indicators and put them as menu items +into the gnome-panel using it's applet interface. + +Copyright 2009 Canonical Ltd. + +Authors: + Ted Gould + +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 . +*/ + +#ifndef __DBUS_SHARED_NAMES_H__ +#define __DBUS_SHARED_NAMES_H__ + +#define INDICATOR_SESSION_DBUS_NAME "com.canonical.indicator.session" +#define INDICATOR_SESSION_DBUS_OBJECT "/com/canonical/indicator/session/menu" +#define INDICATOR_SESSION_DBUS_VERSION 0 + +#define INDICATOR_SESSION_SERVICE_DBUS_OBJECT "/com/canonical/indicator/session/service" +#define INDICATOR_SESSION_SERVICE_DBUS_IFACE "com.canonical.indicator.session.service" +#define USER_ITEM_TYPE "x-canonical-user-item" +#define USER_ITEM_PROP_NAME "user-item-name" +#define USER_ITEM_PROP_LOGGED_IN "user-item-logged-in" +#define USER_ITEM_PROP_IS_CURRENT_USER "user-item-is-current-user" +#define USER_ITEM_PROP_ICON "user-item-icon-path" +#define USER_ITEM_ICON_DEFAULT "avatar-default" + +#define RESTART_ITEM_TYPE "x-canonical-restart-item" +#define RESTART_ITEM_LABEL "restart-label" +#define RESTART_ITEM_ICON "restart-icon" + +#define ICON_DEFAULT "system-devices-panel" +#define ICON_RESTART "system-devices-panel-alert" +#define GREETER_ICON_DEFAULT "system-shutdown-panel" +#define GREETER_ICON_RESTART "system-shutdown-panel-restart" + +/* the session indicator's settings */ +#define SESSION_SCHEMA "com.canonical.indicator.session" +#define SUPPRESS_KEY "suppress-logout-restart-shutdown" +#define LOGOUT_KEY "suppress-logout-menuitem" +#define RESTART_KEY "suppress-restart-menuitem" +#define SHUTDOWN_KEY "suppress-shutdown-menuitem" +#define SHOW_USER_MENU "user-show-menu" + + +#endif /* __DBUS_SHARED_NAMES_H__ */ diff --git a/src/users-service-dbus.c b/src/users-service-dbus.c index 57cc3a6..8a050fc 100644 --- a/src/users-service-dbus.c +++ b/src/users-service-dbus.c @@ -30,13 +30,13 @@ #include /* getpwuid() */ -#include "dbus-shared-names.h" #include "dbus-accounts.h" #include "dbus-consolekit-manager.h" #include "dbus-consolekit-seat.h" #include "dbus-consolekit-session.h" #include "dbus-display-manager.h" #include "dbus-user.h" +#include "shared-names.h" #include "users-service-dbus.h" #define CK_ADDR "org.freedesktop.ConsoleKit" @@ -326,7 +326,6 @@ create_consolekit_session_proxy (const char * ssid) ssid, NULL, &error); - if (error != NULL) { g_warning ("%s: %s", G_STRLOC, error->message); @@ -644,7 +643,6 @@ update_user_list (UsersServiceDbus *self) GError * error = NULL; char ** object_paths = NULL; UsersServiceDbusPrivate * priv = self->priv; - g_debug ("%s updating the user list", G_STRLOC); accounts_call_list_cached_users_sync (priv->accounts_proxy, &object_paths, @@ -680,7 +678,7 @@ on_user_added (Accounts * o G_GNUC_UNUSED, { /* We see a new user but we might not want to list it -- for example, lightdm shows up when we switch to the greeter. - So instead of adding the user directly here, let's ask + So instead of adding the user directly here, let's ask org.freedesktop.Accounts for a fresh list of users because it filters out special cases. */ update_user_list (service); @@ -790,7 +788,7 @@ get_unix_username_from_ssid (UsersServiceDbus * self, g_warning ("Failed to lookup user id %d: %s", (int)uid, g_strerror(errno)); } else - { + { username = g_strdup (pwent->pw_name); } } @@ -807,7 +805,7 @@ is_guest_username (const char * username) if (!g_strcmp0 (username, "guest")) return TRUE; - if ((strlen(username)==12) && !memcmp(username,"guest-",6)) + if (username && (strlen(username)==12) && !memcmp(username,"guest-",6)) return TRUE; return FALSE; -- cgit v1.2.3