aboutsummaryrefslogtreecommitdiff
path: root/engine/src/desktop/com/jme3/input/awt
diff options
context:
space:
mode:
authorScott Barta <sbarta@google.com>2012-03-01 12:35:35 -0800
committerScott Barta <sbarta@google.com>2012-03-01 12:40:08 -0800
commit59b2e6871c65f58fdad78cd7229c292f6a177578 (patch)
tree2d4e7bfc05b93f40b34675d77e403dd1c25efafd /engine/src/desktop/com/jme3/input/awt
parentf9b30489e75ac1eabc365064959804e99534f7ab (diff)
downloadjmonkeyengine-59b2e6871c65f58fdad78cd7229c292f6a177578.tar.gz
Adds the jMonkeyEngine library to the build.
Adds the jMonkeyEngine open source 3D game engine to the build. This is built as a static library and is only used by the Finsky client. Change-Id: I06a3f054df7b8a67757267d884854f70c5a16ca0
Diffstat (limited to 'engine/src/desktop/com/jme3/input/awt')
-rw-r--r--engine/src/desktop/com/jme3/input/awt/AwtKeyInput.java606
-rw-r--r--engine/src/desktop/com/jme3/input/awt/AwtMouseInput.java313
2 files changed, 919 insertions, 0 deletions
diff --git a/engine/src/desktop/com/jme3/input/awt/AwtKeyInput.java b/engine/src/desktop/com/jme3/input/awt/AwtKeyInput.java
new file mode 100644
index 0000000..8667074
--- /dev/null
+++ b/engine/src/desktop/com/jme3/input/awt/AwtKeyInput.java
@@ -0,0 +1,606 @@
+/*
+ * Copyright (c) 2009-2010 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.awt;
+
+import com.jme3.input.KeyInput;
+import com.jme3.input.RawInputListener;
+import com.jme3.input.event.KeyInputEvent;
+import java.awt.Component;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.util.ArrayList;
+import java.util.logging.Logger;
+
+/**
+ * <code>AwtKeyInput</code>
+ *
+ * @author Joshua Slack
+ * @author Kirill Vainer
+ * @version $Revision: 4133 $
+ */
+public class AwtKeyInput implements KeyInput, KeyListener {
+
+ private static final Logger logger = Logger.getLogger(AwtKeyInput.class.getName());
+
+ private final ArrayList<KeyInputEvent> eventQueue = new ArrayList<KeyInputEvent>();
+ private RawInputListener listener;
+ private Component component;
+
+ public AwtKeyInput(){
+ }
+
+ public void initialize() {
+ }
+
+ public void destroy() {
+ }
+
+ public void setInputSource(Component comp){
+ synchronized (eventQueue){
+ if (component != null){
+ component.removeKeyListener(this);
+ eventQueue.clear();
+ }
+ component = comp;
+ component.addKeyListener(this);
+ }
+ }
+
+ public long getInputTimeNanos() {
+ return System.nanoTime();
+ }
+
+ public int getKeyCount() {
+ return KeyEvent.KEY_LAST+1;
+ }
+
+ 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
+// int code = 0;
+// KeyInputEvent keyEvent = new KeyInputEvent(code, evt.getKeyChar(), false, true);
+// keyEvent.setTime(evt.getWhen());
+// synchronized (eventQueue){
+// eventQueue.add(keyEvent);
+// }
+ }
+
+ public void keyPressed(KeyEvent evt) {
+ int code = convertAwtKey(evt.getKeyCode());
+ KeyInputEvent keyEvent = new KeyInputEvent(code, evt.getKeyChar(), true, false);
+ keyEvent.setTime(evt.getWhen());
+ synchronized (eventQueue){
+ eventQueue.add(keyEvent);
+ }
+ }
+
+ public void keyReleased(KeyEvent evt) {
+ int code = convertAwtKey(evt.getKeyCode());
+ KeyInputEvent keyEvent = new KeyInputEvent(code, evt.getKeyChar(), false, false);
+ keyEvent.setTime(evt.getWhen());
+ synchronized (eventQueue){
+ eventQueue.add(keyEvent);
+ }
+ }
+
+ /**
+ * <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.warning("unsupported key:" + 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.warning( "unsupported key:" + key );
+ if ( key >= 0x10000 ) {
+ return key - 0x10000;
+ }
+
+ return 0;
+ }
+
+}
diff --git a/engine/src/desktop/com/jme3/input/awt/AwtMouseInput.java b/engine/src/desktop/com/jme3/input/awt/AwtMouseInput.java
new file mode 100644
index 0000000..e83c92a
--- /dev/null
+++ b/engine/src/desktop/com/jme3/input/awt/AwtMouseInput.java
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2009-2010 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.awt;
+
+import com.jme3.input.MouseInput;
+import com.jme3.input.RawInputListener;
+import com.jme3.input.event.MouseButtonEvent;
+import com.jme3.input.event.MouseMotionEvent;
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.image.BufferedImage;
+import java.util.ArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.SwingUtilities;
+
+/**
+ * <code>AwtMouseInput</code>
+ *
+ * @author Joshua Slack
+ * @author MHenze (cylab)
+ *
+ * @version $Revision$
+ */
+public class AwtMouseInput implements MouseInput, MouseListener, MouseWheelListener, MouseMotionListener {
+
+ 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 Component 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 Cursor transparentCursor;
+
+ private Robot robot;
+ 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 AwtMouseInput() {
+ location = new Point();
+ centerLocation = new Point();
+ centerLocationOnScreen = new Point();
+ lastKnownLocation = new Point();
+
+ try{
+ robot = new Robot();
+ }catch (java.awt.AWTException e){
+ logger.log(Level.SEVERE, "Could not create a robot, so the mouse cannot be grabbed! ", e);
+ }
+ }
+
+ public void setInputSource(Component comp){
+ if (component != null){
+ component.removeMouseListener(this);
+ component.removeMouseMotionListener(this);
+ component.removeMouseWheelListener(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);
+ component.addMouseMotionListener(this);
+ component.addMouseWheelListener(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.x = lastKnownLocation.y = 0;
+
+ this.visible = visible;
+ final boolean newVisible = visible;
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ component.setCursor(newVisible ? null : getTransparentCursor());
+ if (!newVisible)
+ recenterMouse(component);
+ }
+ });
+ }
+ }
+
+ public void update() {
+ if (cursorMoved){
+ int newX = location.x;
+ int newY = location.y;
+ int newWheel = wheelPos;
+
+ // invert DY
+ int actualX = lastKnownLocation.x;
+ int actualY = component.getHeight() - lastKnownLocation.y;
+ 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));
+ }
+ }
+
+ private Cursor getTransparentCursor() {
+ if (transparentCursor == null){
+ BufferedImage cursorImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
+ cursorImage.setRGB(0, 0, 0);
+ transparentCursor = Toolkit.getDefaultToolkit().createCustomCursor(cursorImage, new Point(0, 0), "empty cursor");
+ }
+ return transparentCursor;
+ }
+
+// public void setHardwareCursor(URL file, int xHotspot, int yHotspot) {
+// //Create the image from the provided url
+// java.awt.Image cursorImage = new ImageIcon( file ).getImage( );
+// //Create a custom cursor with this image
+// opaqueCursor = Toolkit.getDefaultToolkit().createCustomCursor( cursorImage , new Point( xHotspot , yHotspot ) , "custom cursor" );
+// //Use this cursor
+// setCursorVisible( isCursorVisible );
+// }
+
+
+ public int getButtonCount() {
+ return 3;
+ }
+
+ public void mouseClicked(MouseEvent arg0) {
+// MouseButtonEvent evt = new MouseButtonEvent(getJMEButtonIndex(arg0), false);
+// listener.onMouseButtonEvent(evt);
+ }
+
+ public void mousePressed(MouseEvent arg0) {
+ MouseButtonEvent evt = new MouseButtonEvent(getJMEButtonIndex(arg0), true, arg0.getX(), arg0.getY());
+ evt.setTime(arg0.getWhen());
+ synchronized (eventQueue){
+ eventQueue.add(evt);
+ }
+ }
+
+ public void mouseReleased(MouseEvent arg0) {
+ MouseButtonEvent evt = new MouseButtonEvent(getJMEButtonIndex(arg0), false, arg0.getX(), arg0.getY());
+ evt.setTime(arg0.getWhen());
+ synchronized (eventQueue){
+ eventQueue.add(evt);
+ }
+ }
+
+ public void mouseEntered(MouseEvent arg0) {
+ if (!visible)
+ recenterMouse(arg0.getComponent());
+ }
+
+ public void mouseExited(MouseEvent arg0) {
+ if (!visible)
+ recenterMouse(arg0.getComponent());
+ }
+
+ public void mouseWheelMoved(MouseWheelEvent arg0) {
+ int dwheel = arg0.getUnitsToScroll();
+ wheelPos += dwheel * WHEEL_AMP;
+ cursorMoved = true;
+ }
+
+ public void mouseDragged(MouseEvent arg0) {
+ mouseMoved(arg0);
+ }
+
+ public void mouseMoved(MouseEvent arg0) {
+ 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.x == arg0.getX() && centerLocation.y == arg0.getY()) || eventsSinceRecenter++ == 5) {
+ lastKnownLocation.x = arg0.getX();
+ lastKnownLocation.y = arg0.getY();
+ isRecentering = false;
+ }
+ } else {
+ // MHenze (cylab) Fix Issue 35:
+ // Compute the delta and absolute coordinates and recenter the mouse if necessary
+ int dx = arg0.getX() - lastKnownLocation.x;
+ int dy = arg0.getY() - lastKnownLocation.y;
+ location.x += dx;
+ location.y += dy;
+ if (!visible) {
+ recenterMouse(arg0.getComponent());
+ }
+ lastKnownLocation.x = arg0.getX();
+ lastKnownLocation.y = arg0.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 Component component) {
+ if (robot != null) {
+ eventsSinceRecenter = 0;
+ isRecentering = true;
+ centerLocation.setLocation(component.getWidth()/2, component.getHeight()/2);
+ centerLocationOnScreen.setLocation(centerLocation);
+ SwingUtilities.convertPointToScreen(centerLocationOnScreen, component);
+ robot.mouseMove(centerLocationOnScreen.x, centerLocationOnScreen.y);
+ }
+ }
+
+ private int getJMEButtonIndex( MouseEvent arg0 ) {
+ int index;
+ switch (arg0.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;
+ }
+ return index;
+ }
+}