History

20100821-1800

forsyth committed 16 years ago

Commit 749be191 parent 31d059f16 files · +212 −102Browse files

Unified · Split

16 files
  1. include/tk.h +9 −3
  2. include/version.h +1 −1
  3. libtk/canvs.c +3 −1
  4. libtk/canvs.h +2 −0
  5. libtk/canvu.c +44 −4
  6. libtk/cwind.c +51 −0
  7. libtk/ebind.c +4 −3
  8. libtk/entry.c +0 −11
  9. libtk/grids.c +1 −27
  10. libtk/packr.c +8 −1
  11. libtk/textu.c +1 −0
  12. libtk/textw.c +2 −0
  13. libtk/textw.h +4 −4
  14. libtk/twind.c +3 −3
  15. libtk/utils.c +79 −21
  16. libtk/windw.c +0 −23
include/tk.h+9−3
@@ -455,7 +455,7 @@ struct Tk · 454 unmodified lines
455455 Tk* master; /* Pack owner */
456456 Tk* slave; /* Packer slaves */
457457 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 */
459459 Tk* depth; /* Window depth when mapped */
460460 void (*geom)(Tk*, int, int, int, int); /* Geometry change notify function */
461461 void (*destroyed)(Tk*); /* Destroy notify function */
@@ -473,7 +473,7 @@ struct Tk · 11 unmodified lines
473473 Rectangle dirty; /* dirty rectangle, relative to widget */
474474 TkGrid* grid; /* children are packed in a grid */
475475
476−// char obj[TKSTRUCTALIGN];
476+ /* followed by widget-dependent data */
477477 };
478478
479479 struct TkWin
@@ -514,6 +514,7 @@ struct TkMethod · 34 unmodified lines
514514 void (*see)(Tk*, Rectangle*, Point*);
515515 Tk* (*inwindow)(Tk*, Point*);
516516 void (*varchanged)(Tk*, char*, char*);
517+ void (*forgetsub)(Tk*, Tk*);
517518 int ncmd;
518519 };
519520
@@ -733,6 +734,7 @@ extern TkEnv* tkdefaultenv(TkTop*); · 213 unmodified lines
733734 extern void tkputenv(TkEnv*);
734735 extern TkEnv* tkdupenv(TkEnv**);
735736 extern Tk* tknewobj(TkTop*, int, int);
737+extern Tk* tkfindsub(Tk*);
736738 extern void tkfreebind(TkAction*);
737739 extern void tkfreename(TkName*);
738740 extern void tkfreeobj(Tk*);
@@ -750,7 +752,6 @@ extern int tksubdeliver(Tk*, TkAction*, int, void*, int); · 11 unmodified lines
750752 extern void tkcancel(TkAction**, int);
751753 extern char* tkaction(TkAction**, int, int, char*, int);
752754 extern char* tkitem(char*, char*);
753−extern int tkismapped(Tk*);
754755 extern Point tkposn(Tk*);
755756 extern Point tkscrn2local(Tk*, Point);
756757 extern int tkvisiblerect(Tk *tk, Rectangle *rr);
@@ -818,6 +819,11 @@ extern int tkextnnewctxt(TkCtxt*); · 61 unmodified lines
818819 extern void tkextnfreectxt(TkCtxt*);
819820 extern char* tkextnparseseq(char*, char*, int*);
820821
822+/* Debugging */
823+extern void tkdump(Tk*);
824+extern void tktopdump(Tk*);
825+extern void tkcvsdump(Tk*);
826+
821827 /* External to libtk */
822828 extern void tkenterleave(TkTop*);
823829 extern void tksetwinimage(Tk*, Image*);
include/version.h+1−1
@@ -1 +1 @@
1−#define VERSION "Fourth Edition (20100819)"
1+#define VERSION "Fourth Edition (20100821)"
libtk/canvs.c+3−1
@@ -2214,5 +2214,7 @@ TkMethod canvasmethod = { · 2213 unmodified lines
22142214 tkcvsrelpos,
22152215 tkcvsevent,
22162216 tkcvsseesub,
2217− tkcvsinwindow
2217+ tkcvsinwindow,
2218+ nil,
2219+ tkcvsforgetsub,
22182220 };
libtk/canvs.h+2−0
@@ -236,3 +236,5 @@ extern char* tkcvsimgcoord(TkCitem*, char*, int, int); · 235 unmodified lines
236236 extern char* tkcvsimgcget(TkCitem*, char*, char**);
237237 extern char* tkcvsimgconf(Tk*, TkCitem*, char*);
238238
239+extern TkCitem* tkcvsfindwin(Tk*);
240+extern void tkcvsforgetsub(Tk*, Tk*);
libtk/canvu.c+44−4
@@ -426,18 +426,22 @@ tkcvsdeliver(Tk *tk, TkCitem *i, int event, void *data) · 425 unmodified lines
426426 if(!(event & TkKey) && (event & TkEmouse)) {
427427 ftk = tkcvsmouseinsub(w, *(TkMouse*)data);
428428 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);}
429430 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));
430433 tkdeliver(ftk, TkEnter, data);
431434 w->focus = ftk;
432435 }
436+else{TkCitem *si; if(ftk != nil && (si = tkcvsfindwin(ftk)) != i)print("focus botch 2: i=%p si=%p\n", i, si);}
433437 if(ftk != nil)
434438 dest = tkdeliver(ftk, event, data);
435− }
436− else {
437− if (event & TkLeave) {
439+ } else {
440+{TkCitem *si; if(w->focus != nil && (si = tkcvsfindwin(w->focus)) != i)print("focus botch 3: i=%p si=%p\n", i, si);}
441+ if(event & TkLeave) {
438442 tkdeliver(w->focus, TkLeave, data);
439443 w->focus = nil;
440− } else if (event & TkEnter) {
444+ } else if(event & TkEnter) {
441445 ftk = tkcvsmouseinsub(w, *(TkMouse*)data);
442446 tkdeliver(ftk, TkEnter, data);
443447 w->focus = ftk;
@@ -504,3 +508,39 @@ tkcvsevent(Tk *tk, int event, void *data) · 60 unmodified lines
504508 tksubdeliver(tk, tk->binds, event, data, 0);
505509 return dest;
506510 }
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+}
libtk/cwind.c+51−0
@@ -64,6 +64,47 @@ tkcvswindsize(TkCitem *i) · 63 unmodified lines
6464 i->p.bb.max.y = p.y + s->act.height + bw;
6565 }
6666
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+
67108 static int
68109 tkcvschkwfocus(TkCwind *w, Tk *tk)
69110 {
@@ -97,6 +138,7 @@ tkcvswindgeom(Tk *sub, int x, int y, int w, int h) · 27 unmodified lines
97138 }
98139
99140 if(win->focus != nil) {
141+if(0)print("check focus %p %q %p %q\n", win, tkname(win->focus), sub, tkname(sub));
100142 if(tkcvschkwfocus(win, sub) == 0)
101143 win->focus = nil;
102144 }
@@ -128,6 +170,15 @@ tkcvssubdestry(Tk *sub) · 25 unmodified lines
128170 if(tk == nil)
129171 return;
130172
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+
131182 c = TKobj(TkCanvas, tk);
132183 for(i = c->head; i; i = i->next) {
133184 if(i->type == TkCVwindow) {
libtk/ebind.c+4−3
@@ -810,7 +810,7 @@ tkdestroy(TkTop *t, char *arg, char **ret) · 809 unmodified lines
810810 if(strcmp(buf, n) == 0) {
811811 tk->flag |= Tkdestroy;
812812 found = 1;
813− } else if(isroot || (strncmp(buf, n, len) == 0 &&n[len] == '.'))
813+ } else if(isroot || (strncmp(buf, n, len) == 0 && n[len] == '.'))
814814 tk->flag |= Tkdestroy;
815815 }
816816 }
@@ -827,13 +827,14 @@ tkdestroy(TkTop *t, char *arg, char **ret) · 10 unmodified lines
827827 continue;
828828 if(tk->flag & Tkwindow) {
829829 tkunmap(tk);
830− if((tk->name != nil)
831− && (strcmp(tk->name->name, ".") == 0))
830+ if(tk->name != nil &&
831+ strcmp(tk->name->name, ".") == 0)
832832 tk->flag &= ~Tkdestroy;
833833 else
834834 tkdeliver(tk, TkDestroy, nil);
835835 } else
836836 tkdeliver(tk, TkDestroy, nil);
837+if(0)print("tkdestroy %q\n", tkname(tk));
837838 if(tk->destroyed != nil)
838839 tk->destroyed(tk);
839840 tkpackqit(tk->master);
libtk/entry.c+0−11
@@ -179,17 +179,6 @@ x2index(Tk *tk, int x, int *xc) · 178 unmodified lines
179179 return t1;
180180 }
181181
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−
193182 /*
194183 * recalculate derived values
195184 */
libtk/grids.c+1−27
@@ -143,7 +143,7 @@ ensuregridsize(TkGrid *grid, Point dim) · 142 unmodified lines
143143 for(i = olddim.y; i < dim.y; i++){
144144 cells[i] = malloc(sizeof(TkGridcell)*dim.x);
145145 if(cells[i] == nil){
146− for(i--; i >= olddim.y; i--)
146+ while(--i >= olddim.y)
147147 free(cells[i]);
148148 return TkNomem;
149149 }
@@ -721,32 +721,6 @@ gridfindloc(TkGridbeam *beam, int blen, int f) · 571 unmodified lines
721721 return -1;
722722 }
723723
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−}
750724 static char*
751725 tkgridcellinfo(TkTop *t, char *arg, char **val, char *buf, char *ebuf)
752726 {
libtk/packr.c+8−1
@@ -80,7 +80,14 @@ TkOption opts[] = · 79 unmodified lines
8080 void
8181 tkdelpack(Tk *t)
8282 {
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+ }
8491
8592 if(t->master == nil)
8693 return;
libtk/textu.c+1−0
@@ -571,6 +571,7 @@ tktbbox(Tk *tk, TkTindex *ix) · 570 unmodified lines
571571 /* r in V space */
572572 r.min = subpt(l->orig, tkt->deltatv);
573573 r.min.y += l->ascent;
574+ r.max = r.min;
574575
575576 /* tabs dependon tags of first non-mark on display line */
576577 for(i = l->items; i->kind == TkTmark; )
libtk/textw.c+2−0
@@ -117,6 +117,8 @@ static TkEbind tktbinds[] = { · 116 unmodified lines
117117 {TkKey|Pgdown, "%W yview scroll 0.75 page"},
118118 {TkKey|CNTL('w'), "%W tkTextDelIns -w"},
119119 {TkKey|Pgup, "%W yview scroll -0.75 page"},
120+ {TkButton4P, "%W yview scroll -0.2 page"},
121+ {TkButton5P, "%W yview scroll 0.2 page"},
120122 {TkFocusout, "%W tkTextCursor delete"},
121123 {TkKey|APP|'\t', ""},
122124 {TkKey|BackTab, ""},
libtk/textw.h+4−4
@@ -112,16 +112,16 @@ struct TkText · 111 unmodified lines
112112 struct TkTwind
113113 {
114114 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 */
115119 int align; /* how to align within line */
116120 char* create; /* creation script */
117121 int padx; /* extra space on each side */
118122 int pady; /* extra space on top and bot */
119− int width; /* current internal width */
120− int height; /* current internal height */
121123 int ascent; /* distance from top of widget to baseline */
122124 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 */
125125 };
126126
127127 struct TkTitem
libtk/twind.c+3−3
@@ -383,9 +383,9 @@ tktwinnames(Tk *tk, char *arg, char **val) · 382 unmodified lines
383383 tktstartind(tkt, &ix);
384384 fmt = "%s";
385385 do {
386− if(ix.item->kind == TkTwin
387− && ix.item->iwin->sub != nil
388− && (ix.item->iwin->sub->name != nil)) {
386+ if(ix.item->kind == TkTwin &&
387+ ix.item->iwin->sub != nil &&
388+ ix.item->iwin->sub->name != nil) {
389389 e = tkvalue(val, fmt, ix.item->iwin->sub->name->name);
390390 if(e != nil)
391391 return e;
libtk/utils.c+79−21
@@ -56,7 +56,8 @@ static struct Cmd cmdmain[] = · 55 unmodified lines
5656
5757 char* tkfont;
5858
59−/* auto-repeating support
59+/*
60+ * auto-repeating support
6061 * should perhaps be one rptproc per TkCtxt
6162 * This is not done for the moment as there isn't
6263 * 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
10161017 char*
10171018 tkname(Tk *tk)
10181019 {
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;
10201025 }
10211026
10221027 Tk*
10231028 tkdeliver(Tk *tk, int event, void *data)
10241029 {
10251030 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+ }
10261036 //print("tkdeliver %v to %s\n", event, tkname(tk));
10271037 if(tk == nil || ((tk->flag&Tkdestroy) && event != TkDestroy))
10281038 return tk;
1029−
10301039 if(event&(TkFocusin|TkFocusout) && (tk->flag&Tktakefocus))
10311040 tk->dirty = tkrect(tk, 1);
10321041
@@ -1058,6 +1067,7 @@ tksubdeliver(Tk *tk, TkAction *binds, int event, void *data, int extn) · 25 unmodified lines
10581067 TkAction *a;
10591068 int delivered, genkey, delivered2, iskey;
10601069 //int (*debug)(char *fmt, ...);
1070+
10611071 if (!extn)
10621072 return tkextndeliver(tk, binds, event, data);
10631073
@@ -1201,20 +1211,18 @@ tkitem(char *buf, char *a) · 137 unmodified lines
12011211 return a;
12021212 }
12031213
1204−int
1205−tkismapped(Tk *tk)
1214+/*
1215+ * if tk is a subwindow or a descendent, return the subwindow;
1216+ * return nil otherwise
1217+ */
1218+Tk*
1219+tkfindsub(Tk *tk)
12061220 {
1207− while(tk->master)
1208− tk = tk->master;
1209−
1210− /* We need subwindows of text & canvas to appear mapped always
1211− * so that the geom function update are seen by the parent
1212− * widget
1213− */
1214− if((tk->flag & Tkwindow) == 0)
1215− return 1;
1216−
1217− return tk->flag & Tkmapped;
1221+ for(; tk != nil; tk = tk->master){
1222+ if(tk->parent != nil)
1223+ return tk; /* tk->parent is canvas or text */
1224+ }
1225+ return nil;
12181226 }
12191227
12201228 /*
@@ -1233,21 +1241,19 @@ tkposn(Tk *tk) · 12 unmodified lines
12331241 if(tk->parent != nil) {
12341242 g = tkmethod[tk->parent->type]->relpos(tk);
12351243 f = tk->parent;
1236− }
1237− else {
1244+ } else {
12381245 g.x = tk->act.x;
12391246 g.y = tk->act.y;
12401247 f = tk->master;
12411248 }
1242− while(f) {
1249+ while(f != nil) {
12431250 g.x += f->borderwidth;
12441251 g.y += f->borderwidth;
12451252 last = f;
12461253 if(f->parent != nil) {
12471254 g = addpt(g, tkmethod[f->parent->type]->relpos(f));
12481255 f = f->parent;
1249− }
1250− else {
1256+ } else {
12511257 g.x += f->act.x;
12521258 g.y += f->act.y;
12531259 f = f->master;
@@ -2064,3 +2070,55 @@ tkblink(Tk *tk, void (*callback)(Tk*, int)) · 810 unmodified lines
20642070 else
20652071 rptwakeup(nil, blinkrpt);
20662072 }
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+}
libtk/windw.c+0−23
@@ -388,29 +388,6 @@ tkmap(Tk *tk) · 387 unmodified lines
388388 //tkupdate(tk->env->top);
389389 }
390390
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−
414391 void
415392 tkunmap(Tk *tk)
416393 {