Instead of having the protocol parsing code directly in the matching functions,
move it to a separate function and return a struct with the interesting data
already set. This eases code readability and improves debugging between
protocol parsing errors and general driver bugs.

Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net>
---
 src/Makefile.am     |    2 +-
 src/wcmISDV4.c      |  120 ++++++++++++++++++++++++++++++++++++++++++---------
 src/wcmISDV4.h      |   50 +++++++++++++++++++++
 src/xf86WacomDefs.h |    2 +
 4 files changed, 152 insertions(+), 22 deletions(-)
 create mode 100644 src/wcmISDV4.h

diff --git a/src/Makefile.am b/src/Makefile.am
index c5de655..e332ca8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -34,7 +34,7 @@ AM_CFLAGS = $(XORG_CFLAGS) $(CWARNFLAGS)
 INCLUDES=-I$(top_srcdir)/include/
 
 @driver_n...@_drv_la_sources = xf86Wacom.c xf86Wacom.h \
-       wcmCommon.c wcmConfig.c wcmISDV4.c \
+       wcmCommon.c wcmConfig.c wcmISDV4.c wcmISDV4.h \
        wcmFilter.c wcmFilter.h xf86WacomDefs.h \
        wcmUSB.c wcmXCommand.c wcmValidateDevice.c \
        wcmTouchFilter.c
diff --git a/src/wcmISDV4.c b/src/wcmISDV4.c
index 8d96216..f60686b 100644
--- a/src/wcmISDV4.c
+++ b/src/wcmISDV4.c
@@ -25,6 +25,7 @@
 #include <xf86_OSproc.h>
 #include "wcmFilter.h"
 #include <linux/serial.h>
+#include "wcmISDV4.h"
 
 #define ISDV4_QUERY "*"       /* ISDV4 query command */
 #define ISDV4_TOUCH_QUERY "%" /* ISDV4 touch query command */
@@ -44,6 +45,11 @@ static int wcmSerialValidate(LocalDevicePtr local, const 
unsigned char* data);
 static int wcmWaitForTablet(LocalDevicePtr local, char * data, int size);
 static int wcmWriteWait(LocalDevicePtr local, const char* request);
 
+static inline int isdv4ParseQuery(const char *buffer, const size_t len,
+                                 ISDV4QueryReply *reply);
+static inline int isdv4ParseTouchQuery(const char *buffer, const size_t len,
+                                       ISDV4TouchQueryReply *reply);
+
 
        WacomDeviceClass gWacomISDV4Device =
        {
@@ -260,20 +266,28 @@ static int isdv4GetRanges(LocalDevicePtr local)
        ret = isdv4Query(local, ISDV4_QUERY, data);
        if (ret == Success)
        {
+               ISDV4QueryReply reply;
+               int rc;
+
+               rc = isdv4ParseQuery(data, sizeof(data), &reply);
+               if (rc <= 0)
+               {
+                       xf86Msg(X_ERROR, "Error while parsing ISDV4 query.\n");
+                       return BadAlloc;
+               }
+
                /* transducer data */
-               common->wcmMaxZ = ( data[5] | ((data[6] & 0x07) << 7) );
-               common->wcmMaxX = ( (data[1] << 9) | 
-                       (data[2] << 2) | ( (data[6] & 0x60) >> 5) );      
-               common->wcmMaxY = ( (data[3] << 9) | (data[4] << 2 ) 
-                       | ( (data[6] & 0x18) >> 3) );
-               if (data[7] && data[8])
+               common->wcmMaxZ = reply.pressure_max;
+               common->wcmMaxX = reply.x_max;
+               common->wcmMaxY = reply.y_max;
+               if (reply.tilt_x_max && reply.tilt_y_max)
                {
-                       common->wcmMaxtiltX = data[7] + 1;
-                       common->wcmMaxtiltY = data[8] + 1;
+                       common->wcmMaxtiltX = reply.tilt_x_max;
+                       common->wcmMaxtiltY = reply.tilt_y_max;
                        common->wcmFlags |= TILT_ENABLED_FLAG;
                }
-                       
-               common->wcmVersion = ( data[10] | (data[9] << 7) );
+
+               common->wcmVersion = reply.version;
 
                /* default to no pen 2FGT if size is undefined */
                if (!common->wcmMaxX || !common->wcmMaxY)
@@ -289,7 +303,17 @@ static int isdv4GetRanges(LocalDevicePtr local)
        common->wcmISDV4Speed = 38400;
        if (isdv4Query(local, ISDV4_TOUCH_QUERY, data) == Success)
        {
-               switch (data[2] & 0x07)
+               ISDV4TouchQueryReply reply;
+               int rc;
+
+               rc = isdv4ParseTouchQuery(data, sizeof(data), &reply);
+               if (rc <= 0)
+               {
+                       xf86Msg(X_ERROR, "Error while parsing ISDV4 touch 
query.\n");
+                       return BadAlloc;
+               }
+
+               switch (reply.sensor_id)
                {
                        case 0x00: /* resistive touch & pen */
                                common->wcmPktLength = ISDV4_PKGLEN_TOUCH93;
@@ -319,7 +343,7 @@ static int isdv4GetRanges(LocalDevicePtr local)
                                break;
                }
 
-               switch(data[0] & 0x3f)
+               switch(reply.data_id)
                {
                                /* single finger touch */
                        case 0x01:
@@ -348,21 +372,19 @@ static int isdv4GetRanges(LocalDevicePtr local)
                }
 
                /* don't overwrite the default */
-               if (((data[2]& 0x78) | data[3] | data[4] | data[5] | data[6]))
+               if (reply.x_max | reply.y_max)
                {
-                       common->wcmMaxTouchX = ((data[3] << 9) |
-                                (data[4] << 2) | ((data[2] & 0x60) >> 5));
-                       common->wcmMaxTouchY = ((data[5] << 9) |
-                                (data[6] << 2) | ((data[2] & 0x18) >> 3));
+                       common->wcmMaxTouchX = reply.x_max;
+                       common->wcmMaxTouchY = reply.y_max;
                }
-               else if (data[1])
+               else if (reply.panel_resolution)
                        common->wcmMaxTouchX = common->wcmMaxTouchY =
-                                (int)(1 << data[1]);
+                               (1 << reply.panel_resolution);
 
-               if (data[1])
+               if (reply.panel_resolution)
                        common->wcmTouchResolX = common->wcmTouchResolY = 10;
 
-               common->wcmVersion = ( data[10] | (data[9] << 7) );
+               common->wcmVersion = reply.version;
                ret = Success;
 
                DBG(2, priv, "touch speed=%d "
@@ -703,4 +725,60 @@ int isdv4ProbeKeys(LocalDevicePtr local, unsigned long 
*keys)
        return tablet_id;
 }
 
+/* Convert buffer data of buffer sized len into a query reply.
+ * Returns the number of bytes read from buffer or 0 if the buffer was on
+ * insufficient length. Returns -1 on parsing or internal errors.
+ */
+static inline int isdv4ParseQuery(const 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 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;
+}
 /* vim: set noexpandtab shiftwidth=8: */
diff --git a/src/wcmISDV4.h b/src/wcmISDV4.h
new file mode 100644
index 0000000..93c5e19
--- /dev/null
+++ b/src/wcmISDV4.h
@@ -0,0 +1,50 @@
+/*
+ * 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 WCMISDV4_H
+#define WCMISDV4_H
+
+/* 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;
+
+#endif /* WCMISDV4_H */
+
+/* vim: set noexpandtab shiftwidth=8: */
diff --git a/src/xf86WacomDefs.h b/src/xf86WacomDefs.h
index 3a9a89a..d4e18f8 100644
--- a/src/xf86WacomDefs.h
+++ b/src/xf86WacomDefs.h
@@ -40,6 +40,8 @@
 #define PROXOUT_GRAPHIRE_DISTANCE      42
 
 #define HEADER_BIT      0x80
+#define CONTROL_BIT     0x40
+#define DATA_ID_MASK    0x3F
 
 #ifndef BTN_TOOL_DOUBLETAP
 #define BTN_TOOL_DOUBLETAP 0x14d
-- 
1.6.6.1


------------------------------------------------------------------------------
Download Intel&#174; 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

Reply via email to