summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/lightdm-gobject-0-sections.txt4
-rw-r--r--doc/tmpl/greeter.sgml24
-rw-r--r--liblightdm-gobject/greeter.c194
-rw-r--r--liblightdm-gobject/lightdm/greeter.h5
-rw-r--r--liblightdm-gobject/lightdm/user.h4
-rw-r--r--liblightdm-gobject/user-private.h15
-rw-r--r--liblightdm-gobject/user.c25
-rw-r--r--src/lightdm.c75
-rw-r--r--src/user-manager.c20
-rw-r--r--src/user-manager.h2
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;