2
0

keymap.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /* Copyright 2017 Colin T.A. Gray
  2. *
  3. * This program is free software: you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation, either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include "xd75.h"
  17. #ifdef IS_COLINTA
  18. #include "secrets.h"
  19. #else
  20. #define SENDSTRING_MM0 ""
  21. #define SENDSTRING_MM1 ""
  22. #define SENDSTRING_MM2 ""
  23. #endif
  24. // layers:
  25. // - colemak,
  26. // - record-mode (adds stop buttons)
  27. // - qwerty
  28. // - fn (recording, changing layers)
  29. #define LAYER_COLEMAK 0
  30. #define LAYER_RECORD 1
  31. #define LAYER_QWERTY 2
  32. #define LAYER_FN 3
  33. // custom keys:
  34. // - goto layer keys
  35. #define GOTO_FN TT(LAYER_FN)
  36. #define GOTO_CM TO(LAYER_COLEMAK)
  37. #define GOTO_QW TO(LAYER_QWERTY)
  38. // - sticky keys, aka one-shot
  39. #define OSCTL OSM(MOD_LCTL)
  40. #define OSALT OSM(MOD_LALT)
  41. #define OSSFT OSM(MOD_LSFT)
  42. #define OSGUI OSM(MOD_LGUI)
  43. // "MMENU" is a macro for "CMD+SPC" (aka Spotlight/Alfred)
  44. #define MMENU LGUI(KC_SPC)
  45. #define _____ KC_TRNS
  46. #define MM_0 DYN_MACRO_PLAY1
  47. #define MM_1 DYN_MACRO_PLAY2
  48. // tap-hold settings
  49. #define LONGPRESS_DELAY 250
  50. #define TH_EVENTS_COUNT 13
  51. enum my_keycods {
  52. TH_M0 = SAFE_RANGE,
  53. TH_M1,
  54. TH_M2,
  55. TH_F1,
  56. TH_F2,
  57. TH_F3,
  58. TH_F4,
  59. TH_F5,
  60. TH_F6,
  61. TH_F7,
  62. TH_F8,
  63. TH_F9,
  64. TH_F10,
  65. TH_LAST,
  66. MM_2,
  67. DM_CLEAR,
  68. DYNAMIC_MACRO_RANGE,
  69. };
  70. #include "dynamic_macro.h"
  71. const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  72. /* COLEMAK
  73. * .--------------------------------------------------------------------------------------------------------------------------------------.
  74. * | ESC | 1 | 2 | 3 | 4 | 5 | M(0) | M(1) | DEL | 6 | 7 | 8 | 9 | 0 | - |
  75. * |--------+-/F1----+-/F2----+-/F3----+-/F4----+-/F5----+--------+--------+--------+-/F6----+-/F7----+-/F8----+-/F9----+-/F10---+--------|
  76. * | TAB | Q | W | F | P | G | M(2) | (FN) | BKSP | J | L | U | Y | ; | = |
  77. * |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+-----------------+--------|
  78. * | SHIFT | A | R | S | T | D | [ | ] | ENTER | H | N | E | I | O | ' |
  79. * |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------------------------+--------|
  80. * | CTRL | Z | X | C | V | B | HOME | END | PG UP | K | M | , | . | / | \ |
  81. * |--------+--------+--------+--------+--------+-----------------+--------+--------+--------+--------+-----------------+--------+--------|
  82. * | VOL- | PLAY | VOL+ | ALT | GUI | SPACE | PG DN | MENU | ESC | LEFT | DOWN | UP | RIGHT |
  83. * '--/RRND----/MUTE----/FFWD-------------------------------------------------------------------------------------------------------------'
  84. */
  85. [LAYER_COLEMAK] = KEYMAP(
  86. KC_GRV, TH_F1, TH_F2, TH_F3, TH_F4, TH_F5, MM_0, MM_1, KC_DEL, TH_F6, TH_F7, TH_F8, TH_F9, TH_F10, KC_MINS,
  87. KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, MM_2, GOTO_FN, KC_BSPC, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_EQL,
  88. OSCTL, KC_A, KC_R, KC_S, KC_T, KC_D, KC_LBRC, KC_RBRC, KC_ENT, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT,
  89. OSSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_HOME, KC_END, KC_PGUP, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_BSLS,
  90. TH_M0, TH_M1, TH_M2, OSALT, OSGUI, _____ , KC_SPC, _____ , KC_PGDN, MMENU, KC_ESC, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT
  91. ),
  92. /* DYN_REC LAYER - recording tap/hold keys is possible, but they will always "tap" (macros don't record holding duration)
  93. * .--------------------------------------------------------------------------------------------------------------------------------------.
  94. * | | | | | | | STOP | STOP | | | | | | | |
  95. * |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+-----------------|
  96. * | | | | | | | STOP | STOP | | | | | | | |
  97. * |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+-----------------+--------|
  98. * | | | | | | | | | | | | | | | |
  99. * |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------------------------+--------|
  100. * | | | | | | | | | | | | | | | |
  101. * |--------+--------+--------+--------+--------+-----------------+--------+--------+--------+--------+-----------------+--------+--------|
  102. * | | | | | | | | | | | | | |
  103. * '--------------------------------------------------------------------------------------------------------------------------------------'
  104. */
  105. [LAYER_RECORD] = KEYMAP(
  106. _____, _____, _____, _____, _____, _____, DYN_REC_STOP, DYN_REC_STOP, _____, _____, _____, _____, _____, _____, _____,
  107. _____, _____, _____, _____, _____, _____, DYN_REC_STOP, DYN_REC_STOP, _____, _____, _____, _____, _____, _____, _____,
  108. _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____,
  109. _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____,
  110. _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____
  111. ),
  112. /* QWERTY - doesn't support recording of macros, btw. Falls through to colemak for most keys, but passes through the recording layer, so heads up.
  113. * .--------------------------------------------------------------------------------------------------------------------------------------.
  114. * | | | | | | | M(0) | M(1) | | | | | | | |
  115. * |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+-----------------|
  116. * | | Q | W | E | R | T | M(2) | (FN) | | Y | U | I | O | P | |
  117. * |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+-----------------+--------|
  118. * | SHIFT | A | S | D | F | G | | | | H | J | K | L | ; | |
  119. * |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------------------------+--------|
  120. * | CTRL | Z | X | C | V | B | | | | N | M | | | | |
  121. * |--------+--------+--------+--------+--------+-----------------+--------+--------+--------+--------+-----------------+--------+--------|
  122. * | | | | ALT | GUI | | | | | | | | |
  123. * '--------------------------------------------------------------------------------------------------------------------------------------'
  124. */
  125. [LAYER_QWERTY] = KEYMAP(
  126. _____, _____, _____, _____, _____, _____, MM_0, MM_1, _____, _____, _____, _____, _____, _____, _____,
  127. _____, KC_Q, KC_W, KC_E, KC_R, KC_T, MM_2, GOTO_FN, _____, KC_Y, KC_U, KC_I, KC_O, KC_P, _____,
  128. MOD_LSFT, KC_A, KC_S, KC_D, KC_F, KC_G, _____, _____, _____, KC_H, KC_J, KC_K, KC_L, KC_SCLN, _____,
  129. MOD_LCTL, KC_Z, KC_X, KC_C, KC_V, KC_B, _____, _____, _____, KC_N, KC_M, _____, _____, _____, _____,
  130. _____, _____, _____, MOD_LALT, MOD_LGUI, _____, _____, _____, _____, _____, _____, _____, _____, _____, _____
  131. ),
  132. /* FN LAYER - change layouts and start recording a macro
  133. * .--------------------------------------------------------------------------------------------------------------------------------------.
  134. * | COLEMAK| QWERTY | | | | | REC 1 | REC 2 | | | | | | | |
  135. * |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+-----------------|
  136. * | | | | | | | | ------ | | | | | | | |
  137. * |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+-----------------+--------|
  138. * | | | | | | | | | | | | | | | |
  139. * |--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------------------------+--------|
  140. * | | | | | | | | | | | | | | | |
  141. * |--------+--------+--------+--------+--------+-----------------+--------+--------+--------+--------+-----------------+--------+--------|
  142. * | | | | | RESET | DM_CLEAR | | | RESET | | | | |
  143. * '--------------------------------------------------------------------------------------------------------------------------------------'
  144. */
  145. [LAYER_FN] = KEYMAP(
  146. GOTO_CM, GOTO_QW, KC_NO, KC_NO, KC_NO, KC_NO, DYN_REC_START1, DYN_REC_START2, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
  147. KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
  148. KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
  149. KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
  150. KC_NO, KC_NO, KC_NO, KC_NO, RESET, KC_NO, DM_CLEAR, KC_NO, KC_NO, KC_NO, RESET, KC_NO, KC_NO, KC_NO, KC_NO
  151. )
  152. };
  153. typedef struct {
  154. bool is_pressed;
  155. uint16_t timer;
  156. uint16_t kc_tap;
  157. uint16_t kc_hold;
  158. } tap_hold_t;
  159. static tap_hold_t th_events[] = {
  160. { .is_pressed = false, .timer = 0, .kc_tap = KC_VOLD, .kc_hold = KC_MRWD }, // TH_M0
  161. { .is_pressed = false, .timer = 0, .kc_tap = KC_MPLY, .kc_hold = KC_MUTE }, // TH_M1
  162. { .is_pressed = false, .timer = 0, .kc_tap = KC_VOLU, .kc_hold = KC_MFFD }, // TH_M2
  163. { .is_pressed = false, .timer = 0, .kc_tap = KC_1, .kc_hold = KC_F1 }, // TH_F1
  164. { .is_pressed = false, .timer = 0, .kc_tap = KC_2, .kc_hold = KC_F2 }, // TH_F2
  165. { .is_pressed = false, .timer = 0, .kc_tap = KC_3, .kc_hold = KC_F3 }, // TH_F3
  166. { .is_pressed = false, .timer = 0, .kc_tap = KC_4, .kc_hold = KC_F4 }, // TH_F4
  167. { .is_pressed = false, .timer = 0, .kc_tap = KC_5, .kc_hold = KC_F5 }, // TH_F5
  168. { .is_pressed = false, .timer = 0, .kc_tap = KC_6, .kc_hold = KC_F6 }, // TH_F6
  169. { .is_pressed = false, .timer = 0, .kc_tap = KC_7, .kc_hold = KC_F7 }, // TH_F7
  170. { .is_pressed = false, .timer = 0, .kc_tap = KC_8, .kc_hold = KC_F8 }, // TH_F8
  171. { .is_pressed = false, .timer = 0, .kc_tap = KC_9, .kc_hold = KC_F9 }, // TH_F9
  172. { .is_pressed = false, .timer = 0, .kc_tap = KC_0, .kc_hold = KC_F10 } // TH_F10
  173. };
  174. void taphold_tapped(uint8_t index, bool pressed) {
  175. if (index >= TH_EVENTS_COUNT) { return; }
  176. tap_hold_t *th_event = &th_events[index];
  177. if (pressed) {
  178. th_event->timer = timer_read();
  179. th_event->is_pressed = true;
  180. } else if (th_event->is_pressed) {
  181. register_code(th_event->kc_tap);
  182. unregister_code(th_event->kc_tap);
  183. th_event->is_pressed = false;
  184. }
  185. }
  186. void matrix_scan_user() {
  187. for (uint8_t index = 0 ; index < TH_EVENTS_COUNT ; ++index ) {
  188. tap_hold_t *th_event = &th_events[index];
  189. if ( th_event->is_pressed && timer_elapsed(th_event->timer) > LONGPRESS_DELAY) {
  190. register_code(th_event->kc_hold);
  191. unregister_code(th_event->kc_hold);
  192. th_event->is_pressed = false;
  193. }
  194. }
  195. }
  196. // if the dynamic macros haven't been recorded, we send the default macro strings.
  197. bool did_record_m1 = false;
  198. bool did_record_m2 = false;
  199. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  200. bool try_dynamic_macro = true;
  201. if ((keycode == DYN_MACRO_PLAY1 && !did_record_m1) || (keycode == DYN_MACRO_PLAY2 && !did_record_m2)) {
  202. try_dynamic_macro = false;
  203. }
  204. else if (keycode == DM_CLEAR) {
  205. try_dynamic_macro = false;
  206. did_record_m1 = false;
  207. did_record_m2 = false;
  208. }
  209. if (try_dynamic_macro && !process_record_dynamic_macro(keycode, record)) {
  210. if (keycode == DYN_MACRO_PLAY1) {
  211. did_record_m1 = true;
  212. }
  213. if (keycode == DYN_MACRO_PLAY2) {
  214. did_record_m2 = true;
  215. }
  216. if (keycode == DYN_REC_START1 || keycode == DYN_REC_START2) {
  217. layer_move(LAYER_RECORD);
  218. }
  219. else if (keycode == DYN_REC_STOP) {
  220. layer_move(LAYER_COLEMAK);
  221. }
  222. return false;
  223. }
  224. switch (keycode) {
  225. case DYN_MACRO_PLAY1:
  226. SEND_STRING(SENDSTRING_MM0);
  227. return false;
  228. case DYN_MACRO_PLAY2:
  229. SEND_STRING(SENDSTRING_MM1);
  230. return false;
  231. case MM_2:
  232. SEND_STRING(SENDSTRING_MM2);
  233. return false;
  234. case TH_M0 ... TH_LAST:
  235. taphold_tapped(keycode - TH_M0, record->event.pressed);
  236. return false;
  237. }
  238. return true;
  239. }