[mutter/wip/wayland-display: 41/62] MonitorManager: fix handling of output transform



commit b9e271750ec8b9e5f6d1214e16942095c0b36d9f
Author: Giovanni Campagna <gcampagn redhat com>
Date:   Wed Jul 24 10:01:57 2013 +0200

    MonitorManager: fix handling of output transform
    
    Read the current transform from XRandR, and expose the transforms
    that are really supported on the bus.
    The dummy backend now advertises all transforms, since it doesn't
    actually apply them.

 src/core/monitor-private.h |   18 ++++++++
 src/core/monitor.c         |   98 +++++++++++++++++++++++++++++++++++++------
 src/wayland/meta-wayland.c |    2 +-
 3 files changed, 103 insertions(+), 15 deletions(-)
---
diff --git a/src/core/monitor-private.h b/src/core/monitor-private.h
index 7325b1c..1809676 100644
--- a/src/core/monitor-private.h
+++ b/src/core/monitor-private.h
@@ -43,6 +43,22 @@
 #include <meta/screen.h>
 #include "stack-tracker.h"
 #include "ui.h"
+#ifdef HAVE_WAYLAND
+#include <wayland-server.h>
+#endif
+
+#ifndef HAVE_WAYLAND
+enum wl_output_transform {
+  WL_OUTPUT_TRANSFORM_NORMAL,
+  WL_OUTPUT_TRANSFORM_90,
+  WL_OUTPUT_TRANSFORM_180,
+  WL_OUTPUT_TRANSFORM_270,
+  WL_OUTPUT_TRANSFORM_FLIPPED,
+  WL_OUTPUT_TRANSFORM_FLIPPED_90,
+  WL_OUTPUT_TRANSFORM_FLIPPED_180,
+  WL_OUTPUT_TRANSFORM_FLIPPED_270
+};
+#endif
 
 typedef struct _MetaOutput MetaOutput;
 typedef struct _MetaCRTC MetaCRTC;
@@ -92,6 +108,8 @@ struct _MetaCRTC
   glong crtc_id;
   MetaRectangle rect;
   MetaMonitorMode *current_mode;
+  enum wl_output_transform transform;
+  unsigned int all_transforms;
 
   /* Only used to build the logical configuration
      from the HW one
diff --git a/src/core/monitor.c b/src/core/monitor.c
index c607963..d4688fe 100644
--- a/src/core/monitor.c
+++ b/src/core/monitor.c
@@ -43,18 +43,7 @@
 
 #include "meta-dbus-xrandr.h"
 
-#ifndef HAVE_WAYLAND
-enum wl_output_transform {
-  WL_OUTPUT_TRANSFORM_NORMAL,
-  WL_OUTPUT_TRANSFORM_90,
-  WL_OUTPUT_TRANSFORM_180,
-  WL_OUTPUT_TRANSFORM_270,
-  WL_OUTPUT_TRANSFORM_FLIPPED,
-  WL_OUTPUT_TRANSFORM_FLIPPED_90,
-  WL_OUTPUT_TRANSFORM_FLIPPED_180,
-  WL_OUTPUT_TRANSFORM_FLIPPED_270
-};
-#endif
+#define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1)
 
 typedef enum {
   META_BACKEND_UNSPECIFIED,
@@ -176,6 +165,8 @@ make_dummy_monitor_config (MetaMonitorManager *manager)
   manager->crtcs[0].rect.width = manager->modes[0].width;
   manager->crtcs[0].rect.height = manager->modes[0].height;
   manager->crtcs[0].current_mode = &manager->modes[0];
+  manager->crtcs[0].transform = WL_OUTPUT_TRANSFORM_NORMAL;
+  manager->crtcs[0].all_transforms = ALL_WL_TRANSFORMS;
   manager->crtcs[0].dirty = FALSE;
   manager->crtcs[0].logical_monitor = NULL;
 
@@ -185,6 +176,8 @@ make_dummy_monitor_config (MetaMonitorManager *manager)
   manager->crtcs[1].rect.width = 0;
   manager->crtcs[1].rect.height = 0;
   manager->crtcs[1].current_mode = NULL;
+  manager->crtcs[1].transform = WL_OUTPUT_TRANSFORM_NORMAL;
+  manager->crtcs[1].all_transforms = ALL_WL_TRANSFORMS;
   manager->crtcs[1].dirty = FALSE;
   manager->crtcs[1].logical_monitor = NULL;
 
@@ -259,6 +252,76 @@ make_dummy_monitor_config (MetaMonitorManager *manager)
 }
 
 #ifdef HAVE_RANDR
+static enum wl_output_transform
+wl_transform_from_xrandr (Rotation rotation)
+{
+  static const enum wl_output_transform y_reflected_map[4] = {
+    WL_OUTPUT_TRANSFORM_FLIPPED_180,
+    WL_OUTPUT_TRANSFORM_FLIPPED_90,
+    WL_OUTPUT_TRANSFORM_FLIPPED,
+    WL_OUTPUT_TRANSFORM_FLIPPED_270
+  };
+  enum wl_output_transform ret;
+
+  switch (rotation & 0x7F)
+    {
+    default:
+    case RR_Rotate_0:
+      ret = WL_OUTPUT_TRANSFORM_NORMAL;
+      break;
+    case RR_Rotate_90:
+      ret = WL_OUTPUT_TRANSFORM_90;
+      break;
+    case RR_Rotate_180:
+      ret = WL_OUTPUT_TRANSFORM_180;
+      break;
+    case RR_Rotate_270:
+      ret = WL_OUTPUT_TRANSFORM_270;
+      break;
+    }
+
+  if (rotation & RR_Reflect_X)
+    return ret + 4;
+  else if (rotation & RR_Reflect_Y)
+    return y_reflected_map[ret];
+  else
+    return ret;
+}
+
+#define ALL_ROTATIONS (RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270)
+
+static unsigned int
+wl_transform_from_xrandr_all (Rotation rotation)
+{
+  unsigned ret;
+
+  /* Handle the common cases first (none or all) */
+  if (rotation == 0 || rotation == RR_Rotate_0)
+    return (1 << WL_OUTPUT_TRANSFORM_NORMAL);
+
+  /* All rotations and one reflection -> all of them by composition */
+  if ((rotation & ALL_ROTATIONS) &&
+      ((rotation & RR_Reflect_X) || (rotation & RR_Reflect_Y)))
+    return ALL_WL_TRANSFORMS;
+
+  ret = 1 << WL_OUTPUT_TRANSFORM_NORMAL;
+  if (rotation & RR_Rotate_90)
+    ret |= 1 << WL_OUTPUT_TRANSFORM_90;
+  if (rotation & RR_Rotate_180)
+    ret |= 1 << WL_OUTPUT_TRANSFORM_180;
+  if (rotation & RR_Rotate_270)
+    ret |= 1 << WL_OUTPUT_TRANSFORM_270;
+  if (rotation & (RR_Rotate_0 | RR_Reflect_X))
+    ret |= 1 << WL_OUTPUT_TRANSFORM_FLIPPED;
+  if (rotation & (RR_Rotate_90 | RR_Reflect_X))
+    ret |= 1 << WL_OUTPUT_TRANSFORM_FLIPPED_90;
+  if (rotation & (RR_Rotate_180 | RR_Reflect_X))
+    ret |= 1 << WL_OUTPUT_TRANSFORM_FLIPPED_180;
+  if (rotation & (RR_Rotate_270 | RR_Reflect_X))
+    ret |= 1 << WL_OUTPUT_TRANSFORM_FLIPPED_270;
+
+  return ret;
+}
 
 static void
 read_monitor_infos_from_xrandr (MetaMonitorManager *manager)
@@ -329,6 +392,8 @@ read_monitor_infos_from_xrandr (MetaMonitorManager *manager)
         meta_crtc->rect.width = crtc->width;
         meta_crtc->rect.height = crtc->height;
         meta_crtc->dirty = FALSE;
+        meta_crtc->transform = wl_transform_from_xrandr (crtc->rotation);
+        meta_crtc->all_transforms = wl_transform_from_xrandr_all (crtc->rotations);
 
         for (j = 0; j < (unsigned)resources->nmode; j++)
           {
@@ -546,6 +611,8 @@ read_monitor_infos_from_cogl (MetaMonitorManager *manager)
                                                             cogl_output_get_width (output),
                                                             cogl_output_get_height (output),
                                                             cogl_output_get_refresh_rate (output));
+      meta_crtc.transform = WL_OUTPUT_TRANSFORM_NORMAL;
+      meta_crtc.all_transforms = 1 << WL_OUTPUT_TRANSFORM_NORMAL;
       meta_crtc.logical_monitor = NULL;
       meta_crtc.dirty = FALSE;
 
@@ -881,7 +948,9 @@ handle_get_resources (MetaDBusDisplayConfig *skeleton,
       GVariantBuilder transforms;
 
       g_variant_builder_init (&transforms, G_VARIANT_TYPE ("au"));
-      g_variant_builder_add (&transforms, "u", 0); /* 0 = WL_OUTPUT_TRANSFORM_NORMAL */
+      for (j = 0; j <= WL_OUTPUT_TRANSFORM_FLIPPED_270; j++)
+        if (crtc->all_transforms & (1 << j))
+          g_variant_builder_add (&transforms, "u", j);
 
       g_variant_builder_add (&crtc_builder, "(uxiiiiiuaua{sv})",
                              i, /* ID */
@@ -891,7 +960,7 @@ handle_get_resources (MetaDBusDisplayConfig *skeleton,
                              (int)crtc->rect.width,
                              (int)crtc->rect.height,
                              (int)(crtc->current_mode ? crtc->current_mode - manager->modes : -1),
-                             0, /* 0 = WL_OUTPUT_TRANSFORM_NORMAL */
+                             crtc->transform,
                              &transforms,
                              NULL /* properties */);
     }
@@ -1174,6 +1243,7 @@ apply_config_dummy (MetaMonitorManager *manager,
           crtc->rect.width = mode->width;
           crtc->rect.height = mode->height;
           crtc->current_mode = mode;
+          crtc->transform = transform;
 
           screen_width = MAX (screen_width, x + mode->width);
           screen_height = MAX (screen_height, y + mode->height);
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index 9119284..d38288c 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -623,7 +623,7 @@ bind_output (struct wl_client *client,
                          output->subpixel_order,
                          output->vendor,
                          output->product,
-                         WL_OUTPUT_TRANSFORM_NORMAL);
+                         output->crtc->transform);
 
   wl_resource_post_event (resource,
                          WL_OUTPUT_MODE,


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