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