<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><meta content="text/html;charset=UTF-8" http-equiv="Content-Type"></head><body ><div style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt;"><div>By running something like<br></div><div><br></div><div>xmodmap -pke<br></div><div><br></div><div>or calling xcb_get_keyboard_mapping_unchecked()<br></div><div><br></div><div>one can get the mapping of 8-bit X11 keycodes to 32-bit keysyms, where each keycode maps to (I think) 8 keysyms or so.<br></div><div><br></div><div>Then, one can send X11 keycodes to applications by calling xcb_send_event(). I have a helper function for that:<br></div><div><br></div><div><br></div><div>void xcb_send_key_press(xcb_connection_t* connection, xcb_window_t root, xcb_window_t window, xcb_keycode_t keycode){<br></div><div> xcb_key_press_event_t ev; memset(&ev,0x00,sizeof(xcb_key_press_event_t));<br></div><div> ev.response_type = XCB_KEY_PRESS;<br></div><div> ev.detail = keycode;<br></div><div> ev.time = XCB_CURRENT_TIME;<br></div><div> ev.root = root;<br></div><div> ev.event = window;<br></div><div> ev.state = 0x0000;<br></div><div> ev.same_screen = 1;<br></div><div> xcb_send_event(connection, 0, window, XCB_EVENT_MASK_NO_EVENT, (const char*)&ev);<br></div><div>}<br></div><div><br></div><div><br></div><div>I'm trying to send arbitrary Unicode codepoints (and, just as importantly, sequences of codepoints) to the X11 application/window currently in focus.<br></div><div>I know this is possible because "every possible Unicode character has already a keysym string defined algorithmically" (source: /usr/include/X11/keysymdef.h).<br></div><div><br></div><div>To send, eg., Unicode codepoint U+1f3f4, I'm doing:<br></div><div><br></div><div><br></div><div>#define X11_UNICODE_BASE 0x01000000<br></div><div>xcb_change_keyboard_mapping(connection, 1,255, 1,(const xcb_keysym_t[]){X11_UNICODE_BASE|0x01f3f4});<br></div><div>xcb_send_key_press(connection, screen->root, get_input_focus_reply->focus, 255);<br></div><div><br></div><div><br></div><div>where I'm remapping keycode 255 (last X11 keycode) on-the-fly to the desired Unicode codepoint.<br></div><div><br></div><div>But I can't figure out how to send keysyms directly, without having to call xcb_change_keyboard_mapping(), which is very, very slow if you call it several times in a row (in that case it freezes certain X11 things for several seconds, like mouse clicking and alt-tabbing).<br></div><div><br></div><div>So, for example, what I'm doing in order to send (say) the flag of England (7 Unicode codepoints), I'm doing (what effectually amounts to):<br></div><div><br></div><div><br></div><div>xcb_get_input_focus_cookie_t get_input_focus_cookie = xcb_get_input_focus_unchecked(connection);<br></div><div>xcb_get_input_focus_reply_t* get_input_focus_reply = xcb_get_input_focus_reply(connection, get_input_focus_cookie, NULL);<br></div><div>xcb_change_keyboard_mapping(connection, 1,249, 1,(const xcb_keysym_t[]){X11_UNICODE_BASE|0x01f3f4});<br></div><div>xcb_send_key_press(connection, screen->root, get_input_focus_reply->focus, 249);<br></div><div>xcb_change_keyboard_mapping(connection, 1,250, 1,(const xcb_keysym_t[]){X11_UNICODE_BASE|0x0e0067});<br></div><div>xcb_send_key_press(connection, screen->root, get_input_focus_reply->focus, 250);<br></div><div>xcb_change_keyboard_mapping(connection, 1,251, 1,(const xcb_keysym_t[]){X11_UNICODE_BASE|0x0e0062});<br></div><div>xcb_send_key_press(connection, screen->root, get_input_focus_reply->focus, 251);<br></div><div>xcb_change_keyboard_mapping(connection, 1,252, 1,(const xcb_keysym_t[]){X11_UNICODE_BASE|0x0e0065});<br></div><div>xcb_send_key_press(connection, screen->root, get_input_focus_reply->focus, 252);<br></div><div>xcb_change_keyboard_mapping(connection, 1,253, 1,(const xcb_keysym_t[]){X11_UNICODE_BASE|0x0e006e});<br></div><div>xcb_send_key_press(connection, screen->root, get_input_focus_reply->focus, 253);<br></div><div>xcb_change_keyboard_mapping(connection, 1,254, 1,(const xcb_keysym_t[]){X11_UNICODE_BASE|0x0e0067});<br></div><div>xcb_send_key_press(connection, screen->root, get_input_focus_reply->focus, 254);<br></div><div>xcb_change_keyboard_mapping(connection, 1,255, 1,(const xcb_keysym_t[]){X11_UNICODE_BASE|0x0e007f});<br></div><div>xcb_send_key_press(connection, screen->root, get_input_focus_reply->focus, 255);<br></div><div>xcb_sync(connection);<br></div><div><br></div><div><br></div><div>which works, but looks insane to me, and is also slow (in the sense described before).<br></div><div><br></div><div>Though the following also works:<br></div><div><br></div><div><br></div><div>xcb_change_keyboard_mapping(connection, 7,249, 1,(const xcb_keysym_t[]){X11_UNICODE_BASE|0x01f3f4,X11_UNICODE_BASE|0x0e0067,X11_UNICODE_BASE|0x0e0062,X11_UNICODE_BASE|0x0e0065,X11_UNICODE_BASE|0x0e006e,X11_UNICODE_BASE|0x0e0067,X11_UNICODE_BASE|0x0e007f});<br></div><div>xcb_send_key_press(connection, screen->root, get_input_focus_reply->focus, 249);<br></div><div>xcb_send_key_press(connection, screen->root, get_input_focus_reply->focus, 250);<br></div><div>xcb_send_key_press(connection, screen->root, get_input_focus_reply->focus, 251);<br></div><div>xcb_send_key_press(connection, screen->root, get_input_focus_reply->focus, 252);<br></div><div>xcb_send_key_press(connection, screen->root, get_input_focus_reply->focus, 253);<br></div><div>xcb_send_key_press(connection, screen->root, get_input_focus_reply->focus, 254);<br></div><div>xcb_send_key_press(connection, screen->root, get_input_focus_reply->focus, 255);<br></div><div><br></div><div><br></div><div>But in general I can't use the trick of calling xcb_change_keyboard_mapping() with multiple desired Unicode values at once (which is way faster than doing it one at a time) because for my application I don't know in advance what Unicode codepoints will be sent by the user.<br></div><div>And, since X11 keycodes are merely 8-bits, they can't fit all of Unicode anyway (not even practical things, like all 3790 emoji, which by my count amount to 11,192 Unicode codepoints).<br></div><div><br></div><div><br></div><div>What would much more sense is to do something like:<br></div><div><br></div><div><br></div><div>xcb_send_keysym(connection, X11_UNICODE_BASE|0x01f3f4);<br></div><div>xcb_send_keysym(connection, X11_UNICODE_BASE|0x0e0067);<br></div><div>xcb_send_keysym(connection, X11_UNICODE_BASE|0x0e0062);<br></div><div>xcb_send_keysym(connection, X11_UNICODE_BASE|0x0e0065);<br></div><div>xcb_send_keysym(connection, X11_UNICODE_BASE|0x0e006e);<br></div><div>xcb_send_keysym(connection, X11_UNICODE_BASE|0x0e0067);<br></div><div>xcb_send_keysym(connection, X11_UNICODE_BASE|0x0e007f);<br></div><div><br></div><div><br></div><div>without the freeze that multiple calls to xcb_change_keyboard_mapping() cause.<br></div><div><br></div><div>So, how can I do that?<br></div><div><br></div><div>(I'm already doing this on Windows and Mac, but I've yet to find a solution for X11.)<br></div><div><br></div></div><br></body></html>