key_repeater.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. * Copyright 2022 Paul Ewing
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "key_repeater.h"
  18. #include <stdlib.h>
  19. #include QMK_KEYBOARD_H
  20. enum key_repeater_state {
  21. KR_DISABLED,
  22. KR_WAITING,
  23. KR_BUTTON_DOWN,
  24. __KR_STATE_COUNT
  25. };
  26. struct key_repeater_t {
  27. int key;
  28. uint32_t key_duration_min;
  29. uint32_t key_duration_max;
  30. uint32_t wait_duration_min;
  31. uint32_t wait_duration_max;
  32. enum key_repeater_state state;
  33. uint32_t previous_button_down;
  34. uint32_t previous_button_up;
  35. uint32_t key_duration;
  36. uint32_t wait_duration;
  37. };
  38. // Utility functions
  39. uint32_t get_rand(uint32_t min, uint32_t max);
  40. // State handler function table
  41. void kr_waiting(struct key_repeater_t *kr);
  42. void kr_button_down(struct key_repeater_t *kr);
  43. typedef void (*kr_state_handler)(struct key_repeater_t *kr);
  44. static kr_state_handler kr_state_handlers[] = {
  45. [KR_DISABLED] = NULL,
  46. [KR_WAITING] = kr_waiting,
  47. [KR_BUTTON_DOWN] = kr_button_down,
  48. };
  49. struct key_repeater_t* kr_new(struct key_repeater_config_t* cfg) {
  50. struct key_repeater_t* kr = (struct key_repeater_t*)malloc(sizeof(struct key_repeater_t));
  51. if (cfg) {
  52. kr->key = cfg->key;
  53. kr->key_duration_min = cfg->key_duration_min;
  54. kr->key_duration_max = cfg->key_duration_max;
  55. kr->wait_duration_min = cfg->wait_duration_min;
  56. kr->wait_duration_max = cfg->wait_duration_max;
  57. } else {
  58. kr->key = KC_NO;
  59. kr->key_duration_min = 0;
  60. kr->key_duration_max = 0;
  61. kr->wait_duration_min = 0;
  62. kr->wait_duration_max = 0;
  63. }
  64. kr->state = KR_DISABLED;
  65. kr->previous_button_down = 0;
  66. kr->previous_button_up = 0;
  67. kr->key_duration = 0;
  68. kr->wait_duration = 0;
  69. return kr;
  70. }
  71. void kr_free(struct key_repeater_t **kr) {
  72. if (kr && *kr) {
  73. free(*kr);
  74. *kr = NULL;
  75. }
  76. }
  77. void kr_enable(struct key_repeater_t *kr) {
  78. if (!kr || kr->key == KC_NO) {
  79. return;
  80. }
  81. if (kr->state != KR_DISABLED) {
  82. return;
  83. }
  84. kr->state = KR_WAITING;
  85. kr->previous_button_down = 0;
  86. kr->previous_button_up = 0;
  87. kr->key_duration = 0;
  88. kr->wait_duration = 0;
  89. }
  90. void kr_disable(struct key_repeater_t *kr) {
  91. if (!kr || kr->key == KC_NO) {
  92. return;
  93. }
  94. if (kr->state == KR_BUTTON_DOWN) {
  95. unregister_code(kr->key);
  96. }
  97. kr->state = KR_DISABLED;
  98. }
  99. void kr_poll(struct key_repeater_t *kr) {
  100. if (!kr || kr->key == KC_NO) {
  101. return;
  102. }
  103. kr_state_handler handler = kr_state_handlers[kr->state];
  104. if (handler) {
  105. (handler)(kr);
  106. }
  107. }
  108. void kr_waiting(struct key_repeater_t *kr) {
  109. if (!kr || kr->key == KC_NO) {
  110. return;
  111. }
  112. uint32_t now = timer_read32();
  113. if (now > (kr->previous_button_up + kr->wait_duration)) {
  114. kr->state = KR_BUTTON_DOWN;
  115. kr->previous_button_down = now;
  116. if (kr->key_duration_min == kr->key_duration_max) {
  117. kr->key_duration = kr->key_duration_min;
  118. } else {
  119. kr->key_duration = get_rand(kr->key_duration_min, kr->key_duration_max);
  120. }
  121. register_code(kr->key);
  122. }
  123. }
  124. void kr_button_down(struct key_repeater_t *kr) {
  125. if (!kr || kr->key == KC_NO) {
  126. return;
  127. }
  128. uint32_t now = timer_read32();
  129. if (now > (kr->previous_button_down + kr->key_duration)) {
  130. kr->state = KR_WAITING;
  131. kr->previous_button_up = now;
  132. if (kr->wait_duration_min == kr->wait_duration_max) {
  133. kr->wait_duration = kr->wait_duration_min;
  134. } else {
  135. kr->wait_duration = get_rand(kr->wait_duration_min, kr->wait_duration_max);
  136. }
  137. unregister_code(kr->key);
  138. }
  139. }
  140. // Return a random number between min and max; assumes that the random number
  141. // generator has already been seeded
  142. uint32_t get_rand(uint32_t min, uint32_t max) {
  143. return (rand() % (max - min)) + min;
  144. }