LdmUserClass
LdmUserPrivate
ldm_user_new
+ldm_user_set_image
+ldm_user_set_logged_in
+ldm_user_set_real_name
</SECTION>
<SECTION>
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
@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>
@Returns:
+<!-- ##### FUNCTION ldm_greeter_get_user_by_name ##### -->
+<para>
+
+</para>
+
+@greeter:
+@username:
+@Returns:
+
+
<!-- ##### FUNCTION ldm_greeter_get_default_language ##### -->
<para>
#include <libxklavier/xklavier.h>
#include "lightdm/greeter.h"
+#include "user-private.h"
#include "greeter-protocol.h"
enum {
SHOW_ERROR,
AUTHENTICATION_COMPLETE,
TIMED_LOGIN,
+ USER_ADDED,
+ USER_CHANGED,
+ USER_REMOVED,
QUIT,
LAST_SIGNAL
};
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)
{
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",
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);
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)
{
* @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
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
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);
};
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);
#include <glib-object.h>
-#include "greeter.h"
-
G_BEGIN_DECLS
#define LDM_TYPE_USER (ldm_user_get_type())
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);
--- /dev/null
+#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_ */
* license.
*/
-#include "lightdm/user.h"
+#include "user-private.h"
enum {
PROP_0,
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
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)
{
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)
{
static UserManager *user_manager = NULL;
static DisplayManager *display_manager = NULL;
+static GDBusConnection *bus = NULL;
+
#define LDM_BUS_NAME "org.lightdm.LightDisplayManager"
static void
}
}
+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,
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));
}
}
+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,
" <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 =
};
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,
&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
enum {
USER_ADDED,
- USER_UPDATED,
+ USER_CHANGED,
USER_REMOVED,
LAST_SIGNAL
};
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);
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
{
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;
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);
{
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;