From 94fc32f43135ac4afb14849c7fb5e99f95455078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20=C4=90or=C4=91evi=C4=87?= Date: Sat, 9 May 2020 10:22:02 +0200 Subject: [PATCH] Fix bug in UC_RMOD, add shift and audio support for UC_MOD/UC_RMOD(#8674) * Invert UC_MOD/UC_RMOD direction when Shift is held Also use MOD_MASK_SHIFT in process_rgb.c * Allow audio to be played for UC_MOD, UC_RMOD keycodes as well * Fix signedness bug in reverse input mode cycling * Misc formatting in process_unicode_common.c * Address clang-format issues * Make decode_utf8 helper function file-local (static) --- quantum/process_keycode/process_rgb.c | 2 +- .../process_keycode/process_unicode_common.c | 118 +++++++++++------- .../process_keycode/process_unicode_common.h | 2 +- quantum/process_keycode/process_unicodemap.c | 3 +- 4 files changed, 74 insertions(+), 51 deletions(-) diff --git a/quantum/process_keycode/process_rgb.c b/quantum/process_keycode/process_rgb.c index 627e5986f..21164b8f9 100644 --- a/quantum/process_keycode/process_rgb.c +++ b/quantum/process_keycode/process_rgb.c @@ -56,7 +56,7 @@ bool process_rgb(const uint16_t keycode, const keyrecord_t *record) { // Split keyboards need to trigger on key-up for edge-case issue if (!record->event.pressed) { #endif - uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)); + uint8_t shifted = get_mods() & MOD_MASK_SHIFT; switch (keycode) { case RGB_TOG: rgblight_toggle(); diff --git a/quantum/process_keycode/process_unicode_common.c b/quantum/process_keycode/process_unicode_common.c index 48ce3961a..fb5021501 100644 --- a/quantum/process_keycode/process_unicode_common.c +++ b/quantum/process_keycode/process_unicode_common.c @@ -24,8 +24,8 @@ uint8_t unicode_saved_mods; #if UNICODE_SELECTED_MODES != -1 static uint8_t selected[] = {UNICODE_SELECTED_MODES}; -static uint8_t selected_count = sizeof selected / sizeof *selected; -static uint8_t selected_index; +static int8_t selected_count = sizeof selected / sizeof *selected; +static int8_t selected_index; #endif void unicode_input_mode_init(void) { @@ -33,7 +33,7 @@ void unicode_input_mode_init(void) { #if UNICODE_SELECTED_MODES != -1 # if UNICODE_CYCLE_PERSIST // Find input_mode in selected modes - uint8_t i; + int8_t i; for (i = 0; i < selected_count; i++) { if (selected[i] == unicode_config.input_mode) { selected_index = i; @@ -60,9 +60,12 @@ void set_unicode_input_mode(uint8_t mode) { dprintf("Unicode input mode set to: %u\n", unicode_config.input_mode); } -void cycle_unicode_input_mode(uint8_t offset) { +void cycle_unicode_input_mode(int8_t offset) { #if UNICODE_SELECTED_MODES != -1 - selected_index = (selected_index + offset) % selected_count; + selected_index = (selected_index + offset) % selected_count; + if (selected_index < 0) { + selected_index += selected_count; + } unicode_config.input_mode = selected[selected_index]; # if UNICODE_CYCLE_PERSIST persist_unicode_input_mode(); @@ -168,6 +171,8 @@ void register_hex32(uint32_t hex) { } } +// clang-format off + void send_unicode_hex_string(const char *str) { if (!str) { return; @@ -175,12 +180,11 @@ void send_unicode_hex_string(const char *str) { while (*str) { // Find the next code point (token) in the string - for (; *str == ' '; str++) - ; + for (; *str == ' '; str++); // Skip leading spaces size_t n = strcspn(str, " "); // Length of the current token - char code_point[n + 1]; - strncpy(code_point, str, n); - code_point[n] = '\0'; // Make sure it's null-terminated + char code_point[n+1]; + strncpy(code_point, str, n); // Copy token into buffer + code_point[n] = '\0'; // Make sure it's null-terminated // Normalize the code point: make all hex digits lowercase for (char *p = code_point; *p; p++) { @@ -196,8 +200,10 @@ void send_unicode_hex_string(const char *str) { } } +// clang-format on + // Borrowed from https://nullprogram.com/blog/2017/10/06/ -const char *decode_utf8(const char *str, int32_t *code_point) { +static const char *decode_utf8(const char *str, int32_t *code_point) { const char *next; if (str[0] < 0x80) { // U+0000-007F @@ -231,7 +237,6 @@ void send_unicode_string(const char *str) { } int32_t code_point = 0; - while (*str) { str = decode_utf8(str, &code_point); @@ -243,53 +248,70 @@ void send_unicode_string(const char *str) { } } +// clang-format off + +static void audio_helper(void) { +#ifdef AUDIO_ENABLE + switch (get_unicode_input_mode()) { +# ifdef UNICODE_SONG_MAC + static float song_mac[][2] = UNICODE_SONG_MAC; + case UC_MAC: + PLAY_SONG(song_mac); + break; +# endif +# ifdef UNICODE_SONG_LNX + static float song_lnx[][2] = UNICODE_SONG_LNX; + case UC_LNX: + PLAY_SONG(song_lnx); + break; +# endif +# ifdef UNICODE_SONG_WIN + static float song_win[][2] = UNICODE_SONG_WIN; + case UC_WIN: + PLAY_SONG(song_win); + break; +# endif +# ifdef UNICODE_SONG_BSD + static float song_bsd[][2] = UNICODE_SONG_BSD; + case UC_BSD: + PLAY_SONG(song_bsd); + break; +# endif +# ifdef UNICODE_SONG_WINC + static float song_winc[][2] = UNICODE_SONG_WINC; + case UC_WINC: + PLAY_SONG(song_winc); + break; +# endif + } +#endif +} + +// clang-format on + bool process_unicode_common(uint16_t keycode, keyrecord_t *record) { if (record->event.pressed) { + bool shifted = get_mods() & MOD_MASK_SHIFT; switch (keycode) { case UNICODE_MODE_FORWARD: - cycle_unicode_input_mode(+1); + cycle_unicode_input_mode(shifted ? -1 : +1); + audio_helper(); break; case UNICODE_MODE_REVERSE: - cycle_unicode_input_mode(-1); + cycle_unicode_input_mode(shifted ? +1 : -1); + audio_helper(); break; - case UNICODE_MODE_MAC: - set_unicode_input_mode(UC_MAC); -#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_MAC) - static float song_mac[][2] = UNICODE_SONG_MAC; - PLAY_SONG(song_mac); -#endif - break; - case UNICODE_MODE_LNX: - set_unicode_input_mode(UC_LNX); -#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_LNX) - static float song_lnx[][2] = UNICODE_SONG_LNX; - PLAY_SONG(song_lnx); -#endif - break; - case UNICODE_MODE_WIN: - set_unicode_input_mode(UC_WIN); -#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_WIN) - static float song_win[][2] = UNICODE_SONG_WIN; - PLAY_SONG(song_win); -#endif - break; - case UNICODE_MODE_BSD: - set_unicode_input_mode(UC_BSD); -#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_BSD) - static float song_bsd[][2] = UNICODE_SONG_BSD; - PLAY_SONG(song_bsd); -#endif - break; - case UNICODE_MODE_WINC: - set_unicode_input_mode(UC_WINC); -#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_WINC) - static float song_winc[][2] = UNICODE_SONG_WINC; - PLAY_SONG(song_winc); -#endif + case UNICODE_MODE_MAC ... UNICODE_MODE_WINC: { + // Keycodes and input modes follow the same ordering + uint8_t delta = keycode - UNICODE_MODE_MAC; + set_unicode_input_mode(UC_MAC + delta); + audio_helper(); break; + } } } + #if defined(UNICODE_ENABLE) return process_unicode(keycode, record); #elif defined(UNICODEMAP_ENABLE) diff --git a/quantum/process_keycode/process_unicode_common.h b/quantum/process_keycode/process_unicode_common.h index 5421c28c7..4579fde8d 100644 --- a/quantum/process_keycode/process_unicode_common.h +++ b/quantum/process_keycode/process_unicode_common.h @@ -80,7 +80,7 @@ extern uint8_t unicode_saved_mods; void unicode_input_mode_init(void); uint8_t get_unicode_input_mode(void); void set_unicode_input_mode(uint8_t mode); -void cycle_unicode_input_mode(uint8_t offset); +void cycle_unicode_input_mode(int8_t offset); void persist_unicode_input_mode(void); void unicode_input_start(void); diff --git a/quantum/process_keycode/process_unicodemap.c b/quantum/process_keycode/process_unicodemap.c index 5445cde12..2f402a2fd 100644 --- a/quantum/process_keycode/process_unicodemap.c +++ b/quantum/process_keycode/process_unicodemap.c @@ -21,7 +21,8 @@ __attribute__((weak)) uint16_t unicodemap_index(uint16_t keycode) { // Keycode is a pair: extract index based on Shift / Caps Lock state uint16_t index = keycode - QK_UNICODEMAP_PAIR; - bool shift = unicode_saved_mods & MOD_MASK_SHIFT, caps = IS_HOST_LED_ON(USB_LED_CAPS_LOCK); + bool shift = unicode_saved_mods & MOD_MASK_SHIFT; + bool caps = IS_HOST_LED_ON(USB_LED_CAPS_LOCK); if (shift ^ caps) { index >>= 7; }