diff options
Diffstat (limited to 'tmk_core/common/action_util.c')
-rw-r--r-- | tmk_core/common/action_util.c | 70 |
1 files changed, 66 insertions, 4 deletions
diff --git a/tmk_core/common/action_util.c b/tmk_core/common/action_util.c index a2d6577b2..61ff202be 100644 --- a/tmk_core/common/action_util.c +++ b/tmk_core/common/action_util.c | |||
@@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
18 | #include "report.h" | 18 | #include "report.h" |
19 | #include "debug.h" | 19 | #include "debug.h" |
20 | #include "action_util.h" | 20 | #include "action_util.h" |
21 | #include "action_layer.h" | ||
21 | #include "timer.h" | 22 | #include "timer.h" |
22 | 23 | ||
23 | static inline void add_key_byte(uint8_t code); | 24 | static inline void add_key_byte(uint8_t code); |
@@ -47,11 +48,70 @@ report_keyboard_t *keyboard_report = &(report_keyboard_t){}; | |||
47 | 48 | ||
48 | #ifndef NO_ACTION_ONESHOT | 49 | #ifndef NO_ACTION_ONESHOT |
49 | static int8_t oneshot_mods = 0; | 50 | static int8_t oneshot_mods = 0; |
51 | static int8_t oneshot_locked_mods = 0; | ||
52 | int8_t get_oneshot_locked_mods(void) { return oneshot_locked_mods; } | ||
53 | void set_oneshot_locked_mods(int8_t mods) { oneshot_locked_mods = mods; } | ||
54 | void clear_oneshot_locked_mods(void) { oneshot_locked_mods = 0; } | ||
50 | #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | 55 | #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) |
51 | static int16_t oneshot_time = 0; | 56 | static int16_t oneshot_time = 0; |
57 | inline bool has_oneshot_mods_timed_out() { | ||
58 | return TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT; | ||
59 | } | ||
52 | #endif | 60 | #endif |
53 | #endif | 61 | #endif |
54 | 62 | ||
63 | /* oneshot layer */ | ||
64 | #ifndef NO_ACTION_ONESHOT | ||
65 | /* oneshot_layer_data bits | ||
66 | * LLLL LSSS | ||
67 | * where: | ||
68 | * L => are layer bits | ||
69 | * S => oneshot state bits | ||
70 | */ | ||
71 | static int8_t oneshot_layer_data = 0; | ||
72 | |||
73 | inline uint8_t get_oneshot_layer(void) { return oneshot_layer_data >> 3; } | ||
74 | inline uint8_t get_oneshot_layer_state(void) { return oneshot_layer_data & 0b111; } | ||
75 | |||
76 | #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
77 | static int16_t oneshot_layer_time = 0; | ||
78 | inline bool has_oneshot_layer_timed_out() { | ||
79 | return TIMER_DIFF_16(timer_read(), oneshot_layer_time) >= ONESHOT_TIMEOUT && | ||
80 | !(get_oneshot_layer_state() & ONESHOT_TOGGLED); | ||
81 | } | ||
82 | #endif | ||
83 | |||
84 | /* Oneshot layer */ | ||
85 | void set_oneshot_layer(uint8_t layer, uint8_t state) | ||
86 | { | ||
87 | oneshot_layer_data = layer << 3 | state; | ||
88 | layer_on(layer); | ||
89 | #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
90 | oneshot_layer_time = timer_read(); | ||
91 | #endif | ||
92 | } | ||
93 | void reset_oneshot_layer(void) { | ||
94 | oneshot_layer_data = 0; | ||
95 | #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
96 | oneshot_layer_time = 0; | ||
97 | #endif | ||
98 | } | ||
99 | void clear_oneshot_layer_state(oneshot_fullfillment_t state) | ||
100 | { | ||
101 | uint8_t start_state = oneshot_layer_data; | ||
102 | oneshot_layer_data &= ~state; | ||
103 | if (!get_oneshot_layer_state() && start_state != oneshot_layer_data) { | ||
104 | layer_off(get_oneshot_layer()); | ||
105 | #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
106 | oneshot_layer_time = 0; | ||
107 | #endif | ||
108 | } | ||
109 | } | ||
110 | bool is_oneshot_layer_active(void) | ||
111 | { | ||
112 | return get_oneshot_layer_state(); | ||
113 | } | ||
114 | #endif | ||
55 | 115 | ||
56 | void send_keyboard_report(void) { | 116 | void send_keyboard_report(void) { |
57 | keyboard_report->mods = real_mods; | 117 | keyboard_report->mods = real_mods; |
@@ -60,7 +120,7 @@ void send_keyboard_report(void) { | |||
60 | #ifndef NO_ACTION_ONESHOT | 120 | #ifndef NO_ACTION_ONESHOT |
61 | if (oneshot_mods) { | 121 | if (oneshot_mods) { |
62 | #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | 122 | #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) |
63 | if (TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT) { | 123 | if (has_oneshot_mods_timed_out()) { |
64 | dprintf("Oneshot: timeout\n"); | 124 | dprintf("Oneshot: timeout\n"); |
65 | clear_oneshot_mods(); | 125 | clear_oneshot_mods(); |
66 | } | 126 | } |
@@ -70,6 +130,7 @@ void send_keyboard_report(void) { | |||
70 | clear_oneshot_mods(); | 130 | clear_oneshot_mods(); |
71 | } | 131 | } |
72 | } | 132 | } |
133 | |||
73 | #endif | 134 | #endif |
74 | host_keyboard_send(keyboard_report); | 135 | host_keyboard_send(keyboard_report); |
75 | } | 136 | } |
@@ -143,11 +204,12 @@ void clear_oneshot_mods(void) | |||
143 | oneshot_time = 0; | 204 | oneshot_time = 0; |
144 | #endif | 205 | #endif |
145 | } | 206 | } |
207 | uint8_t get_oneshot_mods(void) | ||
208 | { | ||
209 | return oneshot_mods; | ||
210 | } | ||
146 | #endif | 211 | #endif |
147 | 212 | ||
148 | |||
149 | |||
150 | |||
151 | /* | 213 | /* |
152 | * inspect keyboard state | 214 | * inspect keyboard state |
153 | */ | 215 | */ |