test_xi2.c revision 20f5670e
153719b08Smrg/*
253719b08Smrg * Copyright © 2009 Red Hat, Inc.
353719b08Smrg *
453719b08Smrg * Permission is hereby granted, free of charge, to any person obtaining a
553719b08Smrg * copy of this software and associated documentation files (the "Software"),
653719b08Smrg * to deal in the Software without restriction, including without limitation
753719b08Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
853719b08Smrg * and/or sell copies of the Software, and to permit persons to whom the
953719b08Smrg * Software is furnished to do so, subject to the following conditions:
1053719b08Smrg *
1153719b08Smrg * The above copyright notice and this permission notice (including the next
1253719b08Smrg * paragraph) shall be included in all copies or substantial portions of the
1353719b08Smrg * Software.
1453719b08Smrg *
1553719b08Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1653719b08Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1753719b08Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1853719b08Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1953719b08Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2053719b08Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2153719b08Smrg * DEALINGS IN THE SOFTWARE.
2253719b08Smrg *
2353719b08Smrg */
2453719b08Smrg
2553719b08Smrg
2653719b08Smrg#include "xinput.h"
2753719b08Smrg#include <string.h>
2853719b08Smrg
2953719b08Smrgextern void print_classes_xi2(Display*, XIAnyClassInfo **classes,
3053719b08Smrg                              int num_classes);
3153719b08Smrg
3253719b08Smrgstatic Window create_win(Display *dpy)
3353719b08Smrg{
3453719b08Smrg    Window win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, 200,
3553719b08Smrg            200, 0, 0, WhitePixel(dpy, 0));
3653719b08Smrg    Window subwindow = XCreateSimpleWindow(dpy, win, 50, 50, 50, 50, 0, 0,
3753719b08Smrg            BlackPixel(dpy, 0));
3853719b08Smrg
3953719b08Smrg    XMapWindow(dpy, subwindow);
4053719b08Smrg    XSelectInput(dpy, win, ExposureMask);
4153719b08Smrg    return win;
4253719b08Smrg}
4353719b08Smrg
4453719b08Smrgstatic void print_deviceevent(XIDeviceEvent* event)
4553719b08Smrg{
4653719b08Smrg    double *val;
4753719b08Smrg    int i;
4853719b08Smrg
4953719b08Smrg    printf("    device: %d (%d)\n", event->deviceid, event->sourceid);
5020f5670eSmrg    printf("    time: %ld\n", event->time);
5153719b08Smrg    printf("    detail: %d\n", event->detail);
520309d3b3Smrg    switch(event->evtype) {
530309d3b3Smrg        case XI_KeyPress:
540309d3b3Smrg        case XI_KeyRelease:
550309d3b3Smrg            printf("    flags: %s\n", (event->flags & XIKeyRepeat) ?  "repeat" : "");
560309d3b3Smrg            break;
570309d3b3Smrg#if HAVE_XI21
580309d3b3Smrg        case XI_ButtonPress:
590309d3b3Smrg        case XI_ButtonRelease:
600309d3b3Smrg        case XI_Motion:
610309d3b3Smrg            printf("    flags: %s\n", (event->flags & XIPointerEmulated) ?  "emulated" : "");
620309d3b3Smrg            break;
63e73734d1Smrg#endif
64e73734d1Smrg#if HAVE_XI22
65e73734d1Smrg        case XI_TouchBegin:
66e73734d1Smrg        case XI_TouchUpdate:
67e73734d1Smrg        case XI_TouchEnd:
68e73734d1Smrg            printf("    flags:%s%s\n",
69e73734d1Smrg                   (event->flags & XITouchPendingEnd) ?  " pending_end" : "",
70e73734d1Smrg                   (event->flags & XITouchEmulatingPointer) ?  " emulating" : "");
71e73734d1Smrg            break;
720309d3b3Smrg#endif
730309d3b3Smrg    }
7453719b08Smrg
7553719b08Smrg    printf("    root: %.2f/%.2f\n", event->root_x, event->root_y);
7653719b08Smrg    printf("    event: %.2f/%.2f\n", event->event_x, event->event_y);
7753719b08Smrg
7853719b08Smrg    printf("    buttons:");
7953719b08Smrg    for (i = 0; i < event->buttons.mask_len * 8; i++)
8053719b08Smrg        if (XIMaskIsSet(event->buttons.mask, i))
8153719b08Smrg            printf(" %d", i);
8253719b08Smrg    printf("\n");
8353719b08Smrg
8453719b08Smrg    printf("    modifiers: locked %#x latched %#x base %#x effective: %#x\n",
8553719b08Smrg            event->mods.locked, event->mods.latched,
8653719b08Smrg            event->mods.base, event->mods.effective);
8753719b08Smrg    printf("    group: locked %#x latched %#x base %#x effective: %#x\n",
8853719b08Smrg            event->group.locked, event->group.latched,
8953719b08Smrg            event->group.base, event->group.effective);
9054e0bb33Smrg    printf("    valuators:\n");
9153719b08Smrg
9253719b08Smrg    val = event->valuators.values;
9353719b08Smrg    for (i = 0; i < event->valuators.mask_len * 8; i++)
9453719b08Smrg        if (XIMaskIsSet(event->valuators.mask, i))
9554e0bb33Smrg            printf("        %i: %.2f\n", i, *val++);
9653719b08Smrg
970309d3b3Smrg    printf("    windows: root 0x%lx event 0x%lx child 0x%lx\n",
9853719b08Smrg            event->root, event->event, event->child);
9953719b08Smrg}
10053719b08Smrg
10153719b08Smrgstatic void print_devicechangedevent(Display *dpy, XIDeviceChangedEvent *event)
10253719b08Smrg{
10353719b08Smrg    printf("    device: %d (%d)\n", event->deviceid, event->sourceid);
10420f5670eSmrg    printf("    time: %ld\n", event->time);
10553719b08Smrg    printf("    reason: %s\n", (event->reason == XISlaveSwitch) ? "SlaveSwitch" :
10653719b08Smrg                                "DeviceChanged");
10753719b08Smrg    print_classes_xi2(dpy, event->classes, event->num_classes);
10853719b08Smrg}
10953719b08Smrg
11053719b08Smrgstatic void print_hierarchychangedevent(XIHierarchyEvent *event)
11153719b08Smrg{
11253719b08Smrg    int i;
11320f5670eSmrg    printf("    time: %ld\n", event->time);
11453719b08Smrg    printf("    Changes happened: %s %s %s %s %s %s %s %s\n",
11553719b08Smrg            (event->flags & XIMasterAdded) ? "[new master]" : "",
11653719b08Smrg            (event->flags & XIMasterRemoved) ? "[master removed]" : "",
11753719b08Smrg            (event->flags & XISlaveAdded) ? "[new slave]" : "",
11853719b08Smrg            (event->flags & XISlaveRemoved) ? "[slave removed]" : "",
11953719b08Smrg            (event->flags & XISlaveAttached) ? "[slave attached]" : "",
12053719b08Smrg            (event->flags & XISlaveDetached) ? "[slave detached]" : "",
12153719b08Smrg            (event->flags & XIDeviceEnabled) ? "[device enabled]" : "",
12253719b08Smrg            (event->flags & XIDeviceDisabled) ? "[device disabled]" : "");
12353719b08Smrg
12453719b08Smrg    for (i = 0; i < event->num_info; i++)
12553719b08Smrg    {
1260309d3b3Smrg        char *use = "<undefined>";
12753719b08Smrg        switch(event->info[i].use)
12853719b08Smrg        {
12953719b08Smrg            case XIMasterPointer: use = "master pointer"; break;
13053719b08Smrg            case XIMasterKeyboard: use = "master keyboard"; break;
13153719b08Smrg            case XISlavePointer: use = "slave pointer"; break;
13253719b08Smrg            case XISlaveKeyboard: use = "slave keyboard"; break;
13353719b08Smrg            case XIFloatingSlave: use = "floating slave"; break;
13453719b08Smrg                break;
13553719b08Smrg        }
13653719b08Smrg
13753719b08Smrg        printf("    device %d [%s (%d)] is %s\n",
13853719b08Smrg                event->info[i].deviceid,
13953719b08Smrg                use,
14053719b08Smrg                event->info[i].attachment,
14153719b08Smrg                (event->info[i].enabled) ? "enabled" : "disabled");
14253719b08Smrg        if (event->info[i].flags)
14353719b08Smrg        {
14453719b08Smrg            printf("    changes: %s %s %s %s %s %s %s %s\n",
14553719b08Smrg                    (event->info[i].flags & XIMasterAdded) ? "[new master]" : "",
14653719b08Smrg                    (event->info[i].flags & XIMasterRemoved) ? "[master removed]" : "",
14753719b08Smrg                    (event->info[i].flags & XISlaveAdded) ? "[new slave]" : "",
14853719b08Smrg                    (event->info[i].flags & XISlaveRemoved) ? "[slave removed]" : "",
14953719b08Smrg                    (event->info[i].flags & XISlaveAttached) ? "[slave attached]" : "",
15053719b08Smrg                    (event->info[i].flags & XISlaveDetached) ? "[slave detached]" : "",
15153719b08Smrg                    (event->info[i].flags & XIDeviceEnabled) ? "[device enabled]" : "",
15253719b08Smrg                    (event->info[i].flags & XIDeviceDisabled) ? "[device disabled]" : "");
15353719b08Smrg        }
15453719b08Smrg    }
15553719b08Smrg}
15653719b08Smrg
15753719b08Smrgstatic void print_rawevent(XIRawEvent *event)
15853719b08Smrg{
15953719b08Smrg    int i;
16053719b08Smrg    double *val, *raw_val;
16153719b08Smrg
1620309d3b3Smrg    printf("    device: %d (%d)\n", event->deviceid, event->sourceid);
16320f5670eSmrg    printf("    time:   %ld\n", event->time);
16453719b08Smrg    printf("    detail: %d\n", event->detail);
1650309d3b3Smrg#if HAVE_XI21
1660309d3b3Smrg    switch(event->evtype) {
1670309d3b3Smrg        case XI_RawButtonPress:
1680309d3b3Smrg        case XI_RawButtonRelease:
1690309d3b3Smrg        case XI_RawMotion:
1700309d3b3Smrg            printf("    flags: %s\n", (event->flags & XIPointerEmulated) ?  "emulated" : "");
1710309d3b3Smrg            break;
1720309d3b3Smrg    }
1730309d3b3Smrg#endif
17453719b08Smrg
175e73734d1Smrg    printf("    valuators:\n");
17653719b08Smrg    val = event->valuators.values;
17753719b08Smrg    raw_val = event->raw_values;
17853719b08Smrg    for (i = 0; i < event->valuators.mask_len * 8; i++)
17953719b08Smrg        if (XIMaskIsSet(event->valuators.mask, i))
18053719b08Smrg            printf("         %2d: %.2f (%.2f)\n", i, *val++, *raw_val++);
18153719b08Smrg    printf("\n");
18253719b08Smrg}
18353719b08Smrg
18453719b08Smrgstatic void print_enterleave(XILeaveEvent* event)
18553719b08Smrg{
1860309d3b3Smrg    char *mode = "<undefined>",
1870309d3b3Smrg         *detail = "<undefined>";
18853719b08Smrg    int i;
18953719b08Smrg
190cea37944Smrg    printf("    device: %d (%d)\n", event->deviceid, event->sourceid);
19120f5670eSmrg    printf("    time:   %ld\n", event->time);
19253719b08Smrg    printf("    windows: root 0x%lx event 0x%lx child 0x%ld\n",
19353719b08Smrg            event->root, event->event, event->child);
19453719b08Smrg    switch(event->mode)
19553719b08Smrg    {
19653719b08Smrg        case XINotifyNormal:       mode = "NotifyNormal"; break;
19753719b08Smrg        case XINotifyGrab:         mode = "NotifyGrab"; break;
19853719b08Smrg        case XINotifyUngrab:       mode = "NotifyUngrab"; break;
19953719b08Smrg        case XINotifyWhileGrabbed: mode = "NotifyWhileGrabbed"; break;
20053719b08Smrg        case XINotifyPassiveGrab:  mode = "NotifyPassiveGrab"; break;
20153719b08Smrg        case XINotifyPassiveUngrab:mode = "NotifyPassiveUngrab"; break;
20253719b08Smrg    }
20353719b08Smrg    switch (event->detail)
20453719b08Smrg    {
20553719b08Smrg        case XINotifyAncestor: detail = "NotifyAncestor"; break;
20653719b08Smrg        case XINotifyVirtual: detail = "NotifyVirtual"; break;
20753719b08Smrg        case XINotifyInferior: detail = "NotifyInferior"; break;
20853719b08Smrg        case XINotifyNonlinear: detail = "NotifyNonlinear"; break;
20953719b08Smrg        case XINotifyNonlinearVirtual: detail = "NotifyNonlinearVirtual"; break;
21053719b08Smrg        case XINotifyPointer: detail = "NotifyPointer"; break;
21153719b08Smrg        case XINotifyPointerRoot: detail = "NotifyPointerRoot"; break;
21253719b08Smrg        case XINotifyDetailNone: detail = "NotifyDetailNone"; break;
21353719b08Smrg    }
21453719b08Smrg    printf("    mode: %s (detail %s)\n", mode, detail);
21553719b08Smrg    printf("    flags: %s %s\n", event->focus ? "[focus]" : "",
21653719b08Smrg                                 event->same_screen ? "[same screen]" : "");
21753719b08Smrg    printf("    buttons:");
21853719b08Smrg    for (i = 0; i < event->buttons.mask_len * 8; i++)
21953719b08Smrg        if (XIMaskIsSet(event->buttons.mask, i))
22053719b08Smrg            printf(" %d", i);
22153719b08Smrg    printf("\n");
22253719b08Smrg
22353719b08Smrg    printf("    modifiers: locked %#x latched %#x base %#x effective: %#x\n",
22453719b08Smrg            event->mods.locked, event->mods.latched,
22553719b08Smrg            event->mods.base, event->mods.effective);
22653719b08Smrg    printf("    group: locked %#x latched %#x base %#x effective: %#x\n",
22753719b08Smrg            event->group.locked, event->group.latched,
22853719b08Smrg            event->group.base, event->group.effective);
22953719b08Smrg
23053719b08Smrg    printf("    root x/y:  %.2f / %.2f\n", event->root_x, event->root_y);
23153719b08Smrg    printf("    event x/y: %.2f / %.2f\n", event->event_x, event->event_y);
23253719b08Smrg
23353719b08Smrg}
23453719b08Smrg
23553719b08Smrgstatic void print_propertyevent(Display *display, XIPropertyEvent* event)
23653719b08Smrg{
23753719b08Smrg    char *changed;
23853719b08Smrg    char *name;
23953719b08Smrg
24053719b08Smrg    if (event->what == XIPropertyDeleted)
24153719b08Smrg        changed = "deleted";
24253719b08Smrg    else if (event->what == XIPropertyCreated)
24353719b08Smrg        changed = "created";
24453719b08Smrg    else
24553719b08Smrg        changed = "modified";
24653719b08Smrg    name = XGetAtomName(display, event->property);
24720f5670eSmrg    printf("     time:   %ld\n", event->time);
24853719b08Smrg    printf("     property: %ld '%s'\n", event->property, name);
24953719b08Smrg    printf("     changed: %s\n", changed);
25053719b08Smrg
25153719b08Smrg    XFree(name);
25253719b08Smrg}
25353719b08Smrgvoid
25453719b08Smrgtest_sync_grab(Display *display, Window win)
25553719b08Smrg{
25653719b08Smrg    int loop = 3;
25753719b08Smrg    int rc;
25853719b08Smrg    XIEventMask mask;
25953719b08Smrg
26053719b08Smrg    /* Select for motion events */
26153719b08Smrg    mask.deviceid = XIAllDevices;
26253719b08Smrg    mask.mask_len = 2;
26353719b08Smrg    mask.mask = calloc(2, sizeof(char));
26453719b08Smrg    XISetMask(mask.mask, XI_ButtonPress);
26553719b08Smrg
26653719b08Smrg    if ((rc = XIGrabDevice(display, 2,  win, CurrentTime, None, GrabModeSync,
26753719b08Smrg                           GrabModeAsync, False, &mask)) != GrabSuccess)
26853719b08Smrg    {
26953719b08Smrg        fprintf(stderr, "Grab failed with %d\n", rc);
27053719b08Smrg        return;
27153719b08Smrg    }
27253719b08Smrg    free(mask.mask);
27353719b08Smrg
27453719b08Smrg    XSync(display, True);
27553719b08Smrg    XIAllowEvents(display, 2, SyncPointer, CurrentTime);
27653719b08Smrg    XFlush(display);
27753719b08Smrg
27853719b08Smrg    printf("Holding sync grab for %d button presses.\n", loop);
27953719b08Smrg
28053719b08Smrg    while(loop--)
28153719b08Smrg    {
28253719b08Smrg        XIEvent ev;
28353719b08Smrg
28453719b08Smrg        XNextEvent(display, (XEvent*)&ev);
28553719b08Smrg        if (ev.type == GenericEvent && ev.extension == xi_opcode )
28653719b08Smrg        {
28753719b08Smrg            XIDeviceEvent *event = (XIDeviceEvent*)&ev;
28853719b08Smrg            print_deviceevent(event);
28953719b08Smrg            XIAllowEvents(display, 2, SyncPointer, CurrentTime);
29053719b08Smrg        }
29153719b08Smrg    }
29253719b08Smrg
29353719b08Smrg    XIUngrabDevice(display, 2, CurrentTime);
29453719b08Smrg    printf("Done\n");
29553719b08Smrg}
29653719b08Smrg
29753719b08Smrgstatic const char* type_to_name(int evtype)
29853719b08Smrg{
29953719b08Smrg    const char *name;
30053719b08Smrg
30153719b08Smrg    switch(evtype) {
30253719b08Smrg        case XI_DeviceChanged:    name = "DeviceChanged";       break;
30353719b08Smrg        case XI_KeyPress:         name = "KeyPress";            break;
30453719b08Smrg        case XI_KeyRelease:       name = "KeyRelease";          break;
30553719b08Smrg        case XI_ButtonPress:      name = "ButtonPress";         break;
30653719b08Smrg        case XI_ButtonRelease:    name = "ButtonRelease";       break;
30753719b08Smrg        case XI_Motion:           name = "Motion";              break;
30853719b08Smrg        case XI_Enter:            name = "Enter";               break;
30953719b08Smrg        case XI_Leave:            name = "Leave";               break;
31053719b08Smrg        case XI_FocusIn:          name = "FocusIn";             break;
31153719b08Smrg        case XI_FocusOut:         name = "FocusOut";            break;
31253719b08Smrg        case XI_HierarchyChanged: name = "HierarchyChanged";    break;
31353719b08Smrg        case XI_PropertyEvent:    name = "PropertyEvent";       break;
31453719b08Smrg        case XI_RawKeyPress:      name = "RawKeyPress";         break;
31553719b08Smrg        case XI_RawKeyRelease:    name = "RawKeyRelease";       break;
31653719b08Smrg        case XI_RawButtonPress:   name = "RawButtonPress";      break;
31753719b08Smrg        case XI_RawButtonRelease: name = "RawButtonRelease";    break;
31853719b08Smrg        case XI_RawMotion:        name = "RawMotion";           break;
3190309d3b3Smrg        case XI_TouchBegin:       name = "TouchBegin";          break;
3200309d3b3Smrg        case XI_TouchUpdate:      name = "TouchUpdate";         break;
3210309d3b3Smrg        case XI_TouchEnd:         name = "TouchEnd";            break;
3220309d3b3Smrg        case XI_RawTouchBegin:    name = "RawTouchBegin";       break;
3230309d3b3Smrg        case XI_RawTouchUpdate:   name = "RawTouchUpdate";      break;
3240309d3b3Smrg        case XI_RawTouchEnd:      name = "RawTouchEnd";         break;
32553719b08Smrg        default:
32653719b08Smrg                                  name = "unknown event type"; break;
32753719b08Smrg    }
32853719b08Smrg    return name;
32953719b08Smrg}
33053719b08Smrg
33153719b08Smrg
33253719b08Smrgint
33353719b08Smrgtest_xi2(Display	*display,
33453719b08Smrg         int	argc,
33553719b08Smrg         char	*argv[],
33653719b08Smrg         char	*name,
33753719b08Smrg         char	*desc)
33853719b08Smrg{
33933734831Smrg    XIEventMask mask[2];
34033734831Smrg    XIEventMask *m;
34153719b08Smrg    Window win;
3420309d3b3Smrg    int deviceid = -1;
34333734831Smrg    int use_root = 0;
3440309d3b3Smrg    int rc;
3450309d3b3Smrg
34633734831Smrg    setvbuf(stdout, NULL, _IOLBF, 0);
34733734831Smrg
34833734831Smrg    if (argc >= 1 && strcmp(argv[0], "--root") == 0) {
34933734831Smrg        use_root = 1;
35033734831Smrg
35133734831Smrg        argc--;
35233734831Smrg        argv++;
35333734831Smrg    }
35433734831Smrg
3550309d3b3Smrg    rc = list(display, argc, argv, name, desc);
3560309d3b3Smrg    if (rc != EXIT_SUCCESS)
3570309d3b3Smrg        return rc;
35853719b08Smrg
35933734831Smrg    if (use_root)
36033734831Smrg        win = DefaultRootWindow(display);
36133734831Smrg    else
36233734831Smrg        win = create_win(display);
36333734831Smrg
3640309d3b3Smrg    if (argc >= 1) {
3650309d3b3Smrg        XIDeviceInfo *info;
3660309d3b3Smrg        info = xi2_find_device_info(display, argv[0]);
367a570218aSmrg        /* info is alway valid, the list() call exits if the device
368a570218aSmrg           cannot be found, but let's shut up coverity */
369a570218aSmrg        if (!info)
370a570218aSmrg            return EXIT_FAILURE;
3710309d3b3Smrg        deviceid = info->deviceid;
3720309d3b3Smrg    }
37353719b08Smrg
37453719b08Smrg    /* Select for motion events */
37533734831Smrg    m = &mask[0];
37633734831Smrg    m->deviceid = (deviceid == -1) ? XIAllDevices : deviceid;
37733734831Smrg    m->mask_len = XIMaskLen(XI_LASTEVENT);
37833734831Smrg    m->mask = calloc(m->mask_len, sizeof(char));
37933734831Smrg    XISetMask(m->mask, XI_ButtonPress);
38033734831Smrg    XISetMask(m->mask, XI_ButtonRelease);
38133734831Smrg    XISetMask(m->mask, XI_KeyPress);
38233734831Smrg    XISetMask(m->mask, XI_KeyRelease);
38333734831Smrg    XISetMask(m->mask, XI_Motion);
38433734831Smrg    XISetMask(m->mask, XI_DeviceChanged);
38533734831Smrg    XISetMask(m->mask, XI_Enter);
38633734831Smrg    XISetMask(m->mask, XI_Leave);
38733734831Smrg    XISetMask(m->mask, XI_FocusIn);
38833734831Smrg    XISetMask(m->mask, XI_FocusOut);
389a570218aSmrg#if HAVE_XI22
39033734831Smrg    XISetMask(m->mask, XI_TouchBegin);
39133734831Smrg    XISetMask(m->mask, XI_TouchUpdate);
39233734831Smrg    XISetMask(m->mask, XI_TouchEnd);
3930309d3b3Smrg#endif
39433734831Smrg    if (m->deviceid == XIAllDevices)
39533734831Smrg        XISetMask(m->mask, XI_HierarchyChanged);
39633734831Smrg    XISetMask(m->mask, XI_PropertyEvent);
39733734831Smrg
39833734831Smrg    m = &mask[1];
39933734831Smrg    m->deviceid = (deviceid == -1) ? XIAllMasterDevices : deviceid;
40033734831Smrg    m->mask_len = XIMaskLen(XI_LASTEVENT);
40133734831Smrg    m->mask = calloc(m->mask_len, sizeof(char));
40233734831Smrg    XISetMask(m->mask, XI_RawKeyPress);
40333734831Smrg    XISetMask(m->mask, XI_RawKeyRelease);
40433734831Smrg    XISetMask(m->mask, XI_RawButtonPress);
40533734831Smrg    XISetMask(m->mask, XI_RawButtonRelease);
40633734831Smrg    XISetMask(m->mask, XI_RawMotion);
407a570218aSmrg#if HAVE_XI22
40833734831Smrg    XISetMask(m->mask, XI_RawTouchBegin);
40933734831Smrg    XISetMask(m->mask, XI_RawTouchUpdate);
41033734831Smrg    XISetMask(m->mask, XI_RawTouchEnd);
4110309d3b3Smrg#endif
41253719b08Smrg
41333734831Smrg    XISelectEvents(display, win, &mask[0], use_root ? 2 : 1);
41433734831Smrg    if (!use_root) {
41533734831Smrg        XISelectEvents(display, DefaultRootWindow(display), &mask[1], 1);
41633734831Smrg        XMapWindow(display, win);
41733734831Smrg    }
41833734831Smrg    XSync(display, False);
41953719b08Smrg
42033734831Smrg    free(mask[0].mask);
42133734831Smrg    free(mask[1].mask);
42233734831Smrg
42333734831Smrg    if (!use_root) {
42453719b08Smrg        XEvent event;
42553719b08Smrg        XMaskEvent(display, ExposureMask, &event);
42653719b08Smrg        XSelectInput(display, win, 0);
42753719b08Smrg    }
42853719b08Smrg
42953719b08Smrg    /*
43053719b08Smrg    test_sync_grab(display, win);
43153719b08Smrg    */
43253719b08Smrg
43353719b08Smrg    while(1)
43453719b08Smrg    {
43553719b08Smrg        XEvent ev;
43653719b08Smrg        XGenericEventCookie *cookie = (XGenericEventCookie*)&ev.xcookie;
43753719b08Smrg        XNextEvent(display, (XEvent*)&ev);
43853719b08Smrg
43953719b08Smrg        if (XGetEventData(display, cookie) &&
44053719b08Smrg            cookie->type == GenericEvent &&
44153719b08Smrg            cookie->extension == xi_opcode)
44253719b08Smrg        {
44353719b08Smrg            printf("EVENT type %d (%s)\n", cookie->evtype, type_to_name(cookie->evtype));
44453719b08Smrg            switch (cookie->evtype)
44553719b08Smrg            {
44653719b08Smrg                case XI_DeviceChanged:
44753719b08Smrg                    print_devicechangedevent(display, cookie->data);
44853719b08Smrg                    break;
44953719b08Smrg                case XI_HierarchyChanged:
45053719b08Smrg                    print_hierarchychangedevent(cookie->data);
45153719b08Smrg                    break;
45253719b08Smrg                case XI_RawKeyPress:
45353719b08Smrg                case XI_RawKeyRelease:
45453719b08Smrg                case XI_RawButtonPress:
45553719b08Smrg                case XI_RawButtonRelease:
45653719b08Smrg                case XI_RawMotion:
4570309d3b3Smrg                case XI_RawTouchBegin:
4580309d3b3Smrg                case XI_RawTouchUpdate:
4590309d3b3Smrg                case XI_RawTouchEnd:
46053719b08Smrg                    print_rawevent(cookie->data);
46153719b08Smrg                    break;
46253719b08Smrg                case XI_Enter:
46353719b08Smrg                case XI_Leave:
46453719b08Smrg                case XI_FocusIn:
46553719b08Smrg                case XI_FocusOut:
46653719b08Smrg                    print_enterleave(cookie->data);
46753719b08Smrg                    break;
46853719b08Smrg                case XI_PropertyEvent:
46953719b08Smrg                    print_propertyevent(display, cookie->data);
47053719b08Smrg                    break;
47153719b08Smrg                default:
47253719b08Smrg                    print_deviceevent(cookie->data);
47353719b08Smrg                    break;
47453719b08Smrg            }
47553719b08Smrg        }
47653719b08Smrg
47753719b08Smrg        XFreeEventData(display, cookie);
47853719b08Smrg    }
47953719b08Smrg
48053719b08Smrg    XDestroyWindow(display, win);
48153719b08Smrg
48253719b08Smrg    return EXIT_SUCCESS;
48353719b08Smrg}
484