1/* 2 * Copyright (c) 2011, 2016, 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 26package sun.lwawt.macosx; 27 28import java.awt.*; 29import java.awt.geom.Rectangle2D; 30import java.util.concurrent.atomic.AtomicBoolean; 31import java.util.concurrent.atomic.AtomicInteger; 32import java.util.concurrent.atomic.AtomicReference; 33 34import sun.awt.CGraphicsConfig; 35import sun.awt.CGraphicsEnvironment; 36import sun.lwawt.LWWindowPeer; 37 38import sun.java2d.SurfaceData; 39import sun.java2d.opengl.CGLLayer; 40import sun.java2d.opengl.CGLSurfaceData; 41 42public class CPlatformView extends CFRetainedResource { 43 private native long nativeCreateView(int x, int y, int width, int height, long windowLayerPtr); 44 private static native void nativeSetAutoResizable(long awtView, boolean toResize); 45 private static native int nativeGetNSViewDisplayID(long awtView); 46 private static native Rectangle2D nativeGetLocationOnScreen(long awtView); 47 private static native boolean nativeIsViewUnderMouse(long ptr); 48 49 private LWWindowPeer peer; 50 private SurfaceData surfaceData; 51 private CGLLayer windowLayer; 52 private CPlatformResponder responder; 53 54 public CPlatformView() { 55 super(0, true); 56 } 57 58 public void initialize(LWWindowPeer peer, CPlatformResponder responder) { 59 initializeBase(peer, responder); 60 61 if (!LWCToolkit.getSunAwtDisableCALayers()) { 62 this.windowLayer = createCGLayer(); 63 } 64 setPtr(nativeCreateView(0, 0, 0, 0, getWindowLayerPtr())); 65 } 66 67 public CGLLayer createCGLayer() { 68 return new CGLLayer(peer); 69 } 70 71 protected void initializeBase(LWWindowPeer peer, CPlatformResponder responder) { 72 this.peer = peer; 73 this.responder = responder; 74 } 75 76 public long getAWTView() { 77 return ptr; 78 } 79 80 public boolean isOpaque() { 81 return !peer.isTranslucent(); 82 } 83 84 /* 85 * All coordinates passed to the method should be based on the origin being in the bottom-left corner (standard 86 * Cocoa coordinates). 87 */ 88 public void setBounds(int x, int y, int width, int height) { 89 execute(ptr->CWrapper.NSView.setFrame(ptr, x, y, width, height)); 90 } 91 92 // REMIND: CGLSurfaceData expects top-level's size 93 public Rectangle getBounds() { 94 return peer.getBounds(); 95 } 96 97 public Object getDestination() { 98 return peer; 99 } 100 101 public void setToolTip(String msg) { 102 execute(ptr -> CWrapper.NSView.setToolTip(ptr, msg)); 103 } 104 105 // ---------------------------------------------------------------------- 106 // PAINTING METHODS 107 // ---------------------------------------------------------------------- 108 public SurfaceData replaceSurfaceData() { 109 if (!LWCToolkit.getSunAwtDisableCALayers()) { 110 surfaceData = windowLayer.replaceSurfaceData(); 111 } else { 112 if (surfaceData == null) { 113 CGraphicsConfig graphicsConfig = (CGraphicsConfig)getGraphicsConfiguration(); 114 surfaceData = graphicsConfig.createSurfaceData(this); 115 } else { 116 validateSurface(); 117 } 118 } 119 return surfaceData; 120 } 121 122 private void validateSurface() { 123 if (surfaceData != null) { 124 ((CGLSurfaceData)surfaceData).validate(); 125 } 126 } 127 128 public GraphicsConfiguration getGraphicsConfiguration() { 129 return peer.getGraphicsConfiguration(); 130 } 131 132 public SurfaceData getSurfaceData() { 133 return surfaceData; 134 } 135 136 @Override 137 public void dispose() { 138 if (!LWCToolkit.getSunAwtDisableCALayers()) { 139 windowLayer.dispose(); 140 } 141 super.dispose(); 142 } 143 144 public long getWindowLayerPtr() { 145 if (!LWCToolkit.getSunAwtDisableCALayers()) { 146 return windowLayer.getPointer(); 147 } else { 148 return 0; 149 } 150 } 151 152 public void setAutoResizable(boolean toResize) { 153 execute(ptr -> nativeSetAutoResizable(ptr, toResize)); 154 } 155 156 public boolean isUnderMouse() { 157 AtomicBoolean ref = new AtomicBoolean(); 158 execute(ptr -> { 159 ref.set(nativeIsViewUnderMouse(ptr)); 160 }); 161 return ref.get(); 162 } 163 164 public GraphicsDevice getGraphicsDevice() { 165 GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 166 CGraphicsEnvironment cge = (CGraphicsEnvironment)ge; 167 AtomicInteger ref = new AtomicInteger(); 168 execute(ptr -> { 169 ref.set(nativeGetNSViewDisplayID(ptr)); 170 }); 171 GraphicsDevice gd = cge.getScreenDevice(ref.get()); 172 if (gd == null) { 173 // this could possibly happen during device removal 174 // use the default screen device in this case 175 gd = ge.getDefaultScreenDevice(); 176 } 177 return gd; 178 } 179 180 public Point getLocationOnScreen() { 181 AtomicReference<Rectangle> ref = new AtomicReference<>(); 182 execute(ptr -> { 183 ref.set(nativeGetLocationOnScreen(ptr).getBounds()); 184 }); 185 Rectangle r = ref.get(); 186 if (r != null) { 187 return new Point(r.x, r.y); 188 } 189 return new Point(0, 0); 190 } 191 192 // ---------------------------------------------------------------------- 193 // NATIVE CALLBACKS 194 // ---------------------------------------------------------------------- 195 196 /* 197 * The callback is called only in the embedded case when the view is 198 * automatically resized by the superview. 199 * In normal mode this method is never called. 200 */ 201 private void deliverResize(int x, int y, int w, int h) { 202 peer.notifyReshape(x, y, w, h); 203 } 204 205 206 private void deliverMouseEvent(final NSEvent event) { 207 int x = event.getX(); 208 int y = getBounds().height - event.getY(); 209 int absX = event.getAbsX(); 210 int absY = event.getAbsY(); 211 212 if (event.getType() == CocoaConstants.NSScrollWheel) { 213 responder.handleScrollEvent(x, y, absX, absY, event.getModifierFlags(), 214 event.getScrollDeltaX(), event.getScrollDeltaY(), 215 event.getScrollPhase()); 216 } else { 217 responder.handleMouseEvent(event.getType(), event.getModifierFlags(), event.getButtonNumber(), 218 event.getClickCount(), x, y, 219 absX, absY); 220 } 221 } 222 223 private void deliverKeyEvent(NSEvent event) { 224 responder.handleKeyEvent(event.getType(), event.getModifierFlags(), event.getCharacters(), 225 event.getCharactersIgnoringModifiers(), event.getKeyCode(), true, false); 226 } 227 228 /** 229 * Called by the native delegate in layer backed view mode or in the simple 230 * NSView mode. See NSView.drawRect(). 231 */ 232 private void deliverWindowDidExposeEvent() { 233 peer.notifyExpose(peer.getSize()); 234 } 235} 236