Home | History | Annotate | Download | only in awt
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 
     18 package java.awt;
     19 
     20 import java.awt.event.AWTEventListener;
     21 import java.awt.event.AWTEventListenerProxy;
     22 import java.awt.event.InputEvent;
     23 import java.awt.im.InputMethodHighlight;
     24 import java.awt.image.ColorModel;
     25 import java.awt.image.ImageObserver;
     26 import java.awt.image.ImageProducer;
     27 import java.awt.peer.FontPeer;
     28 import java.beans.PropertyChangeListener;
     29 import java.beans.PropertyChangeSupport;
     30 
     31 import java.lang.reflect.InvocationTargetException;
     32 import java.net.URL;
     33 import java.security.AccessController;
     34 import java.security.PrivilegedAction;
     35 import java.util.Collections;
     36 import java.util.EventListener;
     37 import java.util.HashMap;
     38 import java.util.HashSet;
     39 import java.util.Iterator;
     40 import java.util.Map;
     41 import java.util.MissingResourceException;
     42 import java.util.Properties;
     43 import java.util.ResourceBundle;
     44 
     45 import org.apache.harmony.awt.ChoiceStyle;
     46 import org.apache.harmony.awt.ComponentInternals;
     47 import org.apache.harmony.awt.ContextStorage;
     48 import org.apache.harmony.awt.ReadOnlyIterator;
     49 import org.apache.harmony.awt.internal.nls.Messages;
     50 import org.apache.harmony.awt.wtk.CreationParams;
     51 import org.apache.harmony.awt.wtk.GraphicsFactory;
     52 import org.apache.harmony.awt.wtk.NativeCursor;
     53 
     54 import org.apache.harmony.awt.wtk.NativeEventQueue;
     55 import org.apache.harmony.awt.wtk.NativeEventThread;
     56 import org.apache.harmony.awt.wtk.ShutdownWatchdog;
     57 import org.apache.harmony.awt.wtk.Synchronizer;
     58 import org.apache.harmony.awt.wtk.WTK;
     59 import org.apache.harmony.luni.util.NotImplementedException;
     60 
     61 /**
     62  * The Toolkit class is the representation of the platform-specific Abstract
     63  * Window Toolkit implementation. Toolkit's subclasses are used to bind the
     64  * various components to particular native toolkit implementations.
     65  *
     66  * @since Android 1.0
     67  */
     68 public abstract class Toolkit {
     69 
     70     /**
     71      * The Constant RECOURCE_PATH.
     72      */
     73     private static final String RECOURCE_PATH = "org.apache.harmony.awt.resources.AWTProperties"; //$NON-NLS-1$
     74 
     75     /**
     76      * The Constant properties.
     77      */
     78     private static final ResourceBundle properties = loadResources(RECOURCE_PATH);
     79 
     80     /**
     81      * The dispatcher.
     82      */
     83     Dispatcher dispatcher;
     84 
     85     /**
     86      * The system event queue core.
     87      */
     88     private EventQueueCore systemEventQueueCore;
     89 
     90     /**
     91      * The dispatch thread.
     92      */
     93     EventDispatchThread dispatchThread;
     94 
     95     /**
     96      * The native thread.
     97      */
     98     NativeEventThread nativeThread;
     99 
    100     /**
    101      * The AWT events manager.
    102      */
    103     protected AWTEventsManager awtEventsManager;
    104 
    105     /**
    106      * The Class AWTTreeLock.
    107      */
    108     private class AWTTreeLock {
    109     }
    110 
    111     /**
    112      * The AWT tree lock.
    113      */
    114     final Object awtTreeLock = new AWTTreeLock();
    115 
    116     /**
    117      * The synchronizer.
    118      */
    119     private final Synchronizer synchronizer = ContextStorage.getSynchronizer();
    120 
    121     /**
    122      * The shutdown watchdog.
    123      */
    124     final ShutdownWatchdog shutdownWatchdog = new ShutdownWatchdog();
    125 
    126     /**
    127      * The auto number.
    128      */
    129     final AutoNumber autoNumber = new AutoNumber();
    130 
    131     /**
    132      * The event type lookup.
    133      */
    134     final AWTEvent.EventTypeLookup eventTypeLookup = new AWTEvent.EventTypeLookup();
    135 
    136     /**
    137      * The b dynamic layout set.
    138      */
    139     private boolean bDynamicLayoutSet = true;
    140 
    141     /**
    142      * The set of desktop properties that user set directly.
    143      */
    144     private final HashSet<String> userPropSet = new HashSet<String>();
    145 
    146     /**
    147      * The desktop properties.
    148      */
    149     protected Map<String, Object> desktopProperties;
    150 
    151     /**
    152      * The desktop props support.
    153      */
    154     protected PropertyChangeSupport desktopPropsSupport;
    155 
    156     /**
    157      * For this component the native window is being created It is used in the
    158      * callback-driven window creation (e.g. on Windows in the handler of
    159      * WM_CREATE event) to establish the connection between this component and
    160      * its native window.
    161      */
    162     private Object recentNativeWindowComponent;
    163 
    164     /**
    165      * The wtk.
    166      */
    167     private WTK wtk;
    168 
    169     /**
    170      * The Class ComponentInternalsImpl.
    171      *
    172      * @since Android 1.0
    173      */
    174     protected final class ComponentInternalsImpl extends ComponentInternals {
    175 
    176         /**
    177          * Shutdown.
    178          */
    179         @Override
    180         public void shutdown() {
    181             dispatchThread.shutdown();
    182         }
    183 
    184         /**
    185          * Sets the desktop property to the specified value and fires a property
    186          * change event.
    187          *
    188          * @param name
    189          *            the name of property.
    190          * @param value
    191          *            the new value of property.
    192          */
    193         @Override
    194         public void setDesktopProperty(String name, Object value) {
    195             Toolkit.this.setDesktopProperty(name, value);
    196         }
    197     }
    198 
    199     /**
    200      * A lot of methods must throw HeadlessException if
    201      * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
    202      *
    203      * @throws HeadlessException
    204      *             the headless exception.
    205      */
    206     static void checkHeadless() throws HeadlessException {
    207         if (GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadlessInstance())
    208             throw new HeadlessException();
    209     }
    210 
    211     /**
    212      * Lock AWT.
    213      */
    214     final void lockAWT() {
    215         synchronizer.lock();
    216     }
    217 
    218     /**
    219      * Static lock AWT.
    220      */
    221     static final void staticLockAWT() {
    222         ContextStorage.getSynchronizer().lock();
    223     }
    224 
    225     /**
    226      * Unlock AWT.
    227      */
    228     final void unlockAWT() {
    229         synchronizer.unlock();
    230     }
    231 
    232     /**
    233      * Static unlock AWT.
    234      */
    235     static final void staticUnlockAWT() {
    236         ContextStorage.getSynchronizer().unlock();
    237     }
    238 
    239     /**
    240      * InvokeAndWait under AWT lock. W/o this method system can hang up. Added
    241      * to support modality (Dialog.show() & PopupMenu.show()) from not event
    242      * dispatch thread. Use in other cases is not recommended. Still can be
    243      * called only for whole API methods that cannot be called from other
    244      * classes API methods. Examples: show() for modal dialogs - correct, only
    245      * user can call it, directly or through setVisible(true) setBounds() for
    246      * components - incorrect, setBounds() can be called from layoutContainer()
    247      * for layout managers
    248      *
    249      * @param runnable
    250      *            the runnable.
    251      * @throws InterruptedException
    252      *             the interrupted exception.
    253      * @throws InvocationTargetException
    254      *             the invocation target exception.
    255      */
    256     final void unsafeInvokeAndWait(Runnable runnable) throws InterruptedException,
    257             InvocationTargetException {
    258         synchronizer.storeStateAndFree();
    259         try {
    260             EventQueue.invokeAndWait(runnable);
    261         } finally {
    262             synchronizer.lockAndRestoreState();
    263         }
    264     }
    265 
    266     /**
    267      * Gets the synchronizer.
    268      *
    269      * @return the synchronizer.
    270      */
    271     final Synchronizer getSynchronizer() {
    272         return synchronizer;
    273     }
    274 
    275     /**
    276      * Gets the wTK.
    277      *
    278      * @return the wTK.
    279      */
    280     final WTK getWTK() {
    281         return wtk;
    282     }
    283 
    284     /**
    285      * Gets the property with the specified key and default value. This method
    286      * returns the defValue if the property is not found.
    287      *
    288      * @param propName
    289      *            the name of property.
    290      * @param defVal
    291      *            the default value.
    292      * @return the property value.
    293      */
    294     public static String getProperty(String propName, String defVal) {
    295         if (propName == null) {
    296             // awt.7D=Property name is null
    297             throw new NullPointerException(Messages.getString("awt.7D")); //$NON-NLS-1$
    298         }
    299         staticLockAWT();
    300         try {
    301             String retVal = null;
    302             if (properties != null) {
    303                 try {
    304                     retVal = properties.getString(propName);
    305                 } catch (MissingResourceException e) {
    306                 } catch (ClassCastException e) {
    307                 }
    308             }
    309             return (retVal == null) ? defVal : retVal;
    310         } finally {
    311             staticUnlockAWT();
    312         }
    313     }
    314 
    315     /**
    316      * Gets the default Toolkit.
    317      *
    318      * @return the default Toolkit.
    319      */
    320     public static Toolkit getDefaultToolkit() {
    321         synchronized (ContextStorage.getContextLock()) {
    322             if (ContextStorage.shutdownPending()) {
    323                 return null;
    324             }
    325             Toolkit defToolkit = ContextStorage.getDefaultToolkit();
    326             if (defToolkit != null) {
    327                 return defToolkit;
    328             }
    329             staticLockAWT();
    330             try {
    331                 defToolkit = GraphicsEnvironment.isHeadless() ? new HeadlessToolkit()
    332                         : new ToolkitImpl();
    333                 ContextStorage.setDefaultToolkit(defToolkit);
    334                 return defToolkit;
    335             } finally {
    336                 staticUnlockAWT();
    337             }
    338             // TODO: read system property named awt.toolkit
    339             // and create an instance of the specified class,
    340             // by default use ToolkitImpl
    341         }
    342     }
    343 
    344     /**
    345      * Gets the default Font.
    346      *
    347      * @return the default Font for Toolkit.
    348      */
    349     Font getDefaultFont() {
    350         return wtk.getSystemProperties().getDefaultFont();
    351     }
    352 
    353     /**
    354      * Load resources.
    355      *
    356      * @param path
    357      *            the path.
    358      * @return the resource bundle.
    359      */
    360     private static ResourceBundle loadResources(String path) {
    361         try {
    362             return ResourceBundle.getBundle(path);
    363         } catch (MissingResourceException e) {
    364             return null;
    365         }
    366     }
    367 
    368     /**
    369      * Gets the wTK class name.
    370      *
    371      * @return the wTK class name.
    372      */
    373     private static String getWTKClassName() {
    374         return "com.android.internal.awt.AndroidWTK";
    375     }
    376 
    377     /**
    378      * Gets the component by id.
    379      *
    380      * @param id
    381      *            the id.
    382      * @return the component by id.
    383      */
    384     Component getComponentById(long id) {
    385         if (id == 0) {
    386             return null;
    387         }
    388         return null;
    389     }
    390 
    391     /**
    392      * Gets the GraphicsFactory.
    393      *
    394      * @return the GraphicsFactory object.
    395      */
    396     public GraphicsFactory getGraphicsFactory() {
    397         return wtk.getGraphicsFactory();
    398     }
    399 
    400     /**
    401      * Instantiates a new toolkit.
    402      */
    403     public Toolkit() {
    404         init();
    405     }
    406 
    407     /**
    408      * Initiates AWT.
    409      */
    410     protected void init() {
    411         lockAWT();
    412         try {
    413             ComponentInternals.setComponentInternals(new ComponentInternalsImpl());
    414             new EventQueue(this); // create the system EventQueue
    415             dispatcher = new Dispatcher(this);
    416             final String className = getWTKClassName();
    417             desktopProperties = new HashMap<String, Object>();
    418             desktopPropsSupport = new PropertyChangeSupport(this);
    419             awtEventsManager = new AWTEventsManager();
    420             dispatchThread = new EventDispatchThread(this, dispatcher);
    421             nativeThread = new NativeEventThread();
    422             NativeEventThread.Init init = new NativeEventThread.Init() {
    423                 public WTK init() {
    424                     wtk = createWTK(className);
    425                     wtk.getNativeEventQueue().setShutdownWatchdog(shutdownWatchdog);
    426                     synchronizer.setEnvironment(wtk, dispatchThread);
    427                     ContextStorage.setWTK(wtk);
    428                     return wtk;
    429                 }
    430             };
    431             nativeThread.start(init);
    432             dispatchThread.start();
    433             wtk.getNativeEventQueue().awake();
    434         } finally {
    435             unlockAWT();
    436         }
    437     }
    438 
    439     /**
    440      * Synchronizes this toolkit's graphics.
    441      */
    442     public abstract void sync();
    443 
    444     /**
    445      * Returns the construction status of a specified image that is being
    446      * created.
    447      *
    448      * @param a0
    449      *            the image to be checked.
    450      * @param a1
    451      *            the width of scaled image for which the status is being
    452      *            checked or -1.
    453      * @param a2
    454      *            the height of scaled image for which the status is being
    455      *            checked or -1.
    456      * @param a3
    457      *            the ImageObserver object to be notified while the image is
    458      *            being prepared.
    459      * @return the ImageObserver flags which give the current state of the image
    460      *         data.
    461      */
    462     public abstract int checkImage(Image a0, int a1, int a2, ImageObserver a3);
    463 
    464     /**
    465      * Creates the image with the specified ImageProducer.
    466      *
    467      * @param a0
    468      *            the ImageProducer to be used for image creation.
    469      * @return the image with the specified ImageProducer.
    470      */
    471     public abstract Image createImage(ImageProducer a0);
    472 
    473     /**
    474      * Creates the image from the specified byte array, offset and length. The
    475      * byte array should contain data with image format supported by Toolkit
    476      * such as JPEG, GIF, or PNG.
    477      *
    478      * @param a0
    479      *            the byte array with the image data.
    480      * @param a1
    481      *            the offset of the beginning the image data in the byte array.
    482      * @param a2
    483      *            the length of the image data in the byte array.
    484      * @return the created Image.
    485      */
    486     public abstract Image createImage(byte[] a0, int a1, int a2);
    487 
    488     /**
    489      * Creates the image using image data from the specified URL.
    490      *
    491      * @param a0
    492      *            the URL for extracting image data.
    493      * @return the Image.
    494      */
    495     public abstract Image createImage(URL a0);
    496 
    497     /**
    498      * Creates the image using image data from the specified file.
    499      *
    500      * @param a0
    501      *            the file name which contains image data of supported format.
    502      * @return the Image.
    503      */
    504     public abstract Image createImage(String a0);
    505 
    506     /**
    507      * Gets the color model.
    508      *
    509      * @return the ColorModel of Toolkit's screen.
    510      * @throws HeadlessException
    511      *             if the GraphicsEnvironment.isHeadless() method returns true.
    512      */
    513     public abstract ColorModel getColorModel() throws HeadlessException;
    514 
    515     /**
    516      * Gets the screen device metrics for the specified font.
    517      *
    518      * @param font
    519      *            the Font.
    520      * @return the FontMetrics for the specified Font.
    521      * @deprecated Use getLineMetrics method from Font class.
    522      */
    523 
    524     @Deprecated
    525     public abstract FontMetrics getFontMetrics(Font font);
    526 
    527     /**
    528      * Prepares the specified image for rendering on the screen with the
    529      * specified size.
    530      *
    531      * @param a0
    532      *            the Image to be prepared.
    533      * @param a1
    534      *            the width of the screen representation or -1 for the current
    535      *            screen.
    536      * @param a2
    537      *            the height of the screen representation or -1 for the current
    538      *            screen.
    539      * @param a3
    540      *            the ImageObserver object to be notified as soon as the image
    541      *            is prepared.
    542      * @return true, if image is fully prepared, false otherwise.
    543      */
    544     public abstract boolean prepareImage(Image a0, int a1, int a2, ImageObserver a3);
    545 
    546     /**
    547      * Creates an audio beep.
    548      */
    549     public abstract void beep();
    550 
    551     /**
    552      * Returns the array of font names which are available in this Toolkit.
    553      *
    554      * @return the array of font names which are available in this Toolkit.
    555      * @deprecated use GraphicsEnvironment.getAvailableFontFamilyNames() method.
    556      */
    557     @Deprecated
    558     public abstract String[] getFontList();
    559 
    560     /**
    561      * Gets the the Font implementation using the specified peer interface.
    562      *
    563      * @param a0
    564      *            the Font name to be implemented.
    565      * @param a1
    566      *            the the font style: PLAIN, BOLD, ITALIC.
    567      * @return the FontPeer implementation of the specified Font.
    568      * @deprecated use java.awt.GraphicsEnvironment.getAllFonts method.
    569      */
    570 
    571     @Deprecated
    572     protected abstract FontPeer getFontPeer(String a0, int a1);
    573 
    574     /**
    575      * Gets the image from the specified file which contains image data in a
    576      * supported image format (such as JPEG, GIF, or PNG); this method should
    577      * return the same Image for multiple calls of this method with the same
    578      * image file name.
    579      *
    580      * @param a0
    581      *            the file name which contains image data in a supported image
    582      *            format (such as JPEG, GIF, or PNG).
    583      * @return the Image.
    584      */
    585     public abstract Image getImage(String a0);
    586 
    587     /**
    588      * Gets the image from the specified URL which contains image data in a
    589      * supported image format (such as JPEG, GIF, or PNG); this method should
    590      * return the same Image for multiple calls of this method with the same
    591      * image URL.
    592      *
    593      * @param a0
    594      *            the URL which contains image data in a supported image format
    595      *            (such as JPEG, GIF, or PNG).
    596      * @return the Image.
    597      */
    598     public abstract Image getImage(URL a0);
    599 
    600     /**
    601      * Gets the screen resolution.
    602      *
    603      * @return the screen resolution.
    604      * @throws HeadlessException
    605      *             if the GraphicsEnvironment.isHeadless() method returns true.
    606      */
    607     public abstract int getScreenResolution() throws HeadlessException;
    608 
    609     /**
    610      * Gets the screen size.
    611      *
    612      * @return a Dimension object containing the width and height of the screen.
    613      * @throws HeadlessException
    614      *             if the GraphicsEnvironment.isHeadless() method returns true.
    615      */
    616     public abstract Dimension getScreenSize() throws HeadlessException;
    617 
    618     /**
    619      * Gets the EventQueue instance without checking access.
    620      *
    621      * @return the system EventQueue.
    622      */
    623     protected abstract EventQueue getSystemEventQueueImpl();
    624 
    625     /**
    626      * Returns a map of text attributes for the abstract level description of
    627      * the specified input method highlight, or null if no mapping is found.
    628      *
    629      * @param highlight
    630      *            the InputMethodHighlight.
    631      * @return the Map<java.awt.font. text attribute,?>.
    632      * @throws HeadlessException
    633      *             if the GraphicsEnvironment.isHeadless() method returns true.
    634      */
    635     public abstract Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlight(
    636             InputMethodHighlight highlight) throws HeadlessException;
    637 
    638     /**
    639      * Map input method highlight impl.
    640      *
    641      * @param highlight
    642      *            the highlight.
    643      * @return the map<java.awt.font. text attribute,?>.
    644      * @throws HeadlessException
    645      *             the headless exception.
    646      */
    647     Map<java.awt.font.TextAttribute, ?> mapInputMethodHighlightImpl(InputMethodHighlight highlight)
    648             throws HeadlessException {
    649         HashMap<java.awt.font.TextAttribute, ?> map = new HashMap<java.awt.font.TextAttribute, Object>();
    650         wtk.getSystemProperties().mapInputMethodHighlight(highlight, map);
    651         return Collections.<java.awt.font.TextAttribute, Object> unmodifiableMap(map);
    652     }
    653 
    654     /**
    655      * Adds the specified PropertyChangeListener listener for the specified
    656      * property.
    657      *
    658      * @param propName
    659      *            the property name for which the specified
    660      *            PropertyChangeListener will be added.
    661      * @param l
    662      *            the PropertyChangeListener object.
    663      */
    664     public void addPropertyChangeListener(String propName, PropertyChangeListener l) {
    665         lockAWT();
    666         try {
    667             if (desktopProperties.isEmpty()) {
    668                 initializeDesktopProperties();
    669             }
    670         } finally {
    671             unlockAWT();
    672         }
    673         if (l != null) { // there is no guarantee that null listener will not be
    674             // added
    675             desktopPropsSupport.addPropertyChangeListener(propName, l);
    676         }
    677     }
    678 
    679     /**
    680      * Returns an array of the property change listeners registered with this
    681      * Toolkit.
    682      *
    683      * @return an array of the property change listeners registered with this
    684      *         Toolkit.
    685      */
    686     public PropertyChangeListener[] getPropertyChangeListeners() {
    687         return desktopPropsSupport.getPropertyChangeListeners();
    688     }
    689 
    690     /**
    691      * Returns an array of the property change listeners registered with this
    692      * Toolkit for notification regarding the specified property.
    693      *
    694      * @param propName
    695      *            the property name for which the PropertyChangeListener was
    696      *            registered.
    697      * @return the array of PropertyChangeListeners registered for the specified
    698      *         property name.
    699      */
    700     public PropertyChangeListener[] getPropertyChangeListeners(String propName) {
    701         return desktopPropsSupport.getPropertyChangeListeners(propName);
    702     }
    703 
    704     /**
    705      * Removes the specified property change listener registered for the
    706      * specified property name.
    707      *
    708      * @param propName
    709      *            the property name.
    710      * @param l
    711      *            the PropertyChangeListener registered for the specified
    712      *            property name.
    713      */
    714     public void removePropertyChangeListener(String propName, PropertyChangeListener l) {
    715         desktopPropsSupport.removePropertyChangeListener(propName, l);
    716     }
    717 
    718     /**
    719      * Creates a custom cursor with the specified Image, hot spot, and cursor
    720      * description.
    721      *
    722      * @param img
    723      *            the image of activated cursor.
    724      * @param hotSpot
    725      *            the Point giving the coordinates of the cursor's hot spot.
    726      * @param name
    727      *            the cursor description.
    728      * @return the cursor with the specified Image, hot spot, and cursor
    729      *         description.
    730      * @throws IndexOutOfBoundsException
    731      *             if the hot spot values are outside the bounds of the cursor.
    732      * @throws HeadlessException
    733      *             if isHeadless() method of GraphicsEnvironment class returns
    734      *             true.
    735      */
    736     public Cursor createCustomCursor(Image img, Point hotSpot, String name)
    737             throws IndexOutOfBoundsException, HeadlessException {
    738         lockAWT();
    739         try {
    740             int w = img.getWidth(null), x = hotSpot.x;
    741             int h = img.getHeight(null), y = hotSpot.y;
    742             if (x < 0 || x >= w || y < 0 || y >= h) {
    743                 // awt.7E=invalid hotSpot
    744                 throw new IndexOutOfBoundsException(Messages.getString("awt.7E")); //$NON-NLS-1$
    745             }
    746             return new Cursor(name, img, hotSpot);
    747         } finally {
    748             unlockAWT();
    749         }
    750     }
    751 
    752     /**
    753      * Returns the supported cursor dimension which is closest to the specified
    754      * width and height. If the Toolkit only supports a single cursor size, this
    755      * method should return the supported cursor size. If custom cursor is not
    756      * supported, a dimension of 0, 0 should be returned.
    757      *
    758      * @param prefWidth
    759      *            the preferred cursor width.
    760      * @param prefHeight
    761      *            the preferred cursor height.
    762      * @return the supported cursor dimension which is closest to the specified
    763      *         width and height.
    764      * @throws HeadlessException
    765      *             if GraphicsEnvironment.isHeadless() returns true.
    766      */
    767     public Dimension getBestCursorSize(int prefWidth, int prefHeight) throws HeadlessException {
    768         lockAWT();
    769         try {
    770             return wtk.getCursorFactory().getBestCursorSize(prefWidth, prefHeight);
    771         } finally {
    772             unlockAWT();
    773         }
    774     }
    775 
    776     /**
    777      * Gets the value for the specified desktop property.
    778      *
    779      * @param propName
    780      *            the property name.
    781      * @return the Object that is the property's value.
    782      */
    783     public final Object getDesktopProperty(String propName) {
    784         lockAWT();
    785         try {
    786             if (desktopProperties.isEmpty()) {
    787                 initializeDesktopProperties();
    788             }
    789             if (propName.equals("awt.dynamicLayoutSupported")) { //$NON-NLS-1$
    790                 // dynamicLayoutSupported is special case
    791                 return Boolean.valueOf(isDynamicLayoutActive());
    792             }
    793             Object val = desktopProperties.get(propName);
    794             if (val == null) {
    795                 // try to lazily load prop value
    796                 // just for compatibility, our lazilyLoad is empty
    797                 val = lazilyLoadDesktopProperty(propName);
    798             }
    799             return val;
    800         } finally {
    801             unlockAWT();
    802         }
    803     }
    804 
    805     /**
    806      * Returns the locking key state for the specified key.
    807      *
    808      * @param a0
    809      *            the key code: VK_CAPS_LOCK, VK_NUM_LOCK, VK_SCROLL_LOCK, or
    810      *            VK_KANA_LOCK.
    811      * @return true if the specified key code is in the locked state, false
    812      *         otherwise.
    813      * @throws UnsupportedOperationException
    814      *             if the state of this key can't be retrieved, or if the
    815      *             keyboard doesn't have this key.
    816      * @throws NotImplementedException
    817      *             if this method is not implemented.
    818      */
    819     public boolean getLockingKeyState(int a0) throws UnsupportedOperationException,
    820             org.apache.harmony.luni.util.NotImplementedException {
    821         lockAWT();
    822         try {
    823         } finally {
    824             unlockAWT();
    825         }
    826         if (true) {
    827             throw new RuntimeException("Method is not implemented"); //TODO: implement //$NON-NLS-1$
    828         }
    829         return true;
    830     }
    831 
    832     /**
    833      * Returns the maximum number of colors which the Toolkit supports for
    834      * custom cursor.
    835      *
    836      * @return the maximum cursor colors.
    837      * @throws HeadlessException
    838      *             if the GraphicsEnvironment.isHeadless() method returns true.
    839      */
    840     public int getMaximumCursorColors() throws HeadlessException {
    841         lockAWT();
    842         try {
    843             return wtk.getCursorFactory().getMaximumCursorColors();
    844         } finally {
    845             unlockAWT();
    846         }
    847     }
    848 
    849     /**
    850      * Gets the menu shortcut key mask.
    851      *
    852      * @return the menu shortcut key mask.
    853      * @throws HeadlessException
    854      *             if the GraphicsEnvironment.isHeadless() method returns true.
    855      */
    856     public int getMenuShortcutKeyMask() throws HeadlessException {
    857         lockAWT();
    858         try {
    859             return InputEvent.CTRL_MASK;
    860         } finally {
    861             unlockAWT();
    862         }
    863     }
    864 
    865     /**
    866      * Gets the screen insets.
    867      *
    868      * @param gc
    869      *            the GraphicsConfiguration.
    870      * @return the insets of this toolkit.
    871      * @throws HeadlessException
    872      *             if the GraphicsEnvironment.isHeadless() method returns true.
    873      */
    874     public Insets getScreenInsets(GraphicsConfiguration gc) throws HeadlessException {
    875         if (gc == null) {
    876             throw new NullPointerException();
    877         }
    878         lockAWT();
    879         try {
    880             return new Insets(0, 0, 0, 0); // TODO: get real screen insets
    881         } finally {
    882             unlockAWT();
    883         }
    884     }
    885 
    886     /**
    887      * Gets the system EventQueue instance. If the default implementation of
    888      * checkAwtEventQueueAccess is used, then this results of a call to the
    889      * security manager's checkPermission method with an
    890      * AWTPermission("accessEventQueue") permission.
    891      *
    892      * @return the system EventQueue instance.
    893      */
    894     public final EventQueue getSystemEventQueue() {
    895         SecurityManager sm = System.getSecurityManager();
    896         if (sm != null) {
    897             sm.checkAwtEventQueueAccess();
    898         }
    899         return getSystemEventQueueImpl();
    900     }
    901 
    902     /**
    903      * Gets the system event queue core.
    904      *
    905      * @return the system event queue core.
    906      */
    907     EventQueueCore getSystemEventQueueCore() {
    908         return systemEventQueueCore;
    909     }
    910 
    911     /**
    912      * Sets the system event queue core.
    913      *
    914      * @param core
    915      *            the new system event queue core.
    916      */
    917     void setSystemEventQueueCore(EventQueueCore core) {
    918         systemEventQueueCore = core;
    919     }
    920 
    921     /**
    922      * Initialize the desktop properties.
    923      */
    924     protected void initializeDesktopProperties() {
    925         lockAWT();
    926         try {
    927             wtk.getSystemProperties().init(desktopProperties);
    928         } finally {
    929             unlockAWT();
    930         }
    931     }
    932 
    933     /**
    934      * Checks if dynamic layout of Containers is active or not.
    935      *
    936      * @return true, if is dynamic layout of Containers is active, false
    937      *         otherwise.
    938      * @throws HeadlessException
    939      *             if the GraphicsEnvironment.isHeadless() method returns true.
    940      */
    941     public boolean isDynamicLayoutActive() throws HeadlessException {
    942         lockAWT();
    943         try {
    944             // always return true
    945             return true;
    946         } finally {
    947             unlockAWT();
    948         }
    949     }
    950 
    951     /**
    952      * Returns if the layout of Containers is checked dynamically during
    953      * resizing, or statically after resizing is completed.
    954      *
    955      * @return true, if if the layout of Containers is checked dynamically
    956      *         during resizing; false, if the layout of Containers is checked
    957      *         statically after resizing is completed.
    958      * @throws HeadlessException
    959      *             if the GraphicsEnvironment.isHeadless() method returns true.
    960      */
    961     protected boolean isDynamicLayoutSet() throws HeadlessException {
    962         lockAWT();
    963         try {
    964             return bDynamicLayoutSet;
    965         } finally {
    966             unlockAWT();
    967         }
    968     }
    969 
    970     /**
    971      * Checks if the specified frame state is supported by Toolkit or not.
    972      *
    973      * @param state
    974      *            the frame state.
    975      * @return true, if frame state is supported, false otherwise.
    976      * @throws HeadlessException
    977      *             if the GraphicsEnvironment.isHeadless() method returns true.
    978      */
    979     public boolean isFrameStateSupported(int state) throws HeadlessException {
    980         lockAWT();
    981         try {
    982             return wtk.getWindowFactory().isWindowStateSupported(state);
    983         } finally {
    984             unlockAWT();
    985         }
    986     }
    987 
    988     /**
    989      * Loads the value of the desktop property with the specified property name.
    990      *
    991      * @param propName
    992      *            the property name.
    993      * @return the desktop property values.
    994      */
    995     protected Object lazilyLoadDesktopProperty(String propName) {
    996         return null;
    997     }
    998 
    999     /**
   1000      * Loads the current system color values to the specified array.
   1001      *
   1002      * @param colors
   1003      *            the array where the current system color values are written by
   1004      *            this method.
   1005      * @throws HeadlessException
   1006      *             if the GraphicsEnvironment.isHeadless() method returns true.
   1007      */
   1008     protected void loadSystemColors(int[] colors) throws HeadlessException {
   1009         lockAWT();
   1010         try {
   1011         } finally {
   1012             unlockAWT();
   1013         }
   1014     }
   1015 
   1016     /**
   1017      * Sets the value of the desktop property with the specified name.
   1018      *
   1019      * @param propName
   1020      *            the property's name.
   1021      * @param value
   1022      *            the property's value.
   1023      */
   1024     protected final void setDesktopProperty(String propName, Object value) {
   1025         Object oldVal;
   1026         lockAWT();
   1027         try {
   1028             oldVal = getDesktopProperty(propName);
   1029             userPropSet.add(propName);
   1030             desktopProperties.put(propName, value);
   1031         } finally {
   1032             unlockAWT();
   1033         }
   1034         desktopPropsSupport.firePropertyChange(propName, oldVal, value);
   1035     }
   1036 
   1037     /**
   1038      * Sets the layout state, whether the Container layout is checked
   1039      * dynamically during resizing, or statically after resizing is completed.
   1040      *
   1041      * @param dynamic
   1042      *            the new dynamic layout state - if true the layout of
   1043      *            Containers is checked dynamically during resizing, if false -
   1044      *            statically after resizing is completed.
   1045      * @throws HeadlessException
   1046      *             if the GraphicsEnvironment.isHeadless() method returns true.
   1047      */
   1048     public void setDynamicLayout(boolean dynamic) throws HeadlessException {
   1049         lockAWT();
   1050         try {
   1051             bDynamicLayoutSet = dynamic;
   1052         } finally {
   1053             unlockAWT();
   1054         }
   1055     }
   1056 
   1057     /**
   1058      * Sets the locking key state for the specified key code.
   1059      *
   1060      * @param a0
   1061      *            the key code: VK_CAPS_LOCK, VK_NUM_LOCK, VK_SCROLL_LOCK, or
   1062      *            VK_KANA_LOCK.
   1063      * @param a1
   1064      *            the state - true to set the specified key code to the locked
   1065      *            state, false - to unlock it.
   1066      * @throws UnsupportedOperationException
   1067      *             if the state of this key can't be set, or if the keyboard
   1068      *             doesn't have this key.
   1069      * @throws NotImplementedException
   1070      *             if this method is not implemented.
   1071      */
   1072     public void setLockingKeyState(int a0, boolean a1) throws UnsupportedOperationException,
   1073             org.apache.harmony.luni.util.NotImplementedException {
   1074         lockAWT();
   1075         try {
   1076         } finally {
   1077             unlockAWT();
   1078         }
   1079         if (true) {
   1080             throw new RuntimeException("Method is not implemented"); //TODO: implement //$NON-NLS-1$
   1081         }
   1082         return;
   1083     }
   1084 
   1085     /**
   1086      * On queue empty.
   1087      */
   1088     void onQueueEmpty() {
   1089         throw new RuntimeException("Not implemented!");
   1090     }
   1091 
   1092     /**
   1093      * Creates the wtk.
   1094      *
   1095      * @param clsName
   1096      *            the cls name.
   1097      * @return the wTK.
   1098      */
   1099     private WTK createWTK(String clsName) {
   1100         WTK newWTK = null;
   1101         try {
   1102             newWTK = (WTK)Class.forName(clsName).newInstance();
   1103         } catch (Exception e) {
   1104             throw new RuntimeException(e);
   1105         }
   1106         return newWTK;
   1107     }
   1108 
   1109     /**
   1110      * Connect the component to its native window
   1111      *
   1112      * @param winId
   1113      *            the id of native window just created.
   1114      */
   1115     boolean onWindowCreated(long winId) {
   1116         return false;
   1117     }
   1118 
   1119     /**
   1120      * Gets the native event queue.
   1121      *
   1122      * @return the native event queue.
   1123      */
   1124     NativeEventQueue getNativeEventQueue() {
   1125         return wtk.getNativeEventQueue();
   1126     }
   1127 
   1128     /**
   1129      * Returns a shared instance of implementation of
   1130      * org.apache.harmony.awt.wtk.NativeCursor for current platform for.
   1131      *
   1132      * @param type
   1133      *            the Java Cursor type.
   1134      * @return new instance of implementation of NativeCursor.
   1135      */
   1136     NativeCursor createNativeCursor(int type) {
   1137         return wtk.getCursorFactory().getCursor(type);
   1138     }
   1139 
   1140     /**
   1141      * Returns a shared instance of implementation of
   1142      * org.apache.harmony.awt.wtk.NativeCursor for current platform for custom
   1143      * cursor
   1144      *
   1145      * @param img
   1146      *            the img.
   1147      * @param hotSpot
   1148      *            the hot spot.
   1149      * @param name
   1150      *            the name.
   1151      * @return new instance of implementation of NativeCursor.
   1152      */
   1153     NativeCursor createCustomNativeCursor(Image img, Point hotSpot, String name) {
   1154         return wtk.getCursorFactory().createCustomCursor(img, hotSpot.x, hotSpot.y);
   1155     }
   1156 
   1157     /**
   1158      * Adds an AWTEventListener to the Toolkit to listen for events of types
   1159      * corresponding to bits in the specified event mask. Event masks are
   1160      * defined in AWTEvent class.
   1161      *
   1162      * @param listener
   1163      *            the AWTEventListener.
   1164      * @param eventMask
   1165      *            the bitmask of event types.
   1166      */
   1167     public void addAWTEventListener(AWTEventListener listener, long eventMask) {
   1168         lockAWT();
   1169         try {
   1170             SecurityManager security = System.getSecurityManager();
   1171             if (security != null) {
   1172                 security.checkPermission(awtEventsManager.permission);
   1173             }
   1174             awtEventsManager.addAWTEventListener(listener, eventMask);
   1175         } finally {
   1176             unlockAWT();
   1177         }
   1178     }
   1179 
   1180     /**
   1181      * Removes the specified AWT event listener.
   1182      *
   1183      * @param listener
   1184      *            the AWTEventListener to be removed.
   1185      */
   1186     public void removeAWTEventListener(AWTEventListener listener) {
   1187         lockAWT();
   1188         try {
   1189             SecurityManager security = System.getSecurityManager();
   1190             if (security != null) {
   1191                 security.checkPermission(awtEventsManager.permission);
   1192             }
   1193             awtEventsManager.removeAWTEventListener(listener);
   1194         } finally {
   1195             unlockAWT();
   1196         }
   1197     }
   1198 
   1199     /**
   1200      * Gets the array of all AWT event listeners registered with this Toolkit.
   1201      *
   1202      * @return the array of all AWT event listeners registered with this
   1203      *         Toolkit.
   1204      */
   1205     public AWTEventListener[] getAWTEventListeners() {
   1206         lockAWT();
   1207         try {
   1208             SecurityManager security = System.getSecurityManager();
   1209             if (security != null) {
   1210                 security.checkPermission(awtEventsManager.permission);
   1211             }
   1212             return awtEventsManager.getAWTEventListeners();
   1213         } finally {
   1214             unlockAWT();
   1215         }
   1216     }
   1217 
   1218     /**
   1219      * Returns the array of the AWT event listeners registered with this Toolkit
   1220      * for the event types corresponding to the specified event mask.
   1221      *
   1222      * @param eventMask
   1223      *            the bit mask of event type.
   1224      * @return the array of the AWT event listeners registered in this Toolkit
   1225      *         for the event types corresponding to the specified event mask.
   1226      */
   1227     public AWTEventListener[] getAWTEventListeners(long eventMask) {
   1228         lockAWT();
   1229         try {
   1230             SecurityManager security = System.getSecurityManager();
   1231             if (security != null) {
   1232                 security.checkPermission(awtEventsManager.permission);
   1233             }
   1234             return awtEventsManager.getAWTEventListeners(eventMask);
   1235         } finally {
   1236             unlockAWT();
   1237         }
   1238     }
   1239 
   1240     /**
   1241      * Dispatch AWT event.
   1242      *
   1243      * @param event
   1244      *            the event.
   1245      */
   1246     void dispatchAWTEvent(AWTEvent event) {
   1247         awtEventsManager.dispatchAWTEvent(event);
   1248     }
   1249 
   1250     /**
   1251      * The Class AWTEventsManager.
   1252      */
   1253     final class AWTEventsManager {
   1254 
   1255         /**
   1256          * The permission.
   1257          */
   1258         AWTPermission permission = new AWTPermission("listenToAllAWTEvents"); //$NON-NLS-1$
   1259 
   1260         /**
   1261          * The listeners.
   1262          */
   1263         private final AWTListenerList<AWTEventListenerProxy> listeners = new AWTListenerList<AWTEventListenerProxy>();
   1264 
   1265         /**
   1266          * Adds the AWT event listener.
   1267          *
   1268          * @param listener
   1269          *            the listener.
   1270          * @param eventMask
   1271          *            the event mask.
   1272          */
   1273         void addAWTEventListener(AWTEventListener listener, long eventMask) {
   1274             if (listener != null) {
   1275                 listeners.addUserListener(new AWTEventListenerProxy(eventMask, listener));
   1276             }
   1277         }
   1278 
   1279         /**
   1280          * Removes the AWT event listener.
   1281          *
   1282          * @param listener
   1283          *            the listener.
   1284          */
   1285         void removeAWTEventListener(AWTEventListener listener) {
   1286             if (listener != null) {
   1287                 for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
   1288                     if (listener == proxy.getListener()) {
   1289                         listeners.removeUserListener(proxy);
   1290                         return;
   1291                     }
   1292                 }
   1293             }
   1294         }
   1295 
   1296         /**
   1297          * Gets the AWT event listeners.
   1298          *
   1299          * @return the AWT event listeners.
   1300          */
   1301         AWTEventListener[] getAWTEventListeners() {
   1302             HashSet<EventListener> listenersSet = new HashSet<EventListener>();
   1303             for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
   1304                 listenersSet.add(proxy.getListener());
   1305             }
   1306             return listenersSet.toArray(new AWTEventListener[listenersSet.size()]);
   1307         }
   1308 
   1309         /**
   1310          * Gets the AWT event listeners.
   1311          *
   1312          * @param eventMask
   1313          *            the event mask.
   1314          * @return the AWT event listeners.
   1315          */
   1316         AWTEventListener[] getAWTEventListeners(long eventMask) {
   1317             HashSet<EventListener> listenersSet = new HashSet<EventListener>();
   1318             for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
   1319                 if ((proxy.getEventMask() & eventMask) == eventMask) {
   1320                     listenersSet.add(proxy.getListener());
   1321                 }
   1322             }
   1323             return listenersSet.toArray(new AWTEventListener[listenersSet.size()]);
   1324         }
   1325 
   1326         /**
   1327          * Dispatch AWT event.
   1328          *
   1329          * @param event
   1330          *            the event.
   1331          */
   1332         void dispatchAWTEvent(AWTEvent event) {
   1333             AWTEvent.EventDescriptor descriptor = eventTypeLookup.getEventDescriptor(event);
   1334             if (descriptor == null) {
   1335                 return;
   1336             }
   1337             for (AWTEventListenerProxy proxy : listeners.getUserListeners()) {
   1338                 if ((proxy.getEventMask() & descriptor.eventMask) != 0) {
   1339                     proxy.eventDispatched(event);
   1340                 }
   1341             }
   1342         }
   1343     }
   1344 
   1345     /**
   1346      * The Class AutoNumber.
   1347      */
   1348     static final class AutoNumber {
   1349 
   1350         /**
   1351          * The next component.
   1352          */
   1353         int nextComponent = 0;
   1354 
   1355         /**
   1356          * The next canvas.
   1357          */
   1358         int nextCanvas = 0;
   1359 
   1360         /**
   1361          * The next panel.
   1362          */
   1363         int nextPanel = 0;
   1364 
   1365         /**
   1366          * The next window.
   1367          */
   1368         int nextWindow = 0;
   1369 
   1370         /**
   1371          * The next frame.
   1372          */
   1373         int nextFrame = 0;
   1374 
   1375         /**
   1376          * The next dialog.
   1377          */
   1378         int nextDialog = 0;
   1379 
   1380         /**
   1381          * The next button.
   1382          */
   1383         int nextButton = 0;
   1384 
   1385         /**
   1386          * The next menu component.
   1387          */
   1388         int nextMenuComponent = 0;
   1389 
   1390         /**
   1391          * The next label.
   1392          */
   1393         int nextLabel = 0;
   1394 
   1395         /**
   1396          * The next check box.
   1397          */
   1398         int nextCheckBox = 0;
   1399 
   1400         /**
   1401          * The next scrollbar.
   1402          */
   1403         int nextScrollbar = 0;
   1404 
   1405         /**
   1406          * The next scroll pane.
   1407          */
   1408         int nextScrollPane = 0;
   1409 
   1410         /**
   1411          * The next list.
   1412          */
   1413         int nextList = 0;
   1414 
   1415         /**
   1416          * The next choice.
   1417          */
   1418         int nextChoice = 0;
   1419 
   1420         /**
   1421          * The next file dialog.
   1422          */
   1423         int nextFileDialog = 0;
   1424 
   1425         /**
   1426          * The next text area.
   1427          */
   1428         int nextTextArea = 0;
   1429 
   1430         /**
   1431          * The next text field.
   1432          */
   1433         int nextTextField = 0;
   1434     }
   1435 
   1436     private class Lock {
   1437     }
   1438 
   1439     /**
   1440      * The lock.
   1441      */
   1442     private final Object lock = new Lock();
   1443 
   1444 }
   1445