aboutsummaryrefslogtreecommitdiff
path: root/common/action.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/action.c')
-rw-r--r--common/action.c331
1 files changed, 179 insertions, 152 deletions
diff --git a/common/action.c b/common/action.c
index 4b3b1dd68..fb06e463c 100644
--- a/common/action.c
+++ b/common/action.c
@@ -1,3 +1,19 @@
1/*
2Copyright 2012,2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
1#include "host.h" 17#include "host.h"
2#include "timer.h" 18#include "timer.h"
3#include "keymap.h" 19#include "keymap.h"
@@ -10,36 +26,44 @@
10#include "action.h" 26#include "action.h"
11 27
12 28
13static void process(keyrecord_t *record); 29static bool process_tapping(keyrecord_t *record);
30static void process_action(keyrecord_t *record);
31
14 32
15// TODO 33/*
16/* layer */ 34 * Tapping
17uint8_t default_layer = 0; 35 */
18uint8_t current_layer = 0; 36/* period of tapping(ms) */
37#ifndef TAPPING_TERM
38#define TAPPING_TERM 200
39#endif
19 40
20/* tap term(ms) */ 41/* tap count needed for toggling a feature */
21#define TAP_TERM 200 42#ifndef TAPPING_TOGGLE
22/* number of tap which fires toggle feature */ 43#define TAPPING_TOGGLE 5
23#define TAP_TOGGLE 5 44#endif
24 45
25/* This counts up when tap occurs */ 46/* stores a key event of current tap. */
26uint8_t tap_count = 0; 47static keyrecord_t tapping_key = {};
27keyevent_t tapping_event = {};
28keyrecord_t tapping_key = {};
29 48
30/* TAPPING: This indicates that whether tap or not is not decided yet. */ 49#define IS_TAPPING() !IS_NOEVENT(tapping_key.event)
31// NOTE: keyevent_t.time 0 means no event.
32#define IS_TAPPING() (tapping_key.event.time != 0)
33#define IS_TAPPING_PRESSED() (IS_TAPPING() && tapping_key.event.pressed) 50#define IS_TAPPING_PRESSED() (IS_TAPPING() && tapping_key.event.pressed)
34#define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed) 51#define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed)
35#define IS_TAPPING_KEY(k) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (k))) 52#define IS_TAPPING_KEY(k) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (k)))
36#define WITHIN_TAP_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < TAP_TERM) 53#define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < TAPPING_TERM)
54
37 55
38/* waiting keys buffer */ 56/*
57 * Waiting buffer
58 *
59 * stores key events waiting for settling current tap.
60 */
39#define WAITING_BUFFER_SIZE 8 61#define WAITING_BUFFER_SIZE 8
40static keyrecord_t waiting_buffer[WAITING_BUFFER_SIZE] = {}; 62static keyrecord_t waiting_buffer[WAITING_BUFFER_SIZE] = {};
63
41/* point to empty cell to enq */ 64/* point to empty cell to enq */
42static uint8_t waiting_buffer_head = 0; 65static uint8_t waiting_buffer_head = 0;
66
43/* point to the oldest data cell to deq */ 67/* point to the oldest data cell to deq */
44static uint8_t waiting_buffer_tail = 0; 68static uint8_t waiting_buffer_tail = 0;
45 69
@@ -65,7 +89,7 @@ static bool waiting_buffer_enq(keyrecord_t record)
65static keyrecord_t waiting_buffer_deq(void) 89static keyrecord_t waiting_buffer_deq(void)
66{ 90{
67 if (waiting_buffer_head == waiting_buffer_tail) { 91 if (waiting_buffer_head == waiting_buffer_tail) {
68 return (keyrecord_t){}; // ??? 92 return (keyrecord_t){};
69 } 93 }
70 uint8_t last_tail = waiting_buffer_tail; 94 uint8_t last_tail = waiting_buffer_tail;
71 waiting_buffer_tail = waiting_buffer_tail + 1 % WAITING_BUFFER_SIZE; 95 waiting_buffer_tail = waiting_buffer_tail + 1 % WAITING_BUFFER_SIZE;
@@ -134,125 +158,6 @@ static void oneshot_toggle(void)
134} 158}
135 159
136 160
137/*
138 * Rule to judge tap:
139 * Tap key is typed(pressed and released) within TAP_TERM
140 * without interfaring by typing other key.
141 */
142/* return true when key event is processed. */
143static bool process_tap(keyrecord_t *keyp)
144{
145 keyevent_t event = keyp->event;
146
147 // if tapping
148 if (IS_TAPPING_PRESSED()) {
149 if (WITHIN_TAP_TERM(event)) {
150 if (tapping_key.tap_count == 0) {
151 if (IS_TAPPING_KEY(event.key) && !event.pressed) {
152 // first tap!
153 debug("Tapping: First tap.\n");
154 tapping_key.tap_count = 1;
155 process(&tapping_key);
156
157 // enqueue
158 keyp->tap_count = tapping_key.tap_count;
159 return false;
160 } else if (!event.pressed && waiting_buffer_typed(event)) {
161 // other key typed. not tap.
162 debug("Tapping: End(No tap. Interfered by typing key).\n");
163 process(&tapping_key);
164 tapping_key = (keyrecord_t){};
165
166 // enqueue
167 return false;
168 } else {
169 // other key events shall be stored till tapping state settles.
170 return false;
171 }
172 } else {
173 if (IS_TAPPING_KEY(event.key) && !event.pressed) {
174 keyp->tap_count = tapping_key.tap_count;
175 debug("Tapping: tap release("); debug_dec(keyp->tap_count); debug(")\n");
176 tapping_key = *keyp;
177 return false;
178 }
179 else if (is_tap_key(keyp->event.key) && event.pressed) {
180 debug("Tapping: Start with forcing to release last tap.\n");
181 process(&(keyrecord_t){
182 .tap_count = tapping_key.tap_count,
183 .event.key = tapping_key.event.key,
184 .event.time = event.time,
185 .event.pressed = false
186 });
187 tapping_key = *keyp;
188 return false;
189 }
190 else {
191 if (!IS_NOEVENT(keyp->event)) debug("Tapping: key event while tap.\n");
192 process(keyp);
193 return true;
194 }
195 }
196 }
197 // not within TAP_TERM
198 else {
199 if (tapping_key.tap_count == 0) {
200 // timeout. not tap.
201 debug("Tapping: End. Not tap(time out).\n");
202 process(&tapping_key);
203 tapping_key = (keyrecord_t){};
204 return false;
205 } else {
206 if (IS_TAPPING_KEY(event.key) && !event.pressed) {
207 debug("Tapping: End. tap release.");
208 keyp->tap_count = tapping_key.tap_count;
209 process(keyp);
210 tapping_key = (keyrecord_t){};
211 return true;
212 } else {
213 // other key after tap time out.
214 process(keyp);
215 return true;
216 }
217 }
218 }
219 } else if (IS_TAPPING_RELEASED()) {
220 if (WITHIN_TAP_TERM(event)) {
221 if (tapping_key.tap_count > 0 && IS_TAPPING_KEY(event.key) && event.pressed) {
222 // sequential tap.
223 keyp->tap_count = tapping_key.tap_count + 1;
224 debug("Tapping: tap press("); debug_dec(keyp->tap_count); debug(")\n");
225 process(keyp);
226 tapping_key = *keyp;
227 return true;
228 } else if (event.pressed && is_tap_key(event.key)) {
229 // Sequential tap can be interfered with other tap key.
230 debug("Tapping: Start with interfering other tap.\n");
231 tapping_key = *keyp;
232 return true;
233 } else {
234 if (!IS_NOEVENT(keyp->event)) debug("Tapping: other key just after tap.\n");
235 process(keyp);
236 return true;
237 }
238 } else {
239 // timeout. no sequential tap.
240 debug("Tapping: End(Time out after releasing last tap).\n");
241 tapping_key = (keyrecord_t){};
242 process(keyp);
243 return true;
244 }
245 } else {
246 if (event.pressed && is_tap_key(event.key)) {
247 debug("Tapping: Start(Press tap key).\n");
248 tapping_key = *keyp;
249 return true;
250 } else {
251 process(keyp);
252 return true;
253 }
254 }
255}
256 161
257void action_exec(keyevent_t event) 162void action_exec(keyevent_t event)
258{ 163{
@@ -268,7 +173,7 @@ void action_exec(keyevent_t event)
268 keyrecord_t record = { .event = event }; 173 keyrecord_t record = { .event = event };
269 174
270 // pre-process on tapping 175 // pre-process on tapping
271 if (process_tap(&record)) { 176 if (process_tapping(&record)) {
272 if (!IS_NOEVENT(record.event)) debug("processed.\n"); 177 if (!IS_NOEVENT(record.event)) debug("processed.\n");
273 } else { 178 } else {
274 if (!IS_NOEVENT(record.event)) debug("enqueued.\n"); 179 if (!IS_NOEVENT(record.event)) debug("enqueued.\n");
@@ -283,7 +188,7 @@ void action_exec(keyevent_t event)
283 188
284 // process waiting_buffer 189 // process waiting_buffer
285 for (; waiting_buffer_tail != waiting_buffer_head; waiting_buffer_tail = (waiting_buffer_tail + 1) % WAITING_BUFFER_SIZE) { 190 for (; waiting_buffer_tail != waiting_buffer_head; waiting_buffer_tail = (waiting_buffer_tail + 1) % WAITING_BUFFER_SIZE) {
286 if (process_tap(&waiting_buffer[waiting_buffer_tail])) { 191 if (process_tapping(&waiting_buffer[waiting_buffer_tail])) {
287 debug("processed: waiting_buffer["); debug_dec(waiting_buffer_tail); debug("] = "); 192 debug("processed: waiting_buffer["); debug_dec(waiting_buffer_tail); debug("] = ");
288 debug_hex16(waiting_buffer[waiting_buffer_tail].event.key.raw); debug("\n"); 193 debug_hex16(waiting_buffer[waiting_buffer_tail].event.key.raw); debug("\n");
289 } else { 194 } else {
@@ -292,7 +197,7 @@ void action_exec(keyevent_t event)
292 } 197 }
293} 198}
294 199
295static void process(keyrecord_t *record) 200static void process_action(keyrecord_t *record)
296{ 201{
297 keyevent_t event = record->event; 202 keyevent_t event = record->event;
298 uint8_t tap_count = record->tap_count; 203 uint8_t tap_count = record->tap_count;
@@ -453,11 +358,11 @@ static void process(keyrecord_t *record)
453 case 0xF0: 358 case 0xF0:
454 // tap toggle 359 // tap toggle
455 if (event.pressed) { 360 if (event.pressed) {
456 if (tap_count < TAP_TOGGLE) { 361 if (tap_count < TAPPING_TOGGLE) {
457 layer_switch(action.layer.opt); 362 layer_switch(action.layer.opt);
458 } 363 }
459 } else { 364 } else {
460 if (tap_count >= TAP_TOGGLE) { 365 if (tap_count >= TAPPING_TOGGLE) {
461 debug("LAYER_PRESSED: tap toggle.\n"); 366 debug("LAYER_PRESSED: tap toggle.\n");
462 layer_switch(action.layer.opt); 367 layer_switch(action.layer.opt);
463 } 368 }
@@ -501,12 +406,12 @@ static void process(keyrecord_t *record)
501 case 0xF0: 406 case 0xF0:
502 // tap toggle 407 // tap toggle
503 if (event.pressed) { 408 if (event.pressed) {
504 if (tap_count >= TAP_TOGGLE) { 409 if (tap_count >= TAPPING_TOGGLE) {
505 debug("LAYER_RELEASED: tap toggle.\n"); 410 debug("LAYER_RELEASED: tap toggle.\n");
506 layer_switch(action.layer.opt); 411 layer_switch(action.layer.opt);
507 } 412 }
508 } else { 413 } else {
509 if (tap_count < TAP_TOGGLE) { 414 if (tap_count < TAPPING_TOGGLE) {
510 layer_switch(action.layer.opt); 415 layer_switch(action.layer.opt);
511 } 416 }
512 } 417 }
@@ -551,12 +456,12 @@ static void process(keyrecord_t *record)
551 case 0xF0: 456 case 0xF0:
552 // tap toggle 457 // tap toggle
553 if (event.pressed) { 458 if (event.pressed) {
554 if (tap_count < TAP_TOGGLE) { 459 if (tap_count < TAPPING_TOGGLE) {
555 debug("LAYER_BIT: tap toggle(press).\n"); 460 debug("LAYER_BIT: tap toggle(press).\n");
556 layer_switch(current_layer | action.layer.opt); 461 layer_switch(current_layer | action.layer.opt);
557 } 462 }
558 } else { 463 } else {
559 if (tap_count < TAP_TOGGLE) { 464 if (tap_count < TAPPING_TOGGLE) {
560 debug("LAYER_BIT: tap toggle(release).\n"); 465 debug("LAYER_BIT: tap toggle(release).\n");
561 layer_switch(current_layer & ~action.layer.opt); 466 layer_switch(current_layer & ~action.layer.opt);
562 } else { 467 } else {
@@ -610,11 +515,11 @@ static void process(keyrecord_t *record)
610 case 0xF0: 515 case 0xF0:
611 // tap toggle 516 // tap toggle
612 if (event.pressed) { 517 if (event.pressed) {
613 if (tap_count < TAP_TOGGLE) { 518 if (tap_count < TAPPING_TOGGLE) {
614 layer_switch(default_layer); 519 layer_switch(default_layer);
615 } 520 }
616 } else { 521 } else {
617 if (tap_count >= TAP_TOGGLE) { 522 if (tap_count >= TAPPING_TOGGLE) {
618 debug("LAYER_EXT_PRESSED: tap toggle.\n"); 523 debug("LAYER_EXT_PRESSED: tap toggle.\n");
619 layer_switch(default_layer); 524 layer_switch(default_layer);
620 } 525 }
@@ -659,12 +564,12 @@ static void process(keyrecord_t *record)
659 case 0xF0: 564 case 0xF0:
660 // tap toggle 565 // tap toggle
661 if (event.pressed) { 566 if (event.pressed) {
662 if (tap_count >= TAP_TOGGLE) { 567 if (tap_count >= TAPPING_TOGGLE) {
663 debug("LAYER_EXT_RELEASED: tap toggle.\n"); 568 debug("LAYER_EXT_RELEASED: tap toggle.\n");
664 layer_switch(default_layer); 569 layer_switch(default_layer);
665 } 570 }
666 } else { 571 } else {
667 if (tap_count < TAP_TOGGLE) { 572 if (tap_count < TAPPING_TOGGLE) {
668 layer_switch(default_layer); 573 layer_switch(default_layer);
669 } 574 }
670 } 575 }
@@ -706,6 +611,7 @@ static void process(keyrecord_t *record)
706 case ACT_COMMAND: 611 case ACT_COMMAND:
707 break; 612 break;
708 case ACT_FUNCTION: 613 case ACT_FUNCTION:
614 // TODO
709 action_call_function(event, action.func.id); 615 action_call_function(event, action.func.id);
710 break; 616 break;
711 default: 617 default:
@@ -713,6 +619,127 @@ static void process(keyrecord_t *record)
713 } 619 }
714} 620}
715 621
622/* Tapping
623 *
624 * Rule: Tap key is typed(pressed and released) within TAPPING_TERM
625 * without interfaring by typing other key.
626 */
627/* return true when key event is processed. */
628static bool process_tapping(keyrecord_t *keyp)
629{
630 keyevent_t event = keyp->event;
631
632 // if tapping
633 if (IS_TAPPING_PRESSED()) {
634 if (WITHIN_TAPPING_TERM(event)) {
635 if (tapping_key.tap_count == 0) {
636 if (IS_TAPPING_KEY(event.key) && !event.pressed) {
637 // first tap!
638 debug("Tapping: First tap.\n");
639 tapping_key.tap_count = 1;
640 process_action(&tapping_key);
641
642 // enqueue
643 keyp->tap_count = tapping_key.tap_count;
644 return false;
645 } else if (!event.pressed && waiting_buffer_typed(event)) {
646 // other key typed. not tap.
647 debug("Tapping: End(No tap. Interfered by typing key).\n");
648 process_action(&tapping_key);
649 tapping_key = (keyrecord_t){};
650
651 // enqueue
652 return false;
653 } else {
654 // other key events shall be stored till tapping state settles.
655 return false;
656 }
657 } else {
658 if (IS_TAPPING_KEY(event.key) && !event.pressed) {
659 keyp->tap_count = tapping_key.tap_count;
660 debug("Tapping: tap release("); debug_dec(keyp->tap_count); debug(")\n");
661 tapping_key = *keyp;
662 return false;
663 }
664 else if (is_tap_key(keyp->event.key) && event.pressed) {
665 debug("Tapping: Start with forcing to release last tap.\n");
666 process_action(&(keyrecord_t){
667 .tap_count = tapping_key.tap_count,
668 .event.key = tapping_key.event.key,
669 .event.time = event.time,
670 .event.pressed = false
671 });
672 tapping_key = *keyp;
673 return false;
674 }
675 else {
676 if (!IS_NOEVENT(keyp->event)) debug("Tapping: key event while tap.\n");
677 process_action(keyp);
678 return true;
679 }
680 }
681 }
682 // not within TAPPING_TERM
683 else {
684 if (tapping_key.tap_count == 0) {
685 // timeout. not tap.
686 debug("Tapping: End. Not tap(time out).\n");
687 process_action(&tapping_key);
688 tapping_key = (keyrecord_t){};
689 return false;
690 } else {
691 if (IS_TAPPING_KEY(event.key) && !event.pressed) {
692 debug("Tapping: End. tap release.");
693 keyp->tap_count = tapping_key.tap_count;
694 process_action(keyp);
695 tapping_key = (keyrecord_t){};
696 return true;
697 } else {
698 // other key after tap time out.
699 process_action(keyp);
700 return true;
701 }
702 }
703 }
704 } else if (IS_TAPPING_RELEASED()) {
705 if (WITHIN_TAPPING_TERM(event)) {
706 if (tapping_key.tap_count > 0 && IS_TAPPING_KEY(event.key) && event.pressed) {
707 // sequential tap.
708 keyp->tap_count = tapping_key.tap_count + 1;
709 debug("Tapping: tap press("); debug_dec(keyp->tap_count); debug(")\n");
710 process_action(keyp);
711 tapping_key = *keyp;
712 return true;
713 } else if (event.pressed && is_tap_key(event.key)) {
714 // Sequential tap can be interfered with other tap key.
715 debug("Tapping: Start with interfering other tap.\n");
716 tapping_key = *keyp;
717 return true;
718 } else {
719 if (!IS_NOEVENT(keyp->event)) debug("Tapping: other key just after tap.\n");
720 process_action(keyp);
721 return true;
722 }
723 } else {
724 // timeout. no sequential tap.
725 debug("Tapping: End(Time out after releasing last tap).\n");
726 tapping_key = (keyrecord_t){};
727 process_action(keyp);
728 return true;
729 }
730 } else {
731 if (event.pressed && is_tap_key(event.key)) {
732 debug("Tapping: Start(Press tap key).\n");
733 tapping_key = *keyp;
734 return true;
735 } else {
736 process_action(keyp);
737 return true;
738 }
739 }
740}
741
742
716 743
717/* 744/*
718 * Utilities for actions. 745 * Utilities for actions.
@@ -813,7 +840,7 @@ void layer_switch(uint8_t new_layer)
813 840
814 current_layer = new_layer; 841 current_layer = new_layer;
815 clear_keyboard_but_mods(); // To avoid stuck keys 842 clear_keyboard_but_mods(); // To avoid stuck keys
816 // TODO: update mods with full scan of matrix? if modifier changes between layers 843 // NOTE: update mods with full scan of matrix? if modifier changes between layers
817 } 844 }
818} 845}
819 846