Не уверен, что это поможет, но...
Вероятно, вы ищете семейство функций X*LookupString:
http://www.xfree86.org/current/Xutf8LookupString.3.html
Теперь у меня была та же проблема, что и у вас, то есть мне нужно было перенести приложение, использующее WM_CHAR
WinAPI, на приложение, использующее xcb
в сочетании с X11
(поскольку такое соединение необходимо для окна OpenGL). Мне не нужен был Unicode, но я все еще был потерян, потому что не было ничего, что позволяло бы мне получить составной ввод от нажатий клавиш (например, нажатие shift
и 7
должно привести к &
)
К сожалению, цитируя список дел от xcb:
Текущий статус
В настоящее время XCB реализует только биты, указанные в системном протоколе X Window, и даже эта поддержка не является полной по сравнению с Xlib (кодировка символов, без XLookupString()...).
Итак, если вам нужно использовать xcb
, это усложняет задачу, так как нет эквивалентных функций X*LookupString
для события нажатия клавиши, возвращаемого xcb - xcb_key_press_event_t
. Что вам нужно сделать, так это преобразовать его в XKeyEvent
, понятное, например, XLookupString
.
Теперь рассмотрим источник XLookupString
, мы видим, что он использует только три поля XKeyEvent
:
display
- вам Display
keycode
- нажатая клавиша
state
- состояние клавиш-модификаторов, например. шифт или капс лок
Так уж получилось, что в xcb_key_press_event_t
есть соответствующие поля, практически идентичные тем, которые нам нужны. То, что я сделал, чтобы заставить мое конкретное приложение работать, было следующим:
// This is your generic event returned by, for example, xcb_poll_for_event
const xcb_generic_event_t* event = ...;
const auto* const press = reinterpret_cast<const xcb_key_press_event_t*>(event);
// Now we have to prepare input understandable by the lookup function
XKeyEvent keyev;
keyev.display = display; // here you'll need to supply your Display*
keyev.keycode = press->detail;
keyev.state = press->state;
std::array<char, 16> buf {};
if (XLookupString(&keyev, buf.data(), buf.size(), nullptr, nullptr)) {
// Now buf should contain a string with your characters;
// I just need ascii so I always take only buf[0] and it works fine
}
else {
// Something's wrong... report error or something
}
Также похоже, что XLookupString
выводит keysym, соответствующий составному символу, через свой входной аргумент KeySym *keysym_return
. Поскольку вы говорите, что вам также нужны символы клавиш, вы можете использовать их.
Я не делаю профессиональное приложение, поэтому это все, что мне нужно, и я не совсем уверен, каков план действий для полной поддержки Unicode, но если я когда-нибудь доберусь до этого, я дам вам знать.
person
Patryk Czachurski
schedule
09.12.2017