#include <lib9.h>#include <kernel.h>#include "draw.h"#include "tk.h"#include "canvs.h" /* Widget Commands (+ means implemented) +addtag except halo and start options of closest spec +bbox +bind +canvasx +canvasy +cget +configure +coords +create +dchars +delete +dtag +find +focus +gettags +icursor +index +insert +itemcget +itemconfigure +lower +move postscript +raise +scale scan +select +type +xview +yview*/ staticTkStab tkbuffer[] = { "visible", TkCbufvisible, "all", TkCbufall, "none", TkCbufnone, "auto", TkCbufauto, /* backwards compatibility */ "1", TkCbufall, "yes", TkCbufall, "off", TkCbufall, "0", TkCbufauto, "no", TkCbufauto, "off", TkCbufauto, nil}; #define O(t, e) ((long)(&((t*)0)->e))#define OA(t, e) ((long)(((t*)0)->e)) staticTkOption opts[] ={ "closeenough", OPTfrac, O(TkCanvas, close), nil, "confine", OPTfrac, O(TkCanvas, confine), nil, "scrollregion", OPTfrac, OA(TkCanvas, scrollr), IAUX(4), "xscrollincrement", OPTfrac, O(TkCanvas, xscrolli), nil, "yscrollincrement", OPTfrac, O(TkCanvas, yscrolli), nil, "xscrollcommand", OPTtext, O(TkCanvas, xscroll), nil, "yscrollcommand", OPTtext, O(TkCanvas, yscroll), nil, "width", OPTnnfrac, O(TkCanvas, width), nil, "height", OPTnnfrac, O(TkCanvas, height), nil, "buffer", OPTstab, O(TkCanvas, buffer), tkbuffer, "buffered", OPTstab, O(TkCanvas, buffer), tkbool, /* backwards compatibility */ "selectborderwidth", OPTnndist, O(TkCanvas, sborderwidth), nil, nil}; int cvslshape[] = { TKI2F(8), TKI2F(10), TKI2F(3) };Rectangle bbnil = { 1000000, 1000000, -1000000, -1000000 };Rectangle huger = { -1000000, -1000000, 1000000, 1000000 }; static void tkcvsgeom(Tk *tk); static voidtkcvsf2i(Tk *tk, TkCanvas *tkc){ Rectangle r; tk->req.width = TKF2I(tkc->width); tk->req.height = TKF2I(tkc->height); r.min.x = TKF2I(tkc->scrollr[0]); r.min.y = TKF2I(tkc->scrollr[1]); r.max.x = TKF2I(tkc->scrollr[2]); r.max.y = TKF2I(tkc->scrollr[3]); /* * make sure that the region is big enough to hold * the actually displayed area */ if (Dx(r) < tk->act.width) r.max.x = r.min.x + tk->act.width; if (Dy(r) < tk->act.height) r.max.y = r.min.y + tk->act.height; tkc->region = r; /* * make sure that the view origin is at a valid * position with respect to the scroll region. */ if (tkc->view.x + tk->act.width > r.max.x) tkc->view.x = r.max.x - tk->act.width; if (tkc->view.x < r.min.x) tkc->view.x = r.min.x; if (tkc->view.y + tk->act.height > r.max.y) tkc->view.y = r.max.y - tk->act.height; if (tkc->view.y < r.min.y) tkc->view.y = r.min.y; } char*tkcanvas(TkTop *t, char *arg, char **ret){ Tk *tk; char *e; TkCanvas *tkc; TkName *names; TkOptab tko[3]; tk = tknewobj(t, TKcanvas, sizeof(Tk)+sizeof(TkCanvas)); if(tk == nil) return TkNomem; tkc = TKobj(TkCanvas, tk); tkc->close = TKI2F(1); tkc->xscrolli = TKI2F(1); tkc->yscrolli = TKI2F(1); tkc->width = TKI2F(360); tkc->height = TKI2F(270); tkc->actions = 0; tkc->actlim = Tksweep; tkc->mask = nil; tkc->sborderwidth = 1; tko[0].ptr = tkc; tko[0].optab = opts; tko[1].ptr = tk; tko[1].optab = tkgeneric; tko[2].ptr = nil; names = nil; e = tkparse(t, arg, tko, &names); if(e != nil) goto err; if(names == nil) { /* tkerr(t, arg); XXX */ e = TkBadwp; goto err; } tkc->current = tkmkname("current"); if(tkc->current == nil) { e = TkNomem; goto err; } tksettransparent(tk, tkhasalpha(tk->env, TkCbackgnd)); tkcvsf2i(tk, tkc); e = tkaddchild(t, tk, &names); tkfreename(names); if(e != nil) { tkfreename(tkc->current); tkc->current = nil; goto err; } tk->name->link = nil; e = tkvalue(ret, "%s", tk->name->name); if(e == nil) return nil; tkfreename(tkc->current); return e;err: tkfreeobj(tk); return e;} voidtkcvsdirty(Tk *sub){ TkCanvas *c; Tk *tk, *parent; Rectangle r; Point rel; rel = ZP; for(tk = sub; tk; tk = tk->master) { rel.x += tk->borderwidth + tk->act.x; rel.y += tk->borderwidth + tk->act.y; if (tk->parent != nil) break; } if (tk == nil) return; parent = tk->parent; c = TKobj(TkCanvas, parent); r = rectaddpt(sub->dirty, rel); tkbbmax(&c->update, &r); tkcvssetdirty(parent);} static voidtkcvsfocusorder(Tk *tk){ TkCanvas *tkc = TKobj(TkCanvas, tk); TkCwind *win; TkCitem *it; TkWinfo *inf; int i, n; n = 0; for (it = tkc->head; it != nil; it = it->next) { if (it->type == TkCVwindow) { win = TKobj(TkCwind, it); if (win->sub != nil) n++; } } if (n == 0) return; inf = malloc(sizeof(*inf) * n); if (inf == nil) return; i = 0; for (it = tkc->head; it != nil; it = it->next) { if (it->type == TkCVwindow) { win = TKobj(TkCwind, it); if (win->sub != nil) { inf[i].w = win->sub; inf[i].r = it->p.bb; i++; } } } tksortfocusorder(inf, n); for (i = 0; i < n; i++) tkappendfocusorder(inf[i].w);} static char*tkcvscget(Tk *tk, char *arg, char **val){ TkOptab tko[3]; TkCanvas *tkc = TKobj(TkCanvas, tk); tko[0].ptr = tkc; tko[0].optab = opts; tko[1].ptr = tk; tko[1].optab = tkgeneric; tko[2].ptr = nil; return tkgencget(tko, arg, val, tk->env->top);} static char*tkcvsconf(Tk *tk, char *arg, char **val){ char *e; int bd; TkGeom g; Rectangle r; TkOptab tko[3]; TkCanvas *c = TKobj(TkCanvas, tk); tko[0].ptr = c; tko[0].optab = opts; tko[1].ptr = tk; tko[1].optab = tkgeneric; tko[2].ptr = nil; if(*arg == '\0') return tkconflist(tko, val); r.min = c->view; r.max.x = r.min.x+tk->act.width; r.max.y = r.min.y+tk->act.height; tkbbmax(&c->update, &r); tkbbmax(&c->update, &c->region); bd = tk->borderwidth; g = tk->req; e = tkparse(tk->env->top, arg, tko, nil); if(e != nil) return e; tksettransparent(tk, tkhasalpha(tk->env, TkCbackgnd)); tkcvsf2i(tk, c); tkcvsgeom(tk); tkgeomchg(tk, &g, bd); tkbbmax(&c->update, &c->region); tk->dirty = tkrect(tk, 1); return nil;} voidtkcvsfreeitem(TkCitem *i){ int locked; Display *d; d = i->env->top->display; locked = lockdisplay(d); tkcimethod[i->type].free(i); if(locked) unlockdisplay(d); tkfreepoint(&i->p); tkputenv(i->env); free(i);} voidtkfreecanv(Tk *tk){ Display *d; int j, locked; TkCanvas *c; TkName *n, *nn; TkCtag *t, *tt; TkCitem *i, *next; c = TKobj(TkCanvas, tk); for(i = c->head; i; i = next) { next = i->next; tkcvsfreeitem(i); } if(c->xscroll != nil) free(c->xscroll); if(c->yscroll != nil) free(c->yscroll); for(j = 0; j < TkChash; j++) { for(n = c->thash[j]; n; n = nn) { nn = n->link; for(t = n->obj; t; t = tt) { tt = t->taglist; free(t); } tkfreebind(n->prop.binds); free(n); } } free(c->current); if((c->ialloc && c->image != nil) || c->mask != nil) { if (c->ialloc && c->image != nil) d = c->image->display; else d = c->mask->display; locked = lockdisplay(d); if (c->image != nil && c->ialloc) freeimage(c->image); if (c->mask != nil) freeimage(c->mask); if(locked) unlockdisplay(d); }} char*tkdrawcanv(Tk *tk, Point orig){ Image *dst; TkCitem *i; Display *d; TkCanvas *c; Rectangle r, bufr, oclipr; int vis, alpha, buffer; Point rel, p; TkCimeth *imeth; c = TKobj(TkCanvas, tk); d = tk->env->top->display; dst = tkimageof(tk); /* * translation from local to screen coords */ rel.x = orig.x + tk->act.x + tk->borderwidth; rel.y = orig.y + tk->act.y + tk->borderwidth; buffer = c->buffer; if (buffer == TkCbufauto) buffer = TkCbufvisible;/* buffer = (dst == TKobj(TkWin, tk->env->top->root)->image) ? TkCbufvisible : TkCbufnone; */ if (buffer == TkCbufnone) { if(c->image != nil && c->ialloc) freeimage(c->image); c->image = dst; c->ialloc = 0; r = tkrect(tk, 0); bufr = r; rectclip(&bufr, tk->dirty); oclipr = dst->clipr; replclipr(dst, 0, rectaddpt(bufr, rel)); draw(dst, rectaddpt(bufr, rel), tkgc(tk->env, TkCbackgnd), nil, ZP); p = subpt(rel, c->view); p.x = TKI2F(p.x); p.y = TKI2F(p.y); bufr = rectaddpt(bufr, c->view); for(i = c->head; i; i = i->next) { if(rectXrect(i->p.bb, bufr)) { imeth = &tkcimethod[i->type]; imeth->coord(i, nil, p.x, p.y); imeth->draw(dst, i, tk->env); imeth->coord(i, nil, -p.x, -p.y); } } replclipr(dst, 0, oclipr); } else { if (c->buffer == TkCbufall) bufr = c->region; else { bufr.min = c->view; bufr.max.x = c->view.x + tk->act.width; bufr.max.y = c->view.y + tk->act.height; } alpha = (tk->env->colors[TkCbackgnd] & 0xff) != 0xff; if(c->image == nil || eqrect(bufr, c->image->r) == 0) { if(c->image != nil && c->ialloc) freeimage(c->image); c->image = allocimage(d, bufr, alpha?RGBA32:d->image->chan, 0, tk->env->colors[TkCbackgnd]); c->ialloc = 1; c->update = bufr; tkcvssetdirty(tk); /* unnecessary? */ } if(c->image == nil) return nil; r = c->update; if (rectclip(&r, c->image->r)) { if (alpha) drawop(c->image, c->update, nil, nil, ZP, Clear); draw(c->image, c->update, tkgc(tk->env, TkCbackgnd), nil, c->view); replclipr(c->image, 0, r); for(i = c->head; i; i = i->next) { if(rectXrect(i->p.bb, r)) tkcimethod[i->type].draw(c->image, i, tk->env); } replclipr(c->image, 0, c->image->r); } /* * if the visible area of the canvas image doesn't * fit completely within the dirty rectangle, * then we'll need to draw the background behind it */ r = tkrect(tk, 0); bufr = rectsubpt(bufr, c->view); vis = rectclip(&bufr, tkrect(tk, 0)); if (!vis || !rectinrect(tk->dirty, bufr)) draw(dst, rectaddpt(tk->dirty, rel), tkgc(tk->env, TkCbackgnd), nil, c->view); if (vis && rectclip(&bufr, tk->dirty)) draw(dst, rectaddpt(bufr, rel), c->image, nil, addpt(bufr.min, c->view)); } /* * if the border is dirty too, then draw that */ if (!rectinrect(tk->dirty, bufr)) { r.min = addpt(r.min, rel); r.min.x -= tk->borderwidth; r.min.y -= tk->borderwidth; tkdrawrelief(dst, tk, r.min, TkCbackgnd, tk->relief); } c->update = bbnil; return nil;} voidtkcvsappend(TkCanvas *c, TkCitem *i){Lines 1–500 of 2220. Load more
#include <lib9.h> #include <kernel.h> #include "draw.h" #include "tk.h" #include "canvs.h" /* Widget Commands (+ means implemented) +addtag except halo and start options of closest spec +bbox +bind +canvasx +canvasy +cget +configure +coords +create +dchars +delete +dtag +find +focus +gettags +icursor +index +insert +itemcget +itemconfigure +lower +move postscript +raise +scale scan +select +type +xview +yview */ static TkStab tkbuffer[] = { "visible", TkCbufvisible, "all", TkCbufall, "none", TkCbufnone, "auto", TkCbufauto, /* backwards compatibility */ "1", TkCbufall, "yes", TkCbufall, "off", TkCbufall, "0", TkCbufauto, "no", TkCbufauto, "off", TkCbufauto, nil }; #define O(t, e) ((long)(&((t*)0)->e)) #define OA(t, e) ((long)(((t*)0)->e)) static TkOption opts[] = { "closeenough", OPTfrac, O(TkCanvas, close), nil, "confine", OPTfrac, O(TkCanvas, confine), nil, "scrollregion", OPTfrac, OA(TkCanvas, scrollr), IAUX(4), "xscrollincrement", OPTfrac, O(TkCanvas, xscrolli), nil, "yscrollincrement", OPTfrac, O(TkCanvas, yscrolli), nil, "xscrollcommand", OPTtext, O(TkCanvas, xscroll), nil, "yscrollcommand", OPTtext, O(TkCanvas, yscroll), nil, "width", OPTnnfrac, O(TkCanvas, width), nil, "height", OPTnnfrac, O(TkCanvas, height), nil, "buffer", OPTstab, O(TkCanvas, buffer), tkbuffer, "buffered", OPTstab, O(TkCanvas, buffer), tkbool, /* backwards compatibility */ "selectborderwidth", OPTnndist, O(TkCanvas, sborderwidth), nil, nil }; int cvslshape[] = { TKI2F(8), TKI2F(10), TKI2F(3) }; Rectangle bbnil = { 1000000, 1000000, -1000000, -1000000 }; Rectangle huger = { -1000000, -1000000, 1000000, 1000000 }; static void tkcvsgeom(Tk *tk); static void tkcvsf2i(Tk *tk, TkCanvas *tkc) { Rectangle r; tk->req.width = TKF2I(tkc->width); tk->req.height = TKF2I(tkc->height); r.min.x = TKF2I(tkc->scrollr[0]); r.min.y = TKF2I(tkc->scrollr[1]); r.max.x = TKF2I(tkc->scrollr[2]); r.max.y = TKF2I(tkc->scrollr[3]); /* * make sure that the region is big enough to hold * the actually displayed area */ if (Dx(r) < tk->act.width) r.max.x = r.min.x + tk->act.width; if (Dy(r) < tk->act.height) r.max.y = r.min.y + tk->act.height; tkc->region = r; /* * make sure that the view origin is at a valid * position with respect to the scroll region. */ if (tkc->view.x + tk->act.width > r.max.x) tkc->view.x = r.max.x - tk->act.width; if (tkc->view.x < r.min.x) tkc->view.x = r.min.x; if (tkc->view.y + tk->act.height > r.max.y) tkc->view.y = r.max.y - tk->act.height; if (tkc->view.y < r.min.y) tkc->view.y = r.min.y; } char* tkcanvas(TkTop *t, char *arg, char **ret) { Tk *tk; char *e; TkCanvas *tkc; TkName *names; TkOptab tko[3]; tk = tknewobj(t, TKcanvas, sizeof(Tk)+sizeof(TkCanvas)); if(tk == nil) return TkNomem; tkc = TKobj(TkCanvas, tk); tkc->close = TKI2F(1); tkc->xscrolli = TKI2F(1); tkc->yscrolli = TKI2F(1); tkc->width = TKI2F(360); tkc->height = TKI2F(270); tkc->actions = 0; tkc->actlim = Tksweep; tkc->mask = nil; tkc->sborderwidth = 1; tko[0].ptr = tkc; tko[0].optab = opts; tko[1].ptr = tk; tko[1].optab = tkgeneric; tko[2].ptr = nil; names = nil; e = tkparse(t, arg, tko, &names); if(e != nil) goto err; if(names == nil) { /* tkerr(t, arg); XXX */ e = TkBadwp; goto err; } tkc->current = tkmkname("current"); if(tkc->current == nil) { e = TkNomem; goto err; } tksettransparent(tk, tkhasalpha(tk->env, TkCbackgnd)); tkcvsf2i(tk, tkc); e = tkaddchild(t, tk, &names); tkfreename(names); if(e != nil) { tkfreename(tkc->current); tkc->current = nil; goto err; } tk->name->link = nil; e = tkvalue(ret, "%s", tk->name->name); if(e == nil) return nil; tkfreename(tkc->current); return e; err: tkfreeobj(tk); return e; } void tkcvsdirty(Tk *sub) { TkCanvas *c; Tk *tk, *parent; Rectangle r; Point rel; rel = ZP; for(tk = sub; tk; tk = tk->master) { rel.x += tk->borderwidth + tk->act.x; rel.y += tk->borderwidth + tk->act.y; if (tk->parent != nil) break; } if (tk == nil) return; parent = tk->parent; c = TKobj(TkCanvas, parent); r = rectaddpt(sub->dirty, rel); tkbbmax(&c->update, &r); tkcvssetdirty(parent); } static void tkcvsfocusorder(Tk *tk) { TkCanvas *tkc = TKobj(TkCanvas, tk); TkCwind *win; TkCitem *it; TkWinfo *inf; int i, n; n = 0; for (it = tkc->head; it != nil; it = it->next) { if (it->type == TkCVwindow) { win = TKobj(TkCwind, it); if (win->sub != nil) n++; } } if (n == 0) return; inf = malloc(sizeof(*inf) * n); if (inf == nil) return; i = 0; for (it = tkc->head; it != nil; it = it->next) { if (it->type == TkCVwindow) { win = TKobj(TkCwind, it); if (win->sub != nil) { inf[i].w = win->sub; inf[i].r = it->p.bb; i++; } } } tksortfocusorder(inf, n); for (i = 0; i < n; i++) tkappendfocusorder(inf[i].w); } static char* tkcvscget(Tk *tk, char *arg, char **val) { TkOptab tko[3]; TkCanvas *tkc = TKobj(TkCanvas, tk); tko[0].ptr = tkc; tko[0].optab = opts; tko[1].ptr = tk; tko[1].optab = tkgeneric; tko[2].ptr = nil; return tkgencget(tko, arg, val, tk->env->top); } static char* tkcvsconf(Tk *tk, char *arg, char **val) { char *e; int bd; TkGeom g; Rectangle r; TkOptab tko[3]; TkCanvas *c = TKobj(TkCanvas, tk); tko[0].ptr = c; tko[0].optab = opts; tko[1].ptr = tk; tko[1].optab = tkgeneric; tko[2].ptr = nil; if(*arg == '\0') return tkconflist(tko, val); r.min = c->view; r.max.x = r.min.x+tk->act.width; r.max.y = r.min.y+tk->act.height; tkbbmax(&c->update, &r); tkbbmax(&c->update, &c->region); bd = tk->borderwidth; g = tk->req; e = tkparse(tk->env->top, arg, tko, nil); if(e != nil) return e; tksettransparent(tk, tkhasalpha(tk->env, TkCbackgnd)); tkcvsf2i(tk, c); tkcvsgeom(tk); tkgeomchg(tk, &g, bd); tkbbmax(&c->update, &c->region); tk->dirty = tkrect(tk, 1); return nil; } void tkcvsfreeitem(TkCitem *i) { int locked; Display *d; d = i->env->top->display; locked = lockdisplay(d); tkcimethod[i->type].free(i); if(locked) unlockdisplay(d); tkfreepoint(&i->p); tkputenv(i->env); free(i); } void tkfreecanv(Tk *tk) { Display *d; int j, locked; TkCanvas *c; TkName *n, *nn; TkCtag *t, *tt; TkCitem *i, *next; c = TKobj(TkCanvas, tk); for(i = c->head; i; i = next) { next = i->next; tkcvsfreeitem(i); } if(c->xscroll != nil) free(c->xscroll); if(c->yscroll != nil) free(c->yscroll); for(j = 0; j < TkChash; j++) { for(n = c->thash[j]; n; n = nn) { nn = n->link; for(t = n->obj; t; t = tt) { tt = t->taglist; free(t); } tkfreebind(n->prop.binds); free(n); } } free(c->current); if((c->ialloc && c->image != nil) || c->mask != nil) { if (c->ialloc && c->image != nil) d = c->image->display; else d = c->mask->display; locked = lockdisplay(d); if (c->image != nil && c->ialloc) freeimage(c->image); if (c->mask != nil) freeimage(c->mask); if(locked) unlockdisplay(d); } } char* tkdrawcanv(Tk *tk, Point orig) { Image *dst; TkCitem *i; Display *d; TkCanvas *c; Rectangle r, bufr, oclipr; int vis, alpha, buffer; Point rel, p; TkCimeth *imeth; c = TKobj(TkCanvas, tk); d = tk->env->top->display; dst = tkimageof(tk); /* * translation from local to screen coords */ rel.x = orig.x + tk->act.x + tk->borderwidth; rel.y = orig.y + tk->act.y + tk->borderwidth; buffer = c->buffer; if (buffer == TkCbufauto) buffer = TkCbufvisible; /* buffer = (dst == TKobj(TkWin, tk->env->top->root)->image) ? TkCbufvisible : TkCbufnone; */ if (buffer == TkCbufnone) { if(c->image != nil && c->ialloc) freeimage(c->image); c->image = dst; c->ialloc = 0; r = tkrect(tk, 0); bufr = r; rectclip(&bufr, tk->dirty); oclipr = dst->clipr; replclipr(dst, 0, rectaddpt(bufr, rel)); draw(dst, rectaddpt(bufr, rel), tkgc(tk->env, TkCbackgnd), nil, ZP); p = subpt(rel, c->view); p.x = TKI2F(p.x); p.y = TKI2F(p.y); bufr = rectaddpt(bufr, c->view); for(i = c->head; i; i = i->next) { if(rectXrect(i->p.bb, bufr)) { imeth = &tkcimethod[i->type]; imeth->coord(i, nil, p.x, p.y); imeth->draw(dst, i, tk->env); imeth->coord(i, nil, -p.x, -p.y); } } replclipr(dst, 0, oclipr); } else { if (c->buffer == TkCbufall) bufr = c->region; else { bufr.min = c->view; bufr.max.x = c->view.x + tk->act.width; bufr.max.y = c->view.y + tk->act.height; } alpha = (tk->env->colors[TkCbackgnd] & 0xff) != 0xff; if(c->image == nil || eqrect(bufr, c->image->r) == 0) { if(c->image != nil && c->ialloc) freeimage(c->image); c->image = allocimage(d, bufr, alpha?RGBA32:d->image->chan, 0, tk->env->colors[TkCbackgnd]); c->ialloc = 1; c->update = bufr; tkcvssetdirty(tk); /* unnecessary? */ } if(c->image == nil) return nil; r = c->update; if (rectclip(&r, c->image->r)) { if (alpha) drawop(c->image, c->update, nil, nil, ZP, Clear); draw(c->image, c->update, tkgc(tk->env, TkCbackgnd), nil, c->view); replclipr(c->image, 0, r); for(i = c->head; i; i = i->next) { if(rectXrect(i->p.bb, r)) tkcimethod[i->type].draw(c->image, i, tk->env); } replclipr(c->image, 0, c->image->r); } /* * if the visible area of the canvas image doesn't * fit completely within the dirty rectangle, * then we'll need to draw the background behind it */ r = tkrect(tk, 0); bufr = rectsubpt(bufr, c->view); vis = rectclip(&bufr, tkrect(tk, 0)); if (!vis || !rectinrect(tk->dirty, bufr)) draw(dst, rectaddpt(tk->dirty, rel), tkgc(tk->env, TkCbackgnd), nil, c->view); if (vis && rectclip(&bufr, tk->dirty)) draw(dst, rectaddpt(bufr, rel), c->image, nil, addpt(bufr.min, c->view)); } /* * if the border is dirty too, then draw that */ if (!rectinrect(tk->dirty, bufr)) { r.min = addpt(r.min, rel); r.min.x -= tk->borderwidth; r.min.y -= tk->borderwidth; tkdrawrelief(dst, tk, r.min, TkCbackgnd, tk->relief); } c->update = bbnil; return nil; } void tkcvsappend(TkCanvas *c, TkCitem *i) {