From bef73f44aacf49d0969e3cdd6718b9a594d49066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20H=C3=A6rvig?= <10219471+jakobhaervig@users.noreply.github.com> Date: Thu, 1 Jul 2021 19:12:19 +0200 Subject: [PATCH] [Keymap] Add haervig userspace and keymaps (#13362) --- .../dztech/dz65rgb/keymaps/haervig/keymap.c | 36 +++ .../dztech/dz65rgb/keymaps/haervig/rules.mk | 3 + users/haervig/config.h | 19 ++ users/haervig/haervig.c | 234 ++++++++++++++ users/haervig/haervig.h | 297 ++++++++++++++++++ users/haervig/readme.md | 11 + users/haervig/rules.mk | 5 + 7 files changed, 605 insertions(+) create mode 100644 keyboards/dztech/dz65rgb/keymaps/haervig/keymap.c create mode 100644 keyboards/dztech/dz65rgb/keymaps/haervig/rules.mk create mode 100644 users/haervig/config.h create mode 100644 users/haervig/haervig.c create mode 100644 users/haervig/haervig.h create mode 100644 users/haervig/readme.md create mode 100644 users/haervig/rules.mk diff --git a/keyboards/dztech/dz65rgb/keymaps/haervig/keymap.c b/keyboards/dztech/dz65rgb/keymaps/haervig/keymap.c new file mode 100644 index 0000000000..6784c14f00 --- /dev/null +++ b/keyboards/dztech/dz65rgb/keymaps/haervig/keymap.c @@ -0,0 +1,36 @@ +/* +Copyright 2021 Jakob Hærvig + +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 . +*/ + +#include QMK_KEYBOARD_H +#include "haervig.h" + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_65_ansi( + KC_GESC, DK_1, CU_2, DK_3, CU_4, DK_5, CU_6, CU_7, CU_8, CU_9, CU_0, CU_MINS, CU_EQL, CU_BSPC, KC_HOME, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, CU_LBRC, CU_RBRC, CU_BSLS, KC_PGUP, + CTL_T(KC_CAPS), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, CU_SCLN, CU_QUOT, KC_ENT, KC_PGDN, + CU_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, CU_COMM, CU_DOT, CU_SLSH, CU_RSFT, KC_UP, KC_END, + KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, MO(1), KC_RALT, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT + ), + [1] = LAYOUT_65_ansi( + _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ) +}; diff --git a/keyboards/dztech/dz65rgb/keymaps/haervig/rules.mk b/keyboards/dztech/dz65rgb/keymaps/haervig/rules.mk new file mode 100644 index 0000000000..676050bfce --- /dev/null +++ b/keyboards/dztech/dz65rgb/keymaps/haervig/rules.mk @@ -0,0 +1,3 @@ +# Userspace defines +DANISH_ENABLE = yes # Enable Custom US Ansi Keycodes for PC with Danish set as input language +RGB_MATRIX_ENABLE = no # Disable the ugly RGB light \ No newline at end of file diff --git a/users/haervig/config.h b/users/haervig/config.h new file mode 100644 index 0000000000..6a7d67737e --- /dev/null +++ b/users/haervig/config.h @@ -0,0 +1,19 @@ +/* +Copyright 2021 Jakob Hærvig + +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 . +*/ + +#pragma once +#define TAPPING_TERM 200 diff --git a/users/haervig/haervig.c b/users/haervig/haervig.c new file mode 100644 index 0000000000..d03b43edc1 --- /dev/null +++ b/users/haervig/haervig.c @@ -0,0 +1,234 @@ +/* +Copyright 2021 Jakob Hærvig + +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 . +*/ + +#include "haervig.h" + +#ifdef DANISH_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; i0; i--){ + prev_kcs[i] = prev_kcs[i-1]; + } + prev_kcs[0] = kc; + } else { + prev_kcs[prev_indx] = kc; + prev_indx++; + } +} + +/* +Unregisters all codes saved in prev_kcs and resets prev_indx. +gets called on multiple occasions mainly when shift is released +and when frankenkeycodes are pressed. Prevents output of +wrong characters when really specific key combinations +that would never occur during normal usage are pressed. +*/ +void unreg_prev(void){ + if (prev_indx == 0) + return; + for (int i=0; ievent.pressed) + timer_timeout(); + return true; + case CU_NAV: + if(record->event.pressed) { + navesc = true; + navesc_timer = timer_read(); + layer_on(_NAV); + } else { + if (timer_elapsed(navesc_timer) < TAPPING_TERM && navesc) { + tap_code(KC_ESC); + } + layer_off(_NAV); + } + return false; + + #ifdef DANISH_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) < TAPPING_TERM && lshiftp) { + register_code(KC_LSFT); + tap_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) < TAPPING_TERM && rshiftp) { + register_code(KC_LSFT); + tap_code(KC_9); + unregister_code(KC_LSFT); + } + unreg_prev(); + if (!lshift) + unregister_code(KC_LSFT); + rshift = false; + } + return false; + case CU_COMM: + SHIFT_NO(DK_COMM, KC_GRV) + case CU_DOT: + SHIFT_NORM(DK_DOT, KC_GRV) + case CU_SLSH: + SHIFT_ALL(DK_7, KC_MINS) + case CU_SCLN: + SHIFT_ALL(DK_COMM, DK_DOT) + case CU_QUOT: + SHIFT_NORM(DK_QUOT, DK_2) + case CU_2: + NORM_ALGR(DK_2, KC_NUHS) + case CU_4: + if (record->event.pressed) { \ + timer_timeout(); \ + if (lshift || rshift) { \ + register_code(KC_LSFT); \ + register_code(KC_ALGR); \ + unregister_code(KC_3); \ + tap_code(KC_3); \ + unregister_code(KC_3); \ + } else { \ + unregister_code(KC_4); \ + tap_code(KC_4); \ + } \ + unregister_code(KC_ALGR); \ + unregister_code(KC_LSFT); \ + } \ + return false; + case CU_6: + SHIFT_NORM(DK_6, KC_RBRC) + case CU_7: + SHIFT_NORM(DK_7, DK_6) + case CU_8: + SHIFT_NORM(DK_8, KC_NUHS) + case CU_9: + SHIFT_NORM(DK_9, DK_8) + case CU_0: + SHIFT_NORM(DK_0, DK_9) + case CU_MINS: + SHIFT_NORM(KC_SLSH, KC_SLSH) + case CU_EQL: + SHIFT_SWITCH(DK_0, DK_PLUS) + case CU_BSPC: + SHIFT_NO(KC_BSPC, KC_DEL) + case CU_LBRC: + NORM_ALGRSHIFT(DK_8, DK_8) + case CU_RBRC: + NORM_ALGRSHIFT(DK_9, DK_9) + case CU_BSLS: + ALGR_SWITCH(DK_7, DK_I) + case KC_LCTL: + case KC_RCTL: + if(!record->event.pressed) { + timer_timeout(); + unregister_code(KC_Z); + unregister_code(KC_Y); + } + return true; + #endif + + default: + if(record->event.pressed) { + timer_timeout(); + + #ifdef DANISH_ENABLE + if (lshift || rshift) + register_code(KC_LSFT); + else + unregister_code(KC_LSFT); + #endif + + } + return process_record_keymap(keycode, record); + } +} + +__attribute__((weak)) +bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { + return true; +} diff --git a/users/haervig/haervig.h b/users/haervig/haervig.h new file mode 100644 index 0000000000..e0d47e4cc9 --- /dev/null +++ b/users/haervig/haervig.h @@ -0,0 +1,297 @@ +/* +Copyright 2021 Jakob Hærvig + +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 . +*/ + +#include "quantum.h" +#include "keymap_danish.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 = SAFE_RANGE, // NAV | ESC + + #ifdef DANISH_ENABLE + CU_LSFT, // LSFT | ( + CU_RSFT, // LSFT | ) + CU_COMM, // , | < + CU_DOT, // . | > + CU_SLSH, // / | ? + CU_SCLN, // ; | : + CU_QUOT, // ' | " + CU_2, // 2 | @ + CU_4, // 4 | $ + CU_6, // 6 | ^ + CU_7, // 7 | & + CU_8, // 8 | * + CU_9, // 9 | ( + CU_0, // 0 | ) + CU_MINS, // - | _ + CU_EQL, // = | + + CU_BSPC, // backspace | delete + CU_LBRC, // [ | { + CU_RBRC, // ] | } + CU_BSLS, // \ | | + #endif + + NEW_SAFE_RANGE // Use for keymap specific keycodes +}; + +#ifdef DANISH_ENABLE +extern bool lshift; +extern bool rshift; +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 + +extern bool navesc; +extern uint16_t navesc_timer; + +void timer_timeout(void); + +void timer_timeout_keymap(void); + +bool process_record_keymap(uint16_t keycode, keyrecord_t *record); + +#define CTRLX LCTL(KC_X) +#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) +#define GUIR RGUI(KC_RIGHT) + +#define CTLENT CTL_T(KC_ENT) + +#define EMOJI LWIN(KC_DOT) + +/* +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; + +// Always shifted +#define SHIFT_ALL(kc1, kc2) \ +if (record->event.pressed) { \ + timer_timeout(); \ + register_code(KC_LSFT); \ + if (lshift || rshift) { \ + tap_code(kc2); \ + add_to_prev(kc2); \ + } else { \ + tap_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; + +// Never shifted +#define SHIFT_NO(kc1, kc2) \ +if (record->event.pressed) { \ + timer_timeout(); \ + unregister_code(KC_LSFT); \ + if (lshift || rshift) { \ + tap_code(kc2); \ + add_to_prev(kc2); \ + } else { \ + tap_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; + +// Norm AltGr +#define NORM_ALGR(kc1, kc2) \ +if (record->event.pressed) { \ + timer_timeout(); \ + if (lshift || rshift) { \ + register_code(KC_ALGR); \ + unregister_code(KC_LSFT); \ + tap_code(kc2); \ + unregister_code(KC_ALGR); \ + } else { \ + unregister_code(KC_ALGR); \ + unregister_code(KC_LSFT); \ + tap_code(kc1); \ + } \ +} else { \ + unregister_code(kc1); \ + unregister_code(kc2); \ +} \ +return false; + +// Norm AltGr shift +#define NORM_ALGRSHIFT(kc1, kc2) \ +if (record->event.pressed) { \ + timer_timeout(); \ + register_code(KC_LSFT); \ + register_code(KC_ALGR); \ + if (lshift || rshift) { \ + unregister_code(kc2); \ + tap_code(kc2); \ + unregister_code(KC_LSFT); \ + } else { \ + unregister_code(KC_LSFT); \ + unregister_code(kc1); \ + register_code(kc1); \ + } \ + unregister_code(KC_ALGR); \ +} else { \ + unregister_code(kc1); \ + unregister_code(kc2); \ +} \ +return false; + +// Inverted altgr status +#define ALGR_SWITCH(kc1, kc2) \ +if (record->event.pressed) { \ + timer_timeout(); \ + register_code(KC_ALGR); \ + if (lshift || rshift) { \ + unregister_code(KC_LSFT); \ + unregister_code(kc2); \ + register_code(kc2); \ + unregister_code(KC_ALGR); \ + add_to_prev(kc2); \ + } else { \ + register_code(KC_LSFT); \ + unregister_code(kc1); \ + register_code(kc1); \ + unregister_code(KC_ALGR); \ + 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; + +// Always AltGr +#define SHIFT_ALGR(kc1, kc2) \ +if (record->event.pressed) { \ + timer_timeout(); \ + unregister_code(KC_LSFT); \ + register_code(KC_ALGR); \ + if (lshift || rshift) { \ + unregister_code(kc2); \ + tap_code(kc2); \ + register_code(KC_LSFT); \ + } else { \ + unregister_code(kc1); \ + tap_code(kc1); \ + } \ + unregister_code(KC_ALGR); \ +} \ +return false; + +// Different keycode when Ctrl is pressed +#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; diff --git a/users/haervig/readme.md b/users/haervig/readme.md new file mode 100644 index 0000000000..dc2ebbd13c --- /dev/null +++ b/users/haervig/readme.md @@ -0,0 +1,11 @@ +# haervig Userspace + +This userspace keeps my userdefined codes. I work on a ANSI keyboard on a Danish macOS system. I believe this code might be relevant for similar users. A big shout out to user spacebarracecar for the ideas on how to map keys, which served as the basis of this code. + +## US Layout Keys for Danish PCs + +By daily work involves a lot of coding. I find an ANSI layout superior and decided to buy a QMK keyboard. However, all PC's here in Denmark are set to input language Danish. Even though I could simply set input language language to US international, I find this inconvenient. I instead decided to map my keys so the ANSI keyboard would will function as expected when the OS inputn language is Danish. + +## More details + +Tracking the current state of the shift code is nessesary for it to work. User spacebarracecar has documented the idea thoroughly and should serve you as a starting point if you wish to implement this code. I modified the code to suit Danish input language. Additionally, a couple of functions were added to accomodate the altgr key. \ No newline at end of file diff --git a/users/haervig/rules.mk b/users/haervig/rules.mk new file mode 100644 index 0000000000..e06647ff27 --- /dev/null +++ b/users/haervig/rules.mk @@ -0,0 +1,5 @@ +SRC += haervig.c + +ifeq ($(strip $(DANISH_ENABLE)), yes) + OPT_DEFS += -DDANISH_ENABLE +endif