summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpingc <pingc>2007-01-11 23:27:30 +0000
committerpingc <pingc>2007-01-11 23:27:30 +0000
commit8d5b18e87378245b377a39dd6d81e4e8db54c4e2 (patch)
tree8a7885db5732d5da421b7944a8e9ce4e0a9f66fc
parente3a5a3acde5ffeaf3b8e74ed1e43d8cce3df15f5 (diff)
downloadxf86-input-wacom-8d5b18e87378245b377a39dd6d81e4e8db54c4e2.tar.gz
Incorporated patches 1630928, 1630926, and 1614296dev-0_7_7-2dev-0.7.7-2
-rw-r--r--ChangeLog14
-rwxr-xr-xsrc/2.6.13/wacom_sys.c6
-rwxr-xr-xsrc/util/wacomcfg.c9
-rwxr-xr-xsrc/util/xidump.c12
-rwxr-xr-xsrc/util/xsetwacom.c7
-rwxr-xr-xsrc/xdrv/wcmCommon.c271
-rwxr-xr-xsrc/xdrv/wcmConfig.c50
-rwxr-xr-xsrc/xdrv/wcmSerial.c6
-rwxr-xr-xsrc/xdrv/wcmUSB.c84
-rwxr-xr-xsrc/xdrv/xf86Wacom.c382
-rwxr-xr-xsrc/xdrv/xf86Wacom.h7
11 files changed, 506 insertions, 342 deletions
diff --git a/ChangeLog b/ChangeLog
index ab1310e..8cc70a2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2007-01-11 Ping Cheng <pingc@wacom.com>
+ * Incorporated patches 1630928, 1630926, and 1614296
+ * Updated xidump to ignore uninitialized tools
+ * Fixed kfree bug in wacom_sys.c for 2.6.13
+
+2007-01-08 Ping Cheng <pingc@wacom.com>
+ * Report raw tablet data in valuators for relative mode
+ * Improve relative movement accuracy in general
+
+2007-01-03 Ping Cheng <pingc@wacom.com>
+ * Improve relative small movement accuracy
+ * Reset pressure for relative in-prox event
+ to fix bug 1562718
+
2006-12-27 Ping Cheng <pingc@wacom.com>
* label 0.7.7-1 for testing
diff --git a/src/2.6.13/wacom_sys.c b/src/2.6.13/wacom_sys.c
index 17e4956..eab83fb 100755
--- a/src/2.6.13/wacom_sys.c
+++ b/src/2.6.13/wacom_sys.c
@@ -221,13 +221,16 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
return -ENOMEM;
memset(wacom, 0, sizeof(struct wacom));
- if (!(wacom_wac = kmalloc(sizeof(struct wacom_wac), GFP_KERNEL)))
+ if (!(wacom_wac = kmalloc(sizeof(struct wacom_wac), GFP_KERNEL))) {
+ kfree(wacom);
return -ENOMEM;
+ }
memset(wacom_wac, 0, sizeof(struct wacom_wac));
wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma);
if (!wacom_wac->data) {
kfree(wacom);
+ kfree(wacom_wac);
return -ENOMEM;
}
@@ -235,6 +238,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
if (!wacom->irq) {
usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma);
kfree(wacom);
+ kfree(wacom_wac);
return -ENOMEM;
}
diff --git a/src/util/wacomcfg.c b/src/util/wacomcfg.c
index f229522..dcaecc0 100755
--- a/src/util/wacomcfg.c
+++ b/src/util/wacomcfg.c
@@ -2,7 +2,7 @@
** wacomcfg.c
**
** Copyright (C) 2003-2004 - John E. Joganic
-** Copyright (C) 2004-2006 - Ping Cheng
+** Copyright (C) 2004-2007 - Ping Cheng
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public License
@@ -25,6 +25,7 @@
** 2005-10-24 0.0.4 - PC - Added Pad
** 2005-11-17 0.0.5 - PC - update mode code
** 2006-07-17 0.0.6 - PC - Exchange info directly with wacom_drv.o
+** 2007-01-10 0.0.7 - PC - don't display uninitialized tools
**
****************************************************************************/
@@ -137,6 +138,7 @@ int WacomConfigListDevices(WACOMCONFIG *hConfig, WACOMDEVICEINFO** ppInfo,
{
info = hConfig->pDevs + i;
if (info->use != IsXExtensionDevice) continue;
+ if (!info->num_classes) continue;
nSize += sizeof(WACOMDEVICEINFO);
nSize += strlen(info->name) + 1;
++nCount;
@@ -157,7 +159,8 @@ int WacomConfigListDevices(WACOMCONFIG *hConfig, WACOMDEVICEINFO** ppInfo,
info = hConfig->pDevs + i;
/* ignore non-extension devices */
if (info->use != IsXExtensionDevice) continue;
-
+ /* ignore uninitialized tools */
+ if (!info->num_classes) continue;
/* copy name */
nLen = strlen(info->name);
pInfo->pszName = (char*)(pReq + nPos);
@@ -212,7 +215,7 @@ WACOMDEVICE * WacomConfigOpenDevice(WACOMCONFIG * hConfig,
for (i=0; i<hConfig->nDevCnt; ++i)
{
info = hConfig->pDevs + i;
- if (strcmp(info->name, pszDeviceName) == 0)
+ if (!strcmp(info->name, pszDeviceName) && info->num_classes)
pDevInfo = info;
}
diff --git a/src/util/xidump.c b/src/util/xidump.c
index 2b965d5..8b0efe4 100755
--- a/src/util/xidump.c
+++ b/src/util/xidump.c
@@ -2,7 +2,7 @@
** xidump.c
**
** Copyright (C) 2003 - 2004 - John E. Joganic
-** Copyright (C) 2004 - 2006 - Ping Cheng
+** Copyright (C) 2004 - 2007 - Ping Cheng
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License
@@ -29,6 +29,7 @@
** 2005-11-11 0.7.1 - report tool ID and serial number
** 2006-05-05 0.7.4 - Removed older 2.6 kernels
** 2006-07-19 0.7.5 - Support buttons and keys combined
+** 2007-01-10 0.7.7 - Don't list uninitialized tools
**
****************************************************************************/
@@ -40,7 +41,7 @@
#include <sys/time.h>
#include <math.h>
-#define XIDUMP_VERSION "0.7.5"
+#define XIDUMP_VERSION "0.7.7"
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -151,7 +152,8 @@ int ListDevices(Display* pDisp, const char* pszDeviceName)
if (pszDeviceName && strcasecmp(pDev->name, pszDeviceName))
continue;
- printf("%-30s %s\n",
+ if (pDev->num_classes)
+ printf("%-30s %s\n",
pDev->name,
(pDev->use == 0) ? "disabled" :
(pDev->use == IsXKeyboard) ? "keyboard" :
@@ -240,7 +242,8 @@ XDeviceInfoPtr GetDevice(Display* pDisp, const char* pszDeviceName)
/* find device by name */
for (i=0; i<gnDevListCnt; ++i)
{
- if (strcasecmp(gpDevList[i].name,pszDeviceName) == 0)
+ if (!strcasecmp(gpDevList[i].name,pszDeviceName) &&
+ gpDevList[i].num_classes)
return gpDevList + i;
}
@@ -921,6 +924,7 @@ int Run(Display* pDisp, UI* pUI, FORMATTYPE fmt, const char* pszDeviceName)
}
/* open device */
+fprintf(stderr, "claess =%d use =%d type = %d \n", (int)pDevInfo->num_classes, (int)(pDevInfo->use), (int)pDevInfo->type);
pDev = XOpenDevice(pDisp,pDevInfo->id);
if (!pDev)
{
diff --git a/src/util/xsetwacom.c b/src/util/xsetwacom.c
index 54b0b4e..72df73c 100755
--- a/src/util/xsetwacom.c
+++ b/src/util/xsetwacom.c
@@ -2,7 +2,7 @@
** xsetwacom.c
**
** Copyright (C) 2003 - John E. Joganic
-** Copyright (C) 2004-2006 - Ping Cheng
+** Copyright (C) 2004-2007 - Ping Cheng
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public License
@@ -24,10 +24,11 @@
** 2005-11-17 0.0.5 - PC - update mode code
** 2006-02-27 0.0.6 - PC - fixed a typo
** 2006-07-19 0.0.7 - PC - supports button and keys combined
-*
+** 2007-01-10 0.0.8 - PC - don't display uninitialized tools
+**
****************************************************************************/
-#define XSETWACOM_VERSION "0.0.7"
+#define XSETWACOM_VERSION "0.0.8"
#include "wacomcfg.h"
#include "../include/Xwacom.h" /* give us raw access to parameter values */
diff --git a/src/xdrv/wcmCommon.c b/src/xdrv/wcmCommon.c
index c0e5027..f995b28 100755
--- a/src/xdrv/wcmCommon.c
+++ b/src/xdrv/wcmCommon.c
@@ -52,7 +52,7 @@ WacomDeviceClass* wcmDeviceClasses[] =
static void transPressureCurve(WacomDevicePtr pDev, WacomDeviceStatePtr pState);
static void commonDispatchDevice(WacomCommonPtr common, unsigned int channel,
- const WacomChannelPtr pChannel);
+ const WacomChannelPtr pChannel, int suppress);
static void resetSampleCounter(const WacomChannelPtr pChannel);
static void sendAButton(LocalDevicePtr local, int button, int mask,
int rx, int ry, int rz, int v3, int v4, int v5);
@@ -131,6 +131,8 @@ static void xf86WcmSetScreen(LocalDevicePtr local, int *value0, int *value1)
screenToSet = miPointerCurrentScreen()->myNum;
priv->factorX = screenInfo.screens[screenToSet]->width / sizeX;
priv->factorY = screenInfo.screens[screenToSet]->height / sizeY;
+ DBG(10, ErrorF("xf86WcmSetScreen current=%d ToSet=%d\n",
+ priv->currentScreen, screenToSet));
priv->currentScreen = screenToSet;
return;
}
@@ -478,8 +480,7 @@ void xf86WcmSendEvents(LocalDevicePtr local, const WacomDeviceState* ds, unsigne
WacomCommonPtr common = priv->common;
int naxes = priv->naxes;
- int rx, ry, rz, v3, v4, v5, no_jitter;
- double param, relacc;
+ int v3, v4, v5;
int is_absolute;
if (priv->serial && serial != priv->serial)
@@ -526,95 +527,32 @@ void xf86WcmSendEvents(LocalDevicePtr local, const WacomDeviceState* ds, unsigne
is_absolute = (priv->flags & ABSOLUTE_FLAG);
- /* sets rx and ry according to the mode */
- if (is_absolute)
+ if(!priv->oldProximity && !is_absolute)
{
- rx = x;
- ry = y;
- rz = z;
- if (IsCursor(priv))
- {
- v3 = rot;
- v4 = throttle;
- }
- else
- {
- v3 = tx;
- v4 = ty;
- }
- v5 = wheel;
+ /* initial current max distance */
+ priv->common->wcmMaxCursorDist = ds->distance;
+ }
+ priv->currentX = x;
+ priv->currentY = y;
+
+ if (IsCursor(priv))
+ {
+ v3 = rot;
+ v4 = throttle;
}
else
{
- if (priv->oldProximity)
- {
- if (x > priv->bottomX || x < priv->topX)
- x = priv->oldX;
- if (y > priv->bottomY || y < priv->topY)
- y = priv->oldY;
-
- rx = x - priv->oldX;
- ry = y - priv->oldY;
- rz = z - priv->oldZ;
- }
- else
- {
- rx = 0;
- ry = 0;
- rz = 0;
- /* initial current max distance */
- common->wcmMaxCursorDist = ds->distance;
- }
-
- /* don't apply speed for fairly small increments */
- no_jitter = (priv->speed*3 > 4) ? priv->speed*3 : 4;
- relacc = (MAX_ACCEL-priv->accel)*(MAX_ACCEL-priv->accel);
- if (ABS(rx) > no_jitter)
- {
- param = priv->speed;
-
- /* apply acceleration only when priv->speed > DEFAULT_SPEED */
- if (priv->speed > DEFAULT_SPEED )
- {
- param += priv->accel > 0 ? abs(rx)/relacc : 0;
- }
- /* don't apply acceleration when too fast. */
- rx *= param > 20.00 ? 20.00 : param;
- }
- if (ABS(ry) > no_jitter)
- {
- param = priv->speed;
- /* apply acceleration only when priv->speed > DEFAULT_SPEED */
- if (priv->speed > DEFAULT_SPEED )
- {
- param += priv->accel > 0 ? abs(ry)/relacc : 0;
-
- }
- /* don't apply acceleration when too fast. */
- ry *= param > 20.00 ? 20.00 : param;
- }
- if (IsCursor(priv))
- {
- v3 = rot - priv->oldRot;
- v4 = throttle - priv->oldThrottle;
- }
- else
- {
- v3 = tx - priv->oldTiltX;
- v4 = ty - priv->oldTiltY;
- }
- v5 = wheel - priv->oldWheel;
+ v3 = tx;
+ v4 = ty;
}
-
- priv->currentX = rx;
- priv->currentY = ry;
+ v5 = wheel;
DBG(6, ErrorF("[%s] %s prox=%d\tx=%d\ty=%d\tz=%d\tv3=%d\tv4=%d\tv5=%d\tid=%d"
"\tserial=%d\tbutton=%s\tbuttons=%d\t on channel=%d\n",
local->name,
is_absolute ? "abs" : "rel",
is_proximity,
- rx, ry, rz, v3, v4, v5, id, serial,
+ x, y, z, v3, v4, v5, id, serial,
is_button ? "true" : "false", buttons, channel));
if (type != PAD_ID)
@@ -638,26 +576,22 @@ void xf86WcmSendEvents(LocalDevicePtr local, const WacomDeviceState* ds, unsigne
* screen and modify the axes before posting events */
if(!(priv->flags & BUTTONS_ONLY_FLAG))
{
- xf86WcmSetScreen(local, &rx, &ry);
+ xf86WcmSetScreen(local, &x, &y);
}
- /* unify acceleration in both directions for relative mode to draw a circle */
- if (!is_absolute)
- rx *= priv->factorY / priv->factorX;
-
/* don't emit proximity events if device does not support proximity */
if ((local->dev->proximity && !priv->oldProximity))
xf86PostProximityEvent(local->dev, 1, 0, naxes,
- rx, ry, rz, v3, v4, v5);
+ x, y, z, v3, v4, v5);
if(!(priv->flags & BUTTONS_ONLY_FLAG))
xf86PostMotionEvent(local->dev, is_absolute,
- 0, naxes, rx, ry, rz, v3, v4, v5);
+ 0, naxes, x, y, z, v3, v4, v5);
if (priv->oldButtons != buttons)
{
- xf86WcmSendButtons(local,buttons,rx,ry,rz,v3,v4,v5);
+ xf86WcmSendButtons(local,buttons,x,y,z,v3,v4,v5);
}
/* simulate button 4 and 5 for relative wheel */
@@ -671,10 +605,10 @@ void xf86WcmSendEvents(LocalDevicePtr local, const WacomDeviceState* ds, unsigne
*/
local->dev->button->map [fakeButton] = fakeButton;
xf86PostButtonEvent(local->dev, is_absolute,
- fakeButton, 1, 0, naxes, rx, ry, rz,
+ fakeButton, 1, 0, naxes, x, y, z,
v3, v4, v5);
xf86PostButtonEvent(local->dev, is_absolute,
- fakeButton, 0, 0, naxes, rx, ry, rz,
+ fakeButton, 0, 0, naxes, x, y, z,
v3, v4, v5);
}
}
@@ -688,9 +622,9 @@ void xf86WcmSendEvents(LocalDevicePtr local, const WacomDeviceState* ds, unsigne
/* reports button up when the device has been
* down and becomes out of proximity */
if (priv->oldButtons)
- xf86WcmSendButtons(local,0,rx,ry,rz,v3,v4,v5);
+ xf86WcmSendButtons(local,0,x,y,z,v3,v4,v5);
if (priv->oldProximity && local->dev->proximity)
- xf86PostProximityEvent(local->dev,0,0,naxes,rx,ry,rz,v3,v4,v5);
+ xf86PostProximityEvent(local->dev,0,0,naxes,x,y,z,v3,v4,v5);
} /* not in proximity */
}
else
@@ -698,15 +632,15 @@ void xf86WcmSendEvents(LocalDevicePtr local, const WacomDeviceState* ds, unsigne
if ((v3 || v4 || buttons || ds->relwheel) && !priv->oldProximity)
{
xf86PostProximityEvent(local->dev, 1, 0, naxes,
- rx, ry, rz, v3, v4, v5);
+ x, y, z, v3, v4, v5);
is_proximity = 1;
}
if ( v3 || v4 )
xf86PostMotionEvent(local->dev, is_absolute,
- 0, naxes, rx, ry, rz, v3, v4, v5);
+ 0, naxes, x, y, z, v3, v4, v5);
if (priv->oldButtons != buttons)
xf86WcmSendButtons(local, buttons,
- rx, ry, rz, v3, v4, v5);
+ x, y, z, v3, v4, v5);
if ( ds->relwheel )
{
@@ -718,32 +652,49 @@ void xf86WcmSendEvents(LocalDevicePtr local, const WacomDeviceState* ds, unsigne
*/
local->dev->button->map [fakeButton] = fakeButton;
xf86PostButtonEvent(local->dev, is_absolute,
- fakeButton, 1, 0, naxes, rx, ry, rz,
+ fakeButton, 1, 0, naxes, x, y, z,
v3, v4, v5);
xf86PostButtonEvent(local->dev, is_absolute,
- fakeButton, 0, 0, naxes, rx, ry, rz,
+ fakeButton, 0, 0, naxes, x, y, z,
v3, v4, v5);
}
}
if ( !v3 && !v4 && !buttons)
{
xf86PostProximityEvent(local->dev, 0, 0, naxes,
- rx, ry, rz, v3, v4, v5);
+ x, y, z, v3, v4, v5);
is_proximity = 0;
}
}
priv->oldProximity = is_proximity;
- priv->oldButtons = buttons;
- priv->oldWheel = wheel;
- priv->oldX = x;
- priv->oldY = y;
- priv->oldZ = z;
- priv->oldTiltX = tx;
- priv->oldTiltY = ty;
- priv->oldStripX = ds->stripx;
- priv->oldStripY = ds->stripy;
- priv->oldRot = rot;
- priv->oldThrottle = throttle;
+ if (is_proximity)
+ {
+ priv->oldButtons = buttons;
+ priv->oldWheel = wheel;
+ priv->oldX = x;
+ priv->oldY = y;
+ priv->oldZ = z;
+ priv->oldTiltX = tx;
+ priv->oldTiltY = ty;
+ priv->oldStripX = ds->stripx;
+ priv->oldStripY = ds->stripy;
+ priv->oldRot = rot;
+ priv->oldThrottle = throttle;
+ }
+ else
+ {
+ priv->oldButtons = 0;
+ priv->oldWheel = 0;
+ priv->oldX = 0;
+ priv->oldY = 0;
+ priv->oldZ = 0;
+ priv->oldTiltX = 0;
+ priv->oldTiltY = 0;
+ priv->oldStripX = 0;
+ priv->oldStripY = 0;
+ priv->oldRot = 0;
+ priv->oldThrottle = 0;
+ }
}
/*****************************************************************************
@@ -760,8 +711,6 @@ static int xf86WcmSuppress(int suppress, const WacomDeviceState* dsOrig,
if (dsOrig->buttons != dsNew->buttons) return 0;
if (dsOrig->proximity != dsNew->proximity) return 0;
- if (ABS(dsOrig->x - dsNew->x) > suppress) return 0;
- if (ABS(dsOrig->y - dsNew->y) > suppress) return 0;
if (ABS(dsOrig->tiltx - dsNew->tiltx) > suppress) return 0;
if (ABS(dsOrig->tilty - dsNew->tilty) > suppress) return 0;
if (ABS(dsOrig->stripx - dsNew->stripx) > suppress) return 0;
@@ -776,6 +725,11 @@ static int xf86WcmSuppress(int suppress, const WacomDeviceState* dsOrig,
if ((ABS(dsOrig->abswheel - dsNew->abswheel) > suppress) ||
(dsNew->relwheel != 0)) return 0;
+ /* need to check if cursor moves or not */
+ if ((ABS(dsOrig->x - dsNew->x) > suppress) ||
+ (ABS(dsOrig->y - dsNew->y) > suppress)) return 2;
+
+ /* discard this event */
DBG(11, ErrorF("xf86WcmSuppress discarded data\n"));
return 1;
}
@@ -839,7 +793,7 @@ void xf86WcmEvent(WacomCommonPtr common, unsigned int channel,
WacomDeviceState ds;
WacomChannelPtr pChannel;
WacomFilterState* fs;
- int i;
+ int i, suppress = 0;
/* tool on the tablet when driver starts */
if (!miPointerCurrentScreen())
@@ -926,22 +880,11 @@ void xf86WcmEvent(WacomCommonPtr common, unsigned int channel,
}
/* Discard unwanted data */
- if (xf86WcmSuppress(common->wcmSuppress, pLast, &ds))
+ suppress = xf86WcmSuppress(common->wcmSuppress, pLast, &ds);
+ if (suppress == 1)
{
- /* If throttle is not in use, discard data. */
- if (ABS(ds.throttle) < common->wcmSuppress)
- {
- resetSampleCounter(pChannel);
- return;
- }
-
- /* Otherwise, we need this event for time-rate-of-change
- * values like the throttle-to-relative-wheel filter.
- * To eliminate position change events, we reset all values
- * to last unsuppressed position. */
-
- ds = *pLast;
- RESET_RELATIVE(ds);
+ resetSampleCounter(pChannel);
+ return;
}
}
@@ -958,7 +901,7 @@ void xf86WcmEvent(WacomCommonPtr common, unsigned int channel,
pChannel->valid.state = ds; /*save last raw sample */
if (pChannel->nSamples < MAX_SAMPLES) ++pChannel->nSamples;
- commonDispatchDevice(common,channel,pChannel);
+ commonDispatchDevice(common,channel,pChannel, suppress);
resetSampleCounter(pChannel);
}
@@ -1002,7 +945,7 @@ static int idtotype(int id)
}
static void commonDispatchDevice(WacomCommonPtr common, unsigned int channel,
- const WacomChannelPtr pChannel)
+ const WacomChannelPtr pChannel, int suppress)
{
LocalDevicePtr pDev = NULL;
WacomToolPtr tool = NULL;
@@ -1058,16 +1001,49 @@ static void commonDispatchDevice(WacomCommonPtr common, unsigned int channel,
/* 2: Find the associated area, and its InputDevice */
if (tool)
{
+ /* if the current area is not in-prox anymore, we
+ * might want to use another area. So move the
+ * current-pointer away for a moment while we have a
+ * look if there's a better area defined */
+ WacomToolAreaPtr outprox = NULL;
+ if (tool->current && !xf86WcmPointInArea(tool->current, ds->x, ds->y))
+ {
+ outprox = tool->current;
+ tool->current = NULL;
+ }
+
/* If no current area in-prox, find a matching area */
if(!tool->current)
{
WacomToolAreaPtr area = tool->arealist;
for(; area; area = area->next)
- if (area->topX <= ds->x && ds->x <= area->bottomX
- && area->topY <= ds->y && ds->y <= area->bottomY)
+ if (xf86WcmPointInArea(area, ds->x, ds->y))
break;
tool->current = area;
}
+
+ /* If a better area was found, send a soft prox-out
+ * for the current in-prox area, else use the old one. */
+ if (outprox)
+ {
+ if (tool->current)
+ {
+ /* Send soft prox-out for the old area */
+ WacomDevicePtr priv = outprox->device->private;
+ DBG(2, ErrorF("Soft prox-out for %s\n",
+ outprox->device->name));
+ xf86PostProximityEvent(outprox->device->dev,0,0,0);
+ /* Set state of the old device to prox-out */
+ priv->oldProximity = 0;
+ priv->oldButtons = 0;
+ /* start over with button-press events */
+ pChannel->work.buttons = 0;
+ pChannel->valid.state.buttons = 0;
+ }
+ else
+ tool->current = outprox;
+ }
+
/* If there was one already in use or we found one */
if(tool->current)
{
@@ -1148,6 +1124,32 @@ static void commonDispatchDevice(WacomCommonPtr common, unsigned int channel,
#endif /* throttle */
+ if (!(priv->flags & ABSOLUTE_FLAG) && (suppress == 2))
+ {
+ /* To improve the accuracy of relative x/y,
+ * don't send event when there is no movement.
+ */
+ double deltx = filtered.x - priv->oldX;
+ double delty = filtered.y - priv->oldY;
+ deltx *= priv->factorY*priv->speed;
+ delty *= priv->factorY*priv->speed;
+
+ if (ABS(deltx)<1 && ABS(delty)<1)
+ {
+ DBG(10, ErrorF("Ignore non-movement relative data \n"));
+ return;
+ }
+ else
+ {
+ int temp = deltx;
+ deltx = (double)temp/(priv->factorY*priv->speed);
+ temp = delty;
+ delty = (double)temp/(priv->factorY*priv->speed);
+ filtered.x = deltx + priv->oldX;
+ filtered.y = delty + priv->oldY;
+ }
+ }
+
/* force out-prox when distance is outside wcmCursorProxoutDist. */
if (!(priv->flags & ABSOLUTE_FLAG) && IsCursor(priv))
{
@@ -1185,7 +1187,7 @@ static void commonDispatchDevice(WacomCommonPtr common, unsigned int channel,
}
xf86WcmSendEvents(pDev, &filtered, channel);
/* If out-prox, reset the current area pointer */
- if (!ds->proximity)
+ if (!filtered.proximity)
tool->current = NULL;
}
@@ -1195,9 +1197,6 @@ static void commonDispatchDevice(WacomCommonPtr common, unsigned int channel,
DBG(11, ErrorF("no device matches with id=%d, serial=%d\n",
ds->device_type, ds->serial_num));
}
-
- /* save the last device */
- pChannel->pDev = pDev;
}
/*****************************************************************************
diff --git a/src/xdrv/wcmConfig.c b/src/xdrv/wcmConfig.c
index 175a88f..f612424 100755
--- a/src/xdrv/wcmConfig.c
+++ b/src/xdrv/wcmConfig.c
@@ -98,11 +98,13 @@ LocalDevicePtr xf86WcmAllocate(char* name, int flag)
memset(priv,0,sizeof(*priv));
priv->flags = flag; /* various flags (device type, absolute, first touch...) */
- priv->oldX = -1; /* previous X position */
- priv->oldY = -1; /* previous Y position */
- priv->oldZ = -1; /* previous pressure */
- priv->oldTiltX = -1; /* previous tilt in x direction */
- priv->oldTiltY = -1; /* previous tilt in y direction */
+ priv->oldX = 0; /* previous X position */
+ priv->oldY = 0; /* previous Y position */
+ priv->oldZ = 0; /* previous pressure */
+ priv->oldTiltX = 0; /* previous tilt in x direction */
+ priv->oldTiltY = 0; /* previous tilt in y direction */
+ priv->oldStripX = 0; /* previous left strip value */
+ priv->oldStripY = 0; /* previous right strip value */
priv->oldButtons = 0; /* previous buttons state */
priv->oldWheel = 0; /* previous wheel */
priv->topX = 0; /* X top */
@@ -113,6 +115,7 @@ LocalDevicePtr xf86WcmAllocate(char* name, int flag)
priv->factorY = 0.0; /* Y factor */
priv->common = common; /* common info pointer */
priv->oldProximity = 0; /* previous proximity */
+ priv->devReverseCount = 0; /* flag for relative Reverse call */
priv->serial = 0; /* serial number */
priv->screen_no = -1; /* associated screen */
priv->speed = DEFAULT_SPEED; /* rel. mode speed */
@@ -168,7 +171,6 @@ LocalDevicePtr xf86WcmAllocate(char* name, int flag)
common->wcmResolY = 0; /* Y resolution in points/inch */
common->wcmMaxStripX = 4095; /* Max fingerstrip X */
common->wcmMaxStripY = 4095; /* Max fingerstrip Y */
- common->wcmChannelCnt = 1; /* number of channels */
common->wcmProtocolLevel = 4; /* protocol level */
common->wcmThreshold = 0; /* unconfigured threshold */
common->wcmLinkSpeed = 9600; /* serial link speed */
@@ -256,6 +258,38 @@ LocalDevicePtr xf86WcmAllocatePad(void)
return local;
}
+/* xf86WcmPointInArea - check whether the point is within the area */
+
+Bool xf86WcmPointInArea(WacomToolAreaPtr area, int x, int y)
+{
+ if (area->topX <= x && x <= area->bottomX &&
+ area->topY <= y && y <= area->bottomY)
+ return 1;
+ return 0;
+}
+
+/* xf86WcmAreasOverlap - check if two areas are overlapping */
+
+static Bool xf86WcmAreasOverlap(WacomToolAreaPtr area1, WacomToolAreaPtr area2)
+{
+ if (xf86WcmPointInArea(area1, area2->topX, area2->topY) ||
+ xf86WcmPointInArea(area1, area2->topX, area2->bottomY) ||
+ xf86WcmPointInArea(area1, area2->bottomX, area2->topY) ||
+ xf86WcmPointInArea(area1, area2->bottomX, area2->bottomY))
+ return 1;
+ return 0;
+}
+
+/* xf86WcmAreaListOverlaps - check if the area overlaps any area in the list */
+
+Bool xf86WcmAreaListOverlap(WacomToolAreaPtr area, WacomToolAreaPtr list)
+{
+ for (; list; list = list->next)
+ if (area != list && xf86WcmAreasOverlap(list, area))
+ return 1;
+ return 0;
+}
+
/*
* Be sure to set vmin appropriately for your device's protocol. You want to
* read a full packet before returning
@@ -639,9 +673,9 @@ static LocalDevicePtr xf86WcmInit(InputDriverPtr drv, IDevPtr dev, int flags)
xfree(tool);
priv->tool = tool = toollist;
- /*TODO: verify area against other areas of the same tool */
- /* Add the area to the end of the list */
arealist = toollist->arealist;
+
+ /* Add the area to the end of the list */
while(arealist->next)
arealist = arealist->next;
arealist->next = area;
diff --git a/src/xdrv/wcmSerial.c b/src/xdrv/wcmSerial.c
index 710ef61..a840faf 100755
--- a/src/xdrv/wcmSerial.c
+++ b/src/xdrv/wcmSerial.c
@@ -849,12 +849,6 @@ static int serialParseProtocol5(WacomCommonPtr common, const unsigned char* data
{
xf86WcmEvent(common,channel,ds);
}
-
- /* otherwise, initialize channel and wait for next packet */
- else
- {
- common->wcmChannel[channel].pDev = NULL;
- }
return common->wcmPktLength;
}
diff --git a/src/xdrv/wcmUSB.c b/src/xdrv/wcmUSB.c
index 3e8cc50..7b1a876 100755
--- a/src/xdrv/wcmUSB.c
+++ b/src/xdrv/wcmUSB.c
@@ -483,14 +483,6 @@ static void usbInitProtocol5(WacomCommonPtr common, const char* id,
{
DBG(2, ErrorF("detected a protocol 5 model (%s)\n",id));
common->wcmProtocolLevel = 5;
- if ( strstr(id, "Intuos3") || strstr(id, "21UX") )
- {
- common->wcmChannelCnt = 1;
- }
- else
- {
- common->wcmChannelCnt = 2;
- }
common->wcmPktLength = sizeof(struct input_event);
common->wcmCursorProxoutDistDefault
= PROXOUT_INTUOS_DISTANCE;
@@ -503,7 +495,6 @@ static void usbInitProtocol4(WacomCommonPtr common, const char* id,
float version)
{
DBG(2, ErrorF("detected a protocol 4 model (%s)\n",id));
- common->wcmChannelCnt = 1;
common->wcmProtocolLevel = 4;
common->wcmPktLength = sizeof(struct input_event);
common->wcmCursorProxoutDistDefault
@@ -711,73 +702,46 @@ static void usbParseEvent(WacomCommonPtr common,
/* figure out the channel to use based on serial number */
channel = -1;
- /* one channel only? */
- if (common->wcmChannelCnt == 1)
+ /* find existing channel */
+ for (i=0; i<MAX_CHANNELS; ++i)
{
- /* Intuos3 or Graphire4 Pad */
- if (common->wcmLastToolSerial == 0xffffffff || common->wcmLastToolSerial == 0xf0)
+ if (common->wcmChannel[i].work.proximity &&
+ common->wcmChannel[i].work.serial_num == common->wcmLastToolSerial)
{
- channel = 1;
- (&common->wcmChannel[channel].work)->device_type = PAD_ID;
- (&common->wcmChannel[channel].work)->proximity = 1;
- }
- else /* must be it. */
- {
- channel = 0;
- if (common->wcmChannel[0].work.proximity == 0)
- {
- memset(&common->wcmChannel[0],0,
- sizeof(WacomChannel));
- common->wcmChannel[0].work.proximity = 1;
- }
+ channel = i;
+ break;
}
}
- /* otherwise, find the channel */
- else
+ /* find an empty channel */
+ if (channel < 0)
{
- /* clear out channels */
- for (i=0; i<common->wcmChannelCnt; ++i)
+ for (i=0; i<MAX_CHANNELS; ++i)
{
- if (common->wcmChannel[i].work.proximity == 0)
+ if (!common->wcmChannel[i].work.proximity)
{
memset(&common->wcmChannel[i],0,
sizeof(WacomChannel));
- }
- }
- /* find existing channel */
- for (i=0; i<common->wcmChannelCnt; ++i)
- {
- if (common->wcmChannel[i].work.serial_num == common->wcmLastToolSerial)
- {
+ /* in case the in-prox event was missing */
+ common->wcmChannel[i].work.proximity = 1;
+ /* Intuos3 or Graphire4 Pad */
+ if (common->wcmLastToolSerial == 0xffffffff ||
+ common->wcmLastToolSerial == 0xf0)
+ common->wcmChannel[i].work.device_type = PAD_ID;
channel = i;
break;
}
}
+ }
- /* find an empty channel */
- if (channel < 0)
- {
- for (i=0; i<common->wcmChannelCnt; ++i)
- {
- if (common->wcmChannel[i].work.proximity == 0)
- {
- channel = i;
- /* the in-prox event was missing */
- common->wcmChannel[i].work.proximity = 1;
- break;
- }
- }
- }
+ /* fresh out of channels */
+ if (channel < 0)
+ {
+ /* this should never happen in normal use */
+ DBG(1, ErrorF("usbParse: Exceeded channel count; "
+ "ignoring.\n"));
+ return;
- /* fresh out of channels */
- if (channel < 0)
- {
- /* this should never happen in normal use */
- DBG(1, ErrorF("usbParse: Exceeded channel count; "
- "ignoring.\n"));
- return;
- }
}
usbParseChannel(common,channel,common->wcmLastToolSerial);
diff --git a/src/xdrv/xf86Wacom.c b/src/xdrv/xf86Wacom.c
index a7eac8b..fa437c8 100755
--- a/src/xdrv/xf86Wacom.c
+++ b/src/xdrv/xf86Wacom.c
@@ -98,111 +98,13 @@ WacomModule gWacomModule =
xf86WcmDevReverseConvert,
};
-/*****************************************************************************
- * xf86WcmRegisterX11Devices --
- * Register the X11 input devices with X11 core.
- ****************************************************************************/
-
-static int xf86WcmRegisterX11Devices (LocalDevicePtr local)
+static int xf86WcmInitArea(LocalDevicePtr local)
{
WacomDevicePtr priv = (WacomDevicePtr)local->private;
+ WacomToolAreaPtr area = priv->toolarea;
WacomCommonPtr common = priv->common;
- int totalWidth = 0, maxHeight = 0, tabletSize = 0;
+ int totalWidth = 0, maxHeight = 0;
double screenRatio, tabletRatio;
- CARD8 butmap[MAX_BUTTONS];
- int nbaxes, nbbuttons, nbkeys;
- int loop;
- WacomToolAreaPtr area = priv->toolarea;
-
- /* Detect tablet configuration, if possible */
- if (priv->common->wcmModel->DetectConfig)
- priv->common->wcmModel->DetectConfig (local);
-
- nbaxes = priv->naxes; /* X, Y, Pressure, Tilt-X, Tilt-Y, Wheel */
- nbbuttons = priv->nbuttons; /* Use actual number of buttons, if possible */
- nbkeys = nbbuttons; /* Same number of keys since any button may be */
- /* configured as an either mouse button or key */
-
- DBG(10,ErrorF("xf86WcmRegisterX11Devices (%s) %d buttons, %d keys, %d axes\n",
- IsStylus(priv) ? "stylus" :
- IsCursor(priv) ? "cursor" :
- IsPad(priv) ? "pad" : "eraser",
- nbbuttons, nbkeys, nbaxes));
-
- for(loop=1; loop<=nbbuttons; loop++)
- butmap[loop] = loop;
-
- if (InitButtonClassDeviceStruct(local->dev, nbbuttons, butmap) == FALSE)
- {
- ErrorF("unable to allocate Button class device\n");
- return FALSE;
- }
-
- if (InitProximityClassDeviceStruct(local->dev) == FALSE)
- {
- ErrorF("unable to init proximity class device\n");
- return FALSE;
- }
-
- if (nbaxes || nbaxes > 6)
- nbaxes = priv->naxes = 6;
-
- if (InitValuatorClassDeviceStruct(local->dev, nbaxes,
- xf86GetMotionEvents,
- local->history_size,
- (priv->flags & ABSOLUTE_FLAG) ?
- Absolute : Relative) == FALSE)
- {
- ErrorF("unable to allocate Valuator class device\n");
- return FALSE;
- }
-
- if (nbkeys)
- {
- KeySymsRec wacom_keysyms;
- KeySym keymap[MAX_BUTTONS];
-
- for (loop = 0; loop < nbkeys; loop++)
- if ((priv->button [loop] & AC_TYPE) == AC_KEY)
- keymap [loop] = priv->button [loop] & AC_CODE;
- else
- keymap [loop] = NoSymbol;
-
- /* There seems to be a long-standing misunderstanding about
- * how a keymap should be defined. All tablet drivers from
- * stock X11 source tree are doing it wrong: they leave first
- * 8 keysyms as VoidSymbol's, and are passing 8 as minimum
- * key code. But if you look at SetKeySymsMap() from
- * programs/Xserver/dix/devices.c you will see that
- * Xserver does not require first 8 keysyms; it supposes
- * that the map begins at minKeyCode.
- *
- * It could be that this assumption is a leftover from
- * earlier XFree86 versions, but that's out of our scope.
- * This also means that no keys on extended input devices
- * with their own keycodes (e.g. tablets) were EVER used.
- */
- wacom_keysyms.map = keymap;
- /* minKeyCode = 8 because this is the min legal key code */
- wacom_keysyms.minKeyCode = 8;
- wacom_keysyms.maxKeyCode = 8 + nbkeys - 1;
- wacom_keysyms.mapWidth = 1;
- if (InitKeyClassDeviceStruct(local->dev, &wacom_keysyms, NULL) == FALSE)
- {
- ErrorF("unable to init key class device\n");
- return FALSE;
- }
- }
-
- /* allocate motion history buffer if needed */
- xf86MotionHistoryAllocate(local);
-
- /* initialize bounding rect */
- if (priv->twinview != TV_NONE && priv->screen_no == -1)
- {
- priv->tvoffsetX = 60;
- priv->tvoffsetY = 60;
- }
priv->bottomX = xf86SetIntOption(local->options, "BottomX", 0);
priv->bottomY = xf86SetIntOption(local->options, "BottomY", 0);
@@ -277,6 +179,16 @@ static int xf86WcmRegisterX11Devices (LocalDevicePtr local)
}
}
+ if (priv->numScreen == 1)
+ {
+ priv->factorX = totalWidth
+ / (double)(priv->bottomX - priv->topX - 2*priv->tvoffsetX);
+ priv->factorY = maxHeight
+ / (double)(priv->bottomY - priv->topY - 2*priv->tvoffsetY);
+ DBG(2, ErrorF("X factor = %.3g, Y factor = %.3g\n",
+ priv->factorX, priv->factorY));
+ }
+
/* Maintain aspect ratio */
if (priv->flags & KEEP_SHAPE_FLAG)
{
@@ -301,20 +213,150 @@ static int xf86WcmRegisterX11Devices (LocalDevicePtr local)
}
} /* end keep shape */
- if (xf86Verbose)
+ if (xf86WcmAreaListOverlap(area, priv->tool->arealist))
+ {
+ int i, j;
+ /* remove this area from the list */
+ WacomToolAreaPtr arealist = priv->tool->arealist;
+ while (arealist && arealist->next != area)
+ {
+ arealist = arealist->next;
+ }
+ arealist->next = area->next;
+ xfree(area);
+
+ /* Remove this device from the common struct */
+ i = 0;
+ while (i<common->wcmNumDevices && common->wcmDevices[i] != local)
+ i++;
+ for (j=i; j<common->wcmNumDevices-1; j++)
+ {
+ common->wcmDevices[j] = common->wcmDevices[j+1];
+ }
+ common->wcmDevices[common->wcmNumDevices-1] = NULL;
+ common->wcmNumDevices--;
+ xf86Msg(X_ERROR, "%s: Top/Bottom area overlaps with another devices.\n",
+ local->conf_idev->identifier);
+ return FALSE;
+ }
+ else if (xf86Verbose)
+ {
ErrorF("%s Wacom device \"%s\" top X=%d top Y=%d "
"bottom X=%d bottom Y=%d\n",
XCONFIG_PROBED, local->name, priv->topX,
priv->topY, priv->bottomX, priv->bottomY);
+ return TRUE;
+ }
- if (priv->numScreen == 1)
+}
+
+/*****************************************************************************
+ * xf86WcmRegisterX11Devices --
+ * Register the X11 input devices with X11 core.
+ ****************************************************************************/
+
+static int xf86WcmRegisterX11Devices (LocalDevicePtr local)
+{
+ WacomDevicePtr priv = (WacomDevicePtr)local->private;
+ WacomCommonPtr common = priv->common;
+ int tabletSize = 0;
+ CARD8 butmap[MAX_BUTTONS];
+ int nbaxes, nbbuttons, nbkeys;
+ int loop;
+
+ /* Detect tablet configuration, if possible */
+ if (priv->common->wcmModel->DetectConfig)
+ priv->common->wcmModel->DetectConfig (local);
+
+ nbaxes = priv->naxes; /* X, Y, Pressure, Tilt-X, Tilt-Y, Wheel */
+ nbbuttons = priv->nbuttons; /* Use actual number of buttons, if possible */
+ nbkeys = nbbuttons; /* Same number of keys since any button may be */
+ /* configured as an either mouse button or key */
+
+ DBG(10,ErrorF("xf86WcmRegisterX11Devices (%s) %d buttons, %d keys, %d axes\n",
+ IsStylus(priv) ? "stylus" :
+ IsCursor(priv) ? "cursor" :
+ IsPad(priv) ? "pad" : "eraser",
+ nbbuttons, nbkeys, nbaxes));
+
+ if (xf86WcmInitArea(local) == FALSE)
{
- priv->factorX = totalWidth
- / (double)(priv->bottomX - priv->topX - 2*priv->tvoffsetX);
- priv->factorY = maxHeight
- / (double)(priv->bottomY - priv->topY - 2*priv->tvoffsetY);
- DBG(2, ErrorF("X factor = %.3g, Y factor = %.3g\n",
- priv->factorX, priv->factorY));
+ return FALSE;
+ }
+
+ for(loop=1; loop<=nbbuttons; loop++)
+ butmap[loop] = loop;
+
+ if (InitButtonClassDeviceStruct(local->dev, nbbuttons, butmap) == FALSE)
+ {
+ ErrorF("unable to allocate Button class device\n");
+ return FALSE;
+ }
+
+ if (InitProximityClassDeviceStruct(local->dev) == FALSE)
+ {
+ ErrorF("unable to init proximity class device\n");
+ return FALSE;
+ }
+
+ if (nbaxes || nbaxes > 6)
+ nbaxes = priv->naxes = 6;
+
+ if (InitValuatorClassDeviceStruct(local->dev, nbaxes,
+ xf86GetMotionEvents,
+ local->history_size,
+ (priv->flags & ABSOLUTE_FLAG) ?
+ Absolute : Relative) == FALSE)
+ {
+ ErrorF("unable to allocate Valuator class device\n");
+ return FALSE;
+ }
+
+ if (nbkeys)
+ {
+ KeySymsRec wacom_keysyms;
+ KeySym keymap[MAX_BUTTONS];
+
+ for (loop = 0; loop < nbkeys; loop++)
+ if ((priv->button [loop] & AC_TYPE) == AC_KEY)
+ keymap [loop] = priv->button [loop] & AC_CODE;
+ else
+ keymap [loop] = NoSymbol;
+
+ /* There seems to be a long-standing misunderstanding about
+ * how a keymap should be defined. All tablet drivers from
+ * stock X11 source tree are doing it wrong: they leave first
+ * 8 keysyms as VoidSymbol's, and are passing 8 as minimum
+ * key code. But if you look at SetKeySymsMap() from
+ * programs/Xserver/dix/devices.c you will see that
+ * Xserver does not require first 8 keysyms; it supposes
+ * that the map begins at minKeyCode.
+ *
+ * It could be that this assumption is a leftover from
+ * earlier XFree86 versions, but that's out of our scope.
+ * This also means that no keys on extended input devices
+ * with their own keycodes (e.g. tablets) were EVER used.
+ */
+ wacom_keysyms.map = keymap;
+ /* minKeyCode = 8 because this is the min legal key code */
+ wacom_keysyms.minKeyCode = 8;
+ wacom_keysyms.maxKeyCode = 8 + nbkeys - 1;
+ wacom_keysyms.mapWidth = 1;
+ if (InitKeyClassDeviceStruct(local->dev, &wacom_keysyms, NULL) == FALSE)
+ {
+ ErrorF("unable to init key class device\n");
+ return FALSE;
+ }
+ }
+
+ /* allocate motion history buffer if needed */
+ xf86MotionHistoryAllocate(local);
+
+ /* initialize bounding rect */
+ if (priv->twinview != TV_NONE && priv->screen_no == -1)
+ {
+ priv->tvoffsetX = 60;
+ priv->tvoffsetY = 60;
}
/* x and y axes */
@@ -587,6 +629,8 @@ static int xf86WcmDevProc(DeviceIntPtr pWcm, int what)
if (!xf86WcmDevOpen(pWcm))
{
DBG(1, ErrorF("xf86WcmProc INIT FAILED\n"));
+ DisableDevice(pWcm);
+ priv->common = NULL;
return !Success;
}
priv->wcmDevOpenCount++;
@@ -596,6 +640,7 @@ static int xf86WcmDevProc(DeviceIntPtr pWcm, int what)
if (!xf86WcmDevOpen(pWcm))
{
DBG(1, ErrorF("xf86WcmProc ON FAILED\n"));
+ DisableDevice(pWcm);
return !Success;
}
priv->wcmDevOpenCount++;
@@ -648,8 +693,17 @@ static int xf86WcmSetParam(LocalDevicePtr local, int param, int value)
case XWACOM_PARAM_TOPX:
if ( priv->topX != value)
{
+ /* check if value overlaps with existing ones */
+ area->topX = value;
+ if (xf86WcmAreaListOverlap(area, common->wcmTool->arealist))
+ {
+ area->topX = priv->topX;
+ return BadValue;
+ }
+
+ /* Area definition is ok */
xf86ReplaceIntOption(local->options, "TopX", value);
- area->topX = priv->topX = xf86SetIntOption(local->options, "TopX", 0);
+ priv->topX = xf86SetIntOption(local->options, "TopX", 0);
if (priv->twinview == TV_LEFT_RIGHT)
tabletSize = 2*(priv->bottomX - priv->topX - 2*priv->tvoffsetX);
else
@@ -662,8 +716,17 @@ static int xf86WcmSetParam(LocalDevicePtr local, int param, int value)
case XWACOM_PARAM_TOPY:
if ( priv->topY != value)
{
+ /* check if value overlaps with existing ones */
+ area->topY = value;
+ if (xf86WcmAreaListOverlap(area, common->wcmTool->arealist))
+ {
+ area->topY = priv->topY;
+ return BadValue;
+ }
+
+ /* Area definition is ok */
xf86ReplaceIntOption(local->options, "TopY", value);
- area->topY = priv->topY = xf86SetIntOption(local->options, "TopY", 0);
+ priv->topY = xf86SetIntOption(local->options, "TopY", 0);
if (priv->twinview == TV_ABOVE_BELOW)
tabletSize = 2*(priv->bottomY - priv->topY - 2*priv->tvoffsetY);
else
@@ -676,8 +739,17 @@ static int xf86WcmSetParam(LocalDevicePtr local, int param, int value)
case XWACOM_PARAM_BOTTOMX:
if ( priv->bottomX != value)
{
+ /* check if value overlaps with existing ones */
+ area->bottomX = value;
+ if (xf86WcmAreaListOverlap(area, common->wcmTool->arealist))
+ {
+ area->bottomX = priv->bottomX;
+ return BadValue;
+ }
+
+ /* Area definition is ok */
xf86ReplaceIntOption(local->options, "BottomX", value);
- area->bottomX = priv->bottomX = xf86SetIntOption(local->options, "BottomX", 0);
+ priv->bottomX = xf86SetIntOption(local->options, "BottomX", 0);
if (priv->twinview == TV_LEFT_RIGHT)
tabletSize = 2*(priv->bottomX - priv->topX - 2*priv->tvoffsetX);
else
@@ -690,8 +762,17 @@ static int xf86WcmSetParam(LocalDevicePtr local, int param, int value)
case XWACOM_PARAM_BOTTOMY:
if ( priv->bottomY != value)
{
+ /* check if value overlaps with existing ones */
+ area->bottomY = value;
+ if (xf86WcmAreaListOverlap(area, common->wcmTool->arealist))
+ {
+ area->bottomY = priv->bottomY;
+ return BadValue;
+ }
+
+ /* Area definition is ok */
xf86ReplaceIntOption(local->options, "BottomY", value);
- area->bottomY = priv->bottomY = xf86SetIntOption(local->options, "BottomY", 0);
+ priv->bottomY = xf86SetIntOption(local->options, "BottomY", 0);
if (priv->twinview == TV_ABOVE_BELOW)
tabletSize = 2*(priv->bottomY - priv->topY - 2*priv->tvoffsetY);
else
@@ -1136,8 +1217,9 @@ static int xf86WcmGetDefaultParam(LocalDevicePtr local, int param)
static int xf86WcmModelToFile(LocalDevicePtr local)
{
FILE *fp = 0;
- LocalDevicePtr localDevices = xf86FirstLocalDevice();
+ LocalDevicePtr localDevices = xf86FirstLocalDevice();
WacomDevicePtr priv = NULL, lprv;
+
char m1[32], m2[32], *m3;
int i = 0, x = 0, y = 0;
@@ -1233,7 +1315,7 @@ static int xf86WcmDevChangeControl(LocalDevicePtr local, xDeviceCtl* control)
WacomDevicePtr priv = (WacomDevicePtr)local->private;
xDeviceResolutionCtl* res = (xDeviceResolutionCtl *)control;
int i, rc = Success, *r = (int*)(res+1);
-
+
if (control->control != DEVICE_RESOLUTION || (res->num_valuators < 1
&& res->num_valuators > 3) || res->first_valuator != 0)
return BadMatch;
@@ -1299,6 +1381,8 @@ static Bool xf86WcmDevConvert(LocalDevicePtr local, int first, int num,
int v0, int v1, int v2, int v3, int v4, int v5, int* x, int* y)
{
WacomDevicePtr priv = (WacomDevicePtr) local->private;
+ int no_jitter;
+ double relacc, param, temp;
DBG(6, ErrorF("xf86WcmDevConvert v0=%d v1=%d \n", v0, v1));
@@ -1401,9 +1485,60 @@ static Bool xf86WcmDevConvert(LocalDevicePtr local, int first, int num,
}
return TRUE;
}
+ temp = (double)v0 * priv->factorX + 0.5;
+ *x += temp;
+ }
+ else
+ {
+ *x = priv->currentSX;
+ *y = priv->currentSY;
+ if(!priv->oldProximity)
+ {
+ /* don't move the cursor */
+ v0 = 0;
+ v1 = 0;
+ }
+ else
+ {
+ v0 -= priv->oldX;
+ v1 -= priv->oldY;
+ }
+ /* don't apply speed for fairly small increments */
+ no_jitter = (priv->speed*3 > 4) ? priv->speed*3 : 4;
+ relacc = (MAX_ACCEL-priv->accel)*(MAX_ACCEL-priv->accel);
+ if (ABS(v0) > no_jitter)
+ {
+ param = priv->speed;
+
+ /* apply acceleration only when priv->speed > DEFAULT_SPEED */
+ if (priv->speed > DEFAULT_SPEED )
+ {
+ param += priv->accel > 0 ? abs(v0)/relacc : 0;
+ }
+ /* don't apply acceleration when too fast. */
+ v0 *= param > 20.00 ? 20.00 : param;
+ }
+ if (ABS(v1) > no_jitter)
+ {
+ param = priv->speed;
+ /* apply acceleration only when priv->speed > DEFAULT_SPEED */
+ if (priv->speed > DEFAULT_SPEED )
+ {
+ param += priv->accel > 0 ? abs(v1)/relacc : 0;
+
+ }
+ /* don't apply acceleration when too fast. */
+ v1 *= param > 20.00 ? 20.00 : param;
+ }
+
+ /* unify acceleration in both directions
+ * for relative mode to draw a circle
+ */
+ temp = (double)v0 * priv->factorY + 0.5;
+ *x += temp;
}
- *x += v0 * priv->factorX + 0.5;
- *y += v1 * priv->factorY + 0.5;
+ temp = (double)v1 * priv->factorY + 0.5;
+ *y += temp;
DBG(6, ErrorF("Wacom converted v0=%d v1=%d to x=%d y=%d\n", v0, v1, *x, *y));
return TRUE;
@@ -1420,6 +1555,7 @@ static Bool xf86WcmDevReverseConvert(LocalDevicePtr local, int x, int y,
int* valuators)
{
WacomDevicePtr priv = (WacomDevicePtr) local->private;
+ int i = 0;
DBG(6, ErrorF("xf86WcmDevReverseConvert x=%d y=%d \n", x, y));
priv->currentSX = x;
@@ -1427,8 +1563,16 @@ static Bool xf86WcmDevReverseConvert(LocalDevicePtr local, int x, int y,
if (!(priv->flags & ABSOLUTE_FLAG))
{
- valuators[0] = x / priv->factorX + 0.5;
- valuators[1] = y / priv->factorY + 0.5;
+ if (!priv->devReverseCount)
+ {
+ /* reset valuators to report raw values */
+ for (i=0; i<priv->naxes; i++)
+ valuators[i] = 0;
+
+ priv->devReverseCount = 1;
+ }
+ else
+ priv->devReverseCount = 0;
}
#ifdef NEVER
diff --git a/src/xdrv/xf86Wacom.h b/src/xdrv/xf86Wacom.h
index 4505bdd..019e5ac 100755
--- a/src/xdrv/xf86Wacom.h
+++ b/src/xdrv/xf86Wacom.h
@@ -297,6 +297,7 @@ struct _WacomDeviceRec
int oldThrottle; /* previous throttle value */
int oldButtons; /* previous buttons state */
int oldProximity; /* previous proximity */
+ int devReverseCount; /* Relative ReverseConvert called twice each movement*/
double speed; /* relative mode speed */
int accel; /* relative mode acceleration */
int numScreen; /* number of configured screens */
@@ -396,7 +397,6 @@ struct _WacomChannel
} valid;
int nSamples;
- LocalDevicePtr pDev; /* device associated with this channel */
WacomFilterState rawFilter;
};
@@ -481,7 +481,6 @@ struct _WacomCommonRec
int wcmForceDevice; /* force device type (used by ISD V4) */
int wcmRotate; /* rotate screen (for TabletPC) */
int wcmThreshold; /* Threshold for button pressure */
- int wcmChannelCnt; /* number of channels available */
WacomChannel wcmChannel[MAX_CHANNELS]; /* channel device state */
unsigned int wcmLinkSpeed; /* serial link speed */
@@ -600,5 +599,9 @@ void xf86WcmEvent(WacomCommonPtr common, unsigned int channel, const WacomDevice
/* dispatches data to XInput event system */
void xf86WcmSendEvents(LocalDevicePtr local, const WacomDeviceState* ds, unsigned int channel);
+/* generic area check for wcmConfig.c, xf86Wacom.c, and wcmCommon.c */
+Bool xf86WcmPointInArea(WacomToolAreaPtr area, int x, int y);
+Bool xf86WcmAreaListOverlap(WacomToolAreaPtr area, WacomToolAreaPtr list);
+
/****************************************************************************/
#endif /* __XF86WACOM_H */