/*******************************************************************************
 * Copyright (c) 2000, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.widgets;


import org.eclipse.swt.internal.carbon.OS;
import org.eclipse.swt.internal.carbon.Rect;
import org.eclipse.swt.internal.carbon.CGPoint;
import org.eclipse.swt.internal.carbon.CGRect;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;

/**
 * Instances of this class represent the "windows"
 * which the desktop or "window manager" is managing.
 * Instances that do not have a parent (that is, they
 * are built using the constructor, which takes a 
 * <code>Display</code> as the argument) are described
 * as <em>top level</em> shells. Instances that do have
 * a parent are described as <em>secondary</em> or
 * <em>dialog</em> shells.
 * <p>
 * Instances are always displayed in one of the maximized, 
 * minimized or normal states:
 * <ul>
 * <li>
 * When an instance is marked as <em>maximized</em>, the
 * window manager will typically resize it to fill the
 * entire visible area of the display, and the instance
 * is usually put in a state where it can not be resized 
 * (even if it has style <code>RESIZE</code>) until it is
 * no longer maximized.
 * </li><li>
 * When an instance is in the <em>normal</em> state (neither
 * maximized or minimized), its appearance is controlled by
 * the style constants which were specified when it was created
 * and the restrictions of the window manager (see below).
 * </li><li>
 * When an instance has been marked as <em>minimized</em>,
 * its contents (client area) will usually not be visible,
 * and depending on the window manager, it may be
 * "iconified" (that is, replaced on the desktop by a small
 * simplified representation of itself), relocated to a
 * distinguished area of the screen, or hidden. Combinations
 * of these changes are also possible.
 * </li>
 * </ul>
 * </p><p>
 * The <em>modality</em> of an instance may be specified using
 * style bits. The modality style bits are used to determine
 * whether input is blocked for other shells on the display.
 * The <code>PRIMARY_MODAL</code> style allows an instance to block
 * input to its parent. The <code>APPLICATION_MODAL</code> style
 * allows an instance to block input to every other shell in the
 * display. The <code>SYSTEM_MODAL</code> style allows an instance
 * to block input to all shells, including shells belonging to
 * different applications.
 * </p><p>
 * Note: The styles supported by this class are treated
 * as <em>HINT</em>s, since the window manager for the
 * desktop on which the instance is visible has ultimate
 * control over the appearance and behavior of decorations
 * and modality. For example, some window managers only
 * support resizable windows and will always assume the
 * RESIZE style, even if it is not set. In addition, if a
 * modality style is not supported, it is "upgraded" to a
 * more restrictive modality style that is supported. For
 * example, if <code>PRIMARY_MODAL</code> is not supported,
 * it would be upgraded to <code>APPLICATION_MODAL</code>.
 * A modality style may also be "downgraded" to a less
 * restrictive style. For example, most operating systems
 * no longer support <code>SYSTEM_MODAL</code> because
 * it can freeze up the desktop, so this is typically
 * downgraded to <code>APPLICATION_MODAL</code>.
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>BORDER, CLOSE, MIN, MAX, NO_TRIM, RESIZE, TITLE, ON_TOP, TOOL</dd>
 * <dd>APPLICATION_MODAL, MODELESS, PRIMARY_MODAL, SYSTEM_MODAL</dd>
 * <dt><b>Events:</b></dt>
 * <dd>Activate, Close, Deactivate, Deiconify, Iconify</dd>
 * </dl>
 * Class <code>SWT</code> provides two "convenience constants"
 * for the most commonly required style combinations:
 * <dl>
 * <dt><code>SHELL_TRIM</code></dt>
 * <dd>
 * the result of combining the constants which are required
 * to produce a typical application top level shell: (that 
 * is, <code>CLOSE | TITLE | MIN | MAX | RESIZE</code>)
 * </dd>
 * <dt><code>DIALOG_TRIM</code></dt>
 * <dd>
 * the result of combining the constants which are required
 * to produce a typical application dialog shell: (that 
 * is, <code>TITLE | CLOSE | BORDER</code>)
 * </dd>
 * </dl>
 * </p>
 * <p>
 * Note: Only one of the styles APPLICATION_MODAL, MODELESS, 
 * PRIMARY_MODAL and SYSTEM_MODAL may be specified.
 * </p><p>
 * IMPORTANT: This class is not intended to be subclassed.
 * </p>
 *
 * @see Decorations
 * @see SWT
 */
public class Shell extends Decorations {
	int shellHandle, windowGroup;
	boolean resized, moved, drawing, reshape, update, deferDispose, active, disposed, opened;
	int invalRgn;
	Control lastActive;
	Region region;
	Rect rgnRect;

	static int DEFAULT_CLIENT_WIDTH = -1;
	static int DEFAULT_CLIENT_HEIGHT = -1;

/**
 * Constructs a new instance of this class. This is equivalent
 * to calling <code>Shell((Display) null)</code>.
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 */
public Shell () {
	this ((Display) null);
}

/**
 * Constructs a new instance of this class given only the style
 * value describing its behavior and appearance. This is equivalent
 * to calling <code>Shell((Display) null, style)</code>.
 * <p>
 * The style value is either one of the style constants defined in
 * class <code>SWT</code> which is applicable to instances of this
 * class, or must be built by <em>bitwise OR</em>'ing together 
 * (that is, using the <code>int</code> "|" operator) two or more
 * of those <code>SWT</code> style constants. The class description
 * lists the style constants that are applicable to the class.
 * Style bits are also inherited from superclasses.
 * </p>
 *
 * @param style the style of control to construct
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 * 
 * @see SWT#BORDER
 * @see SWT#CLOSE
 * @see SWT#MIN
 * @see SWT#MAX
 * @see SWT#RESIZE
 * @see SWT#TITLE
 * @see SWT#NO_TRIM
 * @see SWT#SHELL_TRIM
 * @see SWT#DIALOG_TRIM
 * @see SWT#MODELESS
 * @see SWT#PRIMARY_MODAL
 * @see SWT#APPLICATION_MODAL
 * @see SWT#SYSTEM_MODAL
 */
public Shell (int style) {
	this ((Display) null, style);
}

/**
 * Constructs a new instance of this class given only the display
 * to create it on. It is created with style <code>SWT.SHELL_TRIM</code>.
 * <p>
 * Note: Currently, null can be passed in for the display argument.
 * This has the effect of creating the shell on the currently active
 * display if there is one. If there is no current display, the 
 * shell is created on a "default" display. <b>Passing in null as
 * the display argument is not considered to be good coding style,
 * and may not be supported in a future release of SWT.</b>
 * </p>
 *
 * @param display the display to create the shell on
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 */
public Shell (Display display) {
	this (display, SWT.SHELL_TRIM);
}

/**
 * Constructs a new instance of this class given the display
 * to create it on and a style value describing its behavior
 * and appearance.
 * <p>
 * The style value is either one of the style constants defined in
 * class <code>SWT</code> which is applicable to instances of this
 * class, or must be built by <em>bitwise OR</em>'ing together 
 * (that is, using the <code>int</code> "|" operator) two or more
 * of those <code>SWT</code> style constants. The class description
 * lists the style constants that are applicable to the class.
 * Style bits are also inherited from superclasses.
 * </p><p>
 * Note: Currently, null can be passed in for the display argument.
 * This has the effect of creating the shell on the currently active
 * display if there is one. If there is no current display, the 
 * shell is created on a "default" display. <b>Passing in null as
 * the display argument is not considered to be good coding style,
 * and may not be supported in a future release of SWT.</b>
 * </p>
 *
 * @param display the display to create the shell on
 * @param style the style of control to construct
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 * 
 * @see SWT#BORDER
 * @see SWT#CLOSE
 * @see SWT#MIN
 * @see SWT#MAX
 * @see SWT#RESIZE
 * @see SWT#TITLE
 * @see SWT#NO_TRIM
 * @see SWT#SHELL_TRIM
 * @see SWT#DIALOG_TRIM
 * @see SWT#MODELESS
 * @see SWT#PRIMARY_MODAL
 * @see SWT#APPLICATION_MODAL
 * @see SWT#SYSTEM_MODAL
 */
public Shell (Display display, int style) {
	this (display, null, style, 0, false);
}

Shell (Display display, Shell parent, int style, int handle, boolean embedded) {
	super ();
	checkSubclass ();
	if (display == null) display = Display.getCurrent ();
	if (display == null) display = Display.getDefault ();
	if (!display.isValidThread ()) {
		error (SWT.ERROR_THREAD_INVALID_ACCESS);
	}
	if (parent != null && parent.isDisposed ()) {
		error (SWT.ERROR_INVALID_ARGUMENT);	
	}
	this.style = checkStyle (style);
	this.parent = parent;
	this.display = display;
	if (handle != 0) {
		if (embedded) {
			this.handle = handle;
		} else {
			shellHandle = handle;
			state |= FOREIGN_HANDLE;
		}
	}
	createWidget ();
}

/**
 * Constructs a new instance of this class given only its
 * parent. It is created with style <code>SWT.DIALOG_TRIM</code>.
 * <p>
 * Note: Currently, null can be passed in for the parent.
 * This has the effect of creating the shell on the currently active
 * display if there is one. If there is no current display, the 
 * shell is created on a "default" display. <b>Passing in null as
 * the parent is not considered to be good coding style,
 * and may not be supported in a future release of SWT.</b>
 * </p>
 *
 * @param parent a shell which will be the parent of the new instance
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the parent is disposed</li> 
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 */
public Shell (Shell parent) {
	this (parent, SWT.DIALOG_TRIM);
}

/**
 * Constructs a new instance of this class given its parent
 * and a style value describing its behavior and appearance.
 * <p>
 * The style value is either one of the style constants defined in
 * class <code>SWT</code> which is applicable to instances of this
 * class, or must be built by <em>bitwise OR</em>'ing together 
 * (that is, using the <code>int</code> "|" operator) two or more
 * of those <code>SWT</code> style constants. The class description
 * lists the style constants that are applicable to the class.
 * Style bits are also inherited from superclasses.
 * </p><p>
 * Note: Currently, null can be passed in for the parent.
 * This has the effect of creating the shell on the currently active
 * display if there is one. If there is no current display, the 
 * shell is created on a "default" display. <b>Passing in null as
 * the parent is not considered to be good coding style,
 * and may not be supported in a future release of SWT.</b>
 * </p>
 *
 * @param parent a shell which will be the parent of the new instance
 * @param style the style of control to construct
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the parent is disposed</li> 
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 * 
 * @see SWT#BORDER
 * @see SWT#CLOSE
 * @see SWT#MIN
 * @see SWT#MAX
 * @see SWT#RESIZE
 * @see SWT#TITLE
 * @see SWT#NO_TRIM
 * @see SWT#SHELL_TRIM
 * @see SWT#DIALOG_TRIM
 * @see SWT#ON_TOP
 * @see SWT#TOOL
 * @see SWT#MODELESS
 * @see SWT#PRIMARY_MODAL
 * @see SWT#APPLICATION_MODAL
 * @see SWT#SYSTEM_MODAL
 */
public Shell (Shell parent, int style) {
	this (parent != null ? parent.display : null, parent, style, 0, false);
}

public static Shell internal_new (Display display, int handle) {
	return new Shell (display, null, SWT.NO_TRIM, handle, false);
}

static int checkStyle (int style) {
	style = Decorations.checkStyle (style);
	int mask = SWT.SYSTEM_MODAL | SWT.APPLICATION_MODAL | SWT.PRIMARY_MODAL;
	int bits = style & ~mask;
	if ((style & SWT.SYSTEM_MODAL) != 0) return bits | SWT.SYSTEM_MODAL;
	if ((style & SWT.APPLICATION_MODAL) != 0) return bits | SWT.APPLICATION_MODAL;
	if ((style & SWT.PRIMARY_MODAL) != 0) return bits | SWT.PRIMARY_MODAL;
	return bits;
}

/**
 * Adds the listener to the collection of listeners who will
 * be notified when operations are performed on the receiver,
 * by sending the listener one of the messages defined in the
 * <code>ShellListener</code> interface.
 *
 * @param listener the listener which should be notified
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see ShellListener
 * @see #removeShellListener
 */
public void addShellListener(ShellListener listener) {
	checkWidget();
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	TypedListener typedListener = new TypedListener (listener);
	addListener(SWT.Activate,typedListener);
	addListener(SWT.Close,typedListener);
	addListener(SWT.Deactivate,typedListener);
	addListener(SWT.Iconify,typedListener);
	addListener(SWT.Deiconify,typedListener);
}

void bringToTop (boolean force) {
	if (getMinimized ()) return;
	if (force) {
		forceActive ();
	} else {
		setActive ();
	}
}

void checkOpen () {
	if (!opened) resized = false;
}

/**
 * Requests that the window manager close the receiver in
 * the same way it would be closed when the user clicks on
 * the "close box" or performs some other platform specific
 * key or mouse combination that indicates the window
 * should be removed.
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see SWT#Close
 * @see #dispose
 */
public void close () {
	checkWidget();
	closeWidget ();
}

void closeWidget () {
	Event event = new Event ();
	sendEvent (SWT.Close, event);
	if (event.doit && !isDisposed ()) dispose ();
}

public Rectangle computeTrim (int x, int y, int width, int height) {
	checkWidget();
	Rectangle trim = super.computeTrim (x, y, width, height);
	Rect rect = new Rect ();
	OS.GetWindowStructureWidths (shellHandle, rect);
	trim.x -= rect.left;
	trim.y -= rect.top;
	trim.width += rect.left + rect.right;
	trim.height += rect.top + rect.bottom;
	return trim;
}

void createHandle () {
	state |= CANVAS | GRAB | HIDDEN;
	int attributes = OS.kWindowStandardHandlerAttribute;
	if (OS.HIVIEW) attributes |= OS.kWindowCompositingAttribute;
	if ((style & SWT.NO_TRIM) == 0) {
		if ((style & SWT.CLOSE) != 0) attributes |= OS.kWindowCloseBoxAttribute;
		if ((style & SWT.MIN) != 0) attributes |= OS.kWindowCollapseBoxAttribute;
		if ((style & SWT.MAX) != 0) attributes |= OS.kWindowFullZoomAttribute;
		if ((style & SWT.RESIZE) != 0) {
			attributes |= OS.kWindowResizableAttribute;
			/*
			* Bug in the Macintosh.  For some reason, a window has no title bar
			* and the kWindowResizableAttribute, no rubber banding feedback is
			* given while the window is resizing.  The fix is to create the window 
			* with kWindowLiveResizeAttribute in this case.  This is inconsistent
			* with other windows, but the user will get feedback when resizing.
			*/
			if ((style & SWT.TITLE) == 0) attributes |= OS.kWindowLiveResizeAttribute;
			if (!OS.__BIG_ENDIAN__()) attributes |= OS.kWindowLiveResizeAttribute;
		}
	}
	int windowClass = OS.kDocumentWindowClass;
	if ((style & (SWT.CLOSE | SWT.TITLE)) == 0) windowClass = OS.kSheetWindowClass;
	if ((style & (SWT.APPLICATION_MODAL | SWT.PRIMARY_MODAL | SWT.SYSTEM_MODAL)) != 0) {
		if ((style & (SWT.CLOSE | SWT.MAX | SWT.MIN)) == 0)  {
			windowClass = (style & SWT.TITLE) != 0 ? OS.kMovableModalWindowClass : OS.kModalWindowClass;
		}
	}
	if (shellHandle == 0) {
		Monitor monitor = getMonitor ();
		Rectangle rect = monitor.getClientArea ();
		int width = rect.width * 5 / 8;
		int height = rect.height * 5 / 8;
		Rect bounds = new Rect ();
		OS.SetRect (bounds, (short) 0, (short) 0, (short) width, (short) height);
		int [] outWindow = new int [1];
		attributes &= OS.GetAvailableWindowAttributes (windowClass);
		OS.CreateNewWindow (windowClass, attributes, bounds, outWindow);
		if (outWindow [0] == 0) error (SWT.ERROR_NO_HANDLES);
		shellHandle = outWindow [0];
		OS.RepositionWindow (shellHandle, 0, OS.kWindowCascadeOnMainScreen);
//		OS.SetThemeWindowBackground (shellHandle, (short) OS.kThemeBrushDialogBackgroundActive, false);
		int [] theRoot = new int [1];
		if (OS.HIVIEW) {
			OS.HIViewFindByID (shellHandle, OS.kHIViewWindowContentID (), theRoot);
			/*
			* Bug in the Macintosh.  When the window class is kMovableModalWindowClass or
			* kModalWindowClass, HIViewFindByID() fails to find the control identified by
			* kHIViewWindowContentID.  The fix is to call GetRootControl() if the call
			* failed.
			*/
			if (theRoot [0] == 0) OS.GetRootControl (shellHandle, theRoot);		
		} else {
			OS.CreateRootControl (shellHandle, theRoot);
			OS.GetRootControl (shellHandle, theRoot);
		}
		if (theRoot [0] == 0) error (SWT.ERROR_NO_HANDLES);
		if ((style & (SWT.H_SCROLL | SWT.V_SCROLL)) != 0) {
			createScrolledHandle (theRoot [0]);
		} else {
			createHandle (theRoot [0]);
		}
		OS.SetControlVisibility (topHandle (), false, false);
	} else {
		int [] theRoot = new int [1];
		OS.HIViewFindByID (shellHandle, OS.kHIViewWindowContentID (), theRoot);
		if (theRoot [0] == 0) OS.GetRootControl (shellHandle, theRoot);
		handle = OS.HIViewGetFirstSubview (theRoot [0]);
		if (handle == 0) error (SWT.ERROR_NO_HANDLES);
		if (OS.IsWindowVisible (shellHandle)) state &= ~HIDDEN;
	}
	int [] outGroup = new int [1];
	OS.CreateWindowGroup (OS.kWindowGroupAttrHideOnCollapse, outGroup);
	if (outGroup [0] == 0) error (SWT.ERROR_NO_HANDLES);
	windowGroup = outGroup [0];
	int parentGroup;
	if ((style & SWT.ON_TOP) != 0) {
		parentGroup = OS.GetWindowGroupOfClass (OS.kFloatingWindowClass);		
	} else {
		if (parent != null) {
			parentGroup = parent.getShell ().windowGroup;
		} else {
			parentGroup = OS.GetWindowGroupOfClass (windowClass);
		}
	}
	OS.SetWindowGroup (shellHandle, parentGroup);
	OS.SetWindowGroupParent (windowGroup, parentGroup);
	OS.SetWindowGroupOwner (windowGroup, shellHandle);
	CGPoint inMinLimits = new CGPoint (), inMaxLimits = new CGPoint ();
	OS.GetWindowResizeLimits (shellHandle, inMinLimits, inMaxLimits);
	if (DEFAULT_CLIENT_WIDTH == -1) DEFAULT_CLIENT_WIDTH = (int) inMinLimits.x;
	if (DEFAULT_CLIENT_HEIGHT == -1) DEFAULT_CLIENT_HEIGHT = 0;
	inMinLimits.y = (int) 0;
	int trim = SWT.TITLE | SWT.CLOSE | SWT.MIN | SWT.MAX;
	if ((style & SWT.NO_TRIM) != 0 || (style & trim) == 0) {
		inMinLimits.x = (int) 0;	
	}
	OS.SetWindowResizeLimits (shellHandle, inMinLimits, inMaxLimits);
}

void createWidget () {
	super.createWidget ();
	resizeBounds ();
}

void deregister () {
	super.deregister ();
	int [] theRoot = new int [1];
	OS.GetRootControl (shellHandle, theRoot);
	display.removeWidget (theRoot [0]);
}

void destroyWidget () {
	int theWindow = shellHandle;
	/*
	* Bug in the Macintosh.  Under certain circumstances, yet to
	* be determined, calling HideWindow() and then DisposeWindow()
	* causes a segment fault when an application is exiting.  This
	* seems to happen to large applications.  The fix is to avoid
	* calling HideWindow() when a shell is about to be disposed.
	* 
	* Bug in the Macintosh.  Disposing a window from kEventWindowDeactivated
	* causes a segment fault. The fix is to defer disposing the window until
	* the event loop becomes idle.
	*/
	Display display = this.display;
	Composite parent = this.parent;
	while (!deferDispose && parent != null) {
		Shell shell = parent.getShell ();
		deferDispose = shell.deferDispose;
		parent = shell.parent;
	}
	if (deferDispose) OS.HideWindow (shellHandle);
	releaseHandle ();
	if (theWindow != 0) {
		if (deferDispose) {
			display.addDisposeWindow (theWindow);
		} else {
			OS.DisposeWindow (theWindow);
		}
	} 
}

void drawWidget (int control, int context, int damageRgn, int visibleRgn, int theEvent) {
	super.drawWidget (control, context, damageRgn, visibleRgn, theEvent);
	
	/*
	* Bug in the Macintosh. In kEventWindowGetRegion, 
	* Carbon assumes the origin of the Region is (0, 0)
	* and ignores the actual origin.  This causes the 
	* window to be shifted for a non zero origin.  Also,
	* the size of the window is the size of the region
	* which may be less then the size specified in
	* setSize or setBounds.
	* The fix is to include (0, 0) and the bottom 
	* right corner of the size in the region and to
	* make these points transparent.
	*/
	if (region == null || region.isDisposed ()) return;
	boolean origin = region.contains (0, 0);
	boolean limit = region.contains(rgnRect.right - 1, rgnRect.bottom - 1);
	if (origin && limit) return;
	
	int port = 0; 
	int [] buffer = null;
	if (!OS.HIVIEW) {
		buffer = new int [1];
		Rect portRect = new Rect ();
		port = OS.GetWindowPort (shellHandle);
		OS.GetPortBounds (port, portRect);
		OS.QDBeginCGContext (port, buffer);
		context = buffer [0];
		OS.CGContextScaleCTM (context, 1, -1);
		OS.CGContextTranslateCTM (context, 0, portRect.top - portRect.bottom);
	}
	CGRect cgRect = new CGRect ();
	cgRect.width = 1;
	cgRect.height = 1;
	if (!origin) {
		OS.CGContextClearRect (context, cgRect);
	}
	if (!limit) {
		cgRect.x = rgnRect.right - 1;
		cgRect.y = rgnRect.bottom - 1;
		OS.CGContextClearRect (context, cgRect);
	}
	OS.CGContextSynchronize (context);
	if (!OS.HIVIEW) OS.QDEndCGContext (port, buffer);
}

Control findBackgroundControl () {
	return background != null || backgroundImage != null ? this : null;
}

Composite findDeferredControl () {
	return layoutCount > 0 ? this : null;
}

Cursor findCursor () {
	return cursor;
}

/**
 * If the receiver is visible, moves it to the top of the 
 * drawing order for the display on which it was created 
 * (so that all other shells on that display, which are not 
 * the receiver's children will be drawn behind it) and forces 
 * the window manager to make the shell active.
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @since 2.0
 * @see Control#moveAbove
 * @see Control#setFocus
 * @see Control#setVisible
 * @see Display#getActiveShell
 * @see Decorations#setDefaultButton
 * @see Shell#open
 * @see Shell#setActive
 */
public void forceActive () {
	checkWidget ();
	if (!isVisible ()) return;
	OS.SelectWindow (shellHandle);
	OS.SetFrontProcessWithOptions (new int [] {0, OS.kCurrentProcess}, OS.kSetFrontProcessFrontWindowOnly);
}

public Rectangle getBounds () {
	checkWidget();
	Rect rect = new Rect ();
	OS.GetWindowBounds (shellHandle, (short) OS.kWindowStructureRgn, rect);
	return new Rectangle (rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
}

int getDrawCount (int control) {
	if (!isTrimHandle (control)) return drawCount;
	return 0;
}

/**
 * Returns the receiver's input method editor mode. This
 * will be the result of bitwise OR'ing together one or
 * more of the following constants defined in class
 * <code>SWT</code>:
 * <code>NONE</code>, <code>ROMAN</code>, <code>DBCS</code>, 
 * <code>PHONETIC</code>, <code>NATIVE</code>, <code>ALPHA</code>.
 *
 * @return the IME mode
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see SWT
 */
public int getImeInputMode () {
	checkWidget();
	return SWT.NONE;
}

public Point getLocation () {
	checkWidget();
	Rect rect = new Rect ();
	OS.GetWindowBounds (shellHandle, (short) OS.kWindowStructureRgn, rect);
	return new Point (rect.left, rect.top);
}

public boolean getMaximized () {
	checkWidget();
	//NOT DONE
	return super.getMaximized ();
}

public boolean getMinimized () {
	checkWidget();
	if (!getVisible ()) return super.getMinimized ();
	return OS.IsWindowCollapsed (shellHandle);
}

/**
 * Returns a point describing the minimum receiver's size. The
 * x coordinate of the result is the minimum width of the receiver.
 * The y coordinate of the result is the minimum height of the
 * receiver.
 *
 * @return the receiver's size
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 3.1
 */
public Point getMinimumSize () {
	checkWidget();
	Rect rect = new Rect ();
	OS.GetWindowStructureWidths (shellHandle, rect);
	CGPoint inMinLimits = new CGPoint (), inMaxLimits = new CGPoint ();
	OS.GetWindowResizeLimits (shellHandle, inMinLimits, inMaxLimits);
	int width = Math.max (1, (int) inMinLimits.x + (rect.left + rect.right));
	int height = Math.max (1, (int) inMinLimits.y + (rect.top + rect.bottom));
	return new Point (width, height);
}

float [] getParentBackground () {
	return null;
}

/** 
 * Returns the region that defines the shape of the shell,
 * or null if the shell has the default shape.
 *
 * @return the region that defines the shape of the shell (or null)
 *	
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @since 3.0
 *
 */
public Region getRegion () {
	checkWidget ();
	return region;
}

public Shell getShell () {
	checkWidget();
	return this;
}

/**
 * Returns an array containing all shells which are 
 * descendents of the receiver.
 * <p>
 * @return the dialog shells
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public Shell [] getShells () {
	checkWidget();
	int count = 0;
	Shell [] shells = display.getShells ();
	for (int i=0; i<shells.length; i++) {
		Control shell = shells [i];
		do {
			shell = shell.parent;
		} while (shell != null && shell != this);
		if (shell == this) count++;
	}
	int index = 0;
	Shell [] result = new Shell [count];
	for (int i=0; i<shells.length; i++) {
		Control shell = shells [i];
		do {
			shell = shell.parent;
		} while (shell != null && shell != this);
		if (shell == this) {
			result [index++] = shells [i];
		}
	}
	return result;
}

public Point getSize () {
	checkWidget();
	Rect rect = new Rect ();
	OS.GetWindowBounds (shellHandle, (short) OS.kWindowStructureRgn, rect);
	return new Point (rect.right - rect.left, rect.bottom - rect.top);
}

float getThemeAlpha () {
	return 1;
}

boolean hasBorder () {
	return false;
}

void hookEvents () {
	super.hookEvents ();
	int mouseProc = display.mouseProc;
	int windowProc = display.windowProc;
	int[] mask1 = new int [] {
		OS.kEventClassWindow, OS.kEventWindowActivated,
		OS.kEventClassWindow, OS.kEventWindowBoundsChanged,
		OS.kEventClassWindow, OS.kEventWindowClose,
		OS.kEventClassWindow, OS.kEventWindowCollapsed,
		OS.kEventClassWindow, OS.kEventWindowDeactivated,
		OS.kEventClassWindow, OS.kEventWindowDrawContent,
		OS.kEventClassWindow, OS.kEventWindowExpanded,
		OS.kEventClassWindow, OS.kEventWindowGetRegion,
		OS.kEventClassWindow, OS.kEventWindowHidden,
		OS.kEventClassWindow, OS.kEventWindowHitTest,
		OS.kEventClassWindow, OS.kEventWindowShown,
		OS.kEventClassWindow, OS.kEventWindowUpdate,
		OS.kEventClassWindow, OS.kEventWindowGetClickModality,
	};
	int windowTarget = OS.GetWindowEventTarget (shellHandle);
	OS.InstallEventHandler (windowTarget, windowProc, mask1.length / 2, mask1, shellHandle, null);
	int [] mask2 = new int [] {
		OS.kEventClassMouse, OS.kEventMouseDown,
		OS.kEventClassMouse, OS.kEventMouseDragged,
//		OS.kEventClassMouse, OS.kEventMouseEntered,
//		OS.kEventClassMouse, OS.kEventMouseExited,
		OS.kEventClassMouse, OS.kEventMouseMoved,
		OS.kEventClassMouse, OS.kEventMouseUp,
		OS.kEventClassMouse, OS.kEventMouseWheelMoved,
	};
	OS.InstallEventHandler (windowTarget, mouseProc, mask2.length / 2, mask2, shellHandle, null);
}

void invalidateVisibleRegion (int control) {
	resetVisibleRegion (control);
	invalidateChildrenVisibleRegion (control);
}

void invalWindowRgn (int window, int rgn) {
	if (OS.HIVIEW) {
		display.needsPaint = true;
		if (invalRgn == 0) invalRgn = OS.NewRgn();
		OS.UnionRgn (rgn, invalRgn, invalRgn);
		return;
	}
	/*
	* Bug in the Macintosh.  InvalidWindowRgn() will not invalidate
	* the window when it is called from the default kEventWindowUpdate
	* handler.  The fix is to detect that case, acumulate the region
	* to invalidate and call InvalWindowRgn() after the default handler
	* is done.  
	*/
	if (update) {
		if (invalRgn == 0) invalRgn = OS.NewRgn();
		OS.UnionRgn (rgn, invalRgn, invalRgn);
	} else {
		OS.InvalWindowRgn (window, rgn);
	}
	
}

public boolean isEnabled () {
	checkWidget();
	return getEnabled ();
}

boolean isEnabledCursor () {
	return true;
}

public boolean isVisible () {
	checkWidget();
	return getVisible ();
}

int kEventWindowActivated (int nextHandler, int theEvent, int userData) {
	int result = super.kEventWindowActivated (nextHandler, theEvent, userData);
	if (result == OS.noErr) return result;
	/*
	* Bug in the Macintosh.  Despite the that a window has scope
	* kWindowActivationScopeNone, it gets kEventWindowActivated
	* events but does not get kEventWindowDeactivated events.  The
	* fix is to ignore kEventWindowActivated events.
	*/
	int [] outScope = new int [1];
	OS.GetWindowActivationScope (shellHandle, outScope); 
	if (outScope [0] == OS.kWindowActivationScopeNone) return result;
	if (!active) {
		active = true;
		Display display = this.display;
		display.activeShell = this;
		display.setMenuBar (menuBar);
		if (menuBar != null) OS.DrawMenuBar ();
		sendEvent (SWT.Activate);
		if (!isDisposed ()) {
			if (!restoreFocus () && !traverseGroup (true)) setFocus ();
		}
		display.activeShell = null;
	}
	return result;
}

int kEventWindowBoundsChanged (int nextHandler, int theEvent, int userData) {
	int result = super.kEventWindowBoundsChanged (nextHandler, theEvent, userData);
	if (result == OS.noErr) return result;
	int [] attributes = new int [1];
	OS.GetEventParameter (theEvent, OS.kEventParamAttributes, OS.typeUInt32, null, attributes.length * 4, null, attributes);
	if ((attributes [0] & OS.kWindowBoundsChangeOriginChanged) != 0) {
		moved = true;
		sendEvent (SWT.Move);
		if (isDisposed ()) return OS.noErr;
	}
	if ((attributes [0] & OS.kWindowBoundsChangeSizeChanged) != 0) {
		resized = true;
		resizeBounds ();
		sendEvent (SWT.Resize);
		if (isDisposed ()) return OS.noErr;
		if (layout != null) {
			markLayout (false, false);
			updateLayout (false);
		}
		if (region != null && !region.isDisposed()) {
			OS.GetEventParameter (theEvent, OS.kEventParamCurrentBounds, OS.typeQDRectangle, null, Rect.sizeof, null, rgnRect);
			OS.SetRect (rgnRect, (short) 0, (short) 0, (short) (rgnRect.right - rgnRect.left), (short) (rgnRect.bottom - rgnRect.top));
			OS.ReshapeCustomWindow (shellHandle);
		}
	}
	return result;
}

int kEventWindowClose (int nextHandler, int theEvent, int userData) {
	int result = super.kEventWindowClose (nextHandler, theEvent, userData);
	if (result == OS.noErr) return result;
	if (isEnabled ()) closeWidget ();
	return OS.noErr;
}

int kEventWindowCollapsed (int nextHandler, int theEvent, int userData) {
	int result = super.kEventWindowCollapsed (nextHandler, theEvent, userData);
	if (result == OS.noErr) return result;
	minimized = true;
	sendEvent (SWT.Iconify);
	return result;
}

int kEventWindowDeactivated (int nextHandler, int theEvent, int userData) {
	int result = super.kEventWindowDeactivated (nextHandler, theEvent, userData);
	if (result == OS.noErr) return result;
	if (active) {
		active = false;
		deferDispose = true;
		Display display = this.display;
		sendEvent (SWT.Deactivate);
		if (isDisposed ()) return result;
		saveFocus ();
		if (savedFocus != null) {
			/*
			* Bug in the Macintosh.  When ClearKeyboardFocus() is called,
			* the control that has focus gets two kEventControlSetFocus
			* events indicating that focus was lost.  The fix is to ignore
			* both of these and send the focus lost event explicitly.
			*/
			display.ignoreFocus = true;
			OS.ClearKeyboardFocus (shellHandle);
			display.ignoreFocus = false;
			if (!savedFocus.isDisposed ()) savedFocus.sendFocusEvent (SWT.FocusOut, false);
		}
		display.setMenuBar (null);
		deferDispose = false;
	}
	return result;
}

int kEventWindowDrawContent (int nextHandler, int theEvent, int userData) {
	drawing = true;
	int result = OS.CallNextEventHandler (nextHandler, theEvent);
	drawing = false;	
	if (reshape) {
		reshape = false;
		OS.ReshapeCustomWindow (shellHandle);
	}
	return result;
}

int kEventWindowExpanded (int nextHandler, int theEvent, int userData) {
	int result = super.kEventWindowExpanded (nextHandler, theEvent, userData);
	if (result == OS.noErr) return result;
	minimized = false;
	sendEvent (SWT.Deiconify);
	return result;
}

int kEventWindowGetClickModality (int nextHandler, int theEvent, int userData) {
	/*
	* Bug in the Macintosh.  When the user clicks in an Expose window that is
	* disabled because of a modal dialog, the modal dialog does not come to
	* front and is obscured by the Expose window.  The fix is to select the
	* modal dialog.
	*/
	int result = OS.CallNextEventHandler (nextHandler, theEvent);
	int [] modal = new int [1];
	OS.GetEventParameter (theEvent, OS.kEventParamModalWindow, OS.typeWindowRef, null, 4, null, modal);
	if (modal [0] != 0) OS.SelectWindow (modal [0]);
	return result;
}

int kEventWindowGetRegion (int nextHandler, int theEvent, int userData) {
	int result = super.kEventWindowGetRegion (nextHandler, theEvent, userData);
	if (result == OS.noErr) return result;
	if (region == null || region.isDisposed ()) return OS.eventNotHandledErr;
	short [] regionCode = new short [1];
	OS.GetEventParameter (theEvent, OS.kEventParamWindowRegionCode, OS.typeWindowRegionCode , null, 2, null, regionCode);
	int [] temp = new int [1];
	OS.GetEventParameter (theEvent, OS.kEventParamRgnHandle, OS.typeQDRgnHandle , null, 4, null, temp);
	int hRegion = temp [0];
	switch (regionCode [0]) {
		case OS.kWindowContentRgn:
		case OS.kWindowStructureRgn:
			OS.RectRgn (hRegion, rgnRect);
			OS.SectRgn (hRegion, region.handle, hRegion);
			/*
			* Bug in the Macintosh. In kEventWindowGetRegion, 
			* Carbon assumes the origin of the Region is (0, 0)
			* and ignores the actual origin.  This causes the 
			* window to be shifted for a non zero origin.  Also,
			* the size of the window is the size of the region
			* which may be less then the size specified in
			* setSize or setBounds.
			* The fix is to include (0, 0) and the bottom 
			* right corner of the size in the region and to
			* make these points transparent.
			*/
			if (!region.contains (0, 0)) {
				Rect r = new Rect ();
				OS.SetRect (r, (short)0, (short)0, (short)1, (short)1);
				int rectRgn = OS.NewRgn ();
				OS.RectRgn (rectRgn, r);
				OS.UnionRgn (rectRgn, hRegion, hRegion);
				OS.DisposeRgn (rectRgn);
			}
			if (!region.contains (rgnRect.right - 1, rgnRect.bottom - 1)) {
				Rect r = new Rect ();
				OS.SetRect (r, (short) (rgnRect.right - 1), (short) (rgnRect.bottom - 1), rgnRect.right, rgnRect.bottom);
				int rectRgn = OS.NewRgn ();
				OS.RectRgn (rectRgn, r);
				OS.UnionRgn (rectRgn, hRegion, hRegion);
				OS.DisposeRgn (rectRgn);
			}
			return OS.noErr;
		default:
			OS.DiffRgn (hRegion, hRegion, hRegion);
			return OS.noErr;
	}
}

int kEventWindowHidden (int nextHandler, int theEvent, int userData) {
	int result = super.kEventWindowHidden (nextHandler, theEvent, userData);
	if (result == OS.noErr) return result;
	Shell [] shells = getShells ();
	for (int i=0; i<shells.length; i++) {
		Shell shell = shells [i];
		if (!shell.isDisposed ()) shell.setWindowVisible (false);
	}
	return OS.eventNotHandledErr;
}

int kEventWindowHitTest (int nextHandler, int theEvent, int userData) {
	int result = super.kEventWindowHitTest (nextHandler, theEvent, userData);
	if (result == OS.noErr) return result;
	if (region == null || region.isDisposed ()) return OS.eventNotHandledErr;
	org.eclipse.swt.internal.carbon.Point pt = new org.eclipse.swt.internal.carbon.Point ();
	int sizeof = org.eclipse.swt.internal.carbon.Point.sizeof;
	OS.GetEventParameter (theEvent, OS.kEventParamMouseLocation, OS.typeQDPoint, null, sizeof, null, pt);
	Rect rect = new Rect ();
	OS.GetWindowBounds (shellHandle, (short) OS.kWindowContentRgn, rect);
	OS.SetPt (pt, (short) (pt.h - rect.left), (short) (pt.v - rect.top));
	int rgn = OS.NewRgn ();
	OS.RectRgn (rgn, rgnRect);
	OS.SectRgn (rgn, region.handle, rgn);
	short inData = OS.PtInRgn (pt, rgn) ? OS.wInContent: OS.wNoHit;
	OS.DisposeRgn (rgn);
	OS.SetEventParameter (theEvent, OS.kEventParamWindowDefPart, OS.typeWindowDefPartCode, 2, new short [] {inData});
	return OS.noErr;
}

int kEventWindowShown (int nextHandler, int theEvent, int userData) {
	int result = super.kEventWindowShown (nextHandler, theEvent, userData);
	if (result == OS.noErr) return result;
	invalidateVisibleRegion (topHandle ());
	Shell [] shells = getShells ();
	for (int i=0; i<shells.length; i++) {
		Shell shell = shells [i];
		if (!shell.isDisposed () && shell.getVisible ()) {
			shell.setWindowVisible (true);
		}
	}
	return OS.eventNotHandledErr;
}

int kEventWindowUpdate (int nextHandler, int theEvent, int userData) {
	update = true;
	int result = OS.CallNextEventHandler (nextHandler, theEvent);
	update = false;
	if (invalRgn != 0) {
		OS.InvalWindowRgn (shellHandle, invalRgn);
		OS.DisposeRgn (invalRgn);
		invalRgn = 0;
	}
	return result;
}

void resizeBounds () {
	Rect rect = new Rect ();
	OS.GetWindowBounds (shellHandle, (short)  OS.kWindowContentRgn, rect);
	int control = scrolledHandle != 0 ? scrolledHandle : handle;
	setBounds (control, 0, 0, rect.right - rect.left, rect.bottom - rect.top, false, true, false);
	resizeClientArea ();
}

/**
 * Moves the receiver to the top of the drawing order for
 * the display on which it was created (so that all other
 * shells on that display, which are not the receiver's
 * children will be drawn behind it), marks it visible,
 * sets the focus and asks the window manager to make the
 * shell active.
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see Control#moveAbove
 * @see Control#setFocus
 * @see Control#setVisible
 * @see Display#getActiveShell
 * @see Decorations#setDefaultButton
 * @see Shell#setActive
 * @see Shell#forceActive
 */
public void open () {
	checkWidget();
	bringToTop (false);
	setVisible (true);
	if (isDisposed ()) return;
	if (active) {
		if (!restoreFocus () && !traverseGroup (true)) setFocus ();
	}
}

void register () {
	super.register ();
	int [] theRoot = new int [1];
	OS.GetRootControl (shellHandle, theRoot);
	display.addWidget (theRoot [0], this);
}

void releaseChildren (boolean destroy) {
	Shell [] shells = getShells ();
	for (int i=0; i<shells.length; i++) {
		Shell shell = shells [i];
		if (shell != null && !shell.isDisposed ()) {
			shell.dispose ();
		}
	}
	super.releaseChildren (destroy);
}

void releaseHandle () {
	super.releaseHandle ();
	shellHandle = 0;
}

void releaseParent () {
	/* Do nothing */
}

void releaseWidget () {
	super.releaseWidget ();
	disposed = true;
	if (windowGroup != 0) OS.ReleaseWindowGroup (windowGroup);
	display.updateQuitMenu ();
	if (invalRgn != 0) OS.DisposeRgn (invalRgn);
	invalRgn = windowGroup = 0;
	lastActive = null;
	region = null;
}

/**
 * Removes the listener from the collection of listeners who will
 * be notified when operations are performed on the receiver.
 *
 * @param listener the listener which should no longer be notified
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see ShellListener
 * @see #addShellListener
 */
public void removeShellListener(ShellListener listener) {
	checkWidget();
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (eventTable == null) return;
	eventTable.unhook(SWT.Activate, listener);
	eventTable.unhook(SWT.Close, listener);
	eventTable.unhook(SWT.Deactivate, listener);
	eventTable.unhook(SWT.Iconify,listener);
	eventTable.unhook(SWT.Deiconify,listener);
}

/**
 * If the receiver is visible, moves it to the top of the 
 * drawing order for the display on which it was created 
 * (so that all other shells on that display, which are not 
 * the receiver's children will be drawn behind it) and asks 
 * the window manager to make the shell active 
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @since 2.0
 * @see Control#moveAbove
 * @see Control#setFocus
 * @see Control#setVisible
 * @see Display#getActiveShell
 * @see Decorations#setDefaultButton
 * @see Shell#open
 * @see Shell#setActive
 */
public void setActive () {
	checkWidget ();
	if (!isVisible ()) return;
	OS.SelectWindow (shellHandle);
}

void setActiveControl (Control control) {
	if (control != null && control.isDisposed ()) control = null;
	if (lastActive != null && lastActive.isDisposed ()) lastActive = null;
	if (lastActive == control) return;
	
	/*
	* Compute the list of controls to be activated and
	* deactivated by finding the first common parent
	* control.
	*/
	Control [] activate = (control == null) ? new Control[0] : control.getPath ();
	Control [] deactivate = (lastActive == null) ? new Control[0] : lastActive.getPath ();
	lastActive = control;
	int index = 0, length = Math.min (activate.length, deactivate.length);
	while (index < length) {
		if (activate [index] != deactivate [index]) break;
		index++;
	}
	
	/*
	* It is possible (but unlikely), that application
	* code could have destroyed some of the widgets. If
	* this happens, keep processing those widgets that
	* are not disposed.
	*/
	for (int i=deactivate.length-1; i>=index; --i) {
		if (!deactivate [i].isDisposed ()) {
			deactivate [i].sendEvent (SWT.Deactivate);
		}
	}
	for (int i=activate.length-1; i>=index; --i) {
		if (!activate [i].isDisposed ()) {
			activate [i].sendEvent (SWT.Activate);
		}
	}
}

int setBounds (int x, int y, int width, int height, boolean move, boolean resize, boolean events) {
	Rect rect = new Rect ();
	if (!move) {
		OS.GetWindowBounds (shellHandle, (short) OS.kWindowStructureRgn, rect);
		x = rect.left;
		y = rect.top;
	}
	if (!resize) {
		OS.GetWindowBounds (shellHandle, (short) OS.kWindowStructureRgn, rect);
		width = rect.right - rect.left;
		height = rect.bottom - rect.top;
	} else {
		OS.GetWindowStructureWidths (shellHandle, rect);
		CGPoint inMinLimits = new CGPoint (), inMaxLimits = new CGPoint ();
		OS.GetWindowResizeLimits (shellHandle, inMinLimits, inMaxLimits);
		width = Math.max (1, Math.max (width, (int) inMinLimits.x + (rect.left + rect.right)));
		height = Math.max (1, Math.max (height, (int) inMinLimits.y + (rect.top + rect.bottom)));
	}
	OS.SetRect (rect, (short) x, (short) y, (short) (x + width), (short) (y + height));
	OS.SetWindowBounds (shellHandle, (short) OS.kWindowStructureRgn, rect);
	return 0;
}

public void setEnabled (boolean enabled) {
	checkWidget();
	if (((state & DISABLED) == 0) == enabled) return;
	super.setEnabled (enabled);
	if (enabled && OS.IsWindowActive (shellHandle)) {
		if (!restoreFocus ()) traverseGroup (false);
	}
}

public void setMenuBar (Menu menu) {
	checkWidget();
	super.setMenuBar (menu);
	if (display.getActiveShell () == this) {
		display.setMenuBar (menuBar);
	}
}

/**
 * Sets the input method editor mode to the argument which 
 * should be the result of bitwise OR'ing together one or more
 * of the following constants defined in class <code>SWT</code>:
 * <code>NONE</code>, <code>ROMAN</code>, <code>DBCS</code>, 
 * <code>PHONETIC</code>, <code>NATIVE</code>, <code>ALPHA</code>.
 *
 * @param mode the new IME mode
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see SWT
 */
public void setImeInputMode (int mode) {
	checkWidget();
}

public void setMaximized (boolean maximized) {
	checkWidget();
	super.setMaximized (maximized);
	org.eclipse.swt.internal.carbon.Point pt = new org.eclipse.swt.internal.carbon.Point ();
	if (maximized) {
		Rect rect = new Rect ();
		int gdevice = OS.GetMainDevice ();
		OS.GetAvailableWindowPositioningBounds (gdevice, rect);
		pt.h = (short) (rect.right - rect.left);
		pt.v = (short) (rect.bottom - rect.top);
	}
	short inPartCode = (short) (maximized ? OS.inZoomOut : OS.inZoomIn);
	OS.ZoomWindowIdeal (shellHandle, inPartCode, pt);
}

public void setMinimized (boolean minimized) {
	checkWidget();
	if (this.minimized == minimized) return;
	super.setMinimized (minimized);
	if (!minimized && OS.IsWindowCollapsed (shellHandle)) {
		OS.SelectWindow (shellHandle);
	}
	OS.CollapseWindow (shellHandle, minimized);
}

/**
 * Sets the receiver's minimum size to the size specified by the arguments.
 * If the new minimum size is larger than the current size of the receiver,
 * the receiver is resized to the new minimum size.
 *
 * @param width the new minimum width for the receiver
 * @param height the new minimum height for the receiver
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 3.1
 */
public void setMinimumSize (int width, int height) {
	checkWidget();
	int clientWidth = 0, clientHeight = 0;
	int trim = SWT.TITLE | SWT.CLOSE | SWT.MIN | SWT.MAX;
	if ((style & SWT.NO_TRIM) == 0 && (style & trim) != 0) {
		clientWidth = DEFAULT_CLIENT_WIDTH;
		clientHeight = DEFAULT_CLIENT_HEIGHT;
	}
	Rect rect = new Rect ();
	OS.GetWindowStructureWidths (shellHandle, rect);
	CGPoint inMinLimits = new CGPoint (), inMaxLimits = new CGPoint ();
	OS.GetWindowResizeLimits (shellHandle, inMinLimits, inMaxLimits);
	width = Math.max (width, clientWidth + rect.left + rect.right);
	height = Math.max (height, clientHeight + rect.top + rect.bottom);
	inMinLimits.x = width - (rect.left + rect.right);
	inMinLimits.y = height - (rect.top + rect.bottom);
	OS.SetWindowResizeLimits (shellHandle, inMinLimits, inMaxLimits);
	Point size = getSize ();
	int newWidth = Math.max (size.x, width), newHeight = Math.max (size.y, height);
	if (newWidth != size.x || newHeight != size.y) setSize (newWidth, newHeight);
}

/**
 * Sets the receiver's minimum size to the size specified by the argument.
 * If the new minimum size is larger than the current size of the receiver,
 * the receiver is resized to the new minimum size.
 *
 * @param size the new minimum size for the receiver
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the point is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 3.1
 */
public void setMinimumSize (Point size) {
	checkWidget();
	if (size == null) error (SWT.ERROR_NULL_ARGUMENT);
	setMinimumSize (size.x, size.y);
}

/**
 * Sets the shape of the shell to the region specified
 * by the argument.  When the argument is null, the
 * default shape of the shell is restored.  The shell
 * must be created with the style SWT.NO_TRIM in order
 * to specify a region.
 *
 * @param region the region that defines the shape of the shell (or null)
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the region has been disposed</li>
 * </ul>  
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @since 3.0
 *
 */
public void setRegion (Region region) {
	checkWidget ();
	if ((style & SWT.NO_TRIM) == 0) return;
	if (region != null && region.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
	if (region == null) {
		rgnRect = null;
	} else {
		if (rgnRect == null) {
			rgnRect = new Rect ();
			OS.GetWindowBounds (shellHandle, (short) OS.kWindowStructureRgn, rgnRect);
			OS.SetRect (rgnRect, (short) 0, (short) 0, (short) (rgnRect.right - rgnRect.left), (short) (rgnRect.bottom - rgnRect.top));	
		}
	}
	this.region = region;
	/*
	* Bug in the Macintosh.  Calling ReshapeCustomWindow() from a
	* kEventWindowDrawContent handler originating from ShowWindow()
	* will deadlock.  The fix is to detected this case and only call
	* ReshapeCustomWindow() after the default handler is done.
	*/
	if (drawing) {
		reshape = true;
	} else {
		OS.ReshapeCustomWindow (shellHandle);
		if (OS.HIVIEW) redrawWidget (handle, true);
	}
}

public void setText (String string) {
	checkWidget();
	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
	super.setText (string);
	char [] buffer = new char [string.length ()];
	string.getChars (0, buffer.length, buffer, 0);
	int ptr = OS.CFStringCreateWithCharacters (OS.kCFAllocatorDefault, buffer, buffer.length);
	if (ptr == 0) error (SWT.ERROR_CANNOT_SET_TEXT);
	OS.SetWindowTitleWithCFString (shellHandle, ptr);
	OS.CFRelease (ptr);
}

public void setVisible (boolean visible) {
	checkWidget();
	if (visible) {
		if ((state & HIDDEN) == 0) return;
		state &= ~HIDDEN;
	} else {
		if ((state & HIDDEN) != 0) return;
		state |= HIDDEN;
	}
	setWindowVisible (visible);
}

void setWindowVisible (boolean visible) {
	if (OS.IsWindowVisible (shellHandle) == visible) return;
	if (visible) {
		sendEvent (SWT.Show);
		if (isDisposed ()) return;
		int inModalKind = OS.kWindowModalityNone;
		if ((style & SWT.PRIMARY_MODAL) != 0) inModalKind = OS.kWindowModalityWindowModal;
		if ((style & SWT.APPLICATION_MODAL) != 0) inModalKind = OS.kWindowModalityAppModal;
		if ((style & SWT.SYSTEM_MODAL) != 0) inModalKind = OS.kWindowModalitySystemModal;
		if (inModalKind != OS.kWindowModalityNone) {
			int inUnavailableWindow = 0;
			if (parent != null) inUnavailableWindow = OS.GetControlOwner (parent.handle);
			OS.SetWindowModality (shellHandle, inModalKind, inUnavailableWindow);
		}
		int topHandle = topHandle ();
		OS.SetControlVisibility (topHandle, true, false);
		int [] scope = new int [1];
		if ((style & SWT.ON_TOP) != 0) {
			OS.GetWindowActivationScope (shellHandle, scope);
			OS.SetWindowActivationScope (shellHandle, OS.kWindowActivationScopeNone);
		}
		int shellHandle = this.shellHandle;
		OS.RetainWindow (shellHandle);
		OS.ShowWindow (shellHandle);
		OS.ReleaseWindow (shellHandle);
		if (isDisposed()) return;
		if (minimized != OS.IsWindowCollapsed (shellHandle)) {
			OS.CollapseWindow (shellHandle, minimized);
		}
		if ((style & SWT.ON_TOP) != 0) {
			OS.SetWindowActivationScope (shellHandle, scope [0]);
		}
		opened = true;
		if (!moved) {
			moved = true;
			sendEvent (SWT.Move);
			if (isDisposed ()) return;
		}
		if (!resized) {
			resized = true;
			sendEvent (SWT.Resize);
			if (isDisposed ()) return;
			if (layout != null) {
				markLayout (false, false);
				updateLayout (false);
			}
		}
	} else {
		/*
		* Bug in the Macintosh.  Under certain circumstances, yet to
		* be determined, calling HideWindow() and then DisposeWindow()
		* causes a segment fault when an application is exiting.  This
		* seems to happen to large applications.  The fix is to avoid
		* calling HideWindow() when a shell is about to be disposed.
		*/
		if (!disposed) OS.HideWindow (shellHandle);
		if (isDisposed ()) return;
		int topHandle = topHandle ();
		OS.SetControlVisibility (topHandle, false, false);
		invalidateVisibleRegion (topHandle);
		sendEvent (SWT.Hide);
	}
	display.updateQuitMenu ();
}

void setZOrder () {
	if (scrolledHandle != 0) OS.HIViewAddSubview (scrolledHandle, handle);
}

void setZOrder (Control control, boolean above) {
	if (above) {
		//NOT DONE - move one window above another
	 	OS.BringToFront (shellHandle);
	 } else {
		int window = control == null ? 0 : OS.GetControlOwner (control.handle);
		OS.SendBehind (shellHandle, window);
	}
}

boolean traverseEscape () {
	if (parent == null) return false;
	if (!isVisible () || !isEnabled ()) return false;
	close ();
	return true;
}

}
