Получение раскладки клавиатуры и клавиш с помощью XCB
Я создаю экранную клавиатуру для Linux, интегрированную в простой диспетчер окон. В настоящее время я использую XCB, и теперь я хочу сделать ложные нажатия клавиш. Все работает нормально, используя расширение xtest, за исключением деталей, которые я не могу получить истинные коды клавиш из ключей, которые я хочу поставить.
В настоящее время я использую xcb_key_symbols_get_keycode, а затем я использую xcb_key_symbols_get_keysym, чтобы узнать, какой модификатор мне нужен, чтобы получить этот символ. Это прекрасно работает, когда настроенная клавиатура является США. Но у меня есть испанская клавиатура, и этот вызов возвращает только настройки США. В испанских клавиатурах несколько символов получаются с правым alt (altgr), но предыдущие вызовы, кажется, не поддерживают это.
Итак, как я могу получить коды клавиш, необходимые для получения любых ключей? Я предполагаю, что мне нужны расширения XKB, но я не смог найти их для XCB, и я не хочу переписывать весь оконный менеджер для XLib.
Благодарю.
2 ответа
Вероятно, это устаревшая проблема, но я считаю, что она по-прежнему актуальна.
Вы можете включить расширения xkb через xcb, а затем получить раскладку, ее раскладку и соответствующий симсит для этой раскладки через API xcb (или, более конкретно, из состояния раскладки xkb).
Ссылки:
- libxkbcommon Быстрый старт
- Поддержка X11 для настройки расширения xkb и получения идентификатора устройства (см. Предыдущую ссылку: необходимо создать расширение, прежде чем пытаться получить доступ к любому
xcb_x11
звонки). (с идентификатором устройства вы можете позвонитьxkb_x11_keymap_new_from_device
вернутьxkb_keymap
указатель). - xkb_keymap struct
- Состояние клавиатуры (и что более важно
xkb_state_key_get_sym()
) здесь вы можете использовать xkb_state, чтобы получить sym для соответствующего ключа.
Я должен признать, что на самом деле я еще не сделал это полностью (только до раскладки / раскладки / состояния). Но этого должно быть достаточно, чтобы вы начали.:)
Следующий код распечатает полное сопоставление кода ключа с ключом. Это эквивалентно xmodmap -pk
или же xmodmap -pke
, То есть, учитывая любой код ключа, он дает вам ключевые символы, связанные с этим кодом ключа.
(За исключением того, что он показывает только значения keysym, а не имена keysym, которые вы можете найти в /usr/include/X11/keysymdef.h
или используя Xlib's XKeysymToString()
и я не думаю, что существует порт XCB этой функции, но вы можете написать свой собственный на основе keysymdef.h
.) (На моем X-сервере для каждого кода ключа имеется 7 ключей, и я хотел бы знать, может ли X-сервер поддерживать больше, чем это...)
/*
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);
}
Если вы хотите обратное сопоставление (коды-коды-ключи), вы можете захотеть xcb_key_symbols_get_keycode()
, Я не знаю.
И нет, вам не нужен XKB для работы с клавиатурой. Большинство вещей, которые вы, возможно, захотите, могут быть выполнены с помощью основного протокола X, включая, но не ограничиваясь, модификацию вышеупомянутого сопоставления код-ключ-клавиатура, захват клавиатуры, захват мыши, отправка ввода с клавиатуры / мыши, используя все 8 модификаторов. и писать "псевдо Юникод" (т.е. все символы, которые вы найдете в keysymdef.h
, который я не думаю, что официально Unicode, но содержит много вещей).