~ruther/qmk_firmware

94fc32f43135ac4afb14849c7fb5e99f95455078 — Konstantin Đorđević 5 years ago 1f7bbf2
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)
M quantum/process_keycode/process_rgb.c => quantum/process_keycode/process_rgb.c +1 -1
@@ 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();

M quantum/process_keycode/process_unicode_common.c => quantum/process_keycode/process_unicode_common.c +70 -48
@@ 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)

M quantum/process_keycode/process_unicode_common.h => quantum/process_keycode/process_unicode_common.h +1 -1
@@ 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);

M quantum/process_keycode/process_unicodemap.c => quantum/process_keycode/process_unicodemap.c +2 -1
@@ 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;
        }