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.

281 lines
6.6 KiB

  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. extern inline void add_key(uint8_t key);
  38. extern inline void del_key(uint8_t key);
  39. extern inline void clear_keys(void);
  40. #ifndef NO_ACTION_ONESHOT
  41. static int8_t oneshot_mods = 0;
  42. static int8_t oneshot_locked_mods = 0;
  43. int8_t get_oneshot_locked_mods(void) { return oneshot_locked_mods; }
  44. void set_oneshot_locked_mods(int8_t mods) { oneshot_locked_mods = mods; }
  45. void clear_oneshot_locked_mods(void) { oneshot_locked_mods = 0; }
  46. #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
  47. static int16_t oneshot_time = 0;
  48. bool has_oneshot_mods_timed_out(void) {
  49. return TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT;
  50. }
  51. #else
  52. bool has_oneshot_mods_timed_out(void) {
  53. return false;
  54. }
  55. #endif
  56. #endif
  57. /* oneshot layer */
  58. #ifndef NO_ACTION_ONESHOT
  59. /** \brief oneshot_layer_data bits
  60. * LLLL LSSS
  61. * where:
  62. * L => are layer bits
  63. * S => oneshot state bits
  64. */
  65. static int8_t oneshot_layer_data = 0;
  66. inline uint8_t get_oneshot_layer(void) { return oneshot_layer_data >> 3; }
  67. inline uint8_t get_oneshot_layer_state(void) { return oneshot_layer_data & 0b111; }
  68. #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
  69. static int16_t oneshot_layer_time = 0;
  70. inline bool has_oneshot_layer_timed_out() {
  71. return TIMER_DIFF_16(timer_read(), oneshot_layer_time) >= ONESHOT_TIMEOUT &&
  72. !(get_oneshot_layer_state() & ONESHOT_TOGGLED);
  73. }
  74. #endif
  75. /** \brief Set oneshot layer
  76. *
  77. * FIXME: needs doc
  78. */
  79. void set_oneshot_layer(uint8_t layer, uint8_t state)
  80. {
  81. oneshot_layer_data = layer << 3 | state;
  82. layer_on(layer);
  83. #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
  84. oneshot_layer_time = timer_read();
  85. #endif
  86. }
  87. /** \brief Reset oneshot layer
  88. *
  89. * FIXME: needs doc
  90. */
  91. void reset_oneshot_layer(void) {
  92. oneshot_layer_data = 0;
  93. #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
  94. oneshot_layer_time = 0;
  95. #endif
  96. }
  97. /** \brief Clear oneshot layer
  98. *
  99. * FIXME: needs doc
  100. */
  101. void clear_oneshot_layer_state(oneshot_fullfillment_t state)
  102. {
  103. uint8_t start_state = oneshot_layer_data;
  104. oneshot_layer_data &= ~state;
  105. if (!get_oneshot_layer_state() && start_state != oneshot_layer_data) {
  106. layer_off(get_oneshot_layer());
  107. #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
  108. oneshot_layer_time = 0;
  109. #endif
  110. }
  111. }
  112. /** \brief Is oneshot layer active
  113. *
  114. * FIXME: needs doc
  115. */
  116. bool is_oneshot_layer_active(void)
  117. {
  118. return get_oneshot_layer_state();
  119. }
  120. #endif
  121. /** \brief Send keyboard report
  122. *
  123. * FIXME: needs doc
  124. */
  125. void send_keyboard_report(void) {
  126. keyboard_report->mods = real_mods;
  127. keyboard_report->mods |= weak_mods;
  128. keyboard_report->mods |= macro_mods;
  129. #ifndef NO_ACTION_ONESHOT
  130. if (oneshot_mods) {
  131. #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
  132. if (has_oneshot_mods_timed_out()) {
  133. dprintf("Oneshot: timeout\n");
  134. clear_oneshot_mods();
  135. }
  136. #endif
  137. keyboard_report->mods |= oneshot_mods;
  138. if (has_anykey(keyboard_report)) {
  139. clear_oneshot_mods();
  140. }
  141. }
  142. #endif
  143. host_keyboard_send(keyboard_report);
  144. }
  145. /** \brief Get mods
  146. *
  147. * FIXME: needs doc
  148. */
  149. uint8_t get_mods(void) { return real_mods; }
  150. /** \brief add mods
  151. *
  152. * FIXME: needs doc
  153. */
  154. void add_mods(uint8_t mods) { real_mods |= mods; }
  155. /** \brief del mods
  156. *
  157. * FIXME: needs doc
  158. */
  159. void del_mods(uint8_t mods) { real_mods &= ~mods; }
  160. /** \brief set mods
  161. *
  162. * FIXME: needs doc
  163. */
  164. void set_mods(uint8_t mods) { real_mods = mods; }
  165. /** \brief clear mods
  166. *
  167. * FIXME: needs doc
  168. */
  169. void clear_mods(void) { real_mods = 0; }
  170. /** \brief get weak mods
  171. *
  172. * FIXME: needs doc
  173. */
  174. uint8_t get_weak_mods(void) { return weak_mods; }
  175. /** \brief add weak mods
  176. *
  177. * FIXME: needs doc
  178. */
  179. void add_weak_mods(uint8_t mods) { weak_mods |= mods; }
  180. /** \brief del weak mods
  181. *
  182. * FIXME: needs doc
  183. */
  184. void del_weak_mods(uint8_t mods) { weak_mods &= ~mods; }
  185. /** \brief set weak mods
  186. *
  187. * FIXME: needs doc
  188. */
  189. void set_weak_mods(uint8_t mods) { weak_mods = mods; }
  190. /** \brief clear weak mods
  191. *
  192. * FIXME: needs doc
  193. */
  194. void clear_weak_mods(void) { weak_mods = 0; }
  195. /* macro modifier */
  196. /** \brief get macro mods
  197. *
  198. * FIXME: needs doc
  199. */
  200. uint8_t get_macro_mods(void) { return macro_mods; }
  201. /** \brief add macro mods
  202. *
  203. * FIXME: needs doc
  204. */
  205. void add_macro_mods(uint8_t mods) { macro_mods |= mods; }
  206. /** \brief del macro mods
  207. *
  208. * FIXME: needs doc
  209. */
  210. void del_macro_mods(uint8_t mods) { macro_mods &= ~mods; }
  211. /** \brief set macro mods
  212. *
  213. * FIXME: needs doc
  214. */
  215. void set_macro_mods(uint8_t mods) { macro_mods = mods; }
  216. /** \brief clear macro mods
  217. *
  218. * FIXME: needs doc
  219. */
  220. void clear_macro_mods(void) { macro_mods = 0; }
  221. #ifndef NO_ACTION_ONESHOT
  222. /** \brief set oneshot mods
  223. *
  224. * FIXME: needs doc
  225. */
  226. void set_oneshot_mods(uint8_t mods)
  227. {
  228. oneshot_mods = mods;
  229. #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
  230. oneshot_time = timer_read();
  231. #endif
  232. }
  233. /** \brief clear oneshot mods
  234. *
  235. * FIXME: needs doc
  236. */
  237. void clear_oneshot_mods(void)
  238. {
  239. oneshot_mods = 0;
  240. #if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
  241. oneshot_time = 0;
  242. #endif
  243. }
  244. /** \brief get oneshot mods
  245. *
  246. * FIXME: needs doc
  247. */
  248. uint8_t get_oneshot_mods(void)
  249. {
  250. return oneshot_mods;
  251. }
  252. #endif
  253. /** \brief inspect keyboard state
  254. *
  255. * FIXME: needs doc
  256. */
  257. uint8_t has_anymod(void)
  258. {
  259. return bitpop(real_mods);
  260. }