merge from master
This commit is contained in:
commit
3996250d81
11279 changed files with 499671 additions and 99678 deletions
|
@ -1,5 +1,4 @@
|
|||
#ifndef PROCESS_AUDIO_H
|
||||
#define PROCESS_AUDIO_H
|
||||
#pragma once
|
||||
|
||||
float compute_freq_for_midi_note(uint8_t note);
|
||||
|
||||
|
@ -9,5 +8,3 @@ void process_audio_noteoff(uint8_t note);
|
|||
void process_audio_all_notes_off(void);
|
||||
|
||||
void audio_on_user(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,15 +16,152 @@
|
|||
|
||||
#ifdef AUTO_SHIFT_ENABLE
|
||||
|
||||
# include <stdbool.h>
|
||||
# include <stdio.h>
|
||||
|
||||
# include "process_auto_shift.h"
|
||||
|
||||
static bool autoshift_enabled = true;
|
||||
static uint16_t autoshift_time = 0;
|
||||
static uint16_t autoshift_timeout = AUTO_SHIFT_TIMEOUT;
|
||||
static uint16_t autoshift_lastkey = KC_NO;
|
||||
static struct {
|
||||
// Whether autoshift is enabled.
|
||||
bool enabled : 1;
|
||||
// Whether the last auto-shifted key was released after the timeout. This
|
||||
// is used to replicate the last key for a tap-then-hold.
|
||||
bool lastshifted : 1;
|
||||
// Whether an auto-shiftable key has been pressed but not processed.
|
||||
bool in_progress : 1;
|
||||
// Whether the auto-shifted keypress has been registered.
|
||||
bool holding_shift : 1;
|
||||
} autoshift_flags = {true, false, false, false};
|
||||
|
||||
/** \brief Record the press of an autoshiftable key
|
||||
*
|
||||
* \return Whether the record should be further processed.
|
||||
*/
|
||||
static bool autoshift_press(uint16_t keycode, uint16_t now, keyrecord_t *record) {
|
||||
if (!autoshift_flags.enabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
# ifndef AUTO_SHIFT_MODIFIERS
|
||||
if (get_mods() & (~MOD_BIT(KC_LSFT))) {
|
||||
return true;
|
||||
}
|
||||
# endif
|
||||
# ifdef AUTO_SHIFT_REPEAT
|
||||
const uint16_t elapsed = TIMER_DIFF_16(now, autoshift_time);
|
||||
# ifndef AUTO_SHIFT_NO_AUTO_REPEAT
|
||||
if (!autoshift_flags.lastshifted) {
|
||||
# endif
|
||||
if (elapsed < TAPPING_TERM && keycode == autoshift_lastkey) {
|
||||
// Allow a tap-then-hold for keyrepeat.
|
||||
if (!autoshift_flags.lastshifted) {
|
||||
register_code(autoshift_lastkey);
|
||||
} else {
|
||||
// Simulate pressing the shift key.
|
||||
add_weak_mods(MOD_BIT(KC_LSFT));
|
||||
register_code(autoshift_lastkey);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
# ifndef AUTO_SHIFT_NO_AUTO_REPEAT
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
|
||||
// Record the keycode so we can simulate it later.
|
||||
autoshift_lastkey = keycode;
|
||||
autoshift_time = now;
|
||||
autoshift_flags.in_progress = true;
|
||||
|
||||
# if !defined(NO_ACTION_ONESHOT) && !defined(NO_ACTION_TAPPING)
|
||||
clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
|
||||
# endif
|
||||
return false;
|
||||
}
|
||||
|
||||
/** \brief Registers an autoshiftable key under the right conditions
|
||||
*
|
||||
* If the autoshift delay has elapsed, register a shift and the key.
|
||||
*
|
||||
* If the autoshift key is released before the delay has elapsed, register the
|
||||
* key without a shift.
|
||||
*/
|
||||
static void autoshift_end(uint16_t keycode, uint16_t now, bool matrix_trigger) {
|
||||
// Called on key down with KC_NO, auto-shifted key up, and timeout.
|
||||
if (autoshift_flags.in_progress) {
|
||||
// Process the auto-shiftable key.
|
||||
autoshift_flags.in_progress = false;
|
||||
|
||||
// Time since the initial press was recorded.
|
||||
const uint16_t elapsed = TIMER_DIFF_16(now, autoshift_time);
|
||||
if (elapsed < autoshift_timeout) {
|
||||
register_code(autoshift_lastkey);
|
||||
autoshift_flags.lastshifted = false;
|
||||
} else {
|
||||
// Simulate pressing the shift key.
|
||||
add_weak_mods(MOD_BIT(KC_LSFT));
|
||||
register_code(autoshift_lastkey);
|
||||
autoshift_flags.lastshifted = true;
|
||||
# if defined(AUTO_SHIFT_REPEAT) && !defined(AUTO_SHIFT_NO_AUTO_REPEAT)
|
||||
if (matrix_trigger) {
|
||||
// Prevents release.
|
||||
return;
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
# if TAP_CODE_DELAY > 0
|
||||
wait_ms(TAP_CODE_DELAY);
|
||||
# endif
|
||||
unregister_code(autoshift_lastkey);
|
||||
del_weak_mods(MOD_BIT(KC_LSFT));
|
||||
} else {
|
||||
// Release after keyrepeat.
|
||||
unregister_code(keycode);
|
||||
if (keycode == autoshift_lastkey) {
|
||||
// This will only fire when the key was the last auto-shiftable
|
||||
// pressed. That prevents aaaaBBBB then releasing a from unshifting
|
||||
// later Bs (if B wasn't auto-shiftable).
|
||||
del_weak_mods(MOD_BIT(KC_LSFT));
|
||||
}
|
||||
}
|
||||
send_keyboard_report(); // del_weak_mods doesn't send one.
|
||||
// Roll the autoshift_time forward for detecting tap-and-hold.
|
||||
autoshift_time = now;
|
||||
}
|
||||
|
||||
/** \brief Simulates auto-shifted key releases when timeout is hit
|
||||
*
|
||||
* Can be called from \c matrix_scan_user so that auto-shifted keys are sent
|
||||
* immediately after the timeout has expired, rather than waiting for the key
|
||||
* to be released.
|
||||
*/
|
||||
void autoshift_matrix_scan(void) {
|
||||
if (autoshift_flags.in_progress) {
|
||||
const uint16_t now = timer_read();
|
||||
const uint16_t elapsed = TIMER_DIFF_16(now, autoshift_time);
|
||||
if (elapsed >= autoshift_timeout) {
|
||||
autoshift_end(autoshift_lastkey, now, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void autoshift_toggle(void) {
|
||||
autoshift_flags.enabled = !autoshift_flags.enabled;
|
||||
del_weak_mods(MOD_BIT(KC_LSFT));
|
||||
}
|
||||
|
||||
void autoshift_enable(void) { autoshift_flags.enabled = true; }
|
||||
|
||||
void autoshift_disable(void) {
|
||||
autoshift_flags.enabled = false;
|
||||
del_weak_mods(MOD_BIT(KC_LSFT));
|
||||
}
|
||||
|
||||
# ifndef AUTO_SHIFT_NO_SETUP
|
||||
void autoshift_timer_report(void) {
|
||||
char display[8];
|
||||
|
||||
|
@ -32,63 +169,29 @@ void autoshift_timer_report(void) {
|
|||
|
||||
send_string((const char *)display);
|
||||
}
|
||||
# endif
|
||||
|
||||
void autoshift_on(uint16_t keycode) {
|
||||
autoshift_time = timer_read();
|
||||
autoshift_lastkey = keycode;
|
||||
}
|
||||
|
||||
void autoshift_flush(void) {
|
||||
if (autoshift_lastkey != KC_NO) {
|
||||
uint16_t elapsed = timer_elapsed(autoshift_time);
|
||||
|
||||
if (elapsed > autoshift_timeout) {
|
||||
tap_code16(LSFT(autoshift_lastkey));
|
||||
} else {
|
||||
tap_code(autoshift_lastkey);
|
||||
}
|
||||
|
||||
autoshift_time = 0;
|
||||
autoshift_lastkey = KC_NO;
|
||||
}
|
||||
}
|
||||
|
||||
void autoshift_enable(void) { autoshift_enabled = true; }
|
||||
void autoshift_disable(void) {
|
||||
autoshift_enabled = false;
|
||||
autoshift_flush();
|
||||
}
|
||||
|
||||
void autoshift_toggle(void) {
|
||||
if (autoshift_enabled) {
|
||||
autoshift_enabled = false;
|
||||
autoshift_flush();
|
||||
} else {
|
||||
autoshift_enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool get_autoshift_state(void) { return autoshift_enabled; }
|
||||
bool get_autoshift_state(void) { return autoshift_flags.enabled; }
|
||||
|
||||
uint16_t get_autoshift_timeout(void) { return autoshift_timeout; }
|
||||
|
||||
void set_autoshift_timeout(uint16_t timeout) { autoshift_timeout = timeout; }
|
||||
|
||||
bool process_auto_shift(uint16_t keycode, keyrecord_t *record) {
|
||||
// Note that record->event.time isn't reliable, see:
|
||||
// https://github.com/qmk/qmk_firmware/pull/9826#issuecomment-733559550
|
||||
const uint16_t now = timer_read();
|
||||
|
||||
if (record->event.pressed) {
|
||||
if (autoshift_flags.in_progress) {
|
||||
// Evaluate previous key if there is one. Doing this elsewhere is
|
||||
// more complicated and easier to break.
|
||||
autoshift_end(KC_NO, now, false);
|
||||
}
|
||||
// For pressing another key while keyrepeating shifted autoshift.
|
||||
del_weak_mods(MOD_BIT(KC_LSFT));
|
||||
|
||||
switch (keycode) {
|
||||
case KC_ASUP:
|
||||
autoshift_timeout += 5;
|
||||
return true;
|
||||
|
||||
case KC_ASDN:
|
||||
autoshift_timeout -= 5;
|
||||
return true;
|
||||
|
||||
case KC_ASRP:
|
||||
autoshift_timer_report();
|
||||
return true;
|
||||
|
||||
case KC_ASTG:
|
||||
autoshift_toggle();
|
||||
return true;
|
||||
|
@ -99,41 +202,40 @@ bool process_auto_shift(uint16_t keycode, keyrecord_t *record) {
|
|||
autoshift_disable();
|
||||
return true;
|
||||
|
||||
# ifndef NO_AUTO_SHIFT_ALPHA
|
||||
case KC_A ... KC_Z:
|
||||
# endif
|
||||
# ifndef NO_AUTO_SHIFT_NUMERIC
|
||||
case KC_1 ... KC_0:
|
||||
# endif
|
||||
# ifndef NO_AUTO_SHIFT_SPECIAL
|
||||
case KC_TAB:
|
||||
case KC_MINUS ... KC_SLASH:
|
||||
case KC_NONUS_BSLASH:
|
||||
# endif
|
||||
autoshift_flush();
|
||||
if (!autoshift_enabled) return true;
|
||||
|
||||
# ifndef AUTO_SHIFT_MODIFIERS
|
||||
if (get_mods()) {
|
||||
return true;
|
||||
}
|
||||
# endif
|
||||
autoshift_on(keycode);
|
||||
|
||||
// We need some extra handling here for OSL edge cases
|
||||
# if !defined(NO_ACTION_ONESHOT) && !defined(NO_ACTION_TAPPING)
|
||||
clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
|
||||
# endif
|
||||
return false;
|
||||
|
||||
default:
|
||||
autoshift_flush();
|
||||
# ifndef AUTO_SHIFT_NO_SETUP
|
||||
case KC_ASUP:
|
||||
autoshift_timeout += 5;
|
||||
return true;
|
||||
case KC_ASDN:
|
||||
autoshift_timeout -= 5;
|
||||
return true;
|
||||
|
||||
case KC_ASRP:
|
||||
autoshift_timer_report();
|
||||
return true;
|
||||
# endif
|
||||
}
|
||||
} else {
|
||||
autoshift_flush();
|
||||
}
|
||||
|
||||
switch (keycode) {
|
||||
# ifndef NO_AUTO_SHIFT_ALPHA
|
||||
case KC_A ... KC_Z:
|
||||
# endif
|
||||
# ifndef NO_AUTO_SHIFT_NUMERIC
|
||||
case KC_1 ... KC_0:
|
||||
# endif
|
||||
# ifndef NO_AUTO_SHIFT_SPECIAL
|
||||
case KC_TAB:
|
||||
case KC_MINUS ... KC_SLASH:
|
||||
case KC_NONUS_BSLASH:
|
||||
# endif
|
||||
if (record->event.pressed) {
|
||||
return autoshift_press(keycode, now, record);
|
||||
} else {
|
||||
autoshift_end(keycode, now, false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,3 +30,4 @@ void autoshift_toggle(void);
|
|||
bool get_autoshift_state(void);
|
||||
uint16_t get_autoshift_timeout(void);
|
||||
void set_autoshift_timeout(uint16_t timeout);
|
||||
void autoshift_matrix_scan(void);
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef PROCESS_CLICKY_H
|
||||
#define PROCESS_CLICKY_H
|
||||
#pragma once
|
||||
|
||||
void clicky_play(void);
|
||||
bool process_clicky(uint16_t keycode, keyrecord_t *record);
|
||||
|
@ -13,5 +12,3 @@ void clicky_on(void);
|
|||
void clicky_off(void);
|
||||
|
||||
bool is_clicky_on(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,10 +24,10 @@ extern combo_t key_combos[];
|
|||
extern int COMBO_LEN;
|
||||
#endif
|
||||
|
||||
__attribute__((weak)) void process_combo_event(uint8_t combo_index, bool pressed) {}
|
||||
__attribute__((weak)) void process_combo_event(uint16_t combo_index, bool pressed) {}
|
||||
|
||||
static uint16_t timer = 0;
|
||||
static uint8_t current_combo_index = 0;
|
||||
static uint16_t current_combo_index = 0;
|
||||
static bool drop_buffer = false;
|
||||
static bool is_active = false;
|
||||
static bool b_combo_enable = true; // defaults to enabled
|
||||
|
@ -82,8 +82,8 @@ static inline void dump_key_buffer(bool emit) {
|
|||
} while (0)
|
||||
|
||||
static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *record) {
|
||||
uint8_t count = 0;
|
||||
uint8_t index = -1;
|
||||
uint8_t count = 0;
|
||||
uint16_t index = -1;
|
||||
/* Find index of keycode and number of combo keys */
|
||||
for (const uint16_t *keys = combo->keys;; ++count) {
|
||||
uint16_t key = pgm_read_word(&keys[count]);
|
||||
|
|
|
@ -14,8 +14,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PROCESS_COMBO_H
|
||||
#define PROCESS_COMBO_H
|
||||
#pragma once
|
||||
|
||||
#include "progmem.h"
|
||||
#include "quantum.h"
|
||||
|
@ -56,11 +55,9 @@ typedef struct {
|
|||
|
||||
bool process_combo(uint16_t keycode, keyrecord_t *record);
|
||||
void matrix_scan_combo(void);
|
||||
void process_combo_event(uint8_t combo_index, bool pressed);
|
||||
void process_combo_event(uint16_t combo_index, bool pressed);
|
||||
|
||||
void combo_enable(void);
|
||||
void combo_disable(void);
|
||||
void combo_toggle(void);
|
||||
bool is_combo_enabled(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -216,11 +216,13 @@ bool process_dynamic_macro(uint16_t keycode, keyrecord_t *record) {
|
|||
} else {
|
||||
/* A macro is being recorded right now. */
|
||||
switch (keycode) {
|
||||
case DYN_REC_START1:
|
||||
case DYN_REC_START2:
|
||||
case DYN_REC_STOP:
|
||||
/* Stop the macro recording. */
|
||||
if (record->event.pressed) { /* Ignore the initial release
|
||||
* just after the recoding
|
||||
* starts. */
|
||||
if (record->event.pressed ^ (keycode != DYN_REC_STOP)) { /* Ignore the initial release
|
||||
* just after the recording
|
||||
* starts for DYN_REC_STOP. */
|
||||
switch (macro_id) {
|
||||
case 1:
|
||||
dynamic_macro_record_end(macro_buffer, macro_pointer, +1, ¯o_end);
|
||||
|
|
|
@ -17,8 +17,8 @@ bool process_joystick(uint16_t keycode, keyrecord_t *record) {
|
|||
return true;
|
||||
}
|
||||
|
||||
__attribute__((weak))
|
||||
void joystick_task(void) {
|
||||
|
||||
__attribute__((weak)) void joystick_task(void) {
|
||||
if (process_joystick_analogread() && (joystick_status.status & JS_UPDATED)) {
|
||||
send_joystick_packet(&joystick_status);
|
||||
joystick_status.status &= ~JS_UPDATED;
|
||||
|
@ -47,16 +47,11 @@ uint16_t savePinState(pin_t pin) {
|
|||
return ((PORTx_ADDRESS(pin) >> pinNumber) & 0x1) << 1 | ((DDRx_ADDRESS(pin) >> pinNumber) & 0x1);
|
||||
#elif defined(PROTOCOL_CHIBIOS)
|
||||
/*
|
||||
The pin configuration is backed up in the following format :
|
||||
The pin configuration is backed up in the following format :
|
||||
bit 15 9 8 7 6 5 4 3 2 1 0
|
||||
|unused|ODR|IDR|PUPDR|OSPEEDR|OTYPER|MODER|
|
||||
*/
|
||||
return (( PAL_PORT(pin)->MODER >> (2*PAL_PAD(pin))) & 0x3)
|
||||
| (((PAL_PORT(pin)->OTYPER >> (1*PAL_PAD(pin))) & 0x1) << 2)
|
||||
| (((PAL_PORT(pin)->OSPEEDR >> (2*PAL_PAD(pin))) & 0x3) << 3)
|
||||
| (((PAL_PORT(pin)->PUPDR >> (2*PAL_PAD(pin))) & 0x3) << 5)
|
||||
| (((PAL_PORT(pin)->IDR >> (1*PAL_PAD(pin))) & 0x1) << 7)
|
||||
| (((PAL_PORT(pin)->ODR >> (1*PAL_PAD(pin))) & 0x1) << 8);
|
||||
return ((PAL_PORT(pin)->MODER >> (2 * PAL_PAD(pin))) & 0x3) | (((PAL_PORT(pin)->OTYPER >> (1 * PAL_PAD(pin))) & 0x1) << 2) | (((PAL_PORT(pin)->OSPEEDR >> (2 * PAL_PAD(pin))) & 0x3) << 3) | (((PAL_PORT(pin)->PUPDR >> (2 * PAL_PAD(pin))) & 0x3) << 5) | (((PAL_PORT(pin)->IDR >> (1 * PAL_PAD(pin))) & 0x1) << 7) | (((PAL_PORT(pin)->ODR >> (1 * PAL_PAD(pin))) & 0x1) << 8);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
@ -68,12 +63,12 @@ void restorePinState(pin_t pin, uint16_t restoreState) {
|
|||
PORTx_ADDRESS(pin) = (PORTx_ADDRESS(pin) & ~_BV(pinNumber)) | (((restoreState >> 1) & 0x1) << pinNumber);
|
||||
DDRx_ADDRESS(pin) = (DDRx_ADDRESS(pin) & ~_BV(pinNumber)) | ((restoreState & 0x1) << pinNumber);
|
||||
#elif defined(PROTOCOL_CHIBIOS)
|
||||
PAL_PORT(pin)->MODER = (PAL_PORT(pin)->MODER & ~(0x3<< (2*PAL_PAD(pin)))) | (restoreState & 0x3) << (2*PAL_PAD(pin));
|
||||
PAL_PORT(pin)->OTYPER = (PAL_PORT(pin)->OTYPER & ~(0x1<< (1*PAL_PAD(pin)))) | ((restoreState>>2) & 0x1) << (1*PAL_PAD(pin));
|
||||
PAL_PORT(pin)->OSPEEDR= (PAL_PORT(pin)->OSPEEDR & ~(0x3<< (2*PAL_PAD(pin)))) | ((restoreState>>3) & 0x3) << (2*PAL_PAD(pin));
|
||||
PAL_PORT(pin)->PUPDR = (PAL_PORT(pin)->PUPDR & ~(0x3<< (2*PAL_PAD(pin)))) | ((restoreState>>5) & 0x3) << (2*PAL_PAD(pin));
|
||||
PAL_PORT(pin)->IDR = (PAL_PORT(pin)->IDR & ~(0x1<< (1*PAL_PAD(pin)))) | ((restoreState>>7) & 0x1) << (1*PAL_PAD(pin));
|
||||
PAL_PORT(pin)->ODR = (PAL_PORT(pin)->ODR & ~(0x1<< (1*PAL_PAD(pin)))) | ((restoreState>>8) & 0x1) << (1*PAL_PAD(pin));
|
||||
PAL_PORT(pin)->MODER = (PAL_PORT(pin)->MODER & ~(0x3 << (2 * PAL_PAD(pin)))) | (restoreState & 0x3) << (2 * PAL_PAD(pin));
|
||||
PAL_PORT(pin)->OTYPER = (PAL_PORT(pin)->OTYPER & ~(0x1 << (1 * PAL_PAD(pin)))) | ((restoreState >> 2) & 0x1) << (1 * PAL_PAD(pin));
|
||||
PAL_PORT(pin)->OSPEEDR = (PAL_PORT(pin)->OSPEEDR & ~(0x3 << (2 * PAL_PAD(pin)))) | ((restoreState >> 3) & 0x3) << (2 * PAL_PAD(pin));
|
||||
PAL_PORT(pin)->PUPDR = (PAL_PORT(pin)->PUPDR & ~(0x3 << (2 * PAL_PAD(pin)))) | ((restoreState >> 5) & 0x3) << (2 * PAL_PAD(pin));
|
||||
PAL_PORT(pin)->IDR = (PAL_PORT(pin)->IDR & ~(0x1 << (1 * PAL_PAD(pin)))) | ((restoreState >> 7) & 0x1) << (1 * PAL_PAD(pin));
|
||||
PAL_PORT(pin)->ODR = (PAL_PORT(pin)->ODR & ~(0x1 << (1 * PAL_PAD(pin)))) | ((restoreState >> 8) & 0x1) << (1 * PAL_PAD(pin));
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
|
@ -132,21 +127,21 @@ bool process_joystick_analogread_quantum() {
|
|||
int16_t axis_val = joystick_axes[axis_index].mid_digit;
|
||||
# endif
|
||||
|
||||
//test the converted value against the lower range
|
||||
int32_t ref = joystick_axes[axis_index].mid_digit;
|
||||
int32_t range = joystick_axes[axis_index].min_digit;
|
||||
int32_t ranged_val = ((axis_val - ref) * -127) / (range - ref) ;
|
||||
// test the converted value against the lower range
|
||||
int32_t ref = joystick_axes[axis_index].mid_digit;
|
||||
int32_t range = joystick_axes[axis_index].min_digit;
|
||||
int32_t ranged_val = ((axis_val - ref) * -JOYSTICK_RESOLUTION) / (range - ref);
|
||||
|
||||
if (ranged_val > 0) {
|
||||
//the value is in the higher range
|
||||
range = joystick_axes[axis_index].max_digit;
|
||||
ranged_val = ((axis_val - ref) * 127) / (range - ref);
|
||||
// the value is in the higher range
|
||||
range = joystick_axes[axis_index].max_digit;
|
||||
ranged_val = ((axis_val - ref) * JOYSTICK_RESOLUTION) / (range - ref);
|
||||
}
|
||||
|
||||
//clamp the result in the valid range
|
||||
ranged_val = ranged_val < -127 ? -127 : ranged_val;
|
||||
ranged_val = ranged_val > 127 ? 127 : ranged_val;
|
||||
|
||||
|
||||
// clamp the result in the valid range
|
||||
ranged_val = ranged_val < -JOYSTICK_RESOLUTION ? -JOYSTICK_RESOLUTION : ranged_val;
|
||||
ranged_val = ranged_val > JOYSTICK_RESOLUTION ? JOYSTICK_RESOLUTION : ranged_val;
|
||||
|
||||
if (ranged_val != joystick_status.axes[axis_index]) {
|
||||
joystick_status.axes[axis_index] = ranged_val;
|
||||
joystick_status.status |= JS_UPDATED;
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "inttypes.h"
|
||||
#include "stdint.h"
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include "process_key_lock.h"
|
||||
|
||||
#define BV_64(shift) (((uint64_t)1) << (shift))
|
||||
|
|
|
@ -14,11 +14,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PROCESS_KEY_LOCK_H
|
||||
#define PROCESS_KEY_LOCK_H
|
||||
#pragma once
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
bool process_key_lock(uint16_t *keycode, keyrecord_t *record);
|
||||
|
||||
#endif // PROCESS_KEY_LOCK_H
|
||||
|
|
|
@ -14,8 +14,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PROCESS_LEADER_H
|
||||
#define PROCESS_LEADER_H
|
||||
#pragma once
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
|
@ -37,5 +36,3 @@ void qk_leader_start(void);
|
|||
extern uint16_t leader_sequence[5]; \
|
||||
extern uint8_t leader_sequence_size
|
||||
#define LEADER_DICTIONARY() if (leading && timer_elapsed(leader_time) > LEADER_TIMEOUT)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -41,12 +41,12 @@ static int8_t midi_modulation_step;
|
|||
static uint16_t midi_modulation_timer;
|
||||
midi_config_t midi_config;
|
||||
|
||||
inline uint8_t compute_velocity(uint8_t setting) { return (setting + 1) * (128 / (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN + 1)); }
|
||||
inline uint8_t compute_velocity(uint8_t setting) { return setting * (128 / (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN)); }
|
||||
|
||||
void midi_init(void) {
|
||||
midi_config.octave = MI_OCT_2 - MIDI_OCTAVE_MIN;
|
||||
midi_config.transpose = 0;
|
||||
midi_config.velocity = (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN);
|
||||
midi_config.velocity = 127;
|
||||
midi_config.channel = 0;
|
||||
midi_config.modulation_interval = 8;
|
||||
|
||||
|
@ -66,12 +66,14 @@ bool process_midi(uint16_t keycode, keyrecord_t *record) {
|
|||
case MIDI_TONE_MIN ... MIDI_TONE_MAX: {
|
||||
uint8_t channel = midi_config.channel;
|
||||
uint8_t tone = keycode - MIDI_TONE_MIN;
|
||||
uint8_t velocity = compute_velocity(midi_config.velocity);
|
||||
uint8_t velocity = midi_config.velocity;
|
||||
if (record->event.pressed) {
|
||||
uint8_t note = midi_compute_note(keycode);
|
||||
midi_send_noteon(&midi_device, channel, note, velocity);
|
||||
dprintf("midi noteon channel:%d note:%d velocity:%d\n", channel, note, velocity);
|
||||
tone_status[tone] = note;
|
||||
if (tone_status[tone] == MIDI_INVALID_NOTE) {
|
||||
uint8_t note = midi_compute_note(keycode);
|
||||
midi_send_noteon(&midi_device, channel, note, velocity);
|
||||
dprintf("midi noteon channel:%d note:%d velocity:%d\n", channel, note, velocity);
|
||||
tone_status[tone] = note;
|
||||
}
|
||||
} else {
|
||||
uint8_t note = tone_status[tone];
|
||||
if (note != MIDI_INVALID_NOTE) {
|
||||
|
@ -122,19 +124,30 @@ bool process_midi(uint16_t keycode, keyrecord_t *record) {
|
|||
return false;
|
||||
case MIDI_VELOCITY_MIN ... MIDI_VELOCITY_MAX:
|
||||
if (record->event.pressed) {
|
||||
midi_config.velocity = keycode - MIDI_VELOCITY_MIN;
|
||||
midi_config.velocity = compute_velocity(keycode - MIDI_VELOCITY_MIN);
|
||||
dprintf("midi velocity %d\n", midi_config.velocity);
|
||||
}
|
||||
return false;
|
||||
case MI_VELD:
|
||||
if (record->event.pressed && midi_config.velocity > 0) {
|
||||
midi_config.velocity--;
|
||||
if (midi_config.velocity == 127) {
|
||||
midi_config.velocity -= 10;
|
||||
} else if (midi_config.velocity > 12) {
|
||||
midi_config.velocity -= 13;
|
||||
} else {
|
||||
midi_config.velocity = 0;
|
||||
}
|
||||
|
||||
dprintf("midi velocity %d\n", midi_config.velocity);
|
||||
}
|
||||
return false;
|
||||
case MI_VELU:
|
||||
if (record->event.pressed) {
|
||||
midi_config.velocity++;
|
||||
if (record->event.pressed && midi_config.velocity < 127) {
|
||||
if (midi_config.velocity < 115) {
|
||||
midi_config.velocity += 13;
|
||||
} else {
|
||||
midi_config.velocity = 127;
|
||||
}
|
||||
dprintf("midi velocity %d\n", midi_config.velocity);
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -14,8 +14,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PROCESS_MIDI_H
|
||||
#define PROCESS_MIDI_H
|
||||
#pragma once
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
|
@ -35,7 +34,7 @@ typedef union {
|
|||
struct {
|
||||
uint8_t octave : 4;
|
||||
int8_t transpose : 4;
|
||||
uint8_t velocity : 4;
|
||||
uint8_t velocity : 7;
|
||||
uint8_t channel : 4;
|
||||
uint8_t modulation_interval : 4;
|
||||
};
|
||||
|
@ -53,5 +52,3 @@ uint8_t midi_compute_note(uint16_t keycode);
|
|||
# endif // MIDI_ADVANCED
|
||||
|
||||
#endif // MIDI_ENABLE
|
||||
|
||||
#endif
|
||||
|
|
|
@ -191,7 +191,7 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
|
|||
note = music_starting_note + music_offset + 36 + music_map[record->event.key.row][record->event.key.col];
|
||||
} else {
|
||||
uint8_t position = music_map[record->event.key.row][record->event.key.col];
|
||||
note = music_starting_note + music_offset + 36 + SCALE[position % 12] + (position / 12) * 12;
|
||||
note = music_starting_note + music_offset + 36 + SCALE[position % 7] + (position / 7) * 12;
|
||||
}
|
||||
# else
|
||||
if (music_mode == MUSIC_MODE_CHROMATIC)
|
||||
|
|
|
@ -14,8 +14,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PROCESS_MUSIC_H
|
||||
#define PROCESS_MUSIC_H
|
||||
#pragma once
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
|
@ -57,5 +56,3 @@ bool music_mask_user(uint16_t keycode);
|
|||
# endif
|
||||
|
||||
#endif // defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,13 +14,10 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PROCESS_PRINTER_H
|
||||
#define PROCESS_PRINTER_H
|
||||
#pragma once
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
#include "protocol/serial.h"
|
||||
|
||||
bool process_printer(uint16_t keycode, keyrecord_t *record);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,6 +23,7 @@ typedef void (*rgb_func_pointer)(void);
|
|||
*
|
||||
* noinline to optimise for firmware size not speed (not in hot path)
|
||||
*/
|
||||
#if (defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)) || (defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES))
|
||||
static void __attribute__((noinline)) handleKeycodeRGB(const uint8_t is_shifted, const rgb_func_pointer inc_func, const rgb_func_pointer dec_func) {
|
||||
if (is_shifted) {
|
||||
dec_func();
|
||||
|
@ -30,6 +31,7 @@ static void __attribute__((noinline)) handleKeycodeRGB(const uint8_t is_shifted,
|
|||
inc_func();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Wrapper for animation mode
|
||||
|
@ -56,81 +58,152 @@ bool process_rgb(const uint16_t keycode, const keyrecord_t *record) {
|
|||
// Split keyboards need to trigger on key-up for edge-case issue
|
||||
if (!record->event.pressed) {
|
||||
#endif
|
||||
uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT));
|
||||
#if (defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)) || (defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES))
|
||||
uint8_t shifted = get_mods() & MOD_MASK_SHIFT;
|
||||
#endif
|
||||
switch (keycode) {
|
||||
case RGB_TOG:
|
||||
#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
|
||||
rgblight_toggle();
|
||||
#endif
|
||||
#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
|
||||
rgb_matrix_toggle();
|
||||
#endif
|
||||
return false;
|
||||
case RGB_MODE_FORWARD:
|
||||
#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
|
||||
handleKeycodeRGB(shifted, rgblight_step, rgblight_step_reverse);
|
||||
#endif
|
||||
#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
|
||||
handleKeycodeRGB(shifted, rgb_matrix_step, rgb_matrix_step_reverse);
|
||||
#endif
|
||||
return false;
|
||||
case RGB_MODE_REVERSE:
|
||||
#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
|
||||
handleKeycodeRGB(shifted, rgblight_step_reverse, rgblight_step);
|
||||
#endif
|
||||
#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
|
||||
handleKeycodeRGB(shifted, rgb_matrix_step_reverse, rgb_matrix_step);
|
||||
#endif
|
||||
return false;
|
||||
case RGB_HUI:
|
||||
#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
|
||||
handleKeycodeRGB(shifted, rgblight_increase_hue, rgblight_decrease_hue);
|
||||
#endif
|
||||
#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
|
||||
handleKeycodeRGB(shifted, rgb_matrix_increase_hue, rgb_matrix_decrease_hue);
|
||||
#endif
|
||||
return false;
|
||||
case RGB_HUD:
|
||||
#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
|
||||
handleKeycodeRGB(shifted, rgblight_decrease_hue, rgblight_increase_hue);
|
||||
#endif
|
||||
#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
|
||||
handleKeycodeRGB(shifted, rgb_matrix_decrease_hue, rgb_matrix_increase_hue);
|
||||
#endif
|
||||
return false;
|
||||
case RGB_SAI:
|
||||
#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
|
||||
handleKeycodeRGB(shifted, rgblight_increase_sat, rgblight_decrease_sat);
|
||||
#endif
|
||||
#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
|
||||
handleKeycodeRGB(shifted, rgb_matrix_increase_sat, rgb_matrix_decrease_sat);
|
||||
#endif
|
||||
return false;
|
||||
case RGB_SAD:
|
||||
#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
|
||||
handleKeycodeRGB(shifted, rgblight_decrease_sat, rgblight_increase_sat);
|
||||
#endif
|
||||
#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
|
||||
handleKeycodeRGB(shifted, rgb_matrix_decrease_sat, rgb_matrix_increase_sat);
|
||||
#endif
|
||||
return false;
|
||||
case RGB_VAI:
|
||||
#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
|
||||
handleKeycodeRGB(shifted, rgblight_increase_val, rgblight_decrease_val);
|
||||
#endif
|
||||
#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
|
||||
handleKeycodeRGB(shifted, rgb_matrix_increase_val, rgb_matrix_decrease_val);
|
||||
#endif
|
||||
return false;
|
||||
case RGB_VAD:
|
||||
#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
|
||||
handleKeycodeRGB(shifted, rgblight_decrease_val, rgblight_increase_val);
|
||||
#endif
|
||||
#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
|
||||
handleKeycodeRGB(shifted, rgb_matrix_decrease_val, rgb_matrix_increase_val);
|
||||
#endif
|
||||
return false;
|
||||
case RGB_SPI:
|
||||
#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
|
||||
handleKeycodeRGB(shifted, rgblight_increase_speed, rgblight_decrease_speed);
|
||||
#endif
|
||||
#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
|
||||
handleKeycodeRGB(shifted, rgb_matrix_increase_speed, rgb_matrix_decrease_speed);
|
||||
#endif
|
||||
return false;
|
||||
case RGB_SPD:
|
||||
#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
|
||||
handleKeycodeRGB(shifted, rgblight_decrease_speed, rgblight_increase_speed);
|
||||
#endif
|
||||
#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
|
||||
handleKeycodeRGB(shifted, rgb_matrix_decrease_speed, rgb_matrix_increase_speed);
|
||||
#endif
|
||||
return false;
|
||||
case RGB_MODE_PLAIN:
|
||||
#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
|
||||
rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT);
|
||||
#endif
|
||||
#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)
|
||||
rgb_matrix_mode(RGB_MATRIX_SOLID_COLOR);
|
||||
#endif
|
||||
return false;
|
||||
case RGB_MODE_BREATHE:
|
||||
#ifdef RGBLIGHT_EFFECT_BREATHING
|
||||
#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_BREATHING)
|
||||
handleKeycodeRGBMode(RGBLIGHT_MODE_BREATHING, RGBLIGHT_MODE_BREATHING_end);
|
||||
#endif
|
||||
#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES) && !defined(DISABLE_RGB_MATRIX_BREATHING)
|
||||
rgb_matrix_mode(RGB_MATRIX_BREATHING);
|
||||
#endif
|
||||
return false;
|
||||
case RGB_MODE_RAINBOW:
|
||||
#ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
|
||||
#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_RAINBOW_MOOD)
|
||||
handleKeycodeRGBMode(RGBLIGHT_MODE_RAINBOW_MOOD, RGBLIGHT_MODE_RAINBOW_MOOD_end);
|
||||
#endif
|
||||
#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES) && !defined(DISABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT)
|
||||
rgb_matrix_mode(RGB_MATRIX_CYCLE_LEFT_RIGHT);
|
||||
#endif
|
||||
return false;
|
||||
case RGB_MODE_SWIRL:
|
||||
#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
|
||||
#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_RAINBOW_SWIRL)
|
||||
handleKeycodeRGBMode(RGBLIGHT_MODE_RAINBOW_SWIRL, RGBLIGHT_MODE_RAINBOW_SWIRL_end);
|
||||
#endif
|
||||
#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES) && !defined(DISABLE_RGB_MATRIX_CYCLE_PINWHEEL)
|
||||
rgb_matrix_mode(RGB_MATRIX_CYCLE_PINWHEEL);
|
||||
#endif
|
||||
return false;
|
||||
case RGB_MODE_SNAKE:
|
||||
#ifdef RGBLIGHT_EFFECT_SNAKE
|
||||
#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_SNAKE)
|
||||
handleKeycodeRGBMode(RGBLIGHT_MODE_SNAKE, RGBLIGHT_MODE_SNAKE_end);
|
||||
#endif
|
||||
return false;
|
||||
case RGB_MODE_KNIGHT:
|
||||
#ifdef RGBLIGHT_EFFECT_KNIGHT
|
||||
#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_KNIGHT)
|
||||
handleKeycodeRGBMode(RGBLIGHT_MODE_KNIGHT, RGBLIGHT_MODE_KNIGHT_end);
|
||||
#endif
|
||||
return false;
|
||||
case RGB_MODE_XMAS:
|
||||
#ifdef RGBLIGHT_EFFECT_CHRISTMAS
|
||||
#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_CHRISTMAS)
|
||||
rgblight_mode(RGBLIGHT_MODE_CHRISTMAS);
|
||||
#endif
|
||||
return false;
|
||||
case RGB_MODE_GRADIENT:
|
||||
#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
|
||||
#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_STATIC_GRADIENT)
|
||||
handleKeycodeRGBMode(RGBLIGHT_MODE_STATIC_GRADIENT, RGBLIGHT_MODE_STATIC_GRADIENT_end);
|
||||
#endif
|
||||
return false;
|
||||
case RGB_MODE_RGBTEST:
|
||||
#ifdef RGBLIGHT_EFFECT_RGB_TEST
|
||||
#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_RGB_TEST)
|
||||
rgblight_mode(RGBLIGHT_MODE_RGB_TEST);
|
||||
#endif
|
||||
return false;
|
||||
|
|
62
quantum/process_keycode/process_sequencer.c
Normal file
62
quantum/process_keycode/process_sequencer.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
/* Copyright 2020 Rodolphe Belouin
|
||||
*
|
||||
* 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 "process_sequencer.h"
|
||||
|
||||
bool process_sequencer(uint16_t keycode, keyrecord_t *record) {
|
||||
if (record->event.pressed) {
|
||||
switch (keycode) {
|
||||
case SQ_ON:
|
||||
sequencer_on();
|
||||
return false;
|
||||
case SQ_OFF:
|
||||
sequencer_off();
|
||||
return false;
|
||||
case SQ_TOG:
|
||||
sequencer_toggle();
|
||||
return false;
|
||||
case SQ_TMPD:
|
||||
sequencer_decrease_tempo();
|
||||
return false;
|
||||
case SQ_TMPU:
|
||||
sequencer_increase_tempo();
|
||||
return false;
|
||||
case SEQUENCER_RESOLUTION_MIN ... SEQUENCER_RESOLUTION_MAX:
|
||||
sequencer_set_resolution(keycode - SEQUENCER_RESOLUTION_MIN);
|
||||
return false;
|
||||
case SQ_RESD:
|
||||
sequencer_decrease_resolution();
|
||||
return false;
|
||||
case SQ_RESU:
|
||||
sequencer_increase_resolution();
|
||||
return false;
|
||||
case SQ_SALL:
|
||||
sequencer_set_all_steps_on();
|
||||
return false;
|
||||
case SQ_SCLR:
|
||||
sequencer_set_all_steps_off();
|
||||
return false;
|
||||
case SEQUENCER_STEP_MIN ... SEQUENCER_STEP_MAX:
|
||||
sequencer_toggle_step(keycode - SEQUENCER_STEP_MIN);
|
||||
return false;
|
||||
case SEQUENCER_TRACK_MIN ... SEQUENCER_TRACK_MAX:
|
||||
sequencer_toggle_single_active_track(keycode - SEQUENCER_TRACK_MIN);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
21
quantum/process_keycode/process_sequencer.h
Normal file
21
quantum/process_keycode/process_sequencer.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* Copyright 2020 Rodolphe Belouin
|
||||
*
|
||||
* 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 "quantum.h"
|
||||
|
||||
bool process_sequencer(uint16_t keycode, keyrecord_t *record);
|
|
@ -14,10 +14,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "process_space_cadet.h"
|
||||
|
||||
#ifndef TAPPING_TERM
|
||||
# define TAPPING_TERM 200
|
||||
#endif
|
||||
#include "action_tapping.h"
|
||||
|
||||
// ********** OBSOLETE DEFINES, STOP USING! (pls?) **********
|
||||
// Shift / paren setup
|
||||
|
@ -85,7 +82,7 @@ static uint16_t sc_timer = 0;
|
|||
static uint8_t sc_mods = 0;
|
||||
#endif
|
||||
|
||||
void perform_space_cadet(keyrecord_t *record, uint8_t holdMod, uint8_t tapMod, uint8_t keycode) {
|
||||
void perform_space_cadet(keyrecord_t *record, uint16_t sc_keycode, uint8_t holdMod, uint8_t tapMod, uint8_t keycode) {
|
||||
if (record->event.pressed) {
|
||||
sc_last = holdMod;
|
||||
sc_timer = timer_read();
|
||||
|
@ -96,7 +93,12 @@ void perform_space_cadet(keyrecord_t *record, uint8_t holdMod, uint8_t tapMod, u
|
|||
register_mods(MOD_BIT(holdMod));
|
||||
}
|
||||
} else {
|
||||
if (sc_last == holdMod && timer_elapsed(sc_timer) < TAPPING_TERM) {
|
||||
#ifdef TAPPING_TERM_PER_KEY
|
||||
if (sc_last == holdMod && timer_elapsed(sc_timer) < get_tapping_term(sc_keycode, record))
|
||||
#else
|
||||
if (sc_last == holdMod && timer_elapsed(sc_timer) < TAPPING_TERM)
|
||||
#endif
|
||||
{
|
||||
if (holdMod != tapMod) {
|
||||
if (IS_MOD(holdMod)) {
|
||||
unregister_mods(MOD_BIT(holdMod));
|
||||
|
@ -126,31 +128,31 @@ void perform_space_cadet(keyrecord_t *record, uint8_t holdMod, uint8_t tapMod, u
|
|||
bool process_space_cadet(uint16_t keycode, keyrecord_t *record) {
|
||||
switch (keycode) {
|
||||
case KC_LSPO: {
|
||||
perform_space_cadet(record, LSPO_KEYS);
|
||||
perform_space_cadet(record, keycode, LSPO_KEYS);
|
||||
return false;
|
||||
}
|
||||
case KC_RSPC: {
|
||||
perform_space_cadet(record, RSPC_KEYS);
|
||||
perform_space_cadet(record, keycode, RSPC_KEYS);
|
||||
return false;
|
||||
}
|
||||
case KC_LCPO: {
|
||||
perform_space_cadet(record, LCPO_KEYS);
|
||||
perform_space_cadet(record, keycode, LCPO_KEYS);
|
||||
return false;
|
||||
}
|
||||
case KC_RCPC: {
|
||||
perform_space_cadet(record, RCPC_KEYS);
|
||||
perform_space_cadet(record, keycode, RCPC_KEYS);
|
||||
return false;
|
||||
}
|
||||
case KC_LAPO: {
|
||||
perform_space_cadet(record, LAPO_KEYS);
|
||||
perform_space_cadet(record, keycode, LAPO_KEYS);
|
||||
return false;
|
||||
}
|
||||
case KC_RAPC: {
|
||||
perform_space_cadet(record, RAPC_KEYS);
|
||||
perform_space_cadet(record, keycode, RAPC_KEYS);
|
||||
return false;
|
||||
}
|
||||
case KC_SFTENT: {
|
||||
perform_space_cadet(record, SFTENT_KEYS);
|
||||
perform_space_cadet(record, keycode, SFTENT_KEYS);
|
||||
return false;
|
||||
}
|
||||
default: {
|
||||
|
|
|
@ -17,5 +17,5 @@
|
|||
|
||||
#include "quantum.h"
|
||||
|
||||
void perform_space_cadet(keyrecord_t *record, uint8_t holdMod, uint8_t tapMod, uint8_t keycode);
|
||||
void perform_space_cadet(keyrecord_t *record, uint16_t sc_keycode, uint8_t holdMod, uint8_t tapMod, uint8_t keycode);
|
||||
bool process_space_cadet(uint16_t keycode, keyrecord_t *record);
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef PROCESS_STENO_H
|
||||
#define PROCESS_STENO_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
|
@ -25,5 +25,3 @@ void steno_init(void);
|
|||
void steno_set_mode(steno_mode_t mode);
|
||||
uint8_t *steno_get_state(void);
|
||||
uint8_t *steno_get_chord(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,11 +14,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "quantum.h"
|
||||
#include "action_tapping.h"
|
||||
|
||||
#ifndef TAPPING_TERM
|
||||
# define TAPPING_TERM 200
|
||||
#endif
|
||||
|
||||
#ifndef NO_ACTION_ONESHOT
|
||||
uint8_t get_oneshot_mods(void);
|
||||
|
@ -171,7 +166,11 @@ void matrix_scan_tap_dance() {
|
|||
if (action->custom_tapping_term > 0) {
|
||||
tap_user_defined = action->custom_tapping_term;
|
||||
} else {
|
||||
#ifdef TAPPING_TERM_PER_KEY
|
||||
tap_user_defined = get_tapping_term(action->state.keycode, NULL);
|
||||
#else
|
||||
tap_user_defined = TAPPING_TERM;
|
||||
#endif
|
||||
}
|
||||
if (action->state.count && timer_elapsed(action->state.timer) > tap_user_defined) {
|
||||
process_tap_dance_action_on_dance_finished(action);
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef PROCESS_TAP_DANCE_H
|
||||
#define PROCESS_TAP_DANCE_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef TAP_DANCE_ENABLE
|
||||
|
||||
|
@ -101,5 +101,3 @@ void qk_tap_dance_dual_role_reset(qk_tap_dance_state_t *state, void *user_data);
|
|||
# define TD(n) KC_NO
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,8 +14,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PROCESS_TERMINAL_H
|
||||
#define PROCESS_TERMINAL_H
|
||||
#pragma once
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
|
@ -23,5 +22,3 @@ extern const char keycode_to_ascii_lut[58];
|
|||
extern const char shifted_keycode_to_ascii_lut[58];
|
||||
extern const char terminal_prompt[8];
|
||||
bool process_terminal(uint16_t keycode, keyrecord_t *record);
|
||||
|
||||
#endif
|
|
@ -14,12 +14,9 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PROCESS_TERMINAL_H
|
||||
#define PROCESS_TERMINAL_H
|
||||
#pragma once
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
#define TERM_ON KC_NO
|
||||
#define TERM_OFF KC_NO
|
||||
|
||||
#endif
|
|
@ -27,7 +27,7 @@ void qk_ucis_start(void) {
|
|||
|
||||
__attribute__((weak)) void qk_ucis_start_user(void) {
|
||||
unicode_input_start();
|
||||
register_hex(0x2328);
|
||||
register_hex(0x2328); // ⌨
|
||||
unicode_input_finish();
|
||||
}
|
||||
|
||||
|
@ -35,117 +35,95 @@ __attribute__((weak)) void qk_ucis_success(uint8_t symbol_index) {}
|
|||
|
||||
static bool is_uni_seq(char *seq) {
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; seq[i]; i++) {
|
||||
uint16_t code;
|
||||
if (('1' <= seq[i]) && (seq[i] <= '0'))
|
||||
code = seq[i] - '1' + KC_1;
|
||||
else
|
||||
code = seq[i] - 'a' + KC_A;
|
||||
|
||||
if (i > qk_ucis_state.count || qk_ucis_state.codes[i] != code) return false;
|
||||
uint16_t keycode;
|
||||
if ('1' <= seq[i] && seq[i] <= '0') {
|
||||
keycode = seq[i] - '1' + KC_1;
|
||||
} else {
|
||||
keycode = seq[i] - 'a' + KC_A;
|
||||
}
|
||||
if (i > qk_ucis_state.count || qk_ucis_state.codes[i] != keycode) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return (qk_ucis_state.codes[i] == KC_ENT || qk_ucis_state.codes[i] == KC_SPC);
|
||||
return qk_ucis_state.codes[i] == KC_ENT || qk_ucis_state.codes[i] == KC_SPC;
|
||||
}
|
||||
|
||||
__attribute__((weak)) void qk_ucis_symbol_fallback(void) {
|
||||
for (uint8_t i = 0; i < qk_ucis_state.count - 1; i++) {
|
||||
uint8_t code = qk_ucis_state.codes[i];
|
||||
register_code(code);
|
||||
unregister_code(code);
|
||||
uint8_t keycode = qk_ucis_state.codes[i];
|
||||
register_code(keycode);
|
||||
unregister_code(keycode);
|
||||
wait_ms(UNICODE_TYPE_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((weak)) void qk_ucis_cancel(void) {}
|
||||
|
||||
void register_ucis(const char *hex) {
|
||||
for (int i = 0; hex[i]; i++) {
|
||||
uint8_t kc = 0;
|
||||
char c = hex[i];
|
||||
|
||||
switch (c) {
|
||||
case '0':
|
||||
kc = KC_0;
|
||||
break;
|
||||
case '1' ... '9':
|
||||
kc = c - '1' + KC_1;
|
||||
break;
|
||||
case 'a' ... 'f':
|
||||
kc = c - 'a' + KC_A;
|
||||
break;
|
||||
case 'A' ... 'F':
|
||||
kc = c - 'A' + KC_A;
|
||||
break;
|
||||
}
|
||||
|
||||
if (kc) {
|
||||
register_code(kc);
|
||||
unregister_code(kc);
|
||||
wait_ms(UNICODE_TYPE_DELAY);
|
||||
}
|
||||
void register_ucis(const uint32_t *code_points) {
|
||||
for (int i = 0; i < UCIS_MAX_CODE_POINTS && code_points[i]; i++) {
|
||||
register_unicode(code_points[i]);
|
||||
wait_ms(UNICODE_TYPE_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
bool process_ucis(uint16_t keycode, keyrecord_t *record) {
|
||||
uint8_t i;
|
||||
|
||||
if (!qk_ucis_state.in_progress) return true;
|
||||
|
||||
if (qk_ucis_state.count >= UCIS_MAX_SYMBOL_LENGTH && !(keycode == KC_BSPC || keycode == KC_ESC || keycode == KC_SPC || keycode == KC_ENT)) {
|
||||
return false;
|
||||
if (!qk_ucis_state.in_progress || !record->event.pressed) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!record->event.pressed) return true;
|
||||
bool special = keycode == KC_SPC || keycode == KC_ENT || keycode == KC_ESC || keycode == KC_BSPC;
|
||||
if (qk_ucis_state.count >= UCIS_MAX_SYMBOL_LENGTH && !special) {
|
||||
return false;
|
||||
}
|
||||
|
||||
qk_ucis_state.codes[qk_ucis_state.count] = keycode;
|
||||
qk_ucis_state.count++;
|
||||
|
||||
if (keycode == KC_BSPC) {
|
||||
if (qk_ucis_state.count >= 2) {
|
||||
qk_ucis_state.count -= 2;
|
||||
return true;
|
||||
} else {
|
||||
qk_ucis_state.count--;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (keycode == KC_ENT || keycode == KC_SPC || keycode == KC_ESC) {
|
||||
bool symbol_found = false;
|
||||
|
||||
for (i = qk_ucis_state.count; i > 0; i--) {
|
||||
register_code(KC_BSPC);
|
||||
unregister_code(KC_BSPC);
|
||||
wait_ms(UNICODE_TYPE_DELAY);
|
||||
}
|
||||
|
||||
if (keycode == KC_ESC) {
|
||||
qk_ucis_state.in_progress = false;
|
||||
qk_ucis_cancel();
|
||||
return false;
|
||||
}
|
||||
|
||||
unicode_input_start();
|
||||
for (i = 0; ucis_symbol_table[i].symbol; i++) {
|
||||
if (is_uni_seq(ucis_symbol_table[i].symbol)) {
|
||||
symbol_found = true;
|
||||
register_ucis(ucis_symbol_table[i].code + 2);
|
||||
break;
|
||||
switch (keycode) {
|
||||
case KC_BSPC:
|
||||
if (qk_ucis_state.count >= 2) {
|
||||
qk_ucis_state.count -= 2;
|
||||
return true;
|
||||
} else {
|
||||
qk_ucis_state.count--;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!symbol_found) {
|
||||
qk_ucis_symbol_fallback();
|
||||
}
|
||||
unicode_input_finish();
|
||||
|
||||
if (symbol_found) {
|
||||
qk_ucis_success(i);
|
||||
}
|
||||
case KC_SPC:
|
||||
case KC_ENT:
|
||||
case KC_ESC:
|
||||
for (uint8_t i = 0; i < qk_ucis_state.count; i++) {
|
||||
register_code(KC_BSPC);
|
||||
unregister_code(KC_BSPC);
|
||||
wait_ms(UNICODE_TYPE_DELAY);
|
||||
}
|
||||
|
||||
qk_ucis_state.in_progress = false;
|
||||
return false;
|
||||
if (keycode == KC_ESC) {
|
||||
qk_ucis_state.in_progress = false;
|
||||
qk_ucis_cancel();
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t i;
|
||||
bool symbol_found = false;
|
||||
for (i = 0; ucis_symbol_table[i].symbol; i++) {
|
||||
if (is_uni_seq(ucis_symbol_table[i].symbol)) {
|
||||
symbol_found = true;
|
||||
register_ucis(ucis_symbol_table[i].code_points);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (symbol_found) {
|
||||
qk_ucis_success(i);
|
||||
} else {
|
||||
qk_ucis_symbol_fallback();
|
||||
}
|
||||
|
||||
qk_ucis_state.in_progress = false;
|
||||
return false;
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -22,10 +22,13 @@
|
|||
#ifndef UCIS_MAX_SYMBOL_LENGTH
|
||||
# define UCIS_MAX_SYMBOL_LENGTH 32
|
||||
#endif
|
||||
#ifndef UCIS_MAX_CODE_POINTS
|
||||
# define UCIS_MAX_CODE_POINTS 3
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char *symbol;
|
||||
char *code;
|
||||
char * symbol;
|
||||
uint32_t code_points[UCIS_MAX_CODE_POINTS];
|
||||
} qk_ucis_symbol_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -36,12 +39,17 @@ typedef struct {
|
|||
|
||||
extern qk_ucis_state_t qk_ucis_state;
|
||||
|
||||
#define UCIS_TABLE(...) \
|
||||
{ \
|
||||
__VA_ARGS__, { NULL, NULL } \
|
||||
// clang-format off
|
||||
|
||||
#define UCIS_TABLE(...) \
|
||||
{ \
|
||||
__VA_ARGS__, \
|
||||
{ NULL, {} } \
|
||||
}
|
||||
#define UCIS_SYM(name, code) \
|
||||
{ name, #code }
|
||||
#define UCIS_SYM(name, ...) \
|
||||
{ name, {__VA_ARGS__} }
|
||||
|
||||
// clang-format on
|
||||
|
||||
extern const qk_ucis_symbol_t ucis_symbol_table[];
|
||||
|
||||
|
@ -49,5 +57,7 @@ void qk_ucis_start(void);
|
|||
void qk_ucis_start_user(void);
|
||||
void qk_ucis_symbol_fallback(void);
|
||||
void qk_ucis_success(uint8_t symbol_index);
|
||||
void register_ucis(const char *hex);
|
||||
|
||||
void register_ucis(const uint32_t *code_points);
|
||||
|
||||
bool process_ucis(uint16_t keycode, keyrecord_t *record);
|
||||
|
|
|
@ -21,11 +21,12 @@
|
|||
|
||||
unicode_config_t unicode_config;
|
||||
uint8_t unicode_saved_mods;
|
||||
bool unicode_saved_caps_lock;
|
||||
|
||||
#if UNICODE_SELECTED_MODES != -1
|
||||
static uint8_t selected[] = {UNICODE_SELECTED_MODES};
|
||||
static uint8_t selected_count = sizeof selected / sizeof *selected;
|
||||
static uint8_t selected_index;
|
||||
static int8_t selected_count = sizeof selected / sizeof *selected;
|
||||
static int8_t selected_index;
|
||||
#endif
|
||||
|
||||
void unicode_input_mode_init(void) {
|
||||
|
@ -33,7 +34,7 @@ void unicode_input_mode_init(void) {
|
|||
#if UNICODE_SELECTED_MODES != -1
|
||||
# if UNICODE_CYCLE_PERSIST
|
||||
// Find input_mode in selected modes
|
||||
uint8_t i;
|
||||
int8_t i;
|
||||
for (i = 0; i < selected_count; i++) {
|
||||
if (selected[i] == unicode_config.input_mode) {
|
||||
selected_index = i;
|
||||
|
@ -60,9 +61,12 @@ void set_unicode_input_mode(uint8_t mode) {
|
|||
dprintf("Unicode input mode set to: %u\n", unicode_config.input_mode);
|
||||
}
|
||||
|
||||
void cycle_unicode_input_mode(uint8_t offset) {
|
||||
void cycle_unicode_input_mode(int8_t offset) {
|
||||
#if UNICODE_SELECTED_MODES != -1
|
||||
selected_index = (selected_index + offset) % selected_count;
|
||||
selected_index = (selected_index + offset) % selected_count;
|
||||
if (selected_index < 0) {
|
||||
selected_index += selected_count;
|
||||
}
|
||||
unicode_config.input_mode = selected[selected_index];
|
||||
# if UNICODE_CYCLE_PERSIST
|
||||
persist_unicode_input_mode();
|
||||
|
@ -74,6 +78,16 @@ void cycle_unicode_input_mode(uint8_t offset) {
|
|||
void persist_unicode_input_mode(void) { eeprom_update_byte(EECONFIG_UNICODEMODE, unicode_config.input_mode); }
|
||||
|
||||
__attribute__((weak)) void unicode_input_start(void) {
|
||||
unicode_saved_caps_lock = host_keyboard_led_state().caps_lock;
|
||||
|
||||
// Note the order matters here!
|
||||
// Need to do this before we mess around with the mods, or else
|
||||
// UNICODE_KEY_LNX (which is usually Ctrl-Shift-U) might not work
|
||||
// correctly in the shifted case.
|
||||
if (unicode_config.input_mode == UC_LNX && unicode_saved_caps_lock) {
|
||||
tap_code(KC_CAPS);
|
||||
}
|
||||
|
||||
unicode_saved_mods = get_mods(); // Save current mods
|
||||
clear_mods(); // Unregister mods to start from a clean state
|
||||
|
||||
|
@ -104,6 +118,9 @@ __attribute__((weak)) void unicode_input_finish(void) {
|
|||
break;
|
||||
case UC_LNX:
|
||||
tap_code(KC_SPC);
|
||||
if (unicode_saved_caps_lock) {
|
||||
tap_code(KC_CAPS);
|
||||
}
|
||||
break;
|
||||
case UC_WIN:
|
||||
unregister_code(KC_LALT);
|
||||
|
@ -122,6 +139,11 @@ __attribute__((weak)) void unicode_input_cancel(void) {
|
|||
unregister_code(UNICODE_KEY_MAC);
|
||||
break;
|
||||
case UC_LNX:
|
||||
tap_code(KC_ESC);
|
||||
if (unicode_saved_caps_lock) {
|
||||
tap_code(KC_CAPS);
|
||||
}
|
||||
break;
|
||||
case UC_WINC:
|
||||
tap_code(KC_ESC);
|
||||
break;
|
||||
|
@ -133,20 +155,10 @@ __attribute__((weak)) void unicode_input_cancel(void) {
|
|||
set_mods(unicode_saved_mods); // Reregister previously set mods
|
||||
}
|
||||
|
||||
__attribute__((weak)) uint16_t hex_to_keycode(uint8_t hex) {
|
||||
if (hex == 0x0) {
|
||||
return KC_0;
|
||||
} else if (hex < 0xA) {
|
||||
return KC_1 + (hex - 0x1);
|
||||
} else {
|
||||
return KC_A + (hex - 0xA);
|
||||
}
|
||||
}
|
||||
|
||||
void register_hex(uint16_t hex) {
|
||||
for (int i = 3; i >= 0; i--) {
|
||||
uint8_t digit = ((hex >> (i * 4)) & 0xF);
|
||||
tap_code(hex_to_keycode(digit));
|
||||
tap_code16(hex_to_keycode(digit));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,15 +171,36 @@ void register_hex32(uint32_t hex) {
|
|||
uint8_t digit = ((hex >> (i * 4)) & 0xF);
|
||||
if (digit == 0) {
|
||||
if (!onzerostart) {
|
||||
tap_code(hex_to_keycode(digit));
|
||||
tap_code16(hex_to_keycode(digit));
|
||||
}
|
||||
} else {
|
||||
tap_code(hex_to_keycode(digit));
|
||||
tap_code16(hex_to_keycode(digit));
|
||||
onzerostart = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void register_unicode(uint32_t code_point) {
|
||||
if (code_point > 0x10FFFF || (code_point > 0xFFFF && unicode_config.input_mode == UC_WIN)) {
|
||||
// Code point out of range, do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
unicode_input_start();
|
||||
if (code_point > 0xFFFF && unicode_config.input_mode == UC_MAC) {
|
||||
// Convert code point to UTF-16 surrogate pair on macOS
|
||||
code_point -= 0x10000;
|
||||
uint32_t lo = code_point & 0x3FF, hi = (code_point & 0xFFC00) >> 10;
|
||||
register_hex32(hi + 0xD800);
|
||||
register_hex32(lo + 0xDC00);
|
||||
} else {
|
||||
register_hex32(code_point);
|
||||
}
|
||||
unicode_input_finish();
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
|
||||
void send_unicode_hex_string(const char *str) {
|
||||
if (!str) {
|
||||
return;
|
||||
|
@ -175,12 +208,11 @@ void send_unicode_hex_string(const char *str) {
|
|||
|
||||
while (*str) {
|
||||
// Find the next code point (token) in the string
|
||||
for (; *str == ' '; str++)
|
||||
;
|
||||
for (; *str == ' '; str++); // Skip leading spaces
|
||||
size_t n = strcspn(str, " "); // Length of the current token
|
||||
char code_point[n + 1];
|
||||
strncpy(code_point, str, n);
|
||||
code_point[n] = '\0'; // Make sure it's null-terminated
|
||||
char code_point[n+1];
|
||||
strncpy(code_point, str, n); // Copy token into buffer
|
||||
code_point[n] = '\0'; // Make sure it's null-terminated
|
||||
|
||||
// Normalize the code point: make all hex digits lowercase
|
||||
for (char *p = code_point; *p; p++) {
|
||||
|
@ -196,8 +228,10 @@ void send_unicode_hex_string(const char *str) {
|
|||
}
|
||||
}
|
||||
|
||||
// clang-format on
|
||||
|
||||
// Borrowed from https://nullprogram.com/blog/2017/10/06/
|
||||
const char *decode_utf8(const char *str, int32_t *code_point) {
|
||||
static const char *decode_utf8(const char *str, int32_t *code_point) {
|
||||
const char *next;
|
||||
|
||||
if (str[0] < 0x80) { // U+0000-007F
|
||||
|
@ -230,66 +264,80 @@ void send_unicode_string(const char *str) {
|
|||
return;
|
||||
}
|
||||
|
||||
int32_t code_point = 0;
|
||||
|
||||
while (*str) {
|
||||
str = decode_utf8(str, &code_point);
|
||||
int32_t code_point = 0;
|
||||
str = decode_utf8(str, &code_point);
|
||||
|
||||
if (code_point >= 0) {
|
||||
unicode_input_start();
|
||||
register_hex32(code_point);
|
||||
unicode_input_finish();
|
||||
register_unicode(code_point);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
|
||||
static void audio_helper(void) {
|
||||
#ifdef AUDIO_ENABLE
|
||||
switch (get_unicode_input_mode()) {
|
||||
# ifdef UNICODE_SONG_MAC
|
||||
static float song_mac[][2] = UNICODE_SONG_MAC;
|
||||
case UC_MAC:
|
||||
PLAY_SONG(song_mac);
|
||||
break;
|
||||
# endif
|
||||
# ifdef UNICODE_SONG_LNX
|
||||
static float song_lnx[][2] = UNICODE_SONG_LNX;
|
||||
case UC_LNX:
|
||||
PLAY_SONG(song_lnx);
|
||||
break;
|
||||
# endif
|
||||
# ifdef UNICODE_SONG_WIN
|
||||
static float song_win[][2] = UNICODE_SONG_WIN;
|
||||
case UC_WIN:
|
||||
PLAY_SONG(song_win);
|
||||
break;
|
||||
# endif
|
||||
# ifdef UNICODE_SONG_BSD
|
||||
static float song_bsd[][2] = UNICODE_SONG_BSD;
|
||||
case UC_BSD:
|
||||
PLAY_SONG(song_bsd);
|
||||
break;
|
||||
# endif
|
||||
# ifdef UNICODE_SONG_WINC
|
||||
static float song_winc[][2] = UNICODE_SONG_WINC;
|
||||
case UC_WINC:
|
||||
PLAY_SONG(song_winc);
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// clang-format on
|
||||
|
||||
bool process_unicode_common(uint16_t keycode, keyrecord_t *record) {
|
||||
if (record->event.pressed) {
|
||||
bool shifted = get_mods() & MOD_MASK_SHIFT;
|
||||
switch (keycode) {
|
||||
case UNICODE_MODE_FORWARD:
|
||||
cycle_unicode_input_mode(+1);
|
||||
cycle_unicode_input_mode(shifted ? -1 : +1);
|
||||
audio_helper();
|
||||
break;
|
||||
case UNICODE_MODE_REVERSE:
|
||||
cycle_unicode_input_mode(-1);
|
||||
cycle_unicode_input_mode(shifted ? +1 : -1);
|
||||
audio_helper();
|
||||
break;
|
||||
|
||||
case UNICODE_MODE_MAC:
|
||||
set_unicode_input_mode(UC_MAC);
|
||||
#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_MAC)
|
||||
static float song_mac[][2] = UNICODE_SONG_MAC;
|
||||
PLAY_SONG(song_mac);
|
||||
#endif
|
||||
break;
|
||||
case UNICODE_MODE_LNX:
|
||||
set_unicode_input_mode(UC_LNX);
|
||||
#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_LNX)
|
||||
static float song_lnx[][2] = UNICODE_SONG_LNX;
|
||||
PLAY_SONG(song_lnx);
|
||||
#endif
|
||||
break;
|
||||
case UNICODE_MODE_WIN:
|
||||
set_unicode_input_mode(UC_WIN);
|
||||
#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_WIN)
|
||||
static float song_win[][2] = UNICODE_SONG_WIN;
|
||||
PLAY_SONG(song_win);
|
||||
#endif
|
||||
break;
|
||||
case UNICODE_MODE_BSD:
|
||||
set_unicode_input_mode(UC_BSD);
|
||||
#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_BSD)
|
||||
static float song_bsd[][2] = UNICODE_SONG_BSD;
|
||||
PLAY_SONG(song_bsd);
|
||||
#endif
|
||||
break;
|
||||
case UNICODE_MODE_WINC:
|
||||
set_unicode_input_mode(UC_WINC);
|
||||
#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_WINC)
|
||||
static float song_winc[][2] = UNICODE_SONG_WINC;
|
||||
PLAY_SONG(song_winc);
|
||||
#endif
|
||||
case UNICODE_MODE_MAC ... UNICODE_MODE_WINC: {
|
||||
// Keycodes and input modes follow the same ordering
|
||||
uint8_t delta = keycode - UNICODE_MODE_MAC;
|
||||
set_unicode_input_mode(UC_MAC + delta);
|
||||
audio_helper();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(UNICODE_ENABLE)
|
||||
return process_unicode(keycode, record);
|
||||
#elif defined(UNICODEMAP_ENABLE)
|
||||
|
|
|
@ -75,12 +75,11 @@ typedef union {
|
|||
} unicode_config_t;
|
||||
|
||||
extern unicode_config_t unicode_config;
|
||||
extern uint8_t unicode_saved_mods;
|
||||
|
||||
void unicode_input_mode_init(void);
|
||||
uint8_t get_unicode_input_mode(void);
|
||||
void set_unicode_input_mode(uint8_t mode);
|
||||
void cycle_unicode_input_mode(uint8_t offset);
|
||||
void cycle_unicode_input_mode(int8_t offset);
|
||||
void persist_unicode_input_mode(void);
|
||||
|
||||
void unicode_input_start(void);
|
||||
|
@ -89,6 +88,8 @@ void unicode_input_cancel(void);
|
|||
|
||||
void register_hex(uint16_t hex);
|
||||
void register_hex32(uint32_t hex);
|
||||
void register_unicode(uint32_t code_point);
|
||||
|
||||
void send_unicode_hex_string(const char *str);
|
||||
void send_unicode_string(const char *str);
|
||||
|
||||
|
|
|
@ -21,7 +21,13 @@ __attribute__((weak)) uint16_t unicodemap_index(uint16_t keycode) {
|
|||
// Keycode is a pair: extract index based on Shift / Caps Lock state
|
||||
uint16_t index = keycode - QK_UNICODEMAP_PAIR;
|
||||
|
||||
bool shift = unicode_saved_mods & MOD_MASK_SHIFT, caps = IS_HOST_LED_ON(USB_LED_CAPS_LOCK);
|
||||
uint8_t mods = get_mods() | get_weak_mods();
|
||||
#ifndef NO_ACTION_ONESHOT
|
||||
mods |= get_oneshot_mods();
|
||||
#endif
|
||||
|
||||
bool shift = mods & MOD_MASK_SHIFT;
|
||||
bool caps = host_keyboard_led_state().caps_lock;
|
||||
if (shift ^ caps) {
|
||||
index >>= 7;
|
||||
}
|
||||
|
@ -35,25 +41,8 @@ __attribute__((weak)) uint16_t unicodemap_index(uint16_t keycode) {
|
|||
|
||||
bool process_unicodemap(uint16_t keycode, keyrecord_t *record) {
|
||||
if (keycode >= QK_UNICODEMAP && keycode <= QK_UNICODEMAP_PAIR_MAX && record->event.pressed) {
|
||||
unicode_input_start();
|
||||
|
||||
uint32_t code = pgm_read_dword(unicode_map + unicodemap_index(keycode));
|
||||
uint8_t input_mode = get_unicode_input_mode();
|
||||
|
||||
if (code > 0x10FFFF || (code > 0xFFFF && input_mode == UC_WIN)) {
|
||||
// Character is out of range supported by the platform
|
||||
unicode_input_cancel();
|
||||
} else if (code > 0xFFFF && input_mode == UC_MAC) {
|
||||
// Convert to UTF-16 surrogate pair on Mac
|
||||
code -= 0x10000;
|
||||
uint32_t lo = code & 0x3FF, hi = (code & 0xFFC00) >> 10;
|
||||
register_hex32(hi + 0xD800);
|
||||
register_hex32(lo + 0xDC00);
|
||||
unicode_input_finish();
|
||||
} else {
|
||||
register_hex32(code);
|
||||
unicode_input_finish();
|
||||
}
|
||||
uint32_t code_point = pgm_read_dword(unicode_map + unicodemap_index(keycode));
|
||||
register_unicode(code_point);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue