]> git.donarmstrong.com Git - qmk_firmware.git/blob - tmk_core/common/report.c
Generate API docs from source code comments (#2491)
[qmk_firmware.git] / tmk_core / common / report.c
1 /* Copyright 2017 Fred Sundvik
2  *
3  * This program is free software: you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation, either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  */
16
17 #include "report.h"
18 #include "host.h"
19 #include "keycode_config.h"
20 #include "debug.h"
21 #include "util.h"
22
23 /** \brief has_anykey
24  *
25  * FIXME: Needs doc
26  */
27 uint8_t has_anykey(report_keyboard_t* keyboard_report)
28 {
29     uint8_t cnt = 0;
30     for (uint8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) {
31         if (keyboard_report->raw[i])
32             cnt++;
33     }
34     return cnt;
35 }
36
37 /** \brief get_first_key
38  *
39  * FIXME: Needs doc
40  */
41 uint8_t get_first_key(report_keyboard_t* keyboard_report)
42 {
43 #ifdef NKRO_ENABLE
44     if (keyboard_protocol && keymap_config.nkro) {
45         uint8_t i = 0;
46         for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
47             ;
48         return i<<3 | biton(keyboard_report->nkro.bits[i]);
49     }
50 #endif
51 #ifdef USB_6KRO_ENABLE
52     uint8_t i = cb_head;
53     do {
54         if (keyboard_report->keys[i] != 0) {
55             break;
56         }
57         i = RO_INC(i);
58     } while (i != cb_tail);
59     return keyboard_report->keys[i];
60 #else
61     return keyboard_report->keys[0];
62 #endif
63 }
64
65 /** \brief add key byte
66  *
67  * FIXME: Needs doc
68  */
69 void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code)
70 {
71 #ifdef USB_6KRO_ENABLE
72     int8_t i = cb_head;
73     int8_t empty = -1;
74     if (cb_count) {
75         do {
76             if (keyboard_report->keys[i] == code) {
77                 return;
78             }
79             if (empty == -1 && keyboard_report->keys[i] == 0) {
80                 empty = i;
81             }
82             i = RO_INC(i);
83         } while (i != cb_tail);
84         if (i == cb_tail) {
85             if (cb_tail == cb_head) {
86                 // buffer is full
87                 if (empty == -1) {
88                     // pop head when has no empty space
89                     cb_head = RO_INC(cb_head);
90                     cb_count--;
91                 }
92                 else {
93                     // left shift when has empty space
94                     uint8_t offset = 1;
95                     i = RO_INC(empty);
96                     do {
97                         if (keyboard_report->keys[i] != 0) {
98                             keyboard_report->keys[empty] = keyboard_report->keys[i];
99                             keyboard_report->keys[i] = 0;
100                             empty = RO_INC(empty);
101                         }
102                         else {
103                             offset++;
104                         }
105                         i = RO_INC(i);
106                     } while (i != cb_tail);
107                     cb_tail = RO_SUB(cb_tail, offset);
108                 }
109             }
110         }
111     }
112     // add to tail
113     keyboard_report->keys[cb_tail] = code;
114     cb_tail = RO_INC(cb_tail);
115     cb_count++;
116 #else
117     int8_t i = 0;
118     int8_t empty = -1;
119     for (; i < KEYBOARD_REPORT_KEYS; i++) {
120         if (keyboard_report->keys[i] == code) {
121             break;
122         }
123         if (empty == -1 && keyboard_report->keys[i] == 0) {
124             empty = i;
125         }
126     }
127     if (i == KEYBOARD_REPORT_KEYS) {
128         if (empty != -1) {
129             keyboard_report->keys[empty] = code;
130         }
131     }
132 #endif
133 }
134
135 /** \brief del key byte
136  *
137  * FIXME: Needs doc
138  */
139 void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code)
140 {
141 #ifdef USB_6KRO_ENABLE
142     uint8_t i = cb_head;
143     if (cb_count) {
144         do {
145             if (keyboard_report->keys[i] == code) {
146                 keyboard_report->keys[i] = 0;
147                 cb_count--;
148                 if (cb_count == 0) {
149                     // reset head and tail
150                     cb_tail = cb_head = 0;
151                 }
152                 if (i == RO_DEC(cb_tail)) {
153                     // left shift when next to tail
154                     do {
155                         cb_tail = RO_DEC(cb_tail);
156                         if (keyboard_report->keys[RO_DEC(cb_tail)] != 0) {
157                             break;
158                         }
159                     } while (cb_tail != cb_head);
160                 }
161                 break;
162             }
163             i = RO_INC(i);
164         } while (i != cb_tail);
165     }
166 #else
167     for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
168         if (keyboard_report->keys[i] == code) {
169             keyboard_report->keys[i] = 0;
170         }
171     }
172 #endif
173 }
174
175 #ifdef NKRO_ENABLE
176 /** \brief add key bit
177  *
178  * FIXME: Needs doc
179  */
180 void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code)
181 {
182     if ((code>>3) < KEYBOARD_REPORT_BITS) {
183         keyboard_report->nkro.bits[code>>3] |= 1<<(code&7);
184     } else {
185         dprintf("add_key_bit: can't add: %02X\n", code);
186     }
187 }
188
189 /** \brief del key bit
190  *
191  * FIXME: Needs doc
192  */
193 void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code)
194 {
195     if ((code>>3) < KEYBOARD_REPORT_BITS) {
196         keyboard_report->nkro.bits[code>>3] &= ~(1<<(code&7));
197     } else {
198         dprintf("del_key_bit: can't del: %02X\n", code);
199     }
200 }
201 #endif
202
203 /** \brief add key to report
204  *
205  * FIXME: Needs doc
206  */
207 void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key)
208 {
209 #ifdef NKRO_ENABLE
210     if (keyboard_protocol && keymap_config.nkro) {
211         add_key_bit(keyboard_report, key);
212         return;
213     }
214 #endif
215     add_key_byte(keyboard_report, key);
216 }
217
218 /** \brief del key from report
219  *
220  * FIXME: Needs doc
221  */
222 void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key)
223 {
224 #ifdef NKRO_ENABLE
225     if (keyboard_protocol && keymap_config.nkro) {
226         del_key_bit(keyboard_report, key);
227         return;
228     }
229 #endif
230     del_key_byte(keyboard_report, key);
231 }
232
233 /** \brief clear key from report
234  *
235  * FIXME: Needs doc
236  */
237 void clear_keys_from_report(report_keyboard_t* keyboard_report)
238 {
239     // not clear mods
240     for (int8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) {
241         keyboard_report->raw[i] = 0;
242     }
243 }