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.

425 lines
12 KiB

  1. /* Copyright 2021 Robert Verst <robert@verst.eu> @rverst
  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 "rverst.h"
  17. #include "print.h"
  18. #ifdef UNICODEMAP_ENABLE
  19. # include "unicode.h"
  20. #endif
  21. userspace_config_t userspace_config;
  22. uint8_t get_mode(void) {
  23. int m = 0;
  24. if (userspace_config.mode_1) {
  25. m += 1;
  26. }
  27. if (userspace_config.mode_2) {
  28. m += 2;
  29. }
  30. if (userspace_config.mode_3) {
  31. m += 4;
  32. }
  33. return m;
  34. }
  35. void set_mode(uint8_t mode, bool save) {
  36. dprintf("set_mode - mode: %d, save: %s\n", mode, save ? "true" : "false");
  37. switch_mode(mode);
  38. if (mode > 7) {
  39. mode = 7;
  40. }
  41. if (mode >= 4) {
  42. userspace_config.mode_3 = true;
  43. mode -= 4;
  44. } else {
  45. userspace_config.mode_3 = false;
  46. }
  47. if (mode >= 2) {
  48. userspace_config.mode_2 = true;
  49. mode -= 2;
  50. } else {
  51. userspace_config.mode_2 = false;
  52. }
  53. if (mode > 0) {
  54. userspace_config.mode_1 = true;
  55. } else {
  56. userspace_config.mode_1 = false;
  57. }
  58. if (save) {
  59. eeconfig_update_user(userspace_config.raw);
  60. }
  61. }
  62. void switch_mode(uint8_t mode) {
  63. #ifdef UNICODEMAP_ENABLE
  64. switch (mode) {
  65. case MAC_UNI:
  66. set_unicode_input_mode(UC_MAC);
  67. break;
  68. case WINDOWS_UNI:
  69. set_unicode_input_mode(UC_WINC);
  70. break;
  71. case LINUX_UNI:
  72. set_unicode_input_mode(UC_LNX);
  73. break;
  74. }
  75. #endif
  76. }
  77. bool is_unicode(uint8_t mode) { return (mode == MAC_UNI) || (mode == WINDOWS_UNI) || (mode == LINUX_UNI); }
  78. //**********************
  79. // keyboard_pre_init
  80. //**********************
  81. __attribute__((weak)) void keyboard_pre_init_keymap(void) {}
  82. void keyboard_pre_init_user(void) {
  83. userspace_config.raw = eeconfig_read_user();
  84. switch_mode(get_mode());
  85. keyboard_pre_init_keymap();
  86. }
  87. //************************
  88. // keyboard_post_init
  89. //************************
  90. __attribute__((weak)) void keyboard_post_init_keymap(void) {}
  91. void keyboard_post_init_user(void) {
  92. // debug_enable = true;
  93. // debug_matrix=true;
  94. // debug_keyboard = true;
  95. #ifdef RGBLIGHT_ENABLE
  96. #endif
  97. keyboard_post_init_keymap();
  98. }
  99. //**********************
  100. // eeconfig_init
  101. //**********************
  102. __attribute__((weak)) void eeconfig_init_keymap(void) {}
  103. void eeconfig_init_user(void) {
  104. userspace_config.raw = 0;
  105. eeconfig_update_user(userspace_config.raw);
  106. eeconfig_init_keymap();
  107. keyboard_init();
  108. }
  109. //**********************
  110. // process_record
  111. //**********************
  112. __attribute__((weak)) bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { return true; }
  113. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  114. if (!process_record_keymap(keycode, record)) {
  115. return false;
  116. }
  117. if (!record->event.pressed) {
  118. return true;
  119. }
  120. bool ls = (get_mods() | get_weak_mods()) & MOD_BIT(KC_LSFT);
  121. bool rs = (get_mods() | get_weak_mods()) & MOD_BIT(KC_RSFT);
  122. bool as = ls || rs;
  123. int mode = get_mode();
  124. switch (keycode) {
  125. case RV_SM0:
  126. case RV_SM0S:
  127. set_mode(MAC_UNI, keycode == RV_SM0S);
  128. return false;
  129. case RV_SM1:
  130. case RV_SM1S:
  131. set_mode(WINDOWS_UNI, keycode == RV_SM1S);
  132. return false;
  133. case RV_SM2:
  134. case RV_SM2S:
  135. set_mode(LINUX_UNI, keycode == RV_SM2S);
  136. return false;
  137. case RV_SM3:
  138. case RV_SM3S:
  139. set_mode(MAC, keycode == RV_SM3S);
  140. return false;
  141. case RV_SM4:
  142. case RV_SM4S:
  143. set_mode(WINDOWS, keycode == RV_SM4S);
  144. return false;
  145. case RV_SAYM:
  146. switch (mode) {
  147. case MAC:
  148. send_string("MacOS (normal)");
  149. break;
  150. case WINDOWS:
  151. send_string("Windows (normal)");
  152. break;
  153. case MAC_UNI:
  154. send_string("MacOS (unicode)");
  155. break;
  156. case WINDOWS_UNI:
  157. send_string("Windows (unicode)");
  158. break;
  159. case LINUX_UNI:
  160. send_string("Linux (unicode)");
  161. break;
  162. }
  163. return false;
  164. // Lock computer
  165. case RV_LOCK:
  166. if (mode == MAC || mode == MAC_UNI) {
  167. tap_code16(G(C(KC_Q)));
  168. } else if (mode == WINDOWS || mode == WINDOWS_UNI) {
  169. tap_code16(G(KC_L));
  170. }
  171. return false;
  172. // Screenshot
  173. case RV_SNAP:
  174. if (mode == MAC || mode == MAC_UNI) {
  175. if (ls) unregister_code(KC_LSFT);
  176. if (rs) unregister_code(KC_RSFT);
  177. tap_code16(G(S(as ? KC_4 : KC_5)));
  178. if (ls) register_code(KC_LSFT);
  179. if (rs) register_code(KC_RSFT);
  180. } else if (mode == WINDOWS || mode == WINDOWS_UNI) {
  181. tap_code16(G(S(KC_S)));
  182. }
  183. return false;
  184. // Umlauts - äÄöÖüÜ
  185. case RV_AUML:
  186. case RV_OUML:
  187. case RV_UUML:
  188. if (is_unicode(mode)) {
  189. if (keycode == RV_AUML) {
  190. if (as)
  191. send_unicode_string("Ä");
  192. else
  193. send_unicode_string("ä");
  194. } else if (keycode == RV_OUML) {
  195. if (as)
  196. send_unicode_string("Ö");
  197. else
  198. send_unicode_string("ö");
  199. } else if (keycode == RV_UUML) {
  200. if (as)
  201. send_unicode_string("Ü");
  202. else
  203. send_unicode_string("ü");
  204. }
  205. } else if (mode == MAC) {
  206. if (ls) unregister_code(KC_LSFT);
  207. if (rs) unregister_code(KC_RSFT);
  208. tap_code16(A(KC_U));
  209. if (as) register_code(KC_LSFT);
  210. if (keycode == RV_AUML) {
  211. tap_code(KC_A);
  212. } else if (keycode == RV_OUML) {
  213. tap_code(KC_O);
  214. } else if (keycode == RV_UUML) {
  215. tap_code(KC_U);
  216. }
  217. if (rs) {
  218. unregister_code(KC_LSFT);
  219. register_code(KC_RSFT);
  220. }
  221. } else if (mode == WINDOWS) {
  222. if (ls) unregister_code(KC_LSFT);
  223. if (rs) unregister_code(KC_RSFT);
  224. register_code(KC_RALT);
  225. tap_code(KC_1);
  226. if (keycode == RV_AUML) {
  227. if (as)
  228. tap_code(KC_4);
  229. else
  230. tap_code(KC_3);
  231. tap_code(KC_2);
  232. } else if (keycode == RV_OUML) {
  233. if (as) {
  234. tap_code(KC_5);
  235. tap_code(KC_3);
  236. } else {
  237. tap_code(KC_4);
  238. tap_code(KC_8);
  239. }
  240. } else if (keycode == RV_UUML) {
  241. if (as) {
  242. tap_code(KC_5);
  243. tap_code(KC_4);
  244. } else {
  245. tap_code(KC_2);
  246. tap_code(KC_9);
  247. }
  248. }
  249. unregister_code(KC_RALT);
  250. if (ls) register_code(KC_LSFT);
  251. if (rs) register_code(KC_RSFT);
  252. }
  253. return false;
  254. // Euro sign - €
  255. // with legacy-mode for MAC and WINDOWS without unicode support
  256. case RV_EUR:
  257. if (is_unicode(mode)) {
  258. send_unicode_string("");
  259. } else if (mode == MAC) {
  260. tap_code16(S(A(KC_2)));
  261. } else if (mode == WINDOWS) {
  262. register_code(KC_RALT);
  263. tap_code(KC_0);
  264. tap_code(KC_1);
  265. tap_code(KC_2);
  266. tap_code(KC_8);
  267. unregister_code(KC_RALT);
  268. }
  269. return false;
  270. // Sharp-S - ß
  271. // with legacy-mode for MAC and WINDOWS without unicode support
  272. case RV_SZ:
  273. if (is_unicode(mode)) {
  274. if (as) {
  275. send_unicode_string("§");
  276. } else {
  277. send_unicode_string("ß");
  278. }
  279. } else if (mode == MAC) {
  280. tap_code16(A(KC_S));
  281. } else if (mode == WINDOWS) {
  282. register_code(KC_RALT);
  283. tap_code(KC_2);
  284. tap_code(KC_2);
  285. tap_code(KC_5);
  286. unregister_code(KC_RALT);
  287. }
  288. return false;
  289. // Trademark - ™
  290. case RV_TM:
  291. if (is_unicode(mode)) {
  292. send_unicode_string("");
  293. }
  294. return false;
  295. // Registered trademark - ®
  296. case RV_RT:
  297. if (is_unicode(mode)) {
  298. send_unicode_string("®");
  299. }
  300. return false;
  301. // Copyright - ©
  302. case RV_CC:
  303. if (is_unicode(mode)) {
  304. send_unicode_string("©");
  305. }
  306. return false;
  307. // Degree - °
  308. case RV_DEG:
  309. if (is_unicode(mode)) {
  310. send_unicode_string("°");
  311. }
  312. return false;
  313. // Plus-minus - ±
  314. case RV_PM:
  315. if (is_unicode(mode)) {
  316. send_unicode_string("±");
  317. }
  318. return false;
  319. // Not equal - ≠
  320. case RV_UNEQ:
  321. if (is_unicode(mode)) {
  322. send_unicode_string("");
  323. }
  324. return false;
  325. // Superscript one - ¹
  326. case RV_SUP1:
  327. if (is_unicode(mode)) {
  328. send_unicode_string("¹");
  329. }
  330. return false;
  331. // Superscript two - ²
  332. case RV_SUP2:
  333. if (is_unicode(mode)) {
  334. send_unicode_string("²");
  335. }
  336. return false;
  337. // Superscript three - ³
  338. case RV_SUP3:
  339. if (is_unicode(mode)) {
  340. send_unicode_string("³");
  341. }
  342. return false;
  343. // vim equal split
  344. case RV_SEQU:
  345. tap_code16(C(KC_W));
  346. tap_code(KC_EQL);
  347. return false;
  348. // vim vertical split increase
  349. case RV_VINC:
  350. tap_code16(C(KC_W));
  351. tap_code(KC_4);
  352. tap_code16(S(KC_DOT));
  353. return false;
  354. // vim vertical split decrease
  355. case RV_VDEC:
  356. tap_code16(C(KC_W));
  357. tap_code(KC_4);
  358. tap_code16(S(KC_COMM));
  359. return false;
  360. // vim split increase
  361. case RV_SINC:
  362. tap_code16(C(KC_W));
  363. tap_code(KC_4);
  364. tap_code16(S(KC_EQL));
  365. return false;
  366. // vim split decrease
  367. case RV_SDEC:
  368. tap_code16(C(KC_W));
  369. tap_code(KC_4);
  370. tap_code(KC_MINS);
  371. return false;
  372. }
  373. return true;
  374. }