process_unicode.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. #include "process_unicode.h"
  2. static uint8_t input_mode;
  3. __attribute__((weak))
  4. uint16_t hex_to_keycode(uint8_t hex)
  5. {
  6. if (hex == 0x0) {
  7. return KC_0;
  8. } else if (hex < 0xA) {
  9. return KC_1 + (hex - 0x1);
  10. } else {
  11. return KC_A + (hex - 0xA);
  12. }
  13. }
  14. void set_unicode_input_mode(uint8_t os_target)
  15. {
  16. input_mode = os_target;
  17. }
  18. uint8_t get_unicode_input_mode(void) {
  19. return input_mode;
  20. }
  21. __attribute__((weak))
  22. void unicode_input_start (void) {
  23. switch(input_mode) {
  24. case UC_OSX:
  25. register_code(KC_LALT);
  26. break;
  27. case UC_LNX:
  28. register_code(KC_LCTL);
  29. register_code(KC_LSFT);
  30. register_code(KC_U);
  31. unregister_code(KC_U);
  32. unregister_code(KC_LSFT);
  33. unregister_code(KC_LCTL);
  34. break;
  35. case UC_WIN:
  36. register_code(KC_LALT);
  37. register_code(KC_PPLS);
  38. unregister_code(KC_PPLS);
  39. break;
  40. }
  41. wait_ms(UNICODE_TYPE_DELAY);
  42. }
  43. __attribute__((weak))
  44. void unicode_input_finish (void) {
  45. switch(input_mode) {
  46. case UC_OSX:
  47. case UC_WIN:
  48. unregister_code(KC_LALT);
  49. break;
  50. case UC_LNX:
  51. register_code(KC_SPC);
  52. unregister_code(KC_SPC);
  53. break;
  54. }
  55. }
  56. void register_hex(uint16_t hex) {
  57. for(int i = 3; i >= 0; i--) {
  58. uint8_t digit = ((hex >> (i*4)) & 0xF);
  59. register_code(hex_to_keycode(digit));
  60. unregister_code(hex_to_keycode(digit));
  61. }
  62. }
  63. bool process_unicode(uint16_t keycode, keyrecord_t *record) {
  64. if (keycode > QK_UNICODE && record->event.pressed) {
  65. uint16_t unicode = keycode & 0x7FFF;
  66. unicode_input_start();
  67. register_hex(unicode);
  68. unicode_input_finish();
  69. }
  70. return true;
  71. }
  72. #ifdef UNICODEMAP_ENABLE
  73. __attribute__((weak))
  74. const uint32_t PROGMEM unicode_map[] = {
  75. };
  76. void register_hex32(uint32_t hex) {
  77. uint8_t onzerostart = 1;
  78. for(int i = 7; i >= 0; i--) {
  79. if (i <= 3) {
  80. onzerostart = 0;
  81. }
  82. uint8_t digit = ((hex >> (i*4)) & 0xF);
  83. if (digit == 0) {
  84. if (onzerostart == 0) {
  85. register_code(hex_to_keycode(digit));
  86. unregister_code(hex_to_keycode(digit));
  87. }
  88. } else {
  89. register_code(hex_to_keycode(digit));
  90. unregister_code(hex_to_keycode(digit));
  91. onzerostart = 0;
  92. }
  93. }
  94. }
  95. __attribute__((weak))
  96. void unicode_map_input_error() {}
  97. bool process_unicode_map(uint16_t keycode, keyrecord_t *record) {
  98. if ((keycode & QK_UNICODE_MAP) == QK_UNICODE_MAP && record->event.pressed) {
  99. const uint32_t* map = unicode_map;
  100. uint16_t index = keycode & 0x7FF;
  101. uint32_t code = pgm_read_dword_far(&map[index]);
  102. if ((code > 0xFFFF && input_mode == UC_OSX) || (code > 0xFFFFF && input_mode == UC_LNX)) {
  103. // when character is out of range supported by the OS
  104. unicode_map_input_error();
  105. } else {
  106. unicode_input_start();
  107. register_hex32(code);
  108. unicode_input_finish();
  109. }
  110. }
  111. return true;
  112. }
  113. #endif
  114. #ifdef UCIS_ENABLE
  115. qk_ucis_state_t qk_ucis_state;
  116. void qk_ucis_start(void) {
  117. qk_ucis_state.count = 0;
  118. qk_ucis_state.in_progress = true;
  119. qk_ucis_start_user();
  120. }
  121. __attribute__((weak))
  122. void qk_ucis_start_user(void) {
  123. unicode_input_start();
  124. register_hex(0x2328);
  125. unicode_input_finish();
  126. }
  127. static bool is_uni_seq(char *seq) {
  128. uint8_t i;
  129. for (i = 0; seq[i]; i++) {
  130. uint16_t code;
  131. if (('1' <= seq[i]) && (seq[i] <= '0'))
  132. code = seq[i] - '1' + KC_1;
  133. else
  134. code = seq[i] - 'a' + KC_A;
  135. if (i > qk_ucis_state.count || qk_ucis_state.codes[i] != code)
  136. return false;
  137. }
  138. return (qk_ucis_state.codes[i] == KC_ENT ||
  139. qk_ucis_state.codes[i] == KC_SPC);
  140. }
  141. __attribute__((weak))
  142. void qk_ucis_symbol_fallback (void) {
  143. for (uint8_t i = 0; i < qk_ucis_state.count - 1; i++) {
  144. uint8_t code = qk_ucis_state.codes[i];
  145. register_code(code);
  146. unregister_code(code);
  147. wait_ms(UNICODE_TYPE_DELAY);
  148. }
  149. }
  150. void register_ucis(const char *hex) {
  151. for(int i = 0; hex[i]; i++) {
  152. uint8_t kc = 0;
  153. char c = hex[i];
  154. switch (c) {
  155. case '0':
  156. kc = KC_0;
  157. break;
  158. case '1' ... '9':
  159. kc = c - '1' + KC_1;
  160. break;
  161. case 'a' ... 'f':
  162. kc = c - 'a' + KC_A;
  163. break;
  164. case 'A' ... 'F':
  165. kc = c - 'A' + KC_A;
  166. break;
  167. }
  168. if (kc) {
  169. register_code (kc);
  170. unregister_code (kc);
  171. wait_ms (UNICODE_TYPE_DELAY);
  172. }
  173. }
  174. }
  175. bool process_ucis (uint16_t keycode, keyrecord_t *record) {
  176. uint8_t i;
  177. if (!qk_ucis_state.in_progress)
  178. return true;
  179. if (qk_ucis_state.count >= UCIS_MAX_SYMBOL_LENGTH &&
  180. !(keycode == KC_BSPC || keycode == KC_ESC || keycode == KC_SPC || keycode == KC_ENT)) {
  181. return false;
  182. }
  183. if (!record->event.pressed)
  184. return true;
  185. qk_ucis_state.codes[qk_ucis_state.count] = keycode;
  186. qk_ucis_state.count++;
  187. if (keycode == KC_BSPC) {
  188. if (qk_ucis_state.count >= 2) {
  189. qk_ucis_state.count -= 2;
  190. return true;
  191. } else {
  192. qk_ucis_state.count--;
  193. return false;
  194. }
  195. }
  196. if (keycode == KC_ENT || keycode == KC_SPC || keycode == KC_ESC) {
  197. bool symbol_found = false;
  198. for (i = qk_ucis_state.count; i > 0; i--) {
  199. register_code (KC_BSPC);
  200. unregister_code (KC_BSPC);
  201. wait_ms(UNICODE_TYPE_DELAY);
  202. }
  203. if (keycode == KC_ESC) {
  204. qk_ucis_state.in_progress = false;
  205. return false;
  206. }
  207. unicode_input_start();
  208. for (i = 0; ucis_symbol_table[i].symbol; i++) {
  209. if (is_uni_seq (ucis_symbol_table[i].symbol)) {
  210. symbol_found = true;
  211. register_ucis(ucis_symbol_table[i].code + 2);
  212. break;
  213. }
  214. }
  215. if (!symbol_found) {
  216. qk_ucis_symbol_fallback();
  217. }
  218. unicode_input_finish();
  219. qk_ucis_state.in_progress = false;
  220. return false;
  221. }
  222. return true;
  223. }
  224. #endif