From e7a6e4016d757d37f0b8df28d7b78f38554e0b27 Mon Sep 17 00:00:00 2001 From: Joel Spadin Date: Sat, 29 Oct 2022 23:17:12 -0500 Subject: [PATCH] feat(behaviors): Add key position to key events Extended the virtual key position system from combos so that each sensor also gets a virtual key position. This allows sensor behaviors to use the behavior queue API. --- app/include/drivers/behavior.h | 13 +++++++----- app/include/zmk/sensors.h | 7 ++++++- app/include/zmk/virtual_key_position.h | 20 +++++++++++++++++++ .../behavior_sensor_rotate_key_press.c | 3 ++- app/src/combo.c | 3 ++- app/src/keymap.c | 10 ++++++---- 6 files changed, 44 insertions(+), 12 deletions(-) create mode 100644 app/include/zmk/virtual_key_position.h diff --git a/app/include/drivers/behavior.h b/app/include/drivers/behavior.h index 71df7344..df18385f 100644 --- a/app/include/drivers/behavior.h +++ b/app/include/drivers/behavior.h @@ -26,6 +26,7 @@ typedef int (*behavior_keymap_binding_callback_t)(struct zmk_behavior_binding *b struct zmk_behavior_binding_event event); typedef int (*behavior_sensor_keymap_binding_callback_t)(struct zmk_behavior_binding *binding, const struct device *sensor, + uint32_t virtual_key_position, int64_t timestamp); enum behavior_locality { @@ -150,21 +151,23 @@ static inline int z_impl_behavior_keymap_binding_released(struct zmk_behavior_bi /** * @brief Handle the a sensor keymap binding being triggered - * @param dev Pointer to the device structure for the driver instance. + * @param binding Sensor keymap binding which was triggered. * @param sensor Pointer to the sensor device structure for the sensor driver instance. - * @param param1 User parameter specified at time of behavior binding. - * @param param2 User parameter specified at time of behavior binding. + * @param virtual_key_position ZMK_KEYMAP_LEN + sensor number + * @param timestamp Time at which the binding was triggered. * * @retval 0 If successful. * @retval Negative errno code if failure. */ __syscall int behavior_sensor_keymap_binding_triggered(struct zmk_behavior_binding *binding, const struct device *sensor, + uint32_t virtual_key_position, int64_t timestamp); static inline int z_impl_behavior_sensor_keymap_binding_triggered(struct zmk_behavior_binding *binding, - const struct device *sensor, int64_t timestamp) { + const struct device *sensor, + uint32_t virtual_key_position, int64_t timestamp) { const struct device *dev = device_get_binding(binding->behavior_dev); if (dev == NULL) { @@ -177,7 +180,7 @@ z_impl_behavior_sensor_keymap_binding_triggered(struct zmk_behavior_binding *bin return -ENOTSUP; } - return api->sensor_binding_triggered(binding, sensor, timestamp); + return api->sensor_binding_triggered(binding, sensor, virtual_key_position, timestamp); } /** diff --git a/app/include/zmk/sensors.h b/app/include/zmk/sensors.h index 8c6c28b3..9e54695f 100644 --- a/app/include/zmk/sensors.h +++ b/app/include/zmk/sensors.h @@ -8,5 +8,10 @@ #define ZMK_KEYMAP_SENSORS_NODE DT_INST(0, zmk_keymap_sensors) #define ZMK_KEYMAP_HAS_SENSORS DT_NODE_HAS_STATUS(ZMK_KEYMAP_SENSORS_NODE, okay) -#define ZMK_KEYMAP_SENSORS_LEN DT_PROP_LEN(ZMK_KEYMAP_SENSORS_NODE, sensors) #define ZMK_KEYMAP_SENSORS_BY_IDX(idx) DT_PHANDLE_BY_IDX(ZMK_KEYMAP_SENSORS_NODE, sensors, idx) + +#if ZMK_KEYMAP_HAS_SENSORS +#define ZMK_KEYMAP_SENSORS_LEN DT_PROP_LEN(ZMK_KEYMAP_SENSORS_NODE, sensors) +#else +#define ZMK_KEYMAP_SENSORS_LEN 0 +#endif diff --git a/app/include/zmk/virtual_key_position.h b/app/include/zmk/virtual_key_position.h new file mode 100644 index 00000000..48deee5c --- /dev/null +++ b/app/include/zmk/virtual_key_position.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2022 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#include +#include + +/** + * Gets the virtual key position to use for the sensor with the given index. + */ +#define ZMK_VIRTUAL_KEY_POSITION_SENSOR(index) (ZMK_KEYMAP_LEN + (index)) + +/** + * Gets the virtual key position to use for the combo with the given index. + */ +#define ZMK_VIRTUAL_KEY_POSITION_COMBO(index) (ZMK_KEYMAP_LEN + ZMK_KEYMAP_SENSORS_LEN + (index)) diff --git a/app/src/behaviors/behavior_sensor_rotate_key_press.c b/app/src/behaviors/behavior_sensor_rotate_key_press.c index ed6eedae..72e33ea4 100644 --- a/app/src/behaviors/behavior_sensor_rotate_key_press.c +++ b/app/src/behaviors/behavior_sensor_rotate_key_press.c @@ -21,7 +21,8 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); static int behavior_sensor_rotate_key_press_init(const struct device *dev) { return 0; }; static int on_sensor_binding_triggered(struct zmk_behavior_binding *binding, - const struct device *sensor, int64_t timestamp) { + const struct device *sensor, uint32_t virtual_key_position, + int64_t timestamp) { struct sensor_value value; int err; uint32_t keycode; diff --git a/app/src/combo.c b/app/src/combo.c index 2e237330..90c89c15 100644 --- a/app/src/combo.c +++ b/app/src/combo.c @@ -19,6 +19,7 @@ #include #include #include +#include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); @@ -476,7 +477,7 @@ ZMK_SUBSCRIPTION(combo, zmk_position_state_changed); .key_positions = DT_PROP(n, key_positions), \ .key_position_len = DT_PROP_LEN(n, key_positions), \ .behavior = ZMK_KEYMAP_EXTRACT_BINDING(0, n), \ - .virtual_key_position = ZMK_KEYMAP_LEN + __COUNTER__, \ + .virtual_key_position = ZMK_VIRTUAL_KEY_POSITION_COMBO(__COUNTER__), \ .slow_release = DT_PROP(n, slow_release), \ .layers = DT_PROP(n, layers), \ .layers_len = DT_PROP_LEN(n, layers), \ diff --git a/app/src/keymap.c b/app/src/keymap.c index c4e304d4..825246fa 100644 --- a/app/src/keymap.c +++ b/app/src/keymap.c @@ -4,16 +4,17 @@ * SPDX-License-Identifier: MIT */ +#include #include #include #include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); +#include +#include #include #include -#include -#include -#include +#include #include #if ZMK_BLE_IS_CENTRAL @@ -269,7 +270,8 @@ int zmk_keymap_sensor_triggered(uint8_t sensor_number, const struct device *sens continue; } - ret = behavior_sensor_keymap_binding_triggered(binding, sensor, timestamp); + const uint32_t position = ZMK_VIRTUAL_KEY_POSITION_SENSOR(sensor_number); + ret = behavior_sensor_keymap_binding_triggered(binding, sensor, position, timestamp); if (ret > 0) { LOG_DBG("behavior processing to continue to next layer");