diff --git a/xbanan/Base.cpp b/xbanan/Base.cpp index bbe1810..5105bce 100644 --- a/xbanan/Base.cpp +++ b/xbanan/Base.cpp @@ -8,8 +8,6 @@ #include "SafeGetters.h" #include "Utils.h" -#include - #include #include @@ -2899,8 +2897,19 @@ BAN::ErrorOr handle_packet(Client& client_info, BAN::ConstByteSpan packet) dprintln(" firstKeyCode: {}", request.firstKeyCode); dprintln(" count: {}", request.count); - ASSERT(g_keymap_min_keycode <= request.firstKeyCode); - ASSERT(g_keymap_max_keycode >= request.firstKeyCode + request.count - 1); + if (request.firstKeyCode < g_keymap_min_keycode || request.firstKeyCode + request.count - 1 > g_keymap_max_keycode) + { + xError error { + .type = X_Error, + .errorCode = BadValue, + .sequenceNumber = client_info.sequence, + .resourceID = 0, // TODO: should this be something meaningful? + .minorCode = 0, + .majorCode = opcode, + }; + TRY(encode(client_info.output_buffer, error)); + break; + } xGetKeyboardMappingReply reply { .type = X_Reply, @@ -2909,10 +2918,10 @@ BAN::ErrorOr handle_packet(Client& client_info, BAN::ConstByteSpan packet) .length = static_cast(request.count * g_keymap_layers), }; TRY(encode(client_info.output_buffer, reply)); - - for (size_t i = 0; i < request.count; i++) - for (size_t j = 0; j < g_keymap_layers; j++) - TRY(encode(client_info.output_buffer, g_keymap[request.firstKeyCode + i][j])); + TRY(encode(client_info.output_buffer, BAN::Span( + g_keymap + request.firstKeyCode - g_keymap_min_keycode, + request.count + ))); break; } @@ -2953,36 +2962,12 @@ BAN::ErrorOr handle_packet(Client& client_info, BAN::ConstByteSpan packet) xGetModifierMappingReply reply { .type = X_Reply, - .numKeyPerModifier = 2, + .numKeyPerModifier = g_modifier_layers, .sequenceNumber = client_info.sequence, - .length = 4, + .length = 2 * g_modifier_layers, }; TRY(encode(client_info.output_buffer, reply)); - - using LibInput::keycode_normal; - - // shift - TRY(encode(client_info.output_buffer, keycode_normal(3, 0))); // lshift - TRY(encode(client_info.output_buffer, keycode_normal(3, 12))); // rshift - - // lock - TRY(encode(client_info.output_buffer, keycode_normal(2, 0))); // caps lock - TRY(encode(client_info.output_buffer, static_cast(0))); - - // control - TRY(encode(client_info.output_buffer, keycode_normal(4, 0))); // lcrtl - TRY(encode(client_info.output_buffer, keycode_normal(4, 6))); // rctrl - - // mod1 - TRY(encode(client_info.output_buffer, keycode_normal(4, 2))); // lalt - TRY(encode(client_info.output_buffer, keycode_normal(4, 5))); // ralt - - // mod2 -> mod5 - for (size_t i = 2; i <= 5; i++) - { - TRY(encode(client_info.output_buffer, static_cast(0))); - TRY(encode(client_info.output_buffer, static_cast(0))); - } + TRY(encode(client_info.output_buffer, g_modifier_map)); break; } diff --git a/xbanan/CMakeLists.txt b/xbanan/CMakeLists.txt index a5efc52..2032618 100644 --- a/xbanan/CMakeLists.txt +++ b/xbanan/CMakeLists.txt @@ -38,10 +38,10 @@ endif() add_executable(xbanan ${XBANAN_SOURCES}) banan_link_library(xbanan ban) banan_link_library(xbanan libdeflate) -banan_link_library(xbanan libinput) if(PLATFORM STREQUAL "banan-os") banan_link_library(xbanan libgui) + banan_link_library(xbanan libinput) elseif(PLATFORM STREQUAL "SDL3") find_package(SDL3 REQUIRED) banan_link_library(xbanan SDL3::SDL3) diff --git a/xbanan/Events.cpp b/xbanan/Events.cpp index 4dad86d..48442a7 100644 --- a/xbanan/Events.cpp +++ b/xbanan/Events.cpp @@ -553,19 +553,16 @@ void on_mouse_button_event(WINDOW wid, uint8_t xbutton, bool pressed) void on_key_event(WINDOW wid, uint8_t scancode, uint8_t xmod, bool pressed) { const uint8_t xkeycode = scancode + g_keymap_min_keycode; - if (xkeycode < g_keymap_min_keycode) - { - dwarnln("cannot send keycode {}", xkeycode); + if (xkeycode < g_keymap_min_keycode || xkeycode > g_keymap_max_keycode) return; - } { - const uint8_t byte = xkeycode / 8; - const uint8_t bit = xkeycode % 8; + const uint8_t byte = xkeycode / 8; + const uint8_t mask = 1 << (xkeycode % 8); if (pressed) - g_pressed_keys[byte] |= 1 << bit; + g_pressed_keys[byte] |= mask; else - g_pressed_keys[byte] &= ~(1 << bit); + g_pressed_keys[byte] &= ~mask; } const auto old_state = g_keymask | g_butmask; @@ -580,3 +577,26 @@ void on_key_event(WINDOW wid, uint8_t scancode, uint8_t xmod, bool pressed) old_state ); } + +void on_keymap_changed() +{ + for (auto& [id, object] : g_objects) + { + if (object->type != Object::Type::Window) + continue; + + auto& client_info = object->object.get().owner; + + xEvent event {}; + event.u.u.type = MappingNotify; + event.u.u.sequenceNumber = client_info.sequence; + + event.u.mappingNotify.request = MappingKeyboard, + event.u.mappingNotify.firstKeyCode = g_keymap_min_keycode, + event.u.mappingNotify.count = g_keymap_size, + MUST(encode(client_info.output_buffer, event)); + + event.u.mappingNotify.request = MappingModifier; + MUST(encode(client_info.output_buffer, event)); + } +} diff --git a/xbanan/Events.h b/xbanan/Events.h index 62c3f66..fd9b8c7 100644 --- a/xbanan/Events.h +++ b/xbanan/Events.h @@ -15,3 +15,5 @@ void on_window_leave_event(WINDOW wid); void on_mouse_move_event(WINDOW wid, int32_t x, int32_t y); void on_mouse_button_event(WINDOW wid, uint8_t xbutton, bool pressed); void on_key_event(WINDOW wid, uint8_t scancode, uint8_t xmod, bool pressed); + +void on_keymap_changed(); diff --git a/xbanan/Keymap.cpp b/xbanan/Keymap.cpp index 82e607f..204aadb 100644 --- a/xbanan/Keymap.cpp +++ b/xbanan/Keymap.cpp @@ -1,349 +1,5 @@ #include "Keymap.h" -#include - -#include - -#include -#include -#include - -#include - -#undef None - -uint32_t g_keymap[0x100][g_keymap_layers]; - +uint32_t g_keymap[g_keymap_size][g_keymap_layers] {}; +uint8_t g_modifier_map[8][2] {}; uint8_t g_pressed_keys[32] {}; - -static constexpr uint32_t my_key_to_x_keysym(LibInput::Key key) -{ - using LibInput::Key; - - switch (key) - { - case Key::A: - return XK_A; - case Key::B: - return XK_B; - case Key::C: - return XK_C; - case Key::D: - return XK_D; - case Key::E: - return XK_E; - case Key::F: - return XK_F; - case Key::G: - return XK_G; - case Key::H: - return XK_H; - case Key::I: - return XK_I; - case Key::J: - return XK_J; - case Key::K: - return XK_K; - case Key::L: - return XK_L; - case Key::M: - return XK_M; - case Key::N: - return XK_N; - case Key::O: - return XK_O; - case Key::P: - return XK_P; - case Key::Q: - return XK_Q; - case Key::R: - return XK_R; - case Key::S: - return XK_S; - case Key::T: - return XK_T; - case Key::U: - return XK_U; - case Key::V: - return XK_V; - case Key::W: - return XK_W; - case Key::X: - return XK_X; - case Key::Y: - return XK_Y; - case Key::Z: - return XK_Z; - case Key::A_Ring: - return XK_Aring; - case Key::A_Umlaut: - return XK_Adiaeresis; - case Key::O_Umlaut: - return XK_Odiaeresis; - case Key::_0: - return XK_0; - case Key::_1: - return XK_1; - case Key::_2: - return XK_2; - case Key::_3: - return XK_3; - case Key::_4: - return XK_4; - case Key::_5: - return XK_5; - case Key::_6: - return XK_6; - case Key::_7: - return XK_7; - case Key::_8: - return XK_8; - case Key::_9: - return XK_9; - case Key::F1: - return XK_F1; - case Key::F2: - return XK_F2; - case Key::F3: - return XK_F3; - case Key::F4: - return XK_F4; - case Key::F5: - return XK_F5; - case Key::F6: - return XK_F6; - case Key::F7: - return XK_F7; - case Key::F8: - return XK_F8; - case Key::F9: - return XK_F9; - case Key::F10: - return XK_F10; - case Key::F11: - return XK_F11; - case Key::F12: - return XK_F12; - case Key::Insert: - return XK_Insert; - case Key::PrintScreen: - return XK_Print; - case Key::Delete: - return XK_Delete; - case Key::Home: - return XK_Home; - case Key::End: - return XK_End; - case Key::PageUp: - return XK_Page_Up; - case Key::PageDown: - return XK_Page_Down; - case Key::Enter: - return XK_Return; - case Key::Space: - return XK_space; - case Key::ExclamationMark: - return XK_exclam; - case Key::DoubleQuote: - return XK_quotedbl; - case Key::Hashtag: - return XK_numbersign; - case Key::Currency: - return XK_currency; - case Key::Percent: - return XK_percent; - case Key::Ampersand: - return XK_ampersand; - case Key::Slash: - return XK_slash; - case Key::Section: - return XK_section; - case Key::Half: - return XK_onehalf; - case Key::OpenParenthesis: - return '('; - case Key::CloseParenthesis: - return ')'; - case Key::OpenSquareBracket: - return '['; - case Key::CloseSquareBracket: - return ']'; - case Key::OpenCurlyBracket: - return '{'; - case Key::CloseCurlyBracket: - return '}'; - case Key::Equals: - return '='; - case Key::QuestionMark: - return '?'; - case Key::Plus: - return '+'; - case Key::BackSlash: - return '\\'; - case Key::Acute: - return XK_acute; - case Key::BackTick: - return '`'; - case Key::TwoDots: - return XK_diaeresis; - case Key::Cedilla: - return XK_Ccedilla; - case Key::Backspace: - return XK_BackSpace; - case Key::AtSign: - return XK_at; - case Key::Pound: - return XK_sterling; - case Key::Dollar: - return XK_dollar; - case Key::Euro: - return XK_EuroSign; - case Key::Escape: - return XK_Escape; - case Key::Tab: - return XK_Tab; - case Key::CapsLock: - return XK_Caps_Lock; - case Key::LeftShift: - return XK_Shift_L; - case Key::LeftCtrl: - return XK_Control_L; - case Key::Super: - return XK_Super_L; - case Key::LeftAlt: - return XK_Alt_L; - case Key::RightAlt: - return XK_Alt_R; - case Key::RightCtrl: - return XK_Control_R; - case Key::RightShift: - return XK_Shift_R; - case Key::SingleQuote: - return '\''; - case Key::Asterix: - return '*'; - case Key::Caret: - return '^'; - case Key::Tilde: - return '~'; - case Key::ArrowUp: - return XK_Up; - case Key::ArrowDown: - return XK_Down; - case Key::ArrowLeft: - return XK_Left; - case Key::ArrowRight: - return XK_Right; - case Key::Comma: - return ','; - case Key::Semicolon: - return ';'; - case Key::Period: - return '.'; - case Key::Colon: - return ':'; - case Key::Hyphen: - return '-'; - case Key::Underscore: - return '_'; - case Key::NumLock: - return XK_Num_Lock; - case Key::ScrollLock: - return XK_Scroll_Lock; - case Key::LessThan: - return '<'; - case Key::GreaterThan: - return '>'; - case Key::Pipe: - return '|'; - case Key::Negation: - return XK_notsign; - case Key::BrokenBar: - return XK_brokenbar; - case Key::Numpad0: - return XK_KP_0; - case Key::Numpad1: - return XK_KP_1; - case Key::Numpad2: - return XK_KP_2; - case Key::Numpad3: - return XK_KP_3; - case Key::Numpad4: - return XK_KP_4; - case Key::Numpad5: - return XK_KP_5; - case Key::Numpad6: - return XK_KP_6; - case Key::Numpad7: - return XK_KP_7; - case Key::Numpad8: - return XK_KP_8; - case Key::Numpad9: - return XK_KP_9; - case Key::NumpadPlus: - return XK_KP_Add; - case Key::NumpadMinus: - return XK_KP_Subtract; - case Key::NumpadMultiply: - return XK_KP_Multiply; - case Key::NumpadDivide: - return XK_KP_Divide; - case Key::NumpadEnter: - return XK_KP_Enter; - case Key::NumpadDecimal: - return XK_KP_Decimal; - case Key::VolumeMute: - return XF86XK_AudioMute; - case Key::VolumeUp: - return XF86XK_AudioRaiseVolume; - case Key::VolumeDown: - return XF86XK_AudioLowerVolume; - case Key::Calculator: - return XF86XK_Calculator; - case Key::MediaPlayPause: - return XF86XK_AudioPlay; - case Key::MediaStop: - return XF86XK_AudioStop; - case Key::MediaPrevious: - return XF86XK_AudioPrev; - case Key::MediaNext: - return XF86XK_AudioNext; - - case Key::Invalid: - case Key::None: - case Key::Count: - break; - } - - return NoSymbol; -} - -BAN::ErrorOr initialize_keymap() -{ - for (auto& keycode : g_keymap) - for (auto& keysym : keycode) - keysym = NoSymbol; - - // FIXME: get this from somewhere (gui command? enviroment? tmp file?) - const auto keymap_path = "./us.keymap"_sv; - - TRY(LibInput::KeyboardLayout::initialize()); - - auto& keyboard_layout = LibInput::KeyboardLayout::get(); - TRY(keyboard_layout.load_from_file(keymap_path)); - - const BAN::Span my_keymaps[] { - keyboard_layout.keymap_normal(), - keyboard_layout.keymap_shift(), - keyboard_layout.keymap_altgr(), - keyboard_layout.keymap_altgr(), // add shift+altgr map? - }; - - for (size_t keycode = g_keymap_min_keycode; keycode < g_keymap_max_keycode; keycode++) - for (size_t layer = 0; layer < g_keymap_layers; layer++) - if (auto my_key = my_keymaps[layer][keycode - g_keymap_min_keycode]; my_key != LibInput::Key::None) - if (auto keysym = my_key_to_x_keysym(my_key); keysym != NoSymbol) - g_keymap[keycode][layer] = (layer % 2) ? toupper(keysym) : tolower(keysym); - - return {}; -} diff --git a/xbanan/Keymap.h b/xbanan/Keymap.h index 6f73cb4..7ee8cc5 100644 --- a/xbanan/Keymap.h +++ b/xbanan/Keymap.h @@ -1,15 +1,17 @@ #pragma once -#include - #include #include -BAN::ErrorOr initialize_keymap(); - constexpr size_t g_keymap_min_keycode = 8; constexpr size_t g_keymap_max_keycode = 255; +constexpr size_t g_keymap_size = g_keymap_max_keycode - g_keymap_min_keycode + 1; + constexpr size_t g_keymap_layers = 4; -extern uint32_t g_keymap[0x100][g_keymap_layers]; +extern uint32_t g_keymap[g_keymap_size][g_keymap_layers]; + +// shift, capslock, control, alt, numlock, level5 shift, super, altgr with 2 keycodes per modifier +constexpr size_t g_modifier_layers = 2; +extern uint8_t g_modifier_map[8][g_modifier_layers]; extern uint8_t g_pressed_keys[32]; diff --git a/xbanan/SDL3/sdl3.cpp b/xbanan/SDL3/sdl3.cpp index 1896e4b..6938406 100644 --- a/xbanan/SDL3/sdl3.cpp +++ b/xbanan/SDL3/sdl3.cpp @@ -1,4 +1,5 @@ #include "../Events.h" +#include "../Keymap.h" #include "../Platform.h" #include @@ -52,13 +53,6 @@ struct SDLCursor final : public PlatformCursor static int s_eventfd { -1 }; -struct Keymap -{ - consteval Keymap(); - uint8_t map[SDL_SCANCODE_COUNT]; -}; -static Keymap s_sdl_keymap; - static SDL_Cursor* s_default_cursor { nullptr }; static void* sdl3_thread(void*) @@ -73,6 +67,8 @@ static void* sdl3_thread(void*) return nullptr; } +static void sdl3_initialize_keymap(); + static bool sdl3_initialize(uint32_t* display_w, uint32_t* display_h) { if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) @@ -92,6 +88,8 @@ static bool sdl3_initialize(uint32_t* display_w, uint32_t* display_h) *display_h = BAN::Math::max(*display_h, rect.y + rect.h); } + sdl3_initialize_keymap(); + s_default_cursor = SDL_GetCursor(); s_eventfd = eventfd(0, 0); @@ -270,23 +268,25 @@ static void sdl3_poll_events(void*) case SDL_EVENT_KEY_UP: case SDL_EVENT_KEY_DOWN: { - uint8_t scancode = s_sdl_keymap.map[event.key.scancode]; - - uint8_t xmod { 0 }; - if (event.key.mod & SDL_KMOD_SHIFT) - xmod |= (1 << 0); - if (event.key.mod & SDL_KMOD_CAPS) - xmod |= (1 << 1); - if (event.key.mod & SDL_KMOD_CTRL) - xmod |= (1 << 2); - if (event.key.mod & SDL_KMOD_ALT) - xmod |= (1 << 3); + const uint8_t xmod = + ((event.key.mod & SDL_KMOD_SHIFT) ? (1 << 0) : 0) | + ((event.key.mod & SDL_KMOD_CAPS) ? (1 << 1) : 0) | + ((event.key.mod & SDL_KMOD_CTRL) ? (1 << 2) : 0) | + ((event.key.mod & SDL_KMOD_ALT) ? (1 << 3) : 0) | + ((event.key.mod & SDL_KMOD_NUM) ? (1 << 4) : 0) | + ((event.key.mod & SDL_KMOD_LEVEL5) ? (1 << 5) : 0) | + ((event.key.mod & SDL_KMOD_GUI) ? (1 << 6) : 0) | + ((event.key.mod & SDL_KMOD_MODE) ? (1 << 7) : 0); auto it = s_window_map.find(event.window.windowID); if (it != s_window_map.end()) - on_key_event(it->value->wid, scancode, xmod, (event.type == SDL_EVENT_KEY_DOWN)); + on_key_event(it->value->wid, event.key.scancode, xmod, (event.type == SDL_EVENT_KEY_DOWN)); break; } + case SDL_EVENT_KEYMAP_CHANGED: + sdl3_initialize_keymap(); + on_keymap_changed(); + break; } } } @@ -449,124 +449,255 @@ PlatformOps g_platform_ops = { .set_cursor = sdl3_set_cursor, }; -#include +static uint32_t sdl3_keycode_to_x_keysym(SDL_Keycode keycode); -consteval Keymap::Keymap() +static void sdl3_initialize_keymap() { - for (auto& scancode : map) - scancode = 0; + static constexpr SDL_Keymod modifier_map[] { + SDL_KMOD_NONE, + SDL_KMOD_SHIFT, + SDL_KMOD_MODE, + SDL_KMOD_MODE | SDL_KMOD_SHIFT, + }; - using LibInput::keycode_normal; - using LibInput::keycode_function; - using LibInput::keycode_numpad; + memset(g_keymap, 0, sizeof(g_keymap)); + memset(g_modifier_map, 0, sizeof(g_modifier_map)); - map[SDL_SCANCODE_GRAVE] = keycode_normal(0, 0); - map[SDL_SCANCODE_1] = keycode_normal(0, 1); - map[SDL_SCANCODE_2] = keycode_normal(0, 2); - map[SDL_SCANCODE_3] = keycode_normal(0, 3); - map[SDL_SCANCODE_4] = keycode_normal(0, 4); - map[SDL_SCANCODE_5] = keycode_normal(0, 5); - map[SDL_SCANCODE_6] = keycode_normal(0, 6); - map[SDL_SCANCODE_7] = keycode_normal(0, 7); - map[SDL_SCANCODE_8] = keycode_normal(0, 8); - map[SDL_SCANCODE_9] = keycode_normal(0, 9); - map[SDL_SCANCODE_0] = keycode_normal(0, 10); - map[SDL_SCANCODE_MINUS] = keycode_normal(0, 11); - map[SDL_SCANCODE_EQUALS] = keycode_normal(0, 12); - map[SDL_SCANCODE_BACKSPACE] = keycode_normal(0, 13); + for (size_t scancode = 0; scancode < g_keymap_size; scancode++) + for (size_t layer = 0; layer < g_keymap_layers; layer++) + if (const auto sdl_key = SDL_GetKeyFromScancode(static_cast(scancode), modifier_map[layer], false); sdl_key != SDLK_UNKNOWN) + g_keymap[scancode][layer] = sdl3_keycode_to_x_keysym(sdl_key); - map[SDL_SCANCODE_TAB] = keycode_normal(1, 0); - map[SDL_SCANCODE_Q] = keycode_normal(1, 1); - map[SDL_SCANCODE_W] = keycode_normal(1, 2); - map[SDL_SCANCODE_E] = keycode_normal(1, 3); - map[SDL_SCANCODE_R] = keycode_normal(1, 4); - map[SDL_SCANCODE_T] = keycode_normal(1, 5); - map[SDL_SCANCODE_Y] = keycode_normal(1, 6); - map[SDL_SCANCODE_U] = keycode_normal(1, 7); - map[SDL_SCANCODE_I] = keycode_normal(1, 8); - map[SDL_SCANCODE_O] = keycode_normal(1, 9); - map[SDL_SCANCODE_P] = keycode_normal(1, 10); - map[SDL_SCANCODE_LEFTBRACKET] = keycode_normal(1, 11); - map[SDL_SCANCODE_RIGHTBRACKET] = keycode_normal(1, 12); + const auto get_scancode = [](SDL_Keycode keycode) -> uint8_t { + const auto scancode = SDL_GetScancodeFromKey(keycode, nullptr);; + if (scancode != SDL_SCANCODE_UNKNOWN && scancode < g_keymap_size) + return scancode + g_keymap_min_keycode; + return 0; + }; - map[SDL_SCANCODE_CAPSLOCK] = keycode_normal(2, 0); - map[SDL_SCANCODE_A] = keycode_normal(2, 1); - map[SDL_SCANCODE_S] = keycode_normal(2, 2); - map[SDL_SCANCODE_D] = keycode_normal(2, 3); - map[SDL_SCANCODE_F] = keycode_normal(2, 4); - map[SDL_SCANCODE_G] = keycode_normal(2, 5); - map[SDL_SCANCODE_H] = keycode_normal(2, 6); - map[SDL_SCANCODE_J] = keycode_normal(2, 7); - map[SDL_SCANCODE_K] = keycode_normal(2, 8); - map[SDL_SCANCODE_L] = keycode_normal(2, 9); - map[SDL_SCANCODE_SEMICOLON] = keycode_normal(2, 10); - map[SDL_SCANCODE_APOSTROPHE] = keycode_normal(2, 11); - map[SDL_SCANCODE_BACKSLASH] = keycode_normal(2, 12); - map[SDL_SCANCODE_RETURN] = keycode_normal(2, 13); + g_modifier_map[0][0] = get_scancode(SDLK_LSHIFT); + g_modifier_map[0][1] = get_scancode(SDLK_RSHIFT); - map[SDL_SCANCODE_LSHIFT] = keycode_normal(3, 0); - map[SDL_SCANCODE_NONUSBACKSLASH] = keycode_normal(3, 1); - map[SDL_SCANCODE_Z] = keycode_normal(3, 2); - map[SDL_SCANCODE_X] = keycode_normal(3, 3); - map[SDL_SCANCODE_C] = keycode_normal(3, 4); - map[SDL_SCANCODE_V] = keycode_normal(3, 5); - map[SDL_SCANCODE_B] = keycode_normal(3, 6); - map[SDL_SCANCODE_N] = keycode_normal(3, 7); - map[SDL_SCANCODE_M] = keycode_normal(3, 8); - map[SDL_SCANCODE_COMMA] = keycode_normal(3, 9); - map[SDL_SCANCODE_PERIOD] = keycode_normal(3, 10); - map[SDL_SCANCODE_SLASH] = keycode_normal(3, 11); - map[SDL_SCANCODE_RSHIFT] = keycode_normal(3, 12); + g_modifier_map[1][0] = get_scancode(SDLK_CAPSLOCK); - map[SDL_SCANCODE_LCTRL] = keycode_normal(4, 0); - map[SDL_SCANCODE_LGUI] = keycode_normal(4, 1); - map[SDL_SCANCODE_LALT] = keycode_normal(4, 2); - map[SDL_SCANCODE_SPACE] = keycode_normal(4, 3); - map[SDL_SCANCODE_RALT] = keycode_normal(4, 4); - map[SDL_SCANCODE_RCTRL] = keycode_normal(4, 5); + g_modifier_map[2][0] = get_scancode(SDLK_LCTRL); + g_modifier_map[2][1] = get_scancode(SDLK_RCTRL); - map[SDL_SCANCODE_UP] = keycode_normal(5, 0); - map[SDL_SCANCODE_LEFT] = keycode_normal(5, 1); - map[SDL_SCANCODE_DOWN] = keycode_normal(5, 2); - map[SDL_SCANCODE_RIGHT] = keycode_normal(5, 3); + g_modifier_map[3][0] = get_scancode(SDLK_LALT); + g_modifier_map[3][1] = get_scancode(SDLK_RALT); - map[SDL_SCANCODE_ESCAPE] = keycode_function(0); - map[SDL_SCANCODE_F1] = keycode_function(1); - map[SDL_SCANCODE_F2] = keycode_function(2); - map[SDL_SCANCODE_F3] = keycode_function(3); - map[SDL_SCANCODE_F4] = keycode_function(4); - map[SDL_SCANCODE_F5] = keycode_function(5); - map[SDL_SCANCODE_F6] = keycode_function(6); - map[SDL_SCANCODE_F7] = keycode_function(7); - map[SDL_SCANCODE_F8] = keycode_function(8); - map[SDL_SCANCODE_F9] = keycode_function(9); - map[SDL_SCANCODE_F10] = keycode_function(10); - map[SDL_SCANCODE_F11] = keycode_function(11); - map[SDL_SCANCODE_F12] = keycode_function(12); - map[SDL_SCANCODE_INSERT] = keycode_function(13); - map[SDL_SCANCODE_PRINTSCREEN] = keycode_function(14); - map[SDL_SCANCODE_DELETE] = keycode_function(15); - map[SDL_SCANCODE_HOME] = keycode_function(16); - map[SDL_SCANCODE_END] = keycode_function(17); - map[SDL_SCANCODE_PAGEUP] = keycode_function(18); - map[SDL_SCANCODE_PAGEDOWN] = keycode_function(19); - map[SDL_SCANCODE_SCROLLLOCK] = keycode_function(20); + g_modifier_map[4][0] = get_scancode(SDLK_NUMLOCKCLEAR); - map[SDL_SCANCODE_NUMLOCKCLEAR] = keycode_numpad(0, 0); - map[SDL_SCANCODE_KP_DIVIDE] = keycode_numpad(0, 1); - map[SDL_SCANCODE_KP_MULTIPLY] = keycode_numpad(0, 2); - map[SDL_SCANCODE_KP_MINUS] = keycode_numpad(0, 3); - map[SDL_SCANCODE_KP_7] = keycode_numpad(1, 0); - map[SDL_SCANCODE_KP_8] = keycode_numpad(1, 1); - map[SDL_SCANCODE_KP_9] = keycode_numpad(1, 2); - map[SDL_SCANCODE_KP_PLUS] = keycode_numpad(1, 3); - map[SDL_SCANCODE_KP_4] = keycode_numpad(2, 0); - map[SDL_SCANCODE_KP_5] = keycode_numpad(2, 1); - map[SDL_SCANCODE_KP_6] = keycode_numpad(2, 2); - map[SDL_SCANCODE_KP_1] = keycode_numpad(3, 0); - map[SDL_SCANCODE_KP_2] = keycode_numpad(3, 1); - map[SDL_SCANCODE_KP_3] = keycode_numpad(3, 2); - map[SDL_SCANCODE_KP_ENTER] = keycode_numpad(3, 3); - map[SDL_SCANCODE_KP_0] = keycode_numpad(4, 0); - map[SDL_SCANCODE_KP_COMMA] = keycode_numpad(4, 1); -}; + g_modifier_map[5][0] = get_scancode(SDLK_LEVEL5_SHIFT); + + g_modifier_map[6][0] = get_scancode(SDLK_LGUI); + g_modifier_map[6][1] = get_scancode(SDLK_RGUI); + + g_modifier_map[7][0] = get_scancode(SDLK_MODE); +} + +#include +#include + +#include + +static uint32_t sdl3_keycode_to_x_keysym(SDL_Keycode keycode) +{ + if (iswprint(keycode)) + { + if ((keycode >= 0x20 && keycode <= 0x7E) || (keycode >= 0xA0 && keycode <= 0xFF)) + return keycode; + return 0x01000000 | keycode; + } + + switch (keycode) + { + case SDLK_RETURN: return XK_Return; + case SDLK_ESCAPE: return XK_Escape; + case SDLK_BACKSPACE: return XK_BackSpace; + case SDLK_TAB: return XK_Tab; + case SDLK_DELETE: return XK_Delete; + case SDLK_CAPSLOCK: return XK_Caps_Lock; + case SDLK_F1: return XK_F1; + case SDLK_F2: return XK_F2; + case SDLK_F3: return XK_F3; + case SDLK_F4: return XK_F4; + case SDLK_F5: return XK_F5; + case SDLK_F6: return XK_F6; + case SDLK_F7: return XK_F7; + case SDLK_F8: return XK_F8; + case SDLK_F9: return XK_F9; + case SDLK_F10: return XK_F10; + case SDLK_F11: return XK_F11; + case SDLK_F12: return XK_F12; + case SDLK_PRINTSCREEN: return XK_Print; + case SDLK_SCROLLLOCK: return XK_Scroll_Lock; + case SDLK_PAUSE: return XK_Pause; + case SDLK_INSERT: return XK_Insert; + case SDLK_HOME: return XK_Home; + case SDLK_PAGEUP: return XK_Page_Up; + case SDLK_END: return XK_End; + case SDLK_PAGEDOWN: return XK_Page_Down; + case SDLK_RIGHT: return XK_Right; + case SDLK_LEFT: return XK_Left; + case SDLK_DOWN: return XK_Down; + case SDLK_UP: return XK_Up; + case SDLK_NUMLOCKCLEAR: return XK_Num_Lock; + case SDLK_KP_DIVIDE: return XK_KP_Divide; + case SDLK_KP_MULTIPLY: return XK_KP_Multiply; + case SDLK_KP_MINUS: return XK_KP_Subtract; + case SDLK_KP_PLUS: return XK_KP_Add; + case SDLK_KP_ENTER: return XK_KP_Enter; + case SDLK_KP_1: return XK_KP_1; + case SDLK_KP_2: return XK_KP_2; + case SDLK_KP_3: return XK_KP_3; + case SDLK_KP_4: return XK_KP_4; + case SDLK_KP_5: return XK_KP_5; + case SDLK_KP_6: return XK_KP_6; + case SDLK_KP_7: return XK_KP_7; + case SDLK_KP_8: return XK_KP_8; + case SDLK_KP_9: return XK_KP_9; + case SDLK_KP_0: return XK_KP_0; + case SDLK_KP_PERIOD: return XK_KP_Decimal; + case SDLK_APPLICATION: return XF86XK_ApplicationLeft; + case SDLK_POWER: return XF86XK_PowerOff; + case SDLK_KP_EQUALS: return XK_KP_Equal; + case SDLK_F13: return XK_F13; + case SDLK_F14: return XK_F14; + case SDLK_F15: return XK_F15; + case SDLK_F16: return XK_F16; + case SDLK_F17: return XK_F17; + case SDLK_F18: return XK_F18; + case SDLK_F19: return XK_F19; + case SDLK_F20: return XK_F20; + case SDLK_F21: return XK_F21; + case SDLK_F22: return XK_F22; + case SDLK_F23: return XK_F23; + case SDLK_F24: return XK_F24; + case SDLK_EXECUTE: return XK_Execute; + case SDLK_HELP: return XK_Help; + case SDLK_MENU: return XK_Menu; + case SDLK_SELECT: return XK_Select; + case SDLK_STOP: return XF86XK_Stop; + case SDLK_AGAIN: return XK_Redo; + case SDLK_UNDO: return XK_Undo; + case SDLK_CUT: return XF86XK_Cut; + case SDLK_COPY: return XF86XK_Copy; + case SDLK_PASTE: return XF86XK_Paste; + case SDLK_FIND: return XK_Find; + case SDLK_MUTE: return XF86XK_AudioMute; + case SDLK_VOLUMEUP: return XF86XK_AudioRaiseVolume; + case SDLK_VOLUMEDOWN: return XF86XK_AudioLowerVolume; + case SDLK_KP_COMMA: return XK_KP_Separator; + //case SDLK_KP_EQUALSAS400: return ; + //case SDLK_ALTERASE: return ; + case SDLK_SYSREQ: return XK_Sys_Req; + case SDLK_CANCEL: return XK_Cancel; + case SDLK_CLEAR: return XK_Clear; + case SDLK_PRIOR: return XK_Prior; + case SDLK_RETURN2: return XK_Return; + //case SDLK_SEPARATOR: return ; + //case SDLK_OUT: return ; + //case SDLK_OPER: return ; + //case SDLK_CLEARAGAIN: return ; + //case SDLK_CRSEL: return ; + //case SDLK_EXSEL: return ; + //case SDLK_KP_00: return ; + //case SDLK_KP_000: return ; + //case SDLK_THOUSANDSSEPARATOR: return ; + //case SDLK_DECIMALSEPARATOR: return ; + //case SDLK_CURRENCYUNIT: return ; + //case SDLK_CURRENCYSUBUNIT: return ; + //case SDLK_KP_LEFTPAREN: return ; + //case SDLK_KP_RIGHTPAREN: return ; + //case SDLK_KP_LEFTBRACE: return ; + //case SDLK_KP_RIGHTBRACE: return ; + case SDLK_KP_TAB: return XK_KP_Tab; + //case SDLK_KP_BACKSPACE: return ; + //case SDLK_KP_A: return ; + //case SDLK_KP_B: return ; + //case SDLK_KP_C: return ; + //case SDLK_KP_D: return ; + //case SDLK_KP_E: return ; + //case SDLK_KP_F: return ; + //case SDLK_KP_XOR: return ; + //case SDLK_KP_POWER: return ; + //case SDLK_KP_PERCENT: return ; + //case SDLK_KP_LESS: return ; + //case SDLK_KP_GREATER: return ; + //case SDLK_KP_AMPERSAND: return ; + //case SDLK_KP_DBLAMPERSAND: return ; + //case SDLK_KP_VERTICALBAR: return ; + //case SDLK_KP_DBLVERTICALBAR: return ; + //case SDLK_KP_COLON: return ; + //case SDLK_KP_HASH: return ; + //case SDLK_KP_SPACE: return ; + //case SDLK_KP_AT: return ; + //case SDLK_KP_EXCLAM: return ; + //case SDLK_KP_MEMSTORE: return ; + //case SDLK_KP_MEMRECALL: return ; + //case SDLK_KP_MEMCLEAR: return ; + //case SDLK_KP_MEMADD: return ; + //case SDLK_KP_MEMSUBTRACT: return ; + //case SDLK_KP_MEMMULTIPLY: return ; + //case SDLK_KP_MEMDIVIDE: return ; + //case SDLK_KP_PLUSMINUS: return ; + //case SDLK_KP_CLEAR: return ; + //case SDLK_KP_CLEARENTRY: return ; + //case SDLK_KP_BINARY: return ; + //case SDLK_KP_OCTAL: return ; + //case SDLK_KP_DECIMAL: return ; + //case SDLK_KP_HEXADECIMAL: return ; + case SDLK_LCTRL: return XK_Control_L; + case SDLK_LSHIFT: return XK_Shift_L; + case SDLK_LALT: return XK_Alt_L; + case SDLK_LGUI: return XK_Super_L; + case SDLK_RCTRL: return XK_Control_R; + case SDLK_RSHIFT: return XK_Shift_R; + case SDLK_RALT: return XK_Alt_R; + case SDLK_RGUI: return XK_Super_R; + case SDLK_MODE: return XK_Mode_switch; + case SDLK_SLEEP: return XF86XK_Sleep; + case SDLK_WAKE: return XF86XK_WakeUp; + //case SDLK_CHANNEL_INCREMENT: return XF86XK_ChannelUp; + //case SDLK_CHANNEL_DECREMENT: return XF86XK_ChannelDown; + case SDLK_MEDIA_PLAY: return XF86XK_AudioPlay; + case SDLK_MEDIA_PAUSE: return XF86XK_AudioPause; + case SDLK_MEDIA_RECORD: return XF86XK_AudioRecord; + case SDLK_MEDIA_FAST_FORWARD: return XF86XK_AudioForward; + case SDLK_MEDIA_REWIND: return XF86XK_AudioRewind; + case SDLK_MEDIA_NEXT_TRACK: return XF86XK_AudioNext; + case SDLK_MEDIA_PREVIOUS_TRACK: return XF86XK_AudioPrev; + case SDLK_MEDIA_STOP: return XF86XK_AudioStop; + case SDLK_MEDIA_EJECT: return XF86XK_Eject; + //case SDLK_MEDIA_PLAY_PAUSE: return XF86XK_MediaPlayPause; + case SDLK_MEDIA_SELECT: return XF86XK_AudioMedia; + case SDLK_AC_NEW: return XF86XK_New; + case SDLK_AC_OPEN: return XF86XK_Open; + case SDLK_AC_CLOSE: return XF86XK_Close; + //case SDLK_AC_EXIT: return XF86XK_Exit; + case SDLK_AC_SAVE: return XF86XK_Save; + case SDLK_AC_PRINT: return XK_Print; + //case SDLK_AC_PROPERTIES: return ; + case SDLK_AC_SEARCH: return XF86XK_Search; + case SDLK_AC_HOME: return XF86XK_HomePage; // ? + case SDLK_AC_BACK: return XF86XK_Back; + case SDLK_AC_FORWARD: return XF86XK_Forward; + case SDLK_AC_STOP: return XF86XK_Stop; + case SDLK_AC_REFRESH: return XF86XK_Refresh; + case SDLK_AC_BOOKMARKS: return XF86XK_Book; // ? + //case SDLK_SOFTLEFT: return ; + //case SDLK_SOFTRIGHT: return ; + //case SDLK_CALL: return ; + //case SDLK_ENDCALL: return ; + case SDLK_LEFT_TAB: return XK_ISO_Left_Tab; + case SDLK_LEVEL5_SHIFT: return XK_ISO_Level5_Shift; + case SDLK_MULTI_KEY_COMPOSE: return XK_Multi_key; + case SDLK_LMETA: return XK_Meta_L; + case SDLK_RMETA: return XK_Meta_R; + case SDLK_LHYPER: return XK_Hyper_L; + case SDLK_RHYPER: return XK_Hyper_R; + } + + return 0; +} diff --git a/xbanan/banan-os/banan-os.cpp b/xbanan/banan-os/banan-os.cpp index 091726a..8d5060c 100644 --- a/xbanan/banan-os/banan-os.cpp +++ b/xbanan/banan-os/banan-os.cpp @@ -1,4 +1,5 @@ #include "../Events.h" +#include "../Keymap.h" #include "../Platform.h" #include @@ -25,6 +26,8 @@ struct BananCursor final : public PlatformCursor int32_t origin_y; }; +static BAN::ErrorOr bananos_initialize_keymap(); + static bool bananos_initialize(uint32_t* display_w, uint32_t* display_h) { auto attributes = LibGUI::Window::default_attributes; @@ -40,6 +43,12 @@ static bool bananos_initialize(uint32_t* display_w, uint32_t* display_h) *display_w = dummy_or_error.value()->width(); *display_h = dummy_or_error.value()->height(); + if (auto ret = bananos_initialize_keymap(); ret.is_error()) + { + dwarnln("Could not initialize keymap: {}", ret.error()); + return false; + } + return true; } @@ -103,7 +112,11 @@ static BAN::ErrorOr> bananos_create_window(Platform (event.shift() ? (1 << 0) : 0) | (event.caps_lock() ? (1 << 1) : 0) | (event.ctrl() ? (1 << 2) : 0) | - (event.alt() ? (1 << 3) : 0); + (event.alt() ? (1 << 3) : 0) | + (event.num_lock() ? (1 << 4) : 0) | + // level5 shift + // super + (event.ralt() ? (1 << 7) : 0); // FIXME: altgr on_key_event(wid, event.scancode, xmod, event.pressed()); }); @@ -120,13 +133,6 @@ static void bananos_request_resize(PlatformWindow* window, uint32_t width, uint3 banan_window.window->request_resize(width, height); } -static void bananos_request_reposition(PlatformWindow* window, int32_t x, int32_t y) -{ - (void)window; - (void)x; - (void)y; -} - static void bananos_invalidate(PlatformWindow* window, const uint32_t* pixels, uint32_t x, uint32_t y, uint32_t width, uint32_t height) { auto& banan_window = *static_cast(window); @@ -147,31 +153,6 @@ static void bananos_request_fullscreen(PlatformWindow* window, bool fullscreen) banan_window.window->set_fullscreen(fullscreen); } -static void bananos_warp_pointer(int32_t x, int32_t y, bool relative) -{ - (void)x; - (void)y; - (void)relative; -} - -static void bananos_query_pointer(int32_t* x, int32_t* y) -{ - (void)x; - (void)y; -} - -static void bananos_set_pointer_grab(PlatformWindow* window, bool grabbed) -{ - (void)window; - (void)grabbed; -} - -static BAN::ErrorOr> bananos_create_system_cursor(SystemCursorType type) -{ - (void)type; - return BAN::Error::from_errno(ENOTSUP); -} - static BAN::ErrorOr> bananos_create_bitmap_cursor(const uint32_t* pixels, uint32_t width, uint32_t height, int32_t origin_x, int32_t origin_y) { auto cursor = TRY(BAN::UniqPtr::create()); @@ -207,12 +188,158 @@ PlatformOps g_platform_ops = { .create_window = bananos_create_window, .invalidate = bananos_invalidate, .request_resize = bananos_request_resize, - .request_reposition = bananos_request_reposition, + .request_reposition = nullptr, .request_fullscreen = bananos_request_fullscreen, - .warp_pointer = bananos_warp_pointer, - .query_pointer = nullptr, /* bananos_query_pointer */ - .set_pointer_grab = bananos_set_pointer_grab, - .create_system_cursor = bananos_create_system_cursor, + .warp_pointer = nullptr, + .query_pointer = nullptr, + .set_pointer_grab = nullptr, + .create_system_cursor = nullptr, .create_bitmap_cursor = bananos_create_bitmap_cursor, .set_cursor = bananos_set_cursor, }; + +#include +#include + +static uint32_t bananos_key_to_x_keysym(LibInput::Key, bool upper); + +static BAN::ErrorOr bananos_initialize_keymap() +{ + // FIXME: get this from somewhere (gui command? enviroment? tmp file?) + const auto keymap_path = "./us.keymap"_sv; + + TRY(LibInput::KeyboardLayout::initialize()); + + auto& keyboard_layout = LibInput::KeyboardLayout::get(); + TRY(keyboard_layout.load_from_file(keymap_path)); + + const BAN::Span banan_keymaps[] { + keyboard_layout.keymap_normal(), + keyboard_layout.keymap_shift(), + keyboard_layout.keymap_altgr(), + keyboard_layout.keymap_altgr(), // add shift+altgr map? + }; + + for (size_t scancode = 0; scancode < g_keymap_size; scancode++) + for (size_t layer = 0; layer < g_keymap_layers; layer++) + if (const auto banan_key = banan_keymaps[layer][scancode]; banan_key != LibInput::Key::None) + g_keymap[scancode][layer] = bananos_key_to_x_keysym(banan_key, layer % 2); + + using LibInput::keycode_normal; + using LibInput::keycode_numpad; + + g_modifier_map[0][0] = keycode_normal(3, 0) + g_keymap_min_keycode; // lshift + g_modifier_map[0][1] = keycode_normal(3, 12) + g_keymap_min_keycode; // rshift + + g_modifier_map[1][0] = keycode_normal(2, 0) + g_keymap_min_keycode; // caps lock + + g_modifier_map[2][0] = keycode_normal(4, 0) + g_keymap_min_keycode; // lctrl + g_modifier_map[2][1] = keycode_normal(4, 6) + g_keymap_min_keycode; // rctrl + + g_modifier_map[3][0] = keycode_normal(4, 2) + g_keymap_min_keycode; // lalt + g_modifier_map[3][1] = keycode_normal(4, 5) + g_keymap_min_keycode; // ralt + + g_modifier_map[4][0] = keycode_numpad(0, 0) + g_keymap_min_keycode; // num lock + + //g_modifier_map[5][0] = level5 shift; + + g_modifier_map[6][0] = keycode_normal(4, 1) + g_keymap_min_keycode; // lsuper + g_modifier_map[6][1] = keycode_normal(4, 4) + g_keymap_min_keycode; // rsuper + + g_modifier_map[7][0] = keycode_normal(4, 5) + g_keymap_min_keycode; // FIXME: altgr + + return {}; +} + +#include + +#include +#include + +#include + +static uint32_t bananos_key_to_x_keysym(LibInput::Key key, bool upper) +{ + using namespace LibInput; + + if (const char* utf8 = key_to_utf8(key, upper ? KeyEvent::LShift : 0)) + { + const uint32_t codepoint = BAN::UTF8::to_codepoint(utf8); + if (codepoint != BAN::UTF8::invalid && iswprint(codepoint)) + { + if ((codepoint >= 0x20 && codepoint <= 0x7E) || (codepoint >= 0xA0 && codepoint <= 0xFF)) + return codepoint; + return 0x01000000 | codepoint; + } + } + + switch (key) + { + case Key::F1: return XK_F1; + case Key::F2: return XK_F2; + case Key::F3: return XK_F3; + case Key::F4: return XK_F4; + case Key::F5: return XK_F5; + case Key::F6: return XK_F6; + case Key::F7: return XK_F7; + case Key::F8: return XK_F8; + case Key::F9: return XK_F9; + case Key::F10: return XK_F10; + case Key::F11: return XK_F11; + case Key::F12: return XK_F12; + case Key::Insert: return XK_Insert; + case Key::PrintScreen: return XK_Print; + case Key::Delete: return XK_Delete; + case Key::Home: return XK_Home; + case Key::End: return XK_End; + case Key::PageUp: return XK_Page_Up; + case Key::PageDown: return XK_Page_Down; + case Key::Enter: return XK_Return; + case Key::Backspace: return XK_BackSpace; + case Key::Escape: return XK_Escape; + case Key::Tab: return XK_Tab; + case Key::CapsLock: return XK_Caps_Lock; + case Key::LeftShift: return XK_Shift_L; + case Key::LeftCtrl: return XK_Control_L; + case Key::Super: return XK_Super_L; + case Key::LeftAlt: return XK_Alt_L; + case Key::RightAlt: return XK_Alt_R; + case Key::RightCtrl: return XK_Control_R; + case Key::RightShift: return XK_Shift_R; + case Key::ArrowUp: return XK_Up; + case Key::ArrowDown: return XK_Down; + case Key::ArrowLeft: return XK_Left; + case Key::ArrowRight: return XK_Right; + case Key::NumLock: return XK_Num_Lock; + case Key::ScrollLock: return XK_Scroll_Lock; + case Key::Numpad0: return XK_KP_0; + case Key::Numpad1: return XK_KP_1; + case Key::Numpad2: return XK_KP_2; + case Key::Numpad3: return XK_KP_3; + case Key::Numpad4: return XK_KP_4; + case Key::Numpad5: return XK_KP_5; + case Key::Numpad6: return XK_KP_6; + case Key::Numpad7: return XK_KP_7; + case Key::Numpad8: return XK_KP_8; + case Key::Numpad9: return XK_KP_9; + case Key::NumpadPlus: return XK_KP_Add; + case Key::NumpadMinus: return XK_KP_Subtract; + case Key::NumpadMultiply: return XK_KP_Multiply; + case Key::NumpadDivide: return XK_KP_Divide; + case Key::NumpadEnter: return XK_KP_Enter; + case Key::NumpadDecimal: return XK_KP_Decimal; + case Key::VolumeMute: return XF86XK_AudioMute; + case Key::VolumeUp: return XF86XK_AudioRaiseVolume; + case Key::VolumeDown: return XF86XK_AudioLowerVolume; + case Key::Calculator: return XF86XK_Calculator; + case Key::MediaPlayPause: return XF86XK_AudioPlay; + case Key::MediaStop: return XF86XK_AudioStop; + case Key::MediaPrevious: return XF86XK_AudioPrev; + case Key::MediaNext: return XF86XK_AudioNext; + default: break; + } + + static_assert(static_cast(Key::Count) == 145, "update keymap"); + + return 0; +} diff --git a/xbanan/main.cpp b/xbanan/main.cpp index abbb0c3..676118b 100644 --- a/xbanan/main.cpp +++ b/xbanan/main.cpp @@ -1,10 +1,10 @@ #include "Base.h" #include "Definitions.h" -#include "Keymap.h" #include #include +#include #include #include #include @@ -99,6 +99,8 @@ int g_server_grabber_fd = -1; int main() { + setlocale(LC_ALL, ""); + for (int sig = 1; sig < NSIG; sig++) if (sig != SIGWINCH) signal(sig, exit); @@ -259,8 +261,6 @@ int main() APPEND_ATOM_CUSTOM(_NET_WM_WINDOW_TYPE_UTILITY); #undef APPEND_ATOM_CUSTOM - MUST(initialize_keymap()); - uint32_t display_w, display_h; if (!g_platform_ops.initialize(&display_w, &display_h)) return 1;