]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blob - liblightdm-gobject/user.c
GObject property coding style fixes
[sojka/lightdm.git] / liblightdm-gobject / user.c
1 /* -*- Mode: C; indent-tabs-mode:nil; tab-width:4 -*-
2  *
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>
7  *
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.
12  */
13
14 #include <config.h>
15
16 #include "user-list.h"
17 #include "lightdm/user.h"
18
19 enum
20 {
21     LIST_PROP_NUM_USERS = 1,
22     LIST_PROP_LENGTH,  
23     LIST_PROP_USERS,
24 };
25
26 enum
27 {
28     USER_PROP_COMMON_USER = 1,
29     USER_PROP_NAME,
30     USER_PROP_REAL_NAME,
31     USER_PROP_DISPLAY_NAME,
32     USER_PROP_HOME_DIRECTORY,
33     USER_PROP_IMAGE,
34     USER_PROP_BACKGROUND,
35     USER_PROP_LANGUAGE,
36     USER_PROP_LAYOUT,
37     USER_PROP_LAYOUTS,
38     USER_PROP_SESSION,
39     USER_PROP_LOGGED_IN,
40     USER_PROP_HAS_MESSAGES,
41     USER_PROP_UID,
42 };
43
44 enum
45 {
46     USER_ADDED,
47     USER_CHANGED,
48     USER_REMOVED,
49     LAST_LIST_SIGNAL
50 };
51 static guint list_signals[LAST_LIST_SIGNAL] = { 0 };
52
53 enum
54 {
55     CHANGED,
56     LAST_USER_SIGNAL
57 };
58 static guint user_signals[LAST_USER_SIGNAL] = { 0 };
59
60 typedef struct
61 {
62     gboolean initialized;
63
64     /* Wrapper list, kept locally to preserve transfer-none promises */
65     GList *lightdm_list;
66 } LightDMUserListPrivate;
67
68 typedef struct
69 {
70     CommonUser *common_user;
71 } LightDMUserPrivate;
72
73 G_DEFINE_TYPE (LightDMUserList, lightdm_user_list, G_TYPE_OBJECT);
74 G_DEFINE_TYPE (LightDMUser, lightdm_user, G_TYPE_OBJECT);
75
76 #define GET_LIST_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), LIGHTDM_TYPE_USER_LIST, LightDMUserListPrivate)
77 #define GET_USER_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), LIGHTDM_TYPE_USER, LightDMUserPrivate)
78
79 static LightDMUserList *singleton = NULL;
80
81 /**
82  * lightdm_user_list_get_instance:
83  *
84  * Get the user list.
85  *
86  * Return value: (transfer none): the #LightDMUserList
87  **/
88 LightDMUserList *
89 lightdm_user_list_get_instance (void)
90 {
91     if (!singleton)
92         singleton = g_object_new (LIGHTDM_TYPE_USER_LIST, NULL);
93     return singleton;
94 }
95
96 static void
97 user_changed_cb (CommonUser *common_user, LightDMUser *lightdm_user)
98 {
99     g_signal_emit (lightdm_user, user_signals[CHANGED], 0);
100 }
101
102 static LightDMUser *
103 wrap_common_user (CommonUser *user)
104 {
105     LightDMUser *lightdm_user = g_object_new (LIGHTDM_TYPE_USER, "common-user", user, NULL);
106     g_signal_connect (user, USER_SIGNAL_CHANGED, G_CALLBACK (user_changed_cb), lightdm_user);
107     return lightdm_user;
108 }
109
110 static void
111 user_list_added_cb (CommonUserList *common_list, CommonUser *common_user, LightDMUserList *user_list)
112 {
113     LightDMUserListPrivate *priv = GET_LIST_PRIVATE (user_list);
114     GList *common_users = common_user_list_get_users (common_list);
115     LightDMUser *lightdm_user = wrap_common_user (common_user);
116     priv->lightdm_list = g_list_insert (priv->lightdm_list, lightdm_user, g_list_index (common_users, common_user));
117     g_signal_emit (user_list, list_signals[USER_ADDED], 0, lightdm_user);
118 }
119
120 static void
121 user_list_changed_cb (CommonUserList *common_list, CommonUser *common_user, LightDMUserList *user_list)
122 {
123     LightDMUserListPrivate *priv = GET_LIST_PRIVATE (user_list);
124     GList *common_users = common_user_list_get_users (common_list);
125     LightDMUser *lightdm_user = g_list_nth_data (priv->lightdm_list, g_list_index (common_users, common_user));
126     g_signal_emit (user_list, list_signals[USER_CHANGED], 0, lightdm_user);
127 }
128
129 static void
130 user_list_removed_cb (CommonUserList *common_list, CommonUser *common_user, LightDMUserList *user_list)
131 {
132     LightDMUserListPrivate *priv = GET_LIST_PRIVATE (user_list);
133     GList *link;
134
135     for (link = priv->lightdm_list; link; link = link->next)
136     {
137         LightDMUser *lightdm_user = link->data;
138         LightDMUserPrivate *user_priv = GET_USER_PRIVATE (lightdm_user);
139         if (user_priv->common_user == common_user)
140         {
141             priv->lightdm_list = g_list_delete_link (priv->lightdm_list, link);
142             g_signal_emit (user_list, list_signals[USER_REMOVED], 0, lightdm_user);
143             g_object_unref (lightdm_user);
144             break;
145         }
146     }
147 }
148
149 static void
150 initialize_user_list_if_needed (LightDMUserList *user_list)
151 {
152     LightDMUserListPrivate *priv = GET_LIST_PRIVATE (user_list);
153     GList *common_users;
154     GList *link;
155
156     if (priv->initialized)
157         return;
158
159     common_users = common_user_list_get_users (common_user_list_get_instance ());
160     for (link = common_users; link; link = link->next)
161     {
162         CommonUser *user = link->data;
163         LightDMUser *lightdm_user = wrap_common_user (user);
164         priv->lightdm_list = g_list_prepend (priv->lightdm_list, lightdm_user);
165     }
166     priv->lightdm_list = g_list_reverse (priv->lightdm_list);
167
168     CommonUserList *common_list = common_user_list_get_instance ();
169     g_signal_connect (common_list, USER_LIST_SIGNAL_USER_ADDED, G_CALLBACK (user_list_added_cb), user_list);
170     g_signal_connect (common_list, USER_LIST_SIGNAL_USER_CHANGED, G_CALLBACK (user_list_changed_cb), user_list);
171     g_signal_connect (common_list, USER_LIST_SIGNAL_USER_REMOVED, G_CALLBACK (user_list_removed_cb), user_list);
172
173     priv->initialized = TRUE;
174 }
175
176 /**
177  * lightdm_user_list_get_length:
178  * @user_list: a #LightDMUserList
179  *
180  * Return value: The number of users able to log in
181  **/
182 gint
183 lightdm_user_list_get_length (LightDMUserList *user_list)
184 {
185     g_return_val_if_fail (LIGHTDM_IS_USER_LIST (user_list), 0);
186     initialize_user_list_if_needed (user_list);
187     return g_list_length (GET_LIST_PRIVATE (user_list)->lightdm_list);
188 }
189
190 /**
191  * lightdm_user_list_get_users:
192  * @user_list: A #LightDMUserList
193  *
194  * Get a list of users to present to the user.  This list may be a subset of the
195  * available users and may be empty depending on the server configuration.
196  *
197  * Return value: (element-type LightDMUser) (transfer none): A list of #LightDMUser that should be presented to the user.
198  **/
199 GList *
200 lightdm_user_list_get_users (LightDMUserList *user_list)
201 {
202     g_return_val_if_fail (LIGHTDM_IS_USER_LIST (user_list), NULL);
203     initialize_user_list_if_needed (user_list);
204     return GET_LIST_PRIVATE (user_list)->lightdm_list;
205 }
206
207 /**
208  * lightdm_user_list_get_user_by_name:
209  * @user_list: A #LightDMUserList
210  * @username: Name of user to get.
211  *
212  * Get infomation about a given user or #NULL if this user doesn't exist.
213  *
214  * Return value: (transfer none): A #LightDMUser entry for the given user.
215  **/
216 LightDMUser *
217 lightdm_user_list_get_user_by_name (LightDMUserList *user_list, const gchar *username)
218 {
219     GList *link;
220
221     g_return_val_if_fail (LIGHTDM_IS_USER_LIST (user_list), NULL);
222     g_return_val_if_fail (username != NULL, NULL);
223
224     initialize_user_list_if_needed (user_list);
225
226     for (link = GET_LIST_PRIVATE (user_list)->lightdm_list; link; link = link->next)
227     {
228         LightDMUser *user = link->data;
229         if (g_strcmp0 (lightdm_user_get_name (user), username) == 0)
230             return user;
231     }
232
233     return NULL;
234 }
235
236 static void
237 lightdm_user_list_init (LightDMUserList *user_list)
238 {
239 }
240
241 static void
242 lightdm_user_list_set_property (GObject      *object,
243                                 guint         prop_id,
244                                 const GValue *value,
245                                 GParamSpec   *pspec)
246 {
247     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
248 }
249
250 static void
251 lightdm_user_list_get_property (GObject    *object,
252                                 guint       prop_id,
253                                 GValue     *value,
254                                 GParamSpec *pspec)
255 {
256     LightDMUserList *self;
257
258     self = LIGHTDM_USER_LIST (object);
259
260     switch (prop_id)
261     {
262     case LIST_PROP_NUM_USERS:
263     case LIST_PROP_LENGTH:      
264         g_value_set_int (value, lightdm_user_list_get_length (self));
265         break;
266     default:
267         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
268         break;
269     }
270 }
271
272 static void
273 lightdm_user_list_finalize (GObject *object)
274 {
275     LightDMUserList *self = LIGHTDM_USER_LIST (object);
276     LightDMUserListPrivate *priv = GET_LIST_PRIVATE (self);
277
278     g_list_free_full (priv->lightdm_list, g_object_unref);
279
280     G_OBJECT_CLASS (lightdm_user_list_parent_class)->finalize (object);
281 }
282
283 static void
284 lightdm_user_list_class_init (LightDMUserListClass *klass)
285 {
286     GObjectClass *object_class = G_OBJECT_CLASS (klass);
287
288     g_type_class_add_private (klass, sizeof (LightDMUserListPrivate));
289
290     object_class->set_property = lightdm_user_list_set_property;
291     object_class->get_property = lightdm_user_list_get_property;
292     object_class->finalize = lightdm_user_list_finalize;
293
294     g_object_class_install_property (object_class,
295                                      LIST_PROP_NUM_USERS,
296                                      g_param_spec_int ("num-users",
297                                                        "num-users",
298                                                        "Number of login users",
299                                                        0, G_MAXINT, 0,
300                                                        G_PARAM_DEPRECATED | G_PARAM_READABLE));
301
302     g_object_class_install_property (object_class,
303                                      LIST_PROP_LENGTH,
304                                      g_param_spec_int ("length",
305                                                        "length",
306                                                        "Number of login users",
307                                                        0, G_MAXINT, 0,
308                                                        G_PARAM_READABLE));
309
310     /*g_object_class_install_property (object_class,
311                                      LIST_PROP_USERS,
312                                      g_param_spec_int ("users",
313                                                        "users",
314                                                        "Users to present to user",
315                                                        0, G_MAXINT, 0,
316                                                        G_PARAM_READABLE));*/
317     /**
318      * LightDMUserList::user-added:
319      * @user_list: A #LightDMUserList
320      * @user: The #LightDM user that has been added.
321      *
322      * The ::user-added signal gets emitted when a user account is created.
323      **/
324     list_signals[USER_ADDED] =
325         g_signal_new (LIGHTDM_USER_LIST_SIGNAL_USER_ADDED,
326                       G_TYPE_FROM_CLASS (klass),
327                       G_SIGNAL_RUN_LAST,
328                       G_STRUCT_OFFSET (LightDMUserListClass, user_added),
329                       NULL, NULL,
330                       NULL,
331                       G_TYPE_NONE, 1, LIGHTDM_TYPE_USER);
332
333     /**
334      * LightDMUserList::user-changed:
335      * @user_list: A #LightDMUserList
336      * @user: The #LightDM user that has been changed.
337      *
338      * The ::user-changed signal gets emitted when a user account is modified.
339      **/
340     list_signals[USER_CHANGED] =
341         g_signal_new (LIGHTDM_USER_LIST_SIGNAL_USER_CHANGED,
342                       G_TYPE_FROM_CLASS (klass),
343                       G_SIGNAL_RUN_LAST,
344                       G_STRUCT_OFFSET (LightDMUserListClass, user_changed),
345                       NULL, NULL,
346                       NULL,
347                       G_TYPE_NONE, 1, LIGHTDM_TYPE_USER);
348
349     /**
350      * LightDMUserList::user-removed:
351      * @user_list: A #LightDMUserList
352      * @user: The #LightDM user that has been removed.
353      *
354      * The ::user-removed signal gets emitted when a user account is removed.
355      **/
356     list_signals[USER_REMOVED] =
357         g_signal_new (LIGHTDM_USER_LIST_SIGNAL_USER_REMOVED,
358                       G_TYPE_FROM_CLASS (klass),
359                       G_SIGNAL_RUN_LAST,
360                       G_STRUCT_OFFSET (LightDMUserListClass, user_removed),
361                       NULL, NULL,
362                       NULL,
363                       G_TYPE_NONE, 1, LIGHTDM_TYPE_USER);
364 }
365
366 /**
367  * lightdm_user_get_name:
368  * @user: A #LightDMUser
369  *
370  * Get the name of a user.
371  *
372  * Return value: The name of the given user
373  **/
374 const gchar *
375 lightdm_user_get_name (LightDMUser *user)
376 {
377     g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL);
378     return common_user_get_name (GET_USER_PRIVATE (user)->common_user);
379 }
380
381 /**
382  * lightdm_user_get_real_name:
383  * @user: A #LightDMUser
384  *
385  * Get the real name of a user.
386  *
387  * Return value: The real name of the given user
388  **/
389 const gchar *
390 lightdm_user_get_real_name (LightDMUser *user)
391 {
392     g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL);
393     return common_user_get_real_name (GET_USER_PRIVATE (user)->common_user);
394 }
395
396 /**
397  * lightdm_user_get_display_name:
398  * @user: A #LightDMUser
399  *
400  * Get the display name of a user.
401  *
402  * Return value: The display name of the given user
403  **/
404 const gchar *
405 lightdm_user_get_display_name (LightDMUser *user)
406 {
407     g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL);
408     return common_user_get_display_name (GET_USER_PRIVATE (user)->common_user);
409 }
410
411 /**
412  * lightdm_user_get_home_directory:
413  * @user: A #LightDMUser
414  *
415  * Get the home directory for a user.
416  *
417  * Return value: The users home directory
418  */
419 const gchar *
420 lightdm_user_get_home_directory (LightDMUser *user)
421 {
422     g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL);
423     return common_user_get_home_directory (GET_USER_PRIVATE (user)->common_user);
424 }
425
426 /**
427  * lightdm_user_get_image:
428  * @user: A #LightDMUser
429  *
430  * Get the image URI for a user.
431  *
432  * Return value: (nullable): The image URI for the given user or #NULL if no URI
433  **/
434 const gchar *
435 lightdm_user_get_image (LightDMUser *user)
436 {
437     g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL);
438     return common_user_get_image (GET_USER_PRIVATE (user)->common_user);
439 }
440
441 /**
442  * lightdm_user_get_background:
443  * @user: A #LightDMUser
444  *
445  * Get the background file path for a user.
446  *
447  * Return value: (nullable): The background file path for the given user or #NULL if no path
448  **/
449 const gchar *
450 lightdm_user_get_background (LightDMUser *user)
451 {
452     g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL);
453     return common_user_get_background (GET_USER_PRIVATE (user)->common_user);
454 }
455
456 /**
457  * lightdm_user_get_language:
458  * @user: A #LightDMUser
459  *
460  * Get the language for a user.
461  *
462  * 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.
463  **/
464 const gchar *
465 lightdm_user_get_language (LightDMUser *user)
466 {
467     g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL);
468     return common_user_get_language (GET_USER_PRIVATE (user)->common_user);
469 }
470
471 /**
472  * lightdm_user_get_layout:
473  * @user: A #LightDMUser
474  *
475  * Get the keyboard layout for a user.
476  *
477  * 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.
478  **/
479 const gchar *
480 lightdm_user_get_layout (LightDMUser *user)
481 {
482     g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL);
483     return common_user_get_layout (GET_USER_PRIVATE (user)->common_user);
484 }
485
486 /**
487  * lightdm_user_get_layouts:
488  * @user: A #LightDMUser
489  *
490  * Get the configured keyboard layouts for a user.
491  *
492  * 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.
493  **/
494 const gchar * const *
495 lightdm_user_get_layouts (LightDMUser *user)
496 {
497     g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL);
498     return common_user_get_layouts (GET_USER_PRIVATE (user)->common_user);
499 }
500
501 /**
502  * lightdm_user_get_session:
503  * @user: A #LightDMUser
504  *
505  * Get the session for a user.
506  *
507  * Return value: (nullable): The session for the given user or #NULL if using system defaults.
508  **/
509 const gchar *
510 lightdm_user_get_session (LightDMUser *user)
511 {
512     g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL);
513     return common_user_get_session (GET_USER_PRIVATE (user)->common_user);
514 }
515
516 /**
517  * lightdm_user_get_logged_in:
518  * @user: A #LightDMUser
519  *
520  * Check if a user is logged in.
521  *
522  * Return value: #TRUE if the user is currently logged in.
523  **/
524 gboolean
525 lightdm_user_get_logged_in (LightDMUser *user)
526 {
527     g_return_val_if_fail (LIGHTDM_IS_USER (user), FALSE);
528     return common_user_get_logged_in (GET_USER_PRIVATE (user)->common_user);
529 }
530
531 /**
532  * lightdm_user_get_has_messages:
533  * @user: A #LightDMUser
534  *
535  * Check if a user has waiting messages.
536  *
537  * Return value: #TRUE if the user has waiting messages.
538  **/
539 gboolean
540 lightdm_user_get_has_messages (LightDMUser *user)
541 {
542     g_return_val_if_fail (LIGHTDM_IS_USER (user), FALSE);
543     return common_user_get_has_messages (GET_USER_PRIVATE (user)->common_user);
544 }
545
546 /**
547  * lightdm_user_get_uid:
548  * @user: A #LightDMUser
549  *
550  * Get the uid of a user.
551  *
552  * Return value: The uid of the given user
553  **/
554 uid_t
555 lightdm_user_get_uid (LightDMUser *user)
556 {
557     g_return_val_if_fail (LIGHTDM_IS_USER (user), (uid_t)-1);
558     return common_user_get_uid (GET_USER_PRIVATE (user)->common_user);
559 }
560
561 static void
562 lightdm_user_init (LightDMUser *user)
563 {
564 }
565
566 static void
567 lightdm_user_set_property (GObject    *object,
568                            guint       prop_id,
569                            const GValue *value,
570                            GParamSpec *pspec)
571 {
572     LightDMUser *self = LIGHTDM_USER (object);
573     LightDMUserPrivate *priv = GET_USER_PRIVATE (self);
574
575     switch (prop_id)
576     {
577     case USER_PROP_COMMON_USER:
578         priv->common_user = g_value_dup_object (value);
579         break;
580     default:
581         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
582         break;
583     }
584 }
585
586 static void
587 lightdm_user_get_property (GObject    *object,
588                            guint       prop_id,
589                            GValue     *value,
590                            GParamSpec *pspec)
591 {
592     LightDMUser *self;
593
594     self = LIGHTDM_USER (object);
595
596     switch (prop_id)
597     {
598     case USER_PROP_NAME:
599         g_value_set_string (value, lightdm_user_get_name (self));
600         break;
601     case USER_PROP_REAL_NAME:
602         g_value_set_string (value, lightdm_user_get_real_name (self));
603         break;
604     case USER_PROP_DISPLAY_NAME:
605         g_value_set_string (value, lightdm_user_get_display_name (self));
606         break;
607     case USER_PROP_HOME_DIRECTORY:
608         g_value_set_string (value, lightdm_user_get_home_directory (self));
609         break;
610     case USER_PROP_IMAGE:
611         g_value_set_string (value, lightdm_user_get_image (self));
612         break;
613     case USER_PROP_BACKGROUND:
614         g_value_set_string (value, lightdm_user_get_background (self));
615         break;
616     case USER_PROP_LANGUAGE:
617         g_value_set_string (value, lightdm_user_get_language (self));
618         break;
619     case USER_PROP_LAYOUT:
620         g_value_set_string (value, lightdm_user_get_layout (self));
621         break;
622     case USER_PROP_LAYOUTS:
623         g_value_set_boxed (value, g_strdupv ((gchar **) lightdm_user_get_layouts (self)));
624         break;
625     case USER_PROP_SESSION:
626         g_value_set_string (value, lightdm_user_get_session (self));
627         break;
628     case USER_PROP_LOGGED_IN:
629         g_value_set_boolean (value, lightdm_user_get_logged_in (self));
630         break;
631     case USER_PROP_HAS_MESSAGES:
632         g_value_set_boolean (value, lightdm_user_get_has_messages (self));
633         break;
634     case USER_PROP_UID:
635         g_value_set_uint64 (value, lightdm_user_get_uid (self));
636         break;
637     default:
638         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
639         break;
640     }
641 }
642
643 static void
644 lightdm_user_finalize (GObject *object)
645 {
646     LightDMUser *self = LIGHTDM_USER (object);
647     LightDMUserPrivate *priv = GET_USER_PRIVATE (self);
648
649     g_object_unref (priv->common_user);
650
651     G_OBJECT_CLASS (lightdm_user_parent_class)->finalize (object);
652 }
653
654 static void
655 lightdm_user_class_init (LightDMUserClass *klass)
656 {
657     GObjectClass *object_class = G_OBJECT_CLASS (klass);
658
659     g_type_class_add_private (klass, sizeof (LightDMUserPrivate));
660
661     object_class->set_property = lightdm_user_set_property;
662     object_class->get_property = lightdm_user_get_property;
663     object_class->finalize = lightdm_user_finalize;
664
665     g_object_class_install_property (object_class,
666                                      USER_PROP_COMMON_USER,
667                                      g_param_spec_object ("common-user",
668                                                           "common-user",
669                                                           "Internal user object",
670                                                           COMMON_TYPE_USER,
671                                                           G_PARAM_PRIVATE|G_PARAM_CONSTRUCT_ONLY|G_PARAM_WRITABLE));
672     g_object_class_install_property (object_class,
673                                      USER_PROP_NAME,
674                                      g_param_spec_string ("name",
675                                                           "name",
676                                                           "Username",
677                                                           NULL,
678                                                           G_PARAM_READABLE));
679     g_object_class_install_property (object_class,
680                                      USER_PROP_REAL_NAME,
681                                      g_param_spec_string ("real-name",
682                                                           "real-name",
683                                                           "Users real name",
684                                                           NULL,
685                                                           G_PARAM_READABLE));
686     g_object_class_install_property (object_class,
687                                      USER_PROP_DISPLAY_NAME,
688                                      g_param_spec_string ("display-name",
689                                                           "display-name",
690                                                           "Users display name",
691                                                           NULL,
692                                                           G_PARAM_READABLE));
693     g_object_class_install_property (object_class,
694                                      USER_PROP_HOME_DIRECTORY,
695                                      g_param_spec_string ("home-directory",
696                                                           "home-directory",
697                                                           "Home directory",
698                                                           NULL,
699                                                           G_PARAM_READABLE));
700     g_object_class_install_property (object_class,
701                                      USER_PROP_IMAGE,
702                                      g_param_spec_string ("image",
703                                                           "image",
704                                                           "Avatar image",
705                                                           NULL,
706                                                           G_PARAM_READABLE));
707     g_object_class_install_property (object_class,
708                                      USER_PROP_BACKGROUND,
709                                      g_param_spec_string ("background",
710                                                           "background",
711                                                           "User background",
712                                                           NULL,
713                                                           G_PARAM_READABLE));
714     g_object_class_install_property (object_class,
715                                      USER_PROP_LANGUAGE,
716                                      g_param_spec_string ("language",
717                                                          "language",
718                                                          "Language used by this user",
719                                                          NULL,
720                                                          G_PARAM_READABLE));
721     g_object_class_install_property (object_class,
722                                      USER_PROP_LAYOUT,
723                                      g_param_spec_string ("layout",
724                                                           "layout",
725                                                           "Keyboard layout used by this user",
726                                                           NULL,
727                                                           G_PARAM_READABLE));
728     g_object_class_install_property (object_class,
729                                      USER_PROP_LAYOUTS,
730                                      g_param_spec_boxed ("layouts",
731                                                          "layouts",
732                                                          "Keyboard layouts used by this user",
733                                                          G_TYPE_STRV,
734                                                          G_PARAM_READABLE));
735     g_object_class_install_property (object_class,
736                                      USER_PROP_SESSION,
737                                      g_param_spec_string ("session",
738                                                           "session",
739                                                           "Session used by this user",
740                                                           NULL,
741                                                           G_PARAM_READABLE));
742     g_object_class_install_property (object_class,
743                                      USER_PROP_LOGGED_IN,
744                                      g_param_spec_boolean ("logged-in",
745                                                            "logged-in",
746                                                            "TRUE if the user is currently in a session",
747                                                            FALSE,
748                                                            G_PARAM_READABLE));
749     g_object_class_install_property (object_class,
750                                      USER_PROP_LOGGED_IN,
751                                      g_param_spec_boolean ("has-messages",
752                                                            "has-messages",
753                                                            "TRUE if the user is has waiting messages",
754                                                            FALSE,
755                                                            G_PARAM_READABLE));
756     g_object_class_install_property (object_class,
757                                      USER_PROP_UID,
758                                      g_param_spec_uint64 ("uid",
759                                                           "uid",
760                                                           "User UID",
761                                                           0, G_MAXUINT64, 0,
762                                                           G_PARAM_READABLE));
763
764     /**
765      * LightDMUser::changed:
766      * @user: A #LightDMUser
767      *
768      * The ::changed signal gets emitted this user account is modified.
769      **/
770     user_signals[CHANGED] =
771         g_signal_new (LIGHTDM_SIGNAL_USER_CHANGED,
772                       G_TYPE_FROM_CLASS (klass),
773                       G_SIGNAL_RUN_LAST,
774                       G_STRUCT_OFFSET (LightDMUserClass, changed),
775                       NULL, NULL,
776                       NULL,
777                       G_TYPE_NONE, 0);
778 }