/*******************************************************************************
 * Copyright (c) 2000, 2011 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.*;
import org.eclipse.swt.internal.motif.*;
import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.events.*;

/**
 * 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, SHEET</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 <em>not</em> intended to be subclassed.
 * </p>
 *
 * @see Decorations
 * @see SWT
 * @see <a href="http://www.eclipse.org/swt/snippets/#shell">Shell snippets</a>
 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: ControlExample</a>
 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
 * @noextend This class is not intended to be subclassed by clients.
 */
public class Shell extends Decorations {
	int shellHandle, focusProxy;
	boolean reparented, realized, moved, resized, opened, modified, center;
	int oldX, oldY, oldWidth, oldHeight;
	Control lastActive;

	static final  int MAXIMUM_TRIM = 128;
	static final  byte [] WM_DELETE_WINDOW = Converter.wcsToMbcs(null, "WM_DELETE_WINDOW\0");
	static final  byte [] _NET_WM_STATE = Converter.wcsToMbcs(null, "_NET_WM_STATE\0");
	static final  byte [] _NET_WM_STATE_MAXIMIZED_VERT = Converter.wcsToMbcs(null, "_NET_WM_STATE_MAXIMIZED_VERT\0");
	static final  byte [] _NET_WM_STATE_MAXIMIZED_HORZ = Converter.wcsToMbcs(null, "_NET_WM_STATE_MAXIMIZED_HORZ\0");
	static final  byte [] _NET_WM_STATE_FULLSCREEN = Converter.wcsToMbcs(null, "_NET_WM_STATE_FULLSCREEN\0");
	static final int BORDER = 2;
/**
 * 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#TOOL
 * @see SWT#NO_TRIM
 * @see SWT#SHELL_TRIM
 * @see SWT#DIALOG_TRIM
 * @see SWT#ON_TOP
 * @see SWT#MODELESS
 * @see SWT#PRIMARY_MODAL
 * @see SWT#APPLICATION_MODAL
 * @see SWT#SYSTEM_MODAL
 * @see SWT#SHEET
 */
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#TOOL
 * @see SWT#NO_TRIM
 * @see SWT#SHELL_TRIM
 * @see SWT#DIALOG_TRIM
 * @see SWT#ON_TOP
 * @see SWT#MODELESS
 * @see SWT#PRIMARY_MODAL
 * @see SWT#APPLICATION_MODAL
 * @see SWT#SYSTEM_MODAL
 * @see SWT#SHEET
 */
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.center = parent != null && (style & SWT.SHEET) != 0;
	this.style = checkStyle (parent, style);
	this.parent = parent;
	this.display = display;
	if (handle != 0) {
		if (embedded) {
			this.handle = handle;
		} else {
			this.shellHandle = handle;
			state |= FOREIGN_HANDLE;
		}
	}
	reskinWidget();
	createWidget (0);
}
/**
 * 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
 * @see SWT#SHEET
 */
public Shell (Shell parent, int style) {
	this (parent != null ? parent.display : null, parent, style, 0, false);
}

static int checkStyle (Shell parent, int style) {
	style = Decorations.checkStyle (style);
	style &= ~SWT.TRANSPARENT;
	if ((style & SWT.ON_TOP) != 0) style &= ~(SWT.CLOSE | SWT.TITLE | SWT.MIN | SWT.MAX);
	int mask = SWT.SYSTEM_MODAL | SWT.APPLICATION_MODAL | SWT.PRIMARY_MODAL;
	if ((style & SWT.SHEET) != 0) {
		style &= ~SWT.SHEET;
		style |= parent == null ? SWT.SHELL_TRIM : SWT.DIALOG_TRIM;
		if ((style & mask) == 0) {
			style |= parent == null ? 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;
}

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

/**	 
 * Invokes platform specific functionality to allocate a new shell
 * that is not embedded.
 * <p>
 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
 * API for <code>Shell</code>. It is marked public only so that it
 * can be shared within the packages provided by SWT. It is not
 * available on all platforms, and should never be called from
 * application code.
 * </p>
 *
 * @param display the display for the shell
 * @param handle the handle for the shell
 * @return a new shell object containing the specified display and handle
 * 
 * @noreference This method is not intended to be referenced by clients.
 * 
 * @since 3.3
 */
public static Shell internal_new (Display display, int handle) {
	return new Shell (display, null, SWT.NO_TRIM, handle, false);
}

/**
 * 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 adjustTrim () {
	if (display.ignoreTrim) return;
	if (OS.XtIsSubclass (shellHandle, OS.overrideShellWidgetClass ())) {
		return;
	}
	int [] argList = {OS.XmNoverrideRedirect, 0};
	OS.XtGetValues (shellHandle, argList, argList.length / 2);
	if (argList [1] != 0) return;
	
	/* Query the trim insets */
	int shellWindow = OS.XtWindow (shellHandle);
	if (shellWindow == 0) return;
	int xDisplay = OS.XtDisplay (shellHandle);
	if (xDisplay == 0) return;
	
	/* Find the direct child of the root window */
	int [] unused = new int [1];
	int [] rootWindow = new int [1];
	int [] parent = new int [1];
	int [] ptr = new int [1];
	int trimWindow = shellWindow;
	OS.XQueryTree (xDisplay, trimWindow, rootWindow, parent, ptr, unused);
	if (ptr [0] != 0) OS.XFree (ptr [0]);
	if (parent [0] == 0) return;
	while (parent [0] != rootWindow [0]) {
		trimWindow = parent [0];
		OS.XQueryTree (xDisplay, trimWindow, unused, parent, ptr, unused);
		if (ptr [0] != 0) OS.XFree (ptr [0]);
		if (parent [0] == 0) return;	
	}
	
	/*
	 * Translate the coordinates of the shell window to the
	 * coordinates of the direct child of the root window
	 */
	if (shellWindow == trimWindow) return;

	/* Query the border width of the direct child of the root window */
	int [] trimBorder = new int [1];
	int [] trimWidth = new int [1];
	int [] trimHeight = new int [1];
	int [] trimX = new int [1];
	int [] trimY = new int [1];
	OS.XGetGeometry (xDisplay, trimWindow, unused, trimX, trimY, trimWidth, trimHeight, trimBorder, unused);

	/* Query the border width of the direct child of the shell window */
	int [] shellBorder = new int [1];
	int [] shellWidth = new int [1];
	int [] shellHeight = new int [1];
	OS.XGetGeometry (xDisplay, shellWindow, unused, unused, unused, shellWidth, shellHeight, shellBorder, unused);
	
	/* Query the trim-adjusted position of the inner window */
	short [] inner_x = new short [1], inner_y = new short [1];
	OS.XtTranslateCoords (shellHandle, (short) 0, (short) 0, inner_x, inner_y);

	/* Calculate the trim */
	int width = (trimWidth [0] + (trimBorder [0] * 2)) - (shellWidth [0] + (shellBorder [0] * 2));
	int height = (trimHeight [0] + (trimBorder [0] * 2)) - (shellHeight [0] + (shellBorder [0] * 2));
	int leftInset = inner_x [0] - trimX [0];
	int topInset = inner_y [0] - trimY [0];

	/*
	* Depending on the window manager, the algorithm to compute the window
	* trim sometimes chooses the wrong X window, causing a large incorrect
	* value to be calculated.  The fix is to ignore the trim values if they
	* are too large.
	*/
	if (width > MAXIMUM_TRIM || height > MAXIMUM_TRIM) {
		display.ignoreTrim = true;
		return;
	}
	
	/* Update the trim guesses to match the query */
	boolean hasTitle = false, hasResize = false, hasBorder = false;
	if ((style & SWT.NO_TRIM) == 0) {
		hasTitle = (style & (SWT.MIN | SWT.MAX | SWT.TITLE | SWT.MENU)) != 0;
		hasResize = (style & SWT.RESIZE) != 0;
		hasBorder = (style & SWT.BORDER) != 0;
	}
	if (hasTitle) {
		if (hasResize)  {
			display.leftTitleResizeWidth = leftInset;
			display.rightTitleResizeWidth = width - leftInset;
			display.topTitleResizeHeight = topInset;
			display.bottomTitleResizeHeight = height - topInset;
			return;
		}
		if (hasBorder) {
			display.leftTitleBorderWidth = leftInset;
			display.rightTitleBorderWidth = width - leftInset;
			display.topTitleBorderHeight = topInset;
			display.bottomTitleBorderHeight = height - topInset;
			return;
		}
		display.leftTitleWidth = leftInset;
		display.rightTitleWidth = width - leftInset;
		display.topTitleHeight = topInset;
		display.bottomTitleHeight = height - topInset;
		return;
	}
	if (hasResize) {
		display.leftResizeWidth = leftInset;
		display.rightResizeWidth = width - leftInset;
		display.topResizeHeight = topInset;
		display.bottomResizeHeight = height - topInset;
		return;
	}
	if (hasBorder) {
		display.leftBorderWidth = leftInset;
		display.rightBorderWidth = width - leftInset;
		display.topBorderHeight = topInset;
		display.bottomBorderHeight = height - topInset;
		return;
	}
}
int borderHandle () {
	return handle;
}
void bringToTop (boolean force) {
	/*
	* Feature in X.  Calling XSetInputFocus() when the
	* widget is not viewable causes an X bad match error.
	* The fix is to call XSetInputFocus() when the widget
	* is viewable.
	*/
	if (minimized) return;
	if (!isVisible ()) return;
	int xDisplay = OS.XtDisplay (shellHandle);
	if (xDisplay == 0) return;
	int xWindow = OS.XtWindow (focusProxy != 0 ? focusProxy : shellHandle);
	if (xWindow == 0) return;
	if (!force) {
		int [] buffer1 = new int [1], buffer2 = new int [1];
		OS.XGetInputFocus (xDisplay, buffer1, buffer2);
		if (buffer1 [0] == 0) return;
		int handle = OS.XtWindowToWidget (xDisplay, buffer1 [0]);
		if (handle == 0) return;
	}
	int shellWindow = OS.XtWindow (shellHandle);
	if (shellWindow != 0) OS.XRaiseWindow (xDisplay, shellWindow);
	OS.XSetInputFocus (xDisplay, xWindow, OS.RevertToParent, OS.CurrentTime);
}
void center () {
	if (parent == null) return;
	Rectangle rect = getBounds ();
	Rectangle parentRect = display.map (parent, null, parent.getClientArea());
	int x = Math.max (parentRect.x, parentRect.x + (parentRect.width - rect.width) / 2);
	int y = Math.max (parentRect.y, parentRect.y + (parentRect.height - rect.height) / 2);
	Rectangle monitorRect = parent.getMonitor ().getClientArea();
	if (x + rect.width > monitorRect.x + monitorRect.width) {
		x = Math.max (monitorRect.x, monitorRect.x + monitorRect.width - rect.width);
	} else {
		x = Math.max (x, monitorRect.x);
	}
	if (y + rect.height > monitorRect.y + monitorRect.height) {
		y = Math.max (monitorRect.y, monitorRect.y + monitorRect.height - rect.height);
	} else {
		y = Math.max (y, monitorRect.y);
	}
	setLocation (x, y);
}
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);
	/*
	* Feature in Motif.  There is no way to get the single pixel border
	* surrounding a TopLevelShell or a TransientShell. Attempts to set a
	* border on either the shell handle or the main window handle fail.
	* The fix is to set the border on the client area.  Therefore, the
	* border must be added back into the trim.
	*/
	int border = 0;
	if ((style & (SWT.NO_TRIM | SWT.BORDER | SWT.SHELL_TRIM)) == 0) {
		int [] argList = {OS.XmNborderWidth, 0};
		OS.XtGetValues (handle, argList, argList.length / 2);
		border = argList [1];
	}
	if (isCustomResize ()) {
		int [] argList = {OS.XmNmainWindowMarginHeight, 0};
		OS.XtGetValues (scrolledHandle, argList, argList.length / 2);
		border = argList [1];
	}
	trim.x -= trimLeft () + border;
	trim.y -= trimTop () + border;
	trim.width += trimWidth () + (border * 2);
	trim.height += trimHeight () + imeHeight () + (border * 2);
	return trim;
}
void createFocusProxy () {
	if (focusProxy != 0) return;
	int [] argList = {OS.XmNx, -1, OS.XmNy, -1, OS.XmNwidth, 1, OS.XmNheight, 1};
	focusProxy = OS.XmCreateDrawingArea (scrolledHandle, null, argList, argList.length / 2);
	if (focusProxy == 0) error (SWT.ERROR_NO_HANDLES);
	OS.XtSetMappedWhenManaged (focusProxy, false);
	OS.XtManageChild (focusProxy);
	OS.XtSetMappedWhenManaged (focusProxy, true);
}
void createHandle (int index) {
	state |= CANVAS;
	if (shellHandle == 0) {
		int decorations = 0;
		if ((style & SWT.NO_TRIM) == 0) {
			if ((style & SWT.MIN) != 0) decorations |= OS.MWM_DECOR_MINIMIZE;
			if ((style & SWT.MAX) != 0) decorations |= OS.MWM_DECOR_MAXIMIZE;
			if ((style & SWT.RESIZE) != 0) decorations |= OS.MWM_DECOR_RESIZEH;
			if ((style & SWT.BORDER) != 0) decorations |= OS.MWM_DECOR_BORDER;
			if ((style & SWT.MENU) != 0) decorations |= OS.MWM_DECOR_MENU;
			if ((style & SWT.TITLE) != 0) decorations |= OS.MWM_DECOR_TITLE;
			/*
			* Feature in Motif.  Under some Window Managers (Sawmill), in order
			* to get any border at all from the window manager it is necessary
			* to set MWM_DECOR_BORDER.  The fix is to force these bits when any
			* kind of border is requested.
			*/
			if ((style & SWT.RESIZE) != 0) decorations |= OS.MWM_DECOR_BORDER;
		}
		
		/*
		* Note: Motif treats the modal values as hints to the Window Manager.
		* For example, Enlightenment treats all modes except for SWT.MODELESS
		* as SWT.APPLICATION_MODAL.  The Motif Window Manager honours all modes.
		*/
		int inputMode = OS.MWM_INPUT_MODELESS;
		if ((style & SWT.PRIMARY_MODAL) != 0) inputMode = OS.MWM_INPUT_PRIMARY_APPLICATION_MODAL;
		if ((style & SWT.APPLICATION_MODAL) != 0) inputMode = OS.MWM_INPUT_FULL_APPLICATION_MODAL;
		if ((style & SWT.SYSTEM_MODAL) != 0) inputMode = OS.MWM_INPUT_SYSTEM_MODAL;
		
		/* 
		* Bug in Motif.  For some reason, if the title string
		* length is not a multiple of 4, Motif occasionally
		* draws garbage after the last character in the title.
		* The fix is to pad the title.
		*/
		byte [] buffer = {(byte)' ', 0, 0, 0};
		int ptr = OS.XtMalloc (buffer.length);
		OS.memmove (ptr, buffer, buffer.length);
		int [] argList1 = {
			OS.XmNmwmInputMode, inputMode,
			OS.XmNmwmDecorations, decorations,
			OS.XmNoverrideRedirect, (style & SWT.ON_TOP) != 0 ? 1 : 0,
			OS.XmNtitle, ptr,
		};
		
		/* 
		* Feature in Motif.  On some Window Managers, when a top level
		* shell is created with no decorations, the Window Manager does
		* not reparent the window regardless of the XmNoverrideRedirect
		* resource.  The fix is to treat the window as if it has been
		* reparented by the Window Manager despite the fact that this
		* has not really happened.
		*/	
		if (isUndecorated ()) {
			reparented = true;
		} 
		
		/*
		* Feature in Motif.  When a top level shell has no parent and is
		* application modal, Motif does not honour the modality.  The fix
		* is to create the shell as a child of a hidden shell handle, the
		* same way that XmNoverrideRedirect shells without parents are
		* created.
		*/
		byte [] appClass = display.appClass;
		if (parent == null && (style & SWT.ON_TOP) == 0 && inputMode != OS.MWM_INPUT_FULL_APPLICATION_MODAL) {
			int xDisplay = display.xDisplay;
			int widgetClass = OS.applicationShellWidgetClass ();
			shellHandle = OS.XtAppCreateShell (display.appName, appClass, widgetClass, xDisplay, argList1, argList1.length / 2);
		} else {
			int widgetClass = OS.transientShellWidgetClass ();
//			if ((style & SWT.ON_TOP) != 0) {
//				widgetClass = OS.OverrideShellWidgetClass ();
//			}
			int parentHandle = display.shellHandle;
			if (parent != null) parentHandle = parent.handle;
			shellHandle = OS.XtCreatePopupShell (appClass, widgetClass, parentHandle, argList1, argList1.length / 2);
		}
		OS.XtFree (ptr);
		if (shellHandle == 0) error (SWT.ERROR_NO_HANDLES);
		if (handle != 0) {
			OS.XtSetMappedWhenManaged (shellHandle, false);
			OS.XtRealizeWidget (shellHandle);
			OS.XtSetMappedWhenManaged (shellHandle, true);
			int xDisplay = display.xDisplay;
			int xWindow = OS.XtWindow (shellHandle);
			if (xWindow == 0) error (SWT.ERROR_NO_HANDLES);
			/*
			* NOTE:  The embedded parent handle must be realized
			* before embedding and cannot be realized here because
			* the handle belongs to another thread.
			*/
			OS.XReparentWindow (xDisplay, xWindow, handle, 0, 0);
			handle = 0;
		}
		
		/* Create scrolled handle */
		createHandle (index, shellHandle, true);
	} else {
		int [] buffer = new int [1];
		int [] argList = {OS.XmNchildren, 0, OS.XmNnumChildren, 0};
		OS.XtGetValues (shellHandle, argList, argList.length / 2);
		if (argList [3] < 1) error (SWT.ERROR_NO_HANDLES);
		OS.memmove (buffer, argList [1], 4);
		scrolledHandle = buffer [0];
		if (scrolledHandle == 0) error (SWT.ERROR_NO_HANDLES);
		argList [1] = argList [3] = 0;
		OS.XtGetValues (scrolledHandle, argList, argList.length / 2);
		if (argList [3] < 4) error (SWT.ERROR_NO_HANDLES);
		OS.memmove (buffer, argList [1] + (argList [3] - 1) * 4, 4);
		handle = buffer [0];
		if (handle == 0) error (SWT.ERROR_NO_HANDLES);
	}

	/*
	* Feature in Motif.  There is no way to get the single pixel
	* border surrounding a TopLevelShell or a TransientShell.
	* Attempts to set a border on either the shell handle
	* or the main window handle fail.  The fix is to set the border
	* on the client area.
	*/
	if ((style & (SWT.NO_TRIM | SWT.BORDER | SWT.SHELL_TRIM)) == 0) {
		int [] argList2 = {OS.XmNborderWidth, 1};
		OS.XtSetValues (handle, argList2, argList2.length / 2);
	}
	if (isCustomResize ()) {
		int [] argList2 = {OS.XmNmainWindowMarginWidth, BORDER, OS.XmNmainWindowMarginHeight, BORDER};
		OS.XtSetValues (scrolledHandle, argList2, argList2.length / 2);
	} 
	
	/*
	* Feature in Motif. There is no Motif API to negotiate for the
	* status line. The fix is to force the status line to appear
	* by creating a hidden text widget.  This is much safer than
	* using X API because this may conflict with Motif.
	*
	* Note that  XmNtraversalOn must be set to FALSE or the shell
	* will not take focus when the user clicks on it.
	*/
	if ((style & SWT.ON_TOP) == 0) {
		int [] argList3 = {OS.XmNtraversalOn, 0};
		int textHandle = OS.XmCreateTextField (handle, null, argList3, argList3.length / 2);
		if (textHandle == 0) error (SWT.ERROR_NO_HANDLES);
	}
}
void deregister () {
	super.deregister ();
	display.removeWidget (shellHandle);
}
void destroyWidget () {
	/*
	* Hide the shell before calling XtDestroyWidget ()
	* so that the shell will disappear without having
	* to dispatch events.  Otherwise, the user will be
	* able to interact with the trimmings between the
	* time that the shell is destroyed and the next
	* event is dispatched.
	*/
	if (OS.XtIsRealized (shellHandle)) {
		if (OS.XtIsTopLevelShell (shellHandle)) {
			OS.XtUnmapWidget (shellHandle);
		} else {
			OS.XtPopdown (shellHandle);
		}
	}
	super.destroyWidget ();
}

public void dispose () {
	/*
	* Note:  It is valid to attempt to dispose a widget
	* more than once.  If this happens, fail silently.
	*/
	if (isDisposed()) return;

	/*
	* This code is intentionally commented.  On some
	* platforms, the owner window is repainted right
	* away when the dialog window exits.  This behavior
	* is currently unspecified.
	*/
//	if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
//	Display oldDisplay = display;

	/*
	* Feature in Motif.  When the active shell is disposed,
	* Motif assigns focus temporarily to the root window
	* unless it has previously been told to do otherwise.
	* The fix is to make the parent be the active top level
	* shell when the child shell is disposed.
	*/
	if (parent != null) {
		Shell activeShell = display.getActiveShell ();
		if (activeShell == this) {
			Shell shell = parent.getShell ();
			shell.bringToTop (false);
		}
	}
	super.dispose ();
	
	/*
	* This code intentionally commented.
	*/
//	if (oldDisplay != null) oldDisplay.update ();
}
void enableWidget (boolean enabled) {
	super.enableWidget (enabled);
	enableHandle (enabled, shellHandle);
}
Control findBackgroundControl () {
	return (state & BACKGROUND) != 0 || backgroundImage != null ? this : null;
}
Composite findDeferredControl () {
	return layoutCount > 0 ? this : null;
}
/**
 * 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(Button)
 * @see Shell#open
 * @see Shell#setActive
 */
public void forceActive () {
	checkWidget ();
	bringToTop (true);
}
/**
 * Returns the receiver's alpha value. The alpha value
 * is between 0 (transparent) and 255 (opaque).
 *
 * @return the alpha value
 *
 * @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.4
 */
public int getAlpha () {
	checkWidget ();
	return 255;
}
public int getBorderWidth () {
	checkWidget();
	int [] argList = {OS.XmNborderWidth, 0};
	OS.XtGetValues (scrolledHandle, argList, argList.length / 2);
	return argList [1];
}
public Rectangle getBounds () {
	checkWidget();
	Rectangle bounds = new Rectangle (0, 0, 0, 0);
	getBounds (null, null, bounds);
	return bounds;
}
void getBounds(Point location, Point size, Rectangle bounds) {
	int x = 0, y = 0;
	if (location != null || bounds != null) {
		/*
		* Bug in Motif.  For some reason, XtTranslateCoords() returns different
		* values depending on whether XtMoveWidget() or XtConfigureWidget() has
		* been called.  This only happens after the shell has been realized.
		* The fix is to use XTranslateCoordinates() instead.
		*/
		if (OS.XtIsRealized (shellHandle)) {
			int xDisplay = OS.XtDisplay (shellHandle);
			int xWindow = OS.XtWindow (shellHandle);
			int[] root_x = new int[1], root_y = new int[1], child = new int[1];
			/* Flush outstanding move and resize requests */
			OS.XSync (xDisplay, false);
			OS.XTranslateCoordinates (xDisplay, xWindow, OS.XDefaultRootWindow (xDisplay), 0, 0, root_x, root_y, child);
			x = root_x [0];
			y = root_y [0];
		} else {
			short [] root_x = new short [1], root_y = new short [1];
			OS.XtTranslateCoords (shellHandle, (short) 0, (short) 0, root_x, root_y);
			x = root_x [0];
			y = root_y [0];
		}
		if (reparented) {
			x -= trimLeft ();
			y -= trimTop ();
		}
	}
	int width = 0, height = 0;
	if (size != null || bounds != null) {
		int [] argList = {OS.XmNwidth, 0, OS.XmNheight, 0, OS.XmNborderWidth, 0};
		OS.XtGetValues (shellHandle, argList, argList.length / 2);
		int border = argList [5];
		int trimWidth = trimWidth (), trimHeight = trimHeight ();
		width = argList [1] + trimWidth + (border * 2);		
		height = argList [3] + trimHeight + (border * 2);
	}
	if (location != null) {
		location.x = x;
		location.y = y;
	}
	if (size != null) {
		size.x = width;
		size.y = height;
	}
	if (bounds != null) {
		bounds.x = x;
		bounds.y = y;
		bounds.width = width;
		bounds.height = height;
	}
}
/**
 * Returns <code>true</code> if the receiver is currently
 * in fullscreen state, and false otherwise. 
 * <p>
 *
 * @return the fullscreen state
 *
 * @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.4
 */
public boolean getFullScreen () {
	checkWidget();
	int xDisplay = OS.XtDisplay (shellHandle);
	int xWindow = OS.XtWindow (shellHandle);
	if (xWindow != 0) {
		int property = OS.XInternAtom (xDisplay, _NET_WM_STATE, true);
		if (property != 0) { 
			int[] type = new int[1], format = new int[1], nitems = new int[1], bytes_after = new int[1], atoms = new int[1];
			OS.XGetWindowProperty (xDisplay, xWindow, property, 0, Integer.MAX_VALUE, false, OS.XA_ATOM, type, format, nitems, bytes_after, atoms);
			boolean result = false;
			if (type [0] != OS.None) {
				int fullScreen = OS.XInternAtom (xDisplay, _NET_WM_STATE_FULLSCREEN, true);
				if (fullScreen != 0) {
					int[] atom = new int[1];
					for (int i=0; i<nitems [0]; i++) {
						OS.memmove(atom, atoms [0] + i * 4, 4);
						if (atom [0] == fullScreen) {
							result = true;
							break;
						}
					}
				}
			}
			if (atoms [0] != 0) OS.XFree (atoms [0]);
			return result;
		}
	}
	return false;
}
/**
 * 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();
	Point location = new Point (0, 0);
	getBounds (location, null, null);
	return location;
}
public boolean getMaximized () {
	checkWidget();
	int xDisplay = OS.XtDisplay (shellHandle);
	int xWindow = OS.XtWindow (shellHandle);
	if (xWindow != 0) {
		int property = OS.XInternAtom (xDisplay, _NET_WM_STATE, true);
		if (property != 0) { 
			int[] type = new int[1], format = new int[1], nitems = new int[1], bytes_after = new int[1], atoms = new int[1];
			OS.XGetWindowProperty (xDisplay, xWindow, property, 0, Integer.MAX_VALUE, false, OS.XA_ATOM, type, format, nitems, bytes_after, atoms);
			boolean result = false;
			if (type [0] != OS.None) {
				int maximizedHorz = OS.XInternAtom (xDisplay, _NET_WM_STATE_MAXIMIZED_HORZ, true);
				int maximizedVert = OS.XInternAtom (xDisplay, _NET_WM_STATE_MAXIMIZED_VERT, true);
				if (maximizedHorz != 0 && maximizedVert != 0) {
					int[] atom = new int[1];
					for (int i=0; i<nitems [0]; i++) {
						OS.memmove(atom, atoms [0] + i * 4, 4);
						if (atom [0] == maximizedHorz || atom [0] == maximizedVert) {
							result = true;
							break;
						}
					}
				}
			}
			if (atoms [0] != 0) OS.XFree (atoms [0]);
			return result;
		}
	}
	return super.getMaximized ();
}
/**
 * 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 ();
	int [] argList = {OS.XmNminWidth, 0, OS.XmNminHeight, 0};
	OS.XtGetValues (shellHandle, argList, argList.length / 2);
	int width = Math.max (1, Math.max (0, argList [1]) + trimWidth ());
	int height = Math.max (1, Math.max (0, argList [3]) + trimHeight ());
	return new Point (width, height);
}
/**
 * Gets the receiver's modified state.
 *
 * @return <code>true</code> if the receiver is marked as modified, or <code>false</code> otherwise
 * 
 * @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.5
 */
public boolean getModified () {
	checkWidget ();
	return modified;
}
/** 
 * Returns the region that defines the shape of the shell,
 * or <code>null</code> if the shell has the default shape.
 *
 * @return the region that defines the shape of the shell, or <code>null</code>
 *	
 * @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 () {
	/* This method is needed for the @since 3.0 Javadoc */
	checkWidget ();
	return region;
}
int getResizeMode (int x, int y) {
	int [] argList = {OS.XmNwidth, 0, OS.XmNheight, 0, OS.XmNmainWindowMarginWidth, 0};
	OS.XtGetValues (scrolledHandle, argList, argList.length / 2);
	int width = argList [1];
	int height = argList [3];
	int border = argList [5];
	int mode = 0;
	if (y >= height - border) {
		mode = OS.XC_bottom_side ;
		if (x >= width - border - 16) mode = OS.XC_bottom_right_corner;
		else if (x <= border + 16) mode = OS.XC_bottom_left_corner;
	} else if (x >= width - border) {
		mode = OS.XC_right_side;
		if (y >= height - border - 16) mode = OS.XC_bottom_right_corner;
		else if (y <= border + 16) mode = OS.XC_top_right_corner;
	} else if (y <= border) {
		mode = OS.XC_top_side;
		if (x <= border + 16) mode = OS.XC_top_left_corner;
		else if (x >= width - border - 16) mode = OS.XC_top_right_corner;
	} else if (x <= border) {
		mode = OS.XC_left_side;
		if (y <= border + 16) mode = OS.XC_top_left_corner;
		else if (y >= height - border - 16) mode = OS.XC_bottom_left_corner;
	}
	return mode;
}
public Shell getShell () {
	checkWidget();
	return this;
}
/**
 * Returns an array containing all shells which are 
 * descendants 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();
	Point size = new Point (0, 0);
	getBounds (null, size, null);
	return size;
}

/**
 * Returns a ToolBar object representing the tool bar that can be shown in the receiver's
 * trim. This will return <code>null</code> if the platform does not support tool bars that
 * are not part of the content area of the shell, or if the Shell's style does not support 
 * having a tool bar. 
 * <p>
 * 
 * @return a ToolBar object representing the Shell's tool bar, or <ocde>null</code>.
 *
 * @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.7
 */
public ToolBar getToolBar() {
	checkWidget();
	return null;
}

public boolean getVisible () {
	checkWidget();
	if (!OS.XtIsRealized (handle)) return false;
	int xDisplay = OS.XtDisplay (handle);
	if (xDisplay == 0) return false;
	int xWindow = OS.XtWindow (handle);
	if (xWindow == 0) return false;
	XWindowAttributes attributes = new XWindowAttributes ();
	OS.XGetWindowAttributes (xDisplay, xWindow, attributes);
	if (attributes.map_state == OS.IsViewable && reparented) return true;
	int [] argList = {OS.XmNmappedWhenManaged, 0};
	OS.XtGetValues (shellHandle, argList, argList.length / 2);
	return minimized && attributes.map_state == OS.IsUnviewable && argList [1] != 0;
}
boolean hasBorder () {
	return false;
}
void hookEvents () {
	super.hookEvents ();
	int windowProc = display.windowProc;
	OS.XtInsertEventHandler (shellHandle, OS.StructureNotifyMask, false, windowProc, STRUCTURE_NOTIFY, OS.XtListTail);
	if (OS.XtIsSubclass (shellHandle, OS.overrideShellWidgetClass ())) return;
	OS.XtInsertEventHandler (shellHandle, OS.FocusChangeMask, false, windowProc, FOCUS_CHANGE, OS.XtListTail);
	int [] argList = {OS.XmNdeleteResponse, OS.XmDO_NOTHING};
	OS.XtSetValues (shellHandle, argList, argList.length / 2);
	int xDisplay = OS.XtDisplay (shellHandle);
	if (xDisplay != 0) {
		int atom = OS.XmInternAtom (xDisplay, WM_DELETE_WINDOW, false);	
		OS.XmAddWMProtocolCallback (shellHandle, atom, windowProc, DELETE_WINDOW);
	}
	if (isCustomResize ()) {
		OS.XtAddEventHandler (scrolledHandle, OS.ButtonPressMask, false, windowProc, BUTTON_PRESS);
		OS.XtAddEventHandler (scrolledHandle, OS.PointerMotionMask | OS.PointerMotionHintMask, false, windowProc, POINTER_MOTION);
		OS.XtAddEventHandler (scrolledHandle, OS.LeaveWindowMask, false, windowProc, LEAVE_WINDOW);
		OS.XtInsertEventHandler (scrolledHandle, OS.ExposureMask, false, windowProc, EXPOSURE, OS.XtListTail);
	}
}
int imeHeight () {
	if (!OS.IsDBLocale) return 0;
	int [] argList1 = {OS.XmNheight, 0};
	OS.XtGetValues (shellHandle, argList1, argList1.length / 2);
	int [] argList2 = {OS.XmNheight, 0};
	OS.XtGetValues (scrolledHandle, argList2, argList2.length / 2);
	return argList1 [1] - argList2 [1];
}
public boolean isEnabled () {
	checkWidget();
	return getEnabled ();
}
boolean isModal () {
	checkWidget();
	int [] argList = {OS.XmNmwmInputMode, 0};
	OS.XtGetValues (shellHandle, argList, argList.length / 2);
	return (argList [1] != -1 && argList [1] != OS.MWM_INPUT_MODELESS);
}
boolean isCustomResize () {
	return (style & SWT.NO_TRIM) == 0 && (style & (SWT.RESIZE | SWT.ON_TOP)) == (SWT.RESIZE | SWT.ON_TOP);
}
boolean isUndecorated () {
	return
		(style & (SWT.SHELL_TRIM | SWT.BORDER)) == SWT.NONE ||
		(style & (SWT.NO_TRIM | SWT.ON_TOP)) != 0;
}
public boolean isVisible () {
	checkWidget();
	return getVisible ();
}
void manageChildren () {
	if ((state & FOREIGN_HANDLE) != 0) return;
	OS.XtSetMappedWhenManaged (shellHandle, false);
	super.manageChildren ();
	int width = 0, height = 0;
	if (OS.IsLinux) {
		Monitor monitor = getMonitor ();
		Rectangle rect = monitor.getClientArea ();
		width = rect.width * 5 / 8;
		height = rect.height * 5 / 8;
	} else {
		int xDisplay = OS.XtDisplay (shellHandle);
		if (xDisplay == 0) return;
		width = OS.XDisplayWidth (xDisplay, OS.XDefaultScreen (xDisplay)) * 5 / 8;
		height = OS.XDisplayHeight (xDisplay, OS.XDefaultScreen (xDisplay)) * 5 / 8;
	}
	OS.XtResizeWidget (shellHandle, width, height, 0);
}
/**
 * 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(Button)
 * @see Shell#setActive
 * @see Shell#forceActive
 */
public void open () {
	checkWidget();
	bringToTop (false);
	setVisible (true);
	if (isDisposed ()) return;
	if (!restoreFocus () && !traverseGroup (true)) setFocus ();
}
public boolean print (GC gc) {
	checkWidget ();
	if (gc == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (gc.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
	return false;
}
void propagateWidget (boolean enabled) {
	super.propagateWidget (enabled);
	/* Allow the busy cursor to be displayed in a disabled shell */
	int xCursor = cursor != null && !enabled ? cursor.handle : OS.None;
	propagateHandle (enabled, shellHandle, xCursor);
}
void realizeWidget () {
	if (realized) return;
	OS.XtRealizeWidget (shellHandle);
	realizeChildren ();
	realized = true;
}
void register () {
	super.register ();
	display.addWidget (shellHandle, 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.release (false);
		}
	}
	super.releaseChildren (destroy);
}
void releaseHandle () {
	super.releaseHandle ();
	shellHandle = 0;
}
void releaseParent () {
	/* Do nothing */
}
void releaseWidget () {
	super.releaseWidget ();
	lastActive = 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);
}

void reskinChildren (int flags) {
	Shell [] shells = getShells ();
	for (int i=0; i<shells.length; i++) {
		Shell shell = shells [i];
		if (shell != null) shell.reskin (flags);
	}
	super.reskinChildren (flags);
}

/**
 * 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(Button)
 * @see Shell#open
 * @see Shell#setActive
 */
public void setActive () {
	checkWidget ();
	bringToTop (false);
}

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 ()) {
			if (display.postFocusOut) {
				deactivate [i].postEvent (SWT.Deactivate);
			} else {
				deactivate [i].sendEvent (SWT.Deactivate);
			}
		}
	}
	for (int i=activate.length-1; i>=index; --i) {
		if (!activate [i].isDisposed ()) {
			activate [i].sendEvent (SWT.Activate);
		}
	}
}
/**
 * Sets the receiver's alpha value which must be
 * between 0 (transparent) and 255 (opaque).
 * <p>
 * This operation requires the operating system's advanced
 * widgets subsystem which may not be available on some
 * platforms.
 * </p>
 * @param alpha the alpha value
 *
 * @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.4
 */
public void setAlpha (int alpha) {
	checkWidget ();
	/* Not implemented */
}
/**
 * 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();
}
boolean setBounds (int x, int y, int width, int height, boolean move, boolean resize) {
	/*
	* Bug in Motif.  When a shell that is maximized is resized to
	* the same size, when the shell is unmaximized, the origin of
	* the shell is moved to (0, 0).  The fix is to detect this case
	* and avoid resizing the shell.
	* 
	* NOTE: When only the size is changed, the shell moves to (0, 0).
	* When only the location is changed, the shell is not moved.  There
	* is no fix for these problems at this time.
	*/
	if (getMaximized ()) {
		Rectangle rect = getBounds ();
		boolean sameOrigin = !move || (rect.x == x && rect.y == y);
		boolean sameExtent = !resize || (rect.width == width && rect.height == height);
		if (sameOrigin && sameExtent) return false;
	}
	if (resize) {
		int [] argList = {OS.XmNminWidth, 0, OS.XmNminHeight, 0};
		OS.XtGetValues (shellHandle, argList, argList.length / 2);
		/*
		* Feature in Motif.  Motif will not allow a window
		* to have a zero width or zero height.  The fix is
		* to ensure these values are never zero.
		*/
		width = Math.max (1, Math.max (argList [1], width - trimWidth ()));
		height = Math.max (1, Math.max (argList [3], height - trimHeight ()));
		updateResizable (width, height);
	}
	if (move && resize) {
		OS.XtConfigureWidget (shellHandle, x, y, width, height, 0);
	} else {
		if (move) OS.XtMoveWidget (shellHandle, x, y);
		if (resize) OS.XtResizeWidget (shellHandle, width, height, 0);
	}
	if (redrawWindow != 0) {
		int xDisplay = OS.XtDisplay (handle);
		OS.XResizeWindow (xDisplay, redrawWindow, width, height);
	}
	if (move && (oldX != x || oldY != y)) {
		moved = true;
		oldX = x + trimLeft ();
		oldY = y + trimTop ();
		sendEvent (SWT.Move);
		if (isDisposed ()) return false;
	}
	if (resize && (width != oldWidth || height != oldHeight)) {
		resized = true;
		oldWidth = width;
		oldHeight = height;
		sendEvent (SWT.Resize);
		if (isDisposed ()) return false;
		if (layout != null) {
			markLayout (false, false);
			updateLayout (false);
		}
	}
	return move || resize;
}
public void setEnabled (boolean enabled) {
	checkWidget ();
	if (enabled == getEnabled ()) return;
	super.setEnabled (enabled);
	if (enabled && this == display.getActiveShell ()) {
		if (!restoreFocus ()) traverseGroup (false);
	}
}
/**
 * Sets the full screen state of the receiver.
 * If the argument is <code>true</code> causes the receiver
 * to switch to the full screen state, and if the argument is
 * <code>false</code> and the receiver was previously switched
 * into full screen state, causes the receiver to switch back
 * to either the maximized or normal states.
 * <p>
 * Note: The result of intermixing calls to <code>setFullScreen(true)</code>, 
 * <code>setMaximized(true)</code> and <code>setMinimized(true)</code> will 
 * vary by platform. Typically, the behavior will match the platform user's 
 * expectations, but not always. This should be avoided if possible.
 * </p>
 * 
 * @param fullScreen the new fullscreen state
 *
 * @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.4
 */
public void setFullScreen (boolean fullScreen) {
	checkWidget();
	if (!OS.XtIsRealized (handle)) realizeWidget ();
	int xDisplay = OS.XtDisplay (shellHandle);
	int xWindow = OS.XtWindow (shellHandle);
	if (xWindow == 0) return;
	int property = OS.XInternAtom (xDisplay, _NET_WM_STATE, true);
	if (property == 0) return;
	int atom = OS.XInternAtom (xDisplay, _NET_WM_STATE_FULLSCREEN, true);
	if (atom == 0) return;
	XClientMessageEvent xEvent = new XClientMessageEvent ();
	xEvent.type = OS.ClientMessage;
	xEvent.send_event = 1;
	xEvent.display = xDisplay;
	xEvent.window = xWindow;
	xEvent.message_type = property;
	xEvent.format = 32;
	xEvent.data [0] = fullScreen ? 1 : 0;
	xEvent.data [1] = atom;
	XWindowAttributes attributes = new XWindowAttributes ();
	OS.XGetWindowAttributes (xDisplay, xWindow, attributes);
	int rootWindow = OS.XRootWindowOfScreen (attributes.screen);
	int event = OS.XtMalloc (XEvent.sizeof);
	OS.memmove (event, xEvent, XClientMessageEvent.sizeof);
	OS.XSendEvent (xDisplay, rootWindow, false, OS.SubstructureRedirectMask|OS.SubstructureNotifyMask, event);
	OS.XSync (xDisplay, false);
	OS.XtFree (event);
}
public void setMaximized (boolean maximized) {
	checkWidget();
	super.setMaximized (maximized);
	if (!OS.XtIsRealized (handle)) realizeWidget ();
	int xDisplay = OS.XtDisplay (shellHandle);
	int xWindow = OS.XtWindow (shellHandle);
	if (xWindow == 0) return;
	int property = OS.XInternAtom (xDisplay, _NET_WM_STATE, true);
	if (property == 0) return;
	int hMaxAtom = OS.XInternAtom (xDisplay, _NET_WM_STATE_MAXIMIZED_HORZ, true);
	int vMaxAtom = OS.XInternAtom (xDisplay, _NET_WM_STATE_MAXIMIZED_VERT, true);
	if (hMaxAtom == 0 || vMaxAtom == 0) return;
	XClientMessageEvent xEvent = new XClientMessageEvent ();
	xEvent.type = OS.ClientMessage;
	xEvent.send_event = 1;
	xEvent.display = xDisplay;
	xEvent.window = xWindow;
	xEvent.message_type = property;
	xEvent.format = 32;
	xEvent.data [0] = maximized ? 1 : 0;
	xEvent.data [1] = hMaxAtom;
	xEvent.data [2] = vMaxAtom;
	XWindowAttributes attributes = new XWindowAttributes ();
	OS.XGetWindowAttributes (xDisplay, xWindow, attributes);
	int rootWindow = OS.XRootWindowOfScreen (attributes.screen);
	int event = OS.XtMalloc (XEvent.sizeof);
	OS.memmove (event, xEvent, XClientMessageEvent.sizeof);
	OS.XSendEvent (xDisplay, rootWindow, false, OS.SubstructureRedirectMask|OS.SubstructureNotifyMask, event);
	OS.XSync (xDisplay, false);
	OS.XtFree (event);
}
public void setMinimized (boolean minimized) {
	checkWidget();
	if (minimized == this.minimized) return;
	
	/* 
	* Bug in MOTIF.  For some reason, the receiver does not keep the
	* value of the XmNiconic resource up to date when the user minimizes
	* and restores the window.  As a result, a window that is minimized
	* by the user and then restored by the programmer is not restored.
	* This happens because the XmNiconic resource is unchanged when the
	* window is minimized by the user and subsequent attempts to set the
	* resource fail because the new value of the resource is the same as
	* the old value.  The fix is to force XmNiconic to be up to date
	* before setting the desired value.
	*/
	int [] argList = {
		OS.XmNiconic, 0,
		OS.XmNinitialState, 0,
	};
	OS.XtGetValues (shellHandle, argList, argList.length / 2);
	if ((argList [1] != 0) != this.minimized) {
		argList [1] = this.minimized ? 1 : 0;
		OS.XtSetValues (shellHandle, argList, argList.length / 2);
	}

	/* Minimize or restore the shell */
	super.setMinimized (minimized);
	argList [1] = minimized ? 1 : 0;
	argList [3] = minimized ? OS.IconicState : OS.NormalState;
	OS.XtSetValues (shellHandle, argList, argList.length / 2);

	/* Force the XWindowAttributes to be up to date */
	int xDisplay = OS.XtDisplay (handle);
	if (xDisplay != 0) OS.XSync (xDisplay, false);
	
	/* Make the restored shell be the active shell */
	if (!minimized) {
		int [] argList2 = {OS.XmNmappedWhenManaged, 0};
		OS.XtGetValues (shellHandle, argList2, argList2.length / 2);
		if (argList2 [1] != 0) {
			do {
				display.update ();
			} while (!isVisible ());
			setActive ();
		}
	}
}
/**
 * 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 [] argList = {
		OS.XmNminWidth, Math.max (width, trimWidth ()) - trimWidth (),
		OS.XmNminHeight, Math.max (height, trimHeight ()) - trimHeight (),
	};
	OS.XtSetValues (shellHandle, argList, argList.length / 2);
}
/**
 * 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 receiver's modified state as specified by the argument.
 *
 * @param modified the new modified state for the receiver
 *
 * </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.5
 */
public void setModified (boolean modified) {
	checkWidget ();
	this.modified = modified;
}
void setParentTraversal () {
	/* Do nothing - Child shells do not affect the traversal of their parent shell */
}
/**
 * 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);
	super.setRegion (region);
}
public void setText (String string) {
	checkWidget();
	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
	super.setText (string);
	
	/*
	* Feature in Motif.  It is not possible to set a shell
	* title to an empty string.  The fix is to set the title
	* to be a single space.
	*/
	/* Use the character encoding for the default locale */
	if (string.length () == 0) string = " ";
	byte [] buffer1 = Converter.wcsToMbcs (null, string, true);
	
	/* 
	* Bug in Motif.  For some reason, if the title string
	* length is not a multiple of 4, Motif occasionally
	* draws garbage after the last character in the title.
	* The fix is to pad the title.
	*/
	byte [] buffer2 = buffer1;
	int length = buffer1.length - 1;
	if ((length % 4) != 0) {
		buffer2 = new byte [(length + 3) / 4 * 4];
		System.arraycopy (buffer1, 0, buffer2, 0, length);
	}

	/* Set the title for the shell */
	int ptr = OS.XtMalloc (buffer2.length + 1);
	OS.memmove (ptr, buffer2, buffer2.length);
	int [] argList = {OS.XmNtitle, ptr, OS.XmNiconName, ptr};
	OS.XtSetValues (shellHandle, argList, argList.length / 2);
	OS.XtFree (ptr);
}
public void setVisible (boolean visible) {
	checkWidget();
	realizeWidget ();

	/* Show the shell */
	if (visible) {
		if (center && !moved) {
			center ();
			if (isDisposed ()) return;
		}
		sendEvent (SWT.Show);
		if (isDisposed ()) return;

		/* Map the widget */
		OS.XtSetMappedWhenManaged (shellHandle, true);
		if (OS.XtIsTopLevelShell (shellHandle)) {
			OS.XtMapWidget (shellHandle);
		} else {
			OS.XtPopup (shellHandle, OS.XtGrabNone);
		}
		
		/*
		* Force the shell to be fully exposed before returning.
		* This ensures that the shell coordinates are correct
		* when queried directly after showing the shell.
		* 
		* Note that if the parent is minimized or withdrawn
		* from the desktop, this should not be done since
		* the shell will not be mapped until the parent is
		* unminimized or shown on the desktop.
		*/
		boolean iconic = false;
		Shell shell = parent != null ? parent.getShell() : null;
		do {
			display.update ();
			if (isDisposed ()) return;
			iconic = minimized || (shell != null && shell.minimized);
		} while (!isVisible () && !iconic);
		if (!iconic) adjustTrim ();
		
		int mask = SWT.PRIMARY_MODAL | SWT.APPLICATION_MODAL | SWT.APPLICATION_MODAL;
		if ((style & mask) != 0) {
			OS.XUngrabPointer (display.xDisplay, OS.CurrentTime);
		}
		opened = true;
		if (!moved) {
			moved = true;
			Point location = getLocation ();
			oldX = location.x + trimLeft ();
			oldY = location.x + trimTop ();
			sendEvent (SWT.Move);
			if (isDisposed ()) return;
		}
		if (!resized) {
			resized = true;
			Point size = getSize ();
			oldWidth = size.x - trimWidth ();
			oldHeight = size.y - trimHeight ();
			sendEvent (SWT.Resize);
			if (isDisposed ()) return;
			if (layout != null) {
				markLayout (false, false);
				updateLayout (false);
			}
		}
	} else {
		/*
		* Feature in Motif.  When the active shell is disposed,
		* some window managers place focus in a temporary window.
		* The fix is to make the parent be the active top level
		* shell when the child shell is hidden.
		*/
		if (parent != null) {
			Shell activeShell = display.getActiveShell ();
			if (activeShell == this) {
				Shell shell = parent.getShell ();
				shell.bringToTop (false);
			}
		}
	
		/* Hide the shell */
		OS.XtSetMappedWhenManaged (shellHandle, false);
		if (OS.XtIsTopLevelShell (shellHandle)) {
			OS.XtUnmapWidget (shellHandle);
		} else {
			OS.XtPopdown (shellHandle);
		}
	
		/* If the shell is iconified, hide the icon */
		int xDisplay = OS.XtDisplay (shellHandle);
		if (xDisplay == 0) return;
		int xWindow = OS.XtWindow (shellHandle);
		if (xWindow == 0) return;
		OS.XWithdrawWindow (xDisplay, xWindow, OS.XDefaultScreen (xDisplay));
	
		sendEvent (SWT.Hide);
	}
}
void setZOrder (Control control, boolean above) {
	setZOrder (control, above, false);
}
int topHandle () {
	return shellHandle;
}
boolean traverseEscape () {
	if (parent == null) return false;
	if (!isVisible () || !isEnabled ()) return false;
	close ();
	return true;
}
int trimHeight () {
	if ((style & SWT.NO_TRIM) != 0) return 0;
	boolean hasTitle = false, hasResize = false, hasBorder = false;
	hasTitle = (style & (SWT.MIN | SWT.MAX | SWT.TITLE | SWT.MENU)) != 0;
	hasResize = (style & SWT.RESIZE) != 0;
	hasBorder = (style & SWT.BORDER) != 0;
	if (hasTitle) {
		if (hasResize) {
			return display.topTitleResizeHeight + display.bottomTitleResizeHeight;
		}
		if (hasBorder) {
			return display.topTitleBorderHeight + display.bottomTitleBorderHeight;
		}
		return display.topTitleHeight + display.bottomTitleHeight;
	}
	if (hasResize) {
		return display.topResizeHeight + display.bottomResizeHeight;
	}
	if (hasBorder) {
		return display.topBorderHeight + display.bottomBorderHeight;
	}
	return 0;
}
int trimLeft () {
	if ((style & SWT.NO_TRIM) != 0) return 0;
	boolean hasTitle = false, hasResize = false, hasBorder = false;
	hasTitle = (style & (SWT.MIN | SWT.MAX | SWT.TITLE | SWT.MENU)) != 0;
	hasResize = (style & SWT.RESIZE) != 0;
	hasBorder = (style & SWT.BORDER) != 0;
	if (hasTitle) {
		if (hasResize) return display.leftTitleResizeWidth;
		if (hasBorder) return display.leftTitleBorderWidth;
		return display.leftTitleWidth;
	}
	if (hasResize) return display.leftResizeWidth;
	if (hasBorder) return display.leftBorderWidth;
	return 0;
}
int trimTop () {
	if ((style & SWT.NO_TRIM) != 0) return 0;
	boolean hasTitle = false, hasResize = false, hasBorder = false;
	hasTitle = (style & (SWT.MIN | SWT.MAX | SWT.TITLE | SWT.MENU)) != 0;
	hasResize = (style & SWT.RESIZE) != 0;
	hasBorder = (style & SWT.BORDER) != 0;
	if (hasTitle) {
		if (hasResize) return display.topTitleResizeHeight;
		if (hasBorder) return display.topTitleBorderHeight;
		return display.topTitleHeight;
	}
	if (hasResize) return display.topResizeHeight;
	if (hasBorder) return display.topBorderHeight;
	return 0;
}
int trimWidth () {
	if ((style & SWT.NO_TRIM) != 0) return 0;
	boolean hasTitle = false, hasResize = false, hasBorder = false;
	hasTitle = (style & (SWT.MIN | SWT.MAX | SWT.TITLE | SWT.MENU)) != 0;
	hasResize = (style & SWT.RESIZE) != 0;
	hasBorder = (style & SWT.BORDER) != 0;
	if (hasTitle) {
		if (hasResize) {
			return display.leftTitleResizeWidth + display.rightTitleResizeWidth;
		}
		if (hasBorder) {
			return display.leftTitleBorderWidth + display.rightTitleBorderWidth;
		}
		return display.leftTitleWidth + display.rightTitleWidth;
	}
	if (hasResize) {
		return display.leftResizeWidth + display.rightResizeWidth;
	}
	if (hasBorder) {
		return display.leftBorderWidth + display.rightBorderWidth;
	}
	return 0;
}
void updateResizable (int width, int height) {
	if ((style & SWT.RESIZE) != 0) return;
	if (!OS.XtIsRealized (shellHandle)) return;
	XSizeHints hints = new XSizeHints ();
	hints.flags = OS.PMinSize | OS.PMaxSize | OS.PPosition;
	hints.min_width = hints.max_width = width;
	hints.min_height = hints.max_height = height;
	OS.XSetWMNormalHints (OS.XtDisplay (shellHandle), OS.XtWindow (shellHandle), hints);
}
int WM_DELETE_WINDOW (int w, int client_data, int call_data) {
	if (!isEnabled ()) return 0;
	Control widget = parent;
	while (widget != null && !(widget.getShell ().isModal ())) {
		widget = widget.parent;
	}
	if (widget == null) {
		Shell [] shells = getShells ();
		for (int i=0; i<shells.length; i++) {
			Shell shell = shells [i];
			if (shell != this && shell.isModal () && shell.isVisible ()) {
				shell.bringToTop (false);
				return 0;
			}
		}
	}
	closeWidget ();
	return 0;
}
int XButtonPress (int w, int client_data, int call_data, int continue_to_dispatch) {
	if (w == scrolledHandle) {
		if (isCustomResize ()) {
			if ((style & SWT.ON_TOP) != 0 && (style & SWT.NO_FOCUS) == 0) {
				forceActive ();
			}
			XButtonEvent xEvent = new XButtonEvent ();
			OS.memmove (xEvent, call_data, XButtonEvent.sizeof);
			if (xEvent.button == 1) {
				display.resizeLocationX = xEvent.x_root;
				display.resizeLocationY = xEvent.y_root;
				Point loc = new Point (0, 0);
				getBounds(loc, null, null);
				display.resizeBoundsX  = loc.x;
				display.resizeBoundsY  = loc.y;
				int [] argList = {OS.XmNwidth, 0, OS.XmNheight, 0};
				OS.XtGetValues (shellHandle, argList, argList.length / 2);
				display.resizeBoundsWidth = argList [1];
				display.resizeBoundsHeight = argList [3];
			}
		}
		return 0;
	}
	return super.XButtonPress(w, client_data, call_data, continue_to_dispatch);
}
int XExposure (int w, int client_data, int call_data, int continue_to_dispatch) {
	if (w == scrolledHandle) {
		if (isCustomResize ()) {
			int xDisplay = OS.XtDisplay (scrolledHandle);
			if (xDisplay == 0) return 0;
			int xWindow = OS.XtWindow (scrolledHandle);
			if (xWindow == 0) return 0;
			int xGC = OS.XCreateGC (xDisplay, xWindow, 0, null);
			if (xGC == 0) return 0;;
			OS.XSetGraphicsExposures (xDisplay, xGC, false);
			XExposeEvent xEvent = new XExposeEvent ();
			OS.memmove (xEvent, call_data, XExposeEvent.sizeof);
			int damageRgn = OS.XCreateRegion ();
			OS.XtAddExposureToRegion (call_data, damageRgn);
			OS.XSetRegion (xDisplay, xGC, damageRgn);
			int [] argList = {
					OS.XmNwidth, 0,
					OS.XmNheight, 0, 
					OS.XmNmainWindowMarginWidth, 0,
					OS.XmNmainWindowMarginHeight, 0,
					OS.XmNtopShadowColor, 0,
					OS.XmNbottomShadowColor, 0};
			OS.XtGetValues (scrolledHandle, argList, argList.length / 2);
			int width = argList [1];
			int height = argList [3];
			int marginWidth = argList [5];
			int marginHeight = argList [7];
			int topShadowColor  = argList [9];
			int bottomShadowColor  = argList [11];
			OS.XSetForeground (xDisplay, xGC, bottomShadowColor);
			OS.XFillRectangle (xDisplay, xWindow, xGC, width - marginWidth, 0, marginWidth, height);
			OS.XFillRectangle (xDisplay, xWindow, xGC, 0, height - marginHeight, width, marginHeight);
			OS.XSetForeground (xDisplay, xGC, topShadowColor);
			int half = marginWidth / 2;
			OS.XDrawLine (xDisplay, xWindow, xGC, 0, 0, 0, height - 1);
			OS.XDrawLine (xDisplay, xWindow, xGC, half, 0, half, height - half - 1);
			OS.XDrawLine (xDisplay, xWindow, xGC, 0, 0, width - 1, 0);
			OS.XDrawLine (xDisplay, xWindow, xGC, 0, half, width - half - 1, half);
			OS.XFreeGC (xDisplay, xGC);
			OS.XDestroyRegion (damageRgn);
		}
		return 0;
	}
	return super.XExposure (w, client_data, call_data, continue_to_dispatch);
}
int XFocusChange (int w, int client_data, int call_data, int continue_to_dispatch) {
	XFocusChangeEvent xEvent = new XFocusChangeEvent ();
	OS.memmove (xEvent, call_data, XFocusChangeEvent.sizeof);
	int handle = OS.XtWindowToWidget (xEvent.display, xEvent.window);
	if (handle != shellHandle) {
		return super.XFocusChange (w, client_data, call_data, continue_to_dispatch);
	}
	if (xEvent.mode != OS.NotifyNormal) return 0;
	if (xEvent.type == OS.FocusIn && xEvent.detail == OS.NotifyInferior) {
		if (focusProxy != 0) {
			int xWindow = OS.XtWindow (focusProxy);
			int xDisplay = OS.XtDisplay (focusProxy);
			OS.XSetInputFocus (xDisplay, xWindow, OS.RevertToParent, OS.CurrentTime);
		}
	}
	switch (xEvent.detail) {
		case OS.NotifyNonlinear:
		case OS.NotifyNonlinearVirtual: {
			switch (xEvent.type) {
				case OS.FocusIn:
					if (display.postFocusOut) {
						postEvent (SWT.Activate);
					} else {
						sendEvent (SWT.Activate);
					}
					break;
				case OS.FocusOut:
					Display display = this.display;
					if (display.postFocusOut) {
						postEvent (SWT.Deactivate);
					} else {
						sendEvent (SWT.Deactivate);
					}
					Control focusedCombo = display.focusedCombo;
					display.focusedCombo = null;
					if (focusedCombo != null && focusedCombo != this && !focusedCombo.isDisposed ()) {
						display.sendFocusEvent (focusedCombo, SWT.FocusOut);
					}
					break;
			}
		}
	}
	return 0;
}
int XLeaveWindow (int w, int client_data, int call_data, int continue_to_dispatch) {
	if (w == scrolledHandle) {
		if (isCustomResize ()) {
			XCrossingEvent xEvent = new XCrossingEvent ();
			OS.memmove (xEvent, call_data, XCrossingEvent.sizeof);
			if ((xEvent.state & OS.Button1Mask) == 0) {
				int xDisplay = OS.XtDisplay (scrolledHandle);
				if (xDisplay != 0) {
					int xWindow = OS.XtWindow (scrolledHandle);
					if (xWindow != 0) {
						OS.XUndefineCursor (xDisplay, xWindow);
					}
				}
				display.resizeMode = 0;
			}
		}
		return 0;
	}
	return super.XLeaveWindow (w, client_data, call_data, continue_to_dispatch);
}
int XPointerMotion (int w, int client_data, int call_data, int continue_to_dispatch) {
	if (w == scrolledHandle) {
		if (isCustomResize ()) {
			XMotionEvent xEvent = new XMotionEvent ();
			OS.memmove (xEvent, call_data, XMotionEvent.sizeof);
			int xDisplay = xEvent.display;
			if (xDisplay == 0) return 0;
			int xWindow = xEvent.window;
			if (xWindow == 0) return 0;
			if (xEvent.is_hint != 0) {
				int [] rootX = new int [1], rootY = new int [1], windowX = new int [1], windowY = new int [1], unused = new int [1], mask = new int [1];
				if (OS.XQueryPointer (xDisplay, xWindow, unused, unused, rootX, rootY, windowX, windowY, mask) == 0) {
					return 0;
				}
				xEvent.x = windowX [0];
				xEvent.y = windowY [0];
				xEvent.x_root = rootX [0];
				xEvent.y_root = rootY [0];
				xEvent.state = mask [0];
			}
			if ((xEvent.state & OS.Button1Mask) != 0) {
				int [] argList = {OS.XmNmainWindowMarginWidth, 0};
				OS.XtGetValues (scrolledHandle, argList, argList.length / 2);
				int [] argList2 = {OS.XmNminWidth, 0, OS.XmNminHeight, 0, };
				OS.XtGetValues (shellHandle, argList2, argList2.length / 2);
				int minWidth = argList2 [1];
				int minHeight = argList2 [3];
				int border = argList [1];
				int dx = (int)(xEvent.x_root - display.resizeLocationX);
				int dy = (int)(xEvent.y_root - display.resizeLocationY);
				int x = display.resizeBoundsX;
				int y = display.resizeBoundsY;
				int width = display.resizeBoundsWidth;
				int height = display.resizeBoundsHeight;
				int newWidth = Math.max(width - dx, Math.max(minWidth, border + border));
				int newHeight = Math.max(height - dy, Math.max(minHeight, border + border));
				switch (display.resizeMode) {
					case OS.XC_left_side:
						x += width - newWidth;
						width = newWidth;
						break;
					case OS.XC_top_left_corner:
						x += width - newWidth;
						width = newWidth;
						y += height - newHeight;
						height = newHeight;
						break;
					case OS.XC_top_side:
						y += height - newHeight;
						height = newHeight;
						break;
					case OS.XC_top_right_corner:
						width = Math.max(width + dx, Math.max(minWidth, border + border));
						y += height - newHeight;
						height = newHeight;
						break;
					case OS.XC_right_side:
						width = Math.max(width + dx, Math.max(minWidth, border + border));
						break;
					case OS.XC_bottom_right_corner:
						width = Math.max(width + dx, Math.max(minWidth, border + border));
						height = Math.max(height + dy, Math.max(minHeight, border + border));
						break;
					case OS.XC_bottom_side:
						height = Math.max(height + dy, Math.max(minHeight, border + border));
						break;
					case OS.XC_bottom_left_corner:
						x += width - newWidth;
						width = newWidth;
						height = Math.max(height + dy, Math.max(minHeight, border + border));
						break;
				}
				OS.XtConfigureWidget (shellHandle, x, y, width, height, 0);
			} else {
				int mode = getResizeMode (xEvent.x, xEvent.y);
				if (mode != display.resizeMode) {
					if (mode != 0) {
						int cursor = OS.XCreateFontCursor (xDisplay, mode);
						OS.XDefineCursor (xDisplay, xWindow, cursor);
						OS.XFreeCursor(xDisplay, cursor);
					} else {
						OS.XUndefineCursor (xDisplay, xWindow);
					}
					OS.XFlush (xDisplay);
					display.resizeMode = mode;
				}
			}
		}
		return 0;
	}
	return super.XPointerMotion (w, client_data, call_data, continue_to_dispatch);
}
int XStructureNotify (int w, int client_data, int call_data, int continue_to_dispatch) {
	XConfigureEvent xEvent = new XConfigureEvent ();
	OS.memmove (xEvent, call_data, XConfigureEvent.sizeof);
	int handle = OS.XtWindowToWidget (xEvent.display, xEvent.window);
	if (handle != shellHandle) {
		return super.XStructureNotify (w, client_data, call_data, continue_to_dispatch);
	}
	switch (xEvent.type) {
		case OS.ReparentNotify: {
			reparented = true;
			adjustTrim ();
			break;
		}
		case OS.ConfigureNotify:
			int [] root_x = new int [1], root_y = new int [1], child = new int [1];
			OS.XTranslateCoordinates (xEvent.display, xEvent.window, OS.XDefaultRootWindow (xEvent.display), 0, 0, root_x, root_y, child);
			if (!moved || oldX != root_x [0] || oldY != root_y [0]) {
				moved = true;
				oldX = root_x [0];
				oldY = root_y [0];
				sendEvent (SWT.Move);
				if (isDisposed ()) return 0;
			}
			updateResizable (xEvent.width, xEvent.height);
			if (!resized || oldWidth != xEvent.width || oldHeight != xEvent.height) {
				int xEvent1 = OS.XtMalloc (XEvent.sizeof);
				display.resizeWindow = xEvent.window;
				display.resizeWidth = xEvent.width;
				display.resizeHeight = xEvent.height;
				display.resizeCount = 0;
				int checkResizeProc = display.checkResizeProc;
				OS.XCheckIfEvent (xEvent.display, xEvent1, checkResizeProc, 0);
				OS.XtFree (xEvent1);
				if (display.resizeCount == 0) {
					resized = true;
					oldWidth = xEvent.width;
					oldHeight = xEvent.height;
					sendEvent (SWT.Resize);
					if (isDisposed ()) return 0;
					if (layout != null) {
						markLayout (false, false);
						updateLayout (false);
					}
				}
			}
			return 0;
		case OS.UnmapNotify:
			int [] argList = {OS.XmNmappedWhenManaged, 0};
			OS.XtGetValues (shellHandle, argList, argList.length / 2);
			if (argList [1] != 0) {
				minimized = true;
				sendEvent (SWT.Iconify);
			}
			return 0;
		case OS.MapNotify:
			reparented = true;
			if (minimized) {
				minimized = false;
				sendEvent (SWT.Deiconify);
			}
			return 0;
	}
	return 0;
}
}
