1 /*****************************************************************************
4 ** Copyright (C) 2002 - 2004 - John E. Joganic
5 ** Copyright (C) 2003 - 2009 - Ping Cheng
7 ** This program is free software; you can redistribute it and/or
8 ** modify it under the terms of the GNU General Public License
9 ** as published by the Free Software Foundation; either version 2
10 ** of the License, or (at your option) any later version.
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ** GNU General Public License for more details.
17 ** You should have received a copy of the GNU General Public License
18 ** along with this program; if not, write to the Free Software
19 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 ****************************************************************************/
31 #include <sys/ioctl.h>
34 /*****************************************************************************
35 ** Begin USB Linux Input Subsystem
36 *****************************************************************************/
38 #ifdef WCM_ENABLE_LINUXINPUT
39 #include <linux/input.h>
46 #define MSC_SERIAL 0x00
49 #ifndef BTN_TOOL_DOUBLETAP
50 #define BTN_TOOL_DOUBLETAP 0x14d
53 /*****************************************************************************
55 *****************************************************************************/
57 /* from linux/input.h */
58 #define BITS_PER_LONG (sizeof(long) * 8)
59 #define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
60 #define BIT(x) (1UL<<((x)%BITS_PER_LONG))
61 #define LONG(x) ((x)/BITS_PER_LONG)
62 #define ISBITSET(x,y) ((x)[LONG(y)] & BIT(y))
64 #define MAX_CHANNELS 2
65 #define MAX_USB_EVENTS 32
67 /*****************************************************************************
69 *****************************************************************************/
71 typedef struct _USBSUBTYPE USBSUBTYPE;
72 typedef struct _USBDEVICE USBDEVICE;
73 typedef struct _USBVENDOR USBVENDOR;
79 unsigned int uSubType;
80 unsigned int uProduct;
88 USBSUBTYPE* pSubTypes;
89 unsigned int uChannelCnt;
100 /*****************************************************************************
102 *****************************************************************************/
104 typedef struct _USBTABLET USBTABLET;
108 WACOMTABLET_PRIV tablet;
113 USBSUBTYPE* pSubType;
116 WACOMSTATE state[MAX_CHANNELS];
117 int nToolProx[MAX_CHANNELS];
121 struct input_event events[MAX_USB_EVENTS];
124 /*****************************************************************************
125 ** Autodetect pad key codes
126 *****************************************************************************/
128 static unsigned short padkey_codes [] =
130 BTN_0, BTN_1, BTN_2, BTN_3, BTN_4,
131 BTN_5, BTN_6, BTN_7, BTN_8, BTN_9,
132 BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z,
133 BTN_BASE, BTN_BASE2, BTN_BASE3,
134 BTN_BASE4, BTN_BASE5, BTN_BASE6,
135 BTN_TL, BTN_TR, BTN_TL2, BTN_TR2, BTN_SELECT
138 int gPadKeys [WACOMBUTTON_MAX];
141 /*****************************************************************************
143 *****************************************************************************/
145 static void USBClose(WACOMTABLET_PRIV* pTablet);
146 static WACOMMODEL USBGetModel(WACOMTABLET_PRIV* pTablet);
147 static const char* USBGetVendorName(WACOMTABLET_PRIV* pTablet);
148 static const char* USBGetClassName(WACOMTABLET_PRIV* pTablet);
149 static const char* USBGetDeviceName(WACOMTABLET_PRIV* pTablet);
150 static const char* USBGetSubTypeName(WACOMTABLET_PRIV* pTablet);
151 static const char* USBGetModelName(WACOMTABLET_PRIV* pTablet);
152 static int USBGetROMVer(WACOMTABLET_PRIV* pTablet, int* pnMajor,
153 int* pnMinor, int* pnRelease);
154 static int USBGetCaps(WACOMTABLET_PRIV* pTablet);
155 static int USBGetState(WACOMTABLET_PRIV* pTablet, WACOMSTATE* pState);
156 static int USBGetFD(WACOMTABLET_PRIV* pTablet);
157 static int USBReadRaw(WACOMTABLET_PRIV* pTablet, unsigned char* puchData,
159 static int USBParseData(WACOMTABLET_PRIV* pTablet,
160 const unsigned char* puchData, unsigned int uLength,
163 static int USBFindModel(USBTABLET* pUSB, unsigned int uVendor,
164 unsigned int uProduct);
165 static int USBIdentifyModel(USBTABLET* pUSB);
167 /*****************************************************************************
169 *****************************************************************************/
171 static USBSUBTYPE xPenPartner[] =
173 { "MODEL_PP_0405", "Wacom PenPartner", 1, 0x00 },
177 static USBSUBTYPE xGraphire[] =
179 { "ET_0405", "Wacom Graphire", 1, 0x10 },
183 static USBSUBTYPE xGraphire2[] =
185 { "ET_0405", "Wacom Graphire2 4x5", 1, 0x11 },
186 { "ET_0507", "Wacom Graphire2 5x7", 2, 0x12 },
190 static USBSUBTYPE xGraphire3[] =
192 { "ET_0405", "Wacom Graphire3 4x5", 1, 0x13 },
193 { "ET_0608", "Wacom Graphire3 6x8", 2, 0x14 },
197 static USBSUBTYPE xGraphire4[] =
199 { "CTE_440", "Wacom Graphire4 4x5", 1, 0x15 },
200 { "CTE_640", "Wacom Graphire4 6x8", 2, 0x16 },
204 static USBSUBTYPE xIntuos[] =
206 { "GD_0405-U", "Wacom Intuos 4x5", 1, 0x20 },
207 { "GD_0608-U", "Wacom Intuos 6x8", 2, 0x21 },
208 { "GD_0912-U", "Wacom Intuos 9x12", 3, 0x22 },
209 { "GD_1212-U", "Wacom Intuos 12x12", 4, 0x23 },
210 { "GD_1218-U", "Wacom Intuos 12x18", 5, 0x24 },
214 static USBSUBTYPE xCintiq[] =
216 { "PL400", "Wacom PL400", 1, 0x30 },
217 { "PL500", "Wacom PL500", 2, 0x31 },
218 { "PL600", "Wacom PL600", 3, 0x32 },
219 { "PL600SX", "Wacom PL600SX", 4, 0x33 },
220 { "PL550", "Wacom PL550", 5, 0x34 },
221 { "PL800", "Wacom PL800", 6, 0x35 },
222 { "PL700", "Wacom PL700", 7, 0x37 },
223 { "PL510", "Wacom PL510", 8, 0x38 },
224 { "DTU710", "Wacom PL710", 9, 0x39 },
225 { "DTF720", "Wacom DTF720", 10, 0xC0 },
226 { "DTF521", "Wacom DTF521", 11, 0xC4 },
227 { "DTU1931", "Wacom DTU1931", 12, 0xC7 },
228 { "DTU2231", "Wacom DTU2231", 13, 0xCE },
229 { "DTU1631", "Wacom DTU1631", 14, 0xF0 },
233 static USBSUBTYPE xIntuos2[] =
235 { "XD-0405-U", "Wacom Intuos2 4x5", 1, 0x41 },
236 { "XD-0608-U", "Wacom Intuos2 6x8", 2, 0x42 },
237 { "XD-0912-U", "Wacom Intuos2 9x12", 3, 0x43 },
238 { "XD-1212-U", "Wacom Intuos2 12x12", 4, 0x44 },
239 { "XD-1218-U", "Wacom Intuos2 12x18", 5, 0x45 },
241 /* fix for I2 6x8's reporting as 0x47 */
242 { "XD-0608-U", "Wacom Intuos2 6x8", 2, 0x47 },
247 static USBSUBTYPE xVolito[] =
249 { "MODEL-VOL", "Wacom Volito", 1, 0x60 },
253 static USBSUBTYPE xVolito2[] =
255 { "FT-0203-U", "Wacom PenStation", 1, 0x61 },
256 { "CTF-420-U", "Wacom Volito2 4x5", 2, 0x62 },
257 { "CTF-220-U", "Wacom Volito2 2x3", 3, 0x63 },
258 { "CTF-421-U", "Wacom PenPartner2", 4, 0x64 },
259 { "CTF_430-U", "Wacom Bamboo1", 5, 0x69 },
263 static USBSUBTYPE xBamboo[] =
265 { "MTE_450", "Wacom Bamboo", 1, 0x65 },
266 { "CTE_450", "Wacom BambooFun 4x5", 2, 0x17 },
267 { "CTE_650", "Wacom BambooFun 6x8", 3, 0x18 },
268 { "CTE_631", "Wacom Bamboo1 Medium", 4, 0x19 },
272 static USBSUBTYPE xCintiqPartner[] =
274 { "PTU-600", "Wacom Cintiq Partner", 1, 0x03 },
278 static USBSUBTYPE xTabletPC[] =
280 { "TPC-090", "Wacom Tablet PC90", 1, 0x90 },
281 { "TPC-093", "Wacom Tablet PC93", 2, 0x93 },
282 { "TPC-09A", "Wacom Tablet PC9A", 3, 0x9A },
286 static USBSUBTYPE xCintiqV5[] =
288 { "DTZ-21ux", "Wacom Cintiq 21UX", 1, 0x3F },
289 { "DTZ-20wsx", "Wacom Cintiq 20WSX", 2, 0xC5 },
290 { "DTZ-12wx", "Wacom Cintiq 12WX", 3, 0xC6 },
291 { "DTZ-21ux2", "Wacom Cintiq 21UX2", 4, 0xCC },
295 static USBSUBTYPE xIntuos3[] =
297 { "PTZ-430", "Wacom Intuos3 4x5", 1, 0xB0 },
298 { "PTZ-630", "Wacom Intuos3 6x8", 2, 0xB1 },
299 { "PTZ-930", "Wacom Intuos3 9x12", 3, 0xB2 },
300 { "PTZ-1230", "Wacom Intuos3 12x12", 4, 0xB3 },
301 { "PTZ-1231W", "Wacom Intuos3 12x19", 5, 0xB4 },
302 { "PTZ-631W", "Wacom Intuos3 6x11", 6, 0xB5 },
303 { "PTZ-431W", "Wacom Intuos3 4x6", 7, 0xB7 },
307 static USBSUBTYPE xIntuos4[] =
309 { "PTK-440", "Wacom Intuos4 4x6", 1, 0xB8 },
310 { "PTK-640", "Wacom Intuos4 6x9", 2, 0xB9 },
311 { "PTK-840", "Wacom Intuos4 8x13", 3, 0xBA },
312 { "PTK-1240", "Wacom Intuos4 12x19", 4, 0xBB },
313 { "PTK-540WL", "Wacom Intuos4 WLUSB", 5, 0xBC },
314 { "PTK-540WL", "Wacom Intuos4 WLBT", 6, 0xBD },
318 static USBDEVICE xWacomDevices[] =
320 { "pp", "PenPartner", WACOMDEVICE_PENPARTNER, xPenPartner, 1 },
321 { "gr", "Graphire", WACOMDEVICE_GRAPHIRE, xGraphire, 1 },
322 { "gr2", "Graphire2", WACOMDEVICE_GRAPHIRE2, xGraphire2, 1 },
323 { "gr3", "Graphire3", WACOMDEVICE_GRAPHIRE3, xGraphire3, 1 },
324 { "gr4", "Graphire4", WACOMDEVICE_GRAPHIRE4, xGraphire4, 2 },
325 { "int", "Intuos", WACOMDEVICE_INTUOS, xIntuos, 2 },
326 { "int2", "Intuos2", WACOMDEVICE_INTUOS2, xIntuos2, 2 },
327 { "int3", "Intuos3", WACOMDEVICE_INTUOS3, xIntuos3, 2 },
328 { "int4", "Intuos4", WACOMDEVICE_INTUOS3, xIntuos4, 2 },
329 { "ctq", "Cintiq (V5)", WACOMDEVICE_CINTIQV5, xCintiqV5, 2 },
330 { "pl", "Cintiq (PL)", WACOMDEVICE_CINTIQ, xCintiq, 1 },
331 { "ptu", "Cintiq Partner (PTU)", WACOMDEVICE_PTU, xCintiqPartner, 1 },
332 { "vol", "Volito", WACOMDEVICE_VOLITO, xVolito, 1 },
333 { "vol2", "Volito2", WACOMDEVICE_VOLITO2, xVolito2, 1 },
334 { "mo", "Bamboo", WACOMDEVICE_MO, xBamboo, 2 },
335 { "tpc", "Tablet PC", WACOMDEVICE_TPC, xTabletPC, 1 },
339 static USBVENDOR xVendors[] =
341 { "wacom", "Wacom", WACOMVENDOR_WACOM, xWacomDevices },
345 /*****************************************************************************
347 *****************************************************************************/
351 void (*pfnFree)(void* pv);
354 static void USBFreeDeviceList(void* pv)
356 DEVLIST_INTERNAL* pInt = ((DEVLIST_INTERNAL*)pv) - 1;
360 int WacomGetSupportedUSBDeviceList(WACOMDEVICEREC** ppList, int* pnSize)
362 int nIndex=0, nCnt=0;
363 DEVLIST_INTERNAL* pInt;
366 WACOMDEVICEREC* pRec;
368 if (!ppList || !pnSize) { errno = EINVAL; return 1; }
370 /* for each vendor, count up devices */
371 for (pVendor=xVendors; pVendor->pszName; ++pVendor)
373 /* count up devices */
374 for (pDev=pVendor->pDevices; pDev->pszName; ++pDev, ++nCnt) ;
377 /* allocate enough memory to hold internal structure and all records */
378 pInt = (DEVLIST_INTERNAL*)malloc(sizeof(DEVLIST_INTERNAL) +
379 (sizeof(WACOMDEVICEREC) * nCnt));
381 pInt->pfnFree = USBFreeDeviceList;
382 pRec = (WACOMDEVICEREC*)(pInt + 1);
384 /* for each vendor, add devices */
385 for (pVendor=xVendors; pVendor->pszName; ++pVendor)
387 for (pDev=pVendor->pDevices; pDev->pszName; ++pDev, ++nIndex)
389 pRec[nIndex].pszName = pDev->pszName;
390 pRec[nIndex].pszDesc = pDev->pszDesc;
391 pRec[nIndex].pszVendorName = pVendor->pszName;
392 pRec[nIndex].pszVendorDesc = pVendor->pszDesc;
393 pRec[nIndex].pszClass = "usb";
394 pRec[nIndex].model.uClass = WACOMCLASS_USB;
395 pRec[nIndex].model.uVendor = pVendor->uVendor;
396 pRec[nIndex].model.uDevice = pDev->uDevice;
397 pRec[nIndex].model.uSubType = 0;
400 assert(nIndex == nCnt);
407 unsigned int WacomGetUSBDeviceFromName(const char* pszName)
412 if (!pszName) { errno = EINVAL; return 0; }
414 /* for each vendor, look for device */
415 for (pVendor=xVendors; pVendor->pszName; ++pVendor)
417 /* count up devices */
418 for (pDev=pVendor->pDevices; pDev->pszName; ++pDev)
420 if (strcasecmp(pszName,pDev->pszName) == 0)
421 return pDev->uDevice;
429 WACOMTABLET WacomOpenUSBTablet(WACOMENGINE hEngine, int fd, WACOMMODEL* pModel)
431 USBTABLET* pUSB = NULL;
433 /* Allocate tablet */
434 pUSB = (USBTABLET*)malloc(sizeof(USBTABLET));
435 memset(pUSB,0,sizeof(*pUSB));
436 pUSB->tablet.Close = USBClose;
437 pUSB->tablet.GetModel = USBGetModel;
438 pUSB->tablet.GetVendorName = USBGetVendorName;
439 pUSB->tablet.GetClassName = USBGetClassName;
440 pUSB->tablet.GetDeviceName = USBGetDeviceName;
441 pUSB->tablet.GetSubTypeName = USBGetSubTypeName;
442 pUSB->tablet.GetModelName = USBGetModelName;
443 pUSB->tablet.GetROMVer = USBGetROMVer;
444 pUSB->tablet.GetCaps = USBGetCaps;
445 pUSB->tablet.GetState = USBGetState;
446 pUSB->tablet.GetFD = USBGetFD;
447 pUSB->tablet.ReadRaw = USBReadRaw;
448 pUSB->tablet.ParseData = USBParseData;
449 pUSB->hEngine = hEngine;
452 /* Identify and initialize the model */
453 if (USBIdentifyModel(pUSB))
455 WacomLog(pUSB->hEngine,WACOMLOGLEVEL_ERROR,
456 "Failed to identify model: %s",strerror(errno));
461 return (WACOMTABLET)pUSB;
464 /*****************************************************************************
466 *****************************************************************************/
468 static void USBClose(WACOMTABLET_PRIV* pTablet)
470 USBTABLET* pUSB = (USBTABLET*)pTablet;
475 static WACOMMODEL USBGetModel(WACOMTABLET_PRIV* pTablet)
477 WACOMMODEL model = { 0 };
478 USBTABLET* pUSB = (USBTABLET*)pTablet;
479 model.uClass = WACOMCLASS_USB;
480 model.uVendor = pUSB->pVendor->uVendor;
481 model.uDevice = pUSB->pDevice->uDevice;
482 model.uSubType = pUSB->pSubType->uSubType;
486 static int USBGetRange(USBTABLET* pUSB, unsigned long* pBits, int nAbsField,
491 if (!ISBITSET(pBits,nAbsField))
493 if (ioctl(pUSB->fd, EVIOCGABS(nAbsField), nAbs) != 0)
496 pUSB->state[0].values[uField].nMin = nAbs[1];
497 pUSB->state[0].values[uField].nMax = nAbs[2];
498 pUSB->state[0].uValid |= BIT(uField);
502 static int USBFindModel(USBTABLET* pUSB, unsigned int uVendor,
503 unsigned int uProduct)
505 USBVENDOR* pVendor = NULL;
506 USBDEVICE* pDev = NULL;
507 USBSUBTYPE* pSub = NULL;
509 static USBSUBTYPE xUnkSub[] =
511 { "UNKNOWN", "Unknown", 1, 0x00 },
515 static USBDEVICE xUnkDev[] =
517 { "unk", "Unknown", WACOMDEVICE_UNKNOWN, xUnkSub, MAX_CHANNELS },
521 static USBVENDOR xUnkVendor =
522 { "unknown", "Unknown", WACOMVENDOR_UNKNOWN, xUnkDev };
524 for (pVendor=xVendors; pVendor->pszName; ++pVendor)
526 if (pVendor->uVendor == uVendor)
528 for (pDev=pVendor->pDevices; pDev->pszName; ++pDev)
530 for (pSub=pDev->pSubTypes; pSub->pszName; ++pSub)
532 if (pSub->uProduct == uProduct)
534 pUSB->pVendor = pVendor;
535 pUSB->pDevice = pDev;
536 pUSB->pSubType = pSub;
542 /* only one vendor of this type, so we're done */
548 pUSB->pVendor = &xUnkVendor;
549 pUSB->pDevice = pUSB->pVendor->pDevices;
550 pUSB->pSubType = pUSB->pDevice->pSubTypes;
554 static int USBIdentifyModel(USBTABLET* pUSB)
558 unsigned int uVendor, uProduct;
559 unsigned long evbits[NBITS(EV_MAX)];
560 unsigned long absbits[NBITS(ABS_MAX)];
561 unsigned long relbits[NBITS(REL_MAX)];
562 unsigned long keybits[NBITS(KEY_MAX)];
564 /* Get device name and id */
565 if (ioctl(pUSB->fd,EVIOCGID,sID) < 0)
568 /* initialize state structure */
569 pUSB->state[0].uValueCnt = WACOMFIELD_MAX;
571 /* Get event types supported */
572 nCnt = ioctl(pUSB->fd,EVIOCGBIT(0 /*EV*/,sizeof(evbits)),evbits);
575 WacomLog(pUSB->hEngine,WACOMLOGLEVEL_ERROR,
576 "Failed to CGBIT ev: %s",strerror(errno));
579 assert(nCnt == sizeof(evbits));
581 /* absolute events */
582 if (ISBITSET(evbits,EV_ABS))
584 nCnt = ioctl(pUSB->fd,EVIOCGBIT(EV_ABS,sizeof(absbits)),absbits);
587 WacomLog(pUSB->hEngine,WACOMLOGLEVEL_ERROR,
588 "Failed to CGBIT abs: %s",strerror(errno));
592 /* the following line has problem on Debian systems
593 assert(nCnt == sizeof(absbits));
596 if (USBGetRange(pUSB,absbits,ABS_X,WACOMFIELD_POSITION_X) ||
597 USBGetRange(pUSB,absbits,ABS_Y,WACOMFIELD_POSITION_Y) ||
598 USBGetRange(pUSB,absbits,ABS_RZ,WACOMFIELD_ROTATION_Z) ||
599 USBGetRange(pUSB,absbits,ABS_DISTANCE,WACOMFIELD_DISTANCE) ||
600 USBGetRange(pUSB,absbits,ABS_PRESSURE,WACOMFIELD_PRESSURE) ||
601 USBGetRange(pUSB,absbits,ABS_TILT_X,WACOMFIELD_TILT_X) ||
602 USBGetRange(pUSB,absbits,ABS_TILT_Y,WACOMFIELD_TILT_Y) ||
603 USBGetRange(pUSB,absbits,ABS_WHEEL,WACOMFIELD_ABSWHEEL) ||
604 USBGetRange(pUSB,absbits,ABS_THROTTLE,WACOMFIELD_THROTTLE))
609 /* relative events */
610 if (ISBITSET(evbits,EV_REL))
612 nCnt = ioctl(pUSB->fd,EVIOCGBIT(EV_REL,sizeof(relbits)),relbits);
615 WacomLog(pUSB->hEngine,WACOMLOGLEVEL_ERROR,
616 "Failed to CGBIT rel: %s",strerror(errno));
619 assert(nCnt == sizeof(relbits));
621 if (ISBITSET(relbits,REL_WHEEL))
623 pUSB->state[0].uValid |= BIT(WACOMFIELD_RELWHEEL);
624 pUSB->state[0].values[WACOMFIELD_RELWHEEL].nMin = -1;
625 pUSB->state[0].values[WACOMFIELD_RELWHEEL].nMax = 1;
631 if (ISBITSET(evbits,EV_KEY))
633 nCnt = ioctl(pUSB->fd,EVIOCGBIT(EV_KEY,sizeof(keybits)),keybits);
636 WacomLog(pUSB->hEngine,WACOMLOGLEVEL_ERROR,
637 "Failed to CGBIT key: %s",strerror(errno));
640 assert(nCnt == sizeof(keybits));
643 if (ISBITSET(keybits,BTN_LEFT) ||
644 ISBITSET(keybits,BTN_RIGHT) ||
645 ISBITSET(keybits,BTN_MIDDLE) ||
646 ISBITSET(keybits,BTN_SIDE) ||
647 ISBITSET(keybits,BTN_EXTRA))
648 pUSB->state[0].uValid |= BIT(WACOMFIELD_BUTTONS);
651 if (ISBITSET(keybits,BTN_TOOL_PEN) ||
652 ISBITSET(keybits,BTN_TOOL_RUBBER) ||
653 ISBITSET(keybits,BTN_TOOL_BRUSH) ||
654 ISBITSET(keybits,BTN_TOOL_PENCIL) ||
655 ISBITSET(keybits,BTN_TOOL_AIRBRUSH) ||
656 ISBITSET(keybits,BTN_TOOL_FINGER) ||
657 ISBITSET(keybits,BTN_TOOL_MOUSE) ||
658 ISBITSET(keybits,BTN_TOOL_LENS) ||
659 ISBITSET(keybits,BTN_TOOL_DOUBLETAP))
660 pUSB->state[0].uValid |= BIT(WACOMFIELD_PROXIMITY) |
661 BIT(WACOMFIELD_TOOLTYPE);
663 /* Detect button codes */
664 for (nCnt = 0; nCnt < WACOMBUTTON_MAX; nCnt++)
665 if (ISBITSET (keybits, padkey_codes [nCnt]))
666 gPadKeys [gNumPadKeys++] = padkey_codes [nCnt];
669 /* set identification */
673 pUSB->nVersion = sID[3];
675 if (USBFindModel(pUSB,uVendor,uProduct))
678 /* add additional capabilities by device type */
679 switch (pUSB->pDevice->uDevice)
682 case WACOMDEVICE_GRAPHIRE4:
683 case WACOMDEVICE_INTUOS:
684 case WACOMDEVICE_INTUOS2:
685 case WACOMDEVICE_INTUOS3:
686 case WACOMDEVICE_CINTIQV5:
687 pUSB->state[0].uValid |= BIT(WACOMFIELD_SERIAL);
691 /* Initialize all channels with the same values */
692 for(chcnt=1; chcnt<MAX_CHANNELS; chcnt++)
693 pUSB->state[chcnt] = pUSB->state[0];
698 static const char* USBGetVendorName(WACOMTABLET_PRIV* pTablet)
700 USBTABLET* pUSB = (USBTABLET*)pTablet;
701 return pUSB->pVendor->pszDesc;
704 static const char* USBGetClassName(WACOMTABLET_PRIV* pTablet)
709 static const char* USBGetDeviceName(WACOMTABLET_PRIV* pTablet)
711 USBTABLET* pUSB = (USBTABLET*)pTablet;
712 return pUSB->pDevice->pszDesc;
715 static const char* USBGetSubTypeName(WACOMTABLET_PRIV* pTablet)
717 USBTABLET* pUSB = (USBTABLET*)pTablet;
718 return pUSB->pSubType->pszName;
721 static const char* USBGetModelName(WACOMTABLET_PRIV* pTablet)
723 USBTABLET* pUSB = (USBTABLET*)pTablet;
724 return pUSB->pSubType->pszDesc;
727 static int USBGetROMVer(WACOMTABLET_PRIV* pTablet, int* pnMajor,
728 int* pnMinor, int* pnRelease)
730 USBTABLET* pUSB = (USBTABLET*)pTablet;
731 if (!pnMajor) { errno=EINVAL; return 1; }
733 /* how is the version number broken down?
734 * mine says 0x115. is that 1.1.5 or 1.15? */
735 *pnMajor = pUSB->nVersion >> 8;
736 *pnMinor = (pUSB->nVersion >> 4) & 0xF;
737 *pnRelease = (pUSB->nVersion & 0xF);
741 static int USBGetCaps(WACOMTABLET_PRIV* pTablet)
743 USBTABLET* pUSB = (USBTABLET*)pTablet;
744 return pUSB->state[0].uValid;
747 static int USBGetState(WACOMTABLET_PRIV* pTablet, WACOMSTATE* pState)
749 USBTABLET* pUSB = (USBTABLET*)pTablet;
750 return WacomCopyState(pState,&pUSB->state[pUSB->nChannel]);
753 static int USBGetFD(WACOMTABLET_PRIV* pTablet)
755 USBTABLET* pUSB = (USBTABLET*)pTablet;
759 static int USBReadRaw(WACOMTABLET_PRIV* pTablet, unsigned char* puchData,
763 unsigned int uCnt, uPacketLength;
764 USBTABLET* pUSB = (USBTABLET*)pTablet;
765 uPacketLength = sizeof(struct input_event);
767 /* check size of buffer */
768 if (uSize < uPacketLength) { errno=EINVAL; return 0; }
770 for (uCnt=0; uCnt<uPacketLength; uCnt+=nXfer)
772 nXfer = read(pUSB->fd,puchData+uCnt,uPacketLength-uCnt);
773 if (nXfer <= 0) return nXfer;
779 static int USBParseMSC(USBTABLET* pUSB, struct input_event* pEv)
781 if (pEv->code == MSC_SERIAL && pEv->value)
782 pUSB->state[pUSB->nChannel].values[WACOMFIELD_SERIAL].nValue = pEv->value;
783 if (!pUSB->state[pUSB->nChannel].values[WACOMFIELD_PROXIMITY].nValue)
784 pUSB->state[pUSB->nChannel].values[WACOMFIELD_SERIAL].nValue = 0;
788 static int USBParseKEY(USBTABLET* pUSB, struct input_event* pEv)
790 int i, button=-1, tool=0;
793 case BTN_LEFT: button = WACOMBUTTON_LEFT; break;
794 case BTN_RIGHT: button = WACOMBUTTON_RIGHT; break;
795 case BTN_MIDDLE: button = WACOMBUTTON_MIDDLE; break;
796 case BTN_SIDE: button = WACOMBUTTON_SIDE; break;
797 case BTN_EXTRA: button = WACOMBUTTON_EXTRA; break;
798 case BTN_TOUCH: button = WACOMBUTTON_TOUCH; break;
799 case BTN_STYLUS: button = WACOMBUTTON_STYLUS; break;
800 case BTN_STYLUS2: button = WACOMBUTTON_STYLUS2; break;
801 case BTN_TOOL_PEN: tool = WACOMTOOLTYPE_PEN; break;
802 case BTN_TOOL_PENCIL: tool = WACOMTOOLTYPE_PENCIL; break;
803 case BTN_TOOL_BRUSH: tool = WACOMTOOLTYPE_BRUSH; break;
804 case BTN_TOOL_RUBBER: tool = WACOMTOOLTYPE_ERASER; break;
805 case BTN_TOOL_AIRBRUSH: tool = WACOMTOOLTYPE_AIRBRUSH; break;
806 case BTN_TOOL_MOUSE: tool = WACOMTOOLTYPE_MOUSE; break;
807 case BTN_TOOL_FINGER: tool = WACOMTOOLTYPE_PAD; break;
808 case BTN_TOOL_LENS: tool = WACOMTOOLTYPE_LENS; break;
809 case BTN_TOOL_DOUBLETAP: tool = WACOMTOOLTYPE_TOUCH; break;
811 for (i = 0; i < gNumPadKeys; i++)
812 if (pEv->code == gPadKeys [i])
814 button = WACOMBUTTON_BT0 + i;
819 /* if button was specified */
822 /* button state change */
824 pUSB->state[pUSB->nChannel].values[WACOMFIELD_BUTTONS].nValue |= BIT(button);
826 pUSB->state[pUSB->nChannel].values[WACOMFIELD_BUTTONS].nValue &= ~BIT(button);
829 /* if a tool was specified */
832 /* coming into proximity */
835 /* no prior tool in proximity */
836 if (!(pUSB->nToolProx[pUSB->nChannel] & BIT(tool)))
838 pUSB->state[pUSB->nChannel].values[WACOMFIELD_PROXIMITY].nValue = 1;
841 /* remember tool in prox */
842 pUSB->nToolProx[pUSB->nChannel] |= BIT(tool);
843 pUSB->state[pUSB->nChannel].values[WACOMFIELD_TOOLTYPE].nValue = tool;
846 /* otherwise, going out of proximity */
849 /* forget tool in prox */
850 if (pUSB->nToolProx[pUSB->nChannel] & BIT(tool))
852 pUSB->nToolProx[pUSB->nChannel] &= ~BIT(tool);
856 if (!(pUSB->state[pUSB->nChannel].uValid & BIT(WACOMFIELD_SERIAL)))
857 pUSB->nToolProx[pUSB->nChannel] = 0;
859 pUSB->state[pUSB->nChannel].values[WACOMFIELD_PROXIMITY].nValue = 0;
860 pUSB->state[pUSB->nChannel].values[WACOMFIELD_TOOLTYPE].nValue = 0;
862 /* nobody left? out of proximity */
863 if (!pUSB->nToolProx[pUSB->nChannel])
864 memset(pUSB->state[pUSB->nChannel].values, 0,
865 pUSB->state[pUSB->nChannel].uValueCnt * sizeof(WACOMVALUE));
866 /* otherwise, switch to next tool */
869 for (i=WACOMTOOLTYPE_PEN; i<WACOMTOOLTYPE_MAX; ++i)
871 if (pUSB->nToolProx[pUSB->nChannel] & BIT(i))
873 pUSB->state[pUSB->nChannel].values[WACOMFIELD_TOOLTYPE].nValue = i;
883 static int USBParseABS(USBTABLET* pUSB, struct input_event* pEv)
888 case ABS_X: field = WACOMFIELD_POSITION_X; break;
889 case ABS_Y: field = WACOMFIELD_POSITION_Y; break;
890 case ABS_RZ: field = WACOMFIELD_ROTATION_Z; break;
891 case ABS_DISTANCE: field = WACOMFIELD_DISTANCE; break;
892 case ABS_PRESSURE: field = WACOMFIELD_PRESSURE; break;
893 case ABS_TILT_X: field = WACOMFIELD_TILT_X; break;
894 case ABS_TILT_Y: field = WACOMFIELD_TILT_Y; break;
895 case ABS_WHEEL: field = WACOMFIELD_ABSWHEEL; break;
896 case ABS_THROTTLE: field = WACOMFIELD_THROTTLE; break;
900 pUSB->state[pUSB->nChannel].values[field].nValue = pEv->value;
905 static int USBParseREL(USBTABLET* pUSB, struct input_event* pEv)
910 case REL_WHEEL: field = WACOMFIELD_RELWHEEL; break;
914 pUSB->state[pUSB->nChannel].values[field].nValue = pEv->value;
919 static int USBParseData(WACOMTABLET_PRIV* pTablet,
920 const unsigned char* puchData, unsigned int uLength,
924 USBTABLET* pUSB = (USBTABLET*)pTablet;
925 struct input_event* pEv = (struct input_event*)puchData;
926 if (uLength != sizeof(struct input_event)) return 1;
928 /* store event until we receive a MSC_SERIAL/SYN_REPORT
929 * so we can figure out with channel to use */
930 if (pUSB->nEventCnt >= MAX_USB_EVENTS)
932 /* no more buffer space */
934 pUSB->nLastToolSerial = 0;
938 pUSB->events[pUSB->nEventCnt++] = *pEv;
940 if ((pEv->type == EV_MSC) && (pEv->code == MSC_SERIAL))
942 /* store the serial for the tool for later use */
943 pUSB->nLastToolSerial = pEv->value;
945 /* Kernel 2.4 uses MSC_SERIAL as an end-of-report, 2.6
946 * don't so we're not done yet */
949 else if ((pEv->type == EV_SYN) && (pEv->code == SYN_REPORT))
951 /* Kernel 2.6 used SYN_REPORT as an end-of-record,
957 /* Not a MSC_SERIAL or SYN_REPORT, we're not done yet */
961 /* Select channel here based on the serial number, tablets
962 * with only one channel will always use channel 0, so no
965 if (pUSB->pDevice->uChannelCnt > 1)
968 /* Find existing channel */
969 for (chcnt=0; chcnt<pUSB->pDevice->uChannelCnt; chcnt++)
971 if (pUSB->state[chcnt].values[WACOMFIELD_SERIAL].nValue == pUSB->nLastToolSerial)
973 pUSB->nChannel = chcnt;
978 /* Find en empty channel */
979 if(pUSB->nChannel == -1)
981 for (chcnt=0; chcnt<pUSB->pDevice->uChannelCnt; chcnt++)
983 if(!pUSB->nToolProx[chcnt])
985 pUSB->nChannel = chcnt;
991 /* no more channels?? */
992 if(pUSB->nChannel == -1)
996 pUSB->nLastToolSerial = 0;
1002 /* Channel found/allocated, lets process events */
1003 pUSB->state[pUSB->nChannel].values[WACOMFIELD_RELWHEEL].nValue = 0;
1005 for (evcnt=0; evcnt<pUSB->nEventCnt; evcnt++)
1007 pEv = pUSB->events + evcnt;
1008 /* dispatch event */
1012 case EV_SYN: /* kernel 2.6 */
1014 case EV_MSC: /* kernel 2.4 */
1015 if (USBParseMSC(pUSB,pEv)) return pEv->type; break;
1016 case EV_KEY: if (USBParseKEY(pUSB,pEv)) return pEv->type; break;
1017 case EV_ABS: if (USBParseABS(pUSB,pEv)) return pEv->type; break;
1018 case EV_REL: if (USBParseREL(pUSB,pEv)) return pEv->type; break;
1019 default: errno = EINVAL; return pEv->type;
1023 pUSB->nEventCnt = 0;
1024 pUSB->nLastToolSerial = 0;
1025 return pState ? WacomCopyState(pState,pUSB->state + pUSB->nChannel) : 0;
1028 /*****************************************************************************
1029 ** End USB Linux Input Subsystem
1030 *****************************************************************************/
1032 #else /* WCM_ENABLE_LINUXWACOM */
1034 WACOMTABLET WacomOpenUSBTablet(WACOMENGINE hEngine, int fd, WACOMMODEL* pModel)
1040 unsigned int WacomGetUSBDeviceFromName(const char* pszName)
1046 int WacomGetSupportedUSBDeviceList(WACOMDEVICEREC** ppList, int* pnSize)
1048 if (!ppList || !pnSize) { errno = EINVAL; return 1; }
1054 #endif /* WCM_ENABLE_LINUXWACOM */