mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-01-01 06:23:35 +01:00
keyboard: add custom repeat filters for full repeat control
This change introduces a new getkey_repeat_filter() function that can be used to individually accept, deny or delay repeat events for specific keys and timings.
This commit is contained in:
parent
a4d23ef7ad
commit
4288dc27d9
2 changed files with 70 additions and 5 deletions
|
@ -200,11 +200,13 @@ enum {
|
||||||
/* Repeat arrow keys, or even all keys */
|
/* Repeat arrow keys, or even all keys */
|
||||||
GETKEY_REP_ARROWS = 0x10,
|
GETKEY_REP_ARROWS = 0x10,
|
||||||
GETKEY_REP_ALL = 0x20,
|
GETKEY_REP_ALL = 0x20,
|
||||||
|
/* Enable repeat event filtering; see getkey_repeat_filter() */
|
||||||
|
GETKEY_REP_FILTER = 0x40,
|
||||||
|
|
||||||
/* No modifiers */
|
/* No modifiers */
|
||||||
GETKEY_NONE = 0x00,
|
GETKEY_NONE = 0x00,
|
||||||
/* Default settings of getkey() */
|
/* Default settings of getkey() */
|
||||||
GETKEY_DEFAULT = 0x1f,
|
GETKEY_DEFAULT = 0x5f,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* getkey_opt(): Enhanced getkey()
|
/* getkey_opt(): Enhanced getkey()
|
||||||
|
@ -244,6 +246,33 @@ key_event_t getkey_opt(int options, volatile int *timeout);
|
||||||
@next Delay between subsequent repeats (no more than one hour) */
|
@next Delay between subsequent repeats (no more than one hour) */
|
||||||
void getkey_repeat(int first, int next);
|
void getkey_repeat(int first, int next);
|
||||||
|
|
||||||
|
/* getkey_repeat_filter(): Set the repeat filter function
|
||||||
|
|
||||||
|
This function is called by getkey() and getkey_opt() every time a repeat
|
||||||
|
event occurs when GETKEY_REPEAT_FILTER. The function can decide whether to
|
||||||
|
keep, delay it or drop it entirely. It can also change the repeat delays
|
||||||
|
with getkey_repeat() for fully custom repeat delay curves.
|
||||||
|
|
||||||
|
The time elapsed since the last accepted repeat is passed to the filter
|
||||||
|
function; this time must be larger than the repeat time set with
|
||||||
|
getkey_repeat() for getkey() and getkey_opt() to consider a repeat, but it
|
||||||
|
can be much longer if some repeat events were previously filtered out.
|
||||||
|
|
||||||
|
@key Key that is about to be repeated
|
||||||
|
@duration Duration since last accepted repeat
|
||||||
|
@count Number of previous repeats
|
||||||
|
|
||||||
|
The repeat function must either return:
|
||||||
|
* 0, in which case the even is accepted
|
||||||
|
* A positive number of milliseconds, in which case the event is tentatively
|
||||||
|
re-emitted after that time (the filter function will be called again)
|
||||||
|
* A negative number, in which case the event is dropped and further repeats
|
||||||
|
are denied.
|
||||||
|
|
||||||
|
By default the filter function is NULL, which accepts all repeat events.
|
||||||
|
This behavior can be restored explicitly by calling with function=NULL. */
|
||||||
|
void getkey_repeat_filter(int (*filter)(int key, int duration, int count));
|
||||||
|
|
||||||
//---
|
//---
|
||||||
// Key code functions
|
// Key code functions
|
||||||
//---
|
//---
|
||||||
|
|
|
@ -15,13 +15,16 @@ static int rep_first = 64;
|
||||||
/* Delay between subsequent repeats, in scan intervals */
|
/* Delay between subsequent repeats, in scan intervals */
|
||||||
static int rep_next = 8;
|
static int rep_next = 8;
|
||||||
|
|
||||||
/* getkey() - wait for a pressed key */
|
/* Repeat filter function */
|
||||||
|
static int (*filter_function)(int key, int duration, int count) = NULL;
|
||||||
|
|
||||||
|
/* getkey(): Wait for a key press */
|
||||||
key_event_t getkey(void)
|
key_event_t getkey(void)
|
||||||
{
|
{
|
||||||
return getkey_opt(GETKEY_DEFAULT, NULL);
|
return getkey_opt(GETKEY_DEFAULT, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* getkey_opt() - enhanced getkey() */
|
/* getkey_opt(): Enhanced getkey() */
|
||||||
key_event_t getkey_opt(int opt, volatile int *timeout)
|
key_event_t getkey_opt(int opt, volatile int *timeout)
|
||||||
{
|
{
|
||||||
key_event_t ev;
|
key_event_t ev;
|
||||||
|
@ -33,6 +36,8 @@ key_event_t getkey_opt(int opt, volatile int *timeout)
|
||||||
static int rep_count = 0;
|
static int rep_count = 0;
|
||||||
/* Keyboard time when the key was pressed */
|
/* Keyboard time when the key was pressed */
|
||||||
static int rep_time = 0;
|
static int rep_time = 0;
|
||||||
|
/* Additional repeat delay set by the filtering function */
|
||||||
|
static int rep_delay = 0;
|
||||||
|
|
||||||
/* Reset the state if the repeated key went up while getkey() was not
|
/* Reset the state if the repeated key went up while getkey() was not
|
||||||
aware (this happens when different keyboard primitives are used) */
|
aware (this happens when different keyboard primitives are used) */
|
||||||
|
@ -41,6 +46,7 @@ key_event_t getkey_opt(int opt, volatile int *timeout)
|
||||||
rep_key = 0;
|
rep_key = 0;
|
||||||
rep_count = 0;
|
rep_count = 0;
|
||||||
rep_time = 0;
|
rep_time = 0;
|
||||||
|
rep_delay = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(1) switch((ev = pollevent()).type)
|
while(1) switch((ev = pollevent()).type)
|
||||||
|
@ -85,6 +91,7 @@ key_event_t getkey_opt(int opt, volatile int *timeout)
|
||||||
rep_key = key;
|
rep_key = key;
|
||||||
rep_count = 0;
|
rep_count = 0;
|
||||||
rep_time = ev.time;
|
rep_time = ev.time;
|
||||||
|
rep_delay = 0;
|
||||||
|
|
||||||
ev.mod = 1;
|
ev.mod = 1;
|
||||||
ev.shift = shift;
|
ev.shift = shift;
|
||||||
|
@ -108,11 +115,33 @@ key_event_t getkey_opt(int opt, volatile int *timeout)
|
||||||
/* If the key is key pressed long enough, create a new event */
|
/* If the key is key pressed long enough, create a new event */
|
||||||
int duration = (int16_t)(ev.time - rep_time);
|
int duration = (int16_t)(ev.time - rep_time);
|
||||||
|
|
||||||
int target = (rep_count) ? rep_next : rep_first;
|
if(rep_delay < 0) break;
|
||||||
|
int target = (rep_count ? rep_next : rep_first) + rep_delay;
|
||||||
if(duration < target) break;
|
if(duration < target) break;
|
||||||
|
|
||||||
|
/* Filter out the event if repeat filtering is on */
|
||||||
|
if(filter_function && (opt & GETKEY_REP_FILTER))
|
||||||
|
{
|
||||||
|
int s = filter_function(rep_key, duration, rep_count);
|
||||||
|
/* Drop repeats forever */
|
||||||
|
if(s < 0)
|
||||||
|
{
|
||||||
|
rep_delay = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Delay repeat by set amount */
|
||||||
|
if(s > 0)
|
||||||
|
{
|
||||||
|
s = (s * KEYBOARD_SCAN_FREQUENCY) / 1000;
|
||||||
|
rep_delay += s;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Accepts repeat (fallthrough) */
|
||||||
|
}
|
||||||
|
|
||||||
rep_time += target;
|
rep_time += target;
|
||||||
rep_count++;
|
rep_count++;
|
||||||
|
rep_delay = 0;
|
||||||
|
|
||||||
ev.mod = 1;
|
ev.mod = 1;
|
||||||
ev.shift = shift;
|
ev.shift = shift;
|
||||||
|
@ -128,13 +157,20 @@ key_event_t getkey_opt(int opt, volatile int *timeout)
|
||||||
rep_key = 0;
|
rep_key = 0;
|
||||||
rep_count = 0;
|
rep_count = 0;
|
||||||
rep_time = 0;
|
rep_time = 0;
|
||||||
|
rep_delay = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* getkey_repeat() - set repeat delays for getkey() */
|
/* getkey_repeat(): Set repeat delays for getkey() */
|
||||||
void getkey_repeat(int first, int next)
|
void getkey_repeat(int first, int next)
|
||||||
{
|
{
|
||||||
rep_first = (first * KEYBOARD_SCAN_FREQUENCY) / 1000;
|
rep_first = (first * KEYBOARD_SCAN_FREQUENCY) / 1000;
|
||||||
rep_next = (next * KEYBOARD_SCAN_FREQUENCY) / 1000;
|
rep_next = (next * KEYBOARD_SCAN_FREQUENCY) / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* getkey_repeat_filter(): Set the repeat filter function */
|
||||||
|
void getkey_repeat_filter(int (*filter)(int key, int duration, int count))
|
||||||
|
{
|
||||||
|
filter_function = filter;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue