Unified · Split
| @@ -455,7 +455,7 @@ struct Tk · 454 unmodified lines | |||
| 455 | Tk* master; /* Pack owner */ | 455 | Tk* master; /* Pack owner */ |
| 456 | Tk* slave; /* Packer slaves */ | 456 | Tk* slave; /* Packer slaves */ |
| 457 | Tk* next; /* Link for packer slaves */ | 457 | Tk* next; /* Link for packer slaves */ |
| 458 | Tk* parent; /* Window is sub of canvas or text */ | 458 | Tk* parent; /* Window is sub of this canvas or text */ |
| 459 | Tk* depth; /* Window depth when mapped */ | 459 | Tk* depth; /* Window depth when mapped */ |
| 460 | void (*geom)(Tk*, int, int, int, int); /* Geometry change notify function */ | 460 | void (*geom)(Tk*, int, int, int, int); /* Geometry change notify function */ |
| 461 | void (*destroyed)(Tk*); /* Destroy notify function */ | 461 | void (*destroyed)(Tk*); /* Destroy notify function */ |
| @@ -473,7 +473,7 @@ struct Tk · 11 unmodified lines | |||
| 473 | Rectangle dirty; /* dirty rectangle, relative to widget */ | 473 | Rectangle dirty; /* dirty rectangle, relative to widget */ |
| 474 | TkGrid* grid; /* children are packed in a grid */ | 474 | TkGrid* grid; /* children are packed in a grid */ |
| 475 | 475 | ||
| 476 | // char obj[TKSTRUCTALIGN]; | 476 | /* followed by widget-dependent data */ |
| 477 | }; | 477 | }; |
| 478 | 478 | ||
| 479 | struct TkWin | 479 | struct TkWin |
| @@ -514,6 +514,7 @@ struct TkMethod · 34 unmodified lines | |||
| 514 | void (*see)(Tk*, Rectangle*, Point*); | 514 | void (*see)(Tk*, Rectangle*, Point*); |
| 515 | Tk* (*inwindow)(Tk*, Point*); | 515 | Tk* (*inwindow)(Tk*, Point*); |
| 516 | void (*varchanged)(Tk*, char*, char*); | 516 | void (*varchanged)(Tk*, char*, char*); |
| 517 | void (*forgetsub)(Tk*, Tk*); | ||
| 517 | int ncmd; | 518 | int ncmd; |
| 518 | }; | 519 | }; |
| 519 | 520 | ||
| @@ -733,6 +734,7 @@ extern TkEnv* tkdefaultenv(TkTop*); · 213 unmodified lines | |||
| 733 | extern void tkputenv(TkEnv*); | 734 | extern void tkputenv(TkEnv*); |
| 734 | extern TkEnv* tkdupenv(TkEnv**); | 735 | extern TkEnv* tkdupenv(TkEnv**); |
| 735 | extern Tk* tknewobj(TkTop*, int, int); | 736 | extern Tk* tknewobj(TkTop*, int, int); |
| 737 | extern Tk* tkfindsub(Tk*); | ||
| 736 | extern void tkfreebind(TkAction*); | 738 | extern void tkfreebind(TkAction*); |
| 737 | extern void tkfreename(TkName*); | 739 | extern void tkfreename(TkName*); |
| 738 | extern void tkfreeobj(Tk*); | 740 | extern void tkfreeobj(Tk*); |
| @@ -750,7 +752,6 @@ extern int tksubdeliver(Tk*, TkAction*, int, void*, int); · 11 unmodified lines | |||
| 750 | extern void tkcancel(TkAction**, int); | 752 | extern void tkcancel(TkAction**, int); |
| 751 | extern char* tkaction(TkAction**, int, int, char*, int); | 753 | extern char* tkaction(TkAction**, int, int, char*, int); |
| 752 | extern char* tkitem(char*, char*); | 754 | extern char* tkitem(char*, char*); |
| 753 | extern int tkismapped(Tk*); | ||
| 754 | extern Point tkposn(Tk*); | 755 | extern Point tkposn(Tk*); |
| 755 | extern Point tkscrn2local(Tk*, Point); | 756 | extern Point tkscrn2local(Tk*, Point); |
| 756 | extern int tkvisiblerect(Tk *tk, Rectangle *rr); | 757 | extern int tkvisiblerect(Tk *tk, Rectangle *rr); |
| @@ -818,6 +819,11 @@ extern int tkextnnewctxt(TkCtxt*); · 61 unmodified lines | |||
| 818 | extern void tkextnfreectxt(TkCtxt*); | 819 | extern void tkextnfreectxt(TkCtxt*); |
| 819 | extern char* tkextnparseseq(char*, char*, int*); | 820 | extern char* tkextnparseseq(char*, char*, int*); |
| 820 | 821 | ||
| 822 | /* Debugging */ | ||
| 823 | extern void tkdump(Tk*); | ||
| 824 | extern void tktopdump(Tk*); | ||
| 825 | extern void tkcvsdump(Tk*); | ||
| 826 | |||
| 821 | /* External to libtk */ | 827 | /* External to libtk */ |
| 822 | extern void tkenterleave(TkTop*); | 828 | extern void tkenterleave(TkTop*); |
| 823 | extern void tksetwinimage(Tk*, Image*); | 829 | extern void tksetwinimage(Tk*, Image*); |
| @@ -1 +1 @@ | |||
| 1 | #define VERSION "Fourth Edition (20100819)" | 1 | #define VERSION "Fourth Edition (20100821)" |
| @@ -2214,5 +2214,7 @@ TkMethod canvasmethod = { · 2213 unmodified lines | |||
| 2214 | tkcvsrelpos, | 2214 | tkcvsrelpos, |
| 2215 | tkcvsevent, | 2215 | tkcvsevent, |
| 2216 | tkcvsseesub, | 2216 | tkcvsseesub, |
| 2217 | tkcvsinwindow | 2217 | tkcvsinwindow, |
| 2218 | nil, | ||
| 2219 | tkcvsforgetsub, | ||
| 2218 | }; | 2220 | }; |
| @@ -236,3 +236,5 @@ extern char* tkcvsimgcoord(TkCitem*, char*, int, int); · 235 unmodified lines | |||
| 236 | extern char* tkcvsimgcget(TkCitem*, char*, char**); | 236 | extern char* tkcvsimgcget(TkCitem*, char*, char**); |
| 237 | extern char* tkcvsimgconf(Tk*, TkCitem*, char*); | 237 | extern char* tkcvsimgconf(Tk*, TkCitem*, char*); |
| 238 | 238 | ||
| 239 | extern TkCitem* tkcvsfindwin(Tk*); | ||
| 240 | extern void tkcvsforgetsub(Tk*, Tk*); | ||
| @@ -426,18 +426,22 @@ tkcvsdeliver(Tk *tk, TkCitem *i, int event, void *data) · 425 unmodified lines | |||
| 426 | if(!(event & TkKey) && (event & TkEmouse)) { | 426 | if(!(event & TkKey) && (event & TkEmouse)) { |
| 427 | ftk = tkcvsmouseinsub(w, *(TkMouse*)data); | 427 | ftk = tkcvsmouseinsub(w, *(TkMouse*)data); |
| 428 | if(ftk != w->focus) { | 428 | if(ftk != w->focus) { |
| 429 | {TkCitem *si; if(w->focus != nil && (si = tkcvsfindwin(w->focus)) != i)print("focus botch 4: i=%p si=%p\n", i, si);} | ||
| 429 | tkdeliver(w->focus, TkLeave, data); | 430 | tkdeliver(w->focus, TkLeave, data); |
| 431 | {TkCitem *si; if(ftk != nil && (si = tkcvsfindwin(ftk)) != i)print("focus botch: i=%p si=%p\n", i, si);} | ||
| 432 | if(0)print("focus %p %q %p %q\n", w->sub, tkname(w->sub), ftk, tkname(ftk)); | ||
| 430 | tkdeliver(ftk, TkEnter, data); | 433 | tkdeliver(ftk, TkEnter, data); |
| 431 | w->focus = ftk; | 434 | w->focus = ftk; |
| 432 | } | 435 | } |
| 436 | else{TkCitem *si; if(ftk != nil && (si = tkcvsfindwin(ftk)) != i)print("focus botch 2: i=%p si=%p\n", i, si);} | ||
| 433 | if(ftk != nil) | 437 | if(ftk != nil) |
| 434 | dest = tkdeliver(ftk, event, data); | 438 | dest = tkdeliver(ftk, event, data); |
| 435 | } | 439 | } else { |
| 436 | else { | 440 | {TkCitem *si; if(w->focus != nil && (si = tkcvsfindwin(w->focus)) != i)print("focus botch 3: i=%p si=%p\n", i, si);} |
| 437 | if (event & TkLeave) { | 441 | if(event & TkLeave) { |
| 438 | tkdeliver(w->focus, TkLeave, data); | 442 | tkdeliver(w->focus, TkLeave, data); |
| 439 | w->focus = nil; | 443 | w->focus = nil; |
| 440 | } else if (event & TkEnter) { | 444 | } else if(event & TkEnter) { |
| 441 | ftk = tkcvsmouseinsub(w, *(TkMouse*)data); | 445 | ftk = tkcvsmouseinsub(w, *(TkMouse*)data); |
| 442 | tkdeliver(ftk, TkEnter, data); | 446 | tkdeliver(ftk, TkEnter, data); |
| 443 | w->focus = ftk; | 447 | w->focus = ftk; |
| @@ -504,3 +508,39 @@ tkcvsevent(Tk *tk, int event, void *data) · 60 unmodified lines | |||
| 504 | tksubdeliver(tk, tk->binds, event, data, 0); | 508 | tksubdeliver(tk, tk->binds, event, data, 0); |
| 505 | return dest; | 509 | return dest; |
| 506 | } | 510 | } |
| 511 | |||
| 512 | /* | ||
| 513 | * debugging | ||
| 514 | */ | ||
| 515 | void | ||
| 516 | tkcvsdump(Tk *tk) | ||
| 517 | { | ||
| 518 | TkCanvas *c; | ||
| 519 | TkCitem *it; | ||
| 520 | TkCwind *w; | ||
| 521 | char v1[Tkminitem], v2[Tkminitem]; | ||
| 522 | int i; | ||
| 523 | |||
| 524 | if(tk == nil) | ||
| 525 | return; | ||
| 526 | c = TKobj(TkCanvas, tk); | ||
| 527 | tkfprint(v1, c->width); | ||
| 528 | tkfprint(v2, c->height); | ||
| 529 | print("%q configure -width %s -height %s", tkname(tk), v1, v2); | ||
| 530 | print(" # focus %#p mouse %#p grab %#p\n", c->focus, c->mouse, c->grab); | ||
| 531 | for(it = c->head; it != nil; it = it->next){ | ||
| 532 | print("%q create %q", tkname(tk), tkcimethod[it->type].name); | ||
| 533 | for(i = 0; i < it->p.npoint; i++){ | ||
| 534 | tkfprint(v1, it->p.parampt[i].x); | ||
| 535 | tkfprint(v2, it->p.parampt[i].y); | ||
| 536 | print(" %s %s", v1, v2); | ||
| 537 | } | ||
| 538 | if(it->type == TkCVwindow){ | ||
| 539 | w = TKobj(TkCwind, it); | ||
| 540 | if(w->sub != nil) | ||
| 541 | print(" -window %q", tkname(w->sub)); | ||
| 542 | print(" # item %#p id %d sub %#p focus [%#p %q]\n", it, it->id, w->sub, w->focus, tkname(w->focus)); | ||
| 543 | }else | ||
| 544 | print("# item %#p id %d\n", it, it->id); | ||
| 545 | } | ||
| 546 | } | ||
| @@ -64,6 +64,47 @@ tkcvswindsize(TkCitem *i) · 63 unmodified lines | |||
| 64 | i->p.bb.max.y = p.y + s->act.height + bw; | 64 | i->p.bb.max.y = p.y + s->act.height + bw; |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | TkCitem* | ||
| 68 | tkcvsfindwin(Tk *tk) | ||
| 69 | { | ||
| 70 | Tk *parent, *sub; | ||
| 71 | TkCitem *i; | ||
| 72 | TkCanvas *c; | ||
| 73 | TkCwind *w; | ||
| 74 | |||
| 75 | sub = tkfindsub(tk); | ||
| 76 | if(sub == nil) | ||
| 77 | return nil; | ||
| 78 | parent = sub->parent; | ||
| 79 | if(parent->type != TKcanvas) | ||
| 80 | return nil; /* inconsistent */ | ||
| 81 | c = TKobj(TkCanvas, parent); | ||
| 82 | for(i = c->head; i != nil; i = i->next) { | ||
| 83 | if(i->type == TkCVwindow) { | ||
| 84 | w = TKobj(TkCwind, i); | ||
| 85 | if(w->sub == sub) | ||
| 86 | return i; | ||
| 87 | } | ||
| 88 | } | ||
| 89 | return nil; | ||
| 90 | } | ||
| 91 | |||
| 92 | void | ||
| 93 | tkcvsforgetsub(Tk *sub, Tk *tk) | ||
| 94 | { | ||
| 95 | TkCwind *w; | ||
| 96 | TkCitem *i; | ||
| 97 | |||
| 98 | i = tkcvsfindwin(sub); | ||
| 99 | if(i == nil) | ||
| 100 | return; | ||
| 101 | w = TKobj(TkCwind, i); | ||
| 102 | if(w->focus == tk) { | ||
| 103 | if(0)print("tkcsvsforget sub %p %q focus %p %q\n", sub, tkname(sub), tk, tkname(tk)); | ||
| 104 | w->focus = nil; | ||
| 105 | } | ||
| 106 | } | ||
| 107 | |||
| 67 | static int | 108 | static int |
| 68 | tkcvschkwfocus(TkCwind *w, Tk *tk) | 109 | tkcvschkwfocus(TkCwind *w, Tk *tk) |
| 69 | { | 110 | { |
| @@ -97,6 +138,7 @@ tkcvswindgeom(Tk *sub, int x, int y, int w, int h) · 27 unmodified lines | |||
| 97 | } | 138 | } |
| 98 | 139 | ||
| 99 | if(win->focus != nil) { | 140 | if(win->focus != nil) { |
| 141 | if(0)print("check focus %p %q %p %q\n", win, tkname(win->focus), sub, tkname(sub)); | ||
| 100 | if(tkcvschkwfocus(win, sub) == 0) | 142 | if(tkcvschkwfocus(win, sub) == 0) |
| 101 | win->focus = nil; | 143 | win->focus = nil; |
| 102 | } | 144 | } |
| @@ -128,6 +170,15 @@ tkcvssubdestry(Tk *sub) · 25 unmodified lines | |||
| 128 | if(tk == nil) | 170 | if(tk == nil) |
| 129 | return; | 171 | return; |
| 130 | 172 | ||
| 173 | if(0)print("tkcvssubdestry %p %q\n", sub, tkname(sub)); | ||
| 174 | i = tkcvsfindwin(sub); | ||
| 175 | if(i != nil){ | ||
| 176 | win = TKobj(TkCwind, i); | ||
| 177 | if(win->sub != sub){ | ||
| 178 | print("inconsistent tkcvssubdestry %p %q\n", sub, tkname(sub)); | ||
| 179 | } | ||
| 180 | } | ||
| 181 | |||
| 131 | c = TKobj(TkCanvas, tk); | 182 | c = TKobj(TkCanvas, tk); |
| 132 | for(i = c->head; i; i = i->next) { | 183 | for(i = c->head; i; i = i->next) { |
| 133 | if(i->type == TkCVwindow) { | 184 | if(i->type == TkCVwindow) { |
| @@ -810,7 +810,7 @@ tkdestroy(TkTop *t, char *arg, char **ret) · 809 unmodified lines | |||
| 810 | if(strcmp(buf, n) == 0) { | 810 | if(strcmp(buf, n) == 0) { |
| 811 | tk->flag |= Tkdestroy; | 811 | tk->flag |= Tkdestroy; |
| 812 | found = 1; | 812 | found = 1; |
| 813 | } else if(isroot || (strncmp(buf, n, len) == 0 &&n[len] == '.')) | 813 | } else if(isroot || (strncmp(buf, n, len) == 0 && n[len] == '.')) |
| 814 | tk->flag |= Tkdestroy; | 814 | tk->flag |= Tkdestroy; |
| 815 | } | 815 | } |
| 816 | } | 816 | } |
| @@ -827,13 +827,14 @@ tkdestroy(TkTop *t, char *arg, char **ret) · 10 unmodified lines | |||
| 827 | continue; | 827 | continue; |
| 828 | if(tk->flag & Tkwindow) { | 828 | if(tk->flag & Tkwindow) { |
| 829 | tkunmap(tk); | 829 | tkunmap(tk); |
| 830 | if((tk->name != nil) | 830 | if(tk->name != nil && |
| 831 | && (strcmp(tk->name->name, ".") == 0)) | 831 | strcmp(tk->name->name, ".") == 0) |
| 832 | tk->flag &= ~Tkdestroy; | 832 | tk->flag &= ~Tkdestroy; |
| 833 | else | 833 | else |
| 834 | tkdeliver(tk, TkDestroy, nil); | 834 | tkdeliver(tk, TkDestroy, nil); |
| 835 | } else | 835 | } else |
| 836 | tkdeliver(tk, TkDestroy, nil); | 836 | tkdeliver(tk, TkDestroy, nil); |
| 837 | if(0)print("tkdestroy %q\n", tkname(tk)); | ||
| 837 | if(tk->destroyed != nil) | 838 | if(tk->destroyed != nil) |
| 838 | tk->destroyed(tk); | 839 | tk->destroyed(tk); |
| 839 | tkpackqit(tk->master); | 840 | tkpackqit(tk->master); |
| @@ -179,17 +179,6 @@ x2index(Tk *tk, int x, int *xc) · 178 unmodified lines | |||
| 179 | return t1; | 179 | return t1; |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | static int | ||
| 183 | x2index0(Tk *tk, int x, int *xc) | ||
| 184 | { | ||
| 185 | int xx, z; | ||
| 186 | z = x2index(tk, x, &xx); | ||
| 187 | print("x2index(%d)-> (%d, %d)\n", x, z, xx); | ||
| 188 | if (xc) | ||
| 189 | *xc = xx; | ||
| 190 | return z; | ||
| 191 | } | ||
| 192 | |||
| 193 | /* | 182 | /* |
| 194 | * recalculate derived values | 183 | * recalculate derived values |
| 195 | */ | 184 | */ |
| @@ -143,7 +143,7 @@ ensuregridsize(TkGrid *grid, Point dim) · 142 unmodified lines | |||
| 143 | for(i = olddim.y; i < dim.y; i++){ | 143 | for(i = olddim.y; i < dim.y; i++){ |
| 144 | cells[i] = malloc(sizeof(TkGridcell)*dim.x); | 144 | cells[i] = malloc(sizeof(TkGridcell)*dim.x); |
| 145 | if(cells[i] == nil){ | 145 | if(cells[i] == nil){ |
| 146 | for(i--; i >= olddim.y; i--) | 146 | while(--i >= olddim.y) |
| 147 | free(cells[i]); | 147 | free(cells[i]); |
| 148 | return TkNomem; | 148 | return TkNomem; |
| 149 | } | 149 | } |
| @@ -721,32 +721,6 @@ gridfindloc(TkGridbeam *beam, int blen, int f) · 571 unmodified lines | |||
| 721 | return -1; | 721 | return -1; |
| 722 | } | 722 | } |
| 723 | 723 | ||
| 724 | /* | ||
| 725 | * optimised way to find a given slave, but somewhat more fragile | ||
| 726 | * as it assumes the slave has already been placed on the grid. | ||
| 727 | * not tested. | ||
| 728 | */ | ||
| 729 | static int | ||
| 730 | findslave(TkGrid *grid, Tk *tk, Point *pt) | ||
| 731 | { | ||
| 732 | Point loc, dim, p; | ||
| 733 | TkGridcell **cells; | ||
| 734 | dim = grid->dim; | ||
| 735 | cells = grid->cells; | ||
| 736 | loc.x = gridfindloc(grid->cols, grid->dim.x, tk->act.x); | ||
| 737 | if(loc.x == -1) | ||
| 738 | loc.x = 0; | ||
| 739 | loc.y = gridfindloc(grid->rows, grid->dim.y, tk->act.y); | ||
| 740 | if(loc.y == -1) | ||
| 741 | loc.y = 0; | ||
| 742 | for(p.y = loc.y; p.y < dim.y; p.y++) | ||
| 743 | for(p.x = loc.x; p.x < dim.x; p.x++) | ||
| 744 | if(cells[p.y][p.x].tk == tk){ | ||
| 745 | *pt = p; | ||
| 746 | return 1; | ||
| 747 | } | ||
| 748 | return 0; | ||
| 749 | } | ||
| 750 | static char* | 724 | static char* |
| 751 | tkgridcellinfo(TkTop *t, char *arg, char **val, char *buf, char *ebuf) | 725 | tkgridcellinfo(TkTop *t, char *arg, char **val, char *buf, char *ebuf) |
| 752 | { | 726 | { |
| @@ -80,7 +80,14 @@ TkOption opts[] = · 79 unmodified lines | |||
| 80 | void | 80 | void |
| 81 | tkdelpack(Tk *t) | 81 | tkdelpack(Tk *t) |
| 82 | { | 82 | { |
| 83 | Tk *f, **l; | 83 | Tk *f, **l, *sub, *p; |
| 84 | |||
| 85 | sub = tkfindsub(t); | ||
| 86 | if(sub != nil) { | ||
| 87 | p = sub->parent; | ||
| 88 | if(tkmethod[p->type]->forgetsub != nil) | ||
| 89 | tkmethod[p->type]->forgetsub(sub, t); | ||
| 90 | } | ||
| 84 | 91 | ||
| 85 | if(t->master == nil) | 92 | if(t->master == nil) |
| 86 | return; | 93 | return; |
| @@ -571,6 +571,7 @@ tktbbox(Tk *tk, TkTindex *ix) · 570 unmodified lines | |||
| 571 | /* r in V space */ | 571 | /* r in V space */ |
| 572 | r.min = subpt(l->orig, tkt->deltatv); | 572 | r.min = subpt(l->orig, tkt->deltatv); |
| 573 | r.min.y += l->ascent; | 573 | r.min.y += l->ascent; |
| 574 | r.max = r.min; | ||
| 574 | 575 | ||
| 575 | /* tabs dependon tags of first non-mark on display line */ | 576 | /* tabs dependon tags of first non-mark on display line */ |
| 576 | for(i = l->items; i->kind == TkTmark; ) | 577 | for(i = l->items; i->kind == TkTmark; ) |
| @@ -117,6 +117,8 @@ static TkEbind tktbinds[] = { · 116 unmodified lines | |||
| 117 | {TkKey|Pgdown, "%W yview scroll 0.75 page"}, | 117 | {TkKey|Pgdown, "%W yview scroll 0.75 page"}, |
| 118 | {TkKey|CNTL('w'), "%W tkTextDelIns -w"}, | 118 | {TkKey|CNTL('w'), "%W tkTextDelIns -w"}, |
| 119 | {TkKey|Pgup, "%W yview scroll -0.75 page"}, | 119 | {TkKey|Pgup, "%W yview scroll -0.75 page"}, |
| 120 | {TkButton4P, "%W yview scroll -0.2 page"}, | ||
| 121 | {TkButton5P, "%W yview scroll 0.2 page"}, | ||
| 120 | {TkFocusout, "%W tkTextCursor delete"}, | 122 | {TkFocusout, "%W tkTextCursor delete"}, |
| 121 | {TkKey|APP|'\t', ""}, | 123 | {TkKey|APP|'\t', ""}, |
| 122 | {TkKey|BackTab, ""}, | 124 | {TkKey|BackTab, ""}, |
| @@ -112,16 +112,16 @@ struct TkText · 111 unmodified lines | |||
| 112 | struct TkTwind | 112 | struct TkTwind |
| 113 | { | 113 | { |
| 114 | Tk* sub; /* Subwindow of canvas */ | 114 | Tk* sub; /* Subwindow of canvas */ |
| 115 | Tk* focus; /* Current Mouse focus */ | ||
| 116 | int width; /* current internal width */ | ||
| 117 | int height; /* current internal height */ | ||
| 118 | int owned; /* true if window is destroyed on item deletion */ | ||
| 115 | int align; /* how to align within line */ | 119 | int align; /* how to align within line */ |
| 116 | char* create; /* creation script */ | 120 | char* create; /* creation script */ |
| 117 | int padx; /* extra space on each side */ | 121 | int padx; /* extra space on each side */ |
| 118 | int pady; /* extra space on top and bot */ | 122 | int pady; /* extra space on top and bot */ |
| 119 | int width; /* current internal width */ | ||
| 120 | int height; /* current internal height */ | ||
| 121 | int ascent; /* distance from top of widget to baseline */ | 123 | int ascent; /* distance from top of widget to baseline */ |
| 122 | int stretch; /* true if need to stretch height */ | 124 | int stretch; /* true if need to stretch height */ |
| 123 | int owned; /* true if window is destroyed on item deletion */ | ||
| 124 | Tk* focus; /* Current Mouse focus */ | ||
| 125 | }; | 125 | }; |
| 126 | 126 | ||
| 127 | struct TkTitem | 127 | struct TkTitem |
| @@ -383,9 +383,9 @@ tktwinnames(Tk *tk, char *arg, char **val) · 382 unmodified lines | |||
| 383 | tktstartind(tkt, &ix); | 383 | tktstartind(tkt, &ix); |
| 384 | fmt = "%s"; | 384 | fmt = "%s"; |
| 385 | do { | 385 | do { |
| 386 | if(ix.item->kind == TkTwin | 386 | if(ix.item->kind == TkTwin && |
| 387 | && ix.item->iwin->sub != nil | 387 | ix.item->iwin->sub != nil && |
| 388 | && (ix.item->iwin->sub->name != nil)) { | 388 | ix.item->iwin->sub->name != nil) { |
| 389 | e = tkvalue(val, fmt, ix.item->iwin->sub->name->name); | 389 | e = tkvalue(val, fmt, ix.item->iwin->sub->name->name); |
| 390 | if(e != nil) | 390 | if(e != nil) |
| 391 | return e; | 391 | return e; |
| @@ -56,7 +56,8 @@ static struct Cmd cmdmain[] = · 55 unmodified lines | |||
| 56 | 56 | ||
| 57 | char* tkfont; | 57 | char* tkfont; |
| 58 | 58 | ||
| 59 | /* auto-repeating support | 59 | /* |
| 60 | * auto-repeating support | ||
| 60 | * should perhaps be one rptproc per TkCtxt | 61 | * should perhaps be one rptproc per TkCtxt |
| 61 | * This is not done for the moment as there isn't | 62 | * This is not done for the moment as there isn't |
| 62 | * a mechanism for terminating the rptproc | 63 | * a mechanism for terminating the rptproc |
| @@ -1016,17 +1017,25 @@ tkdrawstring(Tk *tk, Image *i, Point o, char *text, int ul, Image *col, int j) · 953 unmodified lines | |||
| 1016 | char* | 1017 | char* |
| 1017 | tkname(Tk *tk) | 1018 | tkname(Tk *tk) |
| 1018 | { | 1019 | { |
| 1019 | return tk ? (tk->name ? tk->name->name : "(noname)") : "(nil)"; | 1020 | if(tk == nil) |
| 1021 | return "(nil)"; | ||
| 1022 | if(tk->name == nil) | ||
| 1023 | return "(noname)"; | ||
| 1024 | return tk->name->name; | ||
| 1020 | } | 1025 | } |
| 1021 | 1026 | ||
| 1022 | Tk* | 1027 | Tk* |
| 1023 | tkdeliver(Tk *tk, int event, void *data) | 1028 | tkdeliver(Tk *tk, int event, void *data) |
| 1024 | { | 1029 | { |
| 1025 | Tk *dest; | 1030 | Tk *dest; |
| 1031 | |||
| 1032 | if(tk != nil && ((ulong)tk->type >= TKwidgets || (ulong)tk->name < 4096 && tk->name != nil)){ | ||
| 1033 | print("invalid Tk: type %d name %p\n", tk->type, tk->name); | ||
| 1034 | abort(); | ||
| 1035 | } | ||
| 1026 | //print("tkdeliver %v to %s\n", event, tkname(tk)); | 1036 | //print("tkdeliver %v to %s\n", event, tkname(tk)); |
| 1027 | if(tk == nil || ((tk->flag&Tkdestroy) && event != TkDestroy)) | 1037 | if(tk == nil || ((tk->flag&Tkdestroy) && event != TkDestroy)) |
| 1028 | return tk; | 1038 | return tk; |
| 1029 | |||
| 1030 | if(event&(TkFocusin|TkFocusout) && (tk->flag&Tktakefocus)) | 1039 | if(event&(TkFocusin|TkFocusout) && (tk->flag&Tktakefocus)) |
| 1031 | tk->dirty = tkrect(tk, 1); | 1040 | tk->dirty = tkrect(tk, 1); |
| 1032 | 1041 | ||
| @@ -1058,6 +1067,7 @@ tksubdeliver(Tk *tk, TkAction *binds, int event, void *data, int extn) · 25 unmodified lines | |||
| 1058 | TkAction *a; | 1067 | TkAction *a; |
| 1059 | int delivered, genkey, delivered2, iskey; | 1068 | int delivered, genkey, delivered2, iskey; |
| 1060 | //int (*debug)(char *fmt, ...); | 1069 | //int (*debug)(char *fmt, ...); |
| 1070 | |||
| 1061 | if (!extn) | 1071 | if (!extn) |
| 1062 | return tkextndeliver(tk, binds, event, data); | 1072 | return tkextndeliver(tk, binds, event, data); |
| 1063 | 1073 | ||
| @@ -1201,20 +1211,18 @@ tkitem(char *buf, char *a) · 137 unmodified lines | |||
| 1201 | return a; | 1211 | return a; |
| 1202 | } | 1212 | } |
| 1203 | 1213 | ||
| 1204 | int | 1214 | /* |
| 1205 | tkismapped(Tk *tk) | 1215 | * if tk is a subwindow or a descendent, return the subwindow; |
| 1216 | * return nil otherwise | ||
| 1217 | */ | ||
| 1218 | Tk* | ||
| 1219 | tkfindsub(Tk *tk) | ||
| 1206 | { | 1220 | { |
| 1207 | while(tk->master) | 1221 | for(; tk != nil; tk = tk->master){ |
| 1208 | tk = tk->master; | 1222 | if(tk->parent != nil) |
| 1209 | 1223 | return tk; /* tk->parent is canvas or text */ | |
| 1210 | /* We need subwindows of text & canvas to appear mapped always | 1224 | } |
| 1211 | * so that the geom function update are seen by the parent | 1225 | return nil; |
| 1212 | * widget | ||
| 1213 | */ | ||
| 1214 | if((tk->flag & Tkwindow) == 0) | ||
| 1215 | return 1; | ||
| 1216 | |||
| 1217 | return tk->flag & Tkmapped; | ||
| 1218 | } | 1226 | } |
| 1219 | 1227 | ||
| 1220 | /* | 1228 | /* |
| @@ -1233,21 +1241,19 @@ tkposn(Tk *tk) · 12 unmodified lines | |||
| 1233 | if(tk->parent != nil) { | 1241 | if(tk->parent != nil) { |
| 1234 | g = tkmethod[tk->parent->type]->relpos(tk); | 1242 | g = tkmethod[tk->parent->type]->relpos(tk); |
| 1235 | f = tk->parent; | 1243 | f = tk->parent; |
| 1236 | } | 1244 | } else { |
| 1237 | else { | ||
| 1238 | g.x = tk->act.x; | 1245 | g.x = tk->act.x; |
| 1239 | g.y = tk->act.y; | 1246 | g.y = tk->act.y; |
| 1240 | f = tk->master; | 1247 | f = tk->master; |
| 1241 | } | 1248 | } |
| 1242 | while(f) { | 1249 | while(f != nil) { |
| 1243 | g.x += f->borderwidth; | 1250 | g.x += f->borderwidth; |
| 1244 | g.y += f->borderwidth; | 1251 | g.y += f->borderwidth; |
| 1245 | last = f; | 1252 | last = f; |
| 1246 | if(f->parent != nil) { | 1253 | if(f->parent != nil) { |
| 1247 | g = addpt(g, tkmethod[f->parent->type]->relpos(f)); | 1254 | g = addpt(g, tkmethod[f->parent->type]->relpos(f)); |
| 1248 | f = f->parent; | 1255 | f = f->parent; |
| 1249 | } | 1256 | } else { |
| 1250 | else { | ||
| 1251 | g.x += f->act.x; | 1257 | g.x += f->act.x; |
| 1252 | g.y += f->act.y; | 1258 | g.y += f->act.y; |
| 1253 | f = f->master; | 1259 | f = f->master; |
| @@ -2064,3 +2070,55 @@ tkblink(Tk *tk, void (*callback)(Tk*, int)) · 810 unmodified lines | |||
| 2064 | else | 2070 | else |
| 2065 | rptwakeup(nil, blinkrpt); | 2071 | rptwakeup(nil, blinkrpt); |
| 2066 | } | 2072 | } |
| 2073 | |||
| 2074 | /* | ||
| 2075 | * debugging | ||
| 2076 | */ | ||
| 2077 | void | ||
| 2078 | tkdump(Tk *tk) | ||
| 2079 | { | ||
| 2080 | Tk *sl; | ||
| 2081 | |||
| 2082 | if(tk == nil) | ||
| 2083 | return; | ||
| 2084 | if((uint)tk->type < TKwidgets) | ||
| 2085 | print("%s", tkmethod[tk->type]->name); | ||
| 2086 | else | ||
| 2087 | print("TYPE#%#ux", tk->type); | ||
| 2088 | if(tk->name == nil || (ulong)tk->name < 512) | ||
| 2089 | print(" NAME %p", tk->name); | ||
| 2090 | else | ||
| 2091 | print(" %s", tkname(tk)); | ||
| 2092 | print(" # tk %#p flag %#ux grid %#p", tk, tk->flag, tk->grid); | ||
| 2093 | if(tk->parent != nil) | ||
| 2094 | print(" parent [%#p %q]", tk->parent, tkname(tk->parent)); | ||
| 2095 | if(tk->master != nil) | ||
| 2096 | print(" master [%#p %q]", tk->master, tkname(tk->master)); | ||
| 2097 | if(tk->slave != nil){ | ||
| 2098 | print(" slaves"); | ||
| 2099 | for(sl = tk->slave; sl != nil; sl = sl->next) | ||
| 2100 | print(" [%#p %q]", sl, tkname(sl)); | ||
| 2101 | } | ||
| 2102 | print("\n"); | ||
| 2103 | if(tk->type != TKcanvas) | ||
| 2104 | return; | ||
| 2105 | tkcvsdump(tk); | ||
| 2106 | } | ||
| 2107 | |||
| 2108 | void | ||
| 2109 | tktopdump(Tk *tk) | ||
| 2110 | { | ||
| 2111 | TkTop *top; | ||
| 2112 | Tk *sub; | ||
| 2113 | |||
| 2114 | if(tk == nil || tk->env == nil){ | ||
| 2115 | print("# %#p no top\n", tk); | ||
| 2116 | return; | ||
| 2117 | } | ||
| 2118 | top = tk->env->top; | ||
| 2119 | print("# env %#p top %#p\n", tk->env, top); | ||
| 2120 | if(top != nil){ | ||
| 2121 | for(sub = top->root; sub != nil; sub = sub->siblings) | ||
| 2122 | tkdump(sub); | ||
| 2123 | } | ||
| 2124 | } | ||
| @@ -388,29 +388,6 @@ tkmap(Tk *tk) · 387 unmodified lines | |||
| 388 | //tkupdate(tk->env->top); | 388 | //tkupdate(tk->env->top); |
| 389 | } | 389 | } |
| 390 | 390 | ||
| 391 | void | ||
| 392 | tkclrfocus(Tk *master) | ||
| 393 | { | ||
| 394 | TkCtxt *c; | ||
| 395 | Tk *tk; | ||
| 396 | TkTop *top; | ||
| 397 | |||
| 398 | if(master == nil) | ||
| 399 | return; | ||
| 400 | top = master->env->top; | ||
| 401 | c = top->ctxt; | ||
| 402 | |||
| 403 | tk = c->mgrab; | ||
| 404 | if(tkischild(master, tk)) | ||
| 405 | tksetmgrab(top, nil); | ||
| 406 | |||
| 407 | tk = c->entered; | ||
| 408 | if(tkischild(master, tk)){ | ||
| 409 | c->entered = nil; | ||
| 410 | tkdeliver(tk, TkLeave, nil); | ||
| 411 | } | ||
| 412 | } | ||
| 413 | |||
| 414 | void | 391 | void |
| 415 | tkunmap(Tk *tk) | 392 | tkunmap(Tk *tk) |
| 416 | { | 393 | { |