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