Ver Fonte

Mouse and input support for NEWT canvas and display

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9944 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
jul..om há 13 anos atrás
pai
commit
54c7447efa

+ 605 - 0
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<KeyInputEvent> eventQueue = new ArrayList<KeyInputEvent>();
+    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);
+        }
+    }
+
+    /**
+     * <code>convertJmeCode</code> 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;
+    }
+
+    /**
+     * <code>convertAwtKey</code> 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;
+    }
+    
+}

+ 286 - 0
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<MouseButtonEvent> eventQueue = new ArrayList<MouseButtonEvent>();
+    private final ArrayList<MouseButtonEvent> eventQueueCopy = new ArrayList<MouseButtonEvent>();
+
+    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) {
+    }
+}

+ 10 - 6
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() {

+ 2 - 4
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;

+ 1 - 2
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()});
     }