xref: /inferno-os/libtk/buton.c (revision 48c2bcd8842a77d6fca4a18505e622e9a9d3d38b)
137da2899SCharles.Forsyth #include "lib9.h"
237da2899SCharles.Forsyth #include "draw.h"
337da2899SCharles.Forsyth #include "tk.h"
437da2899SCharles.Forsyth #include "label.h"
537da2899SCharles.Forsyth 
637da2899SCharles.Forsyth #define	O(t, e)		((long)(&((t*)0)->e))
737da2899SCharles.Forsyth 
837da2899SCharles.Forsyth /* Widget Commands (+ means implemented)
937da2899SCharles.Forsyth 	+cget
1037da2899SCharles.Forsyth 	+configure
1137da2899SCharles.Forsyth 	+invoke
1237da2899SCharles.Forsyth 	+select
1337da2899SCharles.Forsyth 	+deselect
1437da2899SCharles.Forsyth 	+toggle
1537da2899SCharles.Forsyth  */
1637da2899SCharles.Forsyth 
1737da2899SCharles.Forsyth enum {
1837da2899SCharles.Forsyth 	/* other constants */
1937da2899SCharles.Forsyth 	InvokePause	= 200,	/* delay showing button in down state when invoked */
2037da2899SCharles.Forsyth };
2137da2899SCharles.Forsyth 
2237da2899SCharles.Forsyth TkOption tkbutopts[] =
2337da2899SCharles.Forsyth {
2437da2899SCharles.Forsyth 	"text",		OPTtext,	O(TkLabel, text),	nil,
2537da2899SCharles.Forsyth 	"label",	OPTtext,	O(TkLabel, text),	nil,
2637da2899SCharles.Forsyth 	"underline",	OPTdist,	O(TkLabel, ul),		nil,
2737da2899SCharles.Forsyth 	"justify",	OPTstab,	O(TkLabel, justify),	tkjustify,
2837da2899SCharles.Forsyth 	"anchor",	OPTflag,	O(TkLabel, anchor),	tkanchor,
2937da2899SCharles.Forsyth 	"command",	OPTtext,	O(TkLabel, command),	nil,
3037da2899SCharles.Forsyth 	"bitmap",	OPTbmap,	O(TkLabel, bitmap),	nil,
3137da2899SCharles.Forsyth 	"image",	OPTimag,	O(TkLabel, img),	nil,
3237da2899SCharles.Forsyth 	nil
3337da2899SCharles.Forsyth };
3437da2899SCharles.Forsyth 
3537da2899SCharles.Forsyth TkOption tkcbopts[] =
3637da2899SCharles.Forsyth {
3737da2899SCharles.Forsyth 	"variable",	OPTtext,	O(TkLabel, variable),	nil,
3837da2899SCharles.Forsyth 	"indicatoron",	OPTstab,	O(TkLabel, indicator),	tkbool,
3937da2899SCharles.Forsyth 	"onvalue",	OPTtext,	O(TkLabel, value),	nil,
4037da2899SCharles.Forsyth 	"offvalue",	OPTtext,	O(TkLabel, offvalue), nil,
4137da2899SCharles.Forsyth 	nil,
4237da2899SCharles.Forsyth };
4337da2899SCharles.Forsyth 
4437da2899SCharles.Forsyth TkOption tkradopts[] =
4537da2899SCharles.Forsyth {
4637da2899SCharles.Forsyth 	"variable",	OPTtext,	O(TkLabel, variable),	nil,
4737da2899SCharles.Forsyth 	"value",	OPTtext,	O(TkLabel, value), nil,
4837da2899SCharles.Forsyth 	"indicatoron",	OPTstab,	O(TkLabel, indicator),	tkbool,
4937da2899SCharles.Forsyth 	nil,
5037da2899SCharles.Forsyth };
5137da2899SCharles.Forsyth 
5237da2899SCharles.Forsyth static
5337da2899SCharles.Forsyth TkEbind bb[] =
5437da2899SCharles.Forsyth {
5537da2899SCharles.Forsyth 	{TkEnter,	"%W configure -state active"},
5637da2899SCharles.Forsyth 	{TkLeave,	"%W configure -state normal"},
5737da2899SCharles.Forsyth 	{TkButton1P,	"%W tkButton1P"},
5837da2899SCharles.Forsyth 	{TkButton1R,	"%W tkButton1R %x %y"},
5937da2899SCharles.Forsyth 	{TkMotion|TkButton1P, 	"" },
6037da2899SCharles.Forsyth 	{TkKey,	"%W tkButtonKey 0x%K"},
6137da2899SCharles.Forsyth };
6237da2899SCharles.Forsyth 
6337da2899SCharles.Forsyth static
6437da2899SCharles.Forsyth TkEbind cb[] =
6537da2899SCharles.Forsyth {
6637da2899SCharles.Forsyth 	{TkEnter,		"%W configure -state active"},
6737da2899SCharles.Forsyth 	{TkLeave,		"%W configure -state normal"},
6837da2899SCharles.Forsyth 	{TkButton1P,		"%W invoke"},
6937da2899SCharles.Forsyth 	{TkMotion|TkButton1P, 	"" },
7037da2899SCharles.Forsyth 	{TkKey,	"%W tkButtonKey 0x%K"},
7137da2899SCharles.Forsyth };
7237da2899SCharles.Forsyth 
7337da2899SCharles.Forsyth 
7437da2899SCharles.Forsyth static char	tkselbut[] = "selectedButton";
7537da2899SCharles.Forsyth 
7637da2899SCharles.Forsyth static char*	newbutton(TkTop*, int, char*, char**);
7737da2899SCharles.Forsyth static int	istransparent(Tk*);
7837da2899SCharles.Forsyth static void tkvarchanged(Tk*, char*, char*);
7937da2899SCharles.Forsyth 
8037da2899SCharles.Forsyth char*
tkbutton(TkTop * t,char * arg,char ** ret)8137da2899SCharles.Forsyth tkbutton(TkTop *t, char *arg, char **ret)
8237da2899SCharles.Forsyth {
8337da2899SCharles.Forsyth 	return newbutton(t, TKbutton, arg, ret);
8437da2899SCharles.Forsyth }
8537da2899SCharles.Forsyth 
8637da2899SCharles.Forsyth char*
tkcheckbutton(TkTop * t,char * arg,char ** ret)8737da2899SCharles.Forsyth tkcheckbutton(TkTop *t, char *arg, char **ret)
8837da2899SCharles.Forsyth {
8937da2899SCharles.Forsyth 	return newbutton(t, TKcheckbutton, arg, ret);
9037da2899SCharles.Forsyth }
9137da2899SCharles.Forsyth 
9237da2899SCharles.Forsyth char*
tkradiobutton(TkTop * t,char * arg,char ** ret)9337da2899SCharles.Forsyth tkradiobutton(TkTop *t, char *arg, char **ret)
9437da2899SCharles.Forsyth {
9537da2899SCharles.Forsyth 	return newbutton(t, TKradiobutton, arg, ret);
9637da2899SCharles.Forsyth }
9737da2899SCharles.Forsyth 
9837da2899SCharles.Forsyth static char*
newbutton(TkTop * t,int btype,char * arg,char ** ret)9937da2899SCharles.Forsyth newbutton(TkTop *t, int btype, char *arg, char **ret)
10037da2899SCharles.Forsyth {
10137da2899SCharles.Forsyth 	Tk *tk;
10237da2899SCharles.Forsyth 	char *e;
10337da2899SCharles.Forsyth 	TkLabel *tkl;
10437da2899SCharles.Forsyth 	TkName *names;
10537da2899SCharles.Forsyth 	TkOptab tko[4];
10637da2899SCharles.Forsyth 	TkVar *v;
10737da2899SCharles.Forsyth 
10837da2899SCharles.Forsyth 	tk = tkmkbutton(t, btype);
10937da2899SCharles.Forsyth 	if(tk == nil)
11037da2899SCharles.Forsyth 		return TkNomem;
11137da2899SCharles.Forsyth 
11237da2899SCharles.Forsyth 	tkl = TKobj(TkLabel, tk);
11337da2899SCharles.Forsyth 
11437da2899SCharles.Forsyth 	tko[0].ptr = tk;
11537da2899SCharles.Forsyth 	tko[0].optab = tkgeneric;
11637da2899SCharles.Forsyth 	tko[1].ptr = tkl;
11737da2899SCharles.Forsyth 	tko[1].optab = tkbutopts;
11837da2899SCharles.Forsyth 	switch(btype){
11937da2899SCharles.Forsyth 	case TKcheckbutton:
12037da2899SCharles.Forsyth 		tko[2].ptr = tkl;
12137da2899SCharles.Forsyth 		tko[2].optab = tkcbopts;
12237da2899SCharles.Forsyth 		break;
12337da2899SCharles.Forsyth 	case TKradiobutton:
12437da2899SCharles.Forsyth 		tko[2].ptr = tkl;
12537da2899SCharles.Forsyth 		tko[2].optab = tkradopts;
12637da2899SCharles.Forsyth 		break;
12737da2899SCharles.Forsyth 	default:
12837da2899SCharles.Forsyth 		tk->relief = TKraised;
1290b978350Sforsyth 		tk->borderwidth = 1;
13037da2899SCharles.Forsyth 		tko[2].ptr = nil;
13137da2899SCharles.Forsyth 		break;
13237da2899SCharles.Forsyth 	}
13337da2899SCharles.Forsyth 	tko[3].ptr = nil;
13437da2899SCharles.Forsyth 
13537da2899SCharles.Forsyth 	names = nil;
13637da2899SCharles.Forsyth 	e = tkparse(t, arg, tko, &names);
13737da2899SCharles.Forsyth 	if(e != nil) {
13837da2899SCharles.Forsyth 		tkfreeobj(tk);
13937da2899SCharles.Forsyth 		return e;
14037da2899SCharles.Forsyth 	}
14137da2899SCharles.Forsyth 
14237da2899SCharles.Forsyth 	tksettransparent(tk, istransparent(tk));
14337da2899SCharles.Forsyth 	tksizebutton(tk);
14437da2899SCharles.Forsyth 
14537da2899SCharles.Forsyth 	e = tkaddchild(t, tk, &names);
14637da2899SCharles.Forsyth 	tkfreename(names);
14737da2899SCharles.Forsyth 	if(e != nil) {
14837da2899SCharles.Forsyth 		tkfreeobj(tk);
14937da2899SCharles.Forsyth 		return e;
15037da2899SCharles.Forsyth 	}
15137da2899SCharles.Forsyth 	tk->name->link = nil;
15237da2899SCharles.Forsyth 
15337da2899SCharles.Forsyth 	if (btype == TKradiobutton &&
15437da2899SCharles.Forsyth 			tkl->variable != nil &&
15537da2899SCharles.Forsyth 			strcmp(tkl->variable, tkselbut) == 0 &&
15637da2899SCharles.Forsyth 			tkl->value == nil &&
15737da2899SCharles.Forsyth 			tk->name != nil)
15837da2899SCharles.Forsyth 		tkl->value = strdup(tk->name->name);
15937da2899SCharles.Forsyth 
16037da2899SCharles.Forsyth 	if (tkl->variable != nil) {
16137da2899SCharles.Forsyth 		v = tkmkvar(t, tkl->variable, 0);
16237da2899SCharles.Forsyth 		if (v == nil){
16337da2899SCharles.Forsyth 			if(btype == TKcheckbutton){
16437da2899SCharles.Forsyth 				e = tksetvar(t, tkl->variable, tkl->offvalue ? tkl->offvalue : "0");
16537da2899SCharles.Forsyth 				if (e != nil)
16637da2899SCharles.Forsyth 					goto err;
16737da2899SCharles.Forsyth 			}
16837da2899SCharles.Forsyth 		} else if(v->type != TkVstring){
16937da2899SCharles.Forsyth 			e = TkNotvt;
17037da2899SCharles.Forsyth 			goto err;
17137da2899SCharles.Forsyth 		} else
17237da2899SCharles.Forsyth 			tkvarchanged(tk, tkl->variable, v->value);
17337da2899SCharles.Forsyth 	}
17437da2899SCharles.Forsyth 
17537da2899SCharles.Forsyth 	return tkvalue(ret, "%s", tk->name->name);
17637da2899SCharles.Forsyth 
17737da2899SCharles.Forsyth err:
17837da2899SCharles.Forsyth 	tkfreeobj(tk);
17937da2899SCharles.Forsyth 	return e;
18037da2899SCharles.Forsyth }
18137da2899SCharles.Forsyth 
18237da2899SCharles.Forsyth Tk*
tkmkbutton(TkTop * t,int btype)18337da2899SCharles.Forsyth tkmkbutton(TkTop *t, int btype)
18437da2899SCharles.Forsyth {
18537da2899SCharles.Forsyth 	Tk *tk;
18637da2899SCharles.Forsyth 	TkLabel *tkl;
18737da2899SCharles.Forsyth 	char *e;
18837da2899SCharles.Forsyth 
18937da2899SCharles.Forsyth 	tk = tknewobj(t, btype, sizeof(Tk)+sizeof(TkLabel));
19037da2899SCharles.Forsyth 	if (tk == nil)
19137da2899SCharles.Forsyth 		return nil;
19237da2899SCharles.Forsyth 
19337da2899SCharles.Forsyth 	e = nil;
19437da2899SCharles.Forsyth 	tk->relief = TKraised;
19537da2899SCharles.Forsyth 	tk->borderwidth = 0;
19637da2899SCharles.Forsyth 	tk->highlightwidth = 1;
19737da2899SCharles.Forsyth 	tk->flag |= Tktakefocus;
19837da2899SCharles.Forsyth 	tkl = TKobj(TkLabel, tk);
19937da2899SCharles.Forsyth 	tkl->ul = -1;
20037da2899SCharles.Forsyth 	tkl->justify = Tkleft;
20137da2899SCharles.Forsyth 
20237da2899SCharles.Forsyth 	switch (btype) {
20337da2899SCharles.Forsyth 	case TKbutton:
20437da2899SCharles.Forsyth 		e = tkbindings(t, tk, bb, nelem(bb));
20537da2899SCharles.Forsyth 		break;
20637da2899SCharles.Forsyth 	case TKcheckbutton:
207f94b359dSforsyth 		e = tkbindings(t, tk, cb, nelem(cb));
208f94b359dSforsyth 		break;
20937da2899SCharles.Forsyth 	case TKradiobutton:
210f94b359dSforsyth 		tkl->variable = strdup(tkselbut);
21137da2899SCharles.Forsyth 		e = tkbindings(t, tk, cb, nelem(cb));
21237da2899SCharles.Forsyth 		break;
21337da2899SCharles.Forsyth 	}
21437da2899SCharles.Forsyth 
21537da2899SCharles.Forsyth 	if (e != nil) {
21637da2899SCharles.Forsyth 		print("tkmkbutton internal error: %s\n", e);
21737da2899SCharles.Forsyth 		tkfreeobj(tk);
21837da2899SCharles.Forsyth 		return nil;
21937da2899SCharles.Forsyth 	}
22037da2899SCharles.Forsyth 	return tk;
22137da2899SCharles.Forsyth }
22237da2899SCharles.Forsyth 
2230b978350Sforsyth /*
2240b978350Sforsyth  * draw TKbutton, TKcheckbutton, TKradiobutton
2250b978350Sforsyth  */
2260b978350Sforsyth char*
tkdrawbutton(Tk * tk,Point orig)2270b978350Sforsyth tkdrawbutton(Tk *tk, Point orig)
22837da2899SCharles.Forsyth {
2290b978350Sforsyth  	TkEnv *e;
2300b978350Sforsyth 	TkLabel *tkl;
2310b978350Sforsyth 	Rectangle r, s, mainr, focusr;
2320b978350Sforsyth 	int dx, dy, h;
2330b978350Sforsyth 	Point p, u, v, pp[4];
2340b978350Sforsyth 	Image *i, *dst, *cd, *cl, *ct, *img;
2350b978350Sforsyth 	int relief, bgnd, fgnd;
2360b978350Sforsyth 
2370b978350Sforsyth 	e = tk->env;
2380b978350Sforsyth 
2390b978350Sforsyth 	dst = tkimageof(tk);
2400b978350Sforsyth 	if(dst == nil)
2410b978350Sforsyth 		return nil;
2420b978350Sforsyth 
2430b978350Sforsyth 	v.x = tk->act.width + 2*tk->borderwidth;
2440b978350Sforsyth 	v.y = tk->act.height + 2*tk->borderwidth;
2450b978350Sforsyth 
2460b978350Sforsyth 	r.min = ZP;
2470b978350Sforsyth 	r.max = v;
2480b978350Sforsyth 	focusr = insetrect(r, tk->borderwidth);
2490b978350Sforsyth 	mainr = insetrect(focusr, tk->highlightwidth);
2500b978350Sforsyth 	relief = tk->relief;
2510b978350Sforsyth 
2520b978350Sforsyth 	tkl = TKobj(TkLabel, tk);
2530b978350Sforsyth 
2540b978350Sforsyth 	fgnd = TkCforegnd;
2550b978350Sforsyth 	bgnd = TkCbackgnd;
2560b978350Sforsyth 	if (tk->flag & Tkdisabled)
2570b978350Sforsyth 		fgnd = TkCdisablefgnd;
2580b978350Sforsyth 	else if ((tk->type == TKcheckbutton || tk->type == TKradiobutton) && tkl->indicator == BoolF && tkl->check)
2590b978350Sforsyth 		bgnd = TkCselect;
2600b978350Sforsyth 	else if (tk->flag & Tkactive) {
2610b978350Sforsyth 		fgnd = TkCactivefgnd;
2620b978350Sforsyth 		bgnd = TkCactivebgnd;
26337da2899SCharles.Forsyth 	}
26437da2899SCharles.Forsyth 
2650b978350Sforsyth 	i = tkitmp(e, r.max, bgnd);
2660b978350Sforsyth 	if(i == nil)
2670b978350Sforsyth 		return nil;
2680b978350Sforsyth 
2690b978350Sforsyth 	if(tk->flag & Tkactive)
2700b978350Sforsyth 		draw(i, r, tkgc(e, bgnd), nil, ZP);
2710b978350Sforsyth 
2720b978350Sforsyth 	p = mainr.min;
2730b978350Sforsyth 	h = tkl->h - 2 * tk->highlightwidth;
2740b978350Sforsyth 
2750b978350Sforsyth 	dx = tk->act.width - tkl->w - tk->ipad.x;
2760b978350Sforsyth 	dy = tk->act.height - tkl->h - tk->ipad.y;
2770b978350Sforsyth 	if((tkl->anchor & (Tknorth|Tksouth)) == 0)
2780b978350Sforsyth 		p.y += dy/2;
2790b978350Sforsyth 	else if(tkl->anchor & Tksouth)
2800b978350Sforsyth 		p.y += dy;
2810b978350Sforsyth 
2820b978350Sforsyth 	if((tkl->anchor & (Tkeast|Tkwest)) == 0)
2830b978350Sforsyth 		p.x += dx/2;
2840b978350Sforsyth 	else if(tkl->anchor & Tkeast)
2850b978350Sforsyth 		p.x += dx;
2860b978350Sforsyth 
2870b978350Sforsyth 	switch(tk->type) {
2880b978350Sforsyth 	case TKcheckbutton:
2890b978350Sforsyth 		if(tkl->indicator == BoolF) {
2900b978350Sforsyth 			relief = tkl->check? TKsunken: TKraised;
2910b978350Sforsyth 			break;
2920b978350Sforsyth 		}
2930b978350Sforsyth 		u.x = p.x + ButtonBorder;
2940b978350Sforsyth 		u.y = p.y + ButtonBorder + (h - CheckSpace) / 2;
2950b978350Sforsyth 
2960b978350Sforsyth 		cl = tkgc(e, bgnd+TkLightshade);
2970b978350Sforsyth 		cd = tkgc(e, bgnd+TkDarkshade);
2980b978350Sforsyth 		tkbevel(i, u, CheckButton, CheckButton, CheckButtonBW, cd, cl);
2990b978350Sforsyth 		if(tkl->check) {
3000b978350Sforsyth 			u.x += CheckButtonBW+1;
3010b978350Sforsyth 			u.y += CheckButtonBW+1;
3020b978350Sforsyth 			pp[0] = u;
3030b978350Sforsyth 			pp[0].y += CheckButton/2-1;
3040b978350Sforsyth 			pp[1] = pp[0];
3050b978350Sforsyth 			pp[1].x += 2;
3060b978350Sforsyth 			pp[1].y += 2;
3070b978350Sforsyth 			pp[2] = u;
3080b978350Sforsyth 			pp[2].x += CheckButton/4;
3090b978350Sforsyth 			pp[2].y += CheckButton-2;
3100b978350Sforsyth 			pp[3] = u;
3110b978350Sforsyth 			pp[3].x += CheckButton-2;
3120b978350Sforsyth 			pp[3].y++;
3130b978350Sforsyth 			bezspline(i, pp, 4, Enddisc, Enddisc, 1, tkgc(e, TkCforegnd), ZP);
3140b978350Sforsyth 		}
3150b978350Sforsyth 		break;
3160b978350Sforsyth 	case TKradiobutton:
3170b978350Sforsyth 		if(tkl->indicator == BoolF) {
3180b978350Sforsyth 			relief = tkl->check? TKsunken: TKraised;
3190b978350Sforsyth 			break;
3200b978350Sforsyth 		}
3210b978350Sforsyth 		u.x = p.x + ButtonBorder;
3220b978350Sforsyth 		u.y = p.y + ButtonBorder + (h - CheckSpace) / 2;
3230b978350Sforsyth 		v = Pt(u.x+CheckButton/2,u.y+CheckButton/2);
3240b978350Sforsyth 		ellipse(i, v, CheckButton/2, CheckButton/2, CheckButtonBW-1, tkgc(e, bgnd+TkDarkshade), ZP);
3250b978350Sforsyth 		if(tkl->check)
3260b978350Sforsyth 			fillellipse(i, v, CheckButton/2-2, CheckButton/2-2, tkgc(e, TkCforegnd), ZP);	/* could be TkCselect */
3270b978350Sforsyth 		break;
3280b978350Sforsyth 	case TKbutton:
3290b978350Sforsyth 		if ((tk->flag & (Tkactivated|Tkactive)) == (Tkactivated|Tkactive))
3300b978350Sforsyth 			relief = TKsunken;
3310b978350Sforsyth 		break;
3320b978350Sforsyth 	}
3330b978350Sforsyth 
3340b978350Sforsyth 	p.x += tk->ipad.x/2;
3350b978350Sforsyth 	p.y += tk->ipad.y/2;
3360b978350Sforsyth 	u = ZP;
3370b978350Sforsyth 	if(tk->type == TKbutton && relief == TKsunken) {
3380b978350Sforsyth 		u.x++;
3390b978350Sforsyth 		u.y++;
3400b978350Sforsyth 	}
3410b978350Sforsyth 	if((tk->type == TKcheckbutton || tk->type == TKradiobutton) && tkl->indicator != BoolF)
3420b978350Sforsyth 		u.x += CheckSpace;
3430b978350Sforsyth 
3440b978350Sforsyth 	img = nil;
3450b978350Sforsyth 	if (tkl->img != nil && tkl->img->img != nil)
3460b978350Sforsyth 		img = tkl->img->img;
3470b978350Sforsyth 	else if (tkl->bitmap != nil)
3480b978350Sforsyth 		img = tkl->bitmap;
3490b978350Sforsyth 	if (img != nil) {
3500b978350Sforsyth 		s.min.x = p.x + Bitpadx;
3510b978350Sforsyth 		s.min.y = p.y + Bitpady;
3520b978350Sforsyth 		s.max.x = s.min.x + Dx(img->r);
3530b978350Sforsyth 		s.max.y = s.min.y + Dy(img->r);
3540b978350Sforsyth 		s = rectaddpt(s, u);
3550b978350Sforsyth 		if(tkchanhastype(img->chan, CGrey))
3560b978350Sforsyth 			draw(i, s, tkgc(e, fgnd), img, ZP);
3570b978350Sforsyth 		else
3580b978350Sforsyth 			draw(i, s, img, nil, ZP);
3590b978350Sforsyth 	} else if(tkl->text != nil) {
3600b978350Sforsyth 		u.x += Textpadx;
3610b978350Sforsyth 		u.y += Textpady;
3620b978350Sforsyth 		ct = tkgc(e, fgnd);
3630b978350Sforsyth 
3640b978350Sforsyth 		p.y += (h - tkl->textheight) / 2;
36586018cd3Sforsyth 		tkdrawstring(tk, i, addpt(u, p), tkl->text, tkl->ul, ct, tkl->justify);
3660b978350Sforsyth 	}
3670b978350Sforsyth 
3680b978350Sforsyth //	if(tkhaskeyfocus(tk))
3690b978350Sforsyth //		tkbox(i, focusr, tk->highlightwidth, tkgc(e, TkChighlightfgnd));
3700b978350Sforsyth 	tkdrawrelief(i, tk, ZP, bgnd, relief);
3710b978350Sforsyth 
3720b978350Sforsyth 	p.x = tk->act.x + orig.x;
3730b978350Sforsyth 	p.y = tk->act.y + orig.y;
3740b978350Sforsyth 	r = rectaddpt(r, p);
3750b978350Sforsyth 	draw(dst, r, i, nil, ZP);
3760b978350Sforsyth 
3770b978350Sforsyth 	return nil;
3780b978350Sforsyth }
3790b978350Sforsyth 
3800b978350Sforsyth void
tksizebutton(Tk * tk)3810b978350Sforsyth tksizebutton(Tk *tk)
3820b978350Sforsyth {
3830b978350Sforsyth 	int w, h;
3840b978350Sforsyth 	TkLabel *tkl;
3850b978350Sforsyth 
3860b978350Sforsyth 	tkl = TKobj(TkLabel, tk);
3870b978350Sforsyth 	if(tkl->anchor == 0)
3880b978350Sforsyth 		tkl->anchor = Tkcenter;
3890b978350Sforsyth 
3900b978350Sforsyth 	tksizelabel(tk);	/* text, bitmap or image, and highlight */
3910b978350Sforsyth 	w = tkl->w;
3920b978350Sforsyth 	h = tkl->h;
3930b978350Sforsyth 
3940b978350Sforsyth 	if((tk->type == TKcheckbutton || tk->type == TKradiobutton) && tkl->indicator != BoolF) {
3950b978350Sforsyth 		w += CheckSpace;
3960b978350Sforsyth 		if(h < CheckSpace)
3970b978350Sforsyth 			h = CheckSpace;
3980b978350Sforsyth 	}
3990b978350Sforsyth 	tkl->w = w;
4000b978350Sforsyth 	tkl->h = h;
4010b978350Sforsyth 	if((tk->flag & Tksetwidth) == 0)
4020b978350Sforsyth 		tk->req.width = w;
4030b978350Sforsyth 	if((tk->flag & Tksetheight) == 0)
4040b978350Sforsyth 		tk->req.height = h;
4050b978350Sforsyth }
4060b978350Sforsyth 
40737da2899SCharles.Forsyth int
tkbuttonmargin(Tk * tk)40837da2899SCharles.Forsyth tkbuttonmargin(Tk *tk)
40937da2899SCharles.Forsyth {
41037da2899SCharles.Forsyth 	TkLabel *tkl;
41137da2899SCharles.Forsyth 	tkl = TKobj(TkLabel, tk);
41237da2899SCharles.Forsyth 
41337da2899SCharles.Forsyth 	switch (tk->type) {
41437da2899SCharles.Forsyth 	case TKbutton:
41537da2899SCharles.Forsyth 		if (tkl->img != nil || tkl->bitmap != nil)
41637da2899SCharles.Forsyth 			return 0;
41737da2899SCharles.Forsyth 		return Textpadx+tk->highlightwidth;
41837da2899SCharles.Forsyth 	case TKcheckbutton:
41937da2899SCharles.Forsyth 	case TKradiobutton:
42037da2899SCharles.Forsyth 		return CheckButton + 2*CheckButtonBW + 2*ButtonBorder;
42137da2899SCharles.Forsyth 	}
4220b978350Sforsyth 	return tklabelmargin(tk);
4230b978350Sforsyth }
4240b978350Sforsyth 
4250b978350Sforsyth void
tkfreebutton(Tk * tk)4260b978350Sforsyth tkfreebutton(Tk *tk)
4270b978350Sforsyth {
4280b978350Sforsyth 	tkfreelabel(tk);
42937da2899SCharles.Forsyth }
43037da2899SCharles.Forsyth 
43137da2899SCharles.Forsyth static char*
tkbuttoncget(Tk * tk,char * arg,char ** val)43237da2899SCharles.Forsyth tkbuttoncget(Tk *tk, char *arg, char **val)
43337da2899SCharles.Forsyth {
43437da2899SCharles.Forsyth 	TkOptab tko[4];
43537da2899SCharles.Forsyth 	TkLabel *tkl = TKobj(TkLabel, tk);
43637da2899SCharles.Forsyth 
43737da2899SCharles.Forsyth 	tko[0].ptr = tk;
43837da2899SCharles.Forsyth 	tko[0].optab = tkgeneric;
43937da2899SCharles.Forsyth 	tko[1].ptr = tkl;
44037da2899SCharles.Forsyth 	tko[1].optab = tkbutopts;
44137da2899SCharles.Forsyth 	switch(tk->type){
44237da2899SCharles.Forsyth 	case TKcheckbutton:
44337da2899SCharles.Forsyth 		tko[2].ptr = tkl;
44437da2899SCharles.Forsyth 		tko[2].optab = tkcbopts;
44537da2899SCharles.Forsyth 		break;
44637da2899SCharles.Forsyth 	case TKradiobutton:
44737da2899SCharles.Forsyth 		tko[2].ptr = tkl;
44837da2899SCharles.Forsyth 		tko[2].optab = tkradopts;
44937da2899SCharles.Forsyth 		break;
45037da2899SCharles.Forsyth 	default:
45137da2899SCharles.Forsyth 		tko[2].ptr = nil;
45237da2899SCharles.Forsyth 		break;
45337da2899SCharles.Forsyth 	}
45437da2899SCharles.Forsyth 	tko[3].ptr = nil;
45537da2899SCharles.Forsyth 	return tkgencget(tko, arg, val, tk->env->top);
45637da2899SCharles.Forsyth }
45737da2899SCharles.Forsyth 
45837da2899SCharles.Forsyth static char*
tkbuttonconf(Tk * tk,char * arg,char ** val)45937da2899SCharles.Forsyth tkbuttonconf(Tk *tk, char *arg, char **val)
46037da2899SCharles.Forsyth {
46137da2899SCharles.Forsyth 	char *e;
46237da2899SCharles.Forsyth 	TkGeom g;
46337da2899SCharles.Forsyth 	int bd;
46437da2899SCharles.Forsyth 	TkOptab tko[4];
46537da2899SCharles.Forsyth 	TkVar *v;
46637da2899SCharles.Forsyth 	TkLabel *tkl = TKobj(TkLabel, tk);
46737da2899SCharles.Forsyth 
46837da2899SCharles.Forsyth 	tko[0].ptr = tk;
46937da2899SCharles.Forsyth 	tko[0].optab = tkgeneric;
47037da2899SCharles.Forsyth 	tko[1].ptr = tkl;
47137da2899SCharles.Forsyth 	tko[1].optab = tkbutopts;
47237da2899SCharles.Forsyth 	switch(tk->type){
47337da2899SCharles.Forsyth 	case TKcheckbutton:
47437da2899SCharles.Forsyth 		tko[2].ptr = tkl;
47537da2899SCharles.Forsyth 		tko[2].optab = tkcbopts;
47637da2899SCharles.Forsyth 		break;
47737da2899SCharles.Forsyth 	case TKradiobutton:
47837da2899SCharles.Forsyth 		tko[2].ptr = tkl;
47937da2899SCharles.Forsyth 		tko[2].optab = tkradopts;
48037da2899SCharles.Forsyth 		break;
48137da2899SCharles.Forsyth 	default:
48237da2899SCharles.Forsyth 		tko[2].ptr = nil;
48337da2899SCharles.Forsyth 		break;
48437da2899SCharles.Forsyth 	}
48537da2899SCharles.Forsyth 	tko[3].ptr = nil;
48637da2899SCharles.Forsyth 
48737da2899SCharles.Forsyth 	if(*arg == '\0')
48837da2899SCharles.Forsyth 		return tkconflist(tko, val);
48937da2899SCharles.Forsyth 
49037da2899SCharles.Forsyth 	g = tk->req;
49137da2899SCharles.Forsyth 	bd = tk->borderwidth;
49237da2899SCharles.Forsyth 	e = tkparse(tk->env->top, arg, tko, nil);
49337da2899SCharles.Forsyth 	tksizebutton(tk);
49437da2899SCharles.Forsyth 	tkgeomchg(tk, &g, bd);
49537da2899SCharles.Forsyth 
49637da2899SCharles.Forsyth 	tk->dirty = tkrect(tk, 1);
49737da2899SCharles.Forsyth 	tksettransparent(tk, istransparent(tk));
49837da2899SCharles.Forsyth 	/*
49937da2899SCharles.Forsyth 	 * XXX what happens if we're now disabled, but we were in
50037da2899SCharles.Forsyth 	 * active state before?
50137da2899SCharles.Forsyth 	 */
50237da2899SCharles.Forsyth 	if (tkl->variable != nil) {
50337da2899SCharles.Forsyth 		v = tkmkvar(tk->env->top, tkl->variable, 0);
50437da2899SCharles.Forsyth 		if (v != nil) {
50537da2899SCharles.Forsyth 			if (v->type != TkVstring) {
50637da2899SCharles.Forsyth 				e = TkNotvt;
50737da2899SCharles.Forsyth 				free(tkl->variable);
50837da2899SCharles.Forsyth 				tkl->variable = nil;
50937da2899SCharles.Forsyth 			}
51037da2899SCharles.Forsyth 			else
51137da2899SCharles.Forsyth 				tkvarchanged(tk, tkl->variable, v->value);
51237da2899SCharles.Forsyth 		}
51337da2899SCharles.Forsyth 	}
51437da2899SCharles.Forsyth 	return e;
51537da2899SCharles.Forsyth }
51637da2899SCharles.Forsyth 
51737da2899SCharles.Forsyth static int
istransparent(Tk * tk)51837da2899SCharles.Forsyth istransparent(Tk *tk)
51937da2899SCharles.Forsyth {
52037da2899SCharles.Forsyth 	TkEnv *e = tk->env;
52137da2899SCharles.Forsyth 	return (tkhasalpha(e, TkCbackgnd) || tkhasalpha(e, TkCselectbgnd) || tkhasalpha(e, TkCactivebgnd));
52237da2899SCharles.Forsyth }
52337da2899SCharles.Forsyth 
52437da2899SCharles.Forsyth static void
tkvarchanged(Tk * tk,char * var,char * val)52537da2899SCharles.Forsyth tkvarchanged(Tk *tk, char *var, char *val)
52637da2899SCharles.Forsyth {
52737da2899SCharles.Forsyth 	TkLabel *tkl;
52837da2899SCharles.Forsyth 	char *sval;
52937da2899SCharles.Forsyth 
53037da2899SCharles.Forsyth 	tkl = TKobj(TkLabel, tk);
53137da2899SCharles.Forsyth 	if (tkl->variable != nil && strcmp(tkl->variable, var) == 0) {
53237da2899SCharles.Forsyth 		sval = tkl->value;
53337da2899SCharles.Forsyth 		if (sval == nil)
53437da2899SCharles.Forsyth 			sval = tk->type == TKcheckbutton ? "1" : "";
53537da2899SCharles.Forsyth 		tkl->check = (strcmp(val, sval) == 0);
53637da2899SCharles.Forsyth 		tk->dirty = tkrect(tk, 1);
53737da2899SCharles.Forsyth 		tkdirty(tk);
53837da2899SCharles.Forsyth 	}
53937da2899SCharles.Forsyth }
54037da2899SCharles.Forsyth 
54137da2899SCharles.Forsyth static char*
tkbutton1p(Tk * tk,char * arg,char ** val)54237da2899SCharles.Forsyth tkbutton1p(Tk *tk, char *arg, char **val)
54337da2899SCharles.Forsyth {
54437da2899SCharles.Forsyth 	USED(arg);
54537da2899SCharles.Forsyth 	USED(val);
54637da2899SCharles.Forsyth 	if(tk->flag & Tkdisabled)
54737da2899SCharles.Forsyth 		return nil;
54837da2899SCharles.Forsyth 	tk->flag |= Tkactivated;
54937da2899SCharles.Forsyth 	tk->dirty = tkrect(tk, 1);
55037da2899SCharles.Forsyth 	tkdirty(tk);
55137da2899SCharles.Forsyth 	return nil;
55237da2899SCharles.Forsyth }
55337da2899SCharles.Forsyth 
55437da2899SCharles.Forsyth static char*
tkbutton1r(Tk * tk,char * arg,char ** val)55537da2899SCharles.Forsyth tkbutton1r(Tk *tk, char *arg, char **val)
55637da2899SCharles.Forsyth {
55737da2899SCharles.Forsyth 	char *e;
55837da2899SCharles.Forsyth 	Point p;
55937da2899SCharles.Forsyth 	Rectangle hitr;
56037da2899SCharles.Forsyth 
56137da2899SCharles.Forsyth 	USED(arg);
56237da2899SCharles.Forsyth 
56337da2899SCharles.Forsyth 	if(tk->flag & Tkdisabled)
56437da2899SCharles.Forsyth 		return nil;
56537da2899SCharles.Forsyth 	e = tkxyparse(tk, &arg, &p);
56637da2899SCharles.Forsyth 	if (e == nil) {
56737da2899SCharles.Forsyth 		hitr.min = ZP;
56837da2899SCharles.Forsyth 		hitr.max.x = tk->act.width + tk->borderwidth*2;
56937da2899SCharles.Forsyth 		hitr.max.y = tk->act.height + tk->borderwidth*2;
57037da2899SCharles.Forsyth 		if(ptinrect(p, hitr) && (tk->flag & Tkactivated))
57137da2899SCharles.Forsyth 			e = tkbuttoninvoke(tk, nil, val);
57237da2899SCharles.Forsyth 	}
57337da2899SCharles.Forsyth 	tk->flag &= ~Tkactivated;
57437da2899SCharles.Forsyth 	tk->dirty = tkrect(tk, 1);
57537da2899SCharles.Forsyth 	tkdirty(tk);
57637da2899SCharles.Forsyth 	return e;
57737da2899SCharles.Forsyth }
57837da2899SCharles.Forsyth 
57937da2899SCharles.Forsyth static char*
tkbuttonkey(Tk * tk,char * arg,char ** val)58037da2899SCharles.Forsyth tkbuttonkey(Tk *tk, char *arg, char **val)
58137da2899SCharles.Forsyth {
58237da2899SCharles.Forsyth 	int key;
58337da2899SCharles.Forsyth 
58437da2899SCharles.Forsyth 	if(tk->flag & Tkdisabled)
58537da2899SCharles.Forsyth 		return nil;
58637da2899SCharles.Forsyth 
587*48c2bcd8Sforsyth 	key = strtol(arg, nil, 0);
58837da2899SCharles.Forsyth 	if (key == '\n' || key ==' ')
58937da2899SCharles.Forsyth 		return tkbuttoninvoke(tk, nil, val);
59037da2899SCharles.Forsyth 	return nil;
59137da2899SCharles.Forsyth }
59237da2899SCharles.Forsyth 
59337da2899SCharles.Forsyth static char*
tkbuttontoggle(Tk * tk,char * arg,char ** val)59437da2899SCharles.Forsyth tkbuttontoggle(Tk *tk, char *arg, char **val)
59537da2899SCharles.Forsyth {
59637da2899SCharles.Forsyth 	char *e;
59737da2899SCharles.Forsyth 	TkLabel *tkl = TKobj(TkLabel, tk);
59837da2899SCharles.Forsyth 	char *v;
59937da2899SCharles.Forsyth 
60037da2899SCharles.Forsyth 	USED(arg);
60137da2899SCharles.Forsyth 	USED(val);
60237da2899SCharles.Forsyth 	if(tk->flag & Tkdisabled)
60337da2899SCharles.Forsyth 		return nil;
60437da2899SCharles.Forsyth 	tkl->check = !tkl->check;
60537da2899SCharles.Forsyth 	if (tkl->check)
60637da2899SCharles.Forsyth 		v = tkl->value ? tkl->value : "1";
60737da2899SCharles.Forsyth 	else
60837da2899SCharles.Forsyth 		v = tkl->offvalue ? tkl->offvalue : "0";
60937da2899SCharles.Forsyth 	e = tksetvar(tk->env->top, tkl->variable, v);
61037da2899SCharles.Forsyth 	tk->dirty = tkrect(tk, 0);
61137da2899SCharles.Forsyth 	return e;
61237da2899SCharles.Forsyth }
61337da2899SCharles.Forsyth 
61437da2899SCharles.Forsyth static char*
buttoninvoke(Tk * tk,char ** val)61537da2899SCharles.Forsyth buttoninvoke(Tk *tk, char **val)
61637da2899SCharles.Forsyth {
61737da2899SCharles.Forsyth 	char *e = nil;
61837da2899SCharles.Forsyth 	TkTop *top;
61937da2899SCharles.Forsyth 	TkLabel *tkl = TKobj(TkLabel, tk);
62037da2899SCharles.Forsyth 
62137da2899SCharles.Forsyth 	top = tk->env->top;
62237da2899SCharles.Forsyth 	if (tk->type == TKcheckbutton)
62337da2899SCharles.Forsyth 		e = tkbuttontoggle(tk, "", val);
62437da2899SCharles.Forsyth 	else if (tk->type == TKradiobutton)
62537da2899SCharles.Forsyth 		e = tksetvar(top, tkl->variable, tkl->value);
62637da2899SCharles.Forsyth 	if(e != nil)
62737da2899SCharles.Forsyth 		return e;
62837da2899SCharles.Forsyth 	if(tkl->command != nil)
62937da2899SCharles.Forsyth 		return tkexec(tk->env->top, tkl->command, val);
63037da2899SCharles.Forsyth 	return nil;
63137da2899SCharles.Forsyth }
63237da2899SCharles.Forsyth 
63337da2899SCharles.Forsyth static void
cancelinvoke(Tk * tk,void * v,int cancelled)63437da2899SCharles.Forsyth cancelinvoke(Tk *tk, void *v, int cancelled)
63537da2899SCharles.Forsyth {
63637da2899SCharles.Forsyth 	int unset;
63737da2899SCharles.Forsyth 	USED(cancelled);
63837da2899SCharles.Forsyth 	USED(v);
63937da2899SCharles.Forsyth 
64037da2899SCharles.Forsyth 	/* if it was active before then leave it active unless cleared since */
64137da2899SCharles.Forsyth 	if (v)
64237da2899SCharles.Forsyth 		unset = 0;
64337da2899SCharles.Forsyth 	else
64437da2899SCharles.Forsyth 		unset = Tkactive;
64537da2899SCharles.Forsyth 	unset &= (tk->flag & Tkactive);
64637da2899SCharles.Forsyth 	unset |= Tkactivated;
64737da2899SCharles.Forsyth 	tk->flag &= ~unset;
64837da2899SCharles.Forsyth 	tksettransparent(tk, istransparent(tk));
64937da2899SCharles.Forsyth 	tk->dirty = tkrect(tk, 1);
65037da2899SCharles.Forsyth 	tkdirty(tk);
65137da2899SCharles.Forsyth 	tkupdate(tk->env->top);
65237da2899SCharles.Forsyth }
65337da2899SCharles.Forsyth 
65437da2899SCharles.Forsyth char*
tkbuttoninvoke(Tk * tk,char * arg,char ** val)65537da2899SCharles.Forsyth tkbuttoninvoke(Tk *tk, char *arg, char **val)
65637da2899SCharles.Forsyth {
65737da2899SCharles.Forsyth 	char *e;
65837da2899SCharles.Forsyth 	USED(arg);
65937da2899SCharles.Forsyth 
66037da2899SCharles.Forsyth 	if(tk->flag & Tkdisabled)
66137da2899SCharles.Forsyth 		return nil;
66237da2899SCharles.Forsyth 	e = buttoninvoke(tk, val);
66337da2899SCharles.Forsyth 	if (e == nil && tk->type == TKbutton && !(tk->flag & Tkactivated)) {
66437da2899SCharles.Forsyth 		tkrepeat(tk, cancelinvoke, (void*)(tk->flag&Tkactive), InvokePause, 0);
66537da2899SCharles.Forsyth 		tk->flag |= Tkactivated | Tkactive;
66637da2899SCharles.Forsyth 		tksettransparent(tk, istransparent(tk));
66737da2899SCharles.Forsyth 		tk->dirty = tkrect(tk, 1);
66837da2899SCharles.Forsyth 		tkdirty(tk);
66937da2899SCharles.Forsyth 		tkupdate(tk->env->top);
67037da2899SCharles.Forsyth 	}
67137da2899SCharles.Forsyth 	return e;
67237da2899SCharles.Forsyth }
67337da2899SCharles.Forsyth 
67437da2899SCharles.Forsyth static char*
tkbuttonselect(Tk * tk,char * arg,char ** val)67537da2899SCharles.Forsyth tkbuttonselect(Tk *tk, char *arg, char **val)
67637da2899SCharles.Forsyth {
67737da2899SCharles.Forsyth 	char *e, *v;
67837da2899SCharles.Forsyth 	TkLabel *tkl = TKobj(TkLabel, tk);
67937da2899SCharles.Forsyth 
68037da2899SCharles.Forsyth 	USED(arg);
68137da2899SCharles.Forsyth 	USED(val);
68237da2899SCharles.Forsyth 	if (tk->type == TKradiobutton)
68337da2899SCharles.Forsyth 		v = tkl->value;
68437da2899SCharles.Forsyth 	else if (tk->type == TKcheckbutton) {
68537da2899SCharles.Forsyth 		v = tkl->value ? tkl->value : "1";
68637da2899SCharles.Forsyth 		tkl->check = 1;
68737da2899SCharles.Forsyth 		tk->dirty = tkrect(tk, 0);
68837da2899SCharles.Forsyth 	} else
68937da2899SCharles.Forsyth 		v = nil;
69037da2899SCharles.Forsyth 	e = tksetvar(tk->env->top, tkl->variable, v);
69137da2899SCharles.Forsyth 	if(e != nil)
69237da2899SCharles.Forsyth 		return e;
69337da2899SCharles.Forsyth 	return nil;
69437da2899SCharles.Forsyth }
69537da2899SCharles.Forsyth 
69637da2899SCharles.Forsyth static char*
tkbuttondeselect(Tk * tk,char * arg,char ** val)69737da2899SCharles.Forsyth tkbuttondeselect(Tk *tk, char *arg, char **val)
69837da2899SCharles.Forsyth {
69937da2899SCharles.Forsyth 	char *e, *v;
70037da2899SCharles.Forsyth 	TkLabel *tkl = TKobj(TkLabel, tk);
70137da2899SCharles.Forsyth 
70237da2899SCharles.Forsyth 	USED(arg);
70337da2899SCharles.Forsyth 	USED(val);
70437da2899SCharles.Forsyth 
70537da2899SCharles.Forsyth 	if (tk->type == TKcheckbutton) {
70637da2899SCharles.Forsyth 		v = tkl->offvalue ? tkl->offvalue : "0";
70737da2899SCharles.Forsyth 		tkl->check = 0;
70837da2899SCharles.Forsyth 		tk->dirty = tkrect(tk, 0);
70937da2899SCharles.Forsyth 	} else
71037da2899SCharles.Forsyth 		v = nil;
71137da2899SCharles.Forsyth 
71237da2899SCharles.Forsyth 	e = tksetvar(tk->env->top, tkl->variable, v);
71337da2899SCharles.Forsyth 	if(e != nil)
71437da2899SCharles.Forsyth 		return e;
71537da2899SCharles.Forsyth 	return nil;
71637da2899SCharles.Forsyth }
71737da2899SCharles.Forsyth 
71837da2899SCharles.Forsyth static
71937da2899SCharles.Forsyth TkCmdtab tkbuttoncmd[] =
72037da2899SCharles.Forsyth {
72137da2899SCharles.Forsyth 	"cget",			tkbuttoncget,
72237da2899SCharles.Forsyth 	"configure",		tkbuttonconf,
72337da2899SCharles.Forsyth 	"invoke",		tkbuttoninvoke,
72437da2899SCharles.Forsyth 	"tkButton1P",		tkbutton1p,
72537da2899SCharles.Forsyth 	"tkButton1R",		tkbutton1r,
72637da2899SCharles.Forsyth 	"tkButtonKey",		tkbuttonkey,
72737da2899SCharles.Forsyth 	nil
72837da2899SCharles.Forsyth };
72937da2899SCharles.Forsyth 
73037da2899SCharles.Forsyth static
73137da2899SCharles.Forsyth TkCmdtab tkchkbuttoncmd[] =
73237da2899SCharles.Forsyth {
73337da2899SCharles.Forsyth 	"cget",			tkbuttoncget,
73437da2899SCharles.Forsyth 	"configure",		tkbuttonconf,
73537da2899SCharles.Forsyth 	"invoke",		tkbuttoninvoke,
73637da2899SCharles.Forsyth 	"select",		tkbuttonselect,
73737da2899SCharles.Forsyth 	"deselect",		tkbuttondeselect,
73837da2899SCharles.Forsyth 	"toggle",		tkbuttontoggle,
73937da2899SCharles.Forsyth 	"tkButtonKey",		tkbuttonkey,
74037da2899SCharles.Forsyth 	nil
74137da2899SCharles.Forsyth };
74237da2899SCharles.Forsyth 
74337da2899SCharles.Forsyth static
74437da2899SCharles.Forsyth TkCmdtab tkradbuttoncmd[] =
74537da2899SCharles.Forsyth {
74637da2899SCharles.Forsyth 	"cget",			tkbuttoncget,
74737da2899SCharles.Forsyth 	"configure",		tkbuttonconf,
74837da2899SCharles.Forsyth 	"invoke",		tkbuttoninvoke,
74937da2899SCharles.Forsyth 	"select",		tkbuttonselect,
75037da2899SCharles.Forsyth 	"deselect",		tkbuttondeselect,
75137da2899SCharles.Forsyth 	"tkButtonKey",		tkbuttonkey,
75237da2899SCharles.Forsyth 	nil
75337da2899SCharles.Forsyth };
75437da2899SCharles.Forsyth 
75537da2899SCharles.Forsyth TkMethod buttonmethod = {
75637da2899SCharles.Forsyth 	"button",
75737da2899SCharles.Forsyth 	tkbuttoncmd,
7580b978350Sforsyth 	tkfreebutton,
7590b978350Sforsyth 	tkdrawbutton,
76037da2899SCharles.Forsyth 	nil,
76137da2899SCharles.Forsyth 	tklabelgetimgs
76237da2899SCharles.Forsyth };
76337da2899SCharles.Forsyth 
76437da2899SCharles.Forsyth TkMethod checkbuttonmethod = {
76537da2899SCharles.Forsyth 	"checkbutton",
76637da2899SCharles.Forsyth 	tkchkbuttoncmd,
7670b978350Sforsyth 	tkfreebutton,
7680b978350Sforsyth 	tkdrawbutton,
76937da2899SCharles.Forsyth 	nil,
77037da2899SCharles.Forsyth 	tklabelgetimgs,
77137da2899SCharles.Forsyth 	nil,
77237da2899SCharles.Forsyth 	nil,
77337da2899SCharles.Forsyth 	nil,
77437da2899SCharles.Forsyth 	nil,
77537da2899SCharles.Forsyth 	nil,
77637da2899SCharles.Forsyth 	nil,
77737da2899SCharles.Forsyth 	tkvarchanged
77837da2899SCharles.Forsyth };
77937da2899SCharles.Forsyth 
78037da2899SCharles.Forsyth TkMethod radiobuttonmethod = {
78137da2899SCharles.Forsyth 	"radiobutton",
78237da2899SCharles.Forsyth 	tkradbuttoncmd,
7830b978350Sforsyth 	tkfreebutton,
7840b978350Sforsyth 	tkdrawbutton,
78537da2899SCharles.Forsyth 	nil,
78637da2899SCharles.Forsyth 	nil,
78737da2899SCharles.Forsyth 	nil,
78837da2899SCharles.Forsyth 	nil,
78937da2899SCharles.Forsyth 	nil,
79037da2899SCharles.Forsyth 	nil,
79137da2899SCharles.Forsyth 	nil,
79237da2899SCharles.Forsyth 	nil,
79337da2899SCharles.Forsyth 	tkvarchanged
79437da2899SCharles.Forsyth };
795