From 08cb75f6dfa6885e7c63a82bb8ae40bc4e7306e7 Mon Sep 17 00:00:00 2001 From: Peter Hutterer 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 --- 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 #include -#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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