xref: /plan9/sys/src/cmd/samterm/menu.c (revision 6b6b9ac8b0b103b1e30e4d019522a78c950fce74)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <draw.h>
47dd7cddfSDavid du Colombier #include <thread.h>
57dd7cddfSDavid du Colombier #include <cursor.h>
67dd7cddfSDavid du Colombier #include <mouse.h>
77dd7cddfSDavid du Colombier #include <keyboard.h>
83e12c5d1SDavid du Colombier #include <frame.h>
93e12c5d1SDavid du Colombier #include "flayer.h"
103e12c5d1SDavid du Colombier #include "samterm.h"
113e12c5d1SDavid du Colombier 
12*6b6b9ac8SDavid du Colombier uchar	**name;	/* first byte is ' ' or '\'': modified state */
13*6b6b9ac8SDavid du Colombier Text	**text;	/* pointer to Text associated with file */
14*6b6b9ac8SDavid du Colombier ushort	*tag;		/* text[i].tag, even if text[i] not defined */
153e12c5d1SDavid du Colombier int	nname;
16*6b6b9ac8SDavid du Colombier int	mname;
173e12c5d1SDavid du Colombier int	mw;
183e12c5d1SDavid du Colombier 
193e12c5d1SDavid du Colombier char	*genmenu3(int);
203e12c5d1SDavid du Colombier char	*genmenu2(int);
213e12c5d1SDavid du Colombier char	*genmenu2c(int);
223e12c5d1SDavid du Colombier 
233e12c5d1SDavid du Colombier enum Menu2
243e12c5d1SDavid du Colombier {
253e12c5d1SDavid du Colombier 	Cut,
263e12c5d1SDavid du Colombier 	Paste,
273e12c5d1SDavid du Colombier 	Snarf,
287dd7cddfSDavid du Colombier 	Plumb,
293e12c5d1SDavid du Colombier 	Look,
303e12c5d1SDavid du Colombier 	Exch,
313e12c5d1SDavid du Colombier 	Search,
323e12c5d1SDavid du Colombier 	NMENU2 = Search,
333e12c5d1SDavid du Colombier 	Send = Search,
343e12c5d1SDavid du Colombier 	NMENU2C
353e12c5d1SDavid du Colombier };
363e12c5d1SDavid du Colombier 
373e12c5d1SDavid du Colombier enum Menu3
383e12c5d1SDavid du Colombier {
393e12c5d1SDavid du Colombier 	New,
40219b2ee8SDavid du Colombier 	Zerox,
417dd7cddfSDavid du Colombier 	Resize,
423e12c5d1SDavid du Colombier 	Close,
433e12c5d1SDavid du Colombier 	Write,
443e12c5d1SDavid du Colombier 	NMENU3
453e12c5d1SDavid du Colombier };
463e12c5d1SDavid du Colombier 
473e12c5d1SDavid du Colombier char	*menu2str[] = {
483e12c5d1SDavid du Colombier 	"cut",
493e12c5d1SDavid du Colombier 	"paste",
503e12c5d1SDavid du Colombier 	"snarf",
517dd7cddfSDavid du Colombier 	"plumb",
523e12c5d1SDavid du Colombier 	"look",
537dd7cddfSDavid du Colombier 	"<rio>",
543e12c5d1SDavid du Colombier 	0,		/* storage for last pattern */
553e12c5d1SDavid du Colombier };
563e12c5d1SDavid du Colombier 
573e12c5d1SDavid du Colombier char	*menu3str[] = {
583e12c5d1SDavid du Colombier 	"new",
59219b2ee8SDavid du Colombier 	"zerox",
607dd7cddfSDavid du Colombier 	"resize",
613e12c5d1SDavid du Colombier 	"close",
623e12c5d1SDavid du Colombier 	"write",
633e12c5d1SDavid du Colombier };
643e12c5d1SDavid du Colombier 
653e12c5d1SDavid du Colombier Menu	menu2 =	{0, genmenu2};
663e12c5d1SDavid du Colombier Menu	menu2c ={0, genmenu2c};
673e12c5d1SDavid du Colombier Menu	menu3 =	{0, genmenu3};
683e12c5d1SDavid du Colombier 
693e12c5d1SDavid du Colombier void
menu2hit(void)703e12c5d1SDavid du Colombier menu2hit(void)
713e12c5d1SDavid du Colombier {
723e12c5d1SDavid du Colombier 	Text *t=(Text *)which->user1;
733e12c5d1SDavid du Colombier 	int w = which-t->l;
74bd389b36SDavid du Colombier 	int m;
753e12c5d1SDavid du Colombier 
767dd7cddfSDavid du Colombier 	if(hversion==0 || plumbfd<0)
777dd7cddfSDavid du Colombier 		menu2str[Plumb] = "(plumb)";
787dd7cddfSDavid du Colombier 	m = menuhit(2, mousectl, t==&cmd? &menu2c : &menu2, nil);
797dd7cddfSDavid du Colombier 	if(hostlock || t->lock)
80bd389b36SDavid du Colombier 		return;
81bd389b36SDavid du Colombier 
82bd389b36SDavid du Colombier 	switch(m){
833e12c5d1SDavid du Colombier 	case Cut:
843e12c5d1SDavid du Colombier 		cut(t, w, 1, 1);
853e12c5d1SDavid du Colombier 		break;
863e12c5d1SDavid du Colombier 
873e12c5d1SDavid du Colombier 	case Paste:
883e12c5d1SDavid du Colombier 		paste(t, w);
893e12c5d1SDavid du Colombier 		break;
903e12c5d1SDavid du Colombier 
913e12c5d1SDavid du Colombier 	case Snarf:
923e12c5d1SDavid du Colombier 		snarf(t, w);
933e12c5d1SDavid du Colombier 		break;
943e12c5d1SDavid du Colombier 
957dd7cddfSDavid du Colombier 	case Plumb:
967dd7cddfSDavid du Colombier 		if(hversion > 0)
977dd7cddfSDavid du Colombier 			outTsll(Tplumb, t->tag, which->p0, which->p1);
987dd7cddfSDavid du Colombier 		break;
997dd7cddfSDavid du Colombier 
1003e12c5d1SDavid du Colombier 	case Exch:
1017dd7cddfSDavid du Colombier 		snarf(t, w);
1023e12c5d1SDavid du Colombier 		outT0(Tstartsnarf);
1033e12c5d1SDavid du Colombier 		setlock();
1043e12c5d1SDavid du Colombier 		break;
1053e12c5d1SDavid du Colombier 
1063e12c5d1SDavid du Colombier 	case Look:
1073e12c5d1SDavid du Colombier 		outTsll(Tlook, t->tag, which->p0, which->p1);
1083e12c5d1SDavid du Colombier 		setlock();
1093e12c5d1SDavid du Colombier 		break;
1103e12c5d1SDavid du Colombier 
1113e12c5d1SDavid du Colombier 	case Search:
1123e12c5d1SDavid du Colombier 		outcmd();
1133e12c5d1SDavid du Colombier 		if(t==&cmd)
1143e12c5d1SDavid du Colombier 			outTsll(Tsend, 0 /*ignored*/, which->p0, which->p1);
1153e12c5d1SDavid du Colombier 		else
1163e12c5d1SDavid du Colombier 			outT0(Tsearch);
1173e12c5d1SDavid du Colombier 		setlock();
1183e12c5d1SDavid du Colombier 		break;
1193e12c5d1SDavid du Colombier 	}
1203e12c5d1SDavid du Colombier }
1213e12c5d1SDavid du Colombier 
1223e12c5d1SDavid du Colombier void
menu3hit(void)1233e12c5d1SDavid du Colombier menu3hit(void)
1243e12c5d1SDavid du Colombier {
1253e12c5d1SDavid du Colombier 	Rectangle r;
1263e12c5d1SDavid du Colombier 	Flayer *l;
1273e12c5d1SDavid du Colombier 	int m, i;
1283e12c5d1SDavid du Colombier 	Text *t;
1293e12c5d1SDavid du Colombier 
1303e12c5d1SDavid du Colombier 	mw = -1;
1317dd7cddfSDavid du Colombier 	switch(m = menuhit(3, mousectl, &menu3, nil)){
1323e12c5d1SDavid du Colombier 	case -1:
1333e12c5d1SDavid du Colombier 		break;
1343e12c5d1SDavid du Colombier 
1353e12c5d1SDavid du Colombier 	case New:
1367dd7cddfSDavid du Colombier 		if(!hostlock)
1373e12c5d1SDavid du Colombier 			sweeptext(1, 0);
1383e12c5d1SDavid du Colombier 		break;
1393e12c5d1SDavid du Colombier 
140219b2ee8SDavid du Colombier 	case Zerox:
1417dd7cddfSDavid du Colombier 	case Resize:
1427dd7cddfSDavid du Colombier 		if(!hostlock){
1437dd7cddfSDavid du Colombier 			setcursor(mousectl, &bullseye);
1443e12c5d1SDavid du Colombier 			buttons(Down);
1457dd7cddfSDavid du Colombier 			if((mousep->buttons&4) && (l = flwhich(mousep->xy)) && getr(&r))
1467dd7cddfSDavid du Colombier 				duplicate(l, r, l->f.font, m==Resize);
1473e12c5d1SDavid du Colombier 			else
1487dd7cddfSDavid du Colombier 				setcursor(mousectl, cursor);
1493e12c5d1SDavid du Colombier 			buttons(Up);
1503e12c5d1SDavid du Colombier 		}
1513e12c5d1SDavid du Colombier 		break;
1523e12c5d1SDavid du Colombier 
1533e12c5d1SDavid du Colombier 	case Close:
1547dd7cddfSDavid du Colombier 		if(!hostlock){
1557dd7cddfSDavid du Colombier 			setcursor(mousectl, &bullseye);
1563e12c5d1SDavid du Colombier 			buttons(Down);
1577dd7cddfSDavid du Colombier 			if((mousep->buttons&4) && (l = flwhich(mousep->xy)) && !hostlock){
1583e12c5d1SDavid du Colombier 				t=(Text *)l->user1;
1593e12c5d1SDavid du Colombier 				if (t->nwin>1)
1603e12c5d1SDavid du Colombier 					closeup(l);
161219b2ee8SDavid du Colombier 				else if(t!=&cmd) {
1623e12c5d1SDavid du Colombier 					outTs(Tclose, t->tag);
163219b2ee8SDavid du Colombier 					setlock();
1643e12c5d1SDavid du Colombier 				}
1653e12c5d1SDavid du Colombier 			}
1667dd7cddfSDavid du Colombier 			setcursor(mousectl, cursor);
1673e12c5d1SDavid du Colombier 			buttons(Up);
1683e12c5d1SDavid du Colombier 		}
1693e12c5d1SDavid du Colombier 		break;
1703e12c5d1SDavid du Colombier 
1713e12c5d1SDavid du Colombier 	case Write:
1727dd7cddfSDavid du Colombier 		if(!hostlock){
1737dd7cddfSDavid du Colombier 			setcursor(mousectl, &bullseye);
1743e12c5d1SDavid du Colombier 			buttons(Down);
1757dd7cddfSDavid du Colombier 			if((mousep->buttons&4) && (l = flwhich(mousep->xy))){
1763e12c5d1SDavid du Colombier 				outTs(Twrite, ((Text *)l->user1)->tag);
1773e12c5d1SDavid du Colombier 				setlock();
1783e12c5d1SDavid du Colombier 			}else
1797dd7cddfSDavid du Colombier 				setcursor(mousectl, cursor);
1803e12c5d1SDavid du Colombier 			buttons(Up);
1813e12c5d1SDavid du Colombier 		}
1823e12c5d1SDavid du Colombier 		break;
1833e12c5d1SDavid du Colombier 
1843e12c5d1SDavid du Colombier 	default:
1853e12c5d1SDavid du Colombier 		if(t = text[m-NMENU3]){
1863e12c5d1SDavid du Colombier 			i = t->front;
1873e12c5d1SDavid du Colombier 			if(t->nwin==0 || t->l[i].textfn==0)
1883e12c5d1SDavid du Colombier 				return;	/* not ready yet; try again later */
1893e12c5d1SDavid du Colombier 			if(t->nwin>1 && which==&t->l[i])
1903e12c5d1SDavid du Colombier 				do
1913e12c5d1SDavid du Colombier 					if(++i==NL)
1923e12c5d1SDavid du Colombier 						i = 0;
1933e12c5d1SDavid du Colombier 				while(i!=t->front && t->l[i].textfn==0);
1943e12c5d1SDavid du Colombier 			current(&t->l[i]);
1957dd7cddfSDavid du Colombier 		}else if(!hostlock)
1963e12c5d1SDavid du Colombier 			sweeptext(0, tag[m-NMENU3]);
1973e12c5d1SDavid du Colombier 		break;
1983e12c5d1SDavid du Colombier 	}
1993e12c5d1SDavid du Colombier }
2003e12c5d1SDavid du Colombier 
2013e12c5d1SDavid du Colombier 
2023e12c5d1SDavid du Colombier Text *
sweeptext(int new,int tag)2033e12c5d1SDavid du Colombier sweeptext(int new, int tag)
2043e12c5d1SDavid du Colombier {
2053e12c5d1SDavid du Colombier 	Rectangle r;
2063e12c5d1SDavid du Colombier 	Text *t;
2073e12c5d1SDavid du Colombier 
2083e12c5d1SDavid du Colombier 	if(getr(&r) && (t = malloc(sizeof(Text)))){
209219b2ee8SDavid du Colombier 		memset((void*)t, 0, sizeof(Text));
2103e12c5d1SDavid du Colombier 		current((Flayer *)0);
2113e12c5d1SDavid du Colombier 		flnew(&t->l[0], gettext, 0, (char *)t);
2127dd7cddfSDavid du Colombier 		flinit(&t->l[0], r, font, maincols);	/*bnl*/
2133e12c5d1SDavid du Colombier 		t->nwin = 1;
2143e12c5d1SDavid du Colombier 		rinit(&t->rasp);
2153e12c5d1SDavid du Colombier 		if(new)
2163e12c5d1SDavid du Colombier 			startnewfile(Tstartnewfile, t);
2173e12c5d1SDavid du Colombier 		else{
2183e12c5d1SDavid du Colombier 			rinit(&t->rasp);
2193e12c5d1SDavid du Colombier 			t->tag = tag;
2203e12c5d1SDavid du Colombier 			startfile(t);
2213e12c5d1SDavid du Colombier 		}
2223e12c5d1SDavid du Colombier 		return t;
2233e12c5d1SDavid du Colombier 	}
2243e12c5d1SDavid du Colombier 	return 0;
2253e12c5d1SDavid du Colombier }
2263e12c5d1SDavid du Colombier 
2273e12c5d1SDavid du Colombier int
whichmenu(int tg)2283e12c5d1SDavid du Colombier whichmenu(int tg)
2293e12c5d1SDavid du Colombier {
2303e12c5d1SDavid du Colombier 	int i;
2313e12c5d1SDavid du Colombier 
2323e12c5d1SDavid du Colombier 	for(i=0; i<nname; i++)
2333e12c5d1SDavid du Colombier 		if(tag[i] == tg)
2343e12c5d1SDavid du Colombier 			return i;
2353e12c5d1SDavid du Colombier 	return -1;
2363e12c5d1SDavid du Colombier }
2373e12c5d1SDavid du Colombier 
2383e12c5d1SDavid du Colombier void
menuins(int n,uchar * s,Text * t,int m,int tg)2393e12c5d1SDavid du Colombier menuins(int n, uchar *s, Text *t, int m, int tg)
2403e12c5d1SDavid du Colombier {
2413e12c5d1SDavid du Colombier 	int i;
2423e12c5d1SDavid du Colombier 
243*6b6b9ac8SDavid du Colombier 	if(nname == mname){
244*6b6b9ac8SDavid du Colombier 		if(mname == 0)
245*6b6b9ac8SDavid du Colombier 			mname = 32;
246*6b6b9ac8SDavid du Colombier 		else
247*6b6b9ac8SDavid du Colombier 			mname *= 2;
248*6b6b9ac8SDavid du Colombier 		name = realloc(name, sizeof(name[0])*mname);
249*6b6b9ac8SDavid du Colombier 		text = realloc(text, sizeof(text[0])*mname);
250*6b6b9ac8SDavid du Colombier 		tag = realloc(tag, sizeof(tag[0])*mname);
251*6b6b9ac8SDavid du Colombier 		if(name==nil || text==nil || tag==nil)
252*6b6b9ac8SDavid du Colombier 			panic("realloc");
253*6b6b9ac8SDavid du Colombier 	}
2543e12c5d1SDavid du Colombier 	for(i=nname; i>n; --i)
2553e12c5d1SDavid du Colombier 		name[i]=name[i-1], text[i]=text[i-1], tag[i]=tag[i-1];
2563e12c5d1SDavid du Colombier 	text[n] = t;
2573e12c5d1SDavid du Colombier 	tag[n] = tg;
2583e12c5d1SDavid du Colombier 	name[n] = alloc(strlen((char*)s)+2);
2593e12c5d1SDavid du Colombier 	name[n][0] = m;
2603e12c5d1SDavid du Colombier 	strcpy((char*)name[n]+1, (char*)s);
2613e12c5d1SDavid du Colombier 	nname++;
262bd389b36SDavid du Colombier 	menu3.lasthit = n+NMENU3;
2633e12c5d1SDavid du Colombier }
2643e12c5d1SDavid du Colombier 
2653e12c5d1SDavid du Colombier void
menudel(int n)2663e12c5d1SDavid du Colombier menudel(int n)
2673e12c5d1SDavid du Colombier {
2683e12c5d1SDavid du Colombier 	int i;
2693e12c5d1SDavid du Colombier 
2703e12c5d1SDavid du Colombier 	if(nname==0 || n>=nname || text[n])
2713e12c5d1SDavid du Colombier 		panic("menudel");
2723e12c5d1SDavid du Colombier 	free(name[n]);
2733e12c5d1SDavid du Colombier 	--nname;
2743e12c5d1SDavid du Colombier 	for(i = n; i<nname; i++)
2753e12c5d1SDavid du Colombier 		name[i]=name[i+1], text[i]=text[i+1], tag[i]=tag[i+1];
2763e12c5d1SDavid du Colombier }
2773e12c5d1SDavid du Colombier 
2783e12c5d1SDavid du Colombier void
setpat(char * s)2793e12c5d1SDavid du Colombier setpat(char *s)
2803e12c5d1SDavid du Colombier {
2813e12c5d1SDavid du Colombier 	static char pat[17];
2823e12c5d1SDavid du Colombier 
2833e12c5d1SDavid du Colombier 	pat[0] = '/';
2843e12c5d1SDavid du Colombier 	strncpy(pat+1, s, 15);
2853e12c5d1SDavid du Colombier 	menu2str[Search] = pat;
2863e12c5d1SDavid du Colombier }
2873e12c5d1SDavid du Colombier 
2883e12c5d1SDavid du Colombier #define	NBUF	64
2893e12c5d1SDavid du Colombier static uchar buf[NBUF*UTFmax]={' ', ' ', ' ', ' '};
2903e12c5d1SDavid du Colombier 
2913e12c5d1SDavid du Colombier char *
paren(char * s)2923e12c5d1SDavid du Colombier paren(char *s)
2933e12c5d1SDavid du Colombier {
2943e12c5d1SDavid du Colombier 	uchar *t = buf;
2953e12c5d1SDavid du Colombier 
2963e12c5d1SDavid du Colombier 	*t++ = '(';
2973e12c5d1SDavid du Colombier 	do; while(*t++ = *s++);
2983e12c5d1SDavid du Colombier 	t[-1] = ')';
2993e12c5d1SDavid du Colombier 	*t = 0;
3003e12c5d1SDavid du Colombier 	return (char *)buf;
3013e12c5d1SDavid du Colombier }
3023e12c5d1SDavid du Colombier char*
genmenu2(int n)3033e12c5d1SDavid du Colombier genmenu2(int n)
3043e12c5d1SDavid du Colombier {
3053e12c5d1SDavid du Colombier 	Text *t=(Text *)which->user1;
3063e12c5d1SDavid du Colombier 	char *p;
3073e12c5d1SDavid du Colombier 	if(n>=NMENU2+(menu2str[Search]!=0))
3083e12c5d1SDavid du Colombier 		return 0;
3093e12c5d1SDavid du Colombier 	p = menu2str[n];
3107dd7cddfSDavid du Colombier 	if(!hostlock && !t->lock || n==Search || n==Look)
3113e12c5d1SDavid du Colombier 		return p;
3123e12c5d1SDavid du Colombier 	return paren(p);
3133e12c5d1SDavid du Colombier }
3143e12c5d1SDavid du Colombier char*
genmenu2c(int n)3153e12c5d1SDavid du Colombier genmenu2c(int n)
3163e12c5d1SDavid du Colombier {
3173e12c5d1SDavid du Colombier 	Text *t=(Text *)which->user1;
3183e12c5d1SDavid du Colombier 	char *p;
3193e12c5d1SDavid du Colombier 	if(n >= NMENU2C)
3203e12c5d1SDavid du Colombier 		return 0;
3213e12c5d1SDavid du Colombier 	if(n == Send)
3223e12c5d1SDavid du Colombier 		p="send";
3233e12c5d1SDavid du Colombier 	else
3243e12c5d1SDavid du Colombier 		p = menu2str[n];
3257dd7cddfSDavid du Colombier 	if(!hostlock && !t->lock)
3263e12c5d1SDavid du Colombier 		return p;
3273e12c5d1SDavid du Colombier 	return paren(p);
3283e12c5d1SDavid du Colombier }
3293e12c5d1SDavid du Colombier char *
genmenu3(int n)3303e12c5d1SDavid du Colombier genmenu3(int n)
3313e12c5d1SDavid du Colombier {
3323e12c5d1SDavid du Colombier 	Text *t;
3333e12c5d1SDavid du Colombier 	int c, i, k, l, w;
3343e12c5d1SDavid du Colombier 	Rune r;
3353e12c5d1SDavid du Colombier 	char *p;
3363e12c5d1SDavid du Colombier 
3373e12c5d1SDavid du Colombier 	if(n >= NMENU3+nname)
3383e12c5d1SDavid du Colombier 		return 0;
3393e12c5d1SDavid du Colombier 	if(n < NMENU3){
3403e12c5d1SDavid du Colombier 		p = menu3str[n];
3417dd7cddfSDavid du Colombier 		if(hostlock)
3423e12c5d1SDavid du Colombier 			p = paren(p);
3433e12c5d1SDavid du Colombier 		return p;
3443e12c5d1SDavid du Colombier 	}
3453e12c5d1SDavid du Colombier 	n -= NMENU3;
3463e12c5d1SDavid du Colombier 	if(n == 0)	/* unless we've been fooled, this is cmd */
3473e12c5d1SDavid du Colombier 		return (char *)&name[n][1];
3483e12c5d1SDavid du Colombier 	if(mw == -1){
3493e12c5d1SDavid du Colombier 		mw = 7;	/* strlen("~~sam~~"); */
3503e12c5d1SDavid du Colombier 		for(i=1; i<nname; i++){
3513e12c5d1SDavid du Colombier 			w = utflen((char*)name[i]+1)+4;	/* include "'+. " */
3523e12c5d1SDavid du Colombier 			if(w > mw)
3533e12c5d1SDavid du Colombier 				mw = w;
3543e12c5d1SDavid du Colombier 		}
3553e12c5d1SDavid du Colombier 	}
3563e12c5d1SDavid du Colombier 	if(mw > NBUF)
3573e12c5d1SDavid du Colombier 		mw = NBUF;
3583e12c5d1SDavid du Colombier 	t = text[n];
3593e12c5d1SDavid du Colombier 	buf[0] = name[n][0];
3603e12c5d1SDavid du Colombier 	buf[1] = '-';
3613e12c5d1SDavid du Colombier 	buf[2] = ' ';
3623e12c5d1SDavid du Colombier 	buf[3] = ' ';
3633e12c5d1SDavid du Colombier 	if(t){
3643e12c5d1SDavid du Colombier 		if(t->nwin == 1)
3653e12c5d1SDavid du Colombier 			buf[1] = '+';
3663e12c5d1SDavid du Colombier 		else if(t->nwin > 1)
3673e12c5d1SDavid du Colombier 			buf[1] = '*';
3683e12c5d1SDavid du Colombier 		if(work && t==(Text *)work->user1) {
3693e12c5d1SDavid du Colombier 			buf[2]= '.';
3703e12c5d1SDavid du Colombier 			if(modified)
3713e12c5d1SDavid du Colombier 				buf[0] = '\'';
3723e12c5d1SDavid du Colombier 		}
3733e12c5d1SDavid du Colombier 	}
3743e12c5d1SDavid du Colombier 	l = utflen((char*)name[n]+1);
3753e12c5d1SDavid du Colombier 	if(l > NBUF-4-2){
3763e12c5d1SDavid du Colombier 		i = 4;
3773e12c5d1SDavid du Colombier 		k = 1;
3783e12c5d1SDavid du Colombier 		while(i < NBUF/2){
3793e12c5d1SDavid du Colombier 			k += chartorune(&r, (char*)name[n]+k);
3803e12c5d1SDavid du Colombier 			i++;
3813e12c5d1SDavid du Colombier 		}
3823e12c5d1SDavid du Colombier 		c = name[n][k];
3833e12c5d1SDavid du Colombier 		name[n][k] = 0;
3843e12c5d1SDavid du Colombier 		strcpy((char*)buf+4, (char*)name[n]+1);
3853e12c5d1SDavid du Colombier 		name[n][k] = c;
3863e12c5d1SDavid du Colombier 		strcat((char*)buf, "...");
3873e12c5d1SDavid du Colombier 		while((l-i) >= NBUF/2-4){
3883e12c5d1SDavid du Colombier 			k += chartorune(&r, (char*)name[n]+k);
3893e12c5d1SDavid du Colombier 			i++;
3903e12c5d1SDavid du Colombier 		}
3913e12c5d1SDavid du Colombier 		strcat((char*)buf, (char*)name[n]+k);
3923e12c5d1SDavid du Colombier 	}else
3933e12c5d1SDavid du Colombier 		strcpy((char*)buf+4, (char*)name[n]+1);
3943e12c5d1SDavid du Colombier 	i = utflen((char*)buf);
3953e12c5d1SDavid du Colombier 	k = strlen((char*)buf);
3963e12c5d1SDavid du Colombier 	while(i<mw && k<sizeof buf-1){
3973e12c5d1SDavid du Colombier 		buf[k++] = ' ';
3983e12c5d1SDavid du Colombier 		i++;
3993e12c5d1SDavid du Colombier 	}
4003e12c5d1SDavid du Colombier 	buf[k] = 0;
4013e12c5d1SDavid du Colombier 	return (char *)buf;
4023e12c5d1SDavid du Colombier }
403