qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

send_string.c (11103B)


      1 /* Copyright 2021
      2  *
      3  * This program is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published by
      5  * the Free Software Foundation, either version 2 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * This program is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     11  * GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     15  */
     16 
     17 #include "send_string.h"
     18 
     19 #include <ctype.h>
     20 #include <stdlib.h>
     21 
     22 #include "quantum_keycodes.h"
     23 #include "keycode.h"
     24 #include "action.h"
     25 #include "wait.h"
     26 
     27 #if defined(AUDIO_ENABLE) && defined(SENDSTRING_BELL)
     28 #    include "audio.h"
     29 #    ifndef BELL_SOUND
     30 #        define BELL_SOUND TERMINAL_SOUND
     31 #    endif
     32 float bell_song[][2] = SONG(BELL_SOUND);
     33 #endif
     34 
     35 // clang-format off
     36 
     37 /* Bit-Packed look-up table to convert an ASCII character to whether
     38  * [Shift] needs to be sent with the keycode.
     39  */
     40 __attribute__((weak)) const uint8_t ascii_to_shift_lut[16] PROGMEM = {
     41     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     42     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     43     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     44     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     45 
     46     KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 0),
     47     KCLUT_ENTRY(1, 1, 1, 1, 0, 0, 0, 0),
     48     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     49     KCLUT_ENTRY(0, 0, 1, 0, 1, 0, 1, 1),
     50     KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
     51     KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
     52     KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
     53     KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1),
     54     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     55     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     56     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     57     KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0)
     58 };
     59 
     60 /* Bit-Packed look-up table to convert an ASCII character to whether
     61  * [AltGr] needs to be sent with the keycode.
     62  */
     63 __attribute__((weak)) const uint8_t ascii_to_altgr_lut[16] PROGMEM = {
     64     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     65     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     66     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     67     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     68 
     69     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     70     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     71     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     72     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     73     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     74     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     75     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     76     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     77     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     78     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     79     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     80     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0)
     81 };
     82 
     83 /* Bit-Packed look-up table to convert an ASCII character to whether
     84  * [Space] needs to be sent after the keycode
     85  */
     86 __attribute__((weak)) const uint8_t ascii_to_dead_lut[16] PROGMEM = {
     87     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     88     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     89     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     90     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     91 
     92     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     93     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     94     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     95     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     96     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     97     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     98     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
     99     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
    100     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
    101     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
    102     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
    103     KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0)
    104 };
    105 
    106 /* Look-up table to convert an ASCII character to a keycode.
    107  */
    108 __attribute__((weak)) const uint8_t ascii_to_keycode_lut[128] PROGMEM = {
    109     // NUL   SOH      STX      ETX      EOT      ENQ      ACK      BEL
    110     XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
    111     // BS    TAB      LF       VT       FF       CR       SO       SI
    112     KC_BSPC, KC_TAB,  KC_ENT,  XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
    113     // DLE   DC1      DC2      DC3      DC4      NAK      SYN      ETB
    114     XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
    115     // CAN   EM       SUB      ESC      FS       GS       RS       US
    116     XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC,  XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
    117 
    118     //       !        "        #        $        %        &        '
    119     KC_SPC,  KC_1,    KC_QUOT, KC_3,    KC_4,    KC_5,    KC_7,    KC_QUOT,
    120     // (     )        *        +        ,        -        .        /
    121     KC_9,    KC_0,    KC_8,    KC_EQL,  KC_COMM, KC_MINS, KC_DOT,  KC_SLSH,
    122     // 0     1        2        3        4        5        6        7
    123     KC_0,    KC_1,    KC_2,    KC_3,    KC_4,    KC_5,    KC_6,    KC_7,
    124     // 8     9        :        ;        <        =        >        ?
    125     KC_8,    KC_9,    KC_SCLN, KC_SCLN, KC_COMM, KC_EQL,  KC_DOT,  KC_SLSH,
    126     // @     A        B        C        D        E        F        G
    127     KC_2,    KC_A,    KC_B,    KC_C,    KC_D,    KC_E,    KC_F,    KC_G,
    128     // H     I        J        K        L        M        N        O
    129     KC_H,    KC_I,    KC_J,    KC_K,    KC_L,    KC_M,    KC_N,    KC_O,
    130     // P     Q        R        S        T        U        V        W
    131     KC_P,    KC_Q,    KC_R,    KC_S,    KC_T,    KC_U,    KC_V,    KC_W,
    132     // X     Y        Z        [        \        ]        ^        _
    133     KC_X,    KC_Y,    KC_Z,    KC_LBRC, KC_BSLS, KC_RBRC, KC_6,    KC_MINS,
    134     // `     a        b        c        d        e        f        g
    135     KC_GRV,  KC_A,    KC_B,    KC_C,    KC_D,    KC_E,    KC_F,    KC_G,
    136     // h     i        j        k        l        m        n        o
    137     KC_H,    KC_I,    KC_J,    KC_K,    KC_L,    KC_M,    KC_N,    KC_O,
    138     // p     q        r        s        t        u        v        w
    139     KC_P,    KC_Q,    KC_R,    KC_S,    KC_T,    KC_U,    KC_V,    KC_W,
    140     // x     y        z        {        |        }        ~        DEL
    141     KC_X,    KC_Y,    KC_Z,    KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV,  KC_DEL
    142 };
    143 
    144 // clang-format on
    145 
    146 // Note: we bit-pack in "reverse" order to optimize loading
    147 #define PGM_LOADBIT(mem, pos) ((pgm_read_byte(&((mem)[(pos) / 8])) >> ((pos) % 8)) & 0x01)
    148 
    149 void send_string(const char *string) {
    150     send_string_with_delay(string, TAP_CODE_DELAY);
    151 }
    152 
    153 void send_string_with_delay_impl(char (*getter)(void *), void *arg, uint8_t interval) {
    154     while (1) {
    155         char ascii_code = getter(arg);
    156         if (!ascii_code) break;
    157         if (ascii_code == SS_QMK_PREFIX) {
    158             ascii_code = getter(arg);
    159 
    160             if (ascii_code == SS_TAP_CODE) {
    161                 // tap
    162                 uint8_t keycode = getter(arg);
    163                 tap_code(keycode);
    164             } else if (ascii_code == SS_DOWN_CODE) {
    165                 // down
    166                 uint8_t keycode = getter(arg);
    167                 register_code(keycode);
    168             } else if (ascii_code == SS_UP_CODE) {
    169                 // up
    170                 uint8_t keycode = getter(arg);
    171                 unregister_code(keycode);
    172             } else if (ascii_code == SS_DELAY_CODE) {
    173                 // delay
    174                 int ms     = 0;
    175                 ascii_code = getter(arg);
    176 
    177                 while (isdigit(ascii_code)) {
    178                     ms *= 10;
    179                     ms += ascii_code - '0';
    180                     ascii_code = getter(arg);
    181                 }
    182 
    183                 wait_ms(ms);
    184             }
    185 
    186             wait_ms(interval);
    187 
    188             // if we had a delay that terminated with a null, we're done
    189             if (ascii_code == 0) break;
    190         } else {
    191             send_char_with_delay(ascii_code, interval);
    192         }
    193     }
    194 }
    195 
    196 typedef struct send_string_memory_state_t {
    197     const char *string;
    198 } send_string_memory_state_t;
    199 
    200 char send_string_get_next_ram(void *arg) {
    201     send_string_memory_state_t *state = (send_string_memory_state_t *)arg;
    202     char                        ret   = *state->string;
    203     state->string++;
    204     return ret;
    205 }
    206 
    207 void send_string_with_delay(const char *string, uint8_t interval) {
    208     send_string_memory_state_t state = {string};
    209     send_string_with_delay_impl(send_string_get_next_ram, &state, interval);
    210 }
    211 
    212 void send_char(char ascii_code) {
    213     send_char_with_delay(ascii_code, TAP_CODE_DELAY);
    214 }
    215 
    216 void send_char_with_delay(char ascii_code, uint8_t interval) {
    217 #if defined(AUDIO_ENABLE) && defined(SENDSTRING_BELL)
    218     if (ascii_code == '\a') { // BEL
    219         PLAY_SONG(bell_song);
    220         return;
    221     }
    222 #endif
    223 
    224     uint8_t keycode    = pgm_read_byte(&ascii_to_keycode_lut[(uint8_t)ascii_code]);
    225     bool    is_shifted = PGM_LOADBIT(ascii_to_shift_lut, (uint8_t)ascii_code);
    226     bool    is_altgred = PGM_LOADBIT(ascii_to_altgr_lut, (uint8_t)ascii_code);
    227     bool    is_dead    = PGM_LOADBIT(ascii_to_dead_lut, (uint8_t)ascii_code);
    228 
    229     if (is_shifted) {
    230         register_code(KC_LEFT_SHIFT);
    231         wait_ms(interval);
    232     }
    233 
    234     if (is_altgred) {
    235         register_code(KC_RIGHT_ALT);
    236         wait_ms(interval);
    237     }
    238 
    239     tap_code_delay(keycode, interval);
    240     wait_ms(interval);
    241 
    242     if (is_altgred) {
    243         unregister_code(KC_RIGHT_ALT);
    244         wait_ms(interval);
    245     }
    246 
    247     if (is_shifted) {
    248         unregister_code(KC_LEFT_SHIFT);
    249         wait_ms(interval);
    250     }
    251 
    252     if (is_dead) {
    253         tap_code(KC_SPACE);
    254         wait_ms(interval);
    255     }
    256 }
    257 
    258 void send_dword(uint32_t number) {
    259     send_word(number >> 16);
    260     send_word(number & 0xFFFFUL);
    261 }
    262 
    263 void send_word(uint16_t number) {
    264     send_byte(number >> 8);
    265     send_byte(number & 0xFF);
    266 }
    267 
    268 void send_byte(uint8_t number) {
    269     send_nibble(number >> 4);
    270     send_nibble(number & 0xF);
    271 }
    272 
    273 void send_nibble(uint8_t number) {
    274     switch (number & 0xF) {
    275         case 0 ... 9:
    276             send_char(number + '0');
    277             break;
    278         case 10 ... 15:
    279             send_char(number - 10 + 'a');
    280             break;
    281     }
    282 }
    283 
    284 #if defined(__AVR_ATmega32U4__)
    285 #    include <avr/io.h>
    286 #endif
    287 
    288 void tap_random_base64(void) {
    289 #if defined(__AVR_ATmega32U4__)
    290     uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64;
    291 #else
    292     uint8_t key = rand() % 64;
    293 #endif
    294     switch (key) {
    295         case 0 ... 25:
    296             send_char(key + 'A');
    297             break;
    298         case 26 ... 51:
    299             send_char(key - 26 + 'a');
    300             break;
    301         case 52:
    302             send_char('0');
    303             break;
    304         case 53 ... 61:
    305             send_char(key - 53 + '1');
    306             break;
    307         case 62:
    308             send_char('+');
    309             break;
    310         case 63:
    311             send_char('/');
    312             break;
    313     }
    314 }
    315 
    316 #if defined(__AVR__)
    317 void send_string_P(const char *string) {
    318     send_string_with_delay_P(string, TAP_CODE_DELAY);
    319 }
    320 
    321 char send_string_get_next_progmem(void *arg) {
    322     send_string_memory_state_t *state = (send_string_memory_state_t *)arg;
    323     char                        ret   = pgm_read_byte(state->string);
    324     state->string++;
    325     return ret;
    326 }
    327 
    328 void send_string_with_delay_P(const char *string, uint8_t interval) {
    329     send_string_memory_state_t state = {string};
    330     send_string_with_delay_impl(send_string_get_next_progmem, &state, interval);
    331 }
    332 #endif