]> rtime.felk.cvut.cz Git - sojka/lightdm.git/commitdiff
Start liblightdm-gobject understanding user changes
authorRobert Ancell <robert.ancell@canonical.com>
Tue, 3 May 2011 10:58:05 +0000 (20:58 +1000)
committerRobert Ancell <robert.ancell@canonical.com>
Tue, 3 May 2011 10:58:05 +0000 (20:58 +1000)
doc/lightdm-gobject-0-sections.txt
doc/tmpl/greeter.sgml
liblightdm-gobject/greeter.c
liblightdm-gobject/lightdm/greeter.h
liblightdm-gobject/lightdm/user.h
liblightdm-gobject/user-private.h [new file with mode: 0644]
liblightdm-gobject/user.c
src/lightdm.c
src/user-manager.c
src/user-manager.h

index 6d7cc8800171e171c3bf7a9adab276bfbbf93864..92d95907bd6c0c57404846233e42cea66fedc3c9 100644 (file)
@@ -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
index b61a072bb919296a5d80aa0f018d96fd34471abd..f8dcaf1f05b83badfe05d6fab27b4d0fc0cfa4fb 100644 (file)
@@ -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>
 
index f814fde05d56bd1fc94c7725db581b98da199621..230a57cf8ebc8a1c622eee3cd3fd2e20789233f5 100644 (file)
@@ -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
@@ -1674,6 +1821,51 @@ ldm_greeter_class_init (LdmGreeterClass *klass)
                       g_cclosure_marshal_VOID__STRING,
                       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
index e75b51633dea4879cc67366e61b6ab1f3e5e1bc0..0d44d1e031131d0c732b219033fbf5a35767a4ca 100644 (file)
@@ -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);
index b28ae1517de437a69d0fecfd80db2e892ff3eb52..053fb31bdbe9b3c4b6ff353bf8c95f76e27ab4fb 100644 (file)
@@ -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 (file)
index 0000000..2cdaa6a
--- /dev/null
@@ -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_ */
index b779b7910ee64afff92d45248fa37266769b6a52..d8e367471bf0c842651ca3665b8eb7e9eff69232 100644 (file)
@@ -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)
 {
index ae363f55d982d10c9a51d6461989ea4db2fb2462..e18ed063f9bdf9d671634f8a1d2896c6ca732a7c 100644 (file)
@@ -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));
@@ -301,6 +309,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,
@@ -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
index 3e72c4c4fe0285ea849255ab337e5a985f6d82a1..71e201a52ccfd021907d6e30d098bd343daf8f92 100644 (file)
@@ -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);
index 38091960906abbf86e6d6592fc465e9fba95b4c7..a7e5a8deb924b2d5ffe99017d47835615517c590 100644 (file)
@@ -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;