aboutsummaryrefslogtreecommitdiff
path: root/quantum/process_keycode
diff options
context:
space:
mode:
authorFelix Uhl <iFreilicht@users.noreply.github.com>2016-08-18 12:02:31 +0200
committerGitHub <noreply@github.com>2016-08-18 12:02:31 +0200
commited6ecff292eae378eb89bf6a7b5b8dd4229b84b7 (patch)
treeb2290e1a983134e0d7fc2f328eb949c37d99961c /quantum/process_keycode
parent73f13c8f26f7f3777cec9d3036628a7dd6021ee9 (diff)
parent8144ce8852f690d5772d80ed2b96ae4af201e266 (diff)
downloadqmk_firmware-ed6ecff292eae378eb89bf6a7b5b8dd4229b84b7.tar.gz
qmk_firmware-ed6ecff292eae378eb89bf6a7b5b8dd4229b84b7.zip
Merge pull request #1 from jackhumbert/master
Merging from base Repo
Diffstat (limited to 'quantum/process_keycode')
-rw-r--r--quantum/process_keycode/process_tap_dance.c122
-rw-r--r--quantum/process_keycode/process_tap_dance.h9
-rw-r--r--quantum/process_keycode/process_unicode.c205
-rw-r--r--quantum/process_keycode/process_unicode.h38
4 files changed, 280 insertions, 94 deletions
diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c
index 5429e3438..e152f2350 100644
--- a/quantum/process_keycode/process_tap_dance.c
+++ b/quantum/process_keycode/process_tap_dance.c
@@ -1,18 +1,8 @@
1#include "quantum.h" 1#include "quantum.h"
2#include "action_tapping.h"
2 3
3static qk_tap_dance_state_t qk_tap_dance_state; 4static uint16_t last_td;
4bool td_debug_enable = false; 5static int8_t highest_td = -1;
5
6#if CONSOLE_ENABLE
7#define td_debug(s) if (td_debug_enable) \
8 { \
9 xprintf ("D:tap_dance:%s:%s = { keycode = %d, count = %d, active = %d, pressed = %d }\n", __FUNCTION__, s, \
10 qk_tap_dance_state.keycode, qk_tap_dance_state.count, \
11 qk_tap_dance_state.active, qk_tap_dance_state.pressed); \
12 }
13#else
14#define td_debug(s)
15#endif
16 6
17void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data) { 7void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data) {
18 qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data; 8 qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data;
@@ -35,98 +25,110 @@ void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data) {
35} 25}
36 26
37static inline void _process_tap_dance_action_fn (qk_tap_dance_state_t *state, 27static inline void _process_tap_dance_action_fn (qk_tap_dance_state_t *state,
38 void *user_data, 28 void *user_data,
39 qk_tap_dance_user_fn_t fn) 29 qk_tap_dance_user_fn_t fn)
40{ 30{
41 if (fn) { 31 if (fn) {
42 fn(state, user_data); 32 fn(state, user_data);
43 } 33 }
44} 34}
45 35
46static inline void process_tap_dance_action_on_each_tap (qk_tap_dance_action_t action) 36static inline void process_tap_dance_action_on_each_tap (qk_tap_dance_action_t *action)
47{ 37{
48 td_debug("trigger"); 38 _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_each_tap);
49 _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_each_tap);
50} 39}
51 40
52static inline void process_tap_dance_action_on_dance_finished (qk_tap_dance_action_t action) 41static inline void process_tap_dance_action_on_dance_finished (qk_tap_dance_action_t *action)
53{ 42{
54 td_debug("trigger"); 43 if (action->state.finished)
55 _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_dance_finished); 44 return;
45 action->state.finished = true;
46 _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_dance_finished);
56} 47}
57 48
58static inline void process_tap_dance_action_on_reset (qk_tap_dance_action_t action) 49static inline void process_tap_dance_action_on_reset (qk_tap_dance_action_t *action)
59{ 50{
60 td_debug("trigger") 51 _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_reset);
61 _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_reset);
62} 52}
63 53
64bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { 54bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
65 bool r = true;
66 uint16_t idx = keycode - QK_TAP_DANCE; 55 uint16_t idx = keycode - QK_TAP_DANCE;
67 qk_tap_dance_action_t action; 56 qk_tap_dance_action_t *action;
57
58 if (last_td && last_td != keycode) {
59 (&tap_dance_actions[last_td - QK_TAP_DANCE])->state.interrupted = true;
60 }
68 61
69 switch(keycode) { 62 switch(keycode) {
70 case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: 63 case QK_TAP_DANCE ... QK_TAP_DANCE_MAX:
71 action = tap_dance_actions[idx]; 64 if ((int16_t)idx > highest_td)
72 65 highest_td = idx;
73 process_tap_dance_action_on_each_tap (action); 66 action = &tap_dance_actions[idx];
74 if (qk_tap_dance_state.keycode && qk_tap_dance_state.keycode != keycode) {
75 process_tap_dance_action_on_dance_finished (action);
76 } else if (qk_tap_dance_state.active && qk_tap_dance_state.pressed) {
77 reset_tap_dance (&qk_tap_dance_state);
78 } else {
79 r = false;
80 }
81 67
82 qk_tap_dance_state.active = true; 68 action->state.keycode = keycode;
83 qk_tap_dance_state.pressed = record->event.pressed; 69 action->state.pressed = record->event.pressed;
84 if (record->event.pressed) { 70 if (record->event.pressed) {
85 qk_tap_dance_state.keycode = keycode; 71 action->state.count++;
86 qk_tap_dance_state.timer = timer_read (); 72 action->state.timer = timer_read();
87 qk_tap_dance_state.count++; 73
74 if (last_td && last_td != keycode) {
75 qk_tap_dance_action_t *paction = &tap_dance_actions[last_td - QK_TAP_DANCE];
76 paction->state.interrupted = true;
77 process_tap_dance_action_on_dance_finished (paction);
78 reset_tap_dance (&paction->state);
79 }
88 } 80 }
81 last_td = keycode;
82
89 break; 83 break;
90 84
91 default: 85 default:
92 if (qk_tap_dance_state.keycode) { 86 if (!record->event.pressed)
93 // if we are here, the tap dance was interrupted by a different key 87 return true;
94 idx = qk_tap_dance_state.keycode - QK_TAP_DANCE; 88
95 action = tap_dance_actions[idx]; 89 if (highest_td == -1)
90 return true;
96 91
97 process_tap_dance_action_on_each_tap (action); 92 for (int i = 0; i <= highest_td; i++) {
93 action = &tap_dance_actions[i];
94 if (action->state.count == 0)
95 continue;
96 action->state.interrupted = true;
98 process_tap_dance_action_on_dance_finished (action); 97 process_tap_dance_action_on_dance_finished (action);
99 reset_tap_dance (&qk_tap_dance_state); 98 reset_tap_dance (&action->state);
100 qk_tap_dance_state.active = false;
101 } 99 }
102 break; 100 break;
103 } 101 }
104 102
105 return r; 103 return true;
106} 104}
107 105
108void matrix_scan_tap_dance () { 106void matrix_scan_tap_dance () {
109 if (qk_tap_dance_state.active && timer_elapsed (qk_tap_dance_state.timer) > TAPPING_TERM) { 107 if (highest_td == -1)
110 // if we are here, the tap dance was timed out 108 return;
111 uint16_t idx = qk_tap_dance_state.keycode - QK_TAP_DANCE; 109
112 qk_tap_dance_action_t action = tap_dance_actions[idx]; 110 for (int i = 0; i <= highest_td; i++) {
111 qk_tap_dance_action_t *action = &tap_dance_actions[i];
113 112
114 process_tap_dance_action_on_dance_finished (action); 113 if (action->state.count && timer_elapsed (action->state.timer) > TAPPING_TERM) {
115 reset_tap_dance (&qk_tap_dance_state); 114 process_tap_dance_action_on_dance_finished (action);
115 reset_tap_dance (&action->state);
116 }
116 } 117 }
117} 118}
118 119
119void reset_tap_dance (qk_tap_dance_state_t *state) { 120void reset_tap_dance (qk_tap_dance_state_t *state) {
120 uint16_t idx = state->keycode - QK_TAP_DANCE; 121 qk_tap_dance_action_t *action;
121 qk_tap_dance_action_t action;
122 122
123 if (state->pressed) 123 if (state->pressed)
124 return; 124 return;
125 125
126 action = tap_dance_actions[idx]; 126 action = &tap_dance_actions[state->keycode - QK_TAP_DANCE];
127
127 process_tap_dance_action_on_reset (action); 128 process_tap_dance_action_on_reset (action);
128 129
129 state->keycode = 0;
130 state->count = 0; 130 state->count = 0;
131 state->active = false; 131 state->interrupted = false;
132 state->finished = false;
133 last_td = 0;
132} 134}
diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h
index 6a1258067..d7b857bdc 100644
--- a/quantum/process_keycode/process_tap_dance.h
+++ b/quantum/process_keycode/process_tap_dance.h
@@ -11,8 +11,9 @@ typedef struct
11 uint8_t count; 11 uint8_t count;
12 uint16_t keycode; 12 uint16_t keycode;
13 uint16_t timer; 13 uint16_t timer;
14 bool active:1; 14 bool interrupted;
15 bool pressed:1; 15 bool pressed;
16 bool finished;
16} qk_tap_dance_state_t; 17} qk_tap_dance_state_t;
17 18
18#define TD(n) (QK_TAP_DANCE + n) 19#define TD(n) (QK_TAP_DANCE + n)
@@ -26,6 +27,7 @@ typedef struct
26 qk_tap_dance_user_fn_t on_dance_finished; 27 qk_tap_dance_user_fn_t on_dance_finished;
27 qk_tap_dance_user_fn_t on_reset; 28 qk_tap_dance_user_fn_t on_reset;
28 } fn; 29 } fn;
30 qk_tap_dance_state_t state;
29 void *user_data; 31 void *user_data;
30} qk_tap_dance_action_t; 32} qk_tap_dance_action_t;
31 33
@@ -48,8 +50,7 @@ typedef struct
48 .fn = { user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_reset } \ 50 .fn = { user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_reset } \
49 } 51 }
50 52
51extern const qk_tap_dance_action_t tap_dance_actions[]; 53extern qk_tap_dance_action_t tap_dance_actions[];
52extern bool td_debug_enable;
53 54
54/* To be used internally */ 55/* To be used internally */
55 56
diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c
index ad5d7f86b..72c809c30 100644
--- a/quantum/process_keycode/process_unicode.c
+++ b/quantum/process_keycode/process_unicode.c
@@ -13,45 +13,192 @@ uint16_t hex_to_keycode(uint8_t hex)
13 } 13 }
14} 14}
15 15
16void set_unicode_mode(uint8_t os_target) 16void set_unicode_input_mode(uint8_t os_target)
17{ 17{
18 input_mode = os_target; 18 input_mode = os_target;
19} 19}
20 20
21void unicode_input_start (void) {
22 switch(input_mode) {
23 case UC_OSX:
24 register_code(KC_LALT);
25 break;
26 case UC_LNX:
27 register_code(KC_LCTL);
28 register_code(KC_LSFT);
29 register_code(KC_U);
30 unregister_code(KC_U);
31 unregister_code(KC_LSFT);
32 unregister_code(KC_LCTL);
33 break;
34 case UC_WIN:
35 register_code(KC_LALT);
36 register_code(KC_PPLS);
37 unregister_code(KC_PPLS);
38 break;
39 }
40 wait_ms(UNICODE_TYPE_DELAY);
41}
42
43void unicode_input_finish (void) {
44 switch(input_mode) {
45 case UC_OSX:
46 case UC_WIN:
47 unregister_code(KC_LALT);
48 break;
49 case UC_LNX:
50 register_code(KC_SPC);
51 unregister_code(KC_SPC);
52 break;
53 }
54}
55
56void register_hex(uint16_t hex) {
57 for(int i = 3; i >= 0; i--) {
58 uint8_t digit = ((hex >> (i*4)) & 0xF);
59 register_code(hex_to_keycode(digit));
60 unregister_code(hex_to_keycode(digit));
61 }
62}
63
21bool process_unicode(uint16_t keycode, keyrecord_t *record) { 64bool process_unicode(uint16_t keycode, keyrecord_t *record) {
22 if (keycode > QK_UNICODE && record->event.pressed) { 65 if (keycode > QK_UNICODE && record->event.pressed) {
23 uint16_t unicode = keycode & 0x7FFF; 66 uint16_t unicode = keycode & 0x7FFF;
24 switch(input_mode) { 67 unicode_input_start();
25 case UC_OSX: 68 register_hex(unicode);
26 register_code(KC_LALT); 69 unicode_input_finish();
27 break; 70 }
28 case UC_LNX: 71 return true;
29 register_code(KC_LCTL); 72}
30 register_code(KC_LSFT); 73
31 register_code(KC_U); 74#ifdef UCIS_ENABLE
32 unregister_code(KC_U); 75void qk_ucis_start(void) {
33 break; 76 qk_ucis_state.count = 0;
34 case UC_WIN: 77 qk_ucis_state.in_progress = true;
35 register_code(KC_LALT); 78
36 register_code(KC_PPLS); 79 qk_ucis_start_user();
37 unregister_code(KC_PPLS); 80}
38 break; 81
82__attribute__((weak))
83void qk_ucis_start_user(void) {
84 unicode_input_start();
85 register_hex(0x2328);
86 unicode_input_finish();
87}
88
89static bool is_uni_seq(char *seq) {
90 uint8_t i;
91
92 for (i = 0; seq[i]; i++) {
93 uint16_t code;
94 if (('1' <= seq[i]) && (seq[i] <= '0'))
95 code = seq[i] - '1' + KC_1;
96 else
97 code = seq[i] - 'a' + KC_A;
98
99 if (i > qk_ucis_state.count || qk_ucis_state.codes[i] != code)
100 return false;
101 }
102
103 return (qk_ucis_state.codes[i] == KC_ENT ||
104 qk_ucis_state.codes[i] == KC_SPC);
105}
106
107__attribute__((weak))
108void qk_ucis_symbol_fallback (void) {
109 for (uint8_t i = 0; i < qk_ucis_state.count - 1; i++) {
110 uint8_t code = qk_ucis_state.codes[i];
111 register_code(code);
112 unregister_code(code);
113 wait_ms(UNICODE_TYPE_DELAY);
114 }
115}
116
117void register_ucis(const char *hex) {
118 for(int i = 0; hex[i]; i++) {
119 uint8_t kc = 0;
120 char c = hex[i];
121
122 switch (c) {
123 case '0':
124 kc = KC_0;
125 break;
126 case '1' ... '9':
127 kc = c - '1' + KC_1;
128 break;
129 case 'a' ... 'f':
130 kc = c - 'a' + KC_A;
131 break;
132 case 'A' ... 'F':
133 kc = c - 'A' + KC_A;
134 break;
39 } 135 }
40 for(int i = 3; i >= 0; i--) { 136
41 uint8_t digit = ((unicode >> (i*4)) & 0xF); 137 if (kc) {
42 register_code(hex_to_keycode(digit)); 138 register_code (kc);
43 unregister_code(hex_to_keycode(digit)); 139 unregister_code (kc);
140 wait_ms (UNICODE_TYPE_DELAY);
44 } 141 }
45 switch(input_mode) { 142 }
46 case UC_OSX: 143}
47 case UC_WIN: 144
48 unregister_code(KC_LALT); 145bool process_ucis (uint16_t keycode, keyrecord_t *record) {
49 break; 146 uint8_t i;
50 case UC_LNX: 147
51 unregister_code(KC_LCTL); 148 if (!qk_ucis_state.in_progress)
52 unregister_code(KC_LSFT); 149 return true;
150
151 if (qk_ucis_state.count >= UCIS_MAX_SYMBOL_LENGTH &&
152 !(keycode == KC_BSPC || keycode == KC_ESC || keycode == KC_SPC || keycode == KC_ENT)) {
153 return false;
154 }
155
156 if (!record->event.pressed)
157 return true;
158
159 qk_ucis_state.codes[qk_ucis_state.count] = keycode;
160 qk_ucis_state.count++;
161
162 if (keycode == KC_BSPC) {
163 if (qk_ucis_state.count >= 2) {
164 qk_ucis_state.count -= 2;
165 return true;
166 } else {
167 qk_ucis_state.count--;
168 return false;
169 }
170 }
171
172 if (keycode == KC_ENT || keycode == KC_SPC || keycode == KC_ESC) {
173 bool symbol_found = false;
174
175 for (i = qk_ucis_state.count; i > 0; i--) {
176 register_code (KC_BSPC);
177 unregister_code (KC_BSPC);
178 wait_ms(UNICODE_TYPE_DELAY);
179 }
180
181 if (keycode == KC_ESC) {
182 qk_ucis_state.in_progress = false;
183 return false;
184 }
185
186 unicode_input_start();
187 for (i = 0; ucis_symbol_table[i].symbol; i++) {
188 if (is_uni_seq (ucis_symbol_table[i].symbol)) {
189 symbol_found = true;
190 register_ucis(ucis_symbol_table[i].code + 2);
53 break; 191 break;
192 }
54 } 193 }
194 if (!symbol_found) {
195 qk_ucis_symbol_fallback();
196 }
197 unicode_input_finish();
198
199 qk_ucis_state.in_progress = false;
200 return false;
55 } 201 }
56 return true; 202 return true;
57} \ No newline at end of file 203}
204#endif
diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h
index ca17f8f66..85364e8eb 100644
--- a/quantum/process_keycode/process_unicode.h
+++ b/quantum/process_keycode/process_unicode.h
@@ -8,10 +8,46 @@
8#define UC_WIN 2 8#define UC_WIN 2
9#define UC_BSD 3 9#define UC_BSD 3
10 10
11#ifndef UNICODE_TYPE_DELAY
12#define UNICODE_TYPE_DELAY 10
13#endif
14
11void set_unicode_input_mode(uint8_t os_target); 15void set_unicode_input_mode(uint8_t os_target);
16void unicode_input_start(void);
17void unicode_input_finish(void);
18void register_hex(uint16_t hex);
12 19
13bool process_unicode(uint16_t keycode, keyrecord_t *record); 20bool process_unicode(uint16_t keycode, keyrecord_t *record);
14 21
22#ifdef UCIS_ENABLE
23#ifndef UCIS_MAX_SYMBOL_LENGTH
24#define UCIS_MAX_SYMBOL_LENGTH 32
25#endif
26
27typedef struct {
28 char *symbol;
29 char *code;
30} qk_ucis_symbol_t;
31
32struct {
33 uint8_t count;
34 uint16_t codes[UCIS_MAX_SYMBOL_LENGTH];
35 bool in_progress:1;
36} qk_ucis_state;
37
38#define UCIS_TABLE(...) {__VA_ARGS__, {NULL, NULL}}
39#define UCIS_SYM(name, code) {name, #code}
40
41extern const qk_ucis_symbol_t ucis_symbol_table[];
42
43void qk_ucis_start(void);
44void qk_ucis_start_user(void);
45void qk_ucis_symbol_fallback (void);
46void register_ucis(const char *hex);
47bool process_ucis (uint16_t keycode, keyrecord_t *record);
48
49#endif
50
15#define UC_BSPC UC(0x0008) 51#define UC_BSPC UC(0x0008)
16 52
17#define UC_SPC UC(0x0020) 53#define UC_SPC UC(0x0020)
@@ -119,4 +155,4 @@ bool process_unicode(uint16_t keycode, keyrecord_t *record);
119#define UC_TILD UC(0x007E) 155#define UC_TILD UC(0x007E)
120#define UC_DEL UC(0x007F) 156#define UC_DEL UC(0x007F)
121 157
122#endif \ No newline at end of file 158#endif