Replaces several near-identical calls to XGetDeviceProperty with
a single centralized function to do the same thing. The new '_get'
function is responsible for reading the property from the server,
verifying its format matches that which is intended, and returning
a pointer to the requested piece.

Signed-off-by: Jason Gerecke <killert...@gmail.com>
---
 tools/xsetwacom.c |  217 ++++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 147 insertions(+), 70 deletions(-)

diff --git a/tools/xsetwacom.c b/tools/xsetwacom.c
index 7202b23..392b063 100644
--- a/tools/xsetwacom.c
+++ b/tools/xsetwacom.c
@@ -101,6 +101,8 @@ typedef struct _param
 
 
 /* get_func/set_func calls for special parameters */
+static void* _get_property(Display *dpy, XDevice *dev, const char *prop_name, 
int format, Atom type, unsigned long *items);
+static void* _get(Display *dpy, XDevice *dev, const char *prop_name, int 
prop_offset, int format, Atom type, int items);
 static void map_actions(Display *dpy, XDevice *dev, param_t *param, int argc, 
char **argv);
 static void set_mode(Display *dpy, XDevice *dev, param_t *param, int argc, 
char **argv);
 static void get_mode(Display *dpy, XDevice *dev, param_t *param, int argc, 
char **argv);
@@ -1650,6 +1652,127 @@ out:
        free(data);
 }
 
+/**
+ * Obtains a property from the server. This function is a wrapper around
+ * XGetDeviceProperty which ensures that a pointer to the entire property
+ * data is returned, as well as verifying it has the expected type and
+ * format. If this function fails for any reason, *items will be zero and
+ * the function will return NULL.
+ *
+ * @param dpy        X11 display to connect to
+ * @param dev        Device to query
+ * @param prop_name  Name of device property
+ * @param format     Format of the property (8/16/32)
+ * @param type       Type of the property
+ * @param items      Number of 'format'-bit items successfully retrieved from 
the server
+ * @return           Pointer to the requested data. Must be 'free()'-ed
+ */
+static void* _get_property(Display *dpy, XDevice *dev, const char *prop_name,
+                          int format, Atom type, unsigned long *items)
+{
+       int read_format, error;
+       unsigned long read_items, bytes_after;
+       Atom read_prop, read_type;
+       unsigned char *read = NULL;
+       void *data = NULL;
+
+       *items = 0;
+
+       read_prop = XInternAtom(dpy, prop_name, True);
+       if (!read_prop || !test_property(dpy, dev, read_prop))
+       {
+               printf("Property '%s' does not exist on device.\n", prop_name);
+               goto error;
+       }
+
+       do
+       {
+               int offset = *items * format / 8;
+               void *tmp;
+
+               error = XGetDeviceProperty(dpy, dev, read_prop, offset / 4, 1,
+                                           False, AnyPropertyType, &read_type,
+                                           &read_format, &read_items, 
&bytes_after,
+                                           &read);
+
+               if (error != 0)
+               {
+                       fprintf(stderr, "   %-23s = XGetDeviceProperty error 
%d\n",
+                               prop_name, error);
+                       XFree(read);
+                       goto error;
+               }
+               else if (format != read_format || type != read_type)
+               {
+                       fprintf(stderr, "   %-23s = property mismatch: expected 
type %d, format %d; got type %d, format %d\n",
+                               prop_name, format, type, read_format, 
read_type);
+                       XFree(read);
+                       goto error;
+               }
+
+               *items += read_items;
+               tmp = realloc(data, *items * format / 8);
+               if (tmp == NULL)
+               {
+                       fprintf(stderr, "Unable to allocate memory.\n");
+                       XFree(read);
+                       goto error;
+               }
+               else
+               {
+                       data = tmp;
+                       memcpy(&data[offset], read, read_items * format / 8);
+                       XFree(read);
+               }
+       }
+       while (bytes_after > 0);
+       return data;
+
+error:
+       free(data);
+       *items = 0;
+       return NULL;
+}
+
+/**
+ * Obtains sub-values from a specified server property. This function
+ * relies on '_get_property' to verify the type and format match what
+ * is expected. If this function fails for any reason, the function
+ * will return NULL.
+ *
+ * @param dpy          X11 display to connect to
+ * @param dev          Device to query
+ * @param prop_name    Name of device property
+ * @param prop_offset  Offset (in items) to begin reading
+ * @param format       Format of the underlying property (8/16/32)
+ * @param type         Type of the underlying property
+ * @param items        Number of items to read
+ * @return             Pointer to the requested data; must be 'free()'-ed
+ */
+static void* _get(Display *dpy, XDevice *dev, const char *prop_name, int 
prop_offset,
+                  int format, Atom type, int items)
+{
+       unsigned long read_items;
+       void *read, *data;
+
+       read = _get_property(dpy, dev, prop_name, format, type, &read_items);
+       if (read == NULL)
+               return NULL;
+
+       if (items > prop_offset + read_items)
+       {
+               fprintf(stderr, "   %-23s = count mismatch: expected at least 
%d got %d\n",
+                       prop_name, items, read_items);
+               free(read);
+               return NULL;
+       }
+
+       data = malloc(items * format / 8);
+       memcpy(data, read + (prop_offset * format / 8), items * format / 8);
+       free(read);
+       return data;
+}
+
 static void get_mode(Display *dpy, XDevice *dev, param_t* param, int argc, 
char **argv)
 {
        XDeviceInfo *info, *d = NULL;
@@ -1689,10 +1812,7 @@ static void get_mode(Display *dpy, XDevice *dev, 
param_t* param, int argc, char
 static void get_rotate(Display *dpy, XDevice *dev, param_t* param, int argc, 
char **argv)
 {
        char *rotation = NULL;
-       Atom prop, type;
-       int format;
-       unsigned char* data;
-       unsigned long nitems, bytes_after;
+       char *data;
 
        if (argc != 0)
        {
@@ -1700,25 +1820,12 @@ static void get_rotate(Display *dpy, XDevice *dev, 
param_t* param, int argc, cha
                return;
        }
 
-       prop = XInternAtom(dpy, param->prop_name, True);
-       if (!prop)
-       {
-               fprintf(stderr, "Property for '%s' not available.\n",
-                       param->name);
-               return;
-       }
-
        TRACE("Getting rotation for device %ld.\n", dev->device_id);
 
-       XGetDeviceProperty(dpy, dev, prop, 0, 1000, False, AnyPropertyType,
-                               &type, &format, &nitems, &bytes_after, &data);
-
-       if (nitems == 0 || format != 8)
-       {
-               fprintf(stderr, "Property for '%s' has no or wrong value - this 
is a bug.\n",
-                       param->name);
+       data = _get(dpy, dev, param->prop_name, param->prop_offset, 
param->prop_format,
+                   param->prop_type, param->arg_count);
+       if (data == NULL)
                return;
-       }
 
        switch(*data)
        {
@@ -1737,7 +1844,7 @@ static void get_rotate(Display *dpy, XDevice *dev, 
param_t* param, int argc, cha
        }
 
        print_value(param, "%s", rotation);
-
+       free(data);
        return;
 }
 
@@ -1858,36 +1965,14 @@ static int get_actions(Display *dpy, XDevice *dev,
  */
 static int get_button(Display *dpy, XDevice *dev, param_t *param, int offset)
 {
-       Atom prop, type;
-       int format;
-       unsigned long nitems, bytes_after;
-       unsigned char *data;
-
-       prop = XInternAtom(dpy, param->prop_name, True);
-
-       if (!prop)
-               return 0;
-
-       XGetDeviceProperty(dpy, dev, prop, 0, 100, False,
-                          AnyPropertyType, &type, &format, &nitems,
-                          &bytes_after, (unsigned char**)&data);
-
-       if (offset >= nitems)
-       {
-               XFree(data);
-               return 0;
-       }
+       unsigned char *data = _get(dpy, dev, param->prop_name, offset,
+                                  8, XA_INTEGER, 1);
 
-       prop = data[offset];
-       XFree(data);
-
-       if (format != 8 || type != XA_INTEGER || !prop)
-       {
+       if (data == NULL)
                return 0;
-       }
-
-       print_value(param, "%d", prop);
 
+       print_value(param, "%d", *data);
+       free(data);
        return 1;
 }
 
@@ -1904,6 +1989,7 @@ static int get_button(Display *dpy, XDevice *dev, param_t 
*param, int offset)
  */
 static void get_map(Display *dpy, XDevice *dev, param_t *param, int argc, 
char** argv)
 {
+       Atom prop;
        int offset = param->prop_offset;
 
        TRACE("Getting button map for device %ld.\n", dev->device_id);
@@ -1928,6 +2014,14 @@ static void get_map(Display *dpy, XDevice *dev, param_t 
*param, int argc, char**
                argv = &argv[1]; /*... ditto ...                        */
        }
 
+       prop = XInternAtom(dpy, param->prop_name, True);
+       if (!prop || !test_property(dpy, dev, prop))
+       {
+               printf("Property '%s' does not exist on device.\n",
+                      param->prop_name);
+               return;
+       }
+
 
        if (get_actions(dpy, dev, param, offset))
                return;
@@ -2438,24 +2532,11 @@ static void get(Display *dpy, enum printformat 
printformat, int argc, char **arg
 
 static void get_param(Display *dpy, XDevice *dev, param_t *param, int argc, 
char **argv)
 {
-       Atom prop = None, type;
-       int format;
+       Atom prop = None;
        unsigned char* data;
-       unsigned long nitems, bytes_after;
        int i;
        char str[100] = {0};
 
-       if (param->prop_name)
-       {
-               prop = XInternAtom(dpy, param->prop_name, True);
-               if (!prop || !test_property(dpy, dev, prop))
-               {
-                       printf("Property '%s' does not exist on device.\n",
-                               param->prop_name);
-                       return;
-               }
-       }
-
        if (param->get_func)
        {
                TRACE("custom get func for param\n");
@@ -2463,16 +2544,12 @@ static void get_param(Display *dpy, XDevice *dev, 
param_t *param, int argc, char
                return;
        }
 
+       TRACE("Getting property %s, offset %d\n", param->prop_name, 
param->prop_offset);
 
-       TRACE("Getting property %ld, offset %d\n", prop, param->prop_offset);
-       XGetDeviceProperty(dpy, dev, prop, 0, 1000, False, AnyPropertyType,
-                               &type, &format, &nitems, &bytes_after, &data);
-
-       if (nitems <= param->prop_offset)
-       {
-               fprintf(stderr, "Property offset doesn't exist.\n");
+       data = data = _get(dpy, dev, param->prop_name, param->prop_offset, 
param->prop_format,
+                          param->prop_type, param->arg_count);
+       if (data == NULL)
                return;
-       }
 
        for (i = 0; i < param->arg_count; i++)
        {
-- 
1.7.6


------------------------------------------------------------------------------
All the data continuously generated in your IT infrastructure contains a
definitive record of customers, application performance, security
threats, fraudulent activity and more. Splunk takes this data and makes
sense of it. Business sense. IT sense. Common sense.
http://p.sf.net/sfu/splunk-d2dcopy1
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to