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.

80 lines
2.1 KiB

  1. // Copyright 2021-2022 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "caps_word.h"
  15. /** @brief True when Caps Word is active. */
  16. static bool caps_word_active = false;
  17. #if CAPS_WORD_IDLE_TIMEOUT > 0
  18. // Constrain timeout to a sensible range. With 16-bit timers, the longest
  19. // timeout possible is 32768 ms, rounded here to 30000 ms = half a minute.
  20. # if CAPS_WORD_IDLE_TIMEOUT < 100 || CAPS_WORD_IDLE_TIMEOUT > 30000
  21. # error "CAPS_WORD_IDLE_TIMEOUT must be between 100 and 30000 ms"
  22. # endif
  23. /** @brief Deadline for idle timeout. */
  24. static uint16_t idle_timer = 0;
  25. void caps_word_task(void) {
  26. if (caps_word_active && timer_expired(timer_read(), idle_timer)) {
  27. caps_word_off();
  28. }
  29. }
  30. void caps_word_reset_idle_timer(void) {
  31. idle_timer = timer_read() + CAPS_WORD_IDLE_TIMEOUT;
  32. }
  33. #endif // CAPS_WORD_IDLE_TIMEOUT > 0
  34. void caps_word_on(void) {
  35. if (caps_word_active) {
  36. return;
  37. }
  38. clear_mods();
  39. #ifndef NO_ACTION_ONESHOT
  40. clear_oneshot_mods();
  41. #endif // NO_ACTION_ONESHOT
  42. #if CAPS_WORD_IDLE_TIMEOUT > 0
  43. caps_word_reset_idle_timer();
  44. #endif // CAPS_WORD_IDLE_TIMEOUT > 0
  45. caps_word_active = true;
  46. caps_word_set_user(true);
  47. }
  48. void caps_word_off(void) {
  49. if (!caps_word_active) {
  50. return;
  51. }
  52. unregister_weak_mods(MOD_MASK_SHIFT); // Make sure weak shift is off.
  53. caps_word_active = false;
  54. caps_word_set_user(false);
  55. }
  56. void caps_word_toggle(void) {
  57. if (caps_word_active) {
  58. caps_word_off();
  59. } else {
  60. caps_word_on();
  61. }
  62. }
  63. bool is_caps_word_on(void) {
  64. return caps_word_active;
  65. }
  66. __attribute__((weak)) void caps_word_set_user(bool active) {}