Add XKB interface for x11
This commit is contained in:
parent
7ad237edc1
commit
cf9bace272
15 changed files with 232 additions and 31 deletions
|
@ -1,25 +1,83 @@
|
|||
#include "XcbKeyboard.h"
|
||||
|
||||
XcbKeyboard::XcbKeyboard()
|
||||
: Keyboard()
|
||||
// Header is c-like, uses explicit as a var
|
||||
#define explicit explicit_
|
||||
#include <xcb/xkb.h>
|
||||
#undef explicit
|
||||
#include <xkbcommon/xkbcommon-x11.h>
|
||||
|
||||
#include "FileLogger.h"
|
||||
|
||||
XcbKeyboard::XcbKeyboard(xcb_connection_t* connection)
|
||||
: Keyboard(),
|
||||
mConnection(connection)
|
||||
{
|
||||
mKeyMap = {{10, "1"}, {11, "2"}, {12, "3"}, {13, "4"}, {14, "5"}, {15, "6"},
|
||||
{16, "7"}, {17, "8"}, {18, "9"}, {19, "0"}, {20, "-"}, {21, "+"}, {22, "KEY_BACK"},
|
||||
{24, "q"}, {25, "w"}, {26, "e"}, {27, "r"}, {28, "t"}, {29, "y"},
|
||||
{30, "u"}, {31, "i"}, {32, "o"}, {33, "p"}, {34, "["}, {35, "]"}, {36, "KEY_RETURN"},
|
||||
{38, "a"}, {39, "s"}, {40, "d"}, {41, "f"}, {42, "g"}, {43, "h"},
|
||||
{44, "j"}, {45, "k"}, {46, "l"}, {47, ":"}, {48, "'"}, {49, "#"},
|
||||
{52, "z"}, {53, "x"}, {54, "c"}, {55, "v"}, {56, "b"},
|
||||
{57, "n"}, {58, "m"}, {59, ","}, {60, "."}, {61, "/"},
|
||||
{65, "KEY_SPACE"}, {66, "KEY_CAPS"}};
|
||||
mXkbContext = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
if (!mXkbContext)
|
||||
{
|
||||
MLOG_ERROR("Failed to get XKB context");
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<XcbKeyboard> XcbKeyboard::Create()
|
||||
std::unique_ptr<XcbKeyboard> XcbKeyboard::Create(xcb_connection_t* connection)
|
||||
{
|
||||
return std::make_unique<XcbKeyboard>();
|
||||
return std::make_unique<XcbKeyboard>(connection);
|
||||
}
|
||||
|
||||
std::string XcbKeyboard::GetKeyString(KeyCode keyCode)
|
||||
void XcbKeyboard::updateState(xcb_xkb_state_notify_event_t *state)
|
||||
{
|
||||
return mKeyMap[keyCode];
|
||||
xkb_state_update_mask(mXkbState, state->baseMods,
|
||||
state->latchedMods,
|
||||
state->lockedMods,
|
||||
state->baseGroup,
|
||||
state->latchedGroup,
|
||||
state->lockedGroup);
|
||||
}
|
||||
|
||||
std::string XcbKeyboard::getKeyString(KeyCode keyCode)
|
||||
{
|
||||
if (!mXkbState)
|
||||
{
|
||||
getKeyMap();
|
||||
}
|
||||
|
||||
auto size = xkb_state_key_get_utf8(mXkbState, keyCode, nullptr, 0) + 1;
|
||||
if (size <= 1)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
char buffer[size];
|
||||
xkb_state_key_get_utf8(mXkbState, keyCode, buffer, size);
|
||||
|
||||
std::string ret(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void XcbKeyboard::getKeyMap()
|
||||
{
|
||||
auto device_id = xkb_x11_get_core_keyboard_device_id(mConnection);
|
||||
if (device_id == -1)
|
||||
{
|
||||
MLOG_ERROR("Failed to get connection for keymap");
|
||||
}
|
||||
|
||||
auto xkb_keymap = xkb_x11_keymap_new_from_device(mXkbContext, mConnection, device_id, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
|
||||
struct xkb_state* xkb_state = xkb_x11_state_new_from_device(xkb_keymap, mConnection, device_id);
|
||||
xkb_keymap_unref(mXkbKeymap);
|
||||
xkb_state_unref(mXkbState);
|
||||
mXkbKeymap = xkb_keymap;
|
||||
mXkbState = xkb_state;
|
||||
|
||||
xcb_xkb_select_events_details_t details;
|
||||
auto cookie = xcb_xkb_select_events(mConnection, XCB_XKB_ID_USE_CORE_KBD,
|
||||
XCB_XKB_EVENT_TYPE_STATE_NOTIFY, 0, XCB_XKB_EVENT_TYPE_STATE_NOTIFY, 0, 0, &details);
|
||||
|
||||
// Check errors
|
||||
auto error = xcb_request_check(mConnection, cookie);
|
||||
if (error)
|
||||
{
|
||||
MLOG_ERROR("Failed to select XKB events");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue