merge from master

This commit is contained in:
Jack Humbert
2021-02-07 21:01:30 -05:00
11279 changed files with 499650 additions and 99657 deletions
+1 -4
View File
@@ -14,8 +14,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _API_H_
#define _API_H_
#pragma once
#ifdef __AVR__
# include "lufa.h"
@@ -54,5 +53,3 @@ __attribute__((weak)) bool process_api_quantum(uint8_t length, uint8_t* data);
__attribute__((weak)) bool process_api_keyboard(uint8_t length, uint8_t* data);
__attribute__((weak)) bool process_api_user(uint8_t length, uint8_t* data);
#endif
+1 -4
View File
@@ -14,13 +14,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _API_SYSEX_H_
#define _API_SYSEX_H_
#pragma once
#include "api.h"
void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t* bytes, uint16_t length);
#define SEND_BYTES(mt, dt, b, l) send_bytes_sysex(mt, dt, b, l)
#endif
+2 -7
View File
@@ -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 AUDIO_H
#define AUDIO_H
#pragma once
#include <stdint.h>
#include <stdbool.h>
@@ -99,12 +99,7 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat);
// length. This works around the limitation of C's sizeof operation on pointers.
// The global float array for the song must be used here.
#define NOTE_ARRAY_SIZE(x) ((int16_t)(sizeof(x) / (sizeof(x[0]))))
#define PLAY_NOTE_ARRAY(note_array, note_repeat, deprecated_arg) \
play_notes(&note_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat)); \
_Pragma("message \"'PLAY_NOTE_ARRAY' macro is deprecated\"")
#define PLAY_SONG(note_array) play_notes(&note_array, NOTE_ARRAY_SIZE((note_array)), false)
#define PLAY_LOOP(note_array) play_notes(&note_array, NOTE_ARRAY_SIZE((note_array)), true)
bool is_playing_notes(void);
#endif
+5
View File
@@ -110,6 +110,11 @@
# define TIMER_1_DUTY_CYCLE OCR1C
# define TIMER1_AUDIO_vect TIMER1_COMPC_vect
#endif
#if !defined(BPIN_AUDIO) && !defined(CPIN_AUDIO)
# error "Audio feature enabled, but no suitable pin selected - see docs/feature_audio.md under the AVR settings for available options."
#endif
// -----------------------------------------------------------------------------
int voices = 0;
+2 -2
View File
@@ -15,8 +15,8 @@
*/
#include "audio.h"
#include "ch.h"
#include "hal.h"
#include <ch.h>
#include <hal.h>
#include <string.h>
#include "print.h"
+6 -9
View File
@@ -14,23 +14,20 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#if defined(__AVR__)
# include <avr/io.h>
# include <avr/interrupt.h>
# include <avr/pgmspace.h>
#else
# include "ch.h"
# include "hal.h"
# include <ch.h>
# include <hal.h>
#endif
#ifndef LUTS_H
# define LUTS_H
#define VIBRATO_LUT_LENGTH 20
# define VIBRATO_LUT_LENGTH 20
# define FREQUENCY_LUT_LENGTH 349
#define FREQUENCY_LUT_LENGTH 349
extern const float vibrato_lut[VIBRATO_LUT_LENGTH];
extern const uint16_t frequency_lut[FREQUENCY_LUT_LENGTH];
#endif /* LUTS_H */
+1 -4
View File
@@ -1,9 +1,6 @@
#ifndef MUSE_H
#define MUSE_H
#pragma once
#include "quantum.h"
#include "process_audio.h"
uint8_t muse_clock_pulse(void);
#endif
+1 -4
View File
@@ -14,8 +14,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MUSICAL_NOTES_H
#define MUSICAL_NOTES_H
#pragma once
// Tempo Placeholder
#define TEMPO_DEFAULT 100
@@ -229,5 +228,3 @@
#define NOTE_GF8 NOTE_FS8
#define NOTE_AF8 NOTE_GS8
#define NOTE_BF8 NOTE_AS8
#endif
+129 -41
View File
@@ -20,6 +20,12 @@
#include "musical_notes.h"
#if __GNUC__ > 5 // don't use for older gcc compilers since check isn't supported.
# if __has_include("user_song_list.h")
# include "user_song_list.h"
# endif // if file exists
#endif // __GNUC__
#define NO_SOUND
/* Ode to Joy
@@ -146,44 +152,126 @@
* proof of permission to use them, or public domain status.
*/
#define CLOSE_ENCOUNTERS_5_NOTE
#define DOE_A_DEER
#define IN_LIKE_FLINT
#define IMPERIAL_MARCH
#define BASKET_CASE
#define COIN_SOUND
#define ONE_UP_SOUND
#define SONIC_RING
#define ZELDA_PUZZLE
#define ZELDA_TREASURE
#define OVERWATCH_THEME
#define MARIO_THEME
#define MARIO_GAMEOVER
#define MARIO_MUSHROOM
#define E1M1_DOOM
#define DISNEY_SONG
#define NUMBER_ONE
#define CABBAGE_SONG
#define OLD_SPICE
#define VICTORY_FANFARE_SHORT
#define ALL_STAR
#define RICK_ROLL
#define FF_PRELUDE
#define TO_BOLDLY_GO
#define KATAWARE_DOKI
#define MEGALOVANIA
#define MICHISHIRUBE
#define LIEBESLEID
#define MELODIES_OF_LIFE
#define EYES_ON_ME
#define SONG_OF_THE_ANCIENTS
#define NIER_AMUSEMENT_PARK
#define COPIED_CITY
#define VAGUE_HOPE_COLD_RAIN
#define KAINE_SALVATION
#define WEIGHT_OF_THE_WORLD
#define ISABELLAS_LULLABY
#define TERRAS_THEME
#define RENAI_CIRCULATION
#define PLATINUM_DISCO
#define LP_NUMB
#ifndef CLOSE_ENCOUNTERS_5_NOTE
# define CLOSE_ENCOUNTERS_5_NOTE
#endif
#ifndef DOE_A_DEER
# define DOE_A_DEER
#endif
#ifndef IN_LIKE_FLINT
# define IN_LIKE_FLINT
#endif
#ifndef IMPERIAL_MARCH
# define IMPERIAL_MARCH
#endif
#ifndef BASKET_CASE
# define BASKET_CASE
#endif
#ifndef COIN_SOUND
# define COIN_SOUND
#endif
#ifndef ONE_UP_SOUND
# define ONE_UP_SOUND
#endif
#ifndef SONIC_RING
# define SONIC_RING
#endif
#ifndef ZELDA_PUZZLE
# define ZELDA_PUZZLE
#endif
#ifndef ZELDA_TREASURE
# define ZELDA_TREASURE
#endif
#ifndef OVERWATCH_THEME
# define OVERWATCH_THEME
#endif
#ifndef MARIO_THEME
# define MARIO_THEME
#endif
#ifndef MARIO_GAMEOVER
# define MARIO_GAMEOVER
#endif
#ifndef MARIO_MUSHROOM
# define MARIO_MUSHROOM
#endif
#ifndef E1M1_DOOM
# define E1M1_DOOM
#endif
#ifndef DISNEY_SONG
# define DISNEY_SONG
#endif
#ifndef NUMBER_ONE
# define NUMBER_ONE
#endif
#ifndef CABBAGE_SONG
# define CABBAGE_SONG
#endif
#ifndef OLD_SPICE
# define OLD_SPICE
#endif
#ifndef VICTORY_FANFARE_SHORT
# define VICTORY_FANFARE_SHORT
#endif
#ifndef ALL_STAR
# define ALL_STAR
#endif
#ifndef RICK_ROLL
# define RICK_ROLL
#endif
#ifndef FF_PRELUDE
# define FF_PRELUDE
#endif
#ifndef TO_BOLDLY_GO
# define TO_BOLDLY_GO
#endif
#ifndef KATAWARE_DOKI
# define KATAWARE_DOKI
#endif
#ifndef MEGALOVANIA
# define MEGALOVANIA
#endif
#ifndef MICHISHIRUBE
# define MICHISHIRUBE
#endif
#ifndef LIEBESLEID
# define LIEBESLEID
#endif
#ifndef MELODIES_OF_LIFE
# define MELODIES_OF_LIFE
#endif
#ifndef EYES_ON_ME
# define EYES_ON_ME
#endif
#ifndef SONG_OF_THE_ANCIENTS
# define SONG_OF_THE_ANCIENTS
#endif
#ifndef NIER_AMUSEMENT_PARK
# define NIER_AMUSEMENT_PARK
#endif
#ifndef COPIED_CITY
# define COPIED_CITY
#endif
#ifndef VAGUE_HOPE_COLD_RAIN
# define VAGUE_HOPE_COLD_RAIN
#endif
#ifndef KAINE_SALVATION
# define KAINE_SALVATION
#endif
#ifndef WEIGHT_OF_THE_WORLD
# define WEIGHT_OF_THE_WORLD
#endif
#ifndef ISABELLAS_LULLABY
# define ISABELLAS_LULLABY
#endif
#ifndef TERRAS_THEME
# define TERRAS_THEME
#endif
#ifndef RENAI_CIRCULATION
# define RENAI_CIRCULATION
#endif
#ifndef PLATINUM_DISCO
# define PLATINUM_DISCO
#endif
#ifndef LP_NUMB
# define LP_NUMB
#endif
+1 -1
View File
@@ -15,7 +15,7 @@
*/
#include "voices.h"
#include "audio.h"
#include "stdlib.h"
#include <stdlib.h>
// these are imported from audio.c
extern uint16_t envelope_index;
+5 -7
View File
@@ -13,6 +13,9 @@
* 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 <stdint.h>
#include <stdbool.h>
#if defined(__AVR__)
@@ -21,14 +24,11 @@
#include "wait.h"
#include "luts.h"
#ifndef VOICES_H
# define VOICES_H
float voice_envelope(float frequency);
typedef enum {
default_voice,
# ifdef AUDIO_VOICES
#ifdef AUDIO_VOICES
something,
drums,
butts_fader,
@@ -41,12 +41,10 @@ typedef enum {
// duty_fourth_down,
// duty_third_down,
// duty_fifth_third_down,
# endif
#endif
number_of_voices // important that this is last
} voice_type;
void set_voice(voice_type v);
void voice_iterate(void);
void voice_deiterate(void);
#endif
-4
View File
@@ -20,10 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "eeconfig.h"
#include "debug.h"
#if defined(STM32F0XX) || defined(STM32F0xx)
# pragma message("Backlight support for STMF072 has had limited testing, YMMV. If unsure, set 'BACKLIGHT_ENABLE = no' in your rules.mk")
#endif
backlight_config_t backlight_config;
#ifdef BACKLIGHT_BREATHING
+11 -3
View File
@@ -3,6 +3,11 @@
#include "backlight_driver_common.h"
#include "debug.h"
// Maximum duty cycle limit
#ifndef BACKLIGHT_LIMIT_VAL
# define BACKLIGHT_LIMIT_VAL 255
#endif
// This logic is a bit complex, we support 3 setups:
//
// 1. Hardware PWM when backlight is wired to a PWM pin.
@@ -103,7 +108,7 @@
# define COMxx1 COM1A1
# define OCRxx OCR1A
# endif
#elif defined(__AVR_ATmega328P__) && (BACKLIGHT_PIN == B1 || BACKLIGHT_PIN == B2)
#elif (defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)) && (BACKLIGHT_PIN == B1 || BACKLIGHT_PIN == B2)
# define HARDWARE_PWM
# define ICRx ICR1
# define TCCRxA TCCR1A
@@ -240,6 +245,9 @@ static uint16_t cie_lightness(uint16_t v) {
}
}
// rescale the supplied backlight value to be in terms of the value limit
static uint32_t rescale_limit_val(uint32_t val) { return (val * (BACKLIGHT_LIMIT_VAL + 1)) / 256; }
// range for val is [0..TIMER_TOP]. PWM pin is high while the timer count is below val.
static inline void set_pwm(uint16_t val) { OCRxx = val; }
@@ -269,7 +277,7 @@ void backlight_set(uint8_t level) {
#endif
}
// Set the brightness
set_pwm(cie_lightness(TIMER_TOP * (uint32_t)level / BACKLIGHT_LEVELS));
set_pwm(cie_lightness(rescale_limit_val(TIMER_TOP * (uint32_t)level / BACKLIGHT_LEVELS)));
}
void backlight_task(void) {}
@@ -375,7 +383,7 @@ ISR(TIMERx_OVF_vect)
breathing_interrupt_disable();
}
set_pwm(cie_lightness(scale_backlight((uint16_t)pgm_read_byte(&breathing_table[index]) * 0x0101U)));
set_pwm(cie_lightness(rescale_limit_val(scale_backlight((uint16_t)pgm_read_byte(&breathing_table[index]) * 0x0101U))));
}
#endif // BACKLIGHT_BREATHING
+77 -105
View File
@@ -3,27 +3,42 @@
#include <hal.h>
#include "debug.h"
// TODO: remove short term bodge when refactoring BACKLIGHT_CUSTOM_DRIVER out
#ifdef BACKLIGHT_PIN
// Maximum duty cycle limit
#ifndef BACKLIGHT_LIMIT_VAL
# define BACKLIGHT_LIMIT_VAL 255
#endif
// GPIOV2 && GPIOV3
# ifndef BACKLIGHT_PAL_MODE
# define BACKLIGHT_PAL_MODE 2
# endif
#ifndef BACKLIGHT_PAL_MODE
# define BACKLIGHT_PAL_MODE 2
#endif
// GENERIC
# ifndef BACKLIGHT_PWM_DRIVER
# define BACKLIGHT_PWM_DRIVER PWMD4
# endif
# ifndef BACKLIGHT_PWM_CHANNEL
# define BACKLIGHT_PWM_CHANNEL 3
# endif
#ifndef BACKLIGHT_PWM_DRIVER
# define BACKLIGHT_PWM_DRIVER PWMD4
#endif
#ifndef BACKLIGHT_PWM_CHANNEL
# define BACKLIGHT_PWM_CHANNEL 3
#endif
static void breathing_callback(PWMDriver *pwmp);
// Support for pins which are on TIM1_CH1N - requires STM32_PWM_USE_ADVANCED
#ifdef BACKLIGHT_PWM_COMPLEMENTARY_OUTPUT
# if BACKLIGHT_ON_STATE == 1
# define PWM_OUTPUT_MODE PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW;
# else
# define PWM_OUTPUT_MODE PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH;
# endif
#else
# if BACKLIGHT_ON_STATE == 1
# define PWM_OUTPUT_MODE PWM_OUTPUT_ACTIVE_HIGH;
# else
# define PWM_OUTPUT_MODE PWM_OUTPUT_ACTIVE_LOW;
# endif
#endif
static PWMConfig pwmCFG = {0xFFFF, /* PWM clock frequency */
256, /* PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */
NULL, /* No Callback */
NULL, /* Breathing Callback */
{ /* Default all channels to disabled - Channels will be configured durring init */
{PWM_OUTPUT_DISABLED, NULL},
{PWM_OUTPUT_DISABLED, NULL},
@@ -32,17 +47,6 @@ static PWMConfig pwmCFG = {0xFFFF, /* PWM clock frequency */
0, /* HW dependent part.*/
0};
static PWMConfig pwmCFG_breathing = {0xFFFF, /** PWM clock frequency */
256, /* PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */
breathing_callback, /* Breathing Callback */
{ /* Default all channels to disabled - Channels will be configured durring init */
{PWM_OUTPUT_DISABLED, NULL},
{PWM_OUTPUT_DISABLED, NULL},
{PWM_OUTPUT_DISABLED, NULL},
{PWM_OUTPUT_DISABLED, NULL}},
0, /* HW dependent part.*/
0};
// See http://jared.geek.nz/2013/feb/linear-led-pwm
static uint16_t cie_lightness(uint16_t v) {
if (v <= 5243) // if below 8% of max
@@ -59,126 +63,94 @@ static uint16_t cie_lightness(uint16_t v) {
}
}
static uint32_t rescale_limit_val(uint32_t val) {
// rescale the supplied backlight value to be in terms of the value limit
return (val * (BACKLIGHT_LIMIT_VAL + 1)) / 256;
}
void backlight_init_ports(void) {
// printf("backlight_init_ports()\n");
# ifdef USE_GPIOV1
#ifdef USE_GPIOV1
palSetPadMode(PAL_PORT(BACKLIGHT_PIN), PAL_PAD(BACKLIGHT_PIN), PAL_MODE_STM32_ALTERNATE_PUSHPULL);
# else
#else
palSetPadMode(PAL_PORT(BACKLIGHT_PIN), PAL_PAD(BACKLIGHT_PIN), PAL_MODE_ALTERNATE(BACKLIGHT_PAL_MODE));
# endif
#endif
pwmCFG.channels[BACKLIGHT_PWM_CHANNEL - 1].mode = PWM_OUTPUT_ACTIVE_HIGH;
pwmCFG_breathing.channels[BACKLIGHT_PWM_CHANNEL - 1].mode = PWM_OUTPUT_ACTIVE_HIGH;
pwmCFG.channels[BACKLIGHT_PWM_CHANNEL - 1].mode = PWM_OUTPUT_MODE;
pwmStart(&BACKLIGHT_PWM_DRIVER, &pwmCFG);
backlight_set(get_backlight_level());
#ifdef BACKLIGHT_BREATHING
if (is_backlight_breathing()) {
breathing_enable();
}
#endif
}
void backlight_set(uint8_t level) {
// printf("backlight_set(%d)\n", level);
if (level > BACKLIGHT_LEVELS) level = BACKLIGHT_LEVELS;
if (level == 0) {
// Turn backlight off
pwmDisableChannel(&BACKLIGHT_PWM_DRIVER, BACKLIGHT_PWM_CHANNEL - 1);
} else {
// Turn backlight on
if (!is_breathing()) {
uint32_t duty = (uint32_t)(cie_lightness(0xFFFF * (uint32_t)level / BACKLIGHT_LEVELS));
// printf("duty: (%d)\n", duty);
pwmEnableChannel(&BACKLIGHT_PWM_DRIVER, BACKLIGHT_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&BACKLIGHT_PWM_DRIVER, 0xFFFF, duty));
}
uint32_t duty = (uint32_t)(cie_lightness(rescale_limit_val(0xFFFF * (uint32_t)level / BACKLIGHT_LEVELS)));
pwmEnableChannel(&BACKLIGHT_PWM_DRIVER, BACKLIGHT_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&BACKLIGHT_PWM_DRIVER, 0xFFFF, duty));
}
}
uint8_t backlight_tick = 0;
void backlight_task(void) {}
# define BREATHING_NO_HALT 0
# define BREATHING_HALT_OFF 1
# define BREATHING_HALT_ON 2
#ifdef BACKLIGHT_BREATHING
# define BREATHING_STEPS 128
static uint8_t breathing_halt = BREATHING_NO_HALT;
static uint16_t breathing_counter = 0;
bool is_breathing(void) { return BACKLIGHT_PWM_DRIVER.config == &pwmCFG_breathing; }
static inline void breathing_min(void) { breathing_counter = 0; }
static inline void breathing_max(void) { breathing_counter = get_breathing_period() * 256 / 2; }
void breathing_interrupt_enable(void) {
pwmStop(&BACKLIGHT_PWM_DRIVER);
pwmStart(&BACKLIGHT_PWM_DRIVER, &pwmCFG_breathing);
chSysLockFromISR();
pwmEnablePeriodicNotification(&BACKLIGHT_PWM_DRIVER);
pwmEnableChannelI(&BACKLIGHT_PWM_DRIVER, BACKLIGHT_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&BACKLIGHT_PWM_DRIVER, 0xFFFF, 0xFFFF));
chSysUnlockFromISR();
}
void breathing_interrupt_disable(void) {
pwmStop(&BACKLIGHT_PWM_DRIVER);
pwmStart(&BACKLIGHT_PWM_DRIVER, &pwmCFG);
}
void breathing_enable(void) {
breathing_counter = 0;
breathing_halt = BREATHING_NO_HALT;
breathing_interrupt_enable();
}
void breathing_pulse(void) {
if (get_backlight_level() == 0)
breathing_min();
else
breathing_max();
breathing_halt = BREATHING_HALT_ON;
breathing_interrupt_enable();
}
void breathing_disable(void) {
// printf("breathing_disable()\n");
breathing_interrupt_disable();
// Restore backlight level
backlight_set(get_backlight_level());
}
void breathing_self_disable(void) {
if (get_backlight_level() == 0)
breathing_halt = BREATHING_HALT_OFF;
else
breathing_halt = BREATHING_HALT_ON;
}
/* To generate breathing curve in python:
* from math import sin, pi; [int(sin(x/128.0*pi)**4*255) for x in range(128)]
*/
static const uint8_t breathing_table[BREATHING_STEPS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 17, 20, 24, 28, 32, 36, 41, 46, 51, 57, 63, 70, 76, 83, 91, 98, 106, 113, 121, 129, 138, 146, 154, 162, 170, 178, 185, 193, 200, 207, 213, 220, 225, 231, 235, 240, 244, 247, 250, 252, 253, 254, 255, 254, 253, 252, 250, 247, 244, 240, 235, 231, 225, 220, 213, 207, 200, 193, 185, 178, 170, 162, 154, 146, 138, 129, 121, 113, 106, 98, 91, 83, 76, 70, 63, 57, 51, 46, 41, 36, 32, 28, 24, 20, 17, 15, 12, 10, 8, 6, 5, 4, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
void breathing_callback(PWMDriver *pwmp);
bool is_breathing(void) { return pwmCFG.callback != NULL; }
void breathing_enable(void) {
pwmCFG.callback = breathing_callback;
pwmEnablePeriodicNotification(&BACKLIGHT_PWM_DRIVER);
}
void breathing_disable(void) {
pwmCFG.callback = NULL;
pwmDisablePeriodicNotification(&BACKLIGHT_PWM_DRIVER);
// Restore backlight level
backlight_set(get_backlight_level());
}
// Use this before the cie_lightness function.
static inline uint16_t scale_backlight(uint16_t v) { return v / BACKLIGHT_LEVELS * get_backlight_level(); }
static void breathing_callback(PWMDriver *pwmp) {
(void)pwmp;
void breathing_callback(PWMDriver *pwmp) {
uint8_t breathing_period = get_breathing_period();
uint16_t interval = (uint16_t)breathing_period * 256 / BREATHING_STEPS;
// resetting after one period to prevent ugly reset at overflow.
breathing_counter = (breathing_counter + 1) % (breathing_period * 256);
uint8_t index = breathing_counter / interval % BREATHING_STEPS;
if (((breathing_halt == BREATHING_HALT_ON) && (index == BREATHING_STEPS / 2)) || ((breathing_halt == BREATHING_HALT_OFF) && (index == BREATHING_STEPS - 1))) {
breathing_interrupt_disable();
}
uint32_t duty = cie_lightness(scale_backlight(breathing_table[index] * 256));
static uint16_t breathing_counter = 0;
breathing_counter = (breathing_counter + 1) % (breathing_period * 256);
uint8_t index = breathing_counter / interval % BREATHING_STEPS;
uint32_t duty = cie_lightness(rescale_limit_val(scale_backlight(breathing_table[index] * 256)));
chSysLockFromISR();
pwmEnableChannelI(&BACKLIGHT_PWM_DRIVER, BACKLIGHT_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&BACKLIGHT_PWM_DRIVER, 0xFFFF, duty));
pwmEnableChannelI(pwmp, BACKLIGHT_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&BACKLIGHT_PWM_DRIVER, 0xFFFF, duty));
chSysUnlockFromISR();
}
// TODO: integrate generic pulse solution
void breathing_pulse(void) {
backlight_set(is_backlight_enabled() ? 0 : BACKLIGHT_LEVELS);
wait_ms(10);
backlight_set(is_backlight_enabled() ? get_backlight_level() : 0);
}
#endif
+167
View File
@@ -0,0 +1,167 @@
#include "quantum.h"
#include "backlight.h"
#include "backlight_driver_common.h"
#include "debug.h"
#ifndef BACKLIGHT_GPT_DRIVER
# define BACKLIGHT_GPT_DRIVER GPTD15
#endif
// Platform specific implementations
static void backlight_timer_configure(bool enable);
static void backlight_timer_set_duty(uint16_t duty);
static uint16_t backlight_timer_get_duty(void);
// See http://jared.geek.nz/2013/feb/linear-led-pwm
static uint16_t cie_lightness(uint16_t v) {
if (v <= 5243) // if below 8% of max
return v / 9; // same as dividing by 900%
else {
uint32_t y = (((uint32_t)v + 10486) << 8) / (10486 + 0xFFFFUL); // add 16% of max and compare
// to get a useful result with integer division, we shift left in the expression above
// and revert what we've done again after squaring.
y = y * y * y >> 8;
if (y > 0xFFFFUL) // prevent overflow
return 0xFFFFU;
else
return (uint16_t)y;
}
}
void backlight_init_ports(void) {
backlight_pins_init();
backlight_set(get_backlight_level());
#ifdef BACKLIGHT_BREATHING
if (is_backlight_breathing()) {
breathing_enable();
}
#endif
}
void backlight_set(uint8_t level) {
if (level > BACKLIGHT_LEVELS) level = BACKLIGHT_LEVELS;
backlight_pins_off();
backlight_timer_set_duty(cie_lightness(0xFFFFU / BACKLIGHT_LEVELS * level));
backlight_timer_configure(level != 0);
}
static void backlight_timer_top(void) {
#ifdef BACKLIGHT_BREATHING
if (is_breathing()) {
breathing_task();
}
#endif
if (backlight_timer_get_duty() > 256) {
backlight_pins_on();
}
}
static void backlight_timer_cmp(void) { backlight_pins_off(); }
void backlight_task(void) {}
#ifdef BACKLIGHT_BREATHING
# define BREATHING_STEPS 128
static bool breathing = false;
static uint16_t breathing_counter = 0;
/* To generate breathing curve in python:
* from math import sin, pi; [int(sin(x/128.0*pi)**4*255) for x in range(128)]
*/
static const uint8_t breathing_table[BREATHING_STEPS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 17, 20, 24, 28, 32, 36, 41, 46, 51, 57, 63, 70, 76, 83, 91, 98, 106, 113, 121, 129, 138, 146, 154, 162, 170, 178, 185, 193, 200, 207, 213, 220, 225, 231, 235, 240, 244, 247, 250, 252, 253, 254, 255, 254, 253, 252, 250, 247, 244, 240, 235, 231, 225, 220, 213, 207, 200, 193, 185, 178, 170, 162, 154, 146, 138, 129, 121, 113, 106, 98, 91, 83, 76, 70, 63, 57, 51, 46, 41, 36, 32, 28, 24, 20, 17, 15, 12, 10, 8, 6, 5, 4, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
// Use this before the cie_lightness function.
static inline uint16_t scale_backlight(uint16_t v) { return v / BACKLIGHT_LEVELS * get_backlight_level(); }
void breathing_task(void) {
uint8_t breathing_period = get_breathing_period();
uint16_t interval = (uint16_t)breathing_period * 256 / BREATHING_STEPS;
// resetting after one period to prevent ugly reset at overflow.
breathing_counter = (breathing_counter + 1) % (breathing_period * 256);
uint8_t index = breathing_counter / interval % BREATHING_STEPS;
// printf("index:%u\n", index);
backlight_timer_set_duty(cie_lightness(scale_backlight((uint16_t)breathing_table[index] * 256)));
}
bool is_breathing(void) { return breathing; }
void breathing_enable(void) {
breathing_counter = 0;
breathing = true;
}
void breathing_disable(void) { breathing = false; }
void breathing_pulse(void) {
backlight_set(is_backlight_enabled() ? 0 : BACKLIGHT_LEVELS);
wait_ms(10);
backlight_set(is_backlight_enabled() ? get_backlight_level() : 0);
}
#endif
#ifdef PROTOCOL_CHIBIOS
// On Platforms where timers fire every tick and have no capture/top events
// - fake event in the normal timer callback
uint16_t s_duty = 0;
static void timerCallback(void) {
/* Software PWM
* timer:1111 1111 1111 1111
* \______/| \_______/____ count(0-255)
* \ \______________ unused(1)
* \__________________ index of step table(0-127)
*/
// this works for cca 65536 irqs/sec
static union {
uint16_t raw;
struct {
uint16_t count : 8;
uint8_t dummy : 1;
uint8_t index : 7;
} pwm;
} timer = {.raw = 0};
timer.raw++;
if (timer.pwm.count == 0) {
// LED on
backlight_timer_top();
} else if (timer.pwm.count == (s_duty / 256)) {
// LED off
backlight_timer_cmp();
}
}
static void backlight_timer_set_duty(uint16_t duty) { s_duty = duty; }
static uint16_t backlight_timer_get_duty(void) { return s_duty; }
// ChibiOS - Map GPT timer onto Software PWM
static void gptTimerCallback(GPTDriver *gptp) {
(void)gptp;
timerCallback();
}
static void backlight_timer_configure(bool enable) {
static const GPTConfig gptcfg = {1000000, gptTimerCallback, 0, 0};
static bool s_init = false;
if (!s_init) {
gptStart(&BACKLIGHT_GPT_DRIVER, &gptcfg);
s_init = true;
}
if (enable) {
gptStartContinuous(&BACKLIGHT_GPT_DRIVER, gptcfg.frequency / 0xFFFF);
} else {
gptStopTimer(&BACKLIGHT_GPT_DRIVER);
}
}
#endif
+123
View File
@@ -0,0 +1,123 @@
/*
Copyright 2011 Jun Wako <wakojun@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 "util.h"
// bit population - return number of on-bit
__attribute__((noinline)) uint8_t bitpop(uint8_t bits) {
uint8_t c;
for (c = 0; bits; c++) bits &= bits - 1;
return c;
/*
const uint8_t bit_count[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
return bit_count[bits>>4] + bit_count[bits&0x0F]
*/
}
uint8_t bitpop16(uint16_t bits) {
uint8_t c;
for (c = 0; bits; c++) bits &= bits - 1;
return c;
}
uint8_t bitpop32(uint32_t bits) {
uint8_t c;
for (c = 0; bits; c++) bits &= bits - 1;
return c;
}
// most significant on-bit - return highest location of on-bit
// NOTE: return 0 when bit0 is on or all bits are off
__attribute__((noinline)) uint8_t biton(uint8_t bits) {
uint8_t n = 0;
if (bits >> 4) {
bits >>= 4;
n += 4;
}
if (bits >> 2) {
bits >>= 2;
n += 2;
}
if (bits >> 1) {
bits >>= 1;
n += 1;
}
return n;
}
uint8_t biton16(uint16_t bits) {
uint8_t n = 0;
if (bits >> 8) {
bits >>= 8;
n += 8;
}
if (bits >> 4) {
bits >>= 4;
n += 4;
}
if (bits >> 2) {
bits >>= 2;
n += 2;
}
if (bits >> 1) {
bits >>= 1;
n += 1;
}
return n;
}
uint8_t biton32(uint32_t bits) {
uint8_t n = 0;
if (bits >> 16) {
bits >>= 16;
n += 16;
}
if (bits >> 8) {
bits >>= 8;
n += 8;
}
if (bits >> 4) {
bits >>= 4;
n += 4;
}
if (bits >> 2) {
bits >>= 2;
n += 2;
}
if (bits >> 1) {
bits >>= 1;
n += 1;
}
return n;
}
__attribute__((noinline)) uint8_t bitrev(uint8_t bits) {
bits = (bits & 0x0f) << 4 | (bits & 0xf0) >> 4;
bits = (bits & 0b00110011) << 2 | (bits & 0b11001100) >> 2;
bits = (bits & 0b01010101) << 1 | (bits & 0b10101010) >> 1;
return bits;
}
uint16_t bitrev16(uint16_t bits) {
bits = bitrev(bits & 0x00ff) << 8 | bitrev((bits & 0xff00) >> 8);
return bits;
}
uint32_t bitrev32(uint32_t bits) {
bits = (uint32_t)bitrev16(bits & 0x0000ffff) << 16 | bitrev16((bits & 0xffff0000) >> 16);
return bits;
}
+40
View File
@@ -0,0 +1,40 @@
/*
Copyright 2011 Jun Wako <wakojun@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
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
uint8_t bitpop(uint8_t bits);
uint8_t bitpop16(uint16_t bits);
uint8_t bitpop32(uint32_t bits);
uint8_t biton(uint8_t bits);
uint8_t biton16(uint16_t bits);
uint8_t biton32(uint32_t bits);
uint8_t bitrev(uint8_t bits);
uint16_t bitrev16(uint16_t bits);
uint32_t bitrev32(uint32_t bits);
#ifdef __cplusplus
}
#endif
+23 -3
View File
@@ -18,14 +18,20 @@
#include "led_tables.h"
#include "progmem.h"
RGB hsv_to_rgb(HSV hsv) {
RGB hsv_to_rgb_impl(HSV hsv, bool use_cie) {
RGB rgb;
uint8_t region, remainder, p, q, t;
uint16_t h, s, v;
if (hsv.s == 0) {
#ifdef USE_CIE1931_CURVE
rgb.r = rgb.g = rgb.b = pgm_read_byte(&CIE1931_CURVE[hsv.v]);
if (use_cie) {
rgb.r = rgb.g = rgb.b = pgm_read_byte(&CIE1931_CURVE[hsv.v]);
} else {
rgb.r = hsv.v;
rgb.g = hsv.v;
rgb.b = hsv.v;
}
#else
rgb.r = hsv.v;
rgb.g = hsv.v;
@@ -37,7 +43,11 @@ RGB hsv_to_rgb(HSV hsv) {
h = hsv.h;
s = hsv.s;
#ifdef USE_CIE1931_CURVE
v = pgm_read_byte(&CIE1931_CURVE[hsv.v]);
if (use_cie) {
v = pgm_read_byte(&CIE1931_CURVE[hsv.v]);
} else {
v = hsv.v;
}
#else
v = hsv.v;
#endif
@@ -86,6 +96,16 @@ RGB hsv_to_rgb(HSV hsv) {
return rgb;
}
RGB hsv_to_rgb(HSV hsv) {
#ifdef USE_CIE1931_CURVE
return hsv_to_rgb_impl(hsv, true);
#else
return hsv_to_rgb_impl(hsv, false);
#endif
}
RGB hsv_to_rgb_nocie(HSV hsv) { return hsv_to_rgb_impl(hsv, false); }
#ifdef RGBW
# ifndef MIN
# define MIN(a, b) ((a) < (b) ? (a) : (b))
+30 -4
View File
@@ -14,8 +14,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef COLOR_H
#define COLOR_H
#pragma once
#include <stdint.h>
#include <stdbool.h>
@@ -36,20 +35,47 @@
# define LED_TYPE RGB
#endif
// WS2812 specific layout
#define WS2812_BYTE_ORDER_RGB 0
#define WS2812_BYTE_ORDER_GRB 1
#define WS2812_BYTE_ORDER_BGR 2
#ifndef WS2812_BYTE_ORDER
# define WS2812_BYTE_ORDER WS2812_BYTE_ORDER_GRB
#endif
typedef struct PACKED {
#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
uint8_t g;
uint8_t r;
uint8_t b;
#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
uint8_t r;
uint8_t g;
uint8_t b;
#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR)
uint8_t b;
uint8_t g;
uint8_t r;
#endif
} cRGB;
typedef cRGB RGB;
// WS2812 specific layout
typedef struct PACKED {
#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
uint8_t g;
uint8_t r;
uint8_t b;
#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
uint8_t r;
uint8_t g;
uint8_t b;
#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR)
uint8_t b;
uint8_t g;
uint8_t r;
#endif
uint8_t w;
} cRGBW;
@@ -64,7 +90,7 @@ typedef struct PACKED {
#endif
RGB hsv_to_rgb(HSV hsv);
RGB hsv_to_rgb_nocie(HSV hsv);
#ifdef RGBW
void convert_rgb_to_rgbw(LED_TYPE *led);
#endif
#endif // COLOR_H
+786
View File
@@ -0,0 +1,786 @@
/*
Copyright 2011 Jun Wako <wakojun@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 <stdint.h>
#include <stdbool.h>
#include "wait.h"
#include "keycode.h"
#include "host.h"
#include "keymap.h"
#include "print.h"
#include "debug.h"
#include "util.h"
#include "timer.h"
#include "keyboard.h"
#include "bootloader.h"
#include "action_layer.h"
#include "action_util.h"
#include "eeconfig.h"
#include "sleep_led.h"
#include "led.h"
#include "command.h"
#include "quantum.h"
#include "version.h"
#ifdef BACKLIGHT_ENABLE
# include "backlight.h"
#endif
#if defined(MOUSEKEY_ENABLE) && !defined(MK_3_SPEED)
# include "mousekey.h"
#endif
#ifdef AUDIO_ENABLE
# include "audio.h"
#endif /* AUDIO_ENABLE */
static bool command_common(uint8_t code);
static void command_common_help(void);
static void print_version(void);
static void print_status(void);
static bool command_console(uint8_t code);
static void command_console_help(void);
#if defined(MOUSEKEY_ENABLE) && !defined(MK_3_SPEED)
static bool mousekey_console(uint8_t code);
static void mousekey_console_help(void);
#endif
static void switch_default_layer(uint8_t layer);
command_state_t command_state = ONESHOT;
bool command_proc(uint8_t code) {
switch (command_state) {
case ONESHOT:
if (!IS_COMMAND()) return false;
return (command_extra(code) || command_common(code));
break;
case CONSOLE:
if (IS_COMMAND())
return (command_extra(code) || command_common(code));
else
return (command_console_extra(code) || command_console(code));
break;
#if defined(MOUSEKEY_ENABLE) && !defined(MK_3_SPEED)
case MOUSEKEY:
mousekey_console(code);
break;
#endif
default:
command_state = ONESHOT;
return false;
}
return true;
}
/* TODO: Refactoring is needed. */
/* This allows to define extra commands. return false when not processed. */
bool command_extra(uint8_t code) __attribute__((weak));
bool command_extra(uint8_t code) {
(void)code;
return false;
}
bool command_console_extra(uint8_t code) __attribute__((weak));
bool command_console_extra(uint8_t code) {
(void)code;
return false;
}
/***********************************************************
* Command common
***********************************************************/
static void command_common_help(void) {
print("\n\t- Magic -\n" STR(MAGIC_KEY_DEBUG) ": Debug Message Toggle\n" STR(MAGIC_KEY_DEBUG_MATRIX) ": Matrix Debug Mode Toggle - Show keypresses in matrix grid\n" STR(MAGIC_KEY_DEBUG_KBD) ": Keyboard Debug Toggle - Show keypress report\n" STR(MAGIC_KEY_DEBUG_MOUSE) ": Debug Mouse Toggle\n" STR(MAGIC_KEY_VERSION) ": Version\n" STR(MAGIC_KEY_STATUS) ": Status\n" STR(MAGIC_KEY_CONSOLE) ": Activate Console Mode\n"
#if MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
STR(MAGIC_KEY_LAYER0) ": Switch to Layer 0\n" STR(MAGIC_KEY_LAYER1) ": Switch to Layer 1\n" STR(MAGIC_KEY_LAYER2) ": Switch to Layer 2\n" STR(MAGIC_KEY_LAYER3) ": Switch to Layer 3\n" STR(MAGIC_KEY_LAYER4) ": Switch to Layer 4\n" STR(MAGIC_KEY_LAYER5) ": Switch to Layer 5\n" STR(MAGIC_KEY_LAYER6) ": Switch to Layer 6\n" STR(MAGIC_KEY_LAYER7) ": Switch to Layer 7\n" STR(MAGIC_KEY_LAYER8) ": Switch to Layer 8\n" STR(MAGIC_KEY_LAYER9) ": Switch to Layer 9\n"
#endif
#if MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
"F1-F10: Switch to Layer 0-9 (F10 = L0)\n"
#endif
#if MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
"0-9: Switch to Layer 0-9\n"
#endif
STR(MAGIC_KEY_LAYER0_ALT) ": Switch to Layer 0 (alternate)\n"
STR(MAGIC_KEY_BOOTLOADER) ": Jump to Bootloader\n" STR(MAGIC_KEY_BOOTLOADER_ALT) ": Jump to Bootloader (alternate)\n"
#ifdef KEYBOARD_LOCK_ENABLE
STR(MAGIC_KEY_LOCK) ": Lock Keyboard\n"
#endif
STR(MAGIC_KEY_EEPROM) ": Print EEPROM Settings\n" STR(MAGIC_KEY_EEPROM_CLEAR) ": Clear EEPROM\n"
#ifdef NKRO_ENABLE
STR(MAGIC_KEY_NKRO) ": NKRO Toggle\n"
#endif
#ifdef SLEEP_LED_ENABLE
STR(MAGIC_KEY_SLEEP_LED) ": Sleep LED Test\n"
#endif
);
}
static void print_version(void) {
// print version & information
print("\n\t- Version -\n");
print("VID: " STR(VENDOR_ID) "(" STR(MANUFACTURER) ") "
"PID: " STR(PRODUCT_ID) "(" STR(PRODUCT) ") "
"VER: " STR(DEVICE_VER) "\n");
print("BUILD: (" __DATE__ ")\n");
#ifndef SKIP_VERSION
# ifdef PROTOCOL_CHIBIOS
print("CHIBIOS: " STR(CHIBIOS_VERSION) ", CONTRIB: " STR(CHIBIOS_CONTRIB_VERSION) "\n");
# endif
#endif
/* build options */
print("OPTIONS:"
#ifdef PROTOCOL_LUFA
" LUFA"
#endif
#ifdef PROTOCOL_VUSB
" VUSB"
#endif
#ifdef BOOTMAGIC_ENABLE
" BOOTMAGIC"
#endif
#ifdef MOUSEKEY_ENABLE
" MOUSEKEY"
#endif
#ifdef EXTRAKEY_ENABLE
" EXTRAKEY"
#endif
#ifdef CONSOLE_ENABLE
" CONSOLE"
#endif
#ifdef COMMAND_ENABLE
" COMMAND"
#endif
#ifdef NKRO_ENABLE
" NKRO"
#endif
#ifdef LTO_ENABLE
" LTO"
#endif
" " STR(BOOTLOADER_SIZE) "\n");
print("GCC: " STR(__GNUC__) "." STR(__GNUC_MINOR__) "." STR(__GNUC_PATCHLEVEL__)
#if defined(__AVR__)
" AVR-LIBC: " __AVR_LIBC_VERSION_STRING__ " AVR_ARCH: avr" STR(__AVR_ARCH__)
#endif
"\n");
return;
}
static void print_status(void) {
print("\n\t- Status -\n");
print_val_hex8(host_keyboard_leds());
#ifndef PROTOCOL_VUSB
// these aren't set on the V-USB protocol, so we just ignore them for now
print_val_hex8(keyboard_protocol);
print_val_hex8(keyboard_idle);
#endif
#ifdef NKRO_ENABLE
print_val_hex8(keymap_config.nkro);
#endif
print_val_hex32(timer_read32());
return;
}
static void print_eeconfig(void) {
// Print these variables if NO_PRINT or USER_PRINT are not defined.
#if !defined(NO_PRINT) && !defined(USER_PRINT)
print("default_layer: ");
print_dec(eeconfig_read_default_layer());
print("\n");
debug_config_t dc;
dc.raw = eeconfig_read_debug();
print("debug_config.raw: ");
print_hex8(dc.raw);
print("\n");
print(".enable: ");
print_dec(dc.enable);
print("\n");
print(".matrix: ");
print_dec(dc.matrix);
print("\n");
print(".keyboard: ");
print_dec(dc.keyboard);
print("\n");
print(".mouse: ");
print_dec(dc.mouse);
print("\n");
keymap_config_t kc;
kc.raw = eeconfig_read_keymap();
print("keymap_config.raw: ");
print_hex8(kc.raw);
print("\n");
print(".swap_control_capslock: ");
print_dec(kc.swap_control_capslock);
print("\n");
print(".capslock_to_control: ");
print_dec(kc.capslock_to_control);
print("\n");
print(".swap_lctl_lgui: ");
print_dec(kc.swap_lctl_lgui);
print("\n");
print(".swap_rctl_rgui: ");
print_dec(kc.swap_rctl_rgui);
print("\n");
print(".swap_lalt_lgui: ");
print_dec(kc.swap_lalt_lgui);
print("\n");
print(".swap_ralt_rgui: ");
print_dec(kc.swap_ralt_rgui);
print("\n");
print(".no_gui: ");
print_dec(kc.no_gui);
print("\n");
print(".swap_grave_esc: ");
print_dec(kc.swap_grave_esc);
print("\n");
print(".swap_backslash_backspace: ");
print_dec(kc.swap_backslash_backspace);
print("\n");
print(".nkro: ");
print_dec(kc.nkro);
print("\n");
# ifdef BACKLIGHT_ENABLE
backlight_config_t bc;
bc.raw = eeconfig_read_backlight();
print("backlight_config.raw: ");
print_hex8(bc.raw);
print("\n");
print(".enable: ");
print_dec(bc.enable);
print("\n");
print(".level: ");
print_dec(bc.level);
print("\n");
# endif /* BACKLIGHT_ENABLE */
#endif /* !NO_PRINT */
}
static bool command_common(uint8_t code) {
#ifdef KEYBOARD_LOCK_ENABLE
static host_driver_t *host_driver = 0;
#endif
switch (code) {
#ifdef SLEEP_LED_ENABLE
// test breathing sleep LED
case MAGIC_KC(MAGIC_KEY_SLEEP_LED):
print("Sleep LED Test\n");
sleep_led_toggle();
led_set(host_keyboard_leds());
break;
#endif
// print stored eeprom config
case MAGIC_KC(MAGIC_KEY_EEPROM):
print("eeconfig:\n");
print_eeconfig();
break;
// clear eeprom
case MAGIC_KC(MAGIC_KEY_EEPROM_CLEAR):
print("Clearing EEPROM\n");
eeconfig_init();
break;
#ifdef KEYBOARD_LOCK_ENABLE
// lock/unlock keyboard
case MAGIC_KC(MAGIC_KEY_LOCK):
if (host_get_driver()) {
host_driver = host_get_driver();
clear_keyboard();
host_set_driver(0);
print("Locked.\n");
} else {
host_set_driver(host_driver);
print("Unlocked.\n");
}
break;
#endif
// print help
case MAGIC_KC(MAGIC_KEY_HELP):
case MAGIC_KC(MAGIC_KEY_HELP_ALT):
command_common_help();
break;
// activate console
case MAGIC_KC(MAGIC_KEY_CONSOLE):
debug_matrix = false;
debug_keyboard = false;
debug_mouse = false;
debug_enable = false;
command_console_help();
print("C> ");
command_state = CONSOLE;
break;
// jump to bootloader
case MAGIC_KC(MAGIC_KEY_BOOTLOADER):
case MAGIC_KC(MAGIC_KEY_BOOTLOADER_ALT):
print("\n\nJumping to bootloader... ");
reset_keyboard();
break;
// debug toggle
case MAGIC_KC(MAGIC_KEY_DEBUG):
debug_enable = !debug_enable;
if (debug_enable) {
print("\ndebug: on\n");
} else {
print("\ndebug: off\n");
debug_matrix = false;
debug_keyboard = false;
debug_mouse = false;
}
break;
// debug matrix toggle
case MAGIC_KC(MAGIC_KEY_DEBUG_MATRIX):
debug_matrix = !debug_matrix;
if (debug_matrix) {
print("\nmatrix: on\n");
debug_enable = true;
} else {
print("\nmatrix: off\n");
}
break;
// debug keyboard toggle
case MAGIC_KC(MAGIC_KEY_DEBUG_KBD):
debug_keyboard = !debug_keyboard;
if (debug_keyboard) {
print("\nkeyboard: on\n");
debug_enable = true;
} else {
print("\nkeyboard: off\n");
}
break;
// debug mouse toggle
case MAGIC_KC(MAGIC_KEY_DEBUG_MOUSE):
debug_mouse = !debug_mouse;
if (debug_mouse) {
print("\nmouse: on\n");
debug_enable = true;
} else {
print("\nmouse: off\n");
}
break;
// print version
case MAGIC_KC(MAGIC_KEY_VERSION):
print_version();
break;
// print status
case MAGIC_KC(MAGIC_KEY_STATUS):
print_status();
break;
#ifdef NKRO_ENABLE
// NKRO toggle
case MAGIC_KC(MAGIC_KEY_NKRO):
clear_keyboard(); // clear to prevent stuck keys
keymap_config.nkro = !keymap_config.nkro;
if (keymap_config.nkro) {
print("NKRO: on\n");
} else {
print("NKRO: off\n");
}
break;
#endif
// switch layers
case MAGIC_KC(MAGIC_KEY_LAYER0_ALT):
switch_default_layer(0);
break;
#if MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
case MAGIC_KC(MAGIC_KEY_LAYER0):
switch_default_layer(0);
break;
case MAGIC_KC(MAGIC_KEY_LAYER1):
switch_default_layer(1);
break;
case MAGIC_KC(MAGIC_KEY_LAYER2):
switch_default_layer(2);
break;
case MAGIC_KC(MAGIC_KEY_LAYER3):
switch_default_layer(3);
break;
case MAGIC_KC(MAGIC_KEY_LAYER4):
switch_default_layer(4);
break;
case MAGIC_KC(MAGIC_KEY_LAYER5):
switch_default_layer(5);
break;
case MAGIC_KC(MAGIC_KEY_LAYER6):
switch_default_layer(6);
break;
case MAGIC_KC(MAGIC_KEY_LAYER7):
switch_default_layer(7);
break;
case MAGIC_KC(MAGIC_KEY_LAYER8):
switch_default_layer(8);
break;
case MAGIC_KC(MAGIC_KEY_LAYER9):
switch_default_layer(9);
break;
#endif
#if MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
case KC_F1 ... KC_F9:
switch_default_layer((code - KC_F1) + 1);
break;
case KC_F10:
switch_default_layer(0);
break;
#endif
#if MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
case KC_1 ... KC_9:
switch_default_layer((code - KC_1) + 1);
break;
case KC_0:
switch_default_layer(0);
break;
#endif
default:
print("?");
return false;
}
return true;
}
/***********************************************************
* Command console
***********************************************************/
static void command_console_help(void) {
print("\n\t- Console -\n"
"ESC/q: quit\n"
#ifdef MOUSEKEY_ENABLE
"m: mousekey\n"
#endif
);
}
static bool command_console(uint8_t code) {
switch (code) {
case KC_H:
case KC_SLASH: /* ? */
command_console_help();
break;
case KC_Q:
case KC_ESC:
command_state = ONESHOT;
return false;
#if defined(MOUSEKEY_ENABLE) && !defined(MK_3_SPEED)
case KC_M:
mousekey_console_help();
print("M> ");
command_state = MOUSEKEY;
return true;
#endif
default:
print("?");
return false;
}
print("C> ");
return true;
}
#if defined(MOUSEKEY_ENABLE) && !defined(MK_3_SPEED)
/***********************************************************
* Mousekey console
***********************************************************/
static uint8_t mousekey_param = 0;
static void mousekey_param_print(void) {
// Print these variables if NO_PRINT or USER_PRINT are not defined.
# if !defined(NO_PRINT) && !defined(USER_PRINT)
print("\n\t- Values -\n");
print("1: delay(*10ms): ");
pdec(mk_delay);
print("\n");
print("2: interval(ms): ");
pdec(mk_interval);
print("\n");
print("3: max_speed: ");
pdec(mk_max_speed);
print("\n");
print("4: time_to_max: ");
pdec(mk_time_to_max);
print("\n");
print("5: wheel_max_speed: ");
pdec(mk_wheel_max_speed);
print("\n");
print("6: wheel_time_to_max: ");
pdec(mk_wheel_time_to_max);
print("\n");
# endif /* !NO_PRINT */
}
//#define PRINT_SET_VAL(v) print(#v " = "); print_dec(v); print("\n");
# define PRINT_SET_VAL(v) xprintf(# v " = %d\n", (v))
static void mousekey_param_inc(uint8_t param, uint8_t inc) {
switch (param) {
case 1:
if (mk_delay + inc < UINT8_MAX)
mk_delay += inc;
else
mk_delay = UINT8_MAX;
PRINT_SET_VAL(mk_delay);
break;
case 2:
if (mk_interval + inc < UINT8_MAX)
mk_interval += inc;
else
mk_interval = UINT8_MAX;
PRINT_SET_VAL(mk_interval);
break;
case 3:
if (mk_max_speed + inc < UINT8_MAX)
mk_max_speed += inc;
else
mk_max_speed = UINT8_MAX;
PRINT_SET_VAL(mk_max_speed);
break;
case 4:
if (mk_time_to_max + inc < UINT8_MAX)
mk_time_to_max += inc;
else
mk_time_to_max = UINT8_MAX;
PRINT_SET_VAL(mk_time_to_max);
break;
case 5:
if (mk_wheel_max_speed + inc < UINT8_MAX)
mk_wheel_max_speed += inc;
else
mk_wheel_max_speed = UINT8_MAX;
PRINT_SET_VAL(mk_wheel_max_speed);
break;
case 6:
if (mk_wheel_time_to_max + inc < UINT8_MAX)
mk_wheel_time_to_max += inc;
else
mk_wheel_time_to_max = UINT8_MAX;
PRINT_SET_VAL(mk_wheel_time_to_max);
break;
}
}
static void mousekey_param_dec(uint8_t param, uint8_t dec) {
switch (param) {
case 1:
if (mk_delay > dec)
mk_delay -= dec;
else
mk_delay = 0;
PRINT_SET_VAL(mk_delay);
break;
case 2:
if (mk_interval > dec)
mk_interval -= dec;
else
mk_interval = 0;
PRINT_SET_VAL(mk_interval);
break;
case 3:
if (mk_max_speed > dec)
mk_max_speed -= dec;
else
mk_max_speed = 0;
PRINT_SET_VAL(mk_max_speed);
break;
case 4:
if (mk_time_to_max > dec)
mk_time_to_max -= dec;
else
mk_time_to_max = 0;
PRINT_SET_VAL(mk_time_to_max);
break;
case 5:
if (mk_wheel_max_speed > dec)
mk_wheel_max_speed -= dec;
else
mk_wheel_max_speed = 0;
PRINT_SET_VAL(mk_wheel_max_speed);
break;
case 6:
if (mk_wheel_time_to_max > dec)
mk_wheel_time_to_max -= dec;
else
mk_wheel_time_to_max = 0;
PRINT_SET_VAL(mk_wheel_time_to_max);
break;
}
}
static void mousekey_console_help(void) {
print("\n\t- Mousekey -\n"
"ESC/q: quit\n"
"1: delay(*10ms)\n"
"2: interval(ms)\n"
"3: max_speed\n"
"4: time_to_max\n"
"5: wheel_max_speed\n"
"6: wheel_time_to_max\n"
"\n"
"p: print values\n"
"d: set defaults\n"
"up: +1\n"
"down: -1\n"
"pgup: +10\n"
"pgdown: -10\n"
"\n"
"speed = delta * max_speed * (repeat / time_to_max)\n");
xprintf("where delta: cursor=%d, wheel=%d\n"
"See http://en.wikipedia.org/wiki/Mouse_keys\n",
MOUSEKEY_MOVE_DELTA, MOUSEKEY_WHEEL_DELTA);
}
static bool mousekey_console(uint8_t code) {
switch (code) {
case KC_H:
case KC_SLASH: /* ? */
mousekey_console_help();
break;
case KC_Q:
case KC_ESC:
if (mousekey_param) {
mousekey_param = 0;
} else {
print("C> ");
command_state = CONSOLE;
return false;
}
break;
case KC_P:
mousekey_param_print();
break;
case KC_1:
case KC_2:
case KC_3:
case KC_4:
case KC_5:
case KC_6:
mousekey_param = numkey2num(code);
break;
case KC_UP:
mousekey_param_inc(mousekey_param, 1);
break;
case KC_DOWN:
mousekey_param_dec(mousekey_param, 1);
break;
case KC_PGUP:
mousekey_param_inc(mousekey_param, 10);
break;
case KC_PGDN:
mousekey_param_dec(mousekey_param, 10);
break;
case KC_D:
mk_delay = MOUSEKEY_DELAY / 10;
mk_interval = MOUSEKEY_INTERVAL;
mk_max_speed = MOUSEKEY_MAX_SPEED;
mk_time_to_max = MOUSEKEY_TIME_TO_MAX;
mk_wheel_max_speed = MOUSEKEY_WHEEL_MAX_SPEED;
mk_wheel_time_to_max = MOUSEKEY_WHEEL_TIME_TO_MAX;
print("set default\n");
break;
default:
print("?");
return false;
}
if (mousekey_param) {
xprintf("M%d> ", mousekey_param);
} else {
print("M>");
}
return true;
}
#endif
/***********************************************************
* Utilities
***********************************************************/
uint8_t numkey2num(uint8_t code) {
switch (code) {
case KC_1:
return 1;
case KC_2:
return 2;
case KC_3:
return 3;
case KC_4:
return 4;
case KC_5:
return 5;
case KC_6:
return 6;
case KC_7:
return 7;
case KC_8:
return 8;
case KC_9:
return 9;
case KC_0:
return 0;
}
return 0;
}
static void switch_default_layer(uint8_t layer) {
xprintf("L%d\n", layer);
default_layer_set(1UL << layer);
clear_keyboard();
}
+163
View File
@@ -0,0 +1,163 @@
/*
Copyright 2011 Jun Wako <wakojun@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
/* FIXME: Add doxygen comments for the behavioral defines in here. */
/* TODO: Refactoring */
typedef enum { ONESHOT, CONSOLE, MOUSEKEY } command_state_t;
extern command_state_t command_state;
/* This allows to extend commands. Return false when command is not processed. */
bool command_extra(uint8_t code);
bool command_console_extra(uint8_t code);
#ifdef COMMAND_ENABLE
uint8_t numkey2num(uint8_t code);
bool command_proc(uint8_t code);
#else
# define command_proc(code) false
#endif
#ifndef IS_COMMAND
# define IS_COMMAND() (get_mods() == MOD_MASK_SHIFT)
#endif
#ifndef MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
# define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true
#endif
#ifndef MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
# define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true
#endif
#ifndef MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
# define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
#endif
#ifndef MAGIC_KEY_HELP
# define MAGIC_KEY_HELP H
#endif
#ifndef MAGIC_KEY_HELP_ALT
# define MAGIC_KEY_HELP_ALT SLASH
#endif
#ifndef MAGIC_KEY_DEBUG
# define MAGIC_KEY_DEBUG D
#endif
#ifndef MAGIC_KEY_DEBUG_MATRIX
# define MAGIC_KEY_DEBUG_MATRIX X
#endif
#ifndef MAGIC_KEY_DEBUG_KBD
# define MAGIC_KEY_DEBUG_KBD K
#endif
#ifndef MAGIC_KEY_DEBUG_MOUSE
# define MAGIC_KEY_DEBUG_MOUSE M
#endif
#ifndef MAGIC_KEY_VERSION
# define MAGIC_KEY_VERSION V
#endif
#ifndef MAGIC_KEY_STATUS
# define MAGIC_KEY_STATUS S
#endif
#ifndef MAGIC_KEY_CONSOLE
# define MAGIC_KEY_CONSOLE C
#endif
#ifndef MAGIC_KEY_LAYER0
# define MAGIC_KEY_LAYER0 0
#endif
#ifndef MAGIC_KEY_LAYER0_ALT
# define MAGIC_KEY_LAYER0_ALT GRAVE
#endif
#ifndef MAGIC_KEY_LAYER1
# define MAGIC_KEY_LAYER1 1
#endif
#ifndef MAGIC_KEY_LAYER2
# define MAGIC_KEY_LAYER2 2
#endif
#ifndef MAGIC_KEY_LAYER3
# define MAGIC_KEY_LAYER3 3
#endif
#ifndef MAGIC_KEY_LAYER4
# define MAGIC_KEY_LAYER4 4
#endif
#ifndef MAGIC_KEY_LAYER5
# define MAGIC_KEY_LAYER5 5
#endif
#ifndef MAGIC_KEY_LAYER6
# define MAGIC_KEY_LAYER6 6
#endif
#ifndef MAGIC_KEY_LAYER7
# define MAGIC_KEY_LAYER7 7
#endif
#ifndef MAGIC_KEY_LAYER8
# define MAGIC_KEY_LAYER8 8
#endif
#ifndef MAGIC_KEY_LAYER9
# define MAGIC_KEY_LAYER9 9
#endif
#ifndef MAGIC_KEY_BOOTLOADER
# define MAGIC_KEY_BOOTLOADER B
#endif
#ifndef MAGIC_KEY_BOOTLOADER_ALT
# define MAGIC_KEY_BOOTLOADER_ALT ESC
#endif
#ifndef MAGIC_KEY_LOCK
# define MAGIC_KEY_LOCK CAPS
#endif
#ifndef MAGIC_KEY_EEPROM
# define MAGIC_KEY_EEPROM E
#endif
#ifndef MAGIC_KEY_EEPROM_CLEAR
# define MAGIC_KEY_EEPROM_CLEAR BSPACE
#endif
#ifndef MAGIC_KEY_NKRO
# define MAGIC_KEY_NKRO N
#endif
#ifndef MAGIC_KEY_SLEEP_LED
# define MAGIC_KEY_SLEEP_LED Z
#endif
#define XMAGIC_KC(key) KC_##key
#define MAGIC_KC(key) XMAGIC_KC(key)
+89 -52
View File
@@ -39,12 +39,12 @@
# define PIND_ADDRESS 0x9
# define PINE_ADDRESS 0xC
# define PINF_ADDRESS 0xF
# elif defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__)
# elif defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
# define ADDRESS_BASE 0x00
# define PINB_ADDRESS 0x3
# define PINC_ADDRESS 0x6
# define PIND_ADDRESS 0x9
# elif defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__)
# elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
# define ADDRESS_BASE 0x00
# define PINA_ADDRESS 0x0
# define PINB_ADDRESS 0x3
@@ -58,11 +58,6 @@
# define PINC_ADDRESS 0x3
# define PINB_ADDRESS 0x6
# define PINA_ADDRESS 0x9
# elif defined(__AVR_ATmega328P__)
# define ADDRESS_BASE 0x00
# define PINB_ADDRESS 0x3
# define PINC_ADDRESS 0x6
# define PIND_ADDRESS 0x9
# elif defined(__AVR_ATtiny85__)
# define ADDRESS_BASE 0x10
# define PINB_ADDRESS 0x6
@@ -218,6 +213,8 @@
# define B15 PAL_LINE(GPIOB, 15)
# define B16 PAL_LINE(GPIOB, 16)
# define B17 PAL_LINE(GPIOB, 17)
# define B18 PAL_LINE(GPIOB, 18)
# define B19 PAL_LINE(GPIOB, 19)
# define C0 PAL_LINE(GPIOC, 0)
# define C1 PAL_LINE(GPIOC, 1)
# define C2 PAL_LINE(GPIOC, 2)
@@ -282,51 +279,91 @@
# define F13 PAL_LINE(GPIOF, 13)
# define F14 PAL_LINE(GPIOF, 14)
# define F15 PAL_LINE(GPIOF, 15)
# endif
#endif
/* USART configuration */
#ifdef BLUETOOTH_ENABLE
# ifdef __AVR_ATmega32U4__
# define SERIAL_UART_BAUD 9600
# define SERIAL_UART_DATA UDR1
# define SERIAL_UART_UBRR (F_CPU / (16UL * SERIAL_UART_BAUD) - 1)
# define SERIAL_UART_RXD_VECT USART1_RX_vect
# define SERIAL_UART_TXD_READY (UCSR1A & _BV(UDRE1))
# define SERIAL_UART_INIT() \
do { \
/* baud rate */ \
UBRR1L = SERIAL_UART_UBRR; \
/* baud rate */ \
UBRR1H = SERIAL_UART_UBRR >> 8; \
/* enable TX */ \
UCSR1B = _BV(TXEN1); \
/* 8-bit data */ \
UCSR1C = _BV(UCSZ11) | _BV(UCSZ10); \
sei(); \
} while (0)
# elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__))
# define SERIAL_UART_BAUD 115200
# define SERIAL_UART_DATA UDR1
/* UBRR should result in ~16 and set UCSR1A = _BV(U2X1) as per rn42 documentation. HC05 needs baudrate configured accordingly */
# define SERIAL_UART_UBRR (F_CPU / (8UL * SERIAL_UART_BAUD) - 1)
# define SERIAL_UART_RXD_VECT USART1_RX_vect
# define SERIAL_UART_TXD_READY (UCSR1A & _BV(UDRE1))
# define SERIAL_UART_INIT() \
do { \
UCSR1A = _BV(U2X1); \
/* baud rate */ \
UBRR1L = SERIAL_UART_UBRR; \
/* baud rate */ \
UBRR1H = SERIAL_UART_UBRR >> 8; \
/* enable TX */ \
UCSR1B = _BV(TXEN1); \
/* 8-bit data */ \
UCSR1C = _BV(UCSZ11) | _BV(UCSZ10); \
sei(); \
} while (0)
# else
# error "USART configuration is needed."
# define G0 PAL_LINE(GPIOG, 0)
# define G1 PAL_LINE(GPIOG, 1)
# define G2 PAL_LINE(GPIOG, 2)
# define G3 PAL_LINE(GPIOG, 3)
# define G4 PAL_LINE(GPIOG, 4)
# define G5 PAL_LINE(GPIOG, 5)
# define G6 PAL_LINE(GPIOG, 6)
# define G7 PAL_LINE(GPIOG, 7)
# define G8 PAL_LINE(GPIOG, 8)
# define G9 PAL_LINE(GPIOG, 9)
# define G10 PAL_LINE(GPIOG, 10)
# define G11 PAL_LINE(GPIOG, 11)
# define G12 PAL_LINE(GPIOG, 12)
# define G13 PAL_LINE(GPIOG, 13)
# define G14 PAL_LINE(GPIOG, 14)
# define G15 PAL_LINE(GPIOG, 15)
# define H0 PAL_LINE(GPIOH, 0)
# define H1 PAL_LINE(GPIOH, 1)
# define H2 PAL_LINE(GPIOH, 2)
# define H3 PAL_LINE(GPIOH, 3)
# define H4 PAL_LINE(GPIOH, 4)
# define H5 PAL_LINE(GPIOH, 5)
# define H6 PAL_LINE(GPIOH, 6)
# define H7 PAL_LINE(GPIOH, 7)
# define H8 PAL_LINE(GPIOH, 8)
# define H9 PAL_LINE(GPIOH, 9)
# define H10 PAL_LINE(GPIOH, 10)
# define H11 PAL_LINE(GPIOH, 11)
# define H12 PAL_LINE(GPIOH, 12)
# define H13 PAL_LINE(GPIOH, 13)
# define H14 PAL_LINE(GPIOH, 14)
# define H15 PAL_LINE(GPIOH, 15)
# define I0 PAL_LINE(GPIOI, 0)
# define I1 PAL_LINE(GPIOI, 1)
# define I2 PAL_LINE(GPIOI, 2)
# define I3 PAL_LINE(GPIOI, 3)
# define I4 PAL_LINE(GPIOI, 4)
# define I5 PAL_LINE(GPIOI, 5)
# define I6 PAL_LINE(GPIOI, 6)
# define I7 PAL_LINE(GPIOI, 7)
# define I8 PAL_LINE(GPIOI, 8)
# define I9 PAL_LINE(GPIOI, 9)
# define I10 PAL_LINE(GPIOI, 10)
# define I11 PAL_LINE(GPIOI, 11)
# define I12 PAL_LINE(GPIOI, 12)
# define I13 PAL_LINE(GPIOI, 13)
# define I14 PAL_LINE(GPIOI, 14)
# define I15 PAL_LINE(GPIOI, 15)
# define J0 PAL_LINE(GPIOJ, 0)
# define J1 PAL_LINE(GPIOJ, 1)
# define J2 PAL_LINE(GPIOJ, 2)
# define J3 PAL_LINE(GPIOJ, 3)
# define J4 PAL_LINE(GPIOJ, 4)
# define J5 PAL_LINE(GPIOJ, 5)
# define J6 PAL_LINE(GPIOJ, 6)
# define J7 PAL_LINE(GPIOJ, 7)
# define J8 PAL_LINE(GPIOJ, 8)
# define J9 PAL_LINE(GPIOJ, 9)
# define J10 PAL_LINE(GPIOJ, 10)
# define J11 PAL_LINE(GPIOJ, 11)
# define J12 PAL_LINE(GPIOJ, 12)
# define J13 PAL_LINE(GPIOJ, 13)
# define J14 PAL_LINE(GPIOJ, 14)
# define J15 PAL_LINE(GPIOJ, 15)
// Keyboards can `#define KEYBOARD_REQUIRES_GPIOK` if they need to access GPIO-K pins. These conflict with a whole
// bunch of layout definitions, so it's intentionally left out unless absolutely required -- in that case, the
// keyboard designer should use a different symbol when defining their layout macros.
# ifdef KEYBOARD_REQUIRES_GPIOK
# define K0 PAL_LINE(GPIOK, 0)
# define K1 PAL_LINE(GPIOK, 1)
# define K2 PAL_LINE(GPIOK, 2)
# define K3 PAL_LINE(GPIOK, 3)
# define K4 PAL_LINE(GPIOK, 4)
# define K5 PAL_LINE(GPIOK, 5)
# define K6 PAL_LINE(GPIOK, 6)
# define K7 PAL_LINE(GPIOK, 7)
# define K8 PAL_LINE(GPIOK, 8)
# define K9 PAL_LINE(GPIOK, 9)
# define K10 PAL_LINE(GPIOK, 10)
# define K11 PAL_LINE(GPIOK, 11)
# define K12 PAL_LINE(GPIOK, 12)
# define K13 PAL_LINE(GPIOK, 13)
# define K14 PAL_LINE(GPIOK, 14)
# define K15 PAL_LINE(GPIOK, 15)
# endif
# endif
#endif
-28
View File
@@ -1,28 +0,0 @@
Debounce algorithms belong in this folder.
Here are a few ideas
1) Global vs Per-Key vs Per-Row
* Global - one timer for all keys. Any key change state affects global timer
* Per key - one timer per key
* Per row - one timer per row
2) Eager vs symmetric vs asymmetric
* Eager - any key change is reported immediately. All further inputs for DEBOUNCE ms are ignored.
* Symmetric - wait for no changes for DEBOUNCE ms before reporting change
* Asymmetric - wait for different times depending on key-down/key-up. E.g. Eager key-down, DEBOUNCE ms key up.
3) Timestamp vs cycles
* old old old code waits n cycles, decreasing count by one each matrix_scan
* newer code stores the millisecond the change occurred, and does subraction to figure out time elapsed.
* Timestamps are superior, i don't think cycles will ever be used again once upgraded.
The default algorithm is symmetric and global.
Here are a few that could be implemented:
sym_g.c
sym_pk.c
sym_pr.c
sym_pr_cycles.c
eager_g.c
eager_pk.c
eager_pr.c //could be used in ergo-dox!
@@ -38,12 +38,12 @@ static bool counters_need_update;
#define MAX_DEBOUNCE (DEBOUNCE_ELAPSED - 1)
static uint8_t wrapping_timer_read(void) {
static uint16_t time = 0;
static uint16_t time = 0;
static uint8_t last_result = 0;
uint16_t new_time = timer_read();
uint16_t diff = new_time - time;
time = new_time;
last_result = (last_result + diff) % (MAX_DEBOUNCE + 1);
uint16_t new_time = timer_read();
uint16_t diff = new_time - time;
time = new_time;
last_result = (last_result + diff) % (MAX_DEBOUNCE + 1);
return last_result;
}
+49 -6
View File
@@ -21,14 +21,33 @@
// for memcpy
#include <string.h>
#if !defined(DIP_SWITCH_PINS)
# error "No DIP switch pads defined by DIP_SWITCH_PINS"
#if !defined(DIP_SWITCH_PINS) && !defined(DIP_SWITCH_MATRIX_GRID)
# error "Either DIP_SWITCH_PINS or DIP_SWITCH_MATRIX_GRID must be defined."
#endif
#define NUMBER_OF_DIP_SWITCHES (sizeof(dip_switch_pad) / sizeof(pin_t))
static pin_t dip_switch_pad[] = DIP_SWITCH_PINS;
static bool dip_switch_state[NUMBER_OF_DIP_SWITCHES] = {0};
static bool last_dip_switch_state[NUMBER_OF_DIP_SWITCHES] = {0};
#if defined(DIP_SWITCH_PINS) && defined(DIP_SWITCH_MATRIX_GRID)
# error "Both DIP_SWITCH_PINS and DIP_SWITCH_MATRIX_GRID are defined."
#endif
#ifdef DIP_SWITCH_PINS
# define NUMBER_OF_DIP_SWITCHES (sizeof(dip_switch_pad) / sizeof(pin_t))
static pin_t dip_switch_pad[] = DIP_SWITCH_PINS;
#endif
#ifdef DIP_SWITCH_MATRIX_GRID
typedef struct matrix_index_t {
uint8_t row;
uint8_t col;
} matrix_index_t;
# define NUMBER_OF_DIP_SWITCHES (sizeof(dip_switch_pad) / sizeof(matrix_index_t))
static matrix_index_t dip_switch_pad[] = DIP_SWITCH_MATRIX_GRID;
extern bool peek_matrix(uint8_t row_index, uint8_t col_index, bool read_raw);
static uint16_t scan_count;
#endif /* DIP_SWITCH_MATRIX_GRID */
static bool dip_switch_state[NUMBER_OF_DIP_SWITCHES] = {0};
static bool last_dip_switch_state[NUMBER_OF_DIP_SWITCHES] = {0};
__attribute__((weak)) void dip_switch_update_user(uint8_t index, bool active) {}
@@ -39,18 +58,42 @@ __attribute__((weak)) void dip_switch_update_mask_user(uint32_t state) {}
__attribute__((weak)) void dip_switch_update_mask_kb(uint32_t state) { dip_switch_update_mask_user(state); }
void dip_switch_init(void) {
#ifdef DIP_SWITCH_PINS
for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) {
setPinInputHigh(dip_switch_pad[i]);
}
dip_switch_read(true);
#endif
#ifdef DIP_SWITCH_MATRIX_GRID
scan_count = 0;
#endif
}
void dip_switch_read(bool forced) {
bool has_dip_state_changed = false;
uint32_t dip_switch_mask = 0;
#ifdef DIP_SWITCH_MATRIX_GRID
bool read_raw = false;
if (scan_count < 500) {
scan_count++;
if (scan_count == 10) {
read_raw = true;
forced = true; /* First reading of the dip switch */
} else {
return;
}
}
#endif
for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) {
#ifdef DIP_SWITCH_PINS
dip_switch_state[i] = !readPin(dip_switch_pad[i]);
#endif
#ifdef DIP_SWITCH_MATRIX_GRID
dip_switch_state[i] = peek_matrix(dip_switch_pad[i].row, dip_switch_pad[i].col, read_raw);
#endif
dip_switch_mask |= dip_switch_state[i] << i;
if (last_dip_switch_state[i] != dip_switch_state[i] || forced) {
has_dip_state_changed = true;
+10 -1
View File
@@ -35,7 +35,16 @@
// Explicitly override it if the keyboard uses a microcontroller with
// more EEPROM *and* it makes sense to increase it.
#ifndef DYNAMIC_KEYMAP_EEPROM_MAX_ADDR
# define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR 1023
# if defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
# define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR 2047
# else
# define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR 1023
# endif
#endif
// Due to usage of uint16_t check for max 65535
#if DYNAMIC_KEYMAP_EEPROM_MAX_ADDR > 65535
# error DYNAMIC_KEYMAP_EEPROM_MAX_ADDR must be less than 65536
#endif
// If DYNAMIC_KEYMAP_EEPROM_ADDR not explicitly defined in config.h,
+20 -4
View File
@@ -23,7 +23,7 @@
// for memcpy
#include <string.h>
#ifndef ENCODER_RESOLUTION
#if !defined(ENCODER_RESOLUTIONS) && !defined(ENCODER_RESOLUTION)
# define ENCODER_RESOLUTION 4
#endif
@@ -34,6 +34,9 @@
#define NUMBER_OF_ENCODERS (sizeof(encoders_pad_a) / sizeof(pin_t))
static pin_t encoders_pad_a[] = ENCODERS_PAD_A;
static pin_t encoders_pad_b[] = ENCODERS_PAD_B;
#ifdef ENCODER_RESOLUTIONS
static uint8_t encoder_resolutions[] = ENCODER_RESOLUTIONS;
#endif
#ifndef ENCODER_DIRECTION_FLIP
# define ENCODER_CLOCKWISE true
@@ -65,9 +68,15 @@ void encoder_init(void) {
if (!isLeftHand) {
const pin_t encoders_pad_a_right[] = ENCODERS_PAD_A_RIGHT;
const pin_t encoders_pad_b_right[] = ENCODERS_PAD_B_RIGHT;
# if defined(ENCODER_RESOLUTIONS_RIGHT)
const uint8_t encoder_resolutions_right[] = ENCODER_RESOLUTIONS_RIGHT;
# endif
for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) {
encoders_pad_a[i] = encoders_pad_a_right[i];
encoders_pad_b[i] = encoders_pad_b_right[i];
# if defined(ENCODER_RESOLUTIONS_RIGHT)
encoder_resolutions[i] = encoder_resolutions_right[i];
# endif
}
}
#endif
@@ -87,19 +96,26 @@ void encoder_init(void) {
static void encoder_update(int8_t index, uint8_t state) {
uint8_t i = index;
#ifdef ENCODER_RESOLUTIONS
int8_t resolution = encoder_resolutions[i];
#else
int8_t resolution = ENCODER_RESOLUTION;
#endif
#ifdef SPLIT_KEYBOARD
index += thisHand;
#endif
encoder_pulses[i] += encoder_LUT[state & 0xF];
if (encoder_pulses[i] >= ENCODER_RESOLUTION) {
if (encoder_pulses[i] >= resolution) {
encoder_value[index]++;
encoder_update_kb(index, ENCODER_COUNTER_CLOCKWISE);
}
if (encoder_pulses[i] <= -ENCODER_RESOLUTION) { // direction is arbitrary here, but this clockwise
if (encoder_pulses[i] <= -resolution) { // direction is arbitrary here, but this clockwise
encoder_value[index]--;
encoder_update_kb(index, ENCODER_CLOCKWISE);
}
encoder_pulses[i] %= ENCODER_RESOLUTION;
encoder_pulses[i] %= resolution;
}
void encoder_read(void) {
+3 -3
View File
@@ -15,10 +15,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <avr/interrupt.h>
#include <avr/io.h>
#include <timer.h>
#include <fauxclicky.h>
#include "timer.h"
#include "fauxclicky.h"
#include <stdbool.h>
#include <musical_notes.h>
#include "musical_notes.h"
bool fauxclicky_enabled = true;
uint16_t note_start = 0;
+2 -2
View File
@@ -18,13 +18,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#endif
#include "musical_notes.h"
#include "stdbool.h"
#include <stdbool.h>
__attribute__((weak)) float fauxclicky_pressed_note[2] = MUSICAL_NOTE(_D4, 0.25);
__attribute__((weak)) float fauxclicky_released_note[2] = MUSICAL_NOTE(_C4, 0.125);
__attribute__((weak)) float fauxclicky_beep_note[2] = MUSICAL_NOTE(_C4, 0.25);
bool fauxclicky_enabled;
extern bool fauxclicky_enabled;
//
// tempo in BPM
+10 -2
View File
@@ -1,5 +1,9 @@
#pragma once
#include "quantum.h"
#include <stdint.h>
#ifndef JOYSTICK_BUTTON_COUNT
# define JOYSTICK_BUTTON_COUNT 8
#endif
@@ -8,9 +12,13 @@
# define JOYSTICK_AXES_COUNT 4
#endif
#include "quantum.h"
#ifndef JOYSTICK_AXES_RESOLUTION
# define JOYSTICK_AXES_RESOLUTION 8
#elif JOYSTICK_AXES_RESOLUTION < 8 || JOYSTICK_AXES_RESOLUTION > 16
# error JOYSTICK_AXES_RESOLUTION must be between 8 and 16
#endif
#include <stdint.h>
#define JOYSTICK_RESOLUTION ((1L << (JOYSTICK_AXES_RESOLUTION - 1)) - 1)
// configure on input_pin of the joystick_axes array entry to JS_VIRTUAL_AXIS
// to prevent it from being read from the ADC. This allows outputing forged axis value.
+2 -5
View File
@@ -14,13 +14,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "eeconfig.h"
#include "keycode.h"
#include "action_code.h"
#ifndef KEYCODE_CONFIG_H
# define KEYCODE_CONFIG_H
uint16_t keycode_config(uint16_t keycode);
uint8_t mod_config(uint8_t mod);
@@ -42,5 +41,3 @@ typedef union {
} keymap_config_t;
extern keymap_config_t keymap_config;
#endif /* KEYCODE_CONFIG_H */
+6 -5
View File
@@ -15,8 +15,7 @@ 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 KEYMAP_H
#define KEYMAP_H
#pragma once
#include <stdint.h>
#include <stdbool.h>
@@ -25,7 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# include <avr/pgmspace.h>
#elif defined PROTOCOL_CHIBIOS
// We need to ensure that chibios is include before redefining reset
# include "ch.h"
# include <ch.h>
#endif
#include "keycode.h"
#include "action_macro.h"
@@ -40,6 +39,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#if defined(PROTOCOL_CHIBIOS)
# define RESET QK_RESET
#endif
// Gross hack, remove me and change RESET keycode to QK_BOOT
#if defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1287__)
# undef RESET
#endif
#include "quantum_keycodes.h"
@@ -51,5 +54,3 @@ uint16_t keymap_function_id_to_action(uint16_t function_id);
extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
extern const uint16_t fn_actions[];
#endif
+1 -1
View File
@@ -67,7 +67,7 @@
#define BE_F KC_F // F
#define BE_G KC_G // G
#define BE_H KC_H // H
#define BE_J KC_K // J
#define BE_J KC_J // J
#define BE_K KC_K // K
#define BE_L KC_L // L
#define BE_M KC_SCLN // M
@@ -1,4 +1,4 @@
/* Copyright 2016 Didier Loiseau
/* Copyright 2020
*
* 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
@@ -13,247 +13,421 @@
* 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 KEYMAP_CANADIAN_MULTILINGUAL_H
#define KEYMAP_CANADIAN_MULTILINGUAL_H
#pragma once
#include "keymap.h"
#ifndef GR2A
# define GR2A(kc) RCTL(kc)
#endif
// clang-format off
// Normal characters
// First row
#define CSA_SLASH KC_GRV // /
#define CSA_SLSH CSA_SLASH
/*
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
* │ / │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │       │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
* │     │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ ^ │ Ç │     │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
* │      │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ È │ À │    │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
* │    │ Ù │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ É │          │
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
* │    │    │    │                        │    │    │    │    │
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
*/
// Row 1
#define CA_SLSH KC_GRV // /
#define CA_1 KC_1 // 1
#define CA_2 KC_2 // 2
#define CA_3 KC_3 // 3
#define CA_4 KC_4 // 4
#define CA_5 KC_5 // 5
#define CA_6 KC_6 // 6
#define CA_7 KC_7 // 7
#define CA_8 KC_8 // 8
#define CA_9 KC_9 // 9
#define CA_0 KC_0 // 0
#define CA_MINS KC_MINS // -
#define CA_EQL KC_EQL // =
// Row 2
#define CA_Q KC_Q // Q
#define CA_W KC_W // W
#define CA_E KC_E // E
#define CA_R KC_R // R
#define CA_T KC_T // T
#define CA_Y KC_Y // Y
#define CA_U KC_U // U
#define CA_I KC_I // I
#define CA_O KC_O // O
#define CA_P KC_P // P
#define CA_CIRC KC_LBRC // ^ (dead)
#define CA_CCED KC_RBRC // Ç
// Row 3
#define CA_A KC_A // A
#define CA_S KC_S // S
#define CA_D KC_D // D
#define CA_F KC_F // F
#define CA_G KC_G // G
#define CA_H KC_H // H
#define CA_J KC_J // J
#define CA_K KC_K // K
#define CA_L KC_L // L
#define CA_SCLN KC_SCLN // ;
#define CA_EGRV KC_QUOT // É
#define CA_AGRV KC_NUHS // À
// Row 4
#define CA_UGRV KC_NUBS // Ù
#define CA_Z KC_Z // Z
#define CA_X KC_X // X
#define CA_C KC_C // C
#define CA_V KC_V // V
#define CA_B KC_B // B
#define CA_N KC_N // N
#define CA_M KC_M // M
#define CA_COMM KC_COMM // ,
#define CA_DOT KC_DOT // .
#define CA_EACU KC_SLSH // É
// Second row
#define CSA_DEAD_CIRCUMFLEX KC_LBRACKET // dead ^
#define CSA_DCRC CSA_DEAD_CIRCUMFLEX
#define CSA_C_CEDILLA KC_RBRACKET // Ç
#define CSA_CCED CSA_C_CEDILLA
/* Shifted symbols
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
* │ \ │ ! │ @ │ # │ $ │ % │ ? │ & │ * │ ( │ ) │ _ │ + │       │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
* │     │   │   │   │   │   │   │   │   │   │   │ ¨ │   │     │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
* │      │   │   │   │   │   │   │   │   │   │ : │   │   │    │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
* │    │   │   │   │   │   │   │   │   │ ' │ " │   │          │
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
* │    │    │    │                        │    │    │    │    │
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
*/
// Row 1
#define CA_BSLS S(CA_SLSH) // (backslash)
#define CA_EXLM S(CA_1) // !
#define CA_AT S(CA_2) // @
#define CA_HASH S(CA_3) // #
#define CA_DLR S(CA_4) // $
#define CA_PERC S(CA_5) // %
#define CA_QUES S(CA_6) // ?
#define CA_AMPR S(CA_7) // &
#define CA_ASTR S(CA_8) // *
#define CA_LPRN S(CA_9) // (
#define CA_RPRN S(CA_0) // )
#define CA_UNDS S(CA_MINS) // _
#define CA_PLUS S(CA_EQL) // +
// Row 2
#define CA_DIAE S(CA_CIRC) // ¨ (dead)
// Row 3
#define CA_COLN S(CA_SCLN) // :
// Row 4
#define CA_QUOT S(CA_COMM) // '
#define CA_DQUO S(CA_DOT) // "
// Third row
#define CSA_E_GRAVE KC_QUOT // è
#define CSA_EGRV CSA_E_GRAVE
#define CSA_A_GRAVE KC_BSLASH // à
#define CSA_AGRV CSA_A_GRAVE
/* AltGr symbols
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
* │ | │   │   │   │ ¤ │   │   │ { │ } │ [ │ ] │   │ ¬ │       │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
* │     │   │   │ € │   │   │   │   │   │   │   │ ` │ ~ │     │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
* │      │   │   │   │   │   │   │   │   │   │ ° │   │   │    │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
* │    │   │ « │ » │   │   │   │   │   │ < │ > │   │          │
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
* │    │    │    │                        │    │    │    │    │
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
*/
// Row 1
#define CA_PIPE ALGR(CA_SLSH) // |
#define CA_CURR ALGR(CA_4) // ¤
#define CA_LCBR ALGR(CA_7) // {
#define CA_RCBR ALGR(CA_8) // }
#define CA_LBRC ALGR(CA_9) // [
#define CA_RBRC ALGR(CA_0) // ]
#define CA_NOT ALGR(CA_EQL) // ¬
// Row 2
#define CA_EURO ALGR(CA_E) // €
#define CA_GRV ALGR(CA_CIRC) // ` (dead)
#define CA_DTIL ALGR(CA_CCED) // ~ (dead)
// Row 3
#define CA_DEG ALGR(CA_SCLN) // °
// Row 4
#define CA_LDAQ ALGR(CA_Z) // «
#define CA_RDAQ ALGR(CA_X) // »
#define CA_LABK ALGR(CA_COMM) // <
#define CA_RABK ALGR(CA_DOT) // >
// Fourth row
#define CSA_U_GRAVE KC_NONUS_BSLASH // ù
#define CSA_UGRV CSA_U_GRAVE
#define CSA_E_ACUTE KC_SLSH // é
#define CSA_ECUT CSA_E_ACUTE
/* Right Ctrl symbols
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
* │   │ ¹ │ ² │ ³ │ ¼ │ ½ │ ¾ │   │   │   │   │   │ ¸ │       │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
* │     │ Ω │ Ł │ Œ │ ¶ │ Ŧ │ ← │ ↓ │ → │ Ø │ Þ │   │ ~ │     │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
* │      │ Æ │ ß │ Ð │   │ Ŋ │ Ħ │ IJ │ ĸ │ Ŀ │ ´ │   │   │    │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
* │    │   │   │   │ ¢ │ “ │ ” │ ʼn │ μ │ ― │ ˙ │   │          │
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
* │    │    │    │                        │    │    │    │    │
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
*/
// Row 1
#define CA_SUP1 RCTL(CA_1) // ¹
#define CA_SUP2 RCTL(CA_2) // ²
#define CA_SUP3 RCTL(CA_3) // ³
#define CA_QRTR RCTL(CA_4) // ¼
#define CA_HALF RCTL(CA_5) // ½
#define CA_TQTR RCTL(CA_6) // ¾
#define CA_CEDL RCTL(CA_EQL) // ¸ (dead)
// Row 2
#define CA_OMEG RCTL(CA_Q) // Ω
#define CA_LSTR RCTL(CA_W) // Ł
#define CA_OE RCTL(CA_E) // Œ
#define CA_PARA RCTL(CA_R) // ¶
#define CA_TSTR RCTL(CA_T) // Ŧ
#define CA_LARR RCTL(CA_Y) // ←
#define CA_DARR RCTL(CA_U) // ↓
#define CA_RARR RCTL(CA_I) // →
#define CA_OSTR RCTL(CA_O) // Ø
#define CA_THRN RCTL(CA_P) // Þ
#define CA_TILD RCTL(CA_CCED) // ~
// Row 3
#define CA_AE RCTL(CA_A) // Æ
#define CA_SS RCTL(CA_S) // ß
#define CA_ETH RCTL(CA_D) // Ð
#define CA_ENG RCTL(CA_G) // Ŋ
#define CA_HSTR RCTL(CA_H) // Ħ
#define CA_IJ RCTL(CA_J) // IJ
#define CA_KRA RCTL(CA_K) // ĸ
#define CA_LMDT RCTL(CA_L) // Ŀ
#define CA_ACUT RCTL(CA_SCLN) // ´ (dead)
// Row 4
#define CA_CENT RCTL(CA_C) // ¢
#define CA_LDQU RCTL(CA_V) // “
#define CA_RDQU RCTL(CA_B) // ”
#define CA_APSN RCTL(CA_N) // ʼn
#define CA_MICR RCTL(CA_M) // μ
#define CA_HRZB RCTL(CA_COMM) // ―
#define CA_DOTA RCTL(CA_DOT) // ˙ (dead)
// Shifted characters
// First row
#define CSA_BACKSLASH LSFT(CSA_SLASH) /* \ */
#define CSA_BSLS CSA_BACKSLASH
#define CSA_QUESTION LSFT(KC_6) // ?
#define CSA_QEST CSA_QUESTION
/* Shift+Right Ctrl symbols
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
* │ - │ ¡ │   │ £ │   │ ⅜ │ ⅝ │ ⅞ │ ™ │ ± │   │ ¿ │ ˛ │       │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
* │     │   │   │   │ ® │   │ ¥ │ ↑ │ ı │   │   │ ° │ ¯ │     │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
* │      │   │ § │   │ ª │   │   │   │   │   │ ˝ │ ˇ │ ˘ │    │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
* │    │ ¦ │   │   │ © │ ‘ │ ’ │ ♪ │ º │ × │ ÷ │   │          │
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
* │    │    │    │                        │    │    │    │    │
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
*/
// Row 1
#define CA_SHYP RCTL(S(CA_SLSH)) // (soft hyphen)
#define CA_IEXL RCTL(S(CA_1)) // ¡
#define CA_PND RCTL(S(CA_3)) // £
#define CA_TEIG RCTL(S(CA_5)) // ⅜
#define CA_FEIG RCTL(S(CA_6)) // ⅝
#define CA_SEIG RCTL(S(CA_7)) // ⅞
#define CA_TM RCTL(S(CA_8)) // ™
#define CA_PLMN RCTL(S(CA_9)) // ±
#define CA_IQUE RCTL(S(CA_MINS)) // ¿
#define CA_OGON RCTL(S(CA_EQL)) // ˛ (dead)
// Row 2
#define CA_REGD RCTL(S(CA_R)) // ®
#define CA_YEN RCTL(S(CA_Y)) // ¥
#define CA_UARR RCTL(S(CA_U)) // ↑
#define CA_DLSI RCTL(S(CA_I)) // ı
#define CA_RNGA RCTL(S(CA_CIRC)) // ° (dead)
#define CA_MACR RCTL(S(CA_CCED)) // ¯ (dead)
// Row 3
#define CA_SECT RCTL(S(CA_S)) // §
#define CA_FORD RCTL(S(CA_F)) // ª
#define CA_DACU RCTL(S(CA_SCLN)) // ˝ (dead)
#define CA_CARN RCTL(S(CA_EGRV)) // ˇ (dead)
#define CA_BREV RCTL(S(CA_AGRV)) // ˘ (dead)
// Row 4
#define CA_BRKP RCTL(S(CA_UGRV)) // ¦
#define CA_COPY RCTL(S(CA_C)) // ©
#define CA_LSQU RCTL(S(CA_V)) // ‘
#define CA_RSQU RCTL(S(CA_B)) // ’
#define CA_ENOT RCTL(S(CA_N)) // ♪
#define CA_MORD RCTL(S(CA_M)) // º
#define CA_MUL RCTL(S(CA_COMM)) // ×
#define CA_DIV RCTL(S(CA_DOT)) // ÷
// Second row
#define CSA_DEAD_TREMA LSFT(CSA_DEAD_CIRCUMFLEX) // dead trema/umlaut/diaresis for ä ë ï ö ü
#define CSA_DTRM CSA_DEAD_TREMA
// Third row
// all same as US-QWERTY, or capitalised character of the non-shifted key
// Fourth row
#define CSA_APOSTROPHE LSFT(KC_COMMA) // '
#define CSA_APOS CSA_APOSTROPHE
#define CSA_DOUBLE_QUOTE LSFT(KC_DOT) // "
#define CSA_DQOT CSA_DOUBLE_QUOTE
// Alt Gr-ed characters
// First row
#define CSA_PIPE ALGR(CSA_SLASH) // |
#define CSA_CURRENCY ALGR(KC_4) // ¤
#define CSA_CURR CSA_CURRENCY
#define CSA_LEFT_CURLY_BRACE ALGR(KC_7) // {
#define CSA_LCBR CSA_LEFT_CURLY_BRACE
#define CSA_RIGHT_CURLY_BRACE ALGR(KC_8) // }
#define CSA_RCBR CSA_RIGHT_CURLY_BRACE
#define CSA_LBRACKET ALGR(KC_9) // [
#define CSA_LBRC CSA_LBRACKET
#define CSA_RBRACKET ALGR(KC_0) // ]
#define CSA_RBRC CSA_RBRACKET
#define CSA_NEGATION ALGR(KC_EQUAL) // ¬
#define CSA_NEGT CSA_NEGATION
// Second row
// euro symbol not available on Linux? (X.org)
#define CSA_EURO ALGR(KC_E) // €
#define CSA_DEAD_GRAVE ALGR(CSA_DEAD_CIRCUMFLEX)
#define CSA_DGRV CSA_DEAD_GRAVE // dead `
#define CSA_DEAD_TILDE ALGR(CSA_C_CEDILLA) // ~
#define CSA_DTLD CSA_DEAD_TILDE
// Third row
#define CSA_DEGREE ALGR(KC_SCOLON) // °
#define CSA_DEGR CSA_DEGREE
// Fourth row
#define CSA_LEFT_GUILLEMET ALGR(KC_Z) // «
#define CSA_LGIL CSA_LEFT_GUILLEMET
#define CSA_RIGHT_GUILLEMET ALGR(KC_X) // »
#define CSA_RGIL CSA_RIGHT_GUILLEMET
#define CSA_LESS ALGR(KC_COMMA) // <
#define CSA_GREATER ALGR(KC_DOT) // >
#define CSA_GRTR CSA_GREATER
// Space bar
#define CSA_NON_BREAKING_SPACE ALGR(KC_SPACE)
#define CSA_NBSP CSA_NON_BREAKING_SPACE
// GR2A-ed characters
// First row
#define CSA_SUPERSCRIPT_ONE GR2A(KC_1) // ¹
#define CSA_SUP1 CSA_SUPERSCRIPT_ONE
#define CSA_SUPERSCRIPT_TWO GR2A(KC_2) // ²
#define CSA_SUP2 CSA_SUPERSCRIPT_TWO
#define CSA_SUPERSCRIPT_THREE GR2A(KC_3) // ³
#define CSA_SUP3 CSA_SUPERSCRIPT_THREE
#define CSA_ONE_QUARTER GR2A(KC_4) // ¼
#define CSA_1QRT CSA_ONE_QUARTER
#define CSA_ONE_HALF GR2A(KC_5) // ½
#define CSA_1HLF CSA_ONE_HALF
#define CSA_THREE_QUARTERS GR2A(KC_6) // ¾
#define CSA_3QRT CSA_THREE_QUARTERS
// nothing on 7-0 and -
#define CSA_DEAD_CEDILLA GR2A(KC_EQUAL) // dead ¸
#define CSA_DCED CSA_DEAD_CEDILLA
// Second row
#define CSA_OMEGA GR2A(KC_Q) // ω
#define CSA_OMEG CSA_OMEGA
#define CSA_L_STROKE GR2A(KC_W) // ł
#define CSA_LSTK CSA_L_STROKE
#define CSA_OE_LIGATURE GR2A(KC_E) // œ
#define CSA_OE CSA_OE_LIGATURE
#define CSA_PARAGRAPH GR2A(KC_R) // ¶
#define CSA_PARG CSA_PARAGRAPH
#define CSA_T_STROKE GR2A(KC_T) // ŧ
#define CSA_LEFT_ARROW GR2A(KC_Y) // ←
#define CSA_LARW CSA_LEFT_ARROW
#define CSA_DOWN_ARROW GR2A(KC_U) // ↓
#define CSA_DARW CSA_DOWN_ARROW
#define CSA_RIGHT_ARROW GR2A(KC_I) // →
#define CSA_RARW CSA_RIGHT_ARROW
#define CSA_O_STROKE GR2A(KC_O) // ø
#define CSA_OSTK CSA_O_STROKE
#define CSA_THORN GR2A(KC_P) // þ
#define CSA_THRN CSA_THORN
// nothing on ^
#define CSA_TILDE GR2A(CSA_C_CEDILLA) // dead ~
#define CSA_TILD CSA_TILDE
// Third row
#define CSA_AE_LIGATURE GR2A(KC_A) // æ
#define CSA_AE CSA_AE_LIGATURE
#define CSA_SHARP_S GR2A(KC_S) // ß
#define CSA_SRPS CSA_SHARP_S
#define CSA_ETH GR2A(KC_D) // ð
// nothing on F
#define CSA_ENG GR2A(KC_G) // ŋ
#define CSA_H_SRTOKE GR2A(KC_H) // ħ
#define CSA_HSTK CSA_H_SRTOKE
#define CSA_IJ_LIGATURE GR2A(KC_J) // ij
#define CSA_IJ CSA_IJ_LIGATURE
#define CSA_KRA GR2A(KC_K) // ĸ
#define CSA_L_FLOWN_DOT GR2A(KC_L) // ŀ
#define CSA_LFLD CSA_L_FLOWN_DOT
#define CSA_DEAD_ACUTE GR2A(KC_SCLN) // dead acute accent
#define CSA_DACT CSA_DEAD_ACUTE
// nothing on È & À
// Fourth row
#define CSA_CENT GR2A(KC_C) // ¢
#define CSA_LEFT_DOUBLE_QUOTE GR2A(KC_V) // “
#define CSA_LDQT CSA_LEFT_DOUBLE_QUOTE
#define CSA_RIGHT_DOUBLE_QUOTE GR2A(KC_B) // ”
#define CSA_RDQT CSA_RIGHT_DOUBLE_QUOTE
#define CSA_N_APOSTROPHE GR2A(KC_N) // ʼn (deprecated unicode codepoint)
#define CSA_NAPO CSA_N_APOSTROPHE
#define CSA_MU GR2A(KC_M) // μ
#define CSA_HORIZONTAL_BAR GR2A(KC_COMMA) // ―
#define CSA_HZBR CSA_HORIZONTAL_BAR
#define CSA_DEAD_DOT_ABOVE GR2A(KC_DOT) // dead ˙
#define CSA_DDTA CSA_DEAD_DOT_ABOVE
// GR2A-shifted characters (different from capitalised GR2A-ed characters)
// First row
#define CSA_SOFT_HYPHEN GR2A(LSFT(CSA_SLASH)) // soft-hyphen, appears as a hyphen in wrapped word
#define CSA_SHYP CSA_SOFT_HYPHEN
#define CSA_INVERTED_EXCLAIM GR2A(KC_EXCLAIM) // ¡
#define CSA_IXLM CSA_INVERTED_EXCLAIM
// nothing on 2
#define CSA_POUND GR2A(LSFT(KC_3)) // £
#define CSA_GBP CSA_POUND_SIGN
// already on ALGR(KC_E)
#define CSA_EURO_BIS GR2A(LSFT(KC_4)) // €
#define CSA_EURB CSA_EURO_BIS
#define CSA_THREE_EIGHTHS GR2A(LSFT(KC_5)) // ⅜
#define CSA_3ON8 CSA_THREE_EIGHTHS
#define CSA_FIVE_EIGHTHS GR2A(LSFT(KC_6)) // ⅝
#define CSA_5ON8 CSA_FIVE_EIGHTHS
#define CSA_SEVEN_EIGHTHS GR2A(LSFT(KC_7)) // ⅞
#define CSA_7ON8 CSA_SEVEN_EIGHTHS
#define CSA_TRADEMARK GR2A(LSFT(KC_8)) // ™
#define CSA_TM CSA_TRADEMARK
#define CSA_PLUS_MINUS GR2A(LSFT(KC_9)) // ±
#define CSA_PSMS CSA_PLUS_MINUS
// nothing on 0
#define CSA_INVERTED_QUESTION GR2A(LSFT(KC_MINUS)) // ¿
#define CSA_IQST CSA_INVERTED_QUESTION
#define CSA_DEAD_OGONEK GR2A(LSFT(KC_EQUAL)) // dead ˛
#define CSA_DOGO CSA_DEAD_OGONEK
// Second row
#define CSA_REGISTERED_TRADEMARK GR2A(LSFT(KC_R)) // ®
#define CSA_RTM CSA_REGISTERED_TRADEMARK
#define CSA_YEN GR2A(LSFT(KC_Y)) // ¥
#define CSA_YUAN CSA_YEN
#define CSA_UP_ARROW LSFT(CSA_DOWN_ARROW) // ↑
#define CSA_DOTLESS_I GR2A(LSFT(KC_I)) // ı
#define CSA_DLSI CSA_DOTLESS_I
#define CSA_DEAD_RING GR2A(LSFT(CSA_DCRC)) // dead °
#define CSA_DRNG CSA_DEAD_RING
#define CSA_DEAD_MACRON GR2A(LSFT(CSA_C_CEDILLA)) // dead ¯
#define CSA_DMCR CSA_DEAD_MACRON
// Third row
#define CSA_SECTION GR2A(LSFT(KC_S)) // §
#define CSA_SECT CSA_SECTION
#define CSA_ORDINAL_INDICATOR_A GR2A(LSFT(KC_F)) // ª
#define CSA_ORDA CSA_ORDINAL_INDICATOR_A
#define CSA_DEAD_DOUBLE_ACUTE LSFT(CSA_DEAD_ACUTE) // ˝
#define CSA_DDCT CSA_DEAD_DOUBLE_ACUTE
#define CSA_DEAD_CARON GR2A(LSFT(CSA_E_GRAVE)) // dead ˇ
#define CSA_DCAR CSA_DEAD_CARON
#define CSA_DEAD_BREVE GR2A(LSFT(CSA_A_GRAVE)) // dead ˘
#define CSA_DBRV CSA_DEAD_BREVE
// Fourth row
#define CSA_BROKEN_PIPE GR2A(LSFT(CSA_U_GRAVE)) // ¦
#define CSA_BPIP CSA_BROKEN_PIPE
#define CSA_COPYRIGHT GR2A(LSFT(KC_C)) // ©
#define CSA_CPRT CSA_COPYRIGHT
#define CSA_LEFT_QUOTE GR2A(LSFT(KC_V)) // ‘
#define CSA_LQOT CSA_LEFT_QUOTE
#define CSA_RIGHT_QUOTE GR2A(LSFT(KC_B)) // ’
#define CSA_RQOT CSA_RIGHT_QUOTE
#define CSA_EIGHTH_NOTE GR2A(LSFT(KC_N)) // ♪
#define CSA_8NOT CSA_EIGHTH_NOTE
#define CSA_ORDINAL_INDICATOR_O GR2A(LSFT(KC_M)) // º
#define CSA_ORDO CSA_ORDINAL_INDICATOR_O
#define CSA_TIMES GR2A(LSFT(KC_COMMA)) // ×
#define CSA_TIMS CSA_TIMES
#define CSA_OBELUS GR2A(LSFT(KC_DOT)) // ÷
#define CSA_OBEL CSA_OBELUS
// more conventional name of the symbol
#define CSA_DIVISION_SIGN CSA_OBELUS
#define CSA_DVSN CSA_DIVISION_SIGN
// TODO GR2A(LSFT(CSA_E_ACUTE))
#endif
// DEPRECATED
#define GR2A(kc) RCTL(kc)
#define CSA_SLASH CA_SLSH
#define CSA_SLSH CA_SLSH
#define CSA_DEAD_CIRCUMFLEX CA_CIRC
#define CSA_DCRC CA_CIRC
#define CSA_C_CEDILLA CA_CCED
#define CSA_CCED CA_CCED
#define CSA_E_GRAVE CA_EGRV
#define CSA_EGRV CA_EGRV
#define CSA_A_GRAVE CA_AGRV
#define CSA_AGRV CA_AGRV
#define CSA_U_GRAVE CA_UGRV
#define CSA_UGRV CA_UGRV
#define CSA_E_ACUTE CA_EACU
#define CSA_ECUT CA_EACU
#define CSA_BACKSLASH CA_BSLS
#define CSA_BSLS CA_BSLS
#define CSA_QUESTION CA_QUES
#define CSA_QEST CA_QUES
#define CSA_DEAD_TREMA CA_DIAE
#define CSA_DTRM CA_DIAE
#define CSA_APOSTROPHE CA_QUOT
#define CSA_APOS CA_QUOT
#define CSA_DOUBLE_QUOTE CA_DQUO
#define CSA_DQOT CA_DQUO
#define CSA_PIPE CA_PIPE
#define CSA_CURRENCY CA_CURR
#define CSA_CURR CA_CURR
#define CSA_LEFT_CURLY_BRACE CA_LCBR
#define CSA_LCBR CA_LCBR
#define CSA_RIGHT_CURLY_BRACE CA_RCBR
#define CSA_RCBR CA_RCBR
#define CSA_LBRACKET CA_LBRC
#define CSA_LBRC CA_LBRC
#define CSA_RBRACKET CA_RBRC
#define CSA_RBRC CA_RBRC
#define CSA_NEGATION CA_NOT
#define CSA_NEGT CA_NOT
#define CSA_EURO CA_EURO
#define CSA_DEAD_GRAVE CA_GRV
#define CSA_DGRV CA_GRV
#define CSA_DEAD_TILDE CA_DTIL
#define CSA_DTLD CA_DTIL
#define CSA_DEGREE CA_DEG
#define CSA_DEGR CA_DEG
#define CSA_LEFT_GUILLEMET CA_LDAQ
#define CSA_LGIL CA_LDAQ
#define CSA_RIGHT_GUILLEMET CA_RDAQ
#define CSA_RGIL CA_RDAQ
#define CSA_LESS CA_LABK
#define CSA_GREATER CA_RABK
#define CSA_GRTR CA_RABK
#define CSA_NON_BREAKING_SPACE ALGR(KC_SPC)
#define CSA_NBSP ALGR(KC_SPC)
#define CSA_SUPERSCRIPT_ONE CA_SUP1
#define CSA_SUP1 CA_SUP1
#define CSA_SUPERSCRIPT_TWO CA_SUP2
#define CSA_SUP2 CA_SUP2
#define CSA_SUPERSCRIPT_THREE CA_SUP3
#define CSA_SUP3 CA_SUP3
#define CSA_ONE_QUARTER CA_QRTR
#define CSA_1QRT CA_QRTR
#define CSA_ONE_HALF CA_HALF
#define CSA_1HLF CA_HALF
#define CSA_THREE_QUARTERS CA_TQTR
#define CSA_3QRT CA_TQTR
#define CSA_DEAD_CEDILLA CA_CEDL
#define CSA_DCED CA_CEDL
#define CSA_OMEGA CA_OMEG
#define CSA_OMEG CA_OMEG
#define CSA_L_STROKE CA_LSTR
#define CSA_LSTK CA_LSTR
#define CSA_OE_LIGATURE CA_OE
#define CSA_OE CA_OE
#define CSA_PARAGRAPH CA_PARA
#define CSA_PARG CA_PARA
#define CSA_T_STROKE CA_TSTR
#define CSA_LEFT_ARROW CA_LARR
#define CSA_LARW CA_LARR
#define CSA_DOWN_ARROW CA_DARR
#define CSA_DARW CA_DARR
#define CSA_RIGHT_ARROW CA_RARR
#define CSA_RARW CA_RARR
#define CSA_O_STROKE CA_OSTR
#define CSA_OSTK CA_OSTR
#define CSA_THORN CA_THRN
#define CSA_THRN CA_THRN
#define CSA_TILDE CA_TILD
#define CSA_TILD CA_TILD
#define CSA_AE_LIGATURE CA_AE
#define CSA_AE CA_AE
#define CSA_SHARP_S CA_SS
#define CSA_SRPS CA_SS
#define CSA_ETH CA_ETH
#define CSA_ENG CA_ENG
#define CSA_H_SRTOKE CA_HSTR
#define CSA_HSTK CA_HSTR
#define CSA_IJ_LIGATURE CA_IJ
#define CSA_IJ CA_IJ
#define CSA_KRA CA_KRA
#define CSA_L_FLOWN_DOT CA_LMDT
#define CSA_LFLD CA_LMDT
#define CSA_DEAD_ACUTE CA_ACUT
#define CSA_DACT CA_ACUT
#define CSA_CENT CA_CENT
#define CSA_LEFT_DOUBLE_QUOTE CA_LDQU
#define CSA_LDQT CA_LDQU
#define CSA_RIGHT_DOUBLE_QUOTE CA_RDQU
#define CSA_RDQT CA_RDQU
#define CSA_N_APOSTROPHE CA_APSN
#define CSA_NAPO CA_APSN
#define CSA_MU CA_MICR
#define CSA_HORIZONTAL_BAR CA_HRZB
#define CSA_HZBR CA_HRZB
#define CSA_DEAD_DOT_ABOVE CA_DOTA
#define CSA_DDTA CA_DOTA
#define CSA_SOFT_HYPHEN CA_SHYP
#define CSA_SHYP CA_SHYP
#define CSA_INVERTED_EXCLAIM CA_IEXL
#define CSA_IXLM CA_IEXL
#define CSA_POUND CA_PND
#define CSA_GBP CA_PND
#define CSA_EURO_BIS CA_EURO
#define CSA_EURB CA_EURO
#define CSA_THREE_EIGHTHS CA_TEIG
#define CSA_3ON8 CA_TEIG
#define CSA_FIVE_EIGHTHS CA_FEIG
#define CSA_5ON8 CA_FEIG
#define CSA_SEVEN_EIGHTHS CA_SEIG
#define CSA_7ON8 CA_SEIG
#define CSA_TRADEMARK CA_TM
#define CSA_TM CA_TM
#define CSA_PLUS_MINUS CA_PLMN
#define CSA_PSMS CA_PLMN
#define CSA_INVERTED_QUESTION CA_IQUE
#define CSA_IQST CA_IQUE
#define CSA_DEAD_OGONEK CA_OGON
#define CSA_DOGO CA_OGON
#define CSA_REGISTERED_TRADEMARK CA_REGD
#define CSA_RTM CA_REGD
#define CSA_YEN CA_YEN
#define CSA_YUAN CA_YEN
#define CSA_UP_ARROW CA_UARR
#define CSA_DOTLESS_I CA_DLSI
#define CSA_DLSI CA_DLSI
#define CSA_DEAD_RING CA_RNGA
#define CSA_DRNG CA_RNGA
#define CSA_DEAD_MACRON CA_MACR
#define CSA_DMCR CA_MACR
#define CSA_SECTION CA_SECT
#define CSA_SECT CA_SECT
#define CSA_ORDINAL_INDICATOR_A CA_FORD
#define CSA_ORDA CA_FORD
#define CSA_DEAD_DOUBLE_ACUTE CA_DACU
#define CSA_DDCT CA_DACU
#define CSA_DEAD_CARON CA_CARN
#define CSA_DCAR CA_CARN
#define CSA_DEAD_BREVE CA_BREV
#define CSA_DBRV CA_BREV
#define CSA_BROKEN_PIPE CA_BRKP
#define CSA_BPIP CA_BRKP
#define CSA_COPYRIGHT CA_COPY
#define CSA_CPRT CA_COPY
#define CSA_LEFT_QUOTE CA_LSQU
#define CSA_LQOT CA_LSQU
#define CSA_RIGHT_QUOTE CA_RSQU
#define CSA_RQOT CA_RSQU
#define CSA_EIGHTH_NOTE CA_ENOT
#define CSA_8NOT CA_ENOT
#define CSA_ORDINAL_INDICATOR_O CA_MORD
#define CSA_ORDO CA_MORD
#define CSA_TIMES CA_MUL
#define CSA_TIMS CA_MUL
#define CSA_OBELUS CA_DIV
#define CSA_OBEL CA_DIV
#define CSA_DIVISION_SIGN CA_DIV
#define CSA_DVSN CA_DIV
+2 -2
View File
@@ -94,7 +94,7 @@
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
* │      │   │   │   │   │   │   │   │   │   │ " │ ! │ ' │    │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
* │    │ | │   │   │   │   │   │   │   │ ; │ : │ _ │          │
* │    │ | │   │   │   │   │   │   │   │ ? │ : │ _ │          │
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
* │    │    │    │                        │    │    │    │    │
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
@@ -122,7 +122,7 @@
#define CZ_QUOT S(CZ_DIAE) // '
// Row 4
#define CZ_PIPE S(CZ_BSLS) // |
#define CZ_SCLN S(CZ_COMM) // ;
#define CZ_QUES S(CZ_COMM) // ?
#define CZ_COLN S(CZ_DOT) // :
#define CZ_UNDS S(CZ_MINS) // _
+135
View File
@@ -0,0 +1,135 @@
/* Copyright 2020 Guillaume Gérard
*
* 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/>.
*/
/* Dvorak for the French language
* Version: 2
*
* The layout is designed by Francis Leboutte <dvorak-fr@algo.be>
*
* Source: https://algo.be/ergo/dvorak-fr.html
*/
#pragma once
#include "keymap.h"
// clang-format off
/*
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
* │ « │ » │ / │ - │ è │ \ │ ^ │ ( │ ` │ ) │ _ │ [ │ ] │       │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
* │     │ : │ ' │ é │ G │ . │ H │ V │ C │ M │ K │ Z │ ¨ │     │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
* │      │ O │ A │ U │ E │ B │ F │ S │ T │ N │ D │ W │ ~ │    │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
* │    │ à │ ; │ Q │ , │ I │ Y │ X │ R │ L │ P │ J │          │
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
* │    │    │    │                        │    │    │    │    │
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
*/
// Row 1
#define DV_LDAQ KC_GRV // «
#define DV_RDAQ KC_1 // »
#define DV_SLSH KC_2 // /
#define DV_MINS KC_3 // -
#define DV_EGRV KC_4 // è
#define DV_BSLS KC_5 // (backslash)
#define DV_CIRC KC_6 // ^ (dead)
#define DV_LPRN KC_7 // (
#define DV_GRV KC_8 // ` (dead)
#define DV_RPRN KC_9 // )
#define DV_UNDS KC_0 // _
#define DV_LBRC KC_MINS // [
#define DV_RBRC KC_EQL // ]
// Row 2
#define DV_COLN KC_Q // :
#define DV_QUOT KC_W // '
#define DV_EACU KC_E // é
#define DV_G KC_R // G
#define DV_DOT KC_T // .
#define DV_H KC_Y // H
#define DV_V KC_U // V
#define DV_C KC_I // C
#define DV_M KC_O // M
#define DV_K KC_P // K
#define DV_Z KC_LBRC // Z
#define DV_DIAE KC_RBRC // ¨ (dead)
// Row 3
#define DV_O KC_A // O
#define DV_A KC_S // A
#define DV_U KC_D // U
#define DV_E KC_F // E
#define DV_B KC_G // B
#define DV_F KC_H // F
#define DV_S KC_J // S
#define DV_T KC_K // T
#define DV_N KC_L // N
#define DV_D KC_SCLN // D
#define DV_W KC_QUOT // W
#define DV_TILD KC_NUHS // ~ (dead)
// Row 4
#define DV_AGRV KC_NUBS // à
#define DV_SCLN KC_Z // ;
#define DV_Q KC_X // Q
#define DV_COMM KC_C // ,
#define DV_I KC_V // I
#define DV_Y KC_B // Y
#define DV_X KC_N // X
#define DV_R KC_M // R
#define DV_L KC_COMM // L
#define DV_P KC_DOT // P
#define DV_J KC_SLSH // J
/* Shifted symbols
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
* │ * │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 0 │ 0 │ + │ % │       │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
* │     │ ? │ < │ > │   │ ! │   │   │   │   │   │   │ = │     │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
* │      │   │   │   │   │   │   │   │   │   │   │   │ # │    │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
* │    │ ç │ | │   │ @ │   │   │   │   │   │   │   │          │
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
* │    │    │    │                        │    │    │    │    │
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
*/
// Row 1
#define DV_ASTR S(DV_LDAQ) // *
#define DV_1 S(DV_RDAQ) // 1
#define DV_2 S(DV_SLSH) // 2
#define DV_3 S(DV_MINS) // 3
#define DV_4 S(DV_EGRV) // 4
#define DV_5 S(DV_BSLS) // 5
#define DV_6 S(DV_CIRC) // 6
#define DV_7 S(DV_LPRN) // 7
#define DV_8 S(DV_GRV) // 8
#define DV_9 S(DV_RPRN) // 9
#define DV_0 S(DV_UNDS) // 0
#define DV_PLUS S(DV_LBRC) // +
#define DV_PERC S(DV_RBRC) // %
// Row 2
#define DV_QUES S(DV_COLN) // ?
#define DV_LABK S(DV_QUOT) // <
#define DV_RABK S(DV_EACU) // >
#define DV_EXLM S(DV_DOT) // !
#define DV_EQL S(DV_DIAE) // =
// Row 3
#define DV_HASH S(DV_TILD) // #
// Row 4
#define DV_CCED S(DV_AGRV) // ç
#define DV_PIPE S(DV_SCLN) // |
#define DV_AT S(DV_COMM) // @
+5
View File
@@ -20,6 +20,11 @@
// clang-format off
#ifdef CH_H
// The ChibiOS ch.h file defines this...
# undef CH_H
#endif
/*
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
* │ § │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ ' │ ^ │       │
+253
View File
@@ -0,0 +1,253 @@
/* Copyright 2020 Guillaume Gérard
*
* 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/>.
*/
/* French AZERTY - AFNOR NF Z71-300
*
* A standard for the French keyboard
*
* The project was launched at the end of 2015 on the proposal of the General
* Delegation for the French language and the languages ​​of France (Ministry
* of Culture), starting from the observation that the current "azerty"
* keyboards constrain the writing of French, languages regional and European
* languages ​​with Latin alphabet.
*
* For the first time, a standard (NF Z71-300) defines the placement of
* characters on the French keyboard. It offers two layouts, one of which
* closely follows the QWERTY keyboard used by most people who write in French.
*
* However, it is in many ways superior to the old keyboard:
*
* - it contains all the characters required to enter text in French (for example É, œ and ")
* - it is designed to be more ergonomic and allow faster typing
* - it includes almost 60 additional characters for entering foreign languages, technical content, etc
* - however, the characters remain easy to locate thanks to intuitive groupings
*
* Source: https://norme-azerty.fr
*/
#pragma once
#include "keymap.h"
// clang-format off
/*
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
* │ @ │ à │ é │ è │ ê │ ( │ ) │ ‘ │ ’ │ « │ » │ ' │ ^ │       │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
* │     │ A │ Z │ E │ R │ T │ Y │ U │ I │ O │ P │ - │ + │     │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
* │      │ Q │ S │ D │ F │ G │ H │ J │ K │ L │ M │ / │ * │    │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
* │    │ < │ W │ X │ C │ V │ B │ N │ . │ , │ : │ ; │          │
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
* │    │    │    │                        │    │    │    │    │
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
*/
// Row 1
#define FR_AT KC_GRV // @
#define FR_AGRV KC_1 // à
#define FR_EACU KC_2 // é
#define FR_EGRV KC_3 // è
#define FR_ECIR KC_4 // ê
#define FR_LPRN KC_5 // (
#define FR_RPRN KC_6 // )
#define FR_LSQU KC_7 // ‘
#define FR_RSQU KC_8 // ’
#define FR_LDAQ KC_9 // «
#define FR_RDAQ KC_0 // »
#define FR_QUOT KC_MINS // '
#define FR_DCIR KC_EQL // ^ (dead)
// Row 2
#define FR_A KC_Q // A
#define FR_Z KC_W // Z
#define FR_E KC_E // E
#define FR_R KC_R // R
#define FR_T KC_T // T
#define FR_Y KC_Y // Y
#define FR_U KC_U // U
#define FR_I KC_I // I
#define FR_O KC_O // O
#define FR_P KC_P // P
#define FR_MINS KC_LBRC // -
#define FR_PLUS KC_RBRC // +
// Row 3
#define FR_Q KC_A // Q
#define FR_S KC_S // S
#define FR_D KC_D // D
#define FR_F KC_F // F
#define FR_G KC_G // G
#define FR_H KC_H // H
#define FR_J KC_J // J
#define FR_K KC_K // K
#define FR_L KC_L // L
#define FR_M KC_SCLN // M
#define FR_SLSH KC_QUOT // /
#define FR_ASTR KC_NUHS // *
// Row 4
#define FR_LABK KC_NUBS // <
#define FR_W KC_Z // W
#define FR_X KC_X // X
#define FR_C KC_C // C
#define FR_V KC_V // V
#define FR_B KC_B // B
#define FR_N KC_N // N
#define FR_DOT KC_M // .
#define FR_COMM KC_COMM // ,
#define FR_COLN KC_DOT // :
#define FR_SCLN KC_SLSH // ;
/* Shifted symbols
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
* │ # │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ " │ ¨ │       │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
* │     │   │   │   │   │   │   │   │   │   │   │ – │ ± │     │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
* │      │   │   │   │   │   │   │   │   │   │   │ \ │ ½ │    │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
* │    │ > │   │   │   │   │   │   │ ? │ ! │ … │ = │          │
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
* │    │    │    │                        │    │    │    │    │
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
*/
// Row 1
#define FR_HASH S(FR_AT) // #
#define FR_1 S(FR_AGRV) // 1
#define FR_2 S(FR_EACU) // 2
#define FR_3 S(FR_EGRV) // 3
#define FR_4 S(FR_ECIR) // 4
#define FR_5 S(FR_LPRN) // 5
#define FR_6 S(FR_RPRN) // 6
#define FR_7 S(FR_LSQU) // 7
#define FR_8 S(FR_RSQU) // 8
#define FR_9 S(FR_LDAQ) // 9
#define FR_0 S(FR_RDAQ) // 0
#define FR_DQUO S(FR_QUOT) // "
#define FR_DIAE S(FR_DCIR) // ¨ (dead)
// Row 2
#define FR_NDSH S(FR_MINS) // –
#define FR_PLMN S(FR_PLUS) // ±
// Row 3
#define FR_BSLS S(FR_SLSH) // (backslash)
#define FR_HALF S(FR_ASTR) // ½
// Row 4
#define FR_RABK S(FR_LABK) // >
#define FR_QUES S(FR_DOT) // ?
#define FR_EXLM S(FR_COMM) // !
#define FR_ELLP S(FR_COLN) // …
#define FR_EQL S(FR_SCLN) // =
/* AltGr symbols
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
* │ ˘ │ § │ ´ │ ` │ & │ [ │ ] │ ¯ │ _ │ “ │ ” │ ° │ ˇ │       │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
* │     │ æ │ £ │ € │ ® │ { │ } │ ù │ ˙ │ œ │ % │ − │ † │     │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
* │      │ θ │ ß │ $ │ ¤ │ µ │ Eu│   │ ∕ │ | │ ∞ │ ÷ │ × │    │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
* │    │ ≤ │ ʒ │ © │ ç │ ¸ │ − │ ~ │ ¿ │ ¡ │ · │ ≃ │          │
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
* │    │    │    │                        │    │    │    │    │
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
*/
// Row 1
#define FR_BREV ALGR(FR_AT) // ˘ (dead)
#define FR_SECT ALGR(FR_AGRV) // §
#define FR_ACUT ALGR(FR_EACU) // ´ (dead)
#define FR_GRV ALGR(FR_EGRV) // ` (dead)
#define FR_AMPR ALGR(FR_ECIR) // &
#define FR_LBRC ALGR(FR_LPRN) // [
#define FR_RBRC ALGR(FR_RPRN) // ]
#define FR_MACR ALGR(FR_LSQU) // ¯ (dead)
#define FR_UNDS ALGR(FR_RSQU) // _
#define FR_LDQU ALGR(FR_LDAQ) // “
#define FR_RDQU ALGR(FR_RDAQ) // ”
#define FR_DEG ALGR(FR_QUOT) // °
#define FR_CARN ALGR(FR_DCIR) // ˇ (dead)
// Row 2
#define FR_AE ALGR(FR_A) // æ
#define FR_PND ALGR(FR_Z) // £
#define FR_EURO ALGR(FR_E) // €
#define FR_REGD ALGR(FR_R) // ®
#define FR_LCBR ALGR(FR_T) // {
#define FR_RCBR ALGR(FR_Y) // }
#define FR_UGRV ALGR(FR_U) // ù
#define FR_DOTA ALGR(FR_I) // ˙ (dead)
#define FR_OE ALGR(FR_O) // œ
#define FR_PERC ALGR(FR_P) // %
#define FR_MMNS ALGR(FR_MINS) // −
#define FR_DAGG ALGR(FR_PLUS) // †
// Row 3
#define FR_THET ALGR(FR_Q) // θ
#define FR_SS ALGR(FR_S) // ß
#define FR_DLR ALGR(FR_D) // $
#define FR_CURR ALGR(FR_F) // ¤ (dead monetary key)
#define FR_DGRK ALGR(FR_G) // µ (dead Greek key)
#define FR_EU ALGR(FR_H) // Eu (dead European symbol key)
#define FR_DSLS ALGR(FR_K) // ∕ (dead)
#define FR_PIPE ALGR(FR_L) // |
#define FR_INFN ALGR(FR_M) // ∞
#define FR_DIV ALGR(FR_SLSH) // ÷
#define FR_MUL ALGR(FR_ASTR) // ×
// Row 4
#define FR_LEQL ALGR(FR_LABK) // ≤
#define FR_EZH ALGR(FR_W) // ʒ
#define FR_COPY ALGR(FR_X) // ©
#define FR_CCED ALGR(FR_C) // ç
#define FR_CEDL ALGR(FR_V) // ¸ (dead)
#define FR_DMNS ALGR(FR_B) // − (dead)
#define FR_DTIL ALGR(FR_N) // ~ (dead)
#define FR_IQUE ALGR(FR_DOT) // ¿
#define FR_IEXL ALGR(FR_COMM) // ¡
#define FR_MDDT ALGR(FR_COLN) // ·
#define FR_AEQL ALGR(FR_SCLN) // ≃
/* Shift+AltGr symbols
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
* │  ̑ │   │   │   │   │ ˝ │  ̏ │   │ — │ ‹ │ › │ ˚ │   │       │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
* │     │   │   │   │   │ ™ │   │   │  ̣ │   │ ‰ │ ‑ │ ‡ │     │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
* │      │   │   │   │   │   │ ˍ │   │   │   │   │ √ │ ¼ │    │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
* │    │ ≥ │   │   │   │ ˛ │   │   │   │  ̦ │   │ ≠ │          │
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
* │    │    │    │                        │    │    │    │    │
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
*/
// Row 1
#define FR_IBRV S(ALGR(FR_AT)) //  ̑ (dead)
#define FR_DACU S(ALGR(FR_LPRN)) // ˝ (dead)
#define FR_DGRV S(ALGR(FR_RPRN)) //  ̏ (dead)
#define FR_MDSH S(ALGR(FR_RSQU)) // —
#define FR_LSAQ S(ALGR(FR_LDAQ)) // ‹
#define FR_RSAQ S(ALGR(FR_RDAQ)) // ›
#define FR_RNGA S(ALGR(FR_QUOT)) // ˚ (dead)
// Row 2
#define FR_TM S(ALGR(FR_T)) // ™
#define FR_DOTB S(ALGR(FR_I)) //  ̣ (dead)
#define FR_PERM S(ALGR(FR_P)) // ‰
#define FR_NBHY S(ALGR(FR_MINS)) // ‑ (non-breaking hyphen)
#define FR_DDAG S(ALGR(FR_PLUS)) // ‡
// Row 3
#define FR_MACB S(ALGR(FR_H)) // ˍ (dead)
#define FR_SQRT S(ALGR(FR_SLSH)) // √
#define FR_QRTR S(ALGR(FR_ASTR)) // ¼
// Row 4
#define FR_GEQL S(ALGR(FR_LABK)) // ≥
#define FR_OGON S(ALGR(FR_V)) // ˛ (dead)
#define FR_DCMM S(ALGR(FR_COMM)) //  ̦ (dead)
#define FR_NEQL S(ALGR(FR_SCLN)) // ≠
+1 -1
View File
@@ -237,7 +237,7 @@
#define FR_PERM S(A(FR_LUGR)) // ‰
// Row 4
#define FR_GTEQ S(A(FR_LABK)) // ≥
#define FR_LSAQ S(A(FR_W)) // ›
#define FR_RSAQ S(A(FR_W)) // ›
#define FR_FRSL S(A(FR_X)) // ⁄
#define FR_CENT S(A(FR_C)) // ¢
#define FR_SQRT S(A(FR_V)) // √
+151
View File
@@ -0,0 +1,151 @@
/* Copyright 2020
*
* 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 "keymap.h"
// clang-format off
/*
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
* │ ; │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │       │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
* │     │ / │ ' │ פ │ ם │ ן │ ו │ ט │ א │ ר │ ק │ ] │ [ │     │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
* │      │ ף │ ך │ ל │ ח │ י │ ע │ כ │ ג │ ד │ ש │ , │ \ │    │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
* │    │   │ ץ │ ת │ צ │ מ │ נ │ ה │ ב │ ס │ ז │ . │          │
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
* │    │    │    │                        │    │    │    │    │
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
*/
// Row 1
#define IL_SCLN KC_GRV // ;
#define IL_1 KC_1 // 1
#define IL_2 KC_2 // 2
#define IL_3 KC_3 // 3
#define IL_4 KC_4 // 4
#define IL_5 KC_5 // 5
#define IL_6 KC_6 // 6
#define IL_7 KC_7 // 7
#define IL_8 KC_8 // 8
#define IL_9 KC_9 // 9
#define IL_0 KC_0 // 0
#define IL_MINS KC_MINS // -
#define IL_EQL KC_EQL // =
// Row 2
#define IL_SLSH KC_Q // /
#define IL_QUOT KC_W // '
#define IL_QOF KC_E // ק
#define IL_RESH KC_R // ר
#define IL_ALEF KC_T // א
#define IL_TET KC_Y // ט
#define IL_VAV KC_U // ו
#define IL_FNUN KC_I // ן
#define IL_FMEM KC_O // ם
#define IL_PE KC_P // פ
#define IL_RBRC KC_LBRC // ]
#define IL_LBRC KC_RBRC // [
// Row 3
#define IL_SHIN KC_A // ש
#define IL_DALT KC_S // ד
#define IL_GIML KC_D // ג
#define IL_KAF KC_F // כ
#define IL_AYIN KC_G // ע
#define IL_YOD KC_H // י
#define IL_HET KC_J // ח
#define IL_LAMD KC_K // ל
#define IL_FKAF KC_L // ך
#define IL_FPE KC_SCLN // ף
#define IL_COMM KC_QUOT // ,
#define IL_BSLS KC_NUHS // (backslash)
// Row 4
#define IL_ZAYN KC_Z // ז
#define IL_SMKH KC_X // ס
#define IL_BET KC_C // ב
#define IL_HE KC_V // ה
#define IL_NUN KC_B // נ
#define IL_MEM KC_N // מ
#define IL_TSDI KC_M // צ
#define IL_TAV KC_COMM // ת
#define IL_FTSD KC_DOT // ץ
#define IL_DOT KC_SLSH // .
/* Shifted symbols
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
* │ ~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ) │ ( │ _ │ + │       │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
* │     │   │   │   │   │   │   │   │   │   │   │ } │ { │     │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
* │      │   │   │   │   │   │   │   │   │   │ : │ " │ | │    │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
* │    │   │   │   │   │   │   │   │   │ > │ < │ ? │          │
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
* │    │    │    │                        │    │    │    │    │
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
*/
// Row 1
#define IL_TILD S(IL_SCLN) // ~
#define IL_EXLM S(IL_1) // !
#define IL_AT S(IL_2) // @
#define IL_PND S(IL_3) // #
#define IL_DLR S(IL_4) // $
#define IL_PERC S(IL_5) // %
#define IL_CIRC S(IL_6) // ^
#define IL_AMPR S(IL_7) // &
#define IL_ASTR S(IL_8) // *
#define IL_RPRN S(IL_9) // )
#define IL_LPRN S(IL_0) // (
#define IL_UNDS S(IL_MINS) // _
#define IL_PLUS S(IL_EQL) // +
// Row 2
#define IL_RCBR S(IL_RBRC) // }
#define IL_LCBR S(IL_LBRC) // {
// Row 3
#define IL_COLN S(IL_FPE) // :
#define IL_DQUO S(IL_COMM) // "
#define IL_PIPE S(IL_BSLS) // |
// Row 4
#define IL_RABK S(IL_TAV) // >
#define IL_LABK S(IL_FTSD) // <
#define IL_QUES S(IL_DOT) // ?
/* AltGr symbols
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
* │   │   │   │ € │ ₪ │ ° │   │   │ × │   │   │   │   │       │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
* │     │   │   │   │   │   │ װ │   │   │   │   │   │   │     │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
* │      │   │   │   │   │ ײ │ ױ │   │   │   │   │   │   │    │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
* │    │   │   │   │   │   │   │   │   │   │   │ ÷ │          │
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
* │    │    │    │                        │    │    │    │    │
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
*/
// Row 1
#define IL_EURO ALGR(IL_3) // €
#define IL_SHKL ALGR(IL_4) // ₪
#define IL_DEG ALGR(IL_5) // °
#define IL_MUL ALGR(IL_8) // ×
// Row 2
#define IL_DVAV ALGR(IL_TET) // װ
// Row 3
#define IL_VYOD ALGR(IL_AYIN) // ױ
#define IL_DYOD ALGR(IL_YOD) // ײ
// Row 4
#define IL_DIV ALGR(IL_DOT) // ÷
+122 -58
View File
@@ -13,66 +13,130 @@
* 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 KEYMAP_NEO2
#define KEYMAP_NEO2
#pragma once
#include "keymap.h"
#include "keymap_german.h"
#define NEO_A KC_D
#define NEO_B KC_N
#define NEO_C KC_R
#define NEO_D DE_OE
#define NEO_E KC_F
#define NEO_F KC_O
#define NEO_G KC_I
#define NEO_H KC_U
#define NEO_I KC_S
#define NEO_J DE_MINS
#define NEO_K DE_Z
#define NEO_L KC_E
#define NEO_M KC_M
#define NEO_N KC_J
#define NEO_O KC_G
#define NEO_P KC_V
#define NEO_Q KC_P
#define NEO_R KC_K
#define NEO_S KC_H
#define NEO_T KC_L
#define NEO_U KC_A
#define NEO_V KC_W
#define NEO_W KC_T
#define NEO_X KC_Q
#define NEO_Y DE_AE
#define NEO_Z KC_B
#define NEO_AE KC_C
#define NEO_OE KC_X
#define NEO_UE DE_Y
#define NEO_SS DE_UE
// clang-format off
#define NEO_DOT DE_DOT
#define NEO_COMM DE_COMM
/*
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
* │ ^ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ ` │       │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
* │     │ X │ V │ L │ C │ W │ K │ H │ G │ F │ Q │ ß │ ´ │     │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
* │  L3  │ U │ I │ A │ E │ O │ S │ N │ R │ T │ D │ Y │ L3│    │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
* │    │L4 │ Ü │ Ö │ Ä │ P │ Z │ B │ M │ , │ . │ J │          │
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
* │    │    │    │                        │    │ L4 │    │    │
* └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
*/
// Row 1
#define NE_CIRC KC_GRV // ^ (dead)
#define NE_1 KC_1 // 1
#define NE_2 KC_2 // 2
#define NE_3 KC_3 // 3
#define NE_4 KC_4 // 4
#define NE_5 KC_5 // 5
#define NE_6 KC_6 // 6
#define NE_7 KC_7 // 7
#define NE_8 KC_8 // 8
#define NE_9 KC_9 // 9
#define NE_0 KC_0 // 0
#define NE_MINS KC_MINS // -
#define NE_GRV KC_EQL // ` (dead)
// Row 2
#define NE_X KC_Q // X
#define NE_V KC_W // V
#define NE_L KC_E // L
#define NE_C KC_R // C
#define NE_W KC_T // W
#define NE_K KC_Y // K
#define NE_H KC_U // H
#define NE_G KC_I // G
#define NE_F KC_O // F
#define NE_Q KC_P // Q
#define NE_SS KC_LBRC // ß
#define NE_ACUT KC_RBRC // ´ (dead)
// Row 3
#define NE_L3L KC_CAPS // (layer 3)
#define NE_U KC_A // U
#define NE_I KC_S // I
#define NE_A KC_D // A
#define NE_E KC_F // E
#define NE_O KC_G // O
#define NE_S KC_H // S
#define NE_N KC_J // N
#define NE_R KC_K // R
#define NE_T KC_L // T
#define NE_D KC_SCLN // D
#define NE_Y KC_QUOT // Y
#define NE_L3R KC_NUHS // (layer 3)
// Row 4
#define NE_L4L KC_NUBS // (layer 4)
#define NE_UDIA KC_Z // Ü
#define NE_ODIA KC_X // Ö
#define NE_ADIA KC_C // Ä
#define NE_P KC_V // P
#define NE_Z KC_B // Z
#define NE_B KC_N // B
#define NE_M KC_M // M
#define NE_COMM KC_COMM // ,
#define NE_DOT KC_DOT // .
#define NE_J KC_SLSH // J
// Row 5
#define NE_L4R KC_ALGR // (layer 4)
#define NEO_1 DE_1
#define NEO_2 DE_2
#define NEO_3 DE_3
#define NEO_4 DE_4
#define NEO_5 DE_5
#define NEO_6 DE_6
#define NEO_7 DE_7
#define NEO_8 DE_8
#define NEO_9 DE_9
#define NEO_0 DE_0
#define NEO_MINS DE_SS
#define NEO_ACUT DE_PLUS
#define NEO_GRV DE_ACUT
#define NEO_CIRC DE_CIRC
#define NEO_L1_L KC_CAPS
#define NEO_L1_R DE_HASH
#define NEO_L2_L DE_LESS
#define NEO_L2_R KC_ALGR
#endif
// DEPRECATED
#define NEO_A NE_A
#define NEO_B NE_B
#define NEO_C NE_C
#define NEO_D NE_D
#define NEO_E NE_E
#define NEO_F NE_F
#define NEO_G NE_G
#define NEO_H NE_H
#define NEO_I NE_I
#define NEO_J NE_J
#define NEO_K NE_K
#define NEO_L NE_L
#define NEO_M NE_M
#define NEO_N NE_N
#define NEO_O NE_O
#define NEO_P NE_P
#define NEO_Q NE_Q
#define NEO_R NE_R
#define NEO_S NE_S
#define NEO_T NE_T
#define NEO_U NE_U
#define NEO_V NE_V
#define NEO_W NE_W
#define NEO_X NE_X
#define NEO_Y NE_Y
#define NEO_Z NE_Z
#define NEO_AE NE_ADIA
#define NEO_OE NE_ODIA
#define NEO_UE NE_UDIA
#define NEO_SS NE_SS
#define NEO_DOT NE_DOT
#define NEO_COMM NE_COMM
#define NEO_1 NE_1
#define NEO_2 NE_2
#define NEO_3 NE_3
#define NEO_4 NE_4
#define NEO_5 NE_5
#define NEO_6 NE_6
#define NEO_7 NE_7
#define NEO_8 NE_8
#define NEO_9 NE_9
#define NEO_0 NE_0
#define NEO_MINS NE_MINS
#define NEO_ACUT NE_ACUT
#define NEO_GRV NE_GRV
#define NEO_CIRC NE_CIRC
#define NEO_L1_L NE_L3L
#define NEO_L1_R NE_L3R
#define NEO_L2_L NE_L4L
#define NEO_L2_R NE_L4R
+2 -4
View File
@@ -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 KEYMAP_NORDIC_H
#define KEYMAP_NORDIC_H
#pragma once
#include "keymap.h"
@@ -66,5 +66,3 @@
#define NO_BSLS ALGR(KC_MINS)
#define NO_MU ALGR(KC_M)
#endif
+2 -4
View File
@@ -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 KEYMAP_PLOVER_DVORAK_H
#define KEYMAP_PLOVER_DVORAK_H
#pragma once
#include "keymap_dvorak.h"
@@ -43,5 +43,3 @@
#define PD_O DV_V
#define PD_E DV_N
#define PD_U DV_M
#endif
@@ -0,0 +1,234 @@
/* Copyright 2020
*
* 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 "keymap.h"
// clang-format off
/*
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬─────┐
* │ § │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ ' │ + │     │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬───┤
* │     │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ º │ ´ │   │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐  │
* │      │ A │ S │ D │ F │ G │ H │ J │ K │ L │ Ç │ ~ │ \ │  │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴──┤
* │    │ < │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ - │        │
* ├────┴┬──┴─┬─┴───┼───┴───┴───┴───┴───┴───┼───┴─┬─┴──┬─────┤
* │     │    │     │                       │     │    │     │
* └─────┴────┴─────┴───────────────────────┴─────┴────┴─────┘
*/
// Row 1
#define PT_SECT KC_GRV // §
#define PT_1 KC_1 // 1
#define PT_2 KC_2 // 2
#define PT_3 KC_3 // 3
#define PT_4 KC_4 // 4
#define PT_5 KC_5 // 5
#define PT_6 KC_6 // 6
#define PT_7 KC_7 // 7
#define PT_8 KC_8 // 8
#define PT_9 KC_9 // 9
#define PT_0 KC_0 // 0
#define PT_QUOT KC_MINS // '
#define PT_PLUS KC_EQL // +
// Row 2
#define PT_Q KC_Q // Q
#define PT_W KC_W // W
#define PT_E KC_E // E
#define PT_R KC_R // R
#define PT_T KC_T // T
#define PT_Y KC_Y // Y
#define PT_U KC_U // U
#define PT_I KC_I // I
#define PT_O KC_O // O
#define PT_P KC_P // P
#define PT_MORD KC_LBRC // º
#define PT_ACUT KC_RBRC // ´ (dead)
// Row 3
#define PT_A KC_A // A
#define PT_S KC_S // S
#define PT_D KC_D // D
#define PT_F KC_F // F
#define PT_G KC_G // G
#define PT_H KC_H // H
#define PT_J KC_J // J
#define PT_K KC_K // K
#define PT_L KC_L // L
#define PT_CCED KC_SCLN // Ç
#define PT_TILD KC_QUOT // ~ (dead)
#define PT_BSLS KC_NUHS // (backslash)
// Row 4
#define PT_LABK KC_NUBS // <
#define PT_Z KC_Z // Z
#define PT_X KC_X // X
#define PT_C KC_C // C
#define PT_V KC_V // V
#define PT_B KC_B // B
#define PT_N KC_N // N
#define PT_M KC_M // M
#define PT_COMM KC_COMM // ,
#define PT_DOT KC_DOT // .
#define PT_MINS KC_SLSH // -
/* Shifted symbols
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬─────┐
* │ ± │ ! │ " │ # │ $ │ % │ & │ / │ ( │ ) │ = │ ? │ * │     │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬───┤
* │     │   │   │   │   │   │   │   │   │   │   │ ª │ ` │   │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐  │
* │      │   │   │   │   │   │   │   │   │   │   │ ^ │ | │  │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴──┤
* │    │ > │   │   │   │   │   │   │   │ ; │ : │ _ │        │
* ├────┴┬──┴─┬─┴───┼───┴───┴───┴───┴───┴───┼───┴─┬─┴──┬─────┤
* │     │    │     │                       │     │    │     │
* └─────┴────┴─────┴───────────────────────┴─────┴────┴─────┘
*/
// Row 1
#define PT_PLMN S(PT_SECT) // ±
#define PT_EXLM S(PT_1) // !
#define PT_DQUO S(PT_2) // "
#define PT_HASH S(PT_3) // #
#define PT_DLR S(PT_4) // $
#define PT_PERC S(PT_5) // %
#define PT_AMPR S(PT_6) // &
#define PT_SLSH S(PT_7) // /
#define PT_LPRN S(PT_8) // (
#define PT_RPRN S(PT_9) // )
#define PT_EQL S(PT_0) // =
#define PT_QUES S(PT_QUOT) // ?
#define PT_ASTR S(PT_PLUS) // *
// Row 2
#define PT_FORD S(PT_MORD) // ª
#define PT_GRV S(PT_ACUT) // ` (dead)
// Row 3
#define PT_CIRC S(PT_TILD) // ^ (dead)
#define PT_PIPE S(PT_BSLS) // |
// Row 4
#define PT_RABK S(PT_LABK) // >
#define PT_SCLN S(PT_COMM) // ;
#define PT_COLN S(PT_DOT) // :
#define PT_UNDS S(PT_MINS) // _
/* Alted symbols
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬─────┐
* │   │  │ @ │ € │ £ │ ‰ │ ¶ │ ÷ │ [ │ ] │ ≠ │   │   │     │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬───┤
* │     │ Œ │ ∑ │ Æ │ ® │ ™ │ ¥ │ † │ ı │ Ø │ π │ ° │ ¨ │   │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐  │
* │      │ Å │ ß │ ∂ │ ƒ │ ˙ │ ˇ │ ¯ │ „ │ ‘ │ ¸ │ ˜ │ ‹ │  │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴──┤
* │    │ ≤ │ Ω │ « │ © │ √ │ ∫ │ ¬ │ µ │ “ │ … │ — │        │
* ├────┴┬──┴─┬─┴───┼───┴───┴───┴───┴───┴───┼───┴─┬─┴──┬─────┤
* │     │    │     │                       │     │    │     │
* └─────┴────┴─────┴───────────────────────┴─────┴────┴─────┘
*/
// Row 1
#define PT_APPL A(PT_1) //  (Apple logo)
#define PT_AT A(PT_2) // @
#define PT_EURO A(PT_3) // €
#define PT_PND A(PT_4) // £
#define PT_PERM A(PT_5) // ‰
#define PT_PILC A(PT_6) // ¶
#define PT_DIV A(PT_7) // ÷
#define PT_LBRC A(PT_8) // [
#define PT_RBRC A(PT_9) // ]
#define PT_NEQL A(PT_0) // ≠
// Row 2
#define PT_OE A(PT_Q) // Œ
#define PT_NARS A(PT_W) // ∑
#define PT_AE A(PT_E) // Æ
#define PT_REGD A(PT_R) // ®
#define PT_TM A(PT_T) // ™
#define PT_YEN A(PT_Y) // ¥
#define PT_DAGG A(PT_U) // †
#define PT_DLSI A(PT_I) // ı
#define PT_OSTR A(PT_O) // Ø
#define PT_PI A(PT_P) // π
#define PT_DEG A(PT_MORD) // °
#define PT_DIAE A(PT_ACUT) // ¨ (dead)
// Row 3
#define PT_ARNG A(PT_A) // å
#define PT_SS A(PT_S) // ß
#define PT_PDIF A(PT_D) // ∂
#define PT_FHK A(PT_F) // ƒ
#define PT_DOTA A(PT_G) // ˙
#define PT_CARN A(PT_H) // ˇ
#define PT_MACR A(PT_J) // ¯
#define PT_DLQU A(PT_K) // „
#define PT_LSQU A(PT_L) // ‘
#define PT_CEDL A(PT_CCED) // ¸
#define PT_STIL A(PT_TILD) // ˜ (dead)
#define PT_LSAQ A(PT_BSLS) // ‹
// Row 4
#define PT_LTEQ A(PT_LABK) // ≤
#define PT_OMEG A(PT_Z) // Ω
#define PT_LDAQ A(PT_X) // «
#define PT_COPY A(PT_C) // ©
#define PT_SQRT A(PT_V) // √
#define PT_INTG A(PT_B) // ∫
#define PT_NOT A(PT_N) // ¬
#define PT_MICR A(PT_M) // µ
#define PT_LDQU A(PT_COMM) // “
#define PT_ELLP A(PT_DOT) // …
#define PT_MDSH A(PT_MINS) // —
/* Shift+Alted symbols
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬─────┐
* │   │ ¡ │ fi │ fl │ ¢ │ ∞ │ • │ ⁄ │ { │ } │ ≈ │ ¿ │ ◊ │     │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬───┤
* │     │   │   │   │   │   │   │ ‡ │ ˚ │   │ ∏ │   │ ˝ │   │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐  │
* │      │   │   │ ∆ │   │   │   │   │ ‚ │ ’ │ ˛ │ ˆ │ › │  │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴──┤
* │    │ ≥ │   │ » │   │   │   │   │   │ ” │ · │ – │        │
* ├────┴┬──┴─┬─┴───┼───┴───┴───┴───┴───┴───┼───┴─┬─┴──┬─────┤
* │     │    │     │                       │     │    │     │
* └─────┴────┴─────┴───────────────────────┴─────┴────┴─────┘
*/
// Row 1
#define PT_IEXL S(A(PT_1)) // ¡
#define PT_FI S(A(PT_2)) // fi
#define PT_FL S(A(PT_3)) // fl
#define PT_CENT S(A(PT_4)) // ¢
#define PT_INFN S(A(PT_5)) // ∞
#define PT_BULT S(A(PT_6)) // •
#define PT_FRSL S(A(PT_7)) // ⁄
#define PT_LCBR S(A(PT_8)) // {
#define PT_RCBR S(A(PT_9)) // }
#define PT_AEQL S(A(PT_0)) // ≈
#define PT_IQUE S(A(PT_QUOT)) // ¿
#define PT_LOZN S(A(PT_PLUS)) // ◊
// Row 2
#define PT_DDAG S(A(PT_U)) // ‡
#define PT_RNGA S(A(PT_I)) // ˚
#define PT_NARP S(A(PT_P)) // ∏
#define PT_DACU S(A(PT_ACUT)) // ˝
// Row 3
#define PT_INCR S(A(PT_D)) // ∆
#define PT_SLQU S(A(PT_K)) // ‚
#define PT_RSQU S(A(PT_L)) // ’
#define PT_OGON S(A(PT_CCED)) // ˛
#define PT_DCIR S(A(PT_TILD)) // ˆ (dead)
#define PT_RSAQ S(A(PT_BSLS)) // ›
// Row 4
#define PT_GTEQ S(A(PT_LABK)) // ≥
#define PT_RDAQ S(A(PT_X)) // »
#define PT_RDQU S(A(PT_COMM)) // ”
#define PT_MDDT S(A(PT_DOT)) // ·
#define PT_NDSH S(A(PT_MINS)) // –
+1 -1
View File
@@ -117,7 +117,7 @@
#define ES_CIRC S(ES_GRV) // ^ (dead)
#define ES_ASTR S(ES_PLUS) // *
// Row 3
#define ES_DIAE S(ES_GRV) // ¨ (dead)
#define ES_DIAE S(ES_ACUT) // ¨ (dead)
// Row 4
#define ES_RABK S(ES_LABK) // >
#define ES_SCLN S(KC_COMM) // ;
@@ -26,7 +26,7 @@
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
* │     │ . │ , │ Ñ │ P │ Y │ F │ G │ C │ H │ L │ ` │ + │     │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
* │      │ A │ O │ E │ U │ I │ D │ R │ T │ N │ S │ ' │ Ç │    │
* │      │ A │ O │ E │ U │ I │ D │ R │ T │ N │ S │ ´ │ Ç │    │
* ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
* │    │ < │ - │ Q │ J │ K │ X │ B │ M │ W │ V │ Z │          │
* ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
@@ -119,7 +119,7 @@
#define DV_CIRC S(DV_GRV) // ^ (dead)
#define DV_ASTR S(DV_PLUS) // *
// Row 3
#define DV_DIAE S(DV_GRV) // ¨ (dead)
#define DV_DIAE S(DV_ACUT) // ¨ (dead)
// Row 4
#define DV_RABK S(DV_LABK) // >
#define DV_UNDS S(DV_MINS) // _
+2 -4
View File
@@ -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 KEYMAP_STENO_H
#define KEYMAP_STENO_H
#pragma once
#include "keymap.h"
@@ -72,5 +72,3 @@ enum steno_keycodes {
STN_ZR,
STN__MAX = STN_ZR, // must be less than QK_STENO_BOLT
};
#endif
@@ -59,7 +59,7 @@
#define US_O KC_O // O
#define US_P KC_P // P
#define US_LBRC KC_LBRC // [
#define US_RBRC KC_LBRC // ]
#define US_RBRC KC_RBRC // ]
#define US_BSLS KC_BSLS // (backslash)
// Row 3
#define US_A KC_A // A
+1 -1
View File
@@ -88,7 +88,7 @@ const uint8_t ascii_to_keycode_lut[128] PROGMEM = {
// P Q R S T U V W
BE_P, BE_Q, BE_R, BE_S, BE_T, BE_U, BE_V, BE_W,
// X Y Z [ \ ] ^ _
BE_X, BE_Y, BE_Z, BE_CIRC, BE_LABK, BE_DLR, BE_SECT, BE_MINS,
BE_X, BE_Y, BE_Z, BE_DCIR, BE_LABK, BE_DLR, BE_SECT, BE_MINS,
// ` a b c d e f g
BE_MICR, BE_A, BE_B, BE_C, BE_D, BE_E, BE_F, BE_G,
// h i j k l m n o
@@ -0,0 +1,100 @@
/* Copyright 2020
*
* 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/>.
*/
// Sendstring lookup tables for Canadian Multilingual layouts
#pragma once
#include "keymap_canadian_multilingual.h"
#include "quantum.h"
// clang-format off
const uint8_t ascii_to_shift_lut[16] PROGMEM = {
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1),
KCLUT_ENTRY(1, 1, 1, 1, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 1, 0, 0, 0, 0, 1),
KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
KCLUT_ENTRY(1, 1, 1, 0, 1, 0, 0, 1),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0)
};
const uint8_t ascii_to_altgr_lut[16] PROGMEM = {
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 1, 0, 1, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 0, 0),
KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0)
};
const uint8_t ascii_to_keycode_lut[128] PROGMEM = {
// NUL SOH STX ETX EOT ENQ ACK BEL
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
// BS TAB LF VT FF CR SO SI
KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
// DLE DC1 DC2 DC3 DC4 NAK SYN ETB
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
// CAN EM SUB ESC FS GS RS US
XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
// ! " # $ % & '
KC_SPC, CA_1, CA_DOT, CA_3, CA_4, CA_5, CA_7, CA_COMM,
// ( ) * + , - . /
CA_9, CA_0, CA_8, CA_EQL, CA_COMM, CA_MINS, CA_DOT, CA_SLSH,
// 0 1 2 3 4 5 6 7
CA_0, CA_1, CA_2, CA_3, CA_4, CA_5, CA_6, CA_7,
// 8 9 : ; < = > ?
CA_8, CA_9, CA_SCLN, CA_SCLN, CA_DOT, CA_EQL, CA_COMM, CA_6,
// @ A B C D E F G
CA_2, CA_A, CA_B, CA_C, CA_D, CA_E, CA_F, CA_G,
// H I J K L M N O
CA_H, CA_I, CA_J, CA_K, CA_L, CA_M, CA_N, CA_O,
// P Q R S T U V W
CA_P, CA_Q, CA_R, CA_S, CA_T, CA_U, CA_V, CA_W,
// X Y Z [ \ ] ^ _
CA_X, CA_Y, CA_Z, CA_9, CA_SLSH, CA_0, CA_CIRC, CA_MINS,
// ` a b c d e f g
CA_CIRC, CA_A, CA_B, CA_C, CA_D, CA_E, CA_F, CA_G,
// h i j k l m n o
CA_H, CA_I, CA_J, CA_K, CA_L, CA_M, CA_N, CA_O,
// p q r s t u v w
CA_P, CA_Q, CA_R, CA_S, CA_T, CA_U, CA_V, CA_W,
// x y z { | } ~ DEL
CA_X, CA_Y, CA_Z, CA_7, CA_SLSH, CA_8, CA_CCED, KC_DEL
};
@@ -0,0 +1,80 @@
/* Copyright 2020 Guillaume Gérard
*
* 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/>.
*/
// Sendstring lookup tables for Dvorak French layouts
#pragma once
#include "keymap_dvorak_fr.h"
// clang-format off
const uint8_t ascii_to_shift_lut[16] PROGMEM = {
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 1, 0, 1, 0, 1, 0, 0),
KCLUT_ENTRY(0, 0, 1, 1, 0, 0, 0, 0),
KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
KCLUT_ENTRY(1, 1, 0, 0, 1, 1, 1, 1),
KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 1, 0, 0, 0),
};
const uint8_t ascii_to_keycode_lut[128] PROGMEM = {
// NUL SOH STX ETX EOT ENQ ACK BEL
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
// BS TAB LF VT FF CR SO SI
KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
// DLE DC1 DC2 DC3 DC4 NAK SYN ETB
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
// CAN EM SUB ESC FS GS RS US
XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
// ! " # $ % & '
KC_SPC, DV_DOT, XXXXXXX, DV_TILD, XXXXXXX, DV_RBRC, XXXXXXX, DV_QUOT,
// ( ) * + , - . /
DV_LPRN, DV_RPRN, DV_LDAQ, DV_LBRC, DV_COMM, DV_MINS, DV_DOT, DV_SLSH,
// 0 1 2 3 4 5 6 7
DV_UNDS, DV_RDAQ, DV_SLSH, DV_MINS, DV_EGRV, DV_BSLS, DV_CIRC, DV_LPRN,
// 8 9 : ; < = > ?
DV_GRV, DV_RPRN, DV_COLN, DV_SCLN, DV_QUOT, DV_DIAE, DV_EACU, DV_COLN,
// @ A B C D E F G
DV_COMM, DV_A, DV_B, DV_C, DV_D, DV_E, DV_F, DV_G,
// H I J K L M N O
DV_H, DV_I, DV_J, DV_K, DV_L, DV_M, DV_N, DV_O,
// P Q R S T U V W
DV_P, DV_Q, DV_R, DV_S, DV_T, DV_U, DV_V, DV_W,
// X Y Z [ \ ] ^ _
DV_X, DV_Y, DV_Z, DV_LBRC, DV_BSLS, DV_RBRC, DV_CIRC, DV_UNDS,
// ` a b c d e f g
DV_GRV, DV_A, DV_B, DV_C, DV_D, DV_E, DV_F, DV_G,
// h i j k l m n o
DV_H, DV_I, DV_J, DV_K, DV_L, DV_M, DV_N, DV_O,
// p q r s t u v w
DV_P, DV_Q, DV_R, DV_S, DV_T, DV_U, DV_V, DV_W,
// x y z { | } ~ DEL
DV_X, DV_Y, DV_Z, XXXXXXX, DV_SCLN, XXXXXXX, DV_TILD, KC_DEL
};
+2 -2
View File
@@ -74,13 +74,13 @@ const uint8_t ascii_to_keycode_lut[128] PROGMEM = {
XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
// ! " # $ % & '
KC_SPC, FR_EXLM, FR_QUOT, FR_DQUO, FR_DLR, FR_UGRV, FR_AMPR, FR_QUOT,
KC_SPC, FR_EXLM, FR_DQUO, FR_DQUO, FR_DLR, FR_UGRV, FR_AMPR, FR_QUOT,
// ( ) * + , - . /
FR_LPRN, FR_RPRN, FR_ASTR, FR_EQL, FR_COMM, FR_MINS, FR_SCLN, FR_COLN,
// 0 1 2 3 4 5 6 7
FR_AGRV, FR_AMPR, FR_EACU, FR_DQUO, FR_QUOT, FR_LPRN, FR_MINS, FR_EGRV,
// 8 9 : ; < = > ?
FR_CCED, FR_AGRV, FR_COLN, FR_SCLN, FR_LABK, FR_EQL, FR_LABK, FR_COMM,
FR_UNDS, FR_CCED, FR_COLN, FR_SCLN, FR_LABK, FR_EQL, FR_LABK, FR_COMM,
// @ A B C D E F G
FR_AGRV, FR_A, FR_B, FR_C, FR_D, FR_E, FR_F, FR_G,
// H I J K L M N O
@@ -0,0 +1,100 @@
/* Copyright 2020 Guillaume Gérard
*
* 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/>.
*/
// Sendstring lookup tables for French (AZERTY - AFNOR NF Z71-300) layouts
#pragma once
#include "keymap_french_afnor.h"
#include "quantum.h"
// clang-format off
const uint8_t ascii_to_shift_lut[16] PROGMEM = {
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 1, 1, 1, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
KCLUT_ENTRY(1, 1, 0, 0, 0, 1, 1, 1),
KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1),
KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
KCLUT_ENTRY(1, 1, 1, 0, 1, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0)
};
const uint8_t ascii_to_altgr_lut[16] PROGMEM = {
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 1, 1, 1, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 0, 1),
KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0)
};
const uint8_t ascii_to_keycode_lut[128] PROGMEM = {
// NUL SOH STX ETX EOT ENQ ACK BEL
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
// BS TAB LF VT FF CR SO SI
KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
// DLE DC1 DC2 DC3 DC4 NAK SYN ETB
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
// CAN EM SUB ESC FS GS RS US
XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
// ! " # $ % & '
KC_SPC, FR_COMM, FR_QUOT, FR_AT, FR_D, FR_P, FR_ECIR, FR_QUOT,
// ( ) * + , - . /
FR_LPRN, FR_RPRN, FR_ASTR, FR_PLUS, FR_COMM, FR_MINS, FR_DOT, FR_SLSH,
// 0 1 2 3 4 5 6 7
FR_RDAQ, FR_AGRV, FR_EACU, FR_EGRV, FR_ECIR, FR_LPRN, FR_RPRN, FR_LSQU,
// 8 9 : ; < = > ?
FR_RSQU, FR_LDAQ, FR_COLN, FR_SCLN, FR_LABK, FR_SCLN, FR_LABK, FR_DOT,
// @ A B C D E F G
FR_AT, FR_A, FR_B, FR_C, FR_D, FR_E, FR_F, FR_G,
// H I J K L M N O
FR_H, FR_I, FR_J, FR_K, FR_L, FR_M, FR_N, FR_O,
// P Q R S T U V W
FR_P, FR_Q, FR_R, FR_S, FR_T, FR_U, FR_V, FR_W,
// X Y Z [ \ ] ^ _
FR_X, FR_Y, FR_Z, FR_LPRN, FR_SLSH, FR_RPRN, FR_DCIR, FR_RSQU,
// ` a b c d e f g
FR_EGRV, FR_A, FR_B, FR_C, FR_D, FR_E, FR_F, FR_G,
// h i j k l m n o
FR_H, FR_I, FR_J, FR_K, FR_L, FR_M, FR_N, FR_O,
// p q r s t u v w
FR_P, FR_Q, FR_R, FR_S, FR_T, FR_U, FR_V, FR_W,
// x y z { | } ~ DEL
FR_X, FR_Y, FR_Z, FR_T, FR_L, FR_Y, FR_N, KC_DEL
};
@@ -0,0 +1,100 @@
/* Copyright 2020
*
* 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/>.
*/
// Sendstring lookup tables for Portuguese layouts
#pragma once
#include "keymap_portuguese_osx_iso.h"
#include "quantum.h"
// clang-format off
const uint8_t ascii_to_shift_lut[16] PROGMEM = {
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 0),
KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1),
KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1),
KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1),
KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0)
};
const uint8_t ascii_to_altgr_lut[16] PROGMEM = {
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 0, 0)
};
const uint8_t ascii_to_keycode_lut[128] PROGMEM = {
// NUL SOH STX ETX EOT ENQ ACK BEL
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
// BS TAB LF VT FF CR SO SI
KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
// DLE DC1 DC2 DC3 DC4 NAK SYN ETB
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
// CAN EM SUB ESC FS GS RS US
XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
// ! " # $ % & '
KC_SPC, PT_1, PT_2, PT_3, PT_4, PT_5, PT_6, PT_QUOT,
// ( ) * + , - . /
PT_8, PT_9, PT_PLUS, PT_PLUS, PT_COMM, PT_MINS, PT_DOT, PT_7,
// 0 1 2 3 4 5 6 7
PT_0, PT_1, PT_2, PT_3, PT_4, PT_5, PT_6, PT_7,
// 8 9 : ; < = > ?
PT_8, PT_9, PT_DOT, PT_COMM, PT_LABK, PT_0, PT_LABK, PT_QUOT,
// @ A B C D E F G
PT_2, PT_A, PT_B, PT_C, PT_D, PT_E, PT_F, PT_G,
// H I J K L M N O
PT_H, PT_I, PT_J, PT_K, PT_L, PT_M, PT_N, PT_O,
// P Q R S T U V W
PT_P, PT_Q, PT_R, PT_S, PT_T, PT_U, PT_V, PT_W,
// X Y Z [ \ ] ^ _
PT_X, PT_Y, PT_Z, PT_8, PT_BSLS, PT_9, PT_TILD, PT_MINS,
// ` a b c d e f g
PT_ACUT, PT_A, PT_B, PT_C, PT_D, PT_E, PT_F, PT_G,
// h i j k l m n o
PT_H, PT_I, PT_J, PT_K, PT_L, PT_M, PT_N, PT_O,
// p q r s t u v w
PT_P, PT_Q, PT_R, PT_S, PT_T, PT_U, PT_V, PT_W,
// x y z { | } ~ DEL
PT_X, PT_Y, PT_Z, PT_8, PT_BSLS, PT_9, PT_TILD, KC_DEL
};
+137
View File
@@ -0,0 +1,137 @@
/* Copyright 2020 zvecr<git@zvecr.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 "quantum.h"
#ifdef BACKLIGHT_ENABLE
# include "backlight.h"
extern backlight_config_t backlight_config;
#else
// Cannot use BACKLIGHT_CAPS_LOCK without backlight being enabled
# undef BACKLIGHT_CAPS_LOCK
#endif
#ifndef LED_PIN_ON_STATE
# define LED_PIN_ON_STATE 1
#endif
#if defined(BACKLIGHT_CAPS_LOCK)
/** \brief Caps Lock indicator using backlight (for keyboards without dedicated LED)
*/
static void handle_backlight_caps_lock(led_t led_state) {
// Use backlight as Caps Lock indicator
uint8_t bl_toggle_lvl = 0;
if (led_state.caps_lock && !backlight_config.enable) {
// Turning Caps Lock ON and backlight is disabled in config
// Toggling backlight to the brightest level
bl_toggle_lvl = BACKLIGHT_LEVELS;
} else if (!led_state.caps_lock && backlight_config.enable) {
// Turning Caps Lock OFF and backlight is enabled in config
// Toggling backlight and restoring config level
bl_toggle_lvl = backlight_config.level;
}
// Set level without modify backlight_config to keep ability to restore state
backlight_set(bl_toggle_lvl);
}
#endif
/** \brief Lock LED set callback - keymap/user level
*
* \deprecated Use led_update_user() instead.
*/
__attribute__((weak)) void led_set_user(uint8_t usb_led) {}
/** \brief Lock LED set callback - keyboard level
*
* \deprecated Use led_update_kb() instead.
*/
__attribute__((weak)) void led_set_kb(uint8_t usb_led) { led_set_user(usb_led); }
/** \brief Lock LED update callback - keymap/user level
*
* \return True if led_update_kb() should run its own code, false otherwise.
*/
__attribute__((weak)) bool led_update_user(led_t led_state) { return true; }
/** \brief Lock LED update callback - keyboard level
*
* \return Ignored for now.
*/
__attribute__((weak)) bool led_update_kb(led_t led_state) {
bool res = led_update_user(led_state);
if (res) {
#if defined(LED_NUM_LOCK_PIN) || defined(LED_CAPS_LOCK_PIN) || defined(LED_SCROLL_LOCK_PIN) || defined(LED_COMPOSE_PIN) || defined(LED_KANA_PIN)
# if LED_PIN_ON_STATE == 0
// invert the whole thing to avoid having to conditionally !led_state.x later
led_state.raw = ~led_state.raw;
# endif
# ifdef LED_NUM_LOCK_PIN
writePin(LED_NUM_LOCK_PIN, led_state.num_lock);
# endif
# ifdef LED_CAPS_LOCK_PIN
writePin(LED_CAPS_LOCK_PIN, led_state.caps_lock);
# endif
# ifdef LED_SCROLL_LOCK_PIN
writePin(LED_SCROLL_LOCK_PIN, led_state.scroll_lock);
# endif
# ifdef LED_COMPOSE_PIN
writePin(LED_COMPOSE_PIN, led_state.compose);
# endif
# ifdef LED_KANA_PIN
writePin(LED_KANA_PIN, led_state.kana);
# endif
#endif
}
return res;
}
/** \brief Initialise any LED related hardware and/or state
*/
__attribute__((weak)) void led_init_ports(void) {
#ifdef LED_NUM_LOCK_PIN
setPinOutput(LED_NUM_LOCK_PIN);
writePin(LED_NUM_LOCK_PIN, !LED_PIN_ON_STATE);
#endif
#ifdef LED_CAPS_LOCK_PIN
setPinOutput(LED_CAPS_LOCK_PIN);
writePin(LED_CAPS_LOCK_PIN, !LED_PIN_ON_STATE);
#endif
#ifdef LED_SCROLL_LOCK_PIN
setPinOutput(LED_SCROLL_LOCK_PIN);
writePin(LED_SCROLL_LOCK_PIN, !LED_PIN_ON_STATE);
#endif
#ifdef LED_COMPOSE_PIN
setPinOutput(LED_COMPOSE_PIN);
writePin(LED_COMPOSE_PIN, !LED_PIN_ON_STATE);
#endif
#ifdef LED_KANA_PIN
setPinOutput(LED_KANA_PIN);
writePin(LED_KANA_PIN, !LED_PIN_ON_STATE);
#endif
}
/** \brief Entrypoint for protocol to LED binding
*/
__attribute__((weak)) void led_set(uint8_t usb_led) {
#ifdef BACKLIGHT_CAPS_LOCK
handle_backlight_caps_lock((led_t)usb_led);
#endif
led_set_kb(usb_led);
led_update_kb((led_t)usb_led);
}
+54
View File
@@ -0,0 +1,54 @@
/*
Copyright 2011 Jun Wako <wakojun@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
#include <stdint.h>
#include <stdbool.h>
/* FIXME: Add doxygen comments here. */
/* keyboard LEDs */
#define USB_LED_NUM_LOCK 0
#define USB_LED_CAPS_LOCK 1
#define USB_LED_SCROLL_LOCK 2
#define USB_LED_COMPOSE 3
#define USB_LED_KANA 4
#ifdef __cplusplus
extern "C" {
#endif
typedef union {
uint8_t raw;
struct {
bool num_lock : 1;
bool caps_lock : 1;
bool scroll_lock : 1;
bool compose : 1;
bool kana : 1;
uint8_t reserved : 3;
};
} led_t;
void led_set(uint8_t usb_led);
void led_init_ports(void);
#ifdef __cplusplus
}
#endif
+1 -1
View File
@@ -20,7 +20,7 @@
#include <stdint.h>
#include <stdbool.h>
#include "quantum.h"
#include "ledmatrix.h"
#include "led_matrix.h"
#include "progmem.h"
#include "config.h"
#include "eeprom.h"
+1 -4
View File
@@ -17,8 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef LED_MATRIX_H
#define LED_MATRIX_H
#pragma once
#ifndef BACKLIGHT_ENABLE
# error You must define BACKLIGHT_ENABLE with LED_MATRIX_ENABLE
@@ -123,5 +122,3 @@ typedef struct {
} led_matrix_driver_t;
extern const led_matrix_driver_t led_matrix_driver;
#endif
+1 -1
View File
@@ -18,7 +18,7 @@
#include <stdint.h>
#include <stdbool.h>
#include "quantum.h"
#include "ledmatrix.h"
#include "led_matrix.h"
/* Each driver needs to define a struct:
*
+1 -4
View File
@@ -13,8 +13,7 @@ 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 LED_TABLES_H
#define LED_TABLES_H
#pragma once
#include "progmem.h"
#include <stdint.h>
@@ -22,5 +21,3 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifdef USE_CIE1931_CURVE
extern const uint8_t CIE1931_CURVE[] PROGMEM;
#endif
#endif
+44 -30
View File
@@ -32,6 +32,17 @@ static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
extern matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values
extern matrix_row_t matrix[MATRIX_ROWS]; // debounced values
static inline void setPinOutput_writeLow(pin_t pin) {
ATOMIC_BLOCK_FORCEON {
setPinOutput(pin);
writePinLow(pin);
}
}
static inline void setPinInputHigh_atomic(pin_t pin) {
ATOMIC_BLOCK_FORCEON { setPinInputHigh(pin); }
}
// matrix code
#ifdef DIRECT_PINS
@@ -48,48 +59,47 @@ static void init_pins(void) {
}
static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
matrix_row_t last_row_value = current_matrix[current_row];
current_matrix[current_row] = 0;
// Start with a clear matrix row
matrix_row_t current_row_value = 0;
for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
pin_t pin = direct_pins[current_row][col_index];
if (pin != NO_PIN) {
current_matrix[current_row] |= readPin(pin) ? 0 : (MATRIX_ROW_SHIFTER << col_index);
current_row_value |= readPin(pin) ? 0 : (MATRIX_ROW_SHIFTER << col_index);
}
}
return (last_row_value != current_matrix[current_row]);
// If the row has changed, store the row and return the changed flag.
if (current_matrix[current_row] != current_row_value) {
current_matrix[current_row] = current_row_value;
return true;
}
return false;
}
#elif defined(DIODE_DIRECTION)
# if (DIODE_DIRECTION == COL2ROW)
static void select_row(uint8_t row) {
setPinOutput(row_pins[row]);
writePinLow(row_pins[row]);
}
static void select_row(uint8_t row) { setPinOutput_writeLow(row_pins[row]); }
static void unselect_row(uint8_t row) { setPinInputHigh(row_pins[row]); }
static void unselect_row(uint8_t row) { setPinInputHigh_atomic(row_pins[row]); }
static void unselect_rows(void) {
for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
setPinInputHigh(row_pins[x]);
setPinInputHigh_atomic(row_pins[x]);
}
}
static void init_pins(void) {
unselect_rows();
for (uint8_t x = 0; x < MATRIX_COLS; x++) {
setPinInputHigh(col_pins[x]);
setPinInputHigh_atomic(col_pins[x]);
}
}
static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
// Store last value of row prior to reading
matrix_row_t last_row_value = current_matrix[current_row];
// Clear data in matrix row
current_matrix[current_row] = 0;
// Start with a clear matrix row
matrix_row_t current_row_value = 0;
// Select row and wait for row selecton to stabilize
select_row(current_row);
@@ -101,34 +111,36 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
uint8_t pin_state = readPin(col_pins[col_index]);
// Populate the matrix row with the state of the col pin
current_matrix[current_row] |= pin_state ? 0 : (MATRIX_ROW_SHIFTER << col_index);
current_row_value |= pin_state ? 0 : (MATRIX_ROW_SHIFTER << col_index);
}
// Unselect row
unselect_row(current_row);
return (last_row_value != current_matrix[current_row]);
// If the row has changed, store the row and return the changed flag.
if (current_matrix[current_row] != current_row_value) {
current_matrix[current_row] = current_row_value;
return true;
}
return false;
}
# elif (DIODE_DIRECTION == ROW2COL)
static void select_col(uint8_t col) {
setPinOutput(col_pins[col]);
writePinLow(col_pins[col]);
}
static void select_col(uint8_t col) { setPinOutput_writeLow(col_pins[col]); }
static void unselect_col(uint8_t col) { setPinInputHigh(col_pins[col]); }
static void unselect_col(uint8_t col) { setPinInputHigh_atomic(col_pins[col]); }
static void unselect_cols(void) {
for (uint8_t x = 0; x < MATRIX_COLS; x++) {
setPinInputHigh(col_pins[x]);
setPinInputHigh_atomic(col_pins[x]);
}
}
static void init_pins(void) {
unselect_cols();
for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
setPinInputHigh(row_pins[x]);
setPinInputHigh_atomic(row_pins[x]);
}
}
@@ -142,20 +154,22 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
// For each row...
for (uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) {
// Store last value of row prior to reading
matrix_row_t last_row_value = current_matrix[row_index];
matrix_row_t last_row_value = current_matrix[row_index];
matrix_row_t current_row_value = last_row_value;
// Check row pin state
if (readPin(row_pins[row_index]) == 0) {
// Pin LO, set col bit
current_matrix[row_index] |= (MATRIX_ROW_SHIFTER << current_col);
current_row_value |= (MATRIX_ROW_SHIFTER << current_col);
} else {
// Pin HI, clear col bit
current_matrix[row_index] &= ~(MATRIX_ROW_SHIFTER << current_col);
current_row_value &= ~(MATRIX_ROW_SHIFTER << current_col);
}
// Determine if the matrix changed state
if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) {
matrix_changed = true;
if ((last_row_value != current_row_value)) {
matrix_changed |= true;
current_matrix[row_index] = current_row_value;
}
}
+76
View File
@@ -0,0 +1,76 @@
/*
Copyright 2011 Jun Wako <wakojun@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
#include <stdint.h>
#include <stdbool.h>
#if (MATRIX_COLS <= 8)
typedef uint8_t matrix_row_t;
#elif (MATRIX_COLS <= 16)
typedef uint16_t matrix_row_t;
#elif (MATRIX_COLS <= 32)
typedef uint32_t matrix_row_t;
#else
# error "MATRIX_COLS: invalid value"
#endif
#define MATRIX_ROW_SHIFTER ((matrix_row_t)1)
#ifdef __cplusplus
extern "C" {
#endif
/* number of matrix rows */
uint8_t matrix_rows(void);
/* number of matrix columns */
uint8_t matrix_cols(void);
/* should be called at early stage of startup before matrix_init.(optional) */
void matrix_setup(void);
/* intialize matrix for scaning. */
void matrix_init(void);
/* scan all key states on matrix */
uint8_t matrix_scan(void);
/* whether modified from previous scan. used after matrix_scan. */
bool matrix_is_modified(void) __attribute__((deprecated));
/* whether a switch is on */
bool matrix_is_on(uint8_t row, uint8_t col);
/* matrix state on row */
matrix_row_t matrix_get_row(uint8_t row);
/* print matrix for debug */
void matrix_print(void);
/* delay between changing matrix pin state and reading values */
void matrix_io_delay(void);
/* power control */
void matrix_power_up(void);
void matrix_power_down(void);
/* executes code for Quantum */
void matrix_init_quantum(void);
void matrix_scan_quantum(void);
void matrix_init_kb(void);
void matrix_scan_kb(void);
void matrix_init_user(void);
void matrix_scan_user(void);
#ifdef __cplusplus
}
#endif
+2
View File
@@ -112,3 +112,5 @@ __attribute__((weak)) uint8_t matrix_scan(void) {
matrix_scan_quantum();
return changed;
}
__attribute__((weak)) bool peek_matrix(uint8_t row_index, uint8_t col_index, bool raw) { return 0 != ((raw ? raw_matrix[row_index] : matrix[row_index]) & (MATRIX_ROW_SHIFTER << col_index)); }
+136 -51
View File
@@ -1,3 +1,5 @@
MCU_ORIG := $(MCU)
ifneq ($(findstring MKL26Z64, $(MCU)),)
# Cortex version
MCU = cortex-m0plus
@@ -14,7 +16,6 @@ ifneq ($(findstring MKL26Z64, $(MCU)),)
# Linker script to use
# - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
# or <keyboard_dir>/ld/
# - NOTE: a custom ld script is needed for EEPROM on Teensy LC
MCU_LDSCRIPT ?= MKL26Z64
# Startup code to use
@@ -80,37 +81,37 @@ ifneq ($(findstring MK20DX256, $(MCU)),)
BOARD ?= PJRC_TEENSY_3_1
endif
ifneq ($(findstring STM32F303, $(MCU)),)
ifneq ($(findstring STM32F042, $(MCU)),)
# Cortex version
MCU = cortex-m4
MCU = cortex-m0
# ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7
ARMV = 7
ARMV = 6
## chip/board settings
# - the next two should match the directories in
# <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
MCU_FAMILY = STM32
MCU_SERIES = STM32F3xx
MCU_SERIES = STM32F0xx
# Linker script to use
# - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
# or <keyboard_dir>/ld/
MCU_LDSCRIPT ?= STM32F303xC
MCU_LDSCRIPT ?= STM32F042x6
# Startup code to use
# - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
MCU_STARTUP ?= stm32f3xx
MCU_STARTUP ?= stm32f0xx
# Board: it should exist either in <chibios>/os/hal/boards/,
# <keyboard_dir>/boards/, or drivers/boards/
BOARD ?= GENERIC_STM32_F303XC
BOARD ?= GENERIC_STM32_F042X6
USE_FPU ?= yes
USE_FPU ?= no
# Options to pass to dfu-util when flashing
DFU_ARGS ?= -d 0483:df11 -a 0 -s 0x08000000:leave
DFU_SUFFIX_ARGS ?= -v 0483 -p df11
DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave
DFU_SUFFIX_ARGS ?= -v 0483 -p DF11
endif
ifneq ($(findstring STM32F072, $(MCU)),)
@@ -142,41 +143,8 @@ ifneq ($(findstring STM32F072, $(MCU)),)
USE_FPU ?= no
# Options to pass to dfu-util when flashing
DFU_ARGS ?= -d 0483:df11 -a 0 -s 0x08000000:leave
DFU_SUFFIX_ARGS ?= -v 0483 -p df11
endif
ifneq ($(findstring STM32F042, $(MCU)),)
# Cortex version
MCU = cortex-m0
# ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7
ARMV = 6
## chip/board settings
# - the next two should match the directories in
# <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
MCU_FAMILY = STM32
MCU_SERIES = STM32F0xx
# Linker script to use
# - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
# or <keyboard_dir>/ld/
MCU_LDSCRIPT ?= STM32F042x6
# Startup code to use
# - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
MCU_STARTUP ?= stm32f0xx
# Board: it should exist either in <chibios>/os/hal/boards/,
# <keyboard_dir>/boards/, or drivers/boards/
BOARD ?= GENERIC_STM32_F042X6
USE_FPU ?= no
# Options to pass to dfu-util when flashing
DFU_ARGS ?= -d 0483:df11 -a 0 -s 0x08000000:leave
DFU_SUFFIX_ARGS ?= -v 0483 -p df11
DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave
DFU_SUFFIX_ARGS ?= -v 0483 -p DF11
endif
ifneq ($(findstring STM32F103, $(MCU)),)
@@ -208,11 +176,110 @@ ifneq ($(findstring STM32F103, $(MCU)),)
USE_FPU ?= no
# Options to pass to dfu-util when flashing
DFU_ARGS ?= -d 0483:df11 -a 0 -s 0x08000000:leave
DFU_SUFFIX_ARGS ?= -v 0483 -p df11
DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave
DFU_SUFFIX_ARGS ?= -v 0483 -p DF11
endif
ifneq (,$(filter $(MCU),atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb1286))
ifneq ($(findstring STM32F303, $(MCU)),)
# Cortex version
MCU = cortex-m4
# ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7
ARMV = 7
## chip/board settings
# - the next two should match the directories in
# <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
MCU_FAMILY = STM32
MCU_SERIES = STM32F3xx
# Linker script to use
# - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
# or <keyboard_dir>/ld/
MCU_LDSCRIPT ?= STM32F303xC
# Startup code to use
# - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
MCU_STARTUP ?= stm32f3xx
# Board: it should exist either in <chibios>/os/hal/boards/,
# <keyboard_dir>/boards/, or drivers/boards/
BOARD ?= GENERIC_STM32_F303XC
USE_FPU ?= yes
# Options to pass to dfu-util when flashing
DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave
DFU_SUFFIX_ARGS ?= -v 0483 -p DF11
endif
ifneq ($(findstring STM32F401, $(MCU)),)
# Cortex version
MCU = cortex-m4
# ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7
ARMV = 7
## chip/board settings
# - the next two should match the directories in
# <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
MCU_FAMILY = STM32
MCU_SERIES = STM32F4xx
# Linker script to use
# - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
# or <keyboard_dir>/ld/
MCU_LDSCRIPT ?= STM32F401xC
# Startup code to use
# - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
MCU_STARTUP ?= stm32f4xx
# Board: it should exist either in <chibios>/os/hal/boards/,
# <keyboard_dir>/boards/, or drivers/boards/
BOARD ?= BLACKPILL_STM32_F401
USE_FPU ?= yes
# Options to pass to dfu-util when flashing
DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave
DFU_SUFFIX_ARGS ?= -v 0483 -p DF11
endif
ifneq ($(findstring STM32F411, $(MCU)),)
# Cortex version
MCU = cortex-m4
# ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7
ARMV = 7
## chip/board settings
# - the next two should match the directories in
# <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
MCU_FAMILY = STM32
MCU_SERIES = STM32F4xx
# Linker script to use
# - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
# or <keyboard_dir>/ld/
MCU_LDSCRIPT ?= STM32F411xE
# Startup code to use
# - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
MCU_STARTUP ?= stm32f4xx
# Board: it should exist either in <chibios>/os/hal/boards/,
# <keyboard_dir>/boards/, or drivers/boards/
BOARD ?= BLACKPILL_STM32_F411
USE_FPU ?= yes
# Options to pass to dfu-util when flashing
DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave
DFU_SUFFIX_ARGS ?= -v 0483 -p DF11
endif
ifneq (,$(filter $(MCU),atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647 at90usb1286 at90usb1287))
PROTOCOL = LUFA
# Processor frequency.
@@ -250,6 +317,9 @@ ifneq (,$(filter $(MCU),atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 a
ifeq (,$(filter $(NO_INTERRUPT_CONTROL_ENDPOINT),yes))
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
endif
ifneq (,$(filter $(MCU),atmega16u2 atmega32u2))
NO_I2C = yes
endif
endif
ifneq (,$(filter $(MCU),atmega32a))
@@ -266,7 +336,6 @@ ifneq (,$(filter $(MCU),atmega32a))
F_CPU ?= 12000000
# unsupported features for now
NO_UART ?= yes
NO_SUSPEND_POWER_DOWN ?= yes
endif
@@ -283,6 +352,23 @@ ifneq (,$(filter $(MCU),atmega328p))
# automatically to create a 32-bit value in your source code.
F_CPU ?= 16000000
# unsupported features for now
NO_SUSPEND_POWER_DOWN ?= yes
endif
ifneq (,$(filter $(MCU),atmega328))
# MCU name for avrdude
AVRDUDE_MCU = m328
PROTOCOL = VUSB
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency in Hz. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
F_CPU ?= 16000000
# unsupported features for now
NO_UART ?= yes
NO_SUSPEND_POWER_DOWN ?= yes
@@ -299,6 +385,5 @@ ifneq (,$(filter $(MCU),attiny85))
F_CPU ?= 16500000
# unsupported features for now
NO_UART ?= yes
NO_SUSPEND_POWER_DOWN ?= yes
endif
+9 -2
View File
@@ -25,18 +25,25 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
static report_mouse_t mouseReport = {};
__attribute__((weak)) bool has_mouse_report_changed(report_mouse_t new, report_mouse_t old) { return (new.buttons != old.buttons) || (new.x&& new.x != old.x) || (new.y&& new.y != old.y) || (new.h&& new.h != old.h) || (new.v&& new.v != old.v); }
__attribute__((weak)) void pointing_device_init(void) {
// initialize device, if that needs to be done.
}
__attribute__((weak)) void pointing_device_send(void) {
static report_mouse_t old_report = {};
// If you need to do other things, like debugging, this is the place to do it.
host_mouse_send(&mouseReport);
if (has_mouse_report_changed(mouseReport, old_report)) {
host_mouse_send(&mouseReport);
}
// send it and 0 it out except for buttons, so those stay until they are explicity over-ridden using update_pointing_device
mouseReport.x = 0;
mouseReport.y = 0;
mouseReport.v = 0;
mouseReport.h = 0;
old_report = mouseReport;
}
__attribute__((weak)) void pointing_device_task(void) {
@@ -52,4 +59,4 @@ __attribute__((weak)) void pointing_device_task(void) {
report_mouse_t pointing_device_get_report(void) { return mouseReport; }
void pointing_device_set_report(report_mouse_t newMouseReport) { mouseReport = newMouseReport; }
void pointing_device_set_report(report_mouse_t newMouseReport) { mouseReport = newMouseReport; }
+2 -4
View File
@@ -15,8 +15,7 @@ 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 POINTING_DEVICE_H
#define POINTING_DEVICE_H
#pragma once
#include <stdint.h>
#include "host.h"
@@ -27,5 +26,4 @@ void pointing_device_task(void);
void pointing_device_send(void);
report_mouse_t pointing_device_get_report(void);
void pointing_device_set_report(report_mouse_t newMouseReport);
#endif
bool has_mouse_report_changed(report_mouse_t new, report_mouse_t old);
+1 -4
View File
@@ -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
+182 -80
View File
@@ -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 -4
View File
@@ -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
+4 -4
View File
@@ -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]);
+2 -5
View File
@@ -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, &macro_end);
+22 -27
View File
@@ -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;
+2 -2
View File
@@ -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))
+1 -4
View File
@@ -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
+1 -4
View File
@@ -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
+24 -11
View File
@@ -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;
+2 -5
View File
@@ -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
+1 -1
View File
@@ -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)
+1 -4
View File
@@ -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
+1 -4
View File
@@ -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
+82 -9
View File
@@ -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;
@@ -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;
}
@@ -1,4 +1,4 @@
/* Copyright %YEAR% %YOUR_NAME%
/* 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
@@ -16,4 +16,6 @@
#pragma once
// place overrides here
#include "quantum.h"
bool process_sequencer(uint16_t keycode, keyrecord_t *record);
+15 -13
View File
@@ -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);
+2 -4
View File
@@ -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
+4 -5
View File
@@ -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);
+2 -4
View File
@@ -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
+1 -4
View File
@@ -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
+66 -88
View File
@@ -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;
}
+18 -8
View File
@@ -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);
+114 -66
View File
@@ -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);
+9 -20
View File
@@ -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;
}

Some files were not shown because too many files have changed in this diff Show More