Files
kaizen/lib/source/gainput/keyboard/GainputInputDeviceKeyboardLinux.h
Simone 4e42229bdd Squashed 'external/gainput/' content from commit 2be0a50
git-subtree-dir: external/gainput
git-subtree-split: 2be0a50089eafcc6fccb66142180082e48f27f4c
2024-01-22 08:51:55 +01:00

256 lines
6.6 KiB
C++

#ifndef GAINPUTINPUTDEVICEKEYBOARDLINUX_H_
#define GAINPUTINPUTDEVICEKEYBOARDLINUX_H_
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
#include <X11/Xutil.h>
#include "GainputInputDeviceKeyboardImpl.h"
#include <gainput/GainputHelpers.h>
namespace gainput
{
class InputDeviceKeyboardImplLinux : public InputDeviceKeyboardImpl
{
public:
InputDeviceKeyboardImplLinux(InputManager& manager, InputDevice& device, InputState& state, InputState& previousState) :
manager_(manager),
device_(device),
textInputEnabled_(true),
dialect_(manager_.GetAllocator()),
state_(&state),
previousState_(&previousState),
nextState_(manager.GetAllocator(), KeyCount_),
delta_(0)
{
// Cf. <X11/keysymdef.h>
dialect_[XK_Escape] = KeyEscape;
dialect_[XK_F1] = KeyF1;
dialect_[XK_F2] = KeyF2;
dialect_[XK_F3] = KeyF3;
dialect_[XK_F4] = KeyF4;
dialect_[XK_F5] = KeyF5;
dialect_[XK_F6] = KeyF6;
dialect_[XK_F7] = KeyF7;
dialect_[XK_F8] = KeyF8;
dialect_[XK_F9] = KeyF9;
dialect_[XK_F10] = KeyF10;
dialect_[XK_F11] = KeyF11;
dialect_[XK_F12] = KeyF12;
dialect_[XK_Print] = KeyPrint;
dialect_[XK_Scroll_Lock] = KeyScrollLock;
dialect_[XK_Pause] = KeyBreak;
dialect_[XK_space] = KeySpace;
dialect_[XK_apostrophe] = KeyApostrophe;
dialect_[XK_comma] = KeyComma;
dialect_[XK_minus] = KeyMinus;
dialect_[XK_period] = KeyPeriod;
dialect_[XK_slash] = KeySlash;
dialect_[XK_0] = Key0;
dialect_[XK_1] = Key1;
dialect_[XK_2] = Key2;
dialect_[XK_3] = Key3;
dialect_[XK_4] = Key4;
dialect_[XK_5] = Key5;
dialect_[XK_6] = Key6;
dialect_[XK_7] = Key7;
dialect_[XK_8] = Key8;
dialect_[XK_9] = Key9;
dialect_[XK_semicolon] = KeySemicolon;
dialect_[XK_less] = KeyLess;
dialect_[XK_equal] = KeyEqual;
dialect_[XK_a] = KeyA;
dialect_[XK_b] = KeyB;
dialect_[XK_c] = KeyC;
dialect_[XK_d] = KeyD;
dialect_[XK_e] = KeyE;
dialect_[XK_f] = KeyF;
dialect_[XK_g] = KeyG;
dialect_[XK_h] = KeyH;
dialect_[XK_i] = KeyI;
dialect_[XK_j] = KeyJ;
dialect_[XK_k] = KeyK;
dialect_[XK_l] = KeyL;
dialect_[XK_m] = KeyM;
dialect_[XK_n] = KeyN;
dialect_[XK_o] = KeyO;
dialect_[XK_p] = KeyP;
dialect_[XK_q] = KeyQ;
dialect_[XK_r] = KeyR;
dialect_[XK_s] = KeyS;
dialect_[XK_t] = KeyT;
dialect_[XK_u] = KeyU;
dialect_[XK_v] = KeyV;
dialect_[XK_w] = KeyW;
dialect_[XK_x] = KeyX;
dialect_[XK_y] = KeyY;
dialect_[XK_z] = KeyZ;
dialect_[XK_bracketleft] = KeyBracketLeft;
dialect_[XK_backslash] = KeyBackslash;
dialect_[XK_bracketright] = KeyBracketRight;
dialect_[XK_grave] = KeyGrave;
dialect_[XK_Left] = KeyLeft;
dialect_[XK_Right] = KeyRight;
dialect_[XK_Up] = KeyUp;
dialect_[XK_Down] = KeyDown;
dialect_[XK_Insert] = KeyInsert;
dialect_[XK_Home] = KeyHome;
dialect_[XK_Delete] = KeyDelete;
dialect_[XK_End] = KeyEnd;
dialect_[XK_Page_Up] = KeyPageUp;
dialect_[XK_Page_Down] = KeyPageDown;
dialect_[XK_Num_Lock] = KeyNumLock;
dialect_[XK_KP_Divide] = KeyKpDivide;
dialect_[XK_KP_Multiply] = KeyKpMultiply;
dialect_[XK_KP_Subtract] = KeyKpSubtract;
dialect_[XK_KP_Add] = KeyKpAdd;
dialect_[XK_KP_Enter] = KeyKpEnter;
dialect_[XK_KP_Insert] = KeyKpInsert;
dialect_[XK_KP_End] = KeyKpEnd;
dialect_[XK_KP_Down] = KeyKpDown;
dialect_[XK_KP_Page_Down] = KeyKpPageDown;
dialect_[XK_KP_Left] = KeyKpLeft;
dialect_[XK_KP_Begin] = KeyKpBegin;
dialect_[XK_KP_Right] = KeyKpRight;
dialect_[XK_KP_Home] = KeyKpHome;
dialect_[XK_KP_Up] = KeyKpUp;
dialect_[XK_KP_Page_Up] = KeyKpPageUp;
dialect_[XK_KP_Delete] = KeyKpDelete;
dialect_[XK_BackSpace] = KeyBackSpace;
dialect_[XK_Tab] = KeyTab;
dialect_[XK_Return] = KeyReturn;
dialect_[XK_Caps_Lock] = KeyCapsLock;
dialect_[XK_Shift_L] = KeyShiftL;
dialect_[XK_Control_L] = KeyCtrlL;
dialect_[XK_Super_L] = KeySuperL;
dialect_[XK_Alt_L] = KeyAltL;
dialect_[XK_Alt_R] = KeyAltR;
dialect_[XK_Super_R] = KeySuperR;
dialect_[XK_Menu] = KeyMenu;
dialect_[XK_Control_R] = KeyCtrlR;
dialect_[XK_Shift_R] = KeyShiftR;
dialect_[XK_dead_circumflex] = KeyCircumflex;
dialect_[XK_ssharp] = KeySsharp;
dialect_[XK_dead_acute] = KeyAcute;
dialect_[XK_ISO_Level3_Shift] = KeyAltGr;
dialect_[XK_plus] = KeyPlus;
dialect_[XK_numbersign] = KeyNumbersign;
dialect_[XK_udiaeresis] = KeyUdiaeresis;
dialect_[XK_adiaeresis] = KeyAdiaeresis;
dialect_[XK_odiaeresis] = KeyOdiaeresis;
dialect_[XK_section] = KeySection;
dialect_[XK_aring] = KeyAring;
dialect_[XK_dead_diaeresis] = KeyDiaeresis;
dialect_[XK_twosuperior] = KeyTwosuperior;
dialect_[XK_parenright] = KeyRightParenthesis;
dialect_[XK_dollar] = KeyDollar;
dialect_[XK_ugrave] = KeyUgrave;
dialect_[XK_asterisk] = KeyAsterisk;
dialect_[XK_colon] = KeyColon;
dialect_[XK_exclam] = KeyExclam;
}
InputDevice::DeviceVariant GetVariant() const
{
return InputDevice::DV_STANDARD;
}
void Update(InputDeltaState* delta)
{
delta_ = delta;
*state_ = nextState_;
}
bool IsTextInputEnabled() const { return textInputEnabled_; }
void SetTextInputEnabled(bool enabled) { textInputEnabled_ = enabled; }
char GetNextCharacter()
{
if (!textBuffer_.CanGet())
{
return 0;
}
return textBuffer_.Get();
}
void HandleEvent(XEvent& event)
{
GAINPUT_ASSERT(state_);
GAINPUT_ASSERT(previousState_);
if (event.type == KeyPress || event.type == KeyRelease)
{
XKeyEvent& keyEvent = event.xkey;
KeySym keySym = XkbKeycodeToKeysym(keyEvent.display, keyEvent.keycode, 0, 0);
const bool pressed = event.type == KeyPress;
// Handle key repeat
if (event.type == KeyRelease && XPending(keyEvent.display))
{
XEvent nextEvent;
XPeekEvent(keyEvent.display, &nextEvent);
if (nextEvent.type == KeyPress
&& nextEvent.xkey.keycode == event.xkey.keycode
&& nextEvent.xkey.time == event.xkey.time)
{
XNextEvent(keyEvent.display, &nextEvent);
return;
}
}
if (dialect_.count(keySym))
{
const DeviceButtonId buttonId = dialect_[keySym];
HandleButton(device_, nextState_, delta_, buttonId, pressed);
}
#ifdef GAINPUT_DEBUG
else
{
char* str = XKeysymToString(keySym);
GAINPUT_LOG("Unmapped key >> keycode: %d, keysym: %d, str: %s\n", keyEvent.keycode, int(keySym), str);
}
#endif
if (textInputEnabled_)
{
char buf[32];
int len = XLookupString(&keyEvent, buf, 32, 0, 0);
if (len == 1)
{
textBuffer_.Put(buf[0]);
}
}
}
}
private:
InputManager& manager_;
InputDevice& device_;
bool textInputEnabled_;
RingBuffer<GAINPUT_TEXT_INPUT_QUEUE_LENGTH, char> textBuffer_;
HashMap<unsigned, DeviceButtonId> dialect_;
InputState* state_;
InputState* previousState_;
InputState nextState_;
InputDeltaState* delta_;
};
}
#endif