Skip to content

Commit

Permalink
Revert "Rewrite Keyboard to behave like lwjgl3 (#42)"
Browse files Browse the repository at this point in the history
This reverts commit 34175a0.
  • Loading branch information
eigenraven committed Mar 15, 2023
1 parent 34175a0 commit 0713491
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 45 deletions.
16 changes: 16 additions & 0 deletions src/main/java/me/eigenraven/lwjgl3ify/core/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ public class Config {
public static boolean DEBUG_PRINT_KEY_EVENTS = false;
public static boolean DEBUG_PRINT_MOUSE_EVENTS = false;

public static boolean MBE_ENABLED = true;
public static boolean IME_ENABLED = false;
public static boolean IME_F12_TOGGLE = false;
public static boolean IME_SYS_TOGGLE = false;

public static boolean SHOW_JAVA_VERSION = true;
public static boolean SHOW_LWJGL_VERSION = true;

Expand Down Expand Up @@ -132,6 +137,17 @@ public static void reloadConfigObject() {
DEBUG_PRINT_MOUSE_EVENTS,
"Print mouse-related events to the log");

MBE_ENABLED = config
.getBoolean("handleMultibyteInput", CATEGORY_CORE, MBE_ENABLED, "Enables multibyte character input.");
IME_ENABLED = config.getBoolean("enabled", CATEGORY_IME, IME_ENABLED, "Enables IME support for CJK input.");
IME_F12_TOGGLE = config
.getBoolean("f12Toggle", CATEGORY_IME, IME_F12_TOGGLE, "Enables switching IME mode by pressing F12.");
IME_SYS_TOGGLE = config.getBoolean(
"sysToggle",
CATEGORY_IME,
IME_SYS_TOGGLE,
"Enables switching IME mode by pressing Ctrl/LWin + Shift/Space");

SHOW_JAVA_VERSION = config
.getBoolean("showJavaVersion", CATEGORY_CORE, SHOW_JAVA_VERSION, "Show java version in the debug hud");
SHOW_LWJGL_VERSION = config.getBoolean(
Expand Down
123 changes: 82 additions & 41 deletions src/main/java/org/lwjglx/input/Keyboard.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

import me.eigenraven.lwjgl3ify.core.Config;

import org.apache.commons.lang3.StringUtils;
import org.lwjgl.glfw.GLFW;
Expand Down Expand Up @@ -160,7 +163,10 @@ public class Keyboard {

public static final int keyCount;

public enum KeyState {
private static EventQueue queue = new EventQueue(128);
private static BlockingQueue<Character> imeCharQueue = new ArrayBlockingQueue<>(128);

private enum KeyState {

PRESS(true),
RELEASE(false),
Expand All @@ -175,8 +181,19 @@ public enum KeyState {

private static boolean doRepeatEvents = true;

private static int[] keyEvents = new int[queue.getMaxEvents()];
private static char[] keySpecificChars = new char[queue.getMaxEvents()];
private static KeyState[] keyEventStates = new KeyState[queue.getMaxEvents()];

static {
Arrays.fill(keyEventStates, KeyState.RELEASE);
}

private static long[] nanoTimeEvents = new long[queue.getMaxEvents()];
private static char[] keyEventChars = new char[Short.MAX_VALUE];

public static final int KEYBOARD_SIZE = Short.MAX_VALUE;
public static Queue<KeyEvent> eventQueue = new ArrayBlockingQueue<>(256);

private static final String[] keyName = new String[Short.MAX_VALUE];
private static final Map<String, Integer> keyMap = new HashMap<>(Short.MAX_VALUE);

Expand Down Expand Up @@ -206,10 +223,13 @@ public enum KeyState {
}
keyMap.put(keyName[i], i);
}
eventQueue.add(new KeyEvent(0, '\0', KeyState.RELEASE, Sys.getNanoTime()));
for (int key = 32; key < 128; key++) {
keyEventChars[KeyCodes.glfwToLwjgl(key)] = (char) key;
}
keyEventChars[KEY_NONE] = '\0';
}

public static void addGlfwKeyEvent(long window, int key, int scancode, int action, int mods, char c) {
public static void addGlfwKeyEvent(long window, int key, int scancode, int action, int mods) {
final KeyState state;
switch (action) {
case GLFW.GLFW_PRESS -> state = KeyState.PRESS;
Expand All @@ -222,21 +242,52 @@ public static void addGlfwKeyEvent(long window, int key, int scancode, int actio
}
default -> state = KeyState.RELEASE;
}
try {
eventQueue.add(new KeyEvent(KeyCodes.glfwToLwjgl(key), c, state, Sys.getNanoTime()));
} catch (IllegalStateException ignored) {}
final int nextPos = queue.getNextPos();
keyEvents[nextPos] = KeyCodes.glfwToLwjgl(key);
keyEventStates[nextPos] = state;
nanoTimeEvents[nextPos] = Sys.getNanoTime();
keySpecificChars[nextPos] = '\0';

queue.add();
}

public static void addKeyEvent(int key, boolean pressed) {
try {
eventQueue.add(new KeyEvent(key, '\0', pressed ? KeyState.PRESS : KeyState.RELEASE, Sys.getNanoTime()));
} catch (IllegalStateException ignored) {}
final int nextPos = queue.getNextPos();
keyEvents[nextPos] = KeyCodes.glfwToLwjgl(key);
keyEventStates[nextPos] = pressed ? KeyState.PRESS : KeyState.RELEASE;
nanoTimeEvents[nextPos] = Sys.getNanoTime();
keySpecificChars[nextPos] = '\0';

queue.add();
}

private static void duplicateKeyEvent() {
final int nextPos = queue.getNextPos();
final int prevPos = queue.getLastWrittenPos();
keyEvents[nextPos] = keyEvents[prevPos];
keyEventStates[nextPos] = keyEventStates[prevPos];
nanoTimeEvents[nextPos] = nanoTimeEvents[prevPos];
keySpecificChars[nextPos] = keySpecificChars[prevPos];
queue.add();
}

public static void addCharEvent(int key, char c) {
try {
eventQueue.add(new KeyEvent(KEY_NONE, c, KeyState.PRESS, Sys.getNanoTime()));
} catch (IllegalStateException ignored) {}
final int nextPos = queue.getNextPos();
final int prevPos = queue.getLastWrittenPos();
int index = KeyCodes.glfwToLwjgl(key);
keyEventChars[index] = c;
if (Config.MBE_ENABLED) {
if (keySpecificChars[prevPos] == '\0') {
keySpecificChars[prevPos] = c;
} else {
duplicateKeyEvent();
keySpecificChars[nextPos] = c;
}
}
}

public static void addIMECharEvent(char c) {
imeCharQueue.offer(c);
}

public static void create() throws LWJGLException {}
Expand All @@ -262,36 +313,41 @@ public static int getKeyCount() {
}

public static int getNumKeyboardEvents() {
return eventQueue.size();
return queue.getEventCount();
}

public static boolean isRepeatEvent() {
return eventQueue.peek().state == KeyState.REPEAT;
return keyEventStates[queue.getCurrentPos()] == KeyState.REPEAT;
}

public static boolean next() {
boolean next = eventQueue.size() > 1;
if (next) {
eventQueue.remove();
}
return next;
return queue.next();
}

public static int getEventKey() {
return eventQueue.peek().key;
return keyEvents[queue.getCurrentPos()];
}

public static char getEventCharacter() {
return eventQueue.peek().aChar;

if (!imeCharQueue.isEmpty() && Display.imeOn) {
return imeCharQueue.remove();
}
final int eventKey = getEventKey();
final char eventSpecificChar = keySpecificChars[queue.getCurrentPos()];
// On some systems it seems esc and backspace can generate broken chars sometimes, make sure they always work
return switch (eventKey) {
case KEY_ESCAPE -> '\0';
case KEY_BACK -> '\b';
default -> (eventSpecificChar != '\0') ? eventSpecificChar : keyEventChars[eventKey];
};
}

public static boolean getEventKeyState() {
return eventQueue.peek().state == KeyState.PRESS;
return keyEventStates[queue.getCurrentPos()].isPressed || (!imeCharQueue.isEmpty() && Display.imeOn);
}

public static long getEventNanoseconds() {
return eventQueue.peek().nano;
return nanoTimeEvents[queue.getCurrentPos()];
}

public static String getKeyName(int key) {
Expand All @@ -317,19 +373,4 @@ public static boolean isCreated() {
}

public static void destroy() {}

public static class KeyEvent {

public int key;
public char aChar;
public KeyState state;
public long nano;

public KeyEvent(int key, char aChar, KeyState state, long nano) {
this.key = key;
this.aChar = aChar;
this.state = state;
this.nano = nano;
}
}
}
38 changes: 34 additions & 4 deletions src/main/java/org/lwjglx/opengl/Display.java
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,33 @@ public void invoke(long window, int key, int scancode, int action, int mods) {
KeyEvent.getKeyText(KeyCodes.lwjglToAwt(KeyCodes.glfwToLwjgl(key))),
(key >= 32 && key < 127) ? ((char) key) : '?');
}
if ((mods & GLFW_MOD_CONTROL) != 0 && key >= GLFW_KEY_A && key <= GLFW_KEY_Z) {
Keyboard.addGlfwKeyEvent(window, key, scancode, action, mods, (char) (key & 0x1F));
latestEventKey = key;
if (Config.IME_ENABLED) {
if (Config.IME_F12_TOGGLE && key == GLFW_KEY_F12 && action == 0) {
imeOn = !imeOn;
}
if (Config.IME_SYS_TOGGLE
&& (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL)
|| Keyboard.isKeyDown(Keyboard.KEY_LWIN))) {
if (key == GLFW_KEY_SPACE || key == GLFW_KEY_LEFT_SHIFT || key == GLFW_KEY_RIGHT_SHIFT) {
imeOn = !imeOn;
return;
}
}
if (imeOn) {
if (key > 256) {
Keyboard.addGlfwKeyEvent(window, key, scancode, action, mods);
}
} else {
Keyboard.addGlfwKeyEvent(window, key, scancode, action, mods);
}
} else {
Keyboard.addGlfwKeyEvent(window, key, scancode, action, mods, '\0');
Keyboard.addGlfwKeyEvent(window, key, scancode, action, mods);
}
// Ctrl should generate ASCII modifier keys (0x01-0x1F), glfw does not give use char events for this
if ((mods & GLFW_MOD_CONTROL) != 0 && key >= GLFW_KEY_A && key <= GLFW_KEY_Z) {
int codepoint = key & 0x1F;
Keyboard.addCharEvent(key, (char) codepoint);
}
}
};
Expand All @@ -183,7 +206,14 @@ public void invoke(long window, int codepoint) {
codepoint,
(char) codepoint);
}
Keyboard.addCharEvent(0, (char) codepoint);
if (imeOn) {
Keyboard.addKeyEvent(GLFW_KEY_UNKNOWN, true);
Keyboard.addIMECharEvent((char) codepoint);
Keyboard.addKeyEvent(GLFW_KEY_UNKNOWN, false);

} else {
Keyboard.addCharEvent(latestEventKey, (char) codepoint);
}
}
};

Expand Down

0 comments on commit 0713491

Please sign in to comment.