Blob Blame History Raw
From f5b0e165c71d5114ba5221eea6ac9ec68b8ced94 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Wed, 3 Oct 2018 10:50:47 +0200
Subject: [PATCH 2/2] monitor-manager/xrandr: Create dummy screen sized monitor
 if no RANDR

When there is no RANDR support enabled in the X server, we wont get
notified of any monitors, resulting in mutter believing we're being
headless. To get at least something working, although with no way
configuration ability, lets pretend the whole screen is just a single
monitor with a single output, crtc and mode.
---
 src/backends/x11/meta-gpu-xrandr.c            | 60 +++++++++++++++++++
 .../x11/meta-monitor-manager-xrandr.c         | 20 +++++++
 .../x11/meta-monitor-manager-xrandr.h         |  2 +
 3 files changed, 82 insertions(+)

diff --git a/src/backends/x11/meta-gpu-xrandr.c b/src/backends/x11/meta-gpu-xrandr.c
index a4e187a49..9397c1f64 100644
--- a/src/backends/x11/meta-gpu-xrandr.c
+++ b/src/backends/x11/meta-gpu-xrandr.c
@@ -147,6 +147,63 @@ update_screen_size (MetaMonitorManagerXrandr *monitor_manager_xrandr)
   monitor_manager->screen_height = HeightOfScreen (screen);
 }
 
+static gboolean
+read_current_fallback (MetaGpuXrandr            *gpu_xrandr,
+                       MetaMonitorManagerXrandr *monitor_manager_xrandr)
+{
+  MetaGpu *gpu = META_GPU (gpu_xrandr);
+  MetaMonitorManager *monitor_manager =
+    META_MONITOR_MANAGER (monitor_manager_xrandr);
+  MetaCrtcMode *mode;
+  MetaCrtc *crtc;
+  MetaOutput *output;
+
+  update_dpms_state (monitor_manager_xrandr);
+  update_screen_size (monitor_manager_xrandr);
+
+  mode = g_object_new (META_TYPE_CRTC_MODE, NULL);
+  mode->mode_id = 0;
+  mode->width = monitor_manager->screen_width;
+  mode->height = monitor_manager->screen_height;
+  mode->refresh_rate = 60.0;
+  mode->name = g_strdup_printf ("%dx%d", mode->width, mode->height);
+
+  meta_gpu_take_modes (gpu, g_list_prepend (NULL, mode));
+
+  crtc = g_object_new (META_TYPE_CRTC, NULL);
+  crtc->gpu = gpu;
+  crtc->crtc_id = 0;
+  crtc->rect = (MetaRectangle) { .width = mode->width, .height = mode->height };
+  crtc->current_mode = mode;
+
+  meta_gpu_take_crtcs (gpu, g_list_prepend (NULL, crtc));
+
+  output = g_object_new (META_TYPE_OUTPUT, NULL);
+  output->gpu = gpu;
+  output->winsys_id = 0;
+  output->name = g_strdup ("X11 Screen");
+  output->vendor = g_strdup ("unknown");
+  output->product = g_strdup ("unknown");
+  output->serial = g_strdup ("unknown");
+  output->hotplug_mode_update = TRUE;
+  output->suggested_x = -1;
+  output->suggested_y = -1;
+  output->connector_type = META_CONNECTOR_TYPE_Unknown;
+  output->modes = g_new0 (MetaCrtcMode *, 1);
+  output->modes[0] = mode;
+  output->n_modes = 1;
+  output->preferred_mode = mode;
+  output->possible_crtcs = g_new0 (MetaCrtc *, 1);
+  output->possible_crtcs[0] = crtc;
+  output->n_possible_crtcs = 1;
+  meta_output_assign_crtc (output, crtc);
+  output->is_primary = TRUE;
+
+  meta_gpu_take_outputs (gpu, g_list_prepend (NULL, output));
+
+  return TRUE;
+}
+
 static gboolean
 meta_gpu_xrandr_read_current (MetaGpu  *gpu,
                               GError  **error)
@@ -166,6 +223,9 @@ meta_gpu_xrandr_read_current (MetaGpu  *gpu,
   GList *modes = NULL;
   GList *crtcs = NULL;
 
+  if (!meta_monitor_manager_xrandr_has_randr (monitor_manager_xrandr))
+    return read_current_fallback (gpu_xrandr, monitor_manager_xrandr);
+
   if (gpu_xrandr->resources)
     XRRFreeScreenResources (gpu_xrandr->resources);
   gpu_xrandr->resources = NULL;
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
index d0da2c539..26b057a55 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
@@ -64,6 +64,7 @@ struct _MetaMonitorManagerXrandr
   guint logind_watch_id;
   guint logind_signal_sub_id;
 
+  gboolean has_randr;
   gboolean has_randr15;
 
   /*
@@ -107,6 +108,12 @@ meta_monitor_manager_xrandr_get_xdisplay (MetaMonitorManagerXrandr *manager_xran
   return manager_xrandr->xdisplay;
 }
 
+gboolean
+meta_monitor_manager_xrandr_has_randr (MetaMonitorManagerXrandr *manager_xrandr)
+{
+  return manager_xrandr->has_randr;
+}
+
 gboolean
 meta_monitor_manager_xrandr_has_randr15 (MetaMonitorManagerXrandr *manager_xrandr)
 {
@@ -577,9 +584,18 @@ meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager      *mana
                                                    MetaMonitorsConfigMethod method,
                                                    GError                 **error)
 {
+  MetaMonitorManagerXrandr *manager_xrandr =
+    META_MONITOR_MANAGER_XRANDR (manager);
   GPtrArray *crtc_infos;
   GPtrArray *output_infos;
 
+  if (!manager_xrandr->has_randr)
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Tried to change configuration without XRANDR support");
+      return FALSE;
+    }
+
   if (!config)
     {
       meta_monitor_manager_xrandr_rebuild_derived (manager, NULL);
@@ -1046,11 +1062,15 @@ meta_monitor_manager_xrandr_constructed (GObject *object)
 			  &manager_xrandr->rr_event_base,
 			  &manager_xrandr->rr_error_base))
     {
+      g_warning ("No RANDR support, monitor configuration disabled");
       return;
     }
   else
     {
       int major_version, minor_version;
+
+      manager_xrandr->has_randr = TRUE;
+
       /* We only use ScreenChangeNotify, but GDK uses the others,
 	 and we don't want to step on its toes */
       XRRSelectInput (manager_xrandr->xdisplay,
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.h b/src/backends/x11/meta-monitor-manager-xrandr.h
index f09cbfd83..343c8131e 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.h
+++ b/src/backends/x11/meta-monitor-manager-xrandr.h
@@ -33,6 +33,8 @@ G_DECLARE_FINAL_TYPE (MetaMonitorManagerXrandr, meta_monitor_manager_xrandr,
 
 Display * meta_monitor_manager_xrandr_get_xdisplay (MetaMonitorManagerXrandr *manager_xrandr);
 
+gboolean meta_monitor_manager_xrandr_has_randr (MetaMonitorManagerXrandr *manager_xrandr);
+
 gboolean meta_monitor_manager_xrandr_has_randr15 (MetaMonitorManagerXrandr *manager_xrandr);
 
 gboolean meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager,
-- 
2.21.0