Convert ASCII character to x11 keycode

I have a small program that accepts input as ascii characters. I need to be able to convert them to key codes for use with x11 functions. Is there an xlib function to execute this or another library? Or will a large switch work better?

+4
source share
2 answers

You can use XStringToKeysym to convert to KeySym , then XKeysymToKeycode to convert to KeyCode .

 Display *display = ...; KeySym sym_a = XStringToKeysym("A"); KeyCode code_a = XKeysymToKeycode(display, sym_a); 
+1
source

This question has an old wrong answer (from @oldrinb), which, oddly enough, has never been disputed. As stated in the comment, you cannot use XStringToKeysym to match characters in KeySyms in a general way. It will work for letters and numbers, but more about that because the KeySym name has a direct mapping for these ASCII characters. For other ASCII characters, such as punctuation or space, this will not work.

But you can do better than that. If you look at <X11/keysymdef.h> , you will find that for ASCII 0x20-0xFF characters are mapped directly to XKeySyms . So I would say that it’s easier to just use this character range directly as KeySyms and just map the remaining 32 characters to their corresponding KeyCodes . Therefore, I would say that the code should be more correct:

 Display *display = ...; if ((int)c >= 0x20) { XKeysymToKeycode(display, (KeySym)c); } else { ... // Exercise left to the reader :-) } 

The 'else' KeyCodes will require several KeyCodes because, for example, ASCII 1 (Control-A) XK_A with the modifier XK_CONTROL_R (or XK_CONTROL_L ). Therefore, you will need to issue, for example: XK_CONTROL_L DOWN, XK_A DOWN, XK_A UP, XK_CONTROL_L UP.

Here's a toy program that demonstrates this by repeating the first argument using simulated keyboard events:

 #include <stdio.h> #include <X11/Xlib.h> #include <X11/Xlib-xcb.h> #include <xcb/xcb.h> #include <xcb/xcb_event.h> #include <xcb/xtest.h> main(int argc, char **argv) { char *pc; xcb_connection_t *xconn; KeyCode code_a; Display *dpy = XOpenDisplay(NULL); xconn = XGetXCBConnection(dpy); for (pc = argv[1]; *pc != '\0'; ++pc) { if (*pc >= (char)0x20) { code_a = XKeysymToKeycode(dpy, (KeySym)*pc); xcb_test_fake_input(xconn, XCB_KEY_PRESS, code_a, XCB_CURRENT_TIME, XCB_NONE, 0, 0, 0); xcb_test_fake_input(xconn, XCB_KEY_RELEASE, code_a, XCB_CURRENT_TIME, XCB_NONE, 0, 0, 0); xcb_flush(xconn); } else { fprintf(stderr, "Eeek - out-of-range character 0x%x\n", (unsigned int)*pc); } } XCloseDisplay(dpy); } 

You need to associate it with: -lX11 -lxcb -lxcb-xtest -lX11-xcb

Disclaimer: No KeySyms were harmed when writing this code.

+7
source

Source: https://habr.com/ru/post/1433266/


All Articles