refactor(keys): Unify usage page.

* Remove need for separate `&cp` behavior, but
  keep it for now for backward compat.
* Refactor sensor inc/dec as well.
This commit is contained in:
Pete Johanson 2020-10-26 00:30:24 -04:00 committed by innovaker
parent 542358bfc2
commit 2b5d87334a
12 changed files with 436 additions and 469 deletions

View file

@ -3,17 +3,9 @@
/ { / {
behaviors { behaviors {
kp: behavior_key_press { pr: cp: kp: behavior_key_press {
compatible = "zmk,behavior-key-press"; compatible = "zmk,behavior-key-press";
label = "KEY_PRESS"; label = "KEY_PRESS";
usage_page = <HID_USAGE_KEY>;
#binding-cells = <1>;
};
cp: behavior_consumer_press {
compatible = "zmk,behavior-key-press";
label = "CONSUMER_PRESS";
usage_page = <HID_USAGE_CONSUMER>;
#binding-cells = <1>; #binding-cells = <1>;
}; };
}; };

View file

@ -3,17 +3,9 @@
/ { / {
behaviors { behaviors {
inc_dec_kp: behavior_sensor_rotate_key_press { inc_dec: inc_dec_cp: inc_dec_kp: behavior_sensor_rotate_key_press {
compatible = "zmk,behavior-sensor-rotate-key-press"; compatible = "zmk,behavior-sensor-rotate-key-press";
label = "ENC_KEY_PRESS"; label = "ENC_KEY_PRESS";
usage_page = <HID_USAGE_KEY>;
#sensor-binding-cells = <2>;
};
inc_dec_cp: behavior_sensor_rotate_consumer_press {
compatible = "zmk,behavior-sensor-rotate-key-press";
label = "ENC_CONSUMER_PRESS";
usage_page = <HID_USAGE_CONSUMER>;
#sensor-binding-cells = <2>; #sensor-binding-cells = <2>;
}; };
}; };

View file

@ -6,8 +6,3 @@ description: Key press/release behavior
compatible: "zmk,behavior-key-press" compatible: "zmk,behavior-key-press"
include: one_param.yaml include: one_param.yaml
properties:
usage_page:
type: int
default: 0

View file

@ -13,9 +13,6 @@ properties:
type: int type: int
required: true required: true
const: 2 const: 2
usage_page:
type: int
default: 0
sensor-binding-cells: sensor-binding-cells:
- param1 - param1

File diff suppressed because it is too large Load diff

View file

@ -9,6 +9,7 @@
#include <zephyr.h> #include <zephyr.h>
#include <dt-bindings/zmk/modifiers.h> #include <dt-bindings/zmk/modifiers.h>
#include <zmk/event-manager.h> #include <zmk/event-manager.h>
#include <dt-bindings/zmk/hid_usage_pages.h>
struct keycode_state_changed { struct keycode_state_changed {
struct zmk_event_header header; struct zmk_event_header header;
@ -29,3 +30,15 @@ create_keycode_state_changed(u8_t usage_page, u32_t keycode, bool state) {
ev->state = state; ev->state = state;
return ev; return ev;
} }
static inline struct keycode_state_changed *keycode_state_changed_from_encoded(u32_t encoded,
bool pressed) {
u16_t page = (encoded >> 16) & 0xFF;
u16_t id = encoded & 0xFFFF;
if (!page) {
page = HID_USAGE_KEY;
}
return create_keycode_state_changed(page, id, pressed);
}

View file

@ -16,42 +16,28 @@
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
struct behavior_key_press_config {
u8_t usage_page;
};
struct behavior_key_press_data {};
static int behavior_key_press_init(struct device *dev) { return 0; }; static int behavior_key_press_init(struct device *dev) { return 0; };
static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
struct zmk_behavior_binding_event event) { struct zmk_behavior_binding_event event) {
struct device *dev = device_get_binding(binding->behavior_dev); LOG_DBG("position %d keycode 0x%02X", event.position, binding->param1);
const struct behavior_key_press_config *cfg = dev->config_info;
LOG_DBG("position %d usage_page 0x%02X keycode 0x%02X", event.position, cfg->usage_page,
binding->param1);
return ZMK_EVENT_RAISE(create_keycode_state_changed(cfg->usage_page, binding->param1, true)); return ZMK_EVENT_RAISE(keycode_state_changed_from_encoded(binding->param1, true));
} }
static int on_keymap_binding_released(struct zmk_behavior_binding *binding, static int on_keymap_binding_released(struct zmk_behavior_binding *binding,
struct zmk_behavior_binding_event event) { struct zmk_behavior_binding_event event) {
struct device *dev = device_get_binding(binding->behavior_dev); LOG_DBG("position %d keycode 0x%02X", event.position, binding->param1);
const struct behavior_key_press_config *cfg = dev->config_info;
LOG_DBG("position %d usage_page 0x%02X keycode 0x%02X", event.position, cfg->usage_page,
binding->param1);
return ZMK_EVENT_RAISE(create_keycode_state_changed(cfg->usage_page, binding->param1, false)); return ZMK_EVENT_RAISE(keycode_state_changed_from_encoded(binding->param1, false));
} }
static const struct behavior_driver_api behavior_key_press_driver_api = { static const struct behavior_driver_api behavior_key_press_driver_api = {
.binding_pressed = on_keymap_binding_pressed, .binding_released = on_keymap_binding_released}; .binding_pressed = on_keymap_binding_pressed, .binding_released = on_keymap_binding_released};
#define KP_INST(n) \ #define KP_INST(n) \
static const struct behavior_key_press_config behavior_key_press_config_##n = { \ DEVICE_AND_API_INIT(behavior_key_press_##n, DT_INST_LABEL(n), behavior_key_press_init, NULL, \
.usage_page = DT_INST_PROP(n, usage_page)}; \ NULL, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
static struct behavior_key_press_data behavior_key_press_data_##n; \ &behavior_key_press_driver_api);
DEVICE_AND_API_INIT(behavior_key_press_##n, DT_INST_LABEL(n), behavior_key_press_init, \
&behavior_key_press_data_##n, &behavior_key_press_config_##n, APPLICATION, \
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_key_press_driver_api);
DT_INST_FOREACH_STATUS_OKAY(KP_INST) DT_INST_FOREACH_STATUS_OKAY(KP_INST)

View file

@ -16,23 +16,14 @@
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
struct behavior_sensor_rotate_key_press_config {
u8_t usage_page;
};
struct behavior_sensor_rotate_key_press_data {};
static int behavior_sensor_rotate_key_press_init(struct device *dev) { return 0; }; static int behavior_sensor_rotate_key_press_init(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,
struct device *sensor) { struct device *sensor) {
struct device *dev = device_get_binding(binding->behavior_dev);
const struct behavior_sensor_rotate_key_press_config *cfg = dev->config_info;
struct sensor_value value; struct sensor_value value;
int err; int err;
u32_t keycode; u32_t keycode;
struct keycode_state_changed *ev; LOG_DBG("inc keycode 0x%02X dec keycode 0x%02X", binding->param1, binding->param2);
LOG_DBG("usage_page 0x%02X inc keycode 0x%02X dec keycode 0x%02X", cfg->usage_page,
binding->param1, binding->param2);
err = sensor_channel_get(sensor, SENSOR_CHAN_ROTATION, &value); err = sensor_channel_get(sensor, SENSOR_CHAN_ROTATION, &value);
@ -54,33 +45,21 @@ static int on_sensor_binding_triggered(struct zmk_behavior_binding *binding,
LOG_DBG("SEND %d", keycode); LOG_DBG("SEND %d", keycode);
ev = new_keycode_state_changed(); ZMK_EVENT_RAISE(keycode_state_changed_from_encoded(keycode, true));
ev->usage_page = cfg->usage_page;
ev->keycode = keycode;
ev->state = true;
ZMK_EVENT_RAISE(ev);
// TODO: Better way to do this? // TODO: Better way to do this?
k_msleep(5); k_msleep(5);
ev = new_keycode_state_changed(); return ZMK_EVENT_RAISE(keycode_state_changed_from_encoded(keycode, false));
ev->usage_page = cfg->usage_page;
ev->keycode = keycode;
ev->state = false;
return ZMK_EVENT_RAISE(ev);
} }
static const struct behavior_driver_api behavior_sensor_rotate_key_press_driver_api = { static const struct behavior_driver_api behavior_sensor_rotate_key_press_driver_api = {
.sensor_binding_triggered = on_sensor_binding_triggered}; .sensor_binding_triggered = on_sensor_binding_triggered};
#define KP_INST(n) \ #define KP_INST(n) \
static const struct behavior_sensor_rotate_key_press_config \ DEVICE_AND_API_INIT(behavior_sensor_rotate_key_press_##n, DT_INST_LABEL(n), \
behavior_sensor_rotate_key_press_config_##n = {.usage_page = DT_INST_PROP(n, usage_page)}; \ behavior_sensor_rotate_key_press_init, NULL, NULL, APPLICATION, \
static struct behavior_sensor_rotate_key_press_data behavior_sensor_rotate_key_press_data_##n; \ CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
DEVICE_AND_API_INIT( \ &behavior_sensor_rotate_key_press_driver_api);
behavior_sensor_rotate_key_press_##n, DT_INST_LABEL(n), \
behavior_sensor_rotate_key_press_init, &behavior_sensor_rotate_key_press_data_##n, \
&behavior_sensor_rotate_key_press_config_##n, APPLICATION, \
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_sensor_rotate_key_press_driver_api);
DT_INST_FOREACH_STATUS_OKAY(KP_INST) DT_INST_FOREACH_STATUS_OKAY(KP_INST)

View file

@ -46,22 +46,3 @@ Example:
``` ```
&kp A &kp A
``` ```
## Consumer Key Press
The "consumer key press" behavior allows you to send "consumer" usage page keycodes on press/release.
These are mostly used for media and power related keycodes, such as sending "Pause", "Scan Track Next",
"Scan Track Previous", etc.
There are a subset of the full consumer usage IDs found in the `keys.h` include, prefixed with `C_`, e.g. `C_PREV`.
### Behavior Binding
- Reference: `&cp`
- Parameter: The keycode usage ID from the consumer usage page, e.g. `C_PREV` or `C_EJECT`
Example:
```
&cp C_PREV
```

View file

@ -393,7 +393,6 @@ The two `#include` lines at the top of the keymap are required in order to bring
Further documentation on behaviors and bindings is forthcoming, but a summary of the current behaviors you can bind to key positions is as follows: Further documentation on behaviors and bindings is forthcoming, but a summary of the current behaviors you can bind to key positions is as follows:
- `kp` is the "key press" behavior, and takes a single binding argument of the HID keycode from the 'keyboard/keypad" HID usage table. - `kp` is the "key press" behavior, and takes a single binding argument of the HID keycode from the 'keyboard/keypad" HID usage table.
- `cp` is the "consumer key press" behavior, and takes a single binding argument of the HID keycode from the "consumer page" HID usage table. This is mostly useful for media keys.
- `mo` is the "momentary layer" behaviour, and takes a single binding argument of the numeric ID of the layer to momentarily enable when that key is held. - `mo` is the "momentary layer" behaviour, and takes a single binding argument of the numeric ID of the layer to momentarily enable when that key is held.
- `trans` is the "transparent" behavior, useful to be place in higher layers above `mo` bindings to be sure the key release is handled by the lower layer. No binding arguments are required. - `trans` is the "transparent" behavior, useful to be place in higher layers above `mo` bindings to be sure the key release is handled by the lower layer. No binding arguments are required.
- `mt` is the "mod-tap" behavior, and takes two binding arguments, the modifier to use if held, and the keycode to send if tapped. - `mt` is the "mod-tap" behavior, and takes two binding arguments, the modifier to use if held, and the keycode to send if tapped.

View file

@ -25,7 +25,7 @@ Rotation is handled separately as a type of sensor. The behavior for this is set
sensor-bindings = <BINDING CW_KEY CCW_KEY>; sensor-bindings = <BINDING CW_KEY CCW_KEY>;
``` ```
- `BINDING` is one of two rotation bindings that are currently defined, `&inc_dec_cp` for consumer key presses or `&inc_dec_kp` for normal key presses (see [Key Press](/docs/behavior/key-press) for the difference between the two). - `BINDING` is currently only the one implemented bindings; `&inc_dec` for key presses (see [Key Press](/docs/behavior/key-press) for details on available keycodes).
- `CW_KEY` is the keycode activated by a clockwise turn. - `CW_KEY` is the keycode activated by a clockwise turn.
- `CCW_KEY` is the keycode activated by a counter-clockwise turn. - `CCW_KEY` is the keycode activated by a counter-clockwise turn.
@ -34,7 +34,7 @@ Additional encoders can be configured by adding more `BINDING CW_KEY CCW_KEY` se
As an example, a complete `sensor-bindings` for a Kyria with two encoders could look like: As an example, a complete `sensor-bindings` for a Kyria with two encoders could look like:
``` ```
sensor-bindings = <&inc_dec_cp C_VOL_UP C_VOL_DN &inc_dec_kp PG_UP PG_DN>; sensor-bindings = <&inc_dec C_VOL_UP C_VOL_DN &inc_dec PG_UP PG_DN>;
``` ```
Here, the left encoder is configured to control volume up and down while the right encoder sends either Page Up or Page Down. Here, the left encoder is configured to control volume up and down while the right encoder sends either Page Up or Page Down.

View file

@ -22,7 +22,7 @@ ZMK is currently missing some features found in other popular firmware. This tab
| [Keymaps and Layers](behavior/layers) | ✅ | ✅ | ✅ | | [Keymaps and Layers](behavior/layers) | ✅ | ✅ | ✅ |
| [Hold-Tap](behavior/hold-tap) (which includes [Mod-Tap](behavior/mod-tap) and [Layer-Tap](behavior/layers/#layer-tap)) | ✅ | ✅ | ✅ | | [Hold-Tap](behavior/hold-tap) (which includes [Mod-Tap](behavior/mod-tap) and [Layer-Tap](behavior/layers/#layer-tap)) | ✅ | ✅ | ✅ |
| [Basic Keycodes](behavior/key-press) | ✅ | ✅ | ✅ | | [Basic Keycodes](behavior/key-press) | ✅ | ✅ | ✅ |
| [Basic consumer (Media) Keycodes](behavior/key-press#consumer-key-press) | ✅ | ✅ | ✅ | | [Basic consumer (Media) Keycodes](behavior/key-press) | ✅ | ✅ | ✅ |
| [Encoders](feature/encoders)[^1] | ✅ | | ✅ | | [Encoders](feature/encoders)[^1] | ✅ | | ✅ |
| [OLED Display Support](feature/displays)[^2] | 🚧 | 🚧 | ✅ | | [OLED Display Support](feature/displays)[^2] | 🚧 | 🚧 | ✅ |
| [RGB Underglow](feature/underglow) | ✅ | ✅ | ✅ | | [RGB Underglow](feature/underglow) | ✅ | ✅ | ✅ |