1 /* -*- Mode: C; indent-tabs-mode:nil; tab-width:4 -*-
3 * Copyright (C) 2010 Robert Ancell.
4 * Copyright (C) 2014 Canonical, Ltd.
5 * Authors: Robert Ancell <robert.ancell@canonical.com>
6 * Michael Terry <michael.terry@canonical.com>
8 * This library is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU Lesser General Public License as published by the Free
10 * Software Foundation; either version 2 or version 3 of the License.
11 * See http://www.gnu.org/copyleft/lgpl.html the full text of the license.
16 #include "user-list.h"
17 #include "lightdm/user.h"
21 LIST_PROP_NUM_USERS = 1,
28 USER_PROP_COMMON_USER = 1,
31 USER_PROP_DISPLAY_NAME,
32 USER_PROP_HOME_DIRECTORY,
40 USER_PROP_HAS_MESSAGES,
51 static guint list_signals[LAST_LIST_SIGNAL] = { 0 };
58 static guint user_signals[LAST_USER_SIGNAL] = { 0 };
60 struct _LightDMUserList
62 GObject parent_instance;
66 /* Wrapper list, kept locally to preserve transfer-none promises */
70 G_DEFINE_TYPE (LightDMUserList, lightdm_user_list, G_TYPE_OBJECT);
74 GObject parent_instance;
76 CommonUser *common_user;
79 G_DEFINE_TYPE (LightDMUser, lightdm_user, G_TYPE_OBJECT);
81 static LightDMUserList *singleton = NULL;
84 * lightdm_user_list_get_instance:
88 * Return value: (transfer none): the #LightDMUserList
91 lightdm_user_list_get_instance (void)
94 singleton = g_object_new (LIGHTDM_TYPE_USER_LIST, NULL);
99 user_changed_cb (CommonUser *common_user, LightDMUser *lightdm_user)
101 g_signal_emit (lightdm_user, user_signals[CHANGED], 0);
105 wrap_common_user (CommonUser *user)
107 LightDMUser *lightdm_user = g_object_new (LIGHTDM_TYPE_USER, "common-user", user, NULL);
108 g_signal_connect (user, USER_SIGNAL_CHANGED, G_CALLBACK (user_changed_cb), lightdm_user);
113 user_list_added_cb (CommonUserList *common_list, CommonUser *common_user, LightDMUserList *user_list)
115 GList *common_users = common_user_list_get_users (common_list);
116 LightDMUser *lightdm_user = wrap_common_user (common_user);
117 user_list->lightdm_list = g_list_insert (user_list->lightdm_list, lightdm_user, g_list_index (common_users, common_user));
118 g_signal_emit (user_list, list_signals[USER_ADDED], 0, lightdm_user);
122 user_list_changed_cb (CommonUserList *common_list, CommonUser *common_user, LightDMUserList *user_list)
124 GList *common_users = common_user_list_get_users (common_list);
125 LightDMUser *lightdm_user = g_list_nth_data (user_list->lightdm_list, g_list_index (common_users, common_user));
126 g_signal_emit (user_list, list_signals[USER_CHANGED], 0, lightdm_user);
130 user_list_removed_cb (CommonUserList *common_list, CommonUser *common_user, LightDMUserList *user_list)
134 for (link = user_list->lightdm_list; link; link = link->next)
136 LightDMUser *lightdm_user = link->data;
137 if (lightdm_user->common_user == common_user)
139 user_list->lightdm_list = g_list_delete_link (user_list->lightdm_list, link);
140 g_signal_emit (user_list, list_signals[USER_REMOVED], 0, lightdm_user);
141 g_object_unref (lightdm_user);
148 initialize_user_list_if_needed (LightDMUserList *user_list)
153 if (user_list->initialized)
156 common_users = common_user_list_get_users (common_user_list_get_instance ());
157 for (link = common_users; link; link = link->next)
159 CommonUser *user = link->data;
160 LightDMUser *lightdm_user = wrap_common_user (user);
161 user_list->lightdm_list = g_list_prepend (user_list->lightdm_list, lightdm_user);
163 user_list->lightdm_list = g_list_reverse (user_list->lightdm_list);
165 CommonUserList *common_list = common_user_list_get_instance ();
166 g_signal_connect (common_list, USER_LIST_SIGNAL_USER_ADDED, G_CALLBACK (user_list_added_cb), user_list);
167 g_signal_connect (common_list, USER_LIST_SIGNAL_USER_CHANGED, G_CALLBACK (user_list_changed_cb), user_list);
168 g_signal_connect (common_list, USER_LIST_SIGNAL_USER_REMOVED, G_CALLBACK (user_list_removed_cb), user_list);
170 user_list->initialized = TRUE;
174 * lightdm_user_list_get_length:
175 * @user_list: a #LightDMUserList
177 * Return value: The number of users able to log in
180 lightdm_user_list_get_length (LightDMUserList *user_list)
182 g_return_val_if_fail (LIGHTDM_IS_USER_LIST (user_list), 0);
183 initialize_user_list_if_needed (user_list);
184 return g_list_length (user_list->lightdm_list);
188 * lightdm_user_list_get_users:
189 * @user_list: A #LightDMUserList
191 * Get a list of users to present to the user. This list may be a subset of the
192 * available users and may be empty depending on the server configuration.
194 * Return value: (element-type LightDMUser) (transfer none): A list of #LightDMUser that should be presented to the user.
197 lightdm_user_list_get_users (LightDMUserList *user_list)
199 g_return_val_if_fail (LIGHTDM_IS_USER_LIST (user_list), NULL);
200 initialize_user_list_if_needed (user_list);
201 return user_list->lightdm_list;
205 * lightdm_user_list_get_user_by_name:
206 * @user_list: A #LightDMUserList
207 * @username: Name of user to get.
209 * Get infomation about a given user or #NULL if this user doesn't exist.
211 * Return value: (transfer none): A #LightDMUser entry for the given user.
214 lightdm_user_list_get_user_by_name (LightDMUserList *user_list, const gchar *username)
218 g_return_val_if_fail (LIGHTDM_IS_USER_LIST (user_list), NULL);
219 g_return_val_if_fail (username != NULL, NULL);
221 initialize_user_list_if_needed (user_list);
223 for (link = user_list->lightdm_list; link; link = link->next)
225 LightDMUser *user = link->data;
226 if (g_strcmp0 (lightdm_user_get_name (user), username) == 0)
234 lightdm_user_list_init (LightDMUserList *user_list)
239 lightdm_user_list_set_property (GObject *object,
244 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
248 lightdm_user_list_get_property (GObject *object,
253 LightDMUserList *self;
255 self = LIGHTDM_USER_LIST (object);
259 case LIST_PROP_NUM_USERS:
260 case LIST_PROP_LENGTH:
261 g_value_set_int (value, lightdm_user_list_get_length (self));
264 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
270 lightdm_user_list_finalize (GObject *object)
272 LightDMUserList *self = LIGHTDM_USER_LIST (object);
274 g_list_free_full (self->lightdm_list, g_object_unref);
276 G_OBJECT_CLASS (lightdm_user_list_parent_class)->finalize (object);
280 lightdm_user_list_class_init (LightDMUserListClass *klass)
282 GObjectClass *object_class = G_OBJECT_CLASS (klass);
284 object_class->set_property = lightdm_user_list_set_property;
285 object_class->get_property = lightdm_user_list_get_property;
286 object_class->finalize = lightdm_user_list_finalize;
288 g_object_class_install_property (object_class,
290 g_param_spec_int ("num-users",
292 "Number of login users",
294 G_PARAM_DEPRECATED | G_PARAM_READABLE));
296 g_object_class_install_property (object_class,
298 g_param_spec_int ("length",
300 "Number of login users",
304 /*g_object_class_install_property (object_class,
306 g_param_spec_int ("users",
308 "Users to present to user",
310 G_PARAM_READABLE));*/
312 * LightDMUserList::user-added:
313 * @user_list: A #LightDMUserList
314 * @user: The #LightDM user that has been added.
316 * The ::user-added signal gets emitted when a user account is created.
318 list_signals[USER_ADDED] =
319 g_signal_new (LIGHTDM_USER_LIST_SIGNAL_USER_ADDED,
320 G_TYPE_FROM_CLASS (klass),
325 G_TYPE_NONE, 1, LIGHTDM_TYPE_USER);
328 * LightDMUserList::user-changed:
329 * @user_list: A #LightDMUserList
330 * @user: The #LightDM user that has been changed.
332 * The ::user-changed signal gets emitted when a user account is modified.
334 list_signals[USER_CHANGED] =
335 g_signal_new (LIGHTDM_USER_LIST_SIGNAL_USER_CHANGED,
336 G_TYPE_FROM_CLASS (klass),
341 G_TYPE_NONE, 1, LIGHTDM_TYPE_USER);
344 * LightDMUserList::user-removed:
345 * @user_list: A #LightDMUserList
346 * @user: The #LightDM user that has been removed.
348 * The ::user-removed signal gets emitted when a user account is removed.
350 list_signals[USER_REMOVED] =
351 g_signal_new (LIGHTDM_USER_LIST_SIGNAL_USER_REMOVED,
352 G_TYPE_FROM_CLASS (klass),
357 G_TYPE_NONE, 1, LIGHTDM_TYPE_USER);
361 * lightdm_user_get_name:
362 * @user: A #LightDMUser
364 * Get the name of a user.
366 * Return value: The name of the given user
369 lightdm_user_get_name (LightDMUser *user)
371 g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL);
372 return common_user_get_name (user->common_user);
376 * lightdm_user_get_real_name:
377 * @user: A #LightDMUser
379 * Get the real name of a user.
381 * Return value: The real name of the given user
384 lightdm_user_get_real_name (LightDMUser *user)
386 g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL);
387 return common_user_get_real_name (user->common_user);
391 * lightdm_user_get_display_name:
392 * @user: A #LightDMUser
394 * Get the display name of a user.
396 * Return value: The display name of the given user
399 lightdm_user_get_display_name (LightDMUser *user)
401 g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL);
402 return common_user_get_display_name (user->common_user);
406 * lightdm_user_get_home_directory:
407 * @user: A #LightDMUser
409 * Get the home directory for a user.
411 * Return value: The users home directory
414 lightdm_user_get_home_directory (LightDMUser *user)
416 g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL);
417 return common_user_get_home_directory (user->common_user);
421 * lightdm_user_get_image:
422 * @user: A #LightDMUser
424 * Get the image URI for a user.
426 * Return value: (nullable): The image URI for the given user or #NULL if no URI
429 lightdm_user_get_image (LightDMUser *user)
431 g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL);
432 return common_user_get_image (user->common_user);
436 * lightdm_user_get_background:
437 * @user: A #LightDMUser
439 * Get the background file path for a user.
441 * Return value: (nullable): The background file path for the given user or #NULL if no path
444 lightdm_user_get_background (LightDMUser *user)
446 g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL);
447 return common_user_get_background (user->common_user);
451 * lightdm_user_get_language:
452 * @user: A #LightDMUser
454 * Get the language for a user.
456 * Return value: (nullable): The language in the form of a local specification (e.g. "de_DE.UTF-8") for the given user or #NULL if using the system default locale.
459 lightdm_user_get_language (LightDMUser *user)
461 g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL);
462 return common_user_get_language (user->common_user);
466 * lightdm_user_get_layout:
467 * @user: A #LightDMUser
469 * Get the keyboard layout for a user.
471 * Return value: (nullable): The keyboard layout for the given user or #NULL if using system defaults. Copy the value if you want to use it long term.
474 lightdm_user_get_layout (LightDMUser *user)
476 g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL);
477 return common_user_get_layout (user->common_user);
481 * lightdm_user_get_layouts:
482 * @user: A #LightDMUser
484 * Get the configured keyboard layouts for a user.
486 * Return value: (transfer none): A NULL-terminated array of keyboard layouts for the given user. Copy the values if you want to use them long term.
488 const gchar * const *
489 lightdm_user_get_layouts (LightDMUser *user)
491 g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL);
492 return common_user_get_layouts (user->common_user);
496 * lightdm_user_get_session:
497 * @user: A #LightDMUser
499 * Get the session for a user.
501 * Return value: (nullable): The session for the given user or #NULL if using system defaults.
504 lightdm_user_get_session (LightDMUser *user)
506 g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL);
507 return common_user_get_session (user->common_user);
511 * lightdm_user_get_logged_in:
512 * @user: A #LightDMUser
514 * Check if a user is logged in.
516 * Return value: #TRUE if the user is currently logged in.
519 lightdm_user_get_logged_in (LightDMUser *user)
521 g_return_val_if_fail (LIGHTDM_IS_USER (user), FALSE);
522 return common_user_get_logged_in (user->common_user);
526 * lightdm_user_get_has_messages:
527 * @user: A #LightDMUser
529 * Check if a user has waiting messages.
531 * Return value: #TRUE if the user has waiting messages.
534 lightdm_user_get_has_messages (LightDMUser *user)
536 g_return_val_if_fail (LIGHTDM_IS_USER (user), FALSE);
537 return common_user_get_has_messages (user->common_user);
541 * lightdm_user_get_uid:
542 * @user: A #LightDMUser
544 * Get the uid of a user.
546 * Return value: The uid of the given user
549 lightdm_user_get_uid (LightDMUser *user)
551 g_return_val_if_fail (LIGHTDM_IS_USER (user), (uid_t)-1);
552 return common_user_get_uid (user->common_user);
556 lightdm_user_init (LightDMUser *user)
561 lightdm_user_set_property (GObject *object,
566 LightDMUser *self = LIGHTDM_USER (object);
570 case USER_PROP_COMMON_USER:
571 self->common_user = g_value_dup_object (value);
574 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
580 lightdm_user_get_property (GObject *object,
587 self = LIGHTDM_USER (object);
592 g_value_set_string (value, lightdm_user_get_name (self));
594 case USER_PROP_REAL_NAME:
595 g_value_set_string (value, lightdm_user_get_real_name (self));
597 case USER_PROP_DISPLAY_NAME:
598 g_value_set_string (value, lightdm_user_get_display_name (self));
600 case USER_PROP_HOME_DIRECTORY:
601 g_value_set_string (value, lightdm_user_get_home_directory (self));
603 case USER_PROP_IMAGE:
604 g_value_set_string (value, lightdm_user_get_image (self));
606 case USER_PROP_BACKGROUND:
607 g_value_set_string (value, lightdm_user_get_background (self));
609 case USER_PROP_LANGUAGE:
610 g_value_set_string (value, lightdm_user_get_language (self));
612 case USER_PROP_LAYOUT:
613 g_value_set_string (value, lightdm_user_get_layout (self));
615 case USER_PROP_LAYOUTS:
616 g_value_set_boxed (value, g_strdupv ((gchar **) lightdm_user_get_layouts (self)));
618 case USER_PROP_SESSION:
619 g_value_set_string (value, lightdm_user_get_session (self));
621 case USER_PROP_LOGGED_IN:
622 g_value_set_boolean (value, lightdm_user_get_logged_in (self));
624 case USER_PROP_HAS_MESSAGES:
625 g_value_set_boolean (value, lightdm_user_get_has_messages (self));
628 g_value_set_uint64 (value, lightdm_user_get_uid (self));
631 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
637 lightdm_user_finalize (GObject *object)
639 LightDMUser *self = LIGHTDM_USER (object);
641 g_object_unref (self->common_user);
643 G_OBJECT_CLASS (lightdm_user_parent_class)->finalize (object);
647 lightdm_user_class_init (LightDMUserClass *klass)
649 GObjectClass *object_class = G_OBJECT_CLASS (klass);
651 object_class->set_property = lightdm_user_set_property;
652 object_class->get_property = lightdm_user_get_property;
653 object_class->finalize = lightdm_user_finalize;
655 g_object_class_install_property (object_class,
656 USER_PROP_COMMON_USER,
657 g_param_spec_object ("common-user",
659 "Internal user object",
661 G_PARAM_PRIVATE|G_PARAM_CONSTRUCT_ONLY|G_PARAM_WRITABLE));
662 g_object_class_install_property (object_class,
664 g_param_spec_string ("name",
669 g_object_class_install_property (object_class,
671 g_param_spec_string ("real-name",
676 g_object_class_install_property (object_class,
677 USER_PROP_DISPLAY_NAME,
678 g_param_spec_string ("display-name",
680 "Users display name",
683 g_object_class_install_property (object_class,
684 USER_PROP_HOME_DIRECTORY,
685 g_param_spec_string ("home-directory",
690 g_object_class_install_property (object_class,
692 g_param_spec_string ("image",
697 g_object_class_install_property (object_class,
698 USER_PROP_BACKGROUND,
699 g_param_spec_string ("background",
704 g_object_class_install_property (object_class,
706 g_param_spec_string ("language",
708 "Language used by this user",
711 g_object_class_install_property (object_class,
713 g_param_spec_string ("layout",
715 "Keyboard layout used by this user",
718 g_object_class_install_property (object_class,
720 g_param_spec_boxed ("layouts",
722 "Keyboard layouts used by this user",
725 g_object_class_install_property (object_class,
727 g_param_spec_string ("session",
729 "Session used by this user",
732 g_object_class_install_property (object_class,
734 g_param_spec_boolean ("logged-in",
736 "TRUE if the user is currently in a session",
739 g_object_class_install_property (object_class,
741 g_param_spec_boolean ("has-messages",
743 "TRUE if the user is has waiting messages",
746 g_object_class_install_property (object_class,
748 g_param_spec_uint64 ("uid",
755 * LightDMUser::changed:
756 * @user: A #LightDMUser
758 * The ::changed signal gets emitted when this user account is modified.
760 user_signals[CHANGED] =
761 g_signal_new (LIGHTDM_SIGNAL_USER_CHANGED,
762 G_TYPE_FROM_CLASS (klass),