From 4e68c787b35fa7b43de290d91207514f7cfc2d99 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Tue, 4 Jul 2006 17:07:13 +0000 Subject: [PATCH] Added Keyboard.getEventNanoseconds() and Mouse.getEventNanoseconds() --- src/java/org/lwjgl/input/Keyboard.java | 17 ++++- src/java/org/lwjgl/input/Mouse.java | 16 ++++- .../org/lwjgl/opengl/KeyboardEventQueue.java | 14 ++-- src/java/org/lwjgl/opengl/LinuxDisplay.java | 6 +- src/java/org/lwjgl/opengl/LinuxKeyboard.java | 18 ++--- src/java/org/lwjgl/opengl/LinuxMouse.java | 67 ++++++++++--------- .../org/lwjgl/opengl/MouseEventQueue.java | 40 +++++------ src/java/org/lwjgl/opengl/Win32Display.java | 30 ++++----- .../opengl/WindowsDirectInputDevice.java | 4 +- .../opengl/WindowsDirectInputDevice3.java | 2 + .../opengl/WindowsDirectInputDevice8.java | 2 + .../org/lwjgl/opengl/WindowsKeyboard.java | 9 ++- src/java/org/lwjgl/opengl/WindowsMouse.java | 40 ++++++----- src/native/linux/org_lwjgl_opengl_Display.c | 4 +- src/native/win32/org_lwjgl_opengl_Display.c | 6 +- ...g_lwjgl_opengl_WindowsDirectInputDevice3.c | 3 +- ...g_lwjgl_opengl_WindowsDirectInputDevice8.c | 3 +- 17 files changed, 166 insertions(+), 115 deletions(-) diff --git a/src/java/org/lwjgl/input/Keyboard.java b/src/java/org/lwjgl/input/Keyboard.java index b5df9c3c..9e3339d9 100644 --- a/src/java/org/lwjgl/input/Keyboard.java +++ b/src/java/org/lwjgl/input/Keyboard.java @@ -56,7 +56,7 @@ import org.lwjgl.opengl.Display; */ public class Keyboard { /** Internal use - event size in bytes */ - public static final int EVENT_SIZE = 4 + 1 + 4; + public static final int EVENT_SIZE = 4 + 1 + 4 + 8; /** * The special character meaning that no @@ -256,6 +256,9 @@ public class Keyboard { /** 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; @@ -426,6 +429,7 @@ public class Keyboard { eventKey = readBuffer.getInt() & 0xFF; eventState = readBuffer.get() != 0; eventCharacter = readBuffer.getInt(); + eventNanos = readBuffer.getLong(); return true; } else { return false; @@ -466,4 +470,15 @@ public class Keyboard { public static boolean getEventKeyState() { return eventState; } + + /** + * Gets the time in nanoseconds of the current event. + * Only useful for relative comparisons with other + * Keyboard events, as the absolute time has no defined + * origin. + * @return The time in nanoseconds of the current event + */ + public static long getEventNanoseconds() { + return eventNanos; + } } diff --git a/src/java/org/lwjgl/input/Mouse.java b/src/java/org/lwjgl/input/Mouse.java index 45c95a4f..cc72e3b7 100644 --- a/src/java/org/lwjgl/input/Mouse.java +++ b/src/java/org/lwjgl/input/Mouse.java @@ -60,7 +60,7 @@ import org.lwjgl.opengl.Display; */ public class Mouse { /** Internal use - event size in bytes */ - public static final int EVENT_SIZE = 1 + 1 + 4 + 4 + 4; + public static final int EVENT_SIZE = 1 + 1 + 4 + 4 + 4 + 8; /** Has the mouse been created? */ private static boolean created; @@ -120,6 +120,7 @@ public class Mouse { /** The current absolute position of the mouse in the event queue */ private static int event_x; private static int event_y; + private static long event_nanos; /** Buffer size in events */ private static final int BUFFER_SIZE = 50; @@ -379,6 +380,7 @@ public class Mouse { event_x = Math.min(Display.getDisplayMode().getWidth() - 1, Math.max(0, event_x)); event_y = Math.min(Display.getDisplayMode().getHeight() - 1, Math.max(0, event_y)); event_dwheel = readBuffer.getInt(); + event_nanos = readBuffer.getLong(); return true; } else return false; @@ -437,6 +439,18 @@ public class Mouse { return event_dwheel; } + /** + * Gets the time in nanoseconds of the current event. + * Only useful for relative comparisons with other + * Mouse events, as the absolute time has no defined + * origin. + * + * @return The time in nanoseconds of the current event + */ + public static long getEventNanoseconds() { + return event_nanos; + } + /** * Retrieves the absolute position. If the Display has been created * x will be clamped to 0...width-1. diff --git a/src/java/org/lwjgl/opengl/KeyboardEventQueue.java b/src/java/org/lwjgl/opengl/KeyboardEventQueue.java index b86a038c..932abc6a 100644 --- a/src/java/org/lwjgl/opengl/KeyboardEventQueue.java +++ b/src/java/org/lwjgl/opengl/KeyboardEventQueue.java @@ -242,11 +242,11 @@ final class KeyboardEventQueue extends EventQueue implements KeyListener { super(Keyboard.EVENT_SIZE); } - private void putKeyboardEvent(int key_code, byte state, int character) { - event.putInt(key_code).put(state).putInt(character); + private void putKeyboardEvent(int key_code, byte state, int character, long nanos) { + event.clear(); + event.putInt(key_code).put(state).putInt(character).putLong(nanos); event.flip(); putEvent(event); - event.compact(); } public synchronized void poll(ByteBuffer key_down_buffer) { @@ -255,7 +255,7 @@ final class KeyboardEventQueue extends EventQueue implements KeyListener { key_down_buffer.position(old_position); } - private synchronized void handleKey(int key_code_mapped, byte state, int character) { + private synchronized void handleKey(int key_code_mapped, byte state, int character, long nanos) { if ( character == KeyEvent.CHAR_UNDEFINED ) character = Keyboard.CHAR_NONE; /* Ignore repeating presses */ @@ -263,7 +263,7 @@ final class KeyboardEventQueue extends EventQueue implements KeyListener { return; key_states[key_code_mapped] = state; int key_int_char = character & 0xffff; - putKeyboardEvent(key_code_mapped, state, key_int_char); + putKeyboardEvent(key_code_mapped, state, key_int_char, nanos); } private int getMappedKeyCode(int key_code, int position) { @@ -291,11 +291,11 @@ final class KeyboardEventQueue extends EventQueue implements KeyListener { } public void keyPressed(KeyEvent e) { - handleKey(getMappedKeyCode(e.getKeyCode(), e.getKeyLocation()), (byte)1, e.getKeyChar()); + handleKey(getMappedKeyCode(e.getKeyCode(), e.getKeyLocation()), (byte)1, e.getKeyChar(), e.getWhen()*1000000); } public void keyReleased(KeyEvent e) { - handleKey(getMappedKeyCode(e.getKeyCode(), e.getKeyLocation()), (byte)0, Keyboard.CHAR_NONE); + handleKey(getMappedKeyCode(e.getKeyCode(), e.getKeyLocation()), (byte)0, Keyboard.CHAR_NONE, e.getWhen()*1000000); } public void keyTyped(KeyEvent e) { diff --git a/src/java/org/lwjgl/opengl/LinuxDisplay.java b/src/java/org/lwjgl/opengl/LinuxDisplay.java index 87101e10..f76029be 100644 --- a/src/java/org/lwjgl/opengl/LinuxDisplay.java +++ b/src/java/org/lwjgl/opengl/LinuxDisplay.java @@ -972,7 +972,7 @@ final class LinuxDisplay implements DisplayImplementation { /* Callbacks from nUpdate() */ private static void handleButtonEvent(long millis, int type, int button, int state) { if (mouse != null) - mouse.handleButtonEvent(grab, type, (byte)button); + mouse.handleButtonEvent(grab, millis, type, (byte)button); } private static void handleKeyEvent(long event_ptr, long millis, int type, int keycode, int state) { @@ -980,9 +980,9 @@ final class LinuxDisplay implements DisplayImplementation { keyboard.handleKeyEvent(event_ptr, millis, type, keycode, state); } - private static void handlePointerMotionEvent(long root_window, int x_root, int y_root, int x, int y, int state) { + private static void handlePointerMotionEvent(long millis, long root_window, int x_root, int y_root, int x, int y, int state) { if (mouse != null) - mouse.handlePointerMotion(grab, pointer_grabbed, shouldGrab(), root_window, x_root, y_root, x, y); + mouse.handlePointerMotion(grab, pointer_grabbed, shouldGrab(), millis, root_window, x_root, y_root, x, y); } private static void handleWarpEvent(int x, int y) { diff --git a/src/java/org/lwjgl/opengl/LinuxKeyboard.java b/src/java/org/lwjgl/opengl/LinuxKeyboard.java index 263de149..1ac57963 100644 --- a/src/java/org/lwjgl/opengl/LinuxKeyboard.java +++ b/src/java/org/lwjgl/opengl/LinuxKeyboard.java @@ -160,11 +160,11 @@ final class LinuxKeyboard { keyDownBuffer.position(old_position); } - private void putKeyboardEvent(int keycode, byte state, int ch) { - tmp_event.putInt(keycode).put(state).putInt(ch); + private void putKeyboardEvent(int keycode, byte state, int ch, long nanos) { + tmp_event.clear(); + tmp_event.putInt(keycode).put(state).putInt(ch).putLong(nanos); tmp_event.flip(); event_queue.putEvent(tmp_event); - tmp_event.compact(); } private int lookupStringISO88591(long event_ptr, int[] translation_buffer) { @@ -202,24 +202,24 @@ final class LinuxKeyboard { return lookupStringISO88591(event_ptr, translation_buffer); } - private void translateEvent(long event_ptr, int event_type, int keycode, byte key_state) { + private void translateEvent(long event_ptr, int event_type, int keycode, byte key_state, long nanos) { int num_chars, i; int ch; if (event_type == KeyRelease) { - putKeyboardEvent(keycode, key_state, 0); + putKeyboardEvent(keycode, key_state, 0, nanos); return; } num_chars = lookupString(event_ptr, temp_translation_buffer); if (num_chars > 0) { ch = temp_translation_buffer[0]; - putKeyboardEvent(keycode, key_state, ch); + putKeyboardEvent(keycode, key_state, ch, nanos); for (i = 1; i < num_chars; i++) { ch = temp_translation_buffer[i]; - putKeyboardEvent(0, (byte)0, ch); + putKeyboardEvent(0, (byte)0, ch, nanos); } } else { - putKeyboardEvent(keycode, key_state, 0); + putKeyboardEvent(keycode, key_state, 0, nanos); } } @@ -298,6 +298,6 @@ final class LinuxKeyboard { int keycode = getKeycode(event_ptr, event_state); byte key_state = getKeyState(event_type); key_down_buffer[keycode] = key_state; - translateEvent(event_ptr, event_type, keycode, key_state); + translateEvent(event_ptr, event_type, keycode, key_state, millis*1000000); } } diff --git a/src/java/org/lwjgl/opengl/LinuxMouse.java b/src/java/org/lwjgl/opengl/LinuxMouse.java index 7a70d484..796fbcb3 100644 --- a/src/java/org/lwjgl/opengl/LinuxMouse.java +++ b/src/java/org/lwjgl/opengl/LinuxMouse.java @@ -73,6 +73,7 @@ final class LinuxMouse { private int accum_dz; private byte[] buttons = new byte[NUM_BUTTONS]; private EventQueue event_queue; + private long last_event_nanos; public LinuxMouse(long display, long window) { this.display = display; @@ -103,25 +104,28 @@ final class LinuxMouse { buttons_buffer.put(i, buttons[i]); } - private void putMouseEventWithCoords(byte button, byte state, int coord1, int coord2, int dz) { - event_buffer.put(button).put(state).putInt(coord1).putInt(coord2).putInt(dz); + private void putMouseEventWithCoords(byte button, byte state, int coord1, int coord2, int dz, long nanos) { + event_buffer.clear(); + event_buffer.put(button).put(state).putInt(coord1).putInt(coord2).putInt(dz).putLong(nanos); event_buffer.flip(); event_queue.putEvent(event_buffer); - event_buffer.compact(); + last_event_nanos = nanos; } - private void setCursorPos(boolean grab, int x, int y) { + private void setCursorPos(boolean grab, int x, int y, long nanos) { y = transformY(y); int dx = x - last_x; int dy = y - last_y; - accum_dx += dx; - accum_dy += dy; - last_x = x; - last_y = y; - if (grab) { - putMouseEventWithCoords((byte)-1, (byte)0, dx, dy, 0); - } else { - putMouseEventWithCoords((byte)-1, (byte)0, x, y, 0); + if (dx != 0 || dy != 0) { + accum_dx += dx; + accum_dy += dy; + last_x = x; + last_y = y; + if (grab) { + putMouseEventWithCoords((byte)-1, (byte)0, dx, dy, 0, nanos); + } else { + putMouseEventWithCoords((byte)-1, (byte)0, x, y, 0, nanos); + } } } @@ -131,8 +135,8 @@ final class LinuxMouse { } private static native void nSendWarpEvent(long display, long window, int center_x, int center_y); - private void doHandlePointerMotion(boolean grab, boolean pointer_grabbed, boolean should_grab, long root_window, int root_x, int root_y, int win_x, int win_y) { - setCursorPos(grab, win_x, win_y); + private void doHandlePointerMotion(boolean grab, boolean pointer_grabbed, boolean should_grab, long root_window, int root_x, int root_y, int win_x, int win_y, long nanos) { + setCursorPos(grab, win_x, win_y, nanos); if (!pointer_grabbed || !should_grab) return; int root_window_height = nGetWindowHeight(display, root_window); @@ -164,7 +168,7 @@ final class LinuxMouse { public void changeGrabbed(boolean grab, boolean pointer_grabbed, boolean should_grab) { reset(); long root_window = nQueryPointer(display, window, query_pointer_buffer); - doHandlePointerMotion(grab, pointer_grabbed, should_grab, root_window, query_pointer_buffer.get(0), query_pointer_buffer.get(1), query_pointer_buffer.get(2), query_pointer_buffer.get(3)); + doHandlePointerMotion(grab, pointer_grabbed, should_grab, root_window, query_pointer_buffer.get(0), query_pointer_buffer.get(1), query_pointer_buffer.get(2), query_pointer_buffer.get(3), last_event_nanos); } public int getButtonCount() { @@ -184,11 +188,11 @@ final class LinuxMouse { } private static native void nWarpCursor(long display, long window, int x, int y); - public void handlePointerMotion(boolean grab, boolean pointer_grabbed, boolean should_grab, long root_window, int x_root, int y_root, int x, int y) { - doHandlePointerMotion(grab, pointer_grabbed, should_grab, root_window, x_root, y_root, x, y); + public void handlePointerMotion(boolean grab, boolean pointer_grabbed, boolean should_grab, long millis, long root_window, int x_root, int y_root, int x, int y) { + doHandlePointerMotion(grab, pointer_grabbed, should_grab, root_window, x_root, y_root, x, y, millis*1000000); } - private void handleButton(boolean grab, int button, byte state) { + private void handleButton(boolean grab, int button, byte state, long nanos) { byte button_num; switch (button) { case Button1: @@ -204,46 +208,43 @@ final class LinuxMouse { return; } buttons[button_num] = state; - putMouseEvent(grab, button_num, state, 0); + putMouseEvent(grab, button_num, state, 0, nanos); } - private void putMouseEvent(boolean grab, byte button, byte state, int dz) { + private void putMouseEvent(boolean grab, byte button, byte state, int dz, long nanos) { if (grab) - putMouseEventWithCoords(button, state, 0, 0, dz); + putMouseEventWithCoords(button, state, 0, 0, dz, nanos); else - putMouseEventWithCoords(button, state, last_x, last_y, dz); + putMouseEventWithCoords(button, state, last_x, last_y, dz, nanos); } - private void handleButtonPress(boolean grab, byte button) { + private void handleButtonPress(boolean grab, byte button, long nanos) { int delta = 0; switch (button) { case Button4: delta = WHEEL_SCALE; - putMouseEvent(grab, (byte)-1, (byte)0, delta); + putMouseEvent(grab, (byte)-1, (byte)0, delta, nanos); accum_dz += delta; break; case Button5: delta = -WHEEL_SCALE; - putMouseEvent(grab, (byte)-1, (byte)0, delta); + putMouseEvent(grab, (byte)-1, (byte)0, delta, nanos); accum_dz += delta; break; default: - handleButton(grab, button, (byte)1); + handleButton(grab, button, (byte)1, nanos); break; } } - private void handleButtonRelease(boolean grab, int button) { - handleButton(grab, button, (byte)0); - } - - public void handleButtonEvent(boolean grab, int type, byte button) { + public void handleButtonEvent(boolean grab, long millis, int type, byte button) { + long nanos = millis*1000000; switch (type) { case ButtonRelease: - handleButton(grab, button, (byte)0); + handleButton(grab, button, (byte)0, nanos); break; case ButtonPress: - handleButtonPress(grab, button); + handleButtonPress(grab, button, nanos); break; default: break; diff --git a/src/java/org/lwjgl/opengl/MouseEventQueue.java b/src/java/org/lwjgl/opengl/MouseEventQueue.java index 1a07aab9..aaba9bf2 100644 --- a/src/java/org/lwjgl/opengl/MouseEventQueue.java +++ b/src/java/org/lwjgl/opengl/MouseEventQueue.java @@ -104,18 +104,18 @@ final class MouseEventQueue extends EventQueue implements MouseListener, MouseMo ((MacOSXDisplay)Display.getImplementation()).getMouseDeltas(delta_buffer); } - private void putMouseEvent(byte button, byte state, int dz) { + private void putMouseEvent(byte button, byte state, int dz, long nanos) { if (grabbed) - putMouseEventWithCoords(button, state, 0, 0, dz); + putMouseEventWithCoords(button, state, 0, 0, dz, nanos); else - putMouseEventWithCoords(button, state, last_x, last_y, dz); + putMouseEventWithCoords(button, state, last_x, last_y, dz, nanos); } - private void putMouseEventWithCoords(byte button, byte state, int coord1, int coord2, int dz) { - event.put(button).put(state).putInt(coord1).putInt(coord2).putInt(dz); + private void putMouseEventWithCoords(byte button, byte state, int coord1, int coord2, int dz, long nanos) { + event.clear(); + event.put(button).put(state).putInt(coord1).putInt(coord2).putInt(dz).putLong(nanos); event.flip(); putEvent(event); - event.compact(); } public synchronized void poll(IntBuffer coord_buffer, ByteBuffer buttons_buffer) { @@ -133,7 +133,7 @@ final class MouseEventQueue extends EventQueue implements MouseListener, MouseMo buttons_buffer.position(old_position); } - private synchronized void setCursorPos(int x, int y) { + private synchronized void setCursorPos(int x, int y, long nanos) { y = transformY(y); if ( grabbed ) return; @@ -143,7 +143,7 @@ final class MouseEventQueue extends EventQueue implements MouseListener, MouseMo accum_dy += dy; last_x = x; last_y = y; - putMouseEventWithCoords((byte)-1, (byte)0, x, y, 0); + putMouseEventWithCoords((byte)-1, (byte)0, x, y, 0, nanos); } public void mouseClicked(MouseEvent e) { @@ -195,16 +195,16 @@ final class MouseEventQueue extends EventQueue implements MouseListener, MouseMo default: throw new IllegalArgumentException("Not a valid button: " + e.getButton()); } - setButton(button, state); + setButton(button, state, e.getWhen()*1000000); } public void mousePressed(MouseEvent e) { handleButton(e); } - private synchronized void setButton(byte button, byte state) { + private synchronized void setButton(byte button, byte state, long nanos) { buttons[button] = state; - putMouseEvent(button, state, 0); + putMouseEvent(button, state, 0, nanos); } public void mouseReleased(MouseEvent e) { @@ -212,10 +212,10 @@ final class MouseEventQueue extends EventQueue implements MouseListener, MouseMo } private void handleMotion(MouseEvent e) { - if ( grabbed ) { - updateDeltas(); + if (grabbed) { + updateDeltas(e.getWhen()*1000000); } else { - setCursorPos(e.getX(), e.getY()); + setCursorPos(e.getX(), e.getY(), e.getWhen()*1000000); } } @@ -227,20 +227,20 @@ final class MouseEventQueue extends EventQueue implements MouseListener, MouseMo handleMotion(e); } - private synchronized void handleWheel(int amount) { + private synchronized void handleWheel(int amount, long nanos) { accum_dz += amount; - putMouseEvent((byte)-1, (byte)0, amount); + putMouseEvent((byte)-1, (byte)0, amount, nanos); } - private void updateDeltas() { - if ( !grabbed ) + private void updateDeltas(long nanos) { + if (!grabbed) return; synchronized ( this ) { ((MacOSXDisplay)Display.getImplementation()).getMouseDeltas(delta_buffer); int dx = delta_buffer.get(0); int dy = -delta_buffer.get(1); if ( dx != 0 || dy != 0 ) { - putMouseEventWithCoords((byte)-1, (byte)0, dx, dy, 0); + putMouseEventWithCoords((byte)-1, (byte)0, dx, dy, 0, nanos); accum_dx += dx; accum_dy += dy; } @@ -249,6 +249,6 @@ final class MouseEventQueue extends EventQueue implements MouseListener, MouseMo public void mouseWheelMoved(MouseWheelEvent e) { int wheel_amount = -e.getWheelRotation() * WHEEL_SCALE; - handleWheel(wheel_amount); + handleWheel(wheel_amount, e.getWhen()*1000000); } } diff --git a/src/java/org/lwjgl/opengl/Win32Display.java b/src/java/org/lwjgl/opengl/Win32Display.java index 023cedac..72536410 100644 --- a/src/java/org/lwjgl/opengl/Win32Display.java +++ b/src/java/org/lwjgl/opengl/Win32Display.java @@ -338,51 +338,51 @@ final class Win32Display implements DisplayImplementation { private static native int nSetWindowIcon32(IntBuffer icon); - private static void handleMouseButton(int button, int state) { + private static void handleMouseButton(int button, int state, long millis) { if (mouse != null) - mouse.handleMouseButton((byte)button, (byte)state); + mouse.handleMouseButton((byte)button, (byte)state, millis); } - private static void handleMouseMoved(int x, int y) { + private static void handleMouseMoved(int x, int y, long millis) { if (mouse != null) - mouse.handleMouseMoved(x, y); + mouse.handleMouseMoved(x, y, millis); } - private static void handleMouseScrolled(int amount) { + private static void handleMouseScrolled(int amount, long millis) { if (mouse != null) - mouse.handleMouseScrolled(amount); + mouse.handleMouseScrolled(amount, millis); } private static native int transformY(long hwnd, int y); - private static boolean handleMessage(long hwnd, int msg, long wParam, long lParam) { + private static boolean handleMessage(long hwnd, int msg, long wParam, long lParam, long millis) { switch (msg) { case WM_MOUSEMOVE: int xPos = (int)(short)(lParam & 0xFFFF); int yPos = transformY(getHwnd(), (int)(short)((lParam >> 16) & 0xFFFF)); - handleMouseMoved(xPos, yPos); + handleMouseMoved(xPos, yPos, millis); return true; case WM_MOUSEWHEEL: int dwheel = (int)(short)((wParam >> 16) & 0xFFFF); - handleMouseScrolled(dwheel); + handleMouseScrolled(dwheel, millis); return true; case WM_LBUTTONDOWN: - handleMouseButton(0, 1); + handleMouseButton(0, 1, millis); return true; case WM_LBUTTONUP: - handleMouseButton(0, 0); + handleMouseButton(0, 0, millis); return true; case WM_RBUTTONDOWN: - handleMouseButton(1, 1); + handleMouseButton(1, 1, millis); return true; case WM_RBUTTONUP: - handleMouseButton(1, 0); + handleMouseButton(1, 0, millis); return true; case WM_MBUTTONDOWN: - handleMouseButton(2, 1); + handleMouseButton(2, 1, millis); return true; case WM_MBUTTONUP: - handleMouseButton(2, 0); + handleMouseButton(2, 0, millis); return true; case WM_QUIT: close_requested = true; diff --git a/src/java/org/lwjgl/opengl/WindowsDirectInputDevice.java b/src/java/org/lwjgl/opengl/WindowsDirectInputDevice.java index 1e1ec464..68b2ff71 100644 --- a/src/java/org/lwjgl/opengl/WindowsDirectInputDevice.java +++ b/src/java/org/lwjgl/opengl/WindowsDirectInputDevice.java @@ -54,6 +54,8 @@ abstract class WindowsDirectInputDevice { public final static int GUID_Button = 4; public final static int GUID_Unknown = 5; + public final static int DATA_SIZE = 3; + private final long di_device; private ByteBuffer event_buffer; @@ -100,7 +102,7 @@ abstract class WindowsDirectInputDevice { protected abstract int setBufferSize(long di_device, int buffer_size); public int getDeviceData(IntBuffer buffer) { - int events_remaining = buffer.remaining()/2; + int events_remaining = buffer.remaining()/DATA_SIZE; if (event_buffer == null || events_remaining > event_buffer.remaining()/getEventSize()) event_buffer = BufferUtils.createByteBuffer(events_remaining*getEventSize()); return getDeviceData(di_device, event_buffer, event_buffer.capacity(), buffer, buffer.position(), buffer.remaining()); diff --git a/src/java/org/lwjgl/opengl/WindowsDirectInputDevice3.java b/src/java/org/lwjgl/opengl/WindowsDirectInputDevice3.java index 88d796be..d027e9ae 100644 --- a/src/java/org/lwjgl/opengl/WindowsDirectInputDevice3.java +++ b/src/java/org/lwjgl/opengl/WindowsDirectInputDevice3.java @@ -48,6 +48,8 @@ final class WindowsDirectInputDevice3 extends WindowsDirectInputDevice { public final static int GUID_Button = WindowsDirectInputDevice.GUID_Button; public final static int GUID_Unknown = WindowsDirectInputDevice.GUID_Unknown; + public final static int DATA_SIZE = WindowsDirectInputDevice.DATA_SIZE; + public WindowsDirectInputDevice3(long di_device) { super(di_device); } diff --git a/src/java/org/lwjgl/opengl/WindowsDirectInputDevice8.java b/src/java/org/lwjgl/opengl/WindowsDirectInputDevice8.java index 92cafce3..350b7f97 100644 --- a/src/java/org/lwjgl/opengl/WindowsDirectInputDevice8.java +++ b/src/java/org/lwjgl/opengl/WindowsDirectInputDevice8.java @@ -48,6 +48,8 @@ final class WindowsDirectInputDevice8 extends WindowsDirectInputDevice { public final static int GUID_Button = WindowsDirectInputDevice.GUID_Button; public final static int GUID_Unknown = WindowsDirectInputDevice.GUID_Unknown; + public final static int DATA_SIZE = WindowsDirectInputDevice.DATA_SIZE; + public WindowsDirectInputDevice8(long di_device) { super(di_device); } diff --git a/src/java/org/lwjgl/opengl/WindowsKeyboard.java b/src/java/org/lwjgl/opengl/WindowsKeyboard.java index 80f09fb2..57afced7 100644 --- a/src/java/org/lwjgl/opengl/WindowsKeyboard.java +++ b/src/java/org/lwjgl/opengl/WindowsKeyboard.java @@ -110,6 +110,8 @@ final class WindowsKeyboard { byte dwData = (byte)src.get(); boolean key_down = (dwData & 0x80) != 0; dst.put(key_down ? (byte)1 : (byte)0); + long dwTimeStamp = ((long)src.get()) & 0xFFFFFFFF; + long nanos = dwTimeStamp*1000000; if (key_down) { int virt_key = MapVirtualKey(dwOfs, 1); if (virt_key != 0 && GetKeyboardState(keyboard_state) != 0) { @@ -130,16 +132,21 @@ final class WindowsKeyboard { } int char_int = ((int)unicode_buffer.get()) & 0xFFFF; dst.putInt(char_int); + dst.putLong(nanos); current_char++; } while (dst.hasRemaining() && current_char < num_chars); } else { dst.putInt(0); + dst.putLong(nanos); } } else { dst.putInt(0); + dst.putLong(nanos); } - } else + } else { dst.putInt(0); + dst.putLong(nanos); + } } } private static native int MapVirtualKey(int uCode, int uMapType); diff --git a/src/java/org/lwjgl/opengl/WindowsMouse.java b/src/java/org/lwjgl/opengl/WindowsMouse.java index 75d41d3c..e4046164 100644 --- a/src/java/org/lwjgl/opengl/WindowsMouse.java +++ b/src/java/org/lwjgl/opengl/WindowsMouse.java @@ -180,18 +180,18 @@ final class WindowsMouse { } } - private void putMouseEventWithCoords(byte button, byte state, int coord1, int coord2, int dz) { - mouse_event.put(button).put(state).putInt(coord1).putInt(coord2).putInt(dz); + private void putMouseEventWithCoords(byte button, byte state, int coord1, int coord2, int dz, long nanos) { + mouse_event.clear(); + mouse_event.put(button).put(state).putInt(coord1).putInt(coord2).putInt(dz).putLong(nanos); mouse_event.flip(); event_queue.putEvent(mouse_event); - mouse_event.compact(); } - private void putMouseEvent(byte button, byte state, int dz) { + private void putMouseEvent(byte button, byte state, int dz, long nanos) { if (mouse_grabbed) - putMouseEventWithCoords(button, state, 0, 0, dz); + putMouseEventWithCoords(button, state, 0, 0, dz, nanos); else - putMouseEventWithCoords(button, state, last_x, last_y, dz); + putMouseEventWithCoords(button, state, last_x, last_y, dz, nanos); } private void copyDXEvents(IntBuffer buffer) { @@ -199,25 +199,28 @@ final class WindowsMouse { int dx = 0, dy = 0, dwheel = 0; byte button_state; int i; + long nanos = 0; while (buffer.hasRemaining()) { int dwOfs = buffer.get(); int dwData = buffer.get(); + long dwTimeStamp = ((long)buffer.get()) & 0xFFFFFFFF; + nanos = dwTimeStamp*1000000; button_state = (dwData & 0x80) != 0 ? (byte)1 : (byte)0; switch (dwOfs) { case DIMOFS_BUTTON0: - putMouseEventWithCoords((byte)0, button_state, dx, -dy, dwheel); + putMouseEventWithCoords((byte)0, button_state, dx, -dy, dwheel, nanos); dx = dy = dwheel = 0; break; case DIMOFS_BUTTON1: - putMouseEventWithCoords((byte)1, button_state, dx, -dy, dwheel); + putMouseEventWithCoords((byte)1, button_state, dx, -dy, dwheel, nanos); dx = dy = dwheel = 0; break; case DIMOFS_BUTTON2: - putMouseEventWithCoords((byte)2, button_state, dx, -dy, dwheel); + putMouseEventWithCoords((byte)2, button_state, dx, -dy, dwheel, nanos); dx = dy = dwheel = 0; break; case DIMOFS_BUTTON3: - putMouseEventWithCoords((byte)3, button_state, dx, -dy, dwheel); + putMouseEventWithCoords((byte)3, button_state, dx, -dy, dwheel, nanos); dx = dy = dwheel = 0; break; case DIMOFS_X: @@ -232,7 +235,7 @@ final class WindowsMouse { } } if (dx != 0 || dy != 0 || dwheel != 0) - putMouseEventWithCoords((byte)-1, (byte)0, dx, -dy, dwheel); + putMouseEventWithCoords((byte)-1, (byte)0, dx, -dy, dwheel, nanos); } private void readDXBuffer() { @@ -284,27 +287,28 @@ final class WindowsMouse { event_queue.clearEvents(); } - public void handleMouseScrolled(int event_dwheel) { + public void handleMouseScrolled(int event_dwheel, long millis) { accum_dwheel += event_dwheel; - putMouseEvent((byte)-1, (byte)0, event_dwheel); + putMouseEvent((byte)-1, (byte)0, event_dwheel, millis*1000000); } - public void handleMouseMoved(int x, int y) { + public void handleMouseMoved(int x, int y, long millis) { int dx; int dy; dx = x - last_x; dy = y - last_y; last_x = x; last_y = y; + long nanos = millis*1000000; if (mouse_grabbed) { - putMouseEventWithCoords((byte)-1, (byte)0, dx, dy, 0); + putMouseEventWithCoords((byte)-1, (byte)0, dx, dy, 0, nanos); } else { - putMouseEventWithCoords((byte)-1, (byte)0, x, y, 0); + putMouseEventWithCoords((byte)-1, (byte)0, x, y, 0, nanos); } } - public void handleMouseButton(byte button, byte state) { - putMouseEvent(button, state, 0); + public void handleMouseButton(byte button, byte state, long millis) { + putMouseEvent(button, state, 0, millis*1000000); if (button < BUTTON_STATES_SIZE) win32_message_button_states[button] = state != 0 ? (byte)1 : (byte)0; } diff --git a/src/native/linux/org_lwjgl_opengl_Display.c b/src/native/linux/org_lwjgl_opengl_Display.c index fa3c02b7..7a439c9d 100644 --- a/src/native/linux/org_lwjgl_opengl_Display.c +++ b/src/native/linux/org_lwjgl_opengl_Display.c @@ -175,7 +175,7 @@ static void handleMessages(JNIEnv *env, jclass disp_class) { jmethodID handleButtonEvent_method = (*env)->GetStaticMethodID(env, disp_class, "handleButtonEvent", "(JIII)V"); if (handleButtonEvent_method == NULL) return; - jmethodID handlePointerMotionEvent_method = (*env)->GetStaticMethodID(env, disp_class, "handlePointerMotionEvent", "(JIIIII)V"); + jmethodID handlePointerMotionEvent_method = (*env)->GetStaticMethodID(env, disp_class, "handlePointerMotionEvent", "(JJIIIII)V"); if (handlePointerMotionEvent_method == NULL) return; jmethodID handleWarpEvent_method = (*env)->GetStaticMethodID(env, disp_class, "handleWarpEvent", "(II)V"); @@ -221,7 +221,7 @@ static void handleMessages(JNIEnv *env, jclass disp_class) { (*env)->CallStaticVoidMethod(env, disp_class, handleButtonEvent_method, (jlong)event.xbutton.time, (jint)event.xbutton.type, (jint)event.xbutton.button, (jint)event.xbutton.state); break; case MotionNotify: - (*env)->CallStaticVoidMethod(env, disp_class, handlePointerMotionEvent_method, (jlong)event.xbutton.root, (jint)event.xbutton.x_root, (jint)event.xbutton.y_root, (jint)event.xbutton.x, (jint)event.xbutton.y, (jint)event.xbutton.state); + (*env)->CallStaticVoidMethod(env, disp_class, handlePointerMotionEvent_method, (jlong)event.xbutton.time, (jlong)event.xbutton.root, (jint)event.xbutton.x_root, (jint)event.xbutton.y_root, (jint)event.xbutton.x, (jint)event.xbutton.y, (jint)event.xbutton.state); break; case KeyPress: case KeyRelease: diff --git a/src/native/win32/org_lwjgl_opengl_Display.c b/src/native/win32/org_lwjgl_opengl_Display.c index 45a5431c..63d37239 100644 --- a/src/native/win32/org_lwjgl_opengl_Display.c +++ b/src/native/win32/org_lwjgl_opengl_Display.c @@ -144,6 +144,7 @@ static LRESULT CALLBACK lwjglWindowProc(HWND hWnd, JNIEnv *env; jclass display_class; jmethodID handleMessage_method; + LONG message_time; if (isFullScreen && !isMinimized && isFocused) setupCursorClipping(); switch (msg) { @@ -176,9 +177,10 @@ static LRESULT CALLBACK lwjglWindowProc(HWND hWnd, if (env != NULL && !(*env)->ExceptionOccurred(env)) { display_class = (*env)->FindClass(env, "org/lwjgl/opengl/Win32Display"); if (display_class != NULL) { - handleMessage_method = (*env)->GetStaticMethodID(env, display_class, "handleMessage", "(JIJJ)Z"); + message_time = GetMessageTime(); + handleMessage_method = (*env)->GetStaticMethodID(env, display_class, "handleMessage", "(JIJJJ)Z"); if (handleMessage_method != NULL) - if ((*env)->CallStaticBooleanMethod(env, NULL, handleMessage_method, (jlong)hWnd, (jint)msg, (jlong)wParam, (jlong)lParam)) + if ((*env)->CallStaticBooleanMethod(env, NULL, handleMessage_method, (jlong)hWnd, (jint)msg, (jlong)wParam, (jlong)lParam, (jlong)message_time)) return 0; } } diff --git a/src/native/win32/org_lwjgl_opengl_WindowsDirectInputDevice3.c b/src/native/win32/org_lwjgl_opengl_WindowsDirectInputDevice3.c index f880c1e0..92a15ef5 100644 --- a/src/native/win32/org_lwjgl_opengl_WindowsDirectInputDevice3.c +++ b/src/native/win32/org_lwjgl_opengl_WindowsDirectInputDevice3.c @@ -86,7 +86,7 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice3_getDevice DIDEVICEOBJECTDATA *current_event; DWORD num_events = event_buffer_size/sizeof(DIDEVICEOBJECTDATA); HRESULT ret = IDirectInputDevice_GetDeviceData(lpdevice, sizeof(DIDEVICEOBJECTDATA), event_buffer, &num_events, 0); - jint num_buffer_events = buffer_size/2; + jint num_buffer_events = buffer_size/org_lwjgl_opengl_WindowsDirectInputDevice3_DATA_SIZE; jint i; if (ret != DI_OK && ret != DI_BUFFEROVERFLOW) return ret; @@ -99,6 +99,7 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice3_getDevice current_event = event_buffer + i; buffer[buffer_pos++] = current_event->dwOfs; buffer[buffer_pos++] = current_event->dwData; + buffer[buffer_pos++] = current_event->dwTimeStamp; } positionBuffer(env, buffer_obj, buffer_pos); return ret; diff --git a/src/native/win32/org_lwjgl_opengl_WindowsDirectInputDevice8.c b/src/native/win32/org_lwjgl_opengl_WindowsDirectInputDevice8.c index 83d57f79..5cd9646e 100644 --- a/src/native/win32/org_lwjgl_opengl_WindowsDirectInputDevice8.c +++ b/src/native/win32/org_lwjgl_opengl_WindowsDirectInputDevice8.c @@ -91,7 +91,7 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice8_getDevice DIDEVICEOBJECTDATA *current_event; DWORD num_events = event_buffer_size/sizeof(DIDEVICEOBJECTDATA); HRESULT ret = IDirectInputDevice8_GetDeviceData(lpdevice, sizeof(DIDEVICEOBJECTDATA), event_buffer, &num_events, 0); - jint num_buffer_events = buffer_size/2; + jint num_buffer_events = buffer_size/org_lwjgl_opengl_WindowsDirectInputDevice8_DATA_SIZE; jint i; if (ret != DI_OK && ret != DI_BUFFEROVERFLOW) return ret; @@ -104,6 +104,7 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice8_getDevice current_event = event_buffer + i; buffer[buffer_pos++] = current_event->dwOfs; buffer[buffer_pos++] = current_event->dwData; + buffer[buffer_pos++] = current_event->dwTimeStamp; } positionBuffer(env, buffer_obj, buffer_pos); return ret;