Merge remote-tracking branch 'origin/develop' into xap

This commit is contained in:
QMK Bot 2022-07-02 12:10:26 +00:00
commit 2196d7cb9c
16 changed files with 1566 additions and 623 deletions

View file

@ -15,7 +15,6 @@
QUANTUM_SRC += \
$(QUANTUM_DIR)/quantum.c \
$(QUANTUM_DIR)/send_string.c \
$(QUANTUM_DIR)/bitwise.c \
$(QUANTUM_DIR)/led.c \
$(QUANTUM_DIR)/action.c \
@ -778,6 +777,13 @@ ifeq ($(strip $(MAGIC_ENABLE)), yes)
OPT_DEFS += -DMAGIC_KEYCODE_ENABLE
endif
SEND_STRING_ENABLE ?= yes
ifeq ($(strip $(SEND_STRING_ENABLE)), yes)
OPT_DEFS += -DSEND_STRING_ENABLE
COMMON_VPATH += $(QUANTUM_DIR)/send_string
SRC += $(QUANTUM_DIR)/send_string/send_string.c
endif
ifeq ($(strip $(AUTO_SHIFT_ENABLE)), yes)
SRC += $(QUANTUM_DIR)/process_keycode/process_auto_shift.c
OPT_DEFS += -DAUTO_SHIFT_ENABLE

View file

@ -84,6 +84,7 @@
* [One Shot Keys](one_shot_keys.md)
* [Pointing Device](feature_pointing_device.md)
* [Raw HID](feature_rawhid.md)
* [Send String](feature_send_string.md)
* [Sequencer](feature_sequencer.md)
* [Swap Hands](feature_swap_hands.md)
* [Tap Dance](feature_tap_dance.md)

View file

@ -106,6 +106,8 @@ Only basic keycodes (prefixed by `KC_`) are supported. Do not include the `KC_`
### `SEND_STRING()` & `process_record_user`
See also: [Send String](feature_send_string.md)
Sometimes you want a key to type out words or phrases. For the most common situations, we've provided `SEND_STRING()`, which will type out a string (i.e. a sequence of characters) for you. All ASCII characters that are easily translatable to a keycode are supported (e.g. `qmk 123\n\t`).
Here is an example `keymap.c` for a two-key keyboard:

224
docs/feature_send_string.md Normal file
View file

@ -0,0 +1,224 @@
# Send String
The Send String API is part of QMK's macro system. It allows for sequences of keystrokes to be sent automatically.
The full ASCII character set is supported, along with all of the keycodes in the Basic Keycode range (as these are the only ones that will actually be sent to the host).
?> Unicode characters are **not** supported with this API -- see the [Unicode](feature_unicode.md) feature instead.
## Usage
Send String is enabled by default, so there is usually no need for any special setup. However, if it is disabled, add the following to your `rules.mk`:
```make
SEND_STRING_ENABLE = yes
```
## Basic Configuration
Add the following to your `config.h`:
|Define |Default |Description |
|-----------------|----------------|------------------------------------------------------------------------------------------------------------|
|`SENDSTRING_BELL`|*Not defined* |If the [Audio](feature_audio.md) feature is enabled, the `\a` character (ASCII `BEL`) will beep the speaker.|
|`BELL_SOUND` |`TERMINAL_SOUND`|The song to play when the `\a` character is encountered. By default, this is an eighth note of C5. |
## Keycodes
The Send String functions accept C string literals, but specific keycodes can be injected with the below macros. All of the keycodes in the [Basic Keycode range](keycodes_basic.md) are supported (as these are the only ones that will actually be sent to the host), but with an `X_` prefix instead of `KC_`.
|Macro |Description |
|--------------|-------------------------------------------------------------------|
|`SS_TAP(x)` |Send a keydown, then keyup, event for the given Send String keycode|
|`SS_DOWN(x)` |Send a keydown event for the given Send String keycode |
|`SS_UP(x)` |Send a keyup event for the given Send String keycode |
|`SS_DELAY(ms)`|Wait for `ms` milliseconds |
The following characters are also mapped to their respective keycodes for convenience:
|Character|Hex |ASCII|Keycode |
|---------|------|-----|--------------|
|`\b` |`\x08`|`BS` |`KC_BACKSPACE`|
|`\e` |`\x09`|`ESC`|`KC_ESCAPE` |
|`\n` |`\x0A`|`LF` |`KC_ENTER` |
|`\t` |`\x1B`|`TAB`|`KC_TAB` |
| |`\x7F`|`DEL`|`KC_DELETE` |
### Language Support
By default, Send String assumes your OS keyboard layout is set to US ANSI. If you are using a different keyboard layout, you can [override the lookup tables used to convert ASCII characters to keystrokes](reference_keymap_extras.md#sendstring-support).
## Examples
### Hello World
A simple custom keycode which types out "Hello, world!" and the Enter key when pressed.
Add the following to your `keymap.c`:
```c
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case SS_HELLO:
if (record->event.pressed) {
SEND_STRING("Hello, world!\n");
}
return false;
}
return true;
}
```
### Keycode Injection
This example types out opening and closing curly braces, then taps the left arrow key to move the cursor between the two.
```c
SEND_STRING("{}" SS_TAP(X_LEFT));
```
This example types Ctrl+A, then Ctrl+C, without releasing Ctrl.
```c
SEND_STRING(SS_LCTL("ac"));
```
## API
### `void send_string(const char *string)`
Type out a string of ASCII characters.
This function simply calls `send_string_with_delay(string, 0)`.
#### Arguments
- `const char *string`
The string to type out.
---
### `void send_string_with_delay(const char *string, uint8_t interval)`
Type out a string of ASCII characters, with a delay between each character.
#### Arguments
- `const char *string`
The string to type out.
- `uint8_t interval`
The amount of time, in milliseconds, to wait before typing the next character.
---
### `void send_string_P(const char *string)`
Type out a PROGMEM string of ASCII characters.
On ARM devices, this function is simply an alias for `send_string_with_delay(string, 0)`.
#### Arguments
- `const char *string`
The string to type out.
---
### `void send_string_with_delay_P(const char *string, uint8_t interval)`
Type out a PROGMEM string of ASCII characters, with a delay between each character.
On ARM devices, this function is simply an alias for `send_string_with_delay(string, interval)`.
#### Arguments
- `const char *string`
The string to type out.
- `uint8_t interval`
The amount of time, in milliseconds, to wait before typing the next character.
---
### `void send_char(char ascii_code)`
Type out an ASCII character.
#### Arguments
- `char ascii_code`
The character to type.
---
### `void send_dword(uint32_t number)`
Type out an eight digit (unsigned 32-bit) hexadecimal value.
The format is `[0-9a-f]{8}`, eg. `00000000` through `ffffffff`.
#### Arguments
- `uint32_t number`
The value to type, from 0 to 4,294,967,295.
---
### `void send_word(uint16_t number)`
Type out a four digit (unsigned 16-bit) hexadecimal value.
The format is `[0-9a-f]{4}`, eg. `0000` through `ffff`.
#### Arguments
- `uint16_t number`
The value to type, from 0 to 65,535.
---
### `void send_byte(uint8_t number)`
Type out a two digit (8-bit) hexadecimal value.
The format is `[0-9a-f]{2}`, eg. `00` through `ff`.
#### Arguments
- `uint8_t number`
The value to type, from 0 to 255.
---
### `void send_nibble(uint8_t number)`
Type out a single hexadecimal digit.
The format is `[0-9a-f]{1}`, eg. `0` through `f`.
#### Arguments
- `uint8_t number`
The value to type, from 0 to 15.
---
### `void tap_random_base64(void)`
Type a pseudorandom character from the set `A-Z`, `a-z`, `0-9`, `+` and `/`.
---
### `SEND_STRING(string)`
Shortcut macro for `send_string_with_delay_P(PSTR(string), 0)`.
On ARM devices, this define evaluates to `send_string_with_delay(string, 0)`.
---
### `SEND_STRING_DELAY(string, interval)`
Shortcut macro for `send_string_with_delay_P(PSTR(string), interval)`.
On ARM devices, this define evaluates to `send_string_with_delay(string, interval)`.

View file

@ -0,0 +1,33 @@
/* Copyright 2022 Khoa Truong <foureight84@gmail.com>
*
* 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
#define EE_HANDS
/* clear default encoder def */
#undef TAP_CODE_DELAY
/* encoder support */
#define TAP_CODE_DELAY 100
#define SPLIT_WPM_ENABLE
#define SPLIT_OLED_ENABLE
#define POINTING_DEVICE_ROTATION_90
#define SPLIT_POINTING_ENABLE
#define POINTING_DEVICE_RIGHT
#define POINTING_DEVICE_TASK_THROTTLE_MS 8

View file

@ -0,0 +1,616 @@
/* Copyright 2022 Khoa Truong <foureight84@gmail.com>
*
* 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/>.
*/
#include QMK_KEYBOARD_H
#include <string.h>
#include "lib/lib8tion/lib8tion.h"
enum sofle_layers {
/* _M_XYZ = Mac Os, _W_XYZ = Win/Linux */
_QWERTY,
_COLEMAK,
_LOWER,
_RAISE,
_ADJUST,
_MOUSE,
};
enum custom_keycodes {
KC_QWERTY = SAFE_RANGE,
KC_COLEMAK,
KC_LOWER,
KC_RAISE,
KC_ADJUST,
KC_PRVWD,
KC_NXTWD,
KC_LSTRT,
KC_LEND,
KC_DLINE,
KC_MOUSE,
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/*
* QWERTY
* ,-----------------------------------------. ,-----------------------------------------.
* | ESC | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Bspc |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | Tab | Q | W | E | R | T | | Y | U | I | O | P | \ |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* |LCtrl | A | S | D | F | G |-------. ,-------| H | J | K | L | ; | ' |
* |------+------+------+------+------+------| MUTE | | |------+------+------+------+------+------|
* |LShift| Z | X | C | V | B |-------| |-------| N | M | , | . | / |RShift|
* `-----------------------------------------/ / \ \-----------------------------------------'
* | [ | LGUI | LAlt |LOWER | /Space / \Enter \ |RAISE | RCTR | RAlt | ] |
* | | | | |/ / \ \ | | | | |
* `----------------------------------' '------''---------------------------'
*/
[_QWERTY] = LAYOUT( \
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, \
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSLS, \
KC_LCTRL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, \
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_MUTE, XXXXXXX,KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, \
KC_LBRC ,KC_LGUI, KC_LALT, KC_LOWER, KC_SPC, KC_ENT, KC_RAISE, KC_RCTRL, KC_RALT, KC_RBRC \
),
/*
* COLEMAK
* ,-----------------------------------------. ,-----------------------------------------.
* | ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | ` |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | ESC | Q | W | F | P | G | | J | L | U | Y | ; | Bspc |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | TAB | A | R | S | T | D |-------. ,-------| H | N | E | I | O | ' |
* |------+------+------+------+------+------| MUTE | | |------+------+------+------+------+------|
* |LShift| Z | X | C | V | B |-------| |-------| K | M | , | . | / |RShift|
* `-----------------------------------------/ / \ \-----------------------------------------'
* | LGUI | LAlt | LCTR |LOWER | /Enter / \Space \ |RAISE | RCTR | RAlt | RGUI |
* | | | | |/ / \ \ | | | | |
* `----------------------------------' '------''---------------------------'
*/
[_COLEMAK] = LAYOUT( \
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_GRV, \
KC_ESC, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC, \
KC_TAB, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT, \
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_MUTE, XXXXXXX,KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, \
KC_LGUI,KC_LALT,KC_LCTRL,KC_LOWER, KC_ENT, KC_SPC, KC_RAISE, KC_RCTRL, KC_RALT, KC_RGUI \
),
/* LOWER
* ,-----------------------------------------. ,-----------------------------------------.
* | F1 | F2 | F3 | F4 | F5 | F6 | | F7 | F8 | F9 | F10 | F11 | F12 |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | MOUSE| ! | @ | # | $ | % |-------. ,-------| ^ | & | * | ( | ) | | |
* |------+------+------+------+------+------| MUTE | | |------+------+------+------+------+------|
* | Shift| = | - | + | { | } |-------| |-------| [ | ] | ; | : | \ | Shift|
* `-----------------------------------------/ / \ \-----------------------------------------'
* | LGUI | LAlt | LCTR |LOWER | /Enter / \Space \ |RAISE | RCTR | RAlt | RGUI |
* | | | | |/ / \ \ | | | | |
* `----------------------------------' '------''---------------------------'
*/
[_LOWER] = LAYOUT( \
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_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, _______, \
KC_MOUSE, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_PIPE, \
_______, KC_EQL, KC_MINS, KC_PLUS, KC_LCBR, KC_RCBR, _______, _______, KC_LBRC, KC_RBRC, KC_SCLN, KC_COLN, KC_BSLS, _______, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______\
),
/* RAISE
* ,----------------------------------------. ,-----------------------------------------.
* | | | | | | | | | | | | | |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | Esc | Ins | Pscr | Menu | | | | | PWrd | Up | NWrd | DLine| Bspc |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | Tab | LAt | LCtl |LShift| | Caps |-------. ,-------| | Left | Down | Rigth| Del | Bspc |
* |------+------+------+------+------+------| MPLY | | |------+------+------+------+------+------|
* |Shift | Undo | Cut | Copy | Paste| |-------| |-------| | LStr | | LEnd | | Shift|
* `-----------------------------------------/ / \ \-----------------------------------------'
* | LGUI | LAlt | LCTR |LOWER | /Enter / \Space \ |RAISE | RCTR | RAlt | RGUI |
* | | | | |/ / \ \ | | | | |
* `----------------------------------' '------''---------------------------'
*/
[_RAISE] = LAYOUT( \
_______, _______ , _______ , _______ , _______ , _______, _______, _______ , _______, _______ , _______ ,_______, \
_______, KC_INS, KC_PSCR, KC_APP, XXXXXXX, XXXXXXX, KC_PGUP, KC_PRVWD, KC_UP, KC_NXTWD,KC_DLINE, KC_BSPC, \
_______, KC_LALT, KC_LCTL, KC_LSFT, XXXXXXX, KC_CAPS, KC_PGDN, KC_LEFT, KC_DOWN, KC_RGHT, KC_DEL, KC_BSPC, \
_______,KC_UNDO, KC_CUT, KC_COPY, KC_PASTE, XXXXXXX, KC_MPLY, _______, XXXXXXX, KC_LSTRT, XXXXXXX, KC_LEND, XXXXXXX, _______, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
),
/* ADJUST
* ,-----------------------------------------. ,-----------------------------------------.
* | | | | | | | | | | | | | |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | RESET| |QWERTY|COLEMAK| | | | | | | | | |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | | |MACWIN| | | |-------. ,-------| | VOLDO| MUTE | VOLUP| | |
* |------+------+------+------+------+------| MUTE | | |------+------+------+------+------+------|
* | | | | | | |-------| |-------| | PREV | PLAY | NEXT | | |
* `-----------------------------------------/ / \ \-----------------------------------------'
* | LGUI | LAlt | LCTR |LOWER | /Enter / \Space \ |RAISE | RCTR | RAlt | RGUI |
* | | | | |/ / \ \ | | | | |
* `----------------------------------' '------''---------------------------'
*/
[_ADJUST] = LAYOUT( \
XXXXXXX , XXXXXXX, XXXXXXX , XXXXXXX , XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, \
RESET , XXXXXXX,KC_QWERTY,KC_COLEMAK,CG_TOGG,XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, \
XXXXXXX , XXXXXXX,CG_TOGG, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_VOLD, KC_MUTE, KC_VOLU, XXXXXXX, XXXXXXX, \
XXXXXXX , XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_MPRV, KC_MPLY, KC_MNXT, XXXXXXX, XXXXXXX, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
),
/* MOUSE
* ,-----------------------------------------. ,-----------------------------------------.
* | | | | | | | | | | | | | |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | | | | | | | | | | | | | |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | | | | | | |-------. ,-------|MS_BT1|MS_BT2| | | | |
* |------+------+------+------+------+------| | | |------+------+------+------+------+------|
* | | | | | | |-------| |-------| | | | | | |
* `-----------------------------------------/ / \ \-----------------------------------------'
* | LGUI | LAlt | LCTR |LOWER | /Enter / \Space \ |RAISE | RCTR | RAlt | RGUI |
* | | | | |/ / \ \ | | | | |
* `----------------------------------' '------''---------------------------'
*/
[_MOUSE] = LAYOUT( \
XXXXXXX , XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, \
XXXXXXX , XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, \
XXXXXXX , XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_MS_BTN1, KC_MS_BTN2, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, \
XXXXXXX , XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
)
};
#ifdef OLED_ENABLE
static void print_status_narrow(void) {
// Print current mode
oled_write_P(PSTR("\n\n"), false);
oled_write_ln_P(PSTR("MODE"), false);
oled_write_ln_P(PSTR(""), false);
if (keymap_config.swap_lctl_lgui) {
oled_write_ln_P(PSTR("MAC"), false);
} else {
oled_write_ln_P(PSTR("WIN"), false);
}
switch (get_highest_layer(default_layer_state)) {
case _QWERTY:
oled_write_ln_P(PSTR("Qwrt"), false);
break;
case _COLEMAK:
oled_write_ln_P(PSTR("Clmk"), false);
break;
default:
oled_write_P(PSTR("Undef"), false);
}
oled_write_P(PSTR("\n\n"), false);
// Print current layer
oled_write_ln_P(PSTR("LAYER"), false);
switch (get_highest_layer(layer_state)) {
case _COLEMAK:
case _QWERTY:
oled_write_P(PSTR("Base\n"), false);
break;
case _RAISE:
oled_write_P(PSTR("Raise"), false);
break;
case _LOWER:
oled_write_P(PSTR("Lower"), false);
break;
case _ADJUST:
oled_write_P(PSTR("Adj\n"), false);
break;
case _MOUSE:
oled_write_P(PSTR("Mouse\n"), false);
break;
default:
oled_write_ln_P(PSTR("Undef"), false);
}
oled_write_P(PSTR("\n\n"), false);
led_t led_usb_state = host_keyboard_led_state();
oled_write_ln_P(PSTR("CPSLK"), led_usb_state.caps_lock);
}
oled_rotation_t oled_init_user(oled_rotation_t rotation) {
if (is_keyboard_master()) {
return OLED_ROTATION_270;
}
if (!is_keyboard_master()) {
return OLED_ROTATION_270;
}
return rotation;
}
/* Animation bit by j-inc https://github.com/qmk/qmk_firmware/tree/master/keyboards/kyria/keymaps/j-inc */
// WPM-responsive animation stuff here
#define IDLE_FRAMES 5
#define IDLE_SPEED 40 // below this wpm value your animation will idle
// #define PREP_FRAMES 1 // uncomment if >1
#define TAP_FRAMES 2
#define TAP_SPEED 60 // above this wpm value typing animation to triggere
#define ANIM_FRAME_DURATION 200 // how long each frame lasts in ms
// #define SLEEP_TIMER 60000 // should sleep after this period of 0 wpm, needs fixing
#define ANIM_SIZE 320 // number of bytes in array, minimize for adequate firmware size, max is 1024
uint32_t anim_timer = 0;
uint32_t anim_sleep = 0;
uint8_t current_idle_frame = 0;
// uint8_t current_prep_frame = 0; // uncomment if PREP_FRAMES >1
uint8_t current_tap_frame = 0;
// Implementation credit j-inc(/James Incandenza), pixelbenny, and obosob.
// Bongo cat images changed and adapted for sofle keyboard oled size.
// Original gif can be found here: https://www.pixilart.com/art/bongo-cat-bd2a8e9323aa705
static void render_anim(void) {
static const char PROGMEM idle[IDLE_FRAMES][ANIM_SIZE] = {
{
0x00, 0xc0, 0x3e, 0x01, 0x00, 0x00, 0x00, 0xc0, 0xfc, 0x03, 0x00, 0x03, 0x0c, 0x30, 0xc0, 0x00,
0xe1, 0x1e, 0x00, 0xc0, 0xbc, 0x83, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3c, 0x03, 0x00, 0x00, 0x00, 0x80, 0x78, 0x87, 0x00, 0x03, 0x0c, 0x30, 0xc0, 0x00, 0xe0, 0x1f,
0x01, 0xc0, 0x3c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x31, 0x05, 0x41, 0x12, 0x04,
0x00, 0x00, 0x00, 0x00, 0xf8, 0x87, 0x00, 0x01, 0x06, 0x18, 0x60, 0x80, 0xc0, 0x3f, 0x03, 0x80,
0x78, 0x07, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x03, 0x05,
0x00, 0x00, 0xf0, 0xcf, 0x00, 0x01, 0x06, 0x18, 0x60, 0x80, 0x80, 0x79, 0x07, 0x80, 0x78, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe0, 0x1e, 0x01, 0x00, 0x03, 0x0c, 0x30, 0xc0, 0x00, 0xf9, 0x07, 0x80, 0x78, 0x07, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xc0, 0x2c, 0x32, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x07, 0x03, 0x0c, 0x30, 0xc0, 0x00, 0x00, 0xf0, 0x0f, 0x80, 0x78, 0x07, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x60, 0x80, 0x00, 0x00, 0xe1, 0x1e, 0x01, 0xf0, 0x8f, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
0x0e, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x08, 0x09, 0x0e, 0x0e, 0x01, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x19,
0x19, 0x41, 0x0a, 0x22, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18,
0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x70, 0x80,
0x00, 0x00, 0xf0, 0x1f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02,
0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x01,
}
};
static const char PROGMEM tap[TAP_FRAMES][ANIM_SIZE] = {
{
0x00, 0xc0, 0x3e, 0x01, 0x00, 0x00, 0x00, 0xc0, 0xfc, 0xff, 0xff, 0xff, 0x7c, 0x70, 0x40, 0x40,
0x61, 0x5e, 0x80, 0xc0, 0xbc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3c, 0x03, 0x00, 0x00, 0x00, 0x80, 0x78, 0x87, 0x00, 0x03, 0x0f, 0x3f, 0xf8, 0xf0, 0xf0, 0x20,
0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xf8, 0x87, 0x00, 0x01, 0x06, 0x18, 0x60, 0x80, 0xc0, 0x3f, 0x03, 0x80,
0x78, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04,
0x00, 0x00, 0xf0, 0xcf, 0x00, 0x01, 0x06, 0x18, 0x60, 0x80, 0x80, 0x79, 0x07, 0x80, 0x78, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe0, 0x1e, 0x01, 0x00, 0x03, 0x0c, 0x30, 0xc0, 0x00, 0xf9, 0x07, 0x80, 0x78, 0x07, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xc0, 0x2c, 0x32, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x07, 0x03, 0x0c, 0x30, 0xc0, 0x00, 0x00, 0xf0, 0x0f, 0x80, 0x78, 0x07, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x60, 0x80, 0x00, 0x00, 0xe1, 0x1e, 0x01, 0xf0, 0x8f, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
0x0e, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x08, 0x09, 0x0e, 0x0e, 0x01, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x19,
0x19, 0x41, 0x0a, 0x22, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18,
0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x70, 0x80,
0x00, 0x00, 0xf0, 0x1f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02,
0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x01,
},
{
0x00, 0xc0, 0x3e, 0x01, 0x00, 0x00, 0x00, 0xc0, 0xfc, 0x03, 0x00, 0x03, 0x0c, 0x30, 0xc0, 0x00,
0xe1, 0x1e, 0x00, 0xc0, 0xbc, 0x83, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3c, 0x03, 0x00, 0x00, 0x00, 0x80, 0x78, 0x87, 0x00, 0x03, 0x0c, 0x30, 0xc0, 0x00, 0xe0, 0x1f,
0x01, 0xc0, 0x3c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x31, 0x05, 0x41, 0x12, 0x04,
0x00, 0x00, 0x00, 0x00, 0xf8, 0x87, 0x00, 0x01, 0x06, 0x18, 0x60, 0x80, 0xc0, 0x3f, 0x03, 0x80,
0x78, 0x07, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x03, 0x05,
0x00, 0x00, 0xf0, 0xcf, 0x00, 0x01, 0x06, 0x18, 0x60, 0x80, 0x80, 0x79, 0x07, 0x80, 0x78, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe0, 0xfe, 0xff, 0xff, 0xff, 0xfc, 0xf0, 0xc0, 0x00, 0xf9, 0x07, 0x80, 0x78, 0x07, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xc0, 0x2c, 0x32, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x07, 0x03, 0x0f, 0x3f, 0xff, 0x03, 0x01, 0x03, 0x07, 0x18, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x60, 0x80, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x03, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x0e, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x08, 0x09, 0x0e, 0x0e, 0x01, 0xf3, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18,
0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x70, 0x80,
0x00, 0x00, 0xf0, 0x1f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02,
0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x01
},
};
//assumes 1 frame prep stage
void animation_phase(void) {
if(get_current_wpm() <=IDLE_SPEED){
oled_write_raw_P(idle[0], ANIM_SIZE);
}
if(get_current_wpm() >=TAP_SPEED){
current_tap_frame = (current_tap_frame + 1) % TAP_FRAMES;
oled_write_raw_P(tap[abs((TAP_FRAMES-1)-current_tap_frame)], ANIM_SIZE);
}
}
if(get_current_wpm() != 000) {
oled_on(); // not essential but turns on animation OLED with any alpha keypress
if(timer_elapsed32(anim_timer) > ANIM_FRAME_DURATION) {
anim_timer = timer_read32();
animation_phase();
}
anim_sleep = timer_read32();
} else {
if(timer_elapsed32(anim_sleep) > OLED_TIMEOUT) {
oled_off();
} else {
if(timer_elapsed32(anim_timer) > ANIM_FRAME_DURATION) {
anim_timer = timer_read32();
animation_phase();
}
}
}
}
bool oled_task_user(void) {
if (is_keyboard_master()) {
print_status_narrow();
} else {
render_anim();
oled_set_cursor(1,12);
oled_write_P(PSTR("WPM"), false);
oled_set_cursor(1,13);
oled_write(get_u8_str(get_current_wpm(), '0'), false);
}
return false;
}
#endif
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case KC_QWERTY:
if (record->event.pressed) {
set_single_persistent_default_layer(_QWERTY);
}
return false;
case KC_COLEMAK:
if (record->event.pressed) {
set_single_persistent_default_layer(_COLEMAK);
}
return false;
case KC_LOWER:
if (record->event.pressed) {
layer_on(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
return false;
case KC_RAISE:
if (record->event.pressed) {
layer_on(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
return false;
case KC_ADJUST:
if (record->event.pressed) {
layer_on(_ADJUST);
} else {
layer_off(_ADJUST);
}
return false;
case KC_PRVWD:
if (record->event.pressed) {
if (keymap_config.swap_lctl_lgui) {
register_mods(mod_config(MOD_LALT));
register_code(KC_LEFT);
} else {
register_mods(mod_config(MOD_LCTL));
register_code(KC_LEFT);
}
} else {
if (keymap_config.swap_lctl_lgui) {
unregister_mods(mod_config(MOD_LALT));
unregister_code(KC_LEFT);
} else {
unregister_mods(mod_config(MOD_LCTL));
unregister_code(KC_LEFT);
}
}
break;
case KC_NXTWD:
if (record->event.pressed) {
if (keymap_config.swap_lctl_lgui) {
register_mods(mod_config(MOD_LALT));
register_code(KC_RIGHT);
} else {
register_mods(mod_config(MOD_LCTL));
register_code(KC_RIGHT);
}
} else {
if (keymap_config.swap_lctl_lgui) {
unregister_mods(mod_config(MOD_LALT));
unregister_code(KC_RIGHT);
} else {
unregister_mods(mod_config(MOD_LCTL));
unregister_code(KC_RIGHT);
}
}
break;
case KC_LSTRT:
if (record->event.pressed) {
if (keymap_config.swap_lctl_lgui) {
//CMD-arrow on Mac, but we have CTL and GUI swapped
register_mods(mod_config(MOD_LCTL));
register_code(KC_LEFT);
} else {
register_code(KC_HOME);
}
} else {
if (keymap_config.swap_lctl_lgui) {
unregister_mods(mod_config(MOD_LCTL));
unregister_code(KC_LEFT);
} else {
unregister_code(KC_HOME);
}
}
break;
case KC_LEND:
if (record->event.pressed) {
if (keymap_config.swap_lctl_lgui) {
//CMD-arrow on Mac, but we have CTL and GUI swapped
register_mods(mod_config(MOD_LCTL));
register_code(KC_RIGHT);
} else {
register_code(KC_END);
}
} else {
if (keymap_config.swap_lctl_lgui) {
unregister_mods(mod_config(MOD_LCTL));
unregister_code(KC_RIGHT);
} else {
unregister_code(KC_END);
}
}
break;
case KC_DLINE:
if (record->event.pressed) {
register_mods(mod_config(MOD_LCTL));
register_code(KC_BSPC);
} else {
unregister_mods(mod_config(MOD_LCTL));
unregister_code(KC_BSPC);
}
break;
case KC_COPY:
if (record->event.pressed) {
register_mods(mod_config(MOD_LCTL));
register_code(KC_C);
} else {
unregister_mods(mod_config(MOD_LCTL));
unregister_code(KC_C);
}
return false;
case KC_PASTE:
if (record->event.pressed) {
register_mods(mod_config(MOD_LCTL));
register_code(KC_V);
} else {
unregister_mods(mod_config(MOD_LCTL));
unregister_code(KC_V);
}
return false;
case KC_CUT:
if (record->event.pressed) {
register_mods(mod_config(MOD_LCTL));
register_code(KC_X);
} else {
unregister_mods(mod_config(MOD_LCTL));
unregister_code(KC_X);
}
return false;
break;
case KC_UNDO:
if (record->event.pressed) {
register_mods(mod_config(MOD_LCTL));
register_code(KC_Z);
} else {
unregister_mods(mod_config(MOD_LCTL));
unregister_code(KC_Z);
}
return false;
case KC_MOUSE:
if (record->event.pressed) {
layer_on(_MOUSE);
} else {
layer_off(_MOUSE);
}
return false;
}
return true;
}
#ifdef ENCODER_ENABLE
bool encoder_update_user(uint8_t index, bool clockwise) {
switch (get_highest_layer(layer_state)) {
case _COLEMAK:
case _QWERTY:
if (index == 0) {
if (clockwise) {
tap_code(KC_VOLD);
} else {
tap_code(KC_VOLU);
}
}
break;
case _RAISE:
if (index == 0) {
if (clockwise) {
tap_code(KC_MPRV);
} else {
tap_code(KC_MNXT);
}
}
break;
}
return true;
}
#endif
static uint32_t last_mouse_activity = 0;
static report_mouse_t last_mouse_report = {0};
static bool is_scrolling = false;
report_mouse_t smooth_mouse_movement(report_mouse_t mouse_report) {
// Linear interpolation and ease-in-out
static fract8 fract = 0.5;
int8_t x = 0;
int8_t y = 0;
int8_t h = 0;
int8_t v = 0;
if (!is_scrolling) {
x = ease8InOutApprox(lerp8by8(last_mouse_report.x, mouse_report.x, fract));
y = ease8InOutApprox(lerp8by8(last_mouse_report.y, mouse_report.y, fract));
} else {
h = ease8InOutApprox(lerp8by8(last_mouse_report.x, mouse_report.x, fract));
v = ease8InOutApprox(lerp8by8(last_mouse_report.y, mouse_report.y, fract));
}
// update the new smoothed report
mouse_report.x = x;
mouse_report.y = y;
mouse_report.h = h;
mouse_report.v = v;
return mouse_report;
}
report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) {
if (has_mouse_report_changed(&last_mouse_report, &mouse_report)) {
last_mouse_activity = timer_read32();
memcpy(&last_mouse_report, &mouse_report, sizeof(mouse_report));
}
return smooth_mouse_movement(mouse_report);
}

View file

@ -0,0 +1 @@
For more information on integrating the Pimoroni Trackball, please see: https://github.com/foureight84/sofle-keyboard-pimoroni

View file

@ -0,0 +1,24 @@
OLED_ENABLE = yes
ENCODER_ENABLE = yes
EXTRAKEY_ENABLE = yes
MOUSEKEY_ENABLE = yes
WPM_ENABLE = yes
#Debug options
VERBOSE = no
CONSOLE_ENABLE = no
COMMAND_ENABLE = no
LTO_ENABLE = yes
SPLIT_KEYBOARD = yes
VIA_ENABLE = no
POINTING_DEVICE_ENABLE = yes
POINTING_DEVICE_DRIVER = pimoroni_trackball
SPACE_CADET_ENABLE = no
GRAVE_ESC_ENABLE = no
MAGIC_ENABLE = no
MUSIC_ENABLE = no

View file

@ -325,11 +325,13 @@ void autoshift_disable(void) {
# ifndef AUTO_SHIFT_NO_SETUP
void autoshift_timer_report(void) {
# ifdef SEND_STRING_ENABLE
char display[8];
snprintf(display, 8, "\n%d\n", autoshift_timeout);
send_string((const char *)display);
# endif
}
# endif

View file

@ -22,12 +22,14 @@
#endif
static void tapping_term_report(void) {
#ifdef SEND_STRING_ENABLE
const char *tapping_term_str = get_u16_str(g_tapping_term, ' ');
// Skip padding spaces
while (*tapping_term_str == ' ') {
tapping_term_str++;
}
send_string(tapping_term_str);
#endif
}
bool process_dynamic_tapping_term(uint16_t keycode, keyrecord_t *record) {

View file

@ -49,7 +49,6 @@
#include "action_util.h"
#include "action_tapping.h"
#include "print.h"
#include "send_string.h"
#include "suspend.h"
#include <stddef.h>
#include <stdlib.h>
@ -169,6 +168,10 @@ extern layer_state_t layer_state;
# include "hd44780.h"
#endif
#ifdef SEND_STRING_ENABLE
# include "send_string.h"
#endif
#ifdef HAPTIC_ENABLE
# include "haptic.h"
# include "process_haptic.h"

View file

@ -1,54 +0,0 @@
/* Copyright 2021
*
* 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/>.
*/
#include <stdint.h>
#include "progmem.h"
#include "send_string_keycodes.h"
#define SEND_STRING(string) send_string_P(PSTR(string))
#define SEND_STRING_DELAY(string, interval) send_string_with_delay_P(PSTR(string), interval)
// Look-Up Tables (LUTs) to convert ASCII character to keycode sequence.
extern const uint8_t ascii_to_shift_lut[16];
extern const uint8_t ascii_to_altgr_lut[16];
extern const uint8_t ascii_to_dead_lut[16];
extern const uint8_t ascii_to_keycode_lut[128];
// clang-format off
#define KCLUT_ENTRY(a, b, c, d, e, f, g, h) \
( ((a) ? 1 : 0) << 0 \
| ((b) ? 1 : 0) << 1 \
| ((c) ? 1 : 0) << 2 \
| ((d) ? 1 : 0) << 3 \
| ((e) ? 1 : 0) << 4 \
| ((f) ? 1 : 0) << 5 \
| ((g) ? 1 : 0) << 6 \
| ((h) ? 1 : 0) << 7 )
// clang-format on
void send_string(const char *str);
void send_string_with_delay(const char *str, uint8_t interval);
void send_string_P(const char *str);
void send_string_with_delay_P(const char *str, uint8_t interval);
void send_char(char ascii_code);
void send_dword(uint32_t number);
void send_word(uint16_t number);
void send_byte(uint8_t number);
void send_nibble(uint8_t number);
void tap_random_base64(void);

View file

@ -142,40 +142,36 @@ __attribute__((weak)) const uint8_t ascii_to_keycode_lut[128] PROGMEM = {
// Note: we bit-pack in "reverse" order to optimize loading
#define PGM_LOADBIT(mem, pos) ((pgm_read_byte(&((mem)[(pos) / 8])) >> ((pos) % 8)) & 0x01)
void send_string(const char *str) {
send_string_with_delay(str, 0);
void send_string(const char *string) {
send_string_with_delay(string, 0);
}
void send_string_P(const char *str) {
send_string_with_delay_P(str, 0);
}
void send_string_with_delay(const char *str, uint8_t interval) {
void send_string_with_delay(const char *string, uint8_t interval) {
while (1) {
char ascii_code = *str;
char ascii_code = *string;
if (!ascii_code) break;
if (ascii_code == SS_QMK_PREFIX) {
ascii_code = *(++str);
ascii_code = *(++string);
if (ascii_code == SS_TAP_CODE) {
// tap
uint8_t keycode = *(++str);
uint8_t keycode = *(++string);
tap_code(keycode);
} else if (ascii_code == SS_DOWN_CODE) {
// down
uint8_t keycode = *(++str);
uint8_t keycode = *(++string);
register_code(keycode);
} else if (ascii_code == SS_UP_CODE) {
// up
uint8_t keycode = *(++str);
uint8_t keycode = *(++string);
unregister_code(keycode);
} else if (ascii_code == SS_DELAY_CODE) {
// delay
int ms = 0;
uint8_t keycode = *(++str);
uint8_t keycode = *(++string);
while (isdigit(keycode)) {
ms *= 10;
ms += keycode - '0';
keycode = *(++str);
keycode = *(++string);
}
while (ms--)
wait_ms(1);
@ -183,50 +179,7 @@ void send_string_with_delay(const char *str, uint8_t interval) {
} else {
send_char(ascii_code);
}
++str;
// interval
{
uint8_t ms = interval;
while (ms--)
wait_ms(1);
}
}
}
void send_string_with_delay_P(const char *str, uint8_t interval) {
while (1) {
char ascii_code = pgm_read_byte(str);
if (!ascii_code) break;
if (ascii_code == SS_QMK_PREFIX) {
ascii_code = pgm_read_byte(++str);
if (ascii_code == SS_TAP_CODE) {
// tap
uint8_t keycode = pgm_read_byte(++str);
tap_code(keycode);
} else if (ascii_code == SS_DOWN_CODE) {
// down
uint8_t keycode = pgm_read_byte(++str);
register_code(keycode);
} else if (ascii_code == SS_UP_CODE) {
// up
uint8_t keycode = pgm_read_byte(++str);
unregister_code(keycode);
} else if (ascii_code == SS_DELAY_CODE) {
// delay
int ms = 0;
uint8_t keycode = pgm_read_byte(++str);
while (isdigit(keycode)) {
ms *= 10;
ms += keycode - '0';
keycode = pgm_read_byte(++str);
}
while (ms--)
wait_ms(1);
}
} else {
send_char(ascii_code);
}
++str;
++string;
// interval
{
uint8_t ms = interval;
@ -250,17 +203,17 @@ void send_char(char ascii_code) {
bool is_dead = PGM_LOADBIT(ascii_to_dead_lut, (uint8_t)ascii_code);
if (is_shifted) {
register_code(KC_LSFT);
register_code(KC_LEFT_SHIFT);
}
if (is_altgred) {
register_code(KC_RALT);
register_code(KC_RIGHT_ALT);
}
tap_code(keycode);
if (is_altgred) {
unregister_code(KC_RALT);
unregister_code(KC_RIGHT_ALT);
}
if (is_shifted) {
unregister_code(KC_LSFT);
unregister_code(KC_LEFT_SHIFT);
}
if (is_dead) {
tap_code(KC_SPACE);
@ -320,3 +273,52 @@ void tap_random_base64(void) {
break;
}
}
#if defined(__AVR__)
void send_string_P(const char *string) {
send_string_with_delay_P(string, 0);
}
void send_string_with_delay_P(const char *string, uint8_t interval) {
while (1) {
char ascii_code = pgm_read_byte(string);
if (!ascii_code) break;
if (ascii_code == SS_QMK_PREFIX) {
ascii_code = pgm_read_byte(++string);
if (ascii_code == SS_TAP_CODE) {
// tap
uint8_t keycode = pgm_read_byte(++string);
tap_code(keycode);
} else if (ascii_code == SS_DOWN_CODE) {
// down
uint8_t keycode = pgm_read_byte(++string);
register_code(keycode);
} else if (ascii_code == SS_UP_CODE) {
// up
uint8_t keycode = pgm_read_byte(++string);
unregister_code(keycode);
} else if (ascii_code == SS_DELAY_CODE) {
// delay
int ms = 0;
uint8_t keycode = pgm_read_byte(++string);
while (isdigit(keycode)) {
ms *= 10;
ms += keycode - '0';
keycode = pgm_read_byte(++string);
}
while (ms--)
wait_ms(1);
}
} else {
send_char(ascii_code);
}
++string;
// interval
{
uint8_t ms = interval;
while (ms--)
wait_ms(1);
}
}
}
#endif

View file

@ -0,0 +1,152 @@
/* Copyright 2021
*
* 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/>.
*/
/**
* \defgroup send_string
*
* Send String API. These functions allow you to create macros by typing out sequences of keystrokes.
* \{
*/
#include <stdint.h>
#include "progmem.h"
#include "send_string_keycodes.h"
// Look-Up Tables (LUTs) to convert ASCII character to keycode sequence.
extern const uint8_t ascii_to_shift_lut[16];
extern const uint8_t ascii_to_altgr_lut[16];
extern const uint8_t ascii_to_dead_lut[16];
extern const uint8_t ascii_to_keycode_lut[128];
// clang-format off
#define KCLUT_ENTRY(a, b, c, d, e, f, g, h) \
( ((a) ? 1 : 0) << 0 \
| ((b) ? 1 : 0) << 1 \
| ((c) ? 1 : 0) << 2 \
| ((d) ? 1 : 0) << 3 \
| ((e) ? 1 : 0) << 4 \
| ((f) ? 1 : 0) << 5 \
| ((g) ? 1 : 0) << 6 \
| ((h) ? 1 : 0) << 7 )
// clang-format on
/**
* \brief Type out a string of ASCII characters.
*
* This function simply calls `send_string_with_delay(string, 0)`.
*
* Most keycodes from the basic keycode range are also supported by way of a special sequence - see `send_string_keycodes.h`.
*
* \param string The string to type out.
*/
void send_string(const char *string);
/**
* \brief Type out a string of ASCII characters, with a delay between each character.
*
* \param string The string to type out.
* \param interval The amount of time, in milliseconds, to wait before typing the next character.
*/
void send_string_with_delay(const char *string, uint8_t interval);
/**
* \brief Type out an ASCII character.
*
* \param ascii_code The character to type.
*/
void send_char(char ascii_code);
/**
* \brief Type out an eight digit (unsigned 32-bit) hexadecimal value.
*
* The format is `[0-9a-f]{8}`, eg. `00000000` through `ffffffff`.
*
* \param number The value to type, from 0 to 4,294,967,295.
*/
void send_dword(uint32_t number);
/**
* \brief Type out a four digit (unsigned 16-bit) hexadecimal value.
*
* The format is `[0-9a-f]{4}`, eg. `0000` through `ffff`.
*
* \param number The value to type, from 0 to 65,535.
*/
void send_word(uint16_t number);
/**
* \brief Type out a two digit (8-bit) hexadecimal value.
*
* The format is `[0-9a-f]{2}`, eg. `00` through `ff`.
*
* \param number The value to type, from 0 to 255.
*/
void send_byte(uint8_t number);
/**
* \brief Type out a single hexadecimal digit.
*
* The format is `[0-9a-f]{1}`, eg. `0` through `f`.
*
* \param number The value to type, from 0 to 15.
*/
void send_nibble(uint8_t number);
/**
* \brief Type a pseudorandom character from the set `A-Z`, `a-z`, `0-9`, `+` and `/`.
*/
void tap_random_base64(void);
#if defined(__AVR__) || defined(__DOXYGEN__)
/**
* \brief Type out a PROGMEM string of ASCII characters.
*
* On ARM devices, this function is simply an alias for send_string_with_delay(string, 0).
*
* \param string The string to type out.
*/
void send_string_P(const char *string);
/**
* \brief Type out a PROGMEM string of ASCII characters, with a delay between each character.
*
* On ARM devices, this function is simply an alias for send_string_with_delay(string, interval).
*
* \param string The string to type out.
* \param interval The amount of time, in milliseconds, to wait before typing the next character.
*/
void send_string_with_delay_P(const char *string, uint8_t interval);
#else
# define send_string_P(string) send_string_with_delay(string, 0)
# define send_string_with_delay_P(string, interval) send_string_with_delay(string, interval)
#endif
/**
* \brief Shortcut macro for send_string_with_delay_P(PSTR(string), 0).
*
* On ARM devices, this define evaluates to send_string_with_delay(string, 0).
*/
#define SEND_STRING(string) send_string_with_delay_P(PSTR(string), 0)
/**
* \brief Shortcut macro for send_string_with_delay_P(PSTR(string), interval).
*
* On ARM devices, this define evaluates to send_string_with_delay(string, interval).
*/
#define SEND_STRING_DELAY(string, interval) send_string_with_delay_P(PSTR(string), interval)
/** \} */

View file

@ -0,0 +1,434 @@
/* Copyright 2019
*
* 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
// clang-format off
/* Punctuation */
#define X_ENT X_ENTER
#define X_ESC X_ESCAPE
#define X_BSPC X_BSPACE
#define X_SPC X_SPACE
#define X_MINS X_MINUS
#define X_EQL X_EQUAL
#define X_LBRC X_LBRACKET
#define X_RBRC X_RBRACKET
#define X_BSLS X_BSLASH
#define X_NUHS X_NONUS_HASH
#define X_SCLN X_SCOLON
#define X_QUOT X_QUOTE
#define X_GRV X_GRAVE
#define X_COMM X_COMMA
#define X_SLSH X_SLASH
#define X_NUBS X_NONUS_BSLASH
/* Lock Keys */
#define X_CLCK X_CAPSLOCK
#define X_CAPS X_CAPSLOCK
#define X_SLCK X_SCROLLLOCK
#define X_NLCK X_NUMLOCK
#define X_LCAP X_LOCKING_CAPS
#define X_LNUM X_LOCKING_NUM
#define X_LSCR X_LOCKING_SCROLL
/* Commands */
#define X_PSCR X_PSCREEN
#define X_PAUS X_PAUSE
#define X_BRK X_PAUSE
#define X_INS X_INSERT
#define X_DEL X_DELETE
#define X_PGDN X_PGDOWN
#define X_RGHT X_RIGHT
#define X_APP X_APPLICATION
#define X_EXEC X_EXECUTE
#define X_SLCT X_SELECT
#define X_AGIN X_AGAIN
#define X_PSTE X_PASTE
#define X_ERAS X_ALT_ERASE
#define X_CLR X_CLEAR
/* Keypad */
#define X_PSLS X_KP_SLASH
#define X_PAST X_KP_ASTERISK
#define X_PMNS X_KP_MINUS
#define X_PPLS X_KP_PLUS
#define X_PENT X_KP_ENTER
#define X_P1 X_KP_1
#define X_P2 X_KP_2
#define X_P3 X_KP_3
#define X_P4 X_KP_4
#define X_P5 X_KP_5
#define X_P6 X_KP_6
#define X_P7 X_KP_7
#define X_P8 X_KP_8
#define X_P9 X_KP_9
#define X_P0 X_KP_0
#define X_PDOT X_KP_DOT
#define X_PEQL X_KP_EQUAL
#define X_PCMM X_KP_COMMA
/* Japanese specific */
#define X_ZKHK X_GRAVE
#define X_RO X_INT1
#define X_KANA X_INT2
#define X_JYEN X_INT3
#define X_HENK X_INT4
#define X_MHEN X_INT5
/* Korean specific */
#define X_HAEN X_LANG1
#define X_HANJ X_LANG2
/* Modifiers */
#define X_LCTL X_LCTRL
#define X_LSFT X_LSHIFT
#define X_LOPT X_LALT
#define X_LCMD X_LGUI
#define X_LWIN X_LGUI
#define X_RCTL X_RCTRL
#define X_RSFT X_RSHIFT
#define X_ALGR X_RALT
#define X_ROPT X_RALT
#define X_RCMD X_RGUI
#define X_RWIN X_RGUI
/* Generic Desktop Page (0x01) */
#define X_PWR X_SYSTEM_POWER
#define X_SLEP X_SYSTEM_SLEEP
#define X_WAKE X_SYSTEM_WAKE
/* Consumer Page (0x0C) */
#define X_MUTE X_AUDIO_MUTE
#define X_VOLU X_AUDIO_VOL_UP
#define X_VOLD X_AUDIO_VOL_DOWN
#define X_MNXT X_MEDIA_NEXT_TRACK
#define X_MPRV X_MEDIA_PREV_TRACK
#define X_MSTP X_MEDIA_STOP
#define X_MPLY X_MEDIA_PLAY_PAUSE
#define X_MSEL X_MEDIA_SELECT
#define X_EJCT X_MEDIA_EJECT
#define X_CALC X_CALCULATOR
#define X_MYCM X_MY_COMPUTER
#define X_WSCH X_WWW_SEARCH
#define X_WHOM X_WWW_HOME
#define X_WBAK X_WWW_BACK
#define X_WFWD X_WWW_FORWARD
#define X_WSTP X_WWW_STOP
#define X_WREF X_WWW_REFRESH
#define X_WFAV X_WWW_FAVORITES
#define X_MFFD X_MEDIA_FAST_FORWARD
#define X_MRWD X_MEDIA_REWIND
#define X_BRIU X_BRIGHTNESS_UP
#define X_BRID X_BRIGHTNESS_DOWN
/* System Specific */
#define X_BRMU X_PAUSE
#define X_BRMD X_SCROLLLOCK
/* Mouse Keys */
#define X_MS_U X_MS_UP
#define X_MS_D X_MS_DOWN
#define X_MS_L X_MS_LEFT
#define X_MS_R X_MS_RIGHT
#define X_BTN1 X_MS_BTN1
#define X_BTN2 X_MS_BTN2
#define X_BTN3 X_MS_BTN3
#define X_BTN4 X_MS_BTN4
#define X_BTN5 X_MS_BTN5
#define X_WH_U X_MS_WH_UP
#define X_WH_D X_MS_WH_DOWN
#define X_WH_L X_MS_WH_LEFT
#define X_WH_R X_MS_WH_RIGHT
#define X_ACL0 X_MS_ACCEL0
#define X_ACL1 X_MS_ACCEL1
#define X_ACL2 X_MS_ACCEL2
/* Keyboard/Keypad Page (0x07) */
#define X_A 04
#define X_B 05
#define X_C 06
#define X_D 07
#define X_E 08
#define X_F 09
#define X_G 0a
#define X_H 0b
#define X_I 0c
#define X_J 0d
#define X_K 0e
#define X_L 0f
#define X_M 10
#define X_N 11
#define X_O 12
#define X_P 13
#define X_Q 14
#define X_R 15
#define X_S 16
#define X_T 17
#define X_U 18
#define X_V 19
#define X_W 1a
#define X_X 1b
#define X_Y 1c
#define X_Z 1d
#define X_1 1e
#define X_2 1f
#define X_3 20
#define X_4 21
#define X_5 22
#define X_6 23
#define X_7 24
#define X_8 25
#define X_9 26
#define X_0 27
#define X_ENTER 28
#define X_ESCAPE 29
#define X_BSPACE 2a
#define X_TAB 2b
#define X_SPACE 2c
#define X_MINUS 2d
#define X_EQUAL 2e
#define X_LBRACKET 2f
#define X_RBRACKET 30
#define X_BSLASH 31
#define X_NONUS_HASH 32
#define X_SCOLON 33
#define X_QUOTE 34
#define X_GRAVE 35
#define X_COMMA 36
#define X_DOT 37
#define X_SLASH 38
#define X_CAPSLOCK 39
#define X_F1 3a
#define X_F2 3b
#define X_F3 3c
#define X_F4 3d
#define X_F5 3e
#define X_F6 3f
#define X_F7 40
#define X_F8 41
#define X_F9 42
#define X_F10 43
#define X_F11 44
#define X_F12 45
#define X_PSCREEN 46
#define X_SCROLLLOCK 47
#define X_PAUSE 48
#define X_INSERT 49
#define X_HOME 4a
#define X_PGUP 4b
#define X_DELETE 4c
#define X_END 4d
#define X_PGDOWN 4e
#define X_RIGHT 4f
#define X_LEFT 50
#define X_DOWN 51
#define X_UP 52
#define X_NUMLOCK 53
#define X_KP_SLASH 54
#define X_KP_ASTERISK 55
#define X_KP_MINUS 56
#define X_KP_PLUS 57
#define X_KP_ENTER 58
#define X_KP_1 59
#define X_KP_2 5a
#define X_KP_3 5b
#define X_KP_4 5c
#define X_KP_5 5d
#define X_KP_6 5e
#define X_KP_7 5f
#define X_KP_8 60
#define X_KP_9 61
#define X_KP_0 62
#define X_KP_DOT 63
#define X_NONUS_BSLASH 64
#define X_APPLICATION 65
#define X_POWER 66
#define X_KP_EQUAL 67
#define X_F13 68
#define X_F14 69
#define X_F15 6a
#define X_F16 6b
#define X_F17 6c
#define X_F18 6d
#define X_F19 6e
#define X_F20 6f
#define X_F21 70
#define X_F22 71
#define X_F23 72
#define X_F24 73
#define X_EXECUTE 74
#define X_HELP 75
#define X_MENU 76
#define X_SELECT 77
#define X_STOP 78
#define X_AGAIN 79
#define X_UNDO 7a
#define X_CUT 7b
#define X_COPY 7c
#define X_PASTE 7d
#define X_FIND 7e
#define X__MUTE 7f
#define X__VOLUP 80
#define X__VOLDOWN 81
#define X_LOCKING_CAPS 82
#define X_LOCKING_NUM 83
#define X_LOCKING_SCROLL 84
#define X_KP_COMMA 85
#define X_KP_EQUAL_AS400 86
#define X_INT1 87
#define X_INT2 88
#define X_INT3 89
#define X_INT4 8a
#define X_INT5 8b
#define X_INT6 8c
#define X_INT7 8d
#define X_INT8 8e
#define X_INT9 8f
#define X_LANG1 90
#define X_LANG2 91
#define X_LANG3 92
#define X_LANG4 93
#define X_LANG5 94
#define X_LANG6 95
#define X_LANG7 96
#define X_LANG8 97
#define X_LANG9 98
#define X_ALT_ERASE 99
#define X_SYSREQ 9a
#define X_CANCEL 9b
#define X_CLEAR 9c
#define X_PRIOR 9d
#define X_RETURN 9e
#define X_SEPARATOR 9f
#define X_OUT a0
#define X_OPER a1
#define X_CLEAR_AGAIN a2
#define X_CRSEL a3
#define X_EXSEL a4
/* Modifiers */
#define X_LCTRL e0
#define X_LSHIFT e1
#define X_LALT e2
#define X_LGUI e3
#define X_RCTRL e4
#define X_RSHIFT e5
#define X_RALT e6
#define X_RGUI e7
/* Media and Function keys */
/* Generic Desktop Page (0x01) */
#define X_SYSTEM_POWER a5
#define X_SYSTEM_SLEEP a6
#define X_SYSTEM_WAKE a7
/* Consumer Page (0x0C) */
#define X_AUDIO_MUTE a8
#define X_AUDIO_VOL_UP a9
#define X_AUDIO_VOL_DOWN aa
#define X_MEDIA_NEXT_TRACK ab
#define X_MEDIA_PREV_TRACK ac
#define X_MEDIA_STOP ad
#define X_MEDIA_PLAY_PAUSE ae
#define X_MEDIA_SELECT af
#define X_MEDIA_EJECT b0
#define X_MAIL b1
#define X_CALCULATOR b2
#define X_MY_COMPUTER b3
#define X_WWW_SEARCH b4
#define X_WWW_HOME b5
#define X_WWW_BACK b6
#define X_WWW_FORWARD b7
#define X_WWW_STOP b8
#define X_WWW_REFRESH b9
#define X_WWW_FAVORITES ba
#define X_MEDIA_FAST_FORWARD bb
#define X_MEDIA_REWIND bc
#define X_BRIGHTNESS_UP bd
#define X_BRIGHTNESS_DOWN be
/* Mouse Buttons (unallocated range in HID spec) */
#ifdef VIA_ENABLE
#define X_MS_UP f0
#define X_MS_DOWN f1
#define X_MS_LEFT f2
#define X_MS_RIGHT f3
#define X_MS_BTN1 f4
#define X_MS_BTN2 f5
#define X_MS_BTN3 f6
#define X_MS_BTN4 f7
#define X_MS_BTN5 f8
#define X_MS_BTN6 f8
#define X_MS_BTN7 f8
#define X_MS_BTN8 f8
#else
#define X_MS_UP ed
#define X_MS_DOWN ee
#define X_MS_LEFT ef
#define X_MS_RIGHT f0
#define X_MS_BTN1 f1
#define X_MS_BTN2 f2
#define X_MS_BTN3 f3
#define X_MS_BTN4 f4
#define X_MS_BTN5 f5
#define X_MS_BTN6 f6
#define X_MS_BTN7 f7
#define X_MS_BTN8 f8
#endif
#define X_MS_WH_UP f9
#define X_MS_WH_DOWN fa
#define X_MS_WH_LEFT fb
#define X_MS_WH_RIGHT fc
#define X_MS_ACCEL0 fd
#define X_MS_ACCEL1 fe
#define X_MS_ACCEL2 ff
// Send string macros
#define STRINGIZE(z) #z
#define ADD_SLASH_X(y) STRINGIZE(\x##y)
#define SYMBOL_STR(x) ADD_SLASH_X(x)
#define SS_QMK_PREFIX 1
#define SS_TAP_CODE 1
#define SS_DOWN_CODE 2
#define SS_UP_CODE 3
#define SS_DELAY_CODE 4
#define SS_TAP(keycode) "\1\1" SYMBOL_STR(keycode)
#define SS_DOWN(keycode) "\1\2" SYMBOL_STR(keycode)
#define SS_UP(keycode) "\1\3" SYMBOL_STR(keycode)
#define SS_DELAY(msecs) "\1\4" STRINGIZE(msecs) "|"
// `string` arguments must not be parenthesized
#define SS_LCTL(string) SS_DOWN(X_LCTL) string SS_UP(X_LCTL)
#define SS_LSFT(string) SS_DOWN(X_LSFT) string SS_UP(X_LSFT)
#define SS_LALT(string) SS_DOWN(X_LALT) string SS_UP(X_LALT)
#define SS_LGUI(string) SS_DOWN(X_LGUI) string SS_UP(X_LGUI)
#define SS_LCMD(string) SS_LGUI(string)
#define SS_LWIN(string) SS_LGUI(string)
#define SS_RCTL(string) SS_DOWN(X_RCTL) string SS_UP(X_RCTL)
#define SS_RSFT(string) SS_DOWN(X_RSFT) string SS_UP(X_RSFT)
#define SS_RALT(string) SS_DOWN(X_RALT) string SS_UP(X_RALT)
#define SS_RGUI(string) SS_DOWN(X_RGUI) string SS_UP(X_RGUI)
#define SS_ALGR(string) SS_RALT(string)
#define SS_RCMD(string) SS_RGUI(string)
#define SS_RWIN(string) SS_RGUI(string)
// DEPRECATED
#define SS_LCTRL(string) SS_LCTL(string)

View file

@ -1,505 +0,0 @@
/* Copyright 2019
*
* 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
// clang-format off
/* Punctuation */
#define X_ENT X_ENTER
#define X_ESC X_ESCAPE
#define X_BSPC X_BACKSPACE
#define X_SPC X_SPACE
#define X_MINS X_MINUS
#define X_EQL X_EQUAL
#define X_LBRC X_LEFT_BRACKET
#define X_RBRC X_RIGHT_BRACKET
#define X_BSLS X_BACKSLASH
#define X_NUHS X_NONUS_HASH
#define X_SCLN X_SEMICOLON
#define X_QUOT X_QUOTE
#define X_GRV X_GRAVE
#define X_COMM X_COMMA
#define X_SLSH X_SLASH
#define X_NUBS X_NONUS_BACKSLASH
/* Lock Keys */
#define X_CAPS X_CAPS_LOCK
#define X_SCRL X_SCROLL_LOCK
#define X_NUM X_NUM_LOCK
#define X_LCAP X_LOCKING_CAPS_LOCK
#define X_LNUM X_LOCKING_NUM_LOCK
#define X_LSCR X_LOCKING_SCROLL_LOCK
/* Commands */
#define X_PSCR X_PRINT_SCREEN
#define X_PAUS X_PAUSE
#define X_BRK X_PAUSE
#define X_INS X_INSERT
#define X_PGUP X_PAGE_UP
#define X_DEL X_DELETE
#define X_PGDN X_PAGE_DOWN
#define X_RGHT X_RIGHT
#define X_APP X_APPLICATION
#define X_EXEC X_EXECUTE
#define X_SLCT X_SELECT
#define X_AGIN X_AGAIN
#define X_PSTE X_PASTE
#define X_ERAS X_ALTERNATE_ERASE
#define X_SYRQ X_SYSTEM_REQUEST
#define X_CNCL X_CANCEL
#define X_CLR X_CLEAR
#define X_PRIR X_PRIOR
#define X_RETN X_RETURN
#define X_SEPR X_SEPARATOR
#define X_CLAG X_CLEAR_AGAIN
#define X_CRSL X_CRSEL
#define X_EXSL X_EXSEL
/* Keypad */
#define X_PSLS X_KP_SLASH
#define X_PAST X_KP_ASTERISK
#define X_PMNS X_KP_MINUS
#define X_PPLS X_KP_PLUS
#define X_PENT X_KP_ENTER
#define X_P1 X_KP_1
#define X_P2 X_KP_2
#define X_P3 X_KP_3
#define X_P4 X_KP_4
#define X_P5 X_KP_5
#define X_P6 X_KP_6
#define X_P7 X_KP_7
#define X_P8 X_KP_8
#define X_P9 X_KP_9
#define X_P0 X_KP_0
#define X_PDOT X_KP_DOT
#define X_PEQL X_KP_EQUAL
#define X_PCMM X_KP_COMMA
/* Language Specific */
#define X_INT1 X_INTERNATIONAL_1
#define X_INT2 X_INTERNATIONAL_2
#define X_INT3 X_INTERNATIONAL_3
#define X_INT4 X_INTERNATIONAL_4
#define X_INT5 X_INTERNATIONAL_5
#define X_INT6 X_INTERNATIONAL_6
#define X_INT7 X_INTERNATIONAL_7
#define X_INT8 X_INTERNATIONAL_8
#define X_INT9 X_INTERNATIONAL_9
#define X_LNG1 X_LANGUAGE_1
#define X_LNG2 X_LANGUAGE_2
#define X_LNG3 X_LANGUAGE_3
#define X_LNG4 X_LANGUAGE_4
#define X_LNG5 X_LANGUAGE_5
#define X_LNG6 X_LANGUAGE_6
#define X_LNG7 X_LANGUAGE_7
#define X_LNG8 X_LANGUAGE_8
#define X_LNG9 X_LANGUAGE_9
/* Modifiers */
#define X_LCTL X_LEFT_CTRL
#define X_LSFT X_LEFT_SHIFT
#define X_LALT X_LEFT_ALT
#define X_LOPT X_LEFT_ALT
#define X_LGUI X_LEFT_GUI
#define X_LCMD X_LEFT_GUI
#define X_LWIN X_LEFT_GUI
#define X_RCTL X_RIGHT_CTRL
#define X_RSFT X_RIGHT_SHIFT
#define X_RALT X_RIGHT_ALT
#define X_ALGR X_RIGHT_ALT
#define X_ROPT X_RIGHT_ALT
#define X_RGUI X_RIGHT_GUI
#define X_RCMD X_RIGHT_GUI
#define X_RWIN X_RIGHT_GUI
/* Generic Desktop Page (0x01) */
#define X_PWR X_SYSTEM_POWER
#define X_SLEP X_SYSTEM_SLEEP
#define X_WAKE X_SYSTEM_WAKE
/* Consumer Page (0x0C) */
#define X_MUTE X_AUDIO_MUTE
#define X_VOLU X_AUDIO_VOL_UP
#define X_VOLD X_AUDIO_VOL_DOWN
#define X_MNXT X_MEDIA_NEXT_TRACK
#define X_MPRV X_MEDIA_PREV_TRACK
#define X_MSTP X_MEDIA_STOP
#define X_MPLY X_MEDIA_PLAY_PAUSE
#define X_MSEL X_MEDIA_SELECT
#define X_EJCT X_MEDIA_EJECT
#define X_CALC X_CALCULATOR
#define X_MYCM X_MY_COMPUTER
#define X_WSCH X_WWW_SEARCH
#define X_WHOM X_WWW_HOME
#define X_WBAK X_WWW_BACK
#define X_WFWD X_WWW_FORWARD
#define X_WSTP X_WWW_STOP
#define X_WREF X_WWW_REFRESH
#define X_WFAV X_WWW_FAVORITES
#define X_MFFD X_MEDIA_FAST_FORWARD
#define X_MRWD X_MEDIA_REWIND
#define X_BRIU X_BRIGHTNESS_UP
#define X_BRID X_BRIGHTNESS_DOWN
/* System Specific */
#define X_BRMU X_PAUSE
#define X_BRMD X_SCROLL_LOCK
/* Mouse Keys */
#define X_MS_U X_MS_UP
#define X_MS_D X_MS_DOWN
#define X_MS_L X_MS_LEFT
#define X_MS_R X_MS_RIGHT
#define X_BTN1 X_MS_BTN1
#define X_BTN2 X_MS_BTN2
#define X_BTN3 X_MS_BTN3
#define X_BTN4 X_MS_BTN4
#define X_BTN5 X_MS_BTN5
#define X_BTN6 X_MS_BTN6
#define X_BTN7 X_MS_BTN7
#define X_BTN8 X_MS_BTN8
#define X_WH_U X_MS_WH_UP
#define X_WH_D X_MS_WH_DOWN
#define X_WH_L X_MS_WH_LEFT
#define X_WH_R X_MS_WH_RIGHT
#define X_ACL0 X_MS_ACCEL0
#define X_ACL1 X_MS_ACCEL1
#define X_ACL2 X_MS_ACCEL2
/* Keyboard/Keypad Page (0x07) */
#define X_A 04
#define X_B 05
#define X_C 06
#define X_D 07
#define X_E 08
#define X_F 09
#define X_G 0a
#define X_H 0b
#define X_I 0c
#define X_J 0d
#define X_K 0e
#define X_L 0f
#define X_M 10
#define X_N 11
#define X_O 12
#define X_P 13
#define X_Q 14
#define X_R 15
#define X_S 16
#define X_T 17
#define X_U 18
#define X_V 19
#define X_W 1a
#define X_X 1b
#define X_Y 1c
#define X_Z 1d
#define X_1 1e
#define X_2 1f
#define X_3 20
#define X_4 21
#define X_5 22
#define X_6 23
#define X_7 24
#define X_8 25
#define X_9 26
#define X_0 27
#define X_ENTER 28
#define X_ESCAPE 29
#define X_BACKSPACE 2a
#define X_TAB 2b
#define X_SPACE 2c
#define X_MINUS 2d
#define X_EQUAL 2e
#define X_LEFT_BRACKET 2f
#define X_RIGHT_BRACKET 30
#define X_BACKSLASH 31
#define X_NONUS_HASH 32
#define X_SEMICOLON 33
#define X_QUOTE 34
#define X_GRAVE 35
#define X_COMMA 36
#define X_DOT 37
#define X_SLASH 38
#define X_CAPS_LOCK 39
#define X_F1 3a
#define X_F2 3b
#define X_F3 3c
#define X_F4 3d
#define X_F5 3e
#define X_F6 3f
#define X_F7 40
#define X_F8 41
#define X_F9 42
#define X_F10 43
#define X_F11 44
#define X_F12 45
#define X_PRINT_SCREEN 46
#define X_SCROLL_LOCK 47
#define X_PAUSE 48
#define X_INSERT 49
#define X_HOME 4a
#define X_PAGE_UP 4b
#define X_DELETE 4c
#define X_END 4d
#define X_PAGE_DOWN 4e
#define X_RIGHT 4f
#define X_LEFT 50
#define X_DOWN 51
#define X_UP 52
#define X_NUM_LOCK 53
#define X_KP_SLASH 54
#define X_KP_ASTERISK 55
#define X_KP_MINUS 56
#define X_KP_PLUS 57
#define X_KP_ENTER 58
#define X_KP_1 59
#define X_KP_2 5a
#define X_KP_3 5b
#define X_KP_4 5c
#define X_KP_5 5d
#define X_KP_6 5e
#define X_KP_7 5f
#define X_KP_8 60
#define X_KP_9 61
#define X_KP_0 62
#define X_KP_DOT 63
#define X_NONUS_BACKSLASH 64
#define X_APPLICATION 65
#define X_KB_POWER 66
#define X_KP_EQUAL 67
#define X_F13 68
#define X_F14 69
#define X_F15 6a
#define X_F16 6b
#define X_F17 6c
#define X_F18 6d
#define X_F19 6e
#define X_F20 6f
#define X_F21 70
#define X_F22 71
#define X_F23 72
#define X_F24 73
#define X_EXECUTE 74
#define X_HELP 75
#define X_MENU 76
#define X_SELECT 77
#define X_STOP 78
#define X_AGAIN 79
#define X_UNDO 7a
#define X_CUT 7b
#define X_COPY 7c
#define X_PASTE 7d
#define X_FIND 7e
#define X_KB_MUTE 7f
#define X_KB_VOLUME_UP 80
#define X_KB_VOLUME_DOWN 81
#define X_LOCKING_CAPS_LOCK 82
#define X_LOCKING_NUM_LOCK 83
#define X_LOCKING_SCROLL_LOCK 84
#define X_KP_COMMA 85
#define X_KP_EQUAL_AS400 86
#define X_INTERNATIONAL_1 87
#define X_INTERNATIONAL_2 88
#define X_INTERNATIONAL_3 89
#define X_INTERNATIONAL_4 8a
#define X_INTERNATIONAL_5 8b
#define X_INTERNATIONAL_6 8c
#define X_INTERNATIONAL_7 8d
#define X_INTERNATIONAL_8 8e
#define X_INTERNATIONAL_9 8f
#define X_LANGUAGE_1 90
#define X_LANGUAGE_2 91
#define X_LANGUAGE_3 92
#define X_LANGUAGE_4 93
#define X_LANGUAGE_5 94
#define X_LANGUAGE_6 95
#define X_LANGUAGE_7 96
#define X_LANGUAGE_8 97
#define X_LANGUAGE_9 98
#define X_ALTERNATE_ERASE 99
#define X_SYSTEM_REQUEST 9a
#define X_CANCEL 9b
#define X_CLEAR 9c
#define X_PRIOR 9d
#define X_RETURN 9e
#define X_SEPARATOR 9f
#define X_OUT a0
#define X_OPER a1
#define X_CLEAR_AGAIN a2
#define X_CRSEL a3
#define X_EXSEL a4
/* Modifiers */
#define X_LEFT_CTRL e0
#define X_LEFT_SHIFT e1
#define X_LEFT_ALT e2
#define X_LEFT_GUI e3
#define X_RIGHT_CTRL e4
#define X_RIGHT_SHIFT e5
#define X_RIGHT_ALT e6
#define X_RIGHT_GUI e7
/* Media and Function keys */
/* Generic Desktop Page (0x01) */
#define X_SYSTEM_POWER a5
#define X_SYSTEM_SLEEP a6
#define X_SYSTEM_WAKE a7
/* Consumer Page (0x0C) */
#define X_AUDIO_MUTE a8
#define X_AUDIO_VOL_UP a9
#define X_AUDIO_VOL_DOWN aa
#define X_MEDIA_NEXT_TRACK ab
#define X_MEDIA_PREV_TRACK ac
#define X_MEDIA_STOP ad
#define X_MEDIA_PLAY_PAUSE ae
#define X_MEDIA_SELECT af
#define X_MEDIA_EJECT b0
#define X_MAIL b1
#define X_CALCULATOR b2
#define X_MY_COMPUTER b3
#define X_WWW_SEARCH b4
#define X_WWW_HOME b5
#define X_WWW_BACK b6
#define X_WWW_FORWARD b7
#define X_WWW_STOP b8
#define X_WWW_REFRESH b9
#define X_WWW_FAVORITES ba
#define X_MEDIA_FAST_FORWARD bb
#define X_MEDIA_REWIND bc
#define X_BRIGHTNESS_UP bd
#define X_BRIGHTNESS_DOWN be
/* Mouse Buttons (unallocated range in HID spec) */
#ifdef VIA_ENABLE
#define X_MS_UP f0
#define X_MS_DOWN f1
#define X_MS_LEFT f2
#define X_MS_RIGHT f3
#define X_MS_BTN1 f4
#define X_MS_BTN2 f5
#define X_MS_BTN3 f6
#define X_MS_BTN4 f7
#define X_MS_BTN5 f8
#define X_MS_BTN6 f8
#define X_MS_BTN7 f8
#define X_MS_BTN8 f8
#else
#define X_MS_UP ed
#define X_MS_DOWN ee
#define X_MS_LEFT ef
#define X_MS_RIGHT f0
#define X_MS_BTN1 f1
#define X_MS_BTN2 f2
#define X_MS_BTN3 f3
#define X_MS_BTN4 f4
#define X_MS_BTN5 f5
#define X_MS_BTN6 f6
#define X_MS_BTN7 f7
#define X_MS_BTN8 f8
#endif
#define X_MS_WH_UP f9
#define X_MS_WH_DOWN fa
#define X_MS_WH_LEFT fb
#define X_MS_WH_RIGHT fc
#define X_MS_ACCEL0 fd
#define X_MS_ACCEL1 fe
#define X_MS_ACCEL2 ff
// Send string macros
#define STRINGIZE(z) #z
#define ADD_SLASH_X(y) STRINGIZE(\x##y)
#define SYMBOL_STR(x) ADD_SLASH_X(x)
#define SS_QMK_PREFIX 1
#define SS_TAP_CODE 1
#define SS_DOWN_CODE 2
#define SS_UP_CODE 3
#define SS_DELAY_CODE 4
#define SS_TAP(keycode) "\1\1" SYMBOL_STR(keycode)
#define SS_DOWN(keycode) "\1\2" SYMBOL_STR(keycode)
#define SS_UP(keycode) "\1\3" SYMBOL_STR(keycode)
#define SS_DELAY(msecs) "\1\4" STRINGIZE(msecs) "|"
// `string` arguments must not be parenthesized
#define SS_LCTL(string) SS_DOWN(X_LCTL) string SS_UP(X_LCTL)
#define SS_LSFT(string) SS_DOWN(X_LSFT) string SS_UP(X_LSFT)
#define SS_LALT(string) SS_DOWN(X_LALT) string SS_UP(X_LALT)
#define SS_LGUI(string) SS_DOWN(X_LGUI) string SS_UP(X_LGUI)
#define SS_LCMD(string) SS_LGUI(string)
#define SS_LWIN(string) SS_LGUI(string)
#define SS_RCTL(string) SS_DOWN(X_RCTL) string SS_UP(X_RCTL)
#define SS_RSFT(string) SS_DOWN(X_RSFT) string SS_UP(X_RSFT)
#define SS_RALT(string) SS_DOWN(X_RALT) string SS_UP(X_RALT)
#define SS_RGUI(string) SS_DOWN(X_RGUI) string SS_UP(X_RGUI)
#define SS_ALGR(string) SS_RALT(string)
#define SS_RCMD(string) SS_RGUI(string)
#define SS_RWIN(string) SS_RGUI(string)
// DEPRECATED
#define X_BSPACE X_BACKSPACE
#define X_LBRACKET X_LEFT_BRACKET
#define X_RBRACKET X_RIGHT_BRACKET
#define X_BSLASH X_BACKSLASH
#define X_SCOLON X_SEMICOLON
#define X_CAPSLOCK X_CAPS_LOCK
#define X_PSCREEN X_PRINT_SCREEN
#define X_SCROLLLOCK X_SCROLL_LOCK
#define X_PGDOWN X_PAGE_DOWN
#define X_NUMLOCK X_NUM_LOCK
#define X_NONUS_BSLASH X_NONUS_BACKSLASH
#define X_POWER X_KB_POWER
#define X__MUTE X_KB_MUTE
#define X__VOLUP X_KB_VOLUME_UP
#define X__VOLDOWN X_KB_VOLUME_DOWN
#define X_LOCKING_CAPS X_LOCKING_CAPS_LOCK
#define X_LOCKING_NUM X_LOCKING_NUM_LOCK
#define X_LOCKING_SCROLL X_LOCKING_SCROLL_LOCK
#define X_LANG1 X_LANGUAGE_1
#define X_LANG2 X_LANGUAGE_2
#define X_LANG3 X_LANGUAGE_3
#define X_LANG4 X_LANGUAGE_4
#define X_LANG5 X_LANGUAGE_5
#define X_LANG6 X_LANGUAGE_6
#define X_LANG7 X_LANGUAGE_7
#define X_LANG8 X_LANGUAGE_8
#define X_LANG9 X_LANGUAGE_9
#define X_ALT_ERASE X_ALTERNATE_ERASE
#define X_SYSREQ X_SYSTEM_REQUEST
#define X_LCTRL X_LEFT_CTRL
#define X_LSHIFT X_LEFT_SHIFT
#define X_RCTRL X_RIGHT_CTRL
#define X_RSHIFT X_RIGHT_SHIFT
#define X_ZKHK X_GRAVE
#define X_RO X_INTERNATIONAL_1
#define X_KANA X_INTERNATIONAL_2
#define X_JYEN X_INTERNATIONAL_3
#define X_HENK X_INTERNATIONAL_4
#define X_MHEN X_INTERNATIONAL_5
#define X_HAEN X_LANGUAGE_1
#define X_HANJ X_LANGUAGE_2
#define X_CLCK X_CAPS_LOCK
#define X_SLCK X_SCROLL_LOCK
#define X_NLCK X_NUM_LOCK
#define SS_LCTRL(string) SS_LCTL(string)