action_pseudo_lut.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #include "quantum.h"
  2. #include "action_pseudo_lut.h"
  3. static uint8_t send_key_shift_bit[SHIFT_BIT_SIZE];
  4. /*
  5. * Pseudo layout action.
  6. * This action converts a keycode in order to output the character according to the keymap you specified
  7. * still your keyboard layout recognized wrongly on your OS.
  8. * Memo: Using other layer keymap to get keycode
  9. */
  10. void action_pseudo_lut(keyrecord_t *record, uint8_t base_keymap_id, const uint16_t (*keymap)[2]) {
  11. uint8_t prev_shift;
  12. uint16_t keycode;
  13. uint16_t pseudo_keycode;
  14. /* get keycode from keymap you specified */
  15. keycode = keymap_key_to_keycode(base_keymap_id, record->event.key);
  16. prev_shift = keyboard_report->mods & (MOD_BIT(KC_LSFT) | MOD_BIT(KC_RSFT));
  17. if (record->event.pressed) {
  18. /* when magic commands entered, keycode does not converted */
  19. if (IS_COMMAND()) {
  20. if (prev_shift) {
  21. add_shift_bit(keycode);
  22. }
  23. register_code(keycode);
  24. return;
  25. }
  26. if (prev_shift) {
  27. pseudo_keycode = convert_keycode(keymap, keycode, true);
  28. dprintf("pressed: %02X, converted: %04X\n", keycode, pseudo_keycode);
  29. add_shift_bit(keycode);
  30. if (IS_LSFT(pseudo_keycode)) {
  31. register_code(QK_LSFT ^ pseudo_keycode);
  32. } else {
  33. /* delete shift mod temporarily */
  34. del_mods(prev_shift);
  35. send_keyboard_report();
  36. register_code(pseudo_keycode);
  37. add_mods(prev_shift);
  38. send_keyboard_report();
  39. }
  40. } else {
  41. pseudo_keycode = convert_keycode(keymap, keycode, false);
  42. dprintf("pressed: %02X, converted: %04X\n", keycode, pseudo_keycode);
  43. if (IS_LSFT(pseudo_keycode)) {
  44. add_weak_mods(MOD_BIT(KC_LSFT));
  45. send_keyboard_report();
  46. register_code(QK_LSFT ^ pseudo_keycode);
  47. /* on Windows, prevent key repeat to avoid unintended output */
  48. unregister_code(QK_LSFT ^ pseudo_keycode);
  49. del_weak_mods(MOD_BIT(KC_LSFT));
  50. send_keyboard_report();
  51. } else {
  52. register_code(pseudo_keycode);
  53. }
  54. }
  55. } else {
  56. if (get_shift_bit(keycode)) {
  57. del_shift_bit(keycode);
  58. pseudo_keycode = convert_keycode(keymap, keycode, true);
  59. } else {
  60. pseudo_keycode = convert_keycode(keymap, keycode, false);
  61. }
  62. dprintf("released: %02X, converted: %04X\n", keycode, pseudo_keycode);
  63. if (IS_LSFT(pseudo_keycode)) {
  64. unregister_code(QK_LSFT ^ pseudo_keycode);
  65. } else {
  66. unregister_code(pseudo_keycode);
  67. }
  68. }
  69. }
  70. uint16_t convert_keycode(const uint16_t (*keymap)[2], uint16_t keycode, bool shift_modded)
  71. {
  72. uint16_t pseudo_keycode;
  73. switch (keycode) {
  74. case KC_A ... KC_CAPSLOCK:
  75. #if defined(__AVR__)
  76. if (shift_modded) {
  77. pseudo_keycode = pgm_read_word(&keymap[keycode][1]);
  78. } else {
  79. pseudo_keycode = pgm_read_word(&keymap[keycode][0]);
  80. }
  81. #else
  82. if (shift_modded) {
  83. pseudo_keycode = keymap[keycode][1];
  84. } else {
  85. pseudo_keycode = keymap[keycode][0];
  86. }
  87. #endif
  88. /* if undefined, use got keycode as it is */
  89. if (pseudo_keycode == 0x00) {
  90. if (shift_modded) {
  91. pseudo_keycode = S(keycode);
  92. } else {
  93. pseudo_keycode = keycode;
  94. }
  95. }
  96. break;
  97. default:
  98. if (shift_modded) {
  99. pseudo_keycode = S(keycode);
  100. } else {
  101. pseudo_keycode = keycode;
  102. }
  103. break;
  104. }
  105. return pseudo_keycode;
  106. }
  107. uint8_t get_shift_bit(uint16_t keycode) {
  108. if ((keycode >> 3) < SHIFT_BIT_SIZE) {
  109. return send_key_shift_bit[keycode >> 3] & (1 << (keycode & 7));
  110. } else {
  111. dprintf("get_shift_bit: Can't get shift bit. keycode: %02X\n", keycode);
  112. return 0;
  113. }
  114. }
  115. void add_shift_bit(uint16_t keycode) {
  116. if ((keycode >> 3) < SHIFT_BIT_SIZE) {
  117. send_key_shift_bit[keycode >> 3] |= (1 << (keycode & 7));
  118. } else {
  119. dprintf("add_shift_bit: Can't add shift bit. keycode: %02X\n", keycode);
  120. }
  121. }
  122. void del_shift_bit(uint16_t keycode) {
  123. if ((keycode >> 3) < SHIFT_BIT_SIZE) {
  124. send_key_shift_bit[keycode >> 3] &= ~(1 << (keycode & 7));
  125. } else {
  126. dprintf("del_shift_bit: Can't delete shift bit. keycode: %02X\n", keycode);
  127. }
  128. }