Tôi chỉ đơn giản là cố gắng lấy KeyCode và mặt nạ sửa đổi và chuyển đổi nó thành KeySym bằng cách sử dụng phần mở rộng Xkb. Tôi không thể có vẻ để tìm ra lý do tại sao điều này không hoạt động. Rõ ràng là các modifier không khớp nhưng tôi không biết tại sao. Tôi thậm chí không biết nếu tôi chuyển đổi nhóm một cách chính xác.Xkb: Cách chuyển đổi mã khóa thành 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;
}