]> rtime.felk.cvut.cz Git - sojka/lightdm.git/commitdiff
When a seat stops, try the next seat type if one is defined
authorMichael Terry <michael.terry@canonical.com>
Mon, 18 Nov 2013 18:26:57 +0000 (13:26 -0500)
committerMichael Terry <michael.terry@canonical.com>
Mon, 18 Nov 2013 18:26:57 +0000 (13:26 -0500)
src/lightdm.c
src/seat.c
src/seat.h

index 686a1f83256c5f5b0e5557adb0f486304fca0974..2be0a1618476145250676c6a8bb6a7a39f41180e 100644 (file)
@@ -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)
index 1596a3dac4f63df3262f2a0fc4fc5865f36c8552..772c5620a06be90590152cb3678de5ad737cd483 100644 (file)
@@ -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)
 {
index 7457230d53532677dbb5d11f11f0f68670409f6b..5bde5c2066b764bb0432fdfef04c5c40f715ecdc 100644 (file)
@@ -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);