summaryrefslogtreecommitdiff
path: root/users/haervig
diff options
context:
space:
mode:
authorJakob Hærvig <10219471+jakobhaervig@users.noreply.github.com>2021-07-01 19:12:19 +0200
committerGitHub <noreply@github.com>2021-07-01 10:12:19 -0700
commitbef73f44aacf49d0969e3cdd6718b9a594d49066 (patch)
treea1a01e738dd1d7e9ad33224aa1d075e79c962ada /users/haervig
parentc275828ac20f55a42ca1d1546c330501c00839ab (diff)
downloadqmk_firmware-bef73f44aacf49d0969e3cdd6718b9a594d49066.tar.gz
qmk_firmware-bef73f44aacf49d0969e3cdd6718b9a594d49066.zip
[Keymap] Add haervig userspace and keymaps (#13362)
Diffstat (limited to 'users/haervig')
-rw-r--r--users/haervig/config.h19
-rw-r--r--users/haervig/haervig.c234
-rw-r--r--users/haervig/haervig.h297
-rw-r--r--users/haervig/readme.md11
-rw-r--r--users/haervig/rules.mk5
5 files changed, 566 insertions, 0 deletions
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 <jakob.haervig@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+#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 <jakob.haervig@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "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; i<prev_indx; i++){
+ if (kc == prev_kcs[i])
+ return;
+ }
+ if (prev_indx == 6){
+ for (int i=5; i>0; 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; i<prev_indx; i++){
+ unregister_code(prev_kcs[i]);
+ }
+ prev_indx = 0;
+}
+#endif
+
+// Interrupt and times for Nav/Esc
+bool navesc = false;
+uint16_t navesc_timer = 0;
+
+// Interrupts all timers
+void timer_timeout(void){
+ #ifdef DANISH_ENABLE
+ lshiftp = false;
+ rshiftp = false;
+ #endif
+ navesc = false;
+ timer_timeout_keymap();
+}
+
+__attribute__((weak))
+void timer_timeout_keymap(void){
+}
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case KC_LGUI:
+ case KC_RGUI:
+ if (record->event.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 <jakob.haervig@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "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