gint/src/keyboard/getkey.c

139 lines
2.4 KiB
C

#include <internals/keyboard.h>
#include <keyboard.h>
#include <events.h>
#include <screen.h>
/*
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(
Getkey_ShiftModifier |
Getkey_AlphaModifier |
Getkey_ManageBacklight |
Getkey_RepeatArrowKeys,
0
);
}
/*
getkey_opt()
Enhances getkey() with more general functionalities.
If max_cycles is non-zero and positive, getkey_opt() will return
KEY_NOEVENT if no event occurs during max_cycle analysis.
*/
void getkey_opt_wait(int *cycles)
{
while(!interrupt_flag) sleep();
interrupt_flag = 0;
if(*cycles > 0) (*cycles)--;
}
int getkey_opt(enum GetkeyOpt options, int cycles)
{
struct Event event;
int modifier = 0;
static int event_ref = 0;
if(cycles <= 0) cycles = -1;
while(cycles != 0)
{
event = pollevent();
switch(event.type)
{
case ET_None:
if(last_key == KEY_NONE)
{
getkey_opt_wait(&cycles);
continue;
}
// Handling repetitions.
enum KeyType type = keytype(last_key);
if(!(options & (type << 4))) break;
if(event_ref <= 0)
{
getkey_opt_wait(&cycles);
event_ref++;
continue;
}
last_events++;
event_ref--;
if(last_events >= (last_repeats ? repeat_next :
repeat_first))
{
last_repeats++;
last_events = 0;
return last_key;
}
break;
case ET_KeyPress:
;
int key = event.key;
if(options & Getkey_ManageBacklight && key == KEY_OPTN
&& modifier & MOD_SHIFT)
{
screen_toggleBacklight();
modifier &= ~MOD_SHIFT;
continue;
}
if(options & Getkey_ShiftModifier && key == KEY_SHIFT)
{
modifier ^= MOD_SHIFT;
continue;
}
if(options & Getkey_AlphaModifier && key == KEY_ALPHA)
{
modifier ^= MOD_ALPHA;
continue;
}
last_key = key;
last_repeats = 0;
last_events = 0;
event_ref = 0;
return key | modifier;
case ET_KeyRel:
if(event.key != last_key) break;
last_key = KEY_NONE;
last_repeats = 0;
last_events = 0;
event_ref = 0;
break;
default:
break;
}
}
last_key = KEY_NONE;
last_repeats = 0;
last_events = 0;
event_ref = 0;
return KEY_NONE;
}
/*
int getkey_opt(enum GetkeyOpt options, int max_cycles)
{
while(max_cycles != 0)
{
// Handling "new key" events.
// Handling key repetitions.
}
// When no key was pressed during the given delay...
return KEY_NOEVENT;
}
*/