2 * Copyright (C) 2010-2011 Robert Ancell.
3 * Author: Robert Ancell <robert.ancell@canonical.com>
5 * This program is free software: you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option) any later
8 * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
15 #include <gio/gdesktopappinfo.h>
18 #include "configuration.h"
20 #include "pam-session.h"
22 #include "ldm-marshal.h"
24 #include "guest-account.h"
25 #include "xserver-local.h" // FIXME: Shouldn't know if it's an xserver
33 static guint signals[LAST_SIGNAL] = { 0 };
38 SESSION_GREETER_PRE_CONNECT,
40 SESSION_GREETER_AUTHENTICATED,
47 DisplayServer *display_server;
49 /* User to run greeter as */
53 gchar *greeter_session;
55 /* TRUE if the user list should be shown */
56 gboolean greeter_hide_users;
58 /* Default session for users */
59 gchar *default_session;
61 /* Session requested to log into */
64 /* Program to run sessions through */
65 gchar *session_wrapper;
67 /* PAM service to authenticate against */
70 /* PAM service to authenticate against for automatic logins */
71 gchar *pam_autologin_service;
76 /* Communication link to greeter */
79 /* Timeout for greeter to respond to quit request */
80 guint greeter_quit_timeout;
82 PAMSession *pam_session;
84 /* User that should be automatically logged in */
86 gboolean default_user_is_guest;
87 gboolean default_user_requires_password;
88 gint default_user_timeout;
90 /* TRUE if stopping the display (waiting for dispaly server, greeter and session to stop) */
94 G_DEFINE_TYPE (Display, display, G_TYPE_OBJECT);
96 /* Length of time in milliseconds to wait for a greeter to quit */
97 #define GREETER_QUIT_TIMEOUT 1000
99 static gboolean start_greeter_session (Display *display);
100 static gboolean start_user_session (Display *display, PAMSession *pam_session, const gchar *name);
102 // FIXME: Should be a construct property
104 display_load_config (Display *display, const gchar *config_section)
106 g_return_if_fail (display != NULL);
109 display->priv->greeter_user = config_get_string (config_get_instance (), config_section, "greeter-user");
110 if (!display->priv->greeter_user)
111 display->priv->greeter_user = config_get_string (config_get_instance (), "SeatDefaults", "greeter-user");
113 display->priv->greeter_session = config_get_string (config_get_instance (), config_section, "greeter-session");
114 if (!display->priv->greeter_session)
115 display->priv->greeter_session = config_get_string (config_get_instance (), "SeatDefaults", "greeter-session");
116 if (config_section && config_has_key (config_get_instance (), config_section, "greeter-hide-users"))
117 display->priv->greeter_hide_users = config_get_boolean (config_get_instance (), config_section, "greeter-hide-users");
118 else if (config_has_key (config_get_instance (), "SeatDefaults", "greeter-hide-users"))
119 display->priv->greeter_hide_users = config_get_boolean (config_get_instance (), "SeatDefaults", "greeter-hide-users");
121 display->priv->default_session = config_get_string (config_get_instance (), config_section, "user-session");
122 if (!display->priv->default_session)
123 display->priv->default_session = config_get_string (config_get_instance (), "SeatDefaults", "user-session");
125 display->priv->session_wrapper = config_get_string (config_get_instance (), config_section, "session-wrapper");
126 if (!display->priv->session_wrapper)
127 display->priv->session_wrapper = config_get_string (config_get_instance (), "SeatDefaults", "session-wrapper");
130 // FIXME: Should be a construct property
132 display_set_display_server (Display *display, DisplayServer *display_server)
134 g_return_if_fail (display != NULL);
135 g_return_if_fail (display->priv->display_server == NULL);
136 display->priv->display_server = g_object_ref (display_server);
140 display_get_display_server (Display *display)
142 g_return_val_if_fail (display != NULL, NULL);
143 return display->priv->display_server;
147 display_get_session (Display *display)
149 g_return_val_if_fail (display != NULL, NULL);
150 return display->priv->session;
154 display_set_default_user (Display *display, const gchar *username, gboolean is_guest, gboolean requires_password, gint timeout)
156 g_return_if_fail (display != NULL);
157 g_free (display->priv->default_user);
158 display->priv->default_user = g_strdup (username);
159 display->priv->default_user_is_guest = is_guest;
160 display->priv->default_user_requires_password = requires_password;
161 display->priv->default_user_timeout = timeout;
165 activate_user (Display *display, const gchar *username)
168 g_signal_emit (display, signals[ACTIVATE_USER], 0, username, &result);
173 start_ck_session (Display *display, const gchar *session_type, User *user)
176 const gchar *hostname = "";
177 GVariantBuilder arg_builder;
179 gchar *cookie = NULL;
180 GError *error = NULL;
182 /* Only start ConsoleKit sessions when running as root */
186 proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
187 G_DBUS_PROXY_FLAGS_NONE,
189 "org.freedesktop.ConsoleKit",
190 "/org/freedesktop/ConsoleKit/Manager",
191 "org.freedesktop.ConsoleKit.Manager",
194 g_warning ("Unable to get connection to ConsoleKit: %s", error->message);
195 g_clear_error (&error);
199 g_variant_builder_init (&arg_builder, G_VARIANT_TYPE ("(a(sv))"));
200 g_variant_builder_open (&arg_builder, G_VARIANT_TYPE ("a(sv)"));
201 g_variant_builder_add (&arg_builder, "(sv)", "unix-user", g_variant_new_int32 (user_get_uid (user)));
202 g_variant_builder_add (&arg_builder, "(sv)", "session-type", g_variant_new_string (session_type));
203 if (IS_XSERVER (display->priv->display_server))
205 g_variant_builder_add (&arg_builder, "(sv)", "x11-display",
206 g_variant_new_string (xserver_get_address (XSERVER (display->priv->display_server))));
208 if (IS_XSERVER_LOCAL (display->priv->display_server) && xserver_local_get_vt (XSERVER_LOCAL (display->priv->display_server)) >= 0)
210 gchar *display_device;
211 display_device = g_strdup_printf ("/dev/tty%d", xserver_local_get_vt (XSERVER_LOCAL (display->priv->display_server)));
212 g_variant_builder_add (&arg_builder, "(sv)", "x11-display-device", g_variant_new_string (display_device));
213 g_free (display_device);
217 g_variant_builder_add (&arg_builder, "(sv)", "remote-host-name", g_variant_new_string (hostname));
218 g_variant_builder_add (&arg_builder, "(sv)", "is-local", g_variant_new_boolean (TRUE));
219 g_variant_builder_close (&arg_builder);
221 result = g_dbus_proxy_call_sync (proxy,
222 "OpenSessionWithParameters",
223 g_variant_builder_end (&arg_builder),
224 G_DBUS_CALL_FLAGS_NONE,
228 g_object_unref (proxy);
231 g_warning ("Failed to open CK session: %s", error->message);
232 g_clear_error (&error);
236 if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(s)")))
237 g_variant_get (result, "(s)", &cookie);
239 g_warning ("Unexpected response from OpenSessionWithParameters: %s", g_variant_get_type_string (result));
240 g_variant_unref (result);
243 g_debug ("Opened ConsoleKit session %s", cookie);
249 end_ck_session (const gchar *cookie)
253 GError *error = NULL;
258 g_debug ("Ending ConsoleKit session %s", cookie);
260 proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
261 G_DBUS_PROXY_FLAGS_NONE,
263 "org.freedesktop.ConsoleKit",
264 "/org/freedesktop/ConsoleKit/Manager",
265 "org.freedesktop.ConsoleKit.Manager",
267 result = g_dbus_proxy_call_sync (proxy,
269 g_variant_new ("(s)", cookie),
270 G_DBUS_CALL_FLAGS_NONE,
274 g_object_unref (proxy);
277 g_warning ("Error ending ConsoleKit session: %s", error->message);
278 g_clear_error (&error);
282 if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(b)")))
285 g_variant_get (result, "(b)", &is_closed);
287 g_warning ("ConsoleKit.Manager.CloseSession() returned false");
290 g_warning ("Unexpected response from CloseSession: %s", g_variant_get_type_string (result));
292 g_variant_unref (result);
296 set_env_from_pam_session (Session *session, PAMSession *pam_session)
300 pam_env = pam_session_get_envlist (pam_session);
306 env_string = g_strjoinv (" ", pam_env);
307 g_debug ("PAM returns environment '%s'", env_string);
310 for (i = 0; pam_env[i]; i++)
312 gchar **pam_env_vars = g_strsplit (pam_env[i], "=", 2);
313 if (pam_env_vars && pam_env_vars[0] && pam_env_vars[1])
314 child_process_set_env (CHILD_PROCESS (session), pam_env_vars[0], pam_env_vars[1]);
316 g_warning ("Can't parse PAM environment variable %s", pam_env[i]);
317 g_strfreev (pam_env_vars);
319 g_strfreev (pam_env);
324 session_exited_cb (Session *session, gint status, Display *display)
327 g_debug ("Session exited with value %d", status);
331 session_terminated_cb (Session *session, gint signum, Display *display)
333 g_debug ("Session terminated with signal %d", signum);
337 check_stopped (Display *display)
339 if (display->priv->stopping &&
340 display->priv->display_server == NULL &&
341 display->priv->session == NULL)
343 g_debug ("Display stopped");
344 g_signal_emit (display, signals[STOPPED], 0);
349 session_stopped_cb (Session *session, Display *display)
351 if (display->priv->greeter)
352 g_debug ("Greeter quit");
354 g_debug ("Session quit");
356 if (display->priv->greeter_quit_timeout)
357 g_source_remove (display->priv->greeter_quit_timeout);
358 display->priv->greeter_quit_timeout = 0;
360 /* Stop listening to events from the greeter */
361 if (display->priv->greeter)
362 g_signal_handlers_disconnect_matched (display->priv->greeter, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, display);
364 /* If a guest account, remove the account on exit */
365 if (g_strcmp0 (pam_session_get_username (display->priv->pam_session), guest_account_get_username ()) == 0)
366 guest_account_unref ();
368 g_signal_handlers_disconnect_matched (session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, display);
371 end_ck_session (session_get_cookie (session));
373 pam_session_end (display->priv->pam_session);
374 g_object_unref (display->priv->pam_session);
375 display->priv->pam_session = NULL;
377 g_object_unref (display->priv->session);
378 display->priv->session = NULL;
380 if (display->priv->stopping)
382 check_stopped (display);
386 /* Restart the X server or start a new one if it failed */
387 if (!display_server_restart (display->priv->display_server))
389 g_debug ("Starting new display server");
390 display_server_start (display->priv->display_server);
395 create_session (Display *display, PAMSession *pam_session, const gchar *session_name, gboolean is_greeter, const gchar *log_filename)
398 gchar *xsessions_dir, *filename, *path, *command;
399 GKeyFile *session_desktop_file;
403 GError *error = NULL;
405 /* Can't be any session running already */
406 g_return_val_if_fail (display->priv->session == NULL, FALSE);
407 g_return_val_if_fail (display->priv->pam_session == NULL, FALSE);
409 user = user_get_by_name (pam_session_get_username (pam_session));
410 g_return_val_if_fail (user != NULL, FALSE);
412 g_debug ("Starting session %s as user %s logging to %s", session_name, user_get_name (user), log_filename);
414 xsessions_dir = config_get_string (config_get_instance (), "Directories", "xsessions-directory");
415 filename = g_strdup_printf ("%s.desktop", session_name);
416 path = g_build_filename (xsessions_dir, filename, NULL);
417 g_free (xsessions_dir);
420 session_desktop_file = g_key_file_new ();
421 result = g_key_file_load_from_file (session_desktop_file, path, G_KEY_FILE_NONE, &error);
423 g_warning ("Failed to load session file %s: %s:", path, error->message);
425 g_clear_error (&error);
428 command = g_key_file_get_string (session_desktop_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_EXEC, NULL);
429 g_key_file_free (session_desktop_file);
433 g_warning ("No command in session file %s", path);
436 if (display->priv->session_wrapper)
439 command = g_strdup_printf ("%s '%s'", display->priv->session_wrapper, command);
443 session = DISPLAY_GET_CLASS (display)->create_session (display);
444 g_return_val_if_fail (session != NULL, NULL);
445 g_signal_connect (session, "exited", G_CALLBACK (session_exited_cb), display);
446 g_signal_connect (session, "terminated", G_CALLBACK (session_terminated_cb), display);
447 g_signal_connect (session, "stopped", G_CALLBACK (session_stopped_cb), display);
448 session_set_is_greeter (session, is_greeter);
449 session_set_user (session, user);
450 session_set_command (session, command);
452 child_process_set_env (CHILD_PROCESS (session), "DESKTOP_SESSION", session_name); // FIXME: Apparently deprecated?
453 child_process_set_env (CHILD_PROCESS (session), "GDMSESSION", session_name); // FIXME: Not cross-desktop
455 pam_session_authorize (pam_session);
456 set_env_from_pam_session (session, pam_session);
458 child_process_set_log_file (CHILD_PROCESS (session), log_filename);
460 /* Open ConsoleKit session */
463 cookie = start_ck_session (display, is_greeter ? "LoginWindow" : "", user);
464 session_set_cookie (session, cookie);
468 session_set_cookie (session, g_getenv ("XDG_SESSION_COOKIE"));
470 /* Connect using the session bus */
473 child_process_set_env (CHILD_PROCESS (session), "DBUS_SESSION_BUS_ADDRESS", g_getenv ("DBUS_SESSION_BUS_ADDRESS"));
474 child_process_set_env (CHILD_PROCESS (session), "LDM_BUS", "SESSION");
475 child_process_set_env (CHILD_PROCESS (session), "LD_LIBRARY_PATH", g_getenv ("LD_LIBRARY_PATH"));
476 child_process_set_env (CHILD_PROCESS (session), "PATH", g_getenv ("PATH"));
479 /* Variables required for regression tests */
480 if (g_getenv ("LIGHTDM_TEST_STATUS_SOCKET"))
482 child_process_set_env (CHILD_PROCESS (session), "LIGHTDM_TEST_STATUS_SOCKET", g_getenv ("LIGHTDM_TEST_STATUS_SOCKET"));
483 child_process_set_env (CHILD_PROCESS (session), "LIGHTDM_TEST_CONFIG", g_getenv ("LIGHTDM_TEST_CONFIG"));
484 child_process_set_env (CHILD_PROCESS (session), "LIGHTDM_TEST_HOME_DIR", g_getenv ("LIGHTDM_TEST_HOME_DIR"));
485 child_process_set_env (CHILD_PROCESS (session), "LD_LIBRARY_PATH", g_getenv ("LD_LIBRARY_PATH"));
492 start_session (Display *display, Session *session, PAMSession *pam_session)
496 result = session_start (SESSION (session));
500 display->priv->session = g_object_ref (session);
501 display->priv->pam_session = g_object_ref (pam_session);
504 g_signal_handlers_disconnect_matched (display->priv->session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, display);
510 autologin_pam_message_cb (PAMSession *session, int num_msg, const struct pam_message **msg, Display *display)
512 g_debug ("Aborting automatic login as PAM requests input");
513 pam_session_cancel (session);
517 autologin_authentication_result_cb (PAMSession *session, int result, Display *display)
519 if (!display->priv->stopping)
521 if (result == PAM_SUCCESS)
523 g_debug ("User %s authorized", pam_session_get_username (session));
525 if (activate_user (display, pam_session_get_username (session)))
528 pam_session_authorize (session);
529 start_user_session (display, session, display->priv->default_session);
533 g_debug ("Autologin failed authorization, starting greeter");
535 /* Start greeter and select user that failed */
536 display->priv->default_user_requires_password = TRUE;
537 start_greeter_session (display);
541 g_object_unref (session);
545 quit_timeout_cb (gpointer data)
547 Display *display = data;
549 g_debug ("Greeter did not quit, sending kill signal");
550 session_stop (display->priv->session);
552 display->priv->greeter_quit_timeout = 0;
557 greeter_start_session_cb (Greeter *greeter, const gchar *session, gboolean is_guest, Display *display)
559 PAMSession *pam_session;
560 const gchar *username = NULL;
562 pam_session = greeter_get_pam_session (display->priv->greeter);
563 if (!is_guest && !pam_session_get_in_session (pam_session))
565 g_warning ("Ignoring request for login with unauthenticated user");
569 /* Open guest account */
572 if (!guest_account_ref ())
574 g_debug ("Failed to create guest account, aborting login");
579 /* Default session requested */
581 session = display->priv->default_session;
582 g_free (display->priv->user_session);
583 display->priv->user_session = g_strdup (session);
585 /* Stop this display if can switch to that user */
586 username = pam_session_get_username (pam_session);
587 if (activate_user (display, username))
588 display_stop (display);
591 greeter_quit (display->priv->greeter);
592 if (display->priv->greeter_quit_timeout)
593 g_source_remove (display->priv->greeter_quit_timeout);
594 display->priv->greeter_quit_timeout = g_timeout_add (GREETER_QUIT_TIMEOUT, quit_timeout_cb, display);
601 start_greeter_session (Display *display)
604 const gchar *autologin_user = NULL;
605 gchar *log_dir, *filename, *log_filename;
607 PAMSession *pam_session;
610 g_debug ("Starting greeter session");
612 /* If have user then automatically login the first time */
613 if (display->priv->default_user_is_guest)
615 autologin_user = guest_account_get_username ();
616 guest_account_ref ();
618 else if (display->priv->default_user)
619 autologin_user = display->priv->default_user;
621 if (autologin_user && !display->priv->default_user_requires_password)
623 GError *error = NULL;
624 PAMSession *autologin_pam_session;
626 /* Run using autologin PAM session, abort if get asked any questions */
627 g_debug ("Automatically logging in user %s", autologin_user);
629 autologin_pam_session = pam_session_new (display->priv->pam_autologin_service, autologin_user);
630 g_signal_connect (autologin_pam_session, "got-messages", G_CALLBACK (autologin_pam_message_cb), display);
631 g_signal_connect (autologin_pam_session, "authentication-result", G_CALLBACK (autologin_authentication_result_cb), display);
632 if (pam_session_start (autologin_pam_session, &error))
636 g_object_unref (autologin_pam_session);
637 g_warning ("Failed to autologin user %s, starting greeter instead: %s", autologin_user, error->message);
639 g_clear_error (&error);
642 if (display->priv->greeter_user)
644 user = user_get_by_name (display->priv->greeter_user);
647 g_warning ("Unable to start greeter, user %s does not exist", display->priv->greeter_user);
652 user = user_get_current ();
653 pam_session = pam_session_new (display->priv->pam_service, user_get_name (user));
654 pam_session_authorize (pam_session);
655 g_object_unref (user);
657 log_dir = config_get_string (config_get_instance (), "Directories", "log-directory");
658 // FIXME: May not be an X server
659 filename = g_strdup_printf ("%s-greeter.log", xserver_get_address (XSERVER (display->priv->display_server)));
660 log_filename = g_build_filename (log_dir, filename, NULL);
664 session = create_session (display, pam_session, display->priv->greeter_session, TRUE, log_filename);
665 g_free (log_filename);
667 display->priv->greeter = greeter_new (session);
668 g_signal_connect (G_OBJECT (display->priv->greeter), "start-session", G_CALLBACK (greeter_start_session_cb), display);
669 if (display->priv->default_user_timeout)
671 gchar *value = g_strdup_printf ("%d", display->priv->default_user_timeout);
672 greeter_set_hint (display->priv->greeter, "autologin-timeout", value);
674 if (display->priv->default_user)
675 greeter_set_hint (display->priv->greeter, "autologin-user", display->priv->default_user);
676 else if (display->priv->default_user_is_guest)
677 greeter_set_hint (display->priv->greeter, "autologin-guest", "true");
679 else if (display->priv->default_user)
680 greeter_set_hint (display->priv->greeter, "select-user", display->priv->default_user);
681 else if (display->priv->default_user_is_guest)
682 greeter_set_hint (display->priv->greeter, "select-guest", "true");
683 greeter_set_hint (display->priv->greeter, "default-session", display->priv->default_session);
684 greeter_set_hint (display->priv->greeter, "has-guest-account", guest_account_get_is_enabled () ? "true" : "false");
685 greeter_set_hint (display->priv->greeter, "hide-users", display->priv->greeter_hide_users ? "true" : "false");
687 result = greeter_start (display->priv->greeter);
690 result = start_session (display, session, pam_session);
693 g_debug ("Failed to start greeter session");
694 g_object_unref (session);
699 g_debug ("Failed to start greeter protocol");
701 g_signal_handlers_disconnect_matched (display->priv->greeter, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, display);
702 g_object_unref (display->priv->greeter);
703 display->priv->greeter = NULL;
705 g_object_unref (session);
708 g_object_unref (pam_session);
714 start_user_session (Display *display, PAMSession *pam_session, const gchar *name)
722 g_debug ("Starting user session");
724 user = user_get_by_name (pam_session_get_username (pam_session));
727 g_warning ("Unable to start session, user %s does not exist", pam_session_get_username (pam_session));
731 /* Load the users login settings (~/.dmrc) */
732 dmrc_file = dmrc_load (user_get_name (user));
734 /* Update the .dmrc with changed settings */
735 g_key_file_set_string (dmrc_file, "Desktop", "Session", name);
737 /* Save modified DMRC */
738 dmrc_save (dmrc_file, pam_session_get_username (pam_session));
739 g_key_file_free (dmrc_file);
741 /* Once logged in, don't autologin again */
742 g_free (display->priv->default_user);
743 display->priv->default_user = NULL;
744 display->priv->default_user_is_guest = FALSE;
746 // FIXME: Copy old error file
747 log_filename = g_build_filename (user_get_home_directory (user), ".xsession-errors", NULL);
748 g_object_unref (user);
750 session = create_session (display, pam_session, name, FALSE, log_filename);
751 g_free (log_filename);
754 result = start_session (display, session, pam_session);
758 g_object_unref (session);
765 display_server_stopped_cb (DisplayServer *server, Display *display)
767 if (display->priv->stopping)
769 g_object_unref (display->priv->display_server);
770 display->priv->display_server = NULL;
771 check_stopped (display);
775 /* Stop the session then start a new X server */
776 if (display->priv->session)
778 g_debug ("Stopping session");
779 child_process_stop (CHILD_PROCESS (display->priv->session));
783 g_debug ("Starting new display server");
784 display_server_start (display->priv->display_server);
790 display_server_ready_cb (DisplayServer *display_server, Display *display)
792 PAMSession *pam_session = NULL;
793 gboolean result = FALSE;
795 /* Don't run any sessions on local terminals */
796 // FIXME: Make display_server_get_has_local_session
797 if (IS_XSERVER_LOCAL (display_server) && xserver_local_get_xdmcp_server (XSERVER_LOCAL (display_server)))
800 /* If have had the greeter running then start a user session */
801 if (display->priv->greeter &&
802 greeter_get_pam_session (display->priv->greeter) &&
803 pam_session_get_in_session (greeter_get_pam_session (display->priv->greeter)) &&
804 display->priv->user_session)
805 pam_session = g_object_ref (greeter_get_pam_session (display->priv->greeter));
807 if (display->priv->greeter)
809 g_signal_handlers_disconnect_matched (display->priv->greeter, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, display);
810 g_object_unref (display->priv->greeter);
811 display->priv->greeter = NULL;
816 result = start_user_session (display, pam_session, display->priv->user_session);
818 g_debug ("Failed to start user session, starting greeter");
819 g_object_unref (pam_session);
823 start_greeter_session (display);
825 g_free (display->priv->user_session);
826 display->priv->user_session = NULL;
830 display_start (Display *display)
834 g_return_val_if_fail (display != NULL, FALSE);
836 g_signal_connect (G_OBJECT (display->priv->display_server), "ready", G_CALLBACK (display_server_ready_cb), display);
837 g_signal_connect (G_OBJECT (display->priv->display_server), "stopped", G_CALLBACK (display_server_stopped_cb), display);
838 result = display_server_start (display->priv->display_server);
840 g_signal_emit (display, signals[STARTED], 0);
846 display_stop (Display *display)
848 g_return_if_fail (display != NULL);
850 if (display->priv->stopping)
853 g_debug ("Stopping display");
855 display->priv->stopping = TRUE;
857 if (display->priv->display_server)
858 display_server_stop (display->priv->display_server);
859 if (display->priv->session)
860 session_stop (display->priv->session);
862 check_stopped (display);
866 display_init (Display *display)
868 display->priv = G_TYPE_INSTANCE_GET_PRIVATE (display, DISPLAY_TYPE, DisplayPrivate);
869 display->priv->pam_service = g_strdup ("lightdm");
870 display->priv->pam_autologin_service = g_strdup ("lightdm-autologin");
874 display_create_session (Display *display)
880 display_finalize (GObject *object)
884 self = DISPLAY (object);
886 g_object_unref (self->priv->display_server);
887 g_free (self->priv->greeter_user);
888 g_free (self->priv->greeter_session);
889 if (self->priv->greeter_quit_timeout)
890 g_source_remove (self->priv->greeter_quit_timeout);
891 if (self->priv->greeter)
892 g_object_unref (self->priv->greeter);
893 g_free (self->priv->session_wrapper);
894 g_free (self->priv->pam_service);
895 g_free (self->priv->pam_autologin_service);
896 if (self->priv->session)
898 if (session_get_cookie (self->priv->session))
899 end_ck_session (session_get_cookie (self->priv->session));
900 g_object_unref (self->priv->session);
902 if (self->priv->pam_session)
903 g_object_unref (self->priv->pam_session);
904 g_free (self->priv->default_user);
905 g_free (self->priv->default_session);
906 g_free (self->priv->user_session);
908 G_OBJECT_CLASS (display_parent_class)->finalize (object);
912 display_class_init (DisplayClass *klass)
914 GObjectClass *object_class = G_OBJECT_CLASS (klass);
916 klass->create_session = display_create_session;
917 object_class->finalize = display_finalize;
919 g_type_class_add_private (klass, sizeof (DisplayPrivate));
922 g_signal_new ("started",
923 G_TYPE_FROM_CLASS (klass),
925 G_STRUCT_OFFSET (DisplayClass, started),
927 g_cclosure_marshal_VOID__VOID,
929 signals[ACTIVATE_USER] =
930 g_signal_new ("activate-user",
931 G_TYPE_FROM_CLASS (klass),
933 G_STRUCT_OFFSET (DisplayClass, activate_user),
934 g_signal_accumulator_true_handled,
936 ldm_marshal_BOOLEAN__STRING,
937 G_TYPE_BOOLEAN, 1, G_TYPE_STRING);
939 g_signal_new ("stopped",
940 G_TYPE_FROM_CLASS (klass),
942 G_STRUCT_OFFSET (DisplayClass, stopped),
944 g_cclosure_marshal_VOID__VOID,