On Tue, Sep 27, 2011 at 06:03:55PM -0700, Jason Gerecke wrote: > 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)
actually, if you want to make this really useful, you could return a union in the form union propdata { char *c; int *i; float *f; }; and do the convertion to/fro the stupid property long format for 32-byte properties. it would likely make the callers more clear too. see xinput's src/property.c for an example. Cheers, Peter > +{ > + 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 > ------------------------------------------------------------------------------ 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