diff options
Diffstat (limited to 'src/xdrv/wcmISDV4.c')
-rwxr-xr-x | src/xdrv/wcmISDV4.c | 268 |
1 files changed, 143 insertions, 125 deletions
diff --git a/src/xdrv/wcmISDV4.c b/src/xdrv/wcmISDV4.c index da6d4ab..bf667db 100755 --- a/src/xdrv/wcmISDV4.c +++ b/src/xdrv/wcmISDV4.c @@ -102,7 +102,8 @@ static int isdv4Query(LocalDevicePtr local, const char* query, char* data) err = xf86WcmWrite(local->fd, WC_ISDV4_STOP, strlen(WC_ISDV4_STOP)); if (err == -1) { - ErrorF("Wacom xf86WcmWrite ISDV4_STOP error : %s\n", strerror(errno)); + xf86Msg(X_WARNING, "Wacom xf86WcmWrite ISDV4_STOP error : %s\n", + strerror(errno)); return !Success; } @@ -113,13 +114,13 @@ static int isdv4Query(LocalDevicePtr local, const char* query, char* data) /* Send query command to the tablet */ if (!xf86WcmWriteWait(local->fd, query)) { - ErrorF("Wacom unable to xf86WcmWrite request %s ISDV4 query command " - "after %d tries\n", query, MAXTRY); + xf86Msg(X_WARNING, "Wacom unable to xf86WcmWrite request %s ISDV4" + " query command after %d tries\n", query, MAXTRY); return !Success; } /* Read the control data */ - if (!xf86WcmWaitForTablet(local->fd, data, 11)) + if (!xf86WcmWaitForTablet(local->fd, data, WACOM_PKGLEN_TPCCTL)) { /* Try 19200 if it is not a touch query */ if (common->wcmISDV4Speed != 19200 && strcmp(query, WC_ISDV4_TOUCH_QUERY)) @@ -131,8 +132,8 @@ static int isdv4Query(LocalDevicePtr local, const char* query, char* data) } else { - ErrorF("Wacom unable to read ISDV4 %s data " - "after %d tries at (%d)\n", query, MAXTRY, common->wcmISDV4Speed); + xf86Msg(X_WARNING, "Wacom unable to read ISDV4 %s data after %d" + " tries at (%d)\n", query, MAXTRY, common->wcmISDV4Speed); return !Success; } } @@ -150,11 +151,12 @@ static int isdv4Query(LocalDevicePtr local, const char* query, char* data) } else { - /* Reread the control data since with some vendors it fails the first time */ - xf86WcmWaitForTablet(local->fd, data, 11); + /* Reread the control data since it may fail the first time */ + xf86WcmWaitForTablet(local->fd, data, WACOM_PKGLEN_TPCCTL); if ( !(data[0] & 0x40) ) { - ErrorF("Wacom ISDV4 control data (%x) error in %s query\n", data[0], query); + xf86Msg(X_WARNING, "Wacom ISDV4 control data (%x) error in %s" + " query\n", data[0], query); return !Success; } } @@ -171,11 +173,8 @@ static void isdv4InitISDV4(WacomCommonPtr common, const char* id, float version) { /* set parameters */ common->wcmProtocolLevel = 4; - common->wcmPktLength = WACOM_PKGLEN_TPC; /* length of a packet - * device packets are 9 bytes - * resistive touch is 5 bytes - * capacitive touch is 7 bytes - */ + /* length of a packet */ + common->wcmPktLength = WACOM_PKGLEN_TPC; /* digitizer X resolution in points/inch */ common->wcmResolX = 2540; @@ -198,12 +197,13 @@ static int isdv4GetRanges(LocalDevicePtr local) char data[BUFFER_SIZE]; WacomDevicePtr priv = (WacomDevicePtr)local->private; WacomCommonPtr common = priv->common; - char * s; + int ret = Success; DBG(2, priv->debugLevel, ErrorF("getting ISDV4 Ranges\n")); /* Send query command to the tablet */ - if (isdv4Query(local, WC_ISDV4_QUERY, data) == Success) + ret = isdv4Query(local, WC_ISDV4_QUERY, data); + if (ret == Success) { /* transducer data */ common->wcmMaxZ = ( data[5] | ((data[6] & 0x07) << 7) ); @@ -219,77 +219,117 @@ static int isdv4GetRanges(LocalDevicePtr local) } common->wcmVersion = ( data[10] | (data[9] << 7) ); + + /* default to no pen 2FGT if size is undefined */ + if (!common->wcmMaxX || !common->wcmMaxY) + common->tablet_id = 0xe2; + + DBG(2, priv->debugLevel, ErrorF("isdv4GetRanges Pen speed=%d " + "maxX=%d maxY=%d maxZ=%d TouchresX=%d TouchresY=%d \n", + common->wcmISDV4Speed, common->wcmMaxX, common->wcmMaxY, + common->wcmMaxZ, common->wcmResolX, common->wcmResolY)); } - else - return !Success; - if (common->wcmISDV4Speed != 19200) + /* Touch might be supported. Send a touch query command */ + common->wcmISDV4Speed = 38400; + if (isdv4Query(local, WC_ISDV4_TOUCH_QUERY, data) == Success) { - /* default to 0x93 (resistive touch) */ - common->wcmPktLength = WACOM_PKGLEN_TOUCH0; - common->tablet_id = 0x93; - - /* Touch might be supported. Send a touch query command */ - if (isdv4Query(local, WC_ISDV4_TOUCH_QUERY, data) == Success) + switch(data[2] & 0x07) { - /* (data[2] & 0x07) == 0 is for resistive touch */ - if (!(data[2] & 0x07) && data[1]) - { - common->wcmMaxTouchX = common->wcmMaxTouchY = (int)(1 << data[1]); - } + case 0x00: /* resistive touch & pen */ + common->wcmPktLength = WACOM_PKGLEN_TOUCH0; + common->tablet_id = 0x93; + break; + case 0x01: /* capacitive touch & pen */ + common->wcmPktLength = WACOM_PKGLEN_TOUCH; + common->tablet_id = 0x9a; + break; + case 0x02: /* resistive touch */ + common->wcmPktLength = WACOM_PKGLEN_TOUCH0; + common->tablet_id = 0x93; + break; + case 0x03: /* capacitive touch */ + common->wcmPktLength = WACOM_PKGLEN_TOUCH; + common->tablet_id = 0x9f; + break; + case 0x04: /* capacitive touch */ + common->wcmPktLength = WACOM_PKGLEN_TOUCH; + common->tablet_id = 0x9f; + break; + case 0x05: + common->wcmPktLength = WACOM_PKGLEN_TOUCH2FG; + /* a penabled */ + if (common->tablet_id == 0x90) + common->tablet_id = 0xe3; + break; + } - if ((data[0] & 0x41) && (data[2] & 0x07)) - { - /* tablet model */ - switch (data[2] & 0x07) + switch(data[0] & 0x3f) + { + /* single finger touch */ + case 0x01: + if ((common->tablet_id != 0x93) && + (common->tablet_id != 0x9A) && + (common->tablet_id != 0x9F)) { - case 0x01: - common->wcmPktLength = WACOM_PKGLEN_TOUCH; - common->tablet_id = 0x9A; - break; - case 0x02: - case 0x04: - common->wcmPktLength = WACOM_PKGLEN_TOUCH; - common->tablet_id = 0x9F; - break; + xf86Msg(X_WARNING, "WACOM: %s tablet id(0x%x)" + " mismatch with data id (0x01) \n", + local->name, common->tablet_id); + return ret; } - - /* touch logical size for tablet PC with touch */ - if (data[1]) + break; + /* 2FGT */ + case 0x03: + if ((common->tablet_id != 0xE2) && + (common->tablet_id != 0xE3)) { - common->wcmMaxTouchX = common->wcmMaxTouchY = (int)(1 << data[1]); + xf86Msg(X_WARNING, "WACOM: %s tablet id(0x%x)" + " mismatch with data id (0x03) \n", + local->name, common->tablet_id); + return ret; } + break; + } - /* Max capacity */ - common->wcmMaxCapacity = (int)(1 << data[7]); - - if (common->wcmMaxCapacity) - { - common->wcmTouchResolX = common->wcmMaxTouchX / ( 2540 * - ((data[3] << 9) | (data[4] << 2) | ((data[2] & 0x60) >> 5))); - common->wcmTouchResolX = common->wcmMaxTouchX / ( 2540 * - ((data[5] << 9) | (data[6] << 2) | ((data[2] & 0x18) >> 3))); - } - } + /* don't overwrite the default */ + if ((data[2] & 0x78) | data[3] | data[4] | data[5] | data[6]) + { + common->wcmMaxTouchX = ((data[3] << 9) | + (data[4] << 2) | ((data[2] & 0x60) >> 5)); + common->wcmMaxTouchY = ((data[5] << 9) | + (data[6] << 2) | ((data[2] & 0x18) >> 3)); } + else if (data[1]) + common->wcmMaxTouchX = common->wcmMaxTouchY = (int)(1 << data[1]); - s = xf86FindOptionValue(local->options, "Touch"); - if ( !s || (strstr(s, "on")) ) /* touch option is on */ + if (data[1]) { - common->wcmTouch = 1; + common->wcmTouchResolX = common->wcmTouchResolY = 10; + common->wcmTouchDefault = 1; } + else + common->wcmTouchDefault = 0; - /* TouchDefault was off for all devices - * defaults to enable when it is a touch device - */ - common->wcmTouchDefault = 1; - } + /* updated touch info */ + common->wcmTouch = xf86SetBoolOption(local->options, "Touch", + common->wcmTouchDefault); - DBG(2, priv->debugLevel, ErrorF("isdv4GetRanges speed=%d maxX=%d maxY=%d " - "maxZ=%d TouchresX=%d TouchresY=%d \n", common->wcmISDV4Speed, - common->wcmMaxX, common->wcmMaxY, common->wcmMaxZ, - common->wcmResolX, common->wcmResolY)); - return Success; + if ((common->tablet_id == 0xE2) || + (common->tablet_id == 0xE3)) + common->wcmGestureDefault = 1; + + common->wcmGesture = xf86SetBoolOption(local->options, "Gesture", + common->wcmGestureDefault); + + common->wcmVersion = ( data[10] | (data[9] << 7) ); + ret = Success; + + DBG(2, priv->debugLevel, ErrorF("isdv4GetRanges touch speed=%d " + "maxX=%d maxY=%d TouchresX=%d TouchresY=%d \n", + common->wcmISDV4Speed, common->wcmMaxTouchX, common->wcmMaxTouchY, + common->wcmTouchResolX, common->wcmTouchResolY)); + } + return ret; } static int isdv4StartTablet(LocalDevicePtr local) @@ -313,64 +353,28 @@ static int isdv4Parse(LocalDevicePtr local, const unsigned char* data) WacomDevicePtr priv = (WacomDevicePtr)local->private; WacomCommonPtr common = priv->common; WacomDeviceState* last = &common->wcmChannel[0].valid.state; + WacomDeviceState* lastTemp = &common->wcmChannel[1].valid.state; WacomDeviceState* ds; int n, cur_type, channel = 0; - static int touchInProx; DBG(10, common->debugLevel, ErrorF("isdv4Parse \n")); - channel = 0; /* determine the type of message (touch or stylus)*/ - if (data[0] & 0x18) /* not a pen */ + if (data[0] & 0x10) /* a touch data */ { - if ((last->device_id != TOUCH_DEVICE_ID && last->device_id && last->proximity ) || - !common->wcmTouch ) + if ((last->device_id != TOUCH_DEVICE_ID && last->device_id && + last->proximity) || !common->wcmTouch) { - if ((data[0] & 0x10) && (!(data[0] & 0x01))) /* a touch out-prox data */ - touchInProx = 0; - else - touchInProx = 1; - /* ignore touch event */ return common->wcmPktLength; } - else - { - if (data[0] & 0x10) /* a touch data */ - { - if (!touchInProx) - { - channel = 1; - } - else if (!(data[0] & 0x01)) /* touch out-prox */ - { - touchInProx = 0; - channel = 0; - } - else - { - /* ignore touch event */ - return common->wcmPktLength; - } - } - else - { - /* ignore touch event */ - return common->wcmPktLength; - } - } } else { /* touch was in control */ - if (common->wcmChannel[1].valid.state.proximity) - { + if (last->proximity && last->device_id == TOUCH_DEVICE_ID) /* let touch go */ - xf86WcmSoftOut(common, 1); - return 0; - } - common->wcmPktLength = WACOM_PKGLEN_TPC; - channel = 0; + xf86WcmSoftOut(common, channel); } if (common->buffer + common->bufpos - data < common->wcmPktLength) @@ -379,25 +383,18 @@ static int isdv4Parse(LocalDevicePtr local, const unsigned char* data) return common->wcmPktLength; } - if ((n = xf86WcmSerialValidate(common,data)) > 0) + /* Coordinate data bit check */ + if (data[0] & 0x40) /* control data */ + return common->wcmPktLength; + else if ((n = xf86WcmSerialValidate(common,data)) > 0) return n; - else - { - /* Coordinate data bit check */ - if (data[0] & 0x40) /* control data */ - return common->wcmPktLength; - } /* pick up where we left off, minus relative values */ ds = &common->wcmChannel[channel].work; RESET_RELATIVE(*ds); - if (common->wcmPktLength == WACOM_PKGLEN_TOUCH0 || - common->wcmPktLength == WACOM_PKGLEN_TOUCH) /* a touch */ + if (common->wcmPktLength != WACOM_PKGLEN_TPC) /* a touch */ { - /* touch without capacity has 5 bytes of data - * touch with capacity has 7 bytes of data - */ ds->x = (((int)data[1]) << 7) | ((int)data[2]); ds->y = (((int)data[3]) << 7) | ((int)data[4]); if (common->wcmPktLength == WACOM_PKGLEN_TOUCH) @@ -407,6 +404,27 @@ static int isdv4Parse(LocalDevicePtr local, const unsigned char* data) ds->buttons = ds->proximity = data[0] & 0x01; ds->device_type = TOUCH_ID; ds->device_id = TOUCH_DEVICE_ID; + + if (common->wcmPktLength == WACOM_PKGLEN_TOUCH2FG) + { + if ((data[0] & 0x02) || (!(data[0] & 0x02) && + lastTemp->proximity)) + { + /* Got 2FGT. Send the first one if received */ + if (ds->proximity || (!ds->proximity && + last->proximity)) + xf86WcmEvent(common, channel, ds); + + channel = 1; + ds = &common->wcmChannel[channel].work; + RESET_RELATIVE(*ds); + ds->x = (((int)data[7]) << 7) | ((int)data[8]); + ds->y = (((int)data[9]) << 7) | ((int)data[10]); + ds->device_type = TOUCH_ID; + ds->device_id = TOUCH_DEVICE_ID; + ds->proximity = data[0] & 0x02; + } + } DBG(8, priv->debugLevel, ErrorF("isdv4Parse MultiTouch " "%s proximity \n", ds->proximity ? "in" : "out of")); } |