2004-11-25 17:20:45 -05:00
|
|
|
/*
|
2008-04-07 14:36:09 -04:00
|
|
|
* Copyright (c) 2002-2008 LWJGL Project
|
2003-08-17 12:32:53 -04:00
|
|
|
* All rights reserved.
|
2004-11-25 17:20:45 -05:00
|
|
|
*
|
2003-08-17 12:32:53 -04:00
|
|
|
* Redistribution and use in source and binary forms, with or without
|
2004-11-25 17:20:45 -05:00
|
|
|
* modification, are permitted provided that the following conditions are
|
2003-08-17 12:32:53 -04:00
|
|
|
* met:
|
2004-11-25 17:20:45 -05:00
|
|
|
*
|
|
|
|
* * Redistributions of source code must retain the above copyright
|
2003-08-17 12:32:53 -04:00
|
|
|
* 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.
|
|
|
|
*
|
2004-11-25 17:20:45 -05:00
|
|
|
* * Neither the name of 'LWJGL' nor the names of
|
|
|
|
* its contributors may be used to endorse or promote products derived
|
2003-08-17 12:32:53 -04:00
|
|
|
* from this software without specific prior written permission.
|
2004-11-25 17:20:45 -05:00
|
|
|
*
|
2003-08-17 12:32:53 -04:00
|
|
|
* 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
|
2004-11-25 17:20:45 -05:00
|
|
|
* 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
|
2003-08-17 12:32:53 -04:00
|
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
2004-11-25 17:20:45 -05:00
|
|
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
2003-08-17 12:32:53 -04:00
|
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
package org.lwjgl.input;
|
|
|
|
|
|
|
|
import java.lang.reflect.Field;
|
|
|
|
import java.lang.reflect.Modifier;
|
|
|
|
import java.nio.ByteBuffer;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.Map;
|
|
|
|
|
2004-03-26 16:11:20 -05:00
|
|
|
import org.lwjgl.BufferUtils;
|
2005-05-04 16:59:44 -04:00
|
|
|
import org.lwjgl.LWJGLException;
|
2004-03-26 16:57:57 -05:00
|
|
|
import org.lwjgl.Sys;
|
2004-07-02 15:02:00 -04:00
|
|
|
import org.lwjgl.opengl.Display;
|
2006-10-26 16:19:40 -04:00
|
|
|
import org.lwjgl.opengl.InputImplementation;
|
2003-08-17 12:32:53 -04:00
|
|
|
|
|
|
|
/**
|
2004-02-12 02:10:06 -05:00
|
|
|
* <br>
|
2003-08-17 12:32:53 -04:00
|
|
|
* A raw Keyboard interface. This can be used to poll the current state of the
|
|
|
|
* keys, or read all the keyboard presses / releases since the last read.
|
2004-11-25 17:20:45 -05:00
|
|
|
*
|
2003-08-17 12:32:53 -04:00
|
|
|
* @author cix_foo <cix_foo@users.sourceforge.net>
|
2004-02-12 02:10:06 -05:00
|
|
|
* @author elias_naur <elias_naur@users.sourceforge.net>
|
|
|
|
* @author Brian Matzon <brian@matzon.dk>
|
2003-08-17 12:32:53 -04:00
|
|
|
* @version $Revision$
|
2006-03-23 14:32:21 -05:00
|
|
|
* $Id$
|
2003-08-17 12:32:53 -04:00
|
|
|
*/
|
|
|
|
public class Keyboard {
|
2006-07-03 19:16:26 -04:00
|
|
|
/** Internal use - event size in bytes */
|
2007-05-13 18:01:48 -04:00
|
|
|
public static final int EVENT_SIZE = 4 + 1 + 4 + 8 + 1;
|
2006-07-03 19:16:26 -04:00
|
|
|
|
2004-11-25 17:20:45 -05:00
|
|
|
/**
|
2003-08-17 12:32:53 -04:00
|
|
|
* The special character meaning that no
|
|
|
|
* character was translated for the event.
|
|
|
|
*/
|
2006-06-26 10:13:57 -04:00
|
|
|
public static final int CHAR_NONE = '\0';
|
2003-08-17 12:32:53 -04:00
|
|
|
|
2004-11-25 17:20:45 -05:00
|
|
|
/**
|
|
|
|
* The special keycode meaning that only the
|
2003-08-17 12:32:53 -04:00
|
|
|
* translated character is valid.
|
|
|
|
*/
|
|
|
|
public static final int KEY_NONE = 0x00;
|
|
|
|
|
|
|
|
public static final int KEY_ESCAPE = 0x01;
|
|
|
|
public static final int KEY_1 = 0x02;
|
|
|
|
public static final int KEY_2 = 0x03;
|
|
|
|
public static final int KEY_3 = 0x04;
|
|
|
|
public static final int KEY_4 = 0x05;
|
|
|
|
public static final int KEY_5 = 0x06;
|
|
|
|
public static final int KEY_6 = 0x07;
|
|
|
|
public static final int KEY_7 = 0x08;
|
|
|
|
public static final int KEY_8 = 0x09;
|
|
|
|
public static final int KEY_9 = 0x0A;
|
|
|
|
public static final int KEY_0 = 0x0B;
|
|
|
|
public static final int KEY_MINUS = 0x0C; /* - on main keyboard */
|
|
|
|
public static final int KEY_EQUALS = 0x0D;
|
|
|
|
public static final int KEY_BACK = 0x0E; /* backspace */
|
|
|
|
public static final int KEY_TAB = 0x0F;
|
|
|
|
public static final int KEY_Q = 0x10;
|
|
|
|
public static final int KEY_W = 0x11;
|
|
|
|
public static final int KEY_E = 0x12;
|
|
|
|
public static final int KEY_R = 0x13;
|
|
|
|
public static final int KEY_T = 0x14;
|
|
|
|
public static final int KEY_Y = 0x15;
|
|
|
|
public static final int KEY_U = 0x16;
|
|
|
|
public static final int KEY_I = 0x17;
|
|
|
|
public static final int KEY_O = 0x18;
|
|
|
|
public static final int KEY_P = 0x19;
|
|
|
|
public static final int KEY_LBRACKET = 0x1A;
|
|
|
|
public static final int KEY_RBRACKET = 0x1B;
|
|
|
|
public static final int KEY_RETURN = 0x1C; /* Enter on main keyboard */
|
|
|
|
public static final int KEY_LCONTROL = 0x1D;
|
|
|
|
public static final int KEY_A = 0x1E;
|
|
|
|
public static final int KEY_S = 0x1F;
|
|
|
|
public static final int KEY_D = 0x20;
|
|
|
|
public static final int KEY_F = 0x21;
|
|
|
|
public static final int KEY_G = 0x22;
|
|
|
|
public static final int KEY_H = 0x23;
|
|
|
|
public static final int KEY_J = 0x24;
|
|
|
|
public static final int KEY_K = 0x25;
|
|
|
|
public static final int KEY_L = 0x26;
|
|
|
|
public static final int KEY_SEMICOLON = 0x27;
|
|
|
|
public static final int KEY_APOSTROPHE = 0x28;
|
|
|
|
public static final int KEY_GRAVE = 0x29; /* accent grave */
|
|
|
|
public static final int KEY_LSHIFT = 0x2A;
|
|
|
|
public static final int KEY_BACKSLASH = 0x2B;
|
|
|
|
public static final int KEY_Z = 0x2C;
|
|
|
|
public static final int KEY_X = 0x2D;
|
|
|
|
public static final int KEY_C = 0x2E;
|
|
|
|
public static final int KEY_V = 0x2F;
|
|
|
|
public static final int KEY_B = 0x30;
|
|
|
|
public static final int KEY_N = 0x31;
|
|
|
|
public static final int KEY_M = 0x32;
|
|
|
|
public static final int KEY_COMMA = 0x33;
|
|
|
|
public static final int KEY_PERIOD = 0x34; /* . on main keyboard */
|
|
|
|
public static final int KEY_SLASH = 0x35; /* / on main keyboard */
|
|
|
|
public static final int KEY_RSHIFT = 0x36;
|
|
|
|
public static final int KEY_MULTIPLY = 0x37; /* * on numeric keypad */
|
|
|
|
public static final int KEY_LMENU = 0x38; /* left Alt */
|
|
|
|
public static final int KEY_SPACE = 0x39;
|
|
|
|
public static final int KEY_CAPITAL = 0x3A;
|
|
|
|
public static final int KEY_F1 = 0x3B;
|
|
|
|
public static final int KEY_F2 = 0x3C;
|
|
|
|
public static final int KEY_F3 = 0x3D;
|
|
|
|
public static final int KEY_F4 = 0x3E;
|
|
|
|
public static final int KEY_F5 = 0x3F;
|
|
|
|
public static final int KEY_F6 = 0x40;
|
|
|
|
public static final int KEY_F7 = 0x41;
|
|
|
|
public static final int KEY_F8 = 0x42;
|
|
|
|
public static final int KEY_F9 = 0x43;
|
|
|
|
public static final int KEY_F10 = 0x44;
|
|
|
|
public static final int KEY_NUMLOCK = 0x45;
|
|
|
|
public static final int KEY_SCROLL = 0x46; /* Scroll Lock */
|
|
|
|
public static final int KEY_NUMPAD7 = 0x47;
|
|
|
|
public static final int KEY_NUMPAD8 = 0x48;
|
|
|
|
public static final int KEY_NUMPAD9 = 0x49;
|
|
|
|
public static final int KEY_SUBTRACT = 0x4A; /* - on numeric keypad */
|
|
|
|
public static final int KEY_NUMPAD4 = 0x4B;
|
|
|
|
public static final int KEY_NUMPAD5 = 0x4C;
|
|
|
|
public static final int KEY_NUMPAD6 = 0x4D;
|
|
|
|
public static final int KEY_ADD = 0x4E; /* + on numeric keypad */
|
|
|
|
public static final int KEY_NUMPAD1 = 0x4F;
|
|
|
|
public static final int KEY_NUMPAD2 = 0x50;
|
|
|
|
public static final int KEY_NUMPAD3 = 0x51;
|
|
|
|
public static final int KEY_NUMPAD0 = 0x52;
|
|
|
|
public static final int KEY_DECIMAL = 0x53; /* . on numeric keypad */
|
|
|
|
public static final int KEY_F11 = 0x57;
|
|
|
|
public static final int KEY_F12 = 0x58;
|
|
|
|
public static final int KEY_F13 = 0x64; /* (NEC PC98) */
|
|
|
|
public static final int KEY_F14 = 0x65; /* (NEC PC98) */
|
|
|
|
public static final int KEY_F15 = 0x66; /* (NEC PC98) */
|
2012-11-27 09:14:58 -05:00
|
|
|
public static final int KEY_F16 = 0x67; /* Extended Function keys - (Mac) */
|
|
|
|
public static final int KEY_F17 = 0x68;
|
|
|
|
public static final int KEY_F18 = 0x69;
|
2003-08-17 12:32:53 -04:00
|
|
|
public static final int KEY_KANA = 0x70; /* (Japanese keyboard) */
|
2012-11-27 09:14:58 -05:00
|
|
|
public static final int KEY_F19 = 0x71; /* Extended Function keys - (Mac) */
|
2003-08-17 12:32:53 -04:00
|
|
|
public static final int KEY_CONVERT = 0x79; /* (Japanese keyboard) */
|
|
|
|
public static final int KEY_NOCONVERT = 0x7B; /* (Japanese keyboard) */
|
|
|
|
public static final int KEY_YEN = 0x7D; /* (Japanese keyboard) */
|
|
|
|
public static final int KEY_NUMPADEQUALS = 0x8D; /* = on numeric keypad (NEC PC98) */
|
|
|
|
public static final int KEY_CIRCUMFLEX = 0x90; /* (Japanese keyboard) */
|
|
|
|
public static final int KEY_AT = 0x91; /* (NEC PC98) */
|
|
|
|
public static final int KEY_COLON = 0x92; /* (NEC PC98) */
|
|
|
|
public static final int KEY_UNDERLINE = 0x93; /* (NEC PC98) */
|
|
|
|
public static final int KEY_KANJI = 0x94; /* (Japanese keyboard) */
|
|
|
|
public static final int KEY_STOP = 0x95; /* (NEC PC98) */
|
|
|
|
public static final int KEY_AX = 0x96; /* (Japan AX) */
|
|
|
|
public static final int KEY_UNLABELED = 0x97; /* (J3100) */
|
|
|
|
public static final int KEY_NUMPADENTER = 0x9C; /* Enter on numeric keypad */
|
|
|
|
public static final int KEY_RCONTROL = 0x9D;
|
2012-11-27 09:14:58 -05:00
|
|
|
public static final int KEY_SECTION = 0xA7; /* Section symbol (Mac) */
|
2003-08-17 12:32:53 -04:00
|
|
|
public static final int KEY_NUMPADCOMMA = 0xB3; /* , on numeric keypad (NEC PC98) */
|
|
|
|
public static final int KEY_DIVIDE = 0xB5; /* / on numeric keypad */
|
|
|
|
public static final int KEY_SYSRQ = 0xB7;
|
|
|
|
public static final int KEY_RMENU = 0xB8; /* right Alt */
|
2012-11-29 12:27:08 -05:00
|
|
|
public static final int KEY_FUNCTION = 0xC4; /* Function (Mac) */
|
2003-08-17 12:32:53 -04:00
|
|
|
public static final int KEY_PAUSE = 0xC5; /* Pause */
|
|
|
|
public static final int KEY_HOME = 0xC7; /* Home on arrow keypad */
|
|
|
|
public static final int KEY_UP = 0xC8; /* UpArrow on arrow keypad */
|
|
|
|
public static final int KEY_PRIOR = 0xC9; /* PgUp on arrow keypad */
|
|
|
|
public static final int KEY_LEFT = 0xCB; /* LeftArrow on arrow keypad */
|
|
|
|
public static final int KEY_RIGHT = 0xCD; /* RightArrow on arrow keypad */
|
|
|
|
public static final int KEY_END = 0xCF; /* End on arrow keypad */
|
|
|
|
public static final int KEY_DOWN = 0xD0; /* DownArrow on arrow keypad */
|
|
|
|
public static final int KEY_NEXT = 0xD1; /* PgDn on arrow keypad */
|
|
|
|
public static final int KEY_INSERT = 0xD2; /* Insert on arrow keypad */
|
|
|
|
public static final int KEY_DELETE = 0xD3; /* Delete on arrow keypad */
|
2012-11-27 09:14:58 -05:00
|
|
|
public static final int KEY_CLEAR = 0xDA; /* Clear key (Mac) */
|
2012-11-29 12:27:08 -05:00
|
|
|
public static final int KEY_LMETA = 0xDB; /* Left Windows/Option key */
|
2007-08-28 04:02:24 -04:00
|
|
|
/**
|
|
|
|
* The left windows key, mapped to KEY_LMETA
|
|
|
|
*
|
2008-01-21 17:15:12 -05:00
|
|
|
* @deprecated Use KEY_LMETA instead
|
2007-08-28 04:02:24 -04:00
|
|
|
*/
|
|
|
|
public static final int KEY_LWIN = KEY_LMETA; /* Left Windows key */
|
|
|
|
public static final int KEY_RMETA = 0xDC; /* Right Windows/Option key */
|
|
|
|
/**
|
|
|
|
* The right windows key, mapped to KEY_RMETA
|
|
|
|
*
|
2008-01-21 17:15:12 -05:00
|
|
|
* @deprecated Use KEY_RMETA instead
|
2007-08-28 04:02:24 -04:00
|
|
|
*/
|
|
|
|
public static final int KEY_RWIN = KEY_RMETA; /* Right Windows key */
|
2003-08-17 12:32:53 -04:00
|
|
|
public static final int KEY_APPS = 0xDD; /* AppMenu key */
|
|
|
|
public static final int KEY_POWER = 0xDE;
|
|
|
|
public static final int KEY_SLEEP = 0xDF;
|
2004-03-26 16:11:20 -05:00
|
|
|
|
2006-06-10 16:42:26 -04:00
|
|
|
/* public static final int STATE_ON = 0;
|
2004-03-26 16:11:20 -05:00
|
|
|
public static final int STATE_OFF = 1;
|
|
|
|
public static final int STATE_UNKNOWN = 2;
|
2006-06-10 16:42:26 -04:00
|
|
|
*/
|
2004-11-25 17:20:45 -05:00
|
|
|
public static final int KEYBOARD_SIZE = 256;
|
2004-11-11 11:03:19 -05:00
|
|
|
|
2004-03-26 16:11:20 -05:00
|
|
|
/** Buffer size in events */
|
2004-11-25 17:20:45 -05:00
|
|
|
private static final int BUFFER_SIZE = 50;
|
2004-03-26 16:11:20 -05:00
|
|
|
|
2003-08-17 12:32:53 -04:00
|
|
|
/** Key names */
|
2012-09-10 03:51:13 -04:00
|
|
|
private static final String[] keyName = new String[KEYBOARD_SIZE];
|
2010-09-28 17:11:35 -04:00
|
|
|
private static final Map<String, Integer> keyMap = new HashMap<String, Integer>(253);
|
2004-11-25 17:20:45 -05:00
|
|
|
private static int counter;
|
|
|
|
|
2003-08-17 12:32:53 -04:00
|
|
|
static {
|
|
|
|
// Use reflection to find out key names
|
2010-09-28 17:11:35 -04:00
|
|
|
Field[] fields = Keyboard.class.getFields();
|
2003-08-17 12:32:53 -04:00
|
|
|
try {
|
2010-09-28 17:11:35 -04:00
|
|
|
for ( Field field : fields ) {
|
|
|
|
if ( Modifier.isStatic(field.getModifiers())
|
|
|
|
&& Modifier.isPublic(field.getModifiers())
|
|
|
|
&& Modifier.isFinal(field.getModifiers())
|
|
|
|
&& field.getType().equals(int.class)
|
2012-11-27 10:15:43 -05:00
|
|
|
&& field.getName().startsWith("KEY_")
|
|
|
|
&& !field.getName().endsWith("WIN") ) { /* Don't use deprecated names */
|
2010-09-28 17:11:35 -04:00
|
|
|
|
|
|
|
int key = field.getInt(null);
|
|
|
|
String name = field.getName().substring(4);
|
2003-08-17 12:32:53 -04:00
|
|
|
keyName[key] = name;
|
2010-09-28 17:11:35 -04:00
|
|
|
keyMap.put(name, key);
|
|
|
|
counter++;
|
2003-08-17 12:32:53 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
} catch (Exception e) {
|
|
|
|
}
|
2004-11-25 17:20:45 -05:00
|
|
|
|
2003-08-17 12:32:53 -04:00
|
|
|
}
|
2004-11-25 17:20:45 -05:00
|
|
|
|
2003-08-17 12:32:53 -04:00
|
|
|
/** The number of keys supported */
|
2004-02-04 15:44:07 -05:00
|
|
|
private static final int keyCount = counter;
|
2003-08-17 12:32:53 -04:00
|
|
|
|
|
|
|
/** Has the keyboard been created? */
|
|
|
|
private static boolean created;
|
2004-11-25 17:20:45 -05:00
|
|
|
|
2007-05-13 18:01:48 -04:00
|
|
|
/** Are repeat events enabled? */
|
|
|
|
private static boolean repeat_enabled;
|
|
|
|
|
2003-08-17 12:32:53 -04:00
|
|
|
/** The keys status from the last poll */
|
2004-11-11 11:03:19 -05:00
|
|
|
private static final ByteBuffer keyDownBuffer = BufferUtils.createByteBuffer(KEYBOARD_SIZE);
|
2004-11-25 17:20:45 -05:00
|
|
|
|
2003-08-17 12:32:53 -04:00
|
|
|
/**
|
|
|
|
* The key events from the last read: a sequence of pairs of key number,
|
2005-01-10 03:19:28 -05:00
|
|
|
* followed by state. The state is followed by
|
2006-06-30 19:05:28 -04:00
|
|
|
* a 4 byte code point representing the translated character.
|
2003-08-17 12:32:53 -04:00
|
|
|
*/
|
2006-07-03 19:16:26 -04:00
|
|
|
private static ByteBuffer readBuffer;
|
2003-08-17 12:32:53 -04:00
|
|
|
|
2007-05-13 18:01:48 -04:00
|
|
|
/** current event */
|
|
|
|
private static KeyEvent current_event = new KeyEvent();
|
2004-11-25 17:20:45 -05:00
|
|
|
|
2007-05-13 18:01:48 -04:00
|
|
|
/** scratch event */
|
|
|
|
private static KeyEvent tmp_event = new KeyEvent();
|
2004-11-25 17:20:45 -05:00
|
|
|
|
2003-09-10 18:39:26 -04:00
|
|
|
/** One time initialization */
|
|
|
|
private static boolean initialized;
|
2004-11-25 17:20:45 -05:00
|
|
|
|
2006-10-26 16:19:40 -04:00
|
|
|
private static InputImplementation implementation;
|
2006-10-08 05:05:16 -04:00
|
|
|
|
2003-08-17 12:32:53 -04:00
|
|
|
/**
|
|
|
|
* Keyboard cannot be constructed.
|
|
|
|
*/
|
|
|
|
private Keyboard() {
|
|
|
|
}
|
2004-11-25 17:20:45 -05:00
|
|
|
|
2003-08-17 12:32:53 -04:00
|
|
|
/**
|
|
|
|
* Static initialization
|
|
|
|
*/
|
|
|
|
private static void initialize() {
|
2004-03-27 08:48:58 -05:00
|
|
|
if (initialized)
|
|
|
|
return;
|
|
|
|
Sys.initialize();
|
2003-09-10 18:39:26 -04:00
|
|
|
initialized = true;
|
2003-08-17 12:32:53 -04:00
|
|
|
}
|
2004-11-25 17:20:45 -05:00
|
|
|
|
2003-08-17 12:32:53 -04:00
|
|
|
/**
|
2006-10-26 16:19:40 -04:00
|
|
|
* "Create" the keyboard with the given implementation. This is used
|
|
|
|
* reflectively from AWTInputAdapter.
|
2004-11-25 17:20:45 -05:00
|
|
|
*
|
2004-03-27 10:05:24 -05:00
|
|
|
* @throws LWJGLException if the keyboard could not be created for any reason
|
2003-08-17 12:32:53 -04:00
|
|
|
*/
|
2006-10-26 16:19:40 -04:00
|
|
|
private static void create(InputImplementation impl) throws LWJGLException {
|
|
|
|
if (created)
|
2006-11-16 07:29:52 -05:00
|
|
|
return;
|
2003-09-10 18:39:26 -04:00
|
|
|
if (!initialized)
|
|
|
|
initialize();
|
2006-10-26 16:19:40 -04:00
|
|
|
implementation = impl;
|
2006-10-08 05:05:16 -04:00
|
|
|
implementation.createKeyboard();
|
2003-08-17 12:32:53 -04:00
|
|
|
created = true;
|
2006-07-03 19:16:26 -04:00
|
|
|
readBuffer = ByteBuffer.allocate(EVENT_SIZE*BUFFER_SIZE);
|
2005-05-05 06:16:46 -04:00
|
|
|
reset();
|
|
|
|
}
|
|
|
|
|
2006-10-26 16:19:40 -04:00
|
|
|
/**
|
|
|
|
* "Create" the keyboard. The display must first have been created. The
|
|
|
|
* reason for this is so the keyboard has a window to "focus" in.
|
|
|
|
*
|
|
|
|
* @throws LWJGLException if the keyboard could not be created for any reason
|
|
|
|
*/
|
2007-05-30 16:33:40 -04:00
|
|
|
public static void create() throws LWJGLException {
|
2007-02-12 07:18:26 -05:00
|
|
|
synchronized (OpenGLPackageAccess.global_lock) {
|
|
|
|
if (!Display.isCreated()) throw new IllegalStateException("Display must be created.");
|
2006-10-27 02:27:58 -04:00
|
|
|
|
2007-02-12 07:18:26 -05:00
|
|
|
create(OpenGLPackageAccess.createImplementation());
|
|
|
|
}
|
2006-10-26 16:19:40 -04:00
|
|
|
}
|
|
|
|
|
2005-05-05 06:16:46 -04:00
|
|
|
private static void reset() {
|
2005-01-18 11:42:31 -05:00
|
|
|
readBuffer.limit(0);
|
2005-05-05 06:16:46 -04:00
|
|
|
for (int i = 0; i < keyDownBuffer.remaining(); i++)
|
|
|
|
keyDownBuffer.put(i, (byte)0);
|
2007-05-13 18:01:48 -04:00
|
|
|
current_event.reset();
|
2003-08-17 12:32:53 -04:00
|
|
|
}
|
2004-11-25 17:20:45 -05:00
|
|
|
|
2003-08-17 12:32:53 -04:00
|
|
|
/**
|
|
|
|
* @return true if the keyboard has been created
|
|
|
|
*/
|
2007-05-30 16:33:40 -04:00
|
|
|
public static boolean isCreated() {
|
2007-02-12 07:18:26 -05:00
|
|
|
synchronized (OpenGLPackageAccess.global_lock) {
|
|
|
|
return created;
|
|
|
|
}
|
2003-08-17 12:32:53 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* "Destroy" the keyboard
|
|
|
|
*/
|
2007-05-30 16:33:40 -04:00
|
|
|
public static void destroy() {
|
2007-02-12 07:18:26 -05:00
|
|
|
synchronized (OpenGLPackageAccess.global_lock) {
|
|
|
|
if (!created)
|
|
|
|
return;
|
|
|
|
created = false;
|
|
|
|
implementation.destroyKeyboard();
|
|
|
|
reset();
|
|
|
|
}
|
2003-08-17 12:32:53 -04:00
|
|
|
}
|
2004-11-25 17:20:45 -05:00
|
|
|
|
2003-08-17 12:32:53 -04:00
|
|
|
/**
|
2004-03-26 16:11:20 -05:00
|
|
|
* Polls the keyboard for its current state. Access the polled values using the
|
|
|
|
* <code>isKeyDown</code> method.
|
|
|
|
* By using this method, it is possible to "miss" keyboard keys if you don't
|
2010-09-28 17:11:35 -04:00
|
|
|
* poll fast enough.
|
2004-11-25 17:20:45 -05:00
|
|
|
*
|
2005-01-10 03:19:28 -05:00
|
|
|
* To use buffered values, you have to call <code>next</code> for each event you
|
2004-11-25 17:20:45 -05:00
|
|
|
* want to read. You can query which key caused the event by using
|
2004-03-26 16:11:20 -05:00
|
|
|
* <code>getEventKey</code>. To get the state of that key, for that event, use
|
|
|
|
* <code>getEventKeyState</code> - finally use <code>getEventCharacter</code> to get the
|
|
|
|
* character for that event.
|
2004-04-07 03:55:42 -04:00
|
|
|
*
|
2008-03-02 13:16:39 -05:00
|
|
|
* NOTE: This method does not query the operating system for new events. To do that,
|
|
|
|
* Display.processMessages() (or Display.update()) must be called first.
|
|
|
|
*
|
2004-11-25 17:20:45 -05:00
|
|
|
* @see org.lwjgl.input.Keyboard#isKeyDown(int key)
|
2004-03-26 16:11:20 -05:00
|
|
|
* @see org.lwjgl.input.Keyboard#next()
|
|
|
|
* @see org.lwjgl.input.Keyboard#getEventKey()
|
|
|
|
* @see org.lwjgl.input.Keyboard#getEventKeyState()
|
|
|
|
* @see org.lwjgl.input.Keyboard#getEventCharacter()
|
2003-08-17 12:32:53 -04:00
|
|
|
*/
|
2007-05-30 16:33:40 -04:00
|
|
|
public static void poll() {
|
2007-02-12 07:18:26 -05:00
|
|
|
synchronized (OpenGLPackageAccess.global_lock) {
|
|
|
|
if (!created)
|
|
|
|
throw new IllegalStateException("Keyboard must be created before you can poll the device");
|
|
|
|
implementation.pollKeyboard(keyDownBuffer);
|
|
|
|
read();
|
|
|
|
}
|
2004-04-07 03:55:42 -04:00
|
|
|
}
|
2004-11-25 17:20:45 -05:00
|
|
|
|
2004-04-07 03:55:42 -04:00
|
|
|
private static void read() {
|
2004-03-26 16:11:20 -05:00
|
|
|
readBuffer.compact();
|
2006-10-08 05:05:16 -04:00
|
|
|
implementation.readKeyboard(readBuffer);
|
2004-03-26 16:11:20 -05:00
|
|
|
readBuffer.flip();
|
2003-08-17 12:32:53 -04:00
|
|
|
}
|
2004-11-25 17:20:45 -05:00
|
|
|
|
2003-08-17 12:32:53 -04:00
|
|
|
/**
|
|
|
|
* Checks to see if a key is down.
|
|
|
|
* @param key Keycode to check
|
|
|
|
* @return true if the key is down according to the last poll()
|
|
|
|
*/
|
2007-05-30 16:33:40 -04:00
|
|
|
public static boolean isKeyDown(int key) {
|
2007-02-12 07:18:26 -05:00
|
|
|
synchronized (OpenGLPackageAccess.global_lock) {
|
|
|
|
if (!created)
|
|
|
|
throw new IllegalStateException("Keyboard must be created before you can query key state");
|
|
|
|
return keyDownBuffer.get(key) != 0;
|
|
|
|
}
|
2003-08-17 12:32:53 -04:00
|
|
|
}
|
2004-11-25 17:20:45 -05:00
|
|
|
|
2004-03-26 16:11:20 -05:00
|
|
|
/**
|
|
|
|
* Checks whether one of the state keys are "active"
|
2004-11-25 17:20:45 -05:00
|
|
|
*
|
2004-03-26 16:11:20 -05:00
|
|
|
* @param key State key to test (KEY_CAPITAL | KEY_NUMLOCK | KEY_SYSRQ)
|
|
|
|
* @return STATE_ON if on, STATE_OFF if off and STATE_UNKNOWN if the state is unknown
|
|
|
|
*/
|
2006-06-10 16:42:26 -04:00
|
|
|
/* public static int isStateKeySet(int key) {
|
2004-03-27 06:55:07 -05:00
|
|
|
if (!created)
|
|
|
|
throw new IllegalStateException("Keyboard must be created before you can query key state");
|
2006-10-08 05:05:16 -04:00
|
|
|
return implementation.isStateKeySet(key);
|
2004-03-26 16:11:20 -05:00
|
|
|
}
|
2006-06-10 16:42:26 -04:00
|
|
|
*/
|
2003-08-17 12:32:53 -04:00
|
|
|
/**
|
|
|
|
* Gets a key's name
|
|
|
|
* @param key The key
|
|
|
|
* @return a String with the key's human readable name in it or null if the key is unnamed
|
|
|
|
*/
|
2006-11-24 05:18:36 -05:00
|
|
|
public static synchronized String getKeyName(int key) {
|
2003-08-17 12:32:53 -04:00
|
|
|
return keyName[key];
|
|
|
|
}
|
2004-11-25 17:20:45 -05:00
|
|
|
|
2003-08-17 12:32:53 -04:00
|
|
|
/**
|
|
|
|
* Get's a key's index. If the key is unrecognised then KEY_NONE is returned.
|
|
|
|
* @param keyName The key name
|
|
|
|
*/
|
2006-11-24 05:18:36 -05:00
|
|
|
public static synchronized int getKeyIndex(String keyName) {
|
2010-09-28 17:11:35 -04:00
|
|
|
Integer ret = keyMap.get(keyName);
|
2003-08-17 12:32:53 -04:00
|
|
|
if (ret == null)
|
|
|
|
return KEY_NONE;
|
|
|
|
else
|
2010-09-28 17:11:35 -04:00
|
|
|
return ret;
|
2003-08-17 12:32:53 -04:00
|
|
|
}
|
2004-11-25 17:20:45 -05:00
|
|
|
|
2003-08-17 12:32:53 -04:00
|
|
|
/**
|
2004-07-17 05:38:20 -04:00
|
|
|
* Gets the number of keyboard events waiting after doing a buffer enabled poll().
|
2003-08-17 12:32:53 -04:00
|
|
|
* @return the number of keyboard events
|
|
|
|
*/
|
2007-05-30 16:33:40 -04:00
|
|
|
public static int getNumKeyboardEvents() {
|
2007-02-12 07:18:26 -05:00
|
|
|
synchronized (OpenGLPackageAccess.global_lock) {
|
|
|
|
if (!created)
|
|
|
|
throw new IllegalStateException("Keyboard must be created before you can read events");
|
2007-05-13 18:01:48 -04:00
|
|
|
int old_position = readBuffer.position();
|
|
|
|
int num_events = 0;
|
|
|
|
while (readNext(tmp_event) && (!tmp_event.repeat || repeat_enabled))
|
|
|
|
num_events++;
|
|
|
|
readBuffer.position(old_position);
|
|
|
|
return num_events;
|
2007-02-12 07:18:26 -05:00
|
|
|
}
|
2003-08-17 12:32:53 -04:00
|
|
|
}
|
2004-11-25 17:20:45 -05:00
|
|
|
|
2003-08-17 12:32:53 -04:00
|
|
|
/**
|
2004-11-25 17:20:45 -05:00
|
|
|
* Gets the next keyboard event. You can query which key caused the event by using
|
2004-03-26 16:11:20 -05:00
|
|
|
* <code>getEventKey</code>. To get the state of that key, for that event, use
|
|
|
|
* <code>getEventKeyState</code> - finally use <code>getEventCharacter</code> to get the
|
|
|
|
* character for that event.
|
2004-11-25 17:20:45 -05:00
|
|
|
*
|
2004-03-26 16:11:20 -05:00
|
|
|
* @see org.lwjgl.input.Keyboard#getEventKey()
|
|
|
|
* @see org.lwjgl.input.Keyboard#getEventKeyState()
|
|
|
|
* @see org.lwjgl.input.Keyboard#getEventCharacter()
|
|
|
|
* @return true if a keyboard event was read, false otherwise
|
2003-08-17 12:32:53 -04:00
|
|
|
*/
|
2007-05-30 16:33:40 -04:00
|
|
|
public static boolean next() {
|
2007-02-12 07:18:26 -05:00
|
|
|
synchronized (OpenGLPackageAccess.global_lock) {
|
|
|
|
if (!created)
|
|
|
|
throw new IllegalStateException("Keyboard must be created before you can read events");
|
|
|
|
|
2007-05-13 18:01:48 -04:00
|
|
|
boolean result;
|
|
|
|
while ((result = readNext(current_event)) && current_event.repeat && !repeat_enabled)
|
|
|
|
;
|
|
|
|
return result;
|
2004-03-26 16:11:20 -05:00
|
|
|
}
|
2003-08-17 12:32:53 -04:00
|
|
|
}
|
2004-02-04 15:44:07 -05:00
|
|
|
|
2007-05-13 18:01:48 -04:00
|
|
|
/**
|
|
|
|
* Controls whether repeat events are reported or not. If repeat events
|
|
|
|
* are enabled, key down events are reported when a key is pressed and held for
|
|
|
|
* a OS dependent amount of time. To distinguish a repeat event from a normal event,
|
|
|
|
* use isRepeatEvent().
|
|
|
|
*
|
|
|
|
* @see org.lwjgl.input.Keyboard#getEventKey()
|
|
|
|
*/
|
2007-05-30 16:33:40 -04:00
|
|
|
public static void enableRepeatEvents(boolean enable) {
|
|
|
|
synchronized (OpenGLPackageAccess.global_lock) {
|
|
|
|
repeat_enabled = enable;
|
|
|
|
}
|
2007-05-13 18:01:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check whether repeat events are currently reported or not.
|
|
|
|
*
|
|
|
|
* @return true is repeat events are reported, false if not.
|
|
|
|
* @see org.lwjgl.input.Keyboard#getEventKey()
|
|
|
|
*/
|
2007-05-30 16:33:40 -04:00
|
|
|
public static boolean areRepeatEventsEnabled() {
|
|
|
|
synchronized (OpenGLPackageAccess.global_lock) {
|
|
|
|
return repeat_enabled;
|
|
|
|
}
|
2007-05-13 18:01:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
private static boolean readNext(KeyEvent event) {
|
|
|
|
if (readBuffer.hasRemaining()) {
|
|
|
|
event.key = readBuffer.getInt() & 0xFF;
|
|
|
|
event.state = readBuffer.get() != 0;
|
|
|
|
event.character = readBuffer.getInt();
|
|
|
|
event.nanos = readBuffer.getLong();
|
|
|
|
event.repeat = readBuffer.get() == 1;
|
|
|
|
return true;
|
|
|
|
} else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2004-02-04 15:44:07 -05:00
|
|
|
/**
|
|
|
|
* @return Number of keys on this keyboard
|
|
|
|
*/
|
2007-05-30 16:33:40 -04:00
|
|
|
public static int getKeyCount() {
|
|
|
|
return keyCount;
|
2004-03-26 16:11:20 -05:00
|
|
|
}
|
2004-02-04 15:44:07 -05:00
|
|
|
|
2004-03-26 16:11:20 -05:00
|
|
|
/**
|
|
|
|
* @return The character from the current event
|
|
|
|
*/
|
2007-05-30 16:33:40 -04:00
|
|
|
public static char getEventCharacter() {
|
2007-02-12 07:18:26 -05:00
|
|
|
synchronized (OpenGLPackageAccess.global_lock) {
|
2007-05-13 18:01:48 -04:00
|
|
|
return (char)current_event.character;
|
2007-02-12 07:18:26 -05:00
|
|
|
}
|
2004-03-26 16:11:20 -05:00
|
|
|
}
|
2004-02-04 15:44:07 -05:00
|
|
|
|
2004-03-26 16:11:20 -05:00
|
|
|
/**
|
2005-02-07 13:45:25 -05:00
|
|
|
* Please note that the key code returned is NOT valid against the
|
|
|
|
* current keyboard layout. To get the actual character pressed call
|
|
|
|
* getEventCharacter
|
2010-09-28 17:11:35 -04:00
|
|
|
*
|
2004-03-26 16:11:20 -05:00
|
|
|
* @return The key from the current event
|
|
|
|
*/
|
2007-05-30 16:33:40 -04:00
|
|
|
public static int getEventKey() {
|
2007-02-12 07:18:26 -05:00
|
|
|
synchronized (OpenGLPackageAccess.global_lock) {
|
2007-05-13 18:01:48 -04:00
|
|
|
return current_event.key;
|
2007-02-12 07:18:26 -05:00
|
|
|
}
|
2004-03-26 16:11:20 -05:00
|
|
|
}
|
2004-02-04 15:44:07 -05:00
|
|
|
|
2004-03-26 16:11:20 -05:00
|
|
|
/**
|
2010-12-15 13:48:56 -05:00
|
|
|
* Gets the state of the key that generated the
|
2004-03-26 16:11:20 -05:00
|
|
|
* current event
|
2004-11-25 17:20:45 -05:00
|
|
|
*
|
2004-03-26 16:11:20 -05:00
|
|
|
* @return True if key was down, or false if released
|
|
|
|
*/
|
2007-05-30 16:33:40 -04:00
|
|
|
public static boolean getEventKeyState() {
|
2007-02-12 07:18:26 -05:00
|
|
|
synchronized (OpenGLPackageAccess.global_lock) {
|
2007-05-13 18:01:48 -04:00
|
|
|
return current_event.state;
|
2007-02-12 07:18:26 -05:00
|
|
|
}
|
2004-03-26 16:11:20 -05:00
|
|
|
}
|
2006-07-04 13:07:13 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the time in nanoseconds of the current event.
|
|
|
|
* Only useful for relative comparisons with other
|
|
|
|
* Keyboard events, as the absolute time has no defined
|
|
|
|
* origin.
|
|
|
|
* @return The time in nanoseconds of the current event
|
|
|
|
*/
|
2007-05-30 16:33:40 -04:00
|
|
|
public static long getEventNanoseconds() {
|
2007-02-12 07:18:26 -05:00
|
|
|
synchronized (OpenGLPackageAccess.global_lock) {
|
2007-05-13 18:01:48 -04:00
|
|
|
return current_event.nanos;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2008-01-21 17:15:12 -05:00
|
|
|
* @see org.lwjgl.input.Keyboard#enableRepeatEvents(boolean)
|
2007-05-13 18:01:48 -04:00
|
|
|
* @return true if the current event is a repeat event, false if
|
|
|
|
* the current event is not a repeat even or if repeat events are disabled.
|
|
|
|
*/
|
2007-05-30 16:33:40 -04:00
|
|
|
public static boolean isRepeatEvent() {
|
2007-05-13 18:01:48 -04:00
|
|
|
synchronized (OpenGLPackageAccess.global_lock) {
|
|
|
|
return current_event.repeat;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-28 17:11:35 -04:00
|
|
|
private static final class KeyEvent {
|
2007-05-13 18:01:48 -04:00
|
|
|
/** The current keyboard character being examined */
|
|
|
|
private int character;
|
|
|
|
|
|
|
|
/** The current keyboard event key being examined */
|
|
|
|
private int key;
|
|
|
|
|
|
|
|
/** The current state of the key being examined in the event queue */
|
|
|
|
private boolean state;
|
|
|
|
|
|
|
|
/** The current event time */
|
|
|
|
private long nanos;
|
|
|
|
|
|
|
|
/** Is the current event a repeated event? */
|
|
|
|
private boolean repeat;
|
|
|
|
|
|
|
|
private void reset() {
|
|
|
|
character = 0;
|
|
|
|
key = 0;
|
|
|
|
state = false;
|
|
|
|
repeat = false;
|
2007-02-12 07:18:26 -05:00
|
|
|
}
|
2006-07-04 13:07:13 -04:00
|
|
|
}
|
2004-03-26 16:11:20 -05:00
|
|
|
}
|