Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
The osx x86_64 swt jar as available in the Eclipse 4.6 (Neon) release for OSX. It is suitable for use with jface and other dependencies available from maven central in the org.eclipse.scout.sdk.deps group. The sources is copied from swt-4.6-cocoa-macosx-x86_64.zip from http://download.eclipse.org/eclipse/downloads/drops4/R-4.6-201606061100/ and javadoc is generated from sources.
/*******************************************************************************
* Copyright (c) 2000, 2016 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 java.util.*;
import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.cocoa.*;
/**
* 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.
*
* Applications which are built with SWT will almost always
* require only a single display. In particular, some platforms
* which SWT supports will not allow more than one active
* display. In other words, some platforms do not support
* creating a new display if one already exists that has not been
* sent the dispose() message.
*
* In SWT, the thread which creates a Display
* instance is distinguished as the user-interface thread
* for that display.
*
* The user-interface thread for a particular display has the
* following special attributes:
*
*
* The event loop for that display must be run from the thread.
*
*
* Some SWT API methods (notably, most of the public methods in
* Widget and its subclasses), may only be called
* from the thread. (To support multi-threaded user-interface
* applications, class Display provides inter-thread
* communication methods which allow threads other than the
* user-interface thread to request that it perform operations
* on their behalf.)
*
*
* The thread is not allowed to construct other
* 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.)
*
*
* 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.
*
* 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 "ERROR_THREAD_INVALID_ACCESS"
* SWT exception.
*
*
*
Styles:
*
(none)
*
Events:
*
Close, Dispose, OpenDocument, Settings, Skin
*
*
* IMPORTANT: This class is not intended to be subclassed.
*
* @see #syncExec
* @see #asyncExec
* @see #wake
* @see #readAndDispatch
* @see #sleep
* @see Device#dispose
* @see Display snippets
* @see Sample code and further information
* @noextend This class is not intended to be subclassed by clients.
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public class Display extends Device {
static byte[] types = {'*','\0'};
static int size = C.PTR_SIZEOF, align = C.PTR_SIZEOF == 4 ? 2 : 3;
/* Windows and Events */
Event [] eventQueue;
EventTable eventTable, filterTable;
boolean disposing;
int sendEventCount;
/* gesture event state */
double rotation;
double magnification;
boolean gestureActive;
/* touch event state */
int touchCounter;
long primaryIdentifier;
NSMutableArray currentTouches;
TouchSource[] touchSources;
/* Sync/Async Widget Communication */
Synchronizer synchronizer;
Thread thread;
boolean allowTimers = true, runAsyncMessages = true;
/* AWT Invoke Later */
static final String RUN_AWT_INVOKE_LATER_KEY = "org.eclipse.swt.internal.runAWTInvokeLater"; //$NON-NLS-1$
GCData[] contexts;
Caret currentCaret;
boolean sendEvent;
int clickCountButton, clickCount;
int blinkTime;
Control currentControl, trackingControl, tooltipControl, ignoreFocusControl;
Widget tooltipTarget;
NSMutableArray isPainting, needsDisplay, needsDisplayInRect, runLoopModes;
NSDictionary markedAttributes;
/* Fonts */
boolean smallFonts;
NSFont buttonFont, popUpButtonFont, textFieldFont, secureTextFieldFont;
NSFont searchFieldFont, comboBoxFont, sliderFont, scrollerFont;
NSFont textViewFont, tableViewFont, outlineViewFont, datePickerFont;
NSFont boxFont, tabViewFont, progressIndicatorFont;
Shell [] modalShells;
Dialog modalDialog;
NSPanel modalPanel;
Menu menuBar;
Menu[] menus, popups;
/* Menu items with ESC key as accelerator need to be handled differently on Cocoa */
boolean escAsAcceleratorPresent = false;
NSApplication application;
long /*int*/ applicationClass;
NSImage dockImage;
boolean isEmbedded;
static boolean launched = false;
int systemUIMode, systemUIOptions;
/* Focus */
Control focusControl, currentFocusControl;
int focusEvent;
NSWindow screenWindow, keyWindow;
NSAutoreleasePool[] pools;
int poolCount, loopCount;
int[] screenID = new int[32];
NSPoint[] screenCascade = new NSPoint[32];
long /*int*/ runLoopObserver;
Callback observerCallback;
boolean lockCursor = true;
static final String LOCK_CURSOR = "org.eclipse.swt.internal.lockCursor"; //$NON-NLS-1$
long /*int*/ oldCursorSetProc;
Callback cursorSetCallback;
Combo currentCombo;
boolean mozillaRunning;
static final String MOZILLA_RUNNING = "org.eclipse.swt.internal.mozillaRunning"; //$NON-NLS-1$
// the following Callbacks are never freed
static Callback windowCallback2, windowCallback3, windowCallback4, windowCallback5, windowCallback6;
static Callback dialogCallback3, dialogCallback4, dialogCallback5;
static Callback applicationCallback2, applicationCallback3, applicationCallback4, applicationCallback6;
/* Display Shutdown */
Runnable [] disposeList;
/* Deferred Layout list */
Composite[] layoutDeferred;
int layoutDeferredCount;
/* System Tray */
Tray tray;
TrayItem currentTrayItem;
Menu trayItemMenu;
/* Main menu bar and application menu */
Menu appMenuBar, appMenu;
/* TaskBar */
TaskBar taskBar;
/* System Resources */
Image errorImage, infoImage, warningImage;
Cursor [] cursors = new Cursor [SWT.CURSOR_HAND + 1];
/* System Colors */
double /*float*/ [][] colors;
double /*float*/ [] alternateSelectedControlTextColor, selectedControlTextColor;
double /*float*/ [] alternateSelectedControlColor, secondarySelectedControlColor;
/* Key Mappings. */
static int [] [] KeyTable = {
/* Keyboard and Mouse Masks */
{58, SWT.ALT},
{56, SWT.SHIFT},
{59, SWT.CONTROL},
{55, SWT.COMMAND},
{61, SWT.ALT},
{62, SWT.CONTROL},
{60, SWT.SHIFT},
{54, SWT.COMMAND},
/* Non-Numeric Keypad Keys */
{126, SWT.ARROW_UP},
{125, SWT.ARROW_DOWN},
{123, SWT.ARROW_LEFT},
{124, SWT.ARROW_RIGHT},
{116, SWT.PAGE_UP},
{121, SWT.PAGE_DOWN},
{115, SWT.HOME},
{119, SWT.END},
// {??, SWT.INSERT},
/* Virtual and Ascii Keys */
{51, SWT.BS},
{36, SWT.CR},
{117, SWT.DEL},
{53, SWT.ESC},
{76, SWT.LF},
{48, SWT.TAB},
/* Functions Keys */
{122, SWT.F1},
{120, SWT.F2},
{99, SWT.F3},
{118, SWT.F4},
{96, SWT.F5},
{97, SWT.F6},
{98, SWT.F7},
{100, SWT.F8},
{101, SWT.F9},
{109, SWT.F10},
{103, SWT.F11},
{111, SWT.F12},
{105, SWT.F13},
{107, SWT.F14},
{113, SWT.F15},
{106, SWT.F16},
{64, SWT.F17},
{79, SWT.F18},
{80, SWT.F19},
// {??, SWT.F20},
/* Numeric Keypad Keys */
{67, SWT.KEYPAD_MULTIPLY},
{69, SWT.KEYPAD_ADD},
{76, SWT.KEYPAD_CR},
{78, SWT.KEYPAD_SUBTRACT},
{65, SWT.KEYPAD_DECIMAL},
{75, SWT.KEYPAD_DIVIDE},
{82, SWT.KEYPAD_0},
{83, SWT.KEYPAD_1},
{84, SWT.KEYPAD_2},
{85, SWT.KEYPAD_3},
{86, SWT.KEYPAD_4},
{87, SWT.KEYPAD_5},
{88, SWT.KEYPAD_6},
{89, SWT.KEYPAD_7},
{91, SWT.KEYPAD_8},
{92, SWT.KEYPAD_9},
{81, SWT.KEYPAD_EQUAL},
/* Other keys */
{57, SWT.CAPS_LOCK},
{71, SWT.NUM_LOCK},
// {??, SWT.SCROLL_LOCK},
// {??, SWT.PAUSE},
// {??, SWT.BREAK},
// {??, SWT.PRINT_SCREEN},
{114, SWT.HELP},
};
static String APP_NAME;
static String APP_VERSION = ""; //$NON-NLS-1$
static final String ADD_WIDGET_KEY = "org.eclipse.swt.internal.addWidget"; //$NON-NLS-1$
static final byte[] SWT_OBJECT = {'S', 'W', 'T', '_', 'O', 'B', 'J', 'E', 'C', 'T', '\0'};
static final byte[] SWT_EMBED_FRAMES = {'S', 'W', 'T', '_', 'E', 'M', 'B', 'E', 'D', '_', 'F', 'R', 'A', 'M', 'E', 'S', '\0'};
static final byte[] SWT_IMAGE = {'S', 'W', 'T', '_', 'I', 'M', 'A', 'G', 'E', '\0'};
static final byte[] SWT_ROW = {'S', 'W', 'T', '_', 'R', 'O', 'W', '\0'};
static final byte[] SWT_COLUMN = {'S', 'W', 'T', '_', 'C', 'O', 'L', 'U', 'M', 'N', '\0'};
static final String SET_MODAL_DIALOG = "org.eclipse.swt.internal.modalDialog"; //$NON-NLS-1$
/* Multiple Displays. */
static Display Default;
static Display [] Displays = new Display [4];
/* Skinning support */
static final int GROW_SIZE = 1024;
Widget [] skinList = new Widget [GROW_SIZE];
int skinCount;
/* Package Name */
static final String PACKAGE_PREFIX = "org.eclipse.swt.widgets.";
/* Timer */
Runnable timerList [];
NSTimer nsTimers [];
SWTWindowDelegate timerDelegate;
static SWTApplicationDelegate applicationDelegate;
static NSObject currAppDelegate;
/* Settings */
boolean runSettings;
SWTWindowDelegate settingsDelegate;
static final int DEFAULT_BUTTON_INTERVAL = 30;
/* Display Data */
Object data;
String [] keys;
Object [] values;
static Map/**/ dynamicObjectMap;
/*
* TEMPORARY CODE. Install the runnable that
* gets the current display. This code will
* be removed in the future.
*/
static {
DeviceFinder = new Runnable () {
@Override
public void run () {
Device device = getCurrent ();
if (device == null) {
device = getDefault ();
}
setDevice (device);
}
};
}
/*
* TEMPORARY CODE.
*/
static void setDevice (Device device) {
CurrentDevice = device;
}
static byte [] ascii (String name) {
int length = name.length ();
char [] chars = new char [length];
name.getChars (0, length, chars, 0);
byte [] buffer = new byte [length + 1];
for (int i=0; iSWT. When the event does occur,
* the listener is notified by sending it the handleEvent()
* message.
*
* Setting the type of an event to SWT.None from
* within the handleEvent() method can be used to
* change the event type and stop subsequent Java listeners
* from running. Because event filters run before other listeners,
* event filters can both block other listeners and set arbitrary
* fields within an event. For this reason, event filters are both
* powerful and dangerous. They should generally be avoided for
* performance, debugging and code maintenance reasons.
*
*
* @param eventType the type of event to listen for
* @param listener the listener which should be notified when the event occurs
*
* @exception IllegalArgumentException
*
ERROR_NULL_ARGUMENT - if the listener is null
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @see Listener
* @see SWT
* @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 addLayoutDeferred (Composite comp) {
if (layoutDeferred == null) layoutDeferred = new Composite [64];
if (layoutDeferredCount == layoutDeferred.length) {
Composite [] temp = new Composite [layoutDeferred.length + 64];
System.arraycopy (layoutDeferred, 0, temp, 0, layoutDeferred.length);
layoutDeferred = temp;
}
layoutDeferred[layoutDeferredCount++] = comp;
}
/**
* Adds the listener to the collection of listeners who will
* be notified when an event of the given type occurs. The event
* type is one of the event constants defined in class SWT.
* When the event does occur in the display, the listener is notified by
* sending it the 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
*
ERROR_NULL_ARGUMENT - if the listener is null
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @see Listener
* @see SWT
* @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 addMenu (Menu menu) {
if (menus == null) menus = new Menu [12];
for (int i=0; i= skinList.length) {
Widget[] newSkinWidgets = new Widget [skinList.length + GROW_SIZE];
System.arraycopy (skinList, 0, newSkinWidgets, 0, skinList.length);
skinList = newSkinWidgets;
}
skinList [skinCount++] = widget;
}
void addWidget (NSObject view, Widget widget) {
if (view == null) return;
long /*int*/ ivar = OS.object_setInstanceVariable (view.id, SWT_OBJECT, widget.jniRef);
if (ivar == 0) {
if (dynamicObjectMap == null) {
dynamicObjectMap = new HashMap();
}
LONG JNIRef = new LONG(widget.jniRef);
dynamicObjectMap.put(view, JNIRef);
}
}
/**
* Causes the 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. Specifying null as the
* runnable simply wakes the user-interface thread when run.
*
* Note that at the time the runnable is invoked, widgets
* that have the receiver as their display may have been
* disposed. Therefore, it is necessary to check for this
* case inside the runnable before accessing the widget.
*
*
* @param runnable code to run on the user-interface thread or null
*
* @exception SWTException
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @see #syncExec
*/
public void asyncExec (Runnable runnable) {
synchronized (Device.class) {
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
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*/
public void beep () {
checkDevice ();
OS.NSBeep ();
}
void cascadeWindow (NSWindow window, NSScreen screen) {
NSDictionary dictionary = screen.deviceDescription();
int screenNumber = new NSNumber(dictionary.objectForKey(NSString.stringWith("NSScreenNumber")).id).intValue();
int index = 0;
while (screenID[index] != 0 && screenID[index] != screenNumber) index++;
screenID[index] = screenNumber;
NSPoint cascade = screenCascade[index];
if (cascade == null) {
NSRect frame = screen.frame();
cascade = new NSPoint();
cascade.x = frame.x;
cascade.y = frame.y + frame.height;
}
screenCascade[index] = window.cascadeTopLeftFromPoint(cascade);
}
@Override
protected void checkDevice () {
if (thread == null) error (SWT.ERROR_WIDGET_DISPOSED);
if (thread != Thread.currentThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
}
void checkEnterExit (Control control, NSEvent nsEvent, boolean send) {
if (control != currentControl) {
if (currentControl != null && !currentControl.isDisposed()) {
currentControl.sendMouseEvent (nsEvent, SWT.MouseExit, send);
}
if (control != null && control.isDisposed()) control = null;
currentControl = control;
if (control != null) {
control.sendMouseEvent (nsEvent, SWT.MouseEnter, send);
}
setCursor (control);
}
NSPoint location = NSEvent.mouseLocation();
if (control == null || control != currentControl || hoverLastLocation == null || location.x != hoverLastLocation.x || location.y != hoverLastLocation.y) {
hoverLastLocation = location;
timerExec (control != null && !control.isDisposed() ? getToolTipTime () : -1, hoverTimer);
}
}
void checkFocus () {
Control oldControl = currentFocusControl;
Control newControl = getFocusControl ();
if (oldControl == ignoreFocusControl && newControl == null) {
/*
* Bug in Cocoa. On Mac 10.8, a control loses and gains focus
* when its bounds changes. The fix is to ignore these events.
* See Bug 388574 & 433275.
*/
return;
}
if (oldControl != newControl) {
if (oldControl != null && !oldControl.isDisposed ()) {
oldControl.sendFocusEvent (SWT.FocusOut);
}
currentFocusControl = newControl;
if (newControl != null && !newControl.isDisposed ()) {
newControl.sendFocusEvent (SWT.FocusIn);
}
}
}
/**
* Checks that this class can be subclassed.
*
* IMPORTANT: See the comment in Widget.checkSubclass().
*
*
* @exception SWTException
*
ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
*
*
* @see Widget#checkSubclass
*/
protected void checkSubclass () {
if (!Display.isValidClass (getClass ())) error (SWT.ERROR_INVALID_SUBCLASS);
}
/**
* Constructs a new instance of this class.
*
* Note: The resulting display is marked as the current
* display. If this is the first display which has been
* constructed since the application started, it is also
* marked as the default display.
*
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if called from a thread that already created an existing display
*
ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
*
*
* @see #getCurrent
* @see #getDefault
* @see Widget#checkSubclass
* @see Shell
*/
public Display () {
this (null);
}
/**
* Constructs a new instance of this class using the parameter.
*
* @param data the device data
*/
public Display (DeviceData data) {
super (data);
}
static void checkDisplay (Thread thread, boolean multiple) {
synchronized (Device.class) {
for (int i=0; i
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @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.
*
* This method is called before init.
*
*
* @param data the DeviceData which describes the receiver
*
* @see #init
*/
@Override
protected void create (DeviceData data) {
checkSubclass ();
checkDisplay (thread = Thread.currentThread (), false);
createDisplay (data);
register (this);
synchronizer = new Synchronizer (this);
if (Default == null) Default = this;
}
void createDisplay (DeviceData data) {
if (OS.VERSION < 0x1050) {
System.out.println ("***WARNING: SWT requires MacOS X version " + 10 + "." + 5 + " or greater"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
System.out.println ("***WARNING: Detected: " + Integer.toHexString((OS.VERSION & 0xFF00) >> 8) + "." + Integer.toHexString((OS.VERSION & 0xF0) >> 4) + "." + Integer.toHexString(OS.VERSION & 0xF)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
error(SWT.ERROR_NOT_IMPLEMENTED);
}
NSThread nsthread = NSThread.currentThread();
if (!NSThread.isMainThread()) {
System.out.println ("***WARNING: Display must be created on main thread due to Cocoa restrictions."); //$NON-NLS-1$
error(SWT.ERROR_THREAD_INVALID_ACCESS);
}
NSMutableDictionary dictionary = nsthread.threadDictionary();
NSString key = NSString.stringWith("SWT_NSAutoreleasePool");
NSNumber id = new NSNumber(dictionary.objectForKey(key));
addPool(new NSAutoreleasePool(id.integerValue()));
application = NSApplication.sharedApplication();
isEmbedded = application.isRunning();
/*
* Feature in the Macintosh. On OS 10.2, it is necessary
* to explicitly check in with the Process Manager and set
* the current process to be the front process in order for
* windows to come to the front by default. The fix is call
* both GetCurrentProcess() and SetFrontProcess().
*
* NOTE: It is not actually necessary to use the process
* serial number returned by GetCurrentProcess() in the
* call to SetFrontProcess() (ie. kCurrentProcess can be
* used) but both functions must be called in order for
* windows to come to the front.
*/
int [] psn = new int [2];
if (OS.GetCurrentProcess (psn) == OS.noErr) {
int pid = OS.getpid ();
long /*int*/ ptr = getApplicationName().UTF8String();
if (ptr != 0) OS.CPSSetProcessName (psn, ptr);
if (!isBundled ()) {
if (OS.VERSION_MMB >= OS.VERSION_MMB (10, 9, 0)) {
application.setActivationPolicy (OS.NSApplicationActivationPolicyRegular);
NSRunningApplication.currentApplication().activateWithOptions (OS.NSApplicationActivateIgnoringOtherApps);
} else {
OS.TransformProcessType (psn, OS.kProcessTransformToForegroundApplication);
OS.SetFrontProcess (psn);
}
}
ptr = OS.getenv (ascii ("APP_ICON_" + pid));
if (ptr != 0) {
NSString path = NSString.stringWithUTF8String (ptr);
NSImage image = (NSImage) new NSImage().alloc();
image = image.initByReferencingFile(path);
dockImage = image;
application.setApplicationIconImage(image);
}
}
String className = "SWTApplication";
long /*int*/ cls;
if ((cls = OS.objc_lookUpClass (className)) == 0) {
Class clazz = getClass();
applicationCallback2 = new Callback(clazz, "applicationProc", 2);
long /*int*/ proc2 = applicationCallback2.getAddress();
if (proc2 == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
applicationCallback3 = new Callback(clazz, "applicationProc", 3);
long /*int*/ proc3 = applicationCallback3.getAddress();
if (proc3 == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
applicationCallback4 = new Callback(clazz, "applicationProc", 4);
long /*int*/ proc4 = applicationCallback4.getAddress();
if (proc4 == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
applicationCallback6 = new Callback(clazz, "applicationProc", 6);
long /*int*/ proc6 = applicationCallback6.getAddress();
if (proc6 == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
cls = OS.objc_allocateClassPair(OS.object_getClass(application.id), className, 0);
OS.class_addMethod(cls, OS.sel_sendEvent_, proc3, "@:@");
OS.class_addMethod(cls, OS.sel_nextEventMatchingMask_untilDate_inMode_dequeue_, proc6, "@:i@@B");
OS.class_addMethod(cls, OS.sel_isRunning, proc2, "@:");
OS.class_addMethod(cls, OS.sel_finishLaunching, proc2, "@:");
OS.objc_registerClassPair(cls);
}
applicationClass = OS.object_setClass(application.id, cls);
className = "SWTApplicationDelegate";
if (OS.objc_lookUpClass (className) == 0) {
long /*int*/ appProc3 = applicationCallback3.getAddress();
if (appProc3 == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
cls = OS.objc_allocateClassPair(OS.class_NSObject, className, 0);
long /*int*/ appProc4 = applicationCallback4.getAddress();
if (appProc4 == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
cls = OS.objc_allocateClassPair(OS.class_NSObject, className, 0);
OS.class_addMethod(cls, OS.sel_applicationWillFinishLaunching_, appProc3, "@:@");
OS.class_addMethod(cls, OS.sel_terminate_, appProc3, "@:@");
OS.class_addMethod(cls, OS.sel_orderFrontStandardAboutPanel_, appProc3, "@:@");
OS.class_addMethod(cls, OS.sel_hideOtherApplications_, appProc3, "@:@");
OS.class_addMethod(cls, OS.sel_hide_, appProc3, "@:@");
OS.class_addMethod(cls, OS.sel_unhideAllApplications_, appProc3, "@:@");
OS.class_addMethod(cls, OS.sel_applicationDidBecomeActive_, appProc3, "@:@");
OS.class_addMethod(cls, OS.sel_applicationDidResignActive_, appProc3, "@:@");
OS.class_addMethod(cls, OS.sel_applicationDockMenu_, appProc3, "@:@");
OS.class_addMethod(cls, OS.sel_application_openFile_, appProc4, "@:@@");
OS.class_addMethod(cls, OS.sel_application_openFiles_, appProc4, "@:@@");
OS.class_addMethod(cls, OS.sel_applicationShouldHandleReopen_hasVisibleWindows_, appProc4, "@:@B");
OS.class_addMethod(cls, OS.sel_applicationShouldTerminate_, appProc3, "@:@");
OS.objc_registerClassPair(cls);
}
int[] bufferMode = new int[1], bufferOptions = new int[1];
OS.GetSystemUIMode(bufferMode, bufferOptions);
systemUIMode = bufferMode[0];
systemUIOptions = bufferOptions[0];
}
void createMainMenu () {
NSString appName = getApplicationName();
NSString emptyStr = NSString.string();
NSMenu mainMenu = (NSMenu)new NSMenu().alloc();
mainMenu.initWithTitle(emptyStr);
NSMenuItem menuItem;
NSMenu appleMenu;
NSString format = NSString.stringWith("%@ %@"), title;
NSMenuItem appItem = menuItem = mainMenu.addItemWithTitle(emptyStr, 0, emptyStr);
appleMenu = (NSMenu)new NSMenu().alloc();
appleMenu.initWithTitle(emptyStr);
OS.objc_msgSend(application.id, OS.sel_registerName("setAppleMenu:"), appleMenu.id);
title = new NSString(OS.objc_msgSend(OS.class_NSString, OS.sel_stringWithFormat_, format.id, NSString.stringWith(SWT.getMessage("About")).id, appName.id));
menuItem = appleMenu.addItemWithTitle(title, OS.sel_orderFrontStandardAboutPanel_, emptyStr);
menuItem.setTarget(applicationDelegate);
appleMenu.addItem(NSMenuItem.separatorItem());
title = NSString.stringWith(SWT.getMessage("Preferences..."));
menuItem = appleMenu.addItemWithTitle(title, 0, NSString.stringWith(","));
/*
* Through the magic of nib decompilation, the prefs item must have a tag of 42
* or else the AWT won't be able to find it.
*/
menuItem.setTag(42);
appleMenu.addItem(NSMenuItem.separatorItem());
title = NSString.stringWith(SWT.getMessage("Services"));
menuItem = appleMenu.addItemWithTitle(title, 0, emptyStr);
NSMenu servicesMenu = (NSMenu)new NSMenu().alloc();
servicesMenu.initWithTitle(emptyStr);
appleMenu.setSubmenu(servicesMenu, menuItem);
servicesMenu.release();
application.setServicesMenu(servicesMenu);
appleMenu.addItem(NSMenuItem.separatorItem());
title = new NSString(OS.objc_msgSend(OS.class_NSString, OS.sel_stringWithFormat_, format.id, NSString.stringWith(SWT.getMessage("Hide")).id, appName.id));
menuItem = appleMenu.addItemWithTitle(title, OS.sel_hide_, NSString.stringWith("h"));
menuItem.setTarget(applicationDelegate);
title = NSString.stringWith(SWT.getMessage("Hide Others"));
menuItem = appleMenu.addItemWithTitle(title, OS.sel_hideOtherApplications_, NSString.stringWith("h"));
menuItem.setKeyEquivalentModifierMask(OS.NSCommandKeyMask | OS.NSAlternateKeyMask);
menuItem.setTarget(applicationDelegate);
title = NSString.stringWith(SWT.getMessage("Show All"));
menuItem = appleMenu.addItemWithTitle(title, OS.sel_unhideAllApplications_, emptyStr);
menuItem.setTarget(applicationDelegate);
appleMenu.addItem(NSMenuItem.separatorItem());
title = new NSString(OS.objc_msgSend(OS.class_NSString, OS.sel_stringWithFormat_, format.id, NSString.stringWith(SWT.getMessage("Quit")).id, appName.id));
menuItem = appleMenu.addItemWithTitle(title, OS.sel_applicationShouldTerminate_, NSString.stringWith("q"));
menuItem.setTarget(applicationDelegate);
mainMenu.setSubmenu(appleMenu, appItem);
appleMenu.release();
application.setMainMenu(mainMenu);
mainMenu.release();
}
NSMutableArray currentTouches() {
synchronized (Device.class) {
if (currentTouches == null) {
currentTouches = (NSMutableArray) new NSMutableArray().alloc();
currentTouches = currentTouches.initWithCapacity(5);
}
}
return currentTouches;
}
long /*int*/ cursorSetProc (long /*int*/ id, long /*int*/ sel) {
if (lockCursor) {
if (currentControl != null) {
Cursor cursor = currentControl.findCursor ();
if (cursor != null && cursor.handle.id != id) return 0;
}
}
OS.call (oldCursorSetProc, id, sel);
return 0;
}
static void deregister (Display display) {
synchronized (Device.class) {
for (int i=0; i
* This method is called after release.
*
* @see Device#dispose
* @see #release
*/
@Override
protected void destroy () {
if (this == Default) Default = null;
deregister (this);
destroyDisplay ();
}
void destroyDisplay () {
application = null;
}
/**
* Causes the run() method of the runnable to
* be invoked by the user-interface thread just before the
* receiver is disposed. Specifying a null runnable
* is ignored.
*
* @param runnable code to run at dispose time.
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*/
public void disposeExec (Runnable runnable) {
checkDevice ();
if (disposeList == null) disposeList = new Runnable [4];
for (int i=0; iWidget subclass which
* represents it in the currently running application, if
* such exists, or null if no matching widget can be found.
*
* IMPORTANT: This method should not be called from
* application code. The arguments are platform-specific.
*
*
* @param handle the handle for the widget
* @return the SWT widget that the handle represents
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @noreference This method is not intended to be referenced by clients.
*/
public Widget findWidget (long /*int*/ handle) {
checkDevice ();
return getWidget (handle);
}
/**
* Given the operating system handle for a widget,
* and widget-specific id, returns the instance of
* the Widget subclass which represents
* the handle/id pair in the currently running application,
* if such exists, or null if no matching widget can be found.
*
* IMPORTANT: This method should not be called from
* application code. The arguments are platform-specific.
*
*
* @param handle the handle for the widget
* @param id the id for the subwidget (usually an item)
* @return the SWT widget that the handle/id pair represents
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @noreference This method is not intended to be referenced by clients.
*
* @since 3.1
*/
public Widget findWidget (long /*int*/ handle, long /*int*/ id) {
checkDevice ();
return getWidget (handle);
}
/**
* Given a widget and a widget-specific id, returns the
* instance of the Widget subclass which represents
* the widget/id pair in the currently running application,
* if such exists, or null if no matching widget can be found.
*
* @param widget the widget
* @param id the id for the subwidget (usually an item)
* @return the SWT subwidget (usually an item) that the widget/id pair represents
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @noreference This method is not intended to be referenced by clients.
*
* @since 3.3
*/
public Widget findWidget (Widget widget, long /*int*/ id) {
checkDevice ();
return null;
}
/**
* Returns the display which the given thread is the
* user-interface thread for, or null if the given thread
* is not a user-interface thread for any display. Specifying
* null as the thread will return null
* for the display.
*
* @param thread the user-interface thread
* @return the display for the given thread
*/
public static Display findDisplay (Thread thread) {
synchronized (Device.class) {
for (int i=0; iShell, or null
* if no shell belonging to the currently running application
* is active.
*
* @return the active shell or null
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*/
public Shell getActiveShell () {
checkDevice ();
NSWindow window = keyWindow != null ? keyWindow : application.keyWindow();
if (window != null) {
Widget widget = getWidget(window.contentView());
if (widget instanceof Shell) {
return (Shell)widget;
}
// Embedded shell test: If the NSWindow isn't an SWTWindow walk up the
// hierarchy from the hit view to see if some view maps to a Shell.
NSPoint windowLocation = window.mouseLocationOutsideOfEventStream();
NSView hitView = window.contentView().hitTest(windowLocation);
while (hitView != null) {
widget = getWidget(hitView.id);
if (widget instanceof Shell) {
break;
}
hitView = hitView.superview();
}
return (Shell)widget;
}
return null;
}
/**
* Returns a rectangle describing the receiver's size and location. Note that
* on multi-monitor systems the origin can be negative.
*
* @return the bounding rectangle
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*/
@Override
public Rectangle getBounds () {
checkDevice ();
NSArray screens = NSScreen.screens();
return getBounds (screens);
}
Rectangle getBounds (NSArray screens) {
NSScreen screen = new NSScreen(screens.objectAtIndex(0));
NSRect primaryFrame = screen.frame();
double /*float*/ minX = Float.MAX_VALUE, maxX = Float.MIN_VALUE;
double /*float*/ minY = Float.MAX_VALUE, maxY = Float.MIN_VALUE;
long /*int*/ count = screens.count();
for (int i = 0; i < count; i++) {
screen = new NSScreen(screens.objectAtIndex(i));
NSRect frame = screen.frame();
double /*float*/ x1 = frame.x, x2 = frame.x + frame.width;
double /*float*/ y1 = primaryFrame.height - frame.y, y2 = primaryFrame.height - (frame.y + frame.height);
if (x1 < minX) minX = x1;
if (x2 < minX) minX = x2;
if (x1 > maxX) maxX = x1;
if (x2 > maxX) maxX = x2;
if (y1 < minY) minY = y1;
if (y2 < minY) minY = y2;
if (y1 > maxY) maxY = y1;
if (y2 > maxY) maxY = y2;
}
return new Rectangle ((int)minX, (int)minY, (int)(maxX - minX), (int)(maxY - minY));
}
/**
* 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 Display getCurrent () {
return findDisplay (Thread.currentThread ());
}
int getCaretBlinkTime () {
// checkDevice ();
return blinkTime;
}
/**
* Returns a rectangle which describes the area of the
* receiver which is capable of displaying data.
*
* @return the client area
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @see #getBounds
*/
@Override
public Rectangle getClientArea () {
checkDevice ();
NSArray screens = NSScreen.screens();
if (screens.count() != 1) return getBounds (screens);
NSScreen screen = new NSScreen(screens.objectAtIndex(0));
NSRect frame = screen.frame();
NSRect visibleFrame = screen.visibleFrame();
double /*float*/ y = frame.height - (visibleFrame.y + visibleFrame.height);
return new Rectangle((int)visibleFrame.x, (int)y, (int)visibleFrame.width, (int)visibleFrame.height);
}
/**
* 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 or null
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*/
public Control getCursorControl () {
checkDevice();
return findControl(false);
}
/**
* Returns the location of the on-screen pointer relative
* to the top left corner of the screen.
*
* @return the cursor location
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*/
public Point getCursorLocation () {
checkDevice ();
NSPoint location = NSEvent.mouseLocation();
NSRect primaryFrame = getPrimaryFrame();
return new Point ((int) location.x, (int) (primaryFrame.height - location.y));
}
/**
* Returns an array containing the recommended cursor sizes.
*
* @return the array of cursor sizes
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @since 3.0
*/
public Point [] getCursorSizes () {
checkDevice ();
return new Point [] {new Point (16, 16)};
}
/**
* 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 Display getDefault () {
synchronized (Device.class) {
if (Default == null) Default = new Display ();
return Default;
}
}
/**
* Returns the application defined property of the receiver
* with the specified name, or null if it has not been set.
*
* Applications may have associated arbitrary objects with the
* receiver in this fashion. If the objects stored in the
* properties need to be notified when the display is disposed
* of, it is the application's responsibility to provide a
* disposeExec() handler which does so.
*
*
* @param key the name of the property
* @return the value of the property or null if it has not been set
*
* @exception IllegalArgumentException
*
ERROR_NULL_ARGUMENT - if the key is null
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @see #setData(String, Object)
* @see #disposeExec(Runnable)
*/
public Object getData (String key) {
checkDevice ();
if (key == null) error (SWT.ERROR_NULL_ARGUMENT);
if (keys == null) return null;
for (int i=0; idisplay specific data is a single,
* unnamed field that is stored with every display.
*
* Applications may put arbitrary objects in this field. If
* the object stored in the display specific data needs to
* be notified when the display is disposed of, it is the
* application's responsibility to provide a
* disposeExec() handler which does so.
*
*
* @return the display specific data
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @see #setData(Object)
* @see #disposeExec(Runnable)
*/
public Object getData () {
checkDevice ();
return data;
}
/**
* Returns the button dismissal alignment, one of 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 LEFT, the
* button ordering should be OK/CANCEL. When button dismissal alignment is RIGHT,
* the button ordering should be CANCEL/OK.
*
* @return the button dismissal order
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @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
* double click by the underlying operating system.
*
* @return the double click time
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*/
public int getDoubleClickTime () {
checkDevice ();
return OS.GetDblTime () * 1000 / 60;
}
/**
* 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 focus control or null
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*/
public Control getFocusControl () {
checkDevice ();
if (focusControl != null && !focusControl.isDisposed ()) {
return focusControl;
}
NSWindow window = keyWindow != null ? keyWindow : application.keyWindow();
return _getFocusControl(window);
}
Control _getFocusControl (NSWindow window) {
if (window != null) {
NSResponder responder = window.firstResponder();
if (responder != null && !responder.respondsToSelector(OS.sel_superview)) {
return null;
}
NSView view = new NSView(responder.id);
if (view != null) {
do {
Widget widget = GetWidget (view.id);
if (widget instanceof Control) {
return (Control)widget;
}
view = view.superview();
} while (view != null);
}
}
return null;
}
/**
* Returns true when the high contrast mode is enabled.
* Otherwise, false is returned.
*
* Note: This operation is a hint and is not supported on
* platforms that do not have this concept.
*
*
* @return the high contrast mode
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @since 3.0
*/
public boolean getHighContrast () {
checkDevice ();
return false;
}
/**
* Returns the maximum allowed depth of icons on this display, in bits per pixel.
* On some platforms, this may be different than the actual depth of the display.
*
* @return the maximum icon depth
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @see Device#getDepth
*/
public int getIconDepth () {
return getDepth ();
}
/**
* Returns an array containing the recommended icon sizes.
*
* @return the array of icon sizes
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @see Decorations#setImages(Image[])
*
* @since 3.0
*/
public Point [] getIconSizes () {
checkDevice ();
return new Point [] {
new Point (16, 16), new Point (32, 32),
new Point (64, 64), new Point (128, 128)};
}
int getLastEventTime () {
NSEvent event = application.currentEvent();
if (event == null) return 0;
double timestamp = event.timestamp() * 1000;
while (timestamp > 0x7FFFFFFF) {
timestamp -= 0x7FFFFFFF;
}
return (int)timestamp;
}
Menu [] getMenus (Decorations shell) {
if (menus == null) return new Menu [0];
int count = 0;
for (int i = 0; i < menus.length; i++) {
Menu menu = menus[i];
if (menu != null && menu.parent == shell) count++;
}
int index = 0;
Menu[] result = new Menu[count];
for (int i = 0; i < menus.length; i++) {
Menu menu = menus[i];
if (menu != null && menu.parent == shell) {
result[index++] = menu;
}
}
return result;
}
int getMessageCount () {
return synchronizer.getMessageCount ();
}
Dialog getModalDialog () {
return modalDialog;
}
NSPanel getModalPanel () {
return modalPanel;
}
/**
* Returns an array of monitors attached to the device.
*
* @return the array of monitors
*
* @since 3.0
*/
public Monitor [] getMonitors () {
checkDevice ();
NSArray screens = NSScreen.screens();
NSRect primaryFrame = new NSScreen(screens.objectAtIndex(0)).frame();
int count = (int)/*64*/screens.count();
Monitor [] monitors = new Monitor [count];
for (int i=0; i
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*/
public Shell [] getShells () {
checkDevice ();
NSArray windows = application.windows();
int index = 0;
Shell [] result = new Shell [(int)/*64*/windows.count()];
for (int i = 0; i < result.length; i++) {
NSWindow window = new NSWindow(windows.objectAtIndex(i));
Widget widget = getWidget(window.contentView());
if (widget instanceof Shell) {
result[index++] = (Shell)widget;
}
}
if (index == result.length) return result;
Shell [] newResult = new Shell [index];
System.arraycopy (result, 0, newResult, 0, index);
return newResult;
}
static boolean getSheetEnabled () {
return !"false".equals(System.getProperty("org.eclipse.swt.sheet"));
}
/**
* Gets the synchronizer used by the display.
*
* @return the receiver's synchronizer
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @since 3.4
*/
public Synchronizer getSynchronizer () {
checkDevice ();
return synchronizer;
}
/**
* Returns the thread that has invoked syncExec
* or null if no such runnable is currently being invoked by
* the user-interface thread.
*
* Note: If a runnable invoked by asyncExec is currently
* running, this method will return null.
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*/
public Thread getSyncThread () {
synchronized (Device.class) {
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 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
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @see SWT
*/
@Override
public Color getSystemColor (int id) {
checkDevice ();
Color color = getWidgetColor (id);
if (color != null) return color;
return super.getSystemColor (id);
}
Color getWidgetColor (int id) {
if (0 <= id && id < colors.length && colors [id] != null) {
return Color.cocoa_new (this, colors [id]);
}
return null;
}
double /*float*/ [] getWidgetColorRGB (int id) {
NSColor color = null;
switch (id) {
case SWT.COLOR_INFO_FOREGROUND: color = NSColor.blackColor (); break;
case SWT.COLOR_INFO_BACKGROUND: return
OS.VERSION_MMB >= OS.VERSION_MMB (10, 10, 0)
? new double /*float*/ [] {236/255f, 235/255f, 236/255f, 1}
: new double /*float*/ [] {.984f, .988f, 0.773f, 1};
case SWT.COLOR_TITLE_FOREGROUND: color = NSColor.windowFrameTextColor(); break;
case SWT.COLOR_TITLE_BACKGROUND: color = NSColor.alternateSelectedControlColor(); break;
case SWT.COLOR_TITLE_BACKGROUND_GRADIENT: color = NSColor.selectedControlColor(); break;
case SWT.COLOR_TITLE_INACTIVE_FOREGROUND: color = NSColor.disabledControlTextColor(); break;
case SWT.COLOR_TITLE_INACTIVE_BACKGROUND: color = NSColor.secondarySelectedControlColor(); break;
case SWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT: color = NSColor.secondarySelectedControlColor(); break;
case SWT.COLOR_WIDGET_DARK_SHADOW: color = NSColor.controlDarkShadowColor(); break;
case SWT.COLOR_WIDGET_NORMAL_SHADOW: color = NSColor.controlShadowColor(); break;
case SWT.COLOR_WIDGET_LIGHT_SHADOW: color = NSColor.controlHighlightColor(); break;
case SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW: color = NSColor.controlLightHighlightColor(); break;
case SWT.COLOR_WIDGET_BACKGROUND: color = NSColor.controlHighlightColor(); break;
case SWT.COLOR_WIDGET_FOREGROUND: color = NSColor.controlTextColor(); break;
case SWT.COLOR_WIDGET_BORDER: color = NSColor.blackColor (); break;
case SWT.COLOR_LIST_FOREGROUND: color = NSColor.textColor(); break;
case SWT.COLOR_LIST_BACKGROUND: color = NSColor.textBackgroundColor(); break;
case SWT.COLOR_LIST_SELECTION_TEXT: color = NSColor.selectedTextColor(); break;
case SWT.COLOR_LIST_SELECTION: color = NSColor.selectedTextBackgroundColor(); break;
case SWT.COLOR_LINK_FOREGROUND:
NSTextView textView = (NSTextView)new NSTextView().alloc();
textView.init ();
NSDictionary dict = textView.linkTextAttributes();
color = new NSColor(dict.valueForKey(OS.NSForegroundColorAttributeName));
textView.release ();
break;
}
return getNSColorRGB (color);
}
double /*float*/ [] getNSColorRGB (NSColor color) {
if (color == null) return null;
NSColorSpace colorSpace = color.colorSpace();
if (colorSpace == null || colorSpace.colorSpaceModel() != OS.NSRGBColorSpaceModel) {
color = color.colorUsingColorSpaceName(OS.NSDeviceRGBColorSpace);
}
if (color == null) return null;
double /*float*/[] components = new double /*float*/[(int)/*64*/color.numberOfComponents()];
color.getComponents(components);
return new double /*float*/ []{components[0], components[1], components[2], components[3]};
}
/**
* Returns the matching standard platform cursor for the given
* constant, which should be one of the cursor constants
* specified in class SWT. This cursor should
* not be free'd because it was allocated by the system,
* not the application. A value of 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 null
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @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];
}
NSImage getSystemImageForID(int osType) {
long /*int*/ iconRef[] = new long /*int*/ [1];
OS.GetIconRefFromTypeInfo(OS.kSystemIconsCreator, osType, 0, 0, 0, iconRef);
NSImage nsImage = (NSImage)new NSImage().alloc();
nsImage = nsImage.initWithIconRef(iconRef[0]);
/*
* Feature in Cocoa. GetIconRefFromTypeInfo returns a huge icon that scales well. Resize
* it to 32x32, which is what NSWorkspace does.
*/
NSSize size = new NSSize();
size.width = size.height = 32.0f;
nsImage.setSize(size);
nsImage.setScalesWhenResized(true);
return nsImage;
}
/**
* Returns the matching standard platform image for the given
* constant, which should be one of the icon constants
* specified in class SWT. This image should
* not be free'd because it was allocated by the system,
* not the application. A value of 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 null
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @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) {
checkDevice ();
switch(id) {
case SWT.ICON_ERROR: {
if (errorImage != null) return errorImage;
NSImage img = getSystemImageForID(OS.kAlertStopIcon);
return errorImage = Image.cocoa_new (this, SWT.ICON, img);
}
case SWT.ICON_INFORMATION:
case SWT.ICON_QUESTION:
case SWT.ICON_WORKING: {
if (infoImage != null) return infoImage;
NSImage img = getSystemImageForID(OS.kAlertNoteIcon);
return infoImage = Image.cocoa_new (this, SWT.ICON, img);
}
case SWT.ICON_WARNING: {
if (warningImage != null) return warningImage;
NSImage img = getSystemImageForID(OS.kAlertCautionIcon);
return warningImage = Image.cocoa_new (this, SWT.ICON, img);
}
}
return null;
}
/**
* Returns the single instance of the application menu bar, or
* null if there is no application menu bar for the platform.
*
* @return the application menu bar, or null
*
* @exception SWTException
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @since 3.7
*/
public Menu getMenuBar () {
checkDevice ();
if (appMenuBar != null) return appMenuBar;
appMenuBar = new Menu (this);
// the menubar will be updated when the Shell or the application activates.
return appMenuBar;
}
/**
* Returns the single instance of the system-provided menu for the application, or
* null on platforms where no menu is provided for the application.
*
* @return the system menu, or null
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @since 3.7
*/
public Menu getSystemMenu () {
checkDevice();
if (appMenu == null) {
NSMenu mainMenu = NSApplication.sharedApplication().mainMenu();
NSMenu nsAppMenu = mainMenu.itemAtIndex(0).submenu();
appMenu = new Menu(this, nsAppMenu);
// Create menu items that correspond to the NSMenuItems.
long /*int*/ nsCount = nsAppMenu.numberOfItems();
for (int j = 0; j < nsCount; j++) {
NSMenuItem currMenuItem = nsAppMenu.itemAtIndex(j);
new MenuItem(appMenu, currMenuItem);
}
}
return appMenu;
}
/**
* Returns the single instance of the system tray or null
* when there is no system tray available for the platform.
*
* @return the system tray or null
*
* @exception SWTException
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @since 3.0
*/
public Tray getSystemTray () {
checkDevice ();
if (tray != null) return tray;
return tray = new Tray (this, SWT.NONE);
}
/**
* Returns the single instance of the system taskBar or null
* when there is no system taskBar available for the platform.
*
* @return the system taskBar or null
*
* @exception SWTException
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @since 3.6
*/
public TaskBar getSystemTaskBar () {
checkDevice ();
if (taskBar != null) return taskBar;
taskBar = new TaskBar (this, SWT.NONE);
return taskBar;
}
/**
* Returns the user-interface thread for the receiver.
*
* @return the receiver's user-interface thread
*
* @exception SWTException
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*/
public Thread getThread () {
synchronized (Device.class) {
if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
return thread;
}
}
/**
* Returns a boolean indicating whether a touch-aware input device is
* attached to the system and is ready for use.
*
* @return true if a touch-aware input device is detected, or false otherwise
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @since 3.7
*/
public boolean getTouchEnabled() {
checkDevice();
// Gestures are available on OS X 10.5.3 and later. Touch events are only available on 10.6 and later.
return (OS.VERSION > 0x1053);
}
int getToolTipTime () {
checkDevice ();
//TODO get OS value (NSTooltipManager?)
return 560;
}
Widget getWidget (long /*int*/ id) {
return GetWidget (id);
}
static Widget GetWidget (long /*int*/ id) {
if (id == 0) return null;
long /*int*/ [] jniRef = new long /*int*/ [1];
long /*int*/ iVar = OS.object_getInstanceVariable(id, SWT_OBJECT, jniRef);
if (iVar == 0) {
if (dynamicObjectMap != null) {
NSObject key = new NSObject(id);
LONG dynJNIRef = (LONG) dynamicObjectMap.get(key);
if (dynJNIRef != null) jniRef[0] = dynJNIRef.value;
}
}
if (jniRef[0] == 0) return null;
return (Widget)OS.JNIGetObject(jniRef[0]);
}
Widget getWidget (NSView view) {
if (view == null) return null;
return getWidget(view.id);
}
boolean hasDefaultButton () {
NSArray windows = application.windows();
long /*int*/ count = windows.count();
for (int i = 0; i < count; i++) {
NSWindow window = new NSWindow(windows.objectAtIndex(i));
if (window.defaultButtonCell() != null) {
return true;
}
}
return false;
}
/**
* Initializes any internal resources needed by the
* device.
*
* IMPORTANT: This method is not part of the public
* API for 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.
*
*
* @param data the platform specific GC data
* @return the platform specific GC handle
*
* @exception SWTException
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
* @exception SWTError
*
ERROR_NO_HANDLES if a handle could not be obtained for gc creation
*
*
* @noreference This method is not intended to be referenced by clients.
*/
@Override
public long /*int*/ internal_new_GC (GCData data) {
if (isDisposed()) error(SWT.ERROR_DEVICE_DISPOSED);
if (screenWindow == null) {
NSWindow window = (NSWindow) new NSWindow ().alloc ();
NSRect rect = new NSRect();
window = window.initWithContentRect(rect, OS.NSBorderlessWindowMask, OS.NSBackingStoreBuffered, false);
window.setReleasedWhenClosed(false);
screenWindow = window;
}
NSGraphicsContext context = screenWindow.graphicsContext();
// NSAffineTransform transform = NSAffineTransform.transform();
// NSSize size = handle.size();
// transform.translateXBy(0, size.height);
// transform.scaleXBy(1, -1);
// transform.set();
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.background = getSystemColor(SWT.COLOR_WHITE).handle;
data.foreground = getSystemColor(SWT.COLOR_BLACK).handle;
data.font = getSystemFont();
}
return context.id;
}
/**
* Invokes platform specific functionality to dispose a GC handle.
*
* IMPORTANT: This method is not part of the public
* API for 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.
*
*
* @param hDC the platform specific GC handle
* @param data the platform specific GC data
*
* @noreference This method is not intended to be referenced by clients.
*/
@Override
public void internal_dispose_GC (long /*int*/ hDC, GCData data) {
if (isDisposed()) error(SWT.ERROR_DEVICE_DISPOSED);
}
boolean isBundled () {
NSBundle mainBundle = NSBundle.mainBundle();
if (mainBundle != null) {
NSDictionary info = mainBundle.infoDictionary();
if (info != null) {
return NSString.stringWith("APPL").isEqual(info.objectForKey(NSString.stringWith("CFBundlePackageType"))); //$NON-NLS-1$ $NON-NLS-2$
}
}
return false;
}
static boolean isValidClass (Class clazz) {
String name = clazz.getName ();
int index = name.lastIndexOf ('.');
return name.substring (0, index + 1).equals (PACKAGE_PREFIX);
}
boolean isValidThread () {
return thread == Thread.currentThread ();
}
/**
* Generate a low level system event.
*
* 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.
*
* Note that this operation can fail when the operating system
* fails to generate the event for any reason. For example,
* this can happen when there is no such key or mouse button
* or when the system event queue is full.
*
*
* Event Types:
*
KeyDown, KeyUp
*
The following fields in the Event apply:
*
*
(in) type KeyDown or KeyUp
*
Either one of:
*
(in) character a character that corresponds to a keyboard key
*
(in) keyCode the key code of the key that was typed,
* as defined by the key code constants in class SWT
*
*
MouseDown, MouseUp
*
The following fields in the Event apply:
*
*
(in) type MouseDown or MouseUp
*
(in) button the button that is pressed or released
*
*
MouseMove
*
The following fields in the Event apply:
*
*
(in) type MouseMove
*
(in) x the x coordinate to move the mouse pointer to in screen coordinates
*
(in) y the y coordinate to move the mouse pointer to in screen coordinates
*
*
MouseWheel
*
The following fields in the Event apply:
*
*
(in) type MouseWheel
*
(in) detail either SWT.SCROLL_LINE or SWT.SCROLL_PAGE
*
(in) count the number of lines or pages to scroll
*
*
*
* @param event the event to be generated
*
* @return true if the event was generated or false otherwise
*
* @exception IllegalArgumentException
*
ERROR_NULL_ARGUMENT - if the event is null
*
* @exception SWTException
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @since 3.0
*
*/
public boolean post(Event event) {
synchronized (Device.class) {
if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
if (event == null) error (SWT.ERROR_NULL_ARGUMENT);
long /*int*/ eventRef = 0;
long /*int*/ eventSource = OS.CGEventSourceCreate(OS.kCGEventSourceStateHIDSystemState);
if (eventSource == 0) return false;
boolean returnValue = false;
int deadKeyState[] = new int[1];
int type = event.type;
switch (type) {
case SWT.KeyDown:
case SWT.KeyUp: {
short vKey = (short)Display.untranslateKey (event.keyCode);
if (vKey == 0) {
long /*int*/ uchrPtr = 0;
long /*int*/ currentKbd = OS.TISCopyCurrentKeyboardInputSource();
long /*int*/ uchrCFData = OS.TISGetInputSourceProperty(currentKbd, OS.kTISPropertyUnicodeKeyLayoutData());
if (uchrCFData == 0) return false;
uchrPtr = OS.CFDataGetBytePtr(uchrCFData);
if (uchrPtr == 0) return false;
if (OS.CFDataGetLength(uchrCFData) == 0) return false;
int maxStringLength = 256;
vKey = -1;
char [] output = new char [maxStringLength];
int [] actualStringLength = new int [1];
for (short i = 0 ; i <= 0x7F ; i++) {
deadKeyState[0] = 0;
OS.UCKeyTranslate (uchrPtr, i, (short)(type == SWT.KeyDown ? OS.kUCKeyActionDown : OS.kUCKeyActionUp), 0, OS.LMGetKbdType(), 0, deadKeyState, maxStringLength, actualStringLength, output);
if (output[0] == event.character) {
vKey = i;
break;
}
}
if (vKey == -1) {
for (short i = 0 ; i <= 0x7F ; i++) {
deadKeyState[0] = 0;
OS.UCKeyTranslate (uchrPtr, i, (short)(type == SWT.KeyDown ? OS.kUCKeyActionDown : OS.kUCKeyActionUp), (OS.shiftKey >> 8) & 0xFF, OS.LMGetKbdType(), 0, deadKeyState, maxStringLength, actualStringLength, output);
if (output[0] == event.character) {
vKey = i;
break;
}
}
}
}
/**
* Bug(?) in UCKeyTranslate: If event.keyCode doesn't map to a valid SWT constant and event.characer is 0 we still need to post an event.
* In Carbon, KeyTranslate eventually found a key that generated 0 but UCKeyTranslate never generates 0.
* When that happens, post an event from key 127, which does nothing.
*/
if (vKey == -1 && event.character == 0) {
vKey = 127;
}
if (vKey != -1) {
if (OS.VERSION < 0x1060) {
returnValue = OS.CGPostKeyboardEvent((short)0, vKey, type == SWT.KeyDown) == OS.noErr;
} else {
eventRef = OS.CGEventCreateKeyboardEvent(eventSource, vKey, type == SWT.KeyDown);
}
}
break;
}
case SWT.MouseDown:
case SWT.MouseMove:
case SWT.MouseUp: {
CGPoint mouseCursorPosition = new CGPoint ();
if (type == SWT.MouseMove) {
mouseCursorPosition.x = event.x;
mouseCursorPosition.y = event.y;
eventRef = OS.CGEventCreateMouseEvent(eventSource, OS.kCGEventMouseMoved, mouseCursorPosition, 0);
} else {
NSPoint nsCursorPosition = NSEvent.mouseLocation();
NSRect primaryFrame = getPrimaryFrame();
mouseCursorPosition.x = nsCursorPosition.x;
mouseCursorPosition.y = (int) (primaryFrame.height - nsCursorPosition.y);
int eventType = 0;
// SWT buttons are 1-based: 1,2,3,4,5; CG buttons are 0 based: 0,2,1,3,4
int cgButton;
switch (event.button) {
case 1:
eventType = (event.type == SWT.MouseDown ? OS.kCGEventLeftMouseDown : OS.kCGEventLeftMouseUp);
cgButton = 0;
break;
case 2:
eventType = (event.type == SWT.MouseDown ? OS.kCGEventOtherMouseDown : OS.kCGEventOtherMouseUp);
cgButton = 2;
break;
case 3:
eventType = (event.type == SWT.MouseDown ? OS.kCGEventRightMouseDown : OS.kCGEventRightMouseUp);
cgButton = 1;
break;
default:
eventType = (event.type == SWT.MouseDown ? OS.kCGEventOtherMouseDown : OS.kCGEventOtherMouseUp);
cgButton = event.button - 1;
break;
}
if (cgButton >= 0) {
eventRef = OS.CGEventCreateMouseEvent(eventSource, eventType, mouseCursorPosition, cgButton);
}
}
break;
}
case SWT.MouseWheel: {
// CG does not support scrolling a page at a time. Technically that is a page up/down, but not a scroll-wheel event.
eventRef = OS.CGEventCreateScrollWheelEvent(eventSource, OS.kCGScrollEventUnitLine, 1, event.count);
break;
}
}
// returnValue is true if we called CGPostKeyboardEvent (10.5 only).
if (returnValue == false) {
if (eventRef != 0) {
OS.CGEventPost(OS.kCGHIDEventTap, eventRef);
OS.CFRelease(eventRef);
try {
Thread.sleep(1);
} catch (Exception e) {
}
returnValue = true;
}
}
if (eventSource != 0) OS.CFRelease(eventSource);
return returnValue;
}
}
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;
}
/**
* Maps a point from one coordinate system to another.
* When the control is null, coordinates are mapped to
* the display.
*
* 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.
*
*
* @param from the source Control or null
* @param to the destination Control or null
* @param point to be mapped
* @return point with mapped coordinates
*
* @exception IllegalArgumentException
*
ERROR_NULL_ARGUMENT - if the point is null
*
ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @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.
*
* 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.
*
*
* @param from the source Control or null
* @param to the destination Control or null
* @param x coordinates to be mapped
* @param y coordinates to be mapped
* @return point with mapped coordinates
*
* @exception IllegalArgumentException
*
ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @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 == to) return point;
NSPoint pt = new NSPoint();
pt.x = x;
pt.y = y;
NSWindow fromWindow = from != null ? from.view.window() : null;
NSWindow toWindow = to != null ? to.view.window() : null;
if (toWindow != null && fromWindow != null && toWindow.id == fromWindow.id) {
if (!from.view.isFlipped ()) {
pt.y = from.view.bounds().height - pt.y;
}
pt = from.view.convertPoint_toView_(pt, to.view);
if (!to.view.isFlipped ()) {
pt.y = to.view.bounds().height - pt.y;
}
} else {
NSRect primaryFrame = getPrimaryFrame();
if (from != null) {
NSView view = from.eventView ();
if (!view.isFlipped ()) {
pt.y = view.bounds().height - pt.y;
}
pt = view.convertPoint_toView_(pt, null);
pt = fromWindow.convertBaseToScreen(pt);
pt.y = primaryFrame.height - pt.y;
}
if (to != null) {
NSView view = to.eventView ();
pt.y = primaryFrame.height - pt.y;
pt = toWindow.convertScreenToBase(pt);
pt = view.convertPoint_fromView_(pt, null);
if (!view.isFlipped ()) {
pt.y = view.bounds().height - pt.y;
}
}
}
point.x = (int)pt.x;
point.y = (int)pt.y;
return point;
}
/**
* Maps a point from one coordinate system to another.
* When the control is null, coordinates are mapped to
* the display.
*
* 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.
*
*
* @param from the source Control or null
* @param to the destination Control or null
* @param rectangle to be mapped
* @return rectangle with mapped coordinates
*
* @exception IllegalArgumentException
*
ERROR_NULL_ARGUMENT - if the rectangle is null
*
ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @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);
}
/**
* Maps a point from one coordinate system to another.
* When the control is null, coordinates are mapped to
* the display.
*
* 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.
*
*
* @param from the source Control or null
* @param to the destination 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
*
ERROR_INVALID_ARGUMENT - if the Control from or the Control to have been disposed
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @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 rectangle = new Rectangle (x, y, width, height);
if (from == to) return rectangle;
NSPoint pt = new NSPoint();
pt.x = x;
pt.y = y;
NSWindow fromWindow = from != null ? from.view.window() : null;
NSWindow toWindow = to != null ? to.view.window() : null;
if (toWindow != null && fromWindow != null && toWindow.id == fromWindow.id) {
if (!from.view.isFlipped ()) {
pt.y = from.view.bounds().height - pt.y;
}
pt = from.view.convertPoint_toView_(pt, to.view);
if (!to.view.isFlipped ()) {
pt.y = to.view.bounds().height - pt.y;
}
} else {
NSRect primaryFrame = getPrimaryFrame();
if (from != null) {
NSView view = from.eventView ();
if (!view.isFlipped ()) {
pt.y = view.bounds().height - pt.y;
}
pt = view.convertPoint_toView_(pt, null);
pt = fromWindow.convertBaseToScreen(pt);
pt.y = primaryFrame.height - pt.y;
}
if (to != null) {
NSView view = to.eventView ();
pt.y = primaryFrame.height - pt.y;
pt = toWindow.convertScreenToBase(pt);
pt = view.convertPoint_fromView_(pt, null);
if (!view.isFlipped ()) {
pt.y = view.bounds().height - pt.y;
}
}
}
rectangle.x = (int)pt.x;
rectangle.y = (int)pt.y;
return rectangle;
}
long /*int*/ observerProc (long /*int*/ observer, long /*int*/ activity, long /*int*/ info) {
switch ((int)/*64*/activity) {
case OS.kCFRunLoopBeforeWaiting:
if (runAsyncMessages) {
if (runAsyncMessages (false)) wakeThread ();
}
break;
}
return 0;
}
boolean performKeyEquivalent(NSWindow window, NSEvent nsEvent) {
if (modalDialog == null) return false;
if (nsEvent.type() != OS.NSKeyDown) return false;
int stateMask = 0;
long /*int*/ selector = 0;
long /*int*/ modifierFlags = nsEvent.modifierFlags();
if ((modifierFlags & OS.NSAlternateKeyMask) != 0) stateMask |= SWT.ALT;
if ((modifierFlags & OS.NSShiftKeyMask) != 0) stateMask |= SWT.SHIFT;
if ((modifierFlags & OS.NSControlKeyMask) != 0) stateMask |= SWT.CONTROL;
if ((modifierFlags & OS.NSCommandKeyMask) != 0) stateMask |= SWT.COMMAND;
if (stateMask == SWT.COMMAND) {
short keyCode = nsEvent.keyCode ();
switch (keyCode) {
case 7: /* X */
selector = OS.sel_cut_;
break;
case 8: /* C */
selector = OS.sel_copy_;
break;
case 9: /* V */
selector = OS.sel_paste_;
break;
case 0: /* A */
selector = OS.sel_selectAll_;
break;
}
if (selector != 0) {
NSApplication.sharedApplication().sendAction(selector, null, NSApplication.sharedApplication());
return true;
}
}
return false;
}
/**
* Reads an event from the operating system's event queue,
* dispatches it appropriately, and returns true
* if there is potentially more work to do, or false
* if the caller can sleep until another event is placed on
* the event queue.
*
* In addition to checking the system event queue, this method also
* checks if any inter-thread messages (created by syncExec()
* or asyncExec()) are waiting to be processed, and if
* so handles them before returning.
*
*
* @return false if the caller can sleep upon return from this method
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
ERROR_FAILED_EXEC - if an exception occurred while running an inter-thread message
*
*
* @see #sleep
* @see #wake
*/
public boolean readAndDispatch () {
checkDevice ();
if (sendEventCount == 0 && loopCount == poolCount - 1 && Callback.getEntryCount () == 0) removePool ();
addPool ();
runSkin ();
runDeferredLayouts ();
loopCount++;
boolean events = false;
try {
events |= runSettings ();
events |= runTimers ();
events |= runContexts ();
events |= runPopups ();
NSEvent event = application.nextEventMatchingMask(OS.NSAnyEventMask, null, OS.NSDefaultRunLoopMode, true);
if (event != null) {
events = true;
application.sendEvent(event);
}
events |= runPaint ();
events |= runDeferredEvents ();
if (!events) {
events = isDisposed () || runAsyncMessages (false);
}
} finally {
removePool ();
loopCount--;
if (sendEventCount == 0 && loopCount == poolCount && Callback.getEntryCount () == 0) addPool ();
}
return events;
}
static void register (Display display) {
synchronized (Device.class) {
for (int i=0; i
* Disposes all shells which are currently open on the display.
* After this method has been invoked, all related related shells
* will answer true when sent the message
* isDisposed().
*
* 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 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 destroy.
*
* This method is called before destroy.
*
* @see Device#dispose
* @see #destroy
*/
@Override
protected void release () {
disposing = true;
sendEvent (SWT.Dispose, new Event ());
Shell [] shells = getShells ();
for (int i=0; i 1) {
menubar.removeItemAtIndex(count - 1);
count--;
}
}
if (dynamicObjectMap != null) {
dynamicObjectMap.clear();
dynamicObjectMap = null;
}
// The autorelease pool is cleaned up when we call NSApplication.terminate().
if (application != null && applicationClass != 0) {
OS.object_setClass (application.id, applicationClass);
}
application = null;
applicationClass = 0;
if (runLoopObserver != 0) {
OS.CFRunLoopObserverInvalidate (runLoopObserver);
OS.CFRelease (runLoopObserver);
}
runLoopObserver = 0;
if (observerCallback != null) observerCallback.dispose();
observerCallback = null;
}
void removeContext (GCData context) {
if (contexts == null) return;
int count = 0;
for (int i = 0; i < contexts.length; i++) {
if (contexts[i] != null) {
if (contexts [i] == context) {
contexts[i] = null;
} else {
count++;
}
}
}
if (count == 0) contexts = null;
}
/**
* Removes the listener from the collection of listeners who will
* be notified when an event of the given type occurs anywhere in
* a widget. The event type is one of the event constants defined
* in class SWT.
*
* @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
*
ERROR_NULL_ARGUMENT - if the listener is null
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @see Listener
* @see SWT
* @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;
}
/**
* Removes the listener from the collection of listeners who will
* be notified when an event of the given type occurs. The event type
* is one of the event constants defined in class SWT.
*
* @param eventType the type of event to listen for
* @param listener the listener which should no longer be notified
*
* @exception IllegalArgumentException
*
ERROR_NULL_ARGUMENT - if the listener is null
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @see Listener
* @see SWT
* @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);
}
Widget removeWidget (NSObject view) {
if (view == null) return null;
long /*int*/ [] jniRef = new long /*int*/ [1];
long /*int*/ iVar = OS.object_getInstanceVariable(view.id, SWT_OBJECT, jniRef);
if (iVar == 0) {
if (dynamicObjectMap != null) {
LONG dynJNIRef = (LONG) dynamicObjectMap.get(view);
if (dynJNIRef != null) jniRef[0] = dynJNIRef.value;
dynamicObjectMap.remove(view);
}
}
if (jniRef[0] == 0) return null;
Widget widget = (Widget)OS.JNIGetObject(jniRef[0]);
OS.object_setInstanceVariable(view.id, SWT_OBJECT, 0);
return widget;
}
void removeMenu (Menu menu) {
if (menus == null) return;
for (int i = 0; i < menus.length; i++) {
if (menus [i] == menu) {
menus[i] = null;
break;
}
}
}
void removePool () {
NSAutoreleasePool pool = pools [poolCount - 1];
pools [--poolCount] = null;
if (poolCount == 0) {
NSMutableDictionary dictionary = NSThread.currentThread().threadDictionary();
dictionary.removeObjectForKey(NSString.stringWith("SWT_NSAutoreleasePool"));
}
pool.release ();
}
void removePopup (Menu menu) {
if (popups == null) return;
for (int i=0; i= 10.10 and a SWT TrayItem (NSStatusItem) is present in the menubar,
* changing the OSX appearance or changing the configuration of attached displays causes the textColor and textBackground color to change.
* This sets the text foreground of several widgets as white and hence text is invisible. The workaround is to detect this case and prevent
* the update of LIST_FOREGROUND, LIST_BACKGROUND and COLOR_WIDGET_FOREGROUND colors.
*/
if (OS.VERSION_MMB >= OS.VERSION_MMB (10, 10, 0) && tray != null && tray.itemCount > 0) {
/*
* osxMode will be "Dark" when in OSX dark mode. Otherwise, it'll be null.
*/
NSString osxMode = NSUserDefaults.standardUserDefaults ().stringForKey (NSString.stringWith ("AppleInterfaceStyle"));
if (osxMode != null && "Dark".equals (osxMode.getString ())) {
ignoreColorChange = true;
}
}
initColors (ignoreColorChange);
sendEvent (SWT.Settings, null);
Shell [] shells = getShells ();
for (int i=0; i 0) {
Widget [] oldSkinWidgets = skinList;
int count = skinCount;
skinList = new Widget[GROW_SIZE];
skinCount = 0;
if (eventTable != null && eventTable.hooks(SWT.Skin)) {
for (int i = 0; i < count; i++) {
Widget widget = oldSkinWidgets[i];
if (widget != null && !widget.isDisposed()) {
widget.state &= ~Widget.SKIN_NEEDED;
oldSkinWidgets[i] = null;
Event event = new Event ();
event.widget = widget;
sendEvent (SWT.Skin, event);
}
}
}
return true;
}
return false;
}
boolean runTimers () {
if (timerList == null) return false;
boolean result = false;
for (int i=0; i
* The application name can be used in several ways,
* depending on the platform and tools being used.
* Accessibility tools could ask for the application
* name. On Windows, if the application name is set
* to any value other than "SWT" (case insensitive),
* it is used to set the application user model ID
* which is used by the OS for taskbar grouping.
* @see AppUserModelID (Windows)
*
* Specifying null for the name clears it.
*
*
* @param name the new app name or null
*/
public static void setAppName (String name) {
APP_NAME = name;
}
/**
* Sets the application version to the argument.
*
* @param version the new app version
*
* @since 3.6
*/
public static void setAppVersion (String version) {
APP_VERSION = version;
}
//TODO use custom timer instead of timerExec
NSPoint hoverLastLocation;
Runnable hoverTimer = new Runnable () {
@Override
public void run () {
if (currentControl != null && !currentControl.isDisposed()) {
currentControl.sendMouseEvent (null, SWT.MouseHover, trackingControl != null && !trackingControl.isDisposed());
}
}
};
//TODO - use custom timer instead of timerExec
Runnable caretTimer = new Runnable () {
@Override
public void run () {
if (currentCaret != null) {
if (currentCaret == null || currentCaret.isDisposed()) return;
if (currentCaret.blinkCaret ()) {
int blinkRate = currentCaret.blinkRate;
if (blinkRate != 0) timerExec (blinkRate, this);
} else {
currentCaret = null;
}
}
}
};
//TODO - use custom timer instead of timerExec
Runnable defaultButtonTimer = new Runnable() {
@Override
public void run() {
if (isDisposed ()) return;
Shell shell = getActiveShell();
if (shell != null && !shell.isDisposed()) {
Button defaultButton = shell.defaultButton;
if (defaultButton != null && !defaultButton.isDisposed()) {
NSView view = defaultButton.view;
view.display();
}
}
if (isDisposed ()) return;
if (hasDefaultButton()) timerExec(DEFAULT_BUTTON_INTERVAL, this);
}
};
void setCurrentCaret (Caret caret) {
currentCaret = caret;
int blinkRate = currentCaret != null ? currentCaret.blinkRate : -1;
timerExec (blinkRate, caretTimer);
}
void setCursor (Control control) {
Cursor cursor = null;
if (control != null && !control.isDisposed()) cursor = control.findCursor ();
if (cursor == null) {
NSWindow window = application.keyWindow();
if (window != null) {
if (window.areCursorRectsEnabled ()) {
window.disableCursorRects ();
window.enableCursorRects ();
}
return;
}
cursor = getSystemCursor (SWT.CURSOR_ARROW);
}
lockCursor = false;
cursor.handle.set ();
lockCursor = true;
}
/**
* Sets the location of the on-screen pointer relative to the top left corner
* of the screen. Note: It is typically considered bad practice for a
* program to move the on-screen pointer location.
*
* @param x the new x coordinate for the cursor
* @param y the new y coordinate for the cursor
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @since 2.1
*/
public void setCursorLocation (int x, int y) {
checkDevice ();
Event e = new Event();
e.type = SWT.MouseMove;
e.x = x;
e.y = y;
post(e);
}
/**
* Sets the location of the on-screen pointer relative to the top left corner
* of the screen. Note: It is typically considered bad practice for a
* program to move the on-screen pointer location.
*
* @param point new position
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_NULL_ARGUMENT - if the point is null
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @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.
*
* 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
* disposeExec() handler which does so.
*
*
* @param key the name of the property
* @param value the new value for the property
*
* @exception IllegalArgumentException
*
ERROR_NULL_ARGUMENT - if the key is null
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @see #getData(String)
* @see #disposeExec(Runnable)
*/
public void setData (String key, Object value) {
checkDevice ();
if (key == null) error (SWT.ERROR_NULL_ARGUMENT);
if (key.equals (ADD_WIDGET_KEY)) {
Object [] data = (Object [])value;
NSObject object = (NSObject)data [0];
Widget widget = (Widget)data [1];
if (widget == null) {
removeWidget (object);
} else {
addWidget (object, widget);
}
}
if (key.equals(SET_MODAL_DIALOG)) {
setModalDialog (value != null ? (Dialog) value : null);
}
if (key.equals (MOZILLA_RUNNING)) {
mozillaRunning = ((Boolean)value).booleanValue ();
}
if (key.equals (LOCK_CURSOR)) {
lockCursor = ((Boolean)value).booleanValue ();
}
if (key.equals(RUN_AWT_INVOKE_LATER_KEY)) {
if (value != null) {
value = new Boolean (runAWTInvokeLater());
}
}
/* 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 1) {
menubar.removeItemAtIndex(count - 1);
count--;
}
//set parent of each item to NULL and add them to menubar
if (menu != null) {
MenuItem[] items = menu.getItems();
for (int i = 0; i < items.length; i++) {
MenuItem item = items[i];
NSMenuItem nsItem = item.nsItem;
/*
* Bug in cocoa. Cocoa does not seem to detect the help
* menu for languages other than english. The fix is to detect
* it ourselves.
*/
if (OS.VERSION >= 0x1060) {
NSMenu submenu = nsItem.submenu();
if (submenu != null && submenu.title().getString().equals(SWT.getMessage("SWT_Help"))) {
application.setHelpMenu(submenu);
}
}
nsItem.setMenu(null);
menubar.addItem(nsItem);
/*
* Bug in Cocoa: Calling NSMenuItem.setEnabled() for menu item of a menu bar only
* works when the menu bar is the current menu bar. The underline OS menu does get
* enabled/disable when that menu is set later on. The fix is to toggle the
* item enabled state to force the underline menu to be updated.
*/
boolean enabled = menu.getEnabled () && item.getEnabled ();
nsItem.setEnabled(!enabled);
nsItem.setEnabled(enabled);
}
}
}
void setModalDialog (Dialog modalDialog) {
setModalDialog(modalDialog, null);
}
void setModalDialog (Dialog modalDialog, NSPanel panel) {
this.modalDialog = modalDialog;
this.modalPanel = panel;
}
void setModalShell (Shell shell) {
if (modalShells == null) modalShells = new Shell [4];
int index = 0, length = modalShells.length;
while (index < length) {
if (modalShells [index] == shell) return;
if (modalShells [index] == null) break;
index++;
}
if (index == length) {
Shell [] newModalShells = new Shell [length + 4];
System.arraycopy (modalShells, 0, newModalShells, 0, length);
modalShells = newModalShells;
}
modalShells [index] = shell;
Shell [] shells = getShells ();
for (int i=0; idisplay specific data is a single,
* unnamed field that is stored with every display.
*
* 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
* disposeExec() handler which does so.
*
*
* @param data the new display specific data
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @see #getData()
* @see #disposeExec(Runnable)
*/
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
*
ERROR_NULL_ARGUMENT - if the synchronizer is null
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
ERROR_FAILED_EXEC - if an exception occurred while running an inter-thread message
*
*/
public void setSynchronizer (Synchronizer synchronizer) {
checkDevice ();
if (synchronizer == null) error (SWT.ERROR_NULL_ARGUMENT);
if (synchronizer == this.synchronizer) return;
Synchronizer oldSynchronizer;
synchronized (Device.class) {
oldSynchronizer = this.synchronizer;
this.synchronizer = synchronizer;
}
if (oldSynchronizer != null) {
oldSynchronizer.moveAllEventsTo(synchronizer);
}
}
/**
* Causes the user-interface thread to 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 true if an event requiring dispatching was placed on the queue.
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @see #wake
*/
public boolean sleep () {
checkDevice ();
if (getMessageCount () != 0) return true;
sendPreExternalEventDispatchEvent ();
try {
addPool();
allowTimers = runAsyncMessages = false;
NSRunLoop.currentRunLoop().runMode(OS.NSDefaultRunLoopMode, NSDate.distantFuture());
allowTimers = runAsyncMessages = true;
} finally {
removePool();
}
sendPostExternalEventDispatchEvent ();
return true;
}
int sourceProc (int info) {
return 0;
}
/**
* Causes the 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. Specifying null
* as the runnable simply wakes the user-interface thread.
*
* Note that at the time the runnable is invoked, widgets
* that have the receiver as their display may have been
* disposed. Therefore, it is necessary to check for this
* case inside the runnable before accessing the widget.
*
*
* @param runnable code to run on the user-interface thread or null
*
* @exception SWTException
*
ERROR_FAILED_EXEC - if an exception occurred when executing the runnable
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @see #asyncExec
*/
public void syncExec (Runnable runnable) {
Synchronizer synchronizer;
synchronized (Device.class) {
if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
synchronizer = this.synchronizer;
}
synchronizer.syncExec (runnable);
}
/**
* Causes the 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.
*
* Note that at the time the runnable is invoked, widgets
* that have the receiver as their display may have been
* disposed. Therefore, it is necessary to check for this
* case inside the runnable before accessing the widget.
*
*
* @param milliseconds the delay before running the runnable
* @param runnable code to run on the user-interface thread
*
* @exception IllegalArgumentException
*
ERROR_NULL_ARGUMENT - if the runnable is null
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @see #asyncExec
*/
public void timerExec (int milliseconds, Runnable runnable) {
checkDevice ();
//TODO - remove a timer, reschedule a timer not tested
if (runnable == null) error (SWT.ERROR_NULL_ARGUMENT);
if (timerList == null) timerList = new Runnable [4];
if (nsTimers == null) nsTimers = new NSTimer [4];
int index = 0;
while (index < timerList.length) {
if (timerList [index] == runnable) break;
index++;
}
if (index != timerList.length) {
NSTimer timer = nsTimers [index];
if (timer == null) {
timerList [index] = null;
} else {
if (milliseconds < 0) {
timer.invalidate();
timer.release();
timerList [index] = null;
nsTimers [index] = null;
} else {
timer.setFireDate(NSDate.dateWithTimeIntervalSinceNow (milliseconds / 1000.0));
}
return;
}
}
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;
NSTimer [] newTimerIds = new NSTimer [nsTimers.length + 4];
System.arraycopy (nsTimers, 0, newTimerIds, 0, nsTimers.length);
nsTimers = newTimerIds;
}
NSNumber userInfo = NSNumber.numberWithInt(index);
NSTimer timer = NSTimer.scheduledTimerWithTimeInterval(milliseconds / 1000.0, timerDelegate, OS.sel_timerProc_, userInfo, false);
NSRunLoop runLoop = NSRunLoop.currentRunLoop();
runLoop.addTimer(timer, OS.NSModalPanelRunLoopMode);
runLoop.addTimer(timer, OS.NSEventTrackingRunLoopMode);
timer.retain();
if (timer != null) {
nsTimers [index] = timer;
timerList [index] = runnable;
}
}
long /*int*/ timerProc (long /*int*/ id, long /*int*/ sel, long /*int*/ timerID) {
NSTimer timer = new NSTimer (timerID);
try {
NSNumber number = new NSNumber(timer.userInfo());
int index = number.intValue();
if (timerList == null) return 0;
if (0 <= index && index < timerList.length) {
if (allowTimers) {
Runnable runnable = timerList [index];
timerList [index] = null;
nsTimers [index] = null;
if (runnable != null) runnable.run ();
} else {
nsTimers [index] = null;
wakeThread ();
}
}
} finally {
timer.invalidate();
timer.release();
}
return 0;
}
/**
* Forces all outstanding paint requests for the display
* to be processed before this method returns.
*
* @exception SWTException
*
ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @see Control#update()
*/
public void update () {
checkDevice ();
Shell [] shells = getShells ();
for (int i=0; isleeping,
* causes it to be awakened and start running again. Note that this
* method may be called from any thread.
*
* @exception SWTException
*
ERROR_DEVICE_DISPOSED - if the receiver has been disposed
*
*
* @see #sleep
*/
public void wake () {
synchronized (Device.class) {
if (isDisposed ()) error (SWT.ERROR_DEVICE_DISPOSED);
if (thread == Thread.currentThread ()) return;
wakeThread ();
}
}
void wakeThread () {
//new pool?
NSObject object = new NSObject().alloc().init();
object.performSelectorOnMainThread(OS.sel_release, null, false);
}
Control findControl (boolean checkTrim) {
return findControl(checkTrim, null);
}
Control findControl (boolean checkTrim, NSView[] hitView) {
NSView view = null;
NSPoint screenLocation = NSEvent.mouseLocation();
long /*int*/ hitWindowNumber = 0;
if (OS.VERSION >= 0x1060) {
hitWindowNumber = NSWindow.windowNumberAtPoint(screenLocation, 0);
} else {
long /*int*/ outWindow[] = new long /*int*/ [1];
OS.FindWindow ((long /*int*/)screenLocation.x, (long /*int*/)(getPrimaryFrame().height - screenLocation.y), outWindow);
if (outWindow[0] != 0) {
hitWindowNumber = OS.HIWindowGetCGWindowID(outWindow[0]);
}
}
NSWindow window = application.windowWithWindowNumber(hitWindowNumber);
if (window != null) {
NSView contentView = window.contentView();
if (contentView != null) contentView = contentView.superview();
if (contentView != null) {
NSPoint location = window.convertScreenToBase(screenLocation);
view = contentView.hitTest (location);
if (view == null && !checkTrim) {
view = contentView;
}
}
}
Control control = null;
if (view != null) {
do {
Widget widget = getWidget (view);
if (widget instanceof Control) {
control = (Control)widget;
break;
}
view = view.superview();
} while (view != null);
}
if (checkTrim) {
if (control != null && control.isTrim (view)) control = null;
}
if (control != null && hitView != null) hitView[0] = view;
return control;
}
void finishLaunching (long /*int*/ id, long /*int*/ sel) {
/*
* [NSApplication finishLaunching] cannot run multiple times otherwise
* multiple main menus are added.
*/
if (launched) return;
launched = true;
objc_super super_struct = new objc_super();
super_struct.receiver = id;
super_struct.super_class = OS.objc_msgSend(id, OS.sel_superclass);
OS.objc_msgSendSuper(super_struct, sel);
}
void applicationDidBecomeActive (long /*int*/ id, long /*int*/ sel, long /*int*/ notification) {
NSWindow keyWindow = application.keyWindow();
if (keyWindow != null) {
keyWindow.orderFrontRegardless();
} else {
setMenuBar (menuBar);
}
checkFocus();
checkEnterExit(findControl(true), null, false);
}
void applicationDidResignActive (long /*int*/ id, long /*int*/ sel, long /*int*/ notification) {
checkFocus();
checkEnterExit(null, null, false);
}
long /*int*/ applicationNextEventMatchingMask (long /*int*/ id, long /*int*/ sel, long /*int*/ mask, long /*int*/ expiration, long /*int*/ mode, long /*int*/ dequeue) {
if (dequeue != 0 && trackingControl != null && !trackingControl.isDisposed()) runDeferredEvents();
sendPreExternalEventDispatchEvent();
try {
objc_super super_struct = new objc_super();
super_struct.receiver = id;
super_struct.super_class = OS.objc_msgSend(id, OS.sel_superclass);
long /*int*/ result = OS.objc_msgSendSuper(super_struct, sel, mask, expiration, mode, dequeue != 0);
if (result != 0) {
/*
* Feature of Cocoa. When an NSComboBox's items list is visible it runs an event
* loop that will close the list in response to a processed NSApplicationDefined
* event.
*
* Mozilla-style Browsers are a common source of NSApplicationDefined events that
* will cause this to happen, which is not desirable in the context of SWT. The
* workaround is to detect this case and to not return the event that would trigger
* this to happen.
*/
if (dequeue != 0 && currentCombo != null && !currentCombo.isDisposed()) {
NSEvent nsEvent = new NSEvent(result);
if (mozillaRunning) {
if (nsEvent.type() == OS.NSApplicationDefined) {
return 0;
}
}
if (nsEvent.type() == OS.NSKeyDown) {
currentCombo.sendTrackingKeyEvent(nsEvent, SWT.KeyDown);
}
}
if (dequeue != 0 && trackingControl != null && !trackingControl.isDisposed()) {
applicationSendTrackingEvent(new NSEvent(result), trackingControl);
}
}
return result;
} finally {
sendPostExternalEventDispatchEvent();
}
}
void applicationSendTrackingEvent (NSEvent nsEvent, Control trackingControl) {
int type = (int)/*64*/nsEvent.type();
boolean runEnterExit = false;
Control runEnterExitControl = null;
switch (type) {
case OS.NSLeftMouseDown:
case OS.NSRightMouseDown:
case OS.NSOtherMouseDown:
clickCount = (int)(clickCountButton == nsEvent.buttonNumber() ? nsEvent.clickCount() : 1);
clickCountButton = (int)nsEvent.buttonNumber();
trackingControl.sendMouseEvent (nsEvent, SWT.MouseDown, true);
break;
case OS.NSLeftMouseUp:
case OS.NSRightMouseUp:
case OS.NSOtherMouseUp:
runEnterExit = true;
runEnterExitControl = findControl(true);
Control control = trackingControl;
this.trackingControl = null;
if (clickCount == 2) {
control.sendMouseEvent (nsEvent, SWT.MouseDoubleClick, false);
}
if (!control.isDisposed()) control.sendMouseEvent (nsEvent, SWT.MouseUp, false);
break;
case OS.NSLeftMouseDragged:
case OS.NSRightMouseDragged:
case OS.NSOtherMouseDragged:
runEnterExit = true;
runEnterExitControl = trackingControl;
//FALL THROUGH
case OS.NSMouseMoved:
trackingControl.sendMouseEvent (nsEvent, SWT.MouseMove, true);
break;
}
if (runEnterExit) {
if (runEnterExitControl == null || !runEnterExitControl.isDisposed()) checkEnterExit (runEnterExitControl, nsEvent, false);
}
}
void applicationSendEvent (long /*int*/ id, long /*int*/ sel, long /*int*/ event) {
NSEvent nsEvent = new NSEvent(event);
NSWindow window = nsEvent.window ();
if (performKeyEquivalent(window, nsEvent)) return;
int type = (int)/*64*/nsEvent.type ();
boolean activate = false, down = false;
switch (type) {
case OS.NSLeftMouseDown:
case OS.NSRightMouseDown:
case OS.NSOtherMouseDown:
activate = down = true;
case OS.NSLeftMouseUp:
case OS.NSRightMouseUp:
case OS.NSOtherMouseUp:
activate = true;
case OS.NSLeftMouseDragged:
case OS.NSRightMouseDragged:
case OS.NSOtherMouseDragged:
case OS.NSMouseMoved:
case OS.NSMouseEntered:
case OS.NSMouseExited:
case OS.NSKeyDown:
case OS.NSKeyUp:
case OS.NSScrollWheel:
// TODO: Add touch detection here...
if (window != null) {
Shell shell = (Shell) getWidget (window.id);
if (shell != null) {
Shell modalShell = shell.getModalShell ();
if (modalShell != null) {
if (activate) {
if (application.isActive()) {
modalShell.window.orderFrontRegardless();
} else {
application.activateIgnoringOtherApps(true);
}
if (down) {
NSRect rect = window.contentView().frame();
NSPoint pt = window.convertBaseToScreen(nsEvent.locationInWindow());
if (OS.NSPointInRect(pt, rect)) beep ();
}
}
return;
}
}
}
break;
}
if (type != OS.NSAppKitDefined) sendEvent = true;
/*
* Feature in Cocoa. The help key triggers context-sensitive help but doesn't get forwarded to the window as a key event.
* If the event is destined for the key window, is the help key, and is an NSKeyDown, send it directly to the window first.
*/
if (window != null && window.isKeyWindow() && nsEvent.type() == OS.NSKeyDown && (nsEvent.modifierFlags() & OS.NSHelpKeyMask) != 0) {
window.sendEvent(nsEvent);
}
/*
* Feature in Cocoa. NSKeyUp events are not delivered to the window if the command key is down.
* If the event is destined for the key window, and it's a key up and the command key is down, send it directly to the window.
*/
if (window != null && window.isKeyWindow() && nsEvent.type() == OS.NSKeyUp && (nsEvent.modifierFlags() & OS.NSCommandKeyMask) != 0) {
window.sendEvent(nsEvent);
} else {
objc_super super_struct = new objc_super ();
super_struct.receiver = id;
super_struct.super_class = OS.objc_msgSend (id, OS.sel_superclass);
OS.objc_msgSendSuper (super_struct, sel, event);
}
if (type != OS.NSAppKitDefined) sendEvent = false;
}
void applicationWillFinishLaunching (long /*int*/ id, long /*int*/ sel, long /*int*/ notification) {
boolean loaded = false;
/*
* Bug in AWT: If the AWT starts up first when the VM was started on the first thread it assumes that
* a Carbon-based SWT will be used, so it calls NSApplicationLoad(). This causes the Carbon menu
* manager to create an application menu that isn't accessible via NSMenu. It is, however, accessible
* via the Carbon menu manager, so find and delete the menu items it added.
*
* Note that this code will continue to work if Apple does change this. GetIndMenuWithCommandID will
* return a non-zero value indicating failure, which we ignore.
*/
if (isEmbedded) {
long /*int*/ outMenu [] = new long /*int*/ [1];
short outIndex[] = new short[1];
int status = OS.GetIndMenuItemWithCommandID(0, OS.kHICommandHide, 1, outMenu, outIndex);
if (status == 0) OS.DeleteMenuItem(outMenu[0], outIndex[0]);
status = OS.GetIndMenuItemWithCommandID(0, OS.kHICommandHideOthers, 1, outMenu, outIndex);
if (status == 0) OS.DeleteMenuItem(outMenu[0], outIndex[0]);
status = OS.GetIndMenuItemWithCommandID(0, OS.kHICommandShowAll, 1, outMenu, outIndex);
if (status == 0) OS.DeleteMenuItem(outMenu[0], outIndex[0]);
status = OS.GetIndMenuItemWithCommandID(0, OS.kHICommandQuit, 1, outMenu, outIndex);
if (status == 0) OS.DeleteMenuItem(outMenu[0], outIndex[0]);
status = OS.GetIndMenuItemWithCommandID(0, OS.kHICommandServices, 1, outMenu, outIndex);
if (status == 0) OS.DeleteMenuItem(outMenu[0], outIndex[0]);
}
/*
* Get the default locale's language, and then the display name of the language. Some Mac OS X localizations use the
* display name of the language, but many use the ISO two-char abbreviation instead.
*/
Locale loc = Locale.getDefault();
String languageISOValue = loc.getLanguage();
NSLocale englishLocale = (NSLocale) new NSLocale().alloc();
englishLocale = new NSLocale(englishLocale.initWithLocaleIdentifier(NSString.stringWith("en_US")));
NSString languageDisplayName = englishLocale.displayNameForKey(OS.NSLocaleLanguageCode, NSString.stringWith(languageISOValue));
if (englishLocale != null) englishLocale.release();
/* To find the nib look for each of these paths, in order, until one is found:
* /System/Library/..../Resources/.lproj/DefaultApp.nib
* /System/Library/..../Resources/.lproj/DefaultApp.nib
* /System/Library/..../Resources/.lproj/DefaultApp.nib
* /System/Library/..../Resources/English.lproj/DefaultApp.nib.
*/
NSBundle bundle = NSBundle.bundleWithIdentifier(NSString.stringWith("com.apple.JavaVM"));
NSDictionary dict = NSDictionary.dictionaryWithObject(applicationDelegate, NSString.stringWith("NSOwner"));
NSString path = bundle.pathForResource(NSString.stringWith("DefaultApp"), NSString.stringWith("nib"), null, languageDisplayName);
if (path == null) path = bundle.pathForResource(NSString.stringWith("DefaultApp"), NSString.stringWith("nib"), null, NSString.stringWith(languageISOValue));
if (path == null) path = bundle.pathForResource(NSString.stringWith("DefaultApp"), NSString.stringWith("nib"));
if (!loaded) loaded = path != null && NSBundle.loadNibFile(path, dict, 0);
if (!loaded) {
NSString resourcePath = bundle.resourcePath();
path = resourcePath != null ? resourcePath.stringByAppendingString(NSString.stringWith("/English.lproj/DefaultApp.nib")) : null;
loaded = path != null && NSBundle.loadNibFile(path, dict, 0);
}
if (!loaded) {
path = NSString.stringWith(System.getProperty("java.home") + "/../Resources/English.lproj/DefaultApp.nib");
loaded = path != null && NSBundle.loadNibFile(path, dict, 0);
}
if (!loaded) {
createMainMenu();
}
//replace %@ with application name
NSMenu mainmenu = application.mainMenu();
NSMenuItem appitem = mainmenu.itemAtIndex(0);
if (appitem != null) {
NSString name = getApplicationName();
NSString match = NSString.stringWith("%@");
appitem.setTitle(name);
NSMenu sm = appitem.submenu();
NSArray ia = sm.itemArray();
for(int i = 0; i < ia.count(); i++) {
NSMenuItem ni = new NSMenuItem(ia.objectAtIndex(i));
NSString title = ni.title().stringByReplacingOccurrencesOfString(match, name);
ni.setTitle(title);
long /*int*/ newTag = 0;
switch(i) {
case 0:
newTag = SWT.ID_ABOUT;
break;
case 2:
newTag = SWT.ID_PREFERENCES;
break;
case 6:
newTag = SWT.ID_HIDE;
break;
case 7:
newTag = SWT.ID_HIDE_OTHERS;
break;
case 8:
newTag = SWT.ID_SHOW_ALL;
break;
case 10:
newTag = SWT.ID_QUIT;
break;
}
if (newTag != 0) ni.setTag(newTag);
}
long /*int*/ quitIndex = sm.indexOfItemWithTarget(applicationDelegate, OS.sel_terminate_);
if (quitIndex != -1) {
NSMenuItem quitItem = sm.itemAtIndex(quitIndex);
quitItem.setAction(OS.sel_applicationShouldTerminate_);
}
}
}
static long /*int*/ applicationProc(long /*int*/ id, long /*int*/ sel) {
//TODO optimize getting the display
Display display = getCurrent ();
if (display == null) {
objc_super super_struct = new objc_super ();
super_struct.receiver = id;
super_struct.super_class = OS.objc_msgSend (id, OS.sel_superclass);
return OS.objc_msgSendSuper (super_struct, sel);
}
if (sel == OS.sel_isRunning) {
// #245724: [NSApplication isRunning] must return true to allow the AWT to load correctly.
return display.isDisposed() ? 0 : 1;
}
if (sel == OS.sel_finishLaunching) {
display.finishLaunching (id, sel);
}
return 0;
}
static long /*int*/ applicationProc(long /*int*/ id, long /*int*/ sel, long /*int*/ arg0) {
//TODO optimize getting the display
Display display = getCurrent ();
if (display == null && id != applicationDelegate.id) {
objc_super super_struct = new objc_super ();
super_struct.receiver = id;
super_struct.super_class = OS.objc_msgSend (id, OS.sel_superclass);
return OS.objc_msgSendSuper (super_struct, sel, arg0);
}
if (currAppDelegate != null) {
if (currAppDelegate.respondsToSelector(sel)) OS.objc_msgSend(currAppDelegate.id, sel, arg0);
}
NSApplication application = display.application;
if (sel == OS.sel_sendEvent_) {
display.applicationSendEvent (id, sel, arg0);
} else if (sel == OS.sel_applicationWillFinishLaunching_) {
display.applicationWillFinishLaunching(id, sel, arg0);
} else if (sel == OS.sel_applicationShouldTerminate_) {
int returnVal = OS.NSTerminateCancel;
if (!display.disposing) {
Event event = new Event ();
display.sendEvent (SWT.Close, event);
if (event.doit) {
display.dispose();
returnVal = OS.NSTerminateNow;
}
}
return returnVal;
} else if (sel == OS.sel_orderFrontStandardAboutPanel_) {
// application.orderFrontStandardAboutPanel(application);
} else if (sel == OS.sel_hideOtherApplications_) {
application.hideOtherApplications(application);
} else if (sel == OS.sel_hide_) {
application.hide(application);
} else if (sel == OS.sel_unhideAllApplications_) {
application.unhideAllApplications(application);
} else if (sel == OS.sel_applicationDidBecomeActive_) {
display.applicationDidBecomeActive(id, sel, arg0);
} else if (sel == OS.sel_applicationDidResignActive_) {
display.applicationDidResignActive(id, sel, arg0);
} else if (sel == OS.sel_applicationDockMenu_) {
TaskBar taskbar = display.taskBar;
if (taskbar != null && taskbar.itemCount != 0) {
TaskItem item = taskbar.getItem(null);
if (item != null) {
Menu menu = item.getMenu();
if (menu != null && !menu.isDisposed()) {
return menu.nsMenu.id;
}
}
}
}
return 0;
}
static long /*int*/ applicationProc(long /*int*/ id, long /*int*/ sel, long /*int*/ arg0, long /*int*/ arg1) {
Display display = getCurrent();
if (display == null && id != applicationDelegate.id) {
objc_super super_struct = new objc_super ();
super_struct.receiver = id;
super_struct.super_class = OS.objc_msgSend (id, OS.sel_superclass);
return OS.objc_msgSendSuper (super_struct, sel, arg0, arg1);
}
// Forward to the AWT, if necessary.
if (currAppDelegate != null) {
if (currAppDelegate.respondsToSelector(sel)) OS.objc_msgSend(currAppDelegate.id, sel, arg0, arg1);
}
if (sel == OS.sel_application_openFile_) {
String file = new NSString(arg1).getString();
Event event = new Event();
event.text = file;
display.sendEvent(SWT.OpenDocument, event);
return 1;
} else if (sel == OS.sel_application_openFiles_) {
NSArray files = new NSArray(arg1);
long /*int*/ count = files.count();
for (int i=0; i