aboutsummaryrefslogtreecommitdiff
path: root/common/action_util.c
diff options
context:
space:
mode:
authortmk <nobody@nowhere>2013-10-04 03:30:09 +0900
committertmk <nobody@nowhere>2013-10-04 16:04:31 +0900
commitd52d554360d3bf06189bfd4f386fa99348d8a0a8 (patch)
treeb05d27552402f371e61aa0f29906a60c87e213ad /common/action_util.c
parentcb434cfebc607db15b52a42adae6423bd40f1f98 (diff)
downloadqmk_firmware-d52d554360d3bf06189bfd4f386fa99348d8a0a8.tar.gz
qmk_firmware-d52d554360d3bf06189bfd4f386fa99348d8a0a8.zip
Fix mod stuck of MODS_KEY when leaving layer #62
- Add action_util.c and remove action_oneshot.c - Add oneshot_mods for MODS_ONESHOT - Add weak_mods for MODS_KEY and MACRO - weak_mods is cleared when layer switching
Diffstat (limited to 'common/action_util.c')
-rw-r--r--common/action_util.c192
1 files changed, 192 insertions, 0 deletions
diff --git a/common/action_util.c b/common/action_util.c
new file mode 100644
index 000000000..50d686a07
--- /dev/null
+++ b/common/action_util.c
@@ -0,0 +1,192 @@
1/*
2Copyright 2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17#include "host.h"
18#include "report.h"
19#include "debug.h"
20#include "action_util.h"
21
22static inline void add_key_byte(uint8_t code);
23static inline void del_key_byte(uint8_t code);
24#ifdef NKRO_ENABLE
25static inline void add_key_bit(uint8_t code);
26static inline void del_key_bit(uint8_t code);
27#endif
28
29static uint8_t real_mods = 0;
30static uint8_t weak_mods = 0;
31
32
33// TODO: pointer variable is not needed
34//report_keyboard_t keyboard_report = {};
35report_keyboard_t *keyboard_report = &(report_keyboard_t){};
36
37#ifndef NO_ACTION_ONESHOT
38static bool oneshot_enabled = true;
39static int8_t oneshot_mods = 0;
40#endif
41
42void send_keyboard_report(void) {
43 keyboard_report->mods = real_mods;
44 keyboard_report->mods |= weak_mods;
45#ifndef NO_ACTION_ONESHOT
46 keyboard_report->mods |= oneshot_mods;
47 if (has_anykey()) {
48 clear_oneshot_mods();
49 }
50#endif
51 host_keyboard_send(keyboard_report);
52}
53
54/* key */
55void add_key(uint8_t key)
56{
57#ifdef NKRO_ENABLE
58 if (keyboard_nkro) {
59 add_key_bit(key);
60 return;
61 }
62#endif
63 add_key_byte(key);
64}
65
66void del_key(uint8_t key)
67{
68#ifdef NKRO_ENABLE
69 if (keyboard_nkro) {
70 del_key_bit(key);
71 return;
72 }
73#endif
74 del_key_byte(key);
75}
76
77void clear_keys(void)
78{
79 // not clear mods
80 for (int8_t i = 1; i < REPORT_SIZE; i++) {
81 keyboard_report->raw[i] = 0;
82 }
83}
84
85
86/* modifier */
87uint8_t get_mods(void) { return real_mods; }
88void add_mods(uint8_t mods) { real_mods |= mods; }
89void del_mods(uint8_t mods) { real_mods &= ~mods; }
90void set_mods(uint8_t mods) { real_mods = mods; }
91void clear_mods(void) { real_mods = 0; }
92
93/* weak modifier */
94uint8_t get_weak_mods(void) { return weak_mods; }
95void add_weak_mods(uint8_t mods) { weak_mods |= mods; }
96void del_weak_mods(uint8_t mods) { weak_mods &= ~mods; }
97void set_weak_mods(uint8_t mods) { weak_mods = mods; }
98void clear_weak_mods(void) { weak_mods = 0; }
99
100/* Oneshot modifier */
101#ifndef NO_ACTION_ONESHOT
102void set_oneshot_mods(uint8_t mods) { oneshot_mods = mods; }
103void clear_oneshot_mods(void) { oneshot_mods = 0; }
104void oneshot_toggle(void) { oneshot_enabled = !oneshot_enabled; }
105void oneshot_enable(void) { oneshot_enabled = true; }
106void oneshot_disable(void) { oneshot_enabled = false; }
107#endif
108
109
110
111
112/*
113 * inspect keyboard state
114 */
115uint8_t has_anykey(void)
116{
117 uint8_t cnt = 0;
118 for (uint8_t i = 1; i < REPORT_SIZE; i++) {
119 if (keyboard_report->raw[i])
120 cnt++;
121 }
122 return cnt;
123}
124
125uint8_t has_anymod(void)
126{
127 return bitpop(real_mods);
128}
129
130uint8_t get_first_key(void)
131{
132#ifdef NKRO_ENABLE
133 if (keyboard_nkro) {
134 uint8_t i = 0;
135 for (; i < REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
136 ;
137 return i<<3 | biton(keyboard_report->nkro.bits[i]);
138 }
139#endif
140 return keyboard_report->keys[0];
141}
142
143
144
145/* local functions */
146static inline void add_key_byte(uint8_t code)
147{
148 int8_t i = 0;
149 int8_t empty = -1;
150 for (; i < REPORT_KEYS; i++) {
151 if (keyboard_report->keys[i] == code) {
152 break;
153 }
154 if (empty == -1 && keyboard_report->keys[i] == 0) {
155 empty = i;
156 }
157 }
158 if (i == REPORT_KEYS) {
159 if (empty != -1) {
160 keyboard_report->keys[empty] = code;
161 }
162 }
163}
164
165static inline void del_key_byte(uint8_t code)
166{
167 for (uint8_t i = 0; i < REPORT_KEYS; i++) {
168 if (keyboard_report->keys[i] == code) {
169 keyboard_report->keys[i] = 0;
170 }
171 }
172}
173
174#ifdef NKRO_ENABLE
175static inline void add_key_bit(uint8_t code)
176{
177 if ((code>>3) < REPORT_BITS) {
178 keyboard_report->nkro.bits[code>>3] |= 1<<(code&7);
179 } else {
180 dprintf("add_key_bit: can't add: %02X\n", code);
181 }
182}
183
184static inline void del_key_bit(uint8_t code)
185{
186 if ((code>>3) < REPORT_BITS) {
187 keyboard_report->nkro.bits[code>>3] &= ~(1<<(code&7));
188 } else {
189 dprintf("del_key_bit: can't del: %02X\n", code);
190 }
191}
192#endif