logo

qmk_firmware

custom branch of QMK firmware git clone https://anongit.hacktivis.me/git/qmk_firmware.git

layer_lock.c (3056B)


  1. // Copyright 2022-2023 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 "layer_lock.h"
  15. #include "quantum_keycodes.h"
  16. #ifndef NO_ACTION_LAYER
  17. // The current lock state. The kth bit is on if layer k is locked.
  18. layer_state_t locked_layers = 0;
  19. // Layer Lock timer to disable layer lock after X seconds inactivity
  20. # if defined(LAYER_LOCK_IDLE_TIMEOUT) && LAYER_LOCK_IDLE_TIMEOUT > 0
  21. uint32_t layer_lock_timer = 0;
  22. void layer_lock_timeout_task(void) {
  23. if (locked_layers && timer_elapsed32(layer_lock_timer) > LAYER_LOCK_IDLE_TIMEOUT) {
  24. layer_lock_all_off();
  25. layer_lock_timer = timer_read32();
  26. }
  27. }
  28. void layer_lock_activity_trigger(void) {
  29. layer_lock_timer = timer_read32();
  30. }
  31. # else
  32. void layer_lock_timeout_task(void) {}
  33. void layer_lock_activity_trigger(void) {}
  34. # endif // LAYER_LOCK_IDLE_TIMEOUT > 0
  35. bool is_layer_locked(uint8_t layer) {
  36. return locked_layers & ((layer_state_t)1 << layer);
  37. }
  38. void layer_lock_invert(uint8_t layer) {
  39. const layer_state_t mask = (layer_state_t)1 << layer;
  40. if ((locked_layers & mask) == 0) { // Layer is being locked.
  41. # ifndef NO_ACTION_ONESHOT
  42. if (layer == get_oneshot_layer()) {
  43. reset_oneshot_layer(); // Reset so that OSL doesn't turn layer off.
  44. }
  45. # endif // NO_ACTION_ONESHOT
  46. layer_on(layer);
  47. layer_lock_activity_trigger();
  48. } else { // Layer is being unlocked.
  49. layer_off(layer);
  50. }
  51. layer_lock_set_kb(locked_layers ^= mask);
  52. }
  53. // Implement layer_lock_on/off by deferring to layer_lock_invert.
  54. void layer_lock_on(uint8_t layer) {
  55. if (!is_layer_locked(layer)) {
  56. layer_lock_invert(layer);
  57. }
  58. }
  59. void layer_lock_off(uint8_t layer) {
  60. if (is_layer_locked(layer)) {
  61. layer_lock_invert(layer);
  62. }
  63. }
  64. void layer_lock_all_off(void) {
  65. layer_and(~locked_layers);
  66. locked_layers = 0;
  67. layer_lock_set_kb(locked_layers);
  68. }
  69. #else // NO_ACTION_LAYER
  70. bool is_layer_locked(uint8_t layer) {
  71. return false;
  72. }
  73. void layer_lock_on(uint8_t layer) {}
  74. void layer_lock_off(uint8_t layer) {}
  75. void layer_lock_all_off(void) {}
  76. void layer_lock_invert(uint8_t layer) {}
  77. void layer_lock_timeout_task(void) {}
  78. void layer_lock_activity_trigger(void) {}
  79. #endif // NO_ACTION_LAYER
  80. __attribute__((weak)) bool layer_lock_set_kb(layer_state_t locked_layers) {
  81. return layer_lock_set_user(locked_layers);
  82. }
  83. __attribute__((weak)) bool layer_lock_set_user(layer_state_t locked_layers) {
  84. return true;
  85. }
  86. void layer_lock_task(void) {
  87. layer_lock_timeout_task();
  88. }