|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package sun.awt; |
|
|
|
import java.awt.*; |
|
import static java.awt.RenderingHints.*; |
|
import java.awt.dnd.*; |
|
import java.awt.dnd.peer.DragSourceContextPeer; |
|
import java.awt.peer.*; |
|
import java.awt.event.WindowEvent; |
|
import java.awt.event.KeyEvent; |
|
import java.awt.image.*; |
|
import java.awt.TrayIcon; |
|
import java.awt.SystemTray; |
|
import java.awt.event.InputEvent; |
|
import java.io.File; |
|
import java.io.IOException; |
|
import java.io.InputStream; |
|
import java.net.URL; |
|
import java.util.*; |
|
import java.util.concurrent.TimeUnit; |
|
import java.util.concurrent.locks.Condition; |
|
import java.util.concurrent.locks.Lock; |
|
import java.util.concurrent.locks.ReentrantLock; |
|
|
|
import sun.awt.datatransfer.DataTransferer; |
|
import sun.security.util.SecurityConstants; |
|
import sun.util.logging.PlatformLogger; |
|
import sun.misc.SoftCache; |
|
import sun.font.FontDesignMetrics; |
|
import sun.awt.im.InputContext; |
|
import sun.awt.image.*; |
|
import sun.net.util.URLUtil; |
|
import sun.security.action.GetPropertyAction; |
|
import sun.security.action.GetBooleanAction; |
|
import java.lang.reflect.InvocationTargetException; |
|
import java.security.AccessController; |
|
|
|
public abstract class SunToolkit extends Toolkit |
|
implements WindowClosingSupport, WindowClosingListener, |
|
ComponentFactory, InputMethodSupport, KeyboardFocusManagerPeerProvider { |
|
|
|
// 8014718: logging has been removed from SunToolkit |
|
|
|
|
|
static { |
|
if (AccessController.doPrivileged(new GetBooleanAction("sun.awt.nativedebug"))) { |
|
DebugSettings.init(); |
|
} |
|
touchKeyboardAutoShowIsEnabled = Boolean.valueOf( |
|
AccessController.doPrivileged(new GetPropertyAction( |
|
"awt.touchKeyboardAutoShowIsEnabled", "true"))); |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static final int GRAB_EVENT_MASK = 0x80000000; |
|
|
|
|
|
*/ |
|
private static final String POST_EVENT_QUEUE_KEY = "PostEventQueue"; |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected static int numberOfButtons = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public final static int MAX_BUTTONS_SUPPORTED = 20; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private static void initEQ(AppContext appContext) { |
|
EventQueue eventQueue; |
|
|
|
String eqName = System.getProperty("AWT.EventQueueClass", |
|
"java.awt.EventQueue"); |
|
|
|
try { |
|
eventQueue = (EventQueue)Class.forName(eqName).newInstance(); |
|
} catch (Exception e) { |
|
e.printStackTrace(); |
|
System.err.println("Failed loading " + eqName + ": " + e); |
|
eventQueue = new EventQueue(); |
|
} |
|
appContext.put(AppContext.EVENT_QUEUE_KEY, eventQueue); |
|
|
|
PostEventQueue postEventQueue = new PostEventQueue(eventQueue); |
|
appContext.put(POST_EVENT_QUEUE_KEY, postEventQueue); |
|
} |
|
|
|
public SunToolkit() { |
|
} |
|
|
|
public boolean useBufferPerWindow() { |
|
return false; |
|
} |
|
|
|
public abstract WindowPeer createWindow(Window target) |
|
throws HeadlessException; |
|
|
|
public abstract FramePeer createFrame(Frame target) |
|
throws HeadlessException; |
|
|
|
public abstract FramePeer createLightweightFrame(LightweightFrame target) |
|
throws HeadlessException; |
|
|
|
public abstract DialogPeer createDialog(Dialog target) |
|
throws HeadlessException; |
|
|
|
public abstract ButtonPeer createButton(Button target) |
|
throws HeadlessException; |
|
|
|
public abstract TextFieldPeer createTextField(TextField target) |
|
throws HeadlessException; |
|
|
|
public abstract ChoicePeer createChoice(Choice target) |
|
throws HeadlessException; |
|
|
|
public abstract LabelPeer createLabel(Label target) |
|
throws HeadlessException; |
|
|
|
public abstract ListPeer createList(java.awt.List target) |
|
throws HeadlessException; |
|
|
|
public abstract CheckboxPeer createCheckbox(Checkbox target) |
|
throws HeadlessException; |
|
|
|
public abstract ScrollbarPeer createScrollbar(Scrollbar target) |
|
throws HeadlessException; |
|
|
|
public abstract ScrollPanePeer createScrollPane(ScrollPane target) |
|
throws HeadlessException; |
|
|
|
public abstract TextAreaPeer createTextArea(TextArea target) |
|
throws HeadlessException; |
|
|
|
public abstract FileDialogPeer createFileDialog(FileDialog target) |
|
throws HeadlessException; |
|
|
|
public abstract MenuBarPeer createMenuBar(MenuBar target) |
|
throws HeadlessException; |
|
|
|
public abstract MenuPeer createMenu(Menu target) |
|
throws HeadlessException; |
|
|
|
public abstract PopupMenuPeer createPopupMenu(PopupMenu target) |
|
throws HeadlessException; |
|
|
|
public abstract MenuItemPeer createMenuItem(MenuItem target) |
|
throws HeadlessException; |
|
|
|
public abstract CheckboxMenuItemPeer createCheckboxMenuItem( |
|
CheckboxMenuItem target) |
|
throws HeadlessException; |
|
|
|
public abstract DragSourceContextPeer createDragSourceContextPeer( |
|
DragGestureEvent dge) |
|
throws InvalidDnDOperationException; |
|
|
|
public abstract TrayIconPeer createTrayIcon(TrayIcon target) |
|
throws HeadlessException, AWTException; |
|
|
|
public abstract SystemTrayPeer createSystemTray(SystemTray target); |
|
|
|
public abstract boolean isTraySupported(); |
|
|
|
@SuppressWarnings("deprecation") |
|
public abstract FontPeer getFontPeer(String name, int style); |
|
|
|
public abstract RobotPeer createRobot(Robot target, GraphicsDevice screen) |
|
throws AWTException; |
|
|
|
public abstract KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() |
|
throws HeadlessException; |
|
|
|
/** |
|
* The AWT lock is typically only used on Unix platforms to synchronize |
|
* access to Xlib, OpenGL, etc. However, these methods are implemented |
|
* in SunToolkit so that they can be called from shared code (e.g. |
|
* from the OGL pipeline) or from the X11 pipeline regardless of whether |
|
* XToolkit or MToolkit is currently in use. There are native macros |
|
* (such as AWT_LOCK) defined in awt.h, so if the implementation of these |
|
* methods is changed, make sure it is compatible with the native macros. |
|
* |
|
* Note: The following methods (awtLock(), awtUnlock(), etc) should be |
|
* used in place of: |
|
* synchronized (getAWTLock()) { |
|
* ... |
|
* } |
|
* |
|
* By factoring these methods out specially, we are able to change the |
|
* implementation of these methods (e.g. use more advanced locking |
|
* mechanisms) without impacting calling code. |
|
* |
|
* Sample usage: |
|
* private void doStuffWithXlib() { |
|
* assert !SunToolkit.isAWTLockHeldByCurrentThread(); |
|
* SunToolkit.awtLock(); |
|
* try { |
|
* ... |
|
* XlibWrapper.XDoStuff(); |
|
* } finally { |
|
* SunToolkit.awtUnlock(); |
|
* } |
|
* } |
|
*/ |
|
|
|
private static final ReentrantLock AWT_LOCK = new ReentrantLock(); |
|
private static final Condition AWT_LOCK_COND = AWT_LOCK.newCondition(); |
|
|
|
public static final void awtLock() { |
|
AWT_LOCK.lock(); |
|
} |
|
|
|
public static final boolean awtTryLock() { |
|
return AWT_LOCK.tryLock(); |
|
} |
|
|
|
public static final void awtUnlock() { |
|
AWT_LOCK.unlock(); |
|
} |
|
|
|
public static final void awtLockWait() |
|
throws InterruptedException |
|
{ |
|
AWT_LOCK_COND.await(); |
|
} |
|
|
|
public static final void awtLockWait(long timeout) |
|
throws InterruptedException |
|
{ |
|
AWT_LOCK_COND.await(timeout, TimeUnit.MILLISECONDS); |
|
} |
|
|
|
public static final void awtLockNotify() { |
|
AWT_LOCK_COND.signal(); |
|
} |
|
|
|
public static final void awtLockNotifyAll() { |
|
AWT_LOCK_COND.signalAll(); |
|
} |
|
|
|
public static final boolean isAWTLockHeldByCurrentThread() { |
|
return AWT_LOCK.isHeldByCurrentThread(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static AppContext createNewAppContext() { |
|
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); |
|
return createNewAppContext(threadGroup); |
|
} |
|
|
|
static final AppContext createNewAppContext(ThreadGroup threadGroup) { |
|
// Create appContext before initialization of EventQueue, so all |
|
// the calls to AppContext.getAppContext() from EventQueue ctor |
|
|
|
AppContext appContext = new AppContext(threadGroup); |
|
initEQ(appContext); |
|
|
|
return appContext; |
|
} |
|
|
|
static void wakeupEventQueue(EventQueue q, boolean isShutdown){ |
|
AWTAccessor.getEventQueueAccessor().wakeup(q, isShutdown); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected static Object targetToPeer(Object target) { |
|
if (target != null && !GraphicsEnvironment.isHeadless()) { |
|
return AWTAutoShutdown.getInstance().getPeer(target); |
|
} |
|
return null; |
|
} |
|
|
|
protected static void targetCreatedPeer(Object target, Object peer) { |
|
if (target != null && peer != null && |
|
!GraphicsEnvironment.isHeadless()) |
|
{ |
|
AWTAutoShutdown.getInstance().registerPeer(target, peer); |
|
} |
|
} |
|
|
|
protected static void targetDisposedPeer(Object target, Object peer) { |
|
if (target != null && peer != null && |
|
!GraphicsEnvironment.isHeadless()) |
|
{ |
|
AWTAutoShutdown.getInstance().unregisterPeer(target, peer); |
|
} |
|
} |
|
|
|
// Maps from non-Component/MenuComponent to AppContext. |
|
|
|
private static final Map<Object, AppContext> appContextMap = |
|
Collections.synchronizedMap(new WeakHashMap<Object, AppContext>()); |
|
|
|
|
|
|
|
|
|
*/ |
|
private static boolean setAppContext(Object target, |
|
AppContext context) { |
|
if (target instanceof Component) { |
|
AWTAccessor.getComponentAccessor(). |
|
setAppContext((Component)target, context); |
|
} else if (target instanceof MenuComponent) { |
|
AWTAccessor.getMenuComponentAccessor(). |
|
setAppContext((MenuComponent)target, context); |
|
} else { |
|
return false; |
|
} |
|
return true; |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
private static AppContext getAppContext(Object target) { |
|
if (target instanceof Component) { |
|
return AWTAccessor.getComponentAccessor(). |
|
getAppContext((Component)target); |
|
} else if (target instanceof MenuComponent) { |
|
return AWTAccessor.getMenuComponentAccessor(). |
|
getAppContext((MenuComponent)target); |
|
} else { |
|
return null; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static AppContext targetToAppContext(Object target) { |
|
if (target == null) { |
|
return null; |
|
} |
|
AppContext context = getAppContext(target); |
|
if (context == null) { |
|
// target is not a Component/MenuComponent, try the |
|
|
|
context = appContextMap.get(target); |
|
} |
|
return context; |
|
} |
|
|
|
/** |
|
* Sets the synchronous status of focus requests on lightweight |
|
* components in the specified window to the specified value. |
|
* If the boolean parameter is <code>true</code> then the focus |
|
* requests on lightweight components will be performed |
|
* synchronously, if it is <code>false</code>, then asynchronously. |
|
* By default, all windows have their lightweight request status |
|
* set to asynchronous. |
|
* <p> |
|
* The application can only set the status of lightweight focus |
|
* requests to synchronous for any of its windows if it doesn't |
|
* perform focus transfers between different heavyweight containers. |
|
* In this case the observable focus behaviour is the same as with |
|
* asynchronous status. |
|
* <p> |
|
* If the application performs focus transfer between different |
|
* heavyweight containers and sets the lightweight focus request |
|
* status to synchronous for any of its windows, then further focus |
|
* behaviour is unspecified. |
|
* <p> |
|
* @param w window for which the lightweight focus request status |
|
* should be set |
|
* @param status the value of lightweight focus request status |
|
*/ |
|
|
|
public static void setLWRequestStatus(Window changed,boolean status){ |
|
AWTAccessor.getWindowAccessor().setLWRequestStatus(changed, status); |
|
}; |
|
|
|
public static void checkAndSetPolicy(Container cont) { |
|
FocusTraversalPolicy defaultPolicy = KeyboardFocusManager. |
|
getCurrentKeyboardFocusManager(). |
|
getDefaultFocusTraversalPolicy(); |
|
|
|
cont.setFocusTraversalPolicy(defaultPolicy); |
|
} |
|
|
|
private static FocusTraversalPolicy createLayoutPolicy() { |
|
FocusTraversalPolicy policy = null; |
|
try { |
|
Class<?> layoutPolicyClass = |
|
Class.forName("javax.swing.LayoutFocusTraversalPolicy"); |
|
policy = (FocusTraversalPolicy)layoutPolicyClass.newInstance(); |
|
} |
|
catch (ClassNotFoundException e) { |
|
assert false; |
|
} |
|
catch (InstantiationException e) { |
|
assert false; |
|
} |
|
catch (IllegalAccessException e) { |
|
assert false; |
|
} |
|
|
|
return policy; |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public static void insertTargetMapping(Object target, AppContext appContext) { |
|
if (!setAppContext(target, appContext)) { |
|
// Target is not a Component/MenuComponent, use the private Map |
|
|
|
appContextMap.put(target, appContext); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static void postEvent(AppContext appContext, AWTEvent event) { |
|
if (event == null) { |
|
throw new NullPointerException(); |
|
} |
|
|
|
AWTAccessor.SequencedEventAccessor sea = AWTAccessor.getSequencedEventAccessor(); |
|
if (sea != null && sea.isSequencedEvent(event)) { |
|
AWTEvent nested = sea.getNested(event); |
|
if (nested.getID() == WindowEvent.WINDOW_LOST_FOCUS && |
|
nested instanceof TimedWindowEvent) |
|
{ |
|
TimedWindowEvent twe = (TimedWindowEvent)nested; |
|
((SunToolkit)Toolkit.getDefaultToolkit()). |
|
setWindowDeactivationTime((Window)twe.getSource(), twe.getWhen()); |
|
} |
|
} |
|
|
|
// All events posted via this method are system-generated. |
|
// Placing the following call here reduces considerably the |
|
// number of places throughout the toolkit that would |
|
// otherwise have to be modified to precisely identify |
|
|
|
setSystemGenerated(event); |
|
AppContext eventContext = targetToAppContext(event.getSource()); |
|
if (eventContext != null && !eventContext.equals(appContext)) { |
|
throw new RuntimeException("Event posted on wrong app context : " + event); |
|
} |
|
PostEventQueue postEventQueue = |
|
(PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY); |
|
if (postEventQueue != null) { |
|
postEventQueue.postEvent(event); |
|
} |
|
} |
|
|
|
|
|
|
|
*/ |
|
public static void postPriorityEvent(final AWTEvent e) { |
|
PeerEvent pe = new PeerEvent(Toolkit.getDefaultToolkit(), new Runnable() { |
|
public void run() { |
|
AWTAccessor.getAWTEventAccessor().setPosted(e); |
|
((Component)e.getSource()).dispatchEvent(e); |
|
} |
|
}, PeerEvent.ULTIMATE_PRIORITY_EVENT); |
|
postEvent(targetToAppContext(e.getSource()), pe); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public static void flushPendingEvents() { |
|
AppContext appContext = AppContext.getAppContext(); |
|
flushPendingEvents(appContext); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static void flushPendingEvents(AppContext appContext) { |
|
PostEventQueue postEventQueue = |
|
(PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY); |
|
if (postEventQueue != null) { |
|
postEventQueue.flush(); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static void executeOnEventHandlerThread(Object target, |
|
Runnable runnable) { |
|
executeOnEventHandlerThread(new PeerEvent(target, runnable, PeerEvent.PRIORITY_EVENT)); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
@SuppressWarnings("serial") |
|
public static void executeOnEventHandlerThread(Object target, |
|
Runnable runnable, |
|
final long when) { |
|
executeOnEventHandlerThread( |
|
new PeerEvent(target, runnable, PeerEvent.PRIORITY_EVENT) { |
|
public long getWhen() { |
|
return when; |
|
} |
|
}); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static void executeOnEventHandlerThread(PeerEvent peerEvent) { |
|
postEvent(targetToAppContext(peerEvent.getSource()), peerEvent); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static void invokeLaterOnAppContext( |
|
AppContext appContext, Runnable dispatcher) |
|
{ |
|
postEvent(appContext, |
|
new PeerEvent(Toolkit.getDefaultToolkit(), dispatcher, |
|
PeerEvent.PRIORITY_EVENT)); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static void executeOnEDTAndWait(Object target, Runnable runnable) |
|
throws InterruptedException, InvocationTargetException |
|
{ |
|
if (EventQueue.isDispatchThread()) { |
|
throw new Error("Cannot call executeOnEDTAndWait from any event dispatcher thread"); |
|
} |
|
|
|
class AWTInvocationLock {} |
|
Object lock = new AWTInvocationLock(); |
|
|
|
PeerEvent event = new PeerEvent(target, runnable, lock, true, PeerEvent.PRIORITY_EVENT); |
|
|
|
synchronized (lock) { |
|
executeOnEventHandlerThread(event); |
|
while(!event.isDispatched()) { |
|
lock.wait(); |
|
} |
|
} |
|
|
|
Throwable eventThrowable = event.getThrowable(); |
|
if (eventThrowable != null) { |
|
throw new InvocationTargetException(eventThrowable); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static boolean isDispatchThreadForAppContext(Object target) { |
|
AppContext appContext = targetToAppContext(target); |
|
EventQueue eq = (EventQueue)appContext.get(AppContext.EVENT_QUEUE_KEY); |
|
|
|
AWTAccessor.EventQueueAccessor accessor = AWTAccessor.getEventQueueAccessor(); |
|
return accessor.isDispatchThreadImpl(eq); |
|
} |
|
|
|
public Dimension getScreenSize() { |
|
return new Dimension(getScreenWidth(), getScreenHeight()); |
|
} |
|
protected abstract int getScreenWidth(); |
|
protected abstract int getScreenHeight(); |
|
|
|
@SuppressWarnings("deprecation") |
|
public FontMetrics getFontMetrics(Font font) { |
|
return FontDesignMetrics.getMetrics(font); |
|
} |
|
|
|
@SuppressWarnings("deprecation") |
|
public String[] getFontList() { |
|
String[] hardwiredFontList = { |
|
Font.DIALOG, Font.SANS_SERIF, Font.SERIF, Font.MONOSPACED, |
|
Font.DIALOG_INPUT |
|
|
|
// -- Obsolete font names from 1.0.2. It was decided that |
|
// -- getFontList should not return these old names: |
|
// "Helvetica", "TimesRoman", "Courier", "ZapfDingbats" |
|
}; |
|
return hardwiredFontList; |
|
} |
|
|
|
public PanelPeer createPanel(Panel target) { |
|
return (PanelPeer)createComponent(target); |
|
} |
|
|
|
public CanvasPeer createCanvas(Canvas target) { |
|
return (CanvasPeer)createComponent(target); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void disableBackgroundErase(Canvas canvas) { |
|
disableBackgroundEraseImpl(canvas); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void disableBackgroundErase(Component component) { |
|
disableBackgroundEraseImpl(component); |
|
} |
|
|
|
private void disableBackgroundEraseImpl(Component component) { |
|
AWTAccessor.getComponentAccessor().setBackgroundEraseDisabled(component, true); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public static boolean getSunAwtNoerasebackground() { |
|
return AccessController.doPrivileged(new GetBooleanAction("sun.awt.noerasebackground")); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public static boolean getSunAwtErasebackgroundonresize() { |
|
return AccessController.doPrivileged(new GetBooleanAction("sun.awt.erasebackgroundonresize")); |
|
} |
|
|
|
|
|
static final SoftCache fileImgCache = new SoftCache(); |
|
|
|
static final SoftCache urlImgCache = new SoftCache(); |
|
|
|
static Image getImageFromHash(Toolkit tk, URL url) { |
|
checkPermissions(url); |
|
synchronized (urlImgCache) { |
|
String key = url.toString(); |
|
Image img = (Image)urlImgCache.get(key); |
|
if (img == null) { |
|
try { |
|
img = tk.createImage(new URLImageSource(url)); |
|
urlImgCache.put(key, img); |
|
} catch (Exception e) { |
|
} |
|
} |
|
return img; |
|
} |
|
} |
|
|
|
static Image getImageFromHash(Toolkit tk, |
|
String filename) { |
|
checkPermissions(filename); |
|
synchronized (fileImgCache) { |
|
Image img = (Image)fileImgCache.get(filename); |
|
if (img == null) { |
|
try { |
|
img = tk.createImage(new FileImageSource(filename)); |
|
fileImgCache.put(filename, img); |
|
} catch (Exception e) { |
|
} |
|
} |
|
return img; |
|
} |
|
} |
|
|
|
public Image getImage(String filename) { |
|
return getImageFromHash(this, filename); |
|
} |
|
|
|
public Image getImage(URL url) { |
|
return getImageFromHash(this, url); |
|
} |
|
|
|
protected Image getImageWithResolutionVariant(String fileName, |
|
String resolutionVariantName) { |
|
synchronized (fileImgCache) { |
|
Image image = getImageFromHash(this, fileName); |
|
if (image instanceof MultiResolutionImage) { |
|
return image; |
|
} |
|
Image resolutionVariant = getImageFromHash(this, resolutionVariantName); |
|
image = createImageWithResolutionVariant(image, resolutionVariant); |
|
fileImgCache.put(fileName, image); |
|
return image; |
|
} |
|
} |
|
|
|
protected Image getImageWithResolutionVariant(URL url, |
|
URL resolutionVariantURL) { |
|
synchronized (urlImgCache) { |
|
Image image = getImageFromHash(this, url); |
|
if (image instanceof MultiResolutionImage) { |
|
return image; |
|
} |
|
Image resolutionVariant = getImageFromHash(this, resolutionVariantURL); |
|
image = createImageWithResolutionVariant(image, resolutionVariant); |
|
String key = url.toString(); |
|
urlImgCache.put(key, image); |
|
return image; |
|
} |
|
} |
|
|
|
|
|
public Image createImage(String filename) { |
|
checkPermissions(filename); |
|
return createImage(new FileImageSource(filename)); |
|
} |
|
|
|
public Image createImage(URL url) { |
|
checkPermissions(url); |
|
return createImage(new URLImageSource(url)); |
|
} |
|
|
|
public Image createImage(byte[] data, int offset, int length) { |
|
return createImage(new ByteArrayImageSource(data, offset, length)); |
|
} |
|
|
|
public Image createImage(ImageProducer producer) { |
|
return new ToolkitImage(producer); |
|
} |
|
|
|
public static Image createImageWithResolutionVariant(Image image, |
|
Image resolutionVariant) { |
|
return new MultiResolutionToolkitImage(image, resolutionVariant); |
|
} |
|
|
|
public int checkImage(Image img, int w, int h, ImageObserver o) { |
|
if (!(img instanceof ToolkitImage)) { |
|
return ImageObserver.ALLBITS; |
|
} |
|
|
|
ToolkitImage tkimg = (ToolkitImage)img; |
|
int repbits; |
|
if (w == 0 || h == 0) { |
|
repbits = ImageObserver.ALLBITS; |
|
} else { |
|
repbits = tkimg.getImageRep().check(o); |
|
} |
|
return (tkimg.check(o) | repbits) & checkResolutionVariant(img, w, h, o); |
|
} |
|
|
|
public boolean prepareImage(Image img, int w, int h, ImageObserver o) { |
|
if (w == 0 || h == 0) { |
|
return true; |
|
} |
|
|
|
|
|
if (!(img instanceof ToolkitImage)) { |
|
return true; |
|
} |
|
|
|
ToolkitImage tkimg = (ToolkitImage)img; |
|
if (tkimg.hasError()) { |
|
if (o != null) { |
|
o.imageUpdate(img, ImageObserver.ERROR|ImageObserver.ABORT, |
|
-1, -1, -1, -1); |
|
} |
|
return false; |
|
} |
|
ImageRepresentation ir = tkimg.getImageRep(); |
|
return ir.prepare(o) & prepareResolutionVariant(img, w, h, o); |
|
} |
|
|
|
private int checkResolutionVariant(Image img, int w, int h, ImageObserver o) { |
|
ToolkitImage rvImage = getResolutionVariant(img); |
|
int rvw = getRVSize(w); |
|
int rvh = getRVSize(h); |
|
|
|
return (rvImage == null || rvImage.hasError()) ? 0xFFFF : |
|
checkImage(rvImage, rvw, rvh, MultiResolutionToolkitImage. |
|
getResolutionVariantObserver( |
|
img, o, w, h, rvw, rvh, true)); |
|
} |
|
|
|
private boolean prepareResolutionVariant(Image img, int w, int h, |
|
ImageObserver o) { |
|
|
|
ToolkitImage rvImage = getResolutionVariant(img); |
|
int rvw = getRVSize(w); |
|
int rvh = getRVSize(h); |
|
|
|
return rvImage == null || rvImage.hasError() || prepareImage( |
|
rvImage, rvw, rvh, |
|
MultiResolutionToolkitImage.getResolutionVariantObserver( |
|
img, o, w, h, rvw, rvh, true)); |
|
} |
|
|
|
private static int getRVSize(int size){ |
|
return size == -1 ? -1 : 2 * size; |
|
} |
|
|
|
private static ToolkitImage getResolutionVariant(Image image) { |
|
if (image instanceof MultiResolutionToolkitImage) { |
|
Image resolutionVariant = ((MultiResolutionToolkitImage) image). |
|
getResolutionVariant(); |
|
if (resolutionVariant instanceof ToolkitImage) { |
|
return (ToolkitImage) resolutionVariant; |
|
} |
|
} |
|
return null; |
|
} |
|
|
|
protected static boolean imageCached(String fileName) { |
|
return fileImgCache.containsKey(fileName); |
|
} |
|
|
|
protected static boolean imageCached(URL url) { |
|
String key = url.toString(); |
|
return urlImgCache.containsKey(key); |
|
} |
|
|
|
protected static boolean imageExists(String filename) { |
|
if (filename != null) { |
|
checkPermissions(filename); |
|
return new File(filename).exists(); |
|
} |
|
return false; |
|
} |
|
|
|
@SuppressWarnings("try") |
|
protected static boolean imageExists(URL url) { |
|
if (url != null) { |
|
checkPermissions(url); |
|
try (InputStream is = url.openStream()) { |
|
return true; |
|
}catch(IOException e){ |
|
return false; |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
private static void checkPermissions(String filename) { |
|
SecurityManager security = System.getSecurityManager(); |
|
if (security != null) { |
|
security.checkRead(filename); |
|
} |
|
} |
|
|
|
private static void checkPermissions(URL url) { |
|
SecurityManager sm = System.getSecurityManager(); |
|
if (sm != null) { |
|
try { |
|
java.security.Permission perm = |
|
URLUtil.getConnectPermission(url); |
|
if (perm != null) { |
|
try { |
|
sm.checkPermission(perm); |
|
} catch (SecurityException se) { |
|
// fallback to checkRead/checkConnect for pre 1.2 |
|
|
|
if ((perm instanceof java.io.FilePermission) && |
|
perm.getActions().indexOf("read") != -1) { |
|
sm.checkRead(perm.getName()); |
|
} else if ((perm instanceof |
|
java.net.SocketPermission) && |
|
perm.getActions().indexOf("connect") != -1) { |
|
sm.checkConnect(url.getHost(), url.getPort()); |
|
} else { |
|
throw se; |
|
} |
|
} |
|
} |
|
} catch (java.io.IOException ioe) { |
|
sm.checkConnect(url.getHost(), url.getPort()); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public static BufferedImage getScaledIconImage(java.util.List<Image> imageList, int width, int height) { |
|
if (width == 0 || height == 0) { |
|
return null; |
|
} |
|
Image bestImage = null; |
|
int bestWidth = 0; |
|
int bestHeight = 0; |
|
double bestSimilarity = 3; |
|
double bestScaleFactor = 0; |
|
for (Iterator<Image> i = imageList.iterator();i.hasNext();) { |
|
//Iterate imageList looking for best matching image. |
|
//'Similarity' measure is defined as good scale factor and small insets. |
|
//best possible similarity is 0 (no scale, no insets). |
|
//It's found while the experiments that good-looking result is achieved |
|
|
|
Image im = i.next(); |
|
if (im == null) { |
|
continue; |
|
} |
|
if (im instanceof ToolkitImage) { |
|
ImageRepresentation ir = ((ToolkitImage)im).getImageRep(); |
|
ir.reconstruct(ImageObserver.ALLBITS); |
|
} |
|
int iw; |
|
int ih; |
|
try { |
|
iw = im.getWidth(null); |
|
ih = im.getHeight(null); |
|
} catch (Exception e){ |
|
continue; |
|
} |
|
if (iw > 0 && ih > 0) { |
|
|
|
double scaleFactor = Math.min((double)width / (double)iw, |
|
(double)height / (double)ih); |
|
//Calculate scaled image dimensions |
|
|
|
int adjw = 0; |
|
int adjh = 0; |
|
double scaleMeasure = 1; |
|
if (scaleFactor >= 2) { |
|
//Need to enlarge image more than twice |
|
|
|
scaleFactor = Math.floor(scaleFactor); |
|
adjw = iw * (int)scaleFactor; |
|
adjh = ih * (int)scaleFactor; |
|
scaleMeasure = 1.0 - 0.5 / scaleFactor; |
|
} else if (scaleFactor >= 1) { |
|
|
|
scaleFactor = 1.0; |
|
adjw = iw; |
|
adjh = ih; |
|
scaleMeasure = 0; |
|
} else if (scaleFactor >= 0.75) { |
|
|
|
scaleFactor = 0.75; |
|
adjw = iw * 3 / 4; |
|
adjh = ih * 3 / 4; |
|
scaleMeasure = 0.3; |
|
} else if (scaleFactor >= 0.6666) { |
|
|
|
scaleFactor = 0.6666; |
|
adjw = iw * 2 / 3; |
|
adjh = ih * 2 / 3; |
|
scaleMeasure = 0.33; |
|
} else { |
|
//Multiply size by 1/scaleDivider |
|
//where scaleDivider is minimum possible integer |
|
|
|
double scaleDivider = Math.ceil(1.0 / scaleFactor); |
|
scaleFactor = 1.0 / scaleDivider; |
|
adjw = (int)Math.round((double)iw / scaleDivider); |
|
adjh = (int)Math.round((double)ih / scaleDivider); |
|
scaleMeasure = 1.0 - 1.0 / scaleDivider; |
|
} |
|
double similarity = ((double)width - (double)adjw) / (double)width + |
|
((double)height - (double)adjh) / (double)height + |
|
scaleMeasure; |
|
if (similarity < bestSimilarity) { |
|
bestSimilarity = similarity; |
|
bestScaleFactor = scaleFactor; |
|
bestImage = im; |
|
bestWidth = adjw; |
|
bestHeight = adjh; |
|
} |
|
if (similarity == 0) break; |
|
} |
|
} |
|
if (bestImage == null) { |
|
|
|
return null; |
|
} |
|
BufferedImage bimage = |
|
new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); |
|
Graphics2D g = bimage.createGraphics(); |
|
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, |
|
RenderingHints.VALUE_INTERPOLATION_BILINEAR); |
|
try { |
|
int x = (width - bestWidth) / 2; |
|
int y = (height - bestHeight) / 2; |
|
g.drawImage(bestImage, x, y, bestWidth, bestHeight, null); |
|
} finally { |
|
g.dispose(); |
|
} |
|
return bimage; |
|
} |
|
|
|
public static DataBufferInt getScaledIconData(java.util.List<Image> imageList, int width, int height) { |
|
BufferedImage bimage = getScaledIconImage(imageList, width, height); |
|
if (bimage == null) { |
|
return null; |
|
} |
|
Raster raster = bimage.getRaster(); |
|
DataBuffer buffer = raster.getDataBuffer(); |
|
return (DataBufferInt)buffer; |
|
} |
|
|
|
protected EventQueue getSystemEventQueueImpl() { |
|
return getSystemEventQueueImplPP(); |
|
} |
|
|
|
|
|
static EventQueue getSystemEventQueueImplPP() { |
|
return getSystemEventQueueImplPP(AppContext.getAppContext()); |
|
} |
|
|
|
public static EventQueue getSystemEventQueueImplPP(AppContext appContext) { |
|
EventQueue theEventQueue = |
|
(EventQueue)appContext.get(AppContext.EVENT_QUEUE_KEY); |
|
return theEventQueue; |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public static Container getNativeContainer(Component c) { |
|
return Toolkit.getNativeContainer(c); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static Component getHeavyweightComponent(Component c) { |
|
while (c != null && AWTAccessor.getComponentAccessor().isLightweight(c)) { |
|
c = AWTAccessor.getComponentAccessor().getParent(c); |
|
} |
|
return c; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public int getFocusAcceleratorKeyMask() { |
|
return InputEvent.ALT_MASK; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public boolean isPrintableCharacterModifiersMask(int mods) { |
|
return ((mods & InputEvent.ALT_MASK) == (mods & InputEvent.CTRL_MASK)); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public boolean canPopupOverlapTaskBar() { |
|
boolean result = true; |
|
try { |
|
SecurityManager sm = System.getSecurityManager(); |
|
if (sm != null) { |
|
sm.checkPermission( |
|
SecurityConstants.AWT.SET_WINDOW_ALWAYS_ON_TOP_PERMISSION); |
|
} |
|
} catch (SecurityException se) { |
|
|
|
result = false; |
|
} |
|
return result; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public Window createInputMethodWindow(String title, InputContext context) { |
|
return new sun.awt.im.SimpleInputMethodWindow(title, context); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public boolean enableInputMethodsForTextComponent() { |
|
return false; |
|
} |
|
|
|
private static Locale startupLocale = null; |
|
|
|
|
|
|
|
*/ |
|
public static Locale getStartupLocale() { |
|
if (startupLocale == null) { |
|
String language, region, country, variant; |
|
language = AccessController.doPrivileged( |
|
new GetPropertyAction("user.language", "en")); |
|
|
|
region = AccessController.doPrivileged( |
|
new GetPropertyAction("user.region")); |
|
if (region != null) { |
|
|
|
int i = region.indexOf('_'); |
|
if (i >= 0) { |
|
country = region.substring(0, i); |
|
variant = region.substring(i + 1); |
|
} else { |
|
country = region; |
|
variant = ""; |
|
} |
|
} else { |
|
country = AccessController.doPrivileged( |
|
new GetPropertyAction("user.country", "")); |
|
variant = AccessController.doPrivileged( |
|
new GetPropertyAction("user.variant", "")); |
|
} |
|
startupLocale = new Locale(language, country, variant); |
|
} |
|
return startupLocale; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public Locale getDefaultKeyboardLocale() { |
|
return getStartupLocale(); |
|
} |
|
|
|
|
|
private transient WindowClosingListener windowClosingListener = null; |
|
|
|
|
|
*/ |
|
public WindowClosingListener getWindowClosingListener() { |
|
return windowClosingListener; |
|
} |
|
|
|
|
|
*/ |
|
public void setWindowClosingListener(WindowClosingListener wcl) { |
|
windowClosingListener = wcl; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public RuntimeException windowClosingNotify(WindowEvent event) { |
|
if (windowClosingListener != null) { |
|
return windowClosingListener.windowClosingNotify(event); |
|
} else { |
|
return null; |
|
} |
|
} |
|
|
|
|
|
*/ |
|
public RuntimeException windowClosingDelivered(WindowEvent event) { |
|
if (windowClosingListener != null) { |
|
return windowClosingListener.windowClosingDelivered(event); |
|
} else { |
|
return null; |
|
} |
|
} |
|
|
|
private static DefaultMouseInfoPeer mPeer = null; |
|
|
|
protected synchronized MouseInfoPeer getMouseInfoPeer() { |
|
if (mPeer == null) { |
|
mPeer = new DefaultMouseInfoPeer(); |
|
} |
|
return mPeer; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static boolean needsXEmbed() { |
|
String noxembed = AccessController. |
|
doPrivileged(new GetPropertyAction("sun.awt.noxembed", "false")); |
|
if ("true".equals(noxembed)) { |
|
return false; |
|
} |
|
|
|
Toolkit tk = Toolkit.getDefaultToolkit(); |
|
if (tk instanceof SunToolkit) { |
|
// SunToolkit descendants should override this method to specify |
|
|
|
return ((SunToolkit)tk).needsXEmbedImpl(); |
|
} else { |
|
|
|
return false; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected boolean needsXEmbedImpl() { |
|
return false; |
|
} |
|
|
|
private static Dialog.ModalExclusionType DEFAULT_MODAL_EXCLUSION_TYPE = null; |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected final boolean isXEmbedServerRequested() { |
|
return AccessController.doPrivileged(new GetBooleanAction("sun.awt.xembedserver")); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static boolean isModalExcludedSupported() |
|
{ |
|
Toolkit tk = Toolkit.getDefaultToolkit(); |
|
return tk.isModalExclusionTypeSupported(DEFAULT_MODAL_EXCLUSION_TYPE); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected boolean isModalExcludedSupportedImpl() |
|
{ |
|
return false; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static void setModalExcluded(Window window) |
|
{ |
|
if (DEFAULT_MODAL_EXCLUSION_TYPE == null) { |
|
DEFAULT_MODAL_EXCLUSION_TYPE = Dialog.ModalExclusionType.APPLICATION_EXCLUDE; |
|
} |
|
window.setModalExclusionType(DEFAULT_MODAL_EXCLUSION_TYPE); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static boolean isModalExcluded(Window window) |
|
{ |
|
if (DEFAULT_MODAL_EXCLUSION_TYPE == null) { |
|
DEFAULT_MODAL_EXCLUSION_TYPE = Dialog.ModalExclusionType.APPLICATION_EXCLUDE; |
|
} |
|
return window.getModalExclusionType().compareTo(DEFAULT_MODAL_EXCLUSION_TYPE) >= 0; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public boolean isModalityTypeSupported(Dialog.ModalityType modalityType) { |
|
return (modalityType == Dialog.ModalityType.MODELESS) || |
|
(modalityType == Dialog.ModalityType.APPLICATION_MODAL); |
|
} |
|
|
|
|
|
|
|
*/ |
|
public boolean isModalExclusionTypeSupported(Dialog.ModalExclusionType exclusionType) { |
|
return (exclusionType == Dialog.ModalExclusionType.NO_EXCLUDE); |
|
} |
|
|
|
/////////////////////////////////////////////////////////////////////////// |
|
// |
|
// The following is used by the Java Plug-in to coordinate dialog modality |
|
// between containing applications (browsers, ActiveX containers etc) and |
|
// the AWT. |
|
// |
|
/////////////////////////////////////////////////////////////////////////// |
|
|
|
private ModalityListenerList modalityListeners = new ModalityListenerList(); |
|
|
|
public void addModalityListener(ModalityListener listener) { |
|
modalityListeners.add(listener); |
|
} |
|
|
|
public void removeModalityListener(ModalityListener listener) { |
|
modalityListeners.remove(listener); |
|
} |
|
|
|
public void notifyModalityPushed(Dialog dialog) { |
|
notifyModalityChange(ModalityEvent.MODALITY_PUSHED, dialog); |
|
} |
|
|
|
public void notifyModalityPopped(Dialog dialog) { |
|
notifyModalityChange(ModalityEvent.MODALITY_POPPED, dialog); |
|
} |
|
|
|
final void notifyModalityChange(int id, Dialog source) { |
|
ModalityEvent ev = new ModalityEvent(source, modalityListeners, id); |
|
ev.dispatch(); |
|
} |
|
|
|
static class ModalityListenerList implements ModalityListener { |
|
|
|
Vector<ModalityListener> listeners = new Vector<ModalityListener>(); |
|
|
|
void add(ModalityListener listener) { |
|
listeners.addElement(listener); |
|
} |
|
|
|
void remove(ModalityListener listener) { |
|
listeners.removeElement(listener); |
|
} |
|
|
|
public void modalityPushed(ModalityEvent ev) { |
|
Iterator<ModalityListener> it = listeners.iterator(); |
|
while (it.hasNext()) { |
|
it.next().modalityPushed(ev); |
|
} |
|
} |
|
|
|
public void modalityPopped(ModalityEvent ev) { |
|
Iterator<ModalityListener> it = listeners.iterator(); |
|
while (it.hasNext()) { |
|
it.next().modalityPopped(ev); |
|
} |
|
} |
|
} // end of class ModalityListenerList |
|
|
|
/////////////////////////////////////////////////////////////////////////// |
|
// End Plug-in code |
|
/////////////////////////////////////////////////////////////////////////// |
|
|
|
public static boolean isLightweightOrUnknown(Component comp) { |
|
if (comp.isLightweight() |
|
|| !(getDefaultToolkit() instanceof SunToolkit)) |
|
{ |
|
return true; |
|
} |
|
return !(comp instanceof Button |
|
|| comp instanceof Canvas |
|
|| comp instanceof Checkbox |
|
|| comp instanceof Choice |
|
|| comp instanceof Label |
|
|| comp instanceof java.awt.List |
|
|| comp instanceof Panel |
|
|| comp instanceof Scrollbar |
|
|| comp instanceof ScrollPane |
|
|| comp instanceof TextArea |
|
|| comp instanceof TextField |
|
|| comp instanceof Window); |
|
} |
|
|
|
@SuppressWarnings("serial") |
|
public static class OperationTimedOut extends RuntimeException { |
|
public OperationTimedOut(String msg) { |
|
super(msg); |
|
} |
|
public OperationTimedOut() { |
|
} |
|
} |
|
|
|
@SuppressWarnings("serial") |
|
public static class InfiniteLoop extends RuntimeException { |
|
} |
|
|
|
@SuppressWarnings("serial") |
|
public static class IllegalThreadException extends RuntimeException { |
|
public IllegalThreadException(String msg) { |
|
super(msg); |
|
} |
|
public IllegalThreadException() { |
|
} |
|
} |
|
|
|
public static final int DEFAULT_WAIT_TIME = 10000; |
|
private static final int MAX_ITERS = 20; |
|
private static final int MIN_ITERS = 0; |
|
private static final int MINIMAL_EDELAY = 0; |
|
|
|
|
|
|
|
*/ |
|
public void realSync() throws OperationTimedOut, InfiniteLoop { |
|
realSync(DEFAULT_WAIT_TIME); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void realSync(final long timeout) throws OperationTimedOut, InfiniteLoop |
|
{ |
|
if (EventQueue.isDispatchThread()) { |
|
throw new IllegalThreadException("The SunToolkit.realSync() method cannot be used on the event dispatch thread (EDT)."); |
|
} |
|
int bigLoop = 0; |
|
do { |
|
|
|
sync(); |
|
|
|
// During the wait process, when we were processing incoming |
|
// events, we could have made some new request, which can |
|
// generate new events. Example: MapNotify/XSetInputFocus. |
|
// Therefore, we dispatch them as long as there is something |
|
|
|
int iters = 0; |
|
while (iters < MIN_ITERS) { |
|
syncNativeQueue(timeout); |
|
iters++; |
|
} |
|
while (syncNativeQueue(timeout) && iters < MAX_ITERS) { |
|
iters++; |
|
} |
|
if (iters >= MAX_ITERS) { |
|
throw new InfiniteLoop(); |
|
} |
|
|
|
// native requests were dispatched by X/Window Manager or Windows |
|
// Moreover, we processed them all on Toolkit thread |
|
// Now wait while EDT processes them. |
|
// |
|
// During processing of some events (focus, for example), |
|
// some other events could have been generated. So, after |
|
|
|
iters = 0; |
|
while (iters < MIN_ITERS) { |
|
waitForIdle(timeout); |
|
iters++; |
|
} |
|
while (waitForIdle(timeout) && iters < MAX_ITERS) { |
|
iters++; |
|
} |
|
if (iters >= MAX_ITERS) { |
|
throw new InfiniteLoop(); |
|
} |
|
|
|
bigLoop++; |
|
// Again, for Java events, it was simple to check for new Java |
|
// events by checking event queue, but what if Java events |
|
// resulted in native requests? Therefor, check native events again. |
|
} while ((syncNativeQueue(timeout) || waitForIdle(timeout)) && bigLoop < MAX_ITERS); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected abstract boolean syncNativeQueue(final long timeout); |
|
|
|
private boolean eventDispatched = false; |
|
private boolean queueEmpty = false; |
|
private final Object waitLock = "Wait Lock"; |
|
|
|
private boolean isEQEmpty() { |
|
EventQueue queue = getSystemEventQueueImpl(); |
|
return AWTAccessor.getEventQueueAccessor().noEvents(queue); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
@SuppressWarnings("serial") |
|
protected final boolean waitForIdle(final long timeout) { |
|
flushPendingEvents(); |
|
boolean queueWasEmpty = isEQEmpty(); |
|
queueEmpty = false; |
|
eventDispatched = false; |
|
synchronized(waitLock) { |
|
postEvent(AppContext.getAppContext(), |
|
new PeerEvent(getSystemEventQueueImpl(), null, PeerEvent.LOW_PRIORITY_EVENT) { |
|
public void dispatch() { |
|
// Here we block EDT. It could have some |
|
// events, it should have dispatched them by |
|
// now. So native requests could have been |
|
// generated. First, dispatch them. Then, |
|
|
|
int iters = 0; |
|
while (iters < MIN_ITERS) { |
|
syncNativeQueue(timeout); |
|
iters++; |
|
} |
|
while (syncNativeQueue(timeout) && iters < MAX_ITERS) { |
|
iters++; |
|
} |
|
flushPendingEvents(); |
|
|
|
synchronized(waitLock) { |
|
queueEmpty = isEQEmpty(); |
|
eventDispatched = true; |
|
waitLock.notifyAll(); |
|
} |
|
} |
|
}); |
|
try { |
|
while (!eventDispatched) { |
|
waitLock.wait(); |
|
} |
|
} catch (InterruptedException ie) { |
|
return false; |
|
} |
|
} |
|
|
|
try { |
|
Thread.sleep(MINIMAL_EDELAY); |
|
} catch (InterruptedException ie) { |
|
throw new RuntimeException("Interrupted"); |
|
} |
|
|
|
flushPendingEvents(); |
|
|
|
|
|
synchronized (waitLock) { |
|
return !(queueEmpty && isEQEmpty() && queueWasEmpty); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public abstract void grab(Window w); |
|
|
|
|
|
|
|
*/ |
|
public abstract void ungrab(Window w); |
|
|
|
public void showOrHideTouchKeyboard(Component comp, AWTEvent e) {} |
|
|
|
private static boolean touchKeyboardAutoShowIsEnabled; |
|
|
|
public static boolean isTouchKeyboardAutoShowEnabled() { |
|
return touchKeyboardAutoShowIsEnabled; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static native void closeSplashScreen(); |
|
|
|
/* The following methods and variables are to support retrieving |
|
* desktop text anti-aliasing settings |
|
*/ |
|
|
|
|
|
private void fireDesktopFontPropertyChanges() { |
|
setDesktopProperty(SunToolkit.DESKTOPFONTHINTS, |
|
SunToolkit.getDesktopFontHints()); |
|
} |
|
|
|
private static boolean checkedSystemAAFontSettings; |
|
private static boolean useSystemAAFontSettings; |
|
private static boolean lastExtraCondition = true; |
|
private static RenderingHints desktopFontHints; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static void setAAFontSettingsCondition(boolean extraCondition) { |
|
if (extraCondition != lastExtraCondition) { |
|
lastExtraCondition = extraCondition; |
|
if (checkedSystemAAFontSettings) { |
|
|
|
|
|
|
|
|
|
*/ |
|
checkedSystemAAFontSettings = false; |
|
Toolkit tk = Toolkit.getDefaultToolkit(); |
|
if (tk instanceof SunToolkit) { |
|
((SunToolkit)tk).fireDesktopFontPropertyChanges(); |
|
} |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
private static RenderingHints getDesktopAAHintsByName(String hintname) { |
|
Object aaHint = null; |
|
hintname = hintname.toLowerCase(Locale.ENGLISH); |
|
if (hintname.equals("on")) { |
|
aaHint = VALUE_TEXT_ANTIALIAS_ON; |
|
} else if (hintname.equals("gasp")) { |
|
aaHint = VALUE_TEXT_ANTIALIAS_GASP; |
|
} else if (hintname.equals("lcd") || hintname.equals("lcd_hrgb")) { |
|
aaHint = VALUE_TEXT_ANTIALIAS_LCD_HRGB; |
|
} else if (hintname.equals("lcd_hbgr")) { |
|
aaHint = VALUE_TEXT_ANTIALIAS_LCD_HBGR; |
|
} else if (hintname.equals("lcd_vrgb")) { |
|
aaHint = VALUE_TEXT_ANTIALIAS_LCD_VRGB; |
|
} else if (hintname.equals("lcd_vbgr")) { |
|
aaHint = VALUE_TEXT_ANTIALIAS_LCD_VBGR; |
|
} |
|
if (aaHint != null) { |
|
RenderingHints map = new RenderingHints(null); |
|
map.put(KEY_TEXT_ANTIALIASING, aaHint); |
|
return map; |
|
} else { |
|
return null; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private static boolean useSystemAAFontSettings() { |
|
if (!checkedSystemAAFontSettings) { |
|
useSystemAAFontSettings = true; |
|
String systemAAFonts = null; |
|
Toolkit tk = Toolkit.getDefaultToolkit(); |
|
if (tk instanceof SunToolkit) { |
|
systemAAFonts = |
|
AccessController.doPrivileged( |
|
new GetPropertyAction("awt.useSystemAAFontSettings")); |
|
} |
|
if (systemAAFonts != null) { |
|
useSystemAAFontSettings = |
|
Boolean.valueOf(systemAAFonts).booleanValue(); |
|
|
|
|
|
*/ |
|
if (!useSystemAAFontSettings) { |
|
desktopFontHints = getDesktopAAHintsByName(systemAAFonts); |
|
} |
|
} |
|
|
|
if (useSystemAAFontSettings) { |
|
useSystemAAFontSettings = lastExtraCondition; |
|
} |
|
checkedSystemAAFontSettings = true; |
|
} |
|
return useSystemAAFontSettings; |
|
} |
|
|
|
|
|
public static final String DESKTOPFONTHINTS = "awt.font.desktophints"; |
|
|
|
|
|
protected RenderingHints getDesktopAAHints() { |
|
return null; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static RenderingHints getDesktopFontHints() { |
|
if (useSystemAAFontSettings()) { |
|
Toolkit tk = Toolkit.getDefaultToolkit(); |
|
if (tk instanceof SunToolkit) { |
|
Object map = ((SunToolkit)tk).getDesktopAAHints(); |
|
return (RenderingHints)map; |
|
} else { |
|
return null; |
|
} |
|
} else if (desktopFontHints != null) { |
|
|
|
|
|
*/ |
|
return (RenderingHints)(desktopFontHints.clone()); |
|
} else { |
|
return null; |
|
} |
|
} |
|
|
|
|
|
public abstract boolean isDesktopSupported(); |
|
|
|
|
|
|
|
|
|
*/ |
|
public static synchronized void consumeNextKeyTyped(KeyEvent keyEvent) { |
|
try { |
|
AWTAccessor.getDefaultKeyboardFocusManagerAccessor().consumeNextKeyTyped( |
|
(DefaultKeyboardFocusManager)KeyboardFocusManager. |
|
getCurrentKeyboardFocusManager(), |
|
keyEvent); |
|
} catch (ClassCastException cce) { |
|
cce.printStackTrace(); |
|
} |
|
} |
|
|
|
protected static void dumpPeers(final PlatformLogger aLog) { |
|
AWTAutoShutdown.getInstance().dumpPeers(aLog); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static Window getContainingWindow(Component comp) { |
|
while (comp != null && !(comp instanceof Window)) { |
|
comp = comp.getParent(); |
|
} |
|
return (Window)comp; |
|
} |
|
|
|
private static Boolean sunAwtDisableMixing = null; |
|
|
|
|
|
|
|
|
|
*/ |
|
public synchronized static boolean getSunAwtDisableMixing() { |
|
if (sunAwtDisableMixing == null) { |
|
sunAwtDisableMixing = AccessController.doPrivileged( |
|
new GetBooleanAction("sun.awt.disableMixing")); |
|
} |
|
return sunAwtDisableMixing.booleanValue(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public boolean isNativeGTKAvailable() { |
|
return false; |
|
} |
|
|
|
private static final Object DEACTIVATION_TIMES_MAP_KEY = new Object(); |
|
|
|
public synchronized void setWindowDeactivationTime(Window w, long time) { |
|
AppContext ctx = getAppContext(w); |
|
WeakHashMap<Window, Long> map = (WeakHashMap<Window, Long>)ctx.get(DEACTIVATION_TIMES_MAP_KEY); |
|
if (map == null) { |
|
map = new WeakHashMap<Window, Long>(); |
|
ctx.put(DEACTIVATION_TIMES_MAP_KEY, map); |
|
} |
|
map.put(w, time); |
|
} |
|
|
|
public synchronized long getWindowDeactivationTime(Window w) { |
|
AppContext ctx = getAppContext(w); |
|
WeakHashMap<Window, Long> map = (WeakHashMap<Window, Long>)ctx.get(DEACTIVATION_TIMES_MAP_KEY); |
|
if (map == null) { |
|
return -1; |
|
} |
|
Long time = map.get(w); |
|
return time == null ? -1 : time; |
|
} |
|
|
|
|
|
public boolean isWindowOpacitySupported() { |
|
return false; |
|
} |
|
|
|
|
|
public boolean isWindowShapingSupported() { |
|
return false; |
|
} |
|
|
|
|
|
public boolean isWindowTranslucencySupported() { |
|
return false; |
|
} |
|
|
|
public boolean isTranslucencyCapable(GraphicsConfiguration gc) { |
|
return false; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public boolean isSwingBackbufferTranslucencySupported() { |
|
return false; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static boolean isContainingTopLevelOpaque(Component c) { |
|
Window w = getContainingWindow(c); |
|
return w != null && w.isOpaque(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static boolean isContainingTopLevelTranslucent(Component c) { |
|
Window w = getContainingWindow(c); |
|
return w != null && w.getOpacity() < 1.0f; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public boolean needUpdateWindow() { |
|
return false; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public int getNumberOfButtons(){ |
|
return 3; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static boolean isInstanceOf(Object obj, String type) { |
|
if (obj == null) return false; |
|
if (type == null) return false; |
|
|
|
return isInstanceOf(obj.getClass(), type); |
|
} |
|
|
|
private static boolean isInstanceOf(Class<?> cls, String type) { |
|
if (cls == null) return false; |
|
|
|
if (cls.getName().equals(type)) { |
|
return true; |
|
} |
|
|
|
for (Class<?> c : cls.getInterfaces()) { |
|
if (c.getName().equals(type)) { |
|
return true; |
|
} |
|
} |
|
return isInstanceOf(cls.getSuperclass(), type); |
|
} |
|
|
|
protected static LightweightFrame getLightweightFrame(Component c) { |
|
for (; c != null; c = c.getParent()) { |
|
if (c instanceof LightweightFrame) { |
|
return (LightweightFrame)c; |
|
} |
|
if (c instanceof Window) { |
|
|
|
return null; |
|
} |
|
} |
|
return null; |
|
} |
|
|
|
/////////////////////////////////////////////////////////////////////////// |
|
// |
|
// The following methods help set and identify whether a particular |
|
// AWTEvent object was produced by the system or by user code. As of this |
|
// writing the only consumer is the Java Plug-In, although this information |
|
// could be useful to more clients and probably should be formalized in |
|
// the public API. |
|
// |
|
/////////////////////////////////////////////////////////////////////////// |
|
|
|
public static void setSystemGenerated(AWTEvent e) { |
|
AWTAccessor.getAWTEventAccessor().setSystemGenerated(e); |
|
} |
|
|
|
public static boolean isSystemGenerated(AWTEvent e) { |
|
return AWTAccessor.getAWTEventAccessor().isSystemGenerated(e); |
|
} |
|
|
|
} // class SunToolkit |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
class PostEventQueue { |
|
private EventQueueItem queueHead = null; |
|
private EventQueueItem queueTail = null; |
|
private final EventQueue eventQueue; |
|
|
|
private Thread flushThread = null; |
|
|
|
PostEventQueue(EventQueue eq) { |
|
eventQueue = eq; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void flush() { |
|
|
|
Thread newThread = Thread.currentThread(); |
|
|
|
try { |
|
EventQueueItem tempQueue; |
|
synchronized (this) { |
|
|
|
if (newThread == flushThread) { |
|
return; |
|
} |
|
|
|
while (flushThread != null) { |
|
wait(); |
|
} |
|
|
|
if (queueHead == null) { |
|
return; |
|
} |
|
|
|
flushThread = newThread; |
|
|
|
tempQueue = queueHead; |
|
queueHead = queueTail = null; |
|
} |
|
try { |
|
while (tempQueue != null) { |
|
eventQueue.postEvent(tempQueue.event); |
|
tempQueue = tempQueue.next; |
|
} |
|
} |
|
finally { |
|
|
|
synchronized (this) { |
|
|
|
flushThread = null; |
|
notifyAll(); |
|
} |
|
} |
|
} |
|
catch (InterruptedException e) { |
|
|
|
newThread.interrupt(); |
|
} |
|
} |
|
|
|
|
|
|
|
*/ |
|
void postEvent(AWTEvent event) { |
|
EventQueueItem item = new EventQueueItem(event); |
|
|
|
synchronized (this) { |
|
if (queueHead == null) { |
|
queueHead = queueTail = item; |
|
} else { |
|
queueTail.next = item; |
|
queueTail = item; |
|
} |
|
} |
|
SunToolkit.wakeupEventQueue(eventQueue, event.getSource() == AWTAutoShutdown.getInstance()); |
|
} |
|
} // class PostEventQueue |