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

Fixed several issues for X11 #148

Open
wants to merge 10 commits into
base: 1.3
Choose a base branch
from
32 changes: 6 additions & 26 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 Expand Up @@ -206,12 +210,6 @@ if(UNIX AND NOT APPLE)
add_compile_definitions(uiohook PRIVATE USE_XRECORD_ASYNC)
endif()

option(USE_XTEST "XTest API (default: ON)" ON)
if(USE_XTEST)
# XTest API is provided by Xtst
add_compile_definitions(uiohook PRIVATE USE_XTEST)
endif()

if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
option(USE_EVDEV "Generic Linux input driver (default: ON)" ON)
if(USE_EVDEV)
Expand Down Expand Up @@ -245,31 +243,13 @@ elseif(APPLE)
target_link_libraries(uiohook "${IOKIT}")
endif()

# FIXME Change USE_OBJC flag to USE_APPKIT
#option(USE_APPKIT "AppKit framework (default: ON)" ON)
option(USE_OBJC "Objective-C API (default: ON)" ON)
if(USE_OBJC)
# FIXME Drop USE_OBJC as it is included in AppKit
find_library(OBJC objc REQUIRED)
add_compile_definitions(USE_OBJC)
target_include_directories(uiohook PRIVATE "${OBJC}")
target_link_libraries(uiohook "${OBJC}")

option(USE_APPKIT "AppKit framework (default: ON)" ON)
if(USE_APPKIT)
find_library(APPKIT AppKit REQUIRED)
add_compile_definitions(USE_APPKIT)
target_include_directories(uiohook PRIVATE "${APPKIT}")
target_link_libraries(uiohook "${APPKIT}")
endif()

option(USE_CARBON_LEGACY "Legacy Carbon framework functionality (default: OFF)" OFF)
if(USE_CARBON_LEGACY)
message(DEPRECATION "Legacy Carbon functionality has been deprecated.")
add_compile_definitions(USE_CARBON_LEGACY)

if(USE_CARBON_LEGACY AND CMAKE_SIZEOF_VOID_P EQUAL 8)
message(WARNING "Legacy Carbon functionality should not be used with 64-bit targets.")
endif()
endif()
elseif(WIN32)
target_link_libraries(uiohook Advapi32)
endif()
Expand Down
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ $ 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 |
| | USE_CARBON_LEGACY:BOOL | legacy framework | OFF |
| | USE_APPKIT:BOOL | obj-c api | ON |
| __Win32__ | | | |
| __Linux__ | USE_EVDEV:BOOL | generic input driver | ON |
| __*nix__ | USE_XF86MISC:BOOL | xfree86-misc extension | OFF |
Expand All @@ -45,7 +45,6 @@ $ cmake --build . --parallel 2 --target install
| | USE_XRANDR:BOOL | xrandt extension | OFF |
| | USE_XRECORD_ASYNC:BOOL | xrecord async api | OFF |
| | USE_XT:BOOL | x toolkit extension | ON |
| | USE_XTEST:BOOL | xtest extension | ON |

## Usage
* [Hook Demo](demo/demo_hook.c)
Expand Down
62 changes: 31 additions & 31 deletions demo/demo_hook.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,26 @@
#include <uiohook.h>
#include <wchar.h>

bool logger_proc(unsigned int level, const char *format, ...) {
bool status = false;

va_list args;

static void logger_proc(unsigned int level, void *user_data, const char *format, va_list args) {
switch (level) {
case LOG_LEVEL_INFO:
va_start(args, format);
status = vfprintf(stdout, format, args) >= 0;
va_end(args);
vfprintf(stdout, format, args);
break;

case LOG_LEVEL_WARN:
case LOG_LEVEL_ERROR:
va_start(args, format);
status = vfprintf(stderr, format, args) >= 0;
va_end(args);
vfprintf(stderr, format, args);
break;
}

return status;
}

static void logger(unsigned int level, const char *format, ...) {
va_list args;

va_start(args, format);
logger_proc(level, NULL, format, args);
va_end(args);
}

// NOTE: The following callback executes on the same thread that hook_run() is called
Expand All @@ -56,7 +56,7 @@ bool logger_proc(unsigned int level, const char *format, ...) {
// Furthermore, some operating systems may choose to disable your hook if it
// takes too long to process. If you need to do any extended processing, please
// do so by copying the event to your own queued dispatch thread.
void dispatch_proc(uiohook_event * const event) {
void dispatch_proc(uiohook_event * const event, void *user_data) {
char buffer[256] = { 0 };
size_t length = snprintf(buffer, sizeof(buffer),
"id=%i,when=%" PRIu64 ",mask=0x%X",
Expand All @@ -74,18 +74,18 @@ void dispatch_proc(uiohook_event * const event) {

// System level errors.
case UIOHOOK_ERROR_OUT_OF_MEMORY:
logger_proc(LOG_LEVEL_ERROR, "Failed to allocate memory. (%#X)", status);
logger(LOG_LEVEL_ERROR, "Failed to allocate memory. (%#X)", status);
break;

case UIOHOOK_ERROR_X_RECORD_GET_CONTEXT:
// NOTE This is the only platform specific error that occurs on hook_stop().
logger_proc(LOG_LEVEL_ERROR, "Failed to get XRecord context. (%#X)", status);
logger(LOG_LEVEL_ERROR, "Failed to get XRecord context. (%#X)", status);
break;

// Default error.
case UIOHOOK_FAILURE:
default:
logger_proc(LOG_LEVEL_ERROR, "An unknown hook error occurred. (%#X)", status);
logger(LOG_LEVEL_ERROR, "An unknown hook error occurred. (%#X)", status);
break;
}
}
Expand Down Expand Up @@ -129,10 +129,10 @@ void dispatch_proc(uiohook_event * const event) {

int main() {
// Set the logger callback for library output.
hook_set_logger_proc(&logger_proc);
hook_set_logger_proc(&logger_proc, NULL);

// Set the event callback for uiohook events.
hook_set_dispatch_proc(&dispatch_proc);
hook_set_dispatch_proc(&dispatch_proc, NULL);

// Start the hook and block.
// NOTE If EVENT_HOOK_ENABLED was delivered, the status will always succeed.
Expand All @@ -144,63 +144,63 @@ int main() {

// System level errors.
case UIOHOOK_ERROR_OUT_OF_MEMORY:
logger_proc(LOG_LEVEL_ERROR, "Failed to allocate memory. (%#X)", status);
logger(LOG_LEVEL_ERROR, "Failed to allocate memory. (%#X)", status);
break;


// X11 specific errors.
case UIOHOOK_ERROR_X_OPEN_DISPLAY:
logger_proc(LOG_LEVEL_ERROR, "Failed to open X11 display. (%#X)", status);
logger(LOG_LEVEL_ERROR, "Failed to open X11 display. (%#X)", status);
break;

case UIOHOOK_ERROR_X_RECORD_NOT_FOUND:
logger_proc(LOG_LEVEL_ERROR, "Unable to locate XRecord extension. (%#X)", status);
logger(LOG_LEVEL_ERROR, "Unable to locate XRecord extension. (%#X)", status);
break;

case UIOHOOK_ERROR_X_RECORD_ALLOC_RANGE:
logger_proc(LOG_LEVEL_ERROR, "Unable to allocate XRecord range. (%#X)", status);
logger(LOG_LEVEL_ERROR, "Unable to allocate XRecord range. (%#X)", status);
break;

case UIOHOOK_ERROR_X_RECORD_CREATE_CONTEXT:
logger_proc(LOG_LEVEL_ERROR, "Unable to allocate XRecord context. (%#X)", status);
logger(LOG_LEVEL_ERROR, "Unable to allocate XRecord context. (%#X)", status);
break;

case UIOHOOK_ERROR_X_RECORD_ENABLE_CONTEXT:
logger_proc(LOG_LEVEL_ERROR, "Failed to enable XRecord context. (%#X)", status);
logger(LOG_LEVEL_ERROR, "Failed to enable XRecord context. (%#X)", status);
break;


// Windows specific errors.
case UIOHOOK_ERROR_SET_WINDOWS_HOOK_EX:
logger_proc(LOG_LEVEL_ERROR, "Failed to register low level windows hook. (%#X)", status);
logger(LOG_LEVEL_ERROR, "Failed to register low level windows hook. (%#X)", status);
break;


// Darwin specific errors.
case UIOHOOK_ERROR_AXAPI_DISABLED:
logger_proc(LOG_LEVEL_ERROR, "Failed to enable access for assistive devices. (%#X)", status);
logger(LOG_LEVEL_ERROR, "Failed to enable access for assistive devices. (%#X)", status);
break;

case UIOHOOK_ERROR_CREATE_EVENT_PORT:
logger_proc(LOG_LEVEL_ERROR, "Failed to create apple event port. (%#X)", status);
logger(LOG_LEVEL_ERROR, "Failed to create apple event port. (%#X)", status);
break;

case UIOHOOK_ERROR_CREATE_RUN_LOOP_SOURCE:
logger_proc(LOG_LEVEL_ERROR, "Failed to create apple run loop source. (%#X)", status);
logger(LOG_LEVEL_ERROR, "Failed to create apple run loop source. (%#X)", status);
break;

case UIOHOOK_ERROR_GET_RUNLOOP:
logger_proc(LOG_LEVEL_ERROR, "Failed to acquire apple run loop. (%#X)", status);
logger(LOG_LEVEL_ERROR, "Failed to acquire apple run loop. (%#X)", status);
break;

case UIOHOOK_ERROR_CREATE_OBSERVER:
logger_proc(LOG_LEVEL_ERROR, "Failed to create apple run loop observer. (%#X)", status);
logger(LOG_LEVEL_ERROR, "Failed to create apple run loop observer. (%#X)", status);
break;

// Default error.
case UIOHOOK_FAILURE:
default:
logger_proc(LOG_LEVEL_ERROR, "An unknown hook error occurred. (%#X)", status);
logger(LOG_LEVEL_ERROR, "An unknown hook error occurred. (%#X)", status);
break;
}

Expand Down
Loading