2019-02-21 20:58:38 +01:00
|
|
|
//---
|
|
|
|
// gint:keysc:getkey - High-level keyboard monitoring function
|
|
|
|
//---
|
|
|
|
|
|
|
|
#include <gint/keyboard.h>
|
|
|
|
#include <gint/defs/types.h>
|
|
|
|
|
|
|
|
#ifdef FX9860G
|
|
|
|
#include <gint/drivers/t6k11.h>
|
|
|
|
#endif
|
|
|
|
|
2019-07-17 00:23:21 +02:00
|
|
|
/* Delay between a key press and the first repeat, in scan intervals */
|
|
|
|
static int rep_first = 64;
|
|
|
|
/* Delay between subsequent repeats, in scan intervals */
|
2019-07-18 01:29:12 +02:00
|
|
|
static int rep_next = 8;
|
2019-02-21 20:58:38 +01:00
|
|
|
|
|
|
|
/* getkey() - wait for a pressed key */
|
|
|
|
key_event_t getkey(void)
|
|
|
|
{
|
|
|
|
return getkey_opt(GETKEY_DEFAULT, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* getkey_opt() - enhanced getkey() */
|
|
|
|
key_event_t getkey_opt(int opt, volatile int *timeout)
|
|
|
|
{
|
|
|
|
key_event_t ev;
|
|
|
|
int shift = 0, alpha = 0, key = 0;
|
|
|
|
|
|
|
|
/* Last pressed key (only this key may be repeated) */
|
2019-07-17 00:23:21 +02:00
|
|
|
static int rep_key = 0;
|
2019-02-21 20:58:38 +01:00
|
|
|
/* Number of repeats already emitted */
|
2019-07-17 00:23:21 +02:00
|
|
|
static int rep_count = 0;
|
2019-09-28 19:22:47 +02:00
|
|
|
/* Keyboard time when the key was pressed */
|
2019-07-17 00:23:21 +02:00
|
|
|
static int rep_time = 0;
|
2019-02-21 20:58:38 +01:00
|
|
|
|
2020-05-10 14:03:41 +02:00
|
|
|
/* Reset the state if the repeated key went up while getkey() was not
|
|
|
|
aware (this happens when different keyboard primitives are used) */
|
2020-02-20 21:09:39 +01:00
|
|
|
if(rep_key && !keydown(rep_key))
|
|
|
|
{
|
|
|
|
rep_key = 0;
|
|
|
|
rep_count = 0;
|
|
|
|
rep_time = 0;
|
|
|
|
}
|
|
|
|
|
2019-09-28 19:22:47 +02:00
|
|
|
while(1) switch((ev = pollevent()).type)
|
2019-02-21 20:58:38 +01:00
|
|
|
{
|
|
|
|
/* Key press: handle modifiers or return an event */
|
|
|
|
case KEYEV_DOWN:
|
|
|
|
key = ev.key;
|
2019-07-18 21:20:34 +02:00
|
|
|
if(rep_key && key != rep_key) break;
|
2019-02-21 20:58:38 +01:00
|
|
|
|
|
|
|
/* Handle backlight on fx9860g */
|
|
|
|
#ifdef FX9860G
|
|
|
|
if(opt & GETKEY_BACKLIGHT && key == KEY_OPTN && shift)
|
|
|
|
{
|
|
|
|
t6k11_backlight(-1);
|
|
|
|
shift = 0;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2020-05-10 14:03:41 +02:00
|
|
|
/* Return to menu */
|
2019-02-21 20:58:38 +01:00
|
|
|
if(opt & GETKEY_MENU && key == KEY_MENU && !(alpha || shift))
|
|
|
|
{
|
2020-05-10 14:03:41 +02:00
|
|
|
gint_osmenu();
|
2019-02-21 20:58:38 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Update modifiers */
|
|
|
|
if(opt & GETKEY_MOD_SHIFT && key == KEY_SHIFT)
|
|
|
|
{
|
|
|
|
shift ^= 1;
|
|
|
|
rep_key = 0;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if(opt & GETKEY_MOD_ALPHA && key == KEY_ALPHA)
|
|
|
|
{
|
|
|
|
alpha ^= 1;
|
|
|
|
rep_key = 0;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return current event */
|
2019-09-28 19:22:47 +02:00
|
|
|
rep_key = key;
|
2019-02-21 20:58:38 +01:00
|
|
|
rep_count = 0;
|
2019-09-28 19:22:47 +02:00
|
|
|
rep_time = ev.time;
|
2019-02-21 20:58:38 +01:00
|
|
|
|
|
|
|
ev.mod = 1;
|
|
|
|
ev.shift = shift;
|
|
|
|
ev.alpha = alpha;
|
|
|
|
return ev;
|
|
|
|
|
2019-09-28 19:22:47 +02:00
|
|
|
/* If nothing happens, stop or wait for a repeat to occur */
|
|
|
|
case KEYEV_NONE:
|
|
|
|
/* Timeout has expired, return KEYEV_NONE */
|
|
|
|
if(timeout && *timeout) return ev;
|
2019-07-17 00:23:21 +02:00
|
|
|
|
2019-09-28 19:22:47 +02:00
|
|
|
/* Check that the last pressed key can be repeated */
|
2019-07-17 00:23:21 +02:00
|
|
|
int arrow = (rep_key == KEY_LEFT || rep_key == KEY_RIGHT ||
|
2019-09-28 19:22:47 +02:00
|
|
|
rep_key == KEY_UP || rep_key == KEY_DOWN);
|
2019-07-17 00:23:21 +02:00
|
|
|
|
2019-09-28 19:22:47 +02:00
|
|
|
if(!rep_key || !(
|
|
|
|
(opt & GETKEY_REP_ALL) ||
|
|
|
|
(opt & GETKEY_REP_ARROWS && arrow)
|
|
|
|
)) break;
|
2019-02-21 20:58:38 +01:00
|
|
|
|
|
|
|
/* If the key is key pressed long enough, create a new event */
|
2019-09-28 19:22:47 +02:00
|
|
|
int duration = (int16_t)(ev.time - rep_time);
|
|
|
|
|
2019-07-18 01:29:12 +02:00
|
|
|
int target = (rep_count) ? rep_next : rep_first;
|
2019-09-28 19:22:47 +02:00
|
|
|
if(duration < target) break;
|
2019-07-18 01:29:12 +02:00
|
|
|
|
2019-09-28 19:22:47 +02:00
|
|
|
rep_time += target;
|
2019-07-18 01:29:12 +02:00
|
|
|
rep_count++;
|
2019-02-21 20:58:38 +01:00
|
|
|
|
|
|
|
ev.mod = 1;
|
|
|
|
ev.shift = shift;
|
|
|
|
ev.alpha = alpha;
|
2019-09-28 19:22:47 +02:00
|
|
|
ev.type = KEYEV_HOLD;
|
|
|
|
ev.key = rep_key;
|
2019-02-21 20:58:38 +01:00
|
|
|
return ev;
|
|
|
|
|
|
|
|
/* Reset repeating information if the repeated key is released */
|
|
|
|
case KEYEV_UP:
|
|
|
|
if(ev.key != rep_key) break;
|
|
|
|
|
2019-09-28 19:22:47 +02:00
|
|
|
rep_key = 0;
|
2019-02-21 20:58:38 +01:00
|
|
|
rep_count = 0;
|
2019-09-28 19:22:47 +02:00
|
|
|
rep_time = 0;
|
2019-02-21 20:58:38 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* getkey_repeat() - set repeat delays for getkey() */
|
|
|
|
void getkey_repeat(int first, int next)
|
|
|
|
{
|
2019-07-17 00:23:21 +02:00
|
|
|
rep_first = (first * KEYBOARD_SCAN_FREQUENCY) / 1000;
|
|
|
|
rep_next = (next * KEYBOARD_SCAN_FREQUENCY) / 1000;
|
2019-02-21 20:58:38 +01:00
|
|
|
}
|