-static void process(keyrecord_t *record);
-
-// TODO
-/* layer */
-uint8_t default_layer = 0;
-uint8_t current_layer = 0;
-
-/* tap term(ms) */
-#define TAP_TERM 200
-
-/* This counts up when tap occurs */
-uint8_t tap_count = 0;
-keyevent_t tapping_event = {};
-keyrecord_t tapping_key = {};
-
-/* TAPPING: This indicates that whether tap or not is not decided yet. */
-// NOTE: keyevent_t.time 0 means no event.
-#define IS_TAPPING() (tapping_key.event.time != 0)
-#define IS_TAPPING_PRESSED() (IS_TAPPING() && tapping_key.event.pressed)
-#define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed)
-#define IS_TAPPING_KEY(k) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (k)))
-#define WITHIN_TAP_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < TAP_TERM)
-
-/* waiting keys buffer */
-#define WAITING_BUFFER_SIZE 8
-static keyrecord_t waiting_buffer[WAITING_BUFFER_SIZE] = {};
-/* point to empty cell to enq */
-static uint8_t waiting_buffer_head = 0;
-/* point to the oldest data cell to deq */
-static uint8_t waiting_buffer_tail = 0;
-
-static bool waiting_buffer_enq(keyrecord_t record)
-{
- if (IS_NOEVENT(record.event)) {
- return true;
- }
-
- if ((waiting_buffer_head + 1) % WAITING_BUFFER_SIZE == waiting_buffer_tail) {
- debug("waiting_buffer_enq: Over flow.\n");
- return false;
- }
-
- debug("waiting_buffer_enq["); debug_dec(waiting_buffer_head); debug("] = ");
- debug_hex16(record.event.key.raw); debug("\n");
-
- waiting_buffer[waiting_buffer_head] = record;
- waiting_buffer_head = (waiting_buffer_head + 1) % WAITING_BUFFER_SIZE;
- return true;
-}
-static keyrecord_t waiting_buffer_deq(void)
-{
- if (waiting_buffer_head == waiting_buffer_tail) {
- return (keyrecord_t){};
- }
- uint8_t last_tail = waiting_buffer_tail;
- waiting_buffer_tail = waiting_buffer_tail + 1 % WAITING_BUFFER_SIZE;
- return waiting_buffer[last_tail];
-}
-static bool waiting_buffer_is_empty(void)
-{
- return (waiting_buffer_head == waiting_buffer_tail);
-}
-static void waiting_buffer_clear(void)
-{
- waiting_buffer_head = 0;
- waiting_buffer_tail = 0;
-}
-static bool waiting_buffer_typed(keyevent_t event)
-{
- for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
- if (KEYEQ(event.key, waiting_buffer[i].event.key) && event.pressed != waiting_buffer[i].event.pressed) {
- return true;
- }
- }
- return false;
-}
-static bool waiting_buffer_has_anykey_pressed(void)
-{
- for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
- if (waiting_buffer[i].event.pressed) return true;
- }
- return false;
-}
-static void waiting_buffer_process(void)
-{
-}
-
-/* Oneshot modifier
- *
- * Problem: Want to capitalize like 'The' but the result tends to be 'THe'.
- * Solution: Oneshot modifier have its effect on only one key coming next.
- * Tap Shift, then type 't', 'h' and 'e'. Not need to hold Shift key.
- *
- * Hold: works as normal modifier.
- * Tap: one shot modifier.
- * 2 Tap: cancel one shot modifier.
- * 5-Tap: toggles enable/disable oneshot feature.
- */
-static struct {
- uint8_t mods;
- uint8_t time;
- bool ready;
- bool disabled;
-} oneshot_state;
-static void oneshot_start(uint8_t mods, uint16_t time)
-{
- oneshot_state.mods = mods;
- oneshot_state.time = time;
- oneshot_state.ready = true;
-}
-static void oneshot_cancel(void)
-{
- oneshot_state.mods = 0;
- oneshot_state.time = 0;
- oneshot_state.ready = false;
-}
-static void oneshot_toggle(void)
-{
- oneshot_state.disabled = !oneshot_state.disabled;
-}
-
-
-/*
- * Rule to judge tap:
- * Tap key is typed(pressed and released) within TAP_TERM
- * without interfaring by typing other key.
- */
-/* return true when key event is processed. */
-static bool process_tap(keyrecord_t *keyp)
-{
- keyevent_t event = keyp->event;
-
- // if tapping
- if (IS_TAPPING_PRESSED()) {
- if (WITHIN_TAP_TERM(event)) {
- if (tapping_key.tap_count == 0) {
- if (IS_TAPPING_KEY(event.key) && !event.pressed) {
- // first tap!
- debug("Tapping: First tap.\n");
- tapping_key.tap_count = 1;
- process(&tapping_key);
-
- // enqueue
- keyp->tap_count = tapping_key.tap_count;
- return false;
- } else if (!event.pressed && waiting_buffer_typed(event)) {
- // other key typed. not tap.
- debug("Tapping: End(No tap. Interfered by typing key).\n");
- process(&tapping_key);
- tapping_key = (keyrecord_t){};
-
- // enqueue
- return false;
- } else {
- // other key events shall be stored till tapping state settles.
- return false;
- }
- } else {
- if (IS_TAPPING_KEY(event.key) && !event.pressed) {
- keyp->tap_count = tapping_key.tap_count;
- debug("Tapping: tap release("); debug_dec(keyp->tap_count); debug(")\n");
- tapping_key = *keyp;
- return false;
- }
- else if (is_tap_key(keyp->event.key) && event.pressed) {
- debug("Tapping: Start with forcing to release last tap.\n");
- process(&(keyrecord_t){
- .tap_count = tapping_key.tap_count,
- .event.key = tapping_key.event.key,
- .event.time = event.time,
- .event.pressed = false
- });
- tapping_key = *keyp;
- return false;
- }
- else {
- if (!IS_NOEVENT(keyp->event)) debug("Tapping: key event while tap.\n");
- process(keyp);
- return true;
- }
- }
- }
- // not within TAP_TERM
- else {
- if (tapping_key.tap_count == 0) {
- // timeout. not tap.
- debug("Tapping: End. Not tap(time out).\n");
- process(&tapping_key);
- tapping_key = (keyrecord_t){};
- return false;
- } else {
- if (IS_TAPPING_KEY(event.key) && !event.pressed) {
- debug("Tapping: End. tap release.");
- keyp->tap_count = tapping_key.tap_count;
- process(keyp);
- tapping_key = (keyrecord_t){};
- return true;
- } else {
- // other key after tap time out.
- process(keyp);
- return true;
- }
- }
- }
- } else if (IS_TAPPING_RELEASED()) {
- if (WITHIN_TAP_TERM(event)) {
- if (tapping_key.tap_count > 0 && IS_TAPPING_KEY(event.key) && event.pressed) {
- // sequential tap.
- keyp->tap_count = tapping_key.tap_count + 1;
- debug("Tapping: tap press("); debug_dec(keyp->tap_count); debug(")\n");
- process(keyp);
- tapping_key = *keyp;
- return true;
- } else if (event.pressed && is_tap_key(event.key)) {
- // Sequential tap can be interfered with other tap key.
- debug("Tapping: Start with interfering other tap.\n");
- tapping_key = *keyp;
- return true;
- } else {
- if (!IS_NOEVENT(keyp->event)) debug("Tapping: other key just after tap.\n");
- process(keyp);
- return true;
- }
- } else {
- // timeout. no sequential tap.
- debug("Tapping: End(Time out after releasing last tap).\n");
- tapping_key = (keyrecord_t){};
- process(keyp);
- return true;
- }
- } else {
- if (event.pressed && is_tap_key(event.key)) {
- debug("Tapping: Start(Press tap key).\n");
- tapping_key = *keyp;
- return true;
- } else {
- process(keyp);
- return true;
- }
- }
-}