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<