1 /* 2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.lwawt.macosx; 27 28 import java.awt.*; 29 import java.awt.datatransfer.Clipboard; 30 import java.awt.dnd.*; 31 import java.awt.dnd.peer.DragSourceContextPeer; 32 import java.awt.event.InputEvent; 33 import java.awt.event.InvocationEvent; 34 import java.awt.event.KeyEvent; 35 import java.awt.im.InputMethodHighlight; 36 import java.awt.peer.*; 37 import java.lang.reflect.*; 38 import java.security.*; 39 import java.util.*; 40 import java.util.concurrent.Callable; 41 42 import sun.awt.*; 43 import sun.lwawt.*; 44 import sun.lwawt.LWWindowPeer.PeerType; 45 import sun.security.action.GetBooleanAction; 46 47 import sun.util.CoreResourceBundleControl; 48 49 50 class NamedCursor extends Cursor { 51 NamedCursor(String name) { 52 super(name); 53 } 54 } 55 56 /** 57 * Mac OS X Cocoa-based AWT Toolkit. 58 */ 59 public final class LWCToolkit extends LWToolkit { 60 // While it is possible to enumerate all mouse devices 61 // and query them for the number of buttons, the code 62 // that does it is rather complex. Instead, we opt for 63 // the easy way and just support up to 5 mouse buttons, 64 // like Windows. 65 private static final int BUTTONS = 5; 66 67 private static native void initIDs(); 68 69 private static CInputMethodDescriptor sInputMethodDescriptor; 70 71 static { 72 System.err.flush(); 73 ResourceBundle platformResources = java.security.AccessController.doPrivileged( 74 new java.security.PrivilegedAction<ResourceBundle>() { 75 public ResourceBundle run() { 76 ResourceBundle platformResources = null; 77 try { 78 platformResources = 79 ResourceBundle.getBundle("sun.awt.resources.awtosx", 80 CoreResourceBundleControl.getRBControlInstance()); 81 } catch (MissingResourceException e) { 82 // No resource file; defaults will be used. 83 } 84 85 System.loadLibrary("awt"); 86 System.loadLibrary("fontmanager"); 87 return platformResources; 88 } 89 }); 90 91 AWTAccessor.getToolkitAccessor().setPlatformResources(platformResources); 92 93 if (!GraphicsEnvironment.isHeadless()) { 94 initIDs(); 95 } 96 } 97 98 public LWCToolkit() { 99 SunToolkit.setDataTransfererClassName("sun.lwawt.macosx.CDataTransferer"); 100 101 areExtraMouseButtonsEnabled = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons", "true")); 102 //set system property if not yet assigned 103 System.setProperty("sun.awt.enableExtraMouseButtons", ""+areExtraMouseButtonsEnabled); 104 } 105 106 /* 107 * System colors with default initial values, overwritten by toolkit if system values differ and are available. 108 */ 109 private final static int NUM_APPLE_COLORS = 3; 110 public final static int KEYBOARD_FOCUS_COLOR = 0; 111 public final static int INACTIVE_SELECTION_BACKGROUND_COLOR = 1; 112 public final static int INACTIVE_SELECTION_FOREGROUND_COLOR = 2; 113 private static int[] appleColors = { 114 0xFF808080, // keyboardFocusColor = Color.gray; 115 0xFFC0C0C0, // secondarySelectedControlColor 116 0xFF303030, // controlDarkShadowColor 117 }; 118 119 private native void loadNativeColors(final int[] systemColors, final int[] appleColors); 120 121 protected void loadSystemColors(final int[] systemColors) { 122 if (systemColors == null) return; 123 loadNativeColors(systemColors, appleColors); 124 } 125 126 private static class AppleSpecificColor extends Color { 127 int index; 128 public AppleSpecificColor(int index) { 129 super(appleColors[index]); 130 this.index = index; 131 } 132 133 public int getRGB() { 134 return appleColors[index]; 135 } 136 } 137 138 /** 139 * Returns Apple specific colors that we may expose going forward. 140 * 141 */ 142 public static Color getAppleColor(int color) { 143 return new AppleSpecificColor(color); 144 } 145 146 static void systemColorsChanged() { 147 // This is only called from native code. 148 EventQueue.invokeLater(new Runnable() { 149 public void run() { 150 AccessController.doPrivileged (new PrivilegedAction<Object>() { 151 public Object run() { 152 try { 153 final Method updateColorsMethod = SystemColor.class.getDeclaredMethod("updateSystemColors", new Class[0]); 154 updateColorsMethod.setAccessible(true); 155 updateColorsMethod.invoke(null, new Object[0]); 156 } catch (final Throwable e) { 157 e.printStackTrace(); 158 // swallow this if something goes horribly wrong 159 } 160 return null; 161 } 162 }); 163 } 164 }); 165 } 166 167 public static LWCToolkit getLWCToolkit() { 168 return (LWCToolkit)Toolkit.getDefaultToolkit(); 169 } 170 171 @Override 172 protected PlatformWindow createPlatformWindow(PeerType peerType) { 173 if (peerType == PeerType.EMBEDDED_FRAME) { 174 return new CPlatformEmbeddedFrame(); 175 } else if (peerType == PeerType.VIEW_EMBEDDED_FRAME) { 176 return new CViewPlatformEmbeddedFrame(); 177 } else { 178 assert (peerType == PeerType.SIMPLEWINDOW || peerType == PeerType.DIALOG || peerType == PeerType.FRAME); 179 return new CPlatformWindow(); 180 } 181 } 182 183 @Override 184 protected SecurityWarningWindow createSecurityWarning(Window ownerWindow, LWWindowPeer ownerPeer) { 185 return new CWarningWindow(ownerWindow, ownerPeer); 186 } 187 188 @Override 189 protected PlatformComponent createPlatformComponent() { 190 return new CPlatformComponent(); 191 } 192 193 @Override 194 protected FileDialogPeer createFileDialogPeer(FileDialog target) { 195 return new CFileDialog(target); 196 } 197 198 @Override 199 public MenuPeer createMenu(Menu target) { 200 MenuPeer peer = new CMenu(target); 201 targetCreatedPeer(target, peer); 202 return peer; 203 } 204 205 @Override 206 public MenuBarPeer createMenuBar(MenuBar target) { 207 MenuBarPeer peer = new CMenuBar(target); 208 targetCreatedPeer(target, peer); 209 return peer; 210 } 211 212 @Override 213 public MenuItemPeer createMenuItem(MenuItem target) { 214 MenuItemPeer peer = new CMenuItem(target); 215 targetCreatedPeer(target, peer); 216 return peer; 217 } 218 219 @Override 220 public CheckboxMenuItemPeer createCheckboxMenuItem(CheckboxMenuItem target) { 221 CheckboxMenuItemPeer peer = new CCheckboxMenuItem(target); 222 targetCreatedPeer(target, peer); 223 return peer; 224 } 225 226 @Override 227 public PopupMenuPeer createPopupMenu(PopupMenu target) { 228 PopupMenuPeer peer = new CPopupMenu(target); 229 targetCreatedPeer(target, peer); 230 return peer; 231 232 } 233 234 @Override 235 public SystemTrayPeer createSystemTray(SystemTray target) { 236 SystemTrayPeer peer = new CSystemTray(); 237 return peer; 238 } 239 240 @Override 241 public TrayIconPeer createTrayIcon(TrayIcon target) { 242 TrayIconPeer peer = new CTrayIcon(target); 243 targetCreatedPeer(target, peer); 244 return peer; 245 } 246 247 @Override 248 public LWCursorManager getCursorManager() { 249 return CCursorManager.getInstance(); 250 } 251 252 @Override 253 public Cursor createCustomCursor(final Image cursor, final Point hotSpot, final String name) throws IndexOutOfBoundsException, HeadlessException { 254 return new CCustomCursor(cursor, hotSpot, name); 255 } 256 257 @Override 258 public Dimension getBestCursorSize(final int preferredWidth, final int preferredHeight) throws HeadlessException { 259 return CCustomCursor.getBestCursorSize(preferredWidth, preferredHeight); 260 } 261 262 @Override 263 protected void platformCleanup() { 264 // TODO Auto-generated method stub 265 266 } 267 268 @Override 269 protected void platformInit() { 270 // TODO Auto-generated method stub 271 272 } 273 274 @Override 275 protected void platformRunMessage() { 276 // TODO Auto-generated method stub 277 278 } 279 280 @Override 281 protected void platformShutdown() { 282 // TODO Auto-generated method stub 283 284 } 285 286 class OSXPlatformFont extends sun.awt.PlatformFont 287 { 288 public OSXPlatformFont(String name, int style) 289 { 290 super(name, style); 291 } 292 protected char getMissingGlyphCharacter() 293 { 294 // Follow up for real implementation 295 return (char)0xfff8; // see http://developer.apple.com/fonts/LastResortFont/ 296 } 297 } 298 public FontPeer getFontPeer(String name, int style) { 299 return new OSXPlatformFont(name, style); 300 } 301 302 @Override 303 protected MouseInfoPeer createMouseInfoPeerImpl() { 304 return new CMouseInfoPeer(); 305 } 306 307 @Override 308 protected int getScreenHeight() { 309 return GraphicsEnvironment.getLocalGraphicsEnvironment() 310 .getDefaultScreenDevice().getDefaultConfiguration().getBounds().height; 311 } 312 313 @Override 314 protected int getScreenWidth() { 315 return GraphicsEnvironment.getLocalGraphicsEnvironment() 316 .getDefaultScreenDevice().getDefaultConfiguration().getBounds().width; 317 } 318 319 @Override 320 protected void initializeDesktopProperties() { 321 super.initializeDesktopProperties(); 322 Map <Object, Object> fontHints = new HashMap<Object, Object>(); 323 fontHints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 324 fontHints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 325 desktopProperties.put(SunToolkit.DESKTOPFONTHINTS, fontHints); 326 desktopProperties.put("awt.mouse.numButtons", BUTTONS); 327 328 // These DnD properties must be set, otherwise Swing ends up spewing NPEs 329 // all over the place. The values came straight off of MToolkit. 330 desktopProperties.put("DnD.Autoscroll.initialDelay", new Integer(50)); 331 desktopProperties.put("DnD.Autoscroll.interval", new Integer(50)); 332 desktopProperties.put("DnD.Autoscroll.cursorHysteresis", new Integer(5)); 333 334 desktopProperties.put("DnD.isDragImageSupported", new Boolean(true)); 335 336 // Register DnD cursors 337 desktopProperties.put("DnD.Cursor.CopyDrop", new NamedCursor("DnD.Cursor.CopyDrop")); 338 desktopProperties.put("DnD.Cursor.MoveDrop", new NamedCursor("DnD.Cursor.MoveDrop")); 339 desktopProperties.put("DnD.Cursor.LinkDrop", new NamedCursor("DnD.Cursor.LinkDrop")); 340 desktopProperties.put("DnD.Cursor.CopyNoDrop", new NamedCursor("DnD.Cursor.CopyNoDrop")); 341 desktopProperties.put("DnD.Cursor.MoveNoDrop", new NamedCursor("DnD.Cursor.MoveNoDrop")); 342 desktopProperties.put("DnD.Cursor.LinkNoDrop", new NamedCursor("DnD.Cursor.LinkNoDrop")); 343 344 } 345 346 347 /* 348 * The method returns true if some events were processed during that timeout. 349 * @see sun.awt.SunToolkit#syncNativeQueue(long) 350 */ 351 @Override 352 protected boolean syncNativeQueue(long timeout) { 353 return nativeSyncQueue(timeout); 354 } 355 356 @Override 357 public native void beep(); 358 359 @Override 360 public int getScreenResolution() throws HeadlessException { 361 return (int) ((CGraphicsDevice) GraphicsEnvironment 362 .getLocalGraphicsEnvironment().getDefaultScreenDevice()) 363 .getXResolution(); 364 } 365 366 @Override 367 public Insets getScreenInsets(final GraphicsConfiguration gc) { 368 return ((CGraphicsConfig) gc).getDevice().getScreenInsets(); 369 } 370 371 @Override 372 public void sync() { 373 // TODO Auto-generated method stub 374 375 } 376 377 @Override 378 public RobotPeer createRobot(Robot target, GraphicsDevice screen) { 379 return new CRobot(target, (CGraphicsDevice)screen); 380 } 381 382 private native boolean isCapsLockOn(); 383 384 /* 385 * NOTE: Among the keys this method is supposed to check, 386 * only Caps Lock works as a true locking key with OS X. 387 * There is no Scroll Lock key on modern Apple keyboards, 388 * and with a PC keyboard plugged in Scroll Lock is simply 389 * ignored: no LED lights up if you press it. 390 * The key located at the same position on Apple keyboards 391 * as Num Lock on PC keyboards is called Clear, doesn't lock 392 * anything and is used for entirely different purpose. 393 */ 394 public boolean getLockingKeyState(int keyCode) throws UnsupportedOperationException { 395 switch (keyCode) { 396 case KeyEvent.VK_NUM_LOCK: 397 case KeyEvent.VK_SCROLL_LOCK: 398 case KeyEvent.VK_KANA_LOCK: 399 throw new UnsupportedOperationException("Toolkit.getLockingKeyState"); 400 401 case KeyEvent.VK_CAPS_LOCK: 402 return isCapsLockOn(); 403 404 default: 405 throw new IllegalArgumentException("invalid key for Toolkit.getLockingKeyState"); 406 } 407 } 408 409 //Is it allowed to generate events assigned to extra mouse buttons. 410 //Set to true by default. 411 private static boolean areExtraMouseButtonsEnabled = true; 412 413 public boolean areExtraMouseButtonsEnabled() throws HeadlessException { 414 return areExtraMouseButtonsEnabled; 415 } 416 417 public int getNumberOfButtons(){ 418 return BUTTONS; 419 } 420 421 @Override 422 public boolean isTraySupported() { 423 return true; 424 } 425 426 @Override 427 public boolean isAlwaysOnTopSupported() { 428 return true; 429 } 430 431 // Intended to be called from the LWCToolkit.m only. 432 private static void installToolkitThreadNameInJava() { 433 Thread.currentThread().setName(CThreading.APPKIT_THREAD_NAME); 434 } 435 436 @Override 437 public boolean isWindowOpacitySupported() { 438 return true; 439 } 440 441 @Override 442 public boolean isFrameStateSupported(int state) throws HeadlessException { 443 switch (state) { 444 case Frame.NORMAL: 445 case Frame.ICONIFIED: 446 case Frame.MAXIMIZED_BOTH: 447 return true; 448 default: 449 return false; 450 } 451 } 452 453 /** 454 * Determines which modifier key is the appropriate accelerator 455 * key for menu shortcuts. 456 * <p> 457 * Menu shortcuts, which are embodied in the 458 * <code>MenuShortcut</code> class, are handled by the 459 * <code>MenuBar</code> class. 460 * <p> 461 * By default, this method returns <code>Event.CTRL_MASK</code>. 462 * Toolkit implementations should override this method if the 463 * <b>Control</b> key isn't the correct key for accelerators. 464 * @return the modifier mask on the <code>Event</code> class 465 * that is used for menu shortcuts on this toolkit. 466 * @see java.awt.MenuBar 467 * @see java.awt.MenuShortcut 468 * @since JDK1.1 469 */ 470 public int getMenuShortcutKeyMask() { 471 return Event.META_MASK; 472 } 473 474 @Override 475 public Image getImage(final String filename) { 476 final Image nsImage = checkForNSImage(filename); 477 if (nsImage != null) return nsImage; 478 479 return super.getImage(filename); 480 } 481 482 static final String nsImagePrefix = "NSImage://"; 483 protected Image checkForNSImage(final String imageName) { 484 if (imageName == null) return null; 485 if (!imageName.startsWith(nsImagePrefix)) return null; 486 return CImage.getCreator().createImageFromName(imageName.substring(nsImagePrefix.length())); 487 } 488 489 // Thread-safe Object.equals() called from native 490 public static boolean doEquals(final Object a, final Object b, Component c) { 491 if (a == b) return true; 492 493 final boolean[] ret = new boolean[1]; 494 495 try { invokeAndWait(new Runnable() { public void run() { synchronized(ret) { 496 ret[0] = a.equals(b); 497 }}}, c); } catch (Exception e) { e.printStackTrace(); } 498 499 synchronized(ret) { return ret[0]; } 500 } 501 502 public static <T> T invokeAndWait(final Callable<T> callable, Component component) throws Exception { 503 final CallableWrapper<T> wrapper = new CallableWrapper<T>(callable); 504 invokeAndWait(wrapper, component); 505 return wrapper.getResult(); 506 } 507 508 static final class CallableWrapper<T> implements Runnable { 509 final Callable<T> callable; 510 T object; 511 Exception e; 512 513 public CallableWrapper(final Callable<T> callable) { 514 this.callable = callable; 515 } 516 517 public void run() { 518 try { 519 object = callable.call(); 520 } catch (final Exception e) { 521 this.e = e; 522 } 523 } 524 525 public T getResult() throws Exception { 526 if (e != null) throw e; 527 return object; 528 } 529 } 530 531 // Kicks an event over to the appropriate eventqueue and waits for it to finish 532 // To avoid deadlocking, we manually run the NSRunLoop while waiting 533 // Any selector invoked using ThreadUtilities performOnMainThread will be processed in doAWTRunLoop 534 // The InvocationEvent will call LWCToolkit.stopAWTRunLoop() when finished, which will stop our manual runloop 535 // Does not dispatch native events while in the loop 536 public static void invokeAndWait(Runnable event, Component component) throws InterruptedException, InvocationTargetException { 537 final long mediator = createAWTRunLoopMediator(); 538 539 InvocationEvent invocationEvent = 540 new InvocationEvent(component != null ? component : Toolkit.getDefaultToolkit(), event) { 541 @Override 542 public void dispatch() { 543 try { 544 super.dispatch(); 545 } finally { 546 if (mediator != 0) { 547 stopAWTRunLoop(mediator); 548 } 549 } 550 } 551 }; 552 553 if (component != null) { 554 AppContext appContext = SunToolkit.targetToAppContext(component); 555 SunToolkit.postEvent(appContext, invocationEvent); 556 557 // 3746956 - flush events from PostEventQueue to prevent them from getting stuck and causing a deadlock 558 sun.awt.SunToolkitSubclass.flushPendingEvents(appContext); 559 } else { 560 // This should be the equivalent to EventQueue.invokeAndWait 561 ((LWCToolkit)Toolkit.getDefaultToolkit()).getSystemEventQueueForInvokeAndWait().postEvent(invocationEvent); 562 } 563 564 doAWTRunLoop(mediator, false); 565 566 Throwable eventException = invocationEvent.getException(); 567 if (eventException != null) { 568 if (eventException instanceof UndeclaredThrowableException) { 569 eventException = ((UndeclaredThrowableException)eventException).getUndeclaredThrowable(); 570 } 571 throw new InvocationTargetException(eventException); 572 } 573 } 574 575 public static void invokeLater(Runnable event, Component component) throws InvocationTargetException { 576 final InvocationEvent invocationEvent = 577 new InvocationEvent(component != null ? component : Toolkit.getDefaultToolkit(), event); 578 579 if (component != null) { 580 final AppContext appContext = SunToolkit.targetToAppContext(component); 581 SunToolkit.postEvent(appContext, invocationEvent); 582 583 // 3746956 - flush events from PostEventQueue to prevent them from getting stuck and causing a deadlock 584 sun.awt.SunToolkitSubclass.flushPendingEvents(appContext); 585 } else { 586 // This should be the equivalent to EventQueue.invokeAndWait 587 ((LWCToolkit)Toolkit.getDefaultToolkit()).getSystemEventQueueForInvokeAndWait().postEvent(invocationEvent); 588 } 589 590 final Throwable eventException = invocationEvent.getException(); 591 if (eventException == null) return; 592 593 if (eventException instanceof UndeclaredThrowableException) { 594 throw new InvocationTargetException(((UndeclaredThrowableException)eventException).getUndeclaredThrowable()); 595 } 596 throw new InvocationTargetException(eventException); 597 } 598 599 // This exists purely to get around permissions issues with getSystemEventQueueImpl 600 EventQueue getSystemEventQueueForInvokeAndWait() { 601 return getSystemEventQueueImpl(); 602 } 603 604 605 // DnD support 606 607 public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException { 608 DragSourceContextPeer dscp = CDragSourceContextPeer.createDragSourceContextPeer(dge); 609 610 return dscp; 611 } 612 613 public <T extends DragGestureRecognizer> T createDragGestureRecognizer(Class<T> abstractRecognizerClass, DragSource ds, Component c, int srcActions, DragGestureListener dgl) { 614 DragGestureRecognizer dgr = null; 615 616 // Create a new mouse drag gesture recognizer if we have a class match: 617 if (MouseDragGestureRecognizer.class.equals(abstractRecognizerClass)) 618 dgr = new CMouseDragGestureRecognizer(ds, c, srcActions, dgl); 619 620 return (T)dgr; 621 } 622 623 // InputMethodSupport Method 624 /** 625 * Returns the default keyboard locale of the underlying operating system 626 */ 627 public Locale getDefaultKeyboardLocale() { 628 Locale locale = CInputMethod.getNativeLocale(); 629 630 if (locale == null) { 631 return super.getDefaultKeyboardLocale(); 632 } 633 634 return locale; 635 } 636 637 public java.awt.im.spi.InputMethodDescriptor getInputMethodAdapterDescriptor() { 638 if (sInputMethodDescriptor == null) 639 sInputMethodDescriptor = new CInputMethodDescriptor(); 640 641 return sInputMethodDescriptor; 642 } 643 644 /** 645 * Returns a map of visual attributes for thelevel description 646 * of the given input method highlight, or null if no mapping is found. 647 * The style field of the input method highlight is ignored. The map 648 * returned is unmodifiable. 649 * @param highlight input method highlight 650 * @return style attribute map, or null 651 * @since 1.3 652 */ 653 public Map mapInputMethodHighlight(InputMethodHighlight highlight) { 654 return CInputMethod.mapInputMethodHighlight(highlight); 655 } 656 657 /** 658 * Returns key modifiers used by Swing to set up a focus accelerator key stroke. 659 */ 660 @Override 661 public int getFocusAcceleratorKeyMask() { 662 return InputEvent.CTRL_MASK | InputEvent.ALT_MASK; 663 } 664 665 /** 666 * Tests whether specified key modifiers mask can be used to enter a printable 667 * character. 668 */ 669 @Override 670 public boolean isPrintableCharacterModifiersMask(int mods) { 671 return ((mods & (InputEvent.META_MASK | InputEvent.CTRL_MASK)) == 0); 672 } 673 674 /** 675 * Returns whether popup is allowed to be shown above the task bar. 676 */ 677 @Override 678 public boolean canPopupOverlapTaskBar() { 679 return false; 680 } 681 682 private static Boolean sunAwtDisableCALayers = null; 683 684 /** 685 * Returns the value of "sun.awt.disableCALayers" property. Default 686 * value is {@code false}. 687 */ 688 public synchronized static boolean getSunAwtDisableCALayers() { 689 if (sunAwtDisableCALayers == null) { 690 sunAwtDisableCALayers = AccessController.doPrivileged( 691 new GetBooleanAction("sun.awt.disableCALayers")); 692 } 693 return sunAwtDisableCALayers.booleanValue(); 694 } 695 696 697 /* 698 * Returns true if the application (one of its windows) owns keyboard focus. 699 */ 700 public native boolean isApplicationActive(); 701 702 /************************ 703 * Native methods section 704 ************************/ 705 706 static native long createAWTRunLoopMediator(); 707 /** 708 * Method to run a nested run-loop. The nested loop is spinned in the javaRunLoop mode, so selectors sent 709 * by [JNFRunLoop performOnMainThreadWaiting] are processed. 710 * @param mediator a native pointer to the mediator object created by createAWTRunLoopMediator 711 * @param processEvents if true - dispatches event while in the nested loop. Used in DnD. 712 * Additional attention is needed when using this feature as we short-circuit normal event 713 * processing which could break Appkit. 714 * (One known example is when the window is resized with the mouse) 715 * 716 * if false - all events come after exit form the nested loop 717 */ 718 static native void doAWTRunLoop(long mediator, boolean processEvents); 719 static native void stopAWTRunLoop(long mediator); 720 721 private native boolean nativeSyncQueue(long timeout); 722 723 @Override 724 public Clipboard createPlatformClipboard() { 725 return new CClipboard("System"); 726 } 727 728 @Override 729 public boolean isModalExclusionTypeSupported(Dialog.ModalExclusionType exclusionType) { 730 return (exclusionType == null) || 731 (exclusionType == Dialog.ModalExclusionType.NO_EXCLUDE) || 732 (exclusionType == Dialog.ModalExclusionType.APPLICATION_EXCLUDE) || 733 (exclusionType == Dialog.ModalExclusionType.TOOLKIT_EXCLUDE); 734 } 735 736 @Override 737 public boolean isModalityTypeSupported(Dialog.ModalityType modalityType) { 738 //TODO: FileDialog blocks excluded windows... 739 //TODO: Test: 2 file dialogs, separate AppContexts: a) Dialog 1 blocked, shouldn't be. Frame 4 blocked (shouldn't be). 740 return (modalityType == null) || 741 (modalityType == Dialog.ModalityType.MODELESS) || 742 (modalityType == Dialog.ModalityType.DOCUMENT_MODAL) || 743 (modalityType == Dialog.ModalityType.APPLICATION_MODAL) || 744 (modalityType == Dialog.ModalityType.TOOLKIT_MODAL); 745 } 746 747 @Override 748 public boolean isWindowShapingSupported() { 749 return true; 750 } 751 752 @Override 753 public boolean isWindowTranslucencySupported() { 754 return true; 755 } 756 757 @Override 758 public boolean isTranslucencyCapable(GraphicsConfiguration gc) { 759 return true; 760 } 761 762 public boolean isSwingBackbufferTranslucencySupported() { 763 return true; 764 } 765 766 @Override 767 public boolean enableInputMethodsForTextComponent() { 768 return true; 769 } 770 }