diff options
Diffstat (limited to 'generic/tkPack.c')
-rw-r--r-- | generic/tkPack.c | 218 |
1 files changed, 139 insertions, 79 deletions
diff --git a/generic/tkPack.c b/generic/tkPack.c index 47eddd6..b32cc23 100644 --- a/generic/tkPack.c +++ b/generic/tkPack.c @@ -14,14 +14,14 @@ #include "tkInt.h" typedef enum {TOP, BOTTOM, LEFT, RIGHT} Side; -static CONST char *sideNames[] = { +static const char *const sideNames[] = { "top", "bottom", "left", "right", NULL }; -/* For each window that the packer cares about (either because - * the window is managed by the packer or because the window - * has slaves that are managed by the packer), there is a - * structure of the following type: +/* + * For each window that the packer cares about (either because the window is + * managed by the packer or because the window has slaves that are managed by + * the packer), there is a structure of the following type: */ typedef struct Packer { @@ -32,9 +32,9 @@ typedef struct Packer { struct Packer *masterPtr; /* Master window within which this window is * packed (NULL means this window isn't * managed by the packer). */ - struct Packer *nextPtr; /* Next window packed within same master. - * List is priority-ordered: first on list - * gets packed first. */ + struct Packer *nextPtr; /* Next window packed within same master. List + * is priority-ordered: first on list gets + * packed first. */ struct Packer *slavePtr; /* First in list of slaves packed inside this * window (NULL means no packed slaves). */ Side side; /* Side of master against which this window is @@ -87,6 +87,8 @@ typedef struct Packer { * size. 0 means if this window is a master then * Tk will set its requested size to fit the * needs of its slaves. + * ALLOCED_MASTER 1 means that Pack has allocated itself as + * geometry master for this window. */ #define REQUESTED_REPACK 1 @@ -95,6 +97,7 @@ typedef struct Packer { #define EXPAND 8 #define OLD_STYLE 16 #define DONT_PROPAGATE 32 +#define ALLOCED_MASTER 64 /* * The following structure is the official type record for the packer: @@ -116,11 +119,11 @@ static const Tk_GeomMgr packerType = { static void ArrangePacking(ClientData clientData); static int ConfigureSlaves(Tcl_Interp *interp, Tk_Window tkwin, - int objc, Tcl_Obj *CONST objv[]); + int objc, Tcl_Obj *const objv[]); static void DestroyPacker(char *memPtr); static Packer * GetPacker(Tk_Window tkwin); static int PackAfter(Tcl_Interp *interp, Packer *prevPtr, - Packer *masterPtr, int objc,Tcl_Obj *CONST objv[]); + Packer *masterPtr, int objc,Tcl_Obj *const objv[]); static void PackStructureProc(ClientData clientData, XEvent *eventPtr); static void Unlink(Packer *packPtr); @@ -128,7 +131,7 @@ static int XExpansion(Packer *slavePtr, int cavityWidth); static int YExpansion(Packer *slavePtr, int cavityHeight); /* - *-------------------------------------------------------------- + *------------------------------------------------------------------------ * * TkPrintPadAmount -- * @@ -142,14 +145,14 @@ static int YExpansion(Packer *slavePtr, int cavityHeight); * Side effects: * None. * - *-------------------------------------------------------------- + *------------------------------------------------------------------------ */ void TkPrintPadAmount( Tcl_Interp *interp, /* The interpreter into which the result is * written. */ - char *switchName, /* One of "padx", "pady", "ipadx" or "ipady" */ + const char *switchName, /* One of "padx", "pady", "ipadx" or "ipady" */ int halfSpace, /* The left or top padding amount */ int allSpace) /* The total amount of padding */ { @@ -164,7 +167,7 @@ TkPrintPadAmount( } /* - *-------------------------------------------------------------- + *------------------------------------------------------------------------ * * Tk_PackCmd -- * @@ -177,7 +180,7 @@ TkPrintPadAmount( * Side effects: * See the user documentation. * - *-------------------------------------------------------------- + *------------------------------------------------------------------------ */ int @@ -185,11 +188,11 @@ Tk_PackObjCmd( ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ - Tcl_Obj *CONST objv[]) /* Argument objects. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { - Tk_Window tkwin = (Tk_Window) clientData; - char *argv2; - static CONST char *optionStrings[] = { + Tk_Window tkwin = clientData; + const char *argv2; + static const char *const optionStrings[] = { /* after, append, before and unpack are deprecated */ "after", "append", "before", "unpack", "configure", "forget", "info", "propagate", "slaves", NULL }; @@ -199,7 +202,8 @@ Tk_PackObjCmd( int index; if (objc >= 2) { - char *string = Tcl_GetString(objv[1]); + const char *string = Tcl_GetString(objv[1]); + if (string[0] == '.') { return ConfigureSlaves(interp, tkwin, objc-1, objv+1); } @@ -305,8 +309,7 @@ Tk_PackObjCmd( } slavePtr = GetPacker(slave); if ((slavePtr != NULL) && (slavePtr->masterPtr != NULL)) { - Tk_ManageGeometry(slave, NULL, - (ClientData) NULL); + Tk_ManageGeometry(slave, NULL, NULL); if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) { Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin); @@ -383,6 +386,16 @@ Tk_PackObjCmd( return TCL_ERROR; } if (propagate) { + /* + * If we have slaves, we need to register as geometry master. + */ + + if (masterPtr->slavePtr != NULL) { + if (TkSetGeometryMaster(interp, master, "pack") != TCL_OK) { + return TCL_ERROR; + } + masterPtr->flags |= ALLOCED_MASTER; + } masterPtr->flags &= ~DONT_PROPAGATE; /* @@ -395,9 +408,13 @@ Tk_PackObjCmd( } if (!(masterPtr->flags & REQUESTED_REPACK)) { masterPtr->flags |= REQUESTED_REPACK; - Tcl_DoWhenIdle(ArrangePacking, (ClientData) masterPtr); + Tcl_DoWhenIdle(ArrangePacking, masterPtr); } } else { + if (masterPtr->flags & ALLOCED_MASTER) { + TkFreeGeometryMaster(master, "pack"); + masterPtr->flags &= ~ALLOCED_MASTER; + } masterPtr->flags |= DONT_PROPAGATE; } break; @@ -405,6 +422,7 @@ Tk_PackObjCmd( case PACK_SLAVES: { Tk_Window master; Packer *masterPtr, *slavePtr; + Tcl_Obj *resultObj; if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "window"); @@ -413,11 +431,14 @@ Tk_PackObjCmd( if (TkGetWindowFromObj(interp, tkwin, objv[2], &master) != TCL_OK) { return TCL_ERROR; } + resultObj = Tcl_NewObj(); masterPtr = GetPacker(master); for (slavePtr = masterPtr->slavePtr; slavePtr != NULL; slavePtr = slavePtr->nextPtr) { - Tcl_AppendElement(interp, Tk_PathName(slavePtr->tkwin)); + Tcl_ListObjAppendElement(NULL, resultObj, + TkNewWindowObj(slavePtr->tkwin)); } + Tcl_SetObjResult(interp, resultObj); break; } case PACK_UNPACK: { @@ -433,8 +454,7 @@ Tk_PackObjCmd( } packPtr = GetPacker(tkwin2); if ((packPtr != NULL) && (packPtr->masterPtr != NULL)) { - Tk_ManageGeometry(tkwin2, NULL, - (ClientData) NULL); + Tk_ManageGeometry(tkwin2, NULL, NULL); if (packPtr->masterPtr->tkwin != Tk_Parent(packPtr->tkwin)) { Tk_UnmaintainGeometry(packPtr->tkwin, packPtr->masterPtr->tkwin); @@ -450,7 +470,7 @@ Tk_PackObjCmd( } /* - *-------------------------------------------------------------- + *------------------------------------------------------------------------ * * PackReqProc -- * @@ -464,7 +484,7 @@ Tk_PackObjCmd( * Arranges for tkwin, and all its managed siblings, to be re-packed at * the next idle point. * - *-------------------------------------------------------------- + *------------------------------------------------------------------------ */ /* ARGSUSED */ @@ -475,17 +495,17 @@ PackReqProc( Tk_Window tkwin) /* Other Tk-related information about the * window. */ { - register Packer *packPtr = (Packer *) clientData; + register Packer *packPtr = clientData; packPtr = packPtr->masterPtr; if (!(packPtr->flags & REQUESTED_REPACK)) { packPtr->flags |= REQUESTED_REPACK; - Tcl_DoWhenIdle(ArrangePacking, (ClientData) packPtr); + Tcl_DoWhenIdle(ArrangePacking, packPtr); } } /* - *-------------------------------------------------------------- + *------------------------------------------------------------------------ * * PackLostSlaveProc -- * @@ -498,7 +518,7 @@ PackReqProc( * Side effects: * Forgets all packer-related information about the slave. * - *-------------------------------------------------------------- + *------------------------------------------------------------------------ */ /* ARGSUSED */ @@ -508,7 +528,7 @@ PackLostSlaveProc( * stolen away. */ Tk_Window tkwin) /* Tk's handle for the slave window. */ { - register Packer *slavePtr = (Packer *) clientData; + register Packer *slavePtr = clientData; if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) { Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin); @@ -518,7 +538,7 @@ PackLostSlaveProc( } /* - *-------------------------------------------------------------- + *------------------------------------------------------------------------ * * ArrangePacking -- * @@ -533,7 +553,7 @@ PackLostSlaveProc( * Side effects: * The packed slaves of masterPtr may get resized or moved. * - *-------------------------------------------------------------- + *------------------------------------------------------------------------ */ static void @@ -541,7 +561,7 @@ ArrangePacking( ClientData clientData) /* Structure describing master whose slaves * are to be re-layed out. */ { - register Packer *masterPtr = (Packer *) clientData; + register Packer *masterPtr = clientData; register Packer *slavePtr; int cavityX, cavityY, cavityWidth, cavityHeight; /* These variables keep track of the @@ -581,7 +601,7 @@ ArrangePacking( } masterPtr->abortPtr = &abort; abort = 0; - Tcl_Preserve((ClientData) masterPtr); + Tcl_Preserve(masterPtr); /* * Pass #1: scan all the slaves to figure out the total amount of space @@ -650,7 +670,7 @@ ArrangePacking( && !(masterPtr->flags & DONT_PROPAGATE)) { Tk_GeometryRequest(masterPtr->tkwin, maxWidth, maxHeight); masterPtr->flags |= REQUESTED_REPACK; - Tcl_DoWhenIdle(ArrangePacking, (ClientData) masterPtr); + Tcl_DoWhenIdle(ArrangePacking, masterPtr); goto done; } @@ -841,7 +861,7 @@ ArrangePacking( done: masterPtr->abortPtr = NULL; - Tcl_Release((ClientData) masterPtr); + Tcl_Release(masterPtr); } /* @@ -888,9 +908,11 @@ XExpansion( childWidth = Tk_ReqWidth(slavePtr->tkwin) + slavePtr->doubleBw + slavePtr->padX + slavePtr->iPadX; if ((slavePtr->side == TOP) || (slavePtr->side == BOTTOM)) { - curExpand = (cavityWidth - childWidth)/numExpand; - if (curExpand < minExpand) { - minExpand = curExpand; + if (numExpand) { + curExpand = (cavityWidth - childWidth)/numExpand; + if (curExpand < minExpand) { + minExpand = curExpand; + } } } else { cavityWidth -= childWidth; @@ -899,9 +921,11 @@ XExpansion( } } } - curExpand = cavityWidth/numExpand; - if (curExpand < minExpand) { - minExpand = curExpand; + if (numExpand) { + curExpand = cavityWidth/numExpand; + if (curExpand < minExpand) { + minExpand = curExpand; + } } return (minExpand < 0) ? 0 : minExpand; } @@ -943,9 +967,11 @@ YExpansion( childHeight = Tk_ReqHeight(slavePtr->tkwin) + slavePtr->doubleBw + slavePtr->padY + slavePtr->iPadY; if ((slavePtr->side == LEFT) || (slavePtr->side == RIGHT)) { - curExpand = (cavityHeight - childHeight)/numExpand; - if (curExpand < minExpand) { - minExpand = curExpand; + if (numExpand) { + curExpand = (cavityHeight - childHeight)/numExpand; + if (curExpand < minExpand) { + minExpand = curExpand; + } } } else { cavityHeight -= childHeight; @@ -954,15 +980,17 @@ YExpansion( } } } - curExpand = cavityHeight/numExpand; - if (curExpand < minExpand) { - minExpand = curExpand; + if (numExpand) { + curExpand = cavityHeight/numExpand; + if (curExpand < minExpand) { + minExpand = curExpand; + } } return (minExpand < 0) ? 0 : minExpand; } /* - *-------------------------------------------------------------- + *------------------------------------------------------------------------ * * GetPacker -- * @@ -977,7 +1005,7 @@ YExpansion( * A new packer structure may be created. If so, then a callback is set * up to clean things up when the window is deleted. * - *-------------------------------------------------------------- + *------------------------------------------------------------------------ */ static Packer * @@ -1003,9 +1031,9 @@ GetPacker( hPtr = Tcl_CreateHashEntry(&dispPtr->packerHashTable, (char *) tkwin, &isNew); if (!isNew) { - return (Packer *) Tcl_GetHashValue(hPtr); + return Tcl_GetHashValue(hPtr); } - packPtr = (Packer *) ckalloc(sizeof(Packer)); + packPtr = ckalloc(sizeof(Packer)); packPtr->tkwin = tkwin; packPtr->masterPtr = NULL; packPtr->nextPtr = NULL; @@ -1020,12 +1048,12 @@ GetPacker( packPtr->flags = 0; Tcl_SetHashValue(hPtr, packPtr); Tk_CreateEventHandler(tkwin, StructureNotifyMask, - PackStructureProc, (ClientData) packPtr); + PackStructureProc, packPtr); return packPtr; } /* - *-------------------------------------------------------------- + *------------------------------------------------------------------------ * * PackAfter -- * @@ -1039,7 +1067,7 @@ GetPacker( * The geometry of the specified windows may change, both now and again * in the future. * - *-------------------------------------------------------------- + *------------------------------------------------------------------------ */ static int @@ -1050,7 +1078,7 @@ PackAfter( * masterPtr. */ Packer *masterPtr, /* Master in which to pack windows. */ int objc, /* Number of elements in objv. */ - Tcl_Obj *CONST objv[]) /* Array of lists, each containing 2 elements: + Tcl_Obj *const objv[]) /* Array of lists, each containing 2 elements: * window name and side against which to * pack. */ { @@ -1122,7 +1150,7 @@ PackAfter( packPtr->flags |= OLD_STYLE; for (index = 0 ; index < optionCount; index++) { Tcl_Obj *curOptPtr = options[index]; - char *curOpt = Tcl_GetStringFromObj(curOptPtr, &length); + const char *curOpt = Tcl_GetStringFromObj(curOptPtr, &length); c = curOpt[0]; @@ -1225,7 +1253,17 @@ PackAfter( packPtr->nextPtr = prevPtr->nextPtr; prevPtr->nextPtr = packPtr; } - Tk_ManageGeometry(tkwin, &packerType, (ClientData) packPtr); + Tk_ManageGeometry(tkwin, &packerType, packPtr); + + if (!(masterPtr->flags & DONT_PROPAGATE)) { + if (TkSetGeometryMaster(interp, masterPtr->tkwin, "pack") + != TCL_OK) { + Tk_ManageGeometry(tkwin, NULL, NULL); + Unlink(packPtr); + return TCL_ERROR; + } + masterPtr->flags |= ALLOCED_MASTER; + } } } @@ -1238,7 +1276,7 @@ PackAfter( } if (!(masterPtr->flags & REQUESTED_REPACK)) { masterPtr->flags |= REQUESTED_REPACK; - Tcl_DoWhenIdle(ArrangePacking, (ClientData) masterPtr); + Tcl_DoWhenIdle(ArrangePacking, masterPtr); } return TCL_OK; } @@ -1284,13 +1322,24 @@ Unlink( } if (!(masterPtr->flags & REQUESTED_REPACK)) { masterPtr->flags |= REQUESTED_REPACK; - Tcl_DoWhenIdle(ArrangePacking, (ClientData) masterPtr); + Tcl_DoWhenIdle(ArrangePacking, masterPtr); } if (masterPtr->abortPtr != NULL) { *masterPtr->abortPtr = 1; } packPtr->masterPtr = NULL; + + /* + * If we have emptied this master from slaves it means we are no longer + * handling it and should mark it as free. + */ + + if (masterPtr->slavePtr == NULL && masterPtr->flags & ALLOCED_MASTER) { + TkFreeGeometryMaster(masterPtr->tkwin, "pack"); + masterPtr->flags &= ~ALLOCED_MASTER; + } + } /* @@ -1317,7 +1366,8 @@ DestroyPacker( * dead. */ { register Packer *packPtr = (Packer *) memPtr; - ckfree((char *) packPtr); + + ckfree(packPtr); } /* @@ -1344,20 +1394,20 @@ PackStructureProc( * eventPtr. */ XEvent *eventPtr) /* Describes what just happened. */ { - register Packer *packPtr = (Packer *) clientData; + register Packer *packPtr = clientData; if (eventPtr->type == ConfigureNotify) { if ((packPtr->slavePtr != NULL) && !(packPtr->flags & REQUESTED_REPACK)) { packPtr->flags |= REQUESTED_REPACK; - Tcl_DoWhenIdle(ArrangePacking, (ClientData) packPtr); + Tcl_DoWhenIdle(ArrangePacking, packPtr); } if ((packPtr->masterPtr != NULL) && (packPtr->doubleBw != 2*Tk_Changes(packPtr->tkwin)->border_width)) { if (!(packPtr->masterPtr->flags & REQUESTED_REPACK)) { packPtr->doubleBw = 2*Tk_Changes(packPtr->tkwin)->border_width; packPtr->masterPtr->flags |= REQUESTED_REPACK; - Tcl_DoWhenIdle(ArrangePacking, (ClientData) packPtr->masterPtr); + Tcl_DoWhenIdle(ArrangePacking, packPtr->masterPtr); } } } else if (eventPtr->type == DestroyNotify) { @@ -1369,8 +1419,7 @@ PackStructureProc( for (slavePtr = packPtr->slavePtr; slavePtr != NULL; slavePtr = nextPtr) { - Tk_ManageGeometry(slavePtr->tkwin, NULL, - (ClientData) NULL); + Tk_ManageGeometry(slavePtr->tkwin, NULL, NULL); Tk_UnmapWindow(slavePtr->tkwin); slavePtr->masterPtr = NULL; nextPtr = slavePtr->nextPtr; @@ -1384,10 +1433,10 @@ PackStructureProc( } if (packPtr->flags & REQUESTED_REPACK) { - Tcl_CancelIdleCall(ArrangePacking, (ClientData) packPtr); + Tcl_CancelIdleCall(ArrangePacking, packPtr); } packPtr->tkwin = NULL; - Tcl_EventuallyFree((ClientData) packPtr, DestroyPacker); + Tcl_EventuallyFree(packPtr, DestroyPacker); } else if (eventPtr->type == MapNotify) { /* * When a master gets mapped, must redo the geometry computation so @@ -1397,7 +1446,7 @@ PackStructureProc( if ((packPtr->slavePtr != NULL) && !(packPtr->flags & REQUESTED_REPACK)) { packPtr->flags |= REQUESTED_REPACK; - Tcl_DoWhenIdle(ArrangePacking, (ClientData) packPtr); + Tcl_DoWhenIdle(ArrangePacking, packPtr); } } else if (eventPtr->type == UnmapNotify) { register Packer *packPtr2; @@ -1439,7 +1488,7 @@ ConfigureSlaves( Tk_Window tkwin, /* Any window in application containing * slaves. Used to look up slave names. */ int objc, /* Number of elements in argv. */ - Tcl_Obj *CONST objv[]) /* Argument objects: contains one or more + Tcl_Obj *const objv[]) /* Argument objects: contains one or more * window names followed by any number of * "option value" pairs. Caller must make sure * that there is at least one window name. */ @@ -1447,8 +1496,8 @@ ConfigureSlaves( Packer *masterPtr, *slavePtr, *prevPtr, *otherPtr; Tk_Window other, slave, parent, ancestor; int i, j, numWindows, tmp, positionGiven; - char *string; - static CONST char *optionStrings[] = { + const char *string; + static const char *const optionStrings[] = { "-after", "-anchor", "-before", "-expand", "-fill", "-in", "-ipadx", "-ipady", "-padx", "-pady", "-side", NULL }; enum options { @@ -1530,8 +1579,8 @@ ConfigureSlaves( if (prevPtr->masterPtr == NULL) { notPacked: Tcl_AppendResult(interp, "window \"", - Tcl_GetString(objv[i+1]), - "\" isn't packed", NULL); + Tcl_GetString(objv[i+1]), "\" isn't packed", + NULL); return TCL_ERROR; } masterPtr = prevPtr->masterPtr; @@ -1728,6 +1777,7 @@ ConfigureSlaves( } Unlink(slavePtr); } + slavePtr->masterPtr = masterPtr; if (prevPtr == NULL) { slavePtr->nextPtr = masterPtr->slavePtr; @@ -1736,9 +1786,19 @@ ConfigureSlaves( slavePtr->nextPtr = prevPtr->nextPtr; prevPtr->nextPtr = slavePtr; } - Tk_ManageGeometry(slave, &packerType, (ClientData) slavePtr); + Tk_ManageGeometry(slave, &packerType, slavePtr); prevPtr = slavePtr; + if (!(masterPtr->flags & DONT_PROPAGATE)) { + if (TkSetGeometryMaster(interp, masterPtr->tkwin, "pack") + != TCL_OK) { + Tk_ManageGeometry(slave, NULL, NULL); + Unlink(slavePtr); + return TCL_ERROR; + } + masterPtr->flags |= ALLOCED_MASTER; + } + /* * Arrange for the master to be re-packed at the first idle moment. */ @@ -1749,7 +1809,7 @@ ConfigureSlaves( } if (!(masterPtr->flags & REQUESTED_REPACK)) { masterPtr->flags |= REQUESTED_REPACK; - Tcl_DoWhenIdle(ArrangePacking, (ClientData) masterPtr); + Tcl_DoWhenIdle(ArrangePacking, masterPtr); } } return TCL_OK; |