You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

243 lines
6.2 KiB

  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. #include "report.h"
  17. #include "host.h"
  18. #include "keycode_config.h"
  19. #include "debug.h"
  20. #include "util.h"
  21. /** \brief has_anykey
  22. *
  23. * FIXME: Needs doc
  24. */
  25. uint8_t has_anykey(report_keyboard_t* keyboard_report)
  26. {
  27. uint8_t cnt = 0;
  28. for (uint8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) {
  29. if (keyboard_report->raw[i])
  30. cnt++;
  31. }
  32. return cnt;
  33. }
  34. /** \brief get_first_key
  35. *
  36. * FIXME: Needs doc
  37. */
  38. uint8_t get_first_key(report_keyboard_t* keyboard_report)
  39. {
  40. #ifdef NKRO_ENABLE
  41. if (keyboard_protocol && keymap_config.nkro) {
  42. uint8_t i = 0;
  43. for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
  44. ;
  45. return i<<3 | biton(keyboard_report->nkro.bits[i]);
  46. }
  47. #endif
  48. #ifdef USB_6KRO_ENABLE
  49. uint8_t i = cb_head;
  50. do {
  51. if (keyboard_report->keys[i] != 0) {
  52. break;
  53. }
  54. i = RO_INC(i);
  55. } while (i != cb_tail);
  56. return keyboard_report->keys[i];
  57. #else
  58. return keyboard_report->keys[0];
  59. #endif
  60. }
  61. /** \brief add key byte
  62. *
  63. * FIXME: Needs doc
  64. */
  65. void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code)
  66. {
  67. #ifdef USB_6KRO_ENABLE
  68. int8_t i = cb_head;
  69. int8_t empty = -1;
  70. if (cb_count) {
  71. do {
  72. if (keyboard_report->keys[i] == code) {
  73. return;
  74. }
  75. if (empty == -1 && keyboard_report->keys[i] == 0) {
  76. empty = i;
  77. }
  78. i = RO_INC(i);
  79. } while (i != cb_tail);
  80. if (i == cb_tail) {
  81. if (cb_tail == cb_head) {
  82. // buffer is full
  83. if (empty == -1) {
  84. // pop head when has no empty space
  85. cb_head = RO_INC(cb_head);
  86. cb_count--;
  87. }
  88. else {
  89. // left shift when has empty space
  90. uint8_t offset = 1;
  91. i = RO_INC(empty);
  92. do {
  93. if (keyboard_report->keys[i] != 0) {
  94. keyboard_report->keys[empty] = keyboard_report->keys[i];
  95. keyboard_report->keys[i] = 0;
  96. empty = RO_INC(empty);
  97. }
  98. else {
  99. offset++;
  100. }
  101. i = RO_INC(i);
  102. } while (i != cb_tail);
  103. cb_tail = RO_SUB(cb_tail, offset);
  104. }
  105. }
  106. }
  107. }
  108. // add to tail
  109. keyboard_report->keys[cb_tail] = code;
  110. cb_tail = RO_INC(cb_tail);
  111. cb_count++;
  112. #else
  113. int8_t i = 0;
  114. int8_t empty = -1;
  115. for (; i < KEYBOARD_REPORT_KEYS; i++) {
  116. if (keyboard_report->keys[i] == code) {
  117. break;
  118. }
  119. if (empty == -1 && keyboard_report->keys[i] == 0) {
  120. empty = i;
  121. }
  122. }
  123. if (i == KEYBOARD_REPORT_KEYS) {
  124. if (empty != -1) {
  125. keyboard_report->keys[empty] = code;
  126. }
  127. }
  128. #endif
  129. }
  130. /** \brief del key byte
  131. *
  132. * FIXME: Needs doc
  133. */
  134. void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code)
  135. {
  136. #ifdef USB_6KRO_ENABLE
  137. uint8_t i = cb_head;
  138. if (cb_count) {
  139. do {
  140. if (keyboard_report->keys[i] == code) {
  141. keyboard_report->keys[i] = 0;
  142. cb_count--;
  143. if (cb_count == 0) {
  144. // reset head and tail
  145. cb_tail = cb_head = 0;
  146. }
  147. if (i == RO_DEC(cb_tail)) {
  148. // left shift when next to tail
  149. do {
  150. cb_tail = RO_DEC(cb_tail);
  151. if (keyboard_report->keys[RO_DEC(cb_tail)] != 0) {
  152. break;
  153. }
  154. } while (cb_tail != cb_head);
  155. }
  156. break;
  157. }
  158. i = RO_INC(i);
  159. } while (i != cb_tail);
  160. }
  161. #else
  162. for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
  163. if (keyboard_report->keys[i] == code) {
  164. keyboard_report->keys[i] = 0;
  165. }
  166. }
  167. #endif
  168. }
  169. #ifdef NKRO_ENABLE
  170. /** \brief add key bit
  171. *
  172. * FIXME: Needs doc
  173. */
  174. void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code)
  175. {
  176. if ((code>>3) < KEYBOARD_REPORT_BITS) {
  177. keyboard_report->nkro.bits[code>>3] |= 1<<(code&7);
  178. } else {
  179. dprintf("add_key_bit: can't add: %02X\n", code);
  180. }
  181. }
  182. /** \brief del key bit
  183. *
  184. * FIXME: Needs doc
  185. */
  186. void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code)
  187. {
  188. if ((code>>3) < KEYBOARD_REPORT_BITS) {
  189. keyboard_report->nkro.bits[code>>3] &= ~(1<<(code&7));
  190. } else {
  191. dprintf("del_key_bit: can't del: %02X\n", code);
  192. }
  193. }
  194. #endif
  195. /** \brief add key to report
  196. *
  197. * FIXME: Needs doc
  198. */
  199. void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key)
  200. {
  201. #ifdef NKRO_ENABLE
  202. if (keyboard_protocol && keymap_config.nkro) {
  203. add_key_bit(keyboard_report, key);
  204. return;
  205. }
  206. #endif
  207. add_key_byte(keyboard_report, key);
  208. }
  209. /** \brief del key from report
  210. *
  211. * FIXME: Needs doc
  212. */
  213. void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key)
  214. {
  215. #ifdef NKRO_ENABLE
  216. if (keyboard_protocol && keymap_config.nkro) {
  217. del_key_bit(keyboard_report, key);
  218. return;
  219. }
  220. #endif
  221. del_key_byte(keyboard_report, key);
  222. }
  223. /** \brief clear key from report
  224. *
  225. * FIXME: Needs doc
  226. */
  227. void clear_keys_from_report(report_keyboard_t* keyboard_report)
  228. {
  229. // not clear mods
  230. for (int8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) {
  231. keyboard_report->raw[i] = 0;
  232. }
  233. }