arkag.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. #include "arkag.h"
  2. // Start: Written by konstantin: vomindoraan
  3. #include <ctype.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. void send_unicode_hex_string(const char *str) {
  7. if (!str) { return; } // Saftey net
  8. while (*str) {
  9. // Find the next code point (token) in the string
  10. for (; *str == ' '; str++);
  11. size_t n = strcspn(str, " "); // Length of the current token
  12. char code_point[n+1];
  13. strncpy(code_point, str, n);
  14. code_point[n] = '\0'; // Make sure it's null-terminated
  15. // Normalize the code point: make all hex digits lowercase
  16. for (char *p = code_point; *p; p++) {
  17. *p = tolower(*p);
  18. }
  19. // Send the code point as a Unicode input string
  20. unicode_input_start();
  21. send_string(code_point);
  22. unicode_input_finish();
  23. str += n; // Move to the first ' ' (or '\0') after the current token
  24. }
  25. }
  26. // End: Written by konstantin: vomindoraan
  27. uint8_t current_os, mod_primary_mask, fade_delay;
  28. uint16_t flash_timer_one, flash_timer_two,
  29. fade_timer_one, fade_timer_two,
  30. active_timer_one, active_timer_two,
  31. elapsed = 0,
  32. num_extra_flashes_off = 0;
  33. Color underglow,
  34. flash_color,
  35. saved_color,
  36. hsv_none = {0,0,0},
  37. hsv_white = {0,0,127};
  38. flashState flash_state = no_flash;
  39. fadeState fade_state = add_fade;
  40. activityState state = boot;
  41. void set_color (Color new, bool update) {
  42. rgblight_sethsv_eeprom_helper(new.h, new.s, new.v, update);
  43. }
  44. void save_color(Color to_save) {
  45. saved_color = to_save;
  46. }
  47. void reset_color(void) {
  48. underglow = saved_color;
  49. }
  50. Color mod_color(Color current_color, bool should_add, uint8_t change_amount) {
  51. save_color(underglow);
  52. int addlim = 359 - change_amount;
  53. int sublim = change_amount;
  54. int leftovers;
  55. if (should_add) {
  56. if (current_color.h <= addlim) {
  57. current_color.h += change_amount;
  58. } else {
  59. leftovers = (359 + change_amount) % 359;
  60. current_color.h = 0 + leftovers;
  61. }
  62. } else {
  63. if (current_color.h >= sublim) {
  64. current_color.h -= change_amount;
  65. } else {
  66. leftovers = change_amount - current_color.h;
  67. current_color.h = 359 - leftovers;
  68. }
  69. }
  70. return current_color;
  71. }
  72. void reverse_fade (void) {
  73. if (fade_state == add_fade){
  74. fade_state = sub_fade;
  75. } else {
  76. fade_state = add_fade;
  77. }
  78. }
  79. void check_state (void) {
  80. static bool activated, deactivated, slept;
  81. switch (state) {
  82. case active:
  83. if (!activated) {
  84. fade_delay = LED_FADE_DELAY;
  85. reverse_fade();
  86. activated = true;
  87. deactivated = false;
  88. }
  89. active_timer_two = timer_read();
  90. elapsed = active_timer_two - active_timer_one;
  91. if (elapsed < INACTIVE_DELAY) {return;}
  92. state = inactive;
  93. return;
  94. case inactive:
  95. if (!deactivated) {
  96. fade_delay = LED_FADE_DELAY * 2;
  97. reverse_fade();
  98. deactivated = true;
  99. slept = false;
  100. activated = false;
  101. }
  102. active_timer_two = timer_read();
  103. elapsed = active_timer_two - active_timer_one;
  104. if (elapsed < SLEEP_DELAY) {return;}
  105. state = sleeping;
  106. return;
  107. case sleeping:
  108. if (!slept) {
  109. fade_delay = LED_FADE_DELAY * 6;
  110. reverse_fade();
  111. slept = true;
  112. deactivated = false;
  113. activated = false;
  114. }
  115. return;
  116. case boot:
  117. return;
  118. }
  119. }
  120. void fade_rgb (void) {
  121. static bool ran_once;
  122. if (flash_state != no_flash) {return;}
  123. if (state == boot) {return;}
  124. switch (fade_state) {
  125. case add_fade:
  126. if (!ran_once) {
  127. fade_timer_one = timer_read();
  128. ran_once = true;
  129. }
  130. fade_timer_two = timer_read();
  131. elapsed = fade_timer_two - fade_timer_one;
  132. if (elapsed < fade_delay) {return;}
  133. if (underglow.h == 359) {
  134. fade_state = sub_fade;
  135. return;
  136. }
  137. underglow.h = underglow.h + 1;
  138. set_color(underglow, false);
  139. // set_color_at(underglow, 0);
  140. fade_timer_one = fade_timer_two;
  141. return;
  142. case sub_fade:
  143. fade_timer_two = timer_read();
  144. elapsed = fade_timer_two - fade_timer_one;
  145. if (elapsed < fade_delay) {return;}
  146. if (underglow.h == 0) {
  147. fade_state = add_fade;
  148. return;
  149. }
  150. underglow.h = underglow.h - 1;
  151. set_color(underglow, false);
  152. // set_color_at(underglow, 0);
  153. fade_timer_one = fade_timer_two;
  154. return;
  155. }
  156. }
  157. void flash_rgb (void) {
  158. static bool ran_once;
  159. switch(flash_state) {
  160. case no_flash:
  161. return;
  162. case flash_off:
  163. if (!ran_once) {
  164. set_color(hsv_none, false);
  165. flash_timer_one = timer_read();
  166. ran_once = true;
  167. flash_state = flash_on;
  168. return;
  169. }
  170. flash_timer_two = timer_read();
  171. elapsed = flash_timer_two - flash_timer_one;
  172. if (elapsed >= LED_FLASH_DELAY) {
  173. set_color(hsv_none, false);
  174. flash_timer_one = timer_read();
  175. flash_state = flash_on;
  176. }
  177. return;
  178. case flash_on:
  179. flash_timer_two = timer_read();
  180. elapsed = flash_timer_two - flash_timer_one;
  181. if (elapsed >= LED_FLASH_DELAY) {
  182. set_color(flash_color, false);
  183. flash_timer_one = timer_read();
  184. if (num_extra_flashes_off > 0) {
  185. flash_state = flash_off;
  186. num_extra_flashes_off--;
  187. } else {
  188. set_color(underglow, false);
  189. flash_state = no_flash;
  190. ran_once = false;
  191. }
  192. }
  193. return;
  194. }
  195. }
  196. void set_os (uint8_t os, bool update) {
  197. current_os = os;
  198. if (update) {
  199. eeprom_update_byte(EECONFIG_USERSPACE, current_os);
  200. }
  201. switch (os) {
  202. case OS_MAC:
  203. set_unicode_input_mode(UC_OSX);
  204. underglow = (Color){ 300, 255, 255 };
  205. mod_primary_mask = MOD_GUI_MASK;
  206. break;
  207. case OS_WIN:
  208. set_unicode_input_mode(UC_WINC);
  209. underglow = (Color){ 180, 255, 255 };
  210. mod_primary_mask = MOD_CTL_MASK;
  211. break;
  212. case OS_NIX:
  213. set_unicode_input_mode(UC_LNX);
  214. underglow = (Color){ 60, 255, 255 };
  215. mod_primary_mask = MOD_CTL_MASK;
  216. break;
  217. default:
  218. underglow = (Color){ 0, 0, 255 };
  219. mod_primary_mask = MOD_CTL_MASK;
  220. }
  221. set_color(underglow, update);
  222. flash_color = underglow;
  223. flash_state = flash_off;
  224. num_extra_flashes_off = 1;
  225. }
  226. void tap_key(uint8_t keycode) {
  227. register_code(keycode);
  228. unregister_code(keycode);
  229. }
  230. // register GUI if Mac or Ctrl if other
  231. void pri_mod(bool press) {
  232. if (press) {
  233. if (current_os == OS_MAC) {
  234. register_code(KC_LGUI);
  235. } else {
  236. register_code(KC_LCTL);
  237. }
  238. } else {
  239. if (current_os == OS_MAC) {
  240. unregister_code(KC_LGUI);
  241. } else {
  242. unregister_code(KC_LCTL);
  243. }
  244. }
  245. }
  246. // register Ctrl if Mac or GUI if other
  247. void sec_mod(bool press) {
  248. if (press) {
  249. if (current_os == OS_MAC) {
  250. register_code(KC_LCTL);
  251. } else {
  252. register_code(KC_LGUI);
  253. }
  254. } else {
  255. if (current_os == OS_MAC) {
  256. unregister_code(KC_LCTL);
  257. } else {
  258. unregister_code(KC_LGUI);
  259. }
  260. }
  261. }
  262. void surround_type(uint8_t num_of_chars, uint16_t keycode, bool use_shift) {
  263. if (use_shift) {
  264. register_code(KC_LSFT);
  265. }
  266. for (int i = 0; i < num_of_chars; i++) {
  267. tap_key(keycode);
  268. }
  269. if (use_shift) {
  270. unregister_code(KC_LSFT);
  271. }
  272. for (int i = 0; i < (num_of_chars/2); i++) {
  273. tap_key(KC_LEFT);
  274. }
  275. }
  276. void long_keystroke(size_t num_of_keys, uint16_t keys[]) {
  277. for (int i = 0; i < num_of_keys-1; i++) {
  278. register_code(keys[i]);
  279. }
  280. tap_key(keys[num_of_keys-1]);
  281. for (int i = 0; i < num_of_keys-1; i++) {
  282. unregister_code(keys[i]);
  283. }
  284. }
  285. void dance_grv (qk_tap_dance_state_t *state, void *user_data) {
  286. if (state->count == 1) {
  287. tap_key(KC_GRV);
  288. } else if (state->count == 2) {
  289. surround_type(2, KC_GRAVE, false);
  290. } else {
  291. surround_type(6, KC_GRAVE, false);
  292. }
  293. }
  294. void dance_quot (qk_tap_dance_state_t *state, void *user_data) {
  295. if (state->count == 1) {
  296. tap_key(KC_QUOT);
  297. } else if (state->count == 2) {
  298. surround_type(2, KC_QUOTE, false);
  299. } else if (state->count == 3) {
  300. surround_type(2, KC_QUOTE, true);
  301. }
  302. }
  303. void dance_strk (qk_tap_dance_state_t *state, void *user_data) {
  304. if (state->count == 1) {
  305. surround_type(4, KC_TILDE, true);
  306. } else if (state->count == 2) {
  307. if (current_os == OS_MAC) {
  308. long_keystroke(3, (uint16_t[]){KC_LGUI, KC_LSFT, KC_4});
  309. } else if (current_os == OS_WIN) {
  310. long_keystroke(3, (uint16_t[]){KC_LGUI, KC_LSFT, KC_S});
  311. } else {
  312. return;
  313. }
  314. }
  315. }
  316. void dance_3 (qk_tap_dance_state_t *state, void *user_data) {
  317. if (state->count == 1) {
  318. tap_key(KC_3);
  319. } else if (state->count == 2) {
  320. send_unicode_hex_string("00E8");
  321. } else if (state->count == 3) {
  322. send_unicode_hex_string("00E9");
  323. }
  324. }
  325. void dance_c (qk_tap_dance_state_t *state, void *user_data) {
  326. if (state->count == 1) {
  327. tap_key(KC_C);
  328. } else if (state->count == 2) {
  329. send_unicode_hex_string("00E7");
  330. }
  331. }
  332. void matrix_init_user(void) {
  333. current_os = eeprom_read_byte(EECONFIG_USERSPACE);
  334. set_os(current_os, false);
  335. }
  336. void matrix_scan_user(void) {
  337. check_state();
  338. flash_rgb();
  339. fade_rgb();
  340. }
  341. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  342. switch (keycode) {
  343. case M_PMOD:
  344. if (record->event.pressed) {
  345. pri_mod(true);
  346. } else {
  347. pri_mod(false);
  348. }
  349. return false;
  350. case M_SMOD:
  351. if (record->event.pressed) {
  352. sec_mod(true);
  353. } else {
  354. sec_mod(false);
  355. }
  356. return false;
  357. case M_P_B:
  358. if (record->event.pressed) {
  359. if (current_os == OS_WIN) {
  360. SEND_STRING(SS_DOWN(X_LGUI) SS_TAP(X_PAUSE) SS_UP(X_LGUI));
  361. } else {
  362. }
  363. }
  364. return false;
  365. case M_C_A_D:
  366. if (record->event.pressed) {
  367. if (current_os == OS_WIN) {
  368. SEND_STRING(SS_DOWN(X_LCTRL) SS_DOWN(X_LALT) SS_TAP(X_DELETE) SS_UP(X_LALT) SS_UP(X_LCTRL));
  369. } else {
  370. }
  371. }
  372. return false;
  373. case M_CALC:
  374. if (record->event.pressed) {
  375. if (current_os == OS_WIN) {
  376. SEND_STRING(SS_TAP(X_CALCULATOR));
  377. } else if (current_os == OS_MAC) {
  378. SEND_STRING(SS_DOWN(X_LGUI) SS_TAP(X_SPACE) SS_UP(X_LGUI) "calculator" SS_TAP(X_ENTER));
  379. }
  380. }
  381. return false;
  382. case M_OS:
  383. if (record->event.pressed) {
  384. set_os((current_os+1) % _OS_COUNT, true);
  385. }
  386. return false;
  387. case M_LOD:
  388. if (record->event.pressed) {
  389. send_unicode_hex_string("0CA0 005F 005F 0CA0");
  390. }
  391. return false;
  392. case M_LENNY:
  393. if (record->event.pressed) {
  394. send_unicode_hex_string("0028 0020 0361 00B0 0020 035C 0296 0020 0361 00B0 0029");
  395. }
  396. return false;
  397. case M_TF:
  398. if (record->event.pressed) {
  399. send_unicode_hex_string("0028 256F 2035 0414 2032 0029 256F 5F61 253B 2501 253B");
  400. }
  401. return false;
  402. case M_UF:
  403. if (record->event.pressed) {
  404. send_unicode_hex_string("252C 2500 252C 30CE 0028 0020 00BA 0020 005F 0020 00BA 0020 30CE 0029");
  405. }
  406. return false;
  407. case M_SHRUG:
  408. if (record->event.pressed) {
  409. send_unicode_hex_string("00AF 005C 005F 0028 30C4 0029 005F 002F 00AF");
  410. }
  411. return false;
  412. case M_TM:
  413. if (record->event.pressed) {
  414. send_unicode_hex_string("2122");
  415. }
  416. return false;
  417. case M_REPO:
  418. if (record->event.pressed) {
  419. SEND_STRING("https://github.com/arkag/qmk_firmware/tree/master/keyboards/mechmini/v2/keymaps/arkag");
  420. }
  421. return false;
  422. case M_GGT:
  423. if (record->event.pressed) {
  424. SEND_STRING("@GrahamGoldenTech.com");
  425. }
  426. return false;
  427. case M_SNIPT:
  428. if (record->event.pressed) {
  429. surround_type(6, KC_GRAVE, false);
  430. pri_mod(true);
  431. tap_key(KC_V);
  432. pri_mod(false);
  433. tap_key(KC_RGHT);
  434. tap_key(KC_RGHT);
  435. tap_key(KC_RGHT);
  436. tap_key(KC_ENTER);
  437. }
  438. return false;
  439. case M_BOLD:
  440. if (record->event.pressed) {
  441. surround_type(4, KC_8, true);
  442. }
  443. return false;
  444. case M_ITAL:
  445. if (record->event.pressed) {
  446. surround_type(2, KC_8, true);
  447. }
  448. return false;
  449. case M_ULIN:
  450. if (record->event.pressed) {
  451. surround_type(4, KC_MINS, true);
  452. }
  453. return false;
  454. case KC_LSFT:
  455. if (record->event.pressed) {
  456. set_color(mod_color(underglow, true, 50), false);
  457. SEND_STRING(SS_DOWN(X_LSHIFT));
  458. } else {
  459. set_color(underglow, false);
  460. SEND_STRING(SS_UP(X_LSHIFT));
  461. }
  462. return false;
  463. case MEDIA:
  464. case LAZY:
  465. case KEEB:
  466. case RAISE:
  467. case LOWER:
  468. return true;
  469. default:
  470. if (record->event.pressed) {
  471. active_timer_one = timer_read();
  472. state = active;
  473. }
  474. return true;
  475. }
  476. }
  477. uint32_t layer_state_set_user(uint32_t state) {
  478. switch (biton32(state)) {
  479. case _LAZY:
  480. save_color(underglow);
  481. underglow = mod_color(underglow, true, 50);
  482. break;
  483. case _MEDIA:
  484. save_color(underglow);
  485. underglow = mod_color(underglow, true, 150);
  486. break;
  487. case _KEEB:
  488. save_color(underglow);
  489. underglow = mod_color(underglow, false, 150);
  490. break;
  491. case _LOWER:
  492. save_color(underglow);
  493. underglow = mod_color(underglow, false, 100);
  494. break;
  495. case _RAISE:
  496. save_color(underglow);
  497. underglow = mod_color(underglow, true, 100);
  498. break;
  499. default:
  500. reset_color();
  501. break;
  502. }
  503. set_color(underglow, false);
  504. return state;
  505. }
  506. //Tap Dance Definitions
  507. qk_tap_dance_action_t tap_dance_actions[] = {
  508. [TD_3_GRV_ACT] = ACTION_TAP_DANCE_FN (dance_3),
  509. [TD_C_CED] = ACTION_TAP_DANCE_FN (dance_c),
  510. [TD_GRV_3GRV] = ACTION_TAP_DANCE_FN (dance_grv),
  511. [TD_SING_DOUB] = ACTION_TAP_DANCE_FN (dance_quot),
  512. [TD_STRK_SHOT] = ACTION_TAP_DANCE_FN (dance_strk),
  513. [TD_HYPH_UNDR] = ACTION_TAP_DANCE_DOUBLE (KC_MINS, LSFT(KC_MINS)),
  514. [TD_BRCK_PARN_O] = ACTION_TAP_DANCE_DOUBLE (KC_LBRC, LSFT(KC_9)),
  515. [TD_BRCK_PARN_C] = ACTION_TAP_DANCE_DOUBLE (KC_RBRC, LSFT(KC_0)),
  516. [TD_LALT_RALT] = ACTION_TAP_DANCE_DOUBLE (KC_LALT, KC_RALT),
  517. };