PageRenderTime 67ms CodeModel.GetById 35ms RepoModel.GetById 1ms app.codeStats 0ms

/src/windows/classes/sun/awt/windows/WToolkit.java

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