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

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * tkMacOSXWm.c --
  3.  *
  4.  * This module takes care of the interactions between a Tk-based
  5.  * application and the window manager. Among other things, it
  6.  * implements the "wm" command and passes geometry information
  7.  * to the window manager.
  8.  *
  9.  * Copyright (c) 1994-1997 Sun Microsystems, Inc.
  10.  * Copyright 2001, Apple Computer, Inc.
  11.  * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net>
  12.  *
  13.  * See the file "license.terms" for information on usage and redistribution
  14.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  15.  *
  16.  * RCS: @(#) $Id: tkMacOSXWm.c,v 1.7.2.46 2007/12/18 18:21:31 das Exp $
  17.  */
  18. #include "tkMacOSXPrivate.h"
  19. #include "tkScrollbar.h"
  20. #include "tkMacOSXWm.h"
  21. #include "tkMacOSXEvent.h"
  22. #include "tkMacOSXDebug.h"
  23. /*
  24. #ifdef TK_MAC_DEBUG
  25. #define TK_MAC_DEBUG_WINDOWS
  26. #endif
  27. */
  28. /*
  29.  * Data for [wm attributes] command:
  30.  */
  31. typedef enum {
  32.     WMATT_ALPHA, WMATT_FULLSCREEN, WMATT_MODIFIED,/* WMATT_NOTIFY,*/
  33.     WMATT_TITLEPATH, WMATT_TOPMOST, WMATT_TRANSPARENT,
  34.     _WMATT_LAST_ATTRIBUTE
  35. } WmAttribute;
  36. static const char *WmAttributeNames[] = {
  37.     "-alpha", "-fullscreen", "-modified",/* "-notify",*/
  38.     "-titlepath", "-topmost", "-transparent",
  39.     NULL
  40. };
  41. /*
  42.  * This is a list of all of the toplevels that have been mapped so far. It is
  43.  * used by the menu code to inval windows that were damaged by menus, and will
  44.  * eventually also be used to keep track of floating windows.
  45.  */
  46. TkMacOSXWindowList *tkMacOSXWindowListPtr = NULL;
  47. /*
  48.  * The variable below is used to enable or disable tracing in this
  49.  * module. If tracing is enabled, then information is printed on
  50.  * standard output about interesting interactions with the window
  51.  * manager.
  52.  */
  53. static int wmTracing = 0;
  54. /*
  55.  * The following structure is the official type record for geometry
  56.  * management of top-level windows.
  57.  */
  58. static void TopLevelReqProc(ClientData dummy, Tk_Window tkwin);
  59. static /* const */ Tk_GeomMgr wmMgrType = {
  60.     "wm", /* name */
  61.     TopLevelReqProc, /* requestProc */
  62.     (Tk_GeomLostSlaveProc *) NULL, /* lostSlaveProc */
  63. };
  64. /*
  65.  * The following keeps state for Aqua dock icon bounce notification.
  66.  */
  67. #if 0
  68. static int tkMacOSXWmAttrNotifyVal = 0;
  69. #endif
  70. /*
  71.  * Hash table for Mac Window -> TkWindow mapping.
  72.  */
  73. static Tcl_HashTable windowTable;
  74. static int windowHashInit = false;
  75. /*
  76.  * Forward declarations for procedures defined in this file:
  77.  */
  78. static void InitialWindowBounds(TkWindow *winPtr, WindowRef macWindow,
  79. Rect *geometry);
  80. static int ParseGeometry(Tcl_Interp *interp, char *string, TkWindow *winPtr);
  81. static void TopLevelEventProc(ClientData clientData, XEvent *eventPtr);
  82. static void WmStackorderToplevelWrapperMap(TkWindow *winPtr, Display *display,
  83. Tcl_HashTable *table);
  84. static void UpdateGeometryInfo(ClientData clientData);
  85. static void UpdateSizeHints(TkWindow *winPtr);
  86. static void UpdateVRootGeometry(WmInfo *wmPtr);
  87. static int WmAspectCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp,
  88. int objc, Tcl_Obj *const objv[]);
  89. static int WmAttributesCmd(Tk_Window tkwin, TkWindow *winPtr,
  90. Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
  91. static int WmClientCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp,
  92. int objc, Tcl_Obj *const objv[]);
  93. static int WmColormapwindowsCmd(Tk_Window tkwin, TkWindow *winPtr,
  94. Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
  95. static int WmCommandCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp,
  96. int objc, Tcl_Obj *const objv[]);
  97. static int WmDeiconifyCmd(Tk_Window tkwin, TkWindow *winPtr,
  98. Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
  99. static int WmFocusmodelCmd(Tk_Window tkwin, TkWindow *winPtr,
  100. Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
  101. #if 0
  102. static int WmForgetCmd(Tk_Window tkwin, TkWindow *winPtr,
  103. Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
  104. #endif
  105. static int WmFrameCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp,
  106. int objc, Tcl_Obj *const objv[]);
  107. static int WmGeometryCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp,
  108. int objc, Tcl_Obj *const objv[]);
  109. static int WmGridCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp,
  110. int objc, Tcl_Obj *const objv[]);
  111. static int WmGroupCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp,
  112. int objc, Tcl_Obj *const objv[]);
  113. static int WmIconbitmapCmd(Tk_Window tkwin, TkWindow *winPtr,
  114. Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
  115. static int WmIconifyCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp,
  116. int objc, Tcl_Obj *const objv[]);
  117. static int WmIconmaskCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp,
  118. int objc, Tcl_Obj *const objv[]);
  119. static int WmIconnameCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp,
  120. int objc, Tcl_Obj *const objv[]);
  121. static int WmIconphotoCmd(Tk_Window tkwin, TkWindow *winPtr,
  122. Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
  123. static int WmIconpositionCmd(Tk_Window tkwin, TkWindow *winPtr,
  124. Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
  125. static int WmIconwindowCmd(Tk_Window tkwin, TkWindow *winPtr,
  126. Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
  127. #if 0
  128. static int WmManageCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp,
  129. int objc, Tcl_Obj *const objv[]);
  130. #endif
  131. static int WmMaxsizeCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp,
  132. int objc, Tcl_Obj *const objv[]);
  133. static int WmMinsizeCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp,
  134. int objc, Tcl_Obj *const objv[]);
  135. static int WmOverrideredirectCmd(Tk_Window tkwin, TkWindow *winPtr,
  136. Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
  137. static int WmPositionfromCmd(Tk_Window tkwin, TkWindow *winPtr,
  138. Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
  139. static int WmProtocolCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp,
  140. int objc, Tcl_Obj *const objv[]);
  141. static int WmResizableCmd(Tk_Window tkwin, TkWindow *winPtr,
  142. Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
  143. static int WmSizefromCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp,
  144. int objc, Tcl_Obj *const objv[]);
  145. static int WmStackorderCmd(Tk_Window tkwin, TkWindow *winPtr,
  146. Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
  147. static int WmStateCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp,
  148. int objc, Tcl_Obj *const objv[]);
  149. static int WmTitleCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp,
  150. int objc, Tcl_Obj *const objv[]);
  151. static int WmTransientCmd(Tk_Window tkwin, TkWindow *winPtr,
  152. Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
  153. static int WmWithdrawCmd(Tk_Window tkwin, TkWindow *winPtr, Tcl_Interp *interp,
  154. int objc, Tcl_Obj *const objv[]);
  155. static void WmUpdateGeom(WmInfo *wmPtr, TkWindow *winPtr);
  156. static int WmWinStyle(Tcl_Interp *interp, TkWindow *winPtr, int objc,
  157. Tcl_Obj * const objv[]);
  158. static void ApplyWindowClassAttributeChanges(TkWindow *winPtr,
  159. WindowRef macWindow, WindowClass oldClass,
  160. WindowAttributes oldAttributes, int create);
  161. static void ApplyMasterOverrideChanges(TkWindow *winPtr, WindowRef macWindow);
  162. static WindowGroupRef WmGetWindowGroup(TkWindow *winPtr);
  163. static void GetMinSize(TkWindow *winPtr, int *minWidthPtr, int *minHeightPtr);
  164. static void GetMaxSize(TkWindow *winPtr, int *maxWidthPtr, int *maxHeightPtr);
  165. #if 0
  166. static void RemapWindows(TkWindow *winPtr, MacDrawable *parentWin);
  167. #endif
  168. /*
  169.  *----------------------------------------------------------------------
  170.  *
  171.  * TkWmNewWindow --
  172.  *
  173.  * This procedure is invoked whenever a new top-level
  174.  * window is created. Its job is to initialize the WmInfo
  175.  * structure for the window.
  176.  *
  177.  * Results:
  178.  * None.
  179.  *
  180.  * Side effects:
  181.  * A WmInfo structure gets allocated and initialized.
  182.  *
  183.  *----------------------------------------------------------------------
  184.  */
  185. void
  186. TkWmNewWindow(
  187.     TkWindow *winPtr) /* Newly-created top-level window. */
  188. {
  189.     WmInfo *wmPtr;
  190.     wmPtr = (WmInfo *) ckalloc(sizeof(WmInfo));
  191.     wmPtr->winPtr = winPtr;
  192.     wmPtr->reparent = None;
  193.     wmPtr->titleUid = NULL;
  194.     wmPtr->iconName = NULL;
  195.     wmPtr->master = None;
  196.     wmPtr->hints.flags = InputHint | StateHint;
  197.     wmPtr->hints.input = True;
  198.     wmPtr->hints.initial_state = NormalState;
  199.     wmPtr->hints.icon_pixmap = None;
  200.     wmPtr->hints.icon_window = None;
  201.     wmPtr->hints.icon_x = wmPtr->hints.icon_y = 0;
  202.     wmPtr->hints.icon_mask = None;
  203.     wmPtr->hints.window_group = None;
  204.     wmPtr->leaderName = NULL;
  205.     wmPtr->masterWindowName = NULL;
  206.     wmPtr->icon = NULL;
  207.     wmPtr->iconFor = NULL;
  208.     wmPtr->sizeHintsFlags = 0;
  209.     wmPtr->minWidth = wmPtr->minHeight = 1;
  210.     wmPtr->maxWidth = 0;
  211.     wmPtr->maxHeight = 0;
  212.     wmPtr->gridWin = NULL;
  213.     wmPtr->widthInc = wmPtr->heightInc = 1;
  214.     wmPtr->minAspect.x = wmPtr->minAspect.y = 1;
  215.     wmPtr->maxAspect.x = wmPtr->maxAspect.y = 1;
  216.     wmPtr->reqGridWidth = wmPtr->reqGridHeight = -1;
  217.     wmPtr->gravity = NorthWestGravity;
  218.     wmPtr->width = -1;
  219.     wmPtr->height = -1;
  220.     wmPtr->x = winPtr->changes.x;
  221.     wmPtr->y = winPtr->changes.y;
  222.     wmPtr->parentWidth = winPtr->changes.width
  223. + 2*winPtr->changes.border_width;
  224.     wmPtr->parentHeight = winPtr->changes.height
  225. + 2*winPtr->changes.border_width;
  226.     wmPtr->xInParent = 0;
  227.     wmPtr->yInParent = 0;
  228.     wmPtr->cmapList = NULL;
  229.     wmPtr->cmapCount = 0;
  230.     wmPtr->configX = 0;
  231.     wmPtr->configY = 0;
  232.     wmPtr->configWidth = -1;
  233.     wmPtr->configHeight = -1;
  234.     wmPtr->vRoot = None;
  235.     wmPtr->protPtr = NULL;
  236.     wmPtr->cmdArgv = NULL;
  237.     wmPtr->clientMachine = NULL;
  238.     wmPtr->flags = WM_NEVER_MAPPED;
  239.     wmPtr->style = -1;
  240.     wmPtr->macClass = kDocumentWindowClass;
  241.     wmPtr->attributes = kWindowStandardDocumentAttributes
  242.     | kWindowLiveResizeAttribute;
  243.     wmPtr->scrollWinPtr = NULL;
  244.     winPtr->wmInfoPtr = wmPtr;
  245.     UpdateVRootGeometry(wmPtr);
  246.     /*
  247.      * Tk must monitor structure events for top-level windows, in order
  248.      * to detect size and position changes caused by window managers.
  249.      */
  250.     Tk_CreateEventHandler((Tk_Window) winPtr, StructureNotifyMask,
  251.     TopLevelEventProc, (ClientData) winPtr);
  252.     /*
  253.      * Arrange for geometry requests to be reflected from the window
  254.      * to the window manager.
  255.      */
  256.     Tk_ManageGeometry((Tk_Window) winPtr, &wmMgrType, (ClientData) 0);
  257. }
  258. /*
  259.  *----------------------------------------------------------------------
  260.  *
  261.  * TkWmMapWindow --
  262.  *
  263.  * This procedure is invoked to map a top-level window. This
  264.  * module gets a chance to update all window-manager-related
  265.  * information in properties before the window manager sees
  266.  * the map event and checks the properties. It also gets to
  267.  * decide whether or not to even map the window after all.
  268.  *
  269.  * Results:
  270.  * None.
  271.  *
  272.  * Side effects:
  273.  * Properties of winPtr may get updated to provide up-to-date
  274.  * information to the window manager. The window may also get
  275.  * mapped, but it may not be if this procedure decides that
  276.  * isn't appropriate (e.g. because the window is withdrawn).
  277.  *
  278.  *----------------------------------------------------------------------
  279.  */
  280. void
  281. TkWmMapWindow(
  282.     TkWindow *winPtr) /* Top-level window that's about to
  283.  * be mapped. */
  284. {
  285.     WmInfo *wmPtr = winPtr->wmInfoPtr;
  286.     if (wmPtr->flags & WM_NEVER_MAPPED) {
  287. wmPtr->flags &= ~WM_NEVER_MAPPED;
  288. /*
  289.  * Create the underlying Mac window for this Tk window.
  290.  */
  291. if (!TkMacOSXHostToplevelExists(winPtr)) {
  292.     TkMacOSXMakeRealWindowExist(winPtr);
  293. }
  294. /*
  295.  * Generate configure event when we first map the window.
  296.  */
  297. TkGenWMConfigureEvent((Tk_Window) winPtr, wmPtr->x, wmPtr->y, -1, -1,
  298. TK_LOCATION_CHANGED);
  299. /*
  300.  * This is the first time this window has ever been mapped.
  301.  * Store all the window-manager-related information for the
  302.  * window.
  303.  */
  304. if (wmPtr->titleUid == NULL) {
  305.     wmPtr->titleUid = winPtr->nameUid;
  306. }
  307. if (!Tk_IsEmbedded(winPtr)) {
  308.     TkSetWMName(winPtr, wmPtr->titleUid);
  309. }
  310. TkWmSetClass(winPtr);
  311. if (wmPtr->iconName != NULL) {
  312.     XSetIconName(winPtr->display, winPtr->window, wmPtr->iconName);
  313. }
  314. wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
  315.     }
  316.     if (wmPtr->hints.initial_state == WithdrawnState) {
  317. return;
  318.     }
  319.     /*
  320.      * TODO: we need to display a window if it's iconic on creation.
  321.      */
  322.     if (wmPtr->hints.initial_state == IconicState) {
  323. return;
  324.     }
  325.     /*
  326.      * Update geometry information.
  327.      */
  328.     wmPtr->flags |= WM_ABOUT_TO_MAP;
  329.     if (wmPtr->flags & WM_UPDATE_PENDING) {
  330. Tk_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
  331.     }
  332.     UpdateGeometryInfo((ClientData) winPtr);
  333.     wmPtr->flags &= ~WM_ABOUT_TO_MAP;
  334.     /*
  335.      * Map the window.
  336.      */
  337.     XMapWindow(winPtr->display, winPtr->window);
  338. }
  339. /*
  340.  *----------------------------------------------------------------------
  341.  *
  342.  * TkWmUnmapWindow --
  343.  *
  344.  * This procedure is invoked to unmap a top-level window.
  345.  * On the Macintosh all we do is call XUnmapWindow.
  346.  *
  347.  * Results:
  348.  * None.
  349.  *
  350.  * Side effects:
  351.  * Unmaps the window.
  352.  *
  353.  *----------------------------------------------------------------------
  354.  */
  355. void
  356. TkWmUnmapWindow(
  357.     TkWindow *winPtr) /* Top-level window that's about to
  358.  * be mapped. */
  359. {
  360.     XUnmapWindow(winPtr->display, winPtr->window);
  361. }
  362. /*
  363.  *----------------------------------------------------------------------
  364.  *
  365.  * TkWmDeadWindow --
  366.  *
  367.  * This procedure is invoked when a top-level window is
  368.  * about to be deleted. It cleans up the wm-related data
  369.  * structures for the window.
  370.  *
  371.  * Results:
  372.  * None.
  373.  *
  374.  * Side effects:
  375.  * The WmInfo structure for winPtr gets freed up.
  376.  *
  377.  *----------------------------------------------------------------------
  378.  */
  379. void
  380. TkWmDeadWindow(
  381.     TkWindow *winPtr) /* Top-level window that's being deleted. */
  382. {
  383.     WmInfo *wmPtr = winPtr->wmInfoPtr;
  384.     WmInfo *wmPtr2;
  385.     if (wmPtr == NULL) {
  386. return;
  387.     }
  388.     if (wmPtr->hints.flags & IconPixmapHint) {
  389. Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap);
  390.     }
  391.     if (wmPtr->hints.flags & IconMaskHint) {
  392. Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_mask);
  393.     }
  394.     if (wmPtr->leaderName != NULL) {
  395. ckfree(wmPtr->leaderName);
  396.     }
  397.     if (wmPtr->masterWindowName != NULL) {
  398. ckfree(wmPtr->masterWindowName);
  399.     }
  400.     if (wmPtr->icon != NULL) {
  401. wmPtr2 = ((TkWindow *) wmPtr->icon)->wmInfoPtr;
  402. wmPtr2->iconFor = NULL;
  403.     }
  404.     if (wmPtr->iconFor != NULL) {
  405. wmPtr2 = ((TkWindow *) wmPtr->iconFor)->wmInfoPtr;
  406. wmPtr2->icon = NULL;
  407. wmPtr2->hints.flags &= ~IconWindowHint;
  408.     }
  409.     while (wmPtr->protPtr != NULL) {
  410. ProtocolHandler *protPtr;
  411. protPtr = wmPtr->protPtr;
  412. wmPtr->protPtr = protPtr->nextPtr;
  413. Tcl_EventuallyFree((ClientData) protPtr, TCL_DYNAMIC);
  414.     }
  415.     if (wmPtr->cmdArgv != NULL) {
  416. ckfree((char *) wmPtr->cmdArgv);
  417.     }
  418.     if (wmPtr->clientMachine != NULL) {
  419. ckfree((char *) wmPtr->clientMachine);
  420.     }
  421.     if (wmPtr->flags & WM_UPDATE_PENDING) {
  422. Tk_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
  423.     }
  424.     ckfree((char *) wmPtr);
  425.     winPtr->wmInfoPtr = NULL;
  426. }
  427. /*
  428.  *----------------------------------------------------------------------
  429.  *
  430.  * TkWmSetClass --
  431.  *
  432.  * This procedure is invoked whenever a top-level window's
  433.  * class is changed. If the window has been mapped then this
  434.  * procedure updates the window manager property for the
  435.  * class. If the window hasn't been mapped, the update is
  436.  * deferred until just before the first mapping.
  437.  *
  438.  * Results:
  439.  * None.
  440.  *
  441.  * Side effects:
  442.  * A window property may get updated.
  443.  *
  444.  *----------------------------------------------------------------------
  445.  */
  446. void
  447. TkWmSetClass(
  448.     TkWindow *winPtr) /* Newly-created top-level window. */
  449. {
  450.     return;
  451. }
  452. /*
  453.  *----------------------------------------------------------------------
  454.  *
  455.  * Tk_WmObjCmd --
  456.  *
  457.  * This procedure is invoked to process the "wm" Tcl command.
  458.  * See the user documentation for details on what it does.
  459.  *
  460.  * Results:
  461.  * A standard Tcl result.
  462.  *
  463.  * Side effects:
  464.  * See the user documentation.
  465.  *
  466.  *----------------------------------------------------------------------
  467.  */
  468. /* ARGSUSED */
  469. int
  470. Tk_WmObjCmd(
  471.     ClientData clientData, /* Main window associated with interpreter. */
  472.     Tcl_Interp *interp, /* Current interpreter. */
  473.     int objc, /* Number of arguments. */
  474.     Tcl_Obj *const objv[]) /* Argument objects. */
  475. {
  476.     Tk_Window tkwin = (Tk_Window) clientData;
  477.     static const char *optionStrings[] = {
  478. "aspect", "attributes", "client", "colormapwindows",
  479. "command", "deiconify", "focusmodel",/* "forget",*/
  480. "frame", "geometry", "grid", "group",
  481. "iconbitmap", "iconify", "iconmask", "iconname",
  482. "iconphoto", "iconposition", "iconwindow",
  483. /*"manage", */"maxsize", "minsize", "overrideredirect",
  484. "positionfrom", "protocol", "resizable", "sizefrom",
  485. "stackorder", "state", "title", "transient",
  486. "withdraw", NULL };
  487.     enum options {
  488. WMOPT_ASPECT, WMOPT_ATTRIBUTES, WMOPT_CLIENT, WMOPT_COLORMAPWINDOWS,
  489. WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL,/* WMOPT_FORGET,*/
  490. WMOPT_FRAME, WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP,
  491. WMOPT_ICONBITMAP, WMOPT_ICONIFY, WMOPT_ICONMASK, WMOPT_ICONNAME,
  492. WMOPT_ICONPHOTO, WMOPT_ICONPOSITION, WMOPT_ICONWINDOW,
  493. /*WMOPT_MANAGE, */WMOPT_MAXSIZE, WMOPT_MINSIZE, WMOPT_OVERRIDEREDIRECT,
  494. WMOPT_POSITIONFROM, WMOPT_PROTOCOL, WMOPT_RESIZABLE, WMOPT_SIZEFROM,
  495. WMOPT_STACKORDER, WMOPT_STATE, WMOPT_TITLE, WMOPT_TRANSIENT,
  496. WMOPT_WITHDRAW };
  497.     int index, length;
  498.     char *argv1;
  499.     TkWindow *winPtr;
  500.     if (objc < 2) {
  501. wrongNumArgs:
  502. Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?");
  503. return TCL_ERROR;
  504.     }
  505.     argv1 = Tcl_GetStringFromObj(objv[1], &length);
  506.     if ((argv1[0] == 't') && (strncmp(argv1, "tracing", length) == 0)
  507. && (length >= 3)) {
  508. if ((objc != 2) && (objc != 3)) {
  509.     Tcl_WrongNumArgs(interp, 2, objv, "?boolean?");
  510.     return TCL_ERROR;
  511. }
  512. if (objc == 2) {
  513.     Tcl_SetResult(interp, ((wmTracing) ? "on" : "off"), TCL_STATIC);
  514.     return TCL_OK;
  515. }
  516. return Tcl_GetBooleanFromObj(interp, objv[2], &wmTracing);
  517.     }
  518.     if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
  519.     &index) != TCL_OK) {
  520. return TCL_ERROR;
  521.     }
  522.     if (objc < 3) {
  523. goto wrongNumArgs;
  524.     }
  525.     if (TkGetWindowFromObj(interp, tkwin, objv[2], (Tk_Window *) &winPtr)
  526. != TCL_OK) {
  527. return TCL_ERROR;
  528.     }
  529.     if (!Tk_IsTopLevel(winPtr)
  530. #if 0
  531.     && (index != WMOPT_MANAGE) && (index != WMOPT_FORGET)
  532. #endif
  533.     ) {
  534. Tcl_AppendResult(interp, "window "", winPtr->pathName,
  535. "" isn't a top-level window", NULL);
  536. return TCL_ERROR;
  537.     }
  538.     switch ((enum options) index) {
  539. case WMOPT_ASPECT:
  540.     return WmAspectCmd(tkwin, winPtr, interp, objc, objv);
  541. case WMOPT_ATTRIBUTES:
  542.     return WmAttributesCmd(tkwin, winPtr, interp, objc, objv);
  543. case WMOPT_CLIENT:
  544.     return WmClientCmd(tkwin, winPtr, interp, objc, objv);
  545. case WMOPT_COLORMAPWINDOWS:
  546.     return WmColormapwindowsCmd(tkwin, winPtr, interp, objc, objv);
  547. case WMOPT_COMMAND:
  548.     return WmCommandCmd(tkwin, winPtr, interp, objc, objv);
  549. case WMOPT_DEICONIFY:
  550.     return WmDeiconifyCmd(tkwin, winPtr, interp, objc, objv);
  551. case WMOPT_FOCUSMODEL:
  552.     return WmFocusmodelCmd(tkwin, winPtr, interp, objc, objv);
  553. #if 0
  554. case WMOPT_FORGET:
  555.     return WmForgetCmd(tkwin, winPtr, interp, objc, objv);
  556. #endif
  557. case WMOPT_FRAME:
  558.     return WmFrameCmd(tkwin, winPtr, interp, objc, objv);
  559. case WMOPT_GEOMETRY:
  560.     return WmGeometryCmd(tkwin, winPtr, interp, objc, objv);
  561. case WMOPT_GRID:
  562.     return WmGridCmd(tkwin, winPtr, interp, objc, objv);
  563. case WMOPT_GROUP:
  564.     return WmGroupCmd(tkwin, winPtr, interp, objc, objv);
  565. case WMOPT_ICONBITMAP:
  566.     return WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv);
  567. case WMOPT_ICONIFY:
  568.     return WmIconifyCmd(tkwin, winPtr, interp, objc, objv);
  569. case WMOPT_ICONMASK:
  570.     return WmIconmaskCmd(tkwin, winPtr, interp, objc, objv);
  571. case WMOPT_ICONNAME:
  572.     return WmIconnameCmd(tkwin, winPtr, interp, objc, objv);
  573. case WMOPT_ICONPHOTO:
  574.     return WmIconphotoCmd(tkwin, winPtr, interp, objc, objv);
  575. case WMOPT_ICONPOSITION:
  576.     return WmIconpositionCmd(tkwin, winPtr, interp, objc, objv);
  577. case WMOPT_ICONWINDOW:
  578.     return WmIconwindowCmd(tkwin, winPtr, interp, objc, objv);
  579. #if 0
  580. case WMOPT_MANAGE:
  581.     return WmManageCmd(tkwin, winPtr, interp, objc, objv);
  582. #endif
  583. case WMOPT_MAXSIZE:
  584.     return WmMaxsizeCmd(tkwin, winPtr, interp, objc, objv);
  585. case WMOPT_MINSIZE:
  586.     return WmMinsizeCmd(tkwin, winPtr, interp, objc, objv);
  587. case WMOPT_OVERRIDEREDIRECT:
  588.     return WmOverrideredirectCmd(tkwin, winPtr, interp, objc, objv);
  589. case WMOPT_POSITIONFROM:
  590.     return WmPositionfromCmd(tkwin, winPtr, interp, objc, objv);
  591. case WMOPT_PROTOCOL:
  592.     return WmProtocolCmd(tkwin, winPtr, interp, objc, objv);
  593. case WMOPT_RESIZABLE:
  594.     return WmResizableCmd(tkwin, winPtr, interp, objc, objv);
  595. case WMOPT_SIZEFROM:
  596.     return WmSizefromCmd(tkwin, winPtr, interp, objc, objv);
  597. case WMOPT_STACKORDER:
  598.     return WmStackorderCmd(tkwin, winPtr, interp, objc, objv);
  599. case WMOPT_STATE:
  600.     return WmStateCmd(tkwin, winPtr, interp, objc, objv);
  601. case WMOPT_TITLE:
  602.     return WmTitleCmd(tkwin, winPtr, interp, objc, objv);
  603. case WMOPT_TRANSIENT:
  604.     return WmTransientCmd(tkwin, winPtr, interp, objc, objv);
  605. case WMOPT_WITHDRAW:
  606.     return WmWithdrawCmd(tkwin, winPtr, interp, objc, objv);
  607.     }
  608.     /* This should not happen */
  609.     return TCL_ERROR;
  610. }
  611. /*
  612.  *----------------------------------------------------------------------
  613.  *
  614.  * WmAspectCmd --
  615.  *
  616.  * This procedure is invoked to process the "wm aspect" Tcl command.
  617.  * See the user documentation for details on what it does.
  618.  *
  619.  * Results:
  620.  * A standard Tcl result.
  621.  *
  622.  * Side effects:
  623.  * See the user documentation.
  624.  *
  625.  *----------------------------------------------------------------------
  626.  */
  627. static int
  628. WmAspectCmd(
  629.     Tk_Window tkwin, /* Main window of the application. */
  630.     TkWindow *winPtr, /* Toplevel to work with */
  631.     Tcl_Interp *interp, /* Current interpreter. */
  632.     int objc, /* Number of arguments. */
  633.     Tcl_Obj *const objv[]) /* Argument objects. */
  634. {
  635.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  636.     int numer1, denom1, numer2, denom2;
  637.     if ((objc != 3) && (objc != 7)) {
  638. Tcl_WrongNumArgs(interp, 2, objv,
  639. "window ?minNumer minDenom maxNumer maxDenom?");
  640. return TCL_ERROR;
  641.     }
  642.     if (objc == 3) {
  643. if (wmPtr->sizeHintsFlags & PAspect) {
  644.     char buf[TCL_INTEGER_SPACE * 4];
  645.     sprintf(buf, "%d %d %d %d", wmPtr->minAspect.x,
  646.     wmPtr->minAspect.y, wmPtr->maxAspect.x,
  647.     wmPtr->maxAspect.y);
  648.     Tcl_SetResult(interp, buf, TCL_VOLATILE);
  649. }
  650. return TCL_OK;
  651.     }
  652.     if (*Tcl_GetString(objv[3]) == '') {
  653. wmPtr->sizeHintsFlags &= ~PAspect;
  654.     } else {
  655. if ((Tcl_GetIntFromObj(interp, objv[3], &numer1) != TCL_OK)
  656.     || (Tcl_GetIntFromObj(interp, objv[4], &denom1) != TCL_OK)
  657.     || (Tcl_GetIntFromObj(interp, objv[5], &numer2) != TCL_OK)
  658.     || (Tcl_GetIntFromObj(interp, objv[6], &denom2) != TCL_OK)) {
  659.     return TCL_ERROR;
  660. }
  661. if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) ||
  662.     (denom2 <= 0)) {
  663.     Tcl_SetResult(interp, "aspect number can't be <= 0",
  664.     TCL_STATIC);
  665.     return TCL_ERROR;
  666. }
  667. wmPtr->minAspect.x = numer1;
  668. wmPtr->minAspect.y = denom1;
  669. wmPtr->maxAspect.x = numer2;
  670. wmPtr->maxAspect.y = denom2;
  671. wmPtr->sizeHintsFlags |= PAspect;
  672.     }
  673.     wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
  674.     WmUpdateGeom(wmPtr, winPtr);
  675.     return TCL_OK;
  676. }
  677. /*
  678.  *----------------------------------------------------------------------
  679.  *
  680.  * WmSetAttribute --
  681.  *
  682.  * Helper routine for WmAttributesCmd. Sets the value
  683.  * of the specified attribute.
  684.  *
  685.  * Returns:
  686.  *
  687.  * TCL_OK if successful, TCL_ERROR otherwise. In case of an
  688.  * error, leaves a message in the interpreter's result.
  689.  *
  690.  *----------------------------------------------------------------------
  691.  */
  692. static int WmSetAttribute(
  693.     TkWindow *winPtr, /* Toplevel to work with */
  694.     WindowRef macWindow,
  695.     Tcl_Interp *interp, /* Current interpreter */
  696.     WmAttribute attribute, /* Code of attribute to set */
  697.     Tcl_Obj *value) /* New value */
  698. {
  699.     WmInfo *wmPtr = winPtr->wmInfoPtr;
  700.     int boolean;
  701.     switch (attribute) {
  702. case WMATT_ALPHA: {
  703.     double dval;
  704.     if (Tcl_GetDoubleFromObj(interp, value, &dval) != TCL_OK) {
  705. return TCL_ERROR;
  706.     }
  707.     /*
  708.      * The user should give (transparent) 0 .. 1.0 (opaque)
  709.      */
  710.     if (dval < 0.0) {
  711. dval = 0.0;
  712.     } else if (dval > 1.0) {
  713. dval = 1.0;
  714.     }
  715.     ChkErr(SetWindowAlpha, macWindow, dval);
  716.     break;
  717. }
  718. case WMATT_FULLSCREEN:
  719.     if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) {
  720. return TCL_ERROR;
  721.     }
  722.     if (boolean != ((wmPtr->flags & WM_FULLSCREEN) != 0)) {
  723. if(TkMacOSXMakeFullscreen(winPtr, macWindow, boolean, interp)
  724. != TCL_OK) {
  725.     return TCL_ERROR;
  726. }
  727.     }
  728.     break;
  729. case WMATT_MODIFIED:
  730.     if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) {
  731. return TCL_ERROR;
  732.     }
  733.     if (boolean != IsWindowModified(macWindow)) {
  734. ChkErr(SetWindowModified, macWindow, boolean);
  735.     }
  736.     break;
  737. #if 0
  738. case WMATT_NOTIFY:
  739.     if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) {
  740. return TCL_ERROR;
  741.     }
  742.     if (boolean == !tkMacOSXWmAttrNotifyVal) {
  743. static NMRec notifyRec;
  744. if (boolean) {
  745.     bzero(&notifyRec, sizeof(notifyRec));
  746.     notifyRec.qType = nmType;
  747.     notifyRec.nmMark = 1;
  748.     ChkErr(NMInstall, &notifyRec);
  749. } else {
  750.     ChkErr(NMRemove, &notifyRec);
  751. }
  752. tkMacOSXWmAttrNotifyVal = boolean;
  753.     }
  754.     break;
  755. #endif
  756. case WMATT_TITLEPATH: {
  757.     const char *path;
  758.     OSStatus err;
  759.     path = Tcl_FSGetNativePath(value);
  760.     if (path && *path) {
  761. FSRef ref;
  762. Boolean d;
  763. err = ChkErr(FSPathMakeRef, (const unsigned char*) path, &ref,
  764. &d);
  765. if (err == noErr) {
  766.     TK_IF_MAC_OS_X_API (4, HIWindowSetProxyFSRef,
  767. err = ChkErr(HIWindowSetProxyFSRef, macWindow, &ref);
  768.     ) TK_ELSE_MAC_OS_X (4,
  769. AliasHandle alias;
  770. err = ChkErr(FSNewAlias, NULL, &ref, &alias);
  771. if (err == noErr) {
  772.     err = ChkErr(SetWindowProxyAlias, macWindow,
  773.     alias);
  774.     DisposeHandle((Handle) alias);
  775. }
  776.     ) TK_ENDIF
  777. }
  778.     } else {
  779. int len;
  780. Tcl_GetStringFromObj(value, &len);
  781. if (!len) {
  782.     err = ChkErr(RemoveWindowProxy, macWindow);
  783. } else {
  784.     err = fnfErr;
  785. }
  786.     }
  787.     if (err != noErr) {
  788. return TCL_ERROR;
  789.     }
  790.     break;
  791. }
  792. case WMATT_TOPMOST: {
  793.     if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) {
  794. return TCL_ERROR;
  795.     }
  796.     if (boolean != ((wmPtr->flags & WM_TOPMOST) != 0)) {
  797. WindowGroupRef group;
  798. if (boolean) {
  799.     wmPtr->flags |= WM_TOPMOST;
  800. } else {
  801.     wmPtr->flags &= ~WM_TOPMOST;
  802. }
  803. group = WmGetWindowGroup(winPtr);
  804. if (group && group != GetWindowGroup(macWindow)) {
  805.     ChkErr(SetWindowGroup, macWindow, group);
  806. }
  807.     }
  808.     break;
  809. }
  810. case WMATT_TRANSPARENT:
  811.     if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) {
  812. return TCL_ERROR;
  813.     }
  814.     if (boolean != ((wmPtr->flags & WM_TRANSPARENT) != 0)) {
  815. WindowAttributes oldAttributes = wmPtr->attributes;
  816. if (boolean) {
  817.     wmPtr->flags |= WM_TRANSPARENT;
  818.     wmPtr->attributes |= kWindowNoShadowAttribute;
  819.     TK_IF_MAC_OS_X_API (3, HIWindowChangeFeatures,
  820. UInt32 features;
  821. ChkErr(GetWindowFeatures, macWindow, &features);
  822. if (features & kWindowIsOpaque) {
  823.     ChkErr(HIWindowChangeFeatures, macWindow, 0,
  824.     kWindowIsOpaque);
  825. }
  826.     ) TK_ENDIF
  827. } else {
  828.     wmPtr->flags &= ~WM_TRANSPARENT;
  829.     wmPtr->attributes &= ~kWindowNoShadowAttribute;
  830. }
  831. ApplyWindowClassAttributeChanges(winPtr, macWindow,
  832. wmPtr->macClass, oldAttributes, 1);
  833. ChkErr(ReshapeCustomWindow, macWindow);
  834. TkMacOSXInvalidateWindow((MacDrawable *)(winPtr->window),
  835. TK_PARENT_WINDOW);
  836.     }
  837.     break;
  838. case _WMATT_LAST_ATTRIBUTE:
  839. default:
  840.     return TCL_ERROR;
  841.     }
  842.     return TCL_OK;
  843. }
  844. /*
  845.  *----------------------------------------------------------------------
  846.  *
  847.  * WmGetAttribute --
  848.  *
  849.  * Helper routine for WmAttributesCmd. Returns the current value
  850.  * of the specified attribute.
  851.  *
  852.  *----------------------------------------------------------------------
  853.  */
  854. static Tcl_Obj *WmGetAttribute(
  855.     TkWindow *winPtr, /* Toplevel to work with */
  856.     WindowRef macWindow,
  857.     WmAttribute attribute) /* Code of attribute to get */
  858. {
  859.     WmInfo *wmPtr = winPtr->wmInfoPtr;
  860.     Tcl_Obj *result = NULL;
  861.     switch (attribute) {
  862. case WMATT_ALPHA: {
  863.     float fval = 1.0;
  864.     ChkErr(GetWindowAlpha, macWindow, &fval);
  865.     result = Tcl_NewDoubleObj(fval);
  866.     break;
  867. }
  868. case WMATT_FULLSCREEN:
  869.     result = Tcl_NewBooleanObj(wmPtr->flags & WM_FULLSCREEN);
  870.     break;
  871. case WMATT_MODIFIED:
  872.     result = Tcl_NewBooleanObj(IsWindowModified(macWindow));
  873.     break;
  874. #if 0
  875. case WMATT_NOTIFY:
  876.     result = Tcl_NewBooleanObj(tkMacOSXWmAttrNotifyVal);
  877.     break;
  878. #endif
  879. case WMATT_TITLEPATH: {
  880.     FSRef ref;
  881.     UInt8 path[PATH_MAX+1];
  882.     OSStatus err;
  883.     TK_IF_MAC_OS_X_API (4, HIWindowSetProxyFSRef,
  884. err = ChkErr(HIWindowGetProxyFSRef, macWindow, &ref);
  885.     ) TK_ELSE_MAC_OS_X (4,
  886. Boolean wasChanged;
  887. AliasHandle alias;
  888. err = ChkErr(GetWindowProxyAlias, macWindow, &alias);
  889. if (err == noErr) {
  890.     err = ChkErr(FSResolveAlias, NULL, alias, &ref,
  891.     &wasChanged);
  892. }
  893.     ) TK_ENDIF
  894.     if (err == noErr) {
  895. err = ChkErr(FSRefMakePath, &ref, path, PATH_MAX);
  896.     }
  897.     if (err != noErr) {
  898. *path = 0;
  899.     }
  900.     result = Tcl_NewStringObj((char*) path, -1);
  901.     break;
  902. }
  903. case WMATT_TOPMOST:
  904.     result = Tcl_NewBooleanObj(wmPtr->flags & WM_TOPMOST);
  905.     break;
  906. case WMATT_TRANSPARENT:
  907.     result = Tcl_NewBooleanObj(wmPtr->flags & WM_TRANSPARENT);
  908.     break;
  909. case _WMATT_LAST_ATTRIBUTE:
  910. default:
  911.     break;
  912.     }
  913.     return result;
  914. }
  915. /*
  916.  *----------------------------------------------------------------------
  917.  *
  918.  * WmAttributesCmd --
  919.  *
  920.  * This procedure is invoked to process the "wm attributes" Tcl command.
  921.  * See the user documentation for details on what it does.
  922.  *
  923.  * Results:
  924.  * A standard Tcl result.
  925.  *
  926.  * Side effects:
  927.  * See the user documentation.
  928.  *
  929.  *----------------------------------------------------------------------
  930.  */
  931. static int
  932. WmAttributesCmd(
  933.     Tk_Window tkwin, /* Main window of the application. */
  934.     TkWindow *winPtr, /* Toplevel to work with */
  935.     Tcl_Interp *interp, /* Current interpreter. */
  936.     int objc, /* Number of arguments. */
  937.     Tcl_Obj *const objv[]) /* Argument objects. */
  938. {
  939.     int attribute = 0;
  940.     WindowRef macWindow;
  941.     if (winPtr->window == None) {
  942. Tk_MakeWindowExist((Tk_Window) winPtr);
  943.     }
  944.     if (!TkMacOSXHostToplevelExists(winPtr)) {
  945. TkMacOSXMakeRealWindowExist(winPtr);
  946.     }
  947.     macWindow = TkMacOSXDrawableWindow(winPtr->window);
  948.     if (objc == 3) { /* wm attributes $win */
  949. Tcl_Obj *result = Tcl_NewListObj(0,0);
  950. for (attribute = 0; attribute < _WMATT_LAST_ATTRIBUTE; ++attribute) {
  951.     Tcl_ListObjAppendElement(interp, result,
  952.     Tcl_NewStringObj(WmAttributeNames[attribute], -1));
  953.     Tcl_ListObjAppendElement(interp, result,
  954.     WmGetAttribute(winPtr, macWindow, attribute));
  955. }
  956. Tcl_SetObjResult(interp, result);
  957.     } else if (objc == 4)  { /* wm attributes $win -attribute */
  958. if (Tcl_GetIndexFromObj(interp, objv[3], WmAttributeNames,
  959.     "attribute", 0, &attribute) != TCL_OK) {
  960.     return TCL_ERROR;
  961. }
  962. Tcl_SetObjResult(interp, WmGetAttribute(winPtr, macWindow, attribute));
  963.     } else if ((objc - 3) % 2 == 0) { /* wm attributes $win -att value... */
  964. int i;
  965. for (i = 3; i < objc; i += 2) {
  966.     if (Tcl_GetIndexFromObj(interp, objv[i], WmAttributeNames,
  967. "attribute", 0, &attribute) != TCL_OK) {
  968. return TCL_ERROR;
  969.     }
  970.     if (WmSetAttribute(winPtr, macWindow, interp, attribute, objv[i+1])
  971.     != TCL_OK) {
  972. return TCL_ERROR;
  973.     }
  974. }
  975.     } else {
  976. Tcl_WrongNumArgs(interp, 2, objv, "window ?-attribute ?value ...??");
  977. return TCL_ERROR;
  978.     }
  979.     return TCL_OK;
  980. }
  981. /*
  982.  *----------------------------------------------------------------------
  983.  *
  984.  * WmClientCmd --
  985.  *
  986.  * This procedure is invoked to process the "wm client" Tcl command.
  987.  * See the user documentation for details on what it does.
  988.  *
  989.  * Results:
  990.  * A standard Tcl result.
  991.  *
  992.  * Side effects:
  993.  * See the user documentation.
  994.  *
  995.  *----------------------------------------------------------------------
  996.  */
  997. static int
  998. WmClientCmd(
  999.     Tk_Window tkwin, /* Main window of the application. */
  1000.     TkWindow *winPtr, /* Toplevel to work with */
  1001.     Tcl_Interp *interp, /* Current interpreter. */
  1002.     int objc, /* Number of arguments. */
  1003.     Tcl_Obj *const objv[]) /* Argument objects. */
  1004. {
  1005.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  1006.     char *argv3;
  1007.     int length;
  1008.     if ((objc != 3) && (objc != 4)) {
  1009. Tcl_WrongNumArgs(interp, 2, objv, "window ?name?");
  1010. return TCL_ERROR;
  1011.     }
  1012.     if (objc == 3) {
  1013. if (wmPtr->clientMachine != NULL) {
  1014.     Tcl_SetResult(interp, wmPtr->clientMachine, TCL_STATIC);
  1015. }
  1016. return TCL_OK;
  1017.     }
  1018.     argv3 = Tcl_GetStringFromObj(objv[3], &length);
  1019.     if (argv3[0] == 0) {
  1020. if (wmPtr->clientMachine != NULL) {
  1021.     ckfree((char *) wmPtr->clientMachine);
  1022.     wmPtr->clientMachine = NULL;
  1023. }
  1024. return TCL_OK;
  1025.     }
  1026.     if (wmPtr->clientMachine != NULL) {
  1027. ckfree((char *) wmPtr->clientMachine);
  1028.     }
  1029.     wmPtr->clientMachine = (char *)
  1030. ckalloc((unsigned) (length + 1));
  1031.     strcpy(wmPtr->clientMachine, argv3);
  1032.     return TCL_OK;
  1033. }
  1034. /*
  1035.  *----------------------------------------------------------------------
  1036.  *
  1037.  * WmColormapwindowsCmd --
  1038.  *
  1039.  * This procedure is invoked to process the "wm colormapwindows"
  1040.  * Tcl command.
  1041.  * See the user documentation for details on what it does.
  1042.  *
  1043.  * Results:
  1044.  * A standard Tcl result.
  1045.  *
  1046.  * Side effects:
  1047.  * See the user documentation.
  1048.  *
  1049.  *----------------------------------------------------------------------
  1050.  */
  1051. static int
  1052. WmColormapwindowsCmd(
  1053.     Tk_Window tkwin, /* Main window of the application. */
  1054.     TkWindow *winPtr, /* Toplevel to work with */
  1055.     Tcl_Interp *interp, /* Current interpreter. */
  1056.     int objc, /* Number of arguments. */
  1057.     Tcl_Obj *const objv[]) /* Argument objects. */
  1058. {
  1059.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  1060.     TkWindow **cmapList;
  1061.     TkWindow *winPtr2;
  1062.     int i, windowObjc, gotToplevel = 0;
  1063.     Tcl_Obj **windowObjv;
  1064.     if ((objc != 3) && (objc != 4)) {
  1065. Tcl_WrongNumArgs(interp, 2, objv, "window ?windowList?");
  1066. return TCL_ERROR;
  1067.     }
  1068.     if (objc == 3) {
  1069. Tk_MakeWindowExist((Tk_Window) winPtr);
  1070. for (i = 0; i < wmPtr->cmapCount; i++) {
  1071.     if ((i == (wmPtr->cmapCount-1))
  1072. && (wmPtr->flags & WM_ADDED_TOPLEVEL_COLORMAP)) {
  1073. break;
  1074.     }
  1075.     Tcl_AppendElement(interp, wmPtr->cmapList[i]->pathName);
  1076. }
  1077. return TCL_OK;
  1078.     }
  1079.     if (Tcl_ListObjGetElements(interp, objv[3], &windowObjc, &windowObjv)
  1080. != TCL_OK) {
  1081. return TCL_ERROR;
  1082.     }
  1083.     cmapList = (TkWindow **) ckalloc((unsigned)
  1084. ((windowObjc+1)*sizeof(TkWindow*)));
  1085.     for (i = 0; i < windowObjc; i++) {
  1086. if (TkGetWindowFromObj(interp, tkwin, windowObjv[i],
  1087. (Tk_Window *) &winPtr2) != TCL_OK)
  1088. {
  1089.     ckfree((char *) cmapList);
  1090.     return TCL_ERROR;
  1091. }
  1092. if (winPtr2 == winPtr) {
  1093.     gotToplevel = 1;
  1094. }
  1095. if (winPtr2->window == None) {
  1096.     Tk_MakeWindowExist((Tk_Window) winPtr2);
  1097. }
  1098. cmapList[i] = winPtr2;
  1099.     }
  1100.     if (!gotToplevel) {
  1101. wmPtr->flags |= WM_ADDED_TOPLEVEL_COLORMAP;
  1102. cmapList[windowObjc] = winPtr;
  1103. windowObjc++;
  1104.     } else {
  1105. wmPtr->flags &= ~WM_ADDED_TOPLEVEL_COLORMAP;
  1106.     }
  1107.     wmPtr->flags |= WM_COLORMAPS_EXPLICIT;
  1108.     if (wmPtr->cmapList != NULL) {
  1109. ckfree((char *)wmPtr->cmapList);
  1110.     }
  1111.     wmPtr->cmapList = cmapList;
  1112.     wmPtr->cmapCount = windowObjc;
  1113.     /*
  1114.      * On the Macintosh all of this is just an excercise
  1115.      * in compatability as we don't support colormaps. If
  1116.      * we did they would be installed here.
  1117.      */
  1118.     return TCL_OK;
  1119. }
  1120. /*
  1121.  *----------------------------------------------------------------------
  1122.  *
  1123.  * WmCommandCmd --
  1124.  *
  1125.  * This procedure is invoked to process the "wm command" Tcl command.
  1126.  * See the user documentation for details on what it does.
  1127.  *
  1128.  * Results:
  1129.  * A standard Tcl result.
  1130.  *
  1131.  * Side effects:
  1132.  * See the user documentation.
  1133.  *
  1134.  *----------------------------------------------------------------------
  1135.  */
  1136. static int
  1137. WmCommandCmd(
  1138.     Tk_Window tkwin, /* Main window of the application. */
  1139.     TkWindow *winPtr, /* Toplevel to work with */
  1140.     Tcl_Interp *interp, /* Current interpreter. */
  1141.     int objc, /* Number of arguments. */
  1142.     Tcl_Obj *const objv[]) /* Argument objects. */
  1143. {
  1144.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  1145.     char *argv3;
  1146.     int cmdArgc;
  1147.     const char **cmdArgv;
  1148.     if ((objc != 3) && (objc != 4)) {
  1149. Tcl_WrongNumArgs(interp, 2, objv, "window ?value?");
  1150. return TCL_ERROR;
  1151.     }
  1152.     if (objc == 3) {
  1153. if (wmPtr->cmdArgv != NULL) {
  1154.     Tcl_SetResult(interp,
  1155.     Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv),
  1156.     TCL_DYNAMIC);
  1157. }
  1158. return TCL_OK;
  1159.     }
  1160.     argv3 = Tcl_GetString(objv[3]);
  1161.     if (argv3[0] == 0) {
  1162. if (wmPtr->cmdArgv != NULL) {
  1163.     ckfree((char *) wmPtr->cmdArgv);
  1164.     wmPtr->cmdArgv = NULL;
  1165. }
  1166. return TCL_OK;
  1167.     }
  1168.     if (Tcl_SplitList(interp, argv3, &cmdArgc, &cmdArgv) != TCL_OK) {
  1169. return TCL_ERROR;
  1170.     }
  1171.     if (wmPtr->cmdArgv != NULL) {
  1172. ckfree((char *) wmPtr->cmdArgv);
  1173.     }
  1174.     wmPtr->cmdArgc = cmdArgc;
  1175.     wmPtr->cmdArgv = cmdArgv;
  1176.     return TCL_OK;
  1177. }
  1178. /*
  1179.  *----------------------------------------------------------------------
  1180.  *
  1181.  * WmDeiconifyCmd --
  1182.  *
  1183.  * This procedure is invoked to process the "wm deiconify" Tcl command.
  1184.  * See the user documentation for details on what it does.
  1185.  *
  1186.  * Results:
  1187.  * A standard Tcl result.
  1188.  *
  1189.  * Side effects:
  1190.  * See the user documentation.
  1191.  *
  1192.  *----------------------------------------------------------------------
  1193.  */
  1194. static int
  1195. WmDeiconifyCmd(
  1196.     Tk_Window tkwin, /* Main window of the application. */
  1197.     TkWindow *winPtr, /* Toplevel to work with */
  1198.     Tcl_Interp *interp, /* Current interpreter. */
  1199.     int objc, /* Number of arguments. */
  1200.     Tcl_Obj *const objv[]) /* Argument objects. */
  1201. {
  1202.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  1203.     if (objc != 3) {
  1204. Tcl_WrongNumArgs(interp, 2, objv, "window");
  1205. return TCL_ERROR;
  1206.     }
  1207.     if (wmPtr->iconFor != NULL) {
  1208. Tcl_AppendResult(interp, "can't deiconify ", Tcl_GetString(objv[2]),
  1209. ": it is an icon for ", Tk_PathName(wmPtr->iconFor), NULL);
  1210. return TCL_ERROR;
  1211.     }
  1212.     if (winPtr->flags & TK_EMBEDDED) {
  1213. Tcl_AppendResult(interp, "can't deiconify ", winPtr->pathName,
  1214. ": it is an embedded window", NULL);
  1215. return TCL_ERROR;
  1216.     }
  1217.     TkpWmSetState(winPtr, TkMacOSXIsWindowZoomed(winPtr) ?
  1218.     ZoomState : NormalState);
  1219.     return TCL_OK;
  1220. }
  1221. /*
  1222.  *----------------------------------------------------------------------
  1223.  *
  1224.  * WmFocusmodelCmd --
  1225.  *
  1226.  * This procedure is invoked to process the "wm focusmodel" Tcl command.
  1227.  * See the user documentation for details on what it does.
  1228.  *
  1229.  * Results:
  1230.  * A standard Tcl result.
  1231.  *
  1232.  * Side effects:
  1233.  * See the user documentation.
  1234.  *
  1235.  *----------------------------------------------------------------------
  1236.  */
  1237. static int
  1238. WmFocusmodelCmd(
  1239.     Tk_Window tkwin, /* Main window of the application. */
  1240.     TkWindow *winPtr, /* Toplevel to work with */
  1241.     Tcl_Interp *interp, /* Current interpreter. */
  1242.     int objc, /* Number of arguments. */
  1243.     Tcl_Obj *const objv[]) /* Argument objects. */
  1244. {
  1245.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  1246.     static const char *optionStrings[] = {
  1247. "active", "passive", NULL };
  1248.     enum options {
  1249. OPT_ACTIVE, OPT_PASSIVE };
  1250.     int index;
  1251.     if ((objc != 3) && (objc != 4)) {
  1252. Tcl_WrongNumArgs(interp, 2, objv, "window ?active|passive?");
  1253. return TCL_ERROR;
  1254.     }
  1255.     if (objc == 3) {
  1256. Tcl_SetResult(interp, (wmPtr->hints.input ? "passive" : "active"),
  1257. TCL_STATIC);
  1258. return TCL_OK;
  1259.     }
  1260.     if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
  1261.     &index) != TCL_OK) {
  1262. return TCL_ERROR;
  1263.     }
  1264.     if (index == OPT_ACTIVE) {
  1265. wmPtr->hints.input = False;
  1266.     } else { /* OPT_PASSIVE */
  1267. wmPtr->hints.input = True;
  1268.     }
  1269.     return TCL_OK;
  1270. }
  1271. #if 0
  1272. /*
  1273.  *----------------------------------------------------------------------
  1274.  *
  1275.  * WmForgetCmd --
  1276.  *
  1277.  * This procedure is invoked to process the "wm forget" Tcl command.
  1278.  * See the user documentation for details on what it does.
  1279.  *
  1280.  * Results:
  1281.  * A standard Tcl result.
  1282.  *
  1283.  * Side effects:
  1284.  * See the user documentation.
  1285.  *
  1286.  *----------------------------------------------------------------------
  1287.  */
  1288. static int
  1289. WmForgetCmd(tkwin, winPtr, interp, objc, objv)
  1290.     Tk_Window tkwin; /* Main window of the application. */
  1291.     TkWindow *winPtr;           /* Toplevel or Frame to work with */
  1292.     Tcl_Interp *interp; /* Current interpreter. */
  1293.     int objc; /* Number of arguments. */
  1294.     Tcl_Obj *CONST objv[]; /* Argument objects. */
  1295. {
  1296. #if 1
  1297.     Tcl_AppendResult(interp, "wm forget is not yet supported", (char*)NULL);
  1298.     return TCL_ERROR;
  1299. #else
  1300.     register Tk_Window frameWin = (Tk_Window)winPtr;
  1301.     char *oldClass = (char*)Tk_Class(frameWin);
  1302.     if (Tk_IsTopLevel(frameWin)) {
  1303. MacDrawable *macWin = (MacDrawable *) winPtr->window;
  1304. CGrafPtr destPort = TkMacOSXGetDrawablePort(winPtr->window);
  1305. TkFocusJoin(winPtr);
  1306. Tk_UnmapWindow(frameWin);
  1307. if (destPort != NULL) {
  1308.     WindowRef winRef;
  1309.     winRef = GetWindowFromPort(destPort);
  1310.     TkMacOSXUnregisterMacWindow(winRef);
  1311.     DisposeWindow(winRef);
  1312. }
  1313. macWin->grafPtr = NULL;
  1314. macWin->toplevel = winPtr->parentPtr->privatePtr->toplevel;
  1315. macWin->flags &= ~TK_HOST_EXISTS;
  1316. RemapWindows(winPtr, macWin);
  1317. TkWmDeadWindow(winPtr);
  1318. winPtr->flags &= ~(TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED);
  1319. TkMapTopFrame(frameWin);
  1320.     } else {
  1321. /* Already not managed by wm - ignore it */
  1322.     }
  1323.     return TCL_OK;
  1324. #endif
  1325. }
  1326. #endif
  1327. /*
  1328.  *----------------------------------------------------------------------
  1329.  *
  1330.  * WmFrameCmd --
  1331.  *
  1332.  * This procedure is invoked to process the "wm frame" Tcl command.
  1333.  * See the user documentation for details on what it does.
  1334.  *
  1335.  * Results:
  1336.  * A standard Tcl result.
  1337.  *
  1338.  * Side effects:
  1339.  * See the user documentation.
  1340.  *
  1341.  *----------------------------------------------------------------------
  1342.  */
  1343. static int
  1344. WmFrameCmd(
  1345.     Tk_Window tkwin, /* Main window of the application. */
  1346.     TkWindow *winPtr, /* Toplevel to work with */
  1347.     Tcl_Interp *interp, /* Current interpreter. */
  1348.     int objc, /* Number of arguments. */
  1349.     Tcl_Obj *const objv[]) /* Argument objects. */
  1350. {
  1351.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  1352.     Window window;
  1353.     char buf[TCL_INTEGER_SPACE];
  1354.     if (objc != 3) {
  1355. Tcl_WrongNumArgs(interp, 2, objv, "window");
  1356. return TCL_ERROR;
  1357.     }
  1358.     window = wmPtr->reparent;
  1359.     if (window == None) {
  1360. window = Tk_WindowId((Tk_Window) winPtr);
  1361.     }
  1362.     sprintf(buf, "0x%x", (unsigned int) window);
  1363.     Tcl_SetResult(interp, buf, TCL_VOLATILE);
  1364.     return TCL_OK;
  1365. }
  1366. /*
  1367.  *----------------------------------------------------------------------
  1368.  *
  1369.  * WmGeometryCmd --
  1370.  *
  1371.  * This procedure is invoked to process the "wm geometry" Tcl command.
  1372.  * See the user documentation for details on what it does.
  1373.  *
  1374.  * Results:
  1375.  * A standard Tcl result.
  1376.  *
  1377.  * Side effects:
  1378.  * See the user documentation.
  1379.  *
  1380.  *----------------------------------------------------------------------
  1381.  */
  1382. static int
  1383. WmGeometryCmd(
  1384.     Tk_Window tkwin, /* Main window of the application. */
  1385.     TkWindow *winPtr, /* Toplevel to work with */
  1386.     Tcl_Interp *interp, /* Current interpreter. */
  1387.     int objc, /* Number of arguments. */
  1388.     Tcl_Obj *const objv[]) /* Argument objects. */
  1389. {
  1390.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  1391.     char xSign, ySign;
  1392.     int width, height;
  1393.     char *argv3;
  1394.     if ((objc != 3) && (objc != 4)) {
  1395. Tcl_WrongNumArgs(interp, 2, objv, "window ?newGeometry?");
  1396. return TCL_ERROR;
  1397.     }
  1398.     if (objc == 3) {
  1399. char buf[16 + TCL_INTEGER_SPACE * 4];
  1400. xSign = (wmPtr->flags & WM_NEGATIVE_X) ? '-' : '+';
  1401. ySign = (wmPtr->flags & WM_NEGATIVE_Y) ? '-' : '+';
  1402. if (wmPtr->gridWin != NULL) {
  1403.     width = wmPtr->reqGridWidth + (winPtr->changes.width
  1404.     - winPtr->reqWidth)/wmPtr->widthInc;
  1405.     height = wmPtr->reqGridHeight + (winPtr->changes.height
  1406.     - winPtr->reqHeight)/wmPtr->heightInc;
  1407. } else {
  1408.     width = winPtr->changes.width;
  1409.     height = winPtr->changes.height;
  1410. }
  1411. sprintf(buf, "%dx%d%c%d%c%d", width, height, xSign, wmPtr->x,
  1412. ySign, wmPtr->y);
  1413. Tcl_SetResult(interp, buf, TCL_VOLATILE);
  1414. return TCL_OK;
  1415.     }
  1416.     argv3 = Tcl_GetString(objv[3]);
  1417.     if (*argv3 == '') {
  1418. wmPtr->width = -1;
  1419. wmPtr->height = -1;
  1420. WmUpdateGeom(wmPtr, winPtr);
  1421. return TCL_OK;
  1422.     }
  1423.     return ParseGeometry(interp, argv3, winPtr);
  1424. }
  1425. /*
  1426.  *----------------------------------------------------------------------
  1427.  *
  1428.  * WmGridCmd --
  1429.  *
  1430.  * This procedure is invoked to process the "wm grid" Tcl command.
  1431.  * See the user documentation for details on what it does.
  1432.  *
  1433.  * Results:
  1434.  * A standard Tcl result.
  1435.  *
  1436.  * Side effects:
  1437.  * See the user documentation.
  1438.  *
  1439.  *----------------------------------------------------------------------
  1440.  */
  1441. static int
  1442. WmGridCmd(
  1443.     Tk_Window tkwin, /* Main window of the application. */
  1444.     TkWindow *winPtr, /* Toplevel to work with */
  1445.     Tcl_Interp *interp, /* Current interpreter. */
  1446.     int objc, /* Number of arguments. */
  1447.     Tcl_Obj *const objv[]) /* Argument objects. */
  1448. {
  1449.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  1450.     int reqWidth, reqHeight, widthInc, heightInc;
  1451.     if ((objc != 3) && (objc != 7)) {
  1452. Tcl_WrongNumArgs(interp, 2, objv,
  1453. "window ?baseWidth baseHeight widthInc heightInc?");
  1454. return TCL_ERROR;
  1455.     }
  1456.     if (objc == 3) {
  1457. if (wmPtr->sizeHintsFlags & PBaseSize) {
  1458.     char buf[TCL_INTEGER_SPACE * 4];
  1459.     sprintf(buf, "%d %d %d %d", wmPtr->reqGridWidth,
  1460.     wmPtr->reqGridHeight, wmPtr->widthInc,
  1461.     wmPtr->heightInc);
  1462.     Tcl_SetResult(interp, buf, TCL_VOLATILE);
  1463. }
  1464. return TCL_OK;
  1465.     }
  1466.     if (*Tcl_GetString(objv[3]) == '') {
  1467. /*
  1468.  * Turn off gridding and reset the width and height
  1469.  * to make sense as ungridded numbers.
  1470.  */
  1471. wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc);
  1472. if (wmPtr->width != -1) {
  1473.     wmPtr->width = winPtr->reqWidth + (wmPtr->width
  1474.     - wmPtr->reqGridWidth)*wmPtr->widthInc;
  1475.     wmPtr->height = winPtr->reqHeight + (wmPtr->height
  1476.     - wmPtr->reqGridHeight)*wmPtr->heightInc;
  1477. }
  1478. wmPtr->widthInc = 1;
  1479. wmPtr->heightInc = 1;
  1480.     } else {
  1481. if ((Tcl_GetIntFromObj(interp, objv[3], &reqWidth) != TCL_OK)
  1482.     || (Tcl_GetIntFromObj(interp, objv[4], &reqHeight) != TCL_OK)
  1483.     || (Tcl_GetIntFromObj(interp, objv[5], &widthInc) != TCL_OK)
  1484.     || (Tcl_GetIntFromObj(interp, objv[6], &heightInc) != TCL_OK)) {
  1485.     return TCL_ERROR;
  1486. }
  1487. if (reqWidth < 0) {
  1488.     Tcl_SetResult(interp, "baseWidth can't be < 0", TCL_STATIC);
  1489.     return TCL_ERROR;
  1490. }
  1491. if (reqHeight < 0) {
  1492.     Tcl_SetResult(interp, "baseHeight can't be < 0", TCL_STATIC);
  1493.     return TCL_ERROR;
  1494. }
  1495. if (widthInc <= 0) {
  1496.     Tcl_SetResult(interp, "widthInc can't be <= 0", TCL_STATIC);
  1497.     return TCL_ERROR;
  1498. }
  1499. if (heightInc <= 0) {
  1500.     Tcl_SetResult(interp, "heightInc can't be <= 0", TCL_STATIC);
  1501.     return TCL_ERROR;
  1502. }
  1503. Tk_SetGrid((Tk_Window) winPtr, reqWidth, reqHeight, widthInc,
  1504. heightInc);
  1505.     }
  1506.     wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
  1507.     WmUpdateGeom(wmPtr, winPtr);
  1508.     return TCL_OK;
  1509. }
  1510. /*
  1511.  *----------------------------------------------------------------------
  1512.  *
  1513.  * WmGroupCmd --
  1514.  *
  1515.  * This procedure is invoked to process the "wm group" Tcl command.
  1516.  * See the user documentation for details on what it does.
  1517.  *
  1518.  * Results:
  1519.  * A standard Tcl result.
  1520.  *
  1521.  * Side effects:
  1522.  * See the user documentation.
  1523.  *
  1524.  *----------------------------------------------------------------------
  1525.  */
  1526. static int
  1527. WmGroupCmd(
  1528.     Tk_Window tkwin, /* Main window of the application. */
  1529.     TkWindow *winPtr, /* Toplevel to work with */
  1530.     Tcl_Interp *interp, /* Current interpreter. */
  1531.     int objc, /* Number of arguments. */
  1532.     Tcl_Obj *const objv[]) /* Argument objects. */
  1533. {
  1534.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  1535.     Tk_Window tkwin2;
  1536.     char *argv3;
  1537.     int length;
  1538.     if ((objc != 3) && (objc != 4)) {
  1539. Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?");
  1540. return TCL_ERROR;
  1541.     }
  1542.     if (objc == 3) {
  1543. if (wmPtr->hints.flags & WindowGroupHint) {
  1544.     Tcl_SetResult(interp, wmPtr->leaderName, TCL_STATIC);
  1545. }
  1546. return TCL_OK;
  1547.     }
  1548.     argv3 = Tcl_GetStringFromObj(objv[3], &length);
  1549.     if (*argv3 == '') {
  1550. wmPtr->hints.flags &= ~WindowGroupHint;
  1551. if (wmPtr->leaderName != NULL) {
  1552.     ckfree(wmPtr->leaderName);
  1553. }
  1554. wmPtr->leaderName = NULL;
  1555.     } else {
  1556. if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) {
  1557.     return TCL_ERROR;
  1558. }
  1559. Tk_MakeWindowExist(tkwin2);
  1560. if (wmPtr->leaderName != NULL) {
  1561.     ckfree(wmPtr->leaderName);
  1562. }
  1563. wmPtr->hints.window_group = Tk_WindowId(tkwin2);
  1564. wmPtr->hints.flags |= WindowGroupHint;
  1565. wmPtr->leaderName = ckalloc((unsigned) (length + 1));
  1566. strcpy(wmPtr->leaderName, argv3);
  1567.     }
  1568.     return TCL_OK;
  1569. }
  1570. /*
  1571.  *----------------------------------------------------------------------
  1572.  *
  1573.  * WmIconbitmapCmd --
  1574.  *
  1575.  * This procedure is invoked to process the "wm iconbitmap" Tcl command.
  1576.  * See the user documentation for details on what it does.
  1577.  *
  1578.  * Results:
  1579.  * A standard Tcl result.
  1580.  *
  1581.  * Side effects:
  1582.  * See the user documentation.
  1583.  *
  1584.  *----------------------------------------------------------------------
  1585.  */
  1586. static int
  1587. WmIconbitmapCmd(
  1588.     Tk_Window tkwin, /* Main window of the application. */
  1589.     TkWindow *winPtr, /* Toplevel to work with */
  1590.     Tcl_Interp *interp, /* Current interpreter. */
  1591.     int objc, /* Number of arguments. */
  1592.     Tcl_Obj *const objv[]) /* Argument objects. */
  1593. {
  1594.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  1595.     Pixmap pixmap;
  1596.     char *str;
  1597.     int len;
  1598.     if ((objc != 3) && (objc != 4)) {
  1599. Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?");
  1600. return TCL_ERROR;
  1601.     }
  1602.     if (objc == 3) {
  1603. if (wmPtr->hints.flags & IconPixmapHint) {
  1604.     Tcl_SetResult(interp, (char*)Tk_NameOfBitmap(winPtr->display,
  1605.     wmPtr->hints.icon_pixmap), TCL_STATIC);
  1606. }
  1607. return TCL_OK;
  1608.     }
  1609.     str = Tcl_GetStringFromObj(objv[3], &len);
  1610.     if (winPtr->window == None) {
  1611. Tk_MakeWindowExist((Tk_Window) winPtr);
  1612.     }
  1613.     if (!TkMacOSXHostToplevelExists(winPtr)) {
  1614. TkMacOSXMakeRealWindowExist(winPtr);
  1615.     }
  1616.     if (WmSetAttribute(winPtr, TkMacOSXDrawableWindow(winPtr->window), interp,
  1617.     WMATT_TITLEPATH, objv[3]) == TCL_OK) {
  1618. if (!len) {
  1619.     if (wmPtr->hints.icon_pixmap != None) {
  1620. Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap);
  1621. wmPtr->hints.icon_pixmap = None;
  1622.     }
  1623.     wmPtr->hints.flags &= ~IconPixmapHint;
  1624. }
  1625.     } else {
  1626. pixmap = Tk_GetBitmap(interp, (Tk_Window) winPtr, Tk_GetUid(str));
  1627. if (pixmap == None) {
  1628.     return TCL_ERROR;
  1629. }
  1630. wmPtr->hints.icon_pixmap = pixmap;
  1631. wmPtr->hints.flags |= IconPixmapHint;
  1632.     }
  1633.     return TCL_OK;
  1634. }
  1635. /*
  1636.  *----------------------------------------------------------------------
  1637.  *
  1638.  * WmIconifyCmd --
  1639.  *
  1640.  * This procedure is invoked to process the "wm iconify" Tcl command.
  1641.  * See the user documentation for details on what it does.
  1642.  *
  1643.  * Results:
  1644.  * A standard Tcl result.
  1645.  *
  1646.  * Side effects:
  1647.  * See the user documentation.
  1648.  *
  1649.  *----------------------------------------------------------------------
  1650.  */
  1651. static int
  1652. WmIconifyCmd(
  1653.     Tk_Window tkwin, /* Main window of the application. */
  1654.     TkWindow *winPtr, /* Toplevel to work with */
  1655.     Tcl_Interp *interp, /* Current interpreter. */
  1656.     int objc, /* Number of arguments. */
  1657.     Tcl_Obj *const objv[]) /* Argument objects. */
  1658. {
  1659.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  1660.     if (objc != 3) {
  1661. Tcl_WrongNumArgs(interp, 2, objv, "window");
  1662. return TCL_ERROR;
  1663.     }
  1664.     if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
  1665. Tcl_AppendResult(interp, "can't iconify "", winPtr->pathName,
  1666. "": override-redirect flag is set", NULL);
  1667. return TCL_ERROR;
  1668.     }
  1669.     if (wmPtr->master != None) {
  1670. Tcl_AppendResult(interp, "can't iconify "", winPtr->pathName,
  1671. "": it is a transient", NULL);
  1672. return TCL_ERROR;
  1673.     }
  1674.     if (wmPtr->iconFor != NULL) {
  1675. Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName,
  1676. ": it is an icon for ", Tk_PathName(wmPtr->iconFor), NULL);
  1677. return TCL_ERROR;
  1678.     }
  1679.     if (winPtr->flags & TK_EMBEDDED) {
  1680. Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName,
  1681. ": it is an embedded window", NULL);
  1682. return TCL_ERROR;
  1683.     }
  1684.     TkpWmSetState(winPtr, IconicState);
  1685.     return TCL_OK;
  1686. }
  1687. /*
  1688.  *----------------------------------------------------------------------
  1689.  *
  1690.  * WmIconmaskCmd --
  1691.  *
  1692.  * This procedure is invoked to process the "wm iconmask" Tcl command.
  1693.  * See the user documentation for details on what it does.
  1694.  *
  1695.  * Results:
  1696.  * A standard Tcl result.
  1697.  *
  1698.  * Side effects:
  1699.  * See the user documentation.
  1700.  *
  1701.  *----------------------------------------------------------------------
  1702.  */
  1703. static int
  1704. WmIconmaskCmd(
  1705.     Tk_Window tkwin, /* Main window of the application. */
  1706.     TkWindow *winPtr, /* Toplevel to work with */
  1707.     Tcl_Interp *interp, /* Current interpreter. */
  1708.     int objc, /* Number of arguments. */
  1709.     Tcl_Obj *const objv[]) /* Argument objects. */
  1710. {
  1711.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  1712.     Pixmap pixmap;
  1713.     char *argv3;
  1714.     if ((objc != 3) && (objc != 4)) {
  1715. Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?");
  1716. return TCL_ERROR;
  1717.     }
  1718.     if (objc == 3) {
  1719. if (wmPtr->hints.flags & IconMaskHint) {
  1720.     Tcl_SetResult(interp,
  1721.     (char*)Tk_NameOfBitmap(winPtr->display,
  1722.     wmPtr->hints.icon_mask), TCL_STATIC);
  1723. }
  1724. return TCL_OK;
  1725.     }
  1726.     argv3 = Tcl_GetString(objv[3]);
  1727.     if (*argv3 == '') {
  1728. if (wmPtr->hints.icon_mask != None) {
  1729.     Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_mask);
  1730. }
  1731. wmPtr->hints.flags &= ~IconMaskHint;
  1732.     } else {
  1733. pixmap = Tk_GetBitmap(interp, tkwin, argv3);
  1734. if (pixmap == None) {
  1735.     return TCL_ERROR;
  1736. }
  1737. wmPtr->hints.icon_mask = pixmap;
  1738. wmPtr->hints.flags |= IconMaskHint;
  1739.     }
  1740.     return TCL_OK;
  1741. }
  1742. /*
  1743.  *----------------------------------------------------------------------
  1744.  *
  1745.  * WmIconnameCmd --
  1746.  *
  1747.  * This procedure is invoked to process the "wm iconname" Tcl command.
  1748.  * See the user documentation for details on what it does.
  1749.  *
  1750.  * Results:
  1751.  * A standard Tcl result.
  1752.  *
  1753.  * Side effects:
  1754.  * See the user documentation.
  1755.  *
  1756.  *----------------------------------------------------------------------
  1757.  */
  1758. static int
  1759. WmIconnameCmd(
  1760.     Tk_Window tkwin, /* Main window of the application. */
  1761.     TkWindow *winPtr, /* Toplevel to work with */
  1762.     Tcl_Interp *interp, /* Current interpreter. */
  1763.     int objc, /* Number of arguments. */
  1764.     Tcl_Obj *const objv[]) /* Argument objects. */
  1765. {
  1766.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  1767.     const char *argv3;
  1768.     int length;
  1769.     if (objc > 4) {
  1770. Tcl_WrongNumArgs(interp, 2, objv, "window ?newName?");
  1771. return TCL_ERROR;
  1772.     }
  1773.     if (objc == 3) {
  1774. Tcl_SetResult(interp,
  1775. (char*)((wmPtr->iconName != NULL) ?
  1776. wmPtr->iconName : ""), TCL_STATIC);
  1777. return TCL_OK;
  1778.     } else {
  1779. if (wmPtr->iconName != NULL) {
  1780.     ckfree((char *) wmPtr->iconName);
  1781. }
  1782. argv3 = Tcl_GetStringFromObj(objv[3], &length);
  1783. wmPtr->iconName = ckalloc((unsigned) (length + 1));
  1784. strcpy(wmPtr->iconName, argv3);
  1785. if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
  1786.     XSetIconName(winPtr->display, winPtr->window, wmPtr->iconName);
  1787. }
  1788.     }
  1789.     return TCL_OK;
  1790. }
  1791. /*
  1792.  *----------------------------------------------------------------------
  1793.  *
  1794.  * WmIconphotoCmd --
  1795.  *
  1796.  * This procedure is invoked to process the "wm iconphoto"
  1797.  * Tcl command.
  1798.  * See the user documentation for details on what it does.
  1799.  * Not yet implemented for OS X.
  1800.  *
  1801.  * Results:
  1802.  * A standard Tcl result.
  1803.  *
  1804.  * Side effects:
  1805.  * See the user documentation.
  1806.  *
  1807.  *----------------------------------------------------------------------
  1808.  */
  1809. static int
  1810. WmIconphotoCmd(
  1811.     Tk_Window tkwin, /* Main window of the application. */
  1812.     TkWindow *winPtr, /* Toplevel to work with */
  1813.     Tcl_Interp *interp, /* Current interpreter. */
  1814.     int objc, /* Number of arguments. */
  1815.     Tcl_Obj *const objv[]) /* Argument objects. */
  1816. {
  1817.     Tk_PhotoHandle photo;
  1818.     int i, width, height, isDefault = 0;
  1819.     if (objc < 4) {
  1820. Tcl_WrongNumArgs(interp, 2, objv,
  1821. "window ?-default? image1 ?image2 ...?");
  1822. return TCL_ERROR;
  1823.     }
  1824.     if (strcmp(Tcl_GetString(objv[3]), "-default") == 0) {
  1825. isDefault = 1;
  1826. if (objc == 4) {
  1827.     Tcl_WrongNumArgs(interp, 2, objv,
  1828.     "window ?-default? image1 ?image2 ...?");
  1829.     return TCL_ERROR;
  1830. }
  1831.     }
  1832.     /*
  1833.      * Iterate over all images to retrieve their sizes, in order to allocate a
  1834.      * buffer large enough to hold all images.
  1835.      */
  1836.     for (i = 3 + isDefault; i < objc; i++) {
  1837. photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i]));
  1838. if (photo == NULL) {
  1839.     Tcl_AppendResult(interp, "can't use "", Tcl_GetString(objv[i]),
  1840.     "" as iconphoto: not a photo image", NULL);
  1841.     return TCL_ERROR;
  1842. }
  1843. Tk_PhotoGetSize(photo, &width, &height);
  1844.     }
  1845.     /*
  1846.      * This requires implementation for OS X, but we silently return
  1847.      * for now.
  1848.      */
  1849.     return TCL_OK;
  1850. }
  1851. /*
  1852.  *----------------------------------------------------------------------
  1853.  *
  1854.  * WmIconpositionCmd --
  1855.  *
  1856.  * This procedure is invoked to process the "wm iconposition"
  1857.  * Tcl command.
  1858.  * See the user documentation for details on what it does.
  1859.  *
  1860.  * Results:
  1861.  * A standard Tcl result.
  1862.  *
  1863.  * Side effects:
  1864.  * See the user documentation.
  1865.  *
  1866.  *----------------------------------------------------------------------
  1867.  */
  1868. static int
  1869. WmIconpositionCmd(
  1870.     Tk_Window tkwin, /* Main window of the application. */
  1871.     TkWindow *winPtr, /* Toplevel to work with */
  1872.     Tcl_Interp *interp, /* Current interpreter. */
  1873.     int objc, /* Number of arguments. */
  1874.     Tcl_Obj *const objv[]) /* Argument objects. */
  1875. {
  1876.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  1877.     int x, y;
  1878.     if ((objc != 3) && (objc != 5)) {
  1879. Tcl_WrongNumArgs(interp, 2, objv, "window ?x y?");
  1880. return TCL_ERROR;
  1881.     }
  1882.     if (objc == 3) {
  1883. if (wmPtr->hints.flags & IconPositionHint) {
  1884.     char buf[TCL_INTEGER_SPACE * 2];
  1885.     sprintf(buf, "%d %d", wmPtr->hints.icon_x,
  1886.     wmPtr->hints.icon_y);
  1887.     Tcl_SetResult(interp, buf, TCL_VOLATILE);
  1888. }
  1889. return TCL_OK;
  1890.     }
  1891.     if (*Tcl_GetString(objv[3]) == '') {
  1892. wmPtr->hints.flags &= ~IconPositionHint;
  1893.     } else {
  1894. if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
  1895.     || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)){
  1896.     return TCL_ERROR;
  1897. }
  1898. wmPtr->hints.icon_x = x;
  1899. wmPtr->hints.icon_y = y;
  1900. wmPtr->hints.flags |= IconPositionHint;
  1901.     }
  1902.     return TCL_OK;
  1903. }
  1904. /*
  1905.  *----------------------------------------------------------------------
  1906.  *
  1907.  * WmIconwindowCmd --
  1908.  *
  1909.  * This procedure is invoked to process the "wm iconwindow" Tcl command.
  1910.  * See the user documentation for details on what it does.
  1911.  *
  1912.  * Results:
  1913.  * A standard Tcl result.
  1914.  *
  1915.  * Side effects:
  1916.  * See the user documentation.
  1917.  *
  1918.  *----------------------------------------------------------------------
  1919.  */
  1920. static int
  1921. WmIconwindowCmd(
  1922.     Tk_Window tkwin, /* Main window of the application. */
  1923.     TkWindow *winPtr, /* Toplevel to work with */
  1924.     Tcl_Interp *interp, /* Current interpreter. */
  1925.     int objc, /* Number of arguments. */
  1926.     Tcl_Obj *const objv[]) /* Argument objects. */
  1927. {
  1928.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  1929.     Tk_Window tkwin2;
  1930.     WmInfo *wmPtr2;
  1931.     if ((objc != 3) && (objc != 4)) {
  1932. Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?");
  1933. return TCL_ERROR;
  1934.     }
  1935.     if (objc == 3) {
  1936. if (wmPtr->icon != NULL) {
  1937.     Tcl_SetResult(interp, Tk_PathName(wmPtr->icon), TCL_STATIC);
  1938. }
  1939. return TCL_OK;
  1940.     }
  1941.     if (*Tcl_GetString(objv[3]) == '') {
  1942. wmPtr->hints.flags &= ~IconWindowHint;
  1943. if (wmPtr->icon != NULL) {
  1944.     wmPtr2 = ((TkWindow *) wmPtr->icon)->wmInfoPtr;
  1945.     wmPtr2->iconFor = NULL;
  1946.     wmPtr2->hints.initial_state = WithdrawnState;
  1947. }
  1948. wmPtr->icon = NULL;
  1949.     } else {
  1950. if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) {
  1951.     return TCL_ERROR;
  1952. }
  1953. if (!Tk_IsTopLevel(tkwin2)) {
  1954.     Tcl_AppendResult(interp, "can't use ", Tcl_GetString(objv[3]),
  1955.     " as icon window: not at top level", NULL);
  1956.     return TCL_ERROR;
  1957. }
  1958. wmPtr2 = ((TkWindow *) tkwin2)->wmInfoPtr;
  1959. if (wmPtr2->iconFor != NULL) {
  1960.     Tcl_AppendResult(interp, Tcl_GetString(objv[3]),
  1961.     " is already an icon for ",
  1962.     Tk_PathName(wmPtr2->iconFor), NULL);
  1963.     return TCL_ERROR;
  1964. }
  1965. if (wmPtr->icon != NULL) {
  1966.     WmInfo *wmPtr3 = ((TkWindow *) wmPtr->icon)->wmInfoPtr;
  1967.     wmPtr3->iconFor = NULL;
  1968. }
  1969. Tk_MakeWindowExist(tkwin2);
  1970. wmPtr->hints.icon_window = Tk_WindowId(tkwin2);
  1971. wmPtr->hints.flags |= IconWindowHint;
  1972. wmPtr->icon = tkwin2;
  1973. wmPtr2->iconFor = (Tk_Window) winPtr;
  1974. if (!(wmPtr2->flags & WM_NEVER_MAPPED)) {
  1975.     /*
  1976.      * Don't have iconwindows on the Mac. We just withdraw.
  1977.      */
  1978.     Tk_UnmapWindow(tkwin2);
  1979. }
  1980.     }
  1981.     return TCL_OK;
  1982. }
  1983. #if 0
  1984. /*
  1985.  *----------------------------------------------------------------------
  1986.  *
  1987.  * WmManageCmd --
  1988.  *
  1989.  * This procedure is invoked to process the "wm manage" Tcl command.
  1990.  * See the user documentation for details on what it does.
  1991.  *
  1992.  * Results:
  1993.  * A standard Tcl result.
  1994.  *
  1995.  * Side effects:
  1996.  * See the user documentation.
  1997.  *
  1998.  *----------------------------------------------------------------------
  1999.  */
  2000. static int
  2001. WmManageCmd(
  2002.     Tk_Window tkwin, /* Main window of the application. */
  2003.     TkWindow *winPtr,           /* Toplevel or Frame to work with */
  2004.     Tcl_Interp *interp, /* Current interpreter. */
  2005.     int objc, /* Number of arguments. */
  2006.     Tcl_Obj *CONST objv[]) /* Argument objects. */
  2007. {
  2008. #if 1
  2009.     Tcl_AppendResult(interp, "wm manage is not yet supported", (char*)NULL);
  2010.     return TCL_ERROR;
  2011. #else
  2012.     register Tk_Window frameWin = (Tk_Window)winPtr;
  2013.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  2014.     char *oldClass = (char*)Tk_Class(frameWin);
  2015.     if (!Tk_IsTopLevel(frameWin)) {
  2016. MacDrawable *macWin = (MacDrawable *) winPtr->window;
  2017. TkFocusSplit(winPtr);
  2018. Tk_UnmapWindow(frameWin);
  2019. if (wmPtr == NULL) {
  2020.     TkWmNewWindow(winPtr);
  2021.     if (winPtr->window == None) {
  2022. Tk_MakeWindowExist((Tk_Window) winPtr);
  2023. macWin = (MacDrawable *) winPtr->window;
  2024.     }
  2025.     TkWmMapWindow(winPtr);
  2026.     Tk_UnmapWindow(frameWin);
  2027. }
  2028. wmPtr = winPtr->wmInfoPtr;
  2029. winPtr->flags &= ~TK_MAPPED;
  2030. macWin->grafPtr = NULL;
  2031. macWin->toplevel = macWin;
  2032. RemapWindows(winPtr, macWin);
  2033. winPtr->flags |= (TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED);
  2034. TkMapTopFrame (frameWin);
  2035.     } else if (Tk_IsTopLevel(frameWin)) {
  2036. /* Already managed by wm - ignore it */
  2037.     }
  2038.     return TCL_OK;
  2039. #endif
  2040. }
  2041. #endif
  2042. /*
  2043.  *----------------------------------------------------------------------
  2044.  *
  2045.  * WmMaxsizeCmd --
  2046.  *
  2047.  * This procedure is invoked to process the "wm maxsize" Tcl command.
  2048.  * See the user documentation for details on what it does.
  2049.  *
  2050.  * Results:
  2051.  * A standard Tcl result.
  2052.  *
  2053.  * Side effects:
  2054.  * See the user documentation.
  2055.  *
  2056.  *----------------------------------------------------------------------
  2057.  */
  2058. static int
  2059. WmMaxsizeCmd(
  2060.     Tk_Window tkwin, /* Main window of the application. */
  2061.     TkWindow *winPtr, /* Toplevel to work with */
  2062.     Tcl_Interp *interp, /* Current interpreter. */
  2063.     int objc, /* Number of arguments. */
  2064.     Tcl_Obj *const objv[]) /* Argument objects. */
  2065. {
  2066.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  2067.     int width, height;
  2068.     if ((objc != 3) && (objc != 5)) {
  2069. Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
  2070. return TCL_ERROR;
  2071.     }
  2072.     if (objc == 3) {
  2073. char buf[TCL_INTEGER_SPACE * 2];
  2074. GetMaxSize(winPtr, &width, &height);
  2075. sprintf(buf, "%d %d", width, height);
  2076. Tcl_SetResult(interp, buf, TCL_VOLATILE);
  2077. return TCL_OK;
  2078.     }
  2079.     if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
  2080. || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
  2081. return TCL_ERROR;
  2082.     }
  2083.     wmPtr->maxWidth = width;
  2084.     wmPtr->maxHeight = height;
  2085.     wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
  2086.     WmUpdateGeom(wmPtr, winPtr);
  2087.     return TCL_OK;
  2088. }
  2089. /*
  2090.  *----------------------------------------------------------------------
  2091.  *
  2092.  * WmMinsizeCmd --
  2093.  *
  2094.  * This procedure is invoked to process the "wm minsize" Tcl command.
  2095.  * See the user documentation for details on what it does.
  2096.  *
  2097.  * Results:
  2098.  * A standard Tcl result.
  2099.  *
  2100.  * Side effects:
  2101.  * See the user documentation.
  2102.  *
  2103.  *----------------------------------------------------------------------
  2104.  */
  2105. static int
  2106. WmMinsizeCmd(
  2107.     Tk_Window tkwin, /* Main window of the application. */
  2108.     TkWindow *winPtr, /* Toplevel to work with */
  2109.     Tcl_Interp *interp, /* Current interpreter. */
  2110.     int objc, /* Number of arguments. */
  2111.     Tcl_Obj *const objv[]) /* Argument objects. */
  2112. {
  2113.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  2114.     int width, height;
  2115.     if ((objc != 3) && (objc != 5)) {
  2116. Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
  2117. return TCL_ERROR;
  2118.     }
  2119.     if (objc == 3) {
  2120. char buf[TCL_INTEGER_SPACE * 2];
  2121. GetMinSize(winPtr, &width, &height);
  2122. sprintf(buf, "%d %d", width, height);
  2123. Tcl_SetResult(interp, buf, TCL_VOLATILE);
  2124. return TCL_OK;
  2125.     }
  2126.     if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK)
  2127. || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) {
  2128. return TCL_ERROR;
  2129.     }
  2130.     wmPtr->minWidth = width;
  2131.     wmPtr->minHeight = height;
  2132.     wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
  2133.     WmUpdateGeom(wmPtr, winPtr);
  2134.     return TCL_OK;
  2135. }
  2136. /*
  2137.  *----------------------------------------------------------------------
  2138.  *
  2139.  * WmOverrideredirectCmd --
  2140.  *
  2141.  * This procedure is invoked to process the "wm overrideredirect"
  2142.  * Tcl command.
  2143.  * See the user documentation for details on what it does.
  2144.  *
  2145.  * Results:
  2146.  * A standard Tcl result.
  2147.  *
  2148.  * Side effects:
  2149.  * See the user documentation.
  2150.  *
  2151.  *----------------------------------------------------------------------
  2152.  */
  2153. static int
  2154. WmOverrideredirectCmd(
  2155.     Tk_Window tkwin, /* Main window of the application. */
  2156.     TkWindow *winPtr, /* Toplevel to work with */
  2157.     Tcl_Interp *interp, /* Current interpreter. */
  2158.     int objc, /* Number of arguments. */
  2159.     Tcl_Obj *const objv[]) /* Argument objects. */
  2160. {
  2161.     int boolean;
  2162.     XSetWindowAttributes atts;
  2163.     if ((objc != 3) && (objc != 4)) {
  2164. Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
  2165. return TCL_ERROR;
  2166.     }
  2167.     if (objc == 3) {
  2168. Tcl_SetBooleanObj(Tcl_GetObjResult(interp),
  2169. Tk_Attributes((Tk_Window) winPtr)->override_redirect);
  2170. return TCL_OK;
  2171.     }
  2172.     if (Tcl_GetBooleanFromObj(interp, objv[3], &boolean) != TCL_OK) {
  2173. return TCL_ERROR;
  2174.     }
  2175.     atts.override_redirect = (boolean) ? True : False;
  2176.     Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWOverrideRedirect, &atts);
  2177.     ApplyMasterOverrideChanges(winPtr, NULL);
  2178.     return TCL_OK;
  2179. }
  2180. /*
  2181.  *----------------------------------------------------------------------
  2182.  *
  2183.  * WmPositionfromCmd --
  2184.  *
  2185.  * This procedure is invoked to process the "wm positionfrom"
  2186.  * Tcl command.
  2187.  * See the user documentation for details on what it does.
  2188.  *
  2189.  * Results:
  2190.  * A standard Tcl result.
  2191.  *
  2192.  * Side effects:
  2193.  * See the user documentation.
  2194.  *
  2195.  *----------------------------------------------------------------------
  2196.  */
  2197. static int
  2198. WmPositionfromCmd(
  2199.     Tk_Window tkwin, /* Main window of the application. */
  2200.     TkWindow *winPtr, /* Toplevel to work with */
  2201.     Tcl_Interp *interp, /* Current interpreter. */
  2202.     int objc, /* Number of arguments. */
  2203.     Tcl_Obj *const objv[]) /* Argument objects. */
  2204. {
  2205.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  2206.     static const char *optionStrings[] = {
  2207. "program", "user", NULL };
  2208.     enum options {
  2209. OPT_PROGRAM, OPT_USER };
  2210.     int index;
  2211.     if ((objc != 3) && (objc != 4)) {
  2212. Tcl_WrongNumArgs(interp, 2, objv, "window ?user/program?");
  2213. return TCL_ERROR;
  2214.     }
  2215.     if (objc == 3) {
  2216. if (wmPtr->sizeHintsFlags & USPosition) {
  2217.     Tcl_SetResult(interp, "user", TCL_STATIC);
  2218. } else if (wmPtr->sizeHintsFlags & PPosition) {
  2219.     Tcl_SetResult(interp, "program", TCL_STATIC);
  2220. }
  2221. return TCL_OK;
  2222.     }
  2223.     if (*Tcl_GetString(objv[3]) == '') {
  2224. wmPtr->sizeHintsFlags &= ~(USPosition|PPosition);
  2225.     } else {
  2226. if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
  2227. &index) != TCL_OK) {
  2228.     return TCL_ERROR;
  2229. }
  2230. if (index == OPT_USER) {
  2231.     wmPtr->sizeHintsFlags &= ~PPosition;
  2232.     wmPtr->sizeHintsFlags |= USPosition;
  2233. } else {
  2234.     wmPtr->sizeHintsFlags &= ~USPosition;
  2235.     wmPtr->sizeHintsFlags |= PPosition;
  2236. }
  2237.     }
  2238.     wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
  2239.     WmUpdateGeom(wmPtr, winPtr);
  2240.     return TCL_OK;
  2241. }
  2242. /*
  2243.  *----------------------------------------------------------------------
  2244.  *
  2245.  * WmProtocolCmd --
  2246.  *
  2247.  * This procedure is invoked to process the "wm protocol" Tcl command.
  2248.  * See the user documentation for details on what it does.
  2249.  *
  2250.  * Results:
  2251.  * A standard Tcl result.
  2252.  *
  2253.  * Side effects:
  2254.  * See the user documentation.
  2255.  *
  2256.  *----------------------------------------------------------------------
  2257.  */
  2258. static int
  2259. WmProtocolCmd(
  2260.     Tk_Window tkwin, /* Main window of the application. */
  2261.     TkWindow *winPtr, /* Toplevel to work with */
  2262.     Tcl_Interp *interp, /* Current interpreter. */
  2263.     int objc, /* Number of arguments. */
  2264.     Tcl_Obj *const objv[]) /* Argument objects. */
  2265. {
  2266.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  2267.     register ProtocolHandler *protPtr, *prevPtr;
  2268.     Atom protocol;
  2269.     char *cmd;
  2270.     int cmdLength;
  2271.     if ((objc < 3) || (objc > 5)) {
  2272. Tcl_WrongNumArgs(interp, 2, objv, "window ?name? ?command?");
  2273. return TCL_ERROR;
  2274.     }
  2275.     if (objc == 3) {
  2276. /*
  2277.  * Return a list of all defined protocols for the window.
  2278.  */
  2279. for (protPtr = wmPtr->protPtr; protPtr != NULL;
  2280. protPtr = protPtr->nextPtr) {
  2281.     Tcl_AppendElement(interp,
  2282.     Tk_GetAtomName((Tk_Window) winPtr, protPtr->protocol));
  2283. }
  2284. return TCL_OK;
  2285.     }
  2286.     protocol = Tk_InternAtom((Tk_Window) winPtr, Tcl_GetString(objv[3]));
  2287.     if (objc == 4) {
  2288. /*
  2289.  * Return the command to handle a given protocol.
  2290.  */
  2291. for (protPtr = wmPtr->protPtr; protPtr != NULL;
  2292. protPtr = protPtr->nextPtr) {
  2293.     if (protPtr->protocol == protocol) {
  2294. Tcl_SetResult(interp, protPtr->command, TCL_STATIC);
  2295. return TCL_OK;
  2296.     }
  2297. }
  2298. return TCL_OK;
  2299.     }
  2300.     /*
  2301.      * Delete any current protocol handler, then create a new
  2302.      * one with the specified command, unless the command is
  2303.      * empty.
  2304.      */
  2305.     for (protPtr = wmPtr->protPtr, prevPtr = NULL; protPtr != NULL;
  2306. prevPtr = protPtr, protPtr = protPtr->nextPtr) {
  2307. if (protPtr->protocol == protocol) {
  2308.     if (prevPtr == NULL) {
  2309. wmPtr->protPtr = protPtr->nextPtr;
  2310.     } else {
  2311. prevPtr->nextPtr = protPtr->nextPtr;
  2312.     }
  2313.     Tcl_EventuallyFree((ClientData) protPtr, TCL_DYNAMIC);
  2314.     break;
  2315. }
  2316.     }
  2317.     cmd = Tcl_GetStringFromObj(objv[4], &cmdLength);
  2318.     if (cmdLength > 0) {
  2319. protPtr = (ProtocolHandler *) ckalloc(HANDLER_SIZE(cmdLength));
  2320. protPtr->protocol = protocol;
  2321. protPtr->nextPtr = wmPtr->protPtr;
  2322. wmPtr->protPtr = protPtr;
  2323. protPtr->interp = interp;
  2324. strcpy(protPtr->command, cmd);
  2325.     }
  2326.     return TCL_OK;
  2327. }
  2328. /*
  2329.  *----------------------------------------------------------------------
  2330.  *
  2331.  * WmResizableCmd --
  2332.  *
  2333.  * This procedure is invoked to process the "wm resizable" Tcl command.
  2334.  * See the user documentation for details on what it does.
  2335.  *
  2336.  * Results:
  2337.  * A standard Tcl result.
  2338.  *
  2339.  * Side effects:
  2340.  * See the user documentation.
  2341.  *
  2342.  *----------------------------------------------------------------------
  2343.  */
  2344. static int
  2345. WmResizableCmd(
  2346.     Tk_Window tkwin, /* Main window of the application. */
  2347.     TkWindow *winPtr, /* Toplevel to work with */
  2348.     Tcl_Interp *interp, /* Current interpreter. */
  2349.     int objc, /* Number of arguments. */
  2350.     Tcl_Obj *const objv[]) /* Argument objects. */
  2351. {
  2352.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  2353.     int width, height;
  2354.     WindowAttributes oldAttributes = wmPtr->attributes;
  2355.     if ((objc != 3) && (objc != 5)) {
  2356. Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?");
  2357. return TCL_ERROR;
  2358.     }
  2359.     if (objc == 3) {
  2360. char buf[TCL_INTEGER_SPACE * 2];
  2361. sprintf(buf, "%d %d",
  2362. (wmPtr->flags  & WM_WIDTH_NOT_RESIZABLE) ? 0 : 1,
  2363. (wmPtr->flags  & WM_HEIGHT_NOT_RESIZABLE) ? 0 : 1);
  2364. Tcl_SetResult(interp, buf, TCL_VOLATILE);
  2365. return TCL_OK;
  2366.     }
  2367.     if ((Tcl_GetBooleanFromObj(interp, objv[3], &width) != TCL_OK)
  2368. || (Tcl_GetBooleanFromObj(interp, objv[4], &height) != TCL_OK)) {
  2369. return TCL_ERROR;
  2370.     }
  2371.     if (width) {
  2372. wmPtr->flags &= ~WM_WIDTH_NOT_RESIZABLE;
  2373. wmPtr->attributes |= kWindowHorizontalZoomAttribute;
  2374.     } else {
  2375. wmPtr->flags |= WM_WIDTH_NOT_RESIZABLE;
  2376. wmPtr->attributes &= ~kWindowHorizontalZoomAttribute;
  2377.     }
  2378.     if (height) {
  2379. wmPtr->flags &= ~WM_HEIGHT_NOT_RESIZABLE;
  2380. wmPtr->attributes |= kWindowVerticalZoomAttribute;
  2381.     } else {
  2382. wmPtr->flags |= WM_HEIGHT_NOT_RESIZABLE;
  2383. wmPtr->attributes &= ~kWindowVerticalZoomAttribute;
  2384.     }
  2385.     if (width || height) {
  2386. wmPtr->attributes |= kWindowResizableAttribute;
  2387.     } else {
  2388. wmPtr->attributes &= ~kWindowResizableAttribute;
  2389.     }
  2390.     wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
  2391.     if (wmPtr->scrollWinPtr != NULL) {
  2392. TkScrollbarEventuallyRedraw((TkScrollbar *)
  2393. wmPtr->scrollWinPtr->instanceData);
  2394.     }
  2395.     WmUpdateGeom(wmPtr, winPtr);
  2396.     ApplyWindowClassAttributeChanges(winPtr, NULL, wmPtr->macClass,
  2397. oldAttributes, 1);
  2398.     return TCL_OK;
  2399. }
  2400. /*
  2401.  *----------------------------------------------------------------------
  2402.  *
  2403.  * WmSizefromCmd --
  2404.  *
  2405.  * This procedure is invoked to process the "wm sizefrom" Tcl command.
  2406.  * See the user documentation for details on what it does.
  2407.  *
  2408.  * Results:
  2409.  * A standard Tcl result.
  2410.  *
  2411.  * Side effects:
  2412.  * See the user documentation.
  2413.  *
  2414.  *----------------------------------------------------------------------
  2415.  */
  2416. static int
  2417. WmSizefromCmd(
  2418.     Tk_Window tkwin, /* Main window of the application. */
  2419.     TkWindow *winPtr, /* Toplevel to work with */
  2420.     Tcl_Interp *interp, /* Current interpreter. */
  2421.     int objc, /* Number of arguments. */
  2422.     Tcl_Obj *const objv[]) /* Argument objects. */
  2423. {
  2424.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  2425.     static const char *optionStrings[] = {
  2426. "program", "user", NULL };
  2427.     enum options {
  2428. OPT_PROGRAM, OPT_USER };
  2429.     int index;
  2430.     if ((objc != 3) && (objc != 4)) {
  2431. Tcl_WrongNumArgs(interp, 2, objv, "window ?user|program?");
  2432. return TCL_ERROR;
  2433.     }
  2434.     if (objc == 3) {
  2435. if (wmPtr->sizeHintsFlags & USSize) {
  2436.     Tcl_SetResult(interp, "user", TCL_STATIC);
  2437. } else if (wmPtr->sizeHintsFlags & PSize) {
  2438.     Tcl_SetResult(interp, "program", TCL_STATIC);
  2439. }
  2440. return TCL_OK;
  2441.     }
  2442.     if (*Tcl_GetString(objv[3]) == '') {
  2443. wmPtr->sizeHintsFlags &= ~(USSize|PSize);
  2444.     } else {
  2445. if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
  2446. &index) != TCL_OK) {
  2447.     return TCL_ERROR;
  2448. }
  2449. if (index == OPT_USER) {
  2450.     wmPtr->sizeHintsFlags &= ~PSize;
  2451.     wmPtr->sizeHintsFlags |= USSize;
  2452. } else { /* OPT_PROGRAM */
  2453.     wmPtr->sizeHintsFlags &= ~USSize;
  2454.     wmPtr->sizeHintsFlags |= PSize;
  2455. }
  2456.     }
  2457.     wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
  2458.     WmUpdateGeom(wmPtr, winPtr);
  2459.     return TCL_OK;
  2460. }
  2461. /*
  2462.  *----------------------------------------------------------------------
  2463.  *
  2464.  * WmStackorderCmd --
  2465.  *
  2466.  * This procedure is invoked to process the "wm stackorder" Tcl command.
  2467.  * See the user documentation for details on what it does.
  2468.  *
  2469.  * Results:
  2470.  * A standard Tcl result.
  2471.  *
  2472.  * Side effects:
  2473.  * See the user documentation.
  2474.  *
  2475.  *----------------------------------------------------------------------
  2476.  */
  2477. static int
  2478. WmStackorderCmd(
  2479.     Tk_Window tkwin, /* Main window of the application. */
  2480.     TkWindow *winPtr, /* Toplevel to work with */
  2481.     Tcl_Interp *interp, /* Current interpreter. */
  2482.     int objc, /* Number of arguments. */
  2483.     Tcl_Obj *const objv[]) /* Argument objects. */
  2484. {
  2485.     TkWindow **windows, **window_ptr;
  2486.     static const char *optionStrings[] = {
  2487. "isabove", "isbelow", NULL };
  2488.     enum options {
  2489. OPT_ISABOVE, OPT_ISBELOW };
  2490.     int index;
  2491.     if ((objc != 3) && (objc != 5)) {
  2492. Tcl_WrongNumArgs(interp, 2, objv, "window ?isabove|isbelow window?");
  2493. return TCL_ERROR;
  2494.     }
  2495.     if (objc == 3) {
  2496. windows = TkWmStackorderToplevel(winPtr);
  2497. if (windows == NULL) {
  2498.     Tcl_Panic("TkWmStackorderToplevel failed");
  2499. } else {
  2500.     for (window_ptr = windows; *window_ptr ; window_ptr++) {
  2501. Tcl_AppendElement(interp, (*window_ptr)->pathName);
  2502.     }
  2503.     ckfree((char *) windows);
  2504.     return TCL_OK;
  2505. }
  2506.     } else {
  2507. TkWindow *winPtr2;
  2508. int index1=-1, index2=-1, result;
  2509. if (TkGetWindowFromObj(interp, tkwin, objv[4], (Tk_Window *) &winPtr2)
  2510.     != TCL_OK) {
  2511.     return TCL_ERROR;
  2512. }
  2513. if (!Tk_IsTopLevel(winPtr2)) {
  2514.     Tcl_AppendResult(interp, "window "", winPtr2->pathName,
  2515.     "" isn't a top-level window", NULL);
  2516.     return TCL_ERROR;
  2517. }
  2518. if (!Tk_IsMapped(winPtr)) {
  2519.     Tcl_AppendResult(interp, "window "", winPtr->pathName,
  2520.     "" isn't mapped", NULL);
  2521.     return TCL_ERROR;
  2522. }
  2523. if (!Tk_IsMapped(winPtr2)) {
  2524.     Tcl_AppendResult(interp, "window "", winPtr2->pathName,
  2525.     "" isn't mapped", NULL);
  2526.     return TCL_ERROR;
  2527. }
  2528. /*
  2529.  * Lookup stacking order of all toplevels that are children
  2530.  * of "." and find the position of winPtr and winPtr2
  2531.  * in the stacking order.
  2532.  */
  2533. windows = TkWmStackorderToplevel(winPtr->mainPtr->winPtr);
  2534. if (windows == NULL) {
  2535.     Tcl_AppendResult(interp, "TkWmStackorderToplevel failed", NULL);
  2536.     return TCL_ERROR;
  2537. } else {
  2538.     for (window_ptr = windows; *window_ptr ; window_ptr++) {
  2539. if (*window_ptr == winPtr)
  2540.     index1 = (window_ptr - windows);
  2541. if (*window_ptr == winPtr2)
  2542.     index2 = (window_ptr - windows);
  2543.     }
  2544.     if (index1 == -1)
  2545. Tcl_Panic("winPtr window not found");
  2546.     if (index2 == -1)
  2547. Tcl_Panic("winPtr2 window not found");
  2548.     ckfree((char *) windows);
  2549. }
  2550. if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
  2551. &index) != TCL_OK) {
  2552.     return TCL_ERROR;
  2553. }
  2554. if (index == OPT_ISABOVE) {
  2555.     result = index1 > index2;
  2556. } else { /* OPT_ISBELOW */
  2557.     result = index1 < index2;
  2558. }
  2559. Tcl_SetIntObj(Tcl_GetObjResult(interp), result);
  2560. return TCL_OK;
  2561.     }
  2562.     return TCL_OK;
  2563. }
  2564. /*
  2565.  *----------------------------------------------------------------------
  2566.  *
  2567.  * WmStateCmd --
  2568.  *
  2569.  * This procedure is invoked to process the "wm state" Tcl command.
  2570.  * See the user documentation for details on what it does.
  2571.  *
  2572.  * Results:
  2573.  * A standard Tcl result.
  2574.  *
  2575.  * Side effects:
  2576.  * See the user documentation.
  2577.  *
  2578.  *----------------------------------------------------------------------
  2579.  */
  2580. static int
  2581. WmStateCmd(
  2582.     Tk_Window tkwin, /* Main window of the application. */
  2583.     TkWindow *winPtr, /* Toplevel to work with */
  2584.     Tcl_Interp *interp, /* Current interpreter. */
  2585.     int objc, /* Number of arguments. */
  2586.     Tcl_Obj *const objv[]) /* Argument objects. */
  2587. {
  2588.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  2589.     static const char *optionStrings[] = {
  2590. "normal", "iconic", "withdrawn", "zoomed", NULL };
  2591.     enum options {
  2592. OPT_NORMAL, OPT_ICONIC, OPT_WITHDRAWN, OPT_ZOOMED };
  2593.     int index;
  2594.     if ((objc < 3) || (objc > 4)) {
  2595. Tcl_WrongNumArgs(interp, 2, objv, "window ?state?");
  2596. return TCL_ERROR;
  2597.     }
  2598.     if (objc == 4) {
  2599. if (wmPtr->iconFor != NULL) {
  2600.     Tcl_AppendResult(interp, "can't change state of ",
  2601.     Tcl_GetString(objv[2]), ": it is an icon for ",
  2602.     Tk_PathName(wmPtr->iconFor), NULL);
  2603.     return TCL_ERROR;
  2604. }
  2605. if (winPtr->flags & TK_EMBEDDED) {
  2606.     Tcl_AppendResult(interp, "can't change state of ",
  2607.     winPtr->pathName, ": it is an embedded window", NULL);
  2608.     return TCL_ERROR;
  2609. }
  2610. if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
  2611. &index) != TCL_OK) {
  2612.     return TCL_ERROR;
  2613. }
  2614. if (index == OPT_NORMAL) {
  2615.     TkpWmSetState(winPtr, NormalState);
  2616.     /*
  2617.      * This varies from 'wm deiconify' because it does not
  2618.      * force the window to be raised and receive focus
  2619.      */
  2620. } else if (index == OPT_ICONIC) {
  2621.     if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
  2622. Tcl_AppendResult(interp, "can't iconify "", winPtr->pathName,
  2623. "": override-redirect flag is set", NULL);
  2624. return TCL_ERROR;
  2625.     }
  2626.     if (wmPtr->master != None) {
  2627. Tcl_AppendResult(interp, "can't iconify "", winPtr->pathName,
  2628. "": it is a transient", NULL);
  2629. return TCL_ERROR;
  2630.     }
  2631.     TkpWmSetState(winPtr, IconicState);
  2632. } else if (index == OPT_WITHDRAWN) {
  2633.     TkpWmSetState(winPtr, WithdrawnState);
  2634. } else { /* OPT_ZOOMED */
  2635.     TkpWmSetState(winPtr, ZoomState);
  2636. }
  2637.     } else {
  2638. if (wmPtr->iconFor != NULL) {
  2639.     Tcl_SetResult(interp, "icon", TCL_STATIC);
  2640. } else {
  2641.     if (wmPtr->hints.initial_state == NormalState ||
  2642.     wmPtr->hints.initial_state == ZoomState) {
  2643. wmPtr->hints.initial_state = (TkMacOSXIsWindowZoomed(winPtr) ?
  2644. ZoomState : NormalState);
  2645.     }
  2646.     switch (wmPtr->hints.initial_state) {
  2647. case NormalState:
  2648.     Tcl_SetResult(interp, "normal", TCL_STATIC);
  2649.     break;
  2650. case IconicState:
  2651.     Tcl_SetResult(interp, "iconic", TCL_STATIC);
  2652.     break;
  2653. case WithdrawnState:
  2654.     Tcl_SetResult(interp, "withdrawn", TCL_STATIC);
  2655.     break;
  2656. case ZoomState:
  2657.     Tcl_SetResult(interp, "zoomed", TCL_STATIC);
  2658.     break;
  2659.     }
  2660. }
  2661.     }
  2662.     return TCL_OK;
  2663. }
  2664. /*
  2665.  *----------------------------------------------------------------------
  2666.  *
  2667.  * WmTitleCmd --
  2668.  *
  2669.  * This procedure is invoked to process the "wm title" Tcl command.
  2670.  * See the user documentation for details on what it does.
  2671.  *
  2672.  * Results:
  2673.  * A standard Tcl result.
  2674.  *
  2675.  * Side effects:
  2676.  * See the user documentation.
  2677.  *
  2678.  *----------------------------------------------------------------------
  2679.  */
  2680. static int
  2681. WmTitleCmd(
  2682.     Tk_Window tkwin, /* Main window of the application. */
  2683.     TkWindow *winPtr, /* Toplevel to work with */
  2684.     Tcl_Interp *interp, /* Current interpreter. */
  2685.     int objc, /* Number of arguments. */
  2686.     Tcl_Obj *const objv[]) /* Argument objects. */
  2687. {
  2688.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  2689.     char *argv3;
  2690.     int length;
  2691.     if (objc > 4) {
  2692. Tcl_WrongNumArgs(interp, 2, objv, "window ?newTitle?");
  2693. return TCL_ERROR;
  2694.     }
  2695.     if (objc == 3) {
  2696. Tcl_SetResult(interp, (char *)((wmPtr->titleUid != NULL) ?
  2697. wmPtr->titleUid : winPtr->nameUid), TCL_STATIC);
  2698. return TCL_OK;
  2699.     }
  2700.     argv3 = Tcl_GetStringFromObj(objv[3], &length);
  2701.     wmPtr->titleUid = Tk_GetUid(argv3);
  2702.     if (!(wmPtr->flags & WM_NEVER_MAPPED) && !Tk_IsEmbedded(winPtr)) {
  2703. TkSetWMName(winPtr, wmPtr->titleUid);
  2704.     }
  2705.     return TCL_OK;
  2706. }
  2707. /*
  2708.  *----------------------------------------------------------------------
  2709.  *
  2710.  * WmTransientCmd --
  2711.  *
  2712.  * This procedure is invoked to process the "wm transient" Tcl command.
  2713.  * See the user documentation for details on what it does.
  2714.  *
  2715.  * Results:
  2716.  * A standard Tcl result.
  2717.  *
  2718.  * Side effects:
  2719.  * See the user documentation.
  2720.  *
  2721.  *----------------------------------------------------------------------
  2722.  */
  2723. static int
  2724. WmTransientCmd(
  2725.     Tk_Window tkwin, /* Main window of the application. */
  2726.     TkWindow *winPtr, /* Toplevel to work with */
  2727.     Tcl_Interp *interp, /* Current interpreter. */
  2728.     int objc, /* Number of arguments. */
  2729.     Tcl_Obj *const objv[]) /* Argument objects. */
  2730. {
  2731.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  2732.     Tk_Window master;
  2733.     WmInfo *wmPtr2;
  2734.     char *argv3;
  2735.     int length;
  2736.     if ((objc != 3) && (objc != 4)) {
  2737. Tcl_WrongNumArgs(interp, 2, objv, "window ?master?");
  2738. return TCL_ERROR;
  2739.     }
  2740.     if (objc == 3) {
  2741. if (wmPtr->master != None) {
  2742.     Tcl_SetResult(interp, wmPtr->masterWindowName, TCL_STATIC);
  2743. }
  2744. return TCL_OK;
  2745.     }
  2746.     if (Tcl_GetString(objv[3])[0] == '') {
  2747. wmPtr->master = None;
  2748. if (wmPtr->masterWindowName != NULL) {
  2749.     ckfree(wmPtr->masterWindowName);
  2750. }
  2751. wmPtr->masterWindowName = NULL;
  2752.     } else {
  2753. if (TkGetWindowFromObj(interp, tkwin, objv[3], &master) != TCL_OK) {
  2754.     return TCL_ERROR;
  2755. }
  2756. Tk_MakeWindowExist(master);
  2757. if (wmPtr->iconFor != NULL) {
  2758.     Tcl_AppendResult(interp, "can't make "", Tcl_GetString(objv[2]),
  2759.     "" a transient: it is an icon for ",
  2760.     Tk_PathName(wmPtr->iconFor), NULL);
  2761.     return TCL_ERROR;
  2762. }
  2763. wmPtr2 = ((TkWindow *) master)->wmInfoPtr;
  2764. /* Under some circumstances, wmPtr2 is NULL here */
  2765. if (wmPtr2 != NULL && wmPtr2->iconFor != NULL) {
  2766.     Tcl_AppendResult(interp, "can't make "", Tcl_GetString(objv[3]),
  2767.     "" a master: it is an icon for ",
  2768.     Tk_PathName(wmPtr2->iconFor), NULL);
  2769.     return TCL_ERROR;
  2770. }
  2771. if ((TkWindow *) master == winPtr) {
  2772.     Tcl_AppendResult(interp, "can't make "", Tk_PathName(winPtr),
  2773.     "" its own master", NULL);
  2774.     return TCL_ERROR;
  2775. }
  2776. argv3 = Tcl_GetStringFromObj(objv[3], &length);
  2777. wmPtr->master = Tk_WindowId(master);
  2778. wmPtr->masterWindowName = ckalloc((unsigned) length+1);
  2779. strcpy(wmPtr->masterWindowName, argv3);
  2780.     }
  2781.     ApplyMasterOverrideChanges(winPtr, NULL);
  2782.     return TCL_OK;
  2783. }
  2784. /*
  2785.  *----------------------------------------------------------------------
  2786.  *
  2787.  * WmWithdrawCmd --
  2788.  *
  2789.  * This procedure is invoked to process the "wm withdraw" Tcl command.
  2790.  * See the user documentation for details on what it does.
  2791.  *
  2792.  * Results:
  2793.  * A standard Tcl result.
  2794.  *
  2795.  * Side effects:
  2796.  * See the user documentation.
  2797.  *
  2798.  *----------------------------------------------------------------------
  2799.  */
  2800. static int
  2801. WmWithdrawCmd(
  2802.     Tk_Window tkwin, /* Main window of the application. */
  2803.     TkWindow *winPtr, /* Toplevel to work with */
  2804.     Tcl_Interp *interp, /* Current interpreter. */
  2805.     int objc, /* Number of arguments. */
  2806.     Tcl_Obj *const objv[]) /* Argument objects. */
  2807. {
  2808.     register WmInfo *wmPtr = winPtr->wmInfoPtr;
  2809.     if (objc != 3) {
  2810. Tcl_WrongNumArgs(interp, 2, objv, "window");
  2811. return TCL_ERROR;
  2812.     }
  2813.     if (wmPtr->iconFor != NULL) {
  2814. Tcl_AppendResult(interp, "can't withdraw ", Tcl_GetString(objv[2]),
  2815. ": it is an icon for ", Tk_PathName(wmPtr->iconFor), NULL);
  2816. return TCL_ERROR;
  2817.     }
  2818.     TkpWmSetState(winPtr, WithdrawnState);
  2819.     return TCL_OK;
  2820. }
  2821. /*
  2822.  * Invoked by those wm subcommands that affect geometry.
  2823.  * Schedules a geometry update.
  2824.  */
  2825. static void
  2826. WmUpdateGeom(wmPtr, winPtr)
  2827. WmInfo *wmPtr;
  2828. TkWindow *winPtr;
  2829. {
  2830.     if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
  2831. Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
  2832. wmPtr->flags |= WM_UPDATE_PENDING;
  2833.     }
  2834. }
  2835. /*
  2836.  *----------------------------------------------------------------------
  2837.  *
  2838.  * Tk_SetGrid --
  2839.  *
  2840.  * This procedure is invoked by a widget when it wishes to set a grid
  2841.  * coordinate system that controls the size of a top-level window.
  2842.  * It provides a C interface equivalent to the "wm grid" command and
  2843.  * is usually asscoiated with the -setgrid option.
  2844.  *
  2845.  * Results:
  2846.  * None.
  2847.  *
  2848.  * Side effects:
  2849.  * Grid-related information will be passed to the window manager, so
  2850.  * that the top-level window associated with tkwin will resize on
  2851.  * even grid units. If some other window already controls gridding
  2852.  * for the top-level window then this procedure call has no effect.
  2853.  *
  2854.  *----------------------------------------------------------------------
  2855.  */
  2856. void
  2857. Tk_SetGrid(
  2858.     Tk_Window tkwin, /* Token for window. New window mgr info
  2859.  * will be posted for the top-level window
  2860.  * associated with this window. */
  2861.     int reqWidth, /* Width (in grid units) corresponding to
  2862.  * the requested geometry for tkwin. */
  2863.     int reqHeight, /* Height (in grid units) corresponding to
  2864.  * the requested geometry for tkwin. */
  2865.     int widthInc, int heightInc)/* Pixel increments corresponding to a
  2866.  * change of one grid unit. */
  2867. {
  2868.     TkWindow *winPtr = (TkWindow *) tkwin;
  2869.     WmInfo *wmPtr;
  2870.     /*
  2871.      * Ensure widthInc and heightInc are greater than 0
  2872.      */
  2873.     if (widthInc <= 0) {
  2874. widthInc = 1;
  2875.     }
  2876.     if (heightInc <= 0) {
  2877. heightInc = 1;
  2878.     }
  2879.     /*
  2880.      * Find the top-level window for tkwin, plus the window manager
  2881.      * information.
  2882.      */
  2883.     while (!(winPtr->flags & TK_TOP_LEVEL)) {
  2884. winPtr = winPtr->parentPtr;
  2885.     }
  2886.     wmPtr = winPtr->wmInfoPtr;
  2887.     if ((wmPtr->gridWin != NULL) && (wmPtr->gridWin != tkwin)) {
  2888. return;
  2889.     }
  2890.     if ((wmPtr->reqGridWidth == reqWidth)
  2891.     && (wmPtr->reqGridHeight == reqHeight)
  2892.     && (wmPtr->widthInc == widthInc)
  2893.     && (wmPtr->heightInc == heightInc)
  2894.     && ((wmPtr->sizeHintsFlags & (PBaseSize|PResizeInc))
  2895.     == (PBaseSize|PResizeInc))) {
  2896. return;
  2897.     }
  2898.     /*
  2899.      * If gridding was previously off, then forget about any window
  2900.      * size requests made by the user or via "wm geometry":  these are
  2901.      * in pixel units and there's no easy way to translate them to
  2902.      * grid units since the new requested size of the top-level window in
  2903.      * pixels may not yet have been registered yet (it may filter up
  2904.      * the hierarchy in DoWhenIdle handlers). However, if the window
  2905.      * has never been mapped yet then just leave the window size alone:
  2906.      * assume that it is intended to be in grid units but just happened
  2907.      * to have been specified before this procedure was called.
  2908.      */
  2909.     if ((wmPtr->gridWin == NULL) && !(wmPtr->flags & WM_NEVER_MAPPED)) {
  2910. wmPtr->width = -1;
  2911. wmPtr->height = -1;
  2912.     }
  2913.     /*
  2914.      * Set the new gridding information, and start the process of passing
  2915.      * all of this information to the window manager.
  2916.      */
  2917.     wmPtr->gridWin = tkwin;
  2918.     wmPtr->reqGridWidth = reqWidth;
  2919.     wmPtr->reqGridHeight = reqHeight;
  2920.     wmPtr->widthInc = widthInc;
  2921.     wmPtr->heightInc = heightInc;
  2922.     wmPtr->sizeHintsFlags |= PBaseSize|PResizeInc;
  2923.     wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
  2924.     if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
  2925. Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
  2926. wmPtr->flags |= WM_UPDATE_PENDING;
  2927.     }
  2928. }
  2929. /*
  2930.  *----------------------------------------------------------------------
  2931.  *
  2932.  * Tk_UnsetGrid --
  2933.  *
  2934.  * This procedure cancels the effect of a previous call
  2935.  * to Tk_SetGrid.
  2936.  *
  2937.  * Results:
  2938.  * None.
  2939.  *
  2940.  * Side effects:
  2941.  * If tkwin currently controls gridding for its top-level window,
  2942.  * gridding is cancelled for that top-level window; if some other
  2943.  * window controls gridding then this procedure has no effect.
  2944.  *
  2945.  *----------------------------------------------------------------------
  2946.  */
  2947. void
  2948. Tk_UnsetGrid(
  2949.     Tk_Window tkwin) /* Token for window that is currently
  2950.  * controlling gridding. */
  2951. {
  2952.     TkWindow *winPtr = (TkWindow *) tkwin;
  2953.     WmInfo *wmPtr;
  2954.     /*
  2955.      * Find the top-level window for tkwin, plus the window manager
  2956.      * information.
  2957.      */
  2958.     while (!(winPtr->flags & TK_TOP_LEVEL)) {
  2959. winPtr = winPtr->parentPtr;
  2960.     }
  2961.     wmPtr = winPtr->wmInfoPtr;
  2962.     if (tkwin != wmPtr->gridWin) {
  2963. return;
  2964.     }
  2965.     wmPtr->gridWin = NULL;
  2966.     wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc);
  2967.     if (wmPtr->width != -1) {
  2968. wmPtr->width = winPtr->reqWidth + (wmPtr->width
  2969. - wmPtr->reqGridWidth)*wmPtr->widthInc;
  2970. wmPtr->height = winPtr->reqHeight + (wmPtr->height
  2971. - wmPtr->reqGridHeight)*wmPtr->heightInc;
  2972.     }
  2973.     wmPtr->widthInc = 1;
  2974.     wmPtr->heightInc = 1;
  2975.     wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
  2976.     if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
  2977. Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
  2978. wmPtr->flags |= WM_UPDATE_PENDING;
  2979.     }
  2980. }
  2981. /*
  2982.  *----------------------------------------------------------------------
  2983.  *
  2984.  * TopLevelEventProc --
  2985.  *
  2986.  * This procedure is invoked when a top-level (or other externally-
  2987.  * managed window) is restructured in any way.
  2988.  *
  2989.  * Results:
  2990.  * None.
  2991.  *
  2992.  * Side effects:
  2993.  * Tk's internal data structures for the window get modified to
  2994.  * reflect the structural change.
  2995.  *
  2996.  *----------------------------------------------------------------------
  2997.  */
  2998. static void
  2999. TopLevelEventProc(
  3000.     ClientData clientData, /* Window for which event occurred. */
  3001.     XEvent *eventPtr) /* Event that just happened. */
  3002. {
  3003.     TkWindow *winPtr = (TkWindow *) clientData;
  3004.     winPtr->wmInfoPtr->flags |= WM_VROOT_OFFSET_STALE;
  3005.     if (eventPtr->type == DestroyNotify) {
  3006. if (!(winPtr->flags & TK_ALREADY_DEAD)) {
  3007.     /*
  3008.      * A top-level window was deleted externally (e.g., by the window
  3009.      * manager). This is probably not a good thing, but cleanup as
  3010.      * best we can. The error handler is needed because