summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpingc <pingc>2006-09-07 23:30:13 +0000
committerpingc <pingc>2006-09-07 23:30:13 +0000
commitd6ceb8b0c63f0c5052d2616ead1b8928701de432 (patch)
tree9cfc709ff51c57e81a2c3413f5427a18456ace19
parent32bd4c69f7a7bc1308fd0f3dfcffb803e4bc7a4c (diff)
downloadxf86-input-wacom-d6ceb8b0c63f0c5052d2616ead1b8928701de432.tar.gz
plug/unplug support for both XFree86 and Xorg
-rw-r--r--ChangeLog6
-rw-r--r--src/2.4.22/wacom.c4
-rwxr-xr-xsrc/util/xidump.c6
-rwxr-xr-xsrc/xdrv/wcmCommon.c190
-rwxr-xr-xsrc/xdrv/wcmUSB.c6
-rwxr-xr-xsrc/xdrv/xf86Wacom.c65
-rwxr-xr-xsrc/xdrv/xf86Wacom.h2
7 files changed, 164 insertions, 115 deletions
diff --git a/ChangeLog b/ChangeLog
index fd4d865..af22b73 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2006-09-08 Ping Cheng <pingc@wacom.com>
+ * Fixed Graphire 4 pad/wheel bug
+ * Unified support of USB hot plug/unplug with different tablets
+ for both XFree86 and Xorg
+ * Ready to release 0.7.5-1
+
2006-08-30 Ping Cheng <pingc@wacom.com>
* Added Intuos3 4x6 support
* Updated acinclude.m4 and configure.in
diff --git a/src/2.4.22/wacom.c b/src/2.4.22/wacom.c
index 8b701f4..4b265e2 100644
--- a/src/2.4.22/wacom.c
+++ b/src/2.4.22/wacom.c
@@ -696,8 +696,8 @@ static void wacom_intuos_irq(struct urb *urb)
input_report_key(dev, BTN_MIDDLE, data[8] & 0x08);
input_report_key(dev, BTN_RIGHT, data[8] & 0x10);
/* mouse wheel is positive when rolled backwards */
- input_report_rel(dev, REL_WHEEL, (__u32)(data[8] & 0x01))
- - (__u32)((data[8] & 0x02) >> 1);
+ input_report_rel(dev, REL_WHEEL, (__u32)(data[8] & 0x01)
+ - (__u32)((data[8] & 0x02) >> 1));
/* I3 2D mouse side buttons */
if (strstr(wacom->features->name, "Intuos3"))
diff --git a/src/util/xidump.c b/src/util/xidump.c
index 9a209ea..7368234 100755
--- a/src/util/xidump.c
+++ b/src/util/xidump.c
@@ -617,7 +617,8 @@ static int CursesRun(Display* pDisp, XDeviceInfo* pDevInfo, FORMATTYPE fmt)
XDeviceButtonEvent* pBtn = (XDeviceButtonEvent*)pAny;
bDown = (pAny->type == gnInputEvent[INPUTEVENT_BTN_PRESS]);
nBtn = pBtn->button;
- if ((nBtn < 1) || (nBtn > 5)) nBtn=6;
+ while (nBtn > 5) nBtn -= 5;
+ if (nBtn < 1) nBtn=6;
snprintf(chBuf,sizeof(chBuf),"%d-%s",pBtn->button,
bDown ? "DOWN" : "UP ");
if (bDown) wacscrn_standout();
@@ -630,7 +631,8 @@ static int CursesRun(Display* pDisp, XDeviceInfo* pDevInfo, FORMATTYPE fmt)
XDeviceKeyEvent* pKey = (XDeviceKeyEvent*)pAny;
bDown = (pAny->type == gnInputEvent[INPUTEVENT_KEY_PRESS]);
nBtn = pKey->keycode - 7; /* first key is always 8 */
- if ((nBtn < 1) || (nBtn > 5)) nBtn=6;
+ while (nBtn > 5) nBtn -= 5;
+ if (nBtn < 1) nBtn=6;
snprintf(chBuf,sizeof(chBuf),"%d-%s",pKey->keycode - 7,
bDown ? "DOWN" : "UP ");
if (bDown) wacscrn_standout();
diff --git a/src/xdrv/wcmCommon.c b/src/xdrv/wcmCommon.c
index 840b9f1..178f7a9 100755
--- a/src/xdrv/wcmCommon.c
+++ b/src/xdrv/wcmCommon.c
@@ -410,7 +410,8 @@ static void sendAButton(LocalDevicePtr local, int button, int mask,
local->dev->button->map [button_idx] = button & AC_CODE;
xf86PostButtonEvent(local->dev, is_absolute, button_idx,
- mask != 0,0,naxes,rx,ry,rz,v3,v4,v5);
+ mask != 0,0,naxes,rx,ry,rz,v3,v4,v5);
+
break;
case AC_KEY:
@@ -446,16 +447,18 @@ static void sendAButton(LocalDevicePtr local, int button, int mask,
{
/* Left button down */
xf86PostButtonEvent(local->dev, is_absolute,
- button_idx, 1,0,naxes,rx,ry,rz,v3,v4,v5);
+ button_idx, 1,0,naxes,
+ rx,ry,rz,v3,v4,v5);
/* Left button up */
xf86PostButtonEvent(local->dev, is_absolute,
- button_idx, 0,0,naxes,rx,ry,rz,v3,v4,v5);
+ button_idx,0,0,naxes,
+ rx,ry,rz, v3,v4,v5);
}
/* Left button down/up upon mask is 1/0 */
xf86PostButtonEvent(local->dev, is_absolute, button_idx,
- mask != 0,0,naxes,rx,ry,rz,v3,v4,v5);
+ mask != 0,0,naxes,rx,ry,rz,v3,v4,v5);
break;
}
@@ -652,39 +655,13 @@ void xf86WcmSendEvents(LocalDevicePtr local, const WacomDeviceState* ds, unsigne
v3 = ((id<<16) & 0xffff0000) | (((short)v3)& 0xffff);
v4 = (serial & 0xffff0000) | (((short)v4)& 0xffff);
v5 = ((serial<<16) & 0xffff0000) | (((short)v5)& 0xffff);
- }
- else
- {
- if (v3 || v4 || buttons)
- {
- xf86PostProximityEvent(local->dev, 1, 0, naxes,
- rx, ry, rz, v3, v4, v5);
- xf86PostMotionEvent(local->dev, is_absolute,
- 0, naxes, rx, ry, rz, v3, v4, v5);
- if (priv->oldButtons != buttons)
- {
- xf86WcmSendButtons(local,buttons,rx,ry,rz,v3,v4,v5);
- }
- }
- else
+ /* coordinates are ready we can send events */
+ if (is_proximity)
{
- if (priv->oldButtons != buttons)
- xf86WcmSendButtons(local,0,rx,ry,rz,v3,v4,v5);
- xf86PostProximityEvent(local->dev, 0, 0, naxes,
- rx, ry, rz, v3, v4, v5);
- }
- priv->oldButtons = buttons;
- priv->oldStripX = ds->stripx;
- priv->oldStripY = ds->stripy;
- }
-
- /* coordinates are ready we can send events */
- if (is_proximity)
- {
- /* for multiple monitor support, we need to set the proper
- * screen and modify the axes before posting events */
- if(!(priv->flags & BUTTONS_ONLY_FLAG) )
+ /* for multiple monitor support, we need to set the proper
+ * screen and modify the axes before posting events */
+ if(!(priv->flags & BUTTONS_ONLY_FLAG))
{
xf86WcmSetScreen(local, &rx, &ry);
}
@@ -694,27 +671,74 @@ void xf86WcmSendEvents(LocalDevicePtr local, const WacomDeviceState* ds, unsigne
rx *= priv->factorY / priv->factorX;
/* don't emit proximity events if device does not support proximity */
- if ((local->dev->proximity &&
- !priv->oldProximity && !(priv->flags & BUTTONS_ONLY_FLAG)))
+ if ((local->dev->proximity && !priv->oldProximity))
xf86PostProximityEvent(local->dev, 1, 0, naxes,
- rx, ry, rz, v3, v4, v5);
+ rx, ry, rz, v3, v4, v5);
- xf86PostMotionEvent(local->dev, is_absolute,
- 0, naxes, rx, ry, rz, v3, v4, v5);
+ if(!(priv->flags & BUTTONS_ONLY_FLAG))
+ xf86PostMotionEvent(local->dev, is_absolute,
+ 0, naxes, rx, ry, rz, v3, v4, v5);
- if (priv->oldButtons != buttons)
+ if (priv->oldButtons != buttons)
+ {
+ xf86WcmSendButtons(local,buttons,rx,ry,rz,v3,v4,v5);
+ }
+
+ /* simulate button 4 and 5 for relative wheel */
+ if ( ds->relwheel )
+ {
+ int fakeButton = ds->relwheel > 0 ? 5 : 4;
+ int i;
+ for (i=0; i<abs(ds->relwheel); i++)
+ {
+ xf86PostButtonEvent(local->dev, is_absolute,
+ fakeButton, 1, 0, naxes, rx, ry, rz,
+ v3, v4, v5);
+ xf86PostButtonEvent(local->dev, is_absolute,
+ fakeButton, 0, 0, naxes, rx, ry, rz,
+ v3, v4, v5);
+ }
+ }
+ }
+
+ /* not in proximity */
+ else
+ {
+ buttons = 0;
+
+ /* 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);
+ if (priv->oldProximity && local->dev->proximity)
+ xf86PostProximityEvent(local->dev,0,0,naxes,rx,ry,rz,v3,v4,v5);
+ } /* not in proximity */
+ }
+ else
+ {
+ if ((v3 || v4 || buttons || ds->relwheel) && !priv->oldProximity)
{
- xf86WcmSendButtons(local,buttons,rx,ry,rz,v3,v4,v5);
+ xf86PostProximityEvent(local->dev, 1, 0, naxes,
+ rx, ry, rz, v3, v4, v5);
+ is_proximity = 1;
}
+ if ( v3 || v4 )
+ xf86PostMotionEvent(local->dev, is_absolute,
+ 0, naxes, rx, ry, rz, v3, v4, v5);
+ if (priv->oldButtons != buttons)
+ xf86WcmSendButtons(local, buttons,
+ rx, ry, rz, v3, v4, v5);
- /* simulate button 4 and 5 for relative wheel */
if ( ds->relwheel )
{
int fakeButton = ds->relwheel > 0 ? 5 : 4;
- int i;
+ int i;
for (i=0; i<abs(ds->relwheel); i++)
{
+ /* Dynamically modify the button map
+ */
+ local->dev->button->map [fakeButton] = fakeButton;
xf86PostButtonEvent(local->dev, is_absolute,
fakeButton, 1, 0, naxes, rx, ry, rz,
v3, v4, v5);
@@ -723,21 +747,13 @@ void xf86WcmSendEvents(LocalDevicePtr local, const WacomDeviceState* ds, unsigne
v3, v4, v5);
}
}
+ if ( !v3 && !v4 && !buttons)
+ {
+ xf86PostProximityEvent(local->dev, 0, 0, naxes,
+ rx, ry, rz, v3, v4, v5);
+ is_proximity = 0;
+ }
}
-
- /* not in proximity */
- else
- {
- buttons = 0;
-
- /* 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);
- if (priv->oldProximity && local->dev->proximity)
- xf86PostProximityEvent(local->dev,0,0,naxes,rx,ry,rz,v3,v4,v5);
- } /* not in proximity */
-
priv->oldProximity = is_proximity;
priv->oldButtons = buttons;
priv->oldWheel = wheel;
@@ -970,6 +986,45 @@ void xf86WcmEvent(WacomCommonPtr common, unsigned int channel,
resetSampleCounter(pChannel);
}
+static int idtotype(int id)
+{
+ int type = CURSOR_ID;
+
+ /* tools with id, such as Intuos series and Cintiq 21UX */
+ switch (id)
+ {
+ case 0x812: /* Inking pen */
+ case 0x801: /* Intuos3 Inking pen */
+ case 0x012:
+ case 0x822: /* Pen */
+ case 0x842:
+ case 0x852:
+ case 0x823: /* Intuos3 Grip Pen */
+ case 0x813: /* Intuos3 Classic Pen */
+ case 0x885: /* Intuos3 Marker Pen */
+ case 0x022:
+ case 0x832: /* Stroke pen */
+ case 0x032:
+ case 0xd12: /* Airbrush */
+ case 0x912:
+ case 0x112:
+ case 0x913: /* Intuos3 Airbrush */
+ type = STYLUS_ID;
+ break;
+ case 0x82a: /* Eraser */
+ case 0x85a:
+ case 0x91a:
+ case 0xd1a:
+ case 0x0fa:
+ case 0x82b: /* Intuos3 Grip Pen Eraser */
+ case 0x81b: /* Intuos3 Classic Pen Eraser */
+ case 0x91b: /* Intuos3 Airbrush Eraser */
+ type = ERASER_ID;
+ break;
+ }
+ return type;
+}
+
static void commonDispatchDevice(WacomCommonPtr common, unsigned int channel,
const WacomChannelPtr pChannel)
{
@@ -983,8 +1038,23 @@ static void commonDispatchDevice(WacomCommonPtr common, unsigned int channel,
if (!ds->device_type)
{
- /* defaults to cursor if tool is on the tablet when X starts */
- ds->device_type = CURSOR_ID;
+ /* Tool may be on the tablet when X starts.
+ * Figure out device type by device id
+ */
+ switch (ds->device_id)
+ {
+ case STYLUS_DEVICE_ID:
+ ds->device_type = STYLUS_ID;
+ break;
+ case ERASER_DEVICE_ID:
+ ds->device_type = ERASER_ID;
+ break;
+ case CURSOR_DEVICE_ID:
+ ds->device_type = CURSOR_ID;
+ break;
+ default:
+ ds->device_type = idtotype(ds->device_id);
+ }
ds->proximity = 1;
if (ds->serial_num)
for (idx=0; idx<common->wcmNumDevices; idx++)
diff --git a/src/xdrv/wcmUSB.c b/src/xdrv/wcmUSB.c
index e2f48d0..a610e8f 100755
--- a/src/xdrv/wcmUSB.c
+++ b/src/xdrv/wcmUSB.c
@@ -906,12 +906,6 @@ static void usbParseChannel(WacomCommonPtr common, int channel, int serial)
if (ds->device_type == CURSOR_ID && !ds->proximity)
common->wcmCursorProxoutDist = PROXOUT_DISTANCE;
- /* Disable proximity on pads with just one channel and a pseudo second
- * channel (Intuos3 or Graphire4) when no pad buttons are pressed.
- */
- if (common->wcmChannelCnt == 1 && channel == 1 && !ds->buttons)
- ds->proximity = 0;
-
/* DTF720 doesn't support eraser */
if (common->tablet_id == 0xC0 && ds->device_type == ERASER_ID)
{
diff --git a/src/xdrv/xf86Wacom.c b/src/xdrv/xf86Wacom.c
index 964ef7e..8181c35 100755
--- a/src/xdrv/xf86Wacom.c
+++ b/src/xdrv/xf86Wacom.c
@@ -427,8 +427,9 @@ static int xf86WcmDevOpen(DeviceIntPtr pWcm)
DBG(10,ErrorF("xf86WcmDevOpen\n"));
- /* Drop read error counter */
- common->wcmReadErrorCount = 0;
+ /* Device has been open */
+ if (priv->wcmDevOpenCount)
+ return TRUE;
/* open file, if not already open */
if (common->fd_refs == 0)
@@ -472,36 +473,12 @@ static int xf86WcmDevOpen(DeviceIntPtr pWcm)
static void xf86WcmDevReadInput(LocalDevicePtr local)
{
- int loop=0, i;
+ int loop=0;
#define MAX_READ_LOOPS 10
WacomDevicePtr priv = (WacomDevicePtr)local->private;
WacomCommonPtr common = priv->common;
- /* If there were read errors for USB tablet, it means the device was
- * disconnected or changed. The only way to make the tablet alive again
- * is to reconnect or reregister it.
- */
- if (common->wcmReadErrorCount > 0)
- {
- if (common->wcmDevCls == &gWacomUSBDevice)
- {
- usbWcmInit(local);
- usbWcmGetRanges(local);
- xf86WcmRegisterX11Devices(local);
- /* reinitialize all the other defined tools on the same port */
- for (i=0; i<common->wcmNumDevices; i++)
- {
- if (((WacomDevicePtr)(common->wcmDevices[i]->private))->common == common
- && common->wcmDevices[i] != local)
- xf86WcmRegisterX11Devices(common->wcmDevices[i]);
- }
- common->wcmReadErrorCount = 0;
- return;
- }
- common->wcmReadErrorCount = 0;
- }
-
/* move data until we exhaust the device */
for (loop=0; loop < MAX_READ_LOOPS; ++loop)
{
@@ -523,23 +500,11 @@ void xf86WcmReadPacket(LocalDevicePtr local)
{
WacomCommonPtr common = ((WacomDevicePtr)(local->private))->common;
int len, pos, cnt, remaining;
- short sID[4];
if (!common->wcmModel) return;
remaining = sizeof(common->buffer) - common->bufpos;
- if (common->wcmDevCls == &gWacomUSBDevice && !common->wcmReadErrorCount)
- {
- ioctl(local->fd, EVIOCGID, sID);
-
- if (common->tablet_id != sID[2])
- {
- common->wcmReadErrorCount++;
- DBG(10, ErrorF("Wacom device ID changed from %d to %d\n", common->tablet_id, sID[2]));
- }
- }
-
DBG(10, ErrorF("xf86WcmDevReadPacket: device=%s fd=%d "
"pos=%d remaining=%d\n",
common->wcmDevice, local->fd,
@@ -551,11 +516,14 @@ void xf86WcmReadPacket(LocalDevicePtr local)
if (len <= 0)
{
- if (common->wcmDevCls == &gWacomUSBDevice)
- {
- common->wcmReadErrorCount++;
- xf86WcmWait(500);
- }
+ /* In case of error, we assume the device has been
+ * disconnected. So we close it and iterate over all
+ * wcmDevices to actually close associated devices. */
+ for (cnt=0; cnt<common->wcmNumDevices; cnt++)
+ {
+ if (common->wcmDevices[cnt]->fd >= 0)
+ xf86WcmDevProc(common->wcmDevices[cnt]->dev, DEVICE_OFF);
+ }
ErrorF("Error reading wacom device : %s\n", strerror(errno));
return;
}
@@ -658,14 +626,22 @@ static int xf86WcmDevProc(DeviceIntPtr pWcm, int what)
* register even a 'pad' which doesn't "SendCoreEvents"
*/
case DEVICE_INIT:
+ priv->wcmDevOpenCount = 0;
if (!xf86WcmDevOpen(pWcm))
{
DBG(1, ErrorF("xf86WcmProc INIT FAILED\n"));
return !Success;
}
+ priv->wcmDevOpenCount++;
break;
case DEVICE_ON:
+ if (!xf86WcmDevOpen(pWcm))
+ {
+ DBG(1, ErrorF("xf86WcmProc ON FAILED\n"));
+ return !Success;
+ }
+ priv->wcmDevOpenCount++;
xf86AddEnabledDevice(local);
pWcm->public.on = TRUE;
break;
@@ -678,6 +654,7 @@ static int xf86WcmDevProc(DeviceIntPtr pWcm, int what)
xf86WcmDevClose(local);
}
pWcm->public.on = FALSE;
+ priv->wcmDevOpenCount = 0;
break;
default:
diff --git a/src/xdrv/xf86Wacom.h b/src/xdrv/xf86Wacom.h
index 54e9f2d..8b24648 100755
--- a/src/xdrv/xf86Wacom.h
+++ b/src/xdrv/xf86Wacom.h
@@ -310,6 +310,7 @@ struct _WacomDeviceRec
int tvoffsetX; /* X edge offset for TwinView setup */
int tvoffsetY; /* Y edge offset for TwinView setup */
int tvResolution[4]; /* twinview screens' resultion */
+ int wcmDevOpenCount; /* Device open count */
/* JEJ - throttle */
int throttleStart; /* time in ticks for last wheel movement */
@@ -492,7 +493,6 @@ struct _WacomCommonRec
int wcmGimp; /* support Gimp on Xinerama Enabled multi-monitor desktop */
int wcmMMonitor; /* disable/enable moving across screens in multi-monitor desktop */
int wcmTPCButton; /* set Tablet PC button on/off */
- int wcmReadErrorCount; /* Read error count */
int wcmCursorProxoutDist; /* Max mouse distance for proxy-out max/256 units */
int wcmCursorProxoutHyst; /* Proxy-out distance hysteresis in max/256 units */