Redefine output rotations
authorPekka Paalanen <pekka.paalanen@collabora.com>
Thu, 6 Feb 2020 13:27:54 +0000 (15:27 +0200)
committerDaniel Stone <daniel@fooishbar.org>
Thu, 27 Feb 2020 11:08:48 +0000 (11:08 +0000)
It was discovered in issue #99 that the implementations of the 90 and 270
degree rotations were actually the inverse of what the Wayland specification
spelled out. This patch fixes the libweston implementation to follow the
specification.

As a result, the behaviour of the the weston.ini transform key also changes. To
force all users to re-think their configuration, the transform key values are
also changed. Since Weston and libweston change their behaviour, the handling
of clients' buffer transform changes too.

All the functions had their 90/270 cases simply swapped, probably due to
confusion of whether WL_OUTPUT_TRANSFORM_* refers to rotating the monitor or
the content.

Hint: a key to understanding weston_matrix_rotate_xy(m, c, s) is that the
rotation matrix is formed as

  c -s
  s  c

that is, it's column-major. This fooled me at first.

Fixing window.c fixes weston-terminal and weston-transformed.

In simple-damage, window_get_transformed_ball() is fixed to follow the proper
transform definitions, but the fix to the viewport path in redraw() is purely
mechanical.  The viewport path looks broken to me in the presence of any
transform, but it is not this patch's job to fix it.

Screen-share fix just repeats the general code fix pattern, I did not even try
to understand that bit.

https://gitlab.freedesktop.org/wayland/weston/issues/99

Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
clients/simple-damage.c
clients/transformed.c
clients/window.c
compositor/main.c
compositor/screen-share.c
libweston/compositor.c
man/weston-drm.man
man/weston.ini.man

index 0458bd0649a7e61a2be05ecb5a6a9ccae6286216..821b42b5411a9e734a22837044f50e7e91b421a1 100644 (file)
@@ -461,32 +461,32 @@ window_get_transformed_ball(struct window *window, float *bx, float *by)
                *by = wy;
                break;
        case WL_OUTPUT_TRANSFORM_90:
-               *bx = window->height - wy;
-               *by = wx;
+               *bx = wy;
+               *by = window->width - wx;
                break;
        case WL_OUTPUT_TRANSFORM_180:
                *bx = window->width - wx;
                *by = window->height - wy;
                break;
        case WL_OUTPUT_TRANSFORM_270:
-               *bx = wy;
-               *by = window->width - wx;
+               *bx = window->height - wy;
+               *by = wx;
                break;
        case WL_OUTPUT_TRANSFORM_FLIPPED:
                *bx = window->width - wx;
                *by = wy;
                break;
        case WL_OUTPUT_TRANSFORM_FLIPPED_90:
-               *bx = window->height - wy;
-               *by = window->width - wx;
+               *bx = wy;
+               *by = wx;
                break;
        case WL_OUTPUT_TRANSFORM_FLIPPED_180:
                *bx = wx;
                *by = window->height - wy;
                break;
        case WL_OUTPUT_TRANSFORM_FLIPPED_270:
-               *bx = wy;
-               *by = wx;
+               *bx = window->height - wy;
+               *by = window->width - wx;
                break;
        }
 
@@ -570,32 +570,32 @@ redraw(void *data, struct wl_callback *callback, uint32_t time)
                        off_x = tx;
                        break;
                case WL_OUTPUT_TRANSFORM_90:
-                       off_y = tx;
-                       off_x = bwidth - ty;
+                       off_y = bheight - tx;
+                       off_x = ty;
                        break;
                case WL_OUTPUT_TRANSFORM_180:
                        off_y = bheight - ty;
                        off_x = bwidth - tx;
                        break;
                case WL_OUTPUT_TRANSFORM_270:
-                       off_y = bheight - tx;
-                       off_x = ty;
+                       off_y = tx;
+                       off_x = bwidth - ty;
                        break;
                case WL_OUTPUT_TRANSFORM_FLIPPED:
                        off_y = ty;
                        off_x = bwidth - tx;
                        break;
                case WL_OUTPUT_TRANSFORM_FLIPPED_90:
-                       off_y = bheight - tx;
-                       off_x = bwidth - ty;
+                       off_y = tx;
+                       off_x = ty;
                        break;
                case WL_OUTPUT_TRANSFORM_FLIPPED_180:
                        off_y = bheight - ty;
                        off_x = tx;
                        break;
                case WL_OUTPUT_TRANSFORM_FLIPPED_270:
-                       off_y = tx;
-                       off_x = ty;
+                       off_y = bheight - tx;
+                       off_x = bwidth - ty;
                        break;
                }
                wp_viewport_set_source(window->viewport,
index ab9459fa13729c5d565ac418f99f13fb80ef454e..59f44bcaac1476f2382270d32bc9d908729acfeb 100644 (file)
@@ -231,6 +231,9 @@ usage(int error_code)
                "   -h <height>\tSet window height to <height>\n"
                "   --help\tShow this help text\n\n");
 
+       fprintf(stderr, "This version has been fixed for "
+               "https://gitlab.freedesktop.org/wayland/weston/issues/99 .\n");
+
        exit(error_code);
 }
 
index 970d54ce490d1889f9fb919d8fddc011f4051f98..5a75bd407278690b0a88edae0177cefcc6cb03b8 100644 (file)
@@ -1832,14 +1832,14 @@ widget_cairo_update_transform(struct widget *widget, cairo_t *cr)
                translate_y = 0;
                break;
        case WL_OUTPUT_TRANSFORM_90:
-               angle = M_PI_2;
-               translate_x = surface_height;
-               translate_y = 0;
+               angle = M_PI + M_PI_2;
+               translate_x = 0;
+               translate_y = surface_width;
                break;
        case WL_OUTPUT_TRANSFORM_FLIPPED_90:
-               angle = M_PI_2;
-               translate_x = surface_height;
-               translate_y = surface_width;
+               angle = M_PI + M_PI_2;
+               translate_x = 0;
+               translate_y = 0;
                break;
        case WL_OUTPUT_TRANSFORM_180:
                angle = M_PI;
@@ -1852,14 +1852,14 @@ widget_cairo_update_transform(struct widget *widget, cairo_t *cr)
                translate_y = surface_height;
                break;
        case WL_OUTPUT_TRANSFORM_270:
-               angle = M_PI + M_PI_2;
-               translate_x = 0;
-               translate_y = surface_width;
+               angle = M_PI_2;
+               translate_x = surface_height;
+               translate_y = 0;
                break;
        case WL_OUTPUT_TRANSFORM_FLIPPED_270:
-               angle = M_PI + M_PI_2;
-               translate_x = 0;
-               translate_y = 0;
+               angle = M_PI_2;
+               translate_x = surface_height;
+               translate_y = surface_width;
                break;
        }
 
index 02944f7b2b51d10602a9314e46cf9cc9820e2aad..d5a7f04efdfcddbfec7ba589a5b0469be2758e06 100644 (file)
@@ -1107,14 +1107,14 @@ weston_choose_default_backend(void)
 }
 
 static const struct { const char *name; uint32_t token; } transforms[] = {
-       { "normal",     WL_OUTPUT_TRANSFORM_NORMAL },
-       { "90",         WL_OUTPUT_TRANSFORM_90 },
-       { "180",        WL_OUTPUT_TRANSFORM_180 },
-       { "270",        WL_OUTPUT_TRANSFORM_270 },
-       { "flipped",    WL_OUTPUT_TRANSFORM_FLIPPED },
-       { "flipped-90", WL_OUTPUT_TRANSFORM_FLIPPED_90 },
-       { "flipped-180", WL_OUTPUT_TRANSFORM_FLIPPED_180 },
-       { "flipped-270", WL_OUTPUT_TRANSFORM_FLIPPED_270 },
+       { "normal",             WL_OUTPUT_TRANSFORM_NORMAL },
+       { "rotate-90",          WL_OUTPUT_TRANSFORM_90 },
+       { "rotate-180",         WL_OUTPUT_TRANSFORM_180 },
+       { "rotate-270",         WL_OUTPUT_TRANSFORM_270 },
+       { "flipped",            WL_OUTPUT_TRANSFORM_FLIPPED },
+       { "flipped-rotate-90",  WL_OUTPUT_TRANSFORM_FLIPPED_90 },
+       { "flipped-rotate-180", WL_OUTPUT_TRANSFORM_FLIPPED_180 },
+       { "flipped-rotate-270", WL_OUTPUT_TRANSFORM_FLIPPED_270 },
 };
 
 WL_EXPORT int
index c8256faca2a8d2ce5a1195171466f16a6ab3f375..62b871bf3641b2d6ab2a073d2c0dc6a293199dae 100644 (file)
@@ -551,8 +551,8 @@ output_compute_transform(struct weston_output *output,
                break;
        case WL_OUTPUT_TRANSFORM_90:
        case WL_OUTPUT_TRANSFORM_FLIPPED_90:
-               pixman_transform_rotate(transform, NULL, 0, pixman_fixed_1);
-               pixman_transform_translate(transform, NULL, fh, 0);
+               pixman_transform_rotate(transform, NULL, 0, -pixman_fixed_1);
+               pixman_transform_translate(transform, NULL, 0, fw);
                break;
        case WL_OUTPUT_TRANSFORM_180:
        case WL_OUTPUT_TRANSFORM_FLIPPED_180:
@@ -561,8 +561,8 @@ output_compute_transform(struct weston_output *output,
                break;
        case WL_OUTPUT_TRANSFORM_270:
        case WL_OUTPUT_TRANSFORM_FLIPPED_270:
-               pixman_transform_rotate(transform, NULL, 0, -pixman_fixed_1);
-               pixman_transform_translate(transform, NULL, 0, fw);
+               pixman_transform_rotate(transform, NULL, 0, pixman_fixed_1);
+               pixman_transform_translate(transform, NULL, fh, 0);
                break;
        }
 
index d085126aa8e796082e28e3710e27f58a876a7ccf..29c0ab18ab75720c9440aec83b4498dcd4efed81 100644 (file)
@@ -643,12 +643,12 @@ weston_transformed_coord(int width, int height,
                *by = sy;
                break;
        case WL_OUTPUT_TRANSFORM_90:
-               *bx = height - sy;
-               *by = sx;
+               *bx = sy;
+               *by = width - sx;
                break;
        case WL_OUTPUT_TRANSFORM_FLIPPED_90:
-               *bx = height - sy;
-               *by = width - sx;
+               *bx = sy;
+               *by = sx;
                break;
        case WL_OUTPUT_TRANSFORM_180:
                *bx = width - sx;
@@ -659,12 +659,12 @@ weston_transformed_coord(int width, int height,
                *by = height - sy;
                break;
        case WL_OUTPUT_TRANSFORM_270:
-               *bx = sy;
-               *by = width - sx;
+               *bx = height - sy;
+               *by = sx;
                break;
        case WL_OUTPUT_TRANSFORM_FLIPPED_270:
-               *bx = sy;
-               *by = sx;
+               *bx = height - sy;
+               *by = width - sx;
                break;
        }
 
@@ -830,10 +830,10 @@ weston_transformed_region(int width, int height,
                                dest_rects[i].y2 = src_rects[i].y2;
                                break;
                        case WL_OUTPUT_TRANSFORM_90:
-                               dest_rects[i].x1 = height - src_rects[i].y2;
-                               dest_rects[i].y1 = src_rects[i].x1;
-                               dest_rects[i].x2 = height - src_rects[i].y1;
-                               dest_rects[i].y2 = src_rects[i].x2;
+                               dest_rects[i].x1 = src_rects[i].y1;
+                               dest_rects[i].y1 = width - src_rects[i].x2;
+                               dest_rects[i].x2 = src_rects[i].y2;
+                               dest_rects[i].y2 = width - src_rects[i].x1;
                                break;
                        case WL_OUTPUT_TRANSFORM_180:
                                dest_rects[i].x1 = width - src_rects[i].x2;
@@ -842,10 +842,10 @@ weston_transformed_region(int width, int height,
                                dest_rects[i].y2 = height - src_rects[i].y1;
                                break;
                        case WL_OUTPUT_TRANSFORM_270:
-                               dest_rects[i].x1 = src_rects[i].y1;
-                               dest_rects[i].y1 = width - src_rects[i].x2;
-                               dest_rects[i].x2 = src_rects[i].y2;
-                               dest_rects[i].y2 = width - src_rects[i].x1;
+                               dest_rects[i].x1 = height - src_rects[i].y2;
+                               dest_rects[i].y1 = src_rects[i].x1;
+                               dest_rects[i].x2 = height - src_rects[i].y1;
+                               dest_rects[i].y2 = src_rects[i].x2;
                                break;
                        case WL_OUTPUT_TRANSFORM_FLIPPED:
                                dest_rects[i].x1 = width - src_rects[i].x2;
@@ -854,10 +854,10 @@ weston_transformed_region(int width, int height,
                                dest_rects[i].y2 = src_rects[i].y2;
                                break;
                        case WL_OUTPUT_TRANSFORM_FLIPPED_90:
-                               dest_rects[i].x1 = height - src_rects[i].y2;
-                               dest_rects[i].y1 = width - src_rects[i].x2;
-                               dest_rects[i].x2 = height - src_rects[i].y1;
-                               dest_rects[i].y2 = width - src_rects[i].x1;
+                               dest_rects[i].x1 = src_rects[i].y1;
+                               dest_rects[i].y1 = src_rects[i].x1;
+                               dest_rects[i].x2 = src_rects[i].y2;
+                               dest_rects[i].y2 = src_rects[i].x2;
                                break;
                        case WL_OUTPUT_TRANSFORM_FLIPPED_180:
                                dest_rects[i].x1 = src_rects[i].x1;
@@ -866,10 +866,10 @@ weston_transformed_region(int width, int height,
                                dest_rects[i].y2 = height - src_rects[i].y1;
                                break;
                        case WL_OUTPUT_TRANSFORM_FLIPPED_270:
-                               dest_rects[i].x1 = src_rects[i].y1;
-                               dest_rects[i].y1 = src_rects[i].x1;
-                               dest_rects[i].x2 = src_rects[i].y2;
-                               dest_rects[i].y2 = src_rects[i].x2;
+                               dest_rects[i].x1 = height - src_rects[i].y2;
+                               dest_rects[i].y1 = width - src_rects[i].x2;
+                               dest_rects[i].x2 = height - src_rects[i].y1;
+                               dest_rects[i].y2 = width - src_rects[i].x1;
                                break;
                        }
                }
@@ -3402,9 +3402,9 @@ weston_surface_build_buffer_matrix(const struct weston_surface *surface,
                break;
        case WL_OUTPUT_TRANSFORM_90:
        case WL_OUTPUT_TRANSFORM_FLIPPED_90:
-               weston_matrix_rotate_xy(matrix, 0, 1);
+               weston_matrix_rotate_xy(matrix, 0, -1);
                weston_matrix_translate(matrix,
-                                       surface->height_from_buffer, 0, 0);
+                                       0, surface->width_from_buffer, 0);
                break;
        case WL_OUTPUT_TRANSFORM_180:
        case WL_OUTPUT_TRANSFORM_FLIPPED_180:
@@ -3415,9 +3415,9 @@ weston_surface_build_buffer_matrix(const struct weston_surface *surface,
                break;
        case WL_OUTPUT_TRANSFORM_270:
        case WL_OUTPUT_TRANSFORM_FLIPPED_270:
-               weston_matrix_rotate_xy(matrix, 0, -1);
+               weston_matrix_rotate_xy(matrix, 0, 1);
                weston_matrix_translate(matrix,
-                                       0, surface->width_from_buffer, 0);
+                                       surface->height_from_buffer, 0, 0);
                break;
        }
 
@@ -5786,8 +5786,8 @@ weston_output_update_matrix(struct weston_output *output)
                break;
        case WL_OUTPUT_TRANSFORM_90:
        case WL_OUTPUT_TRANSFORM_FLIPPED_90:
-               weston_matrix_translate(&output->matrix, 0, -output->height, 0);
-               weston_matrix_rotate_xy(&output->matrix, 0, 1);
+               weston_matrix_translate(&output->matrix, -output->width, 0, 0);
+               weston_matrix_rotate_xy(&output->matrix, 0, -1);
                break;
        case WL_OUTPUT_TRANSFORM_180:
        case WL_OUTPUT_TRANSFORM_FLIPPED_180:
@@ -5797,8 +5797,8 @@ weston_output_update_matrix(struct weston_output *output)
                break;
        case WL_OUTPUT_TRANSFORM_270:
        case WL_OUTPUT_TRANSFORM_FLIPPED_270:
-               weston_matrix_translate(&output->matrix, -output->width, 0, 0);
-               weston_matrix_rotate_xy(&output->matrix, 0, -1);
+               weston_matrix_translate(&output->matrix, 0, -output->height, 0);
+               weston_matrix_rotate_xy(&output->matrix, 0, 1);
                break;
        }
 
index 488eef6ef9d5faa9d5bfadd959521b069342abaf..ebf370ebfa5d65fbe25c8a8a8bdbfb3247966349 100644 (file)
@@ -119,8 +119,9 @@ can generate detailed mode lines.
 \fBtransform\fR=\fItransform\fR
 Transform for the output, which can be rotated in 90-degree steps
 and possibly flipped. Possible values are
-.BR normal ", " 90 ", " 180 ", " 270 ", "
-.BR flipped ", " flipped-90 ", " flipped-180 ", and " flipped-270 .
+.BR normal ", " rotate-90 ", " rotate-180 ", " rotate-270 ", "
+.BR flipped ", " flipped-rotate-90 ", " flipped-rotate-180 ", and "
+.BR flipped-rotate-270 .
 .TP
 \fBpixman-shadow\fR=\fIboolean\fR
 If using the Pixman-renderer, use shadow framebuffers. Defaults to
index 5e39e4a58fc4a5cc514f5e3598cf1625a839a68b..bce5628b66f41bcf0a50f96512039d4e751cf0b8 100644 (file)
@@ -504,19 +504,19 @@ for examples of modes-formats supported by DRM backend.
 .RE
 .TP 7
 .BI "transform=" normal
-The transformation applied to screen output (string). The transform key can
-be one of the following 8 strings:
+How you have rotated your monitor from its normal orientation (string).
+The transform key can be one of the following 8 strings:
 .PP
 .RS 10
 .nf
-.BR  "normal        " "Normal output."
-.BR  "90            " "90 degrees clockwise."
-.BR  "180           " "Upside down."
-.BR  "270           " "90 degrees counter clockwise."
-.BR  "flipped       " "Horizontally flipped"
-.BR  "flipped-90    " "Flipped and 90 degrees clockwise"
-.BR  "flipped-180   " "Flipped upside down"
-.BR  "flipped-270   " "Flipped and 90 degrees counter clockwise"
+.BR  "normal               " "Normal output."
+.BR  "rotate-90            " "90 degrees clockwise."
+.BR  "rotate-180           " "Upside down."
+.BR  "rotate-270           " "90 degrees counter clockwise."
+.BR  "flipped              " "Horizontally flipped"
+.BR  "flipped-rotate-90    " "Flipped and 90 degrees clockwise"
+.BR  "flipped-rotate-180   " "Flipped and upside down"
+.BR  "flipped-rotate-270   " "Flipped and 90 degrees counter clockwise"
 .fi
 .RE
 .TP 7