The following code will print the whole keycode-to-keysym mapping. It is equivalent to xmodmap -pk
or xmodmap -pke
. That is, given any keycode, it gives you the keysyms associated to that keycode.
(Except that it only shows keysym values, not keysym names, which you can find in /usr/include/X11/keysymdef.h
or using Xlib's XKeysymToString()
, and I don't think there exists an XCB port of that function, but you could write your own based on keysymdef.h
.) (On my X server, there's 7 keysyms per keycode, and I'd like to know if the X server can support more than that...)
/*
gcc keymap.c -o keymap -lxcb && ./keymap
*/
#include <stdlib.h>
#include <stdio.h>
#include <xcb/xcb.h>
void xcb_show_keyboard_mapping(xcb_connection_t* connection, const xcb_setup_t* setup){
xcb_get_keyboard_mapping_reply_t* keyboard_mapping =
xcb_get_keyboard_mapping_reply(
connection,
xcb_get_keyboard_mapping(
connection,
setup->min_keycode,
setup->max_keycode - setup->min_keycode + 1),
NULL);
int nkeycodes = keyboard_mapping->length / keyboard_mapping->keysyms_per_keycode;
int nkeysyms = keyboard_mapping->length;
xcb_keysym_t* keysyms = (xcb_keysym_t*)(keyboard_mapping + 1); // `xcb_keycode_t` is just a `typedef u8`, and `xcb_keysym_t` is just a `typedef u32`
printf("nkeycodes %u nkeysyms %u keysyms_per_keycode %u\n\n", nkeycodes, nkeysyms, keyboard_mapping->keysyms_per_keycode);
for(int keycode_idx=0; keycode_idx < nkeycodes; ++keycode_idx){
printf("keycode %3u ", setup->min_keycode + keycode_idx);
for(int keysym_idx=0; keysym_idx < keyboard_mapping->keysyms_per_keycode; ++keysym_idx){
printf(" %8x", keysyms[keysym_idx + keycode_idx * keyboard_mapping->keysyms_per_keycode]);
}
putchar('\n');
}
free(keyboard_mapping);
}
int main(){
xcb_connection_t* connection = xcb_connect(NULL, NULL);
const xcb_setup_t* setup = xcb_get_setup(connection);
xcb_show_keyboard_mapping(connection, setup);
xcb_disconnect(connection);
}
If you want the opposite mapping (keysyms-to-keycodes), you may want xcb_key_symbols_get_keycode()
, I don't know.
And no, you don't need XKB to handle keyboard stuff. Most of the stuff you could possibly want can be done with the core X protocol, including but not limited to modifying the aforementioned keycode-to-keysym mapping, grabbing the keyboard, grabbing the mouse, sending keyboard/mouse input, using all 8 modifiers, and writing "pseudo Unicode" (ie. all the symbols you find in keysymdef.h
, which I don't think is oficially Unicode but does contain a lot of stuff).