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.

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