input: support xkb v2 format (#11482)

This commit is contained in:
usering-around 2025-09-11 20:42:20 +03:00 committed by GitHub
parent c7b9969129
commit 38169c8fdd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 62 additions and 28 deletions

View file

@ -43,14 +43,19 @@ void IKeyboard::clearManuallyAllocd() {
if (m_xkbKeymap)
xkb_keymap_unref(m_xkbKeymap);
if (m_xkbKeymapV1)
xkb_keymap_unref(m_xkbKeymapV1);
if (m_xkbSymState)
xkb_state_unref(m_xkbSymState);
m_xkbSymState = nullptr;
m_xkbKeymap = nullptr;
m_xkbKeymapV1 = nullptr;
m_xkbState = nullptr;
m_xkbStaticState = nullptr;
m_xkbKeymapFD.reset();
m_xkbKeymapV1FD.reset();
}
void IKeyboard::setKeymap(const SStringRuleNames& rules) {
@ -86,13 +91,13 @@ void IKeyboard::setKeymap(const SStringRuleNames& rules) {
if (FILE* const KEYMAPFILE = fopen(path.c_str(), "r"); !KEYMAPFILE)
Debug::log(ERR, "Cannot open input:kb_file= file for reading");
else {
m_xkbKeymap = xkb_keymap_new_from_file(CONTEXT, KEYMAPFILE, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
m_xkbKeymap = xkb_keymap_new_from_file(CONTEXT, KEYMAPFILE, XKB_KEYMAP_FORMAT_TEXT_V2, XKB_KEYMAP_COMPILE_NO_FLAGS);
fclose(KEYMAPFILE);
}
}
if (!m_xkbKeymap)
m_xkbKeymap = xkb_keymap_new_from_names(CONTEXT, &XKBRULES, XKB_KEYMAP_COMPILE_NO_FLAGS);
m_xkbKeymap = xkb_keymap_new_from_names2(CONTEXT, &XKBRULES, XKB_KEYMAP_FORMAT_TEXT_V2, XKB_KEYMAP_COMPILE_NO_FLAGS);
if (!m_xkbKeymap) {
g_pConfigManager->addParseError("Invalid keyboard layout passed. ( rules: " + rules.rules + ", model: " + rules.model + ", variant: " + rules.variant +
@ -108,7 +113,16 @@ void IKeyboard::setKeymap(const SStringRuleNames& rules) {
m_currentRules.options = "";
m_currentRules.layout = "us";
m_xkbKeymap = xkb_keymap_new_from_names(CONTEXT, &XKBRULES, XKB_KEYMAP_COMPILE_NO_FLAGS);
m_xkbKeymap = xkb_keymap_new_from_names2(CONTEXT, &XKBRULES, XKB_KEYMAP_FORMAT_TEXT_V2, XKB_KEYMAP_COMPILE_NO_FLAGS);
}
auto cKeymapStr = xkb_keymap_get_as_string(m_xkbKeymap, XKB_KEYMAP_FORMAT_TEXT_V1);
if (!cKeymapStr) {
Debug::log(ERR, "Couldn't convert keymap to V1 format");
m_xkbKeymapV1 = xkb_keymap_new_from_names2(CONTEXT, &XKBRULES, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
} else {
m_xkbKeymapV1 = xkb_keymap_new_from_string(CONTEXT, cKeymapStr, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
free(cKeymapStr);
}
updateXKBTranslationState(m_xkbKeymap);
@ -149,27 +163,44 @@ void IKeyboard::updateKeymapFD() {
if (m_xkbKeymapFD.isValid())
m_xkbKeymapFD.reset();
auto cKeymapStr = xkb_keymap_get_as_string(m_xkbKeymap, XKB_KEYMAP_FORMAT_TEXT_V1);
if (m_xkbKeymapV1FD.isValid())
m_xkbKeymapV1FD.reset();
auto cKeymapStr = xkb_keymap_get_as_string(m_xkbKeymap, XKB_KEYMAP_FORMAT_TEXT_V2);
m_xkbKeymapString = cKeymapStr;
free(cKeymapStr);
auto cKeymapV1Str = xkb_keymap_get_as_string(m_xkbKeymapV1, XKB_KEYMAP_FORMAT_TEXT_V1);
m_xkbKeymapV1String = cKeymapV1Str;
free(cKeymapV1Str);
CFileDescriptor rw, ro;
CFileDescriptor rw, ro, rwV1, roV1;
if (!allocateSHMFilePair(m_xkbKeymapString.length() + 1, rw, ro))
Debug::log(ERR, "IKeyboard: failed to allocate shm pair for the keymap");
else {
auto keymapFDDest = mmap(nullptr, m_xkbKeymapString.length() + 1, PROT_READ | PROT_WRITE, MAP_SHARED, rw.get(), 0);
else if (!allocateSHMFilePair(m_xkbKeymapV1String.length() + 1, rwV1, roV1)) {
ro.reset();
rw.reset();
if (keymapFDDest == MAP_FAILED) {
Debug::log(ERR, "IKeyboard: failed to allocate shm pair for keymap V1");
} else {
auto keymapFDDest = mmap(nullptr, m_xkbKeymapString.length() + 1, PROT_READ | PROT_WRITE, MAP_SHARED, rw.get(), 0);
auto keymapV1FDDest = mmap(nullptr, m_xkbKeymapV1String.length() + 1, PROT_READ | PROT_WRITE, MAP_SHARED, rwV1.get(), 0);
rw.reset();
rwV1.reset();
if (keymapFDDest == MAP_FAILED || keymapV1FDDest == MAP_FAILED) {
Debug::log(ERR, "IKeyboard: failed to mmap a shm pair for the keymap");
ro.reset();
roV1.reset();
} else {
memcpy(keymapFDDest, m_xkbKeymapString.c_str(), m_xkbKeymapString.length());
munmap(keymapFDDest, m_xkbKeymapString.length() + 1);
m_xkbKeymapFD = std::move(ro);
memcpy(keymapV1FDDest, m_xkbKeymapV1String.c_str(), m_xkbKeymapV1String.length());
munmap(keymapV1FDDest, m_xkbKeymapV1String.length() + 1);
m_xkbKeymapV1FD = std::move(roV1);
}
}
Debug::log(LOG, "Updated keymap fd to {}", m_xkbKeymapFD.get());
Debug::log(LOG, "Updated keymap fd to {}, keymap V1 to: {}", m_xkbKeymapFD.get(), m_xkbKeymapV1FD.get());
}
void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
@ -220,19 +251,19 @@ void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
rules.model = model.c_str();
rules.variant = variant.c_str();
auto KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
auto KEYMAP = xkb_keymap_new_from_names2(PCONTEXT, &rules, XKB_KEYMAP_FORMAT_TEXT_V2, XKB_KEYMAP_COMPILE_NO_FLAGS);
if (!KEYMAP) {
Debug::log(ERR, "updateXKBTranslationState: keymap failed 1, fallback without model/variant");
rules.model = "";
rules.variant = "";
KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
KEYMAP = xkb_keymap_new_from_names2(PCONTEXT, &rules, XKB_KEYMAP_FORMAT_TEXT_V2, XKB_KEYMAP_COMPILE_NO_FLAGS);
}
if (!KEYMAP) {
Debug::log(ERR, "updateXKBTranslationState: keymap failed 2, fallback to us");
rules.layout = "us";
KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
KEYMAP = xkb_keymap_new_from_names2(PCONTEXT, &rules, XKB_KEYMAP_FORMAT_TEXT_V2, XKB_KEYMAP_COMPILE_NO_FLAGS);
}
m_xkbState = xkb_state_new(KEYMAP);
@ -256,7 +287,7 @@ void IKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
.options = m_currentRules.options.c_str(),
};
const auto NEWKEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
const auto NEWKEYMAP = xkb_keymap_new_from_names2(PCONTEXT, &rules, XKB_KEYMAP_FORMAT_TEXT_V2, XKB_KEYMAP_COMPILE_NO_FLAGS);
m_xkbState = xkb_state_new(NEWKEYMAP);
m_xkbStaticState = xkb_state_new(NEWKEYMAP);