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 package sun.lwawt.macosx; 27 28 import java.awt.*; 29 30 import sun.awt.CGraphicsConfig; 31 import sun.lwawt.LWWindowPeer; 32 import sun.lwawt.macosx.event.NSEvent; 33 34 import sun.java2d.SurfaceData; 35 import sun.java2d.opengl.CGLLayer; 36 import sun.java2d.opengl.CGLSurfaceData; 37 38 public class CPlatformView extends CFRetainedResource { 39 private native long nativeCreateView(int x, int y, int width, int height, long windowLayerPtr); 40 41 private LWWindowPeer peer; 42 private SurfaceData surfaceData; 43 private CGLLayer windowLayer; 44 private CPlatformResponder responder; 45 46 public CPlatformView() { 47 super(0, true); 48 } 49 50 public void initialize(LWWindowPeer peer, CPlatformResponder responder) { 51 this.peer = peer; 52 this.responder = responder; 53 54 if (!LWCToolkit.getSunAwtDisableCALayers()) { 55 this.windowLayer = new CGLLayer(peer); 56 } 57 setPtr(nativeCreateView(0, 0, 0, 0, getWindowLayerPtr())); 58 } 59 60 public long getAWTView() { 61 return ptr; 62 } 63 64 public boolean isOpaque() { 65 return !peer.isTranslucent(); 66 } 67 68 /* 69 * All coordinates passed to the method should be based on the origin being in the bottom-left corner (standard 70 * Cocoa coordinates). 71 */ 72 public void setBounds(int x, int y, int width, int height) { 73 CWrapper.NSView.setFrame(ptr, x, y, width, height); 74 } 75 76 // REMIND: CGLSurfaceData expects top-level's size 77 public Rectangle getBounds() { 78 return peer.getBounds(); 79 } 80 81 public Object getDestination() { 82 return peer; 83 } 84 85 public void enterFullScreenMode(final long nsWindowPtr) { 86 CWrapper.NSView.enterFullScreenMode(ptr); 87 88 // REMIND: CGLSurfaceData expects top-level's size 89 // and therefore we need to account insets before 90 // recreating the surface data 91 Insets insets = peer.getInsets(); 92 93 Rectangle screenBounds; 94 final long screenPtr = CWrapper.NSWindow.screen(nsWindowPtr); 95 try { 96 screenBounds = CWrapper.NSScreen.frame(screenPtr).getBounds(); 97 } finally { 98 CWrapper.NSObject.release(screenPtr); 99 } 100 101 // the move/size notification from the underlying system comes 102 // but it contains a bounds smaller than the whole screen 103 // and therefore we need to create the synthetic notifications 104 peer.notifyReshape(screenBounds.x - insets.left, 105 screenBounds.y - insets.bottom, 106 screenBounds.width + insets.left + insets.right, 107 screenBounds.height + insets.top + insets.bottom); 108 } 109 110 public void exitFullScreenMode() { 111 CWrapper.NSView.exitFullScreenMode(ptr); 112 } 113 114 // ---------------------------------------------------------------------- 115 // PAINTING METHODS 116 // ---------------------------------------------------------------------- 117 public SurfaceData replaceSurfaceData() { 118 if (!LWCToolkit.getSunAwtDisableCALayers()) { 119 surfaceData = windowLayer.replaceSurfaceData(); 120 } else { 121 if (surfaceData == null) { 122 CGraphicsConfig graphicsConfig = (CGraphicsConfig)peer.getGraphicsConfiguration(); 123 surfaceData = graphicsConfig.createSurfaceData(this); 124 } else { 125 validateSurface(); 126 } 127 } 128 return surfaceData; 129 } 130 131 private void validateSurface() { 132 if (surfaceData != null) { 133 ((CGLSurfaceData)surfaceData).validate(); 134 } 135 } 136 137 public GraphicsConfiguration getGraphicsConfiguration() { 138 return peer.getGraphicsConfiguration(); 139 } 140 141 public SurfaceData getSurfaceData() { 142 return surfaceData; 143 } 144 145 @Override 146 public void dispose() { 147 if (!LWCToolkit.getSunAwtDisableCALayers()) { 148 windowLayer.dispose(); 149 } 150 super.dispose(); 151 } 152 153 public long getWindowLayerPtr() { 154 if (!LWCToolkit.getSunAwtDisableCALayers()) { 155 return windowLayer.getPointer(); 156 } else { 157 return 0; 158 } 159 } 160 161 // ---------------------------------------------------------------------- 162 // NATIVE CALLBACKS 163 // ---------------------------------------------------------------------- 164 165 private void deliverMouseEvent(NSEvent event) { 166 int x = event.getX(); 167 int y = getBounds().height - event.getY(); 168 169 if (event.getType() == CocoaConstants.NSScrollWheel) { 170 responder.handleScrollEvent(x, y, event.getModifierFlags(), 171 event.getScrollDeltaX(), event.getScrollDeltaY()); 172 } else { 173 responder.handleMouseEvent(event.getType(), event.getModifierFlags(), event.getButtonNumber(), 174 event.getClickCount(), x, y, event.getAbsX(), event.getAbsY()); 175 } 176 } 177 178 private void deliverKeyEvent(NSEvent event) { 179 responder.handleKeyEvent(event.getType(), event.getModifierFlags(), 180 event.getCharactersIgnoringModifiers(), event.getKeyCode(), true); 181 } 182 183 /** 184 * Called by the native delegate in layer backed view mode or in the simple 185 * NSView mode. See NSView.drawRect(). 186 */ 187 private void deliverWindowDidExposeEvent() { 188 peer.notifyExpose(peer.getSize()); 189 } 190 }