process_tap_dance.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #include "quantum.h"
  2. #include "action_tapping.h"
  3. static uint16_t last_td;
  4. static int8_t highest_td = -1;
  5. void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data) {
  6. qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data;
  7. if (state->count == 1) {
  8. register_code16 (pair->kc1);
  9. } else if (state->count == 2) {
  10. register_code16 (pair->kc2);
  11. }
  12. }
  13. void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data) {
  14. qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data;
  15. if (state->count == 1) {
  16. unregister_code16 (pair->kc1);
  17. } else if (state->count == 2) {
  18. unregister_code16 (pair->kc2);
  19. }
  20. }
  21. static inline void _process_tap_dance_action_fn (qk_tap_dance_state_t *state,
  22. void *user_data,
  23. qk_tap_dance_user_fn_t fn)
  24. {
  25. if (fn) {
  26. fn(state, user_data);
  27. }
  28. }
  29. static inline void process_tap_dance_action_on_each_tap (qk_tap_dance_action_t *action)
  30. {
  31. _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_each_tap);
  32. }
  33. static inline void process_tap_dance_action_on_dance_finished (qk_tap_dance_action_t *action)
  34. {
  35. if (action->state.finished)
  36. return;
  37. action->state.finished = true;
  38. add_mods(action->state.oneshot_mods);
  39. send_keyboard_report();
  40. _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_dance_finished);
  41. }
  42. static inline void process_tap_dance_action_on_reset (qk_tap_dance_action_t *action)
  43. {
  44. _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_reset);
  45. del_mods(action->state.oneshot_mods);
  46. send_keyboard_report();
  47. }
  48. bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
  49. uint16_t idx = keycode - QK_TAP_DANCE;
  50. qk_tap_dance_action_t *action;
  51. if (last_td && last_td != keycode) {
  52. (&tap_dance_actions[last_td - QK_TAP_DANCE])->state.interrupted = true;
  53. }
  54. switch(keycode) {
  55. case QK_TAP_DANCE ... QK_TAP_DANCE_MAX:
  56. if ((int16_t)idx > highest_td)
  57. highest_td = idx;
  58. action = &tap_dance_actions[idx];
  59. action->state.pressed = record->event.pressed;
  60. if (record->event.pressed) {
  61. action->state.keycode = keycode;
  62. action->state.count++;
  63. action->state.timer = timer_read();
  64. action->state.oneshot_mods = get_oneshot_mods();
  65. process_tap_dance_action_on_each_tap (action);
  66. if (last_td && last_td != keycode) {
  67. qk_tap_dance_action_t *paction = &tap_dance_actions[last_td - QK_TAP_DANCE];
  68. paction->state.interrupted = true;
  69. process_tap_dance_action_on_dance_finished (paction);
  70. reset_tap_dance (&paction->state);
  71. }
  72. last_td = keycode;
  73. }
  74. break;
  75. default:
  76. if (!record->event.pressed)
  77. return true;
  78. if (highest_td == -1)
  79. return true;
  80. for (int i = 0; i <= highest_td; i++) {
  81. action = &tap_dance_actions[i];
  82. if (action->state.count == 0)
  83. continue;
  84. action->state.interrupted = true;
  85. process_tap_dance_action_on_dance_finished (action);
  86. reset_tap_dance (&action->state);
  87. }
  88. break;
  89. }
  90. return true;
  91. }
  92. void matrix_scan_tap_dance () {
  93. if (highest_td == -1)
  94. return;
  95. for (int i = 0; i <= highest_td; i++) {
  96. qk_tap_dance_action_t *action = &tap_dance_actions[i];
  97. if (action->state.count && timer_elapsed (action->state.timer) > TAPPING_TERM) {
  98. process_tap_dance_action_on_dance_finished (action);
  99. reset_tap_dance (&action->state);
  100. }
  101. }
  102. }
  103. void reset_tap_dance (qk_tap_dance_state_t *state) {
  104. qk_tap_dance_action_t *action;
  105. if (state->pressed)
  106. return;
  107. action = &tap_dance_actions[state->keycode - QK_TAP_DANCE];
  108. process_tap_dance_action_on_reset (action);
  109. state->count = 0;
  110. state->interrupted = false;
  111. state->finished = false;
  112. last_td = 0;
  113. }