diff options
Diffstat (limited to 'quantum/process_keycode')
| -rw-r--r-- | quantum/process_keycode/process_auto_shift.c | 2 | ||||
| -rw-r--r-- | quantum/process_keycode/process_chording.c | 76 | ||||
| -rw-r--r-- | quantum/process_keycode/process_chording.h | 32 | ||||
| -rw-r--r-- | quantum/process_keycode/process_clicky.c | 72 | ||||
| -rw-r--r-- | quantum/process_keycode/process_clicky.h | 10 | ||||
| -rw-r--r-- | quantum/process_keycode/process_leader.c | 49 | ||||
| -rw-r--r-- | quantum/process_keycode/process_leader.h | 2 | ||||
| -rw-r--r-- | quantum/process_keycode/process_tap_dance.c | 6 | ||||
| -rw-r--r-- | quantum/process_keycode/process_tap_dance.h | 1 | ||||
| -rw-r--r-- | quantum/process_keycode/process_terminal.c | 6 | ||||
| -rw-r--r-- | quantum/process_keycode/process_ucis.c | 8 | ||||
| -rw-r--r-- | quantum/process_keycode/process_ucis.h | 6 | ||||
| -rw-r--r-- | quantum/process_keycode/process_unicode.c | 7 | ||||
| -rw-r--r-- | quantum/process_keycode/process_unicode.h | 5 | ||||
| -rw-r--r-- | quantum/process_keycode/process_unicode_common.c | 223 | ||||
| -rw-r--r-- | quantum/process_keycode/process_unicode_common.h | 68 | ||||
| -rw-r--r-- | quantum/process_keycode/process_unicodemap.c | 33 | ||||
| -rw-r--r-- | quantum/process_keycode/process_unicodemap.h | 8 |
18 files changed, 353 insertions, 261 deletions
diff --git a/quantum/process_keycode/process_auto_shift.c b/quantum/process_keycode/process_auto_shift.c index 01d99445b..0d0930ee6 100644 --- a/quantum/process_keycode/process_auto_shift.c +++ b/quantum/process_keycode/process_auto_shift.c | |||
| @@ -173,6 +173,8 @@ bool process_auto_shift(uint16_t keycode, keyrecord_t *record) { | |||
| 173 | case KC_DOT: | 173 | case KC_DOT: |
| 174 | case KC_SLSH: | 174 | case KC_SLSH: |
| 175 | case KC_GRAVE: | 175 | case KC_GRAVE: |
| 176 | case KC_NONUS_BSLASH: | ||
| 177 | case KC_NONUS_HASH: | ||
| 176 | #endif | 178 | #endif |
| 177 | 179 | ||
| 178 | autoshift_flush(); | 180 | autoshift_flush(); |
diff --git a/quantum/process_keycode/process_chording.c b/quantum/process_keycode/process_chording.c deleted file mode 100644 index 6c6ebe300..000000000 --- a/quantum/process_keycode/process_chording.c +++ /dev/null | |||
| @@ -1,76 +0,0 @@ | |||
| 1 | /* Copyright 2016 Jack Humbert | ||
| 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 | #include "process_chording.h" | ||
| 18 | |||
| 19 | bool keys_chord(uint8_t keys[]) { | ||
| 20 | uint8_t keys_size = sizeof(keys)/sizeof(keys[0]); | ||
| 21 | bool pass = true; | ||
| 22 | uint8_t in = 0; | ||
| 23 | for (uint8_t i = 0; i < chord_key_count; i++) { | ||
| 24 | bool found = false; | ||
| 25 | for (uint8_t j = 0; j < keys_size; j++) { | ||
| 26 | if (chord_keys[i] == (keys[j] & 0xFF)) { | ||
| 27 | in++; // detects key in chord | ||
| 28 | found = true; | ||
| 29 | break; | ||
| 30 | } | ||
| 31 | } | ||
| 32 | if (found) | ||
| 33 | continue; | ||
| 34 | if (chord_keys[i] != 0) { | ||
| 35 | pass = false; // makes sure rest are blank | ||
| 36 | } | ||
| 37 | } | ||
| 38 | return (pass && (in == keys_size)); | ||
| 39 | } | ||
| 40 | |||
| 41 | bool process_chording(uint16_t keycode, keyrecord_t *record) { | ||
| 42 | if (keycode >= QK_CHORDING && keycode <= QK_CHORDING_MAX) { | ||
| 43 | if (record->event.pressed) { | ||
| 44 | if (!chording) { | ||
| 45 | chording = true; | ||
| 46 | for (uint8_t i = 0; i < CHORDING_MAX; i++) | ||
| 47 | chord_keys[i] = 0; | ||
| 48 | chord_key_count = 0; | ||
| 49 | chord_key_down = 0; | ||
| 50 | } | ||
| 51 | chord_keys[chord_key_count] = (keycode & 0xFF); | ||
| 52 | chord_key_count++; | ||
| 53 | chord_key_down++; | ||
| 54 | return false; | ||
| 55 | } else { | ||
| 56 | if (chording) { | ||
| 57 | chord_key_down--; | ||
| 58 | if (chord_key_down == 0) { | ||
| 59 | chording = false; | ||
| 60 | // Chord Dictionary | ||
| 61 | if (keys_chord((uint8_t[]){KC_ENTER, KC_SPACE})) { | ||
| 62 | register_code(KC_A); | ||
| 63 | unregister_code(KC_A); | ||
| 64 | return false; | ||
| 65 | } | ||
| 66 | for (uint8_t i = 0; i < chord_key_count; i++) { | ||
| 67 | register_code(chord_keys[i]); | ||
| 68 | unregister_code(chord_keys[i]); | ||
| 69 | return false; | ||
| 70 | } | ||
| 71 | } | ||
| 72 | } | ||
| 73 | } | ||
| 74 | } | ||
| 75 | return true; | ||
| 76 | } | ||
diff --git a/quantum/process_keycode/process_chording.h b/quantum/process_keycode/process_chording.h deleted file mode 100644 index 8c0f4862a..000000000 --- a/quantum/process_keycode/process_chording.h +++ /dev/null | |||
| @@ -1,32 +0,0 @@ | |||
| 1 | /* Copyright 2016 Jack Humbert | ||
| 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 | #ifndef PROCESS_CHORDING_H | ||
| 18 | #define PROCESS_CHORDING_H | ||
| 19 | |||
| 20 | #include "quantum.h" | ||
| 21 | |||
| 22 | // Chording stuff | ||
| 23 | #define CHORDING_MAX 4 | ||
| 24 | bool chording = false; | ||
| 25 | |||
| 26 | uint8_t chord_keys[CHORDING_MAX] = {0}; | ||
| 27 | uint8_t chord_key_count = 0; | ||
| 28 | uint8_t chord_key_down = 0; | ||
| 29 | |||
| 30 | bool process_chording(uint16_t keycode, keyrecord_t *record); | ||
| 31 | |||
| 32 | #endif | ||
diff --git a/quantum/process_keycode/process_clicky.c b/quantum/process_keycode/process_clicky.c index 1e950d111..8238c263f 100644 --- a/quantum/process_keycode/process_clicky.c +++ b/quantum/process_keycode/process_clicky.c | |||
| @@ -3,11 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | #ifdef AUDIO_CLICKY | 4 | #ifdef AUDIO_CLICKY |
| 5 | 5 | ||
| 6 | #ifdef AUDIO_CLICKY_ON | ||
| 7 | bool clicky_enable = true; | ||
| 8 | #else // AUDIO_CLICKY_ON | ||
| 9 | bool clicky_enable = false; | ||
| 10 | #endif // AUDIO_CLICKY_ON | ||
| 11 | #ifndef AUDIO_CLICKY_FREQ_DEFAULT | 6 | #ifndef AUDIO_CLICKY_FREQ_DEFAULT |
| 12 | #define AUDIO_CLICKY_FREQ_DEFAULT 440.0f | 7 | #define AUDIO_CLICKY_FREQ_DEFAULT 440.0f |
| 13 | #endif // !AUDIO_CLICKY_FREQ_DEFAULT | 8 | #endif // !AUDIO_CLICKY_FREQ_DEFAULT |
| @@ -25,8 +20,11 @@ bool clicky_enable = false; | |||
| 25 | #endif // !AUDIO_CLICKY_FREQ_RANDOMNESS | 20 | #endif // !AUDIO_CLICKY_FREQ_RANDOMNESS |
| 26 | 21 | ||
| 27 | float clicky_freq = AUDIO_CLICKY_FREQ_DEFAULT; | 22 | float clicky_freq = AUDIO_CLICKY_FREQ_DEFAULT; |
| 23 | float clicky_rand = AUDIO_CLICKY_FREQ_RANDOMNESS; | ||
| 28 | float clicky_song[][2] = {{AUDIO_CLICKY_FREQ_DEFAULT, 3}, {AUDIO_CLICKY_FREQ_DEFAULT, 1}}; // 3 and 1 --> durations | 24 | float clicky_song[][2] = {{AUDIO_CLICKY_FREQ_DEFAULT, 3}, {AUDIO_CLICKY_FREQ_DEFAULT, 1}}; // 3 and 1 --> durations |
| 29 | 25 | ||
| 26 | extern audio_config_t audio_config; | ||
| 27 | |||
| 30 | #ifndef NO_MUSIC_MODE | 28 | #ifndef NO_MUSIC_MODE |
| 31 | extern bool music_activated; | 29 | extern bool music_activated; |
| 32 | extern bool midi_activated; | 30 | extern bool midi_activated; |
| @@ -36,31 +34,61 @@ void clicky_play(void) { | |||
| 36 | #ifndef NO_MUSIC_MODE | 34 | #ifndef NO_MUSIC_MODE |
| 37 | if (music_activated || midi_activated) return; | 35 | if (music_activated || midi_activated) return; |
| 38 | #endif // !NO_MUSIC_MODE | 36 | #endif // !NO_MUSIC_MODE |
| 39 | clicky_song[0][0] = 2.0f * clicky_freq * (1.0f + AUDIO_CLICKY_FREQ_RANDOMNESS * ( ((float)rand()) / ((float)(RAND_MAX)) ) ); | 37 | clicky_song[0][0] = 2.0f * clicky_freq * (1.0f + clicky_rand * ( ((float)rand()) / ((float)(RAND_MAX)) ) ); |
| 40 | clicky_song[1][0] = clicky_freq * (1.0f + AUDIO_CLICKY_FREQ_RANDOMNESS * ( ((float)rand()) / ((float)(RAND_MAX)) ) ); | 38 | clicky_song[1][0] = clicky_freq * (1.0f + clicky_rand * ( ((float)rand()) / ((float)(RAND_MAX)) ) ); |
| 41 | PLAY_SONG(clicky_song); | 39 | PLAY_SONG(clicky_song); |
| 42 | } | 40 | } |
| 43 | 41 | ||
| 42 | void clicky_freq_up(void) { | ||
| 43 | float new_freq = clicky_freq * AUDIO_CLICKY_FREQ_FACTOR; | ||
| 44 | if (new_freq < AUDIO_CLICKY_FREQ_MAX) { | ||
| 45 | clicky_freq = new_freq; | ||
| 46 | } | ||
| 47 | } | ||
| 48 | |||
| 49 | void clicky_freq_down(void) { | ||
| 50 | float new_freq = clicky_freq / AUDIO_CLICKY_FREQ_FACTOR; | ||
| 51 | if (new_freq > AUDIO_CLICKY_FREQ_MIN) { | ||
| 52 | clicky_freq = new_freq; | ||
| 53 | } | ||
| 54 | } | ||
| 55 | |||
| 56 | void clicky_freq_reset(void) { | ||
| 57 | clicky_freq = AUDIO_CLICKY_FREQ_DEFAULT; | ||
| 58 | } | ||
| 59 | |||
| 60 | void clicky_toggle(void) { | ||
| 61 | audio_config.clicky_enable ^= 1; | ||
| 62 | eeconfig_update_audio(audio_config.raw); | ||
| 63 | } | ||
| 64 | |||
| 65 | void clicky_on(void) { | ||
| 66 | audio_config.clicky_enable = 1; | ||
| 67 | eeconfig_update_audio(audio_config.raw); | ||
| 68 | } | ||
| 69 | |||
| 70 | void clicky_off(void) { | ||
| 71 | audio_config.clicky_enable = 0; | ||
| 72 | eeconfig_update_audio(audio_config.raw); | ||
| 73 | } | ||
| 74 | |||
| 75 | bool is_clicky_on(void) { | ||
| 76 | return (audio_config.clicky_enable != 0); | ||
| 77 | } | ||
| 78 | |||
| 44 | bool process_clicky(uint16_t keycode, keyrecord_t *record) { | 79 | bool process_clicky(uint16_t keycode, keyrecord_t *record) { |
| 45 | if (keycode == CLICKY_TOGGLE && record->event.pressed) { clicky_enable = !clicky_enable; } | 80 | if (keycode == CLICKY_TOGGLE && record->event.pressed) { clicky_toggle(); } |
| 46 | 81 | ||
| 47 | if (keycode == CLICKY_RESET && record->event.pressed) { clicky_freq = AUDIO_CLICKY_FREQ_DEFAULT; } | 82 | if (keycode == CLICKY_ENABLE && record->event.pressed) { clicky_on(); } |
| 83 | if (keycode == CLICKY_DISABLE && record->event.pressed) { clicky_off(); } | ||
| 48 | 84 | ||
| 49 | if (keycode == CLICKY_UP && record->event.pressed) { | 85 | if (keycode == CLICKY_RESET && record->event.pressed) { clicky_freq_reset(); } |
| 50 | float new_freq = clicky_freq * AUDIO_CLICKY_FREQ_FACTOR; | 86 | |
| 51 | if (new_freq < AUDIO_CLICKY_FREQ_MAX) { | 87 | if (keycode == CLICKY_UP && record->event.pressed) { clicky_freq_up(); } |
| 52 | clicky_freq = new_freq; | 88 | if (keycode == CLICKY_DOWN && record->event.pressed) { clicky_freq_down(); } |
| 53 | } | ||
| 54 | } | ||
| 55 | if (keycode == CLICKY_DOWN && record->event.pressed) { | ||
| 56 | float new_freq = clicky_freq / AUDIO_CLICKY_FREQ_FACTOR; | ||
| 57 | if (new_freq > AUDIO_CLICKY_FREQ_MIN) { | ||
| 58 | clicky_freq = new_freq; | ||
| 59 | } | ||
| 60 | } | ||
| 61 | 89 | ||
| 62 | 90 | ||
| 63 | if ( clicky_enable ) { | 91 | if ( audio_config.clicky_enable ) { |
| 64 | if (record->event.pressed) { | 92 | if (record->event.pressed) { |
| 65 | clicky_play();; | 93 | clicky_play();; |
| 66 | } | 94 | } |
diff --git a/quantum/process_keycode/process_clicky.h b/quantum/process_keycode/process_clicky.h index e274af56f..f746edb95 100644 --- a/quantum/process_keycode/process_clicky.h +++ b/quantum/process_keycode/process_clicky.h | |||
| @@ -4,4 +4,14 @@ | |||
| 4 | void clicky_play(void); | 4 | void clicky_play(void); |
| 5 | bool process_clicky(uint16_t keycode, keyrecord_t *record); | 5 | bool process_clicky(uint16_t keycode, keyrecord_t *record); |
| 6 | 6 | ||
| 7 | void clicky_freq_up(void); | ||
| 8 | void clicky_freq_down(void); | ||
| 9 | void clicky_freq_reset(void); | ||
| 10 | |||
| 11 | void clicky_toggle(void); | ||
| 12 | void clicky_on(void); | ||
| 13 | void clicky_off(void); | ||
| 14 | |||
| 15 | bool is_clicky_on(void); | ||
| 16 | |||
| 7 | #endif | 17 | #endif |
diff --git a/quantum/process_keycode/process_leader.c b/quantum/process_keycode/process_leader.c index c87ef115a..897e9eabf 100644 --- a/quantum/process_keycode/process_leader.c +++ b/quantum/process_keycode/process_leader.c | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | #ifndef DISABLE_LEADER | 17 | #ifdef LEADER_ENABLE |
| 18 | 18 | ||
| 19 | #include "process_leader.h" | 19 | #include "process_leader.h" |
| 20 | 20 | ||
| @@ -35,25 +35,40 @@ uint16_t leader_time = 0; | |||
| 35 | uint16_t leader_sequence[5] = {0, 0, 0, 0, 0}; | 35 | uint16_t leader_sequence[5] = {0, 0, 0, 0, 0}; |
| 36 | uint8_t leader_sequence_size = 0; | 36 | uint8_t leader_sequence_size = 0; |
| 37 | 37 | ||
| 38 | void qk_leader_start(void) { | ||
| 39 | if (leading) { return; } | ||
| 40 | leader_start(); | ||
| 41 | leading = true; | ||
| 42 | leader_time = timer_read(); | ||
| 43 | leader_sequence_size = 0; | ||
| 44 | leader_sequence[0] = 0; | ||
| 45 | leader_sequence[1] = 0; | ||
| 46 | leader_sequence[2] = 0; | ||
| 47 | leader_sequence[3] = 0; | ||
| 48 | leader_sequence[4] = 0; | ||
| 49 | } | ||
| 50 | |||
| 38 | bool process_leader(uint16_t keycode, keyrecord_t *record) { | 51 | bool process_leader(uint16_t keycode, keyrecord_t *record) { |
| 39 | // Leader key set-up | 52 | // Leader key set-up |
| 40 | if (record->event.pressed) { | 53 | if (record->event.pressed) { |
| 41 | if (!leading && keycode == KC_LEAD) { | 54 | if (leading) { |
| 42 | leader_start(); | 55 | if (timer_elapsed(leader_time) < LEADER_TIMEOUT) { |
| 43 | leading = true; | 56 | #ifndef LEADER_KEY_STRICT_KEY_PROCESSING |
| 44 | leader_time = timer_read(); | 57 | if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)) { |
| 45 | leader_sequence_size = 0; | 58 | keycode = keycode & 0xFF; |
| 46 | leader_sequence[0] = 0; | 59 | } |
| 47 | leader_sequence[1] = 0; | 60 | #endif // LEADER_KEY_STRICT_KEY_PROCESSING |
| 48 | leader_sequence[2] = 0; | 61 | leader_sequence[leader_sequence_size] = keycode; |
| 49 | leader_sequence[3] = 0; | 62 | leader_sequence_size++; |
| 50 | leader_sequence[4] = 0; | 63 | #ifdef LEADER_PER_KEY_TIMING |
| 51 | return false; | 64 | leader_time = timer_read(); |
| 52 | } | 65 | #endif |
| 53 | if (leading && timer_elapsed(leader_time) < LEADER_TIMEOUT) { | 66 | return false; |
| 54 | leader_sequence[leader_sequence_size] = keycode; | 67 | } |
| 55 | leader_sequence_size++; | 68 | } else { |
| 56 | return false; | 69 | if (keycode == KC_LEAD) { |
| 70 | qk_leader_start(); | ||
| 71 | } | ||
| 57 | } | 72 | } |
| 58 | } | 73 | } |
| 59 | return true; | 74 | return true; |
diff --git a/quantum/process_keycode/process_leader.h b/quantum/process_keycode/process_leader.h index 59c3eed1b..15bccc3f6 100644 --- a/quantum/process_keycode/process_leader.h +++ b/quantum/process_keycode/process_leader.h | |||
| @@ -24,7 +24,7 @@ bool process_leader(uint16_t keycode, keyrecord_t *record); | |||
| 24 | 24 | ||
| 25 | void leader_start(void); | 25 | void leader_start(void); |
| 26 | void leader_end(void); | 26 | void leader_end(void); |
| 27 | 27 | void qk_leader_start(void); | |
| 28 | 28 | ||
| 29 | #define SEQ_ONE_KEY(key) if (leader_sequence[0] == (key) && leader_sequence[1] == 0 && leader_sequence[2] == 0 && leader_sequence[3] == 0 && leader_sequence[4] == 0) | 29 | #define SEQ_ONE_KEY(key) if (leader_sequence[0] == (key) && leader_sequence[1] == 0 && leader_sequence[2] == 0 && leader_sequence[3] == 0 && leader_sequence[4] == 0) |
| 30 | #define SEQ_TWO_KEYS(key1, key2) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == 0 && leader_sequence[3] == 0 && leader_sequence[4] == 0) | 30 | #define SEQ_TWO_KEYS(key1, key2) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == 0 && leader_sequence[3] == 0 && leader_sequence[4] == 0) |
diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index 833780691..16d33ddde 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c | |||
| @@ -16,6 +16,10 @@ | |||
| 16 | #include "quantum.h" | 16 | #include "quantum.h" |
| 17 | #include "action_tapping.h" | 17 | #include "action_tapping.h" |
| 18 | 18 | ||
| 19 | #ifndef TAPPING_TERM | ||
| 20 | #define TAPPING_TERM 200 | ||
| 21 | #endif | ||
| 22 | |||
| 19 | #ifndef NO_ACTION_ONESHOT | 23 | #ifndef NO_ACTION_ONESHOT |
| 20 | uint8_t get_oneshot_mods(void); | 24 | uint8_t get_oneshot_mods(void); |
| 21 | #endif | 25 | #endif |
| @@ -127,6 +131,7 @@ void preprocess_tap_dance(uint16_t keycode, keyrecord_t *record) { | |||
| 127 | if (keycode == action->state.keycode && keycode == last_td) | 131 | if (keycode == action->state.keycode && keycode == last_td) |
| 128 | continue; | 132 | continue; |
| 129 | action->state.interrupted = true; | 133 | action->state.interrupted = true; |
| 134 | action->state.interrupting_keycode = keycode; | ||
| 130 | process_tap_dance_action_on_dance_finished (action); | 135 | process_tap_dance_action_on_dance_finished (action); |
| 131 | reset_tap_dance (&action->state); | 136 | reset_tap_dance (&action->state); |
| 132 | } | 137 | } |
| @@ -205,5 +210,6 @@ void reset_tap_dance (qk_tap_dance_state_t *state) { | |||
| 205 | state->count = 0; | 210 | state->count = 0; |
| 206 | state->interrupted = false; | 211 | state->interrupted = false; |
| 207 | state->finished = false; | 212 | state->finished = false; |
| 213 | state->interrupting_keycode = 0; | ||
| 208 | last_td = 0; | 214 | last_td = 0; |
| 209 | } | 215 | } |
diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h index 8b0a47c49..ca12f4746 100644 --- a/quantum/process_keycode/process_tap_dance.h +++ b/quantum/process_keycode/process_tap_dance.h | |||
| @@ -27,6 +27,7 @@ typedef struct | |||
| 27 | uint8_t oneshot_mods; | 27 | uint8_t oneshot_mods; |
| 28 | uint8_t weak_mods; | 28 | uint8_t weak_mods; |
| 29 | uint16_t keycode; | 29 | uint16_t keycode; |
| 30 | uint16_t interrupting_keycode; | ||
| 30 | uint16_t timer; | 31 | uint16_t timer; |
| 31 | bool interrupted; | 32 | bool interrupted; |
| 32 | bool pressed; | 33 | bool pressed; |
diff --git a/quantum/process_keycode/process_terminal.c b/quantum/process_keycode/process_terminal.c index 6998639f2..e791deffc 100644 --- a/quantum/process_keycode/process_terminal.c +++ b/quantum/process_keycode/process_terminal.c | |||
| @@ -273,11 +273,17 @@ bool process_terminal(uint16_t keycode, keyrecord_t *record) { | |||
| 273 | disable_terminal(); | 273 | disable_terminal(); |
| 274 | return false; | 274 | return false; |
| 275 | } | 275 | } |
| 276 | |||
| 277 | if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)) { | ||
| 278 | keycode = keycode & 0xFF; | ||
| 279 | } | ||
| 280 | |||
| 276 | if (keycode < 256) { | 281 | if (keycode < 256) { |
| 277 | uint8_t str_len; | 282 | uint8_t str_len; |
| 278 | char char_to_add; | 283 | char char_to_add; |
| 279 | switch (keycode) { | 284 | switch (keycode) { |
| 280 | case KC_ENTER: | 285 | case KC_ENTER: |
| 286 | case KC_KP_ENTER: | ||
| 281 | push_to_cmd_buffer(); | 287 | push_to_cmd_buffer(); |
| 282 | current_cmd_buffer_pos = 0; | 288 | current_cmd_buffer_pos = 0; |
| 283 | process_terminal_command(); | 289 | process_terminal_command(); |
diff --git a/quantum/process_keycode/process_ucis.c b/quantum/process_keycode/process_ucis.c index 86c0937f5..5de2e41fc 100644 --- a/quantum/process_keycode/process_ucis.c +++ b/quantum/process_keycode/process_ucis.c | |||
| @@ -32,6 +32,10 @@ void qk_ucis_start_user(void) { | |||
| 32 | unicode_input_finish(); | 32 | unicode_input_finish(); |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | __attribute__((weak)) | ||
| 36 | void qk_ucis_success(uint8_t symbol_index) { | ||
| 37 | } | ||
| 38 | |||
| 35 | static bool is_uni_seq(char *seq) { | 39 | static bool is_uni_seq(char *seq) { |
| 36 | uint8_t i; | 40 | uint8_t i; |
| 37 | 41 | ||
| @@ -142,6 +146,10 @@ bool process_ucis (uint16_t keycode, keyrecord_t *record) { | |||
| 142 | } | 146 | } |
| 143 | unicode_input_finish(); | 147 | unicode_input_finish(); |
| 144 | 148 | ||
| 149 | if (symbol_found) { | ||
| 150 | qk_ucis_success(i); | ||
| 151 | } | ||
| 152 | |||
| 145 | qk_ucis_state.in_progress = false; | 153 | qk_ucis_state.in_progress = false; |
| 146 | return false; | 154 | return false; |
| 147 | } | 155 | } |
diff --git a/quantum/process_keycode/process_ucis.h b/quantum/process_keycode/process_ucis.h index 3f736a709..b114d839a 100644 --- a/quantum/process_keycode/process_ucis.h +++ b/quantum/process_keycode/process_ucis.h | |||
| @@ -14,8 +14,7 @@ | |||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | #ifndef PROCESS_UCIS_H | 17 | #pragma once |
| 18 | #define PROCESS_UCIS_H | ||
| 19 | 18 | ||
| 20 | #include "quantum.h" | 19 | #include "quantum.h" |
| 21 | #include "process_unicode_common.h" | 20 | #include "process_unicode_common.h" |
| @@ -45,7 +44,6 @@ extern const qk_ucis_symbol_t ucis_symbol_table[]; | |||
| 45 | void qk_ucis_start(void); | 44 | void qk_ucis_start(void); |
| 46 | void qk_ucis_start_user(void); | 45 | void qk_ucis_start_user(void); |
| 47 | void qk_ucis_symbol_fallback (void); | 46 | void qk_ucis_symbol_fallback (void); |
| 47 | void qk_ucis_success(uint8_t symbol_index); | ||
| 48 | void register_ucis(const char *hex); | 48 | void register_ucis(const char *hex); |
| 49 | bool process_ucis (uint16_t keycode, keyrecord_t *record); | 49 | bool process_ucis (uint16_t keycode, keyrecord_t *record); |
| 50 | |||
| 51 | #endif | ||
diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index fd008eca1..19beb8452 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c | |||
| @@ -17,14 +17,8 @@ | |||
| 17 | #include "action_util.h" | 17 | #include "action_util.h" |
| 18 | #include "eeprom.h" | 18 | #include "eeprom.h" |
| 19 | 19 | ||
| 20 | static uint8_t first_flag = 0; | ||
| 21 | |||
| 22 | bool process_unicode(uint16_t keycode, keyrecord_t *record) { | 20 | bool process_unicode(uint16_t keycode, keyrecord_t *record) { |
| 23 | if (keycode > QK_UNICODE && record->event.pressed) { | 21 | if (keycode > QK_UNICODE && record->event.pressed) { |
| 24 | if (first_flag == 0) { | ||
| 25 | set_unicode_input_mode(eeprom_read_byte(EECONFIG_UNICODEMODE)); | ||
| 26 | first_flag = 1; | ||
| 27 | } | ||
| 28 | uint16_t unicode = keycode & 0x7FFF; | 22 | uint16_t unicode = keycode & 0x7FFF; |
| 29 | unicode_input_start(); | 23 | unicode_input_start(); |
| 30 | register_hex(unicode); | 24 | register_hex(unicode); |
| @@ -32,4 +26,3 @@ bool process_unicode(uint16_t keycode, keyrecord_t *record) { | |||
| 32 | } | 26 | } |
| 33 | return true; | 27 | return true; |
| 34 | } | 28 | } |
| 35 | |||
diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h index c525b74f0..0913e9910 100644 --- a/quantum/process_keycode/process_unicode.h +++ b/quantum/process_keycode/process_unicode.h | |||
| @@ -13,12 +13,9 @@ | |||
| 13 | * You should have received a copy of the GNU General Public License | 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/>. | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 15 | */ | 15 | */ |
| 16 | #ifndef PROCESS_UNICODE_H | 16 | #pragma once |
| 17 | #define PROCESS_UNICODE_H | ||
| 18 | 17 | ||
| 19 | #include "quantum.h" | 18 | #include "quantum.h" |
| 20 | #include "process_unicode_common.h" | 19 | #include "process_unicode_common.h" |
| 21 | 20 | ||
| 22 | bool process_unicode(uint16_t keycode, keyrecord_t *record); | 21 | bool process_unicode(uint16_t keycode, keyrecord_t *record); |
| 23 | |||
| 24 | #endif | ||
diff --git a/quantum/process_keycode/process_unicode_common.c b/quantum/process_keycode/process_unicode_common.c index 7f34ad57c..b64feb700 100644 --- a/quantum/process_keycode/process_unicode_common.c +++ b/quantum/process_keycode/process_unicode_common.c | |||
| @@ -16,94 +16,115 @@ | |||
| 16 | 16 | ||
| 17 | #include "process_unicode_common.h" | 17 | #include "process_unicode_common.h" |
| 18 | #include "eeprom.h" | 18 | #include "eeprom.h" |
| 19 | #include <ctype.h> | ||
| 20 | #include <string.h> | ||
| 19 | 21 | ||
| 20 | static uint8_t input_mode; | 22 | unicode_config_t unicode_config; |
| 21 | uint8_t mods; | 23 | #if UNICODE_SELECTED_MODES != -1 |
| 24 | static uint8_t selected[] = { UNICODE_SELECTED_MODES }; | ||
| 25 | static uint8_t selected_count = sizeof selected / sizeof *selected; | ||
| 26 | static uint8_t selected_index; | ||
| 27 | #endif | ||
| 22 | 28 | ||
| 23 | void set_unicode_input_mode(uint8_t os_target) | 29 | void unicode_input_mode_init(void) { |
| 24 | { | 30 | unicode_config.raw = eeprom_read_byte(EECONFIG_UNICODEMODE); |
| 25 | input_mode = os_target; | 31 | #if UNICODE_SELECTED_MODES != -1 |
| 26 | eeprom_update_byte(EECONFIG_UNICODEMODE, os_target); | 32 | #if UNICODE_CYCLE_PERSIST |
| 33 | // Find input_mode in selected modes | ||
| 34 | uint8_t i; | ||
| 35 | for (i = 0; i < selected_count; i++) { | ||
| 36 | if (selected[i] == unicode_config.input_mode) { | ||
| 37 | selected_index = i; | ||
| 38 | break; | ||
| 39 | } | ||
| 40 | } | ||
| 41 | if (i == selected_count) { | ||
| 42 | // Not found: input_mode isn't selected, change to one that is | ||
| 43 | unicode_config.input_mode = selected[selected_index = 0]; | ||
| 44 | } | ||
| 45 | #else | ||
| 46 | // Always change to the first selected input mode | ||
| 47 | unicode_config.input_mode = selected[selected_index = 0]; | ||
| 48 | #endif | ||
| 49 | #endif | ||
| 50 | dprintf("Unicode input mode init to: %u\n", unicode_config.input_mode); | ||
| 27 | } | 51 | } |
| 28 | 52 | ||
| 29 | uint8_t get_unicode_input_mode(void) { | 53 | uint8_t get_unicode_input_mode(void) { |
| 30 | return input_mode; | 54 | return unicode_config.input_mode; |
| 31 | } | 55 | } |
| 32 | 56 | ||
| 57 | void set_unicode_input_mode(uint8_t mode) { | ||
| 58 | unicode_config.input_mode = mode; | ||
| 59 | persist_unicode_input_mode(); | ||
| 60 | dprintf("Unicode input mode set to: %u\n", unicode_config.input_mode); | ||
| 61 | } | ||
| 62 | |||
| 63 | void cycle_unicode_input_mode(uint8_t offset) { | ||
| 64 | #if UNICODE_SELECTED_MODES != -1 | ||
| 65 | selected_index = (selected_index + offset) % selected_count; | ||
| 66 | unicode_config.input_mode = selected[selected_index]; | ||
| 67 | #if UNICODE_CYCLE_PERSIST | ||
| 68 | persist_unicode_input_mode(); | ||
| 69 | #endif | ||
| 70 | dprintf("Unicode input mode cycle to: %u\n", unicode_config.input_mode); | ||
| 71 | #endif | ||
| 72 | } | ||
| 73 | |||
| 74 | void persist_unicode_input_mode(void) { | ||
| 75 | eeprom_update_byte(EECONFIG_UNICODEMODE, unicode_config.input_mode); | ||
| 76 | } | ||
| 77 | |||
| 78 | static uint8_t saved_mods; | ||
| 79 | |||
| 33 | __attribute__((weak)) | 80 | __attribute__((weak)) |
| 34 | void unicode_input_start (void) { | 81 | void unicode_input_start(void) { |
| 35 | // save current mods | 82 | saved_mods = get_mods(); // Save current mods |
| 36 | mods = keyboard_report->mods; | 83 | clear_mods(); // Unregister mods to start from a clean state |
| 37 | 84 | ||
| 38 | // unregister all mods to start from clean state | 85 | switch (unicode_config.input_mode) { |
| 39 | if (mods & MOD_BIT(KC_LSFT)) unregister_code(KC_LSFT); | ||
| 40 | if (mods & MOD_BIT(KC_RSFT)) unregister_code(KC_RSFT); | ||
| 41 | if (mods & MOD_BIT(KC_LCTL)) unregister_code(KC_LCTL); | ||
| 42 | if (mods & MOD_BIT(KC_RCTL)) unregister_code(KC_RCTL); | ||
| 43 | if (mods & MOD_BIT(KC_LALT)) unregister_code(KC_LALT); | ||
| 44 | if (mods & MOD_BIT(KC_RALT)) unregister_code(KC_RALT); | ||
| 45 | if (mods & MOD_BIT(KC_LGUI)) unregister_code(KC_LGUI); | ||
| 46 | if (mods & MOD_BIT(KC_RGUI)) unregister_code(KC_RGUI); | ||
| 47 | |||
| 48 | switch(input_mode) { | ||
| 49 | case UC_OSX: | 86 | case UC_OSX: |
| 50 | register_code(KC_LALT); | 87 | register_code(UNICODE_OSX_KEY); |
| 51 | break; | ||
| 52 | case UC_OSX_RALT: | ||
| 53 | register_code(KC_RALT); | ||
| 54 | break; | 88 | break; |
| 55 | case UC_LNX: | 89 | case UC_LNX: |
| 56 | register_code(KC_LCTL); | 90 | register_code(KC_LCTL); |
| 57 | register_code(KC_LSFT); | 91 | register_code(KC_LSFT); |
| 58 | register_code(KC_U); | 92 | tap_code(KC_U); // TODO: Replace with tap_code16(LCTL(LSFT(KC_U))); and test |
| 59 | unregister_code(KC_U); | ||
| 60 | unregister_code(KC_LSFT); | 93 | unregister_code(KC_LSFT); |
| 61 | unregister_code(KC_LCTL); | 94 | unregister_code(KC_LCTL); |
| 62 | break; | 95 | break; |
| 63 | case UC_WIN: | 96 | case UC_WIN: |
| 64 | register_code(KC_LALT); | 97 | register_code(KC_LALT); |
| 65 | register_code(KC_PPLS); | 98 | tap_code(KC_PPLS); |
| 66 | unregister_code(KC_PPLS); | ||
| 67 | break; | 99 | break; |
| 68 | case UC_WINC: | 100 | case UC_WINC: |
| 69 | register_code(KC_RALT); | 101 | tap_code(UNICODE_WINC_KEY); |
| 70 | unregister_code(KC_RALT); | 102 | tap_code(KC_U); |
| 71 | register_code(KC_U); | 103 | break; |
| 72 | unregister_code(KC_U); | ||
| 73 | } | 104 | } |
| 105 | |||
| 74 | wait_ms(UNICODE_TYPE_DELAY); | 106 | wait_ms(UNICODE_TYPE_DELAY); |
| 75 | } | 107 | } |
| 76 | 108 | ||
| 77 | __attribute__((weak)) | 109 | __attribute__((weak)) |
| 78 | void unicode_input_finish (void) { | 110 | void unicode_input_finish(void) { |
| 79 | switch(input_mode) { | 111 | switch (unicode_config.input_mode) { |
| 80 | case UC_OSX: | 112 | case UC_OSX: |
| 81 | case UC_WIN: | 113 | unregister_code(UNICODE_OSX_KEY); |
| 82 | unregister_code(KC_LALT); | 114 | break; |
| 83 | break; | 115 | case UC_LNX: |
| 84 | case UC_OSX_RALT: | 116 | tap_code(KC_SPC); |
| 85 | unregister_code(KC_RALT); | 117 | break; |
| 86 | break; | 118 | case UC_WIN: |
| 87 | case UC_LNX: | 119 | unregister_code(KC_LALT); |
| 88 | register_code(KC_SPC); | 120 | break; |
| 89 | unregister_code(KC_SPC); | ||
| 90 | break; | ||
| 91 | } | 121 | } |
| 92 | 122 | ||
| 93 | // reregister previously set mods | 123 | set_mods(saved_mods); // Reregister previously set mods |
| 94 | if (mods & MOD_BIT(KC_LSFT)) register_code(KC_LSFT); | ||
| 95 | if (mods & MOD_BIT(KC_RSFT)) register_code(KC_RSFT); | ||
| 96 | if (mods & MOD_BIT(KC_LCTL)) register_code(KC_LCTL); | ||
| 97 | if (mods & MOD_BIT(KC_RCTL)) register_code(KC_RCTL); | ||
| 98 | if (mods & MOD_BIT(KC_LALT)) register_code(KC_LALT); | ||
| 99 | if (mods & MOD_BIT(KC_RALT)) register_code(KC_RALT); | ||
| 100 | if (mods & MOD_BIT(KC_LGUI)) register_code(KC_LGUI); | ||
| 101 | if (mods & MOD_BIT(KC_RGUI)) register_code(KC_RGUI); | ||
| 102 | } | 124 | } |
| 103 | 125 | ||
| 104 | __attribute__((weak)) | 126 | __attribute__((weak)) |
| 105 | uint16_t hex_to_keycode(uint8_t hex) | 127 | uint16_t hex_to_keycode(uint8_t hex) { |
| 106 | { | ||
| 107 | if (hex == 0x0) { | 128 | if (hex == 0x0) { |
| 108 | return KC_0; | 129 | return KC_0; |
| 109 | } else if (hex < 0xA) { | 130 | } else if (hex < 0xA) { |
| @@ -116,7 +137,89 @@ uint16_t hex_to_keycode(uint8_t hex) | |||
| 116 | void register_hex(uint16_t hex) { | 137 | void register_hex(uint16_t hex) { |
| 117 | for(int i = 3; i >= 0; i--) { | 138 | for(int i = 3; i >= 0; i--) { |
| 118 | uint8_t digit = ((hex >> (i*4)) & 0xF); | 139 | uint8_t digit = ((hex >> (i*4)) & 0xF); |
| 119 | register_code(hex_to_keycode(digit)); | 140 | tap_code(hex_to_keycode(digit)); |
| 120 | unregister_code(hex_to_keycode(digit)); | 141 | } |
| 142 | } | ||
| 143 | |||
| 144 | void send_unicode_hex_string(const char *str) { | ||
| 145 | if (!str) { return; } | ||
| 146 | |||
| 147 | while (*str) { | ||
| 148 | // Find the next code point (token) in the string | ||
| 149 | for (; *str == ' '; str++); | ||
| 150 | size_t n = strcspn(str, " "); // Length of the current token | ||
| 151 | char code_point[n+1]; | ||
| 152 | strncpy(code_point, str, n); | ||
| 153 | code_point[n] = '\0'; // Make sure it's null-terminated | ||
| 154 | |||
| 155 | // Normalize the code point: make all hex digits lowercase | ||
| 156 | for (char *p = code_point; *p; p++) { | ||
| 157 | *p = tolower((unsigned char)*p); | ||
| 158 | } | ||
| 159 | |||
| 160 | // Send the code point as a Unicode input string | ||
| 161 | unicode_input_start(); | ||
| 162 | send_string(code_point); | ||
| 163 | unicode_input_finish(); | ||
| 164 | |||
| 165 | str += n; // Move to the first ' ' (or '\0') after the current token | ||
| 166 | } | ||
| 167 | } | ||
| 168 | |||
| 169 | bool process_unicode_common(uint16_t keycode, keyrecord_t *record) { | ||
| 170 | if (record->event.pressed) { | ||
| 171 | switch (keycode) { | ||
| 172 | case UNICODE_MODE_FORWARD: | ||
| 173 | cycle_unicode_input_mode(+1); | ||
| 174 | break; | ||
| 175 | case UNICODE_MODE_REVERSE: | ||
| 176 | cycle_unicode_input_mode(-1); | ||
| 177 | break; | ||
| 178 | |||
| 179 | case UNICODE_MODE_OSX: | ||
| 180 | set_unicode_input_mode(UC_OSX); | ||
| 181 | #if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_OSX) | ||
| 182 | static float song_osx[][2] = UNICODE_SONG_OSX; | ||
| 183 | PLAY_SONG(song_osx); | ||
| 184 | #endif | ||
| 185 | break; | ||
| 186 | case UNICODE_MODE_LNX: | ||
| 187 | set_unicode_input_mode(UC_LNX); | ||
| 188 | #if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_LNX) | ||
| 189 | static float song_lnx[][2] = UNICODE_SONG_LNX; | ||
| 190 | PLAY_SONG(song_lnx); | ||
| 191 | #endif | ||
| 192 | break; | ||
| 193 | case UNICODE_MODE_WIN: | ||
| 194 | set_unicode_input_mode(UC_WIN); | ||
| 195 | #if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_WIN) | ||
| 196 | static float song_win[][2] = UNICODE_SONG_WIN; | ||
| 197 | PLAY_SONG(song_win); | ||
| 198 | #endif | ||
| 199 | break; | ||
| 200 | case UNICODE_MODE_BSD: | ||
| 201 | set_unicode_input_mode(UC_BSD); | ||
| 202 | #if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_BSD) | ||
| 203 | static float song_bsd[][2] = UNICODE_SONG_BSD; | ||
| 204 | PLAY_SONG(song_bsd); | ||
| 205 | #endif | ||
| 206 | break; | ||
| 207 | case UNICODE_MODE_WINC: | ||
| 208 | set_unicode_input_mode(UC_WINC); | ||
| 209 | #if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_WINC) | ||
| 210 | static float song_winc[][2] = UNICODE_SONG_WINC; | ||
| 211 | PLAY_SONG(song_winc); | ||
| 212 | #endif | ||
| 213 | break; | ||
| 214 | } | ||
| 121 | } | 215 | } |
| 216 | #if defined(UNICODE_ENABLE) | ||
| 217 | return process_unicode(keycode, record); | ||
| 218 | #elif defined(UNICODEMAP_ENABLE) | ||
| 219 | return process_unicodemap(keycode, record); | ||
| 220 | #elif defined(UCIS_ENABLE) | ||
| 221 | return process_ucis(keycode, record); | ||
| 222 | #else | ||
| 223 | return true; | ||
| 224 | #endif | ||
| 122 | } | 225 | } |
diff --git a/quantum/process_keycode/process_unicode_common.h b/quantum/process_keycode/process_unicode_common.h index 4d2b04fb3..e608ab76b 100644 --- a/quantum/process_keycode/process_unicode_common.h +++ b/quantum/process_keycode/process_unicode_common.h | |||
| @@ -14,33 +14,71 @@ | |||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | #ifndef PROCESS_UNICODE_COMMON_H | 17 | #pragma once |
| 18 | #define PROCESS_UNICODE_COMMON_H | ||
| 19 | 18 | ||
| 20 | #include "quantum.h" | 19 | #include "quantum.h" |
| 21 | 20 | ||
| 22 | #ifndef UNICODE_TYPE_DELAY | 21 | #if defined(UNICODE_ENABLE) + defined(UNICODEMAP_ENABLE) + defined(UCIS_ENABLE) > 1 |
| 23 | #define UNICODE_TYPE_DELAY 10 | 22 | #error "Cannot enable more than one Unicode method (UNICODE, UNICODEMAP, UCIS) at the same time" |
| 23 | #endif | ||
| 24 | |||
| 25 | // Keycodes used for starting Unicode input on different platforms | ||
| 26 | #ifndef UNICODE_OSX_KEY | ||
| 27 | #define UNICODE_OSX_KEY KC_LALT | ||
| 28 | #endif | ||
| 29 | #ifndef UNICODE_WINC_KEY | ||
| 30 | #define UNICODE_WINC_KEY KC_RALT | ||
| 24 | #endif | 31 | #endif |
| 25 | 32 | ||
| 26 | __attribute__ ((unused)) | 33 | // Comma-delimited, ordered list of input modes selected for use (e.g. in cycle) |
| 27 | static uint8_t input_mode; | 34 | // Example: #define UNICODE_SELECTED_MODES UC_WINC, UC_LNX |
| 35 | #ifndef UNICODE_SELECTED_MODES | ||
| 36 | #define UNICODE_SELECTED_MODES -1 | ||
| 37 | #endif | ||
| 38 | |||
| 39 | // Whether input mode changes in cycle should be written to EEPROM | ||
| 40 | #ifndef UNICODE_CYCLE_PERSIST | ||
| 41 | #define UNICODE_CYCLE_PERSIST true | ||
| 42 | #endif | ||
| 28 | 43 | ||
| 29 | void set_unicode_input_mode(uint8_t os_target); | 44 | // Delay between starting Unicode input and sending a sequence, in ms |
| 45 | #ifndef UNICODE_TYPE_DELAY | ||
| 46 | #define UNICODE_TYPE_DELAY 10 | ||
| 47 | #endif | ||
| 48 | |||
| 49 | enum unicode_input_modes { | ||
| 50 | UC_OSX, // Mac OS X using Unicode Hex Input | ||
| 51 | UC_LNX, // Linux using IBus | ||
| 52 | UC_WIN, // Windows using EnableHexNumpad | ||
| 53 | UC_BSD, // BSD (not implemented) | ||
| 54 | UC_WINC, // Windows using WinCompose (https://github.com/samhocevar/wincompose) | ||
| 55 | UC__COUNT // Number of available input modes (always leave at the end) | ||
| 56 | }; | ||
| 57 | |||
| 58 | typedef union { | ||
| 59 | uint32_t raw; | ||
| 60 | struct { | ||
| 61 | uint8_t input_mode : 8; | ||
| 62 | }; | ||
| 63 | } unicode_config_t; | ||
| 64 | |||
| 65 | extern unicode_config_t unicode_config; | ||
| 66 | |||
| 67 | void unicode_input_mode_init(void); | ||
| 30 | uint8_t get_unicode_input_mode(void); | 68 | uint8_t get_unicode_input_mode(void); |
| 69 | void set_unicode_input_mode(uint8_t mode); | ||
| 70 | void cycle_unicode_input_mode(uint8_t offset); | ||
| 71 | void persist_unicode_input_mode(void); | ||
| 72 | |||
| 31 | void unicode_input_start(void); | 73 | void unicode_input_start(void); |
| 32 | void unicode_input_finish(void); | 74 | void unicode_input_finish(void); |
| 75 | |||
| 33 | void register_hex(uint16_t hex); | 76 | void register_hex(uint16_t hex); |
| 77 | void send_unicode_hex_string(const char *str); | ||
| 34 | 78 | ||
| 35 | #define UC_OSX 0 // Mac OS X | 79 | bool process_unicode_common(uint16_t keycode, keyrecord_t *record); |
| 36 | #define UC_LNX 1 // Linux | ||
| 37 | #define UC_WIN 2 // Windows 'HexNumpad' | ||
| 38 | #define UC_BSD 3 // BSD (not implemented) | ||
| 39 | #define UC_WINC 4 // WinCompose https://github.com/samhocevar/wincompose | ||
| 40 | #define UC_OSX_RALT 5 // Mac OS X using Right Alt key for Unicode Compose | ||
| 41 | 80 | ||
| 42 | #define UC_BSPC UC(0x0008) | 81 | #define UC_BSPC UC(0x0008) |
| 43 | |||
| 44 | #define UC_SPC UC(0x0020) | 82 | #define UC_SPC UC(0x0020) |
| 45 | 83 | ||
| 46 | #define UC_EXLM UC(0x0021) | 84 | #define UC_EXLM UC(0x0021) |
| @@ -145,5 +183,3 @@ void register_hex(uint16_t hex); | |||
| 145 | #define UC_RCBR UC(0x007D) | 183 | #define UC_RCBR UC(0x007D) |
| 146 | #define UC_TILD UC(0x007E) | 184 | #define UC_TILD UC(0x007E) |
| 147 | #define UC_DEL UC(0x007F) | 185 | #define UC_DEL UC(0x007F) |
| 148 | |||
| 149 | #endif | ||
diff --git a/quantum/process_keycode/process_unicodemap.c b/quantum/process_keycode/process_unicodemap.c index 47c27b911..cee9acb5f 100644 --- a/quantum/process_keycode/process_unicodemap.c +++ b/quantum/process_keycode/process_unicodemap.c | |||
| @@ -18,8 +18,7 @@ | |||
| 18 | #include "process_unicode_common.h" | 18 | #include "process_unicode_common.h" |
| 19 | 19 | ||
| 20 | __attribute__((weak)) | 20 | __attribute__((weak)) |
| 21 | const uint32_t PROGMEM unicode_map[] = { | 21 | const uint32_t PROGMEM unicode_map[] = {}; |
| 22 | }; | ||
| 23 | 22 | ||
| 24 | void register_hex32(uint32_t hex) { | 23 | void register_hex32(uint32_t hex) { |
| 25 | bool onzerostart = true; | 24 | bool onzerostart = true; |
| @@ -42,26 +41,26 @@ void register_hex32(uint32_t hex) { | |||
| 42 | } | 41 | } |
| 43 | 42 | ||
| 44 | __attribute__((weak)) | 43 | __attribute__((weak)) |
| 45 | void unicode_map_input_error() {} | 44 | void unicodemap_input_error() {} |
| 46 | 45 | ||
| 47 | bool process_unicode_map(uint16_t keycode, keyrecord_t *record) { | 46 | bool process_unicodemap(uint16_t keycode, keyrecord_t *record) { |
| 48 | uint8_t input_mode = get_unicode_input_mode(); | 47 | if ((keycode & QK_UNICODEMAP) == QK_UNICODEMAP && record->event.pressed) { |
| 49 | if ((keycode & QK_UNICODE_MAP) == QK_UNICODE_MAP && record->event.pressed) { | 48 | uint16_t index = keycode - QK_UNICODEMAP; |
| 50 | const uint32_t* map = unicode_map; | 49 | uint32_t code = pgm_read_dword(unicode_map + index); |
| 51 | uint16_t index = keycode - QK_UNICODE_MAP; | 50 | uint8_t input_mode = get_unicode_input_mode(); |
| 52 | uint32_t code = pgm_read_dword(&map[index]); | 51 | |
| 53 | if (code > 0xFFFF && code <= 0x10ffff && (input_mode == UC_OSX || input_mode == UC_OSX_RALT)) { | 52 | if (code > 0xFFFF && code <= 0x10FFFF && input_mode == UC_OSX) { |
| 54 | // Convert to UTF-16 surrogate pair | 53 | // Convert to UTF-16 surrogate pair |
| 55 | code -= 0x10000; | 54 | code -= 0x10000; |
| 56 | uint32_t lo = code & 0x3ff; | 55 | uint32_t lo = code & 0x3FF, hi = (code & 0xFFC00) >> 10; |
| 57 | uint32_t hi = (code & 0xffc00) >> 10; | 56 | |
| 58 | unicode_input_start(); | 57 | unicode_input_start(); |
| 59 | register_hex32(hi + 0xd800); | 58 | register_hex32(hi + 0xD800); |
| 60 | register_hex32(lo + 0xdc00); | 59 | register_hex32(lo + 0xDC00); |
| 61 | unicode_input_finish(); | 60 | unicode_input_finish(); |
| 62 | } else if ((code > 0x10ffff && (input_mode == UC_OSX || input_mode == UC_OSX_RALT)) || (code > 0xFFFFF && input_mode == UC_LNX)) { | 61 | } else if ((code > 0x10FFFF && input_mode == UC_OSX) || (code > 0xFFFFF && input_mode == UC_LNX)) { |
| 63 | // when character is out of range supported by the OS | 62 | // Character is out of range supported by the OS |
| 64 | unicode_map_input_error(); | 63 | unicodemap_input_error(); |
| 65 | } else { | 64 | } else { |
| 66 | unicode_input_start(); | 65 | unicode_input_start(); |
| 67 | register_hex32(code); | 66 | register_hex32(code); |
diff --git a/quantum/process_keycode/process_unicodemap.h b/quantum/process_keycode/process_unicodemap.h index 929c88c0b..5764697f8 100644 --- a/quantum/process_keycode/process_unicodemap.h +++ b/quantum/process_keycode/process_unicodemap.h | |||
| @@ -14,12 +14,10 @@ | |||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | #ifndef PROCESS_UNICODEMAP_H | 17 | #pragma once |
| 18 | #define PROCESS_UNICODEMAP_H | ||
| 19 | 18 | ||
| 20 | #include "quantum.h" | 19 | #include "quantum.h" |
| 21 | #include "process_unicode_common.h" | 20 | #include "process_unicode_common.h" |
| 22 | 21 | ||
| 23 | void unicode_map_input_error(void); | 22 | void unicodemap_input_error(void); |
| 24 | bool process_unicode_map(uint16_t keycode, keyrecord_t *record); | 23 | bool process_unicodemap(uint16_t keycode, keyrecord_t *record); |
| 25 | #endif | ||
