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