feat(split): Make locality work nested behavior invocations

Co-authored-by: Tokazio <tokazio@hotmail.com>
This commit is contained in:
Cem Aksoylar
2023-01-17 19:05:04 +01:00
committed by Pete Johanson
parent 11f600d9e5
commit 9e36ebd525
13 changed files with 146 additions and 105 deletions

View File

@@ -17,11 +17,18 @@
#endif
#include <zmk/ble.h>
#if ZMK_BLE_IS_CENTRAL
#include <zmk/split/bluetooth/central.h>
#endif
#include <drivers/behavior.h>
#include <zmk/behavior.h>
#include <zmk/hid.h>
#include <zmk/matrix.h>
#include <zmk/events/position_state_changed.h>
#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
@@ -49,6 +56,66 @@ const struct device *z_impl_behavior_get_binding(const char *name) {
return NULL;
}
static int invoke_locally(struct zmk_behavior_binding *binding,
struct zmk_behavior_binding_event event, bool pressed) {
if (pressed) {
return behavior_keymap_binding_pressed(binding, event);
} else {
return behavior_keymap_binding_released(binding, event);
}
}
int zmk_behavior_invoke_binding(const struct zmk_behavior_binding *src_binding,
struct zmk_behavior_binding_event event, bool pressed) {
// We want to make a copy of this, since it may be converted from
// relative to absolute before being invoked
struct zmk_behavior_binding binding = *src_binding;
const struct device *behavior = zmk_behavior_get_binding(binding.behavior_dev);
if (!behavior) {
LOG_WRN("No behavior assigned to %d on layer %d", event.position, event.layer);
return 1;
}
int err = behavior_keymap_binding_convert_central_state_dependent_params(&binding, event);
if (err) {
LOG_ERR("Failed to convert relative to absolute behavior binding (err %d)", err);
return err;
}
enum behavior_locality locality = BEHAVIOR_LOCALITY_CENTRAL;
err = behavior_get_locality(behavior, &locality);
if (err) {
LOG_ERR("Failed to get behavior locality %d", err);
return err;
}
switch (locality) {
case BEHAVIOR_LOCALITY_CENTRAL:
return invoke_locally(&binding, event, pressed);
case BEHAVIOR_LOCALITY_EVENT_SOURCE:
#if ZMK_BLE_IS_CENTRAL
if (event.source == ZMK_POSITION_STATE_CHANGE_SOURCE_LOCAL) {
return invoke_locally(&binding, event, pressed);
} else {
return zmk_split_bt_invoke_behavior(event.source, &binding, event, pressed);
}
#else
return invoke_locally(&binding, event, pressed);
#endif
case BEHAVIOR_LOCALITY_GLOBAL:
#if ZMK_BLE_IS_CENTRAL
for (int i = 0; i < ZMK_SPLIT_BLE_PERIPHERAL_COUNT; i++) {
zmk_split_bt_invoke_behavior(i, &binding, event, pressed);
}
#endif
return invoke_locally(&binding, event, pressed);
}
return -ENOTSUP;
}
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
int zmk_behavior_get_empty_param_metadata(const struct device *dev,