[gdm] Get users from account service, fallback to old way
- From: William Jon McCann <mccann src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gdm] Get users from account service, fallback to old way
- Date: Fri, 11 Jun 2010 01:54:21 +0000 (UTC)
commit b236a9dab5dcf709546a8721ce823ae7ea989cf0
Author: Ray Strode <rstrode redhat com>
Date: Tue Mar 16 03:07:19 2010 -0400
Get users from account service, fallback to old way
https://bugzilla.gnome.org/show_bug.cgi?id=610179
gui/simple-greeter/gdm-user-manager.c | 413 +++++++++++++++++++++++++-------
gui/simple-greeter/gdm-user.c | 276 +++++++++++++++++-----
gui/simple-greeter/gdm-user.h | 4 +
gui/user-switch-applet/applet.c | 7 +-
4 files changed, 543 insertions(+), 157 deletions(-)
---
diff --git a/gui/simple-greeter/gdm-user-manager.c b/gui/simple-greeter/gdm-user-manager.c
index a91b999..857314a 100644
--- a/gui/simple-greeter/gdm-user-manager.c
+++ b/gui/simple-greeter/gdm-user-manager.c
@@ -61,9 +61,9 @@
/* Prefs Defaults */
#ifdef __sun
-#define DEFAULT_MINIMAL_UID 100
+#define FALLBACK_MINIMAL_UID 100
#else
-#define DEFAULT_MINIMAL_UID 500
+#define FALLBACK_MINIMAL_UID 500
#endif
#ifndef _PATH_SHELLS
@@ -78,13 +78,19 @@
#define GDM_USERNAME "gdm"
#endif
+#define ACCOUNTS_NAME "org.freedesktop.Accounts"
+#define ACCOUNTS_PATH "/org/freedesktop/Accounts"
+#define ACCOUNTS_INTERFACE "org.freedesktop.Accounts"
+
struct GdmUserManagerPrivate
{
GHashTable *users_by_name;
+ GHashTable *users_by_object_path;
GHashTable *sessions;
GHashTable *shells;
DBusGConnection *connection;
DBusGProxy *seat_proxy;
+ DBusGProxy *accounts_proxy;
char *seat_id;
GFileMonitor *passwd_monitor;
@@ -127,7 +133,7 @@ static void gdm_user_manager_class_init (GdmUserManagerClass *klass);
static void gdm_user_manager_init (GdmUserManager *user_manager);
static void gdm_user_manager_finalize (GObject *object);
-static void load_users (GdmUserManager *manager);
+static void load_users_manually (GdmUserManager *manager);
static void monitor_local_users (GdmUserManager *manager);
static gpointer user_manager_object = NULL;
@@ -638,10 +644,19 @@ static void
add_user (GdmUserManager *manager,
GdmUser *user)
{
+ const char *object_path;
+
g_hash_table_insert (manager->priv->users_by_name,
g_strdup (gdm_user_get_user_name (user)),
g_object_ref (user));
+ object_path = gdm_user_get_object_path (user);
+ if (object_path != NULL) {
+ g_hash_table_insert (manager->priv->users_by_object_path,
+ (gpointer) object_path,
+ g_object_ref (user));
+ }
+
if (manager->priv->is_loaded) {
g_signal_emit (manager, signals[USER_ADDED], 0, user);
}
@@ -657,12 +672,15 @@ add_new_user_for_pwent (GdmUserManager *manager,
{
GdmUser *user;
- g_debug ("Creating new user");
+ g_debug ("Creating new user from password entry");
user = create_user (manager);
_gdm_user_update_from_pwent (user, pwent);
add_user (manager, user);
+ g_object_unref (user);
+
+ user = g_hash_table_lookup (manager->priv->users_by_name, pwent->pw_name);
return user;
}
@@ -673,6 +691,9 @@ remove_user (GdmUserManager *manager,
{
g_signal_handlers_disconnect_by_func (user, on_user_changed, manager);
g_signal_handlers_disconnect_by_func (user, on_user_sessions_changed, manager);
+ if (gdm_user_get_object_path (user) != NULL) {
+ g_hash_table_remove (manager->priv->users_by_object_path, gdm_user_get_object_path (user));
+ }
g_hash_table_remove (manager->priv->users_by_name, gdm_user_get_user_name (user));
g_signal_emit (manager, signals[USER_REMOVED], 0, user);
@@ -681,6 +702,62 @@ remove_user (GdmUserManager *manager,
}
}
+static void
+add_new_user_for_object_path (const char *object_path,
+ GdmUserManager *manager)
+{
+ GdmUser *user;
+ const char *username;
+
+ if (g_hash_table_lookup (manager->priv->users_by_object_path, object_path)) {
+ return;
+ }
+ user = gdm_user_new_from_object_path (object_path);
+
+ if (user == NULL) {
+ return;
+ }
+
+ username = gdm_user_get_user_name (user);
+ if (user_in_exclude_list (manager, username)) {
+ g_debug ("GdmUserManager: excluding user '%s'", username);
+ g_object_unref (user);
+ return;
+ }
+
+ g_signal_connect (user, "sessions-changed",
+ G_CALLBACK (on_user_sessions_changed), manager);
+ g_signal_connect (user, "changed",
+ G_CALLBACK (on_user_changed), manager);
+
+ add_user (manager, user);
+ g_object_unref (user);
+}
+
+static void
+on_new_user_in_accounts_service (DBusGProxy *proxy,
+ const char *object_path,
+ gpointer user_data)
+{
+ GdmUserManager *manager = GDM_USER_MANAGER (user_data);
+
+ add_new_user_for_object_path (object_path, manager);
+}
+
+static void
+on_user_removed_in_accounts_service (DBusGProxy *proxy,
+ const char *object_path,
+ gpointer user_data)
+{
+ GdmUserManager *manager = GDM_USER_MANAGER (user_data);
+ GdmUser *user;
+
+ user = g_hash_table_lookup (manager->priv->users_by_object_path, object_path);
+ g_object_ref (user);
+ remove_user (manager, user);
+ g_object_unref (user);
+}
+
static char *
get_current_seat_id (DBusGConnection *connection)
{
@@ -777,6 +854,101 @@ get_uid_from_session_id (GdmUserManager *manager,
return TRUE;
}
+static char *
+get_user_object_path_from_accounts_service (GdmUserManager *manager,
+ const char *name)
+{
+ GError *error;
+ char *object_path;
+ gboolean res;
+
+ g_assert (manager->priv->accounts_proxy != NULL);
+
+ error = NULL;
+ object_path = NULL;
+ res = dbus_g_proxy_call (manager->priv->accounts_proxy,
+ "FindUserByName",
+ &error,
+ G_TYPE_STRING,
+ name,
+ G_TYPE_INVALID,
+ DBUS_TYPE_G_OBJECT_PATH,
+ &object_path,
+ G_TYPE_INVALID);
+ if (! res) {
+ if (error != NULL) {
+ g_debug ("Failed to find user %s: %s", name, error->message);
+ g_error_free (error);
+ } else {
+ g_debug ("Failed to find user %s", name);
+ }
+ return NULL;
+ }
+ return object_path;
+}
+
+static void
+set_is_loaded (GdmUserManager *manager,
+ gboolean is_loaded)
+{
+ if (manager->priv->is_loaded != is_loaded) {
+ manager->priv->is_loaded = is_loaded;
+ g_object_notify (G_OBJECT (manager), "is-loaded");
+ }
+}
+
+static void
+on_list_cached_users_finished (DBusGProxy *proxy,
+ DBusGProxyCall *call_id,
+ gpointer data)
+{
+ GdmUserManager *manager = data;
+ GError *error = NULL;
+ GPtrArray *paths;
+
+ if (!dbus_g_proxy_end_call (proxy,
+ call_id,
+ &error,
+ dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &paths,
+ G_TYPE_INVALID)) {
+ g_debug ("ListCachedUsers failed: %s", error->message);
+ g_error_free (error);
+
+ g_object_unref (manager->priv->accounts_proxy);
+ manager->priv->accounts_proxy = NULL;
+
+ load_users_manually (manager);
+
+ return;
+ }
+
+ g_ptr_array_foreach (paths, (GFunc)add_new_user_for_object_path, manager);
+
+ g_ptr_array_foreach (paths, (GFunc)g_free, NULL);
+ g_ptr_array_free (paths, TRUE);
+
+ /* Add users who are specifically included */
+ if (manager->priv->include_usernames != NULL) {
+ GSList *l;
+
+ for (l = manager->priv->include_usernames; l != NULL; l = l->next) {
+ GdmUser *user;
+
+ g_debug ("Adding included user %s", (char *)l->data);
+ /*
+ * The call to gdm_user_manager_get_user will add the user if it is
+ * valid and not already in the hash.
+ */
+ user = gdm_user_manager_get_user (manager, l->data);
+ if (user == NULL) {
+ g_debug ("GdmUserManager: unable to lookup user '%s'", (char *)l->data);
+ }
+ }
+ }
+
+ set_is_loaded (manager, TRUE);
+}
+
static void
maybe_add_session (GdmUserManager *manager,
const char *session_id)
@@ -785,7 +957,6 @@ maybe_add_session (GdmUserManager *manager,
gboolean res;
struct passwd *pwent;
GdmUser *user;
- gboolean is_new;
char *x11_display;
res = get_uid_from_session_id (manager, session_id, &uid);
@@ -816,22 +987,9 @@ maybe_add_session (GdmUserManager *manager,
return;
}
- user = g_hash_table_lookup (manager->priv->users_by_name, pwent->pw_name);
- if (user == NULL) {
- g_debug ("Creating new user");
-
- user = create_user (manager);
- _gdm_user_update_from_pwent (user, pwent);
- is_new = TRUE;
- } else {
- is_new = FALSE;
- }
-
- add_session_for_user (manager, user, session_id);
-
- /* only add the user if it was newly created */
- if (is_new) {
- add_user (manager, user);
+ user = gdm_user_manager_get_user (manager, pwent->pw_name);
+ if (user != NULL) {
+ add_session_for_user (manager, user, session_id);
}
}
@@ -939,6 +1097,60 @@ get_seat_proxy (GdmUserManager *manager)
}
+static void
+on_accounts_proxy_destroy (DBusGProxy *proxy,
+ GdmUserManager *manager)
+{
+ g_debug ("GdmUserManager: accounts proxy destroyed");
+
+ manager->priv->accounts_proxy = NULL;
+}
+
+static void
+get_accounts_proxy (GdmUserManager *manager)
+{
+ DBusGProxy *proxy;
+ GError *error;
+
+ g_assert (manager->priv->accounts_proxy == NULL);
+
+ error = NULL;
+ proxy = dbus_g_proxy_new_for_name_owner (manager->priv->connection,
+ ACCOUNTS_NAME,
+ ACCOUNTS_PATH,
+ ACCOUNTS_INTERFACE,
+ &error);
+ manager->priv->accounts_proxy = proxy;
+
+ if (proxy != NULL) {
+ g_signal_connect (proxy, "destroy",
+ G_CALLBACK (on_accounts_proxy_destroy),
+ manager);
+
+ dbus_g_proxy_add_signal (proxy,
+ "UserAdded",
+ DBUS_TYPE_G_OBJECT_PATH,
+ G_TYPE_INVALID);
+ dbus_g_proxy_add_signal (proxy,
+ "UserDeleted",
+ DBUS_TYPE_G_OBJECT_PATH,
+ G_TYPE_INVALID);
+
+ dbus_g_proxy_connect_signal (proxy,
+ "UserAdded",
+ G_CALLBACK (on_new_user_in_accounts_service),
+ manager,
+ NULL);
+ dbus_g_proxy_connect_signal (proxy,
+ "UserDeleted",
+ G_CALLBACK (on_user_removed_in_accounts_service),
+ manager,
+ NULL);
+ } else {
+ g_debug ("GdmUserManager: Unable to connect to accounts service");
+ }
+}
+
/**
* gdm_manager_get_user:
* @manager: the manager to query.
@@ -960,13 +1172,24 @@ gdm_user_manager_get_user (GdmUserManager *manager,
user = g_hash_table_lookup (manager->priv->users_by_name, username);
+ /* if we don't have it loaded try to load it now */
if (user == NULL) {
- struct passwd *pwent;
+ if (manager->priv->accounts_proxy != NULL) {
+ char *object_path;
- pwent = getpwnam (username);
+ object_path = get_user_object_path_from_accounts_service (manager, username);
- if (pwent != NULL) {
- user = add_new_user_for_pwent (manager, pwent);
+ if (object_path != NULL) {
+ add_new_user_for_object_path (object_path, manager);
+ g_free (object_path);
+ user = g_hash_table_lookup (manager->priv->users_by_name, username);
+ }
+ } else {
+ struct passwd *pwent;
+ pwent = getpwnam (username);
+ if (pwent != NULL) {
+ user = add_new_user_for_pwent (manager, pwent);
+ }
}
}
@@ -977,7 +1200,6 @@ GdmUser *
gdm_user_manager_get_user_by_uid (GdmUserManager *manager,
gulong uid)
{
- GdmUser *user;
struct passwd *pwent;
g_return_val_if_fail (GDM_IS_USER_MANAGER (manager), NULL);
@@ -988,13 +1210,7 @@ gdm_user_manager_get_user_by_uid (GdmUserManager *manager,
return NULL;
}
- user = g_hash_table_lookup (manager->priv->users_by_name, pwent->pw_name);
-
- if (user == NULL) {
- user = add_new_user_for_pwent (manager, pwent);
- }
-
- return user;
+ return gdm_user_manager_get_user (manager, pwent->pw_name);
}
static void
@@ -1138,16 +1354,6 @@ process_ck_history_line (GdmUserManager *manager,
g_free (username);
}
-static void
-set_is_loaded (GdmUserManager *manager,
- gboolean is_loaded)
-{
- if (manager->priv->is_loaded != is_loaded) {
- manager->priv->is_loaded = is_loaded;
- g_object_notify (G_OBJECT (manager), "is-loaded");
- }
-}
-
static gboolean
ck_history_watch (GIOChannel *source,
GIOCondition condition,
@@ -1351,7 +1557,7 @@ reload_passwd_file (GHashTable *valid_shells,
pwent = fgetpwent (fp)) {
/* Skip users below MinimalUID... */
- if (pwent->pw_uid < DEFAULT_MINIMAL_UID) {
+ if (pwent->pw_uid < FALLBACK_MINIMAL_UID) {
continue;
}
@@ -1575,6 +1781,65 @@ load_sessions (GdmUserManager *manager)
g_ptr_array_free (sessions, TRUE);
}
+static void
+reload_shells (GdmUserManager *manager)
+{
+ char *shell;
+
+ setusershell ();
+
+ g_hash_table_remove_all (manager->priv->shells);
+ for (shell = getusershell (); shell != NULL; shell = getusershell ()) {
+ /* skip well known not-real shells */
+ if (shell == NULL
+ || strcmp (shell, "/sbin/nologin") == 0
+ || strcmp (shell, "/bin/false") == 0) {
+ g_debug ("GdmUserManager: skipping shell %s", shell);
+ continue;
+ }
+ g_hash_table_insert (manager->priv->shells,
+ g_strdup (shell),
+ GUINT_TO_POINTER (TRUE));
+ }
+
+ endusershell ();
+}
+
+static void
+load_users_manually (GdmUserManager *manager)
+{
+ gboolean res;
+
+ manager->priv->shells = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ NULL);
+ reload_shells (manager);
+
+ load_sessions (manager);
+
+ res = load_ck_history (manager);
+ schedule_reload_passwd (manager);
+}
+
+static void
+load_users (GdmUserManager *manager)
+{
+ if (manager->priv->accounts_proxy != NULL) {
+ g_debug ("GdmUserManager: calling 'ListCachedUsers'");
+
+ dbus_g_proxy_begin_call (manager->priv->accounts_proxy,
+ "ListCachedUsers",
+ on_list_cached_users_finished,
+ manager,
+ NULL,
+ G_TYPE_INVALID);
+ } else {
+ g_debug ("GdmUserManager: Getting users manually");
+ load_users_manually (manager);
+ }
+}
+
static gboolean
load_users_idle (GdmUserManager *manager)
{
@@ -1614,30 +1879,6 @@ queue_reload_passwd (GdmUserManager *manager)
}
static void
-reload_shells (GdmUserManager *manager)
-{
- char *shell;
-
- setusershell ();
-
- g_hash_table_remove_all (manager->priv->shells);
- for (shell = getusershell (); shell != NULL; shell = getusershell ()) {
- /* skip well known not-real shells */
- if (shell == NULL
- || strcmp (shell, "/sbin/nologin") == 0
- || strcmp (shell, "/bin/false") == 0) {
- g_debug ("GdmUserManager: skipping shell %s", shell);
- continue;
- }
- g_hash_table_insert (manager->priv->shells,
- g_strdup (shell),
- GUINT_TO_POINTER (TRUE));
- }
-
- endusershell ();
-}
-
-static void
on_shells_monitor_changed (GFileMonitor *monitor,
GFile *file,
GFile *other_file,
@@ -1819,23 +2060,6 @@ monitor_local_users (GdmUserManager *manager)
}
static void
-load_users (GdmUserManager *manager)
-{
- gboolean res;
-
- manager->priv->shells = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- NULL);
- reload_shells (manager);
-
- load_sessions (manager);
-
- res = load_ck_history (manager);
- schedule_reload_passwd (manager);
-}
-
-static void
gdm_user_manager_class_init (GdmUserManagerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -1944,9 +2168,10 @@ gdm_user_manager_init (GdmUserManager *manager)
g_free,
(GDestroyNotify) g_object_run_dispose);
- if (manager->priv->include_all == TRUE) {
- monitor_local_users (manager);
- }
+ manager->priv->users_by_object_path = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ NULL,
+ (GDestroyNotify) g_object_unref);
g_assert (manager->priv->seat_proxy == NULL);
@@ -1965,7 +2190,7 @@ gdm_user_manager_init (GdmUserManager *manager)
manager->priv->cancellable = g_cancellable_new ();
get_seat_proxy (manager);
-
+ get_accounts_proxy (manager);
queue_load_users (manager);
}
@@ -2017,10 +2242,16 @@ gdm_user_manager_finalize (GObject *object)
g_hash_table_destroy (manager->priv->sessions);
- g_file_monitor_cancel (manager->priv->passwd_monitor);
+ if (manager->priv->passwd_monitor != NULL) {
+ g_file_monitor_cancel (manager->priv->passwd_monitor);
+ }
+
g_hash_table_destroy (manager->priv->users_by_name);
+ g_hash_table_destroy (manager->priv->users_by_object_path);
- g_file_monitor_cancel (manager->priv->shells_monitor);
+ if (manager->priv->shells_monitor != NULL) {
+ g_file_monitor_cancel (manager->priv->shells_monitor);
+ }
g_hash_table_destroy (manager->priv->shells);
g_free (manager->priv->seat_id);
diff --git a/gui/simple-greeter/gdm-user.c b/gui/simple-greeter/gdm-user.c
index a83076b..4f6194f 100644
--- a/gui/simple-greeter/gdm-user.c
+++ b/gui/simple-greeter/gdm-user.c
@@ -26,6 +26,9 @@
#include <sys/stat.h>
#include <unistd.h>
+#include <dbus/dbus-glib.h>
+
+#include <glib.h>
#include <glib/gi18n.h>
#include <gio/gio.h>
#include <gtk/gtk.h>
@@ -41,6 +44,9 @@
#define MAX_FILE_SIZE 65536
#define MINIMAL_UID 100
+#define USER_ACCOUNTS_NAME "org.freedesktop.Accounts"
+#define USER_ACCOUNTS_INTERFACE "org.freedesktop.Accounts.User"
+
enum {
CHANGED,
SESSIONS_CHANGED,
@@ -50,11 +56,14 @@ enum {
struct _GdmUser {
GObject parent;
+ DBusGConnection *connection;
+ DBusGProxy *accounts_proxy;
+ char *object_path;
+
uid_t uid;
char *user_name;
char *real_name;
- char *home_dir;
- char *shell;
+ char *icon_file;
GList *sessions;
gulong login_frequency;
};
@@ -65,6 +74,8 @@ typedef struct _GdmUserClass
} GdmUserClass;
static void gdm_user_finalize (GObject *object);
+static gboolean check_user_file (const char *filename,
+ gssize max_file_size);
static guint signals[LAST_SIGNAL] = { 0 };
@@ -158,9 +169,17 @@ gdm_user_class_init (GdmUserClass *class)
static void
gdm_user_init (GdmUser *user)
{
+ GError *error;
+
user->user_name = NULL;
user->real_name = NULL;
user->sessions = NULL;
+
+ error = NULL;
+ user->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (user->connection == NULL) {
+ g_warning ("Couldn't connect to system bus: %s", error->message);
+ }
}
static void
@@ -172,6 +191,15 @@ gdm_user_finalize (GObject *object)
g_free (user->user_name);
g_free (user->real_name);
+ g_free (user->icon_file);
+
+ if (user->accounts_proxy != NULL) {
+ g_object_unref (user->accounts_proxy);
+ }
+
+ if (user->connection != NULL) {
+ dbus_g_connection_unref (user->connection);
+ }
if (G_OBJECT_CLASS (gdm_user_parent_class)->finalize)
(*G_OBJECT_CLASS (gdm_user_parent_class)->finalize) (object);
@@ -195,6 +223,7 @@ _gdm_user_update_from_pwent (GdmUser *user,
g_return_if_fail (GDM_IS_USER (user));
g_return_if_fail (pwent != NULL);
+ g_return_if_fail (user->object_path == NULL);
changed = FALSE;
@@ -253,6 +282,23 @@ _gdm_user_update_from_pwent (GdmUser *user,
(pwent->pw_name &&
user->user_name &&
strcmp (user->user_name, pwent->pw_name) != 0)) {
+
+ g_free (user->icon_file);
+ user->icon_file = NULL;
+ if (pwent->pw_name != NULL) {
+ gboolean res;
+
+ user->icon_file = g_build_filename (GDM_CACHE_DIR, pwent->pw_name, "face", NULL);
+
+ res = check_user_file (user->icon_file,
+ MAX_FILE_SIZE);
+
+ if (!res) {
+ g_free (user->icon_file);
+ user->icon_file = g_build_filename (GLOBAL_FACEDIR, pwent->pw_name, NULL);
+ }
+ }
+
g_free (user->user_name);
user->user_name = g_strdup (pwent->pw_name);
changed = TRUE;
@@ -431,31 +477,6 @@ check_user_file (const char *filename,
return TRUE;
}
-static GdkPixbuf *
-render_icon_from_cache (GdmUser *user,
- int icon_size)
-{
- GdkPixbuf *retval;
- char *path;
- gboolean res;
-
- path = g_build_filename (GDM_CACHE_DIR, user->user_name, "face", NULL);
- res = check_user_file (path,
- MAX_FILE_SIZE);
- if (res) {
- retval = gdk_pixbuf_new_from_file_at_size (path,
- icon_size,
- icon_size,
- NULL);
- } else {
- g_debug ("Could not access face icon %s", path);
- retval = NULL;
- }
- g_free (path);
-
- return retval;
-}
-
static void
rounded_rectangle (cairo_t *cr,
gdouble aspect,
@@ -689,55 +710,41 @@ gdm_user_render_icon (GdmUser *user,
{
GdkPixbuf *pixbuf;
GdkPixbuf *framed;
- char *path;
- char *tmp;
gboolean res;
+ GError *error;
g_return_val_if_fail (GDM_IS_USER (user), NULL);
g_return_val_if_fail (icon_size > 12, NULL);
- path = NULL;
-
- pixbuf = render_icon_from_cache (user, icon_size);
- if (pixbuf != NULL) {
- goto out;
- }
-
- /* Try ${GlobalFaceDir}/${username} */
- path = g_build_filename (GLOBAL_FACEDIR, user->user_name, NULL);
- res = check_user_file (path,
- MAX_FILE_SIZE);
- if (res) {
- pixbuf = gdk_pixbuf_new_from_file_at_size (path,
- icon_size,
- icon_size,
- NULL);
- } else {
- g_debug ("Could not access global face icon %s", path);
- pixbuf = NULL;
+ pixbuf = NULL;
+ if (user->icon_file) {
+ res = check_user_file (user->icon_file,
+ MAX_FILE_SIZE);
+ if (res) {
+ pixbuf = gdk_pixbuf_new_from_file_at_size (user->icon_file,
+ icon_size,
+ icon_size,
+ NULL);
+ } else {
+ pixbuf = NULL;
+ }
}
- g_free (path);
if (pixbuf != NULL) {
goto out;
}
- /* Finally, ${GlobalFaceDir}/${username}.png */
- tmp = g_strconcat (user->user_name, ".png", NULL);
- path = g_build_filename (GLOBAL_FACEDIR, tmp, NULL);
- g_free (tmp);
- res = check_user_file (path,
- MAX_FILE_SIZE);
- if (res) {
- pixbuf = gdk_pixbuf_new_from_file_at_size (path,
- icon_size,
- icon_size,
- NULL);
- } else {
- g_debug ("Could not access global face icon %s", path);
- pixbuf = NULL;
+ error = NULL;
+ pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
+
+ "avatar-default",
+ icon_size,
+ GTK_ICON_LOOKUP_FORCE_SIZE,
+ &error);
+ if (error) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
}
- g_free (path);
out:
if (pixbuf != NULL) {
@@ -751,6 +758,22 @@ gdm_user_render_icon (GdmUser *user,
return pixbuf;
}
+G_CONST_RETURN gchar *
+gdm_user_get_icon_file (GdmUser *user)
+{
+ g_return_val_if_fail (GDM_IS_USER (user), NULL);
+
+ return user->icon_file;
+}
+
+G_CONST_RETURN gchar *
+gdm_user_get_object_path (GdmUser *user)
+{
+ g_return_val_if_fail (GDM_IS_USER (user), NULL);
+
+ return user->object_path;
+}
+
G_CONST_RETURN char *
gdm_user_get_primary_session_id (GdmUser *user)
{
@@ -780,3 +803,128 @@ out:
return primary_ssid;
}
+static void
+collect_props (const gchar *key,
+ const GValue *value,
+ GdmUser *user)
+{
+ gboolean handled = TRUE;
+
+ if (strcmp (key, "Uid") == 0) {
+ user->uid = g_value_get_uint64 (value);
+ } else if (strcmp (key, "UserName") == 0) {
+ g_free (user->user_name);
+ user->user_name = g_value_dup_string (value);
+ } else if (strcmp (key, "RealName") == 0) {
+ g_free (user->real_name);
+ user->real_name = g_value_dup_string (value);
+ } else if (strcmp (key, "AccountType") == 0) {
+ /* ignore */
+ } else if (strcmp (key, "Email") == 0) {
+ /* ignore */
+ } else if (strcmp (key, "Language") == 0) {
+ /* ignore */
+ } else if (strcmp (key, "Location") == 0) {
+ /* ignore */
+ } else if (strcmp (key, "LoginFrequency") == 0) {
+ user->login_frequency = g_value_get_uint64 (value);
+ } else if (strcmp (key, "IconFile") == 0) {
+ g_free (user->icon_file);
+ user->icon_file = g_value_dup_string (value);
+ } else if (strcmp (key, "Locked") == 0) {
+ /* ignore */
+ } else if (strcmp (key, "AutomaticLogin") == 0) {
+ /* ignore */
+ } else if (strcmp (key, "PasswordMode") == 0) {
+ /* ignore */
+ } else if (strcmp (key, "PasswordHint") == 0) {
+ /* ignore */
+ } else if (strcmp (key, "HomeDirectory") == 0) {
+ /* ignore */
+ } else if (strcmp (key, "Shell") == 0) {
+ /* ignore */
+ } else {
+ handled = FALSE;
+ }
+
+ if (!handled) {
+ g_debug ("unhandled property %s", key);
+ }
+}
+
+static gboolean
+update_info (GdmUser *user)
+{
+ GError *error;
+ DBusGProxy *proxy;
+ GHashTable *hash_table;
+ gboolean retval;
+
+ proxy = dbus_g_proxy_new_for_name (user->connection,
+ USER_ACCOUNTS_NAME,
+ user->object_path,
+ DBUS_INTERFACE_PROPERTIES);
+
+ error = NULL;
+ if (!dbus_g_proxy_call (proxy,
+ "GetAll",
+ &error,
+ G_TYPE_STRING,
+ USER_ACCOUNTS_INTERFACE,
+ G_TYPE_INVALID,
+ dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
+ &hash_table,
+ G_TYPE_INVALID)) {
+ g_debug ("Error calling GetAll() when retrieving properties for %s: %s", user->object_path, error->message);
+ g_error_free (error);
+ retval = FALSE;
+ goto out;
+ }
+ g_hash_table_foreach (hash_table, (GHFunc) collect_props, user);
+ g_hash_table_unref (hash_table);
+
+ retval = TRUE;
+ out:
+ g_object_unref (proxy);
+ return retval;
+}
+
+static void
+changed_handler (DBusGProxy *proxy,
+ gpointer *data)
+{
+ GdmUser *user = GDM_USER (data);
+
+ if (update_info (user)) {
+ g_signal_emit (user, signals[CHANGED], 0);
+ }
+}
+
+GdmUser *
+gdm_user_new_from_object_path (const gchar *object_path)
+{
+ GdmUser *user;
+
+ user = (GdmUser *)g_object_new (GDM_TYPE_USER, NULL);
+ user->object_path = g_strdup (object_path);
+
+ user->accounts_proxy = dbus_g_proxy_new_for_name (user->connection,
+ USER_ACCOUNTS_NAME,
+ user->object_path,
+ USER_ACCOUNTS_INTERFACE);
+ dbus_g_proxy_set_default_timeout (user->accounts_proxy, INT_MAX);
+ dbus_g_proxy_add_signal (user->accounts_proxy, "Changed", G_TYPE_INVALID);
+
+ dbus_g_proxy_connect_signal (user->accounts_proxy, "Changed",
+ G_CALLBACK (changed_handler), user, NULL);
+
+ if (!update_info (user)) {
+ goto error;
+ }
+
+ return user;
+
+ error:
+ g_object_unref (user);
+ return NULL;
+}
diff --git a/gui/simple-greeter/gdm-user.h b/gui/simple-greeter/gdm-user.h
index 725c06a..ff566a7 100644
--- a/gui/simple-greeter/gdm-user.h
+++ b/gui/simple-greeter/gdm-user.h
@@ -39,12 +39,16 @@ typedef struct _GdmUser GdmUser;
GType gdm_user_get_type (void) G_GNUC_CONST;
+GdmUser *gdm_user_new_from_object_path (const gchar *path);
+const char *gdm_user_get_object_path (GdmUser *user);
+
gulong gdm_user_get_uid (GdmUser *user);
G_CONST_RETURN char *gdm_user_get_user_name (GdmUser *user);
G_CONST_RETURN char *gdm_user_get_real_name (GdmUser *user);
guint gdm_user_get_num_sessions (GdmUser *user);
gboolean gdm_user_is_logged_in (GdmUser *user);
gulong gdm_user_get_login_frequency (GdmUser *user);
+G_CONST_RETURN char *gdm_user_get_icon_file (GdmUser *user);
G_CONST_RETURN char *gdm_user_get_primary_session_id (GdmUser *user);
GdkPixbuf *gdm_user_render_icon (GdmUser *user,
diff --git a/gui/user-switch-applet/applet.c b/gui/user-switch-applet/applet.c
index 72e77bd..c824eb1 100644
--- a/gui/user-switch-applet/applet.c
+++ b/gui/user-switch-applet/applet.c
@@ -791,9 +791,12 @@ on_account_activate (GtkMenuItem *item,
GdkScreen *screen;
gboolean res;
- args[0] = g_find_program_in_path ("gnome-about-me");
+ args[0] = g_find_program_in_path ("accounts-dialog");
if (args[0] == NULL) {
- return;
+ args[0] = g_find_program_in_path ("gnome-about-me");
+ if (args[0] == NULL) {
+ return;
+ }
}
args[1] = NULL;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]