[PATCH] map-to-output: implement reflections and rotations

Peter Hutterer peter.hutterer at who-t.net
Mon Jun 11 22:40:02 PDT 2012


On Sat, Jun 09, 2012 at 05:23:37PM +0300, Alon Levy wrote:
> Uses the rotation & translation currently set according to RandR.
> 
> Signed-off-by: Alon Levy <alevy at redhat.com>
> ---
> Tested with a x220t (lenovo tablet). The comments below "correct in working
> zone", I believe are not related to the wrong matrix, you can see for instance
> that 'RR_Rotate_270 | RR_Reflect_All' is limited but 'RR_Rotate_90' is not and
> they both set the same matrix. So I think it's a RandR related bug.

confirmed, this is somewhere else since my mouse movement, a relative
device, gets stuck too. merged, thanks for the patch!

Cheers,
  Peter

> 
>  src/transform.c |   78 ++++++++++++++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 69 insertions(+), 9 deletions(-)
> 
> diff --git a/src/transform.c b/src/transform.c
> index f80a592..d85b071 100644
> --- a/src/transform.c
> +++ b/src/transform.c
> @@ -107,10 +107,30 @@ apply_matrix(Display *dpy, int deviceid, Matrix *m)
>  }
>  
>  static void
> +matrix_s4(Matrix *m, float x02, float x12, float d1, float d2, int main_diag)
> +{
> +    matrix_set(m, 0, 2, x02);
> +    matrix_set(m, 1, 2, x12);
> +
> +    if (main_diag) {
> +        matrix_set(m, 0, 0, d1);
> +        matrix_set(m, 1, 1, d2);
> +    } else {
> +        matrix_set(m, 0, 0, 0);
> +        matrix_set(m, 1, 1, 0);
> +        matrix_set(m, 0, 1, d1);
> +        matrix_set(m, 1, 0, d2);
> +    }
> +}
> +
> +#define RR_Reflect_All	(RR_Reflect_X|RR_Reflect_Y)
> +
> +static void
>  set_transformation_matrix(Display *dpy, Matrix *m, int offset_x, int offset_y,
> -                                int screen_width, int screen_height)
> +                          int screen_width, int screen_height,
> +                          int rotation)
>  {
> -    /* offset */
> +    /* total display size */
>      int width = DisplayWidth(dpy, DefaultScreen(dpy));
>      int height = DisplayHeight(dpy, DefaultScreen(dpy));
>  
> @@ -124,11 +144,49 @@ set_transformation_matrix(Display *dpy, Matrix *m, int offset_x, int offset_y,
>  
>      matrix_set_unity(m);
>  
> -    matrix_set(m, 0, 2, x);
> -    matrix_set(m, 1, 2, y);
> -
> -    matrix_set(m, 0, 0, w);
> -    matrix_set(m, 1, 1, h);
> +    /*
> +     * There are 16 cases:
> +     * Rotation X Reflection
> +     * Rotation: 0 | 90 | 180 | 270
> +     * Reflection: None | X | Y | XY
> +     *
> +     * They are spelled out instead of doing matrix multiplication to avoid
> +     * any floating point errors.
> +     */
> +    switch (rotation) {
> +    case RR_Rotate_0:
> +    case RR_Rotate_180 | RR_Reflect_All:
> +        matrix_s4(m, x, y, w, h, 1);
> +        break;
> +    case RR_Reflect_X|RR_Rotate_0:
> +    case RR_Reflect_Y|RR_Rotate_180:
> +        matrix_s4(m, x + w, y, -w, h, 1);
> +        break;
> +    case RR_Reflect_Y|RR_Rotate_0:
> +    case RR_Reflect_X|RR_Rotate_180:
> +        matrix_s4(m, x, y + h, w, -h, 1);
> +        break;
> +    case RR_Rotate_90:
> +    case RR_Rotate_270 | RR_Reflect_All: /* left limited - correct in working zone. */
> +        matrix_s4(m, x + w, y, -w, h, 0);
> +        break;
> +    case RR_Rotate_270:
> +    case RR_Rotate_90 | RR_Reflect_All: /* left limited - correct in working zone. */
> +        matrix_s4(m, x, y + h, w, -h, 0);
> +        break;
> +    case RR_Rotate_90 | RR_Reflect_X: /* left limited - correct in working zone. */
> +    case RR_Rotate_270 | RR_Reflect_Y: /* left limited - correct in working zone. */
> +        matrix_s4(m, x, y, w, h, 0);
> +        break;
> +    case RR_Rotate_90 | RR_Reflect_Y: /* right limited - correct in working zone. */
> +    case RR_Rotate_270 | RR_Reflect_X: /* right limited - correct in working zone. */
> +        matrix_s4(m, x + w, y + h, -w, -h, 0);
> +        break;
> +    case RR_Rotate_180:
> +    case RR_Reflect_All|RR_Rotate_0:
> +        matrix_s4(m, x + w, y + h, -w, -h, 1);
> +        break;
> +    }
>  
>  #if DEBUG
>      matrix_print(m);
> @@ -186,7 +244,8 @@ map_output_xrandr(Display *dpy, int deviceid, const char *output_name)
>          matrix_set_unity(&m);
>          crtc_info = XRRGetCrtcInfo (dpy, res, output_info->crtc);
>          set_transformation_matrix(dpy, &m, crtc_info->x, crtc_info->y,
> -                                  crtc_info->width, crtc_info->height);
> +                                  crtc_info->width, crtc_info->height,
> +                                  crtc_info->rotation);
>          rc = apply_matrix(dpy, deviceid, &m);
>          XRRFreeCrtcInfo(crtc_info);
>          XRRFreeOutputInfo(output_info);
> @@ -242,7 +301,8 @@ map_output_xinerama(Display *dpy, int deviceid, const char *output_name)
>      matrix_set_unity(&m);
>      set_transformation_matrix(dpy, &m,
>                                screens[head].x_org, screens[head].y_org,
> -                              screens[head].width, screens[head].height);
> +                              screens[head].width, screens[head].height,
> +                              RR_Rotate_0);
>      rc = apply_matrix(dpy, deviceid, &m);
>  
>  out:
> -- 
> 1.7.10.1
> 


More information about the xorg-devel mailing list