diff options
Diffstat (limited to 'carbon/tkMacOSXWm.c')
-rw-r--r-- | carbon/tkMacOSXWm.c | 6559 |
1 files changed, 0 insertions, 6559 deletions
diff --git a/carbon/tkMacOSXWm.c b/carbon/tkMacOSXWm.c deleted file mode 100644 index d4b7665..0000000 --- a/carbon/tkMacOSXWm.c +++ /dev/null @@ -1,6559 +0,0 @@ -/* - * tkMacOSXWm.c -- - * - * This module takes care of the interactions between a Tk-based - * application and the window manager. Among other things, it implements - * the "wm" command and passes geometry information to the window - * manager. - * - * Copyright (c) 1994-1997 Sun Microsystems, Inc. - * Copyright 2001, Apple Computer, Inc. - * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkMacOSXPrivate.h" -#include "tkScrollbar.h" -#include "tkMacOSXWm.h" -#include "tkMacOSXEvent.h" -#include "tkMacOSXDebug.h" - -/* -#ifdef TK_MAC_DEBUG -#define TK_MAC_DEBUG_WINDOWS -#endif -*/ - -/* - * Data for [wm attributes] command: - */ -typedef enum { - WMATT_ALPHA, WMATT_FULLSCREEN, WMATT_MODIFIED, WMATT_NOTIFY, - WMATT_TITLEPATH, WMATT_TOPMOST, WMATT_TRANSPARENT, - _WMATT_LAST_ATTRIBUTE -} WmAttribute; - -static const char *const WmAttributeNames[] = { - "-alpha", "-fullscreen", "-modified", "-notify", - "-titlepath", "-topmost", "-transparent", - NULL -}; - -/* - * This is a list of all of the toplevels that have been mapped so far. It is - * used by the menu code to inval windows that were damaged by menus, and will - * eventually also be used to keep track of floating windows. - */ - -TkMacOSXWindowList *tkMacOSXWindowListPtr = NULL; - -/* - * The variable below is used to enable or disable tracing in this module. If - * tracing is enabled, then information is printed on standard output about - * interesting interactions with the window manager. - */ - -static int wmTracing = 0; - -/* - * The following structure is the official type record for geometry management - * of top-level windows. - */ - -static void TopLevelReqProc(ClientData dummy, Tk_Window tkwin); - -static const Tk_GeomMgr wmMgrType = { - "wm", /* name */ - TopLevelReqProc, /* requestProc */ - NULL, /* lostSlaveProc */ -}; - -/* - * The following keeps state for Aqua dock icon bounce notification. - */ - -static int tkMacOSXWmAttrNotifyVal = 0; - -/* - * Hash table for Mac Window -> TkWindow mapping. - */ - -static Tcl_HashTable windowTable; -static int windowHashInit = false; - -/* - * Forward declarations for procedures defined in this file: - */ - -static void InitialWindowBounds(TkWindow *winPtr, - WindowRef macWindow, Rect *geometry); -static int ParseGeometry(Tcl_Interp *interp, char *string, - TkWindow *winPtr); -static void TopLevelEventProc(ClientData clientData, - XEvent *eventPtr); -static void WmStackorderToplevelWrapperMap(TkWindow *winPtr, - Display *display, Tcl_HashTable *table); -static void UpdateGeometryInfo(ClientData clientData); -static void UpdateSizeHints(TkWindow *winPtr); -static void UpdateVRootGeometry(WmInfo *wmPtr); -static int WmAspectCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmAttributesCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmClientCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmColormapwindowsCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmCommandCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmDeiconifyCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmFocusmodelCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmForgetCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmFrameCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmGeometryCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmGridCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmGroupCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmIconbitmapCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmIconifyCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmIconmaskCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmIconnameCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmIconphotoCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmIconpositionCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmIconwindowCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmManageCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmMaxsizeCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmMinsizeCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmOverrideredirectCmd(Tk_Window tkwin, - TkWindow *winPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmPositionfromCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmProtocolCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmResizableCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmSizefromCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmStackorderCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmStateCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmTitleCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmTransientCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static int WmWithdrawCmd(Tk_Window tkwin, TkWindow *winPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static void WmUpdateGeom(WmInfo *wmPtr, TkWindow *winPtr); -static int WmWinStyle(Tcl_Interp *interp, TkWindow *winPtr, - int objc, Tcl_Obj *const objv[]); -static void ApplyWindowClassAttributeChanges(TkWindow *winPtr, - WindowRef macWindow, WindowClass oldClass, - WindowAttributes oldAttributes, int create); -static void ApplyMasterOverrideChanges(TkWindow *winPtr, - WindowRef macWindow); -static WindowGroupRef WmGetWindowGroup(TkWindow *winPtr); -static void GetMinSize(TkWindow *winPtr, int *minWidthPtr, - int *minHeightPtr); -static void GetMaxSize(TkWindow *winPtr, int *maxWidthPtr, - int *maxHeightPtr); -static void RemapWindows(TkWindow *winPtr, - MacDrawable *parentWin); - -/* - *---------------------------------------------------------------------- - * - * TkWmNewWindow -- - * - * This procedure is invoked whenever a new top-level window is created. - * Its job is to initialize the WmInfo structure for the window. - * - * Results: - * None. - * - * Side effects: - * A WmInfo structure gets allocated and initialized. - * - *---------------------------------------------------------------------- - */ - -void -TkWmNewWindow( - TkWindow *winPtr) /* Newly-created top-level window. */ -{ - WmInfo *wmPtr = ckalloc(sizeof(WmInfo)); - - wmPtr->winPtr = winPtr; - wmPtr->reparent = None; - wmPtr->titleUid = NULL; - wmPtr->iconName = NULL; - wmPtr->master = None; - wmPtr->hints.flags = InputHint | StateHint; - wmPtr->hints.input = True; - wmPtr->hints.initial_state = NormalState; - wmPtr->hints.icon_pixmap = None; - wmPtr->hints.icon_window = None; - wmPtr->hints.icon_x = wmPtr->hints.icon_y = 0; - wmPtr->hints.icon_mask = None; - wmPtr->hints.window_group = None; - wmPtr->leaderName = NULL; - wmPtr->masterWindowName = NULL; - wmPtr->icon = NULL; - wmPtr->iconFor = NULL; - wmPtr->sizeHintsFlags = 0; - wmPtr->minWidth = wmPtr->minHeight = 1; - wmPtr->maxWidth = 0; - wmPtr->maxHeight = 0; - wmPtr->gridWin = NULL; - wmPtr->widthInc = wmPtr->heightInc = 1; - wmPtr->minAspect.x = wmPtr->minAspect.y = 1; - wmPtr->maxAspect.x = wmPtr->maxAspect.y = 1; - wmPtr->reqGridWidth = wmPtr->reqGridHeight = -1; - wmPtr->gravity = NorthWestGravity; - wmPtr->width = -1; - wmPtr->height = -1; - wmPtr->x = winPtr->changes.x; - wmPtr->y = winPtr->changes.y; - wmPtr->parentWidth = winPtr->changes.width - + 2*winPtr->changes.border_width; - wmPtr->parentHeight = winPtr->changes.height - + 2*winPtr->changes.border_width; - wmPtr->xInParent = 0; - wmPtr->yInParent = 0; - wmPtr->cmapList = NULL; - wmPtr->cmapCount = 0; - wmPtr->configX = 0; - wmPtr->configY = 0; - wmPtr->configWidth = -1; - wmPtr->configHeight = -1; - wmPtr->vRoot = None; - wmPtr->protPtr = NULL; - wmPtr->cmdArgv = NULL; - wmPtr->clientMachine = NULL; - wmPtr->flags = WM_NEVER_MAPPED; - wmPtr->style = -1; - wmPtr->macClass = kDocumentWindowClass; - wmPtr->attributes = kWindowStandardDocumentAttributes - | kWindowLiveResizeAttribute; - wmPtr->scrollWinPtr = NULL; - winPtr->wmInfoPtr = wmPtr; - - UpdateVRootGeometry(wmPtr); - - /* - * Tk must monitor structure events for top-level windows, in order to - * detect size and position changes caused by window managers. - */ - - Tk_CreateEventHandler((Tk_Window) winPtr, StructureNotifyMask, - TopLevelEventProc, winPtr); - - /* - * Arrange for geometry requests to be reflected from the window to the - * window manager. - */ - - Tk_ManageGeometry((Tk_Window) winPtr, &wmMgrType, (ClientData) 0); -} - -/* - *---------------------------------------------------------------------- - * - * TkWmMapWindow -- - * - * This procedure is invoked to map a top-level window. This module gets - * a chance to update all window-manager-related information in - * properties before the window manager sees the map event and checks the - * properties. It also gets to decide whether or not to even map the - * window after all. - * - * Results: - * None. - * - * Side effects: - * Properties of winPtr may get updated to provide up-to-date information - * to the window manager. The window may also get mapped, but it may not - * be if this procedure decides that isn't appropriate (e.g. because the - * window is withdrawn). - * - *---------------------------------------------------------------------- - */ - -void -TkWmMapWindow( - TkWindow *winPtr) /* Top-level window that's about to be - * mapped. */ -{ - WmInfo *wmPtr = winPtr->wmInfoPtr; - - if (wmPtr->flags & WM_NEVER_MAPPED) { - wmPtr->flags &= ~WM_NEVER_MAPPED; - - /* - * Create the underlying Mac window for this Tk window. - */ - - if (!TkMacOSXHostToplevelExists(winPtr)) { - TkMacOSXMakeRealWindowExist(winPtr); - } - - /* - * Generate configure event when we first map the window. - */ - - TkGenWMConfigureEvent((Tk_Window) winPtr, wmPtr->x, wmPtr->y, -1, -1, - TK_LOCATION_CHANGED); - - /* - * This is the first time this window has ever been mapped. Store all - * the window-manager-related information for the window. - */ - - if (wmPtr->titleUid == NULL) { - wmPtr->titleUid = winPtr->nameUid; - } - - if (!Tk_IsEmbedded(winPtr)) { - TkSetWMName(winPtr, wmPtr->titleUid); - } - - TkWmSetClass(winPtr); - - if (wmPtr->iconName != NULL) { - XSetIconName(winPtr->display, winPtr->window, wmPtr->iconName); - } - - wmPtr->flags |= WM_UPDATE_SIZE_HINTS; - } - if (wmPtr->hints.initial_state == WithdrawnState) { - return; - } - - /* - * TODO: we need to display a window if it's iconic on creation. - */ - - if (wmPtr->hints.initial_state == IconicState) { - return; - } - - /* - * Update geometry information. - */ - - wmPtr->flags |= WM_ABOUT_TO_MAP; - if (wmPtr->flags & WM_UPDATE_PENDING) { - Tk_CancelIdleCall(UpdateGeometryInfo, winPtr); - } - UpdateGeometryInfo(winPtr); - wmPtr->flags &= ~WM_ABOUT_TO_MAP; - - /* - * Map the window. - */ - - XMapWindow(winPtr->display, winPtr->window); -} - -/* - *---------------------------------------------------------------------- - * - * TkWmUnmapWindow -- - * - * This procedure is invoked to unmap a top-level window. On the - * Macintosh all we do is call XUnmapWindow. - * - * Results: - * None. - * - * Side effects: - * Unmaps the window. - * - *---------------------------------------------------------------------- - */ - -void -TkWmUnmapWindow( - TkWindow *winPtr) /* Top-level window that's about to be - * mapped. */ -{ - XUnmapWindow(winPtr->display, winPtr->window); -} - -/* - *---------------------------------------------------------------------- - * - * TkWmDeadWindow -- - * - * This procedure is invoked when a top-level window is about to be - * deleted. It cleans up the wm-related data structures for the window. - * - * Results: - * None. - * - * Side effects: - * The WmInfo structure for winPtr gets freed up. - * - *---------------------------------------------------------------------- - */ - -void -TkWmDeadWindow( - TkWindow *winPtr) /* Top-level window that's being deleted. */ -{ - WmInfo *wmPtr = winPtr->wmInfoPtr; - WmInfo *wmPtr2; - - if (wmPtr == NULL) { - return; - } - if (wmPtr->hints.flags & IconPixmapHint) { - Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap); - } - if (wmPtr->hints.flags & IconMaskHint) { - Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_mask); - } - if (wmPtr->iconName != NULL) { - ckfree(wmPtr->iconName); - } - if (wmPtr->leaderName != NULL) { - ckfree(wmPtr->leaderName); - } - if (wmPtr->masterWindowName != NULL) { - ckfree(wmPtr->masterWindowName); - } - if (wmPtr->icon != NULL) { - wmPtr2 = ((TkWindow *) wmPtr->icon)->wmInfoPtr; - wmPtr2->iconFor = NULL; - } - if (wmPtr->iconFor != NULL) { - wmPtr2 = ((TkWindow *) wmPtr->iconFor)->wmInfoPtr; - wmPtr2->icon = NULL; - wmPtr2->hints.flags &= ~IconWindowHint; - } - while (wmPtr->protPtr != NULL) { - ProtocolHandler *protPtr; - - protPtr = wmPtr->protPtr; - wmPtr->protPtr = protPtr->nextPtr; - Tcl_EventuallyFree(protPtr, TCL_DYNAMIC); - } - if (wmPtr->cmdArgv != NULL) { - ckfree(wmPtr->cmdArgv); - } - if (wmPtr->clientMachine != NULL) { - ckfree(wmPtr->clientMachine); - } - if (wmPtr->flags & WM_UPDATE_PENDING) { - Tk_CancelIdleCall(UpdateGeometryInfo, winPtr); - } - ckfree(wmPtr); - winPtr->wmInfoPtr = NULL; -} - -/* - *---------------------------------------------------------------------- - * - * TkWmSetClass -- - * - * This procedure is invoked whenever a top-level window's class is - * changed. If the window has been mapped then this procedure updates the - * window manager property for the class. If the window hasn't been - * mapped, the update is deferred until just before the first mapping. - * - * Results: - * None. - * - * Side effects: - * A window property may get updated. - * - *---------------------------------------------------------------------- - */ - -void -TkWmSetClass( - TkWindow *winPtr) /* Newly-created top-level window. */ -{ - return; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_WmObjCmd -- - * - * This procedure is invoked to process the "wm" Tcl command. See the - * user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -/* ARGSUSED */ -int -Tk_WmObjCmd( - ClientData clientData, /* Main window associated with interpreter. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - Tk_Window tkwin = (Tk_Window) clientData; - static const char *const optionStrings[] = { - "aspect", "attributes", "client", "colormapwindows", - "command", "deiconify", "focusmodel", "forget", - "frame", "geometry", "grid", "group", - "iconbitmap", "iconify", "iconmask", "iconname", - "iconphoto", "iconposition", "iconwindow", - "manage", "maxsize", "minsize", "overrideredirect", - "positionfrom", "protocol", "resizable", "sizefrom", - "stackorder", "state", "title", "transient", - "withdraw", NULL }; - enum options { - WMOPT_ASPECT, WMOPT_ATTRIBUTES, WMOPT_CLIENT, WMOPT_COLORMAPWINDOWS, - WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL, WMOPT_FORGET, - WMOPT_FRAME, WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP, - WMOPT_ICONBITMAP, WMOPT_ICONIFY, WMOPT_ICONMASK, WMOPT_ICONNAME, - WMOPT_ICONPHOTO, WMOPT_ICONPOSITION, WMOPT_ICONWINDOW, - WMOPT_MANAGE, WMOPT_MAXSIZE, WMOPT_MINSIZE, WMOPT_OVERRIDEREDIRECT, - WMOPT_POSITIONFROM, WMOPT_PROTOCOL, WMOPT_RESIZABLE, WMOPT_SIZEFROM, - WMOPT_STACKORDER, WMOPT_STATE, WMOPT_TITLE, WMOPT_TRANSIENT, - WMOPT_WITHDRAW }; - int index, length; - char *argv1; - TkWindow *winPtr; - - if (objc < 2) { - wrongNumArgs: - Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?"); - return TCL_ERROR; - } - - argv1 = Tcl_GetStringFromObj(objv[1], &length); - if ((argv1[0] == 't') && (strncmp(argv1, "tracing", length) == 0) - && (length >= 3)) { - if ((objc != 2) && (objc != 3)) { - Tcl_WrongNumArgs(interp, 2, objv, "?boolean?"); - return TCL_ERROR; - } - if (objc == 2) { - Tcl_SetObjResult(interp, Tcl_NewBooleanObj(wmTracing)); - return TCL_OK; - } - return Tcl_GetBooleanFromObj(interp, objv[2], &wmTracing); - } - - if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0, - &index) != TCL_OK) { - return TCL_ERROR; - } - - if (objc < 3) { - goto wrongNumArgs; - } - - if (TkGetWindowFromObj(interp, tkwin, objv[2], (Tk_Window *) &winPtr) - != TCL_OK) { - return TCL_ERROR; - } - if (!Tk_IsTopLevel(winPtr) - && (index != WMOPT_MANAGE) && (index != WMOPT_FORGET)) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "window \"%s\" isn't a top-level window", winPtr->pathName)); - Tcl_SetErrorCode(interp, "TK", "LOOKUP", "TOPLEVEL", winPtr->pathName, - NULL); - return TCL_ERROR; - } - - switch ((enum options) index) { - case WMOPT_ASPECT: - return WmAspectCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_ATTRIBUTES: - return WmAttributesCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_CLIENT: - return WmClientCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_COLORMAPWINDOWS: - return WmColormapwindowsCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_COMMAND: - return WmCommandCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_DEICONIFY: - return WmDeiconifyCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_FOCUSMODEL: - return WmFocusmodelCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_FORGET: - return WmForgetCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_FRAME: - return WmFrameCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_GEOMETRY: - return WmGeometryCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_GRID: - return WmGridCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_GROUP: - return WmGroupCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_ICONBITMAP: - return WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_ICONIFY: - return WmIconifyCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_ICONMASK: - return WmIconmaskCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_ICONNAME: - return WmIconnameCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_ICONPHOTO: - return WmIconphotoCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_ICONPOSITION: - return WmIconpositionCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_ICONWINDOW: - return WmIconwindowCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_MANAGE: - return WmManageCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_MAXSIZE: - return WmMaxsizeCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_MINSIZE: - return WmMinsizeCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_OVERRIDEREDIRECT: - return WmOverrideredirectCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_POSITIONFROM: - return WmPositionfromCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_PROTOCOL: - return WmProtocolCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_RESIZABLE: - return WmResizableCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_SIZEFROM: - return WmSizefromCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_STACKORDER: - return WmStackorderCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_STATE: - return WmStateCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_TITLE: - return WmTitleCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_TRANSIENT: - return WmTransientCmd(tkwin, winPtr, interp, objc, objv); - case WMOPT_WITHDRAW: - return WmWithdrawCmd(tkwin, winPtr, interp, objc, objv); - } - - /* This should not happen */ - return TCL_ERROR; -} - -/* - *---------------------------------------------------------------------- - * - * WmAspectCmd -- - * - * This procedure is invoked to process the "wm aspect" Tcl command. See - * the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmAspectCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - int numer1, denom1, numer2, denom2; - - if ((objc != 3) && (objc != 7)) { - Tcl_WrongNumArgs(interp, 2, objv, - "window ?minNumer minDenom maxNumer maxDenom?"); - return TCL_ERROR; - } - if (objc == 3) { - if (wmPtr->sizeHintsFlags & PAspect) { - Tcl_Obj *aspect[4]; - - aspect[0] = Tcl_NewIntObj(wmPtr->minAspect.x); - aspect[1] = Tcl_NewIntObj(wmPtr->minAspect.y); - aspect[2] = Tcl_NewIntObj(wmPtr->maxAspect.x); - aspect[3] = Tcl_NewIntObj(wmPtr->maxAspect.y); - Tcl_SetObjResult(interp, Tcl_NewListObj(4, aspect)); - } - return TCL_OK; - } - if (*Tcl_GetString(objv[3]) == '\0') { - wmPtr->sizeHintsFlags &= ~PAspect; - } else { - if ((Tcl_GetIntFromObj(interp, objv[3], &numer1) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[4], &denom1) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[5], &numer2) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[6], &denom2) != TCL_OK)) { - return TCL_ERROR; - } - if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) || - (denom2 <= 0)) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "aspect number can't be <= 0", -1)); - Tcl_SetErrorCode(interp, "TK", "WM", "ASPECT", NULL); - return TCL_ERROR; - } - wmPtr->minAspect.x = numer1; - wmPtr->minAspect.y = denom1; - wmPtr->maxAspect.x = numer2; - wmPtr->maxAspect.y = denom2; - wmPtr->sizeHintsFlags |= PAspect; - } - wmPtr->flags |= WM_UPDATE_SIZE_HINTS; - WmUpdateGeom(wmPtr, winPtr); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmSetAttribute -- - * - * Helper routine for WmAttributesCmd. Sets the value of the specified - * attribute. - * - * Returns: - * - * TCL_OK if successful, TCL_ERROR otherwise. In case of an error, leaves - * a message in the interpreter's result. - * - *---------------------------------------------------------------------- - */ - -static int -WmSetAttribute( - TkWindow *winPtr, /* Toplevel to work with */ - WindowRef macWindow, - Tcl_Interp *interp, /* Current interpreter */ - WmAttribute attribute, /* Code of attribute to set */ - Tcl_Obj *value) /* New value */ -{ - WmInfo *wmPtr = winPtr->wmInfoPtr; - int boolean; - - switch (attribute) { - case WMATT_ALPHA: { - double dval; - - if (Tcl_GetDoubleFromObj(interp, value, &dval) != TCL_OK) { - return TCL_ERROR; - } - - /* - * The user should give (transparent) 0 .. 1.0 (opaque) - */ - - if (dval < 0.0) { - dval = 0.0; - } else if (dval > 1.0) { - dval = 1.0; - } - ChkErr(SetWindowAlpha, macWindow, dval); - break; - } - case WMATT_FULLSCREEN: - if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) { - return TCL_ERROR; - } - if (boolean != ((wmPtr->flags & WM_FULLSCREEN) != 0)) { - if (TkMacOSXMakeFullscreen(winPtr, macWindow, boolean, interp) - != TCL_OK) { - return TCL_ERROR; - } - } - break; - case WMATT_MODIFIED: - if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) { - return TCL_ERROR; - } - if (boolean != IsWindowModified(macWindow)) { - ChkErr(SetWindowModified, macWindow, boolean); - } - break; - case WMATT_NOTIFY: - if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) { - return TCL_ERROR; - } - if (boolean == !tkMacOSXWmAttrNotifyVal) { - static NMRec notifyRec; - - if (boolean) { - bzero(¬ifyRec, sizeof(notifyRec)); - notifyRec.qType = nmType; - notifyRec.nmMark = 1; - ChkErr(NMInstall, ¬ifyRec); - } else { - ChkErr(NMRemove, ¬ifyRec); - } - tkMacOSXWmAttrNotifyVal = boolean; - } - break; - case WMATT_TITLEPATH: { - const char *path = Tcl_FSGetNativePath(value); - OSStatus err; - - if (path && *path) { - FSRef ref; - Boolean d; - - err = ChkErr(FSPathMakeRef, (const unsigned char*)path, &ref, &d); - if (err == noErr) { - TK_IF_MAC_OS_X_API (4, HIWindowSetProxyFSRef, - err = ChkErr(HIWindowSetProxyFSRef, macWindow, &ref); - ) TK_ELSE_MAC_OS_X (4, - AliasHandle alias; - - err = ChkErr(FSNewAlias, NULL, &ref, &alias); - if (err == noErr) { - err = ChkErr(SetWindowProxyAlias, macWindow, alias); - DisposeHandle((Handle) alias); - } - ) TK_ENDIF - } - } else { - int len; - - Tcl_GetStringFromObj(value, &len); - if (!len) { - err = ChkErr(RemoveWindowProxy, macWindow); - } else { - err = fnfErr; - } - } - if (err != noErr) { - return TCL_ERROR; - } - break; - } - case WMATT_TOPMOST: - if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) { - return TCL_ERROR; - } - if (boolean != ((wmPtr->flags & WM_TOPMOST) != 0)) { - WindowGroupRef group; - - if (boolean) { - wmPtr->flags |= WM_TOPMOST; - } else { - wmPtr->flags &= ~WM_TOPMOST; - } - group = WmGetWindowGroup(winPtr); - if (group && group != GetWindowGroup(macWindow)) { - ChkErr(SetWindowGroup, macWindow, group); - } - } - break; - case WMATT_TRANSPARENT: - if (Tcl_GetBooleanFromObj(interp, value, &boolean) != TCL_OK) { - return TCL_ERROR; - } - if (boolean != ((wmPtr->flags & WM_TRANSPARENT) != 0)) { - WindowAttributes oldAttributes = wmPtr->attributes; - - if (boolean) { - wmPtr->flags |= WM_TRANSPARENT; - wmPtr->attributes |= kWindowNoShadowAttribute; - TK_IF_MAC_OS_X_API (3, HIWindowChangeFeatures, - UInt32 features; - - ChkErr(GetWindowFeatures, macWindow, &features); - if (features & kWindowIsOpaque) { - ChkErr(HIWindowChangeFeatures, macWindow, 0, - kWindowIsOpaque); - } - ) TK_ENDIF - } else { - wmPtr->flags &= ~WM_TRANSPARENT; - wmPtr->attributes &= ~kWindowNoShadowAttribute; - } - ApplyWindowClassAttributeChanges(winPtr, macWindow, - wmPtr->macClass, oldAttributes, 1); - ChkErr(ReshapeCustomWindow, macWindow); - TkMacOSXInvalidateWindow((MacDrawable *) winPtr->window, - TK_PARENT_WINDOW); - } - break; - case _WMATT_LAST_ATTRIBUTE: - default: - return TCL_ERROR; - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmGetAttribute -- - * - * Helper routine for WmAttributesCmd. Returns the current value of the - * specified attribute. - * - *---------------------------------------------------------------------- - */ - -static Tcl_Obj * -WmGetAttribute( - TkWindow *winPtr, /* Toplevel to work with */ - WindowRef macWindow, - WmAttribute attribute) /* Code of attribute to get */ -{ - WmInfo *wmPtr = winPtr->wmInfoPtr; - Tcl_Obj *result = NULL; - - switch (attribute) { - case WMATT_ALPHA: { - float fval = 1.0; - - ChkErr(GetWindowAlpha, macWindow, &fval); - result = Tcl_NewDoubleObj(fval); - break; - } - case WMATT_FULLSCREEN: - result = Tcl_NewBooleanObj(wmPtr->flags & WM_FULLSCREEN); - break; - case WMATT_MODIFIED: - result = Tcl_NewBooleanObj(IsWindowModified(macWindow)); - break; - case WMATT_NOTIFY: - result = Tcl_NewBooleanObj(tkMacOSXWmAttrNotifyVal); - break; - case WMATT_TITLEPATH: { - FSRef ref; - UInt8 path[PATH_MAX+1]; - OSStatus err; - - TK_IF_MAC_OS_X_API (4, HIWindowSetProxyFSRef, - err = ChkErr(HIWindowGetProxyFSRef, macWindow, &ref); - ) TK_ELSE_MAC_OS_X (4, - Boolean wasChanged; - AliasHandle alias; - - err = ChkErr(GetWindowProxyAlias, macWindow, &alias); - if (err == noErr) { - err = ChkErr(FSResolveAlias, NULL, alias, &ref, &wasChanged); - } - ) TK_ENDIF - if (err == noErr) { - err = ChkErr(FSRefMakePath, &ref, path, PATH_MAX); - } - if (err != noErr) { - *path = 0; - } - result = Tcl_NewStringObj((char*) path, -1); - break; - } - case WMATT_TOPMOST: - result = Tcl_NewBooleanObj(wmPtr->flags & WM_TOPMOST); - break; - case WMATT_TRANSPARENT: - result = Tcl_NewBooleanObj(wmPtr->flags & WM_TRANSPARENT); - break; - case _WMATT_LAST_ATTRIBUTE: - default: - break; - } - return result; -} - -/* - *---------------------------------------------------------------------- - * - * WmAttributesCmd -- - * - * This procedure is invoked to process the "wm attributes" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmAttributesCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - int attribute = 0; - WindowRef macWindow; - - if (winPtr->window == None) { - Tk_MakeWindowExist((Tk_Window) winPtr); - } - if (!TkMacOSXHostToplevelExists(winPtr)) { - TkMacOSXMakeRealWindowExist(winPtr); - } - macWindow = TkMacOSXDrawableWindow(winPtr->window); - - if (objc == 3) { /* wm attributes $win */ - Tcl_Obj *result = Tcl_NewObj(); - - for (attribute = 0; attribute < _WMATT_LAST_ATTRIBUTE; ++attribute) { - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(WmAttributeNames[attribute], -1)); - Tcl_ListObjAppendElement(NULL, result, - WmGetAttribute(winPtr, macWindow, attribute)); - } - Tcl_SetObjResult(interp, result); - } else if (objc == 4) { /* wm attributes $win -attribute */ - if (Tcl_GetIndexFromObj(interp, objv[3], WmAttributeNames, - "attribute", 0, &attribute) != TCL_OK) { - return TCL_ERROR; - } - Tcl_SetObjResult(interp, WmGetAttribute(winPtr, macWindow, attribute)); - } else if ((objc - 3) % 2 == 0) { /* wm attributes $win -att value... */ - int i; - - for (i = 3; i < objc; i += 2) { - if (Tcl_GetIndexFromObj(interp, objv[i], WmAttributeNames, - "attribute", 0, &attribute) != TCL_OK) { - return TCL_ERROR; - } - if (WmSetAttribute(winPtr, macWindow, interp, attribute, objv[i+1]) - != TCL_OK) { - return TCL_ERROR; - } - } - } else { - Tcl_WrongNumArgs(interp, 2, objv, "window ?-attribute ?value ...??"); - return TCL_ERROR; - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmClientCmd -- - * - * This procedure is invoked to process the "wm client" Tcl command. See - * the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmClientCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - char *argv3; - int length; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?name?"); - return TCL_ERROR; - } - if (objc == 3) { - if (wmPtr->clientMachine != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj(wmPtr->clientMachine, -1)); - } - return TCL_OK; - } - argv3 = Tcl_GetStringFromObj(objv[3], &length); - if (argv3[0] == 0) { - if (wmPtr->clientMachine != NULL) { - ckfree(wmPtr->clientMachine); - wmPtr->clientMachine = NULL; - } - return TCL_OK; - } - if (wmPtr->clientMachine != NULL) { - ckfree(wmPtr->clientMachine); - } - wmPtr->clientMachine = ckalloc(length + 1); - strcpy(wmPtr->clientMachine, argv3); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmColormapwindowsCmd -- - * - * This procedure is invoked to process the "wm colormapwindows" Tcl - * command. See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmColormapwindowsCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - TkWindow **cmapList, *winPtr2; - int i, windowObjc, gotToplevel = 0; - Tcl_Obj **windowObjv, *resultObj; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?windowList?"); - return TCL_ERROR; - } - if (objc == 3) { - Tk_MakeWindowExist((Tk_Window) winPtr); - resultObj = Tcl_NewObj(); - for (i = 0; i < wmPtr->cmapCount; i++) { - if ((i == (wmPtr->cmapCount-1)) - && (wmPtr->flags & WM_ADDED_TOPLEVEL_COLORMAP)) { - break; - } - Tcl_ListObjAppendElement(NULL, resultObj, - TkNewWindowObj((Tk_Window) wmPtr->cmapList[i])); - } - Tcl_SetObjResult(interp, resultObj); - return TCL_OK; - } - if (Tcl_ListObjGetElements(interp, objv[3], &windowObjc, &windowObjv) - != TCL_OK) { - return TCL_ERROR; - } - cmapList = ckalloc((windowObjc+1) * sizeof(TkWindow*)); - for (i = 0; i < windowObjc; i++) { - if (TkGetWindowFromObj(interp, tkwin, windowObjv[i], - (Tk_Window *) &winPtr2) != TCL_OK) { - ckfree(cmapList); - return TCL_ERROR; - } - if (winPtr2 == winPtr) { - gotToplevel = 1; - } - if (winPtr2->window == None) { - Tk_MakeWindowExist((Tk_Window) winPtr2); - } - cmapList[i] = winPtr2; - } - if (!gotToplevel) { - wmPtr->flags |= WM_ADDED_TOPLEVEL_COLORMAP; - cmapList[windowObjc] = winPtr; - windowObjc++; - } else { - wmPtr->flags &= ~WM_ADDED_TOPLEVEL_COLORMAP; - } - wmPtr->flags |= WM_COLORMAPS_EXPLICIT; - if (wmPtr->cmapList != NULL) { - ckfree(wmPtr->cmapList); - } - wmPtr->cmapList = cmapList; - wmPtr->cmapCount = windowObjc; - - /* - * On the Macintosh all of this is just an excercise in compatability as - * we don't support colormaps. If we did they would be installed here. - */ - - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmCommandCmd -- - * - * This procedure is invoked to process the "wm command" Tcl command. See - * the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmCommandCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - char *argv3; - int cmdArgc; - const char **cmdArgv; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?value?"); - return TCL_ERROR; - } - if (objc == 3) { - if (wmPtr->cmdArgv != NULL) { - argv3 = Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv); - Tcl_SetObjResult(interp, Tcl_NewStringObj(argv3, -1)); - ckfree(argv3); - } - return TCL_OK; - } - argv3 = Tcl_GetString(objv[3]); - if (argv3[0] == 0) { - if (wmPtr->cmdArgv != NULL) { - ckfree(wmPtr->cmdArgv); - wmPtr->cmdArgv = NULL; - } - return TCL_OK; - } - if (Tcl_SplitList(interp, argv3, &cmdArgc, &cmdArgv) != TCL_OK) { - return TCL_ERROR; - } - if (wmPtr->cmdArgv != NULL) { - ckfree(wmPtr->cmdArgv); - } - wmPtr->cmdArgc = cmdArgc; - wmPtr->cmdArgv = cmdArgv; - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmDeiconifyCmd -- - * - * This procedure is invoked to process the "wm deiconify" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmDeiconifyCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "window"); - return TCL_ERROR; - } - if (wmPtr->iconFor != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't deiconify %s: it is an icon for %s", - Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor))); - Tcl_SetErrorCode(interp, "TK", "WM", "DEICONIFY", "ICON", NULL); - return TCL_ERROR; - } - if (winPtr->flags & TK_EMBEDDED) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't deiconify %s: it is an embedded window", - winPtr->pathName)); - Tcl_SetErrorCode(interp, "TK", "WM", "DEICONIFY", "EMBEDDED", NULL); - return TCL_ERROR; - } - TkpWmSetState(winPtr, TkMacOSXIsWindowZoomed(winPtr) ? - ZoomState : NormalState); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmFocusmodelCmd -- - * - * This procedure is invoked to process the "wm focusmodel" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmFocusmodelCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - static const char *const optionStrings[] = { - "active", "passive", NULL }; - enum options { - OPT_ACTIVE, OPT_PASSIVE }; - int index; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?active|passive?"); - return TCL_ERROR; - } - if (objc == 3) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - wmPtr->hints.input ? "passive" : "active", -1)); - return TCL_OK; - } - - if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0, - &index) != TCL_OK) { - return TCL_ERROR; - } - if (index == OPT_ACTIVE) { - wmPtr->hints.input = False; - } else { /* OPT_PASSIVE */ - wmPtr->hints.input = True; - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmForgetCmd -- - * - * This procedure is invoked to process the "wm forget" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmForgetCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel or Frame to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ -#if 1 - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "wm forget is not yet supported", -1)); - Tcl_SetErrorCode(interp, "TK", "WM", "UNSUPPORTED", NULL); - return TCL_ERROR; -#else - register Tk_Window frameWin = (Tk_Window)winPtr; - char *oldClass = (char*)Tk_Class(frameWin); - - if (Tk_IsTopLevel(frameWin)) { - MacDrawable *macWin = (MacDrawable *) winPtr->window; - CGrafPtr destPort = TkMacOSXGetDrawablePort(winPtr->window); - - TkFocusJoin(winPtr); - Tk_UnmapWindow(frameWin); - - if (destPort != NULL) { - WindowRef winRef = GetWindowFromPort(destPort); - - TkMacOSXUnregisterMacWindow(winRef); - DisposeWindow(winRef); - } - macWin->grafPtr = NULL; - macWin->toplevel = winPtr->parentPtr->privatePtr->toplevel; - macWin->flags &= ~TK_HOST_EXISTS; - - RemapWindows(winPtr, macWin); - TkWmDeadWindow(winPtr); - winPtr->flags &= - ~(TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED); - - TkMapTopFrame(frameWin); - } else { - /* Already not managed by wm - ignore it */ - } - return TCL_OK; -#endif -} - -/* - *---------------------------------------------------------------------- - * - * WmFrameCmd -- - * - * This procedure is invoked to process the "wm frame" Tcl command. See - * the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmFrameCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - Window window; - - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "window"); - return TCL_ERROR; - } - window = wmPtr->reparent; - if (window == None) { - window = Tk_WindowId((Tk_Window) winPtr); - } - Tcl_SetObjResult(interp, Tcl_ObjPrintf("0x%x", (unsigned) window)); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmGeometryCmd -- - * - * This procedure is invoked to process the "wm geometry" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmGeometryCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - char xSign, ySign; - int width, height; - char *argv3; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?newGeometry?"); - return TCL_ERROR; - } - if (objc == 3) { - xSign = (wmPtr->flags & WM_NEGATIVE_X) ? '-' : '+'; - ySign = (wmPtr->flags & WM_NEGATIVE_Y) ? '-' : '+'; - if (wmPtr->gridWin != NULL) { - width = wmPtr->reqGridWidth + (winPtr->changes.width - - winPtr->reqWidth)/wmPtr->widthInc; - height = wmPtr->reqGridHeight + (winPtr->changes.height - - winPtr->reqHeight)/wmPtr->heightInc; - } else { - width = winPtr->changes.width; - height = winPtr->changes.height; - } - Tcl_SetObjResult(interp, Tcl_ObjPrintf("%dx%d%c%d%c%d", - width, height, xSign, wmPtr->x, ySign, wmPtr->y)); - return TCL_OK; - } - argv3 = Tcl_GetString(objv[3]); - if (*argv3 == '\0') { - wmPtr->width = -1; - wmPtr->height = -1; - WmUpdateGeom(wmPtr, winPtr); - return TCL_OK; - } - return ParseGeometry(interp, argv3, winPtr); -} - -/* - *---------------------------------------------------------------------- - * - * WmGridCmd -- - * - * This procedure is invoked to process the "wm grid" Tcl command. See - * the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmGridCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - int reqWidth, reqHeight, widthInc, heightInc; - const char *errorMsg; - - if ((objc != 3) && (objc != 7)) { - Tcl_WrongNumArgs(interp, 2, objv, - "window ?baseWidth baseHeight widthInc heightInc?"); - return TCL_ERROR; - } - if (objc == 3) { - if (wmPtr->sizeHintsFlags & PBaseSize) { - Tcl_Obj *grid[4]; - - grid[0] = Tcl_NewIntObj(wmPtr->reqGridWidth); - grid[1] = Tcl_NewIntObj(wmPtr->reqGridHeight); - grid[2] = Tcl_NewIntObj(wmPtr->widthInc); - grid[3] = Tcl_NewIntObj(wmPtr->heightInc); - Tcl_SetObjResult(interp, Tcl_NewListObj(4, grid)); - } - return TCL_OK; - } - if (*Tcl_GetString(objv[3]) == '\0') { - /* - * Turn off gridding and reset the width and height to make sense as - * ungridded numbers. - */ - - wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc); - if (wmPtr->width != -1) { - wmPtr->width = winPtr->reqWidth + (wmPtr->width - - wmPtr->reqGridWidth)*wmPtr->widthInc; - wmPtr->height = winPtr->reqHeight + (wmPtr->height - - wmPtr->reqGridHeight)*wmPtr->heightInc; - } - wmPtr->widthInc = 1; - wmPtr->heightInc = 1; - } else { - if ((Tcl_GetIntFromObj(interp, objv[3], &reqWidth) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[4], &reqHeight) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[5], &widthInc) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[6], &heightInc)!=TCL_OK)) { - return TCL_ERROR; - } - if (reqWidth < 0) { - errorMsg = "baseWidth can't be < 0"; - goto error; - } else if (reqHeight < 0) { - errorMsg = "baseHeight can't be < 0"; - goto error; - } else if (widthInc <= 0) { - errorMsg = "widthInc can't be <= 0"; - goto error; - } else if (heightInc <= 0) { - errorMsg = "heightInc can't be <= 0"; - goto error; - } - Tk_SetGrid((Tk_Window) winPtr, reqWidth, reqHeight, widthInc, - heightInc); - } - wmPtr->flags |= WM_UPDATE_SIZE_HINTS; - WmUpdateGeom(wmPtr, winPtr); - return TCL_OK; - - error: - Tcl_SetObjResult(interp, Tcl_NewStringObj(errorMsg, -1)); - Tcl_SetErrorCode(interp, "TK", "WM", "GRID", NULL); - return TCL_ERROR; -} - -/* - *---------------------------------------------------------------------- - * - * WmGroupCmd -- - * - * This procedure is invoked to process the "wm group" Tcl command. See - * the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmGroupCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - Tk_Window tkwin2; - char *argv3; - int length; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?"); - return TCL_ERROR; - } - if (objc == 3) { - if (wmPtr->hints.flags & WindowGroupHint) { - Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->leaderName, -1)); - } - return TCL_OK; - } - argv3 = Tcl_GetStringFromObj(objv[3], &length); - if (*argv3 == '\0') { - wmPtr->hints.flags &= ~WindowGroupHint; - if (wmPtr->leaderName != NULL) { - ckfree(wmPtr->leaderName); - } - wmPtr->leaderName = NULL; - } else { - if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) { - return TCL_ERROR; - } - Tk_MakeWindowExist(tkwin2); - if (wmPtr->leaderName != NULL) { - ckfree(wmPtr->leaderName); - } - wmPtr->hints.window_group = Tk_WindowId(tkwin2); - wmPtr->hints.flags |= WindowGroupHint; - wmPtr->leaderName = ckalloc(length + 1); - strcpy(wmPtr->leaderName, argv3); - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmIconbitmapCmd -- - * - * This procedure is invoked to process the "wm iconbitmap" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmIconbitmapCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - Pixmap pixmap; - char *str; - int len; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?"); - return TCL_ERROR; - } - if (objc == 3) { - if (wmPtr->hints.flags & IconPixmapHint) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - Tk_NameOfBitmap(winPtr->display, - wmPtr->hints.icon_pixmap), -1)); - } - return TCL_OK; - } - str = Tcl_GetStringFromObj(objv[3], &len); - if (winPtr->window == None) { - Tk_MakeWindowExist((Tk_Window) winPtr); - } - if (!TkMacOSXHostToplevelExists(winPtr)) { - TkMacOSXMakeRealWindowExist(winPtr); - } - if (WmSetAttribute(winPtr, TkMacOSXDrawableWindow(winPtr->window), interp, - WMATT_TITLEPATH, objv[3]) == TCL_OK) { - if (!len) { - if (wmPtr->hints.icon_pixmap != None) { - Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap); - wmPtr->hints.icon_pixmap = None; - } - wmPtr->hints.flags &= ~IconPixmapHint; - } - } else { - pixmap = Tk_GetBitmap(interp, (Tk_Window) winPtr, Tk_GetUid(str)); - if (pixmap == None) { - return TCL_ERROR; - } - wmPtr->hints.icon_pixmap = pixmap; - wmPtr->hints.flags |= IconPixmapHint; - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmIconifyCmd -- - * - * This procedure is invoked to process the "wm iconify" Tcl command. See - * the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmIconifyCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "window"); - return TCL_ERROR; - } - - if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't iconify \"%s\": override-redirect flag is set", - winPtr->pathName)); - Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "OVERRIDE_REDIRECT", - NULL); - return TCL_ERROR; - } else if (wmPtr->master != None) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't iconify \"%s\": it is a transient", winPtr->pathName)); - Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "TRANSIENT", NULL); - return TCL_ERROR; - } else if (wmPtr->iconFor != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't iconify %s: it is an icon for %s", - winPtr->pathName, Tk_PathName(wmPtr->iconFor))); - Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "ICON", NULL); - return TCL_ERROR; - } else if (winPtr->flags & TK_EMBEDDED) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't iconify %s: it is an embedded window", - winPtr->pathName)); - Tcl_SetErrorCode(interp, "TK", "WM", "ICONIFY", "EMBEDDED", NULL); - return TCL_ERROR; - } - - TkpWmSetState(winPtr, IconicState); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmIconmaskCmd -- - * - * This procedure is invoked to process the "wm iconmask" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmIconmaskCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - Pixmap pixmap; - char *argv3; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?"); - return TCL_ERROR; - } - if (objc == 3) { - if (wmPtr->hints.flags & IconMaskHint) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - Tk_NameOfBitmap(winPtr->display, - wmPtr->hints.icon_mask), -1)); - } - return TCL_OK; - } - argv3 = Tcl_GetString(objv[3]); - if (*argv3 == '\0') { - if (wmPtr->hints.icon_mask != None) { - Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_mask); - } - wmPtr->hints.flags &= ~IconMaskHint; - } else { - pixmap = Tk_GetBitmap(interp, tkwin, argv3); - if (pixmap == None) { - return TCL_ERROR; - } - wmPtr->hints.icon_mask = pixmap; - wmPtr->hints.flags |= IconMaskHint; - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmIconnameCmd -- - * - * This procedure is invoked to process the "wm iconname" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmIconnameCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - const char *argv3; - int length; - - if (objc > 4) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?newName?"); - return TCL_ERROR; - } - if (objc == 3) { - if (wmPtr->iconName != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj(wmPtr->iconName, -1)); - } - return TCL_OK; - } - - if (wmPtr->iconName != NULL) { - ckfree(wmPtr->iconName); - } - argv3 = Tcl_GetStringFromObj(objv[3], &length); - wmPtr->iconName = ckalloc(length + 1); - strcpy(wmPtr->iconName, argv3); - if (!(wmPtr->flags & WM_NEVER_MAPPED)) { - XSetIconName(winPtr->display, winPtr->window, wmPtr->iconName); - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmIconphotoCmd -- - * - * This procedure is invoked to process the "wm iconphoto" Tcl command. - * See the user documentation for details on what it does. Not yet - * implemented for OS X. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmIconphotoCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - Tk_PhotoHandle photo; - int i, width, height, isDefault = 0; - - if (objc < 4) { - Tcl_WrongNumArgs(interp, 2, objv, - "window ?-default? image1 ?image2 ...?"); - return TCL_ERROR; - } - if (strcmp(Tcl_GetString(objv[3]), "-default") == 0) { - isDefault = 1; - if (objc == 4) { - Tcl_WrongNumArgs(interp, 2, objv, - "window ?-default? image1 ?image2 ...?"); - return TCL_ERROR; - } - } - - /* - * Iterate over all images to retrieve their sizes, in order to allocate a - * buffer large enough to hold all images. - */ - - for (i = 3 + isDefault; i < objc; i++) { - photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i])); - if (photo == NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't use \"%s\" as iconphoto: not a photo image", - Tcl_GetString(objv[i]))); - Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "PHOTO", NULL); - return TCL_ERROR; - } - Tk_PhotoGetSize(photo, &width, &height); - } - - /* - * TODO: This requires implementation for OS X, but we silently return for - * now. - */ - - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmIconpositionCmd -- - * - * This procedure is invoked to process the "wm iconposition" Tcl - * command. See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmIconpositionCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - int x, y; - - if ((objc != 3) && (objc != 5)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?x y?"); - return TCL_ERROR; - } - if (objc == 3) { - if (wmPtr->hints.flags & IconPositionHint) { - Tcl_Obj *pos[2]; - - pos[0] = Tcl_NewIntObj(wmPtr->hints.icon_x); - pos[1] = Tcl_NewIntObj(wmPtr->hints.icon_y); - Tcl_SetObjResult(interp, Tcl_NewListObj(2, pos)); - } - return TCL_OK; - } - if (*Tcl_GetString(objv[3]) == '\0') { - wmPtr->hints.flags &= ~IconPositionHint; - } else { - if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)){ - return TCL_ERROR; - } - wmPtr->hints.icon_x = x; - wmPtr->hints.icon_y = y; - wmPtr->hints.flags |= IconPositionHint; - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmIconwindowCmd -- - * - * This procedure is invoked to process the "wm iconwindow" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmIconwindowCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - Tk_Window tkwin2; - WmInfo *wmPtr2; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?pathName?"); - return TCL_ERROR; - } - if (objc == 3) { - if (wmPtr->icon != NULL) { - Tcl_SetObjResult(interp, TkNewWindowObj(wmPtr->icon)); - } - return TCL_OK; - } - if (*Tcl_GetString(objv[3]) == '\0') { - wmPtr->hints.flags &= ~IconWindowHint; - if (wmPtr->icon != NULL) { - wmPtr2 = ((TkWindow *) wmPtr->icon)->wmInfoPtr; - wmPtr2->iconFor = NULL; - wmPtr2->hints.initial_state = WithdrawnState; - } - wmPtr->icon = NULL; - } else { - if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) { - return TCL_ERROR; - } - if (!Tk_IsTopLevel(tkwin2)) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't use %s as icon window: not at top level", - Tk_PathName(tkwin2))); - Tcl_SetErrorCode(interp, "TK", "WM", "ICONWINDOW", "TOPLEVEL", - NULL); - return TCL_ERROR; - } - wmPtr2 = ((TkWindow *) tkwin2)->wmInfoPtr; - if (wmPtr2->iconFor != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "%s is already an icon for %s", - Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor))); - Tcl_SetErrorCode(interp, "TK", "WM", "ICONWINDOW", "ICON", NULL); - return TCL_ERROR; - } - if (wmPtr->icon != NULL) { - WmInfo *wmPtr3 = ((TkWindow *) wmPtr->icon)->wmInfoPtr; - wmPtr3->iconFor = NULL; - } - Tk_MakeWindowExist(tkwin2); - wmPtr->hints.icon_window = Tk_WindowId(tkwin2); - wmPtr->hints.flags |= IconWindowHint; - wmPtr->icon = tkwin2; - wmPtr2->iconFor = (Tk_Window) winPtr; - if (!(wmPtr2->flags & WM_NEVER_MAPPED)) { - /* - * Don't have iconwindows on the Mac. We just withdraw. - */ - - Tk_UnmapWindow(tkwin2); - } - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmManageCmd -- - * - * This procedure is invoked to process the "wm manage" Tcl command. See - * the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmManageCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel or Frame to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ -#if 1 - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "wm manage is not yet supported", -1)); - Tcl_SetErrorCode(interp, "TK", "WM", "UNSUPPORTED", NULL); - return TCL_ERROR; -#else - register Tk_Window frameWin = (Tk_Window)winPtr; - register WmInfo *wmPtr = winPtr->wmInfoPtr; - char *oldClass = (char*)Tk_Class(frameWin); - - if (!Tk_IsTopLevel(frameWin)) { - MacDrawable *macWin = (MacDrawable *) winPtr->window; - - if (!Tk_IsManageable(frameWin)) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "window \"%s\" is not manageable: must be a" - " frame, labelframe or toplevel", - Tk_PathName(frameWin))); - Tcl_SetErrorCode(interp, "TK", "WM", "MANAGE", NULL); - return TCL_ERROR; - } - TkFocusSplit(winPtr); - Tk_UnmapWindow(frameWin); - if (wmPtr == NULL) { - TkWmNewWindow(winPtr); - if (winPtr->window == None) { - Tk_MakeWindowExist((Tk_Window) winPtr); - macWin = (MacDrawable *) winPtr->window; - } - TkWmMapWindow(winPtr); - Tk_UnmapWindow(frameWin); - } - wmPtr = winPtr->wmInfoPtr; - winPtr->flags &= ~TK_MAPPED; - macWin->grafPtr = NULL; - macWin->toplevel = macWin; - RemapWindows(winPtr, macWin); - winPtr->flags |= - (TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED); - TkMapTopFrame(frameWin); - } else if (Tk_IsTopLevel(frameWin)) { - /* Already managed by wm - ignore it */ - } - return TCL_OK; -#endif -} - -/* - *---------------------------------------------------------------------- - * - * WmMaxsizeCmd -- - * - * This procedure is invoked to process the "wm maxsize" Tcl command. See - * the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmMaxsizeCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - int width, height; - - if ((objc != 3) && (objc != 5)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?"); - return TCL_ERROR; - } - if (objc == 3) { - Tcl_Obj *size[2]; - - GetMaxSize(winPtr, &width, &height); - size[0] = Tcl_NewIntObj(width); - size[1] = Tcl_NewIntObj(height); - Tcl_SetObjResult(interp, Tcl_NewListObj(2, size)); - return TCL_OK; - } - if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) { - return TCL_ERROR; - } - wmPtr->maxWidth = width; - wmPtr->maxHeight = height; - wmPtr->flags |= WM_UPDATE_SIZE_HINTS; - WmUpdateGeom(wmPtr, winPtr); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmMinsizeCmd -- - * - * This procedure is invoked to process the "wm minsize" Tcl command. See - * the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmMinsizeCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - int width, height; - - if ((objc != 3) && (objc != 5)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?"); - return TCL_ERROR; - } - if (objc == 3) { - Tcl_Obj *size[2]; - - GetMinSize(winPtr, &width, &height); - size[0] = Tcl_NewIntObj(width); - size[1] = Tcl_NewIntObj(height); - Tcl_SetObjResult(interp, Tcl_NewListObj(2, size)); - return TCL_OK; - } - if ((Tcl_GetIntFromObj(interp, objv[3], &width) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[4], &height) != TCL_OK)) { - return TCL_ERROR; - } - wmPtr->minWidth = width; - wmPtr->minHeight = height; - wmPtr->flags |= WM_UPDATE_SIZE_HINTS; - WmUpdateGeom(wmPtr, winPtr); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmOverrideredirectCmd -- - * - * This procedure is invoked to process the "wm overrideredirect" Tcl - * command. See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmOverrideredirectCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - int boolean; - XSetWindowAttributes atts; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?"); - return TCL_ERROR; - } - if (objc == 3) { - Tcl_SetObjResult(interp, Tcl_NewBooleanObj( - Tk_Attributes((Tk_Window) winPtr)->override_redirect)); - return TCL_OK; - } - if (Tcl_GetBooleanFromObj(interp, objv[3], &boolean) != TCL_OK) { - return TCL_ERROR; - } - atts.override_redirect = (boolean) ? True : False; - Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWOverrideRedirect, &atts); - ApplyMasterOverrideChanges(winPtr, NULL); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmPositionfromCmd -- - * - * This procedure is invoked to process the "wm positionfrom" Tcl - * command. See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmPositionfromCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - static const char *const optionStrings[] = { - "program", "user", NULL }; - enum options { - OPT_PROGRAM, OPT_USER }; - int index; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?user/program?"); - return TCL_ERROR; - } - if (objc == 3) { - if (wmPtr->sizeHintsFlags & USPosition) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("user", -1)); - } else if (wmPtr->sizeHintsFlags & PPosition) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("program", -1)); - } - return TCL_OK; - } - if (*Tcl_GetString(objv[3]) == '\0') { - wmPtr->sizeHintsFlags &= ~(USPosition|PPosition); - } else { - if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0, - &index) != TCL_OK) { - return TCL_ERROR; - } - if (index == OPT_USER) { - wmPtr->sizeHintsFlags &= ~PPosition; - wmPtr->sizeHintsFlags |= USPosition; - } else { - wmPtr->sizeHintsFlags &= ~USPosition; - wmPtr->sizeHintsFlags |= PPosition; - } - } - wmPtr->flags |= WM_UPDATE_SIZE_HINTS; - WmUpdateGeom(wmPtr, winPtr); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmProtocolCmd -- - * - * This procedure is invoked to process the "wm protocol" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmProtocolCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - register ProtocolHandler *protPtr, *prevPtr; - Atom protocol; - char *cmd; - int cmdLength; - Tcl_Obj *resultObj; - - if ((objc < 3) || (objc > 5)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?name? ?command?"); - return TCL_ERROR; - } - if (objc == 3) { - /* - * Return a list of all defined protocols for the window. - */ - - resultObj = Tcl_NewObj(); - for (protPtr = wmPtr->protPtr; protPtr != NULL; - protPtr = protPtr->nextPtr) { - Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj( - Tk_GetAtomName((Tk_Window)winPtr, protPtr->protocol),-1)); - } - Tcl_SetObjResult(interp, resultObj); - return TCL_OK; - } - protocol = Tk_InternAtom((Tk_Window) winPtr, Tcl_GetString(objv[3])); - if (objc == 4) { - /* - * Return the command to handle a given protocol. - */ - - for (protPtr = wmPtr->protPtr; protPtr != NULL; - protPtr = protPtr->nextPtr) { - if (protPtr->protocol == protocol) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj(protPtr->command, -1)); - return TCL_OK; - } - } - return TCL_OK; - } - - /* - * Delete any current protocol handler, then create a new one with the - * specified command, unless the command is empty. - */ - - for (protPtr = wmPtr->protPtr, prevPtr = NULL; protPtr != NULL; - prevPtr = protPtr, protPtr = protPtr->nextPtr) { - if (protPtr->protocol == protocol) { - if (prevPtr == NULL) { - wmPtr->protPtr = protPtr->nextPtr; - } else { - prevPtr->nextPtr = protPtr->nextPtr; - } - Tcl_EventuallyFree(protPtr, TCL_DYNAMIC); - break; - } - } - cmd = Tcl_GetStringFromObj(objv[4], &cmdLength); - if (cmdLength > 0) { - protPtr = ckalloc(HANDLER_SIZE(cmdLength)); - protPtr->protocol = protocol; - protPtr->nextPtr = wmPtr->protPtr; - wmPtr->protPtr = protPtr; - protPtr->interp = interp; - strcpy(protPtr->command, cmd); - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmResizableCmd -- - * - * This procedure is invoked to process the "wm resizable" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmResizableCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - int width, height; - WindowAttributes oldAttributes = wmPtr->attributes; - - if ((objc != 3) && (objc != 5)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?width height?"); - return TCL_ERROR; - } - if (objc == 3) { - Tcl_Obj *resize[2]; - - resize[0] = Tcl_NewBooleanObj(!(wmPtr->flags & WM_WIDTH_NOT_RESIZABLE)); - resize[1] = Tcl_NewBooleanObj(!(wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE)); - Tcl_SetObjResult(interp, Tcl_NewListObj(2, resize)); - return TCL_OK; - } - if ((Tcl_GetBooleanFromObj(interp, objv[3], &width) != TCL_OK) - || (Tcl_GetBooleanFromObj(interp, objv[4], &height) != TCL_OK)) { - return TCL_ERROR; - } - if (width) { - wmPtr->flags &= ~WM_WIDTH_NOT_RESIZABLE; - wmPtr->attributes |= kWindowHorizontalZoomAttribute; - } else { - wmPtr->flags |= WM_WIDTH_NOT_RESIZABLE; - wmPtr->attributes &= ~kWindowHorizontalZoomAttribute; - } - if (height) { - wmPtr->flags &= ~WM_HEIGHT_NOT_RESIZABLE; - wmPtr->attributes |= kWindowVerticalZoomAttribute; - } else { - wmPtr->flags |= WM_HEIGHT_NOT_RESIZABLE; - wmPtr->attributes &= ~kWindowVerticalZoomAttribute; - } - if (width || height) { - wmPtr->attributes |= kWindowResizableAttribute; - } else { - wmPtr->attributes &= ~kWindowResizableAttribute; - } - wmPtr->flags |= WM_UPDATE_SIZE_HINTS; - if (wmPtr->scrollWinPtr != NULL) { - TkScrollbarEventuallyRedraw(wmPtr->scrollWinPtr->instanceData); - } - WmUpdateGeom(wmPtr, winPtr); - ApplyWindowClassAttributeChanges(winPtr, NULL, wmPtr->macClass, - oldAttributes, 1); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmSizefromCmd -- - * - * This procedure is invoked to process the "wm sizefrom" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmSizefromCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - static const char *const optionStrings[] = { - "program", "user", NULL }; - enum options { - OPT_PROGRAM, OPT_USER }; - int index; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?user|program?"); - return TCL_ERROR; - } - if (objc == 3) { - if (wmPtr->sizeHintsFlags & USSize) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("user", -1)); - } else if (wmPtr->sizeHintsFlags & PSize) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("program", -1)); - } - return TCL_OK; - } - - if (*Tcl_GetString(objv[3]) == '\0') { - wmPtr->sizeHintsFlags &= ~(USSize|PSize); - } else { - if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0, - &index) != TCL_OK) { - return TCL_ERROR; - } - if (index == OPT_USER) { - wmPtr->sizeHintsFlags &= ~PSize; - wmPtr->sizeHintsFlags |= USSize; - } else { /* OPT_PROGRAM */ - wmPtr->sizeHintsFlags &= ~USSize; - wmPtr->sizeHintsFlags |= PSize; - } - } - wmPtr->flags |= WM_UPDATE_SIZE_HINTS; - WmUpdateGeom(wmPtr, winPtr); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmStackorderCmd -- - * - * This procedure is invoked to process the "wm stackorder" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmStackorderCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - TkWindow **windows, **windowPtr; - static const char *const optionStrings[] = { - "isabove", "isbelow", NULL - }; - enum options { - OPT_ISABOVE, OPT_ISBELOW - }; - Tcl_Obj *resultObj; - int index; - - if ((objc != 3) && (objc != 5)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?isabove|isbelow window?"); - return TCL_ERROR; - } - - if (objc == 3) { - windows = TkWmStackorderToplevel(winPtr); - if (windows == NULL) { - Tcl_Panic("TkWmStackorderToplevel failed"); - } - - resultObj = Tcl_NewObj(); - for (windowPtr = windows; *windowPtr ; windowPtr++) { - Tcl_ListObjAppendElement(NULL, resultObj, - TkNewWindowObj((Tk_Window) *windowPtr)); - } - Tcl_SetObjResult(interp, resultObj); - ckfree(windows); - return TCL_OK; - } else { - TkWindow *winPtr2; - int index1 = -1, index2 = -1, result; - - if (TkGetWindowFromObj(interp, tkwin, objv[4], (Tk_Window *) &winPtr2) - != TCL_OK) { - return TCL_ERROR; - } - - if (!Tk_IsTopLevel(winPtr2)) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "window \"%s\" isn't a top-level window", - winPtr2->pathName)); - Tcl_SetErrorCode(interp, "TK", "WM", "STACK", "TOPLEVEL", NULL); - return TCL_ERROR; - } - - if (!Tk_IsMapped(winPtr)) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "window \"%s\" isn't mapped", winPtr->pathName)); - Tcl_SetErrorCode(interp, "TK", "WM", "STACK", "MAPPED", NULL); - return TCL_ERROR; - } else if (!Tk_IsMapped(winPtr2)) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "window \"%s\" isn't mapped", winPtr2->pathName)); - Tcl_SetErrorCode(interp, "TK", "WM", "STACK", "MAPPED", NULL); - return TCL_ERROR; - } - - /* - * Lookup stacking order of all toplevels that are children of "." and - * find the position of winPtr and winPtr2 in the stacking order. - */ - - windows = TkWmStackorderToplevel(winPtr->mainPtr->winPtr); - if (windows == NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "TkWmStackorderToplevel failed", -1)); - Tcl_SetErrorCode(interp, "TK", "WM", "STACK", "FAIL", NULL); - return TCL_ERROR; - } - - for (windowPtr = windows; *windowPtr ; windowPtr++) { - if (*windowPtr == winPtr) { - index1 = windowPtr - windows; - } - if (*windowPtr == winPtr2) { - index2 = windowPtr - windows; - } - } - if (index1 == -1) { - Tcl_Panic("winPtr window not found"); - } - if (index2 == -1) { - Tcl_Panic("winPtr2 window not found"); - } - - ckfree(windows); - - if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0, - &index) != TCL_OK) { - return TCL_ERROR; - } - if (index == OPT_ISABOVE) { - result = index1 > index2; - } else { /* OPT_ISBELOW */ - result = index1 < index2; - } - Tcl_SetObjResult(interp, Tcl_NewBooleanObj(result)); - return TCL_OK; - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmStateCmd -- - * - * This procedure is invoked to process the "wm state" Tcl command. See - * the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmStateCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - static const char *const optionStrings[] = { - "normal", "iconic", "withdrawn", "zoomed", NULL }; - enum options { - OPT_NORMAL, OPT_ICONIC, OPT_WITHDRAWN, OPT_ZOOMED }; - int index; - - if ((objc < 3) || (objc > 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?state?"); - return TCL_ERROR; - } - if (objc == 4) { - if (wmPtr->iconFor != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't change state of %s: it is an icon for %s", - Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor))); - Tcl_SetErrorCode(interp, "TK", "WM", "STATE", "ICON", NULL); - return TCL_ERROR; - } - if (winPtr->flags & TK_EMBEDDED) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't change state of %s: it is an embedded window", - winPtr->pathName)); - Tcl_SetErrorCode(interp, "TK", "WM", "STATE", "EMBEDDED", NULL); - return TCL_ERROR; - } - - if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0, - &index) != TCL_OK) { - return TCL_ERROR; - } - - if (index == OPT_NORMAL) { - TkpWmSetState(winPtr, NormalState); - - /* - * This varies from 'wm deiconify' because it does not force the - * window to be raised and receive focus - */ - } else if (index == OPT_ICONIC) { - if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't iconify \"%s\": override-redirect flag is set", - winPtr->pathName)); - Tcl_SetErrorCode(interp, "TK", "WM", "STATE", - "OVERRIDE_REDIRECT", NULL); - return TCL_ERROR; - } - if (wmPtr->master != None) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't iconify \"%s\": it is a transient", - winPtr->pathName)); - Tcl_SetErrorCode(interp, "TK", "WM", "STATE", "TRANSIENT", - NULL); - return TCL_ERROR; - } - TkpWmSetState(winPtr, IconicState); - } else if (index == OPT_WITHDRAWN) { - TkpWmSetState(winPtr, WithdrawnState); - } else { /* OPT_ZOOMED */ - TkpWmSetState(winPtr, ZoomState); - } - } else if (wmPtr->iconFor != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("icon", -1)); - } else { - if (wmPtr->hints.initial_state == NormalState || - wmPtr->hints.initial_state == ZoomState) { - wmPtr->hints.initial_state = (TkMacOSXIsWindowZoomed(winPtr) ? - ZoomState : NormalState); - } - switch (wmPtr->hints.initial_state) { - case NormalState: - Tcl_SetObjResult(interp, Tcl_NewStringObj("normal", -1)); - break; - case IconicState: - Tcl_SetObjResult(interp, Tcl_NewStringObj("iconic", -1)); - break; - case WithdrawnState: - Tcl_SetObjResult(interp, Tcl_NewStringObj("withdrawn", -1)); - break; - case ZoomState: - Tcl_SetObjResult(interp, Tcl_NewStringObj("zoomed", -1)); - break; - } - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmTitleCmd -- - * - * This procedure is invoked to process the "wm title" Tcl command. See - * the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmTitleCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - char *argv3; - int length; - - if (objc > 4) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?newTitle?"); - return TCL_ERROR; - } - if (objc == 3) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - wmPtr->titleUid ? wmPtr->titleUid : winPtr->nameUid, -1)); - return TCL_OK; - } - argv3 = Tcl_GetStringFromObj(objv[3], &length); - wmPtr->titleUid = Tk_GetUid(argv3); - if (!(wmPtr->flags & WM_NEVER_MAPPED) && !Tk_IsEmbedded(winPtr)) { - TkSetWMName(winPtr, wmPtr->titleUid); - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmTransientCmd -- - * - * This procedure is invoked to process the "wm transient" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmTransientCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - Tk_Window master; - WmInfo *wmPtr2; - char *argv3; - int length; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?master?"); - return TCL_ERROR; - } - if (objc == 3) { - if (wmPtr->master != None) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj(wmPtr->masterWindowName, -1)); - } - return TCL_OK; - } - if (Tcl_GetString(objv[3])[0] == '\0') { - wmPtr->master = None; - if (wmPtr->masterWindowName != NULL) { - ckfree(wmPtr->masterWindowName); - } - wmPtr->masterWindowName = NULL; - } else { - if (TkGetWindowFromObj(interp, tkwin, objv[3], &master) != TCL_OK) { - return TCL_ERROR; - } - Tk_MakeWindowExist(master); - - if (wmPtr->iconFor != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't make \"%s\" a transient: it is an icon for %s", - Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor))); - Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL); - return TCL_ERROR; - } - - wmPtr2 = ((TkWindow *) master)->wmInfoPtr; - - /* Under some circumstances, wmPtr2 is NULL here */ - if (wmPtr2 != NULL && wmPtr2->iconFor != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't make \"%s\" a master: it is an icon for %s", - Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor))); - Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL); - return TCL_ERROR; - } - - if ((TkWindow *) master == winPtr) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't make \"%s\" its own master", Tk_PathName(winPtr))); - Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL); - return TCL_ERROR; - } - - argv3 = Tcl_GetStringFromObj(objv[3], &length); - wmPtr->master = Tk_WindowId(master); - if (wmPtr->masterWindowName != NULL) { - ckfree(wmPtr->masterWindowName); - } - wmPtr->masterWindowName = ckalloc(length+1); - strcpy(wmPtr->masterWindowName, argv3); - } - ApplyMasterOverrideChanges(winPtr, NULL); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * WmWithdrawCmd -- - * - * This procedure is invoked to process the "wm withdraw" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -WmWithdrawCmd( - Tk_Window tkwin, /* Main window of the application. */ - TkWindow *winPtr, /* Toplevel to work with */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - register WmInfo *wmPtr = winPtr->wmInfoPtr; - - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "window"); - return TCL_ERROR; - } - if (wmPtr->iconFor != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't withdraw %s: it is an icon for %s", - Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor))); - Tcl_SetErrorCode(interp, "TK", "WM", "WITHDRAW", "ICON", NULL); - return TCL_ERROR; - } - TkpWmSetState(winPtr, WithdrawnState); - return TCL_OK; -} - -/* - * Invoked by those wm subcommands that affect geometry. - * Schedules a geometry update. - */ - -static void -WmUpdateGeom( - WmInfo *wmPtr, - TkWindow *winPtr) -{ - if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) { - Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr); - wmPtr->flags |= WM_UPDATE_PENDING; - } -} - -/* - *---------------------------------------------------------------------- - * - * Tk_SetGrid -- - * - * This procedure is invoked by a widget when it wishes to set a grid - * coordinate system that controls the size of a top-level window. It - * provides a C interface equivalent to the "wm grid" command and is - * usually asscoiated with the -setgrid option. - * - * Results: - * None. - * - * Side effects: - * Grid-related information will be passed to the window manager, so that - * the top-level window associated with tkwin will resize on even grid - * units. If some other window already controls gridding for the - * top-level window then this procedure call has no effect. - * - *---------------------------------------------------------------------- - */ - -void -Tk_SetGrid( - Tk_Window tkwin, /* Token for window. New window mgr info will - * be posted for the top-level window - * associated with this window. */ - int reqWidth, /* Width (in grid units) corresponding to the - * requested geometry for tkwin. */ - int reqHeight, /* Height (in grid units) corresponding to the - * requested geometry for tkwin. */ - int widthInc, int heightInc)/* Pixel increments corresponding to a change - * of one grid unit. */ -{ - TkWindow *winPtr = (TkWindow *) tkwin; - WmInfo *wmPtr; - - /* - * Ensure widthInc and heightInc are greater than 0 - */ - - if (widthInc <= 0) { - widthInc = 1; - } - if (heightInc <= 0) { - heightInc = 1; - } - - /* - * Find the top-level window for tkwin, plus the window manager - * information. - */ - - while (!(winPtr->flags & TK_TOP_LEVEL)) { - winPtr = winPtr->parentPtr; - } - wmPtr = winPtr->wmInfoPtr; - - if ((wmPtr->gridWin != NULL) && (wmPtr->gridWin != tkwin)) { - return; - } - - if ((wmPtr->reqGridWidth == reqWidth) - && (wmPtr->reqGridHeight == reqHeight) - && (wmPtr->widthInc == widthInc) - && (wmPtr->heightInc == heightInc) - && ((wmPtr->sizeHintsFlags & (PBaseSize|PResizeInc)) - == (PBaseSize|PResizeInc))) { - return; - } - - /* - * If gridding was previously off, then forget about any window size - * requests made by the user or via "wm geometry": these are in pixel - * units and there's no easy way to translate them to grid units since the - * new requested size of the top-level window in pixels may not yet have - * been registered yet (it may filter up the hierarchy in DoWhenIdle - * handlers). However, if the window has never been mapped yet then just - * leave the window size alone: assume that it is intended to be in grid - * units but just happened to have been specified before this procedure - * was called. - */ - - if ((wmPtr->gridWin == NULL) && !(wmPtr->flags & WM_NEVER_MAPPED)) { - wmPtr->width = -1; - wmPtr->height = -1; - } - - /* - * Set the new gridding information, and start the process of passing all - * of this information to the window manager. - */ - - wmPtr->gridWin = tkwin; - wmPtr->reqGridWidth = reqWidth; - wmPtr->reqGridHeight = reqHeight; - wmPtr->widthInc = widthInc; - wmPtr->heightInc = heightInc; - wmPtr->sizeHintsFlags |= PBaseSize|PResizeInc; - wmPtr->flags |= WM_UPDATE_SIZE_HINTS; - if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) { - Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr); - wmPtr->flags |= WM_UPDATE_PENDING; - } -} - -/* - *---------------------------------------------------------------------- - * - * Tk_UnsetGrid -- - * - * This procedure cancels the effect of a previous call to Tk_SetGrid. - * - * Results: - * None. - * - * Side effects: - * If tkwin currently controls gridding for its top-level window, - * gridding is cancelled for that top-level window; if some other window - * controls gridding then this procedure has no effect. - * - *---------------------------------------------------------------------- - */ - -void -Tk_UnsetGrid( - Tk_Window tkwin) /* Token for window that is currently - * controlling gridding. */ -{ - TkWindow *winPtr = (TkWindow *) tkwin; - WmInfo *wmPtr; - - /* - * Find the top-level window for tkwin, plus the window manager - * information. - */ - - while (!(winPtr->flags & TK_TOP_LEVEL)) { - winPtr = winPtr->parentPtr; - } - wmPtr = winPtr->wmInfoPtr; - if (tkwin != wmPtr->gridWin) { - return; - } - - wmPtr->gridWin = NULL; - wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc); - if (wmPtr->width != -1) { - wmPtr->width = winPtr->reqWidth + (wmPtr->width - - wmPtr->reqGridWidth)*wmPtr->widthInc; - wmPtr->height = winPtr->reqHeight + (wmPtr->height - - wmPtr->reqGridHeight)*wmPtr->heightInc; - } - wmPtr->widthInc = 1; - wmPtr->heightInc = 1; - - wmPtr->flags |= WM_UPDATE_SIZE_HINTS; - if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) { - Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr); - wmPtr->flags |= WM_UPDATE_PENDING; - } -} - -/* - *---------------------------------------------------------------------- - * - * TopLevelEventProc -- - * - * This procedure is invoked when a top-level (or other externally- - * managed window) is restructured in any way. - * - * Results: - * None. - * - * Side effects: - * Tk's internal data structures for the window get modified to reflect - * the structural change. - * - *---------------------------------------------------------------------- - */ - -static void -TopLevelEventProc( - ClientData clientData, /* Window for which event occurred. */ - XEvent *eventPtr) /* Event that just happened. */ -{ - TkWindow *winPtr = clientData; - - winPtr->wmInfoPtr->flags |= WM_VROOT_OFFSET_STALE; - if (eventPtr->type == DestroyNotify) { - if (!(winPtr->flags & TK_ALREADY_DEAD)) { - /* - * A top-level window was deleted externally (e.g., by the window - * manager). This is probably not a good thing, but cleanup as - * best we can. The error handler is needed because - * Tk_DestroyWindow will try to destroy the window, but of course - * it's already gone. - */ - - Tk_ErrorHandler handler = Tk_CreateErrorHandler(winPtr->display, - -1, -1, -1, NULL, NULL); - - Tk_DestroyWindow((Tk_Window) winPtr); - Tk_DeleteErrorHandler(handler); - } - if (wmTracing) { - TkMacOSXDbgMsg("TopLevelEventProc: %s deleted", winPtr->pathName); - } - } else if (eventPtr->type == ReparentNotify) { - Tcl_Panic("recieved unwanted reparent event"); - } -} - -/* - *---------------------------------------------------------------------- - * - * TopLevelReqProc -- - * - * This procedure is invoked by the geometry manager whenever the - * requested size for a top-level window is changed. - * - * Results: - * None. - * - * Side effects: - * Arrange for the window to be resized to satisfy the request (this - * happens as a when-idle action). - * - *---------------------------------------------------------------------- - */ - - /* ARGSUSED */ -static void -TopLevelReqProc( - ClientData dummy, /* Not used. */ - Tk_Window tkwin) /* Information about window. */ -{ - TkWindow *winPtr = (TkWindow *) tkwin; - WmInfo *wmPtr; - - wmPtr = winPtr->wmInfoPtr; - wmPtr->flags |= WM_UPDATE_SIZE_HINTS; - if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) { - Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr); - wmPtr->flags |= WM_UPDATE_PENDING; - } -} - -/* - *---------------------------------------------------------------------- - * - * UpdateGeometryInfo -- - * - * This procedure is invoked when a top-level window is first mapped, and - * also as a when-idle procedure, to bring the geometry and/or position - * of a top-level window back into line with what has been requested by - * the user and/or widgets. This procedure doesn't return until the - * window manager has responded to the geometry change. - * - * Results: - * None. - * - * Side effects: - * The window's size and location may change, unless the WM prevents that - * from happening. - * - *---------------------------------------------------------------------- - */ - -static void -UpdateGeometryInfo( - ClientData clientData) /* Pointer to the window's record. */ -{ - TkWindow *winPtr = clientData; - WmInfo *wmPtr = winPtr->wmInfoPtr; - int x, y, width, height, min, max; - - wmPtr->flags &= ~WM_UPDATE_PENDING; - - if (wmPtr->flags & WM_FULLSCREEN) { - return; - } - - /* - * Compute the new size for the top-level window. See the user - * documentation for details on this, but the size requested depends on - * (a) the size requested internally by the window's widgets, (b) the size - * requested by the user in a "wm geometry" command or via wm-based - * interactive resizing (if any), and (c) whether or not the window is - * gridded. Don't permit sizes <= 0 because this upsets the X server. - */ - - if (wmPtr->width == -1) { - width = winPtr->reqWidth; - } else if (wmPtr->gridWin != NULL) { - width = winPtr->reqWidth - + (wmPtr->width - wmPtr->reqGridWidth)*wmPtr->widthInc; - } else { - width = wmPtr->width; - } - if (width <= 0) { - width = 1; - } - - /* - * Account for window max/min width - */ - - if (wmPtr->gridWin != NULL) { - min = winPtr->reqWidth - + (wmPtr->minWidth - wmPtr->reqGridWidth)*wmPtr->widthInc; - if (wmPtr->maxWidth > 0) { - max = winPtr->reqWidth - + (wmPtr->maxWidth - wmPtr->reqGridWidth)*wmPtr->widthInc; - } else { - max = 0; - } - } else { - min = wmPtr->minWidth; - max = wmPtr->maxWidth; - } - if (width < min) { - width = min; - } else if ((max > 0) && (width > max)) { - width = max; - } - - if (wmPtr->height == -1) { - height = winPtr->reqHeight; - } else if (wmPtr->gridWin != NULL) { - height = winPtr->reqHeight - + (wmPtr->height - wmPtr->reqGridHeight)*wmPtr->heightInc; - } else { - height = wmPtr->height; - } - if (height <= 0) { - height = 1; - } - - /* - * Account for window max/min height - */ - - if (wmPtr->gridWin != NULL) { - min = winPtr->reqHeight - + (wmPtr->minHeight - wmPtr->reqGridHeight)*wmPtr->heightInc; - if (wmPtr->maxHeight > 0) { - max = winPtr->reqHeight - + (wmPtr->maxHeight-wmPtr->reqGridHeight)*wmPtr->heightInc; - } else { - max = 0; - } - } else { - min = wmPtr->minHeight; - max = wmPtr->maxHeight; - } - if (height < min) { - height = min; - } else if ((max > 0) && (height > max)) { - height = max; - } - - /* - * Compute the new position for the upper-left pixel of the window's - * decorative frame. This is tricky, because we need to include the border - * widths supplied by a reparented parent in this calculation, but can't - * use the parent's current overall size since that may change as a result - * of this code. - */ - - if (wmPtr->flags & WM_NEGATIVE_X) { - x = wmPtr->vRootWidth - wmPtr->x - - (width + (wmPtr->parentWidth - winPtr->changes.width)); - } else { - x = wmPtr->x; - } - if (wmPtr->flags & WM_NEGATIVE_Y) { - y = wmPtr->vRootHeight - wmPtr->y - - (height + (wmPtr->parentHeight - winPtr->changes.height)); - } else { - y = wmPtr->y; - } - - /* - * If the window's size is going to change and the window is supposed to - * not be resizable by the user, then we have to update the size hints. - * There may also be a size-hint-update request pending from somewhere - * else, too. - */ - - if (((width != winPtr->changes.width) - || (height != winPtr->changes.height)) - && (wmPtr->gridWin == NULL) - && !(wmPtr->sizeHintsFlags & (PMinSize|PMaxSize))) { - wmPtr->flags |= WM_UPDATE_SIZE_HINTS; - } - if (wmPtr->flags & WM_UPDATE_SIZE_HINTS) { - UpdateSizeHints(winPtr); - } - - /* - * Reconfigure the window if it isn't already configured correctly. A few - * tricky points: - * - * 1. If the window is embedded and the container is also in this process, - * don't actually reconfigure the window; just pass the desired size on - * to the container. Also, zero out any position information, since - * embedded windows are not allowed to move. - * 2. Sometimes the window manager will give us a different size than we - * asked for (e.g. mwm has a minimum size for windows), so base the - * size check on what we *asked for* last time, not what we got. - * 3. Don't move window unless a new position has been requested for it. - * This is because of "features" in some window managers (e.g. twm, as - * of 4/24/91) where they don't interpret coordinates according to - * ICCCM. Moving a window to its current location may cause it to shift - * position on the screen. - */ - - if (Tk_IsEmbedded(winPtr)) { - TkWindow *contWinPtr = TkpGetOtherWindow(winPtr); - - /* - * TODO: Here we should handle out of process embedding. - */ - - if (contWinPtr != NULL) { - /* - * This window is embedded and the container is also in this - * process, so we don't need to do anything special about the - * geometry, except to make sure that the desired size is known by - * the container. Also, zero out any position information, since - * embedded windows are not allowed to move. - */ - - wmPtr->x = wmPtr->y = 0; - wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y); - Tk_GeometryRequest((Tk_Window) contWinPtr, width, height); - } - return; - } - if (wmPtr->flags & WM_MOVE_PENDING) { - wmPtr->configWidth = width; - wmPtr->configHeight = height; - if (wmTracing) { - TkMacOSXDbgMsg("Moving to %d %d, resizing to %d x %d", x, y, - width, height); - } - wmPtr->flags |= WM_SYNC_PENDING; - XMoveResizeWindow(winPtr->display, winPtr->window, x, y, - (unsigned) width, (unsigned) height); - wmPtr->flags &= ~WM_SYNC_PENDING; - } else if ((width != wmPtr->configWidth) - || (height != wmPtr->configHeight)) { - wmPtr->configWidth = width; - wmPtr->configHeight = height; - if (wmTracing) { - TkMacOSXDbgMsg("Resizing to %d x %d\n", width, height); - } - wmPtr->flags |= WM_SYNC_PENDING; - XResizeWindow(winPtr->display, winPtr->window, (unsigned) width, - (unsigned) height); - wmPtr->flags &= ~WM_SYNC_PENDING; - } -} - -/* - *---------------------------------------------------------------------- - * - * UpdateSizeHints -- - * - * This procedure is called to update the window manager's size hints - * information from the information in a WmInfo structure. - * - * Results: - * None. - * - * Side effects: - * Properties get changed for winPtr. - * - *---------------------------------------------------------------------- - */ - -static void -UpdateSizeHints( - TkWindow *winPtr) -{ - WmInfo *wmPtr = winPtr->wmInfoPtr; - - wmPtr->flags &= ~WM_UPDATE_SIZE_HINTS; -} - -/* - *---------------------------------------------------------------------- - * - * ParseGeometry -- - * - * This procedure parses a geometry string and updates information used - * to control the geometry of a top-level window. - * - * Results: - * A standard Tcl return value, plus an error message in the interp's - * result if an error occurs. - * - * Side effects: - * The size and/or location of winPtr may change. - * - *---------------------------------------------------------------------- - */ - -static int -ParseGeometry( - Tcl_Interp *interp, /* Used for error reporting. */ - char *string, /* String containing new geometry. Has the - * standard form "=wxh+x+y". */ - TkWindow *winPtr) /* Pointer to top-level window whose geometry - * is to be changed. */ -{ - WmInfo *wmPtr = winPtr->wmInfoPtr; - int x, y, width, height, flags; - char *end; - char *p = string; - - /* - * The leading "=" is optional. - */ - - if (*p == '=') { - p++; - } - - /* - * Parse the width and height, if they are present. Don't actually update - * any of the fields of wmPtr until we've successfully parsed the entire - * geometry string. - */ - - width = wmPtr->width; - height = wmPtr->height; - x = wmPtr->x; - y = wmPtr->y; - flags = wmPtr->flags; - if (isdigit(UCHAR(*p))) { - width = strtoul(p, &end, 10); - p = end; - if (*p != 'x') { - goto error; - } - p++; - if (!isdigit(UCHAR(*p))) { - goto error; - } - height = strtoul(p, &end, 10); - p = end; - } - - /* - * Parse the X and Y coordinates, if they are present. - */ - - if (*p != '\0') { - flags &= ~(WM_NEGATIVE_X | WM_NEGATIVE_Y); - if (*p == '-') { - flags |= WM_NEGATIVE_X; - } else if (*p != '+') { - goto error; - } - p++; - if (!isdigit(UCHAR(*p)) && (*p != '-')) { - goto error; - } - x = strtol(p, &end, 10); - p = end; - if (*p == '-') { - flags |= WM_NEGATIVE_Y; - } else if (*p != '+') { - goto error; - } - p++; - if (!isdigit(UCHAR(*p)) && (*p != '-')) { - goto error; - } - y = strtol(p, &end, 10); - if (*end != '\0') { - goto error; - } - - /* - * Assume that the geometry information came from the user, unless an - * explicit source has been specified. Otherwise most window managers - * assume that the size hints were program-specified and they ignore - * them. - */ - - if (!(wmPtr->sizeHintsFlags & (USPosition|PPosition))) { - wmPtr->sizeHintsFlags |= USPosition; - flags |= WM_UPDATE_SIZE_HINTS; - } - } - - /* - * Everything was parsed OK. Update the fields of *wmPtr and arrange for - * the appropriate information to be percolated out to the window manager - * at the next idle moment. - */ - - wmPtr->width = width; - wmPtr->height = height; - if ((x != wmPtr->x) || (y != wmPtr->y) - || ((flags & (WM_NEGATIVE_X|WM_NEGATIVE_Y)) - != (wmPtr->flags & (WM_NEGATIVE_X|WM_NEGATIVE_Y)))) { - if (wmPtr->flags & WM_FULLSCREEN) { - wmPtr->configX = x; - wmPtr->configY = y; - } else { - wmPtr->x = x; - wmPtr->y = y; - } - flags |= WM_MOVE_PENDING; - } - wmPtr->flags = flags; - - if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) { - Tcl_DoWhenIdle(UpdateGeometryInfo, winPtr); - wmPtr->flags |= WM_UPDATE_PENDING; - } - return TCL_OK; - - error: - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "bad geometry specifier \"%s\"", string)); - Tcl_SetErrorCode(interp, "TK", "VALUE", "GEOMETRY", NULL); - return TCL_ERROR; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_GetRootCoords -- - * - * Given a token for a window, this procedure traces through the window's - * lineage to find the (virtual) root-window coordinates corresponding to - * point (0,0) in the window. - * - * Results: - * The locations pointed to by xPtr and yPtr are filled in with the root - * coordinates of the (0,0) point in tkwin. If a virtual root window is - * in effect for the window, then the coordinates in the virtual root are - * returned. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -Tk_GetRootCoords( - Tk_Window tkwin, /* Token for window. */ - int *xPtr, /* Where to store x-displacement of (0,0). */ - int *yPtr) /* Where to store y-displacement of (0,0). */ -{ - int x, y; - TkWindow *winPtr = (TkWindow *) tkwin; - - /* - * Search back through this window's parents all the way to a top-level - * window, combining the offsets of each window within its parent. - */ - - x = y = 0; - while (1) { - x += winPtr->changes.x + winPtr->changes.border_width; - y += winPtr->changes.y + winPtr->changes.border_width; - if (winPtr->flags & TK_TOP_LEVEL) { - TkWindow *otherPtr; - - if (!(Tk_IsEmbedded(winPtr))) { - x += winPtr->wmInfoPtr->xInParent; - y += winPtr->wmInfoPtr->yInParent; - break; - } - - otherPtr = TkpGetOtherWindow(winPtr); - if (otherPtr == NULL) { - if (tkMacOSXEmbedHandler->getOffsetProc != NULL) { - Point theOffset; - - /* - * We do not require that the changes.x & changes.y for a - * non-Tk master window be kept up to date. So we first - * subtract off the possibly bogus values that have been - * added on at the top of this pass through the loop, and - * then call out to the getOffsetProc to give us the - * correct offset. - */ - - x -= winPtr->changes.x + winPtr->changes.border_width; - y -= winPtr->changes.y + winPtr->changes.border_width; - - tkMacOSXEmbedHandler->getOffsetProc((Tk_Window) winPtr, - &theOffset); - - x += theOffset.h; - y += theOffset.v; - } - break; - } - - /* - * The container window is in the same application. Query its - * coordinates. - */ - - winPtr = otherPtr; - - /* - * Remember to offset by the container window here, since at the - * end of this if branch, we will pop out to the container's - * parent... - */ - - x += winPtr->changes.x + winPtr->changes.border_width; - y += winPtr->changes.y + winPtr->changes.border_width; - } - winPtr = winPtr->parentPtr; - } - *xPtr = x; - *yPtr = y; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_CoordsToWindow -- - * - * This is a Macintosh specific implementation of this function. Given - * the root coordinates of a point, this procedure returns the token for - * the top-most window covering that point, if there exists such a window - * in this application. - * - * Results: - * The return result is either a token for the window corresponding to - * rootX and rootY, or else NULL to indicate that there is no such - * window. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -Tk_Window -Tk_CoordsToWindow( - int rootX, int rootY, /* Coordinates of point in root window. If a - * virtual-root window manager is in use, - * these coordinates refer to the virtual - * root, not the real root. */ - Tk_Window tkwin) /* Token for any window in application; used - * to identify the display. */ -{ - WindowPtr whichWin; - Point where; - Window rootChild; - TkWindow *winPtr, *childPtr; - TkWindow *nextPtr; /* Coordinates of highest child found so far - * that contains point. */ - int x, y; /* Coordinates in winPtr. */ - int tmpx, tmpy, bd; - TkDisplay *dispPtr; - - /* - * Step 1: find the top-level window that contains the desired point. - */ - - where.h = rootX; - where.v = rootY; - FindWindow(where, &whichWin); - if (whichWin == NULL) { - return NULL; - } - rootChild = TkMacOSXGetXWindow(whichWin); - dispPtr = TkGetDisplayList(); - winPtr = (TkWindow *) Tk_IdToWindow(dispPtr->display, rootChild); - if (winPtr == NULL) { - return NULL; - } - - /* - * Step 2: work down through the hierarchy underneath this window. At each - * level, scan through all the children to find the highest one in the - * stacking order that contains the point. Then repeat the whole process - * on that child. - */ - - x = rootX - winPtr->wmInfoPtr->xInParent; - y = rootY - winPtr->wmInfoPtr->yInParent; - while (1) { - x -= winPtr->changes.x; - y -= winPtr->changes.y; - nextPtr = NULL; - - /* - * Container windows cannot have children. So if it is a container, - * look there, otherwise inspect the children. - */ - - if (Tk_IsContainer(winPtr)) { - childPtr = TkpGetOtherWindow(winPtr); - if (childPtr != NULL) { - if (Tk_IsMapped(childPtr)) { - tmpx = x - childPtr->changes.x; - tmpy = y - childPtr->changes.y; - bd = childPtr->changes.border_width; - - if ((tmpx >= -bd) && (tmpy >= -bd) - && (tmpx < (childPtr->changes.width + bd)) - && (tmpy < (childPtr->changes.height + bd))) { - nextPtr = childPtr; - } - } - } - - /* - * TODO: Here we should handle out of process embedding. - */ - } else { - for (childPtr = winPtr->childList; childPtr != NULL; - childPtr = childPtr->nextPtr) { - if (!Tk_IsMapped(childPtr) || - (childPtr->flags & TK_TOP_LEVEL)) { - continue; - } - tmpx = x - childPtr->changes.x; - tmpy = y - childPtr->changes.y; - bd = childPtr->changes.border_width; - if ((tmpx >= -bd) && (tmpy >= -bd) - && (tmpx < (childPtr->changes.width + bd)) - && (tmpy < (childPtr->changes.height + bd))) { - nextPtr = childPtr; - } - } - } - if (nextPtr == NULL) { - break; - } - winPtr = nextPtr; - } - return (Tk_Window) winPtr; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_TopCoordsToWindow -- - * - * Given a Tk Window, and coordinates of a point relative to that window - * this procedure returns the top-most child of the window (excluding - * toplevels) covering that point, if there exists such a window in this - * application. It also sets newX, and newY to the coords of the point - * relative to the window returned. - * - * Results: - * The return result is either a token for the window corresponding to - * rootX and rootY, or else NULL to indicate that there is no such - * window. newX and newY are also set to the coords of the point relative - * to the returned window. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -Tk_Window -Tk_TopCoordsToWindow( - Tk_Window tkwin, /* Token for a Tk Window which defines the - * coordinates for rootX & rootY */ - int rootX, int rootY, /* Coordinates of a point in tkWin. */ - int *newX, int *newY) /* Coordinates of point in the upperMost child - * of tkWin containing (rootX,rootY) */ -{ - TkWindow *winPtr, *childPtr; - TkWindow *nextPtr; /* Coordinates of highest child found so far - * that contains point. */ - int x, y; /* Coordinates in winPtr. */ - Window *children; /* Children of winPtr, or NULL. */ - - winPtr = (TkWindow *) tkwin; - x = rootX; - y = rootY; - while (1) { - nextPtr = NULL; - children = NULL; - - /* - * Container windows cannot have children. So if it is a container, - * look there, otherwise inspect the children. - */ - - if (Tk_IsContainer(winPtr)) { - childPtr = TkpGetOtherWindow(winPtr); - if (childPtr != NULL) { - if (Tk_IsMapped(childPtr) && - x > childPtr->changes.x && - x < childPtr->changes.x + childPtr->changes.width && - y > childPtr->changes.y && - y < childPtr->changes.y + childPtr->changes.height) { - nextPtr = childPtr; - } - } - - /* - * TODO: Here we should handle out of process embedding. - */ - } else { - for (childPtr = winPtr->childList; childPtr != NULL; - childPtr = childPtr->nextPtr) { - if (!Tk_IsMapped(childPtr) || - (childPtr->flags & TK_TOP_LEVEL)) { - continue; - } - if (x < childPtr->changes.x || y < childPtr->changes.y) { - continue; - } - if (x > childPtr->changes.x + childPtr->changes.width || - y > childPtr->changes.y + childPtr->changes.height) { - continue; - } - nextPtr = childPtr; - } - } - if (nextPtr == NULL) { - break; - } - winPtr = nextPtr; - x -= winPtr->changes.x; - y -= winPtr->changes.y; - } - *newX = x; - *newY = y; - return (Tk_Window) winPtr; -} - -/* - *---------------------------------------------------------------------- - * - * UpdateVRootGeometry -- - * - * This procedure is called to update all the virtual root geometry - * information in wmPtr. - * - * Results: - * None. - * - * Side effects: - * The vRootX, vRootY, vRootWidth, and vRootHeight fields in wmPtr are - * filled with the most up-to-date information. - * - *---------------------------------------------------------------------- - */ - -static void -UpdateVRootGeometry( - WmInfo *wmPtr) /* Window manager information to be updated. - * The wmPtr->vRoot field must be valid. */ -{ - TkWindow *winPtr = wmPtr->winPtr; - unsigned int bd, dummy; - Window dummy2; - Status status; - Tk_ErrorHandler handler; - - /* - * If this isn't a virtual-root window manager, just return information - * about the screen. - */ - - wmPtr->flags &= ~WM_VROOT_OFFSET_STALE; - if (wmPtr->vRoot == None) { - noVRoot: - wmPtr->vRootX = wmPtr->vRootY = 0; - wmPtr->vRootWidth = DisplayWidth(winPtr->display, winPtr->screenNum); - wmPtr->vRootHeight = DisplayHeight(winPtr->display, winPtr->screenNum); - return; - } - - /* - * Refresh the virtual root information if it's out of date. - */ - - handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1, NULL, NULL); - status = XGetGeometry(winPtr->display, wmPtr->vRoot, - &dummy2, &wmPtr->vRootX, &wmPtr->vRootY, - &wmPtr->vRootWidth, &wmPtr->vRootHeight, &bd, &dummy); - if (wmTracing) { - TkMacOSXDbgMsg("x = %d, y = %d, width = %d, height = %d, status = %d", - wmPtr->vRootX, wmPtr->vRootY, wmPtr->vRootWidth, - wmPtr->vRootHeight, status); - } - Tk_DeleteErrorHandler(handler); - if (status == 0) { - /* - * The virtual root is gone! Pretend that it never existed. - */ - - wmPtr->vRoot = None; - goto noVRoot; - } -} - -/* - *---------------------------------------------------------------------- - * - * Tk_GetVRootGeometry -- - * - * This procedure returns information about the virtual root window - * corresponding to a particular Tk window. - * - * Results: - * The values at xPtr, yPtr, widthPtr, and heightPtr are set with the - * offset and dimensions of the root window corresponding to tkwin. If - * tkwin is being managed by a virtual root window manager these values - * correspond to the virtual root window being used for tkwin; otherwise - * the offsets will be 0 and the dimensions will be those of the screen. - * - * Side effects: - * Vroot window information is refreshed if it is out of date. - * - *---------------------------------------------------------------------- - */ - -void -Tk_GetVRootGeometry( - Tk_Window tkwin, /* Window whose virtual root is to be - * queried. */ - int *xPtr, int *yPtr, /* Store x and y offsets of virtual root - * here. */ - int *widthPtr, /* Store dimensions of virtual root here. */ - int *heightPtr) -{ - WmInfo *wmPtr; - TkWindow *winPtr = (TkWindow *) tkwin; - - /* - * Find the top-level window for tkwin, and locate the window manager - * information for that window. - */ - - while (!(winPtr->flags & TK_TOP_LEVEL)) { - winPtr = winPtr->parentPtr; - } - wmPtr = winPtr->wmInfoPtr; - - /* - * Make sure that the geometry information is up-to-date, then copy it out - * to the caller. - */ - - if (wmPtr->flags & WM_VROOT_OFFSET_STALE) { - UpdateVRootGeometry(wmPtr); - } - *xPtr = wmPtr->vRootX; - *yPtr = wmPtr->vRootY; - *widthPtr = wmPtr->vRootWidth; - *heightPtr = wmPtr->vRootHeight; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_MoveToplevelWindow -- - * - * This procedure is called instead of Tk_MoveWindow to adjust the x-y - * location of a top-level window. It delays the actual move to a later - * time and keeps window-manager information up-to-date with the move. - * - * Results: - * None. - * - * Side effects: - * The window is eventually moved so that its upper-left corner - * (actually, the upper-left corner of the window's decorative frame, if - * there is one) is at (x,y). - * - *---------------------------------------------------------------------- - */ - -void -Tk_MoveToplevelWindow( - Tk_Window tkwin, /* Window to move. */ - int x, int y) /* New location for window (within parent). */ -{ - TkWindow *winPtr = (TkWindow *) tkwin; - WmInfo *wmPtr = winPtr->wmInfoPtr; - - if (!(winPtr->flags & TK_TOP_LEVEL)) { - Tcl_Panic("Tk_MoveToplevelWindow called with non-toplevel window"); - } - wmPtr->x = x; - wmPtr->y = y; - wmPtr->flags |= WM_MOVE_PENDING; - wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y); - if (!(wmPtr->sizeHintsFlags & (USPosition|PPosition))) { - wmPtr->sizeHintsFlags |= USPosition; - wmPtr->flags |= WM_UPDATE_SIZE_HINTS; - } - - /* - * If the window has already been mapped, must bring its geometry - * up-to-date immediately, otherwise an event might arrive from the server - * that would overwrite wmPtr->x and wmPtr->y and lose the new position. - */ - - if (!(wmPtr->flags & WM_NEVER_MAPPED)) { - if (wmPtr->flags & WM_UPDATE_PENDING) { - Tk_CancelIdleCall(UpdateGeometryInfo, winPtr); - } - UpdateGeometryInfo(winPtr); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkWmRestackToplevel -- - * - * This procedure restacks a top-level window. - * - * Results: - * None. - * - * Side effects: - * WinPtr gets restacked as specified by aboveBelow and otherPtr. This - * procedure doesn't return until the restack has taken effect and the - * ConfigureNotify event for it has been received. - * - *---------------------------------------------------------------------- - */ - -void -TkWmRestackToplevel( - TkWindow *winPtr, /* Window to restack. */ - int aboveBelow, /* Gives relative position for restacking; - * must be Above or Below. */ - TkWindow *otherPtr) /* Window relative to which to restack; if - * NULL, then winPtr gets restacked above or - * below *all* siblings. */ -{ - WmInfo *wmPtr; - - WindowRef macWindow, otherMacWindow, frontWindow, tmpWindow; - - wmPtr = winPtr->wmInfoPtr; - - /* - * Get the mac window. Make sure it exists & is mapped. - */ - - if (winPtr->window == None) { - Tk_MakeWindowExist((Tk_Window) winPtr); - } - if (winPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) { - /* - * Can't set stacking order properly until the window is on the screen - * (mapping it may give it a reparent window), so make sure it's on - * the screen. - */ - - TkWmMapWindow(winPtr); - } - macWindow = TkMacOSXDrawableWindow(winPtr->window); - - /* - * Get the window in which a raise or lower is in relation to. - */ - - if (otherPtr != NULL) { - if (otherPtr->window == None) { - Tk_MakeWindowExist((Tk_Window) otherPtr); - } - if (otherPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) { - TkWmMapWindow(otherPtr); - } - otherMacWindow = TkMacOSXDrawableWindow(otherPtr->window); - } else { - otherMacWindow = NULL; - } - - frontWindow = ActiveNonFloatingWindow(); - - if (aboveBelow == Above) { - if (macWindow == frontWindow) { - /* - * Do nothing - it's already at the top. - */ - } else if (otherMacWindow == frontWindow || otherMacWindow == NULL) { - /* - * Raise the window to the top. If the window is visible then we - * also make it the active window. - */ - - if (wmPtr->hints.initial_state == WithdrawnState) { - BringToFront(macWindow); - } else { - SelectWindow(macWindow); - } - } else { - /* - * Find the window to be above. (Front window will actually be the - * window to be behind.) Front window is NULL if no other windows. - */ - - while (frontWindow != NULL && - (tmpWindow=GetNextWindow(frontWindow)) != otherMacWindow) { - frontWindow = tmpWindow; - } - if (frontWindow != NULL) { - SendBehind(macWindow, frontWindow); - } - } - } else { - /* - * Send behind. If it was in front find another window to make active. - */ - - if (macWindow == frontWindow) { - tmpWindow = GetNextWindow(macWindow); - if (tmpWindow != NULL) { - SelectWindow(tmpWindow); - } - } - SendBehind(macWindow, otherMacWindow); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkWmAddToColormapWindows -- - * - * This procedure is called to add a given window to the - * WM_COLORMAP_WINDOWS property for its top-level, if it isn't already - * there. It is invoked by the Tk code that creates a new colormap, in - * order to make sure that colormap information is propagated to the - * window manager by default. - * - * Results: - * None. - * - * Side effects: - * WinPtr's window gets added to the WM_COLORMAP_WINDOWS property of its - * nearest top-level ancestor, unless the colormaps have been set - * explicitly with the "wm colormapwindows" command. - * - *---------------------------------------------------------------------- - */ - -void -TkWmAddToColormapWindows( - TkWindow *winPtr) /* Window with a non-default colormap. Should - * not be a top-level window. */ -{ - TkWindow *topPtr; - TkWindow **oldPtr, **newPtr; - int count, i; - - if (winPtr->window == None) { - return; - } - - for (topPtr = winPtr->parentPtr; ; topPtr = topPtr->parentPtr) { - if (topPtr == NULL) { - /* - * Window is being deleted. Skip the whole operation. - */ - - return; - } - if (topPtr->flags & TK_TOP_LEVEL) { - break; - } - } - if (topPtr->wmInfoPtr->flags & WM_COLORMAPS_EXPLICIT) { - return; - } - - /* - * Make sure that the window isn't already in the list. - */ - - count = topPtr->wmInfoPtr->cmapCount; - oldPtr = topPtr->wmInfoPtr->cmapList; - - for (i = 0; i < count; i++) { - if (oldPtr[i] == winPtr) { - return; - } - } - - /* - * Make a new bigger array and use it to reset the property. Automatically - * add the toplevel itself as the last element of the list. - */ - - newPtr = ckalloc((count+2) * sizeof(TkWindow *)); - if (count > 0) { - memcpy(newPtr, oldPtr, count * sizeof(TkWindow *)); - } - if (count == 0) { - count++; - } - newPtr[count-1] = winPtr; - newPtr[count] = topPtr; - if (oldPtr != NULL) { - ckfree(oldPtr); - } - - topPtr->wmInfoPtr->cmapList = newPtr; - topPtr->wmInfoPtr->cmapCount = count+1; - - /* - * On the Macintosh all of this is just an excercise in compatability as - * we don't support colormaps. If we did they would be installed here. - */ -} - -/* - *---------------------------------------------------------------------- - * - * TkWmRemoveFromColormapWindows -- - * - * This procedure is called to remove a given window from the - * WM_COLORMAP_WINDOWS property for its top-level. It is invoked when - * windows are deleted. - * - * Results: - * None. - * - * Side effects: - * WinPtr's window gets removed from the WM_COLORMAP_WINDOWS property of - * its nearest top-level ancestor, unless the top-level itself is being - * deleted too. - * - *---------------------------------------------------------------------- - */ - -void -TkWmRemoveFromColormapWindows( - TkWindow *winPtr) /* Window that may be present in - * WM_COLORMAP_WINDOWS property for its - * top-level. Should not be a top-level - * window. */ -{ - TkWindow *topPtr, **oldPtr; - int count, i, j; - - for (topPtr = winPtr->parentPtr; ; topPtr = topPtr->parentPtr) { - if (topPtr == NULL) { - /* - * Ancestors have been deleted, so skip the whole operation. Seems - * like this can't ever happen? - */ - - return; - } - if (topPtr->flags & TK_TOP_LEVEL) { - break; - } - } - if (topPtr->flags & TK_ALREADY_DEAD) { - /* - * Top-level is being deleted, so there's no need to cleanup the - * WM_COLORMAP_WINDOWS property. - */ - - return; - } - - /* - * Find the window and slide the following ones down to cover it up. - */ - - count = topPtr->wmInfoPtr->cmapCount; - oldPtr = topPtr->wmInfoPtr->cmapList; - for (i = 0; i < count; i++) { - if (oldPtr[i] == winPtr) { - for (j = i ; j < count-1; j++) { - oldPtr[j] = oldPtr[j+1]; - } - topPtr->wmInfoPtr->cmapCount = count - 1; - break; - } - } -} - -/* - *---------------------------------------------------------------------- - * - * TkGetPointerCoords -- - * - * Fetch the position of the mouse pointer. - * - * Results: - * *xPtr and *yPtr are filled in with the (virtual) root coordinates of - * the mouse pointer for tkwin's display. If the pointer isn't on tkwin's - * screen, then -1 values are returned for both coordinates. The argument - * tkwin must be a toplevel window. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkGetPointerCoords( - Tk_Window tkwin, /* Toplevel window that identifies screen on - * which lookup is to be done. */ - int *xPtr, int *yPtr) /* Store pointer coordinates here. */ -{ - XQueryPointer(NULL, None, NULL, NULL, xPtr, yPtr, NULL, NULL, NULL); -} - -/* - *---------------------------------------------------------------------- - * - * InitialWindowBounds -- - * - * This function calculates the initial bounds for a new Mac toplevel - * window. Unless the geometry is specified by the user this code will - * auto place the windows in a cascade diagonially across the main - * monitor of the Mac. - * - * Results: - * The bounds are returned in geometry. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -InitialWindowBounds( - TkWindow *winPtr, /* Window to get initial bounds for. */ - WindowRef macWindow, - Rect *geometry) /* On return the initial bounds. */ -{ - WmInfo *wmPtr = winPtr->wmInfoPtr; - - if (!(wmPtr->sizeHintsFlags & (USPosition | PPosition))) { - WindowRef parent; - - parent = GetFrontWindowOfClass(wmPtr->macClass, false); - if (parent && parent == macWindow) { - parent = GetNextWindowOfClass(parent, wmPtr->macClass, false); - } - if (parent && parent != macWindow) { - Rect bounds; - - ChkErr(RepositionWindow, macWindow, parent, - kWindowCascadeOnParentWindowScreen); - ChkErr(GetWindowBounds, macWindow, kWindowStructureRgn, &bounds); - wmPtr->x = bounds.left; - wmPtr->y = bounds.top; - } else { - static SInt16 menuBarHeight = 0; - - if (!menuBarHeight) { - ChkErr(GetThemeMenuBarHeight, &menuBarHeight); - } - wmPtr->x = 5; - wmPtr->y = menuBarHeight + 5; - } - } - - geometry->left = wmPtr->x; - geometry->top = wmPtr->y; - geometry->right = wmPtr->x + winPtr->changes.width; - geometry->bottom = wmPtr->y + winPtr->changes.height; -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXResizable -- - * - * This function determines if the passed in window is part of a toplevel - * window that is resizable. If the window is resizable in the x, y or - * both directions, true is returned. - * - * Results: - * True if resizable, false otherwise. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TkMacOSXResizable( - TkWindow *winPtr) /* Tk window or NULL. */ -{ - WmInfo *wmPtr; - - if (winPtr == NULL) { - return false; - } - while (winPtr->wmInfoPtr == NULL) { - winPtr = winPtr->parentPtr; - } - - wmPtr = winPtr->wmInfoPtr; - if ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) && - (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE)) { - return false; - } else { - return true; - } -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXGrowToplevel -- - * - * The function is invoked when the user clicks in the grow region of a - * Tk window. The function will handle the dragging procedure and not - * return until completed. Finally, the function may place information - * Tk's event queue is the window was resized. - * - * Results: - * True if events were placed on event queue, false otherwise. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TkMacOSXGrowToplevel( - void *whichWindow, - XPoint s) -{ - Point start = {s.y, s.x}; - Point where = start; - TkDisplay *dispPtr; - Rect portRect; - CGrafPtr destPort = GetWindowPort(whichWindow); - - QDGlobalToLocalPoint(destPort, &where); - GetPortBounds(destPort, &portRect); - if (where.h > (portRect.right - 16) && - where.v > (portRect.bottom - 16)) { - Window window; - TkWindow *winPtr; - WmInfo *wmPtr; - int minWidth, minHeight, maxWidth, maxHeight; - Rect limits, bounds, *maxBounds; - Boolean resizeResult; - - window = TkMacOSXGetXWindow(whichWindow); - dispPtr = TkGetDisplayList(); - winPtr = (TkWindow *) Tk_IdToWindow(dispPtr->display, window); - wmPtr = winPtr->wmInfoPtr; - maxBounds = (Rect*)(dispPtr->display->screens->ext_data); - - if ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) && - (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE)) { - return false; - } - GetMinSize(winPtr, &minWidth, &minHeight); - GetMaxSize(winPtr, &maxWidth, &maxHeight); - if (wmPtr->gridWin != NULL) { - int base = winPtr->reqWidth - (wmPtr->reqGridWidth - * wmPtr->widthInc); - - if (base < 0) { - base = 0; - } - limits.left = base + (minWidth * wmPtr->widthInc); - limits.right = base + (maxWidth * wmPtr->widthInc); - base = winPtr->reqHeight - (wmPtr->reqGridHeight - * wmPtr->heightInc); - if (base < 0) { - base = 0; - } - limits.top = base + (minHeight * wmPtr->heightInc); - limits.bottom = base + (maxHeight * wmPtr->heightInc); - } else { - limits.left = minWidth; - limits.right = maxWidth; - limits.top = minHeight; - limits.bottom = maxHeight; - } - if (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) { - limits.left = limits.right = winPtr->changes.width; - } - if (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) { - limits.top = limits.bottom = winPtr->changes.height; - } - if (PtInRect(start, maxBounds)) { - Rect strBounds, strWidths, limitBounds; - - ChkErr(GetWindowBounds, whichWindow, kWindowStructureRgn, - &strBounds); - ChkErr(GetWindowStructureWidths, whichWindow, &strWidths); - - limitBounds.left = limits.left + (strBounds.left + strWidths.left); - limitBounds.right = limits.right + - (strBounds.left + strWidths.left + strWidths.right); - limitBounds.top = limits.top + (strBounds.top + strWidths.top); - limitBounds.bottom = limits.bottom + - (strBounds.top + strWidths.top + strWidths.bottom); - if (limitBounds.left < maxBounds->left) { - limitBounds.left = maxBounds->left; - } - if (limitBounds.right > maxBounds->right) { - limitBounds.right = maxBounds->right; - } - if (limitBounds.top < maxBounds->top) { - limitBounds.top = maxBounds->top; - } - if (limitBounds.bottom > maxBounds->bottom) { - limitBounds.bottom = maxBounds->bottom; - } - limits.left = limitBounds.left - (strBounds.left + strWidths.left); - limits.right = limitBounds.right - - (strBounds.left + strWidths.left + strWidths.right); - limits.top = limitBounds.top - (strBounds.top + strWidths.top); - limits.bottom = limitBounds.bottom - - (strBounds.top + strWidths.top + strWidths.bottom); - } - TkMacOSXTrackingLoop(1); - resizeResult = ResizeWindow(whichWindow, start, &limits, &bounds); - TkMacOSXTrackingLoop(0); - if (resizeResult) { - return true; - } - } - return false; -} - -/* - *---------------------------------------------------------------------- - * - * TkSetWMName -- - * - * Set the title for a toplevel window. If the window is embedded, do not - * change the window title. - * - * Results: - * None. - * - * Side effects: - * The title of the window is changed. - * - *---------------------------------------------------------------------- - */ - -void -TkSetWMName( - TkWindow *winPtr, - Tk_Uid titleUid) -{ - CFStringRef title; - - if (Tk_IsEmbedded(winPtr)) { - return; - } - - title = CFStringCreateWithBytes(NULL, (const unsigned char *) titleUid, - strlen(titleUid), kCFStringEncodingUTF8, false); - if (title) { - WindowRef macWin = TkMacOSXDrawableWindow(winPtr->window); - - SetWindowTitleWithCFString(macWin, title); - CFRelease(title); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkGetTransientMaster -- - * - * If the passed window has the TRANSIENT_FOR property set this will - * return the master window. Otherwise it will return None. - * - * Results: - * The master window or None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -Window -TkGetTransientMaster( - TkWindow *winPtr) -{ - if (winPtr->wmInfoPtr != NULL) { - return winPtr->wmInfoPtr->master; - } - return None; -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXGetXWindow -- - * - * Returns the X window Id associated with the given WindowRef. - * - * Results: - * The window id is returned. None is returned if not a Tk window. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -Window -TkMacOSXGetXWindow( - void *macWinPtr) -{ - Tcl_HashEntry *hPtr; - - if ((macWinPtr == NULL) || !windowHashInit) { - return None; - } - hPtr = Tcl_FindHashEntry(&windowTable, (char *) macWinPtr); - if (hPtr == NULL) { - return None; - } - return (Window) Tcl_GetHashValue(hPtr); -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXIsWindowZoomed -- - * - * Ask Carbon if the given window is in the zoomed out state. Because - * dragging & growing a window can change the Carbon zoom state, we - * cannot rely on wmInfoPtr->hints.initial_state for this information. - * - * Results: - * True if window is zoomed out, false otherwise. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -MODULE_SCOPE int -TkMacOSXIsWindowZoomed( - TkWindow *winPtr) -{ - WmInfo *wmPtr = winPtr->wmInfoPtr; - int maxWidth, maxHeight; - Point idealSize; - - if ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) && - (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE)) { - return false; - } - GetMaxSize(winPtr, &maxWidth, &maxHeight); - if (wmPtr->gridWin != NULL) { - int base = winPtr->reqWidth - (wmPtr->reqGridWidth * wmPtr->widthInc); - - if (base < 0) { - base = 0; - } - maxWidth = base + (maxWidth * wmPtr->widthInc); - base = winPtr->reqHeight - (wmPtr->reqGridHeight * wmPtr->heightInc); - if (base < 0) { - base = 0; - } - maxHeight = base + (maxHeight * wmPtr->heightInc); - } - if (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) { - idealSize.h = winPtr->changes.width; - } else { - idealSize.h = maxWidth; - } - if (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) { - idealSize.v = winPtr->changes.height; - } else { - idealSize.v = maxHeight; - } - - return IsWindowInStandardState(TkMacOSXDrawableWindow(winPtr->window), - &idealSize, NULL); -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXZoomToplevel -- - * - * The function is invoked when the user clicks in the zoom region of a - * Tk window or when the window state is set/unset to "zoomed" manually. - * If the window is to be zoomed (in or out), the window size is changed - * and events are generated to let Tk know what happened. - * - * Results: - * True if events were placed on event queue, false otherwise. - * - * Side effects: - * The window may be resized & events placed on Tk's queue. - * - *---------------------------------------------------------------------- - */ - -int -TkMacOSXZoomToplevel( - void *whichWindow, /* The Macintosh window to zoom. */ - short zoomPart) /* Either inZoomIn or inZoomOut */ -{ - Window window; - TkDisplay *dispPtr; - TkWindow *winPtr; - WmInfo *wmPtr; - Point idealSize; - int maxWidth, maxHeight; - OSStatus err; - - window = TkMacOSXGetXWindow(whichWindow); - dispPtr = TkGetDisplayList(); - winPtr = (TkWindow *) Tk_IdToWindow(dispPtr->display, window); - wmPtr = winPtr->wmInfoPtr; - - if ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) && - (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE)) { - return false; - } - GetMaxSize(winPtr, &maxWidth, &maxHeight); - if (wmPtr->gridWin != NULL) { - int base = winPtr->reqWidth - (wmPtr->reqGridWidth * wmPtr->widthInc); - - if (base < 0) { - base = 0; - } - maxWidth = base + (maxWidth * wmPtr->widthInc); - base = winPtr->reqHeight - (wmPtr->reqGridHeight * wmPtr->heightInc); - if (base < 0) { - base = 0; - } - maxHeight = base + (maxHeight * wmPtr->heightInc); - } - if (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) { - idealSize.h = winPtr->changes.width; - } else { - idealSize.h = maxWidth; - } - if (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) { - idealSize.v = winPtr->changes.height; - } else { - idealSize.v = maxHeight; - } - - /* - * Do nothing if already in desired zoom state. - */ - - if (!IsWindowInStandardState(whichWindow, &idealSize, NULL) == - (zoomPart == inZoomIn)) { - return false; - } - - err = ChkErr(ZoomWindowIdeal, whichWindow, zoomPart, &idealSize); - if (err != noErr) { - return false; - } - wmPtr->hints.initial_state = - (zoomPart == inZoomIn ? NormalState : ZoomState); - return true; -} - -/* - *---------------------------------------------------------------------- - * - * TkUnsupported1Cmd -- - * - * This procedure is invoked to process the - * "::tk::unsupported::MacWindowStyle" Tcl command. This command allows - * you to set the style of decoration for a Macintosh window. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * Changes the style of a new Mac window. - * - *---------------------------------------------------------------------- - */ - -/* ARGSUSED */ -int -TkUnsupported1ObjCmd( - ClientData clientData, /* Main window associated with interpreter. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - static const char *const subcmds[] = { - "style", NULL - }; - enum SubCmds { - TKMWS_STYLE - }; - Tk_Window tkwin = clientData; - TkWindow *winPtr; - int index; - - if (objc < 3) { - Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?"); - return TCL_ERROR; - } - - winPtr = (TkWindow *) - Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin); - if (winPtr == NULL) { - return TCL_ERROR; - } - if (!(winPtr->flags & TK_TOP_LEVEL)) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "window \"%s\" isn't a top-level window", winPtr->pathName)); - Tcl_SetErrorCode(interp, "TK", "WINDOWSTYLE", "TOPLEVEL", NULL); - return TCL_ERROR; - } - - if (Tcl_GetIndexFromObj(interp, objv[1], subcmds, "option", 0, - &index) != TCL_OK) { - return TCL_ERROR; - } - if (((enum SubCmds) index) == TKMWS_STYLE) { - if ((objc < 3) || (objc > 5)) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?class attributes?"); - return TCL_ERROR; - } - return WmWinStyle(interp, winPtr, objc, objv); - } - /* won't be reached */ - return TCL_ERROR; -} - -/* - *---------------------------------------------------------------------- - * - * WmWinStyle -- - * - * This procedure is invoked to process the - * "::tk::unsupported::MacWindowStyle style" subcommand. This command - * allows you to set the style of decoration for a Macintosh window. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * Changes the style of a new Mac window. - * - *---------------------------------------------------------------------- - */ - -static int -WmWinStyle( - Tcl_Interp *interp, /* Current interpreter. */ - TkWindow *winPtr, /* Window to be manipulated. */ - int objc, /* Number of arguments. */ - Tcl_Obj * const objv[]) /* Argument objects. */ -{ - struct StrIntMap { - const char *strValue; - UInt32 intValue; - }; - static const struct StrIntMap styleMap[] = { - { "documentProc", documentProc }, - { "noGrowDocProc", documentProc }, - { "dBoxProc", dBoxProc }, - { "plainDBox", plainDBox }, - { "altDBoxProc", altDBoxProc }, - { "movableDBoxProc", movableDBoxProc }, - { "zoomDocProc", zoomDocProc }, - { "zoomNoGrow", zoomNoGrow }, - { "floatProc", floatGrowProc }, - { "floatGrowProc", floatGrowProc }, - { "floatZoomProc", floatZoomGrowProc }, - { "floatZoomGrowProc", floatZoomGrowProc }, - { "floatSideProc", floatSideGrowProc }, - { "floatSideGrowProc", floatSideGrowProc }, - { "floatSideZoomProc", floatSideZoomGrowProc }, - { "floatSideZoomGrowProc", floatSideZoomGrowProc }, - { NULL, 0 } - }; - static const struct StrIntMap classMap[] = { - { "alert", kAlertWindowClass }, - { "moveableAlert", kMovableAlertWindowClass }, - { "modal", kModalWindowClass }, - { "moveableModal", kMovableModalWindowClass }, - { "floating", kFloatingWindowClass }, - { "document", kDocumentWindowClass }, - { "utility", kUtilityWindowClass }, - { "help", kHelpWindowClass }, - { "sheet", kSheetWindowClass }, - { "toolbar", kToolbarWindowClass }, - { "plain", kPlainWindowClass }, - { "overlay", kOverlayWindowClass }, - { "sheetAlert", kSheetAlertWindowClass }, - { "altPlain", kAltPlainWindowClass }, - { "simple", kSimpleWindowClass }, - { "drawer", kDrawerWindowClass }, - { NULL, 0 } - }; - static const struct StrIntMap compositeAttrMap[] = { - { "none", kWindowNoAttributes }, - { "standardDocument", kWindowStandardDocumentAttributes }, - { "standardFloating", kWindowStandardFloatingAttributes }, - { "fullZoom", kWindowFullZoomAttribute }, - { NULL, 0 } - }; - static const struct StrIntMap attrMap[] = { - { "closeBox", kWindowCloseBoxAttribute }, - { "horizontalZoom", kWindowHorizontalZoomAttribute }, - { "verticalZoom", kWindowVerticalZoomAttribute }, - { "collapseBox", kWindowCollapseBoxAttribute }, - { "resizable", kWindowResizableAttribute }, - { "sideTitlebar", kWindowSideTitlebarAttribute }, - { "toolbarButton", kWindowToolbarButtonAttribute }, - { "unifiedTitleAndToolbar", kWindowUnifiedTitleAndToolbarAttribute }, - { "metal", kWindowMetalAttribute }, - { "noTitleBar", kWindowNoTitleBarAttribute }, - { "texturedSquareCorners", kWindowTexturedSquareCornersAttribute }, - { "metalNoContentSeparator", kWindowMetalNoContentSeparatorAttribute }, - { "doesNotCycle", kWindowDoesNotCycleAttribute }, - { "noUpdates", kWindowNoUpdatesAttribute }, - { "noActivates", kWindowNoActivatesAttribute }, - { "opaqueForEvents", kWindowOpaqueForEventsAttribute }, - { "noShadow", kWindowNoShadowAttribute }, - { "hideOnSuspend", kWindowHideOnSuspendAttribute }, - { "hideOnFullScreen", kWindowHideOnFullScreenAttribute }, - { "inWindowMenu", kWindowInWindowMenuAttribute }, - { "liveResize", kWindowLiveResizeAttribute }, - { "ignoreClicks", kWindowIgnoreClicksAttribute }, - { "noConstrain", kWindowNoConstrainAttribute }, - { NULL, 0 } - }; - int index, i; - WmInfo *wmPtr = winPtr->wmInfoPtr; - - if (objc == 3) { - if (wmPtr->style != -1) { - for (i = 0; styleMap[i].strValue != NULL; i++) { - if (wmPtr->style == (short) styleMap[i].intValue) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj(styleMap[i].strValue, -1)); - return TCL_OK; - } - } - Tcl_Panic("invalid style"); - } else { - Tcl_Obj *attributeList, *newResult = NULL; - WindowAttributes attributes; - - for (i = 0; classMap[i].strValue != NULL; i++) { - if (wmPtr->macClass == classMap[i].intValue) { - newResult = Tcl_NewStringObj(classMap[i].strValue, -1); - break; - } - } - if (newResult == NULL) { - Tcl_Panic("invalid class"); - } - - attributeList = Tcl_NewObj(); - attributes = wmPtr->attributes; - - for (i = 0; compositeAttrMap[i].strValue != NULL; i++) { - UInt32 intValue = compositeAttrMap[i].intValue; - - if (intValue && (attributes & intValue) == intValue) { - Tcl_ListObjAppendElement(NULL, attributeList, - Tcl_NewStringObj(compositeAttrMap[i].strValue, - -1)); - attributes &= ~intValue; - break; - } - } - for (i = 0; attrMap[i].strValue != NULL; i++) { - if (attributes & attrMap[i].intValue) { - Tcl_ListObjAppendElement(NULL, attributeList, - Tcl_NewStringObj(attrMap[i].strValue, -1)); - } - } - Tcl_ListObjAppendElement(NULL, newResult, attributeList); - Tcl_SetObjResult(interp, newResult); - } - } else if (objc == 4) { - if (Tcl_GetIndexFromObjStruct(interp, objv[3], styleMap, - sizeof(struct StrIntMap), "style", 0, &index) != TCL_OK) { - return TCL_ERROR; - } - wmPtr->style = styleMap[index].intValue; - } else if (objc == 5) { - int attrObjc; - Tcl_Obj **attrObjv = NULL; - WindowClass oldClass = wmPtr->macClass; - WindowAttributes oldAttributes = wmPtr->attributes; - - if (Tcl_GetIndexFromObjStruct(interp, objv[3], classMap, - sizeof(struct StrIntMap), "class", 0, &index) != TCL_OK) { - goto badClassAttrs; - } - wmPtr->macClass = classMap[index].intValue; - if (!IsValidWindowClass(wmPtr->macClass)) { - goto badClassAttrs; - } - if (Tcl_ListObjGetElements(interp, objv[4], &attrObjc, &attrObjv) - != TCL_OK) { - goto badClassAttrs; - } - wmPtr->attributes = kWindowNoAttributes; - for (i = 0; i < attrObjc; i++) { - if (Tcl_GetIndexFromObjStruct(interp, attrObjv[i], - compositeAttrMap, sizeof(struct StrIntMap), - "attribute", 0, &index) == TCL_OK) { - wmPtr->attributes |= compositeAttrMap[index].intValue; - } else if (Tcl_GetIndexFromObjStruct(interp, attrObjv[i], - attrMap, sizeof(struct StrIntMap), - "attribute", 0, &index) == TCL_OK) { - Tcl_ResetResult(interp); - wmPtr->attributes |= attrMap[index].intValue; - } else { - goto badClassAttrs; - } - } - ApplyWindowClassAttributeChanges(winPtr, NULL, oldClass, oldAttributes, - 0); - wmPtr->style = -1; - return TCL_OK; - - badClassAttrs: - wmPtr->macClass = oldClass; - wmPtr->attributes = oldAttributes; - return TCL_ERROR; - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * TkpMakeMenuWindow -- - * - * Configure the window to be either a undecorated pull-down (or pop-up) - * menu, or as a toplevel floating menu (palette). - * - * Results: - * None. - * - * Side effects: - * Changes the style bit used to create a new Mac toplevel. - * - *---------------------------------------------------------------------- - */ - -void -TkpMakeMenuWindow( - Tk_Window tkwin, /* New window. */ - int transient) /* 1 means menu is only posted briefly as a - * popup or pulldown or cascade. 0 means menu - * is always visible, e.g. as a floating - * menu. */ -{ - TkWindow *winPtr = (TkWindow *) tkwin; - - if (transient) { - winPtr->wmInfoPtr->macClass = kSimpleWindowClass; - winPtr->wmInfoPtr->attributes = kWindowNoActivatesAttribute; - } else { - winPtr->wmInfoPtr->macClass = kFloatingWindowClass; - winPtr->wmInfoPtr->attributes = kWindowStandardFloatingAttributes; - winPtr->wmInfoPtr->flags |= WM_WIDTH_NOT_RESIZABLE; - winPtr->wmInfoPtr->flags |= WM_HEIGHT_NOT_RESIZABLE; - } -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXMakeRealWindowExist -- - * - * This function finally creates the real Macintosh window that the Mac - * actually understands. - * - * Results: - * None. - * - * Side effects: - * A new Macintosh toplevel is created. - * - *---------------------------------------------------------------------- - */ - -void -TkMacOSXMakeRealWindowExist( - TkWindow *winPtr) /* Tk window. */ -{ - WmInfo *wmPtr = winPtr->wmInfoPtr; - WindowRef newWindow = NULL; - ControlRef rootControl = NULL; - MacDrawable *macWin; - Rect initialBounds = {42, 0, 43, 1}, geometry, strWidths; - short structureW, structureH; - TkMacOSXWindowList *listPtr; - OSStatus err; - - if (TkMacOSXHostToplevelExists(winPtr)) { - return; - } - - macWin = (MacDrawable *) winPtr->window; - - /* - * If this is embedded, make sure its container's toplevel exists, - * then return... - */ - - if (Tk_IsEmbedded(winPtr)) { - TkWindow *contWinPtr = TkpGetOtherWindow(winPtr); - - if (contWinPtr != NULL) { - TkMacOSXMakeRealWindowExist( - contWinPtr->privatePtr->toplevel->winPtr); - macWin->flags |= TK_HOST_EXISTS; - return; - } - - if (tkMacOSXEmbedHandler == NULL) { - Tcl_Panic("TkMacOSXMakeRealWindowExist could not find container"); - } - if (tkMacOSXEmbedHandler->containerExistProc && - tkMacOSXEmbedHandler->containerExistProc((Tk_Window) winPtr) - != TCL_OK) { - Tcl_Panic("ContainerExistProc could not make container"); - } - return; - - /* - * TODO: Here we should handle out of process embedding. - */ - } - - if (wmPtr->style == -1) { - if (!IsValidWindowClass(wmPtr->macClass)) { - TkMacOSXDbgMsg("Invalid window class: %ld", wmPtr->macClass); - wmPtr->macClass = kPlainWindowClass; - } - wmPtr->attributes = (wmPtr->attributes | kWindowAsyncDragAttribute) & - GetAvailableWindowAttributes(wmPtr->macClass); - err = ChkErr(CreateNewWindow, wmPtr->macClass, wmPtr->attributes, - &initialBounds, &newWindow); - if (err != noErr) { - newWindow = NULL; - } - } else { - TkMacOSXDbgMsg("Window creation via NewCWindow API is deprecated, " - "use a window class instead of style %d", wmPtr->style); - newWindow = NewCWindow(NULL, &initialBounds, "\p", false, - wmPtr->style, (WindowRef) -1, true, 0); - } - - if (newWindow == NULL) { - Tcl_Panic("couldn't allocate new Mac window"); - } - - ChkErr(GetWindowStructureWidths, newWindow, &strWidths); - if (wmPtr->macClass == kFloatingWindowClass) { - /* - * Workaround GetWindowStructureWidths() Carbon bug: - */ - - strWidths.top = 16; - } - wmPtr->xInParent = strWidths.left; - wmPtr->yInParent = strWidths.top; - structureW = strWidths.left + strWidths.right; - structureH = strWidths.top + strWidths.bottom; - wmPtr->parentWidth = winPtr->changes.width + structureW; - wmPtr->parentHeight = winPtr->changes.height + structureH; - InitialWindowBounds(winPtr, newWindow, &geometry); - geometry.right += structureW; - geometry.bottom += structureH; - ChkErr(SetWindowBounds, newWindow, kWindowStructureRgn, &geometry); - - TkMacOSXInstallWindowCarbonEventHandler(NULL, newWindow); - if (ChkErr(CreateRootControl, newWindow, &rootControl) != noErr ) { - Tcl_Panic("couldn't create root control for new Mac window"); - } - if (wmPtr->attributes & kWindowResizableAttribute) { - HIViewRef growBoxView; - - err = HIViewFindByID(HIViewGetRoot(newWindow), - kHIViewWindowGrowBoxID, &growBoxView); - if (err == noErr && !HIGrowBoxViewIsTransparent(growBoxView)) { - ChkErr(HIGrowBoxViewSetTransparent, growBoxView, true); - } - } - - /* - * Add this window to the list of toplevel windows. - */ - - listPtr = ckalloc(sizeof(TkMacOSXWindowList)); - listPtr->nextPtr = tkMacOSXWindowListPtr; - listPtr->winPtr = winPtr; - tkMacOSXWindowListPtr = listPtr; - - macWin->grafPtr = GetWindowPort(newWindow); - macWin->rootControl = rootControl; - - if (wmPtr->master != None || winPtr->atts.override_redirect) { - ApplyMasterOverrideChanges(winPtr, newWindow); - } - SetWindowModified(newWindow, false); - TkMacOSXRegisterOffScreenWindow((Window) macWin, (GWorldPtr) newWindow); - macWin->flags |= TK_HOST_EXISTS; - ChkErr(GetWindowClass, newWindow, &(wmPtr->macClass)); - ChkErr(GetWindowAttributes, newWindow, &(wmPtr->attributes)); - -#ifdef TK_MAC_DEBUG_WINDOWS - TkMacOSXInitNamedDebugSymbol(HIToolbox, void, DebugPrintWindow, WindowRef); - if (DebugPrintWindow) { - DebugPrintWindow(newWindow); - } -#endif /* TK_MAC_DEBUG_WINDOWS */ -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXRegisterOffScreenWindow -- - * - * This function adds the passed in Off Screen Port to the hash table - * that maps Mac windows to root X windows. - * - * Results: - * None. - * - * Side effects: - * An entry is added to the windowTable hash table. - * - *---------------------------------------------------------------------- - */ - -void -TkMacOSXRegisterOffScreenWindow( - Window window, /* Window structure. */ - void *portPtr) /* Pointer to a Mac GWorld. */ -{ - Tcl_HashEntry *valueHashPtr; - int isNew; - - if (!windowHashInit) { - Tcl_InitHashTable(&windowTable, TCL_ONE_WORD_KEYS); - windowHashInit = true; - } - valueHashPtr = Tcl_CreateHashEntry(&windowTable, (char *) portPtr, &isNew); - if (!isNew) { - Tcl_Panic("Same macintosh window allocated twice!"); - } - Tcl_SetHashValue(valueHashPtr, window); -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXUnregisterMacWindow -- - * - * Given a macintosh port window, this function removes the association - * between this window and the root X window that Tk cares about. - * - * Results: - * None. - * - * Side effects: - * An entry is removed from the windowTable hash table. - * - *---------------------------------------------------------------------- - */ - -void -TkMacOSXUnregisterMacWindow( - void *macWinPtr) /* Reference to a Mac Window */ -{ - Tcl_HashEntry *entryPtr; - - if (!windowHashInit) { - Tcl_Panic("TkMacOSXUnregisterMacWindow: unmapping before inited"); - } - entryPtr = Tcl_FindHashEntry(&windowTable,(char *) macWinPtr); - if (!entryPtr) { - TkMacOSXDbgMsg("Failed to find window %08x", (int) macWinPtr); - } else { - Tcl_DeleteHashEntry(entryPtr); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXSetScrollbarGrow -- - * - * Sets a flag for a toplevel window indicating that the passed Tk - * scrollbar window will display the grow region for the toplevel window. - * - * Results: - * None. - * - * Side effects: - * A flag is set int windows toplevel parent. - * - *---------------------------------------------------------------------- - */ - -void -TkMacOSXSetScrollbarGrow( - TkWindow *winPtr, /* Tk scrollbar window. */ - int flag) /* Boolean value true or false. */ -{ - if (flag) { - winPtr->privatePtr->toplevel->flags |= TK_SCROLLBAR_GROW; - winPtr->privatePtr->toplevel->winPtr->wmInfoPtr->scrollWinPtr = winPtr; - } else if (winPtr->privatePtr->toplevel->winPtr->wmInfoPtr->scrollWinPtr - == winPtr) { - winPtr->privatePtr->toplevel->flags &= ~TK_SCROLLBAR_GROW; - winPtr->privatePtr->toplevel->winPtr->wmInfoPtr->scrollWinPtr = NULL; - } -} - -/* - *---------------------------------------------------------------------- - * - * TkWmFocusToplevel -- - * - * This is a utility procedure invoked by focus-management code. It - * exists because of the extra wrapper windows that exist under Unix; its - * job is to map from wrapper windows to the corresponding toplevel - * windows. On PCs and Macs there are no wrapper windows so no mapping is - * necessary; this procedure just determines whether a window is a - * toplevel or not. - * - * Results: - * If winPtr is a toplevel window, returns the pointer to the window; - * otherwise returns NULL. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -TkWindow * -TkWmFocusToplevel( - TkWindow *winPtr) /* Window that received a focus-related - * event. */ -{ - if (!(winPtr->flags & TK_TOP_LEVEL)) { - return NULL; - } - return winPtr; -} - -/* - *---------------------------------------------------------------------- - * - * TkpGetWrapperWindow -- - * - * This is a utility procedure invoked by focus-management code. It maps - * to the wrapper for a top-level, which is just the same as the - * top-level on Macs and PCs. - * - * Results: - * If winPtr is a toplevel window, returns the pointer to the window; - * otherwise returns NULL. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -TkWindow * -TkpGetWrapperWindow( - TkWindow *winPtr) /* Window that received a focus-related - * event. */ -{ - if (!(winPtr->flags & TK_TOP_LEVEL)) { - return NULL; - } - return winPtr; -} - -/* - *---------------------------------------------------------------------- - * - * TkpWmSetState -- - * - * Sets the window manager state for the wrapper window of a given - * toplevel window. - * - * Results: - * None. - * - * Side effects: - * May maximize, minimize, restore, or withdraw a window. - * - *---------------------------------------------------------------------- - */ - -void -TkpWmSetState( - TkWindow *winPtr, /* Toplevel window to operate on. */ - int state) /* One of IconicState, ZoomState, NormalState, - * or WithdrawnState. */ -{ - WmInfo *wmPtr = winPtr->wmInfoPtr; - WindowRef macWin; - - wmPtr->hints.initial_state = state; - if (wmPtr->flags & WM_NEVER_MAPPED) { - return; - } - - macWin = TkMacOSXDrawableWindow(winPtr->window); - - if (state == WithdrawnState) { - Tk_UnmapWindow((Tk_Window) winPtr); - } else if (state == IconicState) { - /* - * The window always gets unmapped. If we can show the icon version of - * the window we also collapse it. - */ - - if (IsWindowCollapsable(macWin) && !IsWindowCollapsed(macWin)) { - CollapseWindow(macWin, true); - } - Tk_UnmapWindow((Tk_Window) winPtr); - } else if (state == NormalState) { - Tk_MapWindow((Tk_Window) winPtr); - if (IsWindowCollapsable(macWin) && IsWindowCollapsed(macWin)) { - CollapseWindow(macWin, false); - } - TkMacOSXZoomToplevel(macWin, inZoomIn); - } else if (state == ZoomState) { - Tk_MapWindow((Tk_Window) winPtr); - if (IsWindowCollapsable(macWin) && IsWindowCollapsed(macWin)) { - CollapseWindow(macWin, false); - } - TkMacOSXZoomToplevel(macWin, inZoomOut); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkpIsWindowFloating -- - * - * Returns 1 if a window is floating, 0 otherwise. - * - * Results: - * 1 or 0 depending on window's floating attribute. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TkpIsWindowFloating( - void *wRef) -{ - WindowClass class; - - if (wRef == NULL) { - return 0; - } - - GetWindowClass(wRef, &class); - return (class == kFloatingWindowClass); -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXWindowClass -- - * - * Returns OS X window class of window - * - * Results: - * 1 or 0 depending on window's floating attribute. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -MODULE_SCOPE WindowClass -TkMacOSXWindowClass( - TkWindow *winPtr) -{ - return winPtr->wmInfoPtr->macClass; -} - -/* - *-------------------------------------------------------------- - * - * TkMacOSXWindowOffset -- - * - * Determines the x and y offset from the orgin of the toplevel window - * dressing (the structure region, i.e. title bar) and the orgin of the - * content area. - * - * Results: - * The x & y offset in pixels. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkMacOSXWindowOffset( - void *wRef, - int *xOffset, - int *yOffset) -{ - Window window; - TkDisplay *dispPtr; - TkWindow *winPtr; - - window = TkMacOSXGetXWindow(wRef); - dispPtr = TkGetDisplayList(); - winPtr = (TkWindow *) Tk_IdToWindow(dispPtr->display, window); - *xOffset = winPtr->wmInfoPtr->xInParent; - *yOffset = winPtr->wmInfoPtr->yInParent; -} - -/* - *---------------------------------------------------------------------- - * - * TkpGetMS -- - * - * Return a relative time in milliseconds. It doesn't matter when the - * epoch was. - * - * Results: - * Number of milliseconds. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -unsigned long -TkpGetMS(void) -{ - Tcl_Time now; - - Tcl_GetTime(&now); - return (long) now.sec * 1000 + now.usec / 1000; -} - -/* - *---------------------------------------------------------------------- - * - * XSetInputFocus -- - * - * Change the focus window for the application. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -XSetInputFocus( - Display* display, - Window focus, - int revert_to, - Time time) -{ - /* - * Don't need to do a thing. Tk manages the focus for us. - */ -} - -/* - *---------------------------------------------------------------------- - * - * TkpChangeFocus -- - * - * This procedure is a stub on the Mac because we always own the focus if - * we are a front most application. - * - * Results: - * The return value is the serial number of the command that changed the - * focus. It may be needed by the caller to filter out focus change - * events that were queued before the command. If the procedure doesn't - * actually change the focus then it returns 0. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TkpChangeFocus( - TkWindow *winPtr, /* Window that is to receive the X focus. */ - int force) /* Non-zero means claim the focus even if it - * didn't originally belong to topLevelPtr's - * application. */ -{ - /* - * We don't really need to do anything on the Mac. Tk will keep all this - * state for us. - */ - - if (winPtr->atts.override_redirect) { - return 0; - } - - /* - * Remember the current serial number for the X server and issue a dummy - * server request. This marks the position at which we changed the focus, - * so we can distinguish FocusIn and FocusOut events on either side of the - * mark. - */ - - return NextRequest(winPtr->display); -} - -/* - *---------------------------------------------------------------------- - * - * WmStackorderToplevelWrapperMap -- - * - * This procedure will create a table that maps the reparent wrapper X id - * for a toplevel to the TkWindow structure that is wraps. Tk keeps track - * of a mapping from the window X id to the TkWindow structure but that - * does us no good here since we only get the X id of the wrapper window. - * Only those toplevel windows that are mapped have a position in the - * stacking order. - * - * Results: - * None. - * - * Side effects: - * Adds entries to the passed hashtable. - * - *---------------------------------------------------------------------- - */ - -static void -WmStackorderToplevelWrapperMap( - TkWindow *winPtr, /* TkWindow to recurse on */ - Display *display, /* X display of parent window */ - Tcl_HashTable *table) /* Maps mac window to TkWindow */ -{ - TkWindow *childPtr; - Tcl_HashEntry *hPtr; - WindowRef macWindow; - int newEntry; - - if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr) - && (winPtr->display == display)) { - macWindow = TkMacOSXDrawableWindow(winPtr->window); - - hPtr = Tcl_CreateHashEntry(table, - (const char *) macWindow, &newEntry); - Tcl_SetHashValue(hPtr, winPtr); - } - - for (childPtr = winPtr->childList; childPtr != NULL; - childPtr = childPtr->nextPtr) { - WmStackorderToplevelWrapperMap(childPtr, display, table); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkWmStackorderToplevel -- - * - * This procedure returns the stack order of toplevel windows. - * - * Results: - * An array of pointers to tk window objects in stacking order or else - * NULL if there was an error. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -TkWindow ** -TkWmStackorderToplevel( - TkWindow *parentPtr) /* Parent toplevel window. */ -{ - WindowRef frontWindow; - TkWindow *childWinPtr, **windows, **windowPtr; - Tcl_HashTable table; - Tcl_HashEntry *hPtr; - Tcl_HashSearch search; - - /* - * Map mac windows to a TkWindow of the wrapped toplevel. - */ - - Tcl_InitHashTable(&table, TCL_ONE_WORD_KEYS); - WmStackorderToplevelWrapperMap(parentPtr, parentPtr->display, &table); - - windows = ckalloc((table.numEntries+1) * sizeof(TkWindow *)); - - /* - * Special cases: If zero or one toplevels were mapped there is no need to - * enumerate Windows. - */ - - switch (table.numEntries) { - case 0: - windows[0] = NULL; - goto done; - case 1: - hPtr = Tcl_FirstHashEntry(&table, &search); - windows[0] = Tcl_GetHashValue(hPtr); - windows[1] = NULL; - goto done; - } - - frontWindow = GetFrontWindowOfClass(kAllWindowClasses, false); - if (frontWindow == NULL) { - ckfree(windows); - windows = NULL; - } else { - windowPtr = windows + table.numEntries; - *windowPtr-- = NULL; - while (frontWindow != NULL) { - hPtr = Tcl_FindHashEntry(&table, (char *) frontWindow); - if (hPtr != NULL) { - childWinPtr = Tcl_GetHashValue(hPtr); - *windowPtr-- = childWinPtr; - } - frontWindow = GetNextWindow(frontWindow); - } - if (windowPtr != windows-1) { - Tcl_Panic("num matched toplevel windows does not equal num " - "children"); - } - } - - done: - Tcl_DeleteHashTable(&table); - return windows; -} - -/* - *---------------------------------------------------------------------- - * - * ApplyWindowClassAttributeChanges -- - * - * This procedure applies carbon window class and attribute changes. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -ApplyWindowClassAttributeChanges( - TkWindow *winPtr, - WindowRef macWindow, - WindowClass oldClass, - WindowAttributes oldAttributes, - int create) -{ - WmInfo *wmPtr = winPtr->wmInfoPtr; - WindowAttributes newAttributes = wmPtr->attributes | - kWindowAsyncDragAttribute; - - if (wmPtr->macClass != oldClass || newAttributes != oldAttributes) { - Rect strWidths; - - if (!macWindow) { - if (winPtr->window == None) { - if (create) { - Tk_MakeWindowExist((Tk_Window) winPtr); - } else { - return; - } - } - if (!TkMacOSXHostToplevelExists(winPtr)) { - if (create) { - TkMacOSXMakeRealWindowExist(winPtr); - } else { - return; - } - } - macWindow = TkMacOSXDrawableWindow(winPtr->window); - } - if (wmPtr->macClass != oldClass) { - TK_IF_MAC_OS_X_API (4, HIWindowChangeClass, - ChkErr(HIWindowChangeClass, macWindow, wmPtr->macClass); - ) TK_ENDIF - ChkErr(GetWindowClass, macWindow, &(wmPtr->macClass)); - } - if (newAttributes != oldAttributes) { - newAttributes &= GetAvailableWindowAttributes(wmPtr->macClass); - ChkErr(ChangeWindowAttributes, macWindow, - newAttributes & (newAttributes ^ oldAttributes), - oldAttributes & (newAttributes ^ oldAttributes)); - } - ChkErr(GetWindowAttributes, macWindow, &(wmPtr->attributes)); - if ((wmPtr->attributes ^ oldAttributes) & kWindowResizableAttribute) { - if (wmPtr->attributes & kWindowResizableAttribute) { - HIViewRef growBoxView; - OSStatus err = HIViewFindByID(HIViewGetRoot(macWindow), - kHIViewWindowGrowBoxID, &growBoxView); - - if (err == noErr && !HIGrowBoxViewIsTransparent(growBoxView)) { - ChkErr(HIGrowBoxViewSetTransparent, growBoxView, true); - } - } - TkMacOSXInvalClipRgns((Tk_Window) winPtr); - TkMacOSXInvalidateWindow((MacDrawable *) winPtr->window, - TK_PARENT_WINDOW); - } - - /* - * The change of window class/attributes might have changed the window - * structure widths: - */ - - GetWindowStructureWidths(macWindow, &strWidths); - wmPtr->xInParent = strWidths.left; - wmPtr->yInParent = strWidths.top; - wmPtr->parentWidth = winPtr->changes.width + strWidths.left - + strWidths.right; - wmPtr->parentHeight = winPtr->changes.height + strWidths.top - + strWidths.bottom; - } -} - -/* - *---------------------------------------------------------------------- - * - * ApplyMasterOverrideChanges -- - * - * This procedure applies changes to override_redirect or master. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -ApplyMasterOverrideChanges( - TkWindow *winPtr, - WindowRef macWindow) -{ - WmInfo *wmPtr = winPtr->wmInfoPtr; - WindowClass oldClass = wmPtr->macClass; - WindowAttributes oldAttributes = wmPtr->attributes; - - /* - * FIX: We need an UpdateWrapper equivalent to make this 100% correct - */ - - if (winPtr->atts.override_redirect) { - if (oldClass == kDocumentWindowClass) { - wmPtr->macClass = kSimpleWindowClass; - wmPtr->attributes = kWindowNoAttributes; - } - wmPtr->attributes |= kWindowNoActivatesAttribute; - } else { - if (oldClass == kSimpleWindowClass && - oldAttributes == kWindowNoActivatesAttribute) { - wmPtr->macClass = kDocumentWindowClass; - wmPtr->attributes = kWindowStandardDocumentAttributes - | kWindowLiveResizeAttribute; - } - wmPtr->attributes &= ~kWindowNoActivatesAttribute; - } - if (!macWindow && winPtr->window != None && - TkMacOSXHostToplevelExists(winPtr)) { - macWindow = TkMacOSXDrawableWindow(winPtr->window); - } - if (macWindow) { - WindowGroupRef group; - - ApplyWindowClassAttributeChanges(winPtr, macWindow, oldClass, - oldAttributes, 0); - - if (winPtr->atts.override_redirect && wmPtr->master != None) { - wmPtr->flags |= WM_TOPMOST; - } else { - wmPtr->flags &= ~WM_TOPMOST; - } - group = WmGetWindowGroup(winPtr); - if (group && group != GetWindowGroup(macWindow)) { - ChkErr(SetWindowGroup, macWindow, group); - } - } -} - -/* - *---------------------------------------------------------------------- - * - * WmGetWindowGroup -- - * - * Gets the window group a toplevel should be placed in. - * - * Results: - * A WindowGroupRef. - * - * Side effects: - * A transient window group for the master (if any) may be created. - * - *---------------------------------------------------------------------- - */ - -static WindowGroupRef -WmGetWindowGroup( - TkWindow *winPtr) -{ - WmInfo *wmPtr = winPtr->wmInfoPtr; - WindowGroupRef group = NULL; - - if (wmPtr->flags & WM_TOPMOST) { - group = GetWindowGroupOfClass(kUtilityWindowClass); - } else if (wmPtr->master != None) { - TkDisplay *dispPtr = TkGetDisplayList(); - TkWindow *masterWinPtr = (TkWindow *) - Tk_IdToWindow(dispPtr->display, wmPtr->master); - - if (masterWinPtr && masterWinPtr->window != None && - TkMacOSXHostToplevelExists(masterWinPtr)) { - WindowRef masterMacWin = - TkMacOSXDrawableWindow(masterWinPtr->window); - - if (masterMacWin && GetWindowProperty(masterMacWin, 'Tk ', 'TsGp', - sizeof(group), NULL, &group) != noErr) { - ChkErr(CreateWindowGroup, 0, &group); - if (group) { - ChkErr(SetWindowGroupParent, group, - GetWindowGroup(masterMacWin)); - ChkErr(SetWindowGroupOwner, group, masterMacWin); - ChkErr(SetWindowProperty, masterMacWin, 'Tk ', 'TsGp', - sizeof(group), &group); - } - } - } - } - if (!group) { - group = GetWindowGroupOfClass(wmPtr->macClass); - } - return group; -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXMakeFullscreen -- - * - * This procedure sets a fullscreen window to the size of the screen. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TkMacOSXMakeFullscreen( - TkWindow *winPtr, - WindowRef window, - int fullscreen, - Tcl_Interp *interp) -{ - WmInfo *wmPtr = winPtr->wmInfoPtr; - int result = TCL_OK, wasFullscreen = (wmPtr->flags & WM_FULLSCREEN); - - if (fullscreen) { - int screenWidth = WidthOfScreen(Tk_Screen(winPtr)); - int screenHeight = HeightOfScreen(Tk_Screen(winPtr)); - - /* - * Check max width and height if set by the user. - */ - - if ((wmPtr->maxWidth > 0 && wmPtr->maxWidth < screenWidth) - || (wmPtr->maxHeight > 0 && wmPtr->maxHeight < screenHeight)) { - if (interp) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't set fullscreen attribute for \"%s\": max" - " width/height is too small", winPtr->pathName)); - Tcl_SetErrorCode(interp, "TK", "FULLSCREEN", - "CONSTRAINT_FAILURE", NULL); - } - result = TCL_ERROR; - wmPtr->flags &= ~WM_FULLSCREEN; - } else { - Rect bounds, screenBounds = {0, 0, screenHeight, screenWidth}; - - ChkErr(GetWindowBounds, window, kWindowContentRgn, &bounds); - if (!EqualRect(&bounds, &screenBounds)) { - if (!wasFullscreen) { - wmPtr->configX = wmPtr->x; - wmPtr->configY = wmPtr->y; - wmPtr->configAttributes = wmPtr->attributes; - wmPtr->attributes &= ~kWindowResizableAttribute; - ApplyWindowClassAttributeChanges(winPtr, window, - wmPtr->macClass, wmPtr->configAttributes, 0); - } - wmPtr->flags |= WM_SYNC_PENDING; - ChkErr(SetWindowBounds, window, kWindowContentRgn, - &screenBounds); - wmPtr->flags &= ~WM_SYNC_PENDING; - } - wmPtr->flags |= WM_FULLSCREEN; - } - } else { - wmPtr->flags &= ~WM_FULLSCREEN; - } - if (wasFullscreen && !(wmPtr->flags & WM_FULLSCREEN)) { - WindowAttributes oldAttributes = wmPtr->attributes; - Rect bounds = {wmPtr->configY, wmPtr->configX, - wmPtr->configY + wmPtr->yInParent + wmPtr->configHeight, - wmPtr->configX + wmPtr->xInParent + wmPtr->configWidth}; - - wmPtr->attributes |= wmPtr->configAttributes & - kWindowResizableAttribute; - ApplyWindowClassAttributeChanges(winPtr, window, wmPtr->macClass, - oldAttributes, 0); - wmPtr->flags |= WM_SYNC_PENDING; - ChkErr(SetWindowBounds, window, kWindowStructureRgn, &bounds); - wmPtr->flags &= ~WM_SYNC_PENDING; - } - TkMacOSXEnterExitFullscreen(winPtr, IsWindowActive(window)); - return result; -} - -/* - *---------------------------------------------------------------------- - * - * TkMacOSXEnterExitFullscreen -- - * - * This procedure enters or exits fullscreen mode if required. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkMacOSXEnterExitFullscreen( - TkWindow *winPtr, - int active) -{ - WmInfo *wmPtr = winPtr->wmInfoPtr; - SystemUIMode mode; - SystemUIOptions options; - - GetSystemUIMode(&mode, &options); - if (wmPtr->flags & WM_FULLSCREEN && active) { - static SystemUIMode fullscreenMode = 0; - static SystemUIOptions fullscreenOptions = 0; - - if (!fullscreenMode) { - TK_IF_HI_TOOLBOX (3, - fullscreenMode = kUIModeAllSuppressed; - ) TK_ELSE_HI_TOOLBOX (3, - fullscreenMode = kUIModeAllHidden; - fullscreenOptions = kUIOptionAutoShowMenuBar; - ) TK_ENDIF - } - if (mode != fullscreenMode) { - ChkErr(SetSystemUIMode, fullscreenMode, fullscreenOptions); - } - } else { - if (mode != kUIModeNormal) { - ChkErr(SetSystemUIMode, kUIModeNormal, 0); - } - } -} - -/* - *---------------------------------------------------------------------- - * - * GetMinSize -- - * - * This function computes the current minWidth and minHeight values for a - * window, taking into account the possibility that they may be - * defaulted. - * - * Results: - * The values at *minWidthPtr and *minHeightPtr are filled in with the - * minimum allowable dimensions of wmPtr's window, in grid units. If the - * requested minimum is smaller than the system required minimum, then - * this function computes the smallest size that will satisfy both the - * system and the grid constraints. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -GetMinSize( - TkWindow *winPtr, /* Toplevel window to operate on. */ - int *minWidthPtr, /* Where to store the current minimum width of - * the window. */ - int *minHeightPtr) /* Where to store the current minimum height - * of the window. */ -{ - WmInfo *wmPtr = winPtr->wmInfoPtr; - int minWidth = 1, minHeight = 1; - - /* - * Compute the minimum width & height by taking the default client size and - * rounding it up to the nearest grid unit. Return the greater of the - * default minimum and the specified minimum. - */ - - switch (wmPtr->macClass) { - case kDocumentWindowClass: - case kMovableAlertWindowClass: - case kMovableModalWindowClass: - minWidth = 72; - if (wmPtr->attributes & kWindowResizableAttribute) { - minHeight = 15; - } - if (wmPtr->attributes & kWindowToolbarButtonAttribute) { - minWidth += 29; - } - break; - case kFloatingWindowClass: - case kUtilityWindowClass: - minWidth = 59; - if (wmPtr->attributes & kWindowResizableAttribute) { - minHeight = 11; - } - if (wmPtr->attributes & kWindowSideTitlebarAttribute) { - int tmp = minWidth; - - minWidth = minHeight; - minHeight = tmp; - } else if (wmPtr->attributes & kWindowToolbarButtonAttribute) { - minWidth += 29; - } - break; - default: - if (wmPtr->attributes & kWindowResizableAttribute) { - minWidth = 15; - minHeight = 15; - } - break; - } - - if (wmPtr->gridWin != NULL) { - int base = winPtr->reqWidth - (wmPtr->reqGridWidth * wmPtr->widthInc); - - if (base < 0) { - base = 0; - } - minWidth = ((minWidth - base) + wmPtr->widthInc-1)/wmPtr->widthInc; - base = winPtr->reqHeight - (wmPtr->reqGridHeight * wmPtr->heightInc); - if (base < 0) { - base = 0; - } - minHeight = ((minHeight - base) + wmPtr->heightInc-1)/wmPtr->heightInc; - } - if (minWidth < wmPtr->minWidth) { - minWidth = wmPtr->minWidth; - } - if (minHeight < wmPtr->minHeight) { - minHeight = wmPtr->minHeight; - } - *minWidthPtr = minWidth; - *minHeightPtr = minHeight; -} - -/* - *---------------------------------------------------------------------- - * - * GetMaxSize -- - * - * This function computes the current maxWidth and maxHeight values for a - * window, taking into account the possibility that they may be - * defaulted. - * - * Results: - * The values at *maxWidthPtr and *maxHeightPtr are filled in with the - * maximum allowable dimensions of wmPtr's window, in grid units. If no - * maximum has been specified for the window, then this function computes - * the largest sizes that will fit on the screen. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -GetMaxSize( - TkWindow *winPtr, /* Toplevel window to operate on. */ - int *maxWidthPtr, /* Where to store the current maximum width of - * the window. */ - int *maxHeightPtr) /* Where to store the current maximum height - * of the window. */ -{ - WmInfo *wmPtr = winPtr->wmInfoPtr; - Rect *maxBounds = (Rect*)(winPtr->display->screens->ext_data); - - if (wmPtr->maxWidth > 0) { - *maxWidthPtr = wmPtr->maxWidth; - } else { - int maxWidth = maxBounds->right - maxBounds->left - wmPtr->xInParent; - - if (wmPtr->gridWin != NULL) { - maxWidth = wmPtr->reqGridWidth - + (maxWidth - winPtr->reqWidth)/wmPtr->widthInc; - } - *maxWidthPtr = maxWidth; - } - if (wmPtr->maxHeight > 0) { - *maxHeightPtr = wmPtr->maxHeight; - } else { - int maxHeight = maxBounds->bottom - maxBounds->top - wmPtr->yInParent; - - if (wmPtr->gridWin != NULL) { - maxHeight = wmPtr->reqGridHeight - + (maxHeight - winPtr->reqHeight)/wmPtr->heightInc; - } - *maxHeightPtr = maxHeight; - } -} - -/* - *---------------------------------------------------------------------- - * - * RemapWindows - * - * Adjust parent/child relation ships of the given window hierarchy. - * - * Results: - * none - * - * Side effects: - * keeps windowing system (X11) happy - * - *---------------------------------------------------------------------- - */ - -static void -RemapWindows( - TkWindow *winPtr, - MacDrawable *parentWin) -{ - TkWindow *childPtr; - - /* - * Remove the OS specific window. It will get rebuilt when the window gets - * Mapped. - */ - - if (winPtr->window != None) { - MacDrawable *macWin = (MacDrawable *) winPtr->window; - - macWin->grafPtr = NULL; - macWin->toplevel = parentWin->toplevel; - winPtr->flags &= ~TK_MAPPED; -#ifdef TK_REBUILD_TOPLEVEL - winPtr->flags |= TK_REBUILD_TOPLEVEL; -#endif - } - - /* Repeat for all the children */ - for (childPtr = winPtr->childList; childPtr != NULL; - childPtr = childPtr->nextPtr) { - RemapWindows(childPtr, (MacDrawable *) winPtr->window); - } -} - -/* - * Local Variables: - * fill-column: 78 - * c-basic-offset: 4 - * End: - */ |