static char* tkscrollfraction(Tk *tk, char *arg, char **val) { int len, frac, pos; char buf[Tkmaxitem]; TkScroll *tks = TKobj(TkScroll, tk); arg = tkitem(buf, arg); if(tks->orient == Tkvertical) tkitem(buf, arg); if(*arg == '\0' || *buf == '\0') return TkBadvl; pos = atoi(buf); if(pos < tks->a1) pos = tks->a1; if(pos > tks->a2) pos = tks->a2; len = tks->a2 - tks->a1 - 4*Elembw; frac = TKI2F(1); if(len != 0) frac = TKI2F(pos-tks->a1)/len; tkfprint(buf, frac); return tkvalue(val, "%s", buf); }
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* tkcvscanvx(Tk *tk, char *arg, char **val) { int x, s; TkCanvas *c; Point p; char buf[Tkmaxitem]; c = TKobj(TkCanvas, tk); arg = tkword(tk->env->top, arg, buf, buf+sizeof(buf), nil); if(buf[0] == '\0') return TkBadvl; p = tkposn(tk); x = atoi(buf) + c->view.x - (p.x + tk->borderwidth); if(*arg) { tkword(tk->env->top, arg, buf, buf+sizeof(buf), nil); s = atoi(buf); if (s) { if (x>=0) x = ((x+s/2)/s)*s; else x = ((x-s/2)/s)*s; } } return tkvalue(val, "%d", x); }
static char* tkcvscanvy(Tk *tk, char *arg, char **val) { int y, s; TkCanvas *c; Point p; char buf[Tkmaxitem]; c = TKobj(TkCanvas, tk); arg = tkword(tk->env->top, arg, buf, buf+sizeof(buf), nil); if(buf[0] == '\0') return TkBadvl; p = tkposn(tk); y = atoi(buf) + c->view.y - (p.y + tk->borderwidth); if(*arg) { tkitem(buf, arg); s = atoi(buf); if (s) { if (y>=0) y = ((y+s/2)/s)*s; else y = ((y-s/2)/s)*s; } } return tkvalue(val, "%d", y); }
static char* tkscalecoords(Tk *tk, char *arg, char **val) { int p, x, y, l, value; TkScale *tks = TKobj(TkScale, tk); char *e; value = tks->value; if(arg != nil && arg[0] != '\0') { e = tkfracword(tk->env->top, &arg, &value, tk->env); if (e != nil) return e; } value -= tks->from; p = tks->pixmax - tks->pixmin; l = TKF2I(tks->to-tks->from); if (l==0) p /= 2; else p = TKF2I(value*p/l); p += tks->pixmin; if(tks->orient == Tkvertical) { x = tks->center; y = p; } else { x = p; y = tks->center; } return tkvalue(val, "%d %d", x, y); }
char* tkscale(TkTop *t, char *arg, char **ret) { Tk *tk; char *e; TkName *names; TkScale *tks; TkOptab tko[3]; tk = tknewobj(t, TKscale, sizeof(Tk)+sizeof(TkScale)); if(tk == nil) return TkNomem; tk->flag |= Tktakefocus; tks = TKobj(TkScale, tk); tks->res = TKI2F(1); tks->to = TKI2F(100); tks->len = ScaleLen; tks->orient = Tkvertical; tks->relief = TKraised; tks->sl = ScaleSlider; tks->sv = BoolT; tks->bigi = 0; tko[0].ptr = tk; tko[0].optab = tkgeneric; tko[1].ptr = tks; tko[1].optab = opts; tko[2].ptr = nil; names = nil; e = tkparse(t, arg, tko, &names); if(e != nil) { tkfreeobj(tk); return e; } tksettransparent(tk, tkhasalpha(tk->env, TkCbackgnd)); tkscalecheckvalue(tk); tksizescale(tk); if (tks->bigi == 0) tks->bigi = TKI2F(TKF2I(tks->to - tks->from) / 10); e = tkbindings(t, tk, b, nelem(b)); if(e != nil) { tkfreeobj(tk); return e; } e = tkaddchild(t, tk, &names); tkfreename(names); if(e != nil) { tkfreeobj(tk); return e; } tk->name->link = nil; return tkvalue(ret, "%s", tk->name->name); }
char* tkcvsrectcreat(Tk* tk, char *arg, char **val) { char *e; TkCrect *r; TkCitem *i; TkCanvas *c; TkOptab tko[3]; c = TKobj(TkCanvas, tk); i = tkcnewitem(tk, TkCVrect, sizeof(TkCitem)+sizeof(TkCrect)); if(i == nil) return TkNomem; r = TKobj(TkCrect, i); r->width = TKI2F(1); e = tkparsepts(tk->env->top, &i->p, &arg, 0); if(e != nil) { tkcvsfreeitem(i); return e; } if(i->p.npoint != 2) { tkcvsfreeitem(i); return TkFewpt; } tko[0].ptr = r; tko[0].optab = rectopts; tko[1].ptr = i; tko[1].optab = itemopts; tko[2].ptr = nil; e = tkparse(tk->env->top, arg, tko, nil); if(e != nil) { tkcvsfreeitem(i); return e; } tkmkstipple(r->stipple); e = tkcaddtag(tk, i, 1); if(e != nil) { tkcvsfreeitem(i); return e; } tkcvsrectsize(i); e = tkvalue(val, "%d", i->id); if(e != nil) { tkcvsfreeitem(i); return e; } tkcvsappend(c, i); tkbbmax(&c->update, &i->p.bb); tkcvssetdirty(tk); return nil; }
static char* tkscaleident(Tk *tk, char *arg, char **val) { char *v; v = tkscaleposn(tk->env, tk, arg, nil); if(v == nil) return TkBadvl; return tkvalue(val, "%s", v); }
static char* tkcvsview(Tk *tk, char *arg, char **val, int nl, int *posn, int min, int max, int inc) { TkTop *t; int top, bot, diff, amount; char *e; char buf[Tkmaxitem], *v; diff = max-min; if(*arg == '\0') { if ( diff == 0 ) top = bot = 0; else { top = TKI2F(*posn-min)/diff; bot = TKI2F(*posn+nl-min)/diff; } v = tkfprint(buf, top); *v++ = ' '; tkfprint(v, bot); return tkvalue(val, "%s", buf); } t = tk->env->top; arg = tkword(t, arg, buf, buf+sizeof(buf), nil); if(strcmp(buf, "moveto") == 0) { e = tkfrac(&arg, &top, nil); if (e != nil) return e; *posn = min + TKF2I((top+1)*diff); } else if(strcmp(buf, "scroll") == 0) { arg = tkword(t, arg, buf, buf+sizeof(buf), nil); amount = atoi(buf); tkword(t, arg, buf, buf+sizeof(buf), nil); if(buf[0] == 'p') /* Pages */ amount = amount * nl * 9 /10; else if (inc > 0) amount *= inc; else amount = amount * nl / 10; *posn += amount; } else return TkBadcm; bot = max - nl; if(*posn > bot) *posn = bot; if(*posn < min) *posn = min; tk->dirty = tkrect(tk, 0); return nil; }
char* tkcvslinecreat(Tk* tk, char *arg, char **val) { char *e; TkCline *l; TkCitem *i; TkCanvas *c; TkOptab tko[3]; c = TKobj(TkCanvas, tk); i = tkcnewitem(tk, TkCVline, sizeof(TkCitem)+sizeof(TkCline)); if(i == nil) return TkNomem; l = TKobj(TkCline, i); l->width = TKI2F(1); e = tkparsepts(tk->env->top, &i->p, &arg, 0); if(e != nil) { tkcvsfreeitem(i); return e; } tko[0].ptr = l; tko[0].optab = lineopts; tko[1].ptr = i; tko[1].optab = itemopts; tko[2].ptr = nil; e = tkparse(tk->env->top, arg, tko, nil); if(e != nil) { tkcvsfreeitem(i); return e; } tkmkpen(&l->pen, i->env, l->stipple); e = tkcaddtag(tk, i, 1); if(e != nil) { tkcvsfreeitem(i); return e; } tkcvslinesize(i); e = tkvalue(val, "%d", i->id); if(e != nil) { tkcvsfreeitem(i); return e; } tkcvsappend(c, i); tkbbmax(&c->update, &i->p.bb); tkcvssetdirty(tk); return nil; }
char* tkvariable(TkTop *t, char *arg, char **ret) { TkVar *v; char *fmt, *e, *buf, *ebuf, *val; int l; l = strlen(arg) + 2; buf = malloc(l); if(buf == nil) return TkNomem; ebuf = buf+l; arg = tkword(t, arg, buf, ebuf, nil); arg = tkskip(arg, " \t"); if (*arg == '\0') { if(strcmp(buf, "lasterror") == 0) { free(buf); if(t->err == nil) return nil; fmt = "%s: %s"; if(strlen(t->errcmd) == sizeof(t->errcmd)-1) fmt = "%s...: %s"; e = tkvalue(ret, fmt, t->errcmd, t->err); t->err = nil; return e; } v = tkmkvar(t, buf, 0); free(buf); if(v == nil || v->value == nil) return nil; if(v->type != TkVstring) return TkNotvt; return tkvalue(ret, "%s", v->value); } val = buf+strlen(buf)+1; tkword(t, arg, val, ebuf, nil); e = tksetvar(t, buf, val); free(buf); return e; }
static char* tkentryget(Tk *tk, char *arg, char **val) { TkTop *top; TkEntry *tke; int first, last; char *e, *buf; tke = TKobj(TkEntry, tk); if(tke->text == nil) return nil; arg = tkskip(arg, " \t"); if(*arg == '\0') return tkvalue(val, "%.*S", tke->textlen, tke->text); top = tk->env->top; buf = mallocz(Tkmaxitem, 0); if(buf == nil) return TkNomem; arg = tkword(top, arg, buf, buf+Tkmaxitem, nil); e = tkentryparseindex(tk, buf, &first); if(e != nil) { free(buf); return e; } last = first+1; tkword(top, arg, buf, buf+Tkmaxitem, nil); if(buf[0] != '\0') { e = tkentryparseindex(tk, buf, &last); if(e != nil) { free(buf); return e; } } free(buf); if(last <= first || tke->textlen == 0 || first == tke->textlen) return tkvalue(val, "%S", L""); return tkvalue(val, "%.*S", last-first, tke->text+first); }
char* tkseecmd(TkTop *t, char *arg, char **ret) { TkOptab tko[2]; TkSee opts; TkName *names; Tk *tk; char *e; Rectangle vr; Point vp; opts.r[0] = bbnil.min.x; opts.r[1] = bbnil.min.y; opts.r[2] = bbnil.max.x; opts.r[3] = bbnil.max.y; opts.p[0] = bbnil.max.x; opts.p[1] = bbnil.max.y; opts.query = 0; tko[0].ptr = &opts; tko[0].optab = seeopts; tko[1].ptr = nil; names = nil; e = tkparse(t, arg, tko, &names); if (e != nil) return e; if (names == nil) return TkBadwp; tk = tklook(t, names->name, 0); tkfreename(names); if (tk == nil) return TkBadwp; if (opts.query) { if (!tkvisiblerect(tk, &vr)) return nil; /* XXX should this be converted into screen coords? */ return tkvalue(ret, "%d %d %d %d", vr.min.x, vr.min.y, vr.max.x, vr.max.y); } vr.min.x = opts.r[0]; vr.min.y = opts.r[1]; vr.max.x = opts.r[2]; vr.max.y = opts.r[3]; vp.x = opts.p[0]; vp.y = opts.p[1]; if (eqrect(vr, bbnil)) vr = tkrect(tk, 1); if (eqpt(vp, bbnil.max)) vp = vr.min; tksee(tk, vr, vp); return nil; }
char* tkentry(TkTop *t, char *arg, char **ret) { Tk *tk; char *e; TkName *names; TkEntry *tke; TkOptab tko[3]; tk = tknewobj(t, TKentry, sizeof(Tk)+sizeof(TkEntry)); if(tk == nil) return TkNomem; tk->relief = TKsunken; tk->borderwidth = 2; tk->flag |= Tktakefocus; tk->highlightwidth = 1; tke = TKobj(TkEntry, tk); tko[0].ptr = tk; tko[0].optab = tkgeneric; tko[1].ptr = tke; tko[1].optab = opts; tko[2].ptr = nil; names = nil; e = tkparse(t, arg, tko, &names); if(e != nil) { tkfreeobj(tk); return e; } tksettransparent(tk, tkhasalpha(tk->env, TkCbackgnd)); tksizeentry(tk); e = tkbindings(t, tk, b, nelem(b)); if(e != nil) { tkfreeobj(tk); return e; } e = tkaddchild(t, tk, &names); tkfreename(names); if(e != nil) { tkfreeobj(tk); return e; } tk->name->link = nil; recalcentry(tk); return tkvalue(ret, "%s", tk->name->name); }
static char* tkscrollget(Tk *tk, char *arg, char **val) { char *v, buf[Tkmaxitem]; TkScroll *tks = TKobj(TkScroll, tk); USED(arg); v = tkfprint(buf, tks->top); *v++ = ' '; tkfprint(v, tks->bot); return tkvalue(val, "%s", buf); }
char* tkcvstextindex(Tk *tk, TkCitem *i, char *arg, char **val) { int first; char *e, buf[Tkmaxitem]; tkword(tk->env->top, arg, buf, buf+sizeof(buf), nil); e = tkcvsparseindex(i, buf, &first); if(e != nil) return e; return tkvalue(val, "%d", first); }
char* tkscrollbar(TkTop *t, char *arg, char **ret) { Tk *tk; char *e; TkName *names; TkScroll *tks; TkOptab tko[3]; tk = tknewobj(t, TKscrollbar, sizeof(Tk)+sizeof(TkScroll)); if(tk == nil) return TkNomem; tks = TKobj(TkScroll, tk); tk->relief = TKflat; tk->borderwidth = 1; tks->activer = TKraised; tks->orient = Tkvertical; tko[0].ptr = tk; tko[0].optab = tkgeneric; tko[1].ptr = tks; tko[1].optab = opts; tko[2].ptr = nil; names = nil; e = tkparse(t, arg, tko, &names); if(e != nil) { tkfreeobj(tk); return e; } tksettransparent(tk, tkhasalpha(tk->env, TkCbackgnd)); e = tkinitscroll(tk); if(e != nil) { tkfreeobj(tk); return e; } e = tkaddchild(t, tk, &names); tkfreename(names); if(e != nil) { tkfreeobj(tk); return e; } tk->name->link = nil; return tkvalue(ret, "%s", tk->name->name); }
static char* tkcvscoords(Tk *tk, char *arg, char **val) { int i; Point *p; TkCtag *t; TkName *f; TkCanvas *c; TkCitem *item; char *fmt, *e, *v, buf[Tkmaxitem]; arg = tkword(tk->env->top, arg, buf, buf+sizeof(buf), nil); if(buf[0] == '\0') return TkBadvl; f = tkctaglook(tk, nil, buf); if(f == nil || f->obj == nil) return TkBadtg; c = TKobj(TkCanvas, tk); t = tkcfirsttag(c->head, f->obj); if(t == nil) return TkBadtg; item = t->item; if(*arg == '\0') { fmt = "%s"; p = item->p.parampt; for(i = 0; i < item->p.npoint; i++) { v = tkfprint(buf, p->x); *v++ = ' '; tkfprint(v, p->y); e = tkvalue(val, fmt, buf); if(e != nil) return e; fmt = " %s"; p++; } return nil; } tkbbmax(&c->update, &item->p.bb); e = tkcimethod[item->type].coord(item, arg, 0, 0); tkbbmax(&c->update, &item->p.bb); tkcvssetdirty(tk); return e; }
static char * tkcvsscreeny(Tk *tk, char *arg, char **val) { int y; TkCanvas *c; Point p; char buf[Tkmaxitem]; c = TKobj(TkCanvas, tk); tkword(tk->env->top, arg, buf, buf+sizeof(buf), nil); if(buf[0] == '\0') return TkBadvl; p = tkposn(tk); y = atoi(buf) - c->view.y + (p.y + tk->borderwidth); return tkvalue(val, "%d", y); }
static char* tkentryindex(Tk *tk, char *arg, char **val) { int index; char *r, *buf; buf = mallocz(Tkmaxitem, 0); if(buf == nil) return TkNomem; tkword(tk->env->top, arg, buf, buf+Tkmaxitem, nil); r = tkentryparseindex(tk, buf, &index); free(buf); if(r != nil) return r; return tkvalue(val, "%d", index); }
static char* tkcvsselect(Tk *tk, char *arg, char **val) { int op; TkCtag *t; TkName *f; TkCanvas *c; char buf[Tkmaxitem]; c = TKobj(TkCanvas, tk); arg = tkword(tk->env->top, arg, buf, buf+sizeof(buf), nil); if(strcmp(buf, "clear") == 0) { tkcvstextclr(tk); return nil; } if(strcmp(buf, "item") == 0) { if(c->selection) return tkvalue(val, "%d", c->selection->id); return nil; } if(strcmp(buf, "to") == 0) op = TkCselto; else if(strcmp(buf, "from") == 0) op = TkCselfrom; else if(strcmp(buf, "adjust") == 0) op = TkCseladjust; else return TkBadcm; arg = tkword(tk->env->top, arg, buf, buf+sizeof(buf), nil); f = tkctaglook(tk, nil, buf); if(f == nil) return TkBadtg; t = tkcfirsttag(c->head, f->obj); if(t == nil) return TkBadtg; return tkcvstextselect(tk, t->item, arg, op); }
static char* tkentrybboxcmd(Tk *tk, char *arg, char **val) { TkEntry *tke = TKobj(TkEntry, tk); char *r, *buf; int index; Rectangle bbox; buf = mallocz(Tkmaxitem, 0); if(buf == nil) return TkNomem; tkword(tk->env->top, arg, buf, buf+Tkmaxitem, nil); r = tkentryparseindex(tk, buf, &index); free(buf); if(r != nil) return r; bbox = rectaddpt(tkentrybbox(tk, index), Pt(xinset(tk) - tke->x0, yinset(tk))); return tkvalue(val, "%d %d %d %d", bbox.min.x, bbox.min.y, bbox.max.x, bbox.max.y); }
char* tklabel(TkTop *t, char *arg, char **ret) { Tk *tk; char *e; TkLabel *tkl; TkName *names; TkOptab tko[3]; tk = tknewobj(t, TKlabel, sizeof(Tk)+sizeof(TkLabel)); if(tk == nil) return TkNomem; tkl = TKobj(TkLabel, tk); tkl->ul = -1; tkl->justify = Tkleft; tko[0].ptr = tk; tko[0].optab = tkgeneric; tko[1].ptr = tkl; tko[1].optab = tklabelopts; tko[2].ptr = nil; names = nil; e = tkparse(t, arg, tko, &names); if(e != nil) { tkfreeobj(tk); return e; } tksizelabel(tk); tksettransparent(tk, tkhasalpha(tk->env, TkCbackgnd)); e = tkaddchild(t, tk, &names); tkfreename(names); if(e != nil) { tkfreeobj(tk); return e; } tk->name->link = nil; return tkvalue(ret, "%s", tk->name->name); }
static char* tkcvsfocus(Tk *tk, char *arg, char **val) { TkName *f; TkCtag *t; TkCanvas *c; TkCitem *i, *focus; char buf[Tkmaxitem]; c = TKobj(TkCanvas, tk); if(*arg == '\0') { if(c->focus == nil) return nil; return tkvalue(val, "%d", c->focus->id); } tkword(tk->env->top, arg, buf, buf+sizeof(buf), nil); if(buf[0] == '\0') return TkBadvl; f = tkctaglook(tk, nil, buf); if(f == nil || f->obj == nil) return nil; focus = c->focus; if(focus != nil && focus->type == TkCVtext) tkcvstextfocus(tk, focus, 0); for(i = c->head; i; i = i->next) { if(i->type == TkCVtext || i->type == TkCVwindow) { for(t = f->obj; t; t = t->taglist) if(t->item == i) focus = i; } } if(focus != nil && focus->type == TkCVtext) tkcvstextfocus(tk, focus, 1); c->focus = focus; return nil; }
static char* tkcvsbbox(Tk *tk, char *arg, char **val) { TkName *f; TkCtag *t; Rectangle bb; char buf[Tkmaxitem]; bb = bbnil; for(;;) { arg = tkword(tk->env->top, arg, buf, buf+sizeof(buf), nil); if(buf[0] == '\0') break; f = tkctaglook(tk, nil, buf); if(f == nil) return TkBadtg; for(t = f->obj; t; t = t->taglist) tkbbmax(&bb, &t->item->p.bb); } return tkvalue(val, "%d %d %d %d", bb.min.x, bb.min.y, bb.max.x, bb.max.y); }
static char* tkscrolldelta(Tk *tk, char *arg, char **val) { int l, delta; char buf[Tkmaxitem]; TkScroll *tks = TKobj(TkScroll, tk); arg = tkitem(buf, arg); if(tks->orient == Tkvertical) tkitem(buf, arg); if(*arg == '\0' || *buf == '\0') return TkBadvl; l = tks->a2-tks->a1-4*Elembw; delta = TKI2F(1); if(l != 0) delta = TKI2F(atoi(buf)) / l; tkfprint(buf, delta); return tkvalue(val, "%s", buf); }
static char* tkscaleget(Tk *tk, char *arg, char **val) { int x, y, value, v, l; char buf[Tkminitem], *e; TkScale *tks = TKobj(TkScale, tk); value = tks->value; if(arg[0] != '\0') { e = tkfracword(tk->env->top, &arg, &x, tk->env); if (e != nil) return e; e = tkfracword(tk->env->top, &arg, &y, tk->env); if (e != nil) return e; if(tks->orient == Tkvertical) v = TKF2I(y) + tk->borderwidth; else v = TKF2I(x) + tk->borderwidth; if(v < tks->pixmin) value = tks->from; else if(v > tks->pixmax) value = tks->to; else { l = tks->pixmax-tks->pixmin; value = 0; if (l!=0) value = v * ((tks->to-tks->from)/l); value += tks->from; } if(tks->res > 0) value = (value/tks->res)*tks->res; } tkfprint(buf, value); return tkvalue(val, "%s", buf); }
static char* tkscrollidentify(Tk *tk, char *arg, char **val) { int gotarg; TkTop *t; char *v, buf[Tkmaxitem]; Point p; TkScroll *tks = TKobj(TkScroll, tk); t = tk->env->top; arg = tkword(t, arg, buf, buf+sizeof(buf), &gotarg); if (!gotarg) return TkBadvl; p.x = atoi(buf); tkword(t, arg, buf, buf+sizeof(buf), &gotarg); if (!gotarg) return TkBadvl; p.y = atoi(buf); if (!ptinrect(p, tkrect(tk, 0))) return nil; if (tks->orient == Tkvertical) p.x = p.y; p.x += tk->borderwidth; v = ""; if(p.x <= tks->a1) v = "arrow1"; if(p.x > tks->a1 && p.x <= tks->t1) v = "trough1"; if(p.x > tks->t1 && p.x < tks->t2) v = "slider"; if(p.x >= tks->t2 && p.x < tks->a2) v = "trough2"; if(p.x >= tks->a2) v = "arrow2"; return tkvalue(val, "%s", v); }
/* * extension to tcl/tk: * grab set tag * grab release tag * grab ifunset tag */ static char* tkcvsgrab(Tk *tk, char *arg, char **val) { TkCtag *t; TkName *f; TkCanvas *c; char buf[Tkmaxitem]; c = TKobj(TkCanvas, tk); arg = tkword(tk->env->top, arg, buf, buf+sizeof(buf), nil); if (strcmp(buf, "status") == 0) { if (c->grab != nil) return tkvalue(val, "%d", c->grab->id); } else if (strcmp(buf, "release") == 0) { c->grab = nil; } else if (strcmp(buf, "set") == 0 || strcmp(buf, "ifunset") == 0) { if (buf[0] == 'i' && c->grab != nil) return nil; tkword(tk->env->top, arg, buf, buf + sizeof(buf), nil); f = tkctaglook(tk, nil, buf); if(f == nil || f->obj == nil) return TkBadtg; c = TKobj(TkCanvas, tk); t = tkcfirsttag(c->head, f->obj); if(t == nil) return TkBadtg; c->grab = t->item; } else return TkBadvl; return nil; }
static char* tkcvstype(Tk *tk, char *arg, char **val) { TkCtag *t; TkName *f; TkCanvas *c; char buf[Tkmaxitem]; tkword(tk->env->top, arg, buf, buf+sizeof(buf), nil); if(buf[0] == '\0') return TkBadvl; f = tkctaglook(tk, nil, buf); if(f == nil || f->obj == nil) return nil; c = TKobj(TkCanvas, tk); t = tkcfirsttag(c->head, f->obj); if(t == nil) return nil; return tkvalue(val, "%s", tkcimethod[t->item->type].name); }