diff options
| author | Jack Humbert <[email protected]> | 2017-02-15 23:46:31 -0500 | 
|---|---|---|
| committer | GitHub <[email protected]> | 2017-02-15 23:46:31 -0500 | 
| commit | 77b6ac831eb58e753cc666c66a67e9a9be369061 (patch) | |
| tree | 04e3074214a8415a8b0404477561d990a9ce205c /quantum/process_keycode | |
| parent | 7bef285553dee01bbcb1eaadefbfb39ed75baea4 (diff) | |
| parent | 58823b4e0324f5b2861fc5a0f74f6faa3673f5dc (diff) | |
| download | qmk_firmware-77b6ac831eb58e753cc666c66a67e9a9be369061.tar.gz qmk_firmware-77b6ac831eb58e753cc666c66a67e9a9be369061.zip | |
Merge pull request #1104 from qmk/layer_tap_toggle0.5.27
Adds layer tap toggle as TT(layer)
Diffstat (limited to 'quantum/process_keycode')
| -rw-r--r-- | quantum/process_keycode/process_ucis.c | 133 | ||||
| -rw-r--r-- | quantum/process_keycode/process_ucis.h | 35 | ||||
| -rw-r--r-- | quantum/process_keycode/process_unicode.c | 285 | ||||
| -rw-r--r-- | quantum/process_keycode/process_unicode.h | 160 | ||||
| -rw-r--r-- | quantum/process_keycode/process_unicode_common.c | 85 | ||||
| -rw-r--r-- | quantum/process_keycode/process_unicode_common.h | 131 | ||||
| -rw-r--r-- | quantum/process_keycode/process_unicodemap.c | 54 | ||||
| -rw-r--r-- | quantum/process_keycode/process_unicodemap.h | 9 | 
8 files changed, 448 insertions, 444 deletions
| diff --git a/quantum/process_keycode/process_ucis.c b/quantum/process_keycode/process_ucis.c new file mode 100644 index 0000000000..4ad2533b08 --- /dev/null +++ b/quantum/process_keycode/process_ucis.c @@ -0,0 +1,133 @@ +#include "process_ucis.h" + +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; +}
\ No newline at end of file diff --git a/quantum/process_keycode/process_ucis.h b/quantum/process_keycode/process_ucis.h new file mode 100644 index 0000000000..4332f57b35 --- /dev/null +++ b/quantum/process_keycode/process_ucis.h @@ -0,0 +1,35 @@ +#ifndef PROCESS_UCIS_H +#define PROCESS_UCIS_H + +#include "quantum.h" +#include "process_unicode_common.h" + +#ifndef UCIS_MAX_SYMBOL_LENGTH +#define UCIS_MAX_SYMBOL_LENGTH 32 +#endif + +typedef struct { +  char *symbol; +  char *code; +} qk_ucis_symbol_t; + +typedef struct { +  uint8_t count; +  uint16_t codes[UCIS_MAX_SYMBOL_LENGTH]; +  bool in_progress:1; +} qk_ucis_state_t; + +extern qk_ucis_state_t qk_ucis_state; + +#define UCIS_TABLE(...) {__VA_ARGS__, {NULL, NULL}} +#define UCIS_SYM(name, code) {name, #code} + +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 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 9d01a592d2..ccae6fdcad 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -1,103 +1,6 @@  #include "process_unicode.h"  #include "action_util.h" -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; -} - -uint8_t get_unicode_input_mode(void) { -  return input_mode; -} - -__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) { -  case UC_OSX: -    register_code(KC_LALT); -    break; -  case UC_LNX: -    register_code(KC_LCTL); -    register_code(KC_LSFT); -    register_code(KC_U); -    unregister_code(KC_U); -    unregister_code(KC_LSFT); -    unregister_code(KC_LCTL); -    break; -  case UC_WIN: -    register_code(KC_LALT); -    register_code(KC_PPLS); -    unregister_code(KC_PPLS); -    break; -  case UC_WINC: -    register_code(KC_RALT); -    unregister_code(KC_RALT); -    register_code(KC_U); -    unregister_code(KC_U); -  } -  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_LNX: -      register_code(KC_SPC); -      unregister_code(KC_SPC); -      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); -} - -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)); -  } -} -  bool process_unicode(uint16_t keycode, keyrecord_t *record) {    if (keycode > QK_UNICODE && record->event.pressed) {      uint16_t unicode = keycode & 0x7FFF; @@ -108,191 +11,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 diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h index f17cfa6cf2..4c21f11eb9 100644 --- a/quantum/process_keycode/process_unicode.h +++ b/quantum/process_keycode/process_unicode.h @@ -2,166 +2,8 @@  #define PROCESS_UNICODE_H  #include "quantum.h" - -#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 - -#ifndef UNICODE_TYPE_DELAY -#define UNICODE_TYPE_DELAY 10 -#endif - -void set_unicode_input_mode(uint8_t os_target); -uint8_t get_unicode_input_mode(void); -void unicode_input_start(void); -void unicode_input_finish(void); -void register_hex(uint16_t hex); +#include "process_unicode_common.h"  bool process_unicode(uint16_t keycode, keyrecord_t *record); -#ifdef UNICODEMAP_ENABLE -void unicode_map_input_error(void); -bool process_unicode_map(uint16_t keycode, keyrecord_t *record); -#endif - -#ifdef UCIS_ENABLE -#ifndef UCIS_MAX_SYMBOL_LENGTH -#define UCIS_MAX_SYMBOL_LENGTH 32 -#endif - -typedef struct { -  char *symbol; -  char *code; -} qk_ucis_symbol_t; - -typedef struct { -  uint8_t count; -  uint16_t codes[UCIS_MAX_SYMBOL_LENGTH]; -  bool in_progress:1; -} qk_ucis_state_t; - -extern qk_ucis_state_t qk_ucis_state; - -#define UCIS_TABLE(...) {__VA_ARGS__, {NULL, NULL}} -#define UCIS_SYM(name, code) {name, #code} - -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 register_ucis(const char *hex); -bool process_ucis (uint16_t keycode, keyrecord_t *record); - -#endif - -#define UC_BSPC	UC(0x0008) - -#define UC_SPC	UC(0x0020) - -#define UC_EXLM	UC(0x0021) -#define UC_DQUT	UC(0x0022) -#define UC_HASH	UC(0x0023) -#define UC_DLR	UC(0x0024) -#define UC_PERC	UC(0x0025) -#define UC_AMPR	UC(0x0026) -#define UC_QUOT	UC(0x0027) -#define UC_LPRN	UC(0x0028) -#define UC_RPRN	UC(0x0029) -#define UC_ASTR	UC(0x002A) -#define UC_PLUS	UC(0x002B) -#define UC_COMM	UC(0x002C) -#define UC_DASH	UC(0x002D) -#define UC_DOT	UC(0x002E) -#define UC_SLSH	UC(0x002F) - -#define UC_0	UC(0x0030) -#define UC_1	UC(0x0031) -#define UC_2	UC(0x0032) -#define UC_3	UC(0x0033) -#define UC_4	UC(0x0034) -#define UC_5	UC(0x0035) -#define UC_6	UC(0x0036) -#define UC_7	UC(0x0037) -#define UC_8	UC(0x0038) -#define UC_9	UC(0x0039) - -#define UC_COLN UC(0x003A) -#define UC_SCLN UC(0x003B) -#define UC_LT	UC(0x003C) -#define UC_EQL	UC(0x003D) -#define UC_GT	UC(0x003E) -#define UC_QUES	UC(0x003F) -#define UC_AT 	UC(0x0040) - -#define UC_A 	UC(0x0041) -#define UC_B 	UC(0x0042) -#define UC_C 	UC(0x0043) -#define UC_D 	UC(0x0044) -#define UC_E 	UC(0x0045) -#define UC_F 	UC(0x0046) -#define UC_G 	UC(0x0047) -#define UC_H 	UC(0x0048) -#define UC_I 	UC(0x0049) -#define UC_J 	UC(0x004A) -#define UC_K 	UC(0x004B) -#define UC_L 	UC(0x004C) -#define UC_M 	UC(0x004D) -#define UC_N 	UC(0x004E) -#define UC_O 	UC(0x004F) -#define UC_P 	UC(0x0050) -#define UC_Q 	UC(0x0051) -#define UC_R 	UC(0x0052) -#define UC_S 	UC(0x0053) -#define UC_T 	UC(0x0054) -#define UC_U 	UC(0x0055) -#define UC_V 	UC(0x0056) -#define UC_W 	UC(0x0057) -#define UC_X 	UC(0x0058) -#define UC_Y 	UC(0x0059) -#define UC_Z 	UC(0x005A) - -#define UC_LBRC	UC(0x005B) -#define UC_BSLS	UC(0x005C) -#define UC_RBRC	UC(0x005D) -#define UC_CIRM	UC(0x005E) -#define UC_UNDR	UC(0x005F) - -#define UC_GRV 	UC(0x0060) - -#define UC_a 	UC(0x0061) -#define UC_b 	UC(0x0062) -#define UC_c 	UC(0x0063) -#define UC_d 	UC(0x0064) -#define UC_e 	UC(0x0065) -#define UC_f 	UC(0x0066) -#define UC_g 	UC(0x0067) -#define UC_h 	UC(0x0068) -#define UC_i 	UC(0x0069) -#define UC_j 	UC(0x006A) -#define UC_k 	UC(0x006B) -#define UC_l 	UC(0x006C) -#define UC_m 	UC(0x006D) -#define UC_n 	UC(0x006E) -#define UC_o 	UC(0x006F) -#define UC_p 	UC(0x0070) -#define UC_q 	UC(0x0071) -#define UC_r 	UC(0x0072) -#define UC_s 	UC(0x0073) -#define UC_t 	UC(0x0074) -#define UC_u 	UC(0x0075) -#define UC_v 	UC(0x0076) -#define UC_w 	UC(0x0077) -#define UC_x 	UC(0x0078) -#define UC_y 	UC(0x0079) -#define UC_z 	UC(0x007A) - -#define UC_LCBR	UC(0x007B) -#define UC_PIPE	UC(0x007C) -#define UC_RCBR	UC(0x007D) -#define UC_TILD	UC(0x007E) -#define UC_DEL	UC(0x007F) -  #endif diff --git a/quantum/process_keycode/process_unicode_common.c b/quantum/process_keycode/process_unicode_common.c new file mode 100644 index 0000000000..31bc3b7ab3 --- /dev/null +++ b/quantum/process_keycode/process_unicode_common.c @@ -0,0 +1,85 @@ +#include "process_unicode_common.h" + +uint8_t mods; + +void set_unicode_input_mode(uint8_t os_target) +{ +  input_mode = os_target; +} + +uint8_t get_unicode_input_mode(void) { +  return input_mode; +} + +__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) { +  case UC_OSX: +    register_code(KC_LALT); +    break; +  case UC_LNX: +    register_code(KC_LCTL); +    register_code(KC_LSFT); +    register_code(KC_U); +    unregister_code(KC_U); +    unregister_code(KC_LSFT); +    unregister_code(KC_LCTL); +    break; +  case UC_WIN: +    register_code(KC_LALT); +    register_code(KC_PPLS); +    unregister_code(KC_PPLS); +    break; +  case UC_WINC: +    register_code(KC_RALT); +    unregister_code(KC_RALT); +    register_code(KC_U); +    unregister_code(KC_U); +  } +  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_LNX: +      register_code(KC_SPC); +      unregister_code(KC_SPC); +      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); +} + +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)); +  } +}
\ No newline at end of file diff --git a/quantum/process_keycode/process_unicode_common.h b/quantum/process_keycode/process_unicode_common.h new file mode 100644 index 0000000000..1f25eae7dd --- /dev/null +++ b/quantum/process_keycode/process_unicode_common.h @@ -0,0 +1,131 @@ +#ifndef PROCESS_UNICODE_COMMON_H +#define PROCESS_UNICODE_COMMON_H + +#include "quantum.h" + +#ifndef UNICODE_TYPE_DELAY +#define UNICODE_TYPE_DELAY 10 +#endif + +static uint8_t input_mode; + +void set_unicode_input_mode(uint8_t os_target); +uint8_t get_unicode_input_mode(void); +void unicode_input_start(void); +void unicode_input_finish(void); +void register_hex(uint16_t hex); + +#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_BSPC	UC(0x0008) + +#define UC_SPC	UC(0x0020) + +#define UC_EXLM	UC(0x0021) +#define UC_DQUT	UC(0x0022) +#define UC_HASH	UC(0x0023) +#define UC_DLR	UC(0x0024) +#define UC_PERC	UC(0x0025) +#define UC_AMPR	UC(0x0026) +#define UC_QUOT	UC(0x0027) +#define UC_LPRN	UC(0x0028) +#define UC_RPRN	UC(0x0029) +#define UC_ASTR	UC(0x002A) +#define UC_PLUS	UC(0x002B) +#define UC_COMM	UC(0x002C) +#define UC_DASH	UC(0x002D) +#define UC_DOT	UC(0x002E) +#define UC_SLSH	UC(0x002F) + +#define UC_0	UC(0x0030) +#define UC_1	UC(0x0031) +#define UC_2	UC(0x0032) +#define UC_3	UC(0x0033) +#define UC_4	UC(0x0034) +#define UC_5	UC(0x0035) +#define UC_6	UC(0x0036) +#define UC_7	UC(0x0037) +#define UC_8	UC(0x0038) +#define UC_9	UC(0x0039) + +#define UC_COLN UC(0x003A) +#define UC_SCLN UC(0x003B) +#define UC_LT	UC(0x003C) +#define UC_EQL	UC(0x003D) +#define UC_GT	UC(0x003E) +#define UC_QUES	UC(0x003F) +#define UC_AT 	UC(0x0040) + +#define UC_A 	UC(0x0041) +#define UC_B 	UC(0x0042) +#define UC_C 	UC(0x0043) +#define UC_D 	UC(0x0044) +#define UC_E 	UC(0x0045) +#define UC_F 	UC(0x0046) +#define UC_G 	UC(0x0047) +#define UC_H 	UC(0x0048) +#define UC_I 	UC(0x0049) +#define UC_J 	UC(0x004A) +#define UC_K 	UC(0x004B) +#define UC_L 	UC(0x004C) +#define UC_M 	UC(0x004D) +#define UC_N 	UC(0x004E) +#define UC_O 	UC(0x004F) +#define UC_P 	UC(0x0050) +#define UC_Q 	UC(0x0051) +#define UC_R 	UC(0x0052) +#define UC_S 	UC(0x0053) +#define UC_T 	UC(0x0054) +#define UC_U 	UC(0x0055) +#define UC_V 	UC(0x0056) +#define UC_W 	UC(0x0057) +#define UC_X 	UC(0x0058) +#define UC_Y 	UC(0x0059) +#define UC_Z 	UC(0x005A) + +#define UC_LBRC	UC(0x005B) +#define UC_BSLS	UC(0x005C) +#define UC_RBRC	UC(0x005D) +#define UC_CIRM	UC(0x005E) +#define UC_UNDR	UC(0x005F) + +#define UC_GRV 	UC(0x0060) + +#define UC_a 	UC(0x0061) +#define UC_b 	UC(0x0062) +#define UC_c 	UC(0x0063) +#define UC_d 	UC(0x0064) +#define UC_e 	UC(0x0065) +#define UC_f 	UC(0x0066) +#define UC_g 	UC(0x0067) +#define UC_h 	UC(0x0068) +#define UC_i 	UC(0x0069) +#define UC_j 	UC(0x006A) +#define UC_k 	UC(0x006B) +#define UC_l 	UC(0x006C) +#define UC_m 	UC(0x006D) +#define UC_n 	UC(0x006E) +#define UC_o 	UC(0x006F) +#define UC_p 	UC(0x0070) +#define UC_q 	UC(0x0071) +#define UC_r 	UC(0x0072) +#define UC_s 	UC(0x0073) +#define UC_t 	UC(0x0074) +#define UC_u 	UC(0x0075) +#define UC_v 	UC(0x0076) +#define UC_w 	UC(0x0077) +#define UC_x 	UC(0x0078) +#define UC_y 	UC(0x0079) +#define UC_z 	UC(0x007A) + +#define UC_LCBR	UC(0x007B) +#define UC_PIPE	UC(0x007C) +#define UC_RCBR	UC(0x007D) +#define UC_TILD	UC(0x007E) +#define UC_DEL	UC(0x007F) + +#endif
\ No newline at end of file diff --git a/quantum/process_keycode/process_unicodemap.c b/quantum/process_keycode/process_unicodemap.c new file mode 100644 index 0000000000..37f10df866 --- /dev/null +++ b/quantum/process_keycode/process_unicodemap.c @@ -0,0 +1,54 @@ +#include "process_unicodemap.h" + +__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; +}
\ No newline at end of file diff --git a/quantum/process_keycode/process_unicodemap.h b/quantum/process_keycode/process_unicodemap.h new file mode 100644 index 0000000000..64a7a01090 --- /dev/null +++ b/quantum/process_keycode/process_unicodemap.h @@ -0,0 +1,9 @@ +#ifndef PROCESS_UNICODEMAP_H +#define PROCESS_UNICODEMAP_H + +#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
\ No newline at end of file | 
