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.

308 lines
15 KiB

  1. // Copyright 2022 Vino Rodrigues (@vinorodrigues)
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include QMK_KEYBOARD_H
  4. #include "specialk.h"
  5. #include "version.h"
  6. typedef union {
  7. uint32_t raw;
  8. struct {
  9. bool in_arrow_mode:1;
  10. #ifdef RGB_MATRIX_ENABLE
  11. bool rgb_disable_perkey:1;
  12. #ifndef ID61_DISABLE_UNDERGLOW
  13. bool rgb_disable_underglow:1;
  14. #endif // ID61_DISABLE_UNDERGLOW
  15. #endif // RGB_MATRIX_ENABLE
  16. };
  17. } user_config_t;
  18. enum {
  19. _BASE = 0,
  20. _FN1,
  21. _FN2,
  22. _FN3
  23. };
  24. enum {
  25. KB_ARRW = QK_KB_0, // toggle right modifiers are arrows feature
  26. KB_RSFT, // right shift or up arrow
  27. KB_RALT, // right alt or left arrow
  28. KB_RAPP, // menu or down arrow (Windows Menu)
  29. KB_RCOM, // right gui or left arrow (macOS Command)
  30. KB_ROPT, // right alt or down arrow (macOS Option)
  31. KB_RCTL, // right ctrl ot right arrow
  32. KB_VRSN // debug, type version
  33. };
  34. /* Special Keys */
  35. #define SK_LT1C LT(_FN1, KC_CAPS) // Layer Tap 1, i.e., Tap = Caps Lock, Hold = Layer 1
  36. #define SK_LT2A LT(_FN2, KC_APP) // Layer Tap 2, i.e., Tap = Menu, Hold = Layer 2
  37. /* key matrix */
  38. const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  39. /*
  40. *
  41. * Esc 1 2 3 4 5 6 7 8 9 0 - = Backspc
  42. *
  43. * Tab Q W E R T Y U I O P [ ] \
  44. *
  45. * *Caps* A S D F G H J K L ; ' Enter *Caps* => Tap = Caps Lock, Hold = Layer 1 (Fn1)
  46. *
  47. * Shift Z X C V B N M , . / Shift
  48. *
  49. * CtrlWin Alt Fn1 AltMnuCtl
  50. *
  51. */
  52. [_BASE] = LAYOUT_60_ansi(
  53. QK_GESC, 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,
  54. 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,
  55. SK_LT1C, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
  56. KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KB_RSFT,
  57. KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(_FN1), KB_RALT, KB_RAPP, KB_RCTL
  58. ),
  59. /*
  60. *
  61. * ' F1 F2 F3 F4 F5 F6 F7 F8 F9 F10F11F12 Del
  62. *
  63. * ArwMd TogHu+Sa+Br+Sp+PScHomEnd Ins
  64. *
  65. * ModHu-Sa-Br-Sp- PUp
  66. *
  67. * VerRstNKR PDn
  68. *
  69. *
  70. *
  71. */
  72. [_FN1] = LAYOUT_60_ansi(
  73. KC_GRV, 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_DEL,
  74. KB_ARRW, _______, KC_UP, _______, _______, RGB_TOG, RGB_HUI, RGB_SAI, RGB_VAI, RGB_SPI, KC_PSCR, KC_HOME, KC_END, KC_INS,
  75. _______, KC_LEFT, KC_DOWN, KC_RGHT, _______, RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD, RGB_SPD, _______, KC_PGUP, _______,
  76. _______, _______, _______, _______, KB_VRSN, QK_BOOT, NK_TOGG, _______, _______, _______, KC_PGDN, _______,
  77. _______, _______, _______, _______, _______, _______, _______, _______
  78. ),
  79. /*
  80. *
  81. *
  82. *
  83. *
  84. *
  85. *
  86. *
  87. *
  88. *
  89. *
  90. *
  91. */
  92. [_FN2] = LAYOUT_60_ansi(
  93. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
  94. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
  95. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
  96. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
  97. _______, _______, _______, _______, _______, _______, _______, _______
  98. ),
  99. [_FN3] = LAYOUT_60_ansi(
  100. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
  101. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
  102. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
  103. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
  104. _______, _______, _______, _______, _______, _______, _______, _______
  105. )
  106. };
  107. user_config_t user_config;
  108. #ifdef RGB_MATRIX_ENABLE
  109. /*
  110. * RGB Stuff
  111. */
  112. #define ID61_CAPS_LOCK_KEY_INDEX 32 // position of Caps Lock key
  113. #define ID61_CAPS_LOCK_MAX_BRIGHTNESS 0xFF
  114. #ifdef RGB_MATRIX_MAXIMUM_BRIGHTNESS
  115. #undef ID61_CAPS_LOCK_MAX_BRIGHTNESS
  116. #define ID61_CAPS_LOCK_MAX_BRIGHTNESS RGB_MATRIX_MAXIMUM_BRIGHTNESS
  117. #endif
  118. #define ID61_CAPS_LOCK_VAL_STEP 8
  119. #ifdef RGB_MATRIX_VAL_STEP
  120. #undef ID61_CAPS_LOCK_VAL_STEP
  121. #define ID61_CAPS_LOCK_VAL_STEP RGB_MATRIX_VAL_STEP
  122. #endif
  123. void ID61_update_rgb_mode(void) {
  124. uint8_t flags = LED_FLAG_ALL;
  125. if (user_config.rgb_disable_perkey
  126. #ifndef ID61_DISABLE_UNDERGLOW
  127. && user_config.rgb_disable_underglow
  128. #endif // ID61_DISABLE_UNDERGLOW
  129. ) {
  130. flags = 0; // All OFF Condition
  131. } else {
  132. if (user_config.rgb_disable_perkey) {
  133. #ifndef ID61_DISABLE_UNDERGLOW
  134. flags = LED_FLAG_UNDERGLOW | 0xF0;
  135. #else
  136. flags = 0xF0;
  137. #endif // ID61_DISABLE_UNDERGLOW
  138. }
  139. #ifndef ID61_DISABLE_UNDERGLOW
  140. if (user_config.rgb_disable_underglow) {
  141. flags = LED_FLAG_MODIFIER | LED_FLAG_KEYLIGHT | LED_FLAG_INDICATOR | 0xF0;
  142. }
  143. #endif // ID61_DISABLE_UNDERGLOW
  144. }
  145. if (flags == 0) {
  146. rgb_matrix_set_flags(0);
  147. rgb_matrix_set_color_all(HSV_OFF);
  148. } else {
  149. rgb_matrix_set_flags(flags);
  150. rgb_matrix_enable_noeeprom();
  151. }
  152. eeconfig_update_kb(user_config.raw); // write back to EEPROM
  153. }
  154. void ID61_get_rgb_mode(void) {
  155. user_config.raw = eeconfig_read_kb(); // read config from EEPROM
  156. ID61_update_rgb_mode();
  157. }
  158. void keyboard_post_init_user(void) {
  159. ID61_get_rgb_mode();
  160. }
  161. void eeconfig_init_user(void) {
  162. // EEPROM is getting reset!
  163. user_config.raw = 0;
  164. ID61_update_rgb_mode();
  165. }
  166. void rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {
  167. // Caps Lock key stuff
  168. if (host_keyboard_led_state().caps_lock) {
  169. uint8_t v = rgb_matrix_get_val();
  170. if (v < ID61_CAPS_LOCK_VAL_STEP) {
  171. v = ID61_CAPS_LOCK_VAL_STEP;
  172. } else if (v < (ID61_CAPS_LOCK_MAX_BRIGHTNESS - ID61_CAPS_LOCK_VAL_STEP)) {
  173. if (!user_config.rgb_disable_perkey) {
  174. v += ID61_CAPS_LOCK_VAL_STEP; // inc. by one more step than current brightness
  175. } // else leave as current brightness
  176. } else {
  177. v = ID61_CAPS_LOCK_MAX_BRIGHTNESS;
  178. }
  179. rgb_matrix_set_color(ID61_CAPS_LOCK_KEY_INDEX, v, v, v); // white, brightness adjusted
  180. } else if (user_config.rgb_disable_perkey) {
  181. rgb_matrix_set_color(ID61_CAPS_LOCK_KEY_INDEX, HSV_OFF); // off
  182. }
  183. }
  184. #endif // RGB_MATRIX_ENABLE
  185. /*
  186. * Extra keys and RGB Toggle handler
  187. */
  188. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  189. switch (keycode) {
  190. // handle RGB toggle key - this ensures caps lock always works
  191. #ifdef RGB_MATRIX_ENABLE
  192. case QK_BOOT:
  193. if (record->event.pressed) {
  194. rgb_matrix_set_color_all(RGB_MATRIX_MAXIMUM_BRIGHTNESS, 0, 0); // All red
  195. rgb_matrix_driver.flush();
  196. }
  197. return true;
  198. case RGB_TOG:
  199. /* roll through the LED modes
  200. * | Level | Per-key | Underglow |
  201. * |-------------|---------|-----------|
  202. * | 0 (default) | on | on |
  203. * | 1 | OFF | on |
  204. * | 2 | on | OFF |
  205. * | 3 | OFF | OFF |
  206. *
  207. * for ID61_DISABLE_UNDERGLOW
  208. * | Level | Per-key |
  209. * |-------------|---------|
  210. * | 0 (default) | on |
  211. * | 1 | OFF |
  212. */
  213. if (record->event.pressed) {
  214. if ( (!user_config.rgb_disable_perkey)
  215. #ifndef ID61_DISABLE_UNDERGLOW
  216. && (!user_config.rgb_disable_underglow)
  217. #endif // ID61_DISABLE_UNDERGLOW
  218. ) {
  219. user_config.rgb_disable_perkey = 1;
  220. #ifndef ID61_DISABLE_UNDERGLOW
  221. } else if ( user_config.rgb_disable_perkey && (!user_config.rgb_disable_underglow) ) {
  222. user_config.rgb_disable_perkey = 0;
  223. user_config.rgb_disable_underglow = 1;
  224. } else if ( (!user_config.rgb_disable_perkey) && user_config.rgb_disable_underglow ) {
  225. user_config.rgb_disable_perkey = 1;
  226. #endif // ID61_DISABLE_UNDERGLOW
  227. } else {
  228. user_config.rgb_disable_perkey = 0;
  229. #ifndef ID61_DISABLE_UNDERGLOW
  230. user_config.rgb_disable_underglow = 0;
  231. #endif // ID61_DISABLE_UNDERGLOW
  232. }
  233. ID61_update_rgb_mode();
  234. }
  235. return false;
  236. case EE_CLR:
  237. if (!record->event.pressed) { // on release
  238. ID61_get_rgb_mode();
  239. }
  240. return true; // let this one pass on
  241. #endif // RGB_MATRIX_ENABLE
  242. case KB_ARRW:
  243. if (record->event.pressed) {
  244. user_config.in_arrow_mode ^= 1;
  245. }
  246. return false;
  247. case KB_RSFT: return ID61_process_special_k(keycode, record, user_config.in_arrow_mode, KC_RSFT, KC_UP, KC_PGUP);
  248. case KB_RALT: return ID61_process_special_k(keycode, record, user_config.in_arrow_mode, KC_RALT, KC_LEFT, KC_HOME);
  249. case KB_RAPP: return ID61_process_special_k(keycode, record, user_config.in_arrow_mode, KC_APP, KC_DOWN, KC_PGDN);
  250. case KB_RCOM: return ID61_process_special_k(keycode, record, user_config.in_arrow_mode, KC_RGUI, KC_LEFT, KC_HOME);
  251. case KB_ROPT: return ID61_process_special_k(keycode, record, user_config.in_arrow_mode, KC_RALT, KC_DOWN, KC_PGDN);
  252. case KB_RCTL: return ID61_process_special_k(keycode, record, user_config.in_arrow_mode, KC_RCTL, KC_RIGHT, KC_END);
  253. // print firmware version
  254. case KB_VRSN:
  255. if (!get_mods()) {
  256. if (!record->event.pressed) {
  257. SEND_STRING(QMK_KEYBOARD ":" QMK_KEYMAP " (v" QMK_VERSION ")");
  258. }
  259. }
  260. return false;
  261. // Shift + Backspace = Delete, see: https://docs.qmk.fm/#/feature_advanced_keycodes?id=shift-backspace-for-delete
  262. case KC_BSPC: return ID61_backspace_special(keycode, record);
  263. default:
  264. return true; /* Process all other keycodes normally */
  265. }
  266. }