common/configuration.c | 1 + data/lightdm.conf | 2 ++ src/seat-local.c | 5 +++-- src/vt.c | 39 +++++++++++++++++++++++++++++++++++---- src/vt.h | 2 +- 5 files changed, 42 insertions(+), 7 deletions(-) diff --git a/common/configuration.c b/common/configuration.c index 058e69e2..b4dd4c5e 100644 --- a/common/configuration.c +++ b/common/configuration.c @@ -347,6 +347,7 @@ config_init (Configuration *config) g_hash_table_insert (config->priv->lightdm_keys, "backup-logs", GINT_TO_POINTER (KEY_SUPPORTED)); g_hash_table_insert (config->priv->lightdm_keys, "dbus-service", GINT_TO_POINTER (KEY_SUPPORTED)); g_hash_table_insert (config->priv->lightdm_keys, "logind-load-seats", GINT_TO_POINTER (KEY_DEPRECATED)); + g_hash_table_insert (config->priv->lightdm_keys, "use-free-vt", GINT_TO_POINTER (KEY_SUPPORTED)); g_hash_table_insert (config->priv->seat_keys, "type", GINT_TO_POINTER (KEY_SUPPORTED)); g_hash_table_insert (config->priv->seat_keys, "pam-service", GINT_TO_POINTER (KEY_SUPPORTED)); diff --git a/data/lightdm.conf b/data/lightdm.conf index 16b80f7e..e352ae05 100644 --- a/data/lightdm.conf +++ b/data/lightdm.conf @@ -17,6 +17,7 @@ # greeters-directory = Directory to find greeters # backup-logs = True to move add a .old suffix to old log files when opening new ones # dbus-service = True if LightDM provides a D-Bus service to control it +# use-free-vt = True to use system VT information to choose free VT instead of using minimum-vt and next VTs even if they're busy. When true, minimum-vt is ignored. # [LightDM] #start-default-seat=true @@ -35,6 +36,7 @@ #greeters-directory=$XDG_DATA_DIRS/lightdm/greeters:$XDG_DATA_DIRS/xgreeters #backup-logs=true #dbus-service=true +#use-free-vt=false # # Seat configuration diff --git a/src/seat-local.c b/src/seat-local.c index aa6a0b0f..c0a619cc 100644 --- a/src/seat-local.c +++ b/src/seat-local.c @@ -131,10 +131,11 @@ get_vt (SeatLocal *seat, DisplayServer *display_server) /* If Plymouth is running, stop it */ gint vt = -1; + gboolean use_free_vt = config_get_boolean (config_get_instance (), "LightDM", "use-free-vt"); if (plymouth_get_is_active () && plymouth_has_active_vt ()) { gint active_vt = vt_get_active (); - if (active_vt >= vt_get_min ()) + if (use_free_vt || (active_vt >= vt_get_min ())) { vt = active_vt; g_signal_connect (display_server, DISPLAY_SERVER_SIGNAL_READY, G_CALLBACK (display_server_ready_cb), seat); @@ -147,7 +148,7 @@ get_vt (SeatLocal *seat, DisplayServer *display_server) if (plymouth_get_is_active ()) plymouth_quit (FALSE); if (vt < 0) - vt = vt_get_unused (); + vt = vt_get_unused (use_free_vt); return vt; } diff --git a/src/vt.c b/src/vt.c index 920ae682..6dab1ea0 100644 --- a/src/vt.c +++ b/src/vt.c @@ -135,14 +135,45 @@ vt_get_min (void) } gint -vt_get_unused (void) +vt_get_unused (gboolean use_free_vt) { if (getuid () != 0) return -1; - gint number = vt_get_min (); - while (vt_is_used (number)) - number++; + gint number = -1; + +#ifdef __linux__ + if (use_free_vt) + { + gint tty_fd = open_tty (); + if (tty_fd >= 0) + { + int vt = -1; + if (ioctl (tty_fd, VT_OPENQRY, &vt) < 0) + { + g_warning ("Error using VT_OPENQRY on /dev/tty0: %s", strerror (errno)); + } + + number = vt; + } + + close (tty_fd); + + if (number < 0) + { + g_warning ("No unused VT is available, trying to reuse active VT"); + number = vt_get_active (); + } + } + else + { +#endif + number = vt_get_min (); + while (vt_is_used (number)) + number++; +#ifdef __linux__ + } +#endif return number; } diff --git a/src/vt.h b/src/vt.h index a731beca..e8e55514 100644 --- a/src/vt.h +++ b/src/vt.h @@ -18,7 +18,7 @@ gboolean vt_can_multi_seat (void); gint vt_get_active (void); -gint vt_get_unused (void); +gint vt_get_unused (gboolean use_free_vt); gint vt_get_min (void);