#pragma once #include #include #include #ifdef HAVE_X11 #include #elif defined(WIN32) #include #endif class KeyboardHook { #if defined(WIN32) friend LRESULT CALLBACK _keyboard_hook_callback(int, WPARAM, LPARAM); friend LRESULT CALLBACK _mouse_hook_callback(int, WPARAM, LPARAM); #endif public: struct KeyType { enum value { KEY_UNKNOWN, KEY_NORMAL, KEY_SHIFT, KEY_ALT, KEY_WIN, KEY_CTRL }; }; struct KeyEvent { enum type { PRESS, RELEASE, TYPE }; type type; std::string key; std::string code; bool key_ctrl; bool key_windows; bool key_shift; bool key_alt; }; typedef std::function& /* event */)> callback_event_t; KeyboardHook(); virtual ~KeyboardHook(); bool attach(); inline bool attached() { return this->_attached; } void detach(); callback_event_t callback_event; private: #ifdef HAVE_X11 typedef int KeyID; Display* display = nullptr; Window window_root = 0; Window window_focused = 0; int focus_revert; long end_id = 0; #elif defined(WIN32) typedef UINT KeyID; HHOOK keyboad_hook_id{nullptr}; HHOOK mouse_hook_id{nullptr}; bool keyboard_hook_callback(int, WPARAM, LPARAM); bool mouse_hook_callback(int, WPARAM, LPARAM); #endif void trigger_key_event(const enum KeyEvent::type&, const std::string& /* key */); std::map map_key; std::map map_special; bool _attached = false; bool active = false; std::thread poll_thread; void poll_events(); };