~ruther/qmk_firmware

a9f65b760a49744b13d822ab359876a52779bd9e — rupa 4 years ago 53f1166
userspace and keymap changes for rupa (#10489)

* userspace and keymap changes for rupa

* remove layout wrappers and blocker rows from wrappers

handle this in keymaps for now
14 files changed, 519 insertions(+), 132 deletions(-)

M keyboards/tada68/keymaps/rupa/config.h
M keyboards/tada68/keymaps/rupa/keymap.c
M keyboards/tada68/keymaps/rupa/readme.md
M keyboards/tada68/keymaps/rupa/rules.mk
M users/rupa/config.h
M users/rupa/process_records.c -rwxr-xr-x => -rw-r--r--
M users/rupa/process_records.h -rwxr-xr-x => -rw-r--r--
A users/rupa/readme.md
M users/rupa/rules.mk
M users/rupa/rupa.c -rwxr-xr-x => -rw-r--r--
M users/rupa/rupa.h -rwxr-xr-x => -rw-r--r--
M users/rupa/unicode.c -rwxr-xr-x => -rw-r--r--
M users/rupa/unicode.h -rwxr-xr-x => -rw-r--r--
A users/rupa/wrappers.h
M keyboards/tada68/keymaps/rupa/config.h => keyboards/tada68/keymaps/rupa/config.h +0 -7
@@ 1,10 1,3 @@
#pragma once

#define GRAVE_ESC_ALT_OVERRIDE

/* disable features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
#define NO_ACTION_MACRO
#define NO_ACTION_FUNCTION

M keyboards/tada68/keymaps/rupa/keymap.c => keyboards/tada68/keymaps/rupa/keymap.c +32 -39
@@ 1,45 1,38 @@
#include "rupa.h"

#define LAYOUT_65_ansi_wrapper(...) LAYOUT_65_ansi(__VA_ARGS__)

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    /* Keymap _QWERTY: (Base Layer) Default Layer
     * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───┐
     * │Esc│ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ Backsp│~ `│
     * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
     * │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │  \  │Del│
     * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
     * │  Fn  │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │  Enter │PgU│
     * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
     * │ Shift  │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ Shift│ ↑ │PgD│
     * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴──┬┴──┬┴──┬───┼───┼───┤
     * │Ctrl│Alt │Gui │        Space           │Fn │Alt│Ctl│ ← │ ↓ │ → │
     * └────┴────┴────┴────────────────────────┴───┴───┴───┴───┴───┴───┘
     */
    [_QWERTY] = LAYOUT_65_ansi(
        KC_GESC, KC_1,    KC_2,    KC_3,  KC_4,  KC_5,  KC_6,    KC_7,  KC_8,  KC_9,    KC_0,    KC_MINS, KC_EQL,  KC_BSPC, KC_GRV,
        KC_TAB,  KC_Q,    KC_W,    KC_E,  KC_R,  KC_T,  KC_Y,    KC_U,  KC_I,  KC_O,    KC_P,    KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL,
        RAISE,   KC_A,    KC_S,    KC_D,  KC_F,  KC_G,  KC_H,    KC_J,  KC_K,  KC_L,    KC_SCLN, KC_QUOT,          KC_ENT,  KC_PGUP,
        KC_LSFT,          KC_Z,    KC_X,  KC_C,  KC_V,  KC_B,    KC_N,  KC_M,  KC_COMM, KC_DOT,  KC_SLSH, KC_RSFT, KC_UP,   KC_PGDN,
        KC_LCTL, KC_LALT, KC_LGUI,                      KC_SPC,                RAISE,   KC_RALT, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
    [_QWERTY] = LAYOUT_65_ansi_wrapper(
        ____65_QWERTY______________ROW1,
        ____65_QWERTY______________ROW2,
        ____65_QWERTY______________ROW3,
        ____65_QWERTY______________ROW4,
        ____65_QWERTY______________ROW5
    ),

    /* Keymap _RAISE: Function Layer
     * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───┐
     * │LOD│F1 │F2 │F3 │F4 │F5 │F6 │F7 │F8 │F9 │F10│F11│F12│  Del  │Hme│
     * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
     * │     │VSN│U_s│U_f│U_m│   │   │uni│   │ ॐ │   │♩ ♪│♫ ♬│★  ☆ │Ins│
     * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
     * │      │   │   │   │   │   │   │   │   │   │   │   │    ✓   │End│
     * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
     * │ RShift │ ⸮ │Rup│Brt│Bls│Blt│   │Mut│V- │V+ │‽ ☭│   McL│M↑ │McR│
     * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴──┬┴──┬┴──┬───┼───┼───┤
     * │RCtl│RAlt│RGui│                        │   │   │CAP│M← │M↓ │M→ │
     * └────┴────┴────┴────────────────────────┴───┴───┴───┴───┴───┴───┘
     */
    [_RAISE] = LAYOUT_65_ansi(
        LOD,     KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,       KC_F12,      KC_DEL,       KC_HOME,
        _______, VRSN,    U_SCRPT, U_FRACT, U_MONOS, _______, _______, UC_MOD,  _______, X(OM),   _______, XP(M4,M8),    XP(M8B,M16), XP(STB, STW), KC_INS,
        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,                   X(CHEK),      KC_END,
        OS_RSFT,          X(IRNY), RUPA,    BL_BRTG, BL_STEP, BL_TOGG, _______, KC_MUTE, KC_VOLD, KC_VOLU, XP(IBNG,HAS), KC_BTN1,     KC_MS_U,      KC_BTN2,
        OS_RCTL, OS_RALT, OS_RGUI,                            _______,                   _______, _______, KC_CAPS,      KC_MS_L,     KC_MS_D,      KC_MS_R
    [_RAISE] = LAYOUT_65_ansi_wrapper(
        ____65_RAISE_______________ROW1,
        ____65_RAISE_______________ROW2,
        ____65_RAISE_______________ROW3,
        ____65_RAISE_______________ROW4,
        ____65_RAISE_______________ROW5
    ),
    [_LOWER] = LAYOUT_65_ansi_wrapper(
        ____65_LOWER_______________ROW1,
        ____65_LOWER_______________ROW2,
        ____65_LOWER_______________ROW3,
        ____65_LOWER_______________ROW4,
        ____65_LOWER_______________ROW5
    ),
    [_ADJUST] = LAYOUT_65_ansi_wrapper(
        ____65_ADJUST______________ROW1,
        ____65_ADJUST___________BL_ROW2,
        ____65_ADJUST______________ROW3,
        ____65_ADJUST______________ROW4,
        ____65_ADJUST______________ROW5
    ),
};

layer_state_t layer_state_set_user(layer_state_t state) {
    return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
}

M keyboards/tada68/keymaps/rupa/readme.md => keyboards/tada68/keymaps/rupa/readme.md +3 -5
@@ 2,9 2,7 @@

i've swapped the lufa-ms bootloader for caterina

most everything is in my userspace dir

console mode is on, and there's barely any room left!
most everything is in my [userspace](../../../../users/rupa/)

* win/alt -> alt/cmd
* alt/fn -> fn/alt


@@ 16,6 14,6 @@ fn layer:
  * rotate mute/vol
  * backlight -> breathing, step, toggle
  * swap home and ins
  * unicode chars sprinkled around
  * script mode!
  * unicode chars and strings sprinkled around
  * script modes!
  * (one-shot) right versions of shift/ctl/alt/gui (not working quite right yet)

M keyboards/tada68/keymaps/rupa/rules.mk => keyboards/tada68/keymaps/rupa/rules.mk +0 -1
@@ 1,4 1,3 @@
BOOTLOADER = caterina

UNICODEMAP_ENABLE = yes
CONSOLE_ENABLE = yes

M users/rupa/config.h => users/rupa/config.h +3 -0
@@ 5,4 5,7 @@
#define ONESHOT_TAP_TOGGLE 5
#define ONESHOT_TIMEOUT 5000

#undef TAP_CODE_DELAY
#define TAP_CODE_DELAY 5 //DEFAULT: 100

//#define UNICODE_SCRIPT_MODE_ENABLE

M users/rupa/process_records.c => users/rupa/process_records.c +82 -36
@@ 17,7 17,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.

#include "rupa.h"

font_t *translator = NULL;
uint16_t processed_keycode;

__attribute__((weak))
bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {


@@ 25,47 25,93 @@ bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
}

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    bool is_shifted = get_mods()&MOD_MASK_SHIFT;
    bool is_pressed = record->event.pressed;
    if (record->event.pressed) {

    switch(keycode) {
        case VRSN:
            if (is_pressed) {
        processed_keycode = keycode;
        // mask out mod taps
        if (
            (keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) ||
            (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)
        ) {
            processed_keycode &= 0xFF;
        }

        bool is_shifted = (get_mods() | get_oneshot_mods() | get_weak_mods()) & MOD_MASK_SHIFT;
        switch(processed_keycode) {
            case VRSN:
                send_string_with_delay_P(PSTR(
                  "# " QMK_KEYBOARD "/" QMK_KEYMAP ":" QMK_VERSION " " QMK_BUILDDATE "\n"
                    "# " QMK_KEYBOARD "/" QMK_KEYMAP ":" QMK_VERSION " " QMK_BUILDDATE "\n"
                ), TAP_CODE_DELAY);
            }
            return false;
                return false;

        case LOD:
        case RUPA:
            if (is_pressed) {
                if (keycode == LOD) {
                    send_unicode_string((is_shifted ? "¯\\_(ツ)_/¯" : "ಠ_ಠ"));
                } else if (keycode == RUPA) {
                    send_unicode_string((is_shifted ? "Śrīrūpa" : "rūpa"));
                }
            }
            return false;
            case BUGS:
                return u_xp(is_shifted, "ᙙᙖ", "ଳ");
            case CATS:
                return u_xp(is_shifted, "ⓛ ᆽ ⓛ ", "ㅇㅅㅇ");
            case DANCE:
                return u_x(dance(is_shifted));
            case DICE:
                return u_x(d6());
            case DOMO:
                return u_xp(is_shifted, "(シ_ _)シ", "m(_ _)m");
            case FART:
                return u_x("⊥ʶ∀Ⅎ");
            case FLIP:
                return u_x(flip(is_shifted));
            case HUGS:
                return u_xp(is_shifted, "(づ ̄ ³ ̄)づ", "(っಠ‿ಠ)っ");
            case JOY:
                return u_x(joy(is_shifted));
            case RNDM:
                return false;
            case KISS:
                return u_xp(is_shifted, "꒒ ০ ⌵ ୧ ♡", "( ˘ ³˘)♥");
            case LOD:
                return u_xp(is_shifted, "( ͡ಠ ʖ̯ ͡ಠ)", "ಠ_ಠ");
            case MUSIC:
                return u_xp(is_shifted, "(˳˘ ɜ˘)˳ ♬ ♪♫", "(´▽`)ノ♫");
            case RUPA:
                return u_xp(is_shifted, "Śrīrūpa", "rūpa");
            case SHRUG:
                return u_xp(is_shifted, "⋌ ༼ •̀ ⌂ •́ ༽⋋", "¯\\_(ツ)_/¯");
            case TADA:
                return u_xp(is_shifted, "☆ *・゜゚・*(^O^)/*・゜゚・*☆", "\\(゜ロ\\)Ξ(//ロ゜)//");
            case WAT:
                return u_xp(is_shifted, "༼  ຶཽཀ  ຶཽ༽", "ヽ༼⊙_⊙༽ノ");
            case YUNO:
                return u_xp(is_shifted, "o(^^o)", "щ(゜ロ゜щ)");
            case ZALGO:
                set_combined_mode(CM_ZALGO);
                break;
            case ZZZZZ:
                cycle_combined_mode();
                break;

        // script modes
        case U_FRACT:
        case U_MONOS:
        case U_SCRPT:
            if (is_pressed) {
                if (keycode == U_SCRPT) {
                    translator = (translator == &script_bold ? NULL : &script_bold);
                } else if (keycode == U_FRACT) {
                    translator = (translator == &fraktu_bold ? NULL : &fraktu_bold);
                } else if (keycode == U_MONOS) {
                    translator = (translator == &monosp_bold ? NULL : &monosp_bold);
                }
            }
            return true;
#if defined(UNICODE_SCRIPT_MODE_ENABLE)
            // script modes
            case U_FRACT:
                return set_script_mode(F_FRACT);
            case U_ITALI:
                return set_script_mode(F_ITALI);
            case U_MONOS:
                return set_script_mode(F_MONOS);
            case U_NORML:
                return set_script_mode(F_NORML);
            case U_SANSI:
                return set_script_mode(F_SANSI);
            case U_SANSN:
                return set_script_mode(F_SANSN);
            case U_SCRPT:
                return set_script_mode(F_SCRPT);

        default:
            if (is_pressed && translator != NULL) {
                return script_mode_translate(translator, is_shifted, keycode);
            default:
                if (get_script_mode() != NULL) {
                    return script_mode_translate(is_shifted, processed_keycode);
                }
                if (combined_mode != CM_NULL && combined_text(processed_keycode)) {
                    return false;
                }
#endif
            }
    }
    return process_record_keymap(keycode, record);

M users/rupa/process_records.h => users/rupa/process_records.h +0 -0
A users/rupa/readme.md => users/rupa/readme.md +7 -0
@@ 0,0 1,7 @@
# rupa's userspace

* rupa.c has some unicode script mode stuff
* unicode.c has my unicode map
* process_record.c has my keycode handler

my keymap is in [keyboards/tada68](../../keyboards/tada68/keymaps/rupa/)

M users/rupa/rules.mk => users/rupa/rules.mk +2 -0
@@ 1,3 1,5 @@
UNICODEMAP_ENABLE = yes
LTO_ENABLE = yes
SRC += rupa.c \
       process_records.c \
       unicode.c

M users/rupa/rupa.c => users/rupa/rupa.c +38 -5
@@ 18,14 18,46 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
#include <print.h>
#include "rupa.h"

#if defined(UNICODE_SCRIPT_MODE_ENABLE)
const font_t * translator = NULL;

// https://en.wikipedia.org/wiki/Mathematical_Alphanumeric_Symbols
font_t script_bold = {0x1D4D0, 0x1D4EA, 0x1D7CE}; // with bold numbers
font_t fraktu_bold = {0x1D56C, 0x1D586, 0x1D7D8}; // with doublestruck numbers
font_t monosp_bold = {0x1D670, 0x1D68A, 0x1D7F6};
static const font_t *fonts_map[] = {
    [F_FRACT] = &(font_t){0x1D56C, 0x1D586, 0x1D7D8}, // fraktur/doublestruck numbers
    [F_ITALI] = &(font_t){0x1D468, 0x1D482, 0x1D7CE}, // italic/bold numbers
    [F_MONOS] = &(font_t){0x1D670, 0x1D68A, 0x1D7F6}, // monospace
    [F_NORML] = &(font_t){0x1D400, 0x1D41A, 0x00030}, // normal!
    [F_SANSI] = &(font_t){0x1D63C, 0x1D656, 0x1D7EC}, // sans 1talic/sans bold numbers
    [F_SANSN] = &(font_t){0x1D5D4, 0x1D5EE, 0x1D7E2}, // sans normal/sans numbers
    [F_SCRPT] = &(font_t){0x1D4D0, 0x1D4EA, 0x1D7CE}, // script/bold numbers
};

/*
font_t doublestruc = {0x1D538, 0x1D552, 0x1D7D8};
uint_32 []snowflakes = {
  // doublestruck
  0x1D53B, // C
  0x1D540, // H
  0x1D546, // N
  0x1D548, // P
  0x1D549, // Q
  0x1D54A, // R
  0x1D552, // Z
};
*/

const font_t *get_script_mode(void) {
    return translator;
}
bool set_script_mode(int fc) {
    translator = translator == fonts_map[fc] ? NULL : fonts_map[fc];
    dprintf("set_script_mode: %u %b\n", fc, translator != NULL);
    return true;
}

// Maps A-Z, a-z, and 0-9 to other unicode ranges. We also map space to EN
// SPACE for some reason :)
uint32_t map_alnum(font_t *f, bool is_shifted, uint32_t keycode) {
uint32_t map_alnum(const font_t *f, bool is_shifted, uint32_t keycode) {
    switch (keycode) {
        case KC_SPACE:
            return (is_shifted ? 0 : 0x2002); // EN SPACE


@@ 40,10 72,11 @@ uint32_t map_alnum(font_t *f, bool is_shifted, uint32_t keycode) {
    }
}

bool script_mode_translate(font_t *translator, bool is_shifted, uint32_t keycode) {
bool script_mode_translate(bool is_shifted, uint32_t keycode) {
    uint32_t translated = map_alnum(translator, is_shifted, keycode);
    if (translated == 0) return true;
    dprintf("script_mode_translate: %u => %d\n", keycode, translated);
    register_unicode(translated);
    return false;
}
#endif

M users/rupa/rupa.h => users/rupa/rupa.h +39 -11
@@ 20,19 20,55 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
#include "version.h"
#include "process_records.h"
#include "unicode.h"
#include "wrappers.h"

enum userspace_layers {
    _QWERTY = 0,
    _LOWER,
    _RAISE,
    _ADJUST
};

enum userspace_custom_keycodes {
    VRSN = SAFE_RANGE,
    BUGS,
    CATS,
    DANCE,
    DICE,
    DOMO,
    FART,
    FLIP,
    HUGS,
    JOY,
    KISS,
    LOD,
    MUSIC,
    RNDM,
    RUPA,
    SHRUG,
    TADA,
    U_FRACT,
    U_ITALI,
    U_MONOS,
    U_NORML,
    U_SANSI,
    U_SANSN,
    U_SCRPT,
    WAT,
    YUNO,
    ZALGO,
    ZZZZZ,
    NEXT_SAFE_RANGE
};

enum userspace_font_choices {
    F_FRACT = 0,
    F_ITALI,
    F_MONOS,
    F_NORML,
    F_SANSI,
    F_SANSN,
    F_SCRPT
};

typedef struct font_t {


@@ 41,14 77,6 @@ typedef struct font_t {
    uint32_t zero_glyph;
} font_t;

font_t fraktu_bold;
font_t monosp_bold;
font_t script_bold;

bool script_mode_translate(font_t *translator, bool is_shifted, uint32_t keycode);

#define RAISE   MO(_RAISE)
#define OS_RGUI OSM(MOD_RGUI)
#define OS_RALT OSM(MOD_RALT)
#define OS_RCTL OSM(MOD_RCTL)
#define OS_RSFT OSM(MOD_RSFT)
const font_t* get_script_mode(void);
bool set_script_mode(int fc);
bool script_mode_translate(bool is_shifted, uint32_t keycode);

M users/rupa/unicode.c => users/rupa/unicode.c +148 -19
@@ 17,26 17,155 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.

#include "unicode.h"

combined_mode_t combined_mode = CM_NULL;
bool _seeded = false;

#if defined(UNICODEMAP_ENABLE)
const uint32_t PROGMEM unicode_map[] = {
    [CHEK] = 0x2713, // ✓
    /*
    [DI1]  = 0x2680, // ⚀
    [DI2]  = 0x2681, // ⚁
    [DI3]  = 0x2682, // ⚂
    [DI4]  = 0x2683, // ⚃
    [DI5]  = 0x2684, // ⚄
    [DI6]  = 0x2685, // ⚅
    */
    [HAS]  = 0x262D, // ☭
    [IBNG] = 0x203D, // ‽
    [IRNY] = 0x2E2E, // ⸮
    [M4]   = 0x2669, // ♩
    [M8]   = 0x266A, // ♪
    [M8B]  = 0x266B, // ♫
    [M16]  = 0x266C, // ♬
    [OM]   = 0x0950, // ॐ
    [STB]  = 0x2605, // ★
    [STW]  = 0x2606, // ☆
    [CCIR] = 0x20DD,  // COMBINING CIRCLE  ⃝
    [CENT] = 0x00A2,  // ¢
    [CHEK] = 0x2713,  // ✓
    [CKEY] = 0x20E3,  // COMBINING KEYCAP  ⃣
    [CUI]  = 0x26A0,  // ⚠
    [ECKS] = 0x2716,  // ✖
    [EFF]  = 0x017F,  // ſ
    [HAS]  = 0x262D,  // ☭
    [HUN]  = 0x1F4AF, // 💯
    [IBNG] = 0x203D,  // ‽
    [IRNY] = 0x2E2E,  // ⸮
    [LALL] = 0x2200,  // ∀
    [LELM] = 0x2208,  // ∈
    [LEXI] = 0x2203,  // ∃
    [LPRO] = 0x22A2,  // ⊢
    [M4]   = 0x2669,  // ♩
    [M8]   = 0x266A,  // ♪
    [M8B]  = 0x266B,  // ♫
    [M16]  = 0x266C,  // ♬
    [NEG]  = 0x20E0,  // COMBINING NO  ⃠
    [NOPE] = 0x1F6AB, // 🚫
    [NUM]  = 0x2116,  // №
    [OM]   = 0x0950,  // ॐ
    [SMB]  = 0x263A,  // ☻
    [SMW]  = 0x263B,  // ☺
    [STB]  = 0x2605,  // ★
    [STOP] = 0x26D4,  // ⛔
    [STW]  = 0x2606,  // ☆
};
#endif

const char *d6_map[] = {
    "⚀", "⚁", "⚂", "⚃", "⚄", "⚅"
};
const char *dance_map[] = {
    "〜( ̄▽ ̄〜)",
    "(〜 ̄▽ ̄)〜"
};
const char *dance_more_map[] = {
    "ƪ(˘⌣˘)┐",
    "┌(˘⌣˘)ʃ"
};
const char *flip_map[] = {
    "(╯°□°)╯︵ ┻━━┻",
    "(ノ-_-)ノ・・ ┻━━┻",
    "(ノꐦ⊙曲ఠ)ノ彡┻━┻"
};
const char *flip_back_map[] = {
    "┬──┬◡ノ(° -°ノ)",
    "┬──┬ノ( ゜-゜ノ)",
    "┬──┬ノ(ಠ_ಠノ)"
};
const char *joy_map[] = {
    "ᕕ( ᐛ )ᕗ ",
    "٩(ˊᗜˋ*)و",
    "٩( ᐛ )و"
};
const char *joy_harder_map[] = {
    "\\\ ٩( ᐛ )و //",
    "✧*。٩(ˊᗜˋ*)و✧*。"
};

const char *choice(const char *choices[], int size) {
    if (_seeded == false) {
        srand(timer_read32());
        dprintf("_seeded the roll\n");
        _seeded = true;
    }
    return choices[rand() % size];
}

const char *d6(void) {
    return choice(d6_map, 6);
}
const char *dance(bool more) {
    if (more) {
        return choice(dance_more_map, 2);
    }
    return choice(dance_map, 2);
}
const char *flip(bool flip_back) {
    if (flip_back) {
        return choice(flip_back_map, 3);
    }
    return choice(flip_map, 3);
}
const char *joy(bool harder) {
    if (harder) {
        return choice(joy_harder_map, 2);
    }
    return choice(joy_map, 3);
}

bool u_x(const char *text) {
    send_unicode_string(text);
    return false;
};
bool u_xp(bool is_shifted, const char *shifted, const char *plain) {
    send_unicode_string(is_shifted ? shifted : plain);
    return false;
};

void zalgo(void) {
    int number = (rand() % (8 + 1 - 2)) + 2;
    unsigned int index;
    for (index=0; index<number; index++) {
        uint16_t hex = (rand() % (0x036F + 1 - 0x0300)) + 0x0300;
        register_hex(hex);
    }
}

bool combined_text(uint16_t keycode) {
    if (keycode < KC_A || (keycode > KC_0 && keycode < KC_MINUS) || keycode > KC_SLASH) {
        return false;
    }
    tap_code(keycode);
    unicode_input_start();
    switch (combined_mode) {
        case CM_CIRCLE:
          register_hex(0x20DD);
          break;
        case CM_NO:
          register_hex(0x20E0);
          break;
        case CM_KEYCAP:
          register_hex(0x20E3);
          break;
        case CM_ZALGO:
          zalgo();
          break;
        default:
          break;
    }
    unicode_input_finish();
    return true;
}

void cycle_combined_mode(void) {
    if (combined_mode++ >= CM_MAX - 1) {
        combined_mode = CM_NULL;
    }
}

combined_mode_t set_combined_mode(combined_mode_t mode) {
    combined_mode = combined_mode == mode ? CM_NULL : mode;
    return combined_mode;
}

M users/rupa/unicode.h => users/rupa/unicode.h +43 -9
@@ 20,24 20,58 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.

#if defined(UNICODEMAP_ENABLE)
enum unicode_names {
    CHEK,
    /*
    DI1, // ⚀
    DI2, // ⚁
    DI3, // ⚂
    DI4, // ⚃
    DI5, // ⚄
    DI6, // ⚅
    */
    CCIR, // COMBINING  ⃝
    CENT, // ¢
    CHEK, // ✓
    CKEY, // COMBINING  ⃣
    CUI,  // ⚠
    ECKS, // ✖
    EFF,  // ſ
    HAS,  // ☭
    HUN,  // 💯
    IBNG, // ‽
    IRNY, // ⸮
    LALL, // ∀
    LELM, // ∈
    LEXI, // ∃
    LPRO, // ⊢
    M4,   // ♩
    M8,   // ♪
    M8B,  // ♫
    M16,  // ♬
    NEG,  // COMBINING  ⃠
    NOPE, // 🚫
    NUM,  // №
    OM,   // ॐ
    SMB,  // ☻
    SMW,  // ☺
    STB,  // ★
    STOP, // ⛔
    STW,  // ☆
};
#endif

typedef enum combined_modes {
    CM_NULL = 0,
    CM_CIRCLE,
    CM_NO,
    CM_KEYCAP,
    CM_ZALGO,
    CM_MAX
} combined_mode_t;

combined_mode_t combined_mode;

// random choices
const char * d6(void);
const char * dance(bool more);
const char * flip(bool back);
const char * joy(bool harder);

// like X and XP
bool u_x(const char *text);
bool u_xp(bool is_shifted, const char * shifted, const char *plain);

bool combined_text(uint16_t keycode);
void cycle_combined_mode(void);
combined_mode_t set_combined_mode(combined_mode_t mode);

A users/rupa/wrappers.h => users/rupa/wrappers.h +122 -0
@@ 0,0 1,122 @@
/*
Copyright 2020 rupa <rupa@lrrr.us> @rupa

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/>.
*/

#pragma once
#include "rupa.h"

#define LOWER   MO(_LOWER)
#define RAISE   MO(_RAISE)
#define OS_RGUI OSM(MOD_RGUI)
#define OS_RALT OSM(MOD_RALT)
#define OS_RCTL OSM(MOD_RCTL)
#define OS_RSFT OSM(MOD_RSFT)

#define G_LWR   LT(_LOWER, KC_G)

#if defined(UNICODEMAP_ENABLE)
#    define CSHAPES XP(CCIR,CKEY)
#    define CUIDADO XP(CUI,HAS)
#    define NOPENAH XP(NOPE,STOP)
#    define MUSIC_A XP(M4,M8)
#    define MUSIC_B XP(M8B,M16)
#    define SMILE   XP(SMB,SMW)
#    define STARS   XP(STB,STW)
#    define YEPYEP  XP(CHEK,HUN)
#endif

/* _QWERTY
 * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───┐
 * │Es~│ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ Backsp│~ `│
 * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
 * │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │  \  │Del│
 * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
 * │RAISE │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │  Enter │PgU│
 * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
 * │ Shift  │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ Shift│ ↑ │PgD│
 * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴──┬┴──┬┴──┬───┼───┼───┤
 * │Ctrl│Alt │Gui │        Space           │RAI│LOW│CAP│ ← │ ↓ │ → │
 * └────┴────┴────┴────────────────────────┴───┴───┴───┴───┴───┴───┘
 */
#define ____65_QWERTY______________ROW1    KC_GESC, KC_1,    KC_2,    KC_3,    KC_4,    KC_5,    KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_MINS, KC_EQL,  KC_BSPC, KC_GRV
#define ____65_QWERTY______________ROW2    KC_TAB,  KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,    KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL
#define ____65_QWERTY______________ROW3    RAISE,   KC_A,    KC_S,    KC_D,    KC_F,    G_LWR,   KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT,          KC_ENT,  KC_PGUP
#define ____65_QWERTY______________ROW4    KC_LSFT,          KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_RSFT, KC_UP,   KC_PGDN
#define ____65_QWERTY______________ROW5    KC_LCTL, KC_LALT, KC_LGUI,                            KC_SPC,                    RAISE,   LOWER,   KC_CAPS, KC_LEFT, KC_DOWN, KC_RGHT

/* _RAISE
 * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───┐
 * │ ` │ ‽ │ ⸮ │   │ ¢ │   │   │   │★  │   │ ☻ │  ⃠ │CSH│  Del  │Hme│
 * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
 * │     │   │WAT│ ∃ │Rup│TAD│YUN│   │ ∈ │ ॐ │   │♩ ♪│♫ ♬│     │Ins│
 * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
 * │      │ ∀ │ ſ │ ⚂ │FRT│   │HUG│JOY│KSS│LOD│   │NO!│ ✓  💯  │End│
 * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
 * │ RShift │⚠ ☭│ ✖ │CAT│BOW│BUG│ № │MUS│DNC│ ⊢ │SHR│   McL│M↑ │McR│
 * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴──┬┴──┬┴──┬───┼───┼───┤
 * │RCtl│RAlt│RGui│          FLIP          │   │   │   │M← │M↓ │M→ │
 * └────┴────┴────┴────────────────────────┴───┴───┴───┴───┴───┴───┘
 */
#define ____65_RAISE_______________ROW1    KC_GRV,  X(IBNG), X(IRNY), _______, X(CENT), _______, _______, _______, STARS,   _______, SMILE,   X(NEG),  CSHAPES, KC_DEL,  KC_HOME
#define ____65_RAISE_______________ROW2    _______, _______, WAT,     X(LEXI), RUPA,    TADA,    YUNO,    _______, X(LELM), X(OM),   _______, MUSIC_A, MUSIC_B, _______, KC_INS
#define ____65_RAISE_______________ROW3    _______, X(LALL), X(EFF),  DICE,    FART,    _______, HUGS,    JOY,     KISS,    LOD,     _______, NOPENAH,          YEPYEP,  KC_END
#define ____65_RAISE_______________ROW4    OS_RSFT,          CUIDADO, X(ECKS), CATS,    DOMO,    BUGS,    X(NUM),  MUSIC,   DANCE,   X(LPRO), SHRUG,   KC_BTN1, KC_MS_U, KC_BTN2
#define ____65_RAISE_______________ROW5    OS_RCTL, OS_RALT, OS_RGUI,                            FLIP,                      _______, _______, _______, KC_MS_L, KC_MS_D, KC_MS_R

/* _LOWER
 * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───┐
 * │   │   │   │   │   │   │   │   │   │   │   │   │zzz│       │   │
 * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
 * │     │u_f│u_i│u_m│u_n│usi│usn│u_s│   │   │PRT│   │   │     │   │
 * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
 * │      │   │SLK│PAU│   │   │   │   │   │   │   │   │        │   │
 * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
 * │        │ZAL│   │CAP│VSN│   │NLK│   │   │   │   │      │   │   │
 * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴──┬┴──┬┴──┬───┼───┼───┤
 * │    │    │    │                        │   │   │   │ ← │ ↓ │ → │
 * └────┴────┴────┴────────────────────────┴───┴───┴───┴───┴───┴───┘
 */
#define ____65_LOWER_______________ROW1    _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, ZZZZZ,   _______, _______
#define ____65_LOWER_______________ROW2    _______, U_FRACT, U_ITALI, U_MONOS, U_NORML, U_SANSI, U_SANSN, U_SCRPT, _______, _______, KC_PSCR, _______, _______, _______, _______
#define ____65_LOWER_______________ROW3    _______, _______, KC_SLCK, KC_PAUS, _______, _______, _______, _______, _______, _______, _______, _______,          _______, _______
#define ____65_LOWER_______________ROW4    _______,          ZALGO  , _______, KC_CAPS, VRSN,    _______, KC_NLCK, _______, _______, _______, _______, _______, _______, _______
#define ____65_LOWER_______________ROW5    _______, _______, _______,                            _______,                   _______, _______, _______, _______, _______, _______

/* _ADJUST
 * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───┐
 * │   │F1 │F2 │F3 │F4 │F5 │F6 │F7 │F8 │F9 │F10│F11│F12│       │   │
 * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
 * │     │r x│r m│rh+│rh-│rs+│rs-│rv+│rv-│ra+│ra-│   │   │RESET│   │
 * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
 * │      │   │   │   │   │   │   │   │   │   │   │   │EEP RSET│   │
 * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
 * │        │   │   │   │   │   │   │Mut│V- │V+ │   │U MODE│   │   │
 * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴──┬┴──┬┴──┬───┼───┼───┤
 * │    │    │    │                        │   │   │   │   │   │   │
 * └────┴────┴────┴────────────────────────┴───┴───┴───┴───┴───┴───┘
 */
#define ____65_ADJUST______________ROW1    _______, KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,  _______, _______
#define ____65_ADJUST______________ROW2    _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET,   _______
#define ____65_ADJUST______________ROW3    _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          EEP_RST, _______
#define ____65_ADJUST______________ROW4    _______,          _______, _______, _______, _______, _______, _______, KC_MUTE, KC_VOLD, KC_VOLU, _______, UC_MOD,  _______, _______
#define ____65_ADJUST______________ROW5    _______, _______, _______,                            _______,                   _______, _______, _______, _______, _______, _______

#define ____65_ADJUST__________RGB_ROW2    _______, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, RGB_SPI, RGB_SPD, _______, _______, RESET,   _______
#define ____65_ADJUST__________RGB_ROW3    _______, RGB_M_P, RGB_M_B, _______, _______, _______, _______, _______, _______, _______, _______, _______,          EEP_RST, _______

#define ____65_ADJUST___________BL_ROW2    _______, BL_TOGG, BL_BRTG, BL_STEP, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET,   _______

// clang-format on