Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> --- src/wcmISDV4.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++-------- src/wcmISDV4.h | 29 ++++++++++++- 2 files changed, 135 insertions(+), 20 deletions(-)
diff --git a/src/wcmISDV4.c b/src/wcmISDV4.c index f60686b..2c70d00 100644 --- a/src/wcmISDV4.c +++ b/src/wcmISDV4.c @@ -50,6 +50,11 @@ static inline int isdv4ParseQuery(const char *buffer, const size_t len, static inline int isdv4ParseTouchQuery(const char *buffer, const size_t len, ISDV4TouchQueryReply *reply); +static inline int isdv4ParseTouchData(const unsigned char *buffer, const size_t len, + const size_t pktlen, ISDV4TouchData *touchdata); + +static inline int isdv4ParseCoordinateData(const unsigned char *buffer, const size_t len, + ISDV4CoordinateData *coord); WacomDeviceClass gWacomISDV4Device = { @@ -450,7 +455,7 @@ static int isdv4Parse(LocalDevicePtr local, const unsigned char* data, int len) return 0; /* determine the type of message (touch or stylus) */ - if (data[0] & 0x10) /* a touch data */ + if (data[0] & TOUCH_CONTROL_BIT) /* a touch data */ { if ((last->device_id != TOUCH_DEVICE_ID && last->device_id && last->proximity ) || !common->wcmTouch) @@ -472,7 +477,7 @@ static int isdv4Parse(LocalDevicePtr local, const unsigned char* data, int len) } /* Coordinate data bit check */ - if (data[0] & 0x40) /* control data */ + if (data[0] & CONTROL_BIT) /* control data */ return common->wcmPktLength; else if ((n = wcmSerialValidate(local,data)) > 0) return n; @@ -483,20 +488,29 @@ static int isdv4Parse(LocalDevicePtr local, const unsigned char* data, int len) if (common->wcmPktLength != ISDV4_PKGLEN_TPCPEN) /* a touch */ { - ds->x = (((int)data[1]) << 7) | ((int)data[2]); - ds->y = (((int)data[3]) << 7) | ((int)data[4]); - if (common->wcmPktLength == ISDV4_PKGLEN_TOUCH9A) + ISDV4TouchData touchdata; + int rc; + + rc = isdv4ParseTouchData(data, len, common->wcmPktLength, &touchdata); + if (rc == -1) { - ds->capacity = (((int)data[5]) << 7) | ((int)data[6]); + xf86Msg(X_ERROR, "%s: failed to parse touch data.\n", + local->name); + return 0; } - ds->buttons = ds->proximity = data[0] & 0x01; + + + ds->x = touchdata.x; + ds->y = touchdata.y; + ds->capacity = touchdata.capacity; + ds->buttons = ds->proximity = touchdata.status; ds->device_type = TOUCH_ID; ds->device_id = TOUCH_DEVICE_ID; if (common->wcmPktLength == ISDV4_PKGLEN_TOUCH2FG) { - if ((data[0] & 0x02) || (!(data[0] & 0x02) && - lastTemp->proximity)) + if (touchdata.finger2.status || + (!touchdata.finger2.status && lastTemp->proximity)) { /* Got 2FGT. Send the first one if received */ if (ds->proximity || (!ds->proximity && @@ -512,11 +526,11 @@ static int isdv4Parse(LocalDevicePtr local, const unsigned char* data, int len) 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->x = touchdata.finger2.x; + ds->y = touchdata.finger2.y; ds->device_type = TOUCH_ID; ds->device_id = TOUCH_DEVICE_ID; - ds->proximity = data[0] & 0x02; + ds->proximity = touchdata.finger2.status; /* time stamp for 2FGT gesture events */ if ((ds->proximity && !lastTemp->proximity) || (!ds->proximity && lastTemp->proximity)) @@ -529,19 +543,28 @@ static int isdv4Parse(LocalDevicePtr local, const unsigned char* data, int len) } else { - ds->proximity = (data[0] & 0x20); + int rc; + ISDV4CoordinateData coord; + + rc = isdv4ParseCoordinateData(data, ISDV4_PKGLEN_TPCPEN, &coord); + + if (rc == -1) + { + xf86Msg(X_ERROR, "%s: failed to parse coordinate data.\n", local->name); + return 0; + } + + ds->proximity = coord.proximity; /* x and y in "normal" orientetion (wide length is X) */ - ds->x = (((int)data[6] & 0x60) >> 5) | ((int)data[2] << 2) | - ((int)data[1] << 9); - ds->y = (((int)data[6] & 0x18) >> 3) | ((int)data[4] << 2) | - ((int)data[3] << 9); + ds->x = coord.x; + ds->y = coord.y; /* pressure */ - ds->pressure = (((data[6] & 0x07) << 7) | data[5] ); + ds->pressure = coord.pressure; /* buttons */ - ds->buttons = (data[0] & 0x07); + ds->buttons = coord.tip | (coord.side << 1) | (coord.eraser << 2); /* check which device we have */ cur_type = (ds->buttons & 4) ? ERASER_ID : STYLUS_ID; @@ -781,4 +804,69 @@ static inline int isdv4ParseTouchQuery(const char *buffer, const size_t len, return ISDV4_PKGLEN_TPCCTL; } + +/* pktlen defines what touch type we parse */ +static inline int isdv4ParseTouchData(const unsigned char *buffer, const size_t buff_len, + const size_t pktlen, ISDV4TouchData *touchdata) +{ + int header, touch; + + if (!touchdata || buff_len < pktlen) + return 0; + + header = !!(buffer[0] & HEADER_BIT); + touch = !!(buffer[0] & TOUCH_CONTROL_BIT); + + if (header != 1 || touch != 1) + return -1; + + memset(touchdata, 0, sizeof(*touchdata)); + + touchdata->status = buffer[0] & 0x1; + /* FIXME: big endian */ + touchdata->x = buffer[1] << 7 | buffer[2]; + touchdata->y = buffer[3] << 7 | buffer[4]; + if (pktlen == ISDV4_PKGLEN_TOUCH9A) + touchdata->capacity = buffer[5] << 7 | buffer[6]; + + if (pktlen == ISDV4_PKGLEN_TOUCH2FG) + { + touchdata->finger2.x = buffer[7] << 7 | buffer[8]; + touchdata->finger2.y = buffer[9] << 7 | buffer[10]; + touchdata->finger2.status = !!(buffer[0] & 0x2); + /* FIXME: is there a fg2 capacity? */ + } + + return pktlen; +} + +static inline int isdv4ParseCoordinateData(const unsigned char *buffer, const size_t len, + ISDV4CoordinateData *coord) +{ + int header, control; + + if (!coord || len < ISDV4_PKGLEN_TPCPEN) + return 0; + + header = !!(buffer[0] & HEADER_BIT); + control = !!(buffer[0] & TOUCH_CONTROL_BIT); + + if (header != 1 || control != 0) + return -1; + + coord->proximity = (buffer[0] >> 5) & 0x1; + coord->tip = buffer[0] & 0x1; + coord->side = (buffer[0] >> 1) & 0x1; + coord->eraser = (buffer[0] >> 2) & 0x1; + /* FIXME: big endian */ + coord->x = (buffer[1] << 9) | (buffer[2] << 2) | ((buffer[6] >> 5) & 0x3); + coord->y = (buffer[3] << 9) | (buffer[4] << 2) | ((buffer[6] >> 3) & 0x3); + + coord->pressure = ((buffer[6] & 0x7) << 7) | buffer[5]; + coord->tilt_x = buffer[7]; + coord->tilt_y = buffer[8]; + + return ISDV4_PKGLEN_TPCPEN; +} + /* vim: set noexpandtab shiftwidth=8: */ diff --git a/src/wcmISDV4.h b/src/wcmISDV4.h index cd57d5e..cb1ad1b 100644 --- a/src/wcmISDV4.h +++ b/src/wcmISDV4.h @@ -30,6 +30,7 @@ #define HEADER_BIT 0x80 #define CONTROL_BIT 0x40 #define DATA_ID_MASK 0x3F +#define TOUCH_CONTROL_BIT 0x10 /* ISDV4 protocol parsing structs. */ @@ -44,7 +45,6 @@ typedef struct { uint16_t version; } ISDV4QueryReply; - /* Touch Query reply data */ typedef struct { uint8_t data_id; /* always 01H */ @@ -56,6 +56,33 @@ typedef struct { uint16_t version; } ISDV4TouchQueryReply; +/* Touch Data format. Note that capacity and finger2 are only set for some + * devices (0 on all others) */ +typedef struct { + uint8_t status; /* touch down/up */ + uint16_t x; + uint16_t y; + uint16_t capacity; + struct { + uint8_t status; /* touch down/up */ + uint16_t x; + uint16_t y; + } finger2; +} ISDV4TouchData; + +/* Coordinate data format */ +typedef struct { + uint8_t proximity; /* in proximity? */ + uint8_t tip; /* tip/eraser pressed? */ + uint8_t side; /* side switch pressed? */ + uint8_t eraser; /* eraser pressed? */ + uint16_t x; + uint16_t y; + uint16_t pressure; + uint8_t tilt_x; + uint8_t tilt_y; +} ISDV4CoordinateData; + #endif /* WCMISDV4_H */ /* vim: set noexpandtab shiftwidth=8: */ -- 1.6.6.1 ------------------------------------------------------------------------------ Download Intel® Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev _______________________________________________ Linuxwacom-devel mailing list Linuxwacom-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel