ref: 856542c51fbe7a4d55e292ad91714f58907d6869
dir: /libenter.c/
#include <u.h> #include <libc.h> #include <draw.h> #include <thread.h> #include <mouse.h> #include <keyboard.h> #include "genenter.h" typedef struct Enterdata Enterdata; struct Enterdata { Mousectl *mc; Keyboardctl *kc; Screen *scr; Alt a[3]; }; static int einitsave(Enterparams *p) { Enterdata *d = (Enterdata*)p->aux; if(d->scr){ if(p->b == nil) p->b = allocwindow(d->scr, p->r, Refbackup, DWhite); if(p->b == nil) d->scr = nil; } if(d->scr == nil && p->save == nil){ if(p->b == nil) p->b = screen; p->save = allocimage(display, p->r, p->b->chan, 0, DNofill); if(p->save == nil) return 1; draw(p->save, p->r, p->b, nil, p->r.min); } return 0; } static int egetevent(Enterparams *p) { Enterdata *d = (Enterdata*)p->aux; switch(alt(d->a)){ case 0: return Gkeyboard; case 1: return Gmouse; } return -1; } static void eloopcleanup(Enterparams *p) { if(p->b != screen){ freeimage(p->b); p->b = nil; } else { draw(p->b, p->save->r, p->save, nil, p->save->r.min); freeimage(p->save); p->save = nil; } } static void ecleanup(Enterparams *p) { replclipr(screen, 0, p->sc); } int enter(char *ask, char *buf, int len, Mousectl *mc, Keyboardctl *kc, Screen *scr) { Enterparams p; Enterdata d; int n; p.sc = screen->clipr; replclipr(screen, 0, screen->r); n = 0; if(kc){ while(nbrecv(kc->c, nil) == 1) ; d.a[n].op = CHANRCV; d.a[n].c = kc->c; d.a[n].v = &p.k; n++; } if(mc){ p.o = mc->xy; d.a[n].op = CHANRCV; d.a[n].c = mc->c; d.a[n].v = &p.m; n++; } d.a[n].op = CHANEND; d.a[n].c = nil; d.a[n].v = nil; d.mc = mc; d.kc = kc; d.scr = scr; p.aux = &d; p.initsave = einitsave; p.getevent = egetevent; p.loopcleanup = eloopcleanup; p.cleanup = ecleanup; return _genenter(ask, buf, len, &p); }