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