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