gt:         if (WDesktopProperties.isWindowsProperty(name) ||
context: /*
   * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.  Oracle designates this
   * particular file as subject to the "Classpath" exception as provided
   * by Oracle in the LICENSE file that accompanied this code.
   *
   * This code is distributed in the hope that it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   * version 2 for more details (a copy is included in the LICENSE file that
   * accompanied this code).
   *
   * You should have received a copy of the GNU General Public License version
   * 2 along with this work; if not, write to the Free Software Foundation,
   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   *
   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   * or visit www.oracle.com if you need additional information or have any
   * questions.
   */
  
  package sun.awt.windows;
  
  import java.awt.*;
  import java.awt.im.InputMethodHighlight;
  import java.awt.im.spi.InputMethodDescriptor;
  import java.awt.image.*;
  import java.awt.peer.*;
  import java.awt.event.KeyEvent;
  import java.awt.datatransfer.Clipboard;
  import java.awt.TrayIcon;
  import java.beans.PropertyChangeListener;
  import java.security.AccessController;
  import java.security.PrivilegedAction;
  import sun.awt.AppContext;
  import sun.awt.AWTAutoShutdown;
  import sun.awt.AWTPermissions;
  import sun.awt.AppContext;
  import sun.awt.LightweightFrame;
  import sun.awt.SunToolkit;
  import sun.awt.util.ThreadGroupUtils;
  import sun.awt.Win32GraphicsDevice;
  import sun.awt.Win32GraphicsEnvironment;
  import sun.awt.datatransfer.DataTransferer;
  import sun.java2d.d3d.D3DRenderQueue;
  import sun.java2d.opengl.OGLRenderQueue;
  
  import sun.print.PrintJob2D;
  
  import java.awt.dnd.DragSource;
  import java.awt.dnd.DragGestureListener;
  import java.awt.dnd.DragGestureEvent;
  import java.awt.dnd.DragGestureRecognizer;
  import java.awt.dnd.MouseDragGestureRecognizer;
  import java.awt.dnd.InvalidDnDOperationException;
  import java.awt.dnd.peer.DragSourceContextPeer;
  
  import java.util.Hashtable;
  import java.util.Locale;
  import java.util.Map;
  import java.util.Properties;
  
  import sun.font.FontManager;
  import sun.font.FontManagerFactory;
  import sun.font.SunFontManager;
  import sun.misc.PerformanceLogger;
  import sun.util.logging.PlatformLogger;
  
  public final class WToolkit extends SunToolkit implements Runnable {
  
      private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.windows.WToolkit");
  
      // Desktop property which specifies whether XP visual styles are in effect
      public static final String XPSTYLE_THEME_ACTIVE = "win.xpstyle.themeActive";
  
      static GraphicsConfiguration config;
  
      // System clipboard.
      WClipboard clipboard;
  
      // cache of font peers
      private Hashtable<String,FontPeer> cacheFontPeer;
  
      // Windows properties
      private WDesktopProperties  wprops;
  
      // Dynamic Layout Resize client code setting
      protected boolean dynamicLayoutSetting = false;
  
      //Is it allowed to generate events assigned to extra mouse buttons.
      //Set to true by default.
      private static boolean areExtraMouseButtonsEnabled = true;
  
      /**
       * Initialize JNI field and method IDs
       */
      private static native void initIDs();
      private static boolean loaded = false;
      public static void loadLibraries() {
          if (!loaded) {
              java.security.AccessController.doPrivileged(
                  new java.security.PrivilegedAction<Void>() {
                      @Override
                      public Void run() {
                          System.loadLibrary("awt");
                          return null;
                      }
                  });
              loaded = true;
          }
      }
  
      private static native String getWindowsVersion();
  
      static {
          loadLibraries();
          initIDs();
  
          // Print out which version of Windows is running
          if (log.isLoggable(PlatformLogger.Level.FINE)) {
              log.fine("Win version: " + getWindowsVersion());
          }
  
          AccessController.doPrivileged(
              new PrivilegedAction <Void> ()
          {
              @Override
              public Void run() {
                  String browserProp = System.getProperty("browser");
                  if (browserProp != null && browserProp.equals("sun.plugin")) {
                      disableCustomPalette();
                  }
                  return null;
              }
          });
      }
  
      private static native void disableCustomPalette();
  
      /*
       * Reset the static GraphicsConfiguration to the default.  Called on
       * startup and when display settings have changed.
       */
      public static void resetGC() {
          if (GraphicsEnvironment.isHeadless()) {
              config = null;
          } else {
            config = (GraphicsEnvironment
                    .getLocalGraphicsEnvironment()
            .getDefaultScreenDevice()
            .getDefaultConfiguration());
          }
      }
  
      /*
       * NOTE: The following embedded*() methods are non-public API intended
       * for internal use only.  The methods are unsupported and could go
       * away in future releases.
       *
       * New hook functions for using the AWT as an embedded service. These
       * functions replace the global C function AwtInit() which was previously
       * exported by awt.dll.
       *
       * When used as an embedded service, the AWT does NOT have its own
       * message pump. It instead relies on the parent application to provide
       * this functionality. embeddedInit() assumes that the thread on which it
       * is called is the message pumping thread. Violating this assumption
       * will lead to undefined behavior.
       *
       * embeddedInit must be called before the WToolkit() constructor.
       * embeddedDispose should be called before the applicaton terminates the
       * Java VM. It is currently unsafe to reinitialize the toolkit again
       * after it has been disposed. Instead, awt.dll must be reloaded and the
       * class loader which loaded WToolkit must be finalized before it is
       * safe to reuse AWT. Dynamic reusability may be added to the toolkit in
       * the future.
       */
  
      /**
       * Initializes the Toolkit for use in an embedded environment.
       *
       * @return true if the initialization succeeded; false if it failed.
       *         The function will fail if the Toolkit was already initialized.
       * @since 1.3
       */
      public static native boolean embeddedInit();
  
      /**
       * Disposes the Toolkit in an embedded environment. This method should
       * not be called on exit unless the Toolkit was constructed with
       * embeddedInit.
       *
       * @return true if the disposal succeeded; false if it failed. The
       *         function will fail if the calling thread is not the same
       *         thread which called embeddedInit(), or if the Toolkit was
       *         already disposed.
       * @since 1.3
       */
      public static native boolean embeddedDispose();
  
      /**
       * To be called after processing the event queue by users of the above
       * embeddedInit() function.  The reason for this additional call is that
       * there are some operations performed during idle time in the AwtToolkit
       * event loop which should also be performed during idle time in any
       * other native event loop.  Failure to do so could result in
       * deadlocks.
       *
       * This method was added at the last minute of the jdk1.4 release
       * to work around a specific customer problem.  As with the above
       * embedded*() class, this method is non-public and should not be
       * used by external applications.
       *
       * See bug #4526587 for more information.
       */
      public native void embeddedEventLoopIdleProcessing();
  
      static class ToolkitDisposer implements sun.java2d.DisposerRecord {
          @Override
          public void dispose() {
              WToolkit.postDispose();
          }
      }
  
      private final Object anchor = new Object();
  
      private static native void postDispose();
  
      private static native boolean startToolkitThread(Runnable thread, ThreadGroup rootThreadGroup);
  
      public WToolkit() {
          // Startup toolkit threads
          if (PerformanceLogger.loggingEnabled()) {
              PerformanceLogger.setTime("WToolkit construction");
          }
  
          sun.java2d.Disposer.addRecord(anchor, new ToolkitDisposer());
  
          /*
           * Fix for 4701990.
           * AWTAutoShutdown state must be changed before the toolkit thread
           * starts to avoid race condition.
           */
          AWTAutoShutdown.notifyToolkitThreadBusy();
  
          // Find a root TG and attach Appkit thread to it
          ThreadGroup rootTG = AccessController.doPrivileged(
                  (PrivilegedAction<ThreadGroup>) ThreadGroupUtils::getRootThreadGroup);
          if (!startToolkitThread(this, rootTG)) {
              Thread toolkitThread = new Thread(rootTG, this, "AWT-Windows");
              toolkitThread.setDaemon(true);
              toolkitThread.start();
          }
  
          try {
              synchronized(this) {
                  while(!inited) {
                      wait();
                  }
              }
          } catch (InterruptedException x) {
              // swallow the exception
          }
  
          // Enabled "live resizing" by default.  It remains controlled
          // by the native system though.
          setDynamicLayout(true);
  
          areExtraMouseButtonsEnabled = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons", "true"));
          //set system property if not yet assigned
          System.setProperty("sun.awt.enableExtraMouseButtons", ""+areExtraMouseButtonsEnabled);
          setExtraMouseButtonsEnabledNative(areExtraMouseButtonsEnabled);
      }
  
      private void registerShutdownHook() {
          AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
              Thread shutdown = new Thread(ThreadGroupUtils.getRootThreadGroup(), this::shutdown);
              shutdown.setContextClassLoader(null);
              Runtime.getRuntime().addShutdownHook(shutdown);
              return null;
           });
       }
  
      @Override
      public void run() {
          AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
              Thread.currentThread().setContextClassLoader(null);
              return null;
          });
          Thread.currentThread().setPriority(Thread.NORM_PRIORITY + 1);
          boolean startPump = init();
  
          if (startPump) {
              registerShutdownHook();
          }
  
          synchronized(this) {
              inited = true;
              notifyAll();
          }
  
          if (startPump) {
              eventLoop(); // will Dispose Toolkit when shutdown hook executes
          }
      }
  
      /*
       * eventLoop() begins the native message pump which retrieves and processes
       * native events.
       *
       * When shutdown() is called by the ShutdownHook added in run(), a
       * WM_QUIT message is posted to the Toolkit thread indicating that
       * eventLoop() should Dispose the toolkit and exit.
       */
      private native boolean init();
      private boolean inited = false;
  
      private native void eventLoop();
      private native void shutdown();
  
      /*
       * Instead of blocking the "AWT-Windows" thread uselessly on a semaphore,
       * use these functions. startSecondaryEventLoop() corresponds to wait()
       * and quitSecondaryEventLoop() corresponds to notify.
       *
       * These functions simulate blocking while allowing the AWT to continue
       * processing native events, eliminating a potential deadlock situation
       * with SendMessage.
       *
       * WARNING: startSecondaryEventLoop must only be called from the "AWT-
       * Windows" thread.
       */
      static native void startSecondaryEventLoop();
      static native void quitSecondaryEventLoop();
  
      /*
       * Create peer objects.
       */
  
      @Override
      public ButtonPeer createButton(Button target) {
          ButtonPeer peer = new WButtonPeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      @Override
      public TextFieldPeer createTextField(TextField target) {
          TextFieldPeer peer = new WTextFieldPeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      @Override
      public LabelPeer createLabel(Label target) {
          LabelPeer peer = new WLabelPeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      @Override
      public ListPeer createList(List target) {
          ListPeer peer = new WListPeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      @Override
      public CheckboxPeer createCheckbox(Checkbox target) {
          CheckboxPeer peer = new WCheckboxPeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      @Override
      public ScrollbarPeer createScrollbar(Scrollbar target) {
          ScrollbarPeer peer = new WScrollbarPeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      @Override
      public ScrollPanePeer createScrollPane(ScrollPane target) {
          ScrollPanePeer peer = new WScrollPanePeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      @Override
      public TextAreaPeer createTextArea(TextArea target) {
          TextAreaPeer peer = new WTextAreaPeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      @Override
      public ChoicePeer createChoice(Choice target) {
          ChoicePeer peer = new WChoicePeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      @Override
      public FramePeer  createFrame(Frame target) {
          FramePeer peer = new WFramePeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      @Override
      public FramePeer createLightweightFrame(LightweightFrame target) {
          FramePeer peer = new WLightweightFramePeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      @Override
      public CanvasPeer createCanvas(Canvas target) {
          CanvasPeer peer = new WCanvasPeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      @Override
      @SuppressWarnings("deprecation")
      public void disableBackgroundErase(Canvas canvas) {
          WCanvasPeer peer = (WCanvasPeer)canvas.getPeer();
          if (peer == null) {
              throw new IllegalStateException("Canvas must have a valid peer");
          }
          peer.disableBackgroundErase();
      }
  
      @Override
      public PanelPeer createPanel(Panel target) {
          PanelPeer peer = new WPanelPeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      @Override
      public WindowPeer createWindow(Window target) {
          WindowPeer peer = new WWindowPeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      @Override
      public DialogPeer createDialog(Dialog target) {
          DialogPeer peer = new WDialogPeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      @Override
      public FileDialogPeer createFileDialog(FileDialog target) {
          FileDialogPeer peer = new WFileDialogPeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      @Override
      public MenuBarPeer createMenuBar(MenuBar target) {
          MenuBarPeer peer = new WMenuBarPeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      @Override
      public MenuPeer createMenu(Menu target) {
          MenuPeer peer = new WMenuPeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      @Override
      public PopupMenuPeer createPopupMenu(PopupMenu target) {
          PopupMenuPeer peer = new WPopupMenuPeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      @Override
      public MenuItemPeer createMenuItem(MenuItem target) {
          MenuItemPeer peer = new WMenuItemPeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      @Override
      public CheckboxMenuItemPeer createCheckboxMenuItem(CheckboxMenuItem target) {
          CheckboxMenuItemPeer peer = new WCheckboxMenuItemPeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      @Override
      public RobotPeer createRobot(Robot target, GraphicsDevice screen) {
          // (target is unused for now)
          // Robot's don't need to go in the peer map since
          // they're not Component's
          return new WRobotPeer(screen);
      }
  
      public WEmbeddedFramePeer createEmbeddedFrame(WEmbeddedFrame target) {
          WEmbeddedFramePeer peer = new WEmbeddedFramePeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      WPrintDialogPeer createWPrintDialog(WPrintDialog target) {
          WPrintDialogPeer peer = new WPrintDialogPeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      WPageDialogPeer createWPageDialog(WPageDialog target) {
          WPageDialogPeer peer = new WPageDialogPeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      @Override
      public TrayIconPeer createTrayIcon(TrayIcon target) {
          WTrayIconPeer peer = new WTrayIconPeer(target);
          targetCreatedPeer(target, peer);
          return peer;
      }
  
      @Override
      public SystemTrayPeer createSystemTray(SystemTray target) {
          return new WSystemTrayPeer(target);
      }
  
      @Override
      public boolean isTraySupported() {
          return true;
      }
  
      @Override
      public DataTransferer getDataTransferer() {
          return WDataTransferer.getInstanceImpl();
      }
  
      @Override
      public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer()
        throws HeadlessException
      {
          return WKeyboardFocusManagerPeer.getInstance();
      }
  
      private native void setDynamicLayoutNative(boolean b);
  
      @Override
      public void setDynamicLayout(boolean b) {
          if (b == dynamicLayoutSetting) {
              return;
          }
  
          dynamicLayoutSetting = b;
          setDynamicLayoutNative(b);
      }
  
      @Override
      protected boolean isDynamicLayoutSet() {
          return dynamicLayoutSetting;
      }
  
      /*
       * Called from lazilyLoadDynamicLayoutSupportedProperty because
       * Windows doesn't always send WM_SETTINGCHANGE when it should.
       */
      private native boolean isDynamicLayoutSupportedNative();
  
      @Override
      public boolean isDynamicLayoutActive() {
          return (isDynamicLayoutSet() && isDynamicLayoutSupported());
      }
  
      /**
       * Returns <code>true</code> if this frame state is supported.
       */
      @Override
      public boolean isFrameStateSupported(int state) {
          switch (state) {
            case Frame.NORMAL:
            case Frame.ICONIFIED:
            case Frame.MAXIMIZED_BOTH:
                return true;
            default:
                return false;
          }
      }
  
      static native ColorModel makeColorModel();
      static ColorModel screenmodel;
  
      static ColorModel getStaticColorModel() {
          if (GraphicsEnvironment.isHeadless()) {
              throw new IllegalArgumentException();
          }
          if (config == null) {
              resetGC();
          }
          return config.getColorModel();
      }
  
      @Override
      public ColorModel getColorModel() {
          return getStaticColorModel();
      }
  
      @Override
      public Insets getScreenInsets(GraphicsConfiguration gc)
      {
          return getScreenInsets(((Win32GraphicsDevice) gc.getDevice()).getScreen());
      }
  
      @Override
      public int getScreenResolution() {
          Win32GraphicsEnvironment ge = (Win32GraphicsEnvironment)
              GraphicsEnvironment.getLocalGraphicsEnvironment();
          return ge.getXResolution();
      }
      @Override
      protected native int getScreenWidth();
      @Override
      protected native int getScreenHeight();
      private native Insets getScreenInsets(int screen);
  
  
      @Override
      public FontMetrics getFontMetrics(Font font) {
          // This is an unsupported hack, but left in for a customer.
          // Do not remove.
          FontManager fm = FontManagerFactory.getInstance();
          if (fm instanceof SunFontManager
              && ((SunFontManager) fm).usePlatformFontMetrics()) {
              return WFontMetrics.getFontMetrics(font);
          }
          return super.getFontMetrics(font);
      }
  
      @Override
      public FontPeer getFontPeer(String name, int style) {
          FontPeer retval = null;
          String lcName = name.toLowerCase();
          if (null != cacheFontPeer) {
              retval = cacheFontPeer.get(lcName + style);
              if (null != retval) {
                  return retval;
              }
          }
          retval = new WFontPeer(name, style);
          if (retval != null) {
              if (null == cacheFontPeer) {
                  cacheFontPeer = new Hashtable<>(5, 0.9f);
              }
              if (null != cacheFontPeer) {
                  cacheFontPeer.put(lcName + style, retval);
              }
          }
          return retval;
      }
  
      private native void nativeSync();
  
      @Override
      public void sync() {
          // flush the GDI/DD buffers
          nativeSync();
          // now flush the OGL pipeline (this is a no-op if OGL is not enabled)
          OGLRenderQueue.sync();
          // now flush the D3D pipeline (this is a no-op if D3D is not enabled)
          D3DRenderQueue.sync();
      }
  
      @Override
      public PrintJob getPrintJob(Frame frame, String doctitle,
                                  Properties props) {
          return getPrintJob(frame, doctitle, null, null);
      }
  
      @Override
      public PrintJob getPrintJob(Frame frame, String doctitle,
                                  JobAttributes jobAttributes,
                                  PageAttributes pageAttributes)
      {
          if (frame == null) {
              throw new NullPointerException("frame must not be null");
          }
  
          PrintJob2D printJob = new PrintJob2D(frame, doctitle,
                                               jobAttributes, pageAttributes);
  
          if (printJob.printDialog() == false) {
              printJob = null;
          }
  
          return printJob;
      }
  
      @Override
      public native void beep();
  
      @Override
      public boolean getLockingKeyState(int key) {
          if (! (key == KeyEvent.VK_CAPS_LOCK || key == KeyEvent.VK_NUM_LOCK ||
                 key == KeyEvent.VK_SCROLL_LOCK || key == KeyEvent.VK_KANA_LOCK)) {
              throw new IllegalArgumentException("invalid key for Toolkit.getLockingKeyState");
          }
          return getLockingKeyStateNative(key);
      }
  
      private native boolean getLockingKeyStateNative(int key);
  
      @Override
      public void setLockingKeyState(int key, boolean on) {
          if (! (key == KeyEvent.VK_CAPS_LOCK || key == KeyEvent.VK_NUM_LOCK ||
                 key == KeyEvent.VK_SCROLL_LOCK || key == KeyEvent.VK_KANA_LOCK)) {
              throw new IllegalArgumentException("invalid key for Toolkit.setLockingKeyState");
          }
          setLockingKeyStateNative(key, on);
      }
  
      private native void setLockingKeyStateNative(int key, boolean on);
  
      @Override
      public Clipboard getSystemClipboard() {
          SecurityManager security = System.getSecurityManager();
          if (security != null) {
              security.checkPermission(AWTPermissions.ACCESS_CLIPBOARD_PERMISSION);
          }
          synchronized (this) {
              if (clipboard == null) {
                  clipboard = new WClipboard();
              }
          }
          return clipboard;
      }
  
      @Override
      protected native void loadSystemColors(int[] systemColors);
  
      public static Object targetToPeer(Object target) {
          return SunToolkit.targetToPeer(target);
      }
  
      public static void targetDisposedPeer(Object target, Object peer) {
          SunToolkit.targetDisposedPeer(target, peer);
      }
  
      /**
       * Returns a new input method adapter descriptor for native input methods.
       */
      @Override
      public InputMethodDescriptor getInputMethodAdapterDescriptor() {
          return new WInputMethodDescriptor();
      }
  
      /**
       * Returns a style map for the input method highlight.
       */
      @Override
      public Map<java.awt.font.TextAttribute,?> mapInputMethodHighlight(
          InputMethodHighlight highlight)
      {
          return WInputMethod.mapInputMethodHighlight(highlight);
      }
  
      /**
       * Returns whether enableInputMethods should be set to true for peered
       * TextComponent instances on this platform.
       */
      @Override
      public boolean enableInputMethodsForTextComponent() {
          return true;
      }
  
      /**
       * Returns the default keyboard locale of the underlying operating system
       */
      @Override
      public Locale getDefaultKeyboardLocale() {
          Locale locale = WInputMethod.getNativeLocale();
  
          if (locale == null) {
              return super.getDefaultKeyboardLocale();
          } else {
              return locale;
          }
      }
  
      /**
       * Returns a new custom cursor.
       */
      @Override
      public Cursor createCustomCursor(Image cursor, Point hotSpot, String name)
          throws IndexOutOfBoundsException {
          return new WCustomCursor(cursor, hotSpot, name);
      }
  
      /**
       * Returns the supported cursor size (Win32 only has one).
       */
      @Override
      public Dimension getBestCursorSize(int preferredWidth, int preferredHeight) {
          return new Dimension(WCustomCursor.getCursorWidth(),
                               WCustomCursor.getCursorHeight());
      }
  
      @Override
      public native int getMaximumCursorColors();
  
      static void paletteChanged() {
          ((Win32GraphicsEnvironment)GraphicsEnvironment
          .getLocalGraphicsEnvironment())
          .paletteChanged();
      }
  
      /*
       * Called from Toolkit native code when a WM_DISPLAYCHANGE occurs.
       * Have Win32GraphicsEnvironment execute the display change code on the
       * Event thread.
       */
      static public void displayChanged() {
          EventQueue.invokeLater(new Runnable() {
              @Override
              public void run() {
                  ((Win32GraphicsEnvironment)GraphicsEnvironment
                  .getLocalGraphicsEnvironment())
                  .displayChanged();
              }
          });
      }
  
      /**
       * create the peer for a DragSourceContext
       */
  
      @Override
      public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException {
          final LightweightFrame f = SunToolkit.getLightweightFrame(dge.getComponent());
          if (f != null) {
              return f.createDragSourceContextPeer(dge);
          }
  
          return WDragSourceContextPeer.createDragSourceContextPeer(dge);
      }
  
      @Override
      @SuppressWarnings("unchecked")
      public <T extends DragGestureRecognizer> T
          createDragGestureRecognizer(Class<T> abstractRecognizerClass,
                                      DragSource ds, Component c, int srcActions,
                                      DragGestureListener dgl)
      {
          final LightweightFrame f = SunToolkit.getLightweightFrame(c);
          if (f != null) {
              return f.createDragGestureRecognizer(abstractRecognizerClass, ds, c, srcActions, dgl);
          }
  
          if (MouseDragGestureRecognizer.class.equals(abstractRecognizerClass))
              return (T)new WMouseDragGestureRecognizer(ds, c, srcActions, dgl);
          else
              return null;
      }
  
      /**
       *
       */
  
      private static final String prefix  = "DnD.Cursor.";
      private static final String postfix = ".32x32";
      private static final String awtPrefix  = "awt.";
      private static final String dndPrefix  = "DnD.";
  
      @Override
      protected Object lazilyLoadDesktopProperty(String name) {
          if (name.startsWith(prefix)) {
              String cursorName = name.substring(prefix.length(), name.length()) + postfix;
  
              try {
                  return Cursor.getSystemCustomCursor(cursorName);
              } catch (AWTException awte) {
                  throw new RuntimeException("cannot load system cursor: " + cursorName, awte);
              }
          }
  
          if (name.equals("awt.dynamicLayoutSupported")) {
              return  Boolean.valueOf(isDynamicLayoutSupported());
          }
  
  