head	1.26;
access;
symbols
	core-8-4-19:1.24.2.1
	core-8-4-18:1.24.2.1
	core-8-4-17:1.24.2.1
	core-8-4-16:1.24.2.1
	core-8-4-15:1.24.2.1
	core-8-4-14:1.24.2.1
	core-8-4-13:1.24.2.1
	core-8-4-12:1.24.2.1
	core-8-4-11:1.24
	core-8-4-10:1.24
	core-8-4-9-branch:1.24.0.6
	core-8-4-9:1.24
	core-8-4-8:1.24
	core-8-4-7:1.24
	core-8-5-a1:1.25
	core-8-4-6:1.24
	core-8-4-5:1.24
	mistachkin-dev-branch:1.24.0.4
	core-8-4-4:1.24
	core-8-4-3:1.24
	core-8-4-branch:1.24.0.2
	core-8-4-2:1.24
	core-8-4-1:1.23
	core-8-3-5:1.10.2.1
	core-8-4-0:1.22
	macosx-8-4-merge-2002-08-31-trunk:1.22
	macosx-8-4-premerge-2002-08-31-branch:1.11.2.4
	macosx-8-4-premerge-2002-08-31-trunk:1.21
	macosx-8-4-merge-2002-08-30-branch:1.11.2.3
	macosx-8-4-merge-2002-08-30-trunk:1.21
	macosx-8-4-merge-2002-08-20-branch:1.11.2.3
	macosx-8-4-merge-2002-08-20-trunk:1.21
	core-8-4-b2:1.21
	core-8-4-b1:1.19
	macosx-premerge-6-9-02:1.11.2.1
	core-8-4-a4:1.14
	core-8-3-4:1.10.2.1
	macosx-8-4-branch:1.11.0.2
	macosx-8-4-branchpoint:1.11
	core-8-4-a3:1.11
	core-8-3-3:1.10.2.1
	dgp-privates-into-namespace:1.10.0.6
	tclpro-1-5-0:1.10
	core-8-4-win-speedup:1.10.0.4
	core-8-4-a2:1.10
	tclpro-1-4-1:1.10
	tclpro-1-4-0:1.10
	core-8-3-2:1.10
	ajuba-ajuba2-2-1-base:1.10
	ajuba-ajuba2-2-0:1.10
	core-8-4-a1:1.10
	core-8-3-1-branch:1.10.0.2
	core-8-3-1:1.10
	scriptics-sc-2-0-b5:1.9
	scriptics-sc-2-0-fixed:1.9
	scriptics-sc-2-0-b2:1.9
	scriptics-sc-2-0-b1:1.9
	core-8-3-0:1.9
	core-8-3-b2:1.8
	core-8-3-b1:1.7
	scriptics-sc-1-1:1.7
	scriptics-sc-1-1-b1:1.7
	core-8-2-3:1.7
	scriptics-sc-1-1-branch:1.7.0.8
	scriptics-sc-1-1-base:1.7
	scriptics-sc-1-0:1.7
	scriptics-sc-1-0-branch:1.7.0.6
	scriptics-sc-1-0-base:1.7
	core-8-2-2:1.7
	core-8-2-1:1.7
	scriptics-bc-1-0-b1:1.7
	core-8-2-1-branch:1.7.0.4
	scriptics-tclpro-1-3-0:1.7
	core-8-2-0:1.7
	core-8-2-b3-branch:1.7.0.2
	core-8-2-b3-base:1.7
	scriptics-tclpro-1-3-b4:1.7
	core-8-2-b2:1.7
	scriptics-tclpro-1-3-b3:1.7
	core-8-2-b1:1.7
	scriptics-tclpro-1-3-b2:1.6
	merge-to-mainline-5/21/99:1.6
	scriptics-tclpro-1-3-b2-branch:1.6.0.2
	core-8-1-1:1.6
	scriptics-tclpro-1-3-b1:1.6
	core-8-1-1-base:1.6
	core-8-1-0:1.6
	merge-to-mainline-4-29-99:1.6
	merge-to-mainline-4-23-99:1.6
	core-8-1-branch-old:1.1.0.4
	core-8-0-6-branch:1.5.0.6
	core-8-0-6-base:1.5
	core-8-0-5:1.5
	core-8-1-b3:1.1.4.4
	core-8-1-b2:1.1.4.4
	dev-8-1-stubs-branch:1.1.4.4.0.2
	dev-stubs-branch:1.5.0.4
	scriptics-tclpro-1-2:1.5
	scriptics-tclpro-1-2-b2:1.5
	core-8-1-merge-2/10/99:1.5
	core-8-0-5-branch:1.5.0.2
	core-8-0-5-base:1.5
	scriptics-tclpro-1-2-b1:1.5
	scriptics-tclpro-1-2-a1:1.5
	core-8-1-b1:1.1.4.3
	core-8-0-4:1.5
	core-8-1-a2:1.1.4.1
	core-8-0-2:1.1
	core-8-0-3:1.4;
locks; strict;
comment	@ * @;


1.26
date	2004.03.17.18.15.49;	author das;	state dead;
branches;
next	1.25;

1.25
date	2004.01.13.02.06.01;	author davygrvy;	state Exp;
branches;
next	1.24;

1.24
date	2003.02.09.07.51.04;	author hobbs;	state Exp;
branches
	1.24.2.1;
next	1.23;

1.23
date	2002.10.09.11.57.01;	author das;	state Exp;
branches;
next	1.22;

1.22
date	2002.08.31.06.12.28;	author das;	state Exp;
branches;
next	1.21;

1.21
date	2002.07.25.22.12.29;	author pspjuth;	state Exp;
branches;
next	1.20;

1.20
date	2002.07.25.21.36.08;	author pspjuth;	state Exp;
branches;
next	1.19;

1.19
date	2002.06.22.10.13.26;	author hobbs;	state Exp;
branches;
next	1.18;

1.18
date	2002.06.14.22.25.12;	author jenglish;	state Exp;
branches;
next	1.17;

1.17
date	2002.05.24.09.50.11;	author mdejong;	state Exp;
branches;
next	1.16;

1.16
date	2002.05.23.19.55.18;	author mdejong;	state Exp;
branches;
next	1.15;

1.15
date	2002.04.10.19.39.01;	author mdejong;	state Exp;
branches;
next	1.14;

1.14
date	2002.01.25.21.09.37;	author dgp;	state Exp;
branches;
next	1.13;

1.13
date	2001.12.05.01.30.44;	author das;	state Exp;
branches;
next	1.12;

1.12
date	2001.11.23.02.06.44;	author das;	state Exp;
branches;
next	1.11;

1.11
date	2001.08.06.18.29.41;	author dgp;	state Exp;
branches
	1.11.2.1;
next	1.10;

1.10
date	2000.04.25.01.02.13;	author hobbs;	state Exp;
branches
	1.10.2.1
	1.10.4.1;
next	1.9;

1.9
date	2000.02.10.08.57.11;	author jingham;	state Exp;
branches;
next	1.8;

1.8
date	2000.01.12.11.45.33;	author hobbs;	state Exp;
branches;
next	1.7;

1.7
date	99.05.22.06.35.34;	author jingham;	state Exp;
branches;
next	1.6;

1.6
date	99.04.16.01.51.32;	author stanton;	state Exp;
branches;
next	1.5;

1.5
date	98.11.11.17.31.51;	author jingham;	state Exp;
branches;
next	1.4;

1.4
date	98.09.14.18.23.40;	author stanton;	state Exp;
branches;
next	1.3;

1.3
date	98.07.06.23.00.58;	author welch;	state Exp;
branches;
next	1.2;

1.2
date	98.06.27.18.07.14;	author welch;	state Exp;
branches;
next	1.1;

1.1
date	98.04.01.09.57.04;	author rjohnson;	state Exp;
branches
	1.1.4.1;
next	;

1.1.4.1
date	98.09.29.00.25.44;	author stanton;	state Exp;
branches;
next	1.1.4.2;

1.1.4.2
date	98.09.30.02.18.18;	author stanton;	state Exp;
branches;
next	1.1.4.3;

1.1.4.3
date	98.11.25.21.16.37;	author stanton;	state Exp;
branches;
next	1.1.4.4;

1.1.4.4
date	98.12.13.08.16.14;	author lfb;	state Exp;
branches;
next	;

1.10.2.1
date	2001.04.04.21.39.49;	author hobbs;	state Exp;
branches;
next	;

1.10.4.1
date	2002.04.02.20.57.56;	author hobbs;	state Exp;
branches;
next	;

1.11.2.1
date	2002.02.05.02.25.17;	author wolfsuit;	state Exp;
branches;
next	1.11.2.2;

1.11.2.2
date	2002.06.10.05.38.25;	author wolfsuit;	state Exp;
branches;
next	1.11.2.3;

1.11.2.3
date	2002.08.20.20.27.11;	author das;	state Exp;
branches;
next	1.11.2.4;

1.11.2.4
date	2002.08.30.18.18.14;	author das;	state Exp;
branches;
next	;

1.24.2.1
date	2005.12.01.18.31.43;	author dgp;	state Exp;
branches;
next	;


desc
@@


1.26
log
@Removed support for Mac OS Classic platform [Patch 918139]
@
text
@/*
 * tkMacWm.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.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @@(#) $Id: tkMacWm.c,v 1.25 2004/01/13 02:06:01 davygrvy Exp $
 */

#include <Gestalt.h>
#include <QDOffscreen.h>
#include <Windows.h>
#include <ToolUtils.h>

#include <tclMac.h>
#include "tkPort.h"
#include "tkInt.h"
#include "tkMacInt.h"
#include <errno.h>
#include "tkScrollbar.h"

/*
 * We now require the Appearance headers.  They come with CodeWarrior Pro,
 * and are on the SDK CD.  However, we do not require the Appearance
 * extension
 */

#include <Appearance.h>

/*
 * A data structure of the following type holds information for
 * each window manager protocol (such as WM_DELETE_WINDOW) for
 * which a handler (i.e. a Tcl command) has been defined for a
 * particular top-level window.
 */

typedef struct ProtocolHandler {
    Atom protocol;		/* Identifies the protocol. */
    struct ProtocolHandler *nextPtr;
				/* Next in list of protocol handlers for
				 * the same top-level window, or NULL for
				 * end of list. */
    Tcl_Interp *interp;		/* Interpreter in which to invoke command. */
    char command[4];		/* Tcl command to invoke when a client
				 * message for this protocol arrives.
				 * The actual size of the structure varies
				 * to accommodate the needs of the actual
				 * command. THIS MUST BE THE LAST FIELD OF
				 * THE STRUCTURE. */
} ProtocolHandler;

#define HANDLER_SIZE(cmdLength) \
((unsigned) (sizeof(ProtocolHandler) - 3 + cmdLength))

/*
 * A data structure of the following type holds window-manager-related
 * information for each top-level window in an application.
 */

typedef struct TkWmInfo {
    TkWindow *winPtr;		/* Pointer to main Tk information for
				 * this window. */
    Window reparent;		/* If the window has been reparented, this
				 * gives the ID of the ancestor of the window
				 * that is a child of the root window (may
				 * not be window's immediate parent).  If
				 * the window isn't reparented, this has the
				 * value None. */
    char *title;		/* Title to display in window caption.  If
				 * NULL, use name of widget.  Malloced. */
    char *iconName;		/* Name to display in icon.  Malloced. */
    Window master;		/* Master window for TRANSIENT_FOR property,
				 * or None. */
    XWMHints hints;		/* Various pieces of information for
				 * window manager. */
    char *leaderName;		/* Path name of leader of window group
				 * (corresponds to hints.window_group).
				 * Malloc-ed.  Note:  this field doesn't
				 * get updated if leader is destroyed. */
    char *masterWindowName;	/* Path name of window specified as master
				 * in "wm transient" command, or NULL.
				 * Malloc-ed. Note:  this field doesn't
				 * get updated if masterWindowName is
				 * destroyed. */
    Tk_Window icon;		/* Window to use as icon for this window,
				 * or NULL. */
    Tk_Window iconFor;		/* Window for which this window is icon, or
				 * NULL if this isn't an icon for anyone. */

    /*
     * Information used to construct an XSizeHints structure for
     * the window manager:
     */

    int sizeHintsFlags;		/* Flags word for XSizeHints structure.
				 * If the PBaseSize flag is set then the
				 * window is gridded;  otherwise it isn't
				 * gridded. */
    int minWidth, minHeight;	/* Minimum dimensions of window, in
				 * grid units, not pixels. */
    int maxWidth, maxHeight;	/* Maximum dimensions of window, in
				 * grid units, not pixels. */
    Tk_Window gridWin;		/* Identifies the window that controls
				 * gridding for this top-level, or NULL if
				 * the top-level isn't currently gridded. */
    int widthInc, heightInc;	/* Increments for size changes (# pixels
				 * per step). */
    struct {
	int x;	/* numerator */
	int y;  /* denominator */
    } minAspect, maxAspect;	/* Min/max aspect ratios for window. */
    int reqGridWidth, reqGridHeight;
				/* The dimensions of the window (in
				 * grid units) requested through
				 * the geometry manager. */
    int gravity;		/* Desired window gravity. */

    /*
     * Information used to manage the size and location of a window.
     */

    int width, height;		/* Desired dimensions of window, specified
				 * in grid units.  These values are
				 * set by the "wm geometry" command and by
				 * ConfigureNotify events (for when wm
				 * resizes window).  -1 means user hasn't
				 * requested dimensions. */
    int x, y;			/* Desired X and Y coordinates for window.
				 * These values are set by "wm geometry",
				 * plus by ConfigureNotify events (when wm
				 * moves window).  These numbers are
				 * different than the numbers stored in
				 * winPtr->changes because (a) they could be
				 * measured from the right or bottom edge
				 * of the screen (see WM_NEGATIVE_X and
				 * WM_NEGATIVE_Y flags) and (b) if the window
				 * has been reparented then they refer to the
				 * parent rather than the window itself. */
    int parentWidth, parentHeight;
				/* Width and height of reparent, in pixels
				 * *including border*.  If window hasn't been
				 * reparented then these will be the outer
				 * dimensions of the window, including
				 * border. */
    int xInParent, yInParent;	/* Offset of window within reparent,  measured
				 * from upper-left outer corner of parent's
				 * border to upper-left outer corner of child's
				 * border.  If not reparented then these are
				 * zero. */
    int configWidth, configHeight;
				/* Dimensions passed to last request that we
				 * issued to change geometry of window.  Used
				 * to eliminate redundant resize operations. */

    /*
     * Information about the virtual root window for this top-level,
     * if there is one.
     */

    Window vRoot;		/* Virtual root window for this top-level,
				 * or None if there is no virtual root
				 * window (i.e. just use the screen's root). */
    int vRootX, vRootY;		/* Position of the virtual root inside the
				 * root window.  If the WM_VROOT_OFFSET_STALE
				 * flag is set then this information may be
				 * incorrect and needs to be refreshed from
				 * the X server.  If vRoot is None then these
				 * values are both 0. */
    unsigned int vRootWidth, vRootHeight;
				/* Dimensions of the virtual root window.
				 * If vRoot is None, gives the dimensions
				 * of the containing screen.  This information
				 * is never stale, even though vRootX and
				 * vRootY can be. */

    /*
     * List of children of the toplevel which have private colormaps.
     */

    TkWindow **cmapList;	/* Array of window with private colormaps. */
    int cmapCount;		/* Number of windows in array. */

    /*
     * Miscellaneous information.
     */

    ProtocolHandler *protPtr;	/* First in list of protocol handlers for
				 * this window (NULL means none). */
    int cmdArgc;		/* Number of elements in cmdArgv below. */
    CONST char **cmdArgv;	/* Array of strings to store in the
				 * WM_COMMAND property.  NULL means nothing
				 * available. */
    char *clientMachine;	/* String to store in WM_CLIENT_MACHINE
				 * property, or NULL. */
    int flags;			/* Miscellaneous flags, defined below. */

    /*
     * Macintosh information.
     */
    int style;			/* Native window style. */
    int macClass;
    int attributes;
    TkWindow *scrollWinPtr;	/* Ptr to scrollbar handling grow widget. */
} WmInfo;


/*
 * Flag values for WmInfo structures:
 *
 * WM_NEVER_MAPPED -		non-zero means window has never been
 *				mapped;  need to update all info when
 *				window is first mapped.
 * WM_UPDATE_PENDING -		non-zero means a call to UpdateGeometryInfo
 *				has already been scheduled for this
 *				window;  no need to schedule another one.
 * WM_NEGATIVE_X -		non-zero means x-coordinate is measured in
 *				pixels from right edge of screen, rather
 *				than from left edge.
 * WM_NEGATIVE_Y -		non-zero means y-coordinate is measured in
 *				pixels up from bottom of screen, rather than
 *				down from top.
 * WM_UPDATE_SIZE_HINTS -	non-zero means that new size hints need to be
 *				propagated to window manager.
 * WM_SYNC_PENDING -		set to non-zero while waiting for the window
 *				manager to respond to some state change.
 * WM_VROOT_OFFSET_STALE -	non-zero means that (x,y) offset information
 *				about the virtual root window is stale and
 *				needs to be fetched fresh from the X server.
 * WM_ABOUT_TO_MAP -		non-zero means that the window is about to
 *				be mapped by TkWmMapWindow.  This is used
 *				by UpdateGeometryInfo to modify its behavior.
 * WM_MOVE_PENDING -		non-zero means the application has requested
 *				a new position for the window, but it hasn't
 *				been reflected through the window manager
 *				yet.
 * WM_COLORMAPS_EXPLICIT -	non-zero means the colormap windows were
 *				set explicitly via "wm colormapwindows".
 * WM_ADDED_TOPLEVEL_COLORMAP - non-zero means that when "wm colormapwindows"
 *				was called the top-level itself wasn't
 *				specified, so we added it implicitly at
 *				the end of the list.
 * WM_WIDTH_NOT_RESIZABLE -	non-zero means that we're not supposed to
 *				allow the user to change the width of the
 *				window (controlled by "wm resizable"
 *				command).
 * WM_HEIGHT_NOT_RESIZABLE -	non-zero means that we're not supposed to
 *				allow the user to change the height of the
 *				window (controlled by "wm resizable"
 *				command).
 */

#define WM_NEVER_MAPPED			1
#define WM_UPDATE_PENDING		2
#define WM_NEGATIVE_X			4
#define WM_NEGATIVE_Y			8
#define WM_UPDATE_SIZE_HINTS		0x10
#define WM_SYNC_PENDING			0x20
#define WM_VROOT_OFFSET_STALE		0x40
#define WM_ABOUT_TO_MAP			0x100
#define WM_MOVE_PENDING			0x200
#define WM_COLORMAPS_EXPLICIT		0x400
#define WM_ADDED_TOPLEVEL_COLORMAP	0x800
#define WM_WIDTH_NOT_RESIZABLE		0x1000
#define WM_HEIGHT_NOT_RESIZABLE		0x2000

/*
 * 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.
 */

TkMacWindowList *tkMacWindowListPtr = 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 _ANSI_ARGS_((ClientData dummy,
	Tk_Window tkwin));

static Tk_GeomMgr wmMgrType = {
    "wm",				/* name */
    TopLevelReqProc,			/* requestProc */
    (Tk_GeomLostSlaveProc *) NULL,	/* lostSlaveProc */
};

/*
 * Hash table for Mac Window -> TkWindow mapping.
 */

static Tcl_HashTable windowTable;
static int windowHashInit = false;

void tkMacMoveWindow(WindowRef window, int x, int y);

/*
 * Forward declarations for procedures defined in this file:
 */

static void		InitialWindowBounds _ANSI_ARGS_((TkWindow *winPtr,
			    Rect *geometry));
static int		ParseGeometry _ANSI_ARGS_((Tcl_Interp *interp,
			    char *string, TkWindow *winPtr));
static void		TopLevelEventProc _ANSI_ARGS_((ClientData clientData,
			    XEvent *eventPtr));
static void		TkWmStackorderToplevelWrapperMap _ANSI_ARGS_((
			    TkWindow *winPtr,
			    Tcl_HashTable *reparentTable));
static void		TopLevelReqProc _ANSI_ARGS_((ClientData dummy,
			    Tk_Window tkwin));
static void		UpdateGeometryInfo _ANSI_ARGS_((
			    ClientData clientData));
static void		UpdateSizeHints _ANSI_ARGS_((TkWindow *winPtr));
static void		UpdateVRootGeometry _ANSI_ARGS_((WmInfo *wmPtr));
static int 		WmAspectCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmAttributesCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmClientCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmColormapwindowsCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmCommandCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmDeiconifyCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmFocusmodelCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmFrameCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmGeometryCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmGridCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmGroupCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmIconbitmapCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmIconifyCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmIconmaskCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmIconnameCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmIconpositionCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmIconwindowCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmMaxsizeCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmMinsizeCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmOverrideredirectCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmPositionfromCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmProtocolCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmResizableCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmSizefromCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmStackorderCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmStateCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmTitleCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmTransientCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmWithdrawCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static void		WmUpdateGeom _ANSI_ARGS_((WmInfo *wmPtr,
			    TkWindow *winPtr));

/*
 *--------------------------------------------------------------
 *
 * 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. */
{
    register WmInfo *wmPtr;

    wmPtr = (WmInfo *) ckalloc(sizeof(WmInfo));
    wmPtr->winPtr = winPtr;
    wmPtr->reparent = None;
    wmPtr->title = 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;

    /*
     * Default the maximum dimensions to the size of the display, minus
     * a guess about how space is needed for window manager decorations.
     */

    wmPtr->maxWidth = DisplayWidth(winPtr->display, winPtr->screenNum) - 15;
    wmPtr->maxHeight = DisplayHeight(winPtr->display, winPtr->screenNum) - 30;
    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->configWidth = -1;
    wmPtr->configHeight = -1;
    wmPtr->vRoot = None;
    wmPtr->protPtr = NULL;
    wmPtr->cmdArgv = NULL;
    wmPtr->clientMachine = NULL;
    wmPtr->flags = WM_NEVER_MAPPED;
    if (TkMacHaveAppearance() >= 0x110) {
        wmPtr->style = -1;
    } else {
        wmPtr->style = documentProc;
    }
    wmPtr->macClass = kDocumentWindowClass;
    wmPtr->attributes = kWindowStandardDocumentAttributes;
    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, (ClientData) 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. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    Point where = {0, 0};
    int xOffset, yOffset;
    int firstMap = false;
    MacDrawable *macWin;

    if (wmPtr->flags & WM_NEVER_MAPPED) {
	wmPtr->flags &= ~WM_NEVER_MAPPED;
	firstMap = true;

	/*
	 * Create the underlying Mac window for this Tk window.
	 */
	macWin = (MacDrawable *) winPtr->window;
	if (!TkMacHostToplevelExists(winPtr)) {
	    TkMacMakeRealWindowExist(winPtr);
	}

	/*
	 * Generate configure event when we first map the window.
	 */
	LocalToGlobal(&where);
	TkMacWindowOffset((WindowRef) TkMacGetDrawablePort((Drawable) macWin),
		&xOffset, &yOffset);
	where.h -= xOffset;
	where.v -= yOffset;
	TkGenWMConfigureEvent((Tk_Window) winPtr,
		where.h, where.v, -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 (!Tk_IsEmbedded(winPtr)) {
	    TkSetWMName(winPtr, ((wmPtr->title != NULL) ?
		    wmPtr->title : winPtr->nameUid));
	}

	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, (ClientData) winPtr);
    }
    UpdateGeometryInfo((ClientData) winPtr);
    wmPtr->flags &= ~WM_ABOUT_TO_MAP;

    /*
     * Map the window.
     */

    XMapWindow(winPtr->display, winPtr->window);

    /*
     * Now that the window is visable we can determine the offset
     * from the window's content orgin to the window's decorative
     * orgin (structure orgin).
     */
    TkMacWindowOffset((WindowRef) TkMacGetDrawablePort(Tk_WindowId(winPtr)),
	&wmPtr->xInParent, &wmPtr->yInParent);
}

/*
 *--------------------------------------------------------------
 *
 * 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(winPtr)
    TkWindow *winPtr;		/* Top-level window that's being deleted. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    WmInfo *wmPtr2;

    if (wmPtr == NULL) {
	return;
    }
    if (wmPtr->title != NULL) {
	ckfree(wmPtr->title);
    }
    if (wmPtr->iconName != NULL) {
	ckfree(wmPtr->iconName);
    }
    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->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((ClientData) protPtr, TCL_DYNAMIC);
    }
    if (wmPtr->cmdArgv != NULL) {
	ckfree((char *) wmPtr->cmdArgv);
    }
    if (wmPtr->clientMachine != NULL) {
	ckfree((char *) wmPtr->clientMachine);
    }
    if (wmPtr->flags & WM_UPDATE_PENDING) {
	Tk_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
    }
    ckfree((char *) 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 *optionStrings[] = {
	"aspect", "attributes", "client", "colormapwindows",
	"command", "deiconify", "focusmodel", "frame",
	"geometry", "grid", "group", "iconbitmap",
	"iconify", "iconmask", "iconname", "iconposition",
	"iconwindow", "maxsize", "minsize", "overrideredirect",
        "positionfrom", "protocol", "resizable", "sizefrom",
        "stackorder", "state", "title", "transient",
	"withdraw", (char *) NULL };
    enum options {
        WMOPT_ASPECT, WMOPT_ATTRIBUTES, WMOPT_CLIENT, WMOPT_COLORMAPWINDOWS,
	WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL, WMOPT_FRAME,
	WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP, WMOPT_ICONBITMAP,
	WMOPT_ICONIFY, WMOPT_ICONMASK, WMOPT_ICONNAME, WMOPT_ICONPOSITION,
	WMOPT_ICONWINDOW, 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;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    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_SetResult(interp, ((wmTracing) ? "on" : "off"), TCL_STATIC);
	    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)) {
	Tcl_AppendResult(interp, "window \"", winPtr->pathName,
		"\" isn't a top-level window", (char *) 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_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_ICONPOSITION:
	return WmIconpositionCmd(tkwin, winPtr, interp, objc, objv);
      case WMOPT_ICONWINDOW:
	return WmIconwindowCmd(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(tkwin, winPtr, interp, objc, objv)
    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) {
	    char buf[TCL_INTEGER_SPACE * 4];

	    sprintf(buf, "%d %d %d %d", wmPtr->minAspect.x,
		    wmPtr->minAspect.y, wmPtr->maxAspect.x,
		    wmPtr->maxAspect.y);
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
	}
	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_SetResult(interp, "aspect number can't be <= 0",
		    TCL_STATIC);
	    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;
}

/*
 *----------------------------------------------------------------------
 *
 * 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(tkwin, winPtr, interp, objc, objv)
    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. */
{
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	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(tkwin, winPtr, interp, objc, objv)
    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_SetResult(interp, wmPtr->clientMachine, TCL_STATIC);
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    if (argv3[0] == 0) {
	if (wmPtr->clientMachine != NULL) {
	    ckfree((char *) wmPtr->clientMachine);
	    wmPtr->clientMachine = NULL;
	}
	return TCL_OK;
    }
    if (wmPtr->clientMachine != NULL) {
	ckfree((char *) wmPtr->clientMachine);
    }
    wmPtr->clientMachine = (char *)
	    ckalloc((unsigned) (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(tkwin, winPtr, interp, objc, objv)
    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;
    TkWindow *winPtr2;
    int i, windowObjc, gotToplevel = 0;
    Tcl_Obj **windowObjv;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?windowList?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tk_MakeWindowExist((Tk_Window) winPtr);
	for (i = 0; i < wmPtr->cmapCount; i++) {
	    if ((i == (wmPtr->cmapCount-1))
		    && (wmPtr->flags & WM_ADDED_TOPLEVEL_COLORMAP)) {
		break;
	    }
	    Tcl_AppendElement(interp, wmPtr->cmapList[i]->pathName);
	}
	return TCL_OK;
    }
    if (Tcl_ListObjGetElements(interp, objv[3], &windowObjc, &windowObjv)
	    != TCL_OK) {
	return TCL_ERROR;
    }
    cmapList = (TkWindow **) ckalloc((unsigned)
	    ((windowObjc+1)*sizeof(TkWindow*)));
    for (i = 0; i < windowObjc; i++) {
	if (TkGetWindowFromObj(interp, tkwin, windowObjv[i],
		(Tk_Window *) &winPtr2) != TCL_OK)
	{
	    ckfree((char *) 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((char *)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(tkwin, winPtr, interp, objc, objv)
    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) {
	    Tcl_SetResult(interp,
		    Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv),
		    TCL_DYNAMIC);
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (argv3[0] == 0) {
	if (wmPtr->cmdArgv != NULL) {
	    ckfree((char *) 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((char *) 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(tkwin, winPtr, interp, objc, objv)
    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_AppendResult(interp, "can't deiconify ", Tcl_GetString(objv[2]),
		": it is an icon for ", Tk_PathName(wmPtr->iconFor),
		(char *) NULL);
	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	Tcl_AppendResult(interp, "can't deiconify ", winPtr->pathName,
		": it is an embedded window", (char *) NULL);
	return TCL_ERROR;
    }

    /*
     * TODO: may not want to call this function - look at Map events gened.
     */

    TkpWmSetState(winPtr, 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(tkwin, winPtr, interp, objc, objv)
    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 *optionStrings[] = {
	"active", "passive", (char *) 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_SetResult(interp, (wmPtr->hints.input ? "passive" : "active"),
		TCL_STATIC);
	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;
}

/*
 *----------------------------------------------------------------------
 *
 * 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(tkwin, winPtr, interp, objc, objv)
    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;
    char buf[TCL_INTEGER_SPACE];

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    window = wmPtr->reparent;
    if (window == None) {
	window = Tk_WindowId((Tk_Window) winPtr);
    }
    sprintf(buf, "0x%x", (unsigned int) window);
    Tcl_SetResult(interp, buf, TCL_VOLATILE);
    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(tkwin, winPtr, interp, objc, objv)
    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) {
	char buf[16 + TCL_INTEGER_SPACE * 4];

	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;
	}
	sprintf(buf, "%dx%d%c%d%c%d", width, height, xSign, wmPtr->x,
		ySign, wmPtr->y);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	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(tkwin, winPtr, interp, objc, objv)
    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;

    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) {
	    char buf[TCL_INTEGER_SPACE * 4];

	    sprintf(buf, "%d %d %d %d", wmPtr->reqGridWidth,
		    wmPtr->reqGridHeight, wmPtr->widthInc,
		    wmPtr->heightInc);
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
	}
	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) {
	    Tcl_SetResult(interp, "baseWidth can't be < 0", TCL_STATIC);
	    return TCL_ERROR;
	}
	if (reqHeight < 0) {
	    Tcl_SetResult(interp, "baseHeight can't be < 0", TCL_STATIC);
	    return TCL_ERROR;
	}
	if (widthInc < 0) {
	    Tcl_SetResult(interp, "widthInc can't be < 0", TCL_STATIC);
	    return TCL_ERROR;
	}
	if (heightInc < 0) {
	    Tcl_SetResult(interp, "heightInc can't be < 0", TCL_STATIC);
	    return TCL_ERROR;
	}
	Tk_SetGrid((Tk_Window) winPtr, reqWidth, reqHeight, widthInc,
		heightInc);
    }
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    WmUpdateGeom(wmPtr, winPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * 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(tkwin, winPtr, interp, objc, objv)
    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_SetResult(interp, wmPtr->leaderName, TCL_STATIC);
	}
	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((unsigned) (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(tkwin, winPtr, interp, objc, objv)
    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;
    Pixmap pixmap;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & IconPixmapHint) {
	    Tcl_SetResult(interp, (char *)
		    Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_pixmap),
		    TCL_STATIC);
	}
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (*argv3 == '\0') {
	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, argv3);
	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(tkwin, winPtr, interp, objc, objv)
    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_AppendResult(interp, "can't iconify \"", winPtr->pathName,
		"\": override-redirect flag is set", (char *) NULL);
	return TCL_ERROR;
    }
    if (wmPtr->master != None) {
	Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
		"\": it is a transient", (char *) NULL);
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName,
		": it is an icon for ", Tk_PathName(wmPtr->iconFor),
		(char *) NULL);
	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName,
		": it is an embedded window", (char *) 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(tkwin, winPtr, interp, objc, objv)
    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_SetResult(interp, (char *)
		    Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_mask),
		    TCL_STATIC);
	}
	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(tkwin, winPtr, interp, objc, objv)
    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 ?newName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_SetResult(interp,
		((wmPtr->iconName != NULL) ? wmPtr->iconName : ""),
		TCL_STATIC);
	return TCL_OK;
    } else {
	if (wmPtr->iconName != NULL) {
	    ckfree((char *) wmPtr->iconName);
	}
	argv3 = Tcl_GetStringFromObj(objv[3], &length);
	wmPtr->iconName = ckalloc((unsigned) (length + 1));
	strcpy(wmPtr->iconName, argv3);
	if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	    XSetIconName(winPtr->display, winPtr->window, wmPtr->iconName);
	}
    }
    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(tkwin, winPtr, interp, objc, objv)
    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) {
	    char buf[TCL_INTEGER_SPACE * 2];

	    sprintf(buf, "%d %d", wmPtr->hints.icon_x,
		    wmPtr->hints.icon_y);
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
	}
	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(tkwin, winPtr, interp, objc, objv)
    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_SetResult(interp, Tk_PathName(wmPtr->icon), TCL_STATIC);
	}
	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_AppendResult(interp, "can't use ", Tcl_GetString(objv[3]),
		    " as icon window: not at top level", (char *) NULL);
	    return TCL_ERROR;
	}
	wmPtr2 = ((TkWindow *) tkwin2)->wmInfoPtr;
	if (wmPtr2->iconFor != NULL) {
	    Tcl_AppendResult(interp, Tcl_GetString(objv[3]),
		    " is already an icon for ",
		    Tk_PathName(wmPtr2->iconFor), (char *) 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;
}

/*
 *----------------------------------------------------------------------
 *
 * 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(tkwin, winPtr, interp, objc, objv)
    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) {
	char buf[TCL_INTEGER_SPACE * 2];

	sprintf(buf, "%d %d", wmPtr->maxWidth, wmPtr->maxHeight);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	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(tkwin, winPtr, interp, objc, objv)
    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) {
	char buf[TCL_INTEGER_SPACE * 2];

	sprintf(buf, "%d %d", wmPtr->minWidth, wmPtr->minHeight);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	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(tkwin, winPtr, interp, objc, objv)
    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 boolean;
    XSetWindowAttributes atts;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_SetBooleanObj(Tcl_GetObjResult(interp),
		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);
    wmPtr->style = (boolean) ? plainDBox : documentProc;
    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(tkwin, winPtr, interp, objc, objv)
    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 *optionStrings[] = {
	"program", "user", (char *) 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_SetResult(interp, "user", TCL_STATIC);
	} else if (wmPtr->sizeHintsFlags & PPosition) {
	    Tcl_SetResult(interp, "program", TCL_STATIC);
	}
	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(tkwin, winPtr, interp, objc, objv)
    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;

    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.
	 */
	for (protPtr = wmPtr->protPtr; protPtr != NULL;
	     protPtr = protPtr->nextPtr) {
	    Tcl_AppendElement(interp,
		    Tk_GetAtomName((Tk_Window) winPtr, protPtr->protocol));
	}
	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_SetResult(interp, protPtr->command, TCL_STATIC);
		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((ClientData) protPtr, TCL_DYNAMIC);
	    break;
	}
    }
    cmd = Tcl_GetStringFromObj(objv[4], &cmdLength);
    if (cmdLength > 0) {
	protPtr = (ProtocolHandler *) 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(tkwin, winPtr, interp, objc, objv)
    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) {
	char buf[TCL_INTEGER_SPACE * 2];

	sprintf(buf, "%d %d",
		(wmPtr->flags  & WM_WIDTH_NOT_RESIZABLE) ? 0 : 1,
		(wmPtr->flags  & WM_HEIGHT_NOT_RESIZABLE) ? 0 : 1);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	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;
    } else {
	wmPtr->flags |= WM_WIDTH_NOT_RESIZABLE;
    }
    if (height) {
	wmPtr->flags &= ~WM_HEIGHT_NOT_RESIZABLE;
    } else {
	wmPtr->flags |= WM_HEIGHT_NOT_RESIZABLE;
    }
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    if (wmPtr->scrollWinPtr != NULL) {
	TkScrollbarEventuallyRedraw(
		(TkScrollbar *) wmPtr->scrollWinPtr->instanceData);
    }
    WmUpdateGeom(wmPtr, winPtr);
    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(tkwin, winPtr, interp, objc, objv)
    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 *optionStrings[] = {
	"program", "user", (char *) 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_SetResult(interp, "user", TCL_STATIC);
	} else if (wmPtr->sizeHintsFlags & PSize) {
	    Tcl_SetResult(interp, "program", TCL_STATIC);
	}
	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(tkwin, winPtr, interp, objc, objv)
    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, **window_ptr;
    static CONST char *optionStrings[] = {
	"isabove", "isbelow", (char *) NULL };
    enum options {
	OPT_ISABOVE, OPT_ISBELOW };
    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");
	} else {
	    for (window_ptr = windows; *window_ptr ; window_ptr++) {
		Tcl_AppendElement(interp, (*window_ptr)->pathName);
	    }
	    ckfree((char *) 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_AppendResult(interp, "window \"", winPtr2->pathName,
		    "\" isn't a top-level window", (char *) NULL);
	    return TCL_ERROR;
	}

	if (!Tk_IsMapped(winPtr)) {
	    Tcl_AppendResult(interp, "window \"", winPtr->pathName,
		    "\" isn't mapped", (char *) NULL);
	    return TCL_ERROR;
	}

	if (!Tk_IsMapped(winPtr2)) {
	    Tcl_AppendResult(interp, "window \"", winPtr2->pathName,
		    "\" isn't mapped", (char *) 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_AppendResult(interp, "TkWmStackorderToplevel failed",
                    (char *) NULL);
	    return TCL_ERROR;
	} else {
	    for (window_ptr = windows; *window_ptr ; window_ptr++) {
		if (*window_ptr == winPtr)
		    index1 = (window_ptr - windows);
		if (*window_ptr == winPtr2)
		    index2 = (window_ptr - windows);
	    }
	    if (index1 == -1)
		Tcl_Panic("winPtr window not found");
	    if (index2 == -1)
		Tcl_Panic("winPtr2 window not found");

	    ckfree((char *) 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_SetIntObj(Tcl_GetObjResult(interp), 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(tkwin, winPtr, interp, objc, objv)
    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 *optionStrings[] = {
	"normal", "iconic", "withdrawn", "zoomed", (char *) 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_AppendResult(interp, "can't change state of ",
		    Tcl_GetString(objv[2]),
		    ": it is an icon for ", Tk_PathName(wmPtr->iconFor),
		    (char *) NULL);
	    return TCL_ERROR;
	}
	if (winPtr->flags & TK_EMBEDDED) {
	    Tcl_AppendResult(interp, "can't change state of ",
		    winPtr->pathName, ": it is an embedded window",
		    (char *) 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_AppendResult(interp, "can't iconify \"",
			winPtr->pathName,
			"\": override-redirect flag is set",
			(char *) NULL);
		return TCL_ERROR;
	    }
	    if (wmPtr->master != NULL) {
		Tcl_AppendResult(interp, "can't iconify \"",
			winPtr->pathName,
			"\": it is a transient", (char *) 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_SetResult(interp, "icon", TCL_STATIC);
	} else {
	    switch (wmPtr->hints.initial_state) {
	      case NormalState:
		Tcl_SetResult(interp, "normal", TCL_STATIC);
		break;
	      case IconicState:
		Tcl_SetResult(interp, "iconic", TCL_STATIC);
		break;
	      case WithdrawnState:
		Tcl_SetResult(interp, "withdrawn", TCL_STATIC);
		break;
	      case ZoomState:
		Tcl_SetResult(interp, "zoomed", TCL_STATIC);
		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(tkwin, winPtr, interp, objc, objv)
    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_SetResult(interp, (char *)
		((wmPtr->title != NULL) ? wmPtr->title : winPtr->nameUid),
		TCL_STATIC);
	return TCL_OK;
    } else {
	if (wmPtr->title != NULL) {
	    ckfree((char *) wmPtr->title);
	}
	argv3 = Tcl_GetStringFromObj(objv[3], &length);
	wmPtr->title = ckalloc((unsigned) (length + 1));
	strcpy(wmPtr->title, argv3);
	if (!(wmPtr->flags & WM_NEVER_MAPPED) && !Tk_IsEmbedded(winPtr)) {
	    TkSetWMName(winPtr, wmPtr->title);
	}
    }
    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(tkwin, winPtr, interp, objc, objv)
    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_SetResult(interp, wmPtr->masterWindowName, TCL_STATIC);
	}
	return TCL_OK;
    }
    if (Tcl_GetString(objv[3])[0] == '\0') {
	wmPtr->master = None;
	if (wmPtr->masterWindowName != NULL) {
	    ckfree(wmPtr->masterWindowName);
	}
	wmPtr->masterWindowName = NULL;
	wmPtr->style = documentProc;
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3], &master) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tk_MakeWindowExist(master);

	if (wmPtr->iconFor != NULL) {
	    Tcl_AppendResult(interp, "can't make \"",
		    Tcl_GetString(objv[2]),
		    "\" a transient: it is an icon for ",
		    Tk_PathName(wmPtr->iconFor),
		    (char *) NULL);
	    return TCL_ERROR;
	}

	wmPtr2 = ((TkWindow *) master)->wmInfoPtr;

	if (wmPtr2->iconFor != NULL) {
	    Tcl_AppendResult(interp, "can't make \"",
		    Tcl_GetString(objv[3]),
		    "\" a master: it is an icon for ",
		    Tk_PathName(wmPtr2->iconFor),
		    (char *) NULL);
	    return TCL_ERROR;
	}

	argv3 = Tcl_GetStringFromObj(objv[3], &length);
	wmPtr->master = Tk_WindowId(master);
	wmPtr->masterWindowName = ckalloc((unsigned) length+1);
	strcpy(wmPtr->masterWindowName, argv3);
	wmPtr->style = plainDBox;
    }
    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(tkwin, winPtr, interp, objc, objv)
    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_AppendResult(interp, "can't withdraw ", Tcl_GetString(objv[2]),
		": it is an icon for ", Tk_PathName(wmPtr->iconFor),
		(char *) 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(wmPtr, winPtr)
    WmInfo *wmPtr;
    TkWindow *winPtr;
{
    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tk_DoWhenIdle(UpdateGeometryInfo, (ClientData) 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;
    register WmInfo *wmPtr;

    /*
     * Find the top-level window for tkwin, plus the window manager
     * information.
     */

    while (!(winPtr->flags & TK_TOP_HIERARCHY)) {
	winPtr = winPtr->parentPtr;
    }
    wmPtr = winPtr->wmInfoPtr;
    if (wmPtr == NULL) {
	return;
    }

    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))) {
	Tk_DoWhenIdle(UpdateGeometryInfo, (ClientData) 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;
    register WmInfo *wmPtr;

    /*
     * Find the top-level window for tkwin, plus the window manager
     * information.
     */

    while (!(winPtr->flags & TK_TOP_HIERARCHY)) {
	winPtr = winPtr->parentPtr;
    }
    wmPtr = winPtr->wmInfoPtr;
    if (wmPtr == NULL) {
	return;
    }

    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))) {
	Tk_DoWhenIdle(UpdateGeometryInfo, (ClientData) 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. */
{
    register TkWindow *winPtr = (TkWindow *) clientData;

    winPtr->wmInfoPtr->flags |= WM_VROOT_OFFSET_STALE;
    if (eventPtr->type == DestroyNotify) {
	Tk_ErrorHandler handler;

	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.
	     */

	    handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1,
		    (Tk_ErrorProc *) NULL, (ClientData) NULL);
	    Tk_DestroyWindow((Tk_Window) winPtr);
	    Tk_DeleteErrorHandler(handler);
	}
	if (wmTracing) {
	    printf("TopLevelEventProc: %s deleted\n", 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))) {
	Tk_DoWhenIdle(UpdateGeometryInfo, (ClientData) 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. */
{
    register TkWindow *winPtr = (TkWindow *) clientData;
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y, width, height;
    unsigned long serial;

    wmPtr->flags &= ~WM_UPDATE_PENDING;

    /*
     * 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;
    }
    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;
    }

    /*
     * 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)) == 0)) {
	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;

	contWinPtr = TkpGetOtherWindow(winPtr);

	/*
	 * NOTE: 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;
    }
    serial = NextRequest(winPtr->display);
    if (wmPtr->flags & WM_MOVE_PENDING) {
	wmPtr->configWidth = width;
	wmPtr->configHeight = height;
	if (wmTracing) {
	    printf(
		"UpdateGeometryInfo moving to %d %d, resizing to %d x %d,\n",
		    x, y, width, height);
	}
	Tk_MoveResizeWindow((Tk_Window) winPtr, x, y, (unsigned) width,
		(unsigned) height);
    } else if ((width != wmPtr->configWidth)
	    || (height != wmPtr->configHeight)) {
	wmPtr->configWidth = width;
	wmPtr->configHeight = height;
	if (wmTracing) {
	    printf("UpdateGeometryInfo resizing to %d x %d\n", width, height);
	}
	Tk_ResizeWindow((Tk_Window) winPtr, (unsigned) width,
		(unsigned) height);
    } else {
	return;
    }
}

/*
 *--------------------------------------------------------------
 *
 * 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)
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    XSizeHints *hintsPtr;

    wmPtr->flags &= ~WM_UPDATE_SIZE_HINTS;

    hintsPtr = XAllocSizeHints();
    if (hintsPtr == NULL) {
	return;
    }

    /*
     * Compute the pixel-based sizes for the various fields in the
     * size hints structure, based on the grid-based sizes in
     * our structure.
     */

    if (wmPtr->gridWin != NULL) {
	hintsPtr->base_width = winPtr->reqWidth
		- (wmPtr->reqGridWidth * wmPtr->widthInc);
	if (hintsPtr->base_width < 0) {
	    hintsPtr->base_width = 0;
	}
	hintsPtr->base_height = winPtr->reqHeight
		- (wmPtr->reqGridHeight * wmPtr->heightInc);
	if (hintsPtr->base_height < 0) {
	    hintsPtr->base_height = 0;
	}
	hintsPtr->min_width = hintsPtr->base_width
		+ (wmPtr->minWidth * wmPtr->widthInc);
	hintsPtr->min_height = hintsPtr->base_height
		+ (wmPtr->minHeight * wmPtr->heightInc);
	hintsPtr->max_width = hintsPtr->base_width
		+ (wmPtr->maxWidth * wmPtr->widthInc);
	hintsPtr->max_height = hintsPtr->base_height
		+ (wmPtr->maxHeight * wmPtr->heightInc);
    } else {
	hintsPtr->min_width = wmPtr->minWidth;
	hintsPtr->min_height = wmPtr->minHeight;
	hintsPtr->max_width = wmPtr->maxWidth;
	hintsPtr->max_height = wmPtr->maxHeight;
	hintsPtr->base_width = 0;
	hintsPtr->base_height = 0;
    }
    hintsPtr->width_inc = wmPtr->widthInc;
    hintsPtr->height_inc = wmPtr->heightInc;
    hintsPtr->min_aspect.x = wmPtr->minAspect.x;
    hintsPtr->min_aspect.y = wmPtr->minAspect.y;
    hintsPtr->max_aspect.x = wmPtr->maxAspect.x;
    hintsPtr->max_aspect.y = wmPtr->maxAspect.y;
    hintsPtr->win_gravity = wmPtr->gravity;
    hintsPtr->flags = wmPtr->sizeHintsFlags | PMinSize | PMaxSize;

    /*
     * If the window isn't supposed to be resizable, then set the
     * minimum and maximum dimensions to be the same.
     */

    if (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) {
	if (wmPtr->width >= 0) {
	    hintsPtr->min_width = wmPtr->width;
	} else {
	    hintsPtr->min_width = winPtr->reqWidth;
	}
	hintsPtr->max_width = hintsPtr->min_width;
    }
    if (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) {
	if (wmPtr->height >= 0) {
	    hintsPtr->min_height = wmPtr->height;
	} else {
	    hintsPtr->min_height = winPtr->reqHeight;
	}
	hintsPtr->max_height = hintsPtr->min_height;
    }

    XSetWMNormalHints(winPtr->display, winPtr->window, hintsPtr);

    XFree((char *) hintsPtr);
}

/*
 *--------------------------------------------------------------
 *
 * 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. */
{
    register WmInfo *wmPtr = winPtr->wmInfoPtr;
    int x, y, width, height, flags;
    char *end;
    register 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;
	}
	x = strtol(p+1, &end, 10);
	p = end;
	if (*p == '-') {
	    flags |= WM_NEGATIVE_Y;
	} else if (*p != '+') {
	    goto error;
	}
	y = strtol(p+1, &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)) == 0) {
	    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)))) {
	wmPtr->x = x;
	wmPtr->y = y;
	flags |= WM_MOVE_PENDING;
    }
    wmPtr->flags = flags;

    if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
	Tk_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
	wmPtr->flags |= WM_UPDATE_PENDING;
    }
    return TCL_OK;

    error:
    Tcl_AppendResult(interp, "bad geometry specifier \"",
	    string, "\"", (char *) 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;
    register 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_HIERARCHY) {
	    if (!(Tk_IsEmbedded(winPtr))) {
	    	x += winPtr->wmInfoPtr->xInParent;
	    	y += winPtr->wmInfoPtr->yInParent;
	    	break;
	    } else {
	        TkWindow *otherPtr;

		otherPtr = TkpGetOtherWindow(winPtr);
		if (otherPtr != NULL) {
		    /*
		     * 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;

		} else {
		    Point theOffset;

		    if (gMacEmbedHandler->getOffsetProc != NULL) {
		        /*
		         * 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;

		        gMacEmbedHandler->getOffsetProc((Tk_Window) winPtr, &theOffset);

		        x += theOffset.h;
		        y += theOffset.v;
		    }
		    break;
		}
	    }
	}
	if (winPtr->flags & TK_TOP_HIERARCHY) {
	    break; /* Punt */
	}
	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;
    register 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 = TkMacGetXWindow(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;
	            }
	    	}
	    }


	    /*
	     * NOTE: 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_HIERARCHY)) {
		    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) */
{
    register 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;
	    	}
	    }

	    /*
	     * NOTE: 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_HIERARCHY)) {
		    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,
	    (Tk_ErrorProc *) NULL, (ClientData) NULL);
    status = XGetGeometry(winPtr->display, wmPtr->vRoot,
	    &dummy2, &wmPtr->vRootX, &wmPtr->vRootY,
	    &wmPtr->vRootWidth, &wmPtr->vRootHeight, &bd, &dummy);
    if (wmTracing) {
	printf("UpdateVRootGeometry: x = %d, y = %d, width = %d, ",
		wmPtr->vRootX, wmPtr->vRootY, wmPtr->vRootWidth);
	printf("height = %d, status = %d\n", 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_HIERARCHY)) {
	winPtr = winPtr->parentPtr;
    }
    wmPtr = winPtr->wmInfoPtr;
    if (wmPtr == NULL) {
	return; /* Punt */
    }

    /*
     * 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;
    register 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)) == 0) {
	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, (ClientData) winPtr);
	}
	UpdateGeometryInfo((ClientData) winPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmProtocolEventProc --
 *
 *	This procedure is called by the Tk_HandleEvent whenever a
 *	ClientMessage event arrives whose type is "WM_PROTOCOLS".
 *	This procedure handles the message from the window manager
 *	in an appropriate fashion.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Depends on what sort of handler, if any, was set up for the
 *	protocol.
 *
 *----------------------------------------------------------------------
 */

void
TkWmProtocolEventProc(
    TkWindow *winPtr,		/* Window to which the event was sent. */
    XEvent *eventPtr)		/* X event. */
{
    WmInfo *wmPtr;
    register ProtocolHandler *protPtr;
    Tcl_Interp *interp;
    Atom protocol;
    int result;

    wmPtr = winPtr->wmInfoPtr;
    if (wmPtr == NULL) {
	return;
    }
    protocol = (Atom) eventPtr->xclient.data.l[0];
    for (protPtr = wmPtr->protPtr; protPtr != NULL;
				   protPtr = protPtr->nextPtr) {
	if (protocol == protPtr->protocol) {
	    Tcl_Preserve((ClientData) protPtr);
            interp = protPtr->interp;
            Tcl_Preserve((ClientData) interp);
	    result = Tcl_GlobalEval(interp, protPtr->command);
	    if (result != TCL_OK) {
		Tcl_AddErrorInfo(interp, "\n    (command for \"");
		Tcl_AddErrorInfo(interp,
			Tk_GetAtomName((Tk_Window) winPtr, protocol));
		Tcl_AddErrorInfo(interp, "\" window manager protocol)");
		Tk_BackgroundError(interp);
	    }
            Tcl_Release((ClientData) interp);
	    Tcl_Release((ClientData) protPtr);
	    return;
	}
    }

    /*
     * No handler was present for this protocol.  If this is a
     * WM_DELETE_WINDOW message then just destroy the window.
     */

    if (protocol == Tk_InternAtom((Tk_Window) winPtr, "WM_DELETE_WINDOW")) {
	Tk_DestroyWindow((Tk_Window) winPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmStackorderToplevelWrapperMap --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */
void
TkWmStackorderToplevelWrapperMap(winPtr, table)
    TkWindow *winPtr;				/* TkWindow to recurse on */
    Tcl_HashTable *table;			/* Maps mac window to TkWindow */
{
    TkWindow *childPtr;
    Tcl_HashEntry *hPtr;
    WindowPeek wrapper;
    int newEntry;

    if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr) &&
            !Tk_IsEmbedded(winPtr)) {
        wrapper = (WindowPeek) TkMacGetDrawablePort(winPtr->window);

        hPtr = Tcl_CreateHashEntry(table,
            (char *) wrapper, &newEntry);
        Tcl_SetHashValue(hPtr, winPtr);
    }

    for (childPtr = winPtr->childList; childPtr != NULL;
            childPtr = childPtr->nextPtr) {
        TkWmStackorderToplevelWrapperMap(childPtr, 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(parentPtr)
    TkWindow *parentPtr;		/* Parent toplevel window. */
{
    WindowPeek frontWindow;
    TkWindow *childWinPtr, **windows, **window_ptr;
    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);
    TkWmStackorderToplevelWrapperMap(parentPtr, &table);

    windows = (TkWindow **) 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] = (TkWindow *) Tcl_GetHashValue(hPtr);
        windows[1] = NULL;
        goto done;
    }

    if (TkMacHaveAppearance() >= 0x110) {
        frontWindow = (WindowPeek) FrontNonFloatingWindow();
    } else {
    	frontWindow = (WindowPeek) FrontWindow();
    }

    if (frontWindow == NULL) {
        ckfree((char *) windows);
        windows = NULL;
    } else {
    	window_ptr = windows + table.numEntries;
    	*window_ptr-- = NULL;
	    while (frontWindow != NULL) {
		    hPtr = Tcl_FindHashEntry(&table, (char *) frontWindow);
            if (hPtr != NULL) {
                childWinPtr = (TkWindow *) Tcl_GetHashValue(hPtr);
                *window_ptr-- = childWinPtr;
            }
			frontWindow = frontWindow->nextWindow;
	    }
        if (window_ptr != (windows-1))
            Tcl_Panic("num matched toplevel windows does not equal num children");
    }

    done:
    Tcl_DeleteHashTable(&table);
    return windows;
}

/*
 *----------------------------------------------------------------------
 *
 * 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;
    WindowPeek macWindow, otherMacWindow, frontWindow;

    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 = (WindowPeek) TkMacGetDrawablePort(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 = (WindowPeek) TkMacGetDrawablePort(otherPtr->window);
    } else {
	otherMacWindow = NULL;
    }

    if (TkMacHaveAppearance() >= 0x110) {
        frontWindow = (WindowPeek) FrontNonFloatingWindow();
    } else {
    frontWindow = (WindowPeek) FrontWindow();
    }

    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 visable then
	     * we also make it the active window.
	     */

	    if (wmPtr->hints.initial_state == WithdrawnState) {
		BringToFront((WindowPtr) macWindow);
	    } else {
		SelectWindow((WindowPtr)  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 &&
		    frontWindow->nextWindow != otherMacWindow) {
		frontWindow = frontWindow->nextWindow;
	    }
	    if (frontWindow != NULL) {
		SendBehind((WindowPtr) macWindow, (WindowPtr) frontWindow);
	    }
	}
    } else {
	/*
	 * Send behind.  If it was in front find another window to make active.
	 */
	if (macWindow == frontWindow) {
	    if (macWindow->nextWindow != NULL) {
		SelectWindow((WindowPtr)  macWindow->nextWindow);
	    }
	}
	SendBehind((WindowPtr) macWindow, (WindowPtr) 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_HIERARCHY) {
	    break;
	}
    }
    if (topPtr->wmInfoPtr == NULL) {
	return;
    }

    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 = (TkWindow **) ckalloc((unsigned) ((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((char *) 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;
    TkWindow **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_HIERARCHY) {
	    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.
     */

    if (topPtr->wmInfoPtr == NULL) {
	return;
    }

    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. */
{
    Point where;

    GetMouse(&where);
    LocalToGlobal(&where);
    *xPtr = where.h;
    *yPtr = where.v;
}

/*
 *----------------------------------------------------------------------
 *
 * 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. */
    Rect *geometry)		/* On return the initial bounds. */
{
    int x, y;
    static int defaultX = 5;
    static int defaultY = 45;

    if (!(winPtr->wmInfoPtr->sizeHintsFlags & (USPosition | PPosition))) {
	/*
	 * We will override the program & hopefully place the
	 * window in a "better" location.
	 */

	if (((tcl_macQdPtr->screenBits.bounds.right - defaultX) < 30) ||
		((tcl_macQdPtr->screenBits.bounds.bottom - defaultY) < 30)) {
	    defaultX = 5;
	    defaultY = 45;
	}
	x = defaultX;
	y = defaultY;
	defaultX += 20;
	defaultY += 20;
    } else {
	x = winPtr->wmInfoPtr->x;
	y = winPtr->wmInfoPtr->y;
    }

    geometry->left = x;
    geometry->top = y;
    geometry->right = x + winPtr->changes.width;
    geometry->bottom = y + winPtr->changes.height;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacResizable --
 *
 *	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
TkMacResizable(
    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;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacGrowToplevel --
 *
 *	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
TkMacGrowToplevel(
    WindowPtr whichWindow,
    Point start)
{
    Point where = start;
    TkDisplay *dispPtr;

    GlobalToLocal(&where);
    if (where.h > (whichWindow->portRect.right - 16) &&
	    where.v > (whichWindow->portRect.bottom - 16)) {

	Window window;
	TkWindow *winPtr;
	WmInfo *wmPtr;
	Rect bounds;
	long growResult;

	window = TkMacGetXWindow(whichWindow);
	dispPtr = TkGetDisplayList();
	winPtr = (TkWindow *) Tk_IdToWindow(dispPtr->display, window);
	wmPtr = winPtr->wmInfoPtr;

	/* TODO: handle grid size options. */
	if ((wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) &&
		(wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE)) {
	    return false;
	}
	if (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) {
	    bounds.left = bounds.right = winPtr->changes.width;
	} else {
	    bounds.left = (wmPtr->minWidth < 64) ? 64 : wmPtr->minWidth;
	    bounds.right = (wmPtr->maxWidth < 64) ? 64 : wmPtr->maxWidth;
	}
	if (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) {
	    bounds.top = bounds.bottom = winPtr->changes.height;
	} else {
	    bounds.top = (wmPtr->minHeight < 64) ? 64 : wmPtr->minHeight;
	    bounds.bottom = (wmPtr->maxHeight < 64) ? 64 : wmPtr->maxHeight;
	}

	growResult = GrowWindow(whichWindow, start, &bounds);

	if (growResult != 0) {
	    SizeWindow(whichWindow,
		    LoWord(growResult), HiWord(growResult), true);
	    SetPort(whichWindow);
	    InvalRect(&whichWindow->portRect);	/* TODO: may not be needed */
	    TkMacInvalClipRgns(winPtr);
	    TkGenWMConfigureEvent((Tk_Window) winPtr, -1, -1,
		    (int) LoWord(growResult), (int) HiWord(growResult),
		    TK_SIZE_CHANGED);
	    return true;
	}
	return false;
    }
    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,
    CONST char *title)
{
    Str255  pTitle;
    GWorldPtr macWin;
    int destWrote;

    if (Tk_IsEmbedded(winPtr)) {
        return;
    }
    Tcl_UtfToExternal(NULL, NULL, title,
	    strlen(title), 0, NULL,
	    (char *) &pTitle[1],
	    255, NULL, &destWrote, NULL); /* Internalize native */
    pTitle[0] = destWrote;

    macWin = TkMacGetDrawablePort(winPtr->window);

    SetWTitle((WindowPtr) macWin, pTitle);
}

void
TkGenWMDestroyEvent(
    Tk_Window tkwin)
{
    XEvent event;

    event.xany.serial = Tk_Display(tkwin)->request;
    event.xany.send_event = False;
    event.xany.display = Tk_Display(tkwin);

    event.xclient.window = Tk_WindowId(tkwin);
    event.xclient.type = ClientMessage;
    event.xclient.message_type = Tk_InternAtom(tkwin, "WM_PROTOCOLS");
    event.xclient.format = 32;
    event.xclient.data.l[0] = Tk_InternAtom(tkwin, "WM_DELETE_WINDOW");
    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
}

/*
 *----------------------------------------------------------------------
 *
 * TkGenWMConfigureEvent --
 *
 *	Generate a ConfigureNotify event for Tk.  Depending on the
 *	value of flag the values of width/height, x/y, or both may
 *	be changed.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A ConfigureNotify event is sent to Tk.
 *
 *----------------------------------------------------------------------
 */

void
TkGenWMConfigureEvent(
    Tk_Window tkwin,
    int x,
    int y,
    int width,
    int height,
    int flags)
{
    XEvent event;
    WmInfo *wmPtr;
    TkWindow *winPtr = (TkWindow *) tkwin;

    if (tkwin == NULL) {
	return;
    }

    event.type = ConfigureNotify;
    event.xconfigure.serial = Tk_Display(tkwin)->request;
    event.xconfigure.send_event = False;
    event.xconfigure.display = Tk_Display(tkwin);
    event.xconfigure.event = Tk_WindowId(tkwin);
    event.xconfigure.window = Tk_WindowId(tkwin);
    event.xconfigure.border_width = winPtr->changes.border_width;
    event.xconfigure.override_redirect = winPtr->atts.override_redirect;
    if (winPtr->changes.stack_mode == Above) {
	event.xconfigure.above = winPtr->changes.sibling;
    } else {
	event.xconfigure.above = None;
    }

    if (flags & TK_LOCATION_CHANGED) {
	event.xconfigure.x = x;
	event.xconfigure.y = y;
    } else {
	event.xconfigure.x = Tk_X(tkwin);
	event.xconfigure.y = Tk_Y(tkwin);
	x = Tk_X(tkwin);
	y = Tk_Y(tkwin);
    }
    if (flags & TK_SIZE_CHANGED) {
	event.xconfigure.width = width;
	event.xconfigure.height = height;
    } else {
	event.xconfigure.width = Tk_Width(tkwin);
	event.xconfigure.height = Tk_Height(tkwin);
	width = Tk_Width(tkwin);
	height = Tk_Height(tkwin);
    }

    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);

    /*
     * Update window manager information.
     */
    if (Tk_IsTopLevel(winPtr)) {
	wmPtr = winPtr->wmInfoPtr;
	if (flags & TK_LOCATION_CHANGED) {
	    wmPtr->x = x;
	    wmPtr->y = y;
	    wmPtr->flags &= ~(WM_NEGATIVE_X | WM_NEGATIVE_Y);
	}
	if ((flags & TK_SIZE_CHANGED) &&
		((width != Tk_Width(tkwin)) || (height != Tk_Height(tkwin)))) {
	    if ((wmPtr->width == -1) && (width == winPtr->reqWidth)) {
		/*
		 * Don't set external width, since the user didn't change it
		 * from what the widgets asked for.
		 */
	    } else {
		if (wmPtr->gridWin != NULL) {
		    wmPtr->width = wmPtr->reqGridWidth
			+ (width - winPtr->reqWidth)/wmPtr->widthInc;
		    if (wmPtr->width < 0) {
			wmPtr->width = 0;
		    }
		} else {
		    wmPtr->width = width;
		}
	    }
	    if ((wmPtr->height == -1) && (height == winPtr->reqHeight)) {
		/*
		 * Don't set external height, since the user didn't change it
		 * from what the widgets asked for.
		 */
	    } else {
		if (wmPtr->gridWin != NULL) {
		    wmPtr->height = wmPtr->reqGridHeight
			+ (height - winPtr->reqHeight)/wmPtr->heightInc;
		    if (wmPtr->height < 0) {
			wmPtr->height = 0;
		    }
		} else {
		    wmPtr->height = height;
		}
	    }
	    wmPtr->configWidth = width;
	    wmPtr->configHeight = height;
	}
    }

    /*
     * Now set up the changes structure.  Under X we wait for the
     * ConfigureNotify to set these values.  On the Mac we know imediatly that
     * this is what we want - so we just set them.  However, we need to
     * make sure the windows clipping region is marked invalid so the
     * change is visable to the subwindow.
     */
    winPtr->changes.x = x;
    winPtr->changes.y = y;
    winPtr->changes.width = width;
    winPtr->changes.height = height;
    TkMacInvalClipRgns(winPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * 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;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacGetXWindow --
 *
 *	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
TkMacGetXWindow(
    WindowRef macWinPtr)
{
    register 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);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacZoomToplevel --
 *
 *	The function is invoked when the user clicks in the zoom region
 *	of a Tk window.  The function will handle the mouse tracking
 *	for the interaction.  If the window is to be zoomed 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
TkMacZoomToplevel(
    WindowPtr whichWindow,	/* The Macintosh window to zoom. */
    Point where,		/* The current mouse position. */
    short zoomPart)		/* Either inZoomIn or inZoomOut */
{
    Window window;
    Tk_Window tkwin;
    Point location = {0, 0};
    int xOffset, yOffset;
    WmInfo *wmPtr;
    TkDisplay *dispPtr;

    SetPort(whichWindow);
    if (!TrackBox(whichWindow, where, zoomPart)) {
	return false;
    }

    /*
     * We should now zoom the window (as long as it's one of ours).  We
     * also need to generate an event to let Tk know that the window size
     * has changed.
     */
    window = TkMacGetXWindow(whichWindow);
    dispPtr = TkGetDisplayList();
    tkwin = Tk_IdToWindow(dispPtr->display, window);
    if (tkwin == NULL) {
	return false;
    }

    /*
     * The following block of code works around a bug in the window
     * definition for Apple's floating windows.  The zoom behavior is
     * broken - we must manually set the standard state (by default
     * it's something like 1x1) and we must swap the zoomPart manually
     * otherwise we always get the same zoomPart and nothing happens.
     */
    wmPtr = ((TkWindow *) tkwin)->wmInfoPtr;
    if (wmPtr->style >= floatProc && wmPtr->style <= floatSideZoomGrowProc) {
	if (zoomPart == inZoomIn) {
	    Rect zoomRect = tcl_macQdPtr->screenBits.bounds;
	    InsetRect(&zoomRect, 60, 60);
	    SetWindowStandardState(whichWindow, &zoomRect);
	    zoomPart = inZoomOut;
	} else {
	    zoomPart = inZoomIn;
	}
    }

    ZoomWindow(whichWindow, zoomPart, false);
    InvalRect(&whichWindow->portRect);
    TkMacInvalClipRgns((TkWindow *) tkwin);

    LocalToGlobal(&location);
    TkMacWindowOffset(whichWindow, &xOffset, &yOffset);
    location.h -= xOffset;
    location.v -= yOffset;
    TkGenWMConfigureEvent(tkwin, location.h, location.v,
	    whichWindow->portRect.right - whichWindow->portRect.left,
	    whichWindow->portRect.bottom - whichWindow->portRect.top,
	    TK_BOTH_CHANGED);
    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
TkUnsupported1Cmd(
    ClientData clientData,	/* Main window associated with
				 * interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int argc,			/* Number of arguments. */
    CONST char **argv)		/* Argument strings. */
{
    Tk_Window tkwin = (Tk_Window) clientData;
    TkWindow *winPtr;
    register WmInfo *wmPtr;
    int c;
    size_t length;

    if (argc < 3) {
	wrongNumArgs:
	Tcl_AppendResult(interp, "wrong # args: should be \"",
		argv[0], " option window ?arg ...?\"", (char *) NULL);
	return TCL_ERROR;
    }

    winPtr = (TkWindow *) Tk_NameToWindow(interp, argv[2], tkwin);
    if (winPtr == NULL) {
	return TCL_ERROR;
    }
    if (!Tk_IsTopLevel(winPtr)) {
	Tcl_AppendResult(interp, "window \"", winPtr->pathName,
		"\" isn't a top-level window", (char *) NULL);
	return TCL_ERROR;
    }
    wmPtr = winPtr->wmInfoPtr;
    c = argv[1][0];
    length = strlen(argv[1]);
    if ((c == 's')  && (strncmp(argv[1], "style", length) == 0)) {
        if (TkMacHaveAppearance() >= 0x110) {
	    if ((argc < 3) || (argc > 5)) {
	        Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		        argv[0], " style window ?windowStyle?\"",
		        " or \"", argv[0], "style window ?class attributes?\"",
		        (char *) NULL);
	        return TCL_ERROR;
	    }
	} else {
	    if ((argc != 3) && (argc != 4)) {
	        Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		        argv[0], " style window ?windowStyle?\"",
		        (char *) NULL);
	        return TCL_ERROR;
	    }
	}

	if (argc == 3) {
	    int appearanceSpec = 0;

	    switch (wmPtr->style) {
	        case -1:
	            appearanceSpec = 1;
	            break;
		case noGrowDocProc:
		case documentProc:
		    Tcl_SetResult(interp, "documentProc", TCL_STATIC);
		    break;
		case dBoxProc:
		    Tcl_SetResult(interp, "dBoxProc", TCL_STATIC);
		    break;
		case plainDBox:
		    Tcl_SetResult(interp, "plainDBox", TCL_STATIC);
		    break;
		case altDBoxProc:
		    Tcl_SetResult(interp, "altDBoxProc", TCL_STATIC);
		    break;
		case movableDBoxProc:
		    Tcl_SetResult(interp, "movableDBoxProc", TCL_STATIC);
		    break;
		case zoomDocProc:
		case zoomNoGrow:
		    Tcl_SetResult(interp, "zoomDocProc", TCL_STATIC);
		    break;
		case rDocProc:
		    Tcl_SetResult(interp, "rDocProc", TCL_STATIC);
		    break;
		case floatProc:
		case floatGrowProc:
		    Tcl_SetResult(interp, "floatProc", TCL_STATIC);
		    break;
		case floatZoomProc:
		case floatZoomGrowProc:
		    Tcl_SetResult(interp, "floatZoomProc", TCL_STATIC);
		    break;
		case floatSideProc:
		case floatSideGrowProc:
		    Tcl_SetResult(interp, "floatSideProc", TCL_STATIC);
		    break;
		case floatSideZoomProc:
		case floatSideZoomGrowProc:
		    Tcl_SetResult(interp, "floatSideZoomProc", TCL_STATIC);
		    break;
		default:
		    Tcl_Panic("invalid style");
	    }
	    if (appearanceSpec) {
	        Tcl_Obj *attributeList, *newResult;

	        switch (wmPtr->macClass) {
	            case kAlertWindowClass:
	                newResult = Tcl_NewStringObj("alert", -1);
	                break;
	            case kMovableAlertWindowClass:
	                newResult = Tcl_NewStringObj("moveableAlert", -1);
	                break;
	            case kModalWindowClass:
	                newResult = Tcl_NewStringObj("modal", -1);
	                break;
	            case kMovableModalWindowClass:
	                newResult = Tcl_NewStringObj("moveableModal", -1);
	                break;
	            case kFloatingWindowClass:
	                newResult = Tcl_NewStringObj("floating", -1);
	                break;
	            case kDocumentWindowClass:
	                newResult = Tcl_NewStringObj("document", -1);
	                break;
                    default:
                        Tcl_Panic("invalid class");
                }

 	        attributeList = Tcl_NewListObj(0, NULL);
                if (wmPtr->attributes == kWindowNoAttributes) {
                    Tcl_ListObjAppendElement(interp, attributeList,
                            Tcl_NewStringObj("none", -1));
                } else if (wmPtr->attributes == kWindowStandardDocumentAttributes) {
		    Tcl_ListObjAppendElement(interp, attributeList, 
                            Tcl_NewStringObj("standardDocument", -1));
                } else if (wmPtr->attributes == kWindowStandardFloatingAttributes) {
		    Tcl_ListObjAppendElement(interp, attributeList, 
                            Tcl_NewStringObj("standardFloating", -1));
                } else {
                    if (wmPtr->attributes & kWindowCloseBoxAttribute) {
                        Tcl_ListObjAppendElement(interp, attributeList,
                                Tcl_NewStringObj("closeBox", -1));
                    }
                    if (wmPtr->attributes & kWindowHorizontalZoomAttribute) {
                        Tcl_ListObjAppendElement(interp, attributeList,
                                Tcl_NewStringObj("horizontalZoom", -1));
                    }
                    if (wmPtr->attributes & kWindowVerticalZoomAttribute) {
                        Tcl_ListObjAppendElement(interp, attributeList,
                                Tcl_NewStringObj("verticalZoom", -1));
                    }
                    if (wmPtr->attributes & kWindowCollapseBoxAttribute) {
                        Tcl_ListObjAppendElement(interp, attributeList,
                                Tcl_NewStringObj("collapseBox", -1));
                    }
                    if (wmPtr->attributes & kWindowResizableAttribute) {
                        Tcl_ListObjAppendElement(interp, attributeList,
                                Tcl_NewStringObj("resizable", -1));
                    }
                    if (wmPtr->attributes & kWindowSideTitlebarAttribute) {
                        Tcl_ListObjAppendElement(interp, attributeList,
                                Tcl_NewStringObj("sideTitlebar", -1));
                    }
                    if (wmPtr->attributes & kWindowNoUpdatesAttribute) {
                        Tcl_ListObjAppendElement(interp, attributeList,
                                Tcl_NewStringObj("noUpdates", -1));
                    }
                    if (wmPtr->attributes & kWindowNoActivatesAttribute) {
                        Tcl_ListObjAppendElement(interp, attributeList,
                                Tcl_NewStringObj("noActivates", -1));
                    }
                }
                Tcl_ListObjAppendElement(interp, newResult, attributeList);
                Tcl_SetObjResult(interp, newResult);
	    }
	    return TCL_OK;
        } else if (argc == 4) {
	    if (strcmp(argv[3], "documentProc") == 0) {
		wmPtr->style = documentProc;
	    } else if (strcmp(argv[3], "noGrowDocProc") == 0) {
		wmPtr->style = documentProc;
	    } else if (strcmp(argv[3], "dBoxProc") == 0) {
		wmPtr->style = dBoxProc;
	    } else if (strcmp(argv[3], "plainDBox") == 0) {
		wmPtr->style = plainDBox;
	    } else if (strcmp(argv[3], "altDBoxProc") == 0) {
		wmPtr->style = altDBoxProc;
	    } else if (strcmp(argv[3], "movableDBoxProc") == 0) {
		wmPtr->style = movableDBoxProc;
	    } else if (strcmp(argv[3], "zoomDocProc") == 0) {
		wmPtr->style = zoomDocProc;
	    } else if (strcmp(argv[3], "zoomNoGrow") == 0) {
		wmPtr->style = zoomNoGrow;
	    } else if (strcmp(argv[3], "rDocProc") == 0) {
		wmPtr->style = rDocProc;
	    } else if (strcmp(argv[3], "floatProc") == 0) {
		wmPtr->style = floatGrowProc;
	    } else if (strcmp(argv[3], "floatGrowProc") == 0) {
		wmPtr->style = floatGrowProc;
	    } else if (strcmp(argv[3], "floatZoomProc") == 0) {
		wmPtr->style = floatZoomGrowProc;
	    } else if (strcmp(argv[3], "floatZoomGrowProc") == 0) {
		wmPtr->style = floatZoomGrowProc;
	    } else if (strcmp(argv[3], "floatSideProc") == 0) {
		wmPtr->style = floatSideGrowProc;
	    } else if (strcmp(argv[3], "floatSideGrowProc") == 0) {
		wmPtr->style = floatSideGrowProc;
	    } else if (strcmp(argv[3], "floatSideZoomProc") == 0) {
		wmPtr->style = floatSideZoomGrowProc;
	    } else if (strcmp(argv[3], "floatSideZoomGrowProc") == 0) {
		wmPtr->style = floatSideZoomGrowProc;
	    } else {
		Tcl_AppendResult(interp, "bad style: should be documentProc, ",
			"dBoxProc, plainDBox, altDBoxProc, movableDBoxProc, ",
			"zoomDocProc, rDocProc, floatProc, floatZoomProc, ",
			"floatSideProc, or floatSideZoomProc",
			(char *) NULL);
		return TCL_ERROR;
	    }
	} else if (argc == 5) {
	    int oldClass = wmPtr->macClass;
	    int oldAttributes = wmPtr->attributes;

	    if (strcmp(argv[3], "alert") == 0) {
	        wmPtr->macClass = kAlertWindowClass;
	    } else if (strcmp(argv[3], "moveableAlert") == 0) {
	        wmPtr->macClass = kMovableAlertWindowClass;
	    } else if (strcmp(argv[3], "modal") == 0) {
	        wmPtr->macClass = kModalWindowClass;
	    } else if (strcmp(argv[3], "moveableModal") == 0) {
	        wmPtr->macClass = kMovableModalWindowClass;
	    } else if (strcmp(argv[3], "floating") == 0) {
	        wmPtr->macClass = kFloatingWindowClass;
	    } else if (strcmp(argv[3], "document") == 0) {
	        wmPtr->macClass = kDocumentWindowClass;
	    } else {
	        wmPtr->macClass = oldClass;
	        Tcl_AppendResult(interp, "bad class: should be alert, ",
	    	        "moveableAlert, modal, moveableModal, floating, ",
	    	        "or document",
		        (char *) NULL);
	        return TCL_ERROR;
	    }

	    if (strcmp(argv[4], "none") == 0) {
	        wmPtr->attributes = kWindowNoAttributes;
	    } else if (strcmp(argv[4], "standardDocument") == 0) {
	        wmPtr->attributes = kWindowStandardDocumentAttributes;
	    } else if (strcmp(argv[4], "standardFloating") == 0) {
	        wmPtr->attributes = kWindowStandardFloatingAttributes;
	    } else {
	        int foundOne = 0;
	        int attrArgc, i;
	        CONST char **attrArgv = NULL;

	        if (Tcl_SplitList(interp, argv[4], &attrArgc, &attrArgv) != TCL_OK) {
	            wmPtr->macClass = oldClass;
	            Tcl_AppendResult(interp, "Ill-formed attributes list: \"",
			    argv[4], "\".", (char *) NULL);
	            return TCL_ERROR;
	        }

	        wmPtr->attributes = kWindowNoAttributes;

	        for (i = 0; i < attrArgc; i++) {
	            if ((*attrArgv[i] == 'c')
	                    && (strcmp(attrArgv[i], "closeBox")  == 0)) {
	                wmPtr->attributes |= kWindowCloseBoxAttribute;
	                foundOne = 1;
	            } else if ((*attrArgv[i] == 'h')
	                    && (strcmp(attrArgv[i], "horizontalZoom")  == 0)) {
	                wmPtr->attributes |= kWindowHorizontalZoomAttribute;
	                foundOne = 1;
	            } else if ((*attrArgv[i] == 'v')
	                    && (strcmp(attrArgv[i], "verticalZoom")  == 0)) {
	                wmPtr->attributes |= kWindowVerticalZoomAttribute;
	                foundOne = 1;
	            } else if ((*attrArgv[i] == 'c')
	                    && (strcmp(attrArgv[i], "collapseBox")  == 0)) {
	                wmPtr->attributes |= kWindowCollapseBoxAttribute;
	                foundOne = 1;
	            } else if ((*attrArgv[i] == 'r')
	                    && (strcmp(attrArgv[i], "resizable")  == 0)) {
	                wmPtr->attributes |= kWindowResizableAttribute;
	                foundOne = 1;
	            } else if ((*attrArgv[i] == 's')
	                    && (strcmp(attrArgv[i], "sideTitlebar")  == 0)) {
	                wmPtr->attributes |= kWindowSideTitlebarAttribute;
	                foundOne = 1;
	            } else {
	                foundOne = 0;
	                break;
	            }
	        }

	        if (attrArgv != NULL) {
	            ckfree ((char *) attrArgv);
	        }

	        if (foundOne != 1) {
	            wmPtr->macClass = oldClass;
	            wmPtr->attributes = oldAttributes;

	            Tcl_AppendResult(interp, "bad attribute: \"", argv[4],
	                    "\", should be standardDocument, ",
	    	            "standardFloating, or some combination of ",
	    	            "closeBox, horizontalZoom, verticalZoom, ",
	    	            "collapseBox, resizable, or sideTitlebar.",
		            (char *) NULL);
	            return TCL_ERROR;
	        }
	    }

	    wmPtr->style = -1;
	}
    } else {
	Tcl_AppendResult(interp, "unknown or ambiguous option \"", argv[1],
		"\": must be style",
		(char *) NULL);
	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. */
{
    if (transient) {
	((TkWindow *) tkwin)->wmInfoPtr->style = plainDBox;
    } else {
	((TkWindow *) tkwin)->wmInfoPtr->style = floatProc;
	((TkWindow *) tkwin)->wmInfoPtr->flags |= WM_WIDTH_NOT_RESIZABLE;
	((TkWindow *) tkwin)->wmInfoPtr->flags |= WM_HEIGHT_NOT_RESIZABLE;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacMakeRealWindowExist --
 *
 *	This function finally creates the real Macintosh window that
 *	the Mac actually understands.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	A new Macintosh toplevel is created.
 *
 *----------------------------------------------------------------------
 */

void
TkMacMakeRealWindowExist(
    TkWindow *winPtr)	/* Tk window. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    WindowRef newWindow = NULL;
    MacDrawable *macWin;
    Rect geometry = {0,0,0,0};
    Tcl_HashEntry *valueHashPtr;
    int new;
    TkMacWindowList *listPtr;

    if (TkMacHostToplevelExists(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;

	contWinPtr = TkpGetOtherWindow(winPtr);
	if (contWinPtr != NULL) {
	    TkMacMakeRealWindowExist(contWinPtr->privatePtr->toplevel->winPtr);
	    macWin->flags |= TK_HOST_EXISTS;
	    return;
	} else if (gMacEmbedHandler != NULL) {
	    if (gMacEmbedHandler->containerExistProc != NULL) {
	        if (gMacEmbedHandler->containerExistProc((Tk_Window) winPtr) != TCL_OK) {
	           Tcl_Panic("ContainerExistProc could not make container");
	       }
	    }
	    return;
	} else {
	    Tcl_Panic("TkMacMakeRealWindowExist could not find container");
	}

	/*
	 * NOTE: Here we should handle out of process embedding.
	 */

    }

    InitialWindowBounds(winPtr, &geometry);

    if (TkMacHaveAppearance() >= 0x110 && wmPtr->style == -1) {
        OSStatus err;
        /*
         * There seems to be a bug in CreateNewWindow: If I set the
         * window geometry to be the too small for the structure region,
         * then the whole window is positioned incorrectly.
         * Adding this here makes the positioning work, and the size will
         * get overwritten when you actually map the contents of the window.
         */

        geometry.right += 64;
        geometry.bottom += 24;
        err = CreateNewWindow(wmPtr->macClass, wmPtr->attributes,
                &geometry, &newWindow);
        if (err != noErr) {
            newWindow = NULL;
        }

    } else {
    newWindow = NewCWindow(NULL, &geometry, "\ptemp", false,
	    (short) wmPtr->style, (WindowRef) -1, true, 0);
    }

    if (newWindow == NULL) {
	Tcl_Panic("couldn't allocate new Mac window");
    }

    /*
     * Add this window to the list of toplevel windows.
     */

    listPtr = (TkMacWindowList *) ckalloc(sizeof(TkMacWindowList));
    listPtr->nextPtr = tkMacWindowListPtr;
    listPtr->winPtr = winPtr;
    tkMacWindowListPtr = listPtr;

    macWin->portPtr = (GWorldPtr) newWindow;
    tkMacMoveWindow(newWindow, (int) geometry.left, (int) geometry.top);
    SetPort((GrafPtr) newWindow);

    if (!windowHashInit) {
	Tcl_InitHashTable(&windowTable, TCL_ONE_WORD_KEYS);
	windowHashInit = true;
    }
    valueHashPtr = Tcl_CreateHashEntry(&windowTable,
	    (char *) newWindow, &new);
    if (!new) {
	Tcl_Panic("same macintosh window allocated twice!");
    }
    Tcl_SetHashValue(valueHashPtr, macWin);

    macWin->flags |= TK_HOST_EXISTS;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacRegisterOffScreenWindow --
 *
 *	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
TkMacRegisterOffScreenWindow(
    Window window,	/* Window structure. */
    GWorldPtr portPtr)	/* Pointer to a Mac GWorld. */
{
    WindowRef newWindow = NULL;
    MacDrawable *macWin;
    Tcl_HashEntry *valueHashPtr;
    int new;

    macWin = (MacDrawable *) window;
    if (!windowHashInit) {
	Tcl_InitHashTable(&windowTable, TCL_ONE_WORD_KEYS);
	windowHashInit = true;
    }
    valueHashPtr = Tcl_CreateHashEntry(&windowTable,
	    (char *) portPtr, &new);
    if (!new) {
	Tcl_Panic("same macintosh window allocated twice!");
    }
    Tcl_SetHashValue(valueHashPtr, macWin);
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacUnregisterMacWindow --
 *
 *	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
TkMacUnregisterMacWindow(
    GWorldPtr portPtr)	/* Pointer to a Mac GWorld. */
{
    if (!windowHashInit) {
	Tcl_Panic("TkMacUnregisterMacWindow: unmapping before inited");;
    }
    Tcl_DeleteHashEntry(Tcl_FindHashEntry(&windowTable,
	(char *) portPtr));
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacSetScrollbarGrow --
 *
 *	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
TkMacSetScrollbarGrow(
    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;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacGetScrollbarGrowWindow --
 *
 *	Tests to see if a given window's toplevel window contains a
 *	scrollbar that will draw the GrowIcon for the window.
 *
 * Results:
 *	Boolean value.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

TkWindow *
TkMacGetScrollbarGrowWindow(
    TkWindow *winPtr)	/* Tk window. */
{
    TkWindow *scrollWinPtr;

    if (winPtr == NULL) {
	return NULL;
    }
    scrollWinPtr =
	winPtr->privatePtr->toplevel->winPtr->wmInfoPtr->scrollWinPtr;
    if (winPtr != NULL) {
	/*
	 * We need to confirm the window exists.
	 */
	if ((Tk_Window) scrollWinPtr !=
		Tk_IdToWindow(winPtr->display, winPtr->window)) {
	    scrollWinPtr = NULL;
	}
    }
    return scrollWinPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * 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_HIERARCHY)) {
	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(winPtr, state)
     TkWindow *winPtr;		/* Toplevel window to operate on. */
     int state;			/* One of IconicState, ZoomState, NormalState,
				 * or WithdrawnState. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    GWorldPtr macWin;

    wmPtr->hints.initial_state = state;
    if (wmPtr->flags & WM_NEVER_MAPPED) {
	return;
    }

    macWin = TkMacGetDrawablePort(winPtr->window);

    if (state == WithdrawnState) {
	Tk_UnmapWindow((Tk_Window) winPtr);
    } else if (state == IconicState) {
	Tk_UnmapWindow((Tk_Window) winPtr);
	if (TkMacHaveAppearance()) {
	    /*
	     * The window always gets unmapped.  However, if we can show the
	     * icon version of the window (collapsed) we make the window visable
	     * and then collapse it.
	     *
	     * TODO: This approach causes flashing!
	     */

	    if (IsWindowCollapsable((WindowRef) macWin)) {
		ShowWindow((WindowRef) macWin);
		CollapseWindow((WindowPtr) macWin, true);
	    }
	}
    } else if (state == NormalState) {
	Tk_MapWindow((Tk_Window) winPtr);
	if (TkMacHaveAppearance()) {
	    CollapseWindow((WindowPtr) macWin, false);
	}
    } else if (state == ZoomState) {
	/* TODO: need to support zoomed windows */
    }
}
/*
 *----------------------------------------------------------------------
 *
 * TkMacHaveAppearance --
 *
 *	Determine if the appearance manager is available on this Mac.
 *	We cache the result so future calls are fast.  Return a different
 *      value if 1.0.1 is present, since many interfaces were added in
 *      1.0.1
 *
 * Results:
 *	1 if the appearance manager is present, 2 if the appearance
 *      manager version is 1.0.1 or greater, 0 if it is not present.
 *
 * Side effects:
 *	Calls Gestalt to query system values.
 *
 *----------------------------------------------------------------------
 */

int
TkMacHaveAppearance()
{
    static initialized = false;
    static int TkMacHaveAppearance = 0;
    long response = 0;
    OSErr err = noErr;

    if (!initialized) {
	err = Gestalt(gestaltAppearanceAttr, &response);
	if (err == noErr) {
	    TkMacHaveAppearance = 1;
	}
/* even if AppearanceManager 1.1 routines are present,
we can't call them from 68K code, so we pretend
to be running Apperarance Mgr 1.0 */
#if !(GENERATING68K && !GENERATINGCFM)
	err = Gestalt(gestaltAppearanceVersion, &response);
#endif
	if (err == noErr) {
	    TkMacHaveAppearance = (int) response;
	}
    }

    return TkMacHaveAppearance;
}
@


1.25
log
@	* generic/tk3d.c:	All uses of 'panic' (the macro) changed
	* generic/tkBind.c:	to 'Tcl_Panic' (the function).  The #define
	* generic/tkBitmap.c:	of panic in tcl.h clearly states it is
	* generic/tkCanvArc.c:	deprecated in the comments.
	* generic/tkCanvBmap.c: [Tcl Patch 865264]
	* generic/tkCanvImg.c:
	* generic/tkCanvLine.c:
	* generic/tkCanvPoly.c:
	* generic/tkCanvText.c:
	* generic/tkCanvWind.c:
	* generic/tkColor.c:
	* generic/tkConfig.c:
	* generic/tkCursor.c:
	* generic/tkError.c:
	* generic/tkEvent.c:
	* generic/tkFocus.c:
	* generic/tkFont.c:
	* generic/tkFrame.c:
	* generic/tkGC.c:
	* generic/tkGrid.c:
	* generic/tkImgBmap.c:
	* generic/tkImgPhoto.c:
	* generic/tkImgUtil.c:
	* generic/tkMenu.c:
	* generic/tkObj.c:
	* generic/tkPack.c:
	* generic/tkPlace.c:
	* generic/tkRectOval.c:
	* generic/tkSelect.c:
	* generic/tkText.c:
	* generic/tkTextBTree.c:
	* generic/tkTextDisp.c:
	* generic/tkTextImage.c:
	* generic/tkTextIndex.c:
	* generic/tkTextMark.c:
	* generic/tkTextWind.c:
	* generic/tkVisual.c:
	* generic/tkWindow.c:
	* mac/tkMacAppInit.c:
	* mac/tkMacAppearanceStubs.c:
	* mac/tkMacButton.c:
	* mac/tkMacDraw.c:
	* mac/tkMacEmbed.c:
	* mac/tkMacFont.c:
	* mac/tkMacInit.c:
	* mac/tkMacMenus.c:
	* mac/tkMacPort.h:
	* mac/tkMacSubwindows.c:
	* mac/tkMacWm.c:
	* mac/tkMacXStubs.c:
	* macosx/tkMacOSXEmbed.c:
	* macosx/tkMacOSXFont.c:
	* macosx/tkMacOSXMenus.c:
	* macosx/tkMacOSXNotify.c:
	* macosx/tkMacOSXPort.h:
	* macosx/tkMacOSXSubwindows.c:
	* macosx/tkMacOSXWm.c:
	* macosx/tkMacOSXXStubs.c:
	* unix/tkUnix3d.c:
	* unix/tkUnixColor.c:
	* unix/tkUnixEmbed.c:
	* unix/tkUnixEvent.c:
	* unix/tkUnixFocus.c:
	* unix/tkUnixFont.c:
	* unix/tkUnixSelect.c:
	* unix/tkUnixSend.c:
	* unix/tkUnixWm.c:
	* win/tkWin3d.c:
	* win/tkWinButton.c:
	* win/tkWinColor.c:
	* win/tkWinDialog.c:
	* win/tkWinDraw.c:
	* win/tkWinEmbed.c:
	* win/tkWinFont.c:
	* win/tkWinPixmap.c:
	* win/tkWinPointer.c:
	* win/tkWinScrlbr.c:
	* win/tkWinWm.c:
	* win/tkWinX.c:
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.24 2003/02/09 07:51:04 hobbs Exp $
@


1.24
log
@2003-02-05  Fred Fish  <fnf@@intrinsity.com>

	* macosx/tkMacOSXWm.c (Tk_SetGrid): Fix precedence problem with
	* mac/tkMacWm.c (Tk_SetGrid):       '==' and '|'.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.23 2002/10/09 11:57:01 das Exp $
d2432 1
a2432 1
	    panic("TkWmStackorderToplevel failed");
d2487 1
a2487 1
		panic("winPtr window not found");
d2489 1
a2489 1
		panic("winPtr2 window not found");
d3012 1
a3012 1
	panic("recieved unwanted reparent event");
d3935 1
a3935 1
	panic("Tk_MoveToplevelWindow called with non-toplevel window");
d4146 1
a4146 1
            panic("num matched toplevel windows does not equal num children");
d5097 1
a5097 1
		    panic("invalid style");
d5122 1
a5122 1
                        panic("invalid class");
d5407 1
a5407 1
	           panic("ContainerExistProc could not make container");
d5412 1
a5412 1
	    panic("TkMacMakeRealWindowExist could not find container");
d5447 1
a5447 1
	panic("couldn't allocate new Mac window");
d5470 1
a5470 1
	panic("same macintosh window allocated twice!");
d5512 1
a5512 1
	panic("same macintosh window allocated twice!");
d5540 1
a5540 1
	panic("TkMacUnregisterMacWindow: unmapping before inited");;
@


1.24.2.1
log
@2005-11-16  Don Porter  <dgp@@users.sourceforge.net>

        *** 8.4.12 TAGGED FOR RELEASE ***

        * changes:      Update changes for 8.4.12 release

        * mac/tkMacWm.c:        Restored consistent error checking and
        * macosx/tkMacOSXWm.c:  messages among different platform's
        * tests/wm.test:        [wm grid] commands.  [Bug 1323972].
        * win/tkWinWm.c:
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.24 2003/02/09 07:51:04 hobbs Exp $
d1515 2
a1516 2
	if (widthInc <= 0) {
	    Tcl_SetResult(interp, "widthInc can't be <= 0", TCL_STATIC);
d1519 2
a1520 2
	if (heightInc <= 0) {
	    Tcl_SetResult(interp, "heightInc can't be <= 0", TCL_STATIC);
@


1.23
log
@	* generic/tkInt.decls(tkIntXlib): added XQueryTree declaration for
	mac & aqua, since it's now called from ParentXId via Tk_HandleEvent.
	* generic/tkIntXlibDecls.h:
	* generic/tkStubInit.c: regen.
	* mac/tkMacXStubs.c: added XQueryTree stub

	* mac/tkMacEmbed.c (TkpUseWindow): check that container window
	has -container option set (sync with other platforms).

	* mac/tkMacBitmap.c:
	* mac/tkMacFont.c:
	* mac/tkMacSend.c:
	* mac/tkMacTest.c:
	* mac/tkMacWm.c: CONSTification.

	* mac/tkMacProjects.sea.hqx: added tkStyle.c and tkUndo.c to
	tk library projects.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.22 2002/08/31 06:12:28 das Exp $
d2864 1
a2864 1
		    == PBaseSize|PResizeInc)) {
@


1.22
log
@	*** macosx-8-4-branch merged into the mainline [tcl patch #602770] ***

	* generic/tk.decls:
	* generic/tkInt.decls: added new "aqua" specific entries to the
	stubs tables. Changed all "unix" entries to "x11" to allow us to
	distinguish and build both "aqua" on MacOSX and "x11" on MacOSX.

	* generic/tk.h: added a #ifnded RESOURCE_INCLUDED so that tk.h can
	be passed to the resource compiler.

	* generic/tkCmds.c (Tk_TkObjCmd): added [tk windowingsystem]
	subcommand: returns "x11" when running on X11, "win32" on Windows,
	"classic" on MacOS9 and "aqua" on MacOSX Aqua (i.e. Carbon)

	* generic/tkFont.c (TkFontGetFirstTextLayout): new private function
	returning the first chunk of a Tk_TextLayout, i.e. until the first
	font change on the first line (or the whole first line if there is
	no such font change).

	* generic/tkMain.c: made Tcl_ThreadDataKey static

	* library/demos/puzzle.tcl: fixed button metrics for aqua

	* tests/cursor.test: check for presence of arrow cursor instead of
	heart cursor

	* xlib/xcolors.c: changed xColors static initialization to more
	standard C

	* macosx/Wish.pbproj/jingham.pbxuser (new):
	* macosx/Wish.pbproj/project.pbxproj (new): project for Apple's
	ProjectBuilder IDE.

	* macosx/Makefile (new): simple makefile for building the project
	from the command line via the ProjectBuilder tool 'pbxbuild'.

	* macosx/tkMacOSXAppInit.c (new): macosx specific AppInit looking
	for a AppMain.tcl file in its bundled Resources/Scripts folder. If
	present, argv[1] is set to that file and the Scripts folder is
	added to the auto_path. This allows tk apps to embed scripts within
	their bundle directory structure.

	* macosx/tkMacOSXInit.c (new): macosx adapted version of
	tkUnixInit.c: we initialize & cache the Carbon native encoding
	(e.g. 'macRoman') and try to find the tk script library files
	inside Tk packaged as a framework.

	* macosx/tkMacOSXNotify.c (new): new macosx specific merged
	Carbon/select-based notifier.

	* macosx/tkMacOSXEvent.c (new):
	* macosx/tkMacOSXEvent.h (new):
	* macosx/tkMacOSXKeyEvent.c (new):
	* macosx/tkMacOSXMouseEvent.c (new):
	* macosx/tkMacOSXWindowEvent.c (new): new macosx specific event
	handling functionality.

	* macosx/tkMacOSX.h (new):
	* macosx/tkMacOSXBitmap.c (new):
	* macosx/tkMacOSXButton.c (new):
	* macosx/tkMacOSXClipboard.c (new):
	* macosx/tkMacOSXColor.c (new):
	* macosx/tkMacOSXConfig.c (new):
	* macosx/tkMacOSXCursor.c (new):
	* macosx/tkMacOSXDefault.h (new):
	* macosx/tkMacOSXDialog.c (new):
	* macosx/tkMacOSXDraw.c (new):
	* macosx/tkMacOSXEmbed.c (new):
	* macosx/tkMacOSXFont.c (new):
	* macosx/tkMacOSXHLEvents.c (new):
	* macosx/tkMacOSXInt.h (new):
	* macosx/tkMacOSXKeyboard.c (new):
	* macosx/tkMacOSXMenu.c (new):
	* macosx/tkMacOSXMenubutton.c (new):
	* macosx/tkMacOSXMenus.c (new):
	* macosx/tkMacOSXPort.h (new):
	* macosx/tkMacOSXRegion.c (new):
	* macosx/tkMacOSXScale.c (new):
	* macosx/tkMacOSXScrlbr.c (new):
	* macosx/tkMacOSXSubwindows.c (new):
	* macosx/tkMacOSXTest.c (new):
	* macosx/tkMacOSXUtil.c (new):
	* macosx/tkMacOSXUtil.h (new):
	* macosx/tkMacOSXWm.c (new):
	* macosx/tkMacOSXWm.h (new):
	* macosx/tkMacOSXXStubs.c (new): macosx ports of classic mac Tk
	implementation in tk/mac.

	* macosx/tkMacOSXSend.c (new): only send to local interp
	implemented currently.

	* macosx/tkMacOSXDebug.h (new):
	* macosx/tkMacOSXDebug.c (new): new macosx specific functions for
	debugging MacOS events, regions, etc.

	* macosx/tkAboutDlg.r (new):
	* macosx/tkMacOSXApplication.r (new):
	* macosx/tkMacOSXCursors.r (new):
	* macosx/tkMacOSXLibrary.r (new):
	* macosx/tkMacOSXMenu.r (new):
	* macosx/tkMacOSXResource.r (new):
	* macosx/tkMacOSXXCursors.r (new):
	* macosx/tclets.r (new): sources for Rez resource compiler.

	* macosx/Wish.icns (new): Wish application icon.

	* generic/tk.h:
	* generic/default.h:
	* generic/tkBind.c:
	* generic/tkCmds.c:
	* generic/tkGrab.c:
	* generic/tkPointer.c:
	* generic/tkPort.h:
	* generic/tkSelect.c:
	* generic/tkStubLib.c:
	* generic/tkTest.c:
	* generic/tkText.c:
	* generic/tkWindow.c:
	* unix/tkUnix3d.c:
	* xlib/xgc.c:
	* xlib/X11/X.h:
	* xlib/X11/Xlib.h:
	* xlib/X11/Xutil.h: added #includes and #ifdefs for macosx

	* library/bgerror.tcl:
	* library/button.tcl:
	* library/console.tcl:
	* library/dialog.tcl:
	* library/entry.tcl:
	* library/listbox.tcl:
	* library/menu.tcl:
	* library/msgbox.tcl:
	* library/scrlbar.tcl:
	* library/spinbox.tcl:
	* library/text.tcl:
	* library/tk.tcl:
	* library/demos/menu.tcl:
	* library/demos/menubu.tcl:
	* library/demos/widget: check [tk windowingsystem] instead of
	and/or in addition to $tcl_platform(platform).

	* generic/tkInt.h:
	* mac/tkMacBitmap.c:
	* mac/tkMacWm.c: added missing CONSTification

	* generic/tkIntDecls.h:
	* generic/tkIntPlatDecls.h:
	* generic/tkIntXlibDecls.h:
	* generic/tkPlatDecls.h:
	* generic/tkStubInit.c: regen
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id$
d592 1
a592 1
		    wmPtr->title : winPtr->nameUid);
d1629 1
a1629 1
	    Tcl_SetResult(interp,
d1743 1
a1743 1
	    Tcl_SetResult(interp,
d2648 1
a2648 1
	Tcl_SetResult(interp,
d4666 1
a4666 1
    char *title)
@


1.21
log
@Last commit missed a few lines.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.20 2002/07/25 21:36:08 pspjuth Exp $
d5005 1
a5005 1
    char **argv)		/* Argument strings. */
@


1.20
log
@Objectifed wm. [Patch #564521]
Note: this commit has not been tested.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.19 2002/06/22 10:13:26 hobbs Exp $
d692 6
@


1.19
log
@	* doc/wm.n:                   TIP #95 Windows implementation and
	* mac/tkMacWm.c (Tk_WmCmd):   docs with mac and unix stubs.
	* unix/tkUnixWm.c (Tk_WmCmd):
	* win/tkWinWm.c (Tk_WmCmd):
	* tests/unixWm.test:
	* tests/winWm.test: more wm attr tests will be needed.
@
text
@d1 1
a1 1
/* 
d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.18 2002/06/14 22:25:12 jenglish Exp $
d31 1
a31 1
 * and are on the SDK CD.  However, we do not require the Appearance 
d34 1
a34 1
 
d52 1
a52 1
				 * message for this protocol arrives. 
d76 3
a78 3
    Tk_Uid titleUid;		/* Title to display in window caption.  If
				 * NULL, use name of widget. */
    Tk_Uid iconName;		/* Name to display in icon. */
d317 1
a317 1
static void		InitialWindowBounds _ANSI_ARGS_((TkWindow *winPtr, 
d332 89
d445 1
a445 1
	
d449 1
a449 1
    wmPtr->titleUid = NULL;
d557 1
a557 1
    int xOffset, yOffset;	    
d572 1
a572 1
	
d581 1
a581 1
	TkGenWMConfigureEvent((Tk_Window) winPtr, 
d583 1
a583 1
	
a589 4
	if (wmPtr->titleUid == NULL) {
	    wmPtr->titleUid = winPtr->nameUid;
	}
	
d591 2
a592 1
	    TkSetWMName(winPtr, wmPtr->titleUid);
d596 1
a596 1
    
d600 1
a600 1
    
d606 1
a606 1
    
d614 1
a614 1
    
d630 1
a630 1
    
d636 1
a636 1
    TkMacWindowOffset((WindowRef) TkMacGetDrawablePort(Tk_WindowId(winPtr)), 
d764 1
a764 1
 * Tk_WmCmd --
d780 1
a780 1
Tk_WmCmd(
d784 2
a785 2
    int argc,			/* Number of arguments. */
    char **argv)		/* Argument strings. */
d788 20
d809 1
a809 3
    register WmInfo *wmPtr;
    int c;
    size_t length;
d811 1
a811 1
    if (argc < 2) {
d813 1
a813 2
	Tcl_AppendResult(interp, "wrong # args: should be \"",
		argv[0], " option window ?arg ...?\"", (char *) NULL);
d816 3
a818 3
    c = argv[1][0];
    length = strlen(argv[1]);
    if ((c == 't') && (strncmp(argv[1], "tracing", length) == 0)
d820 2
a821 3
	if ((argc != 2) && (argc != 3)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " tracing ?boolean?\"", (char *) NULL);
d824 1
a824 1
	if (argc == 2) {
d828 6
a833 1
	return Tcl_GetBoolean(interp, argv[2], &wmTracing);
d836 1
a836 1
    if (argc < 3) {
d839 3
a841 2
    winPtr = (TkWindow *) Tk_NameToWindow(interp, argv[2], tkwin);
    if (winPtr == NULL) {
a848 14
    wmPtr = winPtr->wmInfoPtr;
    if ((c == 'a') && (strncmp(argv[1], "aspect", length) == 0)
	    && (length >= 2)) {
	int numer1, denom1, numer2, denom2;

	if ((argc != 3) && (argc != 7)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " aspect window ?minNumer minDenom ",
		    "maxNumer maxDenom?\"", (char *) NULL);
	    return TCL_ERROR;
	}
	if (argc == 3) {
	    if (wmPtr->sizeHintsFlags & PAspect) {
		char buf[TCL_INTEGER_SPACE * 4];
d850 106
a955 6
		sprintf(buf, "%d %d %d %d", wmPtr->minAspect.x,
			wmPtr->minAspect.y, wmPtr->maxAspect.x,
			wmPtr->maxAspect.y);
		Tcl_SetResult(interp, buf, TCL_VOLATILE);
	    }
	    return TCL_OK;
d957 9
a965 29
	if (*argv[3] == '\0') {
	    wmPtr->sizeHintsFlags &= ~PAspect;
	} else {
	    if ((Tcl_GetInt(interp, argv[3], &numer1) != TCL_OK)
		    || (Tcl_GetInt(interp, argv[4], &denom1) != TCL_OK)
		    || (Tcl_GetInt(interp, argv[5], &numer2) != TCL_OK)
		    || (Tcl_GetInt(interp, argv[6], &denom2) != TCL_OK)) {
		return TCL_ERROR;
	    }
	    if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) ||
		    (denom2 <= 0)) {
		Tcl_SetResult(interp, "aspect number can't be <= 0",
			TCL_STATIC);
		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;
	goto updateGeom;
    } else if ((c == 'a') && (strncmp(argv[1], "attributes", length) == 0)
	    && (length >= 2)) {
	if (argc != 3) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " attributes window",
		    "\"", (char *) NULL);
d968 4
a971 6
    } else if ((c == 'c') && (strncmp(argv[1], "client", length) == 0)
	    && (length >= 2)) {
	if ((argc != 3) && (argc != 4)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " client window ?name?\"",
		    (char *) NULL);
d974 79
a1052 12
	if (argc == 3) {
	    if (wmPtr->clientMachine != NULL) {
		Tcl_SetResult(interp, wmPtr->clientMachine, TCL_STATIC);
	    }
	    return TCL_OK;
	}
	if (argv[3][0] == 0) {
	    if (wmPtr->clientMachine != NULL) {
		ckfree((char *) wmPtr->clientMachine);
		wmPtr->clientMachine = NULL;
	    }
	    return TCL_OK;
d1054 4
d1060 1
d1062 42
a1103 9
	wmPtr->clientMachine = (char *)
	    ckalloc((unsigned) (strlen(argv[3]) + 1));
	strcpy(wmPtr->clientMachine, argv[3]);
    } else if ((c == 'c') && (strncmp(argv[1], "colormapwindows", length) == 0)
	    && (length >= 3)) {
	TkWindow **cmapList;
	TkWindow *winPtr2;
	int i, windowArgc, gotToplevel = 0;
	CONST char **windowArgv;
d1105 10
a1114 14
	if ((argc != 3) && (argc != 4)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " colormapwindows window ?windowList?\"",
		    (char *) NULL);
	    return TCL_ERROR;
	}
	if (argc == 3) {
	    Tk_MakeWindowExist((Tk_Window) winPtr);
	    for (i = 0; i < wmPtr->cmapCount; i++) {
		if ((i == (wmPtr->cmapCount-1))
			&& (wmPtr->flags & WM_ADDED_TOPLEVEL_COLORMAP)) {
		    break;
		}
		Tcl_AppendElement(interp, wmPtr->cmapList[i]->pathName);
d1116 1
a1116 1
	    return TCL_OK;
d1118 42
a1159 36
	if (Tcl_SplitList(interp, argv[3], &windowArgc, &windowArgv)
		!= TCL_OK) {
	    return TCL_ERROR;
	}
	cmapList = (TkWindow **) ckalloc((unsigned)
		((windowArgc+1)*sizeof(TkWindow*)));
	for (i = 0; i < windowArgc; i++) {
	    winPtr2 = (TkWindow *) Tk_NameToWindow(interp, windowArgv[i],
		    tkwin);
	    if (winPtr2 == NULL) {
		ckfree((char *) cmapList);
		ckfree((char *) windowArgv);
		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[windowArgc] = winPtr;
	    windowArgc++;
	} else {
	    wmPtr->flags &= ~WM_ADDED_TOPLEVEL_COLORMAP;
	}
	wmPtr->flags |= WM_COLORMAPS_EXPLICIT;
	if (wmPtr->cmapList != NULL) {
	    ckfree((char *)wmPtr->cmapList);
	}
	wmPtr->cmapList = cmapList;
	wmPtr->cmapCount = windowArgc;
	ckfree((char *) windowArgv);
d1161 19
a1179 5
	/*
	 * 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.
	 */
d1181 12
a1192 5
	return TCL_OK;
    } else if ((c == 'c') && (strncmp(argv[1], "command", length) == 0)
	    && (length >= 3)) {
	int cmdArgc;
	CONST char **cmdArgv;
d1194 9
a1202 23
	if ((argc != 3) && (argc != 4)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " command window ?value?\"",
		    (char *) NULL);
	    return TCL_ERROR;
	}
	if (argc == 3) {
	    if (wmPtr->cmdArgv != NULL) {
		Tcl_SetResult(interp,
			Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv),
			TCL_DYNAMIC);
	    }
	    return TCL_OK;
	}
	if (argv[3][0] == 0) {
	    if (wmPtr->cmdArgv != NULL) {
		ckfree((char *) wmPtr->cmdArgv);
		wmPtr->cmdArgv = NULL;
	    }
	    return TCL_OK;
	}
	if (Tcl_SplitList(interp, argv[3], &cmdArgc, &cmdArgv) != TCL_OK) {
	    return TCL_ERROR;
d1204 4
d1210 1
d1212 207
a1418 7
	wmPtr->cmdArgc = cmdArgc;
	wmPtr->cmdArgv = cmdArgv;
    } else if ((c == 'd') && (strncmp(argv[1], "deiconify", length) == 0)) {
	if (argc != 3) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " deiconify window\"", (char *) NULL);
	    return TCL_ERROR;
d1420 56
a1475 4
	if (wmPtr->iconFor != NULL) {
	    Tcl_AppendResult(interp, "can't deiconify ", argv[2],
		    ": it is an icon for ", winPtr->pathName, (char *) NULL);
	    return TCL_ERROR;
d1477 3
a1479 6
        if (winPtr->flags & TK_EMBEDDED) {
            Tcl_AppendResult(interp, "can't deiconify ", winPtr->pathName,
                    ": it is an embedded window", (char *) NULL);
            return TCL_ERROR;
        }
	
d1481 2
a1482 1
	 * TODO: may not want to call this function - look at Map events gened.
d1485 14
a1498 7
	TkpWmSetState(winPtr, NormalState);
    } else if ((c == 'f') && (strncmp(argv[1], "focusmodel", length) == 0)
	    && (length >= 2)) {
	if ((argc != 3) && (argc != 4)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " focusmodel window ?active|passive?\"",
		    (char *) NULL);
d1501 3
a1503 4
	if (argc == 3) {
	    Tcl_SetResult(interp, (wmPtr->hints.input ? "passive" : "active"),
		    TCL_STATIC);
	    return TCL_OK;
d1505 2
a1506 9
	c = argv[3][0];
	length = strlen(argv[3]);
	if ((c == 'a') && (strncmp(argv[3], "active", length) == 0)) {
	    wmPtr->hints.input = False;
	} else if ((c == 'p') && (strncmp(argv[3], "passive", length) == 0)) {
	    wmPtr->hints.input = True;
	} else {
	    Tcl_AppendResult(interp, "bad argument \"", argv[3],
		    "\": must be active or passive", (char *) NULL);
d1509 2
a1510 8
    } else if ((c == 'f') && (strncmp(argv[1], "frame", length) == 0)
	    && (length >= 2)) {
	Window window;
	char buf[TCL_INTEGER_SPACE];

	if (argc != 3) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " frame window\"", (char *) NULL);
d1513 2
a1514 15
	window = wmPtr->reparent;
	if (window == None) {
	    window = Tk_WindowId((Tk_Window) winPtr);
	}
	sprintf(buf, "0x%x", (unsigned int) window);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
    } else if ((c == 'g') && (strncmp(argv[1], "geometry", length) == 0)
	    && (length >= 2)) {
	char xSign, ySign;
	int width, height;

	if ((argc != 3) && (argc != 4)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " geometry window ?newGeometry?\"",
		    (char *) NULL);
d1517 37
a1553 2
	if (argc == 3) {
	    char buf[16 + TCL_INTEGER_SPACE * 4];
d1555 7
a1561 15
	    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;
	    }
	    sprintf(buf, "%dx%d%c%d%c%d", width, height, xSign, wmPtr->x,
		    ySign, wmPtr->y);
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
	    return TCL_OK;
d1563 7
a1569 4
	if (*argv[3] == '\0') {
	    wmPtr->width = -1;
	    wmPtr->height = -1;
	    goto updateGeom;
d1571 3
a1573 9
	return ParseGeometry(interp, argv[3], winPtr);
    } else if ((c == 'g') && (strncmp(argv[1], "grid", length) == 0)
	    && (length >= 3)) {
	int reqWidth, reqHeight, widthInc, heightInc;

	if ((argc != 3) && (argc != 7)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " grid window ?baseWidth baseHeight ",
		    "widthInc heightInc?\"", (char *) NULL);
d1576 3
a1578 10
	if (argc == 3) {
	    if (wmPtr->sizeHintsFlags & PBaseSize) {
		char buf[TCL_INTEGER_SPACE * 4];

		sprintf(buf, "%d %d %d %d", wmPtr->reqGridWidth,
			wmPtr->reqGridHeight, wmPtr->widthInc,
			wmPtr->heightInc);
		Tcl_SetResult(interp, buf, TCL_VOLATILE);
	    }
	    return TCL_OK;
d1580 24
a1603 5
	if (*argv[3] == '\0') {
	    /*
	     * Turn off gridding and reset the width and height
	     * to make sense as ungridded numbers.
	     */
d1605 11
a1615 40
	    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_GetInt(interp, argv[3], &reqWidth) != TCL_OK)
		    || (Tcl_GetInt(interp, argv[4], &reqHeight) != TCL_OK)
		    || (Tcl_GetInt(interp, argv[5], &widthInc) != TCL_OK)
		    || (Tcl_GetInt(interp, argv[6], &heightInc) != TCL_OK)) {
		return TCL_ERROR;
	    }
	    if (reqWidth < 0) {
		Tcl_SetResult(interp, "baseWidth can't be < 0", TCL_STATIC);
		return TCL_ERROR;
	    }
	    if (reqHeight < 0) {
		Tcl_SetResult(interp, "baseHeight can't be < 0", TCL_STATIC);
		return TCL_ERROR;
	    }
	    if (widthInc < 0) {
		Tcl_SetResult(interp, "widthInc can't be < 0", TCL_STATIC);
		return TCL_ERROR;
	    }
	    if (heightInc < 0) {
		Tcl_SetResult(interp, "heightInc can't be < 0", TCL_STATIC);
		return TCL_ERROR;
	    }
	    Tk_SetGrid((Tk_Window) winPtr, reqWidth, reqHeight, widthInc,
		    heightInc);
	}
	wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
	goto updateGeom;
    } else if ((c == 'g') && (strncmp(argv[1], "group", length) == 0)
	    && (length >= 3)) {
	Tk_Window tkwin2;
d1617 9
a1625 5
	if ((argc != 3) && (argc != 4)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " group window ?pathName?\"",
		    (char *) NULL);
	    return TCL_ERROR;
d1627 7
a1633 5
	if (argc == 3) {
	    if (wmPtr->hints.flags & WindowGroupHint) {
		Tcl_SetResult(interp, wmPtr->leaderName, TCL_STATIC);
	    }
	    return TCL_OK;
d1635 4
a1638 25
	if (*argv[3] == '\0') {
	    wmPtr->hints.flags &= ~WindowGroupHint;
	    if (wmPtr->leaderName != NULL) {
		ckfree(wmPtr->leaderName);
	    }
	    wmPtr->leaderName = NULL;
	} else {
	    tkwin2 = Tk_NameToWindow(interp, argv[3], tkwin);
	    if (tkwin2 == NULL) {
		return TCL_ERROR;
	    }
	    Tk_MakeWindowExist(tkwin2);
	    wmPtr->hints.window_group = Tk_WindowId(tkwin2);
	    wmPtr->hints.flags |= WindowGroupHint;
	    wmPtr->leaderName = ckalloc((unsigned) (strlen(argv[3])+1));
	    strcpy(wmPtr->leaderName, argv[3]);
	}
    } else if ((c == 'i') && (strncmp(argv[1], "iconbitmap", length) == 0)
	    && (length >= 5)) {
	Pixmap pixmap;

	if ((argc != 3) && (argc != 4)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " iconbitmap window ?bitmap?\"",
		    (char *) NULL);
d1641 99
a1739 7
	if (argc == 3) {
	    if (wmPtr->hints.flags & IconPixmapHint) {
		Tcl_SetResult(interp,
			Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_pixmap),
			TCL_STATIC);
	    }
	    return TCL_OK;
d1741 6
a1746 13
	if (*argv[3] == '\0') {
	    if (wmPtr->hints.icon_pixmap != None) {
		Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap);
	    }
	    wmPtr->hints.flags &= ~IconPixmapHint;
	} else {
	    pixmap = Tk_GetBitmap(interp, (Tk_Window) winPtr,
		    Tk_GetUid(argv[3]));
	    if (pixmap == None) {
		return TCL_ERROR;
	    }
	    wmPtr->hints.icon_pixmap = pixmap;
	    wmPtr->hints.flags |= IconPixmapHint;
d1748 4
a1751 5
    } else if ((c == 'i') && (strncmp(argv[1], "iconify", length) == 0)
	    && (length >= 5)) {
	if (argc != 3) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " iconify window\"", (char *) NULL);
d1754 47
a1800 4
	if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
	    Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
		    "\": override-redirect flag is set", (char *) NULL);
	    return TCL_ERROR;
d1802 5
a1806 4
	if (wmPtr->master != None) {
	    Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
		    "\": it is a transient", (char *) NULL);
	    return TCL_ERROR;
d1808 44
a1851 5
	if (wmPtr->iconFor != NULL) {
	    Tcl_AppendResult(interp, "can't iconify ", argv[2],
		    ": it is an icon for ", Tk_PathName(wmPtr->iconFor),
		   (char *) NULL);
	    return TCL_ERROR;
d1853 7
a1859 14
        if (winPtr->flags & TK_EMBEDDED) {
            Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName,
                    ": it is an embedded window", (char *) NULL);
            return TCL_ERROR;
        }
	TkpWmSetState(winPtr, IconicState);
    } else if ((c == 'i') && (strncmp(argv[1], "iconmask", length) == 0)
	    && (length >= 5)) {
	Pixmap pixmap;

	if ((argc != 3) && (argc != 4)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " iconmask window ?bitmap?\"",
		    (char *) NULL);
d1862 43
a1904 7
	if (argc == 3) {
	    if (wmPtr->hints.flags & IconMaskHint) {
		Tcl_SetResult(interp,
			Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_mask),
			TCL_STATIC);
	    }
	    return TCL_OK;
d1906 8
a1913 12
	if (*argv[3] == '\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, Tk_GetUid(argv[3]));
	    if (pixmap == None) {
		return TCL_ERROR;
	    }
	    wmPtr->hints.icon_mask = pixmap;
	    wmPtr->hints.flags |= IconMaskHint;
d1915 3
a1917 5
    } else if ((c == 'i') && (strncmp(argv[1], "iconname", length) == 0)
	    && (length >= 5)) {
	if (argc > 4) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " iconname window ?newName?\"", (char *) NULL);
d1920 3
a1922 19
	if (argc == 3) {
	    Tcl_SetResult(interp,
		    ((wmPtr->iconName != NULL) ? wmPtr->iconName : ""),
		    TCL_STATIC);
	    return TCL_OK;
	} else {
	    wmPtr->iconName = Tk_GetUid(argv[3]);
	    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
		XSetIconName(winPtr->display, winPtr->window, wmPtr->iconName);
	    }
	}
    } else if ((c == 'i') && (strncmp(argv[1], "iconposition", length) == 0)
	    && (length >= 5)) {
	int x, y;

	if ((argc != 3) && (argc != 5)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " iconposition window ?x y?\"",
		    (char *) NULL);
d1925 5
a1929 30
	if (argc == 3) {
	    if (wmPtr->hints.flags & IconPositionHint) {
		char buf[TCL_INTEGER_SPACE * 2];
		
		sprintf(buf, "%d %d", wmPtr->hints.icon_x,
			wmPtr->hints.icon_y);
		Tcl_SetResult(interp, buf, TCL_VOLATILE);
	    }
	    return TCL_OK;
	}
	if (*argv[3] == '\0') {
	    wmPtr->hints.flags &= ~IconPositionHint;
	} else {
	    if ((Tcl_GetInt(interp, argv[3], &x) != TCL_OK)
		    || (Tcl_GetInt(interp, argv[4], &y) != TCL_OK)){
		return TCL_ERROR;
	    }
	    wmPtr->hints.icon_x = x;
	    wmPtr->hints.icon_y = y;
	    wmPtr->hints.flags |= IconPositionHint;
	}
    } else if ((c == 'i') && (strncmp(argv[1], "iconwindow", length) == 0)
	    && (length >= 5)) {
	Tk_Window tkwin2;
	WmInfo *wmPtr2;

	if ((argc != 3) && (argc != 4)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " iconwindow window ?pathName?\"",
		    (char *) NULL);
d1932 3
a1934 5
	if (argc == 3) {
	    if (wmPtr->icon != NULL) {
		Tcl_SetResult(interp, Tk_PathName(wmPtr->icon), TCL_STATIC);
	    }
	    return TCL_OK;
d1936 9
a1944 37
	if (*argv[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 {
	    tkwin2 = Tk_NameToWindow(interp, argv[3], tkwin);
	    if (tkwin2 == NULL) {
		return TCL_ERROR;
	    }
	    if (!Tk_IsTopLevel(tkwin2)) {
		Tcl_AppendResult(interp, "can't use ", argv[3],
			" as icon window: not at top level", (char *) NULL);
		return TCL_ERROR;
	    }
	    wmPtr2 = ((TkWindow *) tkwin2)->wmInfoPtr;
	    if (wmPtr2->iconFor != NULL) {
		Tcl_AppendResult(interp, argv[3], " is already an icon for ",
			Tk_PathName(wmPtr2->iconFor), (char *) 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.
		 */
d1946 1
a1946 2
		Tk_UnmapWindow(tkwin2);
	    }
d1948 195
a2142 14
    } else if ((c == 'm') && (strncmp(argv[1], "maxsize", length) == 0)
	    && (length >= 2)) {
	int width, height;
	if ((argc != 3) && (argc != 5)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " maxsize window ?width height?\"", (char *) NULL);
	    return TCL_ERROR;
	}
	if (argc == 3) {
	    char buf[TCL_INTEGER_SPACE * 2];
	    
	    sprintf(buf, "%d %d", wmPtr->maxWidth, wmPtr->maxHeight);
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
	    return TCL_OK;
d2144 7
a2150 2
	if ((Tcl_GetInt(interp, argv[3], &width) != TCL_OK)
		|| (Tcl_GetInt(interp, argv[4], &height) != TCL_OK)) {
d2153 6
a2158 11
	wmPtr->maxWidth = width;
	wmPtr->maxHeight = height;
	wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
	goto updateGeom;
    } else if ((c == 'm') && (strncmp(argv[1], "minsize", length) == 0)
	    && (length >= 2)) {
	int width, height;
	if ((argc != 3) && (argc != 5)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		   argv[0], " minsize window ?width height?\"", (char *) NULL);
	    return TCL_ERROR;
d2160 49
a2208 6
	if (argc == 3) {
	    char buf[TCL_INTEGER_SPACE * 2];
	    
	    sprintf(buf, "%d %d", wmPtr->minWidth, wmPtr->minHeight);
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
	    return TCL_OK;
d2210 13
a2222 3
	if ((Tcl_GetInt(interp, argv[3], &width) != TCL_OK)
		|| (Tcl_GetInt(interp, argv[4], &height) != TCL_OK)) {
	    return TCL_ERROR;
d2224 14
a2237 18
	wmPtr->minWidth = width;
	wmPtr->minHeight = height;
	wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
	goto updateGeom;
    } else if ((c == 'o')
	    && (strncmp(argv[1], "overrideredirect", length) == 0)) {
	int boolean;
	XSetWindowAttributes atts;

	if ((argc != 3) && (argc != 4)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " overrideredirect window ?boolean?\"",
		    (char *) NULL);
	    return TCL_ERROR;
	}
	if (argc == 3) {
	    if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
		Tcl_SetResult(interp, "1", TCL_STATIC);
d2239 1
a2239 1
		Tcl_SetResult(interp, "0", TCL_STATIC);
d2241 2
a2242 1
	    return TCL_OK;
d2244 118
a2361 2
	if (Tcl_GetBoolean(interp, argv[3], &boolean) != TCL_OK) {
	    return TCL_ERROR;
d2363 8
a2370 10
	    atts.override_redirect = (boolean) ? True : False;
	    Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWOverrideRedirect,
		    &atts);
	    wmPtr->style = (boolean) ? plainDBox : documentProc;
    } else if ((c == 'p') && (strncmp(argv[1], "positionfrom", length) == 0)
	    && (length >= 2)) {
	if ((argc != 3) && (argc != 4)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " positionfrom window ?user/program?\"",
		    (char *) NULL);
d2373 6
a2378 7
	if (argc == 3) {
	    if (wmPtr->sizeHintsFlags & USPosition) {
		Tcl_SetResult(interp, "user", TCL_STATIC);
	    } else if (wmPtr->sizeHintsFlags & PPosition) {
		Tcl_SetResult(interp, "program", TCL_STATIC);
	    }
	    return TCL_OK;
d2380 47
a2426 2
	if (*argv[3] == '\0') {
	    wmPtr->sizeHintsFlags &= ~(USPosition|PPosition);
d2428 2
a2429 51
	    c = argv[3][0];
	    length = strlen(argv[3]);
	    if ((c == 'u') && (strncmp(argv[3], "user", length) == 0)) {
		wmPtr->sizeHintsFlags &= ~PPosition;
		wmPtr->sizeHintsFlags |= USPosition;
	    } else if ((c == 'p') &&
		    (strncmp(argv[3], "program", length) == 0)) {
		wmPtr->sizeHintsFlags &= ~USPosition;
		wmPtr->sizeHintsFlags |= PPosition;
	    } else {
		Tcl_AppendResult(interp, "bad argument \"", argv[3],
			"\": must be program or user", (char *) NULL);
		return TCL_ERROR;
	    }
	}
	wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
	goto updateGeom;
    } else if ((c == 'p') && (strncmp(argv[1], "protocol", length) == 0)
	    && (length >= 2)) {
	register ProtocolHandler *protPtr, *prevPtr;
	Atom protocol;
	int cmdLength;

	if ((argc < 3) || (argc > 5)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " protocol window ?name? ?command?\"",
		    (char *) NULL);
	    return TCL_ERROR;
	}
	if (argc == 3) {
	    /*
	     * Return a list of all defined protocols for the window.
	     */
	    for (protPtr = wmPtr->protPtr; protPtr != NULL;
					   protPtr = protPtr->nextPtr) {
		Tcl_AppendElement(interp,
			Tk_GetAtomName((Tk_Window) winPtr, protPtr->protocol));
	    }
	    return TCL_OK;
	}
	protocol = Tk_InternAtom((Tk_Window) winPtr, argv[3]);
	if (argc == 4) {
	    /*
	     * Return the command to handle a given protocol.
	     */
	    for (protPtr = wmPtr->protPtr; protPtr != NULL;
					   protPtr = protPtr->nextPtr) {
		if (protPtr->protocol == protocol) {
		    Tcl_SetResult(interp, protPtr->command, TCL_STATIC);
		    return TCL_OK;
		}
d2431 1
d2434 3
d2438 2
a2439 34
	/*
	 * 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((ClientData) protPtr, TCL_DYNAMIC);
		break;
	    }
	}
	cmdLength = strlen(argv[4]);
	if (cmdLength > 0) {
	    protPtr = (ProtocolHandler *) ckalloc(HANDLER_SIZE(cmdLength));
	    protPtr->protocol = protocol;
	    protPtr->nextPtr = wmPtr->protPtr;
	    wmPtr->protPtr = protPtr;
	    protPtr->interp = interp;
	    strcpy(protPtr->command, argv[4]);
	}
    } else if ((c == 'r') && (strncmp(argv[1], "resizable", length) == 0)) {
	int width, height;

	if ((argc != 3) && (argc != 5)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " resizable window ?width height?\"",
		    (char *) NULL);
a2441 2
	if (argc == 3) {
	    char buf[TCL_INTEGER_SPACE * 2];
d2443 3
a2445 8
	    sprintf(buf, "%d %d",
		    (wmPtr->flags  & WM_WIDTH_NOT_RESIZABLE) ? 0 : 1,
		    (wmPtr->flags  & WM_HEIGHT_NOT_RESIZABLE) ? 0 : 1);
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
	    return TCL_OK;
	}
	if ((Tcl_GetBoolean(interp, argv[3], &width) != TCL_OK)
		|| (Tcl_GetBoolean(interp, argv[4], &height) != TCL_OK)) {
d2448 4
a2451 22
	if (width) {
	    wmPtr->flags &= ~WM_WIDTH_NOT_RESIZABLE;
	} else {
	    wmPtr->flags |= WM_WIDTH_NOT_RESIZABLE;
	}
	if (height) {
	    wmPtr->flags &= ~WM_HEIGHT_NOT_RESIZABLE;
	} else {
	    wmPtr->flags |= WM_HEIGHT_NOT_RESIZABLE;
	}
	wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
	if (wmPtr->scrollWinPtr != NULL) {
	    TkScrollbarEventuallyRedraw(
		(TkScrollbar *) wmPtr->scrollWinPtr->instanceData);
	}
	goto updateGeom;
    } else if ((c == 's') && (strncmp(argv[1], "sizefrom", length) == 0)
	    && (length >= 2)) {
	if ((argc != 3) && (argc != 4)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " sizefrom window ?user|program?\"",
		    (char *) NULL);
d2454 4
a2457 37
	if (argc == 3) {
	    if (wmPtr->sizeHintsFlags & USSize) {
		Tcl_SetResult(interp, "user", TCL_STATIC);
	    } else if (wmPtr->sizeHintsFlags & PSize) {
		Tcl_SetResult(interp, "program", TCL_STATIC);
	    }
	    return TCL_OK;
	}
	if (*argv[3] == '\0') {
	    wmPtr->sizeHintsFlags &= ~(USSize|PSize);
	} else {
	    c = argv[3][0];
	    length = strlen(argv[3]);
	    if ((c == 'u') && (strncmp(argv[3], "user", length) == 0)) {
		wmPtr->sizeHintsFlags &= ~PSize;
		wmPtr->sizeHintsFlags |= USSize;
	    } else if ((c == 'p')
		    && (strncmp(argv[3], "program", length) == 0)) {
		wmPtr->sizeHintsFlags &= ~USSize;
		wmPtr->sizeHintsFlags |= PSize;
	    } else {
		Tcl_AppendResult(interp, "bad argument \"", argv[3],
			"\": must be program or user", (char *) NULL);
		return TCL_ERROR;
	    }
	}
	wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
	goto updateGeom;
    } else if ((c == 's') && (strncmp(argv[1], "stackorder", length) == 0)
	    && (length >= 2)) {
	TkWindow **windows, **window_ptr;

	if ((argc != 3) && (argc != 5)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0],
		    " stackorder window ?isabove|isbelow window?\"",
		    (char *) NULL);
d2461 12
a2472 11
	if (argc == 3) {
            windows = TkWmStackorderToplevel(winPtr);
            if (windows == NULL) {
                panic("TkWmStackorderToplevel failed");
	    } else {
                for (window_ptr = windows; *window_ptr ; window_ptr++) {
                    Tcl_AppendElement(interp, (*window_ptr)->pathName);
                }
                ckfree((char *) windows);
                return TCL_OK;
	    }
d2474 5
a2478 6
	    TkWindow *winPtr2;
	    int index1=-1, index2=-1, result;

	    winPtr2 = (TkWindow *) Tk_NameToWindow(interp, argv[4], tkwin);
	    if (winPtr2 == NULL) {
		return TCL_ERROR;
d2480 4
d2485 2
a2486 5
	    if (!Tk_IsTopLevel(winPtr2)) {
		Tcl_AppendResult(interp, "window \"", winPtr2->pathName,
		    "\" isn't a top-level window", (char *) NULL);
		return TCL_ERROR;
	    }
d2488 31
a2518 5
	    if (!Tk_IsMapped(winPtr)) {
		Tcl_AppendResult(interp, "window \"", winPtr->pathName,
		    "\" isn't mapped", (char *) NULL);
		return TCL_ERROR;
	    }
d2520 14
a2533 5
	    if (!Tk_IsMapped(winPtr2)) {
		Tcl_AppendResult(interp, "window \"", winPtr2->pathName,
		    "\" isn't mapped", (char *) NULL);
		return TCL_ERROR;
	    }
d2535 11
a2545 42
            /*
             * 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_AppendResult(interp, "TkWmStackorderToplevel failed",
                    (char *) NULL);
                return TCL_ERROR;
	    } else {
                for (window_ptr = windows; *window_ptr ; window_ptr++) {
                    if (*window_ptr == winPtr)
                        index1 = (window_ptr - windows);
                    if (*window_ptr == winPtr2)
                        index2 = (window_ptr - windows);
                }
                if (index1 == -1)
                    panic("winPtr window not found");
                if (index2 == -1)
                    panic("winPtr2 window not found");

                ckfree((char *) windows);
	    }

	    c = argv[3][0];
	    length = strlen(argv[3]);
	    if ((length > 2) && (c == 'i')
		    && (strncmp(argv[3], "isabove", length) == 0)) {
		result = index1 > index2;
	    } else if ((length > 2) && (c == 'i')
		    && (strncmp(argv[3], "isbelow", length) == 0)) {
		result = index1 < index2;
	    } else {
		Tcl_AppendResult(interp, "bad argument \"", argv[3],
			"\": must be isabove or isbelow", (char *) NULL);
		return TCL_ERROR;
	    }
	    Tcl_SetIntObj(Tcl_GetObjResult(interp), result);
	    return TCL_OK;
d2547 4
a2550 5
    } else if ((c == 's') && (strncmp(argv[1], "state", length) == 0)
	    && (length >= 2)) {
	if ((argc < 3) || (argc > 4)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " state window ?state?\"", (char *) NULL);
a2552 13
	if (argc == 4) {
	    if (wmPtr->iconFor != NULL) {
		Tcl_AppendResult(interp, "can't change state of ", argv[2],
			": it is an icon for ", Tk_PathName(wmPtr->iconFor),
			(char *) NULL);
		return TCL_ERROR;
	    }
	    if (winPtr->flags & TK_EMBEDDED) {
		Tcl_AppendResult(interp, "can't change state of ",
			winPtr->pathName, ": it is an embedded window",
			(char *) NULL);
		return TCL_ERROR;
	    }
d2554 4
a2557 2
	    c = argv[3][0];
	    length = strlen(argv[3]);
d2559 11
a2569 31
	    if ((c == 'n') && (strncmp(argv[3], "normal", length) == 0)) {
		TkpWmSetState(winPtr, NormalState);
		/*
		 * This varies from 'wm deiconify' because it does not
		 * force the window to be raised and receive focus
		 */
	    } else if ((c == 'i')
		    && (strncmp(argv[3], "iconic", length) == 0)) {
		if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
		    Tcl_AppendResult(interp, "can't iconify \"",
			    winPtr->pathName,
			    "\": override-redirect flag is set",
			    (char *) NULL);
		    return TCL_ERROR;
		}
		if (wmPtr->master != NULL) {
		    Tcl_AppendResult(interp, "can't iconify \"",
			    winPtr->pathName,
			    "\": it is a transient", (char *) NULL);
		    return TCL_ERROR;
		}
		TkpWmSetState(winPtr, IconicState);
	    } else if ((c == 'w')
		    && (strncmp(argv[3], "withdrawn", length) == 0)) {
		TkpWmSetState(winPtr, WithdrawnState);
	    } else if ((c == 'z')
		    && (strncmp(argv[3], "zoomed", length) == 0)) {
		TkpWmSetState(winPtr, ZoomState);
	    } else {
		Tcl_AppendResult(interp, "bad argument \"", argv[3],
			"\": must be normal, iconic, withdrawn or zoomed",
d2573 5
a2577 18
	} else {
	    if (wmPtr->iconFor != NULL) {
		Tcl_SetResult(interp, "icon", TCL_STATIC);
	    } else {
		switch (wmPtr->hints.initial_state) {
		    case NormalState:
			Tcl_SetResult(interp, "normal", TCL_STATIC);
			break;
		    case IconicState:
			Tcl_SetResult(interp, "iconic", TCL_STATIC);
			break;
		    case WithdrawnState:
			Tcl_SetResult(interp, "withdrawn", TCL_STATIC);
			break;
		    case ZoomState:
			Tcl_SetResult(interp, "zoomed", TCL_STATIC);
			break;
		}
d2579 5
d2585 3
a2587 12
    } else if ((c == 't') && (strncmp(argv[1], "title", length) == 0)
	    && (length >= 2)) {
	if (argc > 4) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " title window ?newTitle?\"", (char *) NULL);
	    return TCL_ERROR;
	}
	if (argc == 3) {
	    Tcl_SetResult(interp,
		    ((wmPtr->titleUid != NULL) ? wmPtr->titleUid : winPtr->nameUid),
		    TCL_STATIC);
	    return TCL_OK;
d2589 13
a2601 3
	    wmPtr->titleUid = Tk_GetUid(argv[3]);
	    if (!(wmPtr->flags & WM_NEVER_MAPPED) && !Tk_IsEmbedded(winPtr)) {
		TkSetWMName(winPtr, wmPtr->titleUid);
d2604 32
a2635 4
    } else if ((c == 't') && (strncmp(argv[1], "transient", length) == 0)
	    && (length >= 3)) {
	Tk_Window master;
	WmInfo *wmPtr2;
d2637 12
a2648 4
	if ((argc != 3) && (argc != 4)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " transient window ?master?\"", (char *) NULL);
	    return TCL_ERROR;
d2650 5
a2654 5
	if (argc == 3) {
	    if (wmPtr->master != None) {
		Tcl_SetResult(interp, wmPtr->masterWindowName, TCL_STATIC);
	    }
	    return TCL_OK;
d2656 20
a2675 13
	if (argv[3][0] == '\0') {
	    wmPtr->master = None;
	    if (wmPtr->masterWindowName != NULL) {
		ckfree(wmPtr->masterWindowName);
	    }
	    wmPtr->masterWindowName = NULL;
	    wmPtr->style = documentProc;
	} else {
	    master = Tk_NameToWindow(interp, argv[3], tkwin);
	    if (master == NULL) {
		return TCL_ERROR;
	    }
	    Tk_MakeWindowExist(master);
d2677 13
a2689 7
	    if (wmPtr->iconFor != NULL) {
	        Tcl_AppendResult(interp, "can't make \"", argv[2],
	    	        "\" a transient: it is an icon for ",
	                Tk_PathName(wmPtr->iconFor),
	                (char *) NULL);
	        return TCL_ERROR;
	    }
d2691 22
a2712 1
	    wmPtr2 = ((TkWindow *) master)->wmInfoPtr;
d2714 6
a2719 17
	    if (wmPtr2->iconFor != NULL) {
	        Tcl_AppendResult(interp, "can't make \"", argv[3],
	                "\" a master: it is an icon for ",
	                Tk_PathName(wmPtr2->iconFor),
	                (char *) NULL);
	        return TCL_ERROR;
	    }

	    wmPtr->master = Tk_WindowId(master);
	    wmPtr->masterWindowName = ckalloc((unsigned) (strlen(argv[3])+1));
	    strcpy(wmPtr->masterWindowName, argv[3]);
	    wmPtr->style = plainDBox;
	}
    } else if ((c == 'w') && (strncmp(argv[1], "withdraw", length) == 0)) {
	if (argc != 3) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " withdraw window\"", (char *) NULL);
d2722 8
a2729 3
	if (wmPtr->iconFor != NULL) {
	    Tcl_AppendResult(interp, "can't withdraw ", argv[2],
		    ": it is an icon for ", Tk_PathName(wmPtr->iconFor),
d2733 44
a2776 9
	TkpWmSetState(winPtr, WithdrawnState);
    } else {
	Tcl_AppendResult(interp, "unknown or ambiguous option \"", argv[1],
		"\": must be aspect, client, command, deiconify, ",
		"focusmodel, frame, geometry, grid, group, iconbitmap, ",
		"iconify, iconmask, iconname, iconposition, ",
		"iconwindow, maxsize, minsize, overrideredirect, ",
		"positionfrom, protocol, resizable, sizefrom, stackorder, ",
		"state, title, transient, or withdraw",
d2780 1
d2782 1
d2784 9
a2792 1
    updateGeom:
a2796 1
    return TCL_OK;
d2879 1
a2879 1
    /* 
d2996 1
a2996 1
    
d3173 1
a3173 1
	
d3178 1
a3178 1
	if (contWinPtr != NULL) {	    
d3493 1
a3493 1
	    	break;	    	
d3496 1
a3496 1
		
d3504 1
a3504 1
		    
d3510 1
a3510 1
		     
d3513 1
a3513 1
		    
d3516 1
a3516 1
		    
d3519 1
a3519 1
		         * We do not require that the changes.x & changes.y for 
d3526 1
a3526 1
		         
d3529 1
a3529 1
	                
d3531 1
a3531 1
		        
d3591 1
a3591 1
     
d3618 1
a3618 1
	
d3623 1
a3623 1
	 
d3631 1
a3631 1
	    	          
d3639 1
a3639 1
	    
d3644 1
a3644 1
	
d3719 1
a3719 1
	 
d3723 2
a3724 2
		if (Tk_IsMapped(childPtr) && 
	    	         (x > childPtr->changes.x && 
d3729 1
a3729 1
				 childPtr->changes.height)) {	    
d3737 1
a3737 1
	
d3739 1
a3739 1
	
d4121 1
a4121 1
    } else {	
d4179 1
a4179 1
    
d4183 1
a4183 1
    
d4198 1
a4198 1
    
d4213 1
a4213 1
	
d4216 1
a4216 1
    } else {	
d4219 1
a4219 1
    
d4222 1
a4222 1
	    /* 
d4355 1
a4355 1
     * in compatability as we don't support colormaps.  If 
d4495 1
a4495 1
	
d4497 1
a4497 1
	/* 
d4501 1
a4501 1
		
d4515 1
a4515 1
	
d4528 1
a4528 1
 *	a toplevel window that is resizable.  If the window is 
d4552 1
a4552 1
    
d4592 1
a4592 1
		
d4603 1
a4603 1
	
d4621 1
a4621 1
	
d4630 1
a4630 1
	    TkGenWMConfigureEvent((Tk_Window) winPtr, -1, -1, 
d4645 1
a4645 1
 *	Set the title for a toplevel window.  If the window is embedded, 
d4660 1
a4660 1
    Tk_Uid titleUid)
d4665 1
a4665 1
    
d4669 2
a4670 2
    Tcl_UtfToExternal(NULL, NULL, titleUid,
	    strlen(titleUid), 0, NULL, 
d4674 1
a4674 1
    
d4685 1
a4685 1
    
d4689 1
a4689 1
	
d4703 1
a4703 1
 *	Generate a ConfigureNotify event for Tk.  Depending on the 
d4728 1
a4728 1
    
d4732 1
a4732 1
    
d4765 1
a4765 1
    
d4767 1
a4767 1
    
d4778 1
a4778 1
	if ((flags & TK_SIZE_CHANGED) && 
d4816 1
a4816 1
    
d4929 2
a4930 2
     * We should now zoom the window (as long as it's one of ours).  We 
     * also need to generate an event to let Tk know that the window size 
d4958 1
a4958 1
    
d4967 1
a4967 1
    TkGenWMConfigureEvent(tkwin, location.h, location.v, 
d4979 1
a4979 1
 *	This procedure is invoked to process the 
d5043 1
a5043 1
	
d5046 1
a5046 1
	    
d5095 1
a5095 1
	        
d5121 1
a5121 1
                    Tcl_ListObjAppendElement(interp, attributeList, 
d5131 1
a5131 1
                        Tcl_ListObjAppendElement(interp, attributeList, 
d5135 1
a5135 1
                        Tcl_ListObjAppendElement(interp, attributeList, 
d5139 1
a5139 1
                        Tcl_ListObjAppendElement(interp, attributeList, 
d5143 1
a5143 1
                        Tcl_ListObjAppendElement(interp, attributeList, 
d5147 1
a5147 1
                        Tcl_ListObjAppendElement(interp, attributeList, 
d5151 1
a5151 1
                        Tcl_ListObjAppendElement(interp, attributeList, 
d5155 1
a5155 1
                        Tcl_ListObjAppendElement(interp, attributeList, 
d5159 1
a5159 1
                        Tcl_ListObjAppendElement(interp, attributeList, 
d5164 1
a5164 1
                Tcl_SetObjResult(interp, newResult);       
d5213 1
a5213 1
	    
d5234 1
a5234 1
	    
d5245 1
a5245 1
	        
d5252 1
a5252 1
	        	        
d5254 1
a5254 1
	        
d5256 1
a5256 1
	            if ((*attrArgv[i] == 'c') 
d5260 1
a5260 1
	            } else if ((*attrArgv[i] == 'h') 
d5264 1
a5264 1
	            } else if ((*attrArgv[i] == 'v') 
d5268 1
a5268 1
	            } else if ((*attrArgv[i] == 'c') 
d5272 1
a5272 1
	            } else if ((*attrArgv[i] == 'r') 
d5276 1
a5276 1
	            } else if ((*attrArgv[i] == 's') 
d5285 1
a5285 1
	        
d5289 1
a5289 1
	        
d5293 2
a5294 2
	            
	            Tcl_AppendResult(interp, "bad attribute: \"", argv[4], 
d5303 1
a5303 1
	    
d5312 1
a5312 1
   
d5321 1
a5321 1
 *	Configure the window to be either a undecorated pull-down 
d5338 1
a5338 1
				 * menu is always visible, e.g. as a 
d5356 1
a5356 1
 *	the Mac actually understands.  
d5367 1
a5367 1
void 
d5382 1
a5382 1
    
d5387 1
a5387 1
     * then return... 
d5389 1
a5389 1
    
d5412 1
a5412 1
	
d5414 1
a5414 1
    
d5416 1
a5416 1
	
d5418 1
a5418 1
        OSStatus err;        
d5426 1
a5426 1
         
d5429 1
a5429 1
        err = CreateNewWindow(wmPtr->macClass, wmPtr->attributes, 
d5434 1
a5434 1
        
d5436 1
a5436 1
    newWindow = NewCWindow(NULL, &geometry, "\ptemp", false, 
d5439 1
a5439 1
    
d5443 1
a5443 1
    
d5447 1
a5447 1
    
d5452 1
a5452 1
    
d5456 1
a5456 1
	
d5467 1
a5467 1
    
d5477 1
a5477 1
 *	hash table that maps Mac windows to root X windows.  
d5488 1
a5488 1
void 
d5516 1
a5516 1
 *	Given a macintosh port window, this function removes the 
d5518 1
a5518 1
 *	Tk cares about.  
d5529 1
a5529 1
void 
d5546 1
a5546 1
 *	Tk scrollbar window will display the grow region for the 
d5558 1
a5558 1
void 
d5590 1
a5590 1
TkWindow * 
d5595 1
a5595 1
    
d5701 1
a5701 1
    
d5763 1
a5763 1
    
@


1.18
log
@TIP #47 "Modifying Tk to Allow Writing X Window managers"
(patch from Neil McKay).
* Add CirculateRequest, Create, MapRequest, ResizeRequest,
  and ConfigureRequest event types;
* Split TK_TOPLEVEL flag into TK_TOPLEVEL, TK_HAS_WRAPPER,
  TK_WIN_MANAGED, and TK_TOP_HIERARCHY.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.17 2002/05/24 09:50:11 mdejong Exp $
d742 2
a743 1
    if ((c == 'a') && (strncmp(argv[1], "aspect", length) == 0)) {
d786 8
d4132 1
a4132 1
		   panic("invalid style");
d4165 1
a4165 1
                     Tcl_ListObjAppendElement(interp, attributeList, 
d4168 2
a4169 2
                     Tcl_ListObjAppendElement(interp, attributeList, 
                            Tcl_NewStringObj("standardFloating", -1));                  
d4209 42
a4250 42
	if (strcmp(argv[3], "documentProc") == 0) {
	    wmPtr->style = documentProc;
	} else if (strcmp(argv[3], "noGrowDocProc") == 0) {
	    wmPtr->style = documentProc;
	} else if (strcmp(argv[3], "dBoxProc") == 0) {
	    wmPtr->style = dBoxProc;
	} else if (strcmp(argv[3], "plainDBox") == 0) {
	    wmPtr->style = plainDBox;
	} else if (strcmp(argv[3], "altDBoxProc") == 0) {
	    wmPtr->style = altDBoxProc;
	} else if (strcmp(argv[3], "movableDBoxProc") == 0) {
	    wmPtr->style = movableDBoxProc;
	} else if (strcmp(argv[3], "zoomDocProc") == 0) {
	    wmPtr->style = zoomDocProc;
	} else if (strcmp(argv[3], "zoomNoGrow") == 0) {
	    wmPtr->style = zoomNoGrow;
	} else if (strcmp(argv[3], "rDocProc") == 0) {
	    wmPtr->style = rDocProc;
	} else if (strcmp(argv[3], "floatProc") == 0) {
	    wmPtr->style = floatGrowProc;
	} else if (strcmp(argv[3], "floatGrowProc") == 0) {
	    wmPtr->style = floatGrowProc;
	} else if (strcmp(argv[3], "floatZoomProc") == 0) {
	    wmPtr->style = floatZoomGrowProc;
	} else if (strcmp(argv[3], "floatZoomGrowProc") == 0) {
	    wmPtr->style = floatZoomGrowProc;
	} else if (strcmp(argv[3], "floatSideProc") == 0) {
	    wmPtr->style = floatSideGrowProc;
	} else if (strcmp(argv[3], "floatSideGrowProc") == 0) {
	    wmPtr->style = floatSideGrowProc;
	} else if (strcmp(argv[3], "floatSideZoomProc") == 0) {
	    wmPtr->style = floatSideZoomGrowProc;
	} else if (strcmp(argv[3], "floatSideZoomGrowProc") == 0) {
	    wmPtr->style = floatSideZoomGrowProc;
	} else {
	    Tcl_AppendResult(interp, "bad style: should be documentProc, ",
	    	    "dBoxProc, plainDBox, altDBoxProc, movableDBoxProc, ",
	    	    "zoomDocProc, rDocProc, floatProc, floatZoomProc, ",
		    "floatSideProc, or floatSideZoomProc",
		    (char *) NULL);
	    return TCL_ERROR;
	}
d4290 1
a4290 1
	                argv[4], "\".", (char *) NULL);
d4353 1
a4353 1
    
@


1.17
log
@	* mac/tkMacWm.c (Tk_WmCmd):
	* tests/unixWm.test: Move wm transient checks over
	to wm.test so they will be run on all systems.
	* tests/wm.test: Add tests to check for error when
	an iconwindow is passed to the wm transient command.
	* unix/tkUnixWm.c (Tk_WmCmd):
	* win/tkWinWm.c (Tk_WmCmd): Raise an error if one
	of the windows passed to the wm transient command
	is an iconwindow for another toplevel.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.16 2002/05/23 19:55:18 mdejong Exp $
d1873 1
a1873 1
    while (!(winPtr->flags & TK_TOP_LEVEL)) {
d1877 3
d1961 1
a1961 1
    while (!(winPtr->flags & TK_TOP_LEVEL)) {
d1965 4
d2521 1
a2521 1
	if (winPtr->flags & TK_TOP_LEVEL) {
d2571 3
d2681 1
a2681 1
			(childPtr->flags & TK_TOP_LEVEL)) {
d2775 1
a2775 1
			(childPtr->flags & TK_TOP_LEVEL)) {
d2908 1
a2908 1
    while (!(winPtr->flags & TK_TOP_LEVEL)) {
d2912 3
d3338 1
a3338 1
	if (topPtr->flags & TK_TOP_LEVEL) {
d3342 4
d3432 1
a3432 1
	if (topPtr->flags & TK_TOP_LEVEL) {
d3450 4
d4672 1
a4672 1
    if (!(winPtr->flags & TK_TOP_LEVEL)) {
@


1.16
log
@	* mac/tkMacWm.c (TkWmStackorderToplevelWrapperMap):
	* tests/wm.test: Add embedded Window test case for
	the stackorder command.
	* unix/tkUnixWm.c (TkWmStackorderToplevelWrapperMap):
	* win/tkWinWm.c (TkWmStackorderToplevelWrapperMap):
	Ignore embedded windows during wm stackorder command.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.15 2002/04/10 19:39:01 mdejong Exp $
d1747 1
d1773 19
@


1.15
log
@	* doc/wm.n:
	* mac/tkMacWm.c:
	* tests/wm.test:
	* unix/tkUnixWm.c:
	* win/tkWinWm.c: Update wm stackorder usage message
	to make it clear that either 1 or 3 arguments are
	required. [Bug 540013]
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.14 2002/01/25 21:09:37 dgp Exp $
d3050 2
a3051 1
    if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr)) {
@


1.14
log
@	* Updated callers of Tcl_SplitList and Tcl_Merge.
	* Updated callers of Tcl_GetStringResult.
	  Rewrote PrintScrollFractions to ScrollFractions to stop scribbling
	  directly on interp->result.
	* Updated callers of Tcl_GetVar, Tcl_GetVar2
	* Updated callers of Tcl_SplitPath, Tcl_JoinPath, and
	  Tcl_TranslateFileName.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.13 2001/12/05 01:30:44 das Exp $
d1562 1
a1562 1
		    " stackorder window ?isabove|isbelow? ?window?\"",
@


1.13
log
@	* mac/tkMacWm.c: mac implementation of wm stackorder
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.12 2001/11/23 02:06:44 das Exp $
d197 1
a197 1
    char **cmdArgv;		/* Array of strings to store in the
d817 1
a817 1
	char **windowArgv;
d883 1
a883 1
	char **cmdArgv;
d4234 1
a4234 1
	        char **attrArgv = NULL;
@


1.12
log
@	**  upport to 8.4 of mac code changes for 8.3.3 & various new
	**  changes for 8.4, some already backported to 8.3.4 (patch #435660)

	see ChangeLog for details
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.11 2001/08/06 18:29:41 dgp Exp $
d323 3
d736 1
a736 1
    if (!(winPtr->flags & TK_TOP_LEVEL)) {
d1555 93
d1796 2
a1797 2
		"positionfrom, protocol, resizable, sizefrom, state, title, ",
		"transient, or withdraw",
d3023 126
d4008 1
a4008 1
    if (!(winPtr->flags & TK_TOP_LEVEL)) {
@


1.11
log
@	* TIP 44 changes specific to the Mac and
	Windows platforms that were overlooked before: tkOpenDocument,
	tkConsoleExit, tkConsoleOutput, unsupported1 out of namespace :: .
	Thanks to Vince Darley for prompting another look.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.10 2000/04/25 01:02:13 hobbs Exp $
d4537 4
d4542 1
@


1.11.2.1
log
@Merge with current TOT
Added support for the wm stackorder command
Fixed crash when selecting Menu items in the Application menu that we didn't
put there.
Added first bits of the use of CG for low-level drawing.  The line-drawing works,
the rest doesn't yet.  You have to set the file static useCGDrawing to 1 and
rebuild to activate this code.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.11 2001/08/06 18:29:41 dgp Exp $
d197 1
a197 1
    CONST char **cmdArgv;	/* Array of strings to store in the
a322 3
static void		TkWmStackorderToplevelWrapperMap _ANSI_ARGS_((
			    TkWindow *winPtr,
			    Tcl_HashTable *reparentTable));
d733 1
a733 1
    if (!Tk_IsTopLevel(winPtr)) {
d814 1
a814 1
	CONST char **windowArgv;
d880 1
a880 1
	CONST char **cmdArgv;
a1551 93
    } else if ((c == 's') && (strncmp(argv[1], "stackorder", length) == 0)
	    && (length >= 2)) {
	TkWindow **windows, **window_ptr;

	if ((argc != 3) && (argc != 5)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0],
		    " stackorder window ?isabove|isbelow? ?window?\"",
		    (char *) NULL);
	    return TCL_ERROR;
	}

	if (argc == 3) {
            windows = TkWmStackorderToplevel(winPtr);
            if (windows == NULL) {
                panic("TkWmStackorderToplevel failed");
	    } else {
                for (window_ptr = windows; *window_ptr ; window_ptr++) {
                    Tcl_AppendElement(interp, (*window_ptr)->pathName);
                }
                ckfree((char *) windows);
                return TCL_OK;
	    }
	} else {
	    TkWindow *winPtr2;
	    int index1=-1, index2=-1, result;

	    winPtr2 = (TkWindow *) Tk_NameToWindow(interp, argv[4], tkwin);
	    if (winPtr2 == NULL) {
		return TCL_ERROR;
	    }

	    if (!Tk_IsTopLevel(winPtr2)) {
		Tcl_AppendResult(interp, "window \"", winPtr2->pathName,
		    "\" isn't a top-level window", (char *) NULL);
		return TCL_ERROR;
	    }

	    if (!Tk_IsMapped(winPtr)) {
		Tcl_AppendResult(interp, "window \"", winPtr->pathName,
		    "\" isn't mapped", (char *) NULL);
		return TCL_ERROR;
	    }

	    if (!Tk_IsMapped(winPtr2)) {
		Tcl_AppendResult(interp, "window \"", winPtr2->pathName,
		    "\" isn't mapped", (char *) 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_AppendResult(interp, "TkWmStackorderToplevel failed",
                    (char *) NULL);
                return TCL_ERROR;
	    } else {
                for (window_ptr = windows; *window_ptr ; window_ptr++) {
                    if (*window_ptr == winPtr)
                        index1 = (window_ptr - windows);
                    if (*window_ptr == winPtr2)
                        index2 = (window_ptr - windows);
                }
                if (index1 == -1)
                    panic("winPtr window not found");
                if (index2 == -1)
                    panic("winPtr2 window not found");

                ckfree((char *) windows);
	    }

	    c = argv[3][0];
	    length = strlen(argv[3]);
	    if ((length > 2) && (c == 'i')
		    && (strncmp(argv[3], "isabove", length) == 0)) {
		result = index1 > index2;
	    } else if ((length > 2) && (c == 'i')
		    && (strncmp(argv[3], "isbelow", length) == 0)) {
		result = index1 < index2;
	    } else {
		Tcl_AppendResult(interp, "bad argument \"", argv[3],
			"\": must be isabove or isbelow", (char *) NULL);
		return TCL_ERROR;
	    }
	    Tcl_SetIntObj(Tcl_GetObjResult(interp), result);
	    return TCL_OK;
	}
d1700 2
a1701 2
		"positionfrom, protocol, resizable, sizefrom, stackorder, ",
		"state, title, transient, or withdraw",
a2926 126
 * TkWmStackorderToplevelWrapperMap --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */
void
TkWmStackorderToplevelWrapperMap(winPtr, table)
    TkWindow *winPtr;				/* TkWindow to recurse on */
    Tcl_HashTable *table;			/* Maps mac window to TkWindow */
{
    TkWindow *childPtr;
    Tcl_HashEntry *hPtr;
    WindowPeek wrapper;
    int newEntry;

    if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr)) {
        wrapper = (WindowPeek) TkMacGetDrawablePort(winPtr->window);

        hPtr = Tcl_CreateHashEntry(table,
            (char *) wrapper, &newEntry);
        Tcl_SetHashValue(hPtr, winPtr);
    }

    for (childPtr = winPtr->childList; childPtr != NULL;
            childPtr = childPtr->nextPtr) {
        TkWmStackorderToplevelWrapperMap(childPtr, 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(parentPtr)
    TkWindow *parentPtr;		/* Parent toplevel window. */
{
    WindowPeek frontWindow;
    TkWindow *childWinPtr, **windows, **window_ptr;
    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);
    TkWmStackorderToplevelWrapperMap(parentPtr, &table);

    windows = (TkWindow **) 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] = (TkWindow *) Tcl_GetHashValue(hPtr);
        windows[1] = NULL;
        goto done;
    }

    if (TkMacHaveAppearance() >= 0x110) {
        frontWindow = (WindowPeek) FrontNonFloatingWindow();
    } else {	
    	frontWindow = (WindowPeek) FrontWindow();
    }

    if (frontWindow == NULL) {
        ckfree((char *) windows);
        windows = NULL;
    } else {
    	window_ptr = windows + table.numEntries;
    	*window_ptr-- = NULL;
	    while (frontWindow != NULL) {
		    hPtr = Tcl_FindHashEntry(&table, (char *) frontWindow);
            if (hPtr != NULL) {
                childWinPtr = (TkWindow *) Tcl_GetHashValue(hPtr);
                *window_ptr-- = childWinPtr;
            }
			frontWindow = frontWindow->nextWindow;
	    }
        if (window_ptr != (windows-1))
            panic("num matched toplevel windows does not equal num children");
    }

    done:
    Tcl_DeleteHashTable(&table);
    return windows;
}

/*
 *----------------------------------------------------------------------
 *
d3786 1
a3786 1
    if (!Tk_IsTopLevel(winPtr)) {
d4012 1
a4012 1
	        CONST char **attrArgv = NULL;
a4536 4
/* even if AppearanceManager 1.1 routines are present,
we can't call them from 68K code, so we pretend
to be running Apperarance Mgr 1.0 */
#if !(GENERATING68K && !GENERATINGCFM)
a4537 1
#endif
@


1.11.2.2
log
@Merging with TOT as of 06/09/2002.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id$
d1562 1
a1562 1
		    " stackorder window ?isabove|isbelow window?\"",
a1746 1
	WmInfo *wmPtr2;
a1771 19

	    if (wmPtr->iconFor != NULL) {
	        Tcl_AppendResult(interp, "can't make \"", argv[2],
	    	        "\" a transient: it is an icon for ",
	                Tk_PathName(wmPtr->iconFor),
	                (char *) NULL);
	        return TCL_ERROR;
	    }

	    wmPtr2 = ((TkWindow *) master)->wmInfoPtr;

	    if (wmPtr2->iconFor != NULL) {
	        Tcl_AppendResult(interp, "can't make \"", argv[3],
	                "\" a master: it is an icon for ",
	                Tk_PathName(wmPtr2->iconFor),
	                (char *) NULL);
	        return TCL_ERROR;
	    }

d3050 1
a3050 2
    if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr) &&
            !Tk_IsEmbedded(winPtr)) {
@


1.11.2.3
log
@merged with trunk at tag macosx-8-4-merge-2002-08-20-trunk
@
text
@d1 1
a1 1
/*
d31 1
a31 1
 * and are on the SDK CD.  However, we do not require the Appearance
d34 1
a34 1

d52 1
a52 1
				 * message for this protocol arrives.
d76 3
a78 3
    char *title;		/* Title to display in window caption.  If
				 * NULL, use name of widget.  Malloced. */
    char *iconName;		/* Name to display in icon.  Malloced. */
d317 1
a317 1
static void		InitialWindowBounds _ANSI_ARGS_((TkWindow *winPtr,
a331 89
static int 		WmAspectCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmAttributesCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmClientCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmColormapwindowsCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmCommandCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmDeiconifyCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmFocusmodelCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmFrameCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmGeometryCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmGridCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmGroupCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmIconbitmapCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmIconifyCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmIconmaskCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmIconnameCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmIconpositionCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmIconwindowCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmMaxsizeCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmMinsizeCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmOverrideredirectCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmPositionfromCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmProtocolCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmResizableCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmSizefromCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmStackorderCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmStateCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmTitleCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmTransientCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static int 		WmWithdrawCmd _ANSI_ARGS_((Tk_Window tkwin,
			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
			    Tcl_Obj *CONST objv[]));
static void		WmUpdateGeom _ANSI_ARGS_((WmInfo *wmPtr,
			    TkWindow *winPtr));
d356 1
a356 1

d360 1
a360 1
    wmPtr->title = NULL;
d468 1
a468 1
    int xOffset, yOffset;
d483 1
a483 1

d492 1
a492 1
	TkGenWMConfigureEvent((Tk_Window) winPtr,
d494 1
a494 1

d501 4
d506 1
a506 2
	    TkSetWMName(winPtr, ((wmPtr->title != NULL) ?
		    wmPtr->title : winPtr->nameUid);
d510 1
a510 1

d514 1
a514 1

d520 1
a520 1

d528 1
a528 1

d544 1
a544 1

d550 1
a550 1
    TkMacWindowOffset((WindowRef) TkMacGetDrawablePort(Tk_WindowId(winPtr)),
a606 6
    if (wmPtr->title != NULL) {
	ckfree(wmPtr->title);
    }
    if (wmPtr->iconName != NULL) {
	ckfree(wmPtr->iconName);
    }
d678 1
a678 1
 * Tk_WmObjCmd --
d694 1
a694 1
Tk_WmObjCmd(
d698 2
a699 2
    int objc,			/* Number of arguments. */
    Tcl_Obj *CONST objv[])	/* Argument objects. */
a701 20
    static CONST char *optionStrings[] = {
	"aspect", "attributes", "client", "colormapwindows",
	"command", "deiconify", "focusmodel", "frame",
	"geometry", "grid", "group", "iconbitmap",
	"iconify", "iconmask", "iconname", "iconposition",
	"iconwindow", "maxsize", "minsize", "overrideredirect",
        "positionfrom", "protocol", "resizable", "sizefrom",
        "stackorder", "state", "title", "transient",
	"withdraw", (char *) NULL };
    enum options {
        WMOPT_ASPECT, WMOPT_ATTRIBUTES, WMOPT_CLIENT, WMOPT_COLORMAPWINDOWS,
	WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL, WMOPT_FRAME,
	WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP, WMOPT_ICONBITMAP,
	WMOPT_ICONIFY, WMOPT_ICONMASK, WMOPT_ICONNAME, WMOPT_ICONPOSITION,
	WMOPT_ICONWINDOW, 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;
d703 3
a705 1
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
d707 1
a707 1
    if (objc < 2) {
d709 2
a710 1
	Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?");
d713 3
a715 3

    argv1 = Tcl_GetStringFromObj(objv[1], &length);
    if ((argv1[0] == 't') && (strncmp(argv1, "tracing", length) == 0)
d717 3
a719 2
	if ((objc != 2) && (objc != 3)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?boolean?");
d722 1
a722 1
	if (objc == 2) {
d726 1
a726 1
	return Tcl_GetBooleanFromObj(interp, objv[2], &wmTracing);
d729 1
a729 6
    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }

    if (objc < 3) {
d732 2
a733 3

    if (TkGetWindowFromObj(interp, tkwin, objv[2], (Tk_Window *) &winPtr)
	    != TCL_OK) {
d741 3
d745 9
a753 60
    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_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_ICONPOSITION:
	return WmIconpositionCmd(tkwin, winPtr, interp, objc, objv);
      case WMOPT_ICONWINDOW:
	return WmIconwindowCmd(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);
    }
d755 27
a781 45
    /* 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(tkwin, winPtr, interp, objc, objv)
    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) {
	    char buf[TCL_INTEGER_SPACE * 4];

	    sprintf(buf, "%d %d %d %d", wmPtr->minAspect.x,
		    wmPtr->minAspect.y, wmPtr->maxAspect.x,
		    wmPtr->maxAspect.y);
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
d783 8
a790 9
	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)) {
d793 5
a797 5
	if ((numer1 <= 0) || (denom1 <= 0) || (numer2 <= 0) ||
		(denom2 <= 0)) {
	    Tcl_SetResult(interp, "aspect number can't be <= 0",
		    TCL_STATIC);
	    return TCL_ERROR;
d799 6
a804 79
	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;
}

/*
 *----------------------------------------------------------------------
 *
 * 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(tkwin, winPtr, interp, objc, objv)
    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. */
{
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	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(tkwin, winPtr, interp, objc, objv)
    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_SetResult(interp, wmPtr->clientMachine, TCL_STATIC);
a805 4
	return TCL_OK;
    }
    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    if (argv3[0] == 0) {
a807 1
	    wmPtr->clientMachine = NULL;
d809 9
a817 28
	return TCL_OK;
    }
    if (wmPtr->clientMachine != NULL) {
	ckfree((char *) wmPtr->clientMachine);
    }
    wmPtr->clientMachine = (char *)
	    ckalloc((unsigned) (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.
 *
 *----------------------------------------------------------------------
 */
d819 36
a854 24
static int
WmColormapwindowsCmd(tkwin, winPtr, interp, objc, objv)
    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;
    TkWindow *winPtr2;
    int i, windowObjc, gotToplevel = 0;
    Tcl_Obj **windowObjv;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?windowList?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tk_MakeWindowExist((Tk_Window) winPtr);
	for (i = 0; i < wmPtr->cmapCount; i++) {
	    if ((i == (wmPtr->cmapCount-1))
		    && (wmPtr->flags & WM_ADDED_TOPLEVEL_COLORMAP)) {
		break;
d856 8
a863 1
	    Tcl_AppendElement(interp, wmPtr->cmapList[i]->pathName);
d865 7
a871 36
	return TCL_OK;
    }
    if (Tcl_ListObjGetElements(interp, objv[3], &windowObjc, &windowObjv)
	    != TCL_OK) {
	return TCL_ERROR;
    }
    cmapList = (TkWindow **) ckalloc((unsigned)
	    ((windowObjc+1)*sizeof(TkWindow*)));
    for (i = 0; i < windowObjc; i++) {
	if (TkGetWindowFromObj(interp, tkwin, windowObjv[i],
		(Tk_Window *) &winPtr2) != TCL_OK)
	{
	    ckfree((char *) 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((char *)wmPtr->cmapList);
    }
    wmPtr->cmapList = cmapList;
    wmPtr->cmapCount = windowObjc;
d873 5
a877 5
    /*
     * 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.
     */
d879 5
a883 19
    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.
 *
 *----------------------------------------------------------------------
 */
d885 23
a907 22
static int
WmCommandCmd(tkwin, winPtr, interp, objc, objv)
    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) {
	    Tcl_SetResult(interp,
		    Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv),
		    TCL_DYNAMIC);
a908 4
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (argv3[0] == 0) {
a910 1
	    wmPtr->cmdArgv = NULL;
d912 77
a988 29
	return TCL_OK;
    }
    if (Tcl_SplitList(interp, argv3, &cmdArgc, &cmdArgv) != TCL_OK) {
	return TCL_ERROR;
    }
    if (wmPtr->cmdArgv != NULL) {
	ckfree((char *) 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.
 *
 *----------------------------------------------------------------------
 */
d990 25
a1014 9
static int
WmDeiconifyCmd(tkwin, winPtr, interp, objc, objv)
    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;
d1016 9
a1024 15
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_AppendResult(interp, "can't deiconify ", Tcl_GetString(objv[2]),
		": it is an icon for ", Tk_PathName(wmPtr->iconFor),
		(char *) NULL);
	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	Tcl_AppendResult(interp, "can't deiconify ", winPtr->pathName,
		": it is an embedded window", (char *) NULL);
	return TCL_ERROR;
    }
d1026 12
a1037 3
    /*
     * TODO: may not want to call this function - look at Map events gened.
     */
d1039 40
a1078 20
    TkpWmSetState(winPtr, 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.
 *
 *----------------------------------------------------------------------
 */
d1080 18
a1097 123
static int
WmFocusmodelCmd(tkwin, winPtr, interp, objc, objv)
    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 *optionStrings[] = {
	"active", "passive", (char *) 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_SetResult(interp, (wmPtr->hints.input ? "passive" : "active"),
		TCL_STATIC);
	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;
}

/*
 *----------------------------------------------------------------------
 *
 * 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(tkwin, winPtr, interp, objc, objv)
    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;
    char buf[TCL_INTEGER_SPACE];

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    window = wmPtr->reparent;
    if (window == None) {
	window = Tk_WindowId((Tk_Window) winPtr);
    }
    sprintf(buf, "0x%x", (unsigned int) window);
    Tcl_SetResult(interp, buf, TCL_VOLATILE);
    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(tkwin, winPtr, interp, objc, objv)
    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) {
	char buf[16 + TCL_INTEGER_SPACE * 4];

	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;
d1099 19
a1117 2
	    width = winPtr->changes.width;
	    height = winPtr->changes.height;
d1119 7
a1125 56
	sprintf(buf, "%dx%d%c%d%c%d", width, height, xSign, wmPtr->x,
		ySign, wmPtr->y);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	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(tkwin, winPtr, interp, objc, objv)
    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;

    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) {
	    char buf[TCL_INTEGER_SPACE * 4];

	    sprintf(buf, "%d %d %d %d", wmPtr->reqGridWidth,
		    wmPtr->reqGridHeight, wmPtr->widthInc,
		    wmPtr->heightInc);
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
d1127 13
a1139 14
	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;
d1141 5
a1145 7
	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)) {
d1148 3
a1150 2
	if (reqWidth < 0) {
	    Tcl_SetResult(interp, "baseWidth can't be < 0", TCL_STATIC);
d1153 3
a1155 2
	if (reqHeight < 0) {
	    Tcl_SetResult(interp, "baseHeight can't be < 0", TCL_STATIC);
d1158 4
a1161 2
	if (widthInc < 0) {
	    Tcl_SetResult(interp, "widthInc can't be < 0", TCL_STATIC);
d1164 14
a1177 2
	if (heightInc < 0) {
	    Tcl_SetResult(interp, "heightInc can't be < 0", TCL_STATIC);
d1180 7
a1186 45
	Tk_SetGrid((Tk_Window) winPtr, reqWidth, reqHeight, widthInc,
		heightInc);
    }
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    WmUpdateGeom(wmPtr, winPtr);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * 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(tkwin, winPtr, interp, objc, objv)
    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_SetResult(interp, wmPtr->leaderName, TCL_STATIC);
d1188 12
a1199 7
	return TCL_OK;
    }
    argv3 = Tcl_GetStringFromObj(objv[3], &length);
    if (*argv3 == '\0') {
	wmPtr->hints.flags &= ~WindowGroupHint;
	if (wmPtr->leaderName != NULL) {
	    ckfree(wmPtr->leaderName);
d1201 5
a1205 3
	wmPtr->leaderName = NULL;
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) {
d1208 10
a1217 3
	Tk_MakeWindowExist(tkwin2);
	if (wmPtr->leaderName != NULL) {
	    ckfree(wmPtr->leaderName);
d1219 9
a1227 46
	wmPtr->hints.window_group = Tk_WindowId(tkwin2);
	wmPtr->hints.flags |= WindowGroupHint;
	wmPtr->leaderName = ckalloc((unsigned) (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(tkwin, winPtr, interp, objc, objv)
    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;
    Pixmap pixmap;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?bitmap?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->hints.flags & IconPixmapHint) {
	    Tcl_SetResult(interp,
		    Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_pixmap),
		    TCL_STATIC);
d1229 9
a1237 7
	return TCL_OK;
    }
    argv3 = Tcl_GetString(objv[3]);
    if (*argv3 == '\0') {
	if (wmPtr->hints.icon_pixmap != None) {
	    Tk_FreeBitmap(winPtr->display, wmPtr->hints.icon_pixmap);
	    wmPtr->hints.icon_pixmap = None;
d1239 20
a1258 4
	wmPtr->hints.flags &= ~IconPixmapHint;
    } else {
	pixmap = Tk_GetBitmap(interp, (Tk_Window) winPtr, argv3);
	if (pixmap == None) {
d1261 43
a1303 22
	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.
 *
 *----------------------------------------------------------------------
 */
d1305 2
a1306 76
static int
WmIconifyCmd(tkwin, winPtr, interp, objc, objv)
    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_AppendResult(interp, "can't iconify \"", winPtr->pathName,
		"\": override-redirect flag is set", (char *) NULL);
	return TCL_ERROR;
    }
    if (wmPtr->master != None) {
	Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
		"\": it is a transient", (char *) NULL);
	return TCL_ERROR;
    }
    if (wmPtr->iconFor != NULL) {
	Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName,
		": it is an icon for ", Tk_PathName(wmPtr->iconFor),
		(char *) NULL);
	return TCL_ERROR;
    }
    if (winPtr->flags & TK_EMBEDDED) {
	Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName,
		": it is an embedded window", (char *) 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(tkwin, winPtr, interp, objc, objv)
    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_SetResult(interp,
		    Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_mask),
		    TCL_STATIC);
d1308 6
a1313 11
	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) {
d1316 1
a1316 93
	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(tkwin, winPtr, interp, objc, objv)
    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 ?newName?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_SetResult(interp,
		((wmPtr->iconName != NULL) ? wmPtr->iconName : ""),
		TCL_STATIC);
	return TCL_OK;
    } else {
	if (wmPtr->iconName != NULL) {
	    ckfree((char *) wmPtr->iconName);
	}
	argv3 = Tcl_GetStringFromObj(objv[3], &length);
	wmPtr->iconName = ckalloc((unsigned) (length + 1));
	strcpy(wmPtr->iconName, argv3);
	if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
	    XSetIconName(winPtr->display, winPtr->window, wmPtr->iconName);
	}
    }
    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(tkwin, winPtr, interp, objc, objv)
    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) {
d1318 2
a1319 3

	    sprintf(buf, "%d %d", wmPtr->hints.icon_x,
		    wmPtr->hints.icon_y);
d1321 1
d1323 2
a1324 7
	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)){
d1327 11
a1337 43
	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(tkwin, winPtr, interp, objc, objv)
    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_SetResult(interp, Tk_PathName(wmPtr->icon), TCL_STATIC);
d1339 6
a1344 8
	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;
d1346 2
a1347 3
	wmPtr->icon = NULL;
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3], &tkwin2) != TCL_OK) {
d1350 13
a1362 3
	if (!Tk_IsTopLevel(tkwin2)) {
	    Tcl_AppendResult(interp, "can't use ", Tcl_GetString(objv[3]),
		    " as icon window: not at top level", (char *) NULL);
d1365 9
a1373 5
	wmPtr2 = ((TkWindow *) tkwin2)->wmInfoPtr;
	if (wmPtr2->iconFor != NULL) {
	    Tcl_AppendResult(interp, Tcl_GetString(objv[3]),
		    " is already an icon for ",
		    Tk_PathName(wmPtr2->iconFor), (char *) NULL);
d1376 10
a1385 219
	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;
}

/*
 *----------------------------------------------------------------------
 *
 * 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(tkwin, winPtr, interp, objc, objv)
    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) {
	char buf[TCL_INTEGER_SPACE * 2];

	sprintf(buf, "%d %d", wmPtr->maxWidth, wmPtr->maxHeight);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	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(tkwin, winPtr, interp, objc, objv)
    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) {
	char buf[TCL_INTEGER_SPACE * 2];

	sprintf(buf, "%d %d", wmPtr->minWidth, wmPtr->minHeight);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	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(tkwin, winPtr, interp, objc, objv)
    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 boolean;
    XSetWindowAttributes atts;

    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	Tcl_SetBooleanObj(Tcl_GetObjResult(interp),
		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);
    wmPtr->style = (boolean) ? plainDBox : documentProc;
    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(tkwin, winPtr, interp, objc, objv)
    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 *optionStrings[] = {
	"program", "user", (char *) 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_SetResult(interp, "user", TCL_STATIC);
	} else if (wmPtr->sizeHintsFlags & PPosition) {
	    Tcl_SetResult(interp, "program", TCL_STATIC);
	}
	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) {
d1388 10
a1397 3
	if (index == OPT_USER) {
	    wmPtr->sizeHintsFlags &= ~PPosition;
	    wmPtr->sizeHintsFlags |= USPosition;
d1399 53
a1451 2
	    wmPtr->sizeHintsFlags &= ~USPosition;
	    wmPtr->sizeHintsFlags |= PPosition;
a1452 36
    }
    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(tkwin, winPtr, interp, objc, objv)
    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;
a1453 5
    if ((objc < 3) || (objc > 5)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?name? ?command?");
	return TCL_ERROR;
    }
    if (objc == 3) {
d1455 3
a1457 1
	 * Return a list of all defined protocols for the window.
d1459 3
a1461 14
	for (protPtr = wmPtr->protPtr; protPtr != NULL;
	     protPtr = protPtr->nextPtr) {
	    Tcl_AppendElement(interp,
		    Tk_GetAtomName((Tk_Window) winPtr, protPtr->protocol));
	}
	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) {
d1463 7
a1469 2
		Tcl_SetResult(interp, protPtr->command, TCL_STATIC);
		return TCL_OK;
d1472 20
a1491 2
	return TCL_OK;
    }
d1493 19
a1511 16
    /*
     * 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((ClientData) protPtr, TCL_DYNAMIC);
	    break;
d1513 3
a1515 71
    }
    cmd = Tcl_GetStringFromObj(objv[4], &cmdLength);
    if (cmdLength > 0) {
	protPtr = (ProtocolHandler *) 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(tkwin, winPtr, interp, objc, objv)
    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) {
	char buf[TCL_INTEGER_SPACE * 2];

	sprintf(buf, "%d %d",
		(wmPtr->flags  & WM_WIDTH_NOT_RESIZABLE) ? 0 : 1,
		(wmPtr->flags  & WM_HEIGHT_NOT_RESIZABLE) ? 0 : 1);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
	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;
    } else {
	wmPtr->flags |= WM_WIDTH_NOT_RESIZABLE;
    }
    if (height) {
	wmPtr->flags &= ~WM_HEIGHT_NOT_RESIZABLE;
    } else {
	wmPtr->flags |= WM_HEIGHT_NOT_RESIZABLE;
    }
    wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
    if (wmPtr->scrollWinPtr != NULL) {
	TkScrollbarEventuallyRedraw(
a1516 46
    }
    WmUpdateGeom(wmPtr, winPtr);
    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(tkwin, winPtr, interp, objc, objv)
    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 *optionStrings[] = {
	"program", "user", (char *) 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_SetResult(interp, "user", TCL_STATIC);
	} else if (wmPtr->sizeHintsFlags & PSize) {
	    Tcl_SetResult(interp, "program", TCL_STATIC);
d1518 7
a1524 8
	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) {
d1527 7
a1533 6
	if (index == OPT_USER) {
	    wmPtr->sizeHintsFlags &= ~PSize;
	    wmPtr->sizeHintsFlags |= USSize;
	} else { /* OPT_PROGRAM */
	    wmPtr->sizeHintsFlags &= ~USSize;
	    wmPtr->sizeHintsFlags |= PSize;
d1535 2
a1536 47
    }
    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(tkwin, winPtr, interp, objc, objv)
    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, **window_ptr;
    static CONST char *optionStrings[] = {
	"isabove", "isbelow", (char *) NULL };
    enum options {
	OPT_ISABOVE, OPT_ISBELOW };
    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) {
	    panic("TkWmStackorderToplevel failed");
d1538 13
a1550 2
	    for (window_ptr = windows; *window_ptr ; window_ptr++) {
		Tcl_AppendElement(interp, (*window_ptr)->pathName);
a1551 2
	    ckfree((char *) windows);
	    return TCL_OK;
d1553 11
a1563 6
    } else {
	TkWindow *winPtr2;
	int index1=-1, index2=-1, result;

	if (TkGetWindowFromObj(interp, tkwin, objv[4], (Tk_Window *) &winPtr2)
		!= TCL_OK) {
d1567 22
a1588 2
	if (!Tk_IsTopLevel(winPtr2)) {
	    Tcl_AppendResult(interp, "window \"", winPtr2->pathName,
d1590 2
a1591 2
	    return TCL_ERROR;
	}
d1593 2
a1594 2
	if (!Tk_IsMapped(winPtr)) {
	    Tcl_AppendResult(interp, "window \"", winPtr->pathName,
d1596 2
a1597 2
	    return TCL_ERROR;
	}
d1599 2
a1600 2
	if (!Tk_IsMapped(winPtr2)) {
	    Tcl_AppendResult(interp, "window \"", winPtr2->pathName,
d1602 2
a1603 2
	    return TCL_ERROR;
	}
d1605 5
a1609 5
	/*
	 * Lookup stacking order of all toplevels that are children
	 * of "." and find the position of winPtr and winPtr2
	 * in the stacking order.
	 */
d1611 1
a1611 1
	windows = TkWmStackorderToplevel(winPtr->mainPtr->winPtr);
d1613 2
a1614 2
	if (windows == NULL) {
	    Tcl_AppendResult(interp, "TkWmStackorderToplevel failed",
d1616 14
a1629 7
	    return TCL_ERROR;
	} else {
	    for (window_ptr = windows; *window_ptr ; window_ptr++) {
		if (*window_ptr == winPtr)
		    index1 = (window_ptr - windows);
		if (*window_ptr == winPtr2)
		    index2 = (window_ptr - windows);
a1630 4
	    if (index1 == -1)
		panic("winPtr window not found");
	    if (index2 == -1)
		panic("winPtr2 window not found");
d1632 15
a1646 61
	    ckfree((char *) 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_SetIntObj(Tcl_GetObjResult(interp), 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(tkwin, winPtr, interp, objc, objv)
    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 *optionStrings[] = {
	"normal", "iconic", "withdrawn", "zoomed", (char *) 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_AppendResult(interp, "can't change state of ",
		    Tcl_GetString(objv[2]),
		    ": it is an icon for ", Tk_PathName(wmPtr->iconFor),
		    (char *) NULL);
	    return TCL_ERROR;
d1648 5
a1652 4
	if (winPtr->flags & TK_EMBEDDED) {
	    Tcl_AppendResult(interp, "can't change state of ",
		    winPtr->pathName, ": it is an embedded window",
		    (char *) NULL);
d1655 13
d1669 2
a1670 4
	if (Tcl_GetIndexFromObj(interp, objv[3], optionStrings, "argument", 0,
		&index) != TCL_OK) {
	    return TCL_ERROR;
	}
d1672 31
a1702 11
	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_AppendResult(interp, "can't iconify \"",
			winPtr->pathName,
			"\": override-redirect flag is set",
d1706 18
a1723 5
	    if (wmPtr->master != NULL) {
		Tcl_AppendResult(interp, "can't iconify \"",
			winPtr->pathName,
			"\": it is a transient", (char *) NULL);
		return TCL_ERROR;
a1724 5
	    TkpWmSetState(winPtr, IconicState);
	} else if (index == OPT_WITHDRAWN) {
	    TkpWmSetState(winPtr, WithdrawnState);
	} else { /* OPT_ZOOMED */
	    TkpWmSetState(winPtr, ZoomState);
d1726 12
a1737 3
    } else {
	if (wmPtr->iconFor != NULL) {
	    Tcl_SetResult(interp, "icon", TCL_STATIC);
d1739 3
a1741 13
	    switch (wmPtr->hints.initial_state) {
	      case NormalState:
		Tcl_SetResult(interp, "normal", TCL_STATIC);
		break;
	      case IconicState:
		Tcl_SetResult(interp, "iconic", TCL_STATIC);
		break;
	      case WithdrawnState:
		Tcl_SetResult(interp, "withdrawn", TCL_STATIC);
		break;
	      case ZoomState:
		Tcl_SetResult(interp, "zoomed", TCL_STATIC);
		break;
d1744 4
a1747 20
    }
    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.
 *
 *----------------------------------------------------------------------
 */
d1749 4
a1752 24
static int
WmTitleCmd(tkwin, winPtr, interp, objc, objv)
    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_SetResult(interp,
		((wmPtr->title != NULL) ? wmPtr->title : winPtr->nameUid),
		TCL_STATIC);
	return TCL_OK;
    } else {
	if (wmPtr->title != NULL) {
	    ckfree((char *) wmPtr->title);
d1754 5
a1758 5
	argv3 = Tcl_GetStringFromObj(objv[3], &length);
	wmPtr->title = ckalloc((unsigned) (length + 1));
	strcpy(wmPtr->title, argv3);
	if (!(wmPtr->flags & WM_NEVER_MAPPED) && !Tk_IsEmbedded(winPtr)) {
	    TkSetWMName(winPtr, wmPtr->title);
d1760 23
a1782 20
    }
    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.
 *
 *----------------------------------------------------------------------
 */
d1784 7
a1790 13
static int
WmTransientCmd(tkwin, winPtr, interp, objc, objv)
    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;
d1792 9
a1800 19
    if ((objc != 3) && (objc != 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?master?");
	return TCL_ERROR;
    }
    if (objc == 3) {
	if (wmPtr->master != None) {
	    Tcl_SetResult(interp, wmPtr->masterWindowName, TCL_STATIC);
	}
	return TCL_OK;
    }
    if (Tcl_GetString(objv[3])[0] == '\0') {
	wmPtr->master = None;
	if (wmPtr->masterWindowName != NULL) {
	    ckfree(wmPtr->masterWindowName);
	}
	wmPtr->masterWindowName = NULL;
	wmPtr->style = documentProc;
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3], &master) != TCL_OK) {
a1802 2
	Tk_MakeWindowExist(master);

d1804 2
a1805 4
	    Tcl_AppendResult(interp, "can't make \"",
		    Tcl_GetString(objv[2]),
		    "\" a transient: it is an icon for ",
		    Tk_PathName(wmPtr->iconFor),
d1809 9
a1817 55

	wmPtr2 = ((TkWindow *) master)->wmInfoPtr;

	if (wmPtr2->iconFor != NULL) {
	    Tcl_AppendResult(interp, "can't make \"",
		    Tcl_GetString(objv[3]),
		    "\" a master: it is an icon for ",
		    Tk_PathName(wmPtr2->iconFor),
		    (char *) NULL);
	    return TCL_ERROR;
	}

	argv3 = Tcl_GetStringFromObj(objv[3], &length);
	wmPtr->master = Tk_WindowId(master);
	wmPtr->masterWindowName = ckalloc((unsigned) length+1);
	strcpy(wmPtr->masterWindowName, argv3);
	wmPtr->style = plainDBox;
    }
    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(tkwin, winPtr, interp, objc, objv)
    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_AppendResult(interp, "can't withdraw ", Tcl_GetString(objv[2]),
		": it is an icon for ", Tk_PathName(wmPtr->iconFor),
a1820 1
    TkpWmSetState(winPtr, WithdrawnState);
a1821 1
}
d1823 1
a1823 9
/*
 * Invoked by those wm subcommands that affect geometry.
 * Schedules a geometry update.
 */
static void
WmUpdateGeom(wmPtr, winPtr)
    WmInfo *wmPtr;
    TkWindow *winPtr;
{
d1828 1
d1873 1
a1873 1
    while (!(winPtr->flags & TK_TOP_HIERARCHY)) {
a1876 3
    if (wmPtr == NULL) {
	return;
    }
d1908 1
a1908 1
    /*
d1958 1
a1958 1
    while (!(winPtr->flags & TK_TOP_HIERARCHY)) {
a1961 4
    if (wmPtr == NULL) {
	return;
    }

d2021 1
a2021 1

d2198 1
a2198 1

d2203 1
a2203 1
	if (contWinPtr != NULL) {
d2514 1
a2514 1
	if (winPtr->flags & TK_TOP_HIERARCHY) {
d2518 1
a2518 1
	    	break;
d2521 1
a2521 1

d2529 1
a2529 1

d2535 1
a2535 1

d2538 1
a2538 1

d2541 1
a2541 1

d2544 1
a2544 1
		         * We do not require that the changes.x & changes.y for
d2551 1
a2551 1

d2554 1
a2554 1

d2556 1
a2556 1

a2563 3
	if (winPtr->flags & TK_TOP_HIERARCHY) {
	    break; /* Punt */
	}
d2613 1
a2613 1

d2640 1
a2640 1

d2645 1
a2645 1

d2653 1
a2653 1

d2661 1
a2661 1

d2666 1
a2666 1

d2671 1
a2671 1
			(childPtr->flags & TK_TOP_HIERARCHY)) {
d2741 1
a2741 1

d2745 2
a2746 2
		if (Tk_IsMapped(childPtr) &&
	    	         (x > childPtr->changes.x &&
d2751 1
a2751 1
				 childPtr->changes.height)) {
d2759 1
a2759 1

d2761 1
a2761 1

d2765 1
a2765 1
			(childPtr->flags & TK_TOP_HIERARCHY)) {
d2898 1
a2898 1
    while (!(winPtr->flags & TK_TOP_HIERARCHY)) {
a2901 3
    if (wmPtr == NULL) {
	return; /* Punt */
    }
d3140 1
a3140 1
    } else {
d3198 1
a3198 1

d3202 1
a3202 1

d3217 1
a3217 1

d3232 1
a3232 1

d3235 1
a3235 1
    } else {
d3238 1
a3238 1

d3241 1
a3241 1
	    /*
d3325 1
a3325 1
	if (topPtr->flags & TK_TOP_HIERARCHY) {
a3328 4
    if (topPtr->wmInfoPtr == NULL) {
	return;
    }

d3370 1
a3370 1
     * in compatability as we don't support colormaps.  If
d3415 1
a3415 1
	if (topPtr->flags & TK_TOP_HIERARCHY) {
a3432 4
    if (topPtr->wmInfoPtr == NULL) {
	return;
    }

d3506 1
a3506 1

d3508 1
a3508 1
	/*
d3512 1
a3512 1

d3526 1
a3526 1

d3539 1
a3539 1
 *	a toplevel window that is resizable.  If the window is
d3563 1
a3563 1

d3603 1
a3603 1

d3614 1
a3614 1

d3632 1
a3632 1

d3641 1
a3641 1
	    TkGenWMConfigureEvent((Tk_Window) winPtr, -1, -1,
d3656 1
a3656 1
 *	Set the title for a toplevel window.  If the window is embedded,
d3671 1
a3671 1
    char *title)
d3676 1
a3676 1

d3680 2
a3681 2
    Tcl_UtfToExternal(NULL, NULL, title,
	    strlen(title), 0, NULL,
d3685 1
a3685 1

d3696 1
a3696 1

d3700 1
a3700 1

d3714 1
a3714 1
 *	Generate a ConfigureNotify event for Tk.  Depending on the
d3739 1
a3739 1

d3743 1
a3743 1

d3776 1
a3776 1

d3778 1
a3778 1

d3789 1
a3789 1
	if ((flags & TK_SIZE_CHANGED) &&
d3827 1
a3827 1

d3940 2
a3941 2
     * We should now zoom the window (as long as it's one of ours).  We
     * also need to generate an event to let Tk know that the window size
d3969 1
a3969 1

d3978 1
a3978 1
    TkGenWMConfigureEvent(tkwin, location.h, location.v,
d3990 1
a3990 1
 *	This procedure is invoked to process the
d4054 1
a4054 1

d4057 1
a4057 1

d4102 1
a4102 1
		    panic("invalid style");
d4106 1
a4106 1

d4132 1
a4132 1
                    Tcl_ListObjAppendElement(interp, attributeList,
d4135 1
a4135 1
		    Tcl_ListObjAppendElement(interp, attributeList, 
d4138 2
a4139 2
		    Tcl_ListObjAppendElement(interp, attributeList, 
                            Tcl_NewStringObj("standardFloating", -1));
d4142 1
a4142 1
                        Tcl_ListObjAppendElement(interp, attributeList,
d4146 1
a4146 1
                        Tcl_ListObjAppendElement(interp, attributeList,
d4150 1
a4150 1
                        Tcl_ListObjAppendElement(interp, attributeList,
d4154 1
a4154 1
                        Tcl_ListObjAppendElement(interp, attributeList,
d4158 1
a4158 1
                        Tcl_ListObjAppendElement(interp, attributeList,
d4162 1
a4162 1
                        Tcl_ListObjAppendElement(interp, attributeList,
d4166 1
a4166 1
                        Tcl_ListObjAppendElement(interp, attributeList,
d4170 1
a4170 1
                        Tcl_ListObjAppendElement(interp, attributeList,
d4175 1
a4175 1
                Tcl_SetObjResult(interp, newResult);
d4179 42
a4220 42
	    if (strcmp(argv[3], "documentProc") == 0) {
		wmPtr->style = documentProc;
	    } else if (strcmp(argv[3], "noGrowDocProc") == 0) {
		wmPtr->style = documentProc;
	    } else if (strcmp(argv[3], "dBoxProc") == 0) {
		wmPtr->style = dBoxProc;
	    } else if (strcmp(argv[3], "plainDBox") == 0) {
		wmPtr->style = plainDBox;
	    } else if (strcmp(argv[3], "altDBoxProc") == 0) {
		wmPtr->style = altDBoxProc;
	    } else if (strcmp(argv[3], "movableDBoxProc") == 0) {
		wmPtr->style = movableDBoxProc;
	    } else if (strcmp(argv[3], "zoomDocProc") == 0) {
		wmPtr->style = zoomDocProc;
	    } else if (strcmp(argv[3], "zoomNoGrow") == 0) {
		wmPtr->style = zoomNoGrow;
	    } else if (strcmp(argv[3], "rDocProc") == 0) {
		wmPtr->style = rDocProc;
	    } else if (strcmp(argv[3], "floatProc") == 0) {
		wmPtr->style = floatGrowProc;
	    } else if (strcmp(argv[3], "floatGrowProc") == 0) {
		wmPtr->style = floatGrowProc;
	    } else if (strcmp(argv[3], "floatZoomProc") == 0) {
		wmPtr->style = floatZoomGrowProc;
	    } else if (strcmp(argv[3], "floatZoomGrowProc") == 0) {
		wmPtr->style = floatZoomGrowProc;
	    } else if (strcmp(argv[3], "floatSideProc") == 0) {
		wmPtr->style = floatSideGrowProc;
	    } else if (strcmp(argv[3], "floatSideGrowProc") == 0) {
		wmPtr->style = floatSideGrowProc;
	    } else if (strcmp(argv[3], "floatSideZoomProc") == 0) {
		wmPtr->style = floatSideZoomGrowProc;
	    } else if (strcmp(argv[3], "floatSideZoomGrowProc") == 0) {
		wmPtr->style = floatSideZoomGrowProc;
	    } else {
		Tcl_AppendResult(interp, "bad style: should be documentProc, ",
			"dBoxProc, plainDBox, altDBoxProc, movableDBoxProc, ",
			"zoomDocProc, rDocProc, floatProc, floatZoomProc, ",
			"floatSideProc, or floatSideZoomProc",
			(char *) NULL);
		return TCL_ERROR;
	    }
d4224 1
a4224 1

d4245 1
a4245 1

d4256 1
a4256 1

d4260 1
a4260 1
			    argv[4], "\".", (char *) NULL);
d4263 1
a4263 1

d4265 1
a4265 1

d4267 1
a4267 1
	            if ((*attrArgv[i] == 'c')
d4271 1
a4271 1
	            } else if ((*attrArgv[i] == 'h')
d4275 1
a4275 1
	            } else if ((*attrArgv[i] == 'v')
d4279 1
a4279 1
	            } else if ((*attrArgv[i] == 'c')
d4283 1
a4283 1
	            } else if ((*attrArgv[i] == 'r')
d4287 1
a4287 1
	            } else if ((*attrArgv[i] == 's')
d4296 1
a4296 1

d4300 1
a4300 1

d4304 2
a4305 2

	            Tcl_AppendResult(interp, "bad attribute: \"", argv[4],
d4314 1
a4314 1

d4323 1
a4323 1

d4332 1
a4332 1
 *	Configure the window to be either a undecorated pull-down
d4349 1
a4349 1
				 * menu is always visible, e.g. as a
d4367 1
a4367 1
 *	the Mac actually understands.
d4378 1
a4378 1
void
d4393 1
a4393 1

d4398 1
a4398 1
     * then return...
d4400 1
a4400 1

d4423 1
a4423 1

d4425 1
a4425 1

d4427 1
a4427 1

d4429 1
a4429 1
        OSStatus err;
d4437 1
a4437 1

d4440 1
a4440 1
        err = CreateNewWindow(wmPtr->macClass, wmPtr->attributes,
d4445 1
a4445 1

d4447 1
a4447 1
    newWindow = NewCWindow(NULL, &geometry, "\ptemp", false,
d4450 1
a4450 1

d4454 1
a4454 1

d4458 1
a4458 1

d4463 1
a4463 1

d4467 1
a4467 1

d4478 1
a4478 1

d4488 1
a4488 1
 *	hash table that maps Mac windows to root X windows.
d4499 1
a4499 1
void
d4527 1
a4527 1
 *	Given a macintosh port window, this function removes the
d4529 1
a4529 1
 *	Tk cares about.
d4540 1
a4540 1
void
d4557 1
a4557 1
 *	Tk scrollbar window will display the grow region for the
d4569 1
a4569 1
void
d4601 1
a4601 1
TkWindow *
d4606 1
a4606 1

d4651 1
a4651 1
    if (!(winPtr->flags & TK_TOP_HIERARCHY)) {
d4712 1
a4712 1

d4774 1
a4774 1

@


1.11.2.4
log
@various project cleanups & enhancements
added macosx/Makefile to facilitate building from cli
added [tk windowingsystem] and removed $::tcl_plaform(windowingsystem)
changed all runtime library references to the above
removed duplicate entries in tk.decls & tkInt.decls
CONSTification and other small changes in macosx/ to remove compiler warnings
@
text
@d5005 1
a5005 1
    CONST char **argv)		/* Argument strings. */
@


1.10
log
@	* mac/tkMacWm.c (Tk_WmCmd): initialized gotToplevel in
	colormapwindows case (bug found by Reasoning, Inc's automated code
	testing).
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.9 2000/02/10 08:57:11 jingham Exp $
d3747 3
a3749 3
 *	This procedure is invoked to process the "unsupported1" Tcl 
 *	command.  This command allows you to set the style of decoration
 *	for a Macintosh window.
@


1.10.4.1
log
@sync with head
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.14 2002/01/25 21:09:37 dgp Exp $
d197 1
a197 1
    CONST char **cmdArgv;	/* Array of strings to store in the
a322 3
static void		TkWmStackorderToplevelWrapperMap _ANSI_ARGS_((
			    TkWindow *winPtr,
			    Tcl_HashTable *reparentTable));
d733 1
a733 1
    if (!Tk_IsTopLevel(winPtr)) {
d814 1
a814 1
	CONST char **windowArgv;
d880 1
a880 1
	CONST char **cmdArgv;
a1551 93
    } else if ((c == 's') && (strncmp(argv[1], "stackorder", length) == 0)
	    && (length >= 2)) {
	TkWindow **windows, **window_ptr;

	if ((argc != 3) && (argc != 5)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0],
		    " stackorder window ?isabove|isbelow? ?window?\"",
		    (char *) NULL);
	    return TCL_ERROR;
	}

	if (argc == 3) {
            windows = TkWmStackorderToplevel(winPtr);
            if (windows == NULL) {
                panic("TkWmStackorderToplevel failed");
	    } else {
                for (window_ptr = windows; *window_ptr ; window_ptr++) {
                    Tcl_AppendElement(interp, (*window_ptr)->pathName);
                }
                ckfree((char *) windows);
                return TCL_OK;
	    }
	} else {
	    TkWindow *winPtr2;
	    int index1=-1, index2=-1, result;

	    winPtr2 = (TkWindow *) Tk_NameToWindow(interp, argv[4], tkwin);
	    if (winPtr2 == NULL) {
		return TCL_ERROR;
	    }

	    if (!Tk_IsTopLevel(winPtr2)) {
		Tcl_AppendResult(interp, "window \"", winPtr2->pathName,
		    "\" isn't a top-level window", (char *) NULL);
		return TCL_ERROR;
	    }

	    if (!Tk_IsMapped(winPtr)) {
		Tcl_AppendResult(interp, "window \"", winPtr->pathName,
		    "\" isn't mapped", (char *) NULL);
		return TCL_ERROR;
	    }

	    if (!Tk_IsMapped(winPtr2)) {
		Tcl_AppendResult(interp, "window \"", winPtr2->pathName,
		    "\" isn't mapped", (char *) 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_AppendResult(interp, "TkWmStackorderToplevel failed",
                    (char *) NULL);
                return TCL_ERROR;
	    } else {
                for (window_ptr = windows; *window_ptr ; window_ptr++) {
                    if (*window_ptr == winPtr)
                        index1 = (window_ptr - windows);
                    if (*window_ptr == winPtr2)
                        index2 = (window_ptr - windows);
                }
                if (index1 == -1)
                    panic("winPtr window not found");
                if (index2 == -1)
                    panic("winPtr2 window not found");

                ckfree((char *) windows);
	    }

	    c = argv[3][0];
	    length = strlen(argv[3]);
	    if ((length > 2) && (c == 'i')
		    && (strncmp(argv[3], "isabove", length) == 0)) {
		result = index1 > index2;
	    } else if ((length > 2) && (c == 'i')
		    && (strncmp(argv[3], "isbelow", length) == 0)) {
		result = index1 < index2;
	    } else {
		Tcl_AppendResult(interp, "bad argument \"", argv[3],
			"\": must be isabove or isbelow", (char *) NULL);
		return TCL_ERROR;
	    }
	    Tcl_SetIntObj(Tcl_GetObjResult(interp), result);
	    return TCL_OK;
	}
d1700 2
a1701 2
		"positionfrom, protocol, resizable, sizefrom, stackorder, ",
		"state, title, transient, or withdraw",
a2926 126
 * TkWmStackorderToplevelWrapperMap --
 *
 *	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.
 *
 *----------------------------------------------------------------------
 */
void
TkWmStackorderToplevelWrapperMap(winPtr, table)
    TkWindow *winPtr;				/* TkWindow to recurse on */
    Tcl_HashTable *table;			/* Maps mac window to TkWindow */
{
    TkWindow *childPtr;
    Tcl_HashEntry *hPtr;
    WindowPeek wrapper;
    int newEntry;

    if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr)) {
        wrapper = (WindowPeek) TkMacGetDrawablePort(winPtr->window);

        hPtr = Tcl_CreateHashEntry(table,
            (char *) wrapper, &newEntry);
        Tcl_SetHashValue(hPtr, winPtr);
    }

    for (childPtr = winPtr->childList; childPtr != NULL;
            childPtr = childPtr->nextPtr) {
        TkWmStackorderToplevelWrapperMap(childPtr, 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(parentPtr)
    TkWindow *parentPtr;		/* Parent toplevel window. */
{
    WindowPeek frontWindow;
    TkWindow *childWinPtr, **windows, **window_ptr;
    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);
    TkWmStackorderToplevelWrapperMap(parentPtr, &table);

    windows = (TkWindow **) 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] = (TkWindow *) Tcl_GetHashValue(hPtr);
        windows[1] = NULL;
        goto done;
    }

    if (TkMacHaveAppearance() >= 0x110) {
        frontWindow = (WindowPeek) FrontNonFloatingWindow();
    } else {	
    	frontWindow = (WindowPeek) FrontWindow();
    }

    if (frontWindow == NULL) {
        ckfree((char *) windows);
        windows = NULL;
    } else {
    	window_ptr = windows + table.numEntries;
    	*window_ptr-- = NULL;
	    while (frontWindow != NULL) {
		    hPtr = Tcl_FindHashEntry(&table, (char *) frontWindow);
            if (hPtr != NULL) {
                childWinPtr = (TkWindow *) Tcl_GetHashValue(hPtr);
                *window_ptr-- = childWinPtr;
            }
			frontWindow = frontWindow->nextWindow;
	    }
        if (window_ptr != (windows-1))
            panic("num matched toplevel windows does not equal num children");
    }

    done:
    Tcl_DeleteHashTable(&table);
    return windows;
}

/*
 *----------------------------------------------------------------------
 *
d3747 3
a3749 3
 *	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.
d3786 1
a3786 1
    if (!Tk_IsTopLevel(winPtr)) {
d4012 1
a4012 1
	        CONST char **attrArgv = NULL;
a4536 4
/* even if AppearanceManager 1.1 routines are present,
we can't call them from 68K code, so we pretend
to be running Apperarance Mgr 1.0 */
#if !(GENERATING68K && !GENERATINGCFM)
a4537 1
#endif
@


1.10.2.1
log
@	* generic/tkInt.decls: removed superfluous declarations.
	* generic/tkIntDecls.h:
	* generic/tkIntPlatDecls.h:
	* generic/tkMain.c: include unistd.h for mac.
	* generic/tkPointer.c: include tkMacInt.h for mac.
	* generic/tkStubInit.c:
	* generic/tkStubLib.c:
	* mac/MW_TkHeader.pch:
	* mac/MW_TkOldImgHeader.h:
	* mac/MW_TkTestHeader.pch:
	* mac/tclets.r:
	* mac/tkMac.h:
	* mac/tkMacAppearanceStubs.c:
	* mac/tkMacApplication.r:
	* mac/tkMacButton.c:
	* mac/tkMacDialog.c: support for -filetypes
	* mac/tkMacFont.c:
	* mac/tkMacInt.h:
	* mac/tkMacLibrary.r:
	* mac/tkMacMDEF.r:
	* mac/tkMacMenu.c:
	* mac/tkMacMenus.c:
	* mac/tkMacPort.h:
	* mac/tkMacResource.r:
	* mac/tkMacScrlbr.c: improved scrollbar code
	* mac/tkMacWindowMgr.c: added control of floating windows
	* mac/tkMacWm.c: improved use of precompiled headers, better
	support for Appearance Manager, change copyrights, resource files,
	use DLLIMPORT/DLLEXPORT, comment corrections.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.10 2000/04/25 01:02:13 hobbs Exp $
a4536 4
/* even if AppearanceManager 1.1 routines are present,
we can't call them from 68K code, so we pretend
to be running Apperarance Mgr 1.0 */
#if !(GENERATING68K && !GENERATINGCFM)
a4537 1
#endif
@


1.9
log
@Add support for Appearance Manager 1.2 Floating windows, and the new window classes in unsupported1
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.8 2000/01/12 11:45:33 hobbs Exp $
d813 1
a813 1
	int i, windowArgc, gotToplevel;
@


1.8
log
@	* tests/winWm.test:
	* tests/unixWm.test:
	* mac/tkMacWm.c:
	* unix/tkUnixWm.c: fixed possible X error being raised [Bug: 3377]
	* win/tkWinWm.c: wm deiconify in zoom state [Bug: 2077],
	fixed possible flashing of unmapped toplevel in deiconify [Bug: 3338]
	and fixed mapping of transient window [Bug: 572]
	Also, for all wm's, extended 'wm state' command to allow setting
	of the state, and added official support of 'zoomed' state on Win.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.7 1999/05/22 06:35:34 jingham Exp $
d208 2
d407 7
a413 1
    wmPtr->style = zoomDocProc;
d1353 1
a1353 1
	int boolean, curValue;
a1361 1
	curValue = Tk_Attributes((Tk_Window) winPtr)->override_redirect;
d1363 5
a1367 1
	    Tcl_SetBooleanObj(Tcl_GetObjResult(interp), curValue);
a1372 4
	if (curValue != boolean) {
	    /*
	     * Only do this if we are really changing value
	     */
a1376 1
	}
d1591 1
a1591 1
		if (wmPtr->masterPtr != NULL) {
d2990 3
d2994 2
d3795 15
a3809 5
	if ((argc != 3) && (argc != 4)) {
	    Tcl_AppendResult(interp, "wrong # arguments: must be \"",
		    argv[0], " style window ?windowStyle?\"",
		    (char *) NULL);
	    return TCL_ERROR;
d3811 1
d3813 2
d3816 3
d3861 73
d3935 1
a3935 1
	}
d3978 96
d4142 1
a4142 1
    Rect geometry;
d4185 19
d4206 2
d4484 2
a4485 2
	     * icon version of the window (collapsed) we make the window
	     * visible and then collapse it.
d4539 1
a4539 1
	    TkMacHaveAppearance = 2;
@


1.7
log
@Changes needed to get Tk8.1 to compile with stubs on the Mac
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.6 1999/04/16 01:51:32 stanton Exp $
d1345 1
a1345 1
	int boolean;
d1354 1
d1356 1
a1356 5
	    if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
		Tcl_SetResult(interp, "1", TCL_STATIC);
	    } else {
		Tcl_SetResult(interp, "0", TCL_STATIC);
	    }
d1362 9
a1370 4
	atts.override_redirect = (boolean) ? True : False;
	Tk_ChangeWindowAttributes((Tk_Window) winPtr, CWOverrideRedirect,
		&atts);
	wmPtr->style = (boolean) ? plainDBox : documentProc;
d1548 1
a1548 1
	if (argc != 3) {
d1550 1
a1550 1
		    argv[0], " state window\"", (char *) NULL);
d1553 51
a1603 2
	if (wmPtr->iconFor != NULL) {
	    Tcl_SetResult(interp, "icon", TCL_STATIC);
d1605 17
a1621 13
	    switch (wmPtr->hints.initial_state) {
		case NormalState:
		    Tcl_SetResult(interp, "normal", TCL_STATIC);
		    break;
		case IconicState:
		    Tcl_SetResult(interp, "iconic", TCL_STATIC);
		    break;
		case WithdrawnState:
		    Tcl_SetResult(interp, "withdrawn", TCL_STATIC);
		    break;
		case ZoomState:
		    Tcl_SetResult(interp, "zoomed", TCL_STATIC);
		    break;
d4267 2
a4268 2
	     * icon version of the window (collapsed) we make the window visable
	     * and then collapse it.
@


1.6
log
@* Merged 8.1 branch into the main trunk
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id$
d3623 1
@


1.5
log
@Make the Macintosh Menu's adopt the current Theme Appearance if the Appearance extension (version 1.0.1 or later) is installed
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.4 1998/09/14 18:23:40 stanton Exp $
d712 1
a712 1
	    interp->result = (wmTracing) ? "on" : "off";
d742 3
a744 1
		sprintf(interp->result, "%d %d %d %d", wmPtr->minAspect.x,
d747 1
d762 2
a763 1
		interp->result = "aspect number can't be <= 0";
d784 1
a784 1
		interp->result = wmPtr->clientMachine;
d882 3
a884 2
		interp->result = Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv);
		interp->freeProc = (Tcl_FreeProc *) free;
d934 2
a935 1
	    interp->result = wmPtr->hints.input ? "passive" : "active";
d952 1
d963 2
a964 1
	sprintf(interp->result, "0x%x", (unsigned int) window);
d977 2
d990 3
a992 2
	    sprintf(interp->result, "%dx%d%c%d%c%d", width, height,
		    xSign, wmPtr->x, ySign, wmPtr->y);
d1013 3
a1015 1
		sprintf(interp->result, "%d %d %d %d", wmPtr->reqGridWidth,
d1018 1
d1045 1
a1045 1
		interp->result = "baseWidth can't be < 0";
d1049 1
a1049 1
		interp->result = "baseHeight can't be < 0";
d1053 1
a1053 1
		interp->result = "widthInc can't be < 0";
d1057 1
a1057 1
		interp->result = "heightInc can't be < 0";
d1077 1
a1077 1
		interp->result = wmPtr->leaderName;
d1110 3
a1112 2
		interp->result = Tk_NameOfBitmap(winPtr->display,
			wmPtr->hints.icon_pixmap);
d1171 3
a1173 2
		interp->result = Tk_NameOfBitmap(winPtr->display,
			wmPtr->hints.icon_mask);
d1198 3
a1200 1
	    interp->result = (wmPtr->iconName != NULL) ? wmPtr->iconName : "";
d1220 3
a1222 1
		sprintf(interp->result, "%d %d", wmPtr->hints.icon_x,
d1224 1
d1252 1
a1252 1
		interp->result = Tk_PathName(wmPtr->icon);
d1306 4
a1309 2
	    sprintf(interp->result, "%d %d", wmPtr->maxWidth,
		    wmPtr->maxHeight);
d1329 4
a1332 2
	    sprintf(interp->result, "%d %d", wmPtr->minWidth,
		    wmPtr->minHeight);
d1356 1
a1356 1
		interp->result = "1";
d1358 1
a1358 1
		interp->result = "0";
d1379 1
a1379 1
		interp->result = "user";
d1381 1
a1381 1
		interp->result = "program";
d1436 1
a1436 1
		    interp->result = protPtr->command;
d1480 3
a1482 1
	    sprintf(interp->result, "%d %d",
d1485 1
d1518 1
a1518 1
		interp->result = "user";
d1520 1
a1520 1
		interp->result = "program";
d1552 1
a1552 1
	    interp->result = "icon";
d1556 1
a1556 1
		    interp->result = "normal";
d1559 1
a1559 1
		    interp->result = "iconic";
d1562 1
a1562 1
		    interp->result = "withdrawn";
d1565 1
a1565 1
		    interp->result = "zoomed";
d1577 3
a1579 2
	    interp->result = (wmPtr->titleUid != NULL) ? wmPtr->titleUid
		: winPtr->nameUid;
d1598 1
a1598 1
		interp->result = wmPtr->masterWindowName;
d2178 1
a2178 1
 *	interp->result if an error occurs.
d2431 1
d2444 2
a2445 1
    winPtr = (TkWindow *) Tk_IdToWindow(tkDisplayList->display, rootChild);
d3289 1
d3302 2
a3303 1
	winPtr = (TkWindow *) Tk_IdToWindow(tkDisplayList->display, window);
d3366 1
d3371 5
d3377 2
a3378 4
     macWin = TkMacGetDrawablePort(winPtr->window);
	
    strcpy((char *) pTitle + 1, titleUid);
    pTitle[0] = strlen(titleUid);
d3635 2
a3636 1
    tkwin = Tk_IdToWindow(tkDisplayList->display, window);
d3738 1
a3738 1
		    interp->result = "documentProc";
d3741 1
a3741 1
		    interp->result = "dBoxProc";
d3744 1
a3744 1
		    interp->result = "plainDBox";
d3747 1
a3747 1
		    interp->result = "altDBoxProc";
d3750 1
a3750 1
		    interp->result = "movableDBoxProc";
d3754 1
a3754 1
		    interp->result = "zoomDocProc";
d3757 1
a3757 1
		    interp->result = "rDocProc";
d3761 1
a3761 1
		    interp->result = "floatProc";
d3765 1
a3765 1
		    interp->result = "floatZoomProc";
d3769 1
a3769 1
		    interp->result = "floatSideProc";
d3773 1
a3773 1
		    interp->result = "floatSideZoomProc";
@


1.4
log
@Replaced SCCS strings, fixed binary files
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id$
d4199 3
a4201 1
 *	We cache the result so future calls are fast.
d4204 2
a4205 1
 *	True if the appearance manager is present, false otherwise.
d4217 1
a4217 1
    static int TkMacHaveAppearance = false;
d4224 5
a4228 1
	    TkMacHaveAppearance = true;
@


1.3
log
@Mac updates for 8.0.3-2
@
text
@d14 1
a14 1
 * SCCS: @@(#) tkMacWm.c 1.72 97/10/29 13:27:30
@


1.2
log
@plugin updates
@
text
@d30 3
a32 3
 * If HAVE_APPEARANCE is defined in MW_TkHeader.pch then we must have the
 * Appearance manager header & library.  If so we can use these new API's to
 * have the iconify code do the right thing.
d34 2
a36 4
#ifdef HAVE_APPEARANCE
#   include <Appearance.h>
#endif

d309 1
a309 1
void MacMoveWindow(WindowRef window, int x, int y);
a314 1
static int		HaveAppearance _ANSI_ARGS_((void));
d3911 1
a3911 1
    MacMoveWindow(newWindow, (int) geometry.left, (int) geometry.top);
d4170 1
a4170 2
#ifdef HAVE_APPEARANCE
	if (HaveAppearance()) {
a4183 1
#endif
d4186 1
a4186 2
#ifdef HAVE_APPEARANCE
	if (HaveAppearance()) {
a4188 1
#endif
d4196 1
a4196 1
 * HaveAppearance --
d4210 2
a4211 2
static int
HaveAppearance()
d4214 1
a4214 1
    static int haveAppearance = false;
a4217 1
#ifdef HAVE_APPEARANCE
d4221 1
a4221 1
	    haveAppearance = true;
a4223 1
#endif
d4225 1
a4225 1
    return haveAppearance;
@


1.1
log
@Initial revision
@
text
@d22 1
d536 1
a536 1

d2337 1
d2339 18
a2356 5
		    /*
		     * NOTE: Here we should handle
		     * out of process embedding.
		     */
		    
d3879 7
@


1.1.4.1
log
@initial tk8.1a2 version
@
text
@d14 1
a14 1
 * SCCS: @@(#) tkMacWm.c 1.77 98/02/18 11:03:54
a21 1
#include <tclMac.h>
d29 3
a31 3
 * We now require the Appearance headers.  They come with CodeWarrior Pro,
 * and are on the SDK CD.  However, we do not require the Appearance 
 * extension
d33 4
a36 2
 
#include <Appearance.h>
d316 1
d535 1
a535 1
    
d714 1
a714 1
	    Tcl_SetResult(interp, ((wmTracing) ? "on" : "off"), TCL_STATIC);
d744 1
a744 3
		char buf[TCL_INTEGER_SPACE * 4];

		sprintf(buf, "%d %d %d %d", wmPtr->minAspect.x,
a746 1
		Tcl_SetResult(interp, buf, TCL_VOLATILE);
d761 1
a761 2
		Tcl_SetResult(interp, "aspect number can't be <= 0",
			TCL_STATIC);
d782 1
a782 1
		Tcl_SetResult(interp, wmPtr->clientMachine, TCL_STATIC);
d880 2
a881 3
		Tcl_SetResult(interp,
			Tcl_Merge(wmPtr->cmdArgc, wmPtr->cmdArgv),
			TCL_DYNAMIC);
d931 1
a931 2
	    Tcl_SetResult(interp, (wmPtr->hints.input ? "passive" : "active"),
		    TCL_STATIC);
a947 1
	char buf[TCL_INTEGER_SPACE];
d958 1
a958 2
	sprintf(buf, "0x%x", (unsigned int) window);
	Tcl_SetResult(interp, buf, TCL_VOLATILE);
a970 2
	    char buf[16 + TCL_INTEGER_SPACE * 4];

d982 2
a983 3
	    sprintf(buf, "%dx%d%c%d%c%d", width, height, xSign, wmPtr->x,
		    ySign, wmPtr->y);
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
d1004 1
a1004 3
		char buf[TCL_INTEGER_SPACE * 4];

		sprintf(buf, "%d %d %d %d", wmPtr->reqGridWidth,
a1006 1
		Tcl_SetResult(interp, buf, TCL_VOLATILE);
d1033 1
a1033 1
		Tcl_SetResult(interp, "baseWidth can't be < 0", TCL_STATIC);
d1037 1
a1037 1
		Tcl_SetResult(interp, "baseHeight can't be < 0", TCL_STATIC);
d1041 1
a1041 1
		Tcl_SetResult(interp, "widthInc can't be < 0", TCL_STATIC);
d1045 1
a1045 1
		Tcl_SetResult(interp, "heightInc can't be < 0", TCL_STATIC);
d1065 1
a1065 1
		Tcl_SetResult(interp, wmPtr->leaderName, TCL_STATIC);
d1098 2
a1099 3
		Tcl_SetResult(interp,
			Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_pixmap),
			TCL_STATIC);
d1158 2
a1159 3
		Tcl_SetResult(interp,
			Tk_NameOfBitmap(winPtr->display, wmPtr->hints.icon_mask),
			TCL_STATIC);
d1184 1
a1184 3
	    Tcl_SetResult(interp,
		    ((wmPtr->iconName != NULL) ? wmPtr->iconName : ""),
		    TCL_STATIC);
d1204 1
a1204 3
		char buf[TCL_INTEGER_SPACE * 2];
		
		sprintf(buf, "%d %d", wmPtr->hints.icon_x,
a1205 1
		Tcl_SetResult(interp, buf, TCL_VOLATILE);
d1233 1
a1233 1
		Tcl_SetResult(interp, Tk_PathName(wmPtr->icon), TCL_STATIC);
d1287 2
a1288 4
	    char buf[TCL_INTEGER_SPACE * 2];
	    
	    sprintf(buf, "%d %d", wmPtr->maxWidth, wmPtr->maxHeight);
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
d1308 2
a1309 4
	    char buf[TCL_INTEGER_SPACE * 2];
	    
	    sprintf(buf, "%d %d", wmPtr->minWidth, wmPtr->minHeight);
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
d1333 1
a1333 1
		Tcl_SetResult(interp, "1", TCL_STATIC);
d1335 1
a1335 1
		Tcl_SetResult(interp, "0", TCL_STATIC);
d1356 1
a1356 1
		Tcl_SetResult(interp, "user", TCL_STATIC);
d1358 1
a1358 1
		Tcl_SetResult(interp, "program", TCL_STATIC);
d1413 1
a1413 1
		    Tcl_SetResult(interp, protPtr->command, TCL_STATIC);
d1457 1
a1457 3
	    char buf[TCL_INTEGER_SPACE * 2];

	    sprintf(buf, "%d %d",
a1459 1
	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
d1492 1
a1492 1
		Tcl_SetResult(interp, "user", TCL_STATIC);
d1494 1
a1494 1
		Tcl_SetResult(interp, "program", TCL_STATIC);
d1526 1
a1526 1
	    Tcl_SetResult(interp, "icon", TCL_STATIC);
d1530 1
a1530 1
		    Tcl_SetResult(interp, "normal", TCL_STATIC);
d1533 1
a1533 1
		    Tcl_SetResult(interp, "iconic", TCL_STATIC);
d1536 1
a1536 1
		    Tcl_SetResult(interp, "withdrawn", TCL_STATIC);
d1539 1
a1539 1
		    Tcl_SetResult(interp, "zoomed", TCL_STATIC);
d1551 2
a1552 3
	    Tcl_SetResult(interp,
		    ((wmPtr->titleUid != NULL) ? wmPtr->titleUid : winPtr->nameUid),
		    TCL_STATIC);
d1571 1
a1571 1
		Tcl_SetResult(interp, wmPtr->masterWindowName, TCL_STATIC);
d2151 1
a2151 1
 *	the interp's result if an error occurs.
a2335 1
		    Point theOffset;
d2337 5
a2341 18
		    if (gMacEmbedHandler->getOffsetProc != NULL) {
		        /*
		         * 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;
	                
		        gMacEmbedHandler->getOffsetProc((Tk_Window) winPtr, &theOffset);
		        
		        x += theOffset.h;
		        y += theOffset.v;
		    }
a3320 1
    int destWrote;
a3324 5
    Tcl_UtfToExternal(NULL, NULL, titleUid,
	    strlen(titleUid), 0, NULL, 
	    (char *) &pTitle[1],
	    255, NULL, &destWrote, NULL); /* Internalize native */
    pTitle[0] = destWrote;
d3326 4
a3329 2
    macWin = TkMacGetDrawablePort(winPtr->window);

d3688 1
a3688 1
		    Tcl_SetResult(interp, "documentProc", TCL_STATIC);
d3691 1
a3691 1
		    Tcl_SetResult(interp, "dBoxProc", TCL_STATIC);
d3694 1
a3694 1
		    Tcl_SetResult(interp, "plainDBox", TCL_STATIC);
d3697 1
a3697 1
		    Tcl_SetResult(interp, "altDBoxProc", TCL_STATIC);
d3700 1
a3700 1
		    Tcl_SetResult(interp, "movableDBoxProc", TCL_STATIC);
d3704 1
a3704 1
		    Tcl_SetResult(interp, "zoomDocProc", TCL_STATIC);
d3707 1
a3707 1
		    Tcl_SetResult(interp, "rDocProc", TCL_STATIC);
d3711 1
a3711 1
		    Tcl_SetResult(interp, "floatProc", TCL_STATIC);
d3715 1
a3715 1
		    Tcl_SetResult(interp, "floatZoomProc", TCL_STATIC);
d3719 1
a3719 1
		    Tcl_SetResult(interp, "floatSideProc", TCL_STATIC);
d3723 1
a3723 1
		    Tcl_SetResult(interp, "floatSideZoomProc", TCL_STATIC);
a3863 7
	} else if (gMacEmbedHandler != NULL) {
	    if (gMacEmbedHandler->containerExistProc != NULL) {
	        if (gMacEmbedHandler->containerExistProc((Tk_Window) winPtr) != TCL_OK) {
	           panic("ContainerExistProc could not make container");
	       }
	    }
	    return;
d4151 2
a4152 1
	if (TkMacHaveAppearance()) {
d4166 1
d4169 2
a4170 1
	if (TkMacHaveAppearance()) {
d4173 1
d4181 1
a4181 1
 * TkMacHaveAppearance --
d4195 2
a4196 2
int
TkMacHaveAppearance()
d4199 1
a4199 1
    static int TkMacHaveAppearance = false;
d4203 1
d4207 1
a4207 1
	    TkMacHaveAppearance = true;
d4210 1
d4212 1
a4212 1
    return TkMacHaveAppearance;
@


1.1.4.2
log
@Merged 8.0.3 changes into 8.1
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.4 1998/09/14 18:23:40 stanton Exp $
d309 1
a309 1
void tkMacMoveWindow(WindowRef window, int x, int y);
d3944 1
a3944 1
    tkMacMoveWindow(newWindow, (int) geometry.left, (int) geometry.top);
@


1.1.4.3
log
@* integrated tk8.0.4 changes.

* generic/tkBind.c: fixed deletion order bug where a crash would
result if a binding deleted "."
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.1.4.2 1998/09/30 02:18:18 stanton Exp $
d4232 1
a4232 3
 *	We cache the result so future calls are fast.  Return a different
 *      value if 1.0.1 is present, since many interfaces were added in
 *      1.0.1
d4235 1
a4235 2
 *	1 if the appearance manager is present, 2 if the appearance
 *      manager version is 1.0.1 or greater, 0 if it is not present.
d4247 1
a4247 1
    static int TkMacHaveAppearance = 0;
d4254 1
a4254 5
	    TkMacHaveAppearance = 1;
	}
	err = Gestalt(gestaltAppearanceVersion, &response);
	if (err == noErr) {
	    TkMacHaveAppearance = 2;
@


1.1.4.4
log
@
Tk 8.1 Muti-threading changes.

Moved static and global data elements into thread-local storage,
or introduced locks where not possible, as first stage of adding
thread safety to Tk.
@
text
@d14 1
a14 1
 * RCS: @@(#) $Id: tkMacWm.c,v 1.1.4.3 1998/11/25 21:16:37 stanton Exp $
a2430 1
    TkDisplay *dispPtr;
d2443 1
a2443 2
    dispPtr = TkGetDisplayList();
    winPtr = (TkWindow *) Tk_IdToWindow(dispPtr->display, rootChild);
a3286 1
    TkDisplay *dispPtr;
d3299 1
a3299 2
	dispPtr = TkGetDisplayList();
	winPtr = (TkWindow *) Tk_IdToWindow(dispPtr->display, window);
d3631 1
a3631 2
    dispPtr = TkGetDisplayList();
    tkwin = Tk_IdToWindow(dispPtr->display, window);
@


