summaryrefslogtreecommitdiffstats
path: root/docs/custom_quantum_functions.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/custom_quantum_functions.md')
-rw-r--r--docs/custom_quantum_functions.md108
1 files changed, 75 insertions, 33 deletions
diff --git a/docs/custom_quantum_functions.md b/docs/custom_quantum_functions.md
index 7be82c650f..2d505b0751 100644
--- a/docs/custom_quantum_functions.md
+++ b/docs/custom_quantum_functions.md
@@ -90,68 +90,110 @@ keyrecord_t record {
# LED Control
-QMK provides methods to read the 5 LEDs defined as part of the HID spec:
+QMK provides methods to read 5 of the LEDs defined in the HID spec:
-* `USB_LED_NUM_LOCK`
-* `USB_LED_CAPS_LOCK`
-* `USB_LED_SCROLL_LOCK`
-* `USB_LED_COMPOSE`
-* `USB_LED_KANA`
+* Num Lock
+* Caps Lock
+* Scroll Lock
+* Compose
+* Kana
-These five constants correspond to the positional bits of the host LED state.
-There are two ways to get the host LED state:
+There are two ways to get the lock LED state:
-* by implementing `led_set_user()`
-* by calling `host_keyboard_leds()`
+* by implementing `bool led_update_kb(led_t led_state)` or `_user(led_t led_state)`; or
+* by calling `led_t host_keyboard_led_state()`
-## `led_set_user()`
+!> `host_keyboard_led_state()` may already reflect a new value before `led_update_user()` is called.
-This function will be called when the state of one of those 5 LEDs changes. It receives the LED state as a parameter.
-Use the `IS_LED_ON(usb_led, led_name)` and `IS_LED_OFF(usb_led, led_name)` macros to check the LED status.
+Two more deprecated functions exist that provide the LED state as a `uint8_t`:
-!> `host_keyboard_leds()` may already reflect a new value before `led_set_user()` is called.
+* `uint8_t led_set_kb(uint8_t usb_led)` and `_user(uint8_t usb_led)`
+* `uint8_t host_keyboard_leds()`
-### Example `led_set_user()` Implementation
+## `led_update_user()`
+
+This function will be called when the state of one of those 5 LEDs changes. It receives the LED state as a struct parameter.
+
+You must return either `true` or `false` from this function, depending on whether you want to override the keyboard-level implementation.
+
+?> Because the `led_set_*` functions return `void` instead of `bool`, they do not allow for overriding the keyboard LED control, and thus it's recommended to use `led_update_*` instead.
+
+### Example `led_update_kb()` Implementation
+
+```c
+bool led_update_kb(led_t led_state) {
+ if(led_update_user(led_state)) {
+ if (led_state.num_lock) {
+ writePinLow(B0);
+ } else {
+ writePinHigh(B0);
+ }
+ if (led_state.caps_lock) {
+ writePinLow(B1);
+ } else {
+ writePinHigh(B1);
+ }
+ if (led_state.scroll_lock) {
+ writePinLow(B2);
+ } else {
+ writePinHigh(B2);
+ }
+ if (led_state.compose) {
+ writePinLow(B3);
+ } else {
+ writePinHigh(B3);
+ }
+ if (led_state.kana) {
+ writePinLow(B4);
+ } else {
+ writePinHigh(B4);
+ }
+ return true;
+ }
+}
+```
+
+### Example `led_update_user()` Implementation
```c
-void led_set_user(uint8_t usb_led) {
- if (IS_LED_ON(usb_led, USB_LED_NUM_LOCK)) {
+bool led_update_user(led_t led_state) {
+ if (led_state.num_lock) {
writePinLow(B0);
} else {
writePinHigh(B0);
}
- if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK)) {
+ if (led_state.caps_lock) {
writePinLow(B1);
} else {
writePinHigh(B1);
}
- if (IS_LED_ON(usb_led, USB_LED_SCROLL_LOCK)) {
+ if (led_state.scroll_lock) {
writePinLow(B2);
} else {
writePinHigh(B2);
}
- if (IS_LED_ON(usb_led, USB_LED_COMPOSE)) {
+ if (led_state.compose) {
writePinLow(B3);
} else {
writePinHigh(B3);
}
- if (IS_LED_ON(usb_led, USB_LED_KANA)) {
+ if (led_state.kana) {
writePinLow(B4);
} else {
writePinHigh(B4);
}
+ return true;
}
```
-### `led_set_*` Function Documentation
+### `led_update_*` Function Documentation
-* Keyboard/Revision: `void led_set_kb(uint8_t usb_led)`
-* Keymap: `void led_set_user(uint8_t usb_led)`
+* Keyboard/Revision: `bool led_update_kb(led_t led_state)`
+* Keymap: `bool led_update_user(led_t led_state)`
-## `host_keyboard_leds()`
+## `host_keyboard_led_state()`
-Call this function to get the last received LED state. This is useful for reading the LED state outside `led_set_*`, e.g. in [`matrix_scan_user()`](#matrix-scanning-code).
-For convenience, you can use the `IS_HOST_LED_ON(led_name)` and `IS_HOST_LED_OFF(led_name)` macros instead of calling and checking `host_keyboard_leds()` directly.
+Call this function to get the last received LED state as a `led_t`. This is useful for reading the LED state outside `led_update_*`, e.g. in [`matrix_scan_user()`](#matrix-scanning-code).
## Setting Physical LED State
@@ -297,8 +339,8 @@ This runs code every time that the layers get changed. This can be useful for l
This example shows how to set the [RGB Underglow](feature_rgblight.md) lights based on the layer, using the Planck as an example
```c
-uint32_t layer_state_set_user(uint32_t state) {
- switch (biton32(state)) {
+layer_state_t layer_state_set_user(layer_state_t state) {
+ switch (get_highest_layer(state)) {
case _RAISE:
rgblight_setrgb (0x00, 0x00, 0xFF);
break;
@@ -320,8 +362,8 @@ uint32_t layer_state_set_user(uint32_t state) {
```
### `layer_state_set_*` Function Documentation
-* Keyboard/Revision: `uint32_t layer_state_set_kb(uint32_t state)`
-* Keymap: `uint32_t layer_state_set_user(uint32_t state)`
+* Keyboard/Revision: `layer_state_t layer_state_set_kb(layer_state_t state)`
+* Keymap: `layer_state_t layer_state_set_user(layer_state_t state)`
The `state` is the bitmask of the active layers, as explained in the [Keymap Overview](keymap.md#keymap-layer-status)
@@ -377,8 +419,8 @@ void keyboard_post_init_user(void) {
The above function will use the EEPROM config immediately after reading it, to set the default layer's RGB color. The "raw" value of it is converted in a usable structure based on the "union" that you created above.
```c
-uint32_t layer_state_set_user(uint32_t state) {
- switch (biton32(state)) {
+layer_state_t layer_state_set_user(layer_state_t state) {
+ switch (get_highest_layer(state)) {
case _RAISE:
if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_magenta(); rgblight_mode_noeeprom(1); }
break;