Logo Search packages:      
Sourcecode: eclipse version File versions  Download package

Display.java

/*******************************************************************************
 * Copyright (c) 2000, 2005 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.*;

/**
 * Instances of this class are responsible for managing the
 * connection between SWT and the underlying operating
 * system. Their most important function is to implement
 * the SWT event loop in terms of the platform event model.
 * They also provide various methods for accessing information
 * about the operating system, and have overall control over
 * the operating system resources which SWT allocates.
 * <p>
 * Applications which are built with SWT will <em>almost always</em>
 * require only a single display. In particular, some platforms
 * which SWT supports will not allow more than one <em>active</em>
 * display. In other words, some platforms do not support
 * creating a new display if one already exists that has not been
 * sent the <code>dispose()</code> message.
 * <p>
 * In SWT, the thread which creates a <code>Display</code>
 * instance is distinguished as the <em>user-interface thread</em>
 * for that display.
 * </p>
 * The user-interface thread for a particular display has the
 * following special attributes:
 * <ul>
 * <li>
 * The event loop for that display must be run from the thread.
 * </li>
 * <li>
 * Some SWT API methods (notably, most of the public methods in
 * <code>Widget</code> and its subclasses), may only be called
 * from the thread. (To support multi-threaded user-interface
 * applications, class <code>Display</code> provides inter-thread
 * communication methods which allow threads other than the 
 * user-interface thread to request that it perform operations
 * on their behalf.)
 * </li>
 * <li>
 * The thread is not allowed to construct other 
 * <code>Display</code>s until that display has been disposed.
 * (Note that, this is in addition to the restriction mentioned
 * above concerning platform support for multiple displays. Thus,
 * the only way to have multiple simultaneously active displays,
 * even on platforms which support it, is to have multiple threads.)
 * </li>
 * </ul>
 * Enforcing these attributes allows SWT to be implemented directly
 * on the underlying operating system's event model. This has 
 * numerous benefits including smaller footprint, better use of 
 * resources, safer memory management, clearer program logic,
 * better performance, and fewer overall operating system threads
 * required. The down side however, is that care must be taken
 * (only) when constructing multi-threaded applications to use the
 * inter-thread communication mechanisms which this class provides
 * when required.
 * </p><p>
 * All SWT API methods which may only be called from the user-interface
 * thread are distinguished in their documentation by indicating that
 * they throw the "<code>ERROR_THREAD_INVALID_ACCESS</code>"
 * SWT exception.
 * </p>
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>(none)</dd>
 * <dt><b>Events:</b></dt>
 * <dd>Close, Dispose</dd>
 * </dl>
 * <p>
 * IMPORTANT: This class is <em>not</em> intended to be subclassed.
 * </p>
 * @see #syncExec
 * @see #asyncExec
 * @see #wake
 * @see #readAndDispatch
 * @see #sleep
 * @see Device#dispose
 */
public class Display extends Device {

      /* Motif Only Public Fields */
      public int xEvent;
      int lastSerial;
      
      /* Windows, Events and Callbacks */
      Callback windowCallback;
      int windowProc, shellHandle;
      static String APP_NAME = "SWT";
      static final String SHELL_HANDLE_KEY = "org.eclipse.swt.internal.motif.shellHandle";
      byte [] displayName, appName, appClass;
      Event [] eventQueue;
      XKeyEvent keyEvent = new XKeyEvent ();
      EventTable eventTable, filterTable;
      
      /* Widget Table */
      int freeSlot = 0;
      int [] indexTable, userData;
      Shell [] shellTable;
      Widget [] widgetTable;
      static final int GROW_SIZE = 1024;
      
      /* Focus */
      int focusEvent;
      boolean postFocusOut;
      
      /* Default Fonts, Colors, Insets, Widths and Heights. */
      Font defaultFont;
      Font listFont, textFont, buttonFont, labelFont;
      int buttonBackground, buttonForeground, buttonShadowThickness;
      int compositeBackground, compositeForeground;
      int compositeTopShadow, compositeBottomShadow, compositeBorder;
      int listBackground, listForeground, listSelect, textBackground, textForeground;
      int labelBackground, labelForeground;
      int scrolledInsetX, scrolledInsetY, scrolledMarginX, scrolledMarginY;
      int defaultBackground, defaultForeground;
      int textHighlightThickness, blinkRate;
      
      /* System Colors */
      XColor COLOR_WIDGET_DARK_SHADOW, COLOR_WIDGET_NORMAL_SHADOW, COLOR_WIDGET_LIGHT_SHADOW;
      XColor COLOR_WIDGET_HIGHLIGHT_SHADOW, COLOR_WIDGET_FOREGROUND, COLOR_WIDGET_BACKGROUND, COLOR_WIDGET_BORDER;
      XColor COLOR_LIST_FOREGROUND, COLOR_LIST_BACKGROUND, COLOR_LIST_SELECTION, COLOR_LIST_SELECTION_TEXT;
      Color COLOR_INFO_BACKGROUND;

      /* Popup Menus */
      Menu [] popups;
      
      /* System Images and Masks */
      int errorPixmap, infoPixmap, questionPixmap, warningPixmap, workingPixmap;
      int errorMask, infoMask, questionMask, warningMask, workingMask;

      /* System Cursors */
      Cursor [] cursors = new Cursor [SWT.CURSOR_HAND + 1];

      /* Initial Guesses for Shell Trimmings. */
      int leftBorderWidth = 2, rightBorderWidth = 2;
      int topBorderHeight = 2, bottomBorderHeight = 2;
      int leftResizeWidth = 3, rightResizeWidth = 3;
      int topResizeHeight = 3, bottomResizeHeight = 3;
      int leftTitleBorderWidth = 3, rightTitleBorderWidth = 2;
      int topTitleBorderHeight = 26, bottomTitleBorderHeight = 2;
      int leftTitleResizeWidth = 3, rightTitleResizeWidth = 3;
      int topTitleResizeHeight = 26, bottomTitleResizeHeight = 3;
      int leftTitleWidth = 0, rightTitleWidth = 0;
      int topTitleHeight = 23, bottomTitleHeight = 0;
      boolean ignoreTrim;
      
      /* Sync/Async Widget Communication */
      Synchronizer synchronizer = new Synchronizer (this);
      Thread thread;
      
      /* Display Shutdown */
      Runnable [] disposeList;
      
      /* System Tray */
      Tray tray;
      
      /* Timers */
      int [] timerIds;
      Runnable [] timerList;
      Callback timerCallback;
      int timerProc;
      
      /* Widget Timers */
      Callback windowTimerCallback;
      int windowTimerProc;
      
      /* Key Mappings. */
      static int [] [] KeyTable = {
            
            /* Keyboard and Mouse Masks */
            {OS.XK_Alt_L,           SWT.ALT},
            {OS.XK_Alt_R,           SWT.ALT},
            {OS.XK_Meta_L,          SWT.ALT},
            {OS.XK_Meta_R,          SWT.ALT},
            {OS.XK_Shift_L,         SWT.SHIFT},
            {OS.XK_Shift_R,         SWT.SHIFT},
            {OS.XK_Control_L, SWT.CONTROL},
            {OS.XK_Control_R, SWT.CONTROL},
//          {OS.XP_????,            SWT.COMMAND},
//          {OS.XP_????,            SWT.COMMAND},
            
            /* Non-Numeric Keypad Keys */
            {OS.XK_Up,              SWT.ARROW_UP},
            {OS.XK_KP_Up,           SWT.ARROW_UP},
            {OS.XK_Down,            SWT.ARROW_DOWN},
            {OS.XK_KP_Down,         SWT.ARROW_DOWN},
            {OS.XK_Left,            SWT.ARROW_LEFT},
            {OS.XK_KP_Left,         SWT.ARROW_LEFT},
            {OS.XK_Right,           SWT.ARROW_RIGHT},
            {OS.XK_KP_Right,  SWT.ARROW_RIGHT},
            {OS.XK_Page_Up,         SWT.PAGE_UP},
            {OS.XK_KP_Page_Up,      SWT.PAGE_UP},
            {OS.XK_Page_Down, SWT.PAGE_DOWN},
            {OS.XK_KP_Page_Down,SWT.PAGE_DOWN},
            {OS.XK_Home,            SWT.HOME},
            {OS.XK_KP_Home,         SWT.HOME},
            {OS.XK_End,             SWT.END},
            {OS.XK_KP_End,          SWT.END},
            {OS.XK_Insert,          SWT.INSERT},
            {OS.XK_KP_Insert, SWT.INSERT},
            
            /* Virtual and Ascii Keys */
            {OS.XK_BackSpace, SWT.BS},
            {OS.XK_Return,          SWT.CR},
            {OS.XK_Delete,          SWT.DEL},
            {OS.XK_KP_Delete, SWT.DEL},
            {OS.XK_Escape,          SWT.ESC},
            {OS.XK_Linefeed,  SWT.LF},
            {OS.XK_Tab,             SWT.TAB},
            {OS.XK_ISO_Left_Tab,SWT.TAB},
      
            /* Functions Keys */
            {OS.XK_F1,  SWT.F1},
            {OS.XK_F2,  SWT.F2},
            {OS.XK_F3,  SWT.F3},
            {OS.XK_F4,  SWT.F4},
            {OS.XK_F5,  SWT.F5},
            {OS.XK_F6,  SWT.F6},
            {OS.XK_F7,  SWT.F7},
            {OS.XK_F8,  SWT.F8},
            {OS.XK_F9,  SWT.F9},
            {OS.XK_F10, SWT.F10},
            {OS.XK_F11, SWT.F11},
            {OS.XK_F12, SWT.F12},
            {OS.XK_F13, SWT.F13},
            {OS.XK_F14, SWT.F14},
            {OS.XK_F15, SWT.F15},
            
            /* Numeric Keypad Keys */
            {OS.XK_KP_Multiply,     SWT.KEYPAD_MULTIPLY},
            {OS.XK_KP_Add,          SWT.KEYPAD_ADD},
            {OS.XK_KP_Enter,  SWT.KEYPAD_CR},
            {OS.XK_KP_Subtract,     SWT.KEYPAD_SUBTRACT},
            {OS.XK_KP_Decimal,      SWT.KEYPAD_DECIMAL},
            {OS.XK_KP_Divide, SWT.KEYPAD_DIVIDE},
            {OS.XK_KP_0,            SWT.KEYPAD_0},
            {OS.XK_KP_1,            SWT.KEYPAD_1},
            {OS.XK_KP_2,            SWT.KEYPAD_2},
            {OS.XK_KP_3,            SWT.KEYPAD_3},
            {OS.XK_KP_4,            SWT.KEYPAD_4},
            {OS.XK_KP_5,            SWT.KEYPAD_5},
            {OS.XK_KP_6,            SWT.KEYPAD_6},
            {OS.XK_KP_7,            SWT.KEYPAD_7},
            {OS.XK_KP_8,            SWT.KEYPAD_8},
            {OS.XK_KP_9,            SWT.KEYPAD_9},
            {OS.XK_KP_Equal,  SWT.KEYPAD_EQUAL},

            /* Other keys */
            {OS.XK_Caps_Lock, SWT.CAPS_LOCK},
            {OS.XK_Num_Lock,  SWT.NUM_LOCK},
            {OS.XK_Scroll_Lock,     SWT.SCROLL_LOCK},
            {OS.XK_Pause,           SWT.PAUSE},
            {OS.XK_Break,           SWT.BREAK},
            {OS.XK_Print,           SWT.PRINT_SCREEN},
            {OS.XK_Help,            SWT.HELP},

      };
      static String numLock;

      /* Multiple Displays. */
      static Display Default;
      static Display [] Displays = new Display [4];

      /* Double Click */
      int lastTime, lastButton;
      
      /* Current caret */
      Caret currentCaret;
      Callback caretCallback;
      int caretID, caretProc;

      /* Workaround for GP when disposing a display */
      static boolean DisplayDisposed;

      /* Package Name */
      static final String PACKAGE_PREFIX = "org.eclipse.swt.widgets.";
      /*
      * This code is intentionally commented.  In order
      * to support CLDC, .class cannot be used because
      * it does not compile on some Java compilers when
      * they are targeted for CLDC.
      */
//    static {
//          String name = Display.class.getName ();
//          int index = name.lastIndexOf ('.');
//          PACKAGE_PREFIX = name.substring (0, index + 1);
//    }
      
      /*
      * In order to support CLDC, .class cannot be used because
      * it does not compile on some Java compilers when they are
      * targeted for CLDC.  Use Class.forName() instead.
      */
      static final Class OS_LOCK;
      static {
            Class lock = null;
            try {
                  lock = Class.forName ("org.eclipse.swt.internal.motif.OS");
            } catch (Throwable th) {
            }
            OS_LOCK = lock;
      }
      
      /* Mouse Hover */
      Callback mouseHoverCallback;
      int mouseHoverID, mouseHoverProc;
      int mouseHoverHandle, toolTipHandle;
      
      /* Xt Translations */
      int dragTranslations;
      int arrowTranslations, tabTranslations;
      
      /* Check Expose Proc */
      Callback checkExposeCallback;
      int checkExposeProc, exposeCount, lastExpose;
      XExposeEvent xExposeEvent  = new XExposeEvent ();
      
      /* Check Resize Proc */
      Callback checkResizeCallback;
      int checkResizeProc, resizeWidth, resizeHeight, resizeCount, resizeWindow;
      XConfigureEvent xConfigureEvent = new XConfigureEvent ();
      
      /* Focus Proc */
      Callback focusCallback;
      int focusProc;

      /* Wake and Sleep */
      Callback wakeCallback;
      int wakeProc, read_fd, write_fd, inputID;
      byte [] wake_buffer = new byte [1];
      int [] timeout = new int [2];
      byte [] fd_set;
      
      /* Display Data */
      Object data;
      String [] keys;
      Object [] values;

      /*
      * TEMPORARY CODE.  Install the runnable that
      * gets the current display. This code will
      * be removed in the future.
      */
      static {
            DeviceFinder = new Runnable () {
                  public void run () {
                        Device device = getCurrent ();
                        if (device == null) {
                              device = getDefault ();
                        }
                        setDevice (device);
                  }
            };
      }

/*
* TEMPORARY CODE.
*/
static void setDevice (Device device) {
      CurrentDevice = device;
}

/**
 * Constructs a new instance of this class.
 * <p>
 * Note: The resulting display is marked as the <em>current</em>
 * display. If this is the first display which has been 
 * constructed since the application started, it is also
 * marked as the <em>default</em> display.
 * </p>
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if called from a thread that already created an existing display</li>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 *
 * @see #getCurrent
 * @see #getDefault
 * @see Widget#checkSubclass
 * @see Shell
 */
00397 public Display () {
      this (null);
}
/**
 * Constructs a new instance of this class using the parameter.
 * 
 * @param data the device data
 */
00405 public Display (DeviceData data) {
      super (checkNull (data));
}
static DeviceData checkNull (DeviceData data) {
      if (data == null) data = new DeviceData ();
      if (data.application_name == null) {
            data.application_name = APP_NAME;
      }
      if (data.application_class == null) {
            data.application_class = APP_NAME;
      }
      return data;
}
00418 protected void checkDevice () {
      if (thread == null) error (SWT.ERROR_WIDGET_DISPOSED);
      if (thread != Thread.currentThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
      if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
}
void addMouseHoverTimeOut (int handle) {
      if (mouseHoverID != 0) OS.XtRemoveTimeOut (mouseHoverID);         
      int xtContext = OS.XtDisplayToApplicationContext (xDisplay);
      mouseHoverID = OS.XtAppAddTimeOut (xtContext, 400, mouseHoverProc, handle);
      mouseHoverHandle = handle;
}
void addWidget (int handle, Widget widget) {
      if (handle == 0) return;
      if (OS.XtIsSubclass (handle, OS.shellWidgetClass ())) {
            for (int i=0; i<shellTable.length; i++) {
                  if (shellTable [i] == null) {
                        shellTable [i] = (Shell) widget;
                        return;
                  }
            }
            Shell [] newShells = new Shell [shellTable.length + GROW_SIZE / 8];
            System.arraycopy (shellTable, 0, newShells, 0, shellTable.length);
            newShells [shellTable.length] = (Shell) widget;
            shellTable = newShells;
            return;
      }
      if (freeSlot == -1) {
            int length = (freeSlot = indexTable.length) + GROW_SIZE;
            int [] newIndexTable = new int [length];
            Widget [] newWidgetTable = new Widget [length];
            System.arraycopy (indexTable, 0, newIndexTable, 0, freeSlot);
            System.arraycopy (widgetTable, 0, newWidgetTable, 0, freeSlot);
            for (int i=freeSlot; i<length-1; i++) {
                  newIndexTable [i] = i + 1;
            }
            newIndexTable [length - 1] = -1;
            indexTable = newIndexTable;
            widgetTable = newWidgetTable;
      }
      userData [1] = freeSlot + 1;
      OS.XtSetValues (handle, userData, userData.length / 2);
      int oldSlot = freeSlot;
      freeSlot = indexTable [oldSlot];
      indexTable [oldSlot] = -2;
      widgetTable [oldSlot] = widget;
}
/**
 * Adds the listener to the collection of listeners who will
 * be notifed when an event of the given type occurs anywhere
 * in a widget. When the event does occur, the listener is
 * notified by sending it the <code>handleEvent()</code> message.
 * <p>
 * Setting the type of an event to <code>SWT.None</code> from
 * within the <code>handleEvent()</code> method can be used to
 * change the event type and stop subsequent Java listeners
 * from running. Because event filters run before other listeners,
 * event filters can both block other listeners and set arbitrary
 * fields within an event. For this reason, event filters are both
 * powerful and dangerous. They should generally be avoided for
 * performance, debugging and code maintenance reasons.
 * </p>
 * 
 * @param eventType the type of event to listen for
 * @param listener the listener which should be notified when the event occurs
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see Listener
 * @see #removeFilter
 * @see #removeListener
 * 
 * @since 3.0 
 */
00497 public void addFilter (int eventType, Listener listener) {
      checkDevice ();
      if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
      if (filterTable == null) filterTable = new EventTable ();
      filterTable.hook (eventType, listener);
}
/**
 * Adds the listener to the collection of listeners who will
 * be notifed when an event of the given type occurs. When the
 * event does occur in the display, the listener is notified by
 * sending it the <code>handleEvent()</code> message.
 *
 * @param eventType the type of event to listen for
 * @param listener the listener which should be notified when the event occurs
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see Listener
 * @see #removeListener
 * 
 * @since 2.0 
 */
00525 public void addListener (int eventType, Listener listener) {
      checkDevice ();
      if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
      if (eventTable == null) eventTable = new EventTable ();
      eventTable.hook (eventType, listener);
}
void addPopup (Menu menu) {
      if (popups == null) popups = new Menu [4];
      int length = popups.length;
      for (int i=0; i<length; i++) {
            if (popups [i] == menu) return;
      }
      int index = 0;
      while (index < length) {
            if (popups [index] == null) break;
            index++;
      }
      if (index == length) {
            Menu [] newPopups = new Menu [length + 4];
            System.arraycopy (popups, 0, newPopups, 0, length);
            popups = newPopups;
      }
      popups [index] = menu;
}
/**
 * Causes the <code>run()</code> method of the runnable to
 * be invoked by the user-interface thread at the next 
 * reasonable opportunity. The caller of this method continues 
 * to run in parallel, and is not notified when the
 * runnable has completed.  Specifying <code>null</code> as the
 * runnable simply wakes the user-interface thread when run.
 * <p>
 * Note that at the time the runnable is invoked, widgets 
 * that have the receiver as their display may have been
 * disposed. Therefore, it is necessary to check for this
 * case inside the runnable before accessing the widget.
 * </p>
 *
 * @param runnable code to run on the user-interface thread or <code>null</code>
 *
 * @exception SWTException <ul>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 * 
 * @see #syncExec
 */
00571 public void asyncExec (Runnable runnable) {
      if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
      synchronizer.asyncExec (runnable);
}
/**
 * Causes the system hardware to emit a short sound
 * (if it supports this capability).
 * 
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
00584 public void beep () {
      checkDevice ();
      OS.XBell (xDisplay, 100);
      OS.XFlush (xDisplay);
}
int caretProc (int clientData, int id) {
      caretID = 0;
      if (currentCaret == null) return 0;
      if (currentCaret.blinkCaret ()) {
            int blinkRate = currentCaret.blinkRate;
            if (blinkRate == 0) return 0;
            int xtContext = OS.XtDisplayToApplicationContext (xDisplay);
            caretID = OS.XtAppAddTimeOut (xtContext, blinkRate, caretProc, 0);
      } else {
            currentCaret = null;
      }
      return 0;
}

int checkExposeProc (int display, int event, int window) {
      OS.memmove (xExposeEvent, event, XExposeEvent.sizeof);
      if (xExposeEvent.window != window) return 0;
      switch (xExposeEvent.type) {
            case OS.Expose:
            case OS.GraphicsExpose:
                  exposeCount++;
                  lastExpose = event;
                  xExposeEvent.count = 1;
                  OS.memmove (event, xExposeEvent, XExposeEvent.sizeof);
                  break;
      }
      return 0;
}
int checkResizeProc (int display, int event, int arg) {
      OS.memmove (xConfigureEvent, event, XConfigureEvent.sizeof);
      if (xConfigureEvent.window != resizeWindow) return 0;
      switch (xConfigureEvent.type) {
            case OS.ConfigureNotify:
                  int width = xConfigureEvent.width;
                  int height = xConfigureEvent.height;
                  if (width != resizeWidth || height != resizeHeight) {
                        resizeCount++;
                  }
                  break;
      }
      return 0;
}
static synchronized void checkDisplay (Thread thread, boolean multiple) {
      for (int i=0; i<Displays.length; i++) {
            if (Displays [i] != null) {
                  if (!multiple) SWT.error (SWT.ERROR_NOT_IMPLEMENTED, null, " [multiple displays]");
                  if (Displays [i].thread == thread) SWT.error (SWT.ERROR_THREAD_INVALID_ACCESS);
            }
      }
}
/**
 * Checks that this class can be subclassed.
 * <p>
 * IMPORTANT: See the comment in <code>Widget.checkSubclass()</code>.
 * </p>
 *
 * @exception SWTException <ul>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 *
 * @see Widget#checkSubclass
 */
00651 protected void checkSubclass () {
      if (!Display.isValidClass (getClass ())) {
            error (SWT.ERROR_INVALID_SUBCLASS);
      }
}
/**
 * Requests that the connection between SWT and the underlying
 * operating system be closed.
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see Device#dispose
 * 
 * @since 2.0
 */
00669 public void close () {
      checkDevice ();
      Event event = new Event ();
      sendEvent (SWT.Close, event);
      if (event.doit) dispose ();
}
String convertToLf(String text) {
      char Cr = '\r';
      char Lf = '\n';
      int length = text.length ();
      if (length == 0) return text;
      
      /* Check for an LF or CR/LF.  Assume the rest of the string 
       * is formated that way.  This will not work if the string 
       * contains mixed delimiters. */
      int i = text.indexOf (Lf, 0);
      if (i == -1 || i == 0) return text;
      if (text.charAt (i - 1) != Cr) return text;

      /* The string is formatted with CR/LF.
       * Create a new string with the LF line delimiter. */
      i = 0;
      StringBuffer result = new StringBuffer ();
      while (i < length) {
            int j = text.indexOf (Cr, i);
            if (j == -1) j = length;
            String s = text.substring (i, j);
            result.append (s);
            i = j + 2;
            result.append (Lf);
      }
      return result.toString ();
}
/**
 * Creates the device in the operating system.  If the device
 * does not have a handle, this method may do nothing depending
 * on the device.
 * <p>
 * This method is called before <code>init</code>.
 * </p>
 *
 * @param data the DeviceData which describes the receiver
 *
 * @see #init
 */
00714 protected void create (DeviceData data) {
      checkSubclass ();
      checkDisplay (thread = Thread.currentThread (), true);
      createDisplay (data);
      register (this);
      if (Default == null) Default = this;
}
void createDisplay (DeviceData data) {
      /* Create the AppContext */
      int [] argc = new int [] {0};
      int xtContext = OS.XtCreateApplicationContext ();
      OS.XtSetLanguageProc (xtContext, 0, 0);
      
      xEvent = OS.XtMalloc (XEvent.sizeof);

      /* 
      * Feature in Linux.  On some DBCS Linux platforms, the default
      * font is not be properly initialized to contain a font set.
      * This causes the IME to fail.  The fix is to set a fallback
      * resource with an appropriated font to ensure a font set is
      * found.
      */
      int ptr1 = 0, ptr2 = 0; 
      if (OS.IsLinux && OS.IsDBLocale) {
            String resource = "*fontList: -*-*-medium-r-*-*-*-120-*-*-*-*-*-*:";
            byte [] buffer = Converter.wcsToMbcs (null, resource, true);
            ptr1 = OS.XtMalloc (buffer.length);
            if (ptr1 != 0) OS.memmove (ptr1, buffer, buffer.length);
            int [] spec = new int[]{ptr1, 0};
            ptr2 = OS.XtMalloc (spec.length * 4);
            if (ptr2 != 0)OS.memmove (ptr2, spec, spec.length * 4);
            OS.XtAppSetFallbackResources(xtContext, ptr2); 
      }
      
      /* Compute the display name, application name and class */
      String display_name = null;
      String application_name = APP_NAME;
      String application_class = APP_NAME;
      if (data != null) {
            if (data.display_name != null) display_name = data.display_name;
            if (data.application_name != null) application_name = data.application_name;
            if (data.application_class != null) application_class = data.application_class;
      }
      /* Use the character encoding for the default locale */
      if (display_name != null) displayName = Converter.wcsToMbcs (null, display_name, true);
      if (application_name != null) appName = Converter.wcsToMbcs (null, application_name, true);
      if (application_class != null) appClass = Converter.wcsToMbcs (null, application_class, true);
      
      /* Create the XDisplay */
      xDisplay = OS.XtOpenDisplay (xtContext, displayName, appName, appClass, 0, 0, argc, 0);
      DisplayDisposed = false;
      
      if (ptr2 != 0) {
            OS.XtAppSetFallbackResources (xtContext, 0);
            OS.XtFree (ptr2);
      }
      if (ptr1 != 0) OS.XtFree (ptr1);
}
int createMask (int pixmap) {
      if (pixmap == 0) return 0;
      int [] unused = new int [1];  int [] width = new int [1];  int [] height = new int [1];
      OS.XGetGeometry (xDisplay, pixmap, unused, unused, unused, width, height, unused, unused);
      int mask = OS.XCreatePixmap (xDisplay, pixmap, width [0], height [0], 1);
      int gc = OS.XCreateGC (xDisplay, mask, 0, null);
      if (OS.IsSunOS) {
            OS.XSetBackground (xDisplay, gc, 0);
            OS.XSetForeground (xDisplay, gc, 1);
      }
      OS.XCopyPlane (xDisplay, pixmap, mask, gc, 0, 0, width [0], height [0], 0, 0, 1);
      OS.XFreeGC (xDisplay, gc);
      return mask;
}
int createPixmap (String name) {
      int screen  = OS.XDefaultScreenOfDisplay (xDisplay);
      int fgPixel = OS.XBlackPixel (xDisplay, OS.XDefaultScreen (xDisplay));
      int bgPixel = OS.XWhitePixel (xDisplay, OS.XDefaultScreen (xDisplay));
      byte[] buffer = Converter.wcsToMbcs (null, name, true);
      int pixmap = OS.XmGetPixmap (screen, buffer, fgPixel, bgPixel);
      if (pixmap == OS.XmUNSPECIFIED_PIXMAP) {
            buffer = Converter.wcsToMbcs (null, "default_" + name, true);
            pixmap = OS.XmGetPixmap (screen, buffer, fgPixel, bgPixel);
            if (pixmap == OS.XmUNSPECIFIED_PIXMAP) {
                  if (OS.IsSunOS) {
                        buffer = Converter.wcsToMbcs (null, "/usr/dt/share/include/bitmaps/" + name, true);
                        pixmap = OS.XmGetPixmap (screen, buffer, fgPixel, bgPixel);
                        if (pixmap == OS.XmUNSPECIFIED_PIXMAP) pixmap = 0;
                  } else {
                        pixmap = 0;
                  }
            }
      }
      return pixmap;
}
synchronized static void deregister (Display display) {
      for (int i=0; i<Displays.length; i++) {
            if (display == Displays [i]) Displays [i] = null;
      }
}
/**
 * Destroys the device in the operating system and releases
 * the device's handle.  If the device does not have a handle,
 * this method may do nothing depending on the device.
 * <p>
 * This method is called after <code>release</code>.
 * </p>
 * @see Device#dispose
 * @see #release
 */
00822 protected void destroy () {
      if (this == Default) Default = null;
      deregister (this);
      destroyDisplay ();
}
void destroyDisplay () {
      /* 
      * Bug in Motif. For some reason, XtAppCreateShell GP's when called
      * after an application context has been destroyed.   The fix is to
      * destroy the default XmDisplay associated with the X Display for
      * the application context.  The following code fragment GP's without
      * this work around:
      * 
      * OS.XtToolkitInitialize();
      * int xContext = OS.XtCreateApplicationContext();
      * int xDisplay = OS.XtOpenDisplay(xContext, null, null, null, 0, 0, new int[1], 0);
      * OS.XtAppCreateShell(null, null, OS.topLevelShellWidgetClass(), xDisplay, null, 0);
      * //OS.XtDestroyWidget (OS.XmGetXmDisplay (xDisplay));
      * OS.XtDestroyApplicationContext(xContext);
      * xContext = OS.XtCreateApplicationContext();
      * xDisplay = OS.XtOpenDisplay(xContext, null, null, null, 0, 0, new int[1], 0);
      * OS.XtAppCreateShell(null, null, OS.topLevelShellWidgetClass(), xDisplay, null, 0);   
      * OS.XtDestroyApplicationContext(xContext);
      */
      if (!OS.IsSunOS) {
            OS.XtDestroyWidget (OS.XmGetXmDisplay (xDisplay));
      }

      /*
      * Destroy AppContext (this destroys the display)
      */
      int xtContext = OS.XtDisplayToApplicationContext (xDisplay);
      OS.XtDestroyApplicationContext (xtContext);
      DisplayDisposed = true;
}
/**
 * Causes the <code>run()</code> method of the runnable to
 * be invoked by the user-interface thread just before the
 * receiver is disposed.  Specifying a <code>null</code> runnable
 * is ignored.
 *
 * @param runnable code to run at dispose time.
 * 
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
00870 public void disposeExec (Runnable runnable) {
      checkDevice ();
      if (disposeList == null) disposeList = new Runnable [4];
      for (int i=0; i<disposeList.length; i++) {
            if (disposeList [i] == null) {
                  disposeList [i] = runnable;
                  return;
            }
      }
      Runnable [] newDisposeList = new Runnable [disposeList.length + 4];
      System.arraycopy (disposeList, 0, newDisposeList, 0, disposeList.length);
      newDisposeList [disposeList.length] = runnable;
      disposeList = newDisposeList;
}
void error (int code) {
      SWT.error(code);
}
boolean filterEvent (Event event) {
      if (filterTable != null) filterTable.sendEvent (event);
      return false;
}
boolean filters (int eventType) {
      if (filterTable == null) return false;
      return filterTable.hooks (eventType);
}
boolean filterEvent (int event) {

      /* Check the event and find the widget */
      OS.memmove (keyEvent, event, XKeyEvent.sizeof);
      if (keyEvent.type != OS.KeyPress) return false;
      if (keyEvent.keycode == 0) return false;
      int xWindow = keyEvent.window;
      if (xWindow == 0) return false;
      int handle = OS.XtWindowToWidget (xDisplay, xWindow);
      if (handle == 0) return false;
      handle = OS.XmGetFocusWidget (handle);
      if (handle == 0) return false;
      Widget widget = getWidget (handle);
      if (widget == null) return false;

      /* Get the unaffected character and keysym */
      char key = 0;
      byte [] buffer = new byte [5];
      int [] keysym = new int [1];
      int oldState = keyEvent.state;
      keyEvent.state = 0;
      int length = OS.XLookupString (keyEvent, buffer, buffer.length, keysym, null);
      keyEvent.state = oldState;
      fixKey (keysym, buffer, 0);
      if (length != 0) {
            char [] result = Converter.mbcsToWcs (null, buffer);
            if (result.length != 0) key = result [0];
      }
      keysym [0] &= 0xFFFF;

      /* 
      * Bug in AIX.  If XFilterEvent() is called for every key event, accelerators
      * do not work. XFilterEvent() is needed on AIX to invoke the default button.
      * The fix is to call XFilterEvent() only for return keys. This means that an
      * accelerator that is only a return key will not work.
      */
      if (keysym [0] == OS.XK_Return || keysym [0] == OS.XK_KP_Enter) {
            /*
            * Bug in Linux. If XFilter() is called more than once for the same
            * event, it causes an infinite loop.  The fix to remember the serial
            * number and never call XFilterEvent() twice for the same event.
            */
            if (keyEvent.serial != lastSerial) {      
                  if (OS.XFilterEvent (event, OS.XtWindow (handle))) return true;
                  lastSerial = keyEvent.serial;
            }
      }

      /*
      * Bug in Solaris.  When accelerators are set more
      * than once in the same menu bar, the time it takes
      * to set the accelerator increases exponentially.
      * The fix is to implement our own accelerator table
      * on Solaris.
      */
      if (OS.IsSunOS) {
            /* Ignore modifiers. */
            switch (keysym [0]) {
                  case OS.XK_Control_L:
                  case OS.XK_Control_R:
                  case OS.XK_Alt_L:
                  case OS.XK_Alt_R:
                  case OS.XK_Meta_L:
                  case OS.XK_Meta_R:
                  case OS.XK_Shift_L:
                  case OS.XK_Shift_R: break;
                  default:
                        if (widget.translateAccelerator (key, keysym [0], keyEvent, true)) {
                              return true;
                        }
            }
      }

      /* Check for a mnemonic key */
      if (key != 0) {
            if (widget.translateMnemonic (key, keysym [0], keyEvent)) return true;
      }

      /* Check for a traversal key */
      switch (keysym [0]) {
            case OS.XK_Escape:
            case OS.XK_Tab:
            case OS.XK_KP_Enter:
            case OS.XK_Return:
            case OS.XK_Up:
            case OS.XK_Down:
            case OS.XK_Left:
            case OS.XK_Right:
            case OS.XK_Page_Up:
            case OS.XK_Page_Down:
                  /*
                  * If a traversal key has been assigned as an accelerator,
                  * allow the accelerator to run, not the traversal key.
                  */
                  if (!OS.IsSunOS) {
                        if (widget.translateAccelerator (key, keysym [0], keyEvent, true)) {
                              return true;
                        }
                  }
                  if (widget.translateTraversal (keysym [0], keyEvent)) return true;
      }

      /* Answer false because the event was not processed */
      return false;
}
/**
 * Given the operating system handle for a widget, returns
 * the instance of the <code>Widget</code> subclass which
 * represents it in the currently running application, if
 * such exists, or null if no matching widget can be found.
 * <p>
 * <b>IMPORTANT:</b> This method should not be called from
 * application code. The arguments are platform-specific.
 * </p>
 *
 * @param handle the handle for the widget
 * @return the SWT widget that the handle represents
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
01018 public Widget findWidget (int handle) {
      checkDevice ();
      return getWidget (handle);
}
/**
 * Given the operating system handle for a widget,
 * and widget-specific id, returns the instance of
 * the <code>Widget</code> subclass which represents
 * the handle/id pair in the currently running application,
 * if such exists, or null if no matching widget can be found.
 * <p>
 * <b>IMPORTANT:</b> This method should not be called from
 * application code. The arguments are platform-specific.
 * </p>
 *
 * @param handle the handle for the widget
 * @param id the id for the subwidget (usually an item)
 * @return the SWT widget that the handle/id pair represents
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 * 
 * @since 3.1
 */
01044 public Widget findWidget (int handle, int id) {
      return null;
}
boolean fixKey (int[] keysym, byte[] buffer, int state) {
      /*
      * Bug in MOTIF.  On Solaris only, XK_F11 and XK_F12 are not
      * translated correctly by XLookupString().  They are mapped
      * to SunXK_F36 and SunXK_F37 respectively.  The fix is to
      * look for these values (and others) and explicitly correct
      * them.
      */
      if (OS.IsSunOS && keysym [0] != 0) {
            switch (keysym [0]) {
                  case OS.SunXK_F36: 
                        keysym [0] = OS.XK_F11;
                        buffer [0] = 0;
                        break;
                  case OS.SunXK_F37:
                        keysym [0] = OS.XK_F12;
                        buffer [0] = 0;
                        break;
                  case OS.XK_R1: keysym [0] = OS.XK_Pause; break;
                  case OS.XK_R2: keysym [0] = OS.XK_Print; break;
                  case OS.XK_R3: keysym [0] = OS.XK_Scroll_Lock; break;
                  case OS.XK_R4: keysym [0] = OS.XK_KP_Subtract; break;
                  case OS.XK_R5: keysym [0] = OS.XK_KP_Divide; break;
                  case OS.XK_R6: keysym [0] = OS.XK_KP_Multiply; break;
                  case OS.XK_R7: keysym [0] = OS.XK_KP_Home; break;
                  case OS.XK_R9: keysym [0] = OS.XK_KP_Page_Up; break;
                  case OS.XK_R13: keysym [0] = OS.XK_KP_End; break;
                  case OS.XK_R15: keysym [0] = OS.XK_KP_Page_Down; break;
            }
            /*
            * Bug in MOTIF.  On Solaris only, there is garbage in the
            * high 16-bits for Keysyms such as XK_Down.  Since Keysyms
            * must be 16-bits to fit into a Character, mask away the
            * high 16-bits on all platforms.
            */
            keysym [0] &= 0xFFFF;
      }
      
      /*
      * Bug in Motif.  On HP-UX only, Shift+F9, Shift+F10, Shift+F11
      * and Shift+F12 are not translated correctly by XLookupString().
      * The fix is to look for these values (and others) explicitly
      * and correct them.
      */
      if (OS.IsHPUX && keysym [0] != 0) {
            switch (keysym [0]) {
                  case OS.XK_KP_F1: keysym [0] = OS.XK_F9; break;
                  case OS.XK_KP_F2: keysym [0] = OS.XK_F10; break;
                  case OS.XK_KP_F3: keysym [0] = OS.XK_F11; break;
                  case OS.XK_KP_F4: keysym [0] = OS.XK_F12; break;
                  case OS.hpXK_BackTab: keysym [0] = OS.XK_ISO_Left_Tab; break;
            }
      }
      
      /*
      * Bug in Motif.  There are some keycodes for which 
      * XLookupString() does not translate the character.
      * Some of examples are Shift+Tab and Ctrl+Space.
      */
      switch (keysym [0]) {
            case OS.XK_KP_Delete: buffer [0] = 0x7f; break;
            case OS.XK_ISO_Left_Tab: buffer [0] = '\t'; break;
            case OS.XK_space: buffer [0] = ' '; break;
      }
      
      /*
      * Feature in MOTIF. For some reason, XLookupString() fails 
      * to translate both the keysym and the character when the
      * control key is down.  For example, Ctrl+2 has the correct
      * keysym value (50) but no character value, while Ctrl+/ has
      * the keysym value (2F) but an invalid character value
      * (1F).  It seems that Motif is applying the algorithm to
      * convert a character to a control character for characters
      * that are not valid control characters.  The fix is to test
      * for 7-bit ASCII keysym values that fall outside of the
      * the valid control character range and use the keysym value
      * as the character, not the incorrect value that XLookupString()
      * returns.  Even though lower case values are not strictly
      * valid control characters, they are included in the range.
      * 
      * Some other cases include Ctrl+3..Ctr+8, Ctrl+[.
      */
      boolean isNull = false;
      int key = keysym [0];
      if ((state & OS.ControlMask) != 0) {
            if (0 <= key && key <= 0x7F) {
                  if ('a' <= key && key <= 'z') key -= 'a' - 'A';
                  if (!(64 <= key && key <= 95)) buffer [0] = (byte) key;
                  isNull = key == '@' && buffer [0] == 0;
            } else {
                  switch (keysym [0]) {
                        case OS.XK_KP_0: buffer [0] = '0'; break;
                        case OS.XK_KP_1: buffer [0] = '1'; break;
                        case OS.XK_KP_2: buffer [0] = '2'; break;
                        case OS.XK_KP_3: buffer [0] = '3'; break;
                        case OS.XK_KP_4: buffer [0] = '4'; break;
                        case OS.XK_KP_5: buffer [0] = '5'; break;
                        case OS.XK_KP_6: buffer [0] = '6'; break;
                        case OS.XK_KP_7: buffer [0] = '7'; break;
                        case OS.XK_KP_8: buffer [0] = '8'; break;
                        case OS.XK_KP_9: buffer [0] = '9'; break;
                  }
            }
      }
      return isNull;
}
int focusProc (int w, int client_data, int call_data, int continue_to_dispatch) {
      Widget widget = getWidget (client_data);
      if (widget == null) return 0;
      return widget.focusProc (w, client_data, call_data, continue_to_dispatch);
}
/**
 * Returns the currently active <code>Shell</code>, or null
 * if no shell belonging to the currently running application
 * is active.
 *
 * @return the active shell or null
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
01170 public Shell getActiveShell () {
      checkDevice ();
      int [] buffer1 = new int [1], buffer2 = new int [1];
      OS.XGetInputFocus (xDisplay, buffer1, buffer2);
      int xWindow = buffer1 [0];
      if (xWindow == 0) return null;
      int handle = OS.XtWindowToWidget (xDisplay, xWindow);
      if (handle == 0) return null;
      do {
            if (OS.XtIsSubclass (handle, OS.shellWidgetClass ())) {
                  Widget widget = getWidget (handle);
                  if (widget instanceof Shell) return (Shell) widget;
                  return null;
            }
      } while ((handle = OS.XtParent (handle)) != 0);
      return null;
}
/**
 * Returns the display which the currently running thread is
 * the user-interface thread for, or null if the currently
 * running thread is not a user-interface thread for any display.
 *
 * @return the current display
 */
01194 public static synchronized Display getCurrent () {
      return findDisplay (Thread.currentThread ());
}
/**
 * Returns the display which the given thread is the
 * user-interface thread for, or null if the given thread
 * is not a user-interface thread for any display.  Specifying
 * <code>null</code> as the thread will return <code>null</code>
 * for the display. 
 *
 * @param thread the user-interface thread
 * @return the display for the given thread
 */
01207 public static synchronized Display findDisplay (Thread thread) {
      for (int i=0; i<Displays.length; i++) {
            Display display = Displays [i];
            if (display != null && display.thread == thread) {
                  return display;
            }
      }
      return null;
}
int getCaretBlinkTime () {
//    checkDevice ();
      return blinkRate;
}
/**
 * Returns the control which the on-screen pointer is currently
 * over top of, or null if it is not currently over one of the
 * controls built by the currently running application.
 *
 * @return the control under the cursor
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
01232 public Control getCursorControl () {
      checkDevice ();
      int [] unused = new int [1], buffer = new int [1];
      int xWindow, xParent = OS.XDefaultRootWindow (xDisplay);
      do {
            if (OS.XQueryPointer (xDisplay, xParent, unused, buffer, unused, unused, unused, unused, unused) == 0) {
                  return null;
            }
            if ((xWindow = buffer [0]) != 0) xParent = xWindow;
      } while (xWindow != 0);
      int handle = OS.XtWindowToWidget (xDisplay, xParent);
      if (handle == 0) return null;
      do {
            Widget widget = getWidget (handle);
            if (widget != null && widget instanceof Control) {
                  Control control = (Control) widget;
                  if (control.isEnabled ()) return control;
            }
      } while ((handle = OS.XtParent (handle)) != 0);
      return null;
}
/**
 * Returns the location of the on-screen pointer relative
 * to the top left corner of the screen.
 *
 * @return the cursor location
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
01264 public Point getCursorLocation () {
      checkDevice ();
      int window = OS.XDefaultRootWindow (xDisplay);
      int [] rootX = new int [1], rootY = new int [1], unused = new int [1];
      OS.XQueryPointer (xDisplay, window, unused, unused, rootX, rootY, unused, unused, unused);
      return new Point (rootX [0], rootY [0]);
}
/**
 * Returns an array containing the recommended cursor sizes.
 *
 * @return the array of cursor sizes
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 * 
 * @since 3.0
 */
01283 public Point [] getCursorSizes() {
      checkDevice ();
      int xDrawable = OS.XDefaultRootWindow (xDisplay);
      int [] width_return = new int [1], height_return = new int [1];
      OS.XQueryBestCursor (xDisplay, xDrawable, 16, 16, width_return, height_return);
      Point pt = new Point (width_return [0], height_return [0]);
      OS.XQueryBestCursor (xDisplay, xDrawable, 32, 32, width_return, height_return);
      return pt.x == width_return [0] && pt.y == height_return [0] ? 
            new Point [] {pt} : new Point [] {pt, new Point (width_return [0], height_return [0])};
}
/**
 * Returns the default display. One is created (making the
 * thread that invokes this method its user-interface thread)
 * if it did not already exist.
 *
 * @return the default display
 */
01300 public static synchronized Display getDefault () {
      if (Default == null) Default = new Display ();
      return Default;
}
/**
 * Returns the application defined property of the receiver
 * with the specified name, or null if it has not been set.
 * <p>
 * Applications may have associated arbitrary objects with the
 * receiver in this fashion. If the objects stored in the
 * properties need to be notified when the display is disposed
 * of, it is the application's responsibility to provide a
 * <code>disposeExec()</code> handler which does so.
 * </p>
 *
 * @param key the name of the property
 * @return the value of the property or null if it has not been set
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the key is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #setData(String, Object)
 * @see #disposeExec(Runnable)
 */
01329 public Object getData (String key) {
      checkDevice ();
      if (key == null) error (SWT.ERROR_NULL_ARGUMENT);
      if (key.equals (SHELL_HANDLE_KEY)) {
            return new Integer(shellHandle);
      }
      if (keys == null) return null;
      for (int i=0; i<keys.length; i++) {
            if (keys [i].equals (key)) return values [i];
      }
      return null;
}
/**
 * Returns the application defined, display specific data
 * associated with the receiver, or null if it has not been
 * set. The <em>display specific data</em> is a single,
 * unnamed field that is stored with every display. 
 * <p>
 * Applications may put arbitrary objects in this field. If
 * the object stored in the display specific data needs to
 * be notified when the display is disposed of, it is the
 * application's responsibility to provide a
 * <code>disposeExec()</code> handler which does so.
 * </p>
 *
 * @return the display specific data
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #setData(Object)
 * @see #disposeExec(Runnable)
 */
01364 public Object getData () {
      checkDevice ();
      return data;
}
/**
 * Returns the button dismissal alignment, one of <code>LEFT</code> or <code>RIGHT</code>.
 * The button dismissal alignment is the ordering that should be used when positioning the
 * default dismissal button for a dialog.  For example, in a dialog that contains an OK and
 * CANCEL button, on platforms where the button dismissal alignment is <code>LEFT</code>, the
 * button ordering should be OK/CANCEL.  When button dismissal alignment is <code>RIGHT</code>,
 * the button ordering should be CANCEL/OK.
 *
 * @return the button dismissal order
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 * 
 * @since 2.1
 */
01385 public int getDismissalAlignment () {
      checkDevice ();
      return SWT.LEFT;
}
/**
 * Returns the longest duration, in milliseconds, between
 * two mouse button clicks that will be considered a
 * <em>double click</em> by the underlying operating system.
 *
 * @return the double click time
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
01401 public int getDoubleClickTime () {
      checkDevice ();
      return OS.XtGetMultiClickTime (xDisplay);
}
/**
 * Returns the control which currently has keyboard focus,
 * or null if keyboard events are not currently going to
 * any of the controls built by the currently running
 * application.
 *
 * @return the control under the cursor
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
01418 public Control getFocusControl () {
      checkDevice ();
      int [] buffer1 = new int [1], buffer2 = new int [1];
      OS.XGetInputFocus (xDisplay, buffer1, buffer2);
      int xWindow = buffer1 [0];
      if (xWindow == 0) return null;
      int handle = OS.XtWindowToWidget (xDisplay, xWindow);
      if (handle == 0) return null;
      handle = OS.XmGetFocusWidget (handle);
      if (handle == 0) return null;
      do {
            Widget widget = getWidget (handle);
            if (widget != null && widget instanceof Control) {
                  Control control = (Control) widget;
                  return control.isEnabled () ? control : null;
            }
      } while ((handle = OS.XtParent (handle)) != 0);
      return null;
}
/**
 * Returns true when the high contrast mode is enabled.
 * Otherwise, false is returned.
 * <p>
 * Note: This operation is a hint and is not supported on
 * platforms that do not have this concept.
 * </p>
 *
 * @return the high contrast mode
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 * 
 * @since 3.0
 */
01454 public boolean getHighContrast () {
      checkDevice ();
      return false;
}
/**
 * Returns the maximum allowed depth of icons on this display, in bits per pixel.
 * On some platforms, this may be different than the actual depth of the display.
 *
 * @return the maximum icon depth
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 * 
 * @see Device#getDepth
 */
01471 public int getIconDepth () {
      return getDepth ();
}
/**
 * Returns an array containing the recommended icon sizes.
 *
 * @return the array of icon sizes
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 * 
 * @see Decorations#setImages(Image[])
 * 
 * @since 3.0
 */
01488 public Point [] getIconSizes () {
      checkDevice ();
      int w = OS.XDefaultRootWindow (xDisplay);
      int [] size_list_return = new int [1];
      int [] count_return = new int [1];
      Point min, max;
      int status = OS.XGetIconSizes (xDisplay, w, size_list_return, count_return);
      if (status != 0 && count_return [0] > 0) {
            XIconSize iconSize = new XIconSize ();
            OS.memmove (iconSize, size_list_return [0], XIconSize.sizeof);
            min = new Point (iconSize.min_width, iconSize.min_height);
            max = new Point (iconSize.max_width, iconSize.max_height);
            OS.XFree (size_list_return [0]);
      } else {
            min = new Point (16, 16);
            max = new Point (32, 32);
      }
      return new Point [] {min, max};
}
int getLastEventTime () {
//    checkDevice ();
      return OS.XtLastTimestampProcessed (xDisplay);
}
int getMessageCount () {
      return synchronizer.getMessageCount ();
}
/**
 * Returns an array of monitors attached to the device.
 * 
 * @return the array of monitors
 * 
 * @since 3.0
 */
01521 public Monitor [] getMonitors () {
      checkDevice ();
      Monitor [] monitors = null;
      if (OS.IsLinux) {
            boolean result = OS.XineramaIsActive (xDisplay);
            if (result) {
                  int [] number = new int [1];
                  int ptr = OS.XineramaQueryScreens (xDisplay, number);
                  int monitorCount = number [0];
                  if (ptr != 0 && monitorCount > 0) {
                        monitors = new Monitor [monitorCount];
                        XineramaScreenInfo info = new XineramaScreenInfo ();
                        int address = ptr;
                        for (int i = 0; i < monitorCount; i++) {
                              Monitor monitor = new Monitor ();
                              OS.memmove (info, address, XineramaScreenInfo.sizeof);
                              address += XineramaScreenInfo.sizeof;
                              monitor.handle = info.screen_number;
                              monitor.x = info.x_org;
                              monitor.y = info.y_org;
                              monitor.width = info.width;
                              monitor.height = info.height;
                              monitor.clientX = monitor.x;
                              monitor.clientY = monitor.y;
                              monitor.clientWidth = monitor.width;
                              monitor.clientHeight = monitor.height;
                              monitors [i] = monitor;
                        }
                  }
                  if (ptr != 0) OS.XFree (ptr);
            }
      }
      if (monitors == null) {
            /* No multimonitor support detected, default to one monitor */
            Monitor monitor = new Monitor ();
            Rectangle bounds = getBounds ();
            monitor.x = bounds.x;
            monitor.y = bounds.y;
            monitor.width = bounds.width;
            monitor.height = bounds.height;
            monitor.clientX = monitor.x;
            monitor.clientY = monitor.y;
            monitor.clientWidth = monitor.width;
            monitor.clientHeight = monitor.height;          
            monitors = new Monitor [] { monitor };                
      }
      return monitors;
}
/**
 * Returns the primary monitor for that device.
 * 
 * @return the primary monitor
 * 
 * @since 3.0
 */
01576 public Monitor getPrimaryMonitor () {
      checkDevice ();
      Monitor monitor = null;
      if (OS.IsLinux) {
            boolean result = OS.XineramaIsActive (xDisplay);
            if (result) {
                  int[] number = new int [1];
                  /* Assume first monitor returned is the primary one */
                  int ptr = OS.XineramaQueryScreens (xDisplay, number);
                  int monitorCount = number [0];
                  if (ptr != 0 && monitorCount >= 1) {
                        monitor = new Monitor ();
                        XineramaScreenInfo info = new XineramaScreenInfo ();
                        OS.memmove (info, ptr, XineramaScreenInfo.sizeof);
                        monitor.handle = info.screen_number;
                        monitor.x = info.x_org;
                        monitor.y = info.y_org;
                        monitor.width = info.width;
                        monitor.height = info.height;
                        monitor.clientX = monitor.x;
                        monitor.clientY = monitor.y;
                        monitor.clientWidth = monitor.width;
                        monitor.clientHeight = monitor.height;
                  }
                  if (ptr != 0) OS.XFree (ptr);
            }
      }
      if (monitor == null) {
            /* No multimonitor support detected, default to one monitor */
            monitor = new Monitor ();
            Rectangle bounds = getBounds ();
            monitor.x = bounds.x;
            monitor.y = bounds.y;
            monitor.width = bounds.width;
            monitor.height = bounds.height;
            monitor.clientX = monitor.x;
            monitor.clientY = monitor.y;
            monitor.clientWidth = monitor.width;
            monitor.clientHeight = monitor.height;
      }
      return monitor;         
}
/**
 * Returns a (possibly empty) array containing all shells which have
 * not been disposed and have the receiver as their display.
 *
 * @return the receiver's shells
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
01629 public Shell [] getShells () {
      checkDevice ();
      int length = 0;
      for (int i=0; i<shellTable.length; i++) {
            if (shellTable [i] != null) length++;
      }
      int index = 0;
      Shell [] result = new Shell [length];
      for (int i=0; i<shellTable.length; i++) {
            Shell widget = shellTable [i];
            if (widget != null) result [index++] = widget;
      }
      return result;
}
/**
 * Returns the thread that has invoked <code>syncExec</code>
 * or null if no such runnable is currently being invoked by
 * the user-interface thread.
 * <p>
 * Note: If a runnable invoked by asyncExec is currently
 * running, this method will return null.
 * </p>
 *
 * @return the receiver's sync-interface thread
 * 
 * @exception SWTException <ul>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
01658 public Thread getSyncThread () {
      if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
      return synchronizer.syncThread;
}
/**
 * Returns the matching standard color for the given
 * constant, which should be one of the color constants
 * specified in class <code>SWT</code>. Any value other
 * than one of the SWT color constants which is passed
 * in will result in the color black. This color should
 * not be free'd because it was allocated by the system,
 * not the application.
 *
 * @param id the color constant
 * @return the matching color
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see SWT
 */
01681 public Color getSystemColor (int id) {
      checkDevice ();
      XColor xColor = null;
      switch (id) {
            case SWT.COLOR_INFO_FOREGROUND:           return super.getSystemColor (SWT.COLOR_BLACK);
            case SWT.COLOR_INFO_BACKGROUND:           return COLOR_INFO_BACKGROUND;
            case SWT.COLOR_TITLE_FOREGROUND:          return super.getSystemColor (SWT.COLOR_WHITE);
            case SWT.COLOR_TITLE_BACKGROUND:          return super.getSystemColor (SWT.COLOR_DARK_BLUE);
            case SWT.COLOR_TITLE_BACKGROUND_GRADIENT: return super.getSystemColor (SWT.COLOR_BLUE);
            case SWT.COLOR_TITLE_INACTIVE_FOREGROUND: return super.getSystemColor (SWT.COLOR_BLACK);
            case SWT.COLOR_TITLE_INACTIVE_BACKGROUND: return super.getSystemColor (SWT.COLOR_DARK_GRAY);
            case SWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT:    return super.getSystemColor (SWT.COLOR_GRAY);
            case SWT.COLOR_WIDGET_DARK_SHADOW:  xColor = COLOR_WIDGET_DARK_SHADOW; break;
            case SWT.COLOR_WIDGET_NORMAL_SHADOW:      xColor = COLOR_WIDGET_NORMAL_SHADOW; break;
            case SWT.COLOR_WIDGET_LIGHT_SHADOW:       xColor = COLOR_WIDGET_LIGHT_SHADOW; break;
            case SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW:   xColor = COLOR_WIDGET_HIGHLIGHT_SHADOW; break;
            case SWT.COLOR_WIDGET_BACKGROUND:   xColor = COLOR_WIDGET_BACKGROUND; break;
            case SWT.COLOR_WIDGET_FOREGROUND:   xColor = COLOR_WIDGET_FOREGROUND; break;
            case SWT.COLOR_WIDGET_BORDER:             xColor = COLOR_WIDGET_BORDER; break;
            case SWT.COLOR_LIST_FOREGROUND:     xColor = COLOR_LIST_FOREGROUND; break;
            case SWT.COLOR_LIST_BACKGROUND:     xColor = COLOR_LIST_BACKGROUND; break;
            case SWT.COLOR_LIST_SELECTION:            xColor = COLOR_LIST_SELECTION; break;
            case SWT.COLOR_LIST_SELECTION_TEXT:       xColor = COLOR_LIST_SELECTION_TEXT; break;
            default:
                  return super.getSystemColor (id);   
      }
      if (xColor == null) return super.getSystemColor (SWT.COLOR_BLACK);
      return Color.motif_new (this, xColor);
}
/**
 * Returns the matching standard platform cursor for the given
 * constant, which should be one of the cursor constants
 * specified in class <code>SWT</code>. This cursor should
 * not be free'd because it was allocated by the system,
 * not the application.  A value of <code>null</code> will
 * be returned if the supplied constant is not an swt cursor
 * constant. 
 *
 * @param id the swt cursor constant
 * @return the corresponding cursor or <code>null</code>
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see SWT#CURSOR_ARROW
 * @see SWT#CURSOR_WAIT
 * @see SWT#CURSOR_CROSS
 * @see SWT#CURSOR_APPSTARTING
 * @see SWT#CURSOR_HELP
 * @see SWT#CURSOR_SIZEALL
 * @see SWT#CURSOR_SIZENESW
 * @see SWT#CURSOR_SIZENS
 * @see SWT#CURSOR_SIZENWSE
 * @see SWT#CURSOR_SIZEWE
 * @see SWT#CURSOR_SIZEN
 * @see SWT#CURSOR_SIZES
 * @see SWT#CURSOR_SIZEE
 * @see SWT#CURSOR_SIZEW
 * @see SWT#CURSOR_SIZENE
 * @see SWT#CURSOR_SIZESE
 * @see SWT#CURSOR_SIZESW
 * @see SWT#CURSOR_SIZENW
 * @see SWT#CURSOR_UPARROW
 * @see SWT#CURSOR_IBEAM
 * @see SWT#CURSOR_NO
 * @see SWT#CURSOR_HAND
 * 
 * @since 3.0
 */
01752 public Cursor getSystemCursor (int id) {
      checkDevice ();
      if (!(0 <= id && id < cursors.length)) return null;
      if (cursors [id] == null) {
            cursors [id] = new Cursor (this, id);
      }
      return cursors [id];
}
/**
 * Returns a reasonable font for applications to use.
 * On some platforms, this will match the "default font"
 * or "system font" if such can be found.  This font
 * should not be free'd because it was allocated by the
 * system, not the application.
 * <p>
 * Typically, applications which want the default look
 * should simply not set the font on the widgets they
 * create. Widgets are always created with the correct
 * default font for the class of user-interface component
 * they represent.
 * </p>
 *
 * @return a font
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
01781 public Font getSystemFont () {
      checkDevice ();
      return defaultFont;
}
/**
 * Returns the matching standard platform image for the given
 * constant, which should be one of the icon constants
 * specified in class <code>SWT</code>. This image should
 * not be free'd because it was allocated by the system,
 * not the application.  A value of <code>null</code> will
 * be returned either if the supplied constant is not an
 * swt icon constant or if the platform does not define an
 * image that corresponds to the constant. 
 *
 * @param id the swt icon constant
 * @return the corresponding image or <code>null</code>
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see SWT#ICON_ERROR
 * @see SWT#ICON_INFORMATION
 * @see SWT#ICON_QUESTION
 * @see SWT#ICON_WARNING
 * @see SWT#ICON_WORKING
 * 
 * @since 3.0
 */
01811 public Image getSystemImage (int style) {
      checkDevice ();
      int imagePixmap = 0, maskPixmap = 0;
      switch (style) {
            case SWT.ICON_ERROR:
                  if (errorPixmap == 0) {
                        errorPixmap = createPixmap ("xm_error");
                        errorMask = createMask (errorPixmap);
                  }
                  imagePixmap = errorPixmap;
                  maskPixmap = errorMask;
                  break;
            case SWT.ICON_INFORMATION:
                  if (infoPixmap == 0) {
                        infoPixmap = createPixmap ("xm_information");
                        infoMask = createMask (infoPixmap);
                  }
                  imagePixmap = infoPixmap;
                  maskPixmap = infoMask;
                  break;
            case SWT.ICON_QUESTION:
                  if (questionPixmap == 0) {
                        questionPixmap = createPixmap ("xm_question");
                        questionMask = createMask (questionPixmap);
                  }
                  imagePixmap = questionPixmap;
                  maskPixmap = questionMask;
                  break;
            case SWT.ICON_WARNING:
                  if (warningPixmap == 0) {
                        warningPixmap = createPixmap ("xm_warning");
                        warningMask = createMask (warningPixmap);
                  }
                  imagePixmap = warningPixmap;
                  maskPixmap = warningMask;
                  break;
            case SWT.ICON_WORKING:
                  if (workingPixmap == 0) {
                        workingPixmap = createPixmap ("xm_working");
                        workingMask = createMask (workingPixmap);
                  }
                  imagePixmap = workingPixmap;
                  maskPixmap = workingMask;
                  break;
      }
      if (imagePixmap == 0) return null;
      return Image.motif_new (this, SWT.ICON, imagePixmap, maskPixmap);
}
/**
 * Returns the single instance of the system tray or null
 * when there is no system tray available for the platform.
 *
 * @return the system tray or <code>null</code>
 * 
 * @exception SWTException <ul>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @since 3.0
 */
01871 public Tray getSystemTray () {
      checkDevice ();
      return null;
}
/**
 * Returns the user-interface thread for the receiver.
 *
 * @return the receiver's user-interface thread
 * 
 * @exception SWTException <ul>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
01884 public Thread getThread () {
      if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
      return thread;
}
Widget getWidget (int handle) {
      if (handle == 0) return null;
      if (OS.XtIsSubclass (handle, OS.shellWidgetClass ())) {
            for (int i=0; i<shellTable.length; i++) {
                  Widget shell = shellTable [i];
                  if (shell != null && shell.topHandle () == handle) return shell;
            }
            return null;
      }
      userData [1] = 0;
      OS.XtGetValues (handle, userData, userData.length / 2);
      if (userData [1] == 0) return null;
      int index = userData [1] - 1;
      if (0 <= index && index < widgetTable.length) return widgetTable [index];
      return null;
}
void hideToolTip () {
      if (toolTipHandle != 0) {
            int shellHandle = OS.XtParent(toolTipHandle);
            OS.XtDestroyWidget(shellHandle);
      }
      toolTipHandle = 0;
}
/**
 * Initializes any internal resources needed by the
 * device.
 * <p>
 * This method is called after <code>create</code>.
 * </p>
 * 
 * @see #create
 */
01920 protected void init () {
      super.init ();
      initializeDisplay ();
      initializeButton ();
      initializeComposite ();
      initializeDialog ();
      initializeLabel ();
      initializeList ();
      initializeScrollBar ();
      initializeText ();
      initializeSystemColors ();
      initializeDefaults ();
      initializeTranslations ();
      initializeWidgetTable ();
      initializeNumLock ();
      initializePixmaps ();
}
void initializeButton () {

      int shellHandle, widgetHandle;
      int widgetClass = OS.topLevelShellWidgetClass ();

      /* Get the push button information */
      shellHandle = OS.XtAppCreateShell (appName, appClass, widgetClass, xDisplay, null, 0);

      /* 
      * Bug in Motif. When running on UTF-8, Motif becomes unstable and
      * GP's some time later  when a button widget is created with empty
      * text. The fix is to create the button with a non-empty string.
      */
      byte [] buffer = Converter.wcsToMbcs(null, "string", true);
      widgetHandle = OS.XmCreatePushButton (shellHandle, buffer, null, 0);
      OS.XtManageChild (widgetHandle);
      OS.XtSetMappedWhenManaged (shellHandle, false);
      OS.XtRealizeWidget (shellHandle);
      int [] argList = {
            OS.XmNforeground, 0,    /* 1 */
            OS.XmNbackground, 0,    /* 3 */
            OS.XmNshadowThickness, 0,     /* 5 */
            OS.XmNfontList, 0,            /* 7 */
      };
      OS.XtGetValues (widgetHandle, argList, argList.length / 2);
      buttonForeground = argList [1];  buttonBackground = argList [3];
      buttonShadowThickness = argList [5];
      /*
       * Feature in Motif. Querying the font list from the widget and
       * then destroying the shell (and the widget) could cause the
       * font list to be freed as well. The fix is to make a copy of
       * the font list, then to free it when the display is disposed.
       */
  
      buttonFont = Font.motif_new (this, OS.XmFontListCopy (argList [7]));
      OS.XtDestroyWidget (shellHandle);
}
void initializeComposite () {
      int widgetClass = OS.topLevelShellWidgetClass ();
      int shellHandle = OS.XtAppCreateShell (appName, appClass, widgetClass, xDisplay, null, 0);
      int scrolledHandle = OS.XmCreateMainWindow (shellHandle, null, null, 0);
      int [] argList1 = {OS.XmNorientation, OS.XmHORIZONTAL};
      int hScrollHandle = OS.XmCreateScrollBar (scrolledHandle, null, argList1, argList1.length / 2);
      OS.XtManageChild (hScrollHandle);
      int [] argList2 = {OS.XmNorientation, OS.XmVERTICAL};
      int vScrollHandle = OS.XmCreateScrollBar (scrolledHandle, null, argList2, argList2.length / 2);
      OS.XtManageChild (vScrollHandle);
      OS.XtManageChild (scrolledHandle);
      int [] argList5 = {
            OS.XmNmarginWidth, 3,
            OS.XmNmarginHeight, 3, 
      };
      int formHandle = OS.XmCreateForm (scrolledHandle, null, argList5, argList5.length / 2);
      OS.XtManageChild (formHandle);
      int [] argList6 = {
            OS.XmNmarginWidth, 0,
            OS.XmNmarginHeight, 0,
            OS.XmNresizePolicy, OS.XmRESIZE_NONE,
            OS.XmNtopAttachment, OS.XmATTACH_FORM,
            OS.XmNbottomAttachment, OS.XmATTACH_FORM,
            OS.XmNleftAttachment, OS.XmATTACH_FORM,
            OS.XmNrightAttachment, OS.XmATTACH_FORM,
      };
      int widgetHandle = OS.XmCreateDrawingArea (formHandle, null, argList6, argList6.length / 2);
      OS.XtManageChild (widgetHandle);
      OS.XmMainWindowSetAreas (scrolledHandle, 0, 0, hScrollHandle, vScrollHandle, formHandle);
      OS.XtSetMappedWhenManaged (shellHandle, false);
      int screen = OS.XDefaultScreen (xDisplay);
      OS.XtResizeWidget (shellHandle, OS.XDisplayWidth (xDisplay, screen), OS.XDisplayHeight (xDisplay, screen), 0);
      OS.XtRealizeWidget (shellHandle);
      int [] argList3 = {OS.XmNwidth, 0, OS.XmNheight, 0};
      OS.XtGetValues (scrolledHandle, argList3, argList3.length / 2);
      int [] argList8 = {OS.XmNx, 0, OS.XmNy, 0, OS.XmNwidth, 0, OS.XmNheight, 0};
      OS.XtGetValues (formHandle, argList8, argList8.length / 2);
      int [] argList4 = {
            OS.XmNx, 0,             /* 1 */
            OS.XmNy, 0,             /* 3 */
            OS.XmNwidth, 0,               /* 5 */
            OS.XmNheight, 0,        /* 7 */
            OS.XmNforeground, 0,          /* 9 */
            OS.XmNbackground, 0,          /* 11 */
            OS.XmNtopShadowColor, 0,      /* 13 */
            OS.XmNbottomShadowColor, 0,   /* 15 */
            OS.XmNborderColor, 0,         /* 17 */
      };
      OS.XtGetValues (widgetHandle, argList4, argList4.length / 2);
      scrolledInsetX = argList4 [1] + argList8 [1];
      scrolledInsetY = argList4 [3] + argList8 [3];
      scrolledMarginX = argList3 [1] - argList8 [1] - argList4 [1] - argList4 [5];
      scrolledMarginY = argList3 [3] - argList8 [3] - argList4 [3] - argList4 [7];
      compositeForeground = argList4 [9];  compositeBackground = argList4 [11];
      compositeTopShadow = argList4 [13];  compositeBottomShadow = argList4 [15];
      compositeBorder = argList4 [17];
      OS.XtDestroyWidget (shellHandle);
}
void initializeDefaults () {
      defaultFont = labelFont;
      defaultForeground = compositeForeground;
      defaultBackground = compositeBackground;
}
void initializeDialog () {
      //int shellHandle, widgetHandle;
      //int widgetClass = OS.topLevelShellWidgetClass ();
      //shellHandle = OS.XtAppCreateShell (appName, appClass, widgetClass, xDisplay, null, 0);
      //widgetHandle = OS.XmCreateDialogShell (shellHandle, null, null, 0);
      //OS.XtSetMappedWhenManaged (shellHandle, false);
      //OS.XtRealizeWidget (shellHandle);
      //int [] argList = {OS.XmNforeground, 0, OS.XmNbackground, 0};
      //OS.XtGetValues (widgetHandle, argList, argList.length / 2);
      //dialogForeground = argList [1];  dialogBackground = argList [3];
      //OS.XtDestroyWidget (shellHandle);
}
void initializeDisplay () {
      
      /* Create the callbacks */
      focusCallback = new Callback (this, "focusProc", 4);
      focusProc = focusCallback.getAddress ();
      if (focusProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
      windowCallback = new Callback (this, "windowProc", 4);
      windowProc = windowCallback.getAddress ();
      if (windowProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
      windowTimerCallback = new Callback (this, "windowTimerProc", 2);
      windowTimerProc = windowTimerCallback.getAddress ();
      if (windowTimerProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
      timerCallback = new Callback (this, "timerProc", 2);
      timerProc = timerCallback.getAddress ();
      if (timerProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
      caretCallback = new Callback (this, "caretProc", 2);
      caretProc = caretCallback.getAddress ();
      if (caretProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
      mouseHoverCallback = new Callback (this, "mouseHoverProc", 2);
      mouseHoverProc = mouseHoverCallback.getAddress ();
      if (mouseHoverProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
      checkExposeCallback = new Callback (this, "checkExposeProc", 3);
      checkExposeProc = checkExposeCallback.getAddress ();
      if (checkExposeProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
      checkResizeCallback = new Callback (this, "checkResizeProc", 3);
      checkResizeProc = checkResizeCallback.getAddress ();
      if (checkResizeProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
      wakeCallback = new Callback (this, "wakeProc", 3);
      wakeProc = wakeCallback.getAddress ();
      if (wakeProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
      
      /* Create and install the pipe used to wake up from sleep */
      int [] filedes = new int [2];
      if (OS.pipe (filedes) != 0) error (SWT.ERROR_NO_HANDLES);
      read_fd = filedes [0];
      write_fd = filedes [1];
      int xtContext = OS.XtDisplayToApplicationContext (xDisplay);
      inputID = OS.XtAppAddInput (xtContext, read_fd, OS.XtInputReadMask, wakeProc, 0);
      fd_set = new byte [OS.fd_set_sizeof ()];

      /*
      * Use dynamic Drag and Drop Protocol styles.
      * Preregistered protocol is not supported.
      */
      int xmDisplay = OS.XmGetXmDisplay (xDisplay);
      int [] args = new int [] {
            OS.XmNenableThinThickness, 1,
            OS.XmNdragInitiatorProtocolStyle, OS.XmDRAG_DYNAMIC,
            OS.XmNdragReceiverProtocolStyle, OS.XmDRAG_DYNAMIC,
      };
      OS.XtSetValues (xmDisplay, args, args.length / 2);

      /* Create the hidden Override shell parent */
      int xScreen = OS.XDefaultScreen (xDisplay);
      int widgetClass = OS.topLevelShellWidgetClass ();
      shellHandle = OS.XtAppCreateShell (appName, appClass, widgetClass, xDisplay, null, 0);
      OS.XtSetMappedWhenManaged (shellHandle, false);
      OS.XtResizeWidget (shellHandle, OS.XDisplayWidth (xDisplay, xScreen), OS.XDisplayHeight (xDisplay, xScreen), 0);
      OS.XtRealizeWidget (shellHandle);
}
void initializeLabel () {
      int shellHandle, widgetHandle;
      int widgetClass = OS.topLevelShellWidgetClass ();
      shellHandle = OS.XtAppCreateShell (appName, appClass, widgetClass, xDisplay, null, 0);
            
      /* 
      * Bug in Motif. When running on UTF-8, Motif becomes unstable and
      * GP's some time later  when a label widget is created with empty
      * text. The fix is to create the label with a non-empty string.
      */
      byte [] buffer = Converter.wcsToMbcs(null, "string", true);
      widgetHandle = OS.XmCreateLabel (shellHandle, buffer, null, 0);
      OS.XtManageChild (widgetHandle);
      OS.XtSetMappedWhenManaged (shellHandle, false);
      OS.XtRealizeWidget (shellHandle);
      int [] argList2 = {OS.XmNforeground, 0, OS.XmNbackground, 0, OS.XmNfontList, 0};
      OS.XtGetValues (widgetHandle, argList2, argList2.length / 2);
      labelForeground = argList2 [1];  labelBackground = argList2 [3]; 
      /*
       * Feature in Motif. Querying the font list from the widget and
       * then destroying the shell (and the widget) could cause the
       * font list to be freed as well. The fix is to make a copy of
       * the font list, then to free it when the display is disposed.
       */
  
      labelFont = Font.motif_new (this, OS.XmFontListCopy (argList2 [5]));
      OS.XtDestroyWidget (shellHandle);
}
void initializeList () {
      int shellHandle, widgetHandle;
      int widgetClass = OS.topLevelShellWidgetClass ();
      shellHandle = OS.XtAppCreateShell (appName, appClass, widgetClass, xDisplay, null, 0);
      widgetHandle = OS.XmCreateScrolledList (shellHandle, new byte [1], null, 0);
      OS.XtManageChild (widgetHandle);
      OS.XtSetMappedWhenManaged (shellHandle, false);
      OS.XtRealizeWidget (shellHandle);
      int [] argList = {OS.XmNforeground, 0, OS.XmNbackground, 0, OS.XmNfontList, 0, OS.XmNselectColor, 0, OS.XmNhighlightColor, 0};
      OS.XtGetValues (widgetHandle, argList, argList.length / 2);
      listForeground = argList [1];
      listBackground = argList [3];
      
      /*
       * Feature in Motif. Querying the font list from the widget and
       * then destroying the shell (and the widget) could cause the
       * font list to be freed as well. The fix is to make a copy of
       * the font list, then to free it when the display is disposed.
       */
  
      listFont = Font.motif_new (this, OS.XmFontListCopy (argList [5]));
      
      /*
      * Feature in Motif.  If the value of resource XmNselectColor is
      * XmDEFAULT_SELECT_COLOR then querying for this resource gives
      * the value of the selection color to use, which is between the
      * background and bottom shadow colors.  If the resource value
      * that is returned is XmDEFAULT_SELECT_COLOR, and not the color,
      * since there is no API to query the color, use the list foreground
      * color.
      */
      int selectColor = (byte) argList [7];
      switch (selectColor) {
            case OS.XmDEFAULT_SELECT_COLOR:
            case OS.XmREVERSED_GROUND_COLORS:
                  listSelect = listForeground;
                  break;
            case OS.XmHIGHLIGHT_COLOR:
                  listSelect = argList [9];
                  break;
            default:
                  listSelect = argList [7];     // the middle color to use
      }
      OS.XtDestroyWidget (shellHandle);
}

void initializeNumLock () {
      int numLockCode = OS.XKeysymToKeycode (xDisplay, OS.XK_Num_Lock);
      int keymapHandle = OS.XGetModifierMapping (xDisplay);
      XModifierKeymap keymap = new XModifierKeymap ();
      OS.memmove (keymap, keymapHandle, XModifierKeymap.sizeof);
      for (int i = 0; i < 8 * keymap.max_keypermod; i++) {
            byte [] keymapCode = new byte [1];
            OS.memmove (keymapCode, keymap.modifiermap + i, 1);
            if (keymapCode [0] == numLockCode) {
                  int modIndex = i / keymap.max_keypermod;
                  switch (modIndex) {
                        case OS.Mod1MapIndex: numLock = "Mod1"; break;
                        case OS.Mod2MapIndex: numLock = "Mod2"; break;
                        case OS.Mod3MapIndex: numLock = "Mod3"; break;
                        case OS.Mod4MapIndex: numLock = "Mod4"; break;
                        case OS.Mod5MapIndex: numLock = "Mod5"; break;
                        default: numLock = "Mod2";
                  }
                  break;
            }
      }
      OS.XFreeModifiermap (keymapHandle);
}
void initializePixmaps () {
      /*
      * Feature in Motif.  The system pixmaps are initially installed the first
      * time a system dialog is created, so create and destroy a system dialog
      * in order to make these pixmaps available.  
      */
      int dialog = OS.XmCreateErrorDialog (shellHandle, null, null, 0);
      OS.XtDestroyWidget (dialog);
}
void initializeScrollBar () {
      //int shellHandle, widgetHandle;
      //int widgetClass = OS.topLevelShellWidgetClass ();
      //shellHandle = OS.XtAppCreateShell (appName, appClass, widgetClass, xDisplay, null, 0);
      //widgetHandle = OS.XmCreateScrollBar (shellHandle, null, null, 0);
      //OS.XtManageChild (widgetHandle);
      //OS.XtSetMappedWhenManaged (shellHandle, false);
      //OS.XtRealizeWidget (shellHandle);
      //int [] argList = {OS.XmNforeground, 0, OS.XmNbackground, 0};
      //OS.XtGetValues (widgetHandle, argList, argList.length / 2);
      //scrollBarForeground = argList [1];  scrollBarBackground = argList [3];
      //OS.XtDestroyWidget (shellHandle);
}
void initializeSystemColors () {
      int [] argList = {OS.XmNcolormap, 0};
      OS.XtGetValues (shellHandle, argList, argList.length / 2);
      int colormap = argList [1];
      
      COLOR_WIDGET_DARK_SHADOW = new XColor();
      COLOR_WIDGET_DARK_SHADOW.pixel = compositeBottomShadow;
      OS.XQueryColor (xDisplay, colormap, COLOR_WIDGET_DARK_SHADOW);
      
      COLOR_WIDGET_NORMAL_SHADOW = new XColor();
      COLOR_WIDGET_NORMAL_SHADOW.pixel = compositeBottomShadow;
      OS.XQueryColor (xDisplay, colormap, COLOR_WIDGET_NORMAL_SHADOW);
      
      COLOR_WIDGET_LIGHT_SHADOW = new XColor();
      COLOR_WIDGET_LIGHT_SHADOW.pixel = compositeTopShadow;
      OS.XQueryColor (xDisplay, colormap, COLOR_WIDGET_LIGHT_SHADOW);
      
      COLOR_WIDGET_HIGHLIGHT_SHADOW = new XColor();
      COLOR_WIDGET_HIGHLIGHT_SHADOW.pixel = compositeTopShadow;
      OS.XQueryColor (xDisplay, colormap, COLOR_WIDGET_HIGHLIGHT_SHADOW);

      COLOR_WIDGET_FOREGROUND = new XColor();
      COLOR_WIDGET_FOREGROUND.pixel = textForeground;
      OS.XQueryColor (xDisplay, colormap, COLOR_WIDGET_FOREGROUND);
      
      COLOR_WIDGET_BACKGROUND = new XColor();
      COLOR_WIDGET_BACKGROUND.pixel = compositeBackground;
      OS.XQueryColor (xDisplay, colormap, COLOR_WIDGET_BACKGROUND);
      
      COLOR_WIDGET_BORDER = new XColor();
      COLOR_WIDGET_BORDER.pixel = compositeBorder;
      OS.XQueryColor (xDisplay, colormap, COLOR_WIDGET_BORDER);
      
      COLOR_LIST_FOREGROUND = new XColor();
      COLOR_LIST_FOREGROUND.pixel = listForeground;
      OS.XQueryColor (xDisplay, colormap, COLOR_LIST_FOREGROUND);
      
      COLOR_LIST_BACKGROUND = new XColor();
      COLOR_LIST_BACKGROUND.pixel = listBackground;
      OS.XQueryColor (xDisplay, colormap, COLOR_LIST_BACKGROUND);
      
      COLOR_LIST_SELECTION = new XColor();
      COLOR_LIST_SELECTION.pixel = listSelect;
      OS.XQueryColor (xDisplay, colormap, COLOR_LIST_SELECTION);
      
      COLOR_LIST_SELECTION_TEXT = new XColor();
      COLOR_LIST_SELECTION_TEXT.pixel = listBackground;
      OS.XQueryColor (xDisplay, colormap, COLOR_LIST_SELECTION_TEXT);
      
      COLOR_INFO_BACKGROUND = new Color (this, 0xFF, 0xFF, 0xE1);
}
void initializeText () {
      int shellHandle, widgetHandle;
      int widgetClass = OS.topLevelShellWidgetClass ();
      shellHandle = OS.XtAppCreateShell (appName, appClass, widgetClass, xDisplay, null, 0);
      widgetHandle = OS.XmCreateScrolledText (shellHandle, new byte [1], null, 0);
      OS.XtManageChild (widgetHandle);
      OS.XtSetMappedWhenManaged (shellHandle, false);
      OS.XtRealizeWidget (shellHandle);
      int [] argList = {OS.XmNforeground, 0, OS.XmNbackground, 0, OS.XmNfontList, 0, OS.XmNhighlightThickness, 0, OS.XmNblinkRate, 0};
      OS.XtGetValues (widgetHandle, argList, argList.length / 2);
      textForeground = argList [1];
      textBackground = argList [3];  
      textHighlightThickness = argList[7];
      blinkRate = argList[9];
      /*
       * Feature in Motif. Querying the font list from the widget and
       * then destroying the shell (and the widget) could cause the
       * font list to be freed as well. The fix is to make a copy of
       * the font list, then to free it when the display is disposed.
       */
  
      textFont = Font.motif_new (this, OS.XmFontListCopy (argList [5])); 
      OS.XtDestroyWidget (shellHandle);

}
void initializeTranslations () {
      byte [] buffer1 = Converter.wcsToMbcs (null, "<Key>osfUp:\n<Key>osfDown:\n<Key>osfLeft:\n<Key>osfRight:\0");
      arrowTranslations = OS.XtParseTranslationTable (buffer1);
      byte [] buffer2 = Converter.wcsToMbcs (null, "~Meta ~Alt <Key>Tab:\nShift ~Meta ~Alt <Key>Tab:\0");
      tabTranslations = OS.XtParseTranslationTable (buffer2);
      byte [] buffer3 = Converter.wcsToMbcs (null, "<Btn2Down>:\0");
      dragTranslations = OS.XtParseTranslationTable (buffer3);
}
void initializeWidgetTable () {
      userData = new int [] {OS.XmNuserData, 0};
      indexTable = new int [GROW_SIZE];
      shellTable = new Shell [GROW_SIZE / 8];
      widgetTable = new Widget [GROW_SIZE];
      for (int i=0; i<GROW_SIZE-1; i++) indexTable [i] = i + 1;
      indexTable [GROW_SIZE - 1] = -1;    
}
/**    
 * Invokes platform specific functionality to allocate a new GC handle.
 * <p>
 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
 * API for <code>Display</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 data the platform specific GC data 
 * @return the platform specific GC handle
 * 
 * @exception SWTException <ul>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 * @exception SWTError <ul>
 *    <li>ERROR_NO_HANDLES if a handle could not be obtained for gc creation</li>
 * </ul>
 */
02340 public int internal_new_GC (GCData data) {
      if (isDisposed()) SWT.error(SWT.ERROR_DEVICE_DISPOSED);
      int xDrawable = OS.XDefaultRootWindow (xDisplay);
      int xGC = OS.XCreateGC (xDisplay, xDrawable, 0, null);
      if (xGC == 0) SWT.error (SWT.ERROR_NO_HANDLES);
      OS.XSetSubwindowMode (xDisplay, xGC, OS.IncludeInferiors);
      if (data != null) {
            int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
            if ((data.style & mask) == 0) {
                  data.style |= SWT.LEFT_TO_RIGHT;
            }
            data.device = this;
            data.display = xDisplay;
            data.drawable = xDrawable;
            data.background = getSystemColor (SWT.COLOR_WHITE).handle.pixel;
            data.foreground = getSystemColor (SWT.COLOR_BLACK).handle.pixel;
            data.font = defaultFont;
            data.colormap = OS.XDefaultColormap (xDisplay, OS.XDefaultScreen (xDisplay));
      }
      return xGC;
}
/**    
 * Invokes platform specific functionality to dispose a GC handle.
 * <p>
 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
 * API for <code>Display</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 hDC the platform specific GC handle
 * @param data the platform specific GC data 
 */
02374 public void internal_dispose_GC (int gc, GCData data) {
      OS.XFreeGC(xDisplay, gc);
}
boolean isValidThread () {
      return thread == Thread.currentThread ();
}
static boolean isValidClass (Class clazz) {
      String name = clazz.getName ();
      int index = name.lastIndexOf ('.');
      return name.substring (0, index + 1).equals (PACKAGE_PREFIX);
}
/**
 * Maps a point from one coordinate system to another.
 * When the control is null, coordinates are mapped to
 * the display.
 * <p>
 * NOTE: On right-to-left platforms where the coordinate
 * systems are mirrored, special care needs to be taken
 * when mapping coordinates from one control to another
 * to ensure the result is correctly mirrored.
 * 
 * Mapping a point that is the origin of a rectangle and
 * then adding the width and height is not equivalent to
 * mapping the rectangle.  When one control is mirrored
 * and the other is not, adding the width and height to a
 * point that was mapped causes the rectangle to extend
 * in the wrong direction.  Mapping the entire rectangle
 * instead of just one point causes both the origin and
 * the corner of the rectangle to be mapped.
 * </p>
 * 
 * @param from the source <code>Control</code> or <code>null</code>
 * @param to the destination <code>Control</code> or <code>null</code>
 * @param point to be mapped 
 * @return point with mapped coordinates 
 * 
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the point is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li> 
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 * 
 * @since 2.1.2
 */
02421 public Point map (Control from, Control to, Point point) {
      checkDevice ();
      if (point == null) error (SWT.ERROR_NULL_ARGUMENT);   
      return map (from, to, point.x, point.y);
}
/**
 * Maps a point from one coordinate system to another.
 * When the control is null, coordinates are mapped to
 * the display.
 * <p>
 * NOTE: On right-to-left platforms where the coordinate
 * systems are mirrored, special care needs to be taken
 * when mapping coordinates from one control to another
 * to ensure the result is correctly mirrored.
 * 
 * Mapping a point that is the origin of a rectangle and
 * then adding the width and height is not equivalent to
 * mapping the rectangle.  When one control is mirrored
 * and the other is not, adding the width and height to a
 * point that was mapped causes the rectangle to extend
 * in the wrong direction.  Mapping the entire rectangle
 * instead of just one point causes both the origin and
 * the corner of the rectangle to be mapped.
 * </p>
 * 
 * @param from the source <code>Control</code> or <code>null</code>
 * @param to the destination <code>Control</code> or <code>null</code>
 * @param x coordinates to be mapped
 * @param y coordinates to be mapped
 * @return point with mapped coordinates
 * 
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li> 
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 * 
 * @since 2.1.2
 */
02462 public Point map (Control from, Control to, int x, int y) {
      checkDevice ();
      if (from != null && from.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
      if (to != null && to.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
      Point point = new Point (x, y);
      if (from != null) {
            short [] root_x = new short [1], root_y = new short [1];
            OS.XtTranslateCoords (from.handle, (short) x, (short) y, root_x, root_y);
            point.x = root_x [0];
            point.y = root_y [0];
      }
      if (to != null) {
            short [] root_x = new short [1], root_y = new short [1];
            OS.XtTranslateCoords (to.handle, (short) 0, (short) 0, root_x, root_y);
            point.x -= root_x [0];
            point.y -= root_y [0];
      }
      return point;
}
/**
 * Maps a point from one coordinate system to another.
 * When the control is null, coordinates are mapped to
 * the display.
 * <p>
 * NOTE: On right-to-left platforms where the coordinate
 * systems are mirrored, special care needs to be taken
 * when mapping coordinates from one control to another
 * to ensure the result is correctly mirrored.
 * 
 * Mapping a point that is the origin of a rectangle and
 * then adding the width and height is not equivalent to
 * mapping the rectangle.  When one control is mirrored
 * and the other is not, adding the width and height to a
 * point that was mapped causes the rectangle to extend
 * in the wrong direction.  Mapping the entire rectangle
 * instead of just one point causes both the origin and
 * the corner of the rectangle to be mapped.
 * </p>
 * 
 * @param from the source <code>Control</code> or <code>null</code>
 * @param to the destination <code>Control</code> or <code>null</code>
 * @param rectangle to be mapped
 * @return rectangle with mapped coordinates
 * 
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the rectangle is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li> 
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 * 
 * @since 2.1.2
 */
02517 public Rectangle map (Control from, Control to, Rectangle rectangle) {
      checkDevice();
      if (rectangle == null) error (SWT.ERROR_NULL_ARGUMENT);
      return map (from, to, rectangle.x, rectangle.y, rectangle.width, rectangle.height);
}
/**
 * Maps a point from one coordinate system to another.
 * When the control is null, coordinates are mapped to
 * the display.
 * <p>
 * NOTE: On right-to-left platforms where the coordinate
 * systems are mirrored, special care needs to be taken
 * when mapping coordinates from one control to another
 * to ensure the result is correctly mirrored.
 * 
 * Mapping a point that is the origin of a rectangle and
 * then adding the width and height is not equivalent to
 * mapping the rectangle.  When one control is mirrored
 * and the other is not, adding the width and height to a
 * point that was mapped causes the rectangle to extend
 * in the wrong direction.  Mapping the entire rectangle
 * instead of just one point causes both the origin and
 * the corner of the rectangle to be mapped.
 * </p>
 * 
 * @param from the source <code>Control</code> or <code>null</code>
 * @param to the destination <code>Control</code> or <code>null</code>
 * @param x coordinates to be mapped
 * @param y coordinates to be mapped
 * @param width coordinates to be mapped
 * @param height coordinates to be mapped
 * @return rectangle with mapped coordinates
 * 
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed</li> 
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 * 
 * @since 2.1.2
 */
02560 public Rectangle map (Control from, Control to, int x, int y, int width, int height) {
      checkDevice();
      if (from != null && from.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
      if (to != null && to.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
      Rectangle rect = new Rectangle (x, y, width, height);
      if (from != null) {
            short [] root_x = new short [1], root_y = new short [1];
            OS.XtTranslateCoords (from.handle, (short) x, (short) y, root_x, root_y);
            rect.x = root_x [0];
            rect.y = root_y [0];
      }
      if (to != null) {
            short [] root_x = new short [1], root_y = new short [1];
            OS.XtTranslateCoords (to.handle, (short) 0, (short) 0, root_x, root_y);
            rect.x -= root_x [0];
            rect.y -= root_y [0];
      }
      return rect;
}
int mouseHoverProc (int handle, int id) {
      mouseHoverID = mouseHoverHandle = 0;
      Widget widget = getWidget (handle);
      if (widget == null) return 0;
      return widget.hoverProc (id);
}
/**
 * Generate a low level system event.
 * 
 * <code>post</code> is used to generate low level keyboard
 * and mouse events. The intent is to enable automated UI
 * testing by simulating the input from the user.  Most
 * SWT applications should never need to call this method.
 * <p>
 * Note that this operation can fail when the operating system
 * fails to generate the event for any reason.  For example,
 * this can happen when there is no such key or mouse button
 * or when the system event queue is full.
 * </p>
 * <p>
 * <b>Event Types:</b>
 * <p>KeyDown, KeyUp
 * <p>The following fields in the <code>Event</code> apply:
 * <ul>
 * <li>(in) type KeyDown or KeyUp</li>
 * <p> Either one of:
 * <li>(in) character a character that corresponds to a keyboard key</li>
 * <li>(in) keyCode the key code of the key that was typed,
 *          as defined by the key code constants in class <code>SWT</code></li>
 * </ul>
 * <p>MouseDown, MouseUp</p>
 * <p>The following fields in the <code>Event</code> apply:
 * <ul>
 * <li>(in) type MouseDown or MouseUp
 * <li>(in) button the button that is pressed or released
 * </ul>
 * <p>MouseMove</p>
 * <p>The following fields in the <code>Event</code> apply:
 * <ul>
 * <li>(in) type MouseMove
 * <li>(in) x the x coordinate to move the mouse pointer to in screen coordinates
 * <li>(in) y the y coordinate to move the mouse pointer to in screen coordinates
 * </ul>
 * </dl>
 * 
 * @param event the event to be generated
 * 
 * @return true if the event was generated or false otherwise
 * 
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the event is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @since 3.0
 * 
 */
02638 public boolean post (Event event) {
      if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
      if (event == null) error (SWT.ERROR_NULL_ARGUMENT);
      int type = event.type;
      switch (type) {
            case SWT.KeyDown :
            case SWT.KeyUp : {
                  int keyCode = 0;
                  int keysym = untranslateKey (event.keyCode);
                  if (keysym != 0) keyCode = OS.XKeysymToKeycode (xDisplay, keysym);
                  if (keyCode == 0) {
                        char key = event.character;
                        switch (key) {
                              case SWT.BS: keysym = OS.XK_BackSpace; break;
                              case SWT.CR: keysym = OS.XK_Return; break;
                              case SWT.DEL: keysym = OS.XK_Delete; break;
                              case SWT.ESC: keysym = OS.XK_Escape; break;
                              case SWT.TAB: keysym = OS.XK_Tab; break;
                              case SWT.LF: keysym = OS.XK_Linefeed; break;
                              default:
                                    keysym = wcsToMbcs (key);
                        }
                        keyCode = OS.XKeysymToKeycode (xDisplay, keysym);
                        if (keyCode == 0) return false;
                  }
                  OS.XTestFakeKeyEvent (xDisplay, keyCode, type == SWT.KeyDown, 0);
                  return true;
            }
            case SWT.MouseDown :
            case SWT.MouseMove : 
            case SWT.MouseUp : {
                  if (type == SWT.MouseMove) {
                        OS.XTestFakeMotionEvent (xDisplay, -1, event.x, event.y, 0);
                        return true;
                  } else {
                        int button = event.button;
                        if (button < 1 || button > 3) return false;
                        OS.XTestFakeButtonEvent (xDisplay, button, type == SWT.MouseDown, 0);
                      return true;
                  }
            }
      }
      return false;
}
void postEvent (Event event) {
      /*
      * Place the event at the end of the event queue.
      * This code is always called in the Display's
      * thread so it must be re-enterant but does not
      * need to be synchronized.
      */
      if (eventQueue == null) eventQueue = new Event [4];
      int index = 0;
      int length = eventQueue.length;
      while (index < length) {
            if (eventQueue [index] == null) break;
            index++;
      }
      if (index == length) {
            Event [] newQueue = new Event [length + 4];
            System.arraycopy (eventQueue, 0, newQueue, 0, length);
            eventQueue = newQueue;
      }
      eventQueue [index] = event;
}
/**
 * Reads an event from the operating system's event queue,
 * dispatches it appropriately, and returns <code>true</code>
 * if there is potentially more work to do, or <code>false</code>
 * if the caller can sleep until another event is placed on
 * the event queue.
 * <p>
 * In addition to checking the system event queue, this method also
 * checks if any inter-thread messages (created by <code>syncExec()</code>
 * or <code>asyncExec()</code>) are waiting to be processed, and if
 * so handles them before returning.
 * </p>
 *
 * @return <code>false</code> if the caller can sleep upon return from this method
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_FAILED_EXEC - if an exception occurred while running an inter-thread message</li>
 * </ul>
 *
 * @see #sleep
 * @see #wake
 */
02727 public boolean readAndDispatch () {
      checkDevice ();
      boolean events = runPopups ();
      int xtContext = OS.XtDisplayToApplicationContext (xDisplay);
      int status = OS.XtAppPending (xtContext);
      if (status != 0) {
            events |= true;
            if ((status & OS.XtIMTimer) != 0) {
                  OS.XtAppProcessEvent (xtContext, OS.XtIMTimer);
                  status = OS.XtAppPending (xtContext);
            }
            if ((status & OS.XtIMAlternateInput) != 0) {
                  OS.XtAppProcessEvent (xtContext, OS.XtIMAlternateInput);
                  status = OS.XtAppPending (xtContext);
            }
            if ((status & OS.XtIMXEvent) != 0) {
                  OS.XtAppNextEvent (xtContext, xEvent);
                  if (!filterEvent (xEvent)) OS.XtDispatchEvent (xEvent);
            }
      }
      if (events) {
            runDeferredEvents ();
            return true;
      }
      return runAsyncMessages (false);
}
static synchronized void register (Display display) {
      for (int i=0; i<Displays.length; i++) {
            if (Displays [i] == null) {
                  Displays [i] = display;
                  return;
            }
      }
      Display [] newDisplays = new Display [Displays.length + 4];
      System.arraycopy (Displays, 0, newDisplays, 0, Displays.length);
      newDisplays [Displays.length] = display;
      Displays = newDisplays;
}
/**
 * Releases any internal resources back to the operating
 * system and clears all fields except the device handle.
 * <p>
 * Disposes all shells which are currently open on the display. 
 * After this method has been invoked, all related related shells
 * will answer <code>true</code> when sent the message
 * <code>isDisposed()</code>.
 * </p><p>
 * When a device is destroyed, resources that were acquired
 * on behalf of the programmer need to be returned to the
 * operating system.  For example, if the device allocated a
 * font to be used as the system font, this font would be
 * freed in <code>release</code>.  Also,to assist the garbage
 * collector and minimize the amount of memory that is not
 * reclaimed when the programmer keeps a reference to a
 * disposed device, all fields except the handle are zero'd.
 * The handle is needed by <code>destroy</code>.
 * </p>
 * This method is called before <code>destroy</code>.
 * 
 * @see Device#dispose
 * @see #destroy
 */
02789 protected void release () {
      sendEvent (SWT.Dispose, new Event ());
      Shell [] shells = getShells ();
      for (int i=0; i<shells.length; i++) {
            Shell shell = shells [i];
            if (!shell.isDisposed ()) shell.dispose ();
      }
      if (tray != null) tray.dispose ();
      tray = null;
      while (readAndDispatch ()) {}
      if (disposeList != null) {
            for (int i=0; i<disposeList.length; i++) {
                  if (disposeList [i] != null) disposeList [i].run ();
            }
      }
      disposeList = null;
      synchronizer.releaseSynchronizer ();
      synchronizer = null;
      releaseDisplay ();
      super.release ();
}
void releaseDisplay () {
      /* destroy the System Images */
      int screen = OS.XDefaultScreenOfDisplay (xDisplay);
      if (errorPixmap != 0) {
            OS.XmDestroyPixmap (screen, errorPixmap);
            OS.XFreePixmap (xDisplay, errorMask);
      }
      if (infoPixmap != 0) {
            OS.XmDestroyPixmap (screen, infoPixmap);
            OS.XFreePixmap (xDisplay, infoMask);
      }
      if (questionPixmap != 0) {
            OS.XmDestroyPixmap (screen, questionPixmap);
            OS.XFreePixmap (xDisplay, questionMask);
      }
      if (warningPixmap != 0) {
            OS.XmDestroyPixmap (screen, warningPixmap);
            OS.XFreePixmap (xDisplay, warningMask);
      }
      if (workingPixmap != 0) {
            OS.XmDestroyPixmap (screen, workingPixmap);
            OS.XFreePixmap (xDisplay, workingMask);
      }
      errorPixmap = infoPixmap = questionPixmap = warningPixmap = workingPixmap = 0;
      errorMask = infoMask = questionMask = warningMask = workingMask = 0;
      
      /* Release the System Cursors */
      for (int i = 0; i < cursors.length; i++) {
            if (cursors [i] != null) cursors [i].dispose ();
      }
      cursors = null;

      /* Destroy the hidden Override shell parent */
      if (shellHandle != 0) {
            if (!OS.IsSunOS) {
                  OS.XtDestroyWidget (shellHandle);
            }
            shellHandle = 0;
      }
      
      /* Dispose the caret callback */
      if (caretID != 0) OS.XtRemoveTimeOut (caretID);
      caretID = caretProc = 0;
      caretCallback.dispose ();
      caretCallback = null;
      
      /* Dispose the timer callback */
      if (timerIds != null) {
            for (int i=0; i<timerIds.length; i++) {
                  if (timerIds [i] != 0) OS.XtRemoveTimeOut (timerIds [i]);
            }
      }
      timerIds = null;
      timerList = null;
      timerProc = 0;
      timerCallback.dispose ();
      timerCallback = null;
      
      /* Dispose the window timer callback */
      windowTimerProc = 0;
      windowTimerCallback.dispose ();
      windowTimerCallback = null;
      
      /* Dispose the mouse hover callback */
      if (mouseHoverID != 0) OS.XtRemoveTimeOut (mouseHoverID);
      mouseHoverID = mouseHoverProc = mouseHoverHandle = toolTipHandle = 0;
      mouseHoverCallback.dispose ();
      mouseHoverCallback = null;

      /* Dispose window, expose and resize callbacks */
      windowCallback.dispose (); windowCallback = null;
      checkExposeCallback.dispose (); checkExposeCallback = null;
      checkExposeProc = 0;
      checkResizeCallback.dispose (); checkResizeCallback = null;
      checkResizeProc = 0;
      
      /* Dispose the wake callback, id and pipe */
      if (inputID != 0) OS.XtRemoveInput (inputID);
      wakeCallback.dispose (); wakeCallback = null;
      wakeProc = 0;
      OS.close (read_fd);
      OS.close (write_fd);

      focusCallback.dispose (); focusCallback = null;
      focusProc = 0;
            
      /* Free the font lists */
      if (buttonFont != null) {
            OS.XmFontListFree (buttonFont.handle);
            buttonFont.handle = 0;
      }
      if (labelFont != null) {
            OS.XmFontListFree (labelFont.handle);
            labelFont.handle = 0;
      }
      if (textFont != null) {
            OS.XmFontListFree (textFont.handle);
            textFont.handle = 0;
      }
      if (listFont != null) {
            OS.XmFontListFree (listFont.handle);
            listFont.handle = 0;
      }
      listFont = textFont = labelFont = buttonFont = null;
      defaultFont = null;     

      /* Free the translations (no documentation describes how to do this) */
      //OS.XtFree (arrowTranslations);
      //OS.XtFree (tabTranslations);
      //OS.XtFree (dragTranslations);

      if (xEvent != 0) OS.XtFree(xEvent);
      xEvent = 0;

      /* Release references */
      thread = null;
      buttonBackground = buttonForeground = 0;
      defaultBackground = defaultForeground = 0;
      COLOR_WIDGET_DARK_SHADOW = COLOR_WIDGET_NORMAL_SHADOW = COLOR_WIDGET_LIGHT_SHADOW =
      COLOR_WIDGET_HIGHLIGHT_SHADOW = COLOR_WIDGET_FOREGROUND = COLOR_WIDGET_BACKGROUND = COLOR_WIDGET_BORDER =
      COLOR_LIST_FOREGROUND = COLOR_LIST_BACKGROUND = COLOR_LIST_SELECTION = COLOR_LIST_SELECTION_TEXT = null;
      COLOR_INFO_BACKGROUND = null;

      popups = null;
}
void releaseToolTipHandle (int handle) {
      if (mouseHoverHandle == handle) removeMouseHoverTimeOut ();
      if (toolTipHandle != 0) {
            int shellHandle = OS.XtParent(toolTipHandle);
            int shellParent = OS.XtParent(shellHandle);
            if (handle == shellParent) toolTipHandle = 0;
      }
}
void removeMouseHoverTimeOut () {
      if (mouseHoverID != 0) OS.XtRemoveTimeOut (mouseHoverID);
      mouseHoverID = mouseHoverHandle = 0;
}
Widget removeWidget (int handle) {
      if (handle == 0) return null;
      if (OS.XtIsSubclass (handle, OS.shellWidgetClass ())) {
            for (int i=0; i<shellTable.length; i++) {
                  Widget shell = shellTable [i];
                  if (shell != null && shell.topHandle () == handle) {
                        shellTable [i] = null;
                        return shell;
                  }
            }
            return null;
      }
      userData [1] = 0;
      Widget widget = null;
      OS.XtGetValues (handle, userData, userData.length / 2);
      int index = userData [1] - 1;
      if (0 <= index && index < widgetTable.length) {
            widget = widgetTable [index];
            widgetTable [index] = null;
            indexTable [index] = freeSlot;
            freeSlot = index;
            userData [1] = 0;
            OS.XtSetValues (handle, userData, userData.length / 2);
      }
      return widget;
}
void removePopup (Menu menu) {
      if (popups == null) return;
      for (int i=0; i<popups.length; i++) {
            if (popups [i] == menu) {
                  popups [i] = null;
                  return;
            }
      }
}
/**
 * Removes the listener from the collection of listeners who will
 * be notifed when an event of the given type occurs anywhere in
 * a widget.
 *
 * @param eventType the type of event to listen for
 * @param listener the listener which should no longer be notified when the event occurs
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see Listener
 * @see #addFilter
 * @see #addListener
 * 
 * @since 3.0
 */
03003 public void removeFilter (int eventType, Listener listener) {
      checkDevice ();
      if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
      if (filterTable == null) return;
      filterTable.unhook (eventType, listener);
      if (filterTable.size () == 0) filterTable = null;
}
/**
 * Removes the listener from the collection of listeners who will
 * be notifed when an event of the given type occurs.
 *
 * @param eventType the type of event to listen for
 * @param listener the listener which should no longer be notified when the event occurs
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see Listener
 * @see #addListener
 * 
 * @since 2.0 
 */
03030 public void removeListener (int eventType, Listener listener) {
      checkDevice ();
      if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
      if (eventTable == null) return;
      eventTable.unhook (eventType, listener);
}
boolean runAsyncMessages (boolean all) {
      return synchronizer.runAsyncMessages (all);
}
boolean runDeferredEvents () {
      /*
      * Run deferred events.  This code is always
      * called in the Display's thread so it must
      * be re-enterant but need not be synchronized.
      */
      while (eventQueue != null) {
            
            /* Take an event off the queue */
            Event event = eventQueue [0];
            if (event == null) break;
            int length = eventQueue.length;
            System.arraycopy (eventQueue, 1, eventQueue, 0, --length);
            eventQueue [length] = null;

            /* Run the event */
            Widget widget = event.widget;
            if (widget != null && !widget.isDisposed ()) {
                  Widget item = event.item;
                  if (item == null || !item.isDisposed ()) {
                        widget.sendEvent (event);
                  }
            }

            /*
            * At this point, the event queue could
            * be null due to a recursive invokation
            * when running the event.
            */
      }

      /* Clear the queue */
      eventQueue = null;
      return true;
}
boolean runFocusOutEvents () {
      if (eventQueue == null) return false;
      Event [] focusQueue = null;
      int index = 0, count = 0, length = eventQueue.length;
      while (index < length) {
            Event event = eventQueue [index];
            if (event != null && event.type == SWT.FocusOut) {
                  if (focusQueue == null) focusQueue = new Event [length];
                  focusQueue [count++] = event;
                  System.arraycopy (eventQueue, index + 1, eventQueue, index, --length - index);
                  eventQueue [length] = null;
            } else {
                  index++;
            }
      }
      if (focusQueue == null) return false;
      for (int i=0; i<count; i++) {
            Event event = focusQueue [i];
            Widget widget = event.widget;
            if (widget != null && !widget.isDisposed ()) {
                  Widget item = event.item;
                  if (item == null || !item.isDisposed ()) {
                        widget.sendEvent (event);
                  }
            }
      }
      return true;
}
boolean runPopups () {
      if (popups == null) return false;
      boolean result = false;
      while (popups != null) {
            Menu menu = popups [0];
            if (menu == null) break;
            int length = popups.length;
            System.arraycopy (popups, 1, popups, 0, --length);
            popups [length] = null;
            runDeferredEvents ();
            menu._setVisible (true);
            result = true;
      }
      popups = null;
      return result;
}
void sendEvent (int eventType, Event event) {
      if (eventTable == null && filterTable == null) {
            return;
      }
      if (event == null) event = new Event ();
      event.display = this;
      event.type = eventType;
      if (event.time == 0) event.time = getLastEventTime ();
      if (!filterEvent (event)) {
            if (eventTable != null) eventTable.sendEvent (event);
      }
}
/**
 * Sets the location of the on-screen pointer relative to the top left corner
 * of the screen.  <b>Note: It is typically considered bad practice for a
 * program to move the on-screen pointer location.</b>
 *
 * @param x the new x coordinate for the cursor
 * @param y the new y coordinate for the cursor
 * 
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 * 
 * @since 2.1
 */
03145 public void setCursorLocation (int x, int y) {
      checkDevice ();
      int xWindow = OS.XDefaultRootWindow (xDisplay); 
      OS.XWarpPointer (xDisplay, OS.None, xWindow, 0, 0, 0, 0, x, y);
}
/**
 * Sets the location of the on-screen pointer relative to the top left corner
 * of the screen.  <b>Note: It is typically considered bad practice for a
 * program to move the on-screen pointer location.</b>
 *
 * @param point new position
 * 
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_NULL_ARGUMENT - if the point is null
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 * 
 * @since 2.0
 */
03165 public void setCursorLocation (Point point) {
      checkDevice ();
      if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
      setCursorLocation (point.x, point.y);
}
/**
 * On platforms which support it, sets the application name
 * to be the argument. On Motif, for example, this can be used
 * to set the name used for resource lookup.  Specifying
 * <code>null</code> for the name clears it.
 *
 * @param name the new app name or <code>null</code>
 */
03178 public static void setAppName (String name) {
      APP_NAME = name;
}
void setCurrentCaret (Caret caret) {
      if (caretID != 0) OS.XtRemoveTimeOut (caretID);
      caretID = 0;
      currentCaret = caret;
      if (currentCaret != null) {
            int blinkRate = currentCaret.blinkRate;
            int xtContext = OS.XtDisplayToApplicationContext (xDisplay);
            caretID = OS.XtAppAddTimeOut (xtContext, blinkRate, caretProc, 0);
      }
}
/**
 * Sets the application defined property of the receiver
 * with the specified name to the given argument.
 * <p>
 * Applications may have associated arbitrary objects with the
 * receiver in this fashion. If the objects stored in the
 * properties need to be notified when the display is disposed
 * of, it is the application's responsibility provide a
 * <code>disposeExec()</code> handler which does so.
 * </p>
 *
 * @param key the name of the property
 * @param value the new value for the property
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the key is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #getData(String)
 * @see #disposeExec(Runnable)
 */
03216 public void setData (String key, Object value) {
      checkDevice ();
      if (key == null) error (SWT.ERROR_NULL_ARGUMENT);
      
      /* Remove the key/value pair */
      if (value == null) {
            if (keys == null) return;
            int index = 0;
            while (index < keys.length && !keys [index].equals (key)) index++;
            if (index == keys.length) return;
            if (keys.length == 1) {
                  keys = null;
                  values = null;
            } else {
                  String [] newKeys = new String [keys.length - 1];
                  Object [] newValues = new Object [values.length - 1];
                  System.arraycopy (keys, 0, newKeys, 0, index);
                  System.arraycopy (keys, index + 1, newKeys, index, newKeys.length - index);
                  System.arraycopy (values, 0, newValues, 0, index);
                  System.arraycopy (values, index + 1, newValues, index, newValues.length - index);
                  keys = newKeys;
                  values = newValues;
            }
            return;
      }
      
      /* Add the key/value pair */
      if (keys == null) {
            keys = new String [] {key};
            values = new Object [] {value};
            return;
      }
      for (int i=0; i<keys.length; i++) {
            if (keys [i].equals (key)) {
                  values [i] = value;
                  return;
            }
      }
      String [] newKeys = new String [keys.length + 1];
      Object [] newValues = new Object [values.length + 1];
      System.arraycopy (keys, 0, newKeys, 0, keys.length);
      System.arraycopy (values, 0, newValues, 0, values.length);
      newKeys [keys.length] = key;
      newValues [values.length] = value;
      keys = newKeys;
      values = newValues;
}
/**
 * Sets the application defined, display specific data
 * associated with the receiver, to the argument.
 * The <em>display specific data</em> is a single,
 * unnamed field that is stored with every display. 
 * <p>
 * Applications may put arbitrary objects in this field. If
 * the object stored in the display specific data needs to
 * be notified when the display is disposed of, it is the
 * application's responsibility provide a
 * <code>disposeExec()</code> handler which does so.
 * </p>
 *
 * @param data the new display specific data
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #getData()
 * @see #disposeExec(Runnable)
 */
03286 public void setData (Object data) {
      checkDevice ();
      this.data = data;
}
/**
 * Sets the synchronizer used by the display to be
 * the argument, which can not be null.
 *
 * @param synchronizer the new synchronizer for the display (must not be null)
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the synchronizer is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_FAILED_EXEC - if an exception occurred while running an inter-thread message</li>
 * </ul>
 */
03305 public void setSynchronizer (Synchronizer synchronizer) {
      checkDevice ();
      if (synchronizer == null) error (SWT.ERROR_NULL_ARGUMENT);
      if (this.synchronizer != null) {
            this.synchronizer.runAsyncMessages(true);
      }
      this.synchronizer = synchronizer;
}
void setToolTipText (int handle, String toolTipText) {
      if (toolTipHandle == 0) return;
      int shellHandle = OS.XtParent (toolTipHandle);
      int shellParent = OS.XtParent (shellHandle);
      if (handle != shellParent) return;
      showToolTip (handle, toolTipText);
}
void showToolTip (int handle, String toolTipText) {
      int shellHandle = 0;
      /* Use the character encoding for the default locale */
      byte [] buffer = Converter.wcsToMbcs (null, toolTipText, true);
      if (toolTipHandle != 0) {
            shellHandle = OS.XtParent (toolTipHandle);
            int shellParent = OS.XtParent (shellHandle);
            if (handle != shellParent) return;
            int xmString = OS.XmStringGenerate (buffer, null, OS.XmCHARSET_TEXT, null);
            int [] argList = {OS.XmNlabelString, xmString};
            OS.XtSetValues (toolTipHandle, argList, argList.length / 2);
            if (xmString != 0) OS.XmStringFree (xmString);
      } else {
            int widgetClass = OS.overrideShellWidgetClass ();
            int [] argList1 = {
                  OS.XmNmwmDecorations, 0,
                  OS.XmNborderWidth, 1,
                  OS.XmNallowShellResize, 1,
            };
            shellHandle = OS.XtCreatePopupShell (null, widgetClass, handle, argList1, argList1.length / 2);
            Color infoForeground = getSystemColor (SWT.COLOR_INFO_FOREGROUND);
            Color infoBackground = getSystemColor (SWT.COLOR_INFO_BACKGROUND);
            int foregroundPixel = infoForeground.handle.pixel;
            int backgroundPixel = infoBackground.handle.pixel;
            int [] argList2 = {
                  OS.XmNforeground, foregroundPixel, 
                  OS.XmNbackground, backgroundPixel,
                  OS.XmNalignment, OS.XmALIGNMENT_BEGINNING,
            };
            toolTipHandle = OS.XmCreateLabel (shellHandle, buffer, argList2, argList2.length / 2);
            OS.XtManageChild (toolTipHandle);
      }
      if (toolTipText == null || toolTipText.length () == 0) {
            OS.XtPopdown (shellHandle);
      } else {
            /*
            * Feature in X.  There is no way to query the size of a cursor.
            * The fix is to use the default cursor size which is 16x16.
            */
            int xWindow = OS.XDefaultRootWindow (xDisplay);
            int [] rootX = new int [1], rootY = new int [1], unused = new int [1], mask = new int [1];
            OS.XQueryPointer (xDisplay, xWindow, unused, unused, rootX, rootY, unused, unused, mask);
            int x = rootX [0] + 16, y = rootY [0] + 16;
            
            /*
            * Ensure that the tool tip is on the screen.
            */
            int screen = OS.XDefaultScreen (xDisplay);
            int width = OS.XDisplayWidth (xDisplay, screen);
            int height = OS.XDisplayHeight (xDisplay, screen);
            int [] argList4 = {OS.XmNwidth, 0, OS.XmNheight, 0};
            OS.XtGetValues (toolTipHandle, argList4, argList4.length / 2);
            x = Math.max (0, Math.min (x, width - argList4 [1]));
            y = Math.max (0, Math.min (y, height - argList4 [3]));
            OS.XtMoveWidget (shellHandle, x, y);
            int flags = OS.Button1Mask | OS.Button2Mask | OS.Button3Mask;
            if ((mask [0] & flags) == 0) OS.XtPopup (shellHandle, OS.XtGrabNone);
      }
}
/**
 * Causes the user-interface thread to <em>sleep</em> (that is,
 * to be put in a state where it does not consume CPU cycles)
 * until an event is received or it is otherwise awakened.
 *
 * @return <code>true</code> if an event requiring dispatching was placed on the queue.
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #wake
 */
03393 public boolean sleep () {
      checkDevice ();
      if (getMessageCount () != 0) return true;
      
      /*
      * This code is intentionally commented.
      */
//    boolean result;
//    int xtContext = OS.XtDisplayToApplicationContext (xDisplay);
//    do {
//          /*
//          * Bug in Xt.  Under certain circumstances Xt waits
//          * forever looking for X events, ignoring alternate
//          * inputs.  The fix is to never sleep forever.
//          */
//          //int sleepID = OS.XtAppAddTimeOut (xtContext, 50, 0, 0);
//          result = OS.XtAppPeekEvent (xtContext, xEvent);
//          //if (sleepID != 0) OS.XtRemoveTimeOut (sleepID);
//    } while (!result && getMessageCount () == 0 && OS.XtAppPending (xtContext) == 0);
//    return result;

      /* Wait for input */
      int result, status;
      boolean workProc = true;
      int display_fd = OS.ConnectionNumber (xDisplay);
      int xtContext = OS.XtDisplayToApplicationContext (xDisplay);
      int max_fd = display_fd > read_fd ? display_fd : read_fd;
      do {
            OS.FD_ZERO (fd_set);
            OS.FD_SET (display_fd, fd_set);
            OS.FD_SET (read_fd, fd_set);
            timeout [0] = 0;
            timeout [1] = 50000;
            /* Exit the OS lock to allow other threads to enter Motif */
            Lock lock = OS.lock;
            int count = lock.lock ();
            for (int i = 0; i < count; i++) lock.unlock ();
            try {
                  result = OS.select (max_fd + 1, fd_set, null, null, timeout);
            } finally {
                  for (int i = 0; i < count; i++) lock.lock ();
                  lock.unlock ();
            }
            /*
            * Force Xt work procs that were added by native
            * widgets to run by calling XtAppProcessEvent().
            * Ensure that XtAppProcessEvent() does not block
            * by adding a time out.
            */
            status = OS.XtAppPending (xtContext);
            if (workProc && status == 0) {
                  workProc = false;
                  OS.XtAppAddTimeOut (xtContext, 1, 0, 0);
                  OS.XtAppProcessEvent (xtContext, OS.XtIMTimer);
            }
      } while (result == 0 && getMessageCount () == 0 && status == 0);
      return OS.FD_ISSET (display_fd, fd_set);
}
/**
 * Causes the <code>run()</code> method of the runnable to
 * be invoked by the user-interface thread at the next 
 * reasonable opportunity. The thread which calls this method
 * is suspended until the runnable completes.  Specifying <code>null</code>
 * as the runnable simply wakes the user-interface thread.
 * <p>
 * Note that at the time the runnable is invoked, widgets 
 * that have the receiver as their display may have been
 * disposed. Therefore, it is necessary to check for this
 * case inside the runnable before accessing the widget.
 * </p>
 * 
 * @param runnable code to run on the user-interface thread or <code>null</code>
 *
 * @exception SWTException <ul>
 *    <li>ERROR_FAILED_EXEC - if an exception occured when executing the runnable</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #asyncExec
 */
03473 public void syncExec (Runnable runnable) {
      if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
      synchronizer.syncExec (runnable);
}
int textWidth (String string, Font font) {
      if (string.length () == 0) return 0;
      int fontList = font.handle;
      String codePage = font.codePage;
      byte [] textBuffer = Converter.wcsToMbcs (codePage, string, true);
      int xmString = OS.XmStringGenerate (textBuffer, null, OS.XmCHARSET_TEXT, null);
      int width = OS.XmStringWidth (fontList, xmString);
      OS.XmStringFree (xmString);
      return width;
}
/**
 * Causes the <code>run()</code> method of the runnable to
 * be invoked by the user-interface thread after the specified
 * number of milliseconds have elapsed. If milliseconds is less
 * than zero, the runnable is not executed.
 * <p>
 * Note that at the time the runnable is invoked, widgets 
 * that have the receiver as their display may have been
 * disposed. Therefore, it is necessary to check for this
 * case inside the runnable before accessing the widget.
 * </p>
 *
 * @param milliseconds the delay before running the runnable
 * @param runnable code to run on the user-interface thread
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the runnable is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #asyncExec
 */
03512 public void timerExec (int milliseconds, Runnable runnable) {
      checkDevice ();
      if (runnable == null) error (SWT.ERROR_NULL_ARGUMENT);
      if (timerList == null) timerList = new Runnable [4];
      if (timerIds == null) timerIds = new int [4];
      int index = 0;
      while (index < timerList.length) {
            if (timerList [index] == runnable) break;
            index++;
      }
      if (index != timerList.length) {
            OS.XtRemoveTimeOut (timerIds [index]);
            timerList [index] = null;
            timerIds [index] = 0;
            if (milliseconds < 0) return;
      } else {
            if (milliseconds < 0) return;
            index = 0;
            while (index < timerList.length) {
                  if (timerList [index] == null) break;
                  index++;
            }
            if (index == timerList.length) {
                  Runnable [] newTimerList = new Runnable [timerList.length + 4];
                  System.arraycopy (timerList, 0, newTimerList, 0, timerList.length);
                  timerList = newTimerList;
                  int [] newTimerIds = new int [timerIds.length + 4];
                  System.arraycopy (timerIds, 0, newTimerIds, 0, timerIds.length);
                  timerIds = newTimerIds;
            }
      }
      int xtContext = OS.XtDisplayToApplicationContext (xDisplay);
      int timerId = OS.XtAppAddTimeOut (xtContext, milliseconds, timerProc, index);
      if (timerId != 0) {
            timerIds [index] = timerId;
            timerList [index] = runnable;
      }
}
int timerProc (int index, int id) {
      if (timerList == null) return 0;
      if (0 <= index && index < timerList.length) {
            Runnable runnable = timerList [index];
            timerList [index] = null;
            timerIds [index] = 0;
            if (runnable != null) runnable.run ();
      }
      return 0;
}
static int translateKey (int key) {
      for (int i=0; i<KeyTable.length; i++) {
            if (KeyTable [i] [0] == key) return KeyTable [i] [1];
      }
      return 0;
}
static int untranslateKey (int key) {
      for (int i=0; i<KeyTable.length; i++) {
            if (KeyTable [i] [1] == key) return KeyTable [i] [0];
      }
      return 0;
}
/**
 * Forces all outstanding paint requests for the display
 * to be processed before this method returns.
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 * 
 * @see Control#update()
 */
03583 public void update () {
      checkDevice ();
      int event = OS.XtMalloc (XEvent.sizeof);
      int mask = OS.ExposureMask | OS.ResizeRedirectMask |
            OS.StructureNotifyMask | OS.SubstructureNotifyMask |
            OS.SubstructureRedirectMask;
      OS.XSync (xDisplay, false);
      OS.XSync (xDisplay, false);
      while (OS.XCheckMaskEvent (xDisplay, mask, event)) OS.XtDispatchEvent (event);
      OS.XtFree (event);
}
/**
 * If the receiver's user-interface thread was <code>sleep</code>ing, 
 * causes it to be awakened and start running again. Note that this
 * method may be called from any thread.
 * 
 * @exception SWTException <ul>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 * 
 * @see #sleep
 */
03605 public void wake () {
      if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
      if (thread == Thread.currentThread ()) return;
      wakeThread ();
}
void wakeThread () {
      /* Write a single byte to the wake up pipe */
      while (OS.write (write_fd, wake_buffer, 1) != 1);
}
int wakeProc (int closure, int source, int id) {
      /* Read a single byte from the wake up pipe */
      while (OS.read (read_fd, wake_buffer, 1) != 1);
      return 0;
}
static int wcsToMbcs (char ch) {
      return wcsToMbcs (ch, null);
}
static int wcsToMbcs (char ch, String codePage) {
      int key = ch & 0xFFFF;
      if (key <= 0x7F) return ch;
      byte [] buffer = Converter.wcsToMbcs (codePage, new char [] {ch}, false);
      if (buffer.length == 1) return (char) buffer [0];
      if (buffer.length == 2) {
            return (char) (((buffer [0] & 0xFF) << 8) | (buffer [1] & 0xFF));
      }
      return 0;
}
int windowTimerProc (int handle, int id) {
      Widget widget = getWidget (handle);
      if (widget == null) return 0;
      return widget.timerProc (id);
}
int windowProc (int w, int client_data, int call_data, int continue_to_dispatch) {
      Widget widget = getWidget (w);
      if (widget == null) return 0;
      return widget.windowProc (w, client_data, call_data, continue_to_dispatch);
}
String wrapText (String text, Font font, int width) {
      String Lf = "\n";
      text = convertToLf (text);
      int length = text.length ();
      if (width <= 0 || length == 0 || length == 1) return text;
      StringBuffer result = new StringBuffer ();
      int lineStart = 0, lineEnd = 0;
      while (lineStart < length) {
            lineEnd = text.indexOf (Lf, lineStart);
            boolean noLf = lineEnd == -1;
            if (noLf) lineEnd = length;
            int nextStart = lineEnd + Lf.length ();
            while (lineEnd > lineStart + 1 && Compatibility.isWhitespace (text.charAt (lineEnd - 1))) {
                  lineEnd--;
            }
            int wordStart = lineStart, wordEnd = lineStart;
            int i = lineStart;
            while (i < lineEnd) {
                  int lastStart = wordStart, lastEnd = wordEnd;
                  wordStart = i;
                  while (i < lineEnd && !Compatibility.isWhitespace (text.charAt (i))) {
                        i++;
                  }
                  wordEnd = i - 1;
                  String line = text.substring (lineStart, wordEnd + 1);
                  int lineWidth = textWidth (line, font);
                  while (i < lineEnd && Compatibility.isWhitespace (text.charAt (i))) {
                        i++;
                  }
                  if (lineWidth > width) {
                        if (lastStart == wordStart) {
                              while (wordStart < wordEnd) {
                                    line = text.substring (lineStart, wordStart + 1);
                                    lineWidth = textWidth (line, font);
                                    if (lineWidth >= width) break;
                                    wordStart++;
                              }
                              if (wordStart == lastStart) wordStart++;
                              lastEnd = wordStart - 1;
                        }
                        line = text.substring (lineStart, lastEnd + 1);
                        result.append (line); result.append (Lf);
                        i = wordStart; lineStart = wordStart; wordEnd = wordStart;
                  }
            }
            if (lineStart < lineEnd) {
                  result.append (text.substring (lineStart, lineEnd));
            }
            if (!noLf) {
                  result.append (Lf);
            }
            lineStart = nextStart;
      }
      return result.toString ();
}
}

Generated by  Doxygen 1.6.0   Back to index