From 54c7447efabda2b9b1279f7398ecd0511852f4e4 Mon Sep 17 00:00:00 2001 From: "jul..om" Date: Sat, 3 Nov 2012 12:11:57 +0000 Subject: [PATCH] Mouse and input support for NEWT canvas and display git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9944 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- .../com/jme3/input/jogl/NewtKeyInput.java | 605 ++++++++++++++++++ .../com/jme3/input/jogl/NewtMouseInput.java | 286 +++++++++ .../jme3/system/jogl/JoglAbstractDisplay.java | 16 +- .../com/jme3/system/jogl/JoglContext.java | 6 +- .../com/jme3/system/jogl/JoglNewtDisplay.java | 3 +- 5 files changed, 904 insertions(+), 12 deletions(-) create mode 100644 engine/src/jogl/com/jme3/input/jogl/NewtKeyInput.java create mode 100644 engine/src/jogl/com/jme3/input/jogl/NewtMouseInput.java diff --git a/engine/src/jogl/com/jme3/input/jogl/NewtKeyInput.java b/engine/src/jogl/com/jme3/input/jogl/NewtKeyInput.java new file mode 100644 index 000000000..9dead1dd2 --- /dev/null +++ b/engine/src/jogl/com/jme3/input/jogl/NewtKeyInput.java @@ -0,0 +1,605 @@ +/* + * Copyright (c) 2009-2012 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jme3.input.jogl; + +import com.jme3.input.KeyInput; +import com.jme3.input.RawInputListener; +import com.jme3.input.event.KeyInputEvent; +import com.jogamp.newt.event.KeyEvent; +import com.jogamp.newt.event.KeyListener; +import com.jogamp.newt.opengl.GLWindow; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class NewtKeyInput implements KeyInput, KeyListener { + + private static final Logger logger = Logger.getLogger(NewtKeyInput.class.getName()); + + private final ArrayList eventQueue = new ArrayList(); + private RawInputListener listener; + private GLWindow component; + private BitSet keyStateSet = new BitSet(0xFF); + + public NewtKeyInput() { + } + + public void initialize() { + } + + public void destroy() { + } + + public void setInputSource(GLWindow comp){ + synchronized (eventQueue){ + if (component != null){ + component.removeKeyListener(this); + eventQueue.clear(); + keyStateSet.clear(); + } + component = comp; + component.addKeyListener(this); + } + } + + public long getInputTimeNanos() { + return System.nanoTime(); + } + + public void update() { + synchronized (eventQueue){ + // flush events to listener + for (int i = 0; i < eventQueue.size(); i++){ + listener.onKeyEvent(eventQueue.get(i)); + } + eventQueue.clear(); + } + } + + public boolean isInitialized() { + return true; + } + + public void setInputListener(RawInputListener listener) { + this.listener = listener; + } + + public void keyTyped(KeyEvent evt) { + // key code is zero for typed events + } + + public void keyPressed(KeyEvent evt) { + int code = convertAwtKey(evt.getKeyCode()); + + // Check if key was already pressed + if (!keyStateSet.get(code)){ + keyStateSet.set(code); + KeyInputEvent keyEvent = new KeyInputEvent(code, evt.getKeyChar(), true, false); + keyEvent.setTime(evt.getWhen()); + synchronized (eventQueue){ + eventQueue.add(keyEvent); + } + System.out.println(evt); + } + } + + public void keyReleased(KeyEvent evt) { + int code = convertAwtKey(evt.getKeyCode()); + + // Check if key was already released + if (keyStateSet.get(code)) { + keyStateSet.clear(code); + KeyInputEvent keyEvent = new KeyInputEvent(code, evt.getKeyChar(), false, false); + keyEvent.setTime(evt.getWhen()); + synchronized (eventQueue){ + eventQueue.add(keyEvent); + } + System.out.println(evt); + } + } + + /** + * convertJmeCode converts KeyInput key codes to AWT key codes. + * + * @param key jme KeyInput key code + * @return awt KeyEvent key code + */ + public static int convertJmeCode( int key ) { + switch ( key ) { + case KEY_ESCAPE: + return KeyEvent.VK_ESCAPE; + case KEY_1: + return KeyEvent.VK_1; + case KEY_2: + return KeyEvent.VK_2; + case KEY_3: + return KeyEvent.VK_3; + case KEY_4: + return KeyEvent.VK_4; + case KEY_5: + return KeyEvent.VK_5; + case KEY_6: + return KeyEvent.VK_6; + case KEY_7: + return KeyEvent.VK_7; + case KEY_8: + return KeyEvent.VK_8; + case KEY_9: + return KeyEvent.VK_9; + case KEY_0: + return KeyEvent.VK_0; + case KEY_MINUS: + return KeyEvent.VK_MINUS; + case KEY_EQUALS: + return KeyEvent.VK_EQUALS; + case KEY_BACK: + return KeyEvent.VK_BACK_SPACE; + case KEY_TAB: + return KeyEvent.VK_TAB; + case KEY_Q: + return KeyEvent.VK_Q; + case KEY_W: + return KeyEvent.VK_W; + case KEY_E: + return KeyEvent.VK_E; + case KEY_R: + return KeyEvent.VK_R; + case KEY_T: + return KeyEvent.VK_T; + case KEY_Y: + return KeyEvent.VK_Y; + case KEY_U: + return KeyEvent.VK_U; + case KEY_I: + return KeyEvent.VK_I; + case KEY_O: + return KeyEvent.VK_O; + case KEY_P: + return KeyEvent.VK_P; + case KEY_LBRACKET: + return KeyEvent.VK_OPEN_BRACKET; + case KEY_RBRACKET: + return KeyEvent.VK_CLOSE_BRACKET; + case KEY_RETURN: + return KeyEvent.VK_ENTER; + case KEY_LCONTROL: + return KeyEvent.VK_CONTROL; + case KEY_A: + return KeyEvent.VK_A; + case KEY_S: + return KeyEvent.VK_S; + case KEY_D: + return KeyEvent.VK_D; + case KEY_F: + return KeyEvent.VK_F; + case KEY_G: + return KeyEvent.VK_G; + case KEY_H: + return KeyEvent.VK_H; + case KEY_J: + return KeyEvent.VK_J; + case KEY_K: + return KeyEvent.VK_K; + case KEY_L: + return KeyEvent.VK_L; + case KEY_SEMICOLON: + return KeyEvent.VK_SEMICOLON; + case KEY_APOSTROPHE: + return KeyEvent.VK_QUOTE; + case KEY_GRAVE: + return KeyEvent.VK_DEAD_GRAVE; + case KEY_LSHIFT: + return KeyEvent.VK_SHIFT; + case KEY_BACKSLASH: + return KeyEvent.VK_BACK_SLASH; + case KEY_Z: + return KeyEvent.VK_Z; + case KEY_X: + return KeyEvent.VK_X; + case KEY_C: + return KeyEvent.VK_C; + case KEY_V: + return KeyEvent.VK_V; + case KEY_B: + return KeyEvent.VK_B; + case KEY_N: + return KeyEvent.VK_N; + case KEY_M: + return KeyEvent.VK_M; + case KEY_COMMA: + return KeyEvent.VK_COMMA; + case KEY_PERIOD: + return KeyEvent.VK_PERIOD; + case KEY_SLASH: + return KeyEvent.VK_SLASH; + case KEY_RSHIFT: + return KeyEvent.VK_SHIFT; + case KEY_MULTIPLY: + return KeyEvent.VK_MULTIPLY; + case KEY_SPACE: + return KeyEvent.VK_SPACE; + case KEY_CAPITAL: + return KeyEvent.VK_CAPS_LOCK; + case KEY_F1: + return KeyEvent.VK_F1; + case KEY_F2: + return KeyEvent.VK_F2; + case KEY_F3: + return KeyEvent.VK_F3; + case KEY_F4: + return KeyEvent.VK_F4; + case KEY_F5: + return KeyEvent.VK_F5; + case KEY_F6: + return KeyEvent.VK_F6; + case KEY_F7: + return KeyEvent.VK_F7; + case KEY_F8: + return KeyEvent.VK_F8; + case KEY_F9: + return KeyEvent.VK_F9; + case KEY_F10: + return KeyEvent.VK_F10; + case KEY_NUMLOCK: + return KeyEvent.VK_NUM_LOCK; + case KEY_SCROLL: + return KeyEvent.VK_SCROLL_LOCK; + case KEY_NUMPAD7: + return KeyEvent.VK_NUMPAD7; + case KEY_NUMPAD8: + return KeyEvent.VK_NUMPAD8; + case KEY_NUMPAD9: + return KeyEvent.VK_NUMPAD9; + case KEY_SUBTRACT: + return KeyEvent.VK_SUBTRACT; + case KEY_NUMPAD4: + return KeyEvent.VK_NUMPAD4; + case KEY_NUMPAD5: + return KeyEvent.VK_NUMPAD5; + case KEY_NUMPAD6: + return KeyEvent.VK_NUMPAD6; + case KEY_ADD: + return KeyEvent.VK_ADD; + case KEY_NUMPAD1: + return KeyEvent.VK_NUMPAD1; + case KEY_NUMPAD2: + return KeyEvent.VK_NUMPAD2; + case KEY_NUMPAD3: + return KeyEvent.VK_NUMPAD3; + case KEY_NUMPAD0: + return KeyEvent.VK_NUMPAD0; + case KEY_DECIMAL: + return KeyEvent.VK_DECIMAL; + case KEY_F11: + return KeyEvent.VK_F11; + case KEY_F12: + return KeyEvent.VK_F12; + case KEY_F13: + return KeyEvent.VK_F13; + case KEY_F14: + return KeyEvent.VK_F14; + case KEY_F15: + return KeyEvent.VK_F15; + case KEY_KANA: + return KeyEvent.VK_KANA; + case KEY_CONVERT: + return KeyEvent.VK_CONVERT; + case KEY_NOCONVERT: + return KeyEvent.VK_NONCONVERT; + case KEY_NUMPADEQUALS: + return KeyEvent.VK_EQUALS; + case KEY_CIRCUMFLEX: + return KeyEvent.VK_CIRCUMFLEX; + case KEY_AT: + return KeyEvent.VK_AT; + case KEY_COLON: + return KeyEvent.VK_COLON; + case KEY_UNDERLINE: + return KeyEvent.VK_UNDERSCORE; + case KEY_STOP: + return KeyEvent.VK_STOP; + case KEY_NUMPADENTER: + return KeyEvent.VK_ENTER; + case KEY_RCONTROL: + return KeyEvent.VK_CONTROL; + case KEY_NUMPADCOMMA: + return KeyEvent.VK_COMMA; + case KEY_DIVIDE: + return KeyEvent.VK_DIVIDE; + case KEY_PAUSE: + return KeyEvent.VK_PAUSE; + case KEY_HOME: + return KeyEvent.VK_HOME; + case KEY_UP: + return KeyEvent.VK_UP; + case KEY_PRIOR: + return KeyEvent.VK_PAGE_UP; + case KEY_LEFT: + return KeyEvent.VK_LEFT; + case KEY_RIGHT: + return KeyEvent.VK_RIGHT; + case KEY_END: + return KeyEvent.VK_END; + case KEY_DOWN: + return KeyEvent.VK_DOWN; + case KEY_NEXT: + return KeyEvent.VK_PAGE_DOWN; + case KEY_INSERT: + return KeyEvent.VK_INSERT; + case KEY_DELETE: + return KeyEvent.VK_DELETE; + case KEY_LMENU: + return KeyEvent.VK_ALT; //todo: location left + case KEY_RMENU: + return KeyEvent.VK_ALT; //todo: location right + } + logger.log(Level.WARNING, "unsupported key:{0}", key); + return 0x10000 + key; + } + + /** + * convertAwtKey converts AWT key codes to KeyInput key codes. + * + * @param key awt KeyEvent key code + * @return jme KeyInput key code + */ + public static int convertAwtKey(int key) { + switch ( key ) { + case KeyEvent.VK_ESCAPE: + return KEY_ESCAPE; + case KeyEvent.VK_1: + return KEY_1; + case KeyEvent.VK_2: + return KEY_2; + case KeyEvent.VK_3: + return KEY_3; + case KeyEvent.VK_4: + return KEY_4; + case KeyEvent.VK_5: + return KEY_5; + case KeyEvent.VK_6: + return KEY_6; + case KeyEvent.VK_7: + return KEY_7; + case KeyEvent.VK_8: + return KEY_8; + case KeyEvent.VK_9: + return KEY_9; + case KeyEvent.VK_0: + return KEY_0; + case KeyEvent.VK_MINUS: + return KEY_MINUS; + case KeyEvent.VK_EQUALS: + return KEY_EQUALS; + case KeyEvent.VK_BACK_SPACE: + return KEY_BACK; + case KeyEvent.VK_TAB: + return KEY_TAB; + case KeyEvent.VK_Q: + return KEY_Q; + case KeyEvent.VK_W: + return KEY_W; + case KeyEvent.VK_E: + return KEY_E; + case KeyEvent.VK_R: + return KEY_R; + case KeyEvent.VK_T: + return KEY_T; + case KeyEvent.VK_Y: + return KEY_Y; + case KeyEvent.VK_U: + return KEY_U; + case KeyEvent.VK_I: + return KEY_I; + case KeyEvent.VK_O: + return KEY_O; + case KeyEvent.VK_P: + return KEY_P; + case KeyEvent.VK_OPEN_BRACKET: + return KEY_LBRACKET; + case KeyEvent.VK_CLOSE_BRACKET: + return KEY_RBRACKET; + case KeyEvent.VK_ENTER: + return KEY_RETURN; + case KeyEvent.VK_CONTROL: + return KEY_LCONTROL; + case KeyEvent.VK_A: + return KEY_A; + case KeyEvent.VK_S: + return KEY_S; + case KeyEvent.VK_D: + return KEY_D; + case KeyEvent.VK_F: + return KEY_F; + case KeyEvent.VK_G: + return KEY_G; + case KeyEvent.VK_H: + return KEY_H; + case KeyEvent.VK_J: + return KEY_J; + case KeyEvent.VK_K: + return KEY_K; + case KeyEvent.VK_L: + return KEY_L; + case KeyEvent.VK_SEMICOLON: + return KEY_SEMICOLON; + case KeyEvent.VK_QUOTE: + return KEY_APOSTROPHE; + case KeyEvent.VK_DEAD_GRAVE: + return KEY_GRAVE; + case KeyEvent.VK_SHIFT: + return KEY_LSHIFT; + case KeyEvent.VK_BACK_SLASH: + return KEY_BACKSLASH; + case KeyEvent.VK_Z: + return KEY_Z; + case KeyEvent.VK_X: + return KEY_X; + case KeyEvent.VK_C: + return KEY_C; + case KeyEvent.VK_V: + return KEY_V; + case KeyEvent.VK_B: + return KEY_B; + case KeyEvent.VK_N: + return KEY_N; + case KeyEvent.VK_M: + return KEY_M; + case KeyEvent.VK_COMMA: + return KEY_COMMA; + case KeyEvent.VK_PERIOD: + return KEY_PERIOD; + case KeyEvent.VK_SLASH: + return KEY_SLASH; + case KeyEvent.VK_MULTIPLY: + return KEY_MULTIPLY; + case KeyEvent.VK_SPACE: + return KEY_SPACE; + case KeyEvent.VK_CAPS_LOCK: + return KEY_CAPITAL; + case KeyEvent.VK_F1: + return KEY_F1; + case KeyEvent.VK_F2: + return KEY_F2; + case KeyEvent.VK_F3: + return KEY_F3; + case KeyEvent.VK_F4: + return KEY_F4; + case KeyEvent.VK_F5: + return KEY_F5; + case KeyEvent.VK_F6: + return KEY_F6; + case KeyEvent.VK_F7: + return KEY_F7; + case KeyEvent.VK_F8: + return KEY_F8; + case KeyEvent.VK_F9: + return KEY_F9; + case KeyEvent.VK_F10: + return KEY_F10; + case KeyEvent.VK_NUM_LOCK: + return KEY_NUMLOCK; + case KeyEvent.VK_SCROLL_LOCK: + return KEY_SCROLL; + case KeyEvent.VK_NUMPAD7: + return KEY_NUMPAD7; + case KeyEvent.VK_NUMPAD8: + return KEY_NUMPAD8; + case KeyEvent.VK_NUMPAD9: + return KEY_NUMPAD9; + case KeyEvent.VK_SUBTRACT: + return KEY_SUBTRACT; + case KeyEvent.VK_NUMPAD4: + return KEY_NUMPAD4; + case KeyEvent.VK_NUMPAD5: + return KEY_NUMPAD5; + case KeyEvent.VK_NUMPAD6: + return KEY_NUMPAD6; + case KeyEvent.VK_ADD: + return KEY_ADD; + case KeyEvent.VK_NUMPAD1: + return KEY_NUMPAD1; + case KeyEvent.VK_NUMPAD2: + return KEY_NUMPAD2; + case KeyEvent.VK_NUMPAD3: + return KEY_NUMPAD3; + case KeyEvent.VK_NUMPAD0: + return KEY_NUMPAD0; + case KeyEvent.VK_DECIMAL: + return KEY_DECIMAL; + case KeyEvent.VK_F11: + return KEY_F11; + case KeyEvent.VK_F12: + return KEY_F12; + case KeyEvent.VK_F13: + return KEY_F13; + case KeyEvent.VK_F14: + return KEY_F14; + case KeyEvent.VK_F15: + return KEY_F15; + case KeyEvent.VK_KANA: + return KEY_KANA; + case KeyEvent.VK_CONVERT: + return KEY_CONVERT; + case KeyEvent.VK_NONCONVERT: + return KEY_NOCONVERT; + case KeyEvent.VK_CIRCUMFLEX: + return KEY_CIRCUMFLEX; + case KeyEvent.VK_AT: + return KEY_AT; + case KeyEvent.VK_COLON: + return KEY_COLON; + case KeyEvent.VK_UNDERSCORE: + return KEY_UNDERLINE; + case KeyEvent.VK_STOP: + return KEY_STOP; + case KeyEvent.VK_DIVIDE: + return KEY_DIVIDE; + case KeyEvent.VK_PAUSE: + return KEY_PAUSE; + case KeyEvent.VK_HOME: + return KEY_HOME; + case KeyEvent.VK_UP: + return KEY_UP; + case KeyEvent.VK_PAGE_UP: + return KEY_PRIOR; + case KeyEvent.VK_LEFT: + return KEY_LEFT; + case KeyEvent.VK_RIGHT: + return KEY_RIGHT; + case KeyEvent.VK_END: + return KEY_END; + case KeyEvent.VK_DOWN: + return KEY_DOWN; + case KeyEvent.VK_PAGE_DOWN: + return KEY_NEXT; + case KeyEvent.VK_INSERT: + return KEY_INSERT; + case KeyEvent.VK_DELETE: + return KEY_DELETE; + case KeyEvent.VK_ALT: + return KEY_LMENU; //Left vs. Right need to improve + case KeyEvent.VK_META: + return KEY_RCONTROL; + + } + logger.log( Level.WARNING, "unsupported key:{0}", key); + if ( key >= 0x10000 ) { + return key - 0x10000; + } + + return 0; + } + +} diff --git a/engine/src/jogl/com/jme3/input/jogl/NewtMouseInput.java b/engine/src/jogl/com/jme3/input/jogl/NewtMouseInput.java new file mode 100644 index 000000000..7ae3f7df3 --- /dev/null +++ b/engine/src/jogl/com/jme3/input/jogl/NewtMouseInput.java @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2009-2012 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jme3.input.jogl; + +import com.jme3.cursors.plugins.JmeCursor; +import com.jme3.input.MouseInput; +import com.jme3.input.RawInputListener; +import com.jme3.input.awt.AwtMouseInput; +import com.jme3.input.event.MouseButtonEvent; +import com.jme3.input.event.MouseMotionEvent; +import com.jogamp.newt.event.MouseEvent; +import com.jogamp.newt.event.MouseListener; +import com.jogamp.newt.opengl.GLWindow; +import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.media.nativewindow.util.Point; + +public class NewtMouseInput implements MouseInput, MouseListener { + + public static int WHEEL_AMP = 40; // arbitrary... Java's mouse wheel seems to report something a lot lower than lwjgl's + + private static final Logger logger = Logger.getLogger(AwtMouseInput.class.getName()); + + private boolean visible = true; + + private RawInputListener listener; + + private GLWindow component; + + private final ArrayList eventQueue = new ArrayList(); + private final ArrayList eventQueueCopy = new ArrayList(); + + private int lastEventX; + private int lastEventY; + private int lastEventWheel; + + private int wheelPos; + private Point location; + private Point centerLocation; + private Point centerLocationOnScreen; + private Point lastKnownLocation; + private boolean isRecentering; + private boolean cursorMoved; + private int eventsSinceRecenter; + + public NewtMouseInput() { + location = new Point(); + centerLocation = new Point(); + centerLocationOnScreen = new Point(); + lastKnownLocation = new Point(); + } + + public void setInputSource(GLWindow comp) { + if (component != null) { + component.removeMouseListener(this); + + eventQueue.clear(); + + wheelPos = 0; + isRecentering = false; + eventsSinceRecenter = 0; + lastEventX = 0; + lastEventY = 0; + lastEventWheel = 0; + location = new Point(); + centerLocation = new Point(); + centerLocationOnScreen = new Point(); + lastKnownLocation = new Point(); + } + + component = comp; + component.addMouseListener(this); + } + + public void initialize() { + } + + public void destroy() { + } + + public boolean isInitialized() { + return true; + } + + public void setInputListener(RawInputListener listener) { + this.listener = listener; + } + + public long getInputTimeNanos() { + return System.nanoTime(); + } + + public void setCursorVisible(boolean visible) { + if (this.visible != visible) { + lastKnownLocation.setX(0); + lastKnownLocation.setY(0); + + this.visible = visible; + component.setPointerVisible(visible); + if (!visible) { + recenterMouse(component); + } + } + } + + public void update() { + if (cursorMoved) { + int newX = location.getX(); + int newY = location.getY(); + int newWheel = wheelPos; + + // invert DY + int actualX = lastKnownLocation.getX(); + int actualY = component.getHeight() - lastKnownLocation.getY(); + MouseMotionEvent evt = new MouseMotionEvent(actualX, actualY, + newX - lastEventX, + lastEventY - newY, + wheelPos, lastEventWheel - wheelPos); + listener.onMouseMotionEvent(evt); + + lastEventX = newX; + lastEventY = newY; + lastEventWheel = newWheel; + + cursorMoved = false; + } + + synchronized (eventQueue) { + eventQueueCopy.clear(); + eventQueueCopy.addAll(eventQueue); + eventQueue.clear(); + } + + int size = eventQueueCopy.size(); + for (int i = 0; i < size; i++) { + listener.onMouseButtonEvent(eventQueueCopy.get(i)); + } + } + + public int getButtonCount() { + return 3; + } + + public void mouseClicked(MouseEvent awtEvt) { +// MouseButtonEvent evt = new MouseButtonEvent(getJMEButtonIndex(arg0), false); +// listener.onMouseButtonEvent(evt); + } + + public void mousePressed(MouseEvent awtEvt) { + MouseButtonEvent evt = new MouseButtonEvent(getJMEButtonIndex(awtEvt), true, awtEvt.getX(), awtEvt.getY()); + evt.setTime(awtEvt.getWhen()); + synchronized (eventQueue) { + eventQueue.add(evt); + } + } + + public void mouseReleased(MouseEvent awtEvt) { + MouseButtonEvent evt = new MouseButtonEvent(getJMEButtonIndex(awtEvt), false, awtEvt.getX(), awtEvt.getY()); + evt.setTime(awtEvt.getWhen()); + synchronized (eventQueue) { + eventQueue.add(evt); + } + } + + public void mouseEntered(MouseEvent awtEvt) { + if (!visible) { + recenterMouse(component); + } + } + + public void mouseExited(MouseEvent awtEvt) { + if (!visible) { + recenterMouse(component); + } + } + + public void mouseWheelMoved(MouseEvent awtEvt) { + //FIXME not sure this is the right way to handle this case + int dwheel = awtEvt.getWheelRotation(); + wheelPos += dwheel * WHEEL_AMP; + cursorMoved = true; + } + + public void mouseDragged(MouseEvent awtEvt) { + mouseMoved(awtEvt); + } + + public void mouseMoved(MouseEvent awtEvt) { + if (isRecentering) { + // MHenze (cylab) Fix Issue 35: + // As long as the MouseInput is in recentering mode, nothing is done until the mouse is entered in the component + // by the events generated by the robot. If this happens, the last known location is resetted. + if ((centerLocation.getX() == awtEvt.getX() && centerLocation.getY() == awtEvt.getY()) || eventsSinceRecenter++ == 5) { + lastKnownLocation.setX(awtEvt.getX()); + lastKnownLocation.setY(awtEvt.getY()); + isRecentering = false; + } + } else { + // MHenze (cylab) Fix Issue 35: + // Compute the delta and absolute coordinates and recenter the mouse if necessary + int dx = awtEvt.getX() - lastKnownLocation.getX(); + int dy = awtEvt.getY() - lastKnownLocation.getY(); + location.setX(location.getX() + dx); + location.setY(location.getY() + dy); + if (!visible) { + recenterMouse(component); + } + lastKnownLocation.setX(awtEvt.getX()); + lastKnownLocation.setY(awtEvt.getY()); + + cursorMoved = true; + } + } + + // MHenze (cylab) Fix Issue 35: A method to generate recenter the mouse to allow the InputSystem to "grab" the mouse + private void recenterMouse(final GLWindow component) { + eventsSinceRecenter = 0; + isRecentering = true; + centerLocation.setX(component.getWidth() / 2); + centerLocation.setY(component.getHeight() / 2); + centerLocationOnScreen.setX(centerLocation.getX()); + centerLocationOnScreen.setY(centerLocation.getY()); + + component.warpPointer(centerLocationOnScreen.getX(), centerLocationOnScreen.getY()); + } + + private int getJMEButtonIndex(MouseEvent awtEvt) { + int index; + switch (awtEvt.getButton()) { + default: + case MouseEvent.BUTTON1: //left + index = MouseInput.BUTTON_LEFT; + break; + case MouseEvent.BUTTON2: //middle + index = MouseInput.BUTTON_MIDDLE; + break; + case MouseEvent.BUTTON3: //right + index = MouseInput.BUTTON_RIGHT; + break; + case MouseEvent.BUTTON4: + case MouseEvent.BUTTON5: + case MouseEvent.BUTTON6: + case MouseEvent.BUTTON7: + case MouseEvent.BUTTON8: + case MouseEvent.BUTTON9: + //FIXME + index = 0; + break; + } + return index; + } + + public void setNativeCursor(JmeCursor cursor) { + } +} \ No newline at end of file diff --git a/engine/src/jogl/com/jme3/system/jogl/JoglAbstractDisplay.java b/engine/src/jogl/com/jme3/system/jogl/JoglAbstractDisplay.java index 8540c0ac6..cc3bd31cd 100644 --- a/engine/src/jogl/com/jme3/system/jogl/JoglAbstractDisplay.java +++ b/engine/src/jogl/com/jme3/system/jogl/JoglAbstractDisplay.java @@ -161,16 +161,20 @@ public abstract class JoglAbstractDisplay extends JoglContext implements GLEvent @Override public KeyInput getKeyInput() { - AwtKeyInput awtKeyInput = new AwtKeyInput(); - awtKeyInput.setInputSource(canvas); - return awtKeyInput; + if (keyInput == null) { + keyInput = new AwtKeyInput(); + ((AwtKeyInput)keyInput).setInputSource(canvas); + } + return keyInput; } @Override public MouseInput getMouseInput() { - AwtMouseInput awtMouseInput = new AwtMouseInput(); - awtMouseInput.setInputSource(canvas); - return awtMouseInput; + if (mouseInput == null) { + mouseInput = new AwtMouseInput(); + ((AwtMouseInput)mouseInput).setInputSource(canvas); + } + return mouseInput; } public TouchInput getTouchInput() { diff --git a/engine/src/jogl/com/jme3/system/jogl/JoglContext.java b/engine/src/jogl/com/jme3/system/jogl/JoglContext.java index f6abcbde8..aadfb2f18 100644 --- a/engine/src/jogl/com/jme3/system/jogl/JoglContext.java +++ b/engine/src/jogl/com/jme3/system/jogl/JoglContext.java @@ -35,8 +35,6 @@ package com.jme3.system.jogl; import com.jme3.input.JoyInput; import com.jme3.input.KeyInput; import com.jme3.input.MouseInput; -import com.jme3.input.awt.AwtKeyInput; -import com.jme3.input.awt.AwtMouseInput; import com.jme3.renderer.Renderer; import com.jme3.renderer.jogl.JoglRenderer; import com.jme3.system.AppSettings; @@ -57,8 +55,8 @@ public abstract class JoglContext implements JmeContext { protected Timer timer; protected SystemListener listener; - protected AwtKeyInput keyInput; - protected AwtMouseInput mouseInput; + protected KeyInput keyInput; + protected MouseInput mouseInput; public void setSystemListener(SystemListener listener){ this.listener = listener; diff --git a/engine/src/jogl/com/jme3/system/jogl/JoglNewtDisplay.java b/engine/src/jogl/com/jme3/system/jogl/JoglNewtDisplay.java index edb404831..398d784b6 100644 --- a/engine/src/jogl/com/jme3/system/jogl/JoglNewtDisplay.java +++ b/engine/src/jogl/com/jme3/system/jogl/JoglNewtDisplay.java @@ -126,11 +126,10 @@ public class JoglNewtDisplay extends JoglNewtAbstractDisplay { } ScreenMode currentScreenMode = screen.getCurrentScreenMode(); - //FIXME get "bits per pixel" logger.log(Level.INFO, "Selected display mode: {0}x{1}x{2} @{3}", new Object[]{currentScreenMode.getRotatedWidth(), currentScreenMode.getRotatedHeight(), - -1, + currentScreenMode.getMonitorMode().getSurfaceSize().getBitsPerPixel(), currentScreenMode.getMonitorMode().getRefreshRate()}); }