1 /*
   2  * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.awt;
  27 
  28 import java.beans.PropertyChangeEvent;
  29 import java.util.MissingResourceException;
  30 import java.util.Properties;
  31 import java.util.ResourceBundle;
  32 import java.util.StringTokenizer;
  33 import java.awt.event.*;
  34 import java.awt.peer.*;
  35 import java.awt.im.InputMethodHighlight;
  36 import java.awt.image.ImageObserver;
  37 import java.awt.image.ImageProducer;
  38 import java.awt.image.ColorModel;
  39 import java.awt.datatransfer.Clipboard;
  40 import java.awt.dnd.DragSource;
  41 import java.awt.dnd.DragGestureRecognizer;
  42 import java.awt.dnd.DragGestureEvent;
  43 import java.awt.dnd.DragGestureListener;
  44 import java.awt.dnd.InvalidDnDOperationException;
  45 import java.awt.dnd.peer.DragSourceContextPeer;
  46 import java.net.URL;
  47 import java.io.File;
  48 import java.io.FileInputStream;
  49 
  50 import java.util.*;
  51 import sun.util.logging.PlatformLogger;
  52 
  53 import java.beans.PropertyChangeListener;
  54 import java.beans.PropertyChangeSupport;
  55 import sun.awt.AppContext;
  56 
  57 import sun.awt.HeadlessToolkit;
  58 import sun.awt.NullComponentPeer;
  59 import sun.awt.PeerEvent;
  60 import sun.awt.SunToolkit;
  61 import sun.security.util.SecurityConstants;
  62 
  63 import sun.util.CoreResourceBundleControl;
  64 
  65 /**
  66  * This class is the abstract superclass of all actual
  67  * implementations of the Abstract Window Toolkit. Subclasses of
  68  * the <code>Toolkit</code> class are used to bind the various components
  69  * to particular native toolkit implementations.
  70  * <p>
  71  * Many GUI events may be delivered to user
  72  * asynchronously, if the opposite is not specified explicitly.
  73  * As well as
  74  * many GUI operations may be performed asynchronously.
  75  * This fact means that if the state of a component is set, and then
  76  * the state immediately queried, the returned value may not yet
  77  * reflect the requested change.  This behavior includes, but is not
  78  * limited to:
  79  * <ul>
  80  * <li>Scrolling to a specified position.
  81  * <br>For example, calling <code>ScrollPane.setScrollPosition</code>
  82  *     and then <code>getScrollPosition</code> may return an incorrect
  83  *     value if the original request has not yet been processed.
  84  * <p>
  85  * <li>Moving the focus from one component to another.
  86  * <br>For more information, see
  87  * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html#transferTiming">Timing
  88  * Focus Transfers</a>, a section in
  89  * <a href="http://java.sun.com/docs/books/tutorial/uiswing/">The Swing
  90  * Tutorial</a>.
  91  * <p>
  92  * <li>Making a top-level container visible.
  93  * <br>Calling <code>setVisible(true)</code> on a <code>Window</code>,
  94  *     <code>Frame</code> or <code>Dialog</code> may occur
  95  *     asynchronously.
  96  * <p>
  97  * <li>Setting the size or location of a top-level container.
  98  * <br>Calls to <code>setSize</code>, <code>setBounds</code> or
  99  *     <code>setLocation</code> on a <code>Window</code>,
 100  *     <code>Frame</code> or <code>Dialog</code> are forwarded
 101  *     to the underlying window management system and may be
 102  *     ignored or modified.  See {@link java.awt.Window} for
 103  *     more information.
 104  * </ul>
 105  * <p>
 106  * Most applications should not call any of the methods in this
 107  * class directly. The methods defined by <code>Toolkit</code> are
 108  * the "glue" that joins the platform-independent classes in the
 109  * <code>java.awt</code> package with their counterparts in
 110  * <code>java.awt.peer</code>. Some methods defined by
 111  * <code>Toolkit</code> query the native operating system directly.
 112  *
 113  * @author      Sami Shaio
 114  * @author      Arthur van Hoff
 115  * @author      Fred Ecks
 116  * @since       JDK1.0
 117  */
 118 public abstract class Toolkit {
 119 
 120     /**
 121      * Creates this toolkit's implementation of the <code>Desktop</code>
 122      * using the specified peer interface.
 123      * @param     target the desktop to be implemented
 124      * @return    this toolkit's implementation of the <code>Desktop</code>
 125      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 126      * returns true
 127      * @see       java.awt.GraphicsEnvironment#isHeadless
 128      * @see       java.awt.Desktop
 129      * @see       java.awt.peer.DesktopPeer
 130      * @since 1.6
 131      */
 132     protected abstract DesktopPeer createDesktopPeer(Desktop target)
 133       throws HeadlessException;
 134 
 135 
 136     /**
 137      * Creates this toolkit's implementation of <code>Button</code> using
 138      * the specified peer interface.
 139      * @param     target the button to be implemented.
 140      * @return    this toolkit's implementation of <code>Button</code>.
 141      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 142      * returns true
 143      * @see       java.awt.GraphicsEnvironment#isHeadless
 144      * @see       java.awt.Button
 145      * @see       java.awt.peer.ButtonPeer
 146      */
 147     protected abstract ButtonPeer createButton(Button target)
 148         throws HeadlessException;
 149 
 150     /**
 151      * Creates this toolkit's implementation of <code>TextField</code> using
 152      * the specified peer interface.
 153      * @param     target the text field to be implemented.
 154      * @return    this toolkit's implementation of <code>TextField</code>.
 155      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 156      * returns true
 157      * @see       java.awt.GraphicsEnvironment#isHeadless
 158      * @see       java.awt.TextField
 159      * @see       java.awt.peer.TextFieldPeer
 160      */
 161     protected abstract TextFieldPeer createTextField(TextField target)
 162         throws HeadlessException;
 163 
 164     /**
 165      * Creates this toolkit's implementation of <code>Label</code> using
 166      * the specified peer interface.
 167      * @param     target the label to be implemented.
 168      * @return    this toolkit's implementation of <code>Label</code>.
 169      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 170      * returns true
 171      * @see       java.awt.GraphicsEnvironment#isHeadless
 172      * @see       java.awt.Label
 173      * @see       java.awt.peer.LabelPeer
 174      */
 175     protected abstract LabelPeer createLabel(Label target)
 176         throws HeadlessException;
 177 
 178     /**
 179      * Creates this toolkit's implementation of <code>List</code> using
 180      * the specified peer interface.
 181      * @param     target the list to be implemented.
 182      * @return    this toolkit's implementation of <code>List</code>.
 183      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 184      * returns true
 185      * @see       java.awt.GraphicsEnvironment#isHeadless
 186      * @see       java.awt.List
 187      * @see       java.awt.peer.ListPeer
 188      */
 189     protected abstract ListPeer createList(java.awt.List target)
 190         throws HeadlessException;
 191 
 192     /**
 193      * Creates this toolkit's implementation of <code>Checkbox</code> using
 194      * the specified peer interface.
 195      * @param     target the check box to be implemented.
 196      * @return    this toolkit's implementation of <code>Checkbox</code>.
 197      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 198      * returns true
 199      * @see       java.awt.GraphicsEnvironment#isHeadless
 200      * @see       java.awt.Checkbox
 201      * @see       java.awt.peer.CheckboxPeer
 202      */
 203     protected abstract CheckboxPeer createCheckbox(Checkbox target)
 204         throws HeadlessException;
 205 
 206     /**
 207      * Creates this toolkit's implementation of <code>Scrollbar</code> using
 208      * the specified peer interface.
 209      * @param     target the scroll bar to be implemented.
 210      * @return    this toolkit's implementation of <code>Scrollbar</code>.
 211      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 212      * returns true
 213      * @see       java.awt.GraphicsEnvironment#isHeadless
 214      * @see       java.awt.Scrollbar
 215      * @see       java.awt.peer.ScrollbarPeer
 216      */
 217     protected abstract ScrollbarPeer createScrollbar(Scrollbar target)
 218         throws HeadlessException;
 219 
 220     /**
 221      * Creates this toolkit's implementation of <code>ScrollPane</code> using
 222      * the specified peer interface.
 223      * @param     target the scroll pane to be implemented.
 224      * @return    this toolkit's implementation of <code>ScrollPane</code>.
 225      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 226      * returns true
 227      * @see       java.awt.GraphicsEnvironment#isHeadless
 228      * @see       java.awt.ScrollPane
 229      * @see       java.awt.peer.ScrollPanePeer
 230      * @since     JDK1.1
 231      */
 232     protected abstract ScrollPanePeer createScrollPane(ScrollPane target)
 233         throws HeadlessException;
 234 
 235     /**
 236      * Creates this toolkit's implementation of <code>TextArea</code> using
 237      * the specified peer interface.
 238      * @param     target the text area to be implemented.
 239      * @return    this toolkit's implementation of <code>TextArea</code>.
 240      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 241      * returns true
 242      * @see       java.awt.GraphicsEnvironment#isHeadless
 243      * @see       java.awt.TextArea
 244      * @see       java.awt.peer.TextAreaPeer
 245      */
 246     protected abstract TextAreaPeer createTextArea(TextArea target)
 247         throws HeadlessException;
 248 
 249     /**
 250      * Creates this toolkit's implementation of <code>Choice</code> using
 251      * the specified peer interface.
 252      * @param     target the choice to be implemented.
 253      * @return    this toolkit's implementation of <code>Choice</code>.
 254      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 255      * returns true
 256      * @see       java.awt.GraphicsEnvironment#isHeadless
 257      * @see       java.awt.Choice
 258      * @see       java.awt.peer.ChoicePeer
 259      */
 260     protected abstract ChoicePeer createChoice(Choice target)
 261         throws HeadlessException;
 262 
 263     /**
 264      * Creates this toolkit's implementation of <code>Frame</code> using
 265      * the specified peer interface.
 266      * @param     target the frame to be implemented.
 267      * @return    this toolkit's implementation of <code>Frame</code>.
 268      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 269      * returns true
 270      * @see       java.awt.GraphicsEnvironment#isHeadless
 271      * @see       java.awt.Frame
 272      * @see       java.awt.peer.FramePeer
 273      */
 274     protected abstract FramePeer createFrame(Frame target)
 275         throws HeadlessException;
 276 
 277     /**
 278      * Creates this toolkit's implementation of <code>Canvas</code> using
 279      * the specified peer interface.
 280      * @param     target the canvas to be implemented.
 281      * @return    this toolkit's implementation of <code>Canvas</code>.
 282      * @see       java.awt.Canvas
 283      * @see       java.awt.peer.CanvasPeer
 284      */
 285     protected abstract CanvasPeer       createCanvas(Canvas target);
 286 
 287     /**
 288      * Creates this toolkit's implementation of <code>Panel</code> using
 289      * the specified peer interface.
 290      * @param     target the panel to be implemented.
 291      * @return    this toolkit's implementation of <code>Panel</code>.
 292      * @see       java.awt.Panel
 293      * @see       java.awt.peer.PanelPeer
 294      */
 295     protected abstract PanelPeer        createPanel(Panel target);
 296 
 297     /**
 298      * Creates this toolkit's implementation of <code>Window</code> using
 299      * the specified peer interface.
 300      * @param     target the window to be implemented.
 301      * @return    this toolkit's implementation of <code>Window</code>.
 302      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 303      * returns true
 304      * @see       java.awt.GraphicsEnvironment#isHeadless
 305      * @see       java.awt.Window
 306      * @see       java.awt.peer.WindowPeer
 307      */
 308     protected abstract WindowPeer createWindow(Window target)
 309         throws HeadlessException;
 310 
 311     /**
 312      * Creates this toolkit's implementation of <code>Dialog</code> using
 313      * the specified peer interface.
 314      * @param     target the dialog to be implemented.
 315      * @return    this toolkit's implementation of <code>Dialog</code>.
 316      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 317      * returns true
 318      * @see       java.awt.GraphicsEnvironment#isHeadless
 319      * @see       java.awt.Dialog
 320      * @see       java.awt.peer.DialogPeer
 321      */
 322     protected abstract DialogPeer createDialog(Dialog target)
 323         throws HeadlessException;
 324 
 325     /**
 326      * Creates this toolkit's implementation of <code>MenuBar</code> using
 327      * the specified peer interface.
 328      * @param     target the menu bar to be implemented.
 329      * @return    this toolkit's implementation of <code>MenuBar</code>.
 330      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 331      * returns true
 332      * @see       java.awt.GraphicsEnvironment#isHeadless
 333      * @see       java.awt.MenuBar
 334      * @see       java.awt.peer.MenuBarPeer
 335      */
 336     protected abstract MenuBarPeer createMenuBar(MenuBar target)
 337         throws HeadlessException;
 338 
 339     /**
 340      * Creates this toolkit's implementation of <code>Menu</code> using
 341      * the specified peer interface.
 342      * @param     target the menu to be implemented.
 343      * @return    this toolkit's implementation of <code>Menu</code>.
 344      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 345      * returns true
 346      * @see       java.awt.GraphicsEnvironment#isHeadless
 347      * @see       java.awt.Menu
 348      * @see       java.awt.peer.MenuPeer
 349      */
 350     protected abstract MenuPeer createMenu(Menu target)
 351         throws HeadlessException;
 352 
 353     /**
 354      * Creates this toolkit's implementation of <code>PopupMenu</code> using
 355      * the specified peer interface.
 356      * @param     target the popup menu to be implemented.
 357      * @return    this toolkit's implementation of <code>PopupMenu</code>.
 358      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 359      * returns true
 360      * @see       java.awt.GraphicsEnvironment#isHeadless
 361      * @see       java.awt.PopupMenu
 362      * @see       java.awt.peer.PopupMenuPeer
 363      * @since     JDK1.1
 364      */
 365     protected abstract PopupMenuPeer createPopupMenu(PopupMenu target)
 366         throws HeadlessException;
 367 
 368     /**
 369      * Creates this toolkit's implementation of <code>MenuItem</code> using
 370      * the specified peer interface.
 371      * @param     target the menu item to be implemented.
 372      * @return    this toolkit's implementation of <code>MenuItem</code>.
 373      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 374      * returns true
 375      * @see       java.awt.GraphicsEnvironment#isHeadless
 376      * @see       java.awt.MenuItem
 377      * @see       java.awt.peer.MenuItemPeer
 378      */
 379     protected abstract MenuItemPeer createMenuItem(MenuItem target)
 380         throws HeadlessException;
 381 
 382     /**
 383      * Creates this toolkit's implementation of <code>FileDialog</code> using
 384      * the specified peer interface.
 385      * @param     target the file dialog to be implemented.
 386      * @return    this toolkit's implementation of <code>FileDialog</code>.
 387      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 388      * returns true
 389      * @see       java.awt.GraphicsEnvironment#isHeadless
 390      * @see       java.awt.FileDialog
 391      * @see       java.awt.peer.FileDialogPeer
 392      */
 393     protected abstract FileDialogPeer createFileDialog(FileDialog target)
 394         throws HeadlessException;
 395 
 396     /**
 397      * Creates this toolkit's implementation of <code>CheckboxMenuItem</code> using
 398      * the specified peer interface.
 399      * @param     target the checkbox menu item to be implemented.
 400      * @return    this toolkit's implementation of <code>CheckboxMenuItem</code>.
 401      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 402      * returns true
 403      * @see       java.awt.GraphicsEnvironment#isHeadless
 404      * @see       java.awt.CheckboxMenuItem
 405      * @see       java.awt.peer.CheckboxMenuItemPeer
 406      */
 407     protected abstract CheckboxMenuItemPeer createCheckboxMenuItem(
 408         CheckboxMenuItem target) throws HeadlessException;
 409 
 410     /**
 411      * Obtains this toolkit's implementation of helper class for
 412      * <code>MouseInfo</code> operations.
 413      * @return    this toolkit's implementation of  helper for <code>MouseInfo</code>
 414      * @throws    UnsupportedOperationException if this operation is not implemented
 415      * @see       java.awt.peer.MouseInfoPeer
 416      * @see       java.awt.MouseInfo
 417      * @since 1.5
 418      */
 419     protected MouseInfoPeer getMouseInfoPeer() {
 420         throw new UnsupportedOperationException("Not implemented");
 421     }
 422 
 423     private static LightweightPeer lightweightMarker;
 424 
 425     /**
 426      * Creates a peer for a component or container.  This peer is windowless
 427      * and allows the Component and Container classes to be extended directly
 428      * to create windowless components that are defined entirely in java.
 429      *
 430      * @param target The Component to be created.
 431      */
 432     protected LightweightPeer createComponent(Component target) {
 433         if (lightweightMarker == null) {
 434             lightweightMarker = new NullComponentPeer();
 435         }
 436         return lightweightMarker;
 437     }
 438 
 439     /**
 440      * Creates this toolkit's implementation of <code>Font</code> using
 441      * the specified peer interface.
 442      * @param     name the font to be implemented
 443      * @param     style the style of the font, such as <code>PLAIN</code>,
 444      *            <code>BOLD</code>, <code>ITALIC</code>, or a combination
 445      * @return    this toolkit's implementation of <code>Font</code>
 446      * @see       java.awt.Font
 447      * @see       java.awt.peer.FontPeer
 448      * @see       java.awt.GraphicsEnvironment#getAllFonts
 449      * @deprecated  see java.awt.GraphicsEnvironment#getAllFonts
 450      */
 451     @Deprecated
 452     protected abstract FontPeer getFontPeer(String name, int style);
 453 
 454     // The following method is called by the private method
 455     // <code>updateSystemColors</code> in <code>SystemColor</code>.
 456 
 457     /**
 458      * Fills in the integer array that is supplied as an argument
 459      * with the current system color values.
 460      *
 461      * @param     systemColors an integer array.
 462      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 463      * returns true
 464      * @see       java.awt.GraphicsEnvironment#isHeadless
 465      * @since     JDK1.1
 466      */
 467     protected void loadSystemColors(int[] systemColors)
 468         throws HeadlessException {
 469         GraphicsEnvironment.checkHeadless();
 470     }
 471 
 472 /**
 473      * Controls whether the layout of Containers is validated dynamically
 474      * during resizing, or statically, after resizing is complete.
 475      * Use {@code isDynamicLayoutActive()} to detect if this feature enabled
 476      * in this program and is supported by this operating system
 477      * and/or window manager.
 478      * Note that this feature is supported not on all platforms, and
 479      * conversely, that this feature cannot be turned off on some platforms.
 480      * On these platforms where dynamic layout during resizing is not supported
 481      * (or is always supported), setting this property has no effect.
 482      * Note that this feature can be set or unset as a property of the
 483      * operating system or window manager on some platforms.  On such
 484      * platforms, the dynamic resize property must be set at the operating
 485      * system or window manager level before this method can take effect.
 486      * This method does not change support or settings of the underlying
 487      * operating system or
 488      * window manager.  The OS/WM support can be
 489      * queried using getDesktopProperty("awt.dynamicLayoutSupported") method.
 490      *
 491      * @param     dynamic  If true, Containers should re-layout their
 492      *            components as the Container is being resized.  If false,
 493      *            the layout will be validated after resizing is completed.
 494      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 495      *            returns true
 496      * @see       #isDynamicLayoutSet()
 497      * @see       #isDynamicLayoutActive()
 498      * @see       #getDesktopProperty(String propertyName)
 499      * @see       java.awt.GraphicsEnvironment#isHeadless
 500      * @since     1.4
 501      */
 502     public void setDynamicLayout(boolean dynamic)
 503         throws HeadlessException {
 504         GraphicsEnvironment.checkHeadless();
 505     }
 506 
 507     /**
 508      * Returns whether the layout of Containers is validated dynamically
 509      * during resizing, or statically, after resizing is complete.
 510      * Note: this method returns the value that was set programmatically;
 511      * it does not reflect support at the level of the operating system
 512      * or window manager for dynamic layout on resizing, or the current
 513      * operating system or window manager settings.  The OS/WM support can
 514      * be queried using getDesktopProperty("awt.dynamicLayoutSupported").
 515      *
 516      * @return    true if validation of Containers is done dynamically,
 517      *            false if validation is done after resizing is finished.
 518      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 519      *            returns true
 520      * @see       #setDynamicLayout(boolean dynamic)
 521      * @see       #isDynamicLayoutActive()
 522      * @see       #getDesktopProperty(String propertyName)
 523      * @see       java.awt.GraphicsEnvironment#isHeadless
 524      * @since     1.4
 525      */
 526     protected boolean isDynamicLayoutSet()
 527         throws HeadlessException {
 528         GraphicsEnvironment.checkHeadless();
 529 
 530         if (this != Toolkit.getDefaultToolkit()) {
 531             return Toolkit.getDefaultToolkit().isDynamicLayoutSet();
 532         } else {
 533             return false;
 534         }
 535     }
 536 
 537     /**
 538      * Returns whether dynamic layout of Containers on resize is
 539      * currently active (both set in program
 540      *( {@code isDynamicLayoutSet()} )
 541      *, and supported
 542      * by the underlying operating system and/or window manager).
 543      * If dynamic layout is currently inactive then Containers
 544      * re-layout their components when resizing is completed. As a result
 545      * the {@code Component.validate()} method will be invoked only
 546      * once per resize.
 547      * If dynamic layout is currently active then Containers
 548      * re-layout their components on every native resize event and
 549      * the {@code validate()} method will be invoked each time.
 550      * The OS/WM support can be queried using
 551      * the getDesktopProperty("awt.dynamicLayoutSupported") method.
 552      *
 553      * @return    true if dynamic layout of Containers on resize is
 554      *            currently active, false otherwise.
 555      * @exception HeadlessException if the GraphicsEnvironment.isHeadless()
 556      *            method returns true
 557      * @see       #setDynamicLayout(boolean dynamic)
 558      * @see       #isDynamicLayoutSet()
 559      * @see       #getDesktopProperty(String propertyName)
 560      * @see       java.awt.GraphicsEnvironment#isHeadless
 561      * @since     1.4
 562      */
 563     public boolean isDynamicLayoutActive()
 564         throws HeadlessException {
 565         GraphicsEnvironment.checkHeadless();
 566 
 567         if (this != Toolkit.getDefaultToolkit()) {
 568             return Toolkit.getDefaultToolkit().isDynamicLayoutActive();
 569         } else {
 570             return false;
 571         }
 572     }
 573 
 574     /**
 575      * Gets the size of the screen.  On systems with multiple displays, the
 576      * primary display is used.  Multi-screen aware display dimensions are
 577      * available from <code>GraphicsConfiguration</code> and
 578      * <code>GraphicsDevice</code>.
 579      * @return    the size of this toolkit's screen, in pixels.
 580      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 581      * returns true
 582      * @see       java.awt.GraphicsConfiguration#getBounds
 583      * @see       java.awt.GraphicsDevice#getDisplayMode
 584      * @see       java.awt.GraphicsEnvironment#isHeadless
 585      */
 586     public abstract Dimension getScreenSize()
 587         throws HeadlessException;
 588 
 589     /**
 590      * Returns the screen resolution in dots-per-inch.
 591      * @return    this toolkit's screen resolution, in dots-per-inch.
 592      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 593      * returns true
 594      * @see       java.awt.GraphicsEnvironment#isHeadless
 595      */
 596     public abstract int getScreenResolution()
 597         throws HeadlessException;
 598 
 599     /**
 600      * Gets the insets of the screen.
 601      * @param     gc a <code>GraphicsConfiguration</code>
 602      * @return    the insets of this toolkit's screen, in pixels.
 603      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 604      * returns true
 605      * @see       java.awt.GraphicsEnvironment#isHeadless
 606      * @since     1.4
 607      */
 608     public Insets getScreenInsets(GraphicsConfiguration gc)
 609         throws HeadlessException {
 610         GraphicsEnvironment.checkHeadless();
 611         if (this != Toolkit.getDefaultToolkit()) {
 612             return Toolkit.getDefaultToolkit().getScreenInsets(gc);
 613         } else {
 614             return new Insets(0, 0, 0, 0);
 615         }
 616     }
 617 
 618     /**
 619      * Determines the color model of this toolkit's screen.
 620      * <p>
 621      * <code>ColorModel</code> is an abstract class that
 622      * encapsulates the ability to translate between the
 623      * pixel values of an image and its red, green, blue,
 624      * and alpha components.
 625      * <p>
 626      * This toolkit method is called by the
 627      * <code>getColorModel</code> method
 628      * of the <code>Component</code> class.
 629      * @return    the color model of this toolkit's screen.
 630      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
 631      * returns true
 632      * @see       java.awt.GraphicsEnvironment#isHeadless
 633      * @see       java.awt.image.ColorModel
 634      * @see       java.awt.Component#getColorModel
 635      */
 636     public abstract ColorModel getColorModel()
 637         throws HeadlessException;
 638 
 639     /**
 640      * Returns the names of the available fonts in this toolkit.<p>
 641      * For 1.1, the following font names are deprecated (the replacement
 642      * name follows):
 643      * <ul>
 644      * <li>TimesRoman (use Serif)
 645      * <li>Helvetica (use SansSerif)
 646      * <li>Courier (use Monospaced)
 647      * </ul><p>
 648      * The ZapfDingbats fontname is also deprecated in 1.1 but the characters
 649      * are defined in Unicode starting at 0x2700, and as of 1.1 Java supports
 650      * those characters.
 651      * @return    the names of the available fonts in this toolkit.
 652      * @deprecated see {@link java.awt.GraphicsEnvironment#getAvailableFontFamilyNames()}
 653      * @see java.awt.GraphicsEnvironment#getAvailableFontFamilyNames()
 654      */
 655     @Deprecated
 656     public abstract String[] getFontList();
 657 
 658     /**
 659      * Gets the screen device metrics for rendering of the font.
 660      * @param     font   a font
 661      * @return    the screen metrics of the specified font in this toolkit
 662      * @deprecated  As of JDK version 1.2, replaced by the <code>Font</code>
 663      *          method <code>getLineMetrics</code>.
 664      * @see java.awt.font.LineMetrics
 665      * @see java.awt.Font#getLineMetrics
 666      * @see java.awt.GraphicsEnvironment#getScreenDevices
 667      */
 668     @Deprecated
 669     public abstract FontMetrics getFontMetrics(Font font);
 670 
 671     /**
 672      * Synchronizes this toolkit's graphics state. Some window systems
 673      * may do buffering of graphics events.
 674      * <p>
 675      * This method ensures that the display is up-to-date. It is useful
 676      * for animation.
 677      */
 678     public abstract void sync();
 679 
 680     /**
 681      * The default toolkit.
 682      */
 683     private static Toolkit toolkit;
 684 
 685     /**
 686      * Used internally by the assistive technologies functions; set at
 687      * init time and used at load time
 688      */
 689     private static String atNames;
 690 
 691     /**
 692      * Initializes properties related to assistive technologies.
 693      * These properties are used both in the loadAssistiveProperties()
 694      * function below, as well as other classes in the jdk that depend
 695      * on the properties (such as the use of the screen_magnifier_present
 696      * property in Java2D hardware acceleration initialization).  The
 697      * initialization of the properties must be done before the platform-
 698      * specific Toolkit class is instantiated so that all necessary
 699      * properties are set up properly before any classes dependent upon them
 700      * are initialized.
 701      */
 702     private static void initAssistiveTechnologies() {
 703 
 704         // Get accessibility properties
 705         final String sep = File.separator;
 706         final Properties properties = new Properties();
 707 
 708 
 709         atNames = java.security.AccessController.doPrivileged(
 710             new java.security.PrivilegedAction<String>() {
 711             public String run() {
 712 
 713                 // Try loading the per-user accessibility properties file.
 714                 try {
 715                     File propsFile = new File(
 716                       System.getProperty("user.home") +
 717                       sep + ".accessibility.properties");
 718                     FileInputStream in =
 719                         new FileInputStream(propsFile);
 720 
 721                     // Inputstream has been buffered in Properties class
 722                     properties.load(in);
 723                     in.close();
 724                 } catch (Exception e) {
 725                     // Per-user accessibility properties file does not exist
 726                 }
 727 
 728                 // Try loading the system-wide accessibility properties
 729                 // file only if a per-user accessibility properties
 730                 // file does not exist or is empty.
 731                 if (properties.size() == 0) {
 732                     try {
 733                         File propsFile = new File(
 734                             System.getProperty("java.home") + sep + "lib" +
 735                             sep + "accessibility.properties");
 736                         FileInputStream in =
 737                             new FileInputStream(propsFile);
 738 
 739                         // Inputstream has been buffered in Properties class
 740                         properties.load(in);
 741                         in.close();
 742                     } catch (Exception e) {
 743                         // System-wide accessibility properties file does
 744                         // not exist;
 745                     }
 746                 }
 747 
 748                 // Get whether a screen magnifier is present.  First check
 749                 // the system property and then check the properties file.
 750                 String magPresent = System.getProperty("javax.accessibility.screen_magnifier_present");
 751                 if (magPresent == null) {
 752                     magPresent = properties.getProperty("screen_magnifier_present", null);
 753                     if (magPresent != null) {
 754                         System.setProperty("javax.accessibility.screen_magnifier_present", magPresent);
 755                     }
 756                 }
 757 
 758                 // Get the names of any assistive technolgies to load.  First
 759                 // check the system property and then check the properties
 760                 // file.
 761                 String classNames = System.getProperty("javax.accessibility.assistive_technologies");
 762                 if (classNames == null) {
 763                     classNames = properties.getProperty("assistive_technologies", null);
 764                     if (classNames != null) {
 765                         System.setProperty("javax.accessibility.assistive_technologies", classNames);
 766                     }
 767                 }
 768                 return classNames;
 769             }
 770         });
 771     }
 772 
 773     /**
 774      * Loads additional classes into the VM, using the property
 775      * 'assistive_technologies' specified in the Sun reference
 776      * implementation by a line in the 'accessibility.properties'
 777      * file.  The form is "assistive_technologies=..." where
 778      * the "..." is a comma-separated list of assistive technology
 779      * classes to load.  Each class is loaded in the order given
 780      * and a single instance of each is created using
 781      * Class.forName(class).newInstance().  All errors are handled
 782      * via an AWTError exception.
 783      *
 784      * <p>The assumption is made that assistive technology classes are supplied
 785      * as part of INSTALLED (as opposed to: BUNDLED) extensions or specified
 786      * on the class path
 787      * (and therefore can be loaded using the class loader returned by
 788      * a call to <code>ClassLoader.getSystemClassLoader</code>, whose
 789      * delegation parent is the extension class loader for installed
 790      * extensions).
 791      */
 792     private static void loadAssistiveTechnologies() {
 793         // Load any assistive technologies
 794         if (atNames != null) {
 795             ClassLoader cl = ClassLoader.getSystemClassLoader();
 796             StringTokenizer parser = new StringTokenizer(atNames," ,");
 797             String atName;
 798             while (parser.hasMoreTokens()) {
 799                 atName = parser.nextToken();
 800                 try {
 801                     Class<?> clazz;
 802                     if (cl != null) {
 803                         clazz = cl.loadClass(atName);
 804                     } else {
 805                         clazz = Class.forName(atName);
 806                     }
 807                     clazz.newInstance();
 808                 } catch (ClassNotFoundException e) {
 809                     throw new AWTError("Assistive Technology not found: "
 810                             + atName);
 811                 } catch (InstantiationException e) {
 812                     throw new AWTError("Could not instantiate Assistive"
 813                             + " Technology: " + atName);
 814                 } catch (IllegalAccessException e) {
 815                     throw new AWTError("Could not access Assistive"
 816                             + " Technology: " + atName);
 817                 } catch (Exception e) {
 818                     throw new AWTError("Error trying to install Assistive"
 819                             + " Technology: " + atName + " " + e);
 820                 }
 821             }
 822         }
 823     }
 824 
 825     /**
 826      * Gets the default toolkit.
 827      * <p>
 828      * If a system property named <code>"java.awt.headless"</code> is set
 829      * to <code>true</code> then the headless implementation
 830      * of <code>Toolkit</code> is used.
 831      * <p>
 832      * If there is no <code>"java.awt.headless"</code> or it is set to
 833      * <code>false</code> and there is a system property named
 834      * <code>"awt.toolkit"</code>,
 835      * that property is treated as the name of a class that is a subclass
 836      * of <code>Toolkit</code>;
 837      * otherwise the default platform-specific implementation of
 838      * <code>Toolkit</code> is used.
 839      * <p>
 840      * Also loads additional classes into the VM, using the property
 841      * 'assistive_technologies' specified in the Sun reference
 842      * implementation by a line in the 'accessibility.properties'
 843      * file.  The form is "assistive_technologies=..." where
 844      * the "..." is a comma-separated list of assistive technology
 845      * classes to load.  Each class is loaded in the order given
 846      * and a single instance of each is created using
 847      * Class.forName(class).newInstance().  This is done just after
 848      * the AWT toolkit is created.  All errors are handled via an
 849      * AWTError exception.
 850      * @return    the default toolkit.
 851      * @exception  AWTError  if a toolkit could not be found, or
 852      *                 if one could not be accessed or instantiated.
 853      */
 854     public static synchronized Toolkit getDefaultToolkit() {
 855         if (toolkit == null) {
 856             try {
 857                 // We disable the JIT during toolkit initialization.  This
 858                 // tends to touch lots of classes that aren't needed again
 859                 // later and therefore JITing is counter-productiive.
 860                 java.lang.Compiler.disable();
 861 
 862                 java.security.AccessController.doPrivileged(
 863                         new java.security.PrivilegedAction<Void>() {
 864                     public Void run() {
 865                         String nm = null;
 866                         Class<?> cls = null;
 867                         try {
 868                             nm = System.getProperty("awt.toolkit");
 869                             try {
 870                                 cls = Class.forName(nm);
 871                             } catch (ClassNotFoundException e) {
 872                                 ClassLoader cl = ClassLoader.getSystemClassLoader();
 873                                 if (cl != null) {
 874                                     try {
 875                                         cls = cl.loadClass(nm);
 876                                     } catch (ClassNotFoundException ee) {
 877                                         throw new AWTError("Toolkit not found: " + nm);
 878                                     }
 879                                 }
 880                             }
 881                             if (cls != null) {
 882                                 toolkit = (Toolkit)cls.newInstance();
 883                                 if (GraphicsEnvironment.isHeadless()) {
 884                                     toolkit = new HeadlessToolkit(toolkit);
 885                                 }
 886                             }
 887                         } catch (InstantiationException e) {
 888                             throw new AWTError("Could not instantiate Toolkit: " + nm);
 889                         } catch (IllegalAccessException e) {
 890                             throw new AWTError("Could not access Toolkit: " + nm);
 891                         }
 892                         return null;
 893                     }
 894                 });
 895                 loadAssistiveTechnologies();
 896             } finally {
 897                 // Make sure to always re-enable the JIT.
 898                 java.lang.Compiler.enable();
 899             }
 900         }
 901         return toolkit;
 902     }
 903 
 904     /**
 905      * Returns an image which gets pixel data from the specified file,
 906      * whose format can be either GIF, JPEG or PNG.
 907      * The underlying toolkit attempts to resolve multiple requests
 908      * with the same filename to the same returned Image.
 909      * <p>
 910      * Since the mechanism required to facilitate this sharing of
 911      * <code>Image</code> objects may continue to hold onto images
 912      * that are no longer in use for an indefinite period of time,
 913      * developers are encouraged to implement their own caching of
 914      * images by using the {@link #createImage(java.lang.String) createImage}
 915      * variant wherever available.
 916      * If the image data contained in the specified file changes,
 917      * the <code>Image</code> object returned from this method may
 918      * still contain stale information which was loaded from the
 919      * file after a prior call.
 920      * Previously loaded image data can be manually discarded by
 921      * calling the {@link Image#flush flush} method on the
 922      * returned <code>Image</code>.
 923      * <p>
 924      * This method first checks if there is a security manager installed.
 925      * If so, the method calls the security manager's
 926      * <code>checkRead</code> method with the file specified to ensure
 927      * that the access to the image is allowed.
 928      * @param     filename   the name of a file containing pixel data
 929      *                         in a recognized file format.
 930      * @return    an image which gets its pixel data from
 931      *                         the specified file.
 932      * @throws SecurityException  if a security manager exists and its
 933      *                            checkRead method doesn't allow the operation.
 934      * @see #createImage(java.lang.String)
 935      */
 936     public abstract Image getImage(String filename);
 937 
 938     /**
 939      * Returns an image which gets pixel data from the specified URL.
 940      * The pixel data referenced by the specified URL must be in one
 941      * of the following formats: GIF, JPEG or PNG.
 942      * The underlying toolkit attempts to resolve multiple requests
 943      * with the same URL to the same returned Image.
 944      * <p>
 945      * Since the mechanism required to facilitate this sharing of
 946      * <code>Image</code> objects may continue to hold onto images
 947      * that are no longer in use for an indefinite period of time,
 948      * developers are encouraged to implement their own caching of
 949      * images by using the {@link #createImage(java.net.URL) createImage}
 950      * variant wherever available.
 951      * If the image data stored at the specified URL changes,
 952      * the <code>Image</code> object returned from this method may
 953      * still contain stale information which was fetched from the
 954      * URL after a prior call.
 955      * Previously loaded image data can be manually discarded by
 956      * calling the {@link Image#flush flush} method on the
 957      * returned <code>Image</code>.
 958      * <p>
 959      * This method first checks if there is a security manager installed.
 960      * If so, the method calls the security manager's
 961      * <code>checkPermission</code> method with the
 962      * url.openConnection().getPermission() permission to ensure
 963      * that the access to the image is allowed. For compatibility
 964      * with pre-1.2 security managers, if the access is denied with
 965      * <code>FilePermission</code> or <code>SocketPermission</code>,
 966      * the method throws the <code>SecurityException</code>
 967      * if the corresponding 1.1-style SecurityManager.checkXXX method
 968      * also denies permission.
 969      * @param     url   the URL to use in fetching the pixel data.
 970      * @return    an image which gets its pixel data from
 971      *                         the specified URL.
 972      * @throws SecurityException  if a security manager exists and its
 973      *                            checkPermission method doesn't allow
 974      *                            the operation.
 975      * @see #createImage(java.net.URL)
 976      */
 977     public abstract Image getImage(URL url);
 978 
 979     /**
 980      * Returns an image which gets pixel data from the specified file.
 981      * The returned Image is a new object which will not be shared
 982      * with any other caller of this method or its getImage variant.
 983      * <p>
 984      * This method first checks if there is a security manager installed.
 985      * If so, the method calls the security manager's
 986      * <code>checkRead</code> method with the specified file to ensure
 987      * that the image creation is allowed.
 988      * @param     filename   the name of a file containing pixel data
 989      *                         in a recognized file format.
 990      * @return    an image which gets its pixel data from
 991      *                         the specified file.
 992      * @throws SecurityException  if a security manager exists and its
 993      *                            checkRead method doesn't allow the operation.
 994      * @see #getImage(java.lang.String)
 995      */
 996     public abstract Image createImage(String filename);
 997 
 998     /**
 999      * Returns an image which gets pixel data from the specified URL.
1000      * The returned Image is a new object which will not be shared
1001      * with any other caller of this method or its getImage variant.
1002      * <p>
1003      * This method first checks if there is a security manager installed.
1004      * If so, the method calls the security manager's
1005      * <code>checkPermission</code> method with the
1006      * url.openConnection().getPermission() permission to ensure
1007      * that the image creation is allowed. For compatibility
1008      * with pre-1.2 security managers, if the access is denied with
1009      * <code>FilePermission</code> or <code>SocketPermission</code>,
1010      * the method throws <code>SecurityException</code>
1011      * if the corresponding 1.1-style SecurityManager.checkXXX method
1012      * also denies permission.
1013      * @param     url   the URL to use in fetching the pixel data.
1014      * @return    an image which gets its pixel data from
1015      *                         the specified URL.
1016      * @throws SecurityException  if a security manager exists and its
1017      *                            checkPermission method doesn't allow
1018      *                            the operation.
1019      * @see #getImage(java.net.URL)
1020      */
1021     public abstract Image createImage(URL url);
1022 
1023     /**
1024      * Prepares an image for rendering.
1025      * <p>
1026      * If the values of the width and height arguments are both
1027      * <code>-1</code>, this method prepares the image for rendering
1028      * on the default screen; otherwise, this method prepares an image
1029      * for rendering on the default screen at the specified width and height.
1030      * <p>
1031      * The image data is downloaded asynchronously in another thread,
1032      * and an appropriately scaled screen representation of the image is
1033      * generated.
1034      * <p>
1035      * This method is called by components <code>prepareImage</code>
1036      * methods.
1037      * <p>
1038      * Information on the flags returned by this method can be found
1039      * with the definition of the <code>ImageObserver</code> interface.
1040 
1041      * @param     image      the image for which to prepare a
1042      *                           screen representation.
1043      * @param     width      the width of the desired screen
1044      *                           representation, or <code>-1</code>.
1045      * @param     height     the height of the desired screen
1046      *                           representation, or <code>-1</code>.
1047      * @param     observer   the <code>ImageObserver</code>
1048      *                           object to be notified as the
1049      *                           image is being prepared.
1050      * @return    <code>true</code> if the image has already been
1051      *                 fully prepared; <code>false</code> otherwise.
1052      * @see       java.awt.Component#prepareImage(java.awt.Image,
1053      *                 java.awt.image.ImageObserver)
1054      * @see       java.awt.Component#prepareImage(java.awt.Image,
1055      *                 int, int, java.awt.image.ImageObserver)
1056      * @see       java.awt.image.ImageObserver
1057      */
1058     public abstract boolean prepareImage(Image image, int width, int height,
1059                                          ImageObserver observer);
1060 
1061     /**
1062      * Indicates the construction status of a specified image that is
1063      * being prepared for display.
1064      * <p>
1065      * If the values of the width and height arguments are both
1066      * <code>-1</code>, this method returns the construction status of
1067      * a screen representation of the specified image in this toolkit.
1068      * Otherwise, this method returns the construction status of a
1069      * scaled representation of the image at the specified width
1070      * and height.
1071      * <p>
1072      * This method does not cause the image to begin loading.
1073      * An application must call <code>prepareImage</code> to force
1074      * the loading of an image.
1075      * <p>
1076      * This method is called by the component's <code>checkImage</code>
1077      * methods.
1078      * <p>
1079      * Information on the flags returned by this method can be found
1080      * with the definition of the <code>ImageObserver</code> interface.
1081      * @param     image   the image whose status is being checked.
1082      * @param     width   the width of the scaled version whose status is
1083      *                 being checked, or <code>-1</code>.
1084      * @param     height  the height of the scaled version whose status
1085      *                 is being checked, or <code>-1</code>.
1086      * @param     observer   the <code>ImageObserver</code> object to be
1087      *                 notified as the image is being prepared.
1088      * @return    the bitwise inclusive <strong>OR</strong> of the
1089      *                 <code>ImageObserver</code> flags for the
1090      *                 image data that is currently available.
1091      * @see       java.awt.Toolkit#prepareImage(java.awt.Image,
1092      *                 int, int, java.awt.image.ImageObserver)
1093      * @see       java.awt.Component#checkImage(java.awt.Image,
1094      *                 java.awt.image.ImageObserver)
1095      * @see       java.awt.Component#checkImage(java.awt.Image,
1096      *                 int, int, java.awt.image.ImageObserver)
1097      * @see       java.awt.image.ImageObserver
1098      */
1099     public abstract int checkImage(Image image, int width, int height,
1100                                    ImageObserver observer);
1101 
1102     /**
1103      * Creates an image with the specified image producer.
1104      * @param     producer the image producer to be used.
1105      * @return    an image with the specified image producer.
1106      * @see       java.awt.Image
1107      * @see       java.awt.image.ImageProducer
1108      * @see       java.awt.Component#createImage(java.awt.image.ImageProducer)
1109      */
1110     public abstract Image createImage(ImageProducer producer);
1111 
1112     /**
1113      * Creates an image which decodes the image stored in the specified
1114      * byte array.
1115      * <p>
1116      * The data must be in some image format, such as GIF or JPEG,
1117      * that is supported by this toolkit.
1118      * @param     imagedata   an array of bytes, representing
1119      *                         image data in a supported image format.
1120      * @return    an image.
1121      * @since     JDK1.1
1122      */
1123     public Image createImage(byte[] imagedata) {
1124         return createImage(imagedata, 0, imagedata.length);
1125     }
1126 
1127     /**
1128      * Creates an image which decodes the image stored in the specified
1129      * byte array, and at the specified offset and length.
1130      * The data must be in some image format, such as GIF or JPEG,
1131      * that is supported by this toolkit.
1132      * @param     imagedata   an array of bytes, representing
1133      *                         image data in a supported image format.
1134      * @param     imageoffset  the offset of the beginning
1135      *                         of the data in the array.
1136      * @param     imagelength  the length of the data in the array.
1137      * @return    an image.
1138      * @since     JDK1.1
1139      */
1140     public abstract Image createImage(byte[] imagedata,
1141                                       int imageoffset,
1142                                       int imagelength);
1143 
1144     /**
1145      * Gets a <code>PrintJob</code> object which is the result of initiating
1146      * a print operation on the toolkit's platform.
1147      * <p>
1148      * Each actual implementation of this method should first check if there
1149      * is a security manager installed. If there is, the method should call
1150      * the security manager's <code>checkPrintJobAccess</code> method to
1151      * ensure initiation of a print operation is allowed. If the default
1152      * implementation of <code>checkPrintJobAccess</code> is used (that is,
1153      * that method is not overriden), then this results in a call to the
1154      * security manager's <code>checkPermission</code> method with a <code>
1155      * RuntimePermission("queuePrintJob")</code> permission.
1156      *
1157      * @param   frame the parent of the print dialog. May not be null.
1158      * @param   jobtitle the title of the PrintJob. A null title is equivalent
1159      *          to "".
1160      * @param   props a Properties object containing zero or more properties.
1161      *          Properties are not standardized and are not consistent across
1162      *          implementations. Because of this, PrintJobs which require job
1163      *          and page control should use the version of this function which
1164      *          takes JobAttributes and PageAttributes objects. This object
1165      *          may be updated to reflect the user's job choices on exit. May
1166      *          be null.
1167      * @return  a <code>PrintJob</code> object, or <code>null</code> if the
1168      *          user cancelled the print job.
1169      * @throws  NullPointerException if frame is null
1170      * @throws  SecurityException if this thread is not allowed to initiate a
1171      *          print job request
1172      * @see     java.awt.GraphicsEnvironment#isHeadless
1173      * @see     java.awt.PrintJob
1174      * @see     java.lang.RuntimePermission
1175      * @since   JDK1.1
1176      */
1177     public abstract PrintJob getPrintJob(Frame frame, String jobtitle,
1178                                          Properties props);
1179 
1180     /**
1181      * Gets a <code>PrintJob</code> object which is the result of initiating
1182      * a print operation on the toolkit's platform.
1183      * <p>
1184      * Each actual implementation of this method should first check if there
1185      * is a security manager installed. If there is, the method should call
1186      * the security manager's <code>checkPrintJobAccess</code> method to
1187      * ensure initiation of a print operation is allowed. If the default
1188      * implementation of <code>checkPrintJobAccess</code> is used (that is,
1189      * that method is not overriden), then this results in a call to the
1190      * security manager's <code>checkPermission</code> method with a <code>
1191      * RuntimePermission("queuePrintJob")</code> permission.
1192      *
1193      * @param   frame the parent of the print dialog. May not be null.
1194      * @param   jobtitle the title of the PrintJob. A null title is equivalent
1195      *          to "".
1196      * @param   jobAttributes a set of job attributes which will control the
1197      *          PrintJob. The attributes will be updated to reflect the user's
1198      *          choices as outlined in the JobAttributes documentation. May be
1199      *          null.
1200      * @param   pageAttributes a set of page attributes which will control the
1201      *          PrintJob. The attributes will be applied to every page in the
1202      *          job. The attributes will be updated to reflect the user's
1203      *          choices as outlined in the PageAttributes documentation. May be
1204      *          null.
1205      * @return  a <code>PrintJob</code> object, or <code>null</code> if the
1206      *          user cancelled the print job.
1207      * @throws  NullPointerException if frame is null
1208      * @throws  IllegalArgumentException if pageAttributes specifies differing
1209      *          cross feed and feed resolutions. Also if this thread has
1210      *          access to the file system and jobAttributes specifies
1211      *          print to file, and the specified destination file exists but
1212      *          is a directory rather than a regular file, does not exist but
1213      *          cannot be created, or cannot be opened for any other reason.
1214      *          However in the case of print to file, if a dialog is also
1215      *          requested to be displayed then the user will be given an
1216      *          opportunity to select a file and proceed with printing.
1217      *          The dialog will ensure that the selected output file
1218      *          is valid before returning from this method.
1219      * @throws  SecurityException if this thread is not allowed to initiate a
1220      *          print job request, or if jobAttributes specifies print to file,
1221      *          and this thread is not allowed to access the file system
1222      * @see     java.awt.PrintJob
1223      * @see     java.awt.GraphicsEnvironment#isHeadless
1224      * @see     java.lang.RuntimePermission
1225      * @see     java.awt.JobAttributes
1226      * @see     java.awt.PageAttributes
1227      * @since   1.3
1228      */
1229     public PrintJob getPrintJob(Frame frame, String jobtitle,
1230                                 JobAttributes jobAttributes,
1231                                 PageAttributes pageAttributes) {
1232         // Override to add printing support with new job/page control classes
1233 
1234         if (this != Toolkit.getDefaultToolkit()) {
1235             return Toolkit.getDefaultToolkit().getPrintJob(frame, jobtitle,
1236                                                            jobAttributes,
1237                                                            pageAttributes);
1238         } else {
1239             return getPrintJob(frame, jobtitle, null);
1240         }
1241     }
1242 
1243     /**
1244      * Emits an audio beep.
1245      * @since     JDK1.1
1246      */
1247     public abstract void beep();
1248 
1249     /**
1250      * Gets the singleton instance of the system Clipboard which interfaces
1251      * with clipboard facilities provided by the native platform. This
1252      * clipboard enables data transfer between Java programs and native
1253      * applications which use native clipboard facilities.
1254      * <p>
1255      * In addition to any and all formats specified in the flavormap.properties
1256      * file, or other file specified by the <code>AWT.DnD.flavorMapFileURL
1257      * </code> Toolkit property, text returned by the system Clipboard's <code>
1258      * getTransferData()</code> method is available in the following flavors:
1259      * <ul>
1260      * <li>DataFlavor.stringFlavor</li>
1261      * <li>DataFlavor.plainTextFlavor (<b>deprecated</b>)</li>
1262      * </ul>
1263      * As with <code>java.awt.datatransfer.StringSelection</code>, if the
1264      * requested flavor is <code>DataFlavor.plainTextFlavor</code>, or an
1265      * equivalent flavor, a Reader is returned. <b>Note:</b> The behavior of
1266      * the system Clipboard's <code>getTransferData()</code> method for <code>
1267      * DataFlavor.plainTextFlavor</code>, and equivalent DataFlavors, is
1268      * inconsistent with the definition of <code>DataFlavor.plainTextFlavor
1269      * </code>. Because of this, support for <code>
1270      * DataFlavor.plainTextFlavor</code>, and equivalent flavors, is
1271      * <b>deprecated</b>.
1272      * <p>
1273      * Each actual implementation of this method should first check if there
1274      * is a security manager installed. If there is, the method should call
1275      * the security manager's <code>checkSystemClipboardAccess</code> method
1276      * to ensure it's ok to to access the system clipboard. If the default
1277      * implementation of <code>checkSystemClipboardAccess</code> is used (that
1278      * is, that method is not overriden), then this results in a call to the
1279      * security manager's <code>checkPermission</code> method with an <code>
1280      * AWTPermission("accessClipboard")</code> permission.
1281      *
1282      * @return    the system Clipboard
1283      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
1284      * returns true
1285      * @see       java.awt.GraphicsEnvironment#isHeadless
1286      * @see       java.awt.datatransfer.Clipboard
1287      * @see       java.awt.datatransfer.StringSelection
1288      * @see       java.awt.datatransfer.DataFlavor#stringFlavor
1289      * @see       java.awt.datatransfer.DataFlavor#plainTextFlavor
1290      * @see       java.io.Reader
1291      * @see       java.awt.AWTPermission
1292      * @since     JDK1.1
1293      */
1294     public abstract Clipboard getSystemClipboard()
1295         throws HeadlessException;
1296 
1297     /**
1298      * Gets the singleton instance of the system selection as a
1299      * <code>Clipboard</code> object. This allows an application to read and
1300      * modify the current, system-wide selection.
1301      * <p>
1302      * An application is responsible for updating the system selection whenever
1303      * the user selects text, using either the mouse or the keyboard.
1304      * Typically, this is implemented by installing a
1305      * <code>FocusListener</code> on all <code>Component</code>s which support
1306      * text selection, and, between <code>FOCUS_GAINED</code> and
1307      * <code>FOCUS_LOST</code> events delivered to that <code>Component</code>,
1308      * updating the system selection <code>Clipboard</code> when the selection
1309      * changes inside the <code>Component</code>. Properly updating the system
1310      * selection ensures that a Java application will interact correctly with
1311      * native applications and other Java applications running simultaneously
1312      * on the system. Note that <code>java.awt.TextComponent</code> and
1313      * <code>javax.swing.text.JTextComponent</code> already adhere to this
1314      * policy. When using these classes, and their subclasses, developers need
1315      * not write any additional code.
1316      * <p>
1317      * Some platforms do not support a system selection <code>Clipboard</code>.
1318      * On those platforms, this method will return <code>null</code>. In such a
1319      * case, an application is absolved from its responsibility to update the
1320      * system selection <code>Clipboard</code> as described above.
1321      * <p>
1322      * Each actual implementation of this method should first check if there
1323      * is a <code>SecurityManager</code> installed. If there is, the method
1324      * should call the <code>SecurityManager</code>'s
1325      * <code>checkSystemClipboardAccess</code> method to ensure that client
1326      * code has access the system selection. If the default implementation of
1327      * <code>checkSystemClipboardAccess</code> is used (that is, if the method
1328      * is not overridden), then this results in a call to the
1329      * <code>SecurityManager</code>'s <code>checkPermission</code> method with
1330      * an <code>AWTPermission("accessClipboard")</code> permission.
1331      *
1332      * @return the system selection as a <code>Clipboard</code>, or
1333      *         <code>null</code> if the native platform does not support a
1334      *         system selection <code>Clipboard</code>
1335      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
1336      *            returns true
1337      *
1338      * @see java.awt.datatransfer.Clipboard
1339      * @see java.awt.event.FocusListener
1340      * @see java.awt.event.FocusEvent#FOCUS_GAINED
1341      * @see java.awt.event.FocusEvent#FOCUS_LOST
1342      * @see TextComponent
1343      * @see javax.swing.text.JTextComponent
1344      * @see AWTPermission
1345      * @see GraphicsEnvironment#isHeadless
1346      * @since 1.4
1347      */
1348     public Clipboard getSystemSelection() throws HeadlessException {
1349         GraphicsEnvironment.checkHeadless();
1350 
1351         if (this != Toolkit.getDefaultToolkit()) {
1352             return Toolkit.getDefaultToolkit().getSystemSelection();
1353         } else {
1354             GraphicsEnvironment.checkHeadless();
1355             return null;
1356         }
1357     }
1358 
1359     /**
1360      * Determines which modifier key is the appropriate accelerator
1361      * key for menu shortcuts.
1362      * <p>
1363      * Menu shortcuts, which are embodied in the
1364      * <code>MenuShortcut</code> class, are handled by the
1365      * <code>MenuBar</code> class.
1366      * <p>
1367      * By default, this method returns <code>Event.CTRL_MASK</code>.
1368      * Toolkit implementations should override this method if the
1369      * <b>Control</b> key isn't the correct key for accelerators.
1370      * @return    the modifier mask on the <code>Event</code> class
1371      *                 that is used for menu shortcuts on this toolkit.
1372      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
1373      * returns true
1374      * @see       java.awt.GraphicsEnvironment#isHeadless
1375      * @see       java.awt.MenuBar
1376      * @see       java.awt.MenuShortcut
1377      * @since     JDK1.1
1378      */
1379     public int getMenuShortcutKeyMask() throws HeadlessException {
1380         GraphicsEnvironment.checkHeadless();
1381 
1382         return Event.CTRL_MASK;
1383     }
1384 
1385     /**
1386      * Returns whether the given locking key on the keyboard is currently in
1387      * its "on" state.
1388      * Valid key codes are
1389      * {@link java.awt.event.KeyEvent#VK_CAPS_LOCK VK_CAPS_LOCK},
1390      * {@link java.awt.event.KeyEvent#VK_NUM_LOCK VK_NUM_LOCK},
1391      * {@link java.awt.event.KeyEvent#VK_SCROLL_LOCK VK_SCROLL_LOCK}, and
1392      * {@link java.awt.event.KeyEvent#VK_KANA_LOCK VK_KANA_LOCK}.
1393      *
1394      * @exception java.lang.IllegalArgumentException if <code>keyCode</code>
1395      * is not one of the valid key codes
1396      * @exception java.lang.UnsupportedOperationException if the host system doesn't
1397      * allow getting the state of this key programmatically, or if the keyboard
1398      * doesn't have this key
1399      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
1400      * returns true
1401      * @see       java.awt.GraphicsEnvironment#isHeadless
1402      * @since 1.3
1403      */
1404     public boolean getLockingKeyState(int keyCode)
1405         throws UnsupportedOperationException
1406     {
1407         GraphicsEnvironment.checkHeadless();
1408 
1409         if (! (keyCode == KeyEvent.VK_CAPS_LOCK || keyCode == KeyEvent.VK_NUM_LOCK ||
1410                keyCode == KeyEvent.VK_SCROLL_LOCK || keyCode == KeyEvent.VK_KANA_LOCK)) {
1411             throw new IllegalArgumentException("invalid key for Toolkit.getLockingKeyState");
1412         }
1413         throw new UnsupportedOperationException("Toolkit.getLockingKeyState");
1414     }
1415 
1416     /**
1417      * Sets the state of the given locking key on the keyboard.
1418      * Valid key codes are
1419      * {@link java.awt.event.KeyEvent#VK_CAPS_LOCK VK_CAPS_LOCK},
1420      * {@link java.awt.event.KeyEvent#VK_NUM_LOCK VK_NUM_LOCK},
1421      * {@link java.awt.event.KeyEvent#VK_SCROLL_LOCK VK_SCROLL_LOCK}, and
1422      * {@link java.awt.event.KeyEvent#VK_KANA_LOCK VK_KANA_LOCK}.
1423      * <p>
1424      * Depending on the platform, setting the state of a locking key may
1425      * involve event processing and therefore may not be immediately
1426      * observable through getLockingKeyState.
1427      *
1428      * @exception java.lang.IllegalArgumentException if <code>keyCode</code>
1429      * is not one of the valid key codes
1430      * @exception java.lang.UnsupportedOperationException if the host system doesn't
1431      * allow setting the state of this key programmatically, or if the keyboard
1432      * doesn't have this key
1433      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
1434      * returns true
1435      * @see       java.awt.GraphicsEnvironment#isHeadless
1436      * @since 1.3
1437      */
1438     public void setLockingKeyState(int keyCode, boolean on)
1439         throws UnsupportedOperationException
1440     {
1441         GraphicsEnvironment.checkHeadless();
1442 
1443         if (! (keyCode == KeyEvent.VK_CAPS_LOCK || keyCode == KeyEvent.VK_NUM_LOCK ||
1444                keyCode == KeyEvent.VK_SCROLL_LOCK || keyCode == KeyEvent.VK_KANA_LOCK)) {
1445             throw new IllegalArgumentException("invalid key for Toolkit.setLockingKeyState");
1446         }
1447         throw new UnsupportedOperationException("Toolkit.setLockingKeyState");
1448     }
1449 
1450     /**
1451      * Give native peers the ability to query the native container
1452      * given a native component (eg the direct parent may be lightweight).
1453      */
1454     protected static Container getNativeContainer(Component c) {
1455         return c.getNativeContainer();
1456     }
1457 
1458     /**
1459      * Creates a new custom cursor object.
1460      * If the image to display is invalid, the cursor will be hidden (made
1461      * completely transparent), and the hotspot will be set to (0, 0).
1462      *
1463      * <p>Note that multi-frame images are invalid and may cause this
1464      * method to hang.
1465      *
1466      * @param cursor the image to display when the cursor is actived
1467      * @param hotSpot the X and Y of the large cursor's hot spot; the
1468      *   hotSpot values must be less than the Dimension returned by
1469      *   <code>getBestCursorSize</code>
1470      * @param     name a localized description of the cursor, for Java Accessibility use
1471      * @exception IndexOutOfBoundsException if the hotSpot values are outside
1472      *   the bounds of the cursor
1473      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
1474      * returns true
1475      * @see       java.awt.GraphicsEnvironment#isHeadless
1476      * @since     1.2
1477      */
1478     public Cursor createCustomCursor(Image cursor, Point hotSpot, String name)
1479         throws IndexOutOfBoundsException, HeadlessException
1480     {
1481         // Override to implement custom cursor support.
1482         if (this != Toolkit.getDefaultToolkit()) {
1483             return Toolkit.getDefaultToolkit().
1484                 createCustomCursor(cursor, hotSpot, name);
1485         } else {
1486             return new Cursor(Cursor.DEFAULT_CURSOR);
1487         }
1488     }
1489 
1490     /**
1491      * Returns the supported cursor dimension which is closest to the desired
1492      * sizes.  Systems which only support a single cursor size will return that
1493      * size regardless of the desired sizes.  Systems which don't support custom
1494      * cursors will return a dimension of 0, 0. <p>
1495      * Note:  if an image is used whose dimensions don't match a supported size
1496      * (as returned by this method), the Toolkit implementation will attempt to
1497      * resize the image to a supported size.
1498      * Since converting low-resolution images is difficult,
1499      * no guarantees are made as to the quality of a cursor image which isn't a
1500      * supported size.  It is therefore recommended that this method
1501      * be called and an appropriate image used so no image conversion is made.
1502      *
1503      * @param     preferredWidth the preferred cursor width the component would like
1504      * to use.
1505      * @param     preferredHeight the preferred cursor height the component would like
1506      * to use.
1507      * @return    the closest matching supported cursor size, or a dimension of 0,0 if
1508      * the Toolkit implementation doesn't support custom cursors.
1509      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
1510      * returns true
1511      * @see       java.awt.GraphicsEnvironment#isHeadless
1512      * @since     1.2
1513      */
1514     public Dimension getBestCursorSize(int preferredWidth,
1515         int preferredHeight) throws HeadlessException {
1516         GraphicsEnvironment.checkHeadless();
1517 
1518         // Override to implement custom cursor support.
1519         if (this != Toolkit.getDefaultToolkit()) {
1520             return Toolkit.getDefaultToolkit().
1521                 getBestCursorSize(preferredWidth, preferredHeight);
1522         } else {
1523             return new Dimension(0, 0);
1524         }
1525     }
1526 
1527     /**
1528      * Returns the maximum number of colors the Toolkit supports in a custom cursor
1529      * palette.<p>
1530      * Note: if an image is used which has more colors in its palette than
1531      * the supported maximum, the Toolkit implementation will attempt to flatten the
1532      * palette to the maximum.  Since converting low-resolution images is difficult,
1533      * no guarantees are made as to the quality of a cursor image which has more
1534      * colors than the system supports.  It is therefore recommended that this method
1535      * be called and an appropriate image used so no image conversion is made.
1536      *
1537      * @return    the maximum number of colors, or zero if custom cursors are not
1538      * supported by this Toolkit implementation.
1539      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
1540      * returns true
1541      * @see       java.awt.GraphicsEnvironment#isHeadless
1542      * @since     1.2
1543      */
1544     public int getMaximumCursorColors() throws HeadlessException {
1545         GraphicsEnvironment.checkHeadless();
1546 
1547         // Override to implement custom cursor support.
1548         if (this != Toolkit.getDefaultToolkit()) {
1549             return Toolkit.getDefaultToolkit().getMaximumCursorColors();
1550         } else {
1551             return 0;
1552         }
1553     }
1554 
1555     /**
1556      * Returns whether Toolkit supports this state for
1557      * <code>Frame</code>s.  This method tells whether the <em>UI
1558      * concept</em> of, say, maximization or iconification is
1559      * supported.  It will always return false for "compound" states
1560      * like <code>Frame.ICONIFIED|Frame.MAXIMIZED_VERT</code>.
1561      * In other words, the rule of thumb is that only queries with a
1562      * single frame state constant as an argument are meaningful.
1563      * <p>Note that supporting a given concept is a platform-
1564      * dependent feature. Due to native limitations the Toolkit
1565      * object may report a particular state as supported, however at
1566      * the same time the Toolkit object will be unable to apply the
1567      * state to a given frame.  This circumstance has two following
1568      * consequences:
1569      * <ul>
1570      * <li>Only the return value of {@code false} for the present
1571      * method actually indicates that the given state is not
1572      * supported. If the method returns {@code true} the given state
1573      * may still be unsupported and/or unavailable for a particular
1574      * frame.
1575      * <li>The developer should consider examining the value of the
1576      * {@link java.awt.event.WindowEvent#getNewState} method of the
1577      * {@code WindowEvent} received through the {@link
1578      * java.awt.event.WindowStateListener}, rather than assuming
1579      * that the state given to the {@code setExtendedState()} method
1580      * will be definitely applied. For more information see the
1581      * documentation for the {@link Frame#setExtendedState} method.
1582      * </ul>
1583      *
1584      * @param state one of named frame state constants.
1585      * @return <code>true</code> is this frame state is supported by
1586      *     this Toolkit implementation, <code>false</code> otherwise.
1587      * @exception HeadlessException
1588      *     if <code>GraphicsEnvironment.isHeadless()</code>
1589      *     returns <code>true</code>.
1590      * @see java.awt.Window#addWindowStateListener
1591      * @since   1.4
1592      */
1593     public boolean isFrameStateSupported(int state)
1594         throws HeadlessException
1595     {
1596         GraphicsEnvironment.checkHeadless();
1597 
1598         if (this != Toolkit.getDefaultToolkit()) {
1599             return Toolkit.getDefaultToolkit().
1600                 isFrameStateSupported(state);
1601         } else {
1602             return (state == Frame.NORMAL); // others are not guaranteed
1603         }
1604     }
1605 
1606     /**
1607      * Support for I18N: any visible strings should be stored in
1608      * sun.awt.resources.awt.properties.  The ResourceBundle is stored
1609      * here, so that only one copy is maintained.
1610      */
1611     private static ResourceBundle resources;
1612 
1613     /**
1614      * Initialize JNI field and method ids
1615      */
1616     private static native void initIDs();
1617 
1618     /**
1619      * WARNING: This is a temporary workaround for a problem in the
1620      * way the AWT loads native libraries. A number of classes in the
1621      * AWT package have a native method, initIDs(), which initializes
1622      * the JNI field and method ids used in the native portion of
1623      * their implementation.
1624      *
1625      * Since the use and storage of these ids is done by the
1626      * implementation libraries, the implementation of these method is
1627      * provided by the particular AWT implementations (for example,
1628      * "Toolkit"s/Peer), such as Motif, Microsoft Windows, or Tiny. The
1629      * problem is that this means that the native libraries must be
1630      * loaded by the java.* classes, which do not necessarily know the
1631      * names of the libraries to load. A better way of doing this
1632      * would be to provide a separate library which defines java.awt.*
1633      * initIDs, and exports the relevant symbols out to the
1634      * implementation libraries.
1635      *
1636      * For now, we know it's done by the implementation, and we assume
1637      * that the name of the library is "awt".  -br.
1638      *
1639      * If you change loadLibraries(), please add the change to
1640      * java.awt.image.ColorModel.loadLibraries(). Unfortunately,
1641      * classes can be loaded in java.awt.image that depend on
1642      * libawt and there is no way to call Toolkit.loadLibraries()
1643      * directly.  -hung
1644      */
1645     private static boolean loaded = false;
1646     static void loadLibraries() {
1647         if (!loaded) {
1648             java.security.AccessController.doPrivileged(
1649                 new java.security.PrivilegedAction<Void>() {
1650                     public Void run() {
1651                         System.loadLibrary("awt");
1652                         return null;
1653                     }
1654                 });
1655             loaded = true;
1656         }
1657     }
1658 
1659     static {
1660         java.security.AccessController.doPrivileged(
1661                                  new java.security.PrivilegedAction<Void>() {
1662             public Void run() {
1663                 try {
1664                     resources =
1665                         ResourceBundle.getBundle("sun.awt.resources.awt",
1666                                                  CoreResourceBundleControl.getRBControlInstance());
1667                 } catch (MissingResourceException e) {
1668                     // No resource file; defaults will be used.
1669                 }
1670                 return null;
1671             }
1672         });
1673 
1674         // ensure that the proper libraries are loaded
1675         loadLibraries();
1676         initAssistiveTechnologies();
1677         if (!GraphicsEnvironment.isHeadless()) {
1678             initIDs();
1679         }
1680     }
1681 
1682     /**
1683      * Gets a property with the specified key and default.
1684      * This method returns defaultValue if the property is not found.
1685      */
1686     public static String getProperty(String key, String defaultValue) {
1687         if (resources != null) {
1688             try {
1689                 return resources.getString(key);
1690             }
1691             catch (MissingResourceException e) {}
1692         }
1693 
1694         return defaultValue;
1695     }
1696 
1697     /**
1698      * Get the application's or applet's EventQueue instance.
1699      * Depending on the Toolkit implementation, different EventQueues
1700      * may be returned for different applets.  Applets should
1701      * therefore not assume that the EventQueue instance returned
1702      * by this method will be shared by other applets or the system.
1703      *
1704      * <p>First, if there is a security manager, its
1705      * <code>checkAwtEventQueueAccess</code>
1706      * method is called.
1707      * If  the default implementation of <code>checkAwtEventQueueAccess</code>
1708      * is used (that is, that method is not overriden), then this results in
1709      * a call to the security manager's <code>checkPermission</code> method
1710      * with an <code>AWTPermission("accessEventQueue")</code> permission.
1711      *
1712      * @return    the <code>EventQueue</code> object
1713      * @throws  SecurityException
1714      *          if a security manager exists and its <code>{@link
1715      *          java.lang.SecurityManager#checkAwtEventQueueAccess}</code>
1716      *          method denies access to the <code>EventQueue</code>
1717      * @see     java.awt.AWTPermission
1718     */
1719     public final EventQueue getSystemEventQueue() {
1720         SecurityManager security = System.getSecurityManager();
1721         if (security != null) {
1722           security.checkAwtEventQueueAccess();
1723         }
1724         return getSystemEventQueueImpl();
1725     }
1726 
1727     /**
1728      * Gets the application's or applet's <code>EventQueue</code>
1729      * instance, without checking access.  For security reasons,
1730      * this can only be called from a <code>Toolkit</code> subclass.
1731      * @return the <code>EventQueue</code> object
1732      */
1733     protected abstract EventQueue getSystemEventQueueImpl();
1734 
1735     /* Accessor method for use by AWT package routines. */
1736     static EventQueue getEventQueue() {
1737         return getDefaultToolkit().getSystemEventQueueImpl();
1738     }
1739 
1740     /**
1741      * Creates the peer for a DragSourceContext.
1742      * Always throws InvalidDndOperationException if
1743      * GraphicsEnvironment.isHeadless() returns true.
1744      * @see java.awt.GraphicsEnvironment#isHeadless
1745      */
1746     public abstract DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException;
1747 
1748     /**
1749      * Creates a concrete, platform dependent, subclass of the abstract
1750      * DragGestureRecognizer class requested, and associates it with the
1751      * DragSource, Component and DragGestureListener specified.
1752      *
1753      * subclasses should override this to provide their own implementation
1754      *
1755      * @param abstractRecognizerClass The abstract class of the required recognizer
1756      * @param ds                      The DragSource
1757      * @param c                       The Component target for the DragGestureRecognizer
1758      * @param srcActions              The actions permitted for the gesture
1759      * @param dgl                     The DragGestureListener
1760      *
1761      * @return the new object or null.  Always returns null if
1762      * GraphicsEnvironment.isHeadless() returns true.
1763      * @see java.awt.GraphicsEnvironment#isHeadless
1764      */
1765     public <T extends DragGestureRecognizer> T
1766         createDragGestureRecognizer(Class<T> abstractRecognizerClass,
1767                                     DragSource ds, Component c, int srcActions,
1768                                     DragGestureListener dgl)
1769     {
1770         return null;
1771     }
1772 
1773     /**
1774      * Obtains a value for the specified desktop property.
1775      *
1776      * A desktop property is a uniquely named value for a resource that
1777      * is Toolkit global in nature. Usually it also is an abstract
1778      * representation for an underlying platform dependent desktop setting.
1779      * For more information on desktop properties supported by the AWT see
1780      * <a href="doc-files/DesktopProperties.html">AWT Desktop Properties</a>.
1781      */
1782     public final synchronized Object getDesktopProperty(String propertyName) {
1783         // This is a workaround for headless toolkits.  It would be
1784         // better to override this method but it is declared final.
1785         // "this instanceof" syntax defeats polymorphism.
1786         // --mm, 03/03/00
1787         if (this instanceof HeadlessToolkit) {
1788             return ((HeadlessToolkit)this).getUnderlyingToolkit()
1789                 .getDesktopProperty(propertyName);
1790         }
1791 
1792         if (desktopProperties.isEmpty()) {
1793             initializeDesktopProperties();
1794         }
1795 
1796         Object value;
1797 
1798         // This property should never be cached
1799         if (propertyName.equals("awt.dynamicLayoutSupported")) {
1800             value = lazilyLoadDesktopProperty(propertyName);
1801             return value;
1802         }
1803 
1804         value = desktopProperties.get(propertyName);
1805 
1806         if (value == null) {
1807             value = lazilyLoadDesktopProperty(propertyName);
1808 
1809             if (value != null) {
1810                 setDesktopProperty(propertyName, value);
1811             }
1812         }
1813 
1814         /* for property "awt.font.desktophints" */
1815         if (value instanceof RenderingHints) {
1816             value = ((RenderingHints)value).clone();
1817         }
1818 
1819         return value;
1820     }
1821 
1822     /**
1823      * Sets the named desktop property to the specified value and fires a
1824      * property change event to notify any listeners that the value has changed.
1825      */
1826     protected final void setDesktopProperty(String name, Object newValue) {
1827         // This is a workaround for headless toolkits.  It would be
1828         // better to override this method but it is declared final.
1829         // "this instanceof" syntax defeats polymorphism.
1830         // --mm, 03/03/00
1831         if (this instanceof HeadlessToolkit) {
1832             ((HeadlessToolkit)this).getUnderlyingToolkit()
1833                 .setDesktopProperty(name, newValue);
1834             return;
1835         }
1836         Object oldValue;
1837 
1838         synchronized (this) {
1839             oldValue = desktopProperties.get(name);
1840             desktopProperties.put(name, newValue);
1841         }
1842 
1843         // Don't fire change event if old and new values are null.
1844         // It helps to avoid recursive resending of WM_THEMECHANGED
1845         if (oldValue != null || newValue != null) {
1846             desktopPropsSupport.firePropertyChange(name, oldValue, newValue);
1847         }
1848     }
1849 
1850     /**
1851      * an opportunity to lazily evaluate desktop property values.
1852      */
1853     protected Object lazilyLoadDesktopProperty(String name) {
1854         return null;
1855     }
1856 
1857     /**
1858      * initializeDesktopProperties
1859      */
1860     protected void initializeDesktopProperties() {
1861     }
1862 
1863     /**
1864      * Adds the specified property change listener for the named desktop
1865      * property. When a {@link java.beans.PropertyChangeListenerProxy} object is added,
1866      * its property name is ignored, and the wrapped listener is added.
1867      * If {@code name} is {@code null} or {@code pcl} is {@code null},
1868      * no exception is thrown and no action is performed.
1869      *
1870      * @param   name The name of the property to listen for
1871      * @param   pcl The property change listener
1872      * @see PropertyChangeSupport#addPropertyChangeListener(String,
1873                 PropertyChangeListener)
1874      * @since   1.2
1875      */
1876     public void addPropertyChangeListener(String name, PropertyChangeListener pcl) {
1877         desktopPropsSupport.addPropertyChangeListener(name, pcl);
1878     }
1879 
1880     /**
1881      * Removes the specified property change listener for the named
1882      * desktop property. When a {@link java.beans.PropertyChangeListenerProxy} object
1883      * is removed, its property name is ignored, and
1884      * the wrapped listener is removed.
1885      * If {@code name} is {@code null} or {@code pcl} is {@code null},
1886      * no exception is thrown and no action is performed.
1887      *
1888      * @param   name The name of the property to remove
1889      * @param   pcl The property change listener
1890      * @see PropertyChangeSupport#removePropertyChangeListener(String,
1891                 PropertyChangeListener)
1892      * @since   1.2
1893      */
1894     public void removePropertyChangeListener(String name, PropertyChangeListener pcl) {
1895         desktopPropsSupport.removePropertyChangeListener(name, pcl);
1896     }
1897 
1898     /**
1899      * Returns an array of all the property change listeners
1900      * registered on this toolkit. The returned array
1901      * contains {@link java.beans.PropertyChangeListenerProxy} objects
1902      * that associate listeners with the names of desktop properties.
1903      *
1904      * @return all of this toolkit's {@link PropertyChangeListener}
1905      *         objects wrapped in {@code java.beans.PropertyChangeListenerProxy} objects
1906      *         or an empty array  if no listeners are added
1907      *
1908      * @see PropertyChangeSupport#getPropertyChangeListeners()
1909      * @since 1.4
1910      */
1911     public PropertyChangeListener[] getPropertyChangeListeners() {
1912         return desktopPropsSupport.getPropertyChangeListeners();
1913     }
1914 
1915     /**
1916      * Returns an array of all property change listeners
1917      * associated with the specified name of a desktop property.
1918      *
1919      * @param  propertyName the named property
1920      * @return all of the {@code PropertyChangeListener} objects
1921      *         associated with the specified name of a desktop property
1922      *         or an empty array if no such listeners are added
1923      *
1924      * @see PropertyChangeSupport#getPropertyChangeListeners(String)
1925      * @since 1.4
1926      */
1927     public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
1928         return desktopPropsSupport.getPropertyChangeListeners(propertyName);
1929     }
1930 
1931     protected final Map<String,Object> desktopProperties =
1932             new HashMap<String,Object>();
1933     protected final PropertyChangeSupport desktopPropsSupport =
1934             Toolkit.createPropertyChangeSupport(this);
1935 
1936     /**
1937      * Returns whether the always-on-top mode is supported by this toolkit.
1938      * To detect whether the always-on-top mode is supported for a
1939      * particular Window, use {@link Window#isAlwaysOnTopSupported}.
1940      * @return <code>true</code>, if current toolkit supports the always-on-top mode,
1941      *     otherwise returns <code>false</code>
1942      * @see Window#isAlwaysOnTopSupported
1943      * @see Window#setAlwaysOnTop(boolean)
1944      * @since 1.6
1945      */
1946     public boolean isAlwaysOnTopSupported() {
1947         return true;
1948     }
1949 
1950     /**
1951      * Returns whether the given modality type is supported by this toolkit. If
1952      * a dialog with unsupported modality type is created, then
1953      * <code>Dialog.ModalityType.MODELESS</code> is used instead.
1954      *
1955      * @param modalityType modality type to be checked for support by this toolkit
1956      *
1957      * @return <code>true</code>, if current toolkit supports given modality
1958      *     type, <code>false</code> otherwise
1959      *
1960      * @see java.awt.Dialog.ModalityType
1961      * @see java.awt.Dialog#getModalityType
1962      * @see java.awt.Dialog#setModalityType
1963      *
1964      * @since 1.6
1965      */
1966     public abstract boolean isModalityTypeSupported(Dialog.ModalityType modalityType);
1967 
1968     /**
1969      * Returns whether the given modal exclusion type is supported by this
1970      * toolkit. If an unsupported modal exclusion type property is set on a window,
1971      * then <code>Dialog.ModalExclusionType.NO_EXCLUDE</code> is used instead.
1972      *
1973      * @param modalExclusionType modal exclusion type to be checked for support by this toolkit
1974      *
1975      * @return <code>true</code>, if current toolkit supports given modal exclusion
1976      *     type, <code>false</code> otherwise
1977      *
1978      * @see java.awt.Dialog.ModalExclusionType
1979      * @see java.awt.Window#getModalExclusionType
1980      * @see java.awt.Window#setModalExclusionType
1981      *
1982      * @since 1.6
1983      */
1984     public abstract boolean isModalExclusionTypeSupported(Dialog.ModalExclusionType modalExclusionType);
1985 
1986     private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.Toolkit");
1987 
1988     private static final int LONG_BITS = 64;
1989     private int[] calls = new int[LONG_BITS];
1990     private static volatile long enabledOnToolkitMask;
1991     private AWTEventListener eventListener = null;
1992     private WeakHashMap<AWTEventListener, SelectiveAWTEventListener> listener2SelectiveListener = new WeakHashMap<>();
1993 
1994     /*
1995      * Extracts a "pure" AWTEventListener from a AWTEventListenerProxy,
1996      * if the listener is proxied.
1997      */
1998     static private AWTEventListener deProxyAWTEventListener(AWTEventListener l)
1999     {
2000         AWTEventListener localL = l;
2001 
2002         if (localL == null) {
2003             return null;
2004         }
2005         // if user passed in a AWTEventListenerProxy object, extract
2006         // the listener
2007         if (l instanceof AWTEventListenerProxy) {
2008             localL = ((AWTEventListenerProxy)l).getListener();
2009         }
2010         return localL;
2011     }
2012 
2013     /**
2014      * Adds an AWTEventListener to receive all AWTEvents dispatched
2015      * system-wide that conform to the given <code>eventMask</code>.
2016      * <p>
2017      * First, if there is a security manager, its <code>checkPermission</code>
2018      * method is called with an
2019      * <code>AWTPermission("listenToAllAWTEvents")</code> permission.
2020      * This may result in a SecurityException.
2021      * <p>
2022      * <code>eventMask</code> is a bitmask of event types to receive.
2023      * It is constructed by bitwise OR-ing together the event masks
2024      * defined in <code>AWTEvent</code>.
2025      * <p>
2026      * Note:  event listener use is not recommended for normal
2027      * application use, but are intended solely to support special
2028      * purpose facilities including support for accessibility,
2029      * event record/playback, and diagnostic tracing.
2030      *
2031      * If listener is null, no exception is thrown and no action is performed.
2032      *
2033      * @param    listener   the event listener.
2034      * @param    eventMask  the bitmask of event types to receive
2035      * @throws SecurityException
2036      *        if a security manager exists and its
2037      *        <code>checkPermission</code> method doesn't allow the operation.
2038      * @see      #removeAWTEventListener
2039      * @see      #getAWTEventListeners
2040      * @see      SecurityManager#checkPermission
2041      * @see      java.awt.AWTEvent
2042      * @see      java.awt.AWTPermission
2043      * @see      java.awt.event.AWTEventListener
2044      * @see      java.awt.event.AWTEventListenerProxy
2045      * @since    1.2
2046      */
2047     public void addAWTEventListener(AWTEventListener listener, long eventMask) {
2048         AWTEventListener localL = deProxyAWTEventListener(listener);
2049 
2050         if (localL == null) {
2051             return;
2052         }
2053         SecurityManager security = System.getSecurityManager();
2054         if (security != null) {
2055           security.checkPermission(SecurityConstants.AWT.ALL_AWT_EVENTS_PERMISSION);
2056         }
2057         synchronized (this) {
2058             SelectiveAWTEventListener selectiveListener =
2059                 listener2SelectiveListener.get(localL);
2060 
2061             if (selectiveListener == null) {
2062                 // Create a new selectiveListener.
2063                 selectiveListener = new SelectiveAWTEventListener(localL,
2064                                                                  eventMask);
2065                 listener2SelectiveListener.put(localL, selectiveListener);
2066                 eventListener = ToolkitEventMulticaster.add(eventListener,
2067                                                             selectiveListener);
2068             }
2069             // OR the eventMask into the selectiveListener's event mask.
2070             selectiveListener.orEventMasks(eventMask);
2071 
2072             enabledOnToolkitMask |= eventMask;
2073 
2074             long mask = eventMask;
2075             for (int i=0; i<LONG_BITS; i++) {
2076                 // If no bits are set, break out of loop.
2077                 if (mask == 0) {
2078                     break;
2079                 }
2080                 if ((mask & 1L) != 0) {  // Always test bit 0.
2081                     calls[i]++;
2082                 }
2083                 mask >>>= 1;  // Right shift, fill with zeros on left.
2084             }
2085         }
2086     }
2087 
2088     /**
2089      * Removes an AWTEventListener from receiving dispatched AWTEvents.
2090      * <p>
2091      * First, if there is a security manager, its <code>checkPermission</code>
2092      * method is called with an
2093      * <code>AWTPermission("listenToAllAWTEvents")</code> permission.
2094      * This may result in a SecurityException.
2095      * <p>
2096      * Note:  event listener use is not recommended for normal
2097      * application use, but are intended solely to support special
2098      * purpose facilities including support for accessibility,
2099      * event record/playback, and diagnostic tracing.
2100      *
2101      * If listener is null, no exception is thrown and no action is performed.
2102      *
2103      * @param    listener   the event listener.
2104      * @throws SecurityException
2105      *        if a security manager exists and its
2106      *        <code>checkPermission</code> method doesn't allow the operation.
2107      * @see      #addAWTEventListener
2108      * @see      #getAWTEventListeners
2109      * @see      SecurityManager#checkPermission
2110      * @see      java.awt.AWTEvent
2111      * @see      java.awt.AWTPermission
2112      * @see      java.awt.event.AWTEventListener
2113      * @see      java.awt.event.AWTEventListenerProxy
2114      * @since    1.2
2115      */
2116     public void removeAWTEventListener(AWTEventListener listener) {
2117         AWTEventListener localL = deProxyAWTEventListener(listener);
2118 
2119         if (listener == null) {
2120             return;
2121         }
2122         SecurityManager security = System.getSecurityManager();
2123         if (security != null) {
2124             security.checkPermission(SecurityConstants.AWT.ALL_AWT_EVENTS_PERMISSION);
2125         }
2126 
2127         synchronized (this) {
2128             SelectiveAWTEventListener selectiveListener =
2129                 listener2SelectiveListener.get(localL);
2130 
2131             if (selectiveListener != null) {
2132                 listener2SelectiveListener.remove(localL);
2133                 int[] listenerCalls = selectiveListener.getCalls();
2134                 for (int i=0; i<LONG_BITS; i++) {
2135                     calls[i] -= listenerCalls[i];
2136                     assert calls[i] >= 0: "Negative Listeners count";
2137 
2138                     if (calls[i] == 0) {
2139                         enabledOnToolkitMask &= ~(1L<<i);
2140                     }
2141                 }
2142             }
2143             eventListener = ToolkitEventMulticaster.remove(eventListener,
2144             (selectiveListener == null) ? localL : selectiveListener);
2145         }
2146     }
2147 
2148     static boolean enabledOnToolkit(long eventMask) {
2149         return (enabledOnToolkitMask & eventMask) != 0;
2150         }
2151 
2152     synchronized int countAWTEventListeners(long eventMask) {
2153         if (log.isLoggable(PlatformLogger.FINE)) {
2154             if (eventMask == 0) {
2155                 log.fine("Assertion (eventMask != 0) failed");
2156             }
2157         }
2158 
2159         int ci = 0;
2160         for (; eventMask != 0; eventMask >>>= 1, ci++) {
2161         }
2162         ci--;
2163         return calls[ci];
2164     }
2165     /**
2166      * Returns an array of all the <code>AWTEventListener</code>s
2167      * registered on this toolkit.
2168      * If there is a security manager, its {@code checkPermission}
2169      * method is called with an
2170      * {@code AWTPermission("listenToAllAWTEvents")} permission.
2171      * This may result in a SecurityException.
2172      * Listeners can be returned
2173      * within <code>AWTEventListenerProxy</code> objects, which also contain
2174      * the event mask for the given listener.
2175      * Note that listener objects
2176      * added multiple times appear only once in the returned array.
2177      *
2178      * @return all of the <code>AWTEventListener</code>s or an empty
2179      *         array if no listeners are currently registered
2180      * @throws SecurityException
2181      *        if a security manager exists and its
2182      *        <code>checkPermission</code> method doesn't allow the operation.
2183      * @see      #addAWTEventListener
2184      * @see      #removeAWTEventListener
2185      * @see      SecurityManager#checkPermission
2186      * @see      java.awt.AWTEvent
2187      * @see      java.awt.AWTPermission
2188      * @see      java.awt.event.AWTEventListener
2189      * @see      java.awt.event.AWTEventListenerProxy
2190      * @since 1.4
2191      */
2192     public AWTEventListener[] getAWTEventListeners() {
2193         SecurityManager security = System.getSecurityManager();
2194         if (security != null) {
2195             security.checkPermission(SecurityConstants.AWT.ALL_AWT_EVENTS_PERMISSION);
2196         }
2197         synchronized (this) {
2198             EventListener[] la = ToolkitEventMulticaster.getListeners(eventListener,AWTEventListener.class);
2199 
2200             AWTEventListener[] ret = new AWTEventListener[la.length];
2201             for (int i = 0; i < la.length; i++) {
2202                 SelectiveAWTEventListener sael = (SelectiveAWTEventListener)la[i];
2203                 AWTEventListener tempL = sael.getListener();
2204                 //assert tempL is not an AWTEventListenerProxy - we should
2205                 // have weeded them all out
2206                 // don't want to wrap a proxy inside a proxy
2207                 ret[i] = new AWTEventListenerProxy(sael.getEventMask(), tempL);
2208             }
2209             return ret;
2210         }
2211     }
2212 
2213     /**
2214      * Returns an array of all the <code>AWTEventListener</code>s
2215      * registered on this toolkit which listen to all of the event
2216      * types specified in the {@code eventMask} argument.
2217      * If there is a security manager, its {@code checkPermission}
2218      * method is called with an
2219      * {@code AWTPermission("listenToAllAWTEvents")} permission.
2220      * This may result in a SecurityException.
2221      * Listeners can be returned
2222      * within <code>AWTEventListenerProxy</code> objects, which also contain
2223      * the event mask for the given listener.
2224      * Note that listener objects
2225      * added multiple times appear only once in the returned array.
2226      *
2227      * @param  eventMask the bitmask of event types to listen for
2228      * @return all of the <code>AWTEventListener</code>s registered
2229      *         on this toolkit for the specified
2230      *         event types, or an empty array if no such listeners
2231      *         are currently registered
2232      * @throws SecurityException
2233      *        if a security manager exists and its
2234      *        <code>checkPermission</code> method doesn't allow the operation.
2235      * @see      #addAWTEventListener
2236      * @see      #removeAWTEventListener
2237      * @see      SecurityManager#checkPermission
2238      * @see      java.awt.AWTEvent
2239      * @see      java.awt.AWTPermission
2240      * @see      java.awt.event.AWTEventListener
2241      * @see      java.awt.event.AWTEventListenerProxy
2242      * @since 1.4
2243      */
2244     public AWTEventListener[] getAWTEventListeners(long eventMask) {
2245         SecurityManager security = System.getSecurityManager();
2246         if (security != null) {
2247             security.checkPermission(SecurityConstants.AWT.ALL_AWT_EVENTS_PERMISSION);
2248         }
2249         synchronized (this) {
2250             EventListener[] la = ToolkitEventMulticaster.getListeners(eventListener,AWTEventListener.class);
2251 
2252             java.util.List<AWTEventListenerProxy> list = new ArrayList<>(la.length);
2253 
2254             for (int i = 0; i < la.length; i++) {
2255                 SelectiveAWTEventListener sael = (SelectiveAWTEventListener)la[i];
2256                 if ((sael.getEventMask() & eventMask) == eventMask) {
2257                     //AWTEventListener tempL = sael.getListener();
2258                     list.add(new AWTEventListenerProxy(sael.getEventMask(),
2259                                                        sael.getListener()));
2260                 }
2261             }
2262             return list.toArray(new AWTEventListener[0]);
2263         }
2264     }
2265 
2266     /*
2267      * This method notifies any AWTEventListeners that an event
2268      * is about to be dispatched.
2269      *
2270      * @param theEvent the event which will be dispatched.
2271      */
2272     void notifyAWTEventListeners(AWTEvent theEvent) {
2273         // This is a workaround for headless toolkits.  It would be
2274         // better to override this method but it is declared package private.
2275         // "this instanceof" syntax defeats polymorphism.
2276         // --mm, 03/03/00
2277         if (this instanceof HeadlessToolkit) {
2278             ((HeadlessToolkit)this).getUnderlyingToolkit()
2279                 .notifyAWTEventListeners(theEvent);
2280             return;
2281         }
2282 
2283         AWTEventListener eventListener = this.eventListener;
2284         if (eventListener != null) {
2285             eventListener.eventDispatched(theEvent);
2286         }
2287     }
2288 
2289     static private class ToolkitEventMulticaster extends AWTEventMulticaster
2290         implements AWTEventListener {
2291         // Implementation cloned from AWTEventMulticaster.
2292 
2293         ToolkitEventMulticaster(AWTEventListener a, AWTEventListener b) {
2294             super(a, b);
2295         }
2296 
2297         static AWTEventListener add(AWTEventListener a,
2298                                     AWTEventListener b) {
2299             if (a == null)  return b;
2300             if (b == null)  return a;
2301             return new ToolkitEventMulticaster(a, b);
2302         }
2303 
2304         static AWTEventListener remove(AWTEventListener l,
2305                                        AWTEventListener oldl) {
2306             return (AWTEventListener) removeInternal(l, oldl);
2307         }
2308 
2309         // #4178589: must overload remove(EventListener) to call our add()
2310         // instead of the static addInternal() so we allocate a
2311         // ToolkitEventMulticaster instead of an AWTEventMulticaster.
2312         // Note: this method is called by AWTEventListener.removeInternal(),
2313         // so its method signature must match AWTEventListener.remove().
2314         protected EventListener remove(EventListener oldl) {
2315             if (oldl == a)  return b;
2316             if (oldl == b)  return a;
2317             AWTEventListener a2 = (AWTEventListener)removeInternal(a, oldl);
2318             AWTEventListener b2 = (AWTEventListener)removeInternal(b, oldl);
2319             if (a2 == a && b2 == b) {
2320                 return this;    // it's not here
2321             }
2322             return add(a2, b2);
2323         }
2324 
2325         public void eventDispatched(AWTEvent event) {
2326             ((AWTEventListener)a).eventDispatched(event);
2327             ((AWTEventListener)b).eventDispatched(event);
2328         }
2329     }
2330 
2331     private class SelectiveAWTEventListener implements AWTEventListener {
2332         AWTEventListener listener;
2333         private long eventMask;
2334         // This array contains the number of times to call the eventlistener
2335         // for each event type.
2336         int[] calls = new int[Toolkit.LONG_BITS];
2337 
2338         public AWTEventListener getListener() {return listener;}
2339         public long getEventMask() {return eventMask;}
2340         public int[] getCalls() {return calls;}
2341 
2342         public void orEventMasks(long mask) {
2343             eventMask |= mask;
2344             // For each event bit set in mask, increment its call count.
2345             for (int i=0; i<Toolkit.LONG_BITS; i++) {
2346                 // If no bits are set, break out of loop.
2347                 if (mask == 0) {
2348                     break;
2349                 }
2350                 if ((mask & 1L) != 0) {  // Always test bit 0.
2351                     calls[i]++;
2352                 }
2353                 mask >>>= 1;  // Right shift, fill with zeros on left.
2354             }
2355         }
2356 
2357         SelectiveAWTEventListener(AWTEventListener l, long mask) {
2358             listener = l;
2359             eventMask = mask;
2360         }
2361 
2362         public void eventDispatched(AWTEvent event) {
2363             long eventBit = 0; // Used to save the bit of the event type.
2364             if (((eventBit = eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0 &&
2365                  event.id >= ComponentEvent.COMPONENT_FIRST &&
2366                  event.id <= ComponentEvent.COMPONENT_LAST)
2367              || ((eventBit = eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 &&
2368                  event.id >= ContainerEvent.CONTAINER_FIRST &&
2369                  event.id <= ContainerEvent.CONTAINER_LAST)
2370              || ((eventBit = eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0 &&
2371                  event.id >= FocusEvent.FOCUS_FIRST &&
2372                  event.id <= FocusEvent.FOCUS_LAST)
2373              || ((eventBit = eventMask & AWTEvent.KEY_EVENT_MASK) != 0 &&
2374                  event.id >= KeyEvent.KEY_FIRST &&
2375                  event.id <= KeyEvent.KEY_LAST)
2376              || ((eventBit = eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0 &&
2377                  event.id == MouseEvent.MOUSE_WHEEL)
2378              || ((eventBit = eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0 &&
2379                  (event.id == MouseEvent.MOUSE_MOVED ||
2380                   event.id == MouseEvent.MOUSE_DRAGGED))
2381              || ((eventBit = eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0 &&
2382                  event.id != MouseEvent.MOUSE_MOVED &&
2383                  event.id != MouseEvent.MOUSE_DRAGGED &&
2384                  event.id != MouseEvent.MOUSE_WHEEL &&
2385                  event.id >= MouseEvent.MOUSE_FIRST &&
2386                  event.id <= MouseEvent.MOUSE_LAST)
2387              || ((eventBit = eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0 &&
2388                  (event.id >= WindowEvent.WINDOW_FIRST &&
2389                  event.id <= WindowEvent.WINDOW_LAST))
2390              || ((eventBit = eventMask & AWTEvent.ACTION_EVENT_MASK) != 0 &&
2391                  event.id >= ActionEvent.ACTION_FIRST &&
2392                  event.id <= ActionEvent.ACTION_LAST)
2393              || ((eventBit = eventMask & AWTEvent.ADJUSTMENT_EVENT_MASK) != 0 &&
2394                  event.id >= AdjustmentEvent.ADJUSTMENT_FIRST &&
2395                  event.id <= AdjustmentEvent.ADJUSTMENT_LAST)
2396              || ((eventBit = eventMask & AWTEvent.ITEM_EVENT_MASK) != 0 &&
2397                  event.id >= ItemEvent.ITEM_FIRST &&
2398                  event.id <= ItemEvent.ITEM_LAST)
2399              || ((eventBit = eventMask & AWTEvent.TEXT_EVENT_MASK) != 0 &&
2400                  event.id >= TextEvent.TEXT_FIRST &&
2401                  event.id <= TextEvent.TEXT_LAST)
2402              || ((eventBit = eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0 &&
2403                  event.id >= InputMethodEvent.INPUT_METHOD_FIRST &&
2404                  event.id <= InputMethodEvent.INPUT_METHOD_LAST)
2405              || ((eventBit = eventMask & AWTEvent.PAINT_EVENT_MASK) != 0 &&
2406                  event.id >= PaintEvent.PAINT_FIRST &&
2407                  event.id <= PaintEvent.PAINT_LAST)
2408              || ((eventBit = eventMask & AWTEvent.INVOCATION_EVENT_MASK) != 0 &&
2409                  event.id >= InvocationEvent.INVOCATION_FIRST &&
2410                  event.id <= InvocationEvent.INVOCATION_LAST)
2411              || ((eventBit = eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 &&
2412                  event.id == HierarchyEvent.HIERARCHY_CHANGED)
2413              || ((eventBit = eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 &&
2414                  (event.id == HierarchyEvent.ANCESTOR_MOVED ||
2415                   event.id == HierarchyEvent.ANCESTOR_RESIZED))
2416              || ((eventBit = eventMask & AWTEvent.WINDOW_STATE_EVENT_MASK) != 0 &&
2417                  event.id == WindowEvent.WINDOW_STATE_CHANGED)
2418              || ((eventBit = eventMask & AWTEvent.WINDOW_FOCUS_EVENT_MASK) != 0 &&
2419                  (event.id == WindowEvent.WINDOW_GAINED_FOCUS ||
2420                   event.id == WindowEvent.WINDOW_LOST_FOCUS))
2421                 || ((eventBit = eventMask & sun.awt.SunToolkit.GRAB_EVENT_MASK) != 0 &&
2422                     (event instanceof sun.awt.UngrabEvent))) {
2423                 // Get the index of the call count for this event type.
2424                 // Instead of using Math.log(...) we will calculate it with
2425                 // bit shifts. That's what previous implementation looked like:
2426                 //
2427                 // int ci = (int) (Math.log(eventBit)/Math.log(2));
2428                 int ci = 0;
2429                 for (long eMask = eventBit; eMask != 0; eMask >>>= 1, ci++) {
2430                 }
2431                 ci--;
2432                 // Call the listener as many times as it was added for this
2433                 // event type.
2434                 for (int i=0; i<calls[ci]; i++) {
2435                     listener.eventDispatched(event);
2436                 }
2437             }
2438         }
2439     }
2440 
2441     /**
2442      * Returns a map of visual attributes for the abstract level description
2443      * of the given input method highlight, or null if no mapping is found.
2444      * The style field of the input method highlight is ignored. The map
2445      * returned is unmodifiable.
2446      * @param highlight input method highlight
2447      * @return style attribute map, or <code>null</code>
2448      * @exception HeadlessException if
2449      *     <code>GraphicsEnvironment.isHeadless</code> returns true
2450      * @see       java.awt.GraphicsEnvironment#isHeadless
2451      * @since 1.3
2452      */
2453     public abstract Map<java.awt.font.TextAttribute,?>
2454         mapInputMethodHighlight(InputMethodHighlight highlight)
2455         throws HeadlessException;
2456 
2457     private static PropertyChangeSupport createPropertyChangeSupport(Toolkit toolkit) {
2458         if (toolkit instanceof SunToolkit || toolkit instanceof HeadlessToolkit) {
2459             return new DesktopPropertyChangeSupport(toolkit);
2460         } else {
2461             return new PropertyChangeSupport(toolkit);
2462         }
2463     }
2464 
2465     @SuppressWarnings("serial")
2466     private static class DesktopPropertyChangeSupport extends PropertyChangeSupport {
2467 
2468         private static final StringBuilder PROP_CHANGE_SUPPORT_KEY =
2469                 new StringBuilder("desktop property change support key");
2470         private final Object source;
2471 
2472         public DesktopPropertyChangeSupport(Object sourceBean) {
2473             super(sourceBean);
2474             source = sourceBean;
2475         }
2476 
2477         @Override
2478         public synchronized void addPropertyChangeListener(
2479                 String propertyName,
2480                 PropertyChangeListener listener)
2481         {
2482             PropertyChangeSupport pcs = (PropertyChangeSupport)
2483                     AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY);
2484             if (null == pcs) {
2485                 pcs = new PropertyChangeSupport(source);
2486                 AppContext.getAppContext().put(PROP_CHANGE_SUPPORT_KEY, pcs);
2487             }
2488             pcs.addPropertyChangeListener(propertyName, listener);
2489         }
2490 
2491         @Override
2492         public synchronized void removePropertyChangeListener(
2493                 String propertyName,
2494                 PropertyChangeListener listener)
2495         {
2496             PropertyChangeSupport pcs = (PropertyChangeSupport)
2497                     AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY);
2498             if (null != pcs) {
2499                 pcs.removePropertyChangeListener(propertyName, listener);
2500             }
2501         }
2502 
2503         @Override
2504         public synchronized PropertyChangeListener[] getPropertyChangeListeners()
2505         {
2506             PropertyChangeSupport pcs = (PropertyChangeSupport)
2507                     AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY);
2508             if (null != pcs) {
2509                 return pcs.getPropertyChangeListeners();
2510             } else {
2511                 return new PropertyChangeListener[0];
2512             }
2513         }
2514 
2515         @Override
2516         public synchronized PropertyChangeListener[] getPropertyChangeListeners(String propertyName)
2517         {
2518             PropertyChangeSupport pcs = (PropertyChangeSupport)
2519                     AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY);
2520             if (null != pcs) {
2521                 return pcs.getPropertyChangeListeners(propertyName);
2522             } else {
2523                 return new PropertyChangeListener[0];
2524             }
2525         }
2526 
2527         @Override
2528         public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
2529             PropertyChangeSupport pcs = (PropertyChangeSupport)
2530                     AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY);
2531             if (null == pcs) {
2532                 pcs = new PropertyChangeSupport(source);
2533                 AppContext.getAppContext().put(PROP_CHANGE_SUPPORT_KEY, pcs);
2534             }
2535             pcs.addPropertyChangeListener(listener);
2536         }
2537 
2538         @Override
2539         public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
2540             PropertyChangeSupport pcs = (PropertyChangeSupport)
2541                     AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY);
2542             if (null != pcs) {
2543                 pcs.removePropertyChangeListener(listener);
2544             }
2545         }
2546 
2547         /*
2548          * we do expect that all other fireXXX() methods of java.beans.PropertyChangeSupport
2549          * use this method.  If this will be changed we will need to change this class.
2550          */
2551         @Override
2552         public void firePropertyChange(final PropertyChangeEvent evt) {
2553             Object oldValue = evt.getOldValue();
2554             Object newValue = evt.getNewValue();
2555             String propertyName = evt.getPropertyName();
2556             if (oldValue != null && newValue != null && oldValue.equals(newValue)) {
2557                 return;
2558             }
2559             Runnable updater = new Runnable() {
2560                 public void run() {
2561                     PropertyChangeSupport pcs = (PropertyChangeSupport)
2562                             AppContext.getAppContext().get(PROP_CHANGE_SUPPORT_KEY);
2563                     if (null != pcs) {
2564                         pcs.firePropertyChange(evt);
2565                     }
2566                 }
2567             };
2568             final AppContext currentAppContext = AppContext.getAppContext();
2569             for (AppContext appContext : AppContext.getAppContexts()) {
2570                 if (null == appContext || appContext.isDisposed()) {
2571                     continue;
2572                 }
2573                 if (currentAppContext == appContext) {
2574                     updater.run();
2575                 } else {
2576                     final PeerEvent e = new PeerEvent(source, updater, PeerEvent.ULTIMATE_PRIORITY_EVENT);
2577                     SunToolkit.postEvent(appContext, e);
2578                 }
2579             }
2580         }
2581     }
2582 
2583     /**
2584     * Reports whether events from extra mouse buttons are allowed to be processed and posted into
2585     * {@code EventQueue}.
2586     * <br>
2587     * To change the returned value it is necessary to set the {@code sun.awt.enableExtraMouseButtons}
2588     * property before the {@code Toolkit} class initialization. This setting could be done on the application
2589     * startup by the following command:
2590     * <pre>
2591     * java -Dsun.awt.enableExtraMouseButtons=false Application
2592     * </pre>
2593     * Alternatively, the property could be set in the application by using the following code:
2594     * <pre>
2595     * System.setProperty("sun.awt.enableExtraMouseButtons", "true");
2596     * </pre>
2597     * before the {@code Toolkit} class initialization.
2598     * If not set by the time of the {@code Toolkit} class initialization, this property will be
2599     * initialized with {@code true}.
2600     * Changing this value after the {@code Toolkit} class initialization will have no effect.
2601     * <p>
2602     * @exception HeadlessException if GraphicsEnvironment.isHeadless() returns true
2603     * @return {@code true} if events from extra mouse buttons are allowed to be processed and posted;
2604     *         {@code false} otherwise
2605     * @see System#getProperty(String propertyName)
2606     * @see System#setProperty(String propertyName, String value)
2607     * @see java.awt.EventQueue
2608     * @since 1.7
2609      */
2610     public boolean areExtraMouseButtonsEnabled() throws HeadlessException {
2611         GraphicsEnvironment.checkHeadless();
2612 
2613         return Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled();
2614     }
2615 }