git: 9front

Download patch

ref: 7284155da2b76f4e70c7cc087cf82f1432aff9cd
parent: 268634601da134b84e1619b85d112d08d05a2200
author: cinap_lenrek <cinap_lenrek@centraldogma>
date: Tue Nov 8 01:16:08 EST 2011

mothra: cut/snarf in entry and edit panels

--- a/sys/src/cmd/mothra/forms.c
+++ b/sys/src/cmd/mothra/forms.c
@@ -64,10 +64,6 @@
 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 @@
 		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:
@@ -456,34 +444,6 @@
 	pldraw(text, screen);
 }
 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;
--- 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 @@
 	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 @@
 		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 @@
 	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);
--- a/sys/src/cmd/mothra/libpanel/entry.c
+++ b/sys/src/cmd/mothra/libpanel/entry.c
@@ -15,6 +15,35 @@
 	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 @@
 		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 @@
 		*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 @@
 		*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){
--- a/sys/src/cmd/mothra/libpanel/panel.h
+++ b/sys/src/cmd/mothra/libpanel/panel.h
@@ -85,7 +85,7 @@
 #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
--- a/sys/src/cmd/mothra/libpanel/popup.c
+++ b/sys/src/cmd/mothra/libpanel/popup.c
@@ -21,6 +21,7 @@
 	Panel *p;
 	Point d;
 	Popup *pp;
+
 	pp=g->data;
 	if(g->state==UP){
 		switch(m->buttons&7){
@@ -66,6 +67,7 @@
 					draw(g->b, p->r, pp->save, 0, p->r.min);
 					flushimage(display, 1);
 					freeimage(pp->save);
+					pp->save=0;
 				}
 				pl_invis(p, 1);
 			}
--- a/sys/src/cmd/mothra/libpanel/textview.c
+++ b/sys/src/cmd/mothra/libpanel/textview.c
@@ -113,6 +113,7 @@
 	tp=p->data;
 	oldhitword=tp->hitword;
 	hitme=0;
+
 	pl_passon(oldhitword, m);
 	if(m->buttons&OUT)
 		p->state=UP;
--- a/sys/src/cmd/mothra/libpanel/textwin.c
+++ b/sys/src/cmd/mothra/libpanel/textwin.c
@@ -26,6 +26,9 @@
 #include <event.h>
 #include <panel.h>
 #include "pldefs.h"
+
+#define SLACK 100
+
 /*
  * Is text at point a before or after that at point b?
  */
@@ -61,8 +64,8 @@
  */
 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 @@
 	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 @@
 	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 *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;
--- a/sys/src/cmd/mothra/mothra.c
+++ b/sys/src/cmd/mothra/mothra.c
@@ -1121,8 +1121,7 @@
 
 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 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);
--