4 * This file contains code to implement a simple geometry manager
5 * for Ck based on absolute placement or "rubber-sheet" placement.
7 * Copyright (c) 1992-1994 The Regents of the University of California.
8 * Copyright (c) 1994-1995 Sun Microsystems, Inc.
9 * Copyright (c) 1995 Christian Werner
11 * See the file "license.terms" for information on usage and redistribution
12 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
19 * Border modes for relative placement:
21 * BM_INSIDE: relative distances computed using area inside
22 * all borders of master window.
23 * BM_IGNORE: border issues are ignored: place relative to
24 * master's actual window size.
27 typedef enum {BM_INSIDE, BM_IGNORE} BorderMode;
30 * For each window whose geometry is managed by the placer there is
31 * a structure of the following type:
34 typedef struct Slave {
35 CkWindow *winPtr; /* Pointer to window. */
36 struct Master *masterPtr; /* Pointer to information for window
37 * relative to which winPtr is placed.
38 * This isn't necessarily the logical
39 * parent of winPtr. NULL means the
40 * master was deleted or never assigned. */
41 struct Slave *nextPtr; /* Next in list of windows placed relative
42 * to same master (NULL for end of list). */
45 * Geometry information for window; where there are both relative
46 * and absolute values for the same attribute (e.g. x and relX) only
47 * one of them is actually used, depending on flags.
50 int x, y; /* X and Y coordinates for winPtr. */
51 double relX, relY; /* X and Y coordinates relative to size of
53 int width, height; /* Absolute dimensions for winPtr. */
54 double relWidth, relHeight; /* Dimensions for winPtr relative to size of
56 Ck_Anchor anchor; /* Which point on winPtr is placed at the
58 BorderMode borderMode; /* How to treat borders of master window. */
59 int flags; /* Various flags; see below for bit
64 * Flag definitions for Slave structures:
66 * CHILD_REL_X - 1 means use relX field; 0 means use x.
67 * CHILD_REL_Y - 1 means use relY field; 0 means use y;
68 * CHILD_WIDTH - 1 means use width field;
69 * CHILD_REL_WIDTH - 1 means use relWidth; if neither this nor
70 * CHILD_WIDTH is 1, use window's requested
72 * CHILD_HEIGHT - 1 means use height field;
73 * CHILD_REL_HEIGHT - 1 means use relHeight; if neither this nor
74 * CHILD_HEIGHT is 1, use window's requested
81 #define CHILD_REL_WIDTH 8
82 #define CHILD_HEIGHT 0x10
83 #define CHILD_REL_HEIGHT 0x20
86 * For each master window that has a slave managed by the placer there
87 * is a structure of the following form:
90 typedef struct Master {
91 CkWindow *winPtr; /* Pointer to master window. */
92 struct Slave *slavePtr; /* First in linked list of slaves
93 * placed relative to this master. */
94 int flags; /* See below for bit definitions. */
98 * Flag definitions for masters:
100 * PARENT_RECONFIG_PENDING - 1 means that a call to RecomputePlacement
101 * is already pending via a Do_When_Idle handler.
104 #define PARENT_RECONFIG_PENDING 1
107 * The hash tables below both use CkWindow pointers as keys. They map
108 * from CkWindows to Slave and Master structures for windows, if they
112 static int initialized = 0;
113 static Tcl_HashTable masterTable;
114 static Tcl_HashTable slaveTable;
117 * The following structure is the official type record for the
121 static void PlaceRequestProc _ANSI_ARGS_((ClientData clientData,
123 static void PlaceLostSlaveProc _ANSI_ARGS_((ClientData clientData,
126 static Ck_GeomMgr placerType = {
128 PlaceRequestProc, /* requestProc */
129 PlaceLostSlaveProc, /* lostSlaveProc */
133 * Forward declarations for procedures defined later in this file:
136 static void SlaveStructureProc _ANSI_ARGS_((ClientData clientData,
138 static int ConfigureSlave _ANSI_ARGS_((Tcl_Interp *interp,
139 Slave *slavePtr, int argc, char **argv));
140 static Slave * FindSlave _ANSI_ARGS_((CkWindow *winPtr));
141 static Master * FindMaster _ANSI_ARGS_((CkWindow *winPtr));
142 static void MasterStructureProc _ANSI_ARGS_((ClientData clientData,
144 static void RecomputePlacement _ANSI_ARGS_((ClientData clientData));
145 static void UnlinkSlave _ANSI_ARGS_((Slave *slavePtr));
148 *--------------------------------------------------------------
152 * This procedure is invoked to process the "place" Tcl
153 * commands. See the user documentation for details on
157 * A standard Tcl result.
160 * See the user documentation.
162 *--------------------------------------------------------------
166 Ck_PlaceCmd(clientData, interp, argc, argv)
167 ClientData clientData; /* Main window associated with interpreter. */
168 Tcl_Interp *interp; /* Current interpreter. */
169 int argc; /* Number of arguments. */
170 char **argv; /* Argument strings. */
179 * Initialize, if that hasn't been done yet.
183 Tcl_InitHashTable(&masterTable, TCL_ONE_WORD_KEYS);
184 Tcl_InitHashTable(&slaveTable, TCL_ONE_WORD_KEYS);
189 Tcl_AppendResult(interp, "wrong # args: should be \"",
190 argv[0], " option|pathName args", (char *) NULL);
194 length = strlen(argv[1]);
197 * Handle special shortcut where window name is first argument.
201 winPtr = Ck_NameToWindow(interp, argv[1], (CkWindow *) clientData);
202 if (winPtr == NULL) {
205 slavePtr = FindSlave(winPtr);
206 return ConfigureSlave(interp, slavePtr, argc-2, argv+2);
210 * Handle more general case of option followed by window name followed
211 * by possible additional arguments.
214 winPtr = Ck_NameToWindow(interp, argv[2], (CkWindow *) clientData);
215 if (winPtr == NULL) {
218 if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0)) {
220 Tcl_AppendResult(interp, "wrong # args: should be \"",
222 " configure pathName option value ?option value ...?\"",
226 slavePtr = FindSlave(winPtr);
227 return ConfigureSlave(interp, slavePtr, argc-3, argv+3);
228 } else if ((c == 'f') && (strncmp(argv[1], "forget", length) == 0)) {
230 Tcl_AppendResult(interp, "wrong # args: should be \"",
231 argv[0], " forget pathName\"", (char *) NULL);
234 hPtr = Tcl_FindHashEntry(&slaveTable, (char *) winPtr);
238 slavePtr = (Slave *) Tcl_GetHashValue(hPtr);
239 UnlinkSlave(slavePtr);
240 Tcl_DeleteHashEntry(hPtr);
241 Ck_DeleteEventHandler(winPtr, CK_EV_MAP | CK_EV_EXPOSE | CK_EV_DESTROY,
242 SlaveStructureProc, (ClientData) slavePtr);
243 Ck_ManageGeometry(winPtr, (Ck_GeomMgr *) NULL, (ClientData) NULL);
244 Ck_UnmapWindow(winPtr);
245 ckfree((char *) slavePtr);
246 } else if ((c == 'i') && (strncmp(argv[1], "info", length) == 0)) {
250 Tcl_AppendResult(interp, "wrong # args: should be \"",
251 argv[0], " info pathName\"", (char *) NULL);
254 hPtr = Tcl_FindHashEntry(&slaveTable, (char *) winPtr);
258 slavePtr = (Slave *) Tcl_GetHashValue(hPtr);
259 if (slavePtr->flags & CHILD_REL_X) {
260 sprintf(buffer, "-relx %.4g", slavePtr->relX);
262 sprintf(buffer, "-x %d", slavePtr->x);
264 Tcl_AppendResult(interp, buffer, (char *) NULL);
265 if (slavePtr->flags & CHILD_REL_Y) {
266 sprintf(buffer, " -rely %.4g", slavePtr->relY);
268 sprintf(buffer, " -y %d", slavePtr->y);
270 Tcl_AppendResult(interp, buffer, (char *) NULL);
271 if (slavePtr->flags & CHILD_REL_WIDTH) {
272 sprintf(buffer, " -relwidth %.4g", slavePtr->relWidth);
273 Tcl_AppendResult(interp, buffer, (char *) NULL);
274 } else if (slavePtr->flags & CHILD_WIDTH) {
275 sprintf(buffer, " -width %d", slavePtr->width);
276 Tcl_AppendResult(interp, buffer, (char *) NULL);
278 if (slavePtr->flags & CHILD_REL_HEIGHT) {
279 sprintf(buffer, " -relheight %.4g", slavePtr->relHeight);
280 Tcl_AppendResult(interp, buffer, (char *) NULL);
281 } else if (slavePtr->flags & CHILD_HEIGHT) {
282 sprintf(buffer, " -height %d", slavePtr->height);
283 Tcl_AppendResult(interp, buffer, (char *) NULL);
285 Tcl_AppendResult(interp, " -anchor ", Ck_NameOfAnchor(slavePtr->anchor),
287 if (slavePtr->borderMode == BM_IGNORE) {
288 Tcl_AppendResult(interp, " -bordermode ignore", (char *) NULL);
290 } else if ((c == 's') && (strncmp(argv[1], "slaves", length) == 0)) {
292 Tcl_AppendResult(interp, "wrong # args: should be \"",
293 argv[0], " slaves pathName\"", (char *) NULL);
296 hPtr = Tcl_FindHashEntry(&masterTable, (char *) winPtr);
299 masterPtr = (Master *) Tcl_GetHashValue(hPtr);
300 for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
301 slavePtr = slavePtr->nextPtr) {
302 Tcl_AppendElement(interp, slavePtr->winPtr->pathName);
306 Tcl_AppendResult(interp, "unknown or ambiguous option \"", argv[1],
307 "\": must be configure, forget, info, or slaves",
315 *----------------------------------------------------------------------
319 * Given a CkWindow *, find the Slave structure corresponding
320 * to that window (making a new one if necessary).
326 * A new Slave structure may be created.
328 *----------------------------------------------------------------------
333 CkWindow *winPtr; /* Pointer to desired slave. */
339 hPtr = Tcl_CreateHashEntry(&slaveTable, (char *) winPtr, &new);
341 slavePtr = (Slave *) ckalloc(sizeof (Slave));
342 slavePtr->winPtr = winPtr;
343 slavePtr->masterPtr = NULL;
344 slavePtr->nextPtr = NULL;
345 slavePtr->x = slavePtr->y = 0;
346 slavePtr->relX = slavePtr->relY = 0.0;
347 slavePtr->width = slavePtr->height = 0;
348 slavePtr->relWidth = slavePtr->relHeight = 0.0;
349 slavePtr->anchor = CK_ANCHOR_NW;
350 slavePtr->borderMode = BM_INSIDE;
352 Tcl_SetHashValue(hPtr, slavePtr);
353 Ck_CreateEventHandler(winPtr, CK_EV_MAP | CK_EV_EXPOSE | CK_EV_DESTROY,
354 SlaveStructureProc, (ClientData) slavePtr);
355 Ck_ManageGeometry(winPtr, &placerType, (ClientData) slavePtr);
357 slavePtr = (Slave *) Tcl_GetHashValue(hPtr);
363 *----------------------------------------------------------------------
367 * This procedure removes a slave window from the chain of slaves
374 * The slave list of slavePtr's master changes.
376 *----------------------------------------------------------------------
380 UnlinkSlave(slavePtr)
381 Slave *slavePtr; /* Slave structure to be unlinked. */
383 register Master *masterPtr;
384 register Slave *prevPtr;
386 masterPtr = slavePtr->masterPtr;
387 if (masterPtr == NULL) {
390 if (masterPtr->slavePtr == slavePtr) {
391 masterPtr->slavePtr = slavePtr->nextPtr;
393 for (prevPtr = masterPtr->slavePtr; ;
394 prevPtr = prevPtr->nextPtr) {
395 if (prevPtr == NULL) {
396 panic("UnlinkSlave couldn't find slave to unlink");
398 if (prevPtr->nextPtr == slavePtr) {
399 prevPtr->nextPtr = slavePtr->nextPtr;
404 slavePtr->masterPtr = NULL;
408 *----------------------------------------------------------------------
412 * Given a CkWindow *, find the Master structure corresponding
413 * to that window (making a new one if necessary).
419 * A new Master structure may be created.
421 *----------------------------------------------------------------------
426 CkWindow *winPtr; /* Pointer to desired master. */
432 hPtr = Tcl_CreateHashEntry(&masterTable, (char *) winPtr, &new);
434 masterPtr = (Master *) ckalloc(sizeof (Master));
435 masterPtr->winPtr = winPtr;
436 masterPtr->slavePtr = NULL;
437 masterPtr->flags = 0;
438 Tcl_SetHashValue(hPtr, masterPtr);
440 * Special case: for toplevels winPtr is NULL,
441 * therefore don't create event handler.
444 Ck_CreateEventHandler(masterPtr->winPtr,
445 CK_EV_MAP | CK_EV_EXPOSE | CK_EV_DESTROY,
446 MasterStructureProc, (ClientData) masterPtr);
448 masterPtr = (Master *) Tcl_GetHashValue(hPtr);
454 *----------------------------------------------------------------------
458 * This procedure is called to process an argv/argc list to
459 * reconfigure the placement of a window.
462 * A standard Tcl result. If an error occurs then a message is
463 * left in interp->result.
466 * Information in slavePtr may change, and slavePtr's master is
467 * scheduled for reconfiguration.
469 *----------------------------------------------------------------------
473 ConfigureSlave(interp, slavePtr, argc, argv)
474 Tcl_Interp *interp; /* Used for error reporting. */
475 Slave *slavePtr; /* Pointer to current information
477 int argc; /* Number of config arguments. */
478 char **argv; /* String values for arguments. */
481 int c, length, result;
485 for ( ; argc > 0; argc -= 2, argv += 2) {
487 Tcl_AppendResult(interp, "extra option \"", argv[0],
488 "\" (option with no value?)", (char *) NULL);
492 length = strlen(argv[0]);
494 if ((c == 'a') && (strncmp(argv[0], "-anchor", length) == 0)) {
495 if (Ck_GetAnchor(interp, argv[1], &slavePtr->anchor) != TCL_OK) {
499 } else if ((c == 'b')
500 && (strncmp(argv[0], "-bordermode", length) == 0)) {
502 length = strlen(argv[1]);
503 if ((c == 'i') && (strncmp(argv[1], "ignore", length) == 0)
505 slavePtr->borderMode = BM_IGNORE;
506 } else if ((c == 'i') && (strncmp(argv[1], "inside", length) == 0)
508 slavePtr->borderMode = BM_INSIDE;
510 Tcl_AppendResult(interp, "bad border mode \"", argv[1],
511 "\": must be ignore or inside",
516 } else if ((c == 'h') && (strncmp(argv[0], "-height", length) == 0)) {
517 if (argv[1][0] == 0) {
518 slavePtr->flags &= ~(CHILD_REL_HEIGHT|CHILD_HEIGHT);
520 if (Ck_GetCoord(interp, slavePtr->winPtr, argv[1],
521 &slavePtr->height) != TCL_OK) {
525 slavePtr->flags &= ~CHILD_REL_HEIGHT;
526 slavePtr->flags |= CHILD_HEIGHT;
528 } else if ((c == 'r') && (strncmp(argv[0], "-relheight", length) == 0)
530 if (Tcl_GetDouble(interp, argv[1], &d) != TCL_OK) {
534 slavePtr->relHeight = d;
535 slavePtr->flags |= CHILD_REL_HEIGHT;
536 slavePtr->flags &= ~CHILD_HEIGHT;
537 } else if ((c == 'r') && (strncmp(argv[0], "-relwidth", length) == 0)
539 if (Tcl_GetDouble(interp, argv[1], &d) != TCL_OK) {
543 slavePtr->relWidth = d;
544 slavePtr->flags |= CHILD_REL_WIDTH;
545 slavePtr->flags &= ~CHILD_WIDTH;
546 } else if ((c == 'r') && (strncmp(argv[0], "-relx", length) == 0)
548 if (Tcl_GetDouble(interp, argv[1], &d) != TCL_OK) {
553 slavePtr->flags |= CHILD_REL_X;
554 } else if ((c == 'r') && (strncmp(argv[0], "-rely", length) == 0)
556 if (Tcl_GetDouble(interp, argv[1], &d) != TCL_OK) {
561 slavePtr->flags |= CHILD_REL_Y;
562 } else if ((c == 'w') && (strncmp(argv[0], "-width", length) == 0)) {
563 if (argv[1][0] == 0) {
564 slavePtr->flags &= ~(CHILD_REL_WIDTH|CHILD_WIDTH);
566 if (Ck_GetCoord(interp, slavePtr->winPtr, argv[1],
567 &slavePtr->width) != TCL_OK) {
571 slavePtr->flags &= ~CHILD_REL_WIDTH;
572 slavePtr->flags |= CHILD_WIDTH;
574 } else if ((c == 'x') && (strncmp(argv[0], "-x", length) == 0)) {
575 if (Ck_GetCoord(interp, slavePtr->winPtr, argv[1],
576 &slavePtr->x) != TCL_OK) {
580 slavePtr->flags &= ~CHILD_REL_X;
581 } else if ((c == 'y') && (strncmp(argv[0], "-y", length) == 0)) {
582 if (Ck_GetCoord(interp, slavePtr->winPtr, argv[1],
583 &slavePtr->y) != TCL_OK) {
587 slavePtr->flags &= ~CHILD_REL_Y;
589 Tcl_AppendResult(interp, "unknown or ambiguous option \"",
590 argv[0], "\": must be -anchor, -bordermode, -height, ",
591 "-relheight, -relwidth, -relx, -rely, -width, ",
592 "-x, or -y", (char *) NULL);
599 * Arrange for a placement recalculation in the master.
603 masterPtr = slavePtr->masterPtr;
604 if (masterPtr == NULL) {
605 masterPtr = FindMaster((slavePtr->winPtr->flags & CK_TOPLEVEL) ?
606 NULL : slavePtr->winPtr->parentPtr);
607 slavePtr->masterPtr = masterPtr;
608 slavePtr->nextPtr = masterPtr->slavePtr;
609 masterPtr->slavePtr = slavePtr;
611 if (!(masterPtr->flags & PARENT_RECONFIG_PENDING)) {
612 masterPtr->flags |= PARENT_RECONFIG_PENDING;
613 Tk_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr);
619 *----------------------------------------------------------------------
621 * RecomputePlacement --
623 * This procedure is called as a when-idle handler. It recomputes
624 * the geometries of all the slaves of a given master.
630 * Windows may change size or shape.
632 *----------------------------------------------------------------------
636 RecomputePlacement(clientData)
637 ClientData clientData; /* Pointer to Master record. */
639 Master *masterPtr = (Master *) clientData;
641 CkWindow *ancestor, *realMaster;
642 int x, y, width, height;
643 int masterWidth, masterHeight, masterBW;
645 masterPtr->flags &= ~PARENT_RECONFIG_PENDING;
648 * Iterate over all the slaves for the master. Each slave's
649 * geometry can be computed independently of the other slaves.
652 for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
653 slavePtr = slavePtr->nextPtr) {
655 * Step 1: compute size and borderwidth of master, taking into
656 * account desired border mode.
662 * Special case: masterPtr->winPtr == NULL, use entire screen !
665 if (masterPtr->winPtr == NULL) {
666 masterWidth = slavePtr->winPtr->mainPtr->maxWidth;
667 masterHeight = slavePtr->winPtr->mainPtr->maxHeight;
669 masterWidth = masterPtr->winPtr->width;
670 masterHeight = masterPtr->winPtr->height;
671 if (slavePtr->borderMode == BM_INSIDE) {
672 masterBW = (masterPtr->winPtr->flags & CK_BORDER) ? 1 : 0;
674 masterWidth -= 2*masterBW;
675 masterHeight -= 2*masterBW;
679 * Step 2: compute size of slave (outside dimensions including
680 * border) and location of anchor point within master.
684 if (slavePtr->flags & CHILD_REL_X) {
685 x = (int) ((slavePtr->relX*masterWidth) +
686 ((slavePtr->relX > 0) ? 0.5 : -0.5));
690 if (slavePtr->flags & CHILD_REL_Y) {
691 y = (int) ((slavePtr->relY*masterHeight) +
692 ((slavePtr->relY > 0) ? 0.5 : -0.5));
695 if (slavePtr->flags & CHILD_REL_WIDTH) {
696 width = (int) ((slavePtr->relWidth*masterWidth) + 0.5);
697 } else if (slavePtr->flags & CHILD_WIDTH) {
698 width = slavePtr->width;
700 width = slavePtr->winPtr->reqWidth;
702 if (slavePtr->flags & CHILD_REL_HEIGHT) {
703 height = (int) ((slavePtr->relHeight*masterHeight) + 0.5);
704 } else if (slavePtr->flags & CHILD_HEIGHT) {
705 height = slavePtr->height;
707 height = slavePtr->winPtr->reqHeight;
711 * Step 3: adjust the x and y positions so that the desired
712 * anchor point on the slave appears at that position. Also
713 * adjust for the border mode and master's border.
716 switch (slavePtr->anchor) {
743 case CK_ANCHOR_CENTER:
750 * Step 4: if masterPtr isn't actually the master of slavePtr,
751 * then translate the x and y coordinates back into the coordinate
752 * system of masterPtr.
755 for (ancestor = masterPtr->winPtr,
756 realMaster = slavePtr->winPtr->parentPtr;
757 ancestor != NULL && ancestor != realMaster;
758 ancestor = ancestor->parentPtr) {
764 * Step 5: adjust width and height again to reflect inside dimensions
765 * of window rather than outside. Also make sure that the width and
766 * height aren't zero.
777 * Step 6: see if the window's size or location has changed; if
778 * so then resize and/or move it.
781 if (width != slavePtr->winPtr->width ||
782 height != slavePtr->winPtr->height)
783 Ck_ResizeWindow(slavePtr->winPtr, width, height);
784 if (x != slavePtr->winPtr->x ||
785 y != slavePtr->winPtr->y)
786 Ck_MoveWindow(slavePtr->winPtr, x, y);
788 * Temporary kludge til Ck_MoveResizeWindow available !!!
790 if (width != slavePtr->winPtr->width ||
791 height != slavePtr->winPtr->height)
792 Ck_ResizeWindow(slavePtr->winPtr, width, height);
794 Ck_MapWindow(slavePtr->winPtr);
799 *----------------------------------------------------------------------
801 * MasterStructureProc --
803 * This procedure is invoked by the event handler when
804 * CK_EV_MAP/CK_EV_EXPOSE/CK_EV_DESTROY events occur for
811 * Structures get cleaned up if the window was deleted. If the
812 * window was resized then slave geometries get recomputed.
814 *----------------------------------------------------------------------
818 MasterStructureProc(clientData, eventPtr)
819 ClientData clientData; /* Pointer to Master structure for window
820 * referred to by eventPtr. */
821 CkEvent *eventPtr; /* Describes what just happened. */
823 Master *masterPtr = (Master *) clientData;
824 Slave *slavePtr, *nextPtr;
826 if (eventPtr->type == CK_EV_EXPOSE ||
827 eventPtr->type == CK_EV_MAP) {
828 if ((masterPtr->slavePtr != NULL)
829 && !(masterPtr->flags & PARENT_RECONFIG_PENDING)) {
830 masterPtr->flags |= PARENT_RECONFIG_PENDING;
831 Tk_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr);
833 } else if (eventPtr->type == CK_EV_DESTROY) {
834 for (slavePtr = masterPtr->slavePtr; slavePtr != NULL;
835 slavePtr = nextPtr) {
836 slavePtr->masterPtr = NULL;
837 nextPtr = slavePtr->nextPtr;
838 slavePtr->nextPtr = NULL;
840 Tcl_DeleteHashEntry(Tcl_FindHashEntry(&masterTable,
841 (char *) masterPtr->winPtr));
842 if (masterPtr->flags & PARENT_RECONFIG_PENDING) {
843 Tk_CancelIdleCall(RecomputePlacement, (ClientData) masterPtr);
845 masterPtr->winPtr = NULL;
846 ckfree((char *) masterPtr);
851 *----------------------------------------------------------------------
853 * SlaveStructureProc --
855 * This procedure is invoked by the event handler when
856 * CK_EV_MAP/CK_EV_EXPOSE/CK_EV_DESTROY events occur for a
863 * Structures get cleaned up if the window was deleted.
865 *----------------------------------------------------------------------
869 SlaveStructureProc(clientData, eventPtr)
870 ClientData clientData; /* Pointer to Slave structure for window
871 * referred to by eventPtr. */
872 CkEvent *eventPtr; /* Describes what just happened. */
874 Slave *slavePtr = (Slave *) clientData;
876 if (eventPtr->type == CK_EV_DESTROY) {
877 UnlinkSlave(slavePtr);
878 Tcl_DeleteHashEntry(Tcl_FindHashEntry(&slaveTable,
879 (char *) slavePtr->winPtr));
880 ckfree((char *) slavePtr);
885 *----------------------------------------------------------------------
887 * PlaceRequestProc --
889 * This procedure is invoked whenever a slave managed by us
890 * changes its requested geometry.
896 * The window will get relayed out, if its requested size has
897 * anything to do with its actual size.
899 *----------------------------------------------------------------------
903 PlaceRequestProc(clientData, winPtr)
904 ClientData clientData; /* Pointer to our record for slave. */
905 CkWindow *winPtr; /* Window that changed its desired
908 Slave *slavePtr = (Slave *) clientData;
911 if (((slavePtr->flags & (CHILD_WIDTH|CHILD_REL_WIDTH)) != 0)
912 && ((slavePtr->flags & (CHILD_HEIGHT|CHILD_REL_HEIGHT)) != 0)) {
915 masterPtr = slavePtr->masterPtr;
916 if (masterPtr == NULL) {
919 if (!(masterPtr->flags & PARENT_RECONFIG_PENDING)) {
920 masterPtr->flags |= PARENT_RECONFIG_PENDING;
921 Tk_DoWhenIdle(RecomputePlacement, (ClientData) masterPtr);
926 *--------------------------------------------------------------
928 * PlaceLostSlaveProc --
930 * This procedure is invoked whenever some other geometry
931 * claims control over a slave that used to be managed by us.
937 * Forgets all placer-related information about the slave.
939 *--------------------------------------------------------------
943 PlaceLostSlaveProc(clientData, winPtr)
944 ClientData clientData; /* Slave structure for slave window that
945 * was stolen away. */
946 CkWindow *winPtr; /* Slave window. */
948 register Slave *slavePtr = (Slave *) clientData;
950 if (slavePtr->masterPtr->winPtr != slavePtr->winPtr->parentPtr) {
951 Ck_UnmaintainGeometry(slavePtr->winPtr, slavePtr->masterPtr->winPtr);
953 Ck_UnmapWindow(winPtr);
954 UnlinkSlave(slavePtr);
955 Tcl_DeleteHashEntry(Tcl_FindHashEntry(&slaveTable, (char *) winPtr));
956 Ck_DeleteEventHandler(winPtr, CK_EV_MAP | CK_EV_EXPOSE | CK_EV_DESTROY,
957 SlaveStructureProc, (ClientData) slavePtr);
958 ckfree((char *) slavePtr);