Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding a compile time option to use Unix epoch time for events. #113

Merged
merged 2 commits into from
Feb 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ jobs:
shell: cmd
run: |
cmake -B ${{github.workspace}}\build ^
-G "Visual Studio 16 2019" -A ARM ^
-G "Visual Studio 17 2022" -A ARM ^
-D CMAKE_INSTALL_PREFIX=${{github.workspace}}\dist\windows\arm ^
-D CMAKE_VERBOSE_MAKEFILE=true ^
-D BUILD_SHARED_LIBS=ON ^
Expand Down Expand Up @@ -382,7 +382,7 @@ jobs:
shell: cmd
run: |
cmake -B ${{github.workspace}}\build ^
-G "Visual Studio 16 2019" -A Win32 ^
-G "Visual Studio 17 2022" -A Win32 ^
-D CMAKE_INSTALL_PREFIX=${{github.workspace}}\dist\windows\x86 ^
-D CMAKE_VERBOSE_MAKEFILE=true ^
-D BUILD_SHARED_LIBS=ON ^
Expand Down Expand Up @@ -418,7 +418,7 @@ jobs:
shell: cmd
run: |
cmake -B ${{github.workspace}}\build ^
-G "Visual Studio 16 2019" -A x64 ^
-G "Visual Studio 17 2022" -A x64 ^
-D CMAKE_INSTALL_PREFIX=${{github.workspace}}\dist\windows\x86_64 ^
-D CMAKE_VERBOSE_MAKEFILE=true ^
-D BUILD_SHARED_LIBS=ON ^
Expand Down
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ if(ENABLE_TEST)
target_link_libraries(uiohook_tests uiohook "${CMAKE_THREAD_LIBS_INIT}")
endif()

option(USE_EPOCH_TIME "Use Unix epoch time for event timestamps (default: OFF)" OFF)
if(USE_EPOCH_TIME)
add_compile_definitions(uiohook PRIVATE USE_EPOCH_TIME)
endif()

if(UNIX AND NOT APPLE)
find_package(PkgConfig REQUIRED)
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ $ cmake --build . --parallel 2 --target install
| __all__ | BUILD_DEMO:BOOL | demo applications | OFF |
| | BUILD_SHARED_LIBS:BOOL | shared library | ON |
| | ENABLE_TEST:BOOL | testing | OFF |
| | USE_EPOCH_TIME:BOOL | unix epch event times | OFF |
| __OSX__ | USE_APPLICATION_SERVICES:BOOL | framework | ON |
| | USE_IOKIT:BOOL | framework | ON |
| | USE_OBJC:BOOL | obj-c api | ON |
Expand Down
26 changes: 22 additions & 4 deletions src/darwin/input_hook.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,10 @@ static CGEventTimestamp click_time = 0;
static unsigned short int click_button = MOUSE_NOBUTTON;
static bool mouse_dragged = false;

#ifdef USE_EPOCH_TIME
// Structure for the current Unix epoch in milliseconds.
static struct timeval system_time;
#endif

// Virtual event pointer.
static uiohook_event event;
Expand Down Expand Up @@ -206,8 +208,24 @@ static void keycode_to_lookup(void *info) {
}
}

#ifdef USE_EPOCH_TIME
static inline uint64_t get_unix_timestamp() {
// Get the local system time in UTC.
gettimeofday(&system_time, NULL);

// Convert the local system time to a Unix epoch in MS.
uint64_t timestamp = (system_time.tv_sec * 1000) + (system_time.tv_usec / 1000);

return timestamp;
}
#endif

static void hook_status_proc(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) {
#ifdef USE_EPOCH_TIME
uint64_t timestamp = get_unix_timestamp();
#else
uint64_t timestamp = mach_absolute_time();
#endif

switch (activity) {
case kCFRunLoopEntry:
Expand Down Expand Up @@ -879,11 +897,11 @@ static inline void process_mouse_wheel(uint64_t timestamp, CGEventRef event_ref)
}

CGEventRef hook_event_proc(CGEventTapProxy tap_proxy, CGEventType type, CGEventRef event_ref, void *refcon) {
// Get the local system time in UTC.
gettimeofday(&system_time, NULL);

// Grab the native event timestamp for use later..
#ifdef USE_EPOCH_TIME
uint64_t timestamp = get_unix_timestamp();
#else
uint64_t timestamp = (uint64_t) CGEventGetTimestamp(event_ref);
#endif

// Get the event class.
switch (type) {
Expand Down
81 changes: 70 additions & 11 deletions src/windows/input_hook.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,14 @@ extern HINSTANCE hInst;
// Modifiers for tracking key masks.
static unsigned short int current_modifiers = 0x0000;

#ifdef USE_EPOCH_TIME
// Structure for the current Unix epoch in milliseconds.
static FILETIME system_time;
#endif

// Click count globals.
static unsigned short click_count = 0;
static DWORD click_time = 0;
static uint64_t click_time = 0;
static unsigned short int click_button = MOUSE_NOBUTTON;
static POINT last_click;

Expand Down Expand Up @@ -142,6 +147,22 @@ static uint16_t get_scroll_wheel_amount() {
return value;
}

#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) {
Expand All @@ -162,8 +183,11 @@ void unregister_running_hooks() {
}

void hook_start_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 start event.
event.time = timestamp;
Expand All @@ -177,8 +201,11 @@ void hook_start_proc() {
}

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;
Expand All @@ -192,6 +219,12 @@ void hook_stop_proc() {
}

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); }
Expand All @@ -206,7 +239,7 @@ static void process_key_pressed(KBDLLHOOKSTRUCT *kbhook) {
else if (kbhook->vkCode == VK_SCROLL) { set_modifier_mask(MASK_SCROLL_LOCK); }

// Populate key pressed event.
event.time = kbhook->time;
event.time = timestamp;
event.reserved = 0x00;

event.type = EVENT_KEY_PRESSED;
Expand All @@ -231,7 +264,7 @@ static void process_key_pressed(KBDLLHOOKSTRUCT *kbhook) {
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 = kbhook->time;
event.time = timestamp;
event.reserved = 0x00;

event.type = EVENT_KEY_TYPED;
Expand All @@ -251,6 +284,12 @@ static void process_key_pressed(KBDLLHOOKSTRUCT *kbhook) {
}

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); }
Expand All @@ -265,7 +304,7 @@ static void process_key_released(KBDLLHOOKSTRUCT *kbhook) {
else if (kbhook->vkCode == VK_SCROLL) { unset_modifier_mask(MASK_SCROLL_LOCK); }

// Populate key pressed event.
event.time = kbhook->time;
event.time = timestamp;
event.reserved = 0x00;

event.type = EVENT_KEY_RELEASED;
Expand Down Expand Up @@ -315,7 +354,11 @@ LRESULT CALLBACK keyboard_hook_event_proc(int nCode, WPARAM wParam, LPARAM lPara


static void process_button_pressed(MSLLHOOKSTRUCT *mshook, uint16_t button) {
DWORD timestamp = mshook->time;
#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()) {
Expand Down Expand Up @@ -362,8 +405,14 @@ static void process_button_pressed(MSLLHOOKSTRUCT *mshook, uint16_t button) {
}

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 = mshook->time;
event.time = timestamp;
event.reserved = 0x00;

event.type = EVENT_MOUSE_RELEASED;
Expand All @@ -386,7 +435,7 @@ static void process_button_released(MSLLHOOKSTRUCT *mshook, uint16_t button) {
// 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 = mshook->time;
event.time = timestamp;
event.reserved = 0x00;

event.type = EVENT_MOUSE_CLICKED;
Expand All @@ -406,14 +455,18 @@ static void process_button_released(MSLLHOOKSTRUCT *mshook, uint16_t button) {
}

// Reset the number of clicks.
if (button == click_button && (long int) (event.time - click_time) > hook_get_multi_click_time()) {
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.
Expand Down Expand Up @@ -454,13 +507,19 @@ static void process_mouse_moved(MSLLHOOKSTRUCT *mshook) {
}

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 = mshook->time;
event.time = timestamp;
event.reserved = 0x00;

event.type = EVENT_MOUSE_WHEEL;
Expand Down
23 changes: 22 additions & 1 deletion src/x11/input_hook.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ typedef union {
static struct xkb_state *state = NULL;
#endif

#ifdef USE_EPOCH_TIME
// Structure for the current Unix epoch in milliseconds.
static struct timeval system_time;
#endif

// Virtual event pointer.
static uiohook_event event;

Expand Down Expand Up @@ -192,7 +197,7 @@ static void initialize_modifiers() {
char keymap[32];
XQueryKeymap(hook->ctrl.display, keymap);

Window unused_win;
Window unused_win;
int unused_int;
unsigned int mask;
if (XQueryPointer(hook->ctrl.display, DefaultRootWindow(hook->ctrl.display), &unused_win, &unused_win, &unused_int, &unused_int, &unused_int, &unused_int, &mask)) {
Expand Down Expand Up @@ -251,8 +256,24 @@ static void initialize_modifiers() {
initialize_locks();
}

#ifdef USE_EPOCH_TIME
static inline uint64_t get_unix_timestamp() {
// Get the local system time in UTC.
gettimeofday(&system_time, NULL);

// Convert the local system time to a Unix epoch in MS.
uint64_t timestamp = (system_time.tv_sec * 1000) + (system_time.tv_usec / 1000);

return timestamp;
}
#endif

void hook_event_proc(XPointer closeure, XRecordInterceptData *recorded_data) {
#ifdef USE_EPOCH_TIME
uint64_t timestamp = get_unix_timestamp();
#else
uint64_t timestamp = (uint64_t) recorded_data->server_time;
#endif

if (recorded_data->category == XRecordStartOfData) {
// Populate the hook start event.
Expand Down