Sto semplicemente cercando di prendere un KeyCode e una maschera di modifica e convertirlo in un KeySym usando l'estensione Xkb. Non riesco a capire perché questo non funziona. È ovvio che i modificatori non corrispondono ma non so perché. Non so nemmeno se sto convertendo il gruppo correttamente.Xkb: Come convertire un keycode in keysym
#include <stdio.h>
#include <stdlib.h>
#include <X11/X.h>
#include <X11/XKBlib.h>
void check(XkbDescPtr keyboard_map, KeyCode keycode, unsigned int mask) {
//What the hell is diff between XkbKeyGroupInfo and XkbKeyNumGroups?
unsigned char info = XkbKeyGroupInfo(keyboard_map, keycode);
int num_groups = XkbKeyNumGroups(keyboard_map, keycode);
int key_width = XkbKeyGroupsWidth(keyboard_map, keycode);
//int num_syms = XkbKeyNumSyms(keyboard_map, keycode);
//Get the group
unsigned int group = 0; // What should this default to?
switch (XkbOutOfRangeGroupAction(info)) {
case XkbRedirectIntoRange:
/* If the RedirectIntoRange flag is set, the four least significant
* bits of the groups wrap control specify the index of a group to
* which all illegal groups correspond. If the specified group is
* also out of range, all illegal groups map to Group1.
*/
printf("XkbRedirectIntoRange\n");
group = XkbOutOfRangeGroupInfo(info);
if (group >= num_groups) {
group = 0;
}
break;
case XkbClampIntoRange:
/* If the ClampIntoRange flag is set, out-of-range groups correspond
* to the nearest legal group. Effective groups larger than the
* highest supported group are mapped to the highest supported group;
* effective groups less than Group1 are mapped to Group1 . For
* example, a key with two groups of symbols uses Group2 type and
* symbols if the global effective group is either Group3 or Group4.
*/
printf("XkbClampIntoRange\n");
group = num_groups - 1;
break;
case XkbWrapIntoRange:
/* If neither flag is set, group is wrapped into range using integer
* modulus. For example, a key with two groups of symbols for which
* groups wrap uses Group1 symbols if the global effective group is
* Group3 or Group2 symbols if the global effective group is Group4.
*/
printf("XkbWrapIntoRange\n");
default:
printf("Default\n");
if (num_groups != 0) {
group %= num_groups;
}
break;
}
printf("Group Info %d, %d, %d\n", group, num_groups, key_width);
//printf("Mask Info %d, %d, %d, %d, %d, %d, %d, %d\n", ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask);
XkbKeyTypePtr key_type = XkbKeyKeyType(keyboard_map, keycode, group);
KeySym keysym = NoSymbol;
int i;
for (i = 0; i < key_type->map_count; i++) {
if (key_type->map[i].active && key_type->map[i].mods.mask == mask) {
keysym = XkbKeySymEntry(keyboard_map, keycode, i, group);
}
}
//printf("%s\n", XKeysymToString(keysym));
printf("KeyCode: %d\n", (int) keycode);
printf("KeySym: %d\n", (int) keysym);
}
int main(int argc, const char * argv[]) {
Display * display;
//Try to attach to the default X11 display.
display = XOpenDisplay(NULL);
if(display == NULL) {
printf("Error: Could not open display!\n");
return EXIT_FAILURE;
}
//Get the map
XkbDescPtr keyboard_map = XkbGetMap(display, XkbAllClientInfoMask, XkbUseCoreKbd);
KeyCode keycode = 56; // b
check(keyboard_map, keycode, ShiftMask | LockMask | ControlMask);
//Close the connection to the selected X11 display.
XCloseDisplay(display);
return EXIT_SUCCESS;
}