137da2899SCharles.Forsyth #include <lib9.h>
237da2899SCharles.Forsyth #include <kernel.h>
337da2899SCharles.Forsyth #include "draw.h"
437da2899SCharles.Forsyth #include "tk.h"
537da2899SCharles.Forsyth #include "canvs.h"
637da2899SCharles.Forsyth
737da2899SCharles.Forsyth char*
tkparsepts(TkTop * t,TkCpoints * i,char ** arg,int close)837da2899SCharles.Forsyth tkparsepts(TkTop *t, TkCpoints *i, char **arg, int close)
937da2899SCharles.Forsyth {
1037da2899SCharles.Forsyth char *s, *e;
1137da2899SCharles.Forsyth Point *p, *d;
1237da2899SCharles.Forsyth int n, npoint;
1337da2899SCharles.Forsyth
1437da2899SCharles.Forsyth i->parampt = nil;
1537da2899SCharles.Forsyth i->drawpt = nil;
1637da2899SCharles.Forsyth i->bb = bbnil;
1737da2899SCharles.Forsyth s = *arg;
1837da2899SCharles.Forsyth npoint = 0;
1937da2899SCharles.Forsyth while(*s) {
2037da2899SCharles.Forsyth s = tkskip(s, " \t");
2137da2899SCharles.Forsyth if(*s == '-' && (s[1] < '0' || s[1] > '9'))
2237da2899SCharles.Forsyth break;
2337da2899SCharles.Forsyth while(*s && *s != ' ' && *s != '\t')
2437da2899SCharles.Forsyth s++;
2537da2899SCharles.Forsyth npoint++;
2637da2899SCharles.Forsyth }
2737da2899SCharles.Forsyth
2837da2899SCharles.Forsyth i->parampt = mallocz(npoint*sizeof(Point), 0);
2937da2899SCharles.Forsyth if(i->parampt == nil)
3037da2899SCharles.Forsyth return TkNomem;
3137da2899SCharles.Forsyth
3237da2899SCharles.Forsyth s = *arg;
3337da2899SCharles.Forsyth p = i->parampt;
3437da2899SCharles.Forsyth npoint = 0;
3537da2899SCharles.Forsyth while(*s) {
3637da2899SCharles.Forsyth e = tkfracword(t, &s, &p->x, nil);
3737da2899SCharles.Forsyth if(e != nil)
3837da2899SCharles.Forsyth goto Error;
3937da2899SCharles.Forsyth e = tkfracword(t, &s, &p->y, nil);
4037da2899SCharles.Forsyth if(e != nil)
4137da2899SCharles.Forsyth goto Error;
4237da2899SCharles.Forsyth npoint++;
4337da2899SCharles.Forsyth s = tkskip(s, " \t");
4437da2899SCharles.Forsyth if(*s == '-' && (s[1] < '0' || s[1] > '9'))
4537da2899SCharles.Forsyth break;
4637da2899SCharles.Forsyth p++;
4737da2899SCharles.Forsyth }
4837da2899SCharles.Forsyth *arg = s;
4937da2899SCharles.Forsyth close = (close != 0);
5037da2899SCharles.Forsyth i->drawpt = mallocz((npoint+close)*sizeof(Point), 0);
5137da2899SCharles.Forsyth if(i->drawpt == nil){
5237da2899SCharles.Forsyth e = TkNomem;
5337da2899SCharles.Forsyth goto Error;
5437da2899SCharles.Forsyth }
5537da2899SCharles.Forsyth
5637da2899SCharles.Forsyth d = i->drawpt;
5737da2899SCharles.Forsyth p = i->parampt;
5837da2899SCharles.Forsyth for(n = 0; n < npoint; n++) {
5937da2899SCharles.Forsyth d->x = TKF2I(p->x);
6037da2899SCharles.Forsyth d->y = TKF2I(p->y);
6137da2899SCharles.Forsyth if(d->x < i->bb.min.x)
6237da2899SCharles.Forsyth i->bb.min.x = d->x;
6337da2899SCharles.Forsyth if(d->x > i->bb.max.x)
6437da2899SCharles.Forsyth i->bb.max.x = d->x;
6537da2899SCharles.Forsyth if(d->y < i->bb.min.y)
6637da2899SCharles.Forsyth i->bb.min.y = d->y;
6737da2899SCharles.Forsyth if(d->y > i->bb.max.y)
6837da2899SCharles.Forsyth i->bb.max.y = d->y;
6937da2899SCharles.Forsyth d++;
7037da2899SCharles.Forsyth p++;
7137da2899SCharles.Forsyth }
7237da2899SCharles.Forsyth if (close)
7337da2899SCharles.Forsyth *d = i->drawpt[0];
7437da2899SCharles.Forsyth
7537da2899SCharles.Forsyth i->npoint = npoint;
7637da2899SCharles.Forsyth return nil;
7737da2899SCharles.Forsyth
7837da2899SCharles.Forsyth Error:
7937da2899SCharles.Forsyth tkfreepoint(i);
8037da2899SCharles.Forsyth i->parampt = nil;
8137da2899SCharles.Forsyth i->drawpt = nil;
8237da2899SCharles.Forsyth return e;
8337da2899SCharles.Forsyth }
8437da2899SCharles.Forsyth
8537da2899SCharles.Forsyth TkCitem*
tkcnewitem(Tk * tk,int t,int n)8637da2899SCharles.Forsyth tkcnewitem(Tk *tk, int t, int n)
8737da2899SCharles.Forsyth {
8837da2899SCharles.Forsyth TkCitem *i;
8937da2899SCharles.Forsyth
9037da2899SCharles.Forsyth i = malloc(n);
9137da2899SCharles.Forsyth if(i == nil)
9237da2899SCharles.Forsyth return nil;
9337da2899SCharles.Forsyth memset(i, 0, n);
9437da2899SCharles.Forsyth
9537da2899SCharles.Forsyth i->type = t;
9637da2899SCharles.Forsyth i->env = tk->env;
9737da2899SCharles.Forsyth i->env->ref++;
9837da2899SCharles.Forsyth
9937da2899SCharles.Forsyth return i;
10037da2899SCharles.Forsyth }
10137da2899SCharles.Forsyth
10237da2899SCharles.Forsyth /*
10337da2899SCharles.Forsyth * expand the canvas's dirty rectangle, clipping
10437da2899SCharles.Forsyth * appropriately to its boundaries.
10537da2899SCharles.Forsyth */
10637da2899SCharles.Forsyth void
tkcvssetdirty(Tk * tk)10737da2899SCharles.Forsyth tkcvssetdirty(Tk *tk)
10837da2899SCharles.Forsyth {
10937da2899SCharles.Forsyth TkCanvas *c;
11037da2899SCharles.Forsyth Rectangle r;
11137da2899SCharles.Forsyth c = TKobj(TkCanvas, tk);
11237da2899SCharles.Forsyth
11337da2899SCharles.Forsyth r = tkrect(tk, 0);
11437da2899SCharles.Forsyth if (rectclip(&r, rectsubpt(c->update, c->view)))
11537da2899SCharles.Forsyth combinerect(&tk->dirty, r);
11637da2899SCharles.Forsyth }
11737da2899SCharles.Forsyth
11837da2899SCharles.Forsyth void
tkxlatepts(Point * p,int npoints,int x,int y)11937da2899SCharles.Forsyth tkxlatepts(Point *p, int npoints, int x, int y)
12037da2899SCharles.Forsyth {
12137da2899SCharles.Forsyth while(npoints--) {
12237da2899SCharles.Forsyth p->x += x;
12337da2899SCharles.Forsyth p->y += y;
12437da2899SCharles.Forsyth p++;
12537da2899SCharles.Forsyth }
12637da2899SCharles.Forsyth }
12737da2899SCharles.Forsyth
12837da2899SCharles.Forsyth void
tkbbmax(Rectangle * bb,Rectangle * r)12937da2899SCharles.Forsyth tkbbmax(Rectangle *bb, Rectangle *r)
13037da2899SCharles.Forsyth {
13137da2899SCharles.Forsyth if(r->min.x < bb->min.x)
13237da2899SCharles.Forsyth bb->min.x = r->min.x;
13337da2899SCharles.Forsyth if(r->min.y < bb->min.y)
13437da2899SCharles.Forsyth bb->min.y = r->min.y;
13537da2899SCharles.Forsyth if(r->max.x > bb->max.x)
13637da2899SCharles.Forsyth bb->max.x = r->max.x;
13737da2899SCharles.Forsyth if(r->max.y > bb->max.y)
13837da2899SCharles.Forsyth bb->max.y = r->max.y;
13937da2899SCharles.Forsyth }
14037da2899SCharles.Forsyth
14137da2899SCharles.Forsyth void
tkpolybound(Point * p,int n,Rectangle * r)14237da2899SCharles.Forsyth tkpolybound(Point *p, int n, Rectangle *r)
14337da2899SCharles.Forsyth {
14437da2899SCharles.Forsyth while(n--) {
14537da2899SCharles.Forsyth if(p->x < r->min.x)
14637da2899SCharles.Forsyth r->min.x = p->x;
14737da2899SCharles.Forsyth if(p->y < r->min.y)
14837da2899SCharles.Forsyth r->min.y = p->y;
14937da2899SCharles.Forsyth if(p->x > r->max.x)
15037da2899SCharles.Forsyth r->max.x = p->x;
15137da2899SCharles.Forsyth if(p->y > r->max.y)
15237da2899SCharles.Forsyth r->max.y = p->y;
15337da2899SCharles.Forsyth p++;
15437da2899SCharles.Forsyth }
15537da2899SCharles.Forsyth }
15637da2899SCharles.Forsyth
15737da2899SCharles.Forsyth /*
15837da2899SCharles.Forsyth * look up a tag for a canvas item.
15937da2899SCharles.Forsyth * if n is non-nil, and the tag isn't found,
16037da2899SCharles.Forsyth * then add it to the canvas's taglist.
16137da2899SCharles.Forsyth * NB if there are no binds done on the
16237da2899SCharles.Forsyth * canvas, these tags never get cleared out,
16337da2899SCharles.Forsyth * even if nothing refers to them.
16437da2899SCharles.Forsyth */
16537da2899SCharles.Forsyth TkName*
tkctaglook(Tk * tk,TkName * n,char * name)16637da2899SCharles.Forsyth tkctaglook(Tk* tk, TkName *n, char *name)
16737da2899SCharles.Forsyth {
16837da2899SCharles.Forsyth ulong h;
16937da2899SCharles.Forsyth TkCanvas *c;
17037da2899SCharles.Forsyth char *p, *s;
17137da2899SCharles.Forsyth TkName *f, **l;
17237da2899SCharles.Forsyth
17337da2899SCharles.Forsyth c = TKobj(TkCanvas, tk);
17437da2899SCharles.Forsyth
17537da2899SCharles.Forsyth s = name;
17637da2899SCharles.Forsyth if(s == nil)
17737da2899SCharles.Forsyth s = n->name;
17837da2899SCharles.Forsyth
17937da2899SCharles.Forsyth if(strcmp(s, "current") == 0)
18037da2899SCharles.Forsyth return c->current;
18137da2899SCharles.Forsyth
18237da2899SCharles.Forsyth h = 0;
18337da2899SCharles.Forsyth for(p = s; *p; p++)
18437da2899SCharles.Forsyth h += 3*h + *p;
18537da2899SCharles.Forsyth
18637da2899SCharles.Forsyth l = &c->thash[h%TkChash];
18737da2899SCharles.Forsyth for(f = *l; f; f = f->link)
18837da2899SCharles.Forsyth if(strcmp(f->name, s) == 0)
18937da2899SCharles.Forsyth return f;
19037da2899SCharles.Forsyth
19137da2899SCharles.Forsyth if(n == nil)
19237da2899SCharles.Forsyth return nil;
19337da2899SCharles.Forsyth n->link = *l;
19437da2899SCharles.Forsyth *l = n;
19537da2899SCharles.Forsyth return n;
19637da2899SCharles.Forsyth }
19737da2899SCharles.Forsyth
19837da2899SCharles.Forsyth char*
tkcaddtag(Tk * tk,TkCitem * i,int new)19937da2899SCharles.Forsyth tkcaddtag(Tk *tk, TkCitem *i, int new)
20037da2899SCharles.Forsyth {
20137da2899SCharles.Forsyth TkCtag *t;
20237da2899SCharles.Forsyth TkCanvas *c;
20337da2899SCharles.Forsyth char buf[16];
20437da2899SCharles.Forsyth TkName *n, *f, *link;
20537da2899SCharles.Forsyth
20637da2899SCharles.Forsyth c = TKobj(TkCanvas, tk);
20737da2899SCharles.Forsyth if(new != 0) {
20837da2899SCharles.Forsyth i->id = ++c->id;
20937da2899SCharles.Forsyth snprint(buf, sizeof(buf), "%d", i->id);
21037da2899SCharles.Forsyth n = tkmkname(buf);
21137da2899SCharles.Forsyth if(n == nil)
21237da2899SCharles.Forsyth return TkNomem;
21337da2899SCharles.Forsyth n->link = i->tags;
21437da2899SCharles.Forsyth i->tags = n;
21537da2899SCharles.Forsyth }
21637da2899SCharles.Forsyth
21737da2899SCharles.Forsyth for(n = i->tags; n; n = link) {
21837da2899SCharles.Forsyth link = n->link;
21937da2899SCharles.Forsyth f = tkctaglook(tk, n, nil);
22037da2899SCharles.Forsyth if(n != f)
22137da2899SCharles.Forsyth free(n);
22237da2899SCharles.Forsyth
22337da2899SCharles.Forsyth for(t = i->stag; t; t = t->itemlist)
22437da2899SCharles.Forsyth if(t->name == f)
22537da2899SCharles.Forsyth break;
22637da2899SCharles.Forsyth if(t == nil) {
22737da2899SCharles.Forsyth t = malloc(sizeof(TkCtag));
22837da2899SCharles.Forsyth if(t == nil) {
22937da2899SCharles.Forsyth tkfreename(link);
23037da2899SCharles.Forsyth return TkNomem;
23137da2899SCharles.Forsyth }
23237da2899SCharles.Forsyth t->name = f;
23337da2899SCharles.Forsyth t->taglist = f->obj; /* add to head of items with this tag */
23437da2899SCharles.Forsyth f->obj = t;
23537da2899SCharles.Forsyth t->item = i;
23637da2899SCharles.Forsyth t->itemlist = i->stag; /* add to head of tags for this item */
23737da2899SCharles.Forsyth i->stag = t;
23837da2899SCharles.Forsyth }
23937da2899SCharles.Forsyth }
24037da2899SCharles.Forsyth i->tags = nil;
24137da2899SCharles.Forsyth
24237da2899SCharles.Forsyth if(new != 0) {
24337da2899SCharles.Forsyth i->tags = tkmkname("all");
24437da2899SCharles.Forsyth if(i->tags == nil)
24537da2899SCharles.Forsyth return TkNomem; /* XXX - Tad: memory leak? */
24637da2899SCharles.Forsyth return tkcaddtag(tk, i, 0);
24737da2899SCharles.Forsyth }
24837da2899SCharles.Forsyth
24937da2899SCharles.Forsyth return nil;
25037da2899SCharles.Forsyth }
25137da2899SCharles.Forsyth
25237da2899SCharles.Forsyth void
tkfreepoint(TkCpoints * p)25337da2899SCharles.Forsyth tkfreepoint(TkCpoints *p)
25437da2899SCharles.Forsyth {
25537da2899SCharles.Forsyth free(p->drawpt);
25637da2899SCharles.Forsyth free(p->parampt);
25737da2899SCharles.Forsyth }
25837da2899SCharles.Forsyth
25937da2899SCharles.Forsyth /*
26037da2899SCharles.Forsyth * of all the items in ilist tagged with tag,
26137da2899SCharles.Forsyth * return that tag for the first (topmost) item.
26237da2899SCharles.Forsyth */
26337da2899SCharles.Forsyth TkCtag*
tkclasttag(TkCitem * ilist,TkCtag * tag)26437da2899SCharles.Forsyth tkclasttag(TkCitem *ilist, TkCtag* tag)
26537da2899SCharles.Forsyth {
26637da2899SCharles.Forsyth TkCtag *last, *t;
26737da2899SCharles.Forsyth
26837da2899SCharles.Forsyth if (tag == nil || tag->taglist == nil)
26937da2899SCharles.Forsyth return tag;
27037da2899SCharles.Forsyth last = nil;
27137da2899SCharles.Forsyth while(ilist) {
27237da2899SCharles.Forsyth for(t = tag; t; t = t->taglist) {
27337da2899SCharles.Forsyth if(t->item == ilist) {
27437da2899SCharles.Forsyth last = t;
27537da2899SCharles.Forsyth break;
27637da2899SCharles.Forsyth }
27737da2899SCharles.Forsyth }
27837da2899SCharles.Forsyth ilist = ilist->next;
27937da2899SCharles.Forsyth }
28037da2899SCharles.Forsyth return last;
28137da2899SCharles.Forsyth }
28237da2899SCharles.Forsyth
28337da2899SCharles.Forsyth /*
28437da2899SCharles.Forsyth * of all the items in ilist tagged with tag,
28537da2899SCharles.Forsyth * return that tag for the first (bottommost) item.
28637da2899SCharles.Forsyth */
28737da2899SCharles.Forsyth TkCtag*
tkcfirsttag(TkCitem * ilist,TkCtag * tag)28837da2899SCharles.Forsyth tkcfirsttag(TkCitem *ilist, TkCtag* tag)
28937da2899SCharles.Forsyth {
29037da2899SCharles.Forsyth TkCtag *t;
29137da2899SCharles.Forsyth
29237da2899SCharles.Forsyth if (tag == nil || tag->taglist == nil)
29337da2899SCharles.Forsyth return tag;
29437da2899SCharles.Forsyth for (; ilist != nil; ilist = ilist->next)
29537da2899SCharles.Forsyth for(t = tag; t; t = t->taglist)
29637da2899SCharles.Forsyth if(t->item == ilist)
29737da2899SCharles.Forsyth return t;
29837da2899SCharles.Forsyth return nil;
29937da2899SCharles.Forsyth }
30037da2899SCharles.Forsyth
30137da2899SCharles.Forsyth void
tkmkpen(Image ** pen,TkEnv * e,Image * stipple)30237da2899SCharles.Forsyth tkmkpen(Image **pen, TkEnv *e, Image *stipple)
30337da2899SCharles.Forsyth {
30437da2899SCharles.Forsyth int locked;
30537da2899SCharles.Forsyth Display *d;
30637da2899SCharles.Forsyth Image *new, *fill;
30737da2899SCharles.Forsyth
30837da2899SCharles.Forsyth fill = tkgc(e, TkCfill);
30937da2899SCharles.Forsyth
31037da2899SCharles.Forsyth d = e->top->display;
31137da2899SCharles.Forsyth locked = lockdisplay(d);
31237da2899SCharles.Forsyth if(*pen != nil) {
31337da2899SCharles.Forsyth freeimage(*pen);
31437da2899SCharles.Forsyth *pen = nil;
31537da2899SCharles.Forsyth }
31637da2899SCharles.Forsyth if(stipple == nil) {
31737da2899SCharles.Forsyth if(locked)
31837da2899SCharles.Forsyth unlockdisplay(d);
31937da2899SCharles.Forsyth return;
32037da2899SCharles.Forsyth }
32137da2899SCharles.Forsyth
32237da2899SCharles.Forsyth if(fill == nil)
32337da2899SCharles.Forsyth fill = d->black;
32437da2899SCharles.Forsyth new = allocimage(d, stipple->r, RGBA32, 1, DTransparent); /* XXX RGBA32 is excessive sometimes... */
32537da2899SCharles.Forsyth if (new != nil)
32637da2899SCharles.Forsyth draw(new, stipple->r, fill, stipple, ZP);
32737da2899SCharles.Forsyth else
32837da2899SCharles.Forsyth new = fill;
32937da2899SCharles.Forsyth if(locked)
33037da2899SCharles.Forsyth unlockdisplay(d);
33137da2899SCharles.Forsyth *pen = new;
33237da2899SCharles.Forsyth }
33337da2899SCharles.Forsyth
33437da2899SCharles.Forsyth Point
tkcvsanchor(Point dp,int w,int h,int anchor)33537da2899SCharles.Forsyth tkcvsanchor(Point dp, int w, int h, int anchor)
33637da2899SCharles.Forsyth {
33737da2899SCharles.Forsyth Point o;
33837da2899SCharles.Forsyth
33937da2899SCharles.Forsyth if(anchor & Tknorth)
34037da2899SCharles.Forsyth o.y = dp.y;
341*c9c0d12eSforsyth else if(anchor & Tksouth)
34237da2899SCharles.Forsyth o.y = dp.y - h;
34337da2899SCharles.Forsyth else
34437da2899SCharles.Forsyth o.y = dp.y - h/2;
34537da2899SCharles.Forsyth
34637da2899SCharles.Forsyth if(anchor & Tkwest)
34737da2899SCharles.Forsyth o.x = dp.x;
348*c9c0d12eSforsyth else if(anchor & Tkeast)
34937da2899SCharles.Forsyth o.x = dp.x - w;
35037da2899SCharles.Forsyth else
35137da2899SCharles.Forsyth o.x = dp.x - w/2;
35237da2899SCharles.Forsyth
35337da2899SCharles.Forsyth return o;
35437da2899SCharles.Forsyth }
35537da2899SCharles.Forsyth
35637da2899SCharles.Forsyth static TkCitem*
tkcvsmousefocus(TkCanvas * c,Point p)35737da2899SCharles.Forsyth tkcvsmousefocus(TkCanvas *c, Point p)
35837da2899SCharles.Forsyth {
35937da2899SCharles.Forsyth TkCitem *i, *s;
36037da2899SCharles.Forsyth int (*hit)(TkCitem*, Point);
36137da2899SCharles.Forsyth
36237da2899SCharles.Forsyth if (c->grab != nil)
36337da2899SCharles.Forsyth return c->grab;
36437da2899SCharles.Forsyth s = nil;
36537da2899SCharles.Forsyth for(i = c->head; i; i = i->next)
36637da2899SCharles.Forsyth if(ptinrect(p, i->p.bb)) {
36737da2899SCharles.Forsyth if ((hit = tkcimethod[i->type].hit) != nil && !(*hit)(i, p))
36837da2899SCharles.Forsyth continue;
36937da2899SCharles.Forsyth s = i;
37037da2899SCharles.Forsyth }
37137da2899SCharles.Forsyth
37237da2899SCharles.Forsyth return s;
37337da2899SCharles.Forsyth }
37437da2899SCharles.Forsyth
37537da2899SCharles.Forsyth Tk*
tkcvsinwindow(Tk * tk,Point * p)37637da2899SCharles.Forsyth tkcvsinwindow(Tk *tk, Point *p)
37737da2899SCharles.Forsyth {
37837da2899SCharles.Forsyth TkCanvas *c;
37937da2899SCharles.Forsyth TkCitem *i;
38037da2899SCharles.Forsyth Point q;
38137da2899SCharles.Forsyth TkCwind *w;
38237da2899SCharles.Forsyth
38337da2899SCharles.Forsyth c = TKobj(TkCanvas, tk);
38437da2899SCharles.Forsyth
38537da2899SCharles.Forsyth q = addpt(*p, c->view);
38637da2899SCharles.Forsyth i = tkcvsmousefocus(c, addpt(*p, c->view));
38737da2899SCharles.Forsyth if (i == nil || i->type != TkCVwindow)
38837da2899SCharles.Forsyth return tk;
38937da2899SCharles.Forsyth w = TKobj(TkCwind, i);
39037da2899SCharles.Forsyth if (w->sub == nil)
39137da2899SCharles.Forsyth return tk;
39237da2899SCharles.Forsyth p->x = q.x - (i->p.bb.min.x + w->sub->borderwidth);
39337da2899SCharles.Forsyth p->y = q.y - (i->p.bb.min.y + w->sub->borderwidth);
39437da2899SCharles.Forsyth return w->sub;
39537da2899SCharles.Forsyth }
39637da2899SCharles.Forsyth
39737da2899SCharles.Forsyth static Tk*
tkcvsmouseinsub(TkCwind * w,TkMouse m)39837da2899SCharles.Forsyth tkcvsmouseinsub(TkCwind *w, TkMouse m)
39937da2899SCharles.Forsyth {
40037da2899SCharles.Forsyth Point g, mp;
40137da2899SCharles.Forsyth int bd;
40237da2899SCharles.Forsyth
40337da2899SCharles.Forsyth g = tkposn(w->sub);
40437da2899SCharles.Forsyth bd = w->sub->borderwidth;
40537da2899SCharles.Forsyth mp.x = m.x - (g.x + bd);
40637da2899SCharles.Forsyth mp.y = m.y - (g.y + bd);
40737da2899SCharles.Forsyth return tkinwindow(w->sub, mp, 0);
40837da2899SCharles.Forsyth }
40937da2899SCharles.Forsyth
41037da2899SCharles.Forsyth static Tk*
tkcvsdeliver(Tk * tk,TkCitem * i,int event,void * data)41137da2899SCharles.Forsyth tkcvsdeliver(Tk *tk, TkCitem *i, int event, void *data)
41237da2899SCharles.Forsyth {
41337da2899SCharles.Forsyth Tk *ftk, *dest;
41437da2899SCharles.Forsyth TkCtag *t;
41537da2899SCharles.Forsyth TkCwind *w;
41637da2899SCharles.Forsyth TkAction *a;
41737da2899SCharles.Forsyth
41837da2899SCharles.Forsyth if(i->type == TkCVwindow) {
41937da2899SCharles.Forsyth dest = nil;
42037da2899SCharles.Forsyth w = TKobj(TkCwind, i);
42137da2899SCharles.Forsyth if(w->sub == nil)
42237da2899SCharles.Forsyth return nil;
42337da2899SCharles.Forsyth
42437da2899SCharles.Forsyth if(!(event & TkKey) && (event & TkEmouse)) {
42537da2899SCharles.Forsyth ftk = tkcvsmouseinsub(w, *(TkMouse*)data);
42637da2899SCharles.Forsyth if(ftk != w->focus) {
42737da2899SCharles.Forsyth tkdeliver(w->focus, TkLeave, data);
4285849851aSforsyth if(0)print("focus %p %q %p %q\n", w->sub, tkname(w->sub), ftk, tkname(ftk));
42937da2899SCharles.Forsyth tkdeliver(ftk, TkEnter, data);
43037da2899SCharles.Forsyth w->focus = ftk;
43137da2899SCharles.Forsyth }
43237da2899SCharles.Forsyth if(ftk != nil)
43337da2899SCharles.Forsyth dest = tkdeliver(ftk, event, data);
4345849851aSforsyth } else {
43537da2899SCharles.Forsyth if(event & TkLeave) {
43637da2899SCharles.Forsyth tkdeliver(w->focus, TkLeave, data);
43737da2899SCharles.Forsyth w->focus = nil;
43837da2899SCharles.Forsyth } else if(event & TkEnter) {
43937da2899SCharles.Forsyth ftk = tkcvsmouseinsub(w, *(TkMouse*)data);
44037da2899SCharles.Forsyth tkdeliver(ftk, TkEnter, data);
44137da2899SCharles.Forsyth w->focus = ftk;
44237da2899SCharles.Forsyth } else
44337da2899SCharles.Forsyth dest = tkdeliver(w->sub, event, data);
44437da2899SCharles.Forsyth }
44537da2899SCharles.Forsyth return dest;
44637da2899SCharles.Forsyth }
44737da2899SCharles.Forsyth
44837da2899SCharles.Forsyth for(t = i->stag; t != nil; t = t->itemlist) {
44937da2899SCharles.Forsyth a = t->name->prop.binds;
45037da2899SCharles.Forsyth if(a != nil)
45137da2899SCharles.Forsyth tksubdeliver(tk, a, event, data, 0);
45237da2899SCharles.Forsyth }
45337da2899SCharles.Forsyth return nil;
45437da2899SCharles.Forsyth }
45537da2899SCharles.Forsyth
45637da2899SCharles.Forsyth Tk*
tkcvsevent(Tk * tk,int event,void * data)45737da2899SCharles.Forsyth tkcvsevent(Tk *tk, int event, void *data)
45837da2899SCharles.Forsyth {
45937da2899SCharles.Forsyth TkMouse m;
46037da2899SCharles.Forsyth TkCitem *f;
46137da2899SCharles.Forsyth Point mp, g;
46237da2899SCharles.Forsyth TkCanvas *c;
46337da2899SCharles.Forsyth Tk *dest;
46437da2899SCharles.Forsyth
46537da2899SCharles.Forsyth c = TKobj(TkCanvas, tk);
46637da2899SCharles.Forsyth
46737da2899SCharles.Forsyth if(event == TkLeave && c->mouse != nil) {
46837da2899SCharles.Forsyth tkcvsdeliver(tk, c->mouse, TkLeave, data);
46937da2899SCharles.Forsyth c->mouse = nil;
47037da2899SCharles.Forsyth }
47137da2899SCharles.Forsyth
47237da2899SCharles.Forsyth dest = nil;
47337da2899SCharles.Forsyth if(!(event & TkKey) && (event & TkEmouse) || (event & TkEnter)) {
47437da2899SCharles.Forsyth m = *(TkMouse*)data;
47537da2899SCharles.Forsyth g = tkposn(tk);
47637da2899SCharles.Forsyth mp.x = (m.x - g.x - tk->borderwidth) + c->view.x;
47737da2899SCharles.Forsyth mp.y = (m.y - g.y - tk->borderwidth) + c->view.y;
47837da2899SCharles.Forsyth f = tkcvsmousefocus(c, mp);
47937da2899SCharles.Forsyth if(c->mouse != f) {
48037da2899SCharles.Forsyth if(c->mouse != nil) {
48137da2899SCharles.Forsyth tkcvsdeliver(tk, c->mouse, TkLeave, data);
48237da2899SCharles.Forsyth c->current->obj = nil;
48337da2899SCharles.Forsyth }
48437da2899SCharles.Forsyth if(f != nil) {
48537da2899SCharles.Forsyth c->current->obj = &c->curtag;
48637da2899SCharles.Forsyth c->curtag.item = f;
48737da2899SCharles.Forsyth tkcvsdeliver(tk, f, TkEnter, data);
48837da2899SCharles.Forsyth }
48937da2899SCharles.Forsyth c->mouse = f;
49037da2899SCharles.Forsyth }
49137da2899SCharles.Forsyth f = c->mouse;
49237da2899SCharles.Forsyth if(f != nil && (event & TkEnter) == 0)
49337da2899SCharles.Forsyth dest = tkcvsdeliver(tk, f, event, &m);
49437da2899SCharles.Forsyth }
49537da2899SCharles.Forsyth
49637da2899SCharles.Forsyth if(event & TkKey) {
49737da2899SCharles.Forsyth f = c->focus;
49837da2899SCharles.Forsyth if(f != nil)
49937da2899SCharles.Forsyth tkcvsdeliver(tk, f, event, data);
50037da2899SCharles.Forsyth }
50137da2899SCharles.Forsyth if(dest == nil)
50237da2899SCharles.Forsyth tksubdeliver(tk, tk->binds, event, data, 0);
50337da2899SCharles.Forsyth return dest;
50437da2899SCharles.Forsyth }
5055849851aSforsyth
5065849851aSforsyth /*
5075849851aSforsyth * debugging
5085849851aSforsyth */
5095849851aSforsyth void
tkcvsdump(Tk * tk)5105849851aSforsyth tkcvsdump(Tk *tk)
5115849851aSforsyth {
5125849851aSforsyth TkCanvas *c;
5135849851aSforsyth TkCitem *it;
5145849851aSforsyth TkCwind *w;
5155849851aSforsyth char v1[Tkminitem], v2[Tkminitem];
5165849851aSforsyth int i;
5175849851aSforsyth
5185849851aSforsyth if(tk == nil)
5195849851aSforsyth return;
5205849851aSforsyth c = TKobj(TkCanvas, tk);
5215849851aSforsyth tkfprint(v1, c->width);
5225849851aSforsyth tkfprint(v2, c->height);
5235849851aSforsyth print("%q configure -width %s -height %s", tkname(tk), v1, v2);
5245849851aSforsyth print(" # focus %#p mouse %#p grab %#p\n", c->focus, c->mouse, c->grab);
5255849851aSforsyth for(it = c->head; it != nil; it = it->next){
5265849851aSforsyth print("%q create %q", tkname(tk), tkcimethod[it->type].name);
5275849851aSforsyth for(i = 0; i < it->p.npoint; i++){
5285849851aSforsyth tkfprint(v1, it->p.parampt[i].x);
5295849851aSforsyth tkfprint(v2, it->p.parampt[i].y);
5305849851aSforsyth print(" %s %s", v1, v2);
5315849851aSforsyth }
5325849851aSforsyth if(it->type == TkCVwindow){
5335849851aSforsyth w = TKobj(TkCwind, it);
5345849851aSforsyth if(w->sub != nil)
5355849851aSforsyth print(" -window %q", tkname(w->sub));
5365849851aSforsyth print(" # item %#p id %d sub %#p focus [%#p %q]\n", it, it->id, w->sub, w->focus, tkname(w->focus));
5375849851aSforsyth }else
5385849851aSforsyth print("# item %#p id %d\n", it, it->id);
5395849851aSforsyth }
5405849851aSforsyth }
541