[gnome-flashback] display-config: construct tiled monitors info



commit 5c955bd92496d1e4009946f1fb08e109adca35ca
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Thu Jun 4 02:36:44 2015 +0300

    display-config: construct tiled monitors info
    
    The monitors info structure is created from the tiled outputs
    and this is used as the central storage for info about a monitor
    as opposed to the output state.
    
    It appears at least the EDID mm w/h is for the whole monitor and
    not per tile.
    
    Based on:
    https://git.gnome.org/browse/mutter/commit/?id=ea2496c80a72b882b5b2a3f6eca2ca11d59c25ca

 .../libdisplay-config/flashback-monitor-manager.c  |  128 +++++++++++++++++++-
 .../libdisplay-config/flashback-monitor-manager.h  |   12 ++
 2 files changed, 139 insertions(+), 1 deletions(-)
---
diff --git a/gnome-flashback/libdisplay-config/flashback-monitor-manager.c 
b/gnome-flashback/libdisplay-config/flashback-monitor-manager.c
index 843d516..8f58880 100644
--- a/gnome-flashback/libdisplay-config/flashback-monitor-manager.c
+++ b/gnome-flashback/libdisplay-config/flashback-monitor-manager.c
@@ -662,6 +662,108 @@ gdk_rectangle_equal (const GdkRectangle *src1,
           (src1->width == src2->width) && (src1->height == src2->height));
 }
 
+static gboolean
+gdk_rectangle_contains_rect (const GdkRectangle *outer_rect,
+                             const GdkRectangle *inner_rect)
+{
+  return inner_rect->x                      >= outer_rect->x &&
+         inner_rect->y                      >= outer_rect->y &&
+         inner_rect->x + inner_rect->width  <= outer_rect->x + outer_rect->width &&
+         inner_rect->y + inner_rect->height <= outer_rect->y + outer_rect->height;
+}
+
+/*
+ * rules for constructing a tiled monitor
+ * 1. find a tile_group_id
+ * 2. iterate over all outputs for that tile group id
+ * 3. see if output has a crtc and if it is configured for the tile size
+ * 4. calculate the total tile size
+ * 5. set tile finished size
+ * 6. check for more tile_group_id
+*/
+static void
+construct_tile_monitor (FlashbackMonitorManager *manager,
+                        GArray                  *monitor_infos,
+                        guint32                  tile_group_id)
+{
+  MetaMonitorInfo info;
+  unsigned i;
+
+  for (i = 0; i < monitor_infos->len; i++)
+    {
+      MetaMonitorInfo *pinfo = &g_array_index (monitor_infos, MetaMonitorInfo, i);
+
+      if (pinfo->tile_group_id == tile_group_id)
+        return;
+    }
+
+  /* didn't find it */
+  info.number = monitor_infos->len;
+  info.tile_group_id = tile_group_id;
+  info.is_presentation = FALSE;
+  info.refresh_rate = 0.0;
+  info.width_mm = 0;
+  info.height_mm = 0;
+  info.is_primary = FALSE;
+  info.rect.x = INT_MAX;
+  info.rect.y = INT_MAX;
+  info.rect.width = 0;
+  info.rect.height = 0;
+  info.winsys_id = 0;
+  info.n_outputs = 0;
+  info.monitor_winsys_xid = 0;
+
+  for (i = 0; i < manager->n_outputs; i++)
+    {
+      MetaOutput *output = &manager->outputs[i];
+
+      if (!output->tile_info.group_id)
+        continue;
+
+      if (output->tile_info.group_id != tile_group_id)
+        continue;
+
+      if (!output->crtc)
+        continue;
+
+      if (output->crtc->rect.width != (int)output->tile_info.tile_w ||
+          output->crtc->rect.height != (int)output->tile_info.tile_h)
+        continue;
+
+      if (output->tile_info.loc_h_tile == 0 && output->tile_info.loc_v_tile == 0)
+        {
+          info.refresh_rate = output->crtc->current_mode->refresh_rate;
+          info.width_mm = output->width_mm;
+          info.height_mm = output->height_mm;
+          info.winsys_id = output->winsys_id;
+        }
+
+      /* hack */
+      if (output->crtc->rect.x < info.rect.x)
+        info.rect.x = output->crtc->rect.x;
+      if (output->crtc->rect.y < info.rect.y)
+        info.rect.y = output->crtc->rect.y;
+
+      if (output->tile_info.loc_h_tile == 0)
+        info.rect.height += output->tile_info.tile_h;
+
+      if (output->tile_info.loc_v_tile == 0)
+        info.rect.width += output->tile_info.tile_w;
+
+      if (info.n_outputs > META_MAX_OUTPUTS_PER_MONITOR)
+        continue;
+
+      info.outputs[info.n_outputs++] = output;
+    }
+
+  /* if we don't have a winsys id, i.e. we haven't found tile 0,0
+     don't try and add this to the monitor infos */
+  if (!info.winsys_id)
+    return;
+
+  g_array_append_val (monitor_infos, info);
+}
+
 /*
  * make_logical_config:
  *
@@ -682,6 +784,16 @@ make_logical_config (FlashbackMonitorManager *manager)
      for each of them, unless they reference a rectangle that
      is already there.
   */
+
+  /* for tiling we need to work out how many tiled outputs there are */
+  for (i = 0; i < manager->n_outputs; i++)
+    {
+      MetaOutput *output = &manager->outputs[i];
+
+      if (output->tile_info.group_id)
+        construct_tile_monitor (manager, monitor_infos, output->tile_info.group_id);
+    }
+
   for (i = 0; i < manager->n_crtcs; i++)
     {
       MetaCRTC *crtc = &manager->crtcs[i];
@@ -693,7 +805,7 @@ make_logical_config (FlashbackMonitorManager *manager)
       for (j = 0; j < monitor_infos->len; j++)
         {
           MetaMonitorInfo *info = &g_array_index (monitor_infos, MetaMonitorInfo, j);
-          if (gdk_rectangle_equal (&crtc->rect, &info->rect))
+          if (gdk_rectangle_contains_rect (&crtc->rect, &info->rect))
             {
               crtc->logical_monitor = info;
               break;
@@ -705,7 +817,9 @@ make_logical_config (FlashbackMonitorManager *manager)
           MetaMonitorInfo info;
 
           info.number = monitor_infos->len;
+          info.tile_group_id = 0;
           info.rect = crtc->rect;
+          info.refresh_rate = crtc->current_mode->refresh_rate;
           info.is_primary = FALSE;
           /* This starts true because we want
              is_presentation only if all outputs are
@@ -716,6 +830,9 @@ make_logical_config (FlashbackMonitorManager *manager)
           info.in_fullscreen = -1;
           info.winsys_id = 0;
 
+          info.n_outputs = 0;
+          info.monitor_winsys_xid = 0;
+
           g_array_append_val (monitor_infos, info);
 
           crtc->logical_monitor = &g_array_index (monitor_infos, MetaMonitorInfo,
@@ -737,6 +854,9 @@ make_logical_config (FlashbackMonitorManager *manager)
       if (output->crtc == NULL)
         continue;
 
+      if (output->tile_info.group_id)
+        continue;
+
       /* We must have a logical monitor on every CRTC at this point */
       g_assert (output->crtc->logical_monitor != NULL);
 
@@ -745,6 +865,12 @@ make_logical_config (FlashbackMonitorManager *manager)
       info->is_primary = info->is_primary || output->is_primary;
       info->is_presentation = info->is_presentation && output->is_presentation;
 
+      info->width_mm = output->width_mm;
+      info->height_mm = output->height_mm;
+
+      info->outputs[0] = output;
+      info->n_outputs = 1;
+
       if (output->is_primary || info->winsys_id == 0)
         info->winsys_id = output->winsys_id;
 
diff --git a/gnome-flashback/libdisplay-config/flashback-monitor-manager.h 
b/gnome-flashback/libdisplay-config/flashback-monitor-manager.h
index f16f621..f19686e 100644
--- a/gnome-flashback/libdisplay-config/flashback-monitor-manager.h
+++ b/gnome-flashback/libdisplay-config/flashback-monitor-manager.h
@@ -168,6 +168,8 @@ struct _MetaMonitorMode
   GDestroyNotify driver_notify;
 };
 
+#define META_MAX_OUTPUTS_PER_MONITOR 4
+
 /**
  * MetaMonitorInfo:
  *
@@ -183,6 +185,10 @@ struct _MetaMonitorInfo
   int          number;
   int          xinerama_index;
   GdkRectangle rect;
+  /* for tiled monitors these are calculated, from untiled just copied */
+  float        refresh_rate;
+  int          width_mm;
+  int          height_mm;
   gboolean     is_primary;
   gboolean     is_presentation; /* XXX: not yet used */
   gboolean     in_fullscreen;
@@ -196,6 +202,12 @@ struct _MetaMonitorInfo
      the primary one).
   */
   glong        winsys_id;
+
+  guint32      tile_group_id;
+
+  int          monitor_winsys_xid;
+  int          n_outputs;
+  MetaOutput  *outputs[META_MAX_OUTPUTS_PER_MONITOR];
 };
 
 /*


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