home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 2010 by Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-
- #ifndef ISDV4_H
- #define ISDV4_H
-
- #define ISDV4_QUERY "*" /* ISDV4 query command */
- #define ISDV4_RESET "&" /* ISDV4 touch panel reset command */
- #define ISDV4_TOUCH_QUERY "%" /* ISDV4 touch query command */
- #define ISDV4_STOP "0" /* ISDV4 stop command */
- #define ISDV4_SAMPLING "1" /* ISDV4 sampling command */
-
- /* packet length for individual models */
- #define ISDV4_PKGLEN_TOUCH93 5
- #define ISDV4_PKGLEN_TOUCH9A 7
- #define ISDV4_PKGLEN_TPCPEN 9
- #define ISDV4_PKGLEN_TPCCTL 11
- #define ISDV4_PKGLEN_TOUCH2FG 13
-
- #define HEADER_BIT 0x80
- #define CONTROL_BIT 0x40
- #define DATA_ID_MASK 0x3F
- #define TOUCH_CONTROL_BIT 0x10
-
- /* Only for touch devices: use serial ID as index to get packet length for device */
- int ISDV4PacketLengths[] = {
- /* 0x00 => */ ISDV4_PKGLEN_TOUCH93,
- /* 0x01 => */ ISDV4_PKGLEN_TOUCH9A,
- /* 0x02 => */ ISDV4_PKGLEN_TOUCH93,
- /* 0x03 => */ ISDV4_PKGLEN_TOUCH9A,
- /* 0x04 => */ ISDV4_PKGLEN_TOUCH9A,
- /* 0x05 => */ ISDV4_PKGLEN_TOUCH2FG
- };
-
- /* ISDV4 protocol parsing structs. */
-
- /* Query reply data */
- typedef struct {
- unsigned char data_id; /* always 00H */
- uint16_t x_max;
- uint16_t y_max;
- uint16_t pressure_max;
- uint8_t tilt_x_max;
- uint8_t tilt_y_max;
- uint16_t version;
- } ISDV4QueryReply;
-
- /* Touch Query reply data */
- typedef struct {
- uint8_t data_id; /* always 01H */
- uint8_t panel_resolution;
- uint8_t sensor_id;
- uint16_t x_max;
- uint16_t y_max;
- uint8_t capacity_resolution;
- 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;
-
- static inline int isdv4ParseQuery(const unsigned char *buffer, const size_t len,
- ISDV4QueryReply *reply)
- {
- int header, control;
-
- if (!reply || len < ISDV4_PKGLEN_TPCCTL)
- return 0;
-
- header = !!(buffer[0] & HEADER_BIT);
- control = !!(buffer[0] & CONTROL_BIT);
-
- if (!header || !control)
- return -1;
-
- reply->data_id = buffer[0] & DATA_ID_MASK;
-
- /* FIXME: big endian? */
- reply->x_max = (buffer[1] << 9) | (buffer[2] << 2) | ((buffer[6] >> 5) & 0x3);
- reply->y_max = (buffer[3] << 9) | (buffer[4] << 2) | ((buffer[6] >> 3) & 0x3);
- reply->pressure_max = buffer[5] | (buffer[6] & 0x7);
- reply->tilt_y_max = buffer[7];
- reply->tilt_x_max = buffer[8];
- reply->version = buffer[9] << 7 | buffer[10];
-
- return ISDV4_PKGLEN_TPCCTL;
- }
-
- static inline int isdv4ParseTouchQuery(const unsigned char *buffer, const size_t len,
- ISDV4TouchQueryReply *reply)
- {
- int header, control;
-
- if (!reply || len < ISDV4_PKGLEN_TPCCTL)
- return 0;
-
- header = !!(buffer[0] & HEADER_BIT);
- control = !!(buffer[0] & CONTROL_BIT);
-
- if (!header || !control)
- return -1;
-
- reply->data_id = buffer[0] & DATA_ID_MASK;
- reply->sensor_id = buffer[2] & 0x7;
- reply->panel_resolution = buffer[1];
- /* FIXME: big endian? */
- reply->x_max = (buffer[3] << 9) | (buffer[4] << 2) | ((buffer[2] >> 5) & 0x3);
- reply->y_max = (buffer[5] << 9) | (buffer[6] << 2) | ((buffer[2] >> 3) & 0x3);
- reply->capacity_resolution = buffer[7];
- reply->version = buffer[9] << 7 | buffer[10];
-
- 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;
- }
-
- #endif /* ISDV4_H */
-
- /* vim: set noexpandtab tabstop=8 shiftwidth=8: */
-