summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorforsyth <forsyth@vitanuova.com>2010-08-21 18:01:11 +0100
committerforsyth <forsyth@vitanuova.com>2010-08-21 18:01:11 +0100
commit5849851a19380dbb62a47d9c4d868a81e42fa79b (patch)
tree075bc8e4607ab67e67781fdad26dcb6d93491b1a
parent55b0bc0011ddae9df99d50fa0498110585d09a81 (diff)
20100821-1800
-rw-r--r--include/tk.h12
-rw-r--r--include/version.h2
-rw-r--r--libtk/canvs.c4
-rw-r--r--libtk/canvs.h2
-rw-r--r--libtk/canvu.c48
-rw-r--r--libtk/cwind.c51
-rw-r--r--libtk/ebind.c7
-rw-r--r--libtk/entry.c11
-rw-r--r--libtk/grids.c28
-rw-r--r--libtk/packr.c9
-rw-r--r--libtk/textu.c1
-rw-r--r--libtk/textw.c2
-rw-r--r--libtk/textw.h8
-rw-r--r--libtk/twind.c6
-rw-r--r--libtk/utils.c100
-rw-r--r--libtk/windw.c23
16 files changed, 212 insertions, 102 deletions
diff --git a/include/tk.h b/include/tk.h
index b990f621..4abfc38c 100644
--- a/include/tk.h
+++ b/include/tk.h
@@ -455,7 +455,7 @@ struct Tk
Tk* master; /* Pack owner */
Tk* slave; /* Packer slaves */
Tk* next; /* Link for packer slaves */
- Tk* parent; /* Window is sub of canvas or text */
+ Tk* parent; /* Window is sub of this canvas or text */
Tk* depth; /* Window depth when mapped */
void (*geom)(Tk*, int, int, int, int); /* Geometry change notify function */
void (*destroyed)(Tk*); /* Destroy notify function */
@@ -473,7 +473,7 @@ struct Tk
Rectangle dirty; /* dirty rectangle, relative to widget */
TkGrid* grid; /* children are packed in a grid */
-// char obj[TKSTRUCTALIGN];
+ /* followed by widget-dependent data */
};
struct TkWin
@@ -514,6 +514,7 @@ struct TkMethod
void (*see)(Tk*, Rectangle*, Point*);
Tk* (*inwindow)(Tk*, Point*);
void (*varchanged)(Tk*, char*, char*);
+ void (*forgetsub)(Tk*, Tk*);
int ncmd;
};
@@ -733,6 +734,7 @@ extern TkEnv* tkdefaultenv(TkTop*);
extern void tkputenv(TkEnv*);
extern TkEnv* tkdupenv(TkEnv**);
extern Tk* tknewobj(TkTop*, int, int);
+extern Tk* tkfindsub(Tk*);
extern void tkfreebind(TkAction*);
extern void tkfreename(TkName*);
extern void tkfreeobj(Tk*);
@@ -750,7 +752,6 @@ extern int tksubdeliver(Tk*, TkAction*, int, void*, int);
extern void tkcancel(TkAction**, int);
extern char* tkaction(TkAction**, int, int, char*, int);
extern char* tkitem(char*, char*);
-extern int tkismapped(Tk*);
extern Point tkposn(Tk*);
extern Point tkscrn2local(Tk*, Point);
extern int tkvisiblerect(Tk *tk, Rectangle *rr);
@@ -818,6 +819,11 @@ extern int tkextnnewctxt(TkCtxt*);
extern void tkextnfreectxt(TkCtxt*);
extern char* tkextnparseseq(char*, char*, int*);
+/* Debugging */
+extern void tkdump(Tk*);
+extern void tktopdump(Tk*);
+extern void tkcvsdump(Tk*);
+
/* External to libtk */
extern void tkenterleave(TkTop*);
extern void tksetwinimage(Tk*, Image*);
diff --git a/include/version.h b/include/version.h
index 7b0a16fb..76d36219 100644
--- a/include/version.h
+++ b/include/version.h
@@ -1 +1 @@
-#define VERSION "Fourth Edition (20100819)"
+#define VERSION "Fourth Edition (20100821)"
diff --git a/libtk/canvs.c b/libtk/canvs.c
index 06b8f93a..cb0b518e 100644
--- a/libtk/canvs.c
+++ b/libtk/canvs.c
@@ -2214,5 +2214,7 @@ TkMethod canvasmethod = {
tkcvsrelpos,
tkcvsevent,
tkcvsseesub,
- tkcvsinwindow
+ tkcvsinwindow,
+ nil,
+ tkcvsforgetsub,
};
diff --git a/libtk/canvs.h b/libtk/canvs.h
index d82b7eb1..b7a8c8d1 100644
--- a/libtk/canvs.h
+++ b/libtk/canvs.h
@@ -236,3 +236,5 @@ extern char* tkcvsimgcoord(TkCitem*, char*, int, int);
extern char* tkcvsimgcget(TkCitem*, char*, char**);
extern char* tkcvsimgconf(Tk*, TkCitem*, char*);
+extern TkCitem* tkcvsfindwin(Tk*);
+extern void tkcvsforgetsub(Tk*, Tk*);
diff --git a/libtk/canvu.c b/libtk/canvu.c
index 3894ff20..f7e65a21 100644
--- a/libtk/canvu.c
+++ b/libtk/canvu.c
@@ -426,18 +426,22 @@ tkcvsdeliver(Tk *tk, TkCitem *i, int event, void *data)
if(!(event & TkKey) && (event & TkEmouse)) {
ftk = tkcvsmouseinsub(w, *(TkMouse*)data);
if(ftk != w->focus) {
+{TkCitem *si; if(w->focus != nil && (si = tkcvsfindwin(w->focus)) != i)print("focus botch 4: i=%p si=%p\n", i, si);}
tkdeliver(w->focus, TkLeave, data);
+{TkCitem *si; if(ftk != nil && (si = tkcvsfindwin(ftk)) != i)print("focus botch: i=%p si=%p\n", i, si);}
+if(0)print("focus %p %q %p %q\n", w->sub, tkname(w->sub), ftk, tkname(ftk));
tkdeliver(ftk, TkEnter, data);
w->focus = ftk;
}
+else{TkCitem *si; if(ftk != nil && (si = tkcvsfindwin(ftk)) != i)print("focus botch 2: i=%p si=%p\n", i, si);}
if(ftk != nil)
dest = tkdeliver(ftk, event, data);
- }
- else {
- if (event & TkLeave) {
+ } else {
+{TkCitem *si; if(w->focus != nil && (si = tkcvsfindwin(w->focus)) != i)print("focus botch 3: i=%p si=%p\n", i, si);}
+ if(event & TkLeave) {
tkdeliver(w->focus, TkLeave, data);
w->focus = nil;
- } else if (event & TkEnter) {
+ } else if(event & TkEnter) {
ftk = tkcvsmouseinsub(w, *(TkMouse*)data);
tkdeliver(ftk, TkEnter, data);
w->focus = ftk;
@@ -504,3 +508,39 @@ tkcvsevent(Tk *tk, int event, void *data)
tksubdeliver(tk, tk->binds, event, data, 0);
return dest;
}
+
+/*
+ * debugging
+ */
+void
+tkcvsdump(Tk *tk)
+{
+ TkCanvas *c;
+ TkCitem *it;
+ TkCwind *w;
+ char v1[Tkminitem], v2[Tkminitem];
+ int i;
+
+ if(tk == nil)
+ return;
+ c = TKobj(TkCanvas, tk);
+ tkfprint(v1, c->width);
+ tkfprint(v2, c->height);
+ print("%q configure -width %s -height %s", tkname(tk), v1, v2);
+ print(" # focus %#p mouse %#p grab %#p\n", c->focus, c->mouse, c->grab);
+ for(it = c->head; it != nil; it = it->next){
+ print("%q create %q", tkname(tk), tkcimethod[it->type].name);
+ for(i = 0; i < it->p.npoint; i++){
+ tkfprint(v1, it->p.parampt[i].x);
+ tkfprint(v2, it->p.parampt[i].y);
+ print(" %s %s", v1, v2);
+ }
+ if(it->type == TkCVwindow){
+ w = TKobj(TkCwind, it);
+ if(w->sub != nil)
+ print(" -window %q", tkname(w->sub));
+ print(" # item %#p id %d sub %#p focus [%#p %q]\n", it, it->id, w->sub, w->focus, tkname(w->focus));
+ }else
+ print("# item %#p id %d\n", it, it->id);
+ }
+}
diff --git a/libtk/cwind.c b/libtk/cwind.c
index dd25eb1b..ffdb3626 100644
--- a/libtk/cwind.c
+++ b/libtk/cwind.c
@@ -64,6 +64,47 @@ tkcvswindsize(TkCitem *i)
i->p.bb.max.y = p.y + s->act.height + bw;
}
+TkCitem*
+tkcvsfindwin(Tk *tk)
+{
+ Tk *parent, *sub;
+ TkCitem *i;
+ TkCanvas *c;
+ TkCwind *w;
+
+ sub = tkfindsub(tk);
+ if(sub == nil)
+ return nil;
+ parent = sub->parent;
+ if(parent->type != TKcanvas)
+ return nil; /* inconsistent */
+ c = TKobj(TkCanvas, parent);
+ for(i = c->head; i != nil; i = i->next) {
+ if(i->type == TkCVwindow) {
+ w = TKobj(TkCwind, i);
+ if(w->sub == sub)
+ return i;
+ }
+ }
+ return nil;
+}
+
+void
+tkcvsforgetsub(Tk *sub, Tk *tk)
+{
+ TkCwind *w;
+ TkCitem *i;
+
+ i = tkcvsfindwin(sub);
+ if(i == nil)
+ return;
+ w = TKobj(TkCwind, i);
+ if(w->focus == tk) {
+if(0)print("tkcsvsforget sub %p %q focus %p %q\n", sub, tkname(sub), tk, tkname(tk));
+ w->focus = nil;
+ }
+}
+
static int
tkcvschkwfocus(TkCwind *w, Tk *tk)
{
@@ -97,6 +138,7 @@ tkcvswindgeom(Tk *sub, int x, int y, int w, int h)
}
if(win->focus != nil) {
+if(0)print("check focus %p %q %p %q\n", win, tkname(win->focus), sub, tkname(sub));
if(tkcvschkwfocus(win, sub) == 0)
win->focus = nil;
}
@@ -128,6 +170,15 @@ tkcvssubdestry(Tk *sub)
if(tk == nil)
return;
+if(0)print("tkcvssubdestry %p %q\n", sub, tkname(sub));
+ i = tkcvsfindwin(sub);
+ if(i != nil){
+ win = TKobj(TkCwind, i);
+ if(win->sub != sub){
+ print("inconsistent tkcvssubdestry %p %q\n", sub, tkname(sub));
+ }
+ }
+
c = TKobj(TkCanvas, tk);
for(i = c->head; i; i = i->next) {
if(i->type == TkCVwindow) {
diff --git a/libtk/ebind.c b/libtk/ebind.c
index 4ef3c686..8a9694ce 100644
--- a/libtk/ebind.c
+++ b/libtk/ebind.c
@@ -810,7 +810,7 @@ tkdestroy(TkTop *t, char *arg, char **ret)
if(strcmp(buf, n) == 0) {
tk->flag |= Tkdestroy;
found = 1;
- } else if(isroot || (strncmp(buf, n, len) == 0 &&n[len] == '.'))
+ } else if(isroot || (strncmp(buf, n, len) == 0 && n[len] == '.'))
tk->flag |= Tkdestroy;
}
}
@@ -827,13 +827,14 @@ tkdestroy(TkTop *t, char *arg, char **ret)
continue;
if(tk->flag & Tkwindow) {
tkunmap(tk);
- if((tk->name != nil)
- && (strcmp(tk->name->name, ".") == 0))
+ if(tk->name != nil &&
+ strcmp(tk->name->name, ".") == 0)
tk->flag &= ~Tkdestroy;
else
tkdeliver(tk, TkDestroy, nil);
} else
tkdeliver(tk, TkDestroy, nil);
+if(0)print("tkdestroy %q\n", tkname(tk));
if(tk->destroyed != nil)
tk->destroyed(tk);
tkpackqit(tk->master);
diff --git a/libtk/entry.c b/libtk/entry.c
index cb7c2b63..9757702e 100644
--- a/libtk/entry.c
+++ b/libtk/entry.c
@@ -179,17 +179,6 @@ x2index(Tk *tk, int x, int *xc)
return t1;
}
-static int
-x2index0(Tk *tk, int x, int *xc)
-{
- int xx, z;
- z = x2index(tk, x, &xx);
- print("x2index(%d)-> (%d, %d)\n", x, z, xx);
- if (xc)
- *xc = xx;
- return z;
-}
-
/*
* recalculate derived values
*/
diff --git a/libtk/grids.c b/libtk/grids.c
index 4403fba2..e1ba5dd9 100644
--- a/libtk/grids.c
+++ b/libtk/grids.c
@@ -143,7 +143,7 @@ ensuregridsize(TkGrid *grid, Point dim)
for(i = olddim.y; i < dim.y; i++){
cells[i] = malloc(sizeof(TkGridcell)*dim.x);
if(cells[i] == nil){
- for(i--; i >= olddim.y; i--)
+ while(--i >= olddim.y)
free(cells[i]);
return TkNomem;
}
@@ -721,32 +721,6 @@ gridfindloc(TkGridbeam *beam, int blen, int f)
return -1;
}
-/*
- * optimised way to find a given slave, but somewhat more fragile
- * as it assumes the slave has already been placed on the grid.
- * not tested.
- */
-static int
-findslave(TkGrid *grid, Tk *tk, Point *pt)
-{
- Point loc, dim, p;
- TkGridcell **cells;
- dim = grid->dim;
- cells = grid->cells;
- loc.x = gridfindloc(grid->cols, grid->dim.x, tk->act.x);
- if(loc.x == -1)
- loc.x = 0;
- loc.y = gridfindloc(grid->rows, grid->dim.y, tk->act.y);
- if(loc.y == -1)
- loc.y = 0;
- for(p.y = loc.y; p.y < dim.y; p.y++)
- for(p.x = loc.x; p.x < dim.x; p.x++)
- if(cells[p.y][p.x].tk == tk){
- *pt = p;
- return 1;
- }
- return 0;
-}
static char*
tkgridcellinfo(TkTop *t, char *arg, char **val, char *buf, char *ebuf)
{
diff --git a/libtk/packr.c b/libtk/packr.c
index 14572e79..c5f2ac6d 100644
--- a/libtk/packr.c
+++ b/libtk/packr.c
@@ -80,7 +80,14 @@ TkOption opts[] =
void
tkdelpack(Tk *t)
{
- Tk *f, **l;
+ Tk *f, **l, *sub, *p;
+
+ sub = tkfindsub(t);
+ if(sub != nil) {
+ p = sub->parent;
+ if(tkmethod[p->type]->forgetsub != nil)
+ tkmethod[p->type]->forgetsub(sub, t);
+ }
if(t->master == nil)
return;
diff --git a/libtk/textu.c b/libtk/textu.c
index 28642130..d4187971 100644
--- a/libtk/textu.c
+++ b/libtk/textu.c
@@ -571,6 +571,7 @@ tktbbox(Tk *tk, TkTindex *ix)
/* r in V space */
r.min = subpt(l->orig, tkt->deltatv);
r.min.y += l->ascent;
+ r.max = r.min;
/* tabs dependon tags of first non-mark on display line */
for(i = l->items; i->kind == TkTmark; )
diff --git a/libtk/textw.c b/libtk/textw.c
index 7eac56bb..8a5edde3 100644
--- a/libtk/textw.c
+++ b/libtk/textw.c
@@ -117,6 +117,8 @@ static TkEbind tktbinds[] = {
{TkKey|Pgdown, "%W yview scroll 0.75 page"},
{TkKey|CNTL('w'), "%W tkTextDelIns -w"},
{TkKey|Pgup, "%W yview scroll -0.75 page"},
+ {TkButton4P, "%W yview scroll -0.2 page"},
+ {TkButton5P, "%W yview scroll 0.2 page"},
{TkFocusout, "%W tkTextCursor delete"},
{TkKey|APP|'\t', ""},
{TkKey|BackTab, ""},
diff --git a/libtk/textw.h b/libtk/textw.h
index c1519f0e..3326cdcc 100644
--- a/libtk/textw.h
+++ b/libtk/textw.h
@@ -112,16 +112,16 @@ struct TkText
struct TkTwind
{
Tk* sub; /* Subwindow of canvas */
+ Tk* focus; /* Current Mouse focus */
+ int width; /* current internal width */
+ int height; /* current internal height */
+ int owned; /* true if window is destroyed on item deletion */
int align; /* how to align within line */
char* create; /* creation script */
int padx; /* extra space on each side */
int pady; /* extra space on top and bot */
- int width; /* current internal width */
- int height; /* current internal height */
int ascent; /* distance from top of widget to baseline */
int stretch; /* true if need to stretch height */
- int owned; /* true if window is destroyed on item deletion */
- Tk* focus; /* Current Mouse focus */
};
struct TkTitem
diff --git a/libtk/twind.c b/libtk/twind.c
index 49b9c94b..19ea7afd 100644
--- a/libtk/twind.c
+++ b/libtk/twind.c
@@ -383,9 +383,9 @@ tktwinnames(Tk *tk, char *arg, char **val)
tktstartind(tkt, &ix);
fmt = "%s";
do {
- if(ix.item->kind == TkTwin
- && ix.item->iwin->sub != nil
- && (ix.item->iwin->sub->name != nil)) {
+ if(ix.item->kind == TkTwin &&
+ ix.item->iwin->sub != nil &&
+ ix.item->iwin->sub->name != nil) {
e = tkvalue(val, fmt, ix.item->iwin->sub->name->name);
if(e != nil)
return e;
diff --git a/libtk/utils.c b/libtk/utils.c
index 2b01af03..28b3318b 100644
--- a/libtk/utils.c
+++ b/libtk/utils.c
@@ -56,7 +56,8 @@ static struct Cmd cmdmain[] =
char* tkfont;
-/* auto-repeating support
+/*
+ * auto-repeating support
* should perhaps be one rptproc per TkCtxt
* This is not done for the moment as there isn't
* 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)
char*
tkname(Tk *tk)
{
- return tk ? (tk->name ? tk->name->name : "(noname)") : "(nil)";
+ if(tk == nil)
+ return "(nil)";
+ if(tk->name == nil)
+ return "(noname)";
+ return tk->name->name;
}
Tk*
tkdeliver(Tk *tk, int event, void *data)
{
Tk *dest;
+
+ if(tk != nil && ((ulong)tk->type >= TKwidgets || (ulong)tk->name < 4096 && tk->name != nil)){
+ print("invalid Tk: type %d name %p\n", tk->type, tk->name);
+ abort();
+ }
//print("tkdeliver %v to %s\n", event, tkname(tk));
if(tk == nil || ((tk->flag&Tkdestroy) && event != TkDestroy))
return tk;
-
if(event&(TkFocusin|TkFocusout) && (tk->flag&Tktakefocus))
tk->dirty = tkrect(tk, 1);
@@ -1058,6 +1067,7 @@ tksubdeliver(Tk *tk, TkAction *binds, int event, void *data, int extn)
TkAction *a;
int delivered, genkey, delivered2, iskey;
//int (*debug)(char *fmt, ...);
+
if (!extn)
return tkextndeliver(tk, binds, event, data);
@@ -1201,20 +1211,18 @@ tkitem(char *buf, char *a)
return a;
}
-int
-tkismapped(Tk *tk)
+/*
+ * if tk is a subwindow or a descendent, return the subwindow;
+ * return nil otherwise
+ */
+Tk*
+tkfindsub(Tk *tk)
{
- while(tk->master)
- tk = tk->master;
-
- /* We need subwindows of text & canvas to appear mapped always
- * so that the geom function update are seen by the parent
- * widget
- */
- if((tk->flag & Tkwindow) == 0)
- return 1;
-
- return tk->flag & Tkmapped;
+ for(; tk != nil; tk = tk->master){
+ if(tk->parent != nil)
+ return tk; /* tk->parent is canvas or text */
+ }
+ return nil;
}
/*
@@ -1233,21 +1241,19 @@ tkposn(Tk *tk)
if(tk->parent != nil) {
g = tkmethod[tk->parent->type]->relpos(tk);
f = tk->parent;
- }
- else {
+ } else {
g.x = tk->act.x;
g.y = tk->act.y;
f = tk->master;
}
- while(f) {
+ while(f != nil) {
g.x += f->borderwidth;
g.y += f->borderwidth;
last = f;
if(f->parent != nil) {
g = addpt(g, tkmethod[f->parent->type]->relpos(f));
f = f->parent;
- }
- else {
+ } else {
g.x += f->act.x;
g.y += f->act.y;
f = f->master;
@@ -2064,3 +2070,55 @@ tkblink(Tk *tk, void (*callback)(Tk*, int))
else
rptwakeup(nil, blinkrpt);
}
+
+/*
+ * debugging
+ */
+void
+tkdump(Tk *tk)
+{
+ Tk *sl;
+
+ if(tk == nil)
+ return;
+ if((uint)tk->type < TKwidgets)
+ print("%s", tkmethod[tk->type]->name);
+ else
+ print("TYPE#%#ux", tk->type);
+ if(tk->name == nil || (ulong)tk->name < 512)
+ print(" NAME %p", tk->name);
+ else
+ print(" %s", tkname(tk));
+ print(" # tk %#p flag %#ux grid %#p", tk, tk->flag, tk->grid);
+ if(tk->parent != nil)
+ print(" parent [%#p %q]", tk->parent, tkname(tk->parent));
+ if(tk->master != nil)
+ print(" master [%#p %q]", tk->master, tkname(tk->master));
+ if(tk->slave != nil){
+ print(" slaves");
+ for(sl = tk->slave; sl != nil; sl = sl->next)
+ print(" [%#p %q]", sl, tkname(sl));
+ }
+ print("\n");
+ if(tk->type != TKcanvas)
+ return;
+ tkcvsdump(tk);
+}
+
+void
+tktopdump(Tk *tk)
+{
+ TkTop *top;
+ Tk *sub;
+
+ if(tk == nil || tk->env == nil){
+ print("# %#p no top\n", tk);
+ return;
+ }
+ top = tk->env->top;
+ print("# env %#p top %#p\n", tk->env, top);
+ if(top != nil){
+ for(sub = top->root; sub != nil; sub = sub->siblings)
+ tkdump(sub);
+ }
+}
diff --git a/libtk/windw.c b/libtk/windw.c
index 6f9fd78d..d11e8af1 100644
--- a/libtk/windw.c
+++ b/libtk/windw.c
@@ -389,29 +389,6 @@ tkmap(Tk *tk)
}
void
-tkclrfocus(Tk *master)
-{
- TkCtxt *c;
- Tk *tk;
- TkTop *top;
-
- if(master == nil)
- return;
- top = master->env->top;
- c = top->ctxt;
-
- tk = c->mgrab;
- if(tkischild(master, tk))
- tksetmgrab(top, nil);
-
- tk = c->entered;
- if(tkischild(master, tk)){
- c->entered = nil;
- tkdeliver(tk, TkLeave, nil);
- }
-}
-
-void
tkunmap(Tk *tk)
{
TkTop *t;