alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*******************************************************************************
 * Copyright (c) 2000, 2004 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.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.gtk.*;
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
 * require only a single display. In particular, some platforms
 * which SWT supports will not allow more than one <em>active
 * 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() message.
 * <p>
 * In SWT, the thread which creates a <code>Display
 * instance is distinguished as the <em>user-interface thread
 * 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 and its subclasses), may only be called
 * from the thread. (To support multi-threaded user-interface
 * applications, class <code>Display 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>Displays 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>

* 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" * SWT exception. * </p> * <dl> * <dt>Styles: * <dd>(none) * <dt>Events: * <dd>Close, Dispose * </dl> * <p> * IMPORTANT: This class is <em>not intended to be subclassed. * </p> * @see #syncExec * @see #asyncExec * @see #wake * @see #readAndDispatch * @see #sleep * @see Device#dispose */ public class Display extends Device { /** * (Warning: This field is only present on GTK) */ public int [] dispatchEvents; /* Events Dispatching and Callback */ int gdkEventCount; int /*long*/ [] gdkEvents; Widget [] gdkEventWidgets; Event [] eventQueue; Callback eventCallback; GdkEventButton gdkEvent = new GdkEventButton (); int /*long*/ eventProc, windowProc2, windowProc3, windowProc4, windowProc5; Callback windowCallback2, windowCallback3, windowCallback4, windowCallback5; EventTable eventTable, filterTable; static String APP_NAME = "SWT"; /* Widget Table */ int freeSlot; int [] indexTable; Widget [] widgetTable; final static int GROW_SIZE = 1024; static final int SWT_OBJECT_INDEX; static { byte [] buffer = Converter.wcsToMbcs (null, "SWT_OBJECT_INDEX", true); SWT_OBJECT_INDEX = OS.g_quark_from_string (buffer); } /* Input method resources */ Control imControl; int /*long*/ preeditWindow, preeditLabel; /* 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 /*long*/ timerProc; Callback windowTimerCallback; int /*long*/ windowTimerProc; /* Caret */ Caret currentCaret; Callback caretCallback; int caretId; int /*long*/ caretProc; /* Mnemonics */ Control mnemonicControl; /* Mouse hover */ int mouseHoverId; int /*long*/ mouseHoverHandle, mouseHoverProc; Callback mouseHoverCallback; /* Menu position callback */ int /*long*/ menuPositionProc; Callback menuPositionCallback; /* Shell map callback */ int /*long*/ shellMapProc; Callback shellMapCallback; /* GtkTreeView callbacks */ int[] treeSelection; int treeSelectionLength; int /*long*/ treeSelectionProc; Callback treeSelectionCallback; int /*long*/ textCellDataProc; Callback textCellDataCallback; int /*long*/ pixbufCellDataProc; Callback pixbufCellDataCallback; /* Drag Detect */ int dragStartX,dragStartY; boolean dragging; /* Fonts */ int /*long*/ defaultFont; /* System Images */ int /*long*/ errorPixmap, infoPixmap, questionPixmap, warningPixmap; int /*long*/ errorMask, infoMask, questionMask, warningMask; /* System Cursors */ Cursor [] cursors = new Cursor [SWT.CURSOR_HAND + 1]; /* Colors */ GdkColor COLOR_WIDGET_DARK_SHADOW, COLOR_WIDGET_NORMAL_SHADOW, COLOR_WIDGET_LIGHT_SHADOW; GdkColor COLOR_WIDGET_HIGHLIGHT_SHADOW, COLOR_WIDGET_BACKGROUND, COLOR_WIDGET_FOREGROUND, COLOR_WIDGET_BORDER; GdkColor COLOR_LIST_FOREGROUND, COLOR_LIST_BACKGROUND, COLOR_LIST_SELECTION, COLOR_LIST_SELECTION_TEXT; GdkColor COLOR_TEXT_FOREGROUND, COLOR_TEXT_BACKGROUND, COLOR_INFO_BACKGROUND, COLOR_INFO_FOREGROUND; GdkColor COLOR_TITLE_FOREGROUND, COLOR_TITLE_BACKGROUND, COLOR_TITLE_BACKGROUND_GRADIENT; GdkColor COLOR_TITLE_INACTIVE_FOREGROUND, COLOR_TITLE_INACTIVE_BACKGROUND, COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT; /* Popup Menus */ Menu [] popups; int popupTime; /* Key Mappings */ static final int [] [] KeyTable = { /* Keyboard and Mouse Masks */ {OS.GDK_Alt_L, SWT.ALT}, {OS.GDK_Alt_R, SWT.ALT}, {OS.GDK_Meta_L, SWT.ALT}, {OS.GDK_Meta_R, SWT.ALT}, {OS.GDK_Shift_L, SWT.SHIFT}, {OS.GDK_Shift_R, SWT.SHIFT}, {OS.GDK_Control_L, SWT.CONTROL}, {OS.GDK_Control_R, SWT.CONTROL}, // {OS.GDK_????, SWT.COMMAND}, // {OS.GDK_????, SWT.COMMAND}, /* Non-Numeric Keypad Keys */ {OS.GDK_Up, SWT.ARROW_UP}, {OS.GDK_KP_Up, SWT.ARROW_UP}, {OS.GDK_Down, SWT.ARROW_DOWN}, {OS.GDK_KP_Down, SWT.ARROW_DOWN}, {OS.GDK_Left, SWT.ARROW_LEFT}, {OS.GDK_KP_Left, SWT.ARROW_LEFT}, {OS.GDK_Right, SWT.ARROW_RIGHT}, {OS.GDK_KP_Right, SWT.ARROW_RIGHT}, {OS.GDK_Page_Up, SWT.PAGE_UP}, {OS.GDK_KP_Page_Up, SWT.PAGE_UP}, {OS.GDK_Page_Down, SWT.PAGE_DOWN}, {OS.GDK_KP_Page_Down, SWT.PAGE_DOWN}, {OS.GDK_Home, SWT.HOME}, {OS.GDK_KP_Home, SWT.HOME}, {OS.GDK_End, SWT.END}, {OS.GDK_KP_End, SWT.END}, {OS.GDK_Insert, SWT.INSERT}, {OS.GDK_KP_Insert, SWT.INSERT}, /* Virtual and Ascii Keys */ {OS.GDK_BackSpace, SWT.BS}, {OS.GDK_Return, SWT.CR}, {OS.GDK_Delete, SWT.DEL}, {OS.GDK_KP_Delete, SWT.DEL}, {OS.GDK_Escape, SWT.ESC}, {OS.GDK_Linefeed, SWT.LF}, {OS.GDK_Tab, SWT.TAB}, {OS.GDK_ISO_Left_Tab, SWT.TAB}, /* Functions Keys */ {OS.GDK_F1, SWT.F1}, {OS.GDK_F2, SWT.F2}, {OS.GDK_F3, SWT.F3}, {OS.GDK_F4, SWT.F4}, {OS.GDK_F5, SWT.F5}, {OS.GDK_F6, SWT.F6}, {OS.GDK_F7, SWT.F7}, {OS.GDK_F8, SWT.F8}, {OS.GDK_F9, SWT.F9}, {OS.GDK_F10, SWT.F10}, {OS.GDK_F11, SWT.F11}, {OS.GDK_F12, SWT.F12}, {OS.GDK_F13, SWT.F13}, {OS.GDK_F14, SWT.F14}, {OS.GDK_F15, SWT.F15}, /* Numeric Keypad Keys */ {OS.GDK_KP_Multiply, SWT.KEYPAD_MULTIPLY}, {OS.GDK_KP_Add, SWT.KEYPAD_ADD}, {OS.GDK_KP_Enter, SWT.KEYPAD_CR}, {OS.GDK_KP_Subtract, SWT.KEYPAD_SUBTRACT}, {OS.GDK_KP_Decimal, SWT.KEYPAD_DECIMAL}, {OS.GDK_KP_Divide, SWT.KEYPAD_DIVIDE}, {OS.GDK_KP_0, SWT.KEYPAD_0}, {OS.GDK_KP_1, SWT.KEYPAD_1}, {OS.GDK_KP_2, SWT.KEYPAD_2}, {OS.GDK_KP_3, SWT.KEYPAD_3}, {OS.GDK_KP_4, SWT.KEYPAD_4}, {OS.GDK_KP_5, SWT.KEYPAD_5}, {OS.GDK_KP_6, SWT.KEYPAD_6}, {OS.GDK_KP_7, SWT.KEYPAD_7}, {OS.GDK_KP_8, SWT.KEYPAD_8}, {OS.GDK_KP_9, SWT.KEYPAD_9}, {OS.GDK_KP_Equal, SWT.KEYPAD_EQUAL}, /* Other keys */ {OS.GDK_Caps_Lock, SWT.CAPS_LOCK}, {OS.GDK_Num_Lock, SWT.NUM_LOCK}, {OS.GDK_Scroll_Lock, SWT.SCROLL_LOCK}, {OS.GDK_Pause, SWT.PAUSE}, {OS.GDK_Break, SWT.BREAK}, {OS.GDK_Print, SWT.PRINT_SCREEN}, {OS.GDK_Help, SWT.HELP}, }; /* Multiple Displays. */ static Display Default; static Display [] Displays = new Display [4]; /* Package name */ static final String PACKAGE_PREFIX = "org.eclipse.swt.widgets."; /* This code is intentionally commented. * ".class" can not be used on CLDC. */ /*static { String name = Display.class.getName (); int index = name.lastIndexOf ('.'); PACKAGE_NAME = 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.gtk.OS"); } catch (Throwable th) { } OS_LOCK = lock; } /* #define in gdkevents.h */ static final int DOUBLE_CLICK_TIME = 250; /* GTK Version */ static final int MAJOR = 2; static final int MINOR = 0; static final int MICRO = 6; /* Display Data */ Object data; String [] keys; Object [] values; /* Initial Guesses for Shell Trimmings. */ int borderTrimWidth = 4, borderTrimHeight = 4; int resizeTrimWidth = 6, resizeTrimHeight = 6; int titleBorderTrimWidth = 5, titleBorderTrimHeight = 28; int titleResizeTrimWidth = 6, titleResizeTrimHeight = 29; int titleTrimWidth = 0, titleTrimHeight = 23; /* * 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 * display. If this is the first display which has been * constructed since the application started, it is also * marked as the <em>default display. * </p> * * @exception SWTException <ul> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass * </ul> * * @see #getCurrent * @see #getDefault * @see Widget#checkSubclass * @see Shell */ public Display () { this (null); } public Display (DeviceData data) { super (data); } /** * Adds the listener to the collection of listeners who will * be notifed when an event of the given type occurs anywhere * in this display. When the event does occur, the listener is * notified by sending it the <code>handleEvent() 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 * </ul> * @exception SWTException <ul> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @see Listener * @see #removeFilter * @see #removeListener * * @since 3.0 */ 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); } void addGdkEvent (int /*long*/ event) { if (gdkEvents == null) { gdkEvents = new int /*long*/ [4]; gdkEventWidgets = new Widget [4]; } if (gdkEventCount == gdkEvents.length) { int /*long*/ [] newEvents = new int /*long*/ [gdkEventCount + 4]; System.arraycopy (gdkEvents, 0, newEvents, 0, gdkEventCount); gdkEvents = newEvents; Widget [] newWidgets = new Widget [gdkEventCount + 4]; System.arraycopy (gdkEventWidgets, 0, newWidgets, 0, gdkEventCount); gdkEventWidgets = newWidgets; } Widget widget = null; int /*long*/ handle = OS.gtk_get_event_widget (event); if (handle != 0) { do { widget = getWidget (handle); } while (widget == null && (handle = OS.gtk_widget_get_parent (handle)) != 0); } gdkEvents [gdkEventCount] = event; gdkEventWidgets [gdkEventCount] = widget; gdkEventCount++; } /** * 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() 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 * </ul> * @exception SWTException <ul> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @see Listener * @see #removeListener * * @since 2.0 */ 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 addMouseHoverTimeout (int /*long*/ handle) { if (mouseHoverId != 0) OS.gtk_timeout_remove (mouseHoverId); mouseHoverId = OS.gtk_timeout_add (400, mouseHoverProc, handle); mouseHoverHandle = handle; } 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; } void addWidget (int /*long*/ handle, Widget widget) { if (handle == 0) 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; } int index = freeSlot + 1; OS.g_object_set_qdata (handle, SWT_OBJECT_INDEX, index); int oldSlot = freeSlot; freeSlot = indexTable[oldSlot]; indexTable [oldSlot] = -2; widgetTable [oldSlot] = widget; } /** * Causes the <code>run() 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. * * @param runnable code to run on the user-interface thread. * * @exception SWTException <ul> * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @see #syncExec */ 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>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> */ public void beep () { if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS); OS.gdk_beep(); OS.gdk_flush(); } 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); } static synchronized void checkDisplay (Thread thread) { for (int i=0; i<Displays.length; i++) { if (Displays [i] != null && 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(). * </p> * * @exception SWTException <ul> * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass * </ul> * * @see Widget#checkSubclass */ protected void checkSubclass () { if (!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>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @see Device#dispose * * @since 2.0 */ public void close () { checkDevice (); Event event = new Event (); sendEvent (SWT.Close, event); if (event.doit) dispose (); } /** * 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. * </p> * * @param data the DeviceData which describes the receiver * * @see #init */ protected void create (DeviceData data) { checkSubclass (); checkDisplay(thread = Thread.currentThread ()); createDisplay (data); register (); if (Default == null) Default = this; } synchronized void createDisplay (DeviceData data) { /* * This code is intentionally commented. */ // if (!OS.g_thread_supported ()) { // OS.g_thread_init (0); // OS.gdk_threads_init (); // } OS.gtk_set_locale(); if (!OS.gtk_init_check (new int /*long*/ [] {0}, null)) { SWT.error (SWT.ERROR_NO_HANDLES); } OS.gtk_widget_set_default_direction (OS.GTK_TEXT_DIR_LTR); OS.gdk_rgb_init (); int /*long*/ ptr = OS.gtk_check_version (MAJOR, MINOR, MICRO); if (ptr != 0) { int length = OS.strlen (ptr); byte [] buffer = new byte [length]; OS.memmove (buffer, ptr, length); System.out.println ("***WARNING: " + new String (Converter.mbcsToWcs (null, buffer))); System.out.println ("***WARNING: SWT requires GTK " + MAJOR+ "." + MINOR + "." + MICRO); int major = OS.gtk_major_version (), minor = OS.gtk_minor_version (), micro = OS.gtk_micro_version (); System.out.println ("***WARNING: Detected: " + major + "." + minor + "." + micro); } byte [] buffer = Converter.wcsToMbcs (null, APP_NAME, true); OS.gdk_set_program_class (buffer); byte [] flatStyle = Converter.wcsToMbcs (null, "style \"swt-flat\" { GtkToolbar::shadow-type = none } widget \"*swt-toolbar-flat*\" style : highest \"swt-flat\"", true); OS.gtk_rc_parse_string (flatStyle); /* Initialize the event callback */ eventCallback = new Callback (this, "eventProc", 2); eventProc = eventCallback.getAddress (); if (eventProc == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS); OS.gdk_event_handler_set (eventProc, 0, 0); } int /*long*/[] createImage (String name) { int /*long*/ style = OS.gtk_widget_get_default_style (); byte[] buffer = Converter.wcsToMbcs (null, name, true); int /*long*/ pixbuf = OS.gtk_icon_set_render_icon ( OS.gtk_icon_factory_lookup_default (buffer), style, OS.GTK_TEXT_DIR_NONE, OS.GTK_STATE_NORMAL, -1, 0, 0); if (pixbuf == 0) return null; int /*long*/[] pixmap_return = new int /*long*/[1]; int /*long*/[] mask_return = new int /*long*/[1]; OS.gdk_pixbuf_render_pixmap_and_mask (pixbuf, pixmap_return, mask_return, 128); OS.g_object_unref (pixbuf); return new int /*long*/[] {pixmap_return [0], mask_return [0]}; } synchronized void deregister () { for (int i=0; i<Displays.length; i++) { if (this == 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. * </p> * @see #dispose * @see #release */ protected void destroy () { if (this == Default) Default = null; deregister (); destroyDisplay (); } void destroyDisplay () { } /** * 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. * * @param thread the user-interface thread * @return the display for the given thread */ 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; } /** * Causes the <code>run() method of the runnable to * be invoked by the user-interface thread just before the * receiver is disposed. * * @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>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> */ 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; } /** * Does whatever display specific cleanup is required, and then * uses the code in <code>SWTError.error to handle the error. * * @param code the descriptive error code * * @see SWTError#error */ void error (int code) { SWT.error (code); } int /*long*/ eventProc (int /*long*/ event, int /*long*/ data) { OS.memmove (gdkEvent, event, GdkEventButton.sizeof); boolean dispatch = true; if (dispatchEvents != null) { dispatch = false; for (int i = 0; i < dispatchEvents.length; i++) { if (gdkEvent.type == dispatchEvents [i]) { dispatch = true; break; } } } if (!dispatch) { addGdkEvent (OS.gdk_event_copy (event)); return 0; } boolean forward = false; Control control = null; int /*long*/ window = 0; switch (gdkEvent.type) { case OS.GDK_ENTER_NOTIFY: case OS.GDK_LEAVE_NOTIFY: case OS.GDK_BUTTON_PRESS: case OS.GDK_2BUTTON_PRESS: case OS.GDK_3BUTTON_PRESS: case OS.GDK_BUTTON_RELEASE: case OS.GDK_MOTION_NOTIFY: { window = gdkEvent.window; int /*long*/ [] user_data = new int /*long*/ [1]; do { OS.gdk_window_get_user_data (window, user_data); int /*long*/ handle = user_data [0]; if (handle != 0) { Widget widget = getWidget (handle); if (widget != null && widget instanceof Control) { control = (Control) widget; if (control.isEnabled ()) break; forward = true; } } } while ((window = OS.gdk_window_get_parent (window)) != 0); } } Shell shell = null; GdkEventButton gdkEventButton = null; int /*long*/ oldWindow = 0; double oldX = 0, oldY = 0; if (control != null ) { if (window == 0) return 0; if (forward) { switch (gdkEvent.type) { case OS.GDK_ENTER_NOTIFY: case OS.GDK_LEAVE_NOTIFY: return 0; } gdkEventButton = new GdkEventButton (); OS.memmove (gdkEventButton, event, GdkEventButton.sizeof); oldWindow = gdkEventButton.window; oldX = gdkEventButton.x; oldY = gdkEventButton.y; int /*long*/ eventHandle = control.eventHandle (); gdkEventButton.window = OS.GTK_WIDGET_WINDOW (eventHandle); int [] origin_x = new int [1], origin_y = new int [1]; OS.gdk_window_get_origin (gdkEventButton.window, origin_x, origin_y); gdkEventButton.x = gdkEventButton.x_root - origin_x [0]; gdkEventButton.y = gdkEventButton.y_root - origin_y [0]; OS.memmove (event, gdkEventButton, GdkEventButton.sizeof); } shell = control.getShell (); if ((shell.style & SWT.ON_TOP) != 0) { OS.gtk_grab_add (shell.shellHandle); } } OS.gtk_main_do_event (event); if (dispatchEvents == null && gdkEventCount != 0) { for (int i = 0; i < gdkEventCount; i++) { if (gdkEventWidgets [i] == null || !gdkEventWidgets [i].isDisposed ()) { OS.gdk_event_put (gdkEvents [i]); OS.gdk_event_free (gdkEvents [i]); } } gdkEventCount = 0; gdkEvents = null; } if (control != null ) { if (shell != null && !shell.isDisposed () && (shell.style & SWT.ON_TOP) != 0) { OS.gtk_grab_remove (shell.shellHandle); } if (forward) { gdkEventButton.window = oldWindow; gdkEventButton.x = oldX; gdkEventButton.y = oldY; OS.memmove (event, gdkEventButton, GdkEventButton.sizeof); } } return 0; } /** * Given the operating system handle for a widget, returns * the instance of the <code>Widget subclass which * represents it in the currently running application, if * such exists, or null if no matching widget can be found. * * @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>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> */ public Widget findWidget (int /*long*/ handle) { checkDevice (); return getWidget (handle); } void flushExposes () { OS.gdk_flush (); OS.gdk_flush (); if (OS.GDK_WINDOWING_X11 ()) { GdkRectangle rect = new GdkRectangle (); XExposeEvent exposeEvent = new XExposeEvent (); int /*long*/ xDisplay = OS.GDK_DISPLAY (); int /*long*/ xEvent = OS.g_malloc (XEvent.sizeof); while (OS.XCheckMaskEvent (xDisplay, OS.ExposureMask, xEvent)) { OS.memmove (exposeEvent, xEvent, XExposeEvent.sizeof); rect.x = exposeEvent.x; rect.y = exposeEvent.y; rect.width = exposeEvent.width; rect.height = exposeEvent.height; int /*long*/ window = OS.gdk_window_lookup (exposeEvent.window); if (window != 0) OS.gdk_window_invalidate_rect (window, rect, true); } OS.g_free (xEvent); } } /** * Returns the currently active <code>Shell, 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>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> */ public Shell getActiveShell () { checkDevice (); Shell [] shells = getShells (); for (int i=0; i<shells.length; i++) { if (shells [i].hasFocus) return shells [i]; } return null; } /** * Returns a rectangle describing the receiver's size and location. * * @return the bounding rectangle * * @exception SWTException <ul> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> */ public Rectangle getBounds () { checkDevice (); return new Rectangle (0, 0, OS.gdk_screen_width (), OS.gdk_screen_height ()); } /** * 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 */ public static synchronized Display getCurrent () { Thread current = Thread.currentThread (); for (int i=0; i<Displays.length; i++) { Display display = Displays [i]; if (display != null && display.thread == current) return display; } return null; } /** * 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>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> */ public Control getCursorControl () { checkDevice(); int[] x = new int[1], y = new int[1]; int /*long*/ window = OS.gdk_window_at_pointer (x,y); if (window == 0) return null; int /*long*/ [] user_data = new int /*long*/ [1]; OS.gdk_window_get_user_data (window, user_data); int /*long*/ handle = user_data [0]; if (handle == 0) return null; do { Widget widget = getWidget (handle); if (widget != null && widget instanceof Control) { Control control = (Control) widget; if (control.getEnabled ()) return control; } } while ((handle = OS.gtk_widget_get_parent (handle)) != 0); return null; } 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); } /** * 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>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> */ public Point getCursorLocation () { checkDevice (); int [] x = new int [1], y = new int [1]; OS.gdk_window_get_pointer (0, x, y, null); return new Point (x [0], y [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>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @since 3.0 */ public Point [] getCursorSizes () { checkDevice (); return new Point [] {new Point (16, 16), new Point (32, 32)}; } /** * 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 provide a * <code>disposeExec() 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 * </ul> * @exception SWTException <ul> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @see #setData * @see #disposeExec */ public Object getData (String key) { checkDevice (); if (key == null) error (SWT.ERROR_NULL_ARGUMENT); 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 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() 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>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @see #setData * @see #disposeExec */ public Object getData () { checkDevice (); return data; } /** * Returns a point whose x coordinate is the horizontal * dots per inch of the display, and whose y coordinate * is the vertical dots per inch of the display. * * @return the horizontal and vertical DPI * * @exception SWTException <ul> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * </ul> */ public Point getDPI () { checkDevice (); int widthMM = OS.gdk_screen_width_mm (); int width = OS.gdk_screen_width (); int dpi = Compatibility.round (254 * width, widthMM * 10); return new Point (dpi, dpi); } /** * 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 */ public static synchronized Display getDefault () { if (Default == null) Default = new Display (); return Default; } static boolean isValidClass (Class clazz) { String name = clazz.getName (); int index = name.lastIndexOf ('.'); return name.substring (0, index + 1).equals (PACKAGE_PREFIX); } /** * Returns the button dismissal alignment, one of <code>LEFT or RIGHT. * 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, the * button ordering should be OK/CANCEL. When button dismissal alignment is <code>RIGHT, * 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>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @since 2.1 */ public int getDismissalAlignment () { checkDevice (); return SWT.RIGHT; } /** * Returns the longest duration, in milliseconds, between * two mouse button clicks that will be considered a * <em>double click 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>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> */ public int getDoubleClickTime () { checkDevice (); return DOUBLE_CLICK_TIME; } /** * 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>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> */ public Control getFocusControl () { checkDevice (); Shell shell = getActiveShell (); if (shell == null) return null; int /*long*/ shellHandle = shell.shellHandle; int /*long*/ handle = OS.gtk_window_get_focus (shellHandle); if (handle == 0) return null; do { Widget widget = getWidget (handle); if (widget != null && widget instanceof Control) { Control window = (Control) widget; if (window.getEnabled ()) return window; } } while ((handle = OS.gtk_widget_get_parent (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>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @since 3.0 */ public boolean getHighContrast () { checkDevice (); return false; } public int getDepth () { checkDevice (); GdkVisual visual = new GdkVisual (); OS.memmove (visual, OS.gdk_visual_get_system()); return visual.depth; } /** * Returns the maximum allowed depth of icons on this display. * 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>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> */ public int getIconDepth () { checkDevice (); 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>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @see Decorations#setImages(Image[]) * * @since 3.0 */ public Point [] getIconSizes () { checkDevice (); return new Point [] {new Point (16, 16), new Point (32, 32)}; } int getLastEventTime () { return OS.gtk_get_current_event_time (); } int getMessageCount () { return synchronizer.getMessageCount (); } /** * Returns an array of monitors attached to the device. * * @return the array of monitors * * @since 3.0 */ public Monitor [] getMonitors () { checkDevice (); Monitor [] monitors = null; int /*long*/ screen = OS.gdk_screen_get_default (); if (screen != 0) { int monitorCount = OS.gdk_screen_get_n_monitors (screen); if (monitorCount > 0) { monitors = new Monitor [monitorCount]; GdkRectangle dest = new GdkRectangle (); for (int i = 0; i < monitorCount; i++) { OS.gdk_screen_get_monitor_geometry (screen, i, dest); Monitor monitor = new Monitor (); monitor.handle = i; monitor.x = dest.x; monitor.y = dest.y; monitor.width = dest.width; monitor.height = dest.height; monitor.clientX = monitor.x; monitor.clientY = monitor.y; monitor.clientWidth = monitor.width; monitor.clientHeight = monitor.height; monitors [i] = monitor; } } } 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 */ public Monitor getPrimaryMonitor () { checkDevice (); Monitor [] monitors = getMonitors (); return monitors [0]; } /** * Returns an 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>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> */ public Shell [] getShells () { checkDevice (); int length = 0; for (int i=0; i<widgetTable.length; i++) { Widget widget = widgetTable [i]; if (widget != null && widget instanceof Shell) length++; } int index = 0; Shell [] result = new Shell [length]; for (int i=0; i<widgetTable.length; i++) { Widget widget = widgetTable [i]; if (widget != null && widget instanceof Shell) { int j = 0; while (j < index) { if (result [j] == widget) break; j++; } if (j == index) result [index++] = (Shell) widget; } } if (index == length) return result; Shell [] newResult = new Shell [index]; System.arraycopy (result, 0, newResult, 0, index); return newResult; } /** * Returns the thread that has invoked <code>syncExec * 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 * </ul> */ 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. 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>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @see SWT */ public Color getSystemColor (int id) { checkDevice (); GdkColor gdkColor = null; switch (id) { case SWT.COLOR_INFO_FOREGROUND: gdkColor = COLOR_INFO_FOREGROUND; break; case SWT.COLOR_INFO_BACKGROUND: gdkColor = COLOR_INFO_BACKGROUND; break; case SWT.COLOR_TITLE_FOREGROUND: gdkColor = COLOR_TITLE_FOREGROUND; break; case SWT.COLOR_TITLE_BACKGROUND: gdkColor = COLOR_TITLE_BACKGROUND; break; case SWT.COLOR_TITLE_BACKGROUND_GRADIENT: gdkColor = COLOR_TITLE_BACKGROUND_GRADIENT; break; case SWT.COLOR_TITLE_INACTIVE_FOREGROUND: gdkColor = COLOR_TITLE_INACTIVE_FOREGROUND; break; case SWT.COLOR_TITLE_INACTIVE_BACKGROUND: gdkColor = COLOR_TITLE_INACTIVE_BACKGROUND; break; case SWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT: gdkColor = COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT; break; case SWT.COLOR_WIDGET_DARK_SHADOW: gdkColor = COLOR_WIDGET_DARK_SHADOW; break; case SWT.COLOR_WIDGET_NORMAL_SHADOW: gdkColor = COLOR_WIDGET_NORMAL_SHADOW; break; case SWT.COLOR_WIDGET_LIGHT_SHADOW: gdkColor = COLOR_WIDGET_LIGHT_SHADOW; break; case SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW: gdkColor = COLOR_WIDGET_HIGHLIGHT_SHADOW; break; case SWT.COLOR_WIDGET_BACKGROUND: gdkColor = COLOR_WIDGET_BACKGROUND; break; case SWT.COLOR_WIDGET_FOREGROUND: gdkColor = COLOR_WIDGET_FOREGROUND; break; case SWT.COLOR_WIDGET_BORDER: gdkColor = COLOR_WIDGET_BORDER; break; case SWT.COLOR_LIST_FOREGROUND: gdkColor = COLOR_LIST_FOREGROUND; break; case SWT.COLOR_LIST_BACKGROUND: gdkColor = COLOR_LIST_BACKGROUND; break; case SWT.COLOR_LIST_SELECTION: gdkColor = COLOR_LIST_SELECTION; break; case SWT.COLOR_LIST_SELECTION_TEXT: gdkColor = COLOR_LIST_SELECTION_TEXT; break; default: return super.getSystemColor (id); } if (gdkColor == null) return super.getSystemColor (SWT.COLOR_BLACK); return Color.gtk_new (this, gdkColor); } /** * Returns the matching standard platform cursor for the given * constant, which should be one of the cursor constants * specified in class <code>SWT. This cursor should * not be free'd because it was allocated by the system, * not the application. A value of <code>null 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 * * @exception SWTException <ul> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </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 */ 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 the matching standard platform image for the given * constant, which should be one of the icon constants * specified in class <code>SWT. This image should * not be free'd because it was allocated by the system, * not the application. A value of <code>null 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 * * @exception SWTException <ul> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @see SWT#ICON_ERROR * @see SWT#ICON_INFORMATION * @see SWT#ICON_QUESTION * @see SWT#ICON_WARNING * @see SWT#ICON_WORKING * * @since 3.0 */ public Image getSystemImage (int id) { int /*long*/ imagePixmap = 0, imageMask = 0; switch (id) { case SWT.ICON_ERROR: if (errorPixmap == 0) { int /*long*/[] image = createImage ("gtk-dialog-error"); if (image != null) { errorPixmap = image [0]; errorMask = image [1]; } } imagePixmap = errorPixmap; imageMask = errorMask; break; case SWT.ICON_INFORMATION: case SWT.ICON_WORKING: if (infoPixmap == 0) { int /*long*/[] image = createImage ("gtk-dialog-info"); if (image != null) { infoPixmap = image [0]; infoMask = image [1]; } } imagePixmap = infoPixmap; imageMask = infoMask; break; case SWT.ICON_QUESTION: if (questionPixmap == 0) { int /*long*/[] image = createImage ("gtk-dialog-question"); if (image != null) { questionPixmap = image [0]; questionMask = image [1]; } } imagePixmap = questionPixmap; imageMask = questionMask; break; case SWT.ICON_WARNING: if (warningPixmap == 0) { int /*long*/[] image = createImage ("gtk-dialog-warning"); if (image != null) { warningPixmap = image [0]; warningMask = image [1]; } } imagePixmap = warningPixmap; imageMask = warningMask; break; } if (imagePixmap == 0) return null; return Image.gtk_new (this, SWT.ICON, imagePixmap, imageMask); } void initializeSystemResources () { int /*long*/ shellHandle = OS.gtk_window_new (OS.GTK_WINDOW_TOPLEVEL); if (shellHandle == 0) SWT.error (SWT.ERROR_NO_HANDLES); OS.gtk_widget_realize (shellHandle); int /*long*/ tooltipShellHandle = OS.gtk_window_new (OS.GTK_WINDOW_POPUP); if (tooltipShellHandle == 0) SWT.error (SWT.ERROR_NO_HANDLES); byte[] gtk_tooltips = Converter.wcsToMbcs (null, "gtk-tooltips", true); OS.gtk_widget_set_name (tooltipShellHandle, gtk_tooltips); OS.gtk_widget_realize (tooltipShellHandle); GdkColor gdkColor; int /*long*/ style = OS.gtk_widget_get_style (shellHandle); int /*long*/ tooltipStyle = OS.gtk_widget_get_style (tooltipShellHandle); defaultFont = OS.pango_font_description_copy (OS.gtk_style_get_font_desc (style)); gdkColor = new GdkColor(); OS.gtk_style_get_black (style, gdkColor); COLOR_WIDGET_DARK_SHADOW = gdkColor; gdkColor = new GdkColor(); OS.gtk_style_get_dark (style, OS.GTK_STATE_NORMAL, gdkColor); COLOR_WIDGET_NORMAL_SHADOW = gdkColor; gdkColor = new GdkColor(); OS.gtk_style_get_bg (style, OS.GTK_STATE_NORMAL, gdkColor); COLOR_WIDGET_LIGHT_SHADOW = gdkColor; gdkColor = new GdkColor(); OS.gtk_style_get_light (style, OS.GTK_STATE_NORMAL, gdkColor); COLOR_WIDGET_HIGHLIGHT_SHADOW = gdkColor; gdkColor = new GdkColor(); OS.gtk_style_get_fg (style, OS.GTK_STATE_NORMAL, gdkColor); COLOR_WIDGET_FOREGROUND = gdkColor; gdkColor = new GdkColor(); OS.gtk_style_get_bg (style, OS.GTK_STATE_NORMAL, gdkColor); COLOR_WIDGET_BACKGROUND = gdkColor; gdkColor = new GdkColor(); OS.gtk_style_get_text (style, OS.GTK_STATE_NORMAL, gdkColor); COLOR_TEXT_FOREGROUND = gdkColor; gdkColor = new GdkColor(); OS.gtk_style_get_base (style, OS.GTK_STATE_NORMAL, gdkColor); COLOR_TEXT_BACKGROUND = gdkColor; gdkColor = new GdkColor(); OS.gtk_style_get_text (style, OS.GTK_STATE_NORMAL, gdkColor); COLOR_LIST_FOREGROUND = gdkColor; gdkColor = new GdkColor(); OS.gtk_style_get_base (style, OS.GTK_STATE_NORMAL, gdkColor); COLOR_LIST_BACKGROUND = gdkColor; gdkColor = new GdkColor(); OS.gtk_style_get_text (style, OS.GTK_STATE_SELECTED, gdkColor); COLOR_LIST_SELECTION_TEXT = gdkColor; gdkColor = new GdkColor(); OS.gtk_style_get_base (style, OS.GTK_STATE_SELECTED, gdkColor); COLOR_LIST_SELECTION = gdkColor; gdkColor = new GdkColor(); OS.gtk_style_get_fg (tooltipStyle, OS.GTK_STATE_NORMAL, gdkColor); COLOR_INFO_FOREGROUND = gdkColor; gdkColor = new GdkColor(); OS.gtk_style_get_bg (tooltipStyle, OS.GTK_STATE_NORMAL, gdkColor); COLOR_INFO_BACKGROUND = gdkColor; gdkColor = new GdkColor(); OS.gtk_style_get_bg (style, OS.GTK_STATE_SELECTED, gdkColor); COLOR_TITLE_BACKGROUND = gdkColor; gdkColor = new GdkColor(); OS.gtk_style_get_fg (style, OS.GTK_STATE_SELECTED, gdkColor); COLOR_TITLE_FOREGROUND = gdkColor; gdkColor = new GdkColor(); OS.gtk_style_get_light (style, OS.GTK_STATE_SELECTED, gdkColor); COLOR_TITLE_BACKGROUND_GRADIENT = gdkColor; gdkColor = new GdkColor(); OS.gtk_style_get_bg (style, OS.GTK_STATE_INSENSITIVE, gdkColor); COLOR_TITLE_INACTIVE_BACKGROUND = gdkColor; gdkColor = new GdkColor(); OS.gtk_style_get_fg (style, OS.GTK_STATE_INSENSITIVE, gdkColor); COLOR_TITLE_INACTIVE_FOREGROUND = gdkColor; gdkColor = new GdkColor(); OS.gtk_style_get_light (style, OS.GTK_STATE_INSENSITIVE, gdkColor); COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT = gdkColor; OS.gtk_widget_destroy (tooltipShellHandle); OS.gtk_widget_destroy (shellHandle); } /** * 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>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> */ public Font getSystemFont () { checkDevice (); return Font.gtk_new (this, defaultFont); } /** * Returns the single instance of the system tray. * * @return the receiver's user-interface thread * * @exception SWTException <ul> * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @since 3.0 */ public Tray getSystemTray () { if (tray != null) return tray; return tray = new Tray (this, SWT.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 * </ul> */ public Thread getThread () { if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED); return thread; } Widget getWidget (int /*long*/ handle) { if (handle == 0) return null; int /*long*/ index = OS.g_object_get_qdata (handle, SWT_OBJECT_INDEX) - 1; if (0 <= index && index < widgetTable.length) return widgetTable [(int)/*64*/index]; return null; } /** * Initializes any internal resources needed by the * device. * <p> * This method is called after <code>create. * </p> * * @see #create */ protected void init () { super.init (); initializeCallbacks (); initializeSystemResources (); initializeWidgetTable (); } void initializeCallbacks () { windowCallback2 = new Callback (this, "windowProc", 2); windowProc2 = windowCallback2.getAddress (); if (windowProc2 == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS); windowCallback3 = new Callback (this, "windowProc", 3); windowProc3 = windowCallback3.getAddress (); if (windowProc3 == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS); windowCallback4 = new Callback (this, "windowProc", 4); windowProc4 = windowCallback4.getAddress (); if (windowProc4 == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS); windowCallback5 = new Callback (this, "windowProc", 5); windowProc5 = windowCallback5.getAddress (); if (windowProc5 == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS); timerCallback = new Callback (this, "timerProc", 1); timerProc = timerCallback.getAddress (); if (timerProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS); windowTimerCallback = new Callback (this, "windowTimerProc", 1); windowTimerProc = windowTimerCallback.getAddress (); if (windowTimerProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS); mouseHoverCallback = new Callback (this, "mouseHoverProc", 1); mouseHoverProc = mouseHoverCallback.getAddress (); if (mouseHoverProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS); caretCallback = new Callback(this, "caretProc", 1); caretProc = caretCallback.getAddress(); if (caretProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS); menuPositionCallback = new Callback(this, "menuPositionProc", 5); menuPositionProc = menuPositionCallback.getAddress(); if (menuPositionProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS); shellMapCallback = new Callback(this, "shellMapProc", 3); shellMapProc = shellMapCallback.getAddress(); if (shellMapProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS); treeSelectionCallback = new Callback(this, "treeSelectionProc", 4); treeSelectionProc = treeSelectionCallback.getAddress(); if (treeSelectionProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS); textCellDataCallback = new Callback (this, "textCellDataProc", 5); textCellDataProc = textCellDataCallback.getAddress (); if (textCellDataProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS); pixbufCellDataCallback = new Callback (this, "pixbufCellDataProc", 5); pixbufCellDataProc = pixbufCellDataCallback.getAddress (); if (pixbufCellDataProc == 0) error (SWT.ERROR_NO_MORE_CALLBACKS); } void initializeWidgetTable () { indexTable = new int [GROW_SIZE]; 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 dispose a GC handle. * <p> * <b>IMPORTANT: This method is not part of the public * API for <code>Display. 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 */ public void internal_dispose_GC (int /*long*/ gdkGC, GCData data) { OS.g_object_unref (gdkGC); } /** * Invokes platform specific functionality to allocate a new GC handle. * <p> * <b>IMPORTANT: This method is not part of the public * API for <code>Display. 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 SWTError <ul> * <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation * </ul> * @exception SWTException <ul> * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> */ public int /*long*/ internal_new_GC (GCData data) { if (isDisposed()) SWT.error(SWT.ERROR_DEVICE_DISPOSED); int /*long*/ root = OS.GDK_ROOT_PARENT (); int /*long*/ gdkGC = OS.gdk_gc_new (root); if (gdkGC == 0) SWT.error (SWT.ERROR_NO_HANDLES); 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.drawable = root; data.font = defaultFont; } return gdkGC; } boolean isValidThread () { return thread == Thread.currentThread (); } /** * 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 or null * @param to the destination <code>Control or null * @param point to be mapped * @return point with mapped coordinates * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the rectangle is null * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed * </ul> * @exception SWTException <ul> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @since 2.1.2 */ 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 or null * @param to the destination <code>Control or null * @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 * </ul> * @exception SWTException <ul> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @since 2.1.2 */ 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) { int /*long*/ eventHandle = from.eventHandle (); OS.gtk_widget_realize (eventHandle); int /*long*/ window = OS.GTK_WIDGET_WINDOW (eventHandle); int [] origin_x = new int [1], origin_y = new int [1]; OS.gdk_window_get_origin (window, origin_x, origin_y); point.x += origin_x [0]; point.y += origin_y [0]; } if (to != null) { int /*long*/ eventHandle = to.eventHandle (); OS.gtk_widget_realize (eventHandle); int /*long*/ window = OS.GTK_WIDGET_WINDOW (eventHandle); int [] origin_x = new int [1], origin_y = new int [1]; OS.gdk_window_get_origin (window, origin_x, origin_y); point.x -= origin_x [0]; point.y -= origin_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 or null * @param to the destination <code>Control or null * @param rectangle to be mapped * @return rectangle with mapped coordinates * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the rectangle is null * <li>ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed * </ul> * @exception SWTException <ul> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @since 2.1.2 */ 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); } static char mbcsToWcs (char ch) { int key = ch & 0xFFFF; if (key <= 0x7F) return ch; byte [] buffer; if (key <= 0xFF) { buffer = new byte [1]; buffer [0] = (byte) key; } else { buffer = new byte [2]; buffer [0] = (byte) ((key >> 8) & 0xFF); buffer [1] = (byte) (key & 0xFF); } char [] result = Converter.mbcsToWcs (null, buffer); if (result.length == 0) return 0; return result [0]; } int /*long*/ menuPositionProc (int /*long*/ menu, int /*long*/ x, int /*long*/ y, int /*long*/ push_in, int /*long*/ user_data) { Widget widget = getWidget (menu); if (widget == null) return 0; return widget.menuPositionProc (menu, x, y, push_in, user_data); } /** * 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 or null * @param to the destination <code>Control or null * @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 * </ul> * @exception SWTException <ul> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @since 2.1.2 */ 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) { int /*long*/ eventHandle = from.eventHandle (); OS.gtk_widget_realize (eventHandle); int /*long*/ window = OS.GTK_WIDGET_WINDOW (eventHandle); int [] origin_x = new int [1], origin_y = new int [1]; OS.gdk_window_get_origin (window, origin_x, origin_y); rect.x += origin_x [0]; rect.y += origin_y [0]; } if (to != null) { int /*long*/ eventHandle = to.eventHandle (); OS.gtk_widget_realize (eventHandle); int /*long*/ window = OS.GTK_WIDGET_WINDOW (eventHandle); int [] origin_x = new int [1], origin_y = new int [1]; OS.gdk_window_get_origin (window, origin_x, origin_y); rect.x -= origin_x [0]; rect.y -= origin_y [0]; } return rect; } int /*long*/ mouseHoverProc (int /*long*/ handle) { Widget widget = getWidget (handle); if (widget == null) return 0; return widget.hoverProc (handle); } /** * Generate a low level system event. * * <code>post 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> * <b>Event Types: * <p>KeyDown, KeyUp * <p>The following fields in the Event apply: * <ul> * <li>(in) type KeyDown or KeyUp * <p> Either one of: * <li>(in) character a character that corresponds to a keyboard key * <li>(in) keyCode the key code of the key that was typed, * as defined by the key code constants in class <code>SWT * </ul> * <p>MouseDown, MouseUp

* <p>The following fields in the Event apply: * <ul> * <li>(in) type MouseDown or MouseUp * <li>(in) button the button that is pressed or released * </ul> * <p>MouseMove

* <p>The following fields in the Event 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 * </ul> * @exception SWTException <ul> * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @since 3.0 * */ public boolean post (Event event) { if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED); if (event == null) error (SWT.ERROR_NULL_ARGUMENT); if (!OS.GDK_WINDOWING_X11()) return false; int /*long*/ xDisplay = OS.GDK_DISPLAY (); int type = event.type; switch (type) { case SWT.KeyDown: case SWT.KeyUp: { int keyCode = 0; int /*long*/ keysym = untranslateKey (event.keyCode); if (keysym != 0) keyCode = OS.XKeysymToKeycode (xDisplay, keysym); if (keyCode == 0) { char key = event.character; switch (key) { case '\r': keysym = OS.GDK_Return; 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); } 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 * if there is potentially more work to do, or <code>false * 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() * or <code>asyncExec()) are waiting to be processed, and if * so handles them before returning. * </p> * * @return <code>false 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>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @see #sleep * @see #wake */ public boolean readAndDispatch () { checkDevice (); runPopups (); int status = OS.gtk_events_pending (); if (status != 0) { OS.gtk_main_iteration (); runDeferredEvents (); return true; } return runAsyncMessages (); } synchronized void register () { for (int i=0; i<Displays.length; i++) { if (Displays [i] == null) { Displays [i] = this; return; } } Display [] newDisplays = new Display [Displays.length + 4]; System.arraycopy (Displays, 0, newDisplays, 0, Displays.length); newDisplays [Displays.length] = this; 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 when sent the message * <code>isDisposed(). * </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. 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. * </p> * This method is called before <code>destroy. * * @see #dispose * @see #destroy */ 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 () { windowCallback2.dispose (); windowCallback2 = null; windowCallback3.dispose (); windowCallback3 = null; windowCallback4.dispose (); windowCallback4 = null; windowCallback5.dispose (); windowCallback5 = null; /* Dispose preedit window */ if (preeditWindow != 0) OS.gtk_widget_destroy (preeditWindow); imControl = null; /* Dispose the menu callback */ menuPositionCallback.dispose (); menuPositionCallback = null; menuPositionProc = 0; /* Dispose the shell map callback */ shellMapCallback.dispose (); shellMapCallback = null; shellMapProc = 0; /* Dispose GtkTreeView callbacks */ treeSelectionCallback.dispose (); treeSelectionCallback = null; treeSelectionProc = 0; textCellDataCallback.dispose (); textCellDataCallback = null; textCellDataProc = 0; pixbufCellDataCallback.dispose (); pixbufCellDataCallback = null; pixbufCellDataProc = 0; /* Dispose the caret callback */ if (caretId != 0) OS.gtk_timeout_remove (caretId); caretId = 0; 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.gtk_timeout_remove (timerIds [i]); } } timerIds = null; timerList = null; timerProc = 0; timerCallback.dispose (); timerCallback = null; windowTimerProc = 0; windowTimerCallback.dispose (); windowTimerCallback = null; /* Dispose mouse hover callback */ if (mouseHoverId != 0) OS.gtk_timeout_remove (mouseHoverId); mouseHoverId = 0; mouseHoverHandle = mouseHoverProc = 0; mouseHoverCallback.dispose (); mouseHoverCallback = null; thread = null; windowProc2 = windowProc3 = windowProc4 = windowProc5 = 0; /* Dispose the default font */ if (defaultFont != 0) OS.pango_font_description_free (defaultFont); defaultFont = 0; /* Dispose the System Images */ if (errorPixmap != 0) { OS.g_object_unref (errorPixmap); OS.g_object_unref (errorMask); } if (infoPixmap != 0) { OS.g_object_unref (infoPixmap); OS.g_object_unref (infoMask); } if (questionPixmap != 0) { OS.g_object_unref (questionPixmap); OS.g_object_unref (questionMask); } if (warningPixmap != 0) { OS.g_object_unref (warningPixmap); OS.g_object_unref (warningMask); } errorPixmap = infoPixmap = questionPixmap = warningPixmap = 0; errorMask = infoMask = questionMask = warningMask = 0; /* Release the System Cursors */ for (int i = 0; i < cursors.length; i++) { if (cursors [i] != null) cursors [i].dispose (); } cursors = null; COLOR_WIDGET_DARK_SHADOW = COLOR_WIDGET_NORMAL_SHADOW = COLOR_WIDGET_LIGHT_SHADOW = COLOR_WIDGET_HIGHLIGHT_SHADOW = COLOR_WIDGET_BACKGROUND = COLOR_WIDGET_BORDER = COLOR_LIST_FOREGROUND = COLOR_LIST_BACKGROUND = COLOR_LIST_SELECTION = COLOR_LIST_SELECTION_TEXT = COLOR_INFO_BACKGROUND = null; /* Dispose the event callback */ OS.gdk_event_handler_set (0, 0, 0); eventCallback.dispose (); eventCallback = null; } /** * Removes the listener from the collection of listeners who will * be notifed when an event of the given type occurs anywhere in * this display. * * @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 * </ul> * @exception SWTException <ul> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * </ul> * * @see Listener * @see #addFilter * @see #addListener * * @since 3.0 */ 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; } int /*long*/ removeGdkEvent () { if (gdkEventCount == 0) return 0; int /*long*/ event = gdkEvents [0]; --gdkEventCount; System.arraycopy (gdkEvents, 1, gdkEvents, 0, gdkEventCount); System.arraycopy (gdkEventWidgets, 1, gdkEventWidgets, 0, gdkEventCount); gdkEvents [gdkEventCount] = 0; gdkEventWidgets [gdkEventCount] = null; if (gdkEventCount == 0) { gdkEvents = null; gdkEventWidgets = null; } return event; } /** * 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 * </ul> * @exception SWTException <ul> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @see Listener * @see #addListener * * @since 2.0 */ public void removeListener (int eventType, Listener listener) { checkDevice (); if (listener == null) error (SWT.ERROR_NULL_ARGUMENT); if (eventTable == null) return; eventTable.unhook (eventType, listener); } void removeMouseHoverTimeout (int /*long*/ handle) { if (handle != mouseHoverHandle) return; if (mouseHoverId != 0) OS.gtk_timeout_remove (mouseHoverId); mouseHoverId = 0; mouseHoverHandle = 0; } void removePopup (Menu menu) { if (popups == null) return; for (int i=0; i<popups.length; i++) { if (popups [i] == menu) { popups [i] = null; return; } } } Widget removeWidget (int /*long*/ handle) { if (handle == 0) return null; Widget widget = null; int index = (int)/*64*/ OS.g_object_get_qdata (handle, SWT_OBJECT_INDEX) - 1; if (0 <= index && index < widgetTable.length) { widget = widgetTable [index]; widgetTable [index] = null; indexTable [index] = freeSlot; freeSlot = index; OS.g_object_set_qdata (handle, SWT_OBJECT_INDEX, 0); } return widget; } boolean runAsyncMessages () { return synchronizer.runAsyncMessages (); } 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); /* Ask for the next mouse event */ if (event.type == SWT.MouseMove) { OS.gdk_window_get_pointer (0, null, null, null); } } } /* * 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 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; } /** * 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. * * @param name the new app name */ public static void setAppName (String name) { APP_NAME = name; } /** * 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>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @since 2.1 */ public void setCursorLocation (int x, int y) { checkDevice (); /* This is not supported on GTK */ } /** * 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>ERROR_NULL_ARGUMENT - if the point is null * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @since 2.0 */ public void setCursorLocation (Point point) { checkDevice (); if (point == null) error (SWT.ERROR_NULL_ARGUMENT); setCursorLocation (point.x, point.y); } /** * 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() 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 * </ul> * @exception SWTException <ul> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @see #setData * @see #disposeExec */ 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 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() 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>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @see #getData * @see #disposeExec */ 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 * </ul> * @exception SWTException <ul> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> */ public void setSynchronizer (Synchronizer synchronizer) { checkDevice (); if (synchronizer == null) error (SWT.ERROR_NULL_ARGUMENT); if (this.synchronizer != null) { this.synchronizer.runAsyncMessages(); } this.synchronizer = synchronizer; } void showIMWindow (Control control) { imControl = control; if (preeditWindow == 0) { preeditWindow = OS.gtk_window_new (OS.GTK_WINDOW_POPUP); if (preeditWindow == 0) error (SWT.ERROR_NO_HANDLES); preeditLabel = OS.gtk_label_new (null); if (preeditLabel == 0) error (SWT.ERROR_NO_HANDLES); OS.gtk_container_add (preeditWindow, preeditLabel); OS.gtk_widget_show (preeditLabel); } int /*long*/ [] preeditString = new int /*long*/ [1]; int /*long*/ [] pangoAttrs = new int /*long*/ [1]; int /*long*/ imHandle = control.imHandle (); OS.gtk_im_context_get_preedit_string (imHandle, preeditString, pangoAttrs, null); if (preeditString [0] != 0 && OS.strlen (preeditString [0]) > 0) { OS.gtk_widget_modify_bg (preeditWindow, OS.GTK_STATE_NORMAL, control.getBackgroundColor ()); OS.gtk_widget_modify_fg (preeditLabel, OS.GTK_STATE_NORMAL, control.getForegroundColor ()); OS.gtk_widget_modify_font (preeditLabel, control.getFontDescription ()); if (pangoAttrs [0] != 0) OS.gtk_label_set_attributes (preeditLabel, pangoAttrs[0]); OS.gtk_label_set_text (preeditLabel, preeditString [0]); Point point = control.toDisplay (control.getIMCaretPos ()); OS.gtk_window_move (preeditWindow, point.x, point.y); GtkRequisition requisition = new GtkRequisition (); OS.gtk_widget_size_request (preeditLabel, requisition); OS.gtk_window_resize (preeditWindow, requisition.width, requisition.height); OS.gtk_widget_show (preeditWindow); } else { OS.gtk_widget_hide (preeditWindow); } if (preeditString [0] != 0) OS.g_free (preeditString [0]); if (pangoAttrs [0] != 0) OS.pango_attr_list_unref (pangoAttrs [0]); } /** * Causes the user-interface thread to <em>sleep (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 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>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @see #wake */ public boolean sleep () { checkDevice (); //TODO need to sleep waiting for the next event do { if (getMessageCount () != 0) break; if (OS.gtk_events_pending () != 0) break; try { synchronized (OS_LOCK) { OS_LOCK.wait (50); } } catch (Exception e) { return false; } } while (true); return true; } /** * Causes the <code>run() 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. * * @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 * </ul> * @exception SWTException <ul> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @see #asyncExec */ 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.gtk_timeout_remove (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 timerId = OS.gtk_timeout_add (milliseconds, timerProc, index); if (timerId != 0) { timerIds [index] = timerId; timerList [index] = runnable; } } int /*long*/ timerProc (int /*long*/ i) { if (timerList == null) return 0; int index = (int)/*64*/i; if (0 <= index && index < timerList.length) { Runnable runnable = timerList [index]; timerList [index] = null; timerIds [index] = 0; if (runnable != null) { //BOGUS long t1 = System.currentTimeMillis (); try { runnable.run (); //BOGUS } finally { long t2 = System.currentTimeMillis (); if (t2 - t1 > 250) { System.out.println ("TIMER: " + (t2 - t1) + "(ms)"); System.out.println (runnable); System.out.println (); } } } } return 0; } int /*long*/ caretProc (int /*long*/ clientData) { caretId = 0; if (currentCaret == null) { return 0; } if (currentCaret.blinkCaret()) { int blinkRate = currentCaret.blinkRate; caretId = OS.gtk_timeout_add (blinkRate, caretProc, 0); } else { currentCaret = null; } return 0; } int /*long*/ pixbufCellDataProc (int /*long*/ tree_column, int /*long*/ cell, int /*long*/ tree_model, int /*long*/ iter, int /*long*/ data) { Widget widget = getWidget (data); if (widget == null) return 0; return widget.pixbufCellDataProc (tree_column, cell, tree_model, iter, data); } int /*long*/ textCellDataProc (int /*long*/ tree_column, int /*long*/ cell, int /*long*/ tree_model, int /*long*/ iter, int /*long*/ data) { Widget widget = getWidget (data); if (widget == null) return 0; return widget.textCellDataProc (tree_column, cell, tree_model, iter, data); } int /*long*/ treeSelectionProc (int /*long*/ model, int /*long*/ path, int /*long*/ iter, int /*long*/ data) { Widget widget = getWidget (data); if (widget == null) return 0; return widget.treeSelectionProc (model, path, iter, treeSelection, treeSelectionLength++); } 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); } } void setCurrentCaret (Caret caret) { if (caretId != 0) OS.gtk_timeout_remove(caretId); caretId = 0; currentCaret = caret; if (caret == null) return; int blinkRate = currentCaret.blinkRate; caretId = OS.gtk_timeout_add (blinkRate, caretProc, 0); } int /*long*/ shellMapProc (int /*long*/ handle, int /*long*/ arg0, int /*long*/ user_data) { Widget widget = getWidget (handle); if (widget == null) return 0; return widget.shellMapProc (handle, arg0, user_data); } /** * Causes the <code>run() 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. * * @param runnable code to run on the user-interface thread. * * @exception SWTException <ul> * <li>ERROR_FAILED_EXEC - if an exception occured when executing the runnable * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @see #asyncExec */ public void syncExec (Runnable runnable) { if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED); synchronizer.syncExec (runnable); } 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>ERROR_DEVICE_DISPOSED - if the receiver has been disposed * </ul> * * @see Control#update */ public void update () { checkDevice (); flushExposes (); OS.gdk_window_process_all_updates (); } /** * If the receiver's user-interface thread was <code>sleep'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 * </ul> * * @see #sleep */ public void wake () { if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED); if (thread == Thread.currentThread ()) return; wakeThread (); } void wakeThread () { // NOT IMPLEMENTED - need to wake up the event loop } static char wcsToMbcs (char ch) { int key = ch & 0xFFFF; if (key <= 0x7F) return ch; byte [] buffer = Converter.wcsToMbcs (null, 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 /*long*/ windowProc (int /*long*/ handle, int /*long*/ user_data) { Widget widget = getWidget (handle); if (widget == null) return 0; return widget.windowProc (handle, user_data); } int /*long*/ windowProc (int /*long*/ handle, int /*long*/ arg0, int /*long*/ user_data) { Widget widget = getWidget (handle); if (widget == null) return 0; return widget.windowProc (handle, arg0, user_data); } int /*long*/ windowProc (int /*long*/ handle, int /*long*/ arg0, int /*long*/ arg1, int /*long*/ user_data) { Widget widget = getWidget (handle); if (widget == null) return 0; return widget.windowProc (handle, arg0, arg1, user_data); } int /*long*/ windowProc (int /*long*/ handle, int /*long*/ arg0, int /*long*/ arg1, int /*long*/ arg2, int /*long*/ user_data) { Widget widget = getWidget (handle); if (widget == null) return 0; return widget.windowProc (handle, arg0, arg1, arg2, user_data); } int /*long*/ windowTimerProc (int /*long*/ handle) { Widget widget = getWidget (handle); if (widget == null) return 0; return widget.timerProc (handle); } }

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.