diff options
-rw-r--r-- | doc/lightdm-gobject-0-sections.txt | 4 | ||||
-rw-r--r-- | doc/tmpl/greeter.sgml | 24 | ||||
-rw-r--r-- | liblightdm-gobject/greeter.c | 194 | ||||
-rw-r--r-- | liblightdm-gobject/lightdm/greeter.h | 5 | ||||
-rw-r--r-- | liblightdm-gobject/lightdm/user.h | 4 | ||||
-rw-r--r-- | liblightdm-gobject/user-private.h | 15 | ||||
-rw-r--r-- | liblightdm-gobject/user.c | 25 | ||||
-rw-r--r-- | src/lightdm.c | 75 | ||||
-rw-r--r-- | src/user-manager.c | 20 | ||||
-rw-r--r-- | src/user-manager.h | 2 |
10 files changed, 346 insertions, 22 deletions
diff --git a/doc/lightdm-gobject-0-sections.txt b/doc/lightdm-gobject-0-sections.txt index 6d7cc880..92d95907 100644 --- a/doc/lightdm-gobject-0-sections.txt +++ b/doc/lightdm-gobject-0-sections.txt @@ -67,6 +67,9 @@ LDM_USER_GET_CLASS LdmUserClass LdmUserPrivate ldm_user_new +ldm_user_set_image +ldm_user_set_logged_in +ldm_user_set_real_name </SECTION> <SECTION> @@ -103,6 +106,7 @@ ldm_greeter_get_integer_property ldm_greeter_get_boolean_property ldm_greeter_get_num_users ldm_greeter_get_users +ldm_greeter_get_user_by_name ldm_greeter_get_default_language ldm_greeter_get_languages ldm_greeter_get_default_layout diff --git a/doc/tmpl/greeter.sgml b/doc/tmpl/greeter.sgml index b61a072b..f8dcaf1f 100644 --- a/doc/tmpl/greeter.sgml +++ b/doc/tmpl/greeter.sgml @@ -133,6 +133,20 @@ g_object_connect (G_OBJECT (greeter), "quit", G_CALLBACK (quit_cb), NULL); @ldmgreeter: the object which received the signal. @arg1: +<!-- ##### SIGNAL LdmGreeter::user-added ##### --> +<para> + +</para> + +@ldmgreeter: the object which received the signal. + +<!-- ##### SIGNAL LdmGreeter::user-changed ##### --> +<para> + +</para> + +@ldmgreeter: the object which received the signal. + <!-- ##### ARG LdmGreeter:authentication-user ##### --> <para> @@ -282,6 +296,16 @@ g_object_connect (G_OBJECT (greeter), "quit", G_CALLBACK (quit_cb), NULL); @Returns: +<!-- ##### FUNCTION ldm_greeter_get_user_by_name ##### --> +<para> + +</para> + +@greeter: +@username: +@Returns: + + <!-- ##### FUNCTION ldm_greeter_get_default_language ##### --> <para> diff --git a/liblightdm-gobject/greeter.c b/liblightdm-gobject/greeter.c index f814fde0..230a57cf 100644 --- a/liblightdm-gobject/greeter.c +++ b/liblightdm-gobject/greeter.c @@ -19,6 +19,7 @@ #include <libxklavier/xklavier.h> #include "lightdm/greeter.h" +#include "user-private.h" #include "greeter-protocol.h" enum { @@ -49,6 +50,9 @@ enum { SHOW_ERROR, AUTHENTICATION_COMPLETE, TIMED_LOGIN, + USER_ADDED, + USER_CHANGED, + USER_REMOVED, QUIT, LAST_SIGNAL }; @@ -544,6 +548,98 @@ ldm_greeter_get_boolean_property (LdmGreeter *greeter, const gchar *name) return result; } +static LdmUser * +get_user_by_name (LdmGreeter *greeter, const gchar *username) +{ + GList *link; + + for (link = greeter->priv->users; link; link = link->next) + { + LdmUser *user = link->data; + if (strcmp (ldm_user_get_name (user), username) == 0) + return user; + } + + return NULL; +} + +static void +user_changed_cb (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + LdmGreeter *greeter = user_data; + gchar *username, *real_name, *image; + gboolean logged_in; + LdmUser *user; + + if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(sssb)"))) + { + g_warning ("Unknown type in %s signal", signal_name); + return; + } + + g_variant_get (parameters, "(sssb)", &username, &real_name, &image, &logged_in); + + user = get_user_by_name (greeter, username); + if (user) + { + g_debug ("User %s changed", username); + ldm_user_set_real_name (user, real_name); + ldm_user_set_image (user, image); + ldm_user_set_logged_in (user, logged_in); + g_signal_emit (greeter, signals[USER_ADDED], 0, user); + } + else + { + g_debug ("User %s added", username); + user = ldm_user_new (greeter, username, real_name, image, logged_in); + greeter->priv->users = g_list_append (greeter->priv->users, user); + g_signal_emit (greeter, signals[USER_ADDED], 0, user); + } + + g_free (username); + g_free (real_name); + g_free (image); +} + +static void +user_removed_cb (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + LdmGreeter *greeter = user_data; + gchar *username; + LdmUser *user; + + if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(s)"))) + { + g_warning ("Unknown type in %s signal", signal_name); + return; + } + + g_variant_get (parameters, "(s)", &username); + + user = get_user_by_name (greeter, username); + if (user) + { + g_debug ("User %s removed", username); + greeter->priv->users = g_list_remove (greeter->priv->users, user); + g_signal_emit (greeter, signals[USER_REMOVED], 0, user); + g_object_unref (user); + } + + g_free (username); +} + static void update_users (LdmGreeter *greeter) { @@ -556,6 +652,37 @@ update_users (LdmGreeter *greeter) if (greeter->priv->have_users) return; + g_dbus_connection_signal_subscribe (greeter->priv->lightdm_bus, + "org.lightdm.LightDisplayManager", + "org.lightdm.LightDisplayManager.Users", + "UserAdded", + "/org/lightdm/LightDisplayManager/Users", + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + user_changed_cb, + greeter, + NULL); + g_dbus_connection_signal_subscribe (greeter->priv->lightdm_bus, + "org.lightdm.LightDisplayManager", + "org.lightdm.LightDisplayManager.Users", + "UserChanged", + "/org/lightdm/LightDisplayManager/Users", + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + user_changed_cb, + greeter, + NULL); + g_dbus_connection_signal_subscribe (greeter->priv->lightdm_bus, + "org.lightdm.LightDisplayManager", + "org.lightdm.LightDisplayManager.Users", + "UserRemoved", + "/org/lightdm/LightDisplayManager/Users", + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + user_removed_cb, + greeter, + NULL); + g_debug ("Getting user list..."); result = g_dbus_proxy_call_sync (greeter->priv->user_proxy, "GetUsers", @@ -586,6 +713,7 @@ update_users (LdmGreeter *greeter) user = ldm_user_new (greeter, name, real_name, image, logged_in); greeter->priv->users = g_list_append (greeter->priv->users, user); } + greeter->priv->have_users = TRUE; g_variant_unref (result); @@ -622,6 +750,25 @@ ldm_greeter_get_users (LdmGreeter *greeter) return greeter->priv->users; } +/** + * ldm_greeter_get_user_by_name: + * @greeter: A #LdmGreeter + * @username: Name of user to get. + * + * Get infomation about a given user or NULL if this user doesn't exist. + * + * Return value: (allow-none): A #LdmUser entry for the given user. + **/ +const LdmUser * +ldm_greeter_get_user_by_name (LdmGreeter *greeter, const gchar *username) +{ + g_return_val_if_fail (LDM_IS_GREETER (greeter), NULL); + + update_users (greeter); + + return get_user_by_name (greeter, username); +} + static void update_languages (LdmGreeter *greeter) { @@ -1310,7 +1457,7 @@ ldm_greeter_shutdown (LdmGreeter *greeter) * @language: (out): Default language for this user. * @layout: (out): Default keyboard layout for this user. * @session: (out): Default session for this user. - * + * * Get the default settings for a given user. **/ gboolean @@ -1675,6 +1822,51 @@ ldm_greeter_class_init (LdmGreeterClass *klass) G_TYPE_NONE, 1, G_TYPE_STRING); /** + * LdmGreeter::user-added: + * @greeter: A #LdmGreeter + * + * The ::user-added signal gets emitted when a user account is created. + **/ + signals[USER_ADDED] = + g_signal_new ("user-added", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (LdmGreeterClass, user_added), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + /** + * LdmGreeter::user-changed: + * @greeter: A #LdmGreeter + * + * The ::user-changed signal gets emitted when a user account is modified. + **/ + signals[USER_CHANGED] = + g_signal_new ("user-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (LdmGreeterClass, user_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + /** + * LdmGreeter::user-removed: + * @greeter: A #LdmGreeter + * + * The ::user-removed signal gets emitted when a user account is removed. + **/ + signals[USER_REMOVED] = + g_signal_new ("user-added", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (LdmGreeterClass, user_removed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + /** * LdmGreeter::quit: * @greeter: A #LdmGreeter * diff --git a/liblightdm-gobject/lightdm/greeter.h b/liblightdm-gobject/lightdm/greeter.h index e75b5163..0d44d1e0 100644 --- a/liblightdm-gobject/lightdm/greeter.h +++ b/liblightdm-gobject/lightdm/greeter.h @@ -49,6 +49,9 @@ struct _LdmGreeterClass void (*show_error)(LdmGreeter *greeter, const gchar *text); void (*authentication_complete)(LdmGreeter *greeter); void (*timed_login)(LdmGreeter *greeter, const gchar *username); + void (*user_added)(LdmGreeter *greeter, LdmUser *user); + void (*user_changed)(LdmGreeter *greeter, LdmUser *user); + void (*user_removed)(LdmGreeter *greeter, LdmUser *user); void (*quit)(LdmGreeter *greeter); }; @@ -72,6 +75,8 @@ gint ldm_greeter_get_num_users (LdmGreeter *greeter); const GList *ldm_greeter_get_users (LdmGreeter *greeter); +const LdmUser *ldm_greeter_get_user_by_name (LdmGreeter *greeter, const gchar *username); + const gchar *ldm_greeter_get_default_language (LdmGreeter *greeter); const GList *ldm_greeter_get_languages (LdmGreeter *greeter); diff --git a/liblightdm-gobject/lightdm/user.h b/liblightdm-gobject/lightdm/user.h index b28ae151..053fb31b 100644 --- a/liblightdm-gobject/lightdm/user.h +++ b/liblightdm-gobject/lightdm/user.h @@ -14,8 +14,6 @@ #include <glib-object.h> -#include "greeter.h" - G_BEGIN_DECLS #define LDM_TYPE_USER (ldm_user_get_type()) @@ -43,8 +41,6 @@ struct _LdmUserClass GType ldm_user_get_type (void); -LdmUser *ldm_user_new (LdmGreeter *greeter, const gchar *name, const gchar *real_name, const gchar *image, gboolean logged_in); - const gchar *ldm_user_get_name (LdmUser *user); const gchar *ldm_user_get_real_name (LdmUser *user); diff --git a/liblightdm-gobject/user-private.h b/liblightdm-gobject/user-private.h new file mode 100644 index 00000000..2cdaa6ab --- /dev/null +++ b/liblightdm-gobject/user-private.h @@ -0,0 +1,15 @@ +#ifndef _LDM_USER_PRIVATE_H_ +#define _LDM_USER_PRIVATE_H_ + +#include "lightdm/greeter.h" +#include "lightdm/user.h" + +LdmUser *ldm_user_new (LdmGreeter *greeter, const gchar *name, const gchar *real_name, const gchar *image, gboolean logged_in); + +void ldm_user_set_real_name (LdmUser *user, const gchar *real_name); + +void ldm_user_set_image (LdmUser *user, const gchar *image); + +void ldm_user_set_logged_in (LdmUser *user, gboolean logged_in); + +#endif /* _LDM_USER_PRIVATE_H_ */ diff --git a/liblightdm-gobject/user.c b/liblightdm-gobject/user.c index b779b791..d8e36747 100644 --- a/liblightdm-gobject/user.c +++ b/liblightdm-gobject/user.c @@ -9,7 +9,7 @@ * license. */ -#include "lightdm/user.h" +#include "user-private.h" enum { PROP_0, @@ -89,6 +89,14 @@ ldm_user_get_real_name (LdmUser *user) return user->priv->real_name; } +void +ldm_user_set_real_name (LdmUser *user, const gchar *real_name) +{ + g_return_if_fail (LDM_IS_USER (user)); + g_free (user->priv->real_name); + user->priv->real_name = g_strdup (real_name); +} + /** * ldm_user_get_display_name: * @user: A #LdmUser @@ -123,6 +131,14 @@ ldm_user_get_image (LdmUser *user) return user->priv->image; } +void +ldm_user_set_image (LdmUser *user, const gchar *image) +{ + g_return_if_fail (LDM_IS_USER (user)); + g_free (user->priv->image); + user->priv->image = g_strdup (image); +} + static void get_defaults (LdmUser *user) { @@ -196,6 +212,13 @@ ldm_user_get_logged_in (LdmUser *user) return user->priv->logged_in; } +void +ldm_user_set_logged_in (LdmUser *user, gboolean logged_in) +{ + g_return_if_fail (LDM_IS_USER (user)); + user->priv->logged_in = logged_in; +} + static void ldm_user_init (LdmUser *user) { diff --git a/src/lightdm.c b/src/lightdm.c index ae363f55..e18ed063 100644 --- a/src/lightdm.c +++ b/src/lightdm.c @@ -33,6 +33,8 @@ static gboolean debug = FALSE; static UserManager *user_manager = NULL; static DisplayManager *display_manager = NULL; +static GDBusConnection *bus = NULL; + #define LDM_BUS_NAME "org.lightdm.LightDisplayManager" static void @@ -248,6 +250,16 @@ handle_display_manager_call (GDBusConnection *connection, } } +static GVariant * +user_info_to_args (UserInfo *info) +{ + return g_variant_new ("(sssb)", + info->name, + info->real_name ? info->real_name : "", + info->image ? info->image : "", + info->logged_in); +} + static void handle_user_manager_call (GDBusConnection *connection, const gchar *sender, @@ -272,11 +284,7 @@ handle_user_manager_call (GDBusConnection *connection, for (iter = users; iter; iter = iter->next) { UserInfo *info = iter->data; - g_variant_builder_add_value (builder, g_variant_new ("(sssb)", - info->name, - info->real_name ? info->real_name : "", - info->image ? info->image : "", - info->logged_in)); + g_variant_builder_add_value (builder, user_info_to_args (info)); } arg0 = g_variant_builder_end (builder); g_dbus_method_invocation_return_value (invocation, g_variant_new_tuple (&arg0, 1)); @@ -302,6 +310,42 @@ handle_user_manager_call (GDBusConnection *connection, } static void +user_added_cb (UserManager *user_manager, UserInfo *info) +{ + g_dbus_connection_emit_signal (bus, + NULL, + "/org/lightdm/LightDisplayManager/Users", + "org.lightdm.LightDisplayManager.Users", + "UserRemoved", + user_info_to_args (info), + NULL); +} + +static void +user_changed_cb (UserManager *user_manager, UserInfo *info) +{ + g_dbus_connection_emit_signal (bus, + NULL, + "/org/lightdm/LightDisplayManager/Users", + "org.lightdm.LightDisplayManager.Users", + "UserRemoved", + user_info_to_args (info), + NULL); +} + +static void +user_removed_cb (UserManager *user_manager, UserInfo *info) +{ + g_dbus_connection_emit_signal (bus, + NULL, + "/org/lightdm/LightDisplayManager/Users", + "org.lightdm.LightDisplayManager.Users", + "UserRemoved", + g_variant_new ("(s)", info->name), + NULL); +} + +static void bus_acquired_cb (GDBusConnection *connection, const gchar *name, gpointer user_data) @@ -332,6 +376,21 @@ bus_acquired_cb (GDBusConnection *connection, " <arg name='layout' direction='out' type='s'/>" " <arg name='session' direction='out' type='s'/>" " </method>" + " <signal name='UserAdded'>" + " <arg name='username' type='s'/>" + " <arg name='real-name' type='s'/>" + " <arg name='image' type='s'/>" + " <arg name='username' type='b'/>" + " </signal>" + " <signal name='UserChanged'>" + " <arg name='username' type='s'/>" + " <arg name='real-name' type='s'/>" + " <arg name='image' type='s'/>" + " <arg name='username' type='b'/>" + " </signal>" + " <signal name='UserRemoved'>" + " <arg name='username' type='s'/>" + " </signal>" " </interface>" "</node>"; static const GDBusInterfaceVTable user_manager_vtable = @@ -340,6 +399,8 @@ bus_acquired_cb (GDBusConnection *connection, }; GDBusNodeInfo *display_manager_info, *user_manager_info; + bus = connection; + display_manager_info = g_dbus_node_info_new_for_xml (display_manager_interface, NULL); g_assert (display_manager_info != NULL); g_dbus_connection_register_object (connection, @@ -357,6 +418,10 @@ bus_acquired_cb (GDBusConnection *connection, &user_manager_vtable, NULL, NULL, NULL); + + g_signal_connect (user_manager, "user-added", G_CALLBACK (user_added_cb), NULL); + g_signal_connect (user_manager, "user-changed", G_CALLBACK (user_changed_cb), NULL); + g_signal_connect (user_manager, "user-removed", G_CALLBACK (user_removed_cb), NULL); } static void diff --git a/src/user-manager.c b/src/user-manager.c index 3e72c4c4..71e201a5 100644 --- a/src/user-manager.c +++ b/src/user-manager.c @@ -18,7 +18,7 @@ enum { USER_ADDED, - USER_UPDATED, + USER_CHANGED, USER_REMOVED, LAST_SIGNAL }; @@ -68,7 +68,7 @@ load_users (UserManager *manager) gchar **hidden_users, **hidden_shells; gchar *value; gint minimum_uid; - GList *users = NULL, *old_users, *new_users = NULL, *updated_users = NULL, *link; + GList *users = NULL, *old_users, *new_users = NULL, *changed_users = NULL, *link; if (g_key_file_has_key (manager->priv->config, "UserManager", "minimum-uid", NULL)) minimum_uid = g_key_file_get_integer (manager->priv->config, "UserManager", "minimum-uid", NULL); @@ -168,7 +168,7 @@ load_users (UserManager *manager) info->logged_in = user->logged_in; g_free (user); user = info; - updated_users = g_list_insert_sorted (updated_users, user, compare_user); + changed_users = g_list_insert_sorted (changed_users, user, compare_user); } else { @@ -209,13 +209,13 @@ load_users (UserManager *manager) g_signal_emit (manager, signals[USER_ADDED], 0, info); } g_list_free (new_users); - for (link = updated_users; link; link = link->next) + for (link = changed_users; link; link = link->next) { UserInfo *info = link->data; - g_debug ("User %s updated", info->name); - g_signal_emit (manager, signals[USER_UPDATED], 0, info); + g_debug ("User %s changed", info->name); + g_signal_emit (manager, signals[USER_CHANGED], 0, info); } - g_list_free (updated_users); + g_list_free (changed_users); for (link = old_users; link; link = link->next) { GList *new_link; @@ -381,11 +381,11 @@ user_manager_class_init (UserManagerClass *klass) NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); - signals[USER_UPDATED] = - g_signal_new ("user-updated", + signals[USER_CHANGED] = + g_signal_new ("user-changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (UserManagerClass, user_updated), + G_STRUCT_OFFSET (UserManagerClass, user_changed), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); diff --git a/src/user-manager.h b/src/user-manager.h index 38091960..a7e5a8de 100644 --- a/src/user-manager.h +++ b/src/user-manager.h @@ -40,7 +40,7 @@ typedef struct { GObjectClass parent_class; void (*user_added)(UserManager *manager, UserInfo *user); - void (*user_updated)(UserManager *manager, UserInfo *user); + void (*user_changed)(UserManager *manager, UserInfo *user); void (*user_removed)(UserManager *manager, UserInfo *user); } UserManagerClass; |