ref: c70b508504537491dbee49e5c5e1a5938998ac83
parent: 627806e4de1f01a670ab6a3ebb960609cbda7a06
author: sirjofri <sirjofri@sirjofri.de>
date: Mon Jul 22 11:54:21 EDT 2024
adds same-code libenter libeenter and genenter
--- a/libeenter.c
+++ b/libeenter.c
@@ -3,369 +3,88 @@
#include <draw.h>
#include <event.h>
#include <keyboard.h>
+#include "genenter.h"
-static void
-sorttick(int *t1, int *t2)
+static int
+eeinitsave(Enterparams *p)
{
- int i;
- if(*t1 <= *t2)
- return;
- i = *t1;
- *t1 = *t2;
- *t2 = i;
-}
-
-static Point
-drawstring(Image *b, char *buf, Point p, int s, int e, Image *bg, int h)
-{
- sorttick(&s, &e);
- p = stringn(b, p, display->black, ZP, font, buf, utfnlen(buf, s));
- if(s == e){
- draw(b, Rect(p.x-1, p.y, p.x+2, p.y+3), display->black, nil, ZP);
- draw(b, Rect(p.x, p.y, p.x+1, p.y+h), display->black, nil, ZP);
- draw(b, Rect(p.x-1, p.y+h-3, p.x+2, p.y+h), display->black, nil, ZP);
- } else {
- p = stringnbg(b, p, display->black, ZP, font, buf+s, utfnlen(buf+s, e-s), bg, ZP);
+ if(p->save)
+ return 0;
+ p->save = allocimage(display, p->r, p->b->chan, 0, DNofill);
+ if(p->save == nil){
+ return 1;
}
- p = string(b, p, display->black, ZP, font, buf+e);
- return p;
+ draw(p->save, p->r, p->b, nil, p->r.min);
+ return 0;
}
-static void
-enterselection(char *buf, int len, int s, int e, int *sp, int *ep)
-{
- int l, i;
- Rune k;
- sorttick(&s, &e);
- *sp = *ep = -1;
- for(i = 0; i < len; i += l){
- l = chartorune(&k, buf+i);
- if(*sp >= 0 && i >= e){
- *ep = i;
- break;
- }
- if(*sp < 0 && i >= s)
- *sp = i;
- }
-}
-
static int
-delsubstring(char *buf, int len, int s, int e, int *nlen)
+eegetevent(Enterparams *p)
{
- int l, i, sp, ep;
- Rune k;
- if(s == e)
- return s;
- if (s < 0)
- s = 0;
- enterselection(buf, len, s, e, &sp, &ep);
- memmove(buf+sp, buf+ep, len - ep);
- buf[len-ep+sp] = 0;
- if (nlen)
- *nlen = sp+len-ep;
- return sp;
-}
+ Event ev;
+ int i = Ekeyboard;
-static int
-entersnarf(char *buf, int len, int s, int e, int *nlen)
-{
- int fd, sp, ep;
- fd = open("/dev/snarf", OWRITE|OTRUNC);
- if(fd < 0){
- fprint(2, "error: %r\n");
- return s;
+ if(p->aux)
+ i |= Emouse;
+
+ replclipr(p->b, 0, p->sc);
+ i = eread(i, &ev);
+
+ /* screen might have been resized */
+ if(p->b != screen || !eqrect(screen->clipr, p->sc)){
+ freeimage(p->save);
+ p->save = nil;
}
- enterselection(buf, len, s, e, &sp, &ep);
- if(sp < 0 || ep < 0){
- close(fd);
- return sp < 0 ? ep : sp;
+ p->b = screen;
+ p->sc = p->b->clipr;
+ replclipr(p->b, 0, p->b->r);
+
+ if(i == Emouse){
+ p->m = ev.mouse;
+ return Gmouse;
}
- pwrite(fd, &buf[sp], ep-sp, 0);
- close(fd);
- return delsubstring(buf, len, s, e, nlen);
+ if(i == Ekeyboard){
+ p->k = ev.kbdc;
+ return Gkeyboard;
+ }
+ return -1;
}
static void
-enterpaste(char *buf, int len, int max, int s, int e, int *nlen, int *ns, int *ne)
+eeloopcleanup(Enterparams *p)
{
- char *str;
- int fd, sp, ep, n, newlen;
-
- fd = open("/dev/snarf", OREAD);
- if(fd < 0){
- fprint(2, "error: %r\n");
- return;
+ if(p->save){
+ draw(p->b, p->save->r, p->save, nil, p->save->r.min);
+ freeimage(p->save);
+ p->save = nil;
}
- str = mallocz(max*sizeof(char), 1);
- n = pread(fd, str, max-1, 0);
- str[n] = 0;
- close(fd);
+}
- newlen = len;
- enterselection(buf, len, s, e, &sp, &ep);
- s = entersnarf(buf, len, s, e, &newlen);
-
- memmove(buf+n+s, buf+s, newlen-s);
- memcpy(buf+s, str, n);
-
- free(str);
- if (nlen)
- *nlen = newlen+n;
- if (ns)
- *ns = s;
- if (ne)
- *ne = s+n;
+static void
+eecleanup(Enterparams *p)
+{
+ replclipr(p->b, 0, p->sc);
}
int
eenter(char *ask, char *buf, int len, Mouse *m)
{
- int done, down, tick, n, h, w, l, i;
- int tick2, mb, ti;
- Image *b, *save, *backcol, *bordcol;
- Point p, o, t;
- Rectangle r, sc;
- Event ev;
- Rune k;
+ Enterparams p;
- mb = 0;
- o = screen->r.min;
- backcol = allocimagemix(display, DPurpleblue, DWhite);
- bordcol = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPurpleblue);
- if(backcol == nil || bordcol == nil)
- return -1;
-
while(ecankbd())
ekbd();
- if(m) o = m->xy;
+ if(m)
+ p.o = m->xy;
- if(buf && len > 0)
- n = strlen(buf);
- else {
- buf = nil;
- len = 0;
- n = 0;
- }
+ p.b = screen;
+ p.sc = p.b->clipr;
+ replclipr(p.b, 0, p.b->r);
- k = -1;
- tick2 = tick = n;
- save = nil;
- done = down = 0;
-
- p = stringsize(font, " ");
- h = p.y;
- w = p.x;
-
- b = screen;
- sc = b->clipr;
- replclipr(b, 0, b->r);
-
- while(!done){
- p = stringsize(font, buf ? buf : "");
- if(ask && ask[0]){
- if(buf) p.x += w;
- p.x += stringwidth(font, ask);
- }
- r = rectaddpt(insetrect(Rpt(ZP, p), -4), o);
- p.x = 0;
- r = rectsubpt(r, p);
-
- p = ZP;
- if(r.min.x < screen->r.min.x)
- p.x = screen->r.min.x - r.min.x;
- if(r.min.y < screen->r.min.y)
- p.y = screen->r.min.y - r.min.y;
- r = rectaddpt(r, p);
- p = ZP;
- if(r.max.x > screen->r.max.x)
- p.x = r.max.x - screen->r.max.x;
- if(r.max.y > screen->r.max.y)
- p.y = r.max.y - screen->r.max.y;
- r = rectsubpt(r, p);
-
- r = insetrect(r, -2);
- if(save == nil){
- save = allocimage(display, r, b->chan, 0, DNofill);
- if(save == nil){
- n = -1;
- break;
- }
- draw(save, r, b, nil, r.min);
- }
- draw(b, r, backcol, nil, ZP);
- border(b, r, 2, bordcol, ZP);
- p = addpt(r.min, Pt(6, 6));
- if(ask && ask[0]){
- p = string(b, p, bordcol, ZP, font, ask);
- if(buf) p.x += w;
- }
- if(buf){
- t = p;
- p = drawstring(b, buf, p, tick, tick2, bordcol, h);
- }
- flushimage(display, 1);
-
-nodraw:
- i = Ekeyboard;
- if(m != nil)
- i |= Emouse;
-
- replclipr(b, 0, sc);
- i = eread(i, &ev);
-
- /* screen might have been resized */
- if(b != screen || !eqrect(screen->clipr, sc)){
- freeimage(save);
- save = nil;
- }
- b = screen;
- sc = b->clipr;
- replclipr(b, 0, b->r);
-
- switch(i){
- default:
- done = 1;
- n = -1;
- break;
- case Ekeyboard:
- k = ev.kbdc;
- if(buf == nil || k == Keof || k == '\n'){
- done = 1;
- break;
- }
- if(k == Knack || k == Kesc){
- done = !n;
- n = tick2 = tick = 0;
- buf[n] = 0;
- break;
- }
- if(k == Ksoh || k == Khome){
- tick2 = tick = 0;
- continue;
- }
- if(k == Kenq || k == Kend){
- tick2 = tick = n;
- continue;
- }
- if(k == Kright){
- if(tick2 < n)
- tick2 = tick += chartorune(&k, buf+tick);
- continue;
- }
- if(k == Kleft){
- for(i = 0; i < n; i += l){
- l = chartorune(&k, buf+i);
- if(i+l >= tick){
- tick2 = tick = i;
- break;
- }
- }
- continue;
- }
- if(k == Ketb){
- l = tick;
- while(tick > 0){
- tick--;
- if(tick == 0 ||
- strchr(" !\"#$%&'()*+,-./:;<=>?@`[\\]^{|}~", buf[tick-1]))
- break;
- }
- memmove(buf+tick, buf+l, n-l);
- buf[n -= l-tick] = 0;
- break;
- }
- if(k == Kbs){
- if(tick <= 0 && tick2 <= 0)
- continue;
- if (tick == tick2)
- for(i = 0; i < n; i += l){
- l = chartorune(&k, buf+i);
- if(i+l >= tick){
- memmove(buf+i, buf+i+l, n - (i+l));
- buf[n -= l] = 0;
- tick2 = tick -= l;
- break;
- }
- }
- else
- tick = tick2 = delsubstring(buf, n, tick-1, tick2, &n);
- break;
- }
- if(k < 0x20 || k == Kdel || (k & 0xFF00) == KF || (k & 0xFF00) == Spec)
- continue;
- if((len-n) <= (l = runelen(k)))
- continue;
- tick = delsubstring(buf, n, tick, tick2, &n);
- memmove(buf+tick+l, buf+tick, n - tick);
- runetochar(buf+tick, &k);
- buf[n += l] = 0;
- tick2 = tick += l;
- break;
- case Emouse:
- *m = ev.mouse;
- if(mb&1 && !m->buttons&1) {
- sorttick(&tick, &tick2);
- mb = m->buttons;
- }
- if(m->buttons&1 && mb&6){
- if (m->buttons != mb)
- goto Mchecks;
- continue;
- }
- if(m->buttons&1 && mb&6){
- continue;
- }
- if(!ptinrect(m->xy, r)){
- down = 0;
- goto nodraw;
- }
- if(m->buttons&1){
- down = 1;
- if(buf && m->xy.x >= (t.x - w)){
- down = 0;
- for(i = 0; i < n; i += l){
- l = chartorune(&k, buf+i);
- t.x += stringnwidth(font, buf+i, 1);
- if(t.x > m->xy.x)
- break;
- }
- if(mb & 1){
- tick2 = i;
- }else
- tick = tick2 = i;
- }
- if(!((m->buttons&2) || (m->buttons&4))){
- mb = m->buttons;
- continue;
- }
- }
-Mchecks:
- if(!(mb&2) && (m->buttons&3) == 3){
- tick = tick2 = entersnarf(buf, n, tick, tick2, &n);
- mb = m->buttons;
- }
- if(!(mb&4) && (m->buttons&5) == 5){
- enterpaste(buf, n, len, tick, tick2, &n, &tick, &tick2);
- mb = m->buttons;
- }
-
- done = down;
- break;
- }
- if(save){
- draw(b, save->r, save, nil, save->r.min);
- freeimage(save);
- save = nil;
- }
- }
-
- replclipr(b, 0, sc);
-
- freeimage(backcol);
- freeimage(bordcol);
- flushimage(display, 1);
-
- return n;
+ p.aux = m;
+ p.initsave = eeinitsave;
+ p.getevent = eegetevent;
+ p.loopcleanup = eeloopcleanup;
+ p.cleanup = eecleanup;
+ return _genenter(ask, buf, len, &p);
}
-
--- a/libenter.c
+++ b/libenter.c
@@ -4,10 +4,114 @@
#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);
+}
+
+#ifdef COMMENT
+int
+enter(char *ask, char *buf, int len, Mousectl *mc, Keyboardctl *kc, Screen *scr)
+{
int done, down, tick, n, h, w, l, i;
Image *b, *save, *backcol, *bordcol;
Point p, o, t;
@@ -235,3 +339,4 @@
return n;
}
+#endif
--- /dev/null
+++ b/libgenenter.c
@@ -1,0 +1,340 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <keyboard.h>
+#include <mouse.h>
+#include "genenter.h"
+
+static void
+sorttick(int *t1, int *t2)
+{
+ int i;
+ if(*t1 <= *t2)
+ return;
+ i = *t1;
+ *t1 = *t2;
+ *t2 = i;
+}
+
+static Point
+drawstring(Image *b, char *buf, Point p, int s, int e, Image *bg, int h)
+{
+ sorttick(&s, &e);
+ p = stringn(b, p, display->black, ZP, font, buf, utfnlen(buf, s));
+ if(s == e){
+ draw(b, Rect(p.x-1, p.y, p.x+2, p.y+3), display->black, nil, ZP);
+ draw(b, Rect(p.x, p.y, p.x+1, p.y+h), display->black, nil, ZP);
+ draw(b, Rect(p.x-1, p.y+h-3, p.x+2, p.y+h), display->black, nil, ZP);
+ } else {
+ p = stringnbg(b, p, display->black, ZP, font, buf+s, utfnlen(buf+s, e-s), bg, ZP);
+ }
+ p = string(b, p, display->black, ZP, font, buf+e);
+ return p;
+}
+
+static void
+enterselection(char *buf, int len, int s, int e, int *sp, int *ep)
+{
+ int l, i;
+ Rune k;
+ sorttick(&s, &e);
+ *sp = *ep = -1;
+ for(i = 0; i < len; i += l){
+ l = chartorune(&k, buf+i);
+ if(*sp >= 0 && i >= e){
+ *ep = i;
+ break;
+ }
+ if(*sp < 0 && i >= s)
+ *sp = i;
+ }
+}
+
+static int
+delsubstring(char *buf, int len, int s, int e, int *nlen)
+{
+ int sp, ep;
+ if(s == e)
+ return s;
+ if (s < 0)
+ s = 0;
+ enterselection(buf, len, s, e, &sp, &ep);
+ memmove(buf+sp, buf+ep, len - ep);
+ buf[len-ep+sp] = 0;
+ if (nlen)
+ *nlen = sp+len-ep;
+ return sp;
+}
+
+static int
+entersnarf(char *buf, int len, int s, int e, int *nlen)
+{
+ int fd, sp, ep;
+ fd = open("/dev/snarf", OWRITE|OTRUNC);
+ if(fd < 0){
+ fprint(2, "error: %r\n");
+ return s;
+ }
+ enterselection(buf, len, s, e, &sp, &ep);
+ if(sp < 0 || ep < 0){
+ close(fd);
+ return sp < 0 ? ep : sp;
+ }
+ pwrite(fd, &buf[sp], ep-sp, 0);
+ close(fd);
+ return delsubstring(buf, len, s, e, nlen);
+}
+
+static void
+enterpaste(char *buf, int len, int max, int s, int e, int *nlen, int *ns, int *ne)
+{
+ char *str;
+ int fd, sp, ep, n, newlen;
+
+ fd = open("/dev/snarf", OREAD);
+ if(fd < 0){
+ fprint(2, "error: %r\n");
+ return;
+ }
+ str = mallocz(max*sizeof(char), 1);
+ n = pread(fd, str, max-1, 0);
+ str[n] = 0;
+ close(fd);
+
+ newlen = len;
+ enterselection(buf, len, s, e, &sp, &ep);
+ s = entersnarf(buf, len, s, e, &newlen);
+
+ memmove(buf+n+s, buf+s, newlen-s);
+ memcpy(buf+s, str, n);
+
+ free(str);
+ if (nlen)
+ *nlen = newlen+n;
+ if (ns)
+ *ns = s;
+ if (ne)
+ *ne = s+n;
+}
+
+int
+_genenter(char *ask, char *buf, int len, Enterparams *ps)
+{
+ int done, down, tick, n, h, w, l, i;
+ int tick2, mb;
+ Image *backcol, *bordcol;
+ Point p, t;
+ Rune k;
+ Mouse m;
+
+ mb = 0;
+ if(!ptinrect(ps->o, screen->r))
+ ps->o = screen->r.min;
+ backcol = allocimagemix(display, DPurpleblue, DWhite);
+ bordcol = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPurpleblue);
+ if(backcol == nil || bordcol == nil)
+ return -1;
+
+ if(buf && len > 0)
+ n = strlen(buf);
+ else {
+ buf = nil;
+ len = 0;
+ n = 0;
+ }
+
+ ps->k = -1;
+ tick2 = tick = n;
+ ps->save = nil;
+ done = down = 0;
+
+ p = stringsize(font, " ");
+ h = p.y;
+ w = p.x;
+
+ while(!done){
+ p = stringsize(font, buf ? buf : "");
+ if(ask && ask[0]){
+ if(buf) p.x += w;
+ p.x += stringwidth(font, ask);
+ }
+ ps->r = rectaddpt(insetrect(Rpt(ZP, p), -4), ps->o);
+ p.x = 0;
+ ps->r = rectsubpt(ps->r, p);
+
+ p = ZP;
+ if(ps->r.min.x < screen->r.min.x)
+ p.x = screen->r.min.x - ps->r.min.x;
+ if(ps->r.min.y < screen->r.min.y)
+ p.y = screen->r.min.y - ps->r.min.y;
+ ps->r = rectaddpt(ps->r, p);
+ p = ZP;
+ if(ps->r.max.x > screen->r.max.x)
+ p.x = ps->r.max.x - screen->r.max.x;
+ if(ps->r.max.y > screen->r.max.y)
+ p.y = ps->r.max.y - screen->r.max.y;
+ ps->r = rectsubpt(ps->r, p);
+
+ ps->r = insetrect(ps->r, -2);
+ if(ps->initsave)
+ if(ps->initsave(ps)){
+ n = -1;
+ break;
+ }
+ draw(ps->b, ps->r, backcol, nil, ZP);
+ border(ps->b, ps->r, 2, bordcol, ZP);
+ p = addpt(ps->r.min, Pt(6, 6));
+ if(ask && ask[0]){
+ p = string(ps->b, p, bordcol, ZP, font, ask);
+ if(buf) p.x += w;
+ }
+ if(buf){
+ t = p;
+ p = drawstring(ps->b, buf, p, tick, tick2, bordcol, h);
+ }
+ flushimage(display, 1);
+
+nodraw:
+ i = ps->getevent(ps);
+ switch(i){
+ default:
+ done = 1;
+ n = -1;
+ break;
+ case Gkeyboard:
+ k = ps->k;
+ if(buf == nil || k == Keof || k == '\n'){
+ done = 1;
+ break;
+ }
+ if(k == Knack || k == Kesc){
+ done = !n;
+ n = tick2 = tick = 0;
+ buf[n] = 0;
+ break;
+ }
+ if(k == Ksoh || k == Khome){
+ tick2 = tick = 0;
+ continue;
+ }
+ if(k == Kenq || k == Kend){
+ tick2 = tick = n;
+ continue;
+ }
+ if(k == Kright){
+ if(tick2 < n)
+ tick2 = tick += chartorune(&k, buf+tick);
+ continue;
+ }
+ if(k == Kleft){
+ for(i = 0; i < n; i += l){
+ l = chartorune(&k, buf+i);
+ if(i+l >= tick){
+ tick2 = tick = i;
+ break;
+ }
+ }
+ continue;
+ }
+ if(k == Ketb){
+ l = tick;
+ while(tick > 0){
+ tick--;
+ if(tick == 0 ||
+ strchr(" !\"#$%&'()*+,-./:;<=>?@`[\\]^{|}~", buf[tick-1]))
+ break;
+ }
+ memmove(buf+tick, buf+l, n-l);
+ buf[n -= l-tick] = 0;
+ break;
+ }
+ if(k == Kbs){
+ if(tick <= 0 && tick2 <= 0)
+ continue;
+ if (tick == tick2)
+ for(i = 0; i < n; i += l){
+ l = chartorune(&k, buf+i);
+ if(i+l >= tick){
+ memmove(buf+i, buf+i+l, n - (i+l));
+ buf[n -= l] = 0;
+ tick2 = tick -= l;
+ break;
+ }
+ }
+ else
+ tick = tick2 = delsubstring(buf, n, tick-1, tick2, &n);
+ break;
+ }
+ if(k < 0x20 || k == Kdel || (k & 0xFF00) == KF || (k & 0xFF00) == Spec)
+ continue;
+ if((len-n) <= (l = runelen(k)))
+ continue;
+ tick = delsubstring(buf, n, tick, tick2, &n);
+ memmove(buf+tick+l, buf+tick, n - tick);
+ runetochar(buf+tick, &k);
+ buf[n += l] = 0;
+ tick2 = tick += l;
+ break;
+ case Gmouse:
+ m = ps->m;
+ if(mb&1 && !m.buttons&1) {
+ sorttick(&tick, &tick2);
+ mb = m.buttons;
+ }
+ if(m.buttons&1 && mb&6){
+ if (m.buttons != mb)
+ goto Mchecks;
+ continue;
+ }
+ if(m.buttons&1 && mb&6){
+ continue;
+ }
+ if(!ptinrect(m.xy, ps->r)){
+ down = 0;
+ goto nodraw;
+ }
+ if(m.buttons&1){
+ down = 1;
+ if(buf && m.xy.x >= (t.x - w)){
+ down = 0;
+ for(i = 0; i < n; i += l){
+ l = chartorune(&k, buf+i);
+ t.x += stringnwidth(font, buf+i, 1);
+ if(t.x > m.xy.x)
+ break;
+ }
+ if(mb & 1){
+ tick2 = i;
+ }else
+ tick = tick2 = i;
+ }
+ if(!((m.buttons&2) || (m.buttons&4))){
+ mb = m.buttons;
+ continue;
+ }
+ }
+Mchecks:
+ if(!(mb&2) && (m.buttons&3) == 3){
+ tick = tick2 = entersnarf(buf, n, tick, tick2, &n);
+ mb = m.buttons;
+ }
+ if(!(mb&4) && (m.buttons&5) == 5){
+ enterpaste(buf, n, len, tick, tick2, &n, &tick, &tick2);
+ mb = m.buttons;
+ }
+
+ done = down;
+ break;
+ }
+ if(ps->loopcleanup)
+ ps->loopcleanup(ps);
+ }
+ if(ps->cleanup)
+ ps->cleanup(ps);
+
+ freeimage(backcol);
+ freeimage(bordcol);
+ flushimage(display, 1);
+
+ return n;
+}
--- /dev/null
+++ b/libgenenter.h
@@ -1,0 +1,22 @@
+typedef struct Enterparams Enterparams;
+struct Enterparams {
+ int (*initsave)(Enterparams*);
+ int (*getevent)(Enterparams*);
+ void (*loopcleanup)(Enterparams*);
+ void (*cleanup)(Enterparams*);
+
+ Rune k;
+ Mouse m;
+ Point o;
+ Rectangle r;
+ Rectangle sc;
+ Image *b;
+ Image *save;
+ void *aux;
+};
+int _genenter(char*, char*, int, Enterparams*);
+
+enum {
+ Gkeyboard = 1,
+ Gmouse = 2,
+};
--- /dev/null
+++ b/libmkfile
@@ -1,0 +1,80 @@
+</$objtype/mkfile
+
+LIB=/$objtype/lib/libdraw.a
+
+OFILES=\
+ alloc.$O\
+ allocimagemix.$O\
+ arith.$O\
+ badrect.$O\
+ bezier.$O\
+ border.$O\
+ buildfont.$O\
+ bytesperline.$O\
+ chan.$O\
+ cloadimage.$O\
+ computil.$O\
+ creadimage.$O\
+ debug.$O\
+ defont.$O\
+ draw.$O\
+ drawrepl.$O\
+ eenter.$O\
+ egetrect.$O\
+ ellipse.$O\
+ emenuhit.$O\
+ enter.$O\
+ event.$O\
+ fmt.$O\
+ font.$O\
+ freesubfont.$O\
+ genenter.$O\
+ getdefont.$O\
+ getrect.$O\
+ getsubfont.$O\
+ icossin.$O\
+ icossin2.$O\
+ init.$O\
+ keyboard.$O\
+ line.$O\
+ menuhit.$O\
+ mkfont.$O\
+ mouse.$O\
+ newwindow.$O\
+ openfont.$O\
+ poly.$O\
+ loadimage.$O\
+ readcolmap.$O\
+ readimage.$O\
+ readsubfont.$O\
+ rectclip.$O\
+ replclipr.$O\
+ rgb.$O\
+ scroll.$O\
+ string.$O\
+ stringbg.$O\
+ stringsubfont.$O\
+ stringwidth.$O\
+ subfont.$O\
+ subfontcache.$O\
+ subfontname.$O\
+ unloadimage.$O\
+ window.$O\
+ writecolmap.$O\
+ writeimage.$O\
+ writesubfont.$O\
+
+HFILES=\
+ /sys/include/draw.h\
+ /sys/include/event.h\
+ /sys/include/mouse.h\
+ /sys/include/keyboard.h\
+ genenter.h
+
+UPDATE=\
+ mkfile\
+ $HFILES\
+ ${OFILES:%.$O=%.c}\
+ ${LIB:/$objtype/%=/386/%}\
+
+</sys/src/cmd/mksyslib
--- a/mkfile
+++ b/mkfile
@@ -4,15 +4,16 @@
</sys/src/cmd/mkmany
-prep:V: libenter.c libeenter.c
+prep:V:
+ cp /sys/src/libdraw/enter.c libenter.c
+ cp /sys/src/libdraw/eenter.c libeenter.c
+ cp /sys/src/libdraw/genenter.h libgenenter.h
+ cp /sys/src/libdraw/genenter.c libgenenter.c
+ cp /sys/src/libdraw/mkfile libmkfile
-instlib:V: /sys/src/libdraw/enter.c /sys/src/libdraw/eenter.c
-
-libenter.c:
- cp /sys/src/libdraw/enter.c $target
-
-libeenter.c:
- cp /sys/src/libdraw/eenter.c $target
-
-/sys/src/libdraw/%.c: lib%.c
- cp $prereq $target
+instlib:V:
+ cp libenter.c /sys/src/libdraw/enter.c
+ cp libeenter.c /sys/src/libdraw/eenter.c
+ cp libgenenter.h /sys/src/libdraw/genenter.h
+ cp libgenenter.c /sys/src/libdraw/genenter.c
+ cp libmkfile /sys/src/libdraw/mkfile