diff options
author | Robert Ancell <robert.ancell@canonical.com> | 2011-08-17 15:49:16 +1000 |
---|---|---|
committer | Robert Ancell <robert.ancell@canonical.com> | 2011-08-17 15:49:16 +1000 |
commit | 4897357cfb1491d2e477ab40cf8dfe5e8eb77141 (patch) | |
tree | 1da4ae807747425cf5c9f8da8a5e7bc05e9d3b28 /utils | |
parent | 2ba06483232942ac2cbbed5c76f21bb9bad3f1c3 (diff) | |
download | lightdm-git-4897357cfb1491d2e477ab40cf8dfe5e8eb77141.tar.gz |
Add dm-tool command add-nested-seat
Diffstat (limited to 'utils')
-rw-r--r-- | utils/dm-tool.c | 101 |
1 files changed, 100 insertions, 1 deletions
diff --git a/utils/dm-tool.c b/utils/dm-tool.c index a5b174b5..bf7b82f3 100644 --- a/utils/dm-tool.c +++ b/utils/dm-tool.c @@ -16,6 +16,11 @@ #include <glib/gi18n.h> #include <gio/gio.h> +static GDBusProxy *dm_proxy, *seat_proxy; + +static gint xephyr_display_number; +static GPid xephyr_pid; + static void usage () { @@ -24,13 +29,58 @@ usage () g_printerr ("\n"); } +static void +xephyr_setup_cb (gpointer user_data) +{ + signal (SIGUSR1, SIG_IGN); +} + +static void +xephyr_signal_cb (int signum) +{ + gchar *display_number_string, *path; + GVariantBuilder *properties; + GVariant *result; + GError *error = NULL; + + properties = g_variant_builder_new (G_VARIANT_TYPE ("a(ss)")); + display_number_string = g_strdup_printf ("%d", xephyr_display_number); + g_variant_builder_add_value (properties, g_variant_new ("(ss)", "xserver-display-number", display_number_string)); + g_free (display_number_string); + + result = g_dbus_proxy_call_sync (dm_proxy, + "AddSeat", + g_variant_new ("(sa(ss))", "xremote", properties), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_variant_builder_unref (properties); + if (!result) + { + g_printerr ("Unable to add seat: %s\n", error->message); + kill (xephyr_pid, SIGQUIT); + exit (EXIT_FAILURE); + } + + if (!g_variant_is_of_type (result, G_VARIANT_TYPE ("(o)"))) + { + g_printerr ("Unexpected response to AddSeat: %s\n", g_variant_get_type_string (result)); + exit (EXIT_FAILURE); + } + + g_variant_get (result, "(&o)", &path); + g_print ("%s\n", path); + + exit (EXIT_SUCCESS); +} + int main (int argc, char **argv) { gchar *command; gint n_options; gchar **options; - GDBusProxy *dm_proxy, *seat_proxy; GError *error = NULL; gint arg_index; GBusType bus_type = G_BUS_TYPE_SYSTEM; @@ -58,6 +108,7 @@ main (int argc, char **argv) " switch-to-greeter Switch to the greeter\n" " switch-to-user USERNAME [SESSION] Switch to a user session\n" " switch-to-guest [SESSION] Switch to a guest session\n" + " add-nested-seat Start a nested display\n" " add-seat TYPE [NAME=VALUE...] Add a dynamic seat\n"); return EXIT_SUCCESS; } @@ -195,6 +246,54 @@ main (int argc, char **argv) } return EXIT_SUCCESS; } + else if (strcmp (command, "add-nested-seat") == 0) + { + gchar *path, *xephyr_command, **xephyr_argv; + GMainLoop *loop; + + path = g_find_program_in_path ("Xephyr"); + if (!path) + { + g_printerr ("Unable to find Xephry, please install it\n"); + return EXIT_FAILURE; + } + + /* Get a unique display number. It's racy, but the only reliable method to get one */ + xephyr_display_number = 0; + while (TRUE) + { + gchar *lock_name; + gboolean has_lock; + + lock_name = g_strdup_printf ("/tmp/.X%d-lock", xephyr_display_number); + has_lock = g_file_test (lock_name, G_FILE_TEST_EXISTS); + g_free (lock_name); + + if (has_lock) + xephyr_display_number++; + else + break; + } + + /* Wait for signal from Xephyr is ready */ + signal (SIGUSR1, xephyr_signal_cb); + + xephyr_command = g_strdup_printf ("Xephyr :%d", xephyr_display_number); + if (!g_shell_parse_argv (xephyr_command, NULL, &xephyr_argv, &error) || + !g_spawn_async (NULL, xephyr_argv, NULL, + G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + xephyr_setup_cb, NULL, + &xephyr_pid, &error)) + { + g_printerr ("Error running Xephyr: %s\n", error->message); + exit (EXIT_FAILURE); + } + g_clear_error (&error); + + /* Block until ready */ + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + } else if (strcmp (command, "add-seat") == 0) { GVariant *result; |