]> git.donarmstrong.com Git - tmk_firmware.git/blob - common/layer_stack.c
07c84870c6b0366f2fa6485cbb023e8e44118e13
[tmk_firmware.git] / common / layer_stack.c
1 #include <stdint.h>
2 #include "keyboard.h"
3 #include "layer_stack.h"
4 #include "debug.h"
5
6
7 static uint8_t top_layer = 0;
8
9 /* [0] always works as sentinel and not used for store.*/
10 static layer_item_t layer_stack[LAYER_STACK_SIZE] = {};
11
12 bool layer_stack_push(uint8_t layer)
13 {
14     for (uint8_t i = 1; i < LAYER_STACK_SIZE; i++) {
15         if (!layer_stack[i].used) {
16             layer_stack[i] = (layer_item_t){ .layer = layer,
17                                               .next = top_layer,
18                                               .used = true };
19             top_layer = i;
20             return true;
21         }
22     }
23     return false;
24 }
25
26 bool layer_stack_pop(void)
27 {
28     if (layer_stack[top_layer].used) {
29         uint8_t popped = top_layer;
30         top_layer = layer_stack[popped].next;
31         layer_stack[popped] = (layer_item_t){};
32         return true;
33     }
34     return false;
35 }
36
37 bool layer_stack_remove(uint8_t layer)
38 {
39     if (layer_stack[top_layer].used && layer_stack[top_layer].layer == layer) {
40         layer_stack_pop();
41         debug("layer_stack_remove: top_layer\n");
42         return true;
43     }
44
45     for (uint8_t i = top_layer; layer_stack[i].used; i = layer_stack[i].next) {
46         debug("layer_stack_remove: ["); debug_dec(i); debug("]");
47         debug_dec(layer_stack[i].layer); debug("\n");
48         uint8_t removed = layer_stack[i].next;
49         if (layer_stack[removed].used && layer_stack[removed].layer == layer) {
50             layer_stack[i].next = layer_stack[removed].next;
51             layer_stack[removed] = (layer_item_t){};
52             debug("layer_stack_remove: removed.\n");
53             return true;
54         }
55     }
56     return false;
57 }
58
59 bool layer_stack_remove_then_push(uint8_t layer)
60 {
61     layer_stack_remove(layer);
62     return layer_stack_push(layer);
63 }
64
65 bool layer_stack_remove_or_push(uint8_t layer)
66 {
67     return (layer_stack_remove(layer)) || layer_stack_push(layer);
68 }
69
70 void layer_stack_debug(void)
71 {
72     debug("layer_stack: ");
73     layer_item_t item = layer_stack[top_layer];
74     while (item.used) {
75         debug_dec(item.layer);
76         debug("["); debug_dec(item.next); debug("]");
77         item = layer_stack[item.next];
78     }
79     debug("\n");
80 }
81
82
83
84 action_t layer_stack_get_action(key_t key)
85 {
86     action_t action;
87     action.code = ACTION_TRANSPARENT;
88
89     /* layer stack */
90     for (layer_item_t i = layer_stack[top_layer]; i.used; i = layer_stack[i.next]) {
91         action = action_for_key(i.layer, key);
92         if (action.code != ACTION_TRANSPARENT) {
93             layer_stack_debug();
94             debug("layer_stack: used. "); debug_dec(i.layer); debug("\n");
95             return action;
96         }
97         debug("layer_stack: through. "); debug_dec(i.layer); debug("\n");
98     }
99     return action;
100 }