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