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,
198 g_debug ("Connected theme=%s default-language=%s default-layout=%s default-session=%s timed-user=%s login-delay=%d",
199 greeter->priv->theme,
200 greeter->priv->default_language, greeter->priv->default_layout, greeter->priv->default_session,
201 greeter->priv->timed_user, greeter->priv->login_delay);
203 g_warning ("Failed to connect to display manager: %s", error->message);
204 g_clear_error (&error);
208 /* Set timeout for default login */
209 if (greeter->priv->timed_user[0] != '\0' && greeter->priv->login_delay > 0)
211 g_debug ("Logging in as %s in %d seconds", greeter->priv->timed_user, greeter->priv->login_delay);
212 greeter->priv->login_timeout = g_timeout_add (greeter->priv->login_delay * 1000, timed_login_cb, greeter);
219 * ldm_greeter_get_hostname:
220 * @greeter: a #LdmGreeter
222 * Return value: The host this greeter is displaying
225 ldm_greeter_get_hostname (LdmGreeter *greeter)
227 g_return_val_if_fail (greeter != NULL, NULL);
229 if (!greeter->priv->hostname)
233 greeter->priv->hostname = g_strdup (info.nodename);
236 return greeter->priv->hostname;
240 * ldm_greeter_get_theme:
241 * @greeter: a #LdmGreeter
243 * Return value: The theme this greeter is using
246 ldm_greeter_get_theme (LdmGreeter *greeter)
248 g_return_val_if_fail (greeter != NULL, NULL);
249 return greeter->priv->theme;
253 load_theme (LdmGreeter *greeter)
255 GError *error = NULL;
257 if (greeter->priv->theme_file)
260 greeter->priv->theme_file = g_key_file_new ();
261 if (!g_key_file_load_from_file (greeter->priv->theme_file, greeter->priv->theme, G_KEY_FILE_NONE, &error))
262 g_warning ("Failed to read theme file: %s", error->message);
263 g_clear_error (&error);
267 * ldm_greeter_get_string_property:
268 * @greeter: a #LdmGreeter
269 * @name: the name of the property to get
271 * Return value: The value of this property or NULL if it is not defined
274 ldm_greeter_get_string_property (LdmGreeter *greeter, const gchar *name)
276 GError *error = NULL;
279 g_return_val_if_fail (greeter != NULL, NULL);
281 load_theme (greeter);
283 result = g_key_file_get_string (greeter->priv->theme_file, "theme", name, &error);
285 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
286 g_clear_error (&error);
292 * ldm_greeter_get_integer_property:
293 * @greeter: a #LdmGreeter
294 * @name: the name of the property to get
296 * Return value: The value of this property or 0 if it is not defined
299 ldm_greeter_get_integer_property (LdmGreeter *greeter, const gchar *name)
301 GError *error = NULL;
304 g_return_val_if_fail (greeter != NULL, 0);
306 load_theme (greeter);
308 result = g_key_file_get_integer (greeter->priv->theme_file, "theme", name, &error);
310 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
311 g_clear_error (&error);
317 * ldm_greeter_get_boolean_property:
318 * @greeter: a #LdmGreeter
319 * @name: the name of the property to get
321 * Return value: The value of this property or FALSE if it is not defined
324 ldm_greeter_get_boolean_property (LdmGreeter *greeter, const gchar *name)
326 GError *error = NULL;
329 g_return_val_if_fail (greeter != NULL, FALSE);
331 load_theme (greeter);
333 result = g_key_file_get_boolean (greeter->priv->theme_file, "theme", name, &error);
335 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
336 g_clear_error (&error);
341 #define TYPE_USER dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INVALID)
342 #define TYPE_USER_LIST dbus_g_type_get_collection ("GPtrArray", TYPE_USER)
345 update_users (LdmGreeter *greeter)
350 GError *error = NULL;
352 if (greeter->priv->have_users)
355 g_debug ("Getting user list...");
356 result = dbus_g_proxy_call (greeter->priv->user_proxy, "GetUsers", &error,
358 TYPE_USER_LIST, &users,
361 g_warning ("Failed to get users: %s", error->message);
362 g_clear_error (&error);
367 g_debug ("Got %d users", users->len);
368 for (i = 0; i < users->len; i++)
370 GValue value = { 0 };
372 gchar *name, *real_name, *image;
375 g_value_init (&value, TYPE_USER);
376 g_value_set_static_boxed (&value, users->pdata[i]);
377 dbus_g_type_struct_get (&value, 0, &name, 1, &real_name, 2, &image, 3, &logged_in, G_MAXUINT);
378 g_value_unset (&value);
380 user = ldm_user_new (greeter, name, real_name, image, logged_in);
385 greeter->priv->users = g_list_append (greeter->priv->users, user);
388 g_ptr_array_free (users, TRUE);
390 greeter->priv->have_users = TRUE;
394 * ldm_greeter_get_num_users:
395 * @greeter: a #LdmGreeter
397 * Return value: The number of users able to log in
400 ldm_greeter_get_num_users (LdmGreeter *greeter)
402 g_return_val_if_fail (greeter != NULL, 0);
403 update_users (greeter);
404 return g_list_length (greeter->priv->users);
408 * ldm_greeter_get_users:
409 * @greeter: A #LdmGreeter
411 * Get a list of users to present to the user. This list may be a subset of the
412 * available users and may be empty depending on the server configuration.
414 * Return value: A list of #LdmUser that should be presented to the user.
417 ldm_greeter_get_users (LdmGreeter *greeter)
419 g_return_val_if_fail (greeter != NULL, NULL);
420 update_users (greeter);
421 return greeter->priv->users;
425 update_languages (LdmGreeter *greeter)
427 gchar *stdout_text = NULL, *stderr_text = NULL;
430 GError *error = NULL;
432 if (greeter->priv->have_languages)
435 result = g_spawn_command_line_sync ("locale -a", &stdout_text, &stderr_text, &exit_status, &error);
436 if (!result || exit_status != 0)
437 g_warning ("Failed to get languages, locale -a returned %d: %s", exit_status, error->message);
443 tokens = g_strsplit_set (stdout_text, "\n\r", -1);
444 for (i = 0; tokens[i]; i++)
446 LdmLanguage *language;
449 code = g_strchug (tokens[i]);
453 /* Ignore the non-interesting languages */
454 if (strcmp (code, "C") == 0 || strcmp (code, "POSIX") == 0)
457 language = ldm_language_new (code);
458 greeter->priv->languages = g_list_append (greeter->priv->languages, language);
464 g_clear_error (&error);
465 g_free (stdout_text);
466 g_free (stderr_text);
468 greeter->priv->have_languages = TRUE;
472 * ldm_greeter_get_default_language:
473 * @greeter: A #LdmGreeter
475 * Get the default language.
477 * Return value: The default language.
480 ldm_greeter_get_default_language (LdmGreeter *greeter)
482 g_return_val_if_fail (greeter != NULL, NULL);
483 return greeter->priv->default_language;
487 * ldm_greeter_get_languages:
488 * @greeter: A #LdmGreeter
490 * Get a list of languages to present to the user.
492 * Return value: A list of #LdmLanguage that should be presented to the user.
495 ldm_greeter_get_languages (LdmGreeter *greeter)
497 g_return_val_if_fail (greeter != NULL, NULL);
498 update_languages (greeter);
499 return greeter->priv->languages;
503 ldm_greeter_get_default_layout (LdmGreeter *greeter)
505 g_return_val_if_fail (greeter != NULL, NULL);
506 return greeter->priv->default_layout;
510 layout_cb (XklConfigRegistry *config,
511 const XklConfigItem *item,
514 LdmGreeter *greeter = data;
517 layout = ldm_layout_new (item->name, item->short_description, item->description);
518 greeter->priv->layouts = g_list_append (greeter->priv->layouts, layout);
522 setup_display (LdmGreeter *greeter)
524 if (!greeter->priv->display)
525 greeter->priv->display = XOpenDisplay (NULL);
529 setup_xkl (LdmGreeter *greeter)
531 setup_display (greeter);
532 greeter->priv->xkl_engine = xkl_engine_get_instance (greeter->priv->display);
533 greeter->priv->xkl_config = xkl_config_rec_new ();
534 if (!xkl_config_rec_get_from_server (greeter->priv->xkl_config, greeter->priv->xkl_engine))
535 g_warning ("Failed to get Xkl configuration from server");
536 greeter->priv->layout = g_strdup (greeter->priv->xkl_config->layouts[0]);
540 * ldm_greeter_get_layouts:
541 * @greeter: A #LdmGreeter
543 * Get a list of keyboard layouts to present to the user.
545 * Return value: A list of #LdmLayout that should be presented to the user.
548 ldm_greeter_get_layouts (LdmGreeter *greeter)
550 XklConfigRegistry *registry;
552 g_return_val_if_fail (greeter != NULL, NULL);
554 if (greeter->priv->have_layouts)
555 return greeter->priv->layouts;
559 registry = xkl_config_registry_get_instance (greeter->priv->xkl_engine);
560 xkl_config_registry_load (registry, FALSE);
561 xkl_config_registry_foreach_layout (registry, layout_cb, greeter);
562 g_object_unref (registry);
563 greeter->priv->have_layouts = TRUE;
565 return greeter->priv->layouts;
569 * ldm_greeter_set_layout:
570 * @greeter: A #LdmGreeter
571 * @layout: The layout to use
573 * Set the layout for this session.
576 ldm_greeter_set_layout (LdmGreeter *greeter, const gchar *layout)
578 XklConfigRec *config;
580 g_return_if_fail (LDM_IS_GREETER (greeter));
581 g_return_if_fail (layout != NULL);
583 g_debug ("Setting keyboard layout to %s", layout);
587 config = xkl_config_rec_new ();
588 config->layouts = g_malloc (sizeof (gchar *) * 2);
589 config->model = g_strdup (greeter->priv->xkl_config->model);
590 config->layouts[0] = g_strdup (layout);
591 config->layouts[1] = NULL;
592 if (!xkl_config_rec_activate (config, greeter->priv->xkl_engine))
593 g_warning ("Failed to activate XKL config");
595 greeter->priv->layout = g_strdup (layout);
596 g_object_unref (config);
600 * ldm_greeter_get_layout:
601 * @greeter: A #LdmGreeter
603 * Get the current keyboard layout.
605 * Return value: The currently active layout for this user.
608 ldm_greeter_get_layout (LdmGreeter *greeter)
610 g_return_val_if_fail (greeter != NULL, NULL);
612 return greeter->priv->layout;
616 update_sessions (LdmGreeter *greeter)
619 GError *error = NULL;
621 if (greeter->priv->have_sessions)
624 directory = g_dir_open (XSESSIONS_DIR, 0, &error);
626 g_warning ("Failed to open sessions directory: %s", error->message);
627 g_clear_error (&error);
633 const gchar *filename;
638 filename = g_dir_read_name (directory);
639 if (filename == NULL)
642 if (!g_str_has_suffix (filename, ".desktop"))
645 key = g_strndup (filename, strlen (filename) - strlen (".desktop"));
646 path = g_build_filename (XSESSIONS_DIR, filename, NULL);
647 g_debug ("Loading session %s", path);
649 key_file = g_key_file_new ();
650 result = g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, &error);
652 g_warning ("Failed to load session file %s: %s:", path, error->message);
653 g_clear_error (&error);
655 if (result && !g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY, NULL))
657 gchar *domain, *name, *comment;
659 #ifdef G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN
660 domain = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN, NULL);
662 domain = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GNOME-Gettext-Domain", NULL);
664 name = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, domain, NULL);
665 comment = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_COMMENT, domain, NULL);
667 comment = g_strdup ("");
670 g_debug ("Loaded session %s (%s, %s)", key, name, comment);
671 greeter->priv->sessions = g_list_append (greeter->priv->sessions, ldm_session_new (key, name, comment));
674 g_warning ("Invalid session %s: %s", path, error->message);
675 g_clear_error (&error);
683 g_key_file_free (key_file);
686 g_dir_close (directory);
688 greeter->priv->have_sessions = TRUE;
692 * ldm_greeter_get_sessions:
693 * @greeter: A #LdmGreeter
695 * Get the available sessions.
697 * Return value: A list of #LdmSession
700 ldm_greeter_get_sessions (LdmGreeter *greeter)
702 g_return_val_if_fail (greeter != NULL, NULL);
703 update_sessions (greeter);
704 return greeter->priv->sessions;
708 * ldm_greeter_get_default_session:
709 * @greeter: A #LdmGreeter
711 * Get the default session to use.
713 * Return value: The session name
716 ldm_greeter_get_default_session (LdmGreeter *greeter)
718 g_return_val_if_fail (greeter != NULL, NULL);
719 return greeter->priv->default_session;
723 * ldm_greeter_get_timed_login_user:
724 * @greeter: A #LdmGreeter
726 * Get the user to log in by as default.
728 * Return value: A username
731 ldm_greeter_get_timed_login_user (LdmGreeter *greeter)
733 g_return_val_if_fail (greeter != NULL, NULL);
734 return greeter->priv->timed_user;
738 * ldm_greeter_get_timed_login_delay:
739 * @greeter: A #LdmGreeter
741 * Get the number of seconds to wait until logging in as the default user.
743 * Return value: The number of seconds before logging in as the default user
746 ldm_greeter_get_timed_login_delay (LdmGreeter *greeter)
748 g_return_val_if_fail (greeter != NULL, 0);
749 return greeter->priv->login_delay;
753 * ldm_greeter_cancel_timed_login:
754 * @greeter: A #LdmGreeter
756 * Cancel the login as the default user.
759 ldm_greeter_cancel_timed_login (LdmGreeter *greeter)
761 g_return_if_fail (LDM_IS_GREETER (greeter));
763 if (greeter->priv->login_timeout)
764 g_source_remove (greeter->priv->login_timeout);
765 greeter->priv->login_timeout = 0;
768 #define TYPE_MESSAGE dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_STRING, G_TYPE_INVALID)
769 #define TYPE_MESSAGE_LIST dbus_g_type_get_collection ("GPtrArray", TYPE_MESSAGE)
772 auth_response_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer userdata)
774 LdmGreeter *greeter = userdata;
776 GError *error = NULL;
781 result = dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INT, &return_code, TYPE_MESSAGE_LIST, &array, G_TYPE_INVALID);
783 g_warning ("Failed to complete StartAuthentication(): %s", error->message);
784 g_clear_error (&error);
789 g_debug ("Authentication continues with %d messages", array->len);
791 g_debug ("Authentication complete with return code %d", return_code);
793 for (i = 0; i < array->len; i++)
795 GValue value = { 0 };
799 g_value_init (&value, TYPE_MESSAGE);
800 g_value_set_static_boxed (&value, array->pdata[i]);
801 dbus_g_type_struct_get (&value, 0, &msg_style, 1, &msg, G_MAXUINT);
803 // FIXME: Should stop on prompts?
806 case PAM_PROMPT_ECHO_OFF:
807 case PAM_PROMPT_ECHO_ON:
808 g_signal_emit (G_OBJECT (greeter), signals[SHOW_PROMPT], 0, msg);
811 g_signal_emit (G_OBJECT (greeter), signals[SHOW_ERROR], 0, msg);
814 g_signal_emit (G_OBJECT (greeter), signals[SHOW_MESSAGE], 0, msg);
820 g_value_unset (&value);
825 greeter->priv->is_authenticated = (return_code == 0);
826 if (!greeter->priv->is_authenticated)
828 g_free (greeter->priv->authentication_user);
829 greeter->priv->authentication_user = NULL;
831 g_signal_emit (G_OBJECT (greeter), signals[AUTHENTICATION_COMPLETE], 0);
834 g_ptr_array_unref (array);
838 * ldm_greeter_start_authentication:
839 * @greeter: A #LdmGreeter
840 * @username: A username
842 * Starts the authentication procedure for a user.
845 ldm_greeter_start_authentication (LdmGreeter *greeter, const char *username)
847 g_return_if_fail (LDM_IS_GREETER (greeter));
848 g_return_if_fail (username != NULL);
850 greeter->priv->is_authenticated = FALSE;
851 g_free (greeter->priv->authentication_user);
852 greeter->priv->authentication_user = g_strdup (username);
853 g_debug ("Starting authentication for user %s...", username);
854 dbus_g_proxy_begin_call (greeter->priv->display_proxy, "StartAuthentication", auth_response_cb, greeter, NULL, G_TYPE_STRING, username, G_TYPE_INVALID);
858 * ldm_greeter_provide_secret:
859 * @greeter: A #LdmGreeter
860 * @secret: Response to a prompt
862 * Provide secret information from a prompt.
865 ldm_greeter_provide_secret (LdmGreeter *greeter, const gchar *secret)
869 g_return_if_fail (LDM_IS_GREETER (greeter));
870 g_return_if_fail (secret != NULL);
872 // FIXME: Could be multiple secrets required
873 secrets = g_malloc (sizeof (char *) * 2);
874 secrets[0] = g_strdup (secret);
876 g_debug ("Providing secret to display manager");
877 dbus_g_proxy_begin_call (greeter->priv->display_proxy, "ContinueAuthentication", auth_response_cb, greeter, NULL, G_TYPE_STRV, secrets, G_TYPE_INVALID);
881 * ldm_greeter_cancel_authentication:
882 * @greeter: A #LdmGreeter
884 * Cancel the current user authentication.
887 ldm_greeter_cancel_authentication (LdmGreeter *greeter)
889 g_return_if_fail (LDM_IS_GREETER (greeter));
893 * ldm_greeter_get_is_authenticated:
894 * @greeter: A #LdmGreeter
896 * Checks if the greeter has successfully authenticated.
898 * Return value: TRUE if the greeter is authenticated for login.
901 ldm_greeter_get_is_authenticated (LdmGreeter *greeter)
903 g_return_val_if_fail (greeter != NULL, FALSE);
904 return greeter->priv->is_authenticated;
908 * ldm_greeter_get_authentication_user:
909 * @greeter: A #LdmGreeter
911 * Get the user that is being authenticated.
913 * Return value: The username of the authentication user being authenticated or NULL if no authentication in progress.
916 ldm_greeter_get_authentication_user (LdmGreeter *greeter)
918 g_return_val_if_fail (greeter != NULL, NULL);
919 return greeter->priv->authentication_user;
924 * @greeter: A #LdmGreeter
925 * @username: The user to log in as
926 * @session: The session to log into or NULL to use the default
927 * @language: The language to use or NULL to use the default
929 * Login a user to a session
932 ldm_greeter_login (LdmGreeter *greeter, const gchar *username, const gchar *session, const gchar *language)
934 GError *error = NULL;
936 g_return_if_fail (LDM_IS_GREETER (greeter));
937 g_return_if_fail (username != NULL);
939 g_debug ("Logging in");
940 if (!dbus_g_proxy_call (greeter->priv->display_proxy, "Login", &error,
941 G_TYPE_STRING, username,
942 G_TYPE_STRING, session ? session : "",
943 G_TYPE_STRING, language ? language : "",
946 g_warning ("Failed to login: %s", error->message);
947 g_clear_error (&error);
951 * ldm_greeter_get_can_suspend:
952 * @greeter: A #LdmGreeter
954 * Checks if the greeter is authorized to do a system suspend.
956 * Return value: TRUE if the greeter can suspend the system
959 ldm_greeter_get_can_suspend (LdmGreeter *greeter)
962 gboolean result = TRUE;
963 GError *error = NULL;
965 g_return_val_if_fail (greeter != NULL, FALSE);
967 proxy = dbus_g_proxy_new_for_name (greeter->priv->system_bus,
968 "org.freedesktop.UPower",
969 "/org/freedesktop/UPower",
970 "org.freedesktop.UPower");
971 if (!dbus_g_proxy_call (proxy, "SuspendAllowed", &error, G_TYPE_INVALID, G_TYPE_BOOLEAN, &result, G_TYPE_INVALID))
972 g_warning ("Error checking for suspend authority: %s", error->message);
973 g_clear_error (&error);
975 g_object_unref (proxy);
981 * ldm_greeter_suspend:
982 * @greeter: A #LdmGreeter
984 * Triggers a system suspend.
987 ldm_greeter_suspend (LdmGreeter *greeter)
990 GError *error = NULL;
992 g_return_if_fail (LDM_IS_GREETER (greeter));
994 proxy = dbus_g_proxy_new_for_name (greeter->priv->system_bus,
995 "org.freedesktop.UPower",
996 "/org/freedesktop/UPower",
997 "org.freedesktop.UPower");
998 if (!dbus_g_proxy_call (proxy, "Suspend", &error, G_TYPE_INVALID, G_TYPE_INVALID))
999 g_warning ("Failed to hibernate: %s", error->message);
1000 g_clear_error (&error);
1002 g_object_unref (proxy);
1006 * ldm_greeter_get_can_hibernate:
1007 * @greeter: A #LdmGreeter
1009 * Checks if the greeter is authorized to do a system hibernate.
1011 * Return value: TRUE if the greeter can hibernate the system
1014 ldm_greeter_get_can_hibernate (LdmGreeter *greeter)
1017 gboolean result = FALSE;
1018 GError *error = NULL;
1020 g_return_val_if_fail (greeter != NULL, FALSE);
1022 proxy = dbus_g_proxy_new_for_name (greeter->priv->system_bus,
1023 "org.freedesktop.UPower",
1024 "/org/freedesktop/UPower",
1025 "org.freedesktop.UPower");
1026 if (!dbus_g_proxy_call (proxy, "HibernateAllowed", &error, G_TYPE_INVALID, G_TYPE_BOOLEAN, &result, G_TYPE_INVALID))
1027 g_warning ("Error checking for hibernate authority: %s", error->message);
1028 g_clear_error (&error);
1030 g_object_unref (proxy);
1036 * ldm_greeter_hibernate:
1037 * @greeter: A #LdmGreeter
1039 * Triggers a system hibernate.
1042 ldm_greeter_hibernate (LdmGreeter *greeter)
1045 GError *error = NULL;
1047 g_return_if_fail (LDM_IS_GREETER (greeter));
1049 proxy = dbus_g_proxy_new_for_name (greeter->priv->system_bus,
1050 "org.freedesktop.UPower",
1051 "/org/freedesktop/UPower",
1052 "org.freedesktop.UPower");
1053 if (!dbus_g_proxy_call (proxy, "Hibernate", &error, G_TYPE_INVALID, G_TYPE_INVALID))
1054 g_warning ("Failed to hibernate: %s", error->message);
1055 g_clear_error (&error);
1057 g_object_unref (proxy);
1061 * ldm_greeter_get_can_restart:
1062 * @greeter: A #LdmGreeter
1064 * Checks if the greeter is authorized to do a system restart.
1066 * Return value: TRUE if the greeter can restart the system
1069 ldm_greeter_get_can_restart (LdmGreeter *greeter)
1072 gboolean result = FALSE;
1073 GError *error = NULL;
1075 g_return_val_if_fail (greeter != NULL, FALSE);
1077 proxy = dbus_g_proxy_new_for_name (greeter->priv->system_bus,
1078 "org.freedesktop.ConsoleKit",
1079 "/org/freedesktop/ConsoleKit/Manager",
1080 "org.freedesktop.ConsoleKit.Manager");
1081 if (!dbus_g_proxy_call (proxy, "CanRestart", &error, G_TYPE_INVALID, G_TYPE_BOOLEAN, &result, G_TYPE_INVALID))
1082 g_warning ("Error checking for restart authority: %s", error->message);
1083 g_clear_error (&error);
1085 g_object_unref (proxy);
1091 * ldm_greeter_restart:
1092 * @greeter: A #LdmGreeter
1094 * Triggers a system restart.
1097 ldm_greeter_restart (LdmGreeter *greeter)
1100 GError *error = NULL;
1102 g_return_if_fail (LDM_IS_GREETER (greeter));
1104 proxy = dbus_g_proxy_new_for_name (greeter->priv->system_bus,
1105 "org.freedesktop.ConsoleKit",
1106 "/org/freedesktop/ConsoleKit/Manager",
1107 "org.freedesktop.ConsoleKit.Manager");
1108 if (!dbus_g_proxy_call (proxy, "Restart", &error, G_TYPE_INVALID, G_TYPE_INVALID))
1109 g_warning ("Failed to restart: %s", error->message);
1110 g_clear_error (&error);
1112 g_object_unref (proxy);
1116 * ldm_greeter_get_can_shutdown:
1117 * @greeter: A #LdmGreeter
1119 * Checks if the greeter is authorized to do a system shutdown.
1121 * Return value: TRUE if the greeter can shutdown the system
1124 ldm_greeter_get_can_shutdown (LdmGreeter *greeter)
1127 gboolean result = FALSE;
1128 GError *error = NULL;
1130 g_return_val_if_fail (greeter != NULL, FALSE);
1132 proxy = dbus_g_proxy_new_for_name (greeter->priv->system_bus,
1133 "org.freedesktop.ConsoleKit",
1134 "/org/freedesktop/ConsoleKit/Manager",
1135 "org.freedesktop.ConsoleKit.Manager");
1136 if (!dbus_g_proxy_call (proxy, "CanStop", &error, G_TYPE_INVALID, G_TYPE_BOOLEAN, &result, G_TYPE_INVALID))
1137 g_warning ("Error checking for shutdown authority: %s", error->message);
1138 g_clear_error (&error);
1140 g_object_unref (proxy);
1146 * ldm_greeter_shutdown:
1147 * @greeter: A #LdmGreeter
1149 * Triggers a system shutdown.
1152 ldm_greeter_shutdown (LdmGreeter *greeter)
1155 GError *error = NULL;
1157 g_return_if_fail (LDM_IS_GREETER (greeter));
1159 proxy = dbus_g_proxy_new_for_name (greeter->priv->system_bus,
1160 "org.freedesktop.ConsoleKit",
1161 "/org/freedesktop/ConsoleKit/Manager",
1162 "org.freedesktop.ConsoleKit.Manager");
1163 if (!dbus_g_proxy_call (proxy, "Stop", &error, G_TYPE_INVALID, G_TYPE_INVALID))
1164 g_warning ("Failed to shutdown: %s", error->message);
1165 g_clear_error (&error);
1167 g_object_unref (proxy);
1171 ldm_greeter_get_user_defaults (LdmGreeter *greeter, const gchar *username, gchar **language, gchar **layout, gchar **session)
1173 GError *error = NULL;
1176 result = dbus_g_proxy_call (greeter->priv->user_proxy, "GetUserDefaults", &error,
1177 G_TYPE_STRING, username,
1179 G_TYPE_STRING, language,
1180 G_TYPE_STRING, layout,
1181 G_TYPE_STRING, session,
1185 g_warning ("Failed to get user defaults: %s", error->message);
1186 g_clear_error (&error);
1192 ldm_greeter_init (LdmGreeter *greeter)
1194 greeter->priv = G_TYPE_INSTANCE_GET_PRIVATE (greeter, LDM_TYPE_GREETER, LdmGreeterPrivate);
1198 ldm_greeter_set_property (GObject *object,
1200 const GValue *value,
1206 self = LDM_GREETER (object);
1210 ldm_greeter_set_layout(self, g_value_get_string (value));
1213 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1219 ldm_greeter_get_property (GObject *object,
1226 self = LDM_GREETER (object);
1230 g_value_set_string (value, ldm_greeter_get_hostname (self));
1232 case PROP_NUM_USERS:
1233 g_value_set_int (value, ldm_greeter_get_num_users (self));
1237 case PROP_DEFAULT_LANGUAGE:
1238 g_value_set_string (value, ldm_greeter_get_default_language (self));
1243 g_value_set_string (value, ldm_greeter_get_layout (self));
1247 case PROP_DEFAULT_SESSION:
1248 g_value_set_string (value, ldm_greeter_get_default_session (self));
1250 case PROP_TIMED_LOGIN_USER:
1251 g_value_set_string (value, ldm_greeter_get_timed_login_user (self));
1253 case PROP_TIMED_LOGIN_DELAY:
1254 g_value_set_int (value, ldm_greeter_get_timed_login_delay (self));
1256 case PROP_AUTHENTICATION_USER:
1257 g_value_set_string (value, ldm_greeter_get_authentication_user (self));
1259 case PROP_IS_AUTHENTICATED:
1260 g_value_set_boolean (value, ldm_greeter_get_is_authenticated (self));
1262 case PROP_CAN_SUSPEND:
1263 g_value_set_boolean (value, ldm_greeter_get_can_suspend (self));
1265 case PROP_CAN_HIBERNATE:
1266 g_value_set_boolean (value, ldm_greeter_get_can_hibernate (self));
1268 case PROP_CAN_RESTART:
1269 g_value_set_boolean (value, ldm_greeter_get_can_restart (self));
1271 case PROP_CAN_SHUTDOWN:
1272 g_value_set_boolean (value, ldm_greeter_get_can_shutdown (self));
1275 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1281 ldm_greeter_class_init (LdmGreeterClass *klass)
1283 GObjectClass *object_class = G_OBJECT_CLASS (klass);
1285 g_type_class_add_private (klass, sizeof (LdmGreeterPrivate));
1287 object_class->set_property = ldm_greeter_set_property;
1288 object_class->get_property = ldm_greeter_get_property;
1290 g_object_class_install_property (object_class,
1292 g_param_spec_string ("hostname",
1294 "Hostname displaying greeter for",
1297 g_object_class_install_property (object_class,
1299 g_param_spec_int ("num-users",
1301 "Number of login users",
1304 /*g_object_class_install_property (object_class,
1306 g_param_spec_list ("users",
1308 "Users that can login"));
1309 g_object_class_install_property (object_class,
1310 PROP_DEFAULT_LANGUAGE,
1311 g_param_spec_string ("default-language",
1315 G_PARAM_READWRITE));
1316 g_object_class_install_property (object_class,
1318 g_param_spec_list ("layouts",
1320 "Available keyboard layouts"));*/
1321 g_object_class_install_property (object_class,
1323 g_param_spec_string ("layout",
1325 "Current keyboard layout",
1327 G_PARAM_READWRITE));
1328 /*g_object_class_install_property (object_class,
1330 g_param_spec_list ("sessions",
1332 "Available sessions"));*/
1333 g_object_class_install_property (object_class,
1334 PROP_DEFAULT_SESSION,
1335 g_param_spec_string ("default-session",
1339 G_PARAM_READWRITE));
1340 g_object_class_install_property (object_class,
1341 PROP_TIMED_LOGIN_USER,
1342 g_param_spec_string ("timed-login-user",
1344 "User to login as when timed expires",
1347 g_object_class_install_property (object_class,
1348 PROP_TIMED_LOGIN_DELAY,
1349 g_param_spec_int ("login-delay",
1351 "Number of seconds until logging in as default user",
1352 G_MININT, G_MAXINT, 0,
1354 g_object_class_install_property (object_class,
1355 PROP_AUTHENTICATION_USER,
1356 g_param_spec_string ("authentication-user",
1357 "authentication-user",
1358 "The user being authenticated",
1361 g_object_class_install_property (object_class,
1362 PROP_IS_AUTHENTICATED,
1363 g_param_spec_boolean ("is-authenticated",
1365 "TRUE if the selected user is authenticated",
1368 g_object_class_install_property (object_class,
1370 g_param_spec_boolean ("can-suspend",
1372 "TRUE if allowed to suspend the system",
1375 g_object_class_install_property (object_class,
1377 g_param_spec_boolean ("can-hibernate",
1379 "TRUE if allowed to hibernate the system",
1382 g_object_class_install_property (object_class,
1384 g_param_spec_boolean ("can-restart",
1386 "TRUE if allowed to restart the system",
1389 g_object_class_install_property (object_class,
1391 g_param_spec_boolean ("can-shutdown",
1393 "TRUE if allowed to shutdown the system",
1398 * LdmGreeter::show-prompt:
1399 * @greeter: A #LdmGreeter
1400 * @text: Prompt text
1402 * The ::show-prompt signal gets emitted when the greeter should show a
1403 * prompt to the user. The given text should be displayed and an input
1404 * field for the user to provide a response.
1406 * Call ldm_greeter_provide_secret() with the resultant input or
1407 * ldm_greeter_cancel_authentication() to abort the authentication.
1409 signals[SHOW_PROMPT] =
1410 g_signal_new ("show-prompt",
1411 G_TYPE_FROM_CLASS (klass),
1413 G_STRUCT_OFFSET (LdmGreeterClass, show_prompt),
1415 g_cclosure_marshal_VOID__STRING,
1416 G_TYPE_NONE, 1, G_TYPE_STRING);
1419 * LdmGreeter::show-message:
1420 * @greeter: A #LdmGreeter
1421 * @text: Message text
1423 * The ::show-message signal gets emitted when the greeter
1424 * should show an informational message to the user.
1426 signals[SHOW_MESSAGE] =
1427 g_signal_new ("show-message",
1428 G_TYPE_FROM_CLASS (klass),
1430 G_STRUCT_OFFSET (LdmGreeterClass, show_message),
1432 g_cclosure_marshal_VOID__STRING,
1433 G_TYPE_NONE, 1, G_TYPE_STRING);
1436 * LdmGreeter::show-error:
1437 * @greeter: A #LdmGreeter
1438 * @text: Message text
1440 * The ::show-error signal gets emitted when the greeter
1441 * should show an error message to the user.
1443 signals[SHOW_ERROR] =
1444 g_signal_new ("show-error",
1445 G_TYPE_FROM_CLASS (klass),
1447 G_STRUCT_OFFSET (LdmGreeterClass, show_error),
1449 g_cclosure_marshal_VOID__STRING,
1450 G_TYPE_NONE, 1, G_TYPE_STRING);
1453 * LdmGreeter::authentication-complete:
1454 * @greeter: A #LdmGreeter
1456 * The ::authentication-complete signal gets emitted when the greeter
1457 * has completed authentication.
1459 * Call ldm_greeter_get_is_authenticated() to check if the authentication
1462 signals[AUTHENTICATION_COMPLETE] =
1463 g_signal_new ("authentication-complete",
1464 G_TYPE_FROM_CLASS (klass),
1466 G_STRUCT_OFFSET (LdmGreeterClass, authentication_complete),
1468 g_cclosure_marshal_VOID__VOID,
1472 * LdmGreeter::timed-login:
1473 * @greeter: A #LdmGreeter
1474 * @username: A username
1476 * The ::timed-login signal gets emitted when the default user timer
1479 signals[TIMED_LOGIN] =
1480 g_signal_new ("timed-login",
1481 G_TYPE_FROM_CLASS (klass),
1483 G_STRUCT_OFFSET (LdmGreeterClass, timed_login),
1485 g_cclosure_marshal_VOID__STRING,
1486 G_TYPE_NONE, 1, G_TYPE_STRING);
1490 * @greeter: A #LdmGreeter
1492 * The ::quit signal gets emitted when the greeter should exit.
1495 g_signal_new ("quit",
1496 G_TYPE_FROM_CLASS (klass),
1498 G_STRUCT_OFFSET (LdmGreeterClass, quit),
1500 g_cclosure_marshal_VOID__VOID,