1 /*
   2  * Copyright (c) 2011, 2014, 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 "GlassTouches.h"
  36 #import "GlassWindow+Java.h"
  37 #import "GlassWindow+Overrides.h"
  38 #import "GlassViewDelegate.h"
  39 #import "GlassApplication.h"
  40 #import "GlassScreen.h"
  41 
  42 #import <AppKit/NSGraphics.h> // NSBeep();
  43 
  44 @implementation GlassWindow (Overrides)
  45 
  46 - (void)dealloc
  47 {
  48     assert(pthread_main_np() == 1);
  49     JNIEnv *env = jEnv;
  50     if (env != NULL)
  51     {
  52         (*env)->DeleteGlobalRef(env, self->jWindow);
  53         GLASS_CHECK_EXCEPTION(env);
  54     }
  55     
  56     self->jWindow = NULL;
  57     
  58     [super dealloc];
  59 }
  60 
  61 #pragma mark --- Delegate
  62 
  63 - (void)windowDidBecomeKey:(NSNotification *)notification
  64 {
  65     if (self->fullscreenWindow)
  66     {
  67         return;
  68     }
  69     
  70     GET_MAIN_JENV;
  71     if (!self->isEnabled)
  72     {
  73         NSBeep();
  74         (*env)->CallVoidMethod(env, self->jWindow, jWindowNotifyFocusDisabled);
  75         return;
  76     }
  77 
  78     (*env)->CallVoidMethod(env, self->jWindow, jWindowNotifyFocus, com_sun_glass_events_WindowEvent_FOCUS_GAINED);
  79     
  80     if (self->menubar != nil)
  81     {
  82         [NSApp setMainMenu:self->menubar->menu];
  83     }
  84     [[NSApp mainMenu] update];
  85 }
  86 
  87 - (void)windowDidResignKey:(NSNotification *)notification
  88 {
  89     if (self->fullscreenWindow)
  90     {
  91         return;
  92     }
  93     
  94     [self _ungrabFocus];
  95 
  96     GET_MAIN_JENV;
  97     (*env)->CallVoidMethod(env, self->jWindow, jWindowNotifyFocus, com_sun_glass_events_WindowEvent_FOCUS_LOST);
  98 }
  99 
 100 - (void)windowWillClose:(NSNotification *)notification
 101 {
 102     // Unparent self. Otherwise the code hangs
 103     if ([self->nsWindow parentWindow])
 104     {
 105         [[self->nsWindow parentWindow] removeChildWindow:self->nsWindow];
 106     }
 107 
 108     // Finally, close owned windows to mimic MS Windows behavior
 109     NSArray *children = [self->nsWindow childWindows];
 110     for (NSUInteger i=0; i<[children count]; i++)
 111     {
 112         NSWindow *child = (NSWindow*)[children objectAtIndex:i];
 113         [child close];
 114     }
 115     
 116     // Call the notification method
 117     GET_MAIN_JENV;
 118     (*env)->CallVoidMethod(env, self->jWindow, jWindowNotifyDestroy);
 119 }
 120 
 121 - (void)windowWillMove:(NSNotification *)notification
 122 {
 123     //NSLog(@"windowWillMove");
 124 }
 125 
 126 - (void)windowDidMove:(NSNotification *)notification
 127 {
 128     //NSLog(@"windowDidMove");
 129     [self _sendJavaWindowMoveEventForFrame:[self _flipFrame]];
 130 }
 131 
 132 - (void)windowDidChangeBackingProperties:(NSNotification *)notification
 133 {
 134     // The spec for [NSWindow backingScaleFactor] only mentions 1.0 and 2.0
 135     // whereas NSScreen's one is more generic. So use the latter.
 136     if ([self->nsWindow screen]) {
 137         [self->view notifyScaleFactorChanged:GetScreenScaleFactor([self->nsWindow screen])];
 138     }
 139 
 140     // Screen.notifySettingsChanged() calls Window.setScreen(), and the latter
 141     // generates the Window.EventHandler.handleScreenChangedEvent notification.
 142 }
 143 
 144 - (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize
 145 {
 146     //NSLog(@"windowWillResize");
 147     return proposedFrameSize;
 148 }
 149 
 150 - (void)windowDidResize:(NSNotification *)notification
 151 {
 152     //NSLog(@"windowDidResize");
 153     NSRect frame = [self _flipFrame];
 154 
 155     if ((int)self->lastReportedLocation.x != (int)frame.origin.x ||
 156             (int)self->lastReportedLocation.y != (int)frame.origin.y)
 157     {
 158         [self _sendJavaWindowMoveEventForFrame:frame];
 159 
 160         // Refetch the frame since it might've been modified due to the previous call
 161         frame = [self _flipFrame];
 162     }
 163 
 164     [self _sendJavaWindowResizeEvent:com_sun_glass_events_WindowEvent_RESIZE forFrame:frame];
 165 }
 166 
 167 - (void)windowDidMiniaturize:(NSNotification *)notification
 168 {
 169     [self _sendJavaWindowResizeEvent:com_sun_glass_events_WindowEvent_MINIMIZE forFrame:[self _flipFrame]];
 170 }
 171 
 172 - (void)windowDidDeminiaturize:(NSNotification *)notification
 173 {
 174     [self _sendJavaWindowResizeEvent:com_sun_glass_events_WindowEvent_RESTORE forFrame:[self _flipFrame]];
 175 }
 176 
 177 - (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame
 178 {
 179     GET_MAIN_JENV;
 180     (*env)->CallVoidMethod(env, jWindow, jWindowNotifyResize, com_sun_glass_events_WindowEvent_MAXIMIZE, (int)newFrame.size.width, (int)newFrame.size.height);
 181     
 182     return YES;
 183 }
 184 
 185 - (void)windowWillEnterFullScreen:(NSNotification *)notification
 186 {
 187     //NSLog(@"windowWillEnterFullScreen");
 188 }
 189 
 190 - (void)windowDidEnterFullScreen:(NSNotification *)notification
 191 {
 192     //NSLog(@"windowDidEnterFullScreen");
 193     [(GlassViewDelegate*)[self->view delegate] sendJavaFullScreenEvent:YES withNativeWidget:YES];
 194     [GlassApplication leaveFullScreenExitingLoopIfNeeded];
 195 }
 196 
 197 - (void)windowWillExitFullScreen:(NSNotification *)notification
 198 {
 199     //NSLog(@"windowWillExitFullScreen");
 200 }
 201 - (void)windowDidExitFullScreen:(NSNotification *)notification 
 202 {
 203     //NSLog(@"windowDidExitFullScreen");
 204     [(GlassViewDelegate*)[self->view delegate] sendJavaFullScreenEvent:NO withNativeWidget:YES];
 205     [GlassApplication leaveFullScreenExitingLoopIfNeeded];
 206 }
 207 
 208 - (BOOL)windowShouldClose:(NSNotification *)notification
 209 {
 210     if (self->isEnabled)
 211     {
 212         GET_MAIN_JENV;
 213         (*env)->CallVoidMethod(env, jWindow, jWindowNotifyClose);
 214     }
 215     
 216     // it's up to app to decide if the window should be closed
 217     return FALSE;
 218 }
 219 
 220 #pragma mark --- Title Icon
 221 
 222 - (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu
 223 {
 224     return NO;
 225 }
 226 
 227 - (BOOL)window:(NSWindow *)window shouldDragDocumentWithEvent:(NSEvent *)event from:(NSPoint)dragImageLocation withPasteboard:(NSPasteboard *)pasteboard
 228 {
 229     return NO;
 230 }
 231 
 232 @end