action_util.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. Copyright 2013 Jun Wako <wakojun@gmail.com>
  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. #include "action_layer.h"
  19. #include "timer.h"
  20. #include "keycode_config.h"
  21. extern keymap_config_t keymap_config;
  22. static uint8_t real_mods = 0;
  23. static uint8_t weak_mods = 0;
  24. static uint8_t macro_mods = 0;
  25. #ifdef USB_6KRO_ENABLE
  26. #define RO_ADD(a, b) ((a + b) % KEYBOARD_REPORT_KEYS)
  27. #define RO_SUB(a, b) ((a - b + KEYBOARD_REPORT_KEYS) % KEYBOARD_REPORT_KEYS)
  28. #define RO_INC(a) RO_ADD(a, 1)
  29. #define RO_DEC(a) RO_SUB(a, 1)
  30. static int8_t cb_head = 0;
  31. static int8_t cb_tail = 0;
  32. static int8_t cb_count = 0;
  33. #endif
  34. // TODO: pointer variable is not needed
  35. //report_keyboard_t keyboard_report = {};
  36. report_keyboard_t *keyboard_report = &(report_keyboard_t){};
  37. #ifndef NO_ACTION_ONESHOT
  38. static int8_t oneshot_mods = 0;
  39. static int8_t oneshot_locked_mods = 0;
  40. int8_t get_oneshot_locked_mods(void) { return oneshot_locked_mods; }
  41. void set_oneshot_locked_mods(int8_t mods) { oneshot_locked_mods = mods; }
  42. void clear_oneshot_locked_mods(void) { oneshot_locked_mods = 0; }
  43. #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
  44. static int16_t oneshot_time = 0;
  45. bool has_oneshot_mods_timed_out(void) {
  46. return TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT;
  47. }
  48. #else
  49. bool has_oneshot_mods_timed_out(void) {
  50. return false;
  51. }
  52. #endif
  53. #endif
  54. /* oneshot layer */
  55. #ifndef NO_ACTION_ONESHOT
  56. /* oneshot_layer_data bits
  57. * LLLL LSSS
  58. * where:
  59. * L => are layer bits
  60. * S => oneshot state bits
  61. */
  62. static int8_t oneshot_layer_data = 0;
  63. inline uint8_t get_oneshot_layer(void) { return oneshot_layer_data >> 3; }
  64. inline uint8_t get_oneshot_layer_state(void) { return oneshot_layer_data & 0b111; }
  65. #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
  66. static int16_t oneshot_layer_time = 0;
  67. inline bool has_oneshot_layer_timed_out() {
  68. return TIMER_DIFF_16(timer_read(), oneshot_layer_time) >= ONESHOT_TIMEOUT &&
  69. !(get_oneshot_layer_state() & ONESHOT_TOGGLED);
  70. }
  71. #endif
  72. /* Oneshot layer */
  73. void set_oneshot_layer(uint8_t layer, uint8_t state)
  74. {
  75. oneshot_layer_data = layer << 3 | state;
  76. layer_on(layer);
  77. #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
  78. oneshot_layer_time = timer_read();
  79. #endif
  80. }
  81. void reset_oneshot_layer(void) {
  82. oneshot_layer_data = 0;
  83. #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
  84. oneshot_layer_time = 0;
  85. #endif
  86. }
  87. void clear_oneshot_layer_state(oneshot_fullfillment_t state)
  88. {
  89. uint8_t start_state = oneshot_layer_data;
  90. oneshot_layer_data &= ~state;
  91. if (!get_oneshot_layer_state() && start_state != oneshot_layer_data) {
  92. layer_off(get_oneshot_layer());
  93. #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
  94. oneshot_layer_time = 0;
  95. #endif
  96. }
  97. }
  98. bool is_oneshot_layer_active(void)
  99. {
  100. return get_oneshot_layer_state();
  101. }
  102. #endif
  103. void send_keyboard_report(void) {
  104. keyboard_report->mods = real_mods;
  105. keyboard_report->mods |= weak_mods;
  106. keyboard_report->mods |= macro_mods;
  107. #ifndef NO_ACTION_ONESHOT
  108. if (oneshot_mods) {
  109. #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
  110. if (has_oneshot_mods_timed_out()) {
  111. dprintf("Oneshot: timeout\n");
  112. clear_oneshot_mods();
  113. }
  114. #endif
  115. keyboard_report->mods |= oneshot_mods;
  116. if (has_anykey(keyboard_report)) {
  117. clear_oneshot_mods();
  118. }
  119. }
  120. #endif
  121. host_keyboard_send(keyboard_report);
  122. }
  123. /* key */
  124. void add_key(uint8_t key)
  125. {
  126. #ifdef NKRO_ENABLE
  127. if (keyboard_protocol && keymap_config.nkro) {
  128. add_key_bit(keyboard_report, key);
  129. return;
  130. }
  131. #endif
  132. add_key_byte(keyboard_report, key);
  133. }
  134. void del_key(uint8_t key)
  135. {
  136. #ifdef NKRO_ENABLE
  137. if (keyboard_protocol && keymap_config.nkro) {
  138. del_key_bit(keyboard_report, key);
  139. return;
  140. }
  141. #endif
  142. del_key_byte(keyboard_report, key);
  143. }
  144. void clear_keys(void)
  145. {
  146. // not clear mods
  147. for (int8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) {
  148. keyboard_report->raw[i] = 0;
  149. }
  150. }
  151. /* modifier */
  152. uint8_t get_mods(void) { return real_mods; }
  153. void add_mods(uint8_t mods) { real_mods |= mods; }
  154. void del_mods(uint8_t mods) { real_mods &= ~mods; }
  155. void set_mods(uint8_t mods) { real_mods = mods; }
  156. void clear_mods(void) { real_mods = 0; }
  157. /* weak modifier */
  158. uint8_t get_weak_mods(void) { return weak_mods; }
  159. void add_weak_mods(uint8_t mods) { weak_mods |= mods; }
  160. void del_weak_mods(uint8_t mods) { weak_mods &= ~mods; }
  161. void set_weak_mods(uint8_t mods) { weak_mods = mods; }
  162. void clear_weak_mods(void) { weak_mods = 0; }
  163. /* macro modifier */
  164. uint8_t get_macro_mods(void) { return macro_mods; }
  165. void add_macro_mods(uint8_t mods) { macro_mods |= mods; }
  166. void del_macro_mods(uint8_t mods) { macro_mods &= ~mods; }
  167. void set_macro_mods(uint8_t mods) { macro_mods = mods; }
  168. void clear_macro_mods(void) { macro_mods = 0; }
  169. /* Oneshot modifier */
  170. #ifndef NO_ACTION_ONESHOT
  171. void set_oneshot_mods(uint8_t mods)
  172. {
  173. oneshot_mods = mods;
  174. #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
  175. oneshot_time = timer_read();
  176. #endif
  177. }
  178. void clear_oneshot_mods(void)
  179. {
  180. oneshot_mods = 0;
  181. #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
  182. oneshot_time = 0;
  183. #endif
  184. }
  185. uint8_t get_oneshot_mods(void)
  186. {
  187. return oneshot_mods;
  188. }
  189. #endif
  190. /*
  191. * inspect keyboard state
  192. */
  193. uint8_t has_anymod(void)
  194. {
  195. return bitpop(real_mods);
  196. }