Files
strans/wayland_state.c

108 lines
1.7 KiB
C

#include "dat.h"
#include "fn.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, u32int key, int eaten, int repeatable, uvlong now)
{
uvlong delay;
if(key >= Wlkeymax)
return 0;
s->down[key] = eaten ? Downeaten : Downforward;
wlstatecancelrepeat(s);
if(eaten && repeatable && s->rate > 0){
delay = s->delay;
if(~(uvlong)0 - now < delay)
s->repeatat = ~(uvlong)0;
else
s->repeatat = now + delay;
s->repeatkey = key;
s->repeating = 1;
}
return 1;
}
int
wlstaterelease(Wlstate *s, u32int 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, uvlong now)
{
uvlong 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, uvlong now, u32int *key)
{
uvlong 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(~(uvlong)0 - now < step)
s->repeatat = ~(uvlong)0;
else
s->repeatat = now + step;
return 1;
}