Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
Это архивный репозиторий. Вы можете его клонировать или просматривать файлы, но не вносить изменения или открывать задачи/запросы на слияние.

action_util.c 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. Copyright 2013 Jun Wako <[email protected]>
  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. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #include "host.h"
  15. #include "report.h"
  16. #include "debug.h"
  17. #include "action_util.h"
  18. static inline void add_key_byte(uint8_t code);
  19. static inline void del_key_byte(uint8_t code);
  20. #ifdef NKRO_ENABLE
  21. static inline void add_key_bit(uint8_t code);
  22. static inline void del_key_bit(uint8_t code);
  23. #endif
  24. static uint8_t real_mods = 0;
  25. static uint8_t weak_mods = 0;
  26. // TODO: pointer variable is not needed
  27. //report_keyboard_t keyboard_report = {};
  28. report_keyboard_t *keyboard_report = &(report_keyboard_t){};
  29. #ifndef NO_ACTION_ONESHOT
  30. static bool oneshot_enabled = true;
  31. static int8_t oneshot_mods = 0;
  32. #endif
  33. void send_keyboard_report(void) {
  34. keyboard_report->mods = real_mods;
  35. keyboard_report->mods |= weak_mods;
  36. #ifndef NO_ACTION_ONESHOT
  37. keyboard_report->mods |= oneshot_mods;
  38. if (has_anykey()) {
  39. clear_oneshot_mods();
  40. }
  41. #endif
  42. host_keyboard_send(keyboard_report);
  43. }
  44. /* key */
  45. void add_key(uint8_t key)
  46. {
  47. #ifdef NKRO_ENABLE
  48. if (keyboard_nkro) {
  49. add_key_bit(key);
  50. return;
  51. }
  52. #endif
  53. add_key_byte(key);
  54. }
  55. void del_key(uint8_t key)
  56. {
  57. #ifdef NKRO_ENABLE
  58. if (keyboard_nkro) {
  59. del_key_bit(key);
  60. return;
  61. }
  62. #endif
  63. del_key_byte(key);
  64. }
  65. void clear_keys(void)
  66. {
  67. // not clear mods
  68. for (int8_t i = 1; i < REPORT_SIZE; i++) {
  69. keyboard_report->raw[i] = 0;
  70. }
  71. }
  72. /* modifier */
  73. uint8_t get_mods(void) { return real_mods; }
  74. void add_mods(uint8_t mods) { real_mods |= mods; }
  75. void del_mods(uint8_t mods) { real_mods &= ~mods; }
  76. void set_mods(uint8_t mods) { real_mods = mods; }
  77. void clear_mods(void) { real_mods = 0; }
  78. /* weak modifier */
  79. uint8_t get_weak_mods(void) { return weak_mods; }
  80. void add_weak_mods(uint8_t mods) { weak_mods |= mods; }
  81. void del_weak_mods(uint8_t mods) { weak_mods &= ~mods; }
  82. void set_weak_mods(uint8_t mods) { weak_mods = mods; }
  83. void clear_weak_mods(void) { weak_mods = 0; }
  84. /* Oneshot modifier */
  85. #ifndef NO_ACTION_ONESHOT
  86. void set_oneshot_mods(uint8_t mods) { oneshot_mods = mods; }
  87. void clear_oneshot_mods(void) { oneshot_mods = 0; }
  88. void oneshot_toggle(void) { oneshot_enabled = !oneshot_enabled; }
  89. void oneshot_enable(void) { oneshot_enabled = true; }
  90. void oneshot_disable(void) { oneshot_enabled = false; }
  91. #endif
  92. /*
  93. * inspect keyboard state
  94. */
  95. uint8_t has_anykey(void)
  96. {
  97. uint8_t cnt = 0;
  98. for (uint8_t i = 1; i < REPORT_SIZE; i++) {
  99. if (keyboard_report->raw[i])
  100. cnt++;
  101. }
  102. return cnt;
  103. }
  104. uint8_t has_anymod(void)
  105. {
  106. return bitpop(real_mods);
  107. }
  108. uint8_t get_first_key(void)
  109. {
  110. #ifdef NKRO_ENABLE
  111. if (keyboard_nkro) {
  112. uint8_t i = 0;
  113. for (; i < REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
  114. ;
  115. return i<<3 | biton(keyboard_report->nkro.bits[i]);
  116. }
  117. #endif
  118. return keyboard_report->keys[0];
  119. }
  120. /* local functions */
  121. static inline void add_key_byte(uint8_t code)
  122. {
  123. int8_t i = 0;
  124. int8_t empty = -1;
  125. for (; i < REPORT_KEYS; i++) {
  126. if (keyboard_report->keys[i] == code) {
  127. break;
  128. }
  129. if (empty == -1 && keyboard_report->keys[i] == 0) {
  130. empty = i;
  131. }
  132. }
  133. if (i == REPORT_KEYS) {
  134. if (empty != -1) {
  135. keyboard_report->keys[empty] = code;
  136. }
  137. }
  138. }
  139. static inline void del_key_byte(uint8_t code)
  140. {
  141. for (uint8_t i = 0; i < REPORT_KEYS; i++) {
  142. if (keyboard_report->keys[i] == code) {
  143. keyboard_report->keys[i] = 0;
  144. }
  145. }
  146. }
  147. #ifdef NKRO_ENABLE
  148. static inline void add_key_bit(uint8_t code)
  149. {
  150. if ((code>>3) < REPORT_BITS) {
  151. keyboard_report->nkro.bits[code>>3] |= 1<<(code&7);
  152. } else {
  153. dprintf("add_key_bit: can't add: %02X\n", code);
  154. }
  155. }
  156. static inline void del_key_bit(uint8_t code)
  157. {
  158. if ((code>>3) < REPORT_BITS) {
  159. keyboard_report->nkro.bits[code>>3] &= ~(1<<(code&7));
  160. } else {
  161. dprintf("del_key_bit: can't del: %02X\n", code);
  162. }
  163. }
  164. #endif