mod_lock.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /*
  2. Copyright 2022 Eric Gebhart <e.a.gebhart@gmail.com>, @possumvibes
  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. // Derived from mod_lock by @possumvibes.
  15. #include "mod_lock.h"
  16. #undef MODL
  17. #define MODL(KEYCODE, MODKC) \
  18. {false, MODKC, KEYCODE},
  19. #define A_KEY(KEYCODE) case KEYCODE:
  20. #define BLANK(...)
  21. #undef IGNORE_KC
  22. #define IGNORE_KC BLANK
  23. mod_lock_state_t modlock_states[] = {
  24. #ifdef MOD_LOCK_ENABLE
  25. #include "mod_lock.def"
  26. #endif
  27. };
  28. uint8_t NUM_MODLOCK_STATES = sizeof(modlock_states) / sizeof(mod_lock_state_t);
  29. void process_mod_lock(uint16_t keycode, keyrecord_t *record) {
  30. #ifdef MOD_LOCK_ENABLE
  31. mod_lock_state_t *curr_state = NULL;
  32. for (int i = 0; i < NUM_MODLOCK_STATES; ++i) {
  33. curr_state = &modlock_states[i];
  34. if (keycode == curr_state->trigger) {
  35. if (record->event.pressed) {
  36. if (curr_state->locking) {
  37. unregister_code(curr_state->mod);
  38. } else {
  39. register_code(curr_state->mod);
  40. }
  41. curr_state->locking = !curr_state->locking;
  42. }
  43. } else {
  44. // check for cancel condition on keydown and keyup
  45. if (curr_state->locking && is_mod_lock_cancel_key(keycode)) {
  46. unregister_code(curr_state->mod);
  47. curr_state->locking = false;
  48. }
  49. }
  50. }
  51. #endif
  52. }
  53. #undef MODL
  54. #undef IGNORE_KC
  55. #define MODL BLANK
  56. #define IGNORE_KC A_KEY
  57. bool is_mod_lock_cancel_key(uint16_t keycode) {
  58. // Mod locks are exclusively used on the nav layer.
  59. // any key besides nav keys should cancel the lock.
  60. switch (keycode) {
  61. #ifdef MOD_LOCK_ENABLE
  62. #include "mod_lock.def"
  63. #endif
  64. return false;
  65. default:
  66. return true;
  67. }
  68. }