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 targetCreatedPeer(target, peer); 220 return peer; 221 } 222 223 @Override 224 public TrayIconPeer createTrayIcon(TrayIcon target) { 225 TrayIconPeer peer = new CTrayIcon(target); 226 targetCreatedPeer(target, peer); 227 return peer; 228 } 229 230 @Override 231 public LWCursorManager getCursorManager() { 232 return CCursorManager.getInstance(); 233 } 234 235 @Override 236 public Cursor createCustomCursor(final Image cursor, final Point hotSpot, final String name) throws IndexOutOfBoundsException, HeadlessException { 237 return new CCustomCursor(cursor, hotSpot, name); 238 } 239 240 @Override 241 public Dimension getBestCursorSize(final int preferredWidth, final int preferredHeight) throws HeadlessException { 242 return CCustomCursor.getBestCursorSize(preferredWidth, preferredHeight); 243 } 244 245 @Override 246 protected void platformCleanup() { 247 // TODO Auto-generated method stub 248 249 } 250 251 @Override 252 protected void platformInit() { 253 // TODO Auto-generated method stub 254 255 } 256 257 @Override 258 protected void platformRunMessage() { 259 // TODO Auto-generated method stub 260 261 } 262 263 @Override 264 protected void platformShutdown() { 265 // TODO Auto-generated method stub 266 267 } 268 269 class OSXPlatformFont extends sun.awt.PlatformFont 270 { 271 public OSXPlatformFont(String name, int style) 272 { 273 super(name, style); 274 } 275 protected char getMissingGlyphCharacter() 276 { 277 // Follow up for real implementation 278 return (char)0xfff8; // see http://developer.apple.com/fonts/LastResortFont/ 279 } 280 } 281 public FontPeer getFontPeer(String name, int style) { 282 return new OSXPlatformFont(name, style); 283 } 284 285 @Override 286 protected MouseInfoPeer createMouseInfoPeerImpl() { 287 return new CMouseInfoPeer(); 288 } 289 290 291 @Override 292 protected int getScreenHeight() { 293 return GraphicsEnvironment.getLocalGraphicsEnvironment() 294 .getDefaultScreenDevice().getDefaultConfiguration().getBounds().height; 295 } 296 297 @Override 298 protected int getScreenWidth() { 299 return GraphicsEnvironment.getLocalGraphicsEnvironment() 300 .getDefaultScreenDevice().getDefaultConfiguration().getBounds().width; 301 } 302 303 @Override 304 protected void initializeDesktopProperties() { 305 super.initializeDesktopProperties(); 306 Map <Object, Object> fontHints = new HashMap<Object, Object>(); 307 fontHints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 308 fontHints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 309 desktopProperties.put(SunToolkit.DESKTOPFONTHINTS, fontHints); 310 desktopProperties.put("awt.mouse.numButtons", BUTTONS); 311 312 // These DnD properties must be set, otherwise Swing ends up spewing NPEs 313 // all over the place. The values came straight off of MToolkit. 314 desktopProperties.put("DnD.Autoscroll.initialDelay", new Integer(50)); 315 desktopProperties.put("DnD.Autoscroll.interval", new Integer(50)); 316 desktopProperties.put("DnD.Autoscroll.cursorHysteresis", new Integer(5)); 317 318 desktopProperties.put("DnD.isDragImageSupported", new Boolean(true)); 319 320 // Register DnD cursors 321 desktopProperties.put("DnD.Cursor.CopyDrop", new NamedCursor("DnD.Cursor.CopyDrop")); 322 desktopProperties.put("DnD.Cursor.MoveDrop", new NamedCursor("DnD.Cursor.MoveDrop")); 323 desktopProperties.put("DnD.Cursor.LinkDrop", new NamedCursor("DnD.Cursor.LinkDrop")); 324 desktopProperties.put("DnD.Cursor.CopyNoDrop", new NamedCursor("DnD.Cursor.CopyNoDrop")); 325 desktopProperties.put("DnD.Cursor.MoveNoDrop", new NamedCursor("DnD.Cursor.MoveNoDrop")); 326 desktopProperties.put("DnD.Cursor.LinkNoDrop", new NamedCursor("DnD.Cursor.LinkNoDrop")); 327 328 } 329 330 331 /* 332 * The method returns true if some events were processed during that timeout. 333 * @see sun.awt.SunToolkit#syncNativeQueue(long) 334 */ 335 @Override 336 protected boolean syncNativeQueue(long timeout) { 337 return nativeSyncQueue(timeout); 338 } 339 340 @Override 341 public native void beep(); 342 343 @Override 344 public int getScreenResolution() throws HeadlessException { 345 return ((CGraphicsDevice) GraphicsEnvironment 346 .getLocalGraphicsEnvironment().getDefaultScreenDevice()).getScreenResolution(); 347 } 348 349 @Override 350 public Insets getScreenInsets(final GraphicsConfiguration gc) { 351 final CGraphicsConfig cgc = (CGraphicsConfig) gc; 352 final int displayId = cgc.getDevice().getCoreGraphicsScreen(); 353 Rectangle fullScreen, workArea; 354 final long screen = CWrapper.NSScreen.screenByDisplayId(displayId); 355 try { 356 fullScreen = CWrapper.NSScreen.frame(screen).getBounds(); 357 workArea = CWrapper.NSScreen.visibleFrame(screen).getBounds(); 358 } finally { 359 CWrapper.NSObject.release(screen); 360 } 361 // Convert between Cocoa's coordinate system and Java. 362 int bottom = workArea.y - fullScreen.y; 363 int top = fullScreen.height - workArea.height - bottom; 364 int left = workArea.x - fullScreen.x; 365 int right = fullScreen.width - workArea.width - left; 366 return new Insets(top, left, bottom, right); 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 isWindowShapingSupported() { 755 return true; 756 } 757 758 @Override 759 public boolean isWindowTranslucencySupported() { 760 return true; 761 } 762 763 @Override 764 public boolean isTranslucencyCapable(GraphicsConfiguration gc) { 765 return true; 766 } 767 768 public boolean isSwingBackbufferTranslucencySupported() { 769 return true; 770 } 771 772 @Override 773 public boolean enableInputMethodsForTextComponent() { 774 return true; 775 } 776 }