Windows: Make sure AWTInputAdapter is not reporting events twice after a grab change
This commit is contained in:
parent
5d6ae4138a
commit
d75d00666a
|
@ -59,10 +59,14 @@ abstract class AbstractAWTInput implements AWTCanvasInputImplementation {
|
|||
this.robot = AWTUtil.createRobot(canvas);
|
||||
}
|
||||
|
||||
protected synchronized MouseEventQueue getMouseEventQueue() {
|
||||
protected MouseEventQueue getMouseEventQueue() {
|
||||
return mouse_queue;
|
||||
}
|
||||
|
||||
protected KeyboardEventQueue getKeyboardEventQueue() {
|
||||
return keyboard_queue;
|
||||
}
|
||||
|
||||
public synchronized void grabMouse(boolean grab) {
|
||||
this.grab = grab;
|
||||
if (mouse_queue != null)
|
||||
|
|
|
@ -115,9 +115,15 @@ final class WindowsAWTInput extends AbstractAWTInput {
|
|||
private void grab(boolean grab) {
|
||||
if (has_grabbed != grab) {
|
||||
cached_mouse.grab(grab);
|
||||
cached_keyboard.grab(grab);
|
||||
has_grabbed = grab;
|
||||
if (!grab)
|
||||
cached_mouse.flush();
|
||||
cached_keyboard.flush();
|
||||
getMouseEventQueue().clearEvents();
|
||||
getKeyboardEventQueue().clearEvents();
|
||||
if (!grab) {
|
||||
getCanvas().setCursor(cached_cursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ import org.lwjgl.BufferUtils;
|
|||
final class WindowsKeyboard {
|
||||
private final static int BUFFER_SIZE = 50;
|
||||
|
||||
private final long hwnd;
|
||||
private final WindowsDirectInput dinput;
|
||||
private final WindowsDirectInputDevice keyboard;
|
||||
private final IntBuffer temp_data_buffer;
|
||||
|
@ -55,14 +56,17 @@ final class WindowsKeyboard {
|
|||
private final CharBuffer unicode_buffer;
|
||||
private final ByteBuffer ascii_buffer;
|
||||
|
||||
private boolean grabbed;
|
||||
|
||||
public WindowsKeyboard(WindowsDirectInput dinput, long hwnd) throws LWJGLException {
|
||||
this.hwnd = hwnd;
|
||||
this.dinput = dinput;
|
||||
try {
|
||||
keyboard = dinput.createDevice(WindowsDirectInput.KEYBOARD_TYPE);
|
||||
try {
|
||||
keyboard.setCooperateLevel(hwnd, WindowsDirectInputDevice.DISCL_NONEXCLUSIVE | WindowsDirectInputDevice.DISCL_FOREGROUND);
|
||||
keyboard.setDataFormat(WindowsDirectInput.KEYBOARD_TYPE);
|
||||
keyboard.setBufferSize(BUFFER_SIZE);
|
||||
acquireNonExclusive();
|
||||
} catch (LWJGLException e) {
|
||||
keyboard.release();
|
||||
throw e;
|
||||
|
@ -84,15 +88,48 @@ final class WindowsKeyboard {
|
|||
ascii_buffer = BufferUtils.createByteBuffer(2);
|
||||
}
|
||||
}
|
||||
|
||||
private static native boolean isWindowsNT();
|
||||
|
||||
private boolean acquire(int flags) {
|
||||
try {
|
||||
keyboard.setCooperateLevel(hwnd, flags);
|
||||
keyboard.acquire();
|
||||
return true;
|
||||
} catch (LWJGLException e) {
|
||||
LWJGLUtil.log("Failed to acquire keyboard: " + e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean acquireNonExclusive() {
|
||||
return acquire(WindowsDirectInputDevice.DISCL_NONEXCLUSIVE | WindowsDirectInputDevice.DISCL_FOREGROUND) ||
|
||||
acquire(WindowsDirectInputDevice.DISCL_NONEXCLUSIVE | WindowsDirectInputDevice.DISCL_BACKGROUND);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
keyboard.unacquire();
|
||||
keyboard.release();
|
||||
dinput.release();
|
||||
}
|
||||
|
||||
public void grab(boolean grab) {
|
||||
if(grab) {
|
||||
if (!grabbed) {
|
||||
flush();
|
||||
grabbed = true;
|
||||
keyboard.unacquire();
|
||||
if (!acquire(WindowsDirectInputDevice.DISCL_EXCLUSIVE | WindowsDirectInputDevice.DISCL_FOREGROUND))
|
||||
LWJGLUtil.log("Failed to reset cooperative mode");
|
||||
}
|
||||
} else {
|
||||
if (grabbed) {
|
||||
grabbed = false;
|
||||
keyboard.unacquire();
|
||||
acquireNonExclusive();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void poll(ByteBuffer keyDownBuffer) {
|
||||
int ret = keyboard.acquire();
|
||||
if (ret != WindowsDirectInput.DI_OK && ret != WindowsDirectInput.DI_NOEFFECT)
|
||||
|
@ -181,7 +218,12 @@ final class WindowsKeyboard {
|
|||
private static native int ToAscii(int wVirtKey, int wScanCode, ByteBuffer lpKeyState, ByteBuffer lpChar, int flags);
|
||||
private static native int GetKeyboardState(ByteBuffer lpKeyState);
|
||||
|
||||
public void read(ByteBuffer buffer) {
|
||||
public void flush() {
|
||||
processEvents();
|
||||
temp_data_buffer.clear();
|
||||
}
|
||||
|
||||
private void processEvents() {
|
||||
int ret = keyboard.acquire();
|
||||
if (ret != WindowsDirectInput.DI_OK && ret != WindowsDirectInput.DI_NOEFFECT)
|
||||
return;
|
||||
|
@ -202,6 +244,10 @@ final class WindowsKeyboard {
|
|||
LWJGLUtil.log("Failed to read keyboard (0x" + Integer.toHexString(ret) + ")");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void read(ByteBuffer buffer) {
|
||||
processEvents();
|
||||
temp_data_buffer.flip();
|
||||
translateData(temp_data_buffer, buffer);
|
||||
}
|
||||
|
|
|
@ -246,32 +246,42 @@ final class WindowsMouse {
|
|||
temp_data_buffer.clear();
|
||||
ret = mouse.getDeviceData(temp_data_buffer);
|
||||
|
||||
if (ret == WindowsDirectInput.DI_OK) {
|
||||
if (mouse_grabbed) {
|
||||
temp_data_buffer.flip();
|
||||
copyDXEvents(temp_data_buffer);
|
||||
}
|
||||
} else if (ret == WindowsDirectInput.DI_BUFFEROVERFLOW) {
|
||||
LWJGLUtil.log("Mouse buffer overflowed");
|
||||
} else if (ret == WindowsDirectInput.DIERR_INPUTLOST) {
|
||||
LWJGLUtil.log("Mouse input lost");
|
||||
} else if (ret == WindowsDirectInput.DIERR_NOTACQUIRED) {
|
||||
LWJGLUtil.log("Mouse not acquired");
|
||||
} else {
|
||||
LWJGLUtil.log("unknown mouse error (" + Integer.toHexString(ret) + ")");
|
||||
switch (ret) {
|
||||
case WindowsDirectInput.DI_OK:
|
||||
break;
|
||||
case WindowsDirectInput.DI_BUFFEROVERFLOW:
|
||||
LWJGLUtil.log("Mouse buffer overflowed");
|
||||
break;
|
||||
case WindowsDirectInput.DIERR_INPUTLOST:
|
||||
LWJGLUtil.log("Mouse input lost");
|
||||
break;
|
||||
case WindowsDirectInput.DIERR_NOTACQUIRED:
|
||||
LWJGLUtil.log("Mouse not acquired");
|
||||
break;
|
||||
default:
|
||||
LWJGLUtil.log("unknown mouse error (" + Integer.toHexString(ret) + ")");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public final void flush() {
|
||||
readDXBuffer();
|
||||
temp_data_buffer.clear();
|
||||
}
|
||||
|
||||
public void read(ByteBuffer buffer) {
|
||||
readDXBuffer();
|
||||
if (mouse_grabbed) {
|
||||
temp_data_buffer.flip();
|
||||
copyDXEvents(temp_data_buffer);
|
||||
}
|
||||
event_queue.copyEvents(buffer);
|
||||
}
|
||||
|
||||
public void grab(boolean grab) {
|
||||
if(grab) {
|
||||
if (!mouse_grabbed) {
|
||||
// flush DX event buffer
|
||||
readDXBuffer();
|
||||
flush();
|
||||
mouse_grabbed = true;
|
||||
mouse.unacquire();
|
||||
if (!acquire(WindowsDirectInputDevice.DISCL_EXCLUSIVE | WindowsDirectInputDevice.DISCL_FOREGROUND))
|
||||
|
|
Loading…
Reference in New Issue