Skip to content

Commit d837c95

Browse files
committed
feat(mouse): Add input configs for data mods.
* Add ability to swap X/Y, invert X and Y values, and apply a scalar multiplier/divisor.
1 parent c5fbb32 commit d837c95

File tree

17 files changed

+325
-21
lines changed

17 files changed

+325
-21
lines changed

app/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ target_sources(app PRIVATE src/activity.c)
2828
target_sources(app PRIVATE src/kscan.c)
2929
target_sources(app PRIVATE src/matrix_transform.c)
3030
target_sources_ifdef(CONFIG_ZMK_MOUSE app PRIVATE src/mouse/main.c)
31+
target_sources_ifdef(CONFIG_ZMK_MOUSE app PRIVATE src/mouse/input_config.c)
3132
target_sources(app PRIVATE src/sensors.c)
3233
target_sources_ifdef(CONFIG_ZMK_WPM app PRIVATE src/wpm.c)
3334
target_sources(app PRIVATE src/event_manager.c)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
description: |
2+
Allows post-processing of input events based on the configuration
3+
4+
compatible: "zmk,input-configs"
5+
6+
child-binding:
7+
description: "A configuration for a given input device"
8+
9+
properties:
10+
device:
11+
type: phandle
12+
required: true
13+
xy-swap:
14+
type: boolean
15+
x-invert:
16+
type: boolean
17+
y-invert:
18+
type: boolean
19+
scale-multiplier:
20+
type: int
21+
default: 1
22+
scale-divisor:
23+
type: int
24+
default: 1
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright (c) 2023 The ZMK Contributors
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*/
6+
7+
#pragma once
8+
9+
#include <zephyr/kernel.h>
10+
#include <zephyr/device.h>
11+
12+
struct zmk_input_config {
13+
const struct device *dev;
14+
bool xy_swap;
15+
bool x_invert;
16+
bool y_invert;
17+
uint16_t scale_multiplier;
18+
uint16_t scale_divisor;
19+
};
20+
21+
const struct zmk_input_config *zmk_input_config_get_for_device(const struct device *dev);

app/src/behaviors/behavior_input_two_axis.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -169,15 +169,17 @@ static void tick_work_cb(struct k_work *work) {
169169
}
170170
}
171171

172-
static void set_start_times_for_activity(struct movement_state_2d *state) {
173-
if (state->x.speed != 0 && state->x.start_time == 0) {
174-
state->x.start_time = k_uptime_get();
175-
}
176-
177-
if (state->y.speed != 0 && state->y.start_time == 0) {
178-
state->y.start_time = k_uptime_get();
172+
static void set_start_times_for_activity_1d(struct movement_state_1d *state) {
173+
if (state->speed != 0 && state->start_time == 0) {
174+
state->start_time = k_uptime_get();
175+
} else if (state->speed == 0) {
176+
state->start_time = 0;
179177
}
180178
}
179+
static void set_start_times_for_activity(struct movement_state_2d *state) {
180+
set_start_times_for_activity_1d(&state->x);
181+
set_start_times_for_activity_1d(&state->y);
182+
}
181183

182184
static void update_work_scheduling(const struct device *dev) {
183185
struct behavior_input_two_axis_data *data = dev->data;

app/src/mouse/hid_input_listener.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <zephyr/dt-bindings/input/input-event-codes.h>
1010

1111
#include <zmk/mouse.h>
12+
#include <zmk/mouse/input_config.h>
1213
#include <zmk/endpoints.h>
1314
#include <zmk/hid.h>
1415

@@ -52,7 +53,44 @@ void handle_key_code(struct input_event *evt) {
5253
}
5354
}
5455

56+
static void swap_xy(struct input_event *evt) {
57+
switch (evt->code) {
58+
case INPUT_REL_X:
59+
evt->code = INPUT_REL_Y;
60+
break;
61+
case INPUT_REL_Y:
62+
evt->code = INPUT_REL_X;
63+
break;
64+
}
65+
}
66+
67+
static void filter_with_input_config(struct input_event *evt) {
68+
if (!evt->dev) {
69+
return;
70+
}
71+
72+
const struct zmk_input_config *cfg = zmk_input_config_get_for_device(evt->dev);
73+
74+
if (!cfg) {
75+
return;
76+
}
77+
78+
if (cfg->xy_swap) {
79+
swap_xy(evt);
80+
}
81+
82+
if ((cfg->x_invert && evt->code == INPUT_REL_X) ||
83+
(cfg->y_invert && evt->code == INPUT_REL_Y)) {
84+
evt->value = -(evt->value);
85+
}
86+
87+
evt->value = (int16_t)((evt->value * cfg->scale_multiplier) / cfg->scale_divisor);
88+
}
89+
5590
void input_handler(struct input_event *evt) {
91+
// First, filter to update the event data as needed.
92+
filter_with_input_config(evt);
93+
5694
switch (evt->type) {
5795
case INPUT_EV_REL:
5896
handle_rel_code(evt);

app/src/mouse/input_config.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (c) 2023 The ZMK Contributors
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*/
6+
7+
#include <zmk/mouse/input_config.h>
8+
#include <zephyr/device.h>
9+
10+
#define DT_DRV_COMPAT zmk_input_configs
11+
12+
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
13+
14+
#define CHILD_CONFIG(inst) \
15+
{ \
16+
.dev = DEVICE_DT_GET(DT_PHANDLE(inst, device)), \
17+
.xy_swap = DT_PROP(inst, xy_swap), \
18+
.x_invert = DT_PROP(inst, x_invert), \
19+
.y_invert = DT_PROP(inst, y_invert), \
20+
.scale_multiplier = DT_PROP(inst, scale_multiplier), \
21+
.scale_divisor = DT_PROP(inst, scale_divisor), \
22+
},
23+
24+
const struct zmk_input_config configs[] = {DT_INST_FOREACH_CHILD(0, CHILD_CONFIG)};
25+
26+
const struct zmk_input_config *zmk_input_config_get_for_device(const struct device *dev) {
27+
for (int i = 0; i < ARRAY_SIZE(configs); i++) {
28+
if (configs[i].dev == dev) {
29+
return &configs[i];
30+
}
31+
}
32+
33+
return NULL;
34+
}
35+
36+
#else
37+
38+
const struct zmk_input_config *zmk_input_config_get_for_device(const struct device *dev) {
39+
return NULL;
40+
}
41+
42+
#endif
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
s/.*hid_mouse_//p
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
movement_update: Mouse movement updated to -1/0
2+
scroll_set: Mouse scroll set to 0/0
3+
movement_set: Mouse movement set to 0/0
4+
movement_update: Mouse movement updated to -3/0
5+
movement_update: Mouse movement updated to -3/-3
6+
scroll_set: Mouse scroll set to 0/0
7+
movement_set: Mouse movement set to 0/0
8+
movement_update: Mouse movement updated to -3/0
9+
movement_update: Mouse movement updated to -3/-3
10+
scroll_set: Mouse scroll set to 0/0
11+
movement_set: Mouse movement set to 0/0
12+
movement_update: Mouse movement updated to -5/0
13+
movement_update: Mouse movement updated to -5/-3
14+
scroll_set: Mouse scroll set to 0/0
15+
movement_set: Mouse movement set to 0/0
16+
movement_update: Mouse movement updated to -5/0
17+
movement_update: Mouse movement updated to -5/-5
18+
scroll_set: Mouse scroll set to 0/0
19+
movement_set: Mouse movement set to 0/0
20+
movement_update: Mouse movement updated to 0/-5
21+
scroll_set: Mouse scroll set to 0/0
22+
movement_set: Mouse movement set to 0/0
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include <behaviors.dtsi>
2+
#include <dt-bindings/zmk/keys.h>
3+
#include <dt-bindings/zmk/kscan_mock.h>
4+
#include <dt-bindings/zmk/mouse.h>
5+
6+
/ {
7+
keymap {
8+
compatible = "zmk,keymap";
9+
label ="Default keymap";
10+
11+
default_layer {
12+
bindings = <
13+
&mmv MOVE_LEFT &mmv MOVE_UP
14+
&none &none
15+
>;
16+
};
17+
};
18+
19+
input_configs {
20+
compatible = "zmk,input-configs";
21+
22+
mmv {
23+
device = <&mmv>;
24+
scale-multiplier = <5>;
25+
scale-divisor = <3>;
26+
};
27+
};
28+
};
29+
30+
31+
&kscan {
32+
events = <
33+
ZMK_MOCK_PRESS(0,0,10)
34+
ZMK_MOCK_PRESS(0,1,100)
35+
ZMK_MOCK_RELEASE(0,0,10)
36+
ZMK_MOCK_RELEASE(0,1,10)
37+
>;
38+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
s/.*hid_mouse_//p

0 commit comments

Comments
 (0)