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