diff -u mouse.c.orig mouse.c
--- mouse.c.orig	2009-04-15 23:01:33.000000000 -0400
+++ mouse.c	2009-04-15 22:58:39.000000000 -0400
@@ -134,6 +134,7 @@
 static Bool MouseConvert(LocalDevicePtr local, int first, int num, int v0,
 		 	     int v1, int v2, int v3, int v4, int v5, int *x,
 		 	     int *y);
+static int MouseControl(InputInfoPtr pInfo, xDeviceCtl * control);
 
 static void MouseCtrl(DeviceIntPtr device, PtrCtrl *ctrl);
 static void MousePostEvent(InputInfoPtr pInfo, int buttons,
@@ -207,6 +208,11 @@
     OPTION_FLOW_CONTROL,
     OPTION_VTIME,
     OPTION_VMIN,
+    OPTION_MINX,
+    OPTION_MAXX,
+    OPTION_MINY,
+    OPTION_MAXY,
+    OPTION_ROTATE,
     OPTION_DRAGLOCKBUTTONS,
     OPTION_DOUBLECLICK_BUTTONS,
     OPTION_BUTTON_MAPPING,
@@ -250,6 +256,13 @@
     { OPTION_VTIME,		"VTime",	  OPTV_INTEGER,	{0}, FALSE },
     { OPTION_VMIN,		"VMin",		  OPTV_INTEGER,	{0}, FALSE },
     /* end serial options */
+    /* touchscreen options */
+    { OPTION_MINX,             "MinX",           OPTV_INTEGER, {0}, FALSE },
+    { OPTION_MAXX,             "MaxX",           OPTV_INTEGER, {0}, FALSE },
+    { OPTION_MINY,             "MinY",           OPTV_INTEGER, {0}, FALSE },
+    { OPTION_MAXY,             "MaxY",           OPTV_INTEGER, {0}, FALSE },
+    { OPTION_ROTATE,           "Rotate",         OPTV_STRING,  {0}, FALSE },
+    /* end touchscreen options */
     { OPTION_DRAGLOCKBUTTONS,	"DragLockButtons",OPTV_STRING,	{0}, FALSE },
     { OPTION_DOUBLECLICK_BUTTONS,"DoubleClickButtons", OPTV_STRING, {0}, FALSE },
     { OPTION_BUTTON_MAPPING,   "ButtonMapping",   OPTV_STRING,  {0}, FALSE },
@@ -948,6 +961,7 @@
 static InputInfoPtr
 MousePreInit(InputDriverPtr drv, IDevPtr dev, int flags)
 {
+    char *s;
     InputInfoPtr pInfo;
     MouseDevPtr pMse;
     mousePrivPtr mPriv;
@@ -975,7 +989,7 @@
     pInfo->motion_history_proc = xf86GetMotionEvents;
     pInfo->history_size = 0;
 #endif
-    pInfo->control_proc = NULL;
+    pInfo->control_proc = MouseControl;
     pInfo->close_proc = NULL;
     pInfo->switch_mode = NULL;
     pInfo->conversion_proc = MouseConvert;
@@ -1134,7 +1148,22 @@
     
     MouseHWOptions(pInfo);
     MouseSerialOptions(pInfo);
-    
+
+    s = xf86SetStrOption(pInfo->options, "Rotate", NULL);
+    if (s) {
+       if (!xf86NameCmp(s, "CW")) {
+            mPriv->rotate = 1;
+       }else if (!xf86NameCmp(s, "CCW")) {
+            mPriv->rotate = -1;
+       }else{
+            mPriv->rotate = 0;
+        }
+    }
+    mPriv->min_x = xf86SetIntOption(pInfo->options, "MinX", 0);
+    mPriv->max_x = xf86SetIntOption(pInfo->options, "MaxX", 1023);
+    mPriv->min_y = xf86SetIntOption(pInfo->options, "MinY", 0);
+    mPriv->max_y = xf86SetIntOption(pInfo->options, "MaxY", 1023);
+
     pInfo->flags |= XI86_CONFIGURED;
     return pInfo;
 }
@@ -1148,7 +1177,7 @@
     int pBufP;
     int c;
     unsigned char *pBuf, u;
-
+    MouseProtocolID tmpProto;
 
     pMse = pInfo->private;
     pBufP = pMse->protoBufTail;
@@ -1389,7 +1418,50 @@
 	 */
     REDO_INTERPRET:
 	dz = dw = 0;
-	switch (pMse->protocolID) {
+       /* The ScreenCoder operates in two modes.  In the first
+          mode, it injects relative motion packets along with
+          packets from an external pointer device.  The format of
+          packets from both sources is identical.  In the second
+          mode, the injected packets represent absolute position.
+          In that case, the external pointer device packets are
+          guaranteed (by reformatting) to have bit 3 of byte 0 set.
+          This block looks for, and processes absolute position
+          packets, while passing relative motion packets along
+          for processing as PS/2, IMPS/2 or EXPPS/2 packets, i.e.,
+          this block of code picks off the absolute position
+          packets from the data stream. [RAB-2002/04/25] */
+       tmpProto = pMse->protocolID;
+       switch (tmpProto) {
+       case PROT_PS2:
+           if (pBuf[0] & 0x08){
+               /* it belongs to the external pointer */
+               tmpProto = PROT_PS2;
+               break;
+           }
+       /* fall through to common code which deals with
+        * absolute positioning information */
+           if ((pBuf[0] & 0x03) == 0x03){
+               buttons = 0;
+           }else if ((pBuf[0] & 0x03) == 0x00){
+               buttons = 0x04;
+           }else{
+               buttons = 0;
+           }
+           dx = ((pBuf[0] & 0x30)<<4) + pBuf[1];
+           dy = ((pBuf[0] & 0xC0)<<2) + pBuf[2];
+           /* dz is ignored in absolute mode */
+            /* this flags dx and dy as absolute position */
+           buttons |= MSE_ABSOLUTE_POSN;
+           tmpProto = 0xFFFFFFFF; // skip
+           break;
+       default:
+           break;
+       }
+
+       switch (tmpProto) {
+       case 0xFFFFFFFF: // skip
+         break;
+
 	case PROT_LOGIMAN:	/* MouseMan / TrackMan   [CHRIS-211092] */
 	case PROT_MS:		/* Microsoft */
 	    if (pMse->chordMiddle)
@@ -1671,6 +1743,27 @@
     pMse->threshold = ctrl->threshold;
 }
 
+static int
+MouseControl(InputInfoPtr pInfo, xDeviceCtl * control)
+{
+    MouseDevPtr pMse;
+    mousePrivPtr mPriv;
+    xDeviceAbsCalibCtl *c;
+
+        pMse = pInfo->private;
+       mPriv = (mousePrivPtr)pMse->mousePriv;
+        c = (xDeviceAbsCalibCtl *) control;
+
+       mPriv->min_x = c->min_x;
+       mPriv->max_x = c->max_x;
+       mPriv->min_y = c->min_y;
+       mPriv->max_y = c->max_y;
+       return (Success);
+} /* [RAB - 2002/04/25] */
+
+
+
+
 /*
  ***************************************************************************
  *
@@ -2228,8 +2321,14 @@
     if (pMse->emulate3ButtonsSoft && pMse->emulate3Pending && (dx || dy))
 	buttonTimer(pInfo);
 
-    if (dx || dy)
-	xf86PostMotionEvent(pInfo->dev, 0, 0, 2, dx, dy);
+    if (buttons & MSE_ABSOLUTE_POSN){
+       xf86PostMotionEvent(pInfo->dev, 1, 0, 2, dx, dy);
+       buttons &= ~MSE_ABSOLUTE_POSN;
+    }else{
+       if (dx || dy)
+           xf86PostMotionEvent(pInfo->dev, 0, 0, 2, dx, dy);
+    }
+
 
     if (change) {
 
@@ -2428,14 +2527,48 @@
 	dy = (int)((dy * cos(rad)) - (ndx * sin(rad)) + 0.5);
     }
 
-    dx = pMse->invX * dx;
-    dy = pMse->invY * dy;
-    if (pMse->flipXY) {
-	int tmp = dx;
-	dx = dy;
-	dy = tmp;
+    if (truebuttons & MSE_ABSOLUTE_POSN){ /* [RAB - 2002/04/25] */
+	buttons |= MSE_ABSOLUTE_POSN;
+    
+      int scaled_x,scaled_y;
+       /*******************************************
+       The use of mousepriv->rotate allows absolute positioning
+       to be rotated here, but defers rotation of relative
+       positioning to the screen driver (since that seems to
+       be where it's done in at least the SiS driver).
+
+       Note: The xf86ScaleAxis function could have been used here,
+       but we can fold inversion and the flip operation into our
+       logic better without using this function.
+       *******************************************/
+       #define SCALE 10000
+        scaled_x = (SCALE * (dx - mousepriv->min_x)) / mousepriv->max_x;
+        scaled_y = (SCALE * (dy - mousepriv->min_y)) / mousepriv->max_y;
+       if (pMse->invX < 0 || mousepriv->rotate == 1){
+            scaled_x = SCALE - scaled_x;
+        }
+       if (pMse->invY < 0 || mousepriv->rotate == -1){
+            scaled_y = SCALE - scaled_y;
+        }
+       if (pMse->flipXY || mousepriv->rotate ) {
+           dx = scaled_y * screenInfo.screens[0]->width / SCALE;
+           dy = scaled_x * screenInfo.screens[0]->height / SCALE;
+       }else{
+           dx = scaled_x * screenInfo.screens[0]->width / SCALE;
+           dy = scaled_y * screenInfo.screens[0]->height / SCALE;
+       }
+    }else{
+       dx = pMse->invX * dx;
+       dy = pMse->invY * dy;
+
+       if (pMse->flipXY) {
+           int tmp = dx;
+           dx = dy;
+           dy = tmp;
+       }
     }
 
+
     /* Accumulate the scaled dx, dy in the private variables 
        fracdx,fracdy and return the integer number part */
     if (mousepriv) {
@@ -2485,7 +2618,7 @@
   {  0x80, 0x80, 0x80, 0x00,  3,   0x00, 0xff, MPF_NONE },  /* ACECAD */
   {  0x40, 0x40, 0x40, 0x00,  4,   0x00, 0xff, MPF_NONE },  /* ValuMouseScroll */
 							    /* PS/2 variants */
-  {  0xc0, 0x00, 0x00, 0x00,  3,   0x00, 0xff, MPF_NONE },  /* PS/2 mouse */
+  {  0x00, 0x00, 0x00, 0x00,  3,   0x00, 0xff, MPF_NONE },  /* PS/2 mouse */
   {  0xc8, 0x08, 0x00, 0x00,  3,   0x00, 0x00, MPF_NONE },  /* genericPS/2 mouse*/
   {  0x08, 0x08, 0x00, 0x00,  4,   0x00, 0xff, MPF_NONE },  /* IntelliMouse */
   {  0x08, 0x08, 0x00, 0x00,  4,   0x00, 0xff, MPF_NONE },  /* Explorer */
@@ -2821,7 +2954,12 @@
 
 	case PROT_PS2:
 	case PROT_GLIDEPS2:
-	    break;
+	{
+	    static unsigned char seq[] = { 243, 80, 243, 60, 243, 100 };
+            param = seq;
+            paramlen = sizeof(seq);
+	}
+	break;
 	
 	case PROT_IMPS2:		/* IntelliMouse */
 	{
diff -u mousePriv.h.orig mousePriv.h
--- mousePriv.h.orig	2009-04-15 23:01:33.000000000 -0400
+++ mousePriv.h	2009-04-15 22:59:58.000000000 -0400
@@ -65,6 +65,12 @@
     Bool	disablePnPauto;
     float	fracdx,fracdy; 
     float	sensitivity;
+    int		min_x;
+    int		max_x;
+    int		min_y;
+    int		max_y;
+    int		rotate;
+    int		reporting_mode;
 } mousePrivRec, *mousePrivPtr;
 
 /* mouse proto flags */
diff -u xf86OSmouse.h.orig xf86OSmouse.h
--- xf86OSmouse.h.orig	2009-04-15 23:01:33.000000000 -0400
+++ xf86OSmouse.h	2009-04-15 23:00:20.000000000 -0400
@@ -184,6 +184,8 @@
 
 #define MSE_MAXBUTTONS	24
 #define MSE_DFLTBUTTONS	 3
+#define MSE_ABSOLUTE_POSN (1<<MSE_MAXBUTTONS)
+
 
 /*
  * Mouse device record.  This is shared by the mouse driver and the OSMouse
