process_combo.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. #include "process_combo.h"
  2. #include "print.h"
  3. // __attribute__ ((weak))
  4. // combo_t key_combos[] = {
  5. // };
  6. #define SEND_KEY(key) \
  7. do { \
  8. register_code16(key); \
  9. send_keyboard_report(); \
  10. unregister_code16(key); \
  11. } while(0)
  12. #define ALL_COMBO_KEYS_ARE_DOWN (((1<<count)-1) == combo->state)
  13. static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *record)
  14. {
  15. uint8_t count = 0;
  16. bool is_combo_key = false;
  17. // bool combo_key_released = false;
  18. // Count the number of combo keys
  19. for (const uint16_t *key = combo->keys; COMBO_END != pgm_read_word(key); ++key, ++count);
  20. for (uint8_t i = 0; i < count; ++i) {
  21. uint16_t key = pgm_read_word(&combo->keys[i]);
  22. if (key == keycode) {
  23. is_combo_key = true;
  24. if (record->event.pressed) {
  25. combo->state |= (1<<i);
  26. } else { // Combo key released
  27. if (!combo->state) {
  28. // The combo was sent, no need to send released key
  29. return true;
  30. }
  31. combo->state &= ~(1<<i);
  32. SEND_KEY(key);
  33. }
  34. }
  35. }
  36. if (ALL_COMBO_KEYS_ARE_DOWN) {
  37. SEND_KEY(combo->action);
  38. combo->state = 0;
  39. }
  40. return is_combo_key;
  41. }
  42. bool process_combo(uint16_t keycode, keyrecord_t *record)
  43. {
  44. bool is_combo_key = false;
  45. for (int i = 0; i < NUM_ELEMS(key_combos); ++i) {
  46. combo_t *combo = &key_combos[i];
  47. is_combo_key |= process_single_combo(combo, keycode, record);
  48. }
  49. return !is_combo_key;
  50. }