You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

501 lines
16 KiB

  1. // this is the style you want to emulate.
  2. // This is the canonical layout file for the Quantum project. If you want to add another keyboard,
  3. #include "dichotomy.h"
  4. // Each layer gets a name for readability, which is then used in the keymap matrix below.
  5. // The underscores don't mean anything - you can have a layer called STUFF or any other name.
  6. // Layer names don't all need to be of the same length, obviously, and you can also skip them
  7. // entirely and just use numbers.
  8. enum dichotomy_layers {
  9. _BS,
  10. _SF,
  11. _NM,
  12. _NS,
  13. _MS
  14. };
  15. #define LONGPRESS_COUNT 4
  16. enum dichotomy_keycodes
  17. {
  18. CK_1G = SAFE_RANGE,
  19. CK_BSPE,
  20. CK_QE,
  21. CK_TE, //these 4 CK_XXXX keys are special "alternate long-press" keys controlled with unique timers. Make sure you understand them before you mess with them.
  22. NS_HYPH,
  23. NS_EQU,
  24. NUMKEY,
  25. SFTKEY,
  26. MOUKEY,
  27. MS_BTN1,
  28. MS_BTN2,
  29. MS_BTN3
  30. };
  31. #define CUSTOM_LONGPRESS 150
  32. #define CUSTOM_TOGGLE_TIME 300
  33. #define RED_BRIGHTNESS 3
  34. #define GREEN_BRIGHTNESS 2
  35. #define BLUE_BRIGHTNESS 2
  36. // Fillers to make layering more clear
  37. #define _______ KC_TRNS
  38. #define XXXXXXX KC_NO
  39. const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  40. [_BS] = LAYOUT( /* Base layout, nearly qwerty but with modifications because it's not a full keyboard. Obviously. */
  41. CK_TE, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC,
  42. NUMKEY, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, CK_QE,
  43. SFTKEY, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, MOUKEY,
  44. KC_LCTL, KC_LALT, KC_LGUI, KC_RGUI, KC_RALT, KC_RCTL,
  45. MS_BTN3, KC_LBRC, KC_LPRN, KC_SPC, KC_SPC, KC_RPRN, KC_RBRC, MS_BTN3
  46. ),
  47. [_SF] = LAYOUT( /* Shifted layout, small changes (because angle brackets have been moved to thumb cluster buttons) */
  48. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
  49. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
  50. _______, _______, _______, _______, _______, _______, _______, _______, NS_HYPH, KC_UNDS, _______, _______,
  51. _______, _______, _______, _______, _______, _______,
  52. _______, _______, KC_LABK, _______, _______, KC_RABK, _______, _______
  53. ),
  54. [_NM] = LAYOUT( /* Number layout, basically the main function layer */
  55. _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, _______,
  56. _______, CK_1G, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, CK_BSPE,
  57. _______, KC_F11, KC_F12, KC_F13, KC_F14, KC_F15, KC_F16, KC_F17, KC_F18, KC_F19, KC_F20, _______,
  58. _______, _______, _______, _______, _______, _______,
  59. _______, _______, _______, _______, _______, _______, _______, _______
  60. ),
  61. [_NS] = LAYOUT( /* Shifted number/function layout, for per-key control. Only active when shift is held, and number is toggled or held */
  62. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
  63. _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_PLUS, NS_EQU, _______,
  64. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
  65. _______, _______, _______, _______, _______, _______,
  66. _______, _______, _______, _______, _______, _______, _______, _______
  67. ),
  68. [_MS] = LAYOUT( /* Mouse layer, including buttons for clicking. */
  69. _______, _______, _______, _______, _______, _______, KC_VOLU, KC_HOME, KC_PGUP, _______, _______, _______,
  70. _______, _______, _______, _______, _______, _______, _______, MS_BTN1, MS_BTN2, _______, _______, _______,
  71. _______, _______, _______, _______, _______, _______, KC_VOLD, KC_END, KC_PGDN, _______, _______, _______,
  72. _______, _______, _______, _______, KC_UP, _______,
  73. _______, _______, _______, _______, KC_LEFT, KC_DOWN, KC_RGHT, _______
  74. )
  75. };
  76. static uint16_t special_timers[LONGPRESS_COUNT] = {0xFFFF,0xFFFF,0xFFFF,0xFFFF};
  77. static bool special_key_states[LONGPRESS_COUNT] = {0,0,0,0};
  78. static bool special_key_pressed[LONGPRESS_COUNT] = {0,0,0,0};
  79. static uint16_t shift_timer;
  80. static uint16_t num_timer;
  81. static uint16_t mouse_timer;
  82. static uint8_t red_timer;
  83. static uint8_t green_timer;
  84. static uint8_t blue_timer;
  85. static bool shift_singular_key = false;
  86. static bool number_singular_key = false;
  87. static bool mouse_singular_key = false;
  88. static bool capsLED = false;
  89. static bool shiftLED = false;
  90. static bool numLED = false;
  91. static bool mouseLED = false;
  92. static bool shift_held = false;
  93. static bool shift_suspended = false;
  94. report_mouse_t currentReport = {};
  95. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  96. //uint8_t layer;
  97. //layer = biton32(layer_state); // get the current layer //Or don't, I didn't use it.
  98. bool returnVal = true; //this is to determine if more key processing is needed.
  99. //custom layer handling for tri_layer,
  100. switch (keycode) {
  101. case NUMKEY:
  102. if (record->event.pressed) {
  103. num_timer = timer_read();
  104. number_singular_key = true;
  105. layer_invert(_NM);
  106. numLED = !numLED;
  107. } else {
  108. if (timer_elapsed(num_timer) < CUSTOM_TOGGLE_TIME && number_singular_key) {
  109. //do nothing, the layer has already been inverted
  110. } else {
  111. layer_invert(_NM);
  112. numLED = !numLED;
  113. }
  114. }
  115. update_tri_layer(_NM, _SF, _NS);
  116. returnVal = false;
  117. break;
  118. //SHIFT is handled as LSHIFT in the general case - 'toggle' shoudl activate caps, while the layer is only active when shift is held.
  119. case SFTKEY:
  120. if (record->event.pressed) {
  121. shift_held = true;
  122. shiftLED = true;
  123. shift_suspended = false;
  124. shift_timer = timer_read();
  125. shift_singular_key = true;
  126. layer_on(_SF);
  127. register_code(KC_LSFT);
  128. } else {
  129. shift_held = false;
  130. shiftLED = false;
  131. if (timer_elapsed(shift_timer) < CUSTOM_TOGGLE_TIME && shift_singular_key) {
  132. //this was basically a toggle, so activate/deactivate caps lock.
  133. SEND_STRING(SS_TAP(X_CAPSLOCK));
  134. capsLED = !capsLED;
  135. }
  136. layer_off(_SF);
  137. unregister_code(KC_LSFT);
  138. }
  139. update_tri_layer(_NM, _SF, _NS);
  140. returnVal = false;
  141. break;
  142. //MOUSE layer needs to be handled the same way as NUMKEY, but differently from shift
  143. case MOUKEY:
  144. if (record->event.pressed) {
  145. mouse_timer = timer_read();
  146. mouse_singular_key = true;
  147. layer_invert(_MS);
  148. mouseLED = !mouseLED;
  149. } else {
  150. if (timer_elapsed(mouse_timer) < CUSTOM_TOGGLE_TIME && mouse_singular_key){
  151. //do nothing, it was a toggle (and it's already been toggled)
  152. } else {
  153. layer_invert(_MS);
  154. mouseLED = !mouseLED;
  155. }
  156. }
  157. returnVal = false;
  158. break;
  159. //Custom macros for strange keys with different long-tap behavior
  160. case CK_1G:
  161. if (shift_held && shift_suspended){
  162. register_code(KC_LSFT);
  163. shift_suspended = false;
  164. }
  165. if (record->event.pressed) {
  166. special_timers[CK_1G-SAFE_RANGE] = timer_read();
  167. special_key_pressed[CK_1G-SAFE_RANGE] = 1;
  168. } else {
  169. if (special_key_states[CK_1G-SAFE_RANGE]){
  170. //key was activated after custom_longpress, need to close those keycodes
  171. special_key_states[CK_1G-SAFE_RANGE] = 0;
  172. unregister_code(KC_GRAVE);
  173. } else {
  174. if (special_key_pressed[CK_1G-SAFE_RANGE]){
  175. //key was not activated, return macro activating proper, pre-long-tap key
  176. SEND_STRING(SS_TAP(X_1));
  177. special_key_pressed[CK_1G-SAFE_RANGE] = 0;
  178. } else {
  179. //the short key was already sent, because another key was pressed.
  180. //Do nothing.
  181. }
  182. }
  183. }
  184. returnVal = false;
  185. break;
  186. case CK_BSPE:
  187. if (shift_held && shift_suspended){
  188. register_code(KC_LSFT);
  189. shift_suspended = false;
  190. }
  191. if (record->event.pressed) {
  192. special_timers[CK_BSPE-SAFE_RANGE] = timer_read();
  193. special_key_pressed[CK_BSPE-SAFE_RANGE] = 1;
  194. } else {
  195. if (special_key_states[CK_BSPE-SAFE_RANGE]){
  196. //key was activated after custom_longpress, need to close those keycodes
  197. special_key_states[CK_BSPE-SAFE_RANGE] = 0;
  198. unregister_code(KC_ENTER);
  199. } else {
  200. if (special_key_pressed[CK_BSPE-SAFE_RANGE]){
  201. //key was not activated, return macro activating proper, pre-long-tap key
  202. SEND_STRING(SS_TAP(X_BSLASH));
  203. special_key_pressed[CK_BSPE-SAFE_RANGE] = 0;
  204. } else {
  205. //the short key was already sent, because another key was pressed.
  206. //Do nothing.
  207. }
  208. }
  209. }
  210. returnVal = false;
  211. break;
  212. case CK_QE:
  213. if (shift_held && shift_suspended){
  214. register_code(KC_LSFT);
  215. shift_suspended = false;
  216. }
  217. if (record->event.pressed) {
  218. special_timers[CK_QE-SAFE_RANGE] = timer_read();
  219. special_key_pressed[CK_QE-SAFE_RANGE] = 1;
  220. } else {
  221. if (special_key_states[CK_QE-SAFE_RANGE]){
  222. //key was activated after custom_longpress, need to close those keycodes
  223. special_key_states[CK_QE-SAFE_RANGE] = 0;
  224. unregister_code(KC_ENTER);
  225. } else {
  226. if (special_key_pressed[CK_QE-SAFE_RANGE]){
  227. //the long-press key was not activated, return macro activating proper, pre-long-tap key
  228. SEND_STRING(SS_TAP(X_QUOTE));
  229. special_key_pressed[CK_QE-SAFE_RANGE] = 0;
  230. } else {
  231. //the short key was already sent, because another key was pressed.
  232. //Do nothing.
  233. }
  234. }
  235. }
  236. returnVal = false;
  237. break;
  238. case CK_TE:
  239. if (shift_held && shift_suspended){
  240. register_code(KC_LSFT);
  241. shift_suspended = false;
  242. }
  243. if (record->event.pressed) {
  244. special_timers[CK_TE-SAFE_RANGE] = timer_read();
  245. special_key_pressed[CK_TE-SAFE_RANGE] = 1;
  246. } else {
  247. if (special_key_states[CK_TE-SAFE_RANGE]){
  248. //key was activated after custom_longpress, need to close those keycodes
  249. special_key_states[CK_TE-SAFE_RANGE] = 0;
  250. unregister_code(KC_ESCAPE);
  251. } else {
  252. if (special_key_pressed[CK_TE-SAFE_RANGE]){
  253. //the long-press key was not activated, return macro activating proper, pre-long-tap key
  254. SEND_STRING(SS_TAP(X_TAB));
  255. special_key_pressed[CK_TE-SAFE_RANGE] = 0;
  256. } else {
  257. //the short key was already sent, because another key was pressed.
  258. //Do nothing.
  259. }
  260. }
  261. }
  262. returnVal = false;
  263. break;
  264. //No-shift keys, they unregister the KC_LSFT code so they can send
  265. //unshifted values - but they don't change the bool. if any other
  266. //key is pressed and the bool is set, KC_LSFT is registered again.
  267. case NS_HYPH:
  268. if (record->event.pressed) {
  269. shift_suspended = true;
  270. unregister_code(KC_LSFT);
  271. register_code(KC_MINS);
  272. } else {
  273. unregister_code(KC_MINS);
  274. if (shift_held && shift_suspended){
  275. register_code(KC_LSFT);
  276. shift_suspended = false;
  277. }
  278. }
  279. returnVal = false;
  280. break;
  281. case NS_EQU:
  282. if (record->event.pressed) {
  283. shift_suspended = true;
  284. unregister_code(KC_LSFT);
  285. register_code(KC_EQUAL);
  286. } else {
  287. unregister_code(KC_EQUAL);
  288. if (shift_held && shift_suspended){
  289. register_code(KC_LSFT);
  290. shift_suspended = false;
  291. }
  292. }
  293. returnVal = false;
  294. break;
  295. //mouse buttons, for 1-3, to update the mouse report:
  296. case MS_BTN1:
  297. currentReport = pointing_device_get_report();
  298. if (record->event.pressed) {
  299. if (shift_held && shift_suspended){
  300. register_code(KC_LSFT);
  301. shift_suspended = false;
  302. }
  303. //update mouse report here
  304. currentReport.buttons |= MOUSE_BTN1; //MOUSE_BTN1 is a const defined in report.h
  305. } else {
  306. //update mouse report here
  307. currentReport.buttons &= ~MOUSE_BTN1;
  308. }
  309. pointing_device_set_report(currentReport);
  310. returnVal = false;
  311. break;
  312. case MS_BTN2:
  313. currentReport = pointing_device_get_report();
  314. if (record->event.pressed) {
  315. if (shift_held && shift_suspended){
  316. register_code(KC_LSFT);
  317. shift_suspended = false;
  318. }
  319. //update mouse report here
  320. currentReport.buttons |= MOUSE_BTN2; //MOUSE_BTN2 is a const defined in report.h
  321. } else {
  322. //update mouse report here
  323. currentReport.buttons &= ~MOUSE_BTN2;
  324. }
  325. pointing_device_set_report(currentReport);
  326. returnVal = false;
  327. break;
  328. case MS_BTN3:
  329. currentReport = pointing_device_get_report();
  330. if (record->event.pressed) {
  331. if (shift_held && shift_suspended){
  332. register_code(KC_LSFT);
  333. shift_suspended = false;
  334. }
  335. //update mouse report here
  336. currentReport.buttons |= MOUSE_BTN3; //MOUSE_BTN3 is a const defined in report.h
  337. } else {
  338. //update mouse report here
  339. currentReport.buttons &= ~MOUSE_BTN3;
  340. }
  341. pointing_device_set_report(currentReport);
  342. returnVal = false;
  343. break;
  344. //Additionally, if NS_ keys are in use, then shift may be held (but is
  345. //disabled for the unshifted keycodes to be send. Check the bool and
  346. //register shift as necessary.
  347. default:
  348. if (shift_held){
  349. register_code(KC_LSFT);
  350. }
  351. break;
  352. }
  353. switch (keycode){
  354. case KC_BSPC:
  355. case KC_NO:
  356. case NUMKEY:
  357. case SFTKEY:
  358. case MOUKEY:
  359. //don't want to reset single key variables
  360. break;
  361. default:
  362. //If any other key was pressed during the layer mod hold period,
  363. //then the layer mod was used momentarily, and should block latching
  364. shift_singular_key = false;
  365. number_singular_key = false;
  366. mouse_singular_key = false;
  367. break;
  368. }
  369. switch (keycode){
  370. case KC_BSPC:
  371. case KC_NO:
  372. case NUMKEY:
  373. case SFTKEY:
  374. case MOUKEY:
  375. case MOUSE_BTN1:
  376. case MOUSE_BTN2:
  377. case MOUSE_BTN3:
  378. case KC_LCTL:
  379. case KC_LALT:
  380. case KC_LGUI:
  381. case KC_RCTL:
  382. case KC_RALT:
  383. case KC_RGUI:
  384. case CK_1G:
  385. case CK_BSPE:
  386. case CK_QE:
  387. case CK_TE:
  388. //Do nothing, don't want to trigger the timer key rollover
  389. break;
  390. default:
  391. //Now we're checking to see if any of the special timer keys are pressed
  392. //if so, we need to activate their short-press features
  393. if (record->event.pressed) {
  394. for (uint8_t i = 0; i<LONGPRESS_COUNT; i++){
  395. if ((!special_key_states[i]) && special_key_pressed[i]){
  396. switch (i + SAFE_RANGE){
  397. case CK_1G:
  398. SEND_STRING(SS_TAP(X_1));
  399. break;
  400. case CK_BSPE:
  401. SEND_STRING(SS_TAP(X_BSLASH));
  402. break;
  403. case CK_QE:
  404. SEND_STRING(SS_TAP(X_QUOTE));
  405. break;
  406. case CK_TE:
  407. SEND_STRING(SS_TAP(X_TAB));
  408. break;
  409. }
  410. special_key_pressed[i] = 0;
  411. }
  412. }
  413. } else {
  414. //do nothing, we don't want to trigger short presses on key releases.
  415. }
  416. break;
  417. }
  418. return returnVal;
  419. };
  420. void matrix_scan_user(void) {
  421. //uint8_t layer = biton32(layer_state);
  422. for (uint8_t i = 0; i<LONGPRESS_COUNT; i++){
  423. if ((timer_elapsed(special_timers[i]) >= CUSTOM_LONGPRESS) && (!special_key_states[i]) && special_key_pressed[i]){
  424. switch (i + SAFE_RANGE){
  425. case CK_1G:
  426. register_code(KC_GRAVE);
  427. break;
  428. case CK_BSPE:
  429. register_code(KC_ENTER);
  430. break;
  431. case CK_QE:
  432. register_code(KC_ENTER);
  433. break;
  434. case CK_TE:
  435. register_code(KC_ESCAPE);
  436. break;
  437. }
  438. special_key_pressed[i] = 0;
  439. special_key_states[i] = 1;
  440. }
  441. }
  442. if (shiftLED || capsLED){
  443. red_timer++;
  444. if (red_timer < RED_BRIGHTNESS){
  445. red_led_on();
  446. } else {
  447. red_timer = 0;
  448. red_led_off();
  449. }
  450. } else {
  451. red_timer = 0;
  452. red_led_off();
  453. }
  454. if (numLED){
  455. green_timer++;
  456. if (green_timer < GREEN_BRIGHTNESS){
  457. grn_led_on();
  458. } else {
  459. green_timer = 0;
  460. grn_led_off();
  461. }
  462. } else {
  463. green_timer = 0;
  464. grn_led_off();
  465. }
  466. if (mouseLED){
  467. blue_timer++;
  468. if (blue_timer < BLUE_BRIGHTNESS){
  469. blu_led_on();
  470. } else {
  471. blue_timer = 0;
  472. blu_led_off();
  473. }
  474. } else {
  475. blue_timer = 0;
  476. blu_led_off();
  477. }
  478. };