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