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