[Xcb] [RFC] xcb/util-keysyms input handling patch
Michael Stapelberg
michael+xcb at stapelberg.de
Tue Oct 23 03:47:45 PDT 2012
Hi,
It’s been a week without any news. Does nobody feel up to reviewing this
code and answering my questions? :-)
Michael Stapelberg <michael+xcb at stapelberg.de> writes:
> Hi Peter,
>
> Michael Stapelberg <michael+xcb at stapelberg.de> writes:
>> solve. In case I can confirm that, I’ll happily help with
>> testing/implementing.
> So I wrote some test code which you can find attached. It’s really
> horrible code and I apologize, but it gets the job done. Compile it with
> gcc -o xlib-ih xlib-ih.c -lX11 -lXi
>
> The program opens a window and then grabs the keyboard forever (so you
> might want to run it via SSH on another computer or keep at vt handy for
> killing it). For every XI_KeyPress event, it translates the keycode to a
> keysym and prints the name of that keysym.
>
> I have the following questions about it:
>
> 1. Is using the function XkbTranslateKeyCode appropriate for this? It
> feels slightly kludgy to use XkbBuildCoreState, but I could not
> figure out what the correct shift level is for calling
> XkbKeycodeToKeysym (it does NOT map 1:1 to the KeyPress’s
> mods.effective in all cases).
>
> 2. Is getting the core keyboard via XKB correct?
>
> 3. To port this code over to XCB, we’d need to implement XInput >= 2.0
> plus maybe more of XKB (haven’t checked) plus all the code which Xlib
> provides (especially XkbTranslateKeyCode and dependencies), right?
>
> 4. Assuming that 3 is true, would it be acceptable to implement the bare
> minimum of XI/XKB to get this working? I’m not interested in
> implementing full XKB, full Xinput or a full port of additional
> functions. I just want to correctly get Keysyms for key presses./*
> * vim:ts=4:sw=4:expandtab
> */
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <unistd.h>
> #include <stdbool.h>
> #include <stdint.h>
> #include <err.h>
>
> #include <X11/Xlib.h>
> #include <X11/XKBlib.h>
> #include <X11/extensions/XI.h>
> #include <X11/extensions/XInput2.h>
> #include <X11/extensions/XKB.h>
>
>
> int xi_opcode;
>
> int
> xinput_version(Display *display)
> {
> XExtensionVersion *version;
> static int vers = -1;
>
> if (vers != -1)
> return vers;
>
> version = XGetExtensionVersion(display, INAME);
>
> if (version && (version != (XExtensionVersion*) NoSuchExtension)) {
> vers = version->major_version;
> XFree(version);
> }
>
> /* Announce our supported version so the server treats us correctly. */
> if (vers >= XI_2_Major)
> {
> int maj = 2,
> min = 2;
>
> XIQueryVersion(display, &maj, &min);
> }
>
> return vers;
> }
>
> static Window create_win(Display *dpy)
> {
> Window win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, 200,
> 200, 0, 0, WhitePixel(dpy, 0));
> Window subwindow = XCreateSimpleWindow(dpy, win, 50, 50, 50, 50, 0, 0,
> BlackPixel(dpy, 0));
>
> XMapWindow(dpy, subwindow);
> XSelectInput(dpy, win, ExposureMask);
> return win;
> }
>
> int main() {
> int event, error;
>
> Display *display = XOpenDisplay(NULL);
> if (!display)
> errx(1, "cannot connect to X11");
> printf("dpy = %p\n", display);
>
> if (!XQueryExtension(display, "XInputExtension", &xi_opcode, &event, &error))
> errx(1, "X Input extension not available.\n");
>
> if (!xinput_version(display))
> errx(1, "xinput not available\n");
>
> Window win = create_win(display);
>
> XMapWindow(display, win);
>
>
> XSync(display, False);
>
> usleep(100 * 1000);
>
> int rc;
> XIEventMask mask;
>
> /* Select for motion events */
> mask.deviceid = XIAllDevices;
> mask.mask_len = 2;
> mask.mask = calloc(2, sizeof(char));
> XISetMask(mask.mask, XI_KeyPress);
>
> if ((rc = XIGrabDevice(display, 3, win, CurrentTime, None, GrabModeAsync,
> GrabModeAsync, False, &mask)) != GrabSuccess)
> {
> fprintf(stderr, "Grab failed with %d\n", rc);
> return;
> }
> free(mask.mask);
> printf("grabbed\n");
>
> XEvent *ev = malloc(65535);
> while (1) {
> printf("next event\n");
> XGenericEventCookie *cookie = (XGenericEventCookie*)&ev->xcookie;
> XNextEvent(display, (XEvent*)ev);
>
> if (XGetEventData(display, cookie) &&
> cookie->type == GenericEvent &&
> cookie->extension == xi_opcode)
> {
> XIDeviceEvent *event = cookie->data;
> if (event->evtype != XI_KeyPress)
> continue;
>
> KeySym ksym;
> int mods_rtrn;
> XkbDescPtr desc = XkbGetKeyboard(display, XkbAllComponentsMask, XkbUseCoreKbd);
>
> XkbTranslateKeyCode(desc, event->detail, XkbBuildCoreState(event->mods.effective, event->group.effective), &mods_rtrn, &ksym);
> printf("keysym = %s\n", XKeysymToString(ksym));
>
> }
> }
> }
>
>
> --
> Best regards,
> Michael
--
Best regards,
Michael
More information about the Xcb
mailing list