[RFC] [PATCH weston v2] Implement output transformations.
Scott Moreau
oreaus at gmail.com
Thu Aug 16 01:33:06 PDT 2012
This patch allows rotation and mirroring outputs for x11 and drm backends.
A new 'transform' key can be set in the [output] section. From the protocol:
"The flipped values correspond to an initial flip around a vertical axis
followed by rotation."
The transform key can be one of the following 8 strings:
normal
90
180
270
flipped
flipped-90
flipped-180
flipped-270
---
Changed in v2:
- x11 output position corrected.
- Fix usage of disable_planes.
src/compositor-android.c | 3 +-
src/compositor-drm.c | 79 ++++++++++++-----
src/compositor-wayland.c | 3 +-
src/compositor-x11.c | 217 ++++++++++++++++++++++++++++++++++++-----------
src/compositor.c | 113 +++++++++++++++++++++++-
src/compositor.h | 2 +-
weston.ini | 3 +
7 files changed, 341 insertions(+), 79 deletions(-)
diff --git a/src/compositor-android.c b/src/compositor-android.c
index a9c45d2..b095262 100644
--- a/src/compositor-android.c
+++ b/src/compositor-android.c
@@ -238,7 +238,8 @@ android_compositor_add_output(struct android_compositor *compositor,
mm_width = output->fb->width / output->fb->xdpi * 25.4f;
mm_height = output->fb->height / output->fb->ydpi * 25.4f;
weston_output_init(&output->base, &compositor->base,
- 0, 0, round(mm_width), round(mm_height));
+ 0, 0, round(mm_width), round(mm_height),
+ WL_OUTPUT_TRANSFORM_NORMAL);
wl_list_insert(compositor->base.output_list.prev, &output->base.link);
}
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 8c8c8c0..0911894 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -46,6 +46,7 @@
static int option_current_mode = 0;
static char *output_name;
static char *output_mode;
+static char *output_transform;
static struct wl_list configured_output_list;
enum output_config {
@@ -60,6 +61,7 @@ enum output_config {
struct drm_configured_output {
char *name;
char *mode;
+ uint32_t transform;
int32_t width, height;
drmModeModeInfo crtc_mode;
enum output_config config;
@@ -1528,7 +1530,8 @@ create_output_for_connector(struct drm_compositor *ec,
}
weston_output_init(&output->base, &ec->base, x, y,
- connector->mmWidth, connector->mmHeight);
+ connector->mmWidth, connector->mmHeight,
+ o ? o->transform : WL_OUTPUT_TRANSFORM_NORMAL);
wl_list_insert(ec->base.output_list.prev, &output->base.link);
@@ -2066,14 +2069,6 @@ evdev_input_destroy(struct weston_seat *seat_base)
}
static void
-drm_free_configured_output(struct drm_configured_output *output)
-{
- free(output->name);
- free(output->mode);
- free(output);
-}
-
-static void
drm_destroy(struct weston_compositor *ec)
{
struct drm_compositor *d = (struct drm_compositor *) ec;
@@ -2083,7 +2078,7 @@ drm_destroy(struct weston_compositor *ec)
wl_list_for_each_safe(seat, next, &ec->seat_list, link)
evdev_input_destroy(seat);
wl_list_for_each_safe(o, n, &configured_output_list, link)
- drm_free_configured_output(o);
+ free(o);
wl_event_source_remove(d->udev_drm_source);
wl_event_source_remove(d->drm_source);
@@ -2412,23 +2407,52 @@ check_for_modeline(struct drm_configured_output *output)
}
static void
+output_set_transform(struct drm_configured_output *output)
+{
+ if (!output_transform) {
+ output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
+ return;
+ }
+
+ if (!strcmp(output_transform, "normal"))
+ output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
+ else if (!strcmp(output_transform, "90"))
+ output->transform = WL_OUTPUT_TRANSFORM_90;
+ else if (!strcmp(output_transform, "180"))
+ output->transform = WL_OUTPUT_TRANSFORM_180;
+ else if (!strcmp(output_transform, "270"))
+ output->transform = WL_OUTPUT_TRANSFORM_270;
+ else if (!strcmp(output_transform, "flipped"))
+ output->transform = WL_OUTPUT_TRANSFORM_FLIPPED;
+ else if (!strcmp(output_transform, "flipped-90"))
+ output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_90;
+ else if (!strcmp(output_transform, "flipped-180"))
+ output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_180;
+ else if (!strcmp(output_transform, "flipped-270"))
+ output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_270;
+ else {
+ weston_log("Invalid transform \"%s\" for output %s\n",
+ output_transform, output_name);
+ output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
+ }
+}
+
+static void
output_section_done(void *data)
{
struct drm_configured_output *output;
output = malloc(sizeof *output);
- if (!output || !output_name || !output_mode) {
- free(output_name);
- output_name = NULL;
- free(output_mode);
- output_mode = NULL;
- return;
- }
+ if (!output || !output_name || !output_mode)
+ goto err_free;
+
+ if (output_name[0] == 'X')
+ goto err_free;
output->config = OUTPUT_CONFIG_INVALID;
- output->name = output_name;
- output->mode = output_mode;
+ output->name = strdup(output_name);
+ output->mode = strdup(output_mode);
if (strcmp(output_mode, "off") == 0)
output->config = OUTPUT_CONFIG_OFF;
@@ -2441,13 +2465,21 @@ output_section_done(void *data)
else if (check_for_modeline(output) == 0)
output->config = OUTPUT_CONFIG_MODELINE;
- if (output->config != OUTPUT_CONFIG_INVALID)
- wl_list_insert(&configured_output_list, &output->link);
- else {
+ if (output->config == OUTPUT_CONFIG_INVALID) {
weston_log("Invalid mode \"%s\" for output %s\n",
output_mode, output_name);
- drm_free_configured_output(output);
+ goto err_free;
}
+
+ output_set_transform(output);
+
+ wl_list_insert(&configured_output_list, &output->link);
+
+err_free:
+ free(output_name);
+ output_name = NULL;
+ free(output_mode);
+ output_mode = NULL;
}
WL_EXPORT struct weston_compositor *
@@ -2471,6 +2503,7 @@ backend_init(struct wl_display *display, int argc, char *argv[],
const struct config_key drm_config_keys[] = {
{ "name", CONFIG_KEY_STRING, &output_name },
{ "mode", CONFIG_KEY_STRING, &output_mode },
+ { "transform", CONFIG_KEY_STRING, &output_transform },
};
const struct config_section config_section[] = {
diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index 4fc77f1..84eaf6c 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -395,7 +395,8 @@ wayland_compositor_create_output(struct wayland_compositor *c,
wl_list_insert(&output->base.mode_list, &output->mode.link);
output->base.current = &output->mode;
- weston_output_init(&output->base, &c->base, 0, 0, width, height);
+ weston_output_init(&output->base, &c->base, 0, 0, width, height,
+ WL_OUTPUT_TRANSFORM_NORMAL);
output->base.border.top = c->border.top;
output->base.border.bottom = c->border.bottom;
diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index c02911d..1f22286 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -52,6 +52,7 @@
static char *output_name;
static char *output_mode;
+static char *output_transform;
static int option_width;
static int option_height;
static int option_count;
@@ -60,6 +61,7 @@ static struct wl_list configured_output_list;
struct x11_configured_output {
char *name;
int width, height;
+ uint32_t transform;
struct wl_list link;
};
@@ -474,9 +476,12 @@ x11_output_set_icon(struct x11_compositor *c,
static int
x11_compositor_create_output(struct x11_compositor *c, int x, int y,
int width, int height, int fullscreen,
- int no_input, const char *name)
+ int no_input, char *configured_name,
+ uint32_t transform)
{
+ static const char name[] = "Weston Compositor";
static const char class[] = "weston-1\0Weston Compositor";
+ char title[32];
struct x11_output *output;
xcb_screen_iterator_t iter;
struct wm_normal_hints normal_hints;
@@ -488,6 +493,11 @@ x11_compositor_create_output(struct x11_compositor *c, int x, int y,
0
};
+ if (configured_name)
+ sprintf(title, "%s - %s", name, configured_name);
+ else
+ strcpy(title, name);
+
if (!no_input)
values[0] |=
XCB_EVENT_MASK_KEY_PRESS |
@@ -517,7 +527,8 @@ x11_compositor_create_output(struct x11_compositor *c, int x, int y,
output->base.current = &output->mode;
output->base.make = "xwayland";
output->base.model = "none";
- weston_output_init(&output->base, &c->base, x, y, width, height);
+ weston_output_init(&output->base, &c->base, x, y, width, height,
+ transform);
values[1] = c->null_cursor;
output->window = xcb_generate_id(c->conn);
@@ -550,7 +561,7 @@ x11_compositor_create_output(struct x11_compositor *c, int x, int y,
/* Set window name. Don't bother with non-EWMH WMs. */
xcb_change_property(c->conn, XCB_PROP_MODE_REPLACE, output->window,
c->atom.net_wm_name, c->atom.utf8_string, 8,
- strlen(name), name);
+ strlen(title), title);
xcb_change_property(c->conn, XCB_PROP_MODE_REPLACE, output->window,
c->atom.wm_class, c->atom.string, 8,
sizeof class, class);
@@ -739,6 +750,98 @@ x11_compositor_deliver_button_event(struct x11_compositor *c,
WL_POINTER_BUTTON_STATE_RELEASED);
}
+static void
+x11_output_transform_coordinate(struct x11_output *x11_output,
+ wl_fixed_t *x, wl_fixed_t *y)
+{
+ struct weston_output *output = &x11_output->base;
+ wl_fixed_t tx, ty;
+ wl_fixed_t width = wl_fixed_from_int(output->current->width - 1);
+ wl_fixed_t height = wl_fixed_from_int(output->current->height - 1);
+
+ switch(output->transform) {
+ case WL_OUTPUT_TRANSFORM_NORMAL:
+ default:
+ tx = *x;
+ ty = *y;
+ break;
+ case WL_OUTPUT_TRANSFORM_90:
+ tx = *y;
+ ty = height - *x;
+ break;
+ case WL_OUTPUT_TRANSFORM_180:
+ tx = width - *x;
+ ty = height - *y;
+ break;
+ case WL_OUTPUT_TRANSFORM_270:
+ tx = width - *y;
+ ty = *x;
+ break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED:
+ tx = width - *x;
+ ty = *y;
+ break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+ tx = width - *y;
+ ty = height - *x;
+ break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED_180:
+ tx = *x;
+ ty = height - *y;
+ break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+ tx = *y;
+ ty = *x;
+ break;
+ }
+
+ tx += wl_fixed_from_int(output->x);
+ ty += wl_fixed_from_int(output->y);
+
+ *x = tx;
+ *y = ty;
+}
+
+static void
+x11_compositor_deliver_motion_event(struct x11_compositor *c,
+ xcb_generic_event_t *event)
+{
+ struct x11_output *output;
+ wl_fixed_t x, y;
+ xcb_motion_notify_event_t *motion_notify =
+ (xcb_motion_notify_event_t *) event;
+
+ if (!c->has_xkb)
+ update_xkb_state_from_core(c, motion_notify->state);
+ output = x11_compositor_find_output(c, motion_notify->event);
+ x = wl_fixed_from_int(motion_notify->event_x);
+ y = wl_fixed_from_int(motion_notify->event_y);
+ x11_output_transform_coordinate(output, &x, &y);
+
+ notify_motion(&c->core_seat, weston_compositor_get_time(), x, y);
+}
+
+static void
+x11_compositor_deliver_enter_event(struct x11_compositor *c,
+ xcb_generic_event_t *event)
+{
+ struct x11_output *output;
+ wl_fixed_t x, y;
+
+ xcb_enter_notify_event_t *enter_notify =
+ (xcb_enter_notify_event_t *) event;
+ if (enter_notify->state >= Button1Mask)
+ return;
+ if (!c->has_xkb)
+ update_xkb_state_from_core(c, enter_notify->state);
+ output = x11_compositor_find_output(c, enter_notify->event);
+ x = wl_fixed_from_int(enter_notify->event_x);
+ y = wl_fixed_from_int(enter_notify->event_y);
+ x11_output_transform_coordinate(output, &x, &y);
+
+ notify_pointer_focus(&c->core_seat, &output->base, x, y);
+}
+
static int
x11_compositor_next_event(struct x11_compositor *c,
xcb_generic_event_t **event, uint32_t mask)
@@ -763,7 +866,6 @@ x11_compositor_handle_event(int fd, uint32_t mask, void *data)
struct x11_output *output;
xcb_generic_event_t *event, *prev;
xcb_client_message_event_t *client_message;
- xcb_motion_notify_event_t *motion_notify;
xcb_enter_notify_event_t *enter_notify;
xcb_key_press_event_t *key_press, *key_release;
xcb_keymap_notify_event_t *keymap_notify;
@@ -772,7 +874,6 @@ x11_compositor_handle_event(int fd, uint32_t mask, void *data)
xcb_atom_t atom;
uint32_t *k;
uint32_t i, set;
- wl_fixed_t x, y;
int count;
prev = NULL;
@@ -872,14 +973,7 @@ x11_compositor_handle_event(int fd, uint32_t mask, void *data)
x11_compositor_deliver_button_event(c, event, 0);
break;
case XCB_MOTION_NOTIFY:
- motion_notify = (xcb_motion_notify_event_t *) event;
- if (!c->has_xkb)
- update_xkb_state_from_core(c, motion_notify->state);
- output = x11_compositor_find_output(c, motion_notify->event);
- x = wl_fixed_from_int(output->base.x + motion_notify->event_x);
- y = wl_fixed_from_int(output->base.y + motion_notify->event_y);
- notify_motion(&c->core_seat,
- weston_compositor_get_time(), x, y);
+ x11_compositor_deliver_motion_event(c, event);
break;
case XCB_EXPOSE:
@@ -889,17 +983,7 @@ x11_compositor_handle_event(int fd, uint32_t mask, void *data)
break;
case XCB_ENTER_NOTIFY:
- enter_notify = (xcb_enter_notify_event_t *) event;
- if (enter_notify->state >= Button1Mask)
- break;
- if (!c->has_xkb)
- update_xkb_state_from_core(c, enter_notify->state);
- output = x11_compositor_find_output(c, enter_notify->event);
- x = wl_fixed_from_int(output->base.x + enter_notify->event_x);
- y = wl_fixed_from_int(output->base.y + enter_notify->event_y);
-
- notify_pointer_focus(&c->core_seat,
- &output->base, x, y);
+ x11_compositor_deliver_enter_event(c, event);
break;
case XCB_LEAVE_NOTIFY:
@@ -1031,20 +1115,13 @@ x11_restore(struct weston_compositor *ec)
}
static void
-x11_free_configured_output(struct x11_configured_output *output)
-{
- free(output->name);
- free(output);
-}
-
-static void
x11_destroy(struct weston_compositor *ec)
{
struct x11_compositor *compositor = (struct x11_compositor *)ec;
struct x11_configured_output *o, *n;
wl_list_for_each_safe(o, n, &configured_output_list, link)
- x11_free_configured_output(o);
+ free(o);
wl_event_source_remove(compositor->xcb_source);
x11_input_destroy(compositor);
@@ -1063,8 +1140,6 @@ x11_compositor_create(struct wl_display *display,
int no_input,
int argc, char *argv[], const char *config_file)
{
- static const char name[] = "Weston Compositor";
- char configured_name[32];
struct x11_compositor *c;
struct x11_configured_output *o;
xcb_screen_iterator_t s;
@@ -1117,16 +1192,27 @@ x11_compositor_create(struct wl_display *display,
count = option_count ? option_count : 1;
wl_list_for_each(o, &configured_output_list, link) {
- sprintf(configured_name, "%s - %s", name, o->name);
if (x11_compositor_create_output(c, x, 0,
- option_width ? option_width :
+ option_width ? width :
o->width,
- option_height ? option_height :
+ option_height ? height :
o->height,
fullscreen, no_input,
- configured_name) < 0)
+ o->name, o->transform) < 0)
goto err_x11_input;
- x += option_width ? option_width : o->width;
+
+ switch(o->transform) {
+ case WL_OUTPUT_TRANSFORM_90:
+ case WL_OUTPUT_TRANSFORM_270:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+ x += option_height ? option_height : o->height;
+ break;
+ default:
+ x += option_width ? option_width : o->width;
+ break;
+ }
+
output_count++;
if (option_count && output_count >= option_count)
break;
@@ -1134,7 +1220,8 @@ x11_compositor_create(struct wl_display *display,
for (i = output_count; i < count; i++) {
if (x11_compositor_create_output(c, x, 0, width, height,
- fullscreen, no_input, name) < 0)
+ fullscreen, no_input, NULL,
+ WL_OUTPUT_TRANSFORM_NORMAL) < 0)
goto err_x11_input;
x += width;
}
@@ -1160,37 +1247,68 @@ err_free:
}
static void
+output_set_transform(struct x11_configured_output *output)
+{
+ if (!output_transform) {
+ output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
+ return;
+ }
+
+ if (!strcmp(output_transform, "normal"))
+ output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
+ else if (!strcmp(output_transform, "90"))
+ output->transform = WL_OUTPUT_TRANSFORM_90;
+ else if (!strcmp(output_transform, "180"))
+ output->transform = WL_OUTPUT_TRANSFORM_180;
+ else if (!strcmp(output_transform, "270"))
+ output->transform = WL_OUTPUT_TRANSFORM_270;
+ else if (!strcmp(output_transform, "flipped"))
+ output->transform = WL_OUTPUT_TRANSFORM_FLIPPED;
+ else if (!strcmp(output_transform, "flipped-90"))
+ output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_90;
+ else if (!strcmp(output_transform, "flipped-180"))
+ output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_180;
+ else if (!strcmp(output_transform, "flipped-270"))
+ output->transform = WL_OUTPUT_TRANSFORM_FLIPPED_270;
+ else {
+ weston_log("Invalid transform \"%s\" for output %s\n",
+ output_transform, output_name);
+ output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
+ }
+}
+
+static void
output_section_done(void *data)
{
struct x11_configured_output *output;
output = malloc(sizeof *output);
- if (!output || !output_name || !output_mode) {
- free(output_name);
- output_name = NULL;
+ if (!output || !output_name || !output_mode)
goto err_free;
- }
- output->name = output_name;
+ output->name = strdup(output_name);
- if (output_name[0] != 'X') {
- x11_free_configured_output(output);
+ if (output_name[0] != 'X')
goto err_free;
- }
if (sscanf(output_mode, "%dx%d", &output->width, &output->height) != 2) {
weston_log("Invalid mode \"%s\" for output %s\n",
output_mode, output_name);
- x11_free_configured_output(output);
goto err_free;
}
+ output_set_transform(output);
+
wl_list_insert(configured_output_list.prev, &output->link);
err_free:
+ free(output_name);
+ output_name = NULL;
free(output_mode);
output_mode = NULL;
+ free(output_transform);
+ output_transform = NULL;
}
WL_EXPORT struct weston_compositor *
@@ -1215,6 +1333,7 @@ backend_init(struct wl_display *display, int argc, char *argv[],
const struct config_key x11_config_keys[] = {
{ "name", CONFIG_KEY_STRING, &output_name },
{ "mode", CONFIG_KEY_STRING, &output_mode },
+ { "transform", CONFIG_KEY_STRING, &output_transform },
};
const struct config_section config_section[] = {
diff --git a/src/compositor.c b/src/compositor.c
index 7370435..8e4cc21 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1136,7 +1136,7 @@ weston_output_repaint(struct weston_output *output, uint32_t msecs)
struct weston_frame_callback *cb, *cnext;
struct wl_list frame_callback_list;
pixman_region32_t opaque, output_damage;
- int32_t width, height;
+ int32_t width, height, temp;
weston_compositor_update_drag_surfaces(ec);
@@ -1144,6 +1144,20 @@ weston_output_repaint(struct weston_output *output, uint32_t msecs)
output->border.left + output->border.right;
height = output->current->height +
output->border.top + output->border.bottom;
+
+ switch(output->transform) {
+ case WL_OUTPUT_TRANSFORM_90:
+ case WL_OUTPUT_TRANSFORM_270:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+ temp = width;
+ width = height;
+ height = temp;
+ break;
+ default:
+ break;
+ }
+
glViewport(0, 0, width, height);
/* Rebuild the surface list and update surface transforms up front. */
@@ -2962,12 +2976,61 @@ weston_output_destroy(struct weston_output *output)
wl_display_remove_global(c->wl_display, output->global);
}
+static void
+weston_output_compute_transform(struct weston_output *output,
+ struct weston_matrix *transform, int *flip)
+{
+ *flip = 1;
+ weston_matrix_init(transform);
+
+ switch(output->transform) {
+ case WL_OUTPUT_TRANSFORM_90:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+ transform->d[0] = 0;
+ transform->d[1] = -1;
+ transform->d[4] = 1;
+ transform->d[5] = 0;
+ break;
+ case WL_OUTPUT_TRANSFORM_180:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_180:
+ transform->d[0] = 1;
+ transform->d[1] = 0;
+ transform->d[4] = 0;
+ transform->d[5] = -1;
+ break;
+ case WL_OUTPUT_TRANSFORM_270:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+ transform->d[0] = 0;
+ transform->d[1] = 1;
+ transform->d[4] = -1;
+ transform->d[5] = 0;
+ break;
+ default:
+ break;
+ }
+
+ switch(output->transform) {
+ case WL_OUTPUT_TRANSFORM_FLIPPED:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+ case WL_OUTPUT_TRANSFORM_180:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+ *flip = -1;
+ break;
+ default:
+ break;
+ }
+}
+
WL_EXPORT void
weston_output_update_matrix(struct weston_output *output)
{
float magnification;
struct weston_matrix camera;
struct weston_matrix modelview;
+ struct weston_matrix transform;
+ int flip;
+
+ weston_output_compute_transform(output, &transform, &flip);
weston_matrix_init(&output->matrix);
weston_matrix_translate(&output->matrix,
@@ -2975,9 +3038,12 @@ weston_output_update_matrix(struct weston_output *output)
-(output->y + (output->border.bottom + output->current->height - output->border.top) / 2.0), 0);
weston_matrix_scale(&output->matrix,
- 2.0 / (output->current->width + output->border.left + output->border.right),
+ flip * 2.0 / (output->current->width + output->border.left + output->border.right),
-2.0 / (output->current->height + output->border.top + output->border.bottom), 1);
+ if (output->transform != WL_OUTPUT_TRANSFORM_NORMAL)
+ weston_matrix_multiply(&output->matrix, &transform);
+
if (output->zoom.active) {
magnification = 1 / (1 - output->zoom.spring_z.current);
weston_matrix_init(&camera);
@@ -2993,6 +3059,39 @@ weston_output_update_matrix(struct weston_output *output)
output->dirty = 0;
}
+static void
+weston_output_transform_init(struct weston_output *output,
+ int *width, int *height,
+ uint32_t transform)
+{
+ int temp_w, temp_h;
+
+ output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
+
+ switch(transform) {
+ case WL_OUTPUT_TRANSFORM_90:
+ case WL_OUTPUT_TRANSFORM_270:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+ /* Swap width and height */
+ temp_w = output->current->height;
+ temp_h = output->current->width;
+ output->current->width = temp_w;
+ output->current->height = temp_h;
+ temp_w = *height;
+ temp_h = *width;
+ *width = temp_w;
+ *height = temp_h;
+ case WL_OUTPUT_TRANSFORM_180:
+ case WL_OUTPUT_TRANSFORM_FLIPPED:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_180:
+ output->transform = transform;
+ break;
+ default:
+ break;
+ }
+}
+
WL_EXPORT void
weston_output_move(struct weston_output *output, int x, int y)
{
@@ -3007,8 +3106,10 @@ weston_output_move(struct weston_output *output, int x, int y)
WL_EXPORT void
weston_output_init(struct weston_output *output, struct weston_compositor *c,
- int x, int y, int width, int height)
+ int x, int y, int width, int height, uint32_t transform)
{
+ weston_output_transform_init(output, &width, &height, transform);
+
output->compositor = c;
output->x = x;
output->y = y;
@@ -3019,7 +3120,11 @@ weston_output_init(struct weston_output *output, struct weston_compositor *c,
output->mm_width = width;
output->mm_height = height;
output->dirty = 1;
- output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
+
+ if (transform != WL_OUTPUT_TRANSFORM_NORMAL)
+ output->disable_planes++;
+
+ output->transform = transform;
weston_output_init_zoom(output);
diff --git a/src/compositor.h b/src/compositor.h
index 7a8058e..f856418 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -682,7 +682,7 @@ void
weston_output_move(struct weston_output *output, int x, int y);
void
weston_output_init(struct weston_output *output, struct weston_compositor *c,
- int x, int y, int width, int height);
+ int x, int y, int width, int height, uint32_t transform);
void
weston_output_destroy(struct weston_output *output);
diff --git a/weston.ini b/weston.ini
index 3fda31b..99d24dd 100644
--- a/weston.ini
+++ b/weston.ini
@@ -37,11 +37,14 @@ duration=600
#[output]
#name=LVDS1
#mode=1680x1050
+#transform=90
#[output]
#name=VGA1
#mode=173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync
+#transform=flipped
#[output]
#name=X1
#mode=1024x768
+#transform=flipped-270
--
1.7.11.2
More information about the wayland-devel
mailing list