summaryrefslogtreecommitdiff
path: root/src/xdrv/wcmISDV4.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xdrv/wcmISDV4.c')
-rwxr-xr-xsrc/xdrv/wcmISDV4.c268
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"));
}