keymap.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /* Copyright 2020 Joshua Moses Diamond
  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. #include "version.h"
  18. #include <stdlib.h>
  19. #define RGB_LAYER_ACK_DURATION 500
  20. enum layers { _MACRO, _NUMPAD, _RGB, _FN };
  21. enum layer_base {
  22. LAYER_BASE = _MACRO,
  23. LAYER_BASE_END = _FN + 1,
  24. };
  25. enum custom_keycodes {
  26. HELLO = SAFE_RANGE,
  27. CH_CPNL, // AL Control Panel
  28. CH_ASST, // AL Context-aware Desktop Assistant
  29. CH_SUSP, // Suspend
  30. };
  31. // clang-format off
  32. const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  33. [_MACRO] = LAYOUT(
  34. A(S(KC_N)), HELLO, CH_SUSP, TO(_MACRO),
  35. KC_MPRV, KC_MPLY, KC_MNXT, TO(_NUMPAD),
  36. C(A(KC_COMM)), KC_F5, C(A(KC_DOT)), TO(_RGB),
  37. MO(_FN), CH_ASST, CH_CPNL),
  38. [_NUMPAD] = LAYOUT(
  39. KC_KP_7, KC_KP_8, KC_KP_9, KC_TRNS,
  40. KC_KP_4, KC_KP_5, KC_KP_6, KC_TRNS,
  41. KC_KP_1, KC_KP_2, KC_KP_3, KC_TRNS,
  42. KC_KP_0, KC_PDOT, KC_PENT),
  43. [_RGB] = LAYOUT(
  44. RGB_HUI, RGB_SAI, RGB_VAI, KC_TRNS,
  45. RGB_HUD, RGB_SAD, RGB_VAD, KC_TRNS,
  46. RGB_SPD, RGB_SPI, KC_NO, KC_TRNS,
  47. RGB_RMOD, RGB_TOG, RGB_MOD),
  48. [_FN] = LAYOUT(
  49. KC_TRNS, DEBUG, RESET, KC_TRNS,
  50. KC_NO, KC_NO, EEP_RST, KC_TRNS,
  51. KC_NO, KC_NO, KC_NO, KC_TRNS,
  52. KC_NO, KC_NO, KC_NO),
  53. };
  54. // clang-format on
  55. typedef enum layer_ack {
  56. ACK_NO = 0,
  57. ACK_YES,
  58. ACK_MEH,
  59. } layer_ack_t;
  60. #define LAYER_OFFSET 0
  61. const rgblight_segment_t PROGMEM _macro_layer[] = RGBLIGHT_LAYER_SEGMENTS({0, 1, HSV_TEAL});
  62. const rgblight_segment_t PROGMEM _numpad_layer[] = RGBLIGHT_LAYER_SEGMENTS({1, 1, HSV_TEAL});
  63. const rgblight_segment_t PROGMEM _rgb_layer[] = RGBLIGHT_LAYER_SEGMENTS({2, 1, HSV_TEAL});
  64. const rgblight_segment_t PROGMEM _fn_layer[] = RGBLIGHT_LAYER_SEGMENTS({0, 3, HSV_PURPLE});
  65. #define ACK_OFFSET 4
  66. const rgblight_segment_t PROGMEM _no_layer[] = RGBLIGHT_LAYER_SEGMENTS({0, 3, HSV_RED});
  67. const rgblight_segment_t PROGMEM _yes_layer[] = RGBLIGHT_LAYER_SEGMENTS({0, 3, HSV_GREEN});
  68. const rgblight_segment_t PROGMEM _meh_layer[] = RGBLIGHT_LAYER_SEGMENTS({0, 3, HSV_YELLOW});
  69. // clang-format on
  70. const rgblight_segment_t *const PROGMEM _rgb_layers[] = {
  71. [LAYER_OFFSET + 0] = _macro_layer,
  72. [LAYER_OFFSET + 1] = _numpad_layer,
  73. [LAYER_OFFSET + 2] = _rgb_layer,
  74. [LAYER_OFFSET + 3] = _fn_layer,
  75. [ACK_OFFSET + ACK_NO] = _no_layer,
  76. [ACK_OFFSET + ACK_YES] = _yes_layer,
  77. [ACK_OFFSET + ACK_MEH] = _meh_layer,
  78. [ACK_OFFSET + ACK_MEH + 1] = NULL
  79. };
  80. // clang-format off
  81. const uint8_t PROGMEM _n_rgb_layers = sizeof(_rgb_layers) / sizeof(_rgb_layers[0]) - 1;
  82. void clear_rgb_layers(void) {
  83. dprint("clear_rgb_layers()\n");
  84. for (uint8_t i = 0; i < _n_rgb_layers; i++) {
  85. rgblight_set_layer_state(i, false);
  86. }
  87. }
  88. void do_rgb_layers(layer_state_t state, uint8_t start, uint8_t end) {
  89. dprintf("start=%u, end=%u, LAYER_OFFSET=%u\n", start, end, LAYER_OFFSET);
  90. for (uint8_t i = start; i < end; i++) {
  91. bool is_on = layer_state_cmp(state, i);
  92. uint8_t rl = LAYER_OFFSET + i;
  93. dprintf("layer[%u]=%u, rl=%u\n", i, is_on, rl);
  94. rgblight_set_layer_state(rl, is_on);
  95. }
  96. }
  97. layer_state_t layer_state_set_user(layer_state_t state) {
  98. do_rgb_layers(state, LAYER_BASE, LAYER_BASE_END);
  99. return state;
  100. }
  101. void rgb_layer_ack(layer_ack_t n) {
  102. uint8_t layer = ACK_OFFSET + n;
  103. dprintf("rgb_layer_ack(%u) ==> %u\n", n, layer);
  104. rgblight_blink_layer(layer, RGB_LAYER_ACK_DURATION);
  105. }
  106. void rgb_layer_ack_yn(bool yn) { rgb_layer_ack(yn ? ACK_YES : ACK_NO); }
  107. void keyboard_post_init_user(void) {
  108. // Enable the LED layers
  109. rgblight_layers = _rgb_layers;
  110. do_rgb_layers(layer_state, LAYER_BASE, LAYER_BASE_END);
  111. }
  112. void shutdown_user() {
  113. clear_rgb_layers();
  114. rgblight_enable();
  115. rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
  116. rgblight_sethsv_noeeprom(HSV_RED);
  117. }
  118. void spidey_glow(void) {
  119. rgblight_enable();
  120. rgblight_mode(RGBLIGHT_MODE_RAINBOW_MOOD);
  121. rgblight_sethsv(255, 230, 128);
  122. }
  123. void eeconfig_init_user(void) { spidey_glow(); }
  124. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  125. if (record->event.pressed) {
  126. switch (keycode) {
  127. // Re-implement this here, but fix the persistence!
  128. case DEBUG:
  129. if (!debug_enable) {
  130. debug_enable = 1;
  131. } else if (!debug_keyboard) {
  132. debug_keyboard = 1;
  133. } else if (!debug_matrix) {
  134. debug_matrix = 1;
  135. } else {
  136. debug_enable = 0;
  137. debug_keyboard = 0;
  138. debug_matrix = 0;
  139. }
  140. uprintf("DEBUG: enable=%u, keyboard=%u, matrix=%u\n", debug_enable, debug_keyboard, debug_matrix);
  141. uprintln(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION ", Built on: " QMK_BUILDDATE);
  142. eeconfig_update_debug(debug_config.raw);
  143. return false;
  144. // clang-format off
  145. case CH_CPNL: host_consumer_send(AL_CONTROL_PANEL); return false;
  146. case CH_ASST: host_consumer_send(AL_ASSISTANT); return false;
  147. case CH_SUSP: tap_code16(LGUI(LSFT(KC_L))); return true;
  148. case HELLO: SEND_STRING("Hello, world!"); return true;
  149. // clang-format on
  150. }
  151. } else {
  152. switch (keycode) {
  153. case CH_CPNL:
  154. case CH_ASST:
  155. host_consumer_send(0);
  156. return false;
  157. }
  158. }
  159. return true;
  160. };
  161. void post_process_record_user(uint16_t keycode, keyrecord_t *record) {
  162. switch (keycode) {
  163. // Acks follow...
  164. case DEBUG:
  165. rgb_layer_ack_yn(debug_enable);
  166. break;
  167. case RGB_TOG:
  168. rgb_layer_ack_yn(rgblight_is_enabled());
  169. break;
  170. }
  171. }
  172. bool encoder_update_user(uint8_t index, bool clockwise) {
  173. switch (get_highest_layer(layer_state)) {
  174. case _RGB:
  175. if (index == 0) {
  176. if (clockwise) {
  177. rgblight_increase_hue();
  178. } else {
  179. rgblight_decrease_hue();
  180. }
  181. } else if (index == 1) {
  182. if (clockwise) {
  183. rgblight_increase_sat();
  184. } else {
  185. rgblight_decrease_sat();
  186. }
  187. } else if (index == 2) {
  188. if (clockwise) {
  189. rgblight_increase_val();
  190. } else {
  191. rgblight_decrease_val();
  192. }
  193. }
  194. break;
  195. default:
  196. if (index == 0) {
  197. tap_code16(C(S(clockwise ? KC_EQL : KC_MINS)));
  198. } else if (index == 1) {
  199. tap_code16(C(clockwise ? KC_EQL : KC_MINS));
  200. } else if (index == 2) {
  201. tap_code(clockwise ? KC_VOLU : KC_VOLD);
  202. }
  203. break;
  204. }
  205. return true;
  206. }