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 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  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. void test_func(keyevent_t event, uint8_t opt)
  13. {
  14. if (event.pressed) {
  15. debug("test_func:pressed: "); debug_hex(opt); debug("\n");
  16. } else {
  17. debug("test_func:released: "); debug_hex(opt); debug("\n");
  18. }
  19. }
  20. /* layer */
  21. uint8_t default_layer = 0;
  22. uint8_t current_layer = 0;
  23. /* tap term(ms) */
  24. #define TAP_TIME 200
  25. /* This counts up when tap occurs */
  26. uint8_t tap_count = 0;
  27. keyevent_t tapping_event = {};
  28. /* TAPPING: This indicates that whether tap or not is not decided yet. */
  29. // NOTE: keyevent_t.time 0 means no event.
  30. #define IS_TAPPING(k) (tapping_event.time != 0 && KEYEQ(tapping_event.key, (k)))
  31. /* waiting keys buffer */
  32. #define WAITING_KEYS_BUFFER 8
  33. static keyevent_t waiting_events[WAITING_KEYS_BUFFER] = {};
  34. static uint8_t waiting_events_head = 0;
  35. static uint8_t waiting_events_tail = 0;
  36. static bool waiting_events_enqueue(keyevent_t event)
  37. {
  38. if (IS_NOEVENT(event)) { return true; }
  39. if ((waiting_events_head + 1) % WAITING_KEYS_BUFFER == waiting_events_tail) {
  40. debug("waiting_events_enqueue: Over flow.\n");
  41. return false;
  42. }
  43. debug("waiting_events["); debug_dec(waiting_events_head); debug("] = ");
  44. debug_hex16(event.key.raw); debug("\n");
  45. waiting_events[waiting_events_head] = event;
  46. waiting_events_head = (waiting_events_head + 1)% WAITING_KEYS_BUFFER;
  47. return true;
  48. }
  49. static keyevent_t waiting_events_dequeue(void)
  50. {
  51. if (waiting_events_head == waiting_events_tail) {
  52. return (keyevent_t){};
  53. }
  54. uint8_t tail = waiting_events_tail;
  55. waiting_events_tail = waiting_events_tail + 1 % WAITING_KEYS_BUFFER;
  56. return waiting_events[tail];
  57. }
  58. static void waiting_events_clear(void)
  59. {
  60. waiting_events_head = 0;
  61. waiting_events_tail = 0;
  62. }
  63. static bool waiting_events_has(key_t key)
  64. {
  65. for (uint8_t i = waiting_events_tail; i != waiting_events_head; i = (i + 1) % WAITING_KEYS_BUFFER) {
  66. if KEYEQ(key, waiting_events[i].key) return true;
  67. }
  68. return false;
  69. }
  70. static void waiting_events_process_in_current_layer(void)
  71. {
  72. // TODO: in case of including tap key in waiting keys
  73. for (uint8_t i = waiting_events_tail; i != waiting_events_head; i = (i + 1) % WAITING_KEYS_BUFFER) {
  74. debug("waiting_events_process_in_current_layer["); debug_dec(i); debug("]\n");
  75. process(waiting_events[i]);
  76. }
  77. waiting_events_clear();
  78. }
  79. static bool waiting_events_has_anykey_pressed(void)
  80. {
  81. for (uint8_t i = waiting_events_tail; i != waiting_events_head; i = (i + 1) % WAITING_KEYS_BUFFER) {
  82. if (waiting_events[i].pressed) return true;
  83. }
  84. return false;
  85. }
  86. void action_exec(keyevent_t event)
  87. {
  88. if (!IS_NOEVENT(event)) {
  89. debug("event: "); debug_hex16(event.key.raw);
  90. debug("[");
  91. if (event.pressed) debug("down"); else debug("up");
  92. debug("]\n");
  93. }
  94. // In tapping term
  95. if (tapping_event.time && timer_elapsed(tapping_event.time) < TAP_TIME) {
  96. if (tapping_event.pressed) {
  97. if (!event.pressed && KEYEQ(tapping_event.key, event.key)) {
  98. debug("Tapping: Release tap key.\n");
  99. if (tap_count == 0) {
  100. debug("Tapping: First tap.\n");
  101. // count up on release
  102. tap_count++;
  103. process(tapping_event);
  104. waiting_events_process_in_current_layer();
  105. }
  106. tapping_event = event;
  107. process(event);
  108. } else if (!event.pressed && waiting_events_has(event.key)) {
  109. debug("Tapping: End(No tap by typing waiting key).\n");
  110. process(tapping_event);
  111. waiting_events_process_in_current_layer();
  112. process(event);
  113. tap_count = 0;
  114. tapping_event = (keyevent_t){};
  115. } else {
  116. if (!IS_NOEVENT(event)) debug("Tapping: other key while tapping.\n");
  117. if (tap_count == 0) {
  118. // store event
  119. waiting_events_enqueue(event);
  120. return;
  121. }
  122. process(event);
  123. }
  124. } else {
  125. // Waiting for sequential tap
  126. if (tap_count && event.pressed && KEYEQ(tapping_event.key, event.key)) {
  127. tap_count++;
  128. tapping_event = event;
  129. debug("Tapping: Sequential tap("); debug_hex(tap_count); debug(")\n");
  130. process(event);
  131. } else if (event.pressed && is_tap_key(event)) {
  132. // Sequential tap can be interfered with other tap key.
  133. debug("Tapping: Start with interfering other tap.\n");
  134. tapping_event = event;
  135. tap_count = 0;
  136. waiting_events_clear();
  137. } else {
  138. if (!IS_NOEVENT(event)) debug("Tapping: other key just after tap.\n");
  139. process(event);
  140. }
  141. }
  142. }
  143. // Not in tapping term
  144. else {
  145. if (tapping_event.time) {
  146. if (tapping_event.pressed) {
  147. if (tap_count == 0) {
  148. // Not tap, holding down normal key.
  149. debug("Tapping: End. Not tap(time out).\n");
  150. process(tapping_event);
  151. waiting_events_process_in_current_layer();
  152. tap_count = 0;
  153. tapping_event = (keyevent_t){};
  154. process(event);
  155. } else {
  156. // Holding down last tap key. waiting for releasing last tap key.
  157. if (!event.pressed && KEYEQ(tapping_event.key, event.key)) {
  158. debug("Tapping: End. Release holding last tap(time out).\n");
  159. process(event);
  160. // clear after release last tap key
  161. tap_count = 0;
  162. tapping_event = (keyevent_t){};
  163. waiting_events_clear();
  164. } else if (event.pressed && is_tap_key(event)) {
  165. debug("Tapping: Start with forcing to release last tap(time out).\n");
  166. process((keyevent_t){
  167. .key = tapping_event.key,
  168. .time = event.time,
  169. .pressed = false });
  170. tap_count = 0;
  171. tapping_event = event;
  172. waiting_events_clear();
  173. } else {
  174. if (!IS_NOEVENT(event)) debug("Tapping: other key while waiting for release of last tap(time out).\n");
  175. process(event);
  176. }
  177. }
  178. } else {
  179. // time out for sequential tap after complete last tap
  180. debug("Tapping: End(Time out after releasing last tap).\n");
  181. tap_count = 0;
  182. tapping_event = (keyevent_t){};
  183. waiting_events_clear();
  184. process(event);
  185. }
  186. } else {
  187. // Normal state without tapping
  188. if (event.pressed && is_tap_key(event)) {
  189. debug("Tapping: Start(Press tap key).\n");
  190. tapping_event = event;
  191. tap_count = 0;
  192. waiting_events_clear();
  193. } else {
  194. //debug("Normal event(No tapping)\n");
  195. process(event);
  196. }
  197. }
  198. }
  199. }
  200. static void process(keyevent_t event)
  201. {
  202. if (IS_NOEVENT(event)) { return; }
  203. action_t action = keymap_get_action(current_layer, event.key.pos.row, event.key.pos.col);
  204. debug("action: "); debug_hex16(action.code);
  205. if (event.pressed) debug("[down]\n"); else debug("[up]\n");
  206. switch (action.kind.id) {
  207. /* Key and Mods */
  208. case ACT_LMODS:
  209. // |pressed |released
  210. // --------------+---------------------------------+------------
  211. // key |down(key) |up(key)
  212. // mods |add(mods) |del(mods)
  213. // key with mods |add(mods), down(key), unset(mods)|up(key)
  214. if (event.pressed) {
  215. uint8_t tmp_mods = host_get_mods();
  216. if (action.key.mods) {
  217. host_add_mods(action.key.mods);
  218. host_send_keyboard_report();
  219. }
  220. register_code(action.key.code);
  221. if (action.key.mods && action.key.code) {
  222. host_set_mods(tmp_mods);
  223. host_send_keyboard_report();
  224. }
  225. } else {
  226. if (action.key.mods && !action.key.code) {
  227. host_del_mods(action.key.mods);
  228. host_send_keyboard_report();
  229. }
  230. unregister_code(action.key.code);
  231. }
  232. break;
  233. case ACT_RMODS:
  234. // |pressed |released
  235. // --------------+---------------------------------+------------
  236. // key |down(key) |up(key)
  237. // mods |add(mods) |del(mods)
  238. // key with mods |add(mods), down(key), unset(mods)|up(key)
  239. if (event.pressed) {
  240. uint8_t tmp_mods = host_get_mods();
  241. if (action.key.mods) {
  242. host_add_mods(action.key.mods<<4);
  243. host_send_keyboard_report();
  244. }
  245. register_code(action.key.code);
  246. if (action.key.mods && action.key.code) {
  247. host_set_mods(tmp_mods);
  248. host_send_keyboard_report();
  249. }
  250. } else {
  251. if (action.key.mods && !action.key.code) {
  252. host_del_mods(action.key.mods<<4);
  253. host_send_keyboard_report();
  254. }
  255. unregister_code(action.key.code);
  256. }
  257. break;
  258. case ACT_LMODS_TAP:
  259. case ACT_RMODS_TAP:
  260. {
  261. uint8_t tmp_mods = (action.kind.id == ACT_LMODS_TAP) ? action.key.mods :
  262. action.key.mods<<4;
  263. if (event.pressed) {
  264. if (IS_TAPPING(event.key) && tap_count > 0) {
  265. if (waiting_events_has_anykey_pressed()) {
  266. debug("MODS_TAP: Tap: Cancel: add_mods\n");
  267. tap_count = 0;
  268. add_mods(tmp_mods);
  269. } else {
  270. debug("MODS_TAP: Tap: register_code\n");
  271. register_code(action.key.code);
  272. }
  273. } else {
  274. debug("MODS_TAP: No tap: add_mods\n");
  275. add_mods(tmp_mods);
  276. }
  277. } else {
  278. if (IS_TAPPING(event.key) && tap_count > 0) {
  279. debug("MODS_TAP: Tap: unregister_code\n");
  280. unregister_code(action.key.code);
  281. } else {
  282. debug("MODS_TAP: No tap: add_mods\n");
  283. del_mods(tmp_mods);
  284. }
  285. }
  286. }
  287. break;
  288. /* other HID usage */
  289. case ACT_USAGE:
  290. #ifdef EXTRAKEY_ENABLE
  291. switch (action.usage.page) {
  292. case ACTION_USAGE_PAGE_SYSTEM:
  293. if (event.pressed) {
  294. host_system_send(action.usage.code);
  295. } else {
  296. host_system_send(0);
  297. }
  298. break;
  299. case ACTION_USAGE_PAGE_CONSUMER:
  300. if (event.pressed) {
  301. host_consumer_send(action.usage.code);
  302. } else {
  303. host_consumer_send(0);
  304. }
  305. break;
  306. }
  307. #endif
  308. break;
  309. /* Mouse key */
  310. case ACT_MOUSEKEY:
  311. #ifdef MOUSEKEY_ENABLE
  312. if (event.pressed) {
  313. mousekey_on(action.key.code);
  314. mousekey_send();
  315. } else {
  316. mousekey_off(action.key.code);
  317. mousekey_send();
  318. }
  319. #endif
  320. break;
  321. /* Layer key */
  322. case ACT_LAYER_PRESSED:
  323. // layer action when pressed
  324. switch (action.layer.code) {
  325. case 0x00:
  326. if (event.pressed) {
  327. layer_switch(action.layer.opt);
  328. }
  329. break;
  330. case 0xF0:
  331. // TODO: tap toggle
  332. break;
  333. case 0xFF:
  334. if (event.pressed) {
  335. default_layer = action.layer.opt;
  336. layer_switch(default_layer);
  337. }
  338. break;
  339. default:
  340. // with tap key
  341. if (event.pressed) {
  342. if (IS_TAPPING(event.key)) {
  343. if (tap_count > 0) {
  344. debug("LAYER_PRESSED: Tap: register_code\n");
  345. register_code(action.layer.code);
  346. } else {
  347. debug("LAYER_PRESSED: No tap: layer_switch\n");
  348. layer_switch(action.layer.opt);
  349. }
  350. } else {
  351. // TODO: while other key tapping
  352. debug("LAYER_PRESSED: No tap: layer_switch\n");
  353. layer_switch(action.layer.opt);
  354. }
  355. /*
  356. if (IS_TAPPING(event.key) && tap_count > 0) {
  357. debug("LAYER_PRESSED: Tap: register_code\n");
  358. register_code(action.layer.code);
  359. } else {
  360. debug("LAYER_PRESSED: No tap: layer_switch\n");
  361. layer_switch(action.layer.opt);
  362. }
  363. */
  364. } else {
  365. if (IS_TAPPING(event.key) && tap_count > 0) {
  366. debug("LAYER_PRESSED: Tap: unregister_code\n");
  367. unregister_code(action.layer.code);
  368. } else {
  369. debug("LAYER_PRESSED: No tap: NO ACTION\n");
  370. }
  371. }
  372. break;
  373. }
  374. break;
  375. case ACT_LAYER_RELEASED:
  376. switch (action.layer.code) {
  377. case 0x00:
  378. if (!event.pressed) {
  379. layer_switch(action.layer.opt);
  380. }
  381. break;
  382. case 0xF0:
  383. // Ignored. LAYER_RELEASED with tap toggle is invalid action.
  384. break;
  385. case 0xFF:
  386. if (!event.pressed) {
  387. default_layer = action.layer.opt;
  388. layer_switch(default_layer);
  389. }
  390. break;
  391. default:
  392. // Ignored. LAYER_RELEASED with tap key is invalid action.
  393. break;
  394. }
  395. break;
  396. case ACT_LAYER_BIT:
  397. switch (action.layer.code) {
  398. case 0x00:
  399. if (event.pressed) {
  400. layer_switch(current_layer | action.layer.opt);
  401. } else {
  402. layer_switch(current_layer & ~action.layer.opt);
  403. }
  404. break;
  405. case 0xF0:
  406. // TODO: tap toggle
  407. break;
  408. case 0xFF:
  409. // change default layer
  410. if (event.pressed) {
  411. default_layer = current_layer | action.layer.opt;
  412. layer_switch(default_layer);
  413. } else {
  414. default_layer = current_layer & ~action.layer.opt;
  415. layer_switch(default_layer);
  416. }
  417. break;
  418. default:
  419. // with tap key
  420. if (event.pressed) {
  421. if (IS_TAPPING(event.key) && tap_count > 0) {
  422. debug("LAYER_BIT: Tap: register_code\n");
  423. register_code(action.layer.code);
  424. } else {
  425. debug("LAYER_BIT: No tap: layer_switch(bit on)\n");
  426. layer_switch(current_layer | action.layer.opt);
  427. }
  428. } else {
  429. if (IS_TAPPING(event.key) && tap_count > 0) {
  430. debug("LAYER_BIT: Tap: unregister_code\n");
  431. unregister_code(action.layer.code);
  432. } else {
  433. debug("LAYER_BIT: No tap: layer_switch(bit off)\n");
  434. layer_switch(current_layer & ~action.layer.opt);
  435. }
  436. }
  437. break;
  438. }
  439. case ACT_LAYER_EXT:
  440. switch (action.layer.opt) {
  441. case 0x00:
  442. // set default layer when pressed
  443. switch (action.layer.code) {
  444. case 0x00:
  445. if (event.pressed) {
  446. layer_switch(default_layer);
  447. }
  448. break;
  449. case 0xF0:
  450. // TODO: tap toggle
  451. break;
  452. case 0xFF:
  453. if (event.pressed) {
  454. default_layer = current_layer;
  455. layer_switch(default_layer);
  456. }
  457. break;
  458. default:
  459. // TODO: tap key
  460. break;
  461. }
  462. break;
  463. case 0x01:
  464. // set default layer when released
  465. switch (action.layer.code) {
  466. case 0x00:
  467. if (!event.pressed) {
  468. layer_switch(default_layer);
  469. }
  470. break;
  471. case 0xFF:
  472. if (!event.pressed) {
  473. default_layer = current_layer;
  474. layer_switch(default_layer);
  475. }
  476. break;
  477. case 0xF0:
  478. default:
  479. // Ignore tap.
  480. if (!event.pressed) {
  481. layer_switch(default_layer);
  482. }
  483. break;
  484. }
  485. break;
  486. }
  487. break;
  488. /* Extentions */
  489. case ACT_MACRO:
  490. break;
  491. case ACT_COMMAND:
  492. break;
  493. case ACT_FUNCTION:
  494. action_call_function(event, action.func.id);
  495. //test_func(event, action.func.opt);
  496. break;
  497. default:
  498. break;
  499. }
  500. }
  501. /*
  502. * Utilities for actions.
  503. */
  504. void register_code(uint8_t code)
  505. {
  506. if (code == KC_NO) {
  507. return;
  508. }
  509. else if IS_KEY(code) {
  510. // TODO: should push command_proc out of this block?
  511. if (!command_proc(code)) {
  512. host_add_key(code);
  513. host_send_keyboard_report();
  514. }
  515. }
  516. else if IS_MOD(code) {
  517. host_add_mods(MOD_BIT(code));
  518. host_send_keyboard_report();
  519. }
  520. }
  521. void unregister_code(uint8_t code)
  522. {
  523. if IS_KEY(code) {
  524. host_del_key(code);
  525. host_send_keyboard_report();
  526. }
  527. else if IS_MOD(code) {
  528. host_del_mods(MOD_BIT(code));
  529. host_send_keyboard_report();
  530. }
  531. }
  532. void add_mods(uint8_t mods)
  533. {
  534. if (mods) {
  535. host_add_mods(mods);
  536. host_send_keyboard_report();
  537. }
  538. }
  539. void del_mods(uint8_t mods)
  540. {
  541. if (mods) {
  542. host_del_mods(mods);
  543. host_send_keyboard_report();
  544. }
  545. }
  546. void set_mods(uint8_t mods)
  547. {
  548. host_set_mods(mods);
  549. host_send_keyboard_report();
  550. }
  551. void clear_keyboard(void)
  552. {
  553. host_clear_mods();
  554. clear_keyboard_but_mods();
  555. }
  556. void clear_keyboard_but_mods(void)
  557. {
  558. host_clear_keys();
  559. host_send_keyboard_report();
  560. #ifdef MOUSEKEY_ENABLE
  561. mousekey_clear();
  562. mousekey_send();
  563. #endif
  564. #ifdef EXTRAKEY_ENABLE
  565. host_system_send(0);
  566. host_consumer_send(0);
  567. #endif
  568. }
  569. bool sending_anykey(void)
  570. {
  571. return (host_has_anykey() || host_mouse_in_use() ||
  572. host_last_sysytem_report() || host_last_consumer_report());
  573. }
  574. void layer_switch(uint8_t new_layer)
  575. {
  576. if (current_layer != new_layer) {
  577. debug("Layer Switch: "); debug_hex(current_layer);
  578. debug(" -> "); debug_hex(new_layer); debug("\n");
  579. current_layer = new_layer;
  580. clear_keyboard_but_mods(); // To avoid stuck keys
  581. // TODO: update mods with full scan of matrix? if modifier changes between layers
  582. }
  583. }
  584. bool is_tap_key(keyevent_t event)
  585. {
  586. action_t action = keymap_get_action(current_layer, event.key.pos.row, event.key.pos.col);
  587. switch (action.kind.id) {
  588. case ACT_LMODS_TAP:
  589. case ACT_RMODS_TAP:
  590. return true;
  591. case ACT_LAYER_PRESSED:
  592. case ACT_LAYER_BIT:
  593. switch (action.layer.code) {
  594. case 0x00:
  595. case 0xF1 ... 0xFF:
  596. return false;
  597. case 0xF0:
  598. default:
  599. return true;
  600. }
  601. return false;
  602. case ACT_FUNCTION:
  603. if (action.func.opt & 0x1) {
  604. return true;
  605. }
  606. return false;
  607. }
  608. return false;
  609. }