diff --git a/src/she/skia/skia_window_x11.h b/src/she/skia/skia_window_x11.h index f5fc6710d..847da6650 100644 --- a/src/she/skia/skia_window_x11.h +++ b/src/she/skia/skia_window_x11.h @@ -36,10 +36,6 @@ public: std::string getLayout() { return ""; } void setLayout(const std::string& layout) { } - void setTranslateDeadKeys(bool state) { - // Do nothing - } - private: void queueEvent(Event& ev) override; void paintGC(const gfx::Rect& rc) override; diff --git a/src/she/x11/keys.cpp b/src/she/x11/keys.cpp index 717d79e7f..b6cf047fa 100644 --- a/src/she/x11/keys.cpp +++ b/src/she/x11/keys.cpp @@ -1,5 +1,5 @@ // SHE library -// Copyright (C) 2016 David Capello +// Copyright (C) 2016-2018 David Capello // // This file is released under the terms of the MIT license. // Read LICENSE.txt for more information. @@ -8,10 +8,160 @@ #include "config.h" #endif -#include "she/keys.h" +#include "base/ints.h" +#include "she/x11/keys.h" + +#include namespace she { +KeyScancode x11_keysym_to_scancode(KeySym keysym) +{ + switch (keysym) { + case XK_BackSpace: return kKeyBackspace; + case XK_Tab: return kKeyTab; + case XK_Linefeed: return kKeyEnter; + case XK_Clear: return kKeyDel; + case XK_Return: return kKeyEnter; + case XK_Pause: + case XK_Break: return kKeyPause; + case XK_Scroll_Lock: return kKeyScrLock; + case XK_Escape: return kKeyEsc; + case XK_Delete: return kKeyDel; + case XK_Home: return kKeyHome; + case XK_Left: return kKeyLeft; + case XK_Up: return kKeyUp; + case XK_Right: return kKeyRight; + case XK_Down: return kKeyDown; + case XK_Page_Up: return kKeyPageUp; + case XK_Page_Down: return kKeyPageDown; + case XK_End: return kKeyEnd; + case XK_Sys_Req: + case XK_Print: return kKeyPrtscr; + case XK_Insert: return kKeyInsert; + case XK_Menu: return kKeyMenu; + case XK_Num_Lock: return kKeyNumLock; + case XK_KP_Space: return kKeySpace; + case XK_KP_Tab: return kKeyTab; + case XK_KP_Enter: return kKeyEnterPad; + case XK_KP_0: case XK_KP_Insert: return kKey0Pad; + case XK_KP_1: case XK_KP_End: return kKey1Pad; + case XK_KP_2: case XK_KP_Down: return kKey2Pad; + case XK_KP_3: case XK_KP_Page_Down: return kKey3Pad; + case XK_KP_4: case XK_KP_Left: return kKey4Pad; + case XK_KP_5: case XK_KP_Begin: return kKey5Pad; + case XK_KP_6: case XK_KP_Right: return kKey6Pad; + case XK_KP_7: case XK_KP_Home: return kKey7Pad; + case XK_KP_8: case XK_KP_Up: return kKey8Pad; + case XK_KP_9: case XK_KP_Page_Up: return kKey9Pad; + case XK_KP_Decimal: + case XK_KP_Delete: return kKeyDelPad; + case XK_KP_Equal: return kKeyEqualsPad; + case XK_KP_Multiply: return kKeyAsterisk; + case XK_KP_Add: return kKeyPlusPad; + case XK_KP_Subtract: return kKeyMinusPad; + case XK_KP_Divide: return kKeySlashPad; + case XK_F1: return kKeyF1; + case XK_F2: return kKeyF2; + case XK_F3: return kKeyF3; + case XK_F4: return kKeyF4; + case XK_F5: return kKeyF5; + case XK_F6: return kKeyF6; + case XK_F7: return kKeyF7; + case XK_F8: return kKeyF8; + case XK_F9: return kKeyF9; + case XK_F10: return kKeyF10; + case XK_F11: return kKeyF11; + case XK_F12: return kKeyF12; + case XK_Shift_L: return kKeyLShift; + case XK_Shift_R: return kKeyRShift; + case XK_Control_L: return kKeyLControl; + case XK_Control_R: return kKeyRControl; + case XK_Caps_Lock: return kKeyCapsLock; + case XK_Alt_L: return kKeyAlt; + case XK_Alt_R: return kKeyAltGr; + case XK_Meta_L: + case XK_Super_L: return kKeyLWin; + case XK_Meta_R: + case XK_Super_R: return kKeyRWin; + case XK_space: return kKeySpace; + case XK_apostrophe: return kKeyQuote; + case XK_comma: return kKeyComma; + case XK_minus: return kKeyMinus; + case XK_period: return kKeyStop; + case XK_slash: return kKeySlash; + case XK_0: return kKey0; + case XK_1: return kKey1; + case XK_2: return kKey2; + case XK_3: return kKey3; + case XK_4: return kKey4; + case XK_5: return kKey5; + case XK_6: return kKey6; + case XK_7: return kKey7; + case XK_8: return kKey8; + case XK_9: return kKey9; + case XK_semicolon: return kKeyColon; + case XK_less: return kKeyBackslash2; + case XK_A: return kKeyA; + case XK_B: return kKeyB; + case XK_C: return kKeyC; + case XK_D: return kKeyD; + case XK_E: return kKeyE; + case XK_F: return kKeyF; + case XK_G: return kKeyG; + case XK_H: return kKeyH; + case XK_I: return kKeyI; + case XK_J: return kKeyJ; + case XK_K: return kKeyK; + case XK_L: return kKeyL; + case XK_M: return kKeyM; + case XK_N: return kKeyN; + case XK_O: return kKeyO; + case XK_P: return kKeyP; + case XK_Q: return kKeyQ; + case XK_R: return kKeyR; + case XK_S: return kKeyS; + case XK_T: return kKeyT; + case XK_U: return kKeyU; + case XK_V: return kKeyV; + case XK_W: return kKeyW; + case XK_X: return kKeyX; + case XK_Y: return kKeyY; + case XK_Z: return kKeyZ; + case XK_bracketleft: return kKeyOpenbrace; + case XK_backslash: return kKeyBackslash; + case XK_bracketright: return kKeyClosebrace; + case XK_grave: return kKeyTilde; + case XK_a: return kKeyA; + case XK_b: return kKeyB; + case XK_c: return kKeyC; + case XK_d: return kKeyD; + case XK_e: return kKeyE; + case XK_f: return kKeyF; + case XK_g: return kKeyG; + case XK_h: return kKeyH; + case XK_i: return kKeyI; + case XK_j: return kKeyJ; + case XK_k: return kKeyK; + case XK_l: return kKeyL; + case XK_m: return kKeyM; + case XK_n: return kKeyN; + case XK_o: return kKeyO; + case XK_p: return kKeyP; + case XK_q: return kKeyQ; + case XK_r: return kKeyR; + case XK_s: return kKeyS; + case XK_t: return kKeyT; + case XK_u: return kKeyU; + case XK_v: return kKeyV; + case XK_w: return kKeyW; + case XK_x: return kKeyX; + case XK_y: return kKeyY; + case XK_z: return kKeyZ; + } + return kKeyNil; +} + bool x11_is_key_pressed(KeyScancode scancode) { return false; // TODO diff --git a/src/she/x11/keys.h b/src/she/x11/keys.h new file mode 100644 index 000000000..476c53612 --- /dev/null +++ b/src/she/x11/keys.h @@ -0,0 +1,22 @@ +// SHE library +// Copyright (C) 2018 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#ifndef SHE_X11_KEYS_INCLUDED +#define SHE_X11_KEYS_INCLUDED +#pragma once + +#include "she/keys.h" +#include + +namespace she { + + KeyScancode x11_keysym_to_scancode(KeySym keysym); + bool x11_is_key_pressed(KeyScancode scancode); + int x11_get_unicode_from_scancode(KeyScancode scancode); + +} // namespace she + +#endif diff --git a/src/she/x11/system.h b/src/she/x11/system.h index bd1b4566f..bb9604177 100644 --- a/src/she/x11/system.h +++ b/src/she/x11/system.h @@ -9,12 +9,10 @@ #pragma once #include "she/common/system.h" +#include "she/x11/keys.h" namespace she { -bool x11_is_key_pressed(KeyScancode scancode); -int x11_get_unicode_from_scancode(KeyScancode scancode); - class X11System : public CommonSystem { public: bool isKeyPressed(KeyScancode scancode) override { diff --git a/src/she/x11/window.cpp b/src/she/x11/window.cpp index eb5335c4a..bfec95f00 100644 --- a/src/she/x11/window.cpp +++ b/src/she/x11/window.cpp @@ -1,5 +1,5 @@ // SHE library -// Copyright (C) 2017 David Capello +// Copyright (C) 2017-2018 David Capello // // This file is released under the terms of the MIT license. // Read LICENSE.txt for more information. @@ -12,10 +12,15 @@ #include "gfx/rect.h" #include "she/event.h" +#include "she/x11/keys.h" #include #include +#define KEY_TRACE(...) +#define MOUSE_TRACE(...) +#define EVENT_TRACE(...) + namespace she { namespace { @@ -35,9 +40,24 @@ std::map<::Window, X11Window*> g_activeWindows; KeyModifiers get_modifiers_from_x(int state) { int modifiers = kKeyNoneModifier; - if (state & ShiftMask) modifiers |= kKeyShiftModifier; - if (state & LockMask) modifiers |= kKeyAltModifier; - if (state & ControlMask) modifiers |= kKeyCtrlModifier; + if (state & ShiftMask) { + modifiers |= kKeyShiftModifier; + KEY_TRACE("+SHIFT\n"); + } + if (state & ControlMask) { + modifiers |= kKeyCtrlModifier; + KEY_TRACE("+CTRL\n"); + } + // Mod1Mask is Alt, and Mod5Mask is AltGr + if (state & (Mod1Mask | Mod5Mask)) { + modifiers |= kKeyAltModifier; + KEY_TRACE("+ALT\n"); + } + // Mod4Mask is Windows key + if (state & Mod4Mask) { + modifiers |= kKeyWinModifier; + KEY_TRACE("+WIN\n"); + } return (KeyModifiers)modifiers; } @@ -64,13 +84,13 @@ gfx::Point get_mouse_wheel_delta(int button) Event::MouseButton get_mouse_button_from_x(int button) { switch (button) { - case Button1: TRACE("LeftButton\n"); return Event::LeftButton; - case Button2: TRACE("MiddleButton\n"); return Event::MiddleButton; - case Button3: TRACE("RightButton\n"); return Event::RightButton; - case 8: TRACE("X1Button\n"); return Event::X1Button; - case 9: TRACE("X2Button\n"); return Event::X2Button; + case Button1: MOUSE_TRACE("LeftButton\n"); return Event::LeftButton; + case Button2: MOUSE_TRACE("MiddleButton\n"); return Event::MiddleButton; + case Button3: MOUSE_TRACE("RightButton\n"); return Event::RightButton; + case 8: MOUSE_TRACE("X1Button\n"); return Event::X1Button; + case 9: MOUSE_TRACE("X2Button\n"); return Event::X2Button; } - TRACE("Unknown Button %d\n", button); + MOUSE_TRACE("Unknown Button %d\n", button); return Event::NoneButton; } @@ -332,6 +352,53 @@ void X11Window::processX11Event(XEvent& event) break; } + case KeyPress: + case KeyRelease: { + Event ev; + + ev.setType(event.type == KeyPress ? Event::KeyDown: Event::KeyUp); + + KeySym keysym = XLookupKeysym(&event.xkey, 0); + ev.setScancode(x11_keysym_to_scancode(keysym)); + + int modifiers = (int)get_modifiers_from_x(event.xkey.state); + switch (keysym) { + case XK_Shift_L: + case XK_Shift_R: + modifiers |= kKeyShiftModifier; + break; + case XK_Control_L: + case XK_Control_R: + modifiers |= kKeyCtrlModifier; + break; + case XK_Alt_L: + case XK_Alt_R: + modifiers |= kKeyAltModifier; + break; + case XK_Meta_L: + case XK_Super_L: + case XK_Meta_R: + case XK_Super_R: + modifiers |= kKeyWinModifier; + break; + } + ev.setModifiers((KeyModifiers)modifiers); + KEY_TRACE("%s state=%04x keycode=%04x\n", + (event.type == KeyPress ? "KeyPress": "KeyRelease"), + event.xkey.state, + event.xkey.keycode); + +#ifndef NDEBUG + { + char* str = XKeysymToString(keysym); + KEY_TRACE(" > %s\n", str); + } +#endif + + queueEvent(ev); + break; + } + case ButtonPress: case ButtonRelease: { Event ev; diff --git a/src/she/x11/window.h b/src/she/x11/window.h index 6fdfaa15b..abb5655bc 100644 --- a/src/she/x11/window.h +++ b/src/she/x11/window.h @@ -1,5 +1,5 @@ // SHE library -// Copyright (C) 2016-2017 David Capello +// Copyright (C) 2016-2018 David Capello // // This file is released under the terms of the MIT license. // Read LICENSE.txt for more information. @@ -49,6 +49,10 @@ public: ::Window handle() const { return m_window; } ::GC gc() const { return m_gc; } + void setTranslateDeadKeys(bool state) { + // TODO + } + void processX11Event(XEvent& event); static X11Window* getPointerFromHandle(Window handle);