From d8b1af77d0c98289669918d87884ff9974cb39d4 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Tue, 8 Nov 2011 06:16:08 +0100 Subject: [PATCH] mothra: cut/snarf in entry and edit panels --- sys/src/cmd/mothra/forms.c | 44 +------------------ sys/src/cmd/mothra/libpanel/edit.c | 46 +++++++++++++++++++- sys/src/cmd/mothra/libpanel/entry.c | 58 ++++++++++++++++++++++---- sys/src/cmd/mothra/libpanel/panel.h | 2 +- sys/src/cmd/mothra/libpanel/popup.c | 2 + sys/src/cmd/mothra/libpanel/textview.c | 1 + sys/src/cmd/mothra/libpanel/textwin.c | 28 +++++++------ sys/src/cmd/mothra/mothra.c | 6 +-- 8 files changed, 117 insertions(+), 70 deletions(-) diff --git a/sys/src/cmd/mothra/forms.c b/sys/src/cmd/mothra/forms.c index 20c7ed26c..febf1e8d3 100644 --- a/sys/src/cmd/mothra/forms.c +++ b/sys/src/cmd/mothra/forms.c @@ -64,10 +64,6 @@ void h_submittype(Panel *, char *); void h_submitindex(Panel *, char *); void h_resetinput(Panel *, int); void h_select(Panel *, int, int); -void h_cut(Panel *, int); -void h_paste(Panel *, int); -void h_snarf(Panel *, int); -void h_edit(Panel *); char *selgen(Panel *, int); char *nullgen(Panel *, int); Field *newfield(Form *form){ @@ -377,20 +373,12 @@ void mkfieldpanel(Rtext *t){ f->p->fixedsize.x=f->pulldown->r.max.x-f->pulldown->r.min.x; break; case TEXTWIN: - menu=plgroup(0,0); f->p=plframe(0,0); pllabel(f->p, PACKN|FILLX, f->name); scrl=plscrollbar(f->p, PACKW|FILLY); - pop=plpopup(f->p, PACKN|FILLX, 0, menu, 0); - f->textwin=pledit(pop, EXPAND, Pt(f->cols*chrwidth, f->rows*font->height), - 0, 0, h_edit); + f->textwin=pledit(f->p, EXPAND, Pt(f->cols*chrwidth, f->rows*font->height), + 0, 0, 0); f->textwin->userp=f; - button=plbutton(menu, PACKN|FILLX, "cut", h_cut); - button->userp=f->textwin; - button=plbutton(menu, PACKN|FILLX, "paste", h_paste); - button->userp=f->textwin; - button=plbutton(menu, PACKN|FILLX, "snarf", h_snarf); - button->userp=f->textwin; plscroll(f->textwin, 0, scrl); break; case INDEX: @@ -457,34 +445,6 @@ void h_resetinput(Panel *p, int){ } void h_buttoninput(Panel *p, int){ } -void h_edit(Panel *p){ - plgrabkb(p); -} -Rune *snarfbuf=0; -int nsnarfbuf=0; -void h_snarf(Panel *p, int){ - int s0, s1; - Rune *text; - p=p->userp; - plegetsel(p, &s0, &s1); - if(s0==s1) return; - text=pleget(p); - if(snarfbuf) free(snarfbuf); - nsnarfbuf=s1-s0; - snarfbuf=malloc(nsnarfbuf*sizeof(Rune)); - if(snarfbuf==0){ - fprint(2, "No mem\n"); - exits("no mem"); - } - memmove(snarfbuf, text+s0, nsnarfbuf*sizeof(Rune)); -} -void h_cut(Panel *p, int b){ - h_snarf(p, b); - plepaste(p->userp, 0, 0); -} -void h_paste(Panel *p, int){ - plepaste(p->userp, snarfbuf, nsnarfbuf); -} int ulen(char *s){ int len; len=0; diff --git a/sys/src/cmd/mothra/libpanel/edit.c b/sys/src/cmd/mothra/libpanel/edit.c index ff14de068..0dd26c4d8 100644 --- a/sys/src/cmd/mothra/libpanel/edit.c +++ b/sys/src/cmd/mothra/libpanel/edit.c @@ -24,9 +24,9 @@ typedef struct Edit Edit; struct Edit{ Point minsize; + void (*hit)(Panel *); int sel0, sel1; Textwin *t; - void (*hit)(Panel *); Rune *text; int ntext; }; @@ -48,6 +48,39 @@ void pl_drawedit(Panel *p){ if(sb && sb->setscrollbar) sb->setscrollbar(sb, ep->t->top, ep->t->bot, ep->t->etext-ep->t->text); } +void pl_snarfedit(Panel *p, int cut){ + int fd, n, s0, s1; + char *s; + Rune *t; + + if((fd=open("/dev/snarf", cut ? OWRITE|OTRUNC : OREAD))<0) + return; + if(cut){ + t=pleget(p); + plegetsel(p, &s0, &s1); + if(t==0 || s0>=s1){ + close(fd); + return; + } + s = smprint("%.*S", s1-s0, t+s0); + if((n = strlen(s))>0) + write(fd, s, n); + free(s); + plepaste(p, 0, 0); + }else{ + if((s=malloc(4096))==0){ + close(fd); + return; + } + if((n=readn(fd, s, 4096))<0) + n=0; + t=runesmprint("%.*s", n, s); + plepaste(p, t, runestrlen(t)); + free(s); + free(t); + } + close(fd); +} /* * Should do double-clicks: * If ep->sel0==ep->sel1 on entry and the @@ -73,7 +106,13 @@ int pl_hitedit(Panel *p, Mouse *m){ twselect(ep->t, m); ep->sel0=ep->t->sel0; ep->sel1=ep->t->sel1; - if(ep->hit) ep->hit(p); + plgrabkb(p); + if((m->buttons&7)==3) + pl_snarfedit(p, 1); + else if((m->buttons&7)==5) + pl_snarfedit(p, 0); + else if(ep->hit) + (*ep->hit)(p); } return 0; } @@ -124,6 +163,9 @@ void pl_typeedit(Panel *p, Rune c){ t->b=p->b; twhilite(t, ep->sel0, ep->sel1, 0); switch(c){ + case Kesc: + pl_snarfedit(p, 1); + break; case Kbs: /* ^H: erase character */ if(ep->sel0!=0) --ep->sel0; twreplace(t, ep->sel0, ep->sel1, 0, 0); diff --git a/sys/src/cmd/mothra/libpanel/entry.c b/sys/src/cmd/mothra/libpanel/entry.c index 9f2d281df..85e724ef7 100644 --- a/sys/src/cmd/mothra/libpanel/entry.c +++ b/sys/src/cmd/mothra/libpanel/entry.c @@ -15,6 +15,35 @@ struct Entry{ Point minsize; }; #define SLACK 7 /* enough for one extra rune and ◀ and a nul */ +void pl_snarfentry(Panel *p, int cut){ + Entry *ep; + int fd, n; + char *s; + + ep=p->data; + if((fd=open("/dev/snarf", cut ? OWRITE|OTRUNC : OREAD))<0) + return; + if(cut){ + if((n=ep->entp-ep->entry)>0) + write(fd, ep->entry, n); + ep->entp=ep->entry; + }else{ + if((s=malloc(1024+SLACK))==0){ + close(fd); + return; + } + if((n=readn(fd, s, 1024))<0) + n=0; + free(ep->entry); + s=realloc(s, n+SLACK); + ep->entry=s; + ep->eent=s+n+SLACK; + ep->entp=s+n; + } + close(fd); + *ep->entp='\0'; + pldraw(p, p->b); +} void pl_drawentry(Panel *p){ Rectangle r; Entry *ep; @@ -37,17 +66,25 @@ void pl_drawentry(Panel *p){ free(s); } int pl_hitentry(Panel *p, Mouse *m){ - int oldstate; - oldstate=p->state; - if(m->buttons&OUT) - p->state=UP; - else if(m->buttons&7) + if((m->buttons&OUT)==0 && (m->buttons&7)){ + plgrabkb(p); + p->state=DOWN; - else{ /* mouse inside, but no buttons down */ - if(p->state==DOWN) plgrabkb(p); + pldraw(p, p->b); + while(m->buttons&7){ + int old; + old=m->buttons; + *m=emouse(); + if((old&7)==1){ + if((m->buttons&7)==3) + pl_snarfentry(p, 1); + if((m->buttons&7)==5) + pl_snarfentry(p, 0); + } + } p->state=UP; + pldraw(p, p->b); } - if(p->state!=oldstate) pldraw(p, p->b); return 0; } void pl_typeentry(Panel *p, Rune c){ @@ -60,6 +97,9 @@ void pl_typeentry(Panel *p, Rune c){ *ep->entp='\0'; if(ep->hit) ep->hit(p, ep->entry); return; + case Kesc: + pl_snarfentry(p, 1); + return; case Knack: /* ^U: erase line */ ep->entp=ep->entry; *ep->entp='\0'; @@ -76,7 +116,7 @@ void pl_typeentry(Panel *p, Rune c){ *ep->entp='\0'; break; default: - if(c < 0x20 || c == Kesc || c == Kdel || (c & 0xFF00) == KF || (c & 0xFF00) == Spec) + if(c < 0x20 || c == Kdel || (c & 0xFF00) == KF || (c & 0xFF00) == Spec) break; ep->entp+=runetochar(ep->entp, &c); if(ep->entp>ep->eent){ diff --git a/sys/src/cmd/mothra/libpanel/panel.h b/sys/src/cmd/mothra/libpanel/panel.h index 6c022cfc4..d5546de27 100644 --- a/sys/src/cmd/mothra/libpanel/panel.h +++ b/sys/src/cmd/mothra/libpanel/panel.h @@ -85,7 +85,7 @@ struct Panel{ #define MAXX 0x1000 /* make x size as big as biggest sibling's */ #define MAXY 0x2000 /* make y size as big as biggest sibling's */ #define BITMAP 0x4000 /* text argument is a bitmap, not a string */ -#define USERFL 0x100000 /* user flag */ +#define USERFL 0x100000 /* start of user flag */ /* * An extra bit in Mouse.buttons diff --git a/sys/src/cmd/mothra/libpanel/popup.c b/sys/src/cmd/mothra/libpanel/popup.c index 345ca4ca5..c4c4d7a0e 100644 --- a/sys/src/cmd/mothra/libpanel/popup.c +++ b/sys/src/cmd/mothra/libpanel/popup.c @@ -21,6 +21,7 @@ int pl_hitpopup(Panel *g, Mouse *m){ Panel *p; Point d; Popup *pp; + pp=g->data; if(g->state==UP){ switch(m->buttons&7){ @@ -66,6 +67,7 @@ int pl_hitpopup(Panel *g, Mouse *m){ draw(g->b, p->r, pp->save, 0, p->r.min); flushimage(display, 1); freeimage(pp->save); + pp->save=0; } pl_invis(p, 1); } diff --git a/sys/src/cmd/mothra/libpanel/textview.c b/sys/src/cmd/mothra/libpanel/textview.c index 7b54d86b9..0eb9448a3 100644 --- a/sys/src/cmd/mothra/libpanel/textview.c +++ b/sys/src/cmd/mothra/libpanel/textview.c @@ -113,6 +113,7 @@ int pl_hittextview(Panel *p, Mouse *m){ tp=p->data; oldhitword=tp->hitword; hitme=0; + pl_passon(oldhitword, m); if(m->buttons&OUT) p->state=UP; diff --git a/sys/src/cmd/mothra/libpanel/textwin.c b/sys/src/cmd/mothra/libpanel/textwin.c index 7a0629ad1..d752a4496 100644 --- a/sys/src/cmd/mothra/libpanel/textwin.c +++ b/sys/src/cmd/mothra/libpanel/textwin.c @@ -26,6 +26,9 @@ #include #include #include "pldefs.h" + +#define SLACK 100 + /* * Is text at point a before or after that at point b? */ @@ -61,8 +64,8 @@ Point tw_rune2pt(Textwin *t, int i){ */ void tw_storeloc(Textwin *t, int l, Point p){ int nloc; - if(l>t->eloc-t->loc){ - nloc=l+100; + if(l>=t->eloc-t->loc){ + nloc=l+SLACK; t->loc=realloc(t->loc, nloc*sizeof(Point)); if(t->loc==0){ fprint(2, "No mem in tw_storeloc\n"); @@ -226,7 +229,7 @@ void twselect(Textwin *t, Mouse *m){ twhilite(t, sel0, sel1, 1); for(;;){ *m=emouse(); - if(m->buttons==0) break; + if((m->buttons&7)!=1) break; newsel=twpt2rune(t, m->xy); newp=tw_rune2pt(t, newsel); if(eqpt(newp, p0)) newp=addpt(newp, Pt(1, 0)); @@ -389,17 +392,16 @@ void twreplace(Textwin *t, int r0, int r1, Rune *ins, int nins){ int olen, nlen, tlen, dtop; Rune *ntext; olen=t->etext-t->text; - nlen=olen+r0-r1+nins; + nlen=olen+nins-(r1-r0); tlen=t->eslack-t->text; if(nlen>tlen){ - tlen=nlen+100; - ntext=malloc(tlen*sizeof(Rune)); - memmove(ntext, t->text, r0*sizeof(Rune)); - memmove(ntext+r0+nins, t->text+r1, (olen-r1)*sizeof(Rune)); + tlen=nlen+SLACK; + if((ntext=realloc(t->text, tlen*sizeof(Rune)))==0) + return; t->text=ntext; t->eslack=ntext+tlen; } - else if(olen!=nlen) + if(olen!=nlen) memmove(t->text+r0+nins, t->text+r1, (olen-r1)*sizeof(Rune)); if(nins!=0) /* ins can be 0 if nins==0 */ memmove(t->text+r0, ins, nins*sizeof(Rune)); @@ -444,20 +446,20 @@ Textwin *twnew(Image *b, Font *f, Rune *text, int ntext){ Textwin *t; t=malloc(sizeof(Textwin)); if(t==0) return 0; - t->text=malloc((ntext+100)*sizeof(Rune)); + t->text=malloc((ntext+SLACK)*sizeof(Rune)); if(t->text==0){ free(t); return 0; } - t->loc=malloc(100*sizeof(Point)); + t->loc=malloc(SLACK*sizeof(Point)); if(t->loc==0){ free(t->text); free(t); return 0; } - t->eloc=t->loc+100; + t->eloc=t->loc+SLACK; t->etext=t->text+ntext; - t->eslack=t->etext+100; + t->eslack=t->etext+SLACK; if(ntext) memmove(t->text, text, ntext*sizeof(Rune)); t->top=0; t->bot=0; diff --git a/sys/src/cmd/mothra/mothra.c b/sys/src/cmd/mothra/mothra.c index 21c35666d..ee0144494 100644 --- a/sys/src/cmd/mothra/mothra.c +++ b/sys/src/cmd/mothra/mothra.c @@ -1121,8 +1121,7 @@ mothon(Www *w, int on) void snarf(Panel *p){ int fd; - fd=create("/dev/snarf", OWRITE, 0666); - if(fd>=0){ + if((fd=open("/dev/snarf", OWRITE|OTRUNC))>=0){ fprint(fd, "%s", urlstr(selection)); close(fd); } @@ -1130,7 +1129,8 @@ void snarf(Panel *p){ void paste(Panel *p){ char buf[1024]; int n, len, fd; - fd=open("/dev/snarf", OREAD); + if((fd=open("/dev/snarf", OREAD))<0) + return; strncpy(buf, plentryval(p), sizeof(buf)); len=strlen(buf); n=read(fd, buf+len, sizeof(buf)-len-1);