keymap.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /* Copyright 2019 Yonatan Zunger
  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 QMK_KEYBOARD_H
  17. enum custom_keycodes {
  18. // We provide special layer management keys:
  19. // GREEK triggers the Greek (aka "Front") layer, or the SHIFTGREEK layer when shift is held.
  20. // (Because we use Unicode, we need to implement shift-handling at the firmware level,
  21. // rather than the OS level like we do in the QWERTY layer)
  22. // CADET or GREEK+ALT triggers the Cadet (aka "Top") layer, or the SHIFTCADET layer when
  23. // shift is held.
  24. // LAYER_LOCK locks the "base" layer (i.e., QWERTY, GREEK, or CADET) to the value which is
  25. // pressed at the moment that it is being released. When a layer lock is set, the
  26. // analogous layer modifier key is reversed; e.g., if you lock the GREEK layer, then the
  27. // GREEK button bounces you back to QWERTY.
  28. //
  29. // We also parse the shift, alt, and caps lock keys to provide management of those which is
  30. // compatible with these various layers.
  31. KC_GREEK = SAFE_RANGE,
  32. KC_CADET,
  33. KC_LAYER_LOCK,
  34. };
  35. enum layers_keymap {
  36. _QWERTY = 0,
  37. _FUNCTION,
  38. _GREEK,
  39. _SHIFTGREEK,
  40. _CADET,
  41. _SHIFTCADET,
  42. };
  43. // This is so that H(xxxx) has the same width as _______, which makes the grids more legible.
  44. #define H(x) UC(0x##x)
  45. #define MO_FN MO(_FUNCTION)
  46. #define KC_LLCK KC_LAYER_LOCK
  47. // TODO: To generalize this, we want some #defines that let us specify how each key on the base
  48. // layer should map to the four special layers, and then use that plus the base layer definition to
  49. // autogenerate the keymaps for the other layers.
  50. // TODO: It would also be nice to be able to put the actual code points in here, rather than
  51. // numbers.
  52. // TODO: Also add checkmark and dengir.
  53. const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  54. /* The diagram below shows five rows for each key: from top to bottom, the QWERTY layer, the
  55. * GREEK layer, the SHIFTGREEK layer, the CADET layer, and the SHIFTCADET layer. (The single
  56. * diagram is to make it easier to see what goes where with this many layers!)
  57. *
  58. * ,----------------------------------------------------------------------------
  59. * | ` |F1 |F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10|F11|F12|HOM|END|PGU|PGD|MUT|BRK| QWERTY
  60. * | ` | ¹ | ² | ³ | ⁴ | ⁵ | ⁶ | ⁷ | ⁸ | ⁹ | ⁰ | ⁻ | ⁺ | ⁽ | ⁾ | | | | | GREEK
  61. * | ` | ₁ | ₂ | ₃ | ₄ | ₅ | ₆ | ₇ | ₈ | ₉ | ₀ | ₋ | ₊ | ₍ | ₎ | | | | | SHIFTGREEK
  62. * | ¬ | | | | | | | | | | | | | | | | | | | CADET
  63. * | ∅ | | | | | | | | | | | | | | | | | | | SHIFTCADET
  64. * |---------------------------------------------------------------------------|
  65. * | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | + | BKSPC |LCK| / | * | - |
  66. * | ` | | | | | | | | | | | ∝ | ∼ | BKSPC |LCK| ⊘ | ⊙ | ⊖ |
  67. * | ` | | | | | | | | | | | | ≁ | BKSPC |LCK| | ⊗ | |
  68. * | | | | | | | | | | | | | ± | BKSPC |LCK| | | |
  69. * | | | | | | | | | | | | | ∓ | BKSPC |LCK| | | |
  70. * |---------------------------------------------------------------------------|
  71. * | TAB | Q | W | E | R | T | Y | U | I | O | P | [ | ] | \ | 7 | 8 | 9 | |
  72. * | | θ | ω | ε | ρ | τ | ψ | υ | ι | ο | π | | | | | | | |
  73. * | | Θ | Ω | Ε | Ρ | Τ | Ψ | Υ | Ι | Ο | Π | | | | | | | |
  74. * | | ∧ | ∨ | ∩ | ∪ | ⊂ | ⊃ | ∀ | ∞ | ∃ | ∂ | ∈ | | | * | * | * | | [1]
  75. * | | ℚ | | | ℝ | ⊆ | ⊇ | | ℵ | ∄ | | ∉ | | | * | * | * | |
  76. * |-----------------------------------------------------------------------| + |
  77. * | CTRL | A | S | D | F | G | H | J | K | L | ; | ' | RET | 4 | 5 | 6 | ⊕ |
  78. * | CTRL | α | σ | δ | φ | γ | η | ϑ | κ | λ | ⋯ | ⋅ | RET | | | | |
  79. * | CTRL | Α | Σ | Δ | Φ | Γ | Η | | Κ | Λ | … | ∴ | RET | | | | |
  80. * | CTRL | ⟘ | ⊤ | ⊢ | ⊣ | ↑ | ↓ | ← | → | ↔ | | | RET | * | * | * | | [1]
  81. * | CTRL | Å | | ∇ | | ⇑ | ⇓ | ⇐ | ⇒ | ⇔ | | | RET | * | * | * | |
  82. * |-----------------------------------------------------------------------|---|
  83. * | SHIFT | Z | X | C | V | B | N | M | , | . | / |SHFT | ↑ | 1 | 2 | 3 | |
  84. * | SHIFT | ζ | ξ | χ | ς | β | ν | μ | ≪ | ≫ | ∫ |SHFT | | | | | |
  85. * | SHIFT | Ζ | Ξ | Χ | ✔ | Β | Ν | Μ | ≲ | ≳ | |SHFT | | | | | |
  86. * | SHIFT | | | ≠ | ≈ | ≡ | ≤ | ≥ | | | ÷ |SHFT | | * | * | * | | [1]
  87. * | SHIFT | ℤ | | ℂ | ≉ | ≢ | ℕ | | | | |SHFT | | * | * | * | |
  88. * |-----------------------------------------------------------------------|ENT|
  89. * | CTL | ALT| CMD| SPACE | α | β | γ | ← | ↓ | → | 0 | . | | [2]
  90. * | CTL | ALT| CMD| SPACE | α | β | γ | | | | | | |
  91. * | CTL | ALT| CMD| SPACE | α | β | γ | | | | | | |
  92. * | CTL | ALT| CMD| SPACE | α | β | γ | | | | | | |
  93. * | CTL | ALT| CMD| SPACE | α | β | γ | | | | | | |
  94. * `---------------------------------------------------------------------------'
  95. *
  96. * [1] CADET + numpad moves the mouse. SHIFT+CADET+NUMPAD moves it more quickly. CADET+5
  97. * clicks the mouse, and SHIFT+CADET+FIVE right-clicks.
  98. * [2] The Greek letters in this row are the three modifier keys (GREEK, CADET, FN),
  99. * not the Unicode Greek letters.
  100. */
  101. // NB: Using GESC for escape in the QWERTY layer as a temporary hack because I messed up the
  102. // switch on the KC_GRV key; change back to KC_ESC once this is fixed.
  103. [_QWERTY] = LAYOUT_hotswap(
  104. KC_GESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_HOME, KC_END, KC_PGUP, KC_PGDN, KC_MPLY, KC_BRK,
  105. KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_LLCK, KC_PSLS, KC_PAST, KC_PMNS,
  106. KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_P7, KC_P8, KC_P9,
  107. KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_P4, KC_P5, KC_P6, KC_PPLS,
  108. KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_P1, KC_P2, KC_P3,
  109. KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_GREEK,KC_CADET,MO_FN, KC_LEFT, KC_DOWN, KC_RGHT, KC_P0, KC_PDOT, KC_PENT),
  110. [_GREEK] = LAYOUT_hotswap(
  111. KC_GRV, H(00b9), H(00b2), H(00b3), H(2074), H(2075), H(2076), H(2077), H(2078), H(2079), H(2070), H(207b), H(207a), H(207d), H(207e), XXXXXXX, XXXXXXX, XXXXXXX, _______,
  112. KC_GRV, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, H(221d), H(223c), _______, _______, H(2298), H(2299), H(2296),
  113. _______, H(03b8), H(03c9), H(03b5), H(03c1), H(03c4), H(03c8), H(03c5), H(03b9), H(03bf), H(03c0), KC_LBRC, KC_RBRC, KC_BSLS, KC_P7, KC_P8, KC_P9,
  114. _______, H(03b1), H(03c3), H(03b4), H(03c6), H(03b3), H(03b7), H(03d1), H(03ba), H(03bb), H(22ef), H(22c5), _______, KC_P4, KC_P5, KC_P6, H(2295),
  115. _______, H(03b6), H(03be), H(03c7), H(03c2), H(03b2), H(03bd), H(03bc), H(226a), H(226b), H(222b), _______, _______, KC_P1, KC_P2, KC_P3,
  116. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_P0, KC_PDOT, KC_PENT),
  117. [_SHIFTGREEK] = LAYOUT_hotswap(
  118. KC_GRV, H(2081), H(2082), H(2083), H(2084), H(2085), H(2086), H(2087), H(2088), H(2089), H(2080), H(208b), H(208a), H(208d), H(208e), XXXXXXX, XXXXXXX, XXXXXXX, _______,
  119. KC_GRV, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, XXXXXXX, H(2241), _______, _______, XXXXXXX, H(2297), XXXXXXX,
  120. _______, H(0398), H(03a9), H(0395), H(03a1), H(03a4), H(03a8), H(03a5), H(0399), H(039f), H(03a0), KC_LBRC, KC_RBRC, KC_BSLS, KC_P7, KC_P8, KC_P9,
  121. _______, H(0391), H(03a3), H(0394), H(03a6), H(0393), H(0397), XXXXXXX, H(039a), H(039b), H(2026), H(2234), _______, KC_P4, KC_P5, KC_P6, H(2295),
  122. _______, H(0396), H(039e), H(03a7), H(2714), H(0392), H(039d), H(039c), H(2272), H(2273), XXXXXXX, _______, _______, KC_P1, KC_P2, KC_P3,
  123. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_P0, KC_PDOT, KC_PENT),
  124. // TODO: Add mouse keys to keypad.
  125. [_CADET] = LAYOUT_hotswap(
  126. H(00AC), KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______,
  127. KC_GRV, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, H(00b1), _______, _______, XXXXXXX, XXXXXXX, XXXXXXX,
  128. _______, H(2227), H(2228), H(2229), H(222a), H(2282), H(2283), H(2200), H(221e), H(2203), H(2202), H(2208), XXXXXXX, XXXXXXX, KC_P7, KC_P8, KC_P9,
  129. _______, H(22a5), H(22a4), H(22a2), H(22a3), H(2191), H(2193), H(2190), H(2192), H(2194), XXXXXXX, XXXXXXX, _______, KC_P4, KC_P5, KC_P6, XXXXXXX,
  130. _______, XXXXXXX, XXXXXXX, H(2260), H(2248), H(2261), H(2264), H(2265), XXXXXXX, XXXXXXX, H(00f7), _______, _______, KC_P1, KC_P2, KC_P3,
  131. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_P0, KC_PDOT, KC_PENT),
  132. [_SHIFTCADET] = LAYOUT_hotswap(
  133. H(2205), KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______,
  134. KC_GRV, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, H(2213), _______, _______, XXXXXXX, XXXXXXX, XXXXXXX,
  135. _______, H(211a), XXXXXXX, XXXXXXX, H(211d), H(2286), H(2287), XXXXXXX, H(2135), H(2204), XXXXXXX, H(2209), XXXXXXX, XXXXXXX, KC_P7, KC_P8, KC_P9,
  136. _______, H(212b), XXXXXXX, H(2207), XXXXXXX, H(21d1), H(21d3), H(21d0), H(21d2), H(21d4), XXXXXXX, XXXXXXX, _______, KC_P4, KC_P5, KC_P6, XXXXXXX,
  137. _______, H(2124), XXXXXXX, H(2102), H(2249), H(2262), H(2115), XXXXXXX, XXXXXXX, XXXXXXX, H(00f7), _______, _______, KC_P1, KC_P2, KC_P3,
  138. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_P0, KC_PDOT, KC_PENT),
  139. // Function layer is mostly for keyboard meta-control operations. Lots of this is just from the
  140. // default layout; TODO make it nicer, add Unicode mode switchers.
  141. [_FUNCTION] = LAYOUT_hotswap(
  142. RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MUTE, KC_VOLD, KC_VOLU, _______, _______, _______,
  143. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
  144. _______, RGB_TOG, _______, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, _______, _______, _______, _______, _______, _______, _______,
  145. BL_TOGG, _______, _______, UC_M_OS, UC_M_LN, UC_M_WI, UC_M_BS, UC_M_WC, _______, _______, _______, _______, _______, _______, _______, _______, _______,
  146. _______, _______, _______, BL_DEC, BL_TOGG, BL_INC, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
  147. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______),
  148. };
  149. // Layer bitfields.
  150. #define GREEK_LAYER (1UL << _GREEK)
  151. #define SHIFTGREEK_LAYER (1UL << _SHIFTGREEK)
  152. #define CADET_LAYER (1UL << _CADET)
  153. #define SHIFTCADET_LAYER (1UL << _SHIFTCADET)
  154. // The layers we don't touch.
  155. #define LAYER_MASK ~(GREEK_LAYER|SHIFTGREEK_LAYER|CADET_LAYER|SHIFTCADET_LAYER)
  156. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  157. // We track these persistent globals and manage them on our own, rather than trying to rely on
  158. // get_mods or the like, because this function is called *before* that's updated!
  159. static bool shift_held = false;
  160. static bool alt_held = false;
  161. static bool greek_held = false;
  162. static bool cadet_held = false;
  163. // These are where we remember the values of lock states.
  164. static bool shift_lock = false;
  165. static int layer_lock = _QWERTY;
  166. // Process any modifier key presses.
  167. if (keycode == KC_LSHIFT || keycode == KC_RSHIFT) {
  168. shift_held = record->event.pressed;
  169. } else if (keycode == KC_LALT || keycode == KC_RALT) {
  170. alt_held = record->event.pressed;
  171. } else if (keycode == KC_GREEK) {
  172. greek_held = record->event.pressed;
  173. } else if (keycode == KC_CADET) {
  174. cadet_held = record->event.pressed;
  175. }
  176. // Now let's transform these into the "cadet request" and "greek request."
  177. const bool greek_request = (greek_held && !alt_held);
  178. const bool cadet_request = (cadet_held || (greek_held && alt_held));
  179. // Now, handle the lock keys. We store next_layer_lock in a local variable so that we can
  180. // determine the layer to pick right now before we update layer_lock.
  181. int next_layer_lock = layer_lock;
  182. if (keycode == KC_CAPS) {
  183. // If we're in QWERTY mode, caps lock is already going to be managed by the host OS, but by
  184. // tracking it ourselves we can also usefully apply it to the GREEK and CADET layers.
  185. if (record->event.pressed) {
  186. shift_lock = !shift_lock;
  187. }
  188. } else if (keycode == KC_LAYER_LOCK) {
  189. if (record->event.pressed) {
  190. if (cadet_request) {
  191. next_layer_lock = _CADET;
  192. } else if (greek_request) {
  193. next_layer_lock = _GREEK;
  194. } else {
  195. next_layer_lock = _QWERTY;
  196. }
  197. }
  198. }
  199. // OK! Now we know which buttons are being held, and the current and upcoming states of the locks.
  200. // We can compute our new base layer. Remember that the CADET and GREEK keys act as their own
  201. // antonyms if they match the layer lock -- e.g., if you have CADET locked, then CADET+X generates
  202. // QWERTY-X.
  203. int base_layer;
  204. if (cadet_request) {
  205. base_layer = (layer_lock == _CADET ? _QWERTY : _CADET);
  206. } else if (greek_request) {
  207. base_layer = (layer_lock == _GREEK ? _QWERTY : _GREEK);
  208. } else {
  209. base_layer = layer_lock;
  210. }
  211. const bool shifted = (shift_held != shift_lock);
  212. int actual_layer;
  213. if (base_layer == _CADET) {
  214. actual_layer = (shifted ? _SHIFTCADET : _CADET);
  215. } else if (base_layer == _GREEK) {
  216. actual_layer = (shifted ? _SHIFTGREEK : _GREEK);
  217. } else {
  218. // We don't do shifting for the QWERTY layer, since for that we emit USB HID codes and shifting
  219. // is managed by the host OS.
  220. actual_layer = _QWERTY;
  221. }
  222. // And now we can update the layer lock and the actual firmware layer selector.
  223. layer_lock = next_layer_lock;
  224. layer_state_t new_layer_state = (layer_state & LAYER_MASK) | (1UL << actual_layer);
  225. if (new_layer_state != layer_state) {
  226. layer_state_set(new_layer_state);
  227. }
  228. // TODO: We can update LED states based on shift_lock (caps), layer_lock (layer lock), and
  229. // base_layer (base layer).
  230. return true;
  231. }