/usr/include/xorg/isdv4.h is in xserver-xorg-input-wacom 1:0.32.0-0ubuntu3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | /*
* 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
#include <stdint.h>
#include <stddef.h>
#include <string.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[6] & 0x7) << 7 | buffer[5];
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: */
|