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
parent 5f83568a93
commit eff1b8223b
20 changed files with 474 additions and 492 deletions

View File

@ -3,17 +3,10 @@
/ {
behaviors {
kp: behavior_key_press {
/* DEPRECATED: `cp` will be removed in the future */
cp: kp: behavior_key_press {
compatible = "zmk,behavior-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>;
};
};

View File

@ -3,17 +3,10 @@
/ {
behaviors {
inc_dec_kp: behavior_sensor_rotate_key_press {
/* DEPRECATED: `inc_dec_cp` will be removed in the future */
inc_dec_cp: inc_dec_kp: behavior_sensor_rotate_key_press {
compatible = "zmk,behavior-sensor-rotate-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>;
};
};

View File

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

View File

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

View File

@ -10,6 +10,10 @@
#pragma once
#define HID_EXT_USAGE(page, id) ((page << 16) | id)
#define HID_EXT_USAGE_ID(ext) (ext & 0xFFFF)
#define HID_EXT_USAGE_PAGE(ext) (ext >> 16)
/* WARNING: DEPRECATED from dt-bindings/zmk/keys.h */
#define USAGE_KEYPAD (0x07) // WARNING: DEPRECATED (DO NOT USE)
#define USAGE_CONSUMER (0x0C) // WARNING: DEPRECATED (DO NOT USE)

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,9 @@
#include <zephyr.h>
#include <dt-bindings/zmk/modifiers.h>
#include <dt-bindings/zmk/hid_usage_pages.h>
#include <zmk/event-manager.h>
#include <zmk/keys.h>
struct keycode_state_changed {
struct zmk_event_header header;
@ -20,12 +22,20 @@ struct keycode_state_changed {
ZMK_EVENT_DECLARE(keycode_state_changed);
static inline struct keycode_state_changed *
create_keycode_state_changed(u8_t usage_page, u32_t keycode, bool state) {
static inline struct keycode_state_changed *keycode_state_changed_from_encoded(u32_t encoded,
bool pressed) {
u16_t page = HID_EXT_USAGE_PAGE(encoded) & 0xFF;
u16_t id = HID_EXT_USAGE_ID(encoded);
zmk_mod_flags implicit_mods = SELECT_MODS(encoded);
if (!page) {
page = HID_USAGE_KEY;
}
struct keycode_state_changed *ev = new_keycode_state_changed();
ev->usage_page = usage_page;
ev->keycode = STRIP_MODS(keycode);
ev->implicit_modifiers = SELECT_MODS(keycode);
ev->state = state;
ev->usage_page = page;
ev->keycode = id;
ev->implicit_modifiers = implicit_mods;
ev->state = pressed;
return ev;
}

View File

@ -429,8 +429,8 @@ static int position_state_changed_listener(const struct zmk_event_header *eh) {
}
static inline bool only_mods(struct keycode_state_changed *ev) {
return ev->usage_page == HID_USAGE_KEY && ev->keycode >= LEFT_CONTROL &&
ev->keycode <= RIGHT_GUI;
return ev->usage_page == HID_USAGE_KEY && ev->keycode >= HID_USAGE_KEY_KEYBOARD_LEFTCONTROL &&
ev->keycode <= HID_USAGE_KEY_KEYBOARD_RIGHT_GUI;
}
static int keycode_state_changed_listener(const struct zmk_event_header *eh) {

View File

@ -16,42 +16,28 @@
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 on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
struct zmk_behavior_binding_event event) {
struct device *dev = device_get_binding(binding->behavior_dev);
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);
LOG_DBG("position %d keycode 0x%02X", event.position, 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,
struct zmk_behavior_binding_event event) {
struct device *dev = device_get_binding(binding->behavior_dev);
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);
LOG_DBG("position %d keycode 0x%02X", event.position, 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 = {
.binding_pressed = on_keymap_binding_pressed, .binding_released = on_keymap_binding_released};
#define KP_INST(n) \
static const struct behavior_key_press_config behavior_key_press_config_##n = { \
.usage_page = DT_INST_PROP(n, usage_page)}; \
static struct behavior_key_press_data behavior_key_press_data_##n; \
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);
DEVICE_AND_API_INIT(behavior_key_press_##n, DT_INST_LABEL(n), behavior_key_press_init, NULL, \
NULL, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
&behavior_key_press_driver_api);
DT_INST_FOREACH_STATUS_OKAY(KP_INST)

View File

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

View File

@ -9,6 +9,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#include <zmk/hid.h>
#include <dt-bindings/zmk/modifiers.h>
#include <dt-bindings/zmk/hid_usage_pages.h>
static struct zmk_hid_keypad_report kp_report = {
.report_id = 1, .body = {.modifiers = 0, ._reserved = 0, .keys = {0}}};
@ -78,16 +79,16 @@ int zmk_hid_implicit_modifiers_release() {
}
int zmk_hid_keypad_press(zmk_key code) {
if (code >= LEFT_CONTROL && code <= RIGHT_GUI) {
return zmk_hid_register_mod(code - LEFT_CONTROL);
if (code >= HID_USAGE_KEY_KEYBOARD_LEFTCONTROL && code <= HID_USAGE_KEY_KEYBOARD_RIGHT_GUI) {
return zmk_hid_register_mod(code - HID_USAGE_KEY_KEYBOARD_LEFTCONTROL);
}
TOGGLE_KEYPAD(0U, code);
return 0;
};
int zmk_hid_keypad_release(zmk_key code) {
if (code >= LEFT_CONTROL && code <= RIGHT_GUI) {
return zmk_hid_unregister_mod(code - LEFT_CONTROL);
if (code >= HID_USAGE_KEY_KEYBOARD_LEFTCONTROL && code <= HID_USAGE_KEY_KEYBOARD_RIGHT_GUI) {
return zmk_hid_unregister_mod(code - HID_USAGE_KEY_KEYBOARD_LEFTCONTROL);
}
TOGGLE_KEYPAD(code, 0U);
return 0;

View File

@ -10,7 +10,7 @@
default_layer {
bindings = <
&kp B &none
&cp C_NEXT &none>;
&kp C_NEXT &none>;
};
};
};

View File

@ -15,7 +15,7 @@
lower_layer {
bindings = <
&cp C_NEXT &trans
&kp C_NEXT &trans
&kp L &kp J>;
};

View File

@ -15,7 +15,7 @@
lower_layer {
bindings = <
&cp C_NEXT &trans
&kp C_NEXT &trans
&kp L &kp J>;
};

View File

@ -62,7 +62,7 @@ A code example which configures a mod-tap setting that works with homerow mods:
If this config does not work for you, try the flavor "tap-preferred" and a short tapping_term_ms such as 120ms.
If you want to use a tap-hold with a keycode from a different code page, you have to define another behavior with another "bindings" parameter.For example, if you want to use SHIFT and volume up, define the bindings like `bindings = <&kp>, <&cp>;`. Only single-argument behaviors are supported at the moment.
If you want to use a tap-hold with a keycode from a different code page, you have to define another behavior with another "bindings" parameter.For example, if you want to use SHIFT and volume up, define the bindings like `bindings = <&kp>, <&kp>;`. Only single-argument behaviors are supported at the moment.
#### Comparison to QMK

View File

@ -46,22 +46,3 @@ Example:
```
&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

@ -377,7 +377,7 @@ Here is an example simple keymap for the Kyria, with only one layer:
&kp LGUI &kp DEL &kp RET &kp SPACE &kp ESC &kp RET &kp SPACE &kp TAB &kp BSPC &kp RALT
>;
sensor-bindings = <&inc_dec_cp C_VOL_UP C_VOL_DN &inc_dec_kp PG_UP PG_DN>;
sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN &inc_dec_kp PG_UP PG_DN>;
};
};
};
@ -385,15 +385,14 @@ Here is an example simple keymap for the Kyria, with only one layer:
```
:::note
The two `#include` lines at the top of the keymap are required in order to bring in the default set of behaviors to make them available to bind, and to import a set of defines for the HID keycodes, so keymaps can use parameters like `N2` or `K` instead of the raw keycode numeric values.
The two `#include` lines at the top of the keymap are required in order to bring in the default set of behaviors to make them available to bind, and to import a set of defines for the key codes, so keymaps can use parameters like `N2` or `K` instead of the raw keycode numeric values.
:::
### Keymap Behaviors
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.
- `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.
- `kp` is the "key press" behavior, and takes a single binding argument of the key code from the 'keyboard/keypad" HID usage table.
- `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.
- `mt` is the "mod-tap" behavior, and takes two binding arguments, the modifier to use if held, and the keycode to send if tapped.
@ -476,7 +475,7 @@ For split keyboards, make sure to add left hand encoders to the left .overlay fi
Add the following line to your keymap file to add default encoder behavior bindings:
```
sensor-bindings = <&inc_dec_cp C_VOL_UP C_VOL_DN>;
sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN>;
```
Add additional bindings as necessary to match the default number of encoders on your board. See the [Encoders](/docs/feature/encoders) and [Keymap](/docs/feature/keymaps) feature documentation for more details.

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>;
```
- `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`, for now, has only one behavior available; `&inc_dec_kp` 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.
- `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:
```
sensor-bindings = <&inc_dec_cp C_VOL_UP C_VOL_DN &inc_dec_kp PG_UP PG_DN>;
sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN &inc_dec_kp 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.

View File

@ -139,7 +139,7 @@ that defines just one layer for this keymap:
&kp LGUI &kp DEL &kp RET &kp SPACE &kp ESC &kp RET &kp SPACE &kp TAB &kp BSPC &kp RALT
>;
sensor-bindings = <&inc_dec_cp C_VOL_UP C_VOL_DN &inc_dec_kp PG_UP PG_DN>;
sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN &inc_dec_kp PG_UP PG_DN>;
};
};
```
@ -176,7 +176,7 @@ Putting this all together, a complete [`kyria.keymap`](https://github.com/zmkfir
&kp LGUI &kp DEL &kp RET &kp SPACE &kp ESC &kp RET &kp SPACE &kp TAB &kp BSPC &kp RALT
>;
sensor-bindings = <&inc_dec_cp C_VOL_UP C_VOL_DN &inc_dec_kp PG_UP PG_DN>;
sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN &inc_dec_kp PG_UP PG_DN>;
};
};
};

View File

@ -22,7 +22,7 @@ ZMK is currently missing some features found in other popular firmware. This tab
| [Keymaps and Layers](behavior/layers) | ✅ | ✅ | ✅ |
| [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 consumer (Media) Keycodes](behavior/key-press#consumer-key-press) | ✅ | ✅ | ✅ |
| [Basic consumer (Media) Keycodes](behavior/key-press) | ✅ | ✅ | ✅ |
| [Encoders](feature/encoders)[^1] | ✅ | | ✅ |
| [OLED Display Support](feature/displays)[^2] | 🚧 | 🚧 | ✅ |
| [RGB Underglow](feature/underglow) | ✅ | ✅ | ✅ |