src/java.desktop/share/classes/sun/awt/SunToolkit.java

Print this page


   1 /*
   2  * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.awt;
  27 
  28 import java.awt.*;
  29 import static java.awt.RenderingHints.*;
  30 import java.awt.dnd.*;
  31 import java.awt.dnd.peer.DragSourceContextPeer;
  32 import java.awt.peer.*;
  33 import java.awt.event.WindowEvent;
  34 import java.awt.event.KeyEvent;
  35 import java.awt.image.*;
  36 import java.awt.TrayIcon;
  37 import java.awt.SystemTray;
  38 import java.awt.event.InputEvent;













  39 import java.io.File;
  40 import java.io.IOException;
  41 import java.io.InputStream;

  42 import java.net.URL;
  43 import java.security.PrivilegedAction;
  44 import java.util.*;





  45 import java.util.concurrent.TimeUnit;
  46 import java.util.concurrent.locks.Condition;
  47 import java.util.concurrent.locks.Lock;
  48 import java.util.concurrent.locks.ReentrantLock;
  49 
  50 import sun.awt.datatransfer.DataTransferer;
  51 import sun.util.logging.PlatformLogger;
  52 import sun.misc.SoftCache;
  53 import sun.font.FontDesignMetrics;
  54 import sun.awt.im.InputContext;
  55 import sun.awt.image.*;
  56 import sun.security.action.GetPropertyAction;







  57 import sun.security.action.GetBooleanAction;
  58 import java.lang.reflect.InvocationTargetException;
  59 import java.security.AccessController;


  60 
  61 public abstract class SunToolkit extends Toolkit
  62     implements ComponentFactory, InputMethodSupport, KeyboardFocusManagerPeerProvider {
  63 
  64     // 8014718: logging has been removed from SunToolkit
  65 
  66     /* Load debug settings for native code */
  67     static {
  68         if (AccessController.doPrivileged(new GetBooleanAction("sun.awt.nativedebug"))) {
  69             DebugSettings.init();
  70         }
  71     };
  72 
  73     /**
  74      * Special mask for the UngrabEvent events, in addition to the
  75      * public masks defined in AWTEvent.  Should be used as the mask
  76      * value for Toolkit.addAWTEventListener.
  77      */
  78     public static final int GRAB_EVENT_MASK = 0x80000000;
  79 


 117         try {
 118             eventQueue = (EventQueue)Class.forName(eqName).newInstance();
 119         } catch (Exception e) {
 120             e.printStackTrace();
 121             System.err.println("Failed loading " + eqName + ": " + e);
 122             eventQueue = new EventQueue();
 123         }
 124         appContext.put(AppContext.EVENT_QUEUE_KEY, eventQueue);
 125 
 126         PostEventQueue postEventQueue = new PostEventQueue(eventQueue);
 127         appContext.put(POST_EVENT_QUEUE_KEY, postEventQueue);
 128     }
 129 
 130     public SunToolkit() {
 131     }
 132 
 133     public boolean useBufferPerWindow() {
 134         return false;
 135     }
 136 
 137     public abstract WindowPeer createWindow(Window target)
 138         throws HeadlessException;
 139 
 140     public abstract FramePeer createFrame(Frame target)
 141         throws HeadlessException;
 142 
 143     public abstract FramePeer createLightweightFrame(LightweightFrame target)
 144         throws HeadlessException;
 145 
 146     public abstract DialogPeer createDialog(Dialog target)
 147         throws HeadlessException;
 148 
 149     public abstract ButtonPeer createButton(Button target)
 150         throws HeadlessException;
 151 
 152     public abstract TextFieldPeer createTextField(TextField target)
 153         throws HeadlessException;
 154 
 155     public abstract ChoicePeer createChoice(Choice target)
 156         throws HeadlessException;
 157 
 158     public abstract LabelPeer createLabel(Label target)
 159         throws HeadlessException;
 160 
 161     public abstract ListPeer createList(java.awt.List target)
 162         throws HeadlessException;
 163 
 164     public abstract CheckboxPeer createCheckbox(Checkbox target)
 165         throws HeadlessException;
 166 
 167     public abstract ScrollbarPeer createScrollbar(Scrollbar target)
 168         throws HeadlessException;
 169 
 170     public abstract ScrollPanePeer createScrollPane(ScrollPane target)
 171         throws HeadlessException;
 172 
 173     public abstract TextAreaPeer createTextArea(TextArea target)
 174         throws HeadlessException;
 175 
 176     public abstract FileDialogPeer createFileDialog(FileDialog target)
 177         throws HeadlessException;
 178 
 179     public abstract MenuBarPeer createMenuBar(MenuBar target)
 180         throws HeadlessException;
 181 
 182     public abstract MenuPeer createMenu(Menu target)
 183         throws HeadlessException;
 184 
 185     public abstract PopupMenuPeer createPopupMenu(PopupMenu target)
 186         throws HeadlessException;
 187 
 188     public abstract MenuItemPeer createMenuItem(MenuItem target)
 189         throws HeadlessException;
 190 
 191     public abstract CheckboxMenuItemPeer createCheckboxMenuItem(
 192         CheckboxMenuItem target)
 193         throws HeadlessException;
 194 
 195     public abstract DragSourceContextPeer createDragSourceContextPeer(
 196         DragGestureEvent dge)
 197         throws InvalidDnDOperationException;
 198 
 199     public abstract TrayIconPeer createTrayIcon(TrayIcon target)
 200         throws HeadlessException, AWTException;
 201 
 202     public abstract SystemTrayPeer createSystemTray(SystemTray target);
 203 
 204     public abstract boolean isTraySupported();
 205 
 206     @SuppressWarnings("deprecation")
 207     public abstract FontPeer getFontPeer(String name, int style);
 208 
 209     public abstract RobotPeer createRobot(Robot target, GraphicsDevice screen)
 210         throws AWTException;
 211 
 212     public abstract KeyboardFocusManagerPeer getKeyboardFocusManagerPeer()
 213         throws HeadlessException;
 214 
 215     /**
 216      * The AWT lock is typically only used on Unix platforms to synchronize
 217      * access to Xlib, OpenGL, etc.  However, these methods are implemented
 218      * in SunToolkit so that they can be called from shared code (e.g.
 219      * from the OGL pipeline) or from the X11 pipeline regardless of whether
 220      * XToolkit or MToolkit is currently in use.  There are native macros
 221      * (such as AWT_LOCK) defined in awt.h, so if the implementation of these
 222      * methods is changed, make sure it is compatible with the native macros.
 223      *
 224      * Note: The following methods (awtLock(), awtUnlock(), etc) should be
 225      * used in place of:
 226      *     synchronized (getAWTLock()) {
 227      *         ...
 228      *     }
 229      *
 230      * By factoring these methods out specially, we are able to change the
 231      * implementation of these methods (e.g. use more advanced locking


 494         // number of places throughout the toolkit that would
 495         // otherwise have to be modified to precisely identify
 496         // system-generated events.
 497         setSystemGenerated(event);
 498         AppContext eventContext = targetToAppContext(event.getSource());
 499         if (eventContext != null && !eventContext.equals(appContext)) {
 500             throw new RuntimeException("Event posted on wrong app context : " + event);
 501         }
 502         PostEventQueue postEventQueue =
 503             (PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY);
 504         if (postEventQueue != null) {
 505             postEventQueue.postEvent(event);
 506         }
 507     }
 508 
 509     /*
 510      * Post AWTEvent of high priority.
 511      */
 512     public static void postPriorityEvent(final AWTEvent e) {
 513         PeerEvent pe = new PeerEvent(Toolkit.getDefaultToolkit(), new Runnable() {

 514                 public void run() {
 515                     AWTAccessor.getAWTEventAccessor().setPosted(e);
 516                     ((Component)e.getSource()).dispatchEvent(e);
 517                 }
 518             }, PeerEvent.ULTIMATE_PRIORITY_EVENT);
 519         postEvent(targetToAppContext(e.getSource()), pe);
 520     }
 521 
 522     /*
 523      * Flush any pending events which haven't been posted to the AWT
 524      * EventQueue yet.
 525      */
 526     public static void flushPendingEvents()  {
 527         AppContext appContext = AppContext.getAppContext();
 528         flushPendingEvents(appContext);
 529     }
 530 
 531     /*
 532      * Flush the PostEventQueue for the right AppContext.
 533      * The default flushPendingEvents only flushes the thread-local context,


 544     /*
 545      * Execute a chunk of code on the Java event handler thread for the
 546      * given target.  Does not wait for the execution to occur before
 547      * returning to the caller.
 548      */
 549     public static void executeOnEventHandlerThread(Object target,
 550                                                    Runnable runnable) {
 551         executeOnEventHandlerThread(new PeerEvent(target, runnable, PeerEvent.PRIORITY_EVENT));
 552     }
 553 
 554     /*
 555      * Fixed 5064013: the InvocationEvent time should be equals
 556      * the time of the ActionEvent
 557      */
 558     @SuppressWarnings("serial")
 559     public static void executeOnEventHandlerThread(Object target,
 560                                                    Runnable runnable,
 561                                                    final long when) {
 562         executeOnEventHandlerThread(
 563             new PeerEvent(target, runnable, PeerEvent.PRIORITY_EVENT) {

 564                 public long getWhen() {
 565                     return when;
 566                 }
 567             });
 568     }
 569 
 570     /*
 571      * Execute a chunk of code on the Java event handler thread for the
 572      * given target.  Does not wait for the execution to occur before
 573      * returning to the caller.
 574      */
 575     public static void executeOnEventHandlerThread(PeerEvent peerEvent) {
 576         postEvent(targetToAppContext(peerEvent.getSource()), peerEvent);
 577     }
 578 
 579     /*
 580      * Execute a chunk of code on the Java event handler thread. The
 581      * method takes into account provided AppContext and sets
 582      * <code>SunToolkit.getDefaultToolkit()</code> as a target of the
 583      * event. See 6451487 for detailes.


 619         Throwable eventThrowable = event.getThrowable();
 620         if (eventThrowable != null) {
 621             throw new InvocationTargetException(eventThrowable);
 622         }
 623     }
 624 
 625     /*
 626      * Returns true if the calling thread is the event dispatch thread
 627      * contained within AppContext which associated with the given target.
 628      * Use this call to ensure that a given task is being executed
 629      * (or not being) on the event dispatch thread for the given target.
 630      */
 631     public static boolean isDispatchThreadForAppContext(Object target) {
 632         AppContext appContext = targetToAppContext(target);
 633         EventQueue eq = (EventQueue)appContext.get(AppContext.EVENT_QUEUE_KEY);
 634 
 635         AWTAccessor.EventQueueAccessor accessor = AWTAccessor.getEventQueueAccessor();
 636         return accessor.isDispatchThreadImpl(eq);
 637     }
 638 

 639     public Dimension getScreenSize() {
 640         return new Dimension(getScreenWidth(), getScreenHeight());
 641     }
 642     protected abstract int getScreenWidth();
 643     protected abstract int getScreenHeight();
 644 

 645     @SuppressWarnings("deprecation")
 646     public FontMetrics getFontMetrics(Font font) {
 647         return FontDesignMetrics.getMetrics(font);
 648     }
 649 

 650     @SuppressWarnings("deprecation")
 651     public String[] getFontList() {
 652         String[] hardwiredFontList = {
 653             Font.DIALOG, Font.SANS_SERIF, Font.SERIF, Font.MONOSPACED,
 654             Font.DIALOG_INPUT
 655 
 656             // -- Obsolete font names from 1.0.2.  It was decided that
 657             // -- getFontList should not return these old names:
 658             //    "Helvetica", "TimesRoman", "Courier", "ZapfDingbats"
 659         };
 660         return hardwiredFontList;
 661     }
 662 
 663     public PanelPeer createPanel(Panel target) {
 664         return (PanelPeer)createComponent(target);
 665     }
 666 
 667     public CanvasPeer createCanvas(Canvas target) {
 668         return (CanvasPeer)createComponent(target);
 669     }
 670 
 671     /**
 672      * Disables erasing of background on the canvas before painting if
 673      * this is supported by the current toolkit. It is recommended to
 674      * call this method early, before the Canvas becomes displayable,
 675      * because some Toolkit implementations do not support changing
 676      * this property once the Canvas becomes displayable.
 677      */
 678     public void disableBackgroundErase(Canvas canvas) {
 679         disableBackgroundEraseImpl(canvas);
 680     }
 681 
 682     /**
 683      * Disables the native erasing of the background on the given
 684      * component before painting if this is supported by the current
 685      * toolkit. This only has an effect for certain components such as
 686      * Canvas, Panel and Window. It is recommended to call this method
 687      * early, before the Component becomes displayable, because some
 688      * Toolkit implementations do not support changing this property
 689      * once the Component becomes displayable.
 690      */


 730             return img;
 731         }
 732     }
 733 
 734     static Image getImageFromHash(Toolkit tk,
 735                                                String filename) {
 736         checkPermissions(filename);
 737         synchronized (imgCache) {
 738             Image img = (Image)imgCache.get(filename);
 739             if (img == null) {
 740                 try {
 741                     img = tk.createImage(new FileImageSource(filename));
 742                     imgCache.put(filename, img);
 743                 } catch (Exception e) {
 744                 }
 745             }
 746             return img;
 747         }
 748     }
 749 

 750     public Image getImage(String filename) {
 751         return getImageFromHash(this, filename);
 752     }
 753 

 754     public Image getImage(URL url) {
 755         return getImageFromHash(this, url);
 756     }
 757 
 758     protected Image getImageWithResolutionVariant(String fileName,
 759             String resolutionVariantName) {
 760         synchronized (imgCache) {
 761             Image image = getImageFromHash(this, fileName);
 762             if (image instanceof MultiResolutionImage) {
 763                 return image;
 764             }
 765             Image resolutionVariant = getImageFromHash(this, resolutionVariantName);
 766             image = createImageWithResolutionVariant(image, resolutionVariant);
 767             imgCache.put(fileName, image);
 768             return image;
 769         }
 770     }
 771 
 772     protected Image getImageWithResolutionVariant(URL url,
 773             URL resolutionVariantURL) {
 774         synchronized (imgCache) {
 775             Image image = getImageFromHash(this, url);
 776             if (image instanceof MultiResolutionImage) {
 777                 return image;
 778             }
 779             Image resolutionVariant = getImageFromHash(this, resolutionVariantURL);
 780             image = createImageWithResolutionVariant(image, resolutionVariant);
 781             imgCache.put(url, image);
 782             return image;
 783         }
 784     }
 785 
 786 

 787     public Image createImage(String filename) {
 788         checkPermissions(filename);
 789         return createImage(new FileImageSource(filename));
 790     }
 791 

 792     public Image createImage(URL url) {
 793         checkPermissions(url);
 794         return createImage(new URLImageSource(url));
 795     }
 796 

 797     public Image createImage(byte[] data, int offset, int length) {
 798         return createImage(new ByteArrayImageSource(data, offset, length));
 799     }
 800 

 801     public Image createImage(ImageProducer producer) {
 802         return new ToolkitImage(producer);
 803     }
 804 
 805     public static Image createImageWithResolutionVariant(Image image,
 806             Image resolutionVariant) {
 807         return new MultiResolutionToolkitImage(image, resolutionVariant);
 808     }
 809 

 810     public int checkImage(Image img, int w, int h, ImageObserver o) {
 811         if (!(img instanceof ToolkitImage)) {
 812             return ImageObserver.ALLBITS;
 813         }
 814 
 815         ToolkitImage tkimg = (ToolkitImage)img;
 816         int repbits;
 817         if (w == 0 || h == 0) {
 818             repbits = ImageObserver.ALLBITS;
 819         } else {
 820             repbits = tkimg.getImageRep().check(o);
 821         }
 822         return (tkimg.check(o) | repbits) & checkResolutionVariant(img, w, h, o);
 823     }
 824 

 825     public boolean prepareImage(Image img, int w, int h, ImageObserver o) {
 826         if (w == 0 || h == 0) {
 827             return true;
 828         }
 829 
 830         // Must be a ToolkitImage
 831         if (!(img instanceof ToolkitImage)) {
 832             return true;
 833         }
 834 
 835         ToolkitImage tkimg = (ToolkitImage)img;
 836         if (tkimg.hasError()) {
 837             if (o != null) {
 838                 o.imageUpdate(img, ImageObserver.ERROR|ImageObserver.ABORT,
 839                               -1, -1, -1, -1);
 840             }
 841             return false;
 842         }
 843         ImageRepresentation ir = tkimg.getImageRep();
 844         return ir.prepare(o) & prepareResolutionVariant(img, w, h, o);


1046         try {
1047             int x = (width - bestWidth) / 2;
1048             int y = (height - bestHeight) / 2;
1049             g.drawImage(bestImage, x, y, bestWidth, bestHeight, null);
1050         } finally {
1051             g.dispose();
1052         }
1053         return bimage;
1054     }
1055 
1056     public static DataBufferInt getScaledIconData(java.util.List<Image> imageList, int width, int height) {
1057         BufferedImage bimage = getScaledIconImage(imageList, width, height);
1058         if (bimage == null) {
1059             return null;
1060         }
1061         Raster raster = bimage.getRaster();
1062         DataBuffer buffer = raster.getDataBuffer();
1063         return (DataBufferInt)buffer;
1064     }
1065 

1066     protected EventQueue getSystemEventQueueImpl() {
1067         return getSystemEventQueueImplPP();
1068     }
1069 
1070     // Package private implementation
1071     static EventQueue getSystemEventQueueImplPP() {
1072         return getSystemEventQueueImplPP(AppContext.getAppContext());
1073     }
1074 
1075     public static EventQueue getSystemEventQueueImplPP(AppContext appContext) {
1076         EventQueue theEventQueue =
1077             (EventQueue)appContext.get(AppContext.EVENT_QUEUE_KEY);
1078         return theEventQueue;
1079     }
1080 
1081     /**
1082      * Give native peers the ability to query the native container
1083      * given a native component (eg the direct parent may be lightweight).
1084      */
1085     public static Container getNativeContainer(Component c) {


1127             if (sm != null) {
1128                 sm.checkPermission(AWTPermissions.SET_WINDOW_ALWAYS_ON_TOP_PERMISSION);
1129             }
1130         } catch (SecurityException se) {
1131             // There is no permission to show popups over the task bar
1132             result = false;
1133         }
1134         return result;
1135     }
1136 
1137     /**
1138      * Returns a new input method window, with behavior as specified in
1139      * {@link java.awt.im.spi.InputMethodContext#createInputMethodWindow}.
1140      * If the inputContext is not null, the window should return it from its
1141      * getInputContext() method. The window needs to implement
1142      * sun.awt.im.InputMethodWindow.
1143      * <p>
1144      * SunToolkit subclasses can override this method to return better input
1145      * method windows.
1146      */

1147     public Window createInputMethodWindow(String title, InputContext context) {
1148         return new sun.awt.im.SimpleInputMethodWindow(title, context);
1149     }
1150 
1151     /**
1152      * Returns whether enableInputMethods should be set to true for peered
1153      * TextComponent instances on this platform. False by default.
1154      */

1155     public boolean enableInputMethodsForTextComponent() {
1156         return false;
1157     }
1158 
1159     private static Locale startupLocale = null;
1160 
1161     /**
1162      * Returns the locale in which the runtime was started.
1163      */
1164     public static Locale getStartupLocale() {
1165         if (startupLocale == null) {
1166             String language, region, country, variant;
1167             language = AccessController.doPrivileged(
1168                             new GetPropertyAction("user.language", "en"));
1169             // for compatibility, check for old user.region property
1170             region = AccessController.doPrivileged(
1171                             new GetPropertyAction("user.region"));
1172             if (region != null) {
1173                 // region can be of form country, country_variant, or _variant
1174                 int i = region.indexOf('_');


1176                     country = region.substring(0, i);
1177                     variant = region.substring(i + 1);
1178                 } else {
1179                     country = region;
1180                     variant = "";
1181                 }
1182             } else {
1183                 country = AccessController.doPrivileged(
1184                                 new GetPropertyAction("user.country", ""));
1185                 variant = AccessController.doPrivileged(
1186                                 new GetPropertyAction("user.variant", ""));
1187             }
1188             startupLocale = new Locale(language, country, variant);
1189         }
1190         return startupLocale;
1191     }
1192 
1193     /**
1194      * Returns the default keyboard locale of the underlying operating system
1195      */

1196     public Locale getDefaultKeyboardLocale() {
1197         return getStartupLocale();
1198     }
1199 
1200     private static DefaultMouseInfoPeer mPeer = null;
1201 
1202     protected synchronized MouseInfoPeer getMouseInfoPeer() {

1203         if (mPeer == null) {
1204             mPeer = new DefaultMouseInfoPeer();
1205         }
1206         return mPeer;
1207     }
1208 
1209 
1210     /**
1211      * Returns whether default toolkit needs the support of the xembed
1212      * from embedding host(if any).
1213      * @return <code>true</code>, if XEmbed is needed, <code>false</code> otherwise
1214      */
1215     public static boolean needsXEmbed() {
1216         String noxembed = AccessController.
1217             doPrivileged(new GetPropertyAction("sun.awt.noxembed", "false"));
1218         if ("true".equals(noxembed)) {
1219             return false;
1220         }
1221 
1222         Toolkit tk = Toolkit.getDefaultToolkit();


1314      * @return true if the window is modal excluded, false otherwise. If
1315      * the modal exclusion isn't supported by the current Toolkit, false
1316      * is returned
1317      *
1318      * @see sun.awt.SunToolkit#isModalExcludedSupported
1319      * @see sun.awt.SunToolkit#setModalExcluded(java.awt.Window)
1320      *
1321      * @since 1.5
1322      */
1323     public static boolean isModalExcluded(Window window)
1324     {
1325         if (DEFAULT_MODAL_EXCLUSION_TYPE == null) {
1326             DEFAULT_MODAL_EXCLUSION_TYPE = Dialog.ModalExclusionType.APPLICATION_EXCLUDE;
1327         }
1328         return window.getModalExclusionType().compareTo(DEFAULT_MODAL_EXCLUSION_TYPE) >= 0;
1329     }
1330 
1331     /**
1332      * Overridden in XToolkit and WToolkit
1333      */

1334     public boolean isModalityTypeSupported(Dialog.ModalityType modalityType) {
1335         return (modalityType == Dialog.ModalityType.MODELESS) ||
1336                (modalityType == Dialog.ModalityType.APPLICATION_MODAL);
1337     }
1338 
1339     /**
1340      * Overridden in XToolkit and WToolkit
1341      */

1342     public boolean isModalExclusionTypeSupported(Dialog.ModalExclusionType exclusionType) {
1343         return (exclusionType == Dialog.ModalExclusionType.NO_EXCLUDE);
1344     }
1345 
1346     ///////////////////////////////////////////////////////////////////////////
1347     //
1348     // The following is used by the Java Plug-in to coordinate dialog modality
1349     // between containing applications (browsers, ActiveX containers etc) and
1350     // the AWT.
1351     //
1352     ///////////////////////////////////////////////////////////////////////////
1353 
1354     private ModalityListenerList modalityListeners = new ModalityListenerList();
1355 
1356     public void addModalityListener(ModalityListener listener) {
1357         modalityListeners.add(listener);
1358     }
1359 
1360     public void removeModalityListener(ModalityListener listener) {
1361         modalityListeners.remove(listener);


1369         notifyModalityChange(ModalityEvent.MODALITY_POPPED, dialog);
1370     }
1371 
1372     final void notifyModalityChange(int id, Dialog source) {
1373         ModalityEvent ev = new ModalityEvent(source, modalityListeners, id);
1374         ev.dispatch();
1375     }
1376 
1377     static class ModalityListenerList implements ModalityListener {
1378 
1379         Vector<ModalityListener> listeners = new Vector<ModalityListener>();
1380 
1381         void add(ModalityListener listener) {
1382             listeners.addElement(listener);
1383         }
1384 
1385         void remove(ModalityListener listener) {
1386             listeners.removeElement(listener);
1387         }
1388 

1389         public void modalityPushed(ModalityEvent ev) {
1390             Iterator<ModalityListener> it = listeners.iterator();
1391             while (it.hasNext()) {
1392                 it.next().modalityPushed(ev);
1393             }
1394         }
1395 

1396         public void modalityPopped(ModalityEvent ev) {
1397             Iterator<ModalityListener> it = listeners.iterator();
1398             while (it.hasNext()) {
1399                 it.next().modalityPopped(ev);
1400             }
1401         }
1402     } // end of class ModalityListenerList
1403 
1404     ///////////////////////////////////////////////////////////////////////////
1405     // End Plug-in code
1406     ///////////////////////////////////////////////////////////////////////////
1407 
1408     public static boolean isLightweightOrUnknown(Component comp) {
1409         if (comp.isLightweight()
1410             || !(getDefaultToolkit() instanceof SunToolkit))
1411         {
1412             return true;
1413         }
1414         return !(comp instanceof Button
1415             || comp instanceof Canvas


1575         EventQueue queue = getSystemEventQueueImpl();
1576         return AWTAccessor.getEventQueueAccessor().noEvents(queue);
1577     }
1578 
1579     /**
1580      * Waits for the Java event queue to empty.  Ensures that all
1581      * events are processed (including paint events), and that if
1582      * recursive events were generated, they are also processed.
1583      * Should return <code>true</code> if more processing is
1584      * necessary, <code>false</code> otherwise.
1585      */
1586     @SuppressWarnings("serial")
1587     protected final boolean waitForIdle(final long timeout) {
1588         flushPendingEvents();
1589         boolean queueWasEmpty = isEQEmpty();
1590         queueEmpty = false;
1591         eventDispatched = false;
1592         synchronized(waitLock) {
1593             postEvent(AppContext.getAppContext(),
1594                       new PeerEvent(getSystemEventQueueImpl(), null, PeerEvent.LOW_PRIORITY_EVENT) {

1595                           public void dispatch() {
1596                               // Here we block EDT.  It could have some
1597                               // events, it should have dispatched them by
1598                               // now.  So native requests could have been
1599                               // generated.  First, dispatch them.  Then,
1600                               // flush Java events again.
1601                               int iters = 0;
1602                               while (iters < MIN_ITERS) {
1603                                   syncNativeQueue(timeout);
1604                                   iters++;
1605                               }
1606                               while (syncNativeQueue(timeout) && iters < MAX_ITERS) {
1607                                   iters++;
1608                               }
1609                               flushPendingEvents();
1610 
1611                               synchronized(waitLock) {
1612                                   queueEmpty = isEQEmpty();
1613                                   eventDispatched = true;
1614                                   waitLock.notifyAll();


   1 /*
   2  * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.awt;
  27 
  28 import java.awt.*;









  29 import java.awt.event.InputEvent;
  30 import java.awt.event.KeyEvent;
  31 import java.awt.event.WindowEvent;
  32 import java.awt.image.BufferedImage;
  33 import java.awt.image.DataBuffer;
  34 import java.awt.image.DataBufferInt;
  35 import java.awt.image.ImageObserver;
  36 import java.awt.image.ImageProducer;
  37 import java.awt.image.Raster;
  38 import java.awt.peer.FramePeer;
  39 import java.awt.peer.KeyboardFocusManagerPeer;
  40 import java.awt.peer.MouseInfoPeer;
  41 import java.awt.peer.SystemTrayPeer;
  42 import java.awt.peer.TrayIconPeer;
  43 import java.io.File;
  44 import java.io.IOException;
  45 import java.io.InputStream;
  46 import java.lang.reflect.InvocationTargetException;
  47 import java.net.URL;
  48 import java.security.AccessController;
  49 import java.util.Collections;
  50 import java.util.Iterator;
  51 import java.util.Locale;
  52 import java.util.Map;
  53 import java.util.Vector;
  54 import java.util.WeakHashMap;
  55 import java.util.concurrent.TimeUnit;
  56 import java.util.concurrent.locks.Condition;

  57 import java.util.concurrent.locks.ReentrantLock;
  58 




  59 import sun.awt.im.InputContext;
  60 import sun.awt.image.ByteArrayImageSource;
  61 import sun.awt.image.FileImageSource;
  62 import sun.awt.image.ImageRepresentation;
  63 import sun.awt.image.MultiResolutionImage;
  64 import sun.awt.image.MultiResolutionToolkitImage;
  65 import sun.awt.image.ToolkitImage;
  66 import sun.awt.image.URLImageSource;
  67 import sun.font.FontDesignMetrics;
  68 import sun.misc.SoftCache;
  69 import sun.security.action.GetBooleanAction;
  70 import sun.security.action.GetPropertyAction;
  71 import sun.util.logging.PlatformLogger;
  72 
  73 import static java.awt.RenderingHints.*;
  74 
  75 public abstract class SunToolkit extends Toolkit
  76     implements ComponentFactory, InputMethodSupport, KeyboardFocusManagerPeerProvider {
  77 
  78     // 8014718: logging has been removed from SunToolkit
  79 
  80     /* Load debug settings for native code */
  81     static {
  82         if (AccessController.doPrivileged(new GetBooleanAction("sun.awt.nativedebug"))) {
  83             DebugSettings.init();
  84         }
  85     };
  86 
  87     /**
  88      * Special mask for the UngrabEvent events, in addition to the
  89      * public masks defined in AWTEvent.  Should be used as the mask
  90      * value for Toolkit.addAWTEventListener.
  91      */
  92     public static final int GRAB_EVENT_MASK = 0x80000000;
  93 


 131         try {
 132             eventQueue = (EventQueue)Class.forName(eqName).newInstance();
 133         } catch (Exception e) {
 134             e.printStackTrace();
 135             System.err.println("Failed loading " + eqName + ": " + e);
 136             eventQueue = new EventQueue();
 137         }
 138         appContext.put(AppContext.EVENT_QUEUE_KEY, eventQueue);
 139 
 140         PostEventQueue postEventQueue = new PostEventQueue(eventQueue);
 141         appContext.put(POST_EVENT_QUEUE_KEY, postEventQueue);
 142     }
 143 
 144     public SunToolkit() {
 145     }
 146 
 147     public boolean useBufferPerWindow() {
 148         return false;
 149     }
 150 






 151     public abstract FramePeer createLightweightFrame(LightweightFrame target)
 152         throws HeadlessException;
 153 





















































 154     public abstract TrayIconPeer createTrayIcon(TrayIcon target)
 155         throws HeadlessException, AWTException;
 156 
 157     public abstract SystemTrayPeer createSystemTray(SystemTray target);
 158 
 159     public abstract boolean isTraySupported();
 160 
 161     @Override





 162     public abstract KeyboardFocusManagerPeer getKeyboardFocusManagerPeer()
 163         throws HeadlessException;
 164 
 165     /**
 166      * The AWT lock is typically only used on Unix platforms to synchronize
 167      * access to Xlib, OpenGL, etc.  However, these methods are implemented
 168      * in SunToolkit so that they can be called from shared code (e.g.
 169      * from the OGL pipeline) or from the X11 pipeline regardless of whether
 170      * XToolkit or MToolkit is currently in use.  There are native macros
 171      * (such as AWT_LOCK) defined in awt.h, so if the implementation of these
 172      * methods is changed, make sure it is compatible with the native macros.
 173      *
 174      * Note: The following methods (awtLock(), awtUnlock(), etc) should be
 175      * used in place of:
 176      *     synchronized (getAWTLock()) {
 177      *         ...
 178      *     }
 179      *
 180      * By factoring these methods out specially, we are able to change the
 181      * implementation of these methods (e.g. use more advanced locking


 444         // number of places throughout the toolkit that would
 445         // otherwise have to be modified to precisely identify
 446         // system-generated events.
 447         setSystemGenerated(event);
 448         AppContext eventContext = targetToAppContext(event.getSource());
 449         if (eventContext != null && !eventContext.equals(appContext)) {
 450             throw new RuntimeException("Event posted on wrong app context : " + event);
 451         }
 452         PostEventQueue postEventQueue =
 453             (PostEventQueue)appContext.get(POST_EVENT_QUEUE_KEY);
 454         if (postEventQueue != null) {
 455             postEventQueue.postEvent(event);
 456         }
 457     }
 458 
 459     /*
 460      * Post AWTEvent of high priority.
 461      */
 462     public static void postPriorityEvent(final AWTEvent e) {
 463         PeerEvent pe = new PeerEvent(Toolkit.getDefaultToolkit(), new Runnable() {
 464                 @Override
 465                 public void run() {
 466                     AWTAccessor.getAWTEventAccessor().setPosted(e);
 467                     ((Component)e.getSource()).dispatchEvent(e);
 468                 }
 469             }, PeerEvent.ULTIMATE_PRIORITY_EVENT);
 470         postEvent(targetToAppContext(e.getSource()), pe);
 471     }
 472 
 473     /*
 474      * Flush any pending events which haven't been posted to the AWT
 475      * EventQueue yet.
 476      */
 477     public static void flushPendingEvents()  {
 478         AppContext appContext = AppContext.getAppContext();
 479         flushPendingEvents(appContext);
 480     }
 481 
 482     /*
 483      * Flush the PostEventQueue for the right AppContext.
 484      * The default flushPendingEvents only flushes the thread-local context,


 495     /*
 496      * Execute a chunk of code on the Java event handler thread for the
 497      * given target.  Does not wait for the execution to occur before
 498      * returning to the caller.
 499      */
 500     public static void executeOnEventHandlerThread(Object target,
 501                                                    Runnable runnable) {
 502         executeOnEventHandlerThread(new PeerEvent(target, runnable, PeerEvent.PRIORITY_EVENT));
 503     }
 504 
 505     /*
 506      * Fixed 5064013: the InvocationEvent time should be equals
 507      * the time of the ActionEvent
 508      */
 509     @SuppressWarnings("serial")
 510     public static void executeOnEventHandlerThread(Object target,
 511                                                    Runnable runnable,
 512                                                    final long when) {
 513         executeOnEventHandlerThread(
 514             new PeerEvent(target, runnable, PeerEvent.PRIORITY_EVENT) {
 515                 @Override
 516                 public long getWhen() {
 517                     return when;
 518                 }
 519             });
 520     }
 521 
 522     /*
 523      * Execute a chunk of code on the Java event handler thread for the
 524      * given target.  Does not wait for the execution to occur before
 525      * returning to the caller.
 526      */
 527     public static void executeOnEventHandlerThread(PeerEvent peerEvent) {
 528         postEvent(targetToAppContext(peerEvent.getSource()), peerEvent);
 529     }
 530 
 531     /*
 532      * Execute a chunk of code on the Java event handler thread. The
 533      * method takes into account provided AppContext and sets
 534      * <code>SunToolkit.getDefaultToolkit()</code> as a target of the
 535      * event. See 6451487 for detailes.


 571         Throwable eventThrowable = event.getThrowable();
 572         if (eventThrowable != null) {
 573             throw new InvocationTargetException(eventThrowable);
 574         }
 575     }
 576 
 577     /*
 578      * Returns true if the calling thread is the event dispatch thread
 579      * contained within AppContext which associated with the given target.
 580      * Use this call to ensure that a given task is being executed
 581      * (or not being) on the event dispatch thread for the given target.
 582      */
 583     public static boolean isDispatchThreadForAppContext(Object target) {
 584         AppContext appContext = targetToAppContext(target);
 585         EventQueue eq = (EventQueue)appContext.get(AppContext.EVENT_QUEUE_KEY);
 586 
 587         AWTAccessor.EventQueueAccessor accessor = AWTAccessor.getEventQueueAccessor();
 588         return accessor.isDispatchThreadImpl(eq);
 589     }
 590 
 591     @Override
 592     public Dimension getScreenSize() {
 593         return new Dimension(getScreenWidth(), getScreenHeight());
 594     }
 595     protected abstract int getScreenWidth();
 596     protected abstract int getScreenHeight();
 597 
 598     @Override
 599     @SuppressWarnings("deprecation")
 600     public FontMetrics getFontMetrics(Font font) {
 601         return FontDesignMetrics.getMetrics(font);
 602     }
 603 
 604     @Override
 605     @SuppressWarnings("deprecation")
 606     public String[] getFontList() {
 607         String[] hardwiredFontList = {
 608             Font.DIALOG, Font.SANS_SERIF, Font.SERIF, Font.MONOSPACED,
 609             Font.DIALOG_INPUT
 610 
 611             // -- Obsolete font names from 1.0.2.  It was decided that
 612             // -- getFontList should not return these old names:
 613             //    "Helvetica", "TimesRoman", "Courier", "ZapfDingbats"
 614         };
 615         return hardwiredFontList;
 616     }
 617 








 618     /**
 619      * Disables erasing of background on the canvas before painting if
 620      * this is supported by the current toolkit. It is recommended to
 621      * call this method early, before the Canvas becomes displayable,
 622      * because some Toolkit implementations do not support changing
 623      * this property once the Canvas becomes displayable.
 624      */
 625     public void disableBackgroundErase(Canvas canvas) {
 626         disableBackgroundEraseImpl(canvas);
 627     }
 628 
 629     /**
 630      * Disables the native erasing of the background on the given
 631      * component before painting if this is supported by the current
 632      * toolkit. This only has an effect for certain components such as
 633      * Canvas, Panel and Window. It is recommended to call this method
 634      * early, before the Component becomes displayable, because some
 635      * Toolkit implementations do not support changing this property
 636      * once the Component becomes displayable.
 637      */


 677             return img;
 678         }
 679     }
 680 
 681     static Image getImageFromHash(Toolkit tk,
 682                                                String filename) {
 683         checkPermissions(filename);
 684         synchronized (imgCache) {
 685             Image img = (Image)imgCache.get(filename);
 686             if (img == null) {
 687                 try {
 688                     img = tk.createImage(new FileImageSource(filename));
 689                     imgCache.put(filename, img);
 690                 } catch (Exception e) {
 691                 }
 692             }
 693             return img;
 694         }
 695     }
 696 
 697     @Override
 698     public Image getImage(String filename) {
 699         return getImageFromHash(this, filename);
 700     }
 701 
 702     @Override
 703     public Image getImage(URL url) {
 704         return getImageFromHash(this, url);
 705     }
 706 
 707     protected Image getImageWithResolutionVariant(String fileName,
 708             String resolutionVariantName) {
 709         synchronized (imgCache) {
 710             Image image = getImageFromHash(this, fileName);
 711             if (image instanceof MultiResolutionImage) {
 712                 return image;
 713             }
 714             Image resolutionVariant = getImageFromHash(this, resolutionVariantName);
 715             image = createImageWithResolutionVariant(image, resolutionVariant);
 716             imgCache.put(fileName, image);
 717             return image;
 718         }
 719     }
 720 
 721     protected Image getImageWithResolutionVariant(URL url,
 722             URL resolutionVariantURL) {
 723         synchronized (imgCache) {
 724             Image image = getImageFromHash(this, url);
 725             if (image instanceof MultiResolutionImage) {
 726                 return image;
 727             }
 728             Image resolutionVariant = getImageFromHash(this, resolutionVariantURL);
 729             image = createImageWithResolutionVariant(image, resolutionVariant);
 730             imgCache.put(url, image);
 731             return image;
 732         }
 733     }
 734 
 735 
 736     @Override
 737     public Image createImage(String filename) {
 738         checkPermissions(filename);
 739         return createImage(new FileImageSource(filename));
 740     }
 741 
 742     @Override
 743     public Image createImage(URL url) {
 744         checkPermissions(url);
 745         return createImage(new URLImageSource(url));
 746     }
 747 
 748     @Override
 749     public Image createImage(byte[] data, int offset, int length) {
 750         return createImage(new ByteArrayImageSource(data, offset, length));
 751     }
 752 
 753     @Override
 754     public Image createImage(ImageProducer producer) {
 755         return new ToolkitImage(producer);
 756     }
 757 
 758     public static Image createImageWithResolutionVariant(Image image,
 759             Image resolutionVariant) {
 760         return new MultiResolutionToolkitImage(image, resolutionVariant);
 761     }
 762 
 763     @Override
 764     public int checkImage(Image img, int w, int h, ImageObserver o) {
 765         if (!(img instanceof ToolkitImage)) {
 766             return ImageObserver.ALLBITS;
 767         }
 768 
 769         ToolkitImage tkimg = (ToolkitImage)img;
 770         int repbits;
 771         if (w == 0 || h == 0) {
 772             repbits = ImageObserver.ALLBITS;
 773         } else {
 774             repbits = tkimg.getImageRep().check(o);
 775         }
 776         return (tkimg.check(o) | repbits) & checkResolutionVariant(img, w, h, o);
 777     }
 778 
 779     @Override
 780     public boolean prepareImage(Image img, int w, int h, ImageObserver o) {
 781         if (w == 0 || h == 0) {
 782             return true;
 783         }
 784 
 785         // Must be a ToolkitImage
 786         if (!(img instanceof ToolkitImage)) {
 787             return true;
 788         }
 789 
 790         ToolkitImage tkimg = (ToolkitImage)img;
 791         if (tkimg.hasError()) {
 792             if (o != null) {
 793                 o.imageUpdate(img, ImageObserver.ERROR|ImageObserver.ABORT,
 794                               -1, -1, -1, -1);
 795             }
 796             return false;
 797         }
 798         ImageRepresentation ir = tkimg.getImageRep();
 799         return ir.prepare(o) & prepareResolutionVariant(img, w, h, o);


1001         try {
1002             int x = (width - bestWidth) / 2;
1003             int y = (height - bestHeight) / 2;
1004             g.drawImage(bestImage, x, y, bestWidth, bestHeight, null);
1005         } finally {
1006             g.dispose();
1007         }
1008         return bimage;
1009     }
1010 
1011     public static DataBufferInt getScaledIconData(java.util.List<Image> imageList, int width, int height) {
1012         BufferedImage bimage = getScaledIconImage(imageList, width, height);
1013         if (bimage == null) {
1014             return null;
1015         }
1016         Raster raster = bimage.getRaster();
1017         DataBuffer buffer = raster.getDataBuffer();
1018         return (DataBufferInt)buffer;
1019     }
1020 
1021     @Override
1022     protected EventQueue getSystemEventQueueImpl() {
1023         return getSystemEventQueueImplPP();
1024     }
1025 
1026     // Package private implementation
1027     static EventQueue getSystemEventQueueImplPP() {
1028         return getSystemEventQueueImplPP(AppContext.getAppContext());
1029     }
1030 
1031     public static EventQueue getSystemEventQueueImplPP(AppContext appContext) {
1032         EventQueue theEventQueue =
1033             (EventQueue)appContext.get(AppContext.EVENT_QUEUE_KEY);
1034         return theEventQueue;
1035     }
1036 
1037     /**
1038      * Give native peers the ability to query the native container
1039      * given a native component (eg the direct parent may be lightweight).
1040      */
1041     public static Container getNativeContainer(Component c) {


1083             if (sm != null) {
1084                 sm.checkPermission(AWTPermissions.SET_WINDOW_ALWAYS_ON_TOP_PERMISSION);
1085             }
1086         } catch (SecurityException se) {
1087             // There is no permission to show popups over the task bar
1088             result = false;
1089         }
1090         return result;
1091     }
1092 
1093     /**
1094      * Returns a new input method window, with behavior as specified in
1095      * {@link java.awt.im.spi.InputMethodContext#createInputMethodWindow}.
1096      * If the inputContext is not null, the window should return it from its
1097      * getInputContext() method. The window needs to implement
1098      * sun.awt.im.InputMethodWindow.
1099      * <p>
1100      * SunToolkit subclasses can override this method to return better input
1101      * method windows.
1102      */
1103     @Override
1104     public Window createInputMethodWindow(String title, InputContext context) {
1105         return new sun.awt.im.SimpleInputMethodWindow(title, context);
1106     }
1107 
1108     /**
1109      * Returns whether enableInputMethods should be set to true for peered
1110      * TextComponent instances on this platform. False by default.
1111      */
1112     @Override
1113     public boolean enableInputMethodsForTextComponent() {
1114         return false;
1115     }
1116 
1117     private static Locale startupLocale = null;
1118 
1119     /**
1120      * Returns the locale in which the runtime was started.
1121      */
1122     public static Locale getStartupLocale() {
1123         if (startupLocale == null) {
1124             String language, region, country, variant;
1125             language = AccessController.doPrivileged(
1126                             new GetPropertyAction("user.language", "en"));
1127             // for compatibility, check for old user.region property
1128             region = AccessController.doPrivileged(
1129                             new GetPropertyAction("user.region"));
1130             if (region != null) {
1131                 // region can be of form country, country_variant, or _variant
1132                 int i = region.indexOf('_');


1134                     country = region.substring(0, i);
1135                     variant = region.substring(i + 1);
1136                 } else {
1137                     country = region;
1138                     variant = "";
1139                 }
1140             } else {
1141                 country = AccessController.doPrivileged(
1142                                 new GetPropertyAction("user.country", ""));
1143                 variant = AccessController.doPrivileged(
1144                                 new GetPropertyAction("user.variant", ""));
1145             }
1146             startupLocale = new Locale(language, country, variant);
1147         }
1148         return startupLocale;
1149     }
1150 
1151     /**
1152      * Returns the default keyboard locale of the underlying operating system
1153      */
1154     @Override
1155     public Locale getDefaultKeyboardLocale() {
1156         return getStartupLocale();
1157     }
1158 
1159     private static DefaultMouseInfoPeer mPeer = null;
1160 
1161     @Override
1162     public synchronized MouseInfoPeer getMouseInfoPeer() {
1163         if (mPeer == null) {
1164             mPeer = new DefaultMouseInfoPeer();
1165         }
1166         return mPeer;
1167     }
1168 
1169 
1170     /**
1171      * Returns whether default toolkit needs the support of the xembed
1172      * from embedding host(if any).
1173      * @return <code>true</code>, if XEmbed is needed, <code>false</code> otherwise
1174      */
1175     public static boolean needsXEmbed() {
1176         String noxembed = AccessController.
1177             doPrivileged(new GetPropertyAction("sun.awt.noxembed", "false"));
1178         if ("true".equals(noxembed)) {
1179             return false;
1180         }
1181 
1182         Toolkit tk = Toolkit.getDefaultToolkit();


1274      * @return true if the window is modal excluded, false otherwise. If
1275      * the modal exclusion isn't supported by the current Toolkit, false
1276      * is returned
1277      *
1278      * @see sun.awt.SunToolkit#isModalExcludedSupported
1279      * @see sun.awt.SunToolkit#setModalExcluded(java.awt.Window)
1280      *
1281      * @since 1.5
1282      */
1283     public static boolean isModalExcluded(Window window)
1284     {
1285         if (DEFAULT_MODAL_EXCLUSION_TYPE == null) {
1286             DEFAULT_MODAL_EXCLUSION_TYPE = Dialog.ModalExclusionType.APPLICATION_EXCLUDE;
1287         }
1288         return window.getModalExclusionType().compareTo(DEFAULT_MODAL_EXCLUSION_TYPE) >= 0;
1289     }
1290 
1291     /**
1292      * Overridden in XToolkit and WToolkit
1293      */
1294     @Override
1295     public boolean isModalityTypeSupported(Dialog.ModalityType modalityType) {
1296         return (modalityType == Dialog.ModalityType.MODELESS) ||
1297                (modalityType == Dialog.ModalityType.APPLICATION_MODAL);
1298     }
1299 
1300     /**
1301      * Overridden in XToolkit and WToolkit
1302      */
1303     @Override
1304     public boolean isModalExclusionTypeSupported(Dialog.ModalExclusionType exclusionType) {
1305         return (exclusionType == Dialog.ModalExclusionType.NO_EXCLUDE);
1306     }
1307 
1308     ///////////////////////////////////////////////////////////////////////////
1309     //
1310     // The following is used by the Java Plug-in to coordinate dialog modality
1311     // between containing applications (browsers, ActiveX containers etc) and
1312     // the AWT.
1313     //
1314     ///////////////////////////////////////////////////////////////////////////
1315 
1316     private ModalityListenerList modalityListeners = new ModalityListenerList();
1317 
1318     public void addModalityListener(ModalityListener listener) {
1319         modalityListeners.add(listener);
1320     }
1321 
1322     public void removeModalityListener(ModalityListener listener) {
1323         modalityListeners.remove(listener);


1331         notifyModalityChange(ModalityEvent.MODALITY_POPPED, dialog);
1332     }
1333 
1334     final void notifyModalityChange(int id, Dialog source) {
1335         ModalityEvent ev = new ModalityEvent(source, modalityListeners, id);
1336         ev.dispatch();
1337     }
1338 
1339     static class ModalityListenerList implements ModalityListener {
1340 
1341         Vector<ModalityListener> listeners = new Vector<ModalityListener>();
1342 
1343         void add(ModalityListener listener) {
1344             listeners.addElement(listener);
1345         }
1346 
1347         void remove(ModalityListener listener) {
1348             listeners.removeElement(listener);
1349         }
1350 
1351         @Override
1352         public void modalityPushed(ModalityEvent ev) {
1353             Iterator<ModalityListener> it = listeners.iterator();
1354             while (it.hasNext()) {
1355                 it.next().modalityPushed(ev);
1356             }
1357         }
1358 
1359         @Override
1360         public void modalityPopped(ModalityEvent ev) {
1361             Iterator<ModalityListener> it = listeners.iterator();
1362             while (it.hasNext()) {
1363                 it.next().modalityPopped(ev);
1364             }
1365         }
1366     } // end of class ModalityListenerList
1367 
1368     ///////////////////////////////////////////////////////////////////////////
1369     // End Plug-in code
1370     ///////////////////////////////////////////////////////////////////////////
1371 
1372     public static boolean isLightweightOrUnknown(Component comp) {
1373         if (comp.isLightweight()
1374             || !(getDefaultToolkit() instanceof SunToolkit))
1375         {
1376             return true;
1377         }
1378         return !(comp instanceof Button
1379             || comp instanceof Canvas


1539         EventQueue queue = getSystemEventQueueImpl();
1540         return AWTAccessor.getEventQueueAccessor().noEvents(queue);
1541     }
1542 
1543     /**
1544      * Waits for the Java event queue to empty.  Ensures that all
1545      * events are processed (including paint events), and that if
1546      * recursive events were generated, they are also processed.
1547      * Should return <code>true</code> if more processing is
1548      * necessary, <code>false</code> otherwise.
1549      */
1550     @SuppressWarnings("serial")
1551     protected final boolean waitForIdle(final long timeout) {
1552         flushPendingEvents();
1553         boolean queueWasEmpty = isEQEmpty();
1554         queueEmpty = false;
1555         eventDispatched = false;
1556         synchronized(waitLock) {
1557             postEvent(AppContext.getAppContext(),
1558                       new PeerEvent(getSystemEventQueueImpl(), null, PeerEvent.LOW_PRIORITY_EVENT) {
1559                           @Override
1560                           public void dispatch() {
1561                               // Here we block EDT.  It could have some
1562                               // events, it should have dispatched them by
1563                               // now.  So native requests could have been
1564                               // generated.  First, dispatch them.  Then,
1565                               // flush Java events again.
1566                               int iters = 0;
1567                               while (iters < MIN_ITERS) {
1568                                   syncNativeQueue(timeout);
1569                                   iters++;
1570                               }
1571                               while (syncNativeQueue(timeout) && iters < MAX_ITERS) {
1572                                   iters++;
1573                               }
1574                               flushPendingEvents();
1575 
1576                               synchronized(waitLock) {
1577                                   queueEmpty = isEQEmpty();
1578                                   eventDispatched = true;
1579                                   waitLock.notifyAll();