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.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

action.c 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. #include "host.h"
  2. #include "timer.h"
  3. #include "keymap.h"
  4. #include "keycode.h"
  5. #include "keyboard.h"
  6. #include "mousekey.h"
  7. #include "command.h"
  8. #include "util.h"
  9. #include "debug.h"
  10. #include "action.h"
  11. static void process(keyevent_t event);
  12. static void register_code(uint8_t code);
  13. static void unregister_code(uint8_t code);
  14. static void add_mods(uint8_t mods);
  15. static void del_mods(uint8_t mods);
  16. static void set_mods(uint8_t mods);
  17. static void clear_keyboard(void);
  18. static void clear_keyboard_but_mods(void);
  19. static bool sending_anykey(void);
  20. static void layer_switch(uint8_t new_layer);
  21. /* tap */
  22. #define TAP_TIME 200
  23. static keyevent_t last_event = {};
  24. static uint8_t tap_count = 0;
  25. /* layer */
  26. uint8_t default_layer = 0;
  27. uint8_t current_layer = 0;
  28. static keyrecord_t tapping_key = {};
  29. // time 0 means no event.
  30. #define IS_TAPPING (tapping_key.event.time != 0)
  31. /* TODO:
  32. #define IS_TAPPING_KEY(key) (tapping_key.event.time != 0 && KEYEQ(tapping_key.event.key, key))
  33. */
  34. /* waiting keys buffer */
  35. #define WAITING_KEYS_BUFFER 3
  36. static keyrecord_t waiting_keys[WAITING_KEYS_BUFFER] = {};
  37. // TODO: double buffer?
  38. static keyrecord_t waiting_keys0[WAITING_KEYS_BUFFER] = {};
  39. static keyrecord_t waiting_keys1[WAITING_KEYS_BUFFER] = {};
  40. static uint8_t waiting_keys_head = 0;
  41. static bool waiting_keys_enqueue(keyevent_t event)
  42. {
  43. debug("waiting_keys["); debug_dec(waiting_keys_head); debug("] = ");
  44. debug_hex8(event.key.row); debug_hex8(event.key.col); debug("\n"); // TODO event.key.raw
  45. if (waiting_keys_head < WAITING_KEYS_BUFFER) {
  46. waiting_keys[waiting_keys_head++] = (keyrecord_t){ .event = event,
  47. .mods = host_get_mods() };
  48. } else {
  49. return true;
  50. }
  51. }
  52. static void waiting_keys_clear(void)
  53. {
  54. waiting_keys_head = 0;
  55. }
  56. static bool waiting_keys_has(keypos_t key)
  57. {
  58. for (uint8_t i = 0; i < waiting_keys_head; i++) {
  59. if KEYEQ(key, waiting_keys[i].event.key) return true;
  60. }
  61. return false;
  62. }
  63. static void waiting_keys_process_in_current_layer(void)
  64. {
  65. // TODO: in case of including layer key in waiting keys
  66. for (uint8_t i = 0; i < waiting_keys_head; i++) {
  67. debug("waiting_keys_process_in_current_layer["); debug_dec(i); debug("]\n");
  68. // TODO: no need action in waiting_keys? should get_action() in process()?
  69. process(waiting_keys[i].event);
  70. }
  71. waiting_keys_clear();
  72. }
  73. void action_exec(keyevent_t event)
  74. {
  75. if (IS_TAPPING) {
  76. /* when tap time elapses or waiting key is released */
  77. if ((timer_elapsed(tapping_key.event.time) > TAP_TIME) ||
  78. (!event.pressed && waiting_keys_has(event.key))) {
  79. // TODO process tapping_key: layer swich, modifier, ...
  80. // action is needed?
  81. debug("notap: process tapping_key.\n");
  82. process(tapping_key.event);
  83. /* Process waiting keys in new layer */
  84. waiting_keys_process_in_current_layer();
  85. }
  86. /* when tapping key is released within tap time */
  87. else if (!event.pressed && KEYEQ(event.key, tapping_key.event.key)) {
  88. /* tap key down */
  89. debug("tap("); debug_hex8(tap_count); debug(")[tapping_key](register): "); debug_hex8(tapping_key.action.layer.code); debug("\n");
  90. register_code(tapping_key.action.layer.code);
  91. tapping_key = (keyrecord_t){};
  92. /* process waiting keys */
  93. waiting_keys_process_in_current_layer();
  94. }
  95. }
  96. // not real event. event just to handle time out of tapping key.
  97. if (IS_NOEVENT(event)) {
  98. return;
  99. }
  100. /* count up tap when key is up */
  101. // key: d u d u d
  102. // tap: 0 1 1 2 2
  103. // key: u d u d u
  104. // tap: 0 0 1 1 2
  105. if (KEYEQ(event.key, last_event.key) && timer_elapsed(last_event.time) <= TAP_TIME) {
  106. if (!event.pressed) tap_count++;
  107. } else {
  108. tap_count = 0;
  109. }
  110. /* store key events while tapping */
  111. if (IS_TAPPING) {
  112. // TODO: action is needed?
  113. waiting_keys_enqueue(event);
  114. } else {
  115. process(event);
  116. }
  117. /* last event */
  118. last_event = event;
  119. }
  120. static void process(keyevent_t event)
  121. {
  122. action_t action = keymap_get_action(current_layer, event.key.row, event.key.col);
  123. debug("action: "); debug_hex16(action.code);
  124. if (event.pressed) debug("[down]\n"); else debug("[up]\n");
  125. switch (action.kind.id) {
  126. /* Key and Mods */
  127. case ACT_LMODS:
  128. // |pressed |released
  129. // --------------+---------------------------------+------------
  130. // key |down(key) |up(key)
  131. // mods |add(mods) |del(mods)
  132. // key with mods |add(mods), down(key), unset(mods)|up(key)
  133. if (event.pressed) {
  134. uint8_t tmp_mods = host_get_mods();
  135. if (action.key.mods) {
  136. host_add_mods(action.key.mods);
  137. host_send_keyboard_report();
  138. }
  139. register_code(action.key.code);
  140. if (action.key.mods && action.key.code) {
  141. host_set_mods(tmp_mods);
  142. host_send_keyboard_report();
  143. }
  144. } else {
  145. if (action.key.mods && !action.key.code) {
  146. host_del_mods(action.key.mods);
  147. host_send_keyboard_report();
  148. }
  149. unregister_code(action.key.code);
  150. }
  151. break;
  152. case ACT_RMODS:
  153. // |pressed |released
  154. // --------------+---------------------------------+------------
  155. // key |down(key) |up(key)
  156. // mods |add(mods) |del(mods)
  157. // key with mods |add(mods), down(key), unset(mods)|up(key)
  158. if (event.pressed) {
  159. uint8_t tmp_mods = host_get_mods();
  160. if (action.key.mods) {
  161. host_add_mods(action.key.mods<<4);
  162. host_send_keyboard_report();
  163. }
  164. register_code(action.key.code);
  165. if (action.key.mods && action.key.code) {
  166. host_set_mods(tmp_mods);
  167. host_send_keyboard_report();
  168. }
  169. } else {
  170. if (action.key.mods && !action.key.code) {
  171. host_del_mods(action.key.mods<<4);
  172. host_send_keyboard_report();
  173. }
  174. unregister_code(action.key.code);
  175. }
  176. break;
  177. case ACT_LMODS_TAP:
  178. if (event.pressed) {
  179. if (tap_count == 0) {
  180. if (host_has_anykey()) {
  181. // This key is a modifier essentially.
  182. // Prioritize mods when key jam or rollover
  183. add_mods(action.key.mods);
  184. } else {
  185. if (IS_TAPPING && KEYEQ(tapping_key.event.key, event.key)) {
  186. // no tapping
  187. add_mods(action.key.mods);
  188. tapping_key = (keyrecord_t){};
  189. } else {
  190. debug("tapping lmods("); debug_hex8(action.key.mods); debug(")\n");
  191. tapping_key = (keyrecord_t){
  192. .event = event,
  193. .action = action,
  194. .mods = host_get_mods()
  195. };
  196. }
  197. }
  198. } else {
  199. // pressed after tapping
  200. debug("tap("); debug_hex(tap_count); debug(")[lmods](register): "); debug_hex8(action.key.code); debug("\n");
  201. register_code(action.key.code);
  202. }
  203. } else {
  204. if (tap_count == 0) {
  205. debug("tap(00)[lmods](del_mods): "); debug_hex8(action.key.mods); debug("\n");
  206. del_mods(action.key.mods);
  207. } else if (tap_count == 1) {
  208. debug("tap(01)[lmods](del_mods/unregister): "); debug_hex8(action.key.mods); debug(" "); debug_hex8(action.key.code); debug("\n");
  209. del_mods(action.key.mods);
  210. unregister_code(action.key.code);
  211. } else {
  212. debug("tap("); debug_hex(tap_count); debug(")[lmods](unregister): "); debug_hex8(action.key.code); debug("\n");
  213. unregister_code(action.key.code);
  214. }
  215. }
  216. break;
  217. case ACT_RMODS_TAP:
  218. if (event.pressed) {
  219. if (tap_count == 0) {
  220. if (host_has_anykey()) {
  221. // This key is a modifier essentially.
  222. // Prioritize mods when key jam or rollover
  223. add_mods(action.key.mods<<4);
  224. } else {
  225. if (IS_TAPPING && KEYEQ(tapping_key.event.key, event.key)) {
  226. // no tapping
  227. add_mods(action.key.mods<<4);
  228. tapping_key = (keyrecord_t){};
  229. } else {
  230. debug("tapping rmods("); debug_hex8(action.key.mods); debug(")\n");
  231. tapping_key = (keyrecord_t){
  232. .event = event,
  233. .action = action,
  234. .mods = host_get_mods()
  235. };
  236. }
  237. }
  238. } else {
  239. // pressed after tapping
  240. debug("tap("); debug_hex(tap_count); debug(")[rmods](register): "); debug_hex8(action.key.code); debug("\n");
  241. register_code(action.key.code);
  242. }
  243. } else {
  244. if (tap_count == 0) {
  245. debug("tap(00)[rmods](del_mods): "); debug_hex8(action.key.mods); debug("\n");
  246. del_mods(action.key.mods<<4);
  247. } else if (tap_count == 1) {
  248. debug("tap(01)[rmods](del_mods/unregister): "); debug_hex8(action.key.mods); debug(" "); debug_hex8(action.key.code); debug("\n");
  249. del_mods(action.key.mods<<4);
  250. unregister_code(action.key.code);
  251. } else {
  252. debug("tap("); debug_hex(tap_count); debug(")[rmods](unregister): "); debug_hex8(action.key.code); debug("\n");
  253. unregister_code(action.key.code);
  254. }
  255. }
  256. break;
  257. /* other HID usage */
  258. case ACT_USAGE:
  259. #ifdef EXTRAKEY_ENABLE
  260. switch (action.usage.page) {
  261. case ACTION_USAGE_PAGE_SYSTEM:
  262. if (event.pressed) {
  263. host_system_send(action.usage.code);
  264. } else {
  265. host_system_send(0);
  266. }
  267. break;
  268. case ACTION_USAGE_PAGE_CONSUMER:
  269. if (event.pressed) {
  270. host_consumer_send(action.usage.code);
  271. } else {
  272. host_consumer_send(0);
  273. }
  274. break;
  275. }
  276. #endif
  277. break;
  278. /* Mouse key */
  279. case ACT_MOUSEKEY:
  280. #ifdef MOUSEKEY_ENABLE
  281. if (event.pressed) {
  282. mousekey_on(action.key.code);
  283. mousekey_send();
  284. } else {
  285. mousekey_off(action.key.code);
  286. mousekey_send();
  287. }
  288. #endif
  289. break;
  290. /* Layer key */
  291. case ACT_LAYER_PRESSED:
  292. // layer action when pressed
  293. switch (action.layer.code) {
  294. case 0x00:
  295. if (event.pressed) {
  296. layer_switch(action.layer.opt);
  297. }
  298. break;
  299. case 0xF0:
  300. // TODO: tap toggle
  301. break;
  302. case 0xFF:
  303. if (event.pressed) {
  304. default_layer = action.layer.opt;
  305. layer_switch(default_layer);
  306. }
  307. break;
  308. default:
  309. // with tap key
  310. if (event.pressed) {
  311. if (tap_count == 0) {
  312. if (host_has_anykey()) {
  313. // This key is a normal key than a leyar key essentially.
  314. // Prioritize 'tap key' when key jam or rollover
  315. register_code(action.layer.code);
  316. } else {
  317. if (IS_TAPPING && KEYEQ(tapping_key.event.key, event.key)) {
  318. layer_switch(action.layer.opt);
  319. tapping_key = (keyrecord_t){};
  320. } else {
  321. debug("tapping layer("); debug_hex8(action.layer.opt); debug(")\n");
  322. tapping_key = (keyrecord_t){
  323. .event = event,
  324. .action = action,
  325. .mods = host_get_mods()
  326. };
  327. }
  328. }
  329. } else if (tap_count > 0) {
  330. // pressed after tapping
  331. debug("tap[layer](register): "); debug_hex(tap_count); debug("\n");
  332. register_code(action.layer.code);
  333. }
  334. } else {
  335. // released after tapping
  336. debug("tap[layer](unregister): "); debug_hex(tap_count); debug("\n");
  337. unregister_code(action.layer.code);
  338. }
  339. break;
  340. }
  341. break;
  342. case ACT_LAYER_RELEASED:
  343. switch (action.layer.code) {
  344. case 0x00:
  345. if (!event.pressed) {
  346. layer_switch(action.layer.opt);
  347. }
  348. break;
  349. case 0xF0:
  350. // Ignored. LAYER_RELEASED with tap toggle is invalid action.
  351. break;
  352. case 0xFF:
  353. if (!event.pressed) {
  354. default_layer = action.layer.opt;
  355. layer_switch(default_layer);
  356. }
  357. break;
  358. default:
  359. // Ignored. LAYER_RELEASED with tap key is invalid action.
  360. break;
  361. }
  362. break;
  363. case ACT_LAYER_BIT:
  364. switch (action.layer.code) {
  365. case 0x00:
  366. if (event.pressed) {
  367. layer_switch(current_layer | action.layer.opt);
  368. } else {
  369. layer_switch(current_layer & ~action.layer.opt);
  370. }
  371. break;
  372. case 0xF0:
  373. // TODO: tap toggle
  374. break;
  375. case 0xFF:
  376. // change default layer
  377. if (event.pressed) {
  378. default_layer = current_layer | action.layer.opt;
  379. layer_switch(default_layer);
  380. } else {
  381. default_layer = current_layer & ~action.layer.opt;
  382. layer_switch(default_layer);
  383. }
  384. break;
  385. default:
  386. // TODO: see ACT_LAYER_PRESSED code
  387. // with tap key
  388. if (event.pressed) {
  389. if (tap_count == 0) {
  390. if (host_has_anykey()) {
  391. register_code(action.layer.code);
  392. } else {
  393. tapping_key = (keyrecord_t){
  394. .event = event,
  395. .action = action,
  396. .mods = keyboard_report->mods
  397. };
  398. }
  399. } else if (tap_count > 0) {
  400. debug("tap[layer_bit](register): "); debug_hex(tap_count); debug("\n");
  401. register_code(action.layer.code);
  402. }
  403. } else {
  404. if (tap_count == 0) {
  405. // no tap
  406. layer_switch(current_layer & ~action.layer.opt);
  407. } else if (tap_count == 1) {
  408. // tap
  409. register_code(action.layer.code);
  410. }
  411. unregister_code(action.layer.code);
  412. }
  413. break;
  414. }
  415. case ACT_LAYER_EXT:
  416. switch (action.layer.opt) {
  417. case 0x00:
  418. // set default layer when pressed
  419. switch (action.layer.code) {
  420. case 0x00:
  421. if (event.pressed) {
  422. layer_switch(default_layer);
  423. }
  424. break;
  425. case 0xF0:
  426. // TODO: tap toggle
  427. break;
  428. case 0xFF:
  429. if (event.pressed) {
  430. default_layer = current_layer;
  431. layer_switch(default_layer);
  432. }
  433. break;
  434. default:
  435. // TODO: tap key
  436. break;
  437. }
  438. break;
  439. case 0x01:
  440. // set default layer when released
  441. switch (action.layer.code) {
  442. case 0x00:
  443. if (!event.pressed) {
  444. layer_switch(default_layer);
  445. }
  446. break;
  447. case 0xFF:
  448. if (!event.pressed) {
  449. default_layer = current_layer;
  450. layer_switch(default_layer);
  451. }
  452. break;
  453. case 0xF0:
  454. default:
  455. // Ignore tap.
  456. if (!event.pressed) {
  457. layer_switch(default_layer);
  458. }
  459. break;
  460. }
  461. break;
  462. }
  463. break;
  464. /* Extentions */
  465. case ACT_MACRO:
  466. case ACT_COMMAND:
  467. case ACT_FUNCTION:
  468. default:
  469. break;
  470. }
  471. }
  472. static void register_code(uint8_t code)
  473. {
  474. if (code == KC_NO) {
  475. return;
  476. }
  477. else if IS_KEY(code) {
  478. // TODO: should push command_proc out of this block?
  479. if (!command_proc(code)) {
  480. host_add_key(code);
  481. host_send_keyboard_report();
  482. }
  483. }
  484. else if IS_MOD(code) {
  485. host_add_mods(MOD_BIT(code));
  486. host_send_keyboard_report();
  487. }
  488. }
  489. static void unregister_code(uint8_t code)
  490. {
  491. if IS_KEY(code) {
  492. host_del_key(code);
  493. host_send_keyboard_report();
  494. }
  495. else if IS_MOD(code) {
  496. host_del_mods(MOD_BIT(code));
  497. host_send_keyboard_report();
  498. }
  499. }
  500. static void add_mods(uint8_t mods)
  501. {
  502. if (mods) {
  503. host_add_mods(mods);
  504. host_send_keyboard_report();
  505. }
  506. }
  507. static void del_mods(uint8_t mods)
  508. {
  509. if (mods) {
  510. host_del_mods(mods);
  511. host_send_keyboard_report();
  512. }
  513. }
  514. static void set_mods(uint8_t mods)
  515. {
  516. host_set_mods(mods);
  517. host_send_keyboard_report();
  518. }
  519. static void clear_keyboard(void)
  520. {
  521. host_clear_mods();
  522. clear_keyboard_but_mods();
  523. }
  524. static void clear_keyboard_but_mods(void)
  525. {
  526. host_clear_keys();
  527. host_send_keyboard_report();
  528. #ifdef MOUSEKEY_ENABLE
  529. mousekey_clear();
  530. mousekey_send();
  531. #endif
  532. #ifdef EXTRAKEY_ENABLE
  533. host_system_send(0);
  534. host_consumer_send(0);
  535. #endif
  536. }
  537. static bool sending_anykey(void)
  538. {
  539. return (host_has_anykey() || host_mouse_in_use() ||
  540. host_last_sysytem_report() || host_last_consumer_report());
  541. }
  542. static void layer_switch(uint8_t new_layer)
  543. {
  544. if (current_layer != new_layer) {
  545. debug("Layer Switch: "); debug_hex(current_layer);
  546. debug(" -> "); debug_hex(new_layer); debug("\n");
  547. current_layer = new_layer;
  548. clear_keyboard_but_mods(); // To avoid stuck keys
  549. // TODO: update mods with full scan of matrix? if modifier changes between layers
  550. }
  551. }