keymap.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. // see https://github.com/pepaslabs/hexon38
  2. #include "hexon38.h"
  3. #define A_ KC_A
  4. #define B_ KC_B
  5. #define C_ KC_C
  6. #define D_ KC_D
  7. #define E_ KC_E
  8. #define F_ KC_F
  9. #define G_ KC_G
  10. #define H_ KC_H
  11. #define I_ KC_I
  12. #define J_ KC_J
  13. #define K_ KC_K
  14. #define L_ KC_L
  15. #define M_ KC_M
  16. #define N_ KC_N
  17. #define O_ KC_O
  18. #define P_ KC_P
  19. #define Q_ KC_Q
  20. #define R_ KC_R
  21. #define S_ KC_S
  22. #define T_ KC_T
  23. #define U_ KC_U
  24. #define V_ KC_V
  25. #define W_ KC_W
  26. #define X_ KC_X
  27. #define Y_ KC_Y
  28. #define Z_ KC_Z
  29. // Dual-role keys: modifier when held, alpha when tapped.
  30. #define A_CTL CTL_T(KC_A)
  31. #define S_ALT ALT_T(KC_S)
  32. #define D_GUI GUI_T(KC_D)
  33. #define F_SFT SFT_T(KC_F)
  34. #define J_SFT SFT_T(KC_J)
  35. #define K_GUI GUI_T(KC_K)
  36. #define L_ALT ALT_T(KC_L)
  37. #define COLN_CTL CTL_T(KC_SCLN)
  38. #define ______ KC_TRNS
  39. #define LSHIFT KC_LSHIFT
  40. #define RSHIFT KC_RSHIFT
  41. #define COMMA KC_COMM
  42. #define SLASH KC_SLSH
  43. #define SPACE KC_SPC
  44. #define TAB KC_TAB
  45. #define BKSPC KC_BSPC
  46. #define ENTER KC_ENT
  47. #define PERIOD KC_DOT
  48. #define BASE_LAYER LAYOUT
  49. #define BLANK_LAYER LAYOUT
  50. const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  51. BASE_LAYER(
  52. // ,--------+--------+--------+--------. ,--------+--------+--------+--------.
  53. W_ , E_ , R_ , T_ , Y_ , U_ , I_ , O_ ,
  54. //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------.
  55. Q_ , A_CTL , S_ALT , D_GUI , F_SFT , G_ , H_ , J_SFT , K_GUI , L_ALT ,COLN_CTL, P_ ,
  56. //|--------+--------+--------+--------+--------+--------' `--------+--------+--------+--------+--------+--------|
  57. B_ , Z_ , X_ , C_ , V_ , M_ , COMMA , PERIOD , SLASH , N_ ,
  58. //`--------+--------+--------+--------+--------' `--------+--------+--------+--------+--------'
  59. // ,--------+--------+--------+--------. ,--------+--------+--------+--------.
  60. LSHIFT , SPACE , TAB , DEBUG , SPACE , BKSPC , ENTER , RSHIFT
  61. // `--------+--------+--------+--------' `--------+--------+--------+--------'
  62. ),
  63. BLANK_LAYER(
  64. // ,--------+--------+--------+--------. ,--------+--------+--------+--------.
  65. ______ , ______ , ______ , ______ , ______ , ______ , ______ , ______ ,
  66. //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------.
  67. ______ , ______ , ______ , ______ , ______ , ______ , ______ , ______ , ______ , ______ , ______ , ______ ,
  68. //|--------+--------+--------+--------+--------+--------' `--------+--------+--------+--------+--------+--------|
  69. ______ , ______ , ______ , ______ , ______ , ______ , ______ , ______ , ______ , ______ ,
  70. //`--------+--------+--------+--------+--------' `--------+--------+--------+--------+--------'
  71. // ,--------+--------+--------+--------. ,--------+--------+--------+--------.
  72. ______ , ______ , ______ , ______ , ______ , ______ , ______ , ______
  73. // `--------+--------+--------+--------' `--------+--------+--------+--------'
  74. )
  75. };
  76. // a linked list of pending key events (press or release) which we haven't processed yet.
  77. struct _pending_key_t {
  78. uint16_t keycode;
  79. keyrecord_t record;
  80. struct _pending_key_t *next;
  81. };
  82. typedef struct _pending_key_t pending_key_t;
  83. // worst case is 10 down strokes and 1 up stroke before we can start disambiguating.
  84. #define RINGSIZE 11
  85. // a ring buffer and linked list to store pending key events (presses and releases).
  86. // (basically, this is a fixed-allocation linked list.)
  87. struct _kring_t {
  88. // the actual key events.
  89. pending_key_t items[RINGSIZE];
  90. // the index of the oldest item, or -1 if no items.
  91. int8_t ifirst;
  92. // the index of the most recently added item, or -1 if no items.
  93. int8_t ilast;
  94. // the number of items in the ring.
  95. uint8_t count;
  96. // the head of the linked list.
  97. pending_key_t *head;
  98. };
  99. typedef struct _kring_t kring_t;
  100. // safe accessor to the i-th item of the linked list (returns pointer or NULL).
  101. pending_key_t* kring_get(kring_t *ring, uint8_t i) {
  102. if (i >= ring->count) {
  103. return NULL;
  104. }
  105. uint8_t j = (ring->ifirst + i) % RINGSIZE;
  106. return &(ring->items[j]);
  107. }
  108. // return the last key in the list of buffered keys.
  109. pending_key_t* kring_last(kring_t *ring) {
  110. if (ring->count == 0) {
  111. return NULL;
  112. }
  113. return kring_get(ring, ring->count - 1);
  114. }
  115. // remove the oldest item from the ring (the head of the list).
  116. void kring_pop(kring_t *ring) {
  117. if (ring->count > 0) {
  118. ring->ifirst += 1;
  119. ring->ifirst %= RINGSIZE;
  120. ring->head = ring->head->next;
  121. ring->count -= 1;
  122. }
  123. }
  124. // add an item to the ring (append to the list).
  125. void kring_append(kring_t *ring, uint16_t keycode, keyrecord_t *record) {
  126. if (ring->count >= RINGSIZE) {
  127. // uh oh, we overflowed the capacity of our buffer :(
  128. return;
  129. }
  130. // if the ring is empty, insert at index 0.
  131. if (ring->count == 0) {
  132. ring->count += 1;
  133. ring->ifirst = 0;
  134. ring->ilast = 0;
  135. ring->head = &(ring->items[0]);
  136. }
  137. // else, append it onto the end.
  138. else {
  139. ring->count += 1;
  140. ring->ilast += 1;
  141. ring->ilast %= RINGSIZE;
  142. }
  143. // the index at which we should insert this item.
  144. int8_t i = ring->ilast;
  145. // insert the item.
  146. ring->items[i].keycode = keycode;
  147. ring->items[i].record.event = record->event;
  148. #ifndef NO_ACTION_TAPPING
  149. ring->items[i].record.tap = record->tap;
  150. #endif
  151. ring->items[i].next = NULL;
  152. // update the previous item to point to this item.
  153. if (ring->count > 1) {
  154. kring_get(ring, ring->count - 2)->next = &(ring->items[i]);
  155. }
  156. }
  157. kring_t g_pending;
  158. void matrix_init_user(void) {
  159. g_pending.ifirst = -1;
  160. g_pending.ilast = -1;
  161. g_pending.count = 0;
  162. g_pending.head = NULL;
  163. }
  164. void matrix_scan_user(void) {}
  165. /*
  166. a_ a-: emit a
  167. a_ b_ b- a-: emit SHIFT+b
  168. a_ b_ a- b-: emit a, b
  169. dual1down, dual1up -> norm1down, norm1up
  170. dual1down, norm2down, norm2up -> mod1down, norm2down, norm2up
  171. dual1down, norm2down, dual1up -> norm1down, norm2down, norm1up
  172. dual1down, dual2down, norm3down, norm3up -> mod1down, mod2down, norm3down, norm3up
  173. so, a dual key can't be disambiguated until the next keyup of a keydown (not including keyups from keys before it).
  174. */
  175. bool is_ambiguous_kc(uint16_t kc) {
  176. // See the MT() define: https://github.com/qmk/qmk_firmware/blob/master/quantum/quantum_keycodes.h#L642
  177. // See the QK_MOD_TAP case: https://github.com/qmk/qmk_firmware/blob/master/quantum/keymap_common.c#L134
  178. uint8_t mod = mod_config((kc >> 0x8) & 0x1F);
  179. return mod != 0;
  180. }
  181. bool is_down(pending_key_t *k) {
  182. return k->record.event.pressed;
  183. }
  184. bool is_up(pending_key_t *k) {
  185. return !is_down(k);
  186. }
  187. bool keys_match(pending_key_t *a, pending_key_t *b) {
  188. return a->record.event.key.col == b->record.event.key.col
  189. && a->record.event.key.row == b->record.event.key.row;
  190. }
  191. // both the down and corresponding upstroke of a keypress.
  192. struct _pending_pair_t {
  193. pending_key_t *down;
  194. pending_key_t *up;
  195. };
  196. typedef struct _pending_pair_t pending_pair_t;
  197. // returns true if this keydown event has a corresponding keyup event in the
  198. // list of buffered keys. also fills out 'p'.
  199. bool is_downup_pair(pending_key_t *k, pending_pair_t *p) {
  200. // first, make sure this event is keydown.
  201. if (!is_down(k)) {
  202. return false;
  203. }
  204. // now find its matching keyup.
  205. pending_key_t *next = k->next;
  206. while (next != NULL) {
  207. if (keys_match(k, next) && is_up(next)) {
  208. // found it.
  209. if (p != NULL) {
  210. p->down = k;
  211. p->up = next;
  212. }
  213. return true;
  214. }
  215. next = next->next;
  216. }
  217. // didn't find it.
  218. return false;
  219. }
  220. // given a QK_MOD_TAP keycode, return the KC_* version of the modifier keycode.
  221. uint16_t get_mod_kc(uint16_t keycode) {
  222. uint8_t mod = mod_config((keycode >> 0x8) & 0x1F);
  223. switch (mod) {
  224. case MOD_LCTL:
  225. return KC_LCTL;
  226. case MOD_RCTL:
  227. return KC_RCTL;
  228. case MOD_LSFT:
  229. return KC_LSFT;
  230. case MOD_RSFT:
  231. return KC_RSFT;
  232. case MOD_LALT:
  233. return KC_LALT;
  234. case MOD_RALT:
  235. return KC_RALT;
  236. case MOD_LGUI:
  237. return KC_LGUI;
  238. case MOD_RGUI:
  239. return KC_RGUI;
  240. default:
  241. // shrug? this shouldn't happen.
  242. return keycode;
  243. }
  244. }
  245. bool is_mod_kc(uint16_t keycode) {
  246. switch (keycode) {
  247. case QK_MODS ... QK_MODS_MAX:
  248. return true;
  249. default:
  250. return false;
  251. }
  252. }
  253. void interpret_as_mod(pending_pair_t *p) {
  254. // see https://github.com/qmk/qmk_firmware/issues/1503
  255. pending_key_t *k;
  256. k = p->down;
  257. if (k != NULL) {
  258. k->keycode = get_mod_kc(k->keycode);
  259. }
  260. k = p->up;
  261. if (k != NULL) {
  262. k->keycode = get_mod_kc(k->keycode);
  263. }
  264. }
  265. void interpret_as_normal(pending_pair_t *p) {
  266. pending_key_t *k;
  267. k = p->down;
  268. if (k != NULL) {
  269. k->keycode = k->keycode & 0xFF;
  270. }
  271. k = p->up;
  272. if (k != NULL) {
  273. k->keycode = k->keycode & 0xFF;
  274. }
  275. }
  276. void execute_head_and_pop(kring_t *ring) {
  277. pending_key_t *head = kring_get(ring, 0);
  278. uint16_t kc = head->keycode;
  279. if (is_mod_kc(kc)) {
  280. if (is_down(head)) {
  281. dprintf(" %s: mod down 0x%04X\n", __func__, kc);
  282. set_mods(get_mods() | MOD_BIT(kc));
  283. } else {
  284. dprintf(" %s: mod up 0x%04X\n", __func__, kc);
  285. set_mods(get_mods() & ~MOD_BIT(kc));
  286. }
  287. } else {
  288. if (is_down(head)) {
  289. dprintf(" %s: key down 0x%04X\n", __func__, kc);
  290. register_code16(kc);
  291. } else {
  292. dprintf(" %s: key up 0x%04X\n", __func__, kc);
  293. unregister_code16(kc);
  294. }
  295. }
  296. kring_pop(ring);
  297. }
  298. // try to figure out what the next pending keypress means.
  299. bool parse_next(kring_t *pending) {
  300. pending_pair_t p;
  301. pending_key_t *first = kring_get(pending, 0);
  302. if (!is_ambiguous_kc(first->keycode)) {
  303. // this pending key isn't ambiguous, so execute it.
  304. dprintf(" %s: found unambiguous key\n", __func__);
  305. execute_head_and_pop(pending);
  306. return true;
  307. } else if (is_ambiguous_kc(first->keycode) && is_up(first)) {
  308. dprintf(" %s: interpreting keyup as mod\n", __func__);
  309. p.down = NULL;
  310. p.up = first;
  311. interpret_as_mod(&p);
  312. execute_head_and_pop(pending);
  313. return true;
  314. } else if (is_downup_pair(first, &p)) {
  315. // 'first' was released before any other pressed key, so treat this as
  316. // a rolling series of normal key taps.
  317. dprintf(" %s: found down-up pair, interpreting as normal key\n", __func__);
  318. interpret_as_normal(&p);
  319. execute_head_and_pop(pending);
  320. return true;
  321. } else {
  322. // if another key was pressed and released while 'first' was held, then we
  323. // should treat it like a modifier.
  324. pending_key_t *next = first->next;
  325. while (next != NULL) {
  326. if (is_downup_pair(next, NULL)) {
  327. dprintf(" %s: found subsequent downup pair, interpreting head as mod\n", __func__);
  328. p.down = first;
  329. p.up = NULL;
  330. interpret_as_mod(&p);
  331. execute_head_and_pop(pending);
  332. return true;
  333. }
  334. next = next->next;
  335. }
  336. // we can't disambiguate 'first' yet. wait for another keypress.
  337. dprintf(" %s: can't disambiguate (yet)\n", __func__);
  338. return false;
  339. }
  340. }
  341. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  342. if (keycode == DEBUG) {
  343. return true;
  344. }
  345. if (g_pending.count == 0 && !is_ambiguous_kc(keycode)) {
  346. // we have no pending keys and this key isn't ambiguous, so we should
  347. // just let QMK take care of it.
  348. dprintf("%s: handled by qmk\n", __func__);
  349. return true;
  350. } else {
  351. dprintf("%s: got dual-role key\n", __func__);
  352. // append the keypress and then try parsing all pending keypresses.
  353. kring_append(&g_pending, keycode, record);
  354. while (g_pending.count > 0) {
  355. dprintf("%s: looping through %d keys...\n", __func__, g_pending.count);
  356. if (!parse_next(&g_pending)) {
  357. // one of our keypresses is ambiguous and we can't proceed until
  358. // we get further keypresses to disambiguate it.
  359. dprintf("%s: %d pending keys are ambiguous\n", __func__, g_pending.count);
  360. break;
  361. }
  362. }
  363. return false;
  364. }
  365. }