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 18package java.awt; 19 20import java.awt.event.AWTEventListener; 21import java.awt.event.AWTEventListenerProxy; 22import java.awt.event.InputEvent; 23import java.awt.im.InputMethodHighlight; 24import java.awt.image.ColorModel; 25import java.awt.image.ImageObserver; 26import java.awt.image.ImageProducer; 27import java.awt.peer.FontPeer; 28import java.beans.PropertyChangeListener; 29import java.beans.PropertyChangeSupport; 30 31import java.lang.reflect.InvocationTargetException; 32import java.net.URL; 33import java.security.AccessController; 34import java.security.PrivilegedAction; 35import java.util.Collections; 36import java.util.EventListener; 37import java.util.HashMap; 38import java.util.HashSet; 39import java.util.Iterator; 40import java.util.Map; 41import java.util.MissingResourceException; 42import java.util.Properties; 43import java.util.ResourceBundle; 44 45import org.apache.harmony.awt.ChoiceStyle; 46import org.apache.harmony.awt.ComponentInternals; 47import org.apache.harmony.awt.ContextStorage; 48import org.apache.harmony.awt.ReadOnlyIterator; 49import org.apache.harmony.awt.internal.nls.Messages; 50import org.apache.harmony.awt.wtk.CreationParams; 51import org.apache.harmony.awt.wtk.GraphicsFactory; 52import org.apache.harmony.awt.wtk.NativeCursor; 53 54import org.apache.harmony.awt.wtk.NativeEventQueue; 55import org.apache.harmony.awt.wtk.NativeEventThread; 56import org.apache.harmony.awt.wtk.ShutdownWatchdog; 57import org.apache.harmony.awt.wtk.Synchronizer; 58import org.apache.harmony.awt.wtk.WTK; 59import 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 */ 68public 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