diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 793f386d..c800d1cc 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -49,6 +49,7 @@ if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_ROLE_CENTRAL) target_sources(app PRIVATE src/behaviors/behavior_outputs.c) target_sources(app PRIVATE src/behaviors/behavior_toggle_layer.c) target_sources(app PRIVATE src/behaviors/behavior_to_layer.c) + target_sources(app PRIVATE src/behaviors/behavior_base_layer.c) target_sources(app PRIVATE src/behaviors/behavior_transparent.c) target_sources(app PRIVATE src/behaviors/behavior_none.c) target_sources_ifdef(CONFIG_ZMK_BEHAVIOR_SENSOR_ROTATE app PRIVATE src/behaviors/behavior_sensor_rotate.c) diff --git a/app/dts/behaviors.dtsi b/app/dts/behaviors.dtsi index b3502cbb..83faeacd 100644 --- a/app/dts/behaviors.dtsi +++ b/app/dts/behaviors.dtsi @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -18,4 +19,4 @@ #include #include #include -#include \ No newline at end of file +#include diff --git a/app/dts/behaviors/base_layer.dtsi b/app/dts/behaviors/base_layer.dtsi new file mode 100644 index 00000000..510829f2 --- /dev/null +++ b/app/dts/behaviors/base_layer.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2022 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +/ { + behaviors { + /omit-if-no-ref/ base: behavior_base_layer { + compatible = "zmk,behavior-base-layer"; + label = "BASE_LAYER"; + #binding-cells = <1>; + }; + }; +}; diff --git a/app/dts/bindings/behaviors/zmk,behavior-base-layer.yaml b/app/dts/bindings/behaviors/zmk,behavior-base-layer.yaml new file mode 100644 index 00000000..91c3809b --- /dev/null +++ b/app/dts/bindings/behaviors/zmk,behavior-base-layer.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2022 The ZMK Contributors +# SPDX-License-Identifier: MIT + +description: Base Layer + +compatible: "zmk,behavior-base-layer" + +include: one_param.yaml diff --git a/app/src/behaviors/behavior_base_layer.c b/app/src/behaviors/behavior_base_layer.c new file mode 100644 index 00000000..dc472900 --- /dev/null +++ b/app/src/behaviors/behavior_base_layer.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2022 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#define DT_DRV_COMPAT zmk_behavior_base_layer + +#include +#include +#include + +#include +#include +#include +#include +#include + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) + +uint8_t base_layer_by_profile[ZMK_PROFILE_COUNT] = {0}; + +static int behavior_to_init(const struct device *dev) { return 0; }; + +static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + LOG_DBG("position %d layer %d", event.position, binding->param1); + + const zmk_profile_index_t profile_index = zmk_current_profile_index(); + const uint8_t layer = binding->param1; + + base_layer_by_profile[profile_index] = layer; + zmk_keymap_layer_to(layer); + LOG_INF("saved base layer %d for profile %d", layer, profile_index); + + return ZMK_BEHAVIOR_OPAQUE; +} + +static int on_keymap_binding_released(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + LOG_DBG("position %d layer %d", event.position, binding->param1); + return ZMK_BEHAVIOR_OPAQUE; +} + +static int base_layer_listener(const zmk_event_t *e) { + if (e == NULL) { + return ZMK_EV_EVENT_BUBBLE; + } + + const zmk_profile_index_t profile_index = zmk_current_profile_index(); + const uint8_t layer = base_layer_by_profile[profile_index]; + + zmk_keymap_layer_to(layer); + LOG_INF("restored base layer %d for profile %d", layer, profile_index); + + return ZMK_EV_EVENT_BUBBLE; +} +static ZMK_LISTENER(base_layer_listener, base_layer_listener); + +static ZMK_SUBSCRIPTION(base_layer_listener, zmk_endpoint_selection_changed); + +#if IS_ENABLED(CONFIG_ZMK_BLE) +static ZMK_SUBSCRIPTION(base_layer_listener, zmk_ble_active_profile_changed); +#endif + +static const struct behavior_driver_api behavior_base_layer_driver_api = { + .binding_pressed = on_keymap_binding_pressed, + .binding_released = on_keymap_binding_released, +}; + +DEVICE_DT_INST_DEFINE(0, behavior_to_init, NULL, NULL, NULL, APPLICATION, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_base_layer_driver_api); + +#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */