1 /* 2 * Copyright (c) 2011, 2016, 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.peer.TaskbarPeer; 29 import java.awt.*; 30 import java.awt.datatransfer.Clipboard; 31 import java.awt.dnd.*; 32 import java.awt.dnd.peer.DragSourceContextPeer; 33 import java.awt.event.InputEvent; 34 import java.awt.event.InvocationEvent; 35 import java.awt.event.KeyEvent; 36 import java.awt.font.TextAttribute; 37 import java.awt.im.InputMethodHighlight; 38 import java.awt.im.spi.InputMethodDescriptor; 39 import java.awt.peer.*; 40 import java.lang.reflect.*; 41 import java.net.URL; 42 import java.security.*; 43 import java.util.*; 44 import java.util.concurrent.Callable; 45 import java.net.MalformedURLException; 46 47 import sun.awt.*; 48 import sun.awt.datatransfer.DataTransferer; 49 import sun.awt.util.ThreadGroupUtils; 50 import sun.java2d.opengl.OGLRenderQueue; 51 import sun.lwawt.*; 52 import sun.lwawt.LWWindowPeer.PeerType; 53 import sun.security.action.GetBooleanAction; 54 55 @SuppressWarnings("serial") // JDK implementation class 56 final class NamedCursor extends Cursor { 57 NamedCursor(String name) { 58 super(name); 59 } 60 } 61 62 /** 63 * Mac OS X Cocoa-based AWT Toolkit. 64 */ 65 public final class LWCToolkit extends LWToolkit { 66 // While it is possible to enumerate all mouse devices 67 // and query them for the number of buttons, the code 68 // that does it is rather complex. Instead, we opt for 69 // the easy way and just support up to 5 mouse buttons, 70 // like Windows. 71 private static final int BUTTONS = 5; 72 73 private static native void initIDs(); 74 private static native void initAppkit(ThreadGroup appKitThreadGroup, boolean headless); 75 private static CInputMethodDescriptor sInputMethodDescriptor; 76 77 static { 78 System.err.flush(); 79 80 ResourceBundle platformResources = java.security.AccessController.doPrivileged( 81 new java.security.PrivilegedAction<ResourceBundle>() { 82 @Override 83 public ResourceBundle run() { 84 ResourceBundle platformResources = null; 85 try { 86 platformResources = ResourceBundle.getBundle("sun.awt.resources.awtosx"); 87 } catch (MissingResourceException e) { 88 // No resource file; defaults will be used. 89 } 90 91 System.loadLibrary("awt"); 92 System.loadLibrary("fontmanager"); 93 94 return platformResources; 95 } 96 }); 97 98 AWTAccessor.getToolkitAccessor().setPlatformResources(platformResources); 99 100 if (!GraphicsEnvironment.isHeadless()) { 101 initIDs(); 102 } 103 inAWT = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { 104 @Override 105 public Boolean run() { 106 return !Boolean.parseBoolean(System.getProperty("javafx.embed.singleThread", "false")); 107 } 108 }); 109 } 110 111 /* 112 * If true we operate in normal mode and nested runloop is executed in JavaRunLoopMode 113 * If false we operate in singleThreaded FX/AWT interop mode and nested loop uses NSDefaultRunLoopMode 114 */ 115 private static final boolean inAWT; 116 117 public LWCToolkit() { 118 areExtraMouseButtonsEnabled = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons", "true")); 119 //set system property if not yet assigned 120 System.setProperty("sun.awt.enableExtraMouseButtons", ""+areExtraMouseButtonsEnabled); 121 initAppkit(ThreadGroupUtils.getRootThreadGroup(), GraphicsEnvironment.isHeadless()); 122 } 123 124 /* 125 * System colors with default initial values, overwritten by toolkit if system values differ and are available. 126 */ 127 private static final int NUM_APPLE_COLORS = 3; 128 public static final int KEYBOARD_FOCUS_COLOR = 0; 129 public static final int INACTIVE_SELECTION_BACKGROUND_COLOR = 1; 130 public static final int INACTIVE_SELECTION_FOREGROUND_COLOR = 2; 131 private static int[] appleColors = { 132 0xFF808080, // keyboardFocusColor = Color.gray; 133 0xFFC0C0C0, // secondarySelectedControlColor 134 0xFF303030, // controlDarkShadowColor 135 }; 136 137 private native void loadNativeColors(final int[] systemColors, final int[] appleColors); 138 139 @Override 140 protected void loadSystemColors(final int[] systemColors) { 141 if (systemColors == null) return; 142 loadNativeColors(systemColors, appleColors); 143 } 144 145 @SuppressWarnings("serial") // JDK implementation class 146 private static class AppleSpecificColor extends Color { 147 private final int index; 148 AppleSpecificColor(int index) { 149 super(appleColors[index]); 150 this.index = index; 151 } 152 153 @Override 154 public int getRGB() { 155 return appleColors[index]; 156 } 157 } 158 159 /** 160 * Returns Apple specific colors that we may expose going forward. 161 */ 162 public static Color getAppleColor(int color) { 163 return new AppleSpecificColor(color); 164 } 165 166 // This is only called from native code. 167 static void systemColorsChanged() { 168 EventQueue.invokeLater(() -> { 169 AccessController.doPrivileged( (PrivilegedAction<Object>) () -> { 170 AWTAccessor.getSystemColorAccessor().updateSystemColors(); 171 return null; 172 }); 173 }); 174 } 175 176 public static LWCToolkit getLWCToolkit() { 177 return (LWCToolkit)Toolkit.getDefaultToolkit(); 178 } 179 180 @Override 181 protected PlatformWindow createPlatformWindow(PeerType peerType) { 182 if (peerType == PeerType.EMBEDDED_FRAME) { 183 return new CPlatformEmbeddedFrame(); 184 } else if (peerType == PeerType.VIEW_EMBEDDED_FRAME) { 185 return new CViewPlatformEmbeddedFrame(); 186 } else if (peerType == PeerType.LW_FRAME) { 187 return new CPlatformLWWindow(); 188 } else { 189 assert (peerType == PeerType.SIMPLEWINDOW 190 || peerType == PeerType.DIALOG 191 || peerType == PeerType.FRAME); 192 return new CPlatformWindow(); 193 } 194 } 195 196 LWWindowPeer createEmbeddedFrame(CEmbeddedFrame target) { 197 PlatformComponent platformComponent = createPlatformComponent(); 198 PlatformWindow platformWindow = createPlatformWindow(PeerType.EMBEDDED_FRAME); 199 return createDelegatedPeer(target, platformComponent, platformWindow, PeerType.EMBEDDED_FRAME); 200 } 201 202 LWWindowPeer createEmbeddedFrame(CViewEmbeddedFrame target) { 203 PlatformComponent platformComponent = createPlatformComponent(); 204 PlatformWindow platformWindow = createPlatformWindow(PeerType.VIEW_EMBEDDED_FRAME); 205 return createDelegatedPeer(target, platformComponent, platformWindow, PeerType.VIEW_EMBEDDED_FRAME); 206 } 207 208 private CPrinterDialogPeer createCPrinterDialog(CPrinterDialog target) { 209 PlatformComponent platformComponent = createPlatformComponent(); 210 PlatformWindow platformWindow = createPlatformWindow(PeerType.DIALOG); 211 CPrinterDialogPeer peer = new CPrinterDialogPeer(target, platformComponent, platformWindow); 212 targetCreatedPeer(target, peer); 213 return peer; 214 } 215 216 @Override 217 public DialogPeer createDialog(Dialog target) { 218 if (target instanceof CPrinterDialog) { 219 return createCPrinterDialog((CPrinterDialog)target); 220 } 221 return super.createDialog(target); 222 } 223 224 @Override 225 protected SecurityWarningWindow createSecurityWarning(Window ownerWindow, 226 LWWindowPeer ownerPeer) { 227 return new CWarningWindow(ownerWindow, ownerPeer); 228 } 229 230 @Override 231 protected PlatformComponent createPlatformComponent() { 232 return new CPlatformComponent(); 233 } 234 235 @Override 236 protected PlatformComponent createLwPlatformComponent() { 237 return new CPlatformLWComponent(); 238 } 239 240 @Override 241 protected FileDialogPeer createFileDialogPeer(FileDialog target) { 242 return new CFileDialog(target); 243 } 244 245 @Override 246 public MenuPeer createMenu(Menu target) { 247 MenuPeer peer = new CMenu(target); 248 targetCreatedPeer(target, peer); 249 return peer; 250 } 251 252 @Override 253 public MenuBarPeer createMenuBar(MenuBar target) { 254 MenuBarPeer peer = new CMenuBar(target); 255 targetCreatedPeer(target, peer); 256 return peer; 257 } 258 259 @Override 260 public MenuItemPeer createMenuItem(MenuItem target) { 261 MenuItemPeer peer = new CMenuItem(target); 262 targetCreatedPeer(target, peer); 263 return peer; 264 } 265 266 @Override 267 public CheckboxMenuItemPeer createCheckboxMenuItem(CheckboxMenuItem target) { 268 CheckboxMenuItemPeer peer = new CCheckboxMenuItem(target); 269 targetCreatedPeer(target, peer); 270 return peer; 271 } 272 273 @Override 274 public PopupMenuPeer createPopupMenu(PopupMenu target) { 275 PopupMenuPeer peer = new CPopupMenu(target); 276 targetCreatedPeer(target, peer); 277 return peer; 278 } 279 280 @Override 281 public SystemTrayPeer createSystemTray(SystemTray target) { 282 return new CSystemTray(); 283 } 284 285 @Override 286 public TrayIconPeer createTrayIcon(TrayIcon target) { 287 TrayIconPeer peer = new CTrayIcon(target); 288 targetCreatedPeer(target, peer); 289 return peer; 290 } 291 292 @Override 293 public DesktopPeer createDesktopPeer(Desktop target) { 294 return new CDesktopPeer(); 295 } 296 297 @Override 298 public TaskbarPeer createTaskbarPeer(Taskbar target) { 299 return new CTaskbarPeer(); 300 } 301 302 @Override 303 public LWCursorManager getCursorManager() { 304 return CCursorManager.getInstance(); 305 } 306 307 @Override 308 public Cursor createCustomCursor(final Image cursor, final Point hotSpot, 309 final String name) 310 throws IndexOutOfBoundsException, HeadlessException { 311 return new CCustomCursor(cursor, hotSpot, name); 312 } 313 314 @Override 315 public Dimension getBestCursorSize(final int preferredWidth, 316 final int preferredHeight) 317 throws HeadlessException { 318 return CCustomCursor.getBestCursorSize(preferredWidth, preferredHeight); 319 } 320 321 @Override 322 protected void platformCleanup() { 323 // TODO Auto-generated method stub 324 } 325 326 @Override 327 protected void platformInit() { 328 // TODO Auto-generated method stub 329 } 330 331 @Override 332 protected void platformRunMessage() { 333 // TODO Auto-generated method stub 334 } 335 336 @Override 337 protected void platformShutdown() { 338 // TODO Auto-generated method stub 339 } 340 341 class OSXPlatformFont extends sun.awt.PlatformFont 342 { 343 OSXPlatformFont(String name, int style) 344 { 345 super(name, style); 346 } 347 @Override 348 protected char getMissingGlyphCharacter() 349 { 350 // Follow up for real implementation 351 return (char)0xfff8; // see http://developer.apple.com/fonts/LastResortFont/ 352 } 353 } 354 @Override 355 public FontPeer getFontPeer(String name, int style) { 356 return new OSXPlatformFont(name, style); 357 } 358 359 @Override 360 protected int getScreenHeight() { 361 return GraphicsEnvironment.getLocalGraphicsEnvironment() 362 .getDefaultScreenDevice().getDefaultConfiguration().getBounds().height; 363 } 364 365 @Override 366 protected int getScreenWidth() { 367 return GraphicsEnvironment.getLocalGraphicsEnvironment() 368 .getDefaultScreenDevice().getDefaultConfiguration().getBounds().width; 369 } 370 371 @Override 372 protected void initializeDesktopProperties() { 373 super.initializeDesktopProperties(); 374 Map <Object, Object> fontHints = new HashMap<>(); 375 fontHints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB); 376 desktopProperties.put(SunToolkit.DESKTOPFONTHINTS, fontHints); 377 desktopProperties.put("awt.mouse.numButtons", BUTTONS); 378 379 // These DnD properties must be set, otherwise Swing ends up spewing NPEs 380 // all over the place. The values came straight off of MToolkit. 381 desktopProperties.put("DnD.Autoscroll.initialDelay", Integer.valueOf(50)); 382 desktopProperties.put("DnD.Autoscroll.interval", Integer.valueOf(50)); 383 desktopProperties.put("DnD.Autoscroll.cursorHysteresis", Integer.valueOf(5)); 384 385 desktopProperties.put("DnD.isDragImageSupported", Boolean.TRUE); 386 387 // Register DnD cursors 388 desktopProperties.put("DnD.Cursor.CopyDrop", new NamedCursor("DnD.Cursor.CopyDrop")); 389 desktopProperties.put("DnD.Cursor.MoveDrop", new NamedCursor("DnD.Cursor.MoveDrop")); 390 desktopProperties.put("DnD.Cursor.LinkDrop", new NamedCursor("DnD.Cursor.LinkDrop")); 391 desktopProperties.put("DnD.Cursor.CopyNoDrop", new NamedCursor("DnD.Cursor.CopyNoDrop")); 392 desktopProperties.put("DnD.Cursor.MoveNoDrop", new NamedCursor("DnD.Cursor.MoveNoDrop")); 393 desktopProperties.put("DnD.Cursor.LinkNoDrop", new NamedCursor("DnD.Cursor.LinkNoDrop")); 394 } 395 396 @Override 397 protected boolean syncNativeQueue(long timeout) { 398 return nativeSyncQueue(timeout); 399 } 400 401 @Override 402 public native void beep(); 403 404 @Override 405 public int getScreenResolution() throws HeadlessException { 406 return (int) ((CGraphicsDevice) GraphicsEnvironment 407 .getLocalGraphicsEnvironment().getDefaultScreenDevice()) 408 .getXResolution(); 409 } 410 411 @Override 412 public Insets getScreenInsets(final GraphicsConfiguration gc) { 413 return ((CGraphicsConfig) gc).getDevice().getScreenInsets(); 414 } 415 416 @Override 417 public void sync() { 418 // flush the OGL pipeline (this is a no-op if OGL is not enabled) 419 OGLRenderQueue.sync(); 420 // setNeedsDisplay() selector was sent to the appropriate CALayer so now 421 // we have to flush the native selectors queue. 422 flushNativeSelectors(); 423 } 424 425 @Override 426 public RobotPeer createRobot(Robot target, GraphicsDevice screen) { 427 return new CRobot(target, (CGraphicsDevice)screen); 428 } 429 430 private native boolean isCapsLockOn(); 431 432 /* 433 * NOTE: Among the keys this method is supposed to check, 434 * only Caps Lock works as a true locking key with OS X. 435 * There is no Scroll Lock key on modern Apple keyboards, 436 * and with a PC keyboard plugged in Scroll Lock is simply 437 * ignored: no LED lights up if you press it. 438 * The key located at the same position on Apple keyboards 439 * as Num Lock on PC keyboards is called Clear, doesn't lock 440 * anything and is used for entirely different purpose. 441 */ 442 @Override 443 public boolean getLockingKeyState(int keyCode) throws UnsupportedOperationException { 444 switch (keyCode) { 445 case KeyEvent.VK_NUM_LOCK: 446 case KeyEvent.VK_SCROLL_LOCK: 447 case KeyEvent.VK_KANA_LOCK: 448 throw new UnsupportedOperationException("Toolkit.getLockingKeyState"); 449 450 case KeyEvent.VK_CAPS_LOCK: 451 return isCapsLockOn(); 452 453 default: 454 throw new IllegalArgumentException("invalid key for Toolkit.getLockingKeyState"); 455 } 456 } 457 458 //Is it allowed to generate events assigned to extra mouse buttons. 459 //Set to true by default. 460 private static boolean areExtraMouseButtonsEnabled = true; 461 462 @Override 463 public boolean areExtraMouseButtonsEnabled() throws HeadlessException { 464 return areExtraMouseButtonsEnabled; 465 } 466 467 @Override 468 public int getNumberOfButtons(){ 469 return BUTTONS; 470 } 471 472 @Override 473 public boolean isTraySupported() { 474 return true; 475 } 476 477 @Override 478 public DataTransferer getDataTransferer() { 479 return CDataTransferer.getInstanceImpl(); 480 } 481 482 @Override 483 public boolean isAlwaysOnTopSupported() { 484 return true; 485 } 486 487 private static final String APPKIT_THREAD_NAME = "AppKit Thread"; 488 489 // Intended to be called from the LWCToolkit.m only. 490 private static void installToolkitThreadInJava() { 491 Thread.currentThread().setName(APPKIT_THREAD_NAME); 492 AccessController.doPrivileged((PrivilegedAction<Void>) () -> { 493 Thread.currentThread().setContextClassLoader(null); 494 return null; 495 }); 496 } 497 498 @Override 499 public boolean isWindowOpacitySupported() { 500 return true; 501 } 502 503 @Override 504 public boolean isFrameStateSupported(int state) throws HeadlessException { 505 switch (state) { 506 case Frame.NORMAL: 507 case Frame.ICONIFIED: 508 case Frame.MAXIMIZED_BOTH: 509 return true; 510 default: 511 return false; 512 } 513 } 514 515 /** 516 * Determines which modifier key is the appropriate accelerator 517 * key for menu shortcuts. 518 * <p> 519 * Menu shortcuts, which are embodied in the 520 * {@code MenuShortcut} class, are handled by the 521 * {@code MenuBar} class. 522 * <p> 523 * By default, this method returns {@code Event.CTRL_MASK}. 524 * Toolkit implementations should override this method if the 525 * <b>Control</b> key isn't the correct key for accelerators. 526 * @return the modifier mask on the {@code Event} class 527 * that is used for menu shortcuts on this toolkit. 528 * @see java.awt.MenuBar 529 * @see java.awt.MenuShortcut 530 * @since 1.1 531 */ 532 @Override 533 public int getMenuShortcutKeyMask() { 534 return Event.META_MASK; 535 } 536 537 @Override 538 public Image getImage(String filename) { 539 final Image nsImage = checkForNSImage(filename); 540 if (nsImage != null) { 541 return nsImage; 542 } 543 544 return super.getImage(filename); 545 } 546 547 private static final String nsImagePrefix = "NSImage://"; 548 private Image checkForNSImage(final String imageName) { 549 if (imageName == null) return null; 550 if (!imageName.startsWith(nsImagePrefix)) return null; 551 return CImage.getCreator().createImageFromName(imageName.substring(nsImagePrefix.length())); 552 } 553 554 // Thread-safe Object.equals() called from native 555 public static boolean doEquals(final Object a, final Object b, Component c) { 556 if (a == b) return true; 557 558 final boolean[] ret = new boolean[1]; 559 560 try { invokeAndWait(new Runnable() { @Override 561 public void run() { synchronized(ret) { 562 ret[0] = a.equals(b); 563 }}}, c); } catch (Exception e) { e.printStackTrace(); } 564 565 synchronized(ret) { return ret[0]; } 566 } 567 568 public static <T> T invokeAndWait(final Callable<T> callable, 569 Component component) throws Exception { 570 final CallableWrapper<T> wrapper = new CallableWrapper<>(callable); 571 invokeAndWait(wrapper, component); 572 return wrapper.getResult(); 573 } 574 575 static final class CallableWrapper<T> implements Runnable { 576 final Callable<T> callable; 577 T object; 578 Exception e; 579 580 CallableWrapper(final Callable<T> callable) { 581 this.callable = callable; 582 } 583 584 @Override 585 public void run() { 586 try { 587 object = callable.call(); 588 } catch (final Exception e) { 589 this.e = e; 590 } 591 } 592 593 public T getResult() throws Exception { 594 if (e != null) throw e; 595 return object; 596 } 597 } 598 599 /** 600 * Kicks an event over to the appropriate event queue and waits for it to 601 * finish To avoid deadlocking, we manually run the NSRunLoop while waiting 602 * Any selector invoked using ThreadUtilities performOnMainThread will be 603 * processed in doAWTRunLoop The InvocationEvent will call 604 * LWCToolkit.stopAWTRunLoop() when finished, which will stop our manual 605 * run loop. Does not dispatch native events while in the loop 606 */ 607 public static void invokeAndWait(Runnable runnable, Component component) 608 throws InvocationTargetException { 609 Objects.requireNonNull(component, "Null component provided to invokeAndWait"); 610 611 long mediator = createAWTRunLoopMediator(); 612 InvocationEvent invocationEvent = 613 new InvocationEvent(component, 614 runnable, 615 () -> { 616 if (mediator != 0) { 617 stopAWTRunLoop(mediator); 618 } 619 }, 620 true); 621 622 AppContext appContext = SunToolkit.targetToAppContext(component); 623 SunToolkit.postEvent(appContext, invocationEvent); 624 // 3746956 - flush events from PostEventQueue to prevent them from getting stuck and causing a deadlock 625 SunToolkit.flushPendingEvents(appContext); 626 doAWTRunLoop(mediator, false); 627 628 checkException(invocationEvent); 629 } 630 631 public static void invokeLater(Runnable event, Component component) 632 throws InvocationTargetException { 633 Objects.requireNonNull(component, "Null component provided to invokeLater"); 634 635 InvocationEvent invocationEvent = new InvocationEvent(component, event); 636 637 AppContext appContext = SunToolkit.targetToAppContext(component); 638 SunToolkit.postEvent(SunToolkit.targetToAppContext(component), invocationEvent); 639 // 3746956 - flush events from PostEventQueue to prevent them from getting stuck and causing a deadlock 640 SunToolkit.flushPendingEvents(appContext); 641 642 checkException(invocationEvent); 643 } 644 645 /** 646 * Checks if exception occurred while {@code InvocationEvent} was processed and rethrows it as 647 * an {@code InvocationTargetException} 648 * 649 * @param event the event to check for an exception 650 * @throws InvocationTargetException if exception occurred when event was processed 651 */ 652 private static void checkException(InvocationEvent event) throws InvocationTargetException { 653 Throwable eventException = event.getException(); 654 if (eventException == null) return; 655 656 if (eventException instanceof UndeclaredThrowableException) { 657 eventException = ((UndeclaredThrowableException)eventException).getUndeclaredThrowable(); 658 } 659 throw new InvocationTargetException(eventException); 660 } 661 662 /** 663 * Schedules a {@code Runnable} execution on the Appkit thread after a delay 664 * @param r a {@code Runnable} to execute 665 * @param delay a delay in milliseconds 666 */ 667 static native void performOnMainThreadAfterDelay(Runnable r, long delay); 668 669 // DnD support 670 671 @Override 672 public DragSourceContextPeer createDragSourceContextPeer( 673 DragGestureEvent dge) throws InvalidDnDOperationException { 674 final LightweightFrame f = SunToolkit.getLightweightFrame(dge.getComponent()); 675 if (f != null) { 676 return f.createDragSourceContextPeer(dge); 677 } 678 679 return CDragSourceContextPeer.createDragSourceContextPeer(dge); 680 } 681 682 @Override 683 @SuppressWarnings("unchecked") 684 public <T extends DragGestureRecognizer> T createDragGestureRecognizer( 685 Class<T> abstractRecognizerClass, DragSource ds, Component c, 686 int srcActions, DragGestureListener dgl) { 687 final LightweightFrame f = SunToolkit.getLightweightFrame(c); 688 if (f != null) { 689 return f.createDragGestureRecognizer(abstractRecognizerClass, ds, c, srcActions, dgl); 690 } 691 692 DragGestureRecognizer dgr = null; 693 694 // Create a new mouse drag gesture recognizer if we have a class match: 695 if (MouseDragGestureRecognizer.class.equals(abstractRecognizerClass)) 696 dgr = new CMouseDragGestureRecognizer(ds, c, srcActions, dgl); 697 698 return (T)dgr; 699 } 700 701 @Override 702 protected PlatformDropTarget createDropTarget(DropTarget dropTarget, 703 Component component, 704 LWComponentPeer<?, ?> peer) { 705 return new CDropTarget(dropTarget, component, peer); 706 } 707 708 // InputMethodSupport Method 709 /** 710 * Returns the default keyboard locale of the underlying operating system 711 */ 712 @Override 713 public Locale getDefaultKeyboardLocale() { 714 Locale locale = CInputMethod.getNativeLocale(); 715 716 if (locale == null) { 717 return super.getDefaultKeyboardLocale(); 718 } 719 720 return locale; 721 } 722 723 @Override 724 public InputMethodDescriptor getInputMethodAdapterDescriptor() { 725 if (sInputMethodDescriptor == null) 726 sInputMethodDescriptor = new CInputMethodDescriptor(); 727 728 return sInputMethodDescriptor; 729 } 730 731 /** 732 * Returns a map of visual attributes for thelevel description 733 * of the given input method highlight, or null if no mapping is found. 734 * The style field of the input method highlight is ignored. The map 735 * returned is unmodifiable. 736 * @param highlight input method highlight 737 * @return style attribute map, or null 738 * @since 1.3 739 */ 740 @Override 741 public Map<TextAttribute, ?> mapInputMethodHighlight(InputMethodHighlight highlight) { 742 return CInputMethod.mapInputMethodHighlight(highlight); 743 } 744 745 /** 746 * Returns key modifiers used by Swing to set up a focus accelerator key 747 * stroke. 748 */ 749 @Override 750 public int getFocusAcceleratorKeyMask() { 751 return InputEvent.CTRL_MASK | InputEvent.ALT_MASK; 752 } 753 754 /** 755 * Tests whether specified key modifiers mask can be used to enter a 756 * printable character. 757 */ 758 @Override 759 public boolean isPrintableCharacterModifiersMask(int mods) { 760 return ((mods & (InputEvent.META_MASK | InputEvent.CTRL_MASK)) == 0); 761 } 762 763 /** 764 * Returns whether popup is allowed to be shown above the task bar. 765 */ 766 @Override 767 public boolean canPopupOverlapTaskBar() { 768 return false; 769 } 770 771 private static Boolean sunAwtDisableCALayers = null; 772 773 /** 774 * Returns the value of "sun.awt.disableCALayers" property. Default 775 * value is {@code false}. 776 */ 777 public static synchronized boolean getSunAwtDisableCALayers() { 778 if (sunAwtDisableCALayers == null) { 779 sunAwtDisableCALayers = AccessController.doPrivileged( 780 new GetBooleanAction("sun.awt.disableCALayers")); 781 } 782 return sunAwtDisableCALayers; 783 } 784 785 /* 786 * Returns true if the application (one of its windows) owns keyboard focus. 787 */ 788 native boolean isApplicationActive(); 789 790 /** 791 * Returns true if AWT toolkit is embedded, false otherwise. 792 * 793 * @return true if AWT toolkit is embedded, false otherwise 794 */ 795 public static native boolean isEmbedded(); 796 797 /* 798 * Activates application ignoring other apps. 799 */ 800 public native void activateApplicationIgnoringOtherApps(); 801 802 /************************ 803 * Native methods section 804 ************************/ 805 806 static native long createAWTRunLoopMediator(); 807 /** 808 * Method to run a nested run-loop. The nested loop is spinned in the javaRunLoop mode, so selectors sent 809 * by [JNFRunLoop performOnMainThreadWaiting] are processed. 810 * @param mediator a native pointer to the mediator object created by createAWTRunLoopMediator 811 * @param processEvents if true - dispatches event while in the nested loop. Used in DnD. 812 * Additional attention is needed when using this feature as we short-circuit normal event 813 * processing which could break Appkit. 814 * (One known example is when the window is resized with the mouse) 815 * 816 * if false - all events come after exit form the nested loop 817 */ 818 static void doAWTRunLoop(long mediator, boolean processEvents) { 819 doAWTRunLoopImpl(mediator, processEvents, inAWT); 820 } 821 private static native void doAWTRunLoopImpl(long mediator, boolean processEvents, boolean inAWT); 822 static native void stopAWTRunLoop(long mediator); 823 824 private native boolean nativeSyncQueue(long timeout); 825 826 /** 827 * Just spin a single empty block synchronously. 828 */ 829 static native void flushNativeSelectors(); 830 831 @Override 832 public Clipboard createPlatformClipboard() { 833 return new CClipboard("System"); 834 } 835 836 @Override 837 public boolean isModalExclusionTypeSupported(Dialog.ModalExclusionType exclusionType) { 838 return (exclusionType == null) || 839 (exclusionType == Dialog.ModalExclusionType.NO_EXCLUDE) || 840 (exclusionType == Dialog.ModalExclusionType.APPLICATION_EXCLUDE) || 841 (exclusionType == Dialog.ModalExclusionType.TOOLKIT_EXCLUDE); 842 } 843 844 @Override 845 public boolean isModalityTypeSupported(Dialog.ModalityType modalityType) { 846 //TODO: FileDialog blocks excluded windows... 847 //TODO: Test: 2 file dialogs, separate AppContexts: a) Dialog 1 blocked, shouldn't be. Frame 4 blocked (shouldn't be). 848 return (modalityType == null) || 849 (modalityType == Dialog.ModalityType.MODELESS) || 850 (modalityType == Dialog.ModalityType.DOCUMENT_MODAL) || 851 (modalityType == Dialog.ModalityType.APPLICATION_MODAL) || 852 (modalityType == Dialog.ModalityType.TOOLKIT_MODAL); 853 } 854 855 @Override 856 public boolean isWindowShapingSupported() { 857 return true; 858 } 859 860 @Override 861 public boolean isWindowTranslucencySupported() { 862 return true; 863 } 864 865 @Override 866 public boolean isTranslucencyCapable(GraphicsConfiguration gc) { 867 return true; 868 } 869 870 @Override 871 public boolean isSwingBackbufferTranslucencySupported() { 872 return true; 873 } 874 875 @Override 876 public boolean enableInputMethodsForTextComponent() { 877 return true; 878 } 879 880 @Override 881 protected PlatformWindow getPlatformWindowUnderMouse() { 882 return CPlatformWindow.nativeGetTopmostPlatformWindowUnderMouse(); 883 } 884 }