2015-04-09 18:32:04 +02:00
# include <stdint.h>
# include <stdbool.h>
2016-04-29 05:23:33 +02:00
# ifdef DEBUG_ACTION
2019-08-30 20:19:03 +02:00
# include "debug.h"
2016-04-29 05:23:33 +02:00
# else
2019-08-30 20:19:03 +02:00
# include "nodebug.h"
2016-04-29 05:23:33 +02:00
# endif
2015-04-09 18:32:04 +02:00
2022-03-09 19:43:12 +01:00
# include "action.h"
# include "action_layer.h"
# include "action_tapping.h"
# include "keycode.h"
# include "timer.h"
2015-04-09 18:32:04 +02:00
# ifndef NO_ACTION_TAPPING
2022-12-13 12:20:07 +01:00
# if defined(IGNORE_MOD_TAP_INTERRUPT_PER_KEY)
# error "IGNORE_MOD_TAP_INTERRUPT_PER_KEY has been removed; the code needs to be ported to use HOLD_ON_OTHER_KEY_PRESS_PER_KEY instead."
# elif !defined(IGNORE_MOD_TAP_INTERRUPT)
# if !defined(PERMISSIVE_HOLD) && !defined(PERMISSIVE_HOLD_PER_KEY) && !defined(HOLD_ON_OTHER_KEY_PRESS) && !defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY)
# pragma message "The default behavior of mod-taps will change to mimic IGNORE_MOD_TAP_INTERRUPT in the future.\nIf you wish to keep the old default behavior of mod-taps, please use HOLD_ON_OTHER_KEY_PRESS."
# endif
# endif
2019-08-30 20:19:03 +02:00
# define IS_TAPPING() !IS_NOEVENT(tapping_key.event)
# 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)))
2021-11-01 20:18:33 +01:00
# ifndef COMBO_ENABLE
# define IS_TAPPING_RECORD(r) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (r->event.key)))
# else
# define IS_TAPPING_RECORD(r) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (r->event.key)) && tapping_key.keycode == r->keycode)
# endif
2022-04-16 20:24:09 +02:00
# define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < GET_TAPPING_TERM(get_record_keycode(&tapping_key, false), &tapping_key))
2022-12-12 16:52:22 +01:00
# define WITHIN_QUICK_TAP_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < GET_QUICK_TAP_TERM(get_record_keycode(&tapping_key, false), &tapping_key))
2015-04-09 18:32:04 +02:00
2022-04-16 20:24:09 +02:00
# ifdef DYNAMIC_TAPPING_TERM_ENABLE
2021-11-25 21:06:50 +01:00
uint16_t g_tapping_term = TAPPING_TERM ;
2022-04-16 20:24:09 +02:00
# endif
2021-11-25 21:06:50 +01:00
2022-04-16 20:24:09 +02:00
# ifdef TAPPING_TERM_PER_KEY
2022-02-12 19:29:31 +01:00
__attribute__ ( ( weak ) ) uint16_t get_tapping_term ( uint16_t keycode , keyrecord_t * record ) {
2022-04-16 20:24:09 +02:00
# ifdef DYNAMIC_TAPPING_TERM_ENABLE
2022-02-12 19:29:31 +01:00
return g_tapping_term ;
2022-04-16 20:24:09 +02:00
# else
return TAPPING_TERM ;
# endif
2022-02-12 19:29:31 +01:00
}
2019-08-30 20:19:03 +02:00
# endif
2015-04-09 18:32:04 +02:00
2022-12-12 16:52:22 +01:00
# ifdef QUICK_TAP_TERM_PER_KEY
__attribute__ ( ( weak ) ) uint16_t get_quick_tap_term ( uint16_t keycode , keyrecord_t * record ) {
return QUICK_TAP_TERM ;
2022-02-12 19:29:31 +01:00
}
2020-01-17 21:49:23 +01:00
# endif
2020-02-25 19:25:52 +01:00
# ifdef PERMISSIVE_HOLD_PER_KEY
2022-02-12 19:29:31 +01:00
__attribute__ ( ( weak ) ) bool get_permissive_hold ( uint16_t keycode , keyrecord_t * record ) {
return false ;
}
2020-02-25 19:25:52 +01:00
# endif
2021-08-07 01:16:26 +02:00
# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY
2022-02-12 19:29:31 +01:00
__attribute__ ( ( weak ) ) bool get_hold_on_other_key_press ( uint16_t keycode , keyrecord_t * record ) {
return false ;
}
2021-08-07 01:16:26 +02:00
# endif
2021-11-25 13:12:14 +01:00
# if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)
# include "process_auto_shift.h"
# endif
2019-08-30 20:19:03 +02:00
static keyrecord_t tapping_key = { } ;
2015-04-09 18:32:04 +02:00
static keyrecord_t waiting_buffer [ WAITING_BUFFER_SIZE ] = { } ;
2019-08-30 20:19:03 +02:00
static uint8_t waiting_buffer_head = 0 ;
static uint8_t waiting_buffer_tail = 0 ;
2015-04-09 18:32:04 +02:00
static bool process_tapping ( keyrecord_t * record ) ;
static bool waiting_buffer_enq ( keyrecord_t record ) ;
static void waiting_buffer_clear ( void ) ;
static bool waiting_buffer_typed ( keyevent_t event ) ;
static bool waiting_buffer_has_anykey_pressed ( void ) ;
static void waiting_buffer_scan_tap ( void ) ;
static void debug_tapping_key ( void ) ;
static void debug_waiting_buffer ( void ) ;
2018-03-22 07:50:38 +01:00
/** \brief Action Tapping Process
*
* FIXME : Needs doc
*/
2019-08-30 20:19:03 +02:00
void action_tapping_process ( keyrecord_t record ) {
2015-04-09 18:32:04 +02:00
if ( process_tapping ( & record ) ) {
if ( ! IS_NOEVENT ( record . event ) ) {
2019-08-30 20:19:03 +02:00
debug ( " processed: " ) ;
debug_record ( record ) ;
debug ( " \n " ) ;
2015-04-09 18:32:04 +02:00
}
} else {
if ( ! waiting_buffer_enq ( record ) ) {
// clear all in case of overflow.
debug ( " OVERFLOW: CLEAR ALL STATES \n " ) ;
clear_keyboard ( ) ;
waiting_buffer_clear ( ) ;
tapping_key = ( keyrecord_t ) { } ;
}
}
// process waiting_buffer
if ( ! IS_NOEVENT ( record . event ) & & waiting_buffer_head ! = waiting_buffer_tail ) {
debug ( " ---- action_exec: process waiting_buffer ----- \n " ) ;
}
for ( ; waiting_buffer_tail ! = waiting_buffer_head ; waiting_buffer_tail = ( waiting_buffer_tail + 1 ) % WAITING_BUFFER_SIZE ) {
if ( process_tapping ( & waiting_buffer [ waiting_buffer_tail ] ) ) {
2019-08-30 20:19:03 +02:00
debug ( " processed: waiting_buffer[ " ) ;
debug_dec ( waiting_buffer_tail ) ;
debug ( " ] = " ) ;
debug_record ( waiting_buffer [ waiting_buffer_tail ] ) ;
debug ( " \n \n " ) ;
2015-04-09 18:32:04 +02:00
} else {
break ;
}
}
if ( ! IS_NOEVENT ( record . event ) ) {
debug ( " \n " ) ;
}
}
2022-11-28 09:16:38 +01:00
/* Some conditionally defined helper macros to keep process_tapping more
* readable . The conditional definition of tapping_keycode and all the
* conditional uses of it are hidden inside macros named TAP_ . . .
*/
2022-12-12 16:52:22 +01:00
# if (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)) || defined(PERMISSIVE_HOLD_PER_KEY) || defined(QUICK_TAP_TERM_PER_KEY) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY)
2022-11-28 09:16:38 +01:00
# define TAP_DEFINE_KEYCODE uint16_t tapping_keycode = get_record_keycode(&tapping_key, false)
# else
# define TAP_DEFINE_KEYCODE
# endif
# if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)
# ifdef RETRO_TAPPING_PER_KEY
# define TAP_GET_RETRO_TAPPING get_retro_tapping(tapping_keycode, &tapping_key)
# else
# define TAP_GET_RETRO_TAPPING true
# endif
# define MAYBE_RETRO_SHIFTING(ev) (TAP_GET_RETRO_TAPPING && (RETRO_SHIFT + 0) != 0 && TIMER_DIFF_16((ev).time, tapping_key.event.time) < (RETRO_SHIFT + 0))
# define TAP_IS_LT IS_LT(tapping_keycode)
# define TAP_IS_MT IS_MT(tapping_keycode)
# define TAP_IS_RETRO IS_RETRO(tapping_keycode)
# else
# define TAP_GET_RETRO_TAPPING false
# define MAYBE_RETRO_SHIFTING(ev) false
# define TAP_IS_LT false
# define TAP_IS_MT false
# define TAP_IS_RETRO false
# endif
# ifdef PERMISSIVE_HOLD_PER_KEY
# define TAP_GET_PERMISSIVE_HOLD get_permissive_hold(tapping_keycode, &tapping_key)
# elif defined(PERMISSIVE_HOLD)
# define TAP_GET_PERMISSIVE_HOLD true
# else
# define TAP_GET_PERMISSIVE_HOLD false
# endif
# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY
# define TAP_GET_HOLD_ON_OTHER_KEY_PRESS get_hold_on_other_key_press(tapping_keycode, &tapping_key)
# elif defined(HOLD_ON_OTHER_KEY_PRESS)
# define TAP_GET_HOLD_ON_OTHER_KEY_PRESS true
# else
# define TAP_GET_HOLD_ON_OTHER_KEY_PRESS false
# endif
2022-12-13 12:20:07 +01:00
# if defined(IGNORE_MOD_TAP_INTERRUPT)
2022-11-28 09:16:38 +01:00
# define TAP_GET_IGNORE_MOD_TAP_INTERRUPT true
# else
# define TAP_GET_IGNORE_MOD_TAP_INTERRUPT false
# endif
2018-03-22 07:50:38 +01:00
/** \brief Tapping
2015-04-09 18:32:04 +02:00
*
* Rule : Tap key is typed ( pressed and released ) within TAPPING_TERM .
* ( without interfering by typing other key )
*/
/* return true when key event is processed or consumed. */
2019-08-30 20:19:03 +02:00
bool process_tapping ( keyrecord_t * keyp ) {
2015-04-09 18:32:04 +02:00
keyevent_t event = keyp - > event ;
2022-11-28 09:16:38 +01:00
TAP_DEFINE_KEYCODE ;
2015-04-09 18:32:04 +02:00
// if tapping
if ( IS_TAPPING_PRESSED ( ) ) {
2022-11-28 09:16:38 +01:00
if ( WITHIN_TAPPING_TERM ( event ) | | MAYBE_RETRO_SHIFTING ( event ) ) {
2015-04-09 18:32:04 +02:00
if ( tapping_key . tap . count = = 0 ) {
2021-08-06 01:44:57 +02:00
if ( IS_TAPPING_RECORD ( keyp ) & & ! event . pressed ) {
2021-11-25 13:12:14 +01:00
# if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)
retroshift_swap_times ( ) ;
# endif
2015-04-09 18:32:04 +02:00
// first tap!
debug ( " Tapping: First tap(0->1). \n " ) ;
tapping_key . tap . count = 1 ;
debug_tapping_key ( ) ;
2016-05-15 06:47:25 +02:00
process_record ( & tapping_key ) ;
2015-04-09 18:32:04 +02:00
// copy tapping state
keyp - > tap = tapping_key . tap ;
// enqueue
return false ;
}
/* Process a key typed within TAPPING_TERM
* This can register the key before settlement of tapping ,
* useful for long TAPPING_TERM but may prevent fast typing .
*/
2021-11-25 13:12:14 +01:00
// clang-format off
else if (
(
2022-11-28 09:16:38 +01:00
IS_RELEASED ( event ) & & waiting_buffer_typed ( event ) & &
TAP_GET_PERMISSIVE_HOLD
2021-11-25 13:12:14 +01:00
)
// Causes nested taps to not wait past TAPPING_TERM/RETRO_SHIFT
// unnecessarily and fixes them for Layer Taps.
2022-11-28 09:16:38 +01:00
| | ( TAP_GET_RETRO_TAPPING & &
2021-11-25 13:12:14 +01:00
(
// Rolled over the two keys.
2022-11-28 09:16:38 +01:00
( tapping_key . tap . interrupted = = true & & (
( TAP_IS_LT & & TAP_GET_HOLD_ON_OTHER_KEY_PRESS ) | |
2022-12-13 12:20:07 +01:00
( TAP_IS_MT & & TAP_GET_HOLD_ON_OTHER_KEY_PRESS )
2022-11-28 09:16:38 +01:00
)
2021-11-25 13:12:14 +01:00
)
// Makes Retro Shift ignore [IGNORE_MOD_TAP_INTERRUPT's
// effects on nested taps for MTs and the default
// behavior of LTs] below TAPPING_TERM or RETRO_SHIFT.
| | (
2022-11-28 09:16:38 +01:00
TAP_IS_RETRO
2021-11-25 13:12:14 +01:00
& & ( event . key . col ! = tapping_key . event . key . col | | event . key . row ! = tapping_key . event . key . row )
& & IS_RELEASED ( event ) & & waiting_buffer_typed ( event )
)
)
)
) {
// clang-format on
2015-04-09 18:32:04 +02:00
debug ( " Tapping: End. No tap. Interfered by typing key \n " ) ;
2016-05-15 06:47:25 +02:00
process_record ( & tapping_key ) ;
2015-04-09 18:32:04 +02:00
tapping_key = ( keyrecord_t ) { } ;
debug_tapping_key ( ) ;
// enqueue
return false ;
}
/* Process release event of a key pressed before tapping starts
* Without this unexpected repeating will occur with having fast repeating setting
* https : //github.com/tmk/tmk_keyboard/issues/60
*/
else if ( IS_RELEASED ( event ) & & ! waiting_buffer_typed ( event ) ) {
2022-11-28 09:16:38 +01:00
// Modifier/Layer should be retained till end of this tapping.
2015-04-09 18:32:04 +02:00
action_t action = layer_switch_get_action ( event . key ) ;
switch ( action . kind . id ) {
case ACT_LMODS :
case ACT_RMODS :
if ( action . key . mods & & ! action . key . code ) return false ;
if ( IS_MOD ( action . key . code ) ) return false ;
break ;
case ACT_LMODS_TAP :
case ACT_RMODS_TAP :
if ( action . key . mods & & keyp - > tap . count = = 0 ) return false ;
if ( IS_MOD ( action . key . code ) ) return false ;
break ;
2022-11-28 09:16:38 +01:00
case ACT_LAYER_TAP :
case ACT_LAYER_TAP_EXT :
switch ( action . layer_tap . code ) {
case 0 . . . ( OP_TAP_TOGGLE - 1 ) :
case OP_ON_OFF :
case OP_OFF_ON :
case OP_SET_CLEAR :
return false ;
}
break ;
2015-04-09 18:32:04 +02:00
}
// Release of key should be process immediately.
debug ( " Tapping: release event of a key pressed before tapping \n " ) ;
2016-05-15 06:47:25 +02:00
process_record ( keyp ) ;
2015-04-09 18:32:04 +02:00
return true ;
2019-08-30 20:19:03 +02:00
} else {
2015-04-09 18:32:04 +02:00
// set interrupted flag when other key preesed during tapping
if ( event . pressed ) {
tapping_key . tap . interrupted = true ;
2022-11-28 09:16:38 +01:00
if ( TAP_GET_HOLD_ON_OTHER_KEY_PRESS ) {
2021-08-07 01:16:26 +02:00
debug ( " Tapping: End. No tap. Interfered by pressed key \n " ) ;
process_record ( & tapping_key ) ;
tapping_key = ( keyrecord_t ) { } ;
debug_tapping_key ( ) ;
// enqueue
return false ;
}
2015-04-09 18:32:04 +02:00
}
2016-04-17 19:54:32 +02:00
// enqueue
2015-04-09 18:32:04 +02:00
return false ;
}
}
// tap_count > 0
else {
2021-08-06 01:44:57 +02:00
if ( IS_TAPPING_RECORD ( keyp ) & & ! event . pressed ) {
2019-08-30 20:19:03 +02:00
debug ( " Tapping: Tap release( " ) ;
debug_dec ( tapping_key . tap . count ) ;
debug ( " ) \n " ) ;
2015-04-09 18:32:04 +02:00
keyp - > tap = tapping_key . tap ;
2016-05-15 06:47:25 +02:00
process_record ( keyp ) ;
2015-04-09 18:32:04 +02:00
tapping_key = * keyp ;
debug_tapping_key ( ) ;
return true ;
2021-08-06 01:44:57 +02:00
} else if ( is_tap_record ( keyp ) & & event . pressed ) {
2015-04-09 18:32:04 +02:00
if ( tapping_key . tap . count > 1 ) {
debug ( " Tapping: Start new tap with releasing last tap(>1). \n " ) ;
// unregister key
2021-11-01 20:18:33 +01:00
process_record ( & ( keyrecord_t ) {
. tap = tapping_key . tap ,
. event . key = tapping_key . event . key ,
. event . time = event . time ,
. event . pressed = false ,
# ifdef COMBO_ENABLE
. keycode = tapping_key . keycode ,
# endif
} ) ;
2015-04-09 18:32:04 +02:00
} else {
debug ( " Tapping: Start while last tap(1). \n " ) ;
}
tapping_key = * keyp ;
waiting_buffer_scan_tap ( ) ;
debug_tapping_key ( ) ;
return true ;
2019-08-30 20:19:03 +02:00
} else {
2015-04-09 18:32:04 +02:00
if ( ! IS_NOEVENT ( event ) ) {
debug ( " Tapping: key event while last tap(>0). \n " ) ;
}
2016-05-15 06:47:25 +02:00
process_record ( keyp ) ;
2015-04-09 18:32:04 +02:00
return true ;
}
}
}
// after TAPPING_TERM
else {
if ( tapping_key . tap . count = = 0 ) {
debug ( " Tapping: End. Timeout. Not tap(0): " ) ;
2019-08-30 20:19:03 +02:00
debug_event ( event ) ;
debug ( " \n " ) ;
2016-05-15 06:47:25 +02:00
process_record ( & tapping_key ) ;
2015-04-09 18:32:04 +02:00
tapping_key = ( keyrecord_t ) { } ;
debug_tapping_key ( ) ;
return false ;
2019-08-30 20:19:03 +02:00
} else {
2021-08-06 01:44:57 +02:00
if ( IS_TAPPING_RECORD ( keyp ) & & ! event . pressed ) {
2015-04-09 18:32:04 +02:00
debug ( " Tapping: End. last timeout tap release(>0). " ) ;
keyp - > tap = tapping_key . tap ;
2016-05-15 06:47:25 +02:00
process_record ( keyp ) ;
2015-04-09 18:32:04 +02:00
tapping_key = ( keyrecord_t ) { } ;
return true ;
2021-08-06 01:44:57 +02:00
} else if ( is_tap_record ( keyp ) & & event . pressed ) {
2015-04-09 18:32:04 +02:00
if ( tapping_key . tap . count > 1 ) {
debug ( " Tapping: Start new tap with releasing last timeout tap(>1). \n " ) ;
// unregister key
2021-11-01 20:18:33 +01:00
process_record ( & ( keyrecord_t ) {
. tap = tapping_key . tap ,
. event . key = tapping_key . event . key ,
. event . time = event . time ,
. event . pressed = false ,
# ifdef COMBO_ENABLE
. keycode = tapping_key . keycode ,
# endif
} ) ;
2015-04-09 18:32:04 +02:00
} else {
debug ( " Tapping: Start while last timeout tap(1). \n " ) ;
}
tapping_key = * keyp ;
waiting_buffer_scan_tap ( ) ;
debug_tapping_key ( ) ;
return true ;
2019-08-30 20:19:03 +02:00
} else {
2015-04-09 18:32:04 +02:00
if ( ! IS_NOEVENT ( event ) ) {
debug ( " Tapping: key event while last timeout tap(>0). \n " ) ;
}
2016-05-15 06:47:25 +02:00
process_record ( keyp ) ;
2015-04-09 18:32:04 +02:00
return true ;
}
}
}
} else if ( IS_TAPPING_RELEASED ( ) ) {
2022-11-28 09:16:38 +01:00
if ( WITHIN_TAPPING_TERM ( event ) | | MAYBE_RETRO_SHIFTING ( event ) ) {
2015-04-09 18:32:04 +02:00
if ( event . pressed ) {
2021-08-06 01:44:57 +02:00
if ( IS_TAPPING_RECORD ( keyp ) ) {
2022-12-12 16:52:22 +01:00
if ( WITHIN_QUICK_TAP_TERM ( event ) & & ! tapping_key . tap . interrupted & & tapping_key . tap . count > 0 ) {
2015-04-09 18:32:04 +02:00
// sequential tap.
keyp - > tap = tapping_key . tap ;
if ( keyp - > tap . count < 15 ) keyp - > tap . count + = 1 ;
2019-08-30 20:19:03 +02:00
debug ( " Tapping: Tap press( " ) ;
debug_dec ( keyp - > tap . count ) ;
debug ( " ) \n " ) ;
2016-05-15 06:47:25 +02:00
process_record ( keyp ) ;
2015-04-09 18:32:04 +02:00
tapping_key = * keyp ;
debug_tapping_key ( ) ;
return true ;
}
2017-02-14 06:12:54 +01:00
// FIX: start new tap again
tapping_key = * keyp ;
return true ;
2021-08-06 01:44:57 +02:00
} else if ( is_tap_record ( keyp ) ) {
2015-04-09 18:32:04 +02:00
// Sequential tap can be interfered with other tap key.
debug ( " Tapping: Start with interfering other tap. \n " ) ;
tapping_key = * keyp ;
waiting_buffer_scan_tap ( ) ;
debug_tapping_key ( ) ;
return true ;
} else {
// should none in buffer
// FIX: interrupted when other key is pressed
tapping_key . tap . interrupted = true ;
2016-05-15 06:47:25 +02:00
process_record ( keyp ) ;
2015-04-09 18:32:04 +02:00
return true ;
}
} else {
2017-02-25 13:49:03 +01:00
if ( ! IS_NOEVENT ( event ) ) debug ( " Tapping: other key just after tap. \n " ) ;
2016-05-15 06:47:25 +02:00
process_record ( keyp ) ;
2015-04-09 18:32:04 +02:00
return true ;
}
} else {
2018-03-12 18:22:49 +01:00
// FIX: process_action here?
2015-04-09 18:32:04 +02:00
// timeout. no sequential tap.
debug ( " Tapping: End(Timeout after releasing last tap): " ) ;
2019-08-30 20:19:03 +02:00
debug_event ( event ) ;
debug ( " \n " ) ;
2015-04-09 18:32:04 +02:00
tapping_key = ( keyrecord_t ) { } ;
debug_tapping_key ( ) ;
return false ;
}
}
// not tapping state
else {
2021-08-06 01:44:57 +02:00
if ( event . pressed & & is_tap_record ( keyp ) ) {
2015-04-09 18:32:04 +02:00
debug ( " Tapping: Start(Press tap key). \n " ) ;
tapping_key = * keyp ;
2018-03-12 18:22:49 +01:00
process_record_tap_hint ( & tapping_key ) ;
2015-04-09 18:32:04 +02:00
waiting_buffer_scan_tap ( ) ;
debug_tapping_key ( ) ;
return true ;
} else {
2016-05-15 06:47:25 +02:00
process_record ( keyp ) ;
2015-04-09 18:32:04 +02:00
return true ;
}
}
}
2018-03-22 07:50:38 +01:00
/** \brief Waiting buffer enq
*
* FIXME : Needs docs
2015-04-09 18:32:04 +02:00
*/
2019-08-30 20:19:03 +02:00
bool waiting_buffer_enq ( keyrecord_t record ) {
2015-04-09 18:32:04 +02:00
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 ;
}
waiting_buffer [ waiting_buffer_head ] = record ;
2019-08-30 20:19:03 +02:00
waiting_buffer_head = ( waiting_buffer_head + 1 ) % WAITING_BUFFER_SIZE ;
2015-04-09 18:32:04 +02:00
2019-08-30 20:19:03 +02:00
debug ( " waiting_buffer_enq: " ) ;
debug_waiting_buffer ( ) ;
2015-04-09 18:32:04 +02:00
return true ;
}
2018-03-22 07:50:38 +01:00
/** \brief Waiting buffer clear
*
* FIXME : Needs docs
*/
2019-08-30 20:19:03 +02:00
void waiting_buffer_clear ( void ) {
2015-04-09 18:32:04 +02:00
waiting_buffer_head = 0 ;
waiting_buffer_tail = 0 ;
}
2018-03-22 07:50:38 +01:00
/** \brief Waiting buffer typed
*
* FIXME : Needs docs
*/
2019-08-30 20:19:03 +02:00
bool waiting_buffer_typed ( keyevent_t event ) {
2015-04-09 18:32:04 +02:00
for ( uint8_t i = waiting_buffer_tail ; i ! = waiting_buffer_head ; i = ( i + 1 ) % WAITING_BUFFER_SIZE ) {
2019-08-30 20:19:03 +02:00
if ( KEYEQ ( event . key , waiting_buffer [ i ] . event . key ) & & event . pressed ! = waiting_buffer [ i ] . event . pressed ) {
2015-04-09 18:32:04 +02:00
return true ;
}
}
return false ;
}
2018-03-22 07:50:38 +01:00
/** \brief Waiting buffer has anykey pressed
*
* FIXME : Needs docs
*/
2019-08-30 20:19:03 +02:00
__attribute__ ( ( unused ) ) bool waiting_buffer_has_anykey_pressed ( void ) {
2015-04-09 18:32:04 +02: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 ;
}
return false ;
}
2018-03-22 07:50:38 +01:00
/** \brief Scan buffer for tapping
*
* FIXME : Needs docs
*/
2019-08-30 20:19:03 +02:00
void waiting_buffer_scan_tap ( void ) {
2015-04-09 18:32:04 +02:00
// tapping already is settled
if ( tapping_key . tap . count > 0 ) return ;
// invalid state: tapping_key released && tap.count == 0
if ( ! tapping_key . event . pressed ) return ;
for ( uint8_t i = waiting_buffer_tail ; i ! = waiting_buffer_head ; i = ( i + 1 ) % WAITING_BUFFER_SIZE ) {
2019-08-30 20:19:03 +02:00
if ( IS_TAPPING_KEY ( waiting_buffer [ i ] . event . key ) & & ! waiting_buffer [ i ] . event . pressed & & WITHIN_TAPPING_TERM ( waiting_buffer [ i ] . event ) ) {
tapping_key . tap . count = 1 ;
2015-04-09 18:32:04 +02:00
waiting_buffer [ i ] . tap . count = 1 ;
2016-05-15 06:47:25 +02:00
process_record ( & tapping_key ) ;
2015-04-09 18:32:04 +02:00
2019-08-30 20:19:03 +02:00
debug ( " waiting_buffer_scan_tap: found at [ " ) ;
debug_dec ( i ) ;
debug ( " ] \n " ) ;
2015-04-09 18:32:04 +02:00
debug_waiting_buffer ( ) ;
return ;
}
}
}
2018-03-22 07:50:38 +01:00
/** \brief Tapping key debug print
*
* FIXME : Needs docs
2015-04-09 18:32:04 +02:00
*/
2019-08-30 20:19:03 +02:00
static void debug_tapping_key ( void ) {
debug ( " TAPPING_KEY= " ) ;
debug_record ( tapping_key ) ;
debug ( " \n " ) ;
2015-04-09 18:32:04 +02:00
}
2018-03-22 07:50:38 +01:00
/** \brief Waiting buffer debug print
*
* FIXME : Needs docs
*/
2019-08-30 20:19:03 +02:00
static void debug_waiting_buffer ( void ) {
2015-04-09 18:32:04 +02:00
debug ( " { " ) ;
for ( uint8_t i = waiting_buffer_tail ; i ! = waiting_buffer_head ; i = ( i + 1 ) % WAITING_BUFFER_SIZE ) {
2019-08-30 20:19:03 +02:00
debug ( " [ " ) ;
debug_dec ( i ) ;
debug ( " ]= " ) ;
debug_record ( waiting_buffer [ i ] ) ;
debug ( " " ) ;
2015-04-09 18:32:04 +02:00
}
debug ( " } \n " ) ;
}
# endif