Reputation: 643
So yesterday, I checked out the xinput source code in order to mimic what's being done there so I could make a keystroke listener for a project I'm making.
After checking out the source code, especially test_xi2.c
, I came around with this.
#include <iostream>
#include <X11/Xlib.h>
#include <X11/extensions/XInput2.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
Display* display = XOpenDisplay(NULL);
Window win;
win = DefaultRootWindow(display);
XIEventMask* m = new XIEventMask;
m->deviceid = XIAllDevices;
m->mask_len = XIMaskLen(XI_LASTEVENT);
m->mask = (unsigned char*)calloc(m->mask_len, sizeof(char));
XISetMask(m->mask, XI_RawKeyPress);
XISetMask(m->mask, XI_RawKeyRelease);
XISelectEvents(display, win, m, 1);
XSync(display, False);
while(true)
{
XEvent ev;
XGenericEventCookie *cookie = (XGenericEventCookie*)&ev.xcookie;
XNextEvent(display, (XEvent*)&ev);
if (XGetEventData(display, cookie) && cookie->type == GenericEvent) {
switch (cookie->evtype) {
case XI_RawKeyPress: std::cout << "keystroke" << std::endl; break;
}
}
XFreeEventData(display, cookie);
}
XDestroyWindow(display, win);
return 0;
}
You compile this by doing g++ main.cpp -lX11 -lXi
.
So, if you compare it to the original source, you'll see the only thing I don't do, apart from listening for all the other event types that are useless to me at the moment, is the check whether cookie->extension == xi_opcode
(line 431 of test_xi2.c
). After researching a bit, I came to the conclusion that it isn't really necessary to check whether this condition is met. xi_opcode
turns out to be an extension opcode, that is queried using XQueryExtension
here. I've checked on my machine, and the extension seems to always be 131, so it's not like half of the RawKeyPress events have one extension and the other half have another extension.
I really can't tell what else could be going on.
Upvotes: 0
Views: 907
Reputation: 76519
It seems XIAllDevices
also captures virtual "extra" devices, which in this case includes a second keyboard, which means you will get all keyboard events times 2.
Try using XIAllMasterDevices
which takes together all these into one "keyboard".
Upvotes: 3