+package org.simantics.g3d.jme.system;\r
+\r
+\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.logging.Level;\r
+import java.util.logging.Logger;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.KeyEvent;\r
+import org.eclipse.swt.events.KeyListener;\r
+import org.eclipse.swt.events.MouseEvent;\r
+import org.eclipse.swt.events.MouseListener;\r
+import org.eclipse.swt.events.MouseMoveListener;\r
+import org.eclipse.swt.events.MouseTrackListener;\r
+import org.eclipse.swt.events.MouseWheelListener;\r
+import org.eclipse.swt.events.PaintEvent;\r
+import org.eclipse.swt.events.PaintListener;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.layout.FillLayout;\r
+import org.eclipse.swt.opengl.GLCanvas;\r
+import org.eclipse.swt.opengl.GLData;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.lwjgl.LWJGLException;\r
+import org.lwjgl.Sys;\r
+import org.lwjgl.input.Keyboard;\r
+import org.lwjgl.input.Mouse;\r
+import org.lwjgl.opengl.GLContext;\r
+import org.lwjgl.opengl.Pbuffer;\r
+import org.lwjgl.opengl.PixelFormat;\r
+\r
+import com.jme3.cursors.plugins.JmeCursor;\r
+import com.jme3.input.JoyInput;\r
+import com.jme3.input.KeyInput;\r
+import com.jme3.input.MouseInput;\r
+import com.jme3.input.RawInputListener;\r
+import com.jme3.input.event.InputEvent;\r
+import com.jme3.input.event.KeyInputEvent;\r
+import com.jme3.input.event.MouseButtonEvent;\r
+import com.jme3.input.event.MouseMotionEvent;\r
+import com.jme3.system.AppSettings;\r
+import com.jme3.system.JmeSystem;\r
+import com.jme3.system.Platform;\r
+import com.jme3.system.lwjgl.LwjglAbstractDisplay;\r
+import com.jme3.system.lwjgl.LwjglDisplay;\r
+import com.jme3.system.lwjgl.LwjglTimer;\r
+\r
+/**\r
+ * SWT OpenGL canvas for jME\r
+ * \r
+ * Note: this class is experimental, and contains questionable code.\r
+ * \r
+ * \r
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
+ *\r
+ */\r
+public class SWTCanvas extends LwjglAbstractDisplay {\r
+\r
+ protected static final boolean USE_SHARED_CONTEXT = false;\r
+\r
+ \r
+ private static final Logger logger = Logger.getLogger(LwjglDisplay.class.getName());\r
+ \r
+ GLCanvas canvas;\r
+ \r
+ private int width;\r
+ private int height;\r
+ \r
+ private boolean runningFirstTime = true;\r
+ private boolean mouseWasGrabbed = false;\r
+ \r
+ private boolean mouseWasCreated = false;\r
+ private boolean keyboardWasCreated = false;\r
+\r
+ private Pbuffer pbuffer;\r
+ private PixelFormat pbufferFormat;\r
+ private PixelFormat canvasFormat;\r
+ \r
+ private boolean disposed = false;\r
+ \r
+ public SWTCanvas(Composite parent) {\r
+ parent.setLayout(new FillLayout());\r
+ \r
+ GLData data = new GLData();\r
+ data.doubleBuffer = true;\r
+ data.blueSize = 8;\r
+ data.redSize = 8;\r
+ data.greenSize = 8;\r
+ data.depthSize = 32;\r
+ data.alphaSize = 8;\r
+ data.stencilSize = 8;\r
+ data.stereo = false;\r
+ data.accumAlphaSize = 0;\r
+ data.accumBlueSize = 0;\r
+ data.accumGreenSize = 0;\r
+ data.accumRedSize = 0;\r
+ canvas = new GLCanvas(parent, SWT.EMBEDDED|SWT.NO_REDRAW_RESIZE, data);\r
+ //canvas = new GLCanvas(parent, SWT.NONE, data);\r
+ \r
+ \r
+ }\r
+ \r
+ public void dispose() {\r
+ if (disposed)\r
+ return;\r
+ \r
+ setCurrent();\r
+ deinitInThread();\r
+// pauseCanvas();\r
+ canvas.dispose();\r
+ disposed = true;\r
+ }\r
+ \r
+ public boolean isDisposed() {\r
+ return disposed;\r
+ }\r
+ \r
+ @Override\r
+ public Type getType() {\r
+ return Type.Canvas; // TODO : is Canvas Correct?\r
+ }\r
+ \r
+ @Override\r
+ public void setTitle(String title) {\r
+ // do nothing\r
+ }\r
+ \r
+ @Override\r
+ public void restart() {\r
+ frameRate = settings.getFrameRate();\r
+ }\r
+ \r
+\r
+ private boolean c = false;\r
+ \r
+ public void create(boolean waitFor){\r
+ if (c)\r
+ return;\r
+ c = true;\r
+ \r
+ setCurrent();\r
+ initInThread();\r
+ renderable.set(true);\r
+ //restoreCanvas();\r
+ \r
+// canvas.addPaintListener(new PaintListener() {\r
+// \r
+// @Override\r
+// public void paintControl(PaintEvent arg0) {\r
+// repaint();\r
+// }\r
+// });\r
+ \r
+ org.eclipse.swt.widgets.Display.getCurrent().asyncExec(new Runnable() {\r
+ \r
+ @Override\r
+ public void run() {\r
+ if (canvas.isDisposed())\r
+ return;\r
+ repaint();\r
+ org.eclipse.swt.widgets.Display.getCurrent().asyncExec(this);\r
+ \r
+ }\r
+ });\r
+\r
+ }\r
+ \r
+ @Override\r
+ protected void runLoop() {\r
+\r
+ if (renderable.get()){\r
+ Point size = canvas.getSize();\r
+ //System.out.println("Render " + size);\r
+ int newWidth = Math.max(size.x, 1);\r
+ int newHeight = Math.max(size.y, 1);\r
+ if (width != newWidth || height != newHeight){\r
+ System.out.println("Render resize " + size);\r
+ width = newWidth;\r
+ height = newHeight;\r
+ if (listener != null){\r
+ listener.reshape(width, height);\r
+ }\r
+ }\r
+ }\r
+ if (!created.get())\r
+ throw new IllegalStateException();\r
+ listener.update();\r
+ if (renderable.get()){\r
+ assert checkGLError();\r
+ \r
+ // calls swap buffers, etc.\r
+ try {\r
+ canvas.swapBuffers();\r
+// Display.processMessages();\r
+// if (autoFlush){\r
+// Display.update(false);\r
+// }else{\r
+// Display.processMessages();\r
+// Thread.sleep(50);\r
+// // add a small wait\r
+// // to reduce CPU usage\r
+// }\r
+ } catch (Throwable ex){\r
+ listener.handleError("Error while swapping buffers", ex);\r
+ }\r
+ }\r
+// if (frameRate > 0)\r
+// Display.sync(frameRate);\r
+\r
+// if (renderable.get()){\r
+// if (autoFlush){\r
+// // check input after we synchronize with framerate.\r
+// // this reduces input lag.\r
+// Display.processMessages();\r
+// }\r
+// }\r
+ }\r
+ \r
+ public void repaint() {\r
+ setCurrent();\r
+// if (renderable.get()){\r
+// if (Display.isCloseRequested())\r
+// listener.requestClose(false);\r
+ \r
+// if (wasActive != Display.isActive()) {\r
+// if (!wasActive) {\r
+// listener.gainFocus();\r
+// timer.reset();\r
+// wasActive = true;\r
+// } else {\r
+// listener.loseFocus();\r
+// wasActive = false;\r
+// }\r
+// }\r
+// }\r
+\r
+ runLoop();\r
+ }\r
+ \r
+ @Override\r
+ public void run() {\r
+ // do nothing\r
+ //super.run();\r
+ }\r
+ \r
+ @Override\r
+ protected void destroyContext() {\r
+ try {\r
+ // invalidate the state so renderer can resume operation\r
+ if (!USE_SHARED_CONTEXT){\r
+ renderer.cleanup();\r
+ }\r
+ \r
+ //if (Display.isCreated()){\r
+ if (!canvas.isDisposed()) {\r
+ /* FIXES:\r
+ * org.lwjgl.LWJGLException: X Error\r
+ * BadWindow (invalid Window parameter) request_code: 2 minor_code: 0\r
+ * \r
+ * Destroying keyboard early prevents the error above, triggered\r
+ * by destroying keyboard in by Display.destroy() or Display.setParent(null).\r
+ * Therefore Keyboard.destroy() should precede any of these calls.\r
+ */\r
+ if (Keyboard.isCreated()){\r
+ // Should only happen if called in \r
+ // LwjglAbstractDisplay.deinitInThread().\r
+ Keyboard.destroy();\r
+ }\r
+\r
+ //try {\r
+ // NOTE: On Windows XP, not calling setParent(null)\r
+ // freezes the application.\r
+ // On Mac it freezes the application.\r
+ // On Linux it fixes a crash with X Window System.\r
+ if (JmeSystem.getPlatform() == Platform.Windows32\r
+ || JmeSystem.getPlatform() == Platform.Windows64){\r
+ //Display.setParent(null);\r
+ }\r
+ //} catch (LWJGLException ex) {\r
+ // logger.log(Level.SEVERE, "Encountered exception when setting parent to null", ex);\r
+ //}\r
+\r
+// Display.destroy();\r
+ }\r
+ \r
+ // The canvas is no longer visible,\r
+ // but the context thread is still running.\r
+ if (!needClose.get()){\r
+ // MUST make sure there's still a context current here ..\r
+ // Display is dead, make pbuffer available to the system\r
+ makePbufferAvailable();\r
+ \r
+ renderer.invalidateState();\r
+ }else{\r
+ // The context thread is no longer running.\r
+ // Destroy pbuffer.\r
+ destroyPbuffer();\r
+ }\r
+ } catch (LWJGLException ex) {\r
+ listener.handleError("Failed make pbuffer available", ex);\r
+ }\r
+ \r
+ }\r
+ \r
+\r
+ \r
+ public void setFocus() {\r
+ canvas.setFocus(); \r
+ }\r
+ \r
+ public void setCurrent(GLCanvas canvas) {\r
+ // delegate to the GLContext\r
+ canvas.setCurrent();\r
+ try {\r
+ GLContext.useContext(canvas);\r
+ } catch (LWJGLException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ \r
+ public void setCurrent() {\r
+ setCurrent(canvas);\r
+ }\r
+ \r
+ \r
+ \r
+ private void pauseCanvas(){\r
+ if (Mouse.isCreated()){\r
+ if (Mouse.isGrabbed()){\r
+ Mouse.setGrabbed(false);\r
+ mouseWasGrabbed = true;\r
+ }\r
+ mouseWasCreated = true;\r
+ Mouse.destroy();\r
+ }\r
+ if (Keyboard.isCreated()){\r
+ keyboardWasCreated = true;\r
+ Keyboard.destroy();\r
+ }\r
+\r
+ renderable.set(false);\r
+ destroyContext();\r
+ }\r
+\r
+ /**\r
+ * Called to restore the canvas.\r
+ */\r
+ private void restoreCanvas(){\r
+ setCurrent();\r
+ logger.log(Level.INFO, "OGL: Waiting for canvas to become displayable..");\r
+ while (!canvas.getVisible()){\r
+ try {\r
+ Thread.sleep(10);\r
+ } catch (InterruptedException ex) {\r
+ logger.log(Level.SEVERE, "OGL: Interrupted! ", ex);\r
+ }\r
+ }\r
+ \r
+ logger.log(Level.INFO, "OGL: Creating display context ..");\r
+\r
+ // Set renderable to true, since canvas is now displayable.\r
+ renderable.set(true);\r
+ createContext(settings);\r
+\r
+ logger.log(Level.INFO, "OGL: Display is active!");\r
+\r
+ try {\r
+ if (mouseWasCreated){\r
+ Mouse.create();\r
+ if (mouseWasGrabbed){\r
+ Mouse.setGrabbed(true);\r
+ mouseWasGrabbed = false;\r
+ }\r
+ }\r
+ if (keyboardWasCreated){\r
+ Keyboard.create();\r
+ keyboardWasCreated = false;\r
+ }\r
+ } catch (LWJGLException ex){\r
+ logger.log(Level.SEVERE, "Encountered exception when restoring input", ex);\r
+ }\r
+\r
+ \r
+ }\r
+ /**\r
+ * It seems it is best to use one pixel format for all shared contexts.\r
+ * @see <a href="http://developer.apple.com/library/mac/#qa/qa1248/_index.html">http://developer.apple.com/library/mac/#qa/qa1248/_index.html</a>\r
+ */\r
+ protected PixelFormat acquirePixelFormat(boolean forPbuffer){\r
+ if (forPbuffer){\r
+ // Use 0 samples for pbuffer format, prevents\r
+ // crashes on bad drivers\r
+ if (pbufferFormat == null){\r
+ pbufferFormat = new PixelFormat(settings.getBitsPerPixel(),\r
+ 0,\r
+ settings.getDepthBits(),\r
+ settings.getStencilBits(),\r
+ 0);\r
+ }\r
+ return pbufferFormat;\r
+ }else{\r
+ if (canvasFormat == null){\r
+ int samples = getNumSamplesToUse();\r
+ canvasFormat = new PixelFormat(settings.getBitsPerPixel(),\r
+ 0,\r
+ settings.getDepthBits(),\r
+ settings.getStencilBits(),\r
+ samples);\r
+ }\r
+ return canvasFormat;\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * Makes sure the pbuffer is available and ready for use\r
+ */\r
+ protected void makePbufferAvailable() throws LWJGLException{\r
+ if (pbuffer != null && pbuffer.isBufferLost()){\r
+ logger.log(Level.WARNING, "PBuffer was lost!");\r
+ pbuffer.destroy();\r
+ pbuffer = null;\r
+ }\r
+ \r
+ if (pbuffer == null) {\r
+ pbuffer = new Pbuffer(1, 1, acquirePixelFormat(true), null);\r
+ pbuffer.makeCurrent();\r
+ logger.log(Level.INFO, "OGL: Pbuffer has been created");\r
+ \r
+ // Any created objects are no longer valid\r
+ if (!runningFirstTime){\r
+ renderer.resetGLObjects();\r
+ }\r
+ }\r
+ \r
+ pbuffer.makeCurrent();\r
+ if (!pbuffer.isCurrent()){\r
+ throw new LWJGLException("Pbuffer cannot be made current");\r
+ }\r
+ }\r
+ \r
+ protected void destroyPbuffer(){\r
+ if (pbuffer != null){\r
+ if (!pbuffer.isBufferLost()){\r
+ pbuffer.destroy();\r
+ }\r
+ pbuffer = null;\r
+ }\r
+ }\r
+ \r
+ @Override\r
+ protected void createContext(AppSettings settings) {\r
+ setCurrent();\r
+ \r
+ // In case canvas is not visible, we still take framerate\r
+ // from settings to prevent "100% CPU usage"\r
+ frameRate = settings.getFrameRate();\r
+ \r
+ try {\r
+ if (renderable.get()){\r
+ if (!runningFirstTime){\r
+ // because the display is a different opengl context\r
+ // must reset the context state.\r
+ if (!USE_SHARED_CONTEXT){\r
+ renderer.cleanup();\r
+ }\r
+ }\r
+ \r
+ // if the pbuffer is currently active, \r
+ // make sure to deactivate it\r
+ destroyPbuffer();\r
+ \r
+ if (Keyboard.isCreated()){\r
+ Keyboard.destroy();\r
+ }\r
+ \r
+ try {\r
+ Thread.sleep(1000);\r
+ } catch (InterruptedException ex) {\r
+ }\r
+ \r
+// Display.setVSyncEnabled(settings.isVSync());\r
+ //Display.setParent(canvas);\r
+ \r
+// if (USE_SHARED_CONTEXT){\r
+// Display.create(acquirePixelFormat(false), pbuffer);\r
+// }else{\r
+// Display.create(acquirePixelFormat(false));\r
+// }\r
+ \r
+ renderer.invalidateState();\r
+ }else{\r
+ // First create the pbuffer, if it is needed.\r
+ makePbufferAvailable();\r
+ }\r
+\r
+ // At this point, the OpenGL context is active.\r
+ if (runningFirstTime){\r
+ // THIS is the part that creates the renderer.\r
+ // It must always be called, now that we have the pbuffer workaround.\r
+ initContextFirstTime();\r
+ runningFirstTime = false;\r
+ }\r
+ } catch (LWJGLException ex) {\r
+ listener.handleError("Failed to initialize OpenGL context", ex);\r
+ // TODO: Fix deadlock that happens after the error (throw runtime exception?)\r
+ }\r
+ }\r
+\r
+ \r
+ public JoyInput getJoyInput() {\r
+ return null;\r
+ }\r
+\r
+ \r
+ SWTMouseInput mouseInput;\r
+ \r
+ public MouseInput getMouseInput() {\r
+ if (mouseInput == null){\r
+ mouseInput = new SWTMouseInput(this);\r
+ }\r
+ return mouseInput;\r
+ }\r
+\r
+ \r
+ SWTKeyInput keyInput;\r
+ \r
+ public KeyInput getKeyInput() {\r
+ if (keyInput == null){\r
+ keyInput = new SWTKeyInput(this);\r
+ }\r
+ return keyInput;\r
+ }\r
+ \r
+\r
+ \r
+ public class SWTMouseInput implements MouseInput, MouseListener, MouseMoveListener, MouseWheelListener, MouseTrackListener {\r
+ SWTCanvas canvas;\r
+ boolean init = false;\r
+ RawInputListener listener;\r
+ \r
+ public SWTMouseInput(SWTCanvas canvas) {\r
+ this.canvas = canvas;\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public void destroy() {\r
+ this.canvas.canvas.removeMouseListener(this);\r
+ this.canvas.canvas.removeMouseMoveListener(this);\r
+ this.canvas.canvas.removeMouseWheelListener(this);\r
+ this.canvas.canvas.removeMouseTrackListener(this);\r
+ }\r
+ \r
+ @Override\r
+ public void initialize() {\r
+ this.canvas.canvas.addMouseListener(this);\r
+ this.canvas.canvas.addMouseMoveListener(this);\r
+ this.canvas.canvas.addMouseWheelListener(this);\r
+ this.canvas.canvas.addMouseTrackListener(this);\r
+ init = true;\r
+ }\r
+ \r
+ @Override\r
+ public int getButtonCount() {\r
+ return 3;\r
+ }\r
+ \r
+ @Override\r
+ public boolean isInitialized() {\r
+ return init;\r
+ }\r
+ \r
+ @Override\r
+ public void setInputListener(RawInputListener listener) {\r
+ this.listener = listener;\r
+\r
+ }\r
+ \r
+ public long getInputTimeNanos() {\r
+ return Sys.getTime() * LwjglTimer.LWJGL_TIME_TO_NANOS;\r
+ }\r
+ \r
+ @Override\r
+ public void setCursorVisible(boolean visible) {\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public void setNativeCursor(JmeCursor cursor) {\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public void update() {\r
+ if (listener == null || events.size() == 0)\r
+ return;\r
+ listener.beginInput();\r
+ for (InputEvent e : events) {\r
+ if (e instanceof MouseButtonEvent)\r
+ listener.onMouseButtonEvent((MouseButtonEvent)e);\r
+ else\r
+ listener.onMouseMotionEvent((MouseMotionEvent)e);\r
+ }\r
+ events.clear();\r
+ listener.endInput();\r
+ }\r
+ \r
+ private List<InputEvent> events = new ArrayList<InputEvent>();\r
+ \r
+ @Override\r
+ public void mouseDoubleClick(MouseEvent e) {\r
+ //events.add(new MouseButtonEvent(e.button,true, e.x, e.y));\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public void mouseDown(MouseEvent e) {\r
+ events.add(new MouseButtonEvent(e.button,true, e.x, e.y));\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public void mouseUp(MouseEvent e) {\r
+ events.add(new MouseButtonEvent(e.button,false, e.x, e.y));\r
+ \r
+ }\r
+ \r
+ int px = 0;\r
+ int py = 0;\r
+ \r
+ @Override\r
+ public void mouseMove(MouseEvent e) {\r
+ events.add(new MouseMotionEvent(e.x, e.y, e.x - px, e.y - py, 0, 0));\r
+ px = e.x;\r
+ py = e.y;\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public void mouseScrolled(MouseEvent e) {\r
+ events.add(new MouseMotionEvent(e.x, e.y, 0, 0, e.button, e.count));\r
+ }\r
+ \r
+ @Override\r
+ public void mouseEnter(MouseEvent e) {\r
+ px = e.x;\r
+ py = e.y;\r
+ }\r
+ \r
+ @Override\r
+ public void mouseExit(MouseEvent e) {\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public void mouseHover(MouseEvent e) {\r
+ \r
+ }\r
+ }\r
+ \r
+ public class SWTKeyInput implements KeyInput, KeyListener {\r
+ SWTCanvas canvas;\r
+ boolean init = false;\r
+ RawInputListener listener;\r
+ \r
+ public SWTKeyInput(SWTCanvas canvas) {\r
+ this.canvas = canvas;\r
+ }\r
+ \r
+ @Override\r
+ public void destroy() {\r
+ this.canvas.canvas.removeKeyListener(this);\r
+ }\r
+ \r
+ @Override\r
+ public void initialize() {\r
+ this.canvas.canvas.addKeyListener(this);\r
+ init = true;\r
+ }\r
+ \r
+ @Override\r
+ public boolean isInitialized() {\r
+ return init;\r
+ }\r
+ \r
+ @Override\r
+ public void setInputListener(RawInputListener listener) {\r
+ this.listener = listener;\r
+ }\r
+ \r
+ public long getInputTimeNanos() {\r
+ return Sys.getTime() * LwjglTimer.LWJGL_TIME_TO_NANOS;\r
+ }\r
+ \r
+ private List<KeyInputEvent> events = new ArrayList<KeyInputEvent>();\r
+ \r
+ KeyInputEvent prevEvent = new KeyInputEvent(0, (char)0, false, false);\r
+ \r
+ @Override\r
+ public void update() {\r
+ if (listener == null || events.size() == 0)\r
+ return;\r
+ listener.beginInput();\r
+ \r
+ for (KeyInputEvent e : events) {\r
+ //System.out.println("Key " + e.getKeyCode() + " " + e.getKeyChar() + " " + e.isPressed() + " " + e.isRepeating());\r
+ \r
+ // SWT reports wrong key code in released event for a key, if multiple keys are down at the same time\r
+ // example:\r
+ // press 'a' -> event press a\r
+ // press 'b' -> event press b\r
+ // release 'a' -> event release b\r
+ // keep 'b' pressed -> event press b (with slight pause before events starts coming by)\r
+ // release 'b' -> event release b\r
+ \r
+ // press 'a' -> event press a\r
+ // press 'b' -> event press b\r
+ // release 'b' -> event release b\r
+ // keep 'a' pressed -> nothing happens.\r
+ // release 'a' -> nothing happens\r
+ \r
+ if (e.isPressed()) {\r
+ if (e.getKeyCode() != prevEvent.getKeyCode() && prevEvent.isPressed()) {\r
+ listener.onKeyEvent(new KeyInputEvent(prevEvent.getKeyCode(), prevEvent.getKeyChar(), false, false));\r
+ }\r
+ }\r
+ \r
+ listener.onKeyEvent(e);\r
+ prevEvent = e;\r
+ }\r
+ events.clear();\r
+ listener.endInput();\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public void keyPressed(KeyEvent e) {\r
+ events.add(new KeyInputEvent(getLWJGLKeyCode(e.keyCode), e.character, true, false));\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public void keyReleased(KeyEvent e) {\r
+ \r
+ events.add(new KeyInputEvent(getLWJGLKeyCode(e.keyCode), e.character, false, false));\r
+ }\r
+ \r
+ private int getLWJGLKeyCode(int swtKeyCode) {\r
+ // TODO : LWJGL uses mapping/layout of US keyboard, these have to be checked \r
+ if(swtKeyCode > 1024) {\r
+ int keyCode = 0;\r
+ switch (swtKeyCode) {\r
+ case SWT.CTRL:\r
+ keyCode = Keyboard.KEY_LCONTROL;\r
+ break;\r
+ case SWT.ALT:\r
+ keyCode = Keyboard.KEY_LMETA;\r
+ break;\r
+ \r
+ case SWT.SHIFT:\r
+ keyCode = Keyboard.KEY_LSHIFT;\r
+ break;\r
+ case SWT.ARROW_LEFT:\r
+ keyCode = Keyboard.KEY_LEFT;\r
+ break;\r
+ case SWT.ARROW_RIGHT:\r
+ keyCode = Keyboard.KEY_RIGHT;\r
+ break;\r
+ case SWT.ARROW_UP:\r
+ keyCode = Keyboard.KEY_UP;\r
+ break;\r
+ case SWT.ARROW_DOWN:\r
+ keyCode = Keyboard.KEY_DOWN;\r
+ break;\r
+ case SWT.KEYPAD_0:\r
+ keyCode = Keyboard.KEY_NUMPAD0;\r
+ break;\r
+ case SWT.KEYPAD_1:\r
+ keyCode = Keyboard.KEY_NUMPAD1;\r
+ break;\r
+ case SWT.KEYPAD_2:\r
+ keyCode = Keyboard.KEY_NUMPAD2;\r
+ break;\r
+ case SWT.KEYPAD_3:\r
+ keyCode = Keyboard.KEY_NUMPAD3;\r
+ break;\r
+ case SWT.KEYPAD_4:\r
+ keyCode = Keyboard.KEY_NUMPAD4;\r
+ break;\r
+ case SWT.KEYPAD_5:\r
+ keyCode = Keyboard.KEY_NUMPAD5;\r
+ break;\r
+ case SWT.KEYPAD_6:\r
+ keyCode = Keyboard.KEY_NUMPAD6;\r
+ break;\r
+ case SWT.KEYPAD_7:\r
+ keyCode = Keyboard.KEY_NUMPAD7;\r
+ break;\r
+ case SWT.KEYPAD_8:\r
+ keyCode = Keyboard.KEY_NUMPAD8;\r
+ break;\r
+ case SWT.KEYPAD_9:\r
+ keyCode = Keyboard.KEY_NUMPAD9;\r
+ break;\r
+ case SWT.KEYPAD_CR:\r
+ keyCode = Keyboard.KEY_NUMPADENTER;\r
+ break;\r
+ case SWT.NUM_LOCK:\r
+ keyCode = Keyboard.KEY_NUMLOCK;\r
+ break;\r
+ case SWT.SCROLL_LOCK:\r
+ keyCode = Keyboard.KEY_SCROLL;\r
+ break;\r
+ case SWT.CAPS_LOCK:\r
+ keyCode = Keyboard.KEY_CAPITAL;\r
+ break;\r
+ case SWT.INSERT:\r
+ keyCode = Keyboard.KEY_INSERT;\r
+ break;\r
+ case SWT.HOME:\r
+ keyCode = Keyboard.KEY_HOME;\r
+ break;\r
+ case SWT.END:\r
+ keyCode = Keyboard.KEY_END;\r
+ break;\r
+ case SWT.PAGE_UP:\r
+ keyCode = Keyboard.KEY_NEXT;\r
+ break;\r
+ case SWT.PAGE_DOWN:\r
+ keyCode = Keyboard.KEY_PRIOR;\r
+ break;\r
+ case SWT.PAUSE:\r
+ keyCode = Keyboard.KEY_PAUSE; \r
+ break;\r
+ case SWT.BREAK:\r
+ keyCode = Keyboard.KEY_PAUSE; \r
+ break;\r
+ case SWT.PRINT_SCREEN:\r
+ keyCode = Keyboard.KEY_SYSRQ; \r
+ break; \r
+ case SWT.HELP:\r
+ keyCode = 0;\r
+ break;\r
+ case SWT.KEYPAD_MULTIPLY:\r
+ keyCode = Keyboard.KEY_MULTIPLY;\r
+ break;\r
+ case SWT.KEYPAD_DIVIDE:\r
+ keyCode = Keyboard.KEY_DIVIDE;\r
+ break;\r
+ case SWT.KEYPAD_DECIMAL:\r
+ keyCode = Keyboard.KEY_DECIMAL;\r
+ break;\r
+ case SWT.F1:\r
+ keyCode = Keyboard.KEY_F1;\r
+ break;\r
+ case SWT.F2:\r
+ keyCode = Keyboard.KEY_F2;\r
+ break;\r
+ case SWT.F3:\r
+ keyCode = Keyboard.KEY_F3;\r
+ break;\r
+ case SWT.F4:\r
+ keyCode = Keyboard.KEY_F4;\r
+ break;\r
+ case SWT.F5:\r
+ keyCode = Keyboard.KEY_F5;\r
+ break;\r
+ case SWT.F6:\r
+ keyCode = Keyboard.KEY_F6;\r
+ break;\r
+ case SWT.F7:\r
+ keyCode = Keyboard.KEY_F7;\r
+ break;\r
+ case SWT.F8:\r
+ keyCode = Keyboard.KEY_F8;\r
+ break;\r
+ case SWT.F9:\r
+ keyCode = Keyboard.KEY_F9;\r
+ break;\r
+ case SWT.F10:\r
+ keyCode = Keyboard.KEY_F10;\r
+ break;\r
+ case SWT.F11:\r
+ keyCode = Keyboard.KEY_F11;\r
+ break;\r
+ case SWT.F12:\r
+ keyCode = Keyboard.KEY_F12;\r
+ break;\r
+ default :\r
+ keyCode = Keyboard.KEY_NONE;\r
+ break;\r
+ }\r
+ \r
+ return keyCode;\r
+ } else if (swtKeyCode == 8) {\r
+ return Keyboard.KEY_BACK;\r
+ } else if (swtKeyCode == SWT.ESC) {\r
+ return Keyboard.KEY_ESCAPE;\r
+ } else if (swtKeyCode == SWT.SPACE) {\r
+ return Keyboard.KEY_SPACE;\r
+ } else if (swtKeyCode >= 49 && swtKeyCode < 58) { // 1 - 9\r
+ return swtKeyCode - 47; \r
+ } else if (swtKeyCode == 48) {\r
+ return Keyboard.KEY_0;\r
+ } else if (swtKeyCode == SWT.TAB) {\r
+ return Keyboard.KEY_TAB;\r
+ } else if (swtKeyCode == 46) {\r
+ return Keyboard.KEY_PERIOD;\r
+ } else if (swtKeyCode == 44) {\r
+ return Keyboard.KEY_COMMA;\r
+ } else if (swtKeyCode == 39) { // '/* on SWE/FI keyboard\r
+ return Keyboard.KEY_SLASH;\r
+ } else if (swtKeyCode == 45) {\r
+ return Keyboard.KEY_MINUS;\r
+ } else if (swtKeyCode == 43) {\r
+ return Keyboard.KEY_EQUALS; // +/? on SWE/FI keyboard\r
+ } else if (swtKeyCode == SWT.DEL) {\r
+ return Keyboard.KEY_DELETE;\r
+ } else if (swtKeyCode == SWT.CR) {\r
+ return Keyboard.KEY_RETURN;\r
+ } else if (swtKeyCode == 167) { // ยง on SWE/FI keyboard\r
+ return Keyboard.KEY_BACKSLASH;\r
+ }\r
+ else if (swtKeyCode >= 97 )\r
+ swtKeyCode -= 32;\r
+ if (swtKeyCode >= 65 && swtKeyCode <= 90) {\r
+ switch (swtKeyCode) {\r
+ case 65:\r
+ return Keyboard.KEY_A;\r
+ case 66:\r
+ return Keyboard.KEY_B;\r
+ case 67:\r
+ return Keyboard.KEY_C;\r
+ case 68:\r
+ return Keyboard.KEY_D;\r
+ case 69:\r
+ return Keyboard.KEY_E;\r
+ case 70:\r
+ return Keyboard.KEY_F;\r
+ case 71:\r
+ return Keyboard.KEY_G;\r
+ case 72:\r
+ return Keyboard.KEY_H;\r
+ case 73:\r
+ return Keyboard.KEY_I;\r
+ case 74:\r
+ return Keyboard.KEY_J;\r
+ case 75:\r
+ return Keyboard.KEY_K;\r
+ case 76:\r
+ return Keyboard.KEY_L;\r
+ case 77:\r
+ return Keyboard.KEY_M;\r
+ case 78:\r
+ return Keyboard.KEY_N;\r
+ case 79:\r
+ return Keyboard.KEY_O;\r
+ case 80:\r
+ return Keyboard.KEY_P;\r
+ case 81:\r
+ return Keyboard.KEY_Q;\r
+ case 82:\r
+ return Keyboard.KEY_R;\r
+ case 83:\r
+ return Keyboard.KEY_S;\r
+ case 84:\r
+ return Keyboard.KEY_T;\r
+ case 85:\r
+ return Keyboard.KEY_U;\r
+ case 86:\r
+ return Keyboard.KEY_V;\r
+ case 87:\r
+ return Keyboard.KEY_W;\r
+ case 88:\r
+ return Keyboard.KEY_X;\r
+ case 89:\r
+ return Keyboard.KEY_Y;\r
+ case 90:\r
+ return Keyboard.KEY_Z;\r
+ \r
+ }\r
+ }\r
+ return Keyboard.KEY_UNLABELED;\r
+ }\r
+\r
+ \r
+ private int getAWTKeyCode(int swtKeyCode) {\r
+ if(swtKeyCode > 1024) {\r
+ int keyCode = 0;\r
+ switch (swtKeyCode) {\r
+ case SWT.CTRL:\r
+ keyCode = java.awt.event.KeyEvent.VK_CONTROL;\r
+ break;\r
+ case SWT.ALT:\r
+ keyCode = java.awt.event.KeyEvent.VK_ALT;\r
+ break;\r
+ \r
+ case SWT.SHIFT:\r
+ keyCode = java.awt.event.KeyEvent.VK_SHIFT;\r
+ break;\r
+ case SWT.ARROW_LEFT:\r
+ keyCode = java.awt.event.KeyEvent.VK_LEFT;\r
+ break;\r
+ case SWT.ARROW_RIGHT:\r
+ keyCode = java.awt.event.KeyEvent.VK_RIGHT;\r
+ break;\r
+ case SWT.ARROW_UP:\r
+ keyCode = java.awt.event.KeyEvent.VK_UP;\r
+ break;\r
+ case SWT.ARROW_DOWN:\r
+ keyCode = java.awt.event.KeyEvent.VK_DOWN;\r
+ break;\r
+ case SWT.KEYPAD_0:\r
+ keyCode = java.awt.event.KeyEvent.VK_NUMPAD0;\r
+ break;\r
+ case SWT.KEYPAD_1:\r
+ keyCode = java.awt.event.KeyEvent.VK_NUMPAD1;\r
+ break;\r
+ case SWT.KEYPAD_2:\r
+ keyCode = java.awt.event.KeyEvent.VK_NUMPAD2;\r
+ break;\r
+ case SWT.KEYPAD_3:\r
+ keyCode = java.awt.event.KeyEvent.VK_NUMPAD3;\r
+ break;\r
+ case SWT.KEYPAD_4:\r
+ keyCode = java.awt.event.KeyEvent.VK_NUMPAD4;\r
+ break;\r
+ case SWT.KEYPAD_5:\r
+ keyCode = java.awt.event.KeyEvent.VK_NUMPAD5;\r
+ break;\r
+ case SWT.KEYPAD_6:\r
+ keyCode = java.awt.event.KeyEvent.VK_NUMPAD6;\r
+ break;\r
+ case SWT.KEYPAD_7:\r
+ keyCode = java.awt.event.KeyEvent.VK_NUMPAD7;\r
+ break;\r
+ case SWT.KEYPAD_8:\r
+ keyCode = java.awt.event.KeyEvent.VK_NUMPAD8;\r
+ break;\r
+ case SWT.KEYPAD_9:\r
+ keyCode = java.awt.event.KeyEvent.VK_NUMPAD9;\r
+ break;\r
+ case SWT.KEYPAD_CR:\r
+ keyCode = java.awt.event.KeyEvent.VK_ENTER;\r
+ break;\r
+ case SWT.NUM_LOCK:\r
+ keyCode = java.awt.event.KeyEvent.VK_NUM_LOCK;\r
+ break;\r
+ case SWT.SCROLL_LOCK:\r
+ keyCode = java.awt.event.KeyEvent.VK_SCROLL_LOCK;\r
+ break;\r
+ case SWT.CAPS_LOCK:\r
+ keyCode = java.awt.event.KeyEvent.VK_CAPS_LOCK;\r
+ break;\r
+ case SWT.INSERT:\r
+ keyCode = java.awt.event.KeyEvent.VK_INSERT;\r
+ break;\r
+ case SWT.HOME:\r
+ keyCode = java.awt.event.KeyEvent.VK_HOME;\r
+ break;\r
+ case SWT.END:\r
+ keyCode = java.awt.event.KeyEvent.VK_END;\r
+ break;\r
+ case SWT.PAGE_UP:\r
+ keyCode = java.awt.event.KeyEvent.VK_PAGE_UP;\r
+ break;\r
+ case SWT.PAGE_DOWN:\r
+ keyCode = java.awt.event.KeyEvent.VK_PAGE_DOWN;\r
+ break;\r
+ case SWT.PAUSE:\r
+ keyCode = java.awt.event.KeyEvent.VK_PAUSE; \r
+ break;\r
+ case SWT.BREAK:\r
+ keyCode = java.awt.event.KeyEvent.VK_PAUSE; \r
+ break;\r
+ case SWT.PRINT_SCREEN:\r
+ keyCode = java.awt.event.KeyEvent.VK_PRINTSCREEN; \r
+ break; \r
+ case SWT.HELP:\r
+ keyCode = java.awt.event.KeyEvent.VK_HELP;\r
+ break;\r
+ default :\r
+ keyCode = 0;\r
+ break;\r
+ }\r
+ \r
+ return keyCode;\r
+ } else if (swtKeyCode == 8) {\r
+ return java.awt.event.KeyEvent.VK_BACK_SPACE;\r
+ }\r
+ else if (swtKeyCode >= 97 )\r
+ return swtKeyCode - 32;\r
+ else\r
+ return swtKeyCode;\r
+ }\r
+ }\r
+\r
+}\r