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
15 #include <sys/utsname.h>
17 #include <gio/gdesktopappinfo.h>
18 #include <dbus/dbus-glib.h>
19 #include <security/pam_appl.h>
20 #include <libxklavier/xklavier.h>
29 PROP_DEFAULT_LANGUAGE,
34 PROP_TIMED_LOGIN_USER,
35 PROP_TIMED_LOGIN_DELAY,
36 PROP_AUTHENTICATION_USER,
37 PROP_IS_AUTHENTICATED,
48 AUTHENTICATION_COMPLETE,
53 static guint signals[LAST_SIGNAL] = { 0 };
55 struct _LdmGreeterPrivate
57 DBusGConnection *lightdm_bus;
59 DBusGConnection *system_bus;
61 DBusGProxy *display_proxy, *session_proxy, *user_proxy;
73 gchar *default_language;
74 gboolean have_languages;
77 gchar *default_layout;
78 XklEngine *xkl_engine;
79 XklConfigRec *xkl_config;
80 gboolean have_layouts;
84 gboolean have_sessions;
86 gchar *default_session;
88 gchar *authentication_user;
89 gboolean is_authenticated;
96 G_DEFINE_TYPE (LdmGreeter, ldm_greeter, G_TYPE_OBJECT);
101 * Create a new greeter.
103 * Return value: the new #LdmGreeter
108 return g_object_new (LDM_TYPE_GREETER, NULL);
112 timed_login_cb (gpointer data)
114 LdmGreeter *greeter = data;
116 greeter->priv->login_timeout = 0;
117 g_signal_emit (G_OBJECT (greeter), signals[TIMED_LOGIN], 0, greeter->priv->timed_user);
123 quit_cb (DBusGProxy *proxy, LdmGreeter *greeter)
125 g_signal_emit (G_OBJECT (greeter), signals[QUIT], 0);
129 * ldm_greeter_connect:
130 * @greeter: The greeter to connect
132 * Connects the greeter to the display manager.
134 * Return value: TRUE if successfully connected
137 ldm_greeter_connect (LdmGreeter *greeter)
139 GError *error = NULL;
140 const gchar *bus_address, *object;
141 DBusBusType bus_type = DBUS_BUS_SYSTEM;
144 g_return_val_if_fail (greeter != NULL, FALSE);
146 greeter->priv->system_bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
147 if (!greeter->priv->system_bus)
148 g_warning ("Failed to connect to system bus: %s", error->message);
149 g_clear_error (&error);
150 if (!greeter->priv->system_bus)
153 bus_address = getenv ("LDM_BUS");
154 if (bus_address && strcmp (bus_address, "SESSION") == 0)
155 bus_type = DBUS_BUS_SESSION;
157 greeter->priv->lightdm_bus = dbus_g_bus_get (bus_type, &error);
158 if (!greeter->priv->lightdm_bus)
159 g_warning ("Failed to connect to LightDM bus: %s", error->message);
160 g_clear_error (&error);
161 if (!greeter->priv->lightdm_bus)
164 object = getenv ("LDM_DISPLAY");
167 g_warning ("No LDM_DISPLAY enviroment variable");
171 greeter->priv->display_proxy = dbus_g_proxy_new_for_name (greeter->priv->lightdm_bus,
172 "org.lightdm.LightDisplayManager",
174 "org.lightdm.LightDisplayManager.Greeter");
175 dbus_g_proxy_add_signal (greeter->priv->display_proxy, "QuitGreeter", G_TYPE_INVALID);
176 dbus_g_proxy_connect_signal (greeter->priv->display_proxy, "QuitGreeter", G_CALLBACK (quit_cb), greeter, NULL);
177 greeter->priv->session_proxy = dbus_g_proxy_new_for_name (greeter->priv->lightdm_bus,
178 "org.lightdm.LightDisplayManager",
179 "/org/lightdm/LightDisplayManager/Session",
180 "org.lightdm.LightDisplayManager.Session");
181 greeter->priv->user_proxy = dbus_g_proxy_new_for_name (greeter->priv->lightdm_bus,
182 "org.lightdm.LightDisplayManager",
183 "/org/lightdm/LightDisplayManager/Users",
184 "org.lightdm.LightDisplayManager.Users");
186 g_debug ("Connecting to display manager...");
187 result = dbus_g_proxy_call (greeter->priv->display_proxy, "Connect", &error,
189 G_TYPE_STRING, &greeter->priv->theme,
190 G_TYPE_STRING, &greeter->priv->default_language,
191 G_TYPE_STRING, &greeter->priv->default_layout,
192 G_TYPE_STRING, &greeter->priv->default_session,
193 G_TYPE_STRING, &greeter->priv->timed_user,
194 G_TYPE_INT, &greeter->priv->login_delay,
196 g_debug ("Connected theme=%s default-language=%s default-layout=%s default-session=%s timed-user=%s login-delay=%d",
197 greeter->priv->theme,
198 greeter->priv->default_language, greeter->priv->default_layout, greeter->priv->default_session,
199 greeter->priv->timed_user, greeter->priv->login_delay);
202 g_warning ("Failed to connect to display manager: %s", error->message);
203 g_clear_error (&error);
207 /* Set timeout for default login */
208 if (greeter->priv->timed_user[0] != '\0' && greeter->priv->login_delay > 0)
210 g_debug ("Logging in as %s in %d seconds", greeter->priv->timed_user, greeter->priv->login_delay);
211 greeter->priv->login_timeout = g_timeout_add (greeter->priv->login_delay * 1000, timed_login_cb, greeter);
218 * ldm_greeter_get_hostname:
219 * @greeter: a #LdmGreeter
221 * Return value: The host this greeter is displaying
224 ldm_greeter_get_hostname (LdmGreeter *greeter)
226 g_return_val_if_fail (greeter != NULL, NULL);
228 if (!greeter->priv->hostname)
232 greeter->priv->hostname = g_strdup (info.nodename);
235 return greeter->priv->hostname;
239 * ldm_greeter_get_theme:
240 * @greeter: a #LdmGreeter
242 * Return value: The theme this greeter is using
245 ldm_greeter_get_theme (LdmGreeter *greeter)
247 g_return_val_if_fail (greeter != NULL, NULL);
248 return greeter->priv->theme;
252 load_theme (LdmGreeter *greeter)
254 GError *error = NULL;
256 if (greeter->priv->theme_file)
259 greeter->priv->theme_file = g_key_file_new ();
260 if (!g_key_file_load_from_file (greeter->priv->theme_file, greeter->priv->theme, G_KEY_FILE_NONE, &error))
261 g_warning ("Failed to read theme file: %s", error->message);
262 g_clear_error (&error);
266 * ldm_greeter_get_string_property:
267 * @greeter: a #LdmGreeter
268 * @name: the name of the property to get
270 * Return value: The value of this property or NULL if it is not defined
273 ldm_greeter_get_string_property (LdmGreeter *greeter, const gchar *name)
275 GError *error = NULL;
278 g_return_val_if_fail (greeter != NULL, NULL);
280 load_theme (greeter);
282 result = g_key_file_get_string (greeter->priv->theme_file, "theme", name, &error);
284 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
285 g_clear_error (&error);
291 * ldm_greeter_get_integer_property:
292 * @greeter: a #LdmGreeter
293 * @name: the name of the property to get
295 * Return value: The value of this property or 0 if it is not defined
298 ldm_greeter_get_integer_property (LdmGreeter *greeter, const gchar *name)
300 GError *error = NULL;
303 g_return_val_if_fail (greeter != NULL, 0);
305 load_theme (greeter);
307 result = g_key_file_get_integer (greeter->priv->theme_file, "theme", name, &error);
309 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
310 g_clear_error (&error);
316 * ldm_greeter_get_boolean_property:
317 * @greeter: a #LdmGreeter
318 * @name: the name of the property to get
320 * Return value: The value of this property or FALSE if it is not defined
323 ldm_greeter_get_boolean_property (LdmGreeter *greeter, const gchar *name)
325 GError *error = NULL;
328 g_return_val_if_fail (greeter != NULL, FALSE);
330 load_theme (greeter);
332 result = g_key_file_get_boolean (greeter->priv->theme_file, "theme", name, &error);
334 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
335 g_clear_error (&error);
340 #define TYPE_USER dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INVALID)
341 #define TYPE_USER_LIST dbus_g_type_get_collection ("GPtrArray", TYPE_USER)
344 update_users (LdmGreeter *greeter)
349 GError *error = NULL;
351 if (greeter->priv->have_users)
354 g_debug ("Getting user list...");
355 result = dbus_g_proxy_call (greeter->priv->user_proxy, "GetUsers", &error,
357 TYPE_USER_LIST, &users,
360 g_warning ("Failed to get users: %s", error->message);
361 g_clear_error (&error);
366 g_debug ("Got %d users", users->len);
367 for (i = 0; i < users->len; i++)
369 GValue value = { 0 };
371 gchar *name, *real_name, *image;
374 g_value_init (&value, TYPE_USER);
375 g_value_set_static_boxed (&value, users->pdata[i]);
376 dbus_g_type_struct_get (&value, 0, &name, 1, &real_name, 2, &image, 3, &logged_in, G_MAXUINT);
377 g_value_unset (&value);
379 user = ldm_user_new (greeter, name, real_name, image, logged_in);
384 greeter->priv->users = g_list_append (greeter->priv->users, user);
387 g_ptr_array_free (users, TRUE);
389 greeter->priv->have_users = TRUE;
393 * ldm_greeter_get_num_users:
394 * @greeter: a #LdmGreeter
396 * Return value: The number of users able to log in
399 ldm_greeter_get_num_users (LdmGreeter *greeter)
401 g_return_val_if_fail (greeter != NULL, 0);
402 update_users (greeter);
403 return g_list_length (greeter->priv->users);
407 * ldm_greeter_get_users:
408 * @greeter: A #LdmGreeter
410 * Get a list of users to present to the user. This list may be a subset of the
411 * available users and may be empty depending on the server configuration.
413 * Return value: A list of #LdmUser that should be presented to the user.
416 ldm_greeter_get_users (LdmGreeter *greeter)
418 g_return_val_if_fail (greeter != NULL, NULL);
419 update_users (greeter);
420 return greeter->priv->users;
424 update_languages (LdmGreeter *greeter)
426 gchar *stdout_text = NULL, *stderr_text = NULL;
429 GError *error = NULL;
431 if (greeter->priv->have_languages)
434 result = g_spawn_command_line_sync ("locale -a", &stdout_text, &stderr_text, &exit_status, &error);
435 if (!result || exit_status != 0)
436 g_warning ("Failed to get languages, locale -a returned %d: %s", exit_status, error->message);
442 tokens = g_strsplit_set (stdout_text, "\n\r", -1);
443 for (i = 0; tokens[i]; i++)
445 LdmLanguage *language;
448 code = g_strchug (tokens[i]);
452 /* Ignore the non-interesting languages */
453 if (strcmp (code, "C") == 0 || strcmp (code, "POSIX") == 0)
456 language = ldm_language_new (code);
457 greeter->priv->languages = g_list_append (greeter->priv->languages, language);
463 g_clear_error (&error);
464 g_free (stdout_text);
465 g_free (stderr_text);
467 greeter->priv->have_languages = TRUE;
471 * ldm_greeter_get_default_language:
472 * @greeter: A #LdmGreeter
474 * Get the default language.
476 * Return value: The default language.
479 ldm_greeter_get_default_language (LdmGreeter *greeter)
481 g_return_val_if_fail (greeter != NULL, NULL);
482 return greeter->priv->default_language;
486 * ldm_greeter_get_languages:
487 * @greeter: A #LdmGreeter
489 * Get a list of languages to present to the user.
491 * Return value: A list of #LdmLanguage that should be presented to the user.
494 ldm_greeter_get_languages (LdmGreeter *greeter)
496 g_return_val_if_fail (greeter != NULL, NULL);
497 update_languages (greeter);
498 return greeter->priv->languages;
502 ldm_greeter_get_default_layout (LdmGreeter *greeter)
504 g_return_val_if_fail (greeter != NULL, NULL);
505 return greeter->priv->default_layout;
509 layout_cb (XklConfigRegistry *config,
510 const XklConfigItem *item,
513 LdmGreeter *greeter = data;
516 layout = ldm_layout_new (item->name, item->short_description, item->description);
517 greeter->priv->layouts = g_list_append (greeter->priv->layouts, layout);
521 setup_display (LdmGreeter *greeter)
523 if (!greeter->priv->display)
524 greeter->priv->display = XOpenDisplay (NULL);
528 setup_xkl (LdmGreeter *greeter)
530 setup_display (greeter);
531 greeter->priv->xkl_engine = xkl_engine_get_instance (greeter->priv->display);
532 greeter->priv->xkl_config = xkl_config_rec_new ();
533 if (!xkl_config_rec_get_from_server (greeter->priv->xkl_config, greeter->priv->xkl_engine))
534 g_warning ("Failed to get Xkl configuration from server");
535 greeter->priv->layout = g_strdup (greeter->priv->xkl_config->layouts[0]);
539 * ldm_greeter_get_layouts:
540 * @greeter: A #LdmGreeter
542 * Get a list of keyboard layouts to present to the user.
544 * Return value: A list of #LdmLayout that should be presented to the user.
547 ldm_greeter_get_layouts (LdmGreeter *greeter)
549 XklConfigRegistry *registry;
551 g_return_val_if_fail (greeter != NULL, NULL);
553 if (greeter->priv->have_layouts)
554 return greeter->priv->layouts;
558 registry = xkl_config_registry_get_instance (greeter->priv->xkl_engine);
559 xkl_config_registry_load (registry, FALSE);
560 xkl_config_registry_foreach_layout (registry, layout_cb, greeter);
561 g_object_unref (registry);
562 greeter->priv->have_layouts = TRUE;
564 return greeter->priv->layouts;
568 * ldm_greeter_set_layout:
569 * @greeter: A #LdmGreeter
570 * @layout: The layout to use
572 * Set the layout for this session.
575 ldm_greeter_set_layout (LdmGreeter *greeter, const gchar *layout)
577 XklConfigRec *config;
579 g_return_if_fail (LDM_IS_GREETER (greeter));
580 g_return_if_fail (layout != NULL);
584 config = xkl_config_rec_new ();
585 config->layouts = g_malloc (sizeof (gchar *) * 2);
586 config->model = g_strdup (greeter->priv->xkl_config->model);
587 config->layouts[0] = g_strdup (layout);
588 config->layouts[1] = NULL;
589 if (!xkl_config_rec_activate (config, greeter->priv->xkl_engine))
590 g_warning ("Failed to activate XKL config");
592 greeter->priv->layout = g_strdup (layout);
593 g_object_unref (config);
597 * ldm_greeter_get_layout:
598 * @greeter: A #LdmGreeter
600 * Get the current keyboard layout.
602 * Return value: The currently active layout for this user.
605 ldm_greeter_get_layout (LdmGreeter *greeter)
607 g_return_val_if_fail (greeter != NULL, NULL);
609 return greeter->priv->layout;
613 update_sessions (LdmGreeter *greeter)
616 GError *error = NULL;
618 if (greeter->priv->have_sessions)
621 directory = g_dir_open (XSESSIONS_DIR, 0, &error);
623 g_warning ("Failed to open sessions directory: %s", error->message);
624 g_clear_error (&error);
630 const gchar *filename;
635 filename = g_dir_read_name (directory);
636 if (filename == NULL)
639 if (!g_str_has_suffix (filename, ".desktop"))
642 key = g_strndup (filename, strlen (filename) - strlen (".desktop"));
643 path = g_build_filename (XSESSIONS_DIR, filename, NULL);
644 g_debug ("Loading session %s", path);
646 key_file = g_key_file_new ();
647 result = g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, &error);
649 g_warning ("Failed to load session file %s: %s:", path, error->message);
650 g_clear_error (&error);
652 if (result && !g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY, NULL))
654 gchar *domain, *name, *comment;
656 #ifdef G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN
657 domain = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN, NULL);
659 domain = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GNOME-Gettext-Domain", NULL);
661 name = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, domain, NULL);
662 comment = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_COMMENT, domain, NULL);
664 comment = g_strdup ("");
667 g_debug ("Loaded session %s (%s, %s)", key, name, comment);
668 greeter->priv->sessions = g_list_append (greeter->priv->sessions, ldm_session_new (key, name, comment));
671 g_warning ("Invalid session %s: %s", path, error->message);
672 g_clear_error (&error);
680 g_key_file_free (key_file);
683 g_dir_close (directory);
685 greeter->priv->have_sessions = TRUE;
689 * ldm_greeter_get_sessions:
690 * @greeter: A #LdmGreeter
692 * Get the available sessions.
694 * Return value: A list of #LdmSession
697 ldm_greeter_get_sessions (LdmGreeter *greeter)
699 g_return_val_if_fail (greeter != NULL, NULL);
700 update_sessions (greeter);
701 return greeter->priv->sessions;
705 * ldm_greeter_get_default_session:
706 * @greeter: A #LdmGreeter
708 * Get the default session to use.
710 * Return value: The session name
713 ldm_greeter_get_default_session (LdmGreeter *greeter)
715 g_return_val_if_fail (greeter != NULL, NULL);
716 return greeter->priv->default_session;
720 * ldm_greeter_get_timed_login_user:
721 * @greeter: A #LdmGreeter
723 * Get the user to log in by as default.
725 * Return value: A username
728 ldm_greeter_get_timed_login_user (LdmGreeter *greeter)
730 g_return_val_if_fail (greeter != NULL, NULL);
731 return greeter->priv->timed_user;
735 * ldm_greeter_get_timed_login_delay:
736 * @greeter: A #LdmGreeter
738 * Get the number of seconds to wait until logging in as the default user.
740 * Return value: The number of seconds before logging in as the default user
743 ldm_greeter_get_timed_login_delay (LdmGreeter *greeter)
745 g_return_val_if_fail (greeter != NULL, 0);
746 return greeter->priv->login_delay;
750 * ldm_greeter_cancel_timed_login:
751 * @greeter: A #LdmGreeter
753 * Cancel the login as the default user.
756 ldm_greeter_cancel_timed_login (LdmGreeter *greeter)
758 g_return_if_fail (LDM_IS_GREETER (greeter));
760 if (greeter->priv->login_timeout)
761 g_source_remove (greeter->priv->login_timeout);
762 greeter->priv->login_timeout = 0;
765 #define TYPE_MESSAGE dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_STRING, G_TYPE_INVALID)
766 #define TYPE_MESSAGE_LIST dbus_g_type_get_collection ("GPtrArray", TYPE_MESSAGE)
769 auth_response_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer userdata)
771 LdmGreeter *greeter = userdata;
773 GError *error = NULL;
778 result = dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INT, &return_code, TYPE_MESSAGE_LIST, &array, G_TYPE_INVALID);
780 g_warning ("Failed to complete StartAuthentication(): %s", error->message);
781 g_clear_error (&error);
786 g_debug ("Authentication continues with %d messages", array->len);
788 g_debug ("Authentication complete with return code %d", return_code);
790 for (i = 0; i < array->len; i++)
792 GValue value = { 0 };
796 g_value_init (&value, TYPE_MESSAGE);
797 g_value_set_static_boxed (&value, array->pdata[i]);
798 dbus_g_type_struct_get (&value, 0, &msg_style, 1, &msg, G_MAXUINT);
800 // FIXME: Should stop on prompts?
803 case PAM_PROMPT_ECHO_OFF:
804 case PAM_PROMPT_ECHO_ON:
805 g_signal_emit (G_OBJECT (greeter), signals[SHOW_PROMPT], 0, msg);
808 g_signal_emit (G_OBJECT (greeter), signals[SHOW_ERROR], 0, msg);
811 g_signal_emit (G_OBJECT (greeter), signals[SHOW_MESSAGE], 0, msg);
817 g_value_unset (&value);
822 greeter->priv->is_authenticated = (return_code == 0);
823 if (!greeter->priv->is_authenticated)
825 g_free (greeter->priv->authentication_user);
826 greeter->priv->authentication_user = NULL;
828 g_signal_emit (G_OBJECT (greeter), signals[AUTHENTICATION_COMPLETE], 0);
831 g_ptr_array_unref (array);
835 * ldm_greeter_start_authentication:
836 * @greeter: A #LdmGreeter
837 * @username: A username
839 * Starts the authentication procedure for a user.
842 ldm_greeter_start_authentication (LdmGreeter *greeter, const char *username)
844 g_return_if_fail (LDM_IS_GREETER (greeter));
845 g_return_if_fail (username != NULL);
847 greeter->priv->is_authenticated = FALSE;
848 g_free (greeter->priv->authentication_user);
849 greeter->priv->authentication_user = g_strdup (username);
850 g_debug ("Starting authentication for user %s...", username);
851 dbus_g_proxy_begin_call (greeter->priv->display_proxy, "StartAuthentication", auth_response_cb, greeter, NULL, G_TYPE_STRING, username, G_TYPE_INVALID);
855 * ldm_greeter_provide_secret:
856 * @greeter: A #LdmGreeter
857 * @secret: Response to a prompt
859 * Provide secret information from a prompt.
862 ldm_greeter_provide_secret (LdmGreeter *greeter, const gchar *secret)
866 g_return_if_fail (LDM_IS_GREETER (greeter));
867 g_return_if_fail (secret != NULL);
869 // FIXME: Could be multiple secrets required
870 secrets = g_malloc (sizeof (char *) * 2);
871 secrets[0] = g_strdup (secret);
873 g_debug ("Providing secret to display manager");
874 dbus_g_proxy_begin_call (greeter->priv->display_proxy, "ContinueAuthentication", auth_response_cb, greeter, NULL, G_TYPE_STRV, secrets, G_TYPE_INVALID);
878 * ldm_greeter_cancel_authentication:
879 * @greeter: A #LdmGreeter
881 * Cancel the current user authentication.
884 ldm_greeter_cancel_authentication (LdmGreeter *greeter)
886 g_return_if_fail (LDM_IS_GREETER (greeter));
890 * ldm_greeter_get_is_authenticated:
891 * @greeter: A #LdmGreeter
893 * Checks if the greeter has successfully authenticated.
895 * Return value: TRUE if the greeter is authenticated for login.
898 ldm_greeter_get_is_authenticated (LdmGreeter *greeter)
900 g_return_val_if_fail (greeter != NULL, FALSE);
901 return greeter->priv->is_authenticated;
905 * ldm_greeter_get_authentication_user:
906 * @greeter: A #LdmGreeter
908 * Get the user that is being authenticated.
910 * Return value: The username of the authentication user being authenticated or NULL if no authentication in progress.
913 ldm_greeter_get_authentication_user (LdmGreeter *greeter)
915 g_return_val_if_fail (greeter != NULL, NULL);
916 return greeter->priv->authentication_user;
921 * @greeter: A #LdmGreeter
922 * @username: The user to log in as
923 * @session: The session to log into or NULL to use the default
924 * @language: The language to use or NULL to use the default
926 * Login a user to a session
929 ldm_greeter_login (LdmGreeter *greeter, const gchar *username, const gchar *session, const gchar *language)
931 GError *error = NULL;
933 g_return_if_fail (LDM_IS_GREETER (greeter));
934 g_return_if_fail (username != NULL);
936 g_debug ("Logging in");
937 if (!dbus_g_proxy_call (greeter->priv->display_proxy, "Login", &error,
938 G_TYPE_STRING, username,
939 G_TYPE_STRING, session ? session : "",
940 G_TYPE_STRING, language ? language : "",
943 g_warning ("Failed to login: %s", error->message);
944 g_clear_error (&error);
948 * ldm_greeter_get_can_suspend:
949 * @greeter: A #LdmGreeter
951 * Checks if the greeter is authorized to do a system suspend.
953 * Return value: TRUE if the greeter can suspend the system
956 ldm_greeter_get_can_suspend (LdmGreeter *greeter)
959 gboolean result = TRUE;
960 GError *error = NULL;
962 g_return_val_if_fail (greeter != NULL, FALSE);
964 proxy = dbus_g_proxy_new_for_name (greeter->priv->system_bus,
965 "org.freedesktop.UPower",
966 "/org/freedesktop/UPower",
967 "org.freedesktop.UPower");
968 if (!dbus_g_proxy_call (proxy, "SuspendAllowed", &error, G_TYPE_INVALID, G_TYPE_BOOLEAN, &result, G_TYPE_INVALID))
969 g_warning ("Error checking for suspend authority: %s", error->message);
970 g_clear_error (&error);
972 g_object_unref (proxy);
978 * ldm_greeter_suspend:
979 * @greeter: A #LdmGreeter
981 * Triggers a system suspend.
984 ldm_greeter_suspend (LdmGreeter *greeter)
987 GError *error = NULL;
989 g_return_if_fail (LDM_IS_GREETER (greeter));
991 proxy = dbus_g_proxy_new_for_name (greeter->priv->system_bus,
992 "org.freedesktop.UPower",
993 "/org/freedesktop/UPower",
994 "org.freedesktop.UPower");
995 if (!dbus_g_proxy_call (proxy, "Suspend", &error, G_TYPE_INVALID, G_TYPE_INVALID))
996 g_warning ("Failed to hibernate: %s", error->message);
997 g_clear_error (&error);
999 g_object_unref (proxy);
1003 * ldm_greeter_get_can_hibernate:
1004 * @greeter: A #LdmGreeter
1006 * Checks if the greeter is authorized to do a system hibernate.
1008 * Return value: TRUE if the greeter can hibernate the system
1011 ldm_greeter_get_can_hibernate (LdmGreeter *greeter)
1014 gboolean result = FALSE;
1015 GError *error = NULL;
1017 g_return_val_if_fail (greeter != NULL, FALSE);
1019 proxy = dbus_g_proxy_new_for_name (greeter->priv->system_bus,
1020 "org.freedesktop.UPower",
1021 "/org/freedesktop/UPower",
1022 "org.freedesktop.UPower");
1023 if (!dbus_g_proxy_call (proxy, "HibernateAllowed", &error, G_TYPE_INVALID, G_TYPE_BOOLEAN, &result, G_TYPE_INVALID))
1024 g_warning ("Error checking for hibernate authority: %s", error->message);
1025 g_clear_error (&error);
1027 g_object_unref (proxy);
1033 * ldm_greeter_hibernate:
1034 * @greeter: A #LdmGreeter
1036 * Triggers a system hibernate.
1039 ldm_greeter_hibernate (LdmGreeter *greeter)
1042 GError *error = NULL;
1044 g_return_if_fail (LDM_IS_GREETER (greeter));
1046 proxy = dbus_g_proxy_new_for_name (greeter->priv->system_bus,
1047 "org.freedesktop.UPower",
1048 "/org/freedesktop/UPower",
1049 "org.freedesktop.UPower");
1050 if (!dbus_g_proxy_call (proxy, "Hibernate", &error, G_TYPE_INVALID, G_TYPE_INVALID))
1051 g_warning ("Failed to hibernate: %s", error->message);
1052 g_clear_error (&error);
1054 g_object_unref (proxy);
1058 * ldm_greeter_get_can_restart:
1059 * @greeter: A #LdmGreeter
1061 * Checks if the greeter is authorized to do a system restart.
1063 * Return value: TRUE if the greeter can restart the system
1066 ldm_greeter_get_can_restart (LdmGreeter *greeter)
1069 gboolean result = FALSE;
1070 GError *error = NULL;
1072 g_return_val_if_fail (greeter != NULL, FALSE);
1074 proxy = dbus_g_proxy_new_for_name (greeter->priv->system_bus,
1075 "org.freedesktop.ConsoleKit",
1076 "/org/freedesktop/ConsoleKit/Manager",
1077 "org.freedesktop.ConsoleKit.Manager");
1078 if (!dbus_g_proxy_call (proxy, "CanRestart", &error, G_TYPE_INVALID, G_TYPE_BOOLEAN, &result, G_TYPE_INVALID))
1079 g_warning ("Error checking for restart authority: %s", error->message);
1080 g_clear_error (&error);
1082 g_object_unref (proxy);
1088 * ldm_greeter_restart:
1089 * @greeter: A #LdmGreeter
1091 * Triggers a system restart.
1094 ldm_greeter_restart (LdmGreeter *greeter)
1097 GError *error = NULL;
1099 g_return_if_fail (LDM_IS_GREETER (greeter));
1101 proxy = dbus_g_proxy_new_for_name (greeter->priv->system_bus,
1102 "org.freedesktop.ConsoleKit",
1103 "/org/freedesktop/ConsoleKit/Manager",
1104 "org.freedesktop.ConsoleKit.Manager");
1105 if (!dbus_g_proxy_call (proxy, "Restart", &error, G_TYPE_INVALID, G_TYPE_INVALID))
1106 g_warning ("Failed to restart: %s", error->message);
1107 g_clear_error (&error);
1109 g_object_unref (proxy);
1113 * ldm_greeter_get_can_shutdown:
1114 * @greeter: A #LdmGreeter
1116 * Checks if the greeter is authorized to do a system shutdown.
1118 * Return value: TRUE if the greeter can shutdown the system
1121 ldm_greeter_get_can_shutdown (LdmGreeter *greeter)
1124 gboolean result = FALSE;
1125 GError *error = NULL;
1127 g_return_val_if_fail (greeter != NULL, FALSE);
1129 proxy = dbus_g_proxy_new_for_name (greeter->priv->system_bus,
1130 "org.freedesktop.ConsoleKit",
1131 "/org/freedesktop/ConsoleKit/Manager",
1132 "org.freedesktop.ConsoleKit.Manager");
1133 if (!dbus_g_proxy_call (proxy, "CanStop", &error, G_TYPE_INVALID, G_TYPE_BOOLEAN, &result, G_TYPE_INVALID))
1134 g_warning ("Error checking for shutdown authority: %s", error->message);
1135 g_clear_error (&error);
1137 g_object_unref (proxy);
1143 * ldm_greeter_shutdown:
1144 * @greeter: A #LdmGreeter
1146 * Triggers a system shutdown.
1149 ldm_greeter_shutdown (LdmGreeter *greeter)
1152 GError *error = NULL;
1154 g_return_if_fail (LDM_IS_GREETER (greeter));
1156 proxy = dbus_g_proxy_new_for_name (greeter->priv->system_bus,
1157 "org.freedesktop.ConsoleKit",
1158 "/org/freedesktop/ConsoleKit/Manager",
1159 "org.freedesktop.ConsoleKit.Manager");
1160 if (!dbus_g_proxy_call (proxy, "Stop", &error, G_TYPE_INVALID, G_TYPE_INVALID))
1161 g_warning ("Failed to shutdown: %s", error->message);
1162 g_clear_error (&error);
1164 g_object_unref (proxy);
1168 ldm_greeter_get_user_defaults (LdmGreeter *greeter, const gchar *username, gchar **language, gchar **layout, gchar **session)
1170 GError *error = NULL;
1173 result = dbus_g_proxy_call (greeter->priv->user_proxy, "GetUserDefaults", &error,
1174 G_TYPE_STRING, username,
1176 G_TYPE_STRING, language,
1177 G_TYPE_STRING, layout,
1178 G_TYPE_STRING, session,
1182 g_warning ("Failed to get user defaults: %s", error->message);
1183 g_clear_error (&error);
1189 ldm_greeter_init (LdmGreeter *greeter)
1191 greeter->priv = G_TYPE_INSTANCE_GET_PRIVATE (greeter, LDM_TYPE_GREETER, LdmGreeterPrivate);
1195 ldm_greeter_set_property (GObject *object,
1197 const GValue *value,
1203 self = LDM_GREETER (object);
1207 ldm_greeter_set_layout(self, g_value_get_string (value));
1210 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1216 ldm_greeter_get_property (GObject *object,
1223 self = LDM_GREETER (object);
1227 g_value_set_string (value, ldm_greeter_get_hostname (self));
1229 case PROP_NUM_USERS:
1230 g_value_set_int (value, ldm_greeter_get_num_users (self));
1234 case PROP_DEFAULT_LANGUAGE:
1235 g_value_set_string (value, ldm_greeter_get_default_language (self));
1240 g_value_set_string (value, ldm_greeter_get_layout (self));
1244 case PROP_DEFAULT_SESSION:
1245 g_value_set_string (value, ldm_greeter_get_default_session (self));
1247 case PROP_TIMED_LOGIN_USER:
1248 g_value_set_string (value, ldm_greeter_get_timed_login_user (self));
1250 case PROP_TIMED_LOGIN_DELAY:
1251 g_value_set_int (value, ldm_greeter_get_timed_login_delay (self));
1253 case PROP_AUTHENTICATION_USER:
1254 g_value_set_string (value, ldm_greeter_get_authentication_user (self));
1256 case PROP_IS_AUTHENTICATED:
1257 g_value_set_boolean (value, ldm_greeter_get_is_authenticated (self));
1259 case PROP_CAN_SUSPEND:
1260 g_value_set_boolean (value, ldm_greeter_get_can_suspend (self));
1262 case PROP_CAN_HIBERNATE:
1263 g_value_set_boolean (value, ldm_greeter_get_can_hibernate (self));
1265 case PROP_CAN_RESTART:
1266 g_value_set_boolean (value, ldm_greeter_get_can_restart (self));
1268 case PROP_CAN_SHUTDOWN:
1269 g_value_set_boolean (value, ldm_greeter_get_can_shutdown (self));
1272 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1278 ldm_greeter_class_init (LdmGreeterClass *klass)
1280 GObjectClass *object_class = G_OBJECT_CLASS (klass);
1282 g_type_class_add_private (klass, sizeof (LdmGreeterPrivate));
1284 object_class->set_property = ldm_greeter_set_property;
1285 object_class->get_property = ldm_greeter_get_property;
1287 g_object_class_install_property (object_class,
1289 g_param_spec_string ("hostname",
1291 "Hostname displaying greeter for",
1294 g_object_class_install_property (object_class,
1296 g_param_spec_int ("num-users",
1298 "Number of login users",
1301 /*g_object_class_install_property (object_class,
1303 g_param_spec_list ("users",
1305 "Users that can login"));
1306 g_object_class_install_property (object_class,
1307 PROP_DEFAULT_LANGUAGE,
1308 g_param_spec_string ("default-language",
1312 G_PARAM_READWRITE));
1313 g_object_class_install_property (object_class,
1315 g_param_spec_list ("layouts",
1317 "Available keyboard layouts"));*/
1318 g_object_class_install_property (object_class,
1320 g_param_spec_string ("layout",
1322 "Current keyboard layout",
1324 G_PARAM_READWRITE));
1325 /*g_object_class_install_property (object_class,
1327 g_param_spec_list ("sessions",
1329 "Available sessions"));*/
1330 g_object_class_install_property (object_class,
1331 PROP_DEFAULT_SESSION,
1332 g_param_spec_string ("default-session",
1336 G_PARAM_READWRITE));
1337 g_object_class_install_property (object_class,
1338 PROP_TIMED_LOGIN_USER,
1339 g_param_spec_string ("timed-login-user",
1341 "User to login as when timed expires",
1344 g_object_class_install_property (object_class,
1345 PROP_TIMED_LOGIN_DELAY,
1346 g_param_spec_int ("login-delay",
1348 "Number of seconds until logging in as default user",
1349 G_MININT, G_MAXINT, 0,
1351 g_object_class_install_property (object_class,
1352 PROP_AUTHENTICATION_USER,
1353 g_param_spec_string ("authentication-user",
1354 "authentication-user",
1355 "The user being authenticated",
1358 g_object_class_install_property (object_class,
1359 PROP_IS_AUTHENTICATED,
1360 g_param_spec_boolean ("is-authenticated",
1362 "TRUE if the selected user is authenticated",
1365 g_object_class_install_property (object_class,
1367 g_param_spec_boolean ("can-suspend",
1369 "TRUE if allowed to suspend the system",
1372 g_object_class_install_property (object_class,
1374 g_param_spec_boolean ("can-hibernate",
1376 "TRUE if allowed to hibernate the system",
1379 g_object_class_install_property (object_class,
1381 g_param_spec_boolean ("can-restart",
1383 "TRUE if allowed to restart the system",
1386 g_object_class_install_property (object_class,
1388 g_param_spec_boolean ("can-shutdown",
1390 "TRUE if allowed to shutdown the system",
1395 * LdmGreeter::show-prompt:
1396 * @greeter: A #LdmGreeter
1397 * @text: Prompt text
1399 * The ::show-prompt signal gets emitted when the greeter should show a
1400 * prompt to the user. The given text should be displayed and an input
1401 * field for the user to provide a response.
1403 * Call ldm_greeter_provide_secret() with the resultant input or
1404 * ldm_greeter_cancel_authentication() to abort the authentication.
1406 signals[SHOW_PROMPT] =
1407 g_signal_new ("show-prompt",
1408 G_TYPE_FROM_CLASS (klass),
1410 G_STRUCT_OFFSET (LdmGreeterClass, show_prompt),
1412 g_cclosure_marshal_VOID__STRING,
1413 G_TYPE_NONE, 1, G_TYPE_STRING);
1416 * LdmGreeter::show-message:
1417 * @greeter: A #LdmGreeter
1418 * @text: Message text
1420 * The ::show-message signal gets emitted when the greeter
1421 * should show an informational message to the user.
1423 signals[SHOW_MESSAGE] =
1424 g_signal_new ("show-message",
1425 G_TYPE_FROM_CLASS (klass),
1427 G_STRUCT_OFFSET (LdmGreeterClass, show_message),
1429 g_cclosure_marshal_VOID__STRING,
1430 G_TYPE_NONE, 1, G_TYPE_STRING);
1433 * LdmGreeter::show-error:
1434 * @greeter: A #LdmGreeter
1435 * @text: Message text
1437 * The ::show-error signal gets emitted when the greeter
1438 * should show an error message to the user.
1440 signals[SHOW_ERROR] =
1441 g_signal_new ("show-error",
1442 G_TYPE_FROM_CLASS (klass),
1444 G_STRUCT_OFFSET (LdmGreeterClass, show_error),
1446 g_cclosure_marshal_VOID__STRING,
1447 G_TYPE_NONE, 1, G_TYPE_STRING);
1450 * LdmGreeter::authentication-complete:
1451 * @greeter: A #LdmGreeter
1453 * The ::authentication-complete signal gets emitted when the greeter
1454 * has completed authentication.
1456 * Call ldm_greeter_get_is_authenticated() to check if the authentication
1459 signals[AUTHENTICATION_COMPLETE] =
1460 g_signal_new ("authentication-complete",
1461 G_TYPE_FROM_CLASS (klass),
1463 G_STRUCT_OFFSET (LdmGreeterClass, authentication_complete),
1465 g_cclosure_marshal_VOID__VOID,
1469 * LdmGreeter::timed-login:
1470 * @greeter: A #LdmGreeter
1471 * @username: A username
1473 * The ::timed-login signal gets emitted when the default user timer
1476 signals[TIMED_LOGIN] =
1477 g_signal_new ("timed-login",
1478 G_TYPE_FROM_CLASS (klass),
1480 G_STRUCT_OFFSET (LdmGreeterClass, timed_login),
1482 g_cclosure_marshal_VOID__STRING,
1483 G_TYPE_NONE, 1, G_TYPE_STRING);
1487 * @greeter: A #LdmGreeter
1489 * The ::quit signal gets emitted when the greeter should exit.
1492 g_signal_new ("quit",
1493 G_TYPE_FROM_CLASS (klass),
1495 G_STRUCT_OFFSET (LdmGreeterClass, quit),
1497 g_cclosure_marshal_VOID__VOID,