Version:
0.2 (draft)
Last Updated:
17-July-2000
A generic Touch Screen major and
minor numbers to be registered according to the procedure documented in ../linux/Documentation/devices.txt.
New registrations are to be sent to the address device@lanana.org.
A major number 10 seems the most likely candidate at this stage (TBD).
In some applications high (sub-pixel) resolution may be required from the device driver for graphical tasks such as drawing (digital ink) and/or hand writing recognition (HWR). In other applications lower (pixel) resolution may be required for core pointer control of menus and other applications. In many applications, however, it is desirable to do both at once.
To achieve this goal in X, several extensions have been added to the X Input support in XFree86 they are currently under investigation for use with this driver. (See the Owen Taylor link below).
From the driver point of view the high (sub-pixel) resolution data are passed to it’s client via the user space and kernel read() functions . The client of the driver will be able to convert to pixel resolution, if required, by using the previously saved affine transform parameters x[y]scale and x[y]trans. (see the Calibration section below).
/dev/ts
This is the device name used to return “raw” sub-pixel resolution coordinates from the digitizer. (Note 3)
typedef struct {
short pressure; /* Note 1 */
int x;
int y;
#if
1
int millisecs;
/* milliseconds time stamp */
#else
struct timeval timestamp; /* microsecs
resolution ? */
#endif
} TS_EVENT;
This structure is generated by the driver module and passed to the user space by the _read() file operation. It is received by the user space read()function.
Each event has it’s own time stamp which may be used to measure pen velocity and/or serialize events from different devices. It is still debatable whether we use microsecond resolution or millisecond resolution. For maximum accuracy the time stamp is created by the interrupt service routine in the kernel.
Pressure indicates a pen up or pen down event. The Cartesian coordinates (x and y) (Note 2) indicate the position of a pen down event. Cartesian coordinates have no meaning for a pen up event.
Although the event is shown in TS_EVENT consist of a simple set of cartesian coordinates and a pressure attribute, work is still under way investigating a more general case which would cater for more sophisticated digitizers such as the range of Wacom tablets. These devices have typically more than one pen type – each pen type having it’s own attributes. For example the Wacom can have three pen types (pen,puck or airbrush) with the airbrush, alone, requiring five parameters - x, y, z(distance from paper),air_volume and paint_volume. In addition to pen types there maybe pen colours, sylus angle etc to worry about.
Owen Taylor’s web site at:
http://www.gtk.org/~otaylor/index.html
describes work already been done for Watcom Artpad II devices using GMIP (Gnu Image Manipulation Program),GTK+ (Gmip Tool Kit) and the X Input extension
In addition to open(), close() and ioctl() functions, blocking and non-blocking read() and asynchronous notification (SIGIO) should be supported at the user level. The select/poll mechanism will also be supported.
_read()
Blocking reads will block until a TS_EVENT structure (see below) can be returned.
_fasync()
SIGIO to user when there is an event to report. An event is defined as reception of a complete TS_EVENT structure.
_poll()
If there are 1 or more TS_EVENT structures to be read then this function will return the (POLLIN | POLLRDNORM) flags otherwise a zero will be returned.
_ioctl()
The list of ioctls will depend on the hardware used to implement the touch screen (example UCB1200). Initialisation ioctls will be called by the driver’s init_module() or equivalent.
The ioctl command numbers should be
‘mangled’ using the _IO,_IOW,_IOR,_IOWR macros as
defined in <linux/ioctl.h>
A ‘magic number’ of ‘t’ should be used (see CALIBRATION section)
#define IOC_MAGIC ‘t’
See the calibration section for
ioctl usage.
The following example code can be found in the ../apps/h3600_test directory on the http://www.handhelds.org/ CVS tree.
ts_poll.c
example of a non-blocking read using the poll/select mechanism.
ts_read.c
example of a blocking read.
fasynctst.c
example of how asynchronous notifications are handled in user space.
The Compaq iPAQ touch screen driver (h3650_ts.c) implements the above file operations and can be found in the ../drivers/char directory in the http://www.handhelds.org/ CVS tree.
It was has been stated that “most” devices will work with a single affine (linear) transform. This section describes the calibration technique used by Itsy and the Compaq iPAQ which uses an affine transform with zero shear and rotation. (Q: If this is an affine transform then will shear and rotation be necessary?)
For a good introduction to the affine transform see
http://gamelan.earthweb.com/javaprogramming/baldwin/new/030700_J306.html#_What_is_an
The affine matrix (calibration parameters x/yscale and x/ytrans) are calculated by a separate calibration application (note 4). It assumes zero shear and rotation.
Xcal = (xscale * Xraw) +
xtrans
Ycal = (yscale * Yraw) +
ytrans
Xcal and Ycal are the (pixel resolution) Cartesian coordinates.
Xraw and Yraw are the high (sub-pixel resolution) Cartesian coordinates.
Xscale and Yscale are the scaling factor
Xtrans and Ytrans are the translation.factor.
For increased accuracy xscale and yscale are multiplied by 256 and stored in the TS_CAL structure in the driver.
Xscale = xscale <<
8
Yscale = yscale <<
8
During conversion from Xraw to Xcal the reverse transformation is required.
Xcal = ( (Xscale * Xraw) >> 8 ) +
xtrans
Ycal = ( (Yscale * Yraw) >> 8 ) +
ytrans
The affine transform matrix (calibration information) is held in the TS_CAL structure. It is stored in the driver using the TS_SET_CALIBRATE ioctl.
Applications requiring sub-pixel to pixel transformations can retrieve the matrix in structure TS_CAL using the TS_GET_CALIBRATE ioctls.
#define TS_SET_CALIBRATE
_IOW(IOC_MAGIC,0,TS_CAL);
#define TS_GET_CALIBRATE
_IOW(IOC_MAGIC,1,TS_CAL);
The TS_CAL structure is used to convert high (sub-pixel) resolution coordinates (Xraw and Yraw) to pixel coordinates (Xcal and Ycal) suitable for core pointer control of menus and other applications.
typedef struct {
int Xscale; /* Xscale =
xscale << 8 */
int xtrans;
int Yscale; /* Yscale =
yscale << 8 */
int ytrans;
} TS_CAL;
The H3600 calibration application can be found in ../apps/calibrate.c. This code is extensively commented and will explain how the Itsy calibration application works. Note is uses a device called /dev/h3600_tsraw to get raw data.