Linux: use XkbSetDetectableAutoRepeat to detect repeated key events more reliably

This commit is contained in:
Elias Naur 2008-01-07 18:29:04 +00:00
parent b5aef81f7e
commit 8f677f1585
3 changed files with 23 additions and 4 deletions

View File

@ -857,7 +857,7 @@ final class LinuxDisplay implements DisplayImplementation {
public void destroyKeyboard() { public void destroyKeyboard() {
lockAWT(); lockAWT();
try { try {
keyboard.destroy(); keyboard.destroy(getDisplay());
keyboard = null; keyboard = null;
} finally { } finally {
unlockAWT(); unlockAWT();

View File

@ -41,6 +41,7 @@ import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetDecoder;
import org.lwjgl.BufferUtils; import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLUtil;
import org.lwjgl.input.Keyboard; import org.lwjgl.input.Keyboard;
final class LinuxKeyboard { final class LinuxKeyboard {
@ -122,13 +123,14 @@ final class LinuxKeyboard {
modeswitch_mask = tmp_modeswitch_mask; modeswitch_mask = tmp_modeswitch_mask;
caps_lock_mask = tmp_caps_lock_mask; caps_lock_mask = tmp_caps_lock_mask;
shift_lock_mask = tmp_shift_lock_mask; shift_lock_mask = tmp_shift_lock_mask;
setDetectableKeyRepeat(display, true);
xim = openIM(display); xim = openIM(display);
if (xim != 0) { if (xim != 0) {
xic = createIC(xim, window); xic = createIC(xim, window);
if (xic != 0) { if (xic != 0) {
setupIMEventMask(display, window, xic); setupIMEventMask(display, window, xic);
} else { } else {
destroy(); destroy(display);
} }
} else { } else {
xic = 0; xic = 0;
@ -146,11 +148,19 @@ final class LinuxKeyboard {
private static native void setupIMEventMask(long display, long window, long xic); private static native void setupIMEventMask(long display, long window, long xic);
private static native ByteBuffer allocateComposeStatus(); private static native ByteBuffer allocateComposeStatus();
public void destroy() { private static void setDetectableKeyRepeat(long display, boolean enabled) {
boolean success = nSetDetectableKeyRepeat(display, enabled);
if (!success)
LWJGLUtil.log("Failed to set detectable key repeat");
}
private static native boolean nSetDetectableKeyRepeat(long display, boolean enabled);
public void destroy(long display) {
if (xic != 0) if (xic != 0)
destroyIC(xic); destroyIC(xic);
if (xim != 0) if (xim != 0)
closeIM(xim); closeIM(xim);
setDetectableKeyRepeat(display, false);
} }
private static native void destroyIC(long xic); private static native void destroyIC(long xic);
private static native void closeIM(long xim); private static native void closeIM(long xim);
@ -300,10 +310,10 @@ final class LinuxKeyboard {
private void handleKeyEvent(long event_ptr, long millis, int event_type, int event_keycode, int event_state) { private void handleKeyEvent(long event_ptr, long millis, int event_type, int event_keycode, int event_state) {
int keycode = getKeycode(event_ptr, event_state); int keycode = getKeycode(event_ptr, event_state);
byte key_state = getKeyState(event_type); byte key_state = getKeyState(event_type);
boolean repeat = key_state == key_down_buffer[keycode];
key_down_buffer[keycode] = key_state; key_down_buffer[keycode] = key_state;
long nanos = millis*1000000; long nanos = millis*1000000;
if (event_type == LinuxEvent.KeyPress) { if (event_type == LinuxEvent.KeyPress) {
boolean repeat = false;
if (has_deferred_event) { if (has_deferred_event) {
if (nanos == deferred_nanos && event_keycode == deferred_event_keycode) { if (nanos == deferred_nanos && event_keycode == deferred_event_keycode) {
has_deferred_event = false; has_deferred_event = false;

View File

@ -41,6 +41,7 @@
#include <X11/X.h> #include <X11/X.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/XKBlib.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include <X11/keysym.h> #include <X11/keysym.h>
#include "common_tools.h" #include "common_tools.h"
@ -52,6 +53,14 @@ JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_getModifierMapping(J
return (intptr_t)modifier_map; return (intptr_t)modifier_map;
} }
JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_nSetDetectableKeyRepeat(JNIEnv *env, jclass unused, jlong display_ptr, jboolean set_enabled) {
Display *disp = (Display *)(intptr_t)display_ptr;
Bool result;
Bool enabled = set_enabled == JNI_TRUE ? True : False;
Bool success = XkbSetDetectableAutoRepeat(disp, enabled, &result);
return success && enabled == result ? JNI_TRUE : JNI_FALSE;
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_freeModifierMapping(JNIEnv *env, jclass unused, jlong mapping_ptr) { JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxKeyboard_freeModifierMapping(JNIEnv *env, jclass unused, jlong mapping_ptr) {
XModifierKeymap *modifier_map = (XModifierKeymap *)(intptr_t)mapping_ptr; XModifierKeymap *modifier_map = (XModifierKeymap *)(intptr_t)mapping_ptr;
XFreeModifiermap(modifier_map); XFreeModifiermap(modifier_map);