gourdo1.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. /* Copyright 2021 Jonavin Eng @Jonavin
  2. Copyright 2022 gourdo1 <jcblake@outlook.com>
  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. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #include QMK_KEYBOARD_H
  15. #include "gourdo1.h"
  16. #include "caps_word.h"
  17. #ifdef TD_LSFT_CAPSLOCK_ENABLE
  18. // Tap once for shift, twice for Caps Lock but only if Win Key in not disabled
  19. void dance_LSFT_each_tap(qk_tap_dance_state_t * state, void * user_data) {
  20. if (state -> count == 1 || keymap_config.no_gui) {
  21. register_code16(KC_LSFT);
  22. } else {
  23. register_code(KC_CAPS);
  24. }
  25. }
  26. void dance_LSFT_reset(qk_tap_dance_state_t * state, void * user_data) {
  27. if (state -> count == 1 || keymap_config.no_gui) {
  28. unregister_code16(KC_LSFT);
  29. } else {
  30. unregister_code(KC_CAPS);
  31. unregister_code16(KC_LSFT);
  32. }
  33. }
  34. // Tap Dance definitions
  35. qk_tap_dance_action_t tap_dance_actions[] = {
  36. // Tap once for shift, twice for Caps Lock
  37. [TD_LSFT_CAPSLOCK] = ACTION_TAP_DANCE_DOUBLE(KC_LSFT, KC_CAPS),
  38. [TD_LSFT_CAPS_WIN] = ACTION_TAP_DANCE_FN_ADVANCED(dance_LSFT_each_tap, NULL, dance_LSFT_reset),
  39. // Tap once for Escape, twice to reset to base layer
  40. [TD_ESC_BASELYR] = ACTION_TAP_DANCE_DUAL_ROLE(KC_ESC, _BASE),
  41. };
  42. #endif // TD_LSFT_CAPSLOCK_ENABLE
  43. // RGB NIGHT MODE
  44. #ifdef RGB_MATRIX_ENABLE
  45. static bool rgb_nightmode = false;
  46. // Turn on/off NUM LOCK if current state is different
  47. void activate_rgb_nightmode(bool turn_on) {
  48. if (rgb_nightmode != turn_on) {
  49. rgb_nightmode = !rgb_nightmode;
  50. }
  51. }
  52. bool get_rgb_nightmode(void) {
  53. return rgb_nightmode;
  54. }
  55. #endif // RGB_MATRIX_ENABLE
  56. // TIMEOUTS
  57. #ifdef IDLE_TIMEOUT_ENABLE
  58. static uint16_t timeout_timer = 0;
  59. static uint16_t timeout_counter = 0; //in minute intervals
  60. static uint16_t timeout_threshold = TIMEOUT_THRESHOLD_DEFAULT;
  61. uint16_t get_timeout_threshold(void) {
  62. return timeout_threshold;
  63. }
  64. void timeout_reset_timer(void) {
  65. timeout_timer = timer_read();
  66. timeout_counter = 0;
  67. };
  68. void timeout_update_threshold(bool increase) {
  69. if (increase && timeout_threshold < TIMEOUT_THRESHOLD_MAX) timeout_threshold++;
  70. if (!increase && timeout_threshold > 0) timeout_threshold--;
  71. };
  72. void timeout_tick_timer(void) {
  73. if (timeout_threshold > 0) {
  74. if (timer_elapsed(timeout_timer) >= 60000) { // 1 minute tick
  75. timeout_counter++;
  76. timeout_timer = timer_read();
  77. }
  78. #ifdef RGB_MATRIX_ENABLE
  79. if (timeout_threshold > 0 && timeout_counter >= timeout_threshold) {
  80. rgb_matrix_disable_noeeprom();
  81. }
  82. #endif
  83. } // timeout_threshold = 0 will disable timeout
  84. }
  85. #endif // IDLE_TIMEOUT_ENABLE
  86. #if defined(ALTTAB_SCROLL_ENABLE) || defined(IDLE_TIMEOUT_ENABLE) // timer features
  87. __attribute__((weak)) void matrix_scan_keymap(void) {}
  88. void matrix_scan_user(void) {
  89. #ifdef ALTTAB_SCROLL_ENABLE
  90. encoder_tick_alttabscroll();
  91. #endif
  92. #ifdef IDLE_TIMEOUT_ENABLE
  93. timeout_tick_timer();
  94. #endif
  95. matrix_scan_keymap();
  96. }
  97. #endif // ALTTAB_SCROLL_ENABLE or IDLE_TIMEOUT_ENABLE
  98. // Initialize variable holding the binary representation of active modifiers.
  99. uint8_t mod_state;
  100. // ============================================= PROCESS KEY CODES =============================================
  101. __attribute__((weak)) bool process_record_keymap(uint16_t keycode, keyrecord_t * record) {
  102. return true;
  103. }
  104. bool process_record_user(uint16_t keycode, keyrecord_t * record) {
  105. mod_state = get_mods();
  106. if (!process_record_keymap(keycode, record)) {
  107. return false;
  108. }
  109. if (!process_caps_word(keycode, record)) {
  110. return false;
  111. }
  112. // Your macros ...
  113. switch (keycode) {
  114. // DotCom domain macros
  115. case DOTCOM:
  116. if (record -> event.pressed) {
  117. SEND_STRING(".com");
  118. } else {
  119. // when keycode is released
  120. }
  121. break;
  122. case YAHOO:
  123. if (record -> event.pressed) {
  124. SEND_STRING("yahoo.com");
  125. } else {
  126. // when keycode is released
  127. }
  128. break;
  129. case OUTLOOK:
  130. if (record -> event.pressed) {
  131. SEND_STRING("outlook.com");
  132. } else {
  133. // when keycode is released
  134. }
  135. break;
  136. case GMAIL:
  137. if (record -> event.pressed) {
  138. SEND_STRING("gmail.com");
  139. } else {
  140. // when keycode is released
  141. }
  142. break;
  143. case HOTMAIL:
  144. if (record -> event.pressed) {
  145. SEND_STRING("hotmail.com");
  146. } else {
  147. // when keycode is released
  148. }
  149. break;
  150. /*
  151. case YAHOO:
  152. if (record -> event.pressed) SEND_STRING("yahoo.com");
  153. else unregister_code16(keycode);
  154. break;
  155. case OUTLOOK:
  156. if (record -> event.pressed) SEND_STRING("outlook.com");
  157. else unregister_code16(keycode);
  158. break;
  159. case GMAIL:
  160. if (record -> event.pressed) SEND_STRING("gmail.com");
  161. else unregister_code16(keycode);
  162. break;
  163. case HOTMAIL:
  164. if (record -> event.pressed) {
  165. SEND_STRING("hotmail.com");
  166. } else unregister_code16(keycode);
  167. break;
  168. case DOTCOM:
  169. if (record -> event.pressed) SEND_STRING(".com");
  170. else unregister_code16(keycode);
  171. break;
  172. */
  173. // Windows key lock
  174. case KC_WINLCK:
  175. if (record -> event.pressed) {
  176. keymap_config.no_gui = !keymap_config.no_gui; //toggle status
  177. } else unregister_code16(keycode);
  178. break;
  179. // Double Zero
  180. case KC_00:
  181. if (record -> event.pressed) {
  182. // when keycode KC_00 is pressed
  183. SEND_STRING("00");
  184. } else unregister_code16(keycode);
  185. break;
  186. // Treat Control+Space as if regular Space
  187. case KC_SPC: {
  188. // Initialize a boolean variable that keeps track of the space key status: registered or not?
  189. static bool spckey_registered;
  190. if (record -> event.pressed) {
  191. // Detect the activation of either ctrl keys
  192. if (mod_state & MOD_MASK_CTRL) {
  193. // First temporarily canceling both ctrls so that
  194. // ctrl isn't applied to the KC_SPC keycode
  195. del_mods(MOD_MASK_CTRL);
  196. register_code(KC_SPC);
  197. // Update the boolean variable to reflect the status of KC_SPC
  198. spckey_registered = true;
  199. // Reapplying modifier state so that the held ctrl key(s)
  200. // still work even after having tapped the Space key.
  201. set_mods(mod_state);
  202. return false;
  203. }
  204. } else { // on release of KC_SPC
  205. // In case KC_SPC is still being sent even after the release of KC_SPC
  206. if (spckey_registered) {
  207. unregister_code(KC_SPC);
  208. spckey_registered = false;
  209. return false;
  210. }
  211. }
  212. }
  213. break;
  214. // Treat Shift+Space as if regular Space
  215. case KC_SHIFTSPC: {
  216. // Initialize a boolean variable that keeps track of the space key status: registered or not?
  217. static bool spc2key_registered;
  218. if (record -> event.pressed) {
  219. // Detect the activation of either shift keys
  220. if (mod_state & MOD_MASK_SHIFT) {
  221. // First temporarily canceling both shifts so that
  222. // shift isn't applied to the KC_SPC keycode
  223. del_mods(MOD_MASK_SHIFT);
  224. register_code(KC_SPC);
  225. // Update the boolean variable to reflect the status of KC_SPC
  226. spc2key_registered = true;
  227. // Reapplying modifier state so that the held shift key(s)
  228. // still work even after having tapped the Space key.
  229. set_mods(mod_state);
  230. return false;
  231. }
  232. } else { // on release of KC_SPC
  233. // In case KC_SPC is still being sent even after the release of KC_SPC
  234. if (spc2key_registered) {
  235. unregister_code(KC_SPC);
  236. spc2key_registered = false;
  237. return false;
  238. }
  239. }
  240. }
  241. break;
  242. // Add INS as SHIFT-modified BackSpace key
  243. case KC_BSPC: {
  244. // Initialize a boolean variable that keeps track of the delete key status: registered or not?
  245. static bool inskey_registered;
  246. if (record -> event.pressed) {
  247. // Detect the activation of either shift keys
  248. if (mod_state & MOD_MASK_SHIFT) {
  249. // First temporarily canceling both shifts so that
  250. // shift isn't applied to the KC_INS keycode
  251. del_mods(MOD_MASK_SHIFT);
  252. register_code(KC_INS);
  253. // Update the boolean variable to reflect the status of KC_INS
  254. inskey_registered = true;
  255. // Reapplying modifier state so that the held shift key(s)
  256. // still work even after having tapped the Delete/Insert key.
  257. set_mods(mod_state);
  258. return false;
  259. }
  260. } else { // on release of KC_BSPC
  261. // In case KC_INS is still being sent even after the release of KC_BSPC
  262. if (inskey_registered) {
  263. unregister_code(KC_INS);
  264. inskey_registered = false;
  265. return false;
  266. }
  267. }
  268. }
  269. break;
  270. /* Add INS as SHIFT-modified DEL key
  271. case KC_DEL: {
  272. // Initialize a boolean variable that keeps track of the delete key status: registered or not?
  273. static bool inskey_registered;
  274. if (record->event.pressed) {
  275. // Detect the activation of either shift keys
  276. if (mod_state & MOD_MASK_SHIFT) {
  277. // First temporarily canceling both shifts so that
  278. // shift isn't applied to the KC_INS keycode
  279. del_mods(MOD_MASK_SHIFT);
  280. register_code(KC_INS);
  281. // Update the boolean variable to reflect the status of KC_INS
  282. inskey_registered = true;
  283. // Reapplying modifier state so that the held shift key(s)
  284. // still work even after having tapped the Delete/Insert key.
  285. set_mods(mod_state);
  286. return false;
  287. }
  288. } else { // on release of KC_DEL
  289. // In case KC_INS is still being sent even after the release of KC_DEL
  290. if (inskey_registered) {
  291. unregister_code(KC_INS);
  292. inskey_registered = false;
  293. return false;
  294. }
  295. }
  296. }
  297. break;
  298. */
  299. #ifdef IDLE_TIMEOUT_ENABLE
  300. case RGB_TOI:
  301. if (record -> event.pressed) {
  302. timeout_update_threshold(true);
  303. } else unregister_code16(keycode);
  304. break;
  305. case RGB_TOD:
  306. if (record -> event.pressed) {
  307. timeout_update_threshold(false); //decrease timeout
  308. } else unregister_code16(keycode);
  309. break;
  310. #endif // IDLE_TIMEOUT_ENABLE
  311. #ifdef RGB_MATRIX_ENABLE
  312. case RGB_NITE:
  313. if (record -> event.pressed) {
  314. rgb_nightmode = !rgb_nightmode;
  315. } else unregister_code16(keycode);
  316. break;
  317. #endif // RGB_MATRIX_ENABLE
  318. #ifdef EMOTICON_ENABLE
  319. case EMO_SHRUG:
  320. if (record -> event.pressed) SEND_STRING("`\\_(\"/)_/`");
  321. else unregister_code16(keycode);
  322. break;
  323. case EMO_CONFUSE:
  324. if (record -> event.pressed) SEND_STRING("(*_*)");
  325. else unregister_code16(keycode);
  326. break;
  327. case EMO_TEARS:
  328. if (record -> event.pressed) SEND_STRING("(T_T)");
  329. else unregister_code16(keycode);
  330. break;
  331. case EMO_NERVOUS:
  332. if (record -> event.pressed) SEND_STRING("(~_~;)");
  333. else unregister_code16(keycode);
  334. break;
  335. case EMO_JOY:
  336. if (record -> event.pressed) SEND_STRING("(^o^)");
  337. else unregister_code16(keycode);
  338. break;
  339. case EMO_SAD:
  340. if (record -> event.pressed) SEND_STRING(":'-(");
  341. else unregister_code16(keycode);
  342. break;
  343. #endif // EMOTICON_ENABLE
  344. #ifdef ALTTAB_SCROLL_ENABLE
  345. case KC_TSTOG:
  346. if (record -> event.pressed) encoder_toggle_alttabscroll();
  347. else unregister_code16(keycode);
  348. break;
  349. #endif // ALTTAB_SCROLL_ENABLE
  350. default:
  351. if (record -> event.pressed) {
  352. #ifdef RGB_MATRIX_ENABLE
  353. rgb_matrix_enable();
  354. #endif
  355. #ifdef IDLE_TIMEOUT_ENABLE
  356. timeout_reset_timer(); //reset activity timer
  357. #endif
  358. }
  359. break;
  360. }
  361. return true;
  362. };
  363. uint16_t get_tapping_term(uint16_t keycode, keyrecord_t * record) {
  364. switch (keycode) {
  365. case KC_SFTUP:
  366. return 300;
  367. case KC_RAISESPC:
  368. case KC_LOWERSPC:
  369. return 450;
  370. default:
  371. return TAPPING_TERM;
  372. }
  373. }
  374. // Turn on/off NUM LOCK if current state is different
  375. void activate_numlock(bool turn_on) {
  376. if (IS_HOST_LED_ON(USB_LED_NUM_LOCK) != turn_on) {
  377. tap_code(KC_NUMLOCK);
  378. }
  379. }
  380. // INITIAL STARTUP
  381. __attribute__((weak)) void keyboard_post_init_keymap(void) {}
  382. void keyboard_post_init_user(void) {
  383. keyboard_post_init_keymap();
  384. #ifdef STARTUP_NUMLOCK_ON
  385. activate_numlock(true); // turn on Num lock by default so that the numpad layer always has predictable results
  386. #endif // STARTUP_NUMLOC_ON
  387. #ifdef IDLE_TIMEOUT_ENABLE
  388. timeout_timer = timer_read(); // set inital time for ide timeout
  389. #endif
  390. }