1 /*
   2  * Copyright (c) 2011, 2015, 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 "common.h"
  27 #import "com_sun_glass_events_ViewEvent.h"
  28 #import "com_sun_glass_events_WindowEvent.h"
  29 #import "com_sun_glass_ui_Window.h"
  30 #import "com_sun_glass_ui_Window_Level.h"
  31 #import "com_sun_glass_ui_mac_MacWindow.h"
  32 
  33 #import "GlassMacros.h"
  34 #import "GlassWindow.h"
  35 #import "GlassWindow+Java.h"
  36 #import "GlassWindow+Overrides.h"
  37 #import "GlassEmbeddedWindow+Overrides.h"
  38 #import "GlassView.h"
  39 #import "GlassScreen.h"
  40 #import "GlassTouches.h"
  41 #import "GlassApplication.h"
  42 #import "GlassLayer3D.h"
  43 #import "GlassHelper.h"
  44 
  45 //#define VERBOSE
  46 #ifndef VERBOSE
  47     #define LOG(MSG, ...)
  48 #else
  49     #define LOG(MSG, ...) GLASS_LOG(MSG, ## __VA_ARGS__);
  50 #endif
  51 
  52 #define BROWSER_PARENT_ID -1L
  53 
  54 #pragma mark --- Internal utilities
  55 
  56 static inline GlassWindow *getGlassWindow(JNIEnv *env, jlong jPtr)
  57 {
  58     assert(jPtr != 0L);
  59 
  60     NSWindow * nsWindow = (NSWindow*)jlong_to_ptr(jPtr);
  61     return (GlassWindow*)[nsWindow delegate];
  62 }
  63 
  64 static inline NSView<GlassView> *getMacView(JNIEnv *env, jobject jview)
  65 {
  66     if (jview != NULL)
  67     {
  68         jfieldID jfID = (*env)->GetFieldID(env, jViewClass, "ptr", "J");
  69         GLASS_CHECK_EXCEPTION(env);
  70         return (NSView<GlassView>*)jlong_to_ptr((*env)->GetLongField(env, jview, jfID));
  71     }
  72     else
  73     {
  74         return nil;
  75     }
  76 }
  77 
  78 // --------------------------------------------------------------------------------------
  79 // NSWindow/NSPanel descendants implementation
  80 #define GLASS_NS_WINDOW_IMPLEMENTATION                                                  \
  81 - (id)initWithDelegate:(GlassWindow*)delegate                                           \
  82              frameRect:(NSRect)rect                                                     \
  83              styleMask:(NSUInteger)styleMask                                            \
  84                 screen:(NSScreen*)screen                                                \
  85 {                                                                                       \
  86     self->gWindow = delegate; /* must be done before calling [super init...] */         \
  87     self = [super initWithContentRect:rect                                              \
  88                             styleMask:styleMask                                         \
  89                               backing:NSBackingStoreBuffered                            \
  90                                 defer:NO                                                \
  91                                screen:screen];                                          \
  92                                                                                         \
  93     if (self == nil) {                                                                  \
  94         return nil;                                                                     \
  95     }                                                                                   \
  96                                                                                         \
  97     [self setDelegate:delegate];                                                        \
  98     [self setAcceptsMouseMovedEvents:NO];                                               \
  99     [self setShowsResizeIndicator:NO];                                                  \
 100     [self setAllowsConcurrentViewDrawing:YES];                                          \
 101                                                                                         \
 102     [self setReleasedWhenClosed:YES];                                                   \
 103                                                                                         \
 104     return self;                                                                        \
 105 }                                                                                       \
 106                                                                                         \
 107 - (void)dealloc                                                                         \
 108 {                                                                                       \
 109     id window = self->gWindow;                                                          \
 110     [super dealloc];                                                                    \
 111     [window release];                                                                   \
 112 }                                                                                       \
 113                                                                                         \
 114 - (void)close                                                                           \
 115 {                                                                                       \
 116     self->gWindow->isClosed = YES;                                                      \
 117     [self->gWindow close];                                                              \
 118     [super close];                                                                      \
 119 }                                                                                       \
 120 /* super calls NSWindow on the next run-loop pass when NSWindow could be released */    \
 121 - (BOOL)performKeyEquivalent:(NSEvent *)theEvent                                        \
 122 {                                                                                       \
 123     [self retain];                                                                      \
 124     BOOL result = [super performKeyEquivalent:theEvent];                                \
 125     result = result || self->gWindow->isClosed;                                         \
 126     [self release];                                                                     \
 127     return result;                                                                      \
 128 }                                                                                       \
 129 - (BOOL)canBecomeMainWindow                                                             \
 130 {                                                                                       \
 131     return [self->gWindow canBecomeMainWindow];                                         \
 132 }                                                                                       \
 133 - (BOOL)canBecomeKeyWindow                                                              \
 134 {                                                                                       \
 135     return [self->gWindow canBecomeKeyWindow];                                          \
 136 }                                                                                       \
 137 - (void)setHidesOnDeactivate:(BOOL)hideOnDeactivate                                     \
 138 {                                                                                       \
 139     [super setHidesOnDeactivate:NO];                                                    \
 140 }                                                                                       \
 141 - (BOOL)hidesOnDeactivate                                                               \
 142 {                                                                                       \
 143     return [self->gWindow hidesOnDeactivate];                                           \
 144 }                                                                                       \
 145 - (BOOL)worksWhenModal                                                                  \
 146 {                                                                                       \
 147     return [self->gWindow worksWhenModal];                                              \
 148 }                                                                                       \
 149 - (void)setBackgroundColor:(NSColor *)color                                             \
 150 {                                                                                       \
 151     [super setBackgroundColor:[self->gWindow setBackgroundColor:color]];                \
 152 }                                                                                       \
 153 - (NSButton *)standardWindowButton:(NSWindowButton)type                                 \
 154 {                                                                                       \
 155     NSButton* button = [super standardWindowButton:type];                               \
 156     switch (type)                                                                       \
 157     {                                                                                   \
 158         case NSWindowDocumentIconButton:                                                \
 159             [button setAcceptsTouchEvents:NO];                                          \
 160             [button setAction:nil];                                                     \
 161             [button setEnabled:NO];                                                     \
 162             break;                                                                      \
 163     }                                                                                   \
 164     return button;                                                                      \
 165 }                                                                                       \
 166 - (void)sendEvent:(NSEvent *)event                                                      \
 167 {                                                                                       \
 168     /* Local copy of the id keeps the retain/release calls balanced. */                 \
 169     id view = [self->gWindow->view retain];                                             \
 170     [self->gWindow sendEvent:event];                                                    \
 171     [super sendEvent:event];                                                            \
 172     [view release];                                                                     \
 173 }
 174 
 175 @implementation GlassWindow_Normal
 176 GLASS_NS_WINDOW_IMPLEMENTATION
 177 @end
 178 
 179 @implementation GlassWindow_Panel
 180 GLASS_NS_WINDOW_IMPLEMENTATION
 181 
 182 - (void)setWorksWhenModal:(BOOL)worksWhenModal
 183 {
 184     [super setWorksWhenModal:NO];
 185 }
 186 
 187 - (BOOL)accessibilityIsIgnored
 188 {
 189     /* In JavaFX NSPanels are used to implement PopupWindows,
 190      * which are used by ContextMenu.  In Accessibility, for a
 191      * menu to work as expected, the window has to be ignored.
 192      * Note that asking the children of the window is
 193      * very important in this context. It ensures that all
 194      * descendants created.  Without it, the menu  will
 195      * not be seen by the assistive technology.
 196      */
 197     __block BOOL ignored = [super accessibilityIsIgnored];
 198     NSArray* children = [self accessibilityAttributeValue: NSAccessibilityChildrenAttribute];
 199     if (children) {
 200         [children enumerateObjectsUsingBlock: ^(id child, NSUInteger index, BOOL *stop) {
 201             NSString* role = [child accessibilityAttributeValue: NSAccessibilityRoleAttribute];
 202             if ([NSAccessibilityMenuRole isEqualToString: role]) {
 203                 ignored = YES;
 204                 *stop = YES;
 205             }
 206             /* Tooltips are exposed by AXHelp attribute and there is no API in Mac
 207              * to represent the tooltip window.
 208              * Nonetheless, the window must be ignored to prevent interfering with
 209              * VoiceOver focus.
 210              */
 211             if ([@"AXJFXTOOLTIP" isEqualToString: role]) {
 212                 ignored = YES;
 213                 *stop = YES;
 214             }
 215         }];
 216     }
 217     return ignored;
 218 }
 219 
 220 - (id)accessibilityAttributeValue:(NSString *)attribute
 221 {
 222     /* 
 223     * The default value of AXRoleDescription for a NSPanel is 'system dialog'.
 224     * While this is correct for an average cocoa application it is not appropriate
 225     * for JFX, where all NSPanels are decoration-less windows used to implement 
 226     * tooltip, context menus, combo boxes, etc.
 227     */
 228     if ([NSAccessibilityRoleDescriptionAttribute isEqualToString: attribute]) {
 229         return @"";
 230     }
 231     return [super accessibilityAttributeValue: attribute];
 232 }
 233 
 234 @end
 235 // --------------------------------------------------------------------------------------
 236 
 237 
 238 @implementation GlassWindow
 239 
 240 - (void)setFullscreenWindow:(NSWindow*)fsWindow
 241 {
 242     if (self->fullscreenWindow == fsWindow) {
 243         return;
 244     }
 245     
 246     [self _ungrabFocus];
 247     
 248     NSWindow *from, *to;
 249     from = self->fullscreenWindow ? self->fullscreenWindow : self->nsWindow;
 250     to = fsWindow ? fsWindow : self->nsWindow;
 251     
 252     NSArray * children = [from childWindows];
 253     for (NSUInteger i=0; i<[children count]; i++)
 254     {
 255         NSWindow *child = (NSWindow*)[children objectAtIndex:i];
 256         if ([[child delegate] isKindOfClass: [GlassWindow class]]) {
 257             [from removeChildWindow: child];
 258             [to addChildWindow:child ordered:NSWindowAbove];
 259         }
 260     }
 261     
 262     self->fullscreenWindow = fsWindow;
 263     
 264     GET_MAIN_JENV;
 265     (*env)->CallVoidMethod(env, self->jWindow, jWindowNotifyDelegatePtr, ptr_to_jlong(fsWindow));
 266     GLASS_CHECK_EXCEPTION(env);
 267 }
 268 
 269 - (void)close
 270 {
 271     [self _ungrabFocus];
 272 }
 273 
 274 - (void)sendEvent:(NSEvent *)event
 275 {
 276     if ([event type] == NSLeftMouseDown || [event type] == NSRightMouseDown || [event type] == NSOtherMouseDown)
 277     {
 278         NSPoint p = [NSEvent mouseLocation];
 279         NSRect frame = [self->nsWindow frame];
 280         NSRect contentRect = [self->nsWindow contentRectForFrameRect:frame];
 281         
 282         if (p.y >= (frame.origin.y + contentRect.size.height))
 283         {
 284             // Click to the titlebar
 285             [self _ungrabFocus];
 286         }
 287         
 288         [self _checkUngrab];
 289     }
 290 }
 291 
 292 // Window vs Panel API
 293 - (BOOL)canBecomeMainWindow
 294 {
 295     if (!self->isEnabled)
 296     {
 297         // We'll send FOCUS_DISABLED
 298         return YES;
 299     }
 300     return self->isFocusable;
 301 }
 302 
 303 // Window vs Panel API
 304 - (BOOL)hidesOnDeactivate
 305 {
 306     return NO;
 307 }
 308 
 309 // Window vs Panel API
 310 - (BOOL)worksWhenModal
 311 {
 312     return NO;
 313 }
 314 
 315 - (BOOL)canBecomeKeyWindow
 316 {
 317     if (!self->isEnabled)
 318     {
 319         // We'll send FOCUS_DISABLED
 320         return YES;
 321     }
 322     return self->isFocusable;
 323 }
 324 
 325 - (NSColor*)setBackgroundColor:(NSColor *)color
 326 {
 327     if (self->isTransparent == NO)
 328     {
 329         // allow color if we're opaque
 330         return color;
 331     }
 332     else
 333     {
 334         // for transparent window, ignore and set to clear color
 335         // FIXME: do we want to store the background color in case we switch to non-transparent mode?
 336         return [NSColor clearColor];
 337     }
 338 }
 339 
 340 
 341 @end
 342 
 343 #pragma mark --- GlassEmbeddedWindow
 344 
 345 static NSMutableArray * embeddedWindowsList = nil;
 346 
 347 @implementation GlassEmbeddedWindow
 348 
 349 - (id)initWithDelegate:(GlassWindow*)delegate
 350              frameRect:(NSRect)rect
 351              styleMask:(NSUInteger)styleMask
 352                 screen:(NSScreen*)screen
 353 {
 354     self = [super initWithDelegate:delegate frameRect:rect styleMask:styleMask screen:screen];
 355     if (self == nil) {
 356         return nil;
 357     }
 358 
 359     if (embeddedWindowsList == nil) {
 360         embeddedWindowsList = [[NSMutableArray alloc] initWithCapacity: 4];
 361     }
 362     [embeddedWindowsList addObject:self]; // retains 'self'
 363 
 364     return self;
 365 }
 366 
 367 - (void)close
 368 {
 369     if (embeddedWindowsList) {
 370         [embeddedWindowsList removeObject:self]; // releases 'self'
 371         if ([embeddedWindowsList count] == 0) {
 372             [embeddedWindowsList release];
 373             embeddedWindowsList = nil;
 374         }
 375     }
 376     [super close];
 377 }
 378 
 379 + (BOOL)exists:(GlassEmbeddedWindow*)window
 380 {
 381     if (embeddedWindowsList && window) {
 382         return [embeddedWindowsList indexOfObjectIdenticalTo:window] != NSNotFound;
 383     }
 384     return NO;
 385 }
 386 
 387 - (void)setFullscreenWindow:(NSWindow*)fsWindow
 388 {
 389     if (self->parent != nil)
 390     {
 391         BOOL fullscreen = (fsWindow != nil);
 392         
 393         CALayer *layer = [self->gWindow->view layer];
 394         if ([layer isKindOfClass:[GlassLayer3D class]] == YES)
 395         {
 396             [((CAOpenGLLayer*)layer) setAsynchronous:fullscreen];
 397             
 398             layer = [self->parent->gWindow->view layer];
 399             if ([layer isKindOfClass:[GlassLayer3D class]] == YES)
 400             {
 401                 [((CAOpenGLLayer*)layer) setAsynchronous:!fullscreen];
 402             }
 403         }
 404         
 405         self->fullscreenWindow = fsWindow;
 406     }
 407 }
 408 
 409 - (void)sendEvent:(NSEvent *)theEvent
 410 {
 411     BOOL fullscreen = (self->fullscreenWindow != nil);
 412     if (fullscreen == NO)
 413     {
 414         [super sendEvent:theEvent];
 415     }
 416     else
 417     {
 418         [self->fullscreenWindow sendEvent:theEvent];
 419     }
 420 }
 421 
 422 
 423 @end
 424 
 425 #pragma mark --- Dispatcher
 426 
 427 // TODO: re-implement using Obj-C blocks ?
 428 static jlong _createWindowCommonDo(JNIEnv *env, jobject jWindow, jlong jOwnerPtr, jlong jScreenPtr, jint jStyleMask, jboolean jIsChild)
 429 {
 430     GlassWindow *window = nil;
 431     
 432     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 433     {
 434         NSUInteger styleMask = NSBorderlessWindowMask;
 435         // only titled windows get title
 436         if ((jStyleMask&com_sun_glass_ui_Window_TITLED) != 0)
 437         {
 438             styleMask = styleMask|NSTitledWindowMask;
 439         }
 440         // only nontransparent windows get decorations
 441         if ((jStyleMask&com_sun_glass_ui_Window_TRANSPARENT) == 0)
 442         {
 443             if ((jStyleMask&com_sun_glass_ui_Window_CLOSABLE) != 0)
 444             {
 445                 styleMask = styleMask|NSClosableWindowMask;
 446             }
 447             
 448             if (((jStyleMask&com_sun_glass_ui_Window_MINIMIZABLE) != 0) ||
 449                 ((jStyleMask&com_sun_glass_ui_Window_MAXIMIZABLE) != 0))
 450             {
 451                 // on Mac OS X there is one set for min/max buttons,
 452                 // so if clients requests either one, we turn them both on
 453                 styleMask = styleMask|NSMiniaturizableWindowMask;
 454             }
 455             
 456             if ((jStyleMask&com_sun_glass_ui_Window_UNIFIED) != 0) {
 457                 styleMask = styleMask|NSTexturedBackgroundWindowMask;
 458             }
 459             
 460             if ((jStyleMask&com_sun_glass_ui_Window_UTILITY) != 0)
 461             {
 462                 styleMask = styleMask | NSUtilityWindowMask | NSNonactivatingPanelMask;
 463             }
 464         }
 465 
 466         if ((jStyleMask&com_sun_glass_ui_Window_POPUP) != 0)
 467         {
 468             // can receive keyboard input without activating the owning application
 469             styleMask = styleMask|NSNonactivatingPanelMask;
 470         }
 471 
 472         // initial size must be 0x0 otherwise we don't get resize update if the initial size happens to be the exact same size as the later programatical one!
 473         CGFloat x = 0.0f;
 474         CGFloat y = 0.0f;
 475         CGFloat w = 0.0f;
 476         CGFloat h = 0.0f;
 477         
 478         NSScreen *screen = (NSScreen*)jlong_to_ptr(jScreenPtr);
 479         window = [[GlassWindow alloc] _initWithContentRect:NSMakeRect(x, y, w, h) styleMask:styleMask screen:screen jwindow:jWindow jIsChild:jIsChild];
 480         
 481         if ((jStyleMask & com_sun_glass_ui_Window_UNIFIED) != 0) {
 482             //Prevent the textured effect from disappearing on border thickness recalculation
 483             [window->nsWindow setAutorecalculatesContentBorderThickness:NO forEdge:NSMaxYEdge];
 484         }
 485 
 486         if ((jStyleMask & com_sun_glass_ui_Window_UTILITY) != 0) {
 487             [[window->nsWindow standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES];
 488             [[window->nsWindow standardWindowButton:NSWindowZoomButton] setHidden:YES];
 489         }
 490 
 491         if (jIsChild == JNI_FALSE)
 492         {
 493             if (jOwnerPtr != 0L)
 494             {
 495                 window->owner = getGlassWindow(env, jOwnerPtr)->nsWindow; // not retained (use weak reference?)
 496             }
 497         }
 498         else
 499         {
 500             if ((jOwnerPtr != 0L) && (jOwnerPtr != BROWSER_PARENT_ID))
 501             {
 502                 GlassEmbeddedWindow *parent = getGlassEmbeddedWindow(env, jOwnerPtr);
 503                 GlassEmbeddedWindow *ewindow = (GlassEmbeddedWindow*)window->nsWindow;
 504                 parent->child = ewindow; // not retained (use weak reference?)
 505                 
 506                 ewindow->parent = parent; // not retained (use weak reference?)
 507             }
 508         }
 509         window->isResizable = NO;
 510         window->isDecorated = (jStyleMask&com_sun_glass_ui_Window_TITLED) != 0;
 511         /* 10.7 full screen window support */ 
 512         if ([NSWindow instancesRespondToSelector:@selector(toggleFullScreen:)]) {
 513             NSWindowCollectionBehavior behavior = [window->nsWindow collectionBehavior];
 514             if (window->isDecorated && !window->owner)
 515             {
 516                 // Only titled ownerless windows should have the Full Screen Toggle control
 517                 behavior |= (1 << 7) /* NSWindowCollectionBehaviorFullScreenPrimary */;
 518             }
 519             else
 520             {
 521                 // Other windows are only allowed to be shown together with a primary
 522                 // full screen window
 523                 behavior |= (1 << 8) /* NSWindowCollectionBehaviorFullScreenAuxiliary */;
 524             }
 525             [window->nsWindow setCollectionBehavior: behavior];
 526         }
 527         
 528         window->isTransparent = (jStyleMask & com_sun_glass_ui_Window_TRANSPARENT) != 0;
 529         if (window->isTransparent == YES)
 530         {
 531             [window->nsWindow setBackgroundColor:[NSColor clearColor]];
 532             [window->nsWindow setHasShadow:NO];
 533             [window->nsWindow setOpaque:NO];
 534         }
 535         else
 536         {
 537             [window->nsWindow setHasShadow:YES];
 538             [window->nsWindow setOpaque:YES];
 539         }
 540         
 541         window->fullscreenWindow = nil;
 542 
 543         window->isSizeAssigned = NO;
 544         window->isLocationAssigned = NO;
 545 
 546         if (jIsChild == JNI_TRUE && jOwnerPtr != 0L && jOwnerPtr != BROWSER_PARENT_ID
 547             && [window->nsWindow isKindOfClass:[GlassEmbeddedWindow class]])
 548         {
 549             GlassEmbeddedWindow* parent = ((GlassEmbeddedWindow*)window->nsWindow)->parent;
 550             if ([GlassEmbeddedWindow exists:parent])
 551             {
 552                 window->isLocationAssigned = YES;
 553                 [window _setBounds:(int)round(parent.frame.origin.x)
 554                                  y:(int)round(parent.frame.origin.y)
 555                               xSet:YES ySet:YES w:0 h:0 cw:0 ch:0];
 556             }
 557         }
 558     }
 559     [pool drain];
 560     
 561     GLASS_CHECK_EXCEPTION(env);
 562     
 563     return ptr_to_jlong(window->nsWindow);
 564 }
 565 
 566 static jlong _createWindowCommon
 567 (JNIEnv *env, jobject jWindow, jlong jOwnerPtr, jlong jScreenPtr, jint jStyleMask, jboolean jIsChild)
 568 {
 569     LOG("_createWindowCommon");
 570     
 571     jlong value = 0L;
 572     
 573     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 574     GLASS_POOL_ENTER;
 575     {
 576         jobject jWindowRef = (*env)->NewGlobalRef(env, jWindow);
 577         value = _createWindowCommonDo(env, jWindowRef, jOwnerPtr, jScreenPtr, jStyleMask, jIsChild);
 578     }
 579     GLASS_POOL_EXIT;
 580     GLASS_CHECK_EXCEPTION(env);
 581     
 582     LOG("   window: %p", value);
 583     return value;
 584 }
 585 
 586 #pragma mark --- JNI
 587 
 588 /*
 589  * Class:     com_sun_glass_ui_mac_MacWindow
 590  * Method:    _initIDs
 591  * Signature: ()V
 592  */
 593 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1initIDs
 594 (JNIEnv *env, jclass jClass)
 595 {
 596     LOG("Java_com_sun_glass_ui_mac_MacWindow__1initIDs");
 597     
 598     if (jWindowClass == NULL)
 599     {
 600         jWindowClass = (*env)->NewGlobalRef(env, jClass);
 601     }
 602     
 603     if (jMenuBarDelegateClass == NULL)
 604     {
 605         jMenuBarDelegateClass = (*env)->NewGlobalRef(env, [GlassHelper ClassForName:"com.sun.glass.ui.mac.MacMenuBarDelegate" withEnv:env]);
 606     }
 607     
 608     if (jViewClass == NULL)
 609     {
 610         jViewClass = (*env)->NewGlobalRef(env, [GlassHelper ClassForName:"com.sun.glass.ui.View" withEnv:env]);
 611     }
 612     
 613     if (jScreenClass == NULL)
 614     {
 615         jScreenClass = (*env)->NewGlobalRef(env, [GlassHelper ClassForName:"com.sun.glass.ui.Screen" withEnv:env]);
 616     }
 617     
 618     if (jWindowNotifyMove == NULL)
 619     {
 620         jWindowNotifyMove = (*env)->GetMethodID(env, jWindowClass, "notifyMove", "(II)V");
 621         if ((*env)->ExceptionCheck(env)) return;
 622     }
 623     
 624     if (jWindowNotifyResize == NULL)
 625     {
 626         jWindowNotifyResize = (*env)->GetMethodID(env, jWindowClass, "notifyResize", "(III)V");
 627         if ((*env)->ExceptionCheck(env)) return;
 628     }
 629     
 630     if (jWindowNotifyMoveToAnotherScreen == NULL)
 631     {
 632         jWindowNotifyMoveToAnotherScreen = (*env)->GetMethodID(env, jWindowClass, "notifyMoveToAnotherScreen", "(Lcom/sun/glass/ui/Screen;)V");
 633         if ((*env)->ExceptionCheck(env)) return;
 634     }
 635     
 636     if (jWindowNotifyClose == NULL)
 637     {
 638         jWindowNotifyClose = (*env)->GetMethodID(env, jWindowClass, "notifyClose", "()V");
 639         if ((*env)->ExceptionCheck(env)) return;
 640     }
 641     
 642     if (jWindowNotifyFocus == NULL)
 643     {
 644         jWindowNotifyFocus = (*env)->GetMethodID(env, jWindowClass, "notifyFocus", "(I)V");
 645         if ((*env)->ExceptionCheck(env)) return;
 646     }
 647     
 648     if (jWindowNotifyFocusUngrab == NULL)
 649     {
 650         jWindowNotifyFocusUngrab = (*env)->GetMethodID(env, jWindowClass, "notifyFocusUngrab", "()V");
 651         if ((*env)->ExceptionCheck(env)) return;
 652     }
 653     
 654     if (jWindowNotifyFocusDisabled == NULL)
 655     {
 656         jWindowNotifyFocusDisabled = (*env)->GetMethodID(env, jWindowClass, "notifyFocusDisabled", "()V");
 657         if ((*env)->ExceptionCheck(env)) return;
 658     }
 659     
 660     if (jWindowNotifyDestroy == NULL)
 661     {
 662         jWindowNotifyDestroy = (*env)->GetMethodID(env, jWindowClass, "notifyDestroy", "()V");
 663         if ((*env)->ExceptionCheck(env)) return;
 664     }
 665     
 666     if (jWindowNotifyDelegatePtr == NULL)
 667     {
 668         jWindowNotifyDelegatePtr = (*env)->GetMethodID(env, jWindowClass, "notifyDelegatePtr", "(J)V");
 669     }
 670 }
 671 
 672 /*
 673  * Class:     com_sun_glass_ui_mac_MacWindow
 674  * Method:    _createWindow
 675  * Signature: (JJI)J
 676  */
 677 JNIEXPORT jlong JNICALL Java_com_sun_glass_ui_mac_MacWindow__1createWindow
 678 (JNIEnv *env, jobject jWindow, jlong jOwnerPtr, jlong jScreenPtr, jint jStyleMask)
 679 {
 680     LOG("Java_com_sun_glass_ui_mac_MacWindow__1createWindow");
 681     
 682     return _createWindowCommon(env, jWindow, jOwnerPtr, jScreenPtr, jStyleMask, JNI_FALSE);
 683 }
 684 
 685 /*
 686  * Class:     com_sun_glass_ui_mac_MacWindow
 687  * Method:    _createChildWindow
 688  * Signature: (J)J
 689  */
 690 JNIEXPORT jlong JNICALL Java_com_sun_glass_ui_mac_MacWindow__1createChildWindow
 691 (JNIEnv *env, jobject jWindow, jlong jOwnerPtr)
 692 {
 693     LOG("Java_com_sun_glass_ui_mac_MacWindow__1createChildWindow");
 694     LOG("   owner: %p", jOwnerPtr);
 695     
 696     jlong jScreenPtr = 0L;
 697     jint jStyleMask = NSBorderlessWindowMask;
 698     if (jOwnerPtr == BROWSER_PARENT_ID)
 699     {
 700         LOG("       case PARENT (PLUGIN)");
 701         // special case: embedded window for plugin (the container which will hold the child window)
 702     }
 703     else
 704     {
 705         LOG("       case CHILD (EMBEDDED)");
 706         // special case: embedded window for plugin (the actual plugin window with remote layer)
 707         // jOwnerPtr must be a valid GlassEmbeddedWindow instance
 708         if (![GlassEmbeddedWindow exists:(GlassEmbeddedWindow*)jlong_to_ptr(jOwnerPtr)]) {
 709             return (jlong)0;
 710         }
 711     }
 712     
 713     return _createWindowCommon(env, jWindow, jOwnerPtr, jScreenPtr, jStyleMask, JNI_TRUE);
 714 }
 715 
 716 /*
 717  * Class:     com_sun_glass_ui_mac_MacWindow
 718  * Method:    _setLevel
 719  * Signature: (JI)V
 720  */
 721 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setLevel
 722 (JNIEnv *env, jobject jWindow, jlong jPtr, jint jLevel)
 723 {
 724     LOG("Java_com_sun_glass_ui_mac_MacWindow__1setLevel");
 725     if (!jPtr) return;
 726     
 727     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 728     GLASS_POOL_ENTER;
 729     {
 730         GlassWindow *window = getGlassWindow(env, jPtr);
 731         NSInteger level = NSNormalWindowLevel;
 732         switch (jLevel)
 733         {
 734             case com_sun_glass_ui_Window_Level_FLOATING:
 735                 level = NSFloatingWindowLevel;
 736                 break;
 737             case com_sun_glass_ui_Window_Level_TOPMOST:
 738                 level = NSScreenSaverWindowLevel;
 739                 break;
 740         }
 741         [window->nsWindow setLevel:level];
 742     }
 743     GLASS_POOL_EXIT;
 744     GLASS_CHECK_EXCEPTION(env);
 745 }
 746 
 747 /*
 748  * Class:     com_sun_glass_ui_mac_MacWindow
 749  * Method:    _setFocusable
 750  * Signature: (Z)V
 751  */
 752 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setFocusable
 753 (JNIEnv *env, jobject jWindow, jlong jPtr, jboolean isFocusable)
 754 {
 755     LOG("Java_com_sun_glass_ui_mac_MacWindow__1setCanBecomeActive");
 756     if (!jPtr) return;
 757     
 758     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 759     GLASS_POOL_ENTER;
 760     {
 761         GlassWindow *window = getGlassWindow(env, jPtr);
 762         window->isFocusable = (isFocusable==JNI_TRUE);
 763     }
 764     GLASS_POOL_EXIT;
 765     GLASS_CHECK_EXCEPTION(env);
 766 }
 767 
 768 /*
 769  * Class:     com_sun_glass_ui_mac_MacWindow
 770  * Method:    _setEnabled
 771  * Signature: (JZ)V
 772  */
 773 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setEnabled
 774 (JNIEnv *env, jobject jwindow, jlong jPtr, jboolean isEnabled)
 775 {
 776     LOG("Java_com_sun_glass_ui_mac_MacWindow__1setEnabled");
 777     if (!jPtr) return;
 778     
 779     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 780     GLASS_POOL_ENTER;
 781     {
 782         GlassWindow *window = getGlassWindow(env, jPtr);
 783         window->isEnabled = (BOOL)isEnabled;
 784 
 785         if (!window->isEnabled) {
 786             window->enabledStyleMask = [window->nsWindow styleMask];
 787             [window->nsWindow setStyleMask: (window->enabledStyleMask & ~(NSUInteger)(NSMiniaturizableWindowMask | NSResizableWindowMask))];
 788 
 789             //XXX: perhaps we could simply enable/disable the buttons w/o playing with the styles at all
 790             NSButton *zoomButton = [window->nsWindow standardWindowButton:NSWindowZoomButton];
 791             [zoomButton setEnabled:NO];
 792         } else {
 793             [window->nsWindow setStyleMask: window->enabledStyleMask];
 794 
 795             if (window->enabledStyleMask & NSResizableWindowMask) {
 796                 NSButton *zoomButton = [window->nsWindow standardWindowButton:NSWindowZoomButton];
 797                 [zoomButton setEnabled:YES];
 798             }
 799         }
 800     }
 801     GLASS_POOL_EXIT;
 802     GLASS_CHECK_EXCEPTION(env);
 803 }
 804 
 805 /*                                                                                                     
 806  * Class:     com_sun_glass_ui_mac_MacWindow                                                     
 807  * Method:    _setAlpha                                                                                
 808  * Signature: (F)V                                                                                     
 809  */
 810 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setAlpha
 811 (JNIEnv *env, jobject jWindow, jlong jPtr, jfloat jAlpha)
 812 {
 813     LOG("Java_com_sun_glass_ui_mac_MacWindow__1setAlpha");
 814     if (!jPtr) return;
 815     
 816     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 817     GLASS_POOL_ENTER;
 818     {
 819         GlassWindow *window = getGlassWindow(env, jPtr);
 820         [window->nsWindow setAlphaValue:jAlpha];
 821     }
 822     GLASS_POOL_EXIT;
 823     GLASS_CHECK_EXCEPTION(env);
 824 }
 825 
 826 /*                                                                                                     
 827  * Class:     com_sun_glass_ui_mac_MacWindow                                                     
 828  * Method:    _setBackground
 829  * Signature: (JFFF)Z                                                                           
 830  */
 831 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setBackground
 832 (JNIEnv *env, jobject jWindow, jlong jPtr, jfloat r, jfloat g, jfloat b)
 833 {
 834     LOG("Java_com_sun_glass_ui_mac_MacWindow__1setBackground");
 835     if (!jPtr) return JNI_FALSE;
 836     
 837     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 838     GLASS_POOL_ENTER;
 839     {
 840         GlassWindow *window = getGlassWindow(env, jPtr);
 841         [window->nsWindow setBackgroundColor:[NSColor colorWithCalibratedRed:r green:g blue:b alpha:1.0f]];
 842     }
 843     GLASS_POOL_EXIT;
 844     GLASS_CHECK_EXCEPTION(env);
 845     
 846     return JNI_TRUE; // gznote: remove this return value if unused
 847 }
 848 
 849 /*
 850  * Class:     com_sun_glass_ui_mac_MacWindow                                                     
 851  * Method:    _setView                                                                                 
 852  * Signature: (J)Z                                        
 853  */
 854 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setView
 855 (JNIEnv *env, jobject jWindow, jlong jPtr, jobject jview)
 856 {
 857     LOG("Java_com_sun_glass_ui_mac_MacWindow__1setView");
 858     LOG("   window: %p", jPtr);
 859     LOG("   view: %p", getMacView(env, jview));
 860     if (!jPtr) return JNI_FALSE;
 861     
 862     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 863     GLASS_POOL_ENTER;
 864     {
 865         GlassWindow *window = getGlassWindow(env, jPtr);
 866 
 867         // We don't support changing views in the FS mode because
 868         // by Glass design the FS functionality belongs to the View.
 869         // Also, this leads to a crash on the Mac
 870         if ([window->nsWindow styleMask] & (1 << 14)/*NSFullScreenWindowMask*/) {
 871             [window->nsWindow performSelector:@selector(toggleFullScreen:) withObject:nil];
 872 
 873             // Wait until the FS mode has really exited
 874             [GlassApplication enterFullScreenExitingLoop];
 875         }
 876 
 877         NSView<GlassView> *oldView = window->view;
 878         window->view = getMacView(env, jview);
 879         //NSLog(@"        window: %@", window);
 880         //NSLog(@"                frame: %.2f,%.2f %.2fx%.2f", [window frame].origin.x, [window frame].origin.y, [window frame].size.width, [window frame].size.height);
 881         //NSLog(@"        view: %@", window->view);
 882         //NSLog(@"                frame: %.2f,%.2f %.2fx%.2f", [window->view frame].origin.x, [window->view frame].origin.y, [window->view frame].size.width, [window->view frame].size.height);
 883 
 884         if (oldView && oldView != window->view) {
 885             [[oldView delegate] resetMouseTracking];
 886         }
 887 
 888         if (window->view != nil)
 889         {
 890             CALayer *layer = [window->view layer];
 891             if (([layer isKindOfClass:[CAOpenGLLayer class]] == YES) &&
 892                 (([window->nsWindow styleMask] & NSTexturedBackgroundWindowMask) == NO))
 893             {
 894                 [((CAOpenGLLayer*)layer) setOpaque:[window->nsWindow isOpaque]];
 895             }
 896             
 897             window->suppressWindowMoveEvent = YES; // RT-11215
 898             {
 899                 NSRect viewFrame = [window->view frame];
 900                 if ((viewFrame.size.width != 0.0f) && (viewFrame.size.height != 0.0f))
 901                 {
 902                     NSRect windowFrame = [window->nsWindow frameRectForContentRect:viewFrame];
 903                     windowFrame.origin.x = [window->nsWindow frame].origin.x;
 904                     windowFrame.origin.y = [window->nsWindow frame].origin.y;
 905                     [window _setWindowFrameWithRect:NSMakeRect(windowFrame.origin.x, windowFrame.origin.y, windowFrame.size.width, windowFrame.size.height) withDisplay:JNI_TRUE withAnimate:JNI_FALSE];
 906                 }
 907                 
 908                 [window->nsWindow setContentView:[window->view superview]]; // use our superview not ourselves!
 909                 [window->nsWindow setInitialFirstResponder:window->view];
 910                 [window->nsWindow makeFirstResponder:window->view];
 911             }
 912             window->suppressWindowMoveEvent = NO;
 913         }
 914         else
 915         {
 916             [window->nsWindow performSelectorOnMainThread:@selector(setContentView:) withObject:nil waitUntilDone:YES];
 917         }
 918     }
 919     GLASS_POOL_EXIT;
 920     GLASS_CHECK_EXCEPTION(env);
 921     
 922     return JNI_TRUE; // gznote: remove this return value if unused
 923 }
 924 
 925 /*
 926  * Class:     com_sun_glass_ui_mac_MacWindow
 927  * Method:    _setMenubar
 928  * Signature: (Lcom/sun/glass/ui/mac/MacMenubarDelegate;)V
 929  */
 930 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setMenubar
 931 (JNIEnv *env, jobject jWindow, jlong jPtr, jlong jMenubarPtr)
 932 {
 933     LOG("Java_com_sun_glass_ui_mac_MacWindow__1setMenubar");
 934     if (!jPtr) return JNI_FALSE;
 935     
 936     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 937     GLASS_POOL_ENTER;
 938     {
 939         GlassWindow *window = getGlassWindow(env, jPtr);
 940         window->menubar = (GlassMenubar*)jlong_to_ptr(jMenubarPtr);
 941         [NSApp setMainMenu:window->menubar->menu];
 942         [[NSApp mainMenu] update];
 943     }
 944     GLASS_POOL_EXIT;
 945     GLASS_CHECK_EXCEPTION(env);
 946     
 947     return JNI_TRUE; // gznote: remove this return value if unused
 948 }
 949 
 950 /*                                                                                                     
 951  * Class:     com_sun_glass_ui_mac_MacWindow                                                     
 952  * Method:    _close                                                                                   
 953  * Signature: ()V                                                                                      
 954  */
 955 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1close
 956 (JNIEnv *env, jclass cls, jlong jPtr)
 957 {
 958     LOG("Java_com_sun_glass_ui_mac_MacWindow__1close");
 959     if (!jPtr) return JNI_FALSE;
 960     
 961     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 962     GLASS_POOL_ENTER;
 963     {
 964         GlassWindow *window = getGlassWindow(env, jPtr);
 965         // this call will always close the window
 966         // without calling the windowShouldClose
 967         [window->nsWindow close];
 968         // The NSWindow will be automatically released after closing
 969         // The GlassWindow is released in the [NSWindow dealloc] override        
 970     }
 971     GLASS_POOL_EXIT;
 972     GLASS_CHECK_EXCEPTION(env);
 973     
 974     return JNI_TRUE; // gznote: remove this return value if unused
 975 }
 976 
 977 /*                                                                                                     
 978  * Class:     com_sun_glass_ui_mac_MacWindow                                                     
 979  * Method:    _requestFocus
 980  * Signature: (J)Z                                                                                      
 981  */
 982 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1requestFocus
 983 (JNIEnv *env, jobject jWindow, jlong jPtr)
 984 {
 985     LOG("Java_com_sun_glass_ui_mac_MacWindow__1requestFocus");
 986     if (!jPtr) return JNI_FALSE;
 987     
 988     jboolean focused = JNI_FALSE;
 989     
 990     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 991     GLASS_POOL_ENTER;
 992     {
 993         GlassWindow *window = getGlassWindow(env, jPtr);
 994 
 995         if ([window->nsWindow isVisible])
 996         {
 997             [window->nsWindow makeMainWindow];
 998             [window->nsWindow makeKeyAndOrderFront:window->nsWindow];
 999             [window->nsWindow orderFrontRegardless];
1000         }
1001 
1002         focused = [window->nsWindow isKeyWindow] ? JNI_TRUE : JNI_FALSE;
1003     }
1004     GLASS_POOL_EXIT;
1005     GLASS_CHECK_EXCEPTION(env);
1006     
1007     return focused;
1008 }
1009 
1010 /*
1011  * Class:     com_sun_glass_ui_mac_MacWindow
1012  * Method:    _grabFocus
1013  * Signature: (J)Z
1014  */
1015 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1grabFocus
1016 (JNIEnv *env, jobject jThis, jlong jPtr)
1017 {
1018     LOG("Java_com_sun_glass_ui_mac_MacWindow__1grabFocus");
1019     if (!jPtr) return JNI_FALSE;
1020 
1021     jboolean ret = JNI_FALSE;
1022     
1023     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
1024     GLASS_POOL_ENTER;
1025     {
1026         GlassWindow * window = getGlassWindow(env, jPtr);
1027         //TODO: full screen
1028         [window _grabFocus];
1029         ret = JNI_TRUE;
1030     }
1031     GLASS_POOL_EXIT;
1032     GLASS_CHECK_EXCEPTION(env);
1033     
1034     return ret;
1035 }
1036 
1037 /*
1038  * Class:     com_sun_glass_ui_mac_MacWindow
1039  * Method:    _ungrabFocus
1040  * Signature: (J)V
1041  */
1042 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1ungrabFocus
1043 (JNIEnv *env, jobject jThis, jlong jPtr)
1044 {
1045     LOG("Java_com_sun_glass_ui_mac_MacWindow__1ungrabFocus");
1046     if (!jPtr) return;
1047     
1048     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
1049     GLASS_POOL_ENTER;
1050     {
1051         GlassWindow * window = getGlassWindow(env, jPtr);
1052         //TODO; full screen
1053         [window _ungrabFocus];
1054     }
1055     GLASS_POOL_EXIT;
1056     GLASS_CHECK_EXCEPTION(env);
1057 }
1058 
1059 /*
1060  * Class:     com_sun_glass_ui_mac_MacWindow
1061  * Method:    _maximize
1062  * Signature: (JZZ)V
1063  */
1064 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1maximize
1065 (JNIEnv *env, jobject jWindow, jlong jPtr, jboolean maximize, jboolean isZoomed)
1066 {
1067     LOG("Java_com_sun_glass_ui_mac_MacWindow__1maximize");
1068     if (!jPtr) return JNI_FALSE;
1069     
1070     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
1071     GLASS_POOL_ENTER;
1072     {
1073         GlassWindow *window = getGlassWindow(env, jPtr);
1074         window->suppressWindowResizeEvent = YES;
1075         
1076         if ((maximize == JNI_TRUE) && (isZoomed == JNI_FALSE))
1077         {
1078             window->preZoomedRect = [window->nsWindow frame];
1079             
1080             if ([window->nsWindow styleMask] != NSBorderlessWindowMask)
1081             { 
1082                 [window->nsWindow zoom:nil];
1083                 // windowShouldZoom will be called automatically in this case
1084             }
1085             else
1086             {
1087                 NSRect visibleRect = [[window _getScreen] visibleFrame];
1088                 [window _setWindowFrameWithRect:NSMakeRect(visibleRect.origin.x, visibleRect.origin.y, visibleRect.size.width, visibleRect.size.height) withDisplay:JNI_TRUE withAnimate:JNI_TRUE];
1089                 
1090                 // calling windowShouldZoom will send Java maximize event
1091                 [window windowShouldZoom:window->nsWindow toFrame:[window->nsWindow frame]];
1092             }
1093         }
1094         else if ((maximize == JNI_FALSE) && (isZoomed == JNI_TRUE))
1095         {
1096             [window _restorePreZoomedRect];
1097         }
1098         
1099         window->suppressWindowResizeEvent = NO;
1100     }
1101     GLASS_POOL_EXIT;
1102     GLASS_CHECK_EXCEPTION(env);
1103     
1104     return JNI_TRUE; // gznote: remove this return value if unused
1105 }
1106 
1107 /*
1108  * Class:     com_sun_glass_ui_mac_MacWindow
1109  * Method:    _setBounds
1110  * Signature: (JIIZZIIIIFF)V
1111  */
1112 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setBounds
1113 (JNIEnv *env, jobject jWindow, jlong jPtr,
1114  jint x, jint y, jboolean xSet, jboolean ySet,
1115  jint w, jint h, jint cw, jint ch, jfloat xGravity, jfloat yGravity)
1116 {
1117     LOG("Java_com_sun_glass_ui_mac_MacWindow__1setBounds");
1118     LOG("   x,y: %d,%d", x, y);
1119     LOG("   xSet,ySet: %d,%d", xSet, ySet);
1120     LOG("   xGravity,yGravity: %.2f,%.2f", xGravity, yGravity);
1121     LOG("   w x h: %dx%d", w, h);
1122     LOG("   cw x ch: %dx%d", cw, ch);
1123     if (!jPtr) return;
1124     
1125     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
1126     GLASS_POOL_ENTER;
1127     {
1128         GlassWindow *window = getGlassWindow(env, jPtr);
1129         if (xSet || ySet) window->isLocationAssigned = YES;
1130         if (w > 0 || h > 0 || cw > 0 || ch > 0) window->isSizeAssigned = YES;
1131         [window _setBounds:x y:y xSet:xSet ySet:ySet w:w h:h cw:cw ch:ch];
1132     }
1133     GLASS_POOL_EXIT;
1134     GLASS_CHECK_EXCEPTION(env);
1135 }
1136 
1137 /*
1138  * Class:     com_sun_glass_ui_mac_MacWindow
1139  * Method:    _setMinimumSize
1140  * Signature: (JII)Z
1141  */
1142 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setMinimumSize
1143 (JNIEnv *env, jobject jWindow, jlong jPtr, jint jW, jint jH)
1144 {
1145     LOG("Java_com_sun_glass_ui_mac_MacWindow__1setMinimumSize");
1146     if (!jPtr) return JNI_FALSE;
1147     
1148     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
1149     GLASS_POOL_ENTER;
1150     {
1151         GlassWindow *window = getGlassWindow(env, jPtr);
1152         [window->nsWindow setMinSize:NSMakeSize(jW, jH)];
1153     }
1154     GLASS_POOL_EXIT;
1155     GLASS_CHECK_EXCEPTION(env);
1156     
1157     return JNI_TRUE; // gznote: remove this return value if unused
1158 }
1159 
1160 /*
1161  * Class:     com_sun_glass_ui_mac_MacWindow
1162  * Method:    _setMaximumSize
1163  * Signature: (JII)Z
1164  */
1165 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setMaximumSize
1166 (JNIEnv *env, jobject jWindow, jlong jPtr, jint jW, jint jH)
1167 {
1168     LOG("Java_com_sun_glass_ui_mac_MacWindow__1setMaximumSize");
1169     if (!jPtr) return JNI_FALSE;
1170     
1171     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
1172     GLASS_POOL_ENTER;
1173     {
1174         GlassWindow *window = getGlassWindow(env, jPtr);
1175         [window->nsWindow setMaxSize:NSMakeSize(jW == -1 ? FLT_MAX : (CGFloat)jW,
1176                                                 jH == -1 ? FLT_MAX : (CGFloat)jH)];
1177     }
1178     GLASS_POOL_EXIT;
1179     GLASS_CHECK_EXCEPTION(env);
1180     
1181     return JNI_TRUE; // gznote: remove this return value if unused
1182 }
1183 
1184 /*                                                                                                     
1185  * Class:     com_sun_glass_ui_mac_MacWindow                                                     
1186  * Method:    _setResizable                                                                              
1187  * Signature: (Z)Z                                                                                     
1188  */
1189 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setResizable
1190 (JNIEnv *env, jobject jWindow, jlong jPtr, jboolean jResizable)
1191 {
1192     LOG("Java_com_sun_glass_ui_mac_MacWindow__1setResizable");
1193     if (!jPtr) return JNI_FALSE;
1194     
1195     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
1196     GLASS_POOL_ENTER;
1197     {
1198         GlassWindow *window = getGlassWindow(env, jPtr);
1199         if (window->isResizable != jResizable)
1200         {
1201             [window performSelectorOnMainThread:@selector(_setResizable) withObject:nil waitUntilDone:YES];
1202         }
1203     }        
1204     GLASS_POOL_EXIT;
1205     GLASS_CHECK_EXCEPTION(env);
1206     
1207     return JNI_TRUE;
1208 }
1209 
1210 /*                                                                                                     
1211  * Class:     com_sun_glass_ui_mac_MacWindow                                                     
1212  * Method:    _setVisible                                                                              
1213  * Signature: (Z)Z                                                                                     
1214  */
1215 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setVisible
1216 (JNIEnv *env, jobject jWindow, jlong jPtr, jboolean jVisible)
1217 {
1218     LOG("Java_com_sun_glass_ui_mac_MacWindow__1setVisible");
1219     if (!jPtr) return JNI_FALSE;
1220     
1221     jboolean now = JNI_FALSE;
1222     
1223     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
1224     GLASS_POOL_ENTER;
1225     {
1226         GlassWindow *window = getGlassWindow(env, jPtr);
1227         if (jVisible == JNI_TRUE)
1228         {
1229             if (!window->isLocationAssigned) {
1230                 [window _setBounds:0 y:0 xSet:JNI_TRUE ySet:JNI_TRUE w:-1 h:-1 cw:-1 ch:-1];
1231             }
1232             if (!window->isSizeAssigned) {
1233                 [window _setBounds:0 y:0 xSet:JNI_FALSE ySet:JNI_FALSE w:320 h:200 cw:-1 ch:-1];
1234             }
1235             [window _setVisible];
1236         }
1237         else
1238         {
1239             [window _ungrabFocus];
1240             if (window->owner != nil)
1241             {
1242                 [window->owner removeChildWindow:window->nsWindow];
1243             }
1244             [window->nsWindow orderOut:window->nsWindow];
1245         }
1246         now = [window->nsWindow isVisible] ? JNI_TRUE : JNI_FALSE;
1247         
1248         // RT-22502 temp workaround: bring plugin window in front of a browser 
1249         if (now == YES)
1250         {
1251             static BOOL isBackgroundOnlyAppChecked = NO;
1252             static BOOL isBackgroundOnlyApp = NO;
1253             if (isBackgroundOnlyAppChecked == NO)
1254             {
1255                 isBackgroundOnlyAppChecked = YES;
1256                 
1257                 ProcessSerialNumber psn;
1258                 if (GetCurrentProcess(&psn) == noErr)
1259                 {
1260                     ProcessInfoRec info;
1261                     memset(&info, 0x00, sizeof(ProcessInfoRec));
1262                     GetProcessInformation(&psn, &info);
1263                     isBackgroundOnlyApp = ((modeOnlyBackground&info.processMode) == modeOnlyBackground);
1264                 }
1265             }
1266             if (isBackgroundOnlyApp == YES)
1267             {
1268                 [window->nsWindow performSelectorOnMainThread:@selector(orderFrontRegardless) withObject:nil waitUntilDone:YES];
1269             }
1270         }
1271     }
1272     GLASS_POOL_EXIT;
1273     GLASS_CHECK_EXCEPTION(env);
1274     
1275     return now;
1276 }
1277 
1278 /*                                                                                                     
1279  * Class:     com_sun_glass_ui_mac_MacWindow                                                     
1280  * Method:    _setTitle                                                                                
1281  * Signature: (Ljava/lang/String;)Z
1282  */
1283 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setTitle
1284 (JNIEnv *env, jobject jWindow, jlong jPtr, jstring jTitle)
1285 {
1286     LOG("Java_com_sun_glass_ui_mac_MacWindow__1setTitle");
1287     LOG("   window: %p", jPtr);
1288     if (!jPtr) return JNI_FALSE;
1289     
1290     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
1291     GLASS_POOL_ENTER;
1292     {
1293         GlassWindow *window = getGlassWindow(env, jPtr);
1294         
1295         NSString *title = [GlassHelper nsStringWithJavaString:jTitle withEnv:env];
1296         LOG("   title: %s", [title UTF8String]);
1297         [window->nsWindow setTitle:title];
1298     }
1299     GLASS_POOL_EXIT;
1300     GLASS_CHECK_EXCEPTION(env);
1301     
1302     return JNI_TRUE; // gnote: remove this return value if unused
1303 }
1304 
1305 /*                                                                                                     
1306  * Class:     com_sun_glass_ui_mac_MacWindow                                                     
1307  * Method:    _minimize                                                                                
1308  * Signature: (Z)V                                                                                     
1309  */
1310 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacWindow__1minimize
1311 (JNIEnv *env, jobject jWindow, jlong jPtr, jboolean jMiniaturize)
1312 {
1313     LOG("Java_com_sun_glass_ui_mac_MacWindow__1minimize");
1314     if (!jPtr) return JNI_FALSE;
1315     
1316     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
1317     GLASS_POOL_ENTER;
1318     {
1319         GlassWindow *window = getGlassWindow(env, jPtr);
1320         
1321         if (jMiniaturize == JNI_TRUE)
1322         {
1323             [window->nsWindow miniaturize:nil];
1324         }
1325         else
1326         {
1327             [window->nsWindow deminiaturize:nil];
1328         }
1329     }
1330     GLASS_POOL_EXIT;
1331     GLASS_CHECK_EXCEPTION(env);
1332     
1333     return JNI_TRUE; // gnote: remove this return value if unused
1334 }
1335 
1336 /*
1337  * Class:     com_sun_glass_ui_mac_MacWindow
1338  * Method:    _setIcon
1339  * Signature: (JLcom/sun/glass/ui/Pixels;)V
1340  */
1341 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1setIcon
1342 (JNIEnv *env, jobject jWindow, jlong jPtr, jobject jPixels)
1343 {
1344     LOG("Java_com_sun_glass_ui_mac_MacWindow__1setIcon");
1345     if (!jPtr) return;
1346     
1347     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
1348     GLASS_POOL_ENTER;
1349     {
1350         GlassWindow *window = getGlassWindow(env, jPtr);
1351         if (jPixels != NULL)
1352         {
1353             NSImage *image = nil;
1354             (*env)->CallVoidMethod(env, jPixels, jPixelsAttachData, ptr_to_jlong(&image));
1355             if (image != nil) {
1356                 // need an explicit window title for the rest of the code to work
1357                 if ([window->nsWindow title] == nil)
1358                 {
1359                     [window->nsWindow setTitle:@"Untitled"];
1360                 }
1361                 
1362                 // http://www.cocoabuilder.com/archive/cocoa/199554-nswindow-title-bar-icon-without-representedurl.html
1363                 [window->nsWindow setRepresentedURL:[NSURL fileURLWithPath:[window->nsWindow title]]];
1364                 [[window->nsWindow standardWindowButton:NSWindowDocumentIconButton] setImage:image];
1365                 [image release];
1366             } else {
1367                 [[window->nsWindow standardWindowButton:NSWindowDocumentIconButton] setImage:nil];
1368             }
1369         } else {
1370             [[window->nsWindow standardWindowButton:NSWindowDocumentIconButton] setImage:nil];
1371         }
1372     }
1373     GLASS_POOL_EXIT;
1374     GLASS_CHECK_EXCEPTION(env);
1375 }
1376 
1377 /*
1378  * Class:     com_sun_glass_ui_mac_MacWindow
1379  * Method:    _toFront
1380  * Signature: (J)V
1381  */
1382 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1toFront
1383 (JNIEnv *env, jobject jWindow, jlong jPtr)
1384 {
1385     LOG("Java_com_sun_glass_ui_mac_MacWindow__1toFront");
1386     LOG("   window: %p", jPtr);
1387     if (!jPtr) return;
1388     
1389     GLASS_POOL_ENTER;
1390     {
1391         GlassWindow *window = getGlassWindow(env, jPtr);
1392         [window->nsWindow orderFrontRegardless];
1393     }
1394     GLASS_POOL_EXIT;
1395     GLASS_CHECK_EXCEPTION(env);
1396 }
1397 
1398 /*
1399  * Class:     com_sun_glass_ui_mac_MacWindow
1400  * Method:    _toBack
1401  * Signature: (J)V
1402  */
1403 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1toBack
1404 (JNIEnv *env, jobject jWindow, jlong jPtr)
1405 {
1406     LOG("Java_com_sun_glass_ui_mac_MacWindow__1toBack");
1407     if (!jPtr) return;
1408     
1409     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
1410     GLASS_POOL_ENTER;
1411     {
1412         GlassWindow *window = getGlassWindow(env, jPtr);
1413         [window->nsWindow orderBack:nil];
1414     }
1415     GLASS_POOL_EXIT;
1416     GLASS_CHECK_EXCEPTION(env);
1417 }
1418 
1419 
1420 /*
1421  * Class:     com_sun_glass_ui_mac_MacWindow
1422  * Method:    _enterModal
1423  * Signature: (J)V
1424  */
1425 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1enterModal
1426 (JNIEnv *env, jobject jWindow, jlong jPtr)
1427 {
1428     LOG("Java_com_sun_glass_ui_mac_MacWindow__1enterModal");
1429     if (!jPtr) return;
1430     
1431     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
1432     GLASS_POOL_ENTER;
1433     {
1434         GlassWindow *window = getGlassWindow(env, jPtr);
1435         [NSApp runModalForWindow:window->nsWindow];
1436     }
1437     GLASS_POOL_EXIT;
1438     GLASS_CHECK_EXCEPTION(env);
1439 }
1440 
1441 /*
1442  * Class:     com_sun_glass_ui_mac_MacWindow
1443  * Method:    _enterModalWithWindow
1444  * Signature: (JJ)V
1445  */
1446 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1enterModalWithWindow
1447 (JNIEnv *env, jobject jWindow, jlong jDialogPtr, jlong jWindowPtr)
1448 {
1449     LOG("Java_com_sun_glass_ui_mac_MacWindow__1enterModalWithWindow");
1450     
1451     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
1452     GLASS_POOL_ENTER;
1453     {
1454         //GlassWindow *window = getGlassWindow(env, jDialogPtr);
1455         // TODO: implement _enterModalWithWindow
1456     }
1457     GLASS_POOL_EXIT;
1458     GLASS_CHECK_EXCEPTION(env);
1459 }
1460 
1461 /*
1462  * Class:     com_sun_glass_ui_mac_MacWindow
1463  * Method:    _exitModal
1464  * Signature: (J)V
1465  */
1466 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacWindow__1exitModal
1467 (JNIEnv *env, jobject jWindow, jlong jPtr)
1468 {
1469     LOG("Java_com_sun_glass_ui_mac_MacWindow__1exitModal");
1470     if (!jPtr) return;
1471     
1472     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
1473     GLASS_POOL_ENTER;
1474     {
1475         GlassWindow *window = getGlassWindow(env, jPtr);
1476         [NSApp stop:window->nsWindow];
1477     }
1478     GLASS_POOL_EXIT;
1479     GLASS_CHECK_EXCEPTION(env);
1480 }
1481 
1482 /*
1483  * Class:     com_sun_glass_ui_mac_MacWindow
1484  * Method:    _getEmbeddedX
1485  * Signature: (J)I
1486  */
1487 JNIEXPORT jint JNICALL Java_com_sun_glass_ui_mac_MacWindow__1getEmbeddedX
1488 (JNIEnv *env, jobject jWindow, jlong jPtr)
1489 {
1490     LOG("Java_com_sun_glass_ui_mac_MacWindow__1getEmbeddedX");
1491     if (!jPtr) return 0;
1492     
1493     jint x = 0;
1494     
1495     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
1496     GLASS_POOL_ENTER;
1497     {
1498         GlassEmbeddedWindow *window = getGlassEmbeddedWindow(env, jPtr);
1499         x = (int)round([window frame].origin.x);
1500     }
1501     GLASS_POOL_EXIT;
1502     GLASS_CHECK_EXCEPTION(env);
1503     
1504     return x;
1505 }
1506 
1507 /*
1508  * Class:     com_sun_glass_ui_mac_MacWindow
1509  * Method:    _getEmbeddedY
1510  * Signature: (J)I
1511  */
1512 JNIEXPORT jint JNICALL Java_com_sun_glass_ui_mac_MacWindow__1getEmbeddedY
1513 (JNIEnv *env, jobject jWindow, jlong jPtr)
1514 {
1515     LOG("Java_com_sun_glass_ui_mac_MacWindow__1getEmbeddedX");
1516     if (!jPtr) return 0;
1517     
1518     jint y = 0;
1519     
1520     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
1521     GLASS_POOL_ENTER;
1522     {
1523         GlassEmbeddedWindow *window = getGlassEmbeddedWindow(env, jPtr);
1524         NSRect frameRect = [window frame];
1525         
1526         // flip y coorindate
1527         NSScreen *screen = [[NSScreen screens] objectAtIndex:0];
1528         NSRect screenFrame = screen.frame;
1529         y = (int)round(screenFrame.size.height - frameRect.size.height - frameRect.origin.y);
1530     }
1531     GLASS_POOL_EXIT;
1532     GLASS_CHECK_EXCEPTION(env);
1533     
1534     return y;
1535 }