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.
This commit is contained in:
Giovanni Campagna 2013-07-24 10:01:57 +02:00
parent 0d1647cbc4
commit ee6b729196
3 changed files with 103 additions and 15 deletions

View File

@ -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

View File

@ -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;
@ -925,7 +992,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 */
@ -935,7 +1004,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 */);
}
@ -1220,6 +1289,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);

View File

@ -658,7 +658,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,