From 7287b77c5df40fad243b68fc72759272d400ff99 Mon Sep 17 00:00:00 2001 From: binary1248 Date: Sat, 28 Mar 2015 13:51:42 +0100 Subject: [PATCH] Replaced a few Xlib keyboard handling functions with XCB keyboard handling functions, fixed modified key events returning sf::Keyboard::Unknown on Unix (#847), fixed sf::Keyboard::Quote and sf::Keyboard::Tilde events not functioning properly on Unix, optimized keycode lookup when using sf::Keyboard::isKeyPressed() on Unix. --- src/SFML/Window/CMakeLists.txt | 2 +- src/SFML/Window/Unix/InputImpl.cpp | 317 ++++++++++++++----------- src/SFML/Window/Unix/WindowImplX11.cpp | 57 +++-- src/SFML/Window/Unix/WindowImplX11.hpp | 2 + 4 files changed, 208 insertions(+), 170 deletions(-) diff --git a/src/SFML/Window/CMakeLists.txt b/src/SFML/Window/CMakeLists.txt index d5ab805e..e39fcd3c 100644 --- a/src/SFML/Window/CMakeLists.txt +++ b/src/SFML/Window/CMakeLists.txt @@ -199,7 +199,7 @@ if(NOT SFML_OPENGL_ES) find_package(OpenGL REQUIRED) include_directories(${OPENGL_INCLUDE_DIR}) if(SFML_OS_LINUX OR SFML_OS_FREEBSD) - find_package(XCB COMPONENTS xlib_xcb icccm image randr util ewmh REQUIRED) + find_package(XCB COMPONENTS xlib_xcb icccm image randr util ewmh keysyms REQUIRED) if(NOT LIBXCB_FOUND) message(FATAL_ERROR "Xcb library not found") endif() diff --git a/src/SFML/Window/Unix/InputImpl.cpp b/src/SFML/Window/Unix/InputImpl.cpp index ee4e2311..63fdb4fb 100644 --- a/src/SFML/Window/Unix/InputImpl.cpp +++ b/src/SFML/Window/Unix/InputImpl.cpp @@ -30,10 +30,158 @@ #include #include #include +#include #include #include #include +//////////////////////////////////////////////////////////// +// Private data +//////////////////////////////////////////////////////////// +namespace +{ + bool mapBuilt = false; + + // We use a simple array instead of a map => constant time lookup + xcb_keycode_t keycodeMap[sf::Keyboard::KeyCount]; + + xcb_keycode_t getKeycode(xcb_key_symbols_t* keySymbols, xcb_keysym_t keysym) + { + // keycodes is actually a vector of keycodes + // Since we only care about the unmodified keycode, + // we simply return the first one + sf::priv::ScopedXcbPtr keycodes(xcb_key_symbols_get_keycode(keySymbols, keysym)); + + if (keycodes) + return *keycodes.get(); + + return 0; + } + + void buildMap() + { + // Open a connection with the X server + xcb_connection_t* connection = sf::priv::OpenConnection(); + + xcb_key_symbols_t* keySymbols = xcb_key_symbols_alloc(connection); + + if (!keySymbols) + { + sf::err() << "Failed to allocate key symbols" << std::endl; + return; + } + + keycodeMap[sf::Keyboard::A] = getKeycode(keySymbols, XK_A); + keycodeMap[sf::Keyboard::B] = getKeycode(keySymbols, XK_B); + keycodeMap[sf::Keyboard::C] = getKeycode(keySymbols, XK_C); + keycodeMap[sf::Keyboard::D] = getKeycode(keySymbols, XK_D); + keycodeMap[sf::Keyboard::E] = getKeycode(keySymbols, XK_E); + keycodeMap[sf::Keyboard::F] = getKeycode(keySymbols, XK_F); + keycodeMap[sf::Keyboard::G] = getKeycode(keySymbols, XK_G); + keycodeMap[sf::Keyboard::H] = getKeycode(keySymbols, XK_H); + keycodeMap[sf::Keyboard::I] = getKeycode(keySymbols, XK_I); + keycodeMap[sf::Keyboard::J] = getKeycode(keySymbols, XK_J); + keycodeMap[sf::Keyboard::K] = getKeycode(keySymbols, XK_K); + keycodeMap[sf::Keyboard::L] = getKeycode(keySymbols, XK_L); + keycodeMap[sf::Keyboard::M] = getKeycode(keySymbols, XK_M); + keycodeMap[sf::Keyboard::N] = getKeycode(keySymbols, XK_N); + keycodeMap[sf::Keyboard::O] = getKeycode(keySymbols, XK_O); + keycodeMap[sf::Keyboard::P] = getKeycode(keySymbols, XK_P); + keycodeMap[sf::Keyboard::Q] = getKeycode(keySymbols, XK_Q); + keycodeMap[sf::Keyboard::R] = getKeycode(keySymbols, XK_R); + keycodeMap[sf::Keyboard::S] = getKeycode(keySymbols, XK_S); + keycodeMap[sf::Keyboard::T] = getKeycode(keySymbols, XK_T); + keycodeMap[sf::Keyboard::U] = getKeycode(keySymbols, XK_U); + keycodeMap[sf::Keyboard::V] = getKeycode(keySymbols, XK_V); + keycodeMap[sf::Keyboard::W] = getKeycode(keySymbols, XK_W); + keycodeMap[sf::Keyboard::X] = getKeycode(keySymbols, XK_X); + keycodeMap[sf::Keyboard::Y] = getKeycode(keySymbols, XK_Y); + keycodeMap[sf::Keyboard::Z] = getKeycode(keySymbols, XK_Z); + keycodeMap[sf::Keyboard::Num0] = getKeycode(keySymbols, XK_0); + keycodeMap[sf::Keyboard::Num1] = getKeycode(keySymbols, XK_1); + keycodeMap[sf::Keyboard::Num2] = getKeycode(keySymbols, XK_2); + keycodeMap[sf::Keyboard::Num3] = getKeycode(keySymbols, XK_3); + keycodeMap[sf::Keyboard::Num4] = getKeycode(keySymbols, XK_4); + keycodeMap[sf::Keyboard::Num5] = getKeycode(keySymbols, XK_5); + keycodeMap[sf::Keyboard::Num6] = getKeycode(keySymbols, XK_6); + keycodeMap[sf::Keyboard::Num7] = getKeycode(keySymbols, XK_7); + keycodeMap[sf::Keyboard::Num8] = getKeycode(keySymbols, XK_8); + keycodeMap[sf::Keyboard::Num9] = getKeycode(keySymbols, XK_9); + keycodeMap[sf::Keyboard::Escape] = getKeycode(keySymbols, XK_Escape); + keycodeMap[sf::Keyboard::LControl] = getKeycode(keySymbols, XK_Control_L); + keycodeMap[sf::Keyboard::LShift] = getKeycode(keySymbols, XK_Shift_L); + keycodeMap[sf::Keyboard::LAlt] = getKeycode(keySymbols, XK_Alt_L); + keycodeMap[sf::Keyboard::LSystem] = getKeycode(keySymbols, XK_Super_L); + keycodeMap[sf::Keyboard::RControl] = getKeycode(keySymbols, XK_Control_R); + keycodeMap[sf::Keyboard::RShift] = getKeycode(keySymbols, XK_Shift_R); + keycodeMap[sf::Keyboard::RAlt] = getKeycode(keySymbols, XK_Alt_R); + keycodeMap[sf::Keyboard::RSystem] = getKeycode(keySymbols, XK_Super_R); + keycodeMap[sf::Keyboard::Menu] = getKeycode(keySymbols, XK_Menu); + keycodeMap[sf::Keyboard::LBracket] = getKeycode(keySymbols, XK_bracketleft); + keycodeMap[sf::Keyboard::RBracket] = getKeycode(keySymbols, XK_bracketright); + keycodeMap[sf::Keyboard::SemiColon] = getKeycode(keySymbols, XK_semicolon); + keycodeMap[sf::Keyboard::Comma] = getKeycode(keySymbols, XK_comma); + keycodeMap[sf::Keyboard::Period] = getKeycode(keySymbols, XK_period); + keycodeMap[sf::Keyboard::Quote] = getKeycode(keySymbols, XK_apostrophe); + keycodeMap[sf::Keyboard::Slash] = getKeycode(keySymbols, XK_slash); + keycodeMap[sf::Keyboard::BackSlash] = getKeycode(keySymbols, XK_backslash); + keycodeMap[sf::Keyboard::Tilde] = getKeycode(keySymbols, XK_grave); + keycodeMap[sf::Keyboard::Equal] = getKeycode(keySymbols, XK_equal); + keycodeMap[sf::Keyboard::Dash] = getKeycode(keySymbols, XK_minus); + keycodeMap[sf::Keyboard::Space] = getKeycode(keySymbols, XK_space); + keycodeMap[sf::Keyboard::Return] = getKeycode(keySymbols, XK_Return); + keycodeMap[sf::Keyboard::BackSpace] = getKeycode(keySymbols, XK_BackSpace); + keycodeMap[sf::Keyboard::Tab] = getKeycode(keySymbols, XK_Tab); + keycodeMap[sf::Keyboard::PageUp] = getKeycode(keySymbols, XK_Prior); + keycodeMap[sf::Keyboard::PageDown] = getKeycode(keySymbols, XK_Next); + keycodeMap[sf::Keyboard::End] = getKeycode(keySymbols, XK_End); + keycodeMap[sf::Keyboard::Home] = getKeycode(keySymbols, XK_Home); + keycodeMap[sf::Keyboard::Insert] = getKeycode(keySymbols, XK_Insert); + keycodeMap[sf::Keyboard::Delete] = getKeycode(keySymbols, XK_Delete); + keycodeMap[sf::Keyboard::Add] = getKeycode(keySymbols, XK_KP_Add); + keycodeMap[sf::Keyboard::Subtract] = getKeycode(keySymbols, XK_KP_Subtract); + keycodeMap[sf::Keyboard::Multiply] = getKeycode(keySymbols, XK_KP_Multiply); + keycodeMap[sf::Keyboard::Divide] = getKeycode(keySymbols, XK_KP_Divide); + keycodeMap[sf::Keyboard::Left] = getKeycode(keySymbols, XK_Left); + keycodeMap[sf::Keyboard::Right] = getKeycode(keySymbols, XK_Right); + keycodeMap[sf::Keyboard::Up] = getKeycode(keySymbols, XK_Up); + keycodeMap[sf::Keyboard::Down] = getKeycode(keySymbols, XK_Down); + keycodeMap[sf::Keyboard::Numpad0] = getKeycode(keySymbols, XK_KP_0); + keycodeMap[sf::Keyboard::Numpad1] = getKeycode(keySymbols, XK_KP_1); + keycodeMap[sf::Keyboard::Numpad2] = getKeycode(keySymbols, XK_KP_2); + keycodeMap[sf::Keyboard::Numpad3] = getKeycode(keySymbols, XK_KP_3); + keycodeMap[sf::Keyboard::Numpad4] = getKeycode(keySymbols, XK_KP_4); + keycodeMap[sf::Keyboard::Numpad5] = getKeycode(keySymbols, XK_KP_5); + keycodeMap[sf::Keyboard::Numpad6] = getKeycode(keySymbols, XK_KP_6); + keycodeMap[sf::Keyboard::Numpad7] = getKeycode(keySymbols, XK_KP_7); + keycodeMap[sf::Keyboard::Numpad8] = getKeycode(keySymbols, XK_KP_8); + keycodeMap[sf::Keyboard::Numpad9] = getKeycode(keySymbols, XK_KP_9); + keycodeMap[sf::Keyboard::F1] = getKeycode(keySymbols, XK_F1); + keycodeMap[sf::Keyboard::F2] = getKeycode(keySymbols, XK_F2); + keycodeMap[sf::Keyboard::F3] = getKeycode(keySymbols, XK_F3); + keycodeMap[sf::Keyboard::F4] = getKeycode(keySymbols, XK_F4); + keycodeMap[sf::Keyboard::F5] = getKeycode(keySymbols, XK_F5); + keycodeMap[sf::Keyboard::F6] = getKeycode(keySymbols, XK_F6); + keycodeMap[sf::Keyboard::F7] = getKeycode(keySymbols, XK_F7); + keycodeMap[sf::Keyboard::F8] = getKeycode(keySymbols, XK_F8); + keycodeMap[sf::Keyboard::F9] = getKeycode(keySymbols, XK_F9); + keycodeMap[sf::Keyboard::F10] = getKeycode(keySymbols, XK_F10); + keycodeMap[sf::Keyboard::F11] = getKeycode(keySymbols, XK_F11); + keycodeMap[sf::Keyboard::F12] = getKeycode(keySymbols, XK_F12); + keycodeMap[sf::Keyboard::F13] = getKeycode(keySymbols, XK_F13); + keycodeMap[sf::Keyboard::F14] = getKeycode(keySymbols, XK_F14); + keycodeMap[sf::Keyboard::F15] = getKeycode(keySymbols, XK_F15); + keycodeMap[sf::Keyboard::Pause] = getKeycode(keySymbols, XK_Pause); + + xcb_key_symbols_free(keySymbols); + + // Close the connection with the X server + sf::priv::CloseConnection(connection); + + mapBuilt = true; + } +} + namespace sf { @@ -42,153 +190,42 @@ namespace priv //////////////////////////////////////////////////////////// bool InputImpl::isKeyPressed(Keyboard::Key key) { - // Get the corresponding X11 keysym - KeySym keysym = 0; - switch (key) - { - case Keyboard::A: keysym = XK_A; break; - case Keyboard::B: keysym = XK_B; break; - case Keyboard::C: keysym = XK_C; break; - case Keyboard::D: keysym = XK_D; break; - case Keyboard::E: keysym = XK_E; break; - case Keyboard::F: keysym = XK_F; break; - case Keyboard::G: keysym = XK_G; break; - case Keyboard::H: keysym = XK_H; break; - case Keyboard::I: keysym = XK_I; break; - case Keyboard::J: keysym = XK_J; break; - case Keyboard::K: keysym = XK_K; break; - case Keyboard::L: keysym = XK_L; break; - case Keyboard::M: keysym = XK_M; break; - case Keyboard::N: keysym = XK_N; break; - case Keyboard::O: keysym = XK_O; break; - case Keyboard::P: keysym = XK_P; break; - case Keyboard::Q: keysym = XK_Q; break; - case Keyboard::R: keysym = XK_R; break; - case Keyboard::S: keysym = XK_S; break; - case Keyboard::T: keysym = XK_T; break; - case Keyboard::U: keysym = XK_U; break; - case Keyboard::V: keysym = XK_V; break; - case Keyboard::W: keysym = XK_W; break; - case Keyboard::X: keysym = XK_X; break; - case Keyboard::Y: keysym = XK_Y; break; - case Keyboard::Z: keysym = XK_Z; break; - case Keyboard::Num0: keysym = XK_0; break; - case Keyboard::Num1: keysym = XK_1; break; - case Keyboard::Num2: keysym = XK_2; break; - case Keyboard::Num3: keysym = XK_3; break; - case Keyboard::Num4: keysym = XK_4; break; - case Keyboard::Num5: keysym = XK_5; break; - case Keyboard::Num6: keysym = XK_6; break; - case Keyboard::Num7: keysym = XK_7; break; - case Keyboard::Num8: keysym = XK_8; break; - case Keyboard::Num9: keysym = XK_9; break; - case Keyboard::Escape: keysym = XK_Escape; break; - case Keyboard::LControl: keysym = XK_Control_L; break; - case Keyboard::LShift: keysym = XK_Shift_L; break; - case Keyboard::LAlt: keysym = XK_Alt_L; break; - case Keyboard::LSystem: keysym = XK_Super_L; break; - case Keyboard::RControl: keysym = XK_Control_R; break; - case Keyboard::RShift: keysym = XK_Shift_R; break; - case Keyboard::RAlt: keysym = XK_Alt_R; break; - case Keyboard::RSystem: keysym = XK_Super_R; break; - case Keyboard::Menu: keysym = XK_Menu; break; - case Keyboard::LBracket: keysym = XK_bracketleft; break; - case Keyboard::RBracket: keysym = XK_bracketright; break; - case Keyboard::SemiColon: keysym = XK_semicolon; break; - case Keyboard::Comma: keysym = XK_comma; break; - case Keyboard::Period: keysym = XK_period; break; - case Keyboard::Quote: keysym = XK_dead_acute; break; - case Keyboard::Slash: keysym = XK_slash; break; - case Keyboard::BackSlash: keysym = XK_backslash; break; - case Keyboard::Tilde: keysym = XK_dead_grave; break; - case Keyboard::Equal: keysym = XK_equal; break; - case Keyboard::Dash: keysym = XK_minus; break; - case Keyboard::Space: keysym = XK_space; break; - case Keyboard::Return: keysym = XK_Return; break; - case Keyboard::BackSpace: keysym = XK_BackSpace; break; - case Keyboard::Tab: keysym = XK_Tab; break; - case Keyboard::PageUp: keysym = XK_Prior; break; - case Keyboard::PageDown: keysym = XK_Next; break; - case Keyboard::End: keysym = XK_End; break; - case Keyboard::Home: keysym = XK_Home; break; - case Keyboard::Insert: keysym = XK_Insert; break; - case Keyboard::Delete: keysym = XK_Delete; break; - case Keyboard::Add: keysym = XK_KP_Add; break; - case Keyboard::Subtract: keysym = XK_KP_Subtract; break; - case Keyboard::Multiply: keysym = XK_KP_Multiply; break; - case Keyboard::Divide: keysym = XK_KP_Divide; break; - case Keyboard::Left: keysym = XK_Left; break; - case Keyboard::Right: keysym = XK_Right; break; - case Keyboard::Up: keysym = XK_Up; break; - case Keyboard::Down: keysym = XK_Down; break; - case Keyboard::Numpad0: keysym = XK_KP_0; break; - case Keyboard::Numpad1: keysym = XK_KP_1; break; - case Keyboard::Numpad2: keysym = XK_KP_2; break; - case Keyboard::Numpad3: keysym = XK_KP_3; break; - case Keyboard::Numpad4: keysym = XK_KP_4; break; - case Keyboard::Numpad5: keysym = XK_KP_5; break; - case Keyboard::Numpad6: keysym = XK_KP_6; break; - case Keyboard::Numpad7: keysym = XK_KP_7; break; - case Keyboard::Numpad8: keysym = XK_KP_8; break; - case Keyboard::Numpad9: keysym = XK_KP_9; break; - case Keyboard::F1: keysym = XK_F1; break; - case Keyboard::F2: keysym = XK_F2; break; - case Keyboard::F3: keysym = XK_F3; break; - case Keyboard::F4: keysym = XK_F4; break; - case Keyboard::F5: keysym = XK_F5; break; - case Keyboard::F6: keysym = XK_F6; break; - case Keyboard::F7: keysym = XK_F7; break; - case Keyboard::F8: keysym = XK_F8; break; - case Keyboard::F9: keysym = XK_F9; break; - case Keyboard::F10: keysym = XK_F10; break; - case Keyboard::F11: keysym = XK_F11; break; - case Keyboard::F12: keysym = XK_F12; break; - case Keyboard::F13: keysym = XK_F13; break; - case Keyboard::F14: keysym = XK_F14; break; - case Keyboard::F15: keysym = XK_F15; break; - case Keyboard::Pause: keysym = XK_Pause; break; - default: keysym = 0; break; - } + if (!mapBuilt) + buildMap(); - // Open a connection with the X server - Display* display = OpenDisplay(); - xcb_connection_t* connection = XGetXCBConnection(display); + // Sanity checks + if (key < 0 || key >= sf::Keyboard::KeyCount) + return false; // Convert to keycode - KeyCode keycode = XKeysymToKeycode(display, keysym); - if (keycode != 0) + xcb_keycode_t keycode = keycodeMap[key]; + + ScopedXcbPtr error(NULL); + + // Open a connection with the X server + xcb_connection_t* connection = OpenConnection(); + + // Get the whole keyboard state + ScopedXcbPtr keymap( + xcb_query_keymap_reply( + connection, + xcb_query_keymap(connection), + &error + ) + ); + + // Close the connection with the X server + CloseConnection(connection); + + if (error) { - ScopedXcbPtr error(NULL); - - // Get the whole keyboard state - ScopedXcbPtr keymap( - xcb_query_keymap_reply( - connection, - xcb_query_keymap(connection), - &error - ) - ); - - // Close the connection with the X server - CloseDisplay(display); - - if (error) - { - err() << "Failed to query keymap" << std::endl; - - return false; - } - - // Check our keycode - return (keymap->keys[keycode / 8] & (1 << (keycode % 8))) != 0; - } - else - { - // Close the connection with the X server - CloseDisplay(display); + err() << "Failed to query keymap" << std::endl; return false; } + + // Check our keycode + return (keymap->keys[keycode / 8] & (1 << (keycode % 8))) != 0; } diff --git a/src/SFML/Window/Unix/WindowImplX11.cpp b/src/SFML/Window/Unix/WindowImplX11.cpp index b05e88dd..2af4deeb 100644 --- a/src/SFML/Window/Unix/WindowImplX11.cpp +++ b/src/SFML/Window/Unix/WindowImplX11.cpp @@ -308,6 +308,7 @@ WindowImplX11::WindowImplX11(WindowHandle handle) : m_window (0), m_inputMethod (NULL), m_inputContext (NULL), +m_keySymbols (NULL), m_isExternal (true), m_atomWmProtocols(0), m_atomClose (0), @@ -379,6 +380,7 @@ WindowImplX11::WindowImplX11(VideoMode mode, const String& title, unsigned long m_window (0), m_inputMethod (NULL), m_inputContext (NULL), +m_keySymbols (NULL), m_isExternal (false), m_atomWmProtocols(0), m_atomClose (0), @@ -541,6 +543,10 @@ WindowImplX11::~WindowImplX11() xcb_flush(m_connection); } + // Free key symbols + if (m_keySymbols) + xcb_key_symbols_free(m_keySymbols); + // Close the input method if (m_inputMethod) XCloseIM(m_inputMethod); @@ -1619,6 +1625,12 @@ void WindowImplX11::initialize() if (!m_inputContext) err() << "Failed to create input context for window -- TextEntered event won't be able to return unicode" << std::endl; + // Allocate our key symbols + m_keySymbols = xcb_key_symbols_alloc(m_connection); + + if (!m_keySymbols) + err() << "Failed to allocate key symbols" << std::endl; + // Show the window setVisible(true); @@ -1857,20 +1869,8 @@ bool WindowImplX11::processEvent(xcb_generic_event_t* windowEvent) xcb_key_press_event_t* e = reinterpret_cast(windowEvent); // Get the keysym of the key that has been pressed - static XComposeStatus keyboard; - char buffer[32]; - KeySym symbol; - - // There is no xcb equivalent of XLookupString, so the xcb event - // has to be converted to an XEvent - XEvent fake_event; - fake_event.type = KeyPress; - fake_event.xany.display = m_display; - fake_event.xany.window = e->event; - fake_event.xkey.state = e->state; - fake_event.xkey.keycode = e->detail; - - XLookupString(&fake_event.xkey, buffer, sizeof(buffer), &symbol, &keyboard); + // We don't pass e->state as the last parameter because we want the unmodified keysym + xcb_keysym_t symbol = xcb_key_press_lookup_keysym(m_keySymbols, e, 0); // Fill the event parameters // TODO: if modifiers are wrong, use XGetModifierMapping to retrieve the actual modifiers mapping @@ -1883,8 +1883,15 @@ bool WindowImplX11::processEvent(xcb_generic_event_t* windowEvent) event.key.system = e->state & XCB_MOD_MASK_4; pushEvent(event); + XEvent fakeEvent; + fakeEvent.type = KeyPress; + fakeEvent.xany.display = m_display; + fakeEvent.xany.window = e->event; + fakeEvent.xkey.state = e->state; + fakeEvent.xkey.keycode = e->detail; + // Generate a TextEntered event - if (!XFilterEvent(&fake_event, None)) + if (!XFilterEvent(&fakeEvent, None)) { #ifdef X_HAVE_UTF8_STRING if (m_inputContext) @@ -1894,7 +1901,7 @@ bool WindowImplX11::processEvent(xcb_generic_event_t* windowEvent) int length = Xutf8LookupString( m_inputContext, - &fake_event.xkey, + &fakeEvent.xkey, reinterpret_cast(keyBuffer), sizeof(keyBuffer), NULL, @@ -1919,7 +1926,7 @@ bool WindowImplX11::processEvent(xcb_generic_event_t* windowEvent) { static XComposeStatus status; char keyBuffer[16]; - if (XLookupString(&fake_event.xkey, keyBuffer, sizeof(keyBuffer), NULL, &status)) + if (XLookupString(&fakeEvent.xkey, keyBuffer, sizeof(keyBuffer), NULL, &status)) { Event textEvent; textEvent.type = Event::TextEntered; @@ -1941,16 +1948,8 @@ bool WindowImplX11::processEvent(xcb_generic_event_t* windowEvent) xcb_key_release_event_t* e = reinterpret_cast(windowEvent); // Get the keysym of the key that has been pressed - char buffer[32]; - KeySym symbol; - - // There is no xcb equivalent of XLookupString, so the xcb event - // has to be converted to an XEvent - XKeyEvent fake_event; - fake_event.display = m_display; - fake_event.state = e->state; - fake_event.keycode = e->detail; - XLookupString(&fake_event, buffer, 32, &symbol, NULL); + // We don't pass e->state as the last parameter because we want the unmodified keysym + xcb_keysym_t symbol = xcb_key_release_lookup_keysym(m_keySymbols, e, 0); // Fill the event parameters Event event; @@ -2253,9 +2252,9 @@ Keyboard::Key WindowImplX11::keysymToSF(xcb_keysym_t symbol) case XK_bracketright: return Keyboard::RBracket; case XK_comma: return Keyboard::Comma; case XK_period: return Keyboard::Period; - case XK_dead_acute: return Keyboard::Quote; + case XK_apostrophe: return Keyboard::Quote; case XK_backslash: return Keyboard::BackSlash; - case XK_dead_grave: return Keyboard::Tilde; + case XK_grave: return Keyboard::Tilde; case XK_space: return Keyboard::Space; case XK_Return: return Keyboard::Return; case XK_KP_Enter: return Keyboard::Return; diff --git a/src/SFML/Window/Unix/WindowImplX11.hpp b/src/SFML/Window/Unix/WindowImplX11.hpp index 5bd596dd..65427907 100644 --- a/src/SFML/Window/Unix/WindowImplX11.hpp +++ b/src/SFML/Window/Unix/WindowImplX11.hpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -278,6 +279,7 @@ private: xcb_screen_t* m_screen; ///< Screen identifier XIM m_inputMethod; ///< Input method linked to the X display XIC m_inputContext; ///< Input context used to get unicode input in our window + xcb_key_symbols_t* m_keySymbols; ///< Symbols used to look up keysyms std::deque m_xcbEvents; ///< Events that were received in another window's loop bool m_isExternal; ///< Tell whether the window has been created externally or by SFML Atom m_atomWmProtocols; ///< Atom used to identify WM protocol messages