From 32aa6f116acc6e3e20a1ec76cef45b29f7005ad7 Mon Sep 17 00:00:00 2001 From: Yuqian Yang Date: Fri, 17 Oct 2025 12:06:14 +0800 Subject: Remove String stage 1. --- src/platform/gui/xcb/CMakeLists.txt | 2 +- src/platform/gui/xcb/Clipboard.cpp | 4 +- src/platform/gui/xcb/Cursor.cpp | 1 - src/platform/gui/xcb/Input.cpp | 279 ++++++++++++++++++++++++++++++++ src/platform/gui/xcb/InputMethod.cpp | 11 +- src/platform/gui/xcb/Keyboard.cpp | 280 --------------------------------- src/platform/gui/xcb/UiApplication.cpp | 3 +- src/platform/gui/xcb/Window.cpp | 15 +- 8 files changed, 293 insertions(+), 302 deletions(-) create mode 100644 src/platform/gui/xcb/Input.cpp delete mode 100644 src/platform/gui/xcb/Keyboard.cpp (limited to 'src/platform/gui/xcb') diff --git a/src/platform/gui/xcb/CMakeLists.txt b/src/platform/gui/xcb/CMakeLists.txt index cafc2e67..676fc7b1 100644 --- a/src/platform/gui/xcb/CMakeLists.txt +++ b/src/platform/gui/xcb/CMakeLists.txt @@ -6,8 +6,8 @@ find_library(LIBRARY_XKBCOMMON_X11 xkbcommon-x11 REQUIRED) add_library(CruPlatformGuiXcb Clipboard.cpp Cursor.cpp + Input.cpp InputMethod.cpp - Keyboard.cpp UiApplication.cpp Window.cpp ) diff --git a/src/platform/gui/xcb/Clipboard.cpp b/src/platform/gui/xcb/Clipboard.cpp index d0d9d74f..a42130ab 100644 --- a/src/platform/gui/xcb/Clipboard.cpp +++ b/src/platform/gui/xcb/Clipboard.cpp @@ -7,7 +7,7 @@ XcbClipboard::XcbClipboard(XcbUiApplication* application) XcbClipboard::~XcbClipboard() {} -String XcbClipboard::GetText() { return String{}; } +std::string XcbClipboard::GetText() { return {}; } -void XcbClipboard::SetText(String text) {} +void XcbClipboard::SetText(std::string text) {} } // namespace cru::platform::gui::xcb diff --git a/src/platform/gui/xcb/Cursor.cpp b/src/platform/gui/xcb/Cursor.cpp index 5582c6a6..69d904df 100644 --- a/src/platform/gui/xcb/Cursor.cpp +++ b/src/platform/gui/xcb/Cursor.cpp @@ -1,6 +1,5 @@ #include "cru/platform/gui/xcb/Cursor.h" #include "cru/base/Exception.h" -#include "cru/platform/gui/Cursor.h" #include "cru/platform/gui/xcb/UiApplication.h" #include diff --git a/src/platform/gui/xcb/Input.cpp b/src/platform/gui/xcb/Input.cpp new file mode 100644 index 00000000..9b6d76c2 --- /dev/null +++ b/src/platform/gui/xcb/Input.cpp @@ -0,0 +1,279 @@ +#include "cru/platform/gui/xcb/Input.h" +#include "cru/base/Exception.h" +#include "cru/base/Guard.h" +#include "cru/platform/gui/xcb/UiApplication.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace cru::platform::gui::xcb { +// Refer to +// https://www.x.org/releases/X11R7.7/doc/xproto/x11protocol.html#keysym_encoding +KeyCode XorgKeysymToCruKeyCode(xcb_keysym_t keysym) { + if (keysym >= 'A' && keysym <= 'Z') { + return KeyCode(static_cast(KeyCode::A) + (keysym - 'A')); + } + + if (keysym >= 'a' && keysym <= 'z') { + return KeyCode(static_cast(KeyCode::A) + (keysym - 'a')); + } + + if (keysym >= '0' && keysym <= '9') { + return KeyCode(static_cast(KeyCode::N0) + (keysym - '0')); + } + + if (keysym >= 0xFFB0 && keysym <= 0xFFB9) { + return KeyCode(static_cast(KeyCode::NumPad0) + (keysym - 0xFFB0)); + } + + if (keysym >= 0xFFBE && keysym <= 0xFFC9) { + return KeyCode(static_cast(KeyCode::F1) + (keysym - 0xFFBE)); + } + + switch (keysym) { +#define CRU_DEFINE_KEYCODE_MAP(keysym, cru) \ + case keysym: \ + return cru; + + CRU_DEFINE_KEYCODE_MAP(',', KeyCode::Comma) + CRU_DEFINE_KEYCODE_MAP('.', KeyCode::Period) + CRU_DEFINE_KEYCODE_MAP('/', KeyCode::Slash) + CRU_DEFINE_KEYCODE_MAP(';', KeyCode::Semicolon) + CRU_DEFINE_KEYCODE_MAP('\'', KeyCode::Quote) + CRU_DEFINE_KEYCODE_MAP('{', KeyCode::LeftSquareBracket) + CRU_DEFINE_KEYCODE_MAP('}', KeyCode::RightSquareBracket) + CRU_DEFINE_KEYCODE_MAP('-', KeyCode::Minus) + CRU_DEFINE_KEYCODE_MAP('=', KeyCode::Equal) + CRU_DEFINE_KEYCODE_MAP('\\', KeyCode::BackSlash) + CRU_DEFINE_KEYCODE_MAP(0xFF1B, KeyCode::Escape) + CRU_DEFINE_KEYCODE_MAP(0xFF09, KeyCode::Tab) + CRU_DEFINE_KEYCODE_MAP(0xFFE5, KeyCode::CapsLock) + CRU_DEFINE_KEYCODE_MAP(0xFFE1, KeyCode::LeftShift) + CRU_DEFINE_KEYCODE_MAP(0xFFE2, KeyCode::RightShift) + CRU_DEFINE_KEYCODE_MAP(0xFFE3, KeyCode::LeftCtrl) + CRU_DEFINE_KEYCODE_MAP(0xFFE4, KeyCode::RightCtrl) + CRU_DEFINE_KEYCODE_MAP(0xFFE9, KeyCode::LeftAlt) + CRU_DEFINE_KEYCODE_MAP(0xFFEA, KeyCode::RightAlt) + CRU_DEFINE_KEYCODE_MAP(0xFF08, KeyCode::Backspace) + CRU_DEFINE_KEYCODE_MAP(0xFF0D, KeyCode::Return) + CRU_DEFINE_KEYCODE_MAP(0xFFFF, KeyCode::Delete) + CRU_DEFINE_KEYCODE_MAP(0xFF50, KeyCode::Home) + CRU_DEFINE_KEYCODE_MAP(0xFF57, KeyCode::End) + CRU_DEFINE_KEYCODE_MAP(0xFF55, KeyCode::PageUp) + CRU_DEFINE_KEYCODE_MAP(0xFF56, KeyCode::PageDown) + CRU_DEFINE_KEYCODE_MAP(0xFF51, KeyCode::Left) + CRU_DEFINE_KEYCODE_MAP(0xFF53, KeyCode::Right) + CRU_DEFINE_KEYCODE_MAP(0xFF52, KeyCode::Up) + CRU_DEFINE_KEYCODE_MAP(0xFF54, KeyCode::Down) + CRU_DEFINE_KEYCODE_MAP(' ', KeyCode::Space) + default: + return KeyCode::Unknown; + } +} + +std::vector XorgKeycodeToKeysyms(XcbUiApplication *application, + xcb_keycode_t keycode) { + auto connection = application->GetXcbConnection(); + auto setup = xcb_get_setup(connection); + auto min_keycode = setup->min_keycode; + auto max_keycode = setup->max_keycode; + + // Get keyboard mapping + auto mapping_cookie = xcb_get_keyboard_mapping(connection, keycode, 1); + auto mapping_reply = FreeLater( + xcb_get_keyboard_mapping_reply(connection, mapping_cookie, NULL)); + + if (!mapping_reply) { + throw XcbException("Cannot get keyboard mapping."); + } + + auto keysyms_per_keycode = mapping_reply->keysyms_per_keycode; + auto *keysyms = xcb_get_keyboard_mapping_keysyms(mapping_reply); + + std::vector result; + for (int i = 0; i < keysyms_per_keycode; i++) { + result.push_back(keysyms[i]); + } + return result; +} + +KeyCode XorgKeycodeToCruKeyCode(XcbUiApplication *application, + xcb_keycode_t keycode) { + auto keysyms = XorgKeycodeToKeysyms(application, keycode); + + for (auto keysym : keysyms) { + auto result = XorgKeysymToCruKeyCode(keysym); + if (result != KeyCode::Unknown) return result; + } + + return KeyCode::Unknown; +} + +namespace { +using KeymapBitset = + std::bitset().keys) * + CHAR_BIT>; + +KeymapBitset GetXorgKeymap(xcb_connection_t *connection) { + auto keymap_cookie = xcb_query_keymap(connection); + auto keymap_reply = + FreeLater(xcb_query_keymap_reply(connection, keymap_cookie, NULL)); + + if (!keymap_reply) { + throw XcbException("Cannot get keymap."); + } + + KeymapBitset result; + int counter = 0; + for (auto member : keymap_reply->keys) { + for (int i = 0; i < sizeof(member); i++) { + result[counter] = member & (1 << i); + counter++; + } + } + + return result; +} +} // namespace + +std::unordered_map GetKeyboardState( + XcbUiApplication *application) { + auto connection = application->GetXcbConnection(); + auto setup = xcb_get_setup(connection); + auto min_keycode = setup->min_keycode; + auto max_keycode = setup->max_keycode; + + // Get keyboard mapping + auto mapping_cookie = xcb_get_keyboard_mapping(connection, min_keycode, + max_keycode - min_keycode + 1); + auto mapping_reply = FreeLater( + xcb_get_keyboard_mapping_reply(connection, mapping_cookie, NULL)); + + if (!mapping_reply) { + throw XcbException("Cannot get keyboard mapping."); + } + + auto keysyms_per_keycode = mapping_reply->keysyms_per_keycode; + auto *keysyms = xcb_get_keyboard_mapping_keysyms(mapping_reply); + + auto keymap = GetXorgKeymap(connection); + + std::unordered_map result; + + for (xcb_keycode_t i = min_keycode; i <= max_keycode; i++) { + auto keysyms_for_this = keysyms + (i - min_keycode) * keysyms_per_keycode; + for (int j = 0; j < keysyms_per_keycode; j++) { + auto keycode = XorgKeysymToCruKeyCode(keysyms_for_this[j]); + if (keycode != KeyCode::Unknown) { + result[keycode] = keymap[i]; + } + } + } + + return result; +} + +// Though X provides GetModifierMapping, it cannot get ALT state. +KeyModifier GetCurrentKeyModifiers(XcbUiApplication *application) { + KeyModifier result{}; + auto state = GetKeyboardState(application); + if (state[KeyCode::LeftShift] || state[KeyCode::RightShift]) { + result |= KeyModifiers::Shift; + } + if (state[KeyCode::LeftCtrl] || state[KeyCode::RightCtrl]) { + result |= KeyModifiers::Ctrl; + } + if (state[KeyCode::LeftAlt] || state[KeyCode::RightAlt]) { + result |= KeyModifiers::Alt; + } + return result; +} + +KeyModifier ConvertModifiersOfEvent(uint32_t mask) { + // const char *MODIFIERS[] = { + // "Shift", "Lock", "Ctrl", "Alt", "Mod2", "Mod3", "Mod4", + // "Mod5", "Button1", "Button2", "Button3", "Button4", "Button5"}; + constexpr KeyModifier MODIFIERS[] = { + KeyModifiers::Shift, KeyModifiers::None, KeyModifiers::Ctrl, + KeyModifiers::Alt, KeyModifiers::None, KeyModifiers::None, + KeyModifiers::None, KeyModifiers::None, KeyModifiers::None, + KeyModifiers::None, KeyModifiers::None, KeyModifiers::None, + KeyModifiers::None, + }; + + KeyModifier result; + for (auto iter = std::begin(MODIFIERS); mask; mask >>= 1, ++iter) { + if (mask & 1) { + result |= *iter; + } + } + return result; +} + +XcbKeyboardManager::XcbKeyboardManager(XcbUiApplication *application) + : application_(application) { + xkb_x11_setup_xkb_extension( + application->GetXcbConnection(), XKB_X11_MIN_MAJOR_XKB_VERSION, + XKB_X11_MIN_MINOR_XKB_VERSION, XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS, + nullptr, nullptr, nullptr, nullptr); + + xkb_context_ = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + if (!xkb_context_) { + throw PlatformException("Failed to call xkb_context_new."); + } + + auto device_id = + xkb_x11_get_core_keyboard_device_id(application->GetXcbConnection()); + if (device_id == -1) { + throw PlatformException( + "Failed to call xkb_x11_get_core_keyboard_device_id."); + } + + xkb_keymap_ = xkb_x11_keymap_new_from_device( + xkb_context_, application->GetXcbConnection(), device_id, + XKB_KEYMAP_COMPILE_NO_FLAGS); + if (!xkb_keymap_) { + throw PlatformException("Failed to call xkb_x11_keymap_new_from_device."); + } + + xkb_state_ = xkb_x11_state_new_from_device( + xkb_keymap_, application->GetXcbConnection(), device_id); + if (!xkb_state_) { + throw PlatformException("Failed to call xkb_x11_state_new_from_device."); + } +} + +XcbKeyboardManager::~XcbKeyboardManager() { + xkb_state_unref(xkb_state_); + xkb_keymap_unref(xkb_keymap_); + xkb_context_unref(xkb_context_); +} + +std::string XcbKeyboardManager::KeycodeToUtf8(xcb_keycode_t keycode) { + auto size = xkb_state_key_get_utf8(xkb_state_, keycode, NULL, 0); + if (size <= 0) { + return {}; + } + std::string buffer(size + 1, 0); + xkb_state_key_get_utf8(xkb_state_, keycode, buffer.data(), size + 1); + buffer.resize(size); + return buffer; +} + +std::string XcbKeyboardManager::KeysymToUtf8(xcb_keysym_t keysym) { + auto size = xkb_keysym_to_utf8(keysym, NULL, 0); + if (size <= 0) { + return {}; + } + std::string buffer(size + 1, 0); + xkb_keysym_to_utf8(keysym, buffer.data(), size + 1); + buffer.resize(size); + return buffer; +} + +} // namespace cru::platform::gui::xcb diff --git a/src/platform/gui/xcb/InputMethod.cpp b/src/platform/gui/xcb/InputMethod.cpp index 16d6b4bd..5ee06ab4 100644 --- a/src/platform/gui/xcb/InputMethod.cpp +++ b/src/platform/gui/xcb/InputMethod.cpp @@ -1,10 +1,7 @@ #include "cru/platform/gui/xcb/InputMethod.h" #include "cru/base/log/Logger.h" #include "cru/platform/Check.h" -#include "cru/platform/gui/InputMethod.h" -#include "cru/platform/gui/Keyboard.h" -#include "cru/platform/gui/Window.h" -#include "cru/platform/gui/xcb/Keyboard.h" +#include "cru/platform/gui/xcb/Input.h" #include "cru/platform/gui/xcb/UiApplication.h" #include "cru/platform/gui/xcb/Window.h" @@ -99,7 +96,7 @@ void XcbXimInputMethodManager::DispatchCommit(xcb_xim_t *im, xcb_xic_t ic, if (focus_context_) { focus_context_->composition_event_.Raise(nullptr); focus_context_->composition_end_event_.Raise(nullptr); - focus_context_->text_event_.Raise(String::FromUtf8(text)); + focus_context_->text_event_.Raise(std::move(text)); } } @@ -135,7 +132,7 @@ XcbXimInputMethodContext::XcbXimInputMethodContext( window->FocusEvent()->AddHandler([this, window](FocusChangeType type) { auto context = CheckPlatform( - window->GetInputMethodContext(), GetPlatformIdUtf8()); + window->GetInputMethodContext(), GetPlatformId()); if (type == FocusChangeType::Gain) { SetFocus(); } @@ -208,7 +205,7 @@ IEvent *XcbXimInputMethodContext::CompositionEvent() { return &composition_event_; } -IEvent *XcbXimInputMethodContext::TextEvent() { +IEvent *XcbXimInputMethodContext::TextEvent() { return &text_event_; } diff --git a/src/platform/gui/xcb/Keyboard.cpp b/src/platform/gui/xcb/Keyboard.cpp deleted file mode 100644 index 4bfc448c..00000000 --- a/src/platform/gui/xcb/Keyboard.cpp +++ /dev/null @@ -1,280 +0,0 @@ -#include "cru/platform/gui/xcb/Keyboard.h" -#include "cru/base/Exception.h" -#include "cru/base/Guard.h" -#include "cru/platform/gui/Keyboard.h" -#include "cru/platform/gui/xcb/UiApplication.h" - -#include -#include -#include -#include -#include -#include -#include - -namespace cru::platform::gui::xcb { -// Refer to -// https://www.x.org/releases/X11R7.7/doc/xproto/x11protocol.html#keysym_encoding -KeyCode XorgKeysymToCruKeyCode(xcb_keysym_t keysym) { - if (keysym >= 'A' && keysym <= 'Z') { - return KeyCode(static_cast(KeyCode::A) + (keysym - 'A')); - } - - if (keysym >= 'a' && keysym <= 'z') { - return KeyCode(static_cast(KeyCode::A) + (keysym - 'a')); - } - - if (keysym >= '0' && keysym <= '9') { - return KeyCode(static_cast(KeyCode::N0) + (keysym - '0')); - } - - if (keysym >= 0xFFB0 && keysym <= 0xFFB9) { - return KeyCode(static_cast(KeyCode::NumPad0) + (keysym - 0xFFB0)); - } - - if (keysym >= 0xFFBE && keysym <= 0xFFC9) { - return KeyCode(static_cast(KeyCode::F1) + (keysym - 0xFFBE)); - } - - switch (keysym) { -#define CRU_DEFINE_KEYCODE_MAP(keysym, cru) \ - case keysym: \ - return cru; - - CRU_DEFINE_KEYCODE_MAP(',', KeyCode::Comma) - CRU_DEFINE_KEYCODE_MAP('.', KeyCode::Period) - CRU_DEFINE_KEYCODE_MAP('/', KeyCode::Slash) - CRU_DEFINE_KEYCODE_MAP(';', KeyCode::Semicolon) - CRU_DEFINE_KEYCODE_MAP('\'', KeyCode::Quote) - CRU_DEFINE_KEYCODE_MAP('{', KeyCode::LeftSquareBracket) - CRU_DEFINE_KEYCODE_MAP('}', KeyCode::RightSquareBracket) - CRU_DEFINE_KEYCODE_MAP('-', KeyCode::Minus) - CRU_DEFINE_KEYCODE_MAP('=', KeyCode::Equal) - CRU_DEFINE_KEYCODE_MAP('\\', KeyCode::BackSlash) - CRU_DEFINE_KEYCODE_MAP(0xFF1B, KeyCode::Escape) - CRU_DEFINE_KEYCODE_MAP(0xFF09, KeyCode::Tab) - CRU_DEFINE_KEYCODE_MAP(0xFFE5, KeyCode::CapsLock) - CRU_DEFINE_KEYCODE_MAP(0xFFE1, KeyCode::LeftShift) - CRU_DEFINE_KEYCODE_MAP(0xFFE2, KeyCode::RightShift) - CRU_DEFINE_KEYCODE_MAP(0xFFE3, KeyCode::LeftCtrl) - CRU_DEFINE_KEYCODE_MAP(0xFFE4, KeyCode::RightCtrl) - CRU_DEFINE_KEYCODE_MAP(0xFFE9, KeyCode::LeftAlt) - CRU_DEFINE_KEYCODE_MAP(0xFFEA, KeyCode::RightAlt) - CRU_DEFINE_KEYCODE_MAP(0xFF08, KeyCode::Backspace) - CRU_DEFINE_KEYCODE_MAP(0xFF0D, KeyCode::Return) - CRU_DEFINE_KEYCODE_MAP(0xFFFF, KeyCode::Delete) - CRU_DEFINE_KEYCODE_MAP(0xFF50, KeyCode::Home) - CRU_DEFINE_KEYCODE_MAP(0xFF57, KeyCode::End) - CRU_DEFINE_KEYCODE_MAP(0xFF55, KeyCode::PageUp) - CRU_DEFINE_KEYCODE_MAP(0xFF56, KeyCode::PageDown) - CRU_DEFINE_KEYCODE_MAP(0xFF51, KeyCode::Left) - CRU_DEFINE_KEYCODE_MAP(0xFF53, KeyCode::Right) - CRU_DEFINE_KEYCODE_MAP(0xFF52, KeyCode::Up) - CRU_DEFINE_KEYCODE_MAP(0xFF54, KeyCode::Down) - CRU_DEFINE_KEYCODE_MAP(' ', KeyCode::Space) - default: - return KeyCode::Unknown; - } -} - -std::vector XorgKeycodeToKeysyms(XcbUiApplication *application, - xcb_keycode_t keycode) { - auto connection = application->GetXcbConnection(); - auto setup = xcb_get_setup(connection); - auto min_keycode = setup->min_keycode; - auto max_keycode = setup->max_keycode; - - // Get keyboard mapping - auto mapping_cookie = xcb_get_keyboard_mapping(connection, keycode, 1); - auto mapping_reply = FreeLater( - xcb_get_keyboard_mapping_reply(connection, mapping_cookie, NULL)); - - if (!mapping_reply) { - throw XcbException("Cannot get keyboard mapping."); - } - - auto keysyms_per_keycode = mapping_reply->keysyms_per_keycode; - auto *keysyms = xcb_get_keyboard_mapping_keysyms(mapping_reply); - - std::vector result; - for (int i = 0; i < keysyms_per_keycode; i++) { - result.push_back(keysyms[i]); - } - return result; -} - -KeyCode XorgKeycodeToCruKeyCode(XcbUiApplication *application, - xcb_keycode_t keycode) { - auto keysyms = XorgKeycodeToKeysyms(application, keycode); - - for (auto keysym : keysyms) { - auto result = XorgKeysymToCruKeyCode(keysym); - if (result != KeyCode::Unknown) return result; - } - - return KeyCode::Unknown; -} - -namespace { -using KeymapBitset = - std::bitset().keys) * - CHAR_BIT>; - -KeymapBitset GetXorgKeymap(xcb_connection_t *connection) { - auto keymap_cookie = xcb_query_keymap(connection); - auto keymap_reply = - FreeLater(xcb_query_keymap_reply(connection, keymap_cookie, NULL)); - - if (!keymap_reply) { - throw XcbException("Cannot get keymap."); - } - - KeymapBitset result; - int counter = 0; - for (auto member : keymap_reply->keys) { - for (int i = 0; i < sizeof(member); i++) { - result[counter] = member & (1 << i); - counter++; - } - } - - return result; -} -} // namespace - -std::unordered_map GetKeyboardState( - XcbUiApplication *application) { - auto connection = application->GetXcbConnection(); - auto setup = xcb_get_setup(connection); - auto min_keycode = setup->min_keycode; - auto max_keycode = setup->max_keycode; - - // Get keyboard mapping - auto mapping_cookie = xcb_get_keyboard_mapping(connection, min_keycode, - max_keycode - min_keycode + 1); - auto mapping_reply = FreeLater( - xcb_get_keyboard_mapping_reply(connection, mapping_cookie, NULL)); - - if (!mapping_reply) { - throw XcbException("Cannot get keyboard mapping."); - } - - auto keysyms_per_keycode = mapping_reply->keysyms_per_keycode; - auto *keysyms = xcb_get_keyboard_mapping_keysyms(mapping_reply); - - auto keymap = GetXorgKeymap(connection); - - std::unordered_map result; - - for (xcb_keycode_t i = min_keycode; i <= max_keycode; i++) { - auto keysyms_for_this = keysyms + (i - min_keycode) * keysyms_per_keycode; - for (int j = 0; j < keysyms_per_keycode; j++) { - auto keycode = XorgKeysymToCruKeyCode(keysyms_for_this[j]); - if (keycode != KeyCode::Unknown) { - result[keycode] = keymap[i]; - } - } - } - - return result; -} - -// Though X provides GetModifierMapping, it cannot get ALT state. -KeyModifier GetCurrentKeyModifiers(XcbUiApplication *application) { - KeyModifier result{}; - auto state = GetKeyboardState(application); - if (state[KeyCode::LeftShift] || state[KeyCode::RightShift]) { - result |= KeyModifiers::Shift; - } - if (state[KeyCode::LeftCtrl] || state[KeyCode::RightCtrl]) { - result |= KeyModifiers::Ctrl; - } - if (state[KeyCode::LeftAlt] || state[KeyCode::RightAlt]) { - result |= KeyModifiers::Alt; - } - return result; -} - -KeyModifier ConvertModifiersOfEvent(uint32_t mask) { - // const char *MODIFIERS[] = { - // "Shift", "Lock", "Ctrl", "Alt", "Mod2", "Mod3", "Mod4", - // "Mod5", "Button1", "Button2", "Button3", "Button4", "Button5"}; - constexpr KeyModifier MODIFIERS[] = { - KeyModifiers::Shift, KeyModifiers::none, KeyModifiers::Ctrl, - KeyModifiers::Alt, KeyModifiers::none, KeyModifiers::none, - KeyModifiers::none, KeyModifiers::none, KeyModifiers::none, - KeyModifiers::none, KeyModifiers::none, KeyModifiers::none, - KeyModifiers::none, - }; - - KeyModifier result; - for (auto iter = std::begin(MODIFIERS); mask; mask >>= 1, ++iter) { - if (mask & 1) { - result |= *iter; - } - } - return result; -} - -XcbKeyboardManager::XcbKeyboardManager(XcbUiApplication *application) - : application_(application) { - xkb_x11_setup_xkb_extension( - application->GetXcbConnection(), XKB_X11_MIN_MAJOR_XKB_VERSION, - XKB_X11_MIN_MINOR_XKB_VERSION, XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS, - nullptr, nullptr, nullptr, nullptr); - - xkb_context_ = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - if (!xkb_context_) { - throw PlatformException("Failed to call xkb_context_new."); - } - - auto device_id = - xkb_x11_get_core_keyboard_device_id(application->GetXcbConnection()); - if (device_id == -1) { - throw PlatformException( - "Failed to call xkb_x11_get_core_keyboard_device_id."); - } - - xkb_keymap_ = xkb_x11_keymap_new_from_device( - xkb_context_, application->GetXcbConnection(), device_id, - XKB_KEYMAP_COMPILE_NO_FLAGS); - if (!xkb_keymap_) { - throw PlatformException("Failed to call xkb_x11_keymap_new_from_device."); - } - - xkb_state_ = xkb_x11_state_new_from_device( - xkb_keymap_, application->GetXcbConnection(), device_id); - if (!xkb_state_) { - throw PlatformException("Failed to call xkb_x11_state_new_from_device."); - } -} - -XcbKeyboardManager::~XcbKeyboardManager() { - xkb_state_unref(xkb_state_); - xkb_keymap_unref(xkb_keymap_); - xkb_context_unref(xkb_context_); -} - -std::string XcbKeyboardManager::KeycodeToUtf8(xcb_keycode_t keycode) { - auto size = xkb_state_key_get_utf8(xkb_state_, keycode, NULL, 0); - if (size <= 0) { - return {}; - } - std::string buffer(size + 1, 0); - xkb_state_key_get_utf8(xkb_state_, keycode, buffer.data(), size + 1); - buffer.resize(size); - return buffer; -} - -std::string XcbKeyboardManager::KeysymToUtf8(xcb_keysym_t keysym) { - auto size = xkb_keysym_to_utf8(keysym, NULL, 0); - if (size <= 0) { - return {}; - } - std::string buffer(size + 1, 0); - xkb_keysym_to_utf8(keysym, buffer.data(), size + 1); - buffer.resize(size); - return buffer; -} - -} // namespace cru::platform::gui::xcb diff --git a/src/platform/gui/xcb/UiApplication.cpp b/src/platform/gui/xcb/UiApplication.cpp index a0a949b7..436bb335 100644 --- a/src/platform/gui/xcb/UiApplication.cpp +++ b/src/platform/gui/xcb/UiApplication.cpp @@ -1,13 +1,12 @@ #include "cru/platform/gui/xcb/UiApplication.h" -#include "cru/base/Base.h" #include "cru/base/Guard.h" #include "cru/platform/graphics/cairo/CairoGraphicsFactory.h" #include "cru/platform/gui/Window.h" #include "cru/platform/gui/xcb/Clipboard.h" #include "cru/platform/gui/xcb/Cursor.h" +#include "cru/platform/gui/xcb/Input.h" #include "cru/platform/gui/xcb/InputMethod.h" -#include "cru/platform/gui/xcb/Keyboard.h" #include "cru/platform/gui/xcb/Window.h" #include diff --git a/src/platform/gui/xcb/Window.cpp b/src/platform/gui/xcb/Window.cpp index 6458046b..003afc40 100644 --- a/src/platform/gui/xcb/Window.cpp +++ b/src/platform/gui/xcb/Window.cpp @@ -7,12 +7,9 @@ #include "cru/platform/graphics/NullPainter.h" #include "cru/platform/graphics/Painter.h" #include "cru/platform/graphics/cairo/CairoPainter.h" -#include "cru/platform/gui/Base.h" -#include "cru/platform/gui/Keyboard.h" -#include "cru/platform/gui/Window.h" #include "cru/platform/gui/xcb/Cursor.h" +#include "cru/platform/gui/xcb/Input.h" #include "cru/platform/gui/xcb/InputMethod.h" -#include "cru/platform/gui/xcb/Keyboard.h" #include "cru/platform/gui/xcb/UiApplication.h" #include @@ -73,7 +70,7 @@ void XcbWindow::Close() { INativeWindow *XcbWindow::GetParent() { return parent_; } void XcbWindow::SetParent(INativeWindow *parent) { - parent_ = CheckPlatform(parent, GetPlatformIdUtf8()); + parent_ = CheckPlatform(parent, GetPlatformId()); if (xcb_window_) { DoSetParent(*xcb_window_); } @@ -90,10 +87,10 @@ void XcbWindow::SetStyleFlag(WindowStyleFlag flag) { application_->XcbFlush(); } -String XcbWindow::GetTitle() { return String::FromUtf8(title_); } +std::string XcbWindow::GetTitle() { return title_; } -void XcbWindow::SetTitle(String title) { - title_ = title.ToUtf8(); +void XcbWindow::SetTitle(std::string title) { + title_ = std::move(title); if (xcb_window_) { DoSetTitle(*xcb_window_); } @@ -271,7 +268,7 @@ bool XcbWindow::ReleaseMouse() { void XcbWindow::SetCursor(std::shared_ptr cursor) { if (!xcb_window_) return; - auto xcb_cursor = CheckPlatform(cursor, GetPlatformIdUtf8()); + auto xcb_cursor = CheckPlatform(cursor, GetPlatformId()); cursor_ = xcb_cursor; DoSetCursor(*xcb_window_, xcb_cursor.get()); } -- cgit v1.2.3