[mutter] backend/x11: add support for setting randr 1.5 monitors



commit 9f65edd4f547f056ebaf1e5a144097390147f042
Author: Dave Airlie <airlied redhat com>
Date:   Tue Mar 31 11:11:12 2015 +1000

    backend/x11: add support for setting randr 1.5 monitors
    
    This interface allows us to propogate back the constructed
    monitors to randr using the randr 1.5 protocol. Apps
    should pick it up from there.

 src/backends/meta-monitor-manager-private.h    |    7 ++
 src/backends/meta-monitor-manager.c            |   27 +++++++-
 src/backends/x11/meta-monitor-manager-xrandr.c |   87 ++++++++++++++++++++++++
 3 files changed, 120 insertions(+), 1 deletions(-)
---
diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h
index c5444d6..d21888e 100644
--- a/src/backends/meta-monitor-manager-private.h
+++ b/src/backends/meta-monitor-manager-private.h
@@ -349,6 +349,13 @@ struct _MetaMonitorManagerClass
                           unsigned short     *,
                           unsigned short     *,
                           unsigned short     *);
+
+  void (*add_monitor) (MetaMonitorManager *,
+                       MetaMonitorInfo *);
+
+  void (*delete_monitor) (MetaMonitorManager *,
+                          int monitor_winsys_xid);
+
 };
 
 void                meta_monitor_manager_rebuild_derived   (MetaMonitorManager *manager);
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 89efaca..21ab215 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -173,6 +173,7 @@ construct_tile_monitor (MetaMonitorManager *manager,
 static void
 make_logical_config (MetaMonitorManager *manager)
 {
+  MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_GET_CLASS (manager);
   GArray *monitor_infos;
   unsigned int i, j;
 
@@ -277,6 +278,10 @@ make_logical_config (MetaMonitorManager *manager)
 
   manager->n_monitor_infos = monitor_infos->len;
   manager->monitor_infos = (void*)g_array_free (monitor_infos, FALSE);
+
+  if (manager_class->add_monitor)
+    for (i = 0; i < manager->n_monitor_infos; i++)
+      manager_class->add_monitor (manager, &manager->monitor_infos[i]);
 }
 
 static void
@@ -1356,15 +1361,35 @@ meta_monitor_manager_read_current_config (MetaMonitorManager *manager)
 void
 meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager)
 {
+  MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_GET_CLASS (manager);
   MetaMonitorInfo *old_monitor_infos;
-
+  unsigned old_n_monitor_infos;
+  unsigned i, j;
   old_monitor_infos = manager->monitor_infos;
+  old_n_monitor_infos = manager->n_monitor_infos;
 
   if (manager->in_init)
     return;
 
   make_logical_config (manager);
 
+  if (manager_class->delete_monitor)
+    {
+      for (i = 0; i < old_n_monitor_infos; i++)
+        {
+          gboolean delete_mon = TRUE;
+          for (j = 0; j < manager->n_monitor_infos; j++)
+            {
+              if (manager->monitor_infos[j].monitor_winsys_xid == old_monitor_infos[i].monitor_winsys_xid)
+                {
+                  delete_mon = FALSE;
+                  break;
+                }
+            }
+          if (delete_mon)
+            manager_class->delete_monitor (manager, old_monitor_infos[i].monitor_winsys_xid);
+        }
+    }
   g_signal_emit_by_name (manager, "monitors-changed");
 
   g_free (old_monitor_infos);
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
index 81948e6..3e52679 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
@@ -1251,6 +1251,88 @@ meta_monitor_manager_xrandr_set_crtc_gamma (MetaMonitorManager *manager,
   XRRFreeGamma (gamma);
 }
 
+#ifdef HAVE_XRANDR15
+static void
+meta_monitor_manager_xrandr_add_monitor(MetaMonitorManager *manager,
+                                        MetaMonitorInfo *monitor)
+{
+  MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager);
+  XRRMonitorInfo *m;
+  int o;
+  Atom name;
+  char name_buf[40];
+
+  if (manager_xrandr->has_randr15 == FALSE)
+    return;
+
+  if (monitor->n_outputs <= 1)
+    return;
+
+  if (monitor->outputs[0]->product)
+    snprintf (name_buf, 40, "%s-%d", monitor->outputs[0]->product, monitor->outputs[0]->tile_info.group_id);
+  else
+    snprintf (name_buf, 40, "Tiled-%d", monitor->outputs[0]->tile_info.group_id);
+
+  name = XInternAtom (manager_xrandr->xdisplay, name_buf, False);
+  monitor->monitor_winsys_xid = name;
+  m = XRRAllocateMonitor (manager_xrandr->xdisplay, monitor->n_outputs);
+  if (!m)
+    return;
+  m->name = name;
+  m->primary = monitor->is_primary;
+  m->automatic = True;
+
+  for (o = 0; o < monitor->n_outputs; o++) {
+    MetaOutput *output = monitor->outputs[o];
+    m->outputs[o] = output->winsys_id;
+  }
+  XRRSetMonitor (manager_xrandr->xdisplay,
+                 DefaultRootWindow (manager_xrandr->xdisplay),
+                 m);
+  XRRFreeMonitors (m);
+}
+
+static void
+meta_monitor_manager_xrandr_delete_monitor(MetaMonitorManager *manager,
+                                           int monitor_winsys_xid)
+{
+  MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager);
+
+  if (manager_xrandr->has_randr15 == FALSE)
+    return;
+  XRRDeleteMonitor (manager_xrandr->xdisplay,
+                    DefaultRootWindow (manager_xrandr->xdisplay),
+                    monitor_winsys_xid);
+}
+
+static void
+meta_monitor_manager_xrandr_init_monitors(MetaMonitorManagerXrandr *manager_xrandr)
+{
+  XRRMonitorInfo *m;
+  int n, i;
+
+  if (manager_xrandr->has_randr15 == FALSE)
+    return;
+
+  /* delete any tiled monitors setup, as mutter will want to recreate
+     things in its image */
+  m = XRRGetMonitors (manager_xrandr->xdisplay,
+                      DefaultRootWindow (manager_xrandr->xdisplay),
+                      FALSE, &n);
+  if (n == -1)
+    return;
+
+  for (i = 0; i < n; i++)
+    {
+      if (m[i].noutput > 1)
+        XRRDeleteMonitor (manager_xrandr->xdisplay,
+                          DefaultRootWindow (manager_xrandr->xdisplay),
+                          m[i].name);
+    }
+  XRRFreeMonitors (m);
+}
+#endif
+
 static void
 meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
 {
@@ -1283,6 +1365,7 @@ meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
           (major_version == 1 &&
            minor_version >= 5))
         manager_xrandr->has_randr15 = TRUE;
+      meta_monitor_manager_xrandr_init_monitors (manager_xrandr);
 #endif
     }
 }
@@ -1314,6 +1397,10 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass)
   manager_class->change_backlight = meta_monitor_manager_xrandr_change_backlight;
   manager_class->get_crtc_gamma = meta_monitor_manager_xrandr_get_crtc_gamma;
   manager_class->set_crtc_gamma = meta_monitor_manager_xrandr_set_crtc_gamma;
+#ifdef HAVE_XRANDR15
+  manager_class->add_monitor = meta_monitor_manager_xrandr_add_monitor;
+  manager_class->delete_monitor = meta_monitor_manager_xrandr_delete_monitor;
+#endif
 }
 
 gboolean


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]