[PATCH] map-to-output: implement reflections and rotations
Alon Levy
alevy at redhat.com
Sat Jun 9 13:05:11 PDT 2012
On Sat, Jun 09, 2012 at 05:23:37PM +0300, Alon Levy wrote:
This is for xinput.. messed the $SUBJECT.
> 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.
I tested with an external monitor, all sixsteen options with the
following xrandr configuration:
o----------.
| .-------.
| Primary | |
| | |
| | |
'----------'-------x
The display crtc was the box defined by 'o' and 'x'
>
> 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
>
> _______________________________________________
> xorg-devel at lists.x.org: X.Org development
> Archives: http://lists.x.org/archives/xorg-devel
> Info: http://lists.x.org/mailman/listinfo/xorg-devel
More information about the xorg-devel
mailing list