From ab90a480eb5233abc4d7122739c24656dd42cc94 Mon Sep 17 00:00:00 2001 From: Peter Mikkelsen Date: Fri, 16 Feb 2024 20:21:57 +0000 Subject: Add missing file --- event.c | 204 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 event.c diff --git a/event.c b/event.c new file mode 100644 index 0000000..878d41a --- /dev/null +++ b/event.c @@ -0,0 +1,204 @@ +#include +#include +#include +#include +#include +#include + +#include "guifs.h" + +GuiElement * +elementat(Point p) +{ + GuiElement *g = nil; + + rlock(&root->lock); + if(ptinrect(p, root->rect)) + g = root; + runlock(&root->lock); + + while(g){ + GuiElement *next = nil; + rlock(&g->lock); + for(int n = 0; n < g->nchildren && next == nil; n++){ + GuiElement *child = g->children[n]; + rlock(&child->lock); + if(ptinrect(p, child->rect)) /* TODO: does not account for floating elements (not a thing yet) */ + next = child; + runlock(&child->lock); + } + runlock(&g->lock); + if(next) + g = next; + else + break; + } + return g; +} + +typedef struct SendEvent SendEvent; +struct SendEvent { + Channel *chan; + char *event; +}; + +void +sendeventthread(void *arg) +{ + SendEvent *s = arg; + send(s->chan, &s->event); +} + +void +sendevent(GuiElement *g, Event event) +{ + SendEvent *s = emalloc(sizeof(SendEvent)); + s->chan = g->events; + + Event *e = emalloc(sizeof(Event)); + memcpy(e, &event, sizeof(Event)); + + switch(e->type){ + case Xmousedown: + s->event = smprint("mousedown %C\n", e->r); + break; + case Xmouseup: + s->event = smprint("mouseup %C\n", e->r); + break; + case Xmouseclick: + s->event = smprint("mouseclick %C\n", e->r); + break; + case Xmousescroll: + s->event = smprint("mousescroll %s\n", e->direction == Up ? "up" : "down"); + break; + case Xkeyboard: + s->event = smprint("key %C\n", e->r); + break; + default: + s->event = smprint("???\n"); + break; + } + + if(nbsend(s->chan, &s->event) == 0) + threadcreate(sendeventthread, s, 1024); +} + +int +mouseevent(Mouse m) +{ + GuiElement *g = elementat(mousexy); + + static int lastbuttons = 0; + static GuiElement *lastL = nil; + static GuiElement *lastM = nil; + static GuiElement *lastR = nil; + + int b = lastbuttons ^ m.buttons; + lastbuttons = m.buttons; + if(b&4 && m.buttons&4) + lastR = g; + if(b&2 && m.buttons&2) + lastM = g; + if(b&1 && m.buttons&1) + lastL = g; + + if(!g) + return 0; + + wlock(&g->lock); + if(!g->listening){ + wunlock(&g->lock); + return 0; + } + + b = g->buttons ^ m.buttons; + g->buttons = m.buttons; + + Event e; + if(b&16 && m.buttons&16){ + e.type = Xmousescroll; + e.direction = Down; + sendevent(g, e); + } + + if(b&8 && m.buttons&8){ + e.type = Xmousescroll; + e.direction = Up; + sendevent(g, e); + } + + if(b&4){ + e.type = (m.buttons&4) ? Xmousedown : Xmouseup; + e.r = 'R'; + sendevent(g, e); + if(e.type == Xmouseup){ + if(lastR == g){ + e.type = Xmouseclick; + sendevent(g, e); + } + lastR = nil; + } + } + + if(b&2){ + e.type = (m.buttons&2) ? Xmousedown : Xmouseup; + e.r = 'M'; + sendevent(g, e); + if(e.type == Xmouseup){ + if(lastM == g){ + e.type = Xmouseclick; + sendevent(g, e); + } + lastM = nil; + } + } + + if(b&1){ + e.type = (m.buttons&1) ? Xmousedown : Xmouseup; + e.r = 'L'; + sendevent(g, e); + if(e.type == Xmouseup){ + if(lastL == g){ + e.type = Xmouseclick; + sendevent(g, e); + } + lastL = nil; + } + } + + wunlock(&g->lock); + return 0; +} + +int +keyboardevent(Rune r) +{ + if(r == Kdel){ /* The user hit DEL */ + postnote(PNGROUP, getpid(), "interrupt"); + exits("interrupt"); + } + + GuiElement *g = elementat(mousexy); + if(!g) + return 0; + + wlock(&g->lock); + if(g->listening){ + Event e; + e.type = Xkeyboard; + e.r = r; + sendevent(g, e); + } + + if(g->type == Gtextbox){ + PropVal val = getprop(g, Ptext, 0); + long len = runestrlen(val.text); + Rune *text = emalloc(sizeof(Rune) * (len + 2)); + memcpy(text, val.text, sizeof(Rune) * len); + text[len] = r; + val.text = text; + setprop(g, Ptext, val, 0); + } + wunlock(&g->lock); + return 1; +} \ No newline at end of file -- cgit v1.2.3