summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Ancell <robert.ancell@canonical.com>2014-09-12 11:46:42 +1200
committerRobert Ancell <robert.ancell@canonical.com>2014-09-12 11:46:42 +1200
commitac3b5e59c3f35e325be39a32fe34bfebabd974aa (patch)
tree41c253ff0f533c686c83853c7bed97b6b010f5d4
parente726d281920fe472616d04d80fe844a3b837ea64 (diff)
downloadlightdm-git-ac3b5e59c3f35e325be39a32fe34bfebabd974aa.tar.gz
Refactor XDMCP client code so it's not hardcoded to use X in seat.c
-rw-r--r--src/seat-unity.c173
-rw-r--r--src/seat-xlocal.c173
-rw-r--r--src/seat.c38
-rw-r--r--src/seat.h3
4 files changed, 233 insertions, 154 deletions
diff --git a/src/seat-unity.c b/src/seat-unity.c
index e116ead7..ec0678a1 100644
--- a/src/seat-unity.c
+++ b/src/seat-unity.c
@@ -27,6 +27,9 @@ struct SeatUnityPrivate
/* System compositor */
UnitySystemCompositor *compositor;
+ /* X server being used for XDMCP */
+ XServerLocal *xdmcp_x_server;
+
/* Next Mir ID to use for a Mir sessions, X server and greeters */
gint next_session_id;
gint next_x_server_id;
@@ -39,11 +42,7 @@ struct SeatUnityPrivate
G_DEFINE_TYPE (SeatUnity, seat_unity, SEAT_TYPE);
-static gboolean
-seat_unity_get_start_local_sessions (Seat *seat)
-{
- return !seat_get_string_property (seat, "xdmcp-manager");
-}
+static XServerLocal *create_x_server (Seat *seat);
static void
seat_unity_setup (Seat *seat)
@@ -53,27 +52,103 @@ seat_unity_setup (Seat *seat)
}
static void
+check_stopped (SeatUnity *seat)
+{
+ if (!seat->priv->compositor && !seat->priv->xdmcp_x_server)
+ SEAT_CLASS (seat_unity_parent_class)->stop (SEAT (seat));
+}
+
+static void
+xdmcp_x_server_stopped_cb (DisplayServer *display_server, Seat *seat)
+{
+ l_debug (seat, "XDMCP X server stopped");
+
+ g_signal_handlers_disconnect_matched (SEAT_UNITY (seat)->priv->xdmcp_x_server, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, seat);
+ SEAT_UNITY (seat)->priv->xdmcp_x_server = NULL;
+
+ g_object_unref (display_server);
+
+ if (seat_get_is_stopping (seat))
+ check_stopped (SEAT_UNITY (seat));
+ else
+ seat_stop (seat);
+}
+
+static void
compositor_ready_cb (UnitySystemCompositor *compositor, SeatUnity *seat)
{
- l_debug (seat, "Compositor ready");
+ const gchar *xdmcp_manager = NULL;
+
+ l_debug (seat, "Compositor ready");
+
+ /* If running as an XDMCP client then just start an X server */
+ xdmcp_manager = seat_get_string_property (SEAT (seat), "xdmcp-manager");
+ if (xdmcp_manager)
+ {
+ const gchar *key_name = NULL;
+ gint port = 0;
+
+ seat->priv->xdmcp_x_server = create_x_server (SEAT (seat));
+ x_server_local_set_xdmcp_server (seat->priv->xdmcp_x_server, xdmcp_manager);
+ port = seat_get_integer_property (SEAT (seat), "xdmcp-port");
+ if (port > 0)
+ x_server_local_set_xdmcp_port (seat->priv->xdmcp_x_server, port);
+ key_name = seat_get_string_property (SEAT (seat), "xdmcp-key");
+ if (key_name)
+ {
+ gchar *dir, *path;
+ GKeyFile *keys;
+ gboolean result;
+ GError *error = NULL;
+
+ dir = config_get_string (config_get_instance (), "LightDM", "config-directory");
+ path = g_build_filename (dir, "keys.conf", NULL);
+ g_free (dir);
+
+ keys = g_key_file_new ();
+ result = g_key_file_load_from_file (keys, path, G_KEY_FILE_NONE, &error);
+ if (error)
+ l_debug (seat, "Error getting key %s", error->message);
+ g_clear_error (&error);
+
+ if (result)
+ {
+ gchar *key = NULL;
+
+ if (g_key_file_has_key (keys, "keyring", key_name, NULL))
+ key = g_key_file_get_string (keys, "keyring", key_name, NULL);
+ else
+ l_debug (seat, "Key %s not defined", key_name);
+
+ if (key)
+ x_server_local_set_xdmcp_key (seat->priv->xdmcp_x_server, key);
+ g_free (key);
+ }
+
+ g_free (path);
+ g_key_file_free (keys);
+ }
+
+ g_signal_connect (seat->priv->xdmcp_x_server, "stopped", G_CALLBACK (xdmcp_x_server_stopped_cb), seat);
+ if (!display_server_start (DISPLAY_SERVER (seat->priv->xdmcp_x_server)))
+ seat_stop (SEAT (seat));
+ }
+
SEAT_CLASS (seat_unity_parent_class)->start (SEAT (seat));
}
static void
compositor_stopped_cb (UnitySystemCompositor *compositor, SeatUnity *seat)
{
+ l_debug (seat, "Compositor stopped");
+
g_object_unref (seat->priv->compositor);
seat->priv->compositor = NULL;
if (seat_get_is_stopping (SEAT (seat)))
- {
- SEAT_CLASS (seat_unity_parent_class)->stop (SEAT (seat));
- return;
- }
-
- l_debug (seat, "Stopping Unity seat, compositor terminated");
-
- seat_stop (SEAT (seat));
+ check_stopped (seat);
+ else
+ seat_stop (SEAT (seat));
}
static gboolean
@@ -104,27 +179,26 @@ seat_unity_start (Seat *seat)
return FALSE;
}
- timeout = seat_get_integer_property (seat, "unity-compositor-timeout");
+ timeout = seat_get_integer_property (SEAT (seat), "unity-compositor-timeout");
if (timeout <= 0)
timeout = 60;
SEAT_UNITY (seat)->priv->compositor = unity_system_compositor_new ();
g_signal_connect (SEAT_UNITY (seat)->priv->compositor, "ready", G_CALLBACK (compositor_ready_cb), seat);
g_signal_connect (SEAT_UNITY (seat)->priv->compositor, "stopped", G_CALLBACK (compositor_stopped_cb), seat);
- unity_system_compositor_set_command (SEAT_UNITY (seat)->priv->compositor, seat_get_string_property (seat, "unity-compositor-command"));
+ unity_system_compositor_set_command (SEAT_UNITY (seat)->priv->compositor, seat_get_string_property (SEAT (seat), "unity-compositor-command"));
unity_system_compositor_set_vt (SEAT_UNITY (seat)->priv->compositor, vt);
unity_system_compositor_set_timeout (SEAT_UNITY (seat)->priv->compositor, timeout);
return display_server_start (DISPLAY_SERVER (SEAT_UNITY (seat)->priv->compositor));
}
-static DisplayServer *
+static XServerLocal *
create_x_server (Seat *seat)
{
XServerLocal *x_server;
- const gchar *command = NULL, *layout = NULL, *config_file = NULL, *xdmcp_manager = NULL, *key_name = NULL;
+ const gchar *command = NULL, *layout = NULL, *config_file = NULL;
gboolean allow_tcp;
- gint port = 0;
gchar *id;
l_debug (seat, "Starting X server on Unity compositor");
@@ -154,49 +228,7 @@ create_x_server (Seat *seat)
allow_tcp = seat_get_boolean_property (seat, "xserver-allow-tcp");
x_server_local_set_allow_tcp (x_server, allow_tcp);
- xdmcp_manager = seat_get_string_property (seat, "xdmcp-manager");
- if (xdmcp_manager)
- x_server_local_set_xdmcp_server (x_server, xdmcp_manager);
-
- port = seat_get_integer_property (seat, "xdmcp-port");
- if (port > 0)
- x_server_local_set_xdmcp_port (x_server, port);
-
- key_name = seat_get_string_property (seat, "xdmcp-key");
- if (key_name)
- {
- gchar *path;
- GKeyFile *keys;
- gboolean result;
- GError *error = NULL;
-
- path = g_build_filename (config_get_directory (config_get_instance ()), "keys.conf", NULL);
-
- keys = g_key_file_new ();
- result = g_key_file_load_from_file (keys, path, G_KEY_FILE_NONE, &error);
- if (error)
- l_debug (seat, "Error getting key %s", error->message);
- g_clear_error (&error);
-
- if (result)
- {
- gchar *key = NULL;
-
- if (g_key_file_has_key (keys, "keyring", key_name, NULL))
- key = g_key_file_get_string (keys, "keyring", key_name, NULL);
- else
- l_debug (seat, "Key %s not defined", key_name);
-
- if (key)
- x_server_local_set_xdmcp_key (x_server, key);
- g_free (key);
- }
-
- g_free (path);
- g_key_file_free (keys);
- }
-
- return DISPLAY_SERVER (x_server);
+ return x_server;
}
static DisplayServer *
@@ -214,7 +246,7 @@ static DisplayServer *
seat_unity_create_display_server (Seat *seat, const gchar *session_type)
{
if (strcmp (session_type, "x") == 0)
- return create_x_server (seat);
+ return DISPLAY_SERVER (create_x_server (seat));
else if (strcmp (session_type, "mir") == 0)
return create_mir_server (seat);
else
@@ -363,12 +395,13 @@ seat_unity_stop (Seat *seat)
{
/* Stop the compositor first */
if (SEAT_UNITY (seat)->priv->compositor)
- {
display_server_stop (DISPLAY_SERVER (SEAT_UNITY (seat)->priv->compositor));
- return;
- }
- SEAT_CLASS (seat_unity_parent_class)->stop (seat);
+ /* Stop the XDMCP X server first */
+ if (SEAT_UNITY (seat)->priv->xdmcp_x_server)
+ display_server_stop (DISPLAY_SERVER (SEAT_UNITY (seat)->priv->xdmcp_x_server));
+
+ check_stopped (SEAT_UNITY (seat));
}
static void
@@ -384,6 +417,11 @@ seat_unity_finalize (GObject *object)
if (seat->priv->compositor)
g_object_unref (seat->priv->compositor);
+ if (seat->priv->xdmcp_x_server)
+ {
+ g_signal_handlers_disconnect_matched (seat->priv->xdmcp_x_server, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, seat);
+ g_object_unref (seat->priv->xdmcp_x_server);
+ }
if (seat->priv->active_session)
g_object_unref (seat->priv->active_session);
if (seat->priv->active_display_server)
@@ -399,7 +437,6 @@ seat_unity_class_init (SeatUnityClass *klass)
SeatClass *seat_class = SEAT_CLASS (klass);
object_class->finalize = seat_unity_finalize;
- seat_class->get_start_local_sessions = seat_unity_get_start_local_sessions;
seat_class->setup = seat_unity_setup;
seat_class->start = seat_unity_start;
seat_class->create_display_server = seat_unity_create_display_server;
diff --git a/src/seat-xlocal.c b/src/seat-xlocal.c
index 08baa75e..b29801f6 100644
--- a/src/seat-xlocal.c
+++ b/src/seat-xlocal.c
@@ -18,13 +18,15 @@
#include "plymouth.h"
#include "vt.h"
+struct SeatXLocalPrivate
+{
+ /* X server being used for XDMCP */
+ XServerLocal *xdmcp_x_server;
+};
+
G_DEFINE_TYPE (SeatXLocal, seat_xlocal, SEAT_TYPE);
-static gboolean
-seat_xlocal_get_start_local_sessions (Seat *seat)
-{
- return !seat_get_string_property (seat, "xdmcp-manager");
-}
+static XServerLocal *create_x_server (Seat *seat);
static void
seat_xlocal_setup (Seat *seat)
@@ -34,9 +36,86 @@ seat_xlocal_setup (Seat *seat)
SEAT_CLASS (seat_xlocal_parent_class)->setup (seat);
}
+static void
+check_stopped (SeatXLocal *seat)
+{
+ if (!seat->priv->xdmcp_x_server)
+ SEAT_CLASS (seat_xlocal_parent_class)->stop (SEAT (seat));
+}
+
+static void
+xdmcp_x_server_stopped_cb (DisplayServer *display_server, Seat *seat)
+{
+ l_debug (seat, "XDMCP X server stopped");
+
+ g_signal_handlers_disconnect_matched (SEAT_XLOCAL (seat)->priv->xdmcp_x_server, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, seat);
+ SEAT_XLOCAL (seat)->priv->xdmcp_x_server = NULL;
+ g_object_unref (display_server);
+
+ if (seat_get_is_stopping (seat))
+ check_stopped (SEAT_XLOCAL (seat));
+ else
+ seat_stop (seat);
+}
+
static gboolean
seat_xlocal_start (Seat *seat)
{
+ const gchar *xdmcp_manager = NULL;
+
+ /* If running as an XDMCP client then just start an X server */
+ xdmcp_manager = seat_get_string_property (seat, "xdmcp-manager");
+ if (xdmcp_manager)
+ {
+ SeatXLocal *s = SEAT_XLOCAL (seat);
+ const gchar *key_name = NULL;
+ gint port = 0;
+
+ s->priv->xdmcp_x_server = create_x_server (seat);
+ x_server_local_set_xdmcp_server (s->priv->xdmcp_x_server, xdmcp_manager);
+ port = seat_get_integer_property (seat, "xdmcp-port");
+ if (port > 0)
+ x_server_local_set_xdmcp_port (s->priv->xdmcp_x_server, port);
+ key_name = seat_get_string_property (seat, "xdmcp-key");
+ if (key_name)
+ {
+ gchar *dir, *path;
+ GKeyFile *keys;
+ gboolean result;
+ GError *error = NULL;
+
+ dir = config_get_string (config_get_instance (), "LightDM", "config-directory");
+ path = g_build_filename (dir, "keys.conf", NULL);
+ g_free (dir);
+
+ keys = g_key_file_new ();
+ result = g_key_file_load_from_file (keys, path, G_KEY_FILE_NONE, &error);
+ if (error)
+ l_debug (seat, "Error getting key %s", error->message);
+ g_clear_error (&error);
+
+ if (result)
+ {
+ gchar *key = NULL;
+
+ if (g_key_file_has_key (keys, "keyring", key_name, NULL))
+ key = g_key_file_get_string (keys, "keyring", key_name, NULL);
+ else
+ l_debug (seat, "Key %s not defined", key_name);
+
+ if (key)
+ x_server_local_set_xdmcp_key (s->priv->xdmcp_x_server, key);
+ g_free (key);
+ }
+
+ g_free (path);
+ g_key_file_free (keys);
+ }
+
+ g_signal_connect (s->priv->xdmcp_x_server, "stopped", G_CALLBACK (xdmcp_x_server_stopped_cb), seat);
+ return display_server_start (DISPLAY_SERVER (s->priv->xdmcp_x_server));
+ }
+
return SEAT_CLASS (seat_xlocal_parent_class)->start (seat);
}
@@ -87,13 +166,13 @@ get_vt (Seat *seat, DisplayServer *display_server)
return vt;
}
-static DisplayServer *
+static XServerLocal *
create_x_server (Seat *seat)
{
XServerLocal *x_server;
- const gchar *command = NULL, *layout = NULL, *config_file = NULL, *xdmcp_manager = NULL, *key_name = NULL;
+ const gchar *command = NULL, *layout = NULL, *config_file = NULL;
gboolean allow_tcp;
- gint vt, port = 0;
+ gint vt;
x_server = x_server_local_new ();
@@ -129,49 +208,7 @@ create_x_server (Seat *seat)
allow_tcp = seat_get_boolean_property (seat, "xserver-allow-tcp");
x_server_local_set_allow_tcp (x_server, allow_tcp);
- xdmcp_manager = seat_get_string_property (seat, "xdmcp-manager");
- if (xdmcp_manager)
- x_server_local_set_xdmcp_server (x_server, xdmcp_manager);
-
- port = seat_get_integer_property (seat, "xdmcp-port");
- if (port > 0)
- x_server_local_set_xdmcp_port (x_server, port);
-
- key_name = seat_get_string_property (seat, "xdmcp-key");
- if (key_name)
- {
- gchar *path;
- GKeyFile *keys;
- gboolean result;
- GError *error = NULL;
-
- path = g_build_filename (config_get_directory (config_get_instance ()), "keys.conf", NULL);
-
- keys = g_key_file_new ();
- result = g_key_file_load_from_file (keys, path, G_KEY_FILE_NONE, &error);
- if (error)
- l_debug (seat, "Error getting key %s", error->message);
- g_clear_error (&error);
-
- if (result)
- {
- gchar *key = NULL;
-
- if (g_key_file_has_key (keys, "keyring", key_name, NULL))
- key = g_key_file_get_string (keys, "keyring", key_name, NULL);
- else
- l_debug (seat, "Key %s not defined", key_name);
-
- if (key)
- x_server_local_set_xdmcp_key (x_server, key);
- g_free (key);
- }
-
- g_free (path);
- g_key_file_free (keys);
- }
-
- return DISPLAY_SERVER (x_server);
+ return x_server;
}
static DisplayServer *
@@ -215,7 +252,7 @@ static DisplayServer *
seat_xlocal_create_display_server (Seat *seat, const gchar *session_type)
{
if (strcmp (session_type, "x") == 0)
- return create_x_server (seat);
+ return DISPLAY_SERVER (create_x_server (seat));
else if (strcmp (session_type, "mir") == 0)
return create_unity_system_compositor (seat);
else
@@ -295,16 +332,43 @@ seat_xlocal_run_script (Seat *seat, DisplayServer *display_server, Process *scri
}
static void
+seat_xlocal_stop (Seat *seat)
+{
+ /* Stop the XDMCP X server first */
+ if (SEAT_XLOCAL (seat)->priv->xdmcp_x_server)
+ display_server_stop (DISPLAY_SERVER (SEAT_XLOCAL (seat)->priv->xdmcp_x_server));
+
+ check_stopped (SEAT_XLOCAL (seat));
+}
+
+static void
seat_xlocal_init (SeatXLocal *seat)
{
+ seat->priv = G_TYPE_INSTANCE_GET_PRIVATE (seat, SEAT_XLOCAL_TYPE, SeatXLocalPrivate);
+}
+
+static void
+seat_xlocal_finalize (GObject *object)
+{
+ SeatXLocal *seat = SEAT_XLOCAL (object);
+
+ if (seat->priv->xdmcp_x_server)
+ {
+ g_signal_handlers_disconnect_matched (seat->priv->xdmcp_x_server, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, seat);
+ g_object_unref (seat->priv->xdmcp_x_server);
+ }
+
+ G_OBJECT_CLASS (seat_xlocal_parent_class)->finalize (object);
}
static void
seat_xlocal_class_init (SeatXLocalClass *klass)
{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
SeatClass *seat_class = SEAT_CLASS (klass);
- seat_class->get_start_local_sessions = seat_xlocal_get_start_local_sessions;
+ object_class->finalize = seat_xlocal_finalize;
+
seat_class->setup = seat_xlocal_setup;
seat_class->start = seat_xlocal_start;
seat_class->create_display_server = seat_xlocal_create_display_server;
@@ -313,4 +377,7 @@ seat_xlocal_class_init (SeatXLocalClass *klass)
seat_class->set_active_session = seat_xlocal_set_active_session;
seat_class->get_active_session = seat_xlocal_get_active_session;
seat_class->run_script = seat_xlocal_run_script;
+ seat_class->stop = seat_xlocal_stop;
+
+ g_type_class_add_private (klass, sizeof (SeatXLocalPrivate));
}
diff --git a/src/seat.c b/src/seat.c
index 208e942b..090e1e35 100644
--- a/src/seat.c
+++ b/src/seat.c
@@ -182,9 +182,13 @@ gboolean
seat_start (Seat *seat)
{
g_return_val_if_fail (seat != NULL, FALSE);
-
+
+ l_debug (seat, "Starting");
+
SEAT_GET_CLASS (seat)->setup (seat);
- return SEAT_GET_CLASS (seat)->start (seat);
+ seat->priv->started = SEAT_GET_CLASS (seat)->start (seat);
+
+ return seat->priv->started;
}
GList *
@@ -344,12 +348,6 @@ check_stopped (Seat *seat)
}
}
-static gboolean
-get_start_local_sessions (Seat *seat)
-{
- return SEAT_GET_CLASS (seat)->get_start_local_sessions (seat);
-}
-
static void
display_server_stopped_cb (DisplayServer *display_server, Seat *seat)
{
@@ -399,7 +397,7 @@ display_server_stopped_cb (DisplayServer *display_server, Seat *seat)
}
g_list_free_full (list, g_object_unref);
- if (!seat->priv->stopping && get_start_local_sessions (seat))
+ if (!seat->priv->stopping)
{
/* If we were the active session, switch to a greeter */
active_session = seat_get_active_session (seat);
@@ -1196,10 +1194,6 @@ display_server_ready_cb (DisplayServer *display_server, Seat *seat)
return;
}
- /* Stop if don't need to run a session */
- if (!get_start_local_sessions (seat))
- return;
-
emit_upstart_signal ("login-session-start");
/* Start the session waiting for this display server */
@@ -1479,12 +1473,6 @@ seat_get_is_stopping (Seat *seat)
return seat->priv->stopping;
}
-static gboolean
-seat_real_get_start_local_sessions (Seat *seat)
-{
- return TRUE;
-}
-
static void
seat_real_setup (Seat *seat)
{
@@ -1499,16 +1487,6 @@ seat_real_start (Seat *seat)
gboolean autologin_in_background;
Session *session = NULL, *background_session = NULL;
- l_debug (seat, "Starting");
-
- /* If this display server doesn't have a session running on it, just start it */
- if (!get_start_local_sessions (seat))
- {
- DisplayServer *display_server;
- display_server = create_display_server (seat, "x"); // FIXME: Not necessarily an X seat, but not sure what to put here
- return display_server_start (display_server);
- }
-
/* Get autologin settings */
autologin_username = seat_get_string_property (seat, "autologin-user");
if (g_strcmp0 (autologin_username, "") == 0)
@@ -1617,7 +1595,6 @@ seat_real_start (Seat *seat)
l_warning (seat, "Failed to start display server for background session");
}
- seat->priv->started = TRUE;
return TRUE;
}
@@ -1732,7 +1709,6 @@ seat_class_init (SeatClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- klass->get_start_local_sessions = seat_real_get_start_local_sessions;
klass->setup = seat_real_setup;
klass->start = seat_real_start;
klass->create_greeter_session = seat_real_create_greeter_session;
diff --git a/src/seat.h b/src/seat.h
index 093f26eb..1b861098 100644
--- a/src/seat.h
+++ b/src/seat.h
@@ -30,7 +30,7 @@ typedef struct SeatPrivate SeatPrivate;
typedef struct
{
- GObject parent_instance;
+ GObject parent_instance;
SeatPrivate *priv;
} Seat;
@@ -38,7 +38,6 @@ typedef struct
{
GObjectClass parent_class;
- gboolean (*get_start_local_sessions) (Seat *seat);
void (*setup)(Seat *seat);
gboolean (*start)(Seat *seat);
DisplayServer *(*create_display_server) (Seat *seat, const gchar *session_type);