encoder.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // Copyright 2022-2023 Nick Brassel (@tzarc)
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include <string.h>
  4. #include "action.h"
  5. #include "encoder.h"
  6. #include "wait.h"
  7. #ifndef ENCODER_MAP_KEY_DELAY
  8. # define ENCODER_MAP_KEY_DELAY TAP_CODE_DELAY
  9. #endif
  10. __attribute__((weak)) bool should_process_encoder(void) {
  11. return is_keyboard_master();
  12. }
  13. static encoder_events_t encoder_events;
  14. void encoder_init(void) {
  15. memset(&encoder_events, 0, sizeof(encoder_events));
  16. encoder_driver_init();
  17. }
  18. static bool encoder_handle_queue(void) {
  19. bool changed = false;
  20. while (encoder_events.tail != encoder_events.head) {
  21. encoder_event_t event = encoder_events.queue[encoder_events.tail];
  22. encoder_events.tail = (encoder_events.tail + 1) % MAX_QUEUED_ENCODER_EVENTS;
  23. #ifdef ENCODER_MAP_ENABLE
  24. // The delays below cater for Windows and its wonderful requirements.
  25. action_exec(event.clockwise ? MAKE_ENCODER_CW_EVENT(event.index, true) : MAKE_ENCODER_CCW_EVENT(event.index, true));
  26. # if ENCODER_MAP_KEY_DELAY > 0
  27. wait_ms(ENCODER_MAP_KEY_DELAY);
  28. # endif // ENCODER_MAP_KEY_DELAY > 0
  29. action_exec(event.clockwise ? MAKE_ENCODER_CW_EVENT(event.index, false) : MAKE_ENCODER_CCW_EVENT(event.index, false));
  30. # if ENCODER_MAP_KEY_DELAY > 0
  31. wait_ms(ENCODER_MAP_KEY_DELAY);
  32. # endif // ENCODER_MAP_KEY_DELAY > 0
  33. #else // ENCODER_MAP_ENABLE
  34. encoder_update_kb(event.index, event.clockwise ? true : false);
  35. #endif // ENCODER_MAP_ENABLE
  36. changed = true;
  37. }
  38. return changed;
  39. }
  40. bool encoder_task(void) {
  41. bool changed = false;
  42. #ifdef SPLIT_KEYBOARD
  43. // Attempt to process existing encoder events in case split handling has already enqueued events
  44. if (should_process_encoder()) {
  45. changed |= encoder_handle_queue();
  46. }
  47. #endif // SPLIT_KEYBOARD
  48. // Let the encoder driver produce events
  49. encoder_driver_task();
  50. // Process any events that were enqueued
  51. if (should_process_encoder()) {
  52. changed |= encoder_handle_queue();
  53. }
  54. return changed;
  55. }
  56. bool encoder_queue_event(uint8_t index, bool clockwise) {
  57. // Drop out if we're full
  58. if ((encoder_events.head + 1) % MAX_QUEUED_ENCODER_EVENTS == encoder_events.tail) {
  59. return false;
  60. }
  61. // Append the event
  62. encoder_event_t new_event = {.index = index, .clockwise = clockwise ? 1 : 0};
  63. encoder_events.queue[encoder_events.head] = new_event;
  64. // Increment the head index
  65. encoder_events.head = (encoder_events.head + 1) % MAX_QUEUED_ENCODER_EVENTS;
  66. return true;
  67. }
  68. void encoder_retrieve_events(encoder_events_t *events) {
  69. memcpy(events, &encoder_events, sizeof(encoder_events));
  70. }
  71. #ifdef SPLIT_KEYBOARD
  72. void encoder_set_tail_index(uint8_t tail_index) {
  73. encoder_events.tail = tail_index;
  74. }
  75. void encoder_handle_slave_events(encoder_events_t *events) {
  76. while (events->tail != events->head) {
  77. encoder_event_t event = events->queue[events->tail];
  78. events->tail = (events->tail + 1) % MAX_QUEUED_ENCODER_EVENTS;
  79. encoder_queue_event(event.index, event.clockwise ? true : false);
  80. }
  81. }
  82. #endif // SPLIT_KEYBOARD
  83. __attribute__((weak)) bool encoder_update_user(uint8_t index, bool clockwise) {
  84. return true;
  85. }
  86. __attribute__((weak)) bool encoder_update_kb(uint8_t index, bool clockwise) {
  87. bool res = encoder_update_user(index, clockwise);
  88. #if !defined(ENCODER_TESTS)
  89. if (res) {
  90. if (clockwise) {
  91. # if defined(EXTRAKEY_ENABLE)
  92. tap_code_delay(KC_VOLU, 10);
  93. # elif defined(MOUSEKEY_ENABLE)
  94. tap_code_delay(KC_MS_WH_UP, 10);
  95. # else
  96. tap_code_delay(KC_PGDN, 10);
  97. # endif
  98. } else {
  99. # if defined(EXTRAKEY_ENABLE)
  100. tap_code_delay(KC_VOLD, 10);
  101. # elif defined(MOUSEKEY_ENABLE)
  102. tap_code_delay(KC_MS_WH_DOWN, 10);
  103. # else
  104. tap_code_delay(KC_PGUP, 10);
  105. # endif
  106. }
  107. }
  108. #endif // ENCODER_TESTS
  109. return res;
  110. }