mirror of
https://github.com/shadowfacts/lwjgl2-arm64.git
synced 2026-03-01 11:04:41 +01:00
Implemented Keyboard.enableRepeatEvents(), Keyboard.areRepeatEventsEnabled() and Keyboard.isEventRepeat() to control repeat event reporting. Added repeat key test to KeyboardTest
This commit is contained in:
parent
eef220a10f
commit
fc759e6192
|
|
@ -57,7 +57,7 @@ import org.lwjgl.opengl.InputImplementation;
|
|||
*/
|
||||
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 @@ public class Keyboard {
|
|||
/** 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,17 +252,11 @@ public class Keyboard {
|
|||
*/
|
||||
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;
|
||||
|
||||
/** The current state of the key being examined in the event queue */
|
||||
private static boolean eventState;
|
||||
|
||||
/** The current event time */
|
||||
private static long eventNanos;
|
||||
/** scratch event */
|
||||
private static KeyEvent tmp_event = new KeyEvent();
|
||||
|
||||
/** One time initialization */
|
||||
private static boolean initialized;
|
||||
|
|
@ -318,9 +315,7 @@ public class Keyboard {
|
|||
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 @@ public class Keyboard {
|
|||
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,18 +452,47 @@ public class Keyboard {
|
|||
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
|
||||
*/
|
||||
|
|
@ -478,7 +507,7 @@ public class Keyboard {
|
|||
*/
|
||||
public static synchronized char getEventCharacter() {
|
||||
synchronized (OpenGLPackageAccess.global_lock) {
|
||||
return (char)eventCharacter;
|
||||
return (char)current_event.character;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -491,7 +520,7 @@ public class Keyboard {
|
|||
*/
|
||||
public static synchronized int getEventKey() {
|
||||
synchronized (OpenGLPackageAccess.global_lock) {
|
||||
return eventKey;
|
||||
return current_event.key;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -503,7 +532,7 @@ public class Keyboard {
|
|||
*/
|
||||
public static synchronized boolean getEventKeyState() {
|
||||
synchronized (OpenGLPackageAccess.global_lock) {
|
||||
return eventState;
|
||||
return current_event.state;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -516,7 +545,42 @@ public class Keyboard {
|
|||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -264,9 +264,9 @@ final class KeyboardEventQueue extends EventQueue implements KeyListener {
|
|||
//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 @@ final class KeyboardEventQueue extends EventQueue implements KeyListener {
|
|||
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 @@ final class KeyboardEventQueue extends EventQueue implements KeyListener {
|
|||
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ final class LinuxKeyboard {
|
|||
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 @@ final class LinuxKeyboard {
|
|||
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 @@ final class LinuxKeyboard {
|
|||
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 @@ final class LinuxKeyboard {
|
|||
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 @@ final class LinuxKeyboard {
|
|||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -608,12 +608,11 @@ final class WindowsDisplay implements DisplayImplementation {
|
|||
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) {
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ final class WindowsKeyboard {
|
|||
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 @@ final class WindowsKeyboard {
|
|||
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 @@ final class WindowsKeyboard {
|
|||
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 @@ final class WindowsKeyboard {
|
|||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -152,7 +152,11 @@ public class KeyboardTest {
|
|||
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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue