Re: Request for comments on zts rotational scaling issue - Proof of concept patch attached

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Re: Request for comments on zts rotational scaling issue - Proof of concept patch attached

asmith-4
Ok I accept that Xorg may at some stage create an extension for doing this but right now, and until OpenBSD accepts that release of Xorg there are scaling issues in the zts driver when subject to rotation.

I'm not pushing this necessarily as a patch but something that you can use parts of if you like etc.. I will run it myself because it adds a lot of functionality to the Zaurus.

What is attached is a patch to zts to implement a custom IOCTL to both set and query the touch screen orientation. Implementation code inside zts (following this patch) applies the rotation that has been set. The initial boot value is 0 and it takes 0, 90, 180 and 270 values via the IOCTL.

The zts_proprietary.h file simply defines these IOCTLs, I didn't want to patch wsconsio.h so they are in this seperate file. I took MOUSE IOCTL 38 for this proof of concept.

The final program ztsrot.c is a simple userland interface to the IOCTL, it takes a variety of methods for selecting the touch screen rotation e.g. you may use the arguments 0, none and wsfbcw to all represent the same value. the wsfb<n> values represent the equivalent rotation values that you would specify in the rotation field for the wsfb driver. Using ztsrot prior to starting X now means that you do not need to change the orientation of the mouse pointer in the ws driver section.

Hope this may be of some use at some stage. Having the rotation support in the touchscreen driver means that we will certainly be ready for the X extensions that you say that Xorg are promising Matthieu - note that although this patch is proof of concept it only patches the zts driver and is a reliable way of correcting the zts rotation scaling issue without disturbing secondary (USB) mouse calibration.

have fun,

- Andy



zts.c.rotationpatch

--- zts.c.original Mon Feb 13 16:49:07 2006
+++ zts.c Tue Feb 14 13:44:19 2006
@@ -35,6 +35,8 @@
 #include <arm/xscale/pxa2x0var.h>
 #include <arm/xscale/pxa2x0_lcd.h>
 
+#include "zts_proprietary.h"
+
 /*
  * ADS784x touch screen controller
  */
@@ -490,6 +492,7 @@
  int s;
  int pindown;
  int down;
+ int ntmp;
  extern int zkbd_modstate;
 
  if (!sc->sc_enabled)
@@ -522,6 +525,27 @@
     (tsp->ts_maxx - tsp->ts_minx);
  tp.y = ((tp.y - tsp->ts_miny) * sc->sc_resy) /
     (tsp->ts_maxy - tsp->ts_miny);
+
+ /*
+ * Now implement any rotation factors specified through the IOCTL
+ * ws_drv CW is normal landscape this is equiv to ORIENTATE_0
+ */
+
+ switch (zts_orientation) {
+ case WSMOUSE_ROTATE_ORIENTATE_270: /* ws_drv = UD */
+ ntmp=sc->sc_resx-tp.x;
+ tp.x=tp.y;
+ tp.y=ntmp;
+ break;
+ case WSMOUSE_ROTATE_ORIENTATE_180: /* ws_drv = CCW */
+ tp.x=sc->sc_resx-tp.x;
+ tp.y=sc->sc_resy-tp.y;
+ break;
+ case WSMOUSE_ROTATE_ORIENTATE_90: /* ws_drv = no rotate */
+ ntmp=sc->sc_resy-tp.y;
+ tp.y=tp.x;
+ tp.x=ntmp;
+ }
  }
  }
 
@@ -561,6 +585,25 @@
  case WSMOUSEIO_GTYPE:
  *(u_int *)data = WSMOUSE_TYPE_TPANEL;
  return (0);
+ case WSMOUSEIO_ROTATE_EXTENSION:
+
+ switch (*(u_int *)data) {
+ case WSMOUSE_ROTATE_QUERY:
+ *(u_int *)data=zts_orientation;
+ return (0);
+ case WSMOUSE_ROTATE_ORIENTATE_0:
+ case WSMOUSE_ROTATE_ORIENTATE_90:
+ case WSMOUSE_ROTATE_ORIENTATE_180:
+ case WSMOUSE_ROTATE_ORIENTATE_270:
+ zts_orientation=*(u_int *)data;
+ printf("zts: Rotation now %d\n",zts_orientation);
+ return (0);
+ default:
+ printf("zts: Rotation extension called with bad data %d\n",
+ *(u_int *)data);
+ /* Invalid command code */
+ return (-1);
+ }
  }
 
  return (-1);




zts_proprietary.h

/*
 * Proprietary stuff for now to provide proof of concept to zts rotation IOCTL
 * target location for this stuff will eventually be wsconsio.h
 */

#define WSMOUSEIO_ROTATE_EXTENSION _IOWR('W', 38, u_int)

#define WSMOUSE_ROTATE_ORIENTATE_0 0
#define WSMOUSE_ROTATE_ORIENTATE_90 90
#define WSMOUSE_ROTATE_ORIENTATE_180 180
#define WSMOUSE_ROTATE_ORIENTATE_270 270

#define WSMOUSE_ROTATE_QUERY 255

/* Default to 0 */
u_int zts_orientation=WSMOUSE_ROTATE_ORIENTATE_0;





ztsrot.c (quickly hacked together, some of the variable namings may not be in keeping with OpenBSD levels of coding but it works well)

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl_compat.h>
#include <dev/wscons/wsconsio.h>
#include "/sys/arch/zaurus/dev/zts_proprietary.h"

void usageexit(char *pProg);

typedef struct {
        u_int nArgVal;
        char* pOpt;
} optionLine;

optionLine argList[] = {
        { WSMOUSE_ROTATE_ORIENTATE_0, "0" },
        { WSMOUSE_ROTATE_ORIENTATE_0, "NONE" },
        { WSMOUSE_ROTATE_ORIENTATE_0, "WSFBCW" },

        { WSMOUSE_ROTATE_ORIENTATE_90, "90" },
        { WSMOUSE_ROTATE_ORIENTATE_90, "CCW" },
        { WSMOUSE_ROTATE_ORIENTATE_90, "WSFBNONE" },

        { WSMOUSE_ROTATE_ORIENTATE_180, "180" },
        { WSMOUSE_ROTATE_ORIENTATE_180, "UD" },
        { WSMOUSE_ROTATE_ORIENTATE_180, "WSFBCCW" },
       
        { WSMOUSE_ROTATE_ORIENTATE_270, "270" },
        { WSMOUSE_ROTATE_ORIENTATE_270, "CW" },
        { WSMOUSE_ROTATE_ORIENTATE_270, "WSFBUD" },

        { WSMOUSE_ROTATE_QUERY, "QUERY" },

        { NULL, NULL }
};

main(int argc, char* argv[])
{
        u_int rot;
        u_int bResult;
        int fd;
        u_int mousetype;
        int nOptLine;

        if (argc<2) usageexit(argv[0]);

        nOptLine=0;
        while (argList[nOptLine].pOpt) {
                if (0==strcasecmp(argList[nOptLine].pOpt,argv[1]))
                        break;
                nOptLine++;
        }

        if (NULL==argList[nOptLine].pOpt) usageexit(argv[0]);
        rot=argList[nOptLine].nArgVal;

        /* Flag for output on query commant */
        bResult=WSMOUSE_ROTATE_QUERY==rot;

        if (-1==(fd=open("/dev/wsmouse0",O_RDWR |O_NONBLOCK|O_EXCL))) {
                printf("Can't open the mouse device\n");
                exit(1);
        } else {
                if (-1==ioctl(fd,WSMOUSEIO_GTYPE,&mousetype)) {
                        printf("Mouse type IOCTL not supported\n");
                        close(fd);
                        exit(1);
                } else {
                        if (mousetype!=WSMOUSE_TYPE_TPANEL) {
                                printf("Not a touch panel (%02X)\n",mousetype);
                                close(fd);
                                exit(1);
                        }
                }

                if (-1==ioctl(fd,WSMOUSEIO_ROTATE_EXTENSION,&rot)) {
                        printf("That IOCTL isn't supported\n");
                        close(fd);
                        exit(1);
                }

                if (bResult) printf("Current rotation %d\n",rot);
        }
        close(fd);
}

void usageexit(char *pProg)
{
        int nOptLine;
        u_int nLastArg;
        printf("usage: %s <option>\n",pProg);
        nOptLine=0;
        printf("equivalent options are grouped below, note that wsfb options\n");
        printf("mimic the rotation options of the X wsfb display driver\n\n"); nLastArg=argList[nOptLine].nArgVal;
        while (argList[nOptLine].pOpt) {
                if (argList[nOptLine].nArgVal!=nLastArg) {
                        nLastArg=argList[nOptLine].nArgVal;
                        printf("\n");
                }
                printf("%s\n",argList[nOptLine].pOpt);
                nOptLine++;
        }
        exit(1);
}


-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On Behalf Of
Matthieu Herrb
Sent: 13 February 2006 17:47
To: Andrew Smith
Cc: [hidden email]
Subject: Re: Request for comments on zts rotational scaling issue

Andrew Smith wrote:
> There is an issue with running the Zaurus touch screen driver in portrait
mode in X.
>
> The issue is as follows.
>
> The zts driver provides /dev/wsmouse as standard and this is accessed
through the ws_drv.so mouse driver.
>
> A USB Mouse will connect on the Zaurus as /dev/wsmouse1 which will also be
accessed through the ws_drv.so driver.
>
> The zts driver requires a certain amount of calibration and internally
handles scalinig factors for X and Y co-ordinates. In the standard mode of
operation the ws driver through zts handles the mouse in Landscape mode.
>
> When the wsfb_drv.so screen driver is placed into portrait mode it starts
to translate mouse co-ordinates to a 90 degree rotation (or 270 degree if
placed in inverse portrait mode). To accomplish this it starts to manipulate
the X and Y co-ordinates of the mouse pointer directly.
>
> Unfortunately the /dev/mouse driver presented by the zts driver sends
absolute position events which are scaled according to landscape
orientation. This means that the zts screen is no longer aligned with the
mouse pointer when in portrait mode.
>
> To observe this issue switch the screen to portrait (comment out the
Option "rotate" "CW" from the wsfb section) and switch the mouse to portrait
mode too (uncomment the Option "Rotate" "CCW" from the ws section). What you
will observe is that the mouse pointer will drift away from the stylus as
the stylus is placed further away from the origin. This means that the
scaling is off when in portrait mode and is explained by the fact that the
wsdv_drv driver uses the scaled position of the X co-ordinate against the Y
axis and vica versa. This is a non issue for devices that don't require
scaling/calibration but is a big issue for devices that do.
>
> This explanation confirms why the screen works in standard landscape mode
(no Rotate on ws and CW rotate on wsfb) and also in upside down mode (UD
rotate on ws driver and CCW rotate on wsfb) since the scaling factor for an
inverted screen is the same as for the standard orientation.
>
> The issue cannot be fixed by coding scaling rotation into the ws driver
within X since this driver is also handling the USB mouse and such an
attempt would cause problems with the USB mouse. The only possible solution
here would be for the ws driver to positively identify the touch screen via
an IOCTL (WSMOUSE_TYPE_TPANEL is feasible) and to then recalculate the
scaling factor. This is messy since the scaling factor is already applied to
the co-ordinates by the zts driver and would require the ws driver to work
back and re-apply the scaling factor to the rotated co-ordinates that it
sends.
>
> My proposal for solution is as follows (I may fix this but I want to get
feedback before starting)..
>
> i. Implement an IOCTL on zts to switch scaling behaviour based upon a
provided screen orientation, this may suit the purposes of developers
wishing to use touch screen orientation independently of X.
>
> ii. Modify the ws driver to check the IOCTL on each mouse driver to see if
this extension exists, if it does exist then it will use this extension to
program the IOCTL to modify its scaling behaviour for landscape or portrait
so that co-ordinates returned are scaled correctly for visual transformation
by drivers such as wsfb.
>
> Common objections may be..
>
> a. This is adding a non standard IOCTL to a common driver type.
> b. It's an X issue so changes shouldn't effect the kernel. - could benefit
non X software though.
>
> Please let me know what you think about the suitability of this as a
solution or any other possible suitable solutions.
>
> - Andy

The X.Org people are currently desining a new extension to make it
possible to pass arbitrarly key/value configuration dynamically to
existing drivers (especially input drivers) to solve on-line
calibration, rotation and other similar issues. Once it's done, the ws
input driver will be able to take advantage of it.

And may be in the mean time we'll have a working randr support for wsfb
too.

--
Matthieu Herrb

[demime 1.01d removed an attachment of type application/x-pkcs7-signature
which had a name of smime.p7s]