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.

394 lines
13 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 "dichotemy.h"
  4. #include "report.h"
  5. #include "pointing_device.h"
  6. // Each layer gets a name for readability, which is then used in the keymap matrix below.
  7. // The underscores don't mean anything - you can have a layer called STUFF or any other name.
  8. // Layer names don't all need to be of the same length, obviously, and you can also skip them
  9. // entirely and just use numbers.
  10. enum dichotemy_layers
  11. {
  12. _BS,
  13. _SF,
  14. _NM,
  15. _NS,
  16. _MS
  17. };
  18. #define LONGPRESS_COUNT 4
  19. enum dichotemy_keycodes
  20. {
  21. CK_1G = SAFE_RANGE,
  22. CK_BSPE,
  23. CK_QE,
  24. 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.
  25. NS_HYPH,
  26. NS_EQU,
  27. NUMKEY,
  28. SFTKEY,
  29. MOUSE,
  30. MS_BTN1,
  31. MS_BTN2
  32. //MS_BTN3
  33. };
  34. // Macro definitions for readability
  35. enum dichotemy_macros
  36. {
  37. VOLU,
  38. VOLD,
  39. ESCM
  40. };
  41. #define LONGPRESS_DELAY 150
  42. #define MAX_TOGGLE_LENGTH 300
  43. #define TAPPING_TOGGLE 1
  44. // Fillers to make layering more clear
  45. #define _______ KC_TRNS
  46. #define XXXXXXX KC_NO
  47. const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  48. [_BS] = { /* Base layout, nearly qwerty but with modifications because it's not a full keyboard. Obviously. */
  49. {CK_TE, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC },
  50. {NUMKEY, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, CK_QE },
  51. {SFTKEY, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, MOUSE },
  52. {XXXXXXX, XXXXXXX, XXXXXXX, KC_LCTL, KC_LALT, KC_LGUI, KC_RGUI, KC_RALT, KC_RCTL, XXXXXXX, XXXXXXX, XXXXXXX },
  53. {XXXXXXX, XXXXXXX, XXXXXXX, KC_LBRC, KC_LPRN, KC_QUOT, KC_SPC, KC_RPRN, KC_RBRC, XXXXXXX, XXXXXXX, XXXXXXX }
  54. },
  55. [_SF] = { /* Shifted layout, small changes (because angle brackets have been moved to thumb cluster buttons) */
  56. {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ },
  57. {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ },
  58. {_______, _______, _______, _______, _______, _______, _______, _______, NS_HYPH, KC_UNDS, _______, _______ },
  59. {XXXXXXX, XXXXXXX, XXXXXXX, _______, _______, _______, _______, _______, _______, XXXXXXX, XXXXXXX, XXXXXXX },
  60. {XXXXXXX, XXXXXXX, XXXXXXX, _______, KC_LABK, _______, _______, KC_RABK, _______, XXXXXXX, XXXXXXX, XXXXXXX }
  61. },
  62. [_NM] = { /* Number layout, basically the main function layer */
  63. {_______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, _______ },
  64. {_______, CK_1G, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, CK_BSPE },
  65. {_______, KC_F11, KC_F12, KC_F13, KC_F14, KC_F15, KC_F16, KC_F17, KC_F18, KC_F19, KC_F20, _______ },
  66. {XXXXXXX, XXXXXXX, XXXXXXX, _______, _______, _______, _______, _______, _______, XXXXXXX, XXXXXXX, XXXXXXX },
  67. {XXXXXXX, XXXXXXX, XXXXXXX, _______, _______, _______, _______, _______, _______, XXXXXXX, XXXXXXX, XXXXXXX }
  68. },
  69. [_NS] = { /* Shifted number/function layout, for per-key control. Only active when shift is held, and number is toggled or held */
  70. {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ },
  71. {_______, _______, _______, _______, _______, _______, _______, _______, _______, KC_PLUS, NS_EQU, _______ },
  72. {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ },
  73. {XXXXXXX, XXXXXXX, XXXXXXX, _______, _______, _______, _______, _______, _______, XXXXXXX, XXXXXXX, XXXXXXX },
  74. {XXXXXXX, XXXXXXX, XXXXXXX, _______, _______, _______, _______, _______, _______, XXXXXXX, XXXXXXX, XXXXXXX }
  75. },
  76. [_MS] = { /* Mouse layer, including buttons for clicking. */
  77. {_______, _______, _______, _______, _______, _______, KC_VOLU, KC_HOME, KC_PGUP, _______, _______, _______ },
  78. {_______, _______, _______, _______, _______, _______, _______, MS_BTN1, MS_BTN2, _______, _______, _______ },
  79. {_______, _______, _______, _______, _______, _______, KC_VOLD, KC_END, KC_PGDN, _______, _______, _______ },
  80. {XXXXXXX, XXXXXXX, XXXXXXX, _______, _______, _______, _______, KC_UP, _______, XXXXXXX, XXXXXXX, XXXXXXX },
  81. {XXXXXXX, XXXXXXX, XXXXXXX, _______, _______, _______, KC_LEFT, KC_DOWN, KC_RGHT, XXXXXXX, XXXXXXX, XXXXXXX }
  82. }
  83. };
  84. const uint16_t PROGMEM fn_actions[] = {
  85. };
  86. static uint16_t special_timers[LONGPRESS_COUNT] = {0xFFFF,0xFFFF,0xFFFF,0xFFFF};
  87. static bool special_key_states[LONGPRESS_COUNT] = {0,0,0,0};
  88. static uint16_t shift_timer;
  89. static uint16_t num_timer;
  90. static uint16_t mouse_timer;
  91. static bool shift_singular_key = false;
  92. static bool number_singular_key = false;
  93. static bool mouse_singular_key = false;
  94. static bool shift_held = false;
  95. static bool shift_suspended = false;
  96. report_mouse_t currentReport = {};
  97. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  98. //uint8_t layer;
  99. //layer = biton32(layer_state); // get the current layer //Or don't, I didn't use it.
  100. //custom layer handling for tri_layer,
  101. switch (keycode) {
  102. case NUMKEY:
  103. if (record->event.pressed) {
  104. num_timer = timer_read();
  105. number_singular_key = true;
  106. layer_invert(_NM);
  107. } else {
  108. if (timer_elapsed(num_timer) < MAX_TOGGLE_LENGTH && number_singular_key) {
  109. //do nothing, the layer has already been inverted
  110. } else {
  111. layer_invert(_NM);
  112. }
  113. }
  114. update_tri_layer(_NM, _SF, _NS);
  115. return false;
  116. break;
  117. //SHIFT is handled as LSHIFT in the general case - 'toggle' shoudl activate caps, while the layer is only active when shift is held.
  118. case SFTKEY:
  119. if (record->event.pressed) {
  120. shift_held = true;
  121. shift_suspended = false;
  122. shift_timer = timer_read();
  123. shift_singular_key = true;
  124. layer_on(_SF);
  125. register_code(KC_LSFT);
  126. } else {
  127. shift_held = false;
  128. if (timer_elapsed(shift_timer) < MAX_TOGGLE_LENGTH && shift_singular_key) {
  129. //this was basically a toggle, so activate/deactivate caps lock.
  130. SEND_STRING(SS_TAP(X_CAPSLOCK));
  131. }
  132. layer_off(_SF);
  133. unregister_code(KC_LSFT);
  134. }
  135. update_tri_layer(_NM, _SF, _NS);
  136. return false;
  137. break;
  138. //MOUSE layer needs to be handled the same way as NUMKEY, but differently from shift
  139. case MOUSE:
  140. if (record->event.pressed) {
  141. mouse_timer = timer_read();
  142. mouse_singular_key = true;
  143. layer_invert(_MS);
  144. } else {
  145. if (timer_elapsed(mouse_timer) < MAX_TOGGLE_LENGTH && number_singular_key){
  146. //do nothing, it was a toggle (and it's already been toggled)
  147. } else {
  148. layer_invert(_MS);
  149. }
  150. }
  151. return false;
  152. break;
  153. //Custom macros for strange keys with different long-tap behavior
  154. case CK_1G:
  155. if (shift_held && shift_suspended){
  156. register_code(KC_LSFT);
  157. shift_suspended = false;
  158. }
  159. shift_singular_key = false;
  160. number_singular_key = false;
  161. mouse_singular_key = false;
  162. if (record->event.pressed) {
  163. special_timers[CK_1G-SAFE_RANGE] = timer_read();
  164. } else {
  165. if (special_key_states[CK_1G-SAFE_RANGE]){
  166. //key was activated after longpress_delay, need to close those keycodes
  167. special_key_states[CK_1G-SAFE_RANGE] = 0;
  168. unregister_code(KC_GRAVE);
  169. } else {
  170. //key was not activated, return macro activating proper, pre-long-tap key
  171. SEND_STRING(SS_TAP(X_1));
  172. }
  173. special_timers[CK_1G-SAFE_RANGE] = 0xFFFF;
  174. }
  175. break;
  176. case CK_BSPE:
  177. if (shift_held && shift_suspended){
  178. register_code(KC_LSFT);
  179. shift_suspended = false;
  180. }
  181. shift_singular_key = false;
  182. number_singular_key = false;
  183. mouse_singular_key = false;
  184. if (record->event.pressed) {
  185. special_timers[CK_BSPE-SAFE_RANGE] = timer_read();
  186. } else {
  187. if (special_key_states[CK_BSPE-SAFE_RANGE]){
  188. //key was activated after longpress_delay, need to close those keycodes
  189. special_key_states[CK_BSPE-SAFE_RANGE] = 0;
  190. unregister_code(KC_ENTER);
  191. } else {
  192. //key was not activated, return macro activating proper, pre-long-tap key
  193. SEND_STRING(SS_TAP(X_BSLASH));
  194. }
  195. special_timers[CK_BSPE-SAFE_RANGE] = 0xFFFF;
  196. }
  197. break;
  198. case CK_QE:
  199. if (shift_held && shift_suspended){
  200. register_code(KC_LSFT);
  201. shift_suspended = false;
  202. }
  203. shift_singular_key = false;
  204. number_singular_key = false;
  205. mouse_singular_key = false;
  206. if (record->event.pressed) {
  207. special_timers[CK_QE-SAFE_RANGE] = timer_read();
  208. } else {
  209. if (special_key_states[CK_QE-SAFE_RANGE]){
  210. //key was activated after longpress_delay, need to close those keycodes
  211. special_key_states[CK_QE-SAFE_RANGE] = 0;
  212. unregister_code(KC_ENTER);
  213. } else {
  214. //key was not activated, return macro activating proper, pre-long-tap key
  215. SEND_STRING(SS_TAP(X_QUOTE));
  216. }
  217. special_timers[CK_QE-SAFE_RANGE] = 0xFFFF;
  218. }
  219. break;
  220. case CK_TE:
  221. if (shift_held && shift_suspended){
  222. register_code(KC_LSFT);
  223. shift_suspended = false;
  224. }
  225. if (record->event.pressed) {
  226. special_timers[CK_TE-SAFE_RANGE] = timer_read();
  227. } else {
  228. if (special_key_states[CK_TE-SAFE_RANGE]){
  229. //key was activated after longpress_delay, need to close those keycodes
  230. special_key_states[CK_TE-SAFE_RANGE] = 0;
  231. unregister_code(KC_ENTER);
  232. } else {
  233. //key was not activated, return macro activating proper, pre-long-tap key
  234. SEND_STRING(SS_TAP(X_TAB));
  235. }
  236. special_timers[CK_TE-SAFE_RANGE] = 0xFFFF;
  237. }
  238. break;
  239. //No-shift keys, they unregister the KC_LSFT code so they can send
  240. //unshifted values - but they don't change the bool. if any other
  241. //key is pressed and the bool is set, KC_LSFT is registered again.
  242. case NS_HYPH:
  243. if (record->event.pressed) {
  244. shift_suspended = true;
  245. unregister_code(KC_LSFT);
  246. register_code(KC_MINS);
  247. } else {
  248. unregister_code(KC_MINS);
  249. if (shift_held && shift_suspended){
  250. register_code(KC_LSFT);
  251. shift_suspended = false;
  252. }
  253. }
  254. break;
  255. case NS_EQU:
  256. if (record->event.pressed) {
  257. shift_suspended = true;
  258. unregister_code(KC_LSFT);
  259. register_code(KC_EQUAL);
  260. } else {
  261. unregister_code(KC_EQUAL);
  262. if (shift_held && shift_suspended){
  263. register_code(KC_LSFT);
  264. shift_suspended = false;
  265. }
  266. }
  267. break;
  268. //mouse buttons, for 1-3, to update the mouse report:
  269. case MS_BTN1:
  270. currentReport = pointing_device_get_report();
  271. if (record->event.pressed) {
  272. if (shift_held && shift_suspended){
  273. register_code(KC_LSFT);
  274. shift_suspended = false;
  275. }
  276. //update mouse report here
  277. currentReport.buttons |= MOUSE_BTN1; //MOUSE_BTN1 is a const defined in report.h
  278. } else {
  279. //update mouse report here
  280. currentReport.buttons &= ~MOUSE_BTN1;
  281. }
  282. pointing_device_set_report(currentReport);
  283. break;
  284. case MS_BTN2:
  285. currentReport = pointing_device_get_report();
  286. if (record->event.pressed) {
  287. if (shift_held && shift_suspended){
  288. register_code(KC_LSFT);
  289. shift_suspended = false;
  290. }
  291. //update mouse report here
  292. currentReport.buttons |= MOUSE_BTN2; //MOUSE_BTN2 is a const defined in report.h
  293. } else {
  294. //update mouse report here
  295. }
  296. pointing_device_set_report(currentReport);
  297. break;
  298. //there is a case for button 3, but that's handled in dichotemy.c, and this is being
  299. //disabled to avoid any conflict.
  300. /*case MS_BTN3:
  301. currentReport = pointing_device_get_report();
  302. if (record->event.pressed) {
  303. if (shift_held && shift_suspended){
  304. register_code(KC_LSFT);
  305. shift_suspended = false;
  306. }
  307. //update mouse report here
  308. currentReport.buttons |= MOUSE_BTN3; //MOUSE_BTN2 is a const defined in report.h
  309. } else {
  310. //update mouse report here
  311. }
  312. pointing_device_set_report(currentReport);
  313. break;*/
  314. //If any other key was pressed during the layer mod hold period,
  315. //then the layer mod was used momentarily, and should block latching
  316. //Additionally, if NS_ keys are in use, then shift may be held (but is
  317. //disabled for the unshifted keycodes to be send. Check the bool and
  318. //register shift as necessary.
  319. default:
  320. if (shift_held){
  321. register_code(KC_LSFT);
  322. }
  323. shift_singular_key = false;
  324. number_singular_key = false;
  325. mouse_singular_key = false;
  326. break;
  327. }
  328. return true;
  329. };
  330. void matrix_scan_user(void) {
  331. uint8_t layer = biton32(layer_state);
  332. for (uint8_t i = 0; i<LONGPRESS_COUNT; i++){
  333. if (timer_elapsed(special_timers[i]) >= LONGPRESS_DELAY && !special_key_states[i]){
  334. switch (i + SAFE_RANGE){
  335. case CK_1G:
  336. register_code(KC_GRAVE);
  337. break;
  338. case CK_BSPE:
  339. register_code(KC_ENTER);
  340. break;
  341. case CK_QE:
  342. register_code(KC_ENTER);
  343. break;
  344. case CK_TE:
  345. register_code(KC_ESCAPE);
  346. break;
  347. }
  348. special_key_states[i] = 1;
  349. }
  350. }
  351. switch (layer) {
  352. case _BS:
  353. set_led_off;
  354. break;
  355. case _NM:
  356. set_led_blue;
  357. break;
  358. case _SF:
  359. set_led_red;
  360. break;
  361. case _NS:
  362. set_led_green;
  363. break;
  364. default:
  365. break;
  366. }
  367. };