logo

qmk_firmware

custom branch of QMK firmware git clone https://anongit.hacktivis.me/git/qmk_firmware.git

report.c (5733B)


  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 "action_util.h"
  18. #include "host.h"
  19. #include "keycode_config.h"
  20. #include "debug.h"
  21. #include "usb_device_state.h"
  22. #include "util.h"
  23. #include <string.h>
  24. /** \brief has_anykey
  25. *
  26. * FIXME: Needs doc
  27. */
  28. uint8_t has_anykey(void) {
  29. uint8_t cnt = 0;
  30. uint8_t* p = keyboard_report->keys;
  31. uint8_t lp = sizeof(keyboard_report->keys);
  32. #ifdef NKRO_ENABLE
  33. if (host_can_send_nkro() && keymap_config.nkro) {
  34. p = nkro_report->bits;
  35. lp = sizeof(nkro_report->bits);
  36. }
  37. #endif
  38. while (lp--) {
  39. if (*p++) cnt++;
  40. }
  41. return cnt;
  42. }
  43. /** \brief get_first_key
  44. *
  45. * FIXME: Needs doc
  46. */
  47. uint8_t get_first_key(void) {
  48. #ifdef NKRO_ENABLE
  49. if (host_can_send_nkro() && keymap_config.nkro) {
  50. uint8_t i = 0;
  51. for (; i < NKRO_REPORT_BITS && !nkro_report->bits[i]; i++)
  52. ;
  53. return i << 3 | biton(nkro_report->bits[i]);
  54. }
  55. #endif
  56. return keyboard_report->keys[0];
  57. }
  58. /** \brief Checks if a key is pressed in the report
  59. *
  60. * Returns true if the keyboard_report reports that the key is pressed, otherwise false
  61. * Note: The function doesn't support modifers currently, and it returns false for KC_NO
  62. */
  63. bool is_key_pressed(uint8_t key) {
  64. if (key == KC_NO) {
  65. return false;
  66. }
  67. #ifdef NKRO_ENABLE
  68. if (host_can_send_nkro() && keymap_config.nkro) {
  69. if ((key >> 3) < NKRO_REPORT_BITS) {
  70. return nkro_report->bits[key >> 3] & 1 << (key & 7);
  71. } else {
  72. return false;
  73. }
  74. }
  75. #endif
  76. for (int i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
  77. if (keyboard_report->keys[i] == key) {
  78. return true;
  79. }
  80. }
  81. return false;
  82. }
  83. /** \brief add key byte
  84. *
  85. * FIXME: Needs doc
  86. */
  87. void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code) {
  88. int8_t i = 0;
  89. int8_t empty = -1;
  90. for (; i < KEYBOARD_REPORT_KEYS; i++) {
  91. if (keyboard_report->keys[i] == code) {
  92. break;
  93. }
  94. if (empty == -1 && keyboard_report->keys[i] == 0) {
  95. empty = i;
  96. }
  97. }
  98. if (i == KEYBOARD_REPORT_KEYS) {
  99. if (empty != -1) {
  100. keyboard_report->keys[empty] = code;
  101. }
  102. }
  103. }
  104. /** \brief del key byte
  105. *
  106. * FIXME: Needs doc
  107. */
  108. void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code) {
  109. for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
  110. if (keyboard_report->keys[i] == code) {
  111. keyboard_report->keys[i] = 0;
  112. }
  113. }
  114. }
  115. #ifdef NKRO_ENABLE
  116. /** \brief add key bit
  117. *
  118. * FIXME: Needs doc
  119. */
  120. void add_key_bit(report_nkro_t* nkro_report, uint8_t code) {
  121. if ((code >> 3) < NKRO_REPORT_BITS) {
  122. nkro_report->bits[code >> 3] |= 1 << (code & 7);
  123. } else {
  124. dprintf("add_key_bit: can't add: %02X\n", code);
  125. }
  126. }
  127. /** \brief del key bit
  128. *
  129. * FIXME: Needs doc
  130. */
  131. void del_key_bit(report_nkro_t* nkro_report, uint8_t code) {
  132. if ((code >> 3) < NKRO_REPORT_BITS) {
  133. nkro_report->bits[code >> 3] &= ~(1 << (code & 7));
  134. } else {
  135. dprintf("del_key_bit: can't del: %02X\n", code);
  136. }
  137. }
  138. #endif
  139. /** \brief add key to report
  140. *
  141. * FIXME: Needs doc
  142. */
  143. void add_key_to_report(uint8_t key) {
  144. #ifdef NKRO_ENABLE
  145. if (host_can_send_nkro() && keymap_config.nkro) {
  146. add_key_bit(nkro_report, key);
  147. return;
  148. }
  149. #endif
  150. add_key_byte(keyboard_report, key);
  151. }
  152. /** \brief del key from report
  153. *
  154. * FIXME: Needs doc
  155. */
  156. void del_key_from_report(uint8_t key) {
  157. #ifdef NKRO_ENABLE
  158. if (host_can_send_nkro() && keymap_config.nkro) {
  159. del_key_bit(nkro_report, key);
  160. return;
  161. }
  162. #endif
  163. del_key_byte(keyboard_report, key);
  164. }
  165. /** \brief clear key from report
  166. *
  167. * FIXME: Needs doc
  168. */
  169. void clear_keys_from_report(void) {
  170. // not clear mods
  171. #ifdef NKRO_ENABLE
  172. if (host_can_send_nkro() && keymap_config.nkro) {
  173. memset(nkro_report->bits, 0, sizeof(nkro_report->bits));
  174. return;
  175. }
  176. #endif
  177. memset(keyboard_report->keys, 0, sizeof(keyboard_report->keys));
  178. }
  179. #ifdef MOUSE_ENABLE
  180. /**
  181. * @brief Compares 2 mouse reports for difference and returns result. Empty
  182. * reports always evaluate as unchanged.
  183. *
  184. * @param[in] new_report report_mouse_t
  185. * @param[in] old_report report_mouse_t
  186. * @return bool result
  187. */
  188. __attribute__((weak)) bool has_mouse_report_changed(report_mouse_t* new_report, report_mouse_t* old_report) {
  189. // memcmp doesn't work here because of the `report_id` field when using
  190. // shared mouse endpoint
  191. bool changed = ((new_report->buttons != old_report->buttons) ||
  192. # ifdef MOUSE_EXTENDED_REPORT
  193. (new_report->boot_x != 0 && new_report->boot_x != old_report->boot_x) || (new_report->boot_y != 0 && new_report->boot_y != old_report->boot_y) ||
  194. # endif
  195. (new_report->x != 0 && new_report->x != old_report->x) || (new_report->y != 0 && new_report->y != old_report->y) || (new_report->h != 0 && new_report->h != old_report->h) || (new_report->v != 0 && new_report->v != old_report->v));
  196. return changed;
  197. }
  198. #endif