unicode_macros.c 80 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349
  1. /*
  2. * License (GPL):
  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. * Author: © 2019, 2020 by Jos Boersema
  14. *
  15. */
  16. /* This file contains mostly the Unicode and special macros.
  17. It contains the function: process_record_user(...)
  18. */
  19. #include "./unicode_macros.h"
  20. #include "./unicode_weurope.h"
  21. // Definition of ƒ (Dutch currency symbol).
  22. // Best changed in user_config.h, if you like a Euro symbol instead.
  23. //
  24. # ifndef UNICODE_CURRENCY // Prior optional definition in user_config.h
  25. # define UNICODE_CURRENCY 0x0192 // Hex number. The unicode hex number for position ƒ in the default keymap.
  26. # endif
  27. //
  28. // 🛠
  29. #define CS_USER_DEFINED 0x1F6E0 // Hammer & wrench (place holder).
  30. #define DIV10POINT TRUE // suggest to function write_number, to divide by 10 and print as a fraction: N.N
  31. // Gives Unicode code points to the relevant QMK functions.
  32. // Handles Dvorak 'descramble' Unicode mode, if compiled (only tested on Linux).
  33. void unicode_hex2output (long unsigned int unshifted, long unsigned int shifted) {
  34. long unsigned int input; // which argument to work on
  35. # ifdef DVORAK_DESCRAMBLE // Do the letter descramble if needed.
  36. char output[10]; // will hold the ascii for output
  37. int index; // count backwards 'to left' in the string
  38. long unsigned int bitmove; // move computation to next digit.
  39. long unsigned int work; // temporary value for computation
  40. # endif
  41. // What to work on
  42. if(shift_ison) input = shifted; // Trying to get everything possible here in this function, to reduce firmware size.
  43. else input = unshifted;
  44. # ifndef DVORAK_DESCRAMBLE // Only normal mode
  45. register_unicode ( (uint32_t) input ) ;
  46. # else
  47. if(_FULL_ != alternate){
  48. register_unicode ( (uint32_t) input ) ; // normal Unicode mode
  49. }else{ // Special Dvorak-descramble mode: 0-9=0-9, a=a, b=n, c=i, d=h, e=d, f=y
  50. // Take the hex value 4 bits at a time, starting with the least significant, convert to ascii, store
  51. index = 9;
  52. output[index] = '\0'; // terminator
  53. bitmove = 0x1;
  54. while ((work = (input / bitmove)) && (index >= 0)) {
  55. index --;
  56. work &= 0xF;
  57. if (work < 0xA){ // numbers
  58. output[index] = work + 0x30; // pad to ASCII
  59. }else{ // alphas
  60. if (0xA == work) output[index] = 'a';
  61. if (0xB == work) output[index] = 'n';
  62. if (0xC == work) output[index] = 'i';
  63. if (0xD == work) output[index] = 'h';
  64. if (0xE == work) output[index] = 'd';
  65. if (0xF == work) output[index] = 'y';
  66. }
  67. bitmove *= 0x10; // next digit
  68. }
  69. SEND_STRING ( SS_DOWN(X_LCTRL) SS_DOWN(X_LSHIFT) "f" SS_UP(X_LSHIFT) SS_UP(X_LCTRL) ); // lead-in for Unicode on Linux, 'descramble' mode
  70. send_string (output + index); // pointer to argument with formatted string
  71. SEND_STRING ( " " ); // Ends the Unicode numerical input mode
  72. }
  73. # endif // DVORAK_DESCRAMBLE mode for that Base layer & mode setting is compiled in
  74. }
  75. // Wrapper for unicode keys that do have the same on shift.
  76. void unicode_hex2output_single (long unsigned int either) {
  77. unicode_hex2output (either, either);
  78. }
  79. // Required by QMK Unicode
  80. const uint32_t PROGMEM unicode_map[] = {
  81. };
  82. // Macro name definitions. The Unicode layers _ACC, _DRA and _BON are defined here,
  83. // because the Unicode map system does not have enough space (at time of this programming, year 2020).
  84. enum custom_keycodes {
  85. // Macro, allowing the upper left button to switch to either _DEF_BASE base layer, or the _ALT_BASE base layer.
  86. // Alternate is set on/half/off in the _RAR layer. The word "base" is used to avoid "default," because the default
  87. // layer system call DF() is not being used.
  88. CTO_BASE = SAFE_RANGE, // 'C' for costum, "TO" for to, "BASE" for chosen base layer
  89. OTHER_BASE, // cycles modes: use _DEF_BASE, _ALT_BASE. For “dvorak²” layout (descramble) compile option, there is a third mode.
  90. # if defined(BASE_NUMPAD__ALT_BASE)
  91. OTHER_BASE_GO, // Like OTHER_BASE, but also immediately switches to the other BASE layer.
  92. # endif
  93. CTO_NUMS, // activates number-symbols layer, taking into account the dual layout mode
  94. CTO_ACCE, // accented ''
  95. CTO_DRAW, // drawings ''
  96. # ifndef CHOLTAP_ACCE_NOP
  97. CHOLTAP_ACCE, // Go to accented layer, or others in combination with other keys.
  98. # endif
  99. // Keys can be pressed together for a separate layer (like 'adjust layer' on the Planck).
  100. DUO_HOLD,
  101. CHOLTAP_RSHFT, // Go to _FUN layer, or shift modifier.
  102. CHOLTAP_LSHFT, // Go to <configurable> layer, or shift modifier.
  103. CHOLTAP_LAYR, // Go to _RAR layer, or right arrow
  104. // Shifts which on tap produce a key
  105. RSFT_TILDE,
  106. LSFT_DASH,
  107. // Special macro to make F-keys one-shot or not.
  108. _FUN_STAY,
  109. // Layer toggle to be guaranteed on up-key, therefore macro definition here.
  110. _MOV_UP,
  111. // These macros protect the critical keys like 'Power' from accidental press, by needing Shift to be pressed.
  112. C_KC_PWR, // Powers computer off.
  113. C_KC_WAKE,
  114. C_KC_SLEP, // sleep computer
  115. C_KC_PAUS, // pauze computer
  116. // Toggles side leds on/off.
  117. LEDS_ON,
  118. RGBTOG_,
  119. // Typing speed measuring
  120. SPEED_TOG,
  121. SPEED_REPORT,
  122. // Word/character counting
  123. COUNT_TOG, // starts word counting
  124. COUNT_REPORT, // writes to the computer as if typing, gives count report
  125. COUNT_WORDMIN, // reduces the word count
  126. COUNT_NULL, // resets count to zero
  127. LT__MOV__KC_ENT, // move to layer _MOV, or <enter>
  128. // The _ACC layer, additional Unicode.
  129. # ifndef REMOVE_ACC // This cuts out the whole _ACC layer.
  130. XP_ACC_AA ,
  131. XP_ACC_AB ,
  132. XP_ACC_AC ,
  133. XP_ACC_AD ,
  134. XP_ACC_AE ,
  135. XP_ACC_AF ,
  136. XP_ACC_AG ,
  137. XP_ACC_AH ,
  138. XP_ACC_AI ,
  139. XP_ACC_AJ ,
  140. XP_ACC_BA ,
  141. XP_ACC_BB ,
  142. XP_ACC_BC ,
  143. XP_ACC_BD ,
  144. XP_ACC_BE ,
  145. XP_ACC_BF ,
  146. XP_ACC_BG ,
  147. XP_ACC_BH ,
  148. XP_ACC_BI ,
  149. XP_ACC_BJ ,
  150. XP_ACC_BK ,
  151. XP_ACC_CA ,
  152. XP_ACC_CB ,
  153. XP_ACC_CC ,
  154. XP_ACC_CD ,
  155. XP_ACC_CE ,
  156. XP_ACC_CF ,
  157. XP_ACC_CG ,
  158. XP_ACC_CH ,
  159. XP_ACC_CI ,
  160. XP_ACC_CJ ,
  161. # endif // REMOVE_ACC
  162. # ifndef REMOVE_DRA // This cuts out the whole _DRA layer
  163. // The _DRA layer, additional Unicode.
  164. XP_DRA_AA ,
  165. XP_DRA_AB ,
  166. XP_DRA_AC ,
  167. XP_DRA_AD ,
  168. XP_DRA_AE ,
  169. XP_DRA_AF ,
  170. XP_DRA_AG ,
  171. XP_DRA_AH ,
  172. XP_DRA_AI ,
  173. XP_DRA_AJ ,
  174. XP_DRA_BA ,
  175. XP_DRA_BB ,
  176. XP_DRA_BC ,
  177. XP_DRA_BD ,
  178. XP_DRA_BE ,
  179. XP_DRA_BF ,
  180. XP_DRA_BG ,
  181. XP_DRA_BH ,
  182. XP_DRA_BI ,
  183. XP_DRA_BJ ,// XP_DRA_BK , // no 'BK' key definition on this layer
  184. XP_DRA_CA ,
  185. XP_DRA_CB ,
  186. XP_DRA_CC ,
  187. XP_DRA_CD ,
  188. XP_DRA_CE ,
  189. XP_DRA_CF ,
  190. # endif // REMOVE_DRA
  191. XP_DRA_CG , // Needed for ☑ on Unicode tester key in _RAR
  192. # ifndef REMOVE_DRA // This cuts out the whole _DRA layer
  193. XP_DRA_CH ,
  194. XP_DRA_CI ,
  195. XP_DRA_CJ ,
  196. # endif // REMOVE_DRA
  197. // The _BON layer, additional Unicode.
  198. # ifndef REMOVE_BON // Removes this layer entirely, if set.
  199. XP_BON_AA ,
  200. XP_BON_AB ,
  201. XP_BON_AC ,
  202. XP_BON_AD ,
  203. XP_BON_AE ,
  204. XP_BON_AF ,
  205. XP_BON_AG ,
  206. XP_BON_AH ,
  207. XP_BON_AI ,
  208. XP_BON_AJ ,
  209. XP_BON_BA ,
  210. XP_BON_BB ,
  211. XP_BON_BC ,
  212. XP_BON_BD ,
  213. XP_BON_BE ,
  214. XP_BON_BF ,
  215. XP_BON_BG ,
  216. XP_BON_BH ,
  217. XP_BON_BI ,
  218. XP_BON_BJ ,
  219. XP_BON_BK ,
  220. XP_BON_CA ,
  221. XP_BON_CB ,
  222. XP_BON_CC ,
  223. XP_BON_CD ,
  224. XP_BON_CE ,
  225. XP_BON_CF ,
  226. XP_BON_CG ,
  227. XP_BON_CH ,
  228. XP_BON_CI ,
  229. XP_BON_CJ ,
  230. # endif // REMOVE_BON
  231. };
  232. // Pre-existing function, called for every key up and down.
  233. // This function is sortof the hub of the whole thing.
  234. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  235. // User input for the word count menu
  236. if (sizecount_menu) {
  237. if (record->event.pressed) { // key down
  238. switch (keycode) {
  239. case KC_0: // read in how many is maximum
  240. sizecount_max = (sizecount_max * 10);
  241. break;
  242. case KC_1:
  243. sizecount_max = (sizecount_max * 10) + 1;
  244. break;
  245. case KC_2:
  246. sizecount_max = (sizecount_max * 10) + 2;
  247. break;
  248. case KC_3:
  249. sizecount_max = (sizecount_max * 10) + 3;
  250. break;
  251. case KC_4:
  252. sizecount_max = (sizecount_max * 10) + 4;
  253. break;
  254. case KC_5:
  255. sizecount_max = (sizecount_max * 10) + 5;
  256. break;
  257. case KC_6:
  258. sizecount_max = (sizecount_max * 10) + 6;
  259. break;
  260. case KC_7:
  261. sizecount_max = (sizecount_max * 10) + 7;
  262. break;
  263. case KC_8:
  264. sizecount_max = (sizecount_max * 10) + 8;
  265. break;
  266. case KC_9:
  267. sizecount_max = (sizecount_max * 10) + 9;
  268. break;
  269. case KC_C: // count characters
  270. sizecount_max_type = SIZECOUNT_CHAR;
  271. sizecount_menu = FALSE;
  272. break;
  273. case KC_W: // count words
  274. sizecount_max_type = SIZECOUNT_WORD;
  275. sizecount_menu = FALSE;
  276. break;
  277. // Anything else ends menu input.
  278. case KC_DOT:
  279. case KC_ESC:
  280. sizecount_menu = FALSE; // break out
  281. break;
  282. }
  283. if (!sizecount_menu) { // end
  284. send_string ("->");
  285. write_number (sizecount_max, FALSE); // just indicate something
  286. }
  287. }
  288. }
  289. // Go back to base-layer after pressing an F-key, on key-up to avoid BASE key activation
  290. if ((_fun_stay == FALSE) && //
  291. (((keycode >= KC_F1) && (keycode <= KC_F12))
  292. ||
  293. ((keycode >= KC_F13) && (keycode <= KC_F24)))) { // assumes keycodes 1-12 and 13-24 are consequtive, which seems likely, although using 1-24 failed (probably not consequtive)
  294. // Go back to base layer
  295. if (!(record->event.pressed)) { // key up
  296. if (alternate) { //
  297. layer_move (_ALT_BASE);
  298. }else{
  299. layer_move (_DEF_BASE);
  300. }
  301. }
  302. }
  303. // Detect if Shift was pressed in isolation, by seeing if another key was pressed during the time
  304. // the right shift key was held down.
  305. // This system is also used by CHOLTAP_ACCE
  306. // This helps make sure a tapped use of these keys is correctly differentiated from their use as a
  307. // modifier/layer-hold key. The Shift and CHOLTAP_ACCE should not normally interfere with each other.
  308. if (isolate_trigger) { // speed: hoping this statement to execute a little quicker overall, than the next
  309. if ((keycode != CHOLTAP_RSHFT) // not right shift up
  310. &&
  311. (keycode != CHOLTAP_LSHFT) // not left shift up
  312. &&
  313. (keycode != CHOLTAP_ACCE) // _ACC layer (and others)
  314. &&
  315. (keycode != RSFT_TILDE) // Shift on _NSY
  316. &&
  317. (keycode != LSFT_DASH) // Shift on _NSY
  318. &&
  319. (keycode != CHOLTAP_LAYR))
  320. { // _RAR layer, or RAlt/Alt-Gr
  321. isolate_trigger = FALSE; // another key was pressed
  322. }
  323. }
  324. // This block contains the complex macros, which should not count in speed counting or word/character counting,
  325. // because they aren't typed characters.
  326. switch (keycode) {
  327. // Typing speed measuring
  328. case SPEED_TOG: // Toggle speed measuring on/off
  329. if (record->event.pressed) { // key down
  330. if (speed_measure) {
  331. speed_measure = FALSE;
  332. # ifdef RGBLIGHT_ENABLE
  333. rgblight_sethsv_noeeprom (HSV_PURPLE); // indicates stop (_RAR color)
  334. # endif
  335. }else{
  336. // initialization of measurements
  337. speed_measure = TRUE; // activates
  338. speed = 0; // start at 0 k/s
  339. speed_countdown = SPEED_COUNTDOWN; // reset, speed is measured in batches of keypresses
  340. speed_counttime = timer_read32 ();// get current time
  341. speed_add = 0;// speed average accumulator, it keeps adding the *speed* of each batch to this total
  342. speed_batches = 0; // divider for speed_add to get the average
  343. # ifdef RGBLIGHT_ENABLE
  344. // set middle led
  345. rgblight_sethsv_noeeprom (HSV_WHITE); // indicates start
  346. # endif
  347. }
  348. # ifdef RGBLIGHT_ENABLE
  349. isolate_rgblight_set ();
  350. # endif
  351. }
  352. break;
  353. case SPEED_REPORT: // Report the current typing speed by writing it, as if typing
  354. if (record->event.pressed) { // down
  355. short added = 5; // This counts how many characters the report itself is adding into the current text,
  356. // to later delete it from the character count for text-size counting.
  357. if (speed_measure) {
  358. # ifdef WORDS_PER_MINUTE
  359. // The speed is recorded as an accumulation of keystrokes-per-second, times 10 for added precision.
  360. // This will be converted into words-per-minute by dividing by 5 characters for a word including
  361. // blank space and punctuation, and multiplied by 60 for seconds per minute. ⁶⁰/₅ = 12. Multiplied
  362. // by 12 is the simple conversion.
  363. send_string ("<"); // +1 character written // analogue to '<POWER>'
  364. added += write_number ((long int)((speed*12)/10), FALSE); // writes the speed
  365. send_string ("wpm"); // +3 character written
  366. if (0 != speed_batches) {
  367. long int average_times_ten;
  368. average_times_ten =(long int) ((speed_add * 12) / speed_batches); // *12 converts k/s to wpm
  369. send_string (";"); // +① ''
  370. added += write_number (average_times_ten / 10, FALSE); // writes the average speed, cannot use decimal because precision is not there
  371. send_string ("wpm"); // +③
  372. added += write_number ((long int) speed_batches, FALSE); // amount of batches
  373. send_string ("x"); // +①
  374. added += 9 + write_number ((long int) SPEED_COUNTDOWN, FALSE); // amount of batches
  375. send_string ("keys"); // +④ = ⑨
  376. speed_led ( (int) (average_times_ten / 12));// on report, show the average
  377. // we need to convert back to k/s now
  378. }
  379. # else // keystrokes per second, k/s
  380. send_string ("<"); // +1 character written // analogue to '<POWER>'
  381. added += write_number ((long int)(speed/10), FALSE); // writes the speed
  382. send_string ("k/s"); // +3 character written
  383. if (0 != speed_batches) {
  384. long int average_times_ten;
  385. average_times_ten =(long int) (speed_add / speed_batches);
  386. send_string (";"); // +① ''
  387. added += write_number (average_times_ten, DIV10POINT); // writes the average speed
  388. send_string ("k/s"); // +③
  389. added += write_number ((long int) speed_batches, FALSE); // amount of batches
  390. send_string ("x"); // +①
  391. added += 9 + write_number ((long int) SPEED_COUNTDOWN, FALSE); // amount of batches
  392. send_string ("keys"); // +④ = ⑨
  393. speed_led ( (int) average_times_ten );// on report, show the average. speed_led divides by 10
  394. }
  395. # endif
  396. send_string (">"); // +1 = 5
  397. if (sizecount_measure) sizecount_chars += added; // the user is expected to hit <backspace>
  398. }else{
  399. send_string ("<Soff>"); // indicates off
  400. if (sizecount_measure) sizecount_chars += 5; // user: <backspace>, to take it down again
  401. }
  402. key_timer = timer_read ();
  403. }else{ // key up
  404. // This use of the key is for callibrating your colors; it is difficult otherwise to see.
  405. // This is not part of normal usage, therefore it is kept bare bones to reduce firmware size
  406. if (timer_elapsed (key_timer) > 999) { // held for one second
  407. speed += 10;
  408. write_number ((long int)(speed/10), FALSE); // writes the speed
  409. speed_led (speed); // update led
  410. }
  411. }
  412. break;
  413. case COUNT_TOG: // Toggle start/stop text size measuring
  414. if (record->event.pressed) { // key down
  415. key_timer = timer_read ();
  416. }else{ // up
  417. if (timer_elapsed (key_timer) < 500) { // held for less than half a second (tapped)
  418. if (sizecount_measure) {
  419. sizecount_measure = FALSE;
  420. # ifdef RGBLIGHT_ENABLE
  421. rgblight_sethsv_noeeprom (HSV_PURPLE); // indicates stop (color of _RAR)
  422. isolate_rgblight_set ();
  423. # endif
  424. }else{
  425. sizecount_measure = TRUE; // start counting
  426. sizecount_word = FALSE; // detect double blanks. leading blanks are not a word
  427. # ifdef RGBLIGHT_ENABLE
  428. if (0 == sizecount_max) {
  429. rgblight_sethsv_noeeprom (HSV_BLUE); // indicates start/activated, but only without maximum set
  430. isolate_rgblight_set (); // .. if maximum set, led goes green to red.
  431. }else{
  432. rgblight_sethsv_noeeprom (HSV_GREEN); // indicates start/activated, but only without maximum set
  433. isolate_rgblight_set (); // .. if maximum set, led goes green to red.
  434. }
  435. # endif
  436. }
  437. }else{ // held longer
  438. sizecount_menu = TRUE;
  439. send_string ("<Nc|w>"); // Menu: N amount, c|w character|word counting. Input is a number then ‛c’ or ‛w’
  440. sizecount_max = 0;
  441. }
  442. }
  443. break;
  444. case COUNT_NULL: // Sets the count to zero, which allows on/off to have a suspend/resume
  445. if (record->event.pressed) { // key up
  446. sizecount_blanks = 0; //
  447. sizecount_chars = 0;
  448. # ifdef RGBLIGHT_ENABLE
  449. rgblight_sethsv_noeeprom (HSV_CYAN); // indicates reset
  450. isolate_rgblight_set ();
  451. # endif
  452. }
  453. break;
  454. case COUNT_REPORT: // Report the current typing speed
  455. if (record->event.pressed) {
  456. // We assume the user is writing a report in its active document, and then likely deleting it.
  457. short added = 0; // This counts how much characters the report adds into the user document.
  458. if (sizecount_measure) {
  459. send_string ("<"); // + 1 and ① characters (1 is one logical stream, ① another)
  460. if (0 == sizecount_max) { // no size counting maximum, print both characters and words
  461. added += write_number (sizecount_chars, FALSE); // returns how many characters where printed
  462. send_string ("c;"); // + 2
  463. added += write_number (sizecount_blanks, FALSE) + 5; // adds here
  464. send_string ("w>"); // + 2 = 5
  465. }else{ // Only show the one for which the maximum is set, don't throw off that mental focus
  466. if (SIZECOUNT_WORD == sizecount_max_type ) {
  467. added += write_number (sizecount_blanks, FALSE) + 3;
  468. send_string ("w>"); // + ② = ③
  469. }else{ // characters
  470. added += write_number (sizecount_chars, FALSE) + 3; // returns how many characters where printed
  471. send_string ("c>"); // + ② = ③
  472. }
  473. // add current maximum setting
  474. send_string ("["); // + 1
  475. added += write_number (sizecount_max, FALSE) + 3;
  476. if (SIZECOUNT_WORD == sizecount_max_type) send_string ("w]"); // + 2
  477. else send_string ("c]"); // + 2
  478. }
  479. sizecount_chars += added; // Account for the written characters in the report itself.
  480. }else{ // no size counting, also here: keep the report terse
  481. send_string ("<Coff>"); // indicates off (no need to add to count, since counting is off)
  482. }
  483. }
  484. break;
  485. // This allows the user to manually remove word counts, when he has deleted a word.
  486. // This is not needed for character count, because <backspace> counts as minus.
  487. case COUNT_WORDMIN: // Take down one word in the word-count.
  488. if (record->event.pressed) { // down
  489. key_timer = timer_read ();
  490. }else{ // up
  491. if (timer_elapsed (key_timer) < 500) { // held for less than half a second (tapped)
  492. sizecount_blanks--;
  493. }else{
  494. sizecount_blanks -= 10;
  495. }
  496. }
  497. break;
  498. // Shift detection system.
  499. // Disused because it turned out 'one shot' like Unicode input. Shift detection copied from.
  500. // https://github.com/kyleterry/qmk_firmware/blob/master/quantum/quantum.c
  501. //uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT));
  502. // Crude but self contained in this source file shift detection.
  503. // ... right shift
  504. case KC_RSFT:
  505. // + ... left shift
  506. case KC_LSFT:
  507. if (record->event.pressed) { // key down
  508. shift_ison = 1; // shift depressed
  509. }else{ // key up
  510. shift_ison = 0; // shift released
  511. }
  512. // There are macros on Shift who also alter this variable.
  513. break;
  514. case OTHER_BASE: // Switching through the default/alternate BASE modes, and Descramble for that Dvorak compile
  515. if (record->event.pressed) {
  516. ;
  517. }else{ // key up
  518. // Cycles through the modes
  519. # ifdef DVORAK_DESCRAMBLE // version Dvorak+Dvorak-descramble has 3 modes
  520. if (_NORMAL_ == alternate) {
  521. alternate = _FULL_;// alternate layers
  522. default_layer_set (_ALT_BASE_MASK); // This is needed only for a rare case,
  523. // where _DEF_BASE and _ALT_BASE their layer switching keys don't line up,
  524. // such as with Qwerty Base Arrow
  525. } else if (_HALF_ == alternate) {
  526. alternate = _NORMAL_;// normal layers
  527. default_layer_set (_DEF_BASE_MASK);
  528. }else{ // _FULL_ == alternate
  529. alternate = _HALF_;// alternate layers, without 'descramble' recomputing Unicode
  530. //default_layer_set (_ALT_BASE_MASK);
  531. // it cycles, and this comes always after it was set _FULL_
  532. }
  533. # else // Only switching the BASE layers between alternate and default
  534. if (_NORMAL_ == alternate) {
  535. alternate = _FULL_;// alternate base layers
  536. default_layer_set (_ALT_BASE_MASK);
  537. }else{
  538. alternate = _NORMAL_;// default base layers
  539. default_layer_set (_DEF_BASE_MASK);
  540. }
  541. # endif
  542. indicate_base (); // activate led change
  543. }
  544. break;
  545. # if defined(BASE_NUMPAD__ALT_BASE)
  546. case OTHER_BASE_GO: // Switching through the default/alternate BASE modes, and Descramble for that Dvorak compile
  547. if (record->event.pressed) {
  548. ;
  549. }else{ // key up
  550. // Cycles through the modes
  551. # ifdef DVORAK_DESCRAMBLE // version Dvorak+Dvorak-descramble has 3 modes
  552. if (_NORMAL_ == alternate) {
  553. alternate = _FULL_;// alternate layers
  554. default_layer_set (_ALT_BASE_MASK);
  555. } else if (_HALF_ == alternate) {
  556. alternate = _NORMAL_;// normal layers
  557. default_layer_set (_DEF_BASE_MASK);
  558. }else{ // _FULL_ == alternate
  559. alternate = _HALF_;// alternate layers, without 'descramble' recomputing Unicode
  560. //default_layer_set (_ALT_BASE_MASK);
  561. // it cycles, and this comes always after it was set _FULL_
  562. }
  563. # else // Only switching the BASE layers between alternate and default
  564. if (_NORMAL_ == alternate) {
  565. alternate = _FULL_;// alternate base layers
  566. default_layer_set (_ALT_BASE_MASK);
  567. }else{
  568. alternate = _NORMAL_;// default base layers
  569. default_layer_set (_DEF_BASE_MASK);
  570. }
  571. # endif
  572. // make the switch to the other Base layer
  573. if (alternate) { //
  574. layer_move (_ALT_BASE);
  575. }else{
  576. layer_move (_DEF_BASE);
  577. }
  578. }
  579. break;
  580. # endif
  581. // Switching to layers:
  582. case CTO_BASE:
  583. // User pressed upper/left button, while not on BASE layer: ‛escape’ from a layer to BASE layer.
  584. // On BASE itself, that key is <Escape>.
  585. if (record->event.pressed) { // key down
  586. ;
  587. }else{ // key up
  588. if (alternate) { // go to the alternate version (bit of a hack maybe, but all alternate
  589. // ... modes are non-zero)
  590. layer_move (_ALT_BASE);
  591. }else{
  592. layer_move (_DEF_BASE);
  593. }
  594. }
  595. break;
  596. case CTO_NUMS: // activates number-symbols layer
  597. if (record->event.pressed) { // key down
  598. ;
  599. }else{ // key up, so that upon key down the target layer isn't already activated, triggering that key on up
  600. if (alternate) { // go to the alternate version
  601. layer_move (_ALT_NSY);
  602. }else{
  603. layer_move (_DEF_NSY);
  604. }
  605. }
  606. break;
  607. case CTO_ACCE: // Unicode layer
  608. if (record->event.pressed) { // key down
  609. ;
  610. }else{ // key up
  611. # ifndef REMOVE_ACC // This cuts out the whole _ACC layer.
  612. layer_move (_ACC); // activates normal accented layer
  613. # else
  614. # ifdef _ACC_KEY_ALT_LAYER
  615. layer_move (_ACC_KEY_ALT_LAYER); // Alternative layer user configuration
  616. # endif
  617. # endif
  618. }
  619. break;
  620. case CTO_DRAW: // Unicode layer
  621. if (record->event.pressed) { // key down
  622. ;
  623. }else{ // key up
  624. # ifndef REMOVE_DRA // This cuts out the whole _DRA layer.
  625. layer_move (_DRA); // activates normal accented layer
  626. # else
  627. # ifdef _DRA_KEY_ALT_LAYER
  628. layer_move (_DRA_KEY_ALT_LAYER); // Alternative layer user configuration
  629. # endif
  630. # endif
  631. }
  632. break;
  633. // The below are a simulated LT(layer,kc), layer-tap.
  634. // Double-tap-hold repeater functionality: not done.
  635. // They switch what layer to use depending on 'alternate' variable
  636. // Basically it starts the right layer on key down, goes back to base layer on key up,
  637. // and throws in a keypress as well if tapped.
  638. // It also integrates with DUO_HOLD, to reach the _BON layer.
  639. # ifndef CHOLTAP_ACCE_NOP // When this key has been eviscerated, this macro becomes useless
  640. case CHOLTAP_ACCE: // Works with DUO_HOLD macro to activate one of several layers.
  641. if (record->event.pressed) { // key down
  642. key_timer = timer_read ();
  643. isolate_trigger = TRUE; // keep track of whether another key gets pressed.
  644. duo_press_acc_bon ++; // This signals to the two DUO_HOLD keys, whether a move to _BON is desired.
  645. if (duo_press_nsy_dra) { // One or more of the DUO_HOLD layer keys was already pressed; move to _BON
  646. # ifndef REMOVE_BON // Removes this layer entirely, if set.
  647. layer_move (_BON); // Bonus Unicode layer
  648. # else
  649. # ifdef _BON_KEY_ALT_LAYER
  650. layer_move (_BON_KEY_ALT_LAYER); // Alternative layer user configuration
  651. # endif
  652. # endif
  653. }else{ // pressed in isolation
  654. # ifndef REMOVE_ACC // This cuts out the whole _ACC layer.
  655. layer_move (_ACC); // Accented layer
  656. # else
  657. # ifdef _ACC_KEY_ALT_LAYER
  658. layer_move (_ACC_KEY_ALT_LAYER); // Alternative layer user configuration
  659. # endif
  660. # endif
  661. }
  662. }else{ // key up
  663. duo_press_acc_bon --;
  664. if (1 == duo_press_nsy_dra) { // One DUO_HOLD layer keys is still pressed; move to numbers/symbols
  665. if (_FULL_ == alternate) {
  666. layer_move (_ALT_NSY);
  667. }else{
  668. layer_move (_DEF_NSY);
  669. }
  670. }else if (2 == duo_press_nsy_dra) { // Two of the DUO_HOLD layer keys are still pressed: move to _DRA
  671. # ifndef REMOVE_DRA // This cuts out the whole _DRA layer.
  672. layer_move (_DRA); // activates normal accented layer
  673. # else
  674. # ifdef _DRA_KEY_ALT_LAYER
  675. layer_move (_DRA_KEY_ALT_LAYER); // Alternative layer user configuration
  676. # endif
  677. # endif
  678. }else{
  679. if (alternate) { // No _DEF_NSY layer keys remain pressed; Go back to base layer
  680. layer_move (_ALT_BASE);
  681. }else{
  682. layer_move (_DEF_BASE);
  683. }
  684. }
  685. // Pressed in isolation
  686. if (isolate_trigger)
  687. {
  688. if (timer_elapsed (key_timer) <= TAPPING_TERM_HOLTAP) { // tapped
  689. SEND_STRING (SS_TAP (X_DEL));
  690. }
  691. }
  692. }
  693. break;
  694. # endif // CHOLTAP_ACCE_NOP
  695. case CHOLTAP_LAYR: //to _RAR on hold, otherwise a keycode
  696. if (record->event.pressed) { // key down
  697. key_timer = timer_read ();
  698. isolate_trigger = TRUE; // keep track of whether another key gets pressed.
  699. # ifdef BASE_RIGHT_ALT
  700. SEND_STRING (SS_DOWN (X_RALT));
  701. # else
  702. layer_move (_RAR); // activates descrambled drawings layer
  703. # endif
  704. }else{ // key up
  705. // Go back to base layer
  706. if (speed_measure) speed_led (speed); // The _RAR layer overwrites the middle led,
  707. //.. for use with alternate _HALF_ led colors (middle); thus needs to be set back to speed
  708. // led color upon leaving.
  709. # ifdef BASE_RIGHT_ALT
  710. SEND_STRING (SS_UP (X_RALT));
  711. # else
  712. if (alternate) {
  713. layer_move (_ALT_BASE);
  714. }else{
  715. layer_move (_DEF_BASE);
  716. }
  717. # endif
  718. // Pressed in isolation
  719. if (isolate_trigger)
  720. {
  721. if (timer_elapsed (key_timer) <= TAPPING_TERM_HOLTAP) { // tapped
  722. SEND_STRING (SS_TAP (X_RIGHT));
  723. }
  724. }
  725. }
  726. break;
  727. # ifndef DUO_HOLD_BASIC
  728. // This is the normal 'big' version, dealing with switching between _DEF_NSY/_ALT_NSY, _ACC, _DRA and _BON, in
  729. // .. conjunction with the CHOLTAP_ACCE macro.
  730. case DUO_HOLD: // The macro around the split space-bar. Both keys come to this macro.
  731. if (record->event.pressed) { // key down
  732. duo_press_nsy_dra ++; // simple way to keep track of how many are pressed
  733. if (duo_press_acc_bon){ // Preceded by holding the _ACC/_BON layer switch key: move to _BON
  734. # ifndef REMOVE_BON // Removes this layer entirely, if set.
  735. layer_move (_BON); // Bonus Unicode layer
  736. # else
  737. # ifdef _BON_KEY_ALT_LAYER
  738. layer_move (_BON_KEY_ALT_LAYER); // Alternative layer user configuration
  739. # endif
  740. # endif
  741. }else if (1 == duo_press_nsy_dra) { // This is the first press of either of the DUO_HOLD keys on BASE
  742. if (_NORMAL_ == alternate) {
  743. layer_move (_DEF_NSY);
  744. }else{
  745. layer_move (_ALT_NSY);
  746. }
  747. }
  748. else if (2 == duo_press_nsy_dra) { // both are pressed
  749. # ifndef REMOVE_DRA // This cuts out the whole _DRA layer.
  750. layer_move (_DRA); // activates normal accented layer
  751. # else
  752. # ifdef _DRA_KEY_ALT_LAYER
  753. layer_move (_DRA_KEY_ALT_LAYER); // Alternative layer user configuration
  754. # endif
  755. # endif
  756. }
  757. }else{ // key up
  758. duo_press_nsy_dra --;
  759. if (1 == duo_press_nsy_dra) {
  760. if (duo_press_acc_bon){ // Still holding the _ACC/_BON layer switch key, and one DUO_HOLD keys
  761. # ifndef REMOVE_BON // Removes this layer entirely, if set.
  762. layer_move (_BON); // Bonus Unicode layer
  763. # else
  764. # ifdef _BON_KEY_ALT_LAYER
  765. layer_move (_BON_KEY_ALT_LAYER); // Alternative layer user configuration
  766. # endif
  767. # endif
  768. }else{
  769. if (_NORMAL_ == alternate) {
  770. layer_move (_DEF_NSY);
  771. }else{
  772. layer_move (_ALT_NSY);
  773. }
  774. }
  775. }
  776. else { // Has to be zero.
  777. if (duo_press_acc_bon){ // Still holding the _ACC/_BON layer switch key, but zero DUO_HOLD layer keys
  778. # ifndef REMOVE_ACC // This cuts out the whole _ACC layer.
  779. layer_move (_ACC); // Accented layer
  780. # else
  781. # ifdef _ACC_KEY_ALT_LAYER
  782. layer_move (_ACC_KEY_ALT_LAYER); // Alternative layer user configuration
  783. # endif
  784. # endif
  785. }else{
  786. if (alternate) { // Back to letters
  787. layer_move (_ALT_BASE);
  788. }else{
  789. layer_move (_DEF_BASE);
  790. }
  791. }
  792. }
  793. }
  794. break;
  795. # else
  796. // This is the eviscerated version, compiled when all Unicode layers _ACC, _DRA, _BON are cut, and layer key
  797. // .. combinations have not been assigned other uses.
  798. case DUO_HOLD: // The macro for the keys around the split space-bar. Both keys come to this macro.
  799. if (record->event.pressed) { // key down
  800. duo_press_nsy_dra ++; // simple way to keep track of how many are pressed
  801. if (0 != duo_press_nsy_dra) { // One or more of the DUO_HOLD keys is pressed
  802. if (_NORMAL_ == alternate) {
  803. layer_move (_DEF_NSY);
  804. }else{
  805. layer_move (_ALT_NSY);
  806. }
  807. }
  808. }else{ // key up
  809. duo_press_nsy_dra --;
  810. if (0 == duo_press_nsy_dra) { // None of the DUO_HOLD keys remains pressed
  811. if (alternate) { // Back to letters
  812. layer_move (_ALT_BASE);
  813. }else{
  814. layer_move (_DEF_BASE);
  815. }
  816. }
  817. }
  818. break;
  819. # endif // DUO_HOLD_BASIC
  820. // When held the key is shift. When tapped it is computed if the tap is short enough,
  821. // and if no other key was pressed, in which case: right-shift-up is a toggle to the _FUN layer.
  822. // The timing is meant to be able to undo an erroneous shift press just by holding longer,
  823. // and the test if another key was pressed is to prevent an erroneous detection when typing
  824. // very fast.
  825. // The reason for this on shift is to isolate GUI, where _FUN was previously more easily
  826. // located. No alternative tapping function with GUI because some systems do not treat GUI
  827. // purely as a modifier it seems. Since it is a toggle anyway, _FUN can fit away from the thumb-hold row.
  828. case CHOLTAP_RSHFT: // When tapped it toggles the _FUN layer, when held it is Shift
  829. if (record->event.pressed) { // key down
  830. SEND_STRING (SS_DOWN (X_RSFT));
  831. shift_ison = 1; // shift depressed
  832. key_timer = timer_read ();
  833. isolate_trigger = TRUE; // keep track of whether another key gets pressed until key-up
  834. }else{ // key up
  835. SEND_STRING (SS_UP (X_RSFT));
  836. shift_ison = 0; // shift released
  837. if (isolate_trigger) { // no other key was hit since key down
  838. // Held medium long: _PAD, long: _MOV.
  839. // The reason to have a switch to _MOV on the left hand, is to be able to reach arrows on a toggle,
  840. // all by the left hand, when the right hand is on the mouse.
  841. if ((timer_elapsed (key_timer) <= 200)) { // tapped short (milliseconds)
  842. # ifndef SWITCH_RSHIFT_FUN_RAR // user config to reverse what this key its timing toggles to
  843. layer_move (_FUN); // activates function layer as a toggle
  844. } else { // held for longer
  845. layer_move (_RAR);
  846. # else
  847. layer_move (_RAR); // activates function layer as a toggle
  848. } else { // held for longer
  849. layer_move (_FUN);
  850. # endif
  851. }
  852. }
  853. }
  854. break;
  855. // The left-shift version of the above keycode. User can configure something (_PAD is default)
  856. case CHOLTAP_LSHFT: // When tapped it toggles the _MOV layer, when held it is Shift
  857. // _RAR was the first idea, but some of its keys are too dangerous regarding accidents.
  858. if (record->event.pressed) { // key down
  859. SEND_STRING (SS_DOWN (X_LSFT));
  860. shift_ison = 1; // shift depressed
  861. # ifndef REMOVE_PAD // The _PAD layer exists, we will use a timer …
  862. key_timer = timer_read ();
  863. # endif
  864. // This variable is re-used, for speed and because using both shifts is useless,
  865. // .. thus very rare, and also not a usage problem if it occured.
  866. isolate_trigger = TRUE; // keep track of whether another key gets pressed.
  867. }else{ // key up
  868. SEND_STRING (SS_UP (X_LSFT));
  869. shift_ison = 0; // shift released
  870. if (isolate_trigger) { // no other key was hit since key down
  871. # ifndef REMOVE_PAD // The _PAD layer exists, differentiate meaning by timer.
  872. // Held medium long: _PAD, long: _MOV.
  873. // The reason to have a switch to _MOV on the left hand, is to be able to reach arrows on a toggle,
  874. // all by the left hand, when the right hand is on the mouse.
  875. if ((timer_elapsed (key_timer) <= 200)) { // tapped medium-long (milliseconds)
  876. # ifndef SWITCH_LSHIFT_PAD_MOV // user config to reverse what this key its timing toggles to
  877. layer_move (_PAD);
  878. } else { // held for longer
  879. layer_move (_MOV);
  880. # else
  881. layer_move (_MOV);
  882. } else { // held for longer
  883. layer_move (_PAD);
  884. # endif
  885. }
  886. # else // _PAD layer was eviscerated
  887. layer_move (_MOV);
  888. # endif
  889. }
  890. }
  891. break;
  892. /*
  893. case RSFT_TILDE:
  894. if (record->event.pressed) { // key down
  895. SEND_STRING (SS_DOWN (X_RSFT));
  896. shift_ison = 1; // shift depressed
  897. key_timer = timer_read ();
  898. isolate_trigger = TRUE; // keep track of whether another key gets pressed until key-up
  899. }else{ // key up
  900. SEND_STRING (SS_UP (X_RSFT));
  901. shift_ison = 0; // shift released
  902. if (isolate_trigger) { // no other key was hit since key down
  903. // Held medium long: _PAD, long: _MOV.
  904. // The reason to have a switch to _MOV on the left hand, is to be able to reach arrows on a toggle,
  905. // all by the left hand, when the right hand is on the mouse.
  906. if ((timer_elapsed (key_timer) <= 200)) { // tapped short (milliseconds)
  907. SEND_STRING ("~");
  908. }
  909. }
  910. }
  911. break;
  912. */
  913. case RSFT_TILDE: // firmware size optimization, saves 36 bytes
  914. case LSFT_DASH:
  915. if (record->event.pressed) { // key down
  916. if (RSFT_TILDE == keycode) { // this is probably not needed, both can be left or right shift
  917. SEND_STRING (SS_DOWN (X_RSFT));
  918. }else{
  919. SEND_STRING (SS_DOWN (X_LSFT));
  920. }
  921. shift_ison = 1; // shift depressed
  922. key_timer = timer_read ();
  923. isolate_trigger = TRUE; // keep track of whether another key gets pressed until key-up
  924. }else{ // key up
  925. if (RSFT_TILDE == keycode) {
  926. SEND_STRING (SS_UP (X_RSFT));
  927. }else{
  928. SEND_STRING (SS_UP (X_LSFT));
  929. }
  930. shift_ison = 0; // shift released
  931. if (isolate_trigger) { // no other key was hit since key down
  932. // Held medium long: _PAD, long: _MOV.
  933. // The reason to have a switch to _MOV on the left hand, is to be able to reach arrows on a toggle,
  934. // all by the left hand, when the right hand is on the mouse.
  935. if ((timer_elapsed (key_timer) <= 200)) { // tapped short (milliseconds)
  936. if (RSFT_TILDE == keycode) {
  937. SEND_STRING ("~");
  938. }else{
  939. SEND_STRING ("-");
  940. }
  941. }
  942. }
  943. }
  944. break;
  945. case _FUN_STAY: // toggles if the f-keys return _FUN layer to BASE after one press
  946. if (record->event.pressed) { // key down
  947. if (_fun_stay == FALSE) {
  948. _fun_stay = TRUE;
  949. }else{
  950. _fun_stay = FALSE;
  951. }
  952. indicate_fun_stay (); // leds
  953. }
  954. break;
  955. # ifdef MOREKEY2_ARROW_CLUSTER
  956. case _MOV_UP: // To be sure it activates on up key, and not already has triggered the _MOV layer during up-key.
  957. if (record->event.pressed) { // key down
  958. ;
  959. }else{ // key up
  960. layer_move (_MOV);
  961. }
  962. break;
  963. # endif
  964. // These keys are so disruptive on an erroneous key press, that they are behind a shift lock.
  965. // When used unshifted, they print a memory aid string: their name.
  966. case C_KC_PWR:
  967. if (record->event.pressed) { // key down
  968. if (shift_ison) {
  969. SEND_STRING (SS_TAP (X_PWR));
  970. }else{
  971. SEND_STRING ("<POWER>"); // Memory aid
  972. }
  973. }
  974. break;
  975. case C_KC_WAKE:
  976. if (record->event.pressed) { // key down
  977. if (shift_ison) {
  978. SEND_STRING (SS_TAP (X_WAKE));
  979. }else{
  980. SEND_STRING ("<WAKE>"); // Memory aid
  981. }
  982. }
  983. break;
  984. case C_KC_SLEP:
  985. if (record->event.pressed) { // key down
  986. if (shift_ison) {
  987. SEND_STRING (SS_TAP (X_SLEP));
  988. }else{
  989. SEND_STRING ("<SLEEP>"); // Memory aid
  990. }
  991. }
  992. break;
  993. case C_KC_PAUS:
  994. if (record->event.pressed) { // key down
  995. if (shift_ison) {
  996. SEND_STRING (SS_TAP (X_PAUS));
  997. }else{
  998. SEND_STRING ("<PAUSE>"); // Memory aid
  999. }
  1000. }
  1001. break;
  1002. case LEDS_ON: // Toggles left/right leds on or off
  1003. if (record->event.pressed) { // key down
  1004. if (leds_on == FALSE) {
  1005. leds_on = TRUE;
  1006. }else{
  1007. leds_on = FALSE;
  1008. }
  1009. }
  1010. break;
  1011. # ifdef LEDS_OFF_BASE_DEF // This messes with led effect on/off, so we need to track the state of this setting now.
  1012. case RGBTOG_: // Toggles middle led on or off
  1013. if (record->event.pressed) { // key down
  1014. if (led_middle_on == FALSE) {
  1015. led_middle_on = TRUE;
  1016. rgblight_enable_noeeprom ();
  1017. }else{
  1018. led_middle_on = FALSE;
  1019. rgblight_disable_noeeprom ();
  1020. }
  1021. }
  1022. break;
  1023. # endif
  1024. // Some keycodes treated specially for the two counting systems (speed, text size)
  1025. // Deletions:
  1026. case KC_BSPC: // non-counting speed
  1027. case KC_DEL: // non-counting speed
  1028. if (record->event.pressed) { // key down
  1029. if (sizecount_measure) sizecount_chars--; // minus count for text size (removed a character)
  1030. }
  1031. break;
  1032. // White space for counting words
  1033. case LT__MOV__KC_ENT: // We want to count the <enter> for word-counts, sadly this looses the key repetition of LT(…)
  1034. if (record->event.pressed) { // key down
  1035. key_timer = timer_read ();
  1036. layer_move (_MOV);
  1037. }else{ // key up
  1038. if (alternate) { // Back to letters
  1039. layer_move (_ALT_BASE);
  1040. }else{
  1041. layer_move (_DEF_BASE);
  1042. }
  1043. if (timer_elapsed (key_timer) <= TAPPING_TERM_HOLTAP) { // tapped
  1044. send_string ("\n");
  1045. if (sizecount_measure) {
  1046. sizecount_chars++;
  1047. if (sizecount_word) sizecount_blanks++; // count a word
  1048. sizecount_word = FALSE; // don't count immediately next blank as a word
  1049. }
  1050. }
  1051. }
  1052. break;
  1053. // Word counting
  1054. case KC_SPC:
  1055. if (record->event.pressed) { // key down
  1056. if (sizecount_measure) {
  1057. sizecount_chars++;
  1058. if (sizecount_word) sizecount_blanks++; // count a word
  1059. sizecount_word = FALSE; // don't count immediately next blank as a word
  1060. }
  1061. }
  1062. break;
  1063. // These are excluded from counting for text size/speed, they prevent the “default“ in the case statement to execute.
  1064. case KC_LEFT:
  1065. case KC_UP:
  1066. case KC_DOWN:
  1067. case KC_RIGHT:
  1068. case KC_PGUP:
  1069. case KC_PGDN:
  1070. case KC_HOME:
  1071. case KC_END:
  1072. case LALT_T ( KC_LEFT ):
  1073. if (speed_measure) speed_countdown++; // Navigation could be integral to someone typing and correcting mistakes,
  1074. // but those keys don't add any text.
  1075. // Mouse movement is discounted in both speed and text size
  1076. case KC_WH_L:
  1077. case KC_WH_D:
  1078. case KC_WH_U:
  1079. case KC_WH_R:
  1080. case KC_MS_L:
  1081. case KC_MS_D:
  1082. case KC_MS_U:
  1083. case KC_MS_R:
  1084. case KC_BTN1:
  1085. case KC_BTN5:
  1086. case KC_BTN4:
  1087. case KC_BTN3:
  1088. case KC_BTN2:
  1089. break;
  1090. default: // If something else, it is a speed- and text measurement counting key
  1091. if (record->event.pressed) { // key down
  1092. if (speed_measure) speed_countdown--;
  1093. if (sizecount_measure) sizecount_chars++;
  1094. }
  1095. }
  1096. // If speed measuring is on, count keypresses
  1097. // The idea is to more/less follow common standard with typing speed counting: shift is not counted,
  1098. // layer-switching or its equivalent is neither. Arrows are not counted.
  1099. if (speed_measure) {
  1100. if (record->event.pressed) { // key down
  1101. if (0 >= speed_countdown) {
  1102. // key presses per second, but times ten for added precision of one digit
  1103. // This calculation quickly looses precision if not calculated with high enough numbers, but low enough to fit.
  1104. speed = (int) ( (SPEED_COUNTDOWN * 1000 ) / ((timer_read32 () - speed_counttime)/10) ); // counts time in ms
  1105. speed_led (speed); // updates led
  1106. // record for average
  1107. if (0 < (speed/10)) { // ignore 0 k/s batches, we assume the typer took a break
  1108. speed_batches++;
  1109. speed_add += speed;
  1110. }
  1111. // reset for next batch
  1112. speed_countdown = SPEED_COUNTDOWN; // reset
  1113. speed_counttime = timer_read32 ();
  1114. }
  1115. }
  1116. }
  1117. // For word-counting, ignore double blanks
  1118. if (sizecount_measure) {
  1119. if (record->event.pressed) {
  1120. bool within = TRUE; // When text size is maximized, this indicates we are not yet at that maximum.
  1121. # ifdef RGBLIGHT_ENABLE
  1122. unsigned short size_fraction = 0; // Used to compute led color as a fraction of a set maximum which is already typed.
  1123. # endif
  1124. // ignoring blanks wordcount
  1125. if ((keycode != KC_SPC)
  1126. &&
  1127. (keycode != KC_TAB) // This is ok, but a tab on BASE layer combo with Control, is not caught by this XXX (problem ignored, I never write Tab in a text worth counting)
  1128. &&
  1129. (keycode != LT__MOV__KC_ENT)
  1130. &&
  1131. (keycode != LT__MOV__KC_ENT)) {
  1132. sizecount_word = TRUE; // current key is not a blank, so we set this trigger for next key press
  1133. }
  1134. // computing maximum count effects: leds
  1135. if (0 != sizecount_max) {
  1136. if (SIZECOUNT_WORD == sizecount_max_type) {
  1137. if (sizecount_blanks > sizecount_max) within = FALSE;
  1138. }else{ // count chars
  1139. if (sizecount_chars > sizecount_max) within = FALSE;
  1140. }
  1141. // led colors
  1142. if (within) { // green to red middle led
  1143. # ifdef RGBLIGHT_ENABLE
  1144. if (SIZECOUNT_WORD == sizecount_max_type) {
  1145. size_fraction = (90 * sizecount_blanks) / sizecount_max;
  1146. }else{
  1147. size_fraction = (90 * sizecount_chars) / sizecount_max;
  1148. }
  1149. rgblight_sethsv_noeeprom (90 - size_fraction , 255, 255); // green to red, full saturation, full lit
  1150. # endif
  1151. }else{ // when at or over the limit: blink led red/white
  1152. if ((KC_BSPC != keycode)
  1153. && (KC_DEL != keycode) // User already deleting, doubling is confusing
  1154. && (CHOLTAP_LAYR != keycode)) { // This brings up the _RAR layer, to access the Count settings.
  1155. SEND_STRING (SS_TAP(X_BSPC)); // refuses to type further, the user is stopped from typing to make it obvious
  1156. }
  1157. # ifdef RGBLIGHT_ENABLE
  1158. if (sizecount_chars & 0x1) { // flip by every keypress
  1159. rgblight_sethsv_noeeprom (HSV_RED);
  1160. }else{
  1161. rgblight_sethsv_noeeprom (HSV_WHITE);
  1162. }
  1163. # endif
  1164. }
  1165. # ifdef RGBLIGHT_ENABLE
  1166. rgblight_set (); // only center led is altered, no need to go through isolate_rgblight_set()
  1167. # endif
  1168. }
  1169. }
  1170. }
  1171. // Simple macros, printing a character.
  1172. switch (keycode) {
  1173. /* _ACC layer definitions. */
  1174. // ------------------------- row 4
  1175. # ifndef REMOVE_ACC // This cuts out the whole _ACC layer.
  1176. case XP_ACC_AA: // because a
  1177. if (record->event.pressed) { // key down
  1178. unicode_hex2output (CAL_ACU, CAU_ACU);// á Á
  1179. }
  1180. break;
  1181. case XP_ACC_AB: // because o (Dvorak)
  1182. if (record->event.pressed) { // key down
  1183. unicode_hex2output (COL_ACU, COU_ACU);// ó Ó
  1184. }
  1185. break;
  1186. case XP_ACC_AC: // because e (Dvorak)
  1187. if (record->event.pressed) { // key down
  1188. unicode_hex2output (CEL_ACU, CEU_ACU);// é É
  1189. }
  1190. break;
  1191. case XP_ACC_AD: // because u (Dvorak)
  1192. if (record->event.pressed) { // key down
  1193. unicode_hex2output (CUL_ACU, CUU_ACU);// ú Ú
  1194. }
  1195. break;
  1196. case XP_ACC_AE: // because i (Dvorak)
  1197. if (record->event.pressed) { // key down
  1198. unicode_hex2output (CIL_ACU, CIU_ACU);// í Í
  1199. }
  1200. break;
  1201. case XP_ACC_AF: // Because near Y
  1202. if (record->event.pressed) { // key down
  1203. unicode_hex2output (CYL_ACU, CYU_ACU);// ý Ý
  1204. }
  1205. break;
  1206. case XP_ACC_AG: // because near Y
  1207. if (record->event.pressed) { // key down
  1208. unicode_hex2output (CIJL_BI, CIJU_BI);// ij IJ
  1209. }
  1210. break;
  1211. case XP_ACC_AH: // because c (Dvorak)
  1212. if (record->event.pressed) { // key down
  1213. unicode_hex2output (CCL_CDL, CCU_CDL);// ç Ç
  1214. }
  1215. break;
  1216. case XP_ACC_AI: // because ring-finger left is o (Dvorak)
  1217. if (record->event.pressed) { // key down
  1218. unicode_hex2output (COL_STK, COU_STK);// ø Ø
  1219. }
  1220. break;
  1221. case XP_ACC_AJ: // because pinky finger left is a
  1222. if (record->event.pressed) { // key down
  1223. unicode_hex2output (CAL_RNG, CAU_RNG);// å Å
  1224. }
  1225. break;
  1226. // ------------------------- row 3
  1227. case XP_ACC_BA: // because a
  1228. if (record->event.pressed) { // key down
  1229. unicode_hex2output (CAL_DIA, CAU_DIA);// ä Ä
  1230. }
  1231. break;
  1232. case XP_ACC_BB: // because o (Dvorak)
  1233. if (record->event.pressed) { // key down
  1234. unicode_hex2output (COL_DIA, COU_DIA);// ö Ö
  1235. }
  1236. break;
  1237. case XP_ACC_BC: // because e (Dvorak)
  1238. if (record->event.pressed) { // key down
  1239. unicode_hex2output (CEL_DIA, CEU_DIA);// ë Ë
  1240. }
  1241. break;
  1242. case XP_ACC_BD: // because u (Dvorak)
  1243. if (record->event.pressed) { // key down
  1244. unicode_hex2output (CUL_DIA, CUU_DIA);// ü Ü
  1245. }
  1246. break;
  1247. case XP_ACC_BE: // because i
  1248. if (record->event.pressed) { // key down
  1249. unicode_hex2output (CIL_DIA, CIU_DIA);// ï Ï
  1250. }
  1251. break;
  1252. case XP_ACC_BF: // because near y
  1253. if (record->event.pressed) { // key down
  1254. unicode_hex2output (CYL_DIA, CYU_DIA);// ÿ Ÿ
  1255. }
  1256. break;
  1257. case XP_ACC_BG: // because vague logic about other hand having ae near on similar fingers
  1258. if (record->event.pressed) { // key down
  1259. unicode_hex2output (COEL_BI, COEU_BI);// œ Œ
  1260. }
  1261. break;
  1262. case XP_ACC_BH: // because near œ, toward the side of a (pinky)
  1263. if (record->event.pressed) { // key down
  1264. unicode_hex2output (CAEL_BI, CAEU_BI);// æ Æ
  1265. }
  1266. break;
  1267. case XP_ACC_BI: // because n
  1268. if (record->event.pressed) { // key down
  1269. unicode_hex2output (CNL_TLD, CNU_TLD);// ñ Ñ
  1270. }
  1271. break;
  1272. case XP_ACC_BJ: // because s
  1273. if (record->event.pressed) { // key down
  1274. unicode_hex2output_single (CSL_SHP);// ß ß
  1275. }
  1276. break;
  1277. case XP_ACC_BK: // because roughly the location on French keyboard
  1278. if (record->event.pressed) { // key down
  1279. unicode_hex2output_single (C_MU_L);// μ
  1280. }
  1281. break;
  1282. // ------------------------- row 2
  1283. case XP_ACC_CA: // because a
  1284. if (record->event.pressed) { // key down
  1285. unicode_hex2output (CAL_GRA, CAU_GRA);//à À
  1286. }
  1287. break;
  1288. case XP_ACC_CB: // because o (Dvorak)
  1289. if (record->event.pressed) { // key down
  1290. unicode_hex2output (COL_GRA, COU_GRA);// ò Ò
  1291. }
  1292. break;
  1293. case XP_ACC_CC: // because e (Dvorak)
  1294. if (record->event.pressed) { // key down
  1295. unicode_hex2output (CEL_GRA, CEU_GRA);// è È
  1296. }
  1297. break;
  1298. case XP_ACC_CD: // because u (Dvorak)
  1299. if (record->event.pressed) { // key down
  1300. unicode_hex2output (CUL_GRA, CUU_GRA);// ù Ù
  1301. }
  1302. break;
  1303. case XP_ACC_CE: // because i (Dvorak)
  1304. if (record->event.pressed) { // key down
  1305. unicode_hex2output (CIL_GRA, CIU_GRA);// ì Ì
  1306. }
  1307. break;
  1308. case XP_ACC_CF: // because other hand same finger i
  1309. if (record->event.pressed) { // key down
  1310. unicode_hex2output (CIL_CAR, CIU_CAR);// î Î
  1311. }
  1312. break;
  1313. case XP_ACC_CG: // because other hand same finger u
  1314. if (record->event.pressed) { // key down
  1315. unicode_hex2output (CUL_CAR, CUU_CAR);// û Û
  1316. }
  1317. break;
  1318. case XP_ACC_CH: // because other hand same finger e
  1319. if (record->event.pressed) { // key down
  1320. unicode_hex2output (CEL_CAR, CEU_CAR);// ê Ê
  1321. }
  1322. break;
  1323. case XP_ACC_CI: // because other hand same finger o
  1324. if (record->event.pressed) { // key down
  1325. unicode_hex2output (COL_CAR, COU_CAR);// ô Ô
  1326. }
  1327. break;
  1328. case XP_ACC_CJ: // because other hand same finger a
  1329. if (record->event.pressed) { // key down
  1330. unicode_hex2output (CAL_CAR, CAU_CAR);// â Â
  1331. }
  1332. break;
  1333. # endif // REMOVE_ACC // This cuts out the whole _ACC layer.
  1334. /* _DRA layer definitions. */
  1335. # ifndef REMOVE_DRA // This cuts out the whole _DRA layer
  1336. // ------------------------- row 4
  1337. case XP_DRA_AA: // because '", the opening „“ at the ‛open’ of the keyboard (left/up)
  1338. if (record->event.pressed) { // key down
  1339. # ifdef FULL_DRA_4THROW
  1340. unicode_hex2output (CS_DQUHR, CS_DQUL);// “ „
  1341. # else
  1342. unicode_hex2output_single (CS_DQUHR);// “
  1343. # endif
  1344. }
  1345. break;
  1346. case XP_DRA_AB: // because to the right of opening “, ≤ on <
  1347. if (record->event.pressed) { // key down
  1348. # ifdef FULL_DRA_4THROW
  1349. unicode_hex2output (CS_DQUH, CS_ELTHAN);// ” ≤
  1350. # else
  1351. unicode_hex2output_single (CS_DQUH);// ”
  1352. # endif
  1353. }
  1354. break;
  1355. case XP_DRA_AC: // because this is where the £ is on an English keyboard, on 'any' money symbols ¤; ≥ on >
  1356. if (record->event.pressed) { // key down
  1357. # ifdef FULL_DRA_4THROW
  1358. unicode_hex2output (CS_POUND, CS_EGTHAN);// £ ≥
  1359. # else
  1360. unicode_hex2output_single (CS_POUND);// £
  1361. # endif
  1362. }
  1363. break;
  1364. case XP_DRA_AD: // because ∅ looks like ¢, and ¢ (cent) is on $ (money) ?
  1365. if (record->event.pressed) { // key down
  1366. # ifdef FULL_DRA_4THROW
  1367. unicode_hex2output (CS_NONE, CS_CENT);// ∅ ¢
  1368. # endif
  1369. }
  1370. break;
  1371. case XP_DRA_AE: // because percentages %‰‱ and money ƒ are numerical ?
  1372. if (record->event.pressed) { // key down
  1373. # ifdef FULL_DRA_4THROW
  1374. unicode_hex2output (CS_PLMI, CS_LGULDEN);// ± ƒ
  1375. # else
  1376. unicode_hex2output_single (CS_PLMI);// ±
  1377. # endif
  1378. }
  1379. break;
  1380. case XP_DRA_AF: // Because left of 🙂, on top of ★
  1381. if (record->event.pressed) { // key down
  1382. # ifdef FULL_DRA_4THROW
  1383. unicode_hex2output (CS_FLEUR, CS_HEART);// ❦ ♥
  1384. # else
  1385. unicode_hex2output_single (CS_HEART);// ♥
  1386. # endif
  1387. }
  1388. break;
  1389. case XP_DRA_AG: // because 😊 ⍨
  1390. if (record->event.pressed) { // key down
  1391. # ifdef FULL_DRA_4THROW
  1392. unicode_hex2output (CS_SMIL, CS_SAD_);// 🙂 🙁
  1393. # endif
  1394. }
  1395. break;
  1396. case XP_DRA_AH: // because «no reason», next to 😊 (emoticons)
  1397. if (record->event.pressed) { // key down
  1398. # ifdef FULL_DRA_4THROW
  1399. unicode_hex2output (CS_THUP, CS_THDN);// 👍 👎
  1400. # endif
  1401. }
  1402. break;
  1403. case XP_DRA_AI: // because (
  1404. if (record->event.pressed) { // key down
  1405. # ifdef FULL_DRA_4THROW
  1406. unicode_hex2output (CS_OPSUP, CS_OPSUB);// ⁽ ₍
  1407. # endif
  1408. }
  1409. break;
  1410. case XP_DRA_AJ: // because )
  1411. if (record->event.pressed) { // key down
  1412. # ifdef FULL_DRA_4THROW
  1413. unicode_hex2output (CS_CPSUP, CS_CPSUB);// ⁾ ₎
  1414. # endif
  1415. }
  1416. break;
  1417. // ------------------------- row 3
  1418. case XP_DRA_BA: // because 1
  1419. if (record->event.pressed) { // key down
  1420. # ifdef SUB_SCRIPT_NUMS
  1421. unicode_hex2output (CN_1SUP, CN_1SUB);// ¹ ₁
  1422. # else
  1423. unicode_hex2output_single (CN_1SUP);// ¹
  1424. # endif
  1425. }
  1426. break;
  1427. case XP_DRA_BB: // because 2
  1428. if (record->event.pressed) { // key down
  1429. # ifdef SUB_SCRIPT_NUMS
  1430. unicode_hex2output (CN_2SUP, CN_2SUB);// ² ₂
  1431. # else
  1432. unicode_hex2output_single (CN_2SUP);// ²
  1433. # endif
  1434. }
  1435. break;
  1436. case XP_DRA_BC: // because 3
  1437. if (record->event.pressed) { // key down
  1438. # ifdef SUB_SCRIPT_NUMS
  1439. unicode_hex2output (CN_3SUP, CN_3SUB);// ³ ₃
  1440. # else
  1441. unicode_hex2output_single (CN_3SUP);// ³
  1442. # endif
  1443. }
  1444. break;
  1445. case XP_DRA_BD: // because 4
  1446. if (record->event.pressed) { // key down
  1447. # ifdef SUB_SCRIPT_NUMS
  1448. unicode_hex2output (CN_4SUP, CN_4SUB);// ⁴ ₄
  1449. # else
  1450. unicode_hex2output_single (CN_4SUP);// ⁴
  1451. # endif
  1452. }
  1453. break;
  1454. case XP_DRA_BE: // because 5
  1455. if (record->event.pressed) { // key down
  1456. # ifdef SUB_SCRIPT_NUMS
  1457. unicode_hex2output (CN_5SUP, CN_5SUB);// ⁵ ₅
  1458. # else
  1459. unicode_hex2output_single (CN_5SUP);// ⁵
  1460. # endif
  1461. }
  1462. break;
  1463. case XP_DRA_BF: // because 6
  1464. if (record->event.pressed) { // key down
  1465. # ifdef SUB_SCRIPT_NUMS
  1466. unicode_hex2output (CN_6SUP, CN_6SUB);// ⁶ ₆
  1467. # else
  1468. unicode_hex2output_single (CN_6SUP);// ⁶
  1469. # endif
  1470. }
  1471. break;
  1472. case XP_DRA_BG: // because 7
  1473. if (record->event.pressed) { // key down
  1474. # ifdef SUB_SCRIPT_NUMS
  1475. unicode_hex2output (CN_7SUP, CN_7SUB);// ⁷ ₇
  1476. # else
  1477. unicode_hex2output_single (CN_7SUP);// ⁷
  1478. # endif
  1479. }
  1480. break;
  1481. case XP_DRA_BH: // because 8
  1482. if (record->event.pressed) { // key down
  1483. # ifdef SUB_SCRIPT_NUMS
  1484. unicode_hex2output (CN_8SUP, CN_8SUB);// ⁸ ₈
  1485. # else
  1486. unicode_hex2output_single (CN_8SUP);// ⁸
  1487. # endif
  1488. }
  1489. break;
  1490. case XP_DRA_BI: // because 9
  1491. if (record->event.pressed) { // key down
  1492. # ifdef SUB_SCRIPT_NUMS
  1493. unicode_hex2output (CN_9SUP, CN_9SUB);// ⁹ ₉
  1494. # else
  1495. unicode_hex2output_single (CN_9SUP);// ⁹
  1496. # endif
  1497. }
  1498. break;
  1499. case XP_DRA_BJ: // because 0
  1500. if (record->event.pressed) { // key down
  1501. # ifdef SUB_SCRIPT_NUMS
  1502. unicode_hex2output (CN_0SUP, CN_0SUB);// ⁰ ₀
  1503. # else
  1504. unicode_hex2output_single (CN_0SUP);// ⁰
  1505. # endif
  1506. }
  1507. break;
  1508. // ------------------------- row 2
  1509. case XP_DRA_CA: // because [
  1510. if (record->event.pressed) { // key down
  1511. # ifdef FULL_DRA_2NDROW
  1512. unicode_hex2output (CS_OCBRA, CB_HHORI);// 「 ━
  1513. # else
  1514. unicode_hex2output_single (CB_HHORI);// ━
  1515. # endif
  1516. }
  1517. break;
  1518. case XP_DRA_CB: // because ]
  1519. if (record->event.pressed) { // key down
  1520. # ifdef FULL_DRA_2NDROW
  1521. unicode_hex2output (CS_CCBRA, CB_LHORI);// 」 ─
  1522. # else
  1523. unicode_hex2output_single (CB_LHORI);// ─
  1524. # endif
  1525. }
  1526. break;
  1527. case XP_DRA_CC: // because «no reason»
  1528. if (record->event.pressed) { // key down
  1529. # ifdef FULL_DRA_2NDROW
  1530. unicode_hex2output (CS_DEGREE, CS_CIRCLE);// ° 〇
  1531. # else
  1532. unicode_hex2output_single (CS_DEGREE);// °
  1533. # endif
  1534. }
  1535. break;
  1536. case XP_DRA_CD: // because «no reason»
  1537. if (record->event.pressed) { // key down
  1538. # ifdef FULL_DRA_2NDROW
  1539. unicode_hex2output (CS_BULLET, CS_PARA);// • §
  1540. # else
  1541. unicode_hex2output_single (CS_BULLET);// •
  1542. # endif
  1543. }
  1544. break;
  1545. case XP_DRA_CE: // because «no reason»
  1546. if (record->event.pressed) { // key down
  1547. # ifdef FULL_DRA_2NDROW
  1548. unicode_hex2output (CS_ELLIPS, CS_MIDDOT);// … ·
  1549. # else
  1550. unicode_hex2output_single (CS_ELLIPS);// …
  1551. # endif
  1552. }
  1553. break;
  1554. case XP_DRA_CF: // because «no reason» (+ resembles ‛☒’ ?), ✗
  1555. if (record->event.pressed) { // key down
  1556. unicode_hex2output (CS_CHECK_B, CS_CHECK_N);// ☐ ☒
  1557. }
  1558. break;
  1559. # endif
  1560. // This one must be included for _RAR layer
  1561. case XP_DRA_CG: // because next to ✗ ☐ ☒
  1562. if (record->event.pressed) { // key down
  1563. # ifdef FULL_DRA_2NDROW
  1564. unicode_hex2output (CS_CHECK_Y, CS_CHECK_H);// ☑ 🗹
  1565. # else
  1566. unicode_hex2output_single (CS_CHECK_Y);// ☑
  1567. # endif
  1568. }
  1569. break;
  1570. # ifndef REMOVE_DRA // This cuts out the whole _DRA layer
  1571. case XP_DRA_CH: // because ?
  1572. if (record->event.pressed) { // key down
  1573. unicode_hex2output (CQU_INV, CEX_INV);// ¿ ¡
  1574. }
  1575. break;
  1576. case XP_DRA_CI: // because {, ┄ «no reason» (opposite side from ━)
  1577. if (record->event.pressed) { // key down
  1578. # ifdef FULL_DRA_2NDROW
  1579. unicode_hex2output (CS_ODABRA, CB_LHORID);// 《 ┄
  1580. # else
  1581. unicode_hex2output_single (CB_LHORID);// ┄
  1582. # endif
  1583. }
  1584. break;
  1585. case XP_DRA_CJ: // because }, ┅ «no reason» (opposite side from ─)
  1586. if (record->event.pressed) { // key down
  1587. # ifdef FULL_DRA_2NDROW
  1588. unicode_hex2output (CS_CDABRA, CB_HHORID);// 》 ┅
  1589. # else
  1590. unicode_hex2output_single (CB_HHORID);// ┅
  1591. # endif
  1592. }
  1593. break;
  1594. # endif // REMOVE_DRA
  1595. /* _BON layer definitions. Due to running out of X(…), XP(…) space.*/
  1596. // ------------------------- row 4
  1597. # ifndef REMOVE_BON // Removes this layer entirely, if set.
  1598. case XP_BON_AA: // because of ' "
  1599. if (record->event.pressed) { // key down
  1600. # ifdef FULL_BON_4THROW
  1601. unicode_hex2output (CS_HQUOSB, CS_USER_DEFINED);// ‛ 🛠
  1602. # else
  1603. unicode_hex2output_single (CS_HQUOSB);// ‛
  1604. # endif
  1605. }
  1606. break;
  1607. case XP_BON_AB: // because of <, because "WASD" on _MOV
  1608. // 0x2019, single quotation mark: ’
  1609. // 0x2B06 arrow up: ⬆
  1610. if (record->event.pressed) { // key down
  1611. unicode_hex2output (CS_HQUOSE, CS_ARR_UP);// ’ ⬆
  1612. }
  1613. break;
  1614. case XP_BON_AC: // because of >
  1615. // 0x00A4 any currency symbol: ¤
  1616. // 0x1F12F Copyleft: 🄯 (means free to copy, see also © for not free to copy.)
  1617. if (record->event.pressed) { // key down
  1618. # ifdef FULL_BON_4THROW
  1619. unicode_hex2output (CS_CURREN, CS_COPYL);// ¤ 🄯
  1620. # else
  1621. unicode_hex2output_single (CS_CURREN);// ¤
  1622. # endif
  1623. }
  1624. break;
  1625. case XP_BON_AD: // because $ and ¢ can be about money, and money is often added together
  1626. // because … no reason, left over space.
  1627. // 0x2211, summation: ∑
  1628. // 0xA9, copyright: ©
  1629. if (record->event.pressed) { // key down
  1630. # ifdef FULL_BON_4THROW
  1631. unicode_hex2output (CS_CUMMU, CS_COPY);// ∑ ©
  1632. # else
  1633. unicode_hex2output_single (CS_CUMMU);// ∑
  1634. # endif
  1635. }
  1636. break;
  1637. case XP_BON_AE: // because % for percent
  1638. // 0x2030,// promille: ‰
  1639. // 0x2031,// pro ten thousandth: ‱
  1640. if (record->event.pressed) { // key down
  1641. # ifdef FULL_BON_4THROW
  1642. unicode_hex2output (CS_PROM, CS_PROTT);// ‰ ‱
  1643. # else
  1644. unicode_hex2output_single (CS_PROM);// ‰
  1645. # endif
  1646. }
  1647. break;
  1648. case XP_BON_AF: // Because ♥ is a star, ❦ and stars can be used as bullet points
  1649. // 0x2605, star: ★
  1650. // 0x066D, star small: ٭
  1651. if (record->event.pressed) { // key down
  1652. # ifdef FULL_BON_4THROW
  1653. unicode_hex2output (CS_STARB, CS_STARL);// ★ ٭
  1654. # else
  1655. unicode_hex2output_single (CS_STARB);// ★
  1656. # endif
  1657. }
  1658. break;
  1659. case XP_BON_AG: // because of 🙂 🙁
  1660. // 0x1f60A,// <smile> ^^ 😊
  1661. // 0x2368,// "Squiggly" face <sad> ⍨
  1662. # ifdef FULL_BON_4THROW
  1663. if (record->event.pressed) { // key down
  1664. unicode_hex2output (CS_SMILP, CS_SQUIG);// 😊 ⍨
  1665. }
  1666. # endif
  1667. break;
  1668. case XP_BON_AH: // because * also for multiply, because asterisk *
  1669. // 0x00D7,// multiply: ×
  1670. // 0x20F0 high asterisk: ⃰(this thing seems to behave a bit weird in vim(1) or terminal)
  1671. if (record->event.pressed) { // key down
  1672. # ifdef FULL_BON_4THROW
  1673. unicode_hex2output (CS_MULT, CS_ASTL);// × ⃰
  1674. # else
  1675. unicode_hex2output_single (CS_MULT);// ×
  1676. # endif
  1677. }
  1678. break;
  1679. case XP_BON_AI: // because ø sort of seems to divide something, and √ also does that, and close to ⁻⁺ (exponential)
  1680. // 0x221A,// square root: √
  1681. if (record->event.pressed) { // key down
  1682. # ifdef FULL_BON_4THROW
  1683. unicode_hex2output_single (CS_SQRT);// √
  1684. # endif
  1685. }
  1686. break;
  1687. case XP_BON_AJ: // because å points in the circle where this exponential minus goes, and it is right/"up" on the board
  1688. // because ⁻⁺ belong together
  1689. // 0x207B,// exponential minus sign: ⁻
  1690. // 0x207A,// exponential plus: ⁺
  1691. # ifdef FULL_BON_4THROW
  1692. if (record->event.pressed) { // key down
  1693. unicode_hex2output (CS_EXPMIN, CS_EXPPLS);// ⁻ ⁺
  1694. }
  1695. # endif
  1696. break;
  1697. // ------------------------- row 3
  1698. case XP_BON_BA: // because 1, because "WASD" on _MOV (depending on setup)
  1699. // 0x2460, "1" : ①
  1700. // 0x2B05, arrow left: ⬅
  1701. if (record->event.pressed) { // key down
  1702. unicode_hex2output (CN_1CIRC, CS_ARR_LE);// ① ⬅
  1703. }
  1704. break;
  1705. case XP_BON_BB: // because 2, because "WASD" on _MOV (depending)
  1706. // 0x2461, "2" : ②
  1707. // 0x2B07, arrow down: ⬇
  1708. if (record->event.pressed) { // key down
  1709. unicode_hex2output (CN_2CIRC, CS_ARR_DN);// ② ⬇
  1710. }
  1711. break;
  1712. case XP_BON_BC: // because 3, because "WASD" on _MOV (depending)
  1713. // 0x2462, "3" : ③
  1714. // 0x27A1, arrow right: ➡
  1715. if (record->event.pressed) { // key down
  1716. unicode_hex2output (CN_3CIRC, CS_ARR_RI);// ③ ➡
  1717. }
  1718. break;
  1719. case XP_BON_BD: // because 4, because ┏ forms a box with the other box drawings to the right/down
  1720. // 0x2463, "4" : ④
  1721. // 0x250F, box drawing heavy: ┏
  1722. if (record->event.pressed) { // key down
  1723. # ifdef BOX_DRAWINGS
  1724. unicode_hex2output (CN_4CIRC, CB_C_RIDN);// ④ ┏
  1725. # else
  1726. unicode_hex2output_single (CN_4CIRC);// ④
  1727. # endif
  1728. }
  1729. break;
  1730. case XP_BON_BE: // because 5, because ┓ forms a box
  1731. // 0x2513,box drawing heavy: ┓
  1732. if (record->event.pressed) { // key down
  1733. # ifdef BOX_DRAWINGS
  1734. unicode_hex2output (CN_5CIRC, CB_C_LEDN);// ⑤ ┓
  1735. # else
  1736. unicode_hex2output_single (CN_5CIRC);// ⑤
  1737. # endif
  1738. }
  1739. break;
  1740. case XP_BON_BF: // because 6, because ┃ continues box block
  1741. // 0x2465, "6" : ⑥
  1742. // 0x2503, box drawing heavy: ┃
  1743. if (record->event.pressed) { // key down
  1744. # ifdef BOX_DRAWINGS
  1745. unicode_hex2output (CN_6CIRC, CB_VE);// ⑥ ┃
  1746. # else
  1747. unicode_hex2output_single (CN_6CIRC);// ⑥
  1748. # endif
  1749. }
  1750. break;
  1751. case XP_BON_BG: // because 7, because ┇ continues box block
  1752. // 0x2466, "7" : ⑦
  1753. // 0x2507, dotted line verticle (heavy): ┇
  1754. if (record->event.pressed) { // key down
  1755. # ifdef BOX_DRAWINGS
  1756. unicode_hex2output (CN_7CIRC, CB_VE_DOT);// ⑦ ┇
  1757. # else
  1758. unicode_hex2output_single (CN_7CIRC);// ⑦
  1759. # endif
  1760. }
  1761. break;
  1762. case XP_BON_BH: // because 8, ╋ because 8 also has a crossing line in it
  1763. // 0x254B, crossing lines: ╋
  1764. // 0x2467, "8" : ⑨
  1765. if (record->event.pressed) { // key down
  1766. # ifdef BOX_DRAWINGS
  1767. unicode_hex2output (CN_8CIRC, CB_VE_BI);// ⑧ ╋
  1768. # else
  1769. unicode_hex2output_single (CN_8CIRC);// ⑧
  1770. # endif
  1771. }
  1772. break;
  1773. case XP_BON_BI: // because 9
  1774. // 0x2468, "9" : ⑨
  1775. // 0x2513,box drawing heavy: ┓
  1776. if (record->event.pressed) { // key down
  1777. unicode_hex2output_single (CN_9CIRC);// ⑨
  1778. }
  1779. break;
  1780. case XP_BON_BJ: // because 0, because a "0" can also be a symbol for infinity, round & round
  1781. // 0x24EA, "0" : ⓪
  1782. // 0x221E,// infinity:∞
  1783. if (record->event.pressed) { // key down
  1784. unicode_hex2output (CN_0CIRC, CS_INFIN);// ⓪ ∞
  1785. }
  1786. break;
  1787. case XP_BON_BK: // because -, because ~
  1788. // 0x2014,// dash: — (might not render differently than a hyphen - in some applications. Dash is longer).
  1789. // 0x2248,// about equal to: ≈
  1790. if (record->event.pressed) { // key down
  1791. unicode_hex2output (CS_DASH, CS_ABOUT);// — ≈
  1792. }
  1793. break;
  1794. // ------------------------- row 2
  1795. case XP_BON_CA: // because 1 above, because 「[
  1796. // 0x2039, opening single corner quotation: ‹
  1797. if (record->event.pressed) { // key down
  1798. unicode_hex2output_single (CS_GUILSLE);// ‹
  1799. }
  1800. break;
  1801. case XP_BON_CB: // because 2 above, because 」]
  1802. // 0x203A, closing sinle corner quotation: ›
  1803. if (record->event.pressed) { // key down
  1804. unicode_hex2output_single (CS_GUILSRI);// ›
  1805. }
  1806. break;
  1807. case XP_BON_CC: // because 3 above, because / (division)
  1808. // 0x00F7,// division: ÷
  1809. if (record->event.pressed) { // key down
  1810. unicode_hex2output_single (CS_DIVI);// ÷
  1811. }
  1812. break;
  1813. case XP_BON_CD: // because 4 above, ┗ because forms box
  1814. // 0x261E, hand bullet point: ☞
  1815. // 0x2517, box drawing heavy: ┗
  1816. if (record->event.pressed) { // key down
  1817. # ifdef BOX_DRAWINGS
  1818. unicode_hex2output (CS_FINGER, CB_C_RIUP);// ☞ ┗
  1819. # else
  1820. unicode_hex2output_single (CS_FINGER);// ☞
  1821. # endif
  1822. }
  1823. break;
  1824. case XP_BON_CE: // because 5 above, because =, ┛ because forms box
  1825. // 0x2260,// inequal: ≠
  1826. // 0x251B, box drawing heavy: ┛
  1827. if (record->event.pressed) { // key down
  1828. # ifdef BOX_DRAWINGS
  1829. unicode_hex2output (CS_UNEQL, CB_C_LEUP);// ≠ ┛
  1830. # else
  1831. unicode_hex2output_single (CS_UNEQL);// ≠
  1832. # endif
  1833. }
  1834. break;
  1835. case XP_BON_CF: // because ☒ , ┣ box drawings block, some place
  1836. // 0x2717, cross mark: ✗ (complements ✓)
  1837. // 0x2523, box drawing: ┣
  1838. if (record->event.pressed) { // key down
  1839. # ifdef BOX_DRAWINGS
  1840. unicode_hex2output (CS_BOTCH, CB_VE_RI);// ✗ ┣
  1841. # else
  1842. unicode_hex2output_single (CS_BOTCH);// ✗
  1843. # endif
  1844. }
  1845. break;
  1846. case XP_BON_CG: // because 7 above, because ☑ 🗹 , ┫ complements with key to its left
  1847. // 0x2713, checkmark: ✓
  1848. // 0x252B, box drawing: ┫
  1849. if (record->event.pressed) { // key down
  1850. # ifdef BOX_DRAWINGS
  1851. unicode_hex2output (CS_CHECK, CB_VE_LE);// ✓ ┫
  1852. # else
  1853. unicode_hex2output_single (CS_CHECK);// ✓
  1854. # endif
  1855. }
  1856. break;
  1857. case XP_BON_CH: // because 8 above, because ¡ (inverted exclamation mark)
  1858. // 0x26A0,// alert: ⚠
  1859. if (record->event.pressed) { // key down
  1860. unicode_hex2output_single (CS_ALERT);// ⚠
  1861. }
  1862. break;
  1863. case XP_BON_CI: // because 9 above, because 《
  1864. // 0xAB, French quotation opening: «
  1865. if (record->event.pressed) { // key down
  1866. unicode_hex2output_single (CS_GUILLE);// «
  1867. }
  1868. break;
  1869. case XP_BON_CJ: // because 0 above, because 》
  1870. // 0xBB, French quotation closing: »
  1871. if (record->event.pressed) { // key down
  1872. unicode_hex2output_single (CS_GUILRI);// »
  1873. }
  1874. break;
  1875. # endif // REMOVE_BON
  1876. }
  1877. return true;
  1878. };