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