From 26adf3706a7822e05977c0eadb6963c0db2e1c3b Mon Sep 17 00:00:00 2001 From: SpacebarRacecar <42380065+SpacebarRacecar@users.noreply.github.com> Date: Fri, 5 Oct 2018 00:00:33 +0200 Subject: Keymap: Added personal userspace and keymaps. (#4073) * added personal userspace, niu mini, planck and fc660c keymaps * removed unnecessary include and some other minor corrections --- users/spacebarracecar/config.h | 0 users/spacebarracecar/rules.mk | 5 + users/spacebarracecar/spacebarracecar.c | 305 ++++++++++++++++++++++++++++++++ users/spacebarracecar/spacebarracecar.h | 242 +++++++++++++++++++++++++ 4 files changed, 552 insertions(+) create mode 100644 users/spacebarracecar/config.h create mode 100644 users/spacebarracecar/rules.mk create mode 100644 users/spacebarracecar/spacebarracecar.c create mode 100644 users/spacebarracecar/spacebarracecar.h (limited to 'users/spacebarracecar') diff --git a/users/spacebarracecar/config.h b/users/spacebarracecar/config.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/users/spacebarracecar/rules.mk b/users/spacebarracecar/rules.mk new file mode 100644 index 0000000000..319e887ae3 --- /dev/null +++ b/users/spacebarracecar/rules.mk @@ -0,0 +1,5 @@ +SRC += spacebarracecar.c + +ifeq ($(strip $(GERMAN_ENABLE)), yes) + OPT_DEFS += -DGERMAN_ENABLE +endif diff --git a/users/spacebarracecar/spacebarracecar.c b/users/spacebarracecar/spacebarracecar.c new file mode 100644 index 0000000000..404331f8df --- /dev/null +++ b/users/spacebarracecar/spacebarracecar.c @@ -0,0 +1,305 @@ +#include "spacebarracecar.h" + +#ifdef GERMAN_ENABLE +bool lshift = false; +bool rshift = false; +bool lshiftp = false; +bool rshiftp = false; +uint16_t lshift_timer = 0; +uint16_t rshift_timer = 0; + +uint8_t prev_indx = 0; +uint16_t prev_kcs[6] = {0, 0, 0, 0, 0, 0}; + +bool esct = false; + +void add_to_prev(uint16_t kc){ + for (int i=0; i0; i--){ + prev_kcs[i] = prev_kcs[i-1]; + } + prev_kcs[0] = kc; + } else { + prev_kcs[prev_indx] = kc; + prev_indx++; + } +} + +void unreg_prev(void){ + if (prev_indx == 0) + return; + for (int i=0; ievent.pressed) { + game = !game; + } + return false; + case KC_LGUI: + case KC_RGUI: + if (game) + return false; + else + return true; + case CU_NAV: + if(record->event.pressed) { + navesc = true; + navesc_timer = timer_read(); + layer_on(_NAV); + } else { + if (timer_elapsed(navesc_timer) < 200 && navesc) { + register_code(KC_ESC); + unregister_code(KC_ESC); + } + layer_off(_NAV); + } + return false; + + #ifdef RGBLIGHT_ENABLE + case CU_RGBV: + if(record->event.pressed) { + if (rgblight_get_val()+32>255) + rgblight_sethsv(rgblight_get_hue(), rgblight_get_sat(), 31); + else + rgblight_sethsv(rgblight_get_hue(), rgblight_get_sat(), rgblight_get_val()+32); + } + return false; + #endif + + #ifdef GERMAN_ENABLE + case CU_LSFT: + if(record->event.pressed) { + lshiftp = true; + lshift_timer = timer_read(); + unregister_code(KC_LSFT); + register_code(KC_LSFT); + lshift = true; + } else { + if (timer_elapsed(lshift_timer) < 200 && lshiftp && !game) { + register_code(KC_LSFT); + register_code(KC_8); + unregister_code(KC_8); + unregister_code(KC_LSFT); + } + unreg_prev(); + if (!rshift) + unregister_code(KC_LSFT); + lshift = false; + } + return false; + case CU_RSFT: + if(record->event.pressed) { + rshiftp = true; + rshift_timer = timer_read(); + unregister_code(KC_LSFT); + register_code(KC_LSFT); + rshift = true; + } else { + if (timer_elapsed(rshift_timer) < 200 && rshiftp && !game) { + register_code(KC_LSFT); + register_code(KC_9); + unregister_code(KC_9); + unregister_code(KC_LSFT); + } + unreg_prev(); + if (!lshift) + unregister_code(KC_LSFT); + rshift = false; + } + return false; + case CU_ESCT: + if(record->event.pressed) { + esct = !esct; + } + return false; + case CU_AE: + UML(DE_AE) + case CU_OE: + UML(DE_OE) + case CU_UE: + UML(DE_UE) + case CU_SS: + if(record->event.pressed) { + timer_timeout(); + unregister_code(KC_LSFT); + register_code(DE_SS); + unregister_code(DE_SS); + if (lshift || rshift) + register_code(KC_LSFT); + layer_off(_DEADKEY); + } + return false; + case CU_DDQ: + if(record->event.pressed) { + timer_timeout(); + register_code(KC_LSFT); + register_code(KC_2); + unregister_code(KC_2); + if (!lshift && !rshift) + unregister_code(KC_LSFT); + layer_off(_DEADKEY); + } + return false; + case CU_ED: + if(record->event.pressed) { + timer_timeout(); + layer_off(_DEADKEY); + } + return false; + case CU_GRV: + if(record->event.pressed) { + timer_timeout(); + if (lshift || rshift){ + unregister_code(KC_LSFT); + register_code(DE_ALGR); + unregister_code(DE_PLUS); + register_code(DE_PLUS); + unregister_code(DE_PLUS); + unregister_code(DE_ALGR); + register_code(KC_LSFT); + } else { + register_code(KC_LSFT); + unregister_code(DE_ACUT); + register_code(DE_ACUT); + unregister_code(DE_ACUT); + unregister_code(KC_LSFT); + if (!esct) { + register_code(KC_SPC); + unregister_code(KC_SPC); + } + } + } + return false; + case CU_CIRC: + if(record->event.pressed) { + timer_timeout(); + unregister_code(KC_LSFT); + unregister_code(DE_CIRC); + register_code(DE_CIRC); + unregister_code(DE_CIRC); + if (!esct) { + register_code(KC_SPC); + unregister_code(KC_SPC); + } + if (lshift || rshift) + register_code(KC_LSFT); + } + return false; + case CU_QUOT: + if(record->event.pressed){ + timer_timeout(); + register_code(KC_LSFT); + if (lshift || rshift){ + layer_on(_DEADKEY); + } else { + unregister_code(DE_HASH); + register_code(DE_HASH); + add_to_prev(DE_HASH); + } + } else { + unregister_code(DE_HASH); + unreg_prev(); + if (lshift || rshift) + register_code(KC_LSFT); + else + unregister_code(KC_LSFT); + } + return false; + case CU_6: + if(record->event.pressed){ + timer_timeout(); + unregister_code(KC_LSFT); + if (lshift || rshift){ + unregister_code(DE_CIRC); + register_code(DE_CIRC); + unregister_code(DE_CIRC); + if (!esct) { + register_code(KC_SPC); + unregister_code(KC_SPC); + } + register_code(KC_LSFT); + } else { + register_code(DE_6); + } + } else { + unregister_code(DE_6); + } + return false; + case CU_COMM: + SHIFT_NO(DE_COMM, DE_LESS) + case CU_DOT: + SHIFT_NORM(DE_DOT, DE_LESS) + case CU_SLSH: + SHIFT_ALL(DE_7, DE_SS) + case CU_SCLN: + SHIFT_ALL(DE_COMM, DE_DOT) + case CU_3: + SHIFT_NO(DE_3, DE_HASH) + case CU_7: + SHIFT_NORM(DE_7, DE_6) + case CU_8: + SHIFT_NORM(DE_8, DE_PLUS) + case CU_9: + SHIFT_NORM(DE_9, DE_8) + case CU_0: + SHIFT_NORM(DE_0, DE_9) + case CU_EQL: + SHIFT_SWITCH(DE_0, DE_PLUS) + case CU_LBRC: + SHIFT_ALGR(DE_8, DE_7) + case CU_RBRC: + SHIFT_ALGR(DE_9, DE_0) + case CU_BSLS: + SHIFT_ALGR(DE_SS, DE_LESS) + case CU_Z: + CTRL(DE_Z, KC_Z) + case CU_Y: + CTRL(DE_Y, KC_Y) + case KC_LCTL: + case KC_RCTL: + if(!record->event.pressed) { + unregister_code(KC_Z); + unregister_code(KC_Y); + } + return true; + #endif + + default: + if(record->event.pressed) { + timer_timeout(); + + #ifdef GERMAN_ENABLE + if (lshift || rshift) + register_code(KC_LSFT); + else + unregister_code(KC_LSFT); + #endif + + } + return true; + } +} diff --git a/users/spacebarracecar/spacebarracecar.h b/users/spacebarracecar/spacebarracecar.h new file mode 100644 index 0000000000..42879d2efb --- /dev/null +++ b/users/spacebarracecar/spacebarracecar.h @@ -0,0 +1,242 @@ +#pragma once + +#include "quantum.h" +#include "keymap_german.h" + +enum userspace_layers { + _DEADKEY = 14, //change if more than 16 layers are required + _NAV +}; + +enum userspace_custom_keycodes { + CU_GAME = SAFE_RANGE, // Toggle game mode on/off + CU_NAV, // NAV | ESC + + #ifdef GERMAN_ENABLE + CU_LSFT, // LSFT | ( + CU_RSFT, // LSFT | ) + CU_COMM, // , | < + CU_DOT, // . | > + CU_SLSH, // / | ? + CU_SCLN, // ; | : + CU_QUOT, // ' | Enable deadkey layer + CU_GRV, // ` | ~ + CU_CIRC, // ^ + CU_3, // 3 | # + CU_6, // 6 | ^ + CU_7, // 7 | & + CU_8, // 8 | * + CU_9, // 9 | ( + CU_0, // 0 | ) + CU_EQL, // = | + + CU_LBRC, // [ | { + CU_RBRC, // ] | } + CU_BSLS, // \ | | + CU_Z, // Z | Y in conjunction with ctrl + CU_Y, // Y | Z in conjunction wiht ctrl + CU_ESCT, // Toggle escape of grv and circ on/off + // Deadkey Layer + CU_AE, // Ä + CU_OE, // Ö + CU_UE, // Ü + CU_SS, // ß + CU_DDQ, // " + CU_ED, // Escape deadkey layer + #endif + + #ifdef RGBLIGHT_ENABLE + CU_RGBV, // Cycle through RGB brightness + #endif + + NEW_SAFE_RANGE // Use for keymap specific keycodes +}; + +#ifdef GERMAN_ENABLE +// these save the current shift status +extern bool lshift; +extern bool rshift; +// stuff for custom space cadet shift +extern bool lshiftp; +extern bool rshiftp; +extern uint16_t lshift_timer; +extern uint16_t rshift_timer; + +extern uint8_t prev_indx; +extern uint16_t prev_kcs[6]; + +void add_to_prev(uint16_t kc); +void unreg_prev(void); + +extern bool esct; +#endif + +// stuff for nav esc +extern bool navesc; +extern uint16_t navesc_timer; + +extern bool game; + +void timer_timeout(void); + +bool process_record_userspace(uint16_t keycode, keyrecord_t *record); + +#define CTRLX LCTL(KC_X) +#define CTRLC LCTL(KC_C) +#define CTRLV LCTL(KC_V) + +#define GUIU LGUI(KC_UP) +#define GUID LGUI(KC_DOWN) +#define GUIL LGUI(KC_LEFT) +#define GUIR RGUI(KC_RIGHT) + +// +// Templates for Keys, with custom shifted and non shifted Characters +// + +// Normal shift status +#define SHIFT_NORM(kc1, kc2) \ +if (record->event.pressed) { \ + timer_timeout(); \ + if (lshift || rshift) { \ + register_code(KC_LSFT); \ + unregister_code(kc2); \ + register_code(kc2); \ + add_to_prev(kc2); \ + } else { \ + unregister_code(KC_LSFT); \ + unregister_code(kc1); \ + register_code(kc1); \ + } \ +} else { \ + unregister_code(kc1); \ + unregister_code(kc2); \ +} \ +return false; + +// Inverted shift status +#define SHIFT_SWITCH(kc1, kc2) \ +if (record->event.pressed) { \ + timer_timeout(); \ + if (lshift || rshift) { \ + unregister_code(KC_LSFT); \ + unregister_code(kc2); \ + register_code(kc2); \ + add_to_prev(kc2); \ + } else { \ + register_code(KC_LSFT); \ + unregister_code(kc1); \ + register_code(kc1); \ + add_to_prev(kc1); \ + } \ +} else { \ + unregister_code(kc1); \ + unregister_code(kc2); \ + unreg_prev(); \ + if (lshift || rshift) \ + register_code(KC_LSFT); \ + else \ + unregister_code(KC_LSFT); \ +} \ +return false; + +// All shift +#define SHIFT_ALL(kc1, kc2) \ +if (record->event.pressed) { \ + timer_timeout(); \ + register_code(KC_LSFT); \ + if (lshift || rshift) { \ + unregister_code(kc2); \ + register_code(kc2); \ + add_to_prev(kc2); \ + } else { \ + unregister_code(kc1); \ + register_code(kc1); \ + add_to_prev(kc1); \ + } \ +} else { \ + unregister_code(kc1); \ + unregister_code(kc2); \ + unreg_prev(); \ + if (lshift || rshift) \ + register_code(KC_LSFT); \ + else \ + unregister_code(KC_LSFT); \ +} \ +return false; + +// All no shift +#define SHIFT_NO(kc1, kc2) \ +if (record->event.pressed) { \ + timer_timeout(); \ + unregister_code(KC_LSFT); \ + if (lshift || rshift) { \ + unregister_code(kc2); \ + register_code(kc2); \ + add_to_prev(kc2); \ + } else { \ + unregister_code(kc1); \ + register_code(kc1); \ + } \ +} else { \ + unregister_code(kc1); \ + unregister_code(kc2); \ + unreg_prev(); \ + if (lshift || rshift) \ + register_code(KC_LSFT); \ + else \ + unregister_code(KC_LSFT); \ +} \ +return false; + +// All algr +#define SHIFT_ALGR(kc1, kc2) \ +if (record->event.pressed) { \ + timer_timeout(); \ + unregister_code(KC_LSFT); \ + register_code(DE_ALGR); \ + if (lshift || rshift) { \ + unregister_code(kc2); \ + register_code(kc2); \ + unregister_code(kc2); \ + register_code(KC_LSFT); \ + } else { \ + unregister_code(kc1); \ + register_code(kc1); \ + unregister_code(kc1); \ + } \ + unregister_code(DE_ALGR); \ +} \ +return false; + +// Different keycode for ctrl +#define CTRL(kc1, kc2) \ +if(record->event.pressed) { \ + timer_timeout(); \ + if (lshift || rshift) \ + register_code(KC_LSFT); \ + else \ + unregister_code(KC_LSFT); \ + if (keyboard_report->mods & (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL))){ \ + register_code(kc2); \ + } else { \ + register_code(kc1); \ + } \ +} else { \ + unregister_code(kc1); \ + unregister_code(kc2); \ +} \ +return false; + +// Umlaute for deadkey layer +#define UML(kc) \ +if(record->event.pressed) { \ + timer_timeout(); \ + if (lshift || rshift) \ + register_code(KC_LSFT); \ + else \ + unregister_code(KC_LSFT); \ + register_code(kc); \ + unregister_code(kc); \ + layer_off(_DEADKEY); \ +} \ +return false; -- cgit v1.2.3 From 704a2e8d3c0bd15f6c8accd5a39fb88ca6c9e2d5 Mon Sep 17 00:00:00 2001 From: SpacebarRacecar <42380065+SpacebarRacecar@users.noreply.github.com> Date: Mon, 22 Oct 2018 22:23:22 +0200 Subject: Keymap: Updates to personal userspace and keymaps (#4206) * - updated personal userspace - updated fc660c, niu mini and planck keymaps - added prime_o keymap * Rename README.md to readme.md --- users/spacebarracecar/spacebarracecar.c | 47 +++++++++++++++++++++++++++++---- users/spacebarracecar/spacebarracecar.h | 25 ++++++++---------- 2 files changed, 53 insertions(+), 19 deletions(-) (limited to 'users/spacebarracecar') diff --git a/users/spacebarracecar/spacebarracecar.c b/users/spacebarracecar/spacebarracecar.c index 404331f8df..f7048869ed 100644 --- a/users/spacebarracecar/spacebarracecar.c +++ b/users/spacebarracecar/spacebarracecar.c @@ -1,18 +1,29 @@ #include "spacebarracecar.h" #ifdef GERMAN_ENABLE +// These indicate if left and right shift are physically pressed bool lshift = false; bool rshift = false; + +// Interrupt and times for space cadet shift bool lshiftp = false; bool rshiftp = false; uint16_t lshift_timer = 0; uint16_t rshift_timer = 0; +// Number of items that are saved in prev_kcs uint8_t prev_indx = 0; +// Used to save the last 6 actual keycodes activated by frankenkeycodes uint16_t prev_kcs[6] = {0, 0, 0, 0, 0, 0}; +// If true the deadkey characters grave and circonflexe are not automatically escaped bool esct = false; +/* +Used to add a keycode to a prev_kcs to remember it. +When full the last code gets discarded and replaced by +the new one. +*/ void add_to_prev(uint16_t kc){ for (int i=0; ievent.pressed) { + timer_timeout(); game = !game; } - return false; + // allows keymap to execute further commands when CU_GAME is pressed, for example enabling a macro layer + return process_record_keymap(keycode, record) && false; case KC_LGUI: case KC_RGUI: + if (record->event.pressed) + timer_timeout(); if (game) return false; else @@ -77,11 +102,21 @@ bool process_record_userspace(uint16_t keycode, keyrecord_t *record) { } layer_off(_NAV); } - return false; + return false; + case KC_P00: + if(record->event.pressed) { + timer_timeout(); + register_code(KC_P0); + unregister_code(KC_P0); + register_code(KC_P0); + unregister_code(KC_P0); + } + return false; #ifdef RGBLIGHT_ENABLE case CU_RGBV: if(record->event.pressed) { + timer_timeout(); if (rgblight_get_val()+32>255) rgblight_sethsv(rgblight_get_hue(), rgblight_get_sat(), 31); else @@ -133,6 +168,7 @@ bool process_record_userspace(uint16_t keycode, keyrecord_t *record) { return false; case CU_ESCT: if(record->event.pressed) { + timer_timeout(); esct = !esct; } return false; @@ -282,6 +318,7 @@ bool process_record_userspace(uint16_t keycode, keyrecord_t *record) { case KC_LCTL: case KC_RCTL: if(!record->event.pressed) { + timer_timeout(); unregister_code(KC_Z); unregister_code(KC_Y); } @@ -300,6 +337,6 @@ bool process_record_userspace(uint16_t keycode, keyrecord_t *record) { #endif } - return true; + return process_record_keymap(keycode, record); } } diff --git a/users/spacebarracecar/spacebarracecar.h b/users/spacebarracecar/spacebarracecar.h index 42879d2efb..1e18253510 100644 --- a/users/spacebarracecar/spacebarracecar.h +++ b/users/spacebarracecar/spacebarracecar.h @@ -4,13 +4,14 @@ #include "keymap_german.h" enum userspace_layers { - _DEADKEY = 14, //change if more than 16 layers are required + _DEADKEY = 14, // Change if more than 16 layers are required _NAV }; enum userspace_custom_keycodes { CU_GAME = SAFE_RANGE, // Toggle game mode on/off CU_NAV, // NAV | ESC + KC_P00, // Numpad double zero #ifdef GERMAN_ENABLE CU_LSFT, // LSFT | ( @@ -52,10 +53,8 @@ enum userspace_custom_keycodes { }; #ifdef GERMAN_ENABLE -// these save the current shift status extern bool lshift; extern bool rshift; -// stuff for custom space cadet shift extern bool lshiftp; extern bool rshiftp; extern uint16_t lshift_timer; @@ -63,14 +62,12 @@ extern uint16_t rshift_timer; extern uint8_t prev_indx; extern uint16_t prev_kcs[6]; - void add_to_prev(uint16_t kc); void unreg_prev(void); extern bool esct; #endif -// stuff for nav esc extern bool navesc; extern uint16_t navesc_timer; @@ -78,7 +75,7 @@ extern bool game; void timer_timeout(void); -bool process_record_userspace(uint16_t keycode, keyrecord_t *record); +bool process_record_keymap(uint16_t keycode, keyrecord_t *record); #define CTRLX LCTL(KC_X) #define CTRLC LCTL(KC_C) @@ -89,9 +86,9 @@ bool process_record_userspace(uint16_t keycode, keyrecord_t *record); #define GUIL LGUI(KC_LEFT) #define GUIR RGUI(KC_RIGHT) -// -// Templates for Keys, with custom shifted and non shifted Characters -// +/* +Templates for Keys, with custom shifted and non shifted Characters +*/ // Normal shift status #define SHIFT_NORM(kc1, kc2) \ @@ -139,7 +136,7 @@ if (record->event.pressed) { \ } \ return false; -// All shift +// Always shifted #define SHIFT_ALL(kc1, kc2) \ if (record->event.pressed) { \ timer_timeout(); \ @@ -164,7 +161,7 @@ if (record->event.pressed) { \ } \ return false; -// All no shift +// Never shifted #define SHIFT_NO(kc1, kc2) \ if (record->event.pressed) { \ timer_timeout(); \ @@ -188,7 +185,7 @@ if (record->event.pressed) { \ } \ return false; -// All algr +// Always AltGr #define SHIFT_ALGR(kc1, kc2) \ if (record->event.pressed) { \ timer_timeout(); \ @@ -208,7 +205,7 @@ if (record->event.pressed) { \ } \ return false; -// Different keycode for ctrl +// Different keycode when Ctrl is pressed #define CTRL(kc1, kc2) \ if(record->event.pressed) { \ timer_timeout(); \ @@ -227,7 +224,7 @@ if(record->event.pressed) { \ } \ return false; -// Umlaute for deadkey layer +// Template for keys on deadkey layer (mostly Umlaute) #define UML(kc) \ if(record->event.pressed) { \ timer_timeout(); \ -- cgit v1.2.3 From 3c95de3c695135be358800911f4d36767392f010 Mon Sep 17 00:00:00 2001 From: SpacebarRacecar <42380065+SpacebarRacecar@users.noreply.github.com> Date: Thu, 25 Oct 2018 22:08:25 +0200 Subject: Adding a readme to my userspace (#4239) * added userspace readme * small fix to userspace readme * another fix to userspace readme * changed and improved userspace readme * Update readme.md * Update readme.md * changes to readme again * readme again --- users/spacebarracecar/readme.md | 111 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 users/spacebarracecar/readme.md (limited to 'users/spacebarracecar') diff --git a/users/spacebarracecar/readme.md b/users/spacebarracecar/readme.md new file mode 100644 index 0000000000..172764c074 --- /dev/null +++ b/users/spacebarracecar/readme.md @@ -0,0 +1,111 @@ +# SpacebarRacecar Userspace + +The main purpose of this userspace is to keep my personal keymaps clean by moving shared code in here and also allowing me to easily change all my keymaps at once. However it also contains code that might be interesting to QMK Users living in Germany. Most of this code will be explained here. + + +## US Layout Keys for German PCs + +I'm using the US Ansi layout however I'm living in Germany which means that every PC here has its input language set to German. My goal was to create custom keycodes that emulate the US Keys so that I can plug my keyboards into any German PC and have them working without changing any settings. + +### How to use + +- To activate the custom keycodes set GERMAN_ENABLE = yes in the keyboards rules.mk file. +- The keycodes are listed and explained in [spacebarracecar.h](spacebarracecar.h) under `enum userspace_custom_keycodes`. +- The keycodes are handled by the `process_record_user` function which is now located in [spacebarracecar.c](spacebarracecar.c). To change keyboard specific configuration `process_record_keymap` is used (see [drashna userspace readme](../drashna/readme.md) for better explanation). +- There is a predefined `_DEADKEY` layer in [spacebarracecar.h](spacebarracecar.h) under `enum userspace_layers`. Shifted CU_QUOT enables the dead key layer, just like KC_QUOT would when using the US International layout. (See `enum userspace_custom_keycodes` for more explanation). +- On Windows grave and circonflexe are defined as dead keys when using the standard german layout. Those are automatically escaped when using the custom keycodes. `CU_ESCT` can be used to enable/disable this behavior. +- For a complete example see my [fc660c](../../keyboards/fc660c/keymaps/spacebarracecar/keymap.c) or [planck](../../keyboards/planck/keymaps/spacebarracecar/keymap.c) keymaps. + +### How it works + +Creating the custom keycodes was not a trivial task because it is necessary that they are able to send different keycodes depending on the physical shift state. Also the shift state of the actual send keycodes has to be completely independent of the physical shift state. At the same time it has to be ensured that shift never gets stuck or disabled accidentaly. + +(Shift state: If shift keycode is registered; Physical shift state: If shift key is actually pressed) + +Here is an example for a custom *US Equal* keycode that illustrates the problem: + +| Physical Shift State | Custom keycode | Actual send keycodes | +|----------------------|----------------|----------------------| +| Unshifted | = | Shifted DE_0 | +| Shifted | + | Unshifted DE_PLUS | + +#### Tracking the physical shift state + +To track the physical shift state there are two custom left and right shift keycodes `CU_LSFT` and `CU_RSFT`. These track the current physical shift state using two booleans `lshift` and `rshift`. To make things easier both custom shifts use KC_LSFT. A space cadet shift functionality is also included. The preexisting space cadet shift implementation could not be used because it doesn't reset when custom keycodes are pressed and therefore produces unwated parenthesis. + +#### Custom keycode templates + +To ease the creation of custom keycodes there are a few templates defined in [spacebarracecar.h](spacebarracecar.h). + +- `SHIFT_NORM(kc1, kc2)` Sends independent keycodes kc1 and kc2 depending on physical shift state without changing shift state. +- `SHIFT_SWITCH(kc1, kc2)` Sends independent keycodes kc1 and kc2 depending on physical shift state while flipping shift state. +- `SHIFT_ALL(kc1, kc2)` Sends independent keycodes kc1 and kc2 depending on physical shift state while always sending shift. +- `SHIFT_NO(kc1, kc2)` Sends independent keycodes kc1 and kc2 depending on physical shift state while never sending shift. +- `SHIFT_ALGR(kc1, kc2)` Sends independent keycodes kc1 and kc2 depending on physical shift state while never sending shift and always sending ralt. +- `UML(kc)` Sends keycode kc without changing shift state and then escapes the `_DEADKEY` layer. + +Here is `SHIFT_NORM` as an example: +```c +#define SHIFT_NORM(kc1, kc2) \ +if (record->event.pressed) { \ + timer_timeout(); \ + if (lshift || rshift) { \ + register_code(KC_LSFT); \ + unregister_code(kc2); \ + register_code(kc2); \ + add_to_prev(kc2); \ + } else { \ + unregister_code(KC_LSFT); \ + unregister_code(kc1); \ + register_code(kc1); \ + } \ +} else { \ + unregister_code(kc1); \ + unregister_code(kc2); \ +} \ +return false; +``` + +It is noticeable that before registering a keycode the same keycode gets unregistered first. The reason for this is that there can now be two physical keys that use the same keycode only with different shift states. When rolling those two keys the keycode has to be unregistered first, otherwise the second key doesn't register. Also noticable is that sometimes the `add_to_prev` function is called. This will be explained later. The `timer_timeout` function is necessary to reset the timers of the custom space cadet shift functionality. + +It's worth mentioning that `SHIFT_ALGR` unlike the other templates doesn't allow repetition of characters when held. This is because it would otherwise require extensive checking of physical ralt status similar to shift to prevent ralt from getting stuck. + +#### Ensuring that shift state is always correct when pressing normal keycodes + +To ensure that non custom keycodes always get send with the correct shift state the default case in `process_record_user` includes a physical shift check that sets shift accordingly before registering the keycode. Also `timer_timeout` is always called to reset the space cadet shift timers to prevent unwanted parenthesis. + +```c +default: + if(record->event.pressed) { + timer_timeout(); + + #ifdef GERMAN_ENABLE + if (lshift || rshift) + register_code(KC_LSFT); + else + unregister_code(KC_LSFT); + #endif + + } + return process_record_keymap(keycode, record); +``` + +#### Ensuring that custom keycodes always produce the correct character + +When very specific key combinations that include custom keycodes and/or shift are pressed it can happen that wrong characters are produced due to changing shift states. The previously mentioned `add_to_prev` function is there to prevent that. It can be used to add a keycode to the `prev_kcs` array that can hold up to 6 keycodes. On various occasions, but mainly when shift is released `unreg_prev` is called, which then unregisters all saved keycodes. + +For real use this is probably not needed, but it doesn't hurt either. + +#### Adapting the templates for other languages + +In theory the templates can be used to create custom keycodes that map any layout to any other layout. + +## Other stuff + +### Custom Nav/Esc Key + +Since I'm always using a navigation layer with all my keyboards there is a `_NAV` layer predefined in [spacebarracecar.h](spacebarracecar.h) under `enum userspace_layers`. In addition to that I wanted to have a keycode that activates the navigation layer when held, but acts as Escape when pressed. In QMK there already exists `LT(layer, kc)`, however I found that there is some amount of lag before the layer is actived. Therefore I created a custom keycode CU_NAV that does the same without lag using a custom timer. Since I already need timers for the custom space cadet shift implementing this was very easy by adding the timer to the `timer_timeout` function. + +### Gamemode + +The userspace includes the custom keycode `CU_GAME` that is used to flip a boolean variable called `game`. That variable is used to enable/disable windows keys and space cadet shift. In my [planck keymap](../../keyboards/planck/keymaps/spacebarracecar/keymap.c) it also makes Lower act like Space which is more comfortable when resting on wasd and it could also be used to change various other things when gaming. -- cgit v1.2.3 From 667e0962eb8c4e1b3ba111bad57c721c347e754a Mon Sep 17 00:00:00 2001 From: SpacebarRacecar <42380065+SpacebarRacecar@users.noreply.github.com> Date: Sun, 18 Nov 2018 16:52:14 +0100 Subject: Update to my keymaps and userspace (#4447) * fix to prime o keymap * changed ortho keymaps * added some symbols to lower layer * set lower to be a higher layer than raise * added split layout option with center numpad to prime_o keymap * added some gaming functionality * added alt f4 ortho keymaps and userspace * fixed small error --- users/spacebarracecar/spacebarracecar.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'users/spacebarracecar') diff --git a/users/spacebarracecar/spacebarracecar.h b/users/spacebarracecar/spacebarracecar.h index 1e18253510..035c1ac790 100644 --- a/users/spacebarracecar/spacebarracecar.h +++ b/users/spacebarracecar/spacebarracecar.h @@ -81,6 +81,8 @@ bool process_record_keymap(uint16_t keycode, keyrecord_t *record); #define CTRLC LCTL(KC_C) #define CTRLV LCTL(KC_V) +#define ALTF4 LALT(KC_F4) + #define GUIU LGUI(KC_UP) #define GUID LGUI(KC_DOWN) #define GUIL LGUI(KC_LEFT) -- cgit v1.2.3 From e76bf17d36c3e23d4c780ab7dd0a10b5883889a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20=C4=90or=C4=91evi=C4=87?= Date: Thu, 3 Jan 2019 17:13:55 +0100 Subject: Remove redundant, language-specific aliases for KC_ALGR (#4720) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Use standard KC_ALGR, remove language-specific redefinitions * Use ALGR instead of ALTGR in BÉPO and Canadian multilingual keymaps * Remove BE_LALT, BE_LGUI aliases --- users/spacebarracecar/spacebarracecar.c | 4 ++-- users/spacebarracecar/spacebarracecar.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'users/spacebarracecar') diff --git a/users/spacebarracecar/spacebarracecar.c b/users/spacebarracecar/spacebarracecar.c index f7048869ed..130d7dc2d4 100644 --- a/users/spacebarracecar/spacebarracecar.c +++ b/users/spacebarracecar/spacebarracecar.c @@ -211,11 +211,11 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { timer_timeout(); if (lshift || rshift){ unregister_code(KC_LSFT); - register_code(DE_ALGR); + register_code(KC_ALGR); unregister_code(DE_PLUS); register_code(DE_PLUS); unregister_code(DE_PLUS); - unregister_code(DE_ALGR); + unregister_code(KC_ALGR); register_code(KC_LSFT); } else { register_code(KC_LSFT); diff --git a/users/spacebarracecar/spacebarracecar.h b/users/spacebarracecar/spacebarracecar.h index 035c1ac790..d0259b73cc 100644 --- a/users/spacebarracecar/spacebarracecar.h +++ b/users/spacebarracecar/spacebarracecar.h @@ -192,7 +192,7 @@ return false; if (record->event.pressed) { \ timer_timeout(); \ unregister_code(KC_LSFT); \ - register_code(DE_ALGR); \ + register_code(KC_ALGR); \ if (lshift || rshift) { \ unregister_code(kc2); \ register_code(kc2); \ @@ -203,7 +203,7 @@ if (record->event.pressed) { \ register_code(kc1); \ unregister_code(kc1); \ } \ - unregister_code(DE_ALGR); \ + unregister_code(KC_ALGR); \ } \ return false; -- cgit v1.2.3