]> git.donarmstrong.com Git - qmk_firmware.git/blob - quantum/process_keycode/process_auto_shift.c
e2e6b02e0ac9f194e0e17b248c667f079227f6f6
[qmk_firmware.git] / quantum / process_keycode / process_auto_shift.c
1 /* Copyright 2017 Jeremy Cowgar
2  *
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  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  */
16
17 #ifdef AUTO_SHIFT_ENABLE
18
19 #include <stdio.h>
20
21 #include "process_auto_shift.h"
22
23 #define TAP(key) \
24   register_code(key); \
25   unregister_code(key)
26
27 #define TAP_WITH_MOD(mod, key) \
28   register_code(mod); \
29   register_code(key); \
30   unregister_code(key); \
31   unregister_code(mod)
32
33 uint16_t autoshift_time = 0;
34 uint16_t autoshift_timeout = AUTO_SHIFT_TIMEOUT;
35 uint16_t autoshift_lastkey = KC_NO;
36
37 bool autoshift_enabled = true;
38
39 void autoshift_timer_report(void) {
40   char display[8];
41
42   snprintf(display, 8, "\n%d\n", autoshift_timeout);
43
44   send_string((const char *)display);
45 }
46
47 void autoshift_on(uint16_t keycode) {
48   autoshift_time = timer_read();
49   autoshift_lastkey = keycode;
50 }
51
52 void autoshift_flush(void) {
53   if (autoshift_lastkey != KC_NO) {
54     uint16_t elapsed = timer_elapsed(autoshift_time);
55
56     if (elapsed > autoshift_timeout) {
57       register_code(KC_LSFT);
58     }
59
60     register_code(autoshift_lastkey);
61     unregister_code(autoshift_lastkey);
62
63     if (elapsed > autoshift_timeout) {
64       unregister_code(KC_LSFT);
65     }
66
67     autoshift_time = 0;
68     autoshift_lastkey = KC_NO;
69   }
70 }
71
72 bool process_auto_shift(uint16_t keycode, keyrecord_t *record) {
73   static uint8_t any_mod_pressed;
74
75   if (record->event.pressed) {
76     switch (keycode) {
77       case KC_ASUP:
78         autoshift_timeout += 5;
79         return false;
80
81       case KC_ASDN:
82         autoshift_timeout -= 5;
83         return false;
84
85       case KC_ASRP:
86         autoshift_timer_report();
87         return false;
88
89       case KC_ASTG:
90         if (autoshift_enabled) {
91           autoshift_enabled = false;
92           autoshift_flush();
93         }
94         else {
95           autoshift_enabled = true;
96         }
97
98 #ifndef NO_AUTO_SHIFT_ALPHA
99       case KC_A:
100       case KC_B:
101       case KC_C:
102       case KC_D:
103       case KC_E:
104       case KC_F:
105       case KC_G:
106       case KC_H:
107       case KC_I:
108       case KC_J:
109       case KC_K:
110       case KC_L:
111       case KC_M:
112       case KC_N:
113       case KC_O:
114       case KC_P:
115       case KC_Q:
116       case KC_R:
117       case KC_S:
118       case KC_T:
119       case KC_U:
120       case KC_V:
121       case KC_W:
122       case KC_X:
123       case KC_Y:
124       case KC_Z:
125 #endif
126 #ifndef NO_AUTO_SHIFT_NUMERIC
127       case KC_1:
128       case KC_2:
129       case KC_3:
130       case KC_4:
131       case KC_5:
132       case KC_6:
133       case KC_7:
134       case KC_8:
135       case KC_9:
136       case KC_0:
137 #endif
138 #ifndef NO_AUTO_SHIFT_SPECIAL
139       case KC_MINUS:
140       case KC_EQL:
141       case KC_TAB:
142       case KC_LBRC:
143       case KC_RBRC:
144       case KC_BSLS:
145       case KC_SCLN:
146       case KC_QUOT:
147       case KC_COMM:
148       case KC_DOT:
149       case KC_SLSH:
150 #endif
151         if (!autoshift_enabled) return true;
152
153         autoshift_flush();
154
155         any_mod_pressed = get_mods() & (
156           MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)|
157           MOD_BIT(KC_LALT)|MOD_BIT(KC_RALT)|
158           MOD_BIT(KC_LCTL)|MOD_BIT(KC_RCTL)|
159           MOD_BIT(KC_LSFT)|MOD_BIT(KC_RSFT)
160         );
161
162         if (any_mod_pressed) {
163           return true;
164         }
165
166         autoshift_on(keycode);
167         return false;
168
169       default:
170         autoshift_flush();
171         return true;
172     }
173   } else {
174     autoshift_flush();
175   }
176
177   return true;
178 }
179
180 #endif