aboutsummaryrefslogtreecommitdiff
path: root/users/ericgebhart/ericgebhart.c
diff options
context:
space:
mode:
authorEric Gebhart <e.a.gebhart@gmail.com>2018-06-08 19:06:25 +0200
committerDrashna Jaelre <drashna@live.com>2018-06-08 10:06:25 -0700
commit984621835d929b79a22ef33c0a4e602adb1ecc5b (patch)
tree11637c54105b229f3127b019ff0cc962926fb770 /users/ericgebhart/ericgebhart.c
parent03c9deb7456d84a8d8cc31496ae2736305bbafd3 (diff)
downloadqmk_firmware-984621835d929b79a22ef33c0a4e602adb1ecc5b.tar.gz
qmk_firmware-984621835d929b79a22ef33c0a4e602adb1ecc5b.zip
Keyboard that works on Qwerty or Bepo OS keyboards. (#3149)
* New layout. * new dvorak bepo layout. * first commit of new ergodox_ez dvorak keyboard for qwerty and bepo.
Diffstat (limited to 'users/ericgebhart/ericgebhart.c')
-rw-r--r--users/ericgebhart/ericgebhart.c637
1 files changed, 637 insertions, 0 deletions
diff --git a/users/ericgebhart/ericgebhart.c b/users/ericgebhart/ericgebhart.c
new file mode 100644
index 000000000..69aa450e0
--- /dev/null
+++ b/users/ericgebhart/ericgebhart.c
@@ -0,0 +1,637 @@
1/*
2 Copyright 2018 Eric Gebhart <e.a.gebhart@gmail.com>
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17#include "ericgebhart.h"
18
19#include "quantum.h"
20#include "version.h"
21#include "action.h"
22#include "action_layer.h"
23#include "process_keycode/process_tap_dance.h"
24#include "keymap_bepo.h"
25
26float tone_copy[][2] = SONG(SCROLL_LOCK_ON_SOUND);
27float tone_paste[][2] = SONG(SCROLL_LOCK_OFF_SOUND);
28
29static uint16_t copy_paste_timer;
30userspace_config_t userspace_config;
31
32void tap(uint16_t keycode){ register_code(keycode); unregister_code(keycode); };
33
34
35// Add reconfigurable functions here, for keymap customization
36// This allows for a global, userspace functions, and continued
37// customization of the keymap. Use _keymap instead of _user
38// functions in the keymaps
39__attribute__ ((weak))
40void matrix_init_keymap(void) {}
41
42__attribute__ ((weak))
43void matrix_scan_keymap(void) {}
44
45__attribute__ ((weak))
46bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
47 return true;
48}
49
50__attribute__ ((weak))
51bool process_record_secrets(uint16_t keycode, keyrecord_t *record) {
52 return true;
53}
54
55__attribute__ ((weak))
56uint32_t layer_state_set_keymap (uint32_t state) {
57 return state;
58}
59
60__attribute__ ((weak))
61void led_set_keymap(uint8_t usb_led) {}
62
63// Runs just one time when the keyboard initializes.
64void matrix_init_user(void) {
65 //ACTION_DEFAULT_LAYER_SET(DVORAK) ;
66}
67
68// check default layerstate to see which layer we are on.
69// if (biton32(layer_state) == _DIABLO) { --- current layer
70// if (biton32(default_layer_state) == _DIABLO) { --- current default layer
71// check for left shift on.
72// if (mods & MOD_BIT(KC_LSFT)) register_code(KC_LSFT);
73
74static void switch_default_layer(uint8_t layer) {
75 default_layer_set(1UL<<layer);
76 clear_keyboard();
77}
78
79// so the keyboard remembers which layer it's in after power disconnect.
80/*
81 uint32_t default_layer_state_set_kb(uint32_t state) {
82 eeconfig_update_default_layer(state);
83 return state;
84 }
85*/
86
87// These are the keys for dvorak on bepo. column one is the keycode and mods for
88// the unshifted key, the second column is the keycode and mods for the shifted key.
89// GR is Good Range. It subtracts SAFE_RANGE from the keycode so we can make a
90// reasnably sized array without difficulties. The macro is for the constant declarations
91// the function is for when we use it.
92const uint8_t key_translations[][2][2] = {
93 [GR(DB_1)] = {{BP_DQOT, MOD_LSFT}, {BP_DCRC, MOD_LSFT}},
94 [GR(DB_2)] = {{BP_LGIL, MOD_LSFT}, {BP_AT, MOD_NONE}},
95 [GR(DB_3)] = {{BP_RGIL, MOD_LSFT}, {BP_DLR, MOD_LSFT}},
96 [GR(DB_4)] = {{BP_LPRN, MOD_LSFT}, {BP_DLR, MOD_NONE}},
97 [GR(DB_5)] = {{BP_RPRN, MOD_LSFT}, {BP_PERC, MOD_NONE}},
98 [GR(DB_6)] = {{BP_AT, MOD_LSFT}, {BP_AT, MOD_BIT(KC_RALT)}},
99 [GR(DB_7)] = {{BP_PLUS, MOD_LSFT}, {BP_P, MOD_BIT(KC_RALT)}},
100 [GR(DB_8)] = {{BP_MINS, MOD_LSFT}, {BP_ASTR, MOD_NONE}},
101 [GR(DB_9)] = {{BP_SLASH, MOD_LSFT}, {BP_LPRN, MOD_NONE}},
102 [GR(DB_0)] = {{BP_ASTR, MOD_LSFT}, {BP_RPRN, MOD_NONE}},
103 [GR(DB_GRV)] = {{BP_PERC, MOD_LSFT}, {BP_K, MOD_BIT(KC_RALT)}},
104 [GR(DB_SCOLON)] = {{BP_COMM, MOD_LSFT}, {BP_DOT, MOD_LSFT}},
105 [GR(DB_SLASH)] = {{BP_SLASH, MOD_NONE}, {BP_APOS, MOD_LSFT}},
106 [GR(DB_BACKSLASH)] = {{BP_AGRV, MOD_BIT(KC_RALT)}, {BP_B, MOD_BIT(KC_RALT)}},
107 [GR(DB_EQL)] = {{BP_EQL, MOD_NONE}, {BP_PLUS, MOD_NONE}},
108 [GR(DB_COMM)] = {{BP_COMMA, MOD_NONE}, {BP_LGIL, MOD_BIT(KC_RALT)}},
109 [GR(DB_DOT)] = {{BP_DOT, MOD_NONE}, {BP_RGIL, MOD_BIT(KC_RALT)}},
110 [GR(DB_QUOT)] = {{BP_APOS, MOD_NONE}, {BP_DQOT, MOD_NONE}},
111 [GR(DB_MINUS)] = {{BP_MINUS, MOD_NONE}, {KC_SPC, MOD_BIT(KC_RALT)}},
112 [GR(DB_LPRN)] = {{BP_LPRN, MOD_NONE}, {BP_LPRN, MOD_BIT(KC_RALT)}},
113 [GR(DB_RPRN)] = {{BP_RPRN, MOD_NONE}, {BP_RPRN, MOD_BIT(KC_RALT)}},
114 [GR(DB_LBRC)] = {{BP_Y, MOD_BIT(KC_RALT)}, {BP_LPRN, MOD_BIT(KC_RALT)}},
115 [GR(DB_RBRC)] = {{BP_X, MOD_BIT(KC_RALT)}, {BP_RPRN, MOD_BIT(KC_RALT)}},
116 // For the symbol layer
117 [GR(DB_HASH)] = {{BP_DLR, MOD_LSFT}, {BP_DLR, MOD_LSFT}},
118 [GR(DB_LCBR)] = {{BP_LPRN, MOD_BIT(KC_RALT)}, {BP_LPRN, MOD_BIT(KC_RALT)}},
119 [GR(DB_RCBR)] = {{BP_LPRN, MOD_BIT(KC_RALT)}, {BP_RPRN, MOD_BIT(KC_RALT)}},
120 [GR(DB_PIPE)] = {{BP_B, MOD_BIT(KC_RALT)}, {BP_B, MOD_BIT(KC_RALT)}},
121 [GR(DB_TILD)] = {{BP_K, MOD_BIT(KC_RALT)}, {BP_K, MOD_BIT(KC_RALT)}},
122 [GR(DB_CIRC)] = {{BP_AT, MOD_BIT(KC_RALT)}, {BP_AT, MOD_BIT(KC_RALT)}},
123 [GR(DB_LESS)] = {{BP_LGIL, MOD_BIT(KC_RALT)}, {BP_LGIL, MOD_BIT(KC_RALT)}},
124 [GR(DB_GRTR)] = {{BP_RGIL, MOD_BIT(KC_RALT)}, {BP_RGIL, MOD_BIT(KC_RALT)}},
125
126
127};
128
129
130uint8_t gr(uint8_t kc){
131 return (kc - SAFE_RANGE);
132}
133// send the right keycode for the right mod.
134// remove the mods we are taking care of,
135// send our keycodes then restore them.
136// all so we can make dvorak keys from bepo keycodes.
137void send_keycode(uint8_t kc){
138 uint8_t tmp_mods = get_mods();
139 bool is_shifted = ( tmp_mods & (MOD_BIT(KC_LSFT)|MOD_BIT(KC_RSFT)) );
140 //uint8_t key[2][2] = key_translations[GR(kc)];
141 // need to turn of the shift if it is on.
142 unregister_mods((MOD_BIT(KC_LSFT)|MOD_BIT(KC_RSFT)));
143 if(is_shifted){
144 register_mods(SHIFTED_MODS(kc));
145 register_code(SHIFTED_KEY(kc));
146 unregister_code(SHIFTED_KEY(kc));
147 unregister_mods(SHIFTED_MODS(kc));
148 } else{
149 register_mods(UNSHIFTED_MODS(kc));
150 register_code(UNSHIFTED_KEY(kc));
151 unregister_code(UNSHIFTED_KEY(kc));
152 unregister_mods(UNSHIFTED_MODS(kc));
153 }
154 clear_mods();
155 register_mods(tmp_mods);
156}
157
158
159bool process_record_user(uint16_t keycode, keyrecord_t *record) {
160
161// If console is enabled, it will print the matrix position and status of each key pressed
162#ifdef KEYLOGGER_ENABLE
163xprintf("KL: row: %u, column: %u, pressed: %u\n", record->event.key.col, record->event.key.row, record->event.pressed);
164#endif //KEYLOGGER_ENABLE
165
166// still dont know how to make #&_ And RALT is not ALTGR, That isn't working in the bepo keyboard
167// either. No {} either probably for the same reasons. ALtGR is the key to some of these.
168 switch (keycode) {
169 // Handle the key translations for Dvorak on bepo. It's best if these are the first
170 // enums after SAFE_RANGE.
171 case DB_1:
172 case DB_2:
173 case DB_3:
174 case DB_4:
175 case DB_5:
176 case DB_6:
177 case DB_7:
178 case DB_8:
179 case DB_9:
180 case DB_0:
181 case DB_GRV:
182 case DB_SCOLON:
183 case DB_SLASH:
184 case DB_BACKSLASH:
185 case DB_EQL:
186 case DB_DOT:
187 case DB_COMM:
188 case DB_QUOT:
189 case DB_MINUS:
190 case DB_LPRN:
191 case DB_RPRN:
192 case DB_LBRC:
193 case DB_RBRC:
194 if(record->event.pressed)
195 send_keycode(keycode);
196 unregister_code(keycode);
197 break;
198
199 case KC_QWERTY:
200 if (record->event.pressed) {
201 set_single_persistent_default_layer(QWERTY);
202 }
203 return false;
204 break;
205 case KC_COLEMAK:
206 if (record->event.pressed) {
207 set_single_persistent_default_layer(COLEMAK);
208 }
209 return false;
210 break;
211 case KC_DVORAK:
212 if (record->event.pressed) {
213 set_single_persistent_default_layer(DVORAK);
214 }
215 return false;
216 break;
217 case KC_WORKMAN:
218 if (record->event.pressed) {
219 set_single_persistent_default_layer(WORKMAN);
220 }
221 return false;
222 break;
223
224 case KC_MAKE: // Compiles the firmware, and adds the flash command based on keyboard bootloader
225 if (!record->event.pressed) {
226 SEND_STRING("make " QMK_KEYBOARD ":" QMK_KEYMAP
227#if (defined(BOOTLOADER_DFU) || defined(BOOTLOADER_LUFA_DFU) || defined(BOOTLOADER_QMK_DFU))
228 ":dfu"
229#elif defined(BOOTLOADER_HALFKAY)
230 ":teensy"
231#elif defined(BOOTLOADER_CATERINA)
232 ":avrdude"
233#endif // bootloader options
234 SS_TAP(X_ENTER));
235 }
236 return false;
237 break;
238
239
240 case KC_RESET: // Custom RESET code
241 if (!record->event.pressed) {
242 reset_keyboard();
243 }
244 return false;
245 break;
246
247
248 case EPRM: // Resets EEPROM
249 if (record->event.pressed) {
250 eeconfig_init();
251 default_layer_set(1UL<<eeconfig_read_default_layer());
252 layer_state_set(layer_state);
253 }
254 return false;
255 break;
256 case VRSN: // Prints firmware version
257 if (record->event.pressed) {
258 SEND_STRING(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION ", Built on: " QMK_BUILDDATE);
259 }
260 return false;
261 break;
262
263 /* Code has been depreciated
264 case KC_SECRET_1 ... KC_SECRET_5: // Secrets! Externally defined strings, not stored in repo
265 if (!record->event.pressed) {
266 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
267 send_string(decoy_secret[keycode - KC_SECRET_1]);
268 }
269 return false;
270 break;
271 */
272
273 // These are a serious of gaming macros.
274 // Only enables for the viterbi, basically,
275 // to save on firmware space, since it's limited.
276#ifdef MACROS_ENABLED
277 case KC_OVERWATCH: // Toggle's if we hit "ENTER" or "BACKSPACE" to input macros
278 if (record->event.pressed) { userspace_config.is_overwatch ^= 1; eeprom_update_byte(EECONFIG_USERSPACE, userspace_config.raw); }
279 return false; break;
280#endif // MACROS_ENABLED
281
282 case KC_CCCV: // One key copy/paste
283 if(record->event.pressed){
284 copy_paste_timer = timer_read();
285 } else {
286 if (timer_elapsed(copy_paste_timer) > TAPPING_TERM) { // Hold, copy
287 register_code(KC_LCTL);
288 tap(KC_C);
289 unregister_code(KC_LCTL);
290#ifdef AUDIO_ENABLE
291 PLAY_SONG(tone_copy);
292#endif
293 } else { // Tap, paste
294 register_code(KC_LCTL);
295 tap(KC_V);
296 unregister_code(KC_LCTL);
297#ifdef AUDIO_ENABLE
298 PLAY_SONG(tone_paste);
299#endif
300 }
301 }
302 return false;
303 break;
304 case CLICKY_TOGGLE:
305#ifdef AUDIO_CLICKY
306 userspace_config.clicky_enable = clicky_enable;
307 eeprom_update_byte(EECONFIG_USERSPACE, userspace_config.raw);
308#endif
309 break;
310#ifdef UNICODE_ENABLE
311 case UC_FLIP: // (╯°□°)╯ ︵ ┻━┻
312 if (record->event.pressed) {
313 register_code(KC_RSFT);
314 tap(KC_9);
315 unregister_code(KC_RSFT);
316 process_unicode((0x256F | QK_UNICODE), record); // Arm
317 process_unicode((0x00B0 | QK_UNICODE), record); // Eye
318 process_unicode((0x25A1 | QK_UNICODE), record); // Mouth
319 process_unicode((0x00B0 | QK_UNICODE), record); // Eye
320 register_code(KC_RSFT);
321 tap(KC_0);
322 unregister_code(KC_RSFT);
323 process_unicode((0x256F | QK_UNICODE), record); // Arm
324 tap(KC_SPC);
325 process_unicode((0x0361 | QK_UNICODE), record); // Flippy
326 tap(KC_SPC);
327 process_unicode((0x253B | QK_UNICODE), record); // Table
328 process_unicode((0x2501 | QK_UNICODE), record); // Table
329 process_unicode((0x253B | QK_UNICODE), record); // Table
330 }
331 return false;
332 break;
333#endif // UNICODE_ENABLE
334
335}
336
337return true;
338 // return process_record_keymap(keycode, record) && process_record_secrets(keycode, record);
339}
340
341void tap_dance_mouse_btns (qk_tap_dance_state_t *state, void *user_data) {
342 switch(state->count){
343 case 1:
344 register_code(KC_BTN1);
345 break;
346 case 2:
347 register_code(KC_BTN2);
348 break;
349 case 3:
350 register_code(KC_BTN3);
351 break;
352 case 4:
353 register_code(KC_BTN4);
354 break;
355 case 5:
356 register_code(KC_BTN5);
357 break;
358 default:
359 break;
360 }
361 reset_tap_dance(state);
362}
363
364// counting on all the qwerty layers to be less than dvorak_on_bepo
365int on_qwerty(){
366 uint8_t deflayer = (biton32(default_layer_state));
367 return (deflayer < DVORAK_ON_BEPO);
368}
369
370void tap_dance_df_bepo_layers_switch (qk_tap_dance_state_t *state, void *user_data) {
371 switch(state->count){
372 case 1:
373 switch_default_layer(DVORAK_ON_BEPO);
374 break;
375 case 2:
376 switch_default_layer(BEPO);
377 break;
378 case 3:
379 layer_invert(LAYERS);
380 break;
381 default:
382 break;
383 }
384 reset_tap_dance(state);
385}
386
387void tap_dance_layer_switch (qk_tap_dance_state_t *state, void *user_data) {
388 switch(state->count){
389 case 1:
390 if(on_qwerty())
391 layer_invert(SYMB);
392 else
393 layer_invert(SYMB_ON_BEPO);
394 break;
395 case 2:
396 layer_invert(MDIA);
397 break;
398 case 3:
399 layer_invert(LAYERS);
400 default:
401 break;
402 }
403 reset_tap_dance(state);
404}
405
406void tap_dance_default_layer_switch (qk_tap_dance_state_t *state, void *user_data) {
407 switch(state->count){
408 case 1:
409 switch_default_layer(DVORAK);
410 break;
411 case 2:
412 switch_default_layer(DVORAK_ON_BEPO);
413 break;
414 case 3:
415 switch_default_layer(BEPO);
416 break;
417 default:
418 break;
419 }
420 reset_tap_dance(state);
421}
422
423// switch the default layer to another qwerty based layer.
424void switch_default_layer_on_qwerty(int count) {
425 switch(count){
426 case 1:
427 switch_default_layer(DVORAK);
428 break;
429 case 2:
430 switch_default_layer(QWERTY);
431 break;
432 case 3:
433 switch_default_layer(COLEMAK);
434 break;
435 case 4:
436 switch_default_layer(WORKMAN);
437 break;
438 case 5:
439 switch_default_layer(NORMAN);
440 break;
441 default:
442 switch_default_layer(DVORAK);
443 break;
444 }
445}
446
447// switch the default layer to another bepo based layer.
448void switch_default_layer_on_bepo(int count) {
449 switch(count){
450 case 1:
451 switch_default_layer(DVORAK_ON_BEPO);
452 break;
453 case 2:
454 switch_default_layer(BEPO);
455 break;
456 default:
457 switch_default_layer(DVORAK_ON_BEPO);
458 break;
459 }
460}
461
462
463// tap to change the default layer. Distinguishes between layers that are based on
464// a qwerty software keyboard and a bepo software keyboard.
465// if shifted, choose layers based on the other software keyboard, otherwise choose only
466// layers that work on the current software keyboard.
467void tap_dance_default_os_layer_switch (qk_tap_dance_state_t *state, void *user_data) {
468 //uint8_t shifted = (get_mods() & MOD_BIT(KC_LSFT|KC_RSFT));
469 bool shifted = ( keyboard_report->mods & (MOD_BIT(KC_LSFT)|MOD_BIT(KC_RSFT)) );
470 int qwerty = on_qwerty();
471
472
473 // shifted, choose between layers on the other software keyboard
474 if(shifted){
475 if (qwerty)
476 switch_default_layer_on_bepo(state->count);
477 else
478 switch_default_layer_on_qwerty(state->count);
479
480 // not shifted, choose between layers on the same software keyboard
481 } else {
482 if (qwerty)
483 switch_default_layer_on_qwerty(state->count);
484 else
485 switch_default_layer_on_bepo(state->count);
486 }
487
488 reset_tap_dance(state);
489}
490
491
492/* Return an integer that corresponds to what kind of tap dance should be executed.
493 *
494 * How to figure out tap dance state: interrupted and pressed.
495 *
496 * Interrupted: If the state of a dance dance is "interrupted", that means that another key has been hit
497 * under the tapping term. This is typically indicitive that you are trying to "tap" the key.
498 *
499 * Pressed: Whether or not the key is still being pressed. If this value is true, that means the tapping term
500 * has ended, but the key is still being pressed down. This generally means the key is being "held".
501 *
502 * One thing that is currenlty not possible with qmk software in regards to tap dance is to mimic the "permissive hold"
503 * feature. In general, advanced tap dances do not work well if they are used with commonly typed letters.
504 * For example "A". Tap dances are best used on non-letter keys that are not hit while typing letters.
505 *
506 * Good places to put an advanced tap dance:
507 * z,q,x,j,k,v,b, any function key, home/end, comma, semi-colon
508 *
509 * Criteria for "good placement" of a tap dance key:
510 * Not a key that is hit frequently in a sentence
511 * Not a key that is used frequently to double tap, for example 'tab' is often double tapped in a terminal, or
512 * in a web form. So 'tab' would be a poor choice for a tap dance.
513 * Letters used in common words as a double. For example 'p' in 'pepper'. If a tap dance function existed on the
514 * letter 'p', the word 'pepper' would be quite frustating to type.
515 *
516 * For the third point, there does exist the 'DOUBLE_SINGLE_TAP', however this is not fully tested
517 *
518 */
519int cur_dance (qk_tap_dance_state_t *state) {
520 if (state->count == 1) {
521 if (state->interrupted || !state->pressed) return SINGLE_TAP;
522 //key has not been interrupted, but they key is still held. Means you want to send a 'HOLD'.
523 else return SINGLE_HOLD;
524 }
525 else if (state->count == 2) {
526 /*
527 * DOUBLE_SINGLE_TAP is to distinguish between typing "pepper", and actually wanting a double tap
528 * action when hitting 'pp'. Suggested use case for this return value is when you want to send two
529 * keystrokes of the key, and not the 'double tap' action/macro.
530 */
531 if (state->interrupted) return DOUBLE_SINGLE_TAP;
532 else if (state->pressed) return DOUBLE_HOLD;
533 else return DOUBLE_TAP;
534 }
535 //Assumes no one is trying to type the same letter three times (at least not quickly).
536 //If your tap dance key is 'KC_W', and you want to type "www." quickly - then you will need to add
537 //an exception here to return a 'TRIPLE_SINGLE_TAP', and define that enum just like 'DOUBLE_SINGLE_TAP'
538 if (state->count == 3) {
539 if (state->interrupted || !state->pressed) return TRIPLE_TAP;
540 else return TRIPLE_HOLD;
541 }
542 else return 8; //magic number. At some point this method will expand to work for more presses
543}
544//instanalize an instance of 'tap' for the 'x' tap dance.
545static tdtap xtap_state = {
546 .is_press_action = true,
547 .state = 0
548};
549/*
550 This so I can have a single key that acts like LGUI in DVORAK no
551 matter which keymap is my current default.
552 It also allows for the
553 shift gui and ctl gui, on the same key, So the same key is Escape,
554 and the mostcommon modifiers in my xmonad control keymap, while also
555 insuring that dvorak is active for the xmonad command key
556 Single tap = ESC
557 tap and hold = dvorak with L_GUI
558 double tap = One shot dvorak layer with LSFT LGUI mods
559 double hold = dvorak with LCTL LGUI
560 double single tap = esc.
561*/
562int get_xmonad_layer(){
563 int qwerty = on_qwerty();
564
565 if (qwerty)
566 return(XMONAD);
567 else
568 return(XMONAD_FR);
569}
570
571
572void x_finished (qk_tap_dance_state_t *state, void *user_data) {
573 int xmonad_layer = get_xmonad_layer();
574 xtap_state.state = cur_dance(state);
575 switch (xtap_state.state) {
576 case SINGLE_TAP:
577 register_code(KC_ESC);
578 break;
579 case SINGLE_HOLD:
580 layer_on(xmonad_layer);
581 set_oneshot_mods (MOD_LGUI);
582 //set_oneshot_layer (DVORAK, ONESHOT_START);
583 break;
584 case DOUBLE_TAP:
585 set_oneshot_mods ((MOD_LCTL | MOD_LGUI));
586 layer_on (xmonad_layer);
587 set_oneshot_layer (xmonad_layer, ONESHOT_START);
588 break;
589 case DOUBLE_HOLD:
590 set_oneshot_mods (MOD_LSFT | MOD_LGUI);
591 if (xmonad_layer != -1)
592 layer_on(xmonad_layer);
593 break;
594 case DOUBLE_SINGLE_TAP:
595 register_code(KC_ESC);
596 unregister_code(KC_ESC);
597 register_code(KC_ESC);
598 //Last case is for fast typing. Assuming your key is `f`:
599 //For example, when typing the word `buffer`, and you want to make sure that you send `ff` and not `Esc`.
600 //In order to type `ff` when typing fast, the next character will have to be hit within the `TAPPING_TERM`, which by default is 200ms.
601 }
602}
603
604void x_reset (qk_tap_dance_state_t *state, void *user_data) {
605 int xmonad_layer = get_xmonad_layer();
606 switch (xtap_state.state) {
607 case SINGLE_TAP:
608 unregister_code(KC_ESC);
609 break;
610 case SINGLE_HOLD:
611 layer_off(xmonad_layer);
612 break;
613 case DOUBLE_TAP:
614 set_oneshot_layer (xmonad_layer, ONESHOT_PRESSED);
615 break;
616 case DOUBLE_HOLD:
617 layer_off(xmonad_layer);
618 break;
619 case DOUBLE_SINGLE_TAP:
620 unregister_code(KC_ESC);
621 }
622 xtap_state.state = 0;
623}
624
625//Tap Dance Definitions
626qk_tap_dance_action_t tap_dance_actions[] = {
627 //Tap once for Esc, twice for Caps Lock
628 [TD_ESC_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_CAPS),
629 [TD_TAB_BKTAB] = ACTION_TAP_DANCE_DOUBLE(KC_TAB, LSFT(KC_TAB)),
630 [TD_MDIA_SYMB] = ACTION_TAP_DANCE_FN(tap_dance_layer_switch),
631 [TD_DVORAK_BEPO] = ACTION_TAP_DANCE_FN(tap_dance_df_bepo_layers_switch),
632 [TD_DEF_LAYER_SW] = ACTION_TAP_DANCE_FN(tap_dance_default_layer_switch),
633 [TD_DEF_OS_LAYER_SW] = ACTION_TAP_DANCE_FN(tap_dance_default_os_layer_switch),
634 [TD_HOME_END] = ACTION_TAP_DANCE_DOUBLE(KC_HOME, KC_END),
635 [TD_XMONAD_ESC] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, x_finished, x_reset),
636 [TD_MOUSE_BTNS] = ACTION_TAP_DANCE_FN(tap_dance_mouse_btns)
637};