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.
This commit is contained in:
Joel Spadin 2022-10-29 23:17:12 -05:00 committed by Pete Johanson
parent 83a151890c
commit e7a6e4016d
6 changed files with 44 additions and 12 deletions

View file

@ -26,6 +26,7 @@ typedef int (*behavior_keymap_binding_callback_t)(struct zmk_behavior_binding *b
struct zmk_behavior_binding_event event); struct zmk_behavior_binding_event event);
typedef int (*behavior_sensor_keymap_binding_callback_t)(struct zmk_behavior_binding *binding, typedef int (*behavior_sensor_keymap_binding_callback_t)(struct zmk_behavior_binding *binding,
const struct device *sensor, const struct device *sensor,
uint32_t virtual_key_position,
int64_t timestamp); int64_t timestamp);
enum behavior_locality { 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 * @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 sensor Pointer to the sensor device structure for the sensor driver instance.
* @param param1 User parameter specified at time of behavior binding. * @param virtual_key_position ZMK_KEYMAP_LEN + sensor number
* @param param2 User parameter specified at time of behavior binding. * @param timestamp Time at which the binding was triggered.
* *
* @retval 0 If successful. * @retval 0 If successful.
* @retval Negative errno code if failure. * @retval Negative errno code if failure.
*/ */
__syscall int behavior_sensor_keymap_binding_triggered(struct zmk_behavior_binding *binding, __syscall int behavior_sensor_keymap_binding_triggered(struct zmk_behavior_binding *binding,
const struct device *sensor, const struct device *sensor,
uint32_t virtual_key_position,
int64_t timestamp); int64_t timestamp);
static inline int static inline int
z_impl_behavior_sensor_keymap_binding_triggered(struct zmk_behavior_binding *binding, 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); const struct device *dev = device_get_binding(binding->behavior_dev);
if (dev == NULL) { if (dev == NULL) {
@ -177,7 +180,7 @@ z_impl_behavior_sensor_keymap_binding_triggered(struct zmk_behavior_binding *bin
return -ENOTSUP; return -ENOTSUP;
} }
return api->sensor_binding_triggered(binding, sensor, timestamp); return api->sensor_binding_triggered(binding, sensor, virtual_key_position, timestamp);
} }
/** /**

View file

@ -8,5 +8,10 @@
#define ZMK_KEYMAP_SENSORS_NODE DT_INST(0, zmk_keymap_sensors) #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_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) #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

View file

@ -0,0 +1,20 @@
/*
* Copyright (c) 2022 The ZMK Contributors
*
* SPDX-License-Identifier: MIT
*/
#pragma once
#include <zmk/matrix.h>
#include <zmk/sensors.h>
/**
* 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))

View file

@ -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 behavior_sensor_rotate_key_press_init(const struct device *dev) { return 0; };
static int on_sensor_binding_triggered(struct zmk_behavior_binding *binding, 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; struct sensor_value value;
int err; int err;
uint32_t keycode; uint32_t keycode;

View file

@ -19,6 +19,7 @@
#include <zmk/hid.h> #include <zmk/hid.h>
#include <zmk/matrix.h> #include <zmk/matrix.h>
#include <zmk/keymap.h> #include <zmk/keymap.h>
#include <zmk/virtual_key_position.h>
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); 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_positions = DT_PROP(n, key_positions), \
.key_position_len = DT_PROP_LEN(n, key_positions), \ .key_position_len = DT_PROP_LEN(n, key_positions), \
.behavior = ZMK_KEYMAP_EXTRACT_BINDING(0, n), \ .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), \ .slow_release = DT_PROP(n, slow_release), \
.layers = DT_PROP(n, layers), \ .layers = DT_PROP(n, layers), \
.layers_len = DT_PROP_LEN(n, layers), \ .layers_len = DT_PROP_LEN(n, layers), \

View file

@ -4,16 +4,17 @@
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
*/ */
#include <drivers/behavior.h>
#include <zephyr/sys/util.h> #include <zephyr/sys/util.h>
#include <zephyr/bluetooth/bluetooth.h> #include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/logging/log.h> #include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#include <zmk/behavior.h>
#include <zmk/keymap.h>
#include <zmk/matrix.h> #include <zmk/matrix.h>
#include <zmk/sensors.h> #include <zmk/sensors.h>
#include <zmk/keymap.h> #include <zmk/virtual_key_position.h>
#include <drivers/behavior.h>
#include <zmk/behavior.h>
#include <zmk/ble.h> #include <zmk/ble.h>
#if ZMK_BLE_IS_CENTRAL #if ZMK_BLE_IS_CENTRAL
@ -269,7 +270,8 @@ int zmk_keymap_sensor_triggered(uint8_t sensor_number, const struct device *sens
continue; 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) { if (ret > 0) {
LOG_DBG("behavior processing to continue to next layer"); LOG_DBG("behavior processing to continue to next layer");