diff options
author | Robert Ancell <robert.ancell@canonical.com> | 2014-09-12 11:46:42 +1200 |
---|---|---|
committer | Robert Ancell <robert.ancell@canonical.com> | 2014-09-12 11:46:42 +1200 |
commit | ac3b5e59c3f35e325be39a32fe34bfebabd974aa (patch) | |
tree | 41c253ff0f533c686c83853c7bed97b6b010f5d4 | |
parent | e726d281920fe472616d04d80fe844a3b837ea64 (diff) | |
download | lightdm-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.c | 173 | ||||
-rw-r--r-- | src/seat-xlocal.c | 173 | ||||
-rw-r--r-- | src/seat.c | 38 | ||||
-rw-r--r-- | src/seat.h | 3 |
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)); } @@ -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; @@ -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); |