# libUIOHook: Cross-platform keyboard and mouse hooking from userland.
# Copyright (C) 2006-2023 Alexander Barker. All Rights Reserved.
# https://github.com/kwhat/libuiohook/
#
# libUIOHook is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# libUIOHook is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see .
cmake_minimum_required(VERSION 3.10)
project(uiohook VERSION 1.2.0 LANGUAGES C)
if (WIN32 OR WIN64)
set(UIOHOOK_SOURCE_DIR "windows")
elseif (APPLE)
set(UIOHOOK_SOURCE_DIR "darwin")
else()
set(UIOHOOK_SOURCE_DIR "x11")
endif()
add_library(uiohook
"src/logger.c"
"src/${UIOHOOK_SOURCE_DIR}/input_helper.c"
"src/${UIOHOOK_SOURCE_DIR}/input_hook.c"
"src/${UIOHOOK_SOURCE_DIR}/post_event.c"
"src/${UIOHOOK_SOURCE_DIR}/system_properties.c"
)
set_target_properties(uiohook PROPERTIES
C_STANDARD 99
C_STANDARD_REQUIRED ON
POSITION_INDEPENDENT_CODE 1
OUTPUT_NAME "${PROJECT_NAME}"
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
PUBLIC_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/include/uiohook.h
)
include(GNUInstallDirs)
target_include_directories(uiohook
PUBLIC
$
$
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR}/src/${UIOHOOK_SOURCE_DIR}
)
install(TARGETS uiohook
EXPORT ${PROJECT_NAME}-config
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
)
export(TARGETS uiohook FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake")
install(EXPORT ${PROJECT_NAME}-config DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
if (BUILD_DEMO)
if (NOT BUILD_SHARED_LIBS)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
endif()
find_package(Threads REQUIRED)
add_executable(demo_hook "./demo/demo_hook.c")
add_dependencies(demo_hook uiohook)
target_link_libraries(demo_hook uiohook "${CMAKE_THREAD_LIBS_INIT}")
add_executable(demo_hook_async "./demo/demo_hook_async.c")
add_dependencies(demo_hook_async uiohook)
target_link_libraries(demo_hook_async uiohook "${CMAKE_THREAD_LIBS_INIT}")
add_executable(demo_post "./demo/demo_post.c")
add_dependencies(demo_post uiohook)
target_link_libraries(demo_post uiohook "${CMAKE_THREAD_LIBS_INIT}")
add_executable(demo_properties "./demo/demo_properties.c")
add_dependencies(demo_properties uiohook)
target_link_libraries(demo_properties uiohook "${CMAKE_THREAD_LIBS_INIT}")
add_custom_target(all_demos DEPENDS
demo_hook
demo_hook_async
demo_post
demo_properties
)
set_target_properties(all_demos PROPERTIES
C_STANDARD 99
C_STANDARD_REQUIRED ON
)
if(MSVC)
add_compile_definitions(all_demos PRIVATE inline=__inline)
add_compile_definitions(all_demos PRIVATE _CRT_SECURE_NO_WARNINGS)
if (MSVC_VERSION LESS "1900")
add_compile_definitions(all_demos PRIVATE snprintf=_snprintf)
endif()
endif()
install(TARGETS demo_hook demo_hook_async demo_post demo_properties RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
if(ENABLE_TEST)
add_executable(uiohook_tests
"./test/input_helper_test.c"
"./test/system_properties_test.c"
"./test/minunit.h"
"./test/uiohook_test.c"
)
target_include_directories(uiohook_tests PRIVATE "./src/${UIOHOOK_SOURCE_DIR}")
target_link_libraries(uiohook_tests uiohook "${CMAKE_THREAD_LIBS_INIT}")
endif()
if(UNIX AND NOT APPLE)
find_package(PkgConfig REQUIRED)
pkg_check_modules(X11 REQUIRED x11)
target_include_directories(uiohook PRIVATE "${X11_INCLUDE_DIRS}")
target_link_libraries(uiohook "${X11_LDFLAGS}")
pkg_check_modules(XTST REQUIRED xtst)
target_include_directories(uiohook PRIVATE "${XTST_INCLUDE_DIRS}")
target_link_libraries(uiohook "${XTST_LDFLAGS}")
include(CheckLibraryExists)
check_library_exists(Xtst XRecordQueryVersion "" HAVE_XRECORD)
include(CheckIncludeFile)
check_include_file(X11/extensions/record.h HAVE_RECORD_H "-include X11/Xlib.h")
option(USE_XKB_COMMON "X Keyboard Common Extension (default: ON)" ON)
if(USE_XKB_COMMON)
pkg_check_modules(XKB_COMMON REQUIRED xkbcommon-x11)
add_compile_definitions(uiohook PRIVATE USE_XKB_COMMON)
target_include_directories(uiohook PRIVATE "${XKB_COMMON_INCLUDE_DIRS}")
target_link_libraries(uiohook "${XKB_COMMON_LDFLAGS}")
pkg_check_modules(X11_XCB REQUIRED x11-xcb)
target_include_directories(uiohook PRIVATE "${X11_XCB_INCLUDE_DIRS}")
target_link_libraries(uiohook "${X11_XCB_LDFLAGS}")
endif()
option(USE_XKB_FILE "X Keyboard File Extension (default: ON)" ON)
if(USE_XKB_FILE)
pkg_check_modules(XKB_FILE REQUIRED xkbfile)
add_compile_definitions(uiohook PRIVATE USE_XKB_FILE)
target_include_directories(uiohook PRIVATE "${XKB_FILE_INCLUDE_DIRS}")
target_link_libraries(uiohook "${XKB_FILE_LDFLAGS}")
endif()
option(USE_XT "X Toolkit Extension (default: ON)" ON)
if(USE_XT)
pkg_check_modules(XT REQUIRED xt)
add_compile_definitions(uiohook PRIVATE USE_XT)
target_include_directories(uiohook PRIVATE "${XT_INCLUDE_DIRS}")
target_link_libraries(uiohook "${XT_LDFLAGS}")
endif()
option(USE_XF86MISC "XFree86-Misc X Extension (default: OFF)" OFF)
if(USE_XF86MISC)
pkg_check_modules(XF86MISC REQUIRED Xxf86misc)
add_compile_definitions(uiohook PRIVATE USE_XF86MISC)
target_include_directories(uiohook PRIVATE "${XF86MISC_INCLUDE_DIRS}")
target_link_libraries(uiohook "${XF86MISC_LDFLAGS}")
endif()
option(USE_XRANDR "XRandR Extension (default: OFF)" OFF)
if(USE_XRANDR)
pkg_check_modules(XRANDR REQUIRED xrandr)
add_compile_definitions(uiohook PRIVATE USE_XRANDR)
target_include_directories(uiohook PRIVATE "${XRANDR_INCLUDE_DIRS}")
target_link_libraries(uiohook "${XRANDR_LDFLAGS}")
endif()
option(USE_XINERAMA "Xinerama Extension (default: ON)" ON)
if(USE_XINERAMA)
pkg_check_modules(XINERAMA REQUIRED xinerama)
add_compile_definitions(uiohook PRIVATE USE_XINERAMA)
target_include_directories(uiohook PRIVATE "${XINERAMA_INCLUDE_DIRS}")
target_link_libraries(uiohook "${XINERAMA_LDFLAGS}")
endif()
option(USE_XRECORD_ASYNC "XRecord Asynchronous API (default: OFF)" OFF)
if(USE_XRECORD_ASYNC)
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)
add_compile_definitions(uiohook PRIVATE USE_EVDEV)
endif()
endif()
elseif(APPLE)
set(CMAKE_MACOSX_RPATH 1)
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.5")
find_package(Threads REQUIRED)
target_link_libraries(uiohook "${CMAKE_THREAD_LIBS_INIT}")
find_library(CARBON Carbon REQUIRED)
target_include_directories(uiohook PRIVATE "${CARBON}")
target_link_libraries(uiohook "${CARBON}")
option(USE_APPLICATION_SERVICES "ApplicationServices framework (default: ON)" ON)
if(USE_APPLICATION_SERVICES)
find_library(APPLICATION_SERVICES ApplicationServices REQUIRED)
add_compile_definitions(USE_APPLICATION_SERVICES)
target_include_directories(uiohook PRIVATE "${APPLICATION_SERVICES}")
target_link_libraries(uiohook "${APPLICATION_SERVICES}")
endif()
option(USE_IOKIT "IOKit framework (default: ON)" ON)
if(USE_IOKIT)
find_library(IOKIT IOKit REQUIRED)
add_compile_definitions(USE_IOKIT)
target_include_directories(uiohook PRIVATE "${IOKIT}")
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}")
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()
list(REMOVE_DUPLICATES INTERFACE_LINK_LIBRARIES)
string(REPLACE ";" " " COMPILE_LIBRARIES "${INTERFACE_LINK_LIBRARIES}")
configure_file("pc/uiohook.pc.in" "${PROJECT_BINARY_DIR}/uiohook.pc" @ONLY)
install(FILES "${PROJECT_BINARY_DIR}/uiohook.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")