137da2899SCharles.Forsyth #include "lib9.h"
237da2899SCharles.Forsyth #include "draw.h"
337da2899SCharles.Forsyth #include "tk.h"
437da2899SCharles.Forsyth #include <kernel.h>
537da2899SCharles.Forsyth #include <interp.h>
637da2899SCharles.Forsyth
737da2899SCharles.Forsyth enum
837da2899SCharles.Forsyth {
937da2899SCharles.Forsyth Cmask,
1037da2899SCharles.Forsyth Cctl,
1137da2899SCharles.Forsyth Ckey,
1237da2899SCharles.Forsyth Cbp,
1337da2899SCharles.Forsyth Cbr,
1437da2899SCharles.Forsyth };
1537da2899SCharles.Forsyth
1637da2899SCharles.Forsyth struct
1737da2899SCharles.Forsyth {
1837da2899SCharles.Forsyth char* event;
1937da2899SCharles.Forsyth int mask;
2037da2899SCharles.Forsyth int action;
2137da2899SCharles.Forsyth } etab[] =
2237da2899SCharles.Forsyth {
2337da2899SCharles.Forsyth "Motion", TkMotion, Cmask,
2437da2899SCharles.Forsyth "Double", TkDouble, Cmask,
2537da2899SCharles.Forsyth "Map", TkMap, Cmask,
2637da2899SCharles.Forsyth "Unmap", TkUnmap, Cmask,
2737da2899SCharles.Forsyth "Destroy", TkDestroy, Cmask,
2837da2899SCharles.Forsyth "Enter", TkEnter, Cmask,
2937da2899SCharles.Forsyth "Leave", TkLeave, Cmask,
3037da2899SCharles.Forsyth "FocusIn", TkFocusin, Cmask,
3137da2899SCharles.Forsyth "FocusOut", TkFocusout, Cmask,
3237da2899SCharles.Forsyth "Configure", TkConfigure, Cmask,
3337da2899SCharles.Forsyth "Control", 0, Cctl,
3437da2899SCharles.Forsyth "Key", 0, Ckey,
3537da2899SCharles.Forsyth "KeyPress", 0, Ckey,
3637da2899SCharles.Forsyth "Button", 0, Cbp,
3737da2899SCharles.Forsyth "ButtonPress", 0, Cbp,
3837da2899SCharles.Forsyth "ButtonRelease", 0, Cbr,
3937da2899SCharles.Forsyth };
4037da2899SCharles.Forsyth
4137da2899SCharles.Forsyth static
4237da2899SCharles.Forsyth TkOption tkcurop[] =
4337da2899SCharles.Forsyth {
4437da2899SCharles.Forsyth "x", OPTdist, O(TkCursor, p.x), nil,
4537da2899SCharles.Forsyth "y", OPTdist, O(TkCursor, p.y), nil,
4637da2899SCharles.Forsyth "bitmap", OPTbmap, O(TkCursor, bit), nil,
4737da2899SCharles.Forsyth "image", OPTimag, O(TkCursor, img), nil,
4837da2899SCharles.Forsyth "default", OPTbool, O(TkCursor, def), nil,
4937da2899SCharles.Forsyth nil
5037da2899SCharles.Forsyth };
5137da2899SCharles.Forsyth
5237da2899SCharles.Forsyth static
5337da2899SCharles.Forsyth TkOption focusopts[] = {
5437da2899SCharles.Forsyth "global", OPTbool, 0, nil,
5537da2899SCharles.Forsyth nil
5637da2899SCharles.Forsyth };
5737da2899SCharles.Forsyth
5837da2899SCharles.Forsyth static char*
tkseqitem(char * buf,char * arg)5937da2899SCharles.Forsyth tkseqitem(char *buf, char *arg)
6037da2899SCharles.Forsyth {
6137da2899SCharles.Forsyth while(*arg && (*arg == ' ' || *arg == '-'))
6237da2899SCharles.Forsyth arg++;
6337da2899SCharles.Forsyth while(*arg && *arg != ' ' && *arg != '-' && *arg != '>')
6437da2899SCharles.Forsyth *buf++ = *arg++;
6537da2899SCharles.Forsyth *buf = '\0';
6637da2899SCharles.Forsyth return arg;
6737da2899SCharles.Forsyth }
6837da2899SCharles.Forsyth
6937da2899SCharles.Forsyth static char*
tkseqkey(Rune * r,char * arg)7037da2899SCharles.Forsyth tkseqkey(Rune *r, char *arg)
7137da2899SCharles.Forsyth {
7237da2899SCharles.Forsyth char *narg;
7337da2899SCharles.Forsyth
7437da2899SCharles.Forsyth while(*arg && (*arg == ' ' || *arg == '-'))
7537da2899SCharles.Forsyth arg++;
7637da2899SCharles.Forsyth if (*arg == '\\') {
7737da2899SCharles.Forsyth if (*++arg == '\0') {
7837da2899SCharles.Forsyth *r = 0;
7937da2899SCharles.Forsyth return arg;
8037da2899SCharles.Forsyth }
8137da2899SCharles.Forsyth } else if (*arg == '\0' || *arg == '>' || *arg == '-') {
8237da2899SCharles.Forsyth *r = 0;
8337da2899SCharles.Forsyth return arg;
8437da2899SCharles.Forsyth }
8537da2899SCharles.Forsyth narg = arg + chartorune(r, arg);
8637da2899SCharles.Forsyth return narg;
8737da2899SCharles.Forsyth }
8837da2899SCharles.Forsyth
8937da2899SCharles.Forsyth int
tkseqparse(char * seq)9037da2899SCharles.Forsyth tkseqparse(char *seq)
9137da2899SCharles.Forsyth {
9237da2899SCharles.Forsyth Rune r;
9337da2899SCharles.Forsyth int i, event;
9437da2899SCharles.Forsyth char *buf;
9537da2899SCharles.Forsyth
9637da2899SCharles.Forsyth buf = mallocz(Tkmaxitem, 0);
9737da2899SCharles.Forsyth if(buf == nil)
9837da2899SCharles.Forsyth return -1;
9937da2899SCharles.Forsyth
10037da2899SCharles.Forsyth event = 0;
10137da2899SCharles.Forsyth
10237da2899SCharles.Forsyth while(*seq && *seq != '>') {
10337da2899SCharles.Forsyth seq = tkseqitem(buf, seq);
10437da2899SCharles.Forsyth
10537da2899SCharles.Forsyth for(i = 0; i < nelem(etab); i++)
10637da2899SCharles.Forsyth if(strcmp(buf, etab[i].event) == 0)
10737da2899SCharles.Forsyth break;
10837da2899SCharles.Forsyth
10937da2899SCharles.Forsyth if(i >= nelem(etab)) {
11037da2899SCharles.Forsyth seq = tkextnparseseq(buf, seq, &event);
11137da2899SCharles.Forsyth if (seq == nil) {
11237da2899SCharles.Forsyth free(buf);
11337da2899SCharles.Forsyth return -1;
11437da2899SCharles.Forsyth }
11537da2899SCharles.Forsyth continue;
11637da2899SCharles.Forsyth }
11737da2899SCharles.Forsyth
11837da2899SCharles.Forsyth
11937da2899SCharles.Forsyth switch(etab[i].action) {
12037da2899SCharles.Forsyth case Cmask:
12137da2899SCharles.Forsyth event |= etab[i].mask;
12237da2899SCharles.Forsyth break;
12337da2899SCharles.Forsyth case Cctl:
12437da2899SCharles.Forsyth seq = tkseqkey(&r, seq);
12537da2899SCharles.Forsyth if(r == 0) {
12637da2899SCharles.Forsyth free(buf);
12737da2899SCharles.Forsyth return -1;
12837da2899SCharles.Forsyth }
12937da2899SCharles.Forsyth if(r <= '~')
13037da2899SCharles.Forsyth r &= 0x1f;
13137da2899SCharles.Forsyth event |= TkKey|TKKEY(r);
13237da2899SCharles.Forsyth break;
13337da2899SCharles.Forsyth case Ckey:
13437da2899SCharles.Forsyth seq = tkseqkey(&r, seq);
13537da2899SCharles.Forsyth if(r != 0)
13637da2899SCharles.Forsyth event |= TKKEY(r);
13737da2899SCharles.Forsyth event |= TkKey;
13837da2899SCharles.Forsyth break;
13937da2899SCharles.Forsyth case Cbp:
14037da2899SCharles.Forsyth seq = tkseqitem(buf, seq);
14137da2899SCharles.Forsyth switch(buf[0]) {
14237da2899SCharles.Forsyth default:
14337da2899SCharles.Forsyth free(buf);
14437da2899SCharles.Forsyth return -1;
14537da2899SCharles.Forsyth case '\0':
14637da2899SCharles.Forsyth event |= TkEpress;
14737da2899SCharles.Forsyth break;
14837da2899SCharles.Forsyth case '1':
14937da2899SCharles.Forsyth event |= TkButton1P;
15037da2899SCharles.Forsyth break;
15137da2899SCharles.Forsyth case '2':
15237da2899SCharles.Forsyth event |= TkButton2P;
15337da2899SCharles.Forsyth break;
15437da2899SCharles.Forsyth case '3':
15537da2899SCharles.Forsyth event |= TkButton3P;
15637da2899SCharles.Forsyth break;
15737da2899SCharles.Forsyth case '4':
15837da2899SCharles.Forsyth event |= TkButton4P;
15937da2899SCharles.Forsyth break;
16037da2899SCharles.Forsyth case '5':
16137da2899SCharles.Forsyth event |= TkButton5P;
16237da2899SCharles.Forsyth break;
16337da2899SCharles.Forsyth case '6':
16437da2899SCharles.Forsyth event |= TkButton6P;
16537da2899SCharles.Forsyth break;
16637da2899SCharles.Forsyth }
16737da2899SCharles.Forsyth break;
16837da2899SCharles.Forsyth case Cbr:
16937da2899SCharles.Forsyth seq = tkseqitem(buf, seq);
17037da2899SCharles.Forsyth switch(buf[0]) {
17137da2899SCharles.Forsyth default:
17237da2899SCharles.Forsyth free(buf);
17337da2899SCharles.Forsyth return -1;
17437da2899SCharles.Forsyth case '\0':
17537da2899SCharles.Forsyth event |= TkErelease;
17637da2899SCharles.Forsyth break;
17737da2899SCharles.Forsyth case '1':
17837da2899SCharles.Forsyth event |= TkButton1R;
17937da2899SCharles.Forsyth break;
18037da2899SCharles.Forsyth case '2':
18137da2899SCharles.Forsyth event |= TkButton2R;
18237da2899SCharles.Forsyth break;
18337da2899SCharles.Forsyth case '3':
18437da2899SCharles.Forsyth event |= TkButton3R;
18537da2899SCharles.Forsyth break;
18637da2899SCharles.Forsyth case '4':
18737da2899SCharles.Forsyth event |= TkButton4R;
18837da2899SCharles.Forsyth break;
18937da2899SCharles.Forsyth case '5':
19037da2899SCharles.Forsyth event |= TkButton5R;
19137da2899SCharles.Forsyth break;
19237da2899SCharles.Forsyth case '6':
19337da2899SCharles.Forsyth event |= TkButton6R;
19437da2899SCharles.Forsyth break;
19537da2899SCharles.Forsyth }
19637da2899SCharles.Forsyth break;
19737da2899SCharles.Forsyth }
19837da2899SCharles.Forsyth }
19937da2899SCharles.Forsyth free(buf);
20037da2899SCharles.Forsyth return event;
20137da2899SCharles.Forsyth }
20237da2899SCharles.Forsyth
20337da2899SCharles.Forsyth void
tkcmdbind(Tk * tk,int event,char * s,void * data)20437da2899SCharles.Forsyth tkcmdbind(Tk *tk, int event, char *s, void *data)
20537da2899SCharles.Forsyth {
20637da2899SCharles.Forsyth Point p;
20737da2899SCharles.Forsyth TkMouse *m;
20837da2899SCharles.Forsyth TkGeom *g;
20937da2899SCharles.Forsyth int v, len;
21037da2899SCharles.Forsyth char *e, *c, *ec, *cmd;
21137da2899SCharles.Forsyth TkTop *t;
21237da2899SCharles.Forsyth
21337da2899SCharles.Forsyth if(s == nil)
21437da2899SCharles.Forsyth return;
21537da2899SCharles.Forsyth cmd = malloc(2*Tkmaxitem);
21637da2899SCharles.Forsyth if (cmd == nil) {
21737da2899SCharles.Forsyth print("tk: bind command \"%s\": %s\n",
21837da2899SCharles.Forsyth tk->name ? tk->name->name : "(noname)", TkNomem);
21937da2899SCharles.Forsyth return;
22037da2899SCharles.Forsyth }
22137da2899SCharles.Forsyth
22237da2899SCharles.Forsyth m = (TkMouse*)data;
22337da2899SCharles.Forsyth c = cmd;
22437da2899SCharles.Forsyth ec = cmd+2*Tkmaxitem-1;
22537da2899SCharles.Forsyth while(*s && c < ec) {
22637da2899SCharles.Forsyth if(*s != '%') {
22737da2899SCharles.Forsyth *c++ = *s++;
22837da2899SCharles.Forsyth continue;
22937da2899SCharles.Forsyth }
23037da2899SCharles.Forsyth s++;
23137da2899SCharles.Forsyth len = ec-c;
23237da2899SCharles.Forsyth switch(*s++) {
23337da2899SCharles.Forsyth def:
23437da2899SCharles.Forsyth default:
23537da2899SCharles.Forsyth *c++ = s[-1];
23637da2899SCharles.Forsyth break;
23737da2899SCharles.Forsyth case '%':
23837da2899SCharles.Forsyth *c++ = '%';
23937da2899SCharles.Forsyth break;
24037da2899SCharles.Forsyth case 'b':
24137da2899SCharles.Forsyth v = 0;
24237da2899SCharles.Forsyth if (!(event & TkKey)) {
24337da2899SCharles.Forsyth if(event & (TkButton1P|TkButton1R))
24437da2899SCharles.Forsyth v = 1;
245c9ccdbd5Sforsyth else if(event & (TkButton2P|TkButton2R))
24637da2899SCharles.Forsyth v = 2;
247c9ccdbd5Sforsyth else if(event & (TkButton3P|TkButton3R))
24837da2899SCharles.Forsyth v = 3;
24937da2899SCharles.Forsyth }
25037da2899SCharles.Forsyth c += snprint(c, len, "%d", v);
25137da2899SCharles.Forsyth break;
25237da2899SCharles.Forsyth case 'h':
25337da2899SCharles.Forsyth if((event & TkConfigure) == 0)
25437da2899SCharles.Forsyth goto def;
25537da2899SCharles.Forsyth g = (TkGeom*)data;
25637da2899SCharles.Forsyth c += snprint(c, len, "%d", g->height);
25737da2899SCharles.Forsyth break;
25837da2899SCharles.Forsyth case 's':
25937da2899SCharles.Forsyth if((event & TkKey))
26037da2899SCharles.Forsyth c += snprint(c, len, "%d", TKKEY(event));
261c9ccdbd5Sforsyth else if((event & (TkEmouse|TkEnter)))
26237da2899SCharles.Forsyth c += snprint(c, len, "%d", m->b);
263c9ccdbd5Sforsyth else if((event & TkFocusin))
26437da2899SCharles.Forsyth c += snprint(c, len, "%d", (int)data);
26537da2899SCharles.Forsyth else
26637da2899SCharles.Forsyth goto def;
26737da2899SCharles.Forsyth break;
26837da2899SCharles.Forsyth case 'w':
26937da2899SCharles.Forsyth if((event & TkConfigure) == 0)
27037da2899SCharles.Forsyth goto def;
27137da2899SCharles.Forsyth g = (TkGeom*)data;
27237da2899SCharles.Forsyth c += snprint(c, len, "%d", g->width);
27337da2899SCharles.Forsyth break;
27437da2899SCharles.Forsyth case 'x': /* Relative mouse coords */
27537da2899SCharles.Forsyth case 'y':
27637da2899SCharles.Forsyth if((event & TkKey) || (event & (TkEmouse|TkEnter)) == 0)
27737da2899SCharles.Forsyth goto def;
27837da2899SCharles.Forsyth p = tkposn(tk);
27937da2899SCharles.Forsyth if(s[-1] == 'x')
28037da2899SCharles.Forsyth v = m->x - p.x;
28137da2899SCharles.Forsyth else
28237da2899SCharles.Forsyth v = m->y - p.y;
28337da2899SCharles.Forsyth c += snprint(c, len, "%d", v - tk->borderwidth);
28437da2899SCharles.Forsyth break;
28537da2899SCharles.Forsyth case 'X': /* Absolute mouse coords */
28637da2899SCharles.Forsyth case 'Y':
28737da2899SCharles.Forsyth if((event & TkKey) || (event & TkEmouse) == 0)
28837da2899SCharles.Forsyth goto def;
28937da2899SCharles.Forsyth c += snprint(c, len, "%d", s[-1] == 'X' ? m->x : m->y);
29037da2899SCharles.Forsyth break;
29137da2899SCharles.Forsyth case 'A':
29237da2899SCharles.Forsyth if((event & TkKey) == 0)
29337da2899SCharles.Forsyth goto def;
29437da2899SCharles.Forsyth v = TKKEY(event);
29537da2899SCharles.Forsyth if(v == '{' || v == '}' || v == '\\')
29637da2899SCharles.Forsyth c += snprint(c, len, "\\%C", v);
297c9ccdbd5Sforsyth else if(v != '\0')
29837da2899SCharles.Forsyth c += snprint(c, len, "%C", v);
29937da2899SCharles.Forsyth break;
30037da2899SCharles.Forsyth case 'K':
30137da2899SCharles.Forsyth if((event & TkKey) == 0)
30237da2899SCharles.Forsyth goto def;
30337da2899SCharles.Forsyth c += snprint(c, len, "%.4X", TKKEY(event));
30437da2899SCharles.Forsyth break;
30537da2899SCharles.Forsyth case 'W':
30637da2899SCharles.Forsyth if (tk->name != nil)
30737da2899SCharles.Forsyth c += snprint(c, len, "%s", tk->name->name);
30837da2899SCharles.Forsyth break;
30937da2899SCharles.Forsyth }
31037da2899SCharles.Forsyth }
31137da2899SCharles.Forsyth *c = '\0';
31237da2899SCharles.Forsyth e = nil;
31337da2899SCharles.Forsyth t = tk->env->top;
31437da2899SCharles.Forsyth t->execdepth = 0;
31537da2899SCharles.Forsyth if(cmd[0] == '|')
31637da2899SCharles.Forsyth tkexec(t, cmd+1, nil);
317c9ccdbd5Sforsyth else if(cmd[0] != '\0')
31837da2899SCharles.Forsyth e = tkexec(t, cmd, nil);
31937da2899SCharles.Forsyth t->execdepth = -1;
32037da2899SCharles.Forsyth
32137da2899SCharles.Forsyth if(e == nil) {
32237da2899SCharles.Forsyth free(cmd);
32337da2899SCharles.Forsyth return;
32437da2899SCharles.Forsyth }
32537da2899SCharles.Forsyth
32637da2899SCharles.Forsyth if(tk->name != nil){
32737da2899SCharles.Forsyth char *s;
32837da2899SCharles.Forsyth
32937da2899SCharles.Forsyth if(t->errx[0] != '\0')
33037da2899SCharles.Forsyth s = tkerrstr(t, e);
33137da2899SCharles.Forsyth else
33237da2899SCharles.Forsyth s = e;
33337da2899SCharles.Forsyth print("tk: bind command \"%s\": %s: %s\n", tk->name->name, cmd, s);
33437da2899SCharles.Forsyth if(s != e)
33537da2899SCharles.Forsyth free(s);
33637da2899SCharles.Forsyth }
33737da2899SCharles.Forsyth free(cmd);
33837da2899SCharles.Forsyth }
33937da2899SCharles.Forsyth
34037da2899SCharles.Forsyth char*
tkbind(TkTop * t,char * arg,char ** ret)34137da2899SCharles.Forsyth tkbind(TkTop *t, char *arg, char **ret)
34237da2899SCharles.Forsyth {
34337da2899SCharles.Forsyth Rune r;
34437da2899SCharles.Forsyth Tk *tk;
34537da2899SCharles.Forsyth TkAction **ap;
34637da2899SCharles.Forsyth int i, mode, event;
34737da2899SCharles.Forsyth char *cmd, *tag, *seq;
34837da2899SCharles.Forsyth char *e;
34937da2899SCharles.Forsyth
35037da2899SCharles.Forsyth USED(ret);
35137da2899SCharles.Forsyth
35237da2899SCharles.Forsyth tag = mallocz(Tkmaxitem, 0);
35337da2899SCharles.Forsyth if(tag == nil)
35437da2899SCharles.Forsyth return TkNomem;
35537da2899SCharles.Forsyth seq = mallocz(Tkmaxitem, 0);
35637da2899SCharles.Forsyth if(seq == nil) {
35737da2899SCharles.Forsyth free(tag);
35837da2899SCharles.Forsyth return TkNomem;
35937da2899SCharles.Forsyth }
36037da2899SCharles.Forsyth
36137da2899SCharles.Forsyth arg = tkword(t, arg, tag, tag+Tkmaxitem, nil);
36237da2899SCharles.Forsyth if(tag[0] == '\0') {
36337da2899SCharles.Forsyth e = TkBadtg;
36437da2899SCharles.Forsyth goto err;
36537da2899SCharles.Forsyth }
36637da2899SCharles.Forsyth
36737da2899SCharles.Forsyth arg = tkword(t, arg, seq, seq+Tkmaxitem, nil);
36837da2899SCharles.Forsyth if(seq[0] == '<') {
36937da2899SCharles.Forsyth event = tkseqparse(seq+1);
37037da2899SCharles.Forsyth if(event == -1) {
37137da2899SCharles.Forsyth e = TkBadsq;
37237da2899SCharles.Forsyth goto err;
37337da2899SCharles.Forsyth }
37437da2899SCharles.Forsyth }
37537da2899SCharles.Forsyth else {
37637da2899SCharles.Forsyth chartorune(&r, seq);
37737da2899SCharles.Forsyth event = TkKey | r;
37837da2899SCharles.Forsyth }
37937da2899SCharles.Forsyth if(event == 0) {
38037da2899SCharles.Forsyth e = TkBadsq;
38137da2899SCharles.Forsyth goto err;
38237da2899SCharles.Forsyth }
38337da2899SCharles.Forsyth
38437da2899SCharles.Forsyth arg = tkskip(arg, " \t");
38537da2899SCharles.Forsyth
38637da2899SCharles.Forsyth mode = TkArepl;
38737da2899SCharles.Forsyth if(*arg == '+') {
38837da2899SCharles.Forsyth mode = TkAadd;
38937da2899SCharles.Forsyth arg++;
39037da2899SCharles.Forsyth }
39137da2899SCharles.Forsyth else if(*arg == '-'){
39237da2899SCharles.Forsyth mode = TkAsub;
39337da2899SCharles.Forsyth arg++;
39437da2899SCharles.Forsyth }
39537da2899SCharles.Forsyth
39637da2899SCharles.Forsyth if(*arg == '{') {
39737da2899SCharles.Forsyth cmd = tkskip(arg+1, " \t");
39837da2899SCharles.Forsyth if(*cmd == '}') {
39937da2899SCharles.Forsyth tk = tklook(t, tag, 0);
40037da2899SCharles.Forsyth if(tk == nil) {
40137da2899SCharles.Forsyth for(i = 0; ; i++) {
40237da2899SCharles.Forsyth if(i >= TKwidgets) {
40337da2899SCharles.Forsyth e = TkBadwp;
40437da2899SCharles.Forsyth tkerr(t, tag);
40537da2899SCharles.Forsyth goto err;
40637da2899SCharles.Forsyth }
40737da2899SCharles.Forsyth if(strcmp(tag, tkmethod[i]->name) == 0) {
40837da2899SCharles.Forsyth ap = &(t->binds[i]);
40937da2899SCharles.Forsyth break;
41037da2899SCharles.Forsyth }
41137da2899SCharles.Forsyth }
41237da2899SCharles.Forsyth }
41337da2899SCharles.Forsyth else
41437da2899SCharles.Forsyth ap = &tk->binds;
41537da2899SCharles.Forsyth tkcancel(ap, event);
41637da2899SCharles.Forsyth }
41737da2899SCharles.Forsyth }
41837da2899SCharles.Forsyth
41937da2899SCharles.Forsyth tkword(t, arg, seq, seq+Tkmaxitem, nil);
42037da2899SCharles.Forsyth if(tag[0] == '.') {
42137da2899SCharles.Forsyth tk = tklook(t, tag, 0);
42237da2899SCharles.Forsyth if(tk == nil) {
42337da2899SCharles.Forsyth e = TkBadwp;
42437da2899SCharles.Forsyth tkerr(t, tag);
42537da2899SCharles.Forsyth goto err;
42637da2899SCharles.Forsyth }
42737da2899SCharles.Forsyth
42837da2899SCharles.Forsyth cmd = strdup(seq);
42937da2899SCharles.Forsyth if(cmd == nil) {
43037da2899SCharles.Forsyth e = TkNomem;
43137da2899SCharles.Forsyth goto err;
43237da2899SCharles.Forsyth }
43337da2899SCharles.Forsyth e = tkaction(&tk->binds, event, TkDynamic, cmd, mode);
43437da2899SCharles.Forsyth if(e != nil)
43537da2899SCharles.Forsyth goto err; /* tkaction does free(cmd) */
43637da2899SCharles.Forsyth free(tag);
43737da2899SCharles.Forsyth free(seq);
43837da2899SCharles.Forsyth return nil;
43937da2899SCharles.Forsyth }
44037da2899SCharles.Forsyth /* documented but doesn't work */
44137da2899SCharles.Forsyth if(strcmp(tag, "all") == 0) {
44237da2899SCharles.Forsyth for(tk = t->root; tk; tk = tk->next) {
44337da2899SCharles.Forsyth cmd = strdup(seq);
44437da2899SCharles.Forsyth if(cmd == nil) {
44537da2899SCharles.Forsyth e = TkNomem;
44637da2899SCharles.Forsyth goto err;
44737da2899SCharles.Forsyth }
44837da2899SCharles.Forsyth e = tkaction(&tk->binds, event, TkDynamic, cmd, mode);
44937da2899SCharles.Forsyth if(e != nil)
45037da2899SCharles.Forsyth goto err;
45137da2899SCharles.Forsyth }
45237da2899SCharles.Forsyth free(tag);
45337da2899SCharles.Forsyth free(seq);
45437da2899SCharles.Forsyth return nil;
45537da2899SCharles.Forsyth }
45637da2899SCharles.Forsyth /* undocumented, probably unused, and doesn't work consistently */
45737da2899SCharles.Forsyth for(i = 0; i < TKwidgets; i++) {
45837da2899SCharles.Forsyth if(strcmp(tag, tkmethod[i]->name) == 0) {
45937da2899SCharles.Forsyth cmd = strdup(seq);
46037da2899SCharles.Forsyth if(cmd == nil) {
46137da2899SCharles.Forsyth e = TkNomem;
46237da2899SCharles.Forsyth goto err;
46337da2899SCharles.Forsyth }
46437da2899SCharles.Forsyth e = tkaction(t->binds + i,event, TkDynamic, cmd, mode);
46537da2899SCharles.Forsyth if(e != nil)
46637da2899SCharles.Forsyth goto err;
46737da2899SCharles.Forsyth free(tag);
46837da2899SCharles.Forsyth free(seq);
46937da2899SCharles.Forsyth return nil;
47037da2899SCharles.Forsyth }
47137da2899SCharles.Forsyth }
47237da2899SCharles.Forsyth
47337da2899SCharles.Forsyth e = TkBadtg;
47437da2899SCharles.Forsyth err:
47537da2899SCharles.Forsyth free(tag);
47637da2899SCharles.Forsyth free(seq);
47737da2899SCharles.Forsyth
47837da2899SCharles.Forsyth return e;
47937da2899SCharles.Forsyth }
48037da2899SCharles.Forsyth
48137da2899SCharles.Forsyth char*
tksend(TkTop * t,char * arg,char ** ret)48237da2899SCharles.Forsyth tksend(TkTop *t, char *arg, char **ret)
48337da2899SCharles.Forsyth {
48437da2899SCharles.Forsyth
48537da2899SCharles.Forsyth TkVar *v;
48637da2899SCharles.Forsyth char *var;
48737da2899SCharles.Forsyth
48837da2899SCharles.Forsyth USED(ret);
48937da2899SCharles.Forsyth
49037da2899SCharles.Forsyth var = mallocz(Tkmaxitem, 0);
49137da2899SCharles.Forsyth if(var == nil)
49237da2899SCharles.Forsyth return TkNomem;
49337da2899SCharles.Forsyth
49437da2899SCharles.Forsyth arg = tkword(t, arg, var, var+Tkmaxitem, nil);
49537da2899SCharles.Forsyth v = tkmkvar(t, var, 0);
49637da2899SCharles.Forsyth free(var);
49737da2899SCharles.Forsyth if(v == nil)
49837da2899SCharles.Forsyth return TkBadvr;
49937da2899SCharles.Forsyth if(v->type != TkVchan)
50037da2899SCharles.Forsyth return TkNotvt;
50137da2899SCharles.Forsyth
50237da2899SCharles.Forsyth arg = tkskip(arg, " \t");
50337da2899SCharles.Forsyth if(tktolimbo(v->value, arg) == 0)
50437da2899SCharles.Forsyth return TkMovfw;
50537da2899SCharles.Forsyth
50637da2899SCharles.Forsyth return nil;
50737da2899SCharles.Forsyth }
50837da2899SCharles.Forsyth
50937da2899SCharles.Forsyth static Tk*
tknextfocus(TkTop * t,int d)51037da2899SCharles.Forsyth tknextfocus(TkTop *t, int d)
51137da2899SCharles.Forsyth {
51237da2899SCharles.Forsyth int i, n, j, k;
51337da2899SCharles.Forsyth Tk *oldfocus;
51437da2899SCharles.Forsyth
51537da2899SCharles.Forsyth if (t->focusorder == nil)
51637da2899SCharles.Forsyth tkbuildfocusorder(t);
51737da2899SCharles.Forsyth
51837da2899SCharles.Forsyth oldfocus = t->ctxt->tkkeygrab;
51937da2899SCharles.Forsyth n = t->nfocus;
52037da2899SCharles.Forsyth if (n == 0)
52137da2899SCharles.Forsyth return oldfocus;
52237da2899SCharles.Forsyth for (i = 0; i < n; i++)
52337da2899SCharles.Forsyth if (t->focusorder[i] == oldfocus)
52437da2899SCharles.Forsyth break;
52537da2899SCharles.Forsyth if (i == n) {
52637da2899SCharles.Forsyth for (i = 0; i < n; i++)
52737da2899SCharles.Forsyth if ((t->focusorder[i]->flag & Tkdisabled) == 0)
52837da2899SCharles.Forsyth return t->focusorder[i];
52937da2899SCharles.Forsyth return oldfocus;
53037da2899SCharles.Forsyth }
53137da2899SCharles.Forsyth for (j = 1; j < n; j++) {
53237da2899SCharles.Forsyth k = (i + d * j + n) % n;
53337da2899SCharles.Forsyth if ((t->focusorder[k]->flag & Tkdisabled) == 0)
53437da2899SCharles.Forsyth return t->focusorder[k];
53537da2899SCharles.Forsyth }
53637da2899SCharles.Forsyth return oldfocus;
53737da2899SCharles.Forsyth }
53837da2899SCharles.Forsyth
53937da2899SCharles.Forsyth /* our dirty little secret */
54037da2899SCharles.Forsyth static void
focusdirty(Tk * tk)54137da2899SCharles.Forsyth focusdirty(Tk *tk)
54237da2899SCharles.Forsyth {
54337da2899SCharles.Forsyth if(tk->highlightwidth > 0){
54437da2899SCharles.Forsyth tk->dirty = tkrect(tk, 1);
54537da2899SCharles.Forsyth tkdirty(tk);
54637da2899SCharles.Forsyth }
54737da2899SCharles.Forsyth }
54837da2899SCharles.Forsyth
54937da2899SCharles.Forsyth void
tksetkeyfocus(TkTop * top,Tk * new,int dir)55037da2899SCharles.Forsyth tksetkeyfocus(TkTop *top, Tk *new, int dir)
55137da2899SCharles.Forsyth {
55237da2899SCharles.Forsyth TkCtxt *c;
55337da2899SCharles.Forsyth Tk *old;
55437da2899SCharles.Forsyth
55537da2899SCharles.Forsyth c = top->ctxt;
55637da2899SCharles.Forsyth old = c->tkkeygrab;
55737da2899SCharles.Forsyth
55837da2899SCharles.Forsyth if(old == new)
55937da2899SCharles.Forsyth return;
56037da2899SCharles.Forsyth c->tkkeygrab = new;
56137da2899SCharles.Forsyth if(top->focused == 0)
56237da2899SCharles.Forsyth return;
56337da2899SCharles.Forsyth if(old != nil && old != top->root){
56437da2899SCharles.Forsyth tkdeliver(old, TkFocusout, nil);
56537da2899SCharles.Forsyth focusdirty(old);
56637da2899SCharles.Forsyth }
56737da2899SCharles.Forsyth if(new != nil && new != top->root){
56837da2899SCharles.Forsyth tkdeliver(new, TkFocusin, (void*)dir);
56937da2899SCharles.Forsyth focusdirty(new);
57037da2899SCharles.Forsyth }
57137da2899SCharles.Forsyth }
57237da2899SCharles.Forsyth
57337da2899SCharles.Forsyth void
tksetglobalfocus(TkTop * top,int in)57437da2899SCharles.Forsyth tksetglobalfocus(TkTop *top, int in)
57537da2899SCharles.Forsyth {
57637da2899SCharles.Forsyth Tk *tk;
57737da2899SCharles.Forsyth in = (in != 0);
57837da2899SCharles.Forsyth if (in != top->focused){
57937da2899SCharles.Forsyth top->focused = in;
58037da2899SCharles.Forsyth tk = top->ctxt->tkkeygrab;
58137da2899SCharles.Forsyth if(in){
58237da2899SCharles.Forsyth tkdeliver(top->root, TkFocusin, (void*)0);
58337da2899SCharles.Forsyth if(tk != nil && tk != top->root){
58437da2899SCharles.Forsyth tkdeliver(tk, TkFocusin, (void*)0);
58537da2899SCharles.Forsyth focusdirty(tk);
58637da2899SCharles.Forsyth }
58737da2899SCharles.Forsyth }else{
58837da2899SCharles.Forsyth if(tk != nil && tk != top->root){
58937da2899SCharles.Forsyth tkdeliver(tk, TkFocusout, nil);
59037da2899SCharles.Forsyth focusdirty(tk);
59137da2899SCharles.Forsyth }
59237da2899SCharles.Forsyth tkdeliver(top->root, TkFocusout, nil);
59337da2899SCharles.Forsyth }
59437da2899SCharles.Forsyth }
59537da2899SCharles.Forsyth }
59637da2899SCharles.Forsyth
59737da2899SCharles.Forsyth char*
tkfocus(TkTop * top,char * arg,char ** ret)59837da2899SCharles.Forsyth tkfocus(TkTop *top, char *arg, char **ret)
59937da2899SCharles.Forsyth {
60037da2899SCharles.Forsyth Tk *tk;
60137da2899SCharles.Forsyth char *wp, *e;
60237da2899SCharles.Forsyth int dir, global;
60337da2899SCharles.Forsyth TkOptab tko[2];
60437da2899SCharles.Forsyth TkName *names;
60537da2899SCharles.Forsyth
60637da2899SCharles.Forsyth tko[0].ptr = &global;
60737da2899SCharles.Forsyth tko[0].optab = focusopts;
60837da2899SCharles.Forsyth tko[1].ptr = nil;
60937da2899SCharles.Forsyth
61037da2899SCharles.Forsyth global = 0;
61137da2899SCharles.Forsyth
61237da2899SCharles.Forsyth names = nil;
61337da2899SCharles.Forsyth e = tkparse(top, arg, tko, &names);
61437da2899SCharles.Forsyth if (e != nil)
61537da2899SCharles.Forsyth return e;
61637da2899SCharles.Forsyth
61737da2899SCharles.Forsyth if(names == nil){
61837da2899SCharles.Forsyth if(global)
61937da2899SCharles.Forsyth return tkvalue(ret, "%d", top->focused);
62037da2899SCharles.Forsyth tk = top->ctxt->tkkeygrab;
62137da2899SCharles.Forsyth if (tk != nil && tk->name != nil)
62237da2899SCharles.Forsyth return tkvalue(ret, "%s", tk->name->name);
62337da2899SCharles.Forsyth return nil;
62437da2899SCharles.Forsyth }
62537da2899SCharles.Forsyth
62637da2899SCharles.Forsyth if(global){
62737da2899SCharles.Forsyth tksetglobalfocus(top, atoi(names->name));
62837da2899SCharles.Forsyth return nil;
62937da2899SCharles.Forsyth }
63037da2899SCharles.Forsyth
63137da2899SCharles.Forsyth wp = mallocz(Tkmaxitem, 0);
63237da2899SCharles.Forsyth if(wp == nil)
63337da2899SCharles.Forsyth return TkNomem;
63437da2899SCharles.Forsyth
63537da2899SCharles.Forsyth tkword(top, arg, wp, wp+Tkmaxitem, nil);
63637da2899SCharles.Forsyth if (!strcmp(wp, "next")) {
63737da2899SCharles.Forsyth tk = tknextfocus(top, 1); /* can only return nil if c->tkkeygrab is already nil */
63837da2899SCharles.Forsyth dir = +1;
63937da2899SCharles.Forsyth } else if (!strcmp(wp, "previous")) {
64037da2899SCharles.Forsyth tk = tknextfocus(top, -1);
64137da2899SCharles.Forsyth dir = -1;
64237da2899SCharles.Forsyth } else if(*wp == '\0') {
64337da2899SCharles.Forsyth tk = nil;
64437da2899SCharles.Forsyth dir = 0;
64537da2899SCharles.Forsyth } else {
64637da2899SCharles.Forsyth tk = tklook(top, wp, 0);
64737da2899SCharles.Forsyth if(tk == nil){
64837da2899SCharles.Forsyth tkerr(top, wp);
64937da2899SCharles.Forsyth free(wp);
65037da2899SCharles.Forsyth return TkBadwp;
65137da2899SCharles.Forsyth }
65237da2899SCharles.Forsyth dir = 0;
65337da2899SCharles.Forsyth }
65437da2899SCharles.Forsyth free(wp);
65537da2899SCharles.Forsyth
65637da2899SCharles.Forsyth tksetkeyfocus(top, tk, dir);
65737da2899SCharles.Forsyth return nil;
65837da2899SCharles.Forsyth }
65937da2899SCharles.Forsyth
66037da2899SCharles.Forsyth char*
tkraise(TkTop * t,char * arg,char ** ret)66137da2899SCharles.Forsyth tkraise(TkTop *t, char *arg, char **ret)
66237da2899SCharles.Forsyth {
66337da2899SCharles.Forsyth Tk *tk;
66437da2899SCharles.Forsyth char *wp;
66537da2899SCharles.Forsyth
66637da2899SCharles.Forsyth USED(ret);
66737da2899SCharles.Forsyth
66837da2899SCharles.Forsyth wp = mallocz(Tkmaxitem, 0);
66937da2899SCharles.Forsyth if(wp == nil)
67037da2899SCharles.Forsyth return TkNomem;
67137da2899SCharles.Forsyth tkword(t, arg, wp, wp+Tkmaxitem, nil);
67237da2899SCharles.Forsyth tk = tklook(t, wp, 0);
67337da2899SCharles.Forsyth if(tk == nil){
67437da2899SCharles.Forsyth tkerr(t, wp);
67537da2899SCharles.Forsyth free(wp);
67637da2899SCharles.Forsyth return TkBadwp;
67737da2899SCharles.Forsyth }
67837da2899SCharles.Forsyth free(wp);
67937da2899SCharles.Forsyth
68037da2899SCharles.Forsyth if((tk->flag & Tkwindow) == 0)
68137da2899SCharles.Forsyth return TkNotwm;
68237da2899SCharles.Forsyth
68337da2899SCharles.Forsyth tkwreq(tk->env->top, "raise %s", tk->name->name);
68437da2899SCharles.Forsyth return nil;
68537da2899SCharles.Forsyth }
68637da2899SCharles.Forsyth
68737da2899SCharles.Forsyth char*
tklower(TkTop * t,char * arg,char ** ret)68837da2899SCharles.Forsyth tklower(TkTop *t, char *arg, char **ret)
68937da2899SCharles.Forsyth {
69037da2899SCharles.Forsyth Tk *tk;
69137da2899SCharles.Forsyth char *wp;
69237da2899SCharles.Forsyth
69337da2899SCharles.Forsyth USED(ret);
69437da2899SCharles.Forsyth wp = mallocz(Tkmaxitem, 0);
69537da2899SCharles.Forsyth if(wp == nil)
69637da2899SCharles.Forsyth return TkNomem;
69737da2899SCharles.Forsyth tkword(t, arg, wp, wp+Tkmaxitem, nil);
69837da2899SCharles.Forsyth tk = tklook(t, wp, 0);
69937da2899SCharles.Forsyth if(tk == nil){
70037da2899SCharles.Forsyth tkerr(t, wp);
70137da2899SCharles.Forsyth free(wp);
70237da2899SCharles.Forsyth return TkBadwp;
70337da2899SCharles.Forsyth }
70437da2899SCharles.Forsyth free(wp);
70537da2899SCharles.Forsyth
70637da2899SCharles.Forsyth if((tk->flag & Tkwindow) == 0)
70737da2899SCharles.Forsyth return TkNotwm;
70837da2899SCharles.Forsyth
70937da2899SCharles.Forsyth tkwreq(tk->env->top, "lower %s", tk->name->name);
71037da2899SCharles.Forsyth return nil;
71137da2899SCharles.Forsyth }
71237da2899SCharles.Forsyth
71337da2899SCharles.Forsyth char*
tkgrab(TkTop * t,char * arg,char ** ret)71437da2899SCharles.Forsyth tkgrab(TkTop *t, char *arg, char **ret)
71537da2899SCharles.Forsyth {
71637da2899SCharles.Forsyth Tk *tk;
71737da2899SCharles.Forsyth TkCtxt *c;
71837da2899SCharles.Forsyth char *r, *buf, *wp;
71937da2899SCharles.Forsyth
72037da2899SCharles.Forsyth USED(ret);
72137da2899SCharles.Forsyth
72237da2899SCharles.Forsyth buf = mallocz(Tkmaxitem, 0);
72337da2899SCharles.Forsyth if(buf == nil)
72437da2899SCharles.Forsyth return TkNomem;
72537da2899SCharles.Forsyth
72637da2899SCharles.Forsyth wp = mallocz(Tkmaxitem, 0);
72737da2899SCharles.Forsyth if(wp == nil) {
72837da2899SCharles.Forsyth free(buf);
72937da2899SCharles.Forsyth return TkNomem;
73037da2899SCharles.Forsyth }
73137da2899SCharles.Forsyth arg = tkword(t, arg, buf, buf+Tkmaxitem, nil);
73237da2899SCharles.Forsyth
73337da2899SCharles.Forsyth tkword(t, arg, wp, wp+Tkmaxitem, nil);
73437da2899SCharles.Forsyth tk = tklook(t, wp, 0);
73537da2899SCharles.Forsyth if(tk == nil) {
73637da2899SCharles.Forsyth free(buf);
73737da2899SCharles.Forsyth tkerr(t, wp);
73837da2899SCharles.Forsyth free(wp);
73937da2899SCharles.Forsyth return TkBadwp;
74037da2899SCharles.Forsyth }
74137da2899SCharles.Forsyth free(wp);
74237da2899SCharles.Forsyth
74337da2899SCharles.Forsyth c = t->ctxt;
74437da2899SCharles.Forsyth if(strcmp(buf, "release") == 0) {
74537da2899SCharles.Forsyth free(buf);
74637da2899SCharles.Forsyth if(c->mgrab == tk)
74737da2899SCharles.Forsyth tksetmgrab(t, nil);
74837da2899SCharles.Forsyth return nil;
74937da2899SCharles.Forsyth }
75037da2899SCharles.Forsyth if(strcmp(buf, "set") == 0) {
75137da2899SCharles.Forsyth free(buf);
75237da2899SCharles.Forsyth return tksetmgrab(t, tk);
75337da2899SCharles.Forsyth }
75437da2899SCharles.Forsyth if(strcmp(buf, "ifunset") == 0) {
75537da2899SCharles.Forsyth free(buf);
75637da2899SCharles.Forsyth if(c->mgrab == nil)
75737da2899SCharles.Forsyth return tksetmgrab(t, tk);
75837da2899SCharles.Forsyth return nil;
75937da2899SCharles.Forsyth }
76037da2899SCharles.Forsyth if(strcmp(buf, "status") == 0) {
76137da2899SCharles.Forsyth free(buf);
76237da2899SCharles.Forsyth r = "none";
76337da2899SCharles.Forsyth if ((c->mgrab != nil) && (c->mgrab->name != nil))
76437da2899SCharles.Forsyth r = c->mgrab->name->name;
76537da2899SCharles.Forsyth return tkvalue(ret, "%s", r);
76637da2899SCharles.Forsyth }
76737da2899SCharles.Forsyth free(buf);
76837da2899SCharles.Forsyth return TkBadcm;
76937da2899SCharles.Forsyth }
77037da2899SCharles.Forsyth
77137da2899SCharles.Forsyth char*
tkputs(TkTop * t,char * arg,char ** ret)77237da2899SCharles.Forsyth tkputs(TkTop *t, char *arg, char **ret)
77337da2899SCharles.Forsyth {
77437da2899SCharles.Forsyth char *buf;
77537da2899SCharles.Forsyth
77637da2899SCharles.Forsyth USED(ret);
77737da2899SCharles.Forsyth
77837da2899SCharles.Forsyth buf = mallocz(Tkmaxitem, 0);
77937da2899SCharles.Forsyth if(buf == nil)
78037da2899SCharles.Forsyth return TkNomem;
78137da2899SCharles.Forsyth tkword(t, arg, buf, buf+Tkmaxitem, nil);
78237da2899SCharles.Forsyth print("%s\n", buf);
78337da2899SCharles.Forsyth free(buf);
78437da2899SCharles.Forsyth return nil;
78537da2899SCharles.Forsyth }
78637da2899SCharles.Forsyth
78737da2899SCharles.Forsyth char*
tkdestroy(TkTop * t,char * arg,char ** ret)78837da2899SCharles.Forsyth tkdestroy(TkTop *t, char *arg, char **ret)
78937da2899SCharles.Forsyth {
79037da2899SCharles.Forsyth int found, len, isroot;
79137da2899SCharles.Forsyth Tk *tk, **l, *next, *slave;
79237da2899SCharles.Forsyth char *n, *e, *buf;
79337da2899SCharles.Forsyth
79437da2899SCharles.Forsyth USED(ret);
79537da2899SCharles.Forsyth buf = mallocz(Tkmaxitem, 0);
79637da2899SCharles.Forsyth if(buf == nil)
79737da2899SCharles.Forsyth return TkNomem;
79837da2899SCharles.Forsyth e = nil;
79937da2899SCharles.Forsyth for(;;) {
80037da2899SCharles.Forsyth arg = tkword(t, arg, buf, buf+Tkmaxitem, nil);
80137da2899SCharles.Forsyth if(buf[0] == '\0')
80237da2899SCharles.Forsyth break;
80337da2899SCharles.Forsyth
80437da2899SCharles.Forsyth len = strlen(buf);
80537da2899SCharles.Forsyth found = 0;
80637da2899SCharles.Forsyth isroot = (strcmp(buf, ".") == 0);
80737da2899SCharles.Forsyth for(tk = t->root; tk; tk = tk->siblings) {
80837da2899SCharles.Forsyth if (tk->name != nil) {
80937da2899SCharles.Forsyth n = tk->name->name;
81037da2899SCharles.Forsyth if(strcmp(buf, n) == 0) {
81137da2899SCharles.Forsyth tk->flag |= Tkdestroy;
81237da2899SCharles.Forsyth found = 1;
81337da2899SCharles.Forsyth } else if(isroot || (strncmp(buf, n, len) == 0 && n[len] == '.'))
81437da2899SCharles.Forsyth tk->flag |= Tkdestroy;
81537da2899SCharles.Forsyth }
81637da2899SCharles.Forsyth }
81737da2899SCharles.Forsyth if(!found) {
81837da2899SCharles.Forsyth e = TkBadwp;
81937da2899SCharles.Forsyth tkerr(t, buf);
82037da2899SCharles.Forsyth break;
82137da2899SCharles.Forsyth }
82237da2899SCharles.Forsyth }
82337da2899SCharles.Forsyth free(buf);
82437da2899SCharles.Forsyth
82537da2899SCharles.Forsyth for(tk = t->root; tk; tk = tk->siblings) {
82637da2899SCharles.Forsyth if((tk->flag & Tkdestroy) == 0)
82737da2899SCharles.Forsyth continue;
82837da2899SCharles.Forsyth if(tk->flag & Tkwindow) {
82937da2899SCharles.Forsyth tkunmap(tk);
830*5849851aSforsyth if(tk->name != nil &&
831*5849851aSforsyth strcmp(tk->name->name, ".") == 0)
83237da2899SCharles.Forsyth tk->flag &= ~Tkdestroy;
83337da2899SCharles.Forsyth else
83437da2899SCharles.Forsyth tkdeliver(tk, TkDestroy, nil);
83537da2899SCharles.Forsyth } else
83637da2899SCharles.Forsyth tkdeliver(tk, TkDestroy, nil);
837*5849851aSforsyth if(0)print("tkdestroy %q\n", tkname(tk));
83837da2899SCharles.Forsyth if(tk->destroyed != nil)
83937da2899SCharles.Forsyth tk->destroyed(tk);
84037da2899SCharles.Forsyth tkpackqit(tk->master);
84137da2899SCharles.Forsyth tkdelpack(tk);
84237da2899SCharles.Forsyth for (slave = tk->slave; slave != nil; slave = next) {
84337da2899SCharles.Forsyth next = slave->next;
84437da2899SCharles.Forsyth slave->master = nil;
84537da2899SCharles.Forsyth slave->next = nil;
84637da2899SCharles.Forsyth }
84737da2899SCharles.Forsyth tk->slave = nil;
84837da2899SCharles.Forsyth if(tk->parent != nil && tk->geom != nil) /* XXX this appears to be bogus */
84937da2899SCharles.Forsyth tk->geom(tk, 0, 0, 0, 0);
85037da2899SCharles.Forsyth if(tk->grid){
85137da2899SCharles.Forsyth tkfreegrid(tk->grid);
85237da2899SCharles.Forsyth tk->grid = nil;
85337da2899SCharles.Forsyth }
85437da2899SCharles.Forsyth }
85537da2899SCharles.Forsyth tkrunpack(t);
85637da2899SCharles.Forsyth
85737da2899SCharles.Forsyth l = &t->windows;
85837da2899SCharles.Forsyth for(tk = t->windows; tk; tk = next) {
85937da2899SCharles.Forsyth next = TKobj(TkWin, tk)->next;
86037da2899SCharles.Forsyth if(tk->flag & Tkdestroy) {
86137da2899SCharles.Forsyth *l = next;
86237da2899SCharles.Forsyth continue;
86337da2899SCharles.Forsyth }
86437da2899SCharles.Forsyth l = &TKobj(TkWin, tk)->next;
86537da2899SCharles.Forsyth }
86637da2899SCharles.Forsyth l = &t->root;
86737da2899SCharles.Forsyth for(tk = t->root; tk; tk = next) {
86837da2899SCharles.Forsyth next = tk->siblings;
86937da2899SCharles.Forsyth if(tk->flag & Tkdestroy) {
87037da2899SCharles.Forsyth *l = next;
87137da2899SCharles.Forsyth tkfreeobj(tk);
87237da2899SCharles.Forsyth continue;
87337da2899SCharles.Forsyth }
87437da2899SCharles.Forsyth l = &tk->siblings;
87537da2899SCharles.Forsyth }
87637da2899SCharles.Forsyth
87737da2899SCharles.Forsyth return e;
87837da2899SCharles.Forsyth }
87937da2899SCharles.Forsyth
88037da2899SCharles.Forsyth char*
tkupdatecmd(TkTop * t,char * arg,char ** ret)88137da2899SCharles.Forsyth tkupdatecmd(TkTop *t, char *arg, char **ret)
88237da2899SCharles.Forsyth {
88337da2899SCharles.Forsyth Tk *tk;
88437da2899SCharles.Forsyth int x, y;
88537da2899SCharles.Forsyth Rectangle *dr;
88637da2899SCharles.Forsyth char buf[Tkmaxitem];
88737da2899SCharles.Forsyth
88837da2899SCharles.Forsyth USED(ret);
88937da2899SCharles.Forsyth
89037da2899SCharles.Forsyth tkword(t, arg, buf, buf+sizeof(buf), nil);
89137da2899SCharles.Forsyth if(strcmp(buf, "-onscreen") == 0){
89237da2899SCharles.Forsyth tk = t->root;
89337da2899SCharles.Forsyth dr = &t->screenr;
89437da2899SCharles.Forsyth x = tk->act.x;
89537da2899SCharles.Forsyth if(x+tk->act.width > dr->max.x)
89637da2899SCharles.Forsyth x = dr->max.x - tk->act.width;
89737da2899SCharles.Forsyth if(x < 0)
89837da2899SCharles.Forsyth x = 0;
89937da2899SCharles.Forsyth y = tk->act.y;
90037da2899SCharles.Forsyth if(y+tk->act.height > dr->max.y)
90137da2899SCharles.Forsyth y = dr->max.y - tk->act.height;
90237da2899SCharles.Forsyth if(y < 0)
90337da2899SCharles.Forsyth y = 0;
90437da2899SCharles.Forsyth tkmovewin(tk, Pt(x, y));
90537da2899SCharles.Forsyth }else if(strcmp(buf, "-disable") == 0){
90637da2899SCharles.Forsyth t->noupdate = 1;
90737da2899SCharles.Forsyth }else if(strcmp(buf, "-enable") == 0){
90837da2899SCharles.Forsyth t->noupdate = 0;
90937da2899SCharles.Forsyth }
91037da2899SCharles.Forsyth return tkupdate(t);
91137da2899SCharles.Forsyth }
91237da2899SCharles.Forsyth
91337da2899SCharles.Forsyth char*
tkwinfo(TkTop * t,char * arg,char ** ret)91437da2899SCharles.Forsyth tkwinfo(TkTop *t, char *arg, char **ret)
91537da2899SCharles.Forsyth {
91637da2899SCharles.Forsyth Tk *tk;
91737da2899SCharles.Forsyth char *cmd, *arg1;
91837da2899SCharles.Forsyth
91937da2899SCharles.Forsyth cmd = mallocz(Tkmaxitem, 0);
92037da2899SCharles.Forsyth if(cmd == nil)
92137da2899SCharles.Forsyth return TkNomem;
92237da2899SCharles.Forsyth
92337da2899SCharles.Forsyth arg = tkword(t, arg, cmd, cmd+Tkmaxitem, nil);
92437da2899SCharles.Forsyth if(strcmp(cmd, "class") == 0) {
92537da2899SCharles.Forsyth arg1 = mallocz(Tkmaxitem, 0);
92637da2899SCharles.Forsyth if(arg1 == nil) {
92737da2899SCharles.Forsyth free(cmd);
92837da2899SCharles.Forsyth return TkNomem;
92937da2899SCharles.Forsyth }
93037da2899SCharles.Forsyth tkword(t, arg, arg1, arg1+Tkmaxitem, nil);
93137da2899SCharles.Forsyth tk = tklook(t, arg1, 0);
93237da2899SCharles.Forsyth if(tk == nil){
93337da2899SCharles.Forsyth tkerr(t, arg1);
93437da2899SCharles.Forsyth free(arg1);
93537da2899SCharles.Forsyth free(cmd);
93637da2899SCharles.Forsyth return TkBadwp;
93737da2899SCharles.Forsyth }
93837da2899SCharles.Forsyth free(arg1);
93937da2899SCharles.Forsyth free(cmd);
94037da2899SCharles.Forsyth return tkvalue(ret, "%s", tkmethod[tk->type]->name);
94137da2899SCharles.Forsyth }
94237da2899SCharles.Forsyth free(cmd);
94337da2899SCharles.Forsyth return TkBadvl;
94437da2899SCharles.Forsyth }
94537da2899SCharles.Forsyth
94637da2899SCharles.Forsyth char*
tkcursorcmd(TkTop * t,char * arg,char ** ret)94737da2899SCharles.Forsyth tkcursorcmd(TkTop *t, char *arg, char **ret)
94837da2899SCharles.Forsyth {
94937da2899SCharles.Forsyth char *e;
95037da2899SCharles.Forsyth int locked;
95137da2899SCharles.Forsyth Display *d;
95237da2899SCharles.Forsyth TkCursor c;
95337da2899SCharles.Forsyth TkOptab tko[3];
95437da2899SCharles.Forsyth enum {Notset = 0x80000000};
95537da2899SCharles.Forsyth
95637da2899SCharles.Forsyth c.def = 0;
95737da2899SCharles.Forsyth c.p.x = Notset;
95837da2899SCharles.Forsyth c.p.y = Notset;
95937da2899SCharles.Forsyth c.bit = nil;
96037da2899SCharles.Forsyth c.img = nil;
96137da2899SCharles.Forsyth
96237da2899SCharles.Forsyth USED(ret);
96337da2899SCharles.Forsyth
96437da2899SCharles.Forsyth c.def = 0;
96537da2899SCharles.Forsyth tko[0].ptr = &c;
96637da2899SCharles.Forsyth tko[0].optab = tkcurop;
96737da2899SCharles.Forsyth tko[1].ptr = nil;
96837da2899SCharles.Forsyth e = tkparse(t, arg, tko, nil);
96937da2899SCharles.Forsyth if(e != nil)
97037da2899SCharles.Forsyth return e;
97137da2899SCharles.Forsyth
97237da2899SCharles.Forsyth d = t->display;
97337da2899SCharles.Forsyth locked = lockdisplay(d);
97437da2899SCharles.Forsyth if(c.def)
97537da2899SCharles.Forsyth tkcursorswitch(t, nil, nil);
97637da2899SCharles.Forsyth if(c.img != nil || c.bit != nil){
97737da2899SCharles.Forsyth e = tkcursorswitch(t, c.bit, c.img);
97837da2899SCharles.Forsyth tkimgput(c.img);
97937da2899SCharles.Forsyth freeimage(c.bit);
98037da2899SCharles.Forsyth }
98137da2899SCharles.Forsyth if(e == nil){
98237da2899SCharles.Forsyth if(c.p.x != Notset && c.p.y != Notset)
98337da2899SCharles.Forsyth tkcursorset(t, c.p);
98437da2899SCharles.Forsyth }
98537da2899SCharles.Forsyth if(locked)
98637da2899SCharles.Forsyth unlockdisplay(d);
98737da2899SCharles.Forsyth return e;
98837da2899SCharles.Forsyth }
98937da2899SCharles.Forsyth
99037da2899SCharles.Forsyth char *
tkbindings(TkTop * t,Tk * tk,TkEbind * b,int blen)99137da2899SCharles.Forsyth tkbindings(TkTop *t, Tk *tk, TkEbind *b, int blen)
99237da2899SCharles.Forsyth {
99337da2899SCharles.Forsyth TkAction *a, **ap;
99437da2899SCharles.Forsyth char *cmd, *e;
99537da2899SCharles.Forsyth int i;
99637da2899SCharles.Forsyth
99737da2899SCharles.Forsyth e = nil;
99837da2899SCharles.Forsyth for(i = 0; e == nil && i < blen; i++) /* default bindings */ {
99937da2899SCharles.Forsyth int how = TkArepl;
100037da2899SCharles.Forsyth char *cmd = b[i].cmd;
100137da2899SCharles.Forsyth if(cmd[0] == '+') {
100237da2899SCharles.Forsyth how = TkAadd;
100337da2899SCharles.Forsyth cmd++;
100437da2899SCharles.Forsyth }
100537da2899SCharles.Forsyth else if(cmd[0] == '-'){
100637da2899SCharles.Forsyth how = TkAsub;
100737da2899SCharles.Forsyth cmd++;
100837da2899SCharles.Forsyth }
100937da2899SCharles.Forsyth e = tkaction(&tk->binds, b[i].event, TkStatic, cmd, how);
101037da2899SCharles.Forsyth }
101137da2899SCharles.Forsyth
101237da2899SCharles.Forsyth if(e != nil)
101337da2899SCharles.Forsyth return e;
101437da2899SCharles.Forsyth
101537da2899SCharles.Forsyth ap = &tk->binds;
101637da2899SCharles.Forsyth for(a = t->binds[tk->type]; a; a = a->link) { /* user "defaults" */
101737da2899SCharles.Forsyth cmd = strdup(a->arg);
101837da2899SCharles.Forsyth if(cmd == nil)
101937da2899SCharles.Forsyth return TkNomem;
102037da2899SCharles.Forsyth
102137da2899SCharles.Forsyth e = tkaction(ap, a->event, TkDynamic, cmd,
102237da2899SCharles.Forsyth (a->type >> 8) & 0xff);
102337da2899SCharles.Forsyth if(e != nil)
102437da2899SCharles.Forsyth return e;
102537da2899SCharles.Forsyth ap = &(*ap)->link;
102637da2899SCharles.Forsyth }
102737da2899SCharles.Forsyth return nil;
102837da2899SCharles.Forsyth }
1029