From 5b5b36421a7c887aad5bf5faef06dcf133d64f15 Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Sun, 28 Nov 2021 23:41:59 -0800 Subject: [Keymap] Unicode and cursor sync - drashna keymap (#15328) --- users/drashna/config.h | 9 ++ users/drashna/oled_stuff.c | 37 +++--- users/drashna/process_records.c | 25 +--- users/drashna/process_records.h | 17 ++- users/drashna/rules.mk | 12 +- users/drashna/transport_sync.c | 3 +- users/drashna/unicoooode.c | 282 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 336 insertions(+), 49 deletions(-) create mode 100644 users/drashna/unicoooode.c (limited to 'users') diff --git a/users/drashna/config.h b/users/drashna/config.h index ebb8d7b7ac..8b5d5ba937 100644 --- a/users/drashna/config.h +++ b/users/drashna/config.h @@ -41,6 +41,15 @@ # endif #endif +#if defined(WPM_ENABLE) +// # define WPM_LAUNCH_CONTROL +// # define WPM_ALLOW_COUNT_REGRESSOIN +// # define WPM_UNFILTERED +# define WPM_SAMPLE_SECONDS 6 +# define WPM_SAMPLE_PERIODS 50 +# define WPM_ESTIMATED_WORD_SIZE 6 +#endif + #ifdef AUDIO_ENABLE # define AUDIO_CLICKY # define AUDIO_CLICKY_FREQ_RANDOMNESS 1.5f diff --git a/users/drashna/oled_stuff.c b/users/drashna/oled_stuff.c index 396e5e05b7..2c92ac6e90 100644 --- a/users/drashna/oled_stuff.c +++ b/users/drashna/oled_stuff.c @@ -15,6 +15,10 @@ */ #include "drashna.h" +#ifdef CUSTOM_UNICODE_ENABLE +# include "process_unicode_common.h" +#endif +#include extern bool host_driver_disabled; @@ -59,7 +63,7 @@ void add_keylog(uint16_t keycode, keyrecord_t *record) { return; } if (record->tap.count) { - keycode = keycode & 0xFF; + keycode &= 0xFF; } else if (keycode > 0xFF) { return; } @@ -150,8 +154,10 @@ void render_keylock_status(uint8_t led_usb_state) { oled_write_P(PSTR(OLED_RENDER_LOCK_NUML), led_usb_state & (1 << USB_LED_NUM_LOCK)); oled_write_P(PSTR(" "), false); oled_write_P(PSTR(OLED_RENDER_LOCK_CAPS), led_usb_state & (1 << USB_LED_CAPS_LOCK)); -// oled_write_P(PSTR(" "), false); -// oled_write_P(PSTR(OLED_RENDER_LOCK_SCLK), led_usb_state & (1 << USB_LED_SCROLL_LOCK)); +#if defined(OLED_DISPLAY_128X64) + oled_write_P(PSTR(" "), false); + oled_write_P(PSTR(OLED_RENDER_LOCK_SCLK), led_usb_state & (1 << USB_LED_SCROLL_LOCK)); +#endif } void render_matrix_scan_rate(void) { @@ -296,7 +302,7 @@ void render_user_status(void) { oled_write_P(rgb_layer_status[userspace_config.rgb_layer_change], false); static const char PROGMEM cat_mode[2][3] = {{0xF8, 0xF9, 0}, {0xF6, 0xF7, 0}}; oled_write_P(cat_mode[0], host_driver_disabled); -#if defined(UNICODE_ENABLE) +#if defined(CUSTOM_UNICODE_ENABLE) static const char PROGMEM uc_mod_status[5][3] = {{0xEA, 0xEB, 0}, {0xEC, 0xED, 0}}; oled_write_P(uc_mod_status[get_unicode_input_mode() == UC_MAC], false); #endif @@ -327,39 +333,28 @@ void oled_driver_render_logo(void) { void render_wpm(uint8_t padding) { #ifdef WPM_ENABLE - uint8_t n = get_current_wpm(); - char wpm_counter[4]; - wpm_counter[3] = '\0'; - wpm_counter[2] = '0' + n % 10; - wpm_counter[1] = (n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' '; - wpm_counter[0] = n / 10 ? '0' + n / 10 : ' '; + oled_write_P(PSTR(OLED_RENDER_WPM_COUNTER), false); if (padding) { for (uint8_t n = padding; n > 0; n--) { oled_write_P(PSTR(" "), false); } } - oled_write(wpm_counter, false); + oled_write(get_u8_str(get_current_wpm(), ' '), false); #endif } #if defined(KEYBOARD_handwired_tractyl_manuform_5x6_right) extern kb_config_data_t kb_config; void render_pointing_dpi_status(uint8_t padding) { - char dpi_status[5]; - uint16_t n = kb_config.device_cpi; - dpi_status[4] = '\0'; - dpi_status[3] = '0' + n % 10; - dpi_status[2] = (n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' '; - dpi_status[1] = (n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' '; - dpi_status[0] = n / 10 ? '0' + n / 10 : ' '; - oled_write_P(PSTR("DPI: "), false); + oled_write_P(PSTR("CPI:"), false); if (padding) { - for (uint8_t n = padding; n > 0; n--) { + for (uint8_t n = padding - 1; n > 0; n--) { oled_write_P(PSTR(" "), false); } } - oled_write(dpi_status, false); + + oled_write(get_u16_str(kb_config.device_cpi, ' '), false); } #endif diff --git a/users/drashna/process_records.c b/users/drashna/process_records.c index c16c70c050..de572d8933 100644 --- a/users/drashna/process_records.c +++ b/users/drashna/process_records.c @@ -39,6 +39,9 @@ bool process_record_user(uint16_t keycode, keyrecord_t *re #endif #ifdef RGBLIGHT_ENABLE && process_record_user_rgb_light(keycode, record) +#endif +#ifdef CUSTOM_UNICODE_ENABLE + && process_record_unicode(keycode, record) #endif && true)) { return false; @@ -117,28 +120,6 @@ bool process_record_user(uint16_t keycode, keyrecord_t *re } } break; -#ifdef UNICODE_ENABLE - 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; -#endif case KC_RGB_T: // This allows me to use underglow as layer indication, or as normal #if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE) if (record->event.pressed) { diff --git a/users/drashna/process_records.h b/users/drashna/process_records.h index 897d7bbcc9..d8c198a2d4 100644 --- a/users/drashna/process_records.h +++ b/users/drashna/process_records.h @@ -46,13 +46,25 @@ enum userspace_custom_keycodes { UC_TABL, // ┬─┬ノ( º _ ºノ) UC_SHRG, // ¯\_(ツ)_/¯ UC_DISA, // ಠ_ಠ + UC_IRNY, + UC_CLUE, KEYLOCK, // Locks keyboard by unmounting driver - NEW_SAFE_RANGE // use "NEWPLACEHOLDER for keymap specific codes + KC_NOMODE, + KC_WIDE, + KC_SCRIPT, + KC_BLOCKS, + KC_REGIONAL, + KC_AUSSIE, + KC_ZALGO, + NEW_SAFE_RANGE // use "NEWPLACEHOLDER for keymap specific codes }; bool process_record_secrets(uint16_t keycode, keyrecord_t *record); bool process_record_keymap(uint16_t keycode, keyrecord_t *record); void post_process_record_keymap(uint16_t keycode, keyrecord_t *record); +#ifdef CUSTOM_UNICODE_ENABLE +bool process_record_unicode(uint16_t keycode, keyrecord_t *record); +#endif #define LOWER MO(_LOWER) #define RAISE MO(_RAISE) @@ -125,6 +137,3 @@ void post_process_record_keymap(uint16_t keycode, keyrecord_t *record); #define ALT_APP ALT_T(KC_APP) #define MG_NKRO MAGIC_TOGGLE_NKRO - -#define UC_IRNY UC(0x2E2E) -#define UC_CLUE UC(0x203D) diff --git a/users/drashna/rules.mk b/users/drashna/rules.mk index e9911979c7..bd661e00a5 100644 --- a/users/drashna/rules.mk +++ b/users/drashna/rules.mk @@ -18,8 +18,18 @@ ifneq ($(strip $(NO_SECRETS)), yes) endif endif +CUSTOM_UNICODE_ENABLE ?= yes +ifeq ($(strip $(CUSTOM_UNICODE_ENABLE)), yes) + UNICODE_ENABLE = no + UNICODEMAP_ENABLE = no + UCIS_ENABLE = no + UNICODE_COMMON = yes + OPT_DEFS += -DCUSTOM_UNICODE_ENABLE + SRC += unicoooode.c +endif + CUSTOM_TAP_DANCE ?= yes -ifeq ($(strip $(TAP_DANCE_ENABLE)), yes) +ifeq ($(strip $(CUSTOM_TAP_DANCE)), yes) ifeq ($(strip $(TAP_DANCE_ENABLE)), yes) SRC += $(USER_PATH)/tap_dances.c endif diff --git a/users/drashna/transport_sync.c b/users/drashna/transport_sync.c index daa14bbef7..cee3f04c8f 100644 --- a/users/drashna/transport_sync.c +++ b/users/drashna/transport_sync.c @@ -18,7 +18,8 @@ #include "transactions.h" #include -#ifdef UNICODE_ENABLE +#ifdef CUSTOM_UNICODE_ENABLE +#include "process_unicode_common.h" extern unicode_config_t unicode_config; #endif #ifdef AUDIO_ENABLE diff --git a/users/drashna/unicoooode.c b/users/drashna/unicoooode.c new file mode 100644 index 0000000000..0e276dec17 --- /dev/null +++ b/users/drashna/unicoooode.c @@ -0,0 +1,282 @@ +/* Copyright 2020 @tzarc + * 2021 Christopher Courtney, aka Drashna Jael're (@drashna) + * + * 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 . + */ + +#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 true; +} -- cgit v1.2.3