From 8dbdd32adb011b278b099c7c1c38ecc32872c0ca Mon Sep 17 00:00:00 2001 From: lephe Date: Tue, 16 Jul 2019 18:23:21 -0400 Subject: [PATCH] keyboard: finalize getkey() --- include/gint/keyboard.h | 24 ++++++++++++------------ src/keysc/getkey.c | 33 ++++++++++++++++++--------------- src/keysc/keysc.c | 11 ++++++++--- 3 files changed, 38 insertions(+), 30 deletions(-) diff --git a/include/gint/keyboard.h b/include/gint/keyboard.h index efc3096..2addd19 100644 --- a/include/gint/keyboard.h +++ b/include/gint/keyboard.h @@ -93,12 +93,12 @@ enum /* pollevent() - poll the next keyboard event This function returns the next yet-unpolled event from the keyboard buffer. If no event is available, it returns a dummy event with type = KEYEV_NONE. - This event has always mod = 0, shift = 0, alpha = 0. */ + This function always returns events with mod=0. */ key_event_t pollevent(void); /* waitevent() - wait for the next keyboard event This function works as pollevent() but waits if no event is available. When - timeout = NULL, it waits indefinitely. Otherwise, it waits until *timeout + timeout=NULL, it waits indefinitely. Otherwise, it waits until *timeout becomes non-zero. It is particularly suitable to set *timeout to 1 using a timer with [timer_timeout] as callback. See . */ key_event_t waitevent(volatile int *timeout); @@ -123,18 +123,18 @@ key_event_t getkey(void); /* The following are the option bits for getkey_opt(). */ enum { /* Enable modifiers keys */ - GETKEY_MOD_SHIFT = 0x01, - GETKEY_MOD_ALPHA = 0x02, + GETKEY_MOD_SHIFT = 0x01, + GETKEY_MOD_ALPHA = 0x02, /* SHIFT + OPTN toggles backlight (requires GETKEY_MOD_SHIFT) */ - GETKEY_BACKLIGHT = 0x04, + GETKEY_BACKLIGHT = 0x04, /* MENU triggers a task switch and displays the main menu */ - GETKEY_MENU = 0x08, + GETKEY_MENU = 0x08, /* Repeat arrow keys, or even all keys */ - GETKEY_REP_ARROWS = 0x10, - GETKEY_REP_ALL = 0x20, + GETKEY_REP_ARROWS = 0x10, + GETKEY_REP_ALL = 0x20, /* Default settings of getkey() */ - GETKEY_DEFAULT = 0x1f, + GETKEY_DEFAULT = 0x1f, }; /* getkey_opt() - enhanced getkey() @@ -148,7 +148,7 @@ enum { pointer [timeout]. If it's NULL, getkey_opt() waits indefinitely. Otherwise, it waits until *timeout becomes non-zero. It's up to you to change the value whenever you want to interrupt the call; using a timer with - [timer_timeout] as callback is suitable. + [timer_timeout] as callback is suitable. See . @options An or-combination of values from the GETKEY_* enumeration @timeout Optional pointer to a timeout value @@ -166,8 +166,8 @@ key_event_t getkey_opt(int options, volatile int *timeout); rounded to the closest feasible delays to ensure that repetitions are perfectly regular, rather than approximating the requested frequency. - The system default is (625 ms, 25 ms). With the 128 Hz setting, this default - will be approximated at (625 ms, 23.4375 ms). + The system default is (500 ms, 125 ms). With the 128 Hz setting, this + default is reached exactly without approximation. @first Delay between key press and first repeat (no more than one hour) @next Delay between subsequent repeats (no more than one hour) */ diff --git a/src/keysc/getkey.c b/src/keysc/getkey.c index c945ed2..73d0ec9 100644 --- a/src/keysc/getkey.c +++ b/src/keysc/getkey.c @@ -9,13 +9,10 @@ #include #endif -/* Atom for counting time in getkey() is 32768 Hz, 1ull << ATOM is a second */ -#define ATOM 15 - -/* Delay between a key press and the first repeat, in 1/32768 seconds */ -static uint64_t rep_first; -/* Delay between subsequent repeats, in 1/32768 seconds */ -static uint64_t rep_next; +/* Delay between a key press and the first repeat, in scan intervals */ +static int rep_first = 64; +/* Delay between subsequent repeats, in scan intervals */ +static int rep_next = 16; /* getkey() - wait for a pressed key */ key_event_t getkey(void) @@ -30,11 +27,11 @@ key_event_t getkey_opt(int opt, volatile int *timeout) int shift = 0, alpha = 0, key = 0; /* Last pressed key (only this key may be repeated) */ - int rep_key = 0; + static int rep_key = 0; /* Number of repeats already emitted */ - int rep_count = 0; - /* Time elapsed since last repeat emission (in atoms) */ - uint64_t rep_time = 0; + static int rep_count = 0; + /* Scan intervals elapsed since last repeat */ + static int rep_time = 0; while(1) switch((ev = waitevent(timeout)).type) { @@ -89,10 +86,16 @@ key_event_t getkey_opt(int opt, volatile int *timeout) /* Return new events when a key is held (maybe) */ case KEYEV_HOLD: if(ev.key != rep_key) break; - rep_time += (1ull << ATOM) / KEYBOARD_SCAN_FREQUENCY; + + /* Check that this key can be repeated */ + int arrow = (rep_key == KEY_LEFT || rep_key == KEY_RIGHT || + rep_key == KEY_UP || rep_key == KEY_DOWN); + + if(!(opt & GETKEY_REP_ALL) && !(opt & GETKEY_REP_ARROWS && + arrow)) break; /* If the key is key pressed long enough, create a new event */ - if(rep_time < (rep_count ? rep_next : rep_first)) break; + if(++rep_time < (rep_count ? rep_next : rep_first)) break; ev.mod = 1; ev.shift = shift; @@ -113,6 +116,6 @@ key_event_t getkey_opt(int opt, volatile int *timeout) /* getkey_repeat() - set repeat delays for getkey() */ void getkey_repeat(int first, int next) { - rep_first = ((uint64_t)first << ATOM) / 1000; - rep_next = ((uint64_t)next << ATOM) / 1000; + rep_first = (first * KEYBOARD_SCAN_FREQUENCY) / 1000; + rep_next = (next * KEYBOARD_SCAN_FREQUENCY) / 1000; } diff --git a/src/keysc/keysc.c b/src/keysc/keysc.c index 63bd3f2..2965ea7 100644 --- a/src/keysc/keysc.c +++ b/src/keysc/keysc.c @@ -148,12 +148,14 @@ key_event_t waitevent(volatile int *timeout) { key_event_t none = { .type = KEYEV_NONE }; - do { + while(1) + { key_event_t ev = pollevent(); if(ev.type != KEYEV_NONE) return ev; - sleep(); - } while(!(timeout && *timeout)); + if(timeout && *timeout) break; + sleep(); + } return none; } @@ -181,6 +183,9 @@ static void init(void) int delay = 32768 / KEYBOARD_SCAN_FREQUENCY; if(!delay) delay = 1; + /* Set the default repeat times (milliseconds) */ + getkey_repeat(500, 125); + timer_setup(tid, delay, 0, callback, NULL); timer_start(tid);