1 /* 2 * Copyright (c) 2012, 2015, 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 package com.sun.glass.ui.swt; 26 27 import java.nio.IntBuffer; 28 import java.util.Map; 29 30 import com.sun.glass.events.*; 31 import com.sun.glass.ui.*; 32 33 import org.eclipse.swt.*; 34 import org.eclipse.swt.widgets.*; 35 import org.eclipse.swt.dnd.DropTarget; 36 import org.eclipse.swt.graphics.*; 37 //import org.eclipse.swt.internal.cocoa.OS; 38 39 final class SWTView extends View { 40 Canvas canvas; 41 DropTarget dropTarget; 42 43 static Shell hiddenShell; 44 45 public SWTView() { 46 super(); 47 } 48 49 //TODO - implement IME 50 @Override protected void _enableInputMethodEvents(long ptr, boolean enable) { } 51 52 @Override 53 protected int _getNativeFrameBuffer(long ptr) { 54 return 0; 55 } 56 57 @Override protected long _create(Map caps) { 58 if (hiddenShell == null) { 59 hiddenShell = new Shell(Display.getDefault(), SWT.SHELL_TRIM); 60 Display.getDefault().disposeExec(() -> { 61 hiddenShell.dispose(); 62 hiddenShell = null; 63 }); 64 } 65 int bits = SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE | SWT.LEFT_TO_RIGHT;// | SWT.NO_FOCUS; 66 if (SWT.getPlatform().equals("cocoa")) { 67 canvas = SWTApplication.createGLCanvas(hiddenShell, bits, caps); 68 69 // NSView view = canvas.view; 70 // long setWantsLayer_SEL = OS.sel_registerName("setWantsLayer:"); 71 // OS.objc_msgSend(view.id, setWantsLayer_SEL, true); 72 } else { 73 canvas = new Canvas(hiddenShell, bits); 74 } 75 canvas.setData(this); 76 Listener keyListener = event -> sendKeyEvent(event); 77 int [] keyEvents = new int[] { 78 SWT.KeyDown, 79 SWT.KeyUp, 80 }; 81 for (int i=0; i<keyEvents.length; i++) { 82 canvas.addListener (keyEvents[i], keyListener); 83 } 84 Listener mouseListener = event -> sendMouseEvent(event); 85 int [] mouseEvents = new int[] { 86 SWT.MouseDown, 87 SWT.MouseUp, 88 SWT.MouseMove, 89 SWT.MouseEnter, 90 SWT.MouseExit, 91 SWT.MouseHorizontalWheel, 92 SWT.MouseVerticalWheel, 93 SWT.MenuDetect, 94 }; 95 for (int i=0; i<mouseEvents.length; i++) { 96 canvas.addListener (mouseEvents[i], mouseListener); 97 } 98 canvas.addListener(SWT.Paint, event -> notifyRepaint(event.x, event.y, event.width, event.height)); 99 canvas.addListener(SWT.Resize, event -> { 100 Rectangle rect = canvas.getClientArea(); 101 notifyResize(rect.width, rect.height); 102 }); 103 104 //TODO - refactor to drop target creation in a better place 105 dropTarget = SWTClipboard.createDropTarget(canvas); 106 107 return SWTApplication.getHandle(canvas); 108 } 109 110 long layerID = 0; 111 @Override public int getNativeRemoteLayerId(String serverName) { 112 if (layerID != 0) return (int)layerID; 113 // used when run inside plugin 114 /* 115 // long JRSRemoteLayer_class = OS.objc_getClass("JRSRenderServer"); 116 117 Class<?> OS = Class.forName("org.eclipse.swt.internal.cocoa.OS"); 118 Method objc_getClass = OS.getDeclaredMethod("objc_getClass", String.class); 119 long JRSRemoteLayer_class = (Long)objc_getClass.invoke(OS, "JRSRenderServer"); 120 121 122 //RemoteLayerStartServer 123 // long startRenderServer_SEL = OS.sel_registerName("startRenderServer"); 124 // long result = OS.objc_msgSend(JRSRemoteLayer_class, startRenderServer_SEL); 125 // System.out.println("sent startRenderServer="+result); 126 127 //RemoteLayerGetServerPort 128 System.out.println("connecting to " + serverName); 129 NSString str = (NSString) new NSString().alloc(); 130 str = NSString.stringWith(serverName); 131 System.out.println("class="+JRSRemoteLayer_class); 132 long recieveRenderServer_SEL = OS.sel_registerName("recieveRenderServer:"); 133 System.out.println("SEL="+recieveRenderServer_SEL); 134 System.out.println("sending msg getPort"); 135 long port = OS.objc_msgSend(JRSRemoteLayer_class, recieveRenderServer_SEL, str.id); 136 System.out.println("port="+port); 137 138 //RemoteLayerGetRemoteFromLocal 139 // long localLayer = getNativeLayer(); 140 NSView view = canvas.view; 141 // 142 // long setWantsLayer_SEL = OS.sel_registerName("setWantsLayer:"); 143 // OS.objc_msgSend(view.id, setWantsLayer_SEL, true); 144 145 long layer_SEL = OS.sel_registerName("layer"); 146 long localLayer = OS.objc_msgSend(view.id, layer_SEL); 147 System.out.println("localLayer="+localLayer); 148 long createRemoteLayer_SEL = OS.sel_registerName("createRemoteLayerBoundTo:"); 149 System.out.println("sending msg createRemoteLayerBoundTo"); 150 long remoteLayer = OS.objc_msgSend(localLayer, createRemoteLayer_SEL, port); 151 System.out.println("remoter layer =" + remoteLayer); 152 153 //RemoteLayerGetIdForRemote 154 long layerID_SEL = OS.sel_registerName("layerID"); 155 System.out.println("sending msg layerID_SEL"); 156 layerID = OS.objc_msgSend(remoteLayer, layerID_SEL); 157 System.out.println("returning layerID="+layerID); 158 159 String s = Display.getAppVersion(); 160 if (s==null) s = ""; 161 s+= " create remote layer " + layerID; 162 Display.setAppVersion(s); 163 */ 164 165 return (int)layerID; 166 } 167 168 @Override protected long _getNativeView(long ptr) { 169 return ptr; 170 } 171 172 @Override protected int _getX(long ptr) { 173 //TODO - implement offset in parent 174 return 0; 175 } 176 @Override protected int _getY(long ptr) { 177 //TODO - implement offset in parent 178 return 0; 179 } 180 181 @Override protected boolean _close(long ptr) { 182 //TODO - implement destroy of a view 183 return false; 184 } 185 186 @Override protected void _scheduleRepaint(long ptr) { 187 canvas.redraw(); 188 } 189 190 @Override protected void _begin(final long ptr) { 191 SWTApplication.lockFocus(canvas); 192 } 193 194 @Override protected void _end(final long ptr) { 195 SWTApplication.unlockFocus(canvas); 196 } 197 198 @Override protected boolean _enterFullscreen(long ptr, boolean animate, boolean keepRatio, boolean hideCursor) { 199 canvas.getShell().setFullScreen(true); 200 if (canvas.getShell().getFullScreen()) { 201 notifyView(ViewEvent.FULLSCREEN_ENTER); 202 return true; 203 } 204 return false; 205 }; 206 @Override protected void _exitFullscreen(long ptr, boolean animate) { 207 canvas.getShell().setFullScreen(false); 208 if (!canvas.getShell().getFullScreen()) { 209 notifyView(ViewEvent.FULLSCREEN_EXIT); 210 } 211 }; 212 213 @Override protected void _setParent(long ptr, long parentPtr) { 214 //TODO - implement set parent (is this necessary?) 215 //throw new RuntimeException("SWTView._setParent not implemented."); 216 } 217 218 @Override protected void _uploadPixels(long ptr, Pixels pixels) { 219 //TODO - optimize pixel uploading 220 int width = pixels.getWidth(), height = pixels.getHeight(); 221 int [] bytes = ((IntBuffer)pixels.getPixels()).array(); 222 PaletteData palette = new PaletteData(0x00ff0000, 0x0000ff00, 0x000000ff); 223 224 //long t0 = System.currentTimeMillis(); 225 ImageData imageData = new ImageData(width, height, 32, palette); 226 //long t1 = System.currentTimeMillis(); 227 //System.out.println("new ImageData: " + (t1-t0)); 228 229 imageData.setPixels(0, 0, width * height, bytes, 0); 230 //long t2 = System.currentTimeMillis(); 231 //System.out.println("setPixels: " + (t2-t1)); 232 233 Image image = new Image(canvas.getDisplay(), imageData); 234 //long t3 = System.currentTimeMillis(); 235 //System.out.println("new Image: " + (t3-t2)); 236 237 GC gc = new GC (canvas); 238 //long t4 = System.currentTimeMillis(); 239 //System.out.println("new GC: " + (t4-t3)); 240 241 gc.drawImage(image, 0, 0); 242 //long t5 = System.currentTimeMillis(); 243 //System.out.println("drawImage: " + (t5-t4)); 244 245 image.dispose(); 246 //long t6 = System.currentTimeMillis(); 247 //System.out.println("image.dispose(): " + (t6-t5)); 248 249 gc.dispose(); 250 //long t7 = System.currentTimeMillis(); 251 //System.out.println("gc.dispose(): " + (t7-t6)); 252 } 253 254 void sendKeyEvent (Event event) { 255 //TODO - should the notifyXXX be called instead? 256 EventHandler eventHandler = getEventHandler(); 257 if (eventHandler == null) return; 258 long time = System.nanoTime(); 259 int keyCode = SWTApplication.getKeyCode(event); 260 int modifiers = SWTApplication.getModifiers(event); 261 int action = event.type == SWT.KeyDown ? KeyEvent.PRESS : KeyEvent.RELEASE; 262 char[] chars = new char[] { event.character }; 263 eventHandler.handleKeyEvent(this, time, action, keyCode, chars, modifiers); 264 if (event.character != '\0' && event.type == SWT.KeyDown) { 265 eventHandler.handleKeyEvent(this, time, KeyEvent.TYPED, keyCode, chars, modifiers); 266 } 267 } 268 269 void sendMouseEvent (Event event) { 270 //TODO - should the notifyXXX be called instead? 271 EventHandler eventHandler = getEventHandler(); 272 if (eventHandler == null) return; 273 long time = System.nanoTime(); 274 int type = 0; 275 switch (event.type) { 276 case SWT.MouseDown: 277 type = MouseEvent.DOWN; 278 if ((canvas.getShell().getStyle() & SWT.NO_FOCUS) != 0) { 279 canvas.forceFocus(); 280 } 281 break; 282 case SWT.MouseUp: 283 type = MouseEvent.UP; 284 break; 285 case SWT.MouseMove: 286 if ((event.stateMask & SWT.BUTTON_MASK) != 0) { 287 type = MouseEvent.DRAG; 288 } else { 289 type = MouseEvent.MOVE; 290 } 291 break; 292 case SWT.MouseEnter: 293 type = MouseEvent.ENTER; 294 break; 295 case SWT.MouseExit: 296 type = MouseEvent.EXIT; 297 break; 298 case SWT.MouseHorizontalWheel: 299 type = MouseEvent.WHEEL; 300 break; 301 case SWT.MouseVerticalWheel: 302 type = MouseEvent.WHEEL; 303 break; 304 case SWT.MenuDetect: 305 break; 306 } 307 int button = SWTApplication.getButton(event); 308 int modifiers = SWTApplication.getModifiers(event); 309 switch (event.type) { 310 case SWT.MouseHorizontalWheel: 311 //TODO - horizontal mouse wheel not implemented 312 break; 313 case SWT.MouseVerticalWheel: { 314 //TODO - mouse wheel not implemented, these values are hard coded 315 Point point = canvas.toDisplay(event.x, event.y); 316 eventHandler.handleScrollEvent(this, time, event.x, event.y, point.x, point.y, 0, event.count, modifiers, 1, 1, 1, 1, 1, 1); 317 break; 318 } 319 case SWT.MenuDetect: { 320 //TODO - compute trigger, don't hard code 321 boolean isKeyboardTrigger = false; 322 Point point = canvas.toControl(event.x, event.y); 323 eventHandler.handleMenuEvent(this, point.x, point.y, event.x, event.y, isKeyboardTrigger); 324 break; 325 } 326 default: { 327 //TODO - compute trigger, don't hard code 328 boolean isPopupTrigger = false; 329 Point point = canvas.toDisplay(event.x, event.y); 330 eventHandler.handleMouseEvent(this, time, type, button, event.x, event.y, point.x, point.y, modifiers, isPopupTrigger, false); 331 } 332 } 333 } 334 335 //TODO - fix visibility 336 public void notifyDragStart(int button, int x, int y, int xAbs, int yAbs) { 337 super. notifyDragStart(button, x, y, xAbs, yAbs); 338 } 339 340 //TODO - fix visibility 341 public void notifyDragEnd(int performedAction) { 342 super.notifyDragEnd(performedAction) ; 343 } 344 345 //TODO - fix visibility 346 public int notifyDragEnter(int x, int y, int xAbs, int yAbs, int recommendedDropAction) { 347 return super.notifyDragEnter(x, y, xAbs, yAbs, recommendedDropAction); 348 } 349 350 //TODO - fix visibility 351 public int notifyDragOver(int x, int y, int xAbs, int yAbs, int recommendedDropAction) { 352 return super.notifyDragOver(x, y, xAbs, yAbs, recommendedDropAction); 353 } 354 355 //TODO - fix visibility 356 public void notifyDragLeave() { 357 super.notifyDragLeave(); 358 } 359 360 //TODO - fix visibility 361 public int notifyDragDrop(int x, int y, int xAbs, int yAbs, int recommendedDropAction) { 362 return super.notifyDragDrop(x, y, xAbs, yAbs, recommendedDropAction); 363 } 364 } 365