2013-01-28 05:06:42 +00:00
/*
Copyright 2012 , 2013 Jun Wako < wakojun @ gmail . com >
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
2012-12-15 17:32:07 +00:00
# include "host.h"
# include "timer.h"
2013-01-09 13:33:33 +00:00
# include "keymap.h"
2012-12-15 17:32:07 +00:00
# include "keycode.h"
# include "keyboard.h"
# include "mousekey.h"
# include "command.h"
# include "util.h"
# include "debug.h"
2013-02-15 09:48:36 +00:00
# include "layer_switch.h"
2013-02-25 06:30:37 +00:00
# include "action_macro.h"
# include "action.h"
2012-12-15 17:32:07 +00:00
2013-01-28 05:06:42 +00:00
static void process_action ( keyrecord_t * record ) ;
2013-01-30 11:31:32 +00:00
static bool process_tapping ( keyrecord_t * record ) ;
static void waiting_buffer_scan_tap ( void ) ;
2013-01-28 05:06:42 +00:00
2013-01-30 11:31:32 +00:00
static void debug_event ( keyevent_t event ) ;
static void debug_record ( keyrecord_t record ) ;
static void debug_action ( action_t action ) ;
static void debug_tapping_key ( void ) ;
static void debug_waiting_buffer ( void ) ;
2013-01-29 01:40:43 +00:00
2013-01-23 14:53:51 +00:00
2013-01-28 05:06:42 +00:00
/*
* Tapping
*/
/* period of tapping(ms) */
# ifndef TAPPING_TERM
# define TAPPING_TERM 200
# endif
2013-01-23 14:53:51 +00:00
2013-01-28 05:06:42 +00:00
/* tap count needed for toggling a feature */
# ifndef TAPPING_TOGGLE
# define TAPPING_TOGGLE 5
# endif
2013-01-23 14:53:51 +00:00
2013-01-28 05:06:42 +00:00
/* stores a key event of current tap. */
static keyrecord_t tapping_key = { } ;
2013-01-20 06:03:07 +00:00
2013-01-28 05:06:42 +00:00
# define IS_TAPPING() !IS_NOEVENT(tapping_key.event)
2013-01-26 17:42:48 +00:00
# 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)))
2013-01-28 05:06:42 +00:00
# define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < TAPPING_TERM)
2012-12-15 17:32:07 +00:00
2013-01-28 05:06:42 +00:00
/*
* Waiting buffer
*
* stores key events waiting for settling current tap .
*/
2013-01-26 17:42:48 +00:00
# define WAITING_BUFFER_SIZE 8
static keyrecord_t waiting_buffer [ WAITING_BUFFER_SIZE ] = { } ;
2013-01-28 05:06:42 +00:00
2013-01-26 17:42:48 +00:00
/* point to empty cell to enq */
static uint8_t waiting_buffer_head = 0 ;
2013-01-28 05:06:42 +00:00
2013-01-26 17:42:48 +00:00
/* point to the oldest data cell to deq */
static uint8_t waiting_buffer_tail = 0 ;
static bool waiting_buffer_enq ( keyrecord_t record )
2012-12-15 17:32:07 +00:00
{
2013-01-26 17:42:48 +00:00
if ( IS_NOEVENT ( record . event ) ) {
return true ;
}
2013-01-20 06:03:07 +00:00
2013-01-26 17:42:48 +00:00
if ( ( waiting_buffer_head + 1 ) % WAITING_BUFFER_SIZE = = waiting_buffer_tail ) {
debug ( " waiting_buffer_enq: Over flow. \n " ) ;
2013-01-23 14:53:51 +00:00
return false ;
2013-01-14 15:06:52 +00:00
}
2013-01-23 14:53:51 +00:00
2013-01-26 17:42:48 +00:00
waiting_buffer [ waiting_buffer_head ] = record ;
waiting_buffer_head = ( waiting_buffer_head + 1 ) % WAITING_BUFFER_SIZE ;
2013-01-29 01:40:43 +00:00
debug ( " waiting_buffer_enq: " ) ; debug_waiting_buffer ( ) ;
2013-01-23 14:53:51 +00:00
return true ;
}
2013-01-30 11:31:32 +00:00
2013-01-26 17:42:48 +00:00
static void waiting_buffer_clear ( void )
2013-01-14 15:06:52 +00:00
{
2013-01-26 17:42:48 +00:00
waiting_buffer_head = 0 ;
waiting_buffer_tail = 0 ;
2013-01-14 15:06:52 +00:00
}
2013-01-30 11:31:32 +00:00
# if TAPPING_TERM >= 500
2013-01-26 17:42:48 +00:00
static bool waiting_buffer_typed ( keyevent_t event )
2013-01-14 15:06:52 +00:00
{
2013-01-26 17:42:48 +00:00
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 ;
}
2013-01-14 15:06:52 +00:00
}
2013-01-26 17:42:48 +00:00
return false ;
2013-01-20 06:03:07 +00:00
}
2013-01-30 11:31:32 +00:00
# endif
2013-02-01 05:48:11 +00:00
bool waiting_buffer_has_anykey_pressed ( void )
2013-01-20 06:03:07 +00:00
{
2013-01-26 17:42:48 +00:00
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 ;
2013-01-20 06:03:07 +00:00
}
return false ;
2013-01-14 15:06:52 +00:00
}
2013-01-28 02:30:23 +00:00
2013-01-14 15:06:52 +00:00
2013-01-27 07:38:19 +00:00
/* 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 ;
2013-01-30 11:31:32 +00:00
2013-01-27 07:38:19 +00:00
static void oneshot_start ( uint8_t mods , uint16_t time )
{
oneshot_state . mods = mods ;
oneshot_state . time = time ;
oneshot_state . ready = true ;
}
2013-01-30 11:31:32 +00:00
2013-01-27 07:38:19 +00:00
static void oneshot_cancel ( void )
{
oneshot_state . mods = 0 ;
oneshot_state . time = 0 ;
oneshot_state . ready = false ;
}
2013-01-30 11:31:32 +00:00
2013-01-27 07:38:19 +00:00
static void oneshot_toggle ( void )
{
oneshot_state . disabled = ! oneshot_state . disabled ;
}
2012-12-15 17:32:07 +00:00
2013-01-15 10:04:58 +00:00
2013-01-26 17:42:48 +00:00
void action_exec ( keyevent_t event )
{
if ( ! IS_NOEVENT ( event ) ) {
2013-01-29 01:40:43 +00:00
debug ( " \n ---- action_exec: start ----- \n " ) ;
debug ( " EVENT: " ) ; debug_event ( event ) ; debug ( " \n " ) ;
2013-01-26 17:42:48 +00:00
}
keyrecord_t record = { . event = event } ;
// pre-process on tapping
2013-01-28 05:06:42 +00:00
if ( process_tapping ( & record ) ) {
2013-01-29 01:40:43 +00:00
if ( ! IS_NOEVENT ( record . event ) ) {
debug ( " processed: " ) ; debug_record ( record ) ; debug ( " \n " ) ;
}
2013-01-26 17:42:48 +00:00
} else {
2013-01-28 02:30:23 +00:00
// enqueue
2013-01-26 17:42:48 +00:00
if ( ! waiting_buffer_enq ( record ) ) {
// clear all in case of overflow.
2013-01-30 11:31:32 +00:00
debug ( " OVERFLOW: CLEAR ALL STATES \n " ) ;
2013-01-26 17:42:48 +00:00
clear_keyboard ( ) ;
waiting_buffer_clear ( ) ;
tapping_key = ( keyrecord_t ) { } ;
2013-01-20 06:03:07 +00:00
}
2013-01-26 17:42:48 +00:00
}
2013-01-15 10:04:58 +00:00
2013-01-26 17:42:48 +00:00
// process waiting_buffer
2013-01-29 01:40:43 +00:00
if ( ! IS_NOEVENT ( event ) & & waiting_buffer_head ! = waiting_buffer_tail ) {
debug ( " ---- action_exec: process waiting_buffer ----- \n " ) ;
}
2013-01-30 11:31:32 +00:00
2013-01-26 17:42:48 +00:00
for ( ; waiting_buffer_tail ! = waiting_buffer_head ; waiting_buffer_tail = ( waiting_buffer_tail + 1 ) % WAITING_BUFFER_SIZE ) {
2013-01-28 05:06:42 +00:00
if ( process_tapping ( & waiting_buffer [ waiting_buffer_tail ] ) ) {
2013-01-26 17:42:48 +00:00
debug ( " processed: waiting_buffer[ " ) ; debug_dec ( waiting_buffer_tail ) ; debug ( " ] = " ) ;
2013-01-29 01:40:43 +00:00
debug_record ( waiting_buffer [ waiting_buffer_tail ] ) ; debug ( " \n \n " ) ;
2013-01-26 17:42:48 +00:00
} else {
break ;
}
2013-01-15 10:04:58 +00:00
}
2013-01-29 01:40:43 +00:00
if ( ! IS_NOEVENT ( event ) ) {
debug ( " \n " ) ;
}
2013-01-15 10:04:58 +00:00
}
2013-01-28 05:06:42 +00:00
static void process_action ( keyrecord_t * record )
2013-01-13 01:24:20 +00:00
{
2013-01-26 17:42:48 +00:00
keyevent_t event = record - > event ;
2013-02-26 07:27:09 +00:00
uint8_t tap_count = record - > tap . count ;
2013-01-26 17:42:48 +00:00
2013-01-20 06:03:07 +00:00
if ( IS_NOEVENT ( event ) ) { return ; }
2013-02-20 02:16:13 +00:00
action_t action = layer_switch_get_action ( event . key ) ;
debug ( " ACTION: " ) ; debug_action ( action ) ;
debug ( " overlays: " ) ; overlay_debug ( ) ;
debug ( " keymaps: " ) ; keymap_debug ( ) ;
debug ( " default_layer: " ) ; debug_dec ( default_layer ) ; debug ( " \n " ) ;
2012-12-15 17:32:07 +00:00
switch ( action . kind . id ) {
2013-01-13 01:24:20 +00:00
/* Key and Mods */
2012-12-15 17:32:07 +00:00
case ACT_LMODS :
case ACT_RMODS :
2013-01-27 07:38:19 +00:00
{
uint8_t mods = ( action . kind . id = = ACT_LMODS ) ? action . key . mods :
action . key . mods < < 4 ;
if ( event . pressed ) {
uint8_t tmp_mods = host_get_mods ( ) ;
if ( mods ) {
host_add_mods ( mods ) ;
host_send_keyboard_report ( ) ;
}
register_code ( action . key . code ) ;
if ( mods & & action . key . code ) {
host_set_mods ( tmp_mods ) ;
host_send_keyboard_report ( ) ;
}
} else {
if ( mods & & ! action . key . code ) {
host_del_mods ( mods ) ;
host_send_keyboard_report ( ) ;
}
unregister_code ( action . key . code ) ;
2013-01-13 01:24:20 +00:00
}
2012-12-15 17:32:07 +00:00
}
break ;
2013-01-15 10:04:58 +00:00
case ACT_LMODS_TAP :
2013-01-20 06:03:07 +00:00
case ACT_RMODS_TAP :
{
2013-01-27 07:38:19 +00:00
uint8_t mods = ( action . kind . id = = ACT_LMODS_TAP ) ? action . key . mods :
action . key . mods < < 4 ;
switch ( action . layer . code ) {
case 0x00 :
// Oneshot modifier
if ( event . pressed ) {
if ( tap_count = = 0 ) {
debug ( " MODS_TAP: Oneshot: add_mods \n " ) ;
add_mods ( mods ) ;
}
else if ( tap_count = = 1 ) {
debug ( " MODS_TAP: Oneshot: start \n " ) ;
oneshot_start ( mods , event . time ) ;
}
2013-02-01 05:48:11 +00:00
else if ( tap_count = = TAPPING_TOGGLE ) {
2013-01-27 07:38:19 +00:00
debug ( " MODS_TAP: Oneshot: toggle \n " ) ;
oneshot_toggle ( ) ;
}
else {
debug ( " MODS_TAP: Oneshot: cancel&add_mods \n " ) ;
// double tap cancels oneshot and works as normal modifier.
oneshot_cancel ( ) ;
add_mods ( mods ) ;
}
2013-01-17 02:46:38 +00:00
} else {
2013-01-27 07:38:19 +00:00
if ( tap_count = = 0 ) {
debug ( " MODS_TAP: Oneshot: cancel/del_mods \n " ) ;
2013-02-14 06:22:59 +00:00
// cancel oneshot on hold
2013-01-27 07:38:19 +00:00
oneshot_cancel ( ) ;
del_mods ( mods ) ;
}
else if ( tap_count = = 1 ) {
debug ( " MODS_TAP: Oneshot: del_mods \n " ) ;
// retain Oneshot
del_mods ( mods ) ;
}
else {
debug ( " MODS_TAP: Oneshot: del_mods \n " ) ;
// cancel Mods
del_mods ( mods ) ;
}
2013-01-17 02:46:38 +00:00
}
2013-01-27 07:38:19 +00:00
break ;
default :
if ( event . pressed ) {
if ( tap_count > 0 ) {
if ( waiting_buffer_has_anykey_pressed ( ) ) {
debug ( " MODS_TAP: Tap: Cancel: add_mods \n " ) ;
// ad hoc: set 0 to cancel tap
2013-02-26 07:27:09 +00:00
record - > tap . count = 0 ;
2013-01-27 07:38:19 +00:00
add_mods ( mods ) ;
} else {
debug ( " MODS_TAP: Tap: register_code \n " ) ;
register_code ( action . key . code ) ;
}
} else {
debug ( " MODS_TAP: No tap: add_mods \n " ) ;
add_mods ( mods ) ;
}
} else {
if ( tap_count > 0 ) {
debug ( " MODS_TAP: Tap: unregister_code \n " ) ;
unregister_code ( action . key . code ) ;
} else {
debug ( " MODS_TAP: No tap: add_mods \n " ) ;
del_mods ( mods ) ;
}
}
break ;
2013-01-15 10:04:58 +00:00
}
}
2013-01-09 13:33:33 +00:00
break ;
2013-01-13 01:24:20 +00:00
/* other HID usage */
2013-01-09 13:33:33 +00:00
case ACT_USAGE :
# ifdef EXTRAKEY_ENABLE
switch ( action . usage . page ) {
2013-02-07 15:50:51 +00:00
case PAGE_SYSTEM :
2012-12-15 17:32:07 +00:00
if ( event . pressed ) {
2013-01-09 13:33:33 +00:00
host_system_send ( action . usage . code ) ;
2012-12-15 17:32:07 +00:00
} else {
2013-01-09 13:33:33 +00:00
host_system_send ( 0 ) ;
2012-12-15 17:32:07 +00:00
}
break ;
2013-02-07 15:50:51 +00:00
case PAGE_CONSUMER :
2013-01-09 13:33:33 +00:00
if ( event . pressed ) {
host_consumer_send ( action . usage . code ) ;
} else {
host_consumer_send ( 0 ) ;
}
2012-12-15 17:32:07 +00:00
break ;
2013-01-09 13:33:33 +00:00
}
# endif
break ;
2013-01-13 01:24:20 +00:00
/* Mouse key */
2013-01-09 13:33:33 +00:00
case ACT_MOUSEKEY :
# ifdef MOUSEKEY_ENABLE
if ( event . pressed ) {
mousekey_on ( action . key . code ) ;
mousekey_send ( ) ;
} else {
mousekey_off ( action . key . code ) ;
mousekey_send ( ) ;
}
# endif
break ;
2013-01-13 01:24:20 +00:00
2013-02-20 02:16:13 +00:00
case ACT_KEYMAP :
2013-01-09 13:33:33 +00:00
switch ( action . layer . code ) {
2013-02-20 06:52:32 +00:00
/* Keymap clear */
2013-02-20 02:16:13 +00:00
case OP_RESET :
2013-02-20 06:52:32 +00:00
switch ( action . layer . val & 0x03 ) {
case 0 :
2013-03-04 17:42:28 +00:00
// NOTE: reserved
2013-02-20 06:52:32 +00:00
overlay_clear ( ) ;
keymap_clear ( ) ;
break ;
case ON_PRESS :
if ( event . pressed ) {
overlay_clear ( ) ;
keymap_clear ( ) ;
}
break ;
case ON_RELEASE :
if ( ! event . pressed ) {
overlay_clear ( ) ;
keymap_clear ( ) ;
}
break ;
case ON_BOTH :
overlay_clear ( ) ;
keymap_clear ( ) ;
break ;
2013-03-04 17:42:28 +00:00
/* NOTE: 4-7 rserved */
2013-02-20 06:52:32 +00:00
}
2012-12-15 17:32:07 +00:00
break ;
2013-02-20 02:16:13 +00:00
/* Keymap Reset default layer */
case ( OP_RESET | ON_PRESS ) :
2013-02-07 15:50:51 +00:00
if ( event . pressed ) {
2013-02-20 06:52:32 +00:00
default_layer_set ( action . layer . val ) ;
2013-02-07 15:50:51 +00:00
}
break ;
2013-02-20 02:16:13 +00:00
case ( OP_RESET | ON_RELEASE ) :
2013-02-07 15:50:51 +00:00
if ( ! event . pressed ) {
2013-02-20 06:52:32 +00:00
default_layer_set ( action . layer . val ) ;
2013-02-07 15:50:51 +00:00
}
break ;
2013-02-20 02:16:13 +00:00
case ( OP_RESET | ON_BOTH ) :
2013-02-20 06:52:32 +00:00
default_layer_set ( action . layer . val ) ;
2013-02-07 15:50:51 +00:00
break ;
2013-02-20 02:16:13 +00:00
/* Keymap Bit invert */
case OP_INV :
/* with tap toggle */
2013-01-28 02:30:23 +00:00
if ( event . pressed ) {
2013-01-28 05:06:42 +00:00
if ( tap_count < TAPPING_TOGGLE ) {
2013-02-20 02:16:13 +00:00
debug ( " KEYMAP_INV: tap toggle(press). \n " ) ;
keymap_invert ( action . layer . val ) ;
2013-01-28 02:30:23 +00:00
}
} else {
2013-02-20 02:16:13 +00:00
if ( tap_count < = TAPPING_TOGGLE ) {
debug ( " KEYMAP_INV: tap toggle(release). \n " ) ;
keymap_invert ( action . layer . val ) ;
2013-01-28 02:30:23 +00:00
}
}
2012-12-15 17:32:07 +00:00
break ;
2013-02-20 02:16:13 +00:00
case ( OP_INV | ON_PRESS ) :
2013-01-09 13:33:33 +00:00
if ( event . pressed ) {
2013-02-20 02:16:13 +00:00
keymap_invert ( action . layer . val ) ;
2013-01-09 13:33:33 +00:00
}
break ;
2013-02-20 02:16:13 +00:00
case ( OP_INV | ON_RELEASE ) :
2013-02-14 06:22:59 +00:00
if ( ! event . pressed ) {
2013-02-20 02:16:13 +00:00
keymap_invert ( action . layer . val ) ;
2013-02-14 06:22:59 +00:00
}
break ;
2013-02-20 02:16:13 +00:00
case ( OP_INV | ON_BOTH ) :
keymap_invert ( action . layer . val ) ;
2013-02-14 06:22:59 +00:00
break ;
2013-02-20 02:16:13 +00:00
/* Keymap Bit on */
case OP_ON :
2012-12-15 17:32:07 +00:00
if ( event . pressed ) {
2013-02-20 02:16:13 +00:00
keymap_on ( action . layer . val ) ;
2012-12-15 17:32:07 +00:00
} else {
2013-02-20 02:16:13 +00:00
keymap_off ( action . layer . val ) ;
2012-12-15 17:32:07 +00:00
}
break ;
2013-02-20 02:16:13 +00:00
case ( OP_ON | ON_PRESS ) :
2013-01-28 02:30:23 +00:00
if ( event . pressed ) {
2013-02-20 02:16:13 +00:00
keymap_on ( action . layer . val ) ;
}
break ;
case ( OP_ON | ON_RELEASE ) :
if ( ! event . pressed ) {
keymap_on ( action . layer . val ) ;
}
break ;
case ( OP_ON | ON_BOTH ) :
keymap_on ( action . layer . val ) ;
break ;
/* Keymap Bit off */
case OP_OFF :
if ( event . pressed ) {
keymap_off ( action . layer . val ) ;
2013-01-28 02:30:23 +00:00
} else {
2013-02-20 02:16:13 +00:00
keymap_on ( action . layer . val ) ;
2013-01-09 13:33:33 +00:00
}
break ;
2013-02-20 02:16:13 +00:00
case ( OP_OFF | ON_PRESS ) :
2013-01-28 02:30:23 +00:00
if ( event . pressed ) {
2013-02-20 02:16:13 +00:00
keymap_off ( action . layer . val ) ;
2013-01-28 02:30:23 +00:00
}
2013-01-09 13:33:33 +00:00
break ;
2013-02-20 02:16:13 +00:00
case ( OP_OFF | ON_RELEASE ) :
2013-02-07 15:50:51 +00:00
if ( ! event . pressed ) {
2013-02-20 02:16:13 +00:00
keymap_off ( action . layer . val ) ;
2012-12-15 17:32:07 +00:00
}
break ;
2013-02-20 02:16:13 +00:00
case ( OP_OFF | ON_BOTH ) :
keymap_off ( action . layer . val ) ;
2013-02-14 06:22:59 +00:00
break ;
2013-02-20 02:16:13 +00:00
/* Keymap Bit set */
case OP_SET :
2013-01-28 02:30:23 +00:00
if ( event . pressed ) {
2013-02-20 02:16:13 +00:00
keymap_set ( action . layer . val ) ;
2013-01-28 02:30:23 +00:00
} else {
2013-02-20 02:16:13 +00:00
keymap_clear ( ) ;
2013-01-28 02:30:23 +00:00
}
2013-01-09 13:33:33 +00:00
break ;
2013-02-20 02:16:13 +00:00
case ( OP_SET | ON_PRESS ) :
2012-12-15 17:32:07 +00:00
if ( event . pressed ) {
2013-02-20 02:16:13 +00:00
keymap_set ( action . layer . val ) ;
2013-02-14 06:22:59 +00:00
}
break ;
2013-02-20 02:16:13 +00:00
case ( OP_SET | ON_RELEASE ) :
2013-02-14 06:22:59 +00:00
if ( ! event . pressed ) {
2013-02-20 02:16:13 +00:00
keymap_set ( action . layer . val ) ;
2013-01-09 13:33:33 +00:00
}
break ;
2013-02-20 02:16:13 +00:00
case ( OP_SET | ON_BOTH ) :
keymap_set ( action . layer . val ) ;
2013-02-14 06:22:59 +00:00
break ;
2013-02-20 02:16:13 +00:00
/* Keymap Bit invert with tap key */
2013-01-09 13:33:33 +00:00
default :
if ( event . pressed ) {
2013-02-20 07:53:55 +00:00
if ( tap_count > 0 ) {
2013-02-20 02:16:13 +00:00
debug ( " KEYMAP_TAP_KEY: Tap: register_code \n " ) ;
2013-01-09 13:33:33 +00:00
register_code ( action . layer . code ) ;
2013-01-20 06:03:07 +00:00
} else {
2013-02-20 07:53:55 +00:00
debug ( " KEYMAP_TAP_KEY: No tap: On on press \n " ) ;
keymap_on ( action . layer . val ) ;
2013-01-09 13:33:33 +00:00
}
} else {
2013-02-20 07:53:55 +00:00
if ( tap_count > 0 ) {
2013-02-20 02:16:13 +00:00
debug ( " KEYMAP_TAP_KEY: Tap: unregister_code \n " ) ;
2013-01-20 06:03:07 +00:00
unregister_code ( action . layer . code ) ;
} else {
2013-02-20 07:53:55 +00:00
debug ( " KEYMAP_TAP_KEY: No tap: Off on release \n " ) ;
keymap_off ( action . layer . val ) ;
2013-01-09 13:33:33 +00:00
}
2012-12-15 17:32:07 +00:00
}
break ;
}
2013-01-28 02:30:23 +00:00
break ;
2013-02-20 02:16:13 +00:00
case ACT_OVERLAY :
2013-02-14 06:22:59 +00:00
switch ( action . layer . code ) {
2013-02-20 02:16:13 +00:00
// Overlay Invert bit4
case OP_INV4 | 0 :
if ( action . layer . val = = 0 ) {
2013-03-04 17:42:28 +00:00
// NOTE: reserved for future use
2013-02-20 02:16:13 +00:00
overlay_clear ( ) ;
2013-02-14 06:22:59 +00:00
} else {
2013-02-20 02:16:13 +00:00
overlay_set ( overlay_stat ^ action . layer . val ) ;
2013-02-14 06:22:59 +00:00
}
break ;
2013-02-20 02:16:13 +00:00
case OP_INV4 | 1 :
if ( action . layer . val = = 0 ) {
2013-03-04 17:42:28 +00:00
// on pressed
2013-02-20 02:16:13 +00:00
if ( event . pressed ) overlay_clear ( ) ;
} else {
overlay_set ( overlay_stat ^ action . layer . val < < 4 ) ;
2013-02-14 06:22:59 +00:00
}
break ;
2013-02-20 02:16:13 +00:00
case OP_INV4 | 2 :
if ( action . layer . val = = 0 ) {
2013-03-04 17:42:28 +00:00
// on released
2013-02-20 02:16:13 +00:00
if ( ! event . pressed ) overlay_clear ( ) ;
} else {
overlay_set ( overlay_stat ^ action . layer . val < < 8 ) ;
2013-02-14 06:22:59 +00:00
}
break ;
2013-02-20 02:16:13 +00:00
case OP_INV4 | 3 :
if ( action . layer . val = = 0 ) {
2013-03-04 17:42:28 +00:00
// on both
2013-02-20 02:16:13 +00:00
overlay_clear ( ) ;
} else {
overlay_set ( overlay_stat ^ action . layer . val < < 12 ) ;
}
2013-02-14 06:22:59 +00:00
break ;
2013-02-20 02:16:13 +00:00
/* Overlay Bit invert */
case OP_INV :
/* with tap toggle */
2013-02-14 06:22:59 +00:00
if ( event . pressed ) {
if ( tap_count < TAPPING_TOGGLE ) {
2013-02-20 02:16:13 +00:00
debug ( " OVERLAY_INV: tap toggle(press). \n " ) ;
overlay_invert ( action . layer . val ) ;
2013-02-14 06:22:59 +00:00
}
} else {
if ( tap_count < = TAPPING_TOGGLE ) {
2013-02-20 02:16:13 +00:00
debug ( " OVERLAY_INV: tap toggle(release). \n " ) ;
overlay_invert ( action . layer . val ) ;
2013-02-14 06:22:59 +00:00
}
}
break ;
2013-02-20 02:16:13 +00:00
case ( OP_INV | ON_PRESS ) :
if ( event . pressed ) {
overlay_invert ( action . layer . val ) ;
}
break ;
case ( OP_INV | ON_RELEASE ) :
if ( ! event . pressed ) {
overlay_invert ( action . layer . val ) ;
}
break ;
case ( OP_INV | ON_BOTH ) :
overlay_invert ( action . layer . val ) ;
break ;
/* Overlay Bit on */
case OP_ON :
if ( event . pressed ) {
overlay_on ( action . layer . val ) ;
} else {
overlay_off ( action . layer . val ) ;
}
break ;
case ( OP_ON | ON_PRESS ) :
if ( event . pressed ) {
overlay_on ( action . layer . val ) ;
}
break ;
case ( OP_ON | ON_RELEASE ) :
if ( ! event . pressed ) {
overlay_on ( action . layer . val ) ;
}
break ;
case ( OP_ON | ON_BOTH ) :
overlay_on ( action . layer . val ) ;
break ;
/* Overlay Bit off */
case OP_OFF :
if ( event . pressed ) {
overlay_off ( action . layer . val ) ;
} else {
overlay_on ( action . layer . val ) ;
}
break ;
case ( OP_OFF | ON_PRESS ) :
if ( event . pressed ) {
overlay_off ( action . layer . val ) ;
}
break ;
case ( OP_OFF | ON_RELEASE ) :
if ( ! event . pressed ) {
overlay_off ( action . layer . val ) ;
}
break ;
case ( OP_OFF | ON_BOTH ) :
overlay_off ( action . layer . val ) ;
break ;
/* Overlay Bit set */
case OP_SET :
if ( event . pressed ) {
overlay_move ( action . layer . val ) ;
} else {
overlay_clear ( ) ;
}
break ;
case ( OP_SET | ON_PRESS ) :
if ( event . pressed ) {
overlay_move ( action . layer . val ) ;
}
break ;
case ( OP_SET | ON_RELEASE ) :
if ( ! event . pressed ) {
overlay_move ( action . layer . val ) ;
}
break ;
case ( OP_SET | ON_BOTH ) :
overlay_move ( action . layer . val ) ;
break ;
/* Overlay Bit invert with tap key */
2013-02-14 06:22:59 +00:00
default :
if ( event . pressed ) {
2013-02-20 07:53:55 +00:00
if ( tap_count > 0 ) {
2013-02-20 02:16:13 +00:00
debug ( " OVERLAY_TAP_KEY: Tap: register_code \n " ) ;
2013-02-14 06:22:59 +00:00
register_code ( action . layer . code ) ;
} else {
2013-02-20 07:53:55 +00:00
debug ( " OVERLAY_TAP_KEY: No tap: On on press \n " ) ;
overlay_on ( action . layer . val ) ;
2013-02-14 06:22:59 +00:00
}
} else {
2013-02-20 07:53:55 +00:00
if ( tap_count > 0 ) {
2013-02-20 02:16:13 +00:00
debug ( " OVERLAY_TAP_KEY: Tap: unregister_code \n " ) ;
2013-02-14 06:22:59 +00:00
unregister_code ( action . layer . code ) ;
} else {
2013-02-20 07:53:55 +00:00
debug ( " OVERLAY_TAP_KEY: No tap: Off on release \n " ) ;
overlay_off ( action . layer . val ) ;
2013-02-14 06:22:59 +00:00
}
}
break ;
}
break ;
2013-01-13 01:24:20 +00:00
/* Extentions */
2012-12-15 17:32:07 +00:00
case ACT_MACRO :
2013-02-25 06:30:37 +00:00
action_macro_play ( action_get_macro ( record , action . func . id , action . func . opt ) ) ;
2013-01-23 14:53:51 +00:00
break ;
2012-12-15 17:32:07 +00:00
case ACT_COMMAND :
2013-01-23 14:53:51 +00:00
break ;
2012-12-15 17:32:07 +00:00
case ACT_FUNCTION :
2013-02-13 02:47:19 +00:00
action_function ( record , action . func . id , action . func . opt ) ;
2013-01-23 14:53:51 +00:00
break ;
2012-12-15 17:32:07 +00:00
default :
break ;
}
2013-01-13 01:24:20 +00:00
}
2013-01-28 05:06:42 +00:00
/* Tapping
*
2013-01-30 11:31:32 +00:00
* Rule : Tap key is typed ( pressed and released ) within TAPPING_TERM .
* ( without interfering by typing other key )
2013-01-28 05:06:42 +00:00
*/
2013-01-30 11:31:32 +00:00
/* return true when key event is processed or consumed. */
2013-01-28 05:06:42 +00:00
static bool process_tapping ( keyrecord_t * keyp )
{
keyevent_t event = keyp - > event ;
// if tapping
if ( IS_TAPPING_PRESSED ( ) ) {
if ( WITHIN_TAPPING_TERM ( event ) ) {
2013-02-26 07:27:09 +00:00
if ( tapping_key . tap . count = = 0 ) {
2013-01-28 05:06:42 +00:00
if ( IS_TAPPING_KEY ( event . key ) & & ! event . pressed ) {
// first tap!
2013-01-30 11:31:32 +00:00
debug ( " Tapping: First tap(0->1). \n " ) ;
2013-02-26 07:27:09 +00:00
tapping_key . tap . count = 1 ;
tapping_key . tap . interrupted = ( waiting_buffer_has_anykey_pressed ( ) ? true : false ) ;
2013-01-30 11:31:32 +00:00
debug_tapping_key ( ) ;
2013-01-28 05:06:42 +00:00
process_action ( & tapping_key ) ;
// enqueue
2013-02-26 07:27:09 +00:00
keyp - > tap = tapping_key . tap ;
2013-01-28 05:06:42 +00:00
return false ;
2013-01-30 11:31:32 +00:00
}
# if TAPPING_TERM >= 500
/* This can prevent from typing some tap keys in a row at a time. */
else if ( ! event . pressed & & waiting_buffer_typed ( event ) ) {
2013-01-28 05:06:42 +00:00
// other key typed. not tap.
2013-01-30 11:31:32 +00:00
debug ( " Tapping: End. No tap. Interfered by typing key \n " ) ;
2013-01-28 05:06:42 +00:00
process_action ( & tapping_key ) ;
tapping_key = ( keyrecord_t ) { } ;
2013-01-30 11:31:32 +00:00
debug_tapping_key ( ) ;
2013-01-28 05:06:42 +00:00
// enqueue
return false ;
2013-01-30 11:31:32 +00:00
}
# endif
else {
// other key events shall be enq'd till tapping state settles.
2013-01-28 05:06:42 +00:00
return false ;
}
2013-01-29 01:40:43 +00:00
}
// tap_count > 0
else {
2013-01-28 05:06:42 +00:00
if ( IS_TAPPING_KEY ( event . key ) & & ! event . pressed ) {
2013-02-26 07:27:09 +00:00
debug ( " Tapping: Tap release( " ) ; debug_dec ( tapping_key . tap . count ) ; debug ( " ) \n " ) ;
keyp - > tap = tapping_key . tap ;
2013-01-30 11:31:32 +00:00
process_action ( keyp ) ;
2013-01-28 05:06:42 +00:00
tapping_key = * keyp ;
2013-01-30 11:31:32 +00:00
debug_tapping_key ( ) ;
return true ;
2013-01-28 05:06:42 +00:00
}
else if ( is_tap_key ( keyp - > event . key ) & & event . pressed ) {
2013-02-26 07:27:09 +00:00
if ( tapping_key . tap . count > 1 ) {
2013-01-30 11:31:32 +00:00
debug ( " Tapping: Start new tap with releasing last tap(>1). \n " ) ;
// unregister key
process_action ( & ( keyrecord_t ) {
2013-02-26 07:27:09 +00:00
. tap = tapping_key . tap ,
2013-01-30 11:31:32 +00:00
. event . key = tapping_key . event . key ,
. event . time = event . time ,
. event . pressed = false
} ) ;
} else {
debug ( " Tapping: Start while last tap(1). \n " ) ;
}
2013-01-28 05:06:42 +00:00
tapping_key = * keyp ;
2013-01-30 11:31:32 +00:00
waiting_buffer_scan_tap ( ) ;
debug_tapping_key ( ) ;
return true ;
2013-01-28 05:06:42 +00:00
}
else {
2013-01-29 01:40:43 +00:00
if ( ! IS_NOEVENT ( keyp - > event ) ) {
2013-01-30 11:31:32 +00:00
debug ( " Tapping: key event while last tap(>0). \n " ) ;
2013-01-29 01:40:43 +00:00
}
2013-01-28 05:06:42 +00:00
process_action ( keyp ) ;
return true ;
}
}
}
2013-01-30 11:31:32 +00:00
// after TAPPING_TERM
2013-01-28 05:06:42 +00:00
else {
2013-02-26 07:27:09 +00:00
if ( tapping_key . tap . count = = 0 ) {
2013-01-30 11:31:32 +00:00
debug ( " Tapping: End. Timeout. Not tap(0): " ) ;
debug_event ( event ) ; debug ( " \n " ) ;
2013-01-28 05:06:42 +00:00
process_action ( & tapping_key ) ;
tapping_key = ( keyrecord_t ) { } ;
2013-01-30 11:31:32 +00:00
debug_tapping_key ( ) ;
2013-01-28 05:06:42 +00:00
return false ;
} else {
if ( IS_TAPPING_KEY ( event . key ) & & ! event . pressed ) {
2013-01-30 11:31:32 +00:00
debug ( " Tapping: End. last timeout tap release(>0). " ) ;
2013-02-26 07:27:09 +00:00
keyp - > tap = tapping_key . tap ;
2013-01-28 05:06:42 +00:00
process_action ( keyp ) ;
tapping_key = ( keyrecord_t ) { } ;
return true ;
2013-01-30 11:31:32 +00:00
}
else if ( is_tap_key ( keyp - > event . key ) & & event . pressed ) {
2013-02-26 07:27:09 +00:00
if ( tapping_key . tap . count > 1 ) {
2013-01-30 11:31:32 +00:00
debug ( " Tapping: Start new tap with releasing last timeout tap(>1). \n " ) ;
// unregister key
process_action ( & ( keyrecord_t ) {
2013-02-26 07:27:09 +00:00
. tap = tapping_key . tap ,
2013-01-30 11:31:32 +00:00
. event . key = tapping_key . event . key ,
. event . time = event . time ,
. event . pressed = false
} ) ;
} else {
debug ( " Tapping: Start while last timeout tap(1). \n " ) ;
}
tapping_key = * keyp ;
waiting_buffer_scan_tap ( ) ;
debug_tapping_key ( ) ;
return true ;
}
else {
if ( ! IS_NOEVENT ( keyp - > event ) ) {
debug ( " Tapping: key event while last timeout tap(>0). \n " ) ;
}
2013-01-28 05:06:42 +00:00
process_action ( keyp ) ;
return true ;
}
}
}
} else if ( IS_TAPPING_RELEASED ( ) ) {
if ( WITHIN_TAPPING_TERM ( event ) ) {
2013-02-26 07:27:09 +00:00
if ( tapping_key . tap . count > 0 & & IS_TAPPING_KEY ( event . key ) & & event . pressed ) {
2013-01-28 05:06:42 +00:00
// sequential tap.
2013-02-26 07:27:09 +00:00
keyp - > tap = tapping_key . tap ;
keyp - > tap . count + = 1 ;
debug ( " Tapping: Tap press( " ) ; debug_dec ( keyp - > tap . count ) ; debug ( " ) \n " ) ;
2013-01-28 05:06:42 +00:00
process_action ( keyp ) ;
tapping_key = * keyp ;
2013-01-30 11:31:32 +00:00
debug_tapping_key ( ) ;
2013-01-28 05:06:42 +00:00
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 ;
2013-01-30 11:31:32 +00:00
waiting_buffer_scan_tap ( ) ;
debug_tapping_key ( ) ;
2013-01-28 05:06:42 +00:00
return true ;
} else {
if ( ! IS_NOEVENT ( keyp - > event ) ) debug ( " Tapping: other key just after tap. \n " ) ;
process_action ( keyp ) ;
return true ;
}
} else {
// timeout. no sequential tap.
2013-01-30 11:31:32 +00:00
debug ( " Tapping: End(Timeout after releasing last tap): " ) ;
debug_event ( event ) ; debug ( " \n " ) ;
2013-01-28 05:06:42 +00:00
tapping_key = ( keyrecord_t ) { } ;
2013-01-30 11:31:32 +00:00
debug_tapping_key ( ) ;
2013-01-31 06:07:01 +00:00
return false ;
2013-01-28 05:06:42 +00:00
}
2013-01-30 11:31:32 +00:00
}
// not tapping satate
else {
2013-01-28 05:06:42 +00:00
if ( event . pressed & & is_tap_key ( event . key ) ) {
debug ( " Tapping: Start(Press tap key). \n " ) ;
tapping_key = * keyp ;
2013-01-30 11:31:32 +00:00
waiting_buffer_scan_tap ( ) ;
debug_tapping_key ( ) ;
2013-01-28 05:06:42 +00:00
return true ;
} else {
process_action ( keyp ) ;
return true ;
}
}
}
2013-01-30 11:31:32 +00:00
/* scan buffer for tapping */
static void waiting_buffer_scan_tap ( void )
{
// tapping already is settled
2013-02-26 07:27:09 +00:00
if ( tapping_key . tap . count > 0 ) return ;
// invalid state: tapping_key released && tap.count == 0
2013-01-30 11:31:32 +00:00
if ( ! tapping_key . event . pressed ) return ;
for ( uint8_t i = waiting_buffer_tail ; i ! = waiting_buffer_head ; i = ( i + 1 ) % WAITING_BUFFER_SIZE ) {
if ( IS_TAPPING_KEY ( waiting_buffer [ i ] . event . key ) & &
! waiting_buffer [ i ] . event . pressed & &
WITHIN_TAPPING_TERM ( waiting_buffer [ i ] . event ) ) {
2013-02-26 07:27:09 +00:00
tapping_key . tap . count = 1 ;
waiting_buffer [ i ] . tap . count = 1 ;
2013-01-30 11:31:32 +00:00
process_action ( & tapping_key ) ;
debug ( " waiting_buffer_scan_tap: found at [ " ) ; debug_dec ( i ) ; debug ( " ] \n " ) ;
debug_waiting_buffer ( ) ;
return ;
}
}
}
2013-01-28 05:06:42 +00:00
2013-01-23 14:53:51 +00:00
/*
* Utilities for actions .
*/
void register_code ( uint8_t code )
2012-12-15 17:32:07 +00:00
{
if ( code = = KC_NO ) {
return ;
}
else if IS_KEY ( code ) {
// TODO: should push command_proc out of this block?
2013-01-27 07:38:19 +00:00
if ( command_proc ( code ) ) return ;
if ( oneshot_state . mods & & oneshot_state . ready & & ! oneshot_state . disabled ) {
uint8_t tmp_mods = host_get_mods ( ) ;
host_add_mods ( oneshot_state . mods ) ;
host_add_key ( code ) ;
host_send_keyboard_report ( ) ;
host_set_mods ( tmp_mods ) ;
oneshot_state . ready = false ;
} else {
2012-12-15 17:32:07 +00:00
host_add_key ( code ) ;
host_send_keyboard_report ( ) ;
}
}
else if IS_MOD ( code ) {
host_add_mods ( MOD_BIT ( code ) ) ;
host_send_keyboard_report ( ) ;
}
}
2013-01-23 14:53:51 +00:00
void unregister_code ( uint8_t code )
2012-12-15 17:32:07 +00:00
{
if IS_KEY ( code ) {
host_del_key ( code ) ;
host_send_keyboard_report ( ) ;
}
else if IS_MOD ( code ) {
host_del_mods ( MOD_BIT ( code ) ) ;
host_send_keyboard_report ( ) ;
}
}
2013-01-23 14:53:51 +00:00
void add_mods ( uint8_t mods )
2013-01-15 10:04:58 +00:00
{
if ( mods ) {
host_add_mods ( mods ) ;
host_send_keyboard_report ( ) ;
}
}
2013-01-23 14:53:51 +00:00
void del_mods ( uint8_t mods )
2013-01-15 10:04:58 +00:00
{
if ( mods ) {
host_del_mods ( mods ) ;
host_send_keyboard_report ( ) ;
}
}
2013-01-23 14:53:51 +00:00
void set_mods ( uint8_t mods )
2013-01-15 10:04:58 +00:00
{
host_set_mods ( mods ) ;
host_send_keyboard_report ( ) ;
}
2013-01-23 14:53:51 +00:00
void clear_keyboard ( void )
2012-12-15 17:32:07 +00:00
{
host_clear_mods ( ) ;
clear_keyboard_but_mods ( ) ;
}
2013-01-23 14:53:51 +00:00
void clear_keyboard_but_mods ( void )
2012-12-15 17:32:07 +00:00
{
host_clear_keys ( ) ;
host_send_keyboard_report ( ) ;
# ifdef MOUSEKEY_ENABLE
mousekey_clear ( ) ;
mousekey_send ( ) ;
# endif
# ifdef EXTRAKEY_ENABLE
host_system_send ( 0 ) ;
host_consumer_send ( 0 ) ;
# endif
}
2013-01-23 14:53:51 +00:00
bool sending_anykey ( void )
2013-01-14 15:06:52 +00:00
{
return ( host_has_anykey ( ) | | host_mouse_in_use ( ) | |
host_last_sysytem_report ( ) | | host_last_consumer_report ( ) ) ;
}
2013-01-26 17:42:48 +00:00
bool is_tap_key ( key_t key )
2013-01-23 14:53:51 +00:00
{
2013-02-20 02:16:13 +00:00
action_t action = layer_switch_get_action ( key ) ;
2013-02-13 00:23:52 +00:00
2013-01-23 14:53:51 +00:00
switch ( action . kind . id ) {
case ACT_LMODS_TAP :
case ACT_RMODS_TAP :
return true ;
2013-02-20 02:16:13 +00:00
case ACT_KEYMAP :
case ACT_OVERLAY :
2013-01-23 14:53:51 +00:00
switch ( action . layer . code ) {
2013-02-20 02:16:13 +00:00
case 0x04 . . . 0xEF : /* tap key */
case OP_INV :
2013-01-23 14:53:51 +00:00
return true ;
2013-02-20 02:16:13 +00:00
default :
return false ;
2013-01-23 14:53:51 +00:00
}
2013-02-26 07:27:09 +00:00
case ACT_MACRO :
2013-01-23 14:53:51 +00:00
case ACT_FUNCTION :
2013-02-10 15:02:11 +00:00
if ( action . func . opt & FUNC_TAP ) { return true ; }
2013-01-23 14:53:51 +00:00
return false ;
}
return false ;
}
2013-01-30 11:31:32 +00:00
/*
* debug print
*/
static void debug_event ( keyevent_t event )
{
2013-02-13 03:16:24 +00:00
debug_hex16 ( ( event . key . row < < 8 ) | event . key . col ) ;
2013-01-30 11:31:32 +00:00
if ( event . pressed ) debug ( " d( " ) ; else debug ( " u( " ) ;
debug_dec ( event . time ) ; debug ( " ) " ) ;
}
static void debug_record ( keyrecord_t record )
{
2013-02-26 07:27:09 +00:00
debug_event ( record . event ) ; debug ( " : " ) ; debug_dec ( record . tap . count ) ;
if ( record . tap . interrupted ) debug ( " - " ) ;
2013-01-30 11:31:32 +00:00
}
static void debug_action ( action_t action )
{
switch ( action . kind . id ) {
case ACT_LMODS : debug ( " ACT_LMODS " ) ; break ;
case ACT_RMODS : debug ( " ACT_RMODS " ) ; break ;
case ACT_LMODS_TAP : debug ( " ACT_LMODS_TAP " ) ; break ;
case ACT_RMODS_TAP : debug ( " ACT_RMODS_TAP " ) ; break ;
case ACT_USAGE : debug ( " ACT_USAGE " ) ; break ;
case ACT_MOUSEKEY : debug ( " ACT_MOUSEKEY " ) ; break ;
2013-02-20 02:16:13 +00:00
case ACT_KEYMAP : debug ( " ACT_KEYMAP " ) ; break ;
case ACT_OVERLAY : debug ( " ACT_OVERLAY " ) ; break ;
2013-01-30 11:31:32 +00:00
case ACT_MACRO : debug ( " ACT_MACRO " ) ; break ;
case ACT_COMMAND : debug ( " ACT_COMMAND " ) ; break ;
case ACT_FUNCTION : debug ( " ACT_FUNCTION " ) ; break ;
default : debug ( " UNKNOWN " ) ; break ;
}
debug ( " [ " ) ;
debug_hex4 ( action . kind . param > > 8 ) ;
debug ( " : " ) ;
debug_hex8 ( action . kind . param & 0xff ) ;
debug ( " ] " ) ;
}
static void debug_tapping_key ( void )
{
debug ( " TAPPING_KEY= " ) ; debug_record ( tapping_key ) ; debug ( " \n " ) ;
}
static void debug_waiting_buffer ( void )
{
debug ( " { " ) ;
for ( uint8_t i = waiting_buffer_tail ; i ! = waiting_buffer_head ; i = ( i + 1 ) % WAITING_BUFFER_SIZE ) {
debug ( " [ " ) ; debug_dec ( i ) ; debug ( " ]= " ) ; debug_record ( waiting_buffer [ i ] ) ; debug ( " " ) ;
}
debug ( " } \n " ) ;
}