From 33a5e05c0899d64b58dcb30a77ea0a2a15773a74 Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Mon, 18 Nov 2013 13:26:57 -0500 Subject: [PATCH] When a seat stops, try the next seat type if one is defined --- src/lightdm.c | 100 ++++++++++++++++++++++++++++++++++---------------- src/seat.c | 31 ++++++++++++++++ src/seat.h | 4 ++ 3 files changed, 104 insertions(+), 31 deletions(-) diff --git a/src/lightdm.c b/src/lightdm.c index 686a1f83..2be0a161 100644 --- a/src/lightdm.c +++ b/src/lightdm.c @@ -138,6 +138,34 @@ log_init (void) g_free (path); } +static void +set_seat_properties (Seat *seat, const gchar *config_section) +{ + gchar **keys; + gint i; + + keys = config_get_keys (config_get_instance (), "SeatDefaults"); + for (i = 0; keys[i]; i++) + { + gchar *value = config_get_string (config_get_instance (), "SeatDefaults", keys[i]); + seat_set_property (seat, keys[i], value); + g_free (value); + } + g_strfreev (keys); + + if (config_section) + { + keys = config_get_keys (config_get_instance (), config_section); + for (i = 0; keys[i]; i++) + { + gchar *value = config_get_string (config_get_instance (), config_section, keys[i]); + seat_set_property (seat, keys[i], value); + g_free (value); + } + g_strfreev (keys); + } +} + static void signal_cb (Process *process, int signum) { @@ -156,7 +184,45 @@ display_manager_stopped_cb (DisplayManager *display_manager) static void display_manager_seat_removed_cb (DisplayManager *display_manager, Seat *seat) { - if (seat_get_boolean_property (seat, "exit-on-failure")) + const gchar *type; + gchar **types; + gchar **iter; + gboolean make_seats = FALSE; + Seat *next_seat = NULL; + + /* If we have fallback types registered for the seat, let's try them + before giving up. This code does not expect a type name to appear twice + in the type list. It is a configuration error to do so. */ + type = seat_get_type_name(seat); + types = seat_get_string_list_property (seat, "type"); + for (iter = types; !next_seat && iter && *iter; iter++) + { + if (make_seats) + next_seat = seat_new (*iter); + else if (g_strcmp0 (type, *iter) == 0) + make_seats = TRUE; + } + g_strfreev (types); + + if (next_seat) + { + const gchar *seat_name; + gchar *config_section = NULL; + + seat_name = seat_get_string_property (seat, "seat-name"); + if (seat_name) + config_section = g_strdup_printf ("Seat:%s", seat_name); + set_seat_properties (next_seat, config_section); + g_free (config_section); + + // We set this manually on default seat. Let's port it over if needed. + if (seat_get_boolean_property (seat, "exit-on-failure")) + seat_set_property (next_seat, "exit-on-failure", "true"); + + display_manager_add_seat (display_manager, next_seat); + g_object_unref (next_seat); + } + else if (seat_get_boolean_property (seat, "exit-on-failure")) { g_debug ("Required seat has stopped"); exit_code = EXIT_FAILURE; @@ -211,34 +277,6 @@ handle_display_manager_get_property (GDBusConnection *connection, return result; } -static void -set_seat_properties (Seat *seat, const gchar *config_section) -{ - gchar **keys; - gint i; - - keys = config_get_keys (config_get_instance (), "SeatDefaults"); - for (i = 0; keys[i]; i++) - { - gchar *value = config_get_string (config_get_instance (), "SeatDefaults", keys[i]); - seat_set_property (seat, keys[i], value); - g_free (value); - } - g_strfreev (keys); - - if (config_section) - { - keys = config_get_keys (config_get_instance (), config_section); - for (i = 0; keys[i]; i++) - { - gchar *value = config_get_string (config_get_instance (), config_section, keys[i]); - seat_set_property (seat, keys[i], value); - g_free (value); - } - g_strfreev (keys); - } -} - static void handle_display_manager_call (GDBusConnection *connection, const gchar *sender, @@ -1211,7 +1249,7 @@ main (int argc, char **argv) types = config_get_string_list (config_get_instance (), config_section, "type"); if (!types) types = config_get_string_list (config_get_instance (), "SeatDefaults", "type"); - for (type = types; !seat && *type; type++) + for (type = types; !seat && type && *type; type++) seat = seat_new (*type); g_strfreev (types); if (seat) @@ -1241,7 +1279,7 @@ main (int argc, char **argv) g_debug ("Adding default seat"); types = config_get_string_list (config_get_instance (), "SeatDefaults", "type"); - for (type = types; !seat && *type; type++) + for (type = types; !seat && type && *type; type++) seat = seat_new (*type); g_strfreev (types); if (seat) diff --git a/src/seat.c b/src/seat.c index 1596a3da..772c5620 100644 --- a/src/seat.c +++ b/src/seat.c @@ -121,6 +121,30 @@ seat_new (const gchar *module_name) return seat; } +const gchar * +seat_get_type_name (Seat *seat) +{ + GList *values = NULL; + GList *iter; + const gchar *name = NULL; + + if (seat_modules) + values = g_hash_table_get_values (seat_modules); + + for (iter = values; iter; iter = iter->next) + { + SeatModule *module = (SeatModule *)iter->data; + if (module->type == G_OBJECT_TYPE (seat)) + { + name = module->name; + break; + } + } + + g_list_free (values); + return name; +} + void seat_set_property (Seat *seat, const gchar *name, const gchar *value) { @@ -135,6 +159,13 @@ seat_get_string_property (Seat *seat, const gchar *name) return g_hash_table_lookup (seat->priv->properties, name); } +gchar ** +seat_get_string_list_property (Seat *seat, const gchar *name) +{ + g_return_val_if_fail (seat != NULL, NULL); + return g_strsplit (g_hash_table_lookup (seat->priv->properties, name), ";", 0); +} + gboolean seat_get_boolean_property (Seat *seat, const gchar *name) { diff --git a/src/seat.h b/src/seat.h index 7457230d..5bde5c20 100644 --- a/src/seat.h +++ b/src/seat.h @@ -63,10 +63,14 @@ void seat_register_module (const gchar *name, GType type); Seat *seat_new (const gchar *module_name); +const gchar *seat_get_type_name (Seat *seat); + void seat_set_property (Seat *seat, const gchar *name, const gchar *value); const gchar *seat_get_string_property (Seat *seat, const gchar *name); +gchar **seat_get_string_list_property (Seat *seat, const gchar *name); + gboolean seat_get_boolean_property (Seat *seat, const gchar *name); gint seat_get_integer_property (Seat *seat, const gchar *name); -- 2.39.2