OSDN Git Service

Please enter the commit message for your changes. Lines starting
[eos/base.git] / util / src / TclTk / tk8.6.4 / generic / tkPlace.c
diff --git a/util/src/TclTk/tk8.6.4/generic/tkPlace.c b/util/src/TclTk/tk8.6.4/generic/tkPlace.c
deleted file mode 100644 (file)
index 9fa406a..0000000
+++ /dev/null
@@ -1,1245 +0,0 @@
-/*
- * tkPlace.c --
- *
- *     This file contains code to implement a simple geometry manager for Tk
- *     based on absolute placement or "rubber-sheet" placement.
- *
- * Copyright (c) 1992-1994 The Regents of the University of California.
- * Copyright (c) 1994-1997 Sun Microsystems, Inc.
- *
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
- */
-
-#include "tkInt.h"
-
-/*
- * Border modes for relative placement:
- *
- * BM_INSIDE:          relative distances computed using area inside all
- *                     borders of master window.
- * BM_OUTSIDE:         relative distances computed using outside area that
- *                     includes all borders of master.
- * BM_IGNORE:          border issues are ignored: place relative to master's
- *                     actual window size.
- */
-
-static const char *const borderModeStrings[] = {
-    "inside", "outside", "ignore", NULL
-};
-
-typedef enum {BM_INSIDE, BM_OUTSIDE, BM_IGNORE} BorderMode;
-
-/*
- * For each window whose geometry is managed by the placer there is a
- * structure of the following type:
- */
-
-typedef struct Slave {
-    Tk_Window tkwin;           /* Tk's token for window. */
-    Tk_Window inTkwin;         /* Token for the -in window. */
-    struct Master *masterPtr;  /* Pointer to information for window relative
-                                * to which tkwin is placed. This isn't
-                                * necessarily the logical parent of tkwin.
-                                * NULL means the master was deleted or never
-                                * assigned. */
-    struct Slave *nextPtr;     /* Next in list of windows placed relative to
-                                * same master (NULL for end of list). */
-    Tk_OptionTable optionTable;        /* Table that defines configuration options
-                                * available for this command. */
-    /*
-     * Geometry information for window; where there are both relative and
-     * absolute values for the same attribute (e.g. x and relX) only one of
-     * them is actually used, depending on flags.
-     */
-
-    int x, y;                  /* X and Y pixel coordinates for tkwin. */
-    Tcl_Obj *xPtr, *yPtr;      /* Tcl_Obj rep's of x, y coords, to keep pixel
-                                * spec. information. */
-    double relX, relY;         /* X and Y coordinates relative to size of
-                                * master. */
-    int width, height;         /* Absolute dimensions for tkwin. */
-    Tcl_Obj *widthPtr;         /* Tcl_Obj rep of width, to keep pixel
-                                * spec. */
-    Tcl_Obj *heightPtr;                /* Tcl_Obj rep of height, to keep pixel
-                                * spec. */
-    double relWidth, relHeight;        /* Dimensions for tkwin relative to size of
-                                * master. */
-    Tcl_Obj *relWidthPtr;
-    Tcl_Obj *relHeightPtr;
-    Tk_Anchor anchor;          /* Which point on tkwin is placed at the given
-                                * position. */
-    BorderMode borderMode;     /* How to treat borders of master window. */
-    int flags;                 /* Various flags; see below for bit
-                                * definitions. */
-} Slave;
-
-/*
- * Type masks for options:
- */
-
-#define IN_MASK                1
-
-static const Tk_OptionSpec optionSpecs[] = {
-    {TK_OPTION_ANCHOR, "-anchor", NULL, NULL, "nw", -1,
-        Tk_Offset(Slave, anchor), 0, 0, 0},
-    {TK_OPTION_STRING_TABLE, "-bordermode", NULL, NULL, "inside", -1,
-        Tk_Offset(Slave, borderMode), 0, borderModeStrings, 0},
-    {TK_OPTION_PIXELS, "-height", NULL, NULL, "", Tk_Offset(Slave, heightPtr),
-        Tk_Offset(Slave, height), TK_OPTION_NULL_OK, 0, 0},
-    {TK_OPTION_WINDOW, "-in", NULL, NULL, "", -1, Tk_Offset(Slave, inTkwin),
-        0, 0, IN_MASK},
-    {TK_OPTION_DOUBLE, "-relheight", NULL, NULL, "",
-        Tk_Offset(Slave, relHeightPtr), Tk_Offset(Slave, relHeight),
-        TK_OPTION_NULL_OK, 0, 0},
-    {TK_OPTION_DOUBLE, "-relwidth", NULL, NULL, "",
-        Tk_Offset(Slave, relWidthPtr), Tk_Offset(Slave, relWidth),
-        TK_OPTION_NULL_OK, 0, 0},
-    {TK_OPTION_DOUBLE, "-relx", NULL, NULL, "0", -1,
-        Tk_Offset(Slave, relX), 0, 0, 0},
-    {TK_OPTION_DOUBLE, "-rely", NULL, NULL, "0", -1,
-        Tk_Offset(Slave, relY), 0, 0, 0},
-    {TK_OPTION_PIXELS, "-width", NULL, NULL, "", Tk_Offset(Slave, widthPtr),
-        Tk_Offset(Slave, width), TK_OPTION_NULL_OK, 0, 0},
-    {TK_OPTION_PIXELS, "-x", NULL, NULL, "0", Tk_Offset(Slave, xPtr),
-        Tk_Offset(Slave, x), TK_OPTION_NULL_OK, 0, 0},
-    {TK_OPTION_PIXELS, "-y", NULL, NULL, "0", Tk_Offset(Slave, yPtr),
-        Tk_Offset(Slave, y), TK_OPTION_NULL_OK, 0, 0},
-    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
-};
-
-/*
- * Flag definitions for Slave structures:
- *
- * CHILD_WIDTH -               1 means -width was specified;
- * CHILD_REL_WIDTH -           1 means -relwidth was specified.
- * CHILD_HEIGHT -              1 means -height was specified;
- * CHILD_REL_HEIGHT -          1 means -relheight was specified.
- */
-
-#define CHILD_WIDTH            1
-#define CHILD_REL_WIDTH                2
-#define CHILD_HEIGHT           4
-#define CHILD_REL_HEIGHT       8
-
-/*
- * For each master window that has a slave managed by the placer there is a
- * structure of the following form:
- */
-
-typedef struct Master {
-    Tk_Window tkwin;           /* Tk's token for master window. */
-    struct Slave *slavePtr;    /* First in linked list of slaves placed
-                                * relative to this master. */
-    int *abortPtr;             /* If non-NULL, it means that there is a nested
-                                * call to RecomputePlacement already working on
-                                * this window.  *abortPtr may be set to 1 to
-                                * abort that nested call.  This happens, for
-                                * example, if tkwin or any of its slaves
-                                * is deleted. */
-    int flags;                 /* See below for bit definitions. */
-} Master;
-
-/*
- * Flag definitions for masters:
- *
- * PARENT_RECONFIG_PENDING -   1 means that a call to RecomputePlacement is
- *                             already pending via a Do_When_Idle handler.
- */
-
-#define PARENT_RECONFIG_PENDING        1
-
-/*
- * The following structure is the official type record for the placer:
- */
-
-static void            PlaceRequestProc(ClientData clientData,
-                           Tk_Window tkwin);
-static void            PlaceLostSlaveProc(ClientData clientData,
-                           Tk_Window tkwin);
-
-static const Tk_GeomMgr placerType = {
-    "place",                   /* name */
-    PlaceRequestProc,          /* requestProc */
-    PlaceLostSlaveProc,                /* lostSlaveProc */
-};
-
-/*
- * Forward declarations for functions defined later in this file:
- */
-
-static void            SlaveStructureProc(ClientData clientData,
-                           XEvent *eventPtr);
-static int             ConfigureSlave(Tcl_Interp *interp, Tk_Window tkwin,
-                           Tk_OptionTable table, int objc,
-                           Tcl_Obj *const objv[]);
-static int             PlaceInfoCommand(Tcl_Interp *interp, Tk_Window tkwin);
-static Slave *         CreateSlave(Tk_Window tkwin, Tk_OptionTable table);
-static void            FreeSlave(Slave *slavePtr);
-static Slave *         FindSlave(Tk_Window tkwin);
-static Master *                CreateMaster(Tk_Window tkwin);
-static Master *                FindMaster(Tk_Window tkwin);
-static void            MasterStructureProc(ClientData clientData,
-                           XEvent *eventPtr);
-static void            RecomputePlacement(ClientData clientData);
-static void            UnlinkSlave(Slave *slavePtr);
-\f
-/*
- *--------------------------------------------------------------
- *
- * Tk_PlaceObjCmd --
- *
- *     This function is invoked to process the "place" Tcl commands. See the
- *     user documentation for details on what it does.
- *
- * Results:
- *     A standard Tcl result.
- *
- * Side effects:
- *     See the user documentation.
- *
- *--------------------------------------------------------------
- */
-
-int
-Tk_PlaceObjCmd(
-    ClientData clientData,     /* Interpreter main window. */
-    Tcl_Interp *interp,                /* Current interpreter. */
-    int objc,                  /* Number of arguments. */
-    Tcl_Obj *const objv[])     /* Argument objects. */
-{
-    Tk_Window main_win = clientData;
-    Tk_Window tkwin;
-    Slave *slavePtr;
-    TkDisplay *dispPtr;
-    Tk_OptionTable optionTable;
-    static const char *const optionStrings[] = {
-       "configure", "forget", "info", "slaves", NULL
-    };
-    enum options { PLACE_CONFIGURE, PLACE_FORGET, PLACE_INFO, PLACE_SLAVES };
-    int index;
-
-    if (objc < 3) {
-       Tcl_WrongNumArgs(interp, 1, objv, "option|pathName args");
-       return TCL_ERROR;
-    }
-
-    /*
-     * Create the option table for this widget class. If it has already been
-     * created, the cached pointer will be returned.
-     */
-
-     optionTable = Tk_CreateOptionTable(interp, optionSpecs);
-
-    /*
-     * Handle special shortcut where window name is first argument.
-     */
-
-    if (Tcl_GetString(objv[1])[0] == '.') {
-       if (TkGetWindowFromObj(interp, main_win, objv[1],
-               &tkwin) != TCL_OK) {
-           return TCL_ERROR;
-       }
-
-       /*
-        * Initialize, if that hasn't been done yet.
-        */
-
-       dispPtr = ((TkWindow *) tkwin)->dispPtr;
-       if (!dispPtr->placeInit) {
-           Tcl_InitHashTable(&dispPtr->masterTable, TCL_ONE_WORD_KEYS);
-           Tcl_InitHashTable(&dispPtr->slaveTable, TCL_ONE_WORD_KEYS);
-           dispPtr->placeInit = 1;
-       }
-
-       return ConfigureSlave(interp, tkwin, optionTable, objc-2, objv+2);
-    }
-
-    /*
-     * Handle more general case of option followed by window name followed by
-     * possible additional arguments.
-     */
-
-    if (TkGetWindowFromObj(interp, main_win, objv[2],
-           &tkwin) != TCL_OK) {
-       return TCL_ERROR;
-    }
-
-    /*
-     * Initialize, if that hasn't been done yet.
-     */
-
-    dispPtr = ((TkWindow *) tkwin)->dispPtr;
-    if (!dispPtr->placeInit) {
-       Tcl_InitHashTable(&dispPtr->masterTable, TCL_ONE_WORD_KEYS);
-       Tcl_InitHashTable(&dispPtr->slaveTable, TCL_ONE_WORD_KEYS);
-       dispPtr->placeInit = 1;
-    }
-
-    if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
-           sizeof(char *), "option", 0, &index) != TCL_OK) {
-       return TCL_ERROR;
-    }
-
-    switch ((enum options) index) {
-    case PLACE_CONFIGURE:
-       if (objc == 3 || objc == 4) {
-           Tcl_Obj *objPtr;
-
-           slavePtr = FindSlave(tkwin);
-           if (slavePtr == NULL) {
-               return TCL_OK;
-           }
-           objPtr = Tk_GetOptionInfo(interp, (char *) slavePtr, optionTable,
-                   (objc == 4) ? objv[3] : NULL, tkwin);
-           if (objPtr == NULL) {
-               return TCL_ERROR;
-           }
-           Tcl_SetObjResult(interp, objPtr);
-           return TCL_OK;
-       }
-       return ConfigureSlave(interp, tkwin, optionTable, objc-3, objv+3);
-
-    case PLACE_FORGET:
-       if (objc != 3) {
-           Tcl_WrongNumArgs(interp, 2, objv, "pathName");
-           return TCL_ERROR;
-       }
-       slavePtr = FindSlave(tkwin);
-       if (slavePtr == NULL) {
-           return TCL_OK;
-       }
-       if ((slavePtr->masterPtr != NULL) &&
-               (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin))) {
-           Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin);
-       }
-       UnlinkSlave(slavePtr);
-       Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable,
-               (char *) tkwin));
-       Tk_DeleteEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc,
-               slavePtr);
-       Tk_ManageGeometry(tkwin, NULL, NULL);
-       Tk_UnmapWindow(tkwin);
-       FreeSlave(slavePtr);
-       break;
-
-    case PLACE_INFO:
-       if (objc != 3) {
-           Tcl_WrongNumArgs(interp, 2, objv, "pathName");
-           return TCL_ERROR;
-       }
-       return PlaceInfoCommand(interp, tkwin);
-
-    case PLACE_SLAVES: {
-       Master *masterPtr;
-
-       if (objc != 3) {
-           Tcl_WrongNumArgs(interp, 2, objv, "pathName");
-           return TCL_ERROR;
-       }
-       masterPtr = FindMaster(tkwin);
-       if (masterPtr != NULL) {
-           Tcl_Obj *listPtr = Tcl_NewObj();
-
-           for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
-                   slavePtr = slavePtr->nextPtr) {
-               Tcl_ListObjAppendElement(NULL, listPtr,
-                       TkNewWindowObj(slavePtr->tkwin));
-           }
-           Tcl_SetObjResult(interp, listPtr);
-       }
-       break;
-    }
-    }
-
-    return TCL_OK;
-}
-\f
-/*
- *----------------------------------------------------------------------
- *
- * CreateSlave --
- *
- *     Given a Tk_Window token, find the Slave structure corresponding to
- *     that token, creating a new one if necessary.
- *
- * Results:
- *     Pointer to the Slave structure.
- *
- * Side effects:
- *     A new Slave structure may be created.
- *
- *----------------------------------------------------------------------
- */
-
-static Slave *
-CreateSlave(
-    Tk_Window tkwin,           /* Token for desired slave. */
-    Tk_OptionTable table)
-{
-    Tcl_HashEntry *hPtr;
-    register Slave *slavePtr;
-    int isNew;
-    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
-
-    hPtr = Tcl_CreateHashEntry(&dispPtr->slaveTable, (char *) tkwin, &isNew);
-    if (!isNew) {
-       return Tcl_GetHashValue(hPtr);
-    }
-
-    /*
-     * No preexisting slave structure for that window, so make a new one and
-     * populate it with some default values.
-     */
-
-    slavePtr = ckalloc(sizeof(Slave));
-    memset(slavePtr, 0, sizeof(Slave));
-    slavePtr->tkwin = tkwin;
-    slavePtr->inTkwin = None;
-    slavePtr->anchor = TK_ANCHOR_NW;
-    slavePtr->borderMode = BM_INSIDE;
-    slavePtr->optionTable = table;
-    Tcl_SetHashValue(hPtr, slavePtr);
-    Tk_CreateEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc,
-           slavePtr);
-    return slavePtr;
-}
-\f
-/*
- *----------------------------------------------------------------------
- *
- * FreeSlave --
- *
- *     Frees the resources held by a Slave structure.
- *
- * Results:
- *     None
- *
- * Side effects:
- *     Memory are freed.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-FreeSlave(
-    Slave *slavePtr)
-{
-    Tk_FreeConfigOptions((char *) slavePtr, slavePtr->optionTable,
-           slavePtr->tkwin);
-    ckfree(slavePtr);
-}
-\f
-/*
- *----------------------------------------------------------------------
- *
- * FindSlave --
- *
- *     Given a Tk_Window token, find the Slave structure corresponding to
- *     that token. This is purely a lookup function; it will not create a
- *     record if one does not yet exist.
- *
- * Results:
- *     Pointer to Slave structure; NULL if none exists.
- *
- * Side effects:
- *     None.
- *
- *----------------------------------------------------------------------
- */
-
-static Slave *
-FindSlave(
-    Tk_Window tkwin)           /* Token for desired slave. */
-{
-    register Tcl_HashEntry *hPtr;
-    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
-
-    hPtr = Tcl_FindHashEntry(&dispPtr->slaveTable, (char *) tkwin);
-    if (hPtr == NULL) {
-       return NULL;
-    }
-    return Tcl_GetHashValue(hPtr);
-}
-\f
-/*
- *----------------------------------------------------------------------
- *
- * UnlinkSlave --
- *
- *     This function removes a slave window from the chain of slaves in its
- *     master.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     The slave list of slavePtr's master changes.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-UnlinkSlave(
-    Slave *slavePtr)           /* Slave structure to be unlinked. */
-{
-    register Master *masterPtr;
-    register Slave *prevPtr;
-
-    masterPtr = slavePtr->masterPtr;
-    if (masterPtr == NULL) {
-       return;
-    }
-    if (masterPtr->slavePtr == slavePtr) {
-       masterPtr->slavePtr = slavePtr->nextPtr;
-    } else {
-       for (prevPtr = masterPtr->slavePtr; ; prevPtr = prevPtr->nextPtr) {
-           if (prevPtr == NULL) {
-               Tcl_Panic("UnlinkSlave couldn't find slave to unlink");
-           }
-           if (prevPtr->nextPtr == slavePtr) {
-               prevPtr->nextPtr = slavePtr->nextPtr;
-               break;
-           }
-       }
-    }
-
-    if (masterPtr->abortPtr != NULL) {
-       *masterPtr->abortPtr = 1;
-    }
-    slavePtr->masterPtr = NULL;
-}
-\f
-/*
- *----------------------------------------------------------------------
- *
- * CreateMaster --
- *
- *     Given a Tk_Window token, find the Master structure corresponding to
- *     that token, creating a new one if necessary.
- *
- * Results:
- *     Pointer to the Master structure.
- *
- * Side effects:
- *     A new Master structure may be created.
- *
- *----------------------------------------------------------------------
- */
-
-static Master *
-CreateMaster(
-    Tk_Window tkwin)           /* Token for desired master. */
-{
-    Tcl_HashEntry *hPtr;
-    register Master *masterPtr;
-    int isNew;
-    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
-
-    hPtr = Tcl_CreateHashEntry(&dispPtr->masterTable, (char *) tkwin, &isNew);
-    if (isNew) {
-       masterPtr = ckalloc(sizeof(Master));
-       masterPtr->tkwin = tkwin;
-       masterPtr->slavePtr = NULL;
-       masterPtr->abortPtr = NULL;
-       masterPtr->flags = 0;
-       Tcl_SetHashValue(hPtr, masterPtr);
-       Tk_CreateEventHandler(masterPtr->tkwin, StructureNotifyMask,
-               MasterStructureProc, masterPtr);
-    } else {
-       masterPtr = Tcl_GetHashValue(hPtr);
-    }
-    return masterPtr;
-}
-\f
-/*
- *----------------------------------------------------------------------
- *
- * FindMaster --
- *
- *     Given a Tk_Window token, find the Master structure corresponding to
- *     that token. This is simply a lookup function; a new record will not be
- *     created if one does not already exist.
- *
- * Results:
- *     Pointer to the Master structure; NULL if one does not exist for the
- *     given Tk_Window token.
- *
- * Side effects:
- *     None.
- *
- *----------------------------------------------------------------------
- */
-
-static Master *
-FindMaster(
-    Tk_Window tkwin)           /* Token for desired master. */
-{
-    register Tcl_HashEntry *hPtr;
-    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
-
-    hPtr = Tcl_FindHashEntry(&dispPtr->masterTable, (char *) tkwin);
-    if (hPtr == NULL) {
-       return NULL;
-    }
-    return Tcl_GetHashValue(hPtr);
-}
-\f
-/*
- *----------------------------------------------------------------------
- *
- * ConfigureSlave --
- *
- *     This function is called to process an argv/argc list to reconfigure
- *     the placement of a window.
- *
- * Results:
- *     A standard Tcl result. If an error occurs then a message is left in
- *     the interp's result.
- *
- * Side effects:
- *     Information in slavePtr may change, and slavePtr's master is scheduled
- *     for reconfiguration.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-ConfigureSlave(
-    Tcl_Interp *interp,                /* Used for error reporting. */
-    Tk_Window tkwin,           /* Token for the window to manipulate. */
-    Tk_OptionTable table,      /* Token for option table. */
-    int objc,                  /* Number of config arguments. */
-    Tcl_Obj *const objv[])     /* Object values for arguments. */
-{
-    register Master *masterPtr;
-    Tk_SavedOptions savedOptions;
-    int mask;
-    Slave *slavePtr;
-    Tk_Window masterWin = (Tk_Window) NULL;
-
-    if (Tk_TopWinHierarchy(tkwin)) {
-       Tcl_SetObjResult(interp, Tcl_ObjPrintf(
-               "can't use placer on top-level window \"%s\"; use "
-               "wm command instead", Tk_PathName(tkwin)));
-       Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "TOPLEVEL", NULL);
-       return TCL_ERROR;
-    }
-
-    slavePtr = CreateSlave(tkwin, table);
-
-    if (Tk_SetOptions(interp, (char *) slavePtr, table, objc, objv,
-           slavePtr->tkwin, &savedOptions, &mask) != TCL_OK) {
-       goto error;
-    }
-
-    /*
-     * Set slave flags. First clear the field, then add bits as needed.
-     */
-
-    slavePtr->flags = 0;
-    if (slavePtr->heightPtr) {
-       slavePtr->flags |= CHILD_HEIGHT;
-    }
-
-    if (slavePtr->relHeightPtr) {
-       slavePtr->flags |= CHILD_REL_HEIGHT;
-    }
-
-    if (slavePtr->relWidthPtr) {
-       slavePtr->flags |= CHILD_REL_WIDTH;
-    }
-
-    if (slavePtr->widthPtr) {
-       slavePtr->flags |= CHILD_WIDTH;
-    }
-
-    if (!(mask & IN_MASK) && (slavePtr->masterPtr != NULL)) {
-       /*
-        * If no -in option was passed and the slave is already placed then
-        * just recompute the placement.
-        */
-
-       masterPtr = slavePtr->masterPtr;
-       goto scheduleLayout;
-    } else if (mask & IN_MASK) {
-       /* -in changed */
-       Tk_Window tkwin;
-       Tk_Window ancestor;
-
-       tkwin = slavePtr->inTkwin;
-
-       /*
-        * Make sure that the new master is either the logical parent of the
-        * slave or a descendant of that window, and that the master and slave
-        * aren't the same.
-        */
-
-       for (ancestor = tkwin; ; ancestor = Tk_Parent(ancestor)) {
-           if (ancestor == Tk_Parent(slavePtr->tkwin)) {
-               break;
-           }
-           if (Tk_TopWinHierarchy(ancestor)) {
-               Tcl_SetObjResult(interp, Tcl_ObjPrintf(
-                       "can't place %s relative to %s",
-                       Tk_PathName(slavePtr->tkwin), Tk_PathName(tkwin)));
-               Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL);
-               goto error;
-           }
-       }
-       if (slavePtr->tkwin == tkwin) {
-           Tcl_SetObjResult(interp, Tcl_ObjPrintf(
-                   "can't place %s relative to itself",
-                   Tk_PathName(slavePtr->tkwin)));
-           Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "LOOP", NULL);
-           goto error;
-       }
-       if ((slavePtr->masterPtr != NULL)
-               && (slavePtr->masterPtr->tkwin == tkwin)) {
-           /*
-            * Re-using same old master. Nothing to do.
-            */
-
-           masterPtr = slavePtr->masterPtr;
-           goto scheduleLayout;
-       }
-       if ((slavePtr->masterPtr != NULL) &&
-               (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin))) {
-           Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin);
-       }
-       UnlinkSlave(slavePtr);
-       masterWin = tkwin;
-    }
-
-    /*
-     * If there's no master specified for this slave, use its Tk_Parent.
-     */
-
-    if (masterWin == NULL) {
-       masterWin = Tk_Parent(slavePtr->tkwin);
-       slavePtr->inTkwin = masterWin;
-    }
-
-    /*
-     * Manage the slave window in this master.
-     */
-
-    masterPtr = CreateMaster(masterWin);
-    slavePtr->masterPtr = masterPtr;
-    slavePtr->nextPtr = masterPtr->slavePtr;
-    masterPtr->slavePtr = slavePtr;
-    Tk_ManageGeometry(slavePtr->tkwin, &placerType, slavePtr);
-
-    /*
-     * Arrange for the master to be re-arranged at the first idle moment.
-     */
-
-  scheduleLayout:
-    Tk_FreeSavedOptions(&savedOptions);
-
-    if (!(masterPtr->flags & PARENT_RECONFIG_PENDING)) {
-       masterPtr->flags |= PARENT_RECONFIG_PENDING;
-       Tcl_DoWhenIdle(RecomputePlacement, masterPtr);
-    }
-    return TCL_OK;
-
-    /*
-     * Error while processing some option, cleanup and return.
-     */
-
-  error:
-    Tk_RestoreSavedOptions(&savedOptions);
-    return TCL_ERROR;
-}
-\f
-/*
- *----------------------------------------------------------------------
- *
- * PlaceInfoCommand --
- *
- *     Implementation of the [place info] subcommand. See the user
- *     documentation for information on what it does.
- *
- * Results:
- *     Standard Tcl result.
- *
- * Side effects:
- *     If the given tkwin is managed by the placer, this function will put
- *     information about that placement in the interp's result.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-PlaceInfoCommand(
-    Tcl_Interp *interp,                /* Interp into which to place result. */
-    Tk_Window tkwin)           /* Token for the window to get info on. */
-{
-    Slave *slavePtr;
-    Tcl_Obj *infoObj;
-
-    slavePtr = FindSlave(tkwin);
-    if (slavePtr == NULL) {
-       return TCL_OK;
-    }
-    infoObj = Tcl_NewObj();
-    if (slavePtr->masterPtr != NULL) {
-       Tcl_AppendToObj(infoObj, "-in", -1);
-       Tcl_ListObjAppendElement(NULL, infoObj,
-               TkNewWindowObj(slavePtr->masterPtr->tkwin));
-       Tcl_AppendToObj(infoObj, " ", -1);
-    }
-    Tcl_AppendPrintfToObj(infoObj,
-           "-x %d -relx %.4g -y %d -rely %.4g",
-           slavePtr->x, slavePtr->relX, slavePtr->y, slavePtr->relY);
-    if (slavePtr->flags & CHILD_WIDTH) {
-       Tcl_AppendPrintfToObj(infoObj, " -width %d", slavePtr->width);
-    } else {
-       Tcl_AppendToObj(infoObj, " -width {}", -1);
-    }
-    if (slavePtr->flags & CHILD_REL_WIDTH) {
-       Tcl_AppendPrintfToObj(infoObj,
-               " -relwidth %.4g", slavePtr->relWidth);
-    } else {
-       Tcl_AppendToObj(infoObj, " -relwidth {}", -1);
-    }
-    if (slavePtr->flags & CHILD_HEIGHT) {
-       Tcl_AppendPrintfToObj(infoObj, " -height %d", slavePtr->height);
-    } else {
-       Tcl_AppendToObj(infoObj, " -height {}", -1);
-    }
-    if (slavePtr->flags & CHILD_REL_HEIGHT) {
-       Tcl_AppendPrintfToObj(infoObj,
-               " -relheight %.4g", slavePtr->relHeight);
-    } else {
-       Tcl_AppendToObj(infoObj, " -relheight {}", -1);
-    }
-
-    Tcl_AppendPrintfToObj(infoObj, " -anchor %s -bordermode %s",
-           Tk_NameOfAnchor(slavePtr->anchor),
-           borderModeStrings[slavePtr->borderMode]);
-    Tcl_SetObjResult(interp, infoObj);
-    return TCL_OK;
-}
-\f
-/*
- *----------------------------------------------------------------------
- *
- * RecomputePlacement --
- *
- *     This function is called as a when-idle handler. It recomputes the
- *     geometries of all the slaves of a given master.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     Windows may change size or shape.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-RecomputePlacement(
-    ClientData clientData)     /* Pointer to Master record. */
-{
-    register Master *masterPtr = clientData;
-    register Slave *slavePtr;
-    int x, y, width, height, tmp;
-    int masterWidth, masterHeight, masterX, masterY;
-    double x1, y1, x2, y2;
-    int abort;                 /* May get set to non-zero to abort this
-                                * placement operation. */
-
-    masterPtr->flags &= ~PARENT_RECONFIG_PENDING;
-
-    /*
-     * Abort any nested call to RecomputePlacement for this window, since
-     * we'll do everything necessary here, and set up so this call can be
-     * aborted if necessary.
-     */
-
-    if (masterPtr->abortPtr != NULL) {
-       *masterPtr->abortPtr = 1;
-    }
-    masterPtr->abortPtr = &abort;
-    abort = 0;
-    Tcl_Preserve(masterPtr);
-
-    /*
-     * Iterate over all the slaves for the master. Each slave's geometry can
-     * be computed independently of the other slaves. Changes to the window's
-     * structure could cause almost anything to happen, including deleting the
-     * parent or child. If this happens, we'll be told to abort.
-     */
-
-    for (slavePtr = masterPtr->slavePtr; slavePtr != NULL && !abort;
-           slavePtr = slavePtr->nextPtr) {
-       /*
-        * Step 1: compute size and borderwidth of master, taking into account
-        * desired border mode.
-        */
-
-       masterX = masterY = 0;
-       masterWidth = Tk_Width(masterPtr->tkwin);
-       masterHeight = Tk_Height(masterPtr->tkwin);
-       if (slavePtr->borderMode == BM_INSIDE) {
-           masterX = Tk_InternalBorderLeft(masterPtr->tkwin);
-           masterY = Tk_InternalBorderTop(masterPtr->tkwin);
-           masterWidth -= masterX + Tk_InternalBorderRight(masterPtr->tkwin);
-           masterHeight -= masterY +
-                   Tk_InternalBorderBottom(masterPtr->tkwin);
-       } else if (slavePtr->borderMode == BM_OUTSIDE) {
-           masterX = masterY = -Tk_Changes(masterPtr->tkwin)->border_width;
-           masterWidth -= 2 * masterX;
-           masterHeight -= 2 * masterY;
-       }
-
-       /*
-        * Step 2: compute size of slave (outside dimensions including border)
-        * and location of anchor point within master.
-        */
-
-       x1 = slavePtr->x + masterX + (slavePtr->relX*masterWidth);
-       x = (int) (x1 + ((x1 > 0) ? 0.5 : -0.5));
-       y1 = slavePtr->y + masterY + (slavePtr->relY*masterHeight);
-       y = (int) (y1 + ((y1 > 0) ? 0.5 : -0.5));
-       if (slavePtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH)) {
-           width = 0;
-           if (slavePtr->flags & CHILD_WIDTH) {
-               width += slavePtr->width;
-           }
-           if (slavePtr->flags & CHILD_REL_WIDTH) {
-               /*
-                * The code below is a bit tricky. In order to round correctly
-                * when both relX and relWidth are specified, compute the
-                * location of the right edge and round that, then compute
-                * width. If we compute the width and round it, rounding
-                * errors in relX and relWidth accumulate.
-                */
-
-               x2 = x1 + (slavePtr->relWidth*masterWidth);
-               tmp = (int) (x2 + ((x2 > 0) ? 0.5 : -0.5));
-               width += tmp - x;
-           }
-       } else {
-           width = Tk_ReqWidth(slavePtr->tkwin)
-                   + 2*Tk_Changes(slavePtr->tkwin)->border_width;
-       }
-       if (slavePtr->flags & (CHILD_HEIGHT|CHILD_REL_HEIGHT)) {
-           height = 0;
-           if (slavePtr->flags & CHILD_HEIGHT) {
-               height += slavePtr->height;
-           }
-           if (slavePtr->flags & CHILD_REL_HEIGHT) {
-               /*
-                * See note above for rounding errors in width computation.
-                */
-
-               y2 = y1 + (slavePtr->relHeight*masterHeight);
-               tmp = (int) (y2 + ((y2 > 0) ? 0.5 : -0.5));
-               height += tmp - y;
-           }
-       } else {
-           height = Tk_ReqHeight(slavePtr->tkwin)
-                   + 2*Tk_Changes(slavePtr->tkwin)->border_width;
-       }
-
-       /*
-        * Step 3: adjust the x and y positions so that the desired anchor
-        * point on the slave appears at that position. Also adjust for the
-        * border mode and master's border.
-        */
-
-       switch (slavePtr->anchor) {
-       case TK_ANCHOR_N:
-           x -= width/2;
-           break;
-       case TK_ANCHOR_NE:
-           x -= width;
-           break;
-       case TK_ANCHOR_E:
-           x -= width;
-           y -= height/2;
-           break;
-       case TK_ANCHOR_SE:
-           x -= width;
-           y -= height;
-           break;
-       case TK_ANCHOR_S:
-           x -= width/2;
-           y -= height;
-           break;
-       case TK_ANCHOR_SW:
-           y -= height;
-           break;
-       case TK_ANCHOR_W:
-           y -= height/2;
-           break;
-       case TK_ANCHOR_NW:
-           break;
-       case TK_ANCHOR_CENTER:
-           x -= width/2;
-           y -= height/2;
-           break;
-       }
-
-       /*
-        * Step 4: adjust width and height again to reflect inside dimensions
-        * of window rather than outside. Also make sure that the width and
-        * height aren't zero.
-        */
-
-       width -= 2*Tk_Changes(slavePtr->tkwin)->border_width;
-       height -= 2*Tk_Changes(slavePtr->tkwin)->border_width;
-       if (width <= 0) {
-           width = 1;
-       }
-       if (height <= 0) {
-           height = 1;
-       }
-
-       /*
-        * Step 5: reconfigure the window and map it if needed. If the slave
-        * is a child of the master, we do this ourselves. If the slave isn't
-        * a child of the master, let Tk_MaintainGeometry do the work (it will
-        * re-adjust things as relevant windows map, unmap, and move).
-        */
-
-       if (masterPtr->tkwin == Tk_Parent(slavePtr->tkwin)) {
-           if ((x != Tk_X(slavePtr->tkwin))
-                   || (y != Tk_Y(slavePtr->tkwin))
-                   || (width != Tk_Width(slavePtr->tkwin))
-                   || (height != Tk_Height(slavePtr->tkwin))) {
-               Tk_MoveResizeWindow(slavePtr->tkwin, x, y, width, height);
-           }
-            if (abort) {
-                break;
-            }
-
-           /*
-            * Don't map the slave unless the master is mapped: the slave will
-            * get mapped later, when the master is mapped.
-            */
-
-           if (Tk_IsMapped(masterPtr->tkwin)) {
-               Tk_MapWindow(slavePtr->tkwin);
-           }
-       } else {
-           if ((width <= 0) || (height <= 0)) {
-               Tk_UnmaintainGeometry(slavePtr->tkwin, masterPtr->tkwin);
-               Tk_UnmapWindow(slavePtr->tkwin);
-           } else {
-               Tk_MaintainGeometry(slavePtr->tkwin, masterPtr->tkwin,
-                       x, y, width, height);
-           }
-       }
-    }
-
-    masterPtr->abortPtr = NULL;
-    Tcl_Release(masterPtr);
-}
-\f
-/*
- *----------------------------------------------------------------------
- *
- * MasterStructureProc --
- *
- *     This function is invoked by the Tk event handler when StructureNotify
- *     events occur for a master window.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     Structures get cleaned up if the window was deleted. If the window was
- *     resized then slave geometries get recomputed.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-MasterStructureProc(
-    ClientData clientData,     /* Pointer to Master structure for window
-                                * referred to by eventPtr. */
-    XEvent *eventPtr)          /* Describes what just happened. */
-{
-    register Master *masterPtr = clientData;
-    register Slave *slavePtr, *nextPtr;
-    TkDisplay *dispPtr = ((TkWindow *) masterPtr->tkwin)->dispPtr;
-
-    switch (eventPtr->type) {
-    case ConfigureNotify:
-       if ((masterPtr->slavePtr != NULL)
-               && !(masterPtr->flags & PARENT_RECONFIG_PENDING)) {
-           masterPtr->flags |= PARENT_RECONFIG_PENDING;
-           Tcl_DoWhenIdle(RecomputePlacement, masterPtr);
-       }
-       return;
-    case DestroyNotify:
-       for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
-               slavePtr = nextPtr) {
-           slavePtr->masterPtr = NULL;
-           nextPtr = slavePtr->nextPtr;
-           slavePtr->nextPtr = NULL;
-       }
-       Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->masterTable,
-               (char *) masterPtr->tkwin));
-       if (masterPtr->flags & PARENT_RECONFIG_PENDING) {
-           Tcl_CancelIdleCall(RecomputePlacement, masterPtr);
-       }
-       masterPtr->tkwin = NULL;
-       if (masterPtr->abortPtr != NULL) {
-           *masterPtr->abortPtr = 1;
-       }
-       Tcl_EventuallyFree(masterPtr, TCL_DYNAMIC);
-       return;
-    case MapNotify:
-       /*
-        * When a master gets mapped, must redo the geometry computation so
-        * that all of its slaves get remapped.
-        */
-
-       if ((masterPtr->slavePtr != NULL)
-               && !(masterPtr->flags & PARENT_RECONFIG_PENDING)) {
-           masterPtr->flags |= PARENT_RECONFIG_PENDING;
-           Tcl_DoWhenIdle(RecomputePlacement, masterPtr);
-       }
-       return;
-    case UnmapNotify:
-       /*
-        * Unmap all of the slaves when the master gets unmapped, so that they
-        * don't keep redisplaying themselves.
-        */
-
-       for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
-               slavePtr = slavePtr->nextPtr) {
-           Tk_UnmapWindow(slavePtr->tkwin);
-       }
-       return;
-    }
-}
-\f
-/*
- *----------------------------------------------------------------------
- *
- * SlaveStructureProc --
- *
- *     This function is invoked by the Tk event handler when StructureNotify
- *     events occur for a slave window.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     Structures get cleaned up if the window was deleted.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-SlaveStructureProc(
-    ClientData clientData,     /* Pointer to Slave structure for window
-                                * referred to by eventPtr. */
-    XEvent *eventPtr)          /* Describes what just happened. */
-{
-    register Slave *slavePtr = clientData;
-    TkDisplay *dispPtr = ((TkWindow *) slavePtr->tkwin)->dispPtr;
-
-    if (eventPtr->type == DestroyNotify) {
-       if (slavePtr->masterPtr != NULL) {
-           UnlinkSlave(slavePtr);
-       }
-       Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable,
-               (char *) slavePtr->tkwin));
-       FreeSlave(slavePtr);
-    }
-}
-\f
-/*
- *----------------------------------------------------------------------
- *
- * PlaceRequestProc --
- *
- *     This function is invoked by Tk whenever a slave managed by us changes
- *     its requested geometry.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     The window will get relayed out, if its requested size has anything to
- *     do with its actual size.
- *
- *----------------------------------------------------------------------
- */
-
-       /* ARGSUSED */
-static void
-PlaceRequestProc(
-    ClientData clientData,     /* Pointer to our record for slave. */
-    Tk_Window tkwin)           /* Window that changed its desired size. */
-{
-    Slave *slavePtr = clientData;
-    Master *masterPtr;
-
-    if ((slavePtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH))
-           && (slavePtr->flags & (CHILD_HEIGHT|CHILD_REL_HEIGHT))) {
-       return;
-    }
-    masterPtr = slavePtr->masterPtr;
-    if (masterPtr == NULL) {
-       return;
-    }
-    if (!(masterPtr->flags & PARENT_RECONFIG_PENDING)) {
-       masterPtr->flags |= PARENT_RECONFIG_PENDING;
-       Tcl_DoWhenIdle(RecomputePlacement, masterPtr);
-    }
-}
-\f
-/*
- *--------------------------------------------------------------
- *
- * PlaceLostSlaveProc --
- *
- *     This function is invoked by Tk whenever some other geometry claims
- *     control over a slave that used to be managed by us.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     Forgets all placer-related information about the slave.
- *
- *--------------------------------------------------------------
- */
-
-       /* ARGSUSED */
-static void
-PlaceLostSlaveProc(
-    ClientData clientData,     /* Slave structure for slave window that was
-                                * stolen away. */
-    Tk_Window tkwin)           /* Tk's handle for the slave window. */
-{
-    register Slave *slavePtr = clientData;
-    TkDisplay *dispPtr = ((TkWindow *) slavePtr->tkwin)->dispPtr;
-
-    if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) {
-       Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin);
-    }
-    Tk_UnmapWindow(tkwin);
-    UnlinkSlave(slavePtr);
-    Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable,
-           (char *) tkwin));
-    Tk_DeleteEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc,
-           slavePtr);
-    FreeSlave(slavePtr);
-}
-\f
-/*
- * Local Variables:
- * mode: c
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */