diff options
author | Cody Russell <crussell@canonical.com> | 2009-09-10 16:26:01 -0500 |
---|---|---|
committer | Cody Russell <crussell@canonical.com> | 2009-09-10 16:26:01 -0500 |
commit | efd24605727ee979b35053397463246456cf0ed0 (patch) | |
tree | 621f85a05dc90b0fe0a519108ba2b8d18897c494 | |
parent | 3211a5e810fbbe830a237127092d221018f4f6a2 (diff) | |
download | ayatana-indicator-session-efd24605727ee979b35053397463246456cf0ed0.tar.gz ayatana-indicator-session-efd24605727ee979b35053397463246456cf0ed0.tar.bz2 ayatana-indicator-session-efd24605727ee979b35053397463246456cf0ed0.zip |
work in progress
-rw-r--r-- | src/Makefile.am | 22 | ||||
-rw-r--r-- | src/dbus-shared-names.h | 14 | ||||
-rw-r--r-- | src/status-service.c | 16 | ||||
-rw-r--r-- | src/users-service-dbus.c | 379 | ||||
-rw-r--r-- | src/users-service-dbus.h | 73 | ||||
-rw-r--r-- | src/users-service.c | 144 | ||||
-rw-r--r-- | src/users-service.xml | 56 |
7 files changed, 656 insertions, 48 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index e2f0008..f7fa7a7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,7 +11,8 @@ sessionlib_LTLIBRARIES = libsession.la libsession_la_SOURCES = \ indicator-session.c \ dbus-shared-names.h \ - status-service-client.h + status-service-client.h \ + users-service-client.h libsession_la_CFLAGS = $(APPLET_CFLAGS) -Wall -Werror libsession_la_LIBADD = $(APPLET_LIBS) libsession_la_LDFLAGS = -module -avoid-version @@ -25,6 +26,9 @@ indicator_status_service_SOURCES = \ status-service-dbus.h \ status-service-dbus.c \ status-service-server.h \ + users-service-dbus.h \ + users-service-dbus.c \ + users-service-server.h \ status-provider.h \ status-provider.c \ status-provider-pidgin.h \ @@ -38,6 +42,20 @@ indicator_status_service_SOURCES = \ indicator_status_service_CFLAGS = $(STATUSSERVICE_CFLAGS) -Wall -Werror indicator_status_service_LDADD = $(STATUSSERVICE_LIBS) +users-service-client.h: $(srcdir)/users-service.xml + dbus-binding-tool \ + --prefix=_users_service_client \ + --mode=glib-client \ + --output=users-service-client.h \ + $(srcdir)/users-service.xml + +users-service-server.h: $(srcdir)/users-service.xml + dbus-binding-tool \ + --prefix=_users_service_server \ + --mode=glib-server \ + --output=users-service-server.h \ + $(srcdir)/users-service.xml + status-service-client.h: $(srcdir)/status-service.xml dbus-binding-tool \ --prefix=_status_service_client \ @@ -93,6 +111,8 @@ indicator_session_service_LDADD = $(SESSIONSERVICE_LIBS) $(GCONF_LIBS) ############### BUILT_SOURCES = \ + users-service-client.h \ + users-service-server.h \ status-service-client.h \ status-service-server.h \ status-provider-pidgin-marshal.h \ diff --git a/src/dbus-shared-names.h b/src/dbus-shared-names.h index a645830..7e7d456 100644 --- a/src/dbus-shared-names.h +++ b/src/dbus-shared-names.h @@ -7,16 +7,16 @@ 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 +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 <http://www.gnu.org/licenses/>. */ @@ -31,6 +31,8 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #define INDICATOR_USERS_DBUS_NAME "org.ayatana.indicator.users" #define INDICATOR_USERS_DBUS_OBJECT "/org/ayatana/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 "org.ayatana.indicator.session" #define INDICATOR_SESSION_DBUS_OBJECT "/org/ayatana/indicator/session/menu" diff --git a/src/status-service.c b/src/status-service.c index b210dcd..542317a 100644 --- a/src/status-service.c +++ b/src/status-service.c @@ -7,16 +7,16 @@ 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 +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 <http://www.gnu.org/licenses/>. */ @@ -228,12 +228,12 @@ main (int argc, char ** argv) if (!org_freedesktop_DBus_request_name(bus_proxy, INDICATOR_STATUS_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; - } + } g_idle_add(build_providers, NULL); diff --git a/src/users-service-dbus.c b/src/users-service-dbus.c new file mode 100644 index 0000000..95b0f49 --- /dev/null +++ b/src/users-service-dbus.c @@ -0,0 +1,379 @@ +/* + * Copyright 2009 Canonical Ltd. + * + * Authors: + * 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/>. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <dbus/dbus-glib.h> + +#include "dbus-shared-names.h" +#include "users-service-dbus.h" +#include "users-service-client.h" + +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 gboolean _users_service_server_count_users (UsersServiceDbus *service, + gint *count, + GError **error); +static gboolean _users_service_server_get_user_list (UsersServiceDbus *service, + GArray **list, + GError **error); +static gboolean _users_service_server_get_user_info (UsersServiceDbus *service, + const gint64 uid, + gchar **username, + gchar **real_name, + gchar **shell, + char **icon_url, + GError **error); +static gboolean _users_service_server_get_users_info (UsersServiceDbus *service, + const GArray *uids, + GPtrArray **user_info, + GError **error); +static void users_loaded (DBusGProxy *proxy, + gpointer user_data); +static void user_added (DBusGProxy *proxy, + guint uid, + gpointer user_data); +static void user_removed (DBusGProxy *proxy, + guint uid, + gpointer user_data); + +#include "users-service-server.h" + +/* Private */ +typedef struct _UsersServiceDbusPrivate UsersServiceDbusPrivate; + +struct _UsersServiceDbusPrivate +{ + GList *users; + gint count; + + DBusGConnection *session_bus; + DBusGConnection *system_bus; + DBusGProxy *dbus_proxy_session; + DBusGProxy *dbus_proxy_system; +}; + +#define USERS_SERVICE_DBUS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), USERS_SERVICE_DBUS_TYPE, UsersServiceDbusPrivate)) + +/* Signals */ +enum { + USERS_LOADED, + USER_ADDED, + USER_REMOVED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +/* GObject Boilerplate */ +G_DEFINE_TYPE (UsersServiceDbus, users_service_dbus, G_TYPE_OBJECT); + +static void +users_service_dbus_class_init (UsersServiceDbusClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (UsersServiceDbusPrivate)); + + object_class->dispose = users_service_dbus_dispose; + object_class->finalize = users_service_dbus_finalize; + + signals[USERS_LOADED] = g_signal_new ("users-loaded", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (UsersServiceDbusClass, users_loaded), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + 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__INT, + G_TYPE_NONE, 1, G_TYPE_INT); + + signals[USER_REMOVED] = g_signal_new ("user-removed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (UsersServiceDbusClass, user_removed), + NULL, NULL, + g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, 1, G_TYPE_INT); + + dbus_g_object_type_install_info (USERS_SERVICE_DBUS_TYPE, &dbus_glib__users_service_server_object_info); +} + +static void +users_service_dbus_init (UsersServiceDbus *self) +{ + GError *error = NULL; + UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); + + priv->users = NULL; + priv->count = 0; + + /* Get the buses */ + priv->session_bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + if (error != NULL) { + g_error ("Unable to get session bus: %s", error->message); + g_error_free (error); + + return; + } + + priv->system_bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (error != NULL) { + g_error("Unable to get system bus: %s", error->message); + g_error_free(error); + + return; + } + + dbus_g_connection_register_g_object (priv->session_bus, + INDICATOR_USERS_SERVICE_DBUS_OBJECT, + G_OBJECT (self)); + + /* Set up the DBUS service proxies */ + priv->dbus_proxy_session = dbus_g_proxy_new_for_name_owner (priv->session_bus, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + &error); + if (error != NULL) { + g_error ("Unable to get dbus proxy on session bus: %s", error->message); + g_error_free (error); + + return; + } + + priv->dbus_proxy_system = dbus_g_proxy_new_for_name_owner (priv->system_bus, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + &error); + if (error != NULL) { + g_error ("Unable to get dbus proxy on system bus: %s", error->message); + g_error_free (error); + + return; + } + + dbus_g_proxy_connect_signal (priv->dbus_proxy_system, + "UsersLoaded", + G_CALLBACK (users_loaded), + self, + NULL); + + dbus_g_proxy_connect_signal (priv->dbus_proxy_system, + "UserAdded", + G_CALLBACK (user_added), + self, + NULL); + + dbus_g_proxy_connect_signal (priv->dbus_proxy_system, + "UserRemoved", + G_CALLBACK (user_removed), + self, + NULL); +} + +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) +{ + G_OBJECT_CLASS (users_service_dbus_parent_class)->finalize (object); +} + +static void +users_loaded (DBusGProxy *proxy, + gpointer user_data) +{ + UsersServiceDbus *service; + UsersServiceDbusPrivate *priv; + GError *error = NULL; + GArray *uids; + GPtrArray *users_info; + gint count; + int i; + + service = (UsersServiceDbus *)user_data; + priv = USERS_SERVICE_DBUS_GET_PRIVATE (service); + + if (!org_gnome_DisplayManager_UserManager_count_users (proxy, + &count, + &error)) + { + g_warning ("failed to retrieve user count: %s", error->message); + g_error_free (error); + + return; + } + + priv->count = count; + + if (!org_gnome_DisplayManager_UserManager_get_user_list (proxy, + &uids, + &error)) + { + g_warning ("failed to retrieve user list: %s", error->message); + g_error_free (error); + + return; + } + + if (!org_gnome_DisplayManager_UserManager_get_users_info (proxy, + uids, + &users_info, + &error)) + { + g_warning ("failed to retrieve user info: %s", error->message); + g_error_free (error); + + return; + } + + for (i = 0; i < users_info->len; i++) + { + UserData *data = g_ptr_array_index (users_info, i); + + priv->users = g_list_prepend (priv->users, data); + } +} + +gint +users_service_dbus_get_user_count (UsersServiceDbus *self) +{ + UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); + + return priv->count; +} + +GList * +users_service_dbus_get_user_list (UsersServiceDbus *self) +{ + UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self); + + return priv->users; +} + +static void +user_added (DBusGProxy *proxy, + guint uid, + gpointer user_data) +{ + UsersServiceDbus *service = (UsersServiceDbus *)user_data; + UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service); + UserData *user = g_new0 (UserData, 1); + GError *error = NULL; + + priv->count++; + + if (!org_gnome_DisplayManager_UserManager_get_user_info (proxy, + uid, + &user->user_name, + &user->real_name, + &user->shell, + &user->icon_url, + &error)) + { + g_warning ("unable to retrieve user info: %s", error->message); + g_error_free (error); + + g_free (user); + + return; + } + + user->uid = uid; + + priv->users = g_list_prepend (priv->users, user); + + g_signal_emit (G_OBJECT (service), signals[USER_ADDED], 0, user, TRUE); +} + +static void +user_removed (DBusGProxy *proxy, + guint uid, + gpointer user_data) +{ + UsersServiceDbus *service = (UsersServiceDbus *)user_data; + UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service); + GList *l; + + priv->count--; + + for (l = priv->users; l != NULL; l = g_list_next (l)) + { + UserData *user = (UserData *)l->data; + + if (user->uid == uid) + { + priv->users = g_list_remove (priv->users, l->data); + g_signal_emit (G_OBJECT (service), signals[USER_REMOVED], 0, user, TRUE); + } + } +} + +static gboolean +_users_service_server_count_users (UsersServiceDbus *service, + gint *uids, + GError **error) +{ + return TRUE; +} + +static gboolean +_users_service_server_get_user_list (UsersServiceDbus *service, + GArray **list, + GError **error) +{ + return TRUE; +} + +static gboolean +_users_service_server_get_user_info (UsersServiceDbus *service, + const gint64 uid, + gchar **username, + gchar **real_name, + gchar **shell, + char **icon_url, + GError **error) +{ + return TRUE; +} + +static gboolean +_users_service_server_get_users_info (UsersServiceDbus *service, + const GArray *uids, + GPtrArray **user_info, + GError **error) +{ + return TRUE; +} diff --git a/src/users-service-dbus.h b/src/users-service-dbus.h new file mode 100644 index 0000000..df07e61 --- /dev/null +++ b/src/users-service-dbus.h @@ -0,0 +1,73 @@ +/* + * Copyright 2009 Canonical Ltd. + * + * Authors: + * 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/>. + */ + +#ifndef __USERS_SERVICE_DBUS_H__ +#define __USERS_SERVICE_DBUS_H__ + +#include <glib.h> +#include <glib-object.h> + +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)) + +typedef struct _UsersServiceDbus UsersServiceDbus; +typedef struct _UsersServiceDbusClass UsersServiceDbusClass; +typedef struct _UserData UserData; + +struct _UserData +{ + guint64 uid; + gchar *user_name; + gchar *real_name; + gchar *shell; + gchar *icon_url; +}; + +struct _UsersServiceDbus { + GObject parent; +}; + +struct _UsersServiceDbusClass { + GObjectClass parent_class; + + /* Signals */ + gboolean (*user_changed) (UsersServiceDbus *self, gchar **name, gpointer user_data); + gboolean (*users_icons_changed) (UsersServiceDbus *self, GArray **icons, gpointer user_data); + + void (* users_loaded) (UsersServiceDbus *self, gpointer user_data); + + void (* user_added) (UsersServiceDbus *self, gint64 uid, gpointer user_data); + void (* user_removed) (UsersServiceDbus *self, gint64 uid, gpointer user_data); + void (* user_updated) (UsersServiceDbus *self, gint64 uid, gpointer user_data); +}; + +GType users_service_dbus_get_type (void) G_GNUC_CONST; + +gint users_service_dbus_get_user_count (UsersServiceDbus *self); +GList *users_service_dbus_get_user_list (UsersServiceDbus *self); + +G_END_DECLS + +#endif diff --git a/src/users-service.c b/src/users-service.c index 5db832b..77b5f95 100644 --- a/src/users-service.c +++ b/src/users-service.c @@ -7,16 +7,16 @@ 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 +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 <http://www.gnu.org/licenses/>. */ @@ -31,15 +31,22 @@ 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" +#define MINIMUM_USERS 1 +#define MAXIMUM_USERS 7 -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 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) @@ -108,24 +115,84 @@ activate_new_session (DbusmenuMenuitem * mi, gpointer user_data) } static void -create_items (DbusmenuMenuitem * root) { - DbusmenuMenuitem * mi = NULL; - - 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) +{ +} - 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 +remove_menu_item (DbusmenuMenuitem *root, gpointer user_data) +{ + DbusmenuMenuitem *child = (DbusmenuMenuitem *)user_data; - return; + dbusmenu_menuitem_child_delete (root, child); +} + +static void +rebuild_items (DbusmenuMenuitem *root, + UsersServiceDbus *service) +{ + DbusmenuMenuitem *mi = NULL; + GList *u; + UserData *user; + + 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 > 1 && count < 7) + { + for (u = users; u != NULL; u = g_list_next (u)) + { + user = u->data; + + 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 +create_items (DbusmenuMenuitem *root, + UsersServiceDbus *service) +{ + g_return_if_fail (IS_USERS_SERVICE_DBUS (service)); + + dbusmenu_menuitem_foreach (root, remove_menu_item, NULL); + + count = users_service_dbus_get_user_count (service); + if (count > 1 && count < 7) + { + users = users_service_dbus_get_user_list (service); + } + + rebuild_items (root, service); +} + +static void +user_added (UsersServiceDbus *service, + gpointer user_data) +{ + /* Never thought you'd see a gpointer user_data get casted to a UserData* did you? */ + users = g_list_append (users, (UserData *) user_data); +} + +static void +user_removed (UsersServiceDbus *service, + gpointer user_data) +{ + users = g_list_remove (users, (UserData *) user_data); } int @@ -134,28 +201,39 @@ main (int argc, char ** argv) g_type_init(); 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; - } + } + + dbus_interface = g_object_new (USERS_SERVICE_DBUS_TYPE, NULL); root_menuitem = dbusmenu_menuitem_new(); - g_debug("Root ID: %d", dbusmenu_menuitem_get_id(root_menuitem)); + g_debug ("Root ID: %d", dbusmenu_menuitem_get_id (root_menuitem)); - create_items(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); diff --git a/src/users-service.xml b/src/users-service.xml new file mode 100644 index 0000000..9eccf5d --- /dev/null +++ b/src/users-service.xml @@ -0,0 +1,56 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node name="/org/gnome/DisplayManager/UserManager"> + <interface name="org.gnome.DisplayManager.UserManager"> + + <!-- Get the number of known users --> + <method name="CountUsers"> + <arg name="user_count" direction="out" type="i"/> + </method> + + <!-- Get the list of known UIDs --> + <method name="GetUserList"> + <arg name="uids" direction="out" type="ax"/> + </method> + + <!-- Get user info for a user --> + <method name="GetUserInfo"> + <arg name="uid" direction="in" type="x"/> + <arg name="user_name" direction="out" type="s"/> + <arg name="real_name" direction="out" type="s"/> + <arg name="shell" direction="out" type="s"/> + <arg name="icon_url" direction="out" type="s"/> + </method> + + <!-- Get user info for a list of users --> + <method name="GetUsersInfo"> + <arg name="uid" direction="in" type="ax"/> + <!-- (uid, user_name, real_name, shell, icon_url) --> + <arg name="user_info" direction="out" type="a(xssss)"/> + </method> + + <!-- Triggered when user information is being reloaded. + All existing user information is invalid from this signal. + Wait for the UsersLoaded signal --> + <signal name="LoadingUsers"></signal> + + <!-- Triggered when user information has been reloaded. + A client should call GetUserList() now --> + <signal name="UsersLoaded"></signal> + + <!-- Triggered when a user has updated information --> + <signal name="UserUpdated"> + <arg name="uid" type="x"/> + </signal> + + <!-- Triggered when a users are added to/removed from the system. + Clients should monitor these signals as soon as they connect to + this object --> + <signal name="UserAdded"> + <arg name="uid" type="x"/> + </signal> + <signal name="UserRemoved"> + <arg name="uid" type="x"/> + </signal> + + </interface> +</node> |