/[dtapublic]/projs/dtats/trunk/shared_source/c_tk_base_7_5_w_mods/tkplace.c
ViewVC logotype

Diff of /projs/dtats/trunk/shared_source/c_tk_base_7_5_w_mods/tkplace.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 69 by dashley, Sat Nov 5 10:54:17 2016 UTC revision 71 by dashley, Sat Nov 5 11:07:06 2016 UTC
# Line 1  Line 1 
1  /* $Header$ */  /* $Header$ */
2    
3  /*  /*
4   * tkPlace.c --   * tkPlace.c --
5   *   *
6   *      This file contains code to implement a simple geometry manager   *      This file contains code to implement a simple geometry manager
7   *      for Tk based on absolute placement or "rubber-sheet" placement.   *      for Tk based on absolute placement or "rubber-sheet" placement.
8   *   *
9   * Copyright (c) 1992-1994 The Regents of the University of California.   * Copyright (c) 1992-1994 The Regents of the University of California.
10   * Copyright (c) 1994-1997 Sun Microsystems, Inc.   * Copyright (c) 1994-1997 Sun Microsystems, Inc.
11   *   *
12   * See the file "license.terms" for information on usage and redistribution   * See the file "license.terms" for information on usage and redistribution
13   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14   *   *
15   * RCS: @(#) $Id: tkplace.c,v 1.1.1.1 2001/06/13 05:07:09 dtashley Exp $   * RCS: @(#) $Id: tkplace.c,v 1.1.1.1 2001/06/13 05:07:09 dtashley Exp $
16   */   */
17    
18  #include "tkPort.h"  #include "tkPort.h"
19  #include "tkInt.h"  #include "tkInt.h"
20    
21  /*  /*
22   * Border modes for relative placement:   * Border modes for relative placement:
23   *   *
24   * BM_INSIDE:           relative distances computed using area inside   * BM_INSIDE:           relative distances computed using area inside
25   *                      all borders of master window.   *                      all borders of master window.
26   * BM_OUTSIDE:          relative distances computed using outside area   * BM_OUTSIDE:          relative distances computed using outside area
27   *                      that includes all borders of master.   *                      that includes all borders of master.
28   * BM_IGNORE:           border issues are ignored:  place relative to   * BM_IGNORE:           border issues are ignored:  place relative to
29   *                      master's actual window size.   *                      master's actual window size.
30   */   */
31    
32  typedef enum {BM_INSIDE, BM_OUTSIDE, BM_IGNORE} BorderMode;  typedef enum {BM_INSIDE, BM_OUTSIDE, BM_IGNORE} BorderMode;
33    
34  /*  /*
35   * For each window whose geometry is managed by the placer there is   * For each window whose geometry is managed by the placer there is
36   * a structure of the following type:   * a structure of the following type:
37   */   */
38    
39  typedef struct Slave {  typedef struct Slave {
40      Tk_Window tkwin;            /* Tk's token for window. */      Tk_Window tkwin;            /* Tk's token for window. */
41      struct Master *masterPtr;   /* Pointer to information for window      struct Master *masterPtr;   /* Pointer to information for window
42                                   * relative to which tkwin is placed.                                   * relative to which tkwin is placed.
43                                   * This isn't necessarily the logical                                   * This isn't necessarily the logical
44                                   * parent of tkwin.  NULL means the                                   * parent of tkwin.  NULL means the
45                                   * master was deleted or never assigned. */                                   * master was deleted or never assigned. */
46      struct Slave *nextPtr;      /* Next in list of windows placed relative      struct Slave *nextPtr;      /* Next in list of windows placed relative
47                                   * to same master (NULL for end of list). */                                   * to same master (NULL for end of list). */
48    
49      /*      /*
50       * Geometry information for window;  where there are both relative       * Geometry information for window;  where there are both relative
51       * and absolute values for the same attribute (e.g. x and relX) only       * and absolute values for the same attribute (e.g. x and relX) only
52       * one of them is actually used, depending on flags.       * one of them is actually used, depending on flags.
53       */       */
54    
55      int x, y;                   /* X and Y pixel coordinates for tkwin. */      int x, y;                   /* X and Y pixel coordinates for tkwin. */
56      float relX, relY;           /* X and Y coordinates relative to size of      float relX, relY;           /* X and Y coordinates relative to size of
57                                   * master. */                                   * master. */
58      int width, height;          /* Absolute dimensions for tkwin. */      int width, height;          /* Absolute dimensions for tkwin. */
59      float relWidth, relHeight;  /* Dimensions for tkwin relative to size of      float relWidth, relHeight;  /* Dimensions for tkwin relative to size of
60                                   * master. */                                   * master. */
61      Tk_Anchor anchor;           /* Which point on tkwin is placed at the      Tk_Anchor anchor;           /* Which point on tkwin is placed at the
62                                   * given position. */                                   * given position. */
63      BorderMode borderMode;      /* How to treat borders of master window. */      BorderMode borderMode;      /* How to treat borders of master window. */
64      int flags;                  /* Various flags;  see below for bit      int flags;                  /* Various flags;  see below for bit
65                                   * definitions. */                                   * definitions. */
66  } Slave;  } Slave;
67    
68  /*  /*
69   * Flag definitions for Slave structures:   * Flag definitions for Slave structures:
70   *   *
71   * CHILD_WIDTH -                1 means -width was specified;   * CHILD_WIDTH -                1 means -width was specified;
72   * CHILD_REL_WIDTH -            1 means -relwidth was specified.   * CHILD_REL_WIDTH -            1 means -relwidth was specified.
73   * CHILD_HEIGHT -               1 means -height was specified;   * CHILD_HEIGHT -               1 means -height was specified;
74   * CHILD_REL_HEIGHT -           1 means -relheight was specified.   * CHILD_REL_HEIGHT -           1 means -relheight was specified.
75   */   */
76    
77  #define CHILD_WIDTH             1  #define CHILD_WIDTH             1
78  #define CHILD_REL_WIDTH         2  #define CHILD_REL_WIDTH         2
79  #define CHILD_HEIGHT            4  #define CHILD_HEIGHT            4
80  #define CHILD_REL_HEIGHT        8  #define CHILD_REL_HEIGHT        8
81    
82  /*  /*
83   * For each master window that has a slave managed by the placer there   * For each master window that has a slave managed by the placer there
84   * is a structure of the following form:   * is a structure of the following form:
85   */   */
86    
87  typedef struct Master {  typedef struct Master {
88      Tk_Window tkwin;            /* Tk's token for master window. */      Tk_Window tkwin;            /* Tk's token for master window. */
89      struct Slave *slavePtr;     /* First in linked list of slaves      struct Slave *slavePtr;     /* First in linked list of slaves
90                                   * placed relative to this master. */                                   * placed relative to this master. */
91      int flags;                  /* See below for bit definitions. */      int flags;                  /* See below for bit definitions. */
92  } Master;  } Master;
93    
94  /*  /*
95   * Flag definitions for masters:   * Flag definitions for masters:
96   *   *
97   * PARENT_RECONFIG_PENDING -    1 means that a call to RecomputePlacement   * PARENT_RECONFIG_PENDING -    1 means that a call to RecomputePlacement
98   *                              is already pending via a Do_When_Idle handler.   *                              is already pending via a Do_When_Idle handler.
99   */   */
100    
101  #define PARENT_RECONFIG_PENDING 1  #define PARENT_RECONFIG_PENDING 1
102    
103  /*  /*
104   * The following structure is the official type record for the   * The following structure is the official type record for the
105   * placer:   * placer:
106   */   */
107    
108  static void             PlaceRequestProc _ANSI_ARGS_((ClientData clientData,  static void             PlaceRequestProc _ANSI_ARGS_((ClientData clientData,
109                              Tk_Window tkwin));                              Tk_Window tkwin));
110  static void             PlaceLostSlaveProc _ANSI_ARGS_((ClientData clientData,  static void             PlaceLostSlaveProc _ANSI_ARGS_((ClientData clientData,
111                              Tk_Window tkwin));                              Tk_Window tkwin));
112    
113  static Tk_GeomMgr placerType = {  static Tk_GeomMgr placerType = {
114      "place",                            /* name */      "place",                            /* name */
115      PlaceRequestProc,                   /* requestProc */      PlaceRequestProc,                   /* requestProc */
116      PlaceLostSlaveProc,                 /* lostSlaveProc */      PlaceLostSlaveProc,                 /* lostSlaveProc */
117  };  };
118    
119  /*  /*
120   * Forward declarations for procedures defined later in this file:   * Forward declarations for procedures defined later in this file:
121   */   */
122    
123  static void             SlaveStructureProc _ANSI_ARGS_((ClientData clientData,  static void             SlaveStructureProc _ANSI_ARGS_((ClientData clientData,
124                              XEvent *eventPtr));                              XEvent *eventPtr));
125  static int              ConfigureSlave _ANSI_ARGS_((Tcl_Interp *interp,  static int              ConfigureSlave _ANSI_ARGS_((Tcl_Interp *interp,
126                              Slave *slavePtr, int argc, char **argv));                              Slave *slavePtr, int argc, char **argv));
127  static Slave *          FindSlave _ANSI_ARGS_((Tk_Window tkwin));  static Slave *          FindSlave _ANSI_ARGS_((Tk_Window tkwin));
128  static Master *         FindMaster _ANSI_ARGS_((Tk_Window tkwin));  static Master *         FindMaster _ANSI_ARGS_((Tk_Window tkwin));
129  static void             MasterStructureProc _ANSI_ARGS_((ClientData clientData,  static void             MasterStructureProc _ANSI_ARGS_((ClientData clientData,
130                              XEvent *eventPtr));                              XEvent *eventPtr));
131  static void             RecomputePlacement _ANSI_ARGS_((ClientData clientData));  static void             RecomputePlacement _ANSI_ARGS_((ClientData clientData));
132  static void             UnlinkSlave _ANSI_ARGS_((Slave *slavePtr));  static void             UnlinkSlave _ANSI_ARGS_((Slave *slavePtr));
133    
134  /*  /*
135   *--------------------------------------------------------------   *--------------------------------------------------------------
136   *   *
137   * Tk_PlaceCmd --   * Tk_PlaceCmd --
138   *   *
139   *      This procedure is invoked to process the "place" Tcl   *      This procedure is invoked to process the "place" Tcl
140   *      commands.  See the user documentation for details on   *      commands.  See the user documentation for details on
141   *      what it does.   *      what it does.
142   *   *
143   * Results:   * Results:
144   *      A standard Tcl result.   *      A standard Tcl result.
145   *   *
146   * Side effects:   * Side effects:
147   *      See the user documentation.   *      See the user documentation.
148   *   *
149   *--------------------------------------------------------------   *--------------------------------------------------------------
150   */   */
151    
152  int  int
153  Tk_PlaceCmd(clientData, interp, argc, argv)  Tk_PlaceCmd(clientData, interp, argc, argv)
154      ClientData clientData;      /* Main window associated with interpreter. */      ClientData clientData;      /* Main window associated with interpreter. */
155      Tcl_Interp *interp;         /* Current interpreter. */      Tcl_Interp *interp;         /* Current interpreter. */
156      int argc;                   /* Number of arguments. */      int argc;                   /* Number of arguments. */
157      char **argv;                /* Argument strings. */      char **argv;                /* Argument strings. */
158  {  {
159      Tk_Window tkwin;      Tk_Window tkwin;
160      Slave *slavePtr;      Slave *slavePtr;
161      Tcl_HashEntry *hPtr;      Tcl_HashEntry *hPtr;
162      size_t length;      size_t length;
163      int c;      int c;
164      TkDisplay *dispPtr;      TkDisplay *dispPtr;
165    
166      dispPtr = ((TkWindow *) clientData)->dispPtr;      dispPtr = ((TkWindow *) clientData)->dispPtr;
167    
168      /*      /*
169       * Initialize, if that hasn't been done yet.       * Initialize, if that hasn't been done yet.
170       */       */
171    
172      if (!dispPtr->placeInit) {      if (!dispPtr->placeInit) {
173          Tcl_InitHashTable(&dispPtr->masterTable, TCL_ONE_WORD_KEYS);          Tcl_InitHashTable(&dispPtr->masterTable, TCL_ONE_WORD_KEYS);
174          Tcl_InitHashTable(&dispPtr->slaveTable, TCL_ONE_WORD_KEYS);          Tcl_InitHashTable(&dispPtr->slaveTable, TCL_ONE_WORD_KEYS);
175          dispPtr->placeInit = 1;          dispPtr->placeInit = 1;
176      }      }
177    
178      if (argc < 3) {      if (argc < 3) {
179          Tcl_AppendResult(interp, "wrong # args: should be \"",          Tcl_AppendResult(interp, "wrong # args: should be \"",
180                  argv[0], " option|pathName args", (char *) NULL);                  argv[0], " option|pathName args", (char *) NULL);
181          return TCL_ERROR;          return TCL_ERROR;
182      }      }
183      c = argv[1][0];      c = argv[1][0];
184      length = strlen(argv[1]);      length = strlen(argv[1]);
185    
186      /*      /*
187       * Handle special shortcut where window name is first argument.       * Handle special shortcut where window name is first argument.
188       */       */
189    
190      if (c == '.') {      if (c == '.') {
191          tkwin = Tk_NameToWindow(interp, argv[1], (Tk_Window) clientData);          tkwin = Tk_NameToWindow(interp, argv[1], (Tk_Window) clientData);
192          if (tkwin == NULL) {          if (tkwin == NULL) {
193              return TCL_ERROR;              return TCL_ERROR;
194          }          }
195          slavePtr = FindSlave(tkwin);          slavePtr = FindSlave(tkwin);
196          return ConfigureSlave(interp, slavePtr, argc-2, argv+2);          return ConfigureSlave(interp, slavePtr, argc-2, argv+2);
197      }      }
198    
199      /*      /*
200       * Handle more general case of option followed by window name followed       * Handle more general case of option followed by window name followed
201       * by possible additional arguments.       * by possible additional arguments.
202       */       */
203    
204      tkwin = Tk_NameToWindow(interp, argv[2], (Tk_Window) clientData);      tkwin = Tk_NameToWindow(interp, argv[2], (Tk_Window) clientData);
205      if (tkwin == NULL) {      if (tkwin == NULL) {
206          return TCL_ERROR;          return TCL_ERROR;
207      }      }
208      if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0)) {      if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0)) {
209          if (argc < 5) {          if (argc < 5) {
210              Tcl_AppendResult(interp, "wrong # args: should be \"",              Tcl_AppendResult(interp, "wrong # args: should be \"",
211                      argv[0],                      argv[0],
212                      " configure pathName option value ?option value ...?\"",                      " configure pathName option value ?option value ...?\"",
213                      (char *) NULL);                      (char *) NULL);
214              return TCL_ERROR;              return TCL_ERROR;
215          }          }
216          slavePtr = FindSlave(tkwin);          slavePtr = FindSlave(tkwin);
217          return ConfigureSlave(interp, slavePtr, argc-3, argv+3);          return ConfigureSlave(interp, slavePtr, argc-3, argv+3);
218      } else if ((c == 'f') && (strncmp(argv[1], "forget", length) == 0)) {      } else if ((c == 'f') && (strncmp(argv[1], "forget", length) == 0)) {
219          if (argc != 3) {          if (argc != 3) {
220              Tcl_AppendResult(interp, "wrong # args: should be \"",              Tcl_AppendResult(interp, "wrong # args: should be \"",
221                      argv[0], " forget pathName\"", (char *) NULL);                      argv[0], " forget pathName\"", (char *) NULL);
222              return TCL_ERROR;              return TCL_ERROR;
223          }          }
224          hPtr = Tcl_FindHashEntry(&dispPtr->slaveTable, (char *) tkwin);          hPtr = Tcl_FindHashEntry(&dispPtr->slaveTable, (char *) tkwin);
225          if (hPtr == NULL) {          if (hPtr == NULL) {
226              return TCL_OK;              return TCL_OK;
227          }          }
228          slavePtr = (Slave *) Tcl_GetHashValue(hPtr);          slavePtr = (Slave *) Tcl_GetHashValue(hPtr);
229          if ((slavePtr->masterPtr != NULL) &&          if ((slavePtr->masterPtr != NULL) &&
230                  (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin))) {                  (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin))) {
231              Tk_UnmaintainGeometry(slavePtr->tkwin,              Tk_UnmaintainGeometry(slavePtr->tkwin,
232                      slavePtr->masterPtr->tkwin);                      slavePtr->masterPtr->tkwin);
233          }          }
234          UnlinkSlave(slavePtr);          UnlinkSlave(slavePtr);
235          Tcl_DeleteHashEntry(hPtr);          Tcl_DeleteHashEntry(hPtr);
236          Tk_DeleteEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc,          Tk_DeleteEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc,
237                  (ClientData) slavePtr);                  (ClientData) slavePtr);
238          Tk_ManageGeometry(tkwin, (Tk_GeomMgr *) NULL, (ClientData) NULL);          Tk_ManageGeometry(tkwin, (Tk_GeomMgr *) NULL, (ClientData) NULL);
239          Tk_UnmapWindow(tkwin);          Tk_UnmapWindow(tkwin);
240          ckfree((char *) slavePtr);          ckfree((char *) slavePtr);
241      } else if ((c == 'i') && (strncmp(argv[1], "info", length) == 0)) {      } else if ((c == 'i') && (strncmp(argv[1], "info", length) == 0)) {
242          char buffer[32 + TCL_INTEGER_SPACE];          char buffer[32 + TCL_INTEGER_SPACE];
243    
244          if (argc != 3) {          if (argc != 3) {
245              Tcl_AppendResult(interp, "wrong # args: should be \"",              Tcl_AppendResult(interp, "wrong # args: should be \"",
246                      argv[0], " info pathName\"", (char *) NULL);                      argv[0], " info pathName\"", (char *) NULL);
247              return TCL_ERROR;              return TCL_ERROR;
248          }          }
249          hPtr = Tcl_FindHashEntry(&dispPtr->slaveTable, (char *) tkwin);          hPtr = Tcl_FindHashEntry(&dispPtr->slaveTable, (char *) tkwin);
250          if (hPtr == NULL) {          if (hPtr == NULL) {
251              return TCL_OK;              return TCL_OK;
252          }          }
253          slavePtr = (Slave *) Tcl_GetHashValue(hPtr);          slavePtr = (Slave *) Tcl_GetHashValue(hPtr);
254          sprintf(buffer, "-x %d", slavePtr->x);          sprintf(buffer, "-x %d", slavePtr->x);
255          Tcl_AppendResult(interp, buffer, (char *) NULL);          Tcl_AppendResult(interp, buffer, (char *) NULL);
256          sprintf(buffer, " -relx %.4g", slavePtr->relX);          sprintf(buffer, " -relx %.4g", slavePtr->relX);
257          Tcl_AppendResult(interp, buffer, (char *) NULL);          Tcl_AppendResult(interp, buffer, (char *) NULL);
258          sprintf(buffer, " -y %d", slavePtr->y);          sprintf(buffer, " -y %d", slavePtr->y);
259          Tcl_AppendResult(interp, buffer, (char *) NULL);          Tcl_AppendResult(interp, buffer, (char *) NULL);
260          sprintf(buffer, " -rely %.4g", slavePtr->relY);          sprintf(buffer, " -rely %.4g", slavePtr->relY);
261          Tcl_AppendResult(interp, buffer, (char *) NULL);          Tcl_AppendResult(interp, buffer, (char *) NULL);
262          if (slavePtr->flags & CHILD_WIDTH) {          if (slavePtr->flags & CHILD_WIDTH) {
263              sprintf(buffer, " -width %d", slavePtr->width);              sprintf(buffer, " -width %d", slavePtr->width);
264              Tcl_AppendResult(interp, buffer, (char *) NULL);              Tcl_AppendResult(interp, buffer, (char *) NULL);
265          } else {          } else {
266              Tcl_AppendResult(interp, " -width {}", (char *) NULL);              Tcl_AppendResult(interp, " -width {}", (char *) NULL);
267          }          }
268          if (slavePtr->flags & CHILD_REL_WIDTH) {          if (slavePtr->flags & CHILD_REL_WIDTH) {
269              sprintf(buffer, " -relwidth %.4g", slavePtr->relWidth);              sprintf(buffer, " -relwidth %.4g", slavePtr->relWidth);
270              Tcl_AppendResult(interp, buffer, (char *) NULL);              Tcl_AppendResult(interp, buffer, (char *) NULL);
271          } else {          } else {
272              Tcl_AppendResult(interp, " -relwidth {}", (char *) NULL);              Tcl_AppendResult(interp, " -relwidth {}", (char *) NULL);
273          }          }
274          if (slavePtr->flags & CHILD_HEIGHT) {          if (slavePtr->flags & CHILD_HEIGHT) {
275              sprintf(buffer, " -height %d", slavePtr->height);              sprintf(buffer, " -height %d", slavePtr->height);
276              Tcl_AppendResult(interp, buffer, (char *) NULL);              Tcl_AppendResult(interp, buffer, (char *) NULL);
277          } else {          } else {
278              Tcl_AppendResult(interp, " -height {}", (char *) NULL);              Tcl_AppendResult(interp, " -height {}", (char *) NULL);
279          }          }
280          if (slavePtr->flags & CHILD_REL_HEIGHT) {          if (slavePtr->flags & CHILD_REL_HEIGHT) {
281              sprintf(buffer, " -relheight %.4g", slavePtr->relHeight);              sprintf(buffer, " -relheight %.4g", slavePtr->relHeight);
282              Tcl_AppendResult(interp, buffer, (char *) NULL);              Tcl_AppendResult(interp, buffer, (char *) NULL);
283          } else {          } else {
284              Tcl_AppendResult(interp, " -relheight {}", (char *) NULL);              Tcl_AppendResult(interp, " -relheight {}", (char *) NULL);
285          }          }
286    
287          Tcl_AppendResult(interp, " -anchor ", Tk_NameOfAnchor(slavePtr->anchor),          Tcl_AppendResult(interp, " -anchor ", Tk_NameOfAnchor(slavePtr->anchor),
288                  (char *) NULL);                  (char *) NULL);
289          if (slavePtr->borderMode == BM_OUTSIDE) {          if (slavePtr->borderMode == BM_OUTSIDE) {
290              Tcl_AppendResult(interp, " -bordermode outside", (char *) NULL);              Tcl_AppendResult(interp, " -bordermode outside", (char *) NULL);
291          } else if (slavePtr->borderMode == BM_IGNORE) {          } else if (slavePtr->borderMode == BM_IGNORE) {
292              Tcl_AppendResult(interp, " -bordermode ignore", (char *) NULL);              Tcl_AppendResult(interp, " -bordermode ignore", (char *) NULL);
293          }          }
294          if ((slavePtr->masterPtr != NULL)          if ((slavePtr->masterPtr != NULL)
295                  && (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin))) {                  && (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin))) {
296              Tcl_AppendResult(interp, " -in ",              Tcl_AppendResult(interp, " -in ",
297                      Tk_PathName(slavePtr->masterPtr->tkwin), (char *) NULL);                      Tk_PathName(slavePtr->masterPtr->tkwin), (char *) NULL);
298          }          }
299      } else if ((c == 's') && (strncmp(argv[1], "slaves", length) == 0)) {      } else if ((c == 's') && (strncmp(argv[1], "slaves", length) == 0)) {
300          if (argc != 3) {          if (argc != 3) {
301              Tcl_AppendResult(interp, "wrong # args: should be \"",              Tcl_AppendResult(interp, "wrong # args: should be \"",
302                      argv[0], " slaves pathName\"", (char *) NULL);                      argv[0], " slaves pathName\"", (char *) NULL);
303              return TCL_ERROR;              return TCL_ERROR;
304          }          }
305          hPtr = Tcl_FindHashEntry(&dispPtr->masterTable, (char *) tkwin);          hPtr = Tcl_FindHashEntry(&dispPtr->masterTable, (char *) tkwin);
306          if (hPtr != NULL) {          if (hPtr != NULL) {
307              Master *masterPtr;              Master *masterPtr;
308              masterPtr = (Master *) Tcl_GetHashValue(hPtr);              masterPtr = (Master *) Tcl_GetHashValue(hPtr);
309              for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;              for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
310                      slavePtr = slavePtr->nextPtr) {                      slavePtr = slavePtr->nextPtr) {
311                  Tcl_AppendElement(interp, Tk_PathName(slavePtr->tkwin));                  Tcl_AppendElement(interp, Tk_PathName(slavePtr->tkwin));
312              }              }
313          }          }
314      } else {      } else {
315          Tcl_AppendResult(interp, "unknown or ambiguous option \"", argv[1],          Tcl_AppendResult(interp, "unknown or ambiguous option \"", argv[1],
316                  "\": must be configure, forget, info, or slaves",                  "\": must be configure, forget, info, or slaves",
317                  (char *) NULL);                  (char *) NULL);
318          return TCL_ERROR;          return TCL_ERROR;
319      }      }
320      return TCL_OK;      return TCL_OK;
321  }  }
322    
323  /*  /*
324   *----------------------------------------------------------------------   *----------------------------------------------------------------------
325   *   *
326   * FindSlave --   * FindSlave --
327   *   *
328   *      Given a Tk_Window token, find the Slave structure corresponding   *      Given a Tk_Window token, find the Slave structure corresponding
329   *      to that token (making a new one if necessary).   *      to that token (making a new one if necessary).
330   *   *
331   * Results:   * Results:
332   *      None.   *      None.
333   *   *
334   * Side effects:   * Side effects:
335   *      A new Slave structure may be created.   *      A new Slave structure may be created.
336   *   *
337   *----------------------------------------------------------------------   *----------------------------------------------------------------------
338   */   */
339    
340  static Slave *  static Slave *
341  FindSlave(tkwin)  FindSlave(tkwin)
342      Tk_Window tkwin;            /* Token for desired slave. */      Tk_Window tkwin;            /* Token for desired slave. */
343  {  {
344      Tcl_HashEntry *hPtr;      Tcl_HashEntry *hPtr;
345      register Slave *slavePtr;      register Slave *slavePtr;
346      int new;      int new;
347      TkDisplay * dispPtr = ((TkWindow *) tkwin)->dispPtr;      TkDisplay * dispPtr = ((TkWindow *) tkwin)->dispPtr;
348    
349      hPtr = Tcl_CreateHashEntry(&dispPtr->slaveTable, (char *) tkwin, &new);      hPtr = Tcl_CreateHashEntry(&dispPtr->slaveTable, (char *) tkwin, &new);
350      if (new) {      if (new) {
351          slavePtr = (Slave *) ckalloc(sizeof(Slave));          slavePtr = (Slave *) ckalloc(sizeof(Slave));
352          slavePtr->tkwin = tkwin;          slavePtr->tkwin = tkwin;
353          slavePtr->masterPtr = NULL;          slavePtr->masterPtr = NULL;
354          slavePtr->nextPtr = NULL;          slavePtr->nextPtr = NULL;
355          slavePtr->x = slavePtr->y = 0;          slavePtr->x = slavePtr->y = 0;
356          slavePtr->relX = slavePtr->relY = (float) 0.0;          slavePtr->relX = slavePtr->relY = (float) 0.0;
357          slavePtr->width = slavePtr->height = 0;          slavePtr->width = slavePtr->height = 0;
358          slavePtr->relWidth = slavePtr->relHeight = (float) 0.0;          slavePtr->relWidth = slavePtr->relHeight = (float) 0.0;
359          slavePtr->anchor = TK_ANCHOR_NW;          slavePtr->anchor = TK_ANCHOR_NW;
360          slavePtr->borderMode = BM_INSIDE;          slavePtr->borderMode = BM_INSIDE;
361          slavePtr->flags = 0;          slavePtr->flags = 0;
362          Tcl_SetHashValue(hPtr, slavePtr);          Tcl_SetHashValue(hPtr, slavePtr);
363          Tk_CreateEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc,          Tk_CreateEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc,
364                  (ClientData) slavePtr);                  (ClientData) slavePtr);
365          Tk_ManageGeometry(tkwin, &placerType, (ClientData) slavePtr);          Tk_ManageGeometry(tkwin, &placerType, (ClientData) slavePtr);
366      } else {      } else {
367          slavePtr = (Slave *) Tcl_GetHashValue(hPtr);          slavePtr = (Slave *) Tcl_GetHashValue(hPtr);
368      }      }
369      return slavePtr;      return slavePtr;
370  }  }
371    
372  /*  /*
373   *----------------------------------------------------------------------   *----------------------------------------------------------------------
374   *   *
375   * UnlinkSlave --   * UnlinkSlave --
376   *   *
377   *      This procedure removes a slave window from the chain of slaves   *      This procedure removes a slave window from the chain of slaves
378   *      in its master.   *      in its master.
379   *   *
380   * Results:   * Results:
381   *      None.   *      None.
382   *   *
383   * Side effects:   * Side effects:
384   *      The slave list of slavePtr's master changes.   *      The slave list of slavePtr's master changes.
385   *   *
386   *----------------------------------------------------------------------   *----------------------------------------------------------------------
387   */   */
388    
389  static void  static void
390  UnlinkSlave(slavePtr)  UnlinkSlave(slavePtr)
391      Slave *slavePtr;            /* Slave structure to be unlinked. */      Slave *slavePtr;            /* Slave structure to be unlinked. */
392  {  {
393      register Master *masterPtr;      register Master *masterPtr;
394      register Slave *prevPtr;      register Slave *prevPtr;
395    
396      masterPtr = slavePtr->masterPtr;      masterPtr = slavePtr->masterPtr;
397      if (masterPtr == NULL) {      if (masterPtr == NULL) {
398          return;          return;
399      }      }
400      if (masterPtr->slavePtr == slavePtr) {      if (masterPtr->slavePtr == slavePtr) {
401          masterPtr->slavePtr = slavePtr->nextPtr;          masterPtr->slavePtr = slavePtr->nextPtr;
402      } else {      } else {
403          for (prevPtr = masterPtr->slavePtr; ;          for (prevPtr = masterPtr->slavePtr; ;
404                  prevPtr = prevPtr->nextPtr) {                  prevPtr = prevPtr->nextPtr) {
405              if (prevPtr == NULL) {              if (prevPtr == NULL) {
406                  panic("UnlinkSlave couldn't find slave to unlink");                  panic("UnlinkSlave couldn't find slave to unlink");
407              }              }
408              if (prevPtr->nextPtr == slavePtr) {              if (prevPtr->nextPtr == slavePtr) {
409                  prevPtr->nextPtr = slavePtr->nextPtr;                  prevPtr->nextPtr = slavePtr->nextPtr;
410                  break;                  break;
411              }              }
412          }          }
413      }      }
414      slavePtr->masterPtr = NULL;      slavePtr->masterPtr = NULL;
415  }  }
416    
417  /*  /*
418   *----------------------------------------------------------------------   *----------------------------------------------------------------------
419   *   *
420   * FindMaster --   * FindMaster --
421   *   *
422   *      Given a Tk_Window token, find the Master structure corresponding   *      Given a Tk_Window token, find the Master structure corresponding
423   *      to that token (making a new one if necessary).   *      to that token (making a new one if necessary).
424   *   *
425   * Results:   * Results:
426   *      None.   *      None.
427   *   *
428   * Side effects:   * Side effects:
429   *      A new Master structure may be created.   *      A new Master structure may be created.
430   *   *
431   *----------------------------------------------------------------------   *----------------------------------------------------------------------
432   */   */
433    
434  static Master *  static Master *
435  FindMaster(tkwin)  FindMaster(tkwin)
436      Tk_Window tkwin;            /* Token for desired master. */      Tk_Window tkwin;            /* Token for desired master. */
437  {  {
438      Tcl_HashEntry *hPtr;      Tcl_HashEntry *hPtr;
439      register Master *masterPtr;      register Master *masterPtr;
440      int new;      int new;
441      TkDisplay * dispPtr = ((TkWindow *) tkwin)->dispPtr;      TkDisplay * dispPtr = ((TkWindow *) tkwin)->dispPtr;
442    
443      hPtr = Tcl_CreateHashEntry(&dispPtr->masterTable, (char *) tkwin, &new);      hPtr = Tcl_CreateHashEntry(&dispPtr->masterTable, (char *) tkwin, &new);
444      if (new) {      if (new) {
445          masterPtr = (Master *) ckalloc(sizeof(Master));          masterPtr = (Master *) ckalloc(sizeof(Master));
446          masterPtr->tkwin = tkwin;          masterPtr->tkwin = tkwin;
447          masterPtr->slavePtr = NULL;          masterPtr->slavePtr = NULL;
448          masterPtr->flags = 0;          masterPtr->flags = 0;
449          Tcl_SetHashValue(hPtr, masterPtr);          Tcl_SetHashValue(hPtr, masterPtr);
450          Tk_CreateEventHandler(masterPtr->tkwin, StructureNotifyMask,          Tk_CreateEventHandler(masterPtr->tkwin, StructureNotifyMask,
451                  MasterStructureProc, (ClientData) masterPtr);                  MasterStructureProc, (ClientData) masterPtr);
452      } else {      } else {
453          masterPtr = (Master *) Tcl_GetHashValue(hPtr);          masterPtr = (Master *) Tcl_GetHashValue(hPtr);
454      }      }
455      return masterPtr;      return masterPtr;
456  }  }
457    
458  /*  /*
459   *----------------------------------------------------------------------   *----------------------------------------------------------------------
460   *   *
461   * ConfigureSlave --   * ConfigureSlave --
462   *   *
463   *      This procedure is called to process an argv/argc list to   *      This procedure is called to process an argv/argc list to
464   *      reconfigure the placement of a window.   *      reconfigure the placement of a window.
465   *   *
466   * Results:   * Results:
467   *      A standard Tcl result.  If an error occurs then a message is   *      A standard Tcl result.  If an error occurs then a message is
468   *      left in the interp's result.   *      left in the interp's result.
469   *   *
470   * Side effects:   * Side effects:
471   *      Information in slavePtr may change, and slavePtr's master is   *      Information in slavePtr may change, and slavePtr's master is
472   *      scheduled for reconfiguration.   *      scheduled for reconfiguration.
473   *   *
474   *----------------------------------------------------------------------   *----------------------------------------------------------------------
475   */   */
476    
477  static int  static int
478  ConfigureSlave(interp, slavePtr, argc, argv)  ConfigureSlave(interp, slavePtr, argc, argv)
479      Tcl_Interp *interp;         /* Used for error reporting. */      Tcl_Interp *interp;         /* Used for error reporting. */
480      Slave *slavePtr;            /* Pointer to current information      Slave *slavePtr;            /* Pointer to current information
481                                   * about slave. */                                   * about slave. */
482      int argc;                   /* Number of config arguments. */      int argc;                   /* Number of config arguments. */
483      char **argv;                /* String values for arguments. */      char **argv;                /* String values for arguments. */
484  {  {
485      register Master *masterPtr;      register Master *masterPtr;
486      int c, result;      int c, result;
487      size_t length;      size_t length;
488      double d;      double d;
489    
490      result = TCL_OK;      result = TCL_OK;
491      if (Tk_IsTopLevel(slavePtr->tkwin)) {      if (Tk_IsTopLevel(slavePtr->tkwin)) {
492          Tcl_AppendResult(interp, "can't use placer on top-level window \"",          Tcl_AppendResult(interp, "can't use placer on top-level window \"",
493                  Tk_PathName(slavePtr->tkwin), "\"; use wm command instead",                  Tk_PathName(slavePtr->tkwin), "\"; use wm command instead",
494                  (char *) NULL);                  (char *) NULL);
495          return TCL_ERROR;          return TCL_ERROR;
496      }      }
497      for ( ; argc > 0; argc -= 2, argv += 2) {      for ( ; argc > 0; argc -= 2, argv += 2) {
498          if (argc < 2) {          if (argc < 2) {
499              Tcl_AppendResult(interp, "extra option \"", argv[0],              Tcl_AppendResult(interp, "extra option \"", argv[0],
500                      "\" (option with no value?)", (char *) NULL);                      "\" (option with no value?)", (char *) NULL);
501              result = TCL_ERROR;              result = TCL_ERROR;
502              goto done;              goto done;
503          }          }
504          length = strlen(argv[0]);          length = strlen(argv[0]);
505          c = argv[0][1];          c = argv[0][1];
506          if ((c == 'a') && (strncmp(argv[0], "-anchor", length) == 0)) {          if ((c == 'a') && (strncmp(argv[0], "-anchor", length) == 0)) {
507              if (Tk_GetAnchor(interp, argv[1], &slavePtr->anchor) != TCL_OK) {              if (Tk_GetAnchor(interp, argv[1], &slavePtr->anchor) != TCL_OK) {
508                  result = TCL_ERROR;                  result = TCL_ERROR;
509                  goto done;                  goto done;
510              }              }
511          } else if ((c == 'b')          } else if ((c == 'b')
512                  && (strncmp(argv[0], "-bordermode", length) == 0)) {                  && (strncmp(argv[0], "-bordermode", length) == 0)) {
513              c = argv[1][0];              c = argv[1][0];
514              length = strlen(argv[1]);              length = strlen(argv[1]);
515              if ((c == 'i') && (strncmp(argv[1], "ignore", length) == 0)              if ((c == 'i') && (strncmp(argv[1], "ignore", length) == 0)
516                      && (length >= 2)) {                      && (length >= 2)) {
517                  slavePtr->borderMode = BM_IGNORE;                  slavePtr->borderMode = BM_IGNORE;
518              } else if ((c == 'i') && (strncmp(argv[1], "inside", length) == 0)              } else if ((c == 'i') && (strncmp(argv[1], "inside", length) == 0)
519                      && (length >= 2)) {                      && (length >= 2)) {
520                  slavePtr->borderMode = BM_INSIDE;                  slavePtr->borderMode = BM_INSIDE;
521              } else if ((c == 'o')              } else if ((c == 'o')
522                      && (strncmp(argv[1], "outside", length) == 0)) {                      && (strncmp(argv[1], "outside", length) == 0)) {
523                  slavePtr->borderMode = BM_OUTSIDE;                  slavePtr->borderMode = BM_OUTSIDE;
524              } else {              } else {
525                  Tcl_AppendResult(interp, "bad border mode \"", argv[1],                  Tcl_AppendResult(interp, "bad border mode \"", argv[1],
526                          "\": must be ignore, inside, or outside",                          "\": must be ignore, inside, or outside",
527                          (char *) NULL);                          (char *) NULL);
528                  result = TCL_ERROR;                  result = TCL_ERROR;
529                  goto done;                  goto done;
530              }              }
531          } else if ((c == 'h') && (strncmp(argv[0], "-height", length) == 0)) {          } else if ((c == 'h') && (strncmp(argv[0], "-height", length) == 0)) {
532              if (argv[1][0] == 0) {              if (argv[1][0] == 0) {
533                  slavePtr->flags &= ~CHILD_HEIGHT;                  slavePtr->flags &= ~CHILD_HEIGHT;
534              } else {              } else {
535                  if (Tk_GetPixels(interp, slavePtr->tkwin, argv[1],                  if (Tk_GetPixels(interp, slavePtr->tkwin, argv[1],
536                          &slavePtr->height) != TCL_OK) {                          &slavePtr->height) != TCL_OK) {
537                      result = TCL_ERROR;                      result = TCL_ERROR;
538                      goto done;                      goto done;
539                  }                  }
540                  slavePtr->flags |= CHILD_HEIGHT;                  slavePtr->flags |= CHILD_HEIGHT;
541              }              }
542          } else if ((c == 'i') && (strncmp(argv[0], "-in", length) == 0)) {          } else if ((c == 'i') && (strncmp(argv[0], "-in", length) == 0)) {
543              Tk_Window tkwin;              Tk_Window tkwin;
544              Tk_Window ancestor;              Tk_Window ancestor;
545    
546              tkwin = Tk_NameToWindow(interp, argv[1], slavePtr->tkwin);              tkwin = Tk_NameToWindow(interp, argv[1], slavePtr->tkwin);
547              if (tkwin == NULL) {              if (tkwin == NULL) {
548                  result = TCL_ERROR;                  result = TCL_ERROR;
549                  goto done;                  goto done;
550              }              }
551    
552              /*              /*
553               * Make sure that the new master is either the logical parent               * Make sure that the new master is either the logical parent
554               * of the slave or a descendant of that window, and that the               * of the slave or a descendant of that window, and that the
555               * master and slave aren't the same.               * master and slave aren't the same.
556               */               */
557    
558              for (ancestor = tkwin; ; ancestor = Tk_Parent(ancestor)) {              for (ancestor = tkwin; ; ancestor = Tk_Parent(ancestor)) {
559                  if (ancestor == Tk_Parent(slavePtr->tkwin)) {                  if (ancestor == Tk_Parent(slavePtr->tkwin)) {
560                      break;                      break;
561                  }                  }
562                  if (Tk_IsTopLevel(ancestor)) {                  if (Tk_IsTopLevel(ancestor)) {
563                      Tcl_AppendResult(interp, "can't place ",                      Tcl_AppendResult(interp, "can't place ",
564                              Tk_PathName(slavePtr->tkwin), " relative to ",                              Tk_PathName(slavePtr->tkwin), " relative to ",
565                              Tk_PathName(tkwin), (char *) NULL);                              Tk_PathName(tkwin), (char *) NULL);
566                      result = TCL_ERROR;                      result = TCL_ERROR;
567                      goto done;                      goto done;
568                  }                  }
569              }              }
570              if (slavePtr->tkwin == tkwin) {              if (slavePtr->tkwin == tkwin) {
571                  Tcl_AppendResult(interp, "can't place ",                  Tcl_AppendResult(interp, "can't place ",
572                          Tk_PathName(slavePtr->tkwin), " relative to itself",                          Tk_PathName(slavePtr->tkwin), " relative to itself",
573                          (char *) NULL);                          (char *) NULL);
574                  result = TCL_ERROR;                  result = TCL_ERROR;
575                  goto done;                  goto done;
576              }              }
577              if ((slavePtr->masterPtr != NULL)              if ((slavePtr->masterPtr != NULL)
578                      && (slavePtr->masterPtr->tkwin == tkwin)) {                      && (slavePtr->masterPtr->tkwin == tkwin)) {
579                  /*                  /*
580                   * Re-using same old master.  Nothing to do.                   * Re-using same old master.  Nothing to do.
581                   */                   */
582              } else {              } else {
583                  if ((slavePtr->masterPtr != NULL)                  if ((slavePtr->masterPtr != NULL)
584                          && (slavePtr->masterPtr->tkwin                          && (slavePtr->masterPtr->tkwin
585                          != Tk_Parent(slavePtr->tkwin))) {                          != Tk_Parent(slavePtr->tkwin))) {
586                      Tk_UnmaintainGeometry(slavePtr->tkwin,                      Tk_UnmaintainGeometry(slavePtr->tkwin,
587                              slavePtr->masterPtr->tkwin);                              slavePtr->masterPtr->tkwin);
588                  }                  }
589                  UnlinkSlave(slavePtr);                  UnlinkSlave(slavePtr);
590                  slavePtr->masterPtr = FindMaster(tkwin);                  slavePtr->masterPtr = FindMaster(tkwin);
591                  slavePtr->nextPtr = slavePtr->masterPtr->slavePtr;                  slavePtr->nextPtr = slavePtr->masterPtr->slavePtr;
592                  slavePtr->masterPtr->slavePtr = slavePtr;                  slavePtr->masterPtr->slavePtr = slavePtr;
593              }              }
594          } else if ((c == 'r') && (strncmp(argv[0], "-relheight", length) == 0)          } else if ((c == 'r') && (strncmp(argv[0], "-relheight", length) == 0)
595                  && (length >= 5)) {                  && (length >= 5)) {
596              if (argv[1][0] == 0) {              if (argv[1][0] == 0) {
597                  slavePtr->flags &= ~CHILD_REL_HEIGHT;                  slavePtr->flags &= ~CHILD_REL_HEIGHT;
598              } else {              } else {
599                  if (Tcl_GetDouble(interp, argv[1], &d) != TCL_OK) {                  if (Tcl_GetDouble(interp, argv[1], &d) != TCL_OK) {
600                      result = TCL_ERROR;                      result = TCL_ERROR;
601                      goto done;                      goto done;
602                  }                  }
603                  slavePtr->relHeight = (float) d;                  slavePtr->relHeight = (float) d;
604                  slavePtr->flags |= CHILD_REL_HEIGHT;                  slavePtr->flags |= CHILD_REL_HEIGHT;
605              }              }
606          } else if ((c == 'r') && (strncmp(argv[0], "-relwidth", length) == 0)          } else if ((c == 'r') && (strncmp(argv[0], "-relwidth", length) == 0)
607                  && (length >= 5)) {                  && (length >= 5)) {
608              if (argv[1][0] == 0) {              if (argv[1][0] == 0) {
609                  slavePtr->flags &= ~CHILD_REL_WIDTH;                  slavePtr->flags &= ~CHILD_REL_WIDTH;
610              } else {              } else {
611                  if (Tcl_GetDouble(interp, argv[1], &d) != TCL_OK) {                  if (Tcl_GetDouble(interp, argv[1], &d) != TCL_OK) {
612                      result = TCL_ERROR;                      result = TCL_ERROR;
613                      goto done;                      goto done;
614                  }                  }
615                  slavePtr->relWidth = (float) d;                  slavePtr->relWidth = (float) d;
616                  slavePtr->flags |= CHILD_REL_WIDTH;                  slavePtr->flags |= CHILD_REL_WIDTH;
617              }              }
618          } else if ((c == 'r') && (strncmp(argv[0], "-relx", length) == 0)          } else if ((c == 'r') && (strncmp(argv[0], "-relx", length) == 0)
619                  && (length >= 5)) {                  && (length >= 5)) {
620              if (Tcl_GetDouble(interp, argv[1], &d) != TCL_OK) {              if (Tcl_GetDouble(interp, argv[1], &d) != TCL_OK) {
621                  result = TCL_ERROR;                  result = TCL_ERROR;
622                  goto done;                  goto done;
623              }              }
624              slavePtr->relX = (float) d;              slavePtr->relX = (float) d;
625          } else if ((c == 'r') && (strncmp(argv[0], "-rely", length) == 0)          } else if ((c == 'r') && (strncmp(argv[0], "-rely", length) == 0)
626                  && (length >= 5)) {                  && (length >= 5)) {
627              if (Tcl_GetDouble(interp, argv[1], &d) != TCL_OK) {              if (Tcl_GetDouble(interp, argv[1], &d) != TCL_OK) {
628                  result = TCL_ERROR;                  result = TCL_ERROR;
629                  goto done;                  goto done;
630              }              }
631              slavePtr->relY = (float) d;              slavePtr->relY = (float) d;
632          } else if ((c == 'w') && (strncmp(argv[0], "-width", length) == 0)) {          } else if ((c == 'w') && (strncmp(argv[0], "-width", length) == 0)) {
633              if (argv[1][0] == 0) {              if (argv[1][0] == 0) {
634                  slavePtr->flags &= ~CHILD_WIDTH;                  slavePtr->flags &= ~CHILD_WIDTH;
635              } else {              } else {
636                  if (Tk_GetPixels(interp, slavePtr->tkwin, argv[1],                  if (Tk_GetPixels(interp, slavePtr->tkwin, argv[1],
637                          &slavePtr->width) != TCL_OK) {                          &slavePtr->width) != TCL_OK) {
638                      result = TCL_ERROR;                      result = TCL_ERROR;
639                      goto done;                      goto done;
640                  }                  }
641                  slavePtr->flags |= CHILD_WIDTH;                  slavePtr->flags |= CHILD_WIDTH;
642              }              }
643          } else if ((c == 'x') && (strncmp(argv[0], "-x", length) == 0)) {          } else if ((c == 'x') && (strncmp(argv[0], "-x", length) == 0)) {
644              if (Tk_GetPixels(interp, slavePtr->tkwin, argv[1],              if (Tk_GetPixels(interp, slavePtr->tkwin, argv[1],
645                      &slavePtr->x) != TCL_OK) {                      &slavePtr->x) != TCL_OK) {
646                  result = TCL_ERROR;                  result = TCL_ERROR;
647                  goto done;                  goto done;
648              }              }
649          } else if ((c == 'y') && (strncmp(argv[0], "-y", length) == 0)) {          } else if ((c == 'y') && (strncmp(argv[0], "-y", length) == 0)) {
650              if (Tk_GetPixels(interp, slavePtr->tkwin, argv[1],              if (Tk_GetPixels(interp, slavePtr->tkwin, argv[1],
651                      &slavePtr->y) != TCL_OK) {                      &slavePtr->y) != TCL_OK) {
652                  result = TCL_ERROR;                  result = TCL_ERROR;
653                  goto done;                  goto done;
654              }              }
655          } else {          } else {
656              Tcl_AppendResult(interp, "unknown or ambiguous option \"",              Tcl_AppendResult(interp, "unknown or ambiguous option \"",
657                      argv[0], "\": must be -anchor, -bordermode, -height, ",                      argv[0], "\": must be -anchor, -bordermode, -height, ",
658                      "-in, -relheight, -relwidth, -relx, -rely, -width, ",                      "-in, -relheight, -relwidth, -relx, -rely, -width, ",
659                      "-x, or -y", (char *) NULL);                      "-x, or -y", (char *) NULL);
660              result = TCL_ERROR;              result = TCL_ERROR;
661              goto done;              goto done;
662          }          }
663      }      }
664    
665      /*      /*
666       * If there's no master specified for this slave, use its Tk_Parent.       * If there's no master specified for this slave, use its Tk_Parent.
667       * Then arrange for a placement recalculation in the master.       * Then arrange for a placement recalculation in the master.
668       */       */
669    
670      done:      done:
671      masterPtr = slavePtr->masterPtr;      masterPtr = slavePtr->masterPtr;
672      if (masterPtr == NULL) {      if (masterPtr == NULL) {
673          masterPtr = FindMaster(Tk_Parent(slavePtr->tkwin));          masterPtr = FindMaster(Tk_Parent(slavePtr->tkwin));
674          slavePtr->masterPtr = masterPtr;          slavePtr->masterPtr = masterPtr;
675          slavePtr->nextPtr = masterPtr->slavePtr;          slavePtr->nextPtr = masterPtr->slavePtr;
676          masterPtr->slavePtr = slavePtr;          masterPtr->slavePtr = slavePtr;
677      }      }
678      if (!(masterPtr->flags & PARENT_RECONFIG_PENDING)) {      if (!(masterPtr->flags & PARENT_RECONFIG_PENDING)) {
679          masterPtr->flags |= PARENT_RECONFIG_PENDING;          masterPtr->flags |= PARENT_RECONFIG_PENDING;
680          Tcl_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr);          Tcl_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr);
681      }      }
682      return result;      return result;
683  }  }
684    
685  /*  /*
686   *----------------------------------------------------------------------   *----------------------------------------------------------------------
687   *   *
688   * RecomputePlacement --   * RecomputePlacement --
689   *   *
690   *      This procedure is called as a when-idle handler.  It recomputes   *      This procedure is called as a when-idle handler.  It recomputes
691   *      the geometries of all the slaves of a given master.   *      the geometries of all the slaves of a given master.
692   *   *
693   * Results:   * Results:
694   *      None.   *      None.
695   *   *
696   * Side effects:   * Side effects:
697   *      Windows may change size or shape.   *      Windows may change size or shape.
698   *   *
699   *----------------------------------------------------------------------   *----------------------------------------------------------------------
700   */   */
701    
702  static void  static void
703  RecomputePlacement(clientData)  RecomputePlacement(clientData)
704      ClientData clientData;      /* Pointer to Master record. */      ClientData clientData;      /* Pointer to Master record. */
705  {  {
706      register Master *masterPtr = (Master *) clientData;      register Master *masterPtr = (Master *) clientData;
707      register Slave *slavePtr;      register Slave *slavePtr;
708      int x, y, width, height, tmp;      int x, y, width, height, tmp;
709      int masterWidth, masterHeight, masterBW;      int masterWidth, masterHeight, masterBW;
710      double x1, y1, x2, y2;      double x1, y1, x2, y2;
711    
712      masterPtr->flags &= ~PARENT_RECONFIG_PENDING;      masterPtr->flags &= ~PARENT_RECONFIG_PENDING;
713    
714      /*      /*
715       * Iterate over all the slaves for the master.  Each slave's       * Iterate over all the slaves for the master.  Each slave's
716       * geometry can be computed independently of the other slaves.       * geometry can be computed independently of the other slaves.
717       */       */
718    
719      for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;      for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
720              slavePtr = slavePtr->nextPtr) {              slavePtr = slavePtr->nextPtr) {
721          /*          /*
722           * Step 1: compute size and borderwidth of master, taking into           * Step 1: compute size and borderwidth of master, taking into
723           * account desired border mode.           * account desired border mode.
724           */           */
725    
726          masterBW = 0;          masterBW = 0;
727          masterWidth = Tk_Width(masterPtr->tkwin);          masterWidth = Tk_Width(masterPtr->tkwin);
728          masterHeight = Tk_Height(masterPtr->tkwin);          masterHeight = Tk_Height(masterPtr->tkwin);
729          if (slavePtr->borderMode == BM_INSIDE) {          if (slavePtr->borderMode == BM_INSIDE) {
730              masterBW = Tk_InternalBorderWidth(masterPtr->tkwin);              masterBW = Tk_InternalBorderWidth(masterPtr->tkwin);
731          } else if (slavePtr->borderMode == BM_OUTSIDE) {          } else if (slavePtr->borderMode == BM_OUTSIDE) {
732              masterBW = -Tk_Changes(masterPtr->tkwin)->border_width;              masterBW = -Tk_Changes(masterPtr->tkwin)->border_width;
733          }          }
734          masterWidth -= 2*masterBW;          masterWidth -= 2*masterBW;
735          masterHeight -= 2*masterBW;          masterHeight -= 2*masterBW;
736    
737          /*          /*
738           * Step 2:  compute size of slave (outside dimensions including           * Step 2:  compute size of slave (outside dimensions including
739           * border) and location of anchor point within master.           * border) and location of anchor point within master.
740           */           */
741    
742          x1 = slavePtr->x + masterBW + (slavePtr->relX*masterWidth);          x1 = slavePtr->x + masterBW + (slavePtr->relX*masterWidth);
743          x = (int) (x1 + ((x1 > 0) ? 0.5 : -0.5));          x = (int) (x1 + ((x1 > 0) ? 0.5 : -0.5));
744          y1 = slavePtr->y + masterBW + (slavePtr->relY*masterHeight);          y1 = slavePtr->y + masterBW + (slavePtr->relY*masterHeight);
745          y = (int) (y1 + ((y1 > 0) ? 0.5 : -0.5));          y = (int) (y1 + ((y1 > 0) ? 0.5 : -0.5));
746          if (slavePtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH)) {          if (slavePtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH)) {
747              width = 0;              width = 0;
748              if (slavePtr->flags & CHILD_WIDTH) {              if (slavePtr->flags & CHILD_WIDTH) {
749                  width += slavePtr->width;                  width += slavePtr->width;
750              }              }
751              if (slavePtr->flags & CHILD_REL_WIDTH) {              if (slavePtr->flags & CHILD_REL_WIDTH) {
752                  /*                  /*
753                   * The code below is a bit tricky.  In order to round                   * The code below is a bit tricky.  In order to round
754                   * correctly when both relX and relWidth are specified,                   * correctly when both relX and relWidth are specified,
755                   * compute the location of the right edge and round that,                   * compute the location of the right edge and round that,
756                   * then compute width.  If we compute the width and round                   * then compute width.  If we compute the width and round
757                   * it, rounding errors in relX and relWidth accumulate.                   * it, rounding errors in relX and relWidth accumulate.
758                   */                   */
759    
760                  x2 = x1 + (slavePtr->relWidth*masterWidth);                  x2 = x1 + (slavePtr->relWidth*masterWidth);
761                  tmp = (int) (x2 + ((x2 > 0) ? 0.5 : -0.5));                  tmp = (int) (x2 + ((x2 > 0) ? 0.5 : -0.5));
762                  width += tmp - x;                  width += tmp - x;
763              }              }
764          } else {          } else {
765              width = Tk_ReqWidth(slavePtr->tkwin)              width = Tk_ReqWidth(slavePtr->tkwin)
766                      + 2*Tk_Changes(slavePtr->tkwin)->border_width;                      + 2*Tk_Changes(slavePtr->tkwin)->border_width;
767          }          }
768          if (slavePtr->flags & (CHILD_HEIGHT|CHILD_REL_HEIGHT)) {          if (slavePtr->flags & (CHILD_HEIGHT|CHILD_REL_HEIGHT)) {
769              height = 0;              height = 0;
770              if (slavePtr->flags & CHILD_HEIGHT) {              if (slavePtr->flags & CHILD_HEIGHT) {
771                  height += slavePtr->height;                  height += slavePtr->height;
772              }              }
773              if (slavePtr->flags & CHILD_REL_HEIGHT) {              if (slavePtr->flags & CHILD_REL_HEIGHT) {
774                  /*                  /*
775                   * See note above for rounding errors in width computation.                   * See note above for rounding errors in width computation.
776                   */                   */
777    
778                  y2 = y1 + (slavePtr->relHeight*masterHeight);                  y2 = y1 + (slavePtr->relHeight*masterHeight);
779                  tmp = (int) (y2 + ((y2 > 0) ? 0.5 : -0.5));                  tmp = (int) (y2 + ((y2 > 0) ? 0.5 : -0.5));
780                  height += tmp - y;                  height += tmp - y;
781              }              }
782          } else {          } else {
783              height = Tk_ReqHeight(slavePtr->tkwin)              height = Tk_ReqHeight(slavePtr->tkwin)
784                      + 2*Tk_Changes(slavePtr->tkwin)->border_width;                      + 2*Tk_Changes(slavePtr->tkwin)->border_width;
785          }          }
786    
787          /*          /*
788           * Step 3: adjust the x and y positions so that the desired           * Step 3: adjust the x and y positions so that the desired
789           * anchor point on the slave appears at that position.  Also           * anchor point on the slave appears at that position.  Also
790           * adjust for the border mode and master's border.           * adjust for the border mode and master's border.
791           */           */
792    
793          switch (slavePtr->anchor) {          switch (slavePtr->anchor) {
794              case TK_ANCHOR_N:              case TK_ANCHOR_N:
795                  x -= width/2;                  x -= width/2;
796                  break;                  break;
797              case TK_ANCHOR_NE:              case TK_ANCHOR_NE:
798                  x -= width;                  x -= width;
799                  break;                  break;
800              case TK_ANCHOR_E:              case TK_ANCHOR_E:
801                  x -= width;                  x -= width;
802                  y -= height/2;                  y -= height/2;
803                  break;                  break;
804              case TK_ANCHOR_SE:              case TK_ANCHOR_SE:
805                  x -= width;                  x -= width;
806                  y -= height;                  y -= height;
807                  break;                  break;
808              case TK_ANCHOR_S:              case TK_ANCHOR_S:
809                  x -= width/2;                  x -= width/2;
810                  y -= height;                  y -= height;
811                  break;                  break;
812              case TK_ANCHOR_SW:              case TK_ANCHOR_SW:
813                  y -= height;                  y -= height;
814                  break;                  break;
815              case TK_ANCHOR_W:              case TK_ANCHOR_W:
816                  y -= height/2;                  y -= height/2;
817                  break;                  break;
818              case TK_ANCHOR_NW:              case TK_ANCHOR_NW:
819                  break;                  break;
820              case TK_ANCHOR_CENTER:              case TK_ANCHOR_CENTER:
821                  x -= width/2;                  x -= width/2;
822                  y -= height/2;                  y -= height/2;
823                  break;                  break;
824          }          }
825    
826          /*          /*
827           * Step 4: adjust width and height again to reflect inside dimensions           * Step 4: adjust width and height again to reflect inside dimensions
828           * of window rather than outside.  Also make sure that the width and           * of window rather than outside.  Also make sure that the width and
829           * height aren't zero.           * height aren't zero.
830           */           */
831    
832          width -= 2*Tk_Changes(slavePtr->tkwin)->border_width;          width -= 2*Tk_Changes(slavePtr->tkwin)->border_width;
833          height -= 2*Tk_Changes(slavePtr->tkwin)->border_width;          height -= 2*Tk_Changes(slavePtr->tkwin)->border_width;
834          if (width <= 0) {          if (width <= 0) {
835              width = 1;              width = 1;
836          }          }
837          if (height <= 0) {          if (height <= 0) {
838              height = 1;              height = 1;
839          }          }
840    
841          /*          /*
842           * Step 5: reconfigure the window and map it if needed.  If the           * Step 5: reconfigure the window and map it if needed.  If the
843           * slave is a child of the master, we do this ourselves.  If the           * slave is a child of the master, we do this ourselves.  If the
844           * slave isn't a child of the master, let Tk_MaintainGeometry do           * slave isn't a child of the master, let Tk_MaintainGeometry do
845           * the work (it will re-adjust things as relevant windows map,           * the work (it will re-adjust things as relevant windows map,
846           * unmap, and move).           * unmap, and move).
847           */           */
848    
849          if (masterPtr->tkwin == Tk_Parent(slavePtr->tkwin)) {          if (masterPtr->tkwin == Tk_Parent(slavePtr->tkwin)) {
850              if ((x != Tk_X(slavePtr->tkwin))              if ((x != Tk_X(slavePtr->tkwin))
851                      || (y != Tk_Y(slavePtr->tkwin))                      || (y != Tk_Y(slavePtr->tkwin))
852                      || (width != Tk_Width(slavePtr->tkwin))                      || (width != Tk_Width(slavePtr->tkwin))
853                      || (height != Tk_Height(slavePtr->tkwin))) {                      || (height != Tk_Height(slavePtr->tkwin))) {
854                  Tk_MoveResizeWindow(slavePtr->tkwin, x, y, width, height);                  Tk_MoveResizeWindow(slavePtr->tkwin, x, y, width, height);
855              }              }
856    
857              /*              /*
858               * Don't map the slave unless the master is mapped: the slave               * Don't map the slave unless the master is mapped: the slave
859               * will get mapped later, when the master is mapped.               * will get mapped later, when the master is mapped.
860               */               */
861    
862              if (Tk_IsMapped(masterPtr->tkwin)) {              if (Tk_IsMapped(masterPtr->tkwin)) {
863                  Tk_MapWindow(slavePtr->tkwin);                  Tk_MapWindow(slavePtr->tkwin);
864              }              }
865          } else {          } else {
866              if ((width <= 0) || (height <= 0)) {              if ((width <= 0) || (height <= 0)) {
867                  Tk_UnmaintainGeometry(slavePtr->tkwin, masterPtr->tkwin);                  Tk_UnmaintainGeometry(slavePtr->tkwin, masterPtr->tkwin);
868                  Tk_UnmapWindow(slavePtr->tkwin);                  Tk_UnmapWindow(slavePtr->tkwin);
869              } else {              } else {
870                  Tk_MaintainGeometry(slavePtr->tkwin, masterPtr->tkwin,                  Tk_MaintainGeometry(slavePtr->tkwin, masterPtr->tkwin,
871                          x, y, width, height);                          x, y, width, height);
872              }              }
873          }          }
874      }      }
875  }  }
876    
877  /*  /*
878   *----------------------------------------------------------------------   *----------------------------------------------------------------------
879   *   *
880   * MasterStructureProc --   * MasterStructureProc --
881   *   *
882   *      This procedure is invoked by the Tk event handler when   *      This procedure is invoked by the Tk event handler when
883   *      StructureNotify events occur for a master window.   *      StructureNotify events occur for a master window.
884   *   *
885   * Results:   * Results:
886   *      None.   *      None.
887   *   *
888   * Side effects:   * Side effects:
889   *      Structures get cleaned up if the window was deleted.  If the   *      Structures get cleaned up if the window was deleted.  If the
890   *      window was resized then slave geometries get recomputed.   *      window was resized then slave geometries get recomputed.
891   *   *
892   *----------------------------------------------------------------------   *----------------------------------------------------------------------
893   */   */
894    
895  static void  static void
896  MasterStructureProc(clientData, eventPtr)  MasterStructureProc(clientData, eventPtr)
897      ClientData clientData;      /* Pointer to Master structure for window      ClientData clientData;      /* Pointer to Master structure for window
898                                   * referred to by eventPtr. */                                   * referred to by eventPtr. */
899      XEvent *eventPtr;           /* Describes what just happened. */      XEvent *eventPtr;           /* Describes what just happened. */
900  {  {
901      register Master *masterPtr = (Master *) clientData;      register Master *masterPtr = (Master *) clientData;
902      register Slave *slavePtr, *nextPtr;      register Slave *slavePtr, *nextPtr;
903      TkDisplay *dispPtr = ((TkWindow *) masterPtr->tkwin)->dispPtr;      TkDisplay *dispPtr = ((TkWindow *) masterPtr->tkwin)->dispPtr;
904    
905      if (eventPtr->type == ConfigureNotify) {      if (eventPtr->type == ConfigureNotify) {
906          if ((masterPtr->slavePtr != NULL)          if ((masterPtr->slavePtr != NULL)
907                  && !(masterPtr->flags & PARENT_RECONFIG_PENDING)) {                  && !(masterPtr->flags & PARENT_RECONFIG_PENDING)) {
908              masterPtr->flags |= PARENT_RECONFIG_PENDING;              masterPtr->flags |= PARENT_RECONFIG_PENDING;
909              Tcl_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr);              Tcl_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr);
910          }          }
911      } else if (eventPtr->type == DestroyNotify) {      } else if (eventPtr->type == DestroyNotify) {
912          for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;          for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
913                  slavePtr = nextPtr) {                  slavePtr = nextPtr) {
914              slavePtr->masterPtr = NULL;              slavePtr->masterPtr = NULL;
915              nextPtr = slavePtr->nextPtr;              nextPtr = slavePtr->nextPtr;
916              slavePtr->nextPtr = NULL;              slavePtr->nextPtr = NULL;
917          }          }
918          Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->masterTable,          Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->masterTable,
919                  (char *) masterPtr->tkwin));                  (char *) masterPtr->tkwin));
920          if (masterPtr->flags & PARENT_RECONFIG_PENDING) {          if (masterPtr->flags & PARENT_RECONFIG_PENDING) {
921              Tcl_CancelIdleCall(RecomputePlacement, (ClientData) masterPtr);              Tcl_CancelIdleCall(RecomputePlacement, (ClientData) masterPtr);
922          }          }
923          masterPtr->tkwin = NULL;          masterPtr->tkwin = NULL;
924          ckfree((char *) masterPtr);          ckfree((char *) masterPtr);
925      } else if (eventPtr->type == MapNotify) {      } else if (eventPtr->type == MapNotify) {
926          /*          /*
927           * When a master gets mapped, must redo the geometry computation           * When a master gets mapped, must redo the geometry computation
928           * so that all of its slaves get remapped.           * so that all of its slaves get remapped.
929           */           */
930    
931          if ((masterPtr->slavePtr != NULL)          if ((masterPtr->slavePtr != NULL)
932                  && !(masterPtr->flags & PARENT_RECONFIG_PENDING)) {                  && !(masterPtr->flags & PARENT_RECONFIG_PENDING)) {
933              masterPtr->flags |= PARENT_RECONFIG_PENDING;              masterPtr->flags |= PARENT_RECONFIG_PENDING;
934              Tcl_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr);              Tcl_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr);
935          }          }
936      } else if (eventPtr->type == UnmapNotify) {      } else if (eventPtr->type == UnmapNotify) {
937          /*          /*
938           * Unmap all of the slaves when the master gets unmapped,           * Unmap all of the slaves when the master gets unmapped,
939           * so that they don't keep redisplaying themselves.           * so that they don't keep redisplaying themselves.
940           */           */
941    
942          for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;          for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
943                  slavePtr = slavePtr->nextPtr) {                  slavePtr = slavePtr->nextPtr) {
944              Tk_UnmapWindow(slavePtr->tkwin);              Tk_UnmapWindow(slavePtr->tkwin);
945          }          }
946      }      }
947  }  }
948    
949  /*  /*
950   *----------------------------------------------------------------------   *----------------------------------------------------------------------
951   *   *
952   * SlaveStructureProc --   * SlaveStructureProc --
953   *   *
954   *      This procedure is invoked by the Tk event handler when   *      This procedure is invoked by the Tk event handler when
955   *      StructureNotify events occur for a slave window.   *      StructureNotify events occur for a slave window.
956   *   *
957   * Results:   * Results:
958   *      None.   *      None.
959   *   *
960   * Side effects:   * Side effects:
961   *      Structures get cleaned up if the window was deleted.   *      Structures get cleaned up if the window was deleted.
962   *   *
963   *----------------------------------------------------------------------   *----------------------------------------------------------------------
964   */   */
965    
966  static void  static void
967  SlaveStructureProc(clientData, eventPtr)  SlaveStructureProc(clientData, eventPtr)
968      ClientData clientData;      /* Pointer to Slave structure for window      ClientData clientData;      /* Pointer to Slave structure for window
969                                   * referred to by eventPtr. */                                   * referred to by eventPtr. */
970      XEvent *eventPtr;           /* Describes what just happened. */      XEvent *eventPtr;           /* Describes what just happened. */
971  {  {
972      register Slave *slavePtr = (Slave *) clientData;      register Slave *slavePtr = (Slave *) clientData;
973      TkDisplay * dispPtr = ((TkWindow *) slavePtr->tkwin)->dispPtr;      TkDisplay * dispPtr = ((TkWindow *) slavePtr->tkwin)->dispPtr;
974    
975      if (eventPtr->type == DestroyNotify) {      if (eventPtr->type == DestroyNotify) {
976          UnlinkSlave(slavePtr);          UnlinkSlave(slavePtr);
977          Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable,          Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable,
978                  (char *) slavePtr->tkwin));                  (char *) slavePtr->tkwin));
979          ckfree((char *) slavePtr);          ckfree((char *) slavePtr);
980      }      }
981  }  }
982    
983  /*  /*
984   *----------------------------------------------------------------------   *----------------------------------------------------------------------
985   *   *
986   * PlaceRequestProc --   * PlaceRequestProc --
987   *   *
988   *      This procedure is invoked by Tk whenever a slave managed by us   *      This procedure is invoked by Tk whenever a slave managed by us
989   *      changes its requested geometry.   *      changes its requested geometry.
990   *   *
991   * Results:   * Results:
992   *      None.   *      None.
993   *   *
994   * Side effects:   * Side effects:
995   *      The window will get relayed out, if its requested size has   *      The window will get relayed out, if its requested size has
996   *      anything to do with its actual size.   *      anything to do with its actual size.
997   *   *
998   *----------------------------------------------------------------------   *----------------------------------------------------------------------
999   */   */
1000    
1001          /* ARGSUSED */          /* ARGSUSED */
1002  static void  static void
1003  PlaceRequestProc(clientData, tkwin)  PlaceRequestProc(clientData, tkwin)
1004      ClientData clientData;              /* Pointer to our record for slave. */      ClientData clientData;              /* Pointer to our record for slave. */
1005      Tk_Window tkwin;                    /* Window that changed its desired      Tk_Window tkwin;                    /* Window that changed its desired
1006                                           * size. */                                           * size. */
1007  {  {
1008      Slave *slavePtr = (Slave *) clientData;      Slave *slavePtr = (Slave *) clientData;
1009      Master *masterPtr;      Master *masterPtr;
1010    
1011      if (((slavePtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH)) != 0)      if (((slavePtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH)) != 0)
1012              && ((slavePtr->flags & (CHILD_HEIGHT|CHILD_REL_HEIGHT)) != 0)) {              && ((slavePtr->flags & (CHILD_HEIGHT|CHILD_REL_HEIGHT)) != 0)) {
1013          return;          return;
1014      }      }
1015      masterPtr = slavePtr->masterPtr;      masterPtr = slavePtr->masterPtr;
1016      if (masterPtr == NULL) {      if (masterPtr == NULL) {
1017          return;          return;
1018      }      }
1019      if (!(masterPtr->flags & PARENT_RECONFIG_PENDING)) {      if (!(masterPtr->flags & PARENT_RECONFIG_PENDING)) {
1020          masterPtr->flags |= PARENT_RECONFIG_PENDING;          masterPtr->flags |= PARENT_RECONFIG_PENDING;
1021          Tcl_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr);          Tcl_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr);
1022      }      }
1023  }  }
1024    
1025  /*  /*
1026   *--------------------------------------------------------------   *--------------------------------------------------------------
1027   *   *
1028   * PlaceLostSlaveProc --   * PlaceLostSlaveProc --
1029   *   *
1030   *      This procedure is invoked by Tk whenever some other geometry   *      This procedure is invoked by Tk whenever some other geometry
1031   *      claims control over a slave that used to be managed by us.   *      claims control over a slave that used to be managed by us.
1032   *   *
1033   * Results:   * Results:
1034   *      None.   *      None.
1035   *   *
1036   * Side effects:   * Side effects:
1037   *      Forgets all placer-related information about the slave.   *      Forgets all placer-related information about the slave.
1038   *   *
1039   *--------------------------------------------------------------   *--------------------------------------------------------------
1040   */   */
1041    
1042          /* ARGSUSED */          /* ARGSUSED */
1043  static void  static void
1044  PlaceLostSlaveProc(clientData, tkwin)  PlaceLostSlaveProc(clientData, tkwin)
1045      ClientData clientData;      /* Slave structure for slave window that      ClientData clientData;      /* Slave structure for slave window that
1046                                   * was stolen away. */                                   * was stolen away. */
1047      Tk_Window tkwin;            /* Tk's handle for the slave window. */      Tk_Window tkwin;            /* Tk's handle for the slave window. */
1048  {  {
1049      register Slave *slavePtr = (Slave *) clientData;      register Slave *slavePtr = (Slave *) clientData;
1050      TkDisplay * dispPtr = ((TkWindow *) slavePtr->tkwin)->dispPtr;      TkDisplay * dispPtr = ((TkWindow *) slavePtr->tkwin)->dispPtr;
1051    
1052      if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) {      if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) {
1053          Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin);          Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin);
1054      }      }
1055      Tk_UnmapWindow(tkwin);      Tk_UnmapWindow(tkwin);
1056      UnlinkSlave(slavePtr);      UnlinkSlave(slavePtr);
1057      Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable,      Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable,
1058              (char *) tkwin));              (char *) tkwin));
1059      Tk_DeleteEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc,      Tk_DeleteEventHandler(tkwin, StructureNotifyMask, SlaveStructureProc,
1060              (ClientData) slavePtr);              (ClientData) slavePtr);
1061      ckfree((char *) slavePtr);      ckfree((char *) slavePtr);
1062  }  }
1063    
1064  /* End of tkplace.c */  /* End of tkplace.c */

Legend:
Removed from v.69  
changed lines
  Added in v.71

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25