summaryrefslogtreecommitdiff
path: root/daemon/gdm-local-display-factory.c
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2021-07-16 12:34:57 -0400
committerRay Strode <rstrode@redhat.com>2021-07-22 13:33:18 -0400
commit04853a3b8c17712cc7f74c3c405ef47af53151c1 (patch)
treebdd174fa2bc01eca932938e8007a9007668cb764 /daemon/gdm-local-display-factory.c
parentf66ff435ab9951c783ff17e16ade0a800cec5497 (diff)
downloadgdm-04853a3b8c17712cc7f74c3c405ef47af53151c1.tar.gz
daemon: Provide more flexibility for configuring display server
There's currently a way to disable wayland, but no way to disable Xorg. We currently prefer wayland if it's not disabled, but have no way to prefer Xorg without disabling wayland entirely. There's currently no way use legacy Xorg support at all if user display server support is enabled at a build time. This commit adds more flexibility to display server selection. It adds two new keys: XorgEnable and and PreferredDisplayServer. XorgEnable=false disables Xorg support entirely on seat 0. PreferredDisplayServer can be set to "wayland", "xorg", "legacy-xorg" or "none" to select which display server is used by default. If it's set to "wayland", it will fall back to "xorg". If it's set to "xorg" it will fall back to "wayland".
Diffstat (limited to 'daemon/gdm-local-display-factory.c')
-rw-r--r--daemon/gdm-local-display-factory.c220
1 files changed, 182 insertions, 38 deletions
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
index 8a4ef06c..0bb3851f 100644
--- a/daemon/gdm-local-display-factory.c
+++ b/daemon/gdm-local-display-factory.c
@@ -183,6 +183,89 @@ take_next_display_number (GdmLocalDisplayFactory *factory)
return ret;
}
+static char *
+get_preferred_display_server (GdmLocalDisplayFactory *factory)
+{
+ g_autofree gchar *preferred_display_server = NULL;
+ gboolean wayland_enabled = FALSE, xorg_enabled = FALSE;
+
+ gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled);
+ gdm_settings_direct_get_boolean (GDM_KEY_XORG_ENABLE, &xorg_enabled);
+
+ if (wayland_enabled && !xorg_enabled) {
+ return g_strdup ("wayland");
+ }
+
+ if (!wayland_enabled && !xorg_enabled) {
+ return g_strdup ("none");
+ }
+
+ gdm_settings_direct_get_string (GDM_KEY_PREFERRED_DISPLAY_SERVER, &preferred_display_server);
+
+ if (g_strcmp0 (preferred_display_server, "wayland") == 0) {
+ if (wayland_enabled)
+ return g_strdup (preferred_display_server);
+ else
+ return g_strdup ("xorg");
+ }
+
+ if (g_strcmp0 (preferred_display_server, "xorg") == 0) {
+ if (xorg_enabled)
+ return g_strdup (preferred_display_server);
+ else
+ return g_strdup ("wayland");
+ }
+
+ if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0) {
+ if (xorg_enabled)
+ return g_strdup (preferred_display_server);
+ }
+
+ return g_strdup ("none");
+}
+
+static const char *
+gdm_local_display_factory_get_session_type (GdmLocalDisplayFactory *factory,
+ gboolean should_fall_back)
+{
+ const char *session_types[3] = { NULL };
+ gsize i, session_type_index = 0, number_of_session_types = 0;
+ g_autofree gchar *preferred_display_server = NULL;
+
+ preferred_display_server = get_preferred_display_server (factory);
+
+ if (g_strcmp0 (preferred_display_server, "wayland") != 0 &&
+ g_strcmp0 (preferred_display_server, "xorg") != 0)
+ return NULL;
+
+ for (i = 0; i < G_N_ELEMENTS (session_types) - 1; i++) {
+#ifdef ENABLE_WAYLAND_SUPPORT
+ if (number_of_session_types > 0 ||
+ g_strcmp0 (preferred_display_server, "wayland") == 0) {
+ gboolean wayland_enabled = FALSE;
+ if (gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled)) {
+ if (wayland_enabled && g_file_test ("/usr/bin/Xwayland", G_FILE_TEST_IS_EXECUTABLE) )
+ session_types[number_of_session_types++] = "wayland";
+ }
+ }
+#endif
+
+ if (number_of_session_types > 0 ||
+ g_strcmp0 (preferred_display_server, "xorg") == 0) {
+ gboolean xorg_enabled = FALSE;
+ if (gdm_settings_direct_get_boolean (GDM_KEY_XORG_ENABLE, &xorg_enabled)) {
+ if (xorg_enabled && g_file_test ("/usr/bin/Xorg", G_FILE_TEST_IS_EXECUTABLE) )
+ session_types[number_of_session_types++] = "x11";
+ }
+ }
+ }
+
+ if (should_fall_back)
+ session_type_index++;
+
+ return session_types[session_type_index];
+}
+
static void
on_display_disposed (GdmLocalDisplayFactory *factory,
GdmDisplay *display)
@@ -200,19 +283,6 @@ store_display (GdmLocalDisplayFactory *factory,
gdm_display_store_add (store, display);
}
-static gboolean
-gdm_local_display_factory_use_wayland (void)
-{
-#ifdef ENABLE_WAYLAND_SUPPORT
- gboolean wayland_enabled = FALSE;
- if (gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled)) {
- if (wayland_enabled && g_file_test ("/usr/bin/Xwayland", G_FILE_TEST_IS_EXECUTABLE) )
- return TRUE;
- }
-#endif
- return FALSE;
-}
-
/*
Example:
dbus-send --system --dest=org.gnome.DisplayManager \
@@ -228,6 +298,8 @@ gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *fact
gboolean ret;
GdmDisplay *display = NULL;
gboolean is_initial = FALSE;
+ const char *session_type;
+ g_autofree gchar *preferred_display_server = NULL;
g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE);
@@ -235,20 +307,43 @@ gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *fact
g_debug ("GdmLocalDisplayFactory: Creating transient display");
-#ifdef ENABLE_USER_DISPLAY_SERVER
- display = gdm_local_display_new ();
- if (gdm_local_display_factory_use_wayland ())
- g_object_set (G_OBJECT (display), "session-type", "wayland", NULL);
- is_initial = TRUE;
-#else
- if (display == NULL) {
- guint32 num;
+ preferred_display_server = get_preferred_display_server (factory);
- num = take_next_display_number (factory);
+#ifdef ENABLE_USER_DISPLAY_SERVER
+ if (g_strcmp0 (preferred_display_server, "wayland") == 0 ||
+ g_strcmp0 (preferred_display_server, "xorg") == 0) {
+ session_type = gdm_local_display_factory_get_session_type (factory, FALSE);
+
+ if (session_type == NULL) {
+ g_set_error_literal (error,
+ GDM_DISPLAY_ERROR,
+ GDM_DISPLAY_ERROR_GENERAL,
+ "Both Wayland and Xorg are unavailable");
+ return FALSE;
+ }
- display = gdm_legacy_display_new (num);
+ display = gdm_local_display_new ();
+ g_object_set (G_OBJECT (display), "session-type", session_type, NULL);
+ is_initial = TRUE;
}
#endif
+ if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0) {
+ if (display == NULL) {
+ guint32 num;
+
+ num = take_next_display_number (factory);
+
+ display = gdm_legacy_display_new (num);
+ }
+ }
+
+ if (display == NULL) {
+ g_set_error_literal (error,
+ GDM_DISPLAY_ERROR,
+ GDM_DISPLAY_ERROR_GENERAL,
+ "Invalid preferred display server configured");
+ return FALSE;
+ }
g_object_set (display,
"seat-id", "seat0",
@@ -481,6 +576,19 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory,
GdmDisplayStore *store;
GdmDisplay *display = NULL;
g_autofree char *login_session_id = NULL;
+ gboolean wayland_enabled = FALSE, xorg_enabled = FALSE;
+ g_autofree gchar *preferred_display_server = NULL;
+ gboolean falling_back;
+
+ gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled);
+ gdm_settings_direct_get_boolean (GDM_KEY_XORG_ENABLE, &xorg_enabled);
+
+ preferred_display_server = get_preferred_display_server (factory);
+
+ if (g_strcmp0 (preferred_display_server, "none") == 0) {
+ g_debug ("GdmLocalDisplayFactory: Preferred display server is none, so not creating display");
+ return;
+ }
ret = sd_seat_can_graphical (seat_id);
@@ -500,21 +608,18 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory,
if (g_strcmp0 (seat_id, "seat0") == 0) {
is_seat0 = TRUE;
- /* If we've failed, or are explicitly told to, fall back to legacy X11 support
- */
- if (factory->num_failures > 0 || !gdm_local_display_factory_use_wayland ()) {
- session_type = NULL;
- g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use X11 fallback");
- } else {
- g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use wayland");
- }
+ falling_back = factory->num_failures > 0;
+ session_type = gdm_local_display_factory_get_session_type (factory, falling_back);
+
+ g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use %s%s",
+ session_type, falling_back? " fallback" : "");
} else {
is_seat0 = FALSE;
g_debug ("GdmLocalDisplayFactory: New displays on seat %s will use X11 fallback", seat_id);
/* Force legacy X11 for all auxiliary seats */
seat_supports_graphics = TRUE;
- session_type = NULL;
+ session_type = "x11";
}
/* For seat0, we have a fallback logic to still try starting it after
@@ -552,7 +657,8 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory,
g_debug ("GdmLocalDisplayFactory: Assuming we can use seat0 for X11 even though system says it doesn't support graphics!");
g_debug ("GdmLocalDisplayFactory: This might indicate an issue where the framebuffer device is not tagged as master-of-seat in udev.");
seat_supports_graphics = TRUE;
- session_type = NULL;
+ session_type = "x11";
+ wayland_enabled = FALSE;
} else {
g_clear_handle_id (&factory->seat0_graphics_check_timeout_id, g_source_remove);
}
@@ -561,8 +667,13 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory,
if (!seat_supports_graphics)
return;
- g_debug ("GdmLocalDisplayFactory: %s login display for seat %s requested",
- session_type? : "X11", seat_id);
+ if (session_type != NULL)
+ g_debug ("GdmLocalDisplayFactory: %s login display for seat %s requested",
+ session_type, seat_id);
+ else if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0)
+ g_debug ("GdmLocalDisplayFactory: Legacy Xorg login display for seat %s requested",
+ seat_id);
+
store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
if (is_seat0)
@@ -597,20 +708,53 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory,
g_debug ("GdmLocalDisplayFactory: Adding display on seat %s", seat_id);
#ifdef ENABLE_USER_DISPLAY_SERVER
- if (is_seat0) {
- display = gdm_local_display_new ();
- if (session_type != NULL) {
+ if (g_strcmp0 (preferred_display_server, "wayland") == 0 ||
+ g_strcmp0 (preferred_display_server, "xorg") == 0) {
+ if (is_seat0) {
+ g_autoptr (GPtrArray) supported_session_types = NULL;
+
+ if (session_type == NULL) {
+ g_warning ("GdmLocalDisplayFactory: Both Wayland and Xorg sessions are unavailable");
+ return;
+ }
+
+ supported_session_types = g_ptr_array_new ();
+
+ if (g_strcmp0 (preferred_display_server, "wayland") == 0) {
+ if (wayland_enabled)
+ g_ptr_array_add (supported_session_types, "wayland");
+ } else {
+ if (xorg_enabled)
+ g_ptr_array_add (supported_session_types, "x11");
+ }
+
+ if (!falling_back) {
+ if (g_strcmp0 (preferred_display_server, "wayland") == 0) {
+ if (xorg_enabled)
+ g_ptr_array_add (supported_session_types, "x11");
+ } else {
+ if (wayland_enabled)
+ g_ptr_array_add (supported_session_types, "wayland");
+ }
+ }
+
+ g_ptr_array_add (supported_session_types, NULL);
+
+ display = gdm_local_display_new ();
g_object_set (G_OBJECT (display), "session-type", session_type, NULL);
+ g_object_set (G_OBJECT (display), "supported-session-types", supported_session_types->pdata, NULL);
}
}
#endif
if (display == NULL) {
guint32 num;
+ const char *supported_session_types[] = { "x11", NULL };
num = take_next_display_number (factory);
display = gdm_legacy_display_new (num);
+ g_object_set (G_OBJECT (display), "supported-session-types", supported_session_types, NULL);
}
g_object_set (display, "seat-id", seat_id, NULL);