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);
}