aboutsummaryrefslogtreecommitdiff
path: root/src/users-service.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/users-service.c')
-rw-r--r--src/users-service.c245
1 files changed, 187 insertions, 58 deletions
diff --git a/src/users-service.c b/src/users-service.c
index 7ad1732..9ebf5f5 100644
--- a/src/users-service.c
+++ b/src/users-service.c
@@ -1,24 +1,25 @@
/*
-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 <ted@canonical.com>
-
-This program is free software: you can redistribute it and/or modify it
-under the terms of the GNU General Public License version 3, as published
-by the Free Software Foundation.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranties of
-MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
-PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
+ * 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 <ted@canonical.com>
+ * Cody Russell <crussell@canonical.com>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ *with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
#include <config.h>
@@ -33,15 +34,27 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include <libdbusmenu-glib/menuitem.h>
#include "dbus-shared-names.h"
+#include "users-service-dbus.h"
#define GUEST_SESSION_LAUNCHER "/usr/share/gdm/guest-session/guest-session-launch"
-static DBusGConnection * session_bus = NULL;
-static DBusGConnection * system_bus = NULL;
-static DBusGProxy * bus_proxy = NULL;
-static DBusGProxy * gdm_proxy = NULL;
-static DbusmenuMenuitem * root_menuitem = NULL;
-static GMainLoop * mainloop = NULL;
+typedef struct _ActivateData ActivateData;
+struct _ActivateData
+{
+ UsersServiceDbus *service;
+ UserData *user;
+};
+
+static DBusGConnection *session_bus = NULL;
+static DBusGConnection *system_bus = NULL;
+static DBusGProxy *bus_proxy = NULL;
+static DBusGProxy *gdm_proxy = NULL;
+static DbusmenuMenuitem *root_menuitem = NULL;
+static GMainLoop *mainloop = NULL;
+static UsersServiceDbus *dbus_interface = NULL;
+
+static gint count;
+static GList *users;
static gboolean
check_guest_session (void)
@@ -137,29 +150,134 @@ lock_screen (DbusmenuMenuitem * mi, gpointer data)
}
static void
-create_items (DbusmenuMenuitem * root) {
- DbusmenuMenuitem * mi = NULL;
-
- mi = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Lock Screen"));
- g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(lock_screen), NULL);
- dbusmenu_menuitem_child_append(root, mi);
-
- if (check_guest_session()) {
- mi = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Guest Session"));
- dbusmenu_menuitem_child_append(root, mi);
- g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_guest_session), NULL);
- }
+activate_user_session (DbusmenuMenuitem *mi, gpointer user_data)
+{
+ UserData *user = (UserData *)user_data;
+ UsersServiceDbus *service = user->service;
- if (check_new_session()) {
- mi = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Switch User..."));
- dbusmenu_menuitem_child_append(root, mi);
- g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_new_session), NULL);
- }
+ users_service_dbus_activate_user_session (service, user);
+}
- return;
+static void
+remove_menu_item (DbusmenuMenuitem *root, gpointer user_data)
+{
+ DbusmenuMenuitem *child = (DbusmenuMenuitem *)user_data;
+
+ dbusmenu_menuitem_child_delete (root, child);
+}
+
+static gint
+compare_users_by_username (const gchar *a,
+ const gchar *b)
+{
+ UserData *user1 = (UserData *)a;
+ UserData *user2 = (UserData *)b;
+
+ return g_strcmp0 (user1->user_name, user2->user_name);
+}
+
+static void
+rebuild_items (DbusmenuMenuitem *root,
+ UsersServiceDbus *service)
+{
+ DbusmenuMenuitem *mi = NULL;
+ GList *u;
+ UserData *user;
+ gboolean can_activate;
+
+ can_activate = users_service_dbus_can_activate_session (service);
+
+ dbusmenu_menuitem_foreach (root, remove_menu_item, NULL);
+
+ mi = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Lock Screen"));
+ g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(lock_screen), NULL);
+ dbusmenu_menuitem_child_append(root, mi);
+
+ if (can_activate == TRUE)
+ {
+ if (check_guest_session ())
+ {
+ mi = dbusmenu_menuitem_new ();
+ dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Guest Session"));
+ dbusmenu_menuitem_child_append (root, mi);
+ g_signal_connect (G_OBJECT (mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (activate_guest_session), NULL);
+ }
+
+ if (count > MINIMUM_USERS && count < MAXIMUM_USERS)
+ {
+ if (users != NULL)
+ {
+ GList *l = NULL;
+
+ for (l = users; l != NULL; l = l->next)
+ {
+ users = g_list_delete_link (users, l);
+ }
+
+ users = NULL;
+ }
+
+ users = users_service_dbus_get_user_list (service);
+
+ users = g_list_sort (users, (GCompareFunc)compare_users_by_username);
+
+ for (u = users; u != NULL; u = g_list_next (u))
+ {
+ user = u->data;
+
+ user->service = service;
+
+ mi = dbusmenu_menuitem_new ();
+ dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, user->real_name);
+ dbusmenu_menuitem_child_append (root, mi);
+ g_signal_connect (G_OBJECT (mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (activate_user_session), user);
+ }
+ }
+
+ if (check_new_session ())
+ {
+ mi = dbusmenu_menuitem_new ();
+ dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, _("New Session..."));
+ dbusmenu_menuitem_child_append (root, mi);
+ g_signal_connect (G_OBJECT (mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (activate_new_session), NULL);
+ }
+ }
+}
+
+static void
+user_added (UsersServiceDbus *service,
+ UserData *user,
+ gpointer user_data)
+{
+ DbusmenuMenuitem *root = (DbusmenuMenuitem *)user_data;
+
+ count++;
+
+ rebuild_items (root, service);
+}
+
+static void
+user_removed (UsersServiceDbus *service,
+ UserData *user,
+ gpointer user_data)
+{
+ DbusmenuMenuitem *root = (DbusmenuMenuitem *)user_data;
+
+ count--;
+
+ rebuild_items (root, service);
+}
+
+static void
+create_items (DbusmenuMenuitem *root,
+ UsersServiceDbus *service)
+{
+ g_return_if_fail (IS_USERS_SERVICE_DBUS (service));
+
+ count = users_service_dbus_get_user_count (service);
+
+ rebuild_items (root, service);
}
int
@@ -167,35 +285,46 @@ main (int argc, char ** argv)
{
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);
session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
- bus_proxy = dbus_g_proxy_new_for_name(session_bus, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
+ bus_proxy = dbus_g_proxy_new_for_name (session_bus, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
GError * error = NULL;
guint nameret = 0;
if (!org_freedesktop_DBus_request_name(bus_proxy, INDICATOR_USERS_DBUS_NAME, 0, &nameret, &error)) {
g_error("Unable to call to request name");
return 1;
- }
+ }
if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
g_error("Unable to get name");
return 1;
- }
+ }
- root_menuitem = dbusmenu_menuitem_new();
- g_debug("Root ID: %d", dbusmenu_menuitem_get_id(root_menuitem));
+ dbus_interface = g_object_new (USERS_SERVICE_DBUS_TYPE, NULL);
- create_items(root_menuitem);
+ root_menuitem = dbusmenu_menuitem_new ();
+ g_debug ("Root ID: %d", dbusmenu_menuitem_get_id (root_menuitem));
+
+ create_items (root_menuitem, dbus_interface);
DbusmenuServer * server = dbusmenu_server_new(INDICATOR_USERS_DBUS_OBJECT);
dbusmenu_server_set_root(server, root_menuitem);
+ g_signal_connect (G_OBJECT (dbus_interface),
+ "user-added",
+ G_CALLBACK (user_added),
+ root_menuitem);
+ g_signal_connect (G_OBJECT (dbus_interface),
+ "user-removed",
+ G_CALLBACK (user_removed),
+ root_menuitem);
+
mainloop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(mainloop);