diff options
author | pingc <pingc> | 2006-09-07 23:30:13 +0000 |
---|---|---|
committer | pingc <pingc> | 2006-09-07 23:30:13 +0000 |
commit | d6ceb8b0c63f0c5052d2616ead1b8928701de432 (patch) | |
tree | 9cfc709ff51c57e81a2c3413f5427a18456ace19 | |
parent | 32bd4c69f7a7bc1308fd0f3dfcffb803e4bc7a4c (diff) | |
download | xf86-input-wacom-d6ceb8b0c63f0c5052d2616ead1b8928701de432.tar.gz |
plug/unplug support for both XFree86 and Xorg
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | src/2.4.22/wacom.c | 4 | ||||
-rwxr-xr-x | src/util/xidump.c | 6 | ||||
-rwxr-xr-x | src/xdrv/wcmCommon.c | 190 | ||||
-rwxr-xr-x | src/xdrv/wcmUSB.c | 6 | ||||
-rwxr-xr-x | src/xdrv/xf86Wacom.c | 65 | ||||
-rwxr-xr-x | src/xdrv/xf86Wacom.h | 2 |
7 files changed, 164 insertions, 115 deletions
@@ -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 */ |