X-Git-Url: https://diplodocus.org/git/xorg-xinput/blobdiff_plain/1c72fd55d61371de81f44be5d92982a3012ad24b..refs/heads/master:/src/test_xi2.c?ds=inline diff --git a/src/test_xi2.c b/src/test_xi2.c index b03b762..5f97258 100644 --- a/src/test_xi2.c +++ b/src/test_xi2.c @@ -29,9 +29,6 @@ extern void print_classes_xi2(Display*, XIAnyClassInfo **classes, int num_classes); -#define BitIsOn(ptr, bit) (((unsigned char *) (ptr))[(bit)>>3] & (1 << ((bit) & 7))) -#define SetBit(ptr, bit) (((unsigned char *) (ptr))[(bit)>>3] |= (1 << ((bit) & 7))) - static Window create_win(Display *dpy) { Window win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, 200, @@ -39,10 +36,8 @@ static Window create_win(Display *dpy) Window subwindow = XCreateSimpleWindow(dpy, win, 50, 50, 50, 50, 0, 0, BlackPixel(dpy, 0)); - XSelectInput(dpy, win, ExposureMask); XMapWindow(dpy, subwindow); - XMapWindow(dpy, win); - XFlush(dpy); + XSelectInput(dpy, win, ExposureMask); return win; } @@ -52,38 +47,61 @@ static void print_deviceevent(XIDeviceEvent* event) int i; printf(" device: %d (%d)\n", event->deviceid, event->sourceid); + printf(" time: %ld\n", event->time); printf(" detail: %d\n", event->detail); + switch(event->evtype) { + case XI_KeyPress: + case XI_KeyRelease: + printf(" flags: %s\n", (event->flags & XIKeyRepeat) ? "repeat" : ""); + break; +#if HAVE_XI21 + case XI_ButtonPress: + case XI_ButtonRelease: + case XI_Motion: + printf(" flags: %s\n", (event->flags & XIPointerEmulated) ? "emulated" : ""); + break; +#endif +#if HAVE_XI22 + case XI_TouchBegin: + case XI_TouchUpdate: + case XI_TouchEnd: + printf(" flags:%s%s\n", + (event->flags & XITouchPendingEnd) ? " pending_end" : "", + (event->flags & XITouchEmulatingPointer) ? " emulating" : ""); + break; +#endif + } printf(" root: %.2f/%.2f\n", event->root_x, event->root_y); - printf(" event: %.2f/%.2f\n", event->event_x, event->event_x); + printf(" event: %.2f/%.2f\n", event->event_x, event->event_y); printf(" buttons:"); - for (i = 0; i < event->buttons->mask_len * 8; i++) - if (BitIsOn(event->buttons->mask, i)) + for (i = 0; i < event->buttons.mask_len * 8; i++) + if (XIMaskIsSet(event->buttons.mask, i)) printf(" %d", i); printf("\n"); - printf(" modifiers: locked 0x%x latched 0x%x base 0x%x\n", - event->mods->locked, event->mods->latched, - event->mods->base); - printf(" group: locked 0x%x latched 0x%x base 0x%x\n", - event->group->locked, event->group->latched, - event->group->base); - printf(" valuators:"); - - val = event->valuators->values; - for (i = 0; i < event->valuators->mask_len * 8; i++) - if (BitIsOn(event->valuators->mask, i)) - printf(" %.2f", *val++); - printf("\n"); + printf(" modifiers: locked %#x latched %#x base %#x effective: %#x\n", + event->mods.locked, event->mods.latched, + event->mods.base, event->mods.effective); + printf(" group: locked %#x latched %#x base %#x effective: %#x\n", + event->group.locked, event->group.latched, + event->group.base, event->group.effective); + printf(" valuators:\n"); - printf(" windows: root 0x%lx event 0x%lx child 0x%ld\n", + val = event->valuators.values; + for (i = 0; i < event->valuators.mask_len * 8; i++) + if (XIMaskIsSet(event->valuators.mask, i)) + printf(" %i: %.2f\n", i, *val++); + + printf(" windows: root 0x%lx event 0x%lx child 0x%lx\n", event->root, event->event, event->child); } static void print_devicechangedevent(Display *dpy, XIDeviceChangedEvent *event) { printf(" device: %d (%d)\n", event->deviceid, event->sourceid); + printf(" time: %ld\n", event->time); printf(" reason: %s\n", (event->reason == XISlaveSwitch) ? "SlaveSwitch" : "DeviceChanged"); print_classes_xi2(dpy, event->classes, event->num_classes); @@ -92,6 +110,7 @@ static void print_devicechangedevent(Display *dpy, XIDeviceChangedEvent *event) static void print_hierarchychangedevent(XIHierarchyEvent *event) { int i; + printf(" time: %ld\n", event->time); printf(" Changes happened: %s %s %s %s %s %s %s %s\n", (event->flags & XIMasterAdded) ? "[new master]" : "", (event->flags & XIMasterRemoved) ? "[master removed]" : "", @@ -102,14 +121,14 @@ static void print_hierarchychangedevent(XIHierarchyEvent *event) (event->flags & XIDeviceEnabled) ? "[device enabled]" : "", (event->flags & XIDeviceDisabled) ? "[device disabled]" : ""); - for (i = 0; i < event->num_devices; i++) + for (i = 0; i < event->num_info; i++) { - char *use; + char *use = ""; switch(event->info[i].use) { - case XIMasterPointer: use = "master pointer"; + case XIMasterPointer: use = "master pointer"; break; case XIMasterKeyboard: use = "master keyboard"; break; - case XISlavePointer: use = "slave pointer"; + case XISlavePointer: use = "slave pointer"; break; case XISlaveKeyboard: use = "slave keyboard"; break; case XIFloatingSlave: use = "floating slave"; break; break; @@ -140,58 +159,73 @@ static void print_rawevent(XIRawEvent *event) int i; double *val, *raw_val; - printf(" device: %d\n", event->deviceid); + printf(" device: %d (%d)\n", event->deviceid, event->sourceid); + printf(" time: %ld\n", event->time); printf(" detail: %d\n", event->detail); - printf(" valuators:\n"); +#if HAVE_XI21 + switch(event->evtype) { + case XI_RawButtonPress: + case XI_RawButtonRelease: + case XI_RawMotion: + printf(" flags: %s\n", (event->flags & XIPointerEmulated) ? "emulated" : ""); + break; + } +#endif - val = event->valuators->values; + printf(" valuators:\n"); + val = event->valuators.values; raw_val = event->raw_values; - for (i = 0; i < event->valuators->mask_len * 8; i++) - if (BitIsOn(event->valuators->mask, i)) + for (i = 0; i < event->valuators.mask_len * 8; i++) + if (XIMaskIsSet(event->valuators.mask, i)) printf(" %2d: %.2f (%.2f)\n", i, *val++, *raw_val++); printf("\n"); } static void print_enterleave(XILeaveEvent* event) { - char *mode, *detail; + char *mode = "", + *detail = ""; int i; + printf(" device: %d (%d)\n", event->deviceid, event->sourceid); + printf(" time: %ld\n", event->time); printf(" windows: root 0x%lx event 0x%lx child 0x%ld\n", event->root, event->event, event->child); switch(event->mode) { - case NotifyNormal: mode = "NotifyNormal"; break; - case NotifyGrab: mode = "NotifyGrab"; break; - case NotifyUngrab: mode = "NotifyUngrab"; break; - case NotifyWhileGrabbed: mode = "NotifyWhileGrabbed"; break; + case XINotifyNormal: mode = "NotifyNormal"; break; + case XINotifyGrab: mode = "NotifyGrab"; break; + case XINotifyUngrab: mode = "NotifyUngrab"; break; + case XINotifyWhileGrabbed: mode = "NotifyWhileGrabbed"; break; + case XINotifyPassiveGrab: mode = "NotifyPassiveGrab"; break; + case XINotifyPassiveUngrab:mode = "NotifyPassiveUngrab"; break; } switch (event->detail) { - case NotifyAncestor: detail = "NotifyAncestor"; break; - case NotifyVirtual: detail = "NotifyVirtual"; break; - case NotifyInferior: detail = "NotifyInferior"; break; - case NotifyNonlinear: detail = "NotifyNonlinear"; break; - case NotifyNonlinearVirtual: detail = "NotifyNonlinearVirtual"; break; - case NotifyPointer: detail = "NotifyPointer"; break; - case NotifyPointerRoot: detail = "NotifyPointerRoot"; break; - case NotifyDetailNone: detail = "NotifyDetailNone"; break; + case XINotifyAncestor: detail = "NotifyAncestor"; break; + case XINotifyVirtual: detail = "NotifyVirtual"; break; + case XINotifyInferior: detail = "NotifyInferior"; break; + case XINotifyNonlinear: detail = "NotifyNonlinear"; break; + case XINotifyNonlinearVirtual: detail = "NotifyNonlinearVirtual"; break; + case XINotifyPointer: detail = "NotifyPointer"; break; + case XINotifyPointerRoot: detail = "NotifyPointerRoot"; break; + case XINotifyDetailNone: detail = "NotifyDetailNone"; break; } printf(" mode: %s (detail %s)\n", mode, detail); printf(" flags: %s %s\n", event->focus ? "[focus]" : "", event->same_screen ? "[same screen]" : ""); printf(" buttons:"); - for (i = 0; i < event->buttons->mask_len * 8; i++) - if (BitIsOn(event->buttons->mask, i)) + for (i = 0; i < event->buttons.mask_len * 8; i++) + if (XIMaskIsSet(event->buttons.mask, i)) printf(" %d", i); printf("\n"); - printf(" modifiers: locked 0x%x latched 0x%x base 0x%x\n", - event->mods->locked, event->mods->latched, - event->mods->base); - printf(" group: locked 0x%x latched 0x%x base 0x%x\n", - event->group->locked, event->group->latched, - event->group->base); + printf(" modifiers: locked %#x latched %#x base %#x effective: %#x\n", + event->mods.locked, event->mods.latched, + event->mods.base, event->mods.effective); + printf(" group: locked %#x latched %#x base %#x effective: %#x\n", + event->group.locked, event->group.latched, + event->group.base, event->group.effective); printf(" root x/y: %.2f / %.2f\n", event->root_x, event->root_y); printf(" event x/y: %.2f / %.2f\n", event->event_x, event->event_y); @@ -201,6 +235,7 @@ static void print_enterleave(XILeaveEvent* event) static void print_propertyevent(Display *display, XIPropertyEvent* event) { char *changed; + char *name; if (event->what == XIPropertyDeleted) changed = "deleted"; @@ -208,10 +243,12 @@ static void print_propertyevent(Display *display, XIPropertyEvent* event) changed = "created"; else changed = "modified"; - - printf(" property: %ld '%s'\n", event->property, XGetAtomName(display, event->property)); + name = XGetAtomName(display, event->property); + printf(" time: %ld\n", event->time); + printf(" property: %ld '%s'\n", event->property, name); printf(" changed: %s\n", changed); + XFree(name); } void test_sync_grab(Display *display, Window win) @@ -224,7 +261,7 @@ test_sync_grab(Display *display, Window win) mask.deviceid = XIAllDevices; mask.mask_len = 2; mask.mask = calloc(2, sizeof(char)); - SetBit(mask.mask, XI_ButtonPress); + XISetMask(mask.mask, XI_ButtonPress); if ((rc = XIGrabDevice(display, 2, win, CurrentTime, None, GrabModeSync, GrabModeAsync, False, &mask)) != GrabSuccess) @@ -245,12 +282,11 @@ test_sync_grab(Display *display, Window win) XIEvent ev; XNextEvent(display, (XEvent*)&ev); - if (ev.type == GenericEvent) + if (ev.type == GenericEvent && ev.extension == xi_opcode ) { XIDeviceEvent *event = (XIDeviceEvent*)&ev; print_deviceevent(event); XIAllowEvents(display, 2, SyncPointer, CurrentTime); - XIFreeEventData(&ev); } } @@ -258,6 +294,41 @@ test_sync_grab(Display *display, Window win) printf("Done\n"); } +static const char* type_to_name(int evtype) +{ + const char *name; + + switch(evtype) { + case XI_DeviceChanged: name = "DeviceChanged"; break; + case XI_KeyPress: name = "KeyPress"; break; + case XI_KeyRelease: name = "KeyRelease"; break; + case XI_ButtonPress: name = "ButtonPress"; break; + case XI_ButtonRelease: name = "ButtonRelease"; break; + case XI_Motion: name = "Motion"; break; + case XI_Enter: name = "Enter"; break; + case XI_Leave: name = "Leave"; break; + case XI_FocusIn: name = "FocusIn"; break; + case XI_FocusOut: name = "FocusOut"; break; + case XI_HierarchyChanged: name = "HierarchyChanged"; break; + case XI_PropertyEvent: name = "PropertyEvent"; break; + case XI_RawKeyPress: name = "RawKeyPress"; break; + case XI_RawKeyRelease: name = "RawKeyRelease"; break; + case XI_RawButtonPress: name = "RawButtonPress"; break; + case XI_RawButtonRelease: name = "RawButtonRelease"; break; + case XI_RawMotion: name = "RawMotion"; break; + case XI_TouchBegin: name = "TouchBegin"; break; + case XI_TouchUpdate: name = "TouchUpdate"; break; + case XI_TouchEnd: name = "TouchEnd"; break; + case XI_RawTouchBegin: name = "RawTouchBegin"; break; + case XI_RawTouchUpdate: name = "RawTouchUpdate"; break; + case XI_RawTouchEnd: name = "RawTouchEnd"; break; + default: + name = "unknown event type"; break; + } + return name; +} + + int test_xi2(Display *display, int argc, @@ -265,59 +336,91 @@ test_xi2(Display *display, char *name, char *desc) { - XIEventMask mask; + XIEventMask mask[2]; + XIEventMask *m; Window win; + int deviceid = -1; + int use_root = 0; + int rc; - list(display, argc, argv, name, desc); - win = create_win(display); + setvbuf(stdout, NULL, _IOLBF, 0); - XSync(display, False); + if (argc >= 1 && strcmp(argv[0], "--root") == 0) { + use_root = 1; - /* Select for motion events */ - mask.deviceid = XIAllDevices; - mask.mask_len = 2; - mask.mask = calloc(mask.mask_len, sizeof(char)); - SetBit(mask.mask, XI_ButtonPress); - SetBit(mask.mask, XI_ButtonRelease); - SetBit(mask.mask, XI_KeyPress); - SetBit(mask.mask, XI_KeyRelease); - SetBit(mask.mask, XI_Motion); - SetBit(mask.mask, XI_DeviceChanged); - SetBit(mask.mask, XI_Enter); - SetBit(mask.mask, XI_Leave); - SetBit(mask.mask, XI_FocusIn); - SetBit(mask.mask, XI_FocusOut); - SetBit(mask.mask, XI_HierarchyChanged); - SetBit(mask.mask, XI_PropertyEvent); - XISelectEvents(display, win, &mask, 1); - XSync(display, False); + argc--; + argv++; + } - { - int modifiers[] = {0, 0x10, 0x1, 0x11}; - int nmods = sizeof(modifiers)/sizeof(modifiers[0]); - - mask.deviceid = 2; - memset(mask.mask, 0, 2); - SetBit(mask.mask, XI_KeyPress); - SetBit(mask.mask, XI_KeyRelease); - SetBit(mask.mask, XI_ButtonPress); - SetBit(mask.mask, XI_Motion); - XIGrabButton(display, 2, 1, win, None, GrabModeAsync, GrabModeAsync, - False, &mask, nmods, modifiers); - XIGrabKeysym(display, 3, 0x71, win, GrabModeAsync, GrabModeAsync, - False, &mask, nmods, modifiers); - XIUngrabButton(display, 3, 1, win, nmods - 2, &modifiers[2]); - XIUngrabKeysym(display, 3, 0x71, win, nmods - 2, &modifiers[2]); + rc = list(display, argc, argv, name, desc); + if (rc != EXIT_SUCCESS) + return rc; + + if (use_root) + win = DefaultRootWindow(display); + else + win = create_win(display); + + if (argc >= 1) { + XIDeviceInfo *info; + info = xi2_find_device_info(display, argv[0]); + /* info is alway valid, the list() call exits if the device + cannot be found, but let's shut up coverity */ + if (!info) + return EXIT_FAILURE; + deviceid = info->deviceid; } - mask.deviceid = XIAllMasterDevices; - memset(mask.mask, 0, 2); - SetBit(mask.mask, XI_RawEvent); - XISelectEvents(display, DefaultRootWindow(display), &mask, 1); + /* Select for motion events */ + m = &mask[0]; + m->deviceid = (deviceid == -1) ? XIAllDevices : deviceid; + m->mask_len = XIMaskLen(XI_LASTEVENT); + m->mask = calloc(m->mask_len, sizeof(char)); + XISetMask(m->mask, XI_ButtonPress); + XISetMask(m->mask, XI_ButtonRelease); + XISetMask(m->mask, XI_KeyPress); + XISetMask(m->mask, XI_KeyRelease); + XISetMask(m->mask, XI_Motion); + XISetMask(m->mask, XI_DeviceChanged); + XISetMask(m->mask, XI_Enter); + XISetMask(m->mask, XI_Leave); + XISetMask(m->mask, XI_FocusIn); + XISetMask(m->mask, XI_FocusOut); +#if HAVE_XI22 + XISetMask(m->mask, XI_TouchBegin); + XISetMask(m->mask, XI_TouchUpdate); + XISetMask(m->mask, XI_TouchEnd); +#endif + if (m->deviceid == XIAllDevices) + XISetMask(m->mask, XI_HierarchyChanged); + XISetMask(m->mask, XI_PropertyEvent); + + m = &mask[1]; + m->deviceid = (deviceid == -1) ? XIAllMasterDevices : deviceid; + m->mask_len = XIMaskLen(XI_LASTEVENT); + m->mask = calloc(m->mask_len, sizeof(char)); + XISetMask(m->mask, XI_RawKeyPress); + XISetMask(m->mask, XI_RawKeyRelease); + XISetMask(m->mask, XI_RawButtonPress); + XISetMask(m->mask, XI_RawButtonRelease); + XISetMask(m->mask, XI_RawMotion); +#if HAVE_XI22 + XISetMask(m->mask, XI_RawTouchBegin); + XISetMask(m->mask, XI_RawTouchUpdate); + XISetMask(m->mask, XI_RawTouchEnd); +#endif + + XISelectEvents(display, win, &mask[0], use_root ? 2 : 1); + if (!use_root) { + XISelectEvents(display, DefaultRootWindow(display), &mask[1], 1); + XMapWindow(display, win); + } + XSync(display, False); - free(mask.mask); + free(mask[0].mask); + free(mask[1].mask); - { + if (!use_root) { XEvent event; XMaskEvent(display, ExposureMask, &event); XSelectInput(display, win, 0); @@ -329,41 +432,49 @@ test_xi2(Display *display, while(1) { - XIEvent ev; + XEvent ev; + XGenericEventCookie *cookie = (XGenericEventCookie*)&ev.xcookie; XNextEvent(display, (XEvent*)&ev); - if (ev.type == GenericEvent) - { - XIDeviceEvent *event = (XIDeviceEvent*)&ev; - printf("EVENT type %d\n", event->evtype); - switch (event->evtype) + if (XGetEventData(display, cookie) && + cookie->type == GenericEvent && + cookie->extension == xi_opcode) + { + printf("EVENT type %d (%s)\n", cookie->evtype, type_to_name(cookie->evtype)); + switch (cookie->evtype) { case XI_DeviceChanged: - print_devicechangedevent(display, - (XIDeviceChangedEvent*)event); + print_devicechangedevent(display, cookie->data); break; case XI_HierarchyChanged: - print_hierarchychangedevent((XIHierarchyEvent*)event); + print_hierarchychangedevent(cookie->data); break; - case XI_RawEvent: - print_rawevent((XIRawEvent*)event); + case XI_RawKeyPress: + case XI_RawKeyRelease: + case XI_RawButtonPress: + case XI_RawButtonRelease: + case XI_RawMotion: + case XI_RawTouchBegin: + case XI_RawTouchUpdate: + case XI_RawTouchEnd: + print_rawevent(cookie->data); break; case XI_Enter: case XI_Leave: case XI_FocusIn: case XI_FocusOut: - print_enterleave((XILeaveEvent*)event); + print_enterleave(cookie->data); break; case XI_PropertyEvent: - print_propertyevent(display, (XIPropertyEvent*)event); + print_propertyevent(display, cookie->data); break; default: - print_deviceevent(event); + print_deviceevent(cookie->data); break; } } - XIFreeEventData(&ev); + XFreeEventData(display, cookie); } XDestroyWindow(display, win);