#include "ericgebhart.h"
#include "quantum.h"
#include "version.h"
#include "action.h"
#include "action_layer.h"
#include "process_keycode/process_tap_dance.h"
#include "keymap_bepo.h"
float tone_copy[][2] = SONG(SCROLL_LOCK_ON_SOUND);
float tone_paste[][2] = SONG(SCROLL_LOCK_OFF_SOUND);
static uint16_t copy_paste_timer;
userspace_config_t userspace_config;
void tap(uint16_t keycode){ register_code(keycode); unregister_code(keycode); };
__attribute__ ((weak))
void matrix_init_keymap(void) {}
__attribute__ ((weak))
void matrix_scan_keymap(void) {}
__attribute__ ((weak))
bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
return true;
}
__attribute__ ((weak))
bool process_record_secrets(uint16_t keycode, keyrecord_t *record) {
return true;
}
__attribute__ ((weak))
uint32_t layer_state_set_keymap (uint32_t state) {
return state;
}
__attribute__ ((weak))
void led_set_keymap(uint8_t usb_led) {}
static void switch_default_layer(uint8_t layer) {
default_layer_set(1UL<<layer);
clear_keyboard();
}
const uint8_t key_translations[][2][2] = {
[GR(DB_1)] = {{BP_DQOT, MOD_LSFT}, {BP_DCRC, MOD_LSFT}},
[GR(DB_2)] = {{BP_LGIL, MOD_LSFT}, {BP_AT, MOD_NONE}},
[GR(DB_3)] = {{BP_RGIL, MOD_LSFT}, {BP_DLR, MOD_LSFT}},
[GR(DB_4)] = {{BP_LPRN, MOD_LSFT}, {BP_DLR, MOD_NONE}},
[GR(DB_5)] = {{BP_RPRN, MOD_LSFT}, {BP_PERC, MOD_NONE}},
[GR(DB_6)] = {{BP_AT, MOD_LSFT}, {BP_AT, MOD_BIT(KC_RALT)}},
[GR(DB_7)] = {{BP_PLUS, MOD_LSFT}, {BP_P, MOD_BIT(KC_RALT)}},
[GR(DB_8)] = {{BP_MINS, MOD_LSFT}, {BP_ASTR, MOD_NONE}},
[GR(DB_9)] = {{BP_SLASH, MOD_LSFT}, {BP_LPRN, MOD_NONE}},
[GR(DB_0)] = {{BP_ASTR, MOD_LSFT}, {BP_RPRN, MOD_NONE}},
[GR(DB_GRV)] = {{BP_PERC, MOD_LSFT}, {BP_K, MOD_BIT(KC_RALT)}},
[GR(DB_SCOLON)] = {{BP_COMM, MOD_LSFT}, {BP_DOT, MOD_LSFT}},
[GR(DB_SLASH)] = {{BP_SLASH, MOD_NONE}, {BP_APOS, MOD_LSFT}},
[GR(DB_BACKSLASH)] = {{BP_AGRV, MOD_BIT(KC_RALT)}, {BP_B, MOD_BIT(KC_RALT)}},
[GR(DB_EQL)] = {{BP_EQL, MOD_NONE}, {BP_PLUS, MOD_NONE}},
[GR(DB_COMM)] = {{BP_COMMA, MOD_NONE}, {BP_LGIL, MOD_BIT(KC_RALT)}},
[GR(DB_DOT)] = {{BP_DOT, MOD_NONE}, {BP_RGIL, MOD_BIT(KC_RALT)}},
[GR(DB_QUOT)] = {{BP_APOS, MOD_NONE}, {BP_DQOT, MOD_NONE}},
[GR(DB_MINUS)] = {{BP_MINUS, MOD_NONE}, {KC_SPC, MOD_BIT(KC_RALT)}},
[GR(DB_LPRN)] = {{BP_LPRN, MOD_NONE}, {BP_LPRN, MOD_BIT(KC_RALT)}},
[GR(DB_RPRN)] = {{BP_RPRN, MOD_NONE}, {BP_RPRN, MOD_BIT(KC_RALT)}},
[GR(DB_LBRC)] = {{BP_Y, MOD_BIT(KC_RALT)}, {BP_LPRN, MOD_BIT(KC_RALT)}},
[GR(DB_RBRC)] = {{BP_X, MOD_BIT(KC_RALT)}, {BP_RPRN, MOD_BIT(KC_RALT)}},
[GR(DB_HASH)] = {{BP_DLR, MOD_LSFT}, {BP_DLR, MOD_LSFT}},
[GR(DB_LCBR)] = {{BP_LPRN, MOD_BIT(KC_RALT)}, {BP_LPRN, MOD_BIT(KC_RALT)}},
[GR(DB_RCBR)] = {{BP_LPRN, MOD_BIT(KC_RALT)}, {BP_RPRN, MOD_BIT(KC_RALT)}},
[GR(DB_PIPE)] = {{BP_B, MOD_BIT(KC_RALT)}, {BP_B, MOD_BIT(KC_RALT)}},
[GR(DB_TILD)] = {{BP_K, MOD_BIT(KC_RALT)}, {BP_K, MOD_BIT(KC_RALT)}},
[GR(DB_CIRC)] = {{BP_AT, MOD_BIT(KC_RALT)}, {BP_AT, MOD_BIT(KC_RALT)}},
[GR(DB_LESS)] = {{BP_LGIL, MOD_BIT(KC_RALT)}, {BP_LGIL, MOD_BIT(KC_RALT)}},
[GR(DB_GRTR)] = {{BP_RGIL, MOD_BIT(KC_RALT)}, {BP_RGIL, MOD_BIT(KC_RALT)}},
};
uint8_t gr(uint8_t kc){
return (kc - SAFE_RANGE);
}
void send_keycode(uint8_t kc){
uint8_t tmp_mods = get_mods();
bool is_shifted = ( tmp_mods & (MOD_BIT(KC_LSFT)|MOD_BIT(KC_RSFT)) );
unregister_mods((MOD_BIT(KC_LSFT)|MOD_BIT(KC_RSFT)));
if(is_shifted){
register_mods(SHIFTED_MODS(kc));
register_code(SHIFTED_KEY(kc));
unregister_code(SHIFTED_KEY(kc));
unregister_mods(SHIFTED_MODS(kc));
} else{
register_mods(UNSHIFTED_MODS(kc));
register_code(UNSHIFTED_KEY(kc));
unregister_code(UNSHIFTED_KEY(kc));
unregister_mods(UNSHIFTED_MODS(kc));
}
clear_mods();
register_mods(tmp_mods);
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
#ifdef KEYLOGGER_ENABLE
xprintf("KL: row: %u, column: %u, pressed: %u\n", record->event.key.col, record->event.key.row, record->event.pressed);
#endif
switch (keycode) {
case DB_1:
case DB_2:
case DB_3:
case DB_4:
case DB_5:
case DB_6:
case DB_7:
case DB_8:
case DB_9:
case DB_0:
case DB_GRV:
case DB_SCOLON:
case DB_SLASH:
case DB_BACKSLASH:
case DB_EQL:
case DB_DOT:
case DB_COMM:
case DB_QUOT:
case DB_MINUS:
case DB_LPRN:
case DB_RPRN:
case DB_LBRC:
case DB_RBRC:
if(record->event.pressed)
send_keycode(keycode);
unregister_code(keycode);
break;
case KC_QWERTY:
if (record->event.pressed) {
set_single_persistent_default_layer(QWERTY);
}
return false;
break;
case KC_COLEMAK:
if (record->event.pressed) {
set_single_persistent_default_layer(COLEMAK);
}
return false;
break;
case KC_DVORAK:
if (record->event.pressed) {
set_single_persistent_default_layer(DVORAK);
}
return false;
break;
case KC_WORKMAN:
if (record->event.pressed) {
set_single_persistent_default_layer(WORKMAN);
}
return false;
break;
case KC_MAKE: if (!record->event.pressed) {
SEND_STRING("make " QMK_KEYBOARD ":" QMK_KEYMAP
#if (defined(BOOTLOADER_DFU) || defined(BOOTLOADER_LUFA_DFU) || defined(BOOTLOADER_QMK_DFU))
":dfu"
#elif defined(BOOTLOADER_HALFKAY)
":teensy"
#elif defined(BOOTLOADER_CATERINA)
":avrdude"
#endif SS_TAP(X_ENTER));
}
return false;
break;
case KC_RESET: if (!record->event.pressed) {
reset_keyboard();
}
return false;
break;
case EPRM: if (record->event.pressed) {
eeconfig_init();
default_layer_set(1UL<<eeconfig_read_default_layer());
layer_state_set(layer_state);
}
return false;
break;
case VRSN: if (record->event.pressed) {
SEND_STRING(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION ", Built on: " QMK_BUILDDATE);
}
return false;
break;
#ifdef MACROS_ENABLED
case KC_OVERWATCH: if (record->event.pressed) { userspace_config.is_overwatch ^= 1; eeprom_update_byte(EECONFIG_USER, userspace_config.raw); }
return false; break;
#endif
case KC_CCCV: if(record->event.pressed){
copy_paste_timer = timer_read();
} else {
if (timer_elapsed(copy_paste_timer) > TAPPING_TERM) { register_code(KC_LCTL);
tap(KC_C);
unregister_code(KC_LCTL);
#ifdef AUDIO_ENABLE
PLAY_SONG(tone_copy);
#endif
} else { register_code(KC_LCTL);
tap(KC_V);
unregister_code(KC_LCTL);
#ifdef AUDIO_ENABLE
PLAY_SONG(tone_paste);
#endif
}
}
return false;
break;
case CLICKY_TOGGLE:
#ifdef AUDIO_CLICKY
userspace_config.clicky_enable = clicky_enable;
eeprom_update_byte(EECONFIG_USER, userspace_config.raw);
#endif
break;
#ifdef UNICODE_ENABLE
case UC_FLIP: if (record->event.pressed) {
register_code(KC_RSFT);
tap(KC_9);
unregister_code(KC_RSFT);
process_unicode((0x256F | QK_UNICODE), record); process_unicode((0x00B0 | QK_UNICODE), record); process_unicode((0x25A1 | QK_UNICODE), record); process_unicode((0x00B0 | QK_UNICODE), record); register_code(KC_RSFT);
tap(KC_0);
unregister_code(KC_RSFT);
process_unicode((0x256F | QK_UNICODE), record); tap(KC_SPC);
process_unicode((0x0361 | QK_UNICODE), record); tap(KC_SPC);
process_unicode((0x253B | QK_UNICODE), record); process_unicode((0x2501 | QK_UNICODE), record); process_unicode((0x253B | QK_UNICODE), record); }
return false;
break;
#endif
}
return true;
}
void tap_dance_mouse_btns (qk_tap_dance_state_t *state, void *user_data) {
switch(state->count){
case 1:
register_code(KC_BTN1);
break;
case 2:
register_code(KC_BTN2);
break;
case 3:
register_code(KC_BTN3);
break;
case 4:
register_code(KC_BTN4);
break;
case 5:
register_code(KC_BTN5);
break;
default:
break;
}
reset_tap_dance(state);
}
int on_qwerty(){
uint8_t deflayer = (biton32(default_layer_state));
return (deflayer < DVORAK_ON_BEPO);
}
void tap_dance_df_bepo_layers_switch (qk_tap_dance_state_t *state, void *user_data) {
switch(state->count){
case 1:
switch_default_layer(DVORAK_ON_BEPO);
break;
case 2:
switch_default_layer(BEPO);
break;
case 3:
layer_invert(LAYERS);
break;
default:
break;
}
reset_tap_dance(state);
}
void tap_dance_layer_switch (qk_tap_dance_state_t *state, void *user_data) {
switch(state->count){
case 1:
if(on_qwerty())
layer_invert(SYMB);
else
layer_invert(SYMB_ON_BEPO);
break;
case 2:
layer_invert(MDIA);
break;
case 3:
layer_invert(LAYERS);
break;
case 4:
if(on_qwerty())
layer_invert(KEYPAD);
else
layer_invert(KEYPAD_ON_BEPO);
break;
default:
break;
}
reset_tap_dance(state);
}
void tap_dance_default_layer_switch (qk_tap_dance_state_t *state, void *user_data) {
switch(state->count){
case 1:
switch_default_layer(DVORAK);
break;
case 2:
switch_default_layer(DVORAK_ON_BEPO);
break;
case 3:
switch_default_layer(BEPO);
break;
default:
break;
}
reset_tap_dance(state);
}
void switch_default_layer_on_qwerty(int count) {
switch(count){
case 1:
switch_default_layer(DVORAK);
break;
case 2:
switch_default_layer(QWERTY);
break;
case 3:
switch_default_layer(COLEMAK);
break;
case 4:
switch_default_layer(WORKMAN);
break;
case 5:
switch_default_layer(NORMAN);
break;
default:
switch_default_layer(DVORAK);
break;
}
}
void switch_default_layer_on_bepo(int count) {
switch(count){
case 1:
switch_default_layer(DVORAK_ON_BEPO);
break;
case 2:
switch_default_layer(BEPO);
break;
default:
switch_default_layer(DVORAK_ON_BEPO);
break;
}
}
void tap_dance_default_os_layer_switch (qk_tap_dance_state_t *state, void *user_data) {
bool shifted = ( keyboard_report->mods & (MOD_BIT(KC_LSFT)|MOD_BIT(KC_RSFT)) );
int qwerty = on_qwerty();
if(shifted){
if (qwerty)
switch_default_layer_on_bepo(state->count);
else
switch_default_layer_on_qwerty(state->count);
} else {
if (qwerty)
switch_default_layer_on_qwerty(state->count);
else
switch_default_layer_on_bepo(state->count);
}
reset_tap_dance(state);
}
int cur_dance (qk_tap_dance_state_t *state) {
if (state->count == 1) {
if (state->interrupted || !state->pressed) return SINGLE_TAP;
else return SINGLE_HOLD;
}
else if (state->count == 2) {
if (state->interrupted) return DOUBLE_SINGLE_TAP;
else if (state->pressed) return DOUBLE_HOLD;
else return DOUBLE_TAP;
}
if (state->count == 3) {
if (state->interrupted || !state->pressed) return TRIPLE_TAP;
else return TRIPLE_HOLD;
}
else return 8; }
static tdtap xtap_state = {
.is_press_action = true,
.state = 0
};
int get_xmonad_layer(){
int qwerty = on_qwerty();
if (qwerty)
return(XMONAD);
else
return(XMONAD_FR);
}
void x_finished (qk_tap_dance_state_t *state, void *user_data) {
int xmonad_layer = get_xmonad_layer();
xtap_state.state = cur_dance(state);
switch (xtap_state.state) {
case SINGLE_TAP:
register_code(KC_ESC);
break;
case SINGLE_HOLD:
layer_on(xmonad_layer);
set_oneshot_mods (MOD_LGUI);
break;
case DOUBLE_TAP:
set_oneshot_mods ((MOD_LCTL | MOD_LGUI));
layer_on (xmonad_layer);
set_oneshot_layer (xmonad_layer, ONESHOT_START);
break;
case DOUBLE_HOLD:
set_oneshot_mods (MOD_LSFT | MOD_LGUI);
if (xmonad_layer != -1)
layer_on(xmonad_layer);
break;
case DOUBLE_SINGLE_TAP:
register_code(KC_ESC);
unregister_code(KC_ESC);
register_code(KC_ESC);
}
}
void x_reset (qk_tap_dance_state_t *state, void *user_data) {
int xmonad_layer = get_xmonad_layer();
switch (xtap_state.state) {
case SINGLE_TAP:
unregister_code(KC_ESC);
break;
case SINGLE_HOLD:
layer_off(xmonad_layer);
break;
case DOUBLE_TAP:
set_oneshot_layer (xmonad_layer, ONESHOT_PRESSED);
break;
case DOUBLE_HOLD:
layer_off(xmonad_layer);
break;
case DOUBLE_SINGLE_TAP:
unregister_code(KC_ESC);
}
xtap_state.state = 0;
}
qk_tap_dance_action_t tap_dance_actions[] = {
[TD_ESC_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_CAPS),
[TD_TAB_BKTAB] = ACTION_TAP_DANCE_DOUBLE(KC_TAB, LSFT(KC_TAB)),
[TD_MDIA_SYMB] = ACTION_TAP_DANCE_FN(tap_dance_layer_switch),
[TD_DVORAK_BEPO] = ACTION_TAP_DANCE_FN(tap_dance_df_bepo_layers_switch),
[TD_DEF_LAYER_SW] = ACTION_TAP_DANCE_FN(tap_dance_default_layer_switch),
[TD_DEF_OS_LAYER_SW] = ACTION_TAP_DANCE_FN(tap_dance_default_os_layer_switch),
[TD_HOME_END] = ACTION_TAP_DANCE_DOUBLE(KC_HOME, KC_END),
[TD_XMONAD_ESC] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, x_finished, x_reset),
[TD_MOUSE_BTNS] = ACTION_TAP_DANCE_FN(tap_dance_mouse_btns)
};