Add example for QMK
This commit is contained in:
parent
eab5fee356
commit
c0a29fa9a6
10 changed files with 1432 additions and 0 deletions
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
8
.idea/crkbd-rev1.iml
generated
Normal file
8
.idea/crkbd-rev1.iml
generated
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="CPP_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/crkbd-rev1.iml" filepath="$PROJECT_DIR$/.idea/crkbd-rev1.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
38
qmk/config.h
Normal file
38
qmk/config.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
This is the c configuration file for the keymap
|
||||
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
|
||||
Copyright 2015 Jack Humbert
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// #define VIAL_KEYBOARD_UID {0xCE, 0x08, 0x17, 0xF3, 0x0D, 0xE4, 0x4A, 0xC8}
|
||||
|
||||
/* Select hand configuration */
|
||||
|
||||
#define MASTER_LEFT
|
||||
// #define MASTER_RIGHT
|
||||
// #define EE_HANDS
|
||||
|
||||
//#define TAPPING_FORCE_HOLD
|
||||
#define TAPPING_TERM 150
|
||||
|
||||
#define LANG_CHANGE_DEFAULT LANG_CHANGE_ALT_SHIFT
|
||||
|
||||
// #define DYNAMIC_KEYMAP_LAYER_COUNT 8
|
||||
|
||||
#define RGBLIGHT_LAYERS
|
||||
254
qmk/keymap.c
Normal file
254
qmk/keymap.c
Normal file
|
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
Copyright 2019 @foostan
|
||||
Copyright 2020 Drashna Jaelre <@drashna>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include QMK_KEYBOARD_H
|
||||
#include <stdio.h>
|
||||
|
||||
#define CUSTOM_SAFE_RANGE SAFE_RANGE
|
||||
#include "lang_shift/include.h"
|
||||
|
||||
#define L_ENG 0
|
||||
#define L_GAME 1
|
||||
#define L_RU 2
|
||||
#define L_PUNC 3
|
||||
#define L_IDK1 4
|
||||
#define L_IDK2 5
|
||||
#define L_NUMF 6
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
|
||||
[L_ENG] = LAYOUT(
|
||||
//,-----------------------------------------------------------. ,-----------------------------------------------------------.
|
||||
KC_ESC, EN_F, EN_L, EN_H, EN_V, EN_Z, EN_Q, EN_W, EN_U, EN_O, EN_Y, DF(L_GAME),
|
||||
//|---------+---------+---------+---------+---------+---------| |---------+---------+---------+---------+---------+---------|
|
||||
XXXXXXX, EN_S, EN_R, EN_N, EN_T, EN_K, EN_C, EN_D, EN_E, EN_A, EN_I, KC_LWIN,
|
||||
//|---------+---------+---------+---------+---------+---------| |---------+---------+---------+---------+---------+---------|
|
||||
CTRL_0 , EN_X, XXXXXXX, EN_B, EN_M, EN_J, EN_P, EN_G, XXXXXXX, XXXXXXX, XXXXXXX, TD(6),
|
||||
//|---------+---------+---------+---------+---------+---------+---------||---------+---------+---------+---------+---------+---------+---------|
|
||||
TD(0), TD(1), KC_LSHIFT, TD(2), TD(3), KC_TAB
|
||||
//`+---------+---------+---------||---------+---------+---------+'
|
||||
),
|
||||
|
||||
[L_RU] = LAYOUT(
|
||||
//,-----------------------------------------------------------. ,-----------------------------------------------------------.
|
||||
KC_ESC, RU_H, RU_G, RU_JA, RU_Y, RU_U, RU_D, RU_CH, RU_M, RU_ZH, RU_E, RU_SC,
|
||||
//|---------+---------+---------+---------+---------+---------| |---------+---------+---------+---------+---------+---------|
|
||||
RU_F, RU_N, RU_I, RU_JE, RU_O, RU_SF, RU_P, RU_V, RU_T, RU_S, RU_R, RU_TS,
|
||||
//|---------+---------+---------+---------+---------+---------| |---------+---------+---------+---------+---------+---------|
|
||||
TD(5), RU_SH, RU_B, RU_JU, RU_A, RU_JO, RU_HD, RU_K, RU_L, RU_Z, RU_J, ALT_0,
|
||||
//|---------+---------+---------+---------+---------+---------+---------||---------+---------+---------+---------+---------+---------+---------|
|
||||
TD(0), TD(1), KC_LSHIFT, TD(2), TD(3), KC_TAB
|
||||
//`+---------+---------+---------||---------+---------+---------+'
|
||||
),
|
||||
|
||||
[L_NUMF] = LAYOUT(
|
||||
//,-----------------------------------------------------------. ,-----------------------------------------------------------.
|
||||
XXXXXXX, XXXXXXX, KC_1, KC_2, KC_3, XXXXXXX, XXXXXXX, KC_F1, KC_F2, KC_F3, KC_F4, XXXXXXX,
|
||||
//|---------+---------+---------+---------+---------+---------| |---------+---------+---------+---------+---------+---------|
|
||||
XXXXXXX, KC_0, KC_4, KC_5, KC_6, KC_PSCR, XXXXXXX, KC_F5, KC_F6, KC_F7, KC_F8, KC_LWIN,
|
||||
//|---------+---------+---------+---------+---------+---------| |---------+---------+---------+---------+---------+---------|
|
||||
KC_LCTL, XXXXXXX, KC_7, KC_8, KC_9, XXXXXXX, XXXXXXX, KC_F9, KC_F10, KC_F11, KC_F12, KC_LALT,
|
||||
//|---------+---------+---------+---------+---------+---------+---------||---------+---------+---------+---------+---------+---------+---------|
|
||||
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
|
||||
//`+---------+---------+---------||---------+---------+---------+'
|
||||
),
|
||||
|
||||
[L_PUNC] = LAYOUT(
|
||||
//,-----------------------------------------------------------. ,-----------------------------------------------------------.
|
||||
AG_PERC, EN_QUOT, AG_MINS, AG_SLSH, AG_EQL, AG_PLUS, EN_PIPE, AG_RPRN, EN_RCBR, EN_RBRC, EN_GT, EN_TILD,
|
||||
//|---------+---------+---------+---------+---------+---------| |---------+---------+---------+---------+---------+---------|
|
||||
EN_CIRC, AG_DQUO, AG_UNDS, AG_COMM, AG_DOT, EN_AT, AG_BSLS, AG_LPRN, EN_LCBR, EN_LBRC, EN_LT, EN_GRV,
|
||||
//|---------+---------+---------+---------+---------+---------| |---------+---------+---------+---------+---------+---------|
|
||||
XXXXXXX, EN_DLR, AG_SCLN, AG_ASTR, AG_QUES, RU_NUME, XXXXXXX, AG_EXCL, EN_HASH, AG_COLN, EN_AMPR, XXXXXXX,
|
||||
//|---------+---------+---------+---------+---------+---------+---------||---------+---------+---------+---------+---------+---------+---------|
|
||||
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
|
||||
//`+---------+---------+---------||---------+---------+---------+'
|
||||
),
|
||||
|
||||
[L_IDK1] = LAYOUT(
|
||||
//,-----------------------------------------------------------------------. ,-----------------------------------------------------------------------.
|
||||
XXXXXXX, C(KC_SLSH), C(KC_R), C(KC_Z), C(KC_S), XXXXXXX, XXXXXXX, C(KC_T), C(KC_N), C(S(KC_P)), C(KC_F5), XXXXXXX,
|
||||
//|-----------+-----------+-----------+-----------+-----------+-----------| |-----------+-----------+-----------+-----------+-----------+-----------|
|
||||
C(S(KC_V)), C(KC_W), C(KC_A), C(KC_C), C(KC_V), C(KC_X), XXXXXXX, A(KC_D), A(KC_ENT), C(KC_F), C(KC_J), XXXXXXX,
|
||||
//|-----------+-----------+-----------+-----------+-----------+-----------| |-----------+-----------+-----------+-----------+-----------+-----------|
|
||||
XXXXXXX, C(S(KC_T)), C(KC_D), C(KC_PGUP), C(KC_PGDN), XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, G(KC_L),
|
||||
//|-----------+-----------+-----------+-----------+-----------+-----------+-----------||-----------+-----------+-----------+-----------+-----------+-----------+-----------|
|
||||
XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
|
||||
//`+-----------+-----------+-----------||-----------+-----------+-----------+'
|
||||
),
|
||||
|
||||
[L_IDK2] = LAYOUT(
|
||||
//,-----------------------------------------------------------------------. ,-----------------------------------------------------------------------------------------.
|
||||
KC_HOME, C(KC_LEFT), C(KC_UP), C(KC_DOWN), C(KC_RGHT), KC_PGUP, LA_SYNC, C(S(KC_LEFT)), C(S(KC_UP)), C(S(KC_DOWN)), C(S(KC_RGHT)), XXXXXXX,
|
||||
//|-----------+-----------+-----------+-----------+-----------+-----------| |--------------+--------------+--------------+--------------+--------------+--------------|
|
||||
KC_END, KC_LEFT, KC_UP, KC_DOWN, KC_RGHT, KC_PGDN, KC_VOLD, KC_MPLY, KC_MNXT, KC_MPRV, KC_MUTE, KC_VOLU,
|
||||
//|-----------+-----------+-----------+-----------+-----------+-----------| |--------------+--------------+--------------+--------------+--------------+--------------|
|
||||
KC_LCTL, KC_WH_L, KC_WH_U, KC_WH_D, KC_WH_R, KC_DEL, RGB_TOG, LA_CAPS, LA_ALSH, LA_CTSH, LA_WISP, KC_LALT,
|
||||
//|-----------+-----------+-----------+-----------+-----------+-----------+-----------||-----------+--------------+--------------+--------------+--------------+--------------+--------------|
|
||||
XXXXXXX, XXXXXXX, XXXXXXX, KC_LSHIFT, XXXXXXX, XXXXXXX
|
||||
//`+-----------+-----------+-----------||-----------+--------------+--------------+'
|
||||
),
|
||||
|
||||
[L_GAME] = LAYOUT(
|
||||
//,-----------------------------------------------------------. ,-----------------------------------------------------------.
|
||||
KC_TAB, KC_T, KC_Q, KC_W, KC_E, KC_R, KC_Y, KC_U, KC_I, KC_O, KC_P, DF(L_ENG),
|
||||
//|---------+---------+---------+---------+---------+---------| |---------+---------+---------+---------+---------+---------|
|
||||
KC_LSFT, KC_G, KC_A, KC_S, KC_D, KC_F, KC_H, KC_J, KC_UP, KC_K, KC_L, KC_GRV,
|
||||
//|---------+---------+---------+---------+---------+---------| |---------+---------+---------+---------+---------+---------|
|
||||
KC_LCTL, KC_B, KC_Z, KC_X, KC_C, KC_V, KC_N, KC_LEFT, KC_DOWN, KC_RGHT, KC_M, KC_SLSH,
|
||||
//|---------+---------+---------+---------+---------+---------+---------||---------+---------+---------+---------+---------+---------+---------|
|
||||
KC_LALT, KC_SPC, TD(4), KC_H, KC_SPC, KC_ENTER
|
||||
//`+---------+---------+---------||---------+---------+---------+'
|
||||
)
|
||||
|
||||
// [7] = LAYOUT(
|
||||
// //,-----------------------------------------------------------. ,-----------------------------------------------------------.
|
||||
// XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
|
||||
// //|---------+---------+---------+---------+---------+---------| |---------+---------+---------+---------+---------+---------|
|
||||
// XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
|
||||
// //|---------+---------+---------+---------+---------+---------| |---------+---------+---------+---------+---------+---------|
|
||||
// XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
|
||||
// //|---------+---------+---------+---------+---------+---------+---------||---------+---------+---------+---------+---------+---------+---------|
|
||||
// XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
|
||||
// //`+---------+---------+---------||---------+---------+---------+'
|
||||
// )
|
||||
};
|
||||
|
||||
//idk lang_shift
|
||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||
if (!lang_shift_process_record(keycode, record))
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
void user_timer(void) {
|
||||
lang_shift_user_timer();
|
||||
};
|
||||
|
||||
|
||||
// Tap Dance
|
||||
// Tap Dance Definitions
|
||||
enum {
|
||||
TD_0,
|
||||
TD_1,
|
||||
TD_2,
|
||||
TD_3,
|
||||
TD_4,
|
||||
TD_5,
|
||||
TD_6
|
||||
};
|
||||
|
||||
// Tap Dance Finished Functions
|
||||
void td0_finished(qk_tap_dance_state_t *state, void *user_data) {
|
||||
if (state->count == 1 && !state->pressed) {
|
||||
tap_code(KC_PSCREEN);
|
||||
} else {
|
||||
layer_on(L_IDK2);
|
||||
}
|
||||
}
|
||||
|
||||
void td1_finished(qk_tap_dance_state_t *state, void *user_data) {
|
||||
if (state->count == 1 && !state->pressed) {
|
||||
tap_code(KC_BSPACE);
|
||||
} else if (state->count == 2) {
|
||||
tap_code16(LCTL(KC_BSPACE));
|
||||
} else if (state->count == 1 && state->pressed) {
|
||||
tap_code(KC_BSPACE); // Tap + Hold
|
||||
} else {
|
||||
layer_on(L_IDK1);
|
||||
}
|
||||
}
|
||||
|
||||
// ... same logic for td2, td3, etc.
|
||||
|
||||
// Tap Dance Reset Functions
|
||||
void td0_reset(qk_tap_dance_state_t *state, void *user_data) {
|
||||
if (state->count != 1) {
|
||||
layer_off(L_IDK2);
|
||||
}
|
||||
}
|
||||
|
||||
void td1_reset(qk_tap_dance_state_t *state, void *user_data) {
|
||||
if (state->count != 1 && state->count != 2) {
|
||||
layer_off(L_IDK1);
|
||||
}
|
||||
}
|
||||
|
||||
// ... same logic for td2, td3, etc.
|
||||
|
||||
// Associate the Tap Dance functions with the Tap Dance enums
|
||||
qk_tap_dance_action_t tap_dance_actions[] = {
|
||||
[TD_0] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, td0_finished, td0_reset),
|
||||
[TD_1] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, td1_finished, td1_reset),
|
||||
// ... same logic for td2, td3, etc.
|
||||
};
|
||||
|
||||
|
||||
// Lighting Layers
|
||||
layer_state_t default_layer_state_set_user(layer_state_t state) {
|
||||
switch (get_highest_layer(state)) {
|
||||
case L_ENG:
|
||||
rgblight_sethsv(HSV_ORANGE);
|
||||
break;
|
||||
case L_GAME:
|
||||
rgblight_sethsv(HSV_YELLOW);
|
||||
break;
|
||||
default: // for any other layers, or the default layer
|
||||
rgblight_sethsv(HSV_WHITE);
|
||||
break;
|
||||
}
|
||||
return state;
|
||||
};
|
||||
|
||||
layer_state_t layer_state_set_user(layer_state_t state) {
|
||||
switch (get_highest_layer(state)) {
|
||||
case L_RU:
|
||||
rgblight_sethsv(HSV_GREEN);
|
||||
break;
|
||||
case L_PUNC:
|
||||
rgblight_sethsv(HSV_MAGENTA);
|
||||
break;
|
||||
case L_IDK1:
|
||||
rgblight_sethsv(HSV_BLUE);
|
||||
break;
|
||||
case L_IDK2:
|
||||
rgblight_sethsv(HSV_RED);
|
||||
break;
|
||||
case L_NUMF:
|
||||
rgblight_sethsv(HSV_CYAN);
|
||||
break;
|
||||
default: // for any other layers, or the default layer
|
||||
rgblight_sethsv(HSV_WHITE);
|
||||
break;
|
||||
}
|
||||
return state;
|
||||
};
|
||||
|
||||
void matrix_scan_user(void) {
|
||||
user_timer();
|
||||
|
||||
// Проверяем, активен ли слой
|
||||
if (!layer_state_cmp(layer_state, L_PUNC) &&
|
||||
!layer_state_cmp(layer_state, L_IDK1) &&
|
||||
!layer_state_cmp(layer_state, L_IDK2) &&
|
||||
!layer_state_cmp(layer_state, L_NUMF) &&
|
||||
!layer_state_cmp(layer_state, L_RU)) {
|
||||
// Если ни один из этих слоев не активен, обновляем подсветку на основе текущего базового слоя
|
||||
default_layer_state_set_user(default_layer_state);
|
||||
}
|
||||
}
|
||||
335
qmk/lang_shift/include.h
Normal file
335
qmk/lang_shift/include.h
Normal file
|
|
@ -0,0 +1,335 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef CUSTOM_SAFE_RANGE
|
||||
#error "You must specify variable CUSTOM_SAFE_RANGE for lang_shift extension."
|
||||
#endif
|
||||
|
||||
enum lang_shift_keycodes {
|
||||
LANG_SHIFT_START = CUSTOM_SAFE_RANGE,
|
||||
|
||||
// Кейкоды, на основе которых реализуются кейкоды ниже, пользователю их лучше не использовать.
|
||||
#include "private_keycodes.h"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Английские символы */
|
||||
EN_GRV, /* ` */
|
||||
EN_TILD, /* ~ */
|
||||
EN_1, /* 1 */
|
||||
EN_EXCL, /* ! */
|
||||
EN_2, /* 2 */
|
||||
EN_AT, /* @ */
|
||||
EN_3, /* 3 */
|
||||
EN_HASH, /* # */
|
||||
EN_4, /* 4 */
|
||||
EN_DLR, /* $ */
|
||||
EN_5, /* 5 */
|
||||
EN_PERC, /* % */
|
||||
EN_6, /* 6 */
|
||||
EN_CIRC, /* ^ */
|
||||
EN_7, /* 7 */
|
||||
EN_AMPR, /* & */
|
||||
EN_8, /* 8 */
|
||||
EN_ASTR, /* * */
|
||||
EN_9, /* 9 */
|
||||
EN_LPRN, /* ( */
|
||||
EN_0, /* 0 */
|
||||
EN_RPRN, /* ) */
|
||||
EN_MINS, /* - */
|
||||
EN_UNDS, /* _ */
|
||||
EN_EQL, /* = */
|
||||
EN_PLUS, /* + */
|
||||
|
||||
EN_Q, /* q */
|
||||
EN_S_Q, /* Q */
|
||||
EN_W, /* w */
|
||||
EN_S_W, /* W */
|
||||
EN_E, /* e */
|
||||
EN_S_E, /* E */
|
||||
EN_R, /* r */
|
||||
EN_S_R, /* R */
|
||||
EN_T, /* t */
|
||||
EN_S_T, /* T */
|
||||
EN_Y, /* y */
|
||||
EN_S_Y, /* Y */
|
||||
EN_U, /* u */
|
||||
EN_S_U, /* U */
|
||||
EN_I, /* i */
|
||||
EN_S_I, /* I */
|
||||
EN_O, /* o */
|
||||
EN_S_O, /* O */
|
||||
EN_P, /* p */
|
||||
EN_S_P, /* P */
|
||||
EN_LBRC, /* [ */
|
||||
EN_LCBR, /* { */
|
||||
EN_RBRC, /* ] */
|
||||
EN_RCBR, /* } */
|
||||
|
||||
EN_A, /* a */
|
||||
EN_S_A, /* A */
|
||||
EN_S, /* s */
|
||||
EN_S_S, /* S */
|
||||
EN_D, /* d */
|
||||
EN_S_D, /* D */
|
||||
EN_F, /* f */
|
||||
EN_S_F, /* F */
|
||||
EN_G, /* g */
|
||||
EN_S_G, /* G */
|
||||
EN_H, /* h */
|
||||
EN_S_H, /* H */
|
||||
EN_J, /* j */
|
||||
EN_S_J, /* J */
|
||||
EN_K, /* k */
|
||||
EN_S_K, /* K */
|
||||
EN_L, /* l */
|
||||
EN_S_L, /* L */
|
||||
EN_SCLN, /* ; */
|
||||
EN_COLN, /* : */
|
||||
EN_QUOT, /* ' */
|
||||
EN_DQUO, /* " */
|
||||
EN_BSLS, /* \ */
|
||||
EN_PIPE, /* | */
|
||||
|
||||
EN_Z, /* z */
|
||||
EN_S_Z, /* Z */
|
||||
EN_X, /* x */
|
||||
EN_S_X, /* X */
|
||||
EN_C, /* c */
|
||||
EN_S_C, /* C */
|
||||
EN_V, /* v */
|
||||
EN_S_V, /* V */
|
||||
EN_B, /* b */
|
||||
EN_S_B, /* B */
|
||||
EN_N, /* n */
|
||||
EN_S_N, /* N */
|
||||
EN_M, /* m */
|
||||
EN_S_M, /* M */
|
||||
EN_COMM, /* , */
|
||||
EN_LT, /* < */
|
||||
EN_DOT, /* . */
|
||||
EN_GT, /* > */
|
||||
EN_SLSH, /* / */
|
||||
EN_QUES, /* ? */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Русские символы */
|
||||
RU_JO, /* ё */
|
||||
RU_S_JO, /* Ё */
|
||||
RU_1, /* 1 */
|
||||
RU_EXCL, /* ! */
|
||||
RU_2, /* 2 */
|
||||
RU_DQUO, /* " */
|
||||
RU_3, /* 3 */
|
||||
RU_NUME, /* № */
|
||||
RU_4, /* 4 */
|
||||
RU_SCLN, /* ; */
|
||||
RU_5, /* 5 */
|
||||
RU_PERC, /* % */
|
||||
RU_6, /* 6 */
|
||||
RU_COLN, /* : */
|
||||
RU_7, /* 7 */
|
||||
RU_QUES, /* ? */
|
||||
RU_8, /* 8 */
|
||||
RU_ASTR, /* * */
|
||||
RU_9, /* 9 */
|
||||
RU_LPRN, /* ( */
|
||||
RU_0, /* 0 */
|
||||
RU_RPRN, /* ) */
|
||||
RU_MINS, /* - */
|
||||
RU_UNDS, /* _ */
|
||||
RU_EQL, /* = */
|
||||
RU_PLUS, /* + */
|
||||
|
||||
RU_J, /* й */
|
||||
RU_S_J, /* Й */
|
||||
RU_TS, /* ц */
|
||||
RU_S_TS, /* Ц */
|
||||
RU_U, /* у */
|
||||
RU_S_U, /* У */
|
||||
RU_K, /* к */
|
||||
RU_S_K, /* К */
|
||||
RU_JE, /* е */
|
||||
RU_S_JE, /* Е */
|
||||
RU_N, /* н */
|
||||
RU_S_N, /* Н */
|
||||
RU_G, /* г */
|
||||
RU_S_G, /* Г */
|
||||
RU_SH, /* ш */
|
||||
RU_S_SH, /* Ш */
|
||||
RU_SC, /* щ */
|
||||
RU_S_SC, /* Щ */
|
||||
RU_Z, /* з */
|
||||
RU_S_Z, /* З */
|
||||
RU_H, /* х */
|
||||
RU_S_H, /* Х */
|
||||
RU_HD, /* ъ */
|
||||
RU_S_HD, /* Ъ */
|
||||
|
||||
RU_F, /* ф */
|
||||
RU_S_F, /* Ф */
|
||||
RU_Y, /* ы */
|
||||
RU_S_Y, /* Ы */
|
||||
RU_V, /* в */
|
||||
RU_S_V, /* В */
|
||||
RU_A, /* а */
|
||||
RU_S_A, /* А */
|
||||
RU_P, /* п */
|
||||
RU_S_P, /* п */
|
||||
RU_R, /* р */
|
||||
RU_S_R, /* Р */
|
||||
RU_O, /* о */
|
||||
RU_S_O, /* О */
|
||||
RU_L, /* л */
|
||||
RU_S_L, /* Л */
|
||||
RU_D, /* д */
|
||||
RU_S_D, /* Д */
|
||||
RU_ZH, /* ж */
|
||||
RU_S_ZH, /* Ж */
|
||||
RU_E, /* э */
|
||||
RU_S_E, /* Э */
|
||||
RU_BSLS, /* \ */
|
||||
RU_SLSH, /* / */
|
||||
|
||||
RU_JA, /* я */
|
||||
RU_S_JA, /* Я */
|
||||
RU_CH, /* ч */
|
||||
RU_S_CH, /* Ч */
|
||||
RU_S, /* с */
|
||||
RU_S_S, /* С */
|
||||
RU_M, /* м */
|
||||
RU_S_M, /* М */
|
||||
RU_I, /* и */
|
||||
RU_S_I, /* И */
|
||||
RU_T, /* т */
|
||||
RU_S_T, /* Т */
|
||||
RU_SF, /* ь */
|
||||
RU_S_SF, /* Ь */
|
||||
RU_B, /* б */
|
||||
RU_S_B, /* Б */
|
||||
RU_JU, /* ю */
|
||||
RU_S_JU, /* Ю */
|
||||
RU_DOT, /* . */
|
||||
RU_COMM, /* , */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Символы, нажимаемые независимо от текущего языка. Language-agnostic-keycodes. */
|
||||
AG_1, /* 1 */
|
||||
AG_2, /* 2 */
|
||||
AG_3, /* 3 */
|
||||
AG_4, /* 4 */
|
||||
AG_5, /* 5 */
|
||||
AG_6, /* 6 */
|
||||
AG_7, /* 7 */
|
||||
AG_8, /* 8 */
|
||||
AG_9, /* 9 */
|
||||
AG_0, /* 0 */
|
||||
AG_EXCL, /* ! */
|
||||
AG_PERC, /* % */
|
||||
AG_ASTR, /* * */
|
||||
AG_LPRN, /* ( */
|
||||
AG_RPRN, /* ) */
|
||||
AG_MINS, /* - */
|
||||
AG_UNDS, /* _ */
|
||||
AG_EQL, /* = */
|
||||
AG_PLUS, /* + */
|
||||
AG_SCLN, /* ; */
|
||||
AG_COLN, /* : */
|
||||
AG_DQUO, /* " */
|
||||
AG_BSLS, /* \ */
|
||||
AG_COMM, /* , */
|
||||
AG_DOT, /* . */
|
||||
AG_SLSH, /* / */
|
||||
AG_QUES, /* ? */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Кастомные language-agnostic-кейкоды */
|
||||
AG_3DOT, /* ... */
|
||||
AG_SDOT, /* Space + Dot + Shift to next key */
|
||||
AG_CMSP, /* Comma + Space */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Шифты для набора текста. */
|
||||
SFT_N, /* Работает как обычный шифт, при её зажатии, шифт зажат. Параллельно переключает на (шифтовый) следующий слой относительно текущего языка (если язык 0, то включает слой 1, если язык 1, то включает слой 3). */
|
||||
SFT_N_O, /* Данная клавиша применит шифт и переключение на шифтовый слой только к следующему символу. Неважно, была ли она нажата одновременно со следующей клавишей, или до неё, или вместе с двумя клавишами. Применится только к одной клавише. То есть это как залипающий шифт, если нажимать отдельно от всех клавиш, и как одиночный шифт, если эту клавишу зажимать. Такая клавиша может пригодиться если вы печатаете с большой скоростью и вам сложно выдерживать время удержания шифта, и у вас получается что-то вроде "ПРивет". */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Модификаторы, переключащие текущий слой на 0. Такое нужно чтобы при включённом русском языке были такие же хоткеи с модификаторами, как и на английском языке. */
|
||||
CTRL_0, /* Ctrl on 0 layer */
|
||||
ALT_0, /* Alt on 0 layer */
|
||||
WIN_0, /* Win on 0 layer */
|
||||
SHAL_0, /* Shift+Alt on 0 layer */
|
||||
CTAL_0, /* Ctrl+Alt on 0 layer */
|
||||
CTSH_0, /* Ctrl+Shift on 0 layer */
|
||||
MCAS_0, /* Ctrl+Alt+Shift on 0 layer */
|
||||
|
||||
/* А данные модификаторы помимо включения 0 слоя ещё и переключают язык на английский. Такое разделение нужно, потому что у некоторых смена языка идёт на комбинации с Ctrl, или Shift, и у них может сниматься выделение текста, например. */
|
||||
CTRL_EN, /* Ctrl on 0 layer */
|
||||
ALT_EN, /* Alt on 0 layer */
|
||||
WIN_EN, /* Win on 0 layer */
|
||||
SHAL_EN, /* Shift+Alt on 0 layer */
|
||||
CTAL_EN, /* Ctrl+Alt on 0 layer */
|
||||
CTSH_EN, /* Ctrl+Shift on 0 layer */
|
||||
MCAS_EN, /* Ctrl+Alt+Shift on 0 layer */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Кнопки, отвечающие за переключение языка. */
|
||||
LA_CHNG, /* Переключает язык и переключает на 2 или 0 слой в зависимости от текущего языка. */
|
||||
LA_SYNC, /* Кнопка для синхронизации языков. Её нужно нажимать в случае если язык в системе и язык в клавиатуре различаются. Данная клавиша изменит язык в системе. */
|
||||
LA_CAPS, /* Задаёт переключение языка на Caps. */
|
||||
LA_ALSH, /* Задаёт переключение языка на Alt + Shift. */
|
||||
LA_SHAL, /* Задаёт переключение языка на Shift + Alt. На Win10 это позволяет избежать появления окна переключения языков. */
|
||||
LA_CTSH, /* Задаёт переключение языка на Ctrl + Shift. */
|
||||
LA_SHCT, /* Задаёт переключение языка на Shift + Ctrl. На Win10 это позволяет избежать появления окна переключения языков. */
|
||||
LA_WISP, /* Задаёт переключение языка на Win + Shift. */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* SAFE_RANGE данной библиотеки. */
|
||||
LANG_SHIFT_NEW_SAFE_RANGE,
|
||||
#undef CUSTOM_SAFE_RANGE
|
||||
#define CUSTOM_SAFE_RANGE LANG_SHIFT_NEW_SAFE_RANGE
|
||||
};
|
||||
|
||||
typedef uint16_t Key;
|
||||
#define NONE_KEY (uint16_t)(65535)
|
||||
|
||||
typedef uint8_t Lang;
|
||||
#define NONE_LANG (uint8_t)(255)
|
||||
|
||||
typedef uint8_t Shift;
|
||||
#define NONE_SHIFT (uint8_t)(255)
|
||||
|
||||
// Способ смены языка
|
||||
enum LangChange {
|
||||
LANG_CHANGE_CAPS,
|
||||
LANG_CHANGE_ALT_SHIFT,
|
||||
LANG_CHANGE_SHIFT_ALT,
|
||||
LANG_CHANGE_CTRL_SHIFT,
|
||||
LANG_CHANGE_SHIFT_CTRL,
|
||||
LANG_CHANGE_WIN_SPACE
|
||||
};
|
||||
|
||||
// Переменная, в которой можно менять текущий способ смены языка
|
||||
enum LangChange lang_current_change =
|
||||
#ifdef LANG_CHANGE_DEFAULT
|
||||
LANG_CHANGE_DEFAULT;
|
||||
#else
|
||||
#error "You must specify default language change method by defining variable LANG_CHANGE_DEFAULT."
|
||||
#endif
|
||||
|
||||
void shift_activate(Shift shift);
|
||||
void shift_activate_from_user(Shift shift);
|
||||
|
||||
void shift_once_use_to_next_key(uint8_t layer);
|
||||
|
||||
uint8_t lang_get_shift_layer_number(void);
|
||||
void lang_synchronize(void);
|
||||
void lang_activate(Lang lang);
|
||||
void lang_activate_from_user(Lang lang);
|
||||
|
||||
void lang_shift_press_key(Key key, bool down);
|
||||
void lang_shift_tap_key(Key key);
|
||||
|
||||
bool lang_shift_process_record(Key key, keyrecord_t* record);
|
||||
void lang_shift_user_timer(void);
|
||||
|
||||
// Инклюжу код напрямую, потому что нельзя сделать линковку, ведь код внутри использует кейкоды отсюда, и обязательно нужно это делать через safe_range
|
||||
#include "src.c"
|
||||
97
qmk/lang_shift/private_keycodes.h
Normal file
97
qmk/lang_shift/private_keycodes.h
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
KS_GRV, /* ` */
|
||||
KS_TILD, /* ~ */
|
||||
KS_1, /* 1 */
|
||||
KS_EXCL, /* ! */
|
||||
KS_2, /* 2 */
|
||||
KS_AT, /* @ */
|
||||
KS_3, /* 3 */
|
||||
KS_HASH, /* # */
|
||||
KS_4, /* 4 */
|
||||
KS_DLR, /* $ */
|
||||
KS_5, /* 5 */
|
||||
KS_PERC, /* % */
|
||||
KS_6, /* 6 */
|
||||
KS_CIRC, /* ^ */
|
||||
KS_7, /* 7 */
|
||||
KS_AMPR, /* & */
|
||||
KS_8, /* 8 */
|
||||
KS_ASTR, /* * */
|
||||
KS_9, /* 9 */
|
||||
KS_LPRN, /* ( */
|
||||
KS_0, /* 0 */
|
||||
KS_RPRN, /* ) */
|
||||
KS_MINS, /* - */
|
||||
KS_UNDS, /* _ */
|
||||
KS_EQL, /* = */
|
||||
KS_PLUS, /* + */
|
||||
|
||||
KS_Q, /* q */
|
||||
KS_S_Q, /* Q */
|
||||
KS_W, /* w */
|
||||
KS_S_W, /* W */
|
||||
KS_E, /* e */
|
||||
KS_S_E, /* E */
|
||||
KS_R, /* r */
|
||||
KS_S_R, /* R */
|
||||
KS_T, /* t */
|
||||
KS_S_T, /* T */
|
||||
KS_Y, /* y */
|
||||
KS_S_Y, /* Y */
|
||||
KS_U, /* u */
|
||||
KS_S_U, /* U */
|
||||
KS_I, /* i */
|
||||
KS_S_I, /* I */
|
||||
KS_O, /* o */
|
||||
KS_S_O, /* O */
|
||||
KS_P, /* p */
|
||||
KS_S_P, /* P */
|
||||
KS_LBRC, /* [ */
|
||||
KS_LCBR, /* { */
|
||||
KS_RBRC, /* ] */
|
||||
KS_RCBR, /* } */
|
||||
|
||||
KS_A, /* a */
|
||||
KS_S_A, /* A */
|
||||
KS_S, /* s */
|
||||
KS_S_S, /* S */
|
||||
KS_D, /* d */
|
||||
KS_S_D, /* D */
|
||||
KS_F, /* f */
|
||||
KS_S_F, /* F */
|
||||
KS_G, /* g */
|
||||
KS_S_G, /* G */
|
||||
KS_H, /* h */
|
||||
KS_S_H, /* H */
|
||||
KS_J, /* j */
|
||||
KS_S_J, /* J */
|
||||
KS_K, /* k */
|
||||
KS_S_K, /* K */
|
||||
KS_L, /* l */
|
||||
KS_S_L, /* L */
|
||||
KS_SCLN, /* ; */
|
||||
KS_COLN, /* : */
|
||||
KS_QUOT, /* ' */
|
||||
KS_DQUO, /* " */
|
||||
KS_BSLS, /* \ */
|
||||
KS_PIPE, /* | */
|
||||
|
||||
KS_Z, /* z */
|
||||
KS_S_Z, /* Z */
|
||||
KS_X, /* x */
|
||||
KS_S_X, /* X */
|
||||
KS_C, /* c */
|
||||
KS_S_C, /* C */
|
||||
KS_V, /* v */
|
||||
KS_S_V, /* V */
|
||||
KS_B, /* b */
|
||||
KS_S_B, /* B */
|
||||
KS_N, /* n */
|
||||
KS_S_N, /* N */
|
||||
KS_M, /* m */
|
||||
KS_S_M, /* M */
|
||||
KS_COMM, /* , */
|
||||
KS_LT, /* < */
|
||||
KS_DOT, /* . */
|
||||
KS_GT, /* > */
|
||||
KS_SLSH, /* / */
|
||||
KS_QUES, /* ? */
|
||||
665
qmk/lang_shift/src.c
Normal file
665
qmk/lang_shift/src.c
Normal file
|
|
@ -0,0 +1,665 @@
|
|||
// ---------------------------------------------------------------------------
|
||||
// Работа с шифтом
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Shift shift_should_be = 0;
|
||||
Shift shift_current = 0;
|
||||
uint32_t shift_timer = 0;
|
||||
uint8_t shift_pressed_count = 0;
|
||||
|
||||
Key shift_get_key(Key key) {
|
||||
switch (key) {
|
||||
case KS_GRV: return KC_GRV;
|
||||
case KS_TILD: return KC_GRV;
|
||||
case KS_1: return KC_1;
|
||||
case KS_EXCL: return KC_1;
|
||||
case KS_2: return KC_2;
|
||||
case KS_AT: return KC_2;
|
||||
case KS_3: return KC_3;
|
||||
case KS_HASH: return KC_3;
|
||||
case KS_4: return KC_4;
|
||||
case KS_DLR: return KC_4;
|
||||
case KS_5: return KC_5;
|
||||
case KS_PERC: return KC_5;
|
||||
case KS_6: return KC_6;
|
||||
case KS_CIRC: return KC_6;
|
||||
case KS_7: return KC_7;
|
||||
case KS_AMPR: return KC_7;
|
||||
case KS_8: return KC_8;
|
||||
case KS_ASTR: return KC_8;
|
||||
case KS_9: return KC_9;
|
||||
case KS_LPRN: return KC_9;
|
||||
case KS_0: return KC_0;
|
||||
case KS_RPRN: return KC_0;
|
||||
case KS_MINS: return KC_MINS;
|
||||
case KS_UNDS: return KC_MINS;
|
||||
case KS_EQL: return KC_EQL;
|
||||
case KS_PLUS: return KC_EQL;
|
||||
case KS_Q: return KC_Q;
|
||||
case KS_S_Q: return KC_Q;
|
||||
case KS_W: return KC_W;
|
||||
case KS_S_W: return KC_W;
|
||||
case KS_E: return KC_E;
|
||||
case KS_S_E: return KC_E;
|
||||
case KS_R: return KC_R;
|
||||
case KS_S_R: return KC_R;
|
||||
case KS_T: return KC_T;
|
||||
case KS_S_T: return KC_T;
|
||||
case KS_Y: return KC_Y;
|
||||
case KS_S_Y: return KC_Y;
|
||||
case KS_U: return KC_U;
|
||||
case KS_S_U: return KC_U;
|
||||
case KS_I: return KC_I;
|
||||
case KS_S_I: return KC_I;
|
||||
case KS_O: return KC_O;
|
||||
case KS_S_O: return KC_O;
|
||||
case KS_P: return KC_P;
|
||||
case KS_S_P: return KC_P;
|
||||
case KS_LBRC: return KC_LBRC;
|
||||
case KS_LCBR: return KC_LBRC;
|
||||
case KS_RBRC: return KC_RBRC;
|
||||
case KS_RCBR: return KC_RBRC;
|
||||
case KS_A: return KC_A;
|
||||
case KS_S_A: return KC_A;
|
||||
case KS_S: return KC_S;
|
||||
case KS_S_S: return KC_S;
|
||||
case KS_D: return KC_D;
|
||||
case KS_S_D: return KC_D;
|
||||
case KS_F: return KC_F;
|
||||
case KS_S_F: return KC_F;
|
||||
case KS_G: return KC_G;
|
||||
case KS_S_G: return KC_G;
|
||||
case KS_H: return KC_H;
|
||||
case KS_S_H: return KC_H;
|
||||
case KS_J: return KC_J;
|
||||
case KS_S_J: return KC_J;
|
||||
case KS_K: return KC_K;
|
||||
case KS_S_K: return KC_K;
|
||||
case KS_L: return KC_L;
|
||||
case KS_S_L: return KC_L;
|
||||
case KS_SCLN: return KC_SCLN;
|
||||
case KS_COLN: return KC_SCLN;
|
||||
case KS_QUOT: return KC_QUOT;
|
||||
case KS_DQUO: return KC_QUOT;
|
||||
case KS_BSLS: return KC_BSLS;
|
||||
case KS_PIPE: return KC_BSLS;
|
||||
case KS_Z: return KC_Z;
|
||||
case KS_S_Z: return KC_Z;
|
||||
case KS_X: return KC_X;
|
||||
case KS_S_X: return KC_X;
|
||||
case KS_C: return KC_C;
|
||||
case KS_S_C: return KC_C;
|
||||
case KS_V: return KC_V;
|
||||
case KS_S_V: return KC_V;
|
||||
case KS_B: return KC_B;
|
||||
case KS_S_B: return KC_B;
|
||||
case KS_N: return KC_N;
|
||||
case KS_S_N: return KC_N;
|
||||
case KS_M: return KC_M;
|
||||
case KS_S_M: return KC_M;
|
||||
case KS_COMM: return KC_COMM;
|
||||
case KS_LT: return KC_COMM;
|
||||
case KS_DOT: return KC_DOT;
|
||||
case KS_GT: return KC_DOT;
|
||||
case KS_SLSH: return KC_SLSH;
|
||||
case KS_QUES: return KC_SLSH;
|
||||
|
||||
default: return NONE_KEY;
|
||||
}
|
||||
}
|
||||
|
||||
Shift shift_get_shift(Key key) {
|
||||
if (KS_GRV <= key && key <= KS_QUES) {
|
||||
return (key - KS_GRV) % 2;
|
||||
} else {
|
||||
return NONE_SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
void shift_activate(Shift shift) {
|
||||
if (shift_current != shift) {
|
||||
shift_timer = timer_read();
|
||||
if (shift) {
|
||||
register_code(KC_LSHIFT);
|
||||
} else {
|
||||
unregister_code(KC_LSHIFT);
|
||||
}
|
||||
}
|
||||
shift_current = shift;
|
||||
}
|
||||
|
||||
void shift_activate_from_user(Shift shift) {
|
||||
shift_should_be = shift;
|
||||
shift_activate(shift);
|
||||
}
|
||||
|
||||
Key shift_process(Key key, bool down) {
|
||||
Shift new_shift = shift_get_shift(key);
|
||||
if (down) {
|
||||
if (new_shift != NONE_SHIFT) {
|
||||
shift_activate(new_shift);
|
||||
} else {
|
||||
shift_activate(shift_should_be);
|
||||
}
|
||||
}
|
||||
|
||||
if (new_shift != NONE_SHIFT) {
|
||||
if (down) {
|
||||
shift_pressed_count++;
|
||||
} else {
|
||||
shift_pressed_count--;
|
||||
}
|
||||
}
|
||||
|
||||
return shift_get_key(key);
|
||||
}
|
||||
|
||||
void shift_user_timer(void) {
|
||||
// Нужно выключать шифт после прохождения определённого времени, потому что пользователь ожидает как будто шифт на самом деле включён
|
||||
if (shift_pressed_count == 0 && shift_current != shift_should_be && timer_read() - shift_timer >= 100) {
|
||||
shift_activate(shift_should_be);
|
||||
shift_timer = timer_read();
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Работа с одиночным шифтом
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
uint8_t shift_once_disable_stage = 2;
|
||||
uint8_t shift_once_layer_off = 0;
|
||||
uint8_t shift_once_layer_current = 0;
|
||||
uint32_t shift_once_enabled_time = 0;
|
||||
bool shift_once_can_disable = true;
|
||||
|
||||
bool shift_once_is_enabled(void) {
|
||||
return shift_once_disable_stage == 2;
|
||||
}
|
||||
|
||||
void shift_once_use_to_next_key(uint8_t layer) {
|
||||
if (shift_current == 0) {
|
||||
shift_activate_from_user(true);
|
||||
layer_on(layer);
|
||||
shift_once_disable_stage = 2;
|
||||
shift_once_layer_off = layer;
|
||||
shift_once_enabled_time = timer_read();
|
||||
}
|
||||
}
|
||||
|
||||
void shift_once_process_key(uint8_t layer, bool down) {
|
||||
if (down) {
|
||||
shift_once_use_to_next_key(layer);
|
||||
shift_once_can_disable = false;
|
||||
} else {
|
||||
shift_once_can_disable = true;
|
||||
shift_once_enabled_time = timer_read();
|
||||
}
|
||||
}
|
||||
|
||||
void shift_once_disable(void) {
|
||||
if (shift_once_disable_stage == 2) {
|
||||
layer_off(shift_once_layer_off);
|
||||
shift_activate_from_user(false);
|
||||
shift_once_disable_stage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void shift_once_process(Key key, keyrecord_t* record) {
|
||||
bool down = record->event.pressed;
|
||||
|
||||
if (shift_once_disable_stage == 1) {
|
||||
shift_once_disable_stage = 0;
|
||||
shift_activate_from_user(false);
|
||||
}
|
||||
if (down && key != SFT_N_O && shift_once_disable_stage == 2) {
|
||||
shift_once_disable_stage = 1;
|
||||
layer_off(shift_once_layer_off);
|
||||
}
|
||||
}
|
||||
|
||||
void shift_once_user_timer(void) {
|
||||
if (shift_once_can_disable && shift_once_is_enabled() && timer_read() - shift_once_enabled_time >= 1000) {
|
||||
shift_once_disable();
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Работа с языком
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Lang lang_should_be = 0;
|
||||
Lang lang_current = 0;
|
||||
uint32_t lang_timer = 0;
|
||||
uint8_t lang_pressed_count = 0;
|
||||
|
||||
Key lang_get_key(Key key) {
|
||||
if (EN_GRV <= key && key <= EN_QUES) {
|
||||
return (key - EN_GRV) + KS_GRV;
|
||||
} else if (RU_JO <= key && key <= RU_COMM) {
|
||||
return (key - RU_JO) + KS_GRV;
|
||||
} else {
|
||||
return NONE_KEY;
|
||||
}
|
||||
}
|
||||
|
||||
Lang lang_get_lang(Key key) {
|
||||
if (EN_GRV <= key && key <= EN_QUES) {
|
||||
return 0;
|
||||
} else if (RU_JO <= key && key <= RU_COMM) {
|
||||
return 1;
|
||||
} else {
|
||||
return NONE_LANG;
|
||||
}
|
||||
}
|
||||
|
||||
Key lang_calc_agnostic(Key key) {
|
||||
if (lang_current == 0) {
|
||||
switch (key) {
|
||||
case AG_1: return EN_1;
|
||||
case AG_2: return EN_2;
|
||||
case AG_3: return EN_3;
|
||||
case AG_4: return EN_4;
|
||||
case AG_5: return EN_5;
|
||||
case AG_6: return EN_6;
|
||||
case AG_7: return EN_7;
|
||||
case AG_8: return EN_8;
|
||||
case AG_9: return EN_9;
|
||||
case AG_0: return EN_0;
|
||||
case AG_EXCL: return EN_EXCL;
|
||||
case AG_PERC: return EN_PERC;
|
||||
case AG_ASTR: return EN_ASTR;
|
||||
case AG_LPRN: return EN_LPRN;
|
||||
case AG_RPRN: return EN_RPRN;
|
||||
case AG_MINS: return EN_MINS;
|
||||
case AG_UNDS: return EN_UNDS;
|
||||
case AG_EQL: return EN_EQL;
|
||||
case AG_PLUS: return EN_PLUS;
|
||||
case AG_SCLN: return EN_SCLN;
|
||||
case AG_COLN: return EN_COLN;
|
||||
case AG_DQUO: return EN_DQUO;
|
||||
case AG_BSLS: return EN_BSLS;
|
||||
case AG_COMM: return EN_COMM;
|
||||
case AG_DOT: return EN_DOT;
|
||||
case AG_SLSH: return EN_SLSH;
|
||||
case AG_QUES: return EN_QUES;
|
||||
default: return NONE_KEY;
|
||||
}
|
||||
} else {
|
||||
switch (key) {
|
||||
case AG_1: return RU_1;
|
||||
case AG_2: return RU_2;
|
||||
case AG_3: return RU_3;
|
||||
case AG_4: return RU_4;
|
||||
case AG_5: return RU_5;
|
||||
case AG_6: return RU_6;
|
||||
case AG_7: return RU_7;
|
||||
case AG_8: return RU_8;
|
||||
case AG_9: return RU_9;
|
||||
case AG_0: return RU_0;
|
||||
case AG_EXCL: return RU_EXCL;
|
||||
case AG_PERC: return RU_PERC;
|
||||
case AG_ASTR: return RU_ASTR;
|
||||
case AG_LPRN: return RU_LPRN;
|
||||
case AG_RPRN: return RU_RPRN;
|
||||
case AG_MINS: return RU_MINS;
|
||||
case AG_UNDS: return RU_UNDS;
|
||||
case AG_EQL: return RU_EQL;
|
||||
case AG_PLUS: return RU_PLUS;
|
||||
case AG_SCLN: return RU_SCLN;
|
||||
case AG_COLN: return RU_COLN;
|
||||
case AG_DQUO: return RU_DQUO;
|
||||
case AG_BSLS: return RU_BSLS;
|
||||
case AG_COMM: return RU_COMM;
|
||||
case AG_DOT: return RU_DOT;
|
||||
case AG_SLSH: return RU_SLSH;
|
||||
case AG_QUES: return RU_QUES;
|
||||
default: return NONE_KEY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t lang_get_shift_layer_number(void) {
|
||||
return lang_should_be * 2 + 1;
|
||||
}
|
||||
|
||||
void lang_synchronize(void) {
|
||||
lang_timer = timer_read();
|
||||
switch (lang_current_change) {
|
||||
case LANG_CHANGE_CAPS: {
|
||||
// Костыль, потому что при нажатии Shift+Caps включается режим Caps, а не переключение языка :facepalm:
|
||||
if (shift_current == 1) {
|
||||
unregister_code(KC_LSHIFT);
|
||||
register_code(KC_CAPS);
|
||||
unregister_code(KC_CAPS);
|
||||
register_code(KC_LSHIFT);
|
||||
} else {
|
||||
register_code(KC_CAPS);
|
||||
unregister_code(KC_CAPS);
|
||||
}
|
||||
} break;
|
||||
case LANG_CHANGE_ALT_SHIFT: {
|
||||
register_code(KC_LALT);
|
||||
register_code(KC_LSHIFT);
|
||||
unregister_code(KC_LSHIFT);
|
||||
unregister_code(KC_LALT);
|
||||
|
||||
// Костыль, потому что при зажатом шифте если хочется нажать клавишу, которая переключает язык, то шифт слетает...
|
||||
if (shift_current == 1) {
|
||||
register_code(KC_LSHIFT);
|
||||
}
|
||||
} break;
|
||||
case LANG_CHANGE_SHIFT_ALT: {
|
||||
register_code(KC_LSHIFT);
|
||||
register_code(KC_LALT);
|
||||
unregister_code(KC_LALT);
|
||||
unregister_code(KC_LSHIFT);
|
||||
|
||||
// Костыль, потому что при зажатом шифте если хочется нажать клавишу, которая переключает язык, то шифт слетает...
|
||||
if (shift_current == 1) {
|
||||
register_code(KC_LSHIFT);
|
||||
}
|
||||
} break;
|
||||
case LANG_CHANGE_CTRL_SHIFT: {
|
||||
register_code(KC_LCTRL);
|
||||
register_code(KC_LSHIFT);
|
||||
unregister_code(KC_LSHIFT);
|
||||
unregister_code(KC_LCTL);
|
||||
|
||||
// Костыль, потому что при зажатом шифте если хочется нажать клавишу, которая переключает язык, то шифт слетает...
|
||||
if (shift_current == 1) {
|
||||
register_code(KC_LSHIFT);
|
||||
}
|
||||
} break;
|
||||
case LANG_CHANGE_SHIFT_CTRL: {
|
||||
register_code(KC_LSHIFT);
|
||||
register_code(KC_LCTRL);
|
||||
unregister_code(KC_LCTL);
|
||||
unregister_code(KC_LSHIFT);
|
||||
|
||||
// Костыль, потому что при зажатом шифте если хочется нажать клавишу, которая переключает язык, то шифт слетает...
|
||||
if (shift_current == 1) {
|
||||
register_code(KC_LSHIFT);
|
||||
}
|
||||
} break;
|
||||
case LANG_CHANGE_WIN_SPACE: {
|
||||
register_code(KC_LGUI);
|
||||
register_code(KC_SPACE);
|
||||
unregister_code(KC_SPACE);
|
||||
unregister_code(KC_LGUI);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void lang_activate(Lang lang) {
|
||||
// Нужно дополнять этот код, если нужно три языка и более
|
||||
if (lang_current != lang) {
|
||||
lang_synchronize();
|
||||
}
|
||||
lang_current = lang;
|
||||
}
|
||||
|
||||
void lang_activate_from_user(Lang lang) {
|
||||
lang_should_be = lang;
|
||||
lang_activate(lang);
|
||||
}
|
||||
|
||||
void lang_activate_from_user_without_sync(Lang lang) {
|
||||
lang_should_be = lang;
|
||||
lang_current = lang;
|
||||
}
|
||||
|
||||
Key lang_process(Key key, bool down) {
|
||||
Key after_agnostic = lang_calc_agnostic(key);
|
||||
if (after_agnostic != NONE_KEY) {
|
||||
key = after_agnostic;
|
||||
}
|
||||
|
||||
Lang new_lang = lang_get_lang(key);
|
||||
if (down) {
|
||||
if (new_lang != NONE_LANG) {
|
||||
lang_activate(new_lang);
|
||||
} else {
|
||||
lang_activate(lang_should_be);
|
||||
}
|
||||
}
|
||||
|
||||
if (new_lang != NONE_LANG) {
|
||||
if (down) {
|
||||
lang_pressed_count++;
|
||||
} else {
|
||||
lang_pressed_count--;
|
||||
}
|
||||
}
|
||||
|
||||
return lang_get_key(key);
|
||||
}
|
||||
|
||||
void lang_user_timer(void) {
|
||||
// Нужно выключать язык после прохождения определённого времени, потому что пользователь ожидает как будто шифт на самом деле включён
|
||||
if (lang_pressed_count == 0 && lang_current != lang_should_be && timer_read() - lang_timer >= 100) {
|
||||
lang_activate(lang_should_be);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Обработка клавиш
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
uint8_t lang_shift_current_shift_layer = 0;
|
||||
|
||||
void lang_shift_press_key(Key key, bool down) {
|
||||
keyrecord_t record = {
|
||||
.event = {
|
||||
.key = {
|
||||
.col = 0,
|
||||
.row = 0,
|
||||
},
|
||||
.pressed = down,
|
||||
.time = timer_read(),
|
||||
},
|
||||
};
|
||||
|
||||
lang_shift_process_record(key, &record);
|
||||
}
|
||||
|
||||
void lang_shift_tap_key(Key key) {
|
||||
lang_shift_press_key(key, true);
|
||||
lang_shift_press_key(key, false);
|
||||
shift_activate(shift_should_be);
|
||||
lang_activate(lang_should_be);
|
||||
}
|
||||
|
||||
bool lang_shift_process_custom_keycodes(Key key, keyrecord_t* record) {
|
||||
bool down = record->event.pressed;
|
||||
|
||||
// Обрабатываем клавиши, связанные с кастомным шифтом и кастомным переключением языка
|
||||
switch (key) {
|
||||
case SFT_N_O:
|
||||
shift_once_process_key(lang_get_shift_layer_number(), down);
|
||||
return false;
|
||||
case SFT_N:
|
||||
if (down) {
|
||||
shift_activate_from_user(true);
|
||||
lang_shift_current_shift_layer = lang_get_shift_layer_number();
|
||||
layer_on(lang_shift_current_shift_layer);
|
||||
} else {
|
||||
shift_should_be = false;
|
||||
if (shift_pressed_count == 0) {
|
||||
shift_activate_from_user(false);
|
||||
}
|
||||
layer_off(lang_shift_current_shift_layer);
|
||||
}
|
||||
return false;
|
||||
case LA_CHNG:
|
||||
if (down) {
|
||||
if (lang_should_be == 0) {
|
||||
lang_activate_from_user(1);
|
||||
layer_on(2);
|
||||
} else {
|
||||
lang_activate_from_user(0);
|
||||
layer_off(2);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
case LA_SYNC:
|
||||
if (down) {
|
||||
lang_synchronize();
|
||||
}
|
||||
return false;
|
||||
case LA_CAPS:
|
||||
if (down) {
|
||||
lang_current_change = LANG_CHANGE_CAPS;
|
||||
}
|
||||
return false;
|
||||
case LA_ALSH:
|
||||
if (down) {
|
||||
lang_current_change = LANG_CHANGE_ALT_SHIFT;
|
||||
}
|
||||
return false;
|
||||
case LA_SHAL:
|
||||
if (down) {
|
||||
lang_current_change = LANG_CHANGE_SHIFT_ALT;
|
||||
}
|
||||
return false;
|
||||
case LA_CTSH:
|
||||
if (down) {
|
||||
lang_current_change = LANG_CHANGE_CTRL_SHIFT;
|
||||
}
|
||||
return false;
|
||||
case LA_SHCT:
|
||||
if (down) {
|
||||
lang_current_change = LANG_CHANGE_SHIFT_CTRL;
|
||||
}
|
||||
return false;
|
||||
case LA_WISP:
|
||||
if (down) {
|
||||
lang_current_change = LANG_CHANGE_WIN_SPACE;
|
||||
}
|
||||
return false;
|
||||
case AG_3DOT:
|
||||
if (record->event.pressed) {
|
||||
lang_shift_tap_key(AG_DOT);
|
||||
lang_shift_tap_key(AG_DOT);
|
||||
lang_shift_tap_key(AG_DOT);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case AG_CMSP:
|
||||
if (record->event.pressed) {
|
||||
lang_shift_tap_key(AG_COMM);
|
||||
register_code(KC_SPC);
|
||||
unregister_code(KC_SPC);
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case AG_SDOT:
|
||||
if (record->event.pressed) {
|
||||
lang_shift_tap_key(AG_DOT);
|
||||
register_code(KC_SPC);
|
||||
unregister_code(KC_SPC);
|
||||
shift_once_use_to_next_key(lang_get_shift_layer_number());
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lang_shift_process_english_modifiers(Key key, keyrecord_t* record) {
|
||||
static Lang lang_stack[3] = {};
|
||||
static uint8_t modifiers_count = 0;
|
||||
#define PROCESS(NAME, REGISTER, UNREGISTER, ACTIVATE_LANG) \
|
||||
case NAME: { \
|
||||
if (record->event.pressed) { \
|
||||
lang_stack[modifiers_count] = lang_should_be; \
|
||||
modifiers_count += 1; \
|
||||
if (lang_should_be == 1) { \
|
||||
layer_off(2); \
|
||||
} \
|
||||
if (ACTIVATE_LANG) { \
|
||||
lang_activate_from_user(0); \
|
||||
} else { \
|
||||
lang_activate_from_user_without_sync(0); \
|
||||
} \
|
||||
REGISTER; \
|
||||
} else { \
|
||||
UNREGISTER; \
|
||||
modifiers_count -= 1; \
|
||||
if (ACTIVATE_LANG) { \
|
||||
lang_activate_from_user(lang_stack[modifiers_count]); \
|
||||
} else { \
|
||||
lang_activate_from_user_without_sync(lang_stack[modifiers_count]); \
|
||||
} \
|
||||
if (lang_should_be == 1) { \
|
||||
layer_on(2); \
|
||||
} \
|
||||
} \
|
||||
return false; \
|
||||
} break;
|
||||
|
||||
#define Rg(x) register_code(KC_L ## x)
|
||||
#define Un(x) unregister_code(KC_L ## x)
|
||||
|
||||
switch (key) {
|
||||
PROCESS(CTRL_0, Rg(CTRL), Un(CTRL), false);
|
||||
PROCESS(ALT_0, Rg(ALT), Un(ALT), false);
|
||||
PROCESS(WIN_0, Rg(GUI), Un(GUI), false);
|
||||
PROCESS(CTAL_0, { Rg(CTRL); Rg(ALT); }, { Un(ALT); Un(CTRL); }, false);
|
||||
PROCESS(SHAL_0, { Rg(SHIFT); Rg(ALT); }, { Un(ALT); Un(SHIFT); }, false);
|
||||
PROCESS(CTSH_0, { Rg(CTRL); Rg(SHIFT); }, { Un(SHIFT); Un(CTRL); }, false);
|
||||
PROCESS(MCAS_0, { Rg(CTRL); Rg(ALT); Rg(SHIFT); }, { Un(SHIFT); Un(ALT); Un(CTRL); }, false);
|
||||
|
||||
PROCESS(CTRL_EN, Rg(CTRL), Un(CTRL), true);
|
||||
PROCESS(ALT_EN, Rg(ALT), Un(ALT), true);
|
||||
PROCESS(WIN_EN, Rg(GUI), Un(GUI), true);
|
||||
PROCESS(CTAL_EN, { Rg(CTRL); Rg(ALT); }, { Un(ALT); Un(CTRL); }, true);
|
||||
PROCESS(SHAL_EN, { Rg(SHIFT); Rg(ALT); }, { Un(ALT); Un(SHIFT); }, true);
|
||||
PROCESS(CTSH_EN, { Rg(CTRL); Rg(SHIFT); }, { Un(SHIFT); Un(CTRL); }, true);
|
||||
PROCESS(MCAS_EN, { Rg(CTRL); Rg(ALT); Rg(SHIFT); }, { Un(SHIFT); Un(ALT); Un(CTRL); }, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lang_shift_process_record(Key key, keyrecord_t* record) {
|
||||
// Обрабатываем Once Shift
|
||||
shift_once_process(key, record);
|
||||
|
||||
bool down = record->event.pressed;
|
||||
|
||||
// Разбираемся, имеет ли эта клавиша какой-то язык, заданный в ней
|
||||
Key key1 = lang_process(key, down);
|
||||
Key key_to_shift = key;
|
||||
if (key1 != NONE_KEY) {
|
||||
key_to_shift = key1;
|
||||
}
|
||||
|
||||
// Разбираемся, имеет ли эта клавиша шифт, засунутый в неё
|
||||
// Это нужно отдельно от обработки языка, чтобы шифт мог выключаться для обычных клавиш
|
||||
Key key2 = shift_process(key_to_shift, down);
|
||||
if (key2 != NONE_KEY) {
|
||||
if (down) {
|
||||
register_code(key2);
|
||||
} else {
|
||||
unregister_code(key2);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!lang_shift_process_custom_keycodes(key, record)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!lang_shift_process_english_modifiers(key, record)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void lang_shift_user_timer(void) {
|
||||
shift_user_timer();
|
||||
shift_once_user_timer();
|
||||
lang_user_timer();
|
||||
}
|
||||
13
qmk/rules.mk
Normal file
13
qmk/rules.mk
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
LTO_ENABLE = yes
|
||||
MOUSEKEY_ENABLE = yes
|
||||
EXTRAKEY_ENABLE = yes # Audio control and System control
|
||||
NKRO_ENABLE = yes
|
||||
RGBLIGHT_ENABLE = yes
|
||||
TAP_DANCE_ENABLE = yes
|
||||
|
||||
BACKLIGHT_ENABLE = no
|
||||
MUSIC_ENABLE = no
|
||||
OLED_ENABLE = no
|
||||
COMBO_ENABLE = no
|
||||
KEY_OVERRIDE_ENABLE = no
|
||||
QMK_SETTINGS = no
|
||||
Reference in a new issue