diff options
author | QMK Bot <hello@qmk.fm> | 2021-12-15 04:54:21 +0000 |
---|---|---|
committer | QMK Bot <hello@qmk.fm> | 2021-12-15 04:54:21 +0000 |
commit | c0bb15315170f9265143833ad879b7c8f87b06ac (patch) | |
tree | 3a61a9cec73aac6c0172af3bf48efda147dedef9 /users/drashna/keyrecords/unicode.c | |
parent | 3c5b9f70f5faf9215d654b4f5d92c1ea6b34248a (diff) | |
parent | 3fa592a4024a24a636fa0c562e6761667a94f565 (diff) |
Merge remote-tracking branch 'origin/master' into develop
Diffstat (limited to 'users/drashna/keyrecords/unicode.c')
-rw-r--r-- | users/drashna/keyrecords/unicode.c | 287 |
1 files changed, 287 insertions, 0 deletions
diff --git a/users/drashna/keyrecords/unicode.c b/users/drashna/keyrecords/unicode.c new file mode 100644 index 0000000000..88df2c9df9 --- /dev/null +++ b/users/drashna/keyrecords/unicode.c @@ -0,0 +1,287 @@ +/* Copyright 2020 @ridingqwerty + * Copyright 2020 @tzarc + * Copyright 2021 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> + * + * 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 "drashna.h" +#include "process_unicode_common.h" + +uint16_t typing_mode; + +void tap_code16_nomods(uint8_t kc) { + uint8_t temp_mod = get_mods(); + clear_mods(); + clear_oneshot_mods(); + tap_code16(kc); + set_mods(temp_mod); +} + +void tap_unicode_glyph_nomods(uint32_t glyph) { + uint8_t temp_mod = get_mods(); + clear_mods(); + clear_oneshot_mods(); + register_unicode(glyph); + set_mods(temp_mod); +} + +typedef uint32_t (*translator_function_t)(bool is_shifted, uint32_t keycode); + +#define DEFINE_UNICODE_RANGE_TRANSLATOR(translator_name, lower_alpha, upper_alpha, zero_glyph, number_one, space_glyph) \ + static inline uint32_t translator_name(bool is_shifted, uint32_t keycode) { \ + switch (keycode) { \ + case KC_A ... KC_Z: \ + return (is_shifted ? upper_alpha : lower_alpha) + keycode - KC_A; \ + case KC_0: \ + return zero_glyph; \ + case KC_1 ... KC_9: \ + return (number_one + keycode - KC_1); \ + case KC_SPACE: \ + return space_glyph; \ + } \ + return keycode; \ + } + +#define DEFINE_UNICODE_LUT_TRANSLATOR(translator_name, ...) \ + static inline uint32_t translator_name(bool is_shifted, uint32_t keycode) { \ + static const uint32_t translation[] = {__VA_ARGS__}; \ + uint32_t ret = keycode; \ + if ((keycode - KC_A) < (sizeof(translation) / sizeof(uint32_t))) { \ + ret = translation[keycode - KC_A]; \ + } \ + return ret; \ + } + +bool process_record_glyph_replacement(uint16_t keycode, keyrecord_t *record, translator_function_t translator) { + uint8_t temp_mod = get_mods(); + uint8_t temp_osm = get_oneshot_mods(); + bool is_shifted = (temp_mod | temp_osm) & MOD_MASK_SHIFT; + if (((temp_mod | temp_osm) & (MOD_MASK_CTRL | MOD_MASK_ALT | MOD_MASK_GUI)) == 0) { + if (KC_A <= keycode && keycode <= KC_Z) { + if (record->event.pressed) { + tap_unicode_glyph_nomods(translator(is_shifted, keycode)); + } + return false; + } else if (KC_1 <= keycode && keycode <= KC_0) { + if (is_shifted) { // skip shifted numbers, so that we can still use symbols etc. + return process_record_keymap(keycode, record); + } + if (record->event.pressed) { + register_unicode(translator(is_shifted, keycode)); + } + return false; + } else if (keycode == KC_SPACE) { + if (record->event.pressed) { + register_unicode(translator(is_shifted, keycode)); + } + return false; + } + } + return true; +} + +DEFINE_UNICODE_RANGE_TRANSLATOR(unicode_range_translator_wide, 0xFF41, 0xFF21, 0xFF10, 0xFF11, 0x2003); +DEFINE_UNICODE_RANGE_TRANSLATOR(unicode_range_translator_script, 0x1D4EA, 0x1D4D0, 0x1D7CE, 0x1D7C1, 0x2002); +DEFINE_UNICODE_RANGE_TRANSLATOR(unicode_range_translator_boxes, 0x1F170, 0x1F170, '0', '1', 0x2002); +DEFINE_UNICODE_RANGE_TRANSLATOR(unicode_range_translator_regional, 0x1F1E6, 0x1F1E6, '0', '1', 0x2003); + +DEFINE_UNICODE_LUT_TRANSLATOR(unicode_lut_translator_aussie, + 0x0250, // a + 'q', // b + 0x0254, // c + 'p', // d + 0x01DD, // e + 0x025F, // f + 0x0183, // g + 0x0265, // h + 0x1D09, // i + 0x027E, // j + 0x029E, // k + 'l', // l + 0x026F, // m + 'u', // n + 'o', // o + 'd', // p + 'b', // q + 0x0279, // r + 's', // s + 0x0287, // t + 'n', // u + 0x028C, // v + 0x028D, // w + 0x2717, // x + 0x028E, // y + 'z', // z + 0x0269, // 1 + 0x3139, // 2 + 0x0190, // 3 + 0x3123, // 4 + 0x03DB, // 5 + '9', // 6 + 0x3125, // 7 + '8', // 8 + '6', // 9 + '0' // 0 +); + +bool process_record_aussie(uint16_t keycode, keyrecord_t *record) { + bool is_shifted = (get_mods() | get_oneshot_mods()) & MOD_MASK_SHIFT; + if ((KC_A <= keycode) && (keycode <= KC_0)) { + if (record->event.pressed) { + if (!process_record_glyph_replacement(keycode, record, unicode_lut_translator_aussie)) { + tap_code16_nomods(KC_LEFT); + return false; + } + } + } else if (record->event.pressed && keycode == KC_SPACE) { + tap_code16_nomods(KC_SPACE); + tap_code16_nomods(KC_LEFT); + return false; + } else if (record->event.pressed && keycode == KC_ENTER) { + tap_code16_nomods(KC_END); + tap_code16_nomods(KC_ENTER); + return false; + } else if (record->event.pressed && keycode == KC_HOME) { + tap_code16_nomods(KC_END); + return false; + } else if (record->event.pressed && keycode == KC_END) { + tap_code16_nomods(KC_HOME); + return false; + } else if (record->event.pressed && keycode == KC_BSPC) { + tap_code16_nomods(KC_DELT); + return false; + } else if (record->event.pressed && keycode == KC_DELT) { + tap_code16_nomods(KC_BSPC); + return false; + } else if (record->event.pressed && keycode == KC_QUOT) { + tap_unicode_glyph_nomods(is_shifted ? 0x201E : 0x201A); + tap_code16_nomods(KC_LEFT); + return false; + } else if (record->event.pressed && keycode == KC_COMMA) { + tap_unicode_glyph_nomods(is_shifted ? '<' : 0x2018); + tap_code16_nomods(KC_LEFT); + return false; + } else if (record->event.pressed && keycode == KC_DOT) { + tap_unicode_glyph_nomods(is_shifted ? '>' : 0x02D9); + tap_code16_nomods(KC_LEFT); + return false; + } else if (record->event.pressed && keycode == KC_SLASH) { + tap_unicode_glyph_nomods(is_shifted ? 0x00BF : '/'); + tap_code16_nomods(KC_LEFT); + return false; + } + return true; +} + +bool process_record_zalgo(uint16_t keycode, keyrecord_t *record) { + if ((KC_A <= keycode) && (keycode <= KC_0)) { + if (record->event.pressed) { + tap_code16_nomods(keycode); + + int number = (rand() % (8 + 1 - 2)) + 2; + for (int index = 0; index < number; index++) { + uint16_t hex = (rand() % (0x036F + 1 - 0x0300)) + 0x0300; + register_unicode(hex); + } + + return false; + } + } + return true; +} + +bool process_record_unicode(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case UC_FLIP: // (ノಠ痊ಠ)ノ彡┻━┻ + if (record->event.pressed) { + send_unicode_string("(ノಠ痊ಠ)ノ彡┻━┻"); + } + break; + + case UC_TABL: // ┬─┬ノ( º _ ºノ) + if (record->event.pressed) { + send_unicode_string("┬─┬ノ( º _ ºノ)"); + } + break; + + case UC_SHRG: // ¯\_(ツ)_/¯ + if (record->event.pressed) { + send_unicode_string("¯\\_(ツ)_/¯"); + } + break; + + case UC_DISA: // ಠ_ಠ + if (record->event.pressed) { + send_unicode_string("ಠ_ಠ"); + } + break; + + case UC_IRNY: // ⸮ + if (record->event.pressed) { + register_unicode(0x2E2E); + } + break; + case UC_CLUE: // ‽ + if (record->event.pressed) { + register_unicode(0x203D); + } + break; + case KC_NOMODE ... KC_ZALGO: + if (record->event.pressed) { + if (typing_mode != keycode) { + typing_mode = keycode; + } else { + typing_mode = 0; + } + } + break; + + break; + } + if (((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)) && record->tap.count) { + keycode &= 0xFF; + } + + if (typing_mode == KC_WIDE) { + if (((KC_A <= keycode) && (keycode <= KC_0)) || keycode == KC_SPACE) { + return process_record_glyph_replacement(keycode, record, unicode_range_translator_wide); + } + } else if (typing_mode == KC_SCRIPT) { + if (((KC_A <= keycode) && (keycode <= KC_0)) || keycode == KC_SPACE) { + return process_record_glyph_replacement(keycode, record, unicode_range_translator_script); + } + } else if (typing_mode == KC_BLOCKS) { + if (((KC_A <= keycode) && (keycode <= KC_0)) || keycode == KC_SPACE) { + return process_record_glyph_replacement(keycode, record, unicode_range_translator_boxes); + } + } else if (typing_mode == KC_REGIONAL) { + if (((KC_A <= keycode) && (keycode <= KC_0)) || keycode == KC_SPACE) { + if (!process_record_glyph_replacement(keycode, record, unicode_range_translator_regional)) { + wait_us(500); + tap_unicode_glyph_nomods(0x200C); + return false; + } + } + } else if (typing_mode == KC_AUSSIE) { + return process_record_aussie(keycode, record); + } else if (typing_mode == KC_ZALGO) { + return process_record_zalgo(keycode, record); + } + return process_unicode_common(keycode, record); +} + +void matrix_init_unicode(void) { + unicode_input_mode_init(); +} |