0N/A/*
3909N/A * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.awt;
0N/A
0N/Aimport java.awt.*;
0N/Aimport static java.awt.RenderingHints.*;
0N/Aimport java.awt.dnd.*;
0N/Aimport java.awt.dnd.peer.DragSourceContextPeer;
0N/Aimport java.awt.peer.*;
0N/Aimport java.awt.event.WindowEvent;
0N/Aimport java.awt.event.KeyEvent;
0N/Aimport java.awt.image.*;
0N/Aimport java.awt.TrayIcon;
0N/Aimport java.awt.SystemTray;
4639N/Aimport java.awt.event.InputEvent;
0N/Aimport java.net.URL;
0N/Aimport java.util.*;
0N/Aimport java.util.concurrent.TimeUnit;
0N/Aimport java.util.concurrent.locks.Condition;
2518N/Aimport java.util.concurrent.locks.Lock;
0N/Aimport java.util.concurrent.locks.ReentrantLock;
4930N/A
4930N/Aimport sun.security.util.SecurityConstants;
1696N/Aimport sun.util.logging.PlatformLogger;
0N/Aimport sun.misc.SoftCache;
0N/Aimport sun.font.FontDesignMetrics;
0N/Aimport sun.awt.im.InputContext;
0N/Aimport sun.awt.image.*;
0N/Aimport sun.security.action.GetPropertyAction;
0N/Aimport sun.security.action.GetBooleanAction;
0N/Aimport java.lang.reflect.InvocationTargetException;
0N/Aimport java.security.AccessController;
0N/A
0N/Apublic abstract class SunToolkit extends Toolkit
0N/A implements WindowClosingSupport, WindowClosingListener,
0N/A ComponentFactory, InputMethodSupport, KeyboardFocusManagerPeerProvider {
0N/A
6398N/A // 8014736: logging has been removed from SunToolkit
0N/A
0N/A /* Load debug settings for native code */
0N/A static {
0N/A if (AccessController.doPrivileged(new GetBooleanAction("sun.awt.nativedebug"))) {
0N/A DebugSettings.init();
0N/A }
0N/A };
0N/A
0N/A /**
0N/A * Special mask for the UngrabEvent events, in addition to the
0N/A * public masks defined in AWTEvent. Should be used as the mask
0N/A * value for Toolkit.addAWTEventListener.
0N/A */
0N/A public static final int GRAB_EVENT_MASK = 0x80000000;
0N/A
0N/A /* The key to put()/get() the PostEventQueue into/from the AppContext.
0N/A */
0N/A private static final String POST_EVENT_QUEUE_KEY = "PostEventQueue";
0N/A
1224N/A /**
1224N/A * Number of buttons.
1224N/A * By default it's taken from the system. If system value does not
1224N/A * fit into int type range, use our own MAX_BUTTONS_SUPPORT value.
1224N/A */
1224N/A protected static int numberOfButtons = 0;
1224N/A
1224N/A
1224N/A /* XFree standard mention 24 buttons as maximum:
1224N/A * http://www.xfree86.org/current/mouse.4.html
1224N/A * We workaround systems supporting more than 24 buttons.
1224N/A * Otherwise, we have to use long type values as masks
1224N/A * which leads to API change.
1224N/A * InputEvent.BUTTON_DOWN_MASK may contain only 21 masks due to
1224N/A * the 4-bytes limit for the int type. (CR 6799099)
1224N/A * One more bit is reserved for FIRST_HIGH_BIT.
1224N/A */
1224N/A public final static int MAX_BUTTONS_SUPPORTED = 20;
1224N/A
6356N/A /**
6356N/A * Creates and initializes EventQueue instance for the specified
6356N/A * AppContext.
6356N/A * Note that event queue must be created from createNewAppContext()
6356N/A * only in order to ensure that EventQueue constructor obtains
6356N/A * the correct AppContext.
6356N/A * @param appContext AppContext to associate with the event queue
6356N/A */
4551N/A private static void initEQ(AppContext appContext) {
4551N/A EventQueue eventQueue;
0N/A
4551N/A String eqName = System.getProperty("AWT.EventQueueClass",
4551N/A "java.awt.EventQueue");
0N/A
4551N/A try {
4551N/A eventQueue = (EventQueue)Class.forName(eqName).newInstance();
4551N/A } catch (Exception e) {
4551N/A e.printStackTrace();
4551N/A System.err.println("Failed loading " + eqName + ": " + e);
4551N/A eventQueue = new EventQueue();
4551N/A }
4551N/A appContext.put(AppContext.EVENT_QUEUE_KEY, eventQueue);
0N/A
4551N/A PostEventQueue postEventQueue = new PostEventQueue(eventQueue);
4551N/A appContext.put(POST_EVENT_QUEUE_KEY, postEventQueue);
4551N/A }
0N/A
4551N/A public SunToolkit() {
0N/A }
0N/A
0N/A public boolean useBufferPerWindow() {
0N/A return false;
0N/A }
0N/A
0N/A public abstract WindowPeer createWindow(Window target)
0N/A throws HeadlessException;
0N/A
0N/A public abstract FramePeer createFrame(Frame target)
0N/A throws HeadlessException;
0N/A
0N/A public abstract DialogPeer createDialog(Dialog target)
0N/A throws HeadlessException;
0N/A
0N/A public abstract ButtonPeer createButton(Button target)
0N/A throws HeadlessException;
0N/A
0N/A public abstract TextFieldPeer createTextField(TextField target)
0N/A throws HeadlessException;
0N/A
0N/A public abstract ChoicePeer createChoice(Choice target)
0N/A throws HeadlessException;
0N/A
0N/A public abstract LabelPeer createLabel(Label target)
0N/A throws HeadlessException;
0N/A
0N/A public abstract ListPeer createList(java.awt.List target)
0N/A throws HeadlessException;
0N/A
0N/A public abstract CheckboxPeer createCheckbox(Checkbox target)
0N/A throws HeadlessException;
0N/A
0N/A public abstract ScrollbarPeer createScrollbar(Scrollbar target)
0N/A throws HeadlessException;
0N/A
0N/A public abstract ScrollPanePeer createScrollPane(ScrollPane target)
0N/A throws HeadlessException;
0N/A
0N/A public abstract TextAreaPeer createTextArea(TextArea target)
0N/A throws HeadlessException;
0N/A
0N/A public abstract FileDialogPeer createFileDialog(FileDialog target)
0N/A throws HeadlessException;
0N/A
0N/A public abstract MenuBarPeer createMenuBar(MenuBar target)
0N/A throws HeadlessException;
0N/A
0N/A public abstract MenuPeer createMenu(Menu target)
0N/A throws HeadlessException;
0N/A
0N/A public abstract PopupMenuPeer createPopupMenu(PopupMenu target)
0N/A throws HeadlessException;
0N/A
0N/A public abstract MenuItemPeer createMenuItem(MenuItem target)
0N/A throws HeadlessException;
0N/A
0N/A public abstract CheckboxMenuItemPeer createCheckboxMenuItem(
0N/A CheckboxMenuItem target)
0N/A throws HeadlessException;
0N/A
0N/A public abstract DragSourceContextPeer createDragSourceContextPeer(
0N/A DragGestureEvent dge)
0N/A throws InvalidDnDOperationException;
0N/A
0N/A public abstract TrayIconPeer createTrayIcon(TrayIcon target)
0N/A throws HeadlessException, AWTException;
0N/A
0N/A public abstract SystemTrayPeer createSystemTray(SystemTray target);
0N/A
0N/A public abstract boolean isTraySupported();
0N/A
0N/A public abstract FontPeer getFontPeer(String name, int style);
0N/A
0N/A public abstract RobotPeer createRobot(Robot target, GraphicsDevice screen)
0N/A throws AWTException;
0N/A
5336N/A public abstract KeyboardFocusManagerPeer getKeyboardFocusManagerPeer()
1058N/A throws HeadlessException;
0N/A
0N/A /**
0N/A * The AWT lock is typically only used on Unix platforms to synchronize
0N/A * access to Xlib, OpenGL, etc. However, these methods are implemented
0N/A * in SunToolkit so that they can be called from shared code (e.g.
0N/A * from the OGL pipeline) or from the X11 pipeline regardless of whether
0N/A * XToolkit or MToolkit is currently in use. There are native macros
0N/A * (such as AWT_LOCK) defined in awt.h, so if the implementation of these
0N/A * methods is changed, make sure it is compatible with the native macros.
0N/A *
0N/A * Note: The following methods (awtLock(), awtUnlock(), etc) should be
0N/A * used in place of:
0N/A * synchronized (getAWTLock()) {
0N/A * ...
0N/A * }
0N/A *
0N/A * By factoring these methods out specially, we are able to change the
0N/A * implementation of these methods (e.g. use more advanced locking
0N/A * mechanisms) without impacting calling code.
0N/A *
0N/A * Sample usage:
0N/A * private void doStuffWithXlib() {
0N/A * assert !SunToolkit.isAWTLockHeldByCurrentThread();
0N/A * SunToolkit.awtLock();
0N/A * try {
0N/A * ...
0N/A * XlibWrapper.XDoStuff();
0N/A * } finally {
0N/A * SunToolkit.awtUnlock();
0N/A * }
0N/A * }
0N/A */
0N/A
0N/A private static final ReentrantLock AWT_LOCK = new ReentrantLock();
0N/A private static final Condition AWT_LOCK_COND = AWT_LOCK.newCondition();
0N/A
0N/A public static final void awtLock() {
0N/A AWT_LOCK.lock();
0N/A }
0N/A
0N/A public static final boolean awtTryLock() {
0N/A return AWT_LOCK.tryLock();
0N/A }
0N/A
0N/A public static final void awtUnlock() {
0N/A AWT_LOCK.unlock();
0N/A }
0N/A
0N/A public static final void awtLockWait()
0N/A throws InterruptedException
0N/A {
0N/A AWT_LOCK_COND.await();
0N/A }
0N/A
0N/A public static final void awtLockWait(long timeout)
0N/A throws InterruptedException
0N/A {
0N/A AWT_LOCK_COND.await(timeout, TimeUnit.MILLISECONDS);
0N/A }
0N/A
0N/A public static final void awtLockNotify() {
0N/A AWT_LOCK_COND.signal();
0N/A }
0N/A
0N/A public static final void awtLockNotifyAll() {
0N/A AWT_LOCK_COND.signalAll();
0N/A }
0N/A
0N/A public static final boolean isAWTLockHeldByCurrentThread() {
0N/A return AWT_LOCK.isHeldByCurrentThread();
0N/A }
0N/A
0N/A /*
0N/A * Create a new AppContext, along with its EventQueue, for a
0N/A * new ThreadGroup. Browser code, for example, would use this
0N/A * method to create an AppContext & EventQueue for an Applet.
0N/A */
0N/A public static AppContext createNewAppContext() {
0N/A ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
6285N/A return createNewAppContext(threadGroup);
6285N/A }
6285N/A
6285N/A static final AppContext createNewAppContext(ThreadGroup threadGroup) {
2855N/A // Create appContext before initialization of EventQueue, so all
2855N/A // the calls to AppContext.getAppContext() from EventQueue ctor
2855N/A // return correct values
2855N/A AppContext appContext = new AppContext(threadGroup);
4551N/A initEQ(appContext);
0N/A
0N/A return appContext;
0N/A }
0N/A
0N/A static void wakeupEventQueue(EventQueue q, boolean isShutdown){
5255N/A AWTAccessor.getEventQueueAccessor().wakeup(q, isShutdown);
0N/A }
0N/A
0N/A /*
0N/A * Fetch the peer associated with the given target (as specified
0N/A * in the peer creation method). This can be used to determine
0N/A * things like what the parent peer is. If the target is null
0N/A * or the target can't be found (either because the a peer was
0N/A * never created for it or the peer was disposed), a null will
0N/A * be returned.
0N/A */
0N/A protected static Object targetToPeer(Object target) {
0N/A if (target != null && !GraphicsEnvironment.isHeadless()) {
0N/A return AWTAutoShutdown.getInstance().getPeer(target);
0N/A }
0N/A return null;
0N/A }
0N/A
0N/A protected static void targetCreatedPeer(Object target, Object peer) {
0N/A if (target != null && peer != null &&
0N/A !GraphicsEnvironment.isHeadless())
0N/A {
0N/A AWTAutoShutdown.getInstance().registerPeer(target, peer);
0N/A }
0N/A }
0N/A
0N/A protected static void targetDisposedPeer(Object target, Object peer) {
0N/A if (target != null && peer != null &&
0N/A !GraphicsEnvironment.isHeadless())
0N/A {
0N/A AWTAutoShutdown.getInstance().unregisterPeer(target, peer);
0N/A }
0N/A }
0N/A
0N/A // Maps from non-Component/MenuComponent to AppContext.
0N/A // WeakHashMap<Component,AppContext>
0N/A private static final Map appContextMap =
0N/A Collections.synchronizedMap(new WeakHashMap());
0N/A
0N/A /**
0N/A * Sets the appContext field of target. If target is not a Component or
0N/A * MenuComponent, this returns false.
0N/A */
1338N/A private static boolean setAppContext(Object target,
1338N/A AppContext context) {
1338N/A if (target instanceof Component) {
1338N/A AWTAccessor.getComponentAccessor().
1338N/A setAppContext((Component)target, context);
1338N/A } else if (target instanceof MenuComponent) {
1338N/A AWTAccessor.getMenuComponentAccessor().
1338N/A setAppContext((MenuComponent)target, context);
1338N/A } else {
0N/A return false;
0N/A }
0N/A return true;
0N/A }
0N/A
0N/A /**
0N/A * Returns the appContext field for target. If target is not a
0N/A * Component or MenuComponent this returns null.
0N/A */
0N/A private static AppContext getAppContext(Object target) {
1338N/A if (target instanceof Component) {
1338N/A return AWTAccessor.getComponentAccessor().
1338N/A getAppContext((Component)target);
1338N/A } else if (target instanceof MenuComponent) {
1338N/A return AWTAccessor.getMenuComponentAccessor().
1338N/A getAppContext((MenuComponent)target);
1338N/A } else {
1338N/A return null;
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Fetch the AppContext associated with the given target.
0N/A * This can be used to determine things like which EventQueue
0N/A * to use for posting events to a Component. If the target is
0N/A * null or the target can't be found, a null with be returned.
0N/A */
0N/A public static AppContext targetToAppContext(Object target) {
0N/A if (target == null || GraphicsEnvironment.isHeadless()) {
0N/A return null;
0N/A }
0N/A AppContext context = getAppContext(target);
0N/A if (context == null) {
0N/A // target is not a Component/MenuComponent, try the
0N/A // appContextMap.
0N/A context = (AppContext)appContextMap.get(target);
0N/A }
0N/A return context;
0N/A }
0N/A
0N/A /**
0N/A * Sets the synchronous status of focus requests on lightweight
0N/A * components in the specified window to the specified value.
0N/A * If the boolean parameter is <code>true</code> then the focus
0N/A * requests on lightweight components will be performed
0N/A * synchronously, if it is <code>false</code>, then asynchronously.
0N/A * By default, all windows have their lightweight request status
0N/A * set to asynchronous.
0N/A * <p>
0N/A * The application can only set the status of lightweight focus
0N/A * requests to synchronous for any of its windows if it doesn't
0N/A * perform focus transfers between different heavyweight containers.
0N/A * In this case the observable focus behaviour is the same as with
0N/A * asynchronous status.
0N/A * <p>
0N/A * If the application performs focus transfer between different
0N/A * heavyweight containers and sets the lightweight focus request
0N/A * status to synchronous for any of its windows, then further focus
0N/A * behaviour is unspecified.
0N/A * <p>
0N/A * @param w window for which the lightweight focus request status
0N/A * should be set
0N/A * @param status the value of lightweight focus request status
0N/A */
0N/A
0N/A public static void setLWRequestStatus(Window changed,boolean status){
1338N/A AWTAccessor.getWindowAccessor().setLWRequestStatus(changed, status);
0N/A };
0N/A
4875N/A public static void checkAndSetPolicy(Container cont) {
4875N/A FocusTraversalPolicy defaultPolicy = KeyboardFocusManager.
4875N/A getCurrentKeyboardFocusManager().
4875N/A getDefaultFocusTraversalPolicy();
0N/A
0N/A cont.setFocusTraversalPolicy(defaultPolicy);
0N/A }
0N/A
0N/A private static FocusTraversalPolicy createLayoutPolicy() {
0N/A FocusTraversalPolicy policy = null;
0N/A try {
0N/A Class layoutPolicyClass =
0N/A Class.forName("javax.swing.LayoutFocusTraversalPolicy");
0N/A policy = (FocusTraversalPolicy) layoutPolicyClass.newInstance();
0N/A }
0N/A catch (ClassNotFoundException e) {
0N/A assert false;
0N/A }
0N/A catch (InstantiationException e) {
0N/A assert false;
0N/A }
0N/A catch (IllegalAccessException e) {
0N/A assert false;
0N/A }
0N/A
0N/A return policy;
0N/A }
0N/A
0N/A /*
0N/A * Insert a mapping from target to AppContext, for later retrieval
0N/A * via targetToAppContext() above.
0N/A */
0N/A public static void insertTargetMapping(Object target, AppContext appContext) {
0N/A if (!GraphicsEnvironment.isHeadless()) {
0N/A if (!setAppContext(target, appContext)) {
0N/A // Target is not a Component/MenuComponent, use the private Map
0N/A // instead.
0N/A appContextMap.put(target, appContext);
0N/A }
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Post an AWTEvent to the Java EventQueue, using the PostEventQueue
0N/A * to avoid possibly calling client code (EventQueueSubclass.postEvent())
0N/A * on the toolkit (AWT-Windows/AWT-Motif) thread. This function should
0N/A * not be called under another lock since it locks the EventQueue.
0N/A * See bugids 4632918, 4526597.
0N/A */
0N/A public static void postEvent(AppContext appContext, AWTEvent event) {
0N/A if (event == null) {
0N/A throw new NullPointerException();
0N/A }
5574N/A
5574N/A AWTAccessor.SequencedEventAccessor sea = AWTAccessor.getSequencedEventAccessor();
5574N/A if (sea != null && sea.isSequencedEvent(event)) {
5574N/A AWTEvent nested = sea.getNested(event);
5574N/A if (nested.getID() == WindowEvent.WINDOW_LOST_FOCUS &&
5574N/A nested instanceof TimedWindowEvent)
5574N/A {
5574N/A TimedWindowEvent twe = (TimedWindowEvent)nested;
5574N/A ((SunToolkit)Toolkit.getDefaultToolkit()).
5574N/A setWindowDeactivationTime((Window)twe.getSource(), twe.getWhen());
5574N/A }
5574N/A }
5574N/A
2860N/A // All events posted via this method are system-generated.
2860N/A // Placing the following call here reduces considerably the
2860N/A // number of places throughout the toolkit that would
2860N/A // otherwise have to be modified to precisely identify
2860N/A // system-generated events.
2860N/A setSystemGenerated(event);
0N/A PostEventQueue postEventQueue =
0N/A (PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY);
2518N/A if (postEventQueue != null) {
0N/A postEventQueue.postEvent(event);
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Post AWTEvent of high priority.
0N/A */
0N/A public static void postPriorityEvent(final AWTEvent e) {
0N/A PeerEvent pe = new PeerEvent(Toolkit.getDefaultToolkit(), new Runnable() {
0N/A public void run() {
1338N/A AWTAccessor.getAWTEventAccessor().setPosted(e);
0N/A ((Component)e.getSource()).dispatchEvent(e);
0N/A }
0N/A }, PeerEvent.ULTIMATE_PRIORITY_EVENT);
0N/A postEvent(targetToAppContext(e.getSource()), pe);
0N/A }
0N/A
4632N/A protected static final Lock flushLock = new ReentrantLock();
2518N/A private static boolean isFlushingPendingEvents = false;
2518N/A
0N/A /*
0N/A * Flush any pending events which haven't been posted to the AWT
0N/A * EventQueue yet.
0N/A */
0N/A public static void flushPendingEvents() {
6356N/A AppContext appContext = AppContext.getAppContext();
6356N/A flushPendingEvents(appContext);
6356N/A }
6356N/A
6356N/A public static void flushPendingEvents(AppContext appContext) {
2518N/A flushLock.lock();
2518N/A try {
2518N/A // Don't call flushPendingEvents() recursively
2518N/A if (!isFlushingPendingEvents) {
2518N/A isFlushingPendingEvents = true;
5566N/A try {
5566N/A PostEventQueue postEventQueue =
5566N/A (PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY);
5566N/A if (postEventQueue != null) {
5566N/A postEventQueue.flush();
5566N/A }
5566N/A }
5566N/A finally {
5566N/A isFlushingPendingEvents = false;
2518N/A }
2518N/A }
2518N/A } finally {
2518N/A flushLock.unlock();
0N/A }
0N/A }
0N/A
0N/A public static boolean isPostEventQueueEmpty() {
0N/A AppContext appContext = AppContext.getAppContext();
0N/A PostEventQueue postEventQueue =
0N/A (PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY);
0N/A if (postEventQueue != null) {
0N/A return postEventQueue.noEvents();
0N/A } else {
0N/A return true;
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Execute a chunk of code on the Java event handler thread for the
0N/A * given target. Does not wait for the execution to occur before
0N/A * returning to the caller.
0N/A */
0N/A public static void executeOnEventHandlerThread(Object target,
0N/A Runnable runnable) {
0N/A executeOnEventHandlerThread(new PeerEvent(target, runnable, PeerEvent.PRIORITY_EVENT));
0N/A }
0N/A
0N/A /*
0N/A * Fixed 5064013: the InvocationEvent time should be equals
0N/A * the time of the ActionEvent
0N/A */
0N/A public static void executeOnEventHandlerThread(Object target,
0N/A Runnable runnable,
0N/A final long when) {
0N/A executeOnEventHandlerThread(new PeerEvent(target, runnable, PeerEvent.PRIORITY_EVENT){
0N/A public long getWhen(){
0N/A return when;
0N/A }
0N/A });
0N/A }
0N/A
0N/A /*
0N/A * Execute a chunk of code on the Java event handler thread for the
0N/A * given target. Does not wait for the execution to occur before
0N/A * returning to the caller.
0N/A */
0N/A public static void executeOnEventHandlerThread(PeerEvent peerEvent) {
0N/A postEvent(targetToAppContext(peerEvent.getSource()), peerEvent);
0N/A }
0N/A
0N/A /*
0N/A * Execute a chunk of code on the Java event handler thread. The
0N/A * method takes into account provided AppContext and sets
0N/A * <code>SunToolkit.getDefaultToolkit()</code> as a target of the
0N/A * event. See 6451487 for detailes.
0N/A * Does not wait for the execution to occur before returning to
0N/A * the caller.
0N/A */
0N/A public static void invokeLaterOnAppContext(
0N/A AppContext appContext, Runnable dispatcher)
0N/A {
0N/A postEvent(appContext,
0N/A new PeerEvent(Toolkit.getDefaultToolkit(), dispatcher,
0N/A PeerEvent.PRIORITY_EVENT));
0N/A }
0N/A
0N/A /*
0N/A * Execute a chunk of code on the Java event handler thread for the
0N/A * given target. Waits for the execution to occur before returning
0N/A * to the caller.
0N/A */
0N/A public static void executeOnEDTAndWait(Object target, Runnable runnable)
0N/A throws InterruptedException, InvocationTargetException
0N/A {
0N/A if (EventQueue.isDispatchThread()) {
0N/A throw new Error("Cannot call executeOnEDTAndWait from any event dispatcher thread");
0N/A }
0N/A
0N/A class AWTInvocationLock {}
0N/A Object lock = new AWTInvocationLock();
0N/A
0N/A PeerEvent event = new PeerEvent(target, runnable, lock, true, PeerEvent.PRIORITY_EVENT);
0N/A
0N/A synchronized (lock) {
0N/A executeOnEventHandlerThread(event);
3366N/A while(!event.isDispatched()) {
3366N/A lock.wait();
3366N/A }
0N/A }
0N/A
0N/A Throwable eventThrowable = event.getThrowable();
0N/A if (eventThrowable != null) {
0N/A throw new InvocationTargetException(eventThrowable);
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Returns true if the calling thread is the event dispatch thread
0N/A * contained within AppContext which associated with the given target.
0N/A * Use this call to ensure that a given task is being executed
0N/A * (or not being) on the event dispatch thread for the given target.
0N/A */
0N/A public static boolean isDispatchThreadForAppContext(Object target) {
0N/A AppContext appContext = targetToAppContext(target);
0N/A EventQueue eq = (EventQueue)appContext.get(AppContext.EVENT_QUEUE_KEY);
0N/A
1338N/A AWTAccessor.EventQueueAccessor accessor = AWTAccessor.getEventQueueAccessor();
1970N/A return accessor.isDispatchThreadImpl(eq);
0N/A }
0N/A
0N/A public Dimension getScreenSize() {
0N/A return new Dimension(getScreenWidth(), getScreenHeight());
0N/A }
0N/A protected abstract int getScreenWidth();
0N/A protected abstract int getScreenHeight();
0N/A
0N/A public FontMetrics getFontMetrics(Font font) {
0N/A return FontDesignMetrics.getMetrics(font);
0N/A }
0N/A
0N/A public String[] getFontList() {
0N/A String[] hardwiredFontList = {
0N/A Font.DIALOG, Font.SANS_SERIF, Font.SERIF, Font.MONOSPACED,
0N/A Font.DIALOG_INPUT
0N/A
0N/A // -- Obsolete font names from 1.0.2. It was decided that
0N/A // -- getFontList should not return these old names:
0N/A // "Helvetica", "TimesRoman", "Courier", "ZapfDingbats"
0N/A };
0N/A return hardwiredFontList;
0N/A }
0N/A
0N/A public PanelPeer createPanel(Panel target) {
0N/A return (PanelPeer)createComponent(target);
0N/A }
0N/A
0N/A public CanvasPeer createCanvas(Canvas target) {
0N/A return (CanvasPeer)createComponent(target);
0N/A }
0N/A
0N/A /**
1045N/A * Disables erasing of background on the canvas before painting if
1045N/A * this is supported by the current toolkit. It is recommended to
1045N/A * call this method early, before the Canvas becomes displayable,
1045N/A * because some Toolkit implementations do not support changing
1045N/A * this property once the Canvas becomes displayable.
0N/A */
0N/A public void disableBackgroundErase(Canvas canvas) {
1045N/A disableBackgroundEraseImpl(canvas);
1045N/A }
1045N/A
1045N/A /**
1045N/A * Disables the native erasing of the background on the given
1045N/A * component before painting if this is supported by the current
1045N/A * toolkit. This only has an effect for certain components such as
1045N/A * Canvas, Panel and Window. It is recommended to call this method
1045N/A * early, before the Component becomes displayable, because some
1045N/A * Toolkit implementations do not support changing this property
1045N/A * once the Component becomes displayable.
1045N/A */
1045N/A public void disableBackgroundErase(Component component) {
1045N/A disableBackgroundEraseImpl(component);
1045N/A }
1045N/A
1045N/A private void disableBackgroundEraseImpl(Component component) {
1045N/A AWTAccessor.getComponentAccessor().setBackgroundEraseDisabled(component, true);
0N/A }
0N/A
0N/A /**
0N/A * Returns the value of "sun.awt.noerasebackground" property. Default
0N/A * value is {@code false}.
0N/A */
0N/A public static boolean getSunAwtNoerasebackground() {
0N/A return AccessController.doPrivileged(new GetBooleanAction("sun.awt.noerasebackground"));
0N/A }
0N/A
0N/A /**
0N/A * Returns the value of "sun.awt.erasebackgroundonresize" property. Default
0N/A * value is {@code false}.
0N/A */
0N/A public static boolean getSunAwtErasebackgroundonresize() {
0N/A return AccessController.doPrivileged(new GetBooleanAction("sun.awt.erasebackgroundonresize"));
0N/A }
0N/A
562N/A
1974N/A static final SoftCache imgCache = new SoftCache();
0N/A
1974N/A static Image getImageFromHash(Toolkit tk, URL url) {
0N/A SecurityManager sm = System.getSecurityManager();
0N/A if (sm != null) {
0N/A try {
0N/A java.security.Permission perm =
0N/A url.openConnection().getPermission();
0N/A if (perm != null) {
0N/A try {
0N/A sm.checkPermission(perm);
0N/A } catch (SecurityException se) {
0N/A // fallback to checkRead/checkConnect for pre 1.2
0N/A // security managers
0N/A if ((perm instanceof java.io.FilePermission) &&
0N/A perm.getActions().indexOf("read") != -1) {
0N/A sm.checkRead(perm.getName());
0N/A } else if ((perm instanceof
0N/A java.net.SocketPermission) &&
0N/A perm.getActions().indexOf("connect") != -1) {
0N/A sm.checkConnect(url.getHost(), url.getPort());
0N/A } else {
0N/A throw se;
0N/A }
0N/A }
0N/A }
0N/A } catch (java.io.IOException ioe) {
0N/A sm.checkConnect(url.getHost(), url.getPort());
0N/A }
0N/A }
1974N/A synchronized (imgCache) {
1974N/A Image img = (Image)imgCache.get(url);
1974N/A if (img == null) {
1974N/A try {
1974N/A img = tk.createImage(new URLImageSource(url));
1974N/A imgCache.put(url, img);
1974N/A } catch (Exception e) {
1974N/A }
0N/A }
1974N/A return img;
0N/A }
0N/A }
0N/A
1974N/A static Image getImageFromHash(Toolkit tk,
0N/A String filename) {
0N/A SecurityManager security = System.getSecurityManager();
0N/A if (security != null) {
0N/A security.checkRead(filename);
0N/A }
1974N/A synchronized (imgCache) {
1974N/A Image img = (Image)imgCache.get(filename);
1974N/A if (img == null) {
1974N/A try {
1974N/A img = tk.createImage(new FileImageSource(filename));
1974N/A imgCache.put(filename, img);
1974N/A } catch (Exception e) {
1974N/A }
0N/A }
1974N/A return img;
0N/A }
0N/A }
0N/A
0N/A public Image getImage(String filename) {
0N/A return getImageFromHash(this, filename);
0N/A }
0N/A
0N/A public Image getImage(URL url) {
0N/A return getImageFromHash(this, url);
0N/A }
0N/A
0N/A public Image createImage(String filename) {
0N/A SecurityManager security = System.getSecurityManager();
0N/A if (security != null) {
0N/A security.checkRead(filename);
0N/A }
0N/A return createImage(new FileImageSource(filename));
0N/A }
0N/A
0N/A public Image createImage(URL url) {
0N/A SecurityManager sm = System.getSecurityManager();
0N/A if (sm != null) {
0N/A try {
0N/A java.security.Permission perm =
0N/A url.openConnection().getPermission();
0N/A if (perm != null) {
0N/A try {
0N/A sm.checkPermission(perm);
0N/A } catch (SecurityException se) {
0N/A // fallback to checkRead/checkConnect for pre 1.2
0N/A // security managers
0N/A if ((perm instanceof java.io.FilePermission) &&
0N/A perm.getActions().indexOf("read") != -1) {
0N/A sm.checkRead(perm.getName());
0N/A } else if ((perm instanceof
0N/A java.net.SocketPermission) &&
0N/A perm.getActions().indexOf("connect") != -1) {
0N/A sm.checkConnect(url.getHost(), url.getPort());
0N/A } else {
0N/A throw se;
0N/A }
0N/A }
0N/A }
0N/A } catch (java.io.IOException ioe) {
0N/A sm.checkConnect(url.getHost(), url.getPort());
0N/A }
0N/A }
0N/A return createImage(new URLImageSource(url));
0N/A }
0N/A
0N/A public Image createImage(byte[] data, int offset, int length) {
0N/A return createImage(new ByteArrayImageSource(data, offset, length));
0N/A }
0N/A
0N/A public Image createImage(ImageProducer producer) {
0N/A return new ToolkitImage(producer);
0N/A }
0N/A
0N/A public int checkImage(Image img, int w, int h, ImageObserver o) {
0N/A if (!(img instanceof ToolkitImage)) {
0N/A return ImageObserver.ALLBITS;
0N/A }
0N/A
0N/A ToolkitImage tkimg = (ToolkitImage)img;
0N/A int repbits;
0N/A if (w == 0 || h == 0) {
0N/A repbits = ImageObserver.ALLBITS;
0N/A } else {
0N/A repbits = tkimg.getImageRep().check(o);
0N/A }
0N/A return tkimg.check(o) | repbits;
0N/A }
0N/A
0N/A public boolean prepareImage(Image img, int w, int h, ImageObserver o) {
0N/A if (w == 0 || h == 0) {
0N/A return true;
0N/A }
0N/A
0N/A // Must be a ToolkitImage
0N/A if (!(img instanceof ToolkitImage)) {
0N/A return true;
0N/A }
0N/A
0N/A ToolkitImage tkimg = (ToolkitImage)img;
0N/A if (tkimg.hasError()) {
0N/A if (o != null) {
0N/A o.imageUpdate(img, ImageObserver.ERROR|ImageObserver.ABORT,
0N/A -1, -1, -1, -1);
0N/A }
0N/A return false;
0N/A }
0N/A ImageRepresentation ir = tkimg.getImageRep();
0N/A return ir.prepare(o);
0N/A }
0N/A
0N/A /**
0N/A * Scans {@code imageList} for best-looking image of specified dimensions.
0N/A * Image can be scaled and/or padded with transparency.
0N/A */
0N/A public static BufferedImage getScaledIconImage(java.util.List<Image> imageList, int width, int height) {
0N/A if (width == 0 || height == 0) {
0N/A return null;
0N/A }
0N/A Image bestImage = null;
0N/A int bestWidth = 0;
0N/A int bestHeight = 0;
0N/A double bestSimilarity = 3; //Impossibly high value
0N/A double bestScaleFactor = 0;
0N/A for (Iterator<Image> i = imageList.iterator();i.hasNext();) {
0N/A //Iterate imageList looking for best matching image.
0N/A //'Similarity' measure is defined as good scale factor and small insets.
0N/A //best possible similarity is 0 (no scale, no insets).
0N/A //It's found while the experiments that good-looking result is achieved
0N/A //with scale factors x1, x3/4, x2/3, xN, x1/N.
0N/A Image im = i.next();
0N/A if (im == null) {
0N/A continue;
0N/A }
0N/A if (im instanceof ToolkitImage) {
0N/A ImageRepresentation ir = ((ToolkitImage)im).getImageRep();
0N/A ir.reconstruct(ImageObserver.ALLBITS);
0N/A }
0N/A int iw;
0N/A int ih;
0N/A try {
0N/A iw = im.getWidth(null);
0N/A ih = im.getHeight(null);
0N/A } catch (Exception e){
0N/A continue;
0N/A }
0N/A if (iw > 0 && ih > 0) {
0N/A //Calc scale factor
0N/A double scaleFactor = Math.min((double)width / (double)iw,
0N/A (double)height / (double)ih);
0N/A //Calculate scaled image dimensions
0N/A //adjusting scale factor to nearest "good" value
0N/A int adjw = 0;
0N/A int adjh = 0;
0N/A double scaleMeasure = 1; //0 - best (no) scale, 1 - impossibly bad
0N/A if (scaleFactor >= 2) {
0N/A //Need to enlarge image more than twice
0N/A //Round down scale factor to multiply by integer value
0N/A scaleFactor = Math.floor(scaleFactor);
0N/A adjw = iw * (int)scaleFactor;
0N/A adjh = ih * (int)scaleFactor;
0N/A scaleMeasure = 1.0 - 0.5 / scaleFactor;
0N/A } else if (scaleFactor >= 1) {
0N/A //Don't scale
0N/A scaleFactor = 1.0;
0N/A adjw = iw;
0N/A adjh = ih;
0N/A scaleMeasure = 0;
0N/A } else if (scaleFactor >= 0.75) {
0N/A //Multiply by 3/4
0N/A scaleFactor = 0.75;
0N/A adjw = iw * 3 / 4;
0N/A adjh = ih * 3 / 4;
0N/A scaleMeasure = 0.3;
0N/A } else if (scaleFactor >= 0.6666) {
0N/A //Multiply by 2/3
0N/A scaleFactor = 0.6666;
0N/A adjw = iw * 2 / 3;
0N/A adjh = ih * 2 / 3;
0N/A scaleMeasure = 0.33;
0N/A } else {
0N/A //Multiply size by 1/scaleDivider
0N/A //where scaleDivider is minimum possible integer
0N/A //larger than 1/scaleFactor
0N/A double scaleDivider = Math.ceil(1.0 / scaleFactor);
0N/A scaleFactor = 1.0 / scaleDivider;
0N/A adjw = (int)Math.round((double)iw / scaleDivider);
0N/A adjh = (int)Math.round((double)ih / scaleDivider);
0N/A scaleMeasure = 1.0 - 1.0 / scaleDivider;
0N/A }
0N/A double similarity = ((double)width - (double)adjw) / (double)width +
0N/A ((double)height - (double)adjh) / (double)height + //Large padding is bad
0N/A scaleMeasure; //Large rescale is bad
0N/A if (similarity < bestSimilarity) {
0N/A bestSimilarity = similarity;
0N/A bestScaleFactor = scaleFactor;
0N/A bestImage = im;
0N/A bestWidth = adjw;
0N/A bestHeight = adjh;
0N/A }
0N/A if (similarity == 0) break;
0N/A }
0N/A }
0N/A if (bestImage == null) {
0N/A //No images were found, possibly all are broken
0N/A return null;
0N/A }
0N/A BufferedImage bimage =
0N/A new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
0N/A Graphics2D g = bimage.createGraphics();
0N/A g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
0N/A RenderingHints.VALUE_INTERPOLATION_BILINEAR);
0N/A try {
0N/A int x = (width - bestWidth) / 2;
0N/A int y = (height - bestHeight) / 2;
0N/A g.drawImage(bestImage, x, y, bestWidth, bestHeight, null);
0N/A } finally {
0N/A g.dispose();
0N/A }
0N/A return bimage;
0N/A }
0N/A
0N/A public static DataBufferInt getScaledIconData(java.util.List<Image> imageList, int width, int height) {
0N/A BufferedImage bimage = getScaledIconImage(imageList, width, height);
0N/A if (bimage == null) {
0N/A return null;
0N/A }
0N/A Raster raster = bimage.getRaster();
0N/A DataBuffer buffer = raster.getDataBuffer();
0N/A return (DataBufferInt)buffer;
0N/A }
0N/A
0N/A protected EventQueue getSystemEventQueueImpl() {
0N/A return getSystemEventQueueImplPP();
0N/A }
0N/A
0N/A // Package private implementation
0N/A static EventQueue getSystemEventQueueImplPP() {
0N/A return getSystemEventQueueImplPP(AppContext.getAppContext());
0N/A }
0N/A
0N/A public static EventQueue getSystemEventQueueImplPP(AppContext appContext) {
0N/A EventQueue theEventQueue =
0N/A (EventQueue)appContext.get(AppContext.EVENT_QUEUE_KEY);
0N/A return theEventQueue;
0N/A }
0N/A
0N/A /**
0N/A * Give native peers the ability to query the native container
0N/A * given a native component (eg the direct parent may be lightweight).
0N/A */
0N/A public static Container getNativeContainer(Component c) {
0N/A return Toolkit.getNativeContainer(c);
0N/A }
0N/A
0N/A /**
1976N/A * Gives native peers the ability to query the closest HW component.
1976N/A * If the given component is heavyweight, then it returns this. Otherwise,
1976N/A * it goes one level up in the hierarchy and tests next component.
1976N/A */
1976N/A public static Component getHeavyweightComponent(Component c) {
1976N/A while (c != null && AWTAccessor.getComponentAccessor().isLightweight(c)) {
1976N/A c = AWTAccessor.getComponentAccessor().getParent(c);
1976N/A }
1976N/A return c;
1976N/A }
1976N/A
1976N/A /**
4639N/A * Returns key modifiers used by Swing to set up a focus accelerator key stroke.
4639N/A */
4639N/A public int getFocusAcceleratorKeyMask() {
4639N/A return InputEvent.ALT_MASK;
4639N/A }
4639N/A
4639N/A /**
4887N/A * Tests whether specified key modifiers mask can be used to enter a printable
4887N/A * character. This is a default implementation of this method, which reflects
4887N/A * the way things work on Windows: here, pressing ctrl + alt allows user to enter
4887N/A * characters from the extended character set (like euro sign or math symbols)
4887N/A */
4887N/A public boolean isPrintableCharacterModifiersMask(int mods) {
4887N/A return ((mods & InputEvent.ALT_MASK) == (mods & InputEvent.CTRL_MASK));
4887N/A }
4887N/A
4887N/A /**
4930N/A * Returns whether popup is allowed to be shown above the task bar.
4930N/A * This is a default implementation of this method, which checks
4930N/A * corresponding security permission.
4930N/A */
4930N/A public boolean canPopupOverlapTaskBar() {
4930N/A boolean result = true;
4930N/A try {
4930N/A SecurityManager sm = System.getSecurityManager();
4930N/A if (sm != null) {
4930N/A sm.checkPermission(
4930N/A SecurityConstants.AWT.SET_WINDOW_ALWAYS_ON_TOP_PERMISSION);
4930N/A }
4930N/A } catch (SecurityException se) {
4930N/A // There is no permission to show popups over the task bar
4930N/A result = false;
4930N/A }
4930N/A return result;
4930N/A }
4930N/A
4930N/A /**
0N/A * Returns a new input method window, with behavior as specified in
0N/A * {@link java.awt.im.spi.InputMethodContext#createInputMethodWindow}.
0N/A * If the inputContext is not null, the window should return it from its
0N/A * getInputContext() method. The window needs to implement
0N/A * sun.awt.im.InputMethodWindow.
0N/A * <p>
0N/A * SunToolkit subclasses can override this method to return better input
0N/A * method windows.
0N/A */
0N/A public Window createInputMethodWindow(String title, InputContext context) {
0N/A return new sun.awt.im.SimpleInputMethodWindow(title, context);
0N/A }
0N/A
0N/A /**
0N/A * Returns whether enableInputMethods should be set to true for peered
0N/A * TextComponent instances on this platform. False by default.
0N/A */
0N/A public boolean enableInputMethodsForTextComponent() {
0N/A return false;
0N/A }
0N/A
0N/A private static Locale startupLocale = null;
0N/A
0N/A /**
0N/A * Returns the locale in which the runtime was started.
0N/A */
0N/A public static Locale getStartupLocale() {
0N/A if (startupLocale == null) {
0N/A String language, region, country, variant;
0N/A language = (String) AccessController.doPrivileged(
0N/A new GetPropertyAction("user.language", "en"));
0N/A // for compatibility, check for old user.region property
0N/A region = (String) AccessController.doPrivileged(
0N/A new GetPropertyAction("user.region"));
0N/A if (region != null) {
0N/A // region can be of form country, country_variant, or _variant
0N/A int i = region.indexOf('_');
0N/A if (i >= 0) {
0N/A country = region.substring(0, i);
0N/A variant = region.substring(i + 1);
0N/A } else {
0N/A country = region;
0N/A variant = "";
0N/A }
0N/A } else {
0N/A country = (String) AccessController.doPrivileged(
0N/A new GetPropertyAction("user.country", ""));
0N/A variant = (String) AccessController.doPrivileged(
0N/A new GetPropertyAction("user.variant", ""));
0N/A }
0N/A startupLocale = new Locale(language, country, variant);
0N/A }
0N/A return startupLocale;
0N/A }
0N/A
0N/A /**
0N/A * Returns the default keyboard locale of the underlying operating system
0N/A */
0N/A public Locale getDefaultKeyboardLocale() {
0N/A return getStartupLocale();
0N/A }
0N/A
0N/A private static String dataTransfererClassName = null;
0N/A
0N/A protected static void setDataTransfererClassName(String className) {
0N/A dataTransfererClassName = className;
0N/A }
0N/A
0N/A public static String getDataTransfererClassName() {
0N/A if (dataTransfererClassName == null) {
0N/A Toolkit.getDefaultToolkit(); // transferer set during toolkit init
0N/A }
0N/A return dataTransfererClassName;
0N/A }
0N/A
0N/A // Support for window closing event notifications
0N/A private transient WindowClosingListener windowClosingListener = null;
0N/A /**
0N/A * @see sun.awt.WindowClosingSupport#getWindowClosingListener
0N/A */
0N/A public WindowClosingListener getWindowClosingListener() {
0N/A return windowClosingListener;
0N/A }
0N/A /**
0N/A * @see sun.awt.WindowClosingSupport#setWindowClosingListener
0N/A */
0N/A public void setWindowClosingListener(WindowClosingListener wcl) {
0N/A windowClosingListener = wcl;
0N/A }
0N/A
0N/A /**
0N/A * @see sun.awt.WindowClosingListener#windowClosingNotify
0N/A */
0N/A public RuntimeException windowClosingNotify(WindowEvent event) {
0N/A if (windowClosingListener != null) {
0N/A return windowClosingListener.windowClosingNotify(event);
0N/A } else {
0N/A return null;
0N/A }
0N/A }
0N/A /**
0N/A * @see sun.awt.WindowClosingListener#windowClosingDelivered
0N/A */
0N/A public RuntimeException windowClosingDelivered(WindowEvent event) {
0N/A if (windowClosingListener != null) {
0N/A return windowClosingListener.windowClosingDelivered(event);
0N/A } else {
0N/A return null;
0N/A }
0N/A }
0N/A
0N/A private static DefaultMouseInfoPeer mPeer = null;
0N/A
0N/A protected synchronized MouseInfoPeer getMouseInfoPeer() {
0N/A if (mPeer == null) {
0N/A mPeer = new DefaultMouseInfoPeer();
0N/A }
0N/A return mPeer;
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Returns whether default toolkit needs the support of the xembed
0N/A * from embedding host(if any).
0N/A * @return <code>true</code>, if XEmbed is needed, <code>false</code> otherwise
0N/A */
0N/A public static boolean needsXEmbed() {
0N/A String noxembed = (String) AccessController.
0N/A doPrivileged(new GetPropertyAction("sun.awt.noxembed", "false"));
0N/A if ("true".equals(noxembed)) {
0N/A return false;
0N/A }
0N/A
0N/A Toolkit tk = Toolkit.getDefaultToolkit();
0N/A if (tk instanceof SunToolkit) {
0N/A // SunToolkit descendants should override this method to specify
0N/A // concrete behavior
0N/A return ((SunToolkit)tk).needsXEmbedImpl();
0N/A } else {
0N/A // Non-SunToolkit doubtly might support XEmbed
0N/A return false;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns whether this toolkit needs the support of the xembed
0N/A * from embedding host(if any).
0N/A * @return <code>true</code>, if XEmbed is needed, <code>false</code> otherwise
0N/A */
0N/A protected boolean needsXEmbedImpl() {
0N/A return false;
0N/A }
0N/A
1338N/A private static Dialog.ModalExclusionType DEFAULT_MODAL_EXCLUSION_TYPE = null;
0N/A
0N/A /**
0N/A * Returns whether the XEmbed server feature is requested by
0N/A * developer. If true, Toolkit should return an
0N/A * XEmbed-server-enabled CanvasPeer instead of the ordinary CanvasPeer.
0N/A */
0N/A protected final boolean isXEmbedServerRequested() {
0N/A return AccessController.doPrivileged(new GetBooleanAction("sun.awt.xembedserver"));
0N/A }
0N/A
0N/A /**
0N/A * Returns whether the modal exclusion API is supported by the current toolkit.
0N/A * When it isn't supported, calling <code>setModalExcluded</code> has no
0N/A * effect, and <code>isModalExcluded</code> returns false for all windows.
0N/A *
0N/A * @return true if modal exclusion is supported by the toolkit, false otherwise
0N/A *
0N/A * @see sun.awt.SunToolkit#setModalExcluded(java.awt.Window)
0N/A * @see sun.awt.SunToolkit#isModalExcluded(java.awt.Window)
0N/A *
0N/A * @since 1.5
0N/A */
0N/A public static boolean isModalExcludedSupported()
0N/A {
0N/A Toolkit tk = Toolkit.getDefaultToolkit();
0N/A return tk.isModalExclusionTypeSupported(DEFAULT_MODAL_EXCLUSION_TYPE);
0N/A }
0N/A /*
0N/A * Default implementation for isModalExcludedSupportedImpl(), returns false.
0N/A *
0N/A * @see sun.awt.windows.WToolkit#isModalExcludeSupportedImpl
0N/A * @see sun.awt.X11.XToolkit#isModalExcludeSupportedImpl
0N/A *
0N/A * @since 1.5
0N/A */
0N/A protected boolean isModalExcludedSupportedImpl()
0N/A {
0N/A return false;
0N/A }
0N/A
0N/A /*
0N/A * Sets this window to be excluded from being modally blocked. When the
0N/A * toolkit supports modal exclusion and this method is called, input
0N/A * events, focus transfer and z-order will continue to work for the
0N/A * window, it's owned windows and child components, even in the
0N/A * presence of a modal dialog.
0N/A * For details on which <code>Window</code>s are normally blocked
0N/A * by modal dialog, see {@link java.awt.Dialog}.
0N/A * Invoking this method when the modal exclusion API is not supported by
0N/A * the current toolkit has no effect.
0N/A * @param window Window to be marked as not modally blocked
0N/A * @see java.awt.Dialog
0N/A * @see java.awt.Dialog#setModal(boolean)
0N/A * @see sun.awt.SunToolkit#isModalExcludedSupported
0N/A * @see sun.awt.SunToolkit#isModalExcluded(java.awt.Window)
0N/A */
0N/A public static void setModalExcluded(Window window)
0N/A {
1338N/A if (DEFAULT_MODAL_EXCLUSION_TYPE == null) {
1338N/A DEFAULT_MODAL_EXCLUSION_TYPE = Dialog.ModalExclusionType.APPLICATION_EXCLUDE;
1338N/A }
0N/A window.setModalExclusionType(DEFAULT_MODAL_EXCLUSION_TYPE);
0N/A }
0N/A
0N/A /*
0N/A * Returns whether the specified window is blocked by modal dialogs.
0N/A * If the modal exclusion API isn't supported by the current toolkit,
0N/A * it returns false for all windows.
0N/A *
0N/A * @param window Window to test for modal exclusion
0N/A *
0N/A * @return true if the window is modal excluded, false otherwise. If
0N/A * the modal exclusion isn't supported by the current Toolkit, false
0N/A * is returned
0N/A *
0N/A * @see sun.awt.SunToolkit#isModalExcludedSupported
0N/A * @see sun.awt.SunToolkit#setModalExcluded(java.awt.Window)
0N/A *
0N/A * @since 1.5
0N/A */
0N/A public static boolean isModalExcluded(Window window)
0N/A {
1338N/A if (DEFAULT_MODAL_EXCLUSION_TYPE == null) {
1338N/A DEFAULT_MODAL_EXCLUSION_TYPE = Dialog.ModalExclusionType.APPLICATION_EXCLUDE;
1338N/A }
0N/A return window.getModalExclusionType().compareTo(DEFAULT_MODAL_EXCLUSION_TYPE) >= 0;
0N/A }
0N/A
0N/A /**
0N/A * Overridden in XToolkit and WToolkit
0N/A */
0N/A public boolean isModalityTypeSupported(Dialog.ModalityType modalityType) {
0N/A return (modalityType == Dialog.ModalityType.MODELESS) ||
0N/A (modalityType == Dialog.ModalityType.APPLICATION_MODAL);
0N/A }
0N/A
0N/A /**
0N/A * Overridden in XToolkit and WToolkit
0N/A */
0N/A public boolean isModalExclusionTypeSupported(Dialog.ModalExclusionType exclusionType) {
0N/A return (exclusionType == Dialog.ModalExclusionType.NO_EXCLUDE);
0N/A }
0N/A
0N/A ///////////////////////////////////////////////////////////////////////////
0N/A //
0N/A // The following is used by the Java Plug-in to coordinate dialog modality
0N/A // between containing applications (browsers, ActiveX containers etc) and
0N/A // the AWT.
0N/A //
0N/A ///////////////////////////////////////////////////////////////////////////
0N/A
0N/A private ModalityListenerList modalityListeners = new ModalityListenerList();
0N/A
0N/A public void addModalityListener(ModalityListener listener) {
0N/A modalityListeners.add(listener);
0N/A }
0N/A
0N/A public void removeModalityListener(ModalityListener listener) {
0N/A modalityListeners.remove(listener);
0N/A }
0N/A
0N/A public void notifyModalityPushed(Dialog dialog) {
0N/A notifyModalityChange(ModalityEvent.MODALITY_PUSHED, dialog);
0N/A }
0N/A
0N/A public void notifyModalityPopped(Dialog dialog) {
0N/A notifyModalityChange(ModalityEvent.MODALITY_POPPED, dialog);
0N/A }
0N/A
0N/A final void notifyModalityChange(int id, Dialog source) {
0N/A ModalityEvent ev = new ModalityEvent(source, modalityListeners, id);
0N/A ev.dispatch();
0N/A }
0N/A
0N/A static class ModalityListenerList implements ModalityListener {
0N/A
0N/A Vector<ModalityListener> listeners = new Vector<ModalityListener>();
0N/A
0N/A void add(ModalityListener listener) {
0N/A listeners.addElement(listener);
0N/A }
0N/A
0N/A void remove(ModalityListener listener) {
0N/A listeners.removeElement(listener);
0N/A }
0N/A
0N/A public void modalityPushed(ModalityEvent ev) {
0N/A Iterator<ModalityListener> it = listeners.iterator();
0N/A while (it.hasNext()) {
0N/A it.next().modalityPushed(ev);
0N/A }
0N/A }
0N/A
0N/A public void modalityPopped(ModalityEvent ev) {
0N/A Iterator<ModalityListener> it = listeners.iterator();
0N/A while (it.hasNext()) {
0N/A it.next().modalityPopped(ev);
0N/A }
0N/A }
0N/A } // end of class ModalityListenerList
0N/A
0N/A ///////////////////////////////////////////////////////////////////////////
0N/A // End Plug-in code
0N/A ///////////////////////////////////////////////////////////////////////////
0N/A
0N/A public static boolean isLightweightOrUnknown(Component comp) {
0N/A if (comp.isLightweight()
0N/A || !(getDefaultToolkit() instanceof SunToolkit))
0N/A {
0N/A return true;
0N/A }
0N/A return !(comp instanceof Button
0N/A || comp instanceof Canvas
0N/A || comp instanceof Checkbox
0N/A || comp instanceof Choice
0N/A || comp instanceof Label
0N/A || comp instanceof java.awt.List
0N/A || comp instanceof Panel
0N/A || comp instanceof Scrollbar
0N/A || comp instanceof ScrollPane
0N/A || comp instanceof TextArea
0N/A || comp instanceof TextField
0N/A || comp instanceof Window);
0N/A }
0N/A
0N/A public static class OperationTimedOut extends RuntimeException {
0N/A public OperationTimedOut(String msg) {
0N/A super(msg);
0N/A }
0N/A public OperationTimedOut() {
0N/A }
0N/A }
0N/A public static class InfiniteLoop extends RuntimeException {
0N/A }
0N/A
0N/A public static class IllegalThreadException extends RuntimeException {
0N/A public IllegalThreadException(String msg) {
0N/A super(msg);
0N/A }
0N/A public IllegalThreadException() {
0N/A }
0N/A }
0N/A
0N/A public static final int DEFAULT_WAIT_TIME = 10000;
0N/A private static final int MAX_ITERS = 20;
0N/A private static final int MIN_ITERS = 0;
0N/A private static final int MINIMAL_EDELAY = 0;
0N/A
0N/A /**
0N/A * Parameterless version of realsync which uses default timout (see DEFAUL_WAIT_TIME).
0N/A */
0N/A public void realSync() throws OperationTimedOut, InfiniteLoop {
0N/A realSync(DEFAULT_WAIT_TIME);
0N/A }
0N/A
0N/A /**
0N/A * Forces toolkit to synchronize with the native windowing
0N/A * sub-system, flushing all pending work and waiting for all the
0N/A * events to be processed. This method guarantees that after
0N/A * return no additional Java events will be generated, unless
0N/A * cause by user. Obviously, the method cannot be used on the
0N/A * event dispatch thread (EDT). In case it nevertheless gets
0N/A * invoked on this thread, the method throws the
0N/A * IllegalThreadException runtime exception.
0N/A *
0N/A * <p> This method allows to write tests without explicit timeouts
0N/A * or wait for some event. Example:
0N/A * <code>
0N/A * Frame f = ...;
0N/A * f.setVisible(true);
0N/A * ((SunToolkit)Toolkit.getDefaultToolkit()).realSync();
0N/A * </code>
0N/A *
0N/A * <p> After realSync, <code>f</code> will be completely visible
0N/A * on the screen, its getLocationOnScreen will be returning the
0N/A * right result and it will be the focus owner.
0N/A *
0N/A * <p> Another example:
0N/A * <code>
0N/A * b.requestFocus();
0N/A * ((SunToolkit)Toolkit.getDefaultToolkit()).realSync();
0N/A * </code>
0N/A *
0N/A * <p> After realSync, <code>b</code> will be focus owner.
0N/A *
0N/A * <p> Notice that realSync isn't guaranteed to work if recurring
0N/A * actions occur, such as if during processing of some event
0N/A * another request which may generate some events occurs. By
0N/A * default, sync tries to perform as much as {@value MAX_ITERS}
0N/A * cycles of event processing, allowing for roughly {@value
0N/A * MAX_ITERS} additional requests.
0N/A *
0N/A * <p> For example, requestFocus() generates native request, which
0N/A * generates one or two Java focus events, which then generate a
0N/A * serie of paint events, a serie of Java focus events, which then
0N/A * generate a serie of paint events which then are processed -
0N/A * three cycles, minimum.
0N/A *
0N/A * @param timeout the maximum time to wait in milliseconds, negative means "forever".
0N/A */
0N/A public void realSync(final long timeout) throws OperationTimedOut, InfiniteLoop
0N/A {
0N/A if (EventQueue.isDispatchThread()) {
0N/A throw new IllegalThreadException("The SunToolkit.realSync() method cannot be used on the event dispatch thread (EDT).");
0N/A }
0N/A int bigLoop = 0;
0N/A do {
0N/A // Let's do sync first
0N/A sync();
0N/A
0N/A // During the wait process, when we were processing incoming
0N/A // events, we could have made some new request, which can
0N/A // generate new events. Example: MapNotify/XSetInputFocus.
0N/A // Therefore, we dispatch them as long as there is something
0N/A // to dispatch.
0N/A int iters = 0;
0N/A while (iters < MIN_ITERS) {
0N/A syncNativeQueue(timeout);
0N/A iters++;
0N/A }
0N/A while (syncNativeQueue(timeout) && iters < MAX_ITERS) {
0N/A iters++;
0N/A }
0N/A if (iters >= MAX_ITERS) {
0N/A throw new InfiniteLoop();
0N/A }
0N/A
0N/A // native requests were dispatched by X/Window Manager or Windows
0N/A // Moreover, we processed them all on Toolkit thread
0N/A // Now wait while EDT processes them.
0N/A //
0N/A // During processing of some events (focus, for example),
0N/A // some other events could have been generated. So, after
0N/A // waitForIdle, we may end up with full EventQueue
0N/A iters = 0;
0N/A while (iters < MIN_ITERS) {
0N/A waitForIdle(timeout);
0N/A iters++;
0N/A }
0N/A while (waitForIdle(timeout) && iters < MAX_ITERS) {
0N/A iters++;
0N/A }
0N/A if (iters >= MAX_ITERS) {
0N/A throw new InfiniteLoop();
0N/A }
0N/A
0N/A bigLoop++;
0N/A // Again, for Java events, it was simple to check for new Java
0N/A // events by checking event queue, but what if Java events
0N/A // resulted in native requests? Therefor, check native events again.
0N/A } while ((syncNativeQueue(timeout) || waitForIdle(timeout)) && bigLoop < MAX_ITERS);
0N/A }
0N/A
0N/A /**
0N/A * Platform toolkits need to implement this method to perform the
0N/A * sync of the native queue. The method should wait until native
0N/A * requests are processed, all native events are processed and
0N/A * corresponding Java events are generated. Should return
0N/A * <code>true</code> if some events were processed,
0N/A * <code>false</code> otherwise.
0N/A */
0N/A protected abstract boolean syncNativeQueue(final long timeout);
0N/A
0N/A private boolean eventDispatched = false;
0N/A private boolean queueEmpty = false;
0N/A private final Object waitLock = "Wait Lock";
0N/A
0N/A private boolean isEQEmpty() {
0N/A EventQueue queue = getSystemEventQueueImpl();
5255N/A return AWTAccessor.getEventQueueAccessor().noEvents(queue);
0N/A }
0N/A
0N/A /**
0N/A * Waits for the Java event queue to empty. Ensures that all
0N/A * events are processed (including paint events), and that if
0N/A * recursive events were generated, they are also processed.
0N/A * Should return <code>true</code> if more processing is
0N/A * necessary, <code>false</code> otherwise.
0N/A */
0N/A protected final boolean waitForIdle(final long timeout) {
0N/A flushPendingEvents();
0N/A boolean queueWasEmpty = isEQEmpty();
0N/A queueEmpty = false;
0N/A eventDispatched = false;
0N/A synchronized(waitLock) {
0N/A postEvent(AppContext.getAppContext(),
0N/A new PeerEvent(getSystemEventQueueImpl(), null, PeerEvent.LOW_PRIORITY_EVENT) {
0N/A public void dispatch() {
0N/A // Here we block EDT. It could have some
0N/A // events, it should have dispatched them by
0N/A // now. So native requests could have been
0N/A // generated. First, dispatch them. Then,
0N/A // flush Java events again.
0N/A int iters = 0;
0N/A while (iters < MIN_ITERS) {
0N/A syncNativeQueue(timeout);
0N/A iters++;
0N/A }
0N/A while (syncNativeQueue(timeout) && iters < MAX_ITERS) {
0N/A iters++;
0N/A }
0N/A flushPendingEvents();
0N/A
0N/A synchronized(waitLock) {
0N/A queueEmpty = isEQEmpty();
0N/A eventDispatched = true;
0N/A waitLock.notifyAll();
0N/A }
0N/A }
0N/A });
0N/A try {
0N/A while (!eventDispatched) {
0N/A waitLock.wait();
0N/A }
0N/A } catch (InterruptedException ie) {
0N/A return false;
0N/A }
0N/A }
0N/A
0N/A try {
0N/A Thread.sleep(MINIMAL_EDELAY);
0N/A } catch (InterruptedException ie) {
0N/A throw new RuntimeException("Interrupted");
0N/A }
0N/A
0N/A flushPendingEvents();
0N/A
0N/A // Lock to force write-cache flush for queueEmpty.
0N/A synchronized (waitLock) {
0N/A return !(queueEmpty && isEQEmpty() && queueWasEmpty);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Grabs the mouse input for the given window. The window must be
0N/A * visible. The window or its children do not receive any
0N/A * additional mouse events besides those targeted to them. All
0N/A * other events will be dispatched as before - to the respective
0N/A * targets. This Window will receive UngrabEvent when automatic
0N/A * ungrab is about to happen. The event can be listened to by
0N/A * installing AWTEventListener with WINDOW_EVENT_MASK. See
0N/A * UngrabEvent class for the list of conditions when ungrab is
0N/A * about to happen.
0N/A * @see UngrabEvent
0N/A */
0N/A public abstract void grab(Window w);
0N/A
0N/A /**
0N/A * Forces ungrab. No event will be sent.
0N/A */
0N/A public abstract void ungrab(Window w);
0N/A
0N/A
0N/A /**
0N/A * Locates the splash screen library in a platform dependent way and closes
0N/A * the splash screen. Should be invoked on first top-level frame display.
0N/A * @see java.awt.SplashScreen
0N/A * @since 1.6
0N/A */
0N/A public static native void closeSplashScreen();
0N/A
0N/A /* The following methods and variables are to support retrieving
0N/A * desktop text anti-aliasing settings
0N/A */
0N/A
0N/A /* Need an instance method because setDesktopProperty(..) is protected. */
0N/A private void fireDesktopFontPropertyChanges() {
0N/A setDesktopProperty(SunToolkit.DESKTOPFONTHINTS,
0N/A SunToolkit.getDesktopFontHints());
0N/A }
0N/A
0N/A private static boolean checkedSystemAAFontSettings;
0N/A private static boolean useSystemAAFontSettings;
0N/A private static boolean lastExtraCondition = true;
0N/A private static RenderingHints desktopFontHints;
0N/A
0N/A /* Since Swing is the reason for this "extra condition" logic its
0N/A * worth documenting it in some detail.
0N/A * First, a goal is for Swing and applications to both retrieve and
0N/A * use the same desktop property value so that there is complete
0N/A * consistency between the settings used by JDK's Swing implementation
0N/A * and 3rd party custom Swing components, custom L&Fs and any general
0N/A * text rendering that wants to be consistent with these.
0N/A * But by default on Solaris & Linux Swing will not use AA text over
0N/A * remote X11 display (unless Xrender can be used which is TBD and may not
0N/A * always be available anyway) as that is a noticeable performance hit.
0N/A * So there needs to be a way to express that extra condition so that
0N/A * it is seen by all clients of the desktop property API.
0N/A * If this were the only condition it could be handled here as it would
0N/A * be the same for any L&F and could reasonably be considered to be
0N/A * a static behaviour of those systems.
0N/A * But GTK currently has an additional test based on locale which is
0N/A * not applied by Metal. So mixing GTK in a few locales with Metal
0N/A * would mean the last one wins.
0N/A * This could be stored per-app context which would work
0N/A * for different applets, but wouldn't help for a single application
0N/A * using GTK and some other L&F concurrently.
0N/A * But it is expected this will be addressed within GTK and the font
0N/A * system so is a temporary and somewhat unlikely harmless corner case.
0N/A */
0N/A public static void setAAFontSettingsCondition(boolean extraCondition) {
0N/A if (extraCondition != lastExtraCondition) {
0N/A lastExtraCondition = extraCondition;
0N/A if (checkedSystemAAFontSettings) {
0N/A /* Someone already asked for this info, under a different
0N/A * condition.
0N/A * We'll force re-evaluation instead of replicating the
0N/A * logic, then notify any listeners of any change.
0N/A */
0N/A checkedSystemAAFontSettings = false;
0N/A Toolkit tk = Toolkit.getDefaultToolkit();
0N/A if (tk instanceof SunToolkit) {
0N/A ((SunToolkit)tk).fireDesktopFontPropertyChanges();
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A /* "false", "off", ""default" aren't explicitly tested, they
0N/A * just fall through to produce a null return which all are equated to
0N/A * "false".
0N/A */
0N/A private static RenderingHints getDesktopAAHintsByName(String hintname) {
0N/A Object aaHint = null;
0N/A hintname = hintname.toLowerCase(Locale.ENGLISH);
0N/A if (hintname.equals("on")) {
0N/A aaHint = VALUE_TEXT_ANTIALIAS_ON;
0N/A } else if (hintname.equals("gasp")) {
0N/A aaHint = VALUE_TEXT_ANTIALIAS_GASP;
0N/A } else if (hintname.equals("lcd") || hintname.equals("lcd_hrgb")) {
0N/A aaHint = VALUE_TEXT_ANTIALIAS_LCD_HRGB;
0N/A } else if (hintname.equals("lcd_hbgr")) {
0N/A aaHint = VALUE_TEXT_ANTIALIAS_LCD_HBGR;
0N/A } else if (hintname.equals("lcd_vrgb")) {
0N/A aaHint = VALUE_TEXT_ANTIALIAS_LCD_VRGB;
0N/A } else if (hintname.equals("lcd_vbgr")) {
0N/A aaHint = VALUE_TEXT_ANTIALIAS_LCD_VBGR;
0N/A }
0N/A if (aaHint != null) {
0N/A RenderingHints map = new RenderingHints(null);
0N/A map.put(KEY_TEXT_ANTIALIASING, aaHint);
0N/A return map;
0N/A } else {
0N/A return null;
0N/A }
0N/A }
0N/A
0N/A /* This method determines whether to use the system font settings,
0N/A * or ignore them if a L&F has specified they should be ignored, or
0N/A * to override both of these with a system property specified value.
0N/A * If the toolkit isn't a SunToolkit, (eg may be headless) then that
0N/A * system property isn't applied as desktop properties are considered
0N/A * to be inapplicable in that case. In that headless case although
0N/A * this method will return "true" the toolkit will return a null map.
0N/A */
0N/A private static boolean useSystemAAFontSettings() {
0N/A if (!checkedSystemAAFontSettings) {
0N/A useSystemAAFontSettings = true; /* initially set this true */
0N/A String systemAAFonts = null;
0N/A Toolkit tk = Toolkit.getDefaultToolkit();
0N/A if (tk instanceof SunToolkit) {
0N/A systemAAFonts =
0N/A (String)AccessController.doPrivileged(
0N/A new GetPropertyAction("awt.useSystemAAFontSettings"));
0N/A }
0N/A if (systemAAFonts != null) {
0N/A useSystemAAFontSettings =
0N/A Boolean.valueOf(systemAAFonts).booleanValue();
0N/A /* If it is anything other than "true", then it may be
0N/A * a hint name , or it may be "off, "default", etc.
0N/A */
0N/A if (!useSystemAAFontSettings) {
0N/A desktopFontHints = getDesktopAAHintsByName(systemAAFonts);
0N/A }
0N/A }
0N/A /* If its still true, apply the extra condition */
0N/A if (useSystemAAFontSettings) {
0N/A useSystemAAFontSettings = lastExtraCondition;
0N/A }
0N/A checkedSystemAAFontSettings = true;
0N/A }
0N/A return useSystemAAFontSettings;
0N/A }
0N/A
0N/A /* A variable defined for the convenience of JDK code */
0N/A public static final String DESKTOPFONTHINTS = "awt.font.desktophints";
0N/A
0N/A /* Overridden by subclasses to return platform/desktop specific values */
0N/A protected RenderingHints getDesktopAAHints() {
0N/A return null;
0N/A }
0N/A
0N/A /* Subclass desktop property loading methods call this which
0N/A * in turn calls the appropriate subclass implementation of
0N/A * getDesktopAAHints() when system settings are being used.
0N/A * Its public rather than protected because subclasses may delegate
0N/A * to a helper class.
0N/A */
0N/A public static RenderingHints getDesktopFontHints() {
0N/A if (useSystemAAFontSettings()) {
0N/A Toolkit tk = Toolkit.getDefaultToolkit();
0N/A if (tk instanceof SunToolkit) {
0N/A Object map = ((SunToolkit)tk).getDesktopAAHints();
0N/A return (RenderingHints)map;
0N/A } else { /* Headless Toolkit */
0N/A return null;
0N/A }
0N/A } else if (desktopFontHints != null) {
0N/A /* cloning not necessary as the return value is cloned later, but
0N/A * its harmless.
0N/A */
0N/A return (RenderingHints)(desktopFontHints.clone());
0N/A } else {
0N/A return null;
0N/A }
0N/A }
0N/A
0N/A
0N/A public abstract boolean isDesktopSupported();
0N/A
0N/A /*
0N/A * consumeNextKeyTyped() method is not currently used,
0N/A * however Swing could use it in the future.
0N/A */
0N/A public static synchronized void consumeNextKeyTyped(KeyEvent keyEvent) {
0N/A try {
5255N/A AWTAccessor.getDefaultKeyboardFocusManagerAccessor().consumeNextKeyTyped(
5255N/A (DefaultKeyboardFocusManager)KeyboardFocusManager.
5255N/A getCurrentKeyboardFocusManager(),
5255N/A keyEvent);
5255N/A } catch (ClassCastException cce) {
5255N/A cce.printStackTrace();
0N/A }
0N/A }
0N/A
1696N/A protected static void dumpPeers(final PlatformLogger aLog) {
0N/A AWTAutoShutdown.getInstance().dumpPeers(aLog);
0N/A }
0N/A
1045N/A /**
1045N/A * Returns the <code>Window</code> ancestor of the component <code>comp</code>.
1045N/A * @return Window ancestor of the component or component by itself if it is Window;
1045N/A * null, if component is not a part of window hierarchy
1045N/A */
1045N/A public static Window getContainingWindow(Component comp) {
1045N/A while (comp != null && !(comp instanceof Window)) {
1045N/A comp = comp.getParent();
1045N/A }
1045N/A return (Window)comp;
1045N/A }
1045N/A
886N/A private static Boolean sunAwtDisableMixing = null;
886N/A
886N/A /**
886N/A * Returns the value of "sun.awt.disableMixing" property. Default
886N/A * value is {@code false}.
886N/A */
886N/A public synchronized static boolean getSunAwtDisableMixing() {
886N/A if (sunAwtDisableMixing == null) {
5255N/A sunAwtDisableMixing = AccessController.doPrivileged(
5255N/A new GetBooleanAction("sun.awt.disableMixing"));
886N/A }
886N/A return sunAwtDisableMixing.booleanValue();
886N/A }
886N/A
0N/A /**
0N/A * Returns true if the native GTK libraries are available. The
0N/A * default implementation returns false, but UNIXToolkit overrides this
0N/A * method to provide a more specific answer.
0N/A */
0N/A public boolean isNativeGTKAvailable() {
0N/A return false;
0N/A }
1045N/A
5574N/A private static final Object DEACTIVATION_TIMES_MAP_KEY = new Object();
5574N/A
5574N/A public synchronized void setWindowDeactivationTime(Window w, long time) {
5574N/A AppContext ctx = getAppContext(w);
5574N/A WeakHashMap<Window, Long> map = (WeakHashMap<Window, Long>)ctx.get(DEACTIVATION_TIMES_MAP_KEY);
5574N/A if (map == null) {
5574N/A map = new WeakHashMap<Window, Long>();
5574N/A ctx.put(DEACTIVATION_TIMES_MAP_KEY, map);
5574N/A }
5574N/A map.put(w, time);
5574N/A }
5574N/A
5574N/A public synchronized long getWindowDeactivationTime(Window w) {
5574N/A AppContext ctx = getAppContext(w);
5574N/A WeakHashMap<Window, Long> map = (WeakHashMap<Window, Long>)ctx.get(DEACTIVATION_TIMES_MAP_KEY);
5574N/A if (map == null) {
5574N/A return -1;
5574N/A }
5574N/A Long time = map.get(w);
5574N/A return time == null ? -1 : time;
5574N/A }
5574N/A
1045N/A // Cosntant alpha
1045N/A public boolean isWindowOpacitySupported() {
1045N/A return false;
1045N/A }
1045N/A
1045N/A // Shaping
1045N/A public boolean isWindowShapingSupported() {
1045N/A return false;
1045N/A }
1045N/A
1045N/A // Per-pixel alpha
1045N/A public boolean isWindowTranslucencySupported() {
1045N/A return false;
1045N/A }
1045N/A
1045N/A public boolean isTranslucencyCapable(GraphicsConfiguration gc) {
1045N/A return false;
1045N/A }
1045N/A
1045N/A /**
5232N/A * Returns true if swing backbuffer should be translucent.
5232N/A */
5232N/A public boolean isSwingBackbufferTranslucencySupported() {
5232N/A return false;
5232N/A }
5232N/A
5232N/A /**
1045N/A * Returns whether or not a containing top level window for the passed
1045N/A * component is
1163N/A * {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT PERPIXEL_TRANSLUCENT}.
1045N/A *
1045N/A * @param c a Component which toplevel's to check
1045N/A * @return {@code true} if the passed component is not null and has a
1045N/A * containing toplevel window which is opaque (so per-pixel translucency
1045N/A * is not enabled), {@code false} otherwise
1163N/A * @see GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT
1045N/A */
1045N/A public static boolean isContainingTopLevelOpaque(Component c) {
1045N/A Window w = getContainingWindow(c);
1403N/A return w != null && w.isOpaque();
1045N/A }
1045N/A
1045N/A /**
1045N/A * Returns whether or not a containing top level window for the passed
1045N/A * component is
1163N/A * {@link GraphicsDevice.WindowTranslucency#TRANSLUCENT TRANSLUCENT}.
1045N/A *
1045N/A * @param c a Component which toplevel's to check
1045N/A * @return {@code true} if the passed component is not null and has a
1045N/A * containing toplevel window which has opacity less than
1045N/A * 1.0f (which means that it is translucent), {@code false} otherwise
1163N/A * @see GraphicsDevice.WindowTranslucency#TRANSLUCENT
1045N/A */
1045N/A public static boolean isContainingTopLevelTranslucent(Component c) {
1045N/A Window w = getContainingWindow(c);
1163N/A return w != null && ((Window)w).getOpacity() < 1.0f;
1045N/A }
1045N/A
1045N/A /**
1045N/A * Returns whether the native system requires using the peer.updateWindow()
1045N/A * method to update the contents of a non-opaque window, or if usual
1045N/A * painting procedures are sufficient. The default return value covers
1045N/A * the X11 systems. On MS Windows this method is overriden in WToolkit
1045N/A * to return true.
1045N/A */
1045N/A public boolean needUpdateWindow() {
1045N/A return false;
1045N/A }
1045N/A
1224N/A /**
1224N/A * Descendants of the SunToolkit should override and put their own logic here.
1224N/A */
1224N/A public int getNumberOfButtons(){
1224N/A return 3;
1224N/A }
1338N/A
1338N/A /**
1338N/A * Checks that the given object implements/extends the given
1338N/A * interface/class.
1338N/A *
1338N/A * Note that using the instanceof operator causes a class to be loaded.
1338N/A * Using this method doesn't load a class and it can be used instead of
1338N/A * the instanceof operator for performance reasons.
1338N/A *
1338N/A * @param obj Object to be checked
1338N/A * @param type The name of the interface/class. Must be
1338N/A * fully-qualified interface/class name.
1338N/A * @return true, if this object implements/extends the given
1338N/A * interface/class, false, otherwise, or if obj or type is null
1338N/A */
1338N/A public static boolean isInstanceOf(Object obj, String type) {
1338N/A if (obj == null) return false;
1338N/A if (type == null) return false;
1338N/A
1338N/A return isInstanceOf(obj.getClass(), type);
1338N/A }
1338N/A
1338N/A private static boolean isInstanceOf(Class cls, String type) {
1338N/A if (cls == null) return false;
1338N/A
1338N/A if (cls.getName().equals(type)) {
1338N/A return true;
1338N/A }
1338N/A
1338N/A for (Class c : cls.getInterfaces()) {
1338N/A if (c.getName().equals(type)) {
1338N/A return true;
1338N/A }
1338N/A }
1338N/A return isInstanceOf(cls.getSuperclass(), type);
1338N/A }
2860N/A
2860N/A ///////////////////////////////////////////////////////////////////////////
2860N/A //
2860N/A // The following methods help set and identify whether a particular
2860N/A // AWTEvent object was produced by the system or by user code. As of this
2860N/A // writing the only consumer is the Java Plug-In, although this information
2860N/A // could be useful to more clients and probably should be formalized in
2860N/A // the public API.
2860N/A //
2860N/A ///////////////////////////////////////////////////////////////////////////
2860N/A
2860N/A public static void setSystemGenerated(AWTEvent e) {
2860N/A AWTAccessor.getAWTEventAccessor().setSystemGenerated(e);
2860N/A }
2860N/A
2860N/A public static boolean isSystemGenerated(AWTEvent e) {
2860N/A return AWTAccessor.getAWTEventAccessor().isSystemGenerated(e);
2860N/A }
2860N/A
0N/A} // class SunToolkit
0N/A
0N/A
0N/A/*
0N/A * PostEventQueue is a Thread that runs in the same AppContext as the
0N/A * Java EventQueue. It is a queue of AWTEvents to be posted to the
0N/A * Java EventQueue. The toolkit Thread (AWT-Windows/AWT-Motif) posts
0N/A * events to this queue, which then calls EventQueue.postEvent().
0N/A *
0N/A * We do this because EventQueue.postEvent() may be overridden by client
0N/A * code, and we mustn't ever call client code from the toolkit thread.
0N/A */
0N/Aclass PostEventQueue {
0N/A private EventQueueItem queueHead = null;
0N/A private EventQueueItem queueTail = null;
0N/A private final EventQueue eventQueue;
0N/A
5565N/A // For the case when queue is cleared but events are not posted
5565N/A private volatile boolean isFlushing = false;
5565N/A
0N/A PostEventQueue(EventQueue eq) {
0N/A eventQueue = eq;
0N/A }
0N/A
2518N/A public synchronized boolean noEvents() {
5565N/A return queueHead == null && !isFlushing;
0N/A }
0N/A
0N/A /*
2518N/A * Continually post pending AWTEvents to the Java EventQueue. The method
2518N/A * is synchronized to ensure the flush is completed before a new event
2518N/A * can be posted to this queue.
5565N/A *
5565N/A * 7177040: The method couldn't be wholly synchronized because of calls
5565N/A * of EventQueue.postEvent() that uses pushPopLock, otherwise it could
5565N/A * potentially lead to deadlock
0N/A */
5565N/A public void flush() {
5565N/A EventQueueItem tempQueue;
5565N/A synchronized (this) {
5565N/A tempQueue = queueHead;
5565N/A queueHead = queueTail = null;
5565N/A isFlushing = (tempQueue != null);
5565N/A }
5565N/A try {
5565N/A while (tempQueue != null) {
5565N/A eventQueue.postEvent(tempQueue.event);
5565N/A tempQueue = tempQueue.next;
5565N/A }
5565N/A }
5565N/A finally {
5565N/A isFlushing = false;
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Enqueue an AWTEvent to be posted to the Java EventQueue.
0N/A */
0N/A void postEvent(AWTEvent event) {
0N/A EventQueueItem item = new EventQueueItem(event);
0N/A
0N/A synchronized (this) {
0N/A if (queueHead == null) {
0N/A queueHead = queueTail = item;
0N/A } else {
0N/A queueTail.next = item;
0N/A queueTail = item;
0N/A }
0N/A }
0N/A SunToolkit.wakeupEventQueue(eventQueue, event.getSource() == AWTAutoShutdown.getInstance());
0N/A }
0N/A} // class PostEventQueue