---
 Xi/chgdctl.c                   |   55 +++++++++++++++++++------
 Xi/getdctl.c                   |   87 +++++++++++++++++++++++++++++++----------
 Xi/getdctl.h                   |   11 +++--
 Xi/stubs.c                     |    2 
 configure.ac                   |    2 
 dix/devices.c                  |   31 +++++++++-----
 hw/kdrive/linux/tslib.c        |    8 +--
 hw/kdrive/src/kinput.c         |    6 +-
 hw/xfree86/common/xf86Xinput.c |    3 -
 include/input.h                |    2 
 include/inputstr.h             |   18 +++++++-
 11 files changed, 162 insertions(+), 63 deletions(-)

Index: xorg-server-1.1.99.3/Xi/chgdctl.c
===================================================================
--- xorg-server-1.1.99.3.orig/Xi/chgdctl.c	2007-01-29 22:58:18.000000000 +0000
+++ xorg-server-1.1.99.3/Xi/chgdctl.c	2007-01-29 22:59:27.000000000 +0000
@@ -104,8 +104,10 @@ ProcXChangeDeviceControl(ClientPtr clien
     xChangeDeviceControlReply rep;
     AxisInfoPtr a;
     CARD32 *resolution;
-    xDeviceTSCtl *ts;
+    xDeviceAbsCalibCtl *calib;
+    xDeviceAbsAreaCtl *area;
     xDeviceCoreCtl *c;
+    xDeviceEnableCtl *e;
 
     REQUEST(xChangeDeviceControlReq);
     REQUEST_AT_LEAST_SIZE(xChangeDeviceControlReq);
@@ -170,25 +172,28 @@ ProcXChangeDeviceControl(ClientPtr clien
 	    return Success;
 	}
 	break;
-    case DEVICE_TOUCHSCREEN:
-        ts = (xDeviceTSCtl *)&stuff[1];
-
-        if (ts->button_threshold < 0 || ts->button_threshold > 255) {
+    case DEVICE_ABS_CALIB:
+        calib = (xDeviceAbsCalibCtl *)&stuff[1];
+ 
+        if (calib->button_threshold < 0 || calib->button_threshold > 255) {
             SendErrorToClient(client, IReqCode, X_ChangeDeviceControl, 0,
                               BadValue);
             return Success;
         }
 
-        status = ChangeDeviceControl(client, dev, (xDeviceCtl *) ts);
+        status = ChangeDeviceControl(client, dev, (xDeviceCtl *) calib);
 
         if (status == Success) {
-            dev->touchscreen->min_x = ts->min_x;
-            dev->touchscreen->max_x = ts->max_x;
-            dev->touchscreen->min_y = ts->min_y;
-            dev->touchscreen->max_y = ts->max_y;
-            dev->touchscreen->button_threshold = ts->button_threshold;
-        } else if (status == DeviceBusy) {
-            rep.status = DeviceBusy;
+            dev->absolute->min_x = calib->min_x;
+            dev->absolute->max_x = calib->max_x;
+            dev->absolute->min_y = calib->min_y;
+            dev->absolute->max_y = calib->max_y;
+            dev->absolute->flip_x = calib->flip_x;
+            dev->absolute->flip_y = calib->flip_y;
+            dev->absolute->rotation = calib->rotation;
+            dev->absolute->button_threshold = calib->button_threshold;
+        } else if (status == DeviceBusy || status == BadValue) {
+            rep.status = status;
             WriteReplyToClient(client, sizeof(xChangeDeviceControlReply),
                                &rep);
             return Success;
@@ -199,6 +204,30 @@ ProcXChangeDeviceControl(ClientPtr clien
         }
 
         break;
+    case DEVICE_ABS_AREA:
+        area = (xDeviceAbsAreaCtl *)&stuff[1];
+
+        status = ChangeDeviceControl(client, dev, (xDeviceCtl *) area);
+
+        if (status == Success) {
+            dev->absolute->offset_x = area->offset_x;
+            dev->absolute->offset_y = area->offset_y;
+            dev->absolute->width = area->width;
+            dev->absolute->height = area->height;
+            dev->absolute->screen = area->screen;
+            dev->absolute->following = area->following;
+        } else if (status == DeviceBusy || status == BadValue) {
+            rep.status = status;
+            WriteReplyToClient(client, sizeof(xChangeDeviceControlReply),
+                                     &rep);
+            return Success;
+        } else {
+            SendErrorToClient(client, IReqCode, X_ChangeDeviceControl, 0,
+                              BadMatch);
+            return Success;
+        }
+
+        break;	
     case DEVICE_CORE:
         c = (xDeviceCoreCtl *)&stuff[1];
 
Index: xorg-server-1.1.99.3/Xi/getdctl.c
===================================================================
--- xorg-server-1.1.99.3.orig/Xi/getdctl.c	2007-01-29 22:58:18.000000000 +0000
+++ xorg-server-1.1.99.3/Xi/getdctl.c	2007-01-29 22:59:27.000000000 +0000
@@ -124,14 +124,23 @@ ProcXGetDeviceControl(ClientPtr client)
 	total_length = sizeof(xDeviceResolutionState) +
 	    (3 * sizeof(int) * dev->valuator->numAxes);
 	break;
-    case DEVICE_TOUCHSCREEN:
-        if (!dev->touchscreen) {
+    case DEVICE_ABS_CALIB:
+        if (!dev->absolute) {
             SendErrorToClient(client, IReqCode, X_GetDeviceControl, 0,
                               BadMatch);
             return Success;
         }
 
-        total_length = sizeof(xDeviceTSCtl);
+        total_length = sizeof(xDeviceAbsCalibCtl);
+        break;
+    case DEVICE_ABS_AREA:
+        if (!dev->absolute) {
+            SendErrorToClient(client, IReqCode, X_GetDeviceControl, 0,
+                              BadMatch);
+            return Success;
+        }
+
+        total_length = sizeof(xDeviceAbsAreaCtl);
         break;
     case DEVICE_CORE:
         total_length = sizeof(xDeviceCoreCtl);
@@ -152,8 +161,11 @@ ProcXGetDeviceControl(ClientPtr client)
     case DEVICE_RESOLUTION:
 	CopySwapDeviceResolution(client, dev->valuator, buf, total_length);
 	break;
-    case DEVICE_TOUCHSCREEN:
-        CopySwapDeviceTouchscreen(client, dev->touchscreen, buf);
+    case DEVICE_ABS_CALIB:
+        CopySwapDeviceAbsCalib(client, dev->absolute, buf);
+        break;
+    case DEVICE_ABS_AREA:
+        CopySwapDeviceAbsArea(client, dev->absolute, buf);
         break;
     case DEVICE_CORE:
         CopySwapDeviceCore(client, dev, buf);
@@ -206,28 +218,61 @@ CopySwapDeviceResolution(ClientPtr clien
     }
 }
 
-void CopySwapDeviceTouchscreen (ClientPtr client, TouchscreenClassPtr dts,
+void CopySwapDeviceAbsCalib (ClientPtr client, AbsoluteClassPtr dts,
                                 char *buf)
 {
     register char n;
-    xDeviceTSState *ts = (xDeviceTSState *) buf;
+    xDeviceAbsCalibState *calib = (xDeviceAbsCalibState *) buf;
 
-    ts->control = DEVICE_TOUCHSCREEN;
-    ts->length = sizeof(ts);
-    ts->min_x = dts->min_x;
-    ts->max_x = dts->max_x;
-    ts->min_y = dts->min_y;
-    ts->max_y = dts->max_y;
-    ts->button_threshold = dts->button_threshold;
+    calib->control = DEVICE_ABS_CALIB;
+    calib->length = sizeof(calib);
+    calib->min_x = dts->min_x;
+    calib->max_x = dts->max_x;
+    calib->min_y = dts->min_y;
+    calib->max_y = dts->max_y;
+    calib->flip_x = dts->flip_x;
+    calib->flip_y = dts->flip_y;
+    calib->rotation = dts->rotation;
+    calib->button_threshold = dts->button_threshold;
 
     if (client->swapped) {
-        swaps(&ts->control, n);
-        swaps(&ts->length, n);
-        swapl(&ts->min_x, n);
-        swapl(&ts->max_x, n);
-        swapl(&ts->min_y, n);
-        swapl(&ts->max_y, n);
-        swapl(&ts->button_threshold, n);
+        swaps(&calib->control, n);
+        swaps(&calib->length, n);
+        swapl(&calib->min_x, n);
+        swapl(&calib->max_x, n);
+        swapl(&calib->min_y, n);
+        swapl(&calib->max_y, n);
+        swapl(&calib->flip_x, n);
+        swapl(&calib->flip_y, n);
+        swapl(&calib->rotation, n);
+        swapl(&calib->button_threshold, n);
+    }
+}
+
+void CopySwapDeviceAbsArea (ClientPtr client, AbsoluteClassPtr dts,
+                                 char *buf)
+{
+    register char n;
+    xDeviceAbsAreaState *area = (xDeviceAbsAreaState *) buf;
+
+    area->control = DEVICE_ABS_AREA;
+    area->length = sizeof(area);
+    area->offset_x = dts->offset_x;
+    area->offset_y = dts->offset_y;
+    area->width = dts->width;
+    area->height = dts->height;
+    area->screen = dts->screen;
+    area->following = dts->following;
+
+    if (client->swapped) {
+        swaps(&area->control, n);
+        swaps(&area->length, n);
+        swapl(&area->offset_x, n);
+        swapl(&area->offset_y, n);
+        swapl(&area->width, n);
+        swapl(&area->height, n);
+        swapl(&area->screen, n);
+        swapl(&area->following, n);
     }
 }
 
Index: xorg-server-1.1.99.3/Xi/getdctl.h
===================================================================
--- xorg-server-1.1.99.3.orig/Xi/getdctl.h	2007-01-29 22:58:18.000000000 +0000
+++ xorg-server-1.1.99.3/Xi/getdctl.h	2007-01-29 22:59:27.000000000 +0000
@@ -42,10 +42,13 @@ void CopySwapDeviceResolution(ClientPtr 
 			      int	/* length */
     );
 
-void CopySwapDeviceTouchscreen(ClientPtr /* client */ ,
-                               TouchscreenClassPtr /* ts */ ,
-                               char * /* buf */
-    );
+void CopySwapDeviceAbsCalib (ClientPtr client,
+                             AbsoluteClassPtr dts,
+                             char *buf);
+
+void CopySwapDeviceAbsArea (ClientPtr client,
+                            AbsoluteClassPtr dts,
+                            char *buf);
 
 void CopySwapDeviceCore(ClientPtr /* client */ ,
                         DeviceIntPtr /* dev */ ,
Index: xorg-server-1.1.99.3/Xi/stubs.c
===================================================================
--- xorg-server-1.1.99.3.orig/Xi/stubs.c	2007-01-29 22:58:18.000000000 +0000
+++ xorg-server-1.1.99.3/Xi/stubs.c	2007-01-29 22:59:27.000000000 +0000
@@ -287,7 +287,7 @@ ChangeDeviceControl(register ClientPtr c
     switch (control->control) {
     case DEVICE_RESOLUTION:
 	return (BadMatch);
-    case DEVICE_TOUCHSCREEN:
+    case DEVICE_ABS_CALIB:
         return (BadMatch);
     case DEVICE_CORE:
         return (BadMatch);
Index: xorg-server-1.1.99.3/dix/devices.c
===================================================================
--- xorg-server-1.1.99.3.orig/dix/devices.c	2007-01-29 22:58:18.000000000 +0000
+++ xorg-server-1.1.99.3/dix/devices.c	2007-01-29 22:59:27.000000000 +0000
@@ -117,7 +117,7 @@ AddInputDevice(DeviceProc deviceProc, Bo
     dev->button = (ButtonClassPtr)NULL;
     dev->focus = (FocusClassPtr)NULL;
     dev->proximity = (ProximityClassPtr)NULL;
-    dev->touchscreen = (TouchscreenClassPtr)NULL;
+    dev->absolute = (AbsoluteClassPtr)NULL;
     dev->kbdfeed = (KbdFeedbackPtr)NULL;
     dev->ptrfeed = (PtrFeedbackPtr)NULL;
     dev->intfeed = (IntegerFeedbackPtr)NULL;
@@ -821,22 +821,31 @@ InitValuatorClassDeviceStruct(DeviceIntP
 }
 
 _X_EXPORT Bool
-InitTouchscreenClassDeviceStruct(DeviceIntPtr dev)
+InitAbsoluteClassDeviceStruct(DeviceIntPtr dev)
 {
-    register TouchscreenClassPtr tsc;
+    register AbsoluteClassPtr abs;
 
-    tsc = (TouchscreenClassPtr)xalloc(sizeof(TouchscreenClassRec));
-    if (!tsc)
+    abs = (AbsoluteClassPtr)xalloc(sizeof(AbsoluteClassRec));
+    if (!abs)
         return FALSE;
 
     /* we don't do anything sensible with these, but should */
-    tsc->min_x = -1;
-    tsc->min_y = -1;
-    tsc->max_x = -1;
-    tsc->max_y = -1;
+    abs->min_x = -1;
+    abs->min_y = -1;
+    abs->max_x = -1;
+    abs->max_y = -1;
+    abs->flip_x = 0;
+    abs->flip_y = 0;
+    abs->rotation = 0;
+    abs->button_threshold = 0;
 
-    tsc->button_threshold = 0;
-    dev->touchscreen = tsc;
+    abs->offset_x = 0;
+    abs->offset_y = 0;
+    abs->width = -1;
+    abs->height = -1;
+    abs->following = 0;
+
+    dev->absolute = abs;
 
     return TRUE;
 }
Index: xorg-server-1.1.99.3/hw/xfree86/common/xf86Xinput.c
===================================================================
--- xorg-server-1.1.99.3.orig/hw/xfree86/common/xf86Xinput.c	2007-01-29 22:58:18.000000000 +0000
+++ xorg-server-1.1.99.3/hw/xfree86/common/xf86Xinput.c	2007-01-29 22:59:27.000000000 +0000
@@ -538,7 +538,8 @@ ChangeDeviceControl (ClientPtr client, D
       switch (control->control) {
       case DEVICE_CORE:
       case DEVICE_RESOLUTION:
-      case DEVICE_TOUCHSCREEN:
+      case DEVICE_ABS_CALIB:
+      case DEVICE_ABS_AREA:
         return Success;
       default:
         return BadMatch;
Index: xorg-server-1.1.99.3/include/input.h
===================================================================
--- xorg-server-1.1.99.3.orig/include/input.h	2007-01-29 22:58:18.000000000 +0000
+++ xorg-server-1.1.99.3/include/input.h	2007-01-29 22:59:27.000000000 +0000
@@ -238,7 +238,7 @@ extern Bool InitValuatorClassDeviceStruc
     int /*numMotionEvents*/,
     int /*mode*/);
 
-extern Bool InitTouchscreenClassDeviceStruct(
+extern Bool InitAbsoluteClassDeviceStruct(
     DeviceIntPtr /*device*/);
 
 extern Bool InitFocusClassDeviceStruct(
Index: xorg-server-1.1.99.3/include/inputstr.h
===================================================================
--- xorg-server-1.1.99.3.orig/include/inputstr.h	2007-01-29 22:58:18.000000000 +0000
+++ xorg-server-1.1.99.3/include/inputstr.h	2007-01-29 22:59:27.000000000 +0000
@@ -185,13 +185,25 @@ typedef struct _ProximityClassRec {
     char	pad;
 } ProximityClassRec, *ProximityClassPtr;
 
-typedef struct _TouchscreenClassRec {
+typedef struct _AbsoluteClassRec {
+    /* Calibration. */
     int         min_x;
     int         max_x;
     int         min_y;
     int         max_y;
+    int         flip_x;
+    int         flip_y;
+    int		rotation;
     int         button_threshold;
-} TouchscreenClassRec, *TouchscreenClassPtr;
+
+    /* Area. */
+    int         offset_x;
+    int         offset_y;
+    int         width;
+    int         height;
+    int         screen;
+    XID		following;
+} AbsoluteClassRec, *AbsoluteClassPtr;
 
 typedef struct _KbdFeedbackClassRec *KbdFeedbackPtr;
 typedef struct _PtrFeedbackClassRec *PtrFeedbackPtr;
@@ -293,7 +305,7 @@ typedef struct _DeviceIntRec {
     ButtonClassPtr	button;
     FocusClassPtr	focus;
     ProximityClassPtr	proximity;
-    TouchscreenClassPtr touchscreen;
+    AbsoluteClassPtr    absolute;
     KbdFeedbackPtr	kbdfeed;
     PtrFeedbackPtr	ptrfeed;
     IntegerFeedbackPtr	intfeed;
Index: xorg-server-1.1.99.3/configure.ac
===================================================================
--- xorg-server-1.1.99.3.orig/configure.ac	2007-01-29 22:58:18.000000000 +0000
+++ xorg-server-1.1.99.3/configure.ac	2007-01-29 22:59:27.000000000 +0000
@@ -1586,7 +1586,7 @@ if test "$KDRIVE" = yes; then
     #KDRIVE_PURE_LIBS="$DIX_LIB $OS_LIB $FB_LIB $XEXT_LIB $MIEXT_DAMAGE_LIB \
     #    $MIEXT_SHADOW_LIB $XPSTUBS_LIB"
     KDRIVE_XKB_DDX_LIB='$(top_builddir)/hw/kdrive/src/libkdrivexkb.a'
-    KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $KDRIVE_XKB_DDX_LIB $XKB_LIB $KDRIVE_XKB_DDX_LIB$COMPOSITE_LIB $XPSTUBS_LIB $OS_LIB $CONFIG_LIB"
+    KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $KDRIVE_XKB_DDX_LIB $XKB_LIB $KDRIVE_XKB_DDX_LIB $COMPOSITE_LIB $XPSTUBS_LIB $OS_LIB $CONFIG_LIB"
     KDRIVE_LIB='$(top_builddir)/hw/kdrive/src/libkdrive.a'
     KDRIVE_OS_LIB='$(top_builddir)/hw/kdrive/linux/liblinux.a'
     KDRIVE_STUB_LIB='$(top_builddir)/hw/kdrive/src/libkdrivestubs.a'
Index: xorg-server-1.1.99.3/hw/kdrive/linux/tslib.c
===================================================================
--- xorg-server-1.1.99.3.orig/hw/kdrive/linux/tslib.c	2007-01-29 22:58:18.000000000 +0000
+++ xorg-server-1.1.99.3/hw/kdrive/linux/tslib.c	2007-01-29 22:59:27.000000000 +0000
@@ -94,7 +94,7 @@ TsRead (int fd, void *closure)
                event.pressure);
         discard = 0;
         if (event.pressure) {
-            if (event.pressure > pi->dixdev->touchscreen->button_threshold) 
+            if (event.pressure > pi->dixdev->absolute->button_threshold) 
                 flags = KD_BUTTON_8;
             else
                 flags = KD_BUTTON_1;
@@ -356,9 +356,9 @@ TslibEnable (KdPointerInfo *pi)
             close(private->fd);
         return BadAlloc;
     }
-    if (pi->dixdev && pi->dixdev->touchscreen &&
-        pi->dixdev->touchscreen->button_threshold == 0)
-        pi->dixdev->touchscreen->button_threshold = 115;
+    if (pi->dixdev && pi->dixdev->absolute &&
+        pi->dixdev->absolute->button_threshold == 0)
+        pi->dixdev->absolute->button_threshold = 115;
 
     DebugF("[tslib/TslibEnable] successfully enabled %s\n", pi->path);
     KdRegisterFd(private->fd, TsRead, pi);
Index: xorg-server-1.1.99.3/hw/kdrive/src/kinput.c
===================================================================
--- xorg-server-1.1.99.3.orig/hw/kdrive/src/kinput.c	2007-01-29 22:58:18.000000000 +0000
+++ xorg-server-1.1.99.3/hw/kdrive/src/kinput.c	2007-01-29 22:59:27.000000000 +0000
@@ -444,7 +444,7 @@ KdPointerProc(DeviceIntPtr pDevice, int 
 
 #ifdef XINPUT
         if (pi->inputClass == KD_TOUCHSCREEN) {
-            InitTouchscreenClassDeviceStruct(pDevice);
+            InitAbsoluteClassDeviceStruct(pDevice);
             xiclass = AtomFromName(XI_TOUCHSCREEN);
         }
         else {
@@ -2323,8 +2323,8 @@ ChangeDeviceControl(register ClientPtr c
         /* FIXME do something more intelligent here */
         return BadMatch;
 
-    case DEVICE_TOUCHSCREEN:
-        if (!pDev->touchscreen)
+    case DEVICE_ABS_CALIB:
+        if (!pDev->absolute)
             return BadDevice;
         else
             return Success;