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