process_unicode: Add a way to enter unicode symbols by name

The purpose of this change is to allow keymaps to specify a dictionary
of unicode symbol name to code mappings, and let the person at the
keyboard enter unicode symbols by name.

This is done by having a way to trigger unicode symbol input mode, when
all keys are cached until Esc, Enter or Space are pressed. Once that
happens, we try to look up the symbol from our lookup table. If found,
we erase back, and type the unicode magic in to get that symbol. If not
found, we still erase back, start unicode input mode, and replay what
the user typed in.

Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
This commit is contained in:
Gergely Nagy 2016-08-13 10:46:38 +02:00
parent 63e5782d2c
commit fa06a16360
3 changed files with 126 additions and 3 deletions

View File

@ -198,6 +198,11 @@ ifeq ($(strip $(AUDIO_ENABLE)), yes)
SRC += $(QUANTUM_DIR)/audio/luts.c SRC += $(QUANTUM_DIR)/audio/luts.c
endif endif
ifeq ($(strip $(UCIS_ENABLE)), yes)
OPT_DEFS += -DUCIS_ENABLE
UNICODE_ENABLE = yes
endif
ifeq ($(strip $(UNICODE_ENABLE)), yes) ifeq ($(strip $(UNICODE_ENABLE)), yes)
OPT_DEFS += -DUNICODE_ENABLE OPT_DEFS += -DUNICODE_ENABLE
SRC += $(QUANTUM_DIR)/process_keycode/process_unicode.c SRC += $(QUANTUM_DIR)/process_keycode/process_unicode.c

View File

@ -69,3 +69,94 @@ bool process_unicode(uint16_t keycode, keyrecord_t *record) {
} }
return true; return true;
} }
#ifdef UCIS_ENABLE
void qk_ucis_start(void) {
qk_ucis_state.count = 0;
qk_ucis_state.in_progress = true;
unicode_input_start();
register_hex(0x2328);
unicode_input_finish();
}
static bool is_uni_seq(char *seq) {
uint8_t i;
for (i = 0; seq[i]; i++) {
uint16_t code;
if (('1' <= seq[i]) && (seq[i] <= '0'))
code = seq[i] - '1' + KC_1;
else
code = seq[i] - 'a' + KC_A;
if (i > qk_ucis_state.count || qk_ucis_state.codes[i] != code)
return false;
}
return (qk_ucis_state.codes[i] == KC_ENT ||
qk_ucis_state.codes[i] == KC_SPC);
}
__attribute__((weak))
void qk_ucis_symbol_fallback (void) {
for (uint8_t i = 0; i < qk_ucis_state.count - 1; i++) {
uint8_t code = qk_ucis_state.codes[i];
register_code(code);
unregister_code(code);
}
}
bool process_record_ucis (uint16_t keycode, keyrecord_t *record) {
uint8_t i;
if (!qk_ucis_state.in_progress || !record->event.pressed)
return true;
qk_ucis_state.codes[qk_ucis_state.count] = keycode;
qk_ucis_state.count++;
if (keycode == KC_BSPC) {
if (qk_ucis_state.count >= 2) {
qk_ucis_state.count -= 2;
return true;
} else {
qk_ucis_state.count--;
return false;
}
}
if (keycode == KC_ENT || keycode == KC_SPC || keycode == KC_ESC) {
bool symbol_found = false;
for (i = qk_ucis_state.count; i > 0; i--) {
register_code (KC_BSPC);
unregister_code (KC_BSPC);
}
if (keycode == KC_ESC) {
qk_ucis_state.in_progress = false;
return false;
}
unicode_input_start();
for (i = 0; ucis_symbol_table[i].symbol; i++) {
if (is_uni_seq (ucis_symbol_table[i].symbol)) {
symbol_found = true;
for (uint8_t j = 0; ucis_symbol_table[i].codes[j]; j++) {
register_hex(ucis_symbol_table[i].codes[j]);
}
break;
}
}
if (!symbol_found) {
qk_ucis_symbol_fallback();
}
unicode_input_finish();
qk_ucis_state.in_progress = false;
return false;
}
return true;
}
#endif

View File

@ -15,6 +15,33 @@ void register_hex(uint16_t hex);
bool process_unicode(uint16_t keycode, keyrecord_t *record); bool process_unicode(uint16_t keycode, keyrecord_t *record);
#ifdef UCIS_ENABLE
#ifndef UCIS_MAX_SYMBOL_LENGTH
#define UCIS_MAX_SYMBOL_LENGTH 32
#endif
typedef struct {
char *symbol;
uint16_t codes[4];
} qk_ucis_symbol_t;
struct {
uint8_t count;
uint16_t codes[UCIS_MAX_SYMBOL_LENGTH];
bool in_progress:1;
} qk_ucis_state;
#define UCIS_TABLE(...) {__VA_ARGS__, {NULL, {}}}
#define UCIS_SYM(name, ...) {name, {__VA_ARGS__, 0}}
extern const qk_ucis_symbol_t ucis_symbol_table[];
void qk_ucis_start(void);
void qk_ucis_symbol_fallback (void);
bool process_record_ucis (uint16_t keycode, keyrecord_t *record);
#endif
#define UC_BSPC UC(0x0008) #define UC_BSPC UC(0x0008)
#define UC_SPC UC(0x0020) #define UC_SPC UC(0x0020)