property.c revision 5b944e2a
15b944e2aSmrg/*
25b944e2aSmrg * Copyright 2007 Peter Hutterer
35b944e2aSmrg *
45b944e2aSmrg * Permission to use, copy, modify, distribute, and sell this software and its
55b944e2aSmrg * documentation for any purpose is hereby granted without fee, provided that
65b944e2aSmrg * the above copyright notice appear in all copies and that both that
75b944e2aSmrg * copyright notice and this permission notice appear in supporting
85b944e2aSmrg * documentation.
95b944e2aSmrg *
105b944e2aSmrg * The above copyright notice and this permission notice shall be included
115b944e2aSmrg * in all copies or substantial portions of the Software.
125b944e2aSmrg *
135b944e2aSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
145b944e2aSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
155b944e2aSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
165b944e2aSmrg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
175b944e2aSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
185b944e2aSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
195b944e2aSmrg * OTHER DEALINGS IN THE SOFTWARE.
205b944e2aSmrg *
215b944e2aSmrg * Except as contained in this notice, the name of the author shall
225b944e2aSmrg * not be used in advertising or otherwise to promote the sale, use or
235b944e2aSmrg * other dealings in this Software without prior written authorization
245b944e2aSmrg * from the author.
255b944e2aSmrg *
265b944e2aSmrg */
275b944e2aSmrg
285b944e2aSmrg#include <ctype.h>
295b944e2aSmrg#include <string.h>
305b944e2aSmrg#include <stdlib.h>
315b944e2aSmrg#include <stdint.h>
325b944e2aSmrg#include <X11/Xatom.h>
335b944e2aSmrg#include <X11/extensions/XIproto.h>
345b944e2aSmrg
355b944e2aSmrg#include "xinput.h"
365b944e2aSmrg
375b944e2aSmrgstatic void
385b944e2aSmrgprint_property(Display *dpy, XDevice* dev, Atom property)
395b944e2aSmrg{
405b944e2aSmrg    Atom                act_type;
415b944e2aSmrg    char                *name;
425b944e2aSmrg    int                 act_format;
435b944e2aSmrg    unsigned long       nitems, bytes_after;
445b944e2aSmrg    unsigned char       *data, *ptr;
455b944e2aSmrg    int                 j;
465b944e2aSmrg
475b944e2aSmrg    name = XGetAtomName(dpy, property);
485b944e2aSmrg    printf("\t%s (%ld):\t", name, property);
495b944e2aSmrg
505b944e2aSmrg    if (XGetDeviceProperty(dpy, dev, property, 0, 1000, False,
515b944e2aSmrg                           AnyPropertyType, &act_type, &act_format,
525b944e2aSmrg                           &nitems, &bytes_after, &data) == Success)
535b944e2aSmrg    {
545b944e2aSmrg        int float_atom = XInternAtom(dpy, "FLOAT", False);
555b944e2aSmrg
565b944e2aSmrg        ptr = data;
575b944e2aSmrg        printf("\t");
585b944e2aSmrg
595b944e2aSmrg        for (j = 0; j < nitems; j++)
605b944e2aSmrg        {
615b944e2aSmrg            switch(act_type)
625b944e2aSmrg            {
635b944e2aSmrg                case XA_INTEGER:
645b944e2aSmrg                    switch(act_format)
655b944e2aSmrg                    {
665b944e2aSmrg                        case 8:
675b944e2aSmrg                            printf("%d", *((int8_t*)ptr));
685b944e2aSmrg                            break;
695b944e2aSmrg                        case 16:
705b944e2aSmrg                            printf("%d", *((int16_t*)ptr));
715b944e2aSmrg                            break;
725b944e2aSmrg                        case 32:
735b944e2aSmrg                            printf("%d", *((int32_t*)ptr));
745b944e2aSmrg                            break;
755b944e2aSmrg                    }
765b944e2aSmrg                    break;
775b944e2aSmrg                case XA_STRING:
785b944e2aSmrg                    printf("\t%s", ptr);
795b944e2aSmrg                    break;
805b944e2aSmrg                case XA_ATOM:
815b944e2aSmrg                    printf("\t%s", XGetAtomName(dpy, *(Atom*)ptr));
825b944e2aSmrg                    break;
835b944e2aSmrg                default:
845b944e2aSmrg                    if (float_atom != None && act_type == float_atom)
855b944e2aSmrg                    {
865b944e2aSmrg                        printf("\t%f\n", *((float*)ptr));
875b944e2aSmrg                        break;
885b944e2aSmrg                    }
895b944e2aSmrg
905b944e2aSmrg                    printf("\t\t... of unknown type %s\n",
915b944e2aSmrg                            XGetAtomName(dpy, act_type));
925b944e2aSmrg                    break;
935b944e2aSmrg            }
945b944e2aSmrg
955b944e2aSmrg            ptr += act_format/8;
965b944e2aSmrg
975b944e2aSmrg            if (j < nitems - 1)
985b944e2aSmrg                printf(", ");
995b944e2aSmrg            if (act_type == XA_STRING)
1005b944e2aSmrg                break;
1015b944e2aSmrg        }
1025b944e2aSmrg        printf("\n");
1035b944e2aSmrg        XFree(data);
1045b944e2aSmrg    } else
1055b944e2aSmrg        printf("\tFetch failure\n");
1065b944e2aSmrg
1075b944e2aSmrg}
1085b944e2aSmrg
1095b944e2aSmrgint list_props(Display *dpy, int argc, char** argv, char* name, char *desc)
1105b944e2aSmrg{
1115b944e2aSmrg    XDeviceInfo *info;
1125b944e2aSmrg    XDevice     *dev;
1135b944e2aSmrg    int          i;
1145b944e2aSmrg    int         nprops;
1155b944e2aSmrg    Atom        *props;
1165b944e2aSmrg
1175b944e2aSmrg    if (argc == 0)
1185b944e2aSmrg    {
1195b944e2aSmrg        fprintf(stderr, "Usage: xinput %s %s\n", name, desc);
1205b944e2aSmrg        return EXIT_FAILURE;
1215b944e2aSmrg    }
1225b944e2aSmrg
1235b944e2aSmrg    for (i = 0; i < argc; i++)
1245b944e2aSmrg    {
1255b944e2aSmrg        info = find_device_info(dpy, argv[i], False);
1265b944e2aSmrg        if (!info)
1275b944e2aSmrg        {
1285b944e2aSmrg            fprintf(stderr, "unable to find device %s\n", argv[i]);
1295b944e2aSmrg            continue;
1305b944e2aSmrg        }
1315b944e2aSmrg
1325b944e2aSmrg        dev = XOpenDevice(dpy, info->id);
1335b944e2aSmrg        if (!dev)
1345b944e2aSmrg        {
1355b944e2aSmrg            fprintf(stderr, "unable to open device '%s'\n", info->name);
1365b944e2aSmrg            continue;
1375b944e2aSmrg        }
1385b944e2aSmrg
1395b944e2aSmrg        props = XListDeviceProperties(dpy, dev, &nprops);
1405b944e2aSmrg        if (!nprops)
1415b944e2aSmrg        {
1425b944e2aSmrg            printf("Device '%s' does not report any properties.\n", info->name);
1435b944e2aSmrg            continue;
1445b944e2aSmrg        }
1455b944e2aSmrg
1465b944e2aSmrg        printf("Device '%s':\n", info->name);
1475b944e2aSmrg        while(nprops--)
1485b944e2aSmrg        {
1495b944e2aSmrg            print_property(dpy, dev, props[nprops]);
1505b944e2aSmrg        }
1515b944e2aSmrg
1525b944e2aSmrg        XFree(props);
1535b944e2aSmrg        XCloseDevice(dpy, dev);
1545b944e2aSmrg    }
1555b944e2aSmrg    return EXIT_SUCCESS;
1565b944e2aSmrg}
1575b944e2aSmrg
1585b944e2aSmrgint
1595b944e2aSmrgset_int_prop(Display *dpy, int argc, char** argv, char* n, char *desc)
1605b944e2aSmrg{
1615b944e2aSmrg    XDeviceInfo *info;
1625b944e2aSmrg    XDevice     *dev;
1635b944e2aSmrg    Atom         prop;
1645b944e2aSmrg    char        *name;
1655b944e2aSmrg    int          i;
1665b944e2aSmrg    Bool         is_atom = True;
1675b944e2aSmrg    char        *data;
1685b944e2aSmrg    int          format, nelements =  0;
1695b944e2aSmrg
1705b944e2aSmrg    if (argc < 3)
1715b944e2aSmrg    {
1725b944e2aSmrg        fprintf(stderr, "Usage: xinput %s %s\n", n, desc);
1735b944e2aSmrg        return EXIT_FAILURE;
1745b944e2aSmrg    }
1755b944e2aSmrg
1765b944e2aSmrg    info = find_device_info(dpy, argv[0], False);
1775b944e2aSmrg    if (!info)
1785b944e2aSmrg    {
1795b944e2aSmrg        fprintf(stderr, "unable to find device %s\n", argv[0]);
1805b944e2aSmrg        return EXIT_FAILURE;
1815b944e2aSmrg    }
1825b944e2aSmrg
1835b944e2aSmrg    dev = XOpenDevice(dpy, info->id);
1845b944e2aSmrg    if (!dev)
1855b944e2aSmrg    {
1865b944e2aSmrg        fprintf(stderr, "unable to open device %s\n", argv[0]);
1875b944e2aSmrg        return EXIT_FAILURE;
1885b944e2aSmrg    }
1895b944e2aSmrg
1905b944e2aSmrg    name = argv[1];
1915b944e2aSmrg
1925b944e2aSmrg    for(i = 0; i < strlen(name); i++) {
1935b944e2aSmrg	if (!isdigit(name[i])) {
1945b944e2aSmrg            is_atom = False;
1955b944e2aSmrg	    break;
1965b944e2aSmrg	}
1975b944e2aSmrg    }
1985b944e2aSmrg
1995b944e2aSmrg    if (!is_atom)
2005b944e2aSmrg        prop = XInternAtom(dpy, name, False);
2015b944e2aSmrg    else
2025b944e2aSmrg        prop = atoi(name);
2035b944e2aSmrg
2045b944e2aSmrg    nelements = argc - 3;
2055b944e2aSmrg    format    = atoi(argv[2]);
2065b944e2aSmrg    if (format != 8 && format != 16 && format != 32)
2075b944e2aSmrg    {
2085b944e2aSmrg        fprintf(stderr, "Invalid format %d\n", format);
2095b944e2aSmrg        return EXIT_FAILURE;
2105b944e2aSmrg    }
2115b944e2aSmrg
2125b944e2aSmrg    data = calloc(nelements, format/8);
2135b944e2aSmrg    for (i = 0; i < nelements; i++)
2145b944e2aSmrg    {
2155b944e2aSmrg        switch(format)
2165b944e2aSmrg        {
2175b944e2aSmrg            case 8:
2185b944e2aSmrg                *(((int8_t*)data) + i) = atoi(argv[3 + i]);
2195b944e2aSmrg                break;
2205b944e2aSmrg            case 16:
2215b944e2aSmrg                *(((int16_t*)data) + i) = atoi(argv[3 + i]);
2225b944e2aSmrg                break;
2235b944e2aSmrg            case 32:
2245b944e2aSmrg                *(((int32_t*)data) + i) = atoi(argv[3 + i]);
2255b944e2aSmrg                break;
2265b944e2aSmrg        }
2275b944e2aSmrg    }
2285b944e2aSmrg
2295b944e2aSmrg    XChangeDeviceProperty(dpy, dev, prop, XA_INTEGER, format, PropModeReplace,
2305b944e2aSmrg                          (unsigned char*)data, nelements);
2315b944e2aSmrg
2325b944e2aSmrg    free(data);
2335b944e2aSmrg    XCloseDevice(dpy, dev);
2345b944e2aSmrg    return EXIT_SUCCESS;
2355b944e2aSmrg}
2365b944e2aSmrg
2375b944e2aSmrgint
2385b944e2aSmrgset_float_prop(Display *dpy, int argc, char** argv, char* n, char *desc)
2395b944e2aSmrg{
2405b944e2aSmrg    XDeviceInfo *info;
2415b944e2aSmrg    XDevice     *dev;
2425b944e2aSmrg    Atom         prop, float_atom;
2435b944e2aSmrg    char        *name;
2445b944e2aSmrg    int          i;
2455b944e2aSmrg    Bool         is_atom = True;
2465b944e2aSmrg    float       *data;
2475b944e2aSmrg    int          nelements =  0;
2485b944e2aSmrg    char*        endptr;
2495b944e2aSmrg
2505b944e2aSmrg    if (argc < 2)
2515b944e2aSmrg    {
2525b944e2aSmrg        fprintf(stderr, "Usage: xinput %s %s\n", n, desc);
2535b944e2aSmrg        return EXIT_FAILURE;
2545b944e2aSmrg    }
2555b944e2aSmrg
2565b944e2aSmrg    info = find_device_info(dpy, argv[0], False);
2575b944e2aSmrg    if (!info)
2585b944e2aSmrg    {
2595b944e2aSmrg        fprintf(stderr, "unable to find device %s\n", argv[0]);
2605b944e2aSmrg        return EXIT_FAILURE;
2615b944e2aSmrg    }
2625b944e2aSmrg
2635b944e2aSmrg    dev = XOpenDevice(dpy, info->id);
2645b944e2aSmrg    if (!dev)
2655b944e2aSmrg    {
2665b944e2aSmrg        fprintf(stderr, "unable to open device %s\n", argv[0]);
2675b944e2aSmrg        return EXIT_FAILURE;
2685b944e2aSmrg    }
2695b944e2aSmrg
2705b944e2aSmrg    name = argv[1];
2715b944e2aSmrg
2725b944e2aSmrg    for(i = 0; i < strlen(name); i++) {
2735b944e2aSmrg	if (!isdigit(name[i])) {
2745b944e2aSmrg            is_atom = False;
2755b944e2aSmrg	    break;
2765b944e2aSmrg	}
2775b944e2aSmrg    }
2785b944e2aSmrg
2795b944e2aSmrg    if (!is_atom)
2805b944e2aSmrg        prop = XInternAtom(dpy, name, False);
2815b944e2aSmrg    else
2825b944e2aSmrg        prop = atoi(name);
2835b944e2aSmrg
2845b944e2aSmrg    nelements = argc - 2;
2855b944e2aSmrg
2865b944e2aSmrg    float_atom = XInternAtom(dpy, "FLOAT", False);
2875b944e2aSmrg
2885b944e2aSmrg    if (float_atom == (Atom)0)
2895b944e2aSmrg    {
2905b944e2aSmrg	fprintf(stderr, "no FLOAT atom present in server\n");
2915b944e2aSmrg	return EXIT_FAILURE;
2925b944e2aSmrg    }
2935b944e2aSmrg
2945b944e2aSmrg    if (sizeof(float) != 4)
2955b944e2aSmrg    {
2965b944e2aSmrg	fprintf(stderr, "sane FP required\n");
2975b944e2aSmrg	return EXIT_FAILURE;
2985b944e2aSmrg    }
2995b944e2aSmrg
3005b944e2aSmrg    data = calloc(nelements, 4);
3015b944e2aSmrg    for (i = 0; i < nelements; i++)
3025b944e2aSmrg    {
3035b944e2aSmrg        *(data + i) = strtod(argv[2 + i], &endptr);
3045b944e2aSmrg	if(endptr == argv[2 + i]){
3055b944e2aSmrg	    fprintf(stderr, "argument %s could not be parsed\n", argv[2 + i]);
3065b944e2aSmrg	    return EXIT_FAILURE;
3075b944e2aSmrg	}
3085b944e2aSmrg    }
3095b944e2aSmrg
3105b944e2aSmrg    XChangeDeviceProperty(dpy, dev, prop, float_atom, 32, PropModeReplace,
3115b944e2aSmrg                          (unsigned char*)data, nelements);
3125b944e2aSmrg
3135b944e2aSmrg    free(data);
3145b944e2aSmrg    XCloseDevice(dpy, dev);
3155b944e2aSmrg    return EXIT_SUCCESS;
3165b944e2aSmrg}
3175b944e2aSmrg
3185b944e2aSmrg
3195b944e2aSmrgint watch_props(Display *dpy, int argc, char** argv, char* n, char *desc)
3205b944e2aSmrg{
3215b944e2aSmrg    XDevice     *dev;
3225b944e2aSmrg    XDeviceInfo *info;
3235b944e2aSmrg    XEvent      ev;
3245b944e2aSmrg    XDevicePropertyNotifyEvent *dpev;
3255b944e2aSmrg    char        *name;
3265b944e2aSmrg    int         type_prop;
3275b944e2aSmrg    XEventClass cls_prop;
3285b944e2aSmrg
3295b944e2aSmrg    if (list_props(dpy, argc, argv, n, desc) != EXIT_SUCCESS)
3305b944e2aSmrg        return EXIT_FAILURE;
3315b944e2aSmrg
3325b944e2aSmrg    info = find_device_info(dpy, argv[0], False);
3335b944e2aSmrg    if (!info)
3345b944e2aSmrg    {
3355b944e2aSmrg        fprintf(stderr, "unable to find device %s\n", argv[0]);
3365b944e2aSmrg        return EXIT_FAILURE;
3375b944e2aSmrg    }
3385b944e2aSmrg
3395b944e2aSmrg    dev = XOpenDevice(dpy, info->id);
3405b944e2aSmrg    if (!dev)
3415b944e2aSmrg    {
3425b944e2aSmrg        fprintf(stderr, "unable to open device '%s'\n", info->name);
3435b944e2aSmrg        return EXIT_FAILURE;
3445b944e2aSmrg    }
3455b944e2aSmrg
3465b944e2aSmrg    DevicePropertyNotify(dev, type_prop, cls_prop);
3475b944e2aSmrg    XSelectExtensionEvent(dpy, DefaultRootWindow(dpy), &cls_prop, 1);
3485b944e2aSmrg
3495b944e2aSmrg    while(1)
3505b944e2aSmrg    {
3515b944e2aSmrg        XNextEvent(dpy, &ev);
3525b944e2aSmrg
3535b944e2aSmrg        dpev = (XDevicePropertyNotifyEvent*)&ev;
3545b944e2aSmrg        if (dpev->type != type_prop)
3555b944e2aSmrg            continue;
3565b944e2aSmrg
3575b944e2aSmrg        name = XGetAtomName(dpy, dpev->atom);
3585b944e2aSmrg        printf("Property '%s' changed.\n", name);
3595b944e2aSmrg        print_property(dpy, dev, dpev->atom);
3605b944e2aSmrg    }
3615b944e2aSmrg
3625b944e2aSmrg    XCloseDevice(dpy, dev);
3635b944e2aSmrg}
3645b944e2aSmrg
3655b944e2aSmrgint delete_prop(Display *dpy, int argc, char** argv, char* n, char *desc)
3665b944e2aSmrg{
3675b944e2aSmrg    XDevice     *dev;
3685b944e2aSmrg    XDeviceInfo *info;
3695b944e2aSmrg    char        *name;
3705b944e2aSmrg    int         i;
3715b944e2aSmrg    Bool        is_atom = True;
3725b944e2aSmrg    Atom        prop;
3735b944e2aSmrg
3745b944e2aSmrg    info = find_device_info(dpy, argv[0], False);
3755b944e2aSmrg    if (!info)
3765b944e2aSmrg    {
3775b944e2aSmrg        fprintf(stderr, "unable to find device %s\n", argv[0]);
3785b944e2aSmrg        return EXIT_FAILURE;
3795b944e2aSmrg    }
3805b944e2aSmrg
3815b944e2aSmrg    dev = XOpenDevice(dpy, info->id);
3825b944e2aSmrg    if (!dev)
3835b944e2aSmrg    {
3845b944e2aSmrg        fprintf(stderr, "unable to open device '%s'\n", info->name);
3855b944e2aSmrg        return EXIT_FAILURE;
3865b944e2aSmrg    }
3875b944e2aSmrg
3885b944e2aSmrg    name = argv[1];
3895b944e2aSmrg
3905b944e2aSmrg    for(i = 0; i < strlen(name); i++) {
3915b944e2aSmrg	if (!isdigit(name[i])) {
3925b944e2aSmrg            is_atom = False;
3935b944e2aSmrg	    break;
3945b944e2aSmrg	}
3955b944e2aSmrg    }
3965b944e2aSmrg
3975b944e2aSmrg    if (!is_atom)
3985b944e2aSmrg        prop = XInternAtom(dpy, name, False);
3995b944e2aSmrg    else
4005b944e2aSmrg        prop = atoi(name);
4015b944e2aSmrg
4025b944e2aSmrg    XDeleteDeviceProperty(dpy, dev, prop);
4035b944e2aSmrg
4045b944e2aSmrg    XCloseDevice(dpy, dev);
4055b944e2aSmrg    return EXIT_SUCCESS;
4065b944e2aSmrg}
4075b944e2aSmrg
4085b944e2aSmrgint
4095b944e2aSmrgset_atom_prop(Display *dpy, int argc, char** argv, char* n, char *desc)
4105b944e2aSmrg{
4115b944e2aSmrg    XDeviceInfo *info;
4125b944e2aSmrg    XDevice     *dev;
4135b944e2aSmrg    Atom         prop;
4145b944e2aSmrg    char        *name;
4155b944e2aSmrg    int          i, j;
4165b944e2aSmrg    Bool         is_atom = True;
4175b944e2aSmrg    Atom        *data;
4185b944e2aSmrg    int          nelements =  0;
4195b944e2aSmrg
4205b944e2aSmrg    if (argc < 3)
4215b944e2aSmrg    {
4225b944e2aSmrg        fprintf(stderr, "Usage: xinput %s %s\n", n, desc);
4235b944e2aSmrg        return EXIT_FAILURE;
4245b944e2aSmrg    }
4255b944e2aSmrg
4265b944e2aSmrg    info = find_device_info(dpy, argv[0], False);
4275b944e2aSmrg    if (!info)
4285b944e2aSmrg    {
4295b944e2aSmrg        fprintf(stderr, "unable to find device %s\n", argv[0]);
4305b944e2aSmrg        return EXIT_FAILURE;
4315b944e2aSmrg    }
4325b944e2aSmrg
4335b944e2aSmrg    dev = XOpenDevice(dpy, info->id);
4345b944e2aSmrg    if (!dev)
4355b944e2aSmrg    {
4365b944e2aSmrg        fprintf(stderr, "unable to open device %s\n", argv[0]);
4375b944e2aSmrg        return EXIT_FAILURE;
4385b944e2aSmrg    }
4395b944e2aSmrg
4405b944e2aSmrg    name = argv[1];
4415b944e2aSmrg
4425b944e2aSmrg    for(i = 0; i < strlen(name); i++) {
4435b944e2aSmrg	if (!isdigit(name[i])) {
4445b944e2aSmrg            is_atom = False;
4455b944e2aSmrg	    break;
4465b944e2aSmrg	}
4475b944e2aSmrg    }
4485b944e2aSmrg
4495b944e2aSmrg    if (!is_atom)
4505b944e2aSmrg        prop = XInternAtom(dpy, name, False);
4515b944e2aSmrg    else
4525b944e2aSmrg        prop = atoi(name);
4535b944e2aSmrg
4545b944e2aSmrg    nelements = argc - 2;
4555b944e2aSmrg    data = calloc(nelements, sizeof(Atom));
4565b944e2aSmrg    for (i = 0; i < nelements; i++)
4575b944e2aSmrg    {
4585b944e2aSmrg        is_atom = True;
4595b944e2aSmrg        name = argv[2 + i];
4605b944e2aSmrg        for(j = 0; j < strlen(name); j++) {
4615b944e2aSmrg            if (!isdigit(name[j])) {
4625b944e2aSmrg                is_atom = False;
4635b944e2aSmrg                break;
4645b944e2aSmrg            }
4655b944e2aSmrg        }
4665b944e2aSmrg
4675b944e2aSmrg        if (!is_atom)
4685b944e2aSmrg            data[i] = XInternAtom(dpy, name, False);
4695b944e2aSmrg        else
4705b944e2aSmrg        {
4715b944e2aSmrg            data[i] = atoi(name);
4725b944e2aSmrg            XFree(XGetAtomName(dpy, data[i]));
4735b944e2aSmrg        }
4745b944e2aSmrg    }
4755b944e2aSmrg
4765b944e2aSmrg    XChangeDeviceProperty(dpy, dev, prop, XA_ATOM, 32, PropModeReplace,
4775b944e2aSmrg                          (unsigned char*)data, nelements);
4785b944e2aSmrg
4795b944e2aSmrg    free(data);
4805b944e2aSmrg    XCloseDevice(dpy, dev);
4815b944e2aSmrg    return EXIT_SUCCESS;
4825b944e2aSmrg}
4835b944e2aSmrg
4845b944e2aSmrg
485