|
|
@ -4,18 +4,6 @@ |
|
|
|
static uint8_t input_mode; |
|
|
|
uint8_t mods; |
|
|
|
|
|
|
|
__attribute__((weak)) |
|
|
|
uint16_t hex_to_keycode(uint8_t hex) |
|
|
|
{ |
|
|
|
if (hex == 0x0) { |
|
|
|
return KC_0; |
|
|
|
} else if (hex < 0xA) { |
|
|
|
return KC_1 + (hex - 0x1); |
|
|
|
} else { |
|
|
|
return KC_A + (hex - 0xA); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void set_unicode_input_mode(uint8_t os_target) |
|
|
|
{ |
|
|
|
input_mode = os_target; |
|
|
@ -108,191 +96,3 @@ bool process_unicode(uint16_t keycode, keyrecord_t *record) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
#ifdef UNICODEMAP_ENABLE |
|
|
|
__attribute__((weak)) |
|
|
|
const uint32_t PROGMEM unicode_map[] = { |
|
|
|
}; |
|
|
|
|
|
|
|
void register_hex32(uint32_t hex) { |
|
|
|
uint8_t onzerostart = 1; |
|
|
|
for(int i = 7; i >= 0; i--) { |
|
|
|
if (i <= 3) { |
|
|
|
onzerostart = 0; |
|
|
|
} |
|
|
|
uint8_t digit = ((hex >> (i*4)) & 0xF); |
|
|
|
if (digit == 0) { |
|
|
|
if (onzerostart == 0) { |
|
|
|
register_code(hex_to_keycode(digit)); |
|
|
|
unregister_code(hex_to_keycode(digit)); |
|
|
|
} |
|
|
|
} else { |
|
|
|
register_code(hex_to_keycode(digit)); |
|
|
|
unregister_code(hex_to_keycode(digit)); |
|
|
|
onzerostart = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
__attribute__((weak)) |
|
|
|
void unicode_map_input_error() {} |
|
|
|
|
|
|
|
bool process_unicode_map(uint16_t keycode, keyrecord_t *record) { |
|
|
|
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_far(&map[index]); |
|
|
|
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; |
|
|
|
unicode_input_start(); |
|
|
|
register_hex32(hi + 0xd800); |
|
|
|
register_hex32(lo + 0xdc00); |
|
|
|
unicode_input_finish(); |
|
|
|
} else if ((code > 0x10ffff && input_mode == UC_OSX) || (code > 0xFFFFF && input_mode == UC_LNX)) { |
|
|
|
// when character is out of range supported by the OS |
|
|
|
unicode_map_input_error(); |
|
|
|
} else { |
|
|
|
unicode_input_start(); |
|
|
|
register_hex32(code); |
|
|
|
unicode_input_finish(); |
|
|
|
} |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
#ifdef UCIS_ENABLE |
|
|
|
qk_ucis_state_t qk_ucis_state; |
|
|
|
|
|
|
|
void qk_ucis_start(void) { |
|
|
|
qk_ucis_state.count = 0; |
|
|
|
qk_ucis_state.in_progress = true; |
|
|
|
|
|
|
|
qk_ucis_start_user(); |
|
|
|
} |
|
|
|
|
|
|
|
__attribute__((weak)) |
|
|
|
void qk_ucis_start_user(void) { |
|
|
|
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); |
|
|
|
wait_ms(UNICODE_TYPE_DELAY); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void register_ucis(const char *hex) { |
|
|
|
for(int i = 0; hex[i]; i++) { |
|
|
|
uint8_t kc = 0; |
|
|
|
char c = hex[i]; |
|
|
|
|
|
|
|
switch (c) { |
|
|
|
case '0': |
|
|
|
kc = KC_0; |
|
|
|
break; |
|
|
|
case '1' ... '9': |
|
|
|
kc = c - '1' + KC_1; |
|
|
|
break; |
|
|
|
case 'a' ... 'f': |
|
|
|
kc = c - 'a' + KC_A; |
|
|
|
break; |
|
|
|
case 'A' ... 'F': |
|
|
|
kc = c - 'A' + KC_A; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
if (kc) { |
|
|
|
register_code (kc); |
|
|
|
unregister_code (kc); |
|
|
|
wait_ms (UNICODE_TYPE_DELAY); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
bool process_ucis (uint16_t keycode, keyrecord_t *record) { |
|
|
|
uint8_t i; |
|
|
|
|
|
|
|
if (!qk_ucis_state.in_progress) |
|
|
|
return true; |
|
|
|
|
|
|
|
if (qk_ucis_state.count >= UCIS_MAX_SYMBOL_LENGTH && |
|
|
|
!(keycode == KC_BSPC || keycode == KC_ESC || keycode == KC_SPC || keycode == KC_ENT)) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
if (!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); |
|
|
|
wait_ms(UNICODE_TYPE_DELAY); |
|
|
|
} |
|
|
|
|
|
|
|
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; |
|
|
|
register_ucis(ucis_symbol_table[i].code + 2); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!symbol_found) { |
|
|
|
qk_ucis_symbol_fallback(); |
|
|
|
} |
|
|
|
unicode_input_finish(); |
|
|
|
|
|
|
|
qk_ucis_state.in_progress = false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
#endif |