235 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			235 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
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;
 | 
						|
}
 |