2 * Copyright (C) 2010 Robert Ancell.
3 * Author: Robert Ancell <robert.ancell@canonical.com>
5 * This library is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU Lesser General Public License as published by the Free
7 * Software Foundation; either version 3 of the License, or (at your option) any
8 * later version. See http://www.gnu.org/copyleft/lgpl.html the full text of the
16 #include <sys/utsname.h>
18 #include <gio/gdesktopappinfo.h>
19 #include <security/pam_appl.h>
20 #include <libxklavier/xklavier.h>
22 #include "lightdm/greeter.h"
23 #include "user-private.h"
24 #include "greeter-protocol.h"
31 PROP_DEFAULT_LANGUAGE,
36 PROP_TIMED_LOGIN_USER,
37 PROP_TIMED_LOGIN_DELAY,
38 PROP_AUTHENTICATION_USER,
39 PROP_IN_AUTHENTICATION,
40 PROP_IS_AUTHENTICATED,
52 AUTHENTICATION_COMPLETE,
60 static guint signals[LAST_SIGNAL] = { 0 };
62 struct _LdmGreeterPrivate
64 GDBusConnection *lightdm_bus;
66 GDBusConnection *system_bus;
68 GDBusProxy *lightdm_proxy;
70 GIOChannel *to_server_channel, *from_server_channel;
78 /* Configuration file */
84 /* File monitor for password file */
85 GFileMonitor *passwd_monitor;
87 /* TRUE if have scanned users */
93 gboolean have_languages;
96 gchar *default_layout;
97 XklEngine *xkl_engine;
98 XklConfigRec *xkl_config;
99 gboolean have_layouts;
103 gboolean have_sessions;
105 gchar *default_session;
107 gchar *authentication_user;
108 gboolean in_authentication;
109 gboolean is_authenticated;
114 gboolean guest_account_supported;
117 G_DEFINE_TYPE (LdmGreeter, ldm_greeter, G_TYPE_OBJECT);
119 #define HEADER_SIZE 8
124 * Create a new greeter.
126 * Return value: the new #LdmGreeter
131 return g_object_new (LDM_TYPE_GREETER, NULL);
135 timed_login_cb (gpointer data)
137 LdmGreeter *greeter = data;
139 greeter->priv->login_timeout = 0;
140 g_signal_emit (G_OBJECT (greeter), signals[TIMED_LOGIN], 0, greeter->priv->timed_user);
152 write_int (LdmGreeter *greeter, guint32 value)
155 buffer[0] = value >> 24;
156 buffer[1] = (value >> 16) & 0xFF;
157 buffer[2] = (value >> 8) & 0xFF;
158 buffer[3] = value & 0xFF;
159 if (g_io_channel_write_chars (greeter->priv->to_server_channel, buffer, int_length (), NULL, NULL) != G_IO_STATUS_NORMAL)
160 g_warning ("Error writing to server");
164 write_string (LdmGreeter *greeter, const gchar *value)
166 write_int (greeter, strlen (value));
167 g_io_channel_write_chars (greeter->priv->to_server_channel, value, -1, NULL, NULL);
171 read_int (LdmGreeter *greeter, gsize *offset)
175 if (greeter->priv->n_read - *offset < int_length ())
177 g_warning ("Not enough space for int, need %i, got %zi", int_length (), greeter->priv->n_read - *offset);
180 buffer = greeter->priv->read_buffer + *offset;
181 value = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
182 *offset += int_length ();
187 read_string (LdmGreeter *greeter, gsize *offset)
192 length = read_int (greeter, offset);
193 if (greeter->priv->n_read - *offset < length)
195 g_warning ("Not enough space for string, need %u, got %zu", length, greeter->priv->n_read - *offset);
196 return g_strdup ("");
199 value = g_malloc (sizeof (gchar) * (length + 1));
200 memcpy (value, greeter->priv->read_buffer + *offset, length);
201 value[length] = '\0';
208 string_length (const gchar *value)
210 return int_length () + strlen (value);
214 write_header (LdmGreeter *greeter, guint32 id, guint32 length)
216 write_int (greeter, id);
217 write_int (greeter, length);
220 static guint32 get_packet_length (LdmGreeter *greeter)
223 return read_int (greeter, &offset);
227 flush (LdmGreeter *greeter)
229 g_io_channel_flush (greeter->priv->to_server_channel, NULL);
233 handle_prompt_authentication (LdmGreeter *greeter, gsize *offset)
237 n_messages = read_int (greeter, offset);
238 g_debug ("Prompt user with %d message(s)", n_messages);
240 for (i = 0; i < n_messages; i++)
245 msg_style = read_int (greeter, offset);
246 msg = read_string (greeter, offset);
248 // FIXME: Should stop on prompts?
251 case PAM_PROMPT_ECHO_OFF:
252 case PAM_PROMPT_ECHO_ON:
253 g_signal_emit (G_OBJECT (greeter), signals[SHOW_PROMPT], 0, msg);
256 g_signal_emit (G_OBJECT (greeter), signals[SHOW_ERROR], 0, msg);
259 g_signal_emit (G_OBJECT (greeter), signals[SHOW_MESSAGE], 0, msg);
268 read_packet (LdmGreeter *greeter, gboolean block)
270 gsize n_to_read, n_read;
271 GError *error = NULL;
273 /* Read the header, or the whole packet if we already have that */
274 n_to_read = HEADER_SIZE;
275 if (greeter->priv->n_read >= HEADER_SIZE)
276 n_to_read += get_packet_length (greeter);
281 status = g_io_channel_read_chars (greeter->priv->from_server_channel,
282 greeter->priv->read_buffer + greeter->priv->n_read,
283 n_to_read - greeter->priv->n_read,
286 if (status == G_IO_STATUS_ERROR)
287 g_warning ("Error reading from server: %s", error->message);
288 g_clear_error (&error);
289 if (status != G_IO_STATUS_NORMAL)
292 greeter->priv->n_read += n_read;
293 } while (greeter->priv->n_read < n_to_read && block);
295 /* Stop if haven't got all the data we want */
296 if (greeter->priv->n_read != n_to_read)
299 /* If have header, rerun for content */
300 if (greeter->priv->n_read == HEADER_SIZE)
302 n_to_read = get_packet_length (greeter);
305 greeter->priv->read_buffer = g_realloc (greeter->priv->read_buffer, HEADER_SIZE + n_to_read);
306 return read_packet (greeter, block);
314 from_server_cb (GIOChannel *source, GIOCondition condition, gpointer data)
316 LdmGreeter *greeter = data;
318 guint32 id, return_code;
320 if (!read_packet (greeter, FALSE))
324 id = read_int (greeter, &offset);
325 read_int (greeter, &offset);
328 case GREETER_MESSAGE_CONNECTED:
329 greeter->priv->theme = read_string (greeter, &offset);
330 greeter->priv->default_layout = read_string (greeter, &offset);
331 greeter->priv->default_session = read_string (greeter, &offset);
332 greeter->priv->timed_user = read_string (greeter, &offset);
333 greeter->priv->login_delay = read_int (greeter, &offset);
334 greeter->priv->guest_account_supported = read_int (greeter, &offset) != 0;
336 g_debug ("Connected theme=%s default-layout=%s default-session=%s timed-user=%s login-delay=%d guest-account-supported=%s",
337 greeter->priv->theme,
338 greeter->priv->default_layout, greeter->priv->default_session,
339 greeter->priv->timed_user, greeter->priv->login_delay,
340 greeter->priv->guest_account_supported ? "true" : "false");
342 /* Set timeout for default login */
343 if (greeter->priv->timed_user[0] != '\0' && greeter->priv->login_delay > 0)
345 g_debug ("Logging in as %s in %d seconds", greeter->priv->timed_user, greeter->priv->login_delay);
346 greeter->priv->login_timeout = g_timeout_add (greeter->priv->login_delay * 1000, timed_login_cb, greeter);
348 g_signal_emit (G_OBJECT (greeter), signals[CONNECTED], 0);
350 case GREETER_MESSAGE_QUIT:
351 g_debug ("Got quit request from server");
352 g_signal_emit (G_OBJECT (greeter), signals[QUIT], 0);
354 case GREETER_MESSAGE_PROMPT_AUTHENTICATION:
355 handle_prompt_authentication (greeter, &offset);
357 case GREETER_MESSAGE_END_AUTHENTICATION:
358 return_code = read_int (greeter, &offset);
359 g_debug ("Authentication complete with return code %d", return_code);
360 greeter->priv->is_authenticated = (return_code == 0);
361 if (!greeter->priv->is_authenticated)
363 g_free (greeter->priv->authentication_user);
364 greeter->priv->authentication_user = NULL;
366 g_signal_emit (G_OBJECT (greeter), signals[AUTHENTICATION_COMPLETE], 0);
367 greeter->priv->in_authentication = FALSE;
370 g_warning ("Unknown message from server: %d", id);
374 greeter->priv->n_read = 0;
380 * ldm_greeter_connect_to_server:
381 * @greeter: The greeter to connect
383 * Connects the greeter to the display manager.
385 * Return value: TRUE if successfully connected
388 ldm_greeter_connect_to_server (LdmGreeter *greeter)
390 GError *error = NULL;
391 const gchar *bus_address, *fd;
392 GBusType bus_type = G_BUS_TYPE_SYSTEM;
394 g_return_val_if_fail (LDM_IS_GREETER (greeter), FALSE);
396 greeter->priv->system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
397 if (!greeter->priv->system_bus)
398 g_warning ("Failed to connect to system bus: %s", error->message);
399 g_clear_error (&error);
400 if (!greeter->priv->system_bus)
403 bus_address = getenv ("LDM_BUS");
404 if (bus_address && strcmp (bus_address, "SESSION") == 0)
405 bus_type = G_BUS_TYPE_SESSION;
407 greeter->priv->lightdm_bus = g_bus_get_sync (bus_type, NULL, &error);
408 if (!greeter->priv->lightdm_bus)
409 g_warning ("Failed to connect to LightDM bus: %s", error->message);
410 g_clear_error (&error);
411 if (!greeter->priv->lightdm_bus)
414 fd = getenv ("LDM_TO_SERVER_FD");
417 g_warning ("No LDM_TO_SERVER_FD environment variable");
420 greeter->priv->to_server_channel = g_io_channel_unix_new (atoi (fd));
421 g_io_channel_set_encoding (greeter->priv->to_server_channel, NULL, NULL);
423 fd = getenv ("LDM_FROM_SERVER_FD");
426 g_warning ("No LDM_FROM_SERVER_FD environment variable");
429 greeter->priv->from_server_channel = g_io_channel_unix_new (atoi (fd));
430 g_io_channel_set_encoding (greeter->priv->from_server_channel, NULL, NULL);
431 g_io_add_watch (greeter->priv->from_server_channel, G_IO_IN, from_server_cb, greeter);
433 greeter->priv->lightdm_proxy = g_dbus_proxy_new_sync (greeter->priv->lightdm_bus,
434 G_DBUS_PROXY_FLAGS_NONE,
436 "org.lightdm.LightDisplayManager",
437 "/org/lightdm/LightDisplayManager",
438 "org.lightdm.LightDisplayManager",
441 g_debug ("Connecting to display manager...");
442 write_header (greeter, GREETER_MESSAGE_CONNECT, 0);
449 * ldm_greeter_get_hostname:
450 * @greeter: a #LdmGreeter
452 * Return value: The host this greeter is displaying
455 ldm_greeter_get_hostname (LdmGreeter *greeter)
457 g_return_val_if_fail (LDM_IS_GREETER (greeter), NULL);
459 if (!greeter->priv->hostname)
463 greeter->priv->hostname = g_strdup (info.nodename);
466 return greeter->priv->hostname;
470 * ldm_greeter_get_theme:
471 * @greeter: a #LdmGreeter
473 * Return value: The theme this greeter is using
476 ldm_greeter_get_theme (LdmGreeter *greeter)
478 g_return_val_if_fail (LDM_IS_GREETER (greeter), NULL);
479 return greeter->priv->theme;
483 load_theme (LdmGreeter *greeter)
485 GError *error = NULL;
487 if (greeter->priv->theme_file)
490 greeter->priv->theme_file = g_key_file_new ();
491 if (!g_key_file_load_from_file (greeter->priv->theme_file, greeter->priv->theme, G_KEY_FILE_NONE, &error))
492 g_warning ("Failed to read theme file: %s", error->message);
493 g_clear_error (&error);
497 * ldm_greeter_get_string_property:
498 * @greeter: a #LdmGreeter
499 * @name: the name of the property to get
501 * Return value: The value of this property or NULL if it is not defined
504 ldm_greeter_get_string_property (LdmGreeter *greeter, const gchar *name)
506 GError *error = NULL;
509 g_return_val_if_fail (LDM_IS_GREETER (greeter), NULL);
510 g_return_val_if_fail (name != NULL, NULL);
512 load_theme (greeter);
514 result = g_key_file_get_string (greeter->priv->theme_file, "theme", name, &error);
516 g_warning ("Error reading theme property: %s", error->message); // FIXME: Can handle G_KEY_FILE_ERROR_KEY_NOT_FOUND and G_KEY_FILE_ERROR_GROUP_NOT_FOUND
517 g_clear_error (&error);
523 * ldm_greeter_get_integer_property:
524 * @greeter: a #LdmGreeter
525 * @name: the name of the property to get
527 * Return value: The value of this property or 0 if it is not defined
530 ldm_greeter_get_integer_property (LdmGreeter *greeter, const gchar *name)
532 GError *error = NULL;
535 g_return_val_if_fail (LDM_IS_GREETER (greeter), 0);
536 g_return_val_if_fail (name != NULL, 0);
538 load_theme (greeter);
540 result = g_key_file_get_integer (greeter->priv->theme_file, "theme", name, &error);
542 g_warning ("Error reading theme property: %s", error->message); // FIXME: Can handle G_KEY_FILE_ERROR_KEY_NOT_FOUND and G_KEY_FILE_ERROR_GROUP_NOT_FOUND
543 g_clear_error (&error);
549 * ldm_greeter_get_boolean_property:
550 * @greeter: a #LdmGreeter
551 * @name: the name of the property to get
553 * Return value: The value of this property or FALSE if it is not defined
556 ldm_greeter_get_boolean_property (LdmGreeter *greeter, const gchar *name)
558 GError *error = NULL;
561 g_return_val_if_fail (LDM_IS_GREETER (greeter), FALSE);
562 g_return_val_if_fail (name != NULL, FALSE);
564 load_theme (greeter);
566 result = g_key_file_get_boolean (greeter->priv->theme_file, "theme", name, &error);
568 g_warning ("Error reading theme property: %s", error->message); // FIXME: Can handle G_KEY_FILE_ERROR_KEY_NOT_FOUND and G_KEY_FILE_ERROR_GROUP_NOT_FOUND
569 g_clear_error (&error);
575 get_user_by_name (LdmGreeter *greeter, const gchar *username)
579 for (link = greeter->priv->users; link; link = link->next)
581 LdmUser *user = link->data;
582 if (strcmp (ldm_user_get_name (user), username) == 0)
590 compare_user (gconstpointer a, gconstpointer b)
592 LdmUser *user_a = (LdmUser *) a, *user_b = (LdmUser *) b;
593 return strcmp (ldm_user_get_display_name (user_a), ldm_user_get_display_name (user_b));
597 load_config (LdmGreeter *greeter)
600 const gchar *config_path = NULL;
602 if (greeter->priv->config)
605 result = g_dbus_proxy_get_cached_property (greeter->priv->lightdm_proxy,
609 g_warning ("No ConfigFile property");
613 if (g_variant_is_of_type (result, G_VARIANT_TYPE_STRING))
614 config_path = g_variant_get_string (result, NULL);
616 g_warning ("Invalid type for config file: %s, expected string", g_variant_get_type_string (result));
620 GError *error = NULL;
622 g_debug ("Loading config from %s", config_path);
624 greeter->priv->config = g_key_file_new ();
625 if (!g_key_file_load_from_file (greeter->priv->config, config_path, G_KEY_FILE_NONE, &error))
626 g_warning ("Failed to load configuration from %s: %s", config_path, error->message); // FIXME: Don't make warning on no file, just info
627 g_clear_error (&error);
630 g_variant_unref (result);
634 load_users (LdmGreeter *greeter)
636 gchar **hidden_users, **hidden_shells;
639 GList *users = NULL, *old_users, *new_users = NULL, *changed_users = NULL, *link;
641 load_config (greeter);
643 if (g_key_file_has_key (greeter->priv->config, "UserManager", "minimum-uid", NULL))
644 minimum_uid = g_key_file_get_integer (greeter->priv->config, "UserManager", "minimum-uid", NULL);
648 value = g_key_file_get_string (greeter->priv->config, "UserManager", "hidden-users", NULL);
650 value = g_strdup ("nobody nobody4 noaccess");
651 hidden_users = g_strsplit (value, " ", -1);
654 value = g_key_file_get_string (greeter->priv->config, "UserManager", "hidden-shells", NULL);
656 value = g_strdup ("/bin/false /usr/sbin/nologin");
657 hidden_shells = g_strsplit (value, " ", -1);
664 struct passwd *entry;
667 gchar *real_name, *image_path, *image;
675 /* Ignore system users */
676 if (entry->pw_uid < minimum_uid)
679 /* Ignore users disabled by shell */
682 for (i = 0; hidden_shells[i] && strcmp (entry->pw_shell, hidden_shells[i]) != 0; i++);
683 if (hidden_shells[i])
687 /* Ignore certain users */
688 for (i = 0; hidden_users[i] && strcmp (entry->pw_name, hidden_users[i]) != 0; i++);
692 tokens = g_strsplit (entry->pw_gecos, ",", -1);
693 if (tokens[0] != NULL && tokens[0][0] != '\0')
694 real_name = g_strdup (tokens[0]);
699 image_path = g_build_filename (entry->pw_dir, ".face", NULL);
700 if (!g_file_test (image_path, G_FILE_TEST_EXISTS))
703 image_path = g_build_filename (entry->pw_dir, ".face.icon", NULL);
704 if (!g_file_test (image_path, G_FILE_TEST_EXISTS))
711 image = g_filename_to_uri (image_path, NULL, NULL);
716 user = ldm_user_new (greeter, entry->pw_name, real_name, entry->pw_dir, image, FALSE);
720 /* Update existing users if have them */
721 for (link = greeter->priv->users; link; link = link->next)
723 LdmUser *info = link->data;
724 if (strcmp (ldm_user_get_name (info), ldm_user_get_name (user)) == 0)
726 if (ldm_user_update (info, ldm_user_get_real_name (user), ldm_user_get_home_directory (user), ldm_user_get_image (user), ldm_user_get_logged_in (user)))
727 changed_users = g_list_insert_sorted (changed_users, user, compare_user);
728 g_object_unref (user);
735 /* Only notify once we have loaded the user list */
736 if (greeter->priv->have_users)
737 new_users = g_list_insert_sorted (new_users, user, compare_user);
739 users = g_list_insert_sorted (users, user, compare_user);
741 g_strfreev (hidden_users);
742 g_strfreev (hidden_shells);
745 g_warning ("Failed to read password database: %s", strerror (errno));
749 /* Use new user list */
750 old_users = greeter->priv->users;
751 greeter->priv->users = users;
753 /* Notify of changes */
754 for (link = new_users; link; link = link->next)
756 LdmUser *info = link->data;
757 g_debug ("User %s added", ldm_user_get_name (info));
758 g_signal_emit (greeter, signals[USER_ADDED], 0, info);
760 g_list_free (new_users);
761 for (link = changed_users; link; link = link->next)
763 LdmUser *info = link->data;
764 g_debug ("User %s changed", ldm_user_get_name (info));
765 g_signal_emit (greeter, signals[USER_CHANGED], 0, info);
767 g_list_free (changed_users);
768 for (link = old_users; link; link = link->next)
772 /* See if this user is in the current list */
773 for (new_link = greeter->priv->users; new_link; new_link = new_link->next)
775 if (new_link->data == link->data)
781 LdmUser *info = link->data;
782 g_debug ("User %s removed", ldm_user_get_name (info));
783 g_signal_emit (greeter, signals[USER_REMOVED], 0, info);
784 g_object_unref (info);
787 g_list_free (old_users);
791 passwd_changed_cb (GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, LdmGreeter *greeter)
793 if (event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT)
795 g_debug ("%s changed, reloading user list", g_file_get_path (file));
796 load_users (greeter);
801 update_users (LdmGreeter *greeter)
804 GError *error = NULL;
806 if (greeter->priv->have_users)
809 load_config (greeter);
811 /* User listing is disabled */
812 if (g_key_file_has_key (greeter->priv->config, "UserManager", "load-users", NULL) &&
813 !g_key_file_get_boolean (greeter->priv->config, "UserManager", "load-users", NULL))
815 greeter->priv->have_users = TRUE;
819 load_users (greeter);
821 /* Watch for changes to user list */
822 passwd_file = g_file_new_for_path ("/etc/passwd");
823 greeter->priv->passwd_monitor = g_file_monitor (passwd_file, G_FILE_MONITOR_NONE, NULL, &error);
824 g_object_unref (passwd_file);
825 if (!greeter->priv->passwd_monitor)
826 g_warning ("Error monitoring /etc/passwd: %s", error->message);
828 g_signal_connect (greeter->priv->passwd_monitor, "changed", G_CALLBACK (passwd_changed_cb), greeter);
829 g_clear_error (&error);
831 greeter->priv->have_users = TRUE;
835 * ldm_greeter_get_num_users:
836 * @greeter: a #LdmGreeter
838 * Return value: The number of users able to log in
841 ldm_greeter_get_num_users (LdmGreeter *greeter)
843 g_return_val_if_fail (LDM_IS_GREETER (greeter), 0);
844 update_users (greeter);
845 return g_list_length (greeter->priv->users);
849 * ldm_greeter_get_users:
850 * @greeter: A #LdmGreeter
852 * Get a list of users to present to the user. This list may be a subset of the
853 * available users and may be empty depending on the server configuration.
855 * Return value: (element-type LdmUser): A list of #LdmUser that should be presented to the user.
858 ldm_greeter_get_users (LdmGreeter *greeter)
860 g_return_val_if_fail (LDM_IS_GREETER (greeter), NULL);
861 update_users (greeter);
862 return greeter->priv->users;
866 * ldm_greeter_get_user_by_name:
867 * @greeter: A #LdmGreeter
868 * @username: Name of user to get.
870 * Get infomation about a given user or NULL if this user doesn't exist.
872 * Return value: (allow-none): A #LdmUser entry for the given user.
875 ldm_greeter_get_user_by_name (LdmGreeter *greeter, const gchar *username)
877 g_return_val_if_fail (LDM_IS_GREETER (greeter), NULL);
879 update_users (greeter);
881 return get_user_by_name (greeter, username);
885 update_languages (LdmGreeter *greeter)
887 gchar *stdout_text = NULL, *stderr_text = NULL;
890 GError *error = NULL;
892 if (greeter->priv->have_languages)
895 result = g_spawn_command_line_sync ("locale -a", &stdout_text, &stderr_text, &exit_status, &error);
896 if (!result || exit_status != 0)
897 g_warning ("Failed to get languages, locale -a returned %d: %s", exit_status, error->message);
903 tokens = g_strsplit_set (stdout_text, "\n\r", -1);
904 for (i = 0; tokens[i]; i++)
906 LdmLanguage *language;
909 code = g_strchug (tokens[i]);
913 /* Ignore the non-interesting languages */
914 if (strcmp (code, "C") == 0 || strcmp (code, "POSIX") == 0)
917 language = ldm_language_new (code);
918 greeter->priv->languages = g_list_append (greeter->priv->languages, language);
924 g_clear_error (&error);
925 g_free (stdout_text);
926 g_free (stderr_text);
928 greeter->priv->have_languages = TRUE;
932 * ldm_greeter_get_default_language:
933 * @greeter: A #LdmGreeter
935 * Get the default language.
937 * Return value: The default language.
940 ldm_greeter_get_default_language (LdmGreeter *greeter)
943 g_return_val_if_fail (LDM_IS_GREETER (greeter), NULL);
944 lang = getenv ("LANG");
952 * ldm_greeter_get_languages:
953 * @greeter: A #LdmGreeter
955 * Get a list of languages to present to the user.
957 * Return value: (element-type LdmLanguage): A list of #LdmLanguage that should be presented to the user.
960 ldm_greeter_get_languages (LdmGreeter *greeter)
962 g_return_val_if_fail (LDM_IS_GREETER (greeter), NULL);
963 update_languages (greeter);
964 return greeter->priv->languages;
968 ldm_greeter_get_default_layout (LdmGreeter *greeter)
970 g_return_val_if_fail (LDM_IS_GREETER (greeter), NULL);
971 return greeter->priv->default_layout;
975 layout_cb (XklConfigRegistry *config,
976 const XklConfigItem *item,
979 LdmGreeter *greeter = data;
982 layout = ldm_layout_new (item->name, item->short_description, item->description);
983 greeter->priv->layouts = g_list_append (greeter->priv->layouts, layout);
987 setup_display (LdmGreeter *greeter)
989 if (!greeter->priv->display)
990 greeter->priv->display = XOpenDisplay (NULL);
994 setup_xkl (LdmGreeter *greeter)
996 setup_display (greeter);
997 greeter->priv->xkl_engine = xkl_engine_get_instance (greeter->priv->display);
998 greeter->priv->xkl_config = xkl_config_rec_new ();
999 if (!xkl_config_rec_get_from_server (greeter->priv->xkl_config, greeter->priv->xkl_engine))
1000 g_warning ("Failed to get Xkl configuration from server");
1001 greeter->priv->layout = g_strdup (greeter->priv->xkl_config->layouts[0]);
1005 * ldm_greeter_get_layouts:
1006 * @greeter: A #LdmGreeter
1008 * Get a list of keyboard layouts to present to the user.
1010 * Return value: (element-type LdmLayout): A list of #LdmLayout that should be presented to the user.
1013 ldm_greeter_get_layouts (LdmGreeter *greeter)
1015 XklConfigRegistry *registry;
1017 g_return_val_if_fail (LDM_IS_GREETER (greeter), NULL);
1019 if (greeter->priv->have_layouts)
1020 return greeter->priv->layouts;
1022 setup_xkl (greeter);
1024 registry = xkl_config_registry_get_instance (greeter->priv->xkl_engine);
1025 xkl_config_registry_load (registry, FALSE);
1026 xkl_config_registry_foreach_layout (registry, layout_cb, greeter);
1027 g_object_unref (registry);
1028 greeter->priv->have_layouts = TRUE;
1030 return greeter->priv->layouts;
1034 * ldm_greeter_set_layout:
1035 * @greeter: A #LdmGreeter
1036 * @layout: The layout to use
1038 * Set the layout for this session.
1041 ldm_greeter_set_layout (LdmGreeter *greeter, const gchar *layout)
1043 XklConfigRec *config;
1045 g_return_if_fail (LDM_IS_GREETER (greeter));
1046 g_return_if_fail (layout != NULL);
1048 g_debug ("Setting keyboard layout to %s", layout);
1050 setup_xkl (greeter);
1052 config = xkl_config_rec_new ();
1053 config->layouts = g_malloc (sizeof (gchar *) * 2);
1054 config->model = g_strdup (greeter->priv->xkl_config->model);
1055 config->layouts[0] = g_strdup (layout);
1056 config->layouts[1] = NULL;
1057 if (!xkl_config_rec_activate (config, greeter->priv->xkl_engine))
1058 g_warning ("Failed to activate XKL config");
1060 greeter->priv->layout = g_strdup (layout);
1061 g_object_unref (config);
1065 * ldm_greeter_get_layout:
1066 * @greeter: A #LdmGreeter
1068 * Get the current keyboard layout.
1070 * Return value: The currently active layout for this user.
1073 ldm_greeter_get_layout (LdmGreeter *greeter)
1075 g_return_val_if_fail (LDM_IS_GREETER (greeter), NULL);
1076 setup_xkl (greeter);
1077 return greeter->priv->layout;
1081 update_sessions (LdmGreeter *greeter)
1084 GError *error = NULL;
1086 if (greeter->priv->have_sessions)
1089 directory = g_dir_open (XSESSIONS_DIR, 0, &error);
1091 g_warning ("Failed to open sessions directory: %s", error->message);
1092 g_clear_error (&error);
1098 const gchar *filename;
1103 filename = g_dir_read_name (directory);
1104 if (filename == NULL)
1107 if (!g_str_has_suffix (filename, ".desktop"))
1110 key = g_strndup (filename, strlen (filename) - strlen (".desktop"));
1111 path = g_build_filename (XSESSIONS_DIR, filename, NULL);
1112 g_debug ("Loading session %s", path);
1114 key_file = g_key_file_new ();
1115 result = g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, &error);
1117 g_warning ("Failed to load session file %s: %s:", path, error->message);
1118 g_clear_error (&error);
1120 if (result && !g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY, NULL))
1122 gchar *domain, *name, *comment;
1124 #ifdef G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN
1125 domain = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN, NULL);
1127 domain = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GNOME-Gettext-Domain", NULL);
1129 name = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, domain, NULL);
1130 comment = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_COMMENT, domain, NULL);
1132 comment = g_strdup ("");
1135 g_debug ("Loaded session %s (%s, %s)", key, name, comment);
1136 greeter->priv->sessions = g_list_append (greeter->priv->sessions, ldm_session_new (key, name, comment));
1139 g_warning ("Invalid session %s: %s", path, error->message);
1140 g_clear_error (&error);
1148 g_key_file_free (key_file);
1151 g_dir_close (directory);
1153 greeter->priv->have_sessions = TRUE;
1157 * ldm_greeter_get_sessions:
1158 * @greeter: A #LdmGreeter
1160 * Get the available sessions.
1162 * Return value: (element-type LdmSession): A list of #LdmSession
1165 ldm_greeter_get_sessions (LdmGreeter *greeter)
1167 g_return_val_if_fail (LDM_IS_GREETER (greeter), NULL);
1168 update_sessions (greeter);
1169 return greeter->priv->sessions;
1173 * ldm_greeter_get_default_session:
1174 * @greeter: A #LdmGreeter
1176 * Get the default session to use.
1178 * Return value: The session name
1181 ldm_greeter_get_default_session (LdmGreeter *greeter)
1183 g_return_val_if_fail (LDM_IS_GREETER (greeter), NULL);
1184 return greeter->priv->default_session;
1188 * ldm_greeter_get_has_guest_session:
1189 * @greeter: A #LdmGreeter
1191 * Check if guest sessions are supported.
1193 * Return value: TRUE if guest sessions are supported.
1196 ldm_greeter_get_has_guest_session (LdmGreeter *greeter)
1198 g_return_val_if_fail (LDM_IS_GREETER (greeter), FALSE);
1199 return greeter->priv->guest_account_supported;
1203 * ldm_greeter_get_timed_login_user:
1204 * @greeter: A #LdmGreeter
1206 * Get the user to log in by as default.
1208 * Return value: A username
1211 ldm_greeter_get_timed_login_user (LdmGreeter *greeter)
1213 g_return_val_if_fail (LDM_IS_GREETER (greeter), NULL);
1214 return greeter->priv->timed_user;
1218 * ldm_greeter_get_timed_login_delay:
1219 * @greeter: A #LdmGreeter
1221 * Get the number of seconds to wait until logging in as the default user.
1223 * Return value: The number of seconds before logging in as the default user
1226 ldm_greeter_get_timed_login_delay (LdmGreeter *greeter)
1228 g_return_val_if_fail (LDM_IS_GREETER (greeter), 0);
1229 return greeter->priv->login_delay;
1233 * ldm_greeter_cancel_timed_login:
1234 * @greeter: A #LdmGreeter
1236 * Cancel the login as the default user.
1239 ldm_greeter_cancel_timed_login (LdmGreeter *greeter)
1241 g_return_if_fail (LDM_IS_GREETER (greeter));
1243 if (greeter->priv->login_timeout)
1244 g_source_remove (greeter->priv->login_timeout);
1245 greeter->priv->login_timeout = 0;
1249 * ldm_greeter_login:
1250 * @greeter: A #LdmGreeter
1251 * @username: A username
1253 * Starts the authentication procedure for a user.
1256 ldm_greeter_login (LdmGreeter *greeter, const char *username)
1258 g_return_if_fail (LDM_IS_GREETER (greeter));
1259 g_return_if_fail (username != NULL);
1261 greeter->priv->in_authentication = TRUE;
1262 greeter->priv->is_authenticated = FALSE;
1263 g_free (greeter->priv->authentication_user);
1264 greeter->priv->authentication_user = g_strdup (username);
1265 g_debug ("Starting authentication for user %s...", username);
1266 write_header (greeter, GREETER_MESSAGE_LOGIN, string_length (username));
1267 write_string (greeter, username);
1272 * ldm_greeter_login_as_guest:
1273 * @greeter: A #LdmGreeter
1275 * Starts the authentication procedure for the guest user.
1278 ldm_greeter_login_as_guest (LdmGreeter *greeter)
1280 g_return_if_fail (LDM_IS_GREETER (greeter));
1282 greeter->priv->in_authentication = TRUE;
1283 greeter->priv->is_authenticated = FALSE;
1284 g_free (greeter->priv->authentication_user);
1285 greeter->priv->authentication_user = NULL;
1286 g_debug ("Starting authentication for guest account...");
1287 write_header (greeter, GREETER_MESSAGE_LOGIN_AS_GUEST, 0);
1292 * ldm_greeter_provide_secret:
1293 * @greeter: A #LdmGreeter
1294 * @secret: Response to a prompt
1296 * Provide secret information from a prompt.
1299 ldm_greeter_provide_secret (LdmGreeter *greeter, const gchar *secret)
1301 g_return_if_fail (LDM_IS_GREETER (greeter));
1302 g_return_if_fail (secret != NULL);
1304 g_debug ("Providing secret to display manager");
1305 write_header (greeter, GREETER_MESSAGE_CONTINUE_AUTHENTICATION, int_length () + string_length (secret));
1306 // FIXME: Could be multiple secrets required
1307 write_int (greeter, 1);
1308 write_string (greeter, secret);
1313 * ldm_greeter_cancel_authentication:
1314 * @greeter: A #LdmGreeter
1316 * Cancel the current user authentication.
1319 ldm_greeter_cancel_authentication (LdmGreeter *greeter)
1321 g_return_if_fail (LDM_IS_GREETER (greeter));
1322 write_header (greeter, GREETER_MESSAGE_CANCEL_AUTHENTICATION, 0);
1327 * ldm_greeter_get_in_authentication:
1328 * @greeter: A #LdmGreeter
1330 * Checks if the greeter is in the process of authenticating.
1332 * Return value: TRUE if the greeter is authenticating a user.
1335 ldm_greeter_get_in_authentication (LdmGreeter *greeter)
1337 g_return_val_if_fail (LDM_IS_GREETER (greeter), FALSE);
1338 return greeter->priv->in_authentication;
1342 * ldm_greeter_get_is_authenticated:
1343 * @greeter: A #LdmGreeter
1345 * Checks if the greeter has successfully authenticated.
1347 * Return value: TRUE if the greeter is authenticated for login.
1350 ldm_greeter_get_is_authenticated (LdmGreeter *greeter)
1352 g_return_val_if_fail (LDM_IS_GREETER (greeter), FALSE);
1353 return greeter->priv->is_authenticated;
1357 * ldm_greeter_get_authentication_user:
1358 * @greeter: A #LdmGreeter
1360 * Get the user that is being authenticated.
1362 * Return value: The username of the authentication user being authenticated or NULL if no authentication in progress.
1365 ldm_greeter_get_authentication_user (LdmGreeter *greeter)
1367 g_return_val_if_fail (LDM_IS_GREETER (greeter), NULL);
1368 return greeter->priv->authentication_user;
1372 * ldm_greeter_start_session:
1373 * @greeter: A #LdmGreeter
1374 * @session: (allow-none): The session to log into or NULL to use the default
1375 * @language: (allow-none): The language to use or NULL to use the default
1377 * Start a session for the logged in user.
1380 ldm_greeter_start_session (LdmGreeter *greeter, const gchar *session, const gchar *language)
1382 g_return_if_fail (LDM_IS_GREETER (greeter));
1389 g_debug ("Starting session %s with language %s", session, language);
1390 write_header (greeter, GREETER_MESSAGE_START_SESSION, string_length (session) + string_length (language));
1391 write_string (greeter, session);
1392 write_string (greeter, language);
1397 * ldm_greeter_start_session_with_defaults:
1398 * @greeter: A #LdmGreeter
1400 * Login a user to a session using default settings for that user.
1403 ldm_greeter_start_session_with_defaults (LdmGreeter *greeter)
1405 ldm_greeter_start_session (greeter, NULL, NULL);
1409 upower_call_function (LdmGreeter *greeter, const gchar *function, gboolean has_result)
1413 GError *error = NULL;
1414 gboolean function_result = FALSE;
1416 proxy = g_dbus_proxy_new_sync (greeter->priv->system_bus,
1417 G_DBUS_PROXY_FLAGS_NONE,
1419 "org.freedesktop.UPower",
1420 "/org/freedesktop/UPower",
1421 "org.freedesktop.UPower",
1423 result = g_dbus_proxy_call_sync (proxy,
1426 G_DBUS_CALL_FLAGS_NONE,
1430 g_object_unref (proxy);
1433 g_warning ("Error calling UPower function %s: %s", function, error->message);
1434 g_clear_error (&error);
1438 if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(b)")))
1439 g_variant_get (result, "(b)", &function_result);
1441 g_variant_unref (result);
1442 return function_result;
1446 * ldm_greeter_get_can_suspend:
1447 * @greeter: A #LdmGreeter
1449 * Checks if the greeter is authorized to do a system suspend.
1451 * Return value: TRUE if the greeter can suspend the system
1454 ldm_greeter_get_can_suspend (LdmGreeter *greeter)
1456 g_return_val_if_fail (LDM_IS_GREETER (greeter), FALSE);
1457 return upower_call_function (greeter, "SuspendAllowed", TRUE);
1461 * ldm_greeter_suspend:
1462 * @greeter: A #LdmGreeter
1464 * Triggers a system suspend.
1467 ldm_greeter_suspend (LdmGreeter *greeter)
1469 g_return_if_fail (LDM_IS_GREETER (greeter));
1470 upower_call_function (greeter, "Suspend", FALSE);
1474 * ldm_greeter_get_can_hibernate:
1475 * @greeter: A #LdmGreeter
1477 * Checks if the greeter is authorized to do a system hibernate.
1479 * Return value: TRUE if the greeter can hibernate the system
1482 ldm_greeter_get_can_hibernate (LdmGreeter *greeter)
1484 g_return_val_if_fail (LDM_IS_GREETER (greeter), FALSE);
1485 return upower_call_function (greeter, "HibernateAllowed", TRUE);
1489 * ldm_greeter_hibernate:
1490 * @greeter: A #LdmGreeter
1492 * Triggers a system hibernate.
1495 ldm_greeter_hibernate (LdmGreeter *greeter)
1497 g_return_if_fail (LDM_IS_GREETER (greeter));
1498 upower_call_function (greeter, "Hibernate", FALSE);
1502 ck_call_function (LdmGreeter *greeter, const gchar *function, gboolean has_result)
1506 GError *error = NULL;
1507 gboolean function_result = FALSE;
1509 proxy = g_dbus_proxy_new_sync (greeter->priv->system_bus,
1510 G_DBUS_PROXY_FLAGS_NONE,
1512 "org.freedesktop.ConsoleKit",
1513 "/org/freedesktop/ConsoleKit/Manager",
1514 "org.freedesktop.ConsoleKit.Manager",
1516 result = g_dbus_proxy_call_sync (proxy,
1519 G_DBUS_CALL_FLAGS_NONE,
1523 g_object_unref (proxy);
1526 g_warning ("Error calling ConsoleKit function %s: %s", function, error->message);
1527 g_clear_error (&error);
1531 if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(b)")))
1532 g_variant_get (result, "(b)", &function_result);
1534 g_variant_unref (result);
1535 return function_result;
1539 * ldm_greeter_get_can_restart:
1540 * @greeter: A #LdmGreeter
1542 * Checks if the greeter is authorized to do a system restart.
1544 * Return value: TRUE if the greeter can restart the system
1547 ldm_greeter_get_can_restart (LdmGreeter *greeter)
1549 g_return_val_if_fail (LDM_IS_GREETER (greeter), FALSE);
1550 return ck_call_function (greeter, "CanRestart", TRUE);
1554 * ldm_greeter_restart:
1555 * @greeter: A #LdmGreeter
1557 * Triggers a system restart.
1560 ldm_greeter_restart (LdmGreeter *greeter)
1562 g_return_if_fail (LDM_IS_GREETER (greeter));
1563 ck_call_function (greeter, "Restart", FALSE);
1567 * ldm_greeter_get_can_shutdown:
1568 * @greeter: A #LdmGreeter
1570 * Checks if the greeter is authorized to do a system shutdown.
1572 * Return value: TRUE if the greeter can shutdown the system
1575 ldm_greeter_get_can_shutdown (LdmGreeter *greeter)
1577 g_return_val_if_fail (LDM_IS_GREETER (greeter), FALSE);
1578 return ck_call_function (greeter, "CanStop", TRUE);
1582 * ldm_greeter_shutdown:
1583 * @greeter: A #LdmGreeter
1585 * Triggers a system shutdown.
1588 ldm_greeter_shutdown (LdmGreeter *greeter)
1590 g_return_if_fail (LDM_IS_GREETER (greeter));
1591 ck_call_function (greeter, "Stop", FALSE);
1595 * ldm_greeter_get_user_defaults:
1596 * @greeter: A #LdmGreeter
1597 * @username: The user to check
1598 * @language: (out): Default language for this user.
1599 * @layout: (out): Default keyboard layout for this user.
1600 * @session: (out): Default session for this user.
1602 * Get the default settings for a given user. If the user does not exist FALSE
1603 * is returned and language, layout and session are not set.
1605 * Return value: TRUE if this user exists.
1608 ldm_greeter_get_user_defaults (LdmGreeter *greeter, const gchar *username, gchar **language, gchar **layout, gchar **session)
1613 g_return_val_if_fail (LDM_IS_GREETER (greeter), FALSE);
1614 g_return_val_if_fail (username != NULL, FALSE);
1616 write_header (greeter, GREETER_MESSAGE_GET_USER_DEFAULTS, string_length (username));
1617 write_string (greeter, username);
1620 if (!read_packet (greeter, TRUE))
1622 g_warning ("Error reading user defaults from server");
1626 id = read_int (greeter, &offset);
1627 g_assert (id == GREETER_MESSAGE_USER_DEFAULTS);
1628 read_int (greeter, &offset);
1629 *language = read_string (greeter, &offset);
1630 *layout = read_string (greeter, &offset);
1631 *session = read_string (greeter, &offset);
1633 g_debug ("User defaults for %s: language=%s, layout=%s, session=%s", username, *language, *layout, *session);
1635 greeter->priv->n_read = 0;
1641 ldm_greeter_init (LdmGreeter *greeter)
1643 greeter->priv = G_TYPE_INSTANCE_GET_PRIVATE (greeter, LDM_TYPE_GREETER, LdmGreeterPrivate);
1644 greeter->priv->read_buffer = g_malloc (HEADER_SIZE);
1646 g_debug ("default-language=%s", ldm_greeter_get_default_language (greeter));
1650 ldm_greeter_set_property (GObject *object,
1652 const GValue *value,
1657 self = LDM_GREETER (object);
1661 ldm_greeter_set_layout(self, g_value_get_string (value));
1664 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1670 ldm_greeter_get_property (GObject *object,
1677 self = LDM_GREETER (object);
1681 g_value_set_string (value, ldm_greeter_get_hostname (self));
1683 case PROP_NUM_USERS:
1684 g_value_set_int (value, ldm_greeter_get_num_users (self));
1688 case PROP_DEFAULT_LANGUAGE:
1689 g_value_set_string (value, ldm_greeter_get_default_language (self));
1694 g_value_set_string (value, ldm_greeter_get_layout (self));
1698 case PROP_DEFAULT_SESSION:
1699 g_value_set_string (value, ldm_greeter_get_default_session (self));
1701 case PROP_TIMED_LOGIN_USER:
1702 g_value_set_string (value, ldm_greeter_get_timed_login_user (self));
1704 case PROP_TIMED_LOGIN_DELAY:
1705 g_value_set_int (value, ldm_greeter_get_timed_login_delay (self));
1707 case PROP_AUTHENTICATION_USER:
1708 g_value_set_string (value, ldm_greeter_get_authentication_user (self));
1710 case PROP_IN_AUTHENTICATION:
1711 g_value_set_boolean (value, ldm_greeter_get_in_authentication (self));
1713 case PROP_IS_AUTHENTICATED:
1714 g_value_set_boolean (value, ldm_greeter_get_is_authenticated (self));
1716 case PROP_CAN_SUSPEND:
1717 g_value_set_boolean (value, ldm_greeter_get_can_suspend (self));
1719 case PROP_CAN_HIBERNATE:
1720 g_value_set_boolean (value, ldm_greeter_get_can_hibernate (self));
1722 case PROP_CAN_RESTART:
1723 g_value_set_boolean (value, ldm_greeter_get_can_restart (self));
1725 case PROP_CAN_SHUTDOWN:
1726 g_value_set_boolean (value, ldm_greeter_get_can_shutdown (self));
1729 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1735 ldm_greeter_class_init (LdmGreeterClass *klass)
1737 GObjectClass *object_class = G_OBJECT_CLASS (klass);
1739 g_type_class_add_private (klass, sizeof (LdmGreeterPrivate));
1741 object_class->set_property = ldm_greeter_set_property;
1742 object_class->get_property = ldm_greeter_get_property;
1744 g_object_class_install_property (object_class,
1746 g_param_spec_string ("hostname",
1748 "Hostname displaying greeter for",
1751 g_object_class_install_property (object_class,
1753 g_param_spec_int ("num-users",
1755 "Number of login users",
1758 /*g_object_class_install_property (object_class,
1760 g_param_spec_list ("users",
1762 "Users that can login"));
1763 g_object_class_install_property (object_class,
1764 PROP_DEFAULT_LANGUAGE,
1765 g_param_spec_string ("default-language",
1769 G_PARAM_READWRITE));
1770 g_object_class_install_property (object_class,
1772 g_param_spec_list ("layouts",
1774 "Available keyboard layouts"));*/
1775 g_object_class_install_property (object_class,
1777 g_param_spec_string ("layout",
1779 "Current keyboard layout",
1781 G_PARAM_READWRITE));
1782 /*g_object_class_install_property (object_class,
1784 g_param_spec_list ("sessions",
1786 "Available sessions"));*/
1787 g_object_class_install_property (object_class,
1788 PROP_DEFAULT_SESSION,
1789 g_param_spec_string ("default-session",
1793 G_PARAM_READWRITE));
1794 g_object_class_install_property (object_class,
1795 PROP_TIMED_LOGIN_USER,
1796 g_param_spec_string ("timed-login-user",
1798 "User to login as when timed expires",
1801 g_object_class_install_property (object_class,
1802 PROP_TIMED_LOGIN_DELAY,
1803 g_param_spec_int ("login-delay",
1805 "Number of seconds until logging in as default user",
1806 G_MININT, G_MAXINT, 0,
1808 g_object_class_install_property (object_class,
1809 PROP_AUTHENTICATION_USER,
1810 g_param_spec_string ("authentication-user",
1811 "authentication-user",
1812 "The user being authenticated",
1815 g_object_class_install_property (object_class,
1816 PROP_IN_AUTHENTICATION,
1817 g_param_spec_boolean ("in-authentication",
1818 "in-authentication",
1819 "TRUE if a user is being authenticated",
1822 g_object_class_install_property (object_class,
1823 PROP_IS_AUTHENTICATED,
1824 g_param_spec_boolean ("is-authenticated",
1826 "TRUE if the selected user is authenticated",
1829 g_object_class_install_property (object_class,
1831 g_param_spec_boolean ("can-suspend",
1833 "TRUE if allowed to suspend the system",
1836 g_object_class_install_property (object_class,
1838 g_param_spec_boolean ("can-hibernate",
1840 "TRUE if allowed to hibernate the system",
1843 g_object_class_install_property (object_class,
1845 g_param_spec_boolean ("can-restart",
1847 "TRUE if allowed to restart the system",
1850 g_object_class_install_property (object_class,
1852 g_param_spec_boolean ("can-shutdown",
1854 "TRUE if allowed to shutdown the system",
1859 * LdmGreeter::connected:
1860 * @greeter: A #LdmGreeter
1862 * The ::connected signal gets emitted when the greeter connects to the
1865 signals[CONNECTED] =
1866 g_signal_new ("connected",
1867 G_TYPE_FROM_CLASS (klass),
1869 G_STRUCT_OFFSET (LdmGreeterClass, connected),
1871 g_cclosure_marshal_VOID__VOID,
1875 * LdmGreeter::show-prompt:
1876 * @greeter: A #LdmGreeter
1877 * @text: Prompt text
1879 * The ::show-prompt signal gets emitted when the greeter should show a
1880 * prompt to the user. The given text should be displayed and an input
1881 * field for the user to provide a response.
1883 * Call ldm_greeter_provide_secret() with the resultant input or
1884 * ldm_greeter_cancel_authentication() to abort the authentication.
1886 signals[SHOW_PROMPT] =
1887 g_signal_new ("show-prompt",
1888 G_TYPE_FROM_CLASS (klass),
1890 G_STRUCT_OFFSET (LdmGreeterClass, show_prompt),
1892 g_cclosure_marshal_VOID__STRING,
1893 G_TYPE_NONE, 1, G_TYPE_STRING);
1896 * LdmGreeter::show-message:
1897 * @greeter: A #LdmGreeter
1898 * @text: Message text
1900 * The ::show-message signal gets emitted when the greeter
1901 * should show an informational message to the user.
1903 signals[SHOW_MESSAGE] =
1904 g_signal_new ("show-message",
1905 G_TYPE_FROM_CLASS (klass),
1907 G_STRUCT_OFFSET (LdmGreeterClass, show_message),
1909 g_cclosure_marshal_VOID__STRING,
1910 G_TYPE_NONE, 1, G_TYPE_STRING);
1913 * LdmGreeter::show-error:
1914 * @greeter: A #LdmGreeter
1915 * @text: Message text
1917 * The ::show-error signal gets emitted when the greeter
1918 * should show an error message to the user.
1920 signals[SHOW_ERROR] =
1921 g_signal_new ("show-error",
1922 G_TYPE_FROM_CLASS (klass),
1924 G_STRUCT_OFFSET (LdmGreeterClass, show_error),
1926 g_cclosure_marshal_VOID__STRING,
1927 G_TYPE_NONE, 1, G_TYPE_STRING);
1930 * LdmGreeter::authentication-complete:
1931 * @greeter: A #LdmGreeter
1933 * The ::authentication-complete signal gets emitted when the greeter
1934 * has completed authentication.
1936 * Call ldm_greeter_get_is_authenticated() to check if the authentication
1939 signals[AUTHENTICATION_COMPLETE] =
1940 g_signal_new ("authentication-complete",
1941 G_TYPE_FROM_CLASS (klass),
1943 G_STRUCT_OFFSET (LdmGreeterClass, authentication_complete),
1945 g_cclosure_marshal_VOID__VOID,
1949 * LdmGreeter::timed-login:
1950 * @greeter: A #LdmGreeter
1951 * @username: A username
1953 * The ::timed-login signal gets emitted when the default user timer
1956 signals[TIMED_LOGIN] =
1957 g_signal_new ("timed-login",
1958 G_TYPE_FROM_CLASS (klass),
1960 G_STRUCT_OFFSET (LdmGreeterClass, timed_login),
1962 g_cclosure_marshal_VOID__STRING,
1963 G_TYPE_NONE, 1, G_TYPE_STRING);
1966 * LdmGreeter::user-added:
1967 * @greeter: A #LdmGreeter
1969 * The ::user-added signal gets emitted when a user account is created.
1971 signals[USER_ADDED] =
1972 g_signal_new ("user-added",
1973 G_TYPE_FROM_CLASS (klass),
1975 G_STRUCT_OFFSET (LdmGreeterClass, user_added),
1977 g_cclosure_marshal_VOID__OBJECT,
1978 G_TYPE_NONE, 1, LDM_TYPE_USER);
1981 * LdmGreeter::user-changed:
1982 * @greeter: A #LdmGreeter
1984 * The ::user-changed signal gets emitted when a user account is modified.
1986 signals[USER_CHANGED] =
1987 g_signal_new ("user-changed",
1988 G_TYPE_FROM_CLASS (klass),
1990 G_STRUCT_OFFSET (LdmGreeterClass, user_changed),
1992 g_cclosure_marshal_VOID__OBJECT,
1993 G_TYPE_NONE, 1, LDM_TYPE_USER);
1996 * LdmGreeter::user-removed:
1997 * @greeter: A #LdmGreeter
1999 * The ::user-removed signal gets emitted when a user account is removed.
2001 signals[USER_REMOVED] =
2002 g_signal_new ("user-removed",
2003 G_TYPE_FROM_CLASS (klass),
2005 G_STRUCT_OFFSET (LdmGreeterClass, user_removed),
2007 g_cclosure_marshal_VOID__OBJECT,
2008 G_TYPE_NONE, 1, LDM_TYPE_USER);
2012 * @greeter: A #LdmGreeter
2014 * The ::quit signal gets emitted when the greeter should exit.
2017 g_signal_new ("quit",
2018 G_TYPE_FROM_CLASS (klass),
2020 G_STRUCT_OFFSET (LdmGreeterClass, quit),
2022 g_cclosure_marshal_VOID__VOID,