summaryrefslogtreecommitdiff
path: root/quantum/process_keycode
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/process_keycode')
-rw-r--r--quantum/process_keycode/process_auto_shift.c2
-rw-r--r--quantum/process_keycode/process_chording.c76
-rw-r--r--quantum/process_keycode/process_chording.h32
-rw-r--r--quantum/process_keycode/process_clicky.c72
-rw-r--r--quantum/process_keycode/process_clicky.h10
-rw-r--r--quantum/process_keycode/process_leader.c49
-rw-r--r--quantum/process_keycode/process_leader.h2
-rw-r--r--quantum/process_keycode/process_tap_dance.c6
-rw-r--r--quantum/process_keycode/process_tap_dance.h1
-rw-r--r--quantum/process_keycode/process_terminal.c6
-rw-r--r--quantum/process_keycode/process_ucis.c8
-rw-r--r--quantum/process_keycode/process_ucis.h6
-rw-r--r--quantum/process_keycode/process_unicode.c7
-rw-r--r--quantum/process_keycode/process_unicode.h5
-rw-r--r--quantum/process_keycode/process_unicode_common.c223
-rw-r--r--quantum/process_keycode/process_unicode_common.h68
-rw-r--r--quantum/process_keycode/process_unicodemap.c33
-rw-r--r--quantum/process_keycode/process_unicodemap.h8
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 01d99445b0..0d0930ee67 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) {
case KC_DOT:
case KC_SLSH:
case KC_GRAVE:
+ case KC_NONUS_BSLASH:
+ case KC_NONUS_HASH:
#endif
autoshift_flush();
diff --git a/quantum/process_keycode/process_chording.c b/quantum/process_keycode/process_chording.c
deleted file mode 100644
index 6c6ebe300a..0000000000
--- a/quantum/process_keycode/process_chording.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Copyright 2016 Jack Humbert
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "process_chording.h"
-
-bool keys_chord(uint8_t keys[]) {
- uint8_t keys_size = sizeof(keys)/sizeof(keys[0]);
- bool pass = true;
- uint8_t in = 0;
- for (uint8_t i = 0; i < chord_key_count; i++) {
- bool found = false;
- for (uint8_t j = 0; j < keys_size; j++) {
- if (chord_keys[i] == (keys[j] & 0xFF)) {
- in++; // detects key in chord
- found = true;
- break;
- }
- }
- if (found)
- continue;
- if (chord_keys[i] != 0) {
- pass = false; // makes sure rest are blank
- }
- }
- return (pass && (in == keys_size));
-}
-
-bool process_chording(uint16_t keycode, keyrecord_t *record) {
- if (keycode >= QK_CHORDING && keycode <= QK_CHORDING_MAX) {
- if (record->event.pressed) {
- if (!chording) {
- chording = true;
- for (uint8_t i = 0; i < CHORDING_MAX; i++)
- chord_keys[i] = 0;
- chord_key_count = 0;
- chord_key_down = 0;
- }
- chord_keys[chord_key_count] = (keycode & 0xFF);
- chord_key_count++;
- chord_key_down++;
- return false;
- } else {
- if (chording) {
- chord_key_down--;
- if (chord_key_down == 0) {
- chording = false;
- // Chord Dictionary
- if (keys_chord((uint8_t[]){KC_ENTER, KC_SPACE})) {
- register_code(KC_A);
- unregister_code(KC_A);
- return false;
- }
- for (uint8_t i = 0; i < chord_key_count; i++) {
- register_code(chord_keys[i]);
- unregister_code(chord_keys[i]);
- return false;
- }
- }
- }
- }
- }
- return true;
-}
diff --git a/quantum/process_keycode/process_chording.h b/quantum/process_keycode/process_chording.h
deleted file mode 100644
index 8c0f4862a8..0000000000
--- a/quantum/process_keycode/process_chording.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Copyright 2016 Jack Humbert
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef PROCESS_CHORDING_H
-#define PROCESS_CHORDING_H
-
-#include "quantum.h"
-
-// Chording stuff
-#define CHORDING_MAX 4
-bool chording = false;
-
-uint8_t chord_keys[CHORDING_MAX] = {0};
-uint8_t chord_key_count = 0;
-uint8_t chord_key_down = 0;
-
-bool process_chording(uint16_t keycode, keyrecord_t *record);
-
-#endif
diff --git a/quantum/process_keycode/process_clicky.c b/quantum/process_keycode/process_clicky.c
index 1e950d1113..8238c263f9 100644
--- a/quantum/process_keycode/process_clicky.c
+++ b/quantum/process_keycode/process_clicky.c
@@ -3,11 +3,6 @@
#ifdef AUDIO_CLICKY
-#ifdef AUDIO_CLICKY_ON
-bool clicky_enable = true;
-#else // AUDIO_CLICKY_ON
-bool clicky_enable = false;
-#endif // AUDIO_CLICKY_ON
#ifndef AUDIO_CLICKY_FREQ_DEFAULT
#define AUDIO_CLICKY_FREQ_DEFAULT 440.0f
#endif // !AUDIO_CLICKY_FREQ_DEFAULT
@@ -25,8 +20,11 @@ bool clicky_enable = false;
#endif // !AUDIO_CLICKY_FREQ_RANDOMNESS
float clicky_freq = AUDIO_CLICKY_FREQ_DEFAULT;
+float clicky_rand = AUDIO_CLICKY_FREQ_RANDOMNESS;
float clicky_song[][2] = {{AUDIO_CLICKY_FREQ_DEFAULT, 3}, {AUDIO_CLICKY_FREQ_DEFAULT, 1}}; // 3 and 1 --> durations
+extern audio_config_t audio_config;
+
#ifndef NO_MUSIC_MODE
extern bool music_activated;
extern bool midi_activated;
@@ -36,31 +34,61 @@ void clicky_play(void) {
#ifndef NO_MUSIC_MODE
if (music_activated || midi_activated) return;
#endif // !NO_MUSIC_MODE
- clicky_song[0][0] = 2.0f * clicky_freq * (1.0f + AUDIO_CLICKY_FREQ_RANDOMNESS * ( ((float)rand()) / ((float)(RAND_MAX)) ) );
- clicky_song[1][0] = clicky_freq * (1.0f + AUDIO_CLICKY_FREQ_RANDOMNESS * ( ((float)rand()) / ((float)(RAND_MAX)) ) );
+ clicky_song[0][0] = 2.0f * clicky_freq * (1.0f + clicky_rand * ( ((float)rand()) / ((float)(RAND_MAX)) ) );
+ clicky_song[1][0] = clicky_freq * (1.0f + clicky_rand * ( ((float)rand()) / ((float)(RAND_MAX)) ) );
PLAY_SONG(clicky_song);
}
+void clicky_freq_up(void) {
+ float new_freq = clicky_freq * AUDIO_CLICKY_FREQ_FACTOR;
+ if (new_freq < AUDIO_CLICKY_FREQ_MAX) {
+ clicky_freq = new_freq;
+ }
+}
+
+void clicky_freq_down(void) {
+ float new_freq = clicky_freq / AUDIO_CLICKY_FREQ_FACTOR;
+ if (new_freq > AUDIO_CLICKY_FREQ_MIN) {
+ clicky_freq = new_freq;
+ }
+}
+
+void clicky_freq_reset(void) {
+ clicky_freq = AUDIO_CLICKY_FREQ_DEFAULT;
+}
+
+void clicky_toggle(void) {
+ audio_config.clicky_enable ^= 1;
+ eeconfig_update_audio(audio_config.raw);
+}
+
+void clicky_on(void) {
+ audio_config.clicky_enable = 1;
+ eeconfig_update_audio(audio_config.raw);
+}
+
+void clicky_off(void) {
+ audio_config.clicky_enable = 0;
+ eeconfig_update_audio(audio_config.raw);
+}
+
+bool is_clicky_on(void) {
+ return (audio_config.clicky_enable != 0);
+}
+
bool process_clicky(uint16_t keycode, keyrecord_t *record) {
- if (keycode == CLICKY_TOGGLE && record->event.pressed) { clicky_enable = !clicky_enable; }
+ if (keycode == CLICKY_TOGGLE && record->event.pressed) { clicky_toggle(); }
- if (keycode == CLICKY_RESET && record->event.pressed) { clicky_freq = AUDIO_CLICKY_FREQ_DEFAULT; }
+ if (keycode == CLICKY_ENABLE && record->event.pressed) { clicky_on(); }
+ if (keycode == CLICKY_DISABLE && record->event.pressed) { clicky_off(); }
- if (keycode == CLICKY_UP && record->event.pressed) {
- float new_freq = clicky_freq * AUDIO_CLICKY_FREQ_FACTOR;
- if (new_freq < AUDIO_CLICKY_FREQ_MAX) {
- clicky_freq = new_freq;
- }
- }
- if (keycode == CLICKY_DOWN && record->event.pressed) {
- float new_freq = clicky_freq / AUDIO_CLICKY_FREQ_FACTOR;
- if (new_freq > AUDIO_CLICKY_FREQ_MIN) {
- clicky_freq = new_freq;
- }
- }
+ if (keycode == CLICKY_RESET && record->event.pressed) { clicky_freq_reset(); }
+
+ if (keycode == CLICKY_UP && record->event.pressed) { clicky_freq_up(); }
+ if (keycode == CLICKY_DOWN && record->event.pressed) { clicky_freq_down(); }
- if ( clicky_enable ) {
+ if ( audio_config.clicky_enable ) {
if (record->event.pressed) {
clicky_play();;
}
diff --git a/quantum/process_keycode/process_clicky.h b/quantum/process_keycode/process_clicky.h
index e274af56f1..f746edb951 100644
--- a/quantum/process_keycode/process_clicky.h
+++ b/quantum/process_keycode/process_clicky.h
@@ -4,4 +4,14 @@
void clicky_play(void);
bool process_clicky(uint16_t keycode, keyrecord_t *record);
+void clicky_freq_up(void);
+void clicky_freq_down(void);
+void clicky_freq_reset(void);
+
+void clicky_toggle(void);
+void clicky_on(void);
+void clicky_off(void);
+
+bool is_clicky_on(void);
+
#endif
diff --git a/quantum/process_keycode/process_leader.c b/quantum/process_keycode/process_leader.c
index c87ef115af..897e9eabf6 100644
--- a/quantum/process_keycode/process_leader.c
+++ b/quantum/process_keycode/process_leader.c
@@ -14,7 +14,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef DISABLE_LEADER
+#ifdef LEADER_ENABLE
#include "process_leader.h"
@@ -35,25 +35,40 @@ uint16_t leader_time = 0;
uint16_t leader_sequence[5] = {0, 0, 0, 0, 0};
uint8_t leader_sequence_size = 0;
+void qk_leader_start(void) {
+ if (leading) { return; }
+ leader_start();
+ leading = true;
+ leader_time = timer_read();
+ leader_sequence_size = 0;
+ leader_sequence[0] = 0;
+ leader_sequence[1] = 0;
+ leader_sequence[2] = 0;
+ leader_sequence[3] = 0;
+ leader_sequence[4] = 0;
+}
+
bool process_leader(uint16_t keycode, keyrecord_t *record) {
// Leader key set-up
if (record->event.pressed) {
- if (!leading && keycode == KC_LEAD) {
- leader_start();
- leading = true;
- leader_time = timer_read();
- leader_sequence_size = 0;
- leader_sequence[0] = 0;
- leader_sequence[1] = 0;
- leader_sequence[2] = 0;
- leader_sequence[3] = 0;
- leader_sequence[4] = 0;
- return false;
- }
- if (leading && timer_elapsed(leader_time) < LEADER_TIMEOUT) {
- leader_sequence[leader_sequence_size] = keycode;
- leader_sequence_size++;
- return false;
+ if (leading) {
+ if (timer_elapsed(leader_time) < LEADER_TIMEOUT) {
+#ifndef LEADER_KEY_STRICT_KEY_PROCESSING
+ if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)) {
+ keycode = keycode & 0xFF;
+ }
+#endif // LEADER_KEY_STRICT_KEY_PROCESSING
+ leader_sequence[leader_sequence_size] = keycode;
+ leader_sequence_size++;
+#ifdef LEADER_PER_KEY_TIMING
+ leader_time = timer_read();
+#endif
+ return false;
+ }
+ } else {
+ if (keycode == KC_LEAD) {
+ qk_leader_start();
+ }
}
}
return true;
diff --git a/quantum/process_keycode/process_leader.h b/quantum/process_keycode/process_leader.h
index 59c3eed1be..15bccc3f67 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);
void leader_start(void);
void leader_end(void);
-
+void qk_leader_start(void);
#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)
#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 8337806912..16d33dddee 100644
--- a/quantum/process_keycode/process_tap_dance.c
+++ b/quantum/process_keycode/process_tap_dance.c
@@ -16,6 +16,10 @@
#include "quantum.h"
#include "action_tapping.h"
+#ifndef TAPPING_TERM
+#define TAPPING_TERM 200
+#endif
+
#ifndef NO_ACTION_ONESHOT
uint8_t get_oneshot_mods(void);
#endif
@@ -127,6 +131,7 @@ void preprocess_tap_dance(uint16_t keycode, keyrecord_t *record) {
if (keycode == action->state.keycode && keycode == last_td)
continue;
action->state.interrupted = true;
+ action->state.interrupting_keycode = keycode;
process_tap_dance_action_on_dance_finished (action);
reset_tap_dance (&action->state);
}
@@ -205,5 +210,6 @@ void reset_tap_dance (qk_tap_dance_state_t *state) {
state->count = 0;
state->interrupted = false;
state->finished = false;
+ state->interrupting_keycode = 0;
last_td = 0;
}
diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h
index 8b0a47c49b..ca12f4746e 100644
--- a/quantum/process_keycode/process_tap_dance.h
+++ b/quantum/process_keycode/process_tap_dance.h
@@ -27,6 +27,7 @@ typedef struct
uint8_t oneshot_mods;
uint8_t weak_mods;
uint16_t keycode;
+ uint16_t interrupting_keycode;
uint16_t timer;
bool interrupted;
bool pressed;
diff --git a/quantum/process_keycode/process_terminal.c b/quantum/process_keycode/process_terminal.c
index 6998639f20..e791deffc1 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) {
disable_terminal();
return false;
}
+
+ if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)) {
+ keycode = keycode & 0xFF;
+ }
+
if (keycode < 256) {
uint8_t str_len;
char char_to_add;
switch (keycode) {
case KC_ENTER:
+ case KC_KP_ENTER:
push_to_cmd_buffer();
current_cmd_buffer_pos = 0;
process_terminal_command();
diff --git a/quantum/process_keycode/process_ucis.c b/quantum/process_keycode/process_ucis.c
index 86c0937f5e..5de2e41fc3 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) {
unicode_input_finish();
}
+__attribute__((weak))
+void qk_ucis_success(uint8_t symbol_index) {
+}
+
static bool is_uni_seq(char *seq) {
uint8_t i;
@@ -142,6 +146,10 @@ bool process_ucis (uint16_t keycode, keyrecord_t *record) {
}
unicode_input_finish();
+ if (symbol_found) {
+ qk_ucis_success(i);
+ }
+
qk_ucis_state.in_progress = false;
return false;
}
diff --git a/quantum/process_keycode/process_ucis.h b/quantum/process_keycode/process_ucis.h
index 3f736a709f..b114d839ab 100644
--- a/quantum/process_keycode/process_ucis.h
+++ b/quantum/process_keycode/process_ucis.h
@@ -14,8 +14,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef PROCESS_UCIS_H
-#define PROCESS_UCIS_H
+#pragma once
#include "quantum.h"
#include "process_unicode_common.h"
@@ -45,7 +44,6 @@ extern const qk_ucis_symbol_t ucis_symbol_table[];
void qk_ucis_start(void);
void qk_ucis_start_user(void);
void qk_ucis_symbol_fallback (void);
+void qk_ucis_success(uint8_t symbol_index);
void register_ucis(const char *hex);
bool process_ucis (uint16_t keycode, keyrecord_t *record);
-
-#endif
diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c
index fd008eca12..19beb84520 100644
--- a/quantum/process_keycode/process_unicode.c
+++ b/quantum/process_keycode/process_unicode.c
@@ -17,14 +17,8 @@
#include "action_util.h"
#include "eeprom.h"
-static uint8_t first_flag = 0;
-
bool process_unicode(uint16_t keycode, keyrecord_t *record) {
if (keycode > QK_UNICODE && record->event.pressed) {
- if (first_flag == 0) {
- set_unicode_input_mode(eeprom_read_byte(EECONFIG_UNICODEMODE));
- first_flag = 1;
- }
uint16_t unicode = keycode & 0x7FFF;
unicode_input_start();
register_hex(unicode);
@@ -32,4 +26,3 @@ bool process_unicode(uint16_t keycode, keyrecord_t *record) {
}
return true;
}
-
diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h
index c525b74f03..0913e99107 100644
--- a/quantum/process_keycode/process_unicode.h
+++ b/quantum/process_keycode/process_unicode.h
@@ -13,12 +13,9 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef PROCESS_UNICODE_H
-#define PROCESS_UNICODE_H
+#pragma once
#include "quantum.h"
#include "process_unicode_common.h"
bool process_unicode(uint16_t keycode, keyrecord_t *record);
-
-#endif
diff --git a/quantum/process_keycode/process_unicode_common.c b/quantum/process_keycode/process_unicode_common.c
index 7f34ad57cf..b64feb7003 100644
--- a/quantum/process_keycode/process_unicode_common.c
+++ b/quantum/process_keycode/process_unicode_common.c
@@ -16,94 +16,115 @@
#include "process_unicode_common.h"
#include "eeprom.h"
+#include <ctype.h>
+#include <string.h>
-static uint8_t input_mode;
-uint8_t mods;
+unicode_config_t unicode_config;
+#if UNICODE_SELECTED_MODES != -1
+static uint8_t selected[] = { UNICODE_SELECTED_MODES };
+static uint8_t selected_count = sizeof selected / sizeof *selected;
+static uint8_t selected_index;
+#endif
-void set_unicode_input_mode(uint8_t os_target)
-{
- input_mode = os_target;
- eeprom_update_byte(EECONFIG_UNICODEMODE, os_target);
+void unicode_input_mode_init(void) {
+ unicode_config.raw = eeprom_read_byte(EECONFIG_UNICODEMODE);
+#if UNICODE_SELECTED_MODES != -1
+ #if UNICODE_CYCLE_PERSIST
+ // Find input_mode in selected modes
+ uint8_t i;
+ for (i = 0; i < selected_count; i++) {
+ if (selected[i] == unicode_config.input_mode) {
+ selected_index = i;
+ break;
+ }
+ }
+ if (i == selected_count) {
+ // Not found: input_mode isn't selected, change to one that is
+ unicode_config.input_mode = selected[selected_index = 0];
+ }
+ #else
+ // Always change to the first selected input mode
+ unicode_config.input_mode = selected[selected_index = 0];
+ #endif
+#endif
+ dprintf("Unicode input mode init to: %u\n", unicode_config.input_mode);
}
uint8_t get_unicode_input_mode(void) {
- return input_mode;
+ return unicode_config.input_mode;
}
+void set_unicode_input_mode(uint8_t mode) {
+ unicode_config.input_mode = mode;
+ persist_unicode_input_mode();
+ dprintf("Unicode input mode set to: %u\n", unicode_config.input_mode);
+}
+
+void cycle_unicode_input_mode(uint8_t offset) {
+#if UNICODE_SELECTED_MODES != -1
+ selected_index = (selected_index + offset) % selected_count;
+ unicode_config.input_mode = selected[selected_index];
+ #if UNICODE_CYCLE_PERSIST
+ persist_unicode_input_mode();
+ #endif
+ dprintf("Unicode input mode cycle to: %u\n", unicode_config.input_mode);
+#endif
+}
+
+void persist_unicode_input_mode(void) {
+ eeprom_update_byte(EECONFIG_UNICODEMODE, unicode_config.input_mode);
+}
+
+static uint8_t saved_mods;
+
__attribute__((weak))
-void unicode_input_start (void) {
- // save current mods
- mods = keyboard_report->mods;
-
- // unregister all mods to start from clean state
- if (mods & MOD_BIT(KC_LSFT)) unregister_code(KC_LSFT);
- if (mods & MOD_BIT(KC_RSFT)) unregister_code(KC_RSFT);
- if (mods & MOD_BIT(KC_LCTL)) unregister_code(KC_LCTL);
- if (mods & MOD_BIT(KC_RCTL)) unregister_code(KC_RCTL);
- if (mods & MOD_BIT(KC_LALT)) unregister_code(KC_LALT);
- if (mods & MOD_BIT(KC_RALT)) unregister_code(KC_RALT);
- if (mods & MOD_BIT(KC_LGUI)) unregister_code(KC_LGUI);
- if (mods & MOD_BIT(KC_RGUI)) unregister_code(KC_RGUI);
-
- switch(input_mode) {
+void unicode_input_start(void) {
+ saved_mods = get_mods(); // Save current mods
+ clear_mods(); // Unregister mods to start from a clean state
+
+ switch (unicode_config.input_mode) {
case UC_OSX:
- register_code(KC_LALT);
- break;
- case UC_OSX_RALT:
- register_code(KC_RALT);
+ register_code(UNICODE_OSX_KEY);
break;
case UC_LNX:
register_code(KC_LCTL);
register_code(KC_LSFT);
- register_code(KC_U);
- unregister_code(KC_U);
+ tap_code(KC_U); // TODO: Replace with tap_code16(LCTL(LSFT(KC_U))); and test
unregister_code(KC_LSFT);
unregister_code(KC_LCTL);
break;
case UC_WIN:
register_code(KC_LALT);
- register_code(KC_PPLS);
- unregister_code(KC_PPLS);
+ tap_code(KC_PPLS);
break;
case UC_WINC:
- register_code(KC_RALT);
- unregister_code(KC_RALT);
- register_code(KC_U);
- unregister_code(KC_U);
+ tap_code(UNICODE_WINC_KEY);
+ tap_code(KC_U);
+ break;
}
+
wait_ms(UNICODE_TYPE_DELAY);
}
__attribute__((weak))
-void unicode_input_finish (void) {
- switch(input_mode) {
- case UC_OSX:
- case UC_WIN:
- unregister_code(KC_LALT);
- break;
- case UC_OSX_RALT:
- unregister_code(KC_RALT);
- break;
- case UC_LNX:
- register_code(KC_SPC);
- unregister_code(KC_SPC);
- break;
+void unicode_input_finish(void) {
+ switch (unicode_config.input_mode) {
+ case UC_OSX:
+ unregister_code(UNICODE_OSX_KEY);
+ break;
+ case UC_LNX:
+ tap_code(KC_SPC);
+ break;
+ case UC_WIN:
+ unregister_code(KC_LALT);
+ break;
}
- // reregister previously set mods
- if (mods & MOD_BIT(KC_LSFT)) register_code(KC_LSFT);
- if (mods & MOD_BIT(KC_RSFT)) register_code(KC_RSFT);
- if (mods & MOD_BIT(KC_LCTL)) register_code(KC_LCTL);
- if (mods & MOD_BIT(KC_RCTL)) register_code(KC_RCTL);
- if (mods & MOD_BIT(KC_LALT)) register_code(KC_LALT);
- if (mods & MOD_BIT(KC_RALT)) register_code(KC_RALT);
- if (mods & MOD_BIT(KC_LGUI)) register_code(KC_LGUI);
- if (mods & MOD_BIT(KC_RGUI)) register_code(KC_RGUI);
+ set_mods(saved_mods); // Reregister previously set mods
}
__attribute__((weak))
-uint16_t hex_to_keycode(uint8_t hex)
-{
+uint16_t hex_to_keycode(uint8_t hex) {
if (hex == 0x0) {
return KC_0;
} else if (hex < 0xA) {
@@ -116,7 +137,89 @@ uint16_t hex_to_keycode(uint8_t hex)
void register_hex(uint16_t hex) {
for(int i = 3; i >= 0; i--) {
uint8_t digit = ((hex >> (i*4)) & 0xF);
- register_code(hex_to_keycode(digit));
- unregister_code(hex_to_keycode(digit));
+ tap_code(hex_to_keycode(digit));
+ }
+}
+
+void send_unicode_hex_string(const char *str) {
+ if (!str) { return; }
+
+ while (*str) {
+ // Find the next code point (token) in the string
+ for (; *str == ' '; str++);
+ size_t n = strcspn(str, " "); // Length of the current token
+ char code_point[n+1];
+ strncpy(code_point, str, n);
+ code_point[n] = '\0'; // Make sure it's null-terminated
+
+ // Normalize the code point: make all hex digits lowercase
+ for (char *p = code_point; *p; p++) {
+ *p = tolower((unsigned char)*p);
+ }
+
+ // Send the code point as a Unicode input string
+ unicode_input_start();
+ send_string(code_point);
+ unicode_input_finish();
+
+ str += n; // Move to the first ' ' (or '\0') after the current token
+ }
+}
+
+bool process_unicode_common(uint16_t keycode, keyrecord_t *record) {
+ if (record->event.pressed) {
+ switch (keycode) {
+ case UNICODE_MODE_FORWARD:
+ cycle_unicode_input_mode(+1);
+ break;
+ case UNICODE_MODE_REVERSE:
+ cycle_unicode_input_mode(-1);
+ break;
+
+ case UNICODE_MODE_OSX:
+ set_unicode_input_mode(UC_OSX);
+#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_OSX)
+ static float song_osx[][2] = UNICODE_SONG_OSX;
+ PLAY_SONG(song_osx);
+#endif
+ break;
+ case UNICODE_MODE_LNX:
+ set_unicode_input_mode(UC_LNX);
+#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_LNX)
+ static float song_lnx[][2] = UNICODE_SONG_LNX;
+ PLAY_SONG(song_lnx);
+#endif
+ break;
+ case UNICODE_MODE_WIN:
+ set_unicode_input_mode(UC_WIN);
+#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_WIN)
+ static float song_win[][2] = UNICODE_SONG_WIN;
+ PLAY_SONG(song_win);
+#endif
+ break;
+ case UNICODE_MODE_BSD:
+ set_unicode_input_mode(UC_BSD);
+#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_BSD)
+ static float song_bsd[][2] = UNICODE_SONG_BSD;
+ PLAY_SONG(song_bsd);
+#endif
+ break;
+ case UNICODE_MODE_WINC:
+ set_unicode_input_mode(UC_WINC);
+#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_WINC)
+ static float song_winc[][2] = UNICODE_SONG_WINC;
+ PLAY_SONG(song_winc);
+#endif
+ break;
+ }
}
+#if defined(UNICODE_ENABLE)
+ return process_unicode(keycode, record);
+#elif defined(UNICODEMAP_ENABLE)
+ return process_unicodemap(keycode, record);
+#elif defined(UCIS_ENABLE)
+ return process_ucis(keycode, record);
+#else
+ return true;
+#endif
}
diff --git a/quantum/process_keycode/process_unicode_common.h b/quantum/process_keycode/process_unicode_common.h
index 4d2b04fb39..e608ab76be 100644
--- a/quantum/process_keycode/process_unicode_common.h
+++ b/quantum/process_keycode/process_unicode_common.h
@@ -14,33 +14,71 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef PROCESS_UNICODE_COMMON_H
-#define PROCESS_UNICODE_COMMON_H
+#pragma once
#include "quantum.h"
-#ifndef UNICODE_TYPE_DELAY
-#define UNICODE_TYPE_DELAY 10
+#if defined(UNICODE_ENABLE) + defined(UNICODEMAP_ENABLE) + defined(UCIS_ENABLE) > 1
+ #error "Cannot enable more than one Unicode method (UNICODE, UNICODEMAP, UCIS) at the same time"
+#endif
+
+// Keycodes used for starting Unicode input on different platforms
+#ifndef UNICODE_OSX_KEY
+ #define UNICODE_OSX_KEY KC_LALT
+#endif
+#ifndef UNICODE_WINC_KEY
+ #define UNICODE_WINC_KEY KC_RALT
#endif
-__attribute__ ((unused))
-static uint8_t input_mode;
+// Comma-delimited, ordered list of input modes selected for use (e.g. in cycle)
+// Example: #define UNICODE_SELECTED_MODES UC_WINC, UC_LNX
+#ifndef UNICODE_SELECTED_MODES
+ #define UNICODE_SELECTED_MODES -1
+#endif
+
+// Whether input mode changes in cycle should be written to EEPROM
+#ifndef UNICODE_CYCLE_PERSIST
+ #define UNICODE_CYCLE_PERSIST true
+#endif
-void set_unicode_input_mode(uint8_t os_target);
+// Delay between starting Unicode input and sending a sequence, in ms
+#ifndef UNICODE_TYPE_DELAY
+ #define UNICODE_TYPE_DELAY 10
+#endif
+
+enum unicode_input_modes {
+ UC_OSX, // Mac OS X using Unicode Hex Input
+ UC_LNX, // Linux using IBus
+ UC_WIN, // Windows using EnableHexNumpad
+ UC_BSD, // BSD (not implemented)
+ UC_WINC, // Windows using WinCompose (https://github.com/samhocevar/wincompose)
+ UC__COUNT // Number of available input modes (always leave at the end)
+};
+
+typedef union {
+ uint32_t raw;
+ struct {
+ uint8_t input_mode : 8;
+ };
+} unicode_config_t;
+
+extern unicode_config_t unicode_config;
+
+void unicode_input_mode_init(void);
uint8_t get_unicode_input_mode(void);
+void set_unicode_input_mode(uint8_t mode);
+void cycle_unicode_input_mode(uint8_t offset);
+void persist_unicode_input_mode(void);
+
void unicode_input_start(void);
void unicode_input_finish(void);
+
void register_hex(uint16_t hex);
+void send_unicode_hex_string(const char *str);
-#define UC_OSX 0 // Mac OS X
-#define UC_LNX 1 // Linux
-#define UC_WIN 2 // Windows 'HexNumpad'
-#define UC_BSD 3 // BSD (not implemented)
-#define UC_WINC 4 // WinCompose https://github.com/samhocevar/wincompose
-#define UC_OSX_RALT 5 // Mac OS X using Right Alt key for Unicode Compose
+bool process_unicode_common(uint16_t keycode, keyrecord_t *record);
#define UC_BSPC UC(0x0008)
-
#define UC_SPC UC(0x0020)
#define UC_EXLM UC(0x0021)
@@ -145,5 +183,3 @@ void register_hex(uint16_t hex);
#define UC_RCBR UC(0x007D)
#define UC_TILD UC(0x007E)
#define UC_DEL UC(0x007F)
-
-#endif
diff --git a/quantum/process_keycode/process_unicodemap.c b/quantum/process_keycode/process_unicodemap.c
index 47c27b9117..cee9acb5fc 100644
--- a/quantum/process_keycode/process_unicodemap.c
+++ b/quantum/process_keycode/process_unicodemap.c
@@ -18,8 +18,7 @@
#include "process_unicode_common.h"
__attribute__((weak))
-const uint32_t PROGMEM unicode_map[] = {
-};
+const uint32_t PROGMEM unicode_map[] = {};
void register_hex32(uint32_t hex) {
bool onzerostart = true;
@@ -42,26 +41,26 @@ void register_hex32(uint32_t hex) {
}
__attribute__((weak))
-void unicode_map_input_error() {}
+void unicodemap_input_error() {}
-bool process_unicode_map(uint16_t keycode, keyrecord_t *record) {
- uint8_t input_mode = get_unicode_input_mode();
- if ((keycode & QK_UNICODE_MAP) == QK_UNICODE_MAP && record->event.pressed) {
- const uint32_t* map = unicode_map;
- uint16_t index = keycode - QK_UNICODE_MAP;
- uint32_t code = pgm_read_dword(&map[index]);
- if (code > 0xFFFF && code <= 0x10ffff && (input_mode == UC_OSX || input_mode == UC_OSX_RALT)) {
+bool process_unicodemap(uint16_t keycode, keyrecord_t *record) {
+ if ((keycode & QK_UNICODEMAP) == QK_UNICODEMAP && record->event.pressed) {
+ uint16_t index = keycode - QK_UNICODEMAP;
+ uint32_t code = pgm_read_dword(unicode_map + index);
+ uint8_t input_mode = get_unicode_input_mode();
+
+ if (code > 0xFFFF && code <= 0x10FFFF && input_mode == UC_OSX) {
// Convert to UTF-16 surrogate pair
code -= 0x10000;
- uint32_t lo = code & 0x3ff;
- uint32_t hi = (code & 0xffc00) >> 10;
+ uint32_t lo = code & 0x3FF, hi = (code & 0xFFC00) >> 10;
+
unicode_input_start();
- register_hex32(hi + 0xd800);
- register_hex32(lo + 0xdc00);
+ register_hex32(hi + 0xD800);
+ register_hex32(lo + 0xDC00);
unicode_input_finish();
- } else if ((code > 0x10ffff && (input_mode == UC_OSX || input_mode == UC_OSX_RALT)) || (code > 0xFFFFF && input_mode == UC_LNX)) {
- // when character is out of range supported by the OS
- unicode_map_input_error();
+ } else if ((code > 0x10FFFF && input_mode == UC_OSX) || (code > 0xFFFFF && input_mode == UC_LNX)) {
+ // Character is out of range supported by the OS
+ unicodemap_input_error();
} else {
unicode_input_start();
register_hex32(code);
diff --git a/quantum/process_keycode/process_unicodemap.h b/quantum/process_keycode/process_unicodemap.h
index 929c88c0b6..5764697f84 100644
--- a/quantum/process_keycode/process_unicodemap.h
+++ b/quantum/process_keycode/process_unicodemap.h
@@ -14,12 +14,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef PROCESS_UNICODEMAP_H
-#define PROCESS_UNICODEMAP_H
+#pragma once
#include "quantum.h"
#include "process_unicode_common.h"
-void unicode_map_input_error(void);
-bool process_unicode_map(uint16_t keycode, keyrecord_t *record);
-#endif
+void unicodemap_input_error(void);
+bool process_unicodemap(uint16_t keycode, keyrecord_t *record);