Skip to content

Commit af664cd

Browse files
committed
Merge branch 'newapi' into develop
2 parents 8b7fbbd + 04feeaa commit af664cd

File tree

4 files changed

+139
-33
lines changed

4 files changed

+139
-33
lines changed

common/action_layer.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ static void default_layer_state_set(uint32_t state)
2222
debug("default_layer_state: ");
2323
default_layer_debug(); debug(" to ");
2424
default_layer_state = state;
25+
hook_default_layer_change(default_layer_state);
2526
default_layer_debug(); debug("\n");
2627
clear_keyboard_but_mods(); // To avoid stuck keys
2728
}

common/hook.c

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,43 +19,31 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
1919
#include "hook.h"
2020

2121
/* -------------------------------------------------
22-
* Definitions of hardware-independent default hooks
22+
* Definitions of default hooks
2323
* ------------------------------------------------- */
2424

25-
/* Called on layer state change event. */
26-
/* Default behaviour: do nothing. */
2725
__attribute__((weak))
28-
void hook_layer_change(uint8_t layer_state) {
29-
(void)layer_state;
26+
void hook_keyboard_loop(void) {}
27+
28+
__attribute__((weak))
29+
void hook_matrix_change(keyevent_t event) {
30+
(void)event;
3031
}
3132

32-
/* Called periodically from the matrix scan loop (very often!) */
33-
/* Default behaviour: do nothing. */
3433
__attribute__((weak))
35-
void hook_keyboard_loop(void) {}
34+
void hook_default_layer_change(uint8_t layer_state) {
35+
(void)layer_state;
36+
}
3637

37-
/* Called on matrix state change event (every keypress => often!) */
38-
/* Default behaviour: do nothing. */
3938
__attribute__((weak))
40-
void hook_matrix_change(keyevent_t event) {
41-
(void)event;
39+
void hook_layer_change(uint8_t layer_state) {
40+
(void)layer_state;
4241
}
4342

44-
/* Called on indicator LED update event (when reported from host). */
45-
/* Default behaviour: calls led_set (for compatibility). */
4643
__attribute__((weak))
4744
void hook_keyboard_leds_change(uint8_t led_status) {
4845
keyboard_set_leds(led_status);
4946
}
5047

51-
/* Called once, on checking the bootmagic combos. */
52-
/* Default behaviour: do nothing. */
5348
__attribute__((weak))
54-
void hook_bootmagic(void) {
55-
/* An example: */
56-
// #include "bootmagic.h"
57-
// #include "keymap.h"
58-
// if(bootmagic_scan_keycode(KC_W)) {
59-
// // do something
60-
// }
61-
}
49+
void hook_bootmagic(void) {}

common/hook.h

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
2222
#include "led.h"
2323

2424
/* -------------------------------------
25-
* Hardware / one-off hooks
25+
* Protocol hooks
2626
* ------------------------------------- */
2727

28-
/* Called once, before initialising USB. */
28+
/* Called once, very early stage of initialization, just after processor startup. */
2929
/* Default behaviour: do nothing. */
3030
void hook_early_init(void);
3131

32-
/* Called once, after USB is connected and keyboard initialised. */
32+
/* Called once, very last stage of initialization, just before keyboard loop. */
3333
/* Default behaviour: do nothing. */
3434
void hook_late_init(void);
3535

@@ -47,12 +47,9 @@ void hook_usb_suspend_loop(void);
4747
* the "normal" indicator LED status by default. */
4848
void hook_usb_wakeup(void);
4949

50-
/* Called once, on checking the bootmagic combos. */
51-
/* Default behaviour: do nothing. */
52-
void hook_bootmagic(void);
5350

5451
/* -------------------------------------
55-
* Keyboard / periodic hooks
52+
* Keyboard hooks
5653
* ------------------------------------- */
5754

5855
/* Called periodically from the keyboard loop (very often!) */
@@ -63,12 +60,21 @@ void hook_keyboard_loop(void);
6360
/* Default behaviour: do nothing. */
6461
void hook_matrix_change(keyevent_t event);
6562

63+
/* Called on default layer state change event. */
64+
/* Default behaviour: do nothing. */
65+
void hook_default_layer_change(uint32_t default_layer_state);
66+
6667
/* Called on layer state change event. */
6768
/* Default behaviour: do nothing. */
68-
void hook_layer_change(uint8_t layer_state);
69+
void hook_layer_change(uint32_t layer_state);
6970

7071
/* Called on indicator LED update event (when reported from host). */
71-
/* Default behaviour: calls keyboard_set_leds (for compatibility). */
72+
/* Default behaviour: calls keyboard_set_leds. */
7273
void hook_keyboard_leds_change(uint8_t led_status);
7374

75+
/* Called once, on checking the bootmagic combos. */
76+
/* Default behaviour: do nothing. */
77+
void hook_bootmagic(void);
78+
79+
7480
#endif /* _HOOKS_H_ */

doc/hook.txt

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
Hooks
2+
-----
3+
Hooks allow you to execute custom code at certain predefined points in the firmware execution. To use them, just define the hook function in your keymap file.
4+
5+
The following hooks are available available:
6+
7+
Hook function | Timing
8+
--------------------------------|-----------------------------------------------
9+
`hook_early_init(void)` | Early in the boot process, before the matrix is initialized and before a connection is made with the host. Thus, this hook has access to very few parameters, but it is a good place to define any custom parameters needed by other early processes.
10+
`hook_late_init(void)` | Near the end of the boot process, after Boot Magic has run and LEDs have been initialized.
11+
`hook_bootmagic(void)` | During the Boot Magic window, after EEPROM and Bootloader checks are made, but before any other built-in Boot Magic checks are made.
12+
`hook_usb_wakeup(void)` | When the device wakes up from USB suspend state.
13+
`hook_usb_suspend_entry(void)` | When the device enters USB suspend state.
14+
`hook_usb_suspend_loop(void)` | Continuously, while the device is in USB suspend state. *Default action:* power down and periodically check the matrix, causing wakeup if needed.
15+
`hook_keyboard_loop(void)` | Continuously, during the main loop, after the matrix is checked.
16+
`hook_matrix_change(keyevent_t event)` | When a matrix state change is detected, before any other actions are processed.
17+
`hook_layer_change(uint32_t layer_state)` | When any layer is changed.
18+
`hook_default_layer_change(uint32_t default_layer_state)` | When any default layer is changed.
19+
`hook_keyboard_leds_change(uint8_t led_status)` | Whenever a change in the LED status is performed. *Default action:* call `keyboard_set_leds(led_status)`
20+
21+
22+
23+
24+
25+
### Hooks Examples
26+
27+
You can try these out by copying the code to your keymap file, or any .c file in the Makefile `SRC`.
28+
29+
#### Activate keymap layer 5 on startup
30+
31+
```C
32+
#include "action_layer.h"
33+
34+
void hook_late_init(void)
35+
{
36+
layer_on(5);
37+
print("Layer 5 enabled!");
38+
}
39+
```
40+
41+
#### Blink the Caps Lock LED every .5 seconds
42+
43+
```C
44+
#include "timer.h"
45+
#include "led.h"
46+
47+
bool my_led_status = 0;
48+
uint16_t my_led_timer;
49+
50+
void hook_keyboard_loop(void)
51+
{
52+
// check if we've reached 500 milliseconds yet...
53+
if (timer_elapsed(my_led_timer) > 500)
54+
{
55+
// we've reached 500 milliseconds!
56+
// reset the timer
57+
my_led_timer = timer_read();
58+
59+
// check the current LED state
60+
if (my_led_status)
61+
{
62+
// LED is on, so let's turn it off
63+
led_set(host_keyboard_leds() & ~(1<<USB_LED_CAPS_LOCK));
64+
my_led_status = 0;
65+
}
66+
else
67+
{
68+
// LED is off, so let's turn it on
69+
led_set(host_keyboard_leds() | (1<<USB_LED_CAPS_LOCK));
70+
my_led_status = 1;
71+
}
72+
}
73+
}
74+
```
75+
76+
#### Flash the Caps Lock LED for 20ms on every keypress
77+
```C
78+
include "timer.h"
79+
#include "led.h"
80+
81+
bool my_led_status = 0;
82+
uint16_t my_led_timer;
83+
84+
void hook_matrix_change(keyevent_t event)
85+
{
86+
// only flash LED for key press events, not key release events.
87+
if (event.pressed)
88+
{
89+
// check the current LED status and reverse it
90+
led_set(host_keyboard_leds() ^ (1<<USB_LED_CAPS_LOCK));
91+
92+
my_led_status = 1;
93+
my_led_timer = timer_read();
94+
}
95+
}
96+
97+
void hook_keyboard_loop(void)
98+
{
99+
if (my_led_status)
100+
{
101+
// check if we've reached 20 milliseconds yet...
102+
if (timer_elapsed(my_led_timer) > 50)
103+
{
104+
led_set(host_keyboard_leds());
105+
106+
my_led_status = 0;
107+
}
108+
}
109+
}
110+
111+
```

0 commit comments

Comments
 (0)