[PATCH xinput] Add rotation support

Peter Hutterer peter.hutterer at who-t.net
Thu Jul 12 23:23:05 PDT 2012


Rotating the device simply sets the Coordinate Transformation Matrix to the
rotation matrix, it does not handle screen mapping or offsets.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 configure.ac    |    3 +++
 man/xinput.man  |    6 ++++++
 src/Makefile.am |    4 ++--
 src/property.c  |   44 ++++++++++++++++++++++++++++++++++++++++++++
 src/xinput.c    |    5 +++++
 src/xinput.h    |    2 ++
 6 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index f53a81f..745d46b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -37,6 +37,9 @@ m4_ifndef([XORG_MACROS_VERSION],
 XORG_MACROS_VERSION(1.8)
 XORG_DEFAULT_OPTIONS
 
+AC_CHECK_LIB([m], [cos])
+AC_CHECK_LIB([m], [sin])
+
 # Obtain compiler/linker options for dependencies
 PKG_CHECK_MODULES(XINPUT, x11 xext [xi >= 1.2] [inputproto >= 1.5] xrandr xinerama)
 
diff --git a/man/xinput.man b/man/xinput.man
index 540308b..8a1b23c 100644
--- a/man/xinput.man
+++ b/man/xinput.man
@@ -158,6 +158,12 @@ Enable the \fIdevice\fP. This call is equivalent to
 Disable the \fIdevice\fP. This call is equivalent to
 .B xinput --set-prop device \fI"Device Enabled"\fP 0
 .PP
+.TP 8
+.B --rotate \fIdevice\fP \fIangle\fP
+Rotate the \fIdevice\fP by \fIangle\fP counterclockwise. This call is equivalent to
+.B xinput --set-prop device \fI"Coordinate Transformation Matrix"\fP <rotation matrix>.
+An angle of 90 degrees is equivalent to RandR's "left" orientation.
+.PP
 \fIdevice\fP can be the device name as a string or the XID of the
 device.
 .PP
diff --git a/src/Makefile.am b/src/Makefile.am
index 985207b..ee69b0f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -22,8 +22,8 @@
 
 bin_PROGRAMS = xinput
 
-AM_CFLAGS = $(XINPUT_CFLAGS)
-xinput_LDADD = $(XINPUT_LIBS)
+AM_CFLAGS = $(XINPUT_CFLAGS) $(M_CFLAGS)
+xinput_LDADD = $(XINPUT_LIBS) $(M_LIBS)
 
 
 if HAVE_XI2
diff --git a/src/property.c b/src/property.c
index 66a3842..4a93459 100644
--- a/src/property.c
+++ b/src/property.c
@@ -23,6 +23,7 @@
  */
 
 #include <ctype.h>
+#include <math.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdint.h>
@@ -841,3 +842,46 @@ int enable(Display *display, int argc, char *argv[], char *name, char *desc)
     char *new_argv[3] = { argv[0], "Device Enabled", "1" };
     return set_prop(display, 3, new_argv, name, desc);
 }
+
+int rotate(Display *display, int argc, char *argv[], char *name, char *desc)
+{
+    char *endptr;
+    char *new_argv[11] = { argv[0], "Coordinate Transformation Matrix" };
+    long int angle;
+    double matrix[9];
+    double rad;
+    char matrix_str[9][6];
+    int i;
+
+    if (argc < 2) {
+        fprintf(stderr, "Usage: xinput %s %s\n", name, desc);
+        return EXIT_FAILURE;
+    }
+
+    angle = strtol(argv[1], &endptr, 10);
+    if (argv[1] == '\0' || *endptr != '\0') {
+        fprintf(stderr, "Invalid angle. Angle must be in degrees counterclockwise.\n");
+        return EXIT_FAILURE;
+    }
+
+    rad = angle * M_PI/180.0;
+
+    memset(matrix, 0, sizeof(matrix));
+    matrix[0] = cos(rad);
+    matrix[1] = -sin(rad);
+    matrix[3] = sin(rad);
+    matrix[4] = cos(rad);
+
+    /* offset */
+    matrix[2] = -0.5 * cos(rad) + 0.5 * sin(rad) + 0.5;
+    matrix[5] = -0.5 * sin(rad) - 0.5 * cos(rad) + 0.5;
+
+    matrix[8] = 1;
+
+    for (i = 0; i < 9; i++) {
+        sprintf(matrix_str[i], "%.2f", matrix[i]);
+        new_argv[i + 2] = matrix_str[i];
+    }
+
+    return set_prop(display, 11, new_argv, name, desc);
+}
diff --git a/src/xinput.c b/src/xinput.c
index 0f86720..d6480f5 100644
--- a/src/xinput.c
+++ b/src/xinput.c
@@ -147,6 +147,11 @@ static entry drivers[] =
       "<device>",
       enable,
     },
+    {
+      "rotate",
+      "<device> <angle>",
+      rotate,
+    },
     {NULL, NULL, NULL
     }
 };
diff --git a/src/xinput.h b/src/xinput.h
index c37e6e6..493c049 100644
--- a/src/xinput.h
+++ b/src/xinput.h
@@ -81,4 +81,6 @@ int set_clientpointer( Display* display, int argc, char *argv[], char *prog_name
 int test_xi2( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
 int map_to_output( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
 
+int rotate( Display* display, int argc, char *argv[], char *prog_name, char *prog_desc);
+
 /* end of xinput.h */
-- 
1.7.10.4



More information about the xorg-devel mailing list