diff --git a/native/ppt/binding.cc b/native/ppt/binding.cc index c82b498..d9c2f4f 100644 --- a/native/ppt/binding.cc +++ b/native/ppt/binding.cc @@ -13,6 +13,8 @@ using namespace std; #include "src/Win32KeyboardHook.h" #else #include "src/KeyboardHook.h" +#include "src/X11KeyboardHook.h" + #endif @@ -67,7 +69,12 @@ NAN_METHOD(UnregisterCallback) { } NAN_MODULE_INIT(init) { +#ifdef WIN32 hook = make_unique(); +#else + hook = make_unique(); +#endif + if(!hook->attach()) { NAN_THROW_EXCEPTION(Error, "Failed to attach hook!"); return; diff --git a/native/ppt/src/KeyboardHook.h b/native/ppt/src/KeyboardHook.h index 4241ea7..753148b 100644 --- a/native/ppt/src/KeyboardHook.h +++ b/native/ppt/src/KeyboardHook.h @@ -4,12 +4,6 @@ #include #include -//#define HOOK_X11 - -#if defined(HOOK_X11) - #include -#endif - enum struct KeyboardHookType { X11, @@ -53,7 +47,7 @@ class KeyboardHook { }; typedef std::function& /* event */)> callback_event_t; - KeyboardHook(KeyboardHookType); + explicit KeyboardHook(KeyboardHookType); virtual ~KeyboardHook(); [[nodiscard]] inline KeyboardHookType type() const { return this->type_; } @@ -68,27 +62,6 @@ class KeyboardHook { protected: const KeyboardHookType type_; -#if 0 - #if defined(HOOK_X11) - typedef int KeyID; - Display* display = nullptr; - Window window_root = 0; - Window window_focused = 0; - int focus_revert; - - long end_id = 0; - #elseif defined(HOOK_WIN32_LL) - typedef UINT KeyID; - HHOOK keyboad_hook_id{nullptr}; - bool keyboard_hook_callback(int, WPARAM, LPARAM); - -#ifdef USE_MOUSE_HOOK - HHOOK mouse_hook_id{nullptr}; - bool mouse_hook_callback(int, WPARAM, LPARAM); -#endif - #endif -#endif - std::map map_key; std::map map_special; diff --git a/native/ppt/src/X11KeyboardHook.cpp b/native/ppt/src/X11KeyboardHook.cpp index a6b1884..bebe03c 100644 --- a/native/ppt/src/X11KeyboardHook.cpp +++ b/native/ppt/src/X11KeyboardHook.cpp @@ -4,13 +4,13 @@ #include #include #include -#include "KeyboardHook.h" +#include "X11KeyboardHook.h" #define ClientMessageMask (1L << 24) #define SelectMask (KeyPressMask | KeyReleaseMask | FocusChangeMask | ClientMessageMask) -using namespace std; -using KeyType = KeyboardHook::KeyType::value; +using namespace hooks; +using KeyType = KeyboardHook::KeyType; inline KeyType key_type(XID key_id) { switch (key_id) { @@ -38,15 +38,17 @@ inline KeyType key_type(XID key_id) { return KeyType::KEY_NORMAL; } -KeyboardHook::KeyboardHook() { - this->map_special[KeyType::KEY_NORMAL] = XK_VoidSymbol; -} -KeyboardHook::~KeyboardHook() { - if(this->active) - this->detach(); +X11KeyboardHook::X11KeyboardHook() : KeyboardHook{KeyboardHookType::X11} { + this->map_special[KeyType::KEY_NORMAL] = XK_VoidSymbol; } -bool KeyboardHook::attach() { +X11KeyboardHook::~X11KeyboardHook() { + if(this->active) { + (void) this->detach(); + } +} + +bool X11KeyboardHook::attach() { assert(!this->active); this->active = true; @@ -73,15 +75,15 @@ bool KeyboardHook::attach() { Serial number of failed request: 32 Current serial number in output stream: 32 */ - cerr << "Caught X11 error: " << event->type << endl; + std::cerr << "Caught X11 error: " << event->type << std::endl; return 0; }); - this->poll_thread = thread(bind(&KeyboardHook::poll_events, this)); + this->poll_thread = std::thread(std::bind(&X11KeyboardHook::poll_events, this)); return true; } -void KeyboardHook::detach() { +void X11KeyboardHook::detach() { assert(this->active); this->active = false; @@ -105,7 +107,7 @@ void KeyboardHook::detach() { this->display = nullptr; } -void KeyboardHook::poll_events() { +void X11KeyboardHook::poll_events() { XEvent event; bool has_event = false; @@ -114,14 +116,14 @@ void KeyboardHook::poll_events() { auto result = XNextEvent(this->display, &event); if(result != 0) { //TODO throw error - cout << "XNextEvent returned invalid code: " << result << endl; + std::cout << "XNextEvent returned invalid code: " << result << std::endl; break; } } has_event = false; if(event.type == FocusOut) { - cout << "Old windows lost focus. Attaching to new one" << endl; + std::cout << "Old windows lost focus. Attaching to new one" << std::endl; int result = 0; if(this->window_root != this->window_focused) { result = XSelectInput(display, this->window_focused, 0); //Release events @@ -154,7 +156,7 @@ void KeyboardHook::poll_events() { if(XEventsQueued(this->display, 0) > 0) { auto result = XNextEvent(this->display, &event); if(result != 0) { - cerr << "XNextEvent(...) => " << result << endl; + std::cerr << "XNextEvent(...) => " << result << std::endl; break; } has_event = true; @@ -174,14 +176,14 @@ void KeyboardHook::poll_events() { this->trigger_key_event(KeyEvent::RELEASE, type == KeyType::KEY_NORMAL ? XKeysymToString(key_sym) : XKeysymToString(this->map_special[KeyType::KEY_NORMAL])); } else if(event.type == ClientMessage) { - cout << "Got client message. End ID: " << event.xclient.data.l[0] << " <=> " << this->end_id << endl; + std::cout << "Got client message. End ID: " << event.xclient.data.l[0] << " <=> " << this->end_id << std::endl; if(event.xclient.data.l[0] == this->end_id) break; } else if(event.type == ButtonPress) { - cout << "Got button" << endl; + std::cout << "Got button" << std::endl; } else if(event.type == ButtonRelease) { - cout << "Got button" << endl; + std::cout << "Got button" << std::endl; } else { - cerr << "Got unknown event of type " << event.type << endl; + std::cerr << "Got unknown event of type " << event.type << std::endl; } } } \ No newline at end of file diff --git a/native/ppt/src/X11KeyboardHook.h b/native/ppt/src/X11KeyboardHook.h new file mode 100644 index 0000000..8a50c15 --- /dev/null +++ b/native/ppt/src/X11KeyboardHook.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include "./KeyboardHook.h" + +namespace hooks { + class X11KeyboardHook : public KeyboardHook { + public: + X11KeyboardHook(); + ~X11KeyboardHook() override; + + bool attach() override; + void detach() override; + + bool keytype_supported() const override { return true; } + private: + Display* display{nullptr}; + Window window_root{0}; + Window window_focused{0}; + int focus_revert{}; + + long end_id{0}; + + bool active{false}; + std::thread poll_thread; + void poll_events(); + }; +} \ No newline at end of file