diff --git a/overlay_experimental/Renderer_Detector.cpp b/overlay_experimental/Renderer_Detector.cpp index 997f146..576ddec 100644 --- a/overlay_experimental/Renderer_Detector.cpp +++ b/overlay_experimental/Renderer_Detector.cpp @@ -134,7 +134,7 @@ private: bool vulkan_hooked; Base_Hook detection_hooks; - Renderer_Hook* renderer_hook; + ingame_overlay::Renderer_Hook* renderer_hook; DX12_Hook* dx12_hook; DX11_Hook* dx11_hook; DX10_Hook* dx10_hook; @@ -238,7 +238,7 @@ private: void HookDetected(T*& detected_renderer) { detection_hooks.UnhookAll(); - renderer_hook = static_cast(detected_renderer); + renderer_hook = static_cast(detected_renderer); detected_renderer = nullptr; detection_done = true; DestroyHWND(); @@ -1032,7 +1032,7 @@ private: } public: - Renderer_Hook* detect_renderer(std::chrono::milliseconds timeout) + ingame_overlay::Renderer_Hook* detect_renderer(std::chrono::milliseconds timeout) { std::unique_lock detection_lock(detector_mutex, std::defer_lock); @@ -1173,7 +1173,7 @@ private: bool openglx_hooked; //bool vulkan_hooked; - Renderer_Hook* renderer_hook; + ingame_overlay::Renderer_Hook* renderer_hook; OpenGLX_Hook* openglx_hook; bool detection_done; @@ -1191,7 +1191,7 @@ private: if (gladLoaderLoadGL() >= GLAD_MAKE_VERSION(3, 1)) { inst->detection_hooks.UnhookAll(); - inst->renderer_hook = static_cast(Inst()->openglx_hook); + inst->renderer_hook = static_cast(Inst()->openglx_hook); inst->openglx_hook = nullptr; inst->detection_done = true; } @@ -1238,7 +1238,7 @@ private: } public: - Renderer_Hook* detect_renderer(std::chrono::milliseconds timeout) + ingame_overlay::Renderer_Hook* detect_renderer(std::chrono::milliseconds timeout) { std::pair libraries[]{ std::pair{OpenGLX_Hook::DLL_NAME, &Renderer_Detector::hook_openglx}, @@ -1352,7 +1352,7 @@ private: bool opengl_hooked; - Renderer_Hook* renderer_hook; + ingame_overlay::Renderer_Hook* renderer_hook; OpenGL_Hook* opengl_hook; bool detection_done; @@ -1368,7 +1368,7 @@ private: if (gladLoaderLoadGL() >= GLAD_MAKE_VERSION(2, 0)) { inst->detection_hooks.UnhookAll(); - inst->renderer_hook = static_cast(Inst()->opengl_hook); + inst->renderer_hook = static_cast(Inst()->opengl_hook); inst->opengl_hook = nullptr; inst->detection_done = true; } @@ -1417,7 +1417,7 @@ private: } public: - Renderer_Hook* detect_renderer(std::chrono::milliseconds timeout) + ingame_overlay::Renderer_Hook* detect_renderer(std::chrono::milliseconds timeout) { std::pair libraries[]{ std::pair{OpenGL_Hook::DLL_NAME, &Renderer_Detector::hook_opengl} @@ -1495,7 +1495,7 @@ Renderer_Detector* Renderer_Detector::instance = nullptr; namespace ingame_overlay { -std::future DetectRenderer(std::chrono::milliseconds timeout) +std::future DetectRenderer(std::chrono::milliseconds timeout) { return std::async(std::launch::async, &Renderer_Detector::detect_renderer, Renderer_Detector::Inst(), timeout); } diff --git a/overlay_experimental/Renderer_Hook.h b/overlay_experimental/Renderer_Hook.h index e11c816..a14b148 100644 --- a/overlay_experimental/Renderer_Hook.h +++ b/overlay_experimental/Renderer_Hook.h @@ -23,6 +23,16 @@ #include #include #include +#include + +namespace ingame_overlay { + +enum class ToggleKey +{ + SHIFT, CTRL, ALT, + TAB, + F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, +}; class Renderer_Hook { @@ -37,7 +47,7 @@ public: std::function OverlayProc; std::function OverlayHookReady; - virtual bool StartHook(std::function key_combination_callback) = 0; + virtual bool StartHook(std::function key_combination_callback, std::set toggle_keys) = 0; virtual bool IsStarted() = 0; // Returns a Handle to the renderer image ressource or nullptr if it failed to create the resource, the handle can be used in ImGui's Image calls, image_buffer must be RGBA ordered virtual std::weak_ptr CreateImageResource(const void* image_data, uint32_t width, uint32_t height) = 0; @@ -45,3 +55,5 @@ public: virtual std::string GetLibraryName() const = 0; }; + +} \ No newline at end of file diff --git a/overlay_experimental/linux/OpenGLX_Hook.cpp b/overlay_experimental/linux/OpenGLX_Hook.cpp index 5c71c7f..c313874 100644 --- a/overlay_experimental/linux/OpenGLX_Hook.cpp +++ b/overlay_experimental/linux/OpenGLX_Hook.cpp @@ -29,7 +29,7 @@ OpenGLX_Hook* OpenGLX_Hook::_inst = nullptr; constexpr decltype(OpenGLX_Hook::DLL_NAME) OpenGLX_Hook::DLL_NAME; -bool OpenGLX_Hook::StartHook(std::function key_combination_callback) +bool OpenGLX_Hook::StartHook(std::function key_combination_callback, std::set toggle_keys) { if (!_Hooked) { @@ -39,7 +39,7 @@ bool OpenGLX_Hook::StartHook(std::function key_combination_callback) return false; } - if (!X11_Hook::Inst()->StartHook(key_combination_callback)) + if (!X11_Hook::Inst()->StartHook(key_combination_callback, toggle_keys)) return false; _X11Hooked = true; diff --git a/overlay_experimental/linux/OpenGLX_Hook.h b/overlay_experimental/linux/OpenGLX_Hook.h index 03ae8d9..ea868c6 100644 --- a/overlay_experimental/linux/OpenGLX_Hook.h +++ b/overlay_experimental/linux/OpenGLX_Hook.h @@ -26,7 +26,7 @@ #include class OpenGLX_Hook : - public Renderer_Hook, + public ingame_overlay::Renderer_Hook, public Base_Hook { public: @@ -59,7 +59,7 @@ public: virtual ~OpenGLX_Hook(); - virtual bool StartHook(std::function key_combination_callback); + virtual bool StartHook(std::function key_combination_callback, std::set toggle_keys); virtual bool IsStarted(); static OpenGLX_Hook* Inst(); virtual std::string GetLibraryName() const; diff --git a/overlay_experimental/linux/X11_Hook.cpp b/overlay_experimental/linux/X11_Hook.cpp index 562b735..5ed6721 100644 --- a/overlay_experimental/linux/X11_Hook.cpp +++ b/overlay_experimental/linux/X11_Hook.cpp @@ -29,10 +29,62 @@ constexpr decltype(X11_Hook::DLL_NAME) X11_Hook::DLL_NAME; X11_Hook* X11_Hook::_inst = nullptr; -bool X11_Hook::StartHook(std::function& _key_combination_callback) +uint32_t ToggleKeyToNativeKey(ingame_overlay::ToggleKey k) +{ + struct { + ingame_overlay::ToggleKey lib_key; + uint32_t native_key; + } mapping[] = { + { ingame_overlay::ToggleKey::ALT , XK_Alt_L }, + { ingame_overlay::ToggleKey::CTRL , XK_Control_L }, + { ingame_overlay::ToggleKey::SHIFT, XK_Shift_L }, + { ingame_overlay::ToggleKey::TAB , XK_Tab }, + { ingame_overlay::ToggleKey::F1 , XK_F1 }, + { ingame_overlay::ToggleKey::F2 , XK_F2 }, + { ingame_overlay::ToggleKey::F3 , XK_F3 }, + { ingame_overlay::ToggleKey::F4 , XK_F4 }, + { ingame_overlay::ToggleKey::F5 , XK_F5 }, + { ingame_overlay::ToggleKey::F6 , XK_F6 }, + { ingame_overlay::ToggleKey::F7 , XK_F7 }, + { ingame_overlay::ToggleKey::F8 , XK_F8 }, + { ingame_overlay::ToggleKey::F9 , XK_F9 }, + { ingame_overlay::ToggleKey::F10 , XK_F10 }, + { ingame_overlay::ToggleKey::F11 , XK_F11 }, + { ingame_overlay::ToggleKey::F12 , XK_F12 }, + }; + + for (auto const& item : mapping) + { + if (item.lib_key == k) + return item.native_key; + } + + return 0; +} + +bool GetKeyState(Display* d, KeySym keySym, char szKey[32]) +{ + int iKeyCodeToFind = XKeysymToKeycode(d, keySym); + + return szKey[iKeyCodeToFind / 8] & (1 << (iKeyCodeToFind % 8)); +} + +bool X11_Hook::StartHook(std::function& _key_combination_callback, std::set const& toggle_keys) { if (!_Hooked) { + if (!_key_combination_callback) + { + SPDLOG_ERROR("Failed to hook X11: No key combination callback."); + return false; + } + + if (toggle_keys.empty()) + { + SPDLOG_ERROR("Failed to hook X11: No key combination."); + return false; + } + void* hX11 = System::Library::GetLibraryHandle(DLL_NAME); if (hX11 == nullptr) { @@ -60,6 +112,16 @@ bool X11_Hook::StartHook(std::function& _key_combination_callback) SPDLOG_INFO("Hooked X11"); _KeyCombinationCallback = std::move(_key_combination_callback); + + for (auto& key : toggle_keys) + { + uint32_t k = ToggleKeyToNativeKey(key); + if (k != 0) + { + _NativeKeyCombination.insert(k); + } + } + _Hooked = true; UnhookAll(); @@ -140,33 +202,47 @@ int X11_Hook::_CheckForOverlay(Display *d, int num_events) static Time prev_time = {}; X11_Hook* inst = Inst(); - if( inst->_Initialized ) + char szKey[32]; + + if( _Initialized ) { XEvent event; while(num_events) { - bool skip_input = inst->_KeyCombinationCallback(false); + bool skip_input = _KeyCombinationCallback(false); XPeekEvent(d, &event); ImGui_ImplX11_EventHandler(event); // Is the event is a key press - if (event.type == KeyPress) + if (event.type == KeyPress || event.type == KeyRelease) { - // Tab is pressed and was not pressed before - if (event.xkey.keycode == XKeysymToKeycode(d, XK_Tab) && event.xkey.state & ShiftMask) + XQueryKeymap(d, szKey); + int key_count = 0; + for (auto const& key : inst->_NativeKeyCombination) { - // if key TAB is held, don't make the overlay flicker :p - if (event.xkey.time != prev_time) + if (GetKeyState(d, key, szKey)) + ++key_count; + } + + if (key_count == inst->_NativeKeyCombination.size()) + {// All shortcut keys are pressed + if (!inst->_KeyCombinationPushed) { - skip_input = true; - inst->_KeyCombinationCallback(true); + if (inst->_KeyCombinationCallback(true)) + { + skip_input = true; + // Save the last known cursor pos when opening the overlay + // so we can spoof the GetCursorPos return value. + //inst->GetCursorPos(&inst->_SavedCursorPos); + } + inst->_KeyCombinationPushed = true; } } - } - else if(event.type == KeyRelease && event.xkey.keycode == XKeysymToKeycode(d, XK_Tab)) - { - prev_time = event.xkey.time; + else + { + inst->_KeyCombinationPushed = false; + } } if (!skip_input || !IgnoreEvent(event)) @@ -215,6 +291,7 @@ X11_Hook::X11_Hook() : _Initialized(false), _Hooked(false), _GameWnd(0), + _KeyCombinationPushed(false), XEventsQueued(nullptr), XPending(nullptr) { @@ -241,3 +318,4 @@ std::string X11_Hook::GetLibraryName() const { return LibraryName; } + diff --git a/overlay_experimental/linux/X11_Hook.h b/overlay_experimental/linux/X11_Hook.h index f1f5339..436469a 100644 --- a/overlay_experimental/linux/X11_Hook.h +++ b/overlay_experimental/linux/X11_Hook.h @@ -41,6 +41,12 @@ private: bool _Initialized; Window _GameWnd; + // In (bool): Is toggle wanted + // Out(bool): Is the overlay visible, if true, inputs will be disabled + std::function _KeyCombinationCallback; + std::set _NativeKeyCombination; + bool _KeyCombinationPushed; + // Functions X11_Hook(); int _CheckForOverlay(Display *d, int num_events); @@ -52,8 +58,6 @@ private: static int MyXEventsQueued(Display * display, int mode); static int MyXPending(Display* display); - std::function _KeyCombinationCallback; - public: std::string LibraryName; @@ -65,7 +69,7 @@ public: Window GetGameWnd() const{ return _GameWnd; } - bool StartHook(std::function& key_combination_callback); + bool StartHook(std::function& key_combination_callback, std::set const& toggle_keys); static X11_Hook* Inst(); virtual std::string GetLibraryName() const; }; diff --git a/overlay_experimental/steam_overlay.cpp b/overlay_experimental/steam_overlay.cpp index df61f65..cf5411d 100644 --- a/overlay_experimental/steam_overlay.cpp +++ b/overlay_experimental/steam_overlay.cpp @@ -967,7 +967,8 @@ void Steam_Overlay::RunCallbacks() _renderer->OverlayProc = std::bind(&Steam_Overlay::OverlayProc, this); auto callback = std::bind(&Steam_Overlay::OpenOverlayHook, this, std::placeholders::_1); PRINT_DEBUG("start renderer\n", _renderer); - bool started = _renderer->StartHook(callback); + std::set keys = {ingame_overlay::ToggleKey::SHIFT, ingame_overlay::ToggleKey::TAB}; + bool started = _renderer->StartHook(callback, keys); PRINT_DEBUG("tried to start renderer %u\n", started); } diff --git a/overlay_experimental/steam_overlay.h b/overlay_experimental/steam_overlay.h index 6840a0e..20c7efb 100644 --- a/overlay_experimental/steam_overlay.h +++ b/overlay_experimental/steam_overlay.h @@ -123,8 +123,8 @@ class Steam_Overlay std::recursive_mutex overlay_mutex; std::atomic i_have_lobby; - std::future future_renderer; - Renderer_Hook* _renderer; + std::future future_renderer; + ingame_overlay::Renderer_Hook* _renderer; Steam_Overlay(Steam_Overlay const&) = delete; Steam_Overlay(Steam_Overlay&&) = delete; diff --git a/overlay_experimental/windows/DX10_Hook.cpp b/overlay_experimental/windows/DX10_Hook.cpp index 55ff7b6..9abefe2 100644 --- a/overlay_experimental/windows/DX10_Hook.cpp +++ b/overlay_experimental/windows/DX10_Hook.cpp @@ -35,7 +35,7 @@ inline void SafeRelease(T*& pUnk) } } -bool DX10_Hook::StartHook(std::function key_combination_callback) +bool DX10_Hook::StartHook(std::function key_combination_callback, std::set toggle_keys) { if (!_Hooked) { @@ -45,7 +45,7 @@ bool DX10_Hook::StartHook(std::function key_combination_callback) return false; } - if (!Windows_Hook::Inst()->StartHook(key_combination_callback)) + if (!Windows_Hook::Inst()->StartHook(key_combination_callback, toggle_keys)) return false; _WindowsHooked = true; diff --git a/overlay_experimental/windows/DX10_Hook.h b/overlay_experimental/windows/DX10_Hook.h index 44aebbb..cf475b0 100644 --- a/overlay_experimental/windows/DX10_Hook.h +++ b/overlay_experimental/windows/DX10_Hook.h @@ -25,7 +25,7 @@ #include class DX10_Hook : - public Renderer_Hook, + public ingame_overlay::Renderer_Hook, public Base_Hook { public: @@ -64,7 +64,7 @@ public: virtual ~DX10_Hook(); - virtual bool StartHook(std::function key_combination_callback); + virtual bool StartHook(std::function key_combination_callback, std::set toggle_keys); virtual bool IsStarted(); static DX10_Hook* Inst(); virtual std::string GetLibraryName() const; diff --git a/overlay_experimental/windows/DX11_Hook.cpp b/overlay_experimental/windows/DX11_Hook.cpp index d34524a..6f5fbec 100644 --- a/overlay_experimental/windows/DX11_Hook.cpp +++ b/overlay_experimental/windows/DX11_Hook.cpp @@ -45,7 +45,7 @@ static HRESULT GetDeviceAndCtxFromSwapchain(IDXGISwapChain* pSwapChain, ID3D11De return ret; } -bool DX11_Hook::StartHook(std::function key_combination_callback) +bool DX11_Hook::StartHook(std::function key_combination_callback, std::set toggle_keys) { if (!_Hooked) { @@ -55,7 +55,7 @@ bool DX11_Hook::StartHook(std::function key_combination_callback) return false; } - if (!Windows_Hook::Inst()->StartHook(key_combination_callback)) + if (!Windows_Hook::Inst()->StartHook(key_combination_callback, toggle_keys)) return false; _WindowsHooked = true; diff --git a/overlay_experimental/windows/DX11_Hook.h b/overlay_experimental/windows/DX11_Hook.h index 6bfbe9d..d064c13 100644 --- a/overlay_experimental/windows/DX11_Hook.h +++ b/overlay_experimental/windows/DX11_Hook.h @@ -25,7 +25,7 @@ #include class DX11_Hook : - public Renderer_Hook, + public ingame_overlay::Renderer_Hook, public Base_Hook { public: @@ -65,7 +65,7 @@ public: virtual ~DX11_Hook(); - virtual bool StartHook(std::function key_combination_callback); + virtual bool StartHook(std::function key_combination_callback, std::set toggle_keys); virtual bool IsStarted(); static DX11_Hook* Inst(); virtual std::string GetLibraryName() const; diff --git a/overlay_experimental/windows/DX12_Hook.cpp b/overlay_experimental/windows/DX12_Hook.cpp index 90e8918..b3819a1 100644 --- a/overlay_experimental/windows/DX12_Hook.cpp +++ b/overlay_experimental/windows/DX12_Hook.cpp @@ -35,7 +35,7 @@ inline void SafeRelease(T*& pUnk) } } -bool DX12_Hook::StartHook(std::function key_combination_callback) +bool DX12_Hook::StartHook(std::function key_combination_callback, std::set toggle_keys) { if (!_Hooked) { @@ -45,7 +45,7 @@ bool DX12_Hook::StartHook(std::function key_combination_callback) return false; } - if (!Windows_Hook::Inst()->StartHook(key_combination_callback)) + if (!Windows_Hook::Inst()->StartHook(key_combination_callback, toggle_keys)) return false; _WindowsHooked = true; diff --git a/overlay_experimental/windows/DX12_Hook.h b/overlay_experimental/windows/DX12_Hook.h index 1a5ce49..730a026 100644 --- a/overlay_experimental/windows/DX12_Hook.h +++ b/overlay_experimental/windows/DX12_Hook.h @@ -25,7 +25,7 @@ #include class DX12_Hook : - public Renderer_Hook, + public ingame_overlay::Renderer_Hook, public Base_Hook { public: @@ -127,7 +127,7 @@ public: virtual ~DX12_Hook(); - virtual bool StartHook(std::function key_combination_callback); + virtual bool StartHook(std::function key_combination_callback, std::set toggle_keys); virtual bool IsStarted(); static DX12_Hook* Inst(); virtual std::string GetLibraryName() const; diff --git a/overlay_experimental/windows/DX9_Hook.cpp b/overlay_experimental/windows/DX9_Hook.cpp index 5bdfb6c..90fb470 100644 --- a/overlay_experimental/windows/DX9_Hook.cpp +++ b/overlay_experimental/windows/DX9_Hook.cpp @@ -36,7 +36,7 @@ inline void SafeRelease(T*& pUnk) } } -bool DX9_Hook::StartHook(std::function key_combination_callback) +bool DX9_Hook::StartHook(std::function key_combination_callback, std::set toggle_keys) { if (!_Hooked) { @@ -46,7 +46,7 @@ bool DX9_Hook::StartHook(std::function key_combination_callback) return false; } - if (!Windows_Hook::Inst()->StartHook(key_combination_callback)) + if (!Windows_Hook::Inst()->StartHook(key_combination_callback, toggle_keys)) return false; _WindowsHooked = true; diff --git a/overlay_experimental/windows/DX9_Hook.h b/overlay_experimental/windows/DX9_Hook.h index 02d6334..a580856 100644 --- a/overlay_experimental/windows/DX9_Hook.h +++ b/overlay_experimental/windows/DX9_Hook.h @@ -24,7 +24,7 @@ #include class DX9_Hook : - public Renderer_Hook, + public ingame_overlay::Renderer_Hook, public Base_Hook { public: @@ -63,7 +63,7 @@ public: virtual ~DX9_Hook(); - virtual bool StartHook(std::function key_combination_callback); + virtual bool StartHook(std::function key_combination_callback, std::set toggle_keys); virtual bool IsStarted(); static DX9_Hook* Inst(); virtual std::string GetLibraryName() const; diff --git a/overlay_experimental/windows/OpenGL_Hook.cpp b/overlay_experimental/windows/OpenGL_Hook.cpp index b2c0085..6a258b5 100644 --- a/overlay_experimental/windows/OpenGL_Hook.cpp +++ b/overlay_experimental/windows/OpenGL_Hook.cpp @@ -27,7 +27,7 @@ OpenGL_Hook* OpenGL_Hook::_inst = nullptr; -bool OpenGL_Hook::StartHook(std::function key_combination_callback) +bool OpenGL_Hook::StartHook(std::function key_combination_callback, std::set toggle_keys) { if (!_Hooked) { @@ -37,7 +37,7 @@ bool OpenGL_Hook::StartHook(std::function key_combination_callback) return false; } - if (!Windows_Hook::Inst()->StartHook(key_combination_callback)) + if (!Windows_Hook::Inst()->StartHook(key_combination_callback, toggle_keys)) return false; _WindowsHooked = true; diff --git a/overlay_experimental/windows/OpenGL_Hook.h b/overlay_experimental/windows/OpenGL_Hook.h index bffe6ba..4d8c483 100644 --- a/overlay_experimental/windows/OpenGL_Hook.h +++ b/overlay_experimental/windows/OpenGL_Hook.h @@ -22,7 +22,7 @@ #include "../internal_includes.h" class OpenGL_Hook : - public Renderer_Hook, + public ingame_overlay::Renderer_Hook, public Base_Hook { public: @@ -56,7 +56,7 @@ public: virtual ~OpenGL_Hook(); - virtual bool StartHook(std::function key_combination_callback); + virtual bool StartHook(std::function key_combination_callback, std::set toggle_keys); virtual bool IsStarted(); static OpenGL_Hook* Inst(); virtual std::string GetLibraryName() const; diff --git a/overlay_experimental/windows/Vulkan_Hook.cpp b/overlay_experimental/windows/Vulkan_Hook.cpp index 75accdc..1eeca4a 100644 --- a/overlay_experimental/windows/Vulkan_Hook.cpp +++ b/overlay_experimental/windows/Vulkan_Hook.cpp @@ -25,7 +25,7 @@ Vulkan_Hook* Vulkan_Hook::_inst = nullptr; -bool Vulkan_Hook::StartHook(std::function key_combination_callback) +bool Vulkan_Hook::StartHook(std::function key_combination_callback, std::set toggle_keys) { SPDLOG_WARN("Vulkan overlay is not yet supported."); return false; @@ -37,7 +37,7 @@ bool Vulkan_Hook::StartHook(std::function key_combination_callback) return false; } - if (!Windows_Hook::Inst()->StartHook(key_combination_callback)) + if (!Windows_Hook::Inst()->StartHook(key_combination_callback, toggle_keys)) return false; _WindowsHooked = true; diff --git a/overlay_experimental/windows/Vulkan_Hook.h b/overlay_experimental/windows/Vulkan_Hook.h index 33eb507..d6e090f 100644 --- a/overlay_experimental/windows/Vulkan_Hook.h +++ b/overlay_experimental/windows/Vulkan_Hook.h @@ -24,7 +24,7 @@ #include class Vulkan_Hook : - public Renderer_Hook, + public ingame_overlay::Renderer_Hook, public Base_Hook { public: @@ -54,7 +54,7 @@ public: virtual ~Vulkan_Hook(); - virtual bool StartHook(std::function key_combination_callback); + virtual bool StartHook(std::function key_combination_callback, std::set toggle_keys); virtual bool IsStarted(); static Vulkan_Hook* Inst(); virtual std::string GetLibraryName() const; diff --git a/overlay_experimental/windows/Windows_Hook.cpp b/overlay_experimental/windows/Windows_Hook.cpp index 149e9da..9ae55df 100644 --- a/overlay_experimental/windows/Windows_Hook.cpp +++ b/overlay_experimental/windows/Windows_Hook.cpp @@ -29,10 +29,55 @@ constexpr decltype(Windows_Hook::DLL_NAME) Windows_Hook::DLL_NAME; Windows_Hook* Windows_Hook::_inst = nullptr; -bool Windows_Hook::StartHook(std::function& _key_combination_callback) +int ToggleKeyToNativeKey(ingame_overlay::ToggleKey k) +{ + struct { + ingame_overlay::ToggleKey lib_key; + int native_key; + } mapping[] = { + { ingame_overlay::ToggleKey::ALT , VK_MENU }, + { ingame_overlay::ToggleKey::CTRL , VK_CONTROL }, + { ingame_overlay::ToggleKey::SHIFT, VK_SHIFT }, + { ingame_overlay::ToggleKey::TAB , VK_TAB }, + { ingame_overlay::ToggleKey::F1 , VK_F1 }, + { ingame_overlay::ToggleKey::F2 , VK_F2 }, + { ingame_overlay::ToggleKey::F3 , VK_F3 }, + { ingame_overlay::ToggleKey::F4 , VK_F4 }, + { ingame_overlay::ToggleKey::F5 , VK_F5 }, + { ingame_overlay::ToggleKey::F6 , VK_F6 }, + { ingame_overlay::ToggleKey::F7 , VK_F7 }, + { ingame_overlay::ToggleKey::F8 , VK_F8 }, + { ingame_overlay::ToggleKey::F9 , VK_F9 }, + { ingame_overlay::ToggleKey::F10 , VK_F10 }, + { ingame_overlay::ToggleKey::F11 , VK_F11 }, + { ingame_overlay::ToggleKey::F12 , VK_F12 }, + }; + + for (auto const& item : mapping) + { + if (item.lib_key == k) + return item.native_key; + } + + return 0; +} + +bool Windows_Hook::StartHook(std::function& _key_combination_callback, std::set const& toggle_keys) { if (!_Hooked) { + if (!_key_combination_callback) + { + SPDLOG_ERROR("Failed to hook Windows: No key combination callback."); + return false; + } + + if (toggle_keys.empty()) + { + SPDLOG_ERROR("Failed to hook Windows: No key combination."); + return false; + } + void* hUser32 = System::Library::GetLibraryHandle(DLL_NAME); if (hUser32 == nullptr) { @@ -71,6 +116,15 @@ bool Windows_Hook::StartHook(std::function& _key_combination_callbac SPDLOG_INFO("Hooked Windows"); _KeyCombinationCallback = std::move(_key_combination_callback); + for (auto& key : toggle_keys) + { + uint32_t k = ToggleKeyToNativeKey(key); + if (k != 0) + { + _NativeKeyCombination.insert(k); + } + } + BeginHook(); HookFuncs( std::make_pair(&(PVOID&)GetRawInputBuffer, &Windows_Hook::MyGetRawInputBuffer), @@ -134,12 +188,9 @@ bool Windows_Hook::PrepareForOverlay(HWND hWnd) POINT pos; if (this->GetCursorPos(&pos) && ScreenToClient(hWnd, &pos)) { - io.MousePos = ImVec2((float)pos.x, (float)pos.y); + io.AddMousePosEvent((float)pos.x, (float)pos.y); } - io.KeyCtrl = (this->GetKeyState(VK_CONTROL) & 0x8000) != 0; - io.KeyShift = (this->GetKeyState(VK_SHIFT) & 0x8000) != 0; - io.KeyAlt = (this->GetKeyState(VK_MENU) & 0x8000) != 0; return true; } @@ -219,13 +270,18 @@ LRESULT CALLBACK Windows_Hook::HookWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, if (inst->_Initialized) { // Is the event is a key press - if (uMsg == WM_KEYDOWN) + if (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN || uMsg == WM_KEYUP || uMsg == WM_SYSKEYUP) { - // Tab is pressed and was not pressed before - if (wParam == VK_TAB && !(lParam & (1 << 30))) + int key_count = 0; + for (auto const& key : inst->_NativeKeyCombination) { - // If Left Shift is pressed - if (inst->GetAsyncKeyState(VK_LSHIFT) & (1 << 15)) + if (inst->GetAsyncKeyState(key) & (1 << 15)) + ++key_count; + } + + if (key_count == inst->_NativeKeyCombination.size()) + {// All shortcut keys are pressed + if (!inst->_KeyCombinationPushed) { if (inst->_KeyCombinationCallback(true)) { @@ -234,12 +290,13 @@ LRESULT CALLBACK Windows_Hook::HookWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, // so we can spoof the GetCursorPos return value. inst->GetCursorPos(&inst->_SavedCursorPos); } - else - { - clean_keys = true; - } + inst->_KeyCombinationPushed = true; } } + else + { + inst->_KeyCombinationPushed = false; + } } if (skip_input && IgnoreMsg(uMsg)) @@ -248,7 +305,8 @@ LRESULT CALLBACK Windows_Hook::HookWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, if (clean_keys) { auto& io = ImGui::GetIO(); - memset(io.KeysDown, 0, sizeof(io.KeysDown)); + io.ClearInputKeys(); + io.ClearInputCharacters(); } return 0; } @@ -369,6 +427,7 @@ Windows_Hook::Windows_Hook() : _RecurseCallCount(0), _GameHwnd(nullptr), _GameWndProc(nullptr), + _KeyCombinationPushed(false), GetRawInputBuffer(nullptr), GetRawInputData(nullptr), GetKeyState(nullptr), diff --git a/overlay_experimental/windows/Windows_Hook.h b/overlay_experimental/windows/Windows_Hook.h index 635d5db..c25a176 100644 --- a/overlay_experimental/windows/Windows_Hook.h +++ b/overlay_experimental/windows/Windows_Hook.h @@ -38,6 +38,12 @@ private: WNDPROC _GameWndProc; POINT _SavedCursorPos; + // In (bool): Is toggle wanted + // Out(bool): Is the overlay visible, if true, inputs will be disabled + std::function _KeyCombinationCallback; + std::set _NativeKeyCombination; + bool _KeyCombinationPushed; + // Functions Windows_Hook(); @@ -59,10 +65,6 @@ private: static BOOL WINAPI MyGetCursorPos(LPPOINT lpPoint); static BOOL WINAPI MySetCursorPos(int X, int Y); - // In (bool): Is toggle wanted - // Out(bool): Is the overlay visible, if true, inputs will be disabled - std::function _KeyCombinationCallback; - public: std::string LibraryName; @@ -75,7 +77,7 @@ public: HWND GetGameHwnd() const; WNDPROC GetGameWndProc() const; - bool StartHook(std::function& key_combination_callback); + bool StartHook(std::function& key_combination_callback, std::set const& toggle_keys); static Windows_Hook* Inst(); virtual std::string GetLibraryName() const; };