xorg-x11-drv-wacom/0011-tools-split-out-the-debugger-into-the-actual-debugge.patch
2014-03-19 19:14:03 +10:00

1044 lines
24 KiB
Diff

From 08cb75f6dfa6885e7c63a82bb8ae40bc4e7306e7 Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Tue, 18 Mar 2014 10:44:46 +1000
Subject: [PATCH 11/14] tools: split out the debugger into the actual debugger
and shared code
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
---
tools/Makefile.am | 4 +
tools/isdv4-serial-debugger.c | 450 +-------------------------------------
tools/tools-shared.c | 487 ++++++++++++++++++++++++++++++++++++++++++
tools/tools-shared.h | 41 ++++
4 files changed, 534 insertions(+), 448 deletions(-)
create mode 100644 tools/tools-shared.c
create mode 100644 tools/tools-shared.h
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 5cd40e2..5eba0a6 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -24,6 +24,10 @@ AM_CPPFLAGS = -I$(top_srcdir)/include
AM_CFLAGS = $(XORG_CFLAGS) $(X11_CFLAGS)
AM_LDFLAGS = $(X11_LIBS)
+shared_sources = tools-shared.h tools-shared.c
+
+isdv4_serial_debugger_SOURCES = isdv4-serial-debugger.c $(shared_sources)
+
if UNITTESTS
check_PROGRAMS = xsetwacom-test
diff --git a/tools/isdv4-serial-debugger.c b/tools/isdv4-serial-debugger.c
index 65bed85..64d7a5b 100644
--- a/tools/isdv4-serial-debugger.c
+++ b/tools/isdv4-serial-debugger.c
@@ -39,12 +39,9 @@
#include <termios.h>
#include <unistd.h>
-#include "isdv4.h"
+#include "tools-shared.h"
-#define TRACE(...) \
- do { if (verbose) printf("... " __VA_ARGS__); } while(0)
-
-static int verbose = 0;
+int verbose = 0;
static void usage(void)
{
@@ -58,449 +55,6 @@ static void usage(void)
" --reset - send reset command before doing anything\n");
}
-static void version(void)
-{
- printf("%d.%d.%d\n", PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR,
- PACKAGE_VERSION_PATCHLEVEL);
-}
-
-int open_device(const char *path)
-{
- int fd;
- struct serial_struct ser;
-
- TRACE("Opening device '%s'.\n", path);
- fd = open(path, O_RDWR | O_NOCTTY);
-
- if (fd < 1)
- perror("Failed to open device file");
-
- if (ioctl(fd, TIOCGSERIAL, &ser) == -1)
- {
- perror("Not a serial device?");
- close(fd);
- fd = -1;
- goto out;
- }
-
-out:
- return fd;
-}
-
-int set_serial_attr(int fd, unsigned int baud)
-{
- struct termios t;
-
- if (tcgetattr(fd, &t) == -1)
- memset(&t, 0, sizeof(t));
-
- /* defaults from xf86OpenSerial */
- t.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
- t.c_oflag &= ~OPOST;
- t.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
- t.c_cflag &= ~(CSIZE|PARENB);
- t.c_cflag |= CS8|CLOCAL;
-
- /* wacom-specific */
- t.c_cflag &= ~(CSTOPB); /* stopbits 1 */
- t.c_cflag &= ~(CSIZE); /* databits 8 */
- t.c_cflag |= (CS8); /* databits 8 */
- t.c_cflag &= ~(PARENB); /* parity none */
- t.c_cc[VMIN] = 1; /* vmin 1 */
- t.c_cc[VTIME] = 10; /* vtime 10 */
- t.c_iflag |= IXOFF; /* flow controll xoff */
-
- TRACE("Baud rate is %d\n", baud);
-
- switch(baud)
- {
- case 19200: baud = B19200; break;
- case 38400: baud = B38400; break;
- default:
- fprintf(stderr, "Unsupported baud rate.\n");
- return -1;
- }
-
- cfsetispeed(&t, baud);
- cfsetospeed(&t, baud);
-
- return tcsetattr(fd, TCSANOW, &t);
-
-}
-
-static int write_to_tablet(int fd, char *command)
-{
- int len = 0;
-
- do {
- int l;
- l = write(fd, &command[len], strlen(command) - len);
-
- TRACE("Written '%s'.\n", command);
-
- if (l == -1 && errno != EAGAIN)
- {
- perror("not written.\n");
- break;
- }
- len += l;
- } while (errno == EAGAIN && len < strlen(command));
-
- return !(len == strlen(command));
-}
-
-static int stop_tablet(int fd)
-{
- int rc;
- char buffer[10];
- int fd_flags;
-
- TRACE("Writing STOP command.\n");
- rc = write_to_tablet(fd, ISDV4_STOP);
-
- usleep(250000);
-
- /* flush the line */
- fd_flags = fcntl(fd, F_GETFL);
- if (fcntl(fd, F_SETFL, fd_flags | O_NONBLOCK) == 0)
- {
- while (read(fd, buffer, sizeof(buffer)) > 0)
- TRACE("garbage flushed\n");
- fcntl(fd, F_SETFL, fd_flags);
- }
-
- return rc;
-}
-
-static int start_tablet(int fd)
-{
- TRACE("Writing SAMPLING command.\n");
- return write_to_tablet(fd, ISDV4_SAMPLING);
-}
-
-static int wait_for_tablet(int fd)
-{
-#if 0
- struct pollfd pfd = { fd, POLLIN, 0 };
- int rc;
-
- TRACE("Waiting for tablet...");
- rc = poll(&pfd, 1, 1000);
- if (rc < 0) {
- perror("poll failed.");
- return -1;
- } else if (rc == 0) {
- fprintf(stderr, "timeout.\n");
- return -1;
- } else if (pfd.revents & POLLIN)
- TRACE("data available.\n");
-
-#endif
- return 0;
-}
-
-static void memdump(const unsigned char *buffer, int len)
-{
- int n = 0;
- if (!len)
- return;
-
- while(len-- && ++n) {
- TRACE("%#hhx ", *buffer++);
- if (n % 8 == 0)
- TRACE("\n");
- }
-
- TRACE("\n");
-}
-
-static int skip_garbage(unsigned char *buffer, size_t len)
-{
- int i;
- for (i = 0; i < len; i++)
- if (buffer[i] & HEADER_BIT)
- break;
-
- if (i != 0)
- TRACE("skipping over %d bytes.\n", (i < len) ? i : -1);
-
- return (i < len) ? i : -1;
-}
-
-static int read_data(int fd, unsigned char* buffer, int min_len)
-{
- int len = 0;
- int attempts = 10;
- int skip;
-
- TRACE("Reading %d bytes from device.\n", min_len);
-redo:
- do {
- int l = read(fd, &buffer[len], min_len);
-
- if (l == -1) {
- if (errno != EAGAIN) {
- perror("Error reading data.");
- return -1;
- }
- wait_for_tablet(fd);
- attempts--;
- continue;
- } else {
- TRACE("read %d bytes in one chunk.\n", l);
- len += l;
- }
-
- } while (len < min_len && attempts);
-
- if (!attempts) {
- fprintf(stderr, "Only able to read %d bytes.\n", len);
- memdump(buffer, len);
- return -1;
- }
-
- TRACE("Read %d bytes.\n", len);
-
- skip = skip_garbage(buffer, len);
- if (skip > 0) {
- TRACE("%d bytes garbage.\n", skip);
- len -= skip;
- memmove(buffer, &buffer[skip], len);
- goto redo;
- }
-
- if (len > min_len)
- {
- TRACE("%d bytes unexpected data.\n", (len - min_len));
- memdump(&buffer[min_len], len - min_len);
- }
-
-
- return len;
-}
-
-static int query_tablet(int fd)
-{
- ISDV4QueryReply reply;
- ISDV4TouchQueryReply touch;
-
- unsigned char buffer[ISDV4_PKGLEN_TPCCTL];
- int len, rc;
-
- TRACE("Querying tablet.\n");
-
- if (stop_tablet(fd)) goto out;
- if (write_to_tablet(fd, ISDV4_QUERY)) goto out;
- if (wait_for_tablet(fd)) goto out;
-
- len = read_data(fd, buffer, ISDV4_PKGLEN_TPCCTL);
- if (len < 1)
- goto out;
-
- if (!(buffer[0] & CONTROL_BIT))
- {
- TRACE("+++ out of cheese error +++ redo from start +++\n");
- /* X driver claims that the first read may fail ??? */
- len = read_data(fd, buffer, ISDV4_PKGLEN_TPCCTL);
- }
-
- TRACE("Parsing query reply.\n");
- rc = isdv4ParseQuery(buffer, len, &reply);
- if (rc < 0)
- {
- fprintf(stderr, "parsing error code %d\n", rc);
- goto out;
- }
-
- printf("TABLET: version: %d\n", reply.version);
- printf("TABLET: x max: %d y max %d\n", reply.x_max, reply.y_max);
- printf("TABLET: tilt_x max: %d tilt_y max %d\n", reply.tilt_x_max, reply.tilt_y_max);
- printf("TABLET: pressure max: %d\n", reply.pressure_max);
-
- /* check for touch capabilities */
- TRACE("Trying touch query\n");
- if (stop_tablet(fd)) goto out;
- if (write_to_tablet(fd, ISDV4_TOUCH_QUERY)) goto out;
- if (wait_for_tablet(fd)) goto out;
-
- memset(buffer, 0, sizeof(buffer));
- len = read_data(fd, buffer, ISDV4_PKGLEN_TPCCTL);
- if (len < 1 && errno != EAGAIN)
- goto out;
-
- TRACE("Parsing touch query reply.\n");
- rc = isdv4ParseTouchQuery(buffer, len, &touch);
- if (rc < 0)
- {
- fprintf(stderr, "touch parsing error code %d\n", rc);
- /* failure to parse touch query is not fatal */
- } else {
- printf("TOUCH version: %d\n", touch.version);
- printf("TOUCH x max: %d y max %d\n", touch.x_max, touch.y_max);
- printf("TOUCH panel resolution: %d\n", touch.panel_resolution);
- printf("TOUCH capacity resolution: %d\n", touch.capacity_resolution);
- printf("TOUCH sensor id: %d\n", touch.sensor_id);
- }
-
- return touch.sensor_id;
-
-out:
- fprintf(stderr, "error during query.\n");
- return -1;
-}
-
-static int reset_tablet(int fd)
-{
- char buffer[10];
- TRACE("Reset requested, resetting tablet\n");
-
- if (stop_tablet(fd)) goto out;
- if (write_to_tablet(fd, ISDV4_RESET)) goto out;
- if (wait_for_tablet(fd)) goto out;
-
- memset(buffer, 0, sizeof(buffer));
- if (read(fd, buffer, sizeof(buffer)) < 1 && errno != EAGAIN)
- goto out;
-
- if (buffer[0] == '&')
- return 0;
-
-out:
- fprintf(stderr, "failed to reset tablet.\n");
- return 1;
-}
-
-static int parse_pen_packet(unsigned char* buffer)
-{
- int rc;
- ISDV4CoordinateData coord;
-
- TRACE("Parsing coordinate data.\n");
- rc = isdv4ParseCoordinateData(buffer, ISDV4_PKGLEN_TPCPEN, &coord);
- if (rc == -1) {
- fprintf(stderr, "failed to parse coordinate data.\n");
- return -1;
- }
-
- printf("PEN ");
- printf("%ld:", time(NULL));
- printf("%5d/%5d | pressure: %3d | ", coord.x, coord.y, coord.pressure);
- printf(" %3d/%3d |", coord.tilt_x, coord.tilt_y);
- printf("%1s %1s %1s %1s |\n", coord.proximity ? "p" : "",
- coord.tip ? "t" : "",
- coord.side ? "s" : "",
- coord.eraser ? "e" : "");
- return 0;
-}
-
-static int parse_touch_packet(unsigned char* buffer, int packetlength)
-{
- ISDV4TouchData touchdata;
- int rc;
-
- rc = isdv4ParseTouchData(buffer, packetlength, packetlength, &touchdata);
- if (rc == -1) {
- fprintf(stderr, "failed to parse touch data.\n");
- return -1;
- }
-
- printf("TOUCH ");
- printf("%ld:", time(NULL));
- printf("%5d/%5d | capacity: %3d | ", touchdata.x, touchdata.y, touchdata.capacity);
- printf("%d | ", touchdata.status);
-
- if (packetlength == ISDV4_PKGLEN_TOUCH2FG)
- printf("%d | %d/%d |", touchdata.finger2.status, touchdata.finger2.x, touchdata.finger2.y);
-
- printf("\n");
-
- return 0;
-
-}
-
-static int event_loop(int fd, int sensor_id)
-{
- unsigned char buffer[256];
- int dlen = 0;
- int packetlength = ISDV4_PKGLEN_TPCPEN;
-
- TRACE("Waiting for events\n");
-
- if (fcntl(fd, F_SETFD, O_NONBLOCK) == -1)
- perror("Nonblock failed.");
-
- memset(buffer, 0, sizeof(buffer));
-
- while (1) {
- int r, garbage = 0;
- r = read(fd, &buffer[dlen], sizeof(buffer) - dlen);
-
- if (r == -1) {
- if (errno == EAGAIN)
- continue;
- else {
- perror("Error during read.");
- goto out;
- }
- }
-
- dlen += r;
-
- if (buffer[0] & HEADER_BIT)
- {
- packetlength = ISDV4_PKGLEN_TPCPEN;
- if (buffer[0] & TOUCH_CONTROL_BIT)
- packetlength = ISDV4PacketLengths[sensor_id];
- } else {
- int bytes = skip_garbage(buffer, dlen);
- if (bytes > 0) {
- dlen -= bytes;
- memmove(buffer, &buffer[bytes], sizeof(buffer) - bytes);
- }
- continue;
- }
-
-
- if (dlen < packetlength)
- continue;
- TRACE("Expecting packet sized %d\n", packetlength);
-
- if (buffer[0] & CONTROL_BIT) {
- dlen -= packetlength;
- continue;
- }
-
- switch(packetlength)
- {
- case ISDV4_PKGLEN_TPCPEN:
- if (parse_pen_packet(buffer))
- garbage = 1;
- break;
- default: /* all others */
- if (parse_touch_packet(buffer, packetlength))
- garbage = 1;
- }
-
- if (garbage) {
- int bytes;
- bytes = skip_garbage(buffer, packetlength);
- if (bytes > 0) {
- dlen -= bytes;
- memmove(buffer, &buffer[bytes], sizeof(buffer) - bytes);
- }
- garbage = 0;
- } else {
- memmove(buffer, &buffer[packetlength], sizeof(buffer) - packetlength);
- dlen -= packetlength;
- }
- }
-
-
- return 0;
-out:
- return 1;
-}
-
int main (int argc, char **argv)
{
int fd;
diff --git a/tools/tools-shared.c b/tools/tools-shared.c
new file mode 100644
index 0000000..4d22cdf
--- /dev/null
+++ b/tools/tools-shared.c
@@ -0,0 +1,487 @@
+/*
+ * Copyright 2014 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#define WACOM_TOOLS
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/serial.h>
+#include <getopt.h>
+#include <poll.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <time.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "isdv4.h"
+#include "tools-shared.h"
+
+extern int verbose;
+
+void version(void)
+{
+ printf("%d.%d.%d\n", PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR,
+ PACKAGE_VERSION_PATCHLEVEL);
+}
+
+int open_device(const char *path)
+{
+ int fd;
+ struct serial_struct ser;
+
+ TRACE("Opening device '%s'.\n", path);
+ fd = open(path, O_RDWR | O_NOCTTY);
+
+ if (fd < 1)
+ perror("Failed to open device file");
+
+ if (ioctl(fd, TIOCGSERIAL, &ser) == -1)
+ {
+ perror("Not a serial device?");
+ close(fd);
+ fd = -1;
+ goto out;
+ }
+
+out:
+ return fd;
+}
+
+int set_serial_attr(int fd, unsigned int baud)
+{
+ struct termios t;
+
+ if (tcgetattr(fd, &t) == -1)
+ memset(&t, 0, sizeof(t));
+
+ /* defaults from xf86OpenSerial */
+ t.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
+ t.c_oflag &= ~OPOST;
+ t.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+ t.c_cflag &= ~(CSIZE|PARENB);
+ t.c_cflag |= CS8|CLOCAL;
+
+ /* wacom-specific */
+ t.c_cflag &= ~(CSTOPB); /* stopbits 1 */
+ t.c_cflag &= ~(CSIZE); /* databits 8 */
+ t.c_cflag |= (CS8); /* databits 8 */
+ t.c_cflag &= ~(PARENB); /* parity none */
+ t.c_cc[VMIN] = 1; /* vmin 1 */
+ t.c_cc[VTIME] = 10; /* vtime 10 */
+ t.c_iflag |= IXOFF; /* flow controll xoff */
+
+ TRACE("Baud rate is %d\n", baud);
+
+ switch(baud)
+ {
+ case 19200: baud = B19200; break;
+ case 38400: baud = B38400; break;
+ default:
+ fprintf(stderr, "Unsupported baud rate.\n");
+ return -1;
+ }
+
+ cfsetispeed(&t, baud);
+ cfsetospeed(&t, baud);
+
+ return tcsetattr(fd, TCSANOW, &t);
+
+}
+
+int write_to_tablet(int fd, char *command)
+{
+ int len = 0;
+
+ do {
+ int l;
+ l = write(fd, &command[len], strlen(command) - len);
+
+ TRACE("Written '%s'.\n", command);
+
+ if (l == -1 && errno != EAGAIN)
+ {
+ perror("not written.\n");
+ break;
+ }
+ len += l;
+ } while (errno == EAGAIN && len < strlen(command));
+
+ return !(len == strlen(command));
+}
+
+int stop_tablet(int fd)
+{
+ int rc;
+ char buffer[10];
+ int fd_flags;
+
+ TRACE("Writing STOP command.\n");
+ rc = write_to_tablet(fd, ISDV4_STOP);
+
+ usleep(250000);
+
+ /* flush the line */
+ fd_flags = fcntl(fd, F_GETFL);
+ if (fcntl(fd, F_SETFL, fd_flags | O_NONBLOCK) == 0)
+ {
+ while (read(fd, buffer, sizeof(buffer)) > 0)
+ TRACE("garbage flushed\n");
+ fcntl(fd, F_SETFL, fd_flags);
+ }
+
+ return rc;
+}
+
+int start_tablet(int fd)
+{
+ TRACE("Writing SAMPLING command.\n");
+ return write_to_tablet(fd, ISDV4_SAMPLING);
+}
+
+int wait_for_tablet(int fd)
+{
+#if 0
+ struct pollfd pfd = { fd, POLLIN, 0 };
+ int rc;
+
+ TRACE("Waiting for tablet...");
+ rc = poll(&pfd, 1, 1000);
+ if (rc < 0) {
+ perror("poll failed.");
+ return -1;
+ } else if (rc == 0) {
+ fprintf(stderr, "timeout.\n");
+ return -1;
+ } else if (pfd.revents & POLLIN)
+ TRACE("data available.\n");
+
+#endif
+ return 0;
+}
+
+void memdump(const unsigned char *buffer, int len)
+{
+ int n = 0;
+ if (!len)
+ return;
+
+ while(len-- && ++n) {
+ TRACE("%#hhx ", *buffer++);
+ if (n % 8 == 0)
+ TRACE("\n");
+ }
+
+ TRACE("\n");
+}
+
+int skip_garbage(unsigned char *buffer, size_t len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ if (buffer[i] & HEADER_BIT)
+ break;
+
+ if (i != 0)
+ TRACE("skipping over %d bytes.\n", (i < len) ? i : -1);
+
+ return (i < len) ? i : -1;
+}
+
+int read_data(int fd, unsigned char* buffer, int min_len)
+{
+ int len = 0;
+ int attempts = 10;
+ int skip;
+
+ TRACE("Reading %d bytes from device.\n", min_len);
+redo:
+ do {
+ int l = read(fd, &buffer[len], min_len);
+
+ if (l == -1) {
+ if (errno != EAGAIN) {
+ perror("Error reading data.");
+ return -1;
+ }
+ wait_for_tablet(fd);
+ attempts--;
+ continue;
+ } else {
+ TRACE("read %d bytes in one chunk.\n", l);
+ len += l;
+ }
+
+ } while (len < min_len && attempts);
+
+ if (!attempts) {
+ fprintf(stderr, "Only able to read %d bytes.\n", len);
+ memdump(buffer, len);
+ return -1;
+ }
+
+ TRACE("Read %d bytes.\n", len);
+
+ skip = skip_garbage(buffer, len);
+ if (skip > 0) {
+ TRACE("%d bytes garbage.\n", skip);
+ len -= skip;
+ memmove(buffer, &buffer[skip], len);
+ goto redo;
+ }
+
+ if (len > min_len)
+ {
+ TRACE("%d bytes unexpected data.\n", (len - min_len));
+ memdump(&buffer[min_len], len - min_len);
+ }
+
+
+ return len;
+}
+
+int query_tablet(int fd)
+{
+ ISDV4QueryReply reply;
+ ISDV4TouchQueryReply touch;
+
+ unsigned char buffer[ISDV4_PKGLEN_TPCCTL];
+ int len, rc;
+
+ TRACE("Querying tablet.\n");
+
+ if (stop_tablet(fd)) goto out;
+ if (write_to_tablet(fd, ISDV4_QUERY)) goto out;
+ if (wait_for_tablet(fd)) goto out;
+
+ len = read_data(fd, buffer, ISDV4_PKGLEN_TPCCTL);
+ if (len < 1)
+ goto out;
+
+ if (!(buffer[0] & CONTROL_BIT))
+ {
+ TRACE("+++ out of cheese error +++ redo from start +++\n");
+ /* X driver claims that the first read may fail ??? */
+ len = read_data(fd, buffer, ISDV4_PKGLEN_TPCCTL);
+ }
+
+ TRACE("Parsing query reply.\n");
+ rc = isdv4ParseQuery(buffer, len, &reply);
+ if (rc < 0)
+ {
+ fprintf(stderr, "parsing error code %d\n", rc);
+ goto out;
+ }
+
+ printf("TABLET: version: %d\n", reply.version);
+ printf("TABLET: x max: %d y max %d\n", reply.x_max, reply.y_max);
+ printf("TABLET: tilt_x max: %d tilt_y max %d\n", reply.tilt_x_max, reply.tilt_y_max);
+ printf("TABLET: pressure max: %d\n", reply.pressure_max);
+
+ /* check for touch capabilities */
+ TRACE("Trying touch query\n");
+ if (stop_tablet(fd)) goto out;
+ if (write_to_tablet(fd, ISDV4_TOUCH_QUERY)) goto out;
+ if (wait_for_tablet(fd)) goto out;
+
+ memset(buffer, 0, sizeof(buffer));
+ len = read_data(fd, buffer, ISDV4_PKGLEN_TPCCTL);
+ if (len < 1 && errno != EAGAIN)
+ goto out;
+
+ TRACE("Parsing touch query reply.\n");
+ rc = isdv4ParseTouchQuery(buffer, len, &touch);
+ if (rc < 0)
+ {
+ fprintf(stderr, "touch parsing error code %d\n", rc);
+ /* failure to parse touch query is not fatal */
+ } else {
+ printf("TOUCH version: %d\n", touch.version);
+ printf("TOUCH x max: %d y max %d\n", touch.x_max, touch.y_max);
+ printf("TOUCH panel resolution: %d\n", touch.panel_resolution);
+ printf("TOUCH capacity resolution: %d\n", touch.capacity_resolution);
+ printf("TOUCH sensor id: %d\n", touch.sensor_id);
+ }
+
+ return touch.sensor_id;
+
+out:
+ fprintf(stderr, "error during query.\n");
+ return -1;
+}
+
+int reset_tablet(int fd)
+{
+ char buffer[10];
+ TRACE("Reset requested, resetting tablet\n");
+
+ if (stop_tablet(fd)) goto out;
+ if (write_to_tablet(fd, ISDV4_RESET)) goto out;
+ if (wait_for_tablet(fd)) goto out;
+
+ memset(buffer, 0, sizeof(buffer));
+ if (read(fd, buffer, sizeof(buffer)) < 1 && errno != EAGAIN)
+ goto out;
+
+ if (buffer[0] == '&')
+ return 0;
+
+out:
+ fprintf(stderr, "failed to reset tablet.\n");
+ return 1;
+}
+
+int parse_pen_packet(unsigned char* buffer)
+{
+ int rc;
+ ISDV4CoordinateData coord;
+
+ TRACE("Parsing coordinate data.\n");
+ rc = isdv4ParseCoordinateData(buffer, ISDV4_PKGLEN_TPCPEN, &coord);
+ if (rc == -1) {
+ fprintf(stderr, "failed to parse coordinate data.\n");
+ return -1;
+ }
+
+ printf("PEN ");
+ printf("%ld:", time(NULL));
+ printf("%5d/%5d | pressure: %3d | ", coord.x, coord.y, coord.pressure);
+ printf(" %3d/%3d |", coord.tilt_x, coord.tilt_y);
+ printf("%1s %1s %1s %1s |\n", coord.proximity ? "p" : "",
+ coord.tip ? "t" : "",
+ coord.side ? "s" : "",
+ coord.eraser ? "e" : "");
+ return 0;
+}
+
+int parse_touch_packet(unsigned char* buffer, int packetlength)
+{
+ ISDV4TouchData touchdata;
+ int rc;
+
+ rc = isdv4ParseTouchData(buffer, packetlength, packetlength, &touchdata);
+ if (rc == -1) {
+ fprintf(stderr, "failed to parse touch data.\n");
+ return -1;
+ }
+
+ printf("TOUCH ");
+ printf("%ld:", time(NULL));
+ printf("%5d/%5d | capacity: %3d | ", touchdata.x, touchdata.y, touchdata.capacity);
+ printf("%d | ", touchdata.status);
+
+ if (packetlength == ISDV4_PKGLEN_TOUCH2FG)
+ printf("%d | %d/%d |", touchdata.finger2.status, touchdata.finger2.x, touchdata.finger2.y);
+
+ printf("\n");
+
+ return 0;
+
+}
+
+int event_loop(int fd, int sensor_id)
+{
+ unsigned char buffer[256];
+ int dlen = 0;
+ int packetlength = ISDV4_PKGLEN_TPCPEN;
+
+ TRACE("Waiting for events\n");
+
+ if (fcntl(fd, F_SETFD, O_NONBLOCK) == -1)
+ perror("Nonblock failed.");
+
+ memset(buffer, 0, sizeof(buffer));
+
+ while (1) {
+ int r, garbage = 0;
+ r = read(fd, &buffer[dlen], sizeof(buffer) - dlen);
+
+ if (r == -1) {
+ if (errno == EAGAIN)
+ continue;
+ else {
+ perror("Error during read.");
+ goto out;
+ }
+ }
+
+ dlen += r;
+
+ if (buffer[0] & HEADER_BIT)
+ {
+ packetlength = ISDV4_PKGLEN_TPCPEN;
+ if (buffer[0] & TOUCH_CONTROL_BIT)
+ packetlength = ISDV4PacketLengths[sensor_id];
+ } else {
+ int bytes = skip_garbage(buffer, dlen);
+ if (bytes > 0) {
+ dlen -= bytes;
+ memmove(buffer, &buffer[bytes], sizeof(buffer) - bytes);
+ }
+ continue;
+ }
+
+
+ if (dlen < packetlength)
+ continue;
+ TRACE("Expecting packet sized %d\n", packetlength);
+
+ if (buffer[0] & CONTROL_BIT) {
+ dlen -= packetlength;
+ continue;
+ }
+
+ switch(packetlength)
+ {
+ case ISDV4_PKGLEN_TPCPEN:
+ if (parse_pen_packet(buffer))
+ garbage = 1;
+ break;
+ default: /* all others */
+ if (parse_touch_packet(buffer, packetlength))
+ garbage = 1;
+ }
+
+ if (garbage) {
+ int bytes;
+ bytes = skip_garbage(buffer, packetlength);
+ if (bytes > 0) {
+ dlen -= bytes;
+ memmove(buffer, &buffer[bytes], sizeof(buffer) - bytes);
+ }
+ garbage = 0;
+ } else {
+ memmove(buffer, &buffer[packetlength], sizeof(buffer) - packetlength);
+ dlen -= packetlength;
+ }
+ }
+
+
+ return 0;
+out:
+ return 1;
+}
+
diff --git a/tools/tools-shared.h b/tools/tools-shared.h
new file mode 100644
index 0000000..0a1e41f
--- /dev/null
+++ b/tools/tools-shared.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2014 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 TOOLS_SHARED_H_
+#define TOOLS_SHARED_H_
+
+void version(void);
+int open_device(const char *path);
+int set_serial_attr(int fd, unsigned int baud);
+int write_to_tablet(int fd, char *command);
+int stop_tablet(int fd);
+int start_tablet(int fd);
+int wait_for_tablet(int fd);
+void memdump(const unsigned char *buffer, int len);
+int skip_garbage(unsigned char *buffer, size_t len);
+int read_data(int fd, unsigned char* buffer, int min_len);
+int query_tablet(int fd);
+int reset_tablet(int fd);
+int parse_pen_packet(unsigned char* buffer);
+int parse_touch_packet(unsigned char* buffer, int packetlength);
+int event_loop(int fd, int sensor_id);
+
+#define TRACE(...) \
+ do { if (verbose) printf("... " __VA_ARGS__); } while(0)
+
+#endif /* TOOLS_SHARED_H_ */
--
1.8.5.3