From bfb50b29f0626b9bd06f4ac67d50243cb798d2d5 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 29 Apr 2021 10:53:32 +1000 Subject: [PATCH 01/41] Default branch is now main To update your local repository, use these commands $ git fetch origin $ git checkout master $ git branch -m main $ git branch --set-upstream-to=origin/main Signed-off-by: Peter Hutterer --- meson.build | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/meson.build b/meson.build index 70cc3037..1b194c42 100644 --- a/meson.build +++ b/meson.build @@ -1025,3 +1025,7 @@ configure_file(input : 'tools/libinput-quirks.man', ############ output files ############ configure_file(output : 'config.h', configuration : config_h) + +warning('*********************************************************************') +warning('This branch is no longer updated. Please switch to the "main" branch.') +warning('*********************************************************************') From ef15144c7db85f0f65135a24d441f96d2959fb81 Mon Sep 17 00:00:00 2001 From: Rafael Sadowski Date: Wed, 2 Nov 2022 18:21:46 +0100 Subject: [PATCH 02/41] Add some OpenBSD notes --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e2333a62..aa306e7b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -libinput +lib(open)input ======== libinput is a library that provides a full input stack for display servers @@ -11,6 +11,17 @@ provide the common set of functionality that users expect. Input event processing includes scaling touch coordinates, generating relative pointer events from touchpads, pointer acceleration, etc. +OpenBSD related changes +----------------------- +This repository fork from https://gitlab.freedesktop.org/libinput/libinput. +It is an attempt to extend libinput so that it works with wscons(4) and +kqueue(2) and thus on OpenBSD. + +TODO: +[ ] Build and Compile on OpenBSD +[ ] Port logic from https://github.com/mpieuchot/libinput + + User documentation ------------------ From cc36e4e7ef64f3c340f99f713e2fc84ee682f62b Mon Sep 17 00:00:00 2001 From: Rafael Sadowski Date: Fri, 4 Nov 2022 11:02:48 +0100 Subject: [PATCH 03/41] Modify meson to build on OpenBSD --- README.md | 7 +- include/linux/input.h | 2 + meson.build | 69 +- src/libinput.h | 2 + src/libinput_openbsd.c | 4250 ++++++++++++++++++++++++++++++++++++++++ src/quirks.c | 2 + src/quirks.h | 2 + 7 files changed, 4325 insertions(+), 9 deletions(-) create mode 100644 src/libinput_openbsd.c diff --git a/README.md b/README.md index aa306e7b..6215e5ad 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,13 @@ This repository fork from https://gitlab.freedesktop.org/libinput/libinput. It is an attempt to extend libinput so that it works with wscons(4) and kqueue(2) and thus on OpenBSD. +``` +$ meson setup builddir -Dlibwacom=false -Ddocumentation=false +$ cd builddir && ninja +``` + TODO: -[ ] Build and Compile on OpenBSD +[X] Build and Compile on OpenBSD [ ] Port logic from https://github.com/mpieuchot/libinput diff --git a/include/linux/input.h b/include/linux/input.h index 03c512ef..827c8390 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -1,5 +1,7 @@ #ifdef __linux__ #include "linux/input.h" +#elif __OpenBSD__ +#include "freebsd/input.h" #elif __FreeBSD__ #include "freebsd/input.h" #endif diff --git a/meson.build b/meson.build index 1b194c42..4aefc3bf 100644 --- a/meson.build +++ b/meson.build @@ -143,11 +143,17 @@ config_h.set10('HAVE_INSTALLED_TESTS', get_option('install-tests')) # Dependencies pkgconfig = import('pkgconfig') -dep_udev = dependency('libudev') -dep_mtdev = dependency('mtdev', version : '>= 1.1.0') -dep_libevdev = dependency('libevdev') -config_h.set10('HAVE_LIBEVDEV_DISABLE_PROPERTY', - dep_libevdev.version().version_compare('>= 1.9.902')) +if host_machine.system() == 'openbsd' + dep_udev = [] + dep_mtdev = [] + dep_libevdev = [] +else + dep_udev = dependency('libudev') + dep_mtdev = dependency('mtdev', version : '>= 1.1.0') + dep_libevdev = dependency('libevdev') + config_h.set10('HAVE_LIBEVDEV_DISABLE_PROPERTY', + dep_libevdev.version().version_compare('>= 1.9.902')) +endif dep_lm = cc.find_library('m', required : false) dep_rt = cc.find_library('rt', required : false) @@ -158,7 +164,11 @@ includes_src = include_directories('src') ############ libwacom configuration ############ +if host_machine.system() == 'openbsd' +have_libwacom = false +else have_libwacom = get_option('libwacom') +endif config_h.set10('HAVE_LIBWACOM', have_libwacom) if have_libwacom dep_libwacom = dependency('libwacom', version : '>= 0.27') @@ -167,7 +177,7 @@ else endif ############ udev bits ############ - +if host_machine.system() != 'openbsd' executable('libinput-device-group', 'udev/libinput-device-group.c', dependencies : [dep_udev, dep_libwacom], @@ -222,6 +232,7 @@ if get_option('tests') suite : ['all']) endif +endif ############ libepoll-shim (BSD) ############ if cc.has_header_symbol('sys/epoll.h', 'epoll_create1', prefix : prefix) @@ -251,7 +262,9 @@ else endif ############ libinput-util.a ############ - +if host_machine.system() == 'openbsd' + dep_libinput_util = [] +else # Basic compilation test to make sure the headers include and define all the # necessary bits. util_headers = [ @@ -289,6 +302,7 @@ libinput_util = static_library('libinput-util', include_directories : includes_include) dep_libinput_util = declare_dependency(link_with : libinput_util) +endif ############ libfilter.a ############ src_libfilter = [ 'src/filter.c', @@ -303,11 +317,14 @@ src_libfilter = [ 'src/filter-trackpoint.c', 'src/filter-trackpoint-flat.c', ] +if host_machine.system() == 'openbsd' + dep_libfilter = [] +else libfilter = static_library('filter', src_libfilter, dependencies : [dep_udev, dep_libwacom], include_directories : includes_include) dep_libfilter = declare_dependency(link_with : libfilter) - +endif ############ libquirks.a ############# libinput_data_path = dir_data libinput_data_override_path = dir_overrides / 'local-overrides.quirks' @@ -339,6 +356,16 @@ endif ############ libinput.so ############ install_headers('src/libinput.h') +if host_machine.system() == 'openbsd' +src_libinput = src_libfilter + [ + 'src/libinput_openbsd.c', + 'src/libinput.h', + 'src/libinput-private.h', + 'src/timer.c', + 'src/timer.h', + 'include/linux/input.h' +] +else src_libinput = src_libfilter + [ 'src/libinput.c', 'src/libinput-private-config.c', @@ -361,6 +388,7 @@ src_libinput = src_libfilter + [ 'src/udev-seat.c', 'src/timer.c', ] +endif deps_libinput = [ dep_mtdev, @@ -397,6 +425,15 @@ lib_libinput = shared_library('input', link_depends : mapfile, install : true ) +if host_machine.system() == 'openbsd' +install_headers('include/linux/freebsd/input-event-codes.h', subdir: 'linux/freebsd') +install_headers('include/linux/freebsd/input.h', subdir: 'linux/freebsd') + +install_headers('include/linux/linux/input-event-codes.h', subdir: 'linux/linux') +install_headers('include/linux/linux/input.h', subdir: 'linux/linux') + +install_headers('include/linux/input.h', subdir: 'linux') +endif dep_libinput = declare_dependency( link_with : lib_libinput, @@ -431,6 +468,8 @@ endif subdir('completion/zsh') ############ tools ############ +if host_machine.system() != 'openbsd' + libinput_tool_path = dir_libexec config_h.set_quoted('LIBINPUT_TOOL_PATH', libinput_tool_path) tools_shared_sources = [ 'tools/shared.c' ] @@ -673,7 +712,9 @@ test('tools-builddir-lookup-installed', suite : ['all'], workdir : '/tmp') +endif ############ tests ############ +if host_machine.system() != 'openbsd' test('symbols-leak-test', find_program('test/symbols-leak-test'), @@ -727,8 +768,10 @@ if get_option('tests') config_h.set10('HAVE_GSTACK', gstack.found()) # for inhibit support during test run +if host_machine.system() != 'openbsd' dep_libsystemd = dependency('libsystemd', version : '>= 221', required : false) config_h.set10('HAVE_LIBSYSTEMD', dep_libsystemd.found()) +endif litest_sources = [ 'src/libinput-private-config.c', @@ -833,6 +876,7 @@ if get_option('tests') 'test/litest.c', ] +if host_machine.system() != 'openbsd' dep_dl = cc.find_library('dl') deps_litest = [ dep_libinput, @@ -844,6 +888,14 @@ if get_option('tests') dep_libsystemd, dep_libquirks, ] +else + deps_litest = [ + dep_libinput, + dep_check, + dep_lm, + dep_libquirks, + ] +endif litest_config_h = configuration_data() litest_config_h.set_quoted('LIBINPUT_DEVICE_GROUPS_RULES_FILE', @@ -967,6 +1019,7 @@ if get_option('tests') endif +endif ############ man pages ############ man_config = configuration_data() man_config.set('LIBINPUT_VERSION', meson.project_version()) diff --git a/src/libinput.h b/src/libinput.h index 6258a1af..cb632369 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -32,7 +32,9 @@ extern "C" { #include #include #include +#ifndef __OpenBSD__ #include +#endif #define LIBINPUT_ATTRIBUTE_PRINTF(_format, _args) \ __attribute__ ((format (printf, _format, _args))) diff --git a/src/libinput_openbsd.c b/src/libinput_openbsd.c new file mode 100644 index 00000000..9caffefc --- /dev/null +++ b/src/libinput_openbsd.c @@ -0,0 +1,4250 @@ +/* + * Copyright © 2013 Jonas Ådahl + * Copyright © 2013-2018 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libinput.h" +#include "libinput-private.h" +#include "timer.h" +#include "quirks.h" + +#define require_event_type(li_, type_, retval_, ...) \ + if (type_ == LIBINPUT_EVENT_NONE) abort(); \ + if (!check_event_type(li_, __func__, type_, __VA_ARGS__, -1)) \ + return retval_; \ + +#define ASSERT_INT_SIZE(type_) \ + static_assert(sizeof(type_) == sizeof(unsigned int), \ + "sizeof(" #type_ ") must be sizeof(uint)") + +ASSERT_INT_SIZE(enum libinput_log_priority); +ASSERT_INT_SIZE(enum libinput_device_capability); +ASSERT_INT_SIZE(enum libinput_key_state); +ASSERT_INT_SIZE(enum libinput_led); +ASSERT_INT_SIZE(enum libinput_button_state); +ASSERT_INT_SIZE(enum libinput_pointer_axis); +ASSERT_INT_SIZE(enum libinput_pointer_axis_source); +ASSERT_INT_SIZE(enum libinput_tablet_pad_ring_axis_source); +ASSERT_INT_SIZE(enum libinput_tablet_pad_strip_axis_source); +ASSERT_INT_SIZE(enum libinput_tablet_tool_type); +ASSERT_INT_SIZE(enum libinput_tablet_tool_proximity_state); +ASSERT_INT_SIZE(enum libinput_tablet_tool_tip_state); +ASSERT_INT_SIZE(enum libinput_switch_state); +ASSERT_INT_SIZE(enum libinput_switch); +ASSERT_INT_SIZE(enum libinput_event_type); +ASSERT_INT_SIZE(enum libinput_config_status); +ASSERT_INT_SIZE(enum libinput_config_tap_state); +ASSERT_INT_SIZE(enum libinput_config_tap_button_map); +ASSERT_INT_SIZE(enum libinput_config_drag_state); +ASSERT_INT_SIZE(enum libinput_config_drag_lock_state); +ASSERT_INT_SIZE(enum libinput_config_send_events_mode); +ASSERT_INT_SIZE(enum libinput_config_accel_profile); +ASSERT_INT_SIZE(enum libinput_config_click_method); +ASSERT_INT_SIZE(enum libinput_config_middle_emulation_state); +ASSERT_INT_SIZE(enum libinput_config_scroll_method); +ASSERT_INT_SIZE(enum libinput_config_dwt_state); + +static inline const char * +event_type_to_str(enum libinput_event_type type) +{ + switch(type) { + CASE_RETURN_STRING(LIBINPUT_EVENT_DEVICE_ADDED); + CASE_RETURN_STRING(LIBINPUT_EVENT_DEVICE_REMOVED); + CASE_RETURN_STRING(LIBINPUT_EVENT_KEYBOARD_KEY); + CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_MOTION); + CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE); + CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_BUTTON); + CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_AXIS); + CASE_RETURN_STRING(LIBINPUT_EVENT_TOUCH_DOWN); + CASE_RETURN_STRING(LIBINPUT_EVENT_TOUCH_UP); + CASE_RETURN_STRING(LIBINPUT_EVENT_TOUCH_MOTION); + CASE_RETURN_STRING(LIBINPUT_EVENT_TOUCH_CANCEL); + CASE_RETURN_STRING(LIBINPUT_EVENT_TOUCH_FRAME); + CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_TOOL_AXIS); + CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_TOOL_TIP); + CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_TOOL_BUTTON); + CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_BUTTON); + CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_RING); + CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_STRIP); + CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_KEY); + CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN); + CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE); + CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_SWIPE_END); + CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_PINCH_BEGIN); + CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_PINCH_UPDATE); + CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_PINCH_END); + CASE_RETURN_STRING(LIBINPUT_EVENT_SWITCH_TOGGLE); + case LIBINPUT_EVENT_NONE: + abort(); + } + + return NULL; +} + +static inline bool +check_event_type(struct libinput *libinput, + const char *function_name, + unsigned int type_in, + ...) +{ + bool rc = false; + return rc; +} + +struct libinput_source { + libinput_source_dispatch_t dispatch; + void *user_data; + int fd; + struct list link; +}; + +struct libinput_event_device_notify { + struct libinput_event base; +}; + +struct libinput_event_keyboard { + struct libinput_event base; + uint64_t time; + uint32_t key; + uint32_t seat_key_count; + enum libinput_key_state state; +}; + +struct libinput_event_pointer { + struct libinput_event base; + uint64_t time; + struct normalized_coords delta; + struct device_float_coords delta_raw; + struct device_coords absolute; + struct discrete_coords discrete; + uint32_t button; + uint32_t seat_button_count; + enum libinput_button_state state; + enum libinput_pointer_axis_source source; + uint32_t axes; +}; + +struct libinput_event_touch { + struct libinput_event base; + uint64_t time; + int32_t slot; + int32_t seat_slot; + struct device_coords point; +}; + +struct libinput_event_gesture { + struct libinput_event base; + uint64_t time; + int finger_count; + int cancelled; + struct normalized_coords delta; + struct normalized_coords delta_unaccel; + double scale; + double angle; +}; + +struct libinput_event_tablet_tool { + struct libinput_event base; + uint32_t button; + enum libinput_button_state state; + uint32_t seat_button_count; + uint64_t time; + struct tablet_axes axes; + unsigned char changed_axes[NCHARS(LIBINPUT_TABLET_TOOL_AXIS_MAX + 1)]; + struct libinput_tablet_tool *tool; + enum libinput_tablet_tool_proximity_state proximity_state; + enum libinput_tablet_tool_tip_state tip_state; +}; + +struct libinput_event_tablet_pad { + struct libinput_event base; + unsigned int mode; + struct libinput_tablet_pad_mode_group *mode_group; + uint64_t time; + struct { + uint32_t number; + enum libinput_button_state state; + } button; + struct { + uint32_t code; + enum libinput_key_state state; + } key; + struct { + enum libinput_tablet_pad_ring_axis_source source; + double position; + int number; + } ring; + struct { + enum libinput_tablet_pad_strip_axis_source source; + double position; + int number; + } strip; +}; + +struct libinput_event_switch { + struct libinput_event base; + uint64_t time; + enum libinput_switch sw; + enum libinput_switch_state state; +}; + +LIBINPUT_ATTRIBUTE_PRINTF(3, 0) +static void +libinput_default_log_func(struct libinput *libinput, + enum libinput_log_priority priority, + const char *format, va_list args) +{ + const char *prefix; + + switch(priority) { + case LIBINPUT_LOG_PRIORITY_DEBUG: prefix = "debug"; break; + case LIBINPUT_LOG_PRIORITY_INFO: prefix = "info"; break; + case LIBINPUT_LOG_PRIORITY_ERROR: prefix = "error"; break; + default: prefix=""; break; + } + + fprintf(stderr, "libinput %s: ", prefix); + vfprintf(stderr, format, args); +} + +void +log_msg_va(struct libinput *libinput, + enum libinput_log_priority priority, + const char *format, + va_list args) +{ + if (is_logged(libinput, priority)) + libinput->log_handler(libinput, priority, format, args); +} + +void +log_msg(struct libinput *libinput, + enum libinput_log_priority priority, + const char *format, ...) +{ + va_list args; + + va_start(args, format); + log_msg_va(libinput, priority, format, args); + va_end(args); +} + +void +log_msg_ratelimit(struct libinput *libinput, + struct ratelimit *ratelimit, + enum libinput_log_priority priority, + const char *format, ...) +{ + va_list args; + enum ratelimit_state state; + + state = ratelimit_test(ratelimit); + if (state == RATELIMIT_EXCEEDED) + return; + + va_start(args, format); + log_msg_va(libinput, priority, format, args); + va_end(args); + + if (state == RATELIMIT_THRESHOLD) + log_msg(libinput, + priority, + "WARNING: log rate limit exceeded (%d msgs per %dms). Discarding future messages.\n", + ratelimit->burst, + us2ms(ratelimit->interval)); +} + +LIBINPUT_EXPORT void +libinput_log_set_priority(struct libinput *libinput, + enum libinput_log_priority priority) +{ + libinput->log_priority = priority; +} + +LIBINPUT_EXPORT enum libinput_log_priority +libinput_log_get_priority(const struct libinput *libinput) +{ + return libinput->log_priority; +} + +LIBINPUT_EXPORT void +libinput_log_set_handler(struct libinput *libinput, + libinput_log_handler log_handler) +{ + libinput->log_handler = log_handler; +} + +static void +libinput_device_group_destroy(struct libinput_device_group *group); + +static void +libinput_post_event(struct libinput *libinput, + struct libinput_event *event); + +LIBINPUT_EXPORT enum libinput_event_type +libinput_event_get_type(struct libinput_event *event) +{ + return event->type; +} + +LIBINPUT_EXPORT struct libinput * +libinput_event_get_context(struct libinput_event *event) +{ + return event->device->seat->libinput; +} + +LIBINPUT_EXPORT struct libinput_device * +libinput_event_get_device(struct libinput_event *event) +{ + return event->device; +} + +LIBINPUT_EXPORT struct libinput_event_pointer * +libinput_event_get_pointer_event(struct libinput_event *event) +{ + require_event_type(libinput_event_get_context(event), + event->type, + NULL, + LIBINPUT_EVENT_POINTER_MOTION, + LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, + LIBINPUT_EVENT_POINTER_BUTTON, + LIBINPUT_EVENT_POINTER_AXIS); + + return (struct libinput_event_pointer *) event; +} + +LIBINPUT_EXPORT struct libinput_event_keyboard * +libinput_event_get_keyboard_event(struct libinput_event *event) +{ + require_event_type(libinput_event_get_context(event), + event->type, + NULL, + LIBINPUT_EVENT_KEYBOARD_KEY); + + return (struct libinput_event_keyboard *) event; +} + +LIBINPUT_EXPORT struct libinput_event_touch * +libinput_event_get_touch_event(struct libinput_event *event) +{ + require_event_type(libinput_event_get_context(event), + event->type, + NULL, + LIBINPUT_EVENT_TOUCH_DOWN, + LIBINPUT_EVENT_TOUCH_UP, + LIBINPUT_EVENT_TOUCH_MOTION, + LIBINPUT_EVENT_TOUCH_CANCEL, + LIBINPUT_EVENT_TOUCH_FRAME); + return (struct libinput_event_touch *) event; +} + +LIBINPUT_EXPORT struct libinput_event_gesture * +libinput_event_get_gesture_event(struct libinput_event *event) +{ + require_event_type(libinput_event_get_context(event), + event->type, + NULL, + LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, + LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, + LIBINPUT_EVENT_GESTURE_SWIPE_END, + LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, + LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, + LIBINPUT_EVENT_GESTURE_PINCH_END); + + return (struct libinput_event_gesture *) event; +} + +LIBINPUT_EXPORT struct libinput_event_tablet_tool * +libinput_event_get_tablet_tool_event(struct libinput_event *event) +{ + require_event_type(libinput_event_get_context(event), + event->type, + NULL, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON); + + return (struct libinput_event_tablet_tool *) event; +} + +LIBINPUT_EXPORT struct libinput_event_tablet_pad * +libinput_event_get_tablet_pad_event(struct libinput_event *event) +{ + require_event_type(libinput_event_get_context(event), + event->type, + NULL, + LIBINPUT_EVENT_TABLET_PAD_RING, + LIBINPUT_EVENT_TABLET_PAD_STRIP, + LIBINPUT_EVENT_TABLET_PAD_BUTTON, + LIBINPUT_EVENT_TABLET_PAD_KEY); + + return (struct libinput_event_tablet_pad *) event; +} + +LIBINPUT_EXPORT struct libinput_event_device_notify * +libinput_event_get_device_notify_event(struct libinput_event *event) +{ + require_event_type(libinput_event_get_context(event), + event->type, + NULL, + LIBINPUT_EVENT_DEVICE_ADDED, + LIBINPUT_EVENT_DEVICE_REMOVED); + + return (struct libinput_event_device_notify *) event; +} + +LIBINPUT_EXPORT struct libinput_event_switch * +libinput_event_get_switch_event(struct libinput_event *event) +{ + require_event_type(libinput_event_get_context(event), + event->type, + NULL, + LIBINPUT_EVENT_SWITCH_TOGGLE); + + return (struct libinput_event_switch *) event; +} + +LIBINPUT_EXPORT uint32_t +libinput_event_keyboard_get_time(struct libinput_event_keyboard *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_KEYBOARD_KEY); + + return us2ms(event->time); +} + +LIBINPUT_EXPORT uint64_t +libinput_event_keyboard_get_time_usec(struct libinput_event_keyboard *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_KEYBOARD_KEY); + + return event->time; +} + +LIBINPUT_EXPORT uint32_t +libinput_event_keyboard_get_key(struct libinput_event_keyboard *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_KEYBOARD_KEY); + + return event->key; +} + +LIBINPUT_EXPORT enum libinput_key_state +libinput_event_keyboard_get_key_state(struct libinput_event_keyboard *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_KEYBOARD_KEY); + + return event->state; +} + +LIBINPUT_EXPORT uint32_t +libinput_event_keyboard_get_seat_key_count( + struct libinput_event_keyboard *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_KEYBOARD_KEY); + + return event->seat_key_count; +} + +LIBINPUT_EXPORT uint32_t +libinput_event_pointer_get_time(struct libinput_event_pointer *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_POINTER_MOTION, + LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, + LIBINPUT_EVENT_POINTER_BUTTON, + LIBINPUT_EVENT_POINTER_AXIS); + + return us2ms(event->time); +} + +LIBINPUT_EXPORT uint64_t +libinput_event_pointer_get_time_usec(struct libinput_event_pointer *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_POINTER_MOTION, + LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, + LIBINPUT_EVENT_POINTER_BUTTON, + LIBINPUT_EVENT_POINTER_AXIS); + + return event->time; +} + +LIBINPUT_EXPORT double +libinput_event_pointer_get_dx(struct libinput_event_pointer *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_POINTER_MOTION); + + return event->delta.x; +} + +LIBINPUT_EXPORT double +libinput_event_pointer_get_dy(struct libinput_event_pointer *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_POINTER_MOTION); + + return event->delta.y; +} + +LIBINPUT_EXPORT double +libinput_event_pointer_get_dx_unaccelerated( + struct libinput_event_pointer *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_POINTER_MOTION); + + return event->delta_raw.x; +} + +LIBINPUT_EXPORT double +libinput_event_pointer_get_dy_unaccelerated( + struct libinput_event_pointer *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_POINTER_MOTION); + + return event->delta_raw.y; +} + +LIBINPUT_EXPORT double +libinput_event_pointer_get_absolute_x(struct libinput_event_pointer *event) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT double +libinput_event_pointer_get_absolute_y(struct libinput_event_pointer *event) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT double +libinput_event_pointer_get_absolute_x_transformed( + struct libinput_event_pointer *event, + uint32_t width) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT double +libinput_event_pointer_get_absolute_y_transformed( + struct libinput_event_pointer *event, + uint32_t height) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT uint32_t +libinput_event_pointer_get_button(struct libinput_event_pointer *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_POINTER_BUTTON); + + return event->button; +} + +LIBINPUT_EXPORT enum libinput_button_state +libinput_event_pointer_get_button_state(struct libinput_event_pointer *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_POINTER_BUTTON); + + return event->state; +} + +LIBINPUT_EXPORT uint32_t +libinput_event_pointer_get_seat_button_count( + struct libinput_event_pointer *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_POINTER_BUTTON); + + return event->seat_button_count; +} + +LIBINPUT_EXPORT int +libinput_event_pointer_has_axis(struct libinput_event_pointer *event, + enum libinput_pointer_axis axis) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_POINTER_AXIS); + + switch (axis) { + case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL: + case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: + return !!(event->axes & bit(axis)); + } + + return 0; +} + +LIBINPUT_EXPORT double +libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event, + enum libinput_pointer_axis axis) +{ + struct libinput *libinput = event->base.device->seat->libinput; + double value = 0; + + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0.0, + LIBINPUT_EVENT_POINTER_AXIS); + + if (!libinput_event_pointer_has_axis(event, axis)) { + log_bug_client(libinput, "value requested for unset axis\n"); + } else { + switch (axis) { + case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL: + value = event->delta.x; + break; + case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: + value = event->delta.y; + break; + } + } + + return value; +} + +LIBINPUT_EXPORT double +libinput_event_pointer_get_axis_value_discrete(struct libinput_event_pointer *event, + enum libinput_pointer_axis axis) +{ + struct libinput *libinput = event->base.device->seat->libinput; + double value = 0; + + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0.0, + LIBINPUT_EVENT_POINTER_AXIS); + + if (!libinput_event_pointer_has_axis(event, axis)) { + log_bug_client(libinput, "value requested for unset axis\n"); + } else { + switch (axis) { + case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL: + value = event->discrete.x; + break; + case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: + value = event->discrete.y; + break; + } + } + return value; +} + +LIBINPUT_EXPORT enum libinput_pointer_axis_source +libinput_event_pointer_get_axis_source(struct libinput_event_pointer *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_POINTER_AXIS); + + return event->source; +} + +LIBINPUT_EXPORT uint32_t +libinput_event_touch_get_time(struct libinput_event_touch *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TOUCH_DOWN, + LIBINPUT_EVENT_TOUCH_UP, + LIBINPUT_EVENT_TOUCH_MOTION, + LIBINPUT_EVENT_TOUCH_CANCEL, + LIBINPUT_EVENT_TOUCH_FRAME); + + return us2ms(event->time); +} + +LIBINPUT_EXPORT uint64_t +libinput_event_touch_get_time_usec(struct libinput_event_touch *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TOUCH_DOWN, + LIBINPUT_EVENT_TOUCH_UP, + LIBINPUT_EVENT_TOUCH_MOTION, + LIBINPUT_EVENT_TOUCH_CANCEL, + LIBINPUT_EVENT_TOUCH_FRAME); + + return event->time; +} + +LIBINPUT_EXPORT int32_t +libinput_event_touch_get_slot(struct libinput_event_touch *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TOUCH_DOWN, + LIBINPUT_EVENT_TOUCH_UP, + LIBINPUT_EVENT_TOUCH_MOTION, + LIBINPUT_EVENT_TOUCH_CANCEL); + + return event->slot; +} + +LIBINPUT_EXPORT int32_t +libinput_event_touch_get_seat_slot(struct libinput_event_touch *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TOUCH_DOWN, + LIBINPUT_EVENT_TOUCH_UP, + LIBINPUT_EVENT_TOUCH_MOTION, + LIBINPUT_EVENT_TOUCH_CANCEL); + + return event->seat_slot; +} + +LIBINPUT_EXPORT double +libinput_event_touch_get_x(struct libinput_event_touch *event) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT double +libinput_event_touch_get_x_transformed(struct libinput_event_touch *event, + uint32_t width) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT double +libinput_event_touch_get_y_transformed(struct libinput_event_touch *event, + uint32_t height) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT double +libinput_event_touch_get_y(struct libinput_event_touch *event) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT uint32_t +libinput_event_gesture_get_time(struct libinput_event_gesture *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, + LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, + LIBINPUT_EVENT_GESTURE_PINCH_END, + LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, + LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, + LIBINPUT_EVENT_GESTURE_SWIPE_END); + + return us2ms(event->time); +} + +LIBINPUT_EXPORT uint64_t +libinput_event_gesture_get_time_usec(struct libinput_event_gesture *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, + LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, + LIBINPUT_EVENT_GESTURE_PINCH_END, + LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, + LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, + LIBINPUT_EVENT_GESTURE_SWIPE_END); + + return event->time; +} + +LIBINPUT_EXPORT int +libinput_event_gesture_get_finger_count(struct libinput_event_gesture *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, + LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, + LIBINPUT_EVENT_GESTURE_PINCH_END, + LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, + LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, + LIBINPUT_EVENT_GESTURE_SWIPE_END); + + return event->finger_count; +} + +LIBINPUT_EXPORT int +libinput_event_gesture_get_cancelled(struct libinput_event_gesture *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_GESTURE_PINCH_END, + LIBINPUT_EVENT_GESTURE_SWIPE_END); + + return event->cancelled; +} + +LIBINPUT_EXPORT double +libinput_event_gesture_get_dx(struct libinput_event_gesture *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0.0, + LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, + LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, + LIBINPUT_EVENT_GESTURE_PINCH_END, + LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, + LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, + LIBINPUT_EVENT_GESTURE_SWIPE_END); + + return event->delta.x; +} + +LIBINPUT_EXPORT double +libinput_event_gesture_get_dy(struct libinput_event_gesture *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0.0, + LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, + LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, + LIBINPUT_EVENT_GESTURE_PINCH_END, + LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, + LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, + LIBINPUT_EVENT_GESTURE_SWIPE_END); + + return event->delta.y; +} + +LIBINPUT_EXPORT double +libinput_event_gesture_get_dx_unaccelerated( + struct libinput_event_gesture *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0.0, + LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, + LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, + LIBINPUT_EVENT_GESTURE_PINCH_END, + LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, + LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, + LIBINPUT_EVENT_GESTURE_SWIPE_END); + + return event->delta_unaccel.x; +} + +LIBINPUT_EXPORT double +libinput_event_gesture_get_dy_unaccelerated( + struct libinput_event_gesture *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0.0, + LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, + LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, + LIBINPUT_EVENT_GESTURE_PINCH_END, + LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, + LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, + LIBINPUT_EVENT_GESTURE_SWIPE_END); + + return event->delta_unaccel.y; +} + +LIBINPUT_EXPORT double +libinput_event_gesture_get_scale(struct libinput_event_gesture *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0.0, + LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, + LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, + LIBINPUT_EVENT_GESTURE_PINCH_END); + + return event->scale; +} + +LIBINPUT_EXPORT double +libinput_event_gesture_get_angle_delta(struct libinput_event_gesture *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0.0, + LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, + LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, + LIBINPUT_EVENT_GESTURE_PINCH_END); + + return event->angle; +} + +LIBINPUT_EXPORT int +libinput_event_tablet_tool_x_has_changed( + struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return bit_is_set(event->changed_axes, + LIBINPUT_TABLET_TOOL_AXIS_X); +} + +LIBINPUT_EXPORT int +libinput_event_tablet_tool_y_has_changed( + struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return bit_is_set(event->changed_axes, + LIBINPUT_TABLET_TOOL_AXIS_Y); +} + +LIBINPUT_EXPORT int +libinput_event_tablet_tool_pressure_has_changed( + struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return bit_is_set(event->changed_axes, + LIBINPUT_TABLET_TOOL_AXIS_PRESSURE); +} + +LIBINPUT_EXPORT int +libinput_event_tablet_tool_distance_has_changed( + struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return bit_is_set(event->changed_axes, + LIBINPUT_TABLET_TOOL_AXIS_DISTANCE); +} + +LIBINPUT_EXPORT int +libinput_event_tablet_tool_tilt_x_has_changed( + struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return bit_is_set(event->changed_axes, + LIBINPUT_TABLET_TOOL_AXIS_TILT_X); +} + +LIBINPUT_EXPORT int +libinput_event_tablet_tool_tilt_y_has_changed( + struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return bit_is_set(event->changed_axes, + LIBINPUT_TABLET_TOOL_AXIS_TILT_Y); +} + +LIBINPUT_EXPORT int +libinput_event_tablet_tool_rotation_has_changed( + struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return bit_is_set(event->changed_axes, + LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z); +} + +LIBINPUT_EXPORT int +libinput_event_tablet_tool_slider_has_changed( + struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return bit_is_set(event->changed_axes, + LIBINPUT_TABLET_TOOL_AXIS_SLIDER); +} + +LIBINPUT_EXPORT int +libinput_event_tablet_tool_size_major_has_changed( + struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return bit_is_set(event->changed_axes, + LIBINPUT_TABLET_TOOL_AXIS_SIZE_MAJOR); +} + +LIBINPUT_EXPORT int +libinput_event_tablet_tool_size_minor_has_changed( + struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return bit_is_set(event->changed_axes, + LIBINPUT_TABLET_TOOL_AXIS_SIZE_MINOR); +} + +LIBINPUT_EXPORT int +libinput_event_tablet_tool_wheel_has_changed( + struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return bit_is_set(event->changed_axes, + LIBINPUT_TABLET_TOOL_AXIS_REL_WHEEL); +} + +LIBINPUT_EXPORT double +libinput_event_tablet_tool_get_x(struct libinput_event_tablet_tool *event) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT double +libinput_event_tablet_tool_get_y(struct libinput_event_tablet_tool *event) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT double +libinput_event_tablet_tool_get_dx(struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return event->axes.delta.x; +} + +LIBINPUT_EXPORT double +libinput_event_tablet_tool_get_dy(struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return event->axes.delta.y; +} + +LIBINPUT_EXPORT double +libinput_event_tablet_tool_get_pressure(struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return event->axes.pressure; +} + +LIBINPUT_EXPORT double +libinput_event_tablet_tool_get_distance(struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return event->axes.distance; +} + +LIBINPUT_EXPORT double +libinput_event_tablet_tool_get_tilt_x(struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return event->axes.tilt.x; +} + +LIBINPUT_EXPORT double +libinput_event_tablet_tool_get_tilt_y(struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return event->axes.tilt.y; +} + +LIBINPUT_EXPORT double +libinput_event_tablet_tool_get_rotation(struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return event->axes.rotation; +} + +LIBINPUT_EXPORT double +libinput_event_tablet_tool_get_slider_position(struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return event->axes.slider; +} + +LIBINPUT_EXPORT double +libinput_event_tablet_tool_get_size_major(struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return event->axes.size.major; +} + +LIBINPUT_EXPORT double +libinput_event_tablet_tool_get_size_minor(struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return event->axes.size.minor; +} + +LIBINPUT_EXPORT double +libinput_event_tablet_tool_get_wheel_delta(struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return event->axes.wheel; +} + +LIBINPUT_EXPORT int +libinput_event_tablet_tool_get_wheel_delta_discrete( + struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return event->axes.wheel_discrete; +} + +LIBINPUT_EXPORT double +libinput_event_tablet_tool_get_x_transformed(struct libinput_event_tablet_tool *event, + uint32_t width) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT double +libinput_event_tablet_tool_get_y_transformed(struct libinput_event_tablet_tool *event, + uint32_t height) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT struct libinput_tablet_tool * +libinput_event_tablet_tool_get_tool(struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return event->tool; +} + +LIBINPUT_EXPORT enum libinput_tablet_tool_proximity_state +libinput_event_tablet_tool_get_proximity_state(struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return event->proximity_state; +} + +LIBINPUT_EXPORT enum libinput_tablet_tool_tip_state +libinput_event_tablet_tool_get_tip_state(struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return event->tip_state; +} + +LIBINPUT_EXPORT uint32_t +libinput_event_tablet_tool_get_time(struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return us2ms(event->time); +} + +LIBINPUT_EXPORT uint64_t +libinput_event_tablet_tool_get_time_usec(struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + + return event->time; +} + +LIBINPUT_EXPORT uint32_t +libinput_event_tablet_tool_get_button(struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON); + + return event->button; +} + +LIBINPUT_EXPORT enum libinput_button_state +libinput_event_tablet_tool_get_button_state(struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON); + + return event->state; +} + +LIBINPUT_EXPORT uint32_t +libinput_event_tablet_tool_get_seat_button_count(struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON); + + return event->seat_button_count; +} + +LIBINPUT_EXPORT enum libinput_tablet_tool_type +libinput_tablet_tool_get_type(struct libinput_tablet_tool *tool) +{ + return tool->type; +} + +LIBINPUT_EXPORT uint64_t +libinput_tablet_tool_get_tool_id(struct libinput_tablet_tool *tool) +{ + return tool->tool_id; +} + +LIBINPUT_EXPORT int +libinput_tablet_tool_is_unique(struct libinput_tablet_tool *tool) +{ + return tool->serial != 0; +} + +LIBINPUT_EXPORT uint64_t +libinput_tablet_tool_get_serial(struct libinput_tablet_tool *tool) +{ + return tool->serial; +} + +LIBINPUT_EXPORT int +libinput_tablet_tool_has_pressure(struct libinput_tablet_tool *tool) +{ + return bit_is_set(tool->axis_caps, + LIBINPUT_TABLET_TOOL_AXIS_PRESSURE); +} + +LIBINPUT_EXPORT int +libinput_tablet_tool_has_distance(struct libinput_tablet_tool *tool) +{ + return bit_is_set(tool->axis_caps, + LIBINPUT_TABLET_TOOL_AXIS_DISTANCE); +} + +LIBINPUT_EXPORT int +libinput_tablet_tool_has_tilt(struct libinput_tablet_tool *tool) +{ + return bit_is_set(tool->axis_caps, + LIBINPUT_TABLET_TOOL_AXIS_TILT_X); +} + +LIBINPUT_EXPORT int +libinput_tablet_tool_has_rotation(struct libinput_tablet_tool *tool) +{ + return bit_is_set(tool->axis_caps, + LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z); +} + +LIBINPUT_EXPORT int +libinput_tablet_tool_has_slider(struct libinput_tablet_tool *tool) +{ + return bit_is_set(tool->axis_caps, + LIBINPUT_TABLET_TOOL_AXIS_SLIDER); +} + +LIBINPUT_EXPORT int +libinput_tablet_tool_has_wheel(struct libinput_tablet_tool *tool) +{ + return bit_is_set(tool->axis_caps, + LIBINPUT_TABLET_TOOL_AXIS_REL_WHEEL); +} + +LIBINPUT_EXPORT int +libinput_tablet_tool_has_size(struct libinput_tablet_tool *tool) +{ + return bit_is_set(tool->axis_caps, + LIBINPUT_TABLET_TOOL_AXIS_SIZE_MAJOR); +} + +LIBINPUT_EXPORT int +libinput_tablet_tool_has_button(struct libinput_tablet_tool *tool, + uint32_t code) +{ + if (NCHARS(code) > sizeof(tool->buttons)) + return 0; + + return bit_is_set(tool->buttons, code); +} + +LIBINPUT_EXPORT void +libinput_tablet_tool_set_user_data(struct libinput_tablet_tool *tool, + void *user_data) +{ + tool->user_data = user_data; +} + +LIBINPUT_EXPORT void * +libinput_tablet_tool_get_user_data(struct libinput_tablet_tool *tool) +{ + return tool->user_data; +} + +LIBINPUT_EXPORT struct libinput_tablet_tool * +libinput_tablet_tool_ref(struct libinput_tablet_tool *tool) +{ + tool->refcount++; + return tool; +} + +LIBINPUT_EXPORT struct libinput_tablet_tool * +libinput_tablet_tool_unref(struct libinput_tablet_tool *tool) +{ + assert(tool->refcount > 0); + + tool->refcount--; + if (tool->refcount > 0) + return tool; + + list_remove(&tool->link); + free(tool); + return NULL; +} + +LIBINPUT_EXPORT struct libinput_event * +libinput_event_switch_get_base_event(struct libinput_event_switch *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + NULL, + LIBINPUT_EVENT_SWITCH_TOGGLE); + + return &event->base; +} + +LIBINPUT_EXPORT enum libinput_switch +libinput_event_switch_get_switch(struct libinput_event_switch *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_SWITCH_TOGGLE); + + return event->sw; +} + +LIBINPUT_EXPORT enum libinput_switch_state +libinput_event_switch_get_switch_state(struct libinput_event_switch *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_SWITCH_TOGGLE); + + return event->state; +} + +LIBINPUT_EXPORT uint32_t +libinput_event_switch_get_time(struct libinput_event_switch *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_SWITCH_TOGGLE); + + return us2ms(event->time); +} + +LIBINPUT_EXPORT uint64_t +libinput_event_switch_get_time_usec(struct libinput_event_switch *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_SWITCH_TOGGLE); + + return event->time; +} + +struct libinput_source * +libinput_add_fd(struct libinput *libinput, + int fd, + libinput_source_dispatch_t dispatch, + void *user_data) +{ + struct libinput_source *source; + struct epoll_event ep; + + source = zalloc(sizeof *source); + source->dispatch = dispatch; + source->user_data = user_data; + source->fd = fd; + + memset(&ep, 0, sizeof ep); + ep.events = EPOLLIN; + ep.data.ptr = source; + + if (epoll_ctl(libinput->epoll_fd, EPOLL_CTL_ADD, fd, &ep) < 0) { + free(source); + return NULL; + } + + return source; +} + +void +libinput_remove_source(struct libinput *libinput, + struct libinput_source *source) +{ + epoll_ctl(libinput->epoll_fd, EPOLL_CTL_DEL, source->fd, NULL); + source->fd = -1; + list_insert(&libinput->source_destroy_list, &source->link); +} + +int +libinput_init(struct libinput *libinput, + const struct libinput_interface *interface, + const struct libinput_interface_backend *interface_backend, + void *user_data) +{ + assert(interface->open_restricted != NULL); + assert(interface->close_restricted != NULL); + + libinput->epoll_fd = epoll_create1(EPOLL_CLOEXEC); + if (libinput->epoll_fd < 0) + return -1; + + libinput->events_len = 4; + libinput->events = zalloc(libinput->events_len * sizeof(*libinput->events)); + libinput->log_handler = libinput_default_log_func; + libinput->log_priority = LIBINPUT_LOG_PRIORITY_ERROR; + libinput->interface = interface; + libinput->interface_backend = interface_backend; + libinput->user_data = user_data; + libinput->refcount = 1; + list_init(&libinput->source_destroy_list); + list_init(&libinput->seat_list); + list_init(&libinput->device_group_list); + list_init(&libinput->tool_list); + + if (libinput_timer_subsys_init(libinput) != 0) { + free(libinput->events); + close(libinput->epoll_fd); + return -1; + } + + return 0; +} + +void +libinput_init_quirks(struct libinput *libinput) +{ + const char *data_path, + *override_file = NULL; + struct quirks_context *quirks; + + if (libinput->quirks_initialized) + return; + + /* If we fail, we'll fail next time too */ + libinput->quirks_initialized = true; + + data_path = getenv("LIBINPUT_QUIRKS_DIR"); + if (!data_path) { + data_path = LIBINPUT_QUIRKS_DIR; + override_file = LIBINPUT_QUIRKS_OVERRIDE_FILE; + } + + quirks = quirks_init_subsystem(data_path, + override_file, + log_msg_va, + libinput, + QLOG_LIBINPUT_LOGGING); + if (!quirks) { + log_error(libinput, + "Failed to load the device quirks from %s%s%s. " + "This will negatively affect device behavior. " + "See %s/device-quirks.html for details.\n", + data_path, + override_file ? " and " : "", + override_file ? override_file : "", + HTTP_DOC_LINK + ); + return; + } + + libinput->quirks = quirks; +} + +static void +libinput_device_destroy(struct libinput_device *device); + +static void +libinput_seat_destroy(struct libinput_seat *seat); + +static void +libinput_drop_destroyed_sources(struct libinput *libinput) +{ + struct libinput_source *source; + + list_for_each_safe(source, &libinput->source_destroy_list, link) + free(source); + list_init(&libinput->source_destroy_list); +} + +LIBINPUT_EXPORT struct libinput * +libinput_ref(struct libinput *libinput) +{ + libinput->refcount++; + return libinput; +} + +LIBINPUT_EXPORT struct libinput * +libinput_unref(struct libinput *libinput) +{ + struct libinput_event *event; + struct libinput_device *device; + struct libinput_seat *seat; + struct libinput_tablet_tool *tool; + struct libinput_device_group *group; + + if (libinput == NULL) + return NULL; + + assert(libinput->refcount > 0); + libinput->refcount--; + if (libinput->refcount > 0) + return libinput; + + libinput_suspend(libinput); + + libinput->interface_backend->destroy(libinput); + + while ((event = libinput_get_event(libinput))) + libinput_event_destroy(event); + + free(libinput->events); + + list_for_each_safe(seat, &libinput->seat_list, link) { + list_for_each_safe(device, + &seat->devices_list, + link) + libinput_device_destroy(device); + + libinput_seat_destroy(seat); + } + + list_for_each_safe(group, + &libinput->device_group_list, + link) { + libinput_device_group_destroy(group); + } + + list_for_each_safe(tool, &libinput->tool_list, link) { + libinput_tablet_tool_unref(tool); + } + + libinput_timer_subsys_destroy(libinput); + libinput_drop_destroyed_sources(libinput); + quirks_context_unref(libinput->quirks); + close(libinput->epoll_fd); + free(libinput); + + return NULL; +} + +static void +libinput_event_tablet_tool_destroy(struct libinput_event_tablet_tool *event) +{ + libinput_tablet_tool_unref(event->tool); +} + +static void +libinput_event_tablet_pad_destroy(struct libinput_event_tablet_pad *event) +{ + if (event->base.type != LIBINPUT_EVENT_TABLET_PAD_KEY) + libinput_tablet_pad_mode_group_unref(event->mode_group); +} + +LIBINPUT_EXPORT void +libinput_event_destroy(struct libinput_event *event) +{ + if (event == NULL) + return; + + switch(event->type) { + case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY: + case LIBINPUT_EVENT_TABLET_TOOL_AXIS: + case LIBINPUT_EVENT_TABLET_TOOL_TIP: + case LIBINPUT_EVENT_TABLET_TOOL_BUTTON: + libinput_event_tablet_tool_destroy( + libinput_event_get_tablet_tool_event(event)); + break; + case LIBINPUT_EVENT_TABLET_PAD_RING: + case LIBINPUT_EVENT_TABLET_PAD_STRIP: + case LIBINPUT_EVENT_TABLET_PAD_BUTTON: + case LIBINPUT_EVENT_TABLET_PAD_KEY: + libinput_event_tablet_pad_destroy( + libinput_event_get_tablet_pad_event(event)); + break; + default: + break; + } + + if (event->device) + libinput_device_unref(event->device); + + free(event); +} + +int +open_restricted(struct libinput *libinput, + const char *path, int flags) +{ + return libinput->interface->open_restricted(path, + flags, + libinput->user_data); +} + +void +close_restricted(struct libinput *libinput, int fd) +{ + libinput->interface->close_restricted(fd, libinput->user_data); +} + +bool +ignore_litest_test_suite_device(struct udev_device *device) +{ + if (!getenv("LIBINPUT_RUNNING_TEST_SUITE") && + udev_device_get_property_value(device, "LIBINPUT_TEST_DEVICE")) + return true; + + return false; +} + +void +libinput_seat_init(struct libinput_seat *seat, + struct libinput *libinput, + const char *physical_name, + const char *logical_name, + libinput_seat_destroy_func destroy) +{ + seat->refcount = 1; + seat->libinput = libinput; + seat->physical_name = safe_strdup(physical_name); + seat->logical_name = safe_strdup(logical_name); + seat->destroy = destroy; + list_init(&seat->devices_list); + list_insert(&libinput->seat_list, &seat->link); +} + +LIBINPUT_EXPORT struct libinput_seat * +libinput_seat_ref(struct libinput_seat *seat) +{ + seat->refcount++; + return seat; +} + +static void +libinput_seat_destroy(struct libinput_seat *seat) +{ + list_remove(&seat->link); + free(seat->logical_name); + free(seat->physical_name); + seat->destroy(seat); +} + +LIBINPUT_EXPORT struct libinput_seat * +libinput_seat_unref(struct libinput_seat *seat) +{ + assert(seat->refcount > 0); + seat->refcount--; + if (seat->refcount == 0) { + libinput_seat_destroy(seat); + return NULL; + } + + return seat; +} + +LIBINPUT_EXPORT void +libinput_seat_set_user_data(struct libinput_seat *seat, void *user_data) +{ + seat->user_data = user_data; +} + +LIBINPUT_EXPORT void * +libinput_seat_get_user_data(struct libinput_seat *seat) +{ + return seat->user_data; +} + +LIBINPUT_EXPORT struct libinput * +libinput_seat_get_context(struct libinput_seat *seat) +{ + return seat->libinput; +} + +LIBINPUT_EXPORT const char * +libinput_seat_get_physical_name(struct libinput_seat *seat) +{ + return seat->physical_name; +} + +LIBINPUT_EXPORT const char * +libinput_seat_get_logical_name(struct libinput_seat *seat) +{ + return seat->logical_name; +} + +void +libinput_device_init(struct libinput_device *device, + struct libinput_seat *seat) +{ + device->seat = seat; + device->refcount = 1; + list_init(&device->event_listeners); +} + +LIBINPUT_EXPORT struct libinput_device * +libinput_device_ref(struct libinput_device *device) +{ + device->refcount++; + return device; +} + +static void +libinput_device_destroy(struct libinput_device *device) +{ + // TODO + //assert(list_empty(&device->event_listeners)); + //evdev_device_destroy(evdev_device(device)); +} + +LIBINPUT_EXPORT struct libinput_device * +libinput_device_unref(struct libinput_device *device) +{ + assert(device->refcount > 0); + device->refcount--; + if (device->refcount == 0) { + libinput_device_destroy(device); + return NULL; + } + + return device; +} + +LIBINPUT_EXPORT int +libinput_get_fd(struct libinput *libinput) +{ + return libinput->epoll_fd; +} + +LIBINPUT_EXPORT int +libinput_dispatch(struct libinput *libinput) +{ + static uint8_t take_time_snapshot; + struct libinput_source *source; + struct epoll_event ep[32]; + int i, count; + + /* Every 10 calls to libinput_dispatch() we take the current time so + * we can check the delay between our current time and the event + * timestamps */ + if ((++take_time_snapshot % 10) == 0) + libinput->dispatch_time = libinput_now(libinput); + else if (libinput->dispatch_time) + libinput->dispatch_time = 0; + + count = epoll_wait(libinput->epoll_fd, ep, ARRAY_LENGTH(ep), 0); + if (count < 0) + return -errno; + + for (i = 0; i < count; ++i) { + source = ep[i].data.ptr; + if (source->fd == -1) + continue; + + source->dispatch(source->user_data); + } + + libinput_drop_destroyed_sources(libinput); + + return 0; +} + +void +libinput_device_init_event_listener(struct libinput_event_listener *listener) +{ + list_init(&listener->link); +} + +void +libinput_device_add_event_listener(struct libinput_device *device, + struct libinput_event_listener *listener, + void (*notify_func)( + uint64_t time, + struct libinput_event *event, + void *notify_func_data), + void *notify_func_data) +{ + listener->notify_func = notify_func; + listener->notify_func_data = notify_func_data; + list_insert(&device->event_listeners, &listener->link); +} + +void +libinput_device_remove_event_listener(struct libinput_event_listener *listener) +{ + list_remove(&listener->link); +} + +static uint32_t +update_seat_key_count(struct libinput_seat *seat, + int32_t key, + enum libinput_key_state state) +{ + assert(key >= 0 && key <= KEY_MAX); + + switch (state) { + case LIBINPUT_KEY_STATE_PRESSED: + return ++seat->button_count[key]; + case LIBINPUT_KEY_STATE_RELEASED: + /* We might not have received the first PRESSED event. */ + if (seat->button_count[key] == 0) + return 0; + + return --seat->button_count[key]; + } + + return 0; +} + +static uint32_t +update_seat_button_count(struct libinput_seat *seat, + int32_t button, + enum libinput_button_state state) +{ + assert(button >= 0 && button <= KEY_MAX); + + switch (state) { + case LIBINPUT_BUTTON_STATE_PRESSED: + return ++seat->button_count[button]; + case LIBINPUT_BUTTON_STATE_RELEASED: + /* We might not have received the first PRESSED event. */ + if (seat->button_count[button] == 0) + return 0; + + return --seat->button_count[button]; + } + + return 0; +} + +static void +init_event_base(struct libinput_event *event, + struct libinput_device *device, + enum libinput_event_type type) +{ + event->type = type; + event->device = device; +} + +static void +post_base_event(struct libinput_device *device, + enum libinput_event_type type, + struct libinput_event *event) +{ + struct libinput *libinput = device->seat->libinput; + init_event_base(event, device, type); + libinput_post_event(libinput, event); +} + +static void +post_device_event(struct libinput_device *device, + uint64_t time, + enum libinput_event_type type, + struct libinput_event *event) +{ + struct libinput_event_listener *listener; +#if 0 + struct libinput *libinput = device->seat->libinput; + + if (libinput->last_event_time > time) { + log_bug_libinput(device->seat->libinput, + "out-of-order timestamps for %s time %" PRIu64 "\n", + event_type_to_str(type), + time); + } + libinput->last_event_time = time; +#endif + + init_event_base(event, device, type); + + list_for_each_safe(listener, &device->event_listeners, link) + listener->notify_func(time, event, listener->notify_func_data); + + libinput_post_event(device->seat->libinput, event); +} + +void +notify_added_device(struct libinput_device *device) +{ + struct libinput_event_device_notify *added_device_event; + + added_device_event = zalloc(sizeof *added_device_event); + + post_base_event(device, + LIBINPUT_EVENT_DEVICE_ADDED, + &added_device_event->base); + +#ifdef __clang_analyzer__ + /* clang doesn't realize we're not leaking the event here, so + * pretend to free it */ + free(added_device_event); +#endif +} + +void +notify_removed_device(struct libinput_device *device) +{ + struct libinput_event_device_notify *removed_device_event; + + removed_device_event = zalloc(sizeof *removed_device_event); + + post_base_event(device, + LIBINPUT_EVENT_DEVICE_REMOVED, + &removed_device_event->base); + +#ifdef __clang_analyzer__ + /* clang doesn't realize we're not leaking the event here, so + * pretend to free it */ + free(removed_device_event); +#endif +} + +static inline bool +device_has_cap(struct libinput_device *device, + enum libinput_device_capability cap) +{ + const char *capability; + + if (libinput_device_has_capability(device, cap)) + return true; + + switch (cap) { + case LIBINPUT_DEVICE_CAP_POINTER: + capability = "CAP_POINTER"; + break; + case LIBINPUT_DEVICE_CAP_KEYBOARD: + capability = "CAP_KEYBOARD"; + break; + case LIBINPUT_DEVICE_CAP_TOUCH: + capability = "CAP_TOUCH"; + break; + case LIBINPUT_DEVICE_CAP_GESTURE: + capability = "CAP_GESTURE"; + break; + case LIBINPUT_DEVICE_CAP_TABLET_TOOL: + capability = "CAP_TABLET_TOOL"; + break; + case LIBINPUT_DEVICE_CAP_TABLET_PAD: + capability = "CAP_TABLET_PAD"; + break; + case LIBINPUT_DEVICE_CAP_SWITCH: + capability = "CAP_SWITCH"; + break; + } + + log_bug_libinput(device->seat->libinput, + "Event for missing capability %s on device \"%s\"\n", + capability, + libinput_device_get_name(device)); + + return false; +} + +void +keyboard_notify_key(struct libinput_device *device, + uint64_t time, + uint32_t key, + enum libinput_key_state state) +{ + struct libinput_event_keyboard *key_event; + uint32_t seat_key_count; + + if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_KEYBOARD)) + return; + + key_event = zalloc(sizeof *key_event); + + seat_key_count = update_seat_key_count(device->seat, key, state); + + *key_event = (struct libinput_event_keyboard) { + .time = time, + .key = key, + .state = state, + .seat_key_count = seat_key_count, + }; + + post_device_event(device, time, + LIBINPUT_EVENT_KEYBOARD_KEY, + &key_event->base); +} + +void +pointer_notify_motion(struct libinput_device *device, + uint64_t time, + const struct normalized_coords *delta, + const struct device_float_coords *raw) +{ + struct libinput_event_pointer *motion_event; + + if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER)) + return; + + motion_event = zalloc(sizeof *motion_event); + + *motion_event = (struct libinput_event_pointer) { + .time = time, + .delta = *delta, + .delta_raw = *raw, + }; + + post_device_event(device, time, + LIBINPUT_EVENT_POINTER_MOTION, + &motion_event->base); +} + +void +pointer_notify_motion_absolute(struct libinput_device *device, + uint64_t time, + const struct device_coords *point) +{ + struct libinput_event_pointer *motion_absolute_event; + + if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER)) + return; + + motion_absolute_event = zalloc(sizeof *motion_absolute_event); + + *motion_absolute_event = (struct libinput_event_pointer) { + .time = time, + .absolute = *point, + }; + + post_device_event(device, time, + LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, + &motion_absolute_event->base); +} + +void +pointer_notify_button(struct libinput_device *device, + uint64_t time, + int32_t button, + enum libinput_button_state state) +{ + struct libinput_event_pointer *button_event; + int32_t seat_button_count; + + if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER)) + return; + + button_event = zalloc(sizeof *button_event); + + seat_button_count = update_seat_button_count(device->seat, + button, + state); + + *button_event = (struct libinput_event_pointer) { + .time = time, + .button = button, + .state = state, + .seat_button_count = seat_button_count, + }; + + post_device_event(device, time, + LIBINPUT_EVENT_POINTER_BUTTON, + &button_event->base); +} + +void +pointer_notify_axis(struct libinput_device *device, + uint64_t time, + uint32_t axes, + enum libinput_pointer_axis_source source, + const struct normalized_coords *delta, + const struct discrete_coords *discrete) +{ + struct libinput_event_pointer *axis_event; + + if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER)) + return; + + axis_event = zalloc(sizeof *axis_event); + + *axis_event = (struct libinput_event_pointer) { + .time = time, + .delta = *delta, + .source = source, + .axes = axes, + .discrete = *discrete, + }; + + post_device_event(device, time, + LIBINPUT_EVENT_POINTER_AXIS, + &axis_event->base); +} + +void +touch_notify_touch_down(struct libinput_device *device, + uint64_t time, + int32_t slot, + int32_t seat_slot, + const struct device_coords *point) +{ + struct libinput_event_touch *touch_event; + + if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_TOUCH)) + return; + + touch_event = zalloc(sizeof *touch_event); + + *touch_event = (struct libinput_event_touch) { + .time = time, + .slot = slot, + .seat_slot = seat_slot, + .point = *point, + }; + + post_device_event(device, time, + LIBINPUT_EVENT_TOUCH_DOWN, + &touch_event->base); +} + +void +touch_notify_touch_motion(struct libinput_device *device, + uint64_t time, + int32_t slot, + int32_t seat_slot, + const struct device_coords *point) +{ + struct libinput_event_touch *touch_event; + + if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_TOUCH)) + return; + + touch_event = zalloc(sizeof *touch_event); + + *touch_event = (struct libinput_event_touch) { + .time = time, + .slot = slot, + .seat_slot = seat_slot, + .point = *point, + }; + + post_device_event(device, time, + LIBINPUT_EVENT_TOUCH_MOTION, + &touch_event->base); +} + +void +touch_notify_touch_up(struct libinput_device *device, + uint64_t time, + int32_t slot, + int32_t seat_slot) +{ + struct libinput_event_touch *touch_event; + + if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_TOUCH)) + return; + + touch_event = zalloc(sizeof *touch_event); + + *touch_event = (struct libinput_event_touch) { + .time = time, + .slot = slot, + .seat_slot = seat_slot, + }; + + post_device_event(device, time, + LIBINPUT_EVENT_TOUCH_UP, + &touch_event->base); +} + +void +touch_notify_touch_cancel(struct libinput_device *device, + uint64_t time, + int32_t slot, + int32_t seat_slot) +{ + struct libinput_event_touch *touch_event; + + if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_TOUCH)) + return; + + touch_event = zalloc(sizeof *touch_event); + + *touch_event = (struct libinput_event_touch) { + .time = time, + .slot = slot, + .seat_slot = seat_slot, + }; + + post_device_event(device, time, + LIBINPUT_EVENT_TOUCH_CANCEL, + &touch_event->base); +} + +void +touch_notify_frame(struct libinput_device *device, + uint64_t time) +{ + struct libinput_event_touch *touch_event; + + if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_TOUCH)) + return; + + touch_event = zalloc(sizeof *touch_event); + + *touch_event = (struct libinput_event_touch) { + .time = time, + }; + + post_device_event(device, time, + LIBINPUT_EVENT_TOUCH_FRAME, + &touch_event->base); +} + +void +tablet_notify_axis(struct libinput_device *device, + uint64_t time, + struct libinput_tablet_tool *tool, + enum libinput_tablet_tool_tip_state tip_state, + unsigned char *changed_axes, + const struct tablet_axes *axes) +{ + struct libinput_event_tablet_tool *axis_event; + + axis_event = zalloc(sizeof *axis_event); + + *axis_event = (struct libinput_event_tablet_tool) { + .time = time, + .tool = libinput_tablet_tool_ref(tool), + .proximity_state = LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN, + .tip_state = tip_state, + .axes = *axes, + }; + + memcpy(axis_event->changed_axes, + changed_axes, + sizeof(axis_event->changed_axes)); + + post_device_event(device, + time, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + &axis_event->base); +} + +void +tablet_notify_proximity(struct libinput_device *device, + uint64_t time, + struct libinput_tablet_tool *tool, + enum libinput_tablet_tool_proximity_state proximity_state, + unsigned char *changed_axes, + const struct tablet_axes *axes) +{ + struct libinput_event_tablet_tool *proximity_event; + + proximity_event = zalloc(sizeof *proximity_event); + + *proximity_event = (struct libinput_event_tablet_tool) { + .time = time, + .tool = libinput_tablet_tool_ref(tool), + .tip_state = LIBINPUT_TABLET_TOOL_TIP_UP, + .proximity_state = proximity_state, + .axes = *axes, + }; + memcpy(proximity_event->changed_axes, + changed_axes, + sizeof(proximity_event->changed_axes)); + + post_device_event(device, + time, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + &proximity_event->base); +} + +void +tablet_notify_tip(struct libinput_device *device, + uint64_t time, + struct libinput_tablet_tool *tool, + enum libinput_tablet_tool_tip_state tip_state, + unsigned char *changed_axes, + const struct tablet_axes *axes) +{ + struct libinput_event_tablet_tool *tip_event; + + tip_event = zalloc(sizeof *tip_event); + + *tip_event = (struct libinput_event_tablet_tool) { + .time = time, + .tool = libinput_tablet_tool_ref(tool), + .tip_state = tip_state, + .proximity_state = LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN, + .axes = *axes, + }; + memcpy(tip_event->changed_axes, + changed_axes, + sizeof(tip_event->changed_axes)); + + post_device_event(device, + time, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + &tip_event->base); +} + +void +tablet_notify_button(struct libinput_device *device, + uint64_t time, + struct libinput_tablet_tool *tool, + enum libinput_tablet_tool_tip_state tip_state, + const struct tablet_axes *axes, + int32_t button, + enum libinput_button_state state) +{ + struct libinput_event_tablet_tool *button_event; + int32_t seat_button_count; + + button_event = zalloc(sizeof *button_event); + + seat_button_count = update_seat_button_count(device->seat, + button, + state); + + *button_event = (struct libinput_event_tablet_tool) { + .time = time, + .tool = libinput_tablet_tool_ref(tool), + .button = button, + .state = state, + .seat_button_count = seat_button_count, + .proximity_state = LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN, + .tip_state = tip_state, + .axes = *axes, + }; + + post_device_event(device, + time, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + &button_event->base); +} + +void +tablet_pad_notify_button(struct libinput_device *device, + uint64_t time, + int32_t button, + enum libinput_button_state state, + struct libinput_tablet_pad_mode_group *group) +{ + struct libinput_event_tablet_pad *button_event; + unsigned int mode; + + button_event = zalloc(sizeof *button_event); + + mode = libinput_tablet_pad_mode_group_get_mode(group); + + *button_event = (struct libinput_event_tablet_pad) { + .time = time, + .button.number = button, + .button.state = state, + .mode_group = libinput_tablet_pad_mode_group_ref(group), + .mode = mode, + }; + + post_device_event(device, + time, + LIBINPUT_EVENT_TABLET_PAD_BUTTON, + &button_event->base); +} + +void +tablet_pad_notify_ring(struct libinput_device *device, + uint64_t time, + unsigned int number, + double value, + enum libinput_tablet_pad_ring_axis_source source, + struct libinput_tablet_pad_mode_group *group) +{ + struct libinput_event_tablet_pad *ring_event; + unsigned int mode; + + ring_event = zalloc(sizeof *ring_event); + + mode = libinput_tablet_pad_mode_group_get_mode(group); + + *ring_event = (struct libinput_event_tablet_pad) { + .time = time, + .ring.number = number, + .ring.position = value, + .ring.source = source, + .mode_group = libinput_tablet_pad_mode_group_ref(group), + .mode = mode, + }; + + post_device_event(device, + time, + LIBINPUT_EVENT_TABLET_PAD_RING, + &ring_event->base); +} + +void +tablet_pad_notify_strip(struct libinput_device *device, + uint64_t time, + unsigned int number, + double value, + enum libinput_tablet_pad_strip_axis_source source, + struct libinput_tablet_pad_mode_group *group) +{ + struct libinput_event_tablet_pad *strip_event; + unsigned int mode; + + strip_event = zalloc(sizeof *strip_event); + + mode = libinput_tablet_pad_mode_group_get_mode(group); + + *strip_event = (struct libinput_event_tablet_pad) { + .time = time, + .strip.number = number, + .strip.position = value, + .strip.source = source, + .mode_group = libinput_tablet_pad_mode_group_ref(group), + .mode = mode, + }; + + post_device_event(device, + time, + LIBINPUT_EVENT_TABLET_PAD_STRIP, + &strip_event->base); +} + +void +tablet_pad_notify_key(struct libinput_device *device, + uint64_t time, + int32_t key, + enum libinput_key_state state) +{ + struct libinput_event_tablet_pad *key_event; + + key_event = zalloc(sizeof *key_event); + + *key_event = (struct libinput_event_tablet_pad) { + .time = time, + .key.code = key, + .key.state = state, + }; + + post_device_event(device, + time, + LIBINPUT_EVENT_TABLET_PAD_KEY, + &key_event->base); +} + +static void +gesture_notify(struct libinput_device *device, + uint64_t time, + enum libinput_event_type type, + int finger_count, + bool cancelled, + const struct normalized_coords *delta, + const struct normalized_coords *unaccel, + double scale, + double angle) +{ + struct libinput_event_gesture *gesture_event; + + if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_GESTURE)) + return; + + gesture_event = zalloc(sizeof *gesture_event); + + *gesture_event = (struct libinput_event_gesture) { + .time = time, + .finger_count = finger_count, + .cancelled = cancelled, + .delta = *delta, + .delta_unaccel = *unaccel, + .scale = scale, + .angle = angle, + }; + + post_device_event(device, time, type, + &gesture_event->base); +} + +void +gesture_notify_swipe(struct libinput_device *device, + uint64_t time, + enum libinput_event_type type, + int finger_count, + const struct normalized_coords *delta, + const struct normalized_coords *unaccel) +{ + gesture_notify(device, time, type, finger_count, 0, delta, unaccel, + 0.0, 0.0); +} + +void +gesture_notify_swipe_end(struct libinput_device *device, + uint64_t time, + int finger_count, + bool cancelled) +{ + const struct normalized_coords zero = { 0.0, 0.0 }; + + gesture_notify(device, time, LIBINPUT_EVENT_GESTURE_SWIPE_END, + finger_count, cancelled, &zero, &zero, 0.0, 0.0); +} + +void +gesture_notify_pinch(struct libinput_device *device, + uint64_t time, + enum libinput_event_type type, + int finger_count, + const struct normalized_coords *delta, + const struct normalized_coords *unaccel, + double scale, + double angle) +{ + gesture_notify(device, time, type, finger_count, 0, + delta, unaccel, scale, angle); +} + +void +gesture_notify_pinch_end(struct libinput_device *device, + uint64_t time, + int finger_count, + double scale, + bool cancelled) +{ + const struct normalized_coords zero = { 0.0, 0.0 }; + + gesture_notify(device, time, LIBINPUT_EVENT_GESTURE_PINCH_END, + finger_count, cancelled, &zero, &zero, scale, 0.0); +} + +void +switch_notify_toggle(struct libinput_device *device, + uint64_t time, + enum libinput_switch sw, + enum libinput_switch_state state) +{ + struct libinput_event_switch *switch_event; + + if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_SWITCH)) + return; + + switch_event = zalloc(sizeof *switch_event); + + *switch_event = (struct libinput_event_switch) { + .time = time, + .sw = sw, + .state = state, + }; + + post_device_event(device, time, + LIBINPUT_EVENT_SWITCH_TOGGLE, + &switch_event->base); + +#ifdef __clang_analyzer__ + /* clang doesn't realize we're not leaking the event here, so + * pretend to free it */ + free(switch_event); +#endif +} + +static void +libinput_post_event(struct libinput *libinput, + struct libinput_event *event) +{ + struct libinput_event **events = libinput->events; + size_t events_len = libinput->events_len; + size_t events_count = libinput->events_count; + size_t move_len; + size_t new_out; + +#if 0 + log_debug(libinput, "Queuing %s\n", event_type_to_str(event->type)); +#endif + + events_count++; + if (events_count > events_len) { + void *tmp; + + events_len *= 2; + tmp = realloc(events, events_len * sizeof *events); + if (!tmp) { + log_error(libinput, + "Failed to reallocate event ring buffer. " + "Events may be discarded\n"); + return; + } + + events = tmp; + + if (libinput->events_count > 0 && libinput->events_in == 0) { + libinput->events_in = libinput->events_len; + } else if (libinput->events_count > 0 && + libinput->events_out >= libinput->events_in) { + move_len = libinput->events_len - libinput->events_out; + new_out = events_len - move_len; + memmove(events + new_out, + events + libinput->events_out, + move_len * sizeof *events); + libinput->events_out = new_out; + } + + libinput->events = events; + libinput->events_len = events_len; + } + + if (event->device) + libinput_device_ref(event->device); + + libinput->events_count = events_count; + events[libinput->events_in] = event; + libinput->events_in = (libinput->events_in + 1) % libinput->events_len; +} + +LIBINPUT_EXPORT struct libinput_event * +libinput_get_event(struct libinput *libinput) +{ + struct libinput_event *event; + + if (libinput->events_count == 0) + return NULL; + + event = libinput->events[libinput->events_out]; + libinput->events_out = + (libinput->events_out + 1) % libinput->events_len; + libinput->events_count--; + + return event; +} + +LIBINPUT_EXPORT enum libinput_event_type +libinput_next_event_type(struct libinput *libinput) +{ + struct libinput_event *event; + + if (libinput->events_count == 0) + return LIBINPUT_EVENT_NONE; + + event = libinput->events[libinput->events_out]; + return event->type; +} + +LIBINPUT_EXPORT void +libinput_set_user_data(struct libinput *libinput, + void *user_data) +{ + libinput->user_data = user_data; +} + +LIBINPUT_EXPORT void * +libinput_get_user_data(struct libinput *libinput) +{ + return libinput->user_data; +} + +LIBINPUT_EXPORT int +libinput_resume(struct libinput *libinput) +{ + return libinput->interface_backend->resume(libinput); +} + +LIBINPUT_EXPORT void +libinput_suspend(struct libinput *libinput) +{ + libinput->interface_backend->suspend(libinput); +} + +LIBINPUT_EXPORT void +libinput_device_set_user_data(struct libinput_device *device, void *user_data) +{ + device->user_data = user_data; +} + +LIBINPUT_EXPORT void * +libinput_device_get_user_data(struct libinput_device *device) +{ + return device->user_data; +} + +LIBINPUT_EXPORT struct libinput * +libinput_device_get_context(struct libinput_device *device) +{ + return libinput_seat_get_context(device->seat); +} + +LIBINPUT_EXPORT struct libinput_device_group * +libinput_device_get_device_group(struct libinput_device *device) +{ + return device->group; +} + +LIBINPUT_EXPORT const char * +libinput_device_get_sysname(struct libinput_device *device) +{ + return NULL; // TODO +} + +LIBINPUT_EXPORT const char * +libinput_device_get_name(struct libinput_device *device) +{ + return NULL; // TODO +} + +LIBINPUT_EXPORT unsigned int +libinput_device_get_id_product(struct libinput_device *device) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT unsigned int +libinput_device_get_id_vendor(struct libinput_device *device) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT const char * +libinput_device_get_output_name(struct libinput_device *device) +{ + return NULL; // TODO +} + +LIBINPUT_EXPORT struct libinput_seat * +libinput_device_get_seat(struct libinput_device *device) +{ + return device->seat; +} + +LIBINPUT_EXPORT int +libinput_device_set_seat_logical_name(struct libinput_device *device, + const char *name) +{ + struct libinput *libinput = device->seat->libinput; + + if (name == NULL) + return -1; + + return libinput->interface_backend->device_change_seat(device, + name); +} + +LIBINPUT_EXPORT struct udev_device * +libinput_device_get_udev_device(struct libinput_device *device) +{ + return NULL; // TODO +} + +LIBINPUT_EXPORT void +libinput_device_led_update(struct libinput_device *device, + enum libinput_led leds) +{ + // TODO +} + +LIBINPUT_EXPORT int +libinput_device_has_capability(struct libinput_device *device, + enum libinput_device_capability capability) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT int +libinput_device_get_size(struct libinput_device *device, + double *width, + double *height) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT int +libinput_device_pointer_has_button(struct libinput_device *device, uint32_t code) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT int +libinput_device_keyboard_has_key(struct libinput_device *device, uint32_t code) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT int +libinput_device_touch_get_touch_count(struct libinput_device *device) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT int +libinput_device_switch_has_switch(struct libinput_device *device, + enum libinput_switch sw) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT int +libinput_device_tablet_pad_has_key(struct libinput_device *device, uint32_t code) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT int +libinput_device_tablet_pad_get_num_buttons(struct libinput_device *device) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT int +libinput_device_tablet_pad_get_num_rings(struct libinput_device *device) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT int +libinput_device_tablet_pad_get_num_strips(struct libinput_device *device) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT int +libinput_device_tablet_pad_get_num_mode_groups(struct libinput_device *device) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT struct libinput_tablet_pad_mode_group* +libinput_device_tablet_pad_get_mode_group(struct libinput_device *device, + unsigned int index) +{ + return 0xdeadbeef; // TODO +} + +LIBINPUT_EXPORT unsigned int +libinput_tablet_pad_mode_group_get_num_modes( + struct libinput_tablet_pad_mode_group *group) +{ + return group->num_modes; +} + +LIBINPUT_EXPORT unsigned int +libinput_tablet_pad_mode_group_get_mode(struct libinput_tablet_pad_mode_group *group) +{ + return group->current_mode; +} + +LIBINPUT_EXPORT unsigned int +libinput_tablet_pad_mode_group_get_index(struct libinput_tablet_pad_mode_group *group) +{ + return group->index; +} + +LIBINPUT_EXPORT int +libinput_tablet_pad_mode_group_has_button(struct libinput_tablet_pad_mode_group *group, + unsigned int button) +{ + if ((int)button >= + libinput_device_tablet_pad_get_num_buttons(group->device)) + return 0; + + return !!(group->button_mask & (1 << button)); +} + +LIBINPUT_EXPORT int +libinput_tablet_pad_mode_group_has_ring(struct libinput_tablet_pad_mode_group *group, + unsigned int ring) +{ + if ((int)ring >= + libinput_device_tablet_pad_get_num_rings(group->device)) + return 0; + + return !!(group->ring_mask & (1 << ring)); +} + +LIBINPUT_EXPORT int +libinput_tablet_pad_mode_group_has_strip(struct libinput_tablet_pad_mode_group *group, + unsigned int strip) +{ + if ((int)strip >= + libinput_device_tablet_pad_get_num_strips(group->device)) + return 0; + + return !!(group->strip_mask & (1 << strip)); +} + +LIBINPUT_EXPORT int +libinput_tablet_pad_mode_group_button_is_toggle(struct libinput_tablet_pad_mode_group *group, + unsigned int button) +{ + if ((int)button >= + libinput_device_tablet_pad_get_num_buttons(group->device)) + return 0; + + return !!(group->toggle_button_mask & (1 << button)); +} + +LIBINPUT_EXPORT struct libinput_tablet_pad_mode_group * +libinput_tablet_pad_mode_group_ref( + struct libinput_tablet_pad_mode_group *group) +{ + group->refcount++; + return group; +} + +LIBINPUT_EXPORT struct libinput_tablet_pad_mode_group * +libinput_tablet_pad_mode_group_unref( + struct libinput_tablet_pad_mode_group *group) +{ + assert(group->refcount > 0); + + group->refcount--; + if (group->refcount > 0) + return group; + + list_remove(&group->link); + group->destroy(group); + return NULL; +} + +LIBINPUT_EXPORT void +libinput_tablet_pad_mode_group_set_user_data( + struct libinput_tablet_pad_mode_group *group, + void *user_data) +{ + group->user_data = user_data; +} + +LIBINPUT_EXPORT void * +libinput_tablet_pad_mode_group_get_user_data( + struct libinput_tablet_pad_mode_group *group) +{ + return group->user_data; +} + +LIBINPUT_EXPORT struct libinput_event * +libinput_event_device_notify_get_base_event(struct libinput_event_device_notify *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + NULL, + LIBINPUT_EVENT_DEVICE_ADDED, + LIBINPUT_EVENT_DEVICE_REMOVED); + + return &event->base; +} + +LIBINPUT_EXPORT struct libinput_event * +libinput_event_keyboard_get_base_event(struct libinput_event_keyboard *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + NULL, + LIBINPUT_EVENT_KEYBOARD_KEY); + + return &event->base; +} + +LIBINPUT_EXPORT struct libinput_event * +libinput_event_pointer_get_base_event(struct libinput_event_pointer *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + NULL, + LIBINPUT_EVENT_POINTER_MOTION, + LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, + LIBINPUT_EVENT_POINTER_BUTTON, + LIBINPUT_EVENT_POINTER_AXIS); + + return &event->base; +} + +LIBINPUT_EXPORT struct libinput_event * +libinput_event_touch_get_base_event(struct libinput_event_touch *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + NULL, + LIBINPUT_EVENT_TOUCH_DOWN, + LIBINPUT_EVENT_TOUCH_UP, + LIBINPUT_EVENT_TOUCH_MOTION, + LIBINPUT_EVENT_TOUCH_CANCEL, + LIBINPUT_EVENT_TOUCH_FRAME); + + return &event->base; +} + +LIBINPUT_EXPORT struct libinput_event * +libinput_event_gesture_get_base_event(struct libinput_event_gesture *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + NULL, + LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, + LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, + LIBINPUT_EVENT_GESTURE_SWIPE_END, + LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, + LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, + LIBINPUT_EVENT_GESTURE_PINCH_END); + + return &event->base; +} + +LIBINPUT_EXPORT struct libinput_event * +libinput_event_tablet_tool_get_base_event(struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + NULL, + LIBINPUT_EVENT_TABLET_TOOL_AXIS, + LIBINPUT_EVENT_TABLET_TOOL_TIP, + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON); + + return &event->base; +} + +LIBINPUT_EXPORT double +libinput_event_tablet_pad_get_ring_position(struct libinput_event_tablet_pad *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0.0, + LIBINPUT_EVENT_TABLET_PAD_RING); + + return event->ring.position; +} + +LIBINPUT_EXPORT unsigned int +libinput_event_tablet_pad_get_ring_number(struct libinput_event_tablet_pad *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_PAD_RING); + + return event->ring.number; +} + +LIBINPUT_EXPORT enum libinput_tablet_pad_ring_axis_source +libinput_event_tablet_pad_get_ring_source(struct libinput_event_tablet_pad *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + LIBINPUT_TABLET_PAD_RING_SOURCE_UNKNOWN, + LIBINPUT_EVENT_TABLET_PAD_RING); + + return event->ring.source; +} + +LIBINPUT_EXPORT double +libinput_event_tablet_pad_get_strip_position(struct libinput_event_tablet_pad *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0.0, + LIBINPUT_EVENT_TABLET_PAD_STRIP); + + return event->strip.position; +} + +LIBINPUT_EXPORT unsigned int +libinput_event_tablet_pad_get_strip_number(struct libinput_event_tablet_pad *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_PAD_STRIP); + + return event->strip.number; +} + +LIBINPUT_EXPORT enum libinput_tablet_pad_strip_axis_source +libinput_event_tablet_pad_get_strip_source(struct libinput_event_tablet_pad *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + LIBINPUT_TABLET_PAD_STRIP_SOURCE_UNKNOWN, + LIBINPUT_EVENT_TABLET_PAD_STRIP); + + return event->strip.source; +} + +LIBINPUT_EXPORT uint32_t +libinput_event_tablet_pad_get_button_number(struct libinput_event_tablet_pad *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_PAD_BUTTON); + + return event->button.number; +} + +LIBINPUT_EXPORT enum libinput_button_state +libinput_event_tablet_pad_get_button_state(struct libinput_event_tablet_pad *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + LIBINPUT_BUTTON_STATE_RELEASED, + LIBINPUT_EVENT_TABLET_PAD_BUTTON); + + return event->button.state; +} + +LIBINPUT_EXPORT uint32_t +libinput_event_tablet_pad_get_key(struct libinput_event_tablet_pad *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_PAD_KEY); + + return event->key.code; +} + +LIBINPUT_EXPORT enum libinput_key_state +libinput_event_tablet_pad_get_key_state(struct libinput_event_tablet_pad *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + LIBINPUT_KEY_STATE_RELEASED, + LIBINPUT_EVENT_TABLET_PAD_KEY); + + return event->key.state; +} + +LIBINPUT_EXPORT unsigned int +libinput_event_tablet_pad_get_mode(struct libinput_event_tablet_pad *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_PAD_RING, + LIBINPUT_EVENT_TABLET_PAD_STRIP, + LIBINPUT_EVENT_TABLET_PAD_BUTTON); + + return event->mode; +} + +LIBINPUT_EXPORT struct libinput_tablet_pad_mode_group * +libinput_event_tablet_pad_get_mode_group(struct libinput_event_tablet_pad *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + NULL, + LIBINPUT_EVENT_TABLET_PAD_RING, + LIBINPUT_EVENT_TABLET_PAD_STRIP, + LIBINPUT_EVENT_TABLET_PAD_BUTTON); + + return event->mode_group; +} + +LIBINPUT_EXPORT uint32_t +libinput_event_tablet_pad_get_time(struct libinput_event_tablet_pad *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_PAD_RING, + LIBINPUT_EVENT_TABLET_PAD_STRIP, + LIBINPUT_EVENT_TABLET_PAD_BUTTON, + LIBINPUT_EVENT_TABLET_PAD_KEY); + + return us2ms(event->time); +} + +LIBINPUT_EXPORT uint64_t +libinput_event_tablet_pad_get_time_usec(struct libinput_event_tablet_pad *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_PAD_RING, + LIBINPUT_EVENT_TABLET_PAD_STRIP, + LIBINPUT_EVENT_TABLET_PAD_BUTTON, + LIBINPUT_EVENT_TABLET_PAD_KEY); + + return event->time; +} + +LIBINPUT_EXPORT struct libinput_event * +libinput_event_tablet_pad_get_base_event(struct libinput_event_tablet_pad *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + NULL, + LIBINPUT_EVENT_TABLET_PAD_RING, + LIBINPUT_EVENT_TABLET_PAD_STRIP, + LIBINPUT_EVENT_TABLET_PAD_BUTTON, + LIBINPUT_EVENT_TABLET_PAD_KEY); + + return &event->base; +} + +LIBINPUT_EXPORT struct libinput_device_group * +libinput_device_group_ref(struct libinput_device_group *group) +{ + group->refcount++; + return group; +} + +struct libinput_device_group * +libinput_device_group_create(struct libinput *libinput, + const char *identifier) +{ + struct libinput_device_group *group; + + group = zalloc(sizeof *group); + group->refcount = 1; + group->identifier = safe_strdup(identifier); + + list_init(&group->link); + list_insert(&libinput->device_group_list, &group->link); + + return group; +} + +struct libinput_device_group * +libinput_device_group_find_group(struct libinput *libinput, + const char *identifier) +{ + struct libinput_device_group *g = NULL; + + list_for_each(g, &libinput->device_group_list, link) { + if (identifier && g->identifier && + streq(g->identifier, identifier)) { + return g; + } + } + + return NULL; +} + +void +libinput_device_set_device_group(struct libinput_device *device, + struct libinput_device_group *group) +{ + device->group = group; + libinput_device_group_ref(group); +} + +static void +libinput_device_group_destroy(struct libinput_device_group *group) +{ + list_remove(&group->link); + free(group->identifier); + free(group); +} + +LIBINPUT_EXPORT struct libinput_device_group * +libinput_device_group_unref(struct libinput_device_group *group) +{ + assert(group->refcount > 0); + group->refcount--; + if (group->refcount == 0) { + libinput_device_group_destroy(group); + return NULL; + } + + return group; +} + +LIBINPUT_EXPORT void +libinput_device_group_set_user_data(struct libinput_device_group *group, + void *user_data) +{ + group->user_data = user_data; +} + +LIBINPUT_EXPORT void * +libinput_device_group_get_user_data(struct libinput_device_group *group) +{ + return group->user_data; +} + +LIBINPUT_EXPORT const char * +libinput_config_status_to_str(enum libinput_config_status status) +{ + const char *str = NULL; + + switch(status) { + case LIBINPUT_CONFIG_STATUS_SUCCESS: + str = "Success"; + break; + case LIBINPUT_CONFIG_STATUS_UNSUPPORTED: + str = "Unsupported configuration option"; + break; + case LIBINPUT_CONFIG_STATUS_INVALID: + str = "Invalid argument range"; + break; + } + + return str; +} + +LIBINPUT_EXPORT int +libinput_device_config_tap_get_finger_count(struct libinput_device *device) +{ + return device->config.tap ? device->config.tap->count(device) : 0; +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_tap_set_enabled(struct libinput_device *device, + enum libinput_config_tap_state enable) +{ + if (enable != LIBINPUT_CONFIG_TAP_ENABLED && + enable != LIBINPUT_CONFIG_TAP_DISABLED) + return LIBINPUT_CONFIG_STATUS_INVALID; + + if (libinput_device_config_tap_get_finger_count(device) == 0) + return enable ? LIBINPUT_CONFIG_STATUS_UNSUPPORTED : + LIBINPUT_CONFIG_STATUS_SUCCESS; + + return device->config.tap->set_enabled(device, enable); + +} + +LIBINPUT_EXPORT enum libinput_config_tap_state +libinput_device_config_tap_get_enabled(struct libinput_device *device) +{ + if (libinput_device_config_tap_get_finger_count(device) == 0) + return LIBINPUT_CONFIG_TAP_DISABLED; + + return device->config.tap->get_enabled(device); +} + +LIBINPUT_EXPORT enum libinput_config_tap_state +libinput_device_config_tap_get_default_enabled(struct libinput_device *device) +{ + if (libinput_device_config_tap_get_finger_count(device) == 0) + return LIBINPUT_CONFIG_TAP_DISABLED; + + return device->config.tap->get_default(device); +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_tap_set_button_map(struct libinput_device *device, + enum libinput_config_tap_button_map map) +{ + switch (map) { + case LIBINPUT_CONFIG_TAP_MAP_LRM: + case LIBINPUT_CONFIG_TAP_MAP_LMR: + break; + default: + return LIBINPUT_CONFIG_STATUS_INVALID; + } + + if (libinput_device_config_tap_get_finger_count(device) == 0) + return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; + + return device->config.tap->set_map(device, map); +} + +LIBINPUT_EXPORT enum libinput_config_tap_button_map +libinput_device_config_tap_get_button_map(struct libinput_device *device) +{ + if (libinput_device_config_tap_get_finger_count(device) == 0) + return LIBINPUT_CONFIG_TAP_MAP_LRM; + + return device->config.tap->get_map(device); +} + +LIBINPUT_EXPORT enum libinput_config_tap_button_map +libinput_device_config_tap_get_default_button_map(struct libinput_device *device) +{ + if (libinput_device_config_tap_get_finger_count(device) == 0) + return LIBINPUT_CONFIG_TAP_MAP_LRM; + + return device->config.tap->get_default_map(device); +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_tap_set_drag_enabled(struct libinput_device *device, + enum libinput_config_drag_state enable) +{ + if (enable != LIBINPUT_CONFIG_DRAG_ENABLED && + enable != LIBINPUT_CONFIG_DRAG_DISABLED) + return LIBINPUT_CONFIG_STATUS_INVALID; + + if (libinput_device_config_tap_get_finger_count(device) == 0) + return enable ? LIBINPUT_CONFIG_STATUS_UNSUPPORTED : + LIBINPUT_CONFIG_STATUS_SUCCESS; + + return device->config.tap->set_drag_enabled(device, enable); +} + +LIBINPUT_EXPORT enum libinput_config_drag_state +libinput_device_config_tap_get_drag_enabled(struct libinput_device *device) +{ + if (libinput_device_config_tap_get_finger_count(device) == 0) + return LIBINPUT_CONFIG_DRAG_DISABLED; + + return device->config.tap->get_drag_enabled(device); +} + +LIBINPUT_EXPORT enum libinput_config_drag_state +libinput_device_config_tap_get_default_drag_enabled(struct libinput_device *device) +{ + if (libinput_device_config_tap_get_finger_count(device) == 0) + return LIBINPUT_CONFIG_DRAG_DISABLED; + + return device->config.tap->get_default_drag_enabled(device); +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_tap_set_drag_lock_enabled(struct libinput_device *device, + enum libinput_config_drag_lock_state enable) +{ + if (enable != LIBINPUT_CONFIG_DRAG_LOCK_ENABLED && + enable != LIBINPUT_CONFIG_DRAG_LOCK_DISABLED) + return LIBINPUT_CONFIG_STATUS_INVALID; + + if (libinput_device_config_tap_get_finger_count(device) == 0) + return enable ? LIBINPUT_CONFIG_STATUS_UNSUPPORTED : + LIBINPUT_CONFIG_STATUS_SUCCESS; + + return device->config.tap->set_draglock_enabled(device, enable); +} + +LIBINPUT_EXPORT enum libinput_config_drag_lock_state +libinput_device_config_tap_get_drag_lock_enabled(struct libinput_device *device) +{ + if (libinput_device_config_tap_get_finger_count(device) == 0) + return LIBINPUT_CONFIG_DRAG_LOCK_DISABLED; + + return device->config.tap->get_draglock_enabled(device); +} + +LIBINPUT_EXPORT enum libinput_config_drag_lock_state +libinput_device_config_tap_get_default_drag_lock_enabled(struct libinput_device *device) +{ + if (libinput_device_config_tap_get_finger_count(device) == 0) + return LIBINPUT_CONFIG_DRAG_LOCK_DISABLED; + + return device->config.tap->get_default_draglock_enabled(device); +} + +LIBINPUT_EXPORT int +libinput_device_config_calibration_has_matrix(struct libinput_device *device) +{ + return device->config.calibration ? + device->config.calibration->has_matrix(device) : 0; +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_calibration_set_matrix(struct libinput_device *device, + const float matrix[6]) +{ + if (!libinput_device_config_calibration_has_matrix(device)) + return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; + + return device->config.calibration->set_matrix(device, matrix); +} + +LIBINPUT_EXPORT int +libinput_device_config_calibration_get_matrix(struct libinput_device *device, + float matrix[6]) +{ + if (!libinput_device_config_calibration_has_matrix(device)) + return 0; + + return device->config.calibration->get_matrix(device, matrix); +} + +LIBINPUT_EXPORT int +libinput_device_config_calibration_get_default_matrix(struct libinput_device *device, + float matrix[6]) +{ + if (!libinput_device_config_calibration_has_matrix(device)) + return 0; + + return device->config.calibration->get_default_matrix(device, matrix); +} + +LIBINPUT_EXPORT uint32_t +libinput_device_config_send_events_get_modes(struct libinput_device *device) +{ + uint32_t modes = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED; + + if (device->config.sendevents) + modes |= device->config.sendevents->get_modes(device); + + return modes; +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_send_events_set_mode(struct libinput_device *device, + uint32_t mode) +{ + if ((libinput_device_config_send_events_get_modes(device) & mode) != mode) + return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; + + if (device->config.sendevents) + return device->config.sendevents->set_mode(device, mode); + + /* mode must be _ENABLED to get here */ + return LIBINPUT_CONFIG_STATUS_SUCCESS; +} + +LIBINPUT_EXPORT uint32_t +libinput_device_config_send_events_get_mode(struct libinput_device *device) +{ + if (device->config.sendevents) + return device->config.sendevents->get_mode(device); + + return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED; +} + +LIBINPUT_EXPORT uint32_t +libinput_device_config_send_events_get_default_mode(struct libinput_device *device) +{ + return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED; +} + +LIBINPUT_EXPORT int +libinput_device_config_accel_is_available(struct libinput_device *device) +{ + return device->config.accel ? + device->config.accel->available(device) : 0; +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_accel_set_speed(struct libinput_device *device, + double speed) +{ + /* Need the negation in case speed is NaN */ + if (!(speed >= -1.0 && speed <= 1.0)) + return LIBINPUT_CONFIG_STATUS_INVALID; + + if (!libinput_device_config_accel_is_available(device)) + return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; + + return device->config.accel->set_speed(device, speed); +} +LIBINPUT_EXPORT double +libinput_device_config_accel_get_speed(struct libinput_device *device) +{ + if (!libinput_device_config_accel_is_available(device)) + return 0; + + return device->config.accel->get_speed(device); +} + +LIBINPUT_EXPORT double +libinput_device_config_accel_get_default_speed(struct libinput_device *device) +{ + if (!libinput_device_config_accel_is_available(device)) + return 0; + + return device->config.accel->get_default_speed(device); +} + +LIBINPUT_EXPORT uint32_t +libinput_device_config_accel_get_profiles(struct libinput_device *device) +{ + if (!libinput_device_config_accel_is_available(device)) + return 0; + + return device->config.accel->get_profiles(device); +} + +LIBINPUT_EXPORT enum libinput_config_accel_profile +libinput_device_config_accel_get_profile(struct libinput_device *device) +{ + if (!libinput_device_config_accel_is_available(device)) + return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE; + + return device->config.accel->get_profile(device); +} + +LIBINPUT_EXPORT enum libinput_config_accel_profile +libinput_device_config_accel_get_default_profile(struct libinput_device *device) +{ + if (!libinput_device_config_accel_is_available(device)) + return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE; + + return device->config.accel->get_default_profile(device); +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_accel_set_profile(struct libinput_device *device, + enum libinput_config_accel_profile profile) +{ + switch (profile) { + case LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT: + case LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE: + break; + default: + return LIBINPUT_CONFIG_STATUS_INVALID; + } + + if (!libinput_device_config_accel_is_available(device) || + (libinput_device_config_accel_get_profiles(device) & profile) == 0) + return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; + + return device->config.accel->set_profile(device, profile); +} + +LIBINPUT_EXPORT int +libinput_device_config_scroll_has_natural_scroll(struct libinput_device *device) +{ + if (!device->config.natural_scroll) + return 0; + + return device->config.natural_scroll->has(device); +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_scroll_set_natural_scroll_enabled(struct libinput_device *device, + int enabled) +{ + if (!libinput_device_config_scroll_has_natural_scroll(device)) + return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; + + return device->config.natural_scroll->set_enabled(device, enabled); +} + +LIBINPUT_EXPORT int +libinput_device_config_scroll_get_natural_scroll_enabled(struct libinput_device *device) +{ + if (!device->config.natural_scroll) + return 0; + + return device->config.natural_scroll->get_enabled(device); +} + +LIBINPUT_EXPORT int +libinput_device_config_scroll_get_default_natural_scroll_enabled(struct libinput_device *device) +{ + if (!device->config.natural_scroll) + return 0; + + return device->config.natural_scroll->get_default_enabled(device); +} + +LIBINPUT_EXPORT int +libinput_device_config_left_handed_is_available(struct libinput_device *device) +{ + if (!device->config.left_handed) + return 0; + + return device->config.left_handed->has(device); +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_left_handed_set(struct libinput_device *device, + int left_handed) +{ + if (!libinput_device_config_left_handed_is_available(device)) + return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; + + return device->config.left_handed->set(device, left_handed); +} + +LIBINPUT_EXPORT int +libinput_device_config_left_handed_get(struct libinput_device *device) +{ + if (!libinput_device_config_left_handed_is_available(device)) + return 0; + + return device->config.left_handed->get(device); +} + +LIBINPUT_EXPORT int +libinput_device_config_left_handed_get_default(struct libinput_device *device) +{ + if (!libinput_device_config_left_handed_is_available(device)) + return 0; + + return device->config.left_handed->get_default(device); +} + +LIBINPUT_EXPORT uint32_t +libinput_device_config_click_get_methods(struct libinput_device *device) +{ + if (device->config.click_method) + return device->config.click_method->get_methods(device); + + return 0; +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_click_set_method(struct libinput_device *device, + enum libinput_config_click_method method) +{ + /* Check method is a single valid method */ + switch (method) { + case LIBINPUT_CONFIG_CLICK_METHOD_NONE: + case LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS: + case LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER: + break; + default: + return LIBINPUT_CONFIG_STATUS_INVALID; + } + + if ((libinput_device_config_click_get_methods(device) & method) != method) + return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; + + if (device->config.click_method) + return device->config.click_method->set_method(device, method); + + /* method must be _NONE to get here */ + return LIBINPUT_CONFIG_STATUS_SUCCESS; +} + +LIBINPUT_EXPORT enum libinput_config_click_method +libinput_device_config_click_get_method(struct libinput_device *device) +{ + if (device->config.click_method) + return device->config.click_method->get_method(device); + + return LIBINPUT_CONFIG_CLICK_METHOD_NONE; +} + +LIBINPUT_EXPORT enum libinput_config_click_method +libinput_device_config_click_get_default_method(struct libinput_device *device) +{ + if (device->config.click_method) + return device->config.click_method->get_default_method(device); + + return LIBINPUT_CONFIG_CLICK_METHOD_NONE; +} + +LIBINPUT_EXPORT int +libinput_device_config_middle_emulation_is_available( + struct libinput_device *device) +{ + if (device->config.middle_emulation) + return device->config.middle_emulation->available(device); + + return LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED; +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_middle_emulation_set_enabled( + struct libinput_device *device, + enum libinput_config_middle_emulation_state enable) +{ + int available = + libinput_device_config_middle_emulation_is_available(device); + + switch (enable) { + case LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED: + if (!available) + return LIBINPUT_CONFIG_STATUS_SUCCESS; + break; + case LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED: + if (!available) + return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; + break; + default: + return LIBINPUT_CONFIG_STATUS_INVALID; + } + + return device->config.middle_emulation->set(device, enable); +} + +LIBINPUT_EXPORT enum libinput_config_middle_emulation_state +libinput_device_config_middle_emulation_get_enabled( + struct libinput_device *device) +{ + if (!libinput_device_config_middle_emulation_is_available(device)) + return LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED; + + return device->config.middle_emulation->get(device); +} + +LIBINPUT_EXPORT enum libinput_config_middle_emulation_state +libinput_device_config_middle_emulation_get_default_enabled( + struct libinput_device *device) +{ + if (!libinput_device_config_middle_emulation_is_available(device)) + return LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED; + + return device->config.middle_emulation->get_default(device); +} + +LIBINPUT_EXPORT uint32_t +libinput_device_config_scroll_get_methods(struct libinput_device *device) +{ + if (device->config.scroll_method) + return device->config.scroll_method->get_methods(device); + + return 0; +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_scroll_set_method(struct libinput_device *device, + enum libinput_config_scroll_method method) +{ + /* Check method is a single valid method */ + switch (method) { + case LIBINPUT_CONFIG_SCROLL_NO_SCROLL: + case LIBINPUT_CONFIG_SCROLL_2FG: + case LIBINPUT_CONFIG_SCROLL_EDGE: + case LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN: + break; + default: + return LIBINPUT_CONFIG_STATUS_INVALID; + } + + if ((libinput_device_config_scroll_get_methods(device) & method) != method) + return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; + + if (device->config.scroll_method) + return device->config.scroll_method->set_method(device, method); + + /* method must be _NO_SCROLL to get here */ + return LIBINPUT_CONFIG_STATUS_SUCCESS; +} + +LIBINPUT_EXPORT enum libinput_config_scroll_method +libinput_device_config_scroll_get_method(struct libinput_device *device) +{ + if (device->config.scroll_method) + return device->config.scroll_method->get_method(device); + + return LIBINPUT_CONFIG_SCROLL_NO_SCROLL; +} + +LIBINPUT_EXPORT enum libinput_config_scroll_method +libinput_device_config_scroll_get_default_method(struct libinput_device *device) +{ + if (device->config.scroll_method) + return device->config.scroll_method->get_default_method(device); + + return LIBINPUT_CONFIG_SCROLL_NO_SCROLL; +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_scroll_set_button(struct libinput_device *device, + uint32_t button) +{ + if ((libinput_device_config_scroll_get_methods(device) & + LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) == 0) + return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; + + if (button && !libinput_device_pointer_has_button(device, button)) + return LIBINPUT_CONFIG_STATUS_INVALID; + + return device->config.scroll_method->set_button(device, button); +} + +LIBINPUT_EXPORT uint32_t +libinput_device_config_scroll_get_button(struct libinput_device *device) +{ + if ((libinput_device_config_scroll_get_methods(device) & + LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) == 0) + return 0; + + return device->config.scroll_method->get_button(device); +} + +LIBINPUT_EXPORT uint32_t +libinput_device_config_scroll_get_default_button(struct libinput_device *device) +{ + if ((libinput_device_config_scroll_get_methods(device) & + LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) == 0) + return 0; + + return device->config.scroll_method->get_default_button(device); +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_scroll_set_button_lock(struct libinput_device *device, + enum libinput_config_scroll_button_lock_state state) +{ + if ((libinput_device_config_scroll_get_methods(device) & + LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) == 0) + return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; + + switch (state) { + case LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_ENABLED: + case LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED: + break; + default: + return LIBINPUT_CONFIG_STATUS_INVALID; + } + + return device->config.scroll_method->set_button_lock(device, state); +} + +LIBINPUT_EXPORT enum libinput_config_scroll_button_lock_state +libinput_device_config_scroll_get_button_lock(struct libinput_device *device) +{ + if ((libinput_device_config_scroll_get_methods(device) & + LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) == 0) + return LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED; + + return device->config.scroll_method->get_button_lock(device); +} + +LIBINPUT_EXPORT enum libinput_config_scroll_button_lock_state +libinput_device_config_scroll_get_default_button_lock(struct libinput_device *device) +{ + if ((libinput_device_config_scroll_get_methods(device) & + LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) == 0) + return LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED; + + return device->config.scroll_method->get_default_button_lock(device); +} + +LIBINPUT_EXPORT int +libinput_device_config_dwt_is_available(struct libinput_device *device) +{ + if (!device->config.dwt) + return 0; + + return device->config.dwt->is_available(device); +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_dwt_set_enabled(struct libinput_device *device, + enum libinput_config_dwt_state enable) +{ + if (enable != LIBINPUT_CONFIG_DWT_ENABLED && + enable != LIBINPUT_CONFIG_DWT_DISABLED) + return LIBINPUT_CONFIG_STATUS_INVALID; + + if (!libinput_device_config_dwt_is_available(device)) + return enable ? LIBINPUT_CONFIG_STATUS_UNSUPPORTED : + LIBINPUT_CONFIG_STATUS_SUCCESS; + + return device->config.dwt->set_enabled(device, enable); +} + +LIBINPUT_EXPORT enum libinput_config_dwt_state +libinput_device_config_dwt_get_enabled(struct libinput_device *device) +{ + if (!libinput_device_config_dwt_is_available(device)) + return LIBINPUT_CONFIG_DWT_DISABLED; + + return device->config.dwt->get_enabled(device); +} + +LIBINPUT_EXPORT enum libinput_config_dwt_state +libinput_device_config_dwt_get_default_enabled(struct libinput_device *device) +{ + if (!libinput_device_config_dwt_is_available(device)) + return LIBINPUT_CONFIG_DWT_DISABLED; + + return device->config.dwt->get_default_enabled(device); +} + +LIBINPUT_EXPORT int +libinput_device_config_rotation_is_available(struct libinput_device *device) +{ + if (!device->config.rotation) + return 0; + + return device->config.rotation->is_available(device); +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_rotation_set_angle(struct libinput_device *device, + unsigned int degrees_cw) +{ + if (!libinput_device_config_rotation_is_available(device)) + return degrees_cw ? LIBINPUT_CONFIG_STATUS_UNSUPPORTED : + LIBINPUT_CONFIG_STATUS_SUCCESS; + + if (degrees_cw >= 360 || degrees_cw % 90) + return LIBINPUT_CONFIG_STATUS_INVALID; + + return device->config.rotation->set_angle(device, degrees_cw); +} + +LIBINPUT_EXPORT unsigned int +libinput_device_config_rotation_get_angle(struct libinput_device *device) +{ + if (!libinput_device_config_rotation_is_available(device)) + return 0; + + return device->config.rotation->get_angle(device); +} + +LIBINPUT_EXPORT unsigned int +libinput_device_config_rotation_get_default_angle(struct libinput_device *device) +{ + if (!libinput_device_config_rotation_is_available(device)) + return 0; + + return device->config.rotation->get_default_angle(device); +} + +#if HAVE_LIBWACOM +WacomDeviceDatabase * +libinput_libwacom_ref(struct libinput *li) +{ + WacomDeviceDatabase *db = NULL; + if (!li->libwacom.db) { + db = libwacom_database_new(); + if (!db) { + log_error(li, + "Failed to initialize libwacom context\n"); + return NULL; + } + + li->libwacom.db = db; + li->libwacom.refcount = 0; + } + + li->libwacom.refcount++; + db = li->libwacom.db; + return db; +} + +void +libinput_libwacom_unref(struct libinput *li) +{ + if (!li->libwacom.db) + return; + + assert(li->libwacom.refcount >= 1); + + if (--li->libwacom.refcount == 0) { + libwacom_database_destroy(li->libwacom.db); + li->libwacom.db = NULL; + } +} +#endif diff --git a/src/quirks.c b/src/quirks.c index 0fbd53f2..b5513ae2 100644 --- a/src/quirks.c +++ b/src/quirks.c @@ -31,7 +31,9 @@ #undef NDEBUG /* You don't get to disable asserts here */ #include #include +#ifndef __OpenBSD__ #include +#endif #include #include #include diff --git a/src/quirks.h b/src/quirks.h index 340d0463..05962bc0 100644 --- a/src/quirks.h +++ b/src/quirks.h @@ -28,7 +28,9 @@ #include #include +#ifndef __OpenBSD__ #include +#endif #include "libinput.h" From e0a6e258e26aadd8242a33c2cb8dc930eb13af61 Mon Sep 17 00:00:00 2001 From: Rafael Sadowski Date: Sun, 6 Nov 2022 09:35:30 +0100 Subject: [PATCH 04/41] add a generic input-event-code header file --- include/linux/input-event-codes.h | 7 +++++++ meson.build | 1 + 2 files changed, 8 insertions(+) create mode 100644 include/linux/input-event-codes.h diff --git a/include/linux/input-event-codes.h b/include/linux/input-event-codes.h new file mode 100644 index 00000000..dda123e2 --- /dev/null +++ b/include/linux/input-event-codes.h @@ -0,0 +1,7 @@ +#ifdef __linux__ +#include "linux/input-event-codes.h" +#elif __OpenBSD__ +#include "freebsd/input-event-codes.h" +#elif __FreeBSD__ +#include "freebsd/input-event-codes.h" +#endif diff --git a/meson.build b/meson.build index 4aefc3bf..807bfb8e 100644 --- a/meson.build +++ b/meson.build @@ -433,6 +433,7 @@ install_headers('include/linux/linux/input-event-codes.h', subdir: 'linux/linux' install_headers('include/linux/linux/input.h', subdir: 'linux/linux') install_headers('include/linux/input.h', subdir: 'linux') +install_headers('include/linux/input-event-codes.h', subdir: 'linux') endif dep_libinput = declare_dependency( From fcf9f4c7a260f3fab7e64c7982ecdc58016d7a97 Mon Sep 17 00:00:00 2001 From: Rafael Sadowski Date: Sun, 6 Nov 2022 10:06:28 +0100 Subject: [PATCH 05/41] Fake udev-seat for now --- meson.build | 2 + src/udev-seat.h | 2 + src/udev-seat_openbsd.c | 155 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 159 insertions(+) create mode 100644 src/udev-seat_openbsd.c diff --git a/meson.build b/meson.build index 807bfb8e..f7148c54 100644 --- a/meson.build +++ b/meson.build @@ -361,6 +361,8 @@ src_libinput = src_libfilter + [ 'src/libinput_openbsd.c', 'src/libinput.h', 'src/libinput-private.h', + 'src/udev-seat_openbsd.c', + 'src/udev-seat.h', 'src/timer.c', 'src/timer.h', 'include/linux/input.h' diff --git a/src/udev-seat.h b/src/udev-seat.h index ee54b422..5326e491 100644 --- a/src/udev-seat.h +++ b/src/udev-seat.h @@ -26,7 +26,9 @@ #include "config.h" +#ifndef __OpenBSD__ #include +#endif #include "libinput-private.h" struct udev_seat { diff --git a/src/udev-seat_openbsd.c b/src/udev-seat_openbsd.c new file mode 100644 index 00000000..b571ad1a --- /dev/null +++ b/src/udev-seat_openbsd.c @@ -0,0 +1,155 @@ +/* + * Copyright © 2013 Intel Corporation + * Copyright © 2013-2015 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "config.h" + +#include +#include +#include + +#ifndef __OpenBSD__ +#include "evdev.h" +#endif +#include "udev-seat.h" + +static const char default_seat[] = "seat0"; +static const char default_seat_name[] = "default"; + +static struct udev_seat * +udev_seat_create(struct udev_input *input, + const char *device_seat, + const char *seat_name); +static struct udev_seat * +udev_seat_get_named(struct udev_input *input, const char *seat_name); + + +static inline bool +filter_duplicates(struct udev_seat *udev_seat, + struct udev_device *udev_device) +{ + bool ignore_device = false; + return ignore_device; // TODO +} + +static int +device_added(struct udev_device *udev_device, + struct udev_input *input, + const char *seat_name) +{ + return 0; // TODO +} + +static void +device_removed(struct udev_device *udev_device, struct udev_input *input) +{ + // TODO +} + +static int +udev_input_add_devices(struct udev_input *input, struct udev *udev) +{ + return 0; // TODO +} + +static void +evdev_udev_handler(void *data) +{ + // TODO +} + +static void +udev_input_remove_devices(struct udev_input *input) +{ + // TODO +} + +static void +udev_input_disable(struct libinput *libinput) +{ + // TODO +} + +static int +udev_input_enable(struct libinput *libinput) +{ + return 0; // TODO +} + +static void +udev_input_destroy(struct libinput *input) +{ + // TODO +} + +static void +udev_seat_destroy(struct libinput_seat *seat) +{ + struct udev_seat *useat = (struct udev_seat*)seat; + free(useat); +} + +static struct udev_seat * +udev_seat_create(struct udev_input *input, + const char *device_seat, + const char *seat_name) +{ + return NULL; // TODO +} + +static struct udev_seat * +udev_seat_get_named(struct udev_input *input, const char *seat_name) +{ + return NULL; // TODO +} + +static int +udev_device_change_seat(struct libinput_device *device, + const char *seat_name) +{ + return 0xdeadbeef; // TODO +} + +static const struct libinput_interface_backend interface_backend = { + .resume = udev_input_enable, + .suspend = udev_input_disable, + .destroy = udev_input_destroy, + .device_change_seat = udev_device_change_seat, +}; + +/* udev-seat_openbsd.c:141:1: error: conflicting types for 'libinput_udev_create_context +LIBINPUT_EXPORT struct libinput * +libinput_udev_create_context(const struct libinput_interface *interface, + void *user_data, + struct udev *udev) +{ + return NULL; // TODO +} +*/ + +LIBINPUT_EXPORT int +libinput_udev_assign_seat(struct libinput *libinput, + const char *seat_id) +{ + return 0; // TODO +} From 63a75a0626dce6d764cc43e8b458895c1a69e92a Mon Sep 17 00:00:00 2001 From: Rafael Sadowski Date: Sat, 12 Nov 2022 07:52:19 +0100 Subject: [PATCH 06/41] Bring back some udev bits since robert imported libudev-openbsd --- meson.build | 2 +- src/libinput.h | 2 -- src/quirks.c | 2 -- src/quirks.h | 2 -- src/udev-seat.h | 2 -- 5 files changed, 1 insertion(+), 9 deletions(-) diff --git a/meson.build b/meson.build index f7148c54..256d3fca 100644 --- a/meson.build +++ b/meson.build @@ -144,7 +144,7 @@ config_h.set10('HAVE_INSTALLED_TESTS', get_option('install-tests')) # Dependencies pkgconfig = import('pkgconfig') if host_machine.system() == 'openbsd' - dep_udev = [] + dep_udev = dependency('libudev') dep_mtdev = [] dep_libevdev = [] else diff --git a/src/libinput.h b/src/libinput.h index cb632369..6258a1af 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -32,9 +32,7 @@ extern "C" { #include #include #include -#ifndef __OpenBSD__ #include -#endif #define LIBINPUT_ATTRIBUTE_PRINTF(_format, _args) \ __attribute__ ((format (printf, _format, _args))) diff --git a/src/quirks.c b/src/quirks.c index b5513ae2..0fbd53f2 100644 --- a/src/quirks.c +++ b/src/quirks.c @@ -31,9 +31,7 @@ #undef NDEBUG /* You don't get to disable asserts here */ #include #include -#ifndef __OpenBSD__ #include -#endif #include #include #include diff --git a/src/quirks.h b/src/quirks.h index 05962bc0..340d0463 100644 --- a/src/quirks.h +++ b/src/quirks.h @@ -28,9 +28,7 @@ #include #include -#ifndef __OpenBSD__ #include -#endif #include "libinput.h" diff --git a/src/udev-seat.h b/src/udev-seat.h index 5326e491..ee54b422 100644 --- a/src/udev-seat.h +++ b/src/udev-seat.h @@ -26,9 +26,7 @@ #include "config.h" -#ifndef __OpenBSD__ #include -#endif #include "libinput-private.h" struct udev_seat { From 2c5c2a4304777e44500234ae79c360e8e3733fb0 Mon Sep 17 00:00:00 2001 From: Rafael Sadowski Date: Sun, 3 Sep 2023 19:12:18 +0200 Subject: [PATCH 07/41] Add wscons and wskbdmap from https://github.com/mherrb/libinput/ --- meson.build | 5 +- src/wscons.c | 310 +++++++++++++++++++++++++++++++++++++++++++++++++ src/wskbdmap.c | 254 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 568 insertions(+), 1 deletion(-) create mode 100644 src/wscons.c create mode 100644 src/wskbdmap.c diff --git a/meson.build b/meson.build index 256d3fca..9fc7ced5 100644 --- a/meson.build +++ b/meson.build @@ -365,7 +365,10 @@ src_libinput = src_libfilter + [ 'src/udev-seat.h', 'src/timer.c', 'src/timer.h', - 'include/linux/input.h' + 'include/linux/input.h', + # OpenBSD + 'src/wskbdmap.c', + 'src/wscons.c' ] else src_libinput = src_libfilter + [ diff --git a/src/wscons.c b/src/wscons.c new file mode 100644 index 00000000..eb12c708 --- /dev/null +++ b/src/wscons.c @@ -0,0 +1,310 @@ +/* + * Copyright © 2015 Martin Pieuchot + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include + +#include "libinput.h" +#include "libinput-util.h" +#include "libinput-private.h" + +static const char default_seat[] = "seat0"; +static const char default_seat_name[] = "default"; + +extern uint32_t wskey_transcode(int); + +static int old_value = -1; + +static void +wscons_process(struct libinput_device *device, struct wscons_event *wsevent) +{ + enum libinput_button_state bstate; + enum libinput_key_state kstate; + struct normalized_coords accel; + struct device_float_coords raw; + uint64_t time; + int button, key; + + time = s2us(wsevent->time.tv_sec) + ns2us(wsevent->time.tv_nsec); + + switch (wsevent->type) { + case WSCONS_EVENT_KEY_UP: + case WSCONS_EVENT_KEY_DOWN: + key = wsevent->value; + if (wsevent->type == WSCONS_EVENT_KEY_UP) { + kstate = LIBINPUT_KEY_STATE_RELEASED; + old_value = -1; + } else { + kstate = LIBINPUT_KEY_STATE_PRESSED; + /* ignore auto-repeat */ + if (key == old_value) + return; + old_value = key; + } + keyboard_notify_key(device, time, + wskey_transcode(key), kstate); + break; + + case WSCONS_EVENT_MOUSE_UP: + case WSCONS_EVENT_MOUSE_DOWN: + /* + * Do not return wscons(4) values directly because + * the left button value being 0 it will be + * interpreted as an error. + */ + button = wsevent->value + BTN_LEFT; + if (wsevent->type == WSCONS_EVENT_MOUSE_UP) + bstate = LIBINPUT_BUTTON_STATE_RELEASED; + else + bstate = LIBINPUT_BUTTON_STATE_PRESSED; + pointer_notify_button(device, time, button, bstate); + break; + + case WSCONS_EVENT_MOUSE_DELTA_X: + case WSCONS_EVENT_MOUSE_DELTA_Y: + memset(&raw, 0, sizeof(raw)); + memset(&accel, 0, sizeof(accel)); + + if (wsevent->type == WSCONS_EVENT_MOUSE_DELTA_X) + accel.x = wsevent->value; + else + accel.y = -wsevent->value; + + pointer_notify_motion(device, time, &accel, &raw); + break; + + case WSCONS_EVENT_MOUSE_DELTA_Z: + memset(&raw, 0, sizeof(raw)); + accel.x = 0; + accel.y = wsevent->value * 32; + axis_notify_event(device, time, &accel, &raw); + break; + + case WSCONS_EVENT_MOUSE_ABSOLUTE_X: + case WSCONS_EVENT_MOUSE_ABSOLUTE_Y: + //return LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE; + break; + + case WSCONS_EVENT_HSCROLL: + memset(&raw, 0, sizeof(raw)); + accel.x = wsevent->value/8; + accel.y = 0; + axis_notify_event(device, time, &accel, &raw); + break; + case WSCONS_EVENT_VSCROLL: + memset(&raw, 0, sizeof(raw)); + accel.x = 0; + accel.y = wsevent->value/8; + axis_notify_event(device, time, &accel, &raw); + break; + + case WSCONS_EVENT_SYNC: + break; + + case WSCONS_EVENT_MOUSE_ABSOLUTE_Z: + case WSCONS_EVENT_MOUSE_ABSOLUTE_W: + case WSCONS_EVENT_TOUCH_WIDTH: + case WSCONS_EVENT_TOUCH_RESET: + /* ignore those */ + break; + default: + fprintf(stderr, "unkown event: %x\n" , wsevent->type); + /* assert(1 == 0); */ + break; + } +} + +static void +wscons_device_dispatch(void *data) +{ + struct libinput_device *device = data; + struct wscons_event wsevents[32]; + ssize_t len; + int count, i; + + len = read(device->fd, wsevents, sizeof(struct wscons_event)); + if (len <= 0 || (len % sizeof(struct wscons_event)) != 0) + return; + + count = len / sizeof(struct wscons_event); + for (i = 0; i < count; i++) { + wscons_process(device, &wsevents[i]); + } +} + +static struct libinput_seat* +wscons_seat_get(struct libinput *libinput, const char *seat_name_physical, + const char *seat_name_logical) +{ + struct libinput_seat *seat; + + fprintf(stderr, "%s: %d\n", __func__, __LINE__); + list_for_each(seat, &libinput->seat_list, link) { + if (streq(seat->physical_name, seat_name_physical) && + streq(seat->logical_name, seat_name_logical)) { + libinput_seat_ref(seat); + return seat; + } + } + + seat = calloc(1, sizeof(*seat)); + if (seat == NULL) + return NULL; + + libinput_seat_init(seat, libinput, seat_name_physical, + seat_name_logical); + + return seat; +} + +LIBINPUT_EXPORT struct libinput * +libinput_udev_create_context(const struct libinput_interface *interface, + void *user_data, struct udev *udev) +{ + struct libinput *libinput; + + fprintf(stderr, "%s: %d\n", __func__, __LINE__); + libinput = calloc(1, sizeof(*libinput)); + if (libinput == NULL) + return NULL; + + if (libinput_init(libinput, interface, user_data) != 0) { + free(libinput); + return NULL; + } + return libinput; +} + +LIBINPUT_EXPORT int +libinput_udev_assign_seat(struct libinput *libinput, const char *seat_id) +{ + + struct libinput_seat *seat; + struct libinput_device *device; + uint64_t time; + struct timespec ts; + struct libinput_event *event; + + fprintf(stderr, "%s: %d\n", __func__, __LINE__); + + /* Add standard muxes */ + libinput_path_add_device(libinput, "/dev/wskbd"); + libinput_path_add_device(libinput, "/dev/wsmouse"); + + seat = wscons_seat_get(libinput, default_seat, default_seat_name); + list_for_each(device, &seat->devices_list, link) { + fprintf(stderr, " %s\n", device->devname); + clock_gettime(CLOCK_REALTIME, &ts); + time = s2us(ts.tv_sec) + ns2us(ts.tv_nsec); + event = calloc(1, sizeof(*event)); + post_device_event(device, time, LIBINPUT_EVENT_DEVICE_ADDED, + event); + } + return 0; +} + + +LIBINPUT_EXPORT struct libinput * +libinput_path_create_context(const struct libinput_interface *interface, + void *user_data) +{ + struct libinput *libinput; + + libinput = calloc(1, sizeof(*libinput)); + if (libinput == NULL) + return NULL; + + if (libinput_init(libinput, interface, user_data) != 0) { + free(libinput); + return NULL; + } + + return libinput; +} + +LIBINPUT_EXPORT struct libinput_device * +libinput_path_add_device(struct libinput *libinput, + const char *path) +{ + struct libinput_seat *seat = NULL; + struct libinput_device *device; + int fd; + + fd = open_restricted(libinput, path, + O_RDWR | O_NONBLOCK | O_CLOEXEC); + if (fd < 0) { + log_info(libinput, + "opening input device '%s' failed (%s).\n", + path, strerror(-fd)); + return NULL; + } + + device = calloc(1, sizeof(*device)); + if (device == NULL) + return NULL; + + /* Only one (default) seat is supported. */ + seat = wscons_seat_get(libinput, default_seat, default_seat_name); + if (seat == NULL) + goto err; + + libinput_device_init(device, seat); + + device->fd = fd; + device->devname = strdup(path); + if (device->devname == NULL) + goto err; + + device->source = + libinput_add_fd(libinput, fd, wscons_device_dispatch, device); + if (!device->source) + goto err; + + list_insert(&seat->devices_list, &device->link); + + return device; + +err: + close_restricted(libinput, device->fd); + free(device); + return NULL; +} + +LIBINPUT_EXPORT void +libinput_path_remove_device(struct libinput_device *device) +{ + struct libinput *libinput = device->seat->libinput; + + libinput_remove_source(libinput, device->source); + device->source = NULL; + + close_restricted(libinput, device->fd); + device->fd = -1; + + libinput_device_unref(device); +} diff --git a/src/wskbdmap.c b/src/wskbdmap.c new file mode 100644 index 00000000..b88b8917 --- /dev/null +++ b/src/wskbdmap.c @@ -0,0 +1,254 @@ +#include + +#include "input-event-codes.h" + +static uint32_t wsXtMap[] = { + /* 0 */ KEY_RESERVED, + /* 1 */ KEY_ESC, + /* 2 */ KEY_1, + /* 3 */ KEY_2, + /* 4 */ KEY_3, + /* 5 */ KEY_4, + /* 6 */ KEY_5, + /* 7 */ KEY_6, + /* 8 */ KEY_7, + /* 9 */ KEY_8, + /* 10 */ KEY_9, + /* 11 */ KEY_0, + /* 12 */ KEY_MINUS, + /* 13 */ KEY_EQUAL, + /* 14 */ KEY_BACKSPACE, + /* 15 */ KEY_TAB, + /* 16 */ KEY_Q, + /* 17 */ KEY_W, + /* 18 */ KEY_E, + /* 19 */ KEY_R, + /* 20 */ KEY_T, + /* 21 */ KEY_Y, + /* 22 */ KEY_U, + /* 23 */ KEY_I, + /* 24 */ KEY_O, + /* 25 */ KEY_P, + /* 26 */ KEY_LEFTBRACE, + /* 27 */ KEY_RIGHTBRACE, + /* 28 */ KEY_ENTER, + /* 29 */ KEY_LEFTCTRL, + /* 30 */ KEY_A, + /* 31 */ KEY_S, + /* 32 */ KEY_D, + /* 33 */ KEY_F, + /* 34 */ KEY_G, + /* 35 */ KEY_H, + /* 36 */ KEY_J, + /* 37 */ KEY_K, + /* 38 */ KEY_L, + /* 39 */ KEY_SEMICOLON, + /* 40 */ KEY_APOSTROPHE, + /* 41 */ KEY_GRAVE, + /* 42 */ KEY_LEFTSHIFT, + /* 43 */ KEY_BACKSLASH, + /* 44 */ KEY_Z, + /* 45 */ KEY_X, + /* 46 */ KEY_C, + /* 47 */ KEY_V, + /* 48 */ KEY_B, + /* 49 */ KEY_N, + /* 50 */ KEY_M, + /* 51 */ KEY_COMMA, + /* 52 */ KEY_DOT, + /* 53 */ KEY_SLASH, + /* 54 */ KEY_RIGHTSHIFT, + /* 55 */ KEY_KPASTERISK, + /* 56 */ KEY_LEFTALT, + /* 57 */ KEY_SPACE, + /* 58 */ KEY_CAPSLOCK, + /* 59 */ KEY_F1, + /* 60 */ KEY_F2, + /* 61 */ KEY_F3, + /* 62 */ KEY_F4, + /* 63 */ KEY_F5, + /* 64 */ KEY_F6, + /* 65 */ KEY_F7, + /* 66 */ KEY_F8, + /* 67 */ KEY_F9, + /* 68 */ KEY_F10, + /* 69 */ KEY_NUMLOCK, + /* 70 */ KEY_SCROLLLOCK, + /* 71 */ KEY_KP7, + /* 72 */ KEY_KP8, + /* 73 */ KEY_KP9, + /* 74 */ KEY_KPMINUS, + /* 75 */ KEY_KP4, + /* 76 */ KEY_KP5, + /* 77 */ KEY_KP6, + /* 78 */ KEY_KPPLUS, + /* 79 */ KEY_KP1, + /* 80 */ KEY_KP2, + /* 81 */ KEY_KP3, + /* 82 */ KEY_KP0, + /* 83 */ KEY_KPDOT, + /* 84 */ KEY_RESERVED, + + /* 85 */ KEY_ZENKAKUHANKAKU, + /* 86 */ KEY_102ND, /* backslash on uk, < on german */ + /* 87 */ KEY_F11, + /* 88 */ KEY_F12, + /* 89 */ KEY_RESERVED, + /* 90 */ KEY_RESERVED, + /* 91 */ KEY_RESERVED, + /* 92 */ KEY_RESERVED, + /* 93 */ KEY_RESERVED, + /* 94 */ KEY_RESERVED, + /* 95 */ KEY_RESERVED, + /* 96 */ KEY_RESERVED, + /* 97 */ KEY_RESERVED, + /* 98 */ KEY_RESERVED, + /* 99 */ KEY_RESERVED, + /* 100 */ KEY_RESERVED, + /* 101 */ KEY_RESERVED, + /* 102 */ KEY_RESERVED, + /* 103 */ KEY_RESERVED, + /* 104 */ KEY_RESERVED, + /* 105 */ KEY_RESERVED, + /* 106 */ KEY_RESERVED, + /* 107 */ KEY_RESERVED, + /* 108 */ KEY_RESERVED, + /* 109 */ KEY_RESERVED, + /* 110 */ KEY_RESERVED, + /* 111 */ KEY_BRIGHTNESSUP, + /* 112 */ KEY_BRIGHTNESSDOWN, + /* 113 */ KEY_RESERVED, + /* 114 */ KEY_RESERVED, + /* 115 */ KEY_RESERVED, + /* 116 */ KEY_RESERVED, + /* 117 */ KEY_RESERVED, + /* 118 */ KEY_RESERVED, + /* 119 */ KEY_RESERVED, + /* 120 */ KEY_RESERVED, + /* 121 */ KEY_RESERVED, + /* 122 */ KEY_RESERVED, + /* 123 */ KEY_RESERVED, + /* 124 */ KEY_RESERVED, + /* 125 */ KEY_RESERVED, + /* 126 */ KEY_RESERVED, + /* 127 */ KEY_PAUSE, + /* 128 */ KEY_RESERVED, + /* 129 */ KEY_RESERVED, + /* 130 */ KEY_RESERVED, + /* 131 */ KEY_RESERVED, + /* 132 */ KEY_RESERVED, + /* 133 */ KEY_RESERVED, + /* 134 */ KEY_RESERVED, + /* 135 */ KEY_RESERVED, + /* 136 */ KEY_RESERVED, + /* 137 */ KEY_RESERVED, + /* 138 */ KEY_RESERVED, + /* 139 */ KEY_RESERVED, + /* 140 */ KEY_RESERVED, + /* 141 */ KEY_RESERVED, + /* 142 */ KEY_RESERVED, + /* 143 */ KEY_RESERVED, + /* 144 */ KEY_PREVIOUSSONG, + /* 145 */ KEY_RESERVED, + /* 146 */ KEY_RESERVED, + /* 147 */ KEY_RESERVED, + /* 148 */ KEY_RESERVED, + /* 149 */ KEY_RESERVED, + /* 150 */ KEY_RESERVED, + /* 151 */ KEY_RESERVED, + /* 152 */ KEY_RESERVED, + /* 153 */ KEY_NEXTSONG, + /* 154 */ KEY_RESERVED, + /* 155 */ KEY_RESERVED, + /* 156 */ KEY_KPENTER, + /* 157 */ KEY_RIGHTCTRL, + /* 158 */ KEY_RESERVED, + /* 159 */ KEY_RESERVED, + /* 160 */ KEY_MUTE, + /* 161 */ KEY_RESERVED, + /* 162 */ KEY_PLAYPAUSE, + /* 163 */ KEY_RESERVED, + /* 164 */ KEY_RESERVED, + /* 165 */ KEY_RESERVED, + /* 166 */ KEY_RESERVED, + /* 167 */ KEY_RESERVED, + /* 168 */ KEY_RESERVED, + /* 169 */ KEY_RESERVED, + /* 170 */ KEY_PRINT, + /* 171 */ KEY_RESERVED, + /* 172 */ KEY_RESERVED, + /* 173 */ KEY_RESERVED, + /* 174 */ KEY_VOLUMEDOWN, + /* 175 */ KEY_RESERVED, + /* 176 */ KEY_VOLUMEUP, + /* 177 */ KEY_RESERVED, + /* 178 */ KEY_RESERVED, + /* 179 */ KEY_RESERVED, + /* 180 */ KEY_RESERVED, + /* 181 */ KEY_KPSLASH, + /* 182 */ KEY_RESERVED, + /* 183 */ KEY_PRINT, + /* 184 */ KEY_RIGHTALT, + /* 185 */ KEY_RESERVED, + /* 186 */ KEY_RESERVED, + /* 187 */ KEY_RESERVED, + /* 188 */ KEY_RESERVED, + /* 189 */ KEY_RESERVED, + /* 190 */ KEY_RESERVED, + /* 191 */ KEY_RESERVED, + /* 192 */ KEY_RESERVED, + /* 193 */ KEY_RESERVED, + /* 194 */ KEY_RESERVED, + /* 195 */ KEY_RESERVED, + /* 196 */ KEY_RESERVED, + /* 197 */ KEY_RESERVED, + /* 198 */ KEY_RESERVED, + /* 199 */ KEY_HOME, + /* 200 */ KEY_UP, + /* 201 */ KEY_PAGEUP, + /* 202 */ KEY_RESERVED, + /* 203 */ KEY_LEFT, + /* 204 */ KEY_RESERVED, + /* 205 */ KEY_RIGHT, + /* 206 */ KEY_RESERVED, + /* 207 */ KEY_END, + /* 208 */ KEY_DOWN, + /* 209 */ KEY_PAGEDOWN, + /* 210 */ KEY_INSERT, + /* 211 */ KEY_DELETE, + /* 212 */ KEY_RESERVED, + /* 213 */ KEY_RESERVED, + /* 214 */ KEY_RESERVED, + /* 215 */ KEY_RESERVED, + /* 216 */ KEY_RESERVED, + /* 217 */ KEY_RESERVED, + /* 218 */ KEY_RESERVED, + /* 219 */ KEY_LEFTMETA, + /* 220 */ KEY_RIGHTMETA, + /* 221 */ KEY_MENU, + /* 222 */ KEY_RESERVED, + /* 223 */ KEY_RESERVED, + /* 224 */ KEY_RESERVED, + /* 225 */ KEY_RESERVED, + /* 226 */ KEY_RESERVED, + /* 227 */ KEY_RESERVED, + /* 228 */ KEY_RESERVED, + /* 229 */ KEY_RESERVED, + /* 230 */ KEY_RESERVED, + /* 231 */ KEY_RESERVED, + /* 232 */ KEY_RESERVED, + /* 233 */ KEY_RESERVED, + /* 234 */ KEY_RESERVED, + /* 235 */ KEY_RESERVED, + /* 236 */ KEY_RESERVED, + /* 237 */ KEY_SETUP, +}; +#define WS_XT_MAP_SIZE (sizeof(wsXtMap)/sizeof(*wsXtMap)) + +uint32_t +wskey_transcode(int wskey) +{ + if (wskey < 0 || wskey >= WS_XT_MAP_SIZE) + return KEY_UNKNOWN; + return wsXtMap[wskey]; +} From 7ac4a15489c59a362ea395a9d50416ca5266df1d Mon Sep 17 00:00:00 2001 From: Rafael Sadowski Date: Sun, 3 Sep 2023 20:25:37 +0200 Subject: [PATCH 08/41] fix compile with new libinput_init API --- meson.build | 6 +++--- src/libinput-private.h | 3 +++ src/wscons.c | 42 ++++++++++++++++++++++++++++++++++++++---- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/meson.build b/meson.build index 9fc7ced5..b5a712c2 100644 --- a/meson.build +++ b/meson.build @@ -361,8 +361,8 @@ src_libinput = src_libfilter + [ 'src/libinput_openbsd.c', 'src/libinput.h', 'src/libinput-private.h', - 'src/udev-seat_openbsd.c', - 'src/udev-seat.h', + #'src/udev-seat_openbsd.c', + #'src/udev-seat.h', 'src/timer.c', 'src/timer.h', 'include/linux/input.h', @@ -423,7 +423,7 @@ mapfile = dir_src / 'libinput.sym' version_flag = '-Wl,--version-script,@0@'.format(mapfile) lib_libinput = shared_library('input', src_libinput, - include_directories : [include_directories('.'), includes_include], + include_directories : [include_directories('.'),include_directories('include/linux/freebsd'), includes_include], dependencies : deps_libinput, version : libinput_so_version, link_args : version_flag, diff --git a/src/libinput-private.h b/src/libinput-private.h index f3f441cb..a14b7711 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -411,6 +411,9 @@ struct libinput_device { void *user_data; int refcount; struct libinput_device_config config; + struct libinput_source *source; + char* devname; + int fd; }; enum libinput_tablet_tool_axis { diff --git a/src/wscons.c b/src/wscons.c index eb12c708..b3db36b5 100644 --- a/src/wscons.c +++ b/src/wscons.c @@ -30,6 +30,7 @@ #include #include "libinput.h" +#include "input-event-codes.h" #include "libinput-util.h" #include "libinput-private.h" @@ -157,6 +158,13 @@ wscons_device_dispatch(void *data) } } +static void +udev_seat_destroy(struct libinput_seat *seat) +{ + struct udev_seat *useat = (struct udev_seat*)seat; + free(useat); +} + static struct libinput_seat* wscons_seat_get(struct libinput *libinput, const char *seat_name_physical, const char *seat_name_logical) @@ -177,14 +185,15 @@ wscons_seat_get(struct libinput *libinput, const char *seat_name_physical, return NULL; libinput_seat_init(seat, libinput, seat_name_physical, - seat_name_logical); + seat_name_logical, udev_seat_destroy); return seat; } LIBINPUT_EXPORT struct libinput * libinput_udev_create_context(const struct libinput_interface *interface, - void *user_data, struct udev *udev) + void *user_data, + struct udev *udev) { struct libinput *libinput; @@ -193,7 +202,7 @@ libinput_udev_create_context(const struct libinput_interface *interface, if (libinput == NULL) return NULL; - if (libinput_init(libinput, interface, user_data) != 0) { + if (libinput_init(libinput, interface, &interface_backend, user_data) != 0) { free(libinput); return NULL; } @@ -228,6 +237,31 @@ libinput_udev_assign_seat(struct libinput *libinput, const char *seat_id) return 0; } +static int +udev_input_enable(struct libinput *libinput) +{ + return 0; +} + +static void +udev_input_disable(struct libinput *libinput) +{ +} +static void +udev_input_destroy(struct libinput *libinput) +{ +} +static void +udev_device_change_seat(struct libinput *libinput) +{ +} + +static const struct libinput_interface_backend interface_backend = { + .resume = udev_input_enable, + .suspend = udev_input_disable, + .destroy = udev_input_destroy, + .device_change_seat = udev_device_change_seat, +}; LIBINPUT_EXPORT struct libinput * libinput_path_create_context(const struct libinput_interface *interface, @@ -239,7 +273,7 @@ libinput_path_create_context(const struct libinput_interface *interface, if (libinput == NULL) return NULL; - if (libinput_init(libinput, interface, user_data) != 0) { + if (libinput_init(libinput, interface, &interface_backend, user_data) != 0) { free(libinput); return NULL; } From 9357ecb64e3f0beb22ce09c2685bca20491767a7 Mon Sep 17 00:00:00 2001 From: Rafael Sadowski Date: Sun, 3 Sep 2023 20:34:49 +0200 Subject: [PATCH 09/41] sync with 1.24.0 --- src/libinput_openbsd.c | 442 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 424 insertions(+), 18 deletions(-) diff --git a/src/libinput_openbsd.c b/src/libinput_openbsd.c index 9caffefc..63d3ef07 100644 --- a/src/libinput_openbsd.c +++ b/src/libinput_openbsd.c @@ -36,6 +36,7 @@ #include "libinput.h" #include "libinput-private.h" +#include "evdev.h" #include "timer.h" #include "quirks.h" @@ -74,6 +75,7 @@ ASSERT_INT_SIZE(enum libinput_config_click_method); ASSERT_INT_SIZE(enum libinput_config_middle_emulation_state); ASSERT_INT_SIZE(enum libinput_config_scroll_method); ASSERT_INT_SIZE(enum libinput_config_dwt_state); +ASSERT_INT_SIZE(enum libinput_config_dwtp_state); static inline const char * event_type_to_str(enum libinput_event_type type) @@ -86,6 +88,9 @@ event_type_to_str(enum libinput_event_type type) CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE); CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_BUTTON); CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_AXIS); + CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_SCROLL_WHEEL); + CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_SCROLL_FINGER); + CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS); CASE_RETURN_STRING(LIBINPUT_EVENT_TOUCH_DOWN); CASE_RETURN_STRING(LIBINPUT_EVENT_TOUCH_UP); CASE_RETURN_STRING(LIBINPUT_EVENT_TOUCH_MOTION); @@ -105,6 +110,8 @@ event_type_to_str(enum libinput_event_type type) CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_PINCH_BEGIN); CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_PINCH_UPDATE); CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_PINCH_END); + CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_HOLD_BEGIN); + CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_HOLD_END); CASE_RETURN_STRING(LIBINPUT_EVENT_SWITCH_TOGGLE); case LIBINPUT_EVENT_NONE: abort(); @@ -120,6 +127,29 @@ check_event_type(struct libinput *libinput, ...) { bool rc = false; + va_list args; + unsigned int type_permitted; + + va_start(args, type_in); + type_permitted = va_arg(args, unsigned int); + + while (type_permitted != (unsigned int)-1) { + if (type_permitted == type_in) { + rc = true; + break; + } + type_permitted = va_arg(args, unsigned int); + } + + va_end(args); + + if (!rc) { + const char *name = event_type_to_str(type_in); + log_bug_client(libinput, + "Invalid event type %s (%d) passed to %s()\n", + name, type_in, function_name); + } + return rc; } @@ -149,6 +179,7 @@ struct libinput_event_pointer { struct device_float_coords delta_raw; struct device_coords absolute; struct discrete_coords discrete; + struct wheel_v120 v120; uint32_t button; uint32_t seat_button_count; enum libinput_button_state state; @@ -340,6 +371,9 @@ libinput_event_get_pointer_event(struct libinput_event *event) LIBINPUT_EVENT_POINTER_MOTION, LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, LIBINPUT_EVENT_POINTER_BUTTON, + LIBINPUT_EVENT_POINTER_SCROLL_WHEEL, + LIBINPUT_EVENT_POINTER_SCROLL_FINGER, + LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS, LIBINPUT_EVENT_POINTER_AXIS); return (struct libinput_event_pointer *) event; @@ -381,7 +415,9 @@ libinput_event_get_gesture_event(struct libinput_event *event) LIBINPUT_EVENT_GESTURE_SWIPE_END, LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, - LIBINPUT_EVENT_GESTURE_PINCH_END); + LIBINPUT_EVENT_GESTURE_PINCH_END, + LIBINPUT_EVENT_GESTURE_HOLD_BEGIN, + LIBINPUT_EVENT_GESTURE_HOLD_END); return (struct libinput_event_gesture *) event; } @@ -502,6 +538,9 @@ libinput_event_pointer_get_time(struct libinput_event_pointer *event) LIBINPUT_EVENT_POINTER_MOTION, LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, LIBINPUT_EVENT_POINTER_BUTTON, + LIBINPUT_EVENT_POINTER_SCROLL_WHEEL, + LIBINPUT_EVENT_POINTER_SCROLL_FINGER, + LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS, LIBINPUT_EVENT_POINTER_AXIS); return us2ms(event->time); @@ -516,6 +555,9 @@ libinput_event_pointer_get_time_usec(struct libinput_event_pointer *event) LIBINPUT_EVENT_POINTER_MOTION, LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, LIBINPUT_EVENT_POINTER_BUTTON, + LIBINPUT_EVENT_POINTER_SCROLL_WHEEL, + LIBINPUT_EVENT_POINTER_SCROLL_FINGER, + LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS, LIBINPUT_EVENT_POINTER_AXIS); return event->time; @@ -636,6 +678,9 @@ libinput_event_pointer_has_axis(struct libinput_event_pointer *event, require_event_type(libinput_event_get_context(&event->base), event->base.type, 0, + LIBINPUT_EVENT_POINTER_SCROLL_WHEEL, + LIBINPUT_EVENT_POINTER_SCROLL_FINGER, + LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS, LIBINPUT_EVENT_POINTER_AXIS); switch (axis) { @@ -702,6 +747,62 @@ libinput_event_pointer_get_axis_value_discrete(struct libinput_event_pointer *ev return value; } +LIBINPUT_EXPORT double +libinput_event_pointer_get_scroll_value(struct libinput_event_pointer *event, + enum libinput_pointer_axis axis) +{ + struct libinput *libinput = event->base.device->seat->libinput; + double value = 0; + + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0.0, + LIBINPUT_EVENT_POINTER_SCROLL_WHEEL, + LIBINPUT_EVENT_POINTER_SCROLL_FINGER, + LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS); + + if (!libinput_event_pointer_has_axis(event, axis)) { + log_bug_client(libinput, "value requested for unset axis\n"); + } else { + switch (axis) { + case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL: + value = event->delta.x; + break; + case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: + value = event->delta.y; + break; + } + } + return value; +} + +LIBINPUT_EXPORT double +libinput_event_pointer_get_scroll_value_v120(struct libinput_event_pointer *event, + enum libinput_pointer_axis axis) +{ + struct libinput *libinput = event->base.device->seat->libinput; + double value = 0; + + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0.0, + LIBINPUT_EVENT_POINTER_SCROLL_WHEEL); + + if (!libinput_event_pointer_has_axis(event, axis)) { + log_bug_client(libinput, "value requested for unset axis\n"); + } else { + switch (axis) { + case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL: + value = event->v120.x; + break; + case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: + value = event->v120.y; + break; + } + } + return value; +} + LIBINPUT_EXPORT enum libinput_pointer_axis_source libinput_event_pointer_get_axis_source(struct libinput_event_pointer *event) { @@ -808,7 +909,9 @@ libinput_event_gesture_get_time(struct libinput_event_gesture *event) LIBINPUT_EVENT_GESTURE_PINCH_END, LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, - LIBINPUT_EVENT_GESTURE_SWIPE_END); + LIBINPUT_EVENT_GESTURE_SWIPE_END, + LIBINPUT_EVENT_GESTURE_HOLD_BEGIN, + LIBINPUT_EVENT_GESTURE_HOLD_END); return us2ms(event->time); } @@ -824,7 +927,9 @@ libinput_event_gesture_get_time_usec(struct libinput_event_gesture *event) LIBINPUT_EVENT_GESTURE_PINCH_END, LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, - LIBINPUT_EVENT_GESTURE_SWIPE_END); + LIBINPUT_EVENT_GESTURE_SWIPE_END, + LIBINPUT_EVENT_GESTURE_HOLD_BEGIN, + LIBINPUT_EVENT_GESTURE_HOLD_END); return event->time; } @@ -840,7 +945,9 @@ libinput_event_gesture_get_finger_count(struct libinput_event_gesture *event) LIBINPUT_EVENT_GESTURE_PINCH_END, LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, - LIBINPUT_EVENT_GESTURE_SWIPE_END); + LIBINPUT_EVENT_GESTURE_SWIPE_END, + LIBINPUT_EVENT_GESTURE_HOLD_BEGIN, + LIBINPUT_EVENT_GESTURE_HOLD_END); return event->finger_count; } @@ -852,7 +959,8 @@ libinput_event_gesture_get_cancelled(struct libinput_event_gesture *event) event->base.type, 0, LIBINPUT_EVENT_GESTURE_PINCH_END, - LIBINPUT_EVENT_GESTURE_SWIPE_END); + LIBINPUT_EVENT_GESTURE_SWIPE_END, + LIBINPUT_EVENT_GESTURE_HOLD_END); return event->cancelled; } @@ -2298,14 +2406,82 @@ pointer_notify_button(struct libinput_device *device, } void -pointer_notify_axis(struct libinput_device *device, - uint64_t time, - uint32_t axes, - enum libinput_pointer_axis_source source, - const struct normalized_coords *delta, - const struct discrete_coords *discrete) +pointer_notify_axis_finger(struct libinput_device *device, + uint64_t time, + uint32_t axes, + const struct normalized_coords *delta) +{ + struct libinput_event_pointer *axis_event, *axis_event_legacy; + const struct discrete_coords zero_discrete = {0}; + const struct wheel_v120 zero_v120 = {0}; + + if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER)) + return; + + axis_event = zalloc(sizeof *axis_event); + axis_event_legacy = zalloc(sizeof *axis_event_legacy); + + *axis_event = (struct libinput_event_pointer) { + .time = time, + .delta = *delta, + .source = LIBINPUT_POINTER_AXIS_SOURCE_FINGER, + .axes = axes, + .discrete = zero_discrete, + .v120 = zero_v120, + }; + *axis_event_legacy = *axis_event; + + post_device_event(device, time, + LIBINPUT_EVENT_POINTER_SCROLL_FINGER, + &axis_event->base); + post_device_event(device, time, + LIBINPUT_EVENT_POINTER_AXIS, + &axis_event_legacy->base); +} + +void +pointer_notify_axis_continuous(struct libinput_device *device, + uint64_t time, + uint32_t axes, + const struct normalized_coords *delta) +{ + struct libinput_event_pointer *axis_event, *axis_event_legacy; + const struct discrete_coords zero_discrete = {0}; + const struct wheel_v120 zero_v120 = {0}; + + if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER)) + return; + + axis_event = zalloc(sizeof *axis_event); + axis_event_legacy = zalloc(sizeof *axis_event_legacy); + + *axis_event = (struct libinput_event_pointer) { + .time = time, + .delta = *delta, + .source = LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS, + .axes = axes, + .discrete = zero_discrete, + .v120 = zero_v120, + }; + *axis_event_legacy = *axis_event; + + post_device_event(device, time, + LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS, + &axis_event->base); + post_device_event(device, time, + LIBINPUT_EVENT_POINTER_AXIS, + &axis_event_legacy->base); +} + +void +pointer_notify_axis_legacy_wheel(struct libinput_device *device, + uint64_t time, + uint32_t axes, + const struct normalized_coords *delta, + const struct discrete_coords *discrete) { struct libinput_event_pointer *axis_event; + const struct wheel_v120 zero_v120 = {0}; if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER)) return; @@ -2315,9 +2491,10 @@ pointer_notify_axis(struct libinput_device *device, *axis_event = (struct libinput_event_pointer) { .time = time, .delta = *delta, - .source = source, + .source = LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, .axes = axes, .discrete = *discrete, + .v120 = zero_v120, }; post_device_event(device, time, @@ -2325,6 +2502,37 @@ pointer_notify_axis(struct libinput_device *device, &axis_event->base); } +void +pointer_notify_axis_wheel(struct libinput_device *device, + uint64_t time, + uint32_t axes, + const struct normalized_coords *delta, + const struct wheel_v120 *v120) +{ + struct libinput_event_pointer *axis_event; + + if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER)) + return; + + axis_event = zalloc(sizeof *axis_event); + + *axis_event = (struct libinput_event_pointer) { + .time = time, + .delta = *delta, + .source = LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, + .axes = axes, + .discrete.x = 0, + .discrete.y = 0, + .v120 = *v120, + }; + + post_device_event(device, time, + LIBINPUT_EVENT_POINTER_SCROLL_WHEEL, + &axis_event->base); + + /* legacy wheel events are sent separately */ +} + void touch_notify_touch_down(struct libinput_device *device, uint64_t time, @@ -2761,6 +2969,29 @@ gesture_notify_pinch_end(struct libinput_device *device, finger_count, cancelled, &zero, &zero, scale, 0.0); } +void +gesture_notify_hold(struct libinput_device *device, + uint64_t time, + int finger_count) +{ + const struct normalized_coords zero = { 0.0, 0.0 }; + + gesture_notify(device, time, LIBINPUT_EVENT_GESTURE_HOLD_BEGIN, + finger_count, 0, &zero, &zero, 0.0, 0.0); +} + +void +gesture_notify_hold_end(struct libinput_device *device, + uint64_t time, + int finger_count, + bool cancelled) +{ + const struct normalized_coords zero = { 0.0, 0.0 }; + + gesture_notify(device, time, LIBINPUT_EVENT_GESTURE_HOLD_END, + finger_count, cancelled, &zero, &zero, 0, 0.0); +} + void switch_notify_toggle(struct libinput_device *device, uint64_t time, @@ -3087,7 +3318,7 @@ libinput_tablet_pad_mode_group_has_button(struct libinput_tablet_pad_mode_group libinput_device_tablet_pad_get_num_buttons(group->device)) return 0; - return !!(group->button_mask & (1 << button)); + return !!(group->button_mask & bit(button)); } LIBINPUT_EXPORT int @@ -3098,7 +3329,7 @@ libinput_tablet_pad_mode_group_has_ring(struct libinput_tablet_pad_mode_group *g libinput_device_tablet_pad_get_num_rings(group->device)) return 0; - return !!(group->ring_mask & (1 << ring)); + return !!(group->ring_mask & bit(ring)); } LIBINPUT_EXPORT int @@ -3109,7 +3340,7 @@ libinput_tablet_pad_mode_group_has_strip(struct libinput_tablet_pad_mode_group * libinput_device_tablet_pad_get_num_strips(group->device)) return 0; - return !!(group->strip_mask & (1 << strip)); + return !!(group->strip_mask & bit(strip)); } LIBINPUT_EXPORT int @@ -3120,7 +3351,7 @@ libinput_tablet_pad_mode_group_button_is_toggle(struct libinput_tablet_pad_mode_ libinput_device_tablet_pad_get_num_buttons(group->device)) return 0; - return !!(group->toggle_button_mask & (1 << button)); + return !!(group->toggle_button_mask & bit(button)); } LIBINPUT_EXPORT struct libinput_tablet_pad_mode_group * @@ -3193,6 +3424,9 @@ libinput_event_pointer_get_base_event(struct libinput_event_pointer *event) LIBINPUT_EVENT_POINTER_MOTION, LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, LIBINPUT_EVENT_POINTER_BUTTON, + LIBINPUT_EVENT_POINTER_SCROLL_WHEEL, + LIBINPUT_EVENT_POINTER_SCROLL_FINGER, + LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS, LIBINPUT_EVENT_POINTER_AXIS); return &event->base; @@ -3224,7 +3458,9 @@ libinput_event_gesture_get_base_event(struct libinput_event_gesture *event) LIBINPUT_EVENT_GESTURE_SWIPE_END, LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, - LIBINPUT_EVENT_GESTURE_PINCH_END); + LIBINPUT_EVENT_GESTURE_PINCH_END, + LIBINPUT_EVENT_GESTURE_HOLD_BEGIN, + LIBINPUT_EVENT_GESTURE_HOLD_END); return &event->base; } @@ -3813,6 +4049,7 @@ libinput_device_config_accel_set_profile(struct libinput_device *device, switch (profile) { case LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT: case LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE: + case LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM: break; default: return LIBINPUT_CONFIG_STATUS_INVALID; @@ -3825,6 +4062,133 @@ libinput_device_config_accel_set_profile(struct libinput_device *device, return device->config.accel->set_profile(device, profile); } +static inline struct libinput_config_accel_custom_func * +libinput_config_accel_custom_func_create(void) +{ + struct libinput_config_accel_custom_func *func = zalloc(sizeof(*func)); + + func->step = 1.0; + func->npoints = 2; + func->points[0] = 0.0; /* default to a flat unaccelerated function */ + func->points[1] = 1.0; + + return func; +} + +static inline void +libinput_config_accel_custom_func_destroy(struct libinput_config_accel_custom_func * func) +{ + free(func); +} + +LIBINPUT_EXPORT struct libinput_config_accel * +libinput_config_accel_create(enum libinput_config_accel_profile profile) +{ + struct libinput_config_accel *config = zalloc(sizeof(*config)); + + config->profile = profile; + + switch (profile) { + case LIBINPUT_CONFIG_ACCEL_PROFILE_NONE: + break; + case LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT: + case LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE: + return config; + case LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM: + config->custom.fallback = libinput_config_accel_custom_func_create(); + return config; + } + + free(config); + return NULL; +} + +LIBINPUT_EXPORT void +libinput_config_accel_destroy(struct libinput_config_accel *accel_config) +{ + libinput_config_accel_custom_func_destroy(accel_config->custom.fallback); + libinput_config_accel_custom_func_destroy(accel_config->custom.motion); + libinput_config_accel_custom_func_destroy(accel_config->custom.scroll); + free(accel_config); +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_accel_apply(struct libinput_device *device, + struct libinput_config_accel *accel_config) +{ + enum libinput_config_status status; + status = libinput_device_config_accel_set_profile(device, accel_config->profile); + if (status != LIBINPUT_CONFIG_STATUS_SUCCESS) + return status; + + switch (accel_config->profile) { + case LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT: + case LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE: + { + double speed = libinput_device_config_accel_get_default_speed(device); + return libinput_device_config_accel_set_speed(device, speed); + } + case LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM: + return device->config.accel->set_accel_config(device, accel_config); + + default: + return LIBINPUT_CONFIG_STATUS_INVALID; + } +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_config_accel_set_points(struct libinput_config_accel *config, + enum libinput_config_accel_type accel_type, + double step, size_t npoints, double *points) +{ + if (config->profile != LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM) + return LIBINPUT_CONFIG_STATUS_INVALID; + + switch (accel_type) { + case LIBINPUT_ACCEL_TYPE_FALLBACK: + case LIBINPUT_ACCEL_TYPE_MOTION: + case LIBINPUT_ACCEL_TYPE_SCROLL: + break; + default: + return LIBINPUT_CONFIG_STATUS_INVALID; + } + + if (step <= 0 || step > LIBINPUT_ACCEL_STEP_MAX) + return LIBINPUT_CONFIG_STATUS_INVALID; + + if (npoints < LIBINPUT_ACCEL_NPOINTS_MIN || npoints > LIBINPUT_ACCEL_NPOINTS_MAX) + return LIBINPUT_CONFIG_STATUS_INVALID; + + for (size_t idx = 0; idx < npoints; idx++) { + if (points[idx] < LIBINPUT_ACCEL_POINT_MIN_VALUE || + points[idx] > LIBINPUT_ACCEL_POINT_MAX_VALUE) + return LIBINPUT_CONFIG_STATUS_INVALID; + } + + struct libinput_config_accel_custom_func *func = libinput_config_accel_custom_func_create(); + + func->step = step; + func->npoints = npoints; + memcpy(func->points, points, sizeof(*points) * npoints); + + switch (accel_type) { + case LIBINPUT_ACCEL_TYPE_FALLBACK: + libinput_config_accel_custom_func_destroy(config->custom.fallback); + config->custom.fallback = func; + break; + case LIBINPUT_ACCEL_TYPE_MOTION: + libinput_config_accel_custom_func_destroy(config->custom.motion); + config->custom.motion = func; + break; + case LIBINPUT_ACCEL_TYPE_SCROLL: + libinput_config_accel_custom_func_destroy(config->custom.scroll); + config->custom.scroll = func; + break; + } + + return LIBINPUT_CONFIG_STATUS_SUCCESS; +} + LIBINPUT_EXPORT int libinput_device_config_scroll_has_natural_scroll(struct libinput_device *device) { @@ -4171,6 +4535,48 @@ libinput_device_config_dwt_get_default_enabled(struct libinput_device *device) return device->config.dwt->get_default_enabled(device); } +LIBINPUT_EXPORT int +libinput_device_config_dwtp_is_available(struct libinput_device *device) +{ + if (!device->config.dwtp) + return 0; + + return device->config.dwtp->is_available(device); +} + +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_dwtp_set_enabled(struct libinput_device *device, + enum libinput_config_dwtp_state enable) +{ + if (enable != LIBINPUT_CONFIG_DWTP_ENABLED && + enable != LIBINPUT_CONFIG_DWTP_DISABLED) + return LIBINPUT_CONFIG_STATUS_INVALID; + + if (!libinput_device_config_dwtp_is_available(device)) + return enable ? LIBINPUT_CONFIG_STATUS_UNSUPPORTED : + LIBINPUT_CONFIG_STATUS_SUCCESS; + + return device->config.dwtp->set_enabled(device, enable); +} + +LIBINPUT_EXPORT enum libinput_config_dwtp_state +libinput_device_config_dwtp_get_enabled(struct libinput_device *device) +{ + if (!libinput_device_config_dwtp_is_available(device)) + return LIBINPUT_CONFIG_DWTP_DISABLED; + + return device->config.dwtp->get_enabled(device); +} + +LIBINPUT_EXPORT enum libinput_config_dwtp_state +libinput_device_config_dwtp_get_default_enabled(struct libinput_device *device) +{ + if (!libinput_device_config_dwtp_is_available(device)) + return LIBINPUT_CONFIG_DWTP_DISABLED; + + return device->config.dwtp->get_default_enabled(device); +} + LIBINPUT_EXPORT int libinput_device_config_rotation_is_available(struct libinput_device *device) { @@ -4188,7 +4594,7 @@ libinput_device_config_rotation_set_angle(struct libinput_device *device, return degrees_cw ? LIBINPUT_CONFIG_STATUS_UNSUPPORTED : LIBINPUT_CONFIG_STATUS_SUCCESS; - if (degrees_cw >= 360 || degrees_cw % 90) + if (degrees_cw >= 360) return LIBINPUT_CONFIG_STATUS_INVALID; return device->config.rotation->set_angle(device, degrees_cw); From 06f10ec99f3b03a404231988c28ebb2633a22c27 Mon Sep 17 00:00:00 2001 From: Rafael Sadowski Date: Sun, 3 Sep 2023 20:37:13 +0200 Subject: [PATCH 10/41] fix with new API --- src/wscons.c | 56 ++++++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/src/wscons.c b/src/wscons.c index b3db36b5..521a0f49 100644 --- a/src/wscons.c +++ b/src/wscons.c @@ -41,6 +41,36 @@ extern uint32_t wskey_transcode(int); static int old_value = -1; +static int +udev_input_enable(struct libinput *libinput) +{ + return 0; +} + +static void +udev_input_disable(struct libinput *libinput) +{ +} + +static void +udev_input_destroy(struct libinput *libinput) +{ +} + +static int +udev_device_change_seat(struct libinput_device *device, + const char *seat_name) +{ + return 0; +} + +static const struct libinput_interface_backend interface_backend = { + .resume = udev_input_enable, + .suspend = udev_input_disable, + .destroy = udev_input_destroy, + .device_change_seat = udev_device_change_seat, +}; + static void wscons_process(struct libinput_device *device, struct wscons_event *wsevent) { @@ -237,32 +267,6 @@ libinput_udev_assign_seat(struct libinput *libinput, const char *seat_id) return 0; } -static int -udev_input_enable(struct libinput *libinput) -{ - return 0; -} - -static void -udev_input_disable(struct libinput *libinput) -{ -} -static void -udev_input_destroy(struct libinput *libinput) -{ -} -static void -udev_device_change_seat(struct libinput *libinput) -{ -} - -static const struct libinput_interface_backend interface_backend = { - .resume = udev_input_enable, - .suspend = udev_input_disable, - .destroy = udev_input_destroy, - .device_change_seat = udev_device_change_seat, -}; - LIBINPUT_EXPORT struct libinput * libinput_path_create_context(const struct libinput_interface *interface, void *user_data) From 06b4a891a24ac94685a316acf6b6bb82dca3581a Mon Sep 17 00:00:00 2001 From: Rafael Sadowski Date: Sun, 3 Sep 2023 21:57:17 +0200 Subject: [PATCH 11/41] add vertical/horizontal scrolling support 3264fd0cc024fbffaa461e928528f0c2e8089916 789609f43978b3ef1998fdb6853701ab2f0ad6ee --- src/libinput-private.h | 10 ++++++++++ src/libinput-util.h | 5 +++++ src/libinput_openbsd.c | 31 ++++++++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/libinput-private.h b/src/libinput-private.h index a14b7711..9f4d7b7f 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -980,4 +980,14 @@ static inline void *libinput_libwacom_ref(struct libinput *li) { return NULL; } static inline void libinput_libwacom_unref(struct libinput *li) {} #endif + +#ifdef __OpenBSD__ +void +axis_notify_event(struct libinput_device *device, + uint64_t time, + const struct normalized_coords *delta, + const struct device_float_coords *raw); +#endif + + #endif /* LIBINPUT_PRIVATE_H */ diff --git a/src/libinput-util.h b/src/libinput-util.h index 8b14f76d..4e6de6b2 100644 --- a/src/libinput-util.h +++ b/src/libinput-util.h @@ -66,4 +66,9 @@ #define LIBINPUT_EXPORT __attribute__ ((visibility("default"))) #define LIBINPUT_UNUSED __attribute__ ((unused)) +#ifdef __OpenBSD__ +#define bit(x_) (1UL << (x_)) +#define NBITS(b) (b * 8) +#endif + #endif /* LIBINPUT_UTIL_H */ diff --git a/src/libinput_openbsd.c b/src/libinput_openbsd.c index 63d3ef07..970705c0 100644 --- a/src/libinput_openbsd.c +++ b/src/libinput_openbsd.c @@ -2329,6 +2329,35 @@ keyboard_notify_key(struct libinput_device *device, &key_event->base); } +void +axis_notify_event(struct libinput_device *device, + uint64_t time, + const struct normalized_coords *delta, + const struct device_float_coords *raw) +{ + struct libinput_event_pointer *axis_event; + uint32_t axes; + + axis_event = zalloc(sizeof *axis_event); + if (!axis_event) + return; + if (delta->x) + axes = bit(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); + else + axes = bit(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); + + *axis_event = (struct libinput_event_pointer) { + .time = time, + .delta = *delta, + .delta_raw = *raw, + .source = LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, + .axes = axes, + }; + + post_device_event(device, time, LIBINPUT_EVENT_POINTER_SCROLL_WHEEL, + &axis_event->base); +} + void pointer_notify_motion(struct libinput_device *device, uint64_t time, @@ -3288,7 +3317,7 @@ LIBINPUT_EXPORT struct libinput_tablet_pad_mode_group* libinput_device_tablet_pad_get_mode_group(struct libinput_device *device, unsigned int index) { - return 0xdeadbeef; // TODO + return NULL; // TODO } LIBINPUT_EXPORT unsigned int From d7210aeae75212cbc2a74e935c103a58e176fedb Mon Sep 17 00:00:00 2001 From: Rafael Sadowski Date: Mon, 4 Sep 2023 11:35:08 +0200 Subject: [PATCH 12/41] Enable dep_libinput_util --- meson.build | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/meson.build b/meson.build index b5a712c2..976a1ef0 100644 --- a/meson.build +++ b/meson.build @@ -262,9 +262,6 @@ else endif ############ libinput-util.a ############ -if host_machine.system() == 'openbsd' - dep_libinput_util = [] -else # Basic compilation test to make sure the headers include and define all the # necessary bits. util_headers = [ @@ -302,7 +299,6 @@ libinput_util = static_library('libinput-util', include_directories : includes_include) dep_libinput_util = declare_dependency(link_with : libinput_util) -endif ############ libfilter.a ############ src_libfilter = [ 'src/filter.c', @@ -359,14 +355,8 @@ install_headers('src/libinput.h') if host_machine.system() == 'openbsd' src_libinput = src_libfilter + [ 'src/libinput_openbsd.c', - 'src/libinput.h', - 'src/libinput-private.h', - #'src/udev-seat_openbsd.c', - #'src/udev-seat.h', + 'src/libinput-private-config.c', 'src/timer.c', - 'src/timer.h', - 'include/linux/input.h', - # OpenBSD 'src/wskbdmap.c', 'src/wscons.c' ] From f84007b7a5680801ff03741dcd6d382b443a308a Mon Sep 17 00:00:00 2001 From: Rafael Sadowski Date: Mon, 4 Sep 2023 13:36:12 +0200 Subject: [PATCH 13/41] add libevdev.h Add https://gitlab.tetaneutral.net/mherrb/libevdev-openbsd/ to avoid conflicts between sysutils/libevdev-openbsd and wayland/libinput-openbsd --- include/libevdev/libevdev.h | 32 ++++++++++++++++++++++++++++++++ meson.build | 5 ++++- 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 include/libevdev/libevdev.h diff --git a/include/libevdev/libevdev.h b/include/libevdev/libevdev.h new file mode 100644 index 00000000..35c5b704 --- /dev/null +++ b/include/libevdev/libevdev.h @@ -0,0 +1,32 @@ +/* + * Copyright © 2013 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +#ifndef LIBEVDEV_H +#define LIBEVDEV_H + +#include + +extern int libevdev_event_code_from_name(unsigned int type, const char *name); +extern const char * libevdev_event_code_get_name(unsigned int type, unsigned int code); +#endif diff --git a/meson.build b/meson.build index 976a1ef0..bac4975a 100644 --- a/meson.build +++ b/meson.build @@ -413,7 +413,10 @@ mapfile = dir_src / 'libinput.sym' version_flag = '-Wl,--version-script,@0@'.format(mapfile) lib_libinput = shared_library('input', src_libinput, - include_directories : [include_directories('.'),include_directories('include/linux/freebsd'), includes_include], + include_directories : [include_directories('.'), + include_directories('include'), + include_directories('include/linux/freebsd'), + includes_include], dependencies : deps_libinput, version : libinput_so_version, link_args : version_flag, From 73273362735a530556bbeaf131500223aa69f059 Mon Sep 17 00:00:00 2001 From: Rafael Sadowski Date: Mon, 4 Sep 2023 13:40:30 +0200 Subject: [PATCH 14/41] Do not install libinput under /etc on OpenBSD --- meson.build | 2 ++ 1 file changed, 2 insertions(+) diff --git a/meson.build b/meson.build index bac4975a..14597067 100644 --- a/meson.build +++ b/meson.build @@ -344,11 +344,13 @@ libquirks = static_library('quirks', src_libquirks, dep_libquirks = declare_dependency(link_with : libquirks) # Create /etc/libinput +if host_machine.system() != 'openbsd' if meson.version().version_compare('>= 0.60') install_emptydir(dir_etc / 'libinput') else install_subdir('libinput', install_dir : dir_etc) endif +endif ############ libinput.so ############ install_headers('src/libinput.h') From 1c9a092a5008425797d60697fc76a61378893c09 Mon Sep 17 00:00:00 2001 From: Rafael Sadowski Date: Mon, 4 Sep 2023 14:23:34 +0200 Subject: [PATCH 15/41] try to fix a lazy binding issue --- src/libinput_openbsd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libinput_openbsd.c b/src/libinput_openbsd.c index 970705c0..8a07ac8a 100644 --- a/src/libinput_openbsd.c +++ b/src/libinput_openbsd.c @@ -2197,7 +2197,7 @@ post_base_event(struct libinput_device *device, libinput_post_event(libinput, event); } -static void +void post_device_event(struct libinput_device *device, uint64_t time, enum libinput_event_type type, From c20e8698abc710c719bc084c8f43c54d1f0b6c38 Mon Sep 17 00:00:00 2001 From: Rafael Sadowski Date: Mon, 4 Sep 2023 18:15:27 +0200 Subject: [PATCH 16/41] return unsupported instead of a null ptr --- src/libinput_openbsd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libinput_openbsd.c b/src/libinput_openbsd.c index 8a07ac8a..eb9c94dc 100644 --- a/src/libinput_openbsd.c +++ b/src/libinput_openbsd.c @@ -3184,13 +3184,13 @@ libinput_device_get_device_group(struct libinput_device *device) LIBINPUT_EXPORT const char * libinput_device_get_sysname(struct libinput_device *device) { - return NULL; // TODO + return "unsupported"; } LIBINPUT_EXPORT const char * libinput_device_get_name(struct libinput_device *device) { - return NULL; // TODO + return "unsupported"; } LIBINPUT_EXPORT unsigned int @@ -3208,7 +3208,7 @@ libinput_device_get_id_vendor(struct libinput_device *device) LIBINPUT_EXPORT const char * libinput_device_get_output_name(struct libinput_device *device) { - return NULL; // TODO + return "unsupported"; } LIBINPUT_EXPORT struct libinput_seat * From 26b7c6bc8b79f2fbc8c58e01d3432ffd7e346d8d Mon Sep 17 00:00:00 2001 From: Rafael Sadowski Date: Mon, 4 Sep 2023 18:50:39 +0200 Subject: [PATCH 17/41] Sync with matthieu --- src/libinput_openbsd.c | 140 ++++++++++++++++++++++++++++++++++------- 1 file changed, 119 insertions(+), 21 deletions(-) diff --git a/src/libinput_openbsd.c b/src/libinput_openbsd.c index eb9c94dc..73458e7f 100644 --- a/src/libinput_openbsd.c +++ b/src/libinput_openbsd.c @@ -526,6 +526,7 @@ libinput_event_keyboard_get_seat_key_count( 0, LIBINPUT_EVENT_KEYBOARD_KEY); + fprintf(stderr, "%s: partial stub\n", __func__); return event->seat_key_count; } @@ -594,6 +595,7 @@ libinput_event_pointer_get_dx_unaccelerated( 0, LIBINPUT_EVENT_POINTER_MOTION); + // fprintf(stderr, "%s: partial stub\n", __func__); return event->delta_raw.x; } @@ -606,19 +608,32 @@ libinput_event_pointer_get_dy_unaccelerated( 0, LIBINPUT_EVENT_POINTER_MOTION); + // fprintf(stderr, "%s: partial stub\n", __func__); return event->delta_raw.y; } LIBINPUT_EXPORT double libinput_event_pointer_get_absolute_x(struct libinput_event_pointer *event) { - return 0xdeadbeef; // TODO + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE); + + fprintf(stderr, "%s: stub\n", __func__); + return (double)(-1); } LIBINPUT_EXPORT double libinput_event_pointer_get_absolute_y(struct libinput_event_pointer *event) { - return 0xdeadbeef; // TODO + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE); + + fprintf(stderr, "%s: stub\n", __func__); + return (double)(-1); } LIBINPUT_EXPORT double @@ -626,7 +641,13 @@ libinput_event_pointer_get_absolute_x_transformed( struct libinput_event_pointer *event, uint32_t width) { - return 0xdeadbeef; // TODO + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE); + + fprintf(stderr, "%s: stub\n", __func__); + return (double)(-1); } LIBINPUT_EXPORT double @@ -634,7 +655,13 @@ libinput_event_pointer_get_absolute_y_transformed( struct libinput_event_pointer *event, uint32_t height) { - return 0xdeadbeef; // TODO + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE); + + fprintf(stderr, "%s: stub\n", __func__); + return (double)(-1); } LIBINPUT_EXPORT uint32_t @@ -668,6 +695,7 @@ libinput_event_pointer_get_seat_button_count( 0, LIBINPUT_EVENT_POINTER_BUTTON); + // fprintf(stderr, "%s: partial stub\n", __func__); return event->seat_button_count; } @@ -696,6 +724,7 @@ LIBINPUT_EXPORT double libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event, enum libinput_pointer_axis axis) { + // XXX differnt struct libinput *libinput = event->base.device->seat->libinput; double value = 0; @@ -724,6 +753,7 @@ LIBINPUT_EXPORT double libinput_event_pointer_get_axis_value_discrete(struct libinput_event_pointer *event, enum libinput_pointer_axis axis) { + // XXX differnt struct libinput *libinput = event->base.device->seat->libinput; double value = 0; @@ -811,7 +841,9 @@ libinput_event_pointer_get_axis_source(struct libinput_event_pointer *event) 0, LIBINPUT_EVENT_POINTER_AXIS); - return event->source; + // return event->source; + /* XXX impossible to return an error, so pick a source type. */ + return LIBINPUT_POINTER_AXIS_SOURCE_WHEEL; } LIBINPUT_EXPORT uint32_t @@ -855,6 +887,7 @@ libinput_event_touch_get_slot(struct libinput_event_touch *event) LIBINPUT_EVENT_TOUCH_MOTION, LIBINPUT_EVENT_TOUCH_CANCEL); + fprintf(stderr, "%s: partial stub\n", __func__); return event->slot; } @@ -869,33 +902,62 @@ libinput_event_touch_get_seat_slot(struct libinput_event_touch *event) LIBINPUT_EVENT_TOUCH_MOTION, LIBINPUT_EVENT_TOUCH_CANCEL); + fprintf(stderr, "%s: partial stub\n", __func__); return event->seat_slot; } LIBINPUT_EXPORT double libinput_event_touch_get_x(struct libinput_event_touch *event) { - return 0xdeadbeef; // TODO + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TOUCH_DOWN, + LIBINPUT_EVENT_TOUCH_MOTION); + + fprintf(stderr, "%s: stub\n", __func__); + return (double)(-1); } LIBINPUT_EXPORT double libinput_event_touch_get_x_transformed(struct libinput_event_touch *event, uint32_t width) { - return 0xdeadbeef; // TODO + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TOUCH_DOWN, + LIBINPUT_EVENT_TOUCH_MOTION); + + fprintf(stderr, "%s: stub\n", __func__); + return (double)(-1); } LIBINPUT_EXPORT double libinput_event_touch_get_y_transformed(struct libinput_event_touch *event, uint32_t height) { - return 0xdeadbeef; // TODO + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TOUCH_DOWN, + LIBINPUT_EVENT_TOUCH_MOTION); + + fprintf(stderr, "%s: stub\n", __func__); + return (double)(-1); } LIBINPUT_EXPORT double libinput_event_touch_get_y(struct libinput_event_touch *event) { - return 0xdeadbeef; // TODO + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TOUCH_DOWN, + LIBINPUT_EVENT_TOUCH_MOTION); + + fprintf(stderr, "%s: stub\n", __func__); + return (double)(-1); } LIBINPUT_EXPORT uint32_t @@ -949,6 +1011,7 @@ libinput_event_gesture_get_finger_count(struct libinput_event_gesture *event) LIBINPUT_EVENT_GESTURE_HOLD_BEGIN, LIBINPUT_EVENT_GESTURE_HOLD_END); + fprintf(stderr, "%s: partial stub\n", __func__); return event->finger_count; } @@ -962,6 +1025,7 @@ libinput_event_gesture_get_cancelled(struct libinput_event_gesture *event) LIBINPUT_EVENT_GESTURE_SWIPE_END, LIBINPUT_EVENT_GESTURE_HOLD_END); + fprintf(stderr, "%s: partial stub\n", __func__); return event->cancelled; } @@ -978,6 +1042,7 @@ libinput_event_gesture_get_dx(struct libinput_event_gesture *event) LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, LIBINPUT_EVENT_GESTURE_SWIPE_END); + fprintf(stderr, "%s: partial stub\n", __func__); return event->delta.x; } @@ -994,6 +1059,7 @@ libinput_event_gesture_get_dy(struct libinput_event_gesture *event) LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, LIBINPUT_EVENT_GESTURE_SWIPE_END); + fprintf(stderr, "%s: partial stub\n", __func__); return event->delta.y; } @@ -1011,6 +1077,7 @@ libinput_event_gesture_get_dx_unaccelerated( LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, LIBINPUT_EVENT_GESTURE_SWIPE_END); + fprintf(stderr, "%s: partial stub\n", __func__); return event->delta_unaccel.x; } @@ -1028,6 +1095,7 @@ libinput_event_gesture_get_dy_unaccelerated( LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, LIBINPUT_EVENT_GESTURE_SWIPE_END); + fprintf(stderr, "%s: partial stub\n", __func__); return event->delta_unaccel.y; } @@ -1041,6 +1109,7 @@ libinput_event_gesture_get_scale(struct libinput_event_gesture *event) LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, LIBINPUT_EVENT_GESTURE_PINCH_END); + fprintf(stderr, "%s: partial stub\n", __func__); return event->scale; } @@ -1054,6 +1123,7 @@ libinput_event_gesture_get_angle_delta(struct libinput_event_gesture *event) LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, LIBINPUT_EVENT_GESTURE_PINCH_END); + fprintf(stderr, "%s: partial stub\n", __func__); return event->angle; } @@ -3247,7 +3317,24 @@ LIBINPUT_EXPORT int libinput_device_has_capability(struct libinput_device *device, enum libinput_device_capability capability) { - return 0xdeadbeef; // TODO + int rc = 0; + + switch (capability) { + case LIBINPUT_DEVICE_CAP_POINTER: + if (strncmp(device->devname, "/dev/wsmouse", 12) == 0) + rc = 1; + break; + case LIBINPUT_DEVICE_CAP_KEYBOARD: + if (strncmp(device->devname, "/dev/wskbd", 10) == 0) + rc = 1; + break; + case LIBINPUT_DEVICE_CAP_TOUCH: + case LIBINPUT_DEVICE_CAP_GESTURE: + default: + break; + } + + return rc; } LIBINPUT_EXPORT int @@ -3255,69 +3342,80 @@ libinput_device_get_size(struct libinput_device *device, double *width, double *height) { - return 0xdeadbeef; // TODO + fprintf(stderr, "%s: stub\n", __func__); + return (-1); } LIBINPUT_EXPORT int libinput_device_pointer_has_button(struct libinput_device *device, uint32_t code) { - return 0xdeadbeef; // TODO + fprintf(stderr, "%s: stub\n", __func__); + return (-1); } LIBINPUT_EXPORT int libinput_device_keyboard_has_key(struct libinput_device *device, uint32_t code) { - return 0xdeadbeef; // TODO + fprintf(stderr, "%s: stub\n", __func__); + return (-1); } LIBINPUT_EXPORT int libinput_device_touch_get_touch_count(struct libinput_device *device) { - return 0xdeadbeef; // TODO + fprintf(stderr, "%s: stub\n", __func__); + return (-1); } LIBINPUT_EXPORT int libinput_device_switch_has_switch(struct libinput_device *device, enum libinput_switch sw) { - return 0xdeadbeef; // TODO + fprintf(stderr, "%s: stub\n", __func__); + return (-1); } LIBINPUT_EXPORT int libinput_device_tablet_pad_has_key(struct libinput_device *device, uint32_t code) { - return 0xdeadbeef; // TODO + fprintf(stderr, "%s: stub\n", __func__); + return (-1); } LIBINPUT_EXPORT int libinput_device_tablet_pad_get_num_buttons(struct libinput_device *device) { - return 0xdeadbeef; // TODO + fprintf(stderr, "%s: stub\n", __func__); + return (-1); } LIBINPUT_EXPORT int libinput_device_tablet_pad_get_num_rings(struct libinput_device *device) { - return 0xdeadbeef; // TODO + fprintf(stderr, "%s: stub\n", __func__); + return (-1); } LIBINPUT_EXPORT int libinput_device_tablet_pad_get_num_strips(struct libinput_device *device) { - return 0xdeadbeef; // TODO + fprintf(stderr, "%s: stub\n", __func__); + return (-1); } LIBINPUT_EXPORT int libinput_device_tablet_pad_get_num_mode_groups(struct libinput_device *device) { - return 0xdeadbeef; // TODO + fprintf(stderr, "%s: stub\n", __func__); + return (-1); } LIBINPUT_EXPORT struct libinput_tablet_pad_mode_group* libinput_device_tablet_pad_get_mode_group(struct libinput_device *device, unsigned int index) { - return NULL; // TODO + fprintf(stderr, "%s: stub\n", __func__); + return 0xdeadbeef; } LIBINPUT_EXPORT unsigned int From 7ef612d71d01e0e04003cc0dcf6ce714f9a52ada Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Wed, 8 Nov 2023 18:09:03 +0100 Subject: [PATCH 18/41] Fix the mouse button mapping for wsmouse libinput has the mouse buttons in order: left, right, middle while wsmouse hase left, middle, right. While here replace the comment before that code that doesn't make sense anymore. --- src/wscons.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/wscons.c b/src/wscons.c index 521a0f49..0d820f9d 100644 --- a/src/wscons.c +++ b/src/wscons.c @@ -103,12 +103,18 @@ wscons_process(struct libinput_device *device, struct wscons_event *wsevent) case WSCONS_EVENT_MOUSE_UP: case WSCONS_EVENT_MOUSE_DOWN: - /* - * Do not return wscons(4) values directly because - * the left button value being 0 it will be - * interpreted as an error. - */ - button = wsevent->value + BTN_LEFT; + /* button to Linux events */ + switch (wsevent->value) { + case 1: + button = BTN_MIDDLE; + break; + case 2: + button = BTN_RIGHT; + break; + default: + button = wsevent->value + BTN_LEFT; + break; + } if (wsevent->type == WSCONS_EVENT_MOUSE_UP) bstate = LIBINPUT_BUTTON_STATE_RELEASED; else From 1369aa24408ff762b517262dd097a26b5072d9b0 Mon Sep 17 00:00:00 2001 From: Rafael Sadowski Date: Wed, 15 Nov 2023 17:45:25 +0100 Subject: [PATCH 19/41] Fix compile --- src/libinput_openbsd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libinput_openbsd.c b/src/libinput_openbsd.c index 73458e7f..4cea37a3 100644 --- a/src/libinput_openbsd.c +++ b/src/libinput_openbsd.c @@ -3415,7 +3415,7 @@ libinput_device_tablet_pad_get_mode_group(struct libinput_device *device, unsigned int index) { fprintf(stderr, "%s: stub\n", __func__); - return 0xdeadbeef; + return NULL; } LIBINPUT_EXPORT unsigned int From f5930e9ffb42354a8c1c13cc8274043ce7f84b31 Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Fri, 22 Dec 2023 17:35:10 +0100 Subject: [PATCH 20/41] Add support for USB keyboards --- src/libinput_openbsd.c | 3 +- src/wscons.c | 25 ++-- src/wscons.h | 23 ++++ src/wskbdmap.c | 257 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 294 insertions(+), 14 deletions(-) create mode 100644 src/wscons.h diff --git a/src/libinput_openbsd.c b/src/libinput_openbsd.c index 4cea37a3..6ea3981f 100644 --- a/src/libinput_openbsd.c +++ b/src/libinput_openbsd.c @@ -36,10 +36,11 @@ #include "libinput.h" #include "libinput-private.h" -#include "evdev.h" #include "timer.h" #include "quirks.h" +#include "wscons.h" + #define require_event_type(li_, type_, retval_, ...) \ if (type_ == LIBINPUT_EVENT_NONE) abort(); \ if (!check_event_type(li_, __func__, type_, __VA_ARGS__, -1)) \ diff --git a/src/wscons.c b/src/wscons.c index 0d820f9d..ad465cbc 100644 --- a/src/wscons.c +++ b/src/wscons.c @@ -21,15 +21,16 @@ * DEALINGS IN THE SOFTWARE. */ +#include #include #include #include #include #include -#include #include "libinput.h" +#include "wscons.h" #include "input-event-codes.h" #include "libinput-util.h" #include "libinput-private.h" @@ -37,8 +38,6 @@ static const char default_seat[] = "seat0"; static const char default_seat_name[] = "default"; -extern uint32_t wskey_transcode(int); - static int old_value = -1; static int @@ -98,7 +97,7 @@ wscons_process(struct libinput_device *device, struct wscons_event *wsevent) old_value = key; } keyboard_notify_key(device, time, - wskey_transcode(key), kstate); + wskey_transcode(wscons_device(device)->wskbd_type, key), kstate); break; case WSCONS_EVENT_MOUSE_UP: @@ -296,8 +295,10 @@ libinput_path_add_device(struct libinput *libinput, const char *path) { struct libinput_seat *seat = NULL; - struct libinput_device *device; + struct libinput_device *device = NULL; + struct wscons_device *wscons_device; int fd; + int type = -1; fd = open_restricted(libinput, path, O_RDWR | O_NONBLOCK | O_CLOEXEC); @@ -308,15 +309,22 @@ libinput_path_add_device(struct libinput *libinput, return NULL; } - device = calloc(1, sizeof(*device)); - if (device == NULL) + if (ioctl(fd, WSKBDIO_GTYPE, &type) == -1) { + log_error(libinput, "getting WSKBD type: %s.\n", + strerror(errno)); + } + + wscons_device = calloc(1, sizeof(*wscons_device)); + if (wscons_device == NULL) return NULL; + wscons_device->wskbd_type = type; /* Only one (default) seat is supported. */ seat = wscons_seat_get(libinput, default_seat, default_seat_name); if (seat == NULL) goto err; + device = &wscons_device->base; libinput_device_init(device, seat); device->fd = fd; @@ -334,7 +342,8 @@ libinput_path_add_device(struct libinput *libinput, return device; err: - close_restricted(libinput, device->fd); + if (device != NULL) + close_restricted(libinput, device->fd); free(device); return NULL; } diff --git a/src/wscons.h b/src/wscons.h new file mode 100644 index 00000000..e78ca6a9 --- /dev/null +++ b/src/wscons.h @@ -0,0 +1,23 @@ +#ifndef _LIBINPUT_WSCONS_H +#define _LIBINPUT_WSCONS_H + +#include + +#include "libinput-private.h" + +struct wscons_device { + struct libinput_device base; + int wskbd_type; +}; + +static inline struct wscons_device * +wscons_device(struct libinput_device *device) +{ + return container_of(device, struct wscons_device, base); +} + +extern uint32_t wskey_transcode(int, int); +extern void post_device_event(struct libinput_device *, uint64_t , + enum libinput_event_type , struct libinput_event *); + +#endif diff --git a/src/wskbdmap.c b/src/wskbdmap.c index b88b8917..00f61890 100644 --- a/src/wskbdmap.c +++ b/src/wskbdmap.c @@ -1,7 +1,244 @@ #include - +#include +#include "wscons.h" #include "input-event-codes.h" +static uint32_t wsUsbMap[] = { + /* 0 */ KEY_RESERVED, + /* 1 */ KEY_RESERVED, + /* 2 */ KEY_RESERVED, + /* 3 */ KEY_RESERVED, + /* 4 */ KEY_A, + /* 5 */ KEY_B, + /* 6 */ KEY_C, + /* 7 */ KEY_D, + /* 8 */ KEY_E, + /* 9 */ KEY_F, + /* 10 */ KEY_G, + /* 11 */ KEY_H, + /* 12 */ KEY_I, + /* 13 */ KEY_J, + /* 14 */ KEY_K, + /* 15 */ KEY_L, + /* 16 */ KEY_M, + /* 17 */ KEY_N, + /* 18 */ KEY_O, + /* 19 */ KEY_P, + /* 20 */ KEY_Q, + /* 21 */ KEY_R, + /* 22 */ KEY_S, + /* 23 */ KEY_T, + /* 24 */ KEY_U, + /* 25 */ KEY_V, + /* 26 */ KEY_W, + /* 27 */ KEY_X, + /* 28 */ KEY_Y, + /* 29 */ KEY_Z, + /* 30 */ KEY_1, /* 1 !*/ + /* 31 */ KEY_2, /* 2 @ */ + /* 32 */ KEY_3, /* 3 # */ + /* 33 */ KEY_4, /* 4 $ */ + /* 34 */ KEY_5, /* 5 % */ + /* 35 */ KEY_6, /* 6 ^ */ + /* 36 */ KEY_7, /* 7 & */ + /* 37 */ KEY_8, /* 8 * */ + /* 38 */ KEY_9, /* 9 ( */ + /* 39 */ KEY_0, /* 0 ) */ + /* 40 */ KEY_ENTER, /* Return */ + /* 41 */ KEY_ESC, /* Escape */ + /* 42 */ KEY_BACKSPACE, /* Backspace Delete */ + /* 43 */ KEY_TAB, /* Tab */ + /* 44 */ KEY_SPACE, /* Space */ + /* 45 */ KEY_MINUS, /* - _ */ + /* 46 */ KEY_EQUAL, /* = + */ + /* 47 */ KEY_LEFTBRACE, /* [ { */ + /* 48 */ KEY_RIGHTBRACE, /* ] } */ + /* 49 */ KEY_BACKSLASH, /* \ | */ + /* 50 */ KEY_BACKSLASH, /* \ _ # ~ on some keyboards */ + /* 51 */ KEY_SEMICOLON, /* ; : */ + /* 52 */ KEY_APOSTROPHE, /* ' " */ + /* 53 */ KEY_GRAVE, /* ` ~ */ + /* 54 */ KEY_COMMA, /* , < */ + /* 55 */ KEY_DOT, /* . > */ + /* 56 */ KEY_SLASH, /* / ? */ + /* 57 */ KEY_CAPSLOCK, /* Caps Lock */ + /* 58 */ KEY_F1, /* F1 */ + /* 59 */ KEY_F2, /* F2 */ + /* 60 */ KEY_F3, /* F3 */ + /* 61 */ KEY_F4, /* F4 */ + /* 62 */ KEY_F5, /* F5 */ + /* 63 */ KEY_F6, /* F6 */ + /* 64 */ KEY_F7, /* F7 */ + /* 65 */ KEY_F8, /* F8 */ + /* 66 */ KEY_F9, /* F9 */ + /* 67 */ KEY_F10, /* F10 */ + /* 68 */ KEY_F11, /* F11 */ + /* 69 */ KEY_F12, /* F12 */ + /* 70 */ KEY_PRINT, /* PrintScrn SysReq */ + /* 71 */ KEY_SCROLLLOCK, /* Scroll Lock */ + /* 72 */ KEY_PAUSE, /* Pause Break */ + /* 73 */ KEY_INSERT, /* Insert XXX Help on some Mac Keyboards */ + /* 74 */ KEY_HOME, /* Home */ + /* 75 */ KEY_PAGEUP, /* Page Up */ + /* 76 */ KEY_DELETE, /* Delete */ + /* 77 */ KEY_END, /* End */ + /* 78 */ KEY_PAGEDOWN, /* Page Down */ + /* 79 */ KEY_RIGHT, /* Right Arrow */ + /* 80 */ KEY_LEFT, /* Left Arrow */ + /* 81 */ KEY_DOWN, /* Down Arrow */ + /* 82 */ KEY_UP, /* Up Arrow */ + /* 83 */ KEY_NUMLOCK, /* Num Lock */ + /* 84 */ KEY_KPSLASH, /* Keypad / */ + /* 85 */ KEY_KPASTERISK, /* Keypad * */ + /* 86 */ KEY_KPMINUS, /* Keypad - */ + /* 87 */ KEY_KPPLUS, /* Keypad + */ + /* 88 */ KEY_KPENTER, /* Keypad Enter */ + /* 89 */ KEY_KP1, /* Keypad 1 End */ + /* 90 */ KEY_KP2, /* Keypad 2 Down */ + /* 91 */ KEY_KP3, /* Keypad 3 Pg Down */ + /* 92 */ KEY_KP4, /* Keypad 4 Left */ + /* 93 */ KEY_KP5, /* Keypad 5 */ + /* 94 */ KEY_KP6, /* Keypad 6 */ + /* 95 */ KEY_KP7, /* Keypad 7 Home */ + /* 96 */ KEY_KP8, /* Keypad 8 Up */ + /* 97 */ KEY_KP9, /* KEypad 9 Pg Up */ + /* 98 */ KEY_KP0, /* Keypad 0 Ins */ + /* 99 */ KEY_KPDOT, /* Keypad . Del */ + /* 100 */ KEY_102ND, /* < > on some keyboards */ + /* 101 */ KEY_MENU, /* Menu */ + /* 102 */ KEY_POWER, /* sleep key on Sun USB */ + /* 103 */ KEY_KPEQUAL, /* Keypad = on Mac keyboards */ + /* 104 */ KEY_F13, + /* 105 */ KEY_F14, + /* 106 */ KEY_F15, + /* 107 */ KEY_F16, + /* 108 */ KEY_RESERVED, + /* 109 */ KEY_POWER, + /* 110 */ KEY_RESERVED, + /* 111 */ KEY_RESERVED, + /* 112 */ KEY_RESERVED, + /* 113 */ KEY_RESERVED, + /* 114 */ KEY_RESERVED, + /* 115 */ KEY_RESERVED, + /* 116 */ KEY_OPEN, /* L7 */ + /* 117 */ KEY_HELP, + /* 118 */ KEY_PROPS, /* L3 */ + /* 119 */ KEY_FRONT, /* L5 */ + /* 120 */ KEY_STOP, /* L1 */ + /* 121 */ KEY_AGAIN, /* L2 */ + /* 122 */ KEY_UNDO, /* L4 */ + /* 123 */ KEY_CUT, /* L10 */ + /* 124 */ KEY_COPY, /* L6 */ + /* 125 */ KEY_PASTE, /* L8 */ + /* 126 */ KEY_FIND, /* L9 */ + /* 127 */ KEY_MUTE, + /* 128 */ KEY_VOLUMEUP, + /* 129 */ KEY_VOLUMEDOWN, + /* 130 */ KEY_RESERVED, + /* 131 */ KEY_RESERVED, + /* 132 */ KEY_RESERVED, + /* 133 */ KEY_RESERVED, + /* 134 */ KEY_RESERVED, + /* 135 */ KEY_RESERVED, /* Japanese 106 kbd: '\_' */ + /* 136 */ KEY_RESERVED, /* Japanese 106 kbd: Hiragana Katakana toggle */ + /* 137 */ KEY_YEN, /* Japanese 106 kbd: '\|' */ + /* 138 */ KEY_RESERVED, /* Japanese 106 kbd: Henkan */ + /* 139 */ KEY_RESERVED, /* Japanese 106 kbd: Muhenkan */ + /* 140 */ KEY_RESERVED, + /* 141 */ KEY_RESERVED, + /* 142 */ KEY_RESERVED, + /* 143 */ KEY_RESERVED, + /* 144 */ KEY_RESERVED, /* Korean 106 kbd: Hangul */ + /* 145 */ KEY_RESERVED, /* Korean 106 kbd: Hangul Hanja */ + /* 146 */ KEY_RESERVED, + /* 147 */ KEY_RESERVED, + /* 148 */ KEY_RESERVED, + /* 149 */ KEY_RESERVED, + /* 150 */ KEY_RESERVED, + /* 151 */ KEY_RESERVED, + /* 152 */ KEY_RESERVED, + /* 153 */ KEY_RESERVED, + /* 154 */ KEY_RESERVED, + /* 155 */ KEY_RESERVED, + /* 156 */ KEY_RESERVED, + /* 157 */ KEY_RESERVED, + /* 158 */ KEY_RESERVED, + /* 159 */ KEY_RESERVED, + /* 160 */ KEY_RESERVED, + /* 161 */ KEY_RESERVED, + /* 162 */ KEY_RESERVED, + /* 163 */ KEY_RESERVED, + /* 164 */ KEY_RESERVED, + /* 165 */ KEY_RESERVED, + /* 166 */ KEY_RESERVED, + /* 167 */ KEY_RESERVED, + /* 168 */ KEY_RESERVED, + /* 169 */ KEY_RESERVED, + /* 170 */ KEY_RESERVED, + /* 171 */ KEY_RESERVED, + /* 172 */ KEY_RESERVED, + /* 173 */ KEY_RESERVED, + /* 174 */ KEY_RESERVED, + /* 175 */ KEY_RESERVED, + /* 176 */ KEY_RESERVED, + /* 177 */ KEY_RESERVED, + /* 178 */ KEY_RESERVED, + /* 179 */ KEY_RESERVED, + /* 180 */ KEY_RESERVED, + /* 181 */ KEY_RESERVED, + /* 182 */ KEY_RESERVED, + /* 183 */ KEY_RESERVED, + /* 184 */ KEY_RESERVED, + /* 185 */ KEY_RESERVED, + /* 186 */ KEY_RESERVED, + /* 187 */ KEY_RESERVED, + /* 188 */ KEY_RESERVED, + /* 189 */ KEY_RESERVED, + /* 190 */ KEY_RESERVED, + /* 191 */ KEY_RESERVED, + /* 192 */ KEY_RESERVED, + /* 193 */ KEY_RESERVED, + /* 194 */ KEY_RESERVED, + /* 195 */ KEY_RESERVED, + /* 196 */ KEY_RESERVED, + /* 197 */ KEY_RESERVED, + /* 198 */ KEY_RESERVED, + /* 199 */ KEY_RESERVED, + /* 200 */ KEY_RESERVED, + /* 201 */ KEY_RESERVED, + /* 202 */ KEY_RESERVED, + /* 203 */ KEY_RESERVED, + /* 204 */ KEY_RESERVED, + /* 205 */ KEY_RESERVED, + /* 206 */ KEY_RESERVED, + /* 207 */ KEY_RESERVED, + /* 208 */ KEY_RESERVED, + /* 209 */ KEY_RESERVED, + /* 210 */ KEY_RESERVED, + /* 211 */ KEY_RESERVED, + /* 212 */ KEY_RESERVED, + /* 213 */ KEY_RESERVED, + /* 214 */ KEY_RESERVED, + /* 215 */ KEY_RESERVED, + /* 216 */ KEY_RESERVED, + /* 217 */ KEY_RESERVED, + /* 218 */ KEY_RESERVED, + /* 219 */ KEY_RESERVED, + /* 220 */ KEY_RESERVED, + /* 221 */ KEY_RESERVED, + /* 222 */ KEY_RESERVED, + /* 223 */ KEY_RESERVED, + /* 224 */ KEY_LEFTCTRL, /* Left Control */ + /* 225 */ KEY_LEFTSHIFT, /* Left Shift */ + /* 226 */ KEY_LEFTALT, /* Left Alt */ + /* 227 */ KEY_LEFTMETA, /* Left Meta */ + /* 228 */ KEY_RIGHTCTRL, /* Right Control */ + /* 229 */ KEY_RIGHTSHIFT, /* Right Shift */ + /* 230 */ KEY_RIGHTALT, /* Right Alt, AKA AltGr */ + /* 231 */ KEY_RIGHTMETA, /* Right Meta */ +}; +#define WS_USB_MAP_SIZE (sizeof(wsUsbMap)/sizeof(*wsUsbMap)) + static uint32_t wsXtMap[] = { /* 0 */ KEY_RESERVED, /* 1 */ KEY_ESC, @@ -246,9 +483,19 @@ static uint32_t wsXtMap[] = { #define WS_XT_MAP_SIZE (sizeof(wsXtMap)/sizeof(*wsXtMap)) uint32_t -wskey_transcode(int wskey) +wskey_transcode(int wskbd_type, int wskey) { - if (wskey < 0 || wskey >= WS_XT_MAP_SIZE) - return KEY_UNKNOWN; - return wsXtMap[wskey]; + switch (wskbd_type) { + case WSKBD_TYPE_PC_XT: + case WSKBD_TYPE_PC_AT: + if (wskey < 0 || wskey >= (int)WS_XT_MAP_SIZE) + return KEY_UNKNOWN; + return wsXtMap[wskey]; + case WSKBD_TYPE_USB: + if (wskey < 0 || wskey >= (int)WS_USB_MAP_SIZE) + return KEY_UNKNOWN; + return wsUsbMap[wskey]; + default: + return KEY_RESERVED; + } } From b12c5d296f0ee8070f6289f9703948a65791c2a2 Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Fri, 22 Dec 2023 17:35:25 +0100 Subject: [PATCH 21/41] OpenBSD lacks strtod_l(3) but defaults to C locale semantics anyways --- src/util-strings.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/util-strings.h b/src/util-strings.h index b0916815..3606ce0f 100644 --- a/src/util-strings.h +++ b/src/util-strings.h @@ -242,7 +242,11 @@ safe_atod(const char *str, double *val) return false; errno = 0; +#ifndef __OpenBSD__ v = strtod_l(str, &endptr, c_locale); +#else + v = strtod(str, &endptr); +#endif freelocale(c_locale); #else /* No locale support in provided libc, assume it already uses '.' */ From 41446a3d0c60d5d9df3aec930ea3dbcc2aeaba5d Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Sat, 23 Dec 2023 12:32:50 +0100 Subject: [PATCH 22/41] white space fixes --- src/libinput_openbsd.c | 6 +++--- src/wscons.c | 8 ++++---- src/wskbdmap.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/libinput_openbsd.c b/src/libinput_openbsd.c index 6ea3981f..23ab4397 100644 --- a/src/libinput_openbsd.c +++ b/src/libinput_openbsd.c @@ -725,7 +725,7 @@ LIBINPUT_EXPORT double libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event, enum libinput_pointer_axis axis) { - // XXX differnt + // XXX differnt struct libinput *libinput = event->base.device->seat->libinput; double value = 0; @@ -754,7 +754,7 @@ LIBINPUT_EXPORT double libinput_event_pointer_get_axis_value_discrete(struct libinput_event_pointer *event, enum libinput_pointer_axis axis) { - // XXX differnt + // XXX differnt struct libinput *libinput = event->base.device->seat->libinput; double value = 0; @@ -1848,7 +1848,7 @@ void libinput_init_quirks(struct libinput *libinput) { const char *data_path, - *override_file = NULL; + *override_file = NULL; struct quirks_context *quirks; if (libinput->quirks_initialized) diff --git a/src/wscons.c b/src/wscons.c index ad465cbc..f9b824fa 100644 --- a/src/wscons.c +++ b/src/wscons.c @@ -37,7 +37,7 @@ static const char default_seat[] = "seat0"; static const char default_seat_name[] = "default"; - + static int old_value = -1; static int @@ -97,7 +97,7 @@ wscons_process(struct libinput_device *device, struct wscons_event *wsevent) old_value = key; } keyboard_notify_key(device, time, - wskey_transcode(wscons_device(device)->wskbd_type, key), kstate); + wskey_transcode(wscons_device(device)->scanCodeMap, key), kstate); break; case WSCONS_EVENT_MOUSE_UP: @@ -158,7 +158,7 @@ wscons_process(struct libinput_device *device, struct wscons_event *wsevent) accel.y = wsevent->value/8; axis_notify_event(device, time, &accel, &raw); break; - + case WSCONS_EVENT_SYNC: break; @@ -188,7 +188,7 @@ wscons_device_dispatch(void *data) return; count = len / sizeof(struct wscons_event); - for (i = 0; i < count; i++) { + for (i = 0; i < count; i++) { wscons_process(device, &wsevents[i]); } } diff --git a/src/wskbdmap.c b/src/wskbdmap.c index 00f61890..51226aee 100644 --- a/src/wskbdmap.c +++ b/src/wskbdmap.c @@ -8,7 +8,7 @@ static uint32_t wsUsbMap[] = { /* 1 */ KEY_RESERVED, /* 2 */ KEY_RESERVED, /* 3 */ KEY_RESERVED, - /* 4 */ KEY_A, + /* 4 */ KEY_A, /* 5 */ KEY_B, /* 6 */ KEY_C, /* 7 */ KEY_D, @@ -325,7 +325,7 @@ static uint32_t wsXtMap[] = { /* 82 */ KEY_KP0, /* 83 */ KEY_KPDOT, /* 84 */ KEY_RESERVED, - + /* 85 */ KEY_ZENKAKUHANKAKU, /* 86 */ KEY_102ND, /* backslash on uk, < on german */ /* 87 */ KEY_F11, From 60f16ee774ba9f24b376ba1502059c4698842f97 Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Sat, 23 Dec 2023 12:34:23 +0100 Subject: [PATCH 23/41] remove some debugging printf()s --- src/wscons.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/wscons.c b/src/wscons.c index f9b824fa..a5423fc5 100644 --- a/src/wscons.c +++ b/src/wscons.c @@ -206,7 +206,6 @@ wscons_seat_get(struct libinput *libinput, const char *seat_name_physical, { struct libinput_seat *seat; - fprintf(stderr, "%s: %d\n", __func__, __LINE__); list_for_each(seat, &libinput->seat_list, link) { if (streq(seat->physical_name, seat_name_physical) && streq(seat->logical_name, seat_name_logical)) { @@ -232,7 +231,6 @@ libinput_udev_create_context(const struct libinput_interface *interface, { struct libinput *libinput; - fprintf(stderr, "%s: %d\n", __func__, __LINE__); libinput = calloc(1, sizeof(*libinput)); if (libinput == NULL) return NULL; @@ -254,15 +252,12 @@ libinput_udev_assign_seat(struct libinput *libinput, const char *seat_id) struct timespec ts; struct libinput_event *event; - fprintf(stderr, "%s: %d\n", __func__, __LINE__); - /* Add standard muxes */ libinput_path_add_device(libinput, "/dev/wskbd"); libinput_path_add_device(libinput, "/dev/wsmouse"); seat = wscons_seat_get(libinput, default_seat, default_seat_name); list_for_each(device, &seat->devices_list, link) { - fprintf(stderr, " %s\n", device->devname); clock_gettime(CLOCK_REALTIME, &ts); time = s2us(ts.tv_sec) + ns2us(ts.tv_nsec); event = calloc(1, sizeof(*event)); From ba8406afbc815993b01c00c52f5e9eadb43db8e3 Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Sat, 23 Dec 2023 12:34:53 +0100 Subject: [PATCH 24/41] Better wscons device initialization and keyboard mapping handling. - store the device capability (pointer/keyboard) in the wscons_device struct - use a pointer to the keyboard mapping table like in the X keyboard driver This should also make adding more advanced pointer support easier --- src/libinput_openbsd.c | 19 +----------- src/wscons.c | 28 ++++++++++++------ src/wscons.h | 17 +++++++++-- src/wskbdmap.c | 66 +++++++++++++++++++++++++++++++++++------- 4 files changed, 90 insertions(+), 40 deletions(-) diff --git a/src/libinput_openbsd.c b/src/libinput_openbsd.c index 23ab4397..dc76ca3d 100644 --- a/src/libinput_openbsd.c +++ b/src/libinput_openbsd.c @@ -3318,24 +3318,7 @@ LIBINPUT_EXPORT int libinput_device_has_capability(struct libinput_device *device, enum libinput_device_capability capability) { - int rc = 0; - - switch (capability) { - case LIBINPUT_DEVICE_CAP_POINTER: - if (strncmp(device->devname, "/dev/wsmouse", 12) == 0) - rc = 1; - break; - case LIBINPUT_DEVICE_CAP_KEYBOARD: - if (strncmp(device->devname, "/dev/wskbd", 10) == 0) - rc = 1; - break; - case LIBINPUT_DEVICE_CAP_TOUCH: - case LIBINPUT_DEVICE_CAP_GESTURE: - default: - break; - } - - return rc; + return (wscons_device(device)->capability == capability); } LIBINPUT_EXPORT int diff --git a/src/wscons.c b/src/wscons.c index a5423fc5..28c1cd33 100644 --- a/src/wscons.c +++ b/src/wscons.c @@ -21,7 +21,6 @@ * DEALINGS IN THE SOFTWARE. */ -#include #include #include #include @@ -285,6 +284,22 @@ libinput_path_create_context(const struct libinput_interface *interface, return libinput; } +static int +wscons_device_init(struct wscons_device *wscons_device) +{ + struct libinput_device *device = &wscons_device->base; + + if (strncmp(device->devname, "/dev/wsmouse", 12) == 0) { + /* XXX handle tablets and touchpanel */ + wscons_device->capability = LIBINPUT_DEVICE_CAP_POINTER; + } else if (strncmp(device->devname, "/dev/wskbd", 10) == 0) { + wscons_device->capability = LIBINPUT_DEVICE_CAP_KEYBOARD; + if (wscons_keyboard_init(wscons_device) == -1) + return -1; + } + return 0; +} + LIBINPUT_EXPORT struct libinput_device * libinput_path_add_device(struct libinput *libinput, const char *path) @@ -293,7 +308,6 @@ libinput_path_add_device(struct libinput *libinput, struct libinput_device *device = NULL; struct wscons_device *wscons_device; int fd; - int type = -1; fd = open_restricted(libinput, path, O_RDWR | O_NONBLOCK | O_CLOEXEC); @@ -304,15 +318,9 @@ libinput_path_add_device(struct libinput *libinput, return NULL; } - if (ioctl(fd, WSKBDIO_GTYPE, &type) == -1) { - log_error(libinput, "getting WSKBD type: %s.\n", - strerror(errno)); - } - wscons_device = calloc(1, sizeof(*wscons_device)); if (wscons_device == NULL) return NULL; - wscons_device->wskbd_type = type; /* Only one (default) seat is supported. */ seat = wscons_seat_get(libinput, default_seat, default_seat_name); @@ -332,6 +340,8 @@ libinput_path_add_device(struct libinput *libinput, if (!device->source) goto err; + if (wscons_device_init(wscons_device) == -1) + goto err; list_insert(&seat->devices_list, &device->link); return device; @@ -339,7 +349,7 @@ libinput_path_add_device(struct libinput *libinput, err: if (device != NULL) close_restricted(libinput, device->fd); - free(device); + free(wscons_device); return NULL; } diff --git a/src/wscons.h b/src/wscons.h index e78ca6a9..244dfd97 100644 --- a/src/wscons.h +++ b/src/wscons.h @@ -5,18 +5,29 @@ #include "libinput-private.h" +#define WSCONS_TYPE_POINTER 1 +#define WSCONS_TYPE_KEYBOARD 2 + +struct TransMapRec { + int begin; + int end; + uint32_t *map; +}; + struct wscons_device { struct libinput_device base; - int wskbd_type; + enum libinput_device_capability capability; + struct TransMapRec *scanCodeMap; }; + static inline struct wscons_device * wscons_device(struct libinput_device *device) { return container_of(device, struct wscons_device, base); } - -extern uint32_t wskey_transcode(int, int); +extern int wscons_keyboard_init(struct wscons_device *); +extern uint32_t wskey_transcode(struct TransMapRec *, int); extern void post_device_event(struct libinput_device *, uint64_t , enum libinput_event_type , struct libinput_event *); diff --git a/src/wskbdmap.c b/src/wskbdmap.c index 51226aee..3756a5b0 100644 --- a/src/wskbdmap.c +++ b/src/wskbdmap.c @@ -1,3 +1,4 @@ +#include #include #include #include "wscons.h" @@ -238,6 +239,12 @@ static uint32_t wsUsbMap[] = { /* 231 */ KEY_RIGHTMETA, /* Right Meta */ }; #define WS_USB_MAP_SIZE (sizeof(wsUsbMap)/sizeof(*wsUsbMap)) +static +struct TransMapRec wsUsb = { + 0, + WS_USB_MAP_SIZE, + wsUsbMap +}; static uint32_t wsXtMap[] = { /* 0 */ KEY_RESERVED, @@ -482,20 +489,59 @@ static uint32_t wsXtMap[] = { }; #define WS_XT_MAP_SIZE (sizeof(wsXtMap)/sizeof(*wsXtMap)) -uint32_t -wskey_transcode(int wskbd_type, int wskey) +static +struct TransMapRec wsXt = { + 0, + WS_XT_MAP_SIZE, + wsXtMap +}; + +static void +printWsType(struct libinput *libinput, const char *name, const char *type) +{ + log_error(libinput, "%s: Keyboard type: %s\n", name, type); +} + +int +wscons_keyboard_init(struct wscons_device *device) { - switch (wskbd_type) { + struct libinput_device *libinput_device = &device->base; + struct libinput *libinput = libinput_device->seat->libinput; + int fd = libinput_device->fd; + int type; + + if (ioctl(fd, WSKBDIO_GTYPE, &type) == -1) { + log_error(libinput, "getting WSKBD type: %s.\n", + strerror(errno)); + return -1; + } + switch (type) { case WSKBD_TYPE_PC_XT: + printWsType(libinput, libinput_device->devname, "XT"); + device->scanCodeMap = &wsXt; + break; case WSKBD_TYPE_PC_AT: - if (wskey < 0 || wskey >= (int)WS_XT_MAP_SIZE) - return KEY_UNKNOWN; - return wsXtMap[wskey]; + printWsType(libinput, libinput_device->devname, "AT"); + device->scanCodeMap = &wsXt; + break; case WSKBD_TYPE_USB: - if (wskey < 0 || wskey >= (int)WS_USB_MAP_SIZE) - return KEY_UNKNOWN; - return wsUsbMap[wskey]; + printWsType(libinput, libinput_device->devname, "USB"); + device->scanCodeMap = &wsUsb; + break; default: - return KEY_RESERVED; + log_error(libinput, "Unsupported wskbd type %d\n", type); + device->scanCodeMap = NULL; + break; } + return 0; +} + +uint32_t +wskey_transcode(struct TransMapRec *map, int wskey) +{ + if (map == NULL) + return KEY_UNKNOWN; + if (wskey < map->begin || wskey >= map->end) + return KEY_UNKNOWN; + return map->map[wskey]; } From dbf066362fa0c1b49cd25c51b9531125a224269d Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Sat, 13 Jul 2024 16:53:36 +0200 Subject: [PATCH 25/41] Provide the actual device names to libinput --- src/libinput_openbsd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libinput_openbsd.c b/src/libinput_openbsd.c index dc76ca3d..491a7894 100644 --- a/src/libinput_openbsd.c +++ b/src/libinput_openbsd.c @@ -3255,13 +3255,13 @@ libinput_device_get_device_group(struct libinput_device *device) LIBINPUT_EXPORT const char * libinput_device_get_sysname(struct libinput_device *device) { - return "unsupported"; + return device->devname; } LIBINPUT_EXPORT const char * libinput_device_get_name(struct libinput_device *device) { - return "unsupported"; + return device->devname; } LIBINPUT_EXPORT unsigned int From 4e305ac3dcc07f3e39cfc30b7c041bf6900b7812 Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Sat, 13 Jul 2024 16:56:17 +0200 Subject: [PATCH 26/41] Implement device enable/disable. This makes VT switches possible with seatd which properly calls back thoses functions to release/acquire the devices when switching from/to the VT runnning a compositor. --- src/wscons.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/wscons.c b/src/wscons.c index 28c1cd33..175a6ee3 100644 --- a/src/wscons.c +++ b/src/wscons.c @@ -37,17 +37,45 @@ static const char default_seat[] = "seat0"; static const char default_seat_name[] = "default"; +static struct libinput_seat* wscons_seat_get(struct libinput *, const char *, + const char *); +static void wscons_device_dispatch(void *); + static int old_value = -1; static int udev_input_enable(struct libinput *libinput) { + struct libinput_seat *seat; + struct libinput_device *device; + + seat = wscons_seat_get(libinput, default_seat, default_seat_name); + list_for_each(device, &seat->devices_list, link) { + device->fd = open_restricted(libinput, device->devname, O_RDWR); + device->source = + libinput_add_fd(libinput, device->fd, + wscons_device_dispatch, device); + if (!device->source) { + return -ENOMEM; + } + } return 0; } static void udev_input_disable(struct libinput *libinput) { + struct libinput_seat *seat; + struct libinput_device *device; + + seat = wscons_seat_get(libinput, default_seat, default_seat_name); + list_for_each(device, &seat->devices_list, link) { + if (device->source) { + libinput_remove_source(libinput, device->source); + device->source = NULL; + } + close_restricted(libinput, device->fd); + } } static void From 3f0bb879b0c276de6459cbdf820713c2c49ee99a Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Sun, 14 Jul 2024 12:14:46 +0200 Subject: [PATCH 27/41] Return 0 as vendor and device id Currently this information is not available from wsconsx --- src/libinput_openbsd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libinput_openbsd.c b/src/libinput_openbsd.c index 491a7894..08be1cd1 100644 --- a/src/libinput_openbsd.c +++ b/src/libinput_openbsd.c @@ -3267,13 +3267,13 @@ libinput_device_get_name(struct libinput_device *device) LIBINPUT_EXPORT unsigned int libinput_device_get_id_product(struct libinput_device *device) { - return 0xdeadbeef; // TODO + return 0; // TODO } LIBINPUT_EXPORT unsigned int libinput_device_get_id_vendor(struct libinput_device *device) { - return 0xdeadbeef; // TODO + return 0; // TODO } LIBINPUT_EXPORT const char * From 7e4471ce25bf1d22147ec3e776d54f3d0a367e1b Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Sun, 14 Jul 2024 12:16:21 +0200 Subject: [PATCH 28/41] Skip "/dev/" from the device name. --- src/libinput_openbsd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libinput_openbsd.c b/src/libinput_openbsd.c index 08be1cd1..69cbd3e9 100644 --- a/src/libinput_openbsd.c +++ b/src/libinput_openbsd.c @@ -3261,7 +3261,10 @@ libinput_device_get_sysname(struct libinput_device *device) LIBINPUT_EXPORT const char * libinput_device_get_name(struct libinput_device *device) { - return device->devname; + if (strncmp(device->devname, "/dev/", 5) == 0) + return device->devname + 5; /* skip /dev/ */ + else + return device->devname; /* XXX */ } LIBINPUT_EXPORT unsigned int From 9e017da35e81c6619dd64afba94c24e827cfe5d9 Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Sun, 14 Jul 2024 12:22:17 +0200 Subject: [PATCH 29/41] Add individual input devices, not the mux. This allows to have diffent kinds of keyboard (USB, PS/2) layouts active at the same time. Currently when using the mux it's not possible to get the layout applying to a given event. --- src/wscons.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/wscons.c b/src/wscons.c index 175a6ee3..32417367 100644 --- a/src/wscons.c +++ b/src/wscons.c @@ -27,7 +27,6 @@ #include #include - #include "libinput.h" #include "wscons.h" #include "input-event-codes.h" @@ -279,9 +278,21 @@ libinput_udev_assign_seat(struct libinput *libinput, const char *seat_id) struct timespec ts; struct libinput_event *event; - /* Add standard muxes */ - libinput_path_add_device(libinput, "/dev/wskbd"); - libinput_path_add_device(libinput, "/dev/wsmouse"); + /* Add standard devices */ + for (int i = 0; i < 10; i++) { + char name[32]; + int fd; + snprintf(name, sizeof(name), "/dev/wskbd%d", i); + if ((fd = open_restricted(libinput, name, O_RDWR|O_NONBLOCK)) >= 0) { + close(fd); + libinput_path_add_device(libinput, name); + } + snprintf(name, sizeof(name), "/dev/wsmouse%d", i); + if ((fd = open_restricted(libinput, name, O_RDWR|O_NONBLOCK)) >= 0) { + close(fd); + libinput_path_add_device(libinput, name); + } + } seat = wscons_seat_get(libinput, default_seat, default_seat_name); list_for_each(device, &seat->devices_list, link) { From 2fd417ec6972694160c8e980d61d9f7222e1c10b Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Sun, 14 Jul 2024 12:24:30 +0200 Subject: [PATCH 30/41] Downgrade the display of keyboard type to level 'info' --- src/wskbdmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wskbdmap.c b/src/wskbdmap.c index 3756a5b0..d030ab6d 100644 --- a/src/wskbdmap.c +++ b/src/wskbdmap.c @@ -499,7 +499,7 @@ struct TransMapRec wsXt = { static void printWsType(struct libinput *libinput, const char *name, const char *type) { - log_error(libinput, "%s: Keyboard type: %s\n", name, type); + log_info(libinput, "%s: Keyboard type: %s\n", name, type); } int From c296ac6b80e3ecf928fc1b0468f18d1871f158a1 Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Sun, 14 Jul 2024 12:26:09 +0200 Subject: [PATCH 31/41] Try to clean up on exit --- src/libinput_openbsd.c | 4 ++-- src/wscons.c | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/libinput_openbsd.c b/src/libinput_openbsd.c index 69cbd3e9..a6ce5611 100644 --- a/src/libinput_openbsd.c +++ b/src/libinput_openbsd.c @@ -2125,8 +2125,8 @@ static void libinput_device_destroy(struct libinput_device *device) { // TODO - //assert(list_empty(&device->event_listeners)); - //evdev_device_destroy(evdev_device(device)); + assert(list_empty(&device->event_listeners)); + //wscons_device_destroy(evdev_device(device)); } LIBINPUT_EXPORT struct libinput_device * diff --git a/src/wscons.c b/src/wscons.c index 32417367..50bf68e0 100644 --- a/src/wscons.c +++ b/src/wscons.c @@ -80,6 +80,14 @@ udev_input_disable(struct libinput *libinput) static void udev_input_destroy(struct libinput *libinput) { + struct libinput_seat *seat; + struct libinput_device *device; + + fprintf(stderr, "%s", __func__); + seat = wscons_seat_get(libinput, default_seat, default_seat_name); + list_for_each(device, &seat->devices_list, link) { + close_restricted(libinput, device->fd); + } } static int From 1fcdd91f71263417a62d1adff59ca36ddc7c83c5 Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Sun, 14 Jul 2024 12:32:56 +0200 Subject: [PATCH 32/41] use close_restricted() to close fd opened by open_restricted(). This fixes running with seatd() --- src/wscons.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wscons.c b/src/wscons.c index 50bf68e0..117faa96 100644 --- a/src/wscons.c +++ b/src/wscons.c @@ -292,12 +292,12 @@ libinput_udev_assign_seat(struct libinput *libinput, const char *seat_id) int fd; snprintf(name, sizeof(name), "/dev/wskbd%d", i); if ((fd = open_restricted(libinput, name, O_RDWR|O_NONBLOCK)) >= 0) { - close(fd); + close_restricted(libinput, fd); libinput_path_add_device(libinput, name); } snprintf(name, sizeof(name), "/dev/wsmouse%d", i); if ((fd = open_restricted(libinput, name, O_RDWR|O_NONBLOCK)) >= 0) { - close(fd); + close_restricted(libinput, fd); libinput_path_add_device(libinput, name); } } From 8f0587590a0ab03d36da9a52480ec5a9b347f925 Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Mon, 4 Nov 2024 20:21:11 +0100 Subject: [PATCH 33/41] merge 1.26.2 --- src/libinput_openbsd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libinput_openbsd.c b/src/libinput_openbsd.c index a6ce5611..f77c6ecf 100644 --- a/src/libinput_openbsd.c +++ b/src/libinput_openbsd.c @@ -105,6 +105,7 @@ event_type_to_str(enum libinput_event_type type) CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_RING); CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_STRIP); CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_KEY); + CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_DIAL); CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN); CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE); CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_SWIPE_END); From 03349b6cdbd7048f1665694ecea7284934594e1a Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Tue, 5 Nov 2024 10:13:24 +0100 Subject: [PATCH 34/41] openbsd : touchpad: add clickfinger button map --- src/libinput_openbsd.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/libinput_openbsd.c b/src/libinput_openbsd.c index f77c6ecf..ae20cc3a 100644 --- a/src/libinput_openbsd.c +++ b/src/libinput_openbsd.c @@ -73,6 +73,7 @@ ASSERT_INT_SIZE(enum libinput_config_drag_lock_state); ASSERT_INT_SIZE(enum libinput_config_send_events_mode); ASSERT_INT_SIZE(enum libinput_config_accel_profile); ASSERT_INT_SIZE(enum libinput_config_click_method); +ASSERT_INT_SIZE(enum libinput_config_clickfinger_button_map); ASSERT_INT_SIZE(enum libinput_config_middle_emulation_state); ASSERT_INT_SIZE(enum libinput_config_scroll_method); ASSERT_INT_SIZE(enum libinput_config_dwt_state); @@ -4429,6 +4430,45 @@ libinput_device_config_click_get_default_method(struct libinput_device *device) return LIBINPUT_CONFIG_CLICK_METHOD_NONE; } +LIBINPUT_EXPORT enum libinput_config_status +libinput_device_config_click_set_clickfinger_button_map(struct libinput_device *device, + enum libinput_config_clickfinger_button_map map) +{ + switch (map) { + case LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM: + case LIBINPUT_CONFIG_CLICKFINGER_MAP_LMR: + break; + default: + return LIBINPUT_CONFIG_STATUS_INVALID; + } + + if ((libinput_device_config_click_get_methods(device) & + LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER) != LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER) + return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; + + return device->config.click_method->set_clickfinger_map(device, map); +} + +LIBINPUT_EXPORT enum libinput_config_clickfinger_button_map +libinput_device_config_click_get_clickfinger_button_map(struct libinput_device *device) +{ + if ((libinput_device_config_click_get_methods(device) & + LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER) != LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER) + return LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM; + + return device->config.click_method->get_clickfinger_map(device); +} + +LIBINPUT_EXPORT enum libinput_config_clickfinger_button_map +libinput_device_config_click_get_default_clickfinger_button_map(struct libinput_device *device) +{ + if ((libinput_device_config_click_get_methods(device) & + LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER) != LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER) + return LIBINPUT_CONFIG_CLICKFINGER_MAP_LRM; + + return device->config.click_method->get_default_clickfinger_map(device); +} + LIBINPUT_EXPORT int libinput_device_config_middle_emulation_is_available( struct libinput_device *device) From c695dd1ff0d73378ae69feba5675cfb729cad9ef Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Sun, 18 Aug 2024 15:14:47 +0200 Subject: [PATCH 35/41] remove unused file --- src/udev-seat_openbsd.c | 155 ---------------------------------------- 1 file changed, 155 deletions(-) delete mode 100644 src/udev-seat_openbsd.c diff --git a/src/udev-seat_openbsd.c b/src/udev-seat_openbsd.c deleted file mode 100644 index b571ad1a..00000000 --- a/src/udev-seat_openbsd.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright © 2013 Intel Corporation - * Copyright © 2013-2015 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "config.h" - -#include -#include -#include - -#ifndef __OpenBSD__ -#include "evdev.h" -#endif -#include "udev-seat.h" - -static const char default_seat[] = "seat0"; -static const char default_seat_name[] = "default"; - -static struct udev_seat * -udev_seat_create(struct udev_input *input, - const char *device_seat, - const char *seat_name); -static struct udev_seat * -udev_seat_get_named(struct udev_input *input, const char *seat_name); - - -static inline bool -filter_duplicates(struct udev_seat *udev_seat, - struct udev_device *udev_device) -{ - bool ignore_device = false; - return ignore_device; // TODO -} - -static int -device_added(struct udev_device *udev_device, - struct udev_input *input, - const char *seat_name) -{ - return 0; // TODO -} - -static void -device_removed(struct udev_device *udev_device, struct udev_input *input) -{ - // TODO -} - -static int -udev_input_add_devices(struct udev_input *input, struct udev *udev) -{ - return 0; // TODO -} - -static void -evdev_udev_handler(void *data) -{ - // TODO -} - -static void -udev_input_remove_devices(struct udev_input *input) -{ - // TODO -} - -static void -udev_input_disable(struct libinput *libinput) -{ - // TODO -} - -static int -udev_input_enable(struct libinput *libinput) -{ - return 0; // TODO -} - -static void -udev_input_destroy(struct libinput *input) -{ - // TODO -} - -static void -udev_seat_destroy(struct libinput_seat *seat) -{ - struct udev_seat *useat = (struct udev_seat*)seat; - free(useat); -} - -static struct udev_seat * -udev_seat_create(struct udev_input *input, - const char *device_seat, - const char *seat_name) -{ - return NULL; // TODO -} - -static struct udev_seat * -udev_seat_get_named(struct udev_input *input, const char *seat_name) -{ - return NULL; // TODO -} - -static int -udev_device_change_seat(struct libinput_device *device, - const char *seat_name) -{ - return 0xdeadbeef; // TODO -} - -static const struct libinput_interface_backend interface_backend = { - .resume = udev_input_enable, - .suspend = udev_input_disable, - .destroy = udev_input_destroy, - .device_change_seat = udev_device_change_seat, -}; - -/* udev-seat_openbsd.c:141:1: error: conflicting types for 'libinput_udev_create_context -LIBINPUT_EXPORT struct libinput * -libinput_udev_create_context(const struct libinput_interface *interface, - void *user_data, - struct udev *udev) -{ - return NULL; // TODO -} -*/ - -LIBINPUT_EXPORT int -libinput_udev_assign_seat(struct libinput *libinput, - const char *seat_id) -{ - return 0; // TODO -} From 65eb6c2b9635d4fac97aba7a30606d95e1bb51bc Mon Sep 17 00:00:00 2001 From: Volker Schlecht <47375452+VlkrS@users.noreply.github.com> Date: Fri, 1 Aug 2025 11:11:26 +0200 Subject: [PATCH 36/41] port pointer acceleration logic from evdev.c to wscons.c and hook it up --- src/wscons.c | 180 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/wscons.h | 4 ++ 2 files changed, 182 insertions(+), 2 deletions(-) diff --git a/src/wscons.c b/src/wscons.c index 117faa96..1e03bb5e 100644 --- a/src/wscons.c +++ b/src/wscons.c @@ -28,6 +28,7 @@ #include #include "libinput.h" +#include "filter.h" #include "wscons.h" #include "input-event-codes.h" #include "libinput-util.h" @@ -40,6 +41,10 @@ static struct libinput_seat* wscons_seat_get(struct libinput *, const char *, const char *); static void wscons_device_dispatch(void *); +static void +wscons_device_init_pointer_acceleration(struct wscons_device *device, + struct motion_filter *filter); + static int old_value = -1; static int @@ -111,6 +116,7 @@ wscons_process(struct libinput_device *device, struct wscons_event *wsevent) enum libinput_key_state kstate; struct normalized_coords accel; struct device_float_coords raw; + struct wscons_device *dev = wscons_device(device); uint64_t time; int button, key; @@ -161,9 +167,19 @@ wscons_process(struct libinput_device *device, struct wscons_event *wsevent) memset(&accel, 0, sizeof(accel)); if (wsevent->type == WSCONS_EVENT_MOUSE_DELTA_X) - accel.x = wsevent->value; + raw.x = wsevent->value; else - accel.y = -wsevent->value; + raw.y = -wsevent->value; + + if (dev->pointer.filter) { + accel = filter_dispatch(dev->pointer.filter, + &raw, + device, + time); + } else { + accel.x = raw.x; + accel.y = raw.y; + } pointer_notify_motion(device, time, &accel, &raw); break; @@ -331,6 +347,165 @@ libinput_path_create_context(const struct libinput_interface *interface, return libinput; } +static double +wscons_accel_config_get_speed(struct libinput_device *device) +{ + struct wscons_device *dev = wscons_device(device); + + return filter_get_speed(dev->pointer.filter); +} + +static enum libinput_config_status +wscons_accel_config_set_speed(struct libinput_device *device, double speed) +{ + struct wscons_device *dev = wscons_device(device); + + if (!filter_set_speed(dev->pointer.filter, speed)) + return LIBINPUT_CONFIG_STATUS_INVALID; + + return LIBINPUT_CONFIG_STATUS_SUCCESS; +} + +static double +wscons_accel_config_get_default_speed(struct libinput_device *device) +{ + return 0.0; +} + +static int +wscons_accel_config_available(struct libinput_device *device) +{ + /* this function is only called if we set up ptraccel, so we can + reply with a resounding "Yes" */ + return 1; +} + +static enum libinput_config_accel_profile +wscons_accel_config_get_profile(struct libinput_device *libinput_device) +{ + struct wscons_device *device = wscons_device(libinput_device); + + return filter_get_type(device->pointer.filter); +} + +static inline bool +wscons_init_accel(struct wscons_device *device, + enum libinput_config_accel_profile which) +{ + struct motion_filter *filter = NULL; + + if (which == LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM) { + filter = create_custom_accelerator_filter(); + } else { + if (which == LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT) + filter = create_pointer_accelerator_filter_flat(DEFAULT_MOUSE_DPI); + else + filter = create_pointer_accelerator_filter_linear_low_dpi(DEFAULT_MOUSE_DPI, + true); + } + + if (!filter) + filter = create_pointer_accelerator_filter_linear(DEFAULT_MOUSE_DPI, + true); + + if (!filter) + return false; + + wscons_device_init_pointer_acceleration(device, filter); + + return true; +} + +static enum libinput_config_status +wscons_accel_config_set_profile(struct libinput_device *libinput_device, + enum libinput_config_accel_profile profile) +{ + struct wscons_device *device = wscons_device(libinput_device); + struct motion_filter *filter; + double speed; + + filter = device->pointer.filter; + if (filter_get_type(filter) == profile) + return LIBINPUT_CONFIG_STATUS_SUCCESS; + + speed = filter_get_speed(filter); + device->pointer.filter = NULL; + + if (wscons_init_accel(device, profile)) { + wscons_accel_config_set_speed(libinput_device, speed); + filter_destroy(filter); + } else { + device->pointer.filter = filter; + return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; + } + + return LIBINPUT_CONFIG_STATUS_SUCCESS; +} + +static uint32_t +wscons_accel_config_get_profiles(struct libinput_device *libinput_device) +{ + struct wscons_device *device = wscons_device(libinput_device); + + if (!device->pointer.filter) + return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE; + + return LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE | + LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT | + LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM; +} + +static enum libinput_config_accel_profile +wscons_accel_config_get_default_profile(struct libinput_device *libinput_device) +{ + struct wscons_device *device = wscons_device(libinput_device); + + if (!device->pointer.filter) + return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE; + + /* No device has a flat profile as default */ + return LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE; +} + +static enum libinput_config_status +wscons_set_accel_config(struct libinput_device *libinput_device, + struct libinput_config_accel *accel_config) +{ + assert(wscons_accel_config_get_profile(libinput_device) == accel_config->profile); + + struct wscons_device *dev = wscons_device(libinput_device); + + if (!filter_set_accel_config(dev->pointer.filter, accel_config)) + return LIBINPUT_CONFIG_STATUS_INVALID; + + return LIBINPUT_CONFIG_STATUS_SUCCESS; +} + +static void +wscons_device_init_pointer_acceleration(struct wscons_device *device, + struct motion_filter *filter) +{ + device->pointer.filter = filter; + + if (device->base.config.accel == NULL) { + double default_speed; + + device->pointer.config.available = wscons_accel_config_available; + device->pointer.config.set_speed = wscons_accel_config_set_speed; + device->pointer.config.get_speed = wscons_accel_config_get_speed; + device->pointer.config.get_default_speed = wscons_accel_config_get_default_speed; + device->pointer.config.get_profiles = wscons_accel_config_get_profiles; + device->pointer.config.set_profile = wscons_accel_config_set_profile; + device->pointer.config.get_profile = wscons_accel_config_get_profile; + device->pointer.config.get_default_profile = wscons_accel_config_get_default_profile; + device->pointer.config.set_accel_config = wscons_set_accel_config; + device->base.config.accel = &device->pointer.config; + + default_speed = wscons_accel_config_get_default_speed(&device->base); + wscons_accel_config_set_speed(&device->base, default_speed); + } +} + static int wscons_device_init(struct wscons_device *wscons_device) { @@ -339,6 +514,7 @@ wscons_device_init(struct wscons_device *wscons_device) if (strncmp(device->devname, "/dev/wsmouse", 12) == 0) { /* XXX handle tablets and touchpanel */ wscons_device->capability = LIBINPUT_DEVICE_CAP_POINTER; + wscons_init_accel(wscons_device, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE); } else if (strncmp(device->devname, "/dev/wskbd", 10) == 0) { wscons_device->capability = LIBINPUT_DEVICE_CAP_KEYBOARD; if (wscons_keyboard_init(wscons_device) == -1) diff --git a/src/wscons.h b/src/wscons.h index 244dfd97..636e7487 100644 --- a/src/wscons.h +++ b/src/wscons.h @@ -18,6 +18,10 @@ struct wscons_device { struct libinput_device base; enum libinput_device_capability capability; struct TransMapRec *scanCodeMap; + struct { + struct libinput_device_config_accel config; + struct motion_filter *filter; + } pointer; }; From cf9699e76e41bf1b824c3820d06d36a2b0fbb8c1 Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Sun, 17 Aug 2025 17:49:37 +0200 Subject: [PATCH 37/41] Remove extra file not part of libinput. On OpenBSD it's provided by the wayland/libevdev-openbsd port --- include/libevdev/libevdev.h | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 include/libevdev/libevdev.h diff --git a/include/libevdev/libevdev.h b/include/libevdev/libevdev.h deleted file mode 100644 index 35c5b704..00000000 --- a/include/libevdev/libevdev.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright © 2013 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - */ - -#ifndef LIBEVDEV_H -#define LIBEVDEV_H - -#include - -extern int libevdev_event_code_from_name(unsigned int type, const char *name); -extern const char * libevdev_event_code_get_name(unsigned int type, unsigned int code); -#endif From f12f63e5a2c589a353d23b318bbbc7bb407c6f21 Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Fri, 19 Sep 2025 15:55:11 +0200 Subject: [PATCH 38/41] Revert "Remove extra file not part of libinput." This reverts commit cf9699e76e41bf1b824c3820d06d36a2b0fbb8c1. This causes a circular dependencies problem. A better solution is needed. --- include/libevdev/libevdev.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 include/libevdev/libevdev.h diff --git a/include/libevdev/libevdev.h b/include/libevdev/libevdev.h new file mode 100644 index 00000000..35c5b704 --- /dev/null +++ b/include/libevdev/libevdev.h @@ -0,0 +1,32 @@ +/* + * Copyright © 2013 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +#ifndef LIBEVDEV_H +#define LIBEVDEV_H + +#include + +extern int libevdev_event_code_from_name(unsigned int type, const char *name); +extern const char * libevdev_event_code_get_name(unsigned int type, unsigned int code); +#endif From b637f07d1a01dacac1484d9a11da2e2bd703d9d9 Mon Sep 17 00:00:00 2001 From: kikadf Date: Sun, 7 Sep 2025 21:41:33 +0200 Subject: [PATCH 39/41] Build on NetBSD --- include/linux/input-event-codes.h | 2 ++ include/linux/input.h | 2 ++ meson.build | 22 +++++++++++----------- src/libinput-private.h | 2 +- src/libinput-util.h | 2 +- src/util-strings.h | 2 +- 6 files changed, 18 insertions(+), 14 deletions(-) diff --git a/include/linux/input-event-codes.h b/include/linux/input-event-codes.h index dda123e2..187e53a2 100644 --- a/include/linux/input-event-codes.h +++ b/include/linux/input-event-codes.h @@ -2,6 +2,8 @@ #include "linux/input-event-codes.h" #elif __OpenBSD__ #include "freebsd/input-event-codes.h" +#elif __NetBSD__ +#include "freebsd/input-event-codes.h" #elif __FreeBSD__ #include "freebsd/input-event-codes.h" #endif diff --git a/include/linux/input.h b/include/linux/input.h index 827c8390..49a17cf4 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -2,6 +2,8 @@ #include "linux/input.h" #elif __OpenBSD__ #include "freebsd/input.h" +#elif __NetBSD__ +#include "freebsd/input.h" #elif __FreeBSD__ #include "freebsd/input.h" #endif diff --git a/meson.build b/meson.build index 56a81947..5cb09bba 100644 --- a/meson.build +++ b/meson.build @@ -143,7 +143,7 @@ config_h.set10('HAVE_INSTALLED_TESTS', get_option('install-tests')) # Dependencies pkgconfig = import('pkgconfig') -if host_machine.system() == 'openbsd' +if host_machine.system() == 'openbsd' or host_machine.system() == 'netbsd' dep_udev = dependency('libudev') dep_mtdev = [] dep_libevdev = [] @@ -164,7 +164,7 @@ includes_src = include_directories('src') ############ libwacom configuration ############ -if host_machine.system() == 'openbsd' +if host_machine.system() == 'openbsd' or host_machine.system() == 'netbsd' have_libwacom = false else have_libwacom = get_option('libwacom') @@ -177,7 +177,7 @@ else endif ############ udev bits ############ -if host_machine.system() != 'openbsd' +if host_machine.system() != 'openbsd' and host_machine.system() != 'netbsd' executable('libinput-device-group', 'udev/libinput-device-group.c', dependencies : [dep_udev, dep_libwacom], @@ -314,7 +314,7 @@ src_libfilter = [ 'src/filter-trackpoint.c', 'src/filter-trackpoint-flat.c', ] -if host_machine.system() == 'openbsd' +if host_machine.system() == 'openbsd' or host_machine.system() == 'netbsd' dep_libfilter = [] else libfilter = static_library('filter', src_libfilter, @@ -345,7 +345,7 @@ libquirks = static_library('quirks', src_libquirks, dep_libquirks = declare_dependency(link_with : libquirks) # Create /etc/libinput -if host_machine.system() != 'openbsd' +if host_machine.system() != 'openbsd' and host_machine.system() != 'netbsd' if meson.version().version_compare('>= 0.60') install_emptydir(dir_etc / 'libinput') else @@ -355,7 +355,7 @@ endif ############ libinput.so ############ install_headers('src/libinput.h') -if host_machine.system() == 'openbsd' +if host_machine.system() == 'openbsd' or host_machine.system() == 'netbsd' src_libinput = src_libfilter + [ 'src/libinput_openbsd.c', 'src/libinput-private-config.c', @@ -426,7 +426,7 @@ lib_libinput = shared_library('input', link_depends : mapfile, install : true ) -if host_machine.system() == 'openbsd' +if host_machine.system() == 'openbsd' or host_machine.system() == 'netbsd' install_headers('include/linux/freebsd/input-event-codes.h', subdir: 'linux/freebsd') install_headers('include/linux/freebsd/input.h', subdir: 'linux/freebsd') @@ -470,7 +470,7 @@ endif subdir('completion/zsh') ############ tools ############ -if host_machine.system() != 'openbsd' +if host_machine.system() != 'openbsd' and host_machine.system() != 'netbsd' libinput_tool_path = dir_libexec config_h.set_quoted('LIBINPUT_TOOL_PATH', libinput_tool_path) @@ -717,7 +717,7 @@ test('tools-builddir-lookup-installed', endif ############ tests ############ -if host_machine.system() != 'openbsd' +if host_machine.system() != 'openbsd' and host_machine.system() != 'netbsd' test('symbols-leak-test', find_program('test/symbols-leak-test'), @@ -771,7 +771,7 @@ if get_option('tests') config_h.set10('HAVE_GSTACK', gstack.found()) # for inhibit support during test run -if host_machine.system() != 'openbsd' +if host_machine.system() != 'openbsd' and host_machine.system() != 'netbsd' dep_libsystemd = dependency('libsystemd', version : '>= 221', required : false) config_h.set10('HAVE_LIBSYSTEMD', dep_libsystemd.found()) endif @@ -883,7 +883,7 @@ endif 'test/litest.c', ] -if host_machine.system() != 'openbsd' +if host_machine.system() != 'openbsd' and host_machine.system() != 'netbsd' dep_dl = cc.find_library('dl') deps_litest = [ dep_libinput, diff --git a/src/libinput-private.h b/src/libinput-private.h index d6b32d27..dab68f2e 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -1015,7 +1015,7 @@ static inline void libinput_libwacom_unref(struct libinput *li) {} #endif -#ifdef __OpenBSD__ +#if defined(__OpenBSD__) || defined(__NetBSD__) void axis_notify_event(struct libinput_device *device, uint64_t time, diff --git a/src/libinput-util.h b/src/libinput-util.h index 8f271f03..a04052dc 100644 --- a/src/libinput-util.h +++ b/src/libinput-util.h @@ -66,7 +66,7 @@ #define LIBINPUT_EXPORT __attribute__ ((visibility("default"))) #define LIBINPUT_UNUSED __attribute__ ((unused)) -#ifdef __OpenBSD__ +#if defined(__OpenBSD__) || defined(__NetBSD__) #define bit(x_) (1UL << (x_)) #define NBITS(b) (b * 8) #endif diff --git a/src/util-strings.h b/src/util-strings.h index 3606ce0f..184080c6 100644 --- a/src/util-strings.h +++ b/src/util-strings.h @@ -242,7 +242,7 @@ safe_atod(const char *str, double *val) return false; errno = 0; -#ifndef __OpenBSD__ +#if !defined(__OpenBSD__) && !defined(__NetBSD__) v = strtod_l(str, &endptr, c_locale); #else v = strtod(str, &endptr); From 15d0a0892b64bdac78c90d486a106e34ffa4eca7 Mon Sep 17 00:00:00 2001 From: kikadf Date: Tue, 9 Sep 2025 17:07:14 +0200 Subject: [PATCH 40/41] Fix build on NetBSD --- include/linux/input-event-codes.h | 6 +----- include/linux/input.h | 6 +----- meson.build | 2 +- src/wscons.c | 4 ++++ 4 files changed, 7 insertions(+), 11 deletions(-) diff --git a/include/linux/input-event-codes.h b/include/linux/input-event-codes.h index 187e53a2..680d8123 100644 --- a/include/linux/input-event-codes.h +++ b/include/linux/input-event-codes.h @@ -1,9 +1,5 @@ #ifdef __linux__ #include "linux/input-event-codes.h" -#elif __OpenBSD__ -#include "freebsd/input-event-codes.h" -#elif __NetBSD__ -#include "freebsd/input-event-codes.h" -#elif __FreeBSD__ +#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) #include "freebsd/input-event-codes.h" #endif diff --git a/include/linux/input.h b/include/linux/input.h index 49a17cf4..2b091d5d 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -1,9 +1,5 @@ #ifdef __linux__ #include "linux/input.h" -#elif __OpenBSD__ -#include "freebsd/input.h" -#elif __NetBSD__ -#include "freebsd/input.h" -#elif __FreeBSD__ +#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) #include "freebsd/input.h" #endif diff --git a/meson.build b/meson.build index 5cb09bba..4458c3a8 100644 --- a/meson.build +++ b/meson.build @@ -426,7 +426,7 @@ lib_libinput = shared_library('input', link_depends : mapfile, install : true ) -if host_machine.system() == 'openbsd' or host_machine.system() == 'netbsd' +if host_machine.system() == 'openbsd' install_headers('include/linux/freebsd/input-event-codes.h', subdir: 'linux/freebsd') install_headers('include/linux/freebsd/input.h', subdir: 'linux/freebsd') diff --git a/src/wscons.c b/src/wscons.c index 1e03bb5e..2dbea2ce 100644 --- a/src/wscons.c +++ b/src/wscons.c @@ -209,13 +209,17 @@ wscons_process(struct libinput_device *device, struct wscons_event *wsevent) axis_notify_event(device, time, &accel, &raw); break; +#ifndef __NetBSD__ case WSCONS_EVENT_SYNC: break; +#endif case WSCONS_EVENT_MOUSE_ABSOLUTE_Z: case WSCONS_EVENT_MOUSE_ABSOLUTE_W: +#ifndef __NetBSD__ case WSCONS_EVENT_TOUCH_WIDTH: case WSCONS_EVENT_TOUCH_RESET: +#endif /* ignore those */ break; default: From 5e93d5c82d455c3901c2cb9b40dbbe5358a88e30 Mon Sep 17 00:00:00 2001 From: kikadf Date: Fri, 19 Sep 2025 16:23:14 +0200 Subject: [PATCH 41/41] Use portable wsevent>type checks instead of OS-specific macros --- src/wscons.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/wscons.c b/src/wscons.c index 2dbea2ce..2120f073 100644 --- a/src/wscons.c +++ b/src/wscons.c @@ -209,15 +209,17 @@ wscons_process(struct libinput_device *device, struct wscons_event *wsevent) axis_notify_event(device, time, &accel, &raw); break; -#ifndef __NetBSD__ +#ifdef WSCONS_EVENT_SYNC case WSCONS_EVENT_SYNC: break; #endif case WSCONS_EVENT_MOUSE_ABSOLUTE_Z: case WSCONS_EVENT_MOUSE_ABSOLUTE_W: -#ifndef __NetBSD__ +#ifdef WSCONS_EVENT_TOUCH_WIDTH case WSCONS_EVENT_TOUCH_WIDTH: +#endif +#ifdef WSCONS_EVENT_TOUCH_RESET case WSCONS_EVENT_TOUCH_RESET: #endif /* ignore those */