xref: /inferno-os/libtk/twind.c (revision c9c0d12ef55c878b0e361f9f6936bbb4c67b40fb)
137da2899SCharles.Forsyth #include "lib9.h"
237da2899SCharles.Forsyth #include "draw.h"
337da2899SCharles.Forsyth #include "tk.h"
437da2899SCharles.Forsyth #include "textw.h"
537da2899SCharles.Forsyth 
637da2899SCharles.Forsyth #define istring u.string
737da2899SCharles.Forsyth #define iwin u.win
837da2899SCharles.Forsyth #define imark u.mark
937da2899SCharles.Forsyth #define iline u.line
1037da2899SCharles.Forsyth 
1137da2899SCharles.Forsyth #define	O(t, e)		((long)(&((t*)0)->e))
1237da2899SCharles.Forsyth 
1337da2899SCharles.Forsyth static char* tktwincget(Tk*, char*, char**);
1437da2899SCharles.Forsyth static char* tktwinconfigure(Tk*, char*, char**);
1537da2899SCharles.Forsyth static char* tktwincreate(Tk*, char*, char**);
1637da2899SCharles.Forsyth static char* tktwinnames(Tk*, char*, char**);
1737da2899SCharles.Forsyth static int winowned(Tk *tk, Tk *sub);
1837da2899SCharles.Forsyth 
1937da2899SCharles.Forsyth static
2037da2899SCharles.Forsyth TkStab tkalign[] =
2137da2899SCharles.Forsyth {
2237da2899SCharles.Forsyth 	"top",		Tktop,
2337da2899SCharles.Forsyth 	"bottom",	Tkbottom,
2437da2899SCharles.Forsyth 	"center",	Tkcenter,
2537da2899SCharles.Forsyth 	"baseline",	Tkbaseline,
2637da2899SCharles.Forsyth 	nil
2737da2899SCharles.Forsyth };
2837da2899SCharles.Forsyth 
2937da2899SCharles.Forsyth static
3037da2899SCharles.Forsyth TkOption twinopts[] =
3137da2899SCharles.Forsyth {
3237da2899SCharles.Forsyth 	"align",	OPTstab,	O(TkTwind, align),	tkalign,
3337da2899SCharles.Forsyth 	"create",	OPTtext,	O(TkTwind, create),	nil,
3437da2899SCharles.Forsyth 	"padx",		OPTnndist,	O(TkTwind, padx),	nil,
3537da2899SCharles.Forsyth 	"pady",		OPTnndist,	O(TkTwind, pady),	nil,
3637da2899SCharles.Forsyth 	"stretch",	OPTstab,	O(TkTwind, stretch),	tkbool,
3737da2899SCharles.Forsyth 	"window",	OPTwinp,	O(TkTwind, sub),	nil,
3837da2899SCharles.Forsyth 	"ascent",	OPTdist,	O(TkTwind, ascent), nil,
3937da2899SCharles.Forsyth 	nil
4037da2899SCharles.Forsyth };
4137da2899SCharles.Forsyth 
4237da2899SCharles.Forsyth TkCmdtab
4337da2899SCharles.Forsyth tktwincmd[] =
4437da2899SCharles.Forsyth {
4537da2899SCharles.Forsyth 	"cget",		tktwincget,
4637da2899SCharles.Forsyth 	"configure",	tktwinconfigure,
4737da2899SCharles.Forsyth 	"create",	tktwincreate,
4837da2899SCharles.Forsyth 	"names",	tktwinnames,
4937da2899SCharles.Forsyth 	nil
5037da2899SCharles.Forsyth };
5137da2899SCharles.Forsyth 
5237da2899SCharles.Forsyth int
tktfindsubitem(Tk * sub,TkTindex * ix)5337da2899SCharles.Forsyth tktfindsubitem(Tk *sub, TkTindex *ix)
5437da2899SCharles.Forsyth {
5537da2899SCharles.Forsyth 	Tk *tk, *isub;
5637da2899SCharles.Forsyth 	TkText *tkt;
5737da2899SCharles.Forsyth 
5837da2899SCharles.Forsyth 	tk = sub->parent;
5937da2899SCharles.Forsyth 	if(tk != nil) {
6037da2899SCharles.Forsyth 		tkt = TKobj(TkText, tk);
6137da2899SCharles.Forsyth 		tktstartind(tkt, ix);
6237da2899SCharles.Forsyth 		do {
6337da2899SCharles.Forsyth 			if(ix->item->kind == TkTwin) {
6437da2899SCharles.Forsyth 				isub = ix->item->iwin->sub;
6537da2899SCharles.Forsyth 				if(isub != nil &&
6637da2899SCharles.Forsyth 				   isub->name != nil &&
6737da2899SCharles.Forsyth 				   strcmp(isub->name->name, sub->name->name) == 0)
6837da2899SCharles.Forsyth 				return 1;
6937da2899SCharles.Forsyth 			}
7037da2899SCharles.Forsyth 		} while(tktadjustind(tkt, TkTbyitem, ix));
7137da2899SCharles.Forsyth 	}
7237da2899SCharles.Forsyth 	return 0;
7337da2899SCharles.Forsyth }
7437da2899SCharles.Forsyth 
7537da2899SCharles.Forsyth static void
tktwindsize(Tk * tk,TkTindex * ix)7637da2899SCharles.Forsyth tktwindsize(Tk *tk, TkTindex *ix)
7737da2899SCharles.Forsyth {
7837da2899SCharles.Forsyth 	Tk *s;
7937da2899SCharles.Forsyth 	TkTitem *i;
8037da2899SCharles.Forsyth 	TkTwind *w;
8137da2899SCharles.Forsyth 
8237da2899SCharles.Forsyth 
8337da2899SCharles.Forsyth 	i = ix->item;
8437da2899SCharles.Forsyth 	/* assert(i->kind == TkTwin); */
8537da2899SCharles.Forsyth 
8637da2899SCharles.Forsyth 	w = i->iwin;
8737da2899SCharles.Forsyth 	s = w->sub;
8837da2899SCharles.Forsyth 	if(s == nil)
8937da2899SCharles.Forsyth 		return;
9037da2899SCharles.Forsyth 
9137da2899SCharles.Forsyth 	if(w->width != s->act.width || w->height != s->act.height) {
9237da2899SCharles.Forsyth 		s->act.width = w->width;
9337da2899SCharles.Forsyth 		s->act.height = w->height;
9437da2899SCharles.Forsyth 		if(s->slave) {
9537da2899SCharles.Forsyth 			tkpackqit(s);
9637da2899SCharles.Forsyth 			tkrunpack(tk->env->top);
9737da2899SCharles.Forsyth 		}
9837da2899SCharles.Forsyth 	}
9937da2899SCharles.Forsyth 
10037da2899SCharles.Forsyth 	tktfixgeom(tk, tktprevwrapline(tk, ix->line), ix->line, 0);
10137da2899SCharles.Forsyth 	tktextsize(tk, 1);
10237da2899SCharles.Forsyth }
10337da2899SCharles.Forsyth 
104*c9c0d12eSforsyth void
tktxtforgetsub(Tk * sub,Tk * tk)105*c9c0d12eSforsyth tktxtforgetsub(Tk *sub, Tk *tk)
10637da2899SCharles.Forsyth {
107*c9c0d12eSforsyth 	TkTwind *w;
108*c9c0d12eSforsyth 	TkTindex ix;
109*c9c0d12eSforsyth 
110*c9c0d12eSforsyth 	if(!tktfindsubitem(sub, &ix))
111*c9c0d12eSforsyth 		return;
112*c9c0d12eSforsyth 	w = ix.item->iwin;
113*c9c0d12eSforsyth 	if(w->focus == tk) {
114*c9c0d12eSforsyth if(0)print("tktxtforget sub %p %q focus %p %q\n", sub, tkname(sub), tk, tkname(tk));
115*c9c0d12eSforsyth 		w->focus = nil;
116*c9c0d12eSforsyth 	}
11737da2899SCharles.Forsyth }
11837da2899SCharles.Forsyth 
11937da2899SCharles.Forsyth static void
tktwingeom(Tk * sub,int x,int y,int w,int h)12037da2899SCharles.Forsyth tktwingeom(Tk *sub, int x, int y, int w, int h)
12137da2899SCharles.Forsyth {
12237da2899SCharles.Forsyth 	TkTindex ix;
12337da2899SCharles.Forsyth 	Tk *tk;
12437da2899SCharles.Forsyth 	TkTwind *win;
12537da2899SCharles.Forsyth 
12637da2899SCharles.Forsyth 	USED(x);
12737da2899SCharles.Forsyth 	USED(y);
12837da2899SCharles.Forsyth 
12937da2899SCharles.Forsyth 	tk = sub->parent;
13037da2899SCharles.Forsyth 	if(!tktfindsubitem(sub, &ix)) {
13137da2899SCharles.Forsyth 		print("tktwingeom: %s not found\n", sub->name->name);
13237da2899SCharles.Forsyth 		return;
13337da2899SCharles.Forsyth 	}
13437da2899SCharles.Forsyth 
13537da2899SCharles.Forsyth 	win = ix.item->iwin;
13637da2899SCharles.Forsyth 
13737da2899SCharles.Forsyth 	win->width = w;
13837da2899SCharles.Forsyth 	win->height = h;
13937da2899SCharles.Forsyth 
14037da2899SCharles.Forsyth 	sub->req.width = w;
14137da2899SCharles.Forsyth 	sub->req.height = h;
14237da2899SCharles.Forsyth 	tktwindsize(tk, &ix);
14337da2899SCharles.Forsyth }
14437da2899SCharles.Forsyth 
14537da2899SCharles.Forsyth static void
tktdestroyed(Tk * sub)14637da2899SCharles.Forsyth tktdestroyed(Tk *sub)
14737da2899SCharles.Forsyth {
14837da2899SCharles.Forsyth 	TkTindex ix;
14937da2899SCharles.Forsyth 	Tk *tk;
15037da2899SCharles.Forsyth 
15137da2899SCharles.Forsyth 	if(tktfindsubitem(sub, &ix)) {
15237da2899SCharles.Forsyth 		ix.item->iwin->sub = nil;
15337da2899SCharles.Forsyth 		ix.item->iwin->focus = nil;
15437da2899SCharles.Forsyth 		if((tk = sub->parent) != nil) {
15537da2899SCharles.Forsyth 			tktfixgeom(tk, tktprevwrapline(tk, ix.line), ix.line, 0);
15637da2899SCharles.Forsyth 			tktextsize(tk, 1);
15737da2899SCharles.Forsyth 			sub->parent = nil;
15837da2899SCharles.Forsyth 		}
15937da2899SCharles.Forsyth 	}
16037da2899SCharles.Forsyth }
16137da2899SCharles.Forsyth 
16237da2899SCharles.Forsyth void
tktdirty(Tk * sub)16337da2899SCharles.Forsyth tktdirty(Tk *sub)
16437da2899SCharles.Forsyth {
16537da2899SCharles.Forsyth 	Tk *tk, *parent, *isub;
16637da2899SCharles.Forsyth 	TkText *tkt;
16737da2899SCharles.Forsyth 	TkTindex ix;
16837da2899SCharles.Forsyth 
16937da2899SCharles.Forsyth 	parent = nil;
17037da2899SCharles.Forsyth 	for(tk = sub; tk && parent == nil; tk = tk->master)
17137da2899SCharles.Forsyth 		parent = tk->parent;
17237da2899SCharles.Forsyth 	if(tk == nil)
17337da2899SCharles.Forsyth 		return;
17437da2899SCharles.Forsyth 
17537da2899SCharles.Forsyth 	tkt = TKobj(TkText, parent);
17637da2899SCharles.Forsyth 	tktstartind(tkt, &ix);
17737da2899SCharles.Forsyth 	do {
17837da2899SCharles.Forsyth 		if(ix.item->kind == TkTwin) {
17937da2899SCharles.Forsyth 			isub = ix.item->iwin->sub;
18037da2899SCharles.Forsyth 			if(isub != nil) {
18137da2899SCharles.Forsyth 				tktfixgeom(parent, tktprevwrapline(parent, ix.line), ix.line, 0);
18237da2899SCharles.Forsyth 				if (sub->flag & Tktransparent)
18337da2899SCharles.Forsyth 					parent->flag |= Tkrefresh;	/* XXX could be more efficient, by drawing the background locally? */
18437da2899SCharles.Forsyth 				return;
18537da2899SCharles.Forsyth 			}
18637da2899SCharles.Forsyth 		}
18737da2899SCharles.Forsyth 	} while(tktadjustind(tkt, TkTbyitem, &ix));
18837da2899SCharles.Forsyth 	tktextsize(parent, 1);
18937da2899SCharles.Forsyth }
19037da2899SCharles.Forsyth 
19137da2899SCharles.Forsyth static char*
tktwinchk(Tk * tk,TkTwind * w,Tk * oldsub)19237da2899SCharles.Forsyth tktwinchk(Tk *tk, TkTwind *w, Tk *oldsub)
19337da2899SCharles.Forsyth {
19437da2899SCharles.Forsyth 	Tk *sub;
19537da2899SCharles.Forsyth 
19637da2899SCharles.Forsyth 	sub = w->sub;
19737da2899SCharles.Forsyth 	if (sub != oldsub) {
19837da2899SCharles.Forsyth 		w->sub = oldsub;
19937da2899SCharles.Forsyth 		if(sub == nil)
20037da2899SCharles.Forsyth 			return nil;
20137da2899SCharles.Forsyth 
20237da2899SCharles.Forsyth 		if(sub->flag & Tkwindow)
20337da2899SCharles.Forsyth 			return TkIstop;
20437da2899SCharles.Forsyth 
20537da2899SCharles.Forsyth 		if(sub->master != nil || sub->parent != nil)
20637da2899SCharles.Forsyth 			return TkWpack;
20737da2899SCharles.Forsyth 
20837da2899SCharles.Forsyth 		if (oldsub != nil) {
20937da2899SCharles.Forsyth 			oldsub->parent = nil;
21037da2899SCharles.Forsyth 			oldsub->geom = nil;
21137da2899SCharles.Forsyth 			oldsub->destroyed = nil;
21237da2899SCharles.Forsyth 		}
21337da2899SCharles.Forsyth 		w->sub = sub;
21437da2899SCharles.Forsyth 		w->focus = nil;
21537da2899SCharles.Forsyth 
21637da2899SCharles.Forsyth 		sub->parent = tk;
21737da2899SCharles.Forsyth 		tksetbits(sub, Tksubsub);
21837da2899SCharles.Forsyth 		sub->geom = tktwingeom;
21937da2899SCharles.Forsyth 		sub->destroyed = tktdestroyed;
22037da2899SCharles.Forsyth 
22137da2899SCharles.Forsyth 		w->width = sub->req.width;
22237da2899SCharles.Forsyth 		w->height = sub->req.height;
22337da2899SCharles.Forsyth 		w->owned = winowned(tk, sub);
22437da2899SCharles.Forsyth 	}
22537da2899SCharles.Forsyth 
22637da2899SCharles.Forsyth 	return nil;
22737da2899SCharles.Forsyth }
22837da2899SCharles.Forsyth 
22937da2899SCharles.Forsyth 
23037da2899SCharles.Forsyth /* Text Window Command (+ means implemented)
23137da2899SCharles.Forsyth 	+cget
23237da2899SCharles.Forsyth 	+configure
23337da2899SCharles.Forsyth 	+create
23437da2899SCharles.Forsyth 	+names
23537da2899SCharles.Forsyth */
23637da2899SCharles.Forsyth 
23737da2899SCharles.Forsyth static char*
tktwincget(Tk * tk,char * arg,char ** val)23837da2899SCharles.Forsyth tktwincget(Tk *tk, char *arg, char **val)
23937da2899SCharles.Forsyth {
24037da2899SCharles.Forsyth 	char *e;
24137da2899SCharles.Forsyth 	TkTindex ix;
24237da2899SCharles.Forsyth 	TkOptab tko[2];
24337da2899SCharles.Forsyth 
24437da2899SCharles.Forsyth 	e = tktindparse(tk, &arg, &ix);
24537da2899SCharles.Forsyth 	if(e != nil)
24637da2899SCharles.Forsyth 		return e;
24737da2899SCharles.Forsyth 	if(ix.item->kind != TkTwin)
24837da2899SCharles.Forsyth 		return TkBadwp;
24937da2899SCharles.Forsyth 
25037da2899SCharles.Forsyth 	tko[0].ptr = ix.item->iwin;
25137da2899SCharles.Forsyth 	tko[0].optab = twinopts;
25237da2899SCharles.Forsyth 	tko[1].ptr = nil;
25337da2899SCharles.Forsyth 
25437da2899SCharles.Forsyth 	return tkgencget(tko, arg, val, tk->env->top);
25537da2899SCharles.Forsyth }
25637da2899SCharles.Forsyth 
25737da2899SCharles.Forsyth static char*
tktwinconfigure(Tk * tk,char * arg,char ** val)25837da2899SCharles.Forsyth tktwinconfigure(Tk *tk, char *arg, char **val)
25937da2899SCharles.Forsyth {
26037da2899SCharles.Forsyth 	char *e;
26137da2899SCharles.Forsyth 	TkTindex ix;
26237da2899SCharles.Forsyth 	TkOptab tko[2];
26337da2899SCharles.Forsyth 	Tk *oldsub;
26437da2899SCharles.Forsyth 
26537da2899SCharles.Forsyth 	USED(val);
26637da2899SCharles.Forsyth 
26737da2899SCharles.Forsyth 	e = tktindparse(tk, &arg, &ix);
26837da2899SCharles.Forsyth 	if(e != nil)
26937da2899SCharles.Forsyth 		return e;
27037da2899SCharles.Forsyth 	if(ix.item->kind != TkTwin)
27137da2899SCharles.Forsyth 		return TkBadwp;
27237da2899SCharles.Forsyth 
27337da2899SCharles.Forsyth 	oldsub = ix.item->iwin->sub;
27437da2899SCharles.Forsyth 
27537da2899SCharles.Forsyth 	tko[0].ptr = ix.item->iwin;
27637da2899SCharles.Forsyth 	tko[0].optab = twinopts;
27737da2899SCharles.Forsyth 	tko[1].ptr = nil;
27837da2899SCharles.Forsyth 
27937da2899SCharles.Forsyth 	e = tkparse(tk->env->top, arg, tko, nil);
28037da2899SCharles.Forsyth 	if(e != nil)
28137da2899SCharles.Forsyth 		return e;
28237da2899SCharles.Forsyth 
28337da2899SCharles.Forsyth 	e = tktwinchk(tk, ix.item->iwin, oldsub);
28437da2899SCharles.Forsyth 	if(e != nil)
28537da2899SCharles.Forsyth 		return e;
28637da2899SCharles.Forsyth 
28737da2899SCharles.Forsyth 	tktwindsize(tk, &ix);
28837da2899SCharles.Forsyth 	return nil;
28937da2899SCharles.Forsyth }
29037da2899SCharles.Forsyth 
29137da2899SCharles.Forsyth /*
29237da2899SCharles.Forsyth  * return true if tk is an ancestor of sub
29337da2899SCharles.Forsyth  */
29437da2899SCharles.Forsyth static int
winowned(Tk * tk,Tk * sub)29537da2899SCharles.Forsyth winowned(Tk *tk, Tk *sub)
29637da2899SCharles.Forsyth {
29737da2899SCharles.Forsyth 	int len;
29837da2899SCharles.Forsyth 	if (tk->name == nil || sub->name == nil)
29937da2899SCharles.Forsyth 		return 0;
30037da2899SCharles.Forsyth 	len = strlen(tk->name->name);
30137da2899SCharles.Forsyth 	if (strncmp(tk->name->name, sub->name->name, len) == 0 &&
30237da2899SCharles.Forsyth 			sub->name->name[len] == '.')
30337da2899SCharles.Forsyth 		return 1;
30437da2899SCharles.Forsyth 	return 0;
30537da2899SCharles.Forsyth }
30637da2899SCharles.Forsyth 
30737da2899SCharles.Forsyth static char*
tktwincreate(Tk * tk,char * arg,char ** val)30837da2899SCharles.Forsyth tktwincreate(Tk *tk, char *arg, char **val)
30937da2899SCharles.Forsyth {
31037da2899SCharles.Forsyth 	char *e;
31137da2899SCharles.Forsyth 	TkTindex ix;
31237da2899SCharles.Forsyth 	TkTitem *i;
31337da2899SCharles.Forsyth 	TkText *tkt;
31437da2899SCharles.Forsyth 	TkOptab tko[2];
31537da2899SCharles.Forsyth 
31637da2899SCharles.Forsyth 	USED(val);
31737da2899SCharles.Forsyth 
31837da2899SCharles.Forsyth 	tkt = TKobj(TkText, tk);
31937da2899SCharles.Forsyth 
32037da2899SCharles.Forsyth 	e = tktindparse(tk, &arg, &ix);
32137da2899SCharles.Forsyth 	if(e != nil)
32237da2899SCharles.Forsyth 		return e;
32337da2899SCharles.Forsyth 
32437da2899SCharles.Forsyth 	e = tktnewitem(TkTwin, 0, &i);
32537da2899SCharles.Forsyth 	if(e != nil)
32637da2899SCharles.Forsyth 		return e;
32737da2899SCharles.Forsyth 
32837da2899SCharles.Forsyth 	i->iwin = malloc(sizeof(TkTwind));
32937da2899SCharles.Forsyth 	if(i->iwin == nil) {
33037da2899SCharles.Forsyth 		tktfreeitems(tkt, i, 1);
33137da2899SCharles.Forsyth 		return TkNomem;
33237da2899SCharles.Forsyth 	}
33337da2899SCharles.Forsyth 
33437da2899SCharles.Forsyth 	memset(i->iwin, 0, sizeof(TkTwind));
33537da2899SCharles.Forsyth 	i->iwin->align = Tkcenter;
33637da2899SCharles.Forsyth 	i->iwin->ascent = -1;
33737da2899SCharles.Forsyth 
33837da2899SCharles.Forsyth 	tko[0].ptr = i->iwin;
33937da2899SCharles.Forsyth 	tko[0].optab = twinopts;
34037da2899SCharles.Forsyth 	tko[1].ptr = nil;
34137da2899SCharles.Forsyth 
34237da2899SCharles.Forsyth 	e = tkparse(tk->env->top, arg, tko, nil);
34337da2899SCharles.Forsyth 	if(e != nil) {
34437da2899SCharles.Forsyth     err1:
34537da2899SCharles.Forsyth 		tktfreeitems(tkt, i, 1);
34637da2899SCharles.Forsyth 		return e;
34737da2899SCharles.Forsyth 	}
34837da2899SCharles.Forsyth 
34937da2899SCharles.Forsyth 	e = tktwinchk(tk, i->iwin, nil);
35037da2899SCharles.Forsyth 	if(e != nil)
35137da2899SCharles.Forsyth 		goto err1;
35237da2899SCharles.Forsyth 
35337da2899SCharles.Forsyth 	e = tktsplititem(&ix);
35437da2899SCharles.Forsyth 	if(e != nil)
35537da2899SCharles.Forsyth 		goto err1;
35637da2899SCharles.Forsyth 
35737da2899SCharles.Forsyth 	tktiteminsert(tkt, &ix, i);
35837da2899SCharles.Forsyth 	if(e != nil)
35937da2899SCharles.Forsyth 		goto err1;
36037da2899SCharles.Forsyth 
36137da2899SCharles.Forsyth 	tktadjustind(tkt, TkTbyitemback, &ix);
36237da2899SCharles.Forsyth 	tktwindsize(tk, &ix);
36337da2899SCharles.Forsyth 
36437da2899SCharles.Forsyth 	return nil;
36537da2899SCharles.Forsyth }
36637da2899SCharles.Forsyth 
36737da2899SCharles.Forsyth static char*
tktwinnames(Tk * tk,char * arg,char ** val)36837da2899SCharles.Forsyth tktwinnames(Tk *tk, char *arg, char **val)
36937da2899SCharles.Forsyth {
37037da2899SCharles.Forsyth 	char *e, *fmt;
37137da2899SCharles.Forsyth 	TkTindex ix;
37237da2899SCharles.Forsyth 	TkText *tkt = TKobj(TkText, tk);
37337da2899SCharles.Forsyth 
37437da2899SCharles.Forsyth 	USED(arg);
37537da2899SCharles.Forsyth 
37637da2899SCharles.Forsyth 	tktstartind(tkt, &ix);
37737da2899SCharles.Forsyth 	fmt = "%s";
37837da2899SCharles.Forsyth 	do {
3795849851aSforsyth 		if(ix.item->kind == TkTwin &&
3805849851aSforsyth 		   ix.item->iwin->sub != nil &&
3815849851aSforsyth                      ix.item->iwin->sub->name != nil) {
38237da2899SCharles.Forsyth 			e = tkvalue(val, fmt, ix.item->iwin->sub->name->name);
38337da2899SCharles.Forsyth 			if(e != nil)
38437da2899SCharles.Forsyth 				return e;
38537da2899SCharles.Forsyth 			fmt = " %s";
38637da2899SCharles.Forsyth 		}
38737da2899SCharles.Forsyth 	} while(tktadjustind(tkt, TkTbyitem, &ix));
38837da2899SCharles.Forsyth 	return nil;
38937da2899SCharles.Forsyth }
390