/* * Copyright 2009 Canonical Ltd. * * Authors: * Cody Russell * * 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 . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #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; }