From: <eli...@us...> - 2007-05-13 22:01:50
|
Revision: 2818 http://svn.sourceforge.net/java-game-lib/?rev=2818&view=rev Author: elias_naur Date: 2007-05-13 15:01:48 -0700 (Sun, 13 May 2007) Log Message: ----------- Implemented Keyboard.enableRepeatEvents(), Keyboard.areRepeatEventsEnabled() and Keyboard.isEventRepeat() to control repeat event reporting. Added repeat key test to KeyboardTest Modified Paths: -------------- trunk/LWJGL/src/java/org/lwjgl/input/Keyboard.java trunk/LWJGL/src/java/org/lwjgl/opengl/KeyboardEventQueue.java trunk/LWJGL/src/java/org/lwjgl/opengl/LinuxKeyboard.java trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsDisplay.java trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsKeyboard.java trunk/LWJGL/src/java/org/lwjgl/test/input/KeyboardTest.java Modified: trunk/LWJGL/src/java/org/lwjgl/input/Keyboard.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/input/Keyboard.java 2007-05-13 21:11:53 UTC (rev 2817) +++ trunk/LWJGL/src/java/org/lwjgl/input/Keyboard.java 2007-05-13 22:01:48 UTC (rev 2818) @@ -57,7 +57,7 @@ */ public class Keyboard { /** Internal use - event size in bytes */ - public static final int EVENT_SIZE = 4 + 1 + 4 + 8; + public static final int EVENT_SIZE = 4 + 1 + 4 + 8 + 1; /** * The special character meaning that no @@ -239,6 +239,9 @@ /** Has the keyboard been created? */ private static boolean created; + /** Are repeat events enabled? */ + private static boolean repeat_enabled; + /** The keys status from the last poll */ private static final ByteBuffer keyDownBuffer = BufferUtils.createByteBuffer(KEYBOARD_SIZE); @@ -249,18 +252,12 @@ */ private static ByteBuffer readBuffer; - /** The current keyboard character being examined */ - private static int eventCharacter; + /** current event */ + private static KeyEvent current_event = new KeyEvent(); - /** The current keyboard event key being examined */ - private static int eventKey; + /** scratch event */ + private static KeyEvent tmp_event = new KeyEvent(); - /** The current state of the key being examined in the event queue */ - private static boolean eventState; - - /** The current event time */ - private static long eventNanos; - /** One time initialization */ private static boolean initialized; @@ -318,9 +315,7 @@ readBuffer.limit(0); for (int i = 0; i < keyDownBuffer.remaining(); i++) keyDownBuffer.put(i, (byte)0); - eventCharacter = 0; - eventKey = 0; - eventState = false; + current_event.reset(); } /** @@ -432,7 +427,12 @@ synchronized (OpenGLPackageAccess.global_lock) { if (!created) throw new IllegalStateException("Keyboard must be created before you can read events"); - return readBuffer.remaining()/EVENT_SIZE; + 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; } } @@ -452,19 +452,48 @@ if (!created) throw new IllegalStateException("Keyboard must be created before you can read events"); - if (readBuffer.hasRemaining()) { - eventKey = readBuffer.getInt() & 0xFF; - eventState = readBuffer.get() != 0; - eventCharacter = readBuffer.getInt(); - eventNanos = readBuffer.getLong(); - return true; - } else { - return false; - } + boolean result; + while ((result = readNext(current_event)) && current_event.repeat && !repeat_enabled) + ; + return result; } } /** + * 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() + */ + public static synchronized void enableRepeatEvents(boolean enable) { + repeat_enabled = enable; + } + + /** + * 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() + */ + public static synchronized boolean areRepeatEventsEnabled() { + return repeat_enabled; + } + + 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; + } + + /** * @return Number of keys on this keyboard */ public static synchronized int getKeyCount() { @@ -478,7 +507,7 @@ */ public static synchronized char getEventCharacter() { synchronized (OpenGLPackageAccess.global_lock) { - return (char)eventCharacter; + return (char)current_event.character; } } @@ -491,7 +520,7 @@ */ public static synchronized int getEventKey() { synchronized (OpenGLPackageAccess.global_lock) { - return eventKey; + return current_event.key; } } @@ -503,7 +532,7 @@ */ public static synchronized boolean getEventKeyState() { synchronized (OpenGLPackageAccess.global_lock) { - return eventState; + return current_event.state; } } @@ -516,7 +545,42 @@ */ public static synchronized long getEventNanoseconds() { synchronized (OpenGLPackageAccess.global_lock) { - return eventNanos; + return current_event.nanos; } } + + /** + * @see org.lwjgl.input.Keyboard#enableRepeatEvents() + * @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. + */ + public static synchronized boolean isRepeatEvent() { + synchronized (OpenGLPackageAccess.global_lock) { + return current_event.repeat; + } + } + + private final static class KeyEvent { + /** 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; + } + } } Modified: trunk/LWJGL/src/java/org/lwjgl/opengl/KeyboardEventQueue.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/opengl/KeyboardEventQueue.java 2007-05-13 21:11:53 UTC (rev 2817) +++ trunk/LWJGL/src/java/org/lwjgl/opengl/KeyboardEventQueue.java 2007-05-13 22:01:48 UTC (rev 2818) @@ -264,9 +264,9 @@ //component.removeKeyListener(this); } - private void putKeyboardEvent(int key_code, byte state, int character, long nanos) { + private void putKeyboardEvent(int key_code, byte state, int character, long nanos, boolean repeat) { event.clear(); - event.putInt(key_code).put(state).putInt(character).putLong(nanos); + event.putInt(key_code).put(state).putInt(character).putLong(nanos).put(repeat ? (byte)1 : (byte)0); event.flip(); putEvent(event); } @@ -287,15 +287,16 @@ if (character == KeyEvent.CHAR_UNDEFINED) character = Keyboard.CHAR_NONE; if (state == 1) { + boolean repeat = false; if (has_deferred_event) { if ((nanos == deferred_nanos && deferred_key_code == key_code && deferred_key_location == key_location)) { has_deferred_event = false; - return; // Ignore repeated key down, key up event pair - } - flushDeferredEvent(); + repeat = true; // Repeat event + } else + flushDeferredEvent(); } - putKeyEvent(key_code, key_location, state, character, nanos); + putKeyEvent(key_code, key_location, state, character, nanos, repeat); } else { flushDeferredEvent(); has_deferred_event = true; @@ -309,19 +310,19 @@ private void flushDeferredEvent() { if (has_deferred_event) { - putKeyEvent(deferred_key_code, deferred_key_location, deferred_key_state, deferred_character, deferred_nanos); + putKeyEvent(deferred_key_code, deferred_key_location, deferred_key_state, deferred_character, deferred_nanos, false); has_deferred_event = false; } } - private void putKeyEvent(int key_code, int key_location, byte state, int character, long nanos) { + private void putKeyEvent(int key_code, int key_location, byte state, int character, long nanos, boolean repeat) { int key_code_mapped = getMappedKeyCode(key_code, key_location); /* Ignore repeating presses */ if ( key_states[key_code_mapped] == state ) - return; + repeat = true; key_states[key_code_mapped] = state; int key_int_char = character & 0xffff; - putKeyboardEvent(key_code_mapped, state, key_int_char, nanos); + putKeyboardEvent(key_code_mapped, state, key_int_char, nanos, repeat); } private int getMappedKeyCode(int key_code, int position) { Modified: trunk/LWJGL/src/java/org/lwjgl/opengl/LinuxKeyboard.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/opengl/LinuxKeyboard.java 2007-05-13 21:11:53 UTC (rev 2817) +++ trunk/LWJGL/src/java/org/lwjgl/opengl/LinuxKeyboard.java 2007-05-13 22:01:48 UTC (rev 2818) @@ -75,7 +75,7 @@ private final CharBuffer char_buffer = CharBuffer.allocate(KEYBOARD_BUFFER_SIZE); // Deferred key released event, to detect key repeat - private boolean has_deferred_event = true; + private boolean has_deferred_event; private int deferred_keycode; private int deferred_event_keycode; private long deferred_nanos; @@ -169,9 +169,9 @@ keyDownBuffer.position(old_position); } - private void putKeyboardEvent(int keycode, byte state, int ch, long nanos) { + private void putKeyboardEvent(int keycode, byte state, int ch, long nanos, boolean repeat) { tmp_event.clear(); - tmp_event.putInt(keycode).put(state).putInt(ch).putLong(nanos); + tmp_event.putInt(keycode).put(state).putInt(ch).putLong(nanos).put(repeat ? (byte)1 : (byte)0); tmp_event.flip(); event_queue.putEvent(tmp_event); } @@ -211,20 +211,20 @@ return lookupStringISO88591(event_ptr, translation_buffer); } - private void translateEvent(long event_ptr, int keycode, byte key_state, long nanos) { + private void translateEvent(long event_ptr, int keycode, byte key_state, long nanos, boolean repeat) { int num_chars, i; int ch; num_chars = lookupString(event_ptr, temp_translation_buffer); if (num_chars > 0) { ch = temp_translation_buffer[0]; - putKeyboardEvent(keycode, key_state, ch, nanos); + putKeyboardEvent(keycode, key_state, ch, nanos, repeat); for (i = 1; i < num_chars; i++) { ch = temp_translation_buffer[i]; - putKeyboardEvent(0, (byte)0, ch, nanos); + putKeyboardEvent(0, (byte)0, ch, nanos, repeat); } } else { - putKeyboardEvent(keycode, key_state, 0, nanos); + putKeyboardEvent(keycode, key_state, 0, nanos, repeat); } } @@ -305,14 +305,15 @@ key_down_buffer[keycode] = key_state; long nanos = millis*1000000; if (event_type == LinuxEvent.KeyPress) { + boolean repeat = false; if (has_deferred_event) { if (nanos == deferred_nanos && event_keycode == deferred_event_keycode) { has_deferred_event = false; - return; // Repeated event, ignore it - } - flushDeferredEvent(); + repeat = true; // Repeated event + } else + flushDeferredEvent(); } - translateEvent(event_ptr, keycode, key_state, nanos); + translateEvent(event_ptr, keycode, key_state, nanos, repeat); } else { flushDeferredEvent(); has_deferred_event = true; @@ -325,7 +326,7 @@ private void flushDeferredEvent() { if (has_deferred_event) { - putKeyboardEvent(deferred_keycode, deferred_key_state, 0, deferred_nanos); + putKeyboardEvent(deferred_keycode, deferred_key_state, 0, deferred_nanos, false); has_deferred_event = false; } } Modified: trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsDisplay.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsDisplay.java 2007-05-13 21:11:53 UTC (rev 2817) +++ trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsDisplay.java 2007-05-13 22:01:48 UTC (rev 2818) @@ -608,12 +608,11 @@ private void handleKeyButton(long wParam, long lParam, long millis) { byte previous_state = (byte)((lParam >>> 30) & 0x1); byte state = (byte)(1 - ((lParam >>> 31) & 0x1)); - if (state == previous_state) - return; // Auto-repeat message + boolean repeat = state == previous_state; // Repeat message byte extended = (byte)((lParam >>> 24) & 0x1); int scan_code = (int)((lParam >>> 16) & 0xFF); if (keyboard != null) - keyboard.handleKey((int)wParam, scan_code, extended != 0, state, millis); + keyboard.handleKey((int)wParam, scan_code, extended != 0, state, millis, repeat); } private static int transformY(long hwnd, int y) { Modified: trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsKeyboard.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsKeyboard.java 2007-05-13 21:11:53 UTC (rev 2817) +++ trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsKeyboard.java 2007-05-13 22:01:48 UTC (rev 2818) @@ -63,6 +63,7 @@ private byte retained_state; private int retained_char; private long retained_millis; + private boolean retained_repeat; public WindowsKeyboard(long hwnd) throws LWJGLException { this.hwnd = hwnd; @@ -97,9 +98,9 @@ private static native int GetKeyboardState(ByteBuffer lpKeyState); private static native int GetKeyState(int virt_key); - private void putEvent(int keycode, byte state, int ch, long millis) { + private void putEvent(int keycode, byte state, int ch, long millis, boolean repeat) { tmp_event.clear(); - tmp_event.putInt(keycode).put(state).putInt(ch).putLong(millis*1000000); + tmp_event.putInt(keycode).put(state).putInt(ch).putLong(millis*1000000).put(repeat ? (byte)1 : (byte)0); tmp_event.flip(); event_queue.putEvent(tmp_event); } @@ -144,11 +145,11 @@ private void flushRetained() { if (has_retained_event) { has_retained_event = false; - putEvent(retained_key_code, retained_state, retained_char, retained_millis); + putEvent(retained_key_code, retained_state, retained_char, retained_millis, retained_repeat); } } - public void handleKey(int virt_key, int scan_code, boolean extended, byte event_state, long millis) { + public void handleKey(int virt_key, int scan_code, boolean extended, byte event_state, long millis, boolean repeat) { virt_key = translateExtended(virt_key, scan_code, event_state, extended); flushRetained(); has_retained_event = true; @@ -159,12 +160,13 @@ retained_state = event_state; retained_millis = millis; retained_char = 0; + retained_repeat = repeat; // translate(virt_key, event_state, millis*1000000); } public void handleChar(int event_char, long millis) { if (!has_retained_event) { - putEvent(0, (byte)0, event_char, millis); + putEvent(0, (byte)0, event_char, millis, false); } else retained_char = event_char; } Modified: trunk/LWJGL/src/java/org/lwjgl/test/input/KeyboardTest.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/test/input/KeyboardTest.java 2007-05-13 21:11:53 UTC (rev 2817) +++ trunk/LWJGL/src/java/org/lwjgl/test/input/KeyboardTest.java 2007-05-13 22:01:48 UTC (rev 2818) @@ -152,7 +152,11 @@ System.out.println("Pressed:" + Keyboard.getEventKeyState()); System.out.println("Key character code: " + character_code); System.out.println("Key character: " + Keyboard.getEventCharacter()); + System.out.println("Repeat event: " + Keyboard.isRepeatEvent()); + if (Keyboard.getEventKey() == Keyboard.KEY_R && Keyboard.getEventKeyState()) { + Keyboard.enableRepeatEvents(!Keyboard.areRepeatEventsEnabled()); + } if (Keyboard.getEventKey() == Keyboard.KEY_ESCAPE) { return; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |