tkMacOSXWm.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:176k
源码类别:

通讯编程

开发平台:

Visual C++

  1.      * Tk_DestroyWindow will try to destroy the window, but of course
  2.      * it's already gone.
  3.      */
  4.     Tk_ErrorHandler handler = Tk_CreateErrorHandler(winPtr->display,
  5.     -1, -1, -1, (Tk_ErrorProc *) NULL, (ClientData) NULL);
  6.     Tk_DestroyWindow((Tk_Window) winPtr);
  7.     Tk_DeleteErrorHandler(handler);
  8. }
  9. if (wmTracing) {
  10.     TkMacOSXDbgMsg("TopLevelEventProc: %s deleted", winPtr->pathName);
  11. }
  12.     } else if (eventPtr->type == ReparentNotify) {
  13. Tcl_Panic("recieved unwanted reparent event");
  14.     }
  15. }
  16. /*
  17.  *----------------------------------------------------------------------
  18.  *
  19.  * TopLevelReqProc --
  20.  *
  21.  * This procedure is invoked by the geometry manager whenever
  22.  * the requested size for a top-level window is changed.
  23.  *
  24.  * Results:
  25.  * None.
  26.  *
  27.  * Side effects:
  28.  * Arrange for the window to be resized to satisfy the request
  29.  * (this happens as a when-idle action).
  30.  *
  31.  *----------------------------------------------------------------------
  32.  */
  33. /* ARGSUSED */
  34. static void
  35. TopLevelReqProc(
  36.     ClientData dummy, /* Not used. */
  37.     Tk_Window tkwin) /* Information about window. */
  38. {
  39.     TkWindow *winPtr = (TkWindow *) tkwin;
  40.     WmInfo *wmPtr;
  41.     wmPtr = winPtr->wmInfoPtr;
  42.     wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
  43.     if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
  44. Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
  45. wmPtr->flags |= WM_UPDATE_PENDING;
  46.     }
  47. }
  48. /*
  49.  *----------------------------------------------------------------------
  50.  *
  51.  * UpdateGeometryInfo --
  52.  *
  53.  * This procedure is invoked when a top-level window is first
  54.  * mapped, and also as a when-idle procedure, to bring the
  55.  * geometry and/or position of a top-level window back into
  56.  * line with what has been requested by the user and/or widgets.
  57.  * This procedure doesn't return until the window manager has
  58.  * responded to the geometry change.
  59.  *
  60.  * Results:
  61.  * None.
  62.  *
  63.  * Side effects:
  64.  * The window's size and location may change, unless the WM prevents
  65.  * that from happening.
  66.  *
  67.  *----------------------------------------------------------------------
  68.  */
  69. static void
  70. UpdateGeometryInfo(
  71.     ClientData clientData) /* Pointer to the window's record. */
  72. {
  73.     TkWindow *winPtr = (TkWindow *) clientData;
  74.     WmInfo *wmPtr = winPtr->wmInfoPtr;
  75.     int x, y, width, height, min, max;
  76.     unsigned long serial;
  77.     wmPtr->flags &= ~WM_UPDATE_PENDING;
  78.     if (wmPtr->flags & WM_FULLSCREEN) {
  79. return;
  80.     }
  81.     /*
  82.      * Compute the new size for the top-level window. See the
  83.      * user documentation for details on this, but the size
  84.      * requested depends on (a) the size requested internally
  85.      * by the window's widgets, (b) the size requested by the
  86.      * user in a "wm geometry" command or via wm-based interactive
  87.      * resizing (if any), and (c) whether or not the window is
  88.      * gridded. Don't permit sizes <= 0 because this upsets
  89.      * the X server.
  90.      */
  91.     if (wmPtr->width == -1) {
  92. width = winPtr->reqWidth;
  93.     } else if (wmPtr->gridWin != NULL) {
  94. width = winPtr->reqWidth
  95. + (wmPtr->width - wmPtr->reqGridWidth)*wmPtr->widthInc;
  96.     } else {
  97. width = wmPtr->width;
  98.     }
  99.     if (width <= 0) {
  100. width = 1;
  101.     }
  102.     /*
  103.      * Account for window max/min width
  104.      */
  105.     if (wmPtr->gridWin != NULL) {
  106. min = winPtr->reqWidth
  107. + (wmPtr->minWidth - wmPtr->reqGridWidth)*wmPtr->widthInc;
  108. if (wmPtr->maxWidth > 0) {
  109.     max = winPtr->reqWidth
  110.     + (wmPtr->maxWidth - wmPtr->reqGridWidth)*wmPtr->widthInc;
  111. } else {
  112.     max = 0;
  113. }
  114.     } else {
  115. min = wmPtr->minWidth;
  116. max = wmPtr->maxWidth;
  117.     }
  118.     if (width < min) {
  119. width = min;
  120.     } else if ((max > 0) && (width > max)) {
  121. width = max;
  122.     }
  123.     if (wmPtr->height == -1) {
  124. height = winPtr->reqHeight;
  125.     } else if (wmPtr->gridWin != NULL) {
  126. height = winPtr->reqHeight
  127. + (wmPtr->height - wmPtr->reqGridHeight)*wmPtr->heightInc;
  128.     } else {
  129. height = wmPtr->height;
  130.     }
  131.     if (height <= 0) {
  132. height = 1;
  133.     }
  134.     /*
  135.      * Account for window max/min height
  136.      */
  137.     if (wmPtr->gridWin != NULL) {
  138. min = winPtr->reqHeight
  139. + (wmPtr->minHeight - wmPtr->reqGridHeight)*wmPtr->heightInc;
  140. if (wmPtr->maxHeight > 0) {
  141.     max = winPtr->reqHeight
  142.     + (wmPtr->maxHeight-wmPtr->reqGridHeight)*wmPtr->heightInc;
  143. } else {
  144.     max = 0;
  145. }
  146.     } else {
  147. min = wmPtr->minHeight;
  148. max = wmPtr->maxHeight;
  149.     }
  150.     if (height < min) {
  151. height = min;
  152.     } else if ((max > 0) && (height > max)) {
  153. height = max;
  154.     }
  155.     /*
  156.      * Compute the new position for the upper-left pixel of the window's
  157.      * decorative frame. This is tricky, because we need to include the
  158.      * border widths supplied by a reparented parent in this calculation,
  159.      * but can't use the parent's current overall size since that may
  160.      * change as a result of this code.
  161.      */
  162.     if (wmPtr->flags & WM_NEGATIVE_X) {
  163. x = wmPtr->vRootWidth - wmPtr->x
  164.     - (width + (wmPtr->parentWidth - winPtr->changes.width));
  165.     } else {
  166. x =  wmPtr->x;
  167.     }
  168.     if (wmPtr->flags & WM_NEGATIVE_Y) {
  169. y = wmPtr->vRootHeight - wmPtr->y
  170.     - (height + (wmPtr->parentHeight - winPtr->changes.height));
  171.     } else {
  172. y =  wmPtr->y;
  173.     }
  174.     /*
  175.      * If the window's size is going to change and the window is
  176.      * supposed to not be resizable by the user, then we have to
  177.      * update the size hints. There may also be a size-hint-update
  178.      * request pending from somewhere else, too.
  179.      */
  180.     if (((width != winPtr->changes.width)
  181.     || (height != winPtr->changes.height))
  182.     && (wmPtr->gridWin == NULL)
  183.     && ((wmPtr->sizeHintsFlags & (PMinSize|PMaxSize)) == 0)) {
  184. wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
  185.     }
  186.     if (wmPtr->flags & WM_UPDATE_SIZE_HINTS) {
  187. UpdateSizeHints(winPtr);
  188.     }
  189.     /*
  190.      * Reconfigure the window if it isn't already configured correctly.
  191.      * A few tricky points:
  192.      *
  193.      * 1. If the window is embedded and the container is also in this
  194.      *    process, don't actually reconfigure the window; just pass the
  195.      *    desired size on to the container. Also, zero out any position
  196.      *    information, since embedded windows are not allowed to move.
  197.      * 2. Sometimes the window manager will give us a different size
  198.      *    than we asked for (e.g. mwm has a minimum size for windows), so
  199.      *    base the size check on what we *asked for* last time, not what we
  200.      *    got.
  201.      * 3. Don't move window unless a new position has been requested for
  202.      *    it. This is because of "features" in some window managers (e.g.
  203.      *    twm, as of 4/24/91) where they don't interpret coordinates
  204.      *    according to ICCCM. Moving a window to its current location may
  205.      *    cause it to shift position on the screen.
  206.      */
  207.     if (Tk_IsEmbedded(winPtr)) {
  208. TkWindow *contWinPtr = TkpGetOtherWindow(winPtr);
  209. /*
  210.  * TODO: Here we should handle out of process embedding.
  211.  */
  212. if (contWinPtr != NULL) {
  213.     /*
  214.      * This window is embedded and the container is also in this
  215.      * process, so we don't need to do anything special about the
  216.      * geometry, except to make sure that the desired size is known
  217.      * by the container. Also, zero out any position information,
  218.      * since embedded windows are not allowed to move.
  219.      */
  220.     wmPtr->x = wmPtr->y = 0;
  221.     wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y);
  222.     Tk_GeometryRequest((Tk_Window) contWinPtr, width, height);
  223. }
  224. return;
  225.     }
  226.     serial = NextRequest(winPtr->display);
  227.     if (wmPtr->flags & WM_MOVE_PENDING) {
  228. wmPtr->configWidth = width;
  229. wmPtr->configHeight = height;
  230. if (wmTracing) {
  231.     TkMacOSXDbgMsg("Moving to %d %d, resizing to %d x %d", x, y,
  232.     width, height);
  233. }
  234. wmPtr->flags |= WM_SYNC_PENDING;
  235. XMoveResizeWindow(winPtr->display, winPtr->window, x, y,
  236. (unsigned) width, (unsigned) height);
  237. wmPtr->flags &= ~WM_SYNC_PENDING;
  238.     } else if ((width != wmPtr->configWidth)
  239.     || (height != wmPtr->configHeight)) {
  240. wmPtr->configWidth = width;
  241. wmPtr->configHeight = height;
  242. if (wmTracing) {
  243.     TkMacOSXDbgMsg("Resizing to %d x %dn", width, height);
  244. }
  245. wmPtr->flags |= WM_SYNC_PENDING;
  246. XResizeWindow(winPtr->display, winPtr->window, (unsigned) width,
  247. (unsigned) height);
  248. wmPtr->flags &= ~WM_SYNC_PENDING;
  249.     }
  250. }
  251. /*
  252.  *----------------------------------------------------------------------
  253.  *
  254.  * UpdateSizeHints --
  255.  *
  256.  * This procedure is called to update the window manager's
  257.  * size hints information from the information in a WmInfo
  258.  * structure.
  259.  *
  260.  * Results:
  261.  * None.
  262.  *
  263.  * Side effects:
  264.  * Properties get changed for winPtr.
  265.  *
  266.  *----------------------------------------------------------------------
  267.  */
  268. static void
  269. UpdateSizeHints(
  270.     TkWindow *winPtr)
  271. {
  272.     WmInfo *wmPtr = winPtr->wmInfoPtr;
  273.     wmPtr->flags &= ~WM_UPDATE_SIZE_HINTS;
  274.     return;
  275. }
  276. /*
  277.  *----------------------------------------------------------------------
  278.  *
  279.  * ParseGeometry --
  280.  *
  281.  * This procedure parses a geometry string and updates
  282.  * information used to control the geometry of a top-level
  283.  * window.
  284.  *
  285.  * Results:
  286.  * A standard Tcl return value, plus an error message in
  287.  * the interp's result if an error occurs.
  288.  *
  289.  * Side effects:
  290.  * The size and/or location of winPtr may change.
  291.  *
  292.  *----------------------------------------------------------------------
  293.  */
  294. static int
  295. ParseGeometry(
  296.     Tcl_Interp *interp, /* Used for error reporting. */
  297.     char *string, /* String containing new geometry. Has the
  298.  * standard form "=wxh+x+y". */
  299.     TkWindow *winPtr) /* Pointer to top-level window whose
  300.  * geometry is to be changed. */
  301. {
  302.     WmInfo *wmPtr = winPtr->wmInfoPtr;
  303.     int x, y, width, height, flags;
  304.     char *end;
  305.     char *p = string;
  306.     /*
  307.      * The leading "=" is optional.
  308.      */
  309.     if (*p == '=') {
  310. p++;
  311.     }
  312.     /*
  313.      * Parse the width and height, if they are present. Don't
  314.      * actually update any of the fields of wmPtr until we've
  315.      * successfully parsed the entire geometry string.
  316.      */
  317.     width = wmPtr->width;
  318.     height = wmPtr->height;
  319.     x = wmPtr->x;
  320.     y = wmPtr->y;
  321.     flags = wmPtr->flags;
  322.     if (isdigit(UCHAR(*p))) {
  323. width = strtoul(p, &end, 10);
  324. p = end;
  325. if (*p != 'x') {
  326.     goto error;
  327. }
  328. p++;
  329. if (!isdigit(UCHAR(*p))) {
  330.     goto error;
  331. }
  332. height = strtoul(p, &end, 10);
  333. p = end;
  334.     }
  335.     /*
  336.      * Parse the X and Y coordinates, if they are present.
  337.      */
  338.     if (*p != '') {
  339. flags &= ~(WM_NEGATIVE_X | WM_NEGATIVE_Y);
  340. if (*p == '-') {
  341.     flags |= WM_NEGATIVE_X;
  342. } else if (*p != '+') {
  343.     goto error;
  344. }
  345. p++;
  346. if (!isdigit(UCHAR(*p)) && (*p != '-')) {
  347.     goto error;
  348. }
  349. x = strtol(p, &end, 10);
  350. p = end;
  351. if (*p == '-') {
  352.     flags |= WM_NEGATIVE_Y;
  353. } else if (*p != '+') {
  354.     goto error;
  355. }
  356. p++;
  357. if (!isdigit(UCHAR(*p)) && (*p != '-')) {
  358.     goto error;
  359. }
  360. y = strtol(p, &end, 10);
  361. if (*end != '') {
  362.     goto error;
  363. }
  364. /*
  365.  * Assume that the geometry information came from the user,
  366.  * unless an explicit source has been specified. Otherwise
  367.  * most window managers assume that the size hints were
  368.  * program-specified and they ignore them.
  369.  */
  370. if ((wmPtr->sizeHintsFlags & (USPosition|PPosition)) == 0) {
  371.     wmPtr->sizeHintsFlags |= USPosition;
  372.     flags |= WM_UPDATE_SIZE_HINTS;
  373. }
  374.     }
  375.     /*
  376.      * Everything was parsed OK. Update the fields of *wmPtr and
  377.      * arrange for the appropriate information to be percolated out
  378.      * to the window manager at the next idle moment.
  379.      */
  380.     wmPtr->width = width;
  381.     wmPtr->height = height;
  382.     if ((x != wmPtr->x) || (y != wmPtr->y)
  383.     || ((flags & (WM_NEGATIVE_X|WM_NEGATIVE_Y))
  384.     != (wmPtr->flags & (WM_NEGATIVE_X|WM_NEGATIVE_Y)))) {
  385. if (wmPtr->flags & WM_FULLSCREEN) {
  386.     wmPtr->configX = x;
  387.     wmPtr->configY = y;
  388. } else {
  389.     wmPtr->x = x;
  390.     wmPtr->y = y;
  391. }
  392. flags |= WM_MOVE_PENDING;
  393.     }
  394.     wmPtr->flags = flags;
  395.     if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
  396. Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
  397. wmPtr->flags |= WM_UPDATE_PENDING;
  398.     }
  399.     return TCL_OK;
  400. error:
  401.     Tcl_AppendResult(interp, "bad geometry specifier "", string, """, NULL);
  402.     return TCL_ERROR;
  403. }
  404. /*
  405.  *----------------------------------------------------------------------
  406.  *
  407.  * Tk_GetRootCoords --
  408.  *
  409.  * Given a token for a window, this procedure traces through the
  410.  * window's lineage to find the (virtual) root-window coordinates
  411.  * corresponding to point (0,0) in the window.
  412.  *
  413.  * Results:
  414.  * The locations pointed to by xPtr and yPtr are filled in with
  415.  * the root coordinates of the (0,0) point in tkwin. If a virtual
  416.  * root window is in effect for the window, then the coordinates
  417.  * in the virtual root are returned.
  418.  *
  419.  * Side effects:
  420.  * None.
  421.  *
  422.  *----------------------------------------------------------------------
  423.  */
  424. void
  425. Tk_GetRootCoords(
  426.     Tk_Window tkwin, /* Token for window. */
  427.     int *xPtr, /* Where to store x-displacement of (0,0). */
  428.     int *yPtr) /* Where to store y-displacement of (0,0). */
  429. {
  430.     int x, y;
  431.     TkWindow *winPtr = (TkWindow *) tkwin;
  432.     /*
  433.      * Search back through this window's parents all the way to a
  434.      * top-level window, combining the offsets of each window within
  435.      * its parent.
  436.      */
  437.     x = y = 0;
  438.     while (1) {
  439. x += winPtr->changes.x + winPtr->changes.border_width;
  440. y += winPtr->changes.y + winPtr->changes.border_width;
  441. if (winPtr->flags & TK_TOP_LEVEL) {
  442.     if (!(Tk_IsEmbedded(winPtr))) {
  443. x += winPtr->wmInfoPtr->xInParent;
  444. y += winPtr->wmInfoPtr->yInParent;
  445. break;
  446.     } else {
  447. TkWindow *otherPtr = TkpGetOtherWindow(winPtr);
  448. if (otherPtr != NULL) {
  449.     /*
  450.      * The container window is in the same application.
  451.      * Query its coordinates.
  452.      */
  453.     winPtr = otherPtr;
  454.     /*
  455.      * Remember to offset by the container window here,
  456.      * since at the end of this if branch, we will
  457.      * pop out to the container's parent...
  458.      */
  459.     x += winPtr->changes.x + winPtr->changes.border_width;
  460.     y += winPtr->changes.y + winPtr->changes.border_width;
  461. } else {
  462.     Point theOffset;
  463.     if (tkMacOSXEmbedHandler->getOffsetProc != NULL) {
  464. /*
  465.  * We do not require that the changes.x & changes.y for
  466.  * a non-Tk master window be kept up to date. So we
  467.  * first subtract off the possibly bogus values that
  468.  * have been added on at the top of this pass through
  469.  * the loop, and then call out to the getOffsetProc to
  470.  * give us the correct offset.
  471.  */
  472. x -= winPtr->changes.x + winPtr->changes.border_width;
  473. y -= winPtr->changes.y + winPtr->changes.border_width;
  474. tkMacOSXEmbedHandler->getOffsetProc((Tk_Window) winPtr,
  475. &theOffset);
  476. x += theOffset.h;
  477. y += theOffset.v;
  478.     }
  479.     break;
  480. }
  481.     }
  482. }
  483. winPtr = winPtr->parentPtr;
  484.     }
  485.     *xPtr = x;
  486.     *yPtr = y;
  487. }
  488. /*
  489.  *----------------------------------------------------------------------
  490.  *
  491.  * Tk_CoordsToWindow --
  492.  *
  493.  * This is a Macintosh specific implementation of this function.
  494.  * Given the root coordinates of a point, this procedure returns
  495.  * the token for the top-most window covering that point, if
  496.  * there exists such a window in this application.
  497.  *
  498.  * Results:
  499.  * The return result is either a token for the window corresponding
  500.  * to rootX and rootY, or else NULL to indicate that there is no such
  501.  * window.
  502.  *
  503.  * Side effects:
  504.  * None.
  505.  *
  506.  *----------------------------------------------------------------------
  507.  */
  508. Tk_Window
  509. Tk_CoordsToWindow(
  510.     int rootX, int rootY, /* Coordinates of point in root window. If
  511.  * a virtual-root window manager is in use,
  512.  * these coordinates refer to the virtual
  513.  * root, not the real root. */
  514.     Tk_Window tkwin) /* Token for any window in application;
  515.  * used to identify the display. */
  516. {
  517.     WindowPtr whichWin;
  518.     Point where;
  519.     Window rootChild;
  520.     TkWindow *winPtr, *childPtr;
  521.     TkWindow *nextPtr; /* Coordinates of highest child found so
  522.  * far that contains point. */
  523.     int x, y; /* Coordinates in winPtr. */
  524.     int tmpx, tmpy, bd;
  525.     TkDisplay *dispPtr;
  526.     /*
  527.      * Step 1: find the top-level window that contains the desired point.
  528.      */
  529.     where.h = rootX;
  530.     where.v = rootY;
  531.     FindWindow(where, &whichWin);
  532.     if (whichWin == NULL) {
  533. return NULL;
  534.     }
  535.     rootChild = TkMacOSXGetXWindow(whichWin);
  536.     dispPtr = TkGetDisplayList();
  537.     winPtr = (TkWindow *) Tk_IdToWindow(dispPtr->display, rootChild);
  538.     if (winPtr == NULL) {
  539. return NULL;
  540.     }
  541.     /*
  542.      * Step 2: work down through the hierarchy underneath this window.
  543.      * At each level, scan through all the children to find the highest
  544.      * one in the stacking order that contains the point. Then repeat
  545.      * the whole process on that child.
  546.      */
  547.     x = rootX - winPtr->wmInfoPtr->xInParent;
  548.     y = rootY - winPtr->wmInfoPtr->yInParent;
  549.     while (1) {
  550. x -= winPtr->changes.x;
  551. y -= winPtr->changes.y;
  552. nextPtr = NULL;
  553. /*
  554.  * Container windows cannot have children. So if it is a container,
  555.  * look there, otherwise inspect the children.
  556.  */
  557. if (Tk_IsContainer(winPtr)) {
  558.     childPtr = TkpGetOtherWindow(winPtr);
  559.     if (childPtr != NULL) {
  560. if (Tk_IsMapped(childPtr)) {
  561.     tmpx = x - childPtr->changes.x;
  562.     tmpy = y - childPtr->changes.y;
  563.     bd = childPtr->changes.border_width;
  564.     if ((tmpx >= -bd) && (tmpy >= -bd)
  565. && (tmpx < (childPtr->changes.width + bd))
  566. && (tmpy < (childPtr->changes.height + bd))) {
  567. nextPtr = childPtr;
  568.     }
  569. }
  570.     }
  571.     /*
  572.      * TODO: Here we should handle out of process embedding.
  573.      */
  574. } else {
  575.     for (childPtr = winPtr->childList; childPtr != NULL;
  576.     childPtr = childPtr->nextPtr) {
  577. if (!Tk_IsMapped(childPtr) ||
  578. (childPtr->flags & TK_TOP_LEVEL)) {
  579.     continue;
  580. }
  581. tmpx = x - childPtr->changes.x;
  582. tmpy = y - childPtr->changes.y;
  583. bd = childPtr->changes.border_width;
  584. if ((tmpx >= -bd) && (tmpy >= -bd)
  585. && (tmpx < (childPtr->changes.width + bd))
  586. && (tmpy < (childPtr->changes.height + bd))) {
  587.     nextPtr = childPtr;
  588. }
  589.     }
  590. }
  591. if (nextPtr == NULL) {
  592.     break;
  593. }
  594. winPtr = nextPtr;
  595.     }
  596.     return (Tk_Window) winPtr;
  597. }
  598. /*
  599.  *----------------------------------------------------------------------
  600.  *
  601.  * Tk_TopCoordsToWindow --
  602.  *
  603.  * Given a Tk Window, and coordinates of a point relative to that window
  604.  * this procedure returns the top-most child of the window (excluding
  605.  * toplevels) covering that point, if there exists such a window in this
  606.  * application.
  607.  * It also sets newX, and newY to the coords of the point relative to the
  608.  * window returned.
  609.  *
  610.  * Results:
  611.  * The return result is either a token for the window corresponding
  612.  * to rootX and rootY, or else NULL to indicate that there is no such
  613.  * window. newX and newY are also set to the coords of the point relative
  614.  * to the returned window.
  615.  *
  616.  * Side effects:
  617.  * None.
  618.  *
  619.  *----------------------------------------------------------------------
  620.  */
  621. Tk_Window
  622. Tk_TopCoordsToWindow(
  623.     Tk_Window tkwin, /* Token for a Tk Window which defines the;
  624.  * coordinates for rootX & rootY */
  625.     int rootX, int rootY, /* Coordinates of a point in tkWin. */
  626.     int *newX, int *newY) /* Coordinates of point in the upperMost child
  627.  * of tkWin containing (rootX,rootY) */
  628. {
  629.     TkWindow *winPtr, *childPtr;
  630.     TkWindow *nextPtr; /* Coordinates of highest child found so
  631.  * far that contains point. */
  632.     int x, y; /* Coordinates in winPtr. */
  633.     Window *children; /* Children of winPtr, or NULL. */
  634.     winPtr = (TkWindow *) tkwin;
  635.     x = rootX;
  636.     y = rootY;
  637.     while (1) {
  638. nextPtr = NULL;
  639. children = NULL;
  640. /*
  641.  * Container windows cannot have children. So if it is a container,
  642.  * look there, otherwise inspect the children.
  643.  */
  644. if (Tk_IsContainer(winPtr)) {
  645.     childPtr = TkpGetOtherWindow(winPtr);
  646.     if (childPtr != NULL) {
  647. if (Tk_IsMapped(childPtr) &&
  648. x > childPtr->changes.x &&
  649. x < childPtr->changes.x + childPtr->changes.width &&
  650. y > childPtr->changes.y &&
  651. y < childPtr->changes.y + childPtr->changes.height) {
  652.     nextPtr = childPtr;
  653. }
  654.     }
  655.     /*
  656.      * TODO: Here we should handle out of process embedding.
  657.      */
  658. } else {
  659.     for (childPtr = winPtr->childList; childPtr != NULL;
  660.     childPtr = childPtr->nextPtr) {
  661. if (!Tk_IsMapped(childPtr) ||
  662. (childPtr->flags & TK_TOP_LEVEL)) {
  663.     continue;
  664. }
  665. if (x < childPtr->changes.x || y < childPtr->changes.y) {
  666.     continue;
  667. }
  668. if (x > childPtr->changes.x + childPtr->changes.width ||
  669. y > childPtr->changes.y + childPtr->changes.height) {
  670.     continue;
  671. }
  672. nextPtr = childPtr;
  673.     }
  674. }
  675. if (nextPtr == NULL) {
  676.     break;
  677. }
  678. winPtr = nextPtr;
  679. x -= winPtr->changes.x;
  680. y -= winPtr->changes.y;
  681.     }
  682.     *newX = x;
  683.     *newY = y;
  684.     return (Tk_Window) winPtr;
  685. }
  686. /*
  687.  *----------------------------------------------------------------------
  688.  *
  689.  * UpdateVRootGeometry --
  690.  *
  691.  * This procedure is called to update all the virtual root
  692.  * geometry information in wmPtr.
  693.  *
  694.  * Results:
  695.  * None.
  696.  *
  697.  * Side effects:
  698.  * The vRootX, vRootY, vRootWidth, and vRootHeight fields in
  699.  * wmPtr are filled with the most up-to-date information.
  700.  *
  701.  *----------------------------------------------------------------------
  702.  */
  703. static void
  704. UpdateVRootGeometry(
  705.     WmInfo *wmPtr) /* Window manager information to be
  706.  * updated. The wmPtr->vRoot field must
  707.  * be valid. */
  708. {
  709.     TkWindow *winPtr = wmPtr->winPtr;
  710.     unsigned int bd, dummy;
  711.     Window dummy2;
  712.     Status status;
  713.     Tk_ErrorHandler handler;
  714.     /*
  715.      * If this isn't a virtual-root window manager, just return information
  716.      * about the screen.
  717.      */
  718.     wmPtr->flags &= ~WM_VROOT_OFFSET_STALE;
  719.     if (wmPtr->vRoot == None) {
  720. noVRoot:
  721. wmPtr->vRootX = wmPtr->vRootY = 0;
  722. wmPtr->vRootWidth = DisplayWidth(winPtr->display, winPtr->screenNum);
  723. wmPtr->vRootHeight = DisplayHeight(winPtr->display, winPtr->screenNum);
  724. return;
  725.     }
  726.     /*
  727.      * Refresh the virtual root information if it's out of date.
  728.      */
  729.     handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1,
  730.     (Tk_ErrorProc *) NULL, (ClientData) NULL);
  731.     status = XGetGeometry(winPtr->display, wmPtr->vRoot,
  732.     &dummy2, &wmPtr->vRootX, &wmPtr->vRootY,
  733.     &wmPtr->vRootWidth, &wmPtr->vRootHeight, &bd, &dummy);
  734.     if (wmTracing) {
  735. TkMacOSXDbgMsg("x = %d, y = %d, width = %d, height = %d, status = %d",
  736. wmPtr->vRootX, wmPtr->vRootY, wmPtr->vRootWidth,
  737. wmPtr->vRootHeight, status);
  738.     }
  739.     Tk_DeleteErrorHandler(handler);
  740.     if (status == 0) {
  741. /*
  742.  * The virtual root is gone!  Pretend that it never existed.
  743.  */
  744. wmPtr->vRoot = None;
  745. goto noVRoot;
  746.     }
  747. }
  748. /*
  749.  *----------------------------------------------------------------------
  750.  *
  751.  * Tk_GetVRootGeometry --
  752.  *
  753.  * This procedure returns information about the virtual root
  754.  * window corresponding to a particular Tk window.
  755.  *
  756.  * Results:
  757.  * The values at xPtr, yPtr, widthPtr, and heightPtr are set
  758.  * with the offset and dimensions of the root window corresponding
  759.  * to tkwin. If tkwin is being managed by a virtual root window
  760.  * manager these values correspond to the virtual root window being
  761.  * used for tkwin; otherwise the offsets will be 0 and the
  762.  * dimensions will be those of the screen.
  763.  *
  764.  * Side effects:
  765.  * Vroot window information is refreshed if it is out of date.
  766.  *
  767.  *----------------------------------------------------------------------
  768.  */
  769. void
  770. Tk_GetVRootGeometry(
  771.     Tk_Window tkwin, /* Window whose virtual root is to be
  772.  * queried. */
  773.     int *xPtr, int *yPtr, /* Store x and y offsets of virtual root
  774.  * here. */
  775.     int *widthPtr, /* Store dimensions of virtual root here. */
  776.     int *heightPtr)
  777. {
  778.     WmInfo *wmPtr;
  779.     TkWindow *winPtr = (TkWindow *) tkwin;
  780.     /*
  781.      * Find the top-level window for tkwin, and locate the window manager
  782.      * information for that window.
  783.      */
  784.     while (!(winPtr->flags & TK_TOP_LEVEL)) {
  785. winPtr = winPtr->parentPtr;
  786.     }
  787.     wmPtr = winPtr->wmInfoPtr;
  788.     /*
  789.      * Make sure that the geometry information is up-to-date, then copy
  790.      * it out to the caller.
  791.      */
  792.     if (wmPtr->flags & WM_VROOT_OFFSET_STALE) {
  793. UpdateVRootGeometry(wmPtr);
  794.     }
  795.     *xPtr = wmPtr->vRootX;
  796.     *yPtr = wmPtr->vRootY;
  797.     *widthPtr = wmPtr->vRootWidth;
  798.     *heightPtr = wmPtr->vRootHeight;
  799. }
  800. /*
  801.  *----------------------------------------------------------------------
  802.  *
  803.  * Tk_MoveToplevelWindow --
  804.  *
  805.  * This procedure is called instead of Tk_MoveWindow to adjust
  806.  * the x-y location of a top-level window. It delays the actual
  807.  * move to a later time and keeps window-manager information
  808.  * up-to-date with the move
  809.  *
  810.  * Results:
  811.  * None.
  812.  *
  813.  * Side effects:
  814.  * The window is eventually moved so that its upper-left corner
  815.  * (actually, the upper-left corner of the window's decorative
  816.  * frame, if there is one) is at (x,y).
  817.  *
  818.  *----------------------------------------------------------------------
  819.  */
  820. void
  821. Tk_MoveToplevelWindow(
  822.     Tk_Window tkwin, /* Window to move. */
  823.     int x, int y) /* New location for window (within
  824.  * parent). */
  825. {
  826.     TkWindow *winPtr = (TkWindow *) tkwin;
  827.     WmInfo *wmPtr = winPtr->wmInfoPtr;
  828.     if (!(winPtr->flags & TK_TOP_LEVEL)) {
  829. Tcl_Panic("Tk_MoveToplevelWindow called with non-toplevel window");
  830.     }
  831.     wmPtr->x = x;
  832.     wmPtr->y = y;
  833.     wmPtr->flags |= WM_MOVE_PENDING;
  834.     wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y);
  835.     if ((wmPtr->sizeHintsFlags & (USPosition|PPosition)) == 0) {
  836. wmPtr->sizeHintsFlags |= USPosition;
  837. wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
  838.     }
  839.     /*
  840.      * If the window has already been mapped, must bring its geometry
  841.      * up-to-date immediately, otherwise an event might arrive from the
  842.      * server that would overwrite wmPtr->x and wmPtr->y and lose the
  843.      * new position.
  844.      */
  845.     if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
  846. if (wmPtr->flags & WM_UPDATE_PENDING) {
  847.     Tk_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
  848. }
  849. UpdateGeometryInfo((ClientData) winPtr);
  850.     }
  851. }
  852. /*
  853.  *----------------------------------------------------------------------
  854.  *
  855.  * TkWmRestackToplevel --
  856.  *
  857.  * This procedure restacks a top-level window.
  858.  *
  859.  * Results:
  860.  * None.
  861.  *
  862.  * Side effects:
  863.  * WinPtr gets restacked  as specified by aboveBelow and otherPtr.
  864.  * This procedure doesn't return until the restack has taken
  865.  * effect and the ConfigureNotify event for it has been received.
  866.  *
  867.  *----------------------------------------------------------------------
  868.  */
  869. void
  870. TkWmRestackToplevel(
  871.     TkWindow *winPtr, /* Window to restack. */
  872.     int aboveBelow, /* Gives relative position for restacking;
  873.  * must be Above or Below. */
  874.     TkWindow *otherPtr) /* Window relative to which to restack;
  875.  * if NULL, then winPtr gets restacked
  876.  * above or below *all* siblings. */
  877. {
  878.     WmInfo *wmPtr;
  879.     WindowRef macWindow, otherMacWindow, frontWindow, tmpWindow;
  880.     wmPtr = winPtr->wmInfoPtr;
  881.     /*
  882.      * Get the mac window. Make sure it exists & is mapped.
  883.      */
  884.     if (winPtr->window == None) {
  885. Tk_MakeWindowExist((Tk_Window) winPtr);
  886.     }
  887.     if (winPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) {
  888. /*
  889.  * Can't set stacking order properly until the window is on the
  890.  * screen (mapping it may give it a reparent window), so make sure
  891.  * it's on the screen.
  892.  */
  893. TkWmMapWindow(winPtr);
  894.     }
  895.     macWindow = TkMacOSXDrawableWindow(winPtr->window);
  896.     /*
  897.      * Get the window in which a raise or lower is in relation to.
  898.      */
  899.     if (otherPtr != NULL) {
  900. if (otherPtr->window == None) {
  901.     Tk_MakeWindowExist((Tk_Window) otherPtr);
  902. }
  903. if (otherPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) {
  904.     TkWmMapWindow(otherPtr);
  905. }
  906. otherMacWindow = TkMacOSXDrawableWindow(otherPtr->window);
  907.     } else {
  908. otherMacWindow = NULL;
  909.     }
  910.     frontWindow = ActiveNonFloatingWindow();
  911.     if (aboveBelow == Above) {
  912. if (macWindow == frontWindow) {
  913.     /*
  914.      * Do nothing - it's already at the top.
  915.      */
  916. } else if (otherMacWindow == frontWindow || otherMacWindow == NULL) {
  917.     /*
  918.      * Raise the window to the top. If the window is visible then
  919.      * we also make it the active window.
  920.      */
  921.     if (wmPtr->hints.initial_state == WithdrawnState) {
  922. BringToFront(macWindow);
  923.     } else {
  924. SelectWindow(macWindow);
  925.     }
  926. } else {
  927.     /*
  928.      * Find the window to be above. (Front window will actually be the
  929.      * window to be behind.) Front window is NULL if no other windows.
  930.      */
  931.     while (frontWindow != NULL &&
  932.     (tmpWindow=GetNextWindow(frontWindow)) != otherMacWindow) {
  933. frontWindow = tmpWindow;
  934.     }
  935.     if (frontWindow != NULL) {
  936. SendBehind(macWindow, frontWindow);
  937.     }
  938. }
  939.     } else {
  940. /*
  941.  * Send behind. If it was in front find another window to make active.
  942.  */
  943. if (macWindow == frontWindow) {
  944.     tmpWindow = GetNextWindow(macWindow);
  945.     if (tmpWindow != NULL) {
  946. SelectWindow(tmpWindow);
  947.     }
  948. }
  949. SendBehind(macWindow, otherMacWindow);
  950.     }
  951. }
  952. /*
  953.  *----------------------------------------------------------------------
  954.  *
  955.  * TkWmAddToColormapWindows --
  956.  *
  957.  * This procedure is called to add a given window to the
  958.  * WM_COLORMAP_WINDOWS property for its top-level, if it
  959.  * isn't already there. It is invoked by the Tk code that
  960.  * creates a new colormap, in order to make sure that colormap
  961.  * information is propagated to the window manager by default.
  962.  *
  963.  * Results:
  964.  * None.
  965.  *
  966.  * Side effects:
  967.  * WinPtr's window gets added to the WM_COLORMAP_WINDOWS
  968.  * property of its nearest top-level ancestor, unless the
  969.  * colormaps have been set explicitly with the
  970.  * "wm colormapwindows" command.
  971.  *
  972.  *----------------------------------------------------------------------
  973.  */
  974. void
  975. TkWmAddToColormapWindows(
  976.     TkWindow *winPtr) /* Window with a non-default colormap.
  977.  * Should not be a top-level window. */
  978. {
  979.     TkWindow *topPtr;
  980.     TkWindow **oldPtr, **newPtr;
  981.     int count, i;
  982.     if (winPtr->window == None) {
  983. return;
  984.     }
  985.     for (topPtr = winPtr->parentPtr; ; topPtr = topPtr->parentPtr) {
  986. if (topPtr == NULL) {
  987.     /*
  988.      * Window is being deleted. Skip the whole operation.
  989.      */
  990.     return;
  991. }
  992. if (topPtr->flags & TK_TOP_LEVEL) {
  993.     break;
  994. }
  995.     }
  996.     if (topPtr->wmInfoPtr->flags & WM_COLORMAPS_EXPLICIT) {
  997. return;
  998.     }
  999.     /*
  1000.      * Make sure that the window isn't already in the list.
  1001.      */
  1002.     count = topPtr->wmInfoPtr->cmapCount;
  1003.     oldPtr = topPtr->wmInfoPtr->cmapList;
  1004.     for (i = 0; i < count; i++) {
  1005. if (oldPtr[i] == winPtr) {
  1006.     return;
  1007. }
  1008.     }
  1009.     /*
  1010.      * Make a new bigger array and use it to reset the property.
  1011.      * Automatically add the toplevel itself as the last element
  1012.      * of the list.
  1013.      */
  1014.     newPtr = (TkWindow **) ckalloc((unsigned) ((count+2)*sizeof(TkWindow*)));
  1015.     if (count > 0) {
  1016. memcpy(newPtr, oldPtr, count * sizeof(TkWindow*));
  1017.     }
  1018.     if (count == 0) {
  1019. count++;
  1020.     }
  1021.     newPtr[count-1] = winPtr;
  1022.     newPtr[count] = topPtr;
  1023.     if (oldPtr != NULL) {
  1024. ckfree((char *) oldPtr);
  1025.     }
  1026.     topPtr->wmInfoPtr->cmapList = newPtr;
  1027.     topPtr->wmInfoPtr->cmapCount = count+1;
  1028.     /*
  1029.      * On the Macintosh all of this is just an excercise
  1030.      * in compatability as we don't support colormaps. If
  1031.      * we did they would be installed here.
  1032.      */
  1033. }
  1034. /*
  1035.  *----------------------------------------------------------------------
  1036.  *
  1037.  * TkWmRemoveFromColormapWindows --
  1038.  *
  1039.  * This procedure is called to remove a given window from the
  1040.  * WM_COLORMAP_WINDOWS property for its top-level. It is invoked
  1041.  * when windows are deleted.
  1042.  *
  1043.  * Results:
  1044.  * None.
  1045.  *
  1046.  * Side effects:
  1047.  * WinPtr's window gets removed from the WM_COLORMAP_WINDOWS
  1048.  * property of its nearest top-level ancestor, unless the
  1049.  * top-level itself is being deleted too.
  1050.  *
  1051.  *----------------------------------------------------------------------
  1052.  */
  1053. void
  1054. TkWmRemoveFromColormapWindows(
  1055.     TkWindow *winPtr) /* Window that may be present in
  1056.  * WM_COLORMAP_WINDOWS property for its
  1057.  * top-level. Should not be a top-level
  1058.  * window. */
  1059. {
  1060.     TkWindow *topPtr, **oldPtr;
  1061.     int count, i, j;
  1062.     for (topPtr = winPtr->parentPtr; ; topPtr = topPtr->parentPtr) {
  1063. if (topPtr == NULL) {
  1064.     /*
  1065.      * Ancestors have been deleted, so skip the whole operation.
  1066.      * Seems like this can't ever happen?
  1067.      */
  1068.     return;
  1069. }
  1070. if (topPtr->flags & TK_TOP_LEVEL) {
  1071.     break;
  1072. }
  1073.     }
  1074.     if (topPtr->flags & TK_ALREADY_DEAD) {
  1075. /*
  1076.  * Top-level is being deleted, so there's no need to cleanup
  1077.  * the WM_COLORMAP_WINDOWS property.
  1078.  */
  1079. return;
  1080.     }
  1081.     /*
  1082.      * Find the window and slide the following ones down to cover
  1083.      * it up.
  1084.      */
  1085.     count = topPtr->wmInfoPtr->cmapCount;
  1086.     oldPtr = topPtr->wmInfoPtr->cmapList;
  1087.     for (i = 0; i < count; i++) {
  1088. if (oldPtr[i] == winPtr) {
  1089.     for (j = i ; j < count-1; j++) {
  1090. oldPtr[j] = oldPtr[j+1];
  1091.     }
  1092.     topPtr->wmInfoPtr->cmapCount = count - 1;
  1093.     break;
  1094. }
  1095.     }
  1096. }
  1097. /*
  1098.  *----------------------------------------------------------------------
  1099.  *
  1100.  * TkGetPointerCoords --
  1101.  *
  1102.  * Fetch the position of the mouse pointer.
  1103.  *
  1104.  * Results:
  1105.  * *xPtr and *yPtr are filled in with the (virtual) root coordinates
  1106.  * of the mouse pointer for tkwin's display. If the pointer isn't
  1107.  * on tkwin's screen, then -1 values are returned for both
  1108.  * coordinates. The argument tkwin must be a toplevel window.
  1109.  *
  1110.  * Side effects:
  1111.  * None.
  1112.  *
  1113.  *----------------------------------------------------------------------
  1114.  */
  1115. void
  1116. TkGetPointerCoords(
  1117.     Tk_Window tkwin, /* Toplevel window that identifies screen
  1118.  * on which lookup is to be done. */
  1119.     int *xPtr, int *yPtr) /* Store pointer coordinates here. */
  1120. {
  1121.     XQueryPointer(NULL, None, NULL, NULL, xPtr, yPtr, NULL, NULL, NULL);
  1122. }
  1123. /*
  1124.  *----------------------------------------------------------------------
  1125.  *
  1126.  * InitialWindowBounds --
  1127.  *
  1128.  * This function calculates the initial bounds for a new Mac
  1129.  * toplevel window. Unless the geometry is specified by the user
  1130.  * this code will auto place the windows in a cascade diagonially
  1131.  * across the main monitor of the Mac.
  1132.  *
  1133.  * Results:
  1134.  * The bounds are returned in geometry.
  1135.  *
  1136.  * Side effects:
  1137.  * None.
  1138.  *
  1139.  *----------------------------------------------------------------------
  1140.  */
  1141. static void
  1142. InitialWindowBounds(
  1143.     TkWindow *winPtr, /* Window to get initial bounds for. */
  1144.     WindowRef macWindow,
  1145.     Rect *geometry) /* On return the initial bounds. */
  1146. {
  1147.     WmInfo *wmPtr = winPtr->wmInfoPtr;
  1148.     if (!(wmPtr->sizeHintsFlags & (USPosition | PPosition))) {
  1149. WindowRef parent;
  1150. parent = GetFrontWindowOfClass(wmPtr->macClass, false);
  1151. if (parent && parent == macWindow) {
  1152.     parent = GetNextWindowOfClass(parent, wmPtr->macClass, false);
  1153. }
  1154. if (parent && parent != macWindow) {
  1155.     Rect bounds;
  1156.     ChkErr(RepositionWindow, macWindow, parent,
  1157.     kWindowCascadeOnParentWindowScreen);
  1158.     ChkErr(GetWindowBounds, macWindow, kWindowStructureRgn, &bounds);
  1159.     wmPtr->x = bounds.left;
  1160.     wmPtr->y = bounds.top;
  1161. } else {
  1162.     static SInt16 menuBarHeight = 0;
  1163.     if (!menuBarHeight) {
  1164. ChkErr(GetThemeMenuBarHeight, &menuBarHeight);
  1165.     }
  1166.     wmPtr->x = 5;
  1167.     wmPtr->y = menuBarHeight + 5;
  1168. }
  1169.     }
  1170.     geometry->left = wmPtr->x;
  1171.     geometry->top = wmPtr->y;
  1172.     geometry->right = wmPtr->x + winPtr->changes.width;
  1173.     geometry->bottom = wmPtr->y + winPtr->changes.height;
  1174. }
  1175. /*
  1176.  *----------------------------------------------------------------------
  1177.  *
  1178.  * TkMacOSXResizable --
  1179.  *
  1180.  * This function determines if the passed in window is part of
  1181.  * a toplevel window that is resizable. If the window is
  1182.  * resizable in the x, y or both directions, true is returned.
  1183.  *
  1184.  * Results:
  1185.  * True if resizable, false otherwise.
  1186.  *
  1187.  * Side effects:
  1188.  * None.
  1189.  *
  1190.  *----------------------------------------------------------------------
  1191.  */
  1192. int
  1193. TkMacOSXResizable(
  1194.     TkWindow *winPtr) /* Tk window or NULL. */
  1195. {
  1196.     WmInfo *wmPtr;
  1197.     if (winPtr == NULL) {
  1198. return false;
  1199.     }
  1200.     while (winPtr->wmInfoPtr == NULL) {
  1201. winPtr = winPtr->parentPtr;
  1202.     }
  1203.     wmPtr = winPtr->wmInfoPtr;
  1204.     if ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) &&
  1205.     (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE)) {
  1206. return false;
  1207.     } else {
  1208. return true;
  1209.     }
  1210. }
  1211. /*
  1212.  *----------------------------------------------------------------------
  1213.  *
  1214.  * TkMacOSXGrowToplevel --
  1215.  *
  1216.  * The function is invoked when the user clicks in the grow region
  1217.  * of a Tk window. The function will handle the dragging
  1218.  * procedure and not return until completed. Finally, the function
  1219.  * may place information Tk's event queue is the window was resized.
  1220.  *
  1221.  * Results:
  1222.  * True if events were placed on event queue, false otherwise.
  1223.  *
  1224.  * Side effects:
  1225.  * None.
  1226.  *
  1227.  *----------------------------------------------------------------------
  1228.  */
  1229. int
  1230. TkMacOSXGrowToplevel(
  1231.     WindowRef whichWindow,
  1232.     Point start)
  1233. {
  1234.     Point where = start;
  1235.     TkDisplay *dispPtr;
  1236.     Rect portRect;
  1237.     CGrafPtr destPort = GetWindowPort(whichWindow);
  1238.     QDGlobalToLocalPoint(destPort, &where);
  1239.     GetPortBounds(destPort, &portRect);
  1240.     if (where.h > (portRect.right - 16) &&
  1241.     where.v > (portRect.bottom - 16)) {
  1242. Window window;
  1243. TkWindow *winPtr;
  1244. WmInfo *wmPtr;
  1245. int minWidth, minHeight, maxWidth, maxHeight;
  1246. Rect limits, bounds, *maxBounds;
  1247. Boolean resizeResult;
  1248. window = TkMacOSXGetXWindow(whichWindow);
  1249. dispPtr = TkGetDisplayList();
  1250. winPtr = (TkWindow *) Tk_IdToWindow(dispPtr->display, window);
  1251. wmPtr = winPtr->wmInfoPtr;
  1252. maxBounds = (Rect*)(dispPtr->display->screens->ext_data);
  1253. if ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) &&
  1254. (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE)) {
  1255.     return false;
  1256. }
  1257. GetMinSize(winPtr, &minWidth, &minHeight);
  1258. GetMaxSize(winPtr, &maxWidth, &maxHeight);
  1259. if (wmPtr->gridWin != NULL) {
  1260.     int base = winPtr->reqWidth - (wmPtr->reqGridWidth
  1261.     * wmPtr->widthInc);
  1262.     if (base < 0) {
  1263. base = 0;
  1264.     }
  1265.     limits.left  = base + (minWidth * wmPtr->widthInc);
  1266.     limits.right = base + (maxWidth * wmPtr->widthInc);
  1267.     base = winPtr->reqHeight - (wmPtr->reqGridHeight
  1268.     * wmPtr->heightInc);
  1269.     if (base < 0) {
  1270. base = 0;
  1271.     }
  1272.     limits.top   = base + (minHeight * wmPtr->heightInc);
  1273.     limits.bottom = base + (maxHeight * wmPtr->heightInc);
  1274. } else {
  1275.     limits.left = minWidth;
  1276.     limits.right = maxWidth;
  1277.     limits.top = minHeight;
  1278.     limits.bottom = maxHeight;
  1279. }
  1280. if (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) {
  1281.     limits.left = limits.right = winPtr->changes.width;
  1282. }
  1283. if (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) {
  1284.     limits.top = limits.bottom = winPtr->changes.height;
  1285. }
  1286. if (PtInRect(start, maxBounds)) {
  1287.     Rect strBounds, strWidths, limitBounds;
  1288.     ChkErr(GetWindowBounds, whichWindow, kWindowStructureRgn,
  1289.     &strBounds);
  1290.     ChkErr(GetWindowStructureWidths, whichWindow, &strWidths);
  1291.     limitBounds.left = limits.left + (strBounds.left + strWidths.left);
  1292.     limitBounds.right = limits.right +
  1293.     (strBounds.left + strWidths.left + strWidths.right);
  1294.     limitBounds.top = limits.top + (strBounds.top + strWidths.top);
  1295.     limitBounds.bottom = limits.bottom +
  1296.     (strBounds.top + strWidths.top + strWidths.bottom);
  1297.     if (limitBounds.left < maxBounds->left) {
  1298. limitBounds.left = maxBounds->left;
  1299.     }
  1300.     if (limitBounds.right > maxBounds->right) {
  1301. limitBounds.right = maxBounds->right;
  1302.     }
  1303.     if (limitBounds.top < maxBounds->top) {
  1304. limitBounds.top = maxBounds->top;
  1305.     }
  1306.     if (limitBounds.bottom > maxBounds->bottom) {
  1307. limitBounds.bottom = maxBounds->bottom;
  1308.     }
  1309.     limits.left = limitBounds.left - (strBounds.left + strWidths.left);
  1310.     limits.right = limitBounds.right -
  1311.     (strBounds.left + strWidths.left + strWidths.right);
  1312.     limits.top = limitBounds.top - (strBounds.top + strWidths.top);
  1313.     limits.bottom = limitBounds.bottom -
  1314.     (strBounds.top + strWidths.top + strWidths.bottom);
  1315. }
  1316. TkMacOSXTrackingLoop(1);
  1317. resizeResult = ResizeWindow(whichWindow, start, &limits, &bounds);
  1318. TkMacOSXTrackingLoop(0);
  1319. if (resizeResult) {
  1320.     return true;
  1321. }
  1322.     }
  1323.     return false;
  1324. }
  1325. /*
  1326.  *----------------------------------------------------------------------
  1327.  *
  1328.  * TkSetWMName --
  1329.  *
  1330.  * Set the title for a toplevel window. If the window is embedded,
  1331.  * do not change the window title.
  1332.  *
  1333.  * Results:
  1334.  * None.
  1335.  *
  1336.  * Side effects:
  1337.  * The title of the window is changed.
  1338.  *
  1339.  *----------------------------------------------------------------------
  1340.  */
  1341. void
  1342. TkSetWMName(
  1343.     TkWindow *winPtr,
  1344.     Tk_Uid titleUid)
  1345. {
  1346.     CFStringRef title;
  1347.     if (Tk_IsEmbedded(winPtr)) {
  1348. return;
  1349.     }
  1350.     title = CFStringCreateWithBytes(NULL, (const unsigned char*) titleUid,
  1351.     strlen(titleUid), kCFStringEncodingUTF8, false);
  1352.     if (title) {
  1353. WindowRef macWin = TkMacOSXDrawableWindow(winPtr->window);
  1354. SetWindowTitleWithCFString(macWin, title);
  1355. CFRelease(title);
  1356.     }
  1357. }
  1358. /*
  1359.  *----------------------------------------------------------------------
  1360.  *
  1361.  * TkGetTransientMaster --
  1362.  *
  1363.  * If the passed window has the TRANSIENT_FOR property set this
  1364.  * will return the master window. Otherwise it will return None.
  1365.  *
  1366.  * Results:
  1367.  * The master window or None.
  1368.  *
  1369.  * Side effects:
  1370.  * None.
  1371.  *
  1372.  *----------------------------------------------------------------------
  1373.  */
  1374. Window
  1375. TkGetTransientMaster(
  1376.     TkWindow *winPtr)
  1377. {
  1378.     if (winPtr->wmInfoPtr != NULL) {
  1379. return winPtr->wmInfoPtr->master;
  1380.     }
  1381.     return None;
  1382. }
  1383. /*
  1384.  *----------------------------------------------------------------------
  1385.  *
  1386.  * TkMacOSXGetXWindow --
  1387.  *
  1388.  * Returns the X window Id associated with the given WindowRef.
  1389.  *
  1390.  * Results:
  1391.  * The window id is returned. None is returned if not a Tk window.
  1392.  *
  1393.  * Side effects:
  1394.  * None.
  1395.  *
  1396.  *----------------------------------------------------------------------
  1397.  */
  1398. Window
  1399. TkMacOSXGetXWindow(
  1400.     WindowRef macWinPtr)
  1401. {
  1402.     Tcl_HashEntry *hPtr;
  1403.     if ((macWinPtr == NULL) || !windowHashInit) {
  1404. return None;
  1405.     }
  1406.     hPtr = Tcl_FindHashEntry(&windowTable, (char *) macWinPtr);
  1407.     if (hPtr == NULL) {
  1408. return None;
  1409.     }
  1410.     return (Window) Tcl_GetHashValue(hPtr);
  1411. }
  1412. /*
  1413.  *----------------------------------------------------------------------
  1414.  *
  1415.  * TkMacOSXIsWindowZoomed --
  1416.  *
  1417.  * Ask Carbon if the given window is in the zoomed out state.
  1418.  * Because dragging & growing a window can change the Carbon
  1419.  * zoom state, we cannot rely on wmInfoPtr->hints.initial_state
  1420.  * for this information.
  1421.  *
  1422.  * Results:
  1423.  * True if window is zoomed out, false otherwise.
  1424.  *
  1425.  * Side effects:
  1426.  * None.
  1427.  *
  1428.  *----------------------------------------------------------------------
  1429.  */
  1430. MODULE_SCOPE int
  1431. TkMacOSXIsWindowZoomed(
  1432.     TkWindow *winPtr)
  1433. {
  1434.     WmInfo *wmPtr = winPtr->wmInfoPtr;
  1435.     int maxWidth, maxHeight;
  1436.     Point idealSize;
  1437.     if ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) &&
  1438.     (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE)) {
  1439. return false;
  1440.     }
  1441.     GetMaxSize(winPtr, &maxWidth, &maxHeight);
  1442.     if (wmPtr->gridWin != NULL) {
  1443. int base = winPtr->reqWidth - (wmPtr->reqGridWidth * wmPtr->widthInc);
  1444. if (base < 0) {
  1445.     base = 0;
  1446. }
  1447. maxWidth = base + (maxWidth * wmPtr->widthInc);
  1448. base = winPtr->reqHeight - (wmPtr->reqGridHeight * wmPtr->heightInc);
  1449. if (base < 0) {
  1450.     base = 0;
  1451. }
  1452. maxHeight = base + (maxHeight * wmPtr->heightInc);
  1453.     }
  1454.     if (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) {
  1455. idealSize.h = winPtr->changes.width;
  1456.     } else {
  1457. idealSize.h = maxWidth;
  1458.     }
  1459.     if (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) {
  1460. idealSize.v = winPtr->changes.height;
  1461.     } else {
  1462. idealSize.v = maxHeight;
  1463.     }
  1464.     return IsWindowInStandardState(TkMacOSXDrawableWindow(winPtr->window),
  1465.     &idealSize, NULL);
  1466. }
  1467. /*
  1468.  *----------------------------------------------------------------------
  1469.  *
  1470.  * TkMacOSXZoomToplevel --
  1471.  *
  1472.  * The function is invoked when the user clicks in the zoom region
  1473.  * of a Tk window or when the window state is set/unset to "zoomed"
  1474.  * manually. If the window is to be zoomed (in or out), the window
  1475.  * size is changed and events are generated to let Tk know what
  1476.  * happened.
  1477.  *
  1478.  * Results:
  1479.  * True if events were placed on event queue, false otherwise.
  1480.  *
  1481.  * Side effects:
  1482.  * The window may be resized & events placed on Tk's queue.
  1483.  *
  1484.  *----------------------------------------------------------------------
  1485.  */
  1486. int
  1487. TkMacOSXZoomToplevel(
  1488.     WindowRef whichWindow, /* The Macintosh window to zoom. */
  1489.     short zoomPart) /* Either inZoomIn or inZoomOut */
  1490. {
  1491.     Window window;
  1492.     TkDisplay *dispPtr;
  1493.     TkWindow *winPtr;
  1494.     WmInfo *wmPtr;
  1495.     Point idealSize;
  1496.     int maxWidth, maxHeight;
  1497.     OSStatus err;
  1498.     window = TkMacOSXGetXWindow(whichWindow);
  1499.     dispPtr = TkGetDisplayList();
  1500.     winPtr = (TkWindow *) Tk_IdToWindow(dispPtr->display, window);
  1501.     wmPtr = winPtr->wmInfoPtr;
  1502.     if ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) &&
  1503.     (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE)) {
  1504. return false;
  1505.     }
  1506.     GetMaxSize(winPtr, &maxWidth, &maxHeight);
  1507.     if (wmPtr->gridWin != NULL) {
  1508. int base = winPtr->reqWidth - (wmPtr->reqGridWidth * wmPtr->widthInc);
  1509. if (base < 0) {
  1510.     base = 0;
  1511. }
  1512. maxWidth = base + (maxWidth * wmPtr->widthInc);
  1513. base = winPtr->reqHeight - (wmPtr->reqGridHeight * wmPtr->heightInc);
  1514. if (base < 0) {
  1515.     base = 0;
  1516. }
  1517. maxHeight = base + (maxHeight * wmPtr->heightInc);
  1518.     }
  1519.     if (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) {
  1520. idealSize.h = winPtr->changes.width;
  1521.     } else {
  1522. idealSize.h = maxWidth;
  1523.     }
  1524.     if (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) {
  1525. idealSize.v = winPtr->changes.height;
  1526.     } else {
  1527. idealSize.v = maxHeight;
  1528.     }
  1529.     /* Do nothing if already in desired zoom state */
  1530.     if (!IsWindowInStandardState(whichWindow, &idealSize, NULL) ==
  1531.     (zoomPart == inZoomIn)) {
  1532. return false;
  1533.     }
  1534.     err = ChkErr(ZoomWindowIdeal, whichWindow, zoomPart, &idealSize);
  1535.     if (err == noErr) {
  1536. wmPtr->hints.initial_state =
  1537. (zoomPart == inZoomIn ? NormalState : ZoomState);
  1538. return true;
  1539.     } else {
  1540. return false;
  1541.     }
  1542. }
  1543. /*
  1544.  *----------------------------------------------------------------------
  1545.  *
  1546.  * TkUnsupported1Cmd --
  1547.  *
  1548.  * This procedure is invoked to process the
  1549.  * "::tk::unsupported::MacWindowStyle" Tcl command.
  1550.  * This command allows you to set the style of decoration
  1551.  * for a Macintosh window.
  1552.  *
  1553.  * Results:
  1554.  * A standard Tcl result.
  1555.  *
  1556.  * Side effects:
  1557.  * Changes the style of a new Mac window.
  1558.  *
  1559.  *----------------------------------------------------------------------
  1560.  */
  1561. /* ARGSUSED */
  1562. int
  1563. TkUnsupported1ObjCmd(
  1564.     ClientData clientData, /* Main window associated with
  1565.  * interpreter. */
  1566.     Tcl_Interp *interp, /* Current interpreter. */
  1567.     int objc, /* Number of arguments. */
  1568.     Tcl_Obj * const objv[]) /* Argument objects. */
  1569. {
  1570.     static const char *subcmds[] = {
  1571. "style", NULL
  1572.     };
  1573.     enum SubCmds {
  1574. TKMWS_STYLE
  1575.     };
  1576.     Tk_Window tkwin = (Tk_Window) clientData;
  1577.     TkWindow *winPtr;
  1578.     int index;
  1579.     if (objc < 3) {
  1580. Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?");
  1581. return TCL_ERROR;
  1582.     }
  1583.     winPtr = (TkWindow *) Tk_NameToWindow(interp,
  1584.     Tcl_GetString(objv[2]), tkwin);
  1585.     if (winPtr == NULL) {
  1586. return TCL_ERROR;
  1587.     }
  1588.     if (!(winPtr->flags & TK_TOP_LEVEL)) {
  1589. Tcl_ResetResult(interp);
  1590. Tcl_AppendResult(interp, "window "", winPtr->pathName,
  1591. "" isn't a top-level window", NULL);
  1592. return TCL_ERROR;
  1593.     }
  1594.     if (Tcl_GetIndexFromObj(interp, objv[1], subcmds, "option",
  1595. 0, &index) != TCL_OK) {
  1596. return TCL_ERROR;
  1597.     }
  1598.     if (((enum SubCmds) index) == TKMWS_STYLE) {
  1599. if ((objc < 3) || (objc > 5)) {
  1600.     Tcl_WrongNumArgs(interp, 2, objv, "window ?class attributes?");
  1601.     return TCL_ERROR;
  1602. }
  1603. return WmWinStyle(interp, winPtr, objc, objv);
  1604.     }
  1605.     /* won't be reached */
  1606.     return TCL_ERROR;
  1607. }
  1608. /*
  1609.  *----------------------------------------------------------------------
  1610.  *
  1611.  * WmWinStyle --
  1612.  *
  1613.  * This procedure is invoked to process the
  1614.  * "::tk::unsupported::MacWindowStyle style" subcommand.
  1615.  * This command allows you to set the style of decoration
  1616.  * for a Macintosh window.
  1617.  *
  1618.  * Results:
  1619.  * A standard Tcl result.
  1620.  *
  1621.  * Side effects:
  1622.  * Changes the style of a new Mac window.
  1623.  *
  1624.  *----------------------------------------------------------------------
  1625.  */
  1626. static int
  1627. WmWinStyle(
  1628.     Tcl_Interp *interp, /* Current interpreter. */
  1629.     TkWindow *winPtr, /* Window to be manipulated. */
  1630.     int objc, /* Number of arguments. */
  1631.     Tcl_Obj * const objv[]) /* Argument objects. */
  1632. {
  1633.     struct StrIntMap {
  1634. const char *strValue;
  1635. UInt32 intValue;
  1636.     };
  1637.     static const struct StrIntMap styleMap[] = {
  1638. { "documentProc",     documentProc },
  1639. { "noGrowDocProc",     documentProc },
  1640. { "dBoxProc",     dBoxProc },
  1641. { "plainDBox",     plainDBox },
  1642. { "altDBoxProc",     altDBoxProc },
  1643. { "movableDBoxProc",     movableDBoxProc },
  1644. { "zoomDocProc",     zoomDocProc },
  1645. { "zoomNoGrow",     zoomNoGrow },
  1646. { "floatProc",     floatGrowProc },
  1647. { "floatGrowProc",     floatGrowProc },
  1648. { "floatZoomProc",     floatZoomGrowProc },
  1649. { "floatZoomGrowProc",     floatZoomGrowProc },
  1650. { "floatSideProc",     floatSideGrowProc },
  1651. { "floatSideGrowProc",     floatSideGrowProc },
  1652. { "floatSideZoomProc",     floatSideZoomGrowProc },
  1653. { "floatSideZoomGrowProc",  floatSideZoomGrowProc },
  1654. { NULL,     0 }
  1655.     };
  1656.     static const struct StrIntMap classMap[] = {
  1657. { "alert",     kAlertWindowClass },
  1658. { "moveableAlert",  kMovableAlertWindowClass },
  1659. { "modal",     kModalWindowClass },
  1660. { "moveableModal",  kMovableModalWindowClass },
  1661. { "floating",     kFloatingWindowClass },
  1662. { "document",     kDocumentWindowClass },
  1663. { "utility",     kUtilityWindowClass },
  1664. { "help",     kHelpWindowClass },
  1665. { "sheet",     kSheetWindowClass },
  1666. { "toolbar",     kToolbarWindowClass },
  1667. { "plain",     kPlainWindowClass },
  1668. { "overlay",     kOverlayWindowClass },
  1669. { "sheetAlert",     kSheetAlertWindowClass },
  1670. { "altPlain",     kAltPlainWindowClass },
  1671. { "simple",     kSimpleWindowClass },
  1672. { "drawer",     kDrawerWindowClass },
  1673. { NULL,     0 }
  1674.     };
  1675.     static const struct StrIntMap compositeAttrMap[] = {
  1676. { "none", kWindowNoAttributes },
  1677. { "standardDocument", kWindowStandardDocumentAttributes },
  1678. { "standardFloating", kWindowStandardFloatingAttributes },
  1679. { "fullZoom", kWindowFullZoomAttribute },
  1680. { NULL, 0 }
  1681.     };
  1682.     static const struct StrIntMap attrMap[] = {
  1683. { "closeBox", kWindowCloseBoxAttribute      },
  1684. { "horizontalZoom", kWindowHorizontalZoomAttribute      },
  1685. { "verticalZoom", kWindowVerticalZoomAttribute      },
  1686. { "collapseBox", kWindowCollapseBoxAttribute      },
  1687. { "resizable", kWindowResizableAttribute      },
  1688. { "sideTitlebar", kWindowSideTitlebarAttribute      },
  1689. { "toolbarButton", kWindowToolbarButtonAttribute      },
  1690. { "unifiedTitleAndToolbar", kWindowUnifiedTitleAndToolbarAttribute   },
  1691. { "metal", kWindowMetalAttribute      },
  1692. { "noTitleBar", kWindowNoTitleBarAttribute      },
  1693. { "texturedSquareCorners", kWindowTexturedSquareCornersAttribute     },
  1694. { "metalNoContentSeparator", kWindowMetalNoContentSeparatorAttribute },
  1695. { "doesNotCycle", kWindowDoesNotCycleAttribute      },
  1696. { "noUpdates", kWindowNoUpdatesAttribute      },
  1697. { "noActivates", kWindowNoActivatesAttribute      },
  1698. { "opaqueForEvents", kWindowOpaqueForEventsAttribute      },
  1699. { "noShadow", kWindowNoShadowAttribute      },
  1700. { "hideOnSuspend", kWindowHideOnSuspendAttribute      },
  1701. { "hideOnFullScreen", kWindowHideOnFullScreenAttribute      },
  1702. { "inWindowMenu", kWindowInWindowMenuAttribute      },
  1703. { "liveResize", kWindowLiveResizeAttribute      },
  1704. { "ignoreClicks", kWindowIgnoreClicksAttribute      },
  1705. { "noConstrain", kWindowNoConstrainAttribute      },
  1706. { NULL, 0      }
  1707.     };
  1708.     int index, i;
  1709.     WmInfo *wmPtr = winPtr->wmInfoPtr;
  1710.     if (objc == 3) {
  1711. if (wmPtr->style != -1) {
  1712.     for (i = 0; styleMap[i].strValue != NULL; i++) {
  1713. if (wmPtr->style == (short)(styleMap[i].intValue)) {
  1714.     Tcl_SetObjResult(interp,
  1715.     Tcl_NewStringObj(styleMap[i].strValue, -1));
  1716.     return TCL_OK;
  1717. }
  1718.     }
  1719.     Tcl_Panic("invalid style");
  1720. } else {
  1721.     Tcl_Obj *attributeList, *newResult = NULL;
  1722.     WindowAttributes attributes;
  1723.     for (i = 0; classMap[i].strValue != NULL; i++) {
  1724. if (wmPtr->macClass == classMap[i].intValue) {
  1725.     newResult = Tcl_NewStringObj(classMap[i].strValue, -1);
  1726.     break;
  1727. }
  1728.     }
  1729.     if (newResult == NULL) {
  1730. Tcl_Panic("invalid class");
  1731.     }
  1732.     attributeList = Tcl_NewListObj(0, NULL);
  1733.     attributes = wmPtr->attributes;
  1734.     for (i = 0; compositeAttrMap[i].strValue != NULL; i++) {
  1735. UInt32 intValue = compositeAttrMap[i].intValue;
  1736. if (intValue && (attributes & intValue) == intValue) {
  1737.     Tcl_ListObjAppendElement(interp, attributeList,
  1738.     Tcl_NewStringObj(compositeAttrMap[i].strValue,
  1739.     -1));
  1740.     attributes &= ~intValue;
  1741.     break;
  1742. }
  1743.     }
  1744.     for (i = 0; attrMap[i].strValue != NULL; i++) {
  1745. if (attributes & attrMap[i].intValue) {
  1746.     Tcl_ListObjAppendElement(interp, attributeList,
  1747.     Tcl_NewStringObj(attrMap[i].strValue, -1));
  1748. }
  1749.     }
  1750.     Tcl_ListObjAppendElement(interp, newResult, attributeList);
  1751.     Tcl_SetObjResult(interp, newResult);
  1752. }
  1753.     } else if (objc == 4) {
  1754. if (Tcl_GetIndexFromObjStruct(interp, objv[3], styleMap,
  1755. sizeof(struct StrIntMap), "style", 0, &index) != TCL_OK) {
  1756.     return TCL_ERROR;
  1757. }
  1758. wmPtr->style = styleMap[index].intValue;
  1759.     } else if (objc == 5) {
  1760. int attrObjc;
  1761. Tcl_Obj **attrObjv = NULL;
  1762. WindowClass oldClass = wmPtr->macClass;
  1763. WindowAttributes oldAttributes = wmPtr->attributes;
  1764. if (Tcl_GetIndexFromObjStruct(interp, objv[3], classMap,
  1765. sizeof(struct StrIntMap), "class", 0, &index) != TCL_OK) {
  1766.     goto badClassAttrs;
  1767. }
  1768. wmPtr->macClass = classMap[index].intValue;
  1769. if (!IsValidWindowClass(wmPtr->macClass)) {
  1770.     goto badClassAttrs;
  1771. }
  1772. if (Tcl_ListObjGetElements(interp, objv[4], &attrObjc, &attrObjv)
  1773. != TCL_OK) {
  1774.     goto badClassAttrs;
  1775. }
  1776. wmPtr->attributes = kWindowNoAttributes;
  1777. for (i = 0; i < attrObjc; i++) {
  1778.     if (Tcl_GetIndexFromObjStruct(interp, attrObjv[i],
  1779.     compositeAttrMap, sizeof(struct StrIntMap),
  1780.     "attribute", 0, &index) == TCL_OK) {
  1781. wmPtr->attributes |= compositeAttrMap[index].intValue;
  1782.     } else if (Tcl_GetIndexFromObjStruct(interp, attrObjv[i],
  1783.     attrMap, sizeof(struct StrIntMap),
  1784.     "attribute", 0, &index) == TCL_OK) {
  1785. Tcl_ResetResult(interp);
  1786. wmPtr->attributes |= attrMap[index].intValue;
  1787.     } else {
  1788. goto badClassAttrs;
  1789.     }
  1790. }
  1791. ApplyWindowClassAttributeChanges(winPtr, NULL, oldClass, oldAttributes,
  1792. 0);
  1793. wmPtr->style = -1;
  1794. return TCL_OK;
  1795.     badClassAttrs:
  1796. wmPtr->macClass = oldClass;
  1797. wmPtr->attributes = oldAttributes;
  1798. return TCL_ERROR;
  1799.     }
  1800.     return TCL_OK;
  1801. }
  1802. /*
  1803.  *----------------------------------------------------------------------
  1804.  *
  1805.  * TkpMakeMenuWindow --
  1806.  *
  1807.  * Configure the window to be either a undecorated pull-down
  1808.  * (or pop-up) menu, or as a toplevel floating menu (palette).
  1809.  *
  1810.  * Results:
  1811.  * None.
  1812.  *
  1813.  * Side effects:
  1814.  * Changes the style bit used to create a new Mac toplevel.
  1815.  *
  1816.  *----------------------------------------------------------------------
  1817.  */
  1818. void
  1819. TkpMakeMenuWindow(
  1820.     Tk_Window tkwin, /* New window. */
  1821.     int transient) /* 1 means menu is only posted briefly as
  1822.  * a popup or pulldown or cascade. 0 means
  1823.  * menu is always visible, e.g. as a
  1824.  * floating menu. */
  1825. {
  1826.     TkWindow *winPtr = (TkWindow *) tkwin;
  1827.     if (transient) {
  1828. winPtr->wmInfoPtr->macClass = kSimpleWindowClass;
  1829. winPtr->wmInfoPtr->attributes = kWindowNoActivatesAttribute;
  1830.     } else {
  1831. winPtr->wmInfoPtr->macClass = kFloatingWindowClass;
  1832. winPtr->wmInfoPtr->attributes = kWindowStandardFloatingAttributes;
  1833. winPtr->wmInfoPtr->flags |= WM_WIDTH_NOT_RESIZABLE;
  1834. winPtr->wmInfoPtr->flags |= WM_HEIGHT_NOT_RESIZABLE;
  1835.     }
  1836. }
  1837. /*
  1838.  *----------------------------------------------------------------------
  1839.  *
  1840.  * TkMacOSXMakeRealWindowExist --
  1841.  *
  1842.  * This function finally creates the real Macintosh window that
  1843.  * the Mac actually understands.
  1844.  *
  1845.  * Results:
  1846.  * None.
  1847.  *
  1848.  * Side effects:
  1849.  * A new Macintosh toplevel is created.
  1850.  *
  1851.  *----------------------------------------------------------------------
  1852.  */
  1853. void
  1854. TkMacOSXMakeRealWindowExist(
  1855.     TkWindow *winPtr) /* Tk window. */
  1856. {
  1857.     WmInfo *wmPtr = winPtr->wmInfoPtr;
  1858.     WindowRef newWindow = NULL;
  1859.     ControlRef rootControl = NULL;
  1860.     MacDrawable *macWin;
  1861.     Rect initialBounds = {42, 0, 43, 1}, geometry, strWidths;
  1862.     short structureW, structureH;
  1863.     TkMacOSXWindowList *listPtr;
  1864.     OSStatus err;
  1865.     if (TkMacOSXHostToplevelExists(winPtr)) {
  1866. return;
  1867.     }
  1868.     macWin = (MacDrawable *) winPtr->window;
  1869.     /*
  1870.      * If this is embedded, make sure its container's toplevel exists,
  1871.      * then return...
  1872.      */
  1873.     if (Tk_IsEmbedded(winPtr)) {
  1874. TkWindow *contWinPtr = TkpGetOtherWindow(winPtr);
  1875. if (contWinPtr != NULL) {
  1876.     TkMacOSXMakeRealWindowExist(
  1877.     contWinPtr->privatePtr->toplevel->winPtr);
  1878.     macWin->flags |= TK_HOST_EXISTS;
  1879.     return;
  1880. }
  1881. if (tkMacOSXEmbedHandler == NULL) {
  1882.     Tcl_Panic("TkMacOSXMakeRealWindowExist could not find container");
  1883. }
  1884. if (tkMacOSXEmbedHandler->containerExistProc &&
  1885. tkMacOSXEmbedHandler->containerExistProc((Tk_Window) winPtr) !=
  1886. TCL_OK) {
  1887.     Tcl_Panic("ContainerExistProc could not make container");
  1888. }
  1889. return;
  1890. /*
  1891.  * TODO: Here we should handle out of process embedding.
  1892.  */
  1893.     }
  1894.     if (wmPtr->style == -1) {
  1895. if (!IsValidWindowClass(wmPtr->macClass)) {
  1896.     TkMacOSXDbgMsg("Invalid window class: %ld", wmPtr->macClass);
  1897.     wmPtr->macClass = kPlainWindowClass;
  1898. }
  1899. wmPtr->attributes = (wmPtr->attributes | kWindowAsyncDragAttribute) &
  1900. GetAvailableWindowAttributes(wmPtr->macClass);
  1901. err = ChkErr(CreateNewWindow, wmPtr->macClass, wmPtr->attributes,
  1902. &initialBounds, &newWindow);
  1903. if (err != noErr) {
  1904.     newWindow = NULL;
  1905. }
  1906.     } else {
  1907. TkMacOSXDbgMsg("Window creation via NewCWindow API is deprecated, "
  1908.        "use a window class instead of style %d", wmPtr->style);
  1909. newWindow = NewCWindow(NULL, &initialBounds, "p", false,
  1910. wmPtr->style, (WindowRef) -1, true, 0);
  1911.     }
  1912.     if (newWindow == NULL) {
  1913. Tcl_Panic("couldn't allocate new Mac window");
  1914.     }
  1915.     ChkErr(GetWindowStructureWidths, newWindow, &strWidths);
  1916.     if (wmPtr->macClass == kFloatingWindowClass) {
  1917. /*
  1918.  * Workaround GetWindowStructureWidths() Carbon bug:
  1919.  */
  1920. strWidths.top = 16;
  1921.     }
  1922.     wmPtr->xInParent = strWidths.left;
  1923.     wmPtr->yInParent = strWidths.top;
  1924.     structureW = strWidths.left + strWidths.right;
  1925.     structureH = strWidths.top + strWidths.bottom;
  1926.     wmPtr->parentWidth = winPtr->changes.width + structureW;
  1927.     wmPtr->parentHeight = winPtr->changes.height + structureH;
  1928.     InitialWindowBounds(winPtr, newWindow, &geometry);
  1929.     geometry.right +=  structureW;
  1930.     geometry.bottom += structureH;
  1931.     ChkErr(SetWindowBounds, newWindow, kWindowStructureRgn, &geometry);
  1932.     TkMacOSXInstallWindowCarbonEventHandler(NULL, newWindow);
  1933.     if (ChkErr(CreateRootControl, newWindow, &rootControl) != noErr ) {
  1934. Tcl_Panic("couldn't create root control for new Mac window");
  1935.     }
  1936.     if (wmPtr->attributes & kWindowResizableAttribute) {
  1937. HIViewRef growBoxView;
  1938. err = HIViewFindByID(HIViewGetRoot(newWindow),
  1939. kHIViewWindowGrowBoxID, &growBoxView);
  1940. if (err == noErr && !HIGrowBoxViewIsTransparent(growBoxView)) {
  1941.     ChkErr(HIGrowBoxViewSetTransparent, growBoxView, true);
  1942. }
  1943.     }
  1944.     /*
  1945.      * Add this window to the list of toplevel windows.
  1946.      */
  1947.     listPtr = (TkMacOSXWindowList *) ckalloc(sizeof(TkMacOSXWindowList));
  1948.     listPtr->nextPtr = tkMacOSXWindowListPtr;
  1949.     listPtr->winPtr = winPtr;
  1950.     tkMacOSXWindowListPtr = listPtr;
  1951.     macWin->grafPtr = GetWindowPort(newWindow);
  1952.     macWin->rootControl = rootControl;
  1953.     if (wmPtr->master != None || winPtr->atts.override_redirect) {
  1954. ApplyMasterOverrideChanges(winPtr, newWindow);
  1955.     }
  1956.     SetWindowModified(newWindow, false);
  1957.     TkMacOSXRegisterOffScreenWindow((Window) macWin, (GWorldPtr) newWindow);
  1958.     macWin->flags |= TK_HOST_EXISTS;
  1959.     ChkErr(GetWindowClass, newWindow, &(wmPtr->macClass));
  1960.     ChkErr(GetWindowAttributes, newWindow, &(wmPtr->attributes));
  1961. #ifdef TK_MAC_DEBUG_WINDOWS
  1962.     TkMacOSXInitNamedDebugSymbol(HIToolbox, void, DebugPrintWindow, WindowRef);
  1963.     if (DebugPrintWindow) {
  1964. DebugPrintWindow(newWindow);
  1965.     }
  1966. #endif /* TK_MAC_DEBUG_WINDOWS */
  1967. }
  1968. /*
  1969.  *----------------------------------------------------------------------
  1970.  *
  1971.  * TkMacOSXRegisterOffScreenWindow --
  1972.  *
  1973.  * This function adds the passed in Off Screen Port to the
  1974.  * hash table that maps Mac windows to root X windows.
  1975.  *
  1976.  * Results:
  1977.  * None.
  1978.  *
  1979.  * Side effects:
  1980.  * An entry is added to the windowTable hash table.
  1981.  *
  1982.  *----------------------------------------------------------------------
  1983.  */
  1984. void
  1985. TkMacOSXRegisterOffScreenWindow(
  1986.     Window window, /* Window structure. */
  1987.     GWorldPtr portPtr) /* Pointer to a Mac GWorld. */
  1988. {
  1989.     Tcl_HashEntry *valueHashPtr;
  1990.     int isNew;
  1991.     if (!windowHashInit) {
  1992. Tcl_InitHashTable(&windowTable, TCL_ONE_WORD_KEYS);
  1993. windowHashInit = true;
  1994.     }
  1995.     valueHashPtr = Tcl_CreateHashEntry(&windowTable, (char *) portPtr, &isNew);
  1996.     if (!isNew) {
  1997. Tcl_Panic("Same macintosh window allocated twice!");
  1998.     }
  1999.     Tcl_SetHashValue(valueHashPtr, window);
  2000. }
  2001. /*
  2002.  *----------------------------------------------------------------------
  2003.  *
  2004.  * TkMacOSXUnregisterMacWindow --
  2005.  *
  2006.  * Given a macintosh port window, this function removes the
  2007.  * association between this window and the root X window that
  2008.  * Tk cares about.
  2009.  *
  2010.  * Results:
  2011.  * None.
  2012.  *
  2013.  * Side effects:
  2014.  * An entry is removed from the windowTable hash table.
  2015.  *
  2016.  *----------------------------------------------------------------------
  2017.  */
  2018. void
  2019. TkMacOSXUnregisterMacWindow(
  2020.     WindowRef macWinPtr) /* Reference to a Mac Window */
  2021. {
  2022.     Tcl_HashEntry *entryPtr;
  2023.     if (!windowHashInit) {
  2024. Tcl_Panic("TkMacOSXUnregisterMacWindow: unmapping before inited");
  2025.     }
  2026.     entryPtr = Tcl_FindHashEntry(&windowTable,(char *) macWinPtr);
  2027.     if (!entryPtr) {
  2028. TkMacOSXDbgMsg("Failed to find window %08x", (int) macWinPtr);
  2029.     } else {
  2030. Tcl_DeleteHashEntry(entryPtr);
  2031.     }
  2032. }
  2033. /*
  2034.  *----------------------------------------------------------------------
  2035.  *
  2036.  * TkMacOSXSetScrollbarGrow --
  2037.  *
  2038.  * Sets a flag for a toplevel window indicating that the passed
  2039.  * Tk scrollbar window will display the grow region for the
  2040.  * toplevel window.
  2041.  *
  2042.  * Results:
  2043.  * None.
  2044.  *
  2045.  * Side effects:
  2046.  * A flag is set int windows toplevel parent.
  2047.  *
  2048.  *----------------------------------------------------------------------
  2049.  */
  2050. void
  2051. TkMacOSXSetScrollbarGrow(
  2052.     TkWindow *winPtr, /* Tk scrollbar window. */
  2053.     int flag) /* Boolean value true or false. */
  2054. {
  2055.     if (flag) {
  2056. winPtr->privatePtr->toplevel->flags |= TK_SCROLLBAR_GROW;
  2057. winPtr->privatePtr->toplevel->winPtr->wmInfoPtr->scrollWinPtr = winPtr;
  2058.     } else if (winPtr->privatePtr->toplevel->winPtr->wmInfoPtr->scrollWinPtr
  2059.     == winPtr) {
  2060. winPtr->privatePtr->toplevel->flags &= ~TK_SCROLLBAR_GROW;
  2061. winPtr->privatePtr->toplevel->winPtr->wmInfoPtr->scrollWinPtr = NULL;
  2062.     }
  2063. }
  2064. /*
  2065.  *----------------------------------------------------------------------
  2066.  *
  2067.  * TkWmFocusToplevel --
  2068.  *
  2069.  * This is a utility procedure invoked by focus-management code. It
  2070.  * exists because of the extra wrapper windows that exist under
  2071.  * Unix; its job is to map from wrapper windows to the
  2072.  * corresponding toplevel windows. On PCs and Macs there are no
  2073.  * wrapper windows so no mapping is necessary; this procedure just
  2074.  * determines whether a window is a toplevel or not.
  2075.  *
  2076.  * Results:
  2077.  * If winPtr is a toplevel window, returns the pointer to the
  2078.  * window; otherwise returns NULL.
  2079.  *
  2080.  * Side effects:
  2081.  * None.
  2082.  *
  2083.  *----------------------------------------------------------------------
  2084.  */
  2085. TkWindow *
  2086. TkWmFocusToplevel(
  2087.     TkWindow *winPtr) /* Window that received a focus-related
  2088.  * event. */
  2089. {
  2090.     if (!(winPtr->flags & TK_TOP_LEVEL)) {
  2091. return NULL;
  2092.     }
  2093.     return winPtr;
  2094. }
  2095. /*
  2096.  *----------------------------------------------------------------------
  2097.  *
  2098.  * TkpGetWrapperWindow --
  2099.  *
  2100.  * This is a utility procedure invoked by focus-management code. It
  2101.  * maps to the wrapper for a top-level, which is just the same
  2102.  * as the top-level on Macs and PCs.
  2103.  *
  2104.  * Results:
  2105.  * If winPtr is a toplevel window, returns the pointer to the
  2106.  * window; otherwise returns NULL.
  2107.  *
  2108.  * Side effects:
  2109.  * None.
  2110.  *
  2111.  *----------------------------------------------------------------------
  2112.  */
  2113. TkWindow *
  2114. TkpGetWrapperWindow(
  2115.     TkWindow *winPtr) /* Window that received a focus-related
  2116.  * event. */
  2117. {
  2118.     if (!(winPtr->flags & TK_TOP_LEVEL)) {
  2119. return NULL;
  2120.     }
  2121.     return winPtr;
  2122. }
  2123. /*
  2124.  *----------------------------------------------------------------------
  2125.  *
  2126.  * TkpWmSetState --
  2127.  *
  2128.  * Sets the window manager state for the wrapper window of a
  2129.  * given toplevel window.
  2130.  *
  2131.  * Results:
  2132.  * None.
  2133.  *
  2134.  * Side effects:
  2135.  * May maximize, minimize, restore, or withdraw a window.
  2136.  *
  2137.  *----------------------------------------------------------------------
  2138.  */
  2139. void
  2140. TkpWmSetState(winPtr, state)
  2141.     TkWindow *winPtr; /* Toplevel window to operate on. */
  2142.     int state; /* One of IconicState, ZoomState, NormalState,
  2143.  * or WithdrawnState. */
  2144. {
  2145.     WmInfo *wmPtr = winPtr->wmInfoPtr;
  2146.     WindowRef macWin;
  2147.     wmPtr->hints.initial_state = state;
  2148.     if (wmPtr->flags & WM_NEVER_MAPPED) {
  2149. return;
  2150.     }
  2151.     macWin = TkMacOSXDrawableWindow(winPtr->window);
  2152.     if (state == WithdrawnState) {
  2153. Tk_UnmapWindow((Tk_Window) winPtr);
  2154.     } else if (state == IconicState) {
  2155. /*
  2156.  * The window always gets unmapped. If we can show the
  2157.  * icon version of the window we also collapse it.
  2158.  */
  2159. if (IsWindowCollapsable(macWin) && !IsWindowCollapsed(macWin)) {
  2160.     CollapseWindow(macWin, true);
  2161. }
  2162. Tk_UnmapWindow((Tk_Window) winPtr);
  2163.     } else if (state == NormalState) {
  2164. Tk_MapWindow((Tk_Window) winPtr);
  2165. if (IsWindowCollapsable(macWin) && IsWindowCollapsed(macWin)) {
  2166.     CollapseWindow(macWin, false);
  2167. }
  2168. TkMacOSXZoomToplevel(macWin, inZoomIn);
  2169.     } else if (state == ZoomState) {
  2170. Tk_MapWindow((Tk_Window) winPtr);
  2171. if (IsWindowCollapsable(macWin) && IsWindowCollapsed(macWin)) {
  2172.     CollapseWindow(macWin, false);
  2173. }
  2174. TkMacOSXZoomToplevel(macWin, inZoomOut);
  2175.     }
  2176. }
  2177. /*
  2178.  *----------------------------------------------------------------------
  2179.  *
  2180.  * TkpIsWindowFloating --
  2181.  *
  2182.  * Returns 1 if a window is floating, 0 otherwise.
  2183.  *
  2184.  * Results:
  2185.  * 1 or 0 depending on window's floating attribute.
  2186.  *
  2187.  * Side effects:
  2188.  * None.
  2189.  *
  2190.  *----------------------------------------------------------------------
  2191.  */
  2192. int
  2193. TkpIsWindowFloating(
  2194.     WindowRef wRef)
  2195. {
  2196.     WindowClass class;
  2197.     if (wRef == NULL) {
  2198. return 0;
  2199.     }
  2200.     GetWindowClass(wRef, &class);
  2201.     return (class == kFloatingWindowClass);
  2202. }
  2203. /*
  2204.  *----------------------------------------------------------------------
  2205.  *
  2206.  * TkMacOSXWindowClass --
  2207.  *
  2208.  * Returns OS X window class of window
  2209.  *
  2210.  * Results:
  2211.  * 1 or 0 depending on window's floating attribute.
  2212.  *
  2213.  * Side effects:
  2214.  * None.
  2215.  *
  2216.  *----------------------------------------------------------------------
  2217.  */
  2218. MODULE_SCOPE WindowClass
  2219. TkMacOSXWindowClass(
  2220.     TkWindow *winPtr)
  2221. {
  2222.     return winPtr->wmInfoPtr->macClass;
  2223. }
  2224. /*
  2225.  *--------------------------------------------------------------
  2226.  *
  2227.  * TkMacOSXWindowOffset --
  2228.  *
  2229.  * Determines the x and y offset from the orgin of the toplevel
  2230.  * window dressing (the structure region, ie. title bar) and the
  2231.  * orgin of the content area.
  2232.  *
  2233.  * Results:
  2234.  * The x & y offset in pixels.
  2235.  *
  2236.  * Side effects:
  2237.  * None.
  2238.  *
  2239.  *----------------------------------------------------------------------
  2240.  */
  2241. void
  2242. TkMacOSXWindowOffset(
  2243.     WindowRef wRef,
  2244.     int *xOffset,
  2245.     int *yOffset)
  2246. {
  2247.     Window window;
  2248.     TkDisplay *dispPtr;
  2249.     TkWindow *winPtr;
  2250.     window = TkMacOSXGetXWindow(wRef);
  2251.     dispPtr = TkGetDisplayList();
  2252.     winPtr = (TkWindow *) Tk_IdToWindow(dispPtr->display, window);
  2253.     *xOffset = winPtr->wmInfoPtr->xInParent;
  2254.     *yOffset = winPtr->wmInfoPtr->yInParent;
  2255. }
  2256. /*
  2257.  *----------------------------------------------------------------------
  2258.  *
  2259.  * TkpGetMS --
  2260.  *
  2261.  * Return a relative time in milliseconds. It doesn't matter
  2262.  * when the epoch was.
  2263.  *
  2264.  * Results:
  2265.  * Number of milliseconds.
  2266.  *
  2267.  * Side effects:
  2268.  * None.
  2269.  *
  2270.  *----------------------------------------------------------------------
  2271.  */
  2272. unsigned long
  2273. TkpGetMS(void)
  2274. {
  2275.     Tcl_Time now;
  2276.     Tcl_GetTime(&now);
  2277.     return (long) now.sec * 1000 + now.usec / 1000;
  2278. }
  2279. /*
  2280.  *----------------------------------------------------------------------
  2281.  *
  2282.  * XSetInputFocus --
  2283.  *
  2284.  * Change the focus window for the application.
  2285.  *
  2286.  * Results:
  2287.  * None.
  2288.  *
  2289.  * Side effects:
  2290.  * None.
  2291.  *
  2292.  *----------------------------------------------------------------------
  2293.  */
  2294. void
  2295. XSetInputFocus(
  2296.     Display* display,
  2297.     Window focus,
  2298.     int revert_to,
  2299.     Time time)
  2300. {
  2301.     /*
  2302.      * Don't need to do a thing. Tk manages the focus for us.
  2303.      */
  2304. }
  2305. /*
  2306.  *----------------------------------------------------------------------
  2307.  *
  2308.  * TkpChangeFocus --
  2309.  *
  2310.  * This procedure is a stub on the Mac because we always own the
  2311.  * focus if we are a front most application.
  2312.  *
  2313.  * Results:
  2314.  * The return value is the serial number of the command that
  2315.  * changed the focus. It may be needed by the caller to filter
  2316.  * out focus change events that were queued before the command.
  2317.  * If the procedure doesn't actually change the focus then
  2318.  * it returns 0.
  2319.  *
  2320.  * Side effects:
  2321.  * None.
  2322.  *
  2323.  *----------------------------------------------------------------------
  2324.  */
  2325. int
  2326. TkpChangeFocus(winPtr, force)
  2327.     TkWindow *winPtr; /* Window that is to receive the X focus. */
  2328.     int force; /* Non-zero means claim the focus even
  2329.  * if it didn't originally belong to
  2330.  * topLevelPtr's application. */
  2331. {
  2332.     /*
  2333.      * We don't really need to do anything on the Mac. Tk will
  2334.      * keep all this state for us.
  2335.      */
  2336.     if (winPtr->atts.override_redirect) {
  2337. return 0;
  2338.     }
  2339.     /*
  2340.      * Remember the current serial number for the X server and issue
  2341.      * a dummy server request. This marks the position at which we
  2342.      * changed the focus, so we can distinguish FocusIn and FocusOut
  2343.      * events on either side of the mark.
  2344.      */
  2345.     return NextRequest(winPtr->display);
  2346. }
  2347. /*
  2348.  *----------------------------------------------------------------------
  2349.  *
  2350.  * WmStackorderToplevelWrapperMap --
  2351.  *
  2352.  * This procedure will create a table that maps the reparent wrapper
  2353.  * X id for a toplevel to the TkWindow structure that is wraps.
  2354.  * Tk keeps track of a mapping from the window X id to the TkWindow
  2355.  * structure but that does us no good here since we only get the X
  2356.  * id of the wrapper window. Only those toplevel windows that are
  2357.  * mapped have a position in the stacking order.
  2358.  *
  2359.  *
  2360.  * Results:
  2361.  * None.
  2362.  *
  2363.  * Side effects:
  2364.  * Adds entries to the passed hashtable.
  2365.  *
  2366.  *----------------------------------------------------------------------
  2367.  */
  2368. static void
  2369. WmStackorderToplevelWrapperMap(
  2370.     TkWindow *winPtr, /* TkWindow to recurse on */
  2371.     Display *display, /* X display of parent window */
  2372.     Tcl_HashTable *table) /* Maps mac window to TkWindow */
  2373. {
  2374.     TkWindow *childPtr;
  2375.     Tcl_HashEntry *hPtr;
  2376.     WindowRef macWindow;
  2377.     int newEntry;
  2378.     if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr)
  2379.     && (winPtr->display == display)) {
  2380. macWindow = TkMacOSXDrawableWindow(winPtr->window);
  2381. hPtr = Tcl_CreateHashEntry(table,
  2382.     (const char *) macWindow, &newEntry);
  2383. Tcl_SetHashValue(hPtr, winPtr);
  2384.     }
  2385.     for (childPtr = winPtr->childList; childPtr != NULL;
  2386.     childPtr = childPtr->nextPtr) {
  2387. WmStackorderToplevelWrapperMap(childPtr, display, table);
  2388.     }
  2389. }
  2390. /*
  2391.  *----------------------------------------------------------------------
  2392.  *
  2393.  * TkWmStackorderToplevel --
  2394.  *
  2395.  * This procedure returns the stack order of toplevel windows.
  2396.  *
  2397.  * Results:
  2398.  * An array of pointers to tk window objects in stacking order
  2399.  * or else NULL if there was an error.
  2400.  *
  2401.  * Side effects:
  2402.  * None.
  2403.  *
  2404.  *----------------------------------------------------------------------
  2405.  */
  2406. TkWindow **
  2407. TkWmStackorderToplevel(parentPtr)
  2408.     TkWindow *parentPtr; /* Parent toplevel window. */
  2409. {
  2410.     WindowRef frontWindow;
  2411.     TkWindow *childWinPtr, **windows, **window_ptr;
  2412.     Tcl_HashTable table;
  2413.     Tcl_HashEntry *hPtr;
  2414.     Tcl_HashSearch search;
  2415.     /*
  2416.      * Map mac windows to a TkWindow of the wrapped toplevel.
  2417.      */
  2418.     Tcl_InitHashTable(&table, TCL_ONE_WORD_KEYS);
  2419.     WmStackorderToplevelWrapperMap(parentPtr, parentPtr->display, &table);
  2420.     windows = (TkWindow **) ckalloc((table.numEntries+1)
  2421. * sizeof(TkWindow *));
  2422.     /*
  2423.      * Special cases: If zero or one toplevels were mapped
  2424.      * there is no need to enumerate Windows.
  2425.      */
  2426.     switch (table.numEntries) {
  2427.     case 0:
  2428. windows[0] = NULL;
  2429. goto done;
  2430.     case 1:
  2431. hPtr = Tcl_FirstHashEntry(&table, &search);
  2432. windows[0] = (TkWindow *) Tcl_GetHashValue(hPtr);
  2433. windows[1] = NULL;
  2434. goto done;
  2435.     }
  2436.     frontWindow = GetFrontWindowOfClass(kAllWindowClasses, false);
  2437.     if (frontWindow == NULL) {
  2438. ckfree((char *) windows);
  2439. windows = NULL;
  2440.     } else {
  2441. window_ptr = windows + table.numEntries;
  2442. *window_ptr-- = NULL;
  2443.     while (frontWindow != NULL) {
  2444.     hPtr = Tcl_FindHashEntry(&table, (char *) frontWindow);
  2445. if (hPtr != NULL) {
  2446.     childWinPtr = (TkWindow *) Tcl_GetHashValue(hPtr);
  2447.     *window_ptr-- = childWinPtr;
  2448. }
  2449. frontWindow = GetNextWindow(frontWindow);
  2450.     }
  2451. if (window_ptr != (windows-1))
  2452.     Tcl_Panic("num matched toplevel windows does not equal num "
  2453.     "children");
  2454.     }
  2455.     done:
  2456.     Tcl_DeleteHashTable(&table);
  2457.     return windows;
  2458. }
  2459. /*
  2460.  *----------------------------------------------------------------------
  2461.  *
  2462.  * ApplyWindowClassAttributeChanges --
  2463.  *
  2464.  * This procedure applies carbon window class and attribute changes.
  2465.  *
  2466.  * Results:
  2467.  * None.
  2468.  *
  2469.  * Side effects:
  2470.  * None.
  2471.  *
  2472.  *----------------------------------------------------------------------
  2473.  */
  2474. static void
  2475. ApplyWindowClassAttributeChanges(
  2476.     TkWindow *winPtr,
  2477.     WindowRef macWindow,
  2478.     WindowClass oldClass,
  2479.     WindowAttributes oldAttributes,
  2480.     int create)
  2481. {
  2482.     WmInfo *wmPtr = winPtr->wmInfoPtr;
  2483.     WindowAttributes newAttributes = wmPtr->attributes |
  2484.     kWindowAsyncDragAttribute;
  2485.     if (wmPtr->macClass != oldClass || newAttributes != oldAttributes) {
  2486. Rect strWidths;
  2487. if (!macWindow) {
  2488.     if (winPtr->window == None) {
  2489. if (create) {
  2490.     Tk_MakeWindowExist((Tk_Window) winPtr);
  2491. } else {
  2492.     return;
  2493. }
  2494.     }
  2495.     if (!TkMacOSXHostToplevelExists(winPtr)) {
  2496. if (create) {
  2497.     TkMacOSXMakeRealWindowExist(winPtr);
  2498. } else {
  2499.     return;
  2500. }
  2501.     }
  2502.     macWindow = TkMacOSXDrawableWindow(winPtr->window);
  2503. }
  2504. if (wmPtr->macClass != oldClass) {
  2505.     TK_IF_MAC_OS_X_API (4, HIWindowChangeClass,
  2506. ChkErr(HIWindowChangeClass, macWindow, wmPtr->macClass);
  2507.     ) TK_ENDIF
  2508.     ChkErr(GetWindowClass, macWindow, &(wmPtr->macClass));
  2509. }
  2510. if (newAttributes != oldAttributes) {
  2511.     newAttributes &= GetAvailableWindowAttributes(wmPtr->macClass);
  2512.     ChkErr(ChangeWindowAttributes, macWindow,
  2513.     newAttributes & (newAttributes ^ oldAttributes),
  2514.     oldAttributes & (newAttributes ^ oldAttributes));
  2515. }
  2516. ChkErr(GetWindowAttributes, macWindow, &(wmPtr->attributes));
  2517. if ((wmPtr->attributes ^ oldAttributes) & kWindowResizableAttribute) {
  2518.     if (wmPtr->attributes & kWindowResizableAttribute) {
  2519. HIViewRef growBoxView;
  2520. OSStatus err = HIViewFindByID(HIViewGetRoot(macWindow),
  2521. kHIViewWindowGrowBoxID, &growBoxView);
  2522. if (err == noErr && !HIGrowBoxViewIsTransparent(growBoxView)) {
  2523.     ChkErr(HIGrowBoxViewSetTransparent, growBoxView, true);
  2524. }
  2525.     }
  2526.     TkMacOSXInvalClipRgns((Tk_Window) winPtr);
  2527.     TkMacOSXInvalidateWindow((MacDrawable *)(winPtr->window),
  2528.     TK_PARENT_WINDOW);
  2529. }
  2530. /*
  2531.  * The change of window class/attributes might have changed the window
  2532.  * structure widths:
  2533.  */
  2534. GetWindowStructureWidths(macWindow, &strWidths);
  2535. wmPtr->xInParent = strWidths.left;
  2536. wmPtr->yInParent = strWidths.top;
  2537. wmPtr->parentWidth = winPtr->changes.width + strWidths.left
  2538. + strWidths.right;
  2539. wmPtr->parentHeight = winPtr->changes.height + strWidths.top
  2540. + strWidths.bottom;
  2541.     }
  2542. }
  2543. /*
  2544.  *----------------------------------------------------------------------
  2545.  *
  2546.  * ApplyMasterOverrideChanges --
  2547.  *
  2548.  * This procedure applies changes to override_redirect or master.
  2549.  *
  2550.  * Results:
  2551.  * None.
  2552.  *
  2553.  * Side effects:
  2554.  * None.
  2555.  *
  2556.  *----------------------------------------------------------------------
  2557.  */
  2558. static void
  2559. ApplyMasterOverrideChanges(
  2560.     TkWindow *winPtr,
  2561.     WindowRef macWindow)
  2562. {
  2563.     WmInfo *wmPtr = winPtr->wmInfoPtr;
  2564.     WindowClass oldClass = wmPtr->macClass;
  2565.     WindowAttributes oldAttributes = wmPtr->attributes;
  2566.     /*
  2567.      * FIX: We need an UpdateWrapper equivalent to make this 100% correct
  2568.      */
  2569.     if (winPtr->atts.override_redirect) {
  2570. if (oldClass == kDocumentWindowClass) {
  2571.     wmPtr->macClass = kSimpleWindowClass;
  2572.     wmPtr->attributes = kWindowNoAttributes;
  2573. }
  2574. wmPtr->attributes |= kWindowNoActivatesAttribute;
  2575.     } else {
  2576. if (oldClass == kSimpleWindowClass &&
  2577. oldAttributes == kWindowNoActivatesAttribute) {
  2578.     wmPtr->macClass = kDocumentWindowClass;
  2579.     wmPtr->attributes = kWindowStandardDocumentAttributes
  2580.     | kWindowLiveResizeAttribute;
  2581. }
  2582. wmPtr->attributes &= ~kWindowNoActivatesAttribute;
  2583.     }
  2584.     if (!macWindow && winPtr->window != None &&
  2585.     TkMacOSXHostToplevelExists(winPtr)) {
  2586. macWindow = TkMacOSXDrawableWindow(winPtr->window);
  2587.     }
  2588.     if (macWindow) {
  2589. WindowGroupRef group;
  2590. ApplyWindowClassAttributeChanges(winPtr, macWindow, oldClass,
  2591.     oldAttributes, 0);
  2592. if (winPtr->atts.override_redirect && wmPtr->master != None) {
  2593.     wmPtr->flags |= WM_TOPMOST;
  2594. } else {
  2595.     wmPtr->flags &= ~WM_TOPMOST;
  2596. }
  2597. group = WmGetWindowGroup(winPtr);
  2598. if (group && group != GetWindowGroup(macWindow)) {
  2599.     ChkErr(SetWindowGroup, macWindow, group);
  2600. }
  2601.     }
  2602. }
  2603. /*
  2604.  *----------------------------------------------------------------------
  2605.  *
  2606.  * WmGetWindowGroup --
  2607.  *
  2608.  * Gets the window group a toplevel should be placed in.
  2609.  *
  2610.  * Results:
  2611.  * A WindowGroupRef.
  2612.  *
  2613.  * Side effects:
  2614.  * A transient window group for the master (if any) may be created.
  2615.  *
  2616.  *----------------------------------------------------------------------
  2617.  */
  2618. static WindowGroupRef
  2619. WmGetWindowGroup(
  2620.     TkWindow *winPtr)
  2621. {
  2622.     WmInfo *wmPtr = winPtr->wmInfoPtr;
  2623.     WindowGroupRef group = NULL;
  2624.     if (wmPtr->flags & WM_TOPMOST) {
  2625. group = GetWindowGroupOfClass(kUtilityWindowClass);
  2626.     } else if (wmPtr->master != None) {
  2627. TkDisplay *dispPtr = TkGetDisplayList();
  2628. TkWindow *masterWinPtr = (TkWindow *)Tk_IdToWindow(dispPtr->display,
  2629. wmPtr->master);
  2630. if (masterWinPtr && masterWinPtr->window != None &&
  2631. TkMacOSXHostToplevelExists(masterWinPtr)) {
  2632.     WindowRef masterMacWin =
  2633.     TkMacOSXDrawableWindow(masterWinPtr->window);
  2634.     if (masterMacWin && GetWindowProperty(masterMacWin, 'Tk  ', 'TsGp',
  2635.     sizeof(group), NULL, &group) != noErr) {
  2636. ChkErr(CreateWindowGroup, 0, &group);
  2637. if (group) {
  2638.     ChkErr(SetWindowGroupParent, group,
  2639.     GetWindowGroup(masterMacWin));
  2640.     ChkErr(SetWindowGroupOwner, group, masterMacWin);
  2641.     ChkErr(SetWindowProperty, masterMacWin, 'Tk  ', 'TsGp',
  2642.     sizeof(group), &group);
  2643. }
  2644.     }
  2645. }
  2646.     }
  2647.     if (!group) {
  2648. group = GetWindowGroupOfClass(wmPtr->macClass);
  2649.     }
  2650.     return group;
  2651. }
  2652. /*
  2653.  *----------------------------------------------------------------------
  2654.  *
  2655.  * TkMacOSXMakeFullscreen --
  2656.  *
  2657.  * This procedure sets a fullscreen window to the size of the screen.
  2658.  *
  2659.  * Results:
  2660.  * A standard Tcl result.
  2661.  *
  2662.  * Side effects:
  2663.  * None.
  2664.  *
  2665.  *----------------------------------------------------------------------
  2666.  */
  2667. int
  2668. TkMacOSXMakeFullscreen(
  2669.     TkWindow *winPtr,
  2670.     WindowRef window,
  2671.     int fullscreen,
  2672.     Tcl_Interp *interp)
  2673. {
  2674.     WmInfo *wmPtr = winPtr->wmInfoPtr;
  2675.     int result = TCL_OK, wasFullscreen = (wmPtr->flags & WM_FULLSCREEN);
  2676.     if (fullscreen) {
  2677. int screenWidth =  WidthOfScreen(Tk_Screen(winPtr));
  2678. int screenHeight = HeightOfScreen(Tk_Screen(winPtr));
  2679. /*
  2680.  * Check max width and height if set by the user.
  2681.  */
  2682. if ((wmPtr->maxWidth > 0 && wmPtr->maxWidth < screenWidth)
  2683. || (wmPtr->maxHeight > 0 && wmPtr->maxHeight < screenHeight)) {
  2684.     if (interp) {
  2685. Tcl_AppendResult(interp,
  2686. "can't set fullscreen attribute for "",
  2687. winPtr->pathName,
  2688. "": max width/height is too small", NULL);
  2689.     }
  2690.     result = TCL_ERROR;
  2691.     wmPtr->flags &= ~WM_FULLSCREEN;
  2692. } else {
  2693.     Rect bounds, screenBounds = {0, 0, screenHeight, screenWidth};
  2694.     ChkErr(GetWindowBounds, window, kWindowContentRgn, &bounds);
  2695.     if (!EqualRect(&bounds, &screenBounds)) {
  2696. if (!wasFullscreen) {
  2697.     wmPtr->configX = wmPtr->x;
  2698.     wmPtr->configY = wmPtr->y;
  2699.     wmPtr->configAttributes = wmPtr->attributes;
  2700.     wmPtr->attributes &= ~kWindowResizableAttribute;
  2701.     ApplyWindowClassAttributeChanges(winPtr, window,
  2702.     wmPtr->macClass, wmPtr->configAttributes, 0);
  2703. }
  2704. wmPtr->flags |= WM_SYNC_PENDING;
  2705. ChkErr(SetWindowBounds, window, kWindowContentRgn,
  2706. &screenBounds);
  2707. wmPtr->flags &= ~WM_SYNC_PENDING;
  2708.     }
  2709.     wmPtr->flags |= WM_FULLSCREEN;
  2710. }
  2711.     } else {
  2712. wmPtr->flags &= ~WM_FULLSCREEN;
  2713.     }
  2714.     if (wasFullscreen && !(wmPtr->flags & WM_FULLSCREEN)) {
  2715. WindowAttributes oldAttributes = wmPtr->attributes;
  2716. Rect bounds = {wmPtr->configY, wmPtr->configX,
  2717. wmPtr->configY + wmPtr->yInParent + wmPtr->configHeight,
  2718. wmPtr->configX + wmPtr->xInParent + wmPtr->configWidth};
  2719. wmPtr->attributes |= wmPtr->configAttributes &
  2720. kWindowResizableAttribute;
  2721. ApplyWindowClassAttributeChanges(winPtr, window, wmPtr->macClass,
  2722. oldAttributes, 0);
  2723. wmPtr->flags |= WM_SYNC_PENDING;
  2724. ChkErr(SetWindowBounds, window, kWindowStructureRgn, &bounds);
  2725. wmPtr->flags &= ~WM_SYNC_PENDING;
  2726.     }
  2727.     TkMacOSXEnterExitFullscreen(winPtr, IsWindowActive(window));
  2728.     return result;
  2729. }
  2730. /*
  2731.  *----------------------------------------------------------------------
  2732.  *
  2733.  * TkMacOSXEnterExitFullscreen --
  2734.  *
  2735.  * This procedure enters or exits fullscreen mode if required.
  2736.  *
  2737.  * Results:
  2738.  * None.
  2739.  *
  2740.  * Side effects:
  2741.  * None.
  2742.  *
  2743.  *----------------------------------------------------------------------
  2744.  */
  2745. void
  2746. TkMacOSXEnterExitFullscreen(
  2747.     TkWindow *winPtr,
  2748.     int active)
  2749. {
  2750.     WmInfo *wmPtr = winPtr->wmInfoPtr;
  2751.     SystemUIMode mode;
  2752.     SystemUIOptions options;
  2753.     GetSystemUIMode(&mode, &options);
  2754.     if (wmPtr->flags & WM_FULLSCREEN && active) {
  2755. static SystemUIMode fullscreenMode = 0;
  2756. static SystemUIOptions fullscreenOptions = 0;
  2757. if (!fullscreenMode) {
  2758.     TK_IF_HI_TOOLBOX (3,
  2759. fullscreenMode = kUIModeAllSuppressed;
  2760.     ) TK_ELSE_HI_TOOLBOX (3,
  2761. fullscreenMode = kUIModeAllHidden;
  2762. fullscreenOptions = kUIOptionAutoShowMenuBar;
  2763.     ) TK_ENDIF
  2764. }
  2765. if (mode != fullscreenMode) {
  2766.     ChkErr(SetSystemUIMode, fullscreenMode, fullscreenOptions);
  2767. }
  2768.     } else {
  2769. if (mode != kUIModeNormal) {
  2770.     ChkErr(SetSystemUIMode, kUIModeNormal, 0);
  2771. }
  2772.     }
  2773. }
  2774. /*
  2775.  *----------------------------------------------------------------------
  2776.  *
  2777.  * GetMinSize --
  2778.  *
  2779.  * This function computes the current minWidth and minHeight values for
  2780.  * a window, taking into account the possibility that they may be
  2781.  * defaulted.
  2782.  *
  2783.  * Results:
  2784.  * The values at *minWidthPtr and *minHeightPtr are filled in with the
  2785.  * minimum allowable dimensions of wmPtr's window, in grid units. If the
  2786.  * requested minimum is smaller than the system required minimum, then
  2787.  * this function computes the smallest size that will satisfy both the
  2788.  * system and the grid constraints.
  2789.  *
  2790.  * Side effects:
  2791.  * None.
  2792.  *
  2793.  *----------------------------------------------------------------------
  2794.  */
  2795. static void
  2796. GetMinSize(
  2797.     TkWindow *winPtr, /* Toplevel window to operate on. */
  2798.     int *minWidthPtr, /* Where to store the current minimum width of
  2799.  * the window. */
  2800.     int *minHeightPtr) /* Where to store the current minimum height
  2801.  * of the window. */
  2802. {
  2803.     WmInfo *wmPtr = winPtr->wmInfoPtr;
  2804.     int minWidth = 1, minHeight = 1;
  2805.     /*
  2806.      * Compute the minimum width & height by taking the default client size and
  2807.      * rounding it up to the nearest grid unit. Return the greater of the
  2808.      * default minimum and the specified minimum.
  2809.      */
  2810.     switch (wmPtr->macClass) {
  2811. case kDocumentWindowClass:
  2812. case kMovableAlertWindowClass:
  2813. case kMovableModalWindowClass:
  2814.     minWidth = 72;
  2815.     if (wmPtr->attributes & kWindowResizableAttribute) {
  2816. minHeight = 15;
  2817.     }
  2818.     if (wmPtr->attributes & kWindowToolbarButtonAttribute) {
  2819. minWidth += 29;
  2820.     }
  2821.     break;
  2822. case kFloatingWindowClass:
  2823. case kUtilityWindowClass:
  2824.     minWidth = 59;
  2825.     if (wmPtr->attributes & kWindowResizableAttribute) {
  2826. minHeight = 11;
  2827.     }
  2828.     if (wmPtr->attributes & kWindowSideTitlebarAttribute) {
  2829. int tmp = minWidth;
  2830. minWidth = minHeight;
  2831. minHeight = tmp;
  2832.     } else if (wmPtr->attributes & kWindowToolbarButtonAttribute) {
  2833. minWidth += 29;
  2834.     }
  2835.     break;
  2836. default:
  2837.     if (wmPtr->attributes & kWindowResizableAttribute) {
  2838. minWidth = 15;
  2839. minHeight = 15;
  2840.     }
  2841.     break;
  2842.     }
  2843.     if (wmPtr->gridWin != NULL) {
  2844. int base = winPtr->reqWidth - (wmPtr->reqGridWidth * wmPtr->widthInc);
  2845. if (base < 0) {
  2846.     base = 0;
  2847. }
  2848. minWidth = ((minWidth - base) + wmPtr->widthInc-1)/wmPtr->widthInc;
  2849. base = winPtr->reqHeight - (wmPtr->reqGridHeight * wmPtr->heightInc);
  2850. if (base < 0) {
  2851.     base = 0;
  2852. }
  2853. minHeight = ((minHeight - base) + wmPtr->heightInc-1)/wmPtr->heightInc;
  2854.     }
  2855.     if (minWidth < wmPtr->minWidth) {
  2856. minWidth = wmPtr->minWidth;
  2857.     }
  2858.     if (minHeight < wmPtr->minHeight) {
  2859. minHeight = wmPtr->minHeight;
  2860.     }
  2861.     *minWidthPtr = minWidth;
  2862.     *minHeightPtr = minHeight;
  2863. }
  2864. /*
  2865.  *----------------------------------------------------------------------
  2866.  *
  2867.  * GetMaxSize --
  2868.  *
  2869.  * This function computes the current maxWidth and maxHeight values for
  2870.  * a window, taking into account the possibility that they may be
  2871.  * defaulted.
  2872.  *
  2873.  * Results:
  2874.  * The values at *maxWidthPtr and *maxHeightPtr are filled in with the
  2875.  * maximum allowable dimensions of wmPtr's window, in grid units. If no
  2876.  * maximum has been specified for the window, then this function computes
  2877.  * the largest sizes that will fit on the screen.
  2878.  *
  2879.  * Side effects:
  2880.  * None.
  2881.  *
  2882.  *----------------------------------------------------------------------
  2883.  */
  2884. static void
  2885. GetMaxSize(
  2886.     TkWindow *winPtr, /* Toplevel window to operate on. */
  2887.     int *maxWidthPtr, /* Where to store the current maximum width of
  2888.  * the window. */
  2889.     int *maxHeightPtr) /* Where to store the current maximum height
  2890.  * of the window. */
  2891. {
  2892.     WmInfo *wmPtr = winPtr->wmInfoPtr;
  2893.     Rect *maxBounds = (Rect*)(winPtr->display->screens->ext_data);
  2894.     if (wmPtr->maxWidth > 0) {
  2895. *maxWidthPtr = wmPtr->maxWidth;
  2896.     } else {
  2897. int maxWidth = maxBounds->right - maxBounds->left - wmPtr->xInParent;
  2898. if (wmPtr->gridWin != NULL) {
  2899.     maxWidth = wmPtr->reqGridWidth
  2900.     + (maxWidth - winPtr->reqWidth)/wmPtr->widthInc;
  2901. }
  2902. *maxWidthPtr = maxWidth;
  2903.     }
  2904.     if (wmPtr->maxHeight > 0) {
  2905. *maxHeightPtr = wmPtr->maxHeight;
  2906.     } else {
  2907. int maxHeight = maxBounds->bottom - maxBounds->top - wmPtr->yInParent;
  2908. if (wmPtr->gridWin != NULL) {
  2909.     maxHeight = wmPtr->reqGridHeight
  2910.     + (maxHeight - winPtr->reqHeight)/wmPtr->heightInc;
  2911. }
  2912. *maxHeightPtr = maxHeight;
  2913.     }
  2914. }
  2915. #if 0
  2916. /*
  2917.  *----------------------------------------------------------------------
  2918.  *
  2919.  * RemapWindows
  2920.  *
  2921.  * Adjust parent/child relation ships of
  2922.  * the given window hierarchy.
  2923.  *
  2924.  * Results:
  2925.  * none
  2926.  *
  2927.  * Side effects:
  2928.  * keeps windowing system (X11) happy
  2929.  *
  2930.  *----------------------------------------------------------------------
  2931.  */
  2932. static void
  2933. RemapWindows(TkWindow *winPtr, MacDrawable *parentWin)
  2934. {
  2935.     TkWindow *childPtr;
  2936.     /* Remove the OS specific window.
  2937.      * It will get rebuilt when the window gets Mapped.
  2938.      */
  2939.     if (winPtr->window != None) {
  2940. MacDrawable *macWin = (MacDrawable *) winPtr->window;
  2941. macWin->grafPtr = NULL;
  2942. macWin->toplevel = parentWin->toplevel;
  2943. winPtr->flags &= ~TK_MAPPED;
  2944. #ifdef TK_REBUILD_TOPLEVEL
  2945. winPtr->flags |= TK_REBUILD_TOPLEVEL;
  2946. #endif
  2947.     }
  2948.     /* Repeat for all the children */
  2949.     for (childPtr = winPtr->childList; childPtr != NULL;
  2950.  childPtr = childPtr->nextPtr) {
  2951. RemapWindows(childPtr, (MacDrawable *) winPtr->window);
  2952.     }
  2953. }
  2954. #endif