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 #import <Cocoa/Cocoa.h>
  27 #import <JavaNativeFoundation/JavaNativeFoundation.h>
  28 #import <JavaRuntimeSupport/JavaRuntimeSupport.h>
  29 
  30 #import "sun_lwawt_macosx_CPlatformWindow.h"
  31 #import "com_apple_eawt_event_GestureHandler.h"
  32 #import "com_apple_eawt_FullScreenHandler.h"
  33 
  34 #import "AWTWindow.h"
  35 #import "AWTView.h"
  36 #import "CMenu.h"
  37 #import "CMenuBar.h"
  38 #import "LWCToolkit.h"
  39 #import "GeomUtilities.h"
  40 #import "ThreadUtilities.h"
  41 #import "OSVersion.h"
  42 
  43 
  44 #define MASK(KEY) \
  45     (sun_lwawt_macosx_CPlatformWindow_ ## KEY)
  46 
  47 #define IS(BITS, KEY) \
  48     ((BITS & MASK(KEY)) != 0)
  49 
  50 #define SET(BITS, KEY, VALUE) \
  51     BITS = VALUE ? BITS | MASK(KEY) : BITS & ~MASK(KEY)
  52 
  53 
  54 static JNF_CLASS_CACHE(jc_CPlatformWindow, "sun/lwawt/macosx/CPlatformWindow");
  55 
  56 @interface JavaResizeGrowBoxOverlayWindow : NSWindow { }
  57 
  58 @end
  59 
  60 @implementation JavaResizeGrowBoxOverlayWindow
  61 
  62 - (BOOL) accessibilityIsIgnored
  63 {
  64     return YES;
  65 }
  66 
  67 - (NSArray *)accessibilityChildrenAttribute
  68 {
  69     return nil;
  70 }
  71 @end
  72 
  73 @implementation AWTWindow
  74 
  75 @synthesize javaPlatformWindow;
  76 @synthesize javaMenuBar;
  77 @synthesize growBoxWindow;
  78 @synthesize javaMinSize;
  79 @synthesize javaMaxSize;
  80 @synthesize styleBits;
  81 
  82 - (void) updateMinMaxSize:(BOOL)resizable {
  83     if (resizable) {
  84         [self setMinSize:self.javaMinSize];
  85         [self setMaxSize:self.javaMaxSize];
  86     } else {
  87         NSRect currentFrame = [self frame];
  88         [self setMinSize:currentFrame.size];
  89         [self setMaxSize:currentFrame.size];
  90     }
  91 }
  92 
  93 // creates a new NSWindow style mask based on the _STYLE_PROP_BITMASK bits
  94 + (NSUInteger) styleMaskForStyleBits:(jint)styleBits {
  95     NSUInteger type = 0;
  96     if (IS(styleBits, DECORATED)) {
  97         type |= NSTitledWindowMask;
  98         if (IS(styleBits, CLOSEABLE))   type |= NSClosableWindowMask;
  99         if (IS(styleBits, MINIMIZABLE)) type |= NSMiniaturizableWindowMask;
 100         if (IS(styleBits, RESIZABLE))   type |= NSResizableWindowMask;
 101     } else {
 102         type |= NSBorderlessWindowMask;
 103     }
 104 
 105     if (IS(styleBits, TEXTURED))      type |= NSTexturedBackgroundWindowMask;
 106     if (IS(styleBits, UNIFIED))       type |= NSUnifiedTitleAndToolbarWindowMask;
 107     if (IS(styleBits, UTILITY))       type |= NSUtilityWindowMask;
 108     if (IS(styleBits, HUD))           type |= NSHUDWindowMask;
 109     if (IS(styleBits, SHEET))         type |= NSDocModalWindowMask;
 110     if (IS(styleBits, NONACTIVATING)) type |= NSNonactivatingPanelMask;
 111 
 112     return type;
 113 }
 114 
 115 // updates _METHOD_PROP_BITMASK based properties on the window
 116 - (void) setPropertiesForStyleBits:(jint)bits mask:(jint)mask {
 117     if (IS(mask, RESIZABLE)) {
 118         BOOL resizable = IS(bits, RESIZABLE);
 119         [self updateMinMaxSize:resizable];
 120         [self setShowsResizeIndicator:resizable];
 121     }
 122 
 123     if (IS(mask, HAS_SHADOW)) {
 124         [self setHasShadow:IS(bits, HAS_SHADOW)];
 125     }
 126 
 127     if (IS(mask, ZOOMABLE)) {
 128         [[self standardWindowButton:NSWindowZoomButton] setEnabled:IS(bits, ZOOMABLE)];
 129     }
 130 
 131     if (IS(mask, ALWAYS_ON_TOP)) {
 132         [self setLevel:IS(bits, ALWAYS_ON_TOP) ? NSFloatingWindowLevel : NSNormalWindowLevel];
 133     }
 134 
 135     if (IS(mask, HIDES_ON_DEACTIVATE)) {
 136         [self setHidesOnDeactivate:IS(bits, HIDES_ON_DEACTIVATE)];
 137     }
 138 
 139     if (IS(mask, DRAGGABLE_BACKGROUND)) {
 140         [self setMovableByWindowBackground:IS(bits, DRAGGABLE_BACKGROUND)];
 141     }
 142 
 143     if (IS(mask, DOCUMENT_MODIFIED)) {
 144         [self setDocumentEdited:IS(bits, DOCUMENT_MODIFIED)];
 145     }
 146 
 147     if ([self respondsToSelector:@selector(toggleFullScreen:)]) {
 148         if (IS(mask, FULLSCREENABLE)) {
 149             [self setCollectionBehavior:(1 << 7) /*NSWindowCollectionBehaviorFullScreenPrimary*/];
 150         } else {
 151             [self setCollectionBehavior:NSWindowCollectionBehaviorDefault];
 152         }
 153     }
 154 
 155 }
 156 
 157 - (BOOL) shouldShowGrowBox {
 158     return isSnowLeopardOrLower() && IS(self.styleBits, RESIZABLE);
 159 }
 160 
 161 - (NSImage *) createGrowBoxImage {
 162     NSImage *image = [[NSImage alloc] initWithSize:NSMakeSize(12, 12)];
 163     JRSUIControlRef growBoxWidget = JRSUIControlCreate(FALSE);
 164     JRSUIControlSetWidget(growBoxWidget, kJRSUI_Widget_growBoxTextured);
 165     JRSUIControlSetWindowType(growBoxWidget, kJRSUI_WindowType_utility);
 166     JRSUIRendererRef renderer = JRSUIRendererCreate();
 167     [image lockFocus]; // sets current graphics context to that of the image
 168     JRSUIControlDraw(renderer, growBoxWidget, [[NSGraphicsContext currentContext] graphicsPort], CGRectMake(0, 1, 11, 11));
 169     [image unlockFocus];
 170     JRSUIRendererRelease(renderer);
 171     JRSUIControlRelease(growBoxWidget);
 172     return image;
 173 }
 174 
 175 - (id) initWithPlatformWindow:(JNFWeakJObjectWrapper *)platformWindow
 176                     styleBits:(jint)bits
 177                     frameRect:(NSRect)rect
 178                   contentView:(NSView *)view
 179 {
 180 AWT_ASSERT_APPKIT_THREAD;
 181 
 182     NSUInteger styleMask = [AWTWindow styleMaskForStyleBits:bits];
 183     NSRect contentRect = rect; //[NSWindow contentRectForFrameRect:rect styleMask:styleMask];
 184     if (contentRect.size.width <= 0.0) {
 185         contentRect.size.width = 1.0;
 186     }
 187     if (contentRect.size.height <= 0.0) {
 188         contentRect.size.height = 1.0;
 189     }
 190 
 191     self = [super initWithContentRect:contentRect
 192                             styleMask:styleMask
 193                               backing:NSBackingStoreBuffered
 194                                 defer:NO];
 195 
 196     if (self == nil) return nil; // no hope
 197 
 198     self.javaPlatformWindow = platformWindow;
 199     self.styleBits = bits;
 200     [self setPropertiesForStyleBits:styleBits mask:MASK(_METHOD_PROP_BITMASK)];
 201 
 202     [self setDelegate:self];
 203     [self setContentView:view];
 204     [self setInitialFirstResponder:view];
 205     [self setReleasedWhenClosed:NO];
 206     [self setPreservesContentDuringLiveResize:YES];
 207 
 208     if ([self shouldShowGrowBox]) {
 209         NSImage *growBoxImage = [self createGrowBoxImage];
 210         growBoxWindow = [[JavaResizeGrowBoxOverlayWindow alloc] initWithContentRect:NSMakeRect(0, 0, [growBoxImage size].width, [growBoxImage size].height) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
 211         [self.growBoxWindow setIgnoresMouseEvents:YES];
 212         [self.growBoxWindow setOpaque:NO];
 213         [self.growBoxWindow setBackgroundColor:[NSColor clearColor]];
 214         [self.growBoxWindow setHasShadow:NO];
 215         [self.growBoxWindow setReleasedWhenClosed:NO];
 216 
 217         NSImageView *imageView = [[NSImageView alloc] initWithFrame:[self.growBoxWindow frame]];
 218         [imageView setEditable:NO];
 219         [imageView setAnimates:NO];
 220         [imageView setAllowsCutCopyPaste:NO];
 221         [self.growBoxWindow setContentView:imageView];
 222         [imageView setImage:growBoxImage];
 223         [growBoxImage release];
 224         [imageView release];
 225 
 226         [self addChildWindow:self.growBoxWindow ordered:NSWindowAbove];
 227         [self adjustGrowBoxWindow];
 228     } else growBoxWindow = nil;
 229 
 230     return self;
 231 }
 232 
 233 -(BOOL)  isTopmostWindowUnderMouse{
 234     
 235     int currentWinID = [self windowNumber]; 
 236     
 237     NSRect screenRect = [[NSScreen mainScreen] frame];    
 238     NSPoint nsMouseLocation = [NSEvent mouseLocation];
 239     CGPoint cgMouseLocation = CGPointMake(nsMouseLocation.x, screenRect.size.height - nsMouseLocation.y);    
 240     
 241     NSMutableArray *windows = (NSMutableArray *)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
 242     
 243     
 244     for (NSDictionary *window in windows) {
 245         int layer = [[window objectForKey:(id)kCGWindowLayer] intValue];
 246         if (layer == 0) {
 247             int winID = [[window objectForKey:(id)kCGWindowNumber] intValue];            
 248             CGRect rect;
 249             CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:(id)kCGWindowBounds], &rect);
 250             if(CGRectContainsPoint(rect, cgMouseLocation)){
 251                 return currentWinID == winID;
 252             }else if(currentWinID == winID){
 253                 return NO;
 254             }
 255         }
 256     }
 257     return NO;
 258 }
 259 
 260 - (void) synthesizeMouseEnteredExitedEvents{
 261     
 262     int eventType = 0;
 263     BOOL isUnderMouse = [self isTopmostWindowUnderMouse];
 264     BOOL mouseIsOver = [[self contentView] mouseIsOver];
 265     
 266     if(isUnderMouse && !mouseIsOver){
 267         eventType = NSMouseEntered;
 268     }else if(!isUnderMouse && mouseIsOver){
 269         eventType = NSMouseExited;        
 270     }else{
 271         return;
 272     }
 273     
 274     NSPoint screenLocation = [NSEvent mouseLocation];        
 275     NSPoint windowLocation = [self convertScreenToBase: screenLocation];        
 276     int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask;
 277     
 278     NSEvent * mouseEvent = [NSEvent 
 279                             enterExitEventWithType: eventType
 280                             location: windowLocation
 281                             modifierFlags: modifierFlags
 282                             timestamp: 0
 283                             windowNumber: [self windowNumber]
 284                             context: nil
 285                             eventNumber: 0
 286                             trackingNumber: 0
 287                             userData: nil
 288                             ];
 289     
 290     [[self contentView] deliverJavaMouseEvent: mouseEvent];
 291 }
 292 
 293 - (void) dealloc {
 294 AWT_ASSERT_APPKIT_THREAD;
 295 
 296     JNIEnv *env = [ThreadUtilities getJNIEnv];
 297     [self.javaPlatformWindow setJObject:nil withEnv:env];
 298     self.growBoxWindow = nil;
 299 
 300     [super dealloc];
 301 }
 302 
 303 
 304 // NSWindow overrides
 305 - (BOOL) canBecomeKeyWindow {
 306 AWT_ASSERT_APPKIT_THREAD;
 307     return IS(self.styleBits, SHOULD_BECOME_KEY);
 308 }
 309 
 310 - (BOOL) canBecomeMainWindow {
 311 AWT_ASSERT_APPKIT_THREAD;
 312     return IS(self.styleBits, SHOULD_BECOME_MAIN);
 313 }
 314 
 315 - (BOOL) worksWhenModal {
 316 AWT_ASSERT_APPKIT_THREAD;
 317     return IS(self.styleBits, MODAL_EXCLUDED);
 318 }
 319 
 320 
 321 // Gesture support
 322 - (void)postGesture:(NSEvent *)event as:(jint)type a:(jdouble)a b:(jdouble)b {
 323 AWT_ASSERT_APPKIT_THREAD;
 324 
 325     JNIEnv *env = [ThreadUtilities getJNIEnv];
 326     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 327     if (platformWindow != NULL) {
 328         // extract the target AWT Window object out of the CPlatformWindow
 329         static JNF_MEMBER_CACHE(jf_target, jc_CPlatformWindow, "target", "Ljava/awt/Window;");
 330         jobject awtWindow = JNFGetObjectField(env, platformWindow, jf_target);
 331         if (awtWindow != NULL) {
 332             // translate the point into Java coordinates
 333             NSPoint loc = [event locationInWindow];
 334             loc.y = [self frame].size.height - loc.y;
 335 
 336             // send up to the GestureHandler to recursively dispatch on the AWT event thread
 337             static JNF_CLASS_CACHE(jc_GestureHandler, "com/apple/eawt/event/GestureHandler");
 338             static JNF_STATIC_MEMBER_CACHE(sjm_handleGestureFromNative, jc_GestureHandler, "handleGestureFromNative", "(Ljava/awt/Window;IDDDD)V");
 339             JNFCallStaticVoidMethod(env, sjm_handleGestureFromNative, awtWindow, type, (jdouble)loc.x, (jdouble)loc.y, (jdouble)a, (jdouble)b);
 340             (*env)->DeleteLocalRef(env, awtWindow);
 341         }
 342         (*env)->DeleteLocalRef(env, platformWindow);
 343     }
 344 }
 345 
 346 - (void)beginGestureWithEvent:(NSEvent *)event {
 347     [self postGesture:event
 348                    as:com_apple_eawt_event_GestureHandler_PHASE
 349                     a:-1.0
 350                     b:0.0];
 351 }
 352 
 353 - (void)endGestureWithEvent:(NSEvent *)event {
 354     [self postGesture:event
 355                    as:com_apple_eawt_event_GestureHandler_PHASE
 356                     a:1.0
 357                     b:0.0];
 358 }
 359 
 360 - (void)magnifyWithEvent:(NSEvent *)event {
 361     [self postGesture:event
 362                    as:com_apple_eawt_event_GestureHandler_MAGNIFY
 363                     a:[event magnification]
 364                     b:0.0];
 365 }
 366 
 367 - (void)rotateWithEvent:(NSEvent *)event {
 368     [self postGesture:event
 369                    as:com_apple_eawt_event_GestureHandler_ROTATE
 370                     a:[event rotation]
 371                     b:0.0];
 372 }
 373 
 374 - (void)swipeWithEvent:(NSEvent *)event {
 375     [self postGesture:event
 376                    as:com_apple_eawt_event_GestureHandler_SWIPE
 377                     a:[event deltaX]
 378                     b:[event deltaY]];
 379 }
 380 
 381 
 382 // NSWindowDelegate methods
 383 
 384 - (void) adjustGrowBoxWindow {
 385     if (self.growBoxWindow != nil) {
 386         NSRect parentRect = [self frame];
 387         parentRect.origin.x += (parentRect.size.width - [self.growBoxWindow frame].size.width);
 388         [self.growBoxWindow setFrameOrigin:parentRect.origin];
 389     }
 390 }
 391 
 392 - (void) _deliverMoveResizeEvent {
 393 AWT_ASSERT_APPKIT_THREAD;
 394 
 395     // deliver the event if this is a user-initiated live resize or as a side-effect
 396     // of a Java initiated resize, because AppKit can override the bounds and force
 397     // the bounds of the window to avoid the Dock or remain on screen.
 398     [AWTToolkit eventCountPlusPlus];
 399     JNIEnv *env = [ThreadUtilities getJNIEnv];
 400     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 401     if (platformWindow == NULL) {
 402         // TODO: create generic AWT assert
 403     }
 404 
 405     [self adjustGrowBoxWindow];
 406 
 407     NSRect frame = ConvertNSScreenRect(env, [self frame]);
 408 
 409     static JNF_MEMBER_CACHE(jm_deliverMoveResizeEvent, jc_CPlatformWindow, "deliverMoveResizeEvent", "(IIII)V");
 410     JNFCallVoidMethod(env, platformWindow, jm_deliverMoveResizeEvent,
 411                       (jint)frame.origin.x,
 412                       (jint)frame.origin.y,
 413                       (jint)frame.size.width,
 414                       (jint)frame.size.height);
 415     (*env)->DeleteLocalRef(env, platformWindow);
 416 }
 417 
 418 - (void)windowDidMove:(NSNotification *)notification {
 419 AWT_ASSERT_APPKIT_THREAD;
 420 
 421     [self _deliverMoveResizeEvent];
 422 }
 423 
 424 - (void)windowDidResize:(NSNotification *)notification {
 425 AWT_ASSERT_APPKIT_THREAD;
 426 
 427     [self _deliverMoveResizeEvent];
 428 }
 429 
 430 - (void)windowDidExpose:(NSNotification *)notification {
 431 AWT_ASSERT_APPKIT_THREAD;
 432 
 433     [AWTToolkit eventCountPlusPlus];
 434     // TODO: don't see this callback invoked anytime so we track
 435     // window exposing in _setVisible:(BOOL)
 436 }
 437 
 438 - (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)proposedFrame {
 439 AWT_ASSERT_APPKIT_THREAD;
 440 
 441     [AWTToolkit eventCountPlusPlus];
 442     JNIEnv *env = [ThreadUtilities getJNIEnv];
 443     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 444     if (platformWindow != NULL) {
 445         static JNF_MEMBER_CACHE(jm_deliverZoom, jc_CPlatformWindow, "deliverZoom", "(Z)V");
 446         JNFCallVoidMethod(env, platformWindow, jm_deliverZoom, ![window isZoomed]);
 447         (*env)->DeleteLocalRef(env, platformWindow);
 448     }
 449     return YES;
 450 }
 451 
 452 - (void) _deliverIconify:(BOOL)iconify {
 453 AWT_ASSERT_APPKIT_THREAD;
 454 
 455     [AWTToolkit eventCountPlusPlus];
 456     JNIEnv *env = [ThreadUtilities getJNIEnv];
 457     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 458     if (platformWindow != NULL) {
 459         static JNF_MEMBER_CACHE(jm_deliverIconify, jc_CPlatformWindow, "deliverIconify", "(Z)V");
 460         JNFCallVoidMethod(env, platformWindow, jm_deliverIconify, iconify);
 461         (*env)->DeleteLocalRef(env, platformWindow);
 462     }
 463 }
 464 
 465 - (void)windowDidMiniaturize:(NSNotification *)notification {
 466 AWT_ASSERT_APPKIT_THREAD;
 467 
 468     [self _deliverIconify:JNI_TRUE];
 469 }
 470 
 471 - (void)windowDidDeminiaturize:(NSNotification *)notification {
 472 AWT_ASSERT_APPKIT_THREAD;
 473 
 474     [self _deliverIconify:JNI_FALSE];
 475 }
 476 
 477 - (void) _deliverWindowFocusEvent:(BOOL)focused {
 478 //AWT_ASSERT_APPKIT_THREAD;
 479 
 480     JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
 481     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 482     if (platformWindow != NULL) {
 483         static JNF_MEMBER_CACHE(jm_deliverWindowFocusEvent, jc_CPlatformWindow, "deliverWindowFocusEvent", "(Z)V");
 484         JNFCallVoidMethod(env, platformWindow, jm_deliverWindowFocusEvent, (jboolean)focused);
 485         (*env)->DeleteLocalRef(env, platformWindow);
 486     }
 487 }
 488 
 489 
 490 - (void) windowDidBecomeKey: (NSNotification *) notification {
 491 AWT_ASSERT_APPKIT_THREAD;
 492     [AWTToolkit eventCountPlusPlus];
 493     [CMenuBar activate:self.javaMenuBar modallyDisabled:NO];
 494     [self _deliverWindowFocusEvent:YES];
 495 }
 496 
 497 - (void) windowDidResignKey: (NSNotification *) notification {
 498     // TODO: check why sometimes at start is invoked *not* on AppKit main thread.
 499 AWT_ASSERT_APPKIT_THREAD;
 500     [AWTToolkit eventCountPlusPlus];
 501     [self.javaMenuBar deactivate];
 502     [self _deliverWindowFocusEvent:NO];
 503 }
 504 
 505 - (void) windowDidBecomeMain: (NSNotification *) notification {
 506 AWT_ASSERT_APPKIT_THREAD;
 507     [AWTToolkit eventCountPlusPlus];
 508 
 509     JNIEnv *env = [ThreadUtilities getJNIEnv];
 510     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 511     if (platformWindow != NULL) {
 512         static JNF_MEMBER_CACHE(jm_windowDidBecomeMain, jc_CPlatformWindow, "windowDidBecomeMain", "()V");
 513         JNFCallVoidMethod(env, platformWindow, jm_windowDidBecomeMain);
 514         (*env)->DeleteLocalRef(env, platformWindow);
 515     }
 516 }
 517 
 518 - (BOOL)windowShouldClose:(id)sender {
 519 AWT_ASSERT_APPKIT_THREAD;
 520     [AWTToolkit eventCountPlusPlus];
 521     JNIEnv *env = [ThreadUtilities getJNIEnv];
 522     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 523     if (platformWindow != NULL) {
 524         static JNF_MEMBER_CACHE(jm_deliverWindowClosingEvent, jc_CPlatformWindow, "deliverWindowClosingEvent", "()V");
 525         JNFCallVoidMethod(env, platformWindow, jm_deliverWindowClosingEvent);
 526         (*env)->DeleteLocalRef(env, platformWindow);
 527     }
 528     // The window will be closed (if allowed) as result of sending Java event
 529     return NO;
 530 }
 531 
 532 
 533 - (void)_notifyFullScreenOp:(jint)op withEnv:(JNIEnv *)env {
 534     static JNF_CLASS_CACHE(jc_FullScreenHandler, "com/apple/eawt/FullScreenHandler");
 535     static JNF_STATIC_MEMBER_CACHE(jm_notifyFullScreenOperation, jc_FullScreenHandler, "handleFullScreenEventFromNative", "(Ljava/awt/Window;I)V");
 536     static JNF_MEMBER_CACHE(jf_target, jc_CPlatformWindow, "target", "Ljava/awt/Window;");
 537     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 538     if (platformWindow != NULL) {
 539         jobject awtWindow = JNFGetObjectField(env, platformWindow, jf_target);
 540         if (awtWindow != NULL) {
 541             JNFCallStaticVoidMethod(env, jm_notifyFullScreenOperation, awtWindow, op);
 542             (*env)->DeleteLocalRef(env, awtWindow);
 543         }
 544         (*env)->DeleteLocalRef(env, platformWindow);
 545     }
 546 }
 547 
 548 
 549 - (void)windowWillEnterFullScreen:(NSNotification *)notification {
 550     static JNF_MEMBER_CACHE(jm_windowWillEnterFullScreen, jc_CPlatformWindow, "windowWillEnterFullScreen", "()V");
 551     JNIEnv *env = [ThreadUtilities getJNIEnv];
 552     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 553     if (platformWindow != NULL) {
 554         JNFCallVoidMethod(env, platformWindow, jm_windowWillEnterFullScreen);
 555         [self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_WILL_ENTER withEnv:env];
 556         (*env)->DeleteLocalRef(env, platformWindow);
 557     }
 558 }
 559 
 560 - (void)windowDidEnterFullScreen:(NSNotification *)notification {
 561     static JNF_MEMBER_CACHE(jm_windowDidEnterFullScreen, jc_CPlatformWindow, "windowDidEnterFullScreen", "()V");
 562     JNIEnv *env = [ThreadUtilities getJNIEnv];
 563     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 564     if (platformWindow != NULL) {
 565         JNFCallVoidMethod(env, platformWindow, jm_windowDidEnterFullScreen);
 566         [self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_DID_ENTER withEnv:env];
 567         (*env)->DeleteLocalRef(env, platformWindow);
 568     }
 569 }
 570 
 571 - (void)windowWillExitFullScreen:(NSNotification *)notification {
 572     static JNF_MEMBER_CACHE(jm_windowWillExitFullScreen, jc_CPlatformWindow, "windowWillExitFullScreen", "()V");
 573     JNIEnv *env = [ThreadUtilities getJNIEnv];
 574     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 575     if (platformWindow != NULL) {
 576         JNFCallVoidMethod(env, platformWindow, jm_windowWillExitFullScreen);
 577         [self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_WILL_EXIT withEnv:env];
 578         (*env)->DeleteLocalRef(env, platformWindow);
 579     }
 580 }
 581 
 582 - (void)windowDidExitFullScreen:(NSNotification *)notification {
 583     static JNF_MEMBER_CACHE(jm_windowDidExitFullScreen, jc_CPlatformWindow, "windowDidExitFullScreen", "()V");
 584     JNIEnv *env = [ThreadUtilities getJNIEnv];
 585     jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 586     if (platformWindow != NULL) {
 587         JNFCallVoidMethod(env, platformWindow, jm_windowDidExitFullScreen);
 588         [self _notifyFullScreenOp:com_apple_eawt_FullScreenHandler_FULLSCREEN_DID_EXIT withEnv:env];
 589         (*env)->DeleteLocalRef(env, platformWindow);
 590     }
 591 }
 592 
 593 - (void)sendEvent:(NSEvent *)event {
 594         if ([event type] == NSLeftMouseDown || [event type] == NSRightMouseDown || [event type] == NSOtherMouseDown) {
 595 
 596             NSPoint p = [NSEvent mouseLocation];
 597             NSRect frame = [self frame];
 598             NSRect contentRect = [self contentRectForFrameRect:frame];
 599 
 600             // Check if the click happened in the non-client area (title bar)
 601             if (p.y >= (frame.origin.y + contentRect.size.height)) {
 602                 JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
 603                 jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
 604                 // Currently, no need to deliver the whole NSEvent.
 605                 static JNF_MEMBER_CACHE(jm_deliverNCMouseDown, jc_CPlatformWindow, "deliverNCMouseDown", "()V");
 606                 JNFCallVoidMethod(env, platformWindow, jm_deliverNCMouseDown);
 607             }
 608         }
 609         [super sendEvent:event];
 610 }
 611 @end // AWTWindow
 612 
 613 
 614 /*
 615  * Class:     sun_lwawt_macosx_CPlatformWindow
 616  * Method:    nativeCreateNSWindow
 617  * Signature: (JJIIII)J
 618  */
 619 JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeCreateNSWindow
 620 (JNIEnv *env, jobject obj, jlong contentViewPtr, jlong styleBits, jdouble x, jdouble y, jdouble w, jdouble h)
 621 {
 622     __block AWTWindow *window = nil;
 623 
 624 JNF_COCOA_ENTER(env);
 625 AWT_ASSERT_NOT_APPKIT_THREAD;
 626 
 627     JNFWeakJObjectWrapper *platformWindow = [JNFWeakJObjectWrapper wrapperWithJObject:obj withEnv:env];
 628     NSView *contentView = OBJC(contentViewPtr);
 629     NSRect frameRect = NSMakeRect(x, y, w, h);
 630 
 631     [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
 632         AWT_ASSERT_APPKIT_THREAD;
 633 
 634         window = [[AWTWindow alloc] initWithPlatformWindow:platformWindow
 635                                                   styleBits:styleBits
 636                                                   frameRect:frameRect
 637                                                 contentView:contentView];
 638 
 639         if (window) CFRetain(window);
 640         [window release]; // GC
 641     }];
 642 
 643 JNF_COCOA_EXIT(env);
 644 
 645     return ptr_to_jlong(window);
 646 }
 647 
 648 /*
 649  * Class:     sun_lwawt_macosx_CPlatformWindow
 650  * Method:    nativeSetNSWindowStyleBits
 651  * Signature: (JII)V
 652  */
 653 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowStyleBits
 654 (JNIEnv *env, jclass clazz, jlong windowPtr, jint mask, jint bits)
 655 {
 656 JNF_COCOA_ENTER(env);
 657 AWT_ASSERT_NOT_APPKIT_THREAD;
 658 
 659     AWTWindow *window = OBJC(windowPtr);
 660     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 661         AWT_ASSERT_APPKIT_THREAD;
 662 
 663         // scans the bit field, and only updates the values requested by the mask
 664         // (this implicity handles the _CALLBACK_PROP_BITMASK case, since those are passive reads)
 665         jint newBits = window.styleBits & ~mask | bits & mask;
 666 
 667         // resets the NSWindow's style mask if the mask intersects any of those bits
 668         if (mask & MASK(_STYLE_PROP_BITMASK)) {
 669             [window setStyleMask:[AWTWindow styleMaskForStyleBits:newBits]];
 670         }
 671 
 672         // calls methods on NSWindow to change other properties, based on the mask
 673         if (mask & MASK(_METHOD_PROP_BITMASK)) {
 674             [window setPropertiesForStyleBits:bits mask:mask];
 675         }
 676 
 677         window.styleBits = newBits;
 678     }];
 679 
 680 JNF_COCOA_EXIT(env);
 681 }
 682 
 683 /*
 684  * Class:     sun_lwawt_macosx_CPlatformWindow
 685  * Method:    nativeSetNSWindowMenuBar
 686  * Signature: (JJ)V
 687  */
 688 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMenuBar
 689 (JNIEnv *env, jclass clazz, jlong windowPtr, jlong menuBarPtr)
 690 {
 691 JNF_COCOA_ENTER(env);
 692 AWT_ASSERT_NOT_APPKIT_THREAD;
 693 
 694     AWTWindow *window = OBJC(windowPtr);
 695     CMenuBar *menuBar = OBJC(menuBarPtr);
 696     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 697         AWT_ASSERT_APPKIT_THREAD;
 698 
 699         if ([window isKeyWindow]) [window.javaMenuBar deactivate];
 700         window.javaMenuBar = menuBar;
 701 
 702         // if ([self isKeyWindow]) {
 703         [CMenuBar activate:window.javaMenuBar modallyDisabled:NO];
 704         // }
 705     }];
 706 
 707 JNF_COCOA_EXIT(env);
 708 }
 709 
 710 /*
 711  * Class:     sun_lwawt_macosx_CPlatformWindow
 712  * Method:    nativeGetNSWindowInsets
 713  * Signature: (J)Ljava/awt/Insets;
 714  */
 715 JNIEXPORT jobject JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetNSWindowInsets
 716 (JNIEnv *env, jclass clazz, jlong windowPtr)
 717 {
 718     jobject ret = NULL;
 719 
 720 JNF_COCOA_ENTER(env);
 721 AWT_ASSERT_NOT_APPKIT_THREAD;
 722 
 723     AWTWindow *window = OBJC(windowPtr);
 724     __block NSRect contentRect = NSZeroRect;
 725     __block NSRect frame = NSZeroRect;
 726 
 727     [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
 728         AWT_ASSERT_APPKIT_THREAD;
 729 
 730         frame = [window frame];
 731         contentRect = [NSWindow contentRectForFrameRect:frame styleMask:[window styleMask]];
 732     }];
 733 
 734     jint top = (jint)(frame.size.height - contentRect.size.height);
 735     jint left = (jint)(contentRect.origin.x - frame.origin.x);
 736     jint bottom = (jint)(contentRect.origin.y - frame.origin.y);
 737     jint right = (jint)(frame.size.width - (contentRect.size.width + left));
 738 
 739     static JNF_CLASS_CACHE(jc_Insets, "java/awt/Insets");
 740     static JNF_CTOR_CACHE(jc_Insets_ctor, jc_Insets, "(IIII)V");
 741     ret = JNFNewObject(env, jc_Insets_ctor, top, left, bottom, right);
 742 
 743 JNF_COCOA_EXIT(env);
 744     return ret;
 745 }
 746 
 747 /*
 748  * Class:     sun_lwawt_macosx_CPlatformWindow
 749  * Method:    nativeSetNSWindowBounds
 750  * Signature: (JDDDD)V
 751  */
 752 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowBounds
 753 (JNIEnv *env, jclass clazz, jlong windowPtr, jdouble originX, jdouble originY, jdouble width, jdouble height)
 754 {
 755 JNF_COCOA_ENTER(env);
 756 AWT_ASSERT_NOT_APPKIT_THREAD;
 757 
 758     NSRect jrect = NSMakeRect(originX, originY, width, height);
 759 
 760     // TODO: not sure we need displayIfNeeded message in our view
 761     AWTWindow *window = OBJC(windowPtr);
 762     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 763         AWT_ASSERT_APPKIT_THREAD;
 764 
 765         NSRect rect = ConvertNSScreenRect(NULL, jrect);
 766         [window setFrame:rect display:YES];
 767 
 768         // only start tracking events if pointer is above the toplevel
 769         // TODO: should post an Entered event if YES.
 770         NSPoint mLocation = [NSEvent mouseLocation];
 771         [window setAcceptsMouseMovedEvents:NSPointInRect(mLocation, rect)];
 772 
 773         // ensure we repaint the whole window after the resize operation
 774         // (this will also re-enable screen updates, which were disabled above)
 775         // TODO: send PaintEvent
 776         
 777         [window synthesizeMouseEnteredExitedEvents];
 778     }];
 779 
 780 JNF_COCOA_EXIT(env);
 781 }
 782 
 783 /*
 784  * Class:     sun_lwawt_macosx_CPlatformWindow
 785  * Method:    nativeSetNSWindowMinMax
 786  * Signature: (JDDDD)V
 787  */
 788 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMinMax
 789 (JNIEnv *env, jclass clazz, jlong windowPtr, jdouble minW, jdouble minH, jdouble maxW, jdouble maxH)
 790 {
 791 JNF_COCOA_ENTER(env);
 792 AWT_ASSERT_NOT_APPKIT_THREAD;
 793 
 794     if (minW < 1) minW = 1;
 795     if (minH < 1) minH = 1;
 796     if (maxW < 1) maxW = 1;
 797     if (maxH < 1) maxH = 1;
 798 
 799     NSSize min = { minW, minH };
 800     NSSize max = { maxW, maxH };
 801 
 802     AWTWindow *window = OBJC(windowPtr);
 803     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 804         AWT_ASSERT_APPKIT_THREAD;
 805 
 806         window.javaMinSize = min;
 807         window.javaMaxSize = max;
 808         [window updateMinMaxSize:IS(window.styleBits, RESIZABLE)];
 809     }];
 810 
 811 JNF_COCOA_EXIT(env);
 812 }
 813 
 814 /*
 815  * Class:     sun_lwawt_macosx_CPlatformWindow
 816  * Method:    nativePushNSWindowToBack
 817  * Signature: (J)V
 818  */
 819 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativePushNSWindowToBack
 820 (JNIEnv *env, jclass clazz, jlong windowPtr)
 821 {
 822 JNF_COCOA_ENTER(env);
 823 AWT_ASSERT_NOT_APPKIT_THREAD;
 824 
 825     AWTWindow *window = OBJC(windowPtr);
 826     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 827         AWT_ASSERT_APPKIT_THREAD;
 828 
 829         [window orderBack:nil];
 830         [window synthesizeMouseEnteredExitedEvents];
 831     }];
 832 
 833 JNF_COCOA_EXIT(env);
 834 }
 835 
 836 /*
 837  * Class:     sun_lwawt_macosx_CPlatformWindow
 838  * Method:    nativePushNSWindowToFront
 839  * Signature: (J)V
 840  */
 841 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativePushNSWindowToFront
 842 (JNIEnv *env, jclass clazz, jlong windowPtr)
 843 {
 844 JNF_COCOA_ENTER(env);
 845 AWT_ASSERT_NOT_APPKIT_THREAD;
 846 
 847     AWTWindow *window = OBJC(windowPtr);
 848     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 849         AWT_ASSERT_APPKIT_THREAD;
 850 
 851         if (![window isKeyWindow]) {
 852             [window makeKeyAndOrderFront:window];
 853         } else {
 854             [window orderFront:window];
 855         }
 856         
 857         [window synthesizeMouseEnteredExitedEvents];
 858     }];
 859 
 860 JNF_COCOA_EXIT(env);
 861 }
 862 
 863 /*
 864  * Class:     sun_lwawt_macosx_CPlatformWindow
 865  * Method:    nativeSetNSWindowTitle
 866  * Signature: (JLjava/lang/String;)V
 867  */
 868 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowTitle
 869 (JNIEnv *env, jclass clazz, jlong windowPtr, jstring jtitle)
 870 {
 871 JNF_COCOA_ENTER(env);
 872 AWT_ASSERT_NOT_APPKIT_THREAD;
 873 
 874     AWTWindow *window = OBJC(windowPtr);
 875     [window performSelectorOnMainThread:@selector(setTitle:)
 876                               withObject:JNFJavaToNSString(env, jtitle)
 877                            waitUntilDone:NO];
 878 
 879 JNF_COCOA_EXIT(env);
 880 }
 881 
 882 /*
 883  * Class:     sun_lwawt_macosx_CPlatformWindow
 884  * Method:    nativeSetNSWindowAlpha
 885  * Signature: (JF)V
 886  */
 887 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowAlpha
 888 (JNIEnv *env, jclass clazz, jlong windowPtr, jfloat alpha)
 889 {
 890 JNF_COCOA_ENTER(env);
 891 AWT_ASSERT_NOT_APPKIT_THREAD;
 892 
 893     AWTWindow *window = OBJC(windowPtr);
 894     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 895         AWT_ASSERT_APPKIT_THREAD;
 896 
 897         [window setAlphaValue:alpha];
 898         [window.growBoxWindow setAlphaValue:alpha];
 899     }];
 900 
 901 JNF_COCOA_EXIT(env);
 902 }
 903 
 904 /*
 905  * Class:     sun_lwawt_macosx_CPlatformWindow
 906  * Method:    nativeRevalidateNSWindowShadow
 907  * Signature: (J)V
 908  */
 909 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeRevalidateNSWindowShadow
 910 (JNIEnv *env, jclass clazz, jlong windowPtr)
 911 {
 912 JNF_COCOA_ENTER(env);
 913 AWT_ASSERT_NOT_APPKIT_THREAD;
 914 
 915     AWTWindow *window = OBJC(windowPtr);
 916     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 917         AWT_ASSERT_APPKIT_THREAD;
 918 
 919         [window invalidateShadow];
 920     }];
 921 
 922 JNF_COCOA_EXIT(env);
 923 }
 924 
 925 /*
 926  * Class:     sun_lwawt_macosx_CPlatformWindow
 927  * Method:    nativeScreenOn_AppKitThread
 928  * Signature: (J)I
 929  */
 930 JNIEXPORT jint JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeScreenOn_1AppKitThread
 931 (JNIEnv *env, jclass clazz, jlong windowPtr)
 932 {
 933     jint ret = 0;
 934 
 935 JNF_COCOA_ENTER(env);
 936 AWT_ASSERT_APPKIT_THREAD;
 937 
 938     AWTWindow *window = OBJC(windowPtr);
 939     NSDictionary *props = [[window screen] deviceDescription];
 940     ret = [[props objectForKey:@"NSScreenNumber"] intValue];
 941 
 942 JNF_COCOA_EXIT(env);
 943 
 944     return ret;
 945 }
 946 
 947 /*
 948  * Class:     sun_lwawt_macosx_CPlatformWindow
 949  * Method:    nativeSetNSWindowMinimizedIcon
 950  * Signature: (JJ)V
 951  */
 952 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowMinimizedIcon
 953 (JNIEnv *env, jclass clazz, jlong windowPtr, jlong nsImagePtr)
 954 {
 955 JNF_COCOA_ENTER(env);
 956 AWT_ASSERT_NOT_APPKIT_THREAD;
 957 
 958     AWTWindow *window = OBJC(windowPtr);
 959     NSImage *image = OBJC(nsImagePtr);
 960     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 961         AWT_ASSERT_APPKIT_THREAD;
 962 
 963         [window setMiniwindowImage:image];
 964     }];
 965 
 966 JNF_COCOA_EXIT(env);
 967 }
 968 
 969 /*
 970  * Class:     sun_lwawt_macosx_CPlatformWindow
 971  * Method:    nativeSetNSWindowRepresentedFilename
 972  * Signature: (JLjava/lang/String;)V
 973  */
 974 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowRepresentedFilename
 975 (JNIEnv *env, jclass clazz, jlong windowPtr, jstring filename)
 976 {
 977 JNF_COCOA_ENTER(env);
 978 AWT_ASSERT_NOT_APPKIT_THREAD;
 979 
 980     AWTWindow *window = OBJC(windowPtr);
 981     NSURL *url = (filename == NULL) ? nil : [NSURL fileURLWithPath:JNFNormalizedNSStringForPath(env, filename)];
 982     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
 983         AWT_ASSERT_APPKIT_THREAD;
 984 
 985         [window setRepresentedURL:url];
 986     }];
 987 
 988 JNF_COCOA_EXIT(env);
 989 }
 990 
 991 /*
 992  * Class:     sun_lwawt_macosx_CPlatformWindow
 993  * Method:    nativeSetNSWindowSecurityWarningPositioning
 994  * Signature: (JDDFF)V
 995  */
 996 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowSecurityWarningPositioning
 997 (JNIEnv *env, jclass clazz, jlong windowPtr, jdouble x, jdouble y, jfloat biasX, jfloat biasY)
 998 {
 999 JNF_COCOA_ENTER(env);
1000 AWT_ASSERT_NOT_APPKIT_THREAD;
1001 
1002     [JNFException raise:env as:kRuntimeException reason:"unimplemented"];
1003 
1004 JNF_COCOA_EXIT(env);
1005 }
1006 
1007 /*
1008  * Class:     sun_lwawt_macosx_CPlatformWindow
1009  * Method:    nativeGetScreenNSWindowIsOn_AppKitThread
1010  * Signature: (J)I
1011  */
1012 JNIEXPORT jint JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetScreenNSWindowIsOn_1AppKitThread
1013 (JNIEnv *env, jclass clazz, jlong windowPtr)
1014 {
1015     jint index = -1;
1016 
1017 JNF_COCOA_ENTER(env);
1018 AWT_ASSERT_APPKIT_THREAD;
1019 
1020     AWTWindow *window = OBJC(windowPtr);
1021     NSScreen* screen = [window screen];
1022 
1023     //+++gdb NOTE: This is using a linear search of the screens. If it should
1024     //  prove to be a bottleneck, this can definitely be improved. However,
1025     //  many screens should prove to be the exception, rather than the rule.
1026     NSArray* screens = [NSScreen screens];
1027     NSUInteger i;
1028     for (i = 0; i < [screens count]; i++)
1029     {
1030         if ([[screens objectAtIndex:i] isEqualTo:screen])
1031         {
1032             index = i;
1033             break;
1034         }
1035     }
1036 
1037 JNF_COCOA_EXIT(env);
1038     return 1;
1039 }
1040 
1041 
1042 /*
1043  * Class:     sun_lwawt_macosx_CPlatformWindow
1044  * Method:    _toggleFullScreenMode
1045  * Signature: (J)V
1046  */
1047 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow__1toggleFullScreenMode
1048 (JNIEnv *env, jobject peer, jlong windowPtr)
1049 {
1050 JNF_COCOA_ENTER(env);
1051 
1052     AWTWindow *window = OBJC(windowPtr);
1053     SEL toggleFullScreenSelector = @selector(toggleFullScreen:);
1054     if (![window respondsToSelector:toggleFullScreenSelector]) return;
1055 
1056     [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
1057         [window performSelector:toggleFullScreenSelector withObject:nil];
1058     }];
1059 
1060 JNF_COCOA_EXIT(env);
1061 }
1062 
1063 JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CMouseInfoPeer_nativeIsWindowUnderMouse
1064 (JNIEnv *env, jclass clazz, jlong windowPtr)
1065 {
1066     __block jboolean underMouse = JNI_FALSE;
1067 
1068 JNF_COCOA_ENTER(env);
1069 AWT_ASSERT_NOT_APPKIT_THREAD;
1070 
1071     AWTWindow *aWindow = OBJC(windowPtr);
1072     [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^() {
1073         AWT_ASSERT_APPKIT_THREAD;
1074 
1075         NSPoint pt = [aWindow mouseLocationOutsideOfEventStream];
1076         underMouse = [[aWindow contentView] hitTest:pt] != nil;
1077     }];
1078 
1079 JNF_COCOA_EXIT(env);
1080 
1081     return underMouse;
1082 }