diff --git a/src/windows/dispatch_event.c b/src/windows/dispatch_event.c
index b06ebfe4..3b9e88ee 100644
--- a/src/windows/dispatch_event.c
+++ b/src/windows/dispatch_event.c
@@ -15,3 +15,461 @@
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*/
+
+#include
+
+#include "dispatch_event.h"
+#include "input_helper.h"
+#include "logger.h"
+
+// Virtual event pointer.
+static uiohook_event uio_event;
+
+// Click count globals.
+static unsigned short click_count = 0;
+static uint64_t click_time = 0;
+static unsigned short int click_button = MOUSE_NOBUTTON;
+static POINT last_click;
+
+// Event dispatch callback.
+static dispatcher_t dispatch = NULL;
+static void *dispatch_data = NULL;
+
+
+UIOHOOK_API void hook_set_dispatch_proc(dispatcher_t dispatch_proc, void *user_data) {
+ logger(LOG_LEVEL_DEBUG, "%s [%u]: Setting new dispatch callback to %#p.\n",
+ __FUNCTION__, __LINE__, dispatch_proc);
+
+ dispatch = dispatch_proc;
+ dispatch_data = user_data;
+}
+
+#ifdef USE_EPOCH_TIME
+static uint64_t get_unix_timestamp() {
+ // Get the local system time in UTC.
+ GetSystemTimeAsFileTime(&system_time);
+
+ // Convert the local system time to a Unix epoch in MS.
+ // milliseconds = 100-nanoseconds / 10000
+ uint64_t timestamp = (((uint64_t) system_time.dwHighDateTime << 32) | system_time.dwLowDateTime) / 10000;
+
+ // Convert Windows epoch to Unix epoch. (1970 - 1601 in milliseconds)
+ timestamp -= 11644473600000;
+
+ return timestamp;
+}
+#endif
+
+// Send out an event if a dispatcher was set.
+static void dispatch_event(uiohook_event *const event) {
+ if (dispatch != NULL) {
+ logger(LOG_LEVEL_DEBUG, "%s [%u]: Dispatching event type %u.\n",
+ __FUNCTION__, __LINE__, event->type);
+
+ dispatch(event, dispatch_data);
+ } else {
+ logger(LOG_LEVEL_WARN, "%s [%u]: No dispatch callback set!\n",
+ __FUNCTION__, __LINE__);
+ }
+}
+
+bool dispatch_hook_enable() {
+ bool consumed = false;
+ // Initialize native input helper functions.
+ load_input_helper();
+
+ // Get the local system time in UNIX epoch form.
+ #ifdef USE_EPOCH_TIME
+ uint64_t timestamp = get_unix_timestamp();
+ #else
+ uint64_t timestamp = GetMessageTime();
+ #endif
+
+ // Populate the hook start event.
+ uio_event.time = timestamp;
+ uio_event.reserved = 0x00;
+
+ uio_event.type = EVENT_HOOK_ENABLED;
+ uio_event.mask = 0x00;
+
+ // Fire the hook start event.
+ dispatch_event(&uio_event);
+ consumed = uio_event.reserved & 0x01;
+
+ return consumed;
+}
+
+bool dispatch_hook_disable() {
+ bool consumed = false;
+ // Get the local system time in UNIX epoch form.
+ #ifdef USE_EPOCH_TIME
+ uint64_t timestamp = get_unix_timestamp();
+ #else
+ uint64_t timestamp = GetMessageTime();
+ #endif
+
+ // Populate the hook stop event.
+ uio_event.time = timestamp;
+ uio_event.reserved = 0x00;
+
+ uio_event.type = EVENT_HOOK_DISABLED;
+ uio_event.mask = 0x00;
+
+ // Fire the hook stop event.
+ dispatch_event(&uio_event);
+ consumed = uio_event.reserved & 0x01;
+
+ // Deinitialize native input helper functions.
+ unload_input_helper();
+
+ return consumed;
+}
+
+bool dispatch_key_press(KBDLLHOOKSTRUCT *kbhook) {
+ bool consumed = false;
+ #ifdef USE_EPOCH_TIME
+ uint64_t timestamp = get_unix_timestamp();
+ #else
+ uint64_t timestamp = kbhook->time;
+ #endif
+
+ // Check and setup modifiers.
+ if (kbhook->vkCode == VK_LSHIFT) { set_modifier_mask(MASK_SHIFT_L); }
+ else if (kbhook->vkCode == VK_RSHIFT) { set_modifier_mask(MASK_SHIFT_R); }
+ else if (kbhook->vkCode == VK_LCONTROL) { set_modifier_mask(MASK_CTRL_L); }
+ else if (kbhook->vkCode == VK_RCONTROL) { set_modifier_mask(MASK_CTRL_R); }
+ else if (kbhook->vkCode == VK_LMENU) { set_modifier_mask(MASK_ALT_L); }
+ else if (kbhook->vkCode == VK_RMENU) { set_modifier_mask(MASK_ALT_R); }
+ else if (kbhook->vkCode == VK_LWIN) { set_modifier_mask(MASK_META_L); }
+ else if (kbhook->vkCode == VK_RWIN) { set_modifier_mask(MASK_META_R); }
+ else if (kbhook->vkCode == VK_NUMLOCK) { set_modifier_mask(MASK_NUM_LOCK); }
+ else if (kbhook->vkCode == VK_CAPITAL) { set_modifier_mask(MASK_CAPS_LOCK); }
+ else if (kbhook->vkCode == VK_SCROLL) { set_modifier_mask(MASK_SCROLL_LOCK); }
+
+ // Populate key pressed event.
+ uio_event.time = timestamp;
+ uio_event.reserved = 0x00;
+
+ uio_event.type = EVENT_KEY_PRESSED;
+ uio_event.mask = get_modifiers();
+
+ uio_event.data.keyboard.keycode = keycode_to_scancode(kbhook->vkCode, kbhook->flags);
+ uio_event.data.keyboard.rawcode = (uint16_t) kbhook->vkCode;
+ uio_event.data.keyboard.keychar = CHAR_UNDEFINED;
+
+ logger(LOG_LEVEL_DEBUG, "%s [%u]: Key %#X pressed. (%#X)\n",
+ __FUNCTION__, __LINE__,
+ uio_event.data.keyboard.keycode, uio_event.data.keyboard.rawcode);
+
+ // Populate key pressed event.
+ dispatch_event(&uio_event);
+ consumed = uio_event.reserved & 0x01;
+
+ // If the pressed event was not consumed...
+ if (!consumed) {
+ // Buffer for unicode typed chars. No more than 2 needed.
+ WCHAR buffer[2]; // = { WCH_NONE };
+
+ // If the pressed event was not consumed and a unicode char exists...
+ SIZE_T count = keycode_to_unicode(kbhook->vkCode, buffer, sizeof(buffer));
+ for (unsigned int i = 0; i < count; i++) {
+ // Populate key typed event.
+ uio_event.time = timestamp;
+ uio_event.reserved = 0x00;
+
+ uio_event.type = EVENT_KEY_TYPED;
+ uio_event.mask = get_modifiers();
+
+ uio_event.data.keyboard.keycode = VC_UNDEFINED;
+ uio_event.data.keyboard.rawcode = (uint16_t) kbhook->vkCode;
+ uio_event.data.keyboard.keychar = buffer[i];
+
+ logger(LOG_LEVEL_DEBUG, "%s [%u]: Key %#X typed. (%lc)\n",
+ __FUNCTION__, __LINE__,
+ uio_event.data.keyboard.keycode, (wint_t) uio_event.data.keyboard.keychar);
+
+ // Fire key typed event.
+ dispatch_event(&uio_event);
+ consumed = uio_event.reserved & 0x01;
+ }
+ }
+
+ return consumed;
+}
+
+bool dispatch_key_release(KBDLLHOOKSTRUCT *kbhook) {
+ bool consumed = false;
+ #ifdef USE_EPOCH_TIME
+ uint64_t timestamp = get_unix_timestamp();
+ #else
+ uint64_t timestamp = kbhook->time;
+ #endif
+
+ // Check and setup modifiers.
+ if (kbhook->vkCode == VK_LSHIFT) { unset_modifier_mask(MASK_SHIFT_L); }
+ else if (kbhook->vkCode == VK_RSHIFT) { unset_modifier_mask(MASK_SHIFT_R); }
+ else if (kbhook->vkCode == VK_LCONTROL) { unset_modifier_mask(MASK_CTRL_L); }
+ else if (kbhook->vkCode == VK_RCONTROL) { unset_modifier_mask(MASK_CTRL_R); }
+ else if (kbhook->vkCode == VK_LMENU) { unset_modifier_mask(MASK_ALT_L); }
+ else if (kbhook->vkCode == VK_RMENU) { unset_modifier_mask(MASK_ALT_R); }
+ else if (kbhook->vkCode == VK_LWIN) { unset_modifier_mask(MASK_META_L); }
+ else if (kbhook->vkCode == VK_RWIN) { unset_modifier_mask(MASK_META_R); }
+ else if (kbhook->vkCode == VK_NUMLOCK) { unset_modifier_mask(MASK_NUM_LOCK); }
+ else if (kbhook->vkCode == VK_CAPITAL) { unset_modifier_mask(MASK_CAPS_LOCK); }
+ else if (kbhook->vkCode == VK_SCROLL) { unset_modifier_mask(MASK_SCROLL_LOCK); }
+
+ // Populate key pressed event.
+ uio_event.time = timestamp;
+ uio_event.reserved = 0x00;
+
+ uio_event.type = EVENT_KEY_RELEASED;
+ uio_event.mask = get_modifiers();
+
+ uio_event.data.keyboard.keycode = keycode_to_scancode(kbhook->vkCode, kbhook->flags);
+ uio_event.data.keyboard.rawcode = (uint16_t) kbhook->vkCode;
+ uio_event.data.keyboard.keychar = CHAR_UNDEFINED;
+
+ logger(LOG_LEVEL_DEBUG, "%s [%u]: Key %#X released. (%#X)\n",
+ __FUNCTION__, __LINE__,
+ uio_event.data.keyboard.keycode, uio_event.data.keyboard.rawcode);
+
+ // Fire key released event.
+ dispatch_event(&uio_event);
+ consumed = uio_event.reserved & 0x01;
+
+ return consumed;
+}
+
+bool dispatch_button_press(MSLLHOOKSTRUCT *mshook, uint16_t button) {
+ bool consumed = false;
+ #ifdef USE_EPOCH_TIME
+ uint64_t timestamp = get_unix_timestamp();
+ #else
+ uint64_t timestamp = mshook->time;
+ #endif
+
+ // Track the number of clicks, the button must match the previous button.
+ if (button == click_button && (long int) (timestamp - click_time) <= hook_get_multi_click_time()) {
+ if (click_count < USHRT_MAX) {
+ click_count++;
+ } else {
+ logger(LOG_LEVEL_WARN, "%s [%u]: Click count overflow detected!\n",
+ __FUNCTION__, __LINE__);
+ }
+ } else {
+ // Reset the click count.
+ click_count = 1;
+
+ // Set the previous button.
+ click_button = button;
+ }
+
+ // Save this events time to calculate the click_count.
+ click_time = timestamp;
+
+ // Store the last click point.
+ last_click.x = mshook->pt.x;
+ last_click.y = mshook->pt.y;
+
+ // Populate mouse pressed event.
+ uio_event.time = timestamp;
+ uio_event.reserved = 0x00;
+
+ uio_event.type = EVENT_MOUSE_PRESSED;
+ uio_event.mask = get_modifiers();
+
+ uio_event.data.mouse.button = button;
+ uio_event.data.mouse.clicks = click_count;
+
+ uio_event.data.mouse.x = (int16_t) mshook->pt.x;
+ uio_event.data.mouse.y = (int16_t) mshook->pt.y;
+
+ logger(LOG_LEVEL_DEBUG, "%s [%u]: Button %u pressed %u time(s). (%u, %u)\n",
+ __FUNCTION__, __LINE__,
+ uio_event.data.mouse.button, uio_event.data.mouse.clicks,
+ uio_event.data.mouse.x, uio_event.data.mouse.y);
+
+ // Fire mouse pressed event.
+ dispatch_event(&uio_event);
+ consumed = uio_event.reserved & 0x01;
+
+ return consumed;
+}
+
+bool dispatch_button_release(MSLLHOOKSTRUCT *mshook, uint16_t button) {
+ bool consumed = false;
+ #ifdef USE_EPOCH_TIME
+ uint64_t timestamp = get_unix_timestamp();
+ #else
+ uint64_t timestamp = mshook->time;
+ #endif
+
+ // Populate mouse released event.
+ uio_event.time = timestamp;
+ uio_event.reserved = 0x00;
+
+ uio_event.type = EVENT_MOUSE_RELEASED;
+ uio_event.mask = get_modifiers();
+
+ uio_event.data.mouse.button = button;
+ uio_event.data.mouse.clicks = click_count;
+
+ uio_event.data.mouse.x = (int16_t) mshook->pt.x;
+ uio_event.data.mouse.y = (int16_t) mshook->pt.y;
+
+ logger(LOG_LEVEL_DEBUG, "%s [%u]: Button %u released %u time(s). (%u, %u)\n",
+ __FUNCTION__, __LINE__,
+ uio_event.data.mouse.button, uio_event.data.mouse.clicks,
+ uio_event.data.mouse.x, uio_event.data.mouse.y);
+
+ // Fire mouse released event.
+ dispatch_event(&uio_event);
+ consumed = uio_event.reserved & 0x01;
+
+ // If the pressed event was not consumed...
+ if (!consumed && last_click.x == mshook->pt.x && last_click.y == mshook->pt.y) {
+ // Populate mouse clicked event.
+ uio_event.time = timestamp;
+ uio_event.reserved = 0x00;
+
+ uio_event.type = EVENT_MOUSE_CLICKED;
+ uio_event.mask = get_modifiers();
+
+ uio_event.data.mouse.button = button;
+ uio_event.data.mouse.clicks = click_count;
+ uio_event.data.mouse.x = (int16_t) mshook->pt.x;
+ uio_event.data.mouse.y = (int16_t) mshook->pt.y;
+
+ logger(LOG_LEVEL_DEBUG, "%s [%u]: Button %u clicked %u time(s). (%u, %u)\n",
+ __FUNCTION__, __LINE__,
+ uio_event.data.mouse.button, uio_event.data.mouse.clicks,
+ uio_event.data.mouse.x, uio_event.data.mouse.y);
+
+ // Fire mouse clicked event.
+ dispatch_event(&uio_event);
+ consumed = uio_event.reserved & 0x01;
+ }
+
+ // Reset the number of clicks.
+ if (button == click_button && (long int) (timestamp - click_time) > hook_get_multi_click_time()) {
+ // Reset the click count.
+ click_count = 0;
+ }
+
+ return consumed;
+}
+
+
+bool dispatch_mouse_move(MSLLHOOKSTRUCT *mshook) {
+ bool consumed = false;
+ #ifdef USE_EPOCH_TIME
+ uint64_t timestamp = get_unix_timestamp();
+ #else
+ uint64_t timestamp = mshook->time;
+ #endif
+
+ // We received a mouse move event with the mouse actually moving.
+ // This verifies that the mouse was moved after being depressed.
+ if (last_click.x != mshook->pt.x || last_click.y != mshook->pt.y) {
+ // Reset the click count.
+ if (click_count != 0 && (long) (timestamp - click_time) > hook_get_multi_click_time()) {
+ click_count = 0;
+ }
+
+ // Populate mouse move event.
+ uio_event.time = timestamp;
+ uio_event.reserved = 0x00;
+
+ uio_event.mask = get_modifiers();
+
+ // Check the modifier mask range for MASK_BUTTON1 - 5.
+ bool mouse_dragged = uio_event.mask & (MASK_BUTTON1 | MASK_BUTTON2 | MASK_BUTTON3 | MASK_BUTTON4 | MASK_BUTTON5);
+ if (mouse_dragged) {
+ // Create Mouse Dragged event.
+ uio_event.type = EVENT_MOUSE_DRAGGED;
+ } else {
+ // Create a Mouse Moved event.
+ uio_event.type = EVENT_MOUSE_MOVED;
+ }
+
+ uio_event.data.mouse.button = MOUSE_NOBUTTON;
+ uio_event.data.mouse.clicks = click_count;
+ uio_event.data.mouse.x = (int16_t) mshook->pt.x;
+ uio_event.data.mouse.y = (int16_t) mshook->pt.y;
+
+ logger(LOG_LEVEL_DEBUG, "%s [%u]: Mouse %s to %u, %u.\n",
+ __FUNCTION__, __LINE__,
+ mouse_dragged ? "dragged" : "moved",
+ uio_event.data.mouse.x, uio_event.data.mouse.y);
+
+ // Fire mouse move event.
+ dispatch_event(&uio_event);
+ consumed = uio_event.reserved & 0x01;
+ }
+
+ return consumed;
+}
+
+bool dispatch_mouse_wheel(MSLLHOOKSTRUCT *mshook, uint8_t direction) {
+ bool consumed = false;
+ #ifdef USE_EPOCH_TIME
+ uint64_t timestamp = get_unix_timestamp();
+ #else
+ uint64_t timestamp = mshook->time;
+ #endif
+
+ // Track the number of clicks.
+ // Reset the click count and previous button.
+ click_count = 1;
+ click_button = MOUSE_NOBUTTON;
+
+ // Populate mouse wheel event.
+ uio_event.time = timestamp;
+ uio_event.reserved = 0x00;
+
+ uio_event.type = EVENT_MOUSE_WHEEL;
+ uio_event.mask = get_modifiers();
+
+ uio_event.data.wheel.clicks = click_count;
+ uio_event.data.wheel.x = (int16_t) mshook->pt.x;
+ uio_event.data.wheel.y = (int16_t) mshook->pt.y;
+
+ uio_event.data.wheel.rotation = get_scroll_wheel_rotation(mshook->mouseData, direction);
+
+ UINT uiAction = SPI_GETWHEELSCROLLCHARS;
+ if (direction == WHEEL_VERTICAL_DIRECTION) {
+ uiAction = SPI_GETWHEELSCROLLLINES;
+ }
+
+ UINT wheel_amount = 3;
+ if (SystemParametersInfo(uiAction, 0, &wheel_amount, 0)) {
+ if (wheel_amount == WHEEL_PAGESCROLL) {
+ uio_event.data.wheel.type = WHEEL_BLOCK_SCROLL;
+ uio_event.data.wheel.amount = 1;
+ } else {
+ uio_event.data.wheel.type = WHEEL_UNIT_SCROLL;
+ uio_event.data.wheel.amount = (uint16_t) wheel_amount;
+ }
+
+ // Set the direction based on what event was received.
+ uio_event.data.wheel.direction = direction;
+
+ logger(LOG_LEVEL_DEBUG, "%s [%u]: Mouse wheel type %u, rotated %i units in the %u direction at %u, %u.\n",
+ __FUNCTION__, __LINE__,
+ uio_event.data.wheel.type,
+ uio_event.data.wheel.amount * uio_event.data.wheel.rotation,
+ uio_event.data.wheel.direction,
+ uio_event.data.wheel.x, uio_event.data.wheel.y);
+
+ // Fire mouse wheel event.
+ dispatch_event(&uio_event);
+ consumed = uio_event.reserved & 0x01;
+ } else {
+ logger(LOG_LEVEL_WARN, "%s [%u]: SystemParametersInfo() failed, event will be consumed.\n",
+ __FUNCTION__, __LINE__);
+
+ consumed = true;
+ }
+
+ return consumed;
+}
diff --git a/src/windows/dispatch_event.h b/src/windows/dispatch_event.h
index b06ebfe4..3ac9edf0 100644
--- a/src/windows/dispatch_event.h
+++ b/src/windows/dispatch_event.h
@@ -15,3 +15,22 @@
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*/
+
+#include
+#include
+
+extern bool dispatch_hook_enable();
+
+extern bool dispatch_hook_disable();
+
+extern bool dispatch_key_press(KBDLLHOOKSTRUCT *kbhook);
+
+extern bool dispatch_key_release(KBDLLHOOKSTRUCT *kbhook);
+
+extern bool dispatch_button_press(MSLLHOOKSTRUCT *mshook, uint16_t button);
+
+extern bool dispatch_button_release(MSLLHOOKSTRUCT *mshook, uint16_t button);
+
+extern bool dispatch_mouse_move(MSLLHOOKSTRUCT *mshook);
+
+extern bool dispatch_mouse_wheel(MSLLHOOKSTRUCT *mshook, uint8_t direction);
diff --git a/src/windows/input_helper.c b/src/windows/input_helper.c
index 4d0afb9a..c2225f84 100644
--- a/src/windows/input_helper.c
+++ b/src/windows/input_helper.c
@@ -27,6 +27,9 @@
#include "logger.h"
#include "input_helper.h"
+
+static uint16_t modifier_mask;
+
static const uint16_t keycode_scancode_table[][2] = {
/* idx { vk_code, scancode }, */
/* 0 */ { VC_UNDEFINED, 0x0000 }, // 0x00
@@ -255,10 +258,10 @@ static const uint16_t keycode_scancode_table[][2] = {
/* 220 */ { VC_BACK_SLASH, VK_RWIN }, // 0xDC VK_OEM_5 Varies by keyboard. For the US standard keyboard, the '\|' key
/* 221 */ { VC_CLOSE_BRACKET, VK_APPS }, // 0xDD VK_OEM_6 Varies by keyboard. For the US standard keyboard, the ']}' key
/* 222 */ { VC_QUOTE, 0x0000 }, // 0xDE VK_OEM_7 Varies by keyboard. For the US standard keyboard, the 'single-quote/double-quote' key
- /* 223 */ { VC_YEN, VK_SLEEP }, // 0xDF VK_OEM_8 Varies by keyboard.
+ /* 223 */ { VC_UNDEFINED, VK_SLEEP }, // 0xDF VK_OEM_8 Varies by keyboard.
/* 224 */ { VC_UNDEFINED, 0x0000 }, // 0xE0 Reserved
/* 225 */ { VC_UNDEFINED, 0x0000 }, // 0xE1 OEM specific
- /* 226 */ { VC_LESSER_GREATER, VK_OEM_102 }, // 0xE2 VK_OEM_102 Either the angle bracket key or the backslash key on the RT 102-key keyboard
+ /* 226 */ { VC_UNDEFINED, VK_OEM_102 }, // 0xE2 VK_OEM_102 Either the angle bracket key or the backslash key on the RT 102-key keyboard
/* 227 */ { VC_UNDEFINED, 0x0000 }, // 0xE3 OEM specific
/* 228 */ { VC_UNDEFINED, 0x00E5 }, // 0xE4 VC_APP_PICTURES OEM specific
/* 229 */ { VC_APP_PICTURES, VK_BROWSER_SEARCH }, // 0xE5 VK_PROCESSKEY IME PROCESS key
@@ -286,7 +289,7 @@ static const uint16_t keycode_scancode_table[][2] = {
/* 251 */ { VC_UNDEFINED, 0x0000 }, // 0xFB VK_ZOOM Zoom key
/* 252 */ { VC_UNDEFINED, 0x0000 }, // 0xFC VK_NONAME Reserved
/* 253 */ { VC_UNDEFINED, 0x0000 }, // 0xFD
- /* 254 */ { VC_CLEAR, 0x0000 }, // 0xFE VK_OEM_CLEAR Clear key
+ /* 254 */ { VC_KP_CLEAR, 0x0000 }, // 0xFE VK_OEM_CLEAR Clear key
/* 255 */ { VC_UNDEFINED, 0x0000 } // 0xFE Unassigned
};
@@ -349,6 +352,18 @@ DWORD scancode_to_keycode(unsigned short scancode) {
return keycode;
}
+void set_modifier_mask(uint16_t mask) {
+ modifier_mask |= mask;
+}
+
+void unset_modifier_mask(uint16_t mask) {
+ modifier_mask &= ~mask;
+}
+
+uint16_t get_modifiers() {
+ return modifier_mask;
+}
+
/* Track the amount of vertical and horizontal rotation between "clicks."
* This is between mouse wheel delta. */
static int16_t v_rotation, h_rotation;
diff --git a/src/windows/input_helper.h b/src/windows/input_helper.h
index bfff4c0f..1a4273c8 100644
--- a/src/windows/input_helper.h
+++ b/src/windows/input_helper.h
@@ -134,6 +134,15 @@ extern unsigned short keycode_to_scancode(DWORD vk_code, DWORD flags);
extern DWORD scancode_to_keycode(unsigned short scancode);
+/* Set the native modifier mask for future events. */
+extern void set_modifier_mask(uint16_t mask);
+
+/* Unset the native modifier mask for future events. */
+extern void unset_modifier_mask(uint16_t mask);
+
+/* Get the current native modifier mask state. */
+extern uint16_t get_modifiers();
+
/* Help track how much rotation should be applied to a scroll wheel event. */
extern int16_t get_scroll_wheel_rotation(DWORD data, uint8_t direction);
diff --git a/src/windows/input_hook.c b/src/windows/input_hook.c
index 2e053427..10e8f5b9 100644
--- a/src/windows/input_hook.c
+++ b/src/windows/input_hook.c
@@ -20,6 +20,7 @@
#include
#include
+#include "dispatch_event.h"
#include "input_helper.h"
#include "logger.h"
@@ -39,56 +40,6 @@ static unsigned short int current_modifiers = 0x0000;
static FILETIME system_time;
#endif
-// Click count globals.
-static unsigned short click_count = 0;
-static uint64_t click_time = 0;
-static unsigned short int click_button = MOUSE_NOBUTTON;
-static POINT last_click;
-
-// Static event memory.
-static uiohook_event event;
-
-// Event dispatch callback.
-static dispatcher_t dispatch = NULL;
-static void *dispatch_data = NULL;
-
-UIOHOOK_API void hook_set_dispatch_proc(dispatcher_t dispatch_proc, void *user_data) {
- logger(LOG_LEVEL_DEBUG, "%s [%u]: Setting new dispatch callback to %#p.\n",
- __FUNCTION__, __LINE__, dispatch_proc);
-
- dispatch = dispatch_proc;
- dispatch_data = user_data;
-}
-
-// Send out an event if a dispatcher was set.
-static void dispatch_event(uiohook_event *const event) {
- if (dispatch != NULL) {
- logger(LOG_LEVEL_DEBUG, "%s [%u]: Dispatching event type %u.\n",
- __FUNCTION__, __LINE__, event->type);
-
- dispatch(event, dispatch_data);
- } else {
- logger(LOG_LEVEL_WARN, "%s [%u]: No dispatch callback set!\n",
- __FUNCTION__, __LINE__);
- }
-}
-
-
-// Set the native modifier mask for future events.
-static inline void set_modifier_mask(unsigned short int mask) {
- current_modifiers |= mask;
-}
-
-// Unset the native modifier mask for future events.
-static inline void unset_modifier_mask(unsigned short int mask) {
- current_modifiers &= ~mask;
-}
-
-// Get the current native modifier mask state.
-static inline unsigned short int get_modifiers() {
- return current_modifiers;
-}
-
// Initialize the modifier mask to the current modifiers.
static void initialize_modifiers() {
current_modifiers = 0x0000;
@@ -114,23 +65,6 @@ static void initialize_modifiers() {
if (GetKeyState(VK_SCROLL) < 0) { set_modifier_mask(MASK_SCROLL_LOCK); }
}
-
-#ifdef USE_EPOCH_TIME
-static inline uint64_t get_unix_timestamp() {
- // Get the local system time in UTC.
- GetSystemTimeAsFileTime(&system_time);
-
- // Convert the local system time to a Unix epoch in MS.
- // milliseconds = 100-nanoseconds / 10000
- uint64_t timestamp = (((uint64_t) system_time.dwHighDateTime << 32) | system_time.dwLowDateTime) / 10000;
-
- // Convert Windows epoch to Unix epoch. (1970 - 1601 in milliseconds)
- timestamp -= 11644473600000;
-
- return timestamp;
-}
-#endif
-
void unregister_running_hooks() {
// Stop the event hook and any timer still running.
if (win_event_hhook != NULL) {
@@ -150,164 +84,19 @@ void unregister_running_hooks() {
}
}
-void hook_start_proc() {
- // Initialize native input helper functions.
- load_input_helper();
-
- // Get the local system time in UNIX epoch form.
- #ifdef USE_EPOCH_TIME
- uint64_t timestamp = get_unix_timestamp();
- #else
- uint64_t timestamp = GetMessageTime();
- #endif
-
- // Populate the hook start event.
- event.time = timestamp;
- event.reserved = 0x00;
-
- event.type = EVENT_HOOK_ENABLED;
- event.mask = 0x00;
-
- // Fire the hook start event.
- dispatch_event(&event);
-}
-
-void hook_stop_proc() {
- // Get the local system time in UNIX epoch form.
- #ifdef USE_EPOCH_TIME
- uint64_t timestamp = get_unix_timestamp();
- #else
- uint64_t timestamp = GetMessageTime();
- #endif
-
- // Populate the hook stop event.
- event.time = timestamp;
- event.reserved = 0x00;
-
- event.type = EVENT_HOOK_DISABLED;
- event.mask = 0x00;
-
- // Fire the hook stop event.
- dispatch_event(&event);
-
- // Deinitialize native input helper functions.
- unload_input_helper();
-}
-
-static void process_key_pressed(KBDLLHOOKSTRUCT *kbhook) {
- #ifdef USE_EPOCH_TIME
- uint64_t timestamp = get_unix_timestamp();
- #else
- uint64_t timestamp = kbhook->time;
- #endif
-
- // Check and setup modifiers.
- if (kbhook->vkCode == VK_LSHIFT) { set_modifier_mask(MASK_SHIFT_L); }
- else if (kbhook->vkCode == VK_RSHIFT) { set_modifier_mask(MASK_SHIFT_R); }
- else if (kbhook->vkCode == VK_LCONTROL) { set_modifier_mask(MASK_CTRL_L); }
- else if (kbhook->vkCode == VK_RCONTROL) { set_modifier_mask(MASK_CTRL_R); }
- else if (kbhook->vkCode == VK_LMENU) { set_modifier_mask(MASK_ALT_L); }
- else if (kbhook->vkCode == VK_RMENU) { set_modifier_mask(MASK_ALT_R); }
- else if (kbhook->vkCode == VK_LWIN) { set_modifier_mask(MASK_META_L); }
- else if (kbhook->vkCode == VK_RWIN) { set_modifier_mask(MASK_META_R); }
- else if (kbhook->vkCode == VK_NUMLOCK) { set_modifier_mask(MASK_NUM_LOCK); }
- else if (kbhook->vkCode == VK_CAPITAL) { set_modifier_mask(MASK_CAPS_LOCK); }
- else if (kbhook->vkCode == VK_SCROLL) { set_modifier_mask(MASK_SCROLL_LOCK); }
-
- // Populate key pressed event.
- event.time = timestamp;
- event.reserved = 0x00;
-
- event.type = EVENT_KEY_PRESSED;
- event.mask = get_modifiers();
-
- event.data.keyboard.keycode = keycode_to_scancode(kbhook->vkCode, kbhook->flags);
- event.data.keyboard.rawcode = (uint16_t) kbhook->vkCode;
- event.data.keyboard.keychar = CHAR_UNDEFINED;
-
- logger(LOG_LEVEL_DEBUG, "%s [%u]: Key %#X pressed. (%#X)\n",
- __FUNCTION__, __LINE__, event.data.keyboard.keycode, event.data.keyboard.rawcode);
-
- // Populate key pressed event.
- dispatch_event(&event);
-
- // If the pressed event was not consumed...
- if (event.reserved ^ 0x01) {
- // Buffer for unicode typed chars. No more than 2 needed.
- WCHAR buffer[2]; // = { WCH_NONE };
-
- // If the pressed event was not consumed and a unicode char exists...
- SIZE_T count = keycode_to_unicode(kbhook->vkCode, buffer, sizeof(buffer));
- for (unsigned int i = 0; i < count; i++) {
- // Populate key typed event.
- event.time = timestamp;
- event.reserved = 0x00;
-
- event.type = EVENT_KEY_TYPED;
- event.mask = get_modifiers();
-
- event.data.keyboard.keycode = VC_UNDEFINED;
- event.data.keyboard.rawcode = (uint16_t) kbhook->vkCode;
- event.data.keyboard.keychar = buffer[i];
-
- logger(LOG_LEVEL_DEBUG, "%s [%u]: Key %#X typed. (%lc)\n",
- __FUNCTION__, __LINE__, event.data.keyboard.keycode, (wint_t) event.data.keyboard.keychar);
-
- // Fire key typed event.
- dispatch_event(&event);
- }
- }
-}
-
-static void process_key_released(KBDLLHOOKSTRUCT *kbhook) {
- #ifdef USE_EPOCH_TIME
- uint64_t timestamp = get_unix_timestamp();
- #else
- uint64_t timestamp = kbhook->time;
- #endif
-
- // Check and setup modifiers.
- if (kbhook->vkCode == VK_LSHIFT) { unset_modifier_mask(MASK_SHIFT_L); }
- else if (kbhook->vkCode == VK_RSHIFT) { unset_modifier_mask(MASK_SHIFT_R); }
- else if (kbhook->vkCode == VK_LCONTROL) { unset_modifier_mask(MASK_CTRL_L); }
- else if (kbhook->vkCode == VK_RCONTROL) { unset_modifier_mask(MASK_CTRL_R); }
- else if (kbhook->vkCode == VK_LMENU) { unset_modifier_mask(MASK_ALT_L); }
- else if (kbhook->vkCode == VK_RMENU) { unset_modifier_mask(MASK_ALT_R); }
- else if (kbhook->vkCode == VK_LWIN) { unset_modifier_mask(MASK_META_L); }
- else if (kbhook->vkCode == VK_RWIN) { unset_modifier_mask(MASK_META_R); }
- else if (kbhook->vkCode == VK_NUMLOCK) { unset_modifier_mask(MASK_NUM_LOCK); }
- else if (kbhook->vkCode == VK_CAPITAL) { unset_modifier_mask(MASK_CAPS_LOCK); }
- else if (kbhook->vkCode == VK_SCROLL) { unset_modifier_mask(MASK_SCROLL_LOCK); }
-
- // Populate key pressed event.
- event.time = timestamp;
- event.reserved = 0x00;
-
- event.type = EVENT_KEY_RELEASED;
- event.mask = get_modifiers();
-
- event.data.keyboard.keycode = keycode_to_scancode(kbhook->vkCode, kbhook->flags);
- event.data.keyboard.rawcode = (uint16_t) kbhook->vkCode;
- event.data.keyboard.keychar = CHAR_UNDEFINED;
-
- logger(LOG_LEVEL_DEBUG, "%s [%u]: Key %#X released. (%#X)\n",
- __FUNCTION__, __LINE__, event.data.keyboard.keycode, event.data.keyboard.rawcode);
-
- // Fire key released event.
- dispatch_event(&event);
-}
-
LRESULT CALLBACK keyboard_hook_event_proc(int nCode, WPARAM wParam, LPARAM lParam) {
+ bool consumed = false;
+
KBDLLHOOKSTRUCT *kbhook = (KBDLLHOOKSTRUCT *) lParam;
switch (wParam) {
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
- process_key_pressed(kbhook);
+ consumed = dispatch_key_press(kbhook);
break;
case WM_KEYUP:
case WM_SYSKEYUP:
- process_key_released(kbhook);
+ consumed = dispatch_key_release(kbhook);
break;
default:
@@ -318,7 +107,7 @@ LRESULT CALLBACK keyboard_hook_event_proc(int nCode, WPARAM wParam, LPARAM lPara
}
LRESULT hook_result = -1;
- if (nCode < 0 || event.reserved ^ 0x01) {
+ if (nCode < 0 || !consumed) {
hook_result = CallNextHookEx(keyboard_event_hhook, nCode, wParam, lParam);
} else {
logger(LOG_LEVEL_DEBUG, "%s [%u]: Consuming the current event. (%li)\n",
@@ -328,245 +117,34 @@ LRESULT CALLBACK keyboard_hook_event_proc(int nCode, WPARAM wParam, LPARAM lPara
return hook_result;
}
-
-static void process_button_pressed(MSLLHOOKSTRUCT *mshook, uint16_t button) {
- #ifdef USE_EPOCH_TIME
- uint64_t timestamp = get_unix_timestamp();
- #else
- uint64_t timestamp = mshook->time;
- #endif
-
- // Track the number of clicks, the button must match the previous button.
- if (button == click_button && (long int) (timestamp - click_time) <= hook_get_multi_click_time()) {
- if (click_count < USHRT_MAX) {
- click_count++;
- } else {
- logger(LOG_LEVEL_WARN, "%s [%u]: Click count overflow detected!\n",
- __FUNCTION__, __LINE__);
- }
- } else {
- // Reset the click count.
- click_count = 1;
-
- // Set the previous button.
- click_button = button;
- }
-
- // Save this events time to calculate the click_count.
- click_time = timestamp;
-
- // Store the last click point.
- last_click.x = mshook->pt.x;
- last_click.y = mshook->pt.y;
-
- // Populate mouse pressed event.
- event.time = timestamp;
- event.reserved = 0x00;
-
- event.type = EVENT_MOUSE_PRESSED;
- event.mask = get_modifiers();
-
- event.data.mouse.button = button;
- event.data.mouse.clicks = click_count;
-
- event.data.mouse.x = (int16_t) mshook->pt.x;
- event.data.mouse.y = (int16_t) mshook->pt.y;
-
- logger(LOG_LEVEL_DEBUG, "%s [%u]: Button %u pressed %u time(s). (%u, %u)\n",
- __FUNCTION__, __LINE__, event.data.mouse.button, event.data.mouse.clicks,
- event.data.mouse.x, event.data.mouse.y);
-
- // Fire mouse pressed event.
- dispatch_event(&event);
-}
-
-static void process_button_released(MSLLHOOKSTRUCT *mshook, uint16_t button) {
- #ifdef USE_EPOCH_TIME
- uint64_t timestamp = get_unix_timestamp();
- #else
- uint64_t timestamp = mshook->time;
- #endif
-
- // Populate mouse released event.
- event.time = timestamp;
- event.reserved = 0x00;
-
- event.type = EVENT_MOUSE_RELEASED;
- event.mask = get_modifiers();
-
- event.data.mouse.button = button;
- event.data.mouse.clicks = click_count;
-
- event.data.mouse.x = (int16_t) mshook->pt.x;
- event.data.mouse.y = (int16_t) mshook->pt.y;
-
- logger(LOG_LEVEL_DEBUG, "%s [%u]: Button %u released %u time(s). (%u, %u)\n",
- __FUNCTION__, __LINE__, event.data.mouse.button,
- event.data.mouse.clicks,
- event.data.mouse.x, event.data.mouse.y);
-
- // Fire mouse released event.
- dispatch_event(&event);
-
- // If the pressed event was not consumed...
- if (event.reserved ^ 0x01 && last_click.x == mshook->pt.x && last_click.y == mshook->pt.y) {
- // Populate mouse clicked event.
- event.time = timestamp;
- event.reserved = 0x00;
-
- event.type = EVENT_MOUSE_CLICKED;
- event.mask = get_modifiers();
-
- event.data.mouse.button = button;
- event.data.mouse.clicks = click_count;
- event.data.mouse.x = (int16_t) mshook->pt.x;
- event.data.mouse.y = (int16_t) mshook->pt.y;
-
- logger(LOG_LEVEL_DEBUG, "%s [%u]: Button %u clicked %u time(s). (%u, %u)\n",
- __FUNCTION__, __LINE__, event.data.mouse.button, event.data.mouse.clicks,
- event.data.mouse.x, event.data.mouse.y);
-
- // Fire mouse clicked event.
- dispatch_event(&event);
- }
-
- // Reset the number of clicks.
- if (button == click_button && (long int) (timestamp - click_time) > hook_get_multi_click_time()) {
- // Reset the click count.
- click_count = 0;
- }
-}
-
-static void process_mouse_moved(MSLLHOOKSTRUCT *mshook) {
- #ifdef USE_EPOCH_TIME
- uint64_t timestamp = get_unix_timestamp();
- #else
- uint64_t timestamp = mshook->time;
- #endif
-
- // We received a mouse move event with the mouse actually moving.
- // This verifies that the mouse was moved after being depressed.
- if (last_click.x != mshook->pt.x || last_click.y != mshook->pt.y) {
- // Reset the click count.
- if (click_count != 0 && (long) (timestamp - click_time) > hook_get_multi_click_time()) {
- click_count = 0;
- }
-
- // Populate mouse move event.
- event.time = timestamp;
- event.reserved = 0x00;
-
- event.mask = get_modifiers();
-
- // Check the modifier mask range for MASK_BUTTON1 - 5.
- bool mouse_dragged = event.mask & (MASK_BUTTON1 | MASK_BUTTON2 | MASK_BUTTON3 | MASK_BUTTON4 | MASK_BUTTON5);
- if (mouse_dragged) {
- // Create Mouse Dragged event.
- event.type = EVENT_MOUSE_DRAGGED;
- } else {
- // Create a Mouse Moved event.
- event.type = EVENT_MOUSE_MOVED;
- }
-
- event.data.mouse.button = MOUSE_NOBUTTON;
- event.data.mouse.clicks = click_count;
- event.data.mouse.x = (int16_t) mshook->pt.x;
- event.data.mouse.y = (int16_t) mshook->pt.y;
-
- logger(LOG_LEVEL_DEBUG, "%s [%u]: Mouse %s to %u, %u.\n",
- __FUNCTION__, __LINE__, mouse_dragged ? "dragged" : "moved",
- event.data.mouse.x, event.data.mouse.y);
-
- // Fire mouse move event.
- dispatch_event(&event);
- }
-}
-
-static void process_mouse_wheel(MSLLHOOKSTRUCT *mshook, uint8_t direction) {
- #ifdef USE_EPOCH_TIME
- uint64_t timestamp = get_unix_timestamp();
- #else
- uint64_t timestamp = mshook->time;
- #endif
-
- // Track the number of clicks.
- // Reset the click count and previous button.
- click_count = 1;
- click_button = MOUSE_NOBUTTON;
-
- // Populate mouse wheel event.
- event.time = timestamp;
- event.reserved = 0x00;
-
- event.type = EVENT_MOUSE_WHEEL;
- event.mask = get_modifiers();
-
- event.data.wheel.clicks = click_count;
- event.data.wheel.x = (int16_t) mshook->pt.x;
- event.data.wheel.y = (int16_t) mshook->pt.y;
-
- event.data.wheel.rotation = get_scroll_wheel_rotation(mshook->mouseData, direction);
-
- UINT uiAction = SPI_GETWHEELSCROLLCHARS;
- if (direction == WHEEL_VERTICAL_DIRECTION) {
- uiAction = SPI_GETWHEELSCROLLLINES;
- }
-
- UINT wheel_amount = 3;
- if (SystemParametersInfo(uiAction, 0, &wheel_amount, 0)) {
- if (wheel_amount == WHEEL_PAGESCROLL) {
- event.data.wheel.type = WHEEL_BLOCK_SCROLL;
- event.data.wheel.amount = 1;
- } else {
- event.data.wheel.type = WHEEL_UNIT_SCROLL;
- event.data.wheel.amount = (uint16_t) wheel_amount;
- }
-
- // Set the direction based on what event was received.
- event.data.wheel.direction = direction;
-
- logger(LOG_LEVEL_DEBUG, "%s [%u]: Mouse wheel type %u, rotated %i units in the %u direction at %u, %u.\n",
- __FUNCTION__, __LINE__,
- event.data.wheel.type,
- event.data.wheel.amount * event.data.wheel.rotation,
- event.data.wheel.direction,
- event.data.wheel.x, event.data.wheel.y);
-
- // Fire mouse wheel event.
- dispatch_event(&event);
- } else {
- event.reserved = 0x01;
- logger(LOG_LEVEL_WARN, "%s [%u]: SystemParametersInfo() failed, event will be ignored.\n",
- __FUNCTION__, __LINE__);
- }
-}
-
LRESULT CALLBACK mouse_hook_event_proc(int nCode, WPARAM wParam, LPARAM lParam) {
+ bool consumed = false;
+
MSLLHOOKSTRUCT *mshook = (MSLLHOOKSTRUCT *) lParam;
switch (wParam) {
case WM_LBUTTONDOWN:
set_modifier_mask(MASK_BUTTON1);
- process_button_pressed(mshook, MOUSE_BUTTON1);
+ consumed = dispatch_button_press(mshook, MOUSE_BUTTON1);
break;
case WM_RBUTTONDOWN:
set_modifier_mask(MASK_BUTTON2);
- process_button_pressed(mshook, MOUSE_BUTTON2);
+ consumed = dispatch_button_press(mshook, MOUSE_BUTTON2);
break;
case WM_MBUTTONDOWN:
set_modifier_mask(MASK_BUTTON3);
- process_button_pressed(mshook, MOUSE_BUTTON3);
+ consumed = dispatch_button_press(mshook, MOUSE_BUTTON3);
break;
case WM_XBUTTONDOWN:
case WM_NCXBUTTONDOWN:
if (HIWORD(mshook->mouseData) == XBUTTON1) {
set_modifier_mask(MASK_BUTTON4);
- process_button_pressed(mshook, MOUSE_BUTTON4);
+ consumed = dispatch_button_press(mshook, MOUSE_BUTTON4);
} else if (HIWORD(mshook->mouseData) == XBUTTON2) {
set_modifier_mask(MASK_BUTTON5);
- process_button_pressed(mshook, MOUSE_BUTTON5);
+ consumed = dispatch_button_press(mshook, MOUSE_BUTTON5);
} else {
// Extra mouse buttons.
uint16_t button = HIWORD(mshook->mouseData);
@@ -578,34 +156,34 @@ LRESULT CALLBACK mouse_hook_event_proc(int nCode, WPARAM wParam, LPARAM lParam)
set_modifier_mask(MOUSE_BUTTON5);
}
- process_button_pressed(mshook, button);
+ consumed = dispatch_button_press(mshook, button);
}
break;
case WM_LBUTTONUP:
unset_modifier_mask(MASK_BUTTON1);
- process_button_released(mshook, MOUSE_BUTTON1);
+ consumed = dispatch_button_release(mshook, MOUSE_BUTTON1);
break;
case WM_RBUTTONUP:
unset_modifier_mask(MASK_BUTTON2);
- process_button_released(mshook, MOUSE_BUTTON2);
+ consumed = dispatch_button_release(mshook, MOUSE_BUTTON2);
break;
case WM_MBUTTONUP:
unset_modifier_mask(MASK_BUTTON3);
- process_button_released(mshook, MOUSE_BUTTON3);
+ consumed = dispatch_button_release(mshook, MOUSE_BUTTON3);
break;
case WM_XBUTTONUP:
case WM_NCXBUTTONUP:
if (HIWORD(mshook->mouseData) == XBUTTON1) {
unset_modifier_mask(MASK_BUTTON4);
- process_button_released(mshook, MOUSE_BUTTON4);
+ consumed = dispatch_button_release(mshook, MOUSE_BUTTON4);
} else if (HIWORD(mshook->mouseData) == XBUTTON2) {
unset_modifier_mask(MASK_BUTTON5);
- process_button_released(mshook, MOUSE_BUTTON5);
+ consumed = dispatch_button_release(mshook, MOUSE_BUTTON5);
} else {
// Extra mouse buttons.
uint16_t button = HIWORD(mshook->mouseData);
@@ -617,16 +195,16 @@ LRESULT CALLBACK mouse_hook_event_proc(int nCode, WPARAM wParam, LPARAM lParam)
unset_modifier_mask(MOUSE_BUTTON5);
}
- process_button_released(mshook, MOUSE_BUTTON5);
+ consumed = dispatch_button_release(mshook, MOUSE_BUTTON5);
}
break;
case WM_MOUSEMOVE:
- process_mouse_moved(mshook);
+ consumed = dispatch_mouse_move(mshook);
break;
case WM_MOUSEWHEEL:
- process_mouse_wheel(mshook, WHEEL_VERTICAL_DIRECTION);
+ consumed = dispatch_mouse_wheel(mshook, WHEEL_VERTICAL_DIRECTION);
break;
/* For horizontal scroll wheel support.
@@ -634,7 +212,7 @@ LRESULT CALLBACK mouse_hook_event_proc(int nCode, WPARAM wParam, LPARAM lParam)
* case 0x020E:
*/
case WM_MOUSEHWHEEL:
- process_mouse_wheel(mshook, WHEEL_HORIZONTAL_DIRECTION);
+ consumed = dispatch_mouse_wheel(mshook, WHEEL_HORIZONTAL_DIRECTION);
break;
default:
@@ -645,7 +223,7 @@ LRESULT CALLBACK mouse_hook_event_proc(int nCode, WPARAM wParam, LPARAM lParam)
}
LRESULT hook_result = -1;
- if (nCode < 0 || event.reserved ^ 0x01) {
+ if (nCode < 0 || !consumed) {
hook_result = CallNextHookEx(mouse_event_hhook, nCode, wParam, lParam);
} else {
logger(LOG_LEVEL_DEBUG, "%s [%u]: Consuming the current event. (%li)\n",
@@ -655,7 +233,6 @@ LRESULT CALLBACK mouse_hook_event_proc(int nCode, WPARAM wParam, LPARAM lParam)
return hook_result;
}
-
// Callback function that handles events.
void CALLBACK win_hook_event_proc(HWINEVENTHOOK hook, DWORD event, HWND hWnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime) {
switch (event) {
@@ -750,7 +327,7 @@ UIOHOOK_API int hook_run() {
// Windows does not have a hook start event or callback so we need to
// manually fake it.
- hook_start_proc();
+ dispatch_hook_enable();
// Block until the thread receives an WM_QUIT request.
MSG message;
@@ -771,7 +348,7 @@ UIOHOOK_API int hook_run() {
// We must explicitly call the cleanup handler because Windows does not
// provide a thread cleanup method like POSIX pthread_cleanup_push/pop.
- hook_stop_proc();
+ dispatch_hook_disable();
return status;
}