2016-07-25 09:04:22 +02:00
|
|
|
#include <internals/keyboard.h>
|
2017-03-26 18:38:32 +02:00
|
|
|
#include <internals/timer.h>
|
2016-07-06 11:28:51 +02:00
|
|
|
#include <keyboard.h>
|
2016-11-05 22:00:23 +01:00
|
|
|
#include <events.h>
|
2017-01-20 21:11:00 +01:00
|
|
|
#include <screen.h>
|
2016-07-06 11:28:51 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
getkey()
|
|
|
|
Blocking function with auto-repeat and SHIFT modifying functionalities.
|
|
|
|
Roughly reproduces the behavior of the system's GetKey().
|
|
|
|
*/
|
|
|
|
int getkey(void)
|
|
|
|
{
|
|
|
|
return getkey_opt(
|
2017-03-26 18:38:32 +02:00
|
|
|
getkey_shift_modifier |
|
|
|
|
getkey_alpha_modifier |
|
|
|
|
getkey_manage_backlight |
|
|
|
|
getkey_repeat_arrow_keys,
|
|
|
|
|
2016-07-06 11:28:51 +02:00
|
|
|
0
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
getkey_opt()
|
2016-11-05 22:00:23 +01:00
|
|
|
Enhances getkey() with more general functionalities.
|
2017-03-26 18:38:32 +02:00
|
|
|
If delay_ms is non-zero and positive, getkey_opt() will return
|
|
|
|
KEY_NOEVENT if no event occurs before delay_ms.
|
2016-07-06 11:28:51 +02:00
|
|
|
*/
|
2017-03-26 18:38:32 +02:00
|
|
|
static void getkey_opt_wait(int *delay_ms)
|
2016-07-06 11:28:51 +02:00
|
|
|
{
|
2016-11-05 22:00:23 +01:00
|
|
|
while(!interrupt_flag) sleep();
|
|
|
|
interrupt_flag = 0;
|
2016-07-06 11:28:51 +02:00
|
|
|
|
2017-03-26 18:38:32 +02:00
|
|
|
if(*delay_ms > 0)
|
|
|
|
{
|
|
|
|
(*delay_ms) -= vtimer->ms_delay;
|
|
|
|
if(*delay_ms < 0) *delay_ms = 0;
|
|
|
|
}
|
2016-11-05 22:00:23 +01:00
|
|
|
}
|
2017-03-26 18:38:32 +02:00
|
|
|
int getkey_opt(getkey_option_t options, int delay_ms)
|
2016-11-05 22:00:23 +01:00
|
|
|
{
|
2017-02-25 23:19:35 +01:00
|
|
|
event_t event;
|
2017-03-26 18:38:32 +02:00
|
|
|
int modifier = 0, key;
|
|
|
|
key_type_t type;
|
2016-07-06 11:28:51 +02:00
|
|
|
|
2017-03-26 18:38:32 +02:00
|
|
|
if(delay_ms <= 0) delay_ms = -1;
|
|
|
|
|
|
|
|
while(delay_ms != 0) switch((event = pollevent()).type)
|
2016-07-06 11:28:51 +02:00
|
|
|
{
|
2017-03-26 18:38:32 +02:00
|
|
|
case event_none:
|
|
|
|
getkey_opt_wait(&delay_ms);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case event_key_press:
|
|
|
|
key = event.key;
|
|
|
|
|
|
|
|
if(options & getkey_manage_backlight && key == KEY_OPTN
|
|
|
|
&& (modifier & MOD_SHIFT))
|
|
|
|
{
|
|
|
|
screen_toggleBacklight();
|
|
|
|
modifier &= ~MOD_SHIFT;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if(options & getkey_shift_modifier && key == KEY_SHIFT)
|
|
|
|
{
|
|
|
|
modifier ^= MOD_SHIFT;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if(options & getkey_alpha_modifier && key == KEY_ALPHA)
|
2016-11-05 22:00:23 +01:00
|
|
|
{
|
2017-03-26 18:38:32 +02:00
|
|
|
modifier ^= MOD_ALPHA;
|
|
|
|
continue;
|
2016-07-06 11:28:51 +02:00
|
|
|
}
|
2017-03-26 18:38:32 +02:00
|
|
|
|
|
|
|
last_key = key;
|
|
|
|
last_repeats = 0;
|
|
|
|
last_time = 0;
|
|
|
|
return key | modifier;
|
|
|
|
|
|
|
|
case event_key_repeat:
|
|
|
|
key = event.key;
|
|
|
|
if(key != last_key) continue;
|
|
|
|
|
|
|
|
// Checking that this type of repetition is allowed.
|
|
|
|
type = key_type(key);
|
|
|
|
if(!(options & (type << 4))) break;
|
|
|
|
|
|
|
|
last_time += vtimer->ms_delay;
|
|
|
|
int cmp = last_repeats ? repeat_next : repeat_first;
|
|
|
|
|
|
|
|
if(last_time >= cmp)
|
|
|
|
{
|
|
|
|
last_repeats++;
|
|
|
|
last_time -= cmp;
|
|
|
|
return last_key;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case event_key_release:
|
|
|
|
if(event.key != last_key) break;
|
|
|
|
last_key = KEY_NONE;
|
|
|
|
last_repeats = 0;
|
|
|
|
last_time = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
2016-11-05 22:00:23 +01:00
|
|
|
}
|
2016-07-06 11:28:51 +02:00
|
|
|
|
2016-11-05 22:00:23 +01:00
|
|
|
last_key = KEY_NONE;
|
|
|
|
last_repeats = 0;
|
2017-03-26 18:38:32 +02:00
|
|
|
last_time = 0;
|
2016-11-05 22:00:23 +01:00
|
|
|
return KEY_NONE;
|
|
|
|
}
|