gio-2.0 >= 2.26
gio-unix-2.0
xdmcp
+ xcb
])
PKG_CHECK_MODULES(GLIB, [
static gboolean
display_server_real_start (DisplayServer *server)
{
- return FALSE;
+ g_signal_emit (server, signals[READY], 0);
+ return TRUE;
}
gboolean
return DISPLAY_SERVER_GET_CLASS (server)->start (server);
}
-void
-display_server_set_ready (DisplayServer *server)
-{
- g_return_if_fail (server != NULL);
- g_signal_emit (server, signals[READY], 0);
-}
-
-static gboolean
-display_server_real_restart (DisplayServer *server)
-{
- return FALSE;
-}
-
-gboolean
-display_server_restart (DisplayServer *server)
-{
- g_return_val_if_fail (server != NULL, FALSE);
- return DISPLAY_SERVER_GET_CLASS (server)->restart (server);
-}
-
static void
display_server_real_stop (DisplayServer *server)
{
+ g_signal_emit (server, signals[STOPPED], 0);
}
void
DISPLAY_SERVER_GET_CLASS (server)->stop (server);
}
-void
-display_server_set_stopped (DisplayServer *server)
-{
- g_return_if_fail (server != NULL);
- g_signal_emit (server, signals[STOPPED], 0);
-}
-
static void
display_server_init (DisplayServer *server)
{
display_server_class_init (DisplayServerClass *klass)
{
klass->start = display_server_real_start;
- klass->restart = display_server_real_restart;
klass->stop = display_server_real_stop;
signals[READY] =
void (*stopped)(DisplayServer *server);
gboolean (*start)(DisplayServer *server);
- gboolean (*restart)(DisplayServer *server);
void (*stop)(DisplayServer *server);
} DisplayServerClass;
gboolean display_server_start (DisplayServer *server);
-void display_server_set_ready (DisplayServer *server);
-
-gboolean display_server_restart (DisplayServer *server);
-
void display_server_stop (DisplayServer *server);
-void display_server_set_stopped (DisplayServer *server);
-
G_END_DECLS
#endif /* _DISPLAY_SERVER_H_ */
}
}
-static void
-session_stopped_cb (Session *session, Display *display)
-{
- if (session_get_is_greeter (display->priv->session))
- g_debug ("Greeter quit");
- else
- g_debug ("User session quit");
-
- /* Stop listening to events from the greeter */
- if (display->priv->greeter)
- g_signal_handlers_disconnect_matched (display->priv->greeter, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, display);
-
- /* If a guest account, remove the account on exit */
- // FIXME
- //if (g_strcmp0 (pam_session_get_username (display->priv->pam_session), guest_account_get_username ()) == 0)
- // guest_account_unref ();
+static void display_server_ready_cb (DisplayServer *display_server, Display *display);
- g_signal_handlers_disconnect_matched (session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, display);
+static gboolean
+cleanup_after_session (Display *display)
+{
+ g_signal_handlers_disconnect_matched (display->priv->session, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, display);
+ /* Close ConsoleKit session */
if (getuid () == 0)
- end_ck_session (session_get_cookie (session));
+ end_ck_session (session_get_cookie (display->priv->session));
+ /* Close PAM session */
pam_session_end (display->priv->pam_session);
g_object_unref (display->priv->pam_session);
display->priv->pam_session = NULL;
if (display->priv->stopping)
{
check_stopped (display);
- return;
+ return TRUE;
}
- /* Restart the X server or start a new one if it failed */
- if (!display_server_restart (display->priv->display_server))
- {
- g_debug ("Starting new display server");
- display_server_start (display->priv->display_server);
- }
+ return FALSE;
+}
+
+static void
+greeter_session_stopped_cb (Session *session, Display *display)
+{
+ g_debug ("Greeter quit");
+
+ if (cleanup_after_session (display))
+ return;
+
+ /* Start the session */
+ if (display->priv->display_server)
+ display_server_ready_cb (display->priv->display_server, display);
+}
+
+static void
+user_session_stopped_cb (Session *session, Display *display)
+{
+ g_debug ("User session quit");
+
+ if (cleanup_after_session (display))
+ return;
+
+ /* This display has ended */
+ display_stop (display);
}
static Session *
g_return_val_if_fail (session != NULL, NULL);
g_signal_connect (session, "exited", G_CALLBACK (session_exited_cb), display);
g_signal_connect (session, "terminated", G_CALLBACK (session_terminated_cb), display);
- g_signal_connect (session, "stopped", G_CALLBACK (session_stopped_cb), display);
+ if (is_greeter)
+ g_signal_connect (session, "stopped", G_CALLBACK (greeter_session_stopped_cb), display);
+ else
+ g_signal_connect (session, "stopped", G_CALLBACK (user_session_stopped_cb), display);
session_set_is_greeter (session, is_greeter);
session_set_user (session, user);
session_set_command (session, command);
static void
display_server_stopped_cb (DisplayServer *server, Display *display)
{
- if (display->priv->stopping)
- {
- g_object_unref (display->priv->display_server);
- display->priv->display_server = NULL;
- check_stopped (display);
- }
- else
- {
- g_debug ("Display server stopped");
-
- /* Stop the session then start a new X server */
- if (display->priv->session)
- {
- g_debug ("Stopping session");
- process_stop (PROCESS (display->priv->session));
- }
- else
- {
- g_debug ("Starting new display server");
- display_server_start (display->priv->display_server);
- }
- }
+ g_debug ("Display server stopped");
+
+ g_object_unref (display->priv->display_server);
+ display->priv->display_server = NULL;
+
+ /* Stop this display, it will be restarted by the seat if necessary */
+ display_stop (display);
}
static void
pam_session_get_in_session (greeter_get_pam_session (display->priv->greeter)))
pam_session = g_object_ref (greeter_get_pam_session (display->priv->greeter));
- /* Stop any existing greeter */
+ /* Stop the greeter connection */
if (display->priv->greeter)
{
g_signal_handlers_disconnect_matched (display->priv->greeter, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, display);
{
g_return_if_fail (display != NULL);
- if (display->priv->stopping)
- return;
-
- g_debug ("Stopping display");
+ if (!display->priv->stopping)
+ {
+ g_debug ("Stopping display");
- display->priv->stopping = TRUE;
+ display->priv->stopping = TRUE;
- if (display->priv->display_server)
- display_server_stop (display->priv->display_server);
- if (display->priv->session)
- session_stop (display->priv->session);
+ if (display->priv->display_server)
+ display_server_stop (display->priv->display_server);
+ if (display->priv->session)
+ session_stop (display->priv->session);
+ }
check_stopped (display);
}
struct SeatXDMCPSessionPrivate
{
+ /* Remote display */
+ XDisplay *display;
+
/* Session being serviced */
XDMCPSession *session;
};
{
XAuthority *authority;
XServerRemote *xserver;
- XDisplay *display;
authority = xdmcp_session_get_authority (SEAT_XDMCP_SESSION (seat)->priv->session);
xserver = xserver_remote_new (xauth_get_address (authority), xdmcp_session_get_display_number (SEAT_XDMCP_SESSION (seat)->priv->session), authority);
- display = xdisplay_new (XSERVER (xserver));
+ SEAT_XDMCP_SESSION (seat)->priv->display = xdisplay_new (XSERVER (xserver));
g_object_unref (xserver);
- return DISPLAY (display);
+ return DISPLAY (SEAT_XDMCP_SESSION (seat)->priv->display);
+}
+
+static void
+seat_xdmcp_session_display_removed (Seat *seat, Display *display)
+{
+ seat_stop (seat);
}
static void
seat->priv = G_TYPE_INSTANCE_GET_PRIVATE (seat, SEAT_XDMCP_SESSION_TYPE, SeatXDMCPSessionPrivate);
}
+static void
+seat_xdmcp_session_finalize (GObject *object)
+{
+ SeatXDMCPSession *self;
+
+ self = SEAT_XDMCP_SESSION (object);
+
+ if (self->priv->display)
+ g_object_unref (self->priv->display);
+ g_object_unref (self->priv->session);
+
+ G_OBJECT_CLASS (seat_xdmcp_session_parent_class)->finalize (object);
+}
+
static void
seat_xdmcp_session_class_init (SeatXDMCPSessionClass *klass)
{
SeatClass *seat_class = SEAT_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
seat_class->add_display = seat_xdmcp_session_add_display;
+ seat_class->display_removed = seat_xdmcp_session_display_removed;
+ object_class->finalize = seat_xdmcp_session_finalize;
g_type_class_add_private (klass, sizeof (SeatXDMCPSessionPrivate));
}
G_DEFINE_TYPE (SeatXLocal, seat_xlocal, SEAT_TYPE);
+struct SeatXLocalPrivate
+{
+ /* TRUE if stopping this seat (waiting for displays to stop) */
+ gboolean stopping;
+};
+
static void
seat_xlocal_setup (Seat *seat)
{
vt_set_active (number);
}
+static void
+seat_xlocal_display_removed (Seat *seat, Display *display)
+{
+ if (SEAT_XLOCAL (seat)->priv->stopping)
+ return;
+
+ /* Show a new greeter */
+ g_debug ("Display stopped, switching to greeter");
+ seat_switch_to_greeter (seat);
+}
+
+static void
+seat_xlocal_stop (Seat *seat)
+{
+ SEAT_XLOCAL (seat)->priv->stopping = TRUE;
+ SEAT_CLASS (seat_xlocal_parent_class)->stop (seat);
+}
+
static void
seat_xlocal_init (SeatXLocal *seat)
{
+ seat->priv = G_TYPE_INSTANCE_GET_PRIVATE (seat, SEAT_XLOCAL_TYPE, SeatXLocalPrivate);
}
static void
seat_class->setup = seat_xlocal_setup;
seat_class->add_display = seat_xlocal_add_display;
seat_class->set_active_display = seat_xlocal_set_active_display;
+ seat_class->display_removed = seat_xlocal_display_removed;
+ seat_class->stop = seat_xlocal_stop;
+
+ g_type_class_add_private (klass, sizeof (SeatXLocalPrivate));
}
#define SEAT_XLOCAL_TYPE (seat_xlocal_get_type())
#define SEAT_XLOCAL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAT_XLOCAL_TYPE, SeatXLocal))
+typedef struct SeatXLocalPrivate SeatXLocalPrivate;
+
typedef struct
{
- Seat parent_instance;
+ Seat parent_instance;
+ SeatXLocalPrivate *priv;
} SeatXLocal;
typedef struct
gboolean autologin_guest;
guint autologin_timeout;
+ /* Display running greeter */
+ Display *greeter_display;
+
/* The displays for this seat */
GList *displays;
}
static gboolean
-display_switch_to_user_cb (Display *display, const gchar *username, Seat *seat)
+switch_to_user (Seat *seat, const gchar *username)
{
GList *link;
/* Switch to active display if it exists */
for (link = seat->priv->displays; link; link = link->next)
{
- Display *d = link->data;
+ Display *display = link->data;
Session *session;
- if (d == display)
- continue;
-
- session = display_get_session (d);
- if (!session || session_get_is_greeter (session))
- continue;
-
/* If already logged in, then switch to that display and stop the greeter display */
- if (g_strcmp0 (user_get_name (session_get_user (session)), username) == 0)
+ session = display_get_session (display);
+ if (session && !session_get_is_greeter (session) &&
+ g_strcmp0 (user_get_name (session_get_user (session)), username) == 0)
{
// FIXME: Use display_get_name
g_debug ("Switching to user %s session on display %s", username, xserver_get_address (XSERVER (display_get_display_server (display))));
return FALSE;
}
+static gboolean
+display_switch_to_user_cb (Display *display, const gchar *username, Seat *seat)
+{
+ return switch_to_user (seat, username);
+}
+
static gboolean
display_switch_to_guest_cb (Display *display, Seat *seat)
{
return g_strdup (seat->priv->guest_username);
}
+static void
+display_session_started_cb (Display *display, Seat *seat)
+{
+ GList *link;
+
+ /* Switch to this new display */
+ SEAT_GET_CLASS (seat)->set_active_display (seat, display);
+
+ /* Stop any other greeters */
+ // FIXME: Do this when the switch is complete
+ for (link = seat->priv->displays; link; link = link->next)
+ {
+ Display *d = link->data;
+ Session *session;
+
+ if (d == display)
+ continue;
+
+ /* Must be a user session */
+ session = display_get_session (d);
+ if (session && session_get_is_greeter (session))
+ {
+ g_debug ("Stopping existing greeter");
+ display_stop (d);
+ }
+ }
+}
+
static void
display_session_stopped_cb (Display *display, Seat *seat)
{
}
static gboolean
-switch_to_user (Seat *seat, const gchar *username, gboolean is_guest, gboolean autologin)
+switch_to_user_or_start_greeter (Seat *seat, const gchar *username, gboolean is_guest, gboolean autologin)
{
- Display *display;
GList *link;
+ Display *new_display = NULL;
/* Switch to active display if it exists */
for (link = seat->priv->displays; link; link = link->next)
{
- display = link->data;
+ Display *display = link->data;
Session *session;
+ const gchar *session_username = NULL;
session = display_get_session (display);
- if (!session)
- continue;
-
- /* Shouldn't be any other greeters running, close them if so */
- if (!session || session_get_is_greeter (session))
- {
- display_stop (display);
- continue;
- }
+ if (session && !session_get_is_greeter (session))
+ session_username = user_get_name (session_get_user (session));
- /* If already logged in, then switch to that display */
- if (g_strcmp0 (user_get_name (session_get_user (session)), username) == 0)
+ /* If already logged in, then switch to that display and stop the greeter display */
+ if (g_strcmp0 (session_username, username) == 0)
{
// FIXME: Use display_get_name
- g_debug ("Switching to user %s session on display %s", username, xserver_get_address (XSERVER (display_get_display_server (display))));
+ if (username)
+ g_debug ("Switching to user %s session on display %s", username, xserver_get_address (XSERVER (display_get_display_server (display))));
+ else
+ g_debug ("Switching to greeter on display %s", xserver_get_address (XSERVER (display_get_display_server (display))));
SEAT_GET_CLASS (seat)->set_active_display (seat, display);
return TRUE;
}
}
/* They don't exist, so start a greeter */
- display = SEAT_GET_CLASS (seat)->add_display (seat);
- display_load_config (DISPLAY (display), seat->priv->config_section);
- g_signal_connect (display, "switch-to-user", G_CALLBACK (display_switch_to_user_cb), seat);
- g_signal_connect (display, "switch-to-guest", G_CALLBACK (display_switch_to_guest_cb), seat);
- g_signal_connect (display, "get-guest-username", G_CALLBACK (display_get_guest_username_cb), seat);
- g_signal_connect (display, "session-stopped", G_CALLBACK (display_session_stopped_cb), seat);
- g_signal_connect (display, "stopped", G_CALLBACK (display_stopped_cb), seat);
- display_set_allow_guest (display, seat_get_allow_guest (seat));
if (is_guest)
- display_set_default_user (display, NULL, TRUE, autologin, 0);
+ g_debug ("Starting new greeter to authenticate guest");
else if (username)
- display_set_default_user (display, username, FALSE, autologin, 0);
+ g_debug ("Starting new greeter to authenticate user %s", username);
+ else
+ g_debug ("Starting new greeter");
+
+ new_display = SEAT_GET_CLASS (seat)->add_display (seat);
+ display_load_config (DISPLAY (new_display), seat->priv->config_section);
+ g_signal_connect (new_display, "switch-to-user", G_CALLBACK (display_switch_to_user_cb), seat);
+ g_signal_connect (new_display, "switch-to-guest", G_CALLBACK (display_switch_to_guest_cb), seat);
+ g_signal_connect (new_display, "get-guest-username", G_CALLBACK (display_get_guest_username_cb), seat);
+ g_signal_connect (new_display, "session-started", G_CALLBACK (display_session_started_cb), seat);
+ g_signal_connect (new_display, "session-stopped", G_CALLBACK (display_session_stopped_cb), seat);
+ g_signal_connect (new_display, "stopped", G_CALLBACK (display_stopped_cb), seat);
+ display_set_allow_guest (new_display, seat_get_allow_guest (seat));
+ if (is_guest)
+ display_set_default_user (new_display, NULL, TRUE, autologin, 0);
+ else if (username)
+ display_set_default_user (new_display, username, FALSE, autologin, 0);
- seat->priv->displays = g_list_append (seat->priv->displays, g_object_ref (display));
- g_signal_emit (seat, signals[DISPLAY_ADDED], 0, display);
+ seat->priv->displays = g_list_append (seat->priv->displays, new_display);
+ g_signal_emit (seat, signals[DISPLAY_ADDED], 0, new_display);
- return display_start (display);
+ return display_start (new_display);
}
gboolean
return FALSE;
g_debug ("Showing greeter");
-
- return switch_to_user (seat, NULL, FALSE, FALSE);
+ return switch_to_user_or_start_greeter (seat, NULL, FALSE, FALSE);
}
gboolean
return FALSE;
g_debug ("Switching to user %s", username);
- return switch_to_user (seat, username, FALSE, FALSE);
+ return switch_to_user_or_start_greeter (seat, username, FALSE, FALSE);
}
gboolean
g_debug ("Switching to existing guest account %s", seat->priv->guest_username);
else
g_debug ("Switching to new guest account");
- return switch_to_user (seat, seat->priv->guest_username, TRUE, TRUE);
+ return switch_to_user_or_start_greeter (seat, seat->priv->guest_username, TRUE, TRUE);
}
void
static gboolean
seat_real_start (Seat *seat)
{
+ g_debug ("Starting seat");
+
/* Start showing a greeter */
if (seat->priv->autologin_username)
- return switch_to_user (seat, seat->priv->autologin_username, FALSE, TRUE);
+ return switch_to_user_or_start_greeter (seat, seat->priv->autologin_username, FALSE, TRUE);
else if (seat->priv->autologin_guest)
- return switch_to_user (seat, NULL, TRUE, TRUE);
+ return switch_to_user_or_start_greeter (seat, NULL, TRUE, TRUE);
else
- return switch_to_user (seat, NULL, FALSE, FALSE);
+ return switch_to_user_or_start_greeter (seat, NULL, FALSE, FALSE);
}
static Display *
plymouth_quit (TRUE);
}
- display_server_set_ready (DISPLAY_SERVER (server));
+ // FIXME: Check return value
+ DISPLAY_SERVER_CLASS (xserver_local_parent_class)->start (DISPLAY_SERVER (server));
}
}
g_object_unref (server->priv->xserver_process);
server->priv->xserver_process = NULL;
+ if (xserver_get_authority (XSERVER (server)) && server->priv->authority_file)
+ {
+ GError *error = NULL;
+ gchar *path;
+
+ path = g_file_get_path (server->priv->authority_file);
+ g_debug ("Removing X server authority from %s", path);
+ g_free (path);
+
+ if (!xauth_write (xserver_get_authority (XSERVER (server)), XAUTH_WRITE_MODE_REMOVE, NULL, server->priv->authority_file, &error))
+ g_debug ("Error removing authority: %s", error->message);
+ g_clear_error (&error);
+
+ g_object_unref (server->priv->authority_file);
+ server->priv->authority_file = NULL;
+ }
+
+ release_display_number (xserver_get_display_number (XSERVER (server)));
+
+ if (server->priv->vt >= 0)
+ vt_release (server->priv->vt);
+
if (server->priv->replacing_plymouth && plymouth_get_is_running ())
{
g_debug ("Stopping Plymouth, X server failed to start");
plymouth_quit (FALSE);
}
- display_server_set_stopped (DISPLAY_SERVER (server));
+ DISPLAY_SERVER_CLASS (xserver_local_parent_class)->stop (DISPLAY_SERVER (server));
}
static void
GError *error = NULL;
authority = xserver_get_authority (XSERVER (server));
+ if (!authority)
+ return;
/* Get file to write to if have authority */
- if (authority && !server->priv->authority_file)
+ if (!server->priv->authority_file)
{
gchar *run_dir, *dir;
g_free (path);
}
- /* Delete existing file if no authority */
- if (!authority)
- {
- if (server->priv->authority_file)
- {
- path = g_file_get_path (server->priv->authority_file);
- g_debug ("Deleting X server authority %s", path);
- g_free (path);
-
- g_file_delete (server->priv->authority_file, NULL, NULL);
- g_object_unref (server->priv->authority_file);
- server->priv->authority_file = NULL;
- }
- return;
- }
-
path = g_file_get_path (server->priv->authority_file);
g_debug ("Writing X server authority to %s", path);
g_free (path);
- if (!xauth_write (authority, XAUTH_WRITE_MODE_SET, NULL, server->priv->authority_file, &error))
+ if (!xauth_write (authority, XAUTH_WRITE_MODE_REPLACE, NULL, server->priv->authority_file, &error))
g_warning ("Failed to write authority: %s", error->message);
g_clear_error (&error);
}
return result;
}
-static gboolean
-xserver_local_restart (DisplayServer *display_server)
-{
- XServerLocal *server = XSERVER_LOCAL (display_server);
- gchar hostname[1024], *number;
-
- /* Not running */
- if (!server->priv->xserver_process)
- return FALSE;
-
- /* Can only restart with not using authentication */
- if (server->priv->xdmcp_key)
- return FALSE;
-
- g_debug ("Generating new cookie for X server");
- gethostname (hostname, 1024);
- number = g_strdup_printf ("%d", xserver_get_display_number (XSERVER (server)));
- xserver_set_authority (XSERVER (server), xauth_new_cookie (XAUTH_FAMILY_LOCAL, hostname, number));
- g_free (number);
- write_authority_file (server);
-
- g_debug ("Sending signal to X server to disconnect clients");
-
- server->priv->got_signal = FALSE;
- process_signal (server->priv->xserver_process, SIGHUP);
-
- return TRUE;
-}
-
static void
xserver_local_stop (DisplayServer *server)
{
self = XSERVER_LOCAL (object);
- release_display_number (xserver_get_display_number (XSERVER (self)));
-
- if (self->priv->vt >= 0)
- vt_release (self->priv->vt);
-
+ if (self->priv->xserver_process)
+ g_object_unref (self->priv->xserver_process);
g_free (self->priv->command);
g_free (self->priv->config_file);
g_free (self->priv->layout);
g_free (self->priv->xdmcp_server);
g_free (self->priv->xdmcp_key);
if (self->priv->authority_file)
- {
- g_file_delete (self->priv->authority_file, NULL, NULL);
g_object_unref (self->priv->authority_file);
- }
G_OBJECT_CLASS (xserver_local_parent_class)->finalize (object);
}
DisplayServerClass *display_server_class = DISPLAY_SERVER_CLASS (klass);
display_server_class->start = xserver_local_start;
- display_server_class->restart = xserver_local_restart;
display_server_class->stop = xserver_local_stop;
object_class->finalize = xserver_local_finalize;
return self;
}
-static gboolean
-xserver_remote_start (DisplayServer *server)
-{
- display_server_set_ready (DISPLAY_SERVER (server));
- return TRUE;
-}
-
-static void
-xserver_remote_stop (DisplayServer *server)
-{
- display_server_set_stopped (DISPLAY_SERVER (server));
-}
-
static void
xserver_remote_init (XServerRemote *server)
{
static void
xserver_remote_class_init (XServerRemoteClass *klass)
{
- DisplayServerClass *display_server_class = DISPLAY_SERVER_CLASS (klass);
-
- display_server_class->start = xserver_remote_start;
- display_server_class->stop = xserver_remote_stop;
}
*/
#include <config.h>
+#include <string.h>
+#include <xcb/xcb.h>
#include "xserver.h"
#include "configuration.h"
/* Authority */
XAuthority *authority;
+
+ /* Connection to this X server */
+ xcb_connection_t *connection;
};
G_DEFINE_TYPE (XServer, xserver, DISPLAY_SERVER_TYPE);
return server->priv->authority;
}
+static gboolean
+xserver_start (DisplayServer *display_server)
+{
+ XServer *server = XSERVER (display_server);
+ xcb_auth_info_t *auth = NULL, a;
+
+ if (server->priv->authority)
+ {
+ a.namelen = strlen (xauth_get_authorization_name (server->priv->authority));
+ a.name = (char *) xauth_get_authorization_name (server->priv->authority);
+ a.datalen = xauth_get_authorization_data_length (server->priv->authority);
+ a.data = (char *) xauth_get_authorization_data (server->priv->authority);
+ auth = &a;
+ }
+
+ /* Open connection */
+ g_debug ("Connecting to XServer %s", xserver_get_address (server));
+ server->priv->connection = xcb_connect_to_display_with_auth_info (xserver_get_address (server), auth, NULL);
+ if (xcb_connection_has_error (server->priv->connection))
+ {
+ g_debug ("Error connecting to XServer %s", xserver_get_address (server));
+ return FALSE;
+ }
+
+ return DISPLAY_SERVER_CLASS (xserver_parent_class)->start (display_server);
+}
+
static void
xserver_init (XServer *server)
{
g_free (self->priv->address);
if (self->priv->authority)
g_object_unref (self->priv->authority);
+ if (self->priv->connection)
+ xcb_disconnect (self->priv->connection);
G_OBJECT_CLASS (xserver_parent_class)->finalize (object);
}
xserver_class_init (XServerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ DisplayServerClass *display_server_class = DISPLAY_SERVER_CLASS (klass);
+ display_server_class->start = xserver_start;
object_class->finalize = xserver_finalize;
g_type_class_add_private (klass, sizeof (XServerPrivate));
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Default session starts
SESSION START USER=guest
XSERVER :50 ACCEPT-CONNECT
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Autologin session starts
SESSION START USER=alice
XSERVER :50 ACCEPT-CONNECT
# Logout
SESSION LOGOUT
-# X server resets
-XSERVER :50 DISCONNECT-CLIENTS
+# X server stops
+XSERVER :50 TERMINATE SIGNAL=15
+
+# X server starts
+XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Default session starts
SESSION START USER=alice
XSERVER :50 ACCEPT-CONNECT
# Session terminates
SESSION TERMINATE SIGNAL=15
-# X server restarts and loads greeter
+# X server restarts
XSERVER :50 START
XSERVER :50 INDICATE-READY
+
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
+# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
GREETER CONNECT-XSERVER :50
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Default session starts
SESSION START USER=alice
XSERVER :50 ACCEPT-CONNECT
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
GREETER CRASH-XSERVER
XSERVER :50 CRASH
-# X server restarts and loads greeter
+# X server restarts
XSERVER :50 START
XSERVER :50 INDICATE-READY
+
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
+# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
GREETER CONNECT-XSERVER :50
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
GREETER AUTHENTICATION-COMPLETE AUTHENTICATED=TRUE
GREETER TERMINATE SIGNAL=15
-# X server resets
-XSERVER :50 DISCONNECT-CLIENTS
-XSERVER :50 INDICATE-READY
-
# (guest account attempts to start, fails, then returns to greeter)
# Greeter starts
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
GREETER AUTHENTICATION-COMPLETE AUTHENTICATED=TRUE
GREETER TERMINATE SIGNAL=15
-# X server resets
-XSERVER :50 DISCONNECT-CLIENTS
-XSERVER :50 INDICATE-READY
-
# Guest session starts
SESSION START USER=guest
XSERVER :50 ACCEPT-CONNECT
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
GREETER AUTHENTICATION-COMPLETE USERNAME=alice AUTHENTICATED=TRUE
GREETER TERMINATE SIGNAL=15
-# X server resets
-XSERVER :50 DISCONNECT-CLIENTS
-XSERVER :50 INDICATE-READY
-
# Session starts
SESSION START USER=alice
XSERVER :50 ACCEPT-CONNECT
# Logout of session
SESSION LOGOUT
-# X server resets
-XSERVER :50 DISCONNECT-CLIENTS
+# X server stops
+XSERVER :50 TERMINATE SIGNAL=15
+
+# X server starts
+XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
GREETER AUTHENTICATION-COMPLETE USERNAME=alice AUTHENTICATED=TRUE
GREETER TERMINATE SIGNAL=15
-# X server resets
-XSERVER :50 DISCONNECT-CLIENTS
-XSERVER :50 INDICATE-READY
-
# Session starts
SESSION START USER=alice
XSERVER :50 ACCEPT-CONNECT
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
GREETER AUTHENTICATION-COMPLETE USERNAME=bob AUTHENTICATED=TRUE
GREETER TERMINATE SIGNAL=15
-# X server resets
-XSERVER :50 DISCONNECT-CLIENTS
-XSERVER :50 INDICATE-READY
-
# Session starts
SESSION START USER=bob
XSERVER :50 ACCEPT-CONNECT
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
GREETER AUTHENTICATION-COMPLETE USERNAME=alice AUTHENTICATED=TRUE
GREETER TERMINATE SIGNAL=15
-# X server resets
-XSERVER :50 DISCONNECT-CLIENTS
-XSERVER :50 INDICATE-READY
-
# Session starts
SESSION START USER=alice
XSERVER :50 ACCEPT-CONNECT
# Session crashes
SESSION CRASH
-# X server resets
-XSERVER :50 DISCONNECT-CLIENTS
+# X server stops
+XSERVER :50 TERMINATE SIGNAL=15
+
+# X server starts
+XSERVER :50 START
XSERVER :50 INDICATE-READY
-# Greeter starts on X server
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
+# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
GREETER CONNECT-XSERVER :50
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
GREETER AUTHENTICATION-COMPLETE USERNAME=alice AUTHENTICATED=TRUE
GREETER TERMINATE SIGNAL=15
-# X server resets
-XSERVER :50 DISCONNECT-CLIENTS
-XSERVER :50 INDICATE-READY
-
# Session starts
SESSION START USER=alice
XSERVER :50 ACCEPT-CONNECT
# User session is terminated
SESSION TERMINATE SIGNAL=15
-# X server restarts and loads greeter
+# X server restarts
XSERVER :50 START
XSERVER :50 INDICATE-READY
+XSERVER :50 ACCEPT-CONNECT
+
+# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
GREETER CONNECT-XSERVER :50
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
GREETER CONNECT-TO-DAEMON
GREETER CONNECTED-TO-DAEMON
-# Login
+# Login as alice
GREETER AUTHENTICATE USERNAME=alice
GREETER SHOW-PROMPT TEXT="Password:"
GREETER RESPOND TEXT="password"
GREETER AUTHENTICATION-COMPLETE USERNAME=alice AUTHENTICATED=TRUE
GREETER TERMINATE SIGNAL=15
-# X server resets
-XSERVER :50 DISCONNECT-CLIENTS
-XSERVER :50 INDICATE-READY
-
# Session starts
SESSION START USER=alice
XSERVER :50 ACCEPT-CONNECT
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
# X server starts
XSERVER :50 START
XSERVER :50 INDICATE-READY
+
+# Plymouth quits but keeps image in framebuffer
PLYMOUTH QUIT RETAIN-SPLASH=TRUE
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
GREETER AUTHENTICATION-COMPLETE USERNAME=alice AUTHENTICATED=TRUE
GREETER TERMINATE SIGNAL=15
-# X server resets
-XSERVER :50 DISCONNECT-CLIENTS
-XSERVER :50 INDICATE-READY
-
# Session starts
SESSION START USER=alice
XSERVER :50 ACCEPT-CONNECT
XSERVER :51 START
XSERVER :51 INDICATE-READY
+# LightDM connects to X server
+XSERVER :51 ACCEPT-CONNECT
+
# Greeter starts
GREETER START
XSERVER :51 ACCEPT-CONNECT
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Default session starts
SESSION START USER=alice
XSERVER :50 ACCEPT-CONNECT
XSERVER :51 START
XSERVER :51 INDICATE-READY
+# LightDM connects to X server
+XSERVER :51 ACCEPT-CONNECT
+
# Guest session starts
SESSION START USER=guest
XSERVER :51 ACCEPT-CONNECT
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
*SWITCH-TO-USER USERNAME=alice
RUNNER SWITCH-TO-USER USERNAME=alice
-# Existing X server and greeter stops
-(GREETER TERMINATE SIGNAL=15|XSERVER :50 TERMINATE SIGNAL=15)
-(GREETER TERMINATE SIGNAL=15|XSERVER :50 TERMINATE SIGNAL=15)
-
# New X server starts
XSERVER :51 START
XSERVER :51 INDICATE-READY
-# New greeter starts
-GREETER START
+# LightDM connects to X server
XSERVER :51 ACCEPT-CONNECT
-GREETER CONNECT-XSERVER :51
-GREETER CONNECT-TO-DAEMON
-GREETER CONNECTED-TO-DAEMON
+
+# Existing X server stops, new greeter starts
+(XSERVER :50 TERMINATE SIGNAL=15|GREETER TERMINATE SIGNAL=15||GREETER CONNECT-XSERVER :51|XSERVER :51 ACCEPT-CONNECT|GREETER CONNECT-TO-DAEMON|GREETER CONNECTED-TO-DAEMON)
+(XSERVER :50 TERMINATE SIGNAL=15|GREETER TERMINATE SIGNAL=15|GREETER START|GREETER CONNECT-XSERVER :51|XSERVER :51 ACCEPT-CONNECT|GREETER CONNECT-TO-DAEMON|GREETER CONNECTED-TO-DAEMON)
+(XSERVER :50 TERMINATE SIGNAL=15|GREETER TERMINATE SIGNAL=15|GREETER START|GREETER CONNECT-XSERVER :51|XSERVER :51 ACCEPT-CONNECT|GREETER CONNECT-TO-DAEMON|GREETER CONNECTED-TO-DAEMON)
+(XSERVER :50 TERMINATE SIGNAL=15|GREETER TERMINATE SIGNAL=15|GREETER START|GREETER CONNECT-XSERVER :51|XSERVER :51 ACCEPT-CONNECT|GREETER CONNECT-TO-DAEMON|GREETER CONNECTED-TO-DAEMON)
+(XSERVER :50 TERMINATE SIGNAL=15|GREETER TERMINATE SIGNAL=15|GREETER START|GREETER CONNECT-XSERVER :51|XSERVER :51 ACCEPT-CONNECT|GREETER CONNECT-TO-DAEMON|GREETER CONNECTED-TO-DAEMON)
+(XSERVER :50 TERMINATE SIGNAL=15|GREETER TERMINATE SIGNAL=15|GREETER START|GREETER CONNECT-XSERVER :51|XSERVER :51 ACCEPT-CONNECT|GREETER CONNECT-TO-DAEMON|GREETER CONNECTED-TO-DAEMON)
+(XSERVER :50 TERMINATE SIGNAL=15|GREETER TERMINATE SIGNAL=15|GREETER START|GREETER CONNECT-XSERVER :51|XSERVER :51 ACCEPT-CONNECT|GREETER CONNECT-TO-DAEMON|GREETER CONNECTED-TO-DAEMON)
# Alice is automatically selected
GREETER AUTHENTICATE-SELECTED USERNAME=alice
XSERVER :98 GOT-ACCEPT SESSION-ID=[0-9]* AUTHENTICATION-NAME="" AUTHORIZATION-NAME=""
XSERVER :98 SEND-MANAGE SESSION-ID=[0-9]* DISPLAY-NUMBER=98 DISPLAY-CLASS="DISPLAY CLASS"
+# LightDM connects to X server
+XSERVER :98 ACCEPT-CONNECT
+
# Greeter starts and connects to remote X server
GREETER START
XSERVER :98 ACCEPT-CONNECT
XSERVER :50 START
XSERVER :50 INDICATE-READY
+# LightDM connects to X server
+XSERVER :50 ACCEPT-CONNECT
+
# Greeter starts
GREETER START
XSERVER :50 ACCEPT-CONNECT
}
}
+static void
+indicate_ready ()
+{
+ void *handler;
+ handler = signal (SIGUSR1, SIG_IGN);
+ if (handler == SIG_IGN)
+ {
+ notify_status ("XSERVER :%d INDICATE-READY", display_number);
+ kill (getppid (), SIGUSR1);
+ }
+ signal (SIGUSR1, handler);
+}
+
static gboolean
socket_data_cb (GIOChannel *channel, GIOCondition condition, gpointer data)
{
+ Connection *connection;
guint8 buffer[MAXIMUM_REQUEST_LENGTH];
gssize n_read;
+ connection = g_hash_table_lookup (connections, channel);
+
n_read = recv (g_io_channel_unix_get_fd (channel), buffer, MAXIMUM_REQUEST_LENGTH, 0);
if (n_read < 0)
g_warning ("Error reading from socket: %s", strerror (errno));
else if (n_read == 0)
{
- g_debug ("EOF");
+ if (connection)
+ {
+ g_debug ("Client disconnected");
+ g_hash_table_remove (connections, connection->channel);
+ if (g_hash_table_size (connections) == 0)
+ indicate_ready ();
+ }
+ else
+ g_debug ("EOF before connection made");
return FALSE;
}
else
{
- Connection *connection;
-
log_buffer ("Read X", buffer, n_read);
- connection = g_hash_table_lookup (connections, channel);
if (connection)
decode_request (connection, buffer, n_read);
else
return TRUE;
}
-static void
-indicate_ready ()
-{
- void *handler;
- handler = signal (SIGUSR1, SIG_IGN);
- if (handler == SIG_IGN)
- {
- notify_status ("XSERVER :%d INDICATE-READY", display_number);
- kill (getppid (), SIGUSR1);
- }
- signal (SIGUSR1, handler);
-}
-
static void
signal_cb (int signum)
{