[PATCH 2/2] xinput: add set-prop command

Peter Hutterer peter.hutterer at who-t.net
Sun Apr 19 18:40:25 PDT 2009


On Thu, Apr 16, 2009 at 06:55:47PM +0200, Julien Cristau wrote:
> There's no reason to require the user to know the difference between
> set-int-prop, set-float-prop and set-atom-prop, and to know the required
> format for each integer property, since we can just ask
> XGetDeviceProperty.

Agree with the intent of the patch, but the float handling is broken on 64
bit. Floats need to be passed in as longs in the library.

> ---
>  src/property.c |   99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  src/xinput.c   |    4 ++
>  src/xinput.h   |   11 ++++++
>  3 files changed, 114 insertions(+), 0 deletions(-)
> 
> diff --git a/src/property.c b/src/property.c
> index 31a0346..385dcb1 100644
> --- a/src/property.c
> +++ b/src/property.c
> @@ -462,4 +462,103 @@ set_atom_prop(Display *dpy, int argc, char** argv, char* n, char *desc)
>      return EXIT_SUCCESS;
>  }
>  
> +int set_prop(Display *dpy, int argc, char **argv, char *n, char *desc)
> +{
> +    XDeviceInfo  *info;
> +    XDevice      *dev;
> +    Atom          prop;
> +    Atom          type;
> +    char         *name;
> +    int           i;
> +    Atom          float_atom;
> +    int           format, nelements = 0;
> +    unsigned long act_nitems, bytes_after;
> +    char         *endptr;
> +    union { unsigned char *c; short *s; long *l; float *f; Atom *a; } data;

please add linebreaks in between to improve legibility

> +
> +    if (argc < 3)
> +    {
> +        fprintf(stderr, "Usage: xinput %s %s\n", n, desc);
> +        return EXIT_FAILURE;
> +    }
> +
> +    info = find_device_info(dpy, argv[0], False);
> +    if (!info)
> +    {
> +        fprintf(stderr, "unable to find device %s\n", argv[0]);
> +        return EXIT_FAILURE;
> +    }
> +
> +    dev = XOpenDevice(dpy, info->id);
> +    if (!dev)
> +    {
> +        fprintf(stderr, "unable to open device %s\n", argv[0]);
> +        return EXIT_FAILURE;
> +    }
> +
> +    name = argv[1];
> +
> +    prop = parse_atom(dpy, name);
> +
> +    if (prop == None) {
> +        fprintf(stderr, "invalid property %s\n", name);
> +        return EXIT_FAILURE;
> +    }
> +
> +    float_atom = XInternAtom(dpy, "FLOAT", False);
> +
> +    nelements = argc - 2;
> +    if (XGetDeviceProperty(dpy, dev, prop, 0, 0, False, AnyPropertyType,
> +                           &type, &format, &act_nitems, &bytes_after, &data.c)
> +            != Success) {
> +        fprintf(stderr, "failed to get property type and format for %s\n", name);
> +        return EXIT_FAILURE;
> +    }
>  
> +    XFree(data.c);
> +
> +    if (type == None) {
> +        fprintf(stderr, "property %s doesn't exist\n", name);
> +        return EXIT_FAILURE;
> +    }
> +
> +    data.c = calloc(nelements, sizeof(long));
> +
> +    for (i = 0; i < nelements; i++)
> +    {
> +        if (type == XA_INTEGER) {
> +            switch (format)
> +            {
> +                case 8:
> +                    data.c[i] = atoi(argv[2 + i]);
> +                    break;
> +                case 16:
> +                    data.s[i] = atoi(argv[2 + i]);
> +                    break;
> +                case 32:
> +                    data.l[i] = atoi(argv[2 + i]);
> +                    break;
> +                default:
> +                    fprintf(stderr, "unexpected size for property %s", name);
> +                    return EXIT_FAILURE;
> +            }
> +        } else if (type == float_atom) {
> +            data.f[i] = strtod(argv[2 + i], &endptr);
> +            if (endptr == argv[2 + i]) {
> +                fprintf(stderr, "argument %s could not be parsed\n", argv[2 + i]);
> +                return EXIT_FAILURE;
> +            }
> +        } else if (type == XA_ATOM) {
> +            data.a[i] = parse_atom(dpy, argv[2 + i]);
> +        } else {
> +            fprintf(stderr, "unexpected type for property %s\n", name);
> +            return EXIT_FAILURE;
> +        }
> +    }
> +
> +    XChangeDeviceProperty(dpy, dev, prop, type, format, PropModeReplace,
> +                          data.c, nelements);
> +    free(data.c);
> +    XCloseDevice(dpy, dev);
> +    return EXIT_SUCCESS;
> +}
> diff --git a/src/xinput.c b/src/xinput.c
> index b319326..f584459 100644
> --- a/src/xinput.c
> +++ b/src/xinput.c
> @@ -131,6 +131,10 @@ static entry drivers[] =
>        "<device> <property>",
>        delete_prop
>      },
> +    { "set-prop",
> +      "<device> <property> <val> [<val> ...]",
> +      set_prop
> +    },
>      {NULL, NULL, NULL
>      }
>  };
> diff --git a/src/xinput.h b/src/xinput.h
> index 3c36497..24c0417 100644
> --- a/src/xinput.h
> +++ b/src/xinput.h
> @@ -289,4 +289,15 @@ delete_prop(
>  #endif
>  );
>  
> +int
> +set_prop(
> +#if NeedFunctionPrototypes
> +		Display*	display,
> +		int		argc,
> +		char		*argv[],
> +		char		*prog_name,
> +		char		*prog_desc
> +#endif
> +);
> +
>  /* end of xinput.h */
> -- 
> 1.6.2.3

maybe set-int-prop/set-float-prop should be using set-prop now to avoid
duplication?

Cheers,
  Peter


More information about the xorg-devel mailing list