108 lines
1.7 KiB
C
108 lines
1.7 KiB
C
#include "wayland_state.h"
|
|
|
|
#include <limits.h>
|
|
#include <string.h>
|
|
|
|
enum {
|
|
Downforward = 1,
|
|
Downeaten = 2,
|
|
};
|
|
|
|
void
|
|
wlstateinit(Wlstate *s)
|
|
{
|
|
memset(s, 0, sizeof *s);
|
|
}
|
|
|
|
void
|
|
wlstatecancelrepeat(Wlstate *s)
|
|
{
|
|
s->repeating = 0;
|
|
s->repeatkey = 0;
|
|
s->repeatat = 0;
|
|
}
|
|
|
|
void
|
|
wlstateclear(Wlstate *s)
|
|
{
|
|
memset(s->down, 0, sizeof s->down);
|
|
wlstatecancelrepeat(s);
|
|
}
|
|
|
|
void
|
|
wlstaterepeatinfo(Wlstate *s, int rate, int delay)
|
|
{
|
|
/* Settings changes end the old schedule; a later press starts a new one. */
|
|
wlstatecancelrepeat(s);
|
|
s->rate = rate > 0 ? rate : 0;
|
|
s->delay = delay > 0 ? delay : 0;
|
|
}
|
|
|
|
int
|
|
wlstatepress(Wlstate *s, uint32_t key, int eaten, int repeatable,
|
|
uint64_t now)
|
|
{
|
|
uint64_t delay;
|
|
|
|
if(key >= Wlkeymax)
|
|
return 0;
|
|
s->down[key] = eaten ? Downeaten : Downforward;
|
|
wlstatecancelrepeat(s);
|
|
if(eaten && repeatable && s->rate > 0){
|
|
delay = s->delay;
|
|
if(UINT64_MAX - now < delay)
|
|
s->repeatat = UINT64_MAX;
|
|
else
|
|
s->repeatat = now + delay;
|
|
s->repeatkey = key;
|
|
s->repeating = 1;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int
|
|
wlstaterelease(Wlstate *s, uint32_t key)
|
|
{
|
|
int forward;
|
|
|
|
if(key >= Wlkeymax)
|
|
return 1;
|
|
forward = s->down[key] != Downeaten;
|
|
s->down[key] = 0;
|
|
if(s->repeating && s->repeatkey == key)
|
|
wlstatecancelrepeat(s);
|
|
return forward;
|
|
}
|
|
|
|
int
|
|
wlstatetimeout(Wlstate *s, uint64_t now)
|
|
{
|
|
uint64_t d;
|
|
|
|
if(!s->repeating)
|
|
return -1;
|
|
if(now >= s->repeatat)
|
|
return 0;
|
|
d = s->repeatat - now;
|
|
return d > INT_MAX ? INT_MAX : (int)d;
|
|
}
|
|
|
|
int
|
|
wlstaterepeat(Wlstate *s, uint64_t now, uint32_t *key)
|
|
{
|
|
uint64_t step;
|
|
|
|
if(!s->repeating || now < s->repeatat)
|
|
return 0;
|
|
if(key != 0)
|
|
*key = s->repeatkey;
|
|
step = 1000 / s->rate;
|
|
if(step == 0)
|
|
step = 1;
|
|
if(UINT64_MAX - now < step)
|
|
s->repeatat = UINT64_MAX;
|
|
else
|
|
s->repeatat = now + step;
|
|
return 1;
|
|
}
|