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