PageRenderTime 52ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 1ms

/MRI-J/jdk/src/windows/classes/sun/awt/windows/WToolkit.java

http://github.com/GregBowyer/ManagedRuntimeInitiative
Java | 943 lines | 603 code | 145 blank | 195 comment | 92 complexity | 7c80dbfc6184ed703b6e44d4f7355136 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-3.0
  1. /*
  2. * Copyright 1996-2007 Sun Microsystems, Inc. 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. Sun designates this
  8. * particular file as subject to the "Classpath" exception as provided
  9. * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22. * CA 95054 USA or visit www.sun.com if you need additional information or
  23. * have any questions.
  24. */
  25. package sun.awt.windows;
  26. import java.awt.*;
  27. import java.awt.im.InputMethodHighlight;
  28. import java.awt.im.spi.InputMethodDescriptor;
  29. import java.awt.image.*;
  30. import java.awt.peer.*;
  31. import java.awt.event.KeyEvent;
  32. import java.awt.datatransfer.Clipboard;
  33. import java.awt.TrayIcon;
  34. import java.beans.PropertyChangeListener;
  35. import java.security.AccessController;
  36. import java.security.PrivilegedAction;
  37. import sun.awt.AWTAutoShutdown;
  38. import sun.awt.SunToolkit;
  39. import sun.awt.Win32GraphicsDevice;
  40. import sun.awt.Win32GraphicsEnvironment;
  41. import sun.java2d.opengl.OGLRenderQueue;
  42. import sun.print.PrintJob2D;
  43. import java.awt.dnd.DragSource;
  44. import java.awt.dnd.DragGestureListener;
  45. import java.awt.dnd.DragGestureEvent;
  46. import java.awt.dnd.DragGestureRecognizer;
  47. import java.awt.dnd.MouseDragGestureRecognizer;
  48. import java.awt.dnd.InvalidDnDOperationException;
  49. import java.awt.dnd.peer.DragSourceContextPeer;
  50. import java.util.Hashtable;
  51. import java.util.Locale;
  52. import java.util.Map;
  53. import java.util.Properties;
  54. import java.util.logging.*;
  55. import sun.misc.PerformanceLogger;
  56. public class WToolkit extends SunToolkit implements Runnable {
  57. private static final Logger log = Logger.getLogger("sun.awt.windows.WToolkit");
  58. static GraphicsConfiguration config;
  59. // System clipboard.
  60. WClipboard clipboard;
  61. // cache of font peers
  62. private Hashtable cacheFontPeer;
  63. // Windows properties
  64. private WDesktopProperties wprops;
  65. // Dynamic Layout Resize client code setting
  66. protected boolean dynamicLayoutSetting = false;
  67. /**
  68. * Initialize JNI field and method IDs
  69. */
  70. private static native void initIDs();
  71. private static boolean loaded = false;
  72. public static void loadLibraries() {
  73. if (!loaded) {
  74. java.security.AccessController.doPrivileged(
  75. new sun.security.action.LoadLibraryAction("awt"));
  76. loaded = true;
  77. }
  78. }
  79. private static native String getWindowsVersion();
  80. static {
  81. loadLibraries();
  82. // Force Win32GE to load if it is not already loaded; this loads
  83. // various other classes that are required for basic awt functionality
  84. Win32GraphicsEnvironment.init();
  85. initIDs();
  86. // Print out which version of Windows is running
  87. if (log.isLoggable(Level.FINE)) {
  88. log.log(Level.FINE, "Win version: " + getWindowsVersion());
  89. }
  90. java.security.AccessController.doPrivileged(
  91. new java.security.PrivilegedAction()
  92. {
  93. public Object run() {
  94. String browserProp = System.getProperty("browser");
  95. if (browserProp != null && browserProp.equals("sun.plugin")) {
  96. disableCustomPalette();
  97. }
  98. return null;
  99. }
  100. });
  101. }
  102. private static native void disableCustomPalette();
  103. /*
  104. * Reset the static GraphicsConfiguration to the default. Called on
  105. * startup and when display settings have changed.
  106. */
  107. public static void resetGC() {
  108. if (GraphicsEnvironment.isHeadless()) {
  109. config = null;
  110. } else {
  111. config = (GraphicsEnvironment
  112. .getLocalGraphicsEnvironment()
  113. .getDefaultScreenDevice()
  114. .getDefaultConfiguration());
  115. }
  116. }
  117. /*
  118. * NOTE: The following embedded*() methods are non-public API intended
  119. * for internal use only. The methods are unsupported and could go
  120. * away in future releases.
  121. *
  122. * New hook functions for using the AWT as an embedded service. These
  123. * functions replace the global C function AwtInit() which was previously
  124. * exported by awt.dll.
  125. *
  126. * When used as an embedded service, the AWT does NOT have its own
  127. * message pump. It instead relies on the parent application to provide
  128. * this functionality. embeddedInit() assumes that the thread on which it
  129. * is called is the message pumping thread. Violating this assumption
  130. * will lead to undefined behavior.
  131. *
  132. * embeddedInit must be called before the WToolkit() constructor.
  133. * embeddedDispose should be called before the applicaton terminates the
  134. * Java VM. It is currently unsafe to reinitialize the toolkit again
  135. * after it has been disposed. Instead, awt.dll must be reloaded and the
  136. * class loader which loaded WToolkit must be finalized before it is
  137. * safe to reuse AWT. Dynamic reusability may be added to the toolkit in
  138. * the future.
  139. */
  140. /**
  141. * Initializes the Toolkit for use in an embedded environment.
  142. *
  143. * @return true if the the initialization succeeded; false if it failed.
  144. * The function will fail if the Toolkit was already initialized.
  145. * @since 1.3
  146. */
  147. public static native boolean embeddedInit();
  148. /**
  149. * Disposes the Toolkit in an embedded environment. This method should
  150. * not be called on exit unless the Toolkit was constructed with
  151. * embeddedInit.
  152. *
  153. * @return true if the disposal succeeded; false if it failed. The
  154. * function will fail if the calling thread is not the same
  155. * thread which called embeddedInit(), or if the Toolkit was
  156. * already disposed.
  157. * @since 1.3
  158. */
  159. public static native boolean embeddedDispose();
  160. /**
  161. * To be called after processing the event queue by users of the above
  162. * embeddedInit() function. The reason for this additional call is that
  163. * there are some operations performed during idle time in the AwtToolkit
  164. * event loop which should also be performed during idle time in any
  165. * other native event loop. Failure to do so could result in
  166. * deadlocks.
  167. *
  168. * This method was added at the last minute of the jdk1.4 release
  169. * to work around a specific customer problem. As with the above
  170. * embedded*() class, this method is non-public and should not be
  171. * used by external applications.
  172. *
  173. * See bug #4526587 for more information.
  174. */
  175. public native void embeddedEventLoopIdleProcessing();
  176. public static final String DATA_TRANSFERER_CLASS_NAME = "sun.awt.windows.WDataTransferer";
  177. static class ToolkitDisposer implements sun.java2d.DisposerRecord {
  178. public void dispose() {
  179. WToolkit.postDispose();
  180. }
  181. }
  182. private final Object anchor = new Object();
  183. private static native void postDispose();
  184. public WToolkit() {
  185. // Startup toolkit threads
  186. if (PerformanceLogger.loggingEnabled()) {
  187. PerformanceLogger.setTime("WToolkit construction");
  188. }
  189. sun.java2d.Disposer.addRecord(anchor, new ToolkitDisposer());
  190. synchronized (this) {
  191. // Fix for bug #4046430 -- Race condition
  192. // where notifyAll can be called before
  193. // the "AWT-Windows" thread's parent thread is
  194. // waiting, resulting in a deadlock on startup.
  195. Thread toolkitThread = new Thread(this, "AWT-Windows");
  196. toolkitThread.setDaemon(true);
  197. toolkitThread.setPriority(Thread.NORM_PRIORITY+1);
  198. /*
  199. * Fix for 4701990.
  200. * AWTAutoShutdown state must be changed before the toolkit thread
  201. * starts to avoid race condition.
  202. */
  203. AWTAutoShutdown.notifyToolkitThreadBusy();
  204. toolkitThread.start();
  205. try {
  206. wait();
  207. }
  208. catch (InterruptedException x) {
  209. }
  210. }
  211. SunToolkit.setDataTransfererClassName(DATA_TRANSFERER_CLASS_NAME);
  212. // Enabled "live resizing" by default. It remains controlled
  213. // by the native system though.
  214. setDynamicLayout(true);
  215. }
  216. public void run() {
  217. boolean startPump = init();
  218. if (startPump) {
  219. ThreadGroup mainTG = (ThreadGroup)AccessController.doPrivileged(
  220. new PrivilegedAction() {
  221. public Object run() {
  222. ThreadGroup currentTG =
  223. Thread.currentThread().getThreadGroup();
  224. ThreadGroup parentTG = currentTG.getParent();
  225. while (parentTG != null) {
  226. currentTG = parentTG;
  227. parentTG = currentTG.getParent();
  228. }
  229. return currentTG;
  230. }
  231. });
  232. Runtime.getRuntime().addShutdownHook(
  233. new Thread(mainTG, new Runnable() {
  234. public void run() {
  235. shutdown();
  236. }
  237. })
  238. );
  239. }
  240. synchronized(this) {
  241. notifyAll();
  242. }
  243. if (startPump) {
  244. eventLoop(); // will Dispose Toolkit when shutdown hook executes
  245. }
  246. }
  247. /*
  248. * eventLoop() begins the native message pump which retrieves and processes
  249. * native events.
  250. *
  251. * When shutdown() is called by the ShutdownHook added in run(), a
  252. * WM_QUIT message is posted to the Toolkit thread indicating that
  253. * eventLoop() should Dispose the toolkit and exit.
  254. */
  255. private native boolean init();
  256. private native void eventLoop();
  257. private native void shutdown();
  258. /*
  259. * Instead of blocking the "AWT-Windows" thread uselessly on a semaphore,
  260. * use these functions. startSecondaryEventLoop() corresponds to wait()
  261. * and quitSecondaryEventLoop() corresponds to notify.
  262. *
  263. * These functions simulate blocking while allowing the AWT to continue
  264. * processing native events, eliminating a potential deadlock situation
  265. * with SendMessage.
  266. *
  267. * WARNING: startSecondaryEventLoop must only be called from the "AWT-
  268. * Windows" thread.
  269. */
  270. public static native void startSecondaryEventLoop();
  271. public static native void quitSecondaryEventLoop();
  272. /*
  273. * Create peer objects.
  274. */
  275. public ButtonPeer createButton(Button target) {
  276. ButtonPeer peer = new WButtonPeer(target);
  277. targetCreatedPeer(target, peer);
  278. return peer;
  279. }
  280. public TextFieldPeer createTextField(TextField target) {
  281. TextFieldPeer peer = new WTextFieldPeer(target);
  282. targetCreatedPeer(target, peer);
  283. return peer;
  284. }
  285. public LabelPeer createLabel(Label target) {
  286. LabelPeer peer = new WLabelPeer(target);
  287. targetCreatedPeer(target, peer);
  288. return peer;
  289. }
  290. public ListPeer createList(List target) {
  291. ListPeer peer = new WListPeer(target);
  292. targetCreatedPeer(target, peer);
  293. return peer;
  294. }
  295. public CheckboxPeer createCheckbox(Checkbox target) {
  296. CheckboxPeer peer = new WCheckboxPeer(target);
  297. targetCreatedPeer(target, peer);
  298. return peer;
  299. }
  300. public ScrollbarPeer createScrollbar(Scrollbar target) {
  301. ScrollbarPeer peer = new WScrollbarPeer(target);
  302. targetCreatedPeer(target, peer);
  303. return peer;
  304. }
  305. public ScrollPanePeer createScrollPane(ScrollPane target) {
  306. ScrollPanePeer peer = new WScrollPanePeer(target);
  307. targetCreatedPeer(target, peer);
  308. return peer;
  309. }
  310. public TextAreaPeer createTextArea(TextArea target) {
  311. TextAreaPeer peer = new WTextAreaPeer(target);
  312. targetCreatedPeer(target, peer);
  313. return peer;
  314. }
  315. public ChoicePeer createChoice(Choice target) {
  316. ChoicePeer peer = new WChoicePeer(target);
  317. targetCreatedPeer(target, peer);
  318. return peer;
  319. }
  320. public FramePeer createFrame(Frame target) {
  321. FramePeer peer = new WFramePeer(target);
  322. targetCreatedPeer(target, peer);
  323. return peer;
  324. }
  325. public CanvasPeer createCanvas(Canvas target) {
  326. CanvasPeer peer = new WCanvasPeer(target);
  327. targetCreatedPeer(target, peer);
  328. return peer;
  329. }
  330. public void disableBackgroundErase(Canvas canvas) {
  331. WCanvasPeer peer = (WCanvasPeer)canvas.getPeer();
  332. if (peer == null) {
  333. throw new IllegalStateException("Canvas must have a valid peer");
  334. }
  335. peer.disableBackgroundErase();
  336. }
  337. public PanelPeer createPanel(Panel target) {
  338. PanelPeer peer = new WPanelPeer(target);
  339. targetCreatedPeer(target, peer);
  340. return peer;
  341. }
  342. public WindowPeer createWindow(Window target) {
  343. WindowPeer peer = new WWindowPeer(target);
  344. targetCreatedPeer(target, peer);
  345. return peer;
  346. }
  347. public DialogPeer createDialog(Dialog target) {
  348. DialogPeer peer = new WDialogPeer(target);
  349. targetCreatedPeer(target, peer);
  350. return peer;
  351. }
  352. public FileDialogPeer createFileDialog(FileDialog target) {
  353. FileDialogPeer peer = new WFileDialogPeer(target);
  354. targetCreatedPeer(target, peer);
  355. return peer;
  356. }
  357. public MenuBarPeer createMenuBar(MenuBar target) {
  358. MenuBarPeer peer = new WMenuBarPeer(target);
  359. targetCreatedPeer(target, peer);
  360. return peer;
  361. }
  362. public MenuPeer createMenu(Menu target) {
  363. MenuPeer peer = new WMenuPeer(target);
  364. targetCreatedPeer(target, peer);
  365. return peer;
  366. }
  367. public PopupMenuPeer createPopupMenu(PopupMenu target) {
  368. PopupMenuPeer peer = new WPopupMenuPeer(target);
  369. targetCreatedPeer(target, peer);
  370. return peer;
  371. }
  372. public MenuItemPeer createMenuItem(MenuItem target) {
  373. MenuItemPeer peer = new WMenuItemPeer(target);
  374. targetCreatedPeer(target, peer);
  375. return peer;
  376. }
  377. public CheckboxMenuItemPeer createCheckboxMenuItem(CheckboxMenuItem target) {
  378. CheckboxMenuItemPeer peer = new WCheckboxMenuItemPeer(target);
  379. targetCreatedPeer(target, peer);
  380. return peer;
  381. }
  382. public RobotPeer createRobot(Robot target, GraphicsDevice screen) {
  383. // (target is unused for now)
  384. // Robot's don't need to go in the peer map since
  385. // they're not Component's
  386. return new WRobotPeer(screen);
  387. }
  388. public WEmbeddedFramePeer createEmbeddedFrame(WEmbeddedFrame target) {
  389. WEmbeddedFramePeer peer = new WEmbeddedFramePeer(target);
  390. targetCreatedPeer(target, peer);
  391. return peer;
  392. }
  393. WPrintDialogPeer createWPrintDialog(WPrintDialog target) {
  394. WPrintDialogPeer peer = new WPrintDialogPeer(target);
  395. targetCreatedPeer(target, peer);
  396. return peer;
  397. }
  398. WPageDialogPeer createWPageDialog(WPageDialog target) {
  399. WPageDialogPeer peer = new WPageDialogPeer(target);
  400. targetCreatedPeer(target, peer);
  401. return peer;
  402. }
  403. public TrayIconPeer createTrayIcon(TrayIcon target) {
  404. WTrayIconPeer peer = new WTrayIconPeer(target);
  405. targetCreatedPeer(target, peer);
  406. return peer;
  407. }
  408. public SystemTrayPeer createSystemTray(SystemTray target) {
  409. return new WSystemTrayPeer(target);
  410. }
  411. public boolean isTraySupported() {
  412. // workaround for 6419042
  413. if (isProtectedMode()) {
  414. return false;
  415. }
  416. return true;
  417. }
  418. protected native void setDynamicLayoutNative(boolean b);
  419. public void setDynamicLayout(boolean b) {
  420. if (b == dynamicLayoutSetting) {
  421. return;
  422. }
  423. dynamicLayoutSetting = b;
  424. setDynamicLayoutNative(b);
  425. }
  426. protected boolean isDynamicLayoutSet() {
  427. return dynamicLayoutSetting;
  428. }
  429. /*
  430. * Called from lazilyLoadDynamicLayoutSupportedProperty because
  431. * Windows doesn't always send WM_SETTINGCHANGE when it should.
  432. */
  433. protected native boolean isDynamicLayoutSupportedNative();
  434. public boolean isDynamicLayoutActive() {
  435. return (isDynamicLayoutSet() && isDynamicLayoutSupported());
  436. }
  437. /**
  438. * Returns <code>true</code> if this frame state is supported.
  439. */
  440. public boolean isFrameStateSupported(int state) {
  441. switch (state) {
  442. case Frame.NORMAL:
  443. case Frame.ICONIFIED:
  444. case Frame.MAXIMIZED_BOTH:
  445. return true;
  446. default:
  447. return false;
  448. }
  449. }
  450. static native ColorModel makeColorModel();
  451. static ColorModel screenmodel;
  452. static ColorModel getStaticColorModel() {
  453. if (GraphicsEnvironment.isHeadless()) {
  454. throw new IllegalArgumentException();
  455. }
  456. if (config == null) {
  457. resetGC();
  458. }
  459. return config.getColorModel();
  460. }
  461. public ColorModel getColorModel() {
  462. return getStaticColorModel();
  463. }
  464. public Insets getScreenInsets(GraphicsConfiguration gc)
  465. {
  466. return getScreenInsets(((Win32GraphicsDevice) gc.getDevice()).getScreen());
  467. }
  468. public int getScreenResolution() {
  469. Win32GraphicsEnvironment ge = (Win32GraphicsEnvironment)
  470. GraphicsEnvironment.getLocalGraphicsEnvironment();
  471. return ge.getXResolution();
  472. }
  473. protected native int getScreenWidth();
  474. protected native int getScreenHeight();
  475. protected native Insets getScreenInsets(int screen);
  476. public FontMetrics getFontMetrics(Font font) {
  477. // REMIND: platform font flag should be removed post-merlin.
  478. if (sun.font.FontManager.usePlatformFontMetrics()) {
  479. return WFontMetrics.getFontMetrics(font);
  480. }
  481. return super.getFontMetrics(font);
  482. }
  483. public FontPeer getFontPeer(String name, int style) {
  484. FontPeer retval = null;
  485. String lcName = name.toLowerCase();
  486. if (null != cacheFontPeer) {
  487. retval = (FontPeer)cacheFontPeer.get(lcName + style);
  488. if (null != retval) {
  489. return retval;
  490. }
  491. }
  492. retval = new WFontPeer(name, style);
  493. if (retval != null) {
  494. if (null == cacheFontPeer) {
  495. cacheFontPeer = new Hashtable(5, (float)0.9);
  496. }
  497. if (null != cacheFontPeer) {
  498. cacheFontPeer.put(lcName + style, retval);
  499. }
  500. }
  501. return retval;
  502. }
  503. private native void nativeSync();
  504. public void sync() {
  505. // flush the GDI/DD buffers
  506. nativeSync();
  507. // now flush the OGL pipeline (this is a no-op if OGL is not enabled)
  508. OGLRenderQueue.sync();
  509. }
  510. public PrintJob getPrintJob(Frame frame, String doctitle,
  511. Properties props) {
  512. return getPrintJob(frame, doctitle, null, null);
  513. }
  514. public PrintJob getPrintJob(Frame frame, String doctitle,
  515. JobAttributes jobAttributes,
  516. PageAttributes pageAttributes) {
  517. if (GraphicsEnvironment.isHeadless()) {
  518. throw new IllegalArgumentException();
  519. }
  520. PrintJob2D printJob = new PrintJob2D(frame, doctitle,
  521. jobAttributes, pageAttributes);
  522. if (printJob.printDialog() == false) {
  523. printJob = null;
  524. }
  525. return printJob;
  526. }
  527. public native void beep();
  528. public boolean getLockingKeyState(int key) {
  529. if (! (key == KeyEvent.VK_CAPS_LOCK || key == KeyEvent.VK_NUM_LOCK ||
  530. key == KeyEvent.VK_SCROLL_LOCK || key == KeyEvent.VK_KANA_LOCK)) {
  531. throw new IllegalArgumentException("invalid key for Toolkit.getLockingKeyState");
  532. }
  533. return getLockingKeyStateNative(key);
  534. }
  535. public native boolean getLockingKeyStateNative(int key);
  536. public void setLockingKeyState(int key, boolean on) {
  537. if (! (key == KeyEvent.VK_CAPS_LOCK || key == KeyEvent.VK_NUM_LOCK ||
  538. key == KeyEvent.VK_SCROLL_LOCK || key == KeyEvent.VK_KANA_LOCK)) {
  539. throw new IllegalArgumentException("invalid key for Toolkit.setLockingKeyState");
  540. }
  541. setLockingKeyStateNative(key, on);
  542. }
  543. public native void setLockingKeyStateNative(int key, boolean on);
  544. public Clipboard getSystemClipboard() {
  545. SecurityManager security = System.getSecurityManager();
  546. if (security != null) {
  547. security.checkSystemClipboardAccess();
  548. }
  549. synchronized (this) {
  550. if (clipboard == null) {
  551. clipboard = new WClipboard();
  552. }
  553. }
  554. return clipboard;
  555. }
  556. protected native void loadSystemColors(int[] systemColors);
  557. public static final Object targetToPeer(Object target) {
  558. return SunToolkit.targetToPeer(target);
  559. }
  560. public static final void targetDisposedPeer(Object target, Object peer) {
  561. SunToolkit.targetDisposedPeer(target, peer);
  562. }
  563. /**
  564. * Returns a new input method adapter descriptor for native input methods.
  565. */
  566. public InputMethodDescriptor getInputMethodAdapterDescriptor() {
  567. return new WInputMethodDescriptor();
  568. }
  569. /**
  570. * Returns a style map for the input method highlight.
  571. */
  572. public Map mapInputMethodHighlight(InputMethodHighlight highlight) {
  573. return WInputMethod.mapInputMethodHighlight(highlight);
  574. }
  575. /**
  576. * Returns whether enableInputMethods should be set to true for peered
  577. * TextComponent instances on this platform.
  578. */
  579. public boolean enableInputMethodsForTextComponent() {
  580. return true;
  581. }
  582. /**
  583. * Returns the default keyboard locale of the underlying operating system
  584. */
  585. public Locale getDefaultKeyboardLocale() {
  586. Locale locale = WInputMethod.getNativeLocale();
  587. if (locale == null) {
  588. return super.getDefaultKeyboardLocale();
  589. } else {
  590. return locale;
  591. }
  592. }
  593. /**
  594. * Returns a new custom cursor.
  595. */
  596. public Cursor createCustomCursor(Image cursor, Point hotSpot, String name)
  597. throws IndexOutOfBoundsException {
  598. return new WCustomCursor(cursor, hotSpot, name);
  599. }
  600. /**
  601. * Returns the supported cursor size (Win32 only has one).
  602. */
  603. public Dimension getBestCursorSize(int preferredWidth, int preferredHeight) {
  604. return new Dimension(WCustomCursor.getCursorWidth(),
  605. WCustomCursor.getCursorHeight());
  606. }
  607. public native int getMaximumCursorColors();
  608. static void paletteChanged() {
  609. ((Win32GraphicsEnvironment)GraphicsEnvironment
  610. .getLocalGraphicsEnvironment())
  611. .paletteChanged();
  612. }
  613. /*
  614. * Called from Toolkit native code when a WM_DISPLAYCHANGE occurs.
  615. * Have Win32GraphicsEnvironment execute the display change code on the
  616. * Event thread.
  617. */
  618. static public void displayChanged() {
  619. EventQueue.invokeLater(new Runnable() {
  620. public void run() {
  621. ((Win32GraphicsEnvironment)GraphicsEnvironment
  622. .getLocalGraphicsEnvironment())
  623. .displayChanged();
  624. }
  625. });
  626. }
  627. /**
  628. * create the peer for a DragSourceContext
  629. */
  630. public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException {
  631. return WDragSourceContextPeer.createDragSourceContextPeer(dge);
  632. }
  633. public <T extends DragGestureRecognizer> T
  634. createDragGestureRecognizer(Class<T> abstractRecognizerClass,
  635. DragSource ds, Component c, int srcActions,
  636. DragGestureListener dgl)
  637. {
  638. if (MouseDragGestureRecognizer.class.equals(abstractRecognizerClass))
  639. return (T)new WMouseDragGestureRecognizer(ds, c, srcActions, dgl);
  640. else
  641. return null;
  642. }
  643. /**
  644. *
  645. */
  646. private static final String prefix = "DnD.Cursor.";
  647. private static final String postfix = ".32x32";
  648. private static final String awtPrefix = "awt.";
  649. private static final String dndPrefix = "DnD.";
  650. protected Object lazilyLoadDesktopProperty(String name) {
  651. if (name.startsWith(prefix)) {
  652. String cursorName = name.substring(prefix.length(), name.length()) + postfix;
  653. try {
  654. return Cursor.getSystemCustomCursor(cursorName);
  655. } catch (AWTException awte) {
  656. throw new RuntimeException("cannot load system cursor: " + cursorName, awte);
  657. }
  658. }
  659. if (name.equals("awt.dynamicLayoutSupported")) {
  660. return Boolean.valueOf(isDynamicLayoutSupported());
  661. }
  662. if (WDesktopProperties.isWindowsProperty(name) ||
  663. name.startsWith(awtPrefix) || name.startsWith(dndPrefix))
  664. {
  665. synchronized(this) {
  666. lazilyInitWProps();
  667. return desktopProperties.get(name);
  668. }
  669. }
  670. return super.lazilyLoadDesktopProperty(name);
  671. }
  672. private synchronized void lazilyInitWProps() {
  673. if (wprops == null) {
  674. wprops = new WDesktopProperties(this);
  675. updateProperties();
  676. }
  677. }
  678. /*
  679. * Called from lazilyLoadDesktopProperty because Windows doesn't
  680. * always send WM_SETTINGCHANGE when it should.
  681. */
  682. private synchronized boolean isDynamicLayoutSupported() {
  683. boolean nativeDynamic = isDynamicLayoutSupportedNative();
  684. lazilyInitWProps();
  685. Boolean prop = (Boolean) desktopProperties.get("awt.dynamicLayoutSupported");
  686. if (log.isLoggable(Level.FINER)) {
  687. log.log(Level.FINER, "In WTK.isDynamicLayoutSupported()" +
  688. " nativeDynamic == " + nativeDynamic +
  689. " wprops.dynamic == " + prop);
  690. }
  691. if ((prop == null) || (nativeDynamic != prop.booleanValue())) {
  692. // We missed the WM_SETTINGCHANGE, so we pretend
  693. // we just got one - fire the propertyChange, etc.
  694. windowsSettingChange();
  695. return nativeDynamic;
  696. }
  697. return prop.booleanValue();
  698. }
  699. /*
  700. * Called from native toolkit code when WM_SETTINGCHANGE message received
  701. * Also called from lazilyLoadDynamicLayoutSupportedProperty because
  702. * Windows doesn't always send WM_SETTINGCHANGE when it should.
  703. */
  704. private void windowsSettingChange() {
  705. EventQueue.invokeLater(new Runnable() {
  706. public void run() {
  707. updateProperties();
  708. }
  709. });
  710. }
  711. private synchronized void updateProperties() {
  712. if (null == wprops) {
  713. // wprops has not been initialized, so we have nothing to update
  714. return;
  715. }
  716. Map<String, Object> props = wprops.getProperties();
  717. for (String propName : props.keySet()) {
  718. Object val = props.get(propName);
  719. if (log.isLoggable(Level.FINER)) {
  720. log.log(Level.FINER, "changed " + propName + " to " + val);
  721. }
  722. setDesktopProperty(propName, val);
  723. }
  724. }
  725. public synchronized void addPropertyChangeListener(String name, PropertyChangeListener pcl) {
  726. if ( WDesktopProperties.isWindowsProperty(name)
  727. || name.startsWith(awtPrefix)
  728. || name.startsWith(dndPrefix))
  729. {
  730. // someone is interested in Windows-specific desktop properties
  731. // we should initialize wprops
  732. lazilyInitWProps();
  733. }
  734. super.addPropertyChangeListener(name, pcl);
  735. }
  736. /*
  737. * initialize only static props here and do not try to initialize props which depends on wprops,
  738. * this should be done in lazilyLoadDesktopProperty() only.
  739. */
  740. protected synchronized void initializeDesktopProperties() {
  741. desktopProperties.put("DnD.Autoscroll.initialDelay", Integer.valueOf(50));
  742. desktopProperties.put("DnD.Autoscroll.interval", Integer.valueOf(50));
  743. try {
  744. desktopProperties.put("Shell.shellFolderManager",
  745. Class.forName("sun.awt.shell.Win32ShellFolderManager2"));
  746. } catch (ClassNotFoundException ex) {
  747. }
  748. }
  749. /*
  750. * This returns the value for the desktop property "awt.font.desktophints"
  751. * This requires that the Windows properties have already been gathered.
  752. */
  753. protected synchronized RenderingHints getDesktopAAHints() {
  754. if (wprops == null) {
  755. return null;
  756. } else {
  757. return wprops.getDesktopAAHints();
  758. }
  759. }
  760. public boolean isModalityTypeSupported(Dialog.ModalityType modalityType) {
  761. return (modalityType == null) ||
  762. (modalityType == Dialog.ModalityType.MODELESS) ||
  763. (modalityType == Dialog.ModalityType.DOCUMENT_MODAL) ||
  764. (modalityType == Dialog.ModalityType.APPLICATION_MODAL) ||
  765. (modalityType == Dialog.ModalityType.TOOLKIT_MODAL);
  766. }
  767. public boolean isModalExclusionTypeSupported(Dialog.ModalExclusionType exclusionType) {
  768. return (exclusionType == null) ||
  769. (exclusionType == Dialog.ModalExclusionType.NO_EXCLUDE) ||
  770. (exclusionType == Dialog.ModalExclusionType.APPLICATION_EXCLUDE) ||
  771. (exclusionType == Dialog.ModalExclusionType.TOOLKIT_EXCLUDE);
  772. }
  773. public static WToolkit getWToolkit() {
  774. WToolkit toolkit = (WToolkit)Toolkit.getDefaultToolkit();
  775. return toolkit;
  776. }
  777. public boolean useBufferPerWindow() {
  778. return true;
  779. }
  780. public void grab(Window w) {
  781. if (w.getPeer() != null) {
  782. ((WWindowPeer)w.getPeer()).grab();
  783. }
  784. }
  785. public void ungrab(Window w) {
  786. if (w.getPeer() != null) {
  787. ((WWindowPeer)w.getPeer()).ungrab();
  788. }
  789. }
  790. public native boolean syncNativeQueue(final long timeout);
  791. public boolean isDesktopSupported() {
  792. return true;
  793. }
  794. public DesktopPeer createDesktopPeer(Desktop target) {
  795. return new WDesktopPeer();
  796. }
  797. private static native boolean isProtectedMode();
  798. }