char* tkpropagate(TkTop *t, char *arg) { Tk *tk; TkStab *s; char *buf; buf = mallocz(Tkmaxitem, 0); if(buf == nil) return TkNomem; arg = tkword(t, arg, buf, buf+Tkmaxitem, nil); tk = tklook(t, buf, 0); if(tk == nil) { tkerr(t, buf); free(buf); return TkBadwp; } tkword(t, arg, buf, buf+Tkmaxitem, nil); for(s = tkbool; s->val; s++) { if(strcmp(s->val, buf) == 0) { if(s->con == BoolT) { tk->flag &= ~Tknoprop; tkpackqit(tk); tkrunpack(t); } else tk->flag |= Tknoprop; free(buf); return nil; } } free(buf); return TkBadvl; }
static char* tkslaves(TkTop *t, char *arg, char **val) { Tk *tk; char *fmt, *e, *buf; buf = mallocz(Tkmaxitem, 0); if(buf == nil) return TkNomem; tkword(t, arg, buf, buf+Tkmaxitem, nil); tk = tklook(t, buf, 0); if(tk == nil){ tkerr(t, buf); free(buf); return TkBadwp; } free(buf); fmt = "%s"; for(tk = tk->slave; tk; tk = tk->next) { if (tk->name != nil) { e = tkvalue(val, fmt, tk->name->name); if(e != nil) return e; fmt = " %s"; } } return nil; }
static char* tkforget(TkTop *t, char *arg) { Tk *tk; char *buf; buf = mallocz(Tkmaxitem, 0); if(buf == nil) return TkNomem; for(;;) { arg = tkword(t, arg, buf, buf+Tkmaxitem, nil); if(buf[0] == '\0') break; tk = tklook(t, buf, 0); if(tk == nil) { tkrunpack(t); tkerr(t, buf); free(buf); return TkBadwp; } tkpackqit(tk->master); tkdelpack(tk); } free(buf); tkrunpack(t); return nil; }
char* tkbind(TkTop *t, char *arg, char **ret) { Rune r; Tk *tk; TkAction **ap; int i, mode, event; char *cmd, *tag, *seq; char *e; USED(ret); tag = mallocz(Tkmaxitem, 0); if(tag == nil) return TkNomem; seq = mallocz(Tkmaxitem, 0); if(seq == nil) { free(tag); return TkNomem; } arg = tkword(t, arg, tag, tag+Tkmaxitem, nil); if(tag[0] == '\0') { e = TkBadtg; goto err; } arg = tkword(t, arg, seq, seq+Tkmaxitem, nil); if(seq[0] == '<') { event = tkseqparse(seq+1); if(event == -1) { e = TkBadsq; goto err; } } else { chartorune(&r, seq); event = TkKey | r; } if(event == 0) { e = TkBadsq; goto err; } arg = tkskip(arg, " \t"); mode = TkArepl; if(*arg == '+') { mode = TkAadd; arg++; } else if(*arg == '-'){ mode = TkAsub; arg++; } if(*arg == '{') { cmd = tkskip(arg+1, " \t"); if(*cmd == '}') { tk = tklook(t, tag, 0); if(tk == nil) { for(i = 0; ; i++) { if(i >= TKwidgets) { e = TkBadwp; tkerr(t, tag); goto err; } if(strcmp(tag, tkmethod[i]->name) == 0) { ap = &(t->binds[i]); break; } } } else ap = &tk->binds; tkcancel(ap, event); } } tkword(t, arg, seq, seq+Tkmaxitem, nil); if(tag[0] == '.') { tk = tklook(t, tag, 0); if(tk == nil) { e = TkBadwp; tkerr(t, tag); goto err; } cmd = strdup(seq); if(cmd == nil) { e = TkNomem; goto err; } e = tkaction(&tk->binds, event, TkDynamic, cmd, mode); if(e != nil) goto err; /* tkaction does free(cmd) */ free(tag); free(seq); return nil; } /* documented but doesn't work */ if(strcmp(tag, "all") == 0) { for(tk = t->root; tk; tk = tk->next) { cmd = strdup(seq); if(cmd == nil) { e = TkNomem; goto err; } e = tkaction(&tk->binds, event, TkDynamic, cmd, mode); if(e != nil) goto err; } free(tag); free(seq); return nil; } /* undocumented, probably unused, and doesn't work consistently */ for(i = 0; i < TKwidgets; i++) { if(strcmp(tag, tkmethod[i]->name) == 0) { cmd = strdup(seq); if(cmd == nil) { e = TkNomem; goto err; } e = tkaction(t->binds + i,event, TkDynamic, cmd, mode); if(e != nil) goto err; free(tag); free(seq); return nil; } } e = TkBadtg; err: free(tag); free(seq); return e; }
char* tkpack(TkTop *t, char *arg, char **val) { TkParam param = defparam; TkParam *p = ¶m; TkOptab tko[2]; Tk *tk, **l, *tkp; TkName *names, *n; char *e, *w, *buf; buf = mallocz(Tkminitem, 0); if(buf == nil) return TkNomem; w = tkword(t, arg, buf, buf+Tkminitem, nil); if(strcmp(buf, "forget") == 0) { e = tkforget(t, w); free(buf); return e; } if(strcmp(buf, "propagate") == 0) { e = tkpropagate(t, w); free(buf); return e; } if(strcmp(buf, "slaves") == 0) { e = tkslaves(t, w, val); free(buf); return e; } free(buf); tko[0].ptr = p; tko[0].optab = opts; tko[1].ptr = nil; names = nil; e = tkparse(t, arg, tko, &names); if(e != nil) return e; if((p->before && p->before->master == nil) || (p->after && p->after->master == nil)) { tkfreename(names); return TkNotpk; } for(n = names; n; n = n->link) { tkp = tklook(t, n->name, 0); if(tkp == nil) { tkerr(t, n->name); tkfreename(names); return TkBadwp; } if(tkp->flag & Tkwindow) { tkfreename(names); return TkIstop; } if(tkp->parent != nil) { tkfreename(names); return TkWpack; } n->obj = tkp; } e = nil; for(n = names; n; n = n->link) { tk = n->obj; if(tk->master == nil) { tk->pad = ZP; tk->ipad = ZP; tk->flag &= ~(Tkanchor|Tkside|Tkfill|Tkexpand); tk->flag |= Tktop; } if(tk->master != nil) { tkpackqit(tk->master); tkdelpack(tk); } if(p->before == nil && p->after == nil && p->in == nil) { tkp = tklook(t, n->name, 1); if(tkp == nil) { e = TkBadwp; tkerr(t, n->name); goto Error; } e = tkcanpack(tk, tkp); if (e != nil) goto Error; tkappendpack(tkp, tk, -1); } else { if(p->in != nil) { e = tkcanpack(tk, p->in); if(e != nil) goto Error; tkappendpack(p->in, tk, -1); } else if(p->before != nil) { e = tkcanpack(tk, p->before->master); if (e != nil) goto Error; tk->master = p->before->master; l = &tk->master->slave; for(;;) { if(*l == p->before) { tk->next = *l; *l = tk; break; } l = &(*l)->next; } p->before = tk; } else { e = tkcanpack(tk, p->after->master); if (e != nil) goto Error; tk->master = p->after->master; tk->next = p->after->next; p->after->next = tk; p->after = tk; } } tksetopt(p, tk); if (tk->master->flag&Tksubsub) tksetbits(tk, Tksubsub); tkpackqit(tk->master); } Error: tkfreename(names); tkrunpack(t); return e; }