2 * Copyright (C) 2010-2011 Robert Ancell.
3 * Author: Robert Ancell <robert.ancell@canonical.com>
5 * This program is free software: you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option) any later
8 * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
16 #include <glib/gi18n.h>
19 static GBusType bus_type = G_BUS_TYPE_SYSTEM;
20 static GDBusProxy *dm_proxy, *seat_proxy = NULL;
22 static gint xephyr_display_number;
23 static GPid xephyr_pid;
28 g_printerr (/* Text printed out when an unknown command-line argument provided */
29 _("Run 'dm-tool --help' to see a full list of available command line options."));
34 xephyr_setup_cb (gpointer user_data)
36 signal (SIGUSR1, SIG_IGN);
40 xephyr_signal_cb (int signum)
46 result = g_dbus_proxy_call_sync (dm_proxy,
48 g_variant_new ("(i)", xephyr_display_number),
49 G_DBUS_CALL_FLAGS_NONE,
55 g_printerr ("Unable to add seat: %s\n", error->message);
56 kill (xephyr_pid, SIGQUIT);
60 if (!g_variant_is_of_type (result, G_VARIANT_TYPE ("(o)")))
62 g_printerr ("Unexpected response to AddSeat: %s\n", g_variant_get_type_string (result));
66 g_variant_get (result, "(&o)", &path);
67 g_print ("%s\n", path);
80 if (!g_getenv ("XDG_SEAT_PATH"))
82 g_printerr ("Not running inside a display manager, XDG_SEAT_PATH not defined\n");
86 seat_proxy = g_dbus_proxy_new_for_bus_sync (bus_type,
87 G_DBUS_PROXY_FLAGS_NONE,
89 "org.freedesktop.DisplayManager",
90 g_getenv ("XDG_SEAT_PATH"),
91 "org.freedesktop.DisplayManager.Seat",
96 g_printerr ("Unable to contact display manager: %s\n", error->message);
99 g_clear_error (&error);
105 main (int argc, char **argv)
110 GError *error = NULL;
113 #if !defined(GLIB_VERSION_2_36)
117 for (arg_index = 1; arg_index < argc; arg_index++)
119 gchar *arg = argv[arg_index];
121 if (!g_str_has_prefix (arg, "-"))
124 if (strcmp (arg, "-h") == 0 || strcmp (arg, "--help") == 0)
126 g_printerr ("Usage:\n"
127 " dm-tool [OPTION...] COMMAND [ARGS...] - Display Manager tool\n"
130 " -h, --help Show help options\n"
131 " -v, --version Show release version\n"
132 " --session-bus Use session D-Bus\n"
135 " switch-to-greeter Switch to the greeter\n"
136 " switch-to-user USERNAME [SESSION] Switch to a user session\n"
137 " switch-to-guest [SESSION] Switch to a guest session\n"
138 " lock Lock the current seat\n"
139 " list-seats List the active seats\n"
140 " add-nested-seat [--fullscreen|--screen DIMENSIONS] Start a nested display\n"
141 " add-local-x-seat DISPLAY_NUMBER Add a local X seat\n"
142 " add-seat TYPE [NAME=VALUE...] Add a dynamic seat\n");
145 else if (strcmp (arg, "-v") == 0 || strcmp (arg, "--version") == 0)
147 /* NOTE: Is not translated so can be easily parsed */
148 g_printerr ("lightdm %s\n", VERSION);
151 else if (strcmp (arg, "--session-bus") == 0)
152 bus_type = G_BUS_TYPE_SESSION;
155 g_printerr ("Unknown option %s\n", arg);
161 if (arg_index >= argc)
163 g_printerr ("Missing command\n");
168 dm_proxy = g_dbus_proxy_new_for_bus_sync (bus_type,
169 G_DBUS_PROXY_FLAGS_NONE,
171 "org.freedesktop.DisplayManager",
172 "/org/freedesktop/DisplayManager",
173 "org.freedesktop.DisplayManager",
178 g_printerr ("Unable to contact display manager: %s\n", error->message);
181 g_clear_error (&error);
183 command = argv[arg_index];
185 n_options = argc - arg_index;
186 options = argv + arg_index;
187 if (strcmp (command, "switch-to-greeter") == 0)
191 g_printerr ("Usage switch-to-greeter\n");
196 if (!g_dbus_proxy_call_sync (get_seat_proxy (),
198 g_variant_new ("()"),
199 G_DBUS_CALL_FLAGS_NONE,
204 g_printerr ("Unable to switch to greeter: %s\n", error->message);
209 else if (strcmp (command, "switch-to-user") == 0)
211 gchar *username, *session = "";
213 if (n_options < 1 || n_options > 2)
215 g_printerr ("Usage switch-to-user USERNAME [SESSION]\n");
220 username = options[0];
222 session = options[1];
224 if (!g_dbus_proxy_call_sync (get_seat_proxy (),
226 g_variant_new ("(ss)", username, session),
227 G_DBUS_CALL_FLAGS_NONE,
232 g_printerr ("Unable to switch to user %s: %s\n", username, error->message);
237 else if (strcmp (command, "switch-to-guest") == 0)
243 g_printerr ("Usage switch-to-guest [SESSION]\n");
249 session = options[0];
251 if (!g_dbus_proxy_call_sync (get_seat_proxy (),
253 g_variant_new ("(s)", session),
254 G_DBUS_CALL_FLAGS_NONE,
259 g_printerr ("Unable to switch to guest: %s\n", error->message);
264 else if (strcmp (command, "lock") == 0)
268 g_printerr ("Usage lock\n");
273 if (!g_dbus_proxy_call_sync (get_seat_proxy (),
275 g_variant_new ("()"),
276 G_DBUS_CALL_FLAGS_NONE,
281 g_printerr ("Unable to lock seat: %s\n", error->message);
286 else if (strcmp (command, "list-seats") == 0)
289 GVariantIter *seat_iter;
292 if (!g_dbus_proxy_get_name_owner (dm_proxy))
294 g_printerr ("Unable to contact display manager\n");
297 seats = g_dbus_proxy_get_cached_property (dm_proxy, "Seats");
299 g_variant_get (seats, "ao", &seat_iter);
300 while (g_variant_iter_loop (seat_iter, "&o", &seat_path))
304 gchar **property_names;
306 GVariantIter *session_iter;
310 if (g_str_has_prefix (seat_path, "/org/freedesktop/DisplayManager/"))
311 seat_name = seat_path + strlen ("/org/freedesktop/DisplayManager/");
313 seat_name = seat_path;
315 proxy = g_dbus_proxy_new_sync (g_dbus_proxy_get_connection (dm_proxy),
316 G_DBUS_PROXY_FLAGS_NONE,
318 "org.freedesktop.DisplayManager",
320 "org.freedesktop.DisplayManager.Seat",
323 if (!proxy || !g_dbus_proxy_get_name_owner (proxy))
326 g_print ("%s\n", seat_name);
327 property_names = g_dbus_proxy_get_cached_property_names (proxy);
328 for (i = 0; property_names[i]; i++)
332 if (strcmp (property_names[i], "Sessions") == 0)
335 value = g_dbus_proxy_get_cached_property (proxy, property_names[i]);
336 g_print (" %s=%s\n", property_names[i], g_variant_print (value, FALSE));
337 g_variant_unref (value);
340 sessions = g_dbus_proxy_get_cached_property (proxy, "Sessions");
344 g_variant_get (sessions, "ao", &session_iter);
345 while (g_variant_iter_loop (session_iter, "&o", &session_path))
347 GDBusProxy *session_proxy;
350 if (g_str_has_prefix (session_path, "/org/freedesktop/DisplayManager/"))
351 session_name = session_path + strlen ("/org/freedesktop/DisplayManager/");
353 session_name = session_path;
355 session_proxy = g_dbus_proxy_new_sync (g_dbus_proxy_get_connection (dm_proxy),
356 G_DBUS_PROXY_FLAGS_NONE,
358 "org.freedesktop.DisplayManager",
360 "org.freedesktop.DisplayManager.Session",
363 if (!session_proxy || !g_dbus_proxy_get_name_owner (session_proxy))
366 g_print (" %s\n", session_name);
367 property_names = g_dbus_proxy_get_cached_property_names (session_proxy);
368 for (i = 0; property_names[i]; i++)
372 if (strcmp (property_names[i], "Seat") == 0)
375 value = g_dbus_proxy_get_cached_property (session_proxy, property_names[i]);
376 g_print (" %s=%s\n", property_names[i], g_variant_print (value, FALSE));
377 g_variant_unref (value);
380 g_object_unref (session_proxy);
382 g_variant_iter_free (session_iter);
384 g_object_unref (proxy);
386 g_variant_iter_free (seat_iter);
390 else if (strcmp (command, "add-nested-seat") == 0)
392 gchar *path, *xephyr_command, **xephyr_argv;
393 gchar *dimensions = NULL;
396 path = g_find_program_in_path ("Xephyr");
399 g_printerr ("Unable to find Xephyr, please install it\n");
405 /* Parse the given options */
406 if (strcmp (options[0], "--fullscreen") == 0 && n_options == 1)
408 dimensions = "fullscreen";
410 else if (strcmp (options[0], "--screen") == 0 && n_options == 2)
412 dimensions = options[1];
416 g_printerr ("Usage add-nested-seat [--fullscreen|--screen DIMENSIONS]\n");
422 /* Get a unique display number. It's racy, but the only reliable method to get one */
423 xephyr_display_number = 0;
429 lock_name = g_strdup_printf ("/tmp/.X%d-lock", xephyr_display_number);
430 has_lock = g_file_test (lock_name, G_FILE_TEST_EXISTS);
434 xephyr_display_number++;
439 /* Wait for signal from Xephyr is ready */
440 signal (SIGUSR1, xephyr_signal_cb);
442 if (dimensions == NULL)
444 xephyr_command = g_strdup_printf ("Xephyr :%d ", xephyr_display_number);
446 else if (strcmp (dimensions, "fullscreen") == 0)
448 xephyr_command = g_strdup_printf ("Xephyr :%d -fullscreen", xephyr_display_number);
452 xephyr_command = g_strdup_printf ("Xephyr :%d -screen %s", xephyr_display_number, dimensions);
454 if (!g_shell_parse_argv (xephyr_command, NULL, &xephyr_argv, &error) ||
455 !g_spawn_async (NULL, xephyr_argv, NULL,
456 G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
457 xephyr_setup_cb, NULL,
458 &xephyr_pid, &error))
460 g_printerr ("Error running Xephyr: %s\n", error->message);
463 g_clear_error (&error);
465 /* Block until ready */
466 loop = g_main_loop_new (NULL, FALSE);
467 g_main_loop_run (loop);
469 else if (strcmp (command, "add-local-x-seat") == 0)
477 g_printerr ("Usage add-seat DISPLAY_NUMBER\n");
482 display_number = atoi (options[0]);
484 result = g_dbus_proxy_call_sync (dm_proxy,
486 g_variant_new ("(i)", display_number),
487 G_DBUS_CALL_FLAGS_NONE,
493 g_printerr ("Unable to add local X seat: %s\n", error->message);
497 if (!g_variant_is_of_type (result, G_VARIANT_TYPE ("(o)")))
499 g_printerr ("Unexpected response to AddLocalXSeat: %s\n", g_variant_get_type_string (result));
503 g_variant_get (result, "(&o)", &path);
504 g_print ("%s\n", path);
508 else if (strcmp (command, "add-seat") == 0)
512 GVariantBuilder *properties;
517 g_printerr ("Usage add-seat TYPE [NAME=VALUE...]\n");
523 properties = g_variant_builder_new (G_VARIANT_TYPE ("a(ss)"));
525 for (i = 1; i < n_options; i++)
527 gchar *property, *name, *value;
529 property = g_strdup (options[i]);
531 value = strchr (property, '=');
540 g_variant_builder_add_value (properties, g_variant_new ("(ss)", name, value));
544 result = g_dbus_proxy_call_sync (dm_proxy,
546 g_variant_new ("(sa(ss))", type, properties),
547 G_DBUS_CALL_FLAGS_NONE,
551 g_variant_builder_unref (properties);
554 g_printerr ("Unable to add seat: %s\n", error->message);
558 if (!g_variant_is_of_type (result, G_VARIANT_TYPE ("(o)")))
560 g_printerr ("Unexpected response to AddSeat: %s\n", g_variant_get_type_string (result));
564 g_variant_get (result, "(&o)", &path);
565 g_print ("%s\n", path);
570 g_printerr ("Unknown command %s\n", command);