diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index ffb4b08cf520..df4cd4a680a4 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -48,6 +48,7 @@ target_sources_ifdef(CONFIG_ZMK_EXT_POWER app PRIVATE src/behaviors/behavior_ext if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_ROLE_CENTRAL) target_sources(app PRIVATE src/hid.c) target_sources_ifdef(CONFIG_ZMK_MOUSE app PRIVATE src/mouse/main.c) + target_sources_ifdef(CONFIG_ZMK_MOUSE app PRIVATE src/mouse/hid_input_listener.c) target_sources(app PRIVATE src/behaviors/behavior_key_press.c) target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_KEY_TOGGLE app PRIVATE src/behaviors/behavior_key_toggle.c) target_sources(app PRIVATE src/behaviors/behavior_hold_tap.c) @@ -66,7 +67,7 @@ if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_ROLE_CENTRAL) target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_SENSOR_ROTATE_VAR app PRIVATE src/behaviors/behavior_sensor_rotate_var.c) target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_SENSOR_ROTATE_COMMON app PRIVATE src/behaviors/behavior_sensor_rotate_common.c) target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_MOUSE_KEY_PRESS app PRIVATE src/behaviors/behavior_mouse_key_press.c) - target_sources_ifdef(CONFIG_ZMK_MOUSE app PRIVATE src/behaviors/behavior_mouse_move.c) + target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_MOUSE_MOVE app PRIVATE src/behaviors/behavior_mouse_move.c) target_sources_ifdef(CONFIG_ZMK_MOUSE app PRIVATE src/behaviors/behavior_mouse_scroll.c) target_sources(app PRIVATE src/combo.c) target_sources(app PRIVATE src/behaviors/behavior_tap_dance.c) diff --git a/app/Kconfig.behaviors b/app/Kconfig.behaviors index 11bc8c5900f1..ebd24c1c7dab 100644 --- a/app/Kconfig.behaviors +++ b/app/Kconfig.behaviors @@ -12,6 +12,12 @@ config ZMK_BEHAVIOR_MOUSE_KEY_PRESS depends on DT_HAS_ZMK_BEHAVIOR_MOUSE_KEY_PRESS_ENABLED imply ZMK_MOUSE +config ZMK_BEHAVIOR_MOUSE_MOVE + bool + default y + depends on DT_HAS_ZMK_BEHAVIOR_MOUSE_MOVE_ENABLED + imply ZMK_MOUSE + config ZMK_BEHAVIOR_SENSOR_ROTATE_COMMON bool default n diff --git a/app/src/behaviors/behavior_mouse_key_press.c b/app/src/behaviors/behavior_mouse_key_press.c index 6718155768cd..d0a5f2a6144a 100644 --- a/app/src/behaviors/behavior_mouse_key_press.c +++ b/app/src/behaviors/behavior_mouse_key_press.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); @@ -20,19 +22,30 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); static int behavior_mouse_key_press_init(const struct device *dev) { return 0; }; +static void process_key_state(const struct device *dev, int32_t val, bool pressed) { + for (int i = 0; i < ZMK_HID_MOUSE_NUM_BUTTONS; i++) { + if (val & BIT(i)) { + WRITE_BIT(val, i, 0); + input_report_key(dev, INPUT_BTN_0 + i, pressed ? 1 : 0, val == 0, K_FOREVER); + } + } +} static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event) { LOG_DBG("position %d keycode 0x%02X", event.position, binding->param1); - return ZMK_EVENT_RAISE( - zmk_mouse_button_state_changed_from_encoded(binding->param1, true, event.timestamp)); + process_key_state(device_get_binding(binding->behavior_dev), binding->param1, true); + + return 0; } static int on_keymap_binding_released(struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event) { LOG_DBG("position %d keycode 0x%02X", event.position, binding->param1); - return ZMK_EVENT_RAISE( - zmk_mouse_button_state_changed_from_encoded(binding->param1, false, event.timestamp)); + + process_key_state(device_get_binding(binding->behavior_dev), binding->param1, false); + + return 0; } static const struct behavior_driver_api behavior_mouse_key_press_driver_api = { diff --git a/app/src/mouse/Kconfig b/app/src/mouse/Kconfig index 9c40c51f5b96..8eb64f4cc847 100644 --- a/app/src/mouse/Kconfig +++ b/app/src/mouse/Kconfig @@ -4,6 +4,8 @@ config ZMK_MOUSE bool "Enable ZMK mouse emulation" default n + select INPUT + select INPUT_THREAD_PRIORITY_OVERRIDE config ZMK_MOUSE_TICK_DURATION int "Mouse tick duration in ms" diff --git a/app/src/mouse/hid_input_listener.c b/app/src/mouse/hid_input_listener.c new file mode 100644 index 000000000000..aca917b017e6 --- /dev/null +++ b/app/src/mouse/hid_input_listener.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include + +#include +#include +#include + +void handle_rel_code(struct input_event *evt) { + switch (evt->code) { + case INPUT_REL_X: + zmk_hid_mouse_movement_update(evt->value, 0); + break; + case INPUT_REL_Y: + zmk_hid_mouse_movement_update(0, evt->value); + break; + case INPUT_REL_WHEEL: + zmk_hid_mouse_scroll_update(0, evt->value); + break; + case INPUT_REL_HWHEEL: + zmk_hid_mouse_scroll_update(evt->value, 0); + break; + default: + break; + } +} + +void handle_key_code(struct input_event *evt) { + + switch (evt->code) { + case INPUT_BTN_0: + case INPUT_BTN_1: + case INPUT_BTN_2: + case INPUT_BTN_3: + case INPUT_BTN_4: + int8_t btn = evt->code - INPUT_BTN_0; + if (evt->value > 0) { + zmk_hid_mouse_button_press(btn); + } else { + zmk_hid_mouse_button_release(btn); + } + break; + default: + break; + } +} + +void input_handler(struct input_event *evt) { + switch (evt->type) { + case INPUT_EV_REL: + handle_rel_code(evt); + break; + case INPUT_EV_KEY: + handle_key_code(evt); + } + + if (evt->sync) { + zmk_endpoints_send_mouse_report(); + } +} + +INPUT_CALLBACK_DEFINE(NULL, input_handler); diff --git a/app/src/mouse/key_listener.c b/app/src/mouse/key_listener.c index bd06efebd9f5..093bcf8e4575 100644 --- a/app/src/mouse/key_listener.c +++ b/app/src/mouse/key_listener.c @@ -52,7 +52,7 @@ static void mouse_tick_timer_handler(struct k_work *work) { LOG_DBG("Raising mouse tick event"); ZMK_EVENT_RAISE( zmk_mouse_tick(move_speed, scroll_speed, move_config, scroll_config, start_times)); - zmk_endpoints_send_mouse_report(); + // zmk_endpoints_send_mouse_report(); } K_WORK_DEFINE(mouse_tick, &mouse_tick_timer_handler); diff --git a/app/src/mouse/tick_listener.c b/app/src/mouse/tick_listener.c index 90aaf1119dd9..75ec571a9eae 100644 --- a/app/src/mouse/tick_listener.c +++ b/app/src/mouse/tick_listener.c @@ -15,6 +15,8 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include #include // CLAMP +#include +#include #if !defined(CONFIG_ZMK_SPLIT) || defined(CONFIG_ZMK_SPLIT_ROLE_CENTRAL) #if CONFIG_MINIMAL_LIBC @@ -87,13 +89,20 @@ static void mouse_tick_handler(const struct zmk_mouse_tick *tick) { struct vector2d move = update_movement(&move_remainder, &(tick->move_config), tick->max_move, tick->timestamp, tick->start_times.m_x, tick->start_times.m_y); - zmk_hid_mouse_movement_update((int16_t)CLAMP(move.x, INT16_MIN, INT16_MAX), - (int16_t)CLAMP(move.y, INT16_MIN, INT16_MAX)); + + int ret = 0; + ret = input_report_rel(NULL, INPUT_REL_X, (int16_t)CLAMP(move.x, INT16_MIN, INT16_MAX), false, + K_NO_WAIT); + ret = input_report_rel(NULL, INPUT_REL_Y, (int16_t)CLAMP(move.y, INT16_MIN, INT16_MAX), false, + K_NO_WAIT); + struct vector2d scroll = update_movement(&scroll_remainder, &(tick->scroll_config), tick->max_scroll, tick->timestamp, tick->start_times.s_x, tick->start_times.s_y); - zmk_hid_mouse_scroll_update((int8_t)CLAMP(scroll.x, INT8_MIN, INT8_MAX), - (int8_t)CLAMP(scroll.y, INT8_MIN, INT8_MAX)); + ret = input_report_rel(NULL, INPUT_REL_WHEEL, (int16_t)CLAMP(scroll.y, INT16_MIN, INT16_MAX), + false, K_NO_WAIT); + ret = input_report_rel(NULL, INPUT_REL_HWHEEL, (int16_t)CLAMP(scroll.x, INT16_MIN, INT16_MAX), + true, K_NO_WAIT); } int zmk_mouse_tick_listener(const zmk_event_t *eh) {