diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 6082d018c168..fb0a34618bd0 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -23,6 +23,7 @@ target_sources(app PRIVATE src/behavior.c) target_sources(app PRIVATE src/kscan.c) target_sources(app PRIVATE src/matrix_transform.c) target_sources_ifdef(CONFIG_ZMK_MOUSE app PRIVATE src/mouse/main.c) +target_sources_ifdef(CONFIG_ZMK_MOUSE app PRIVATE src/mouse/input_config.c) target_sources(app PRIVATE src/sensors.c) target_sources_ifdef(CONFIG_ZMK_WPM app PRIVATE src/wpm.c) target_sources(app PRIVATE src/event_manager.c) diff --git a/app/dts/bindings/zmk,input-configs.yaml b/app/dts/bindings/zmk,input-configs.yaml new file mode 100644 index 000000000000..83bd4a1939df --- /dev/null +++ b/app/dts/bindings/zmk,input-configs.yaml @@ -0,0 +1,24 @@ +description: | + Allows post-processing of input events based on the configuration + +compatible: "zmk,input-configs" + +child-binding: + description: "A configuration for a given input device" + + properties: + device: + type: phandle + required: true + xy-swap: + type: boolean + x-invert: + type: boolean + y-invert: + type: boolean + scale-multiplier: + type: int + default: 1 + scale-divisor: + type: int + default: 1 diff --git a/app/include/zmk/mouse/input_config.h b/app/include/zmk/mouse/input_config.h new file mode 100644 index 000000000000..0a37b346cafe --- /dev/null +++ b/app/include/zmk/mouse/input_config.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#include +#include + +struct zmk_input_config { + const struct device *dev; + bool xy_swap; + bool x_invert; + bool y_invert; + uint16_t scale_multiplier; + uint16_t scale_divisor; +}; + +const struct zmk_input_config *zmk_input_config_get_for_device(const struct device *dev); \ No newline at end of file diff --git a/app/src/behaviors/behavior_input_two_axis.c b/app/src/behaviors/behavior_input_two_axis.c index 5a94895e2890..5a6afe63384a 100644 --- a/app/src/behaviors/behavior_input_two_axis.c +++ b/app/src/behaviors/behavior_input_two_axis.c @@ -169,15 +169,17 @@ static void tick_work_cb(struct k_work *work) { } } -static void set_start_times_for_activity(struct movement_state_2d *state) { - if (state->x.speed != 0 && state->x.start_time == 0) { - state->x.start_time = k_uptime_get(); - } - - if (state->y.speed != 0 && state->y.start_time == 0) { - state->y.start_time = k_uptime_get(); +static void set_start_times_for_activity_1d(struct movement_state_1d *state) { + if (state->speed != 0 && state->start_time == 0) { + state->start_time = k_uptime_get(); + } else if (state->speed == 0) { + state->start_time = 0; } } +static void set_start_times_for_activity(struct movement_state_2d *state) { + set_start_times_for_activity_1d(&state->x); + set_start_times_for_activity_1d(&state->y); +} static void update_work_scheduling(const struct device *dev) { struct behavior_input_two_axis_data *data = dev->data; diff --git a/app/src/mouse/hid_input_listener.c b/app/src/mouse/hid_input_listener.c index 6c053755f877..712bb5675c21 100644 --- a/app/src/mouse/hid_input_listener.c +++ b/app/src/mouse/hid_input_listener.c @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -52,7 +53,44 @@ void handle_key_code(struct input_event *evt) { } } +static void swap_xy(struct input_event *evt) { + switch (evt->code) { + case INPUT_REL_X: + evt->code = INPUT_REL_Y; + break; + case INPUT_REL_Y: + evt->code = INPUT_REL_X; + break; + } +} + +static void filter_with_input_config(struct input_event *evt) { + if (!evt->dev) { + return; + } + + const struct zmk_input_config *cfg = zmk_input_config_get_for_device(evt->dev); + + if (!cfg) { + return; + } + + if (cfg->xy_swap) { + swap_xy(evt); + } + + if ((cfg->x_invert && evt->code == INPUT_REL_X) || + (cfg->y_invert && evt->code == INPUT_REL_Y)) { + evt->value = -(evt->value); + } + + evt->value = (int16_t)((evt->value * cfg->scale_multiplier) / cfg->scale_divisor); +} + void input_handler(struct input_event *evt) { + // First, filter to update the event data as needed. + filter_with_input_config(evt); + switch (evt->type) { case INPUT_EV_REL: handle_rel_code(evt); diff --git a/app/src/mouse/input_config.c b/app/src/mouse/input_config.c new file mode 100644 index 000000000000..745fb49bac5e --- /dev/null +++ b/app/src/mouse/input_config.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include + +#define DT_DRV_COMPAT zmk_input_configs + +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) + +#define CHILD_CONFIG(inst) \ + { \ + .dev = DEVICE_DT_GET(DT_PHANDLE(inst, device)), \ + .xy_swap = DT_PROP(inst, xy_swap), \ + .x_invert = DT_PROP(inst, x_invert), \ + .y_invert = DT_PROP(inst, y_invert), \ + .scale_multiplier = DT_PROP(inst, scale_multiplier), \ + .scale_divisor = DT_PROP(inst, scale_divisor), \ + }, + +const struct zmk_input_config configs[] = {DT_INST_FOREACH_CHILD(0, CHILD_CONFIG)}; + +const struct zmk_input_config *zmk_input_config_get_for_device(const struct device *dev) { + for (int i = 0; i < ARRAY_SIZE(configs); i++) { + if (configs[i].dev == dev) { + return &configs[i]; + } + } + + return NULL; +} + +#else + +const struct zmk_input_config *zmk_input_config_get_for_device(const struct device *dev) { + return NULL; +} + +#endif \ No newline at end of file diff --git a/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_scaling/events.patterns b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_scaling/events.patterns new file mode 100644 index 000000000000..812126fb8285 --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_scaling/events.patterns @@ -0,0 +1 @@ +s/.*hid_mouse_//p \ No newline at end of file diff --git a/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_scaling/keycode_events.snapshot b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_scaling/keycode_events.snapshot new file mode 100644 index 000000000000..99fa148876f8 --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_scaling/keycode_events.snapshot @@ -0,0 +1,22 @@ +movement_update: Mouse movement updated to -1/0 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to -3/0 +movement_update: Mouse movement updated to -3/-3 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to -3/0 +movement_update: Mouse movement updated to -3/-3 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to -5/0 +movement_update: Mouse movement updated to -5/-3 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to -5/0 +movement_update: Mouse movement updated to -5/-5 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 0/-5 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 diff --git a/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_scaling/native_posix_64.keymap b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_scaling/native_posix_64.keymap new file mode 100644 index 000000000000..b1ddbc1d8d0d --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_scaling/native_posix_64.keymap @@ -0,0 +1,38 @@ +#include +#include +#include +#include + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &mmv MOVE_LEFT &mmv MOVE_UP + &none &none + >; + }; + }; + + input_configs { + compatible = "zmk,input-configs"; + + mmv { + device = <&mmv>; + scale-multiplier = <5>; + scale-divisor = <3>; + }; + }; +}; + + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_PRESS(0,1,100) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(0,1,10) + >; +}; \ No newline at end of file diff --git a/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_invert/events.patterns b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_invert/events.patterns new file mode 100644 index 000000000000..812126fb8285 --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_invert/events.patterns @@ -0,0 +1 @@ +s/.*hid_mouse_//p \ No newline at end of file diff --git a/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_invert/keycode_events.snapshot b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_invert/keycode_events.snapshot new file mode 100644 index 000000000000..94faacceb619 --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_invert/keycode_events.snapshot @@ -0,0 +1,22 @@ +movement_update: Mouse movement updated to 1/0 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 2/0 +movement_update: Mouse movement updated to 2/2 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 2/0 +movement_update: Mouse movement updated to 2/2 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 3/0 +movement_update: Mouse movement updated to 3/2 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 3/0 +movement_update: Mouse movement updated to 3/3 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 0/3 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 diff --git a/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_invert/native_posix_64.keymap b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_invert/native_posix_64.keymap new file mode 100644 index 000000000000..4767e0ac55e5 --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_invert/native_posix_64.keymap @@ -0,0 +1,38 @@ +#include +#include +#include +#include + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &mmv MOVE_LEFT &mmv MOVE_UP + &none &none + >; + }; + }; + + input_configs { + compatible = "zmk,input-configs"; + + mmv { + device = <&mmv>; + x-invert; + y-invert; + }; + }; +}; + + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_PRESS(0,1,100) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(0,1,10) + >; +}; \ No newline at end of file diff --git a/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_swap/events.patterns b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_swap/events.patterns new file mode 100644 index 000000000000..812126fb8285 --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_swap/events.patterns @@ -0,0 +1 @@ +s/.*hid_mouse_//p \ No newline at end of file diff --git a/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_swap/keycode_events.snapshot b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_swap/keycode_events.snapshot new file mode 100644 index 000000000000..5ca5300c1a7e --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_swap/keycode_events.snapshot @@ -0,0 +1,22 @@ +movement_update: Mouse movement updated to 0/-1 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 0/-2 +movement_update: Mouse movement updated to -2/-2 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 0/-2 +movement_update: Mouse movement updated to -2/-2 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 0/-3 +movement_update: Mouse movement updated to -2/-3 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to 0/-3 +movement_update: Mouse movement updated to -3/-3 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 +movement_update: Mouse movement updated to -3/0 +scroll_set: Mouse scroll set to 0/0 +movement_set: Mouse movement set to 0/0 diff --git a/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_swap/native_posix_64.keymap b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_swap/native_posix_64.keymap new file mode 100644 index 000000000000..153270231fad --- /dev/null +++ b/app/tests/mouse-keys/mouse-move/input-configs/move_diagonal_xy_swap/native_posix_64.keymap @@ -0,0 +1,37 @@ +#include +#include +#include +#include + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &mmv MOVE_LEFT &mmv MOVE_UP + &none &none + >; + }; + }; + + input_configs { + compatible = "zmk,input-configs"; + + mmv { + device = <&mmv>; + xy-swap; + }; + }; +}; + + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_PRESS(0,1,100) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(0,1,10) + >; +}; \ No newline at end of file diff --git a/app/tests/mouse-keys/mouse-move/move_x/keycode_events.snapshot b/app/tests/mouse-keys/mouse-move/move_x/keycode_events.snapshot index 027e83e9f066..dfbc4a76eab4 100644 --- a/app/tests/mouse-keys/mouse-move/move_x/keycode_events.snapshot +++ b/app/tests/mouse-keys/mouse-move/move_x/keycode_events.snapshot @@ -10,18 +10,15 @@ movement_set: Mouse movement set to 0/0 movement_update: Mouse movement updated to -3/0 scroll_set: Mouse scroll set to 0/0 movement_set: Mouse movement set to 0/0 -movement_update: Mouse movement updated to 3/0 +movement_update: Mouse movement updated to 1/0 scroll_set: Mouse scroll set to 0/0 movement_set: Mouse movement set to 0/0 -movement_update: Mouse movement updated to 5/0 +movement_update: Mouse movement updated to 2/0 scroll_set: Mouse scroll set to 0/0 movement_set: Mouse movement set to 0/0 -movement_update: Mouse movement updated to 5/0 +movement_update: Mouse movement updated to 2/0 scroll_set: Mouse scroll set to 0/0 movement_set: Mouse movement set to 0/0 -movement_update: Mouse movement updated to 6/0 +movement_update: Mouse movement updated to 3/0 scroll_set: Mouse scroll set to 0/0 movement_set: Mouse movement set to 0/0 -movement_update: Mouse movement updated to 6/0 -scroll_set: Mouse scroll set to 0/0 -movement_set: Mouse movement set to 0/0 \ No newline at end of file diff --git a/app/tests/mouse-keys/mouse-move/move_y/keycode_events.snapshot b/app/tests/mouse-keys/mouse-move/move_y/keycode_events.snapshot index 178d5e7453a3..4fd9a25202ca 100644 --- a/app/tests/mouse-keys/mouse-move/move_y/keycode_events.snapshot +++ b/app/tests/mouse-keys/mouse-move/move_y/keycode_events.snapshot @@ -10,18 +10,15 @@ movement_set: Mouse movement set to 0/0 movement_update: Mouse movement updated to 0/-3 scroll_set: Mouse scroll set to 0/0 movement_set: Mouse movement set to 0/0 -movement_update: Mouse movement updated to 0/3 -scroll_set: Mouse scroll set to 0/0 -movement_set: Mouse movement set to 0/0 -movement_update: Mouse movement updated to 0/5 +movement_update: Mouse movement updated to 0/1 scroll_set: Mouse scroll set to 0/0 movement_set: Mouse movement set to 0/0 -movement_update: Mouse movement updated to 0/5 +movement_update: Mouse movement updated to 0/2 scroll_set: Mouse scroll set to 0/0 movement_set: Mouse movement set to 0/0 -movement_update: Mouse movement updated to 0/6 +movement_update: Mouse movement updated to 0/2 scroll_set: Mouse scroll set to 0/0 movement_set: Mouse movement set to 0/0 -movement_update: Mouse movement updated to 0/6 +movement_update: Mouse movement updated to 0/3 scroll_set: Mouse scroll set to 0/0 movement_set: Mouse movement set to 0/0