#include "wayland_state.h" #include #include 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; }