From: <eli...@us...> - 2007-04-24 09:30:08
|
Revision: 2799 http://svn.sourceforge.net/java-game-lib/?rev=2799&view=rev Author: elias_naur Date: 2007-04-24 02:30:03 -0700 (Tue, 24 Apr 2007) Log Message: ----------- Windows: Remove dependency on DirectInput for WindowsMouse used by WindowsDisplay. Keyboard conversion coming up. Reasons: 1. DirectInput is deprecated (http://en.wikipedia.org/wiki/DirectInput). Specifically, Microsoft recommends using regular windows messages for keyboard and mouse input. 2. Not using DirectInput enable us to use the Raw Input JInput plugin to access multiple mice (and keyboards). 3. We're already using windows messages for features DirectInput never supported, so by removing DirectInput dependency, we get rid of some special case code. 4. When we're only using windows messages for input, we're (theoretically) more compatible than with a dependency on a properly working DirectInput. Modified Paths: -------------- trunk/LWJGL/src/java/org/lwjgl/Sys.java trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsAWTInput.java trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsDisplay.java trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsMouse.java trunk/LWJGL/src/native/common/common_tools.c trunk/LWJGL/src/native/common/common_tools.h trunk/LWJGL/src/native/windows/org_lwjgl_input_Cursor.c trunk/LWJGL/src/native/windows/org_lwjgl_opengl_Display.c Added Paths: ----------- trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsDirectInputMouse.java Modified: trunk/LWJGL/src/java/org/lwjgl/Sys.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/Sys.java 2007-04-23 20:50:44 UTC (rev 2798) +++ trunk/LWJGL/src/java/org/lwjgl/Sys.java 2007-04-24 09:30:03 UTC (rev 2799) @@ -57,7 +57,7 @@ private static final String VERSION = "1.1"; /** Current version of the JNI library */ - static final int JNI_VERSION = 8; + static final int JNI_VERSION = 9; /** The implementation instance to delegate platform specific behavior to */ private final static SysImplementation implementation; Modified: trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsAWTInput.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsAWTInput.java 2007-04-23 20:50:44 UTC (rev 2798) +++ trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsAWTInput.java 2007-04-24 09:30:03 UTC (rev 2799) @@ -53,7 +53,7 @@ private Cursor cached_cursor; private long cached_hwnd; - private WindowsMouse cached_mouse; + private WindowsDirectInputMouse cached_mouse; // private WindowsKeyboard cached_keyboard; private boolean has_grabbed; @@ -96,7 +96,7 @@ cached_keyboard.destroy(); }*/ WindowsDirectInput dinput = WindowsDisplay.createDirectInput(); - cached_mouse = new WindowsMouse(dinput, hwnd); + cached_mouse = new WindowsDirectInputMouse(dinput, hwnd); // cached_keyboard = new WindowsKeyboard(dinput, hwnd); } if (isGrabbed()) { @@ -105,7 +105,7 @@ * task bar and clicking on it. So we'll use ClipCursor to * contain it while the cursor is grabbed. */ - WindowsDisplay.setupCursorClipping(hwnd); + WindowsDisplay.setupCursorClipping(hwnd, true); // Just clip it to a fullscreen window if (getCanvas().getCursor() != blank_cursor) { cached_cursor = getCanvas().getCursor(); /** Added: trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsDirectInputMouse.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsDirectInputMouse.java (rev 0) +++ trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsDirectInputMouse.java 2007-04-24 09:30:03 UTC (rev 2799) @@ -0,0 +1,353 @@ +/* + * Copyright (c) 2002-2004 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +/** + * This is the Windows implementation of the Mouse. + * @author elias_naur + */ + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; +import java.nio.CharBuffer; + +import org.lwjgl.LWJGLException; +import org.lwjgl.LWJGLUtil; +import org.lwjgl.BufferUtils; +import org.lwjgl.input.Mouse; + +final class WindowsDirectInputMouse { + private final static int BUFFER_SIZE = 50; + private final static int BUTTON_STATES_SIZE = 7; + + private final static int DIMOFS_X = 0; + private final static int DIMOFS_Y = 4; + private final static int DIMOFS_Z = 8; + private final static int DIMOFS_BUTTON0 = 12; + private final static int DIMOFS_BUTTON1 = 13; + private final static int DIMOFS_BUTTON2 = 14; + private final static int DIMOFS_BUTTON3 = 15; + + private final long hwnd; + private final WindowsDirectInput dinput; + private final WindowsDirectInputDevice mouse; + + private final int mouse_button_count; + private final boolean has_wheel; + + private final EventQueue event_queue = new EventQueue(Mouse.EVENT_SIZE); + /* Buffer to hold a DIMOUSESTATE */ + private final ByteBuffer mouse_state; + private final IntBuffer temp_data_buffer; + + private final ByteBuffer mouse_event = ByteBuffer.allocate(Mouse.EVENT_SIZE); + + private boolean mouse_grabbed; + private byte[] win32_message_button_states = new byte[BUTTON_STATES_SIZE]; + private int accum_dwheel; + private int last_x; + private int last_y; + + public WindowsDirectInputMouse(WindowsDirectInput dinput, long hwnd) throws LWJGLException { + this.hwnd = hwnd; + this.dinput = dinput; + try { + mouse = dinput.createDevice(WindowsDirectInput.MOUSE_TYPE); + try { + mouse.setDataFormat(WindowsDirectInput.MOUSE_TYPE); + mouse.setBufferSize(BUFFER_SIZE); + if (!acquireNonExclusive()) + throw new LWJGLException("Failed to acquire mouse non-exclusive"); + } catch (LWJGLException e) { + mouse.release(); + throw e; + } + } catch (LWJGLException e) { + dinput.release(); + throw e; + } + MouseEnumerator enumerator = new MouseEnumerator(); + mouse.enumObjects(enumerator); + this.mouse_button_count = Math.min(enumerator.getButtonCount(), 4); + this.has_wheel = enumerator.hasWheel(); + mouse_state = BufferUtils.createByteBuffer(3*4 + 4); + temp_data_buffer = BufferUtils.createIntBuffer(BUFFER_SIZE*WindowsDirectInputDevice.DATA_SIZE); + } + + public boolean hasWheel() { + return has_wheel; + } + + public int getButtonCount() { + return mouse_button_count; + } + + private boolean acquire(int flags) { + try { + mouse.setCooperateLevel(hwnd, flags); + mouse.acquire(); + return true; + } catch (LWJGLException e) { + LWJGLUtil.log("Failed to acquire mouse: " + e); + return false; + } + } + + private boolean acquireNonExclusive() { + return acquire(WindowsDirectInputDevice.DISCL_NONEXCLUSIVE | WindowsDirectInputDevice.DISCL_FOREGROUND) || + acquire(WindowsDirectInputDevice.DISCL_NONEXCLUSIVE | WindowsDirectInputDevice.DISCL_BACKGROUND); + } + + public void destroy() { + mouse.unacquire(); + mouse.release(); + dinput.release(); + } + + public void poll(IntBuffer coord_buffer, ByteBuffer buttons) { + int ret = mouse.acquire(); + if (ret != WindowsDirectInput.DI_OK && ret != WindowsDirectInput.DI_NOEFFECT) + return; + mouse.poll(); + for (int i = 0; i < coord_buffer.remaining(); i++) + coord_buffer.put(coord_buffer.position() + i, 0); + mouse_state.clear(); + ret = mouse.getDeviceState(mouse_state); + int mouse_state_lx = mouse_state.getInt(); + int mouse_state_ly = mouse_state.getInt(); + int mouse_state_lz = mouse_state.getInt(); + int num_buttons = mouse_button_count; + if (mouse_grabbed || ret == WindowsDirectInput.DI_OK) { + if (ret != WindowsDirectInput.DI_OK) { + LWJGLUtil.log("Error getting mouse state: (0x" + Integer.toHexString(ret) + ")"); + return; + } + + coord_buffer.put(coord_buffer.position() + 2, mouse_state_lz); + if (num_buttons > buttons.remaining()) + num_buttons = buttons.remaining(); + for (int j = 0; j < num_buttons; j++) { + byte button_state = (mouse_state.get() & 0x80) != 0 ? (byte)1 : (byte)0; + buttons.put(buttons.position() + j, button_state); + // track the button state in the windows message buffer state array + // to get accurate button information when releasing a grab + win32_message_button_states[j] = button_state; + } + } else { + coord_buffer.put(coord_buffer.position() + 2, accum_dwheel); + if (num_buttons > win32_message_button_states.length) + num_buttons = win32_message_button_states.length; + for (int j = 0; j < num_buttons; j++) { + buttons.put(buttons.position() + j, win32_message_button_states[j]); + } + } + accum_dwheel = 0; + if (mouse_grabbed) { + coord_buffer.put(coord_buffer.position() + 0, mouse_state_lx); + coord_buffer.put(coord_buffer.position() + 1, -mouse_state_ly); + } else { + coord_buffer.put(coord_buffer.position() + 0, last_x); + coord_buffer.put(coord_buffer.position() + 1, last_y); + } + } + + 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); + } + + private void putMouseEvent(byte button, byte state, int dz, long nanos) { + if (mouse_grabbed) + putMouseEventWithCoords(button, state, 0, 0, dz, nanos); + else + putMouseEventWithCoords(button, state, last_x, last_y, dz, nanos); + } + + private void copyDXEvents(IntBuffer buffer) { + int buffer_index = 0; + 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, nanos); + dx = dy = dwheel = 0; + break; + case DIMOFS_BUTTON1: + 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, nanos); + dx = dy = dwheel = 0; + break; + case DIMOFS_BUTTON3: + putMouseEventWithCoords((byte)3, button_state, dx, -dy, dwheel, nanos); + dx = dy = dwheel = 0; + break; + case DIMOFS_X: + dx += dwData; + break; + case DIMOFS_Y: + dy += dwData; + break; + case DIMOFS_Z: + dwheel += dwData; + break; + } + } + if (dx != 0 || dy != 0 || dwheel != 0) + putMouseEventWithCoords((byte)-1, (byte)0, dx, -dy, dwheel, nanos); + } + + private void readDXBuffer() { + int ret = mouse.acquire(); + if (ret != WindowsDirectInput.DI_OK && ret != WindowsDirectInput.DI_NOEFFECT) + return; + mouse.poll(); + temp_data_buffer.clear(); + ret = mouse.getDeviceData(temp_data_buffer); + + 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(); + mouse_grabbed = true; + mouse.unacquire(); + if (!acquire(WindowsDirectInputDevice.DISCL_EXCLUSIVE | WindowsDirectInputDevice.DISCL_FOREGROUND)) + LWJGLUtil.log("Failed to reset cooperative mode"); + } + } else { + if (mouse_grabbed) { + mouse_grabbed = false; + mouse.unacquire(); + acquireNonExclusive(); + } + } + event_queue.clearEvents(); + } + + public void handleMouseScrolled(int event_dwheel, long millis) { + accum_dwheel += event_dwheel; + putMouseEvent((byte)-1, (byte)0, event_dwheel, millis*1000000); + } + + 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, nanos); + } else { + putMouseEventWithCoords((byte)-1, (byte)0, x, y, 0, nanos); + } + } + + 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; + } + + private static class MouseEnumerator implements WindowsDirectInputDeviceObjectCallback { + private int button_count; + private boolean has_wheel; + + public int getButtonCount() { + return button_count; + } + + public boolean hasWheel() { + return has_wheel; + } + + public boolean nextObject(int type, String name) { + LWJGLUtil.log("Found mouse object: " + name); + switch (type) { + case WindowsDirectInputDevice.GUID_ZAxis: + has_wheel = true; + break; + case WindowsDirectInputDevice.GUID_Button: + button_count++; + break; + default: + break; + } + return true; + } + } +} Modified: trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsDisplay.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsDisplay.java 2007-04-23 20:50:44 UTC (rev 2798) +++ trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsDisplay.java 2007-04-24 09:30:03 UTC (rev 2799) @@ -44,6 +44,7 @@ import org.lwjgl.LWJGLException; import org.lwjgl.LWJGLUtil; +import org.lwjgl.BufferUtils; import org.lwjgl.input.Cursor; final class WindowsDisplay implements DisplayImplementation { @@ -85,7 +86,10 @@ private final static int SC_CONTEXTHELP = 0xF180; private final static int SC_SEPARATOR = 0xF00F; - private final static int SM_CXCURSOR = 13; + final static int SM_CXCURSOR = 13; + final static int SM_CYCURSOR = 14; + final static int SM_CMOUSEBUTTONS = 43; + final static int SM_MOUSEWHEELPRESENT = 75; private final static int SIZE_RESTORED = 0; private final static int SIZE_MINIMIZED = 1; @@ -99,9 +103,14 @@ private final static int SW_SHOWDEFAULT = 10; private final static int SW_RESTORE = 9; + private final static IntBuffer rect_buffer = BufferUtils.createIntBuffer(4); + private final static Rect rect = new Rect(); + private final static Rect rect2 = new Rect(); private static WindowsDisplay current_display; + private static boolean cursor_clipped; private WindowsDisplayPeerInfo peer_info; + private Object current_cursor; private WindowsKeyboard keyboard; private WindowsMouse mouse; @@ -141,13 +150,38 @@ public void destroyWindow() { nDestroyWindow(); - if (isFullscreen) - resetCursorClipping(); + resetCursorClipping(); } private static native void nDestroyWindow(); - static native void resetCursorClipping(); - static native void setupCursorClipping(long hwnd) throws LWJGLException; + static void resetCursorClipping() { + if (cursor_clipped) { + try { + clipCursor(0, null); + } catch (LWJGLException e) { + LWJGLUtil.log("Failed to reset cursor clipping: " + e); + } + cursor_clipped = false; + } + } + private static void getGlobalClientRect(long hwnd, Rect rect) { + rect_buffer.put(0, 0).put(1, 0); + clientToScreen(hwnd, rect_buffer); + int offset_x = rect_buffer.get(0); + int offset_y = rect_buffer.get(1); + getClientRect(hwnd, rect_buffer); + rect.copyFromBuffer(rect_buffer); + rect.offset(offset_x, offset_y); + } + + static void setupCursorClipping(long hwnd) throws LWJGLException { + cursor_clipped = true; + getGlobalClientRect(hwnd, rect); + rect.copyToBuffer(rect_buffer); + clipCursor(hwnd, rect_buffer); + } + private static native void clipCursor(long hwnd, IntBuffer rect) throws LWJGLException; + public void switchDisplayMode(DisplayMode mode) throws LWJGLException { nSwitchDisplayMode(mode); current_mode = mode; @@ -330,11 +364,12 @@ } public void createMouse() throws LWJGLException { - mouse = new WindowsMouse(createDirectInput(), getHwnd()); + mouse = new WindowsMouse(getHwnd()); } public void destroyMouse() { - mouse.destroy(); + if (mouse != null) + mouse.destroy(); mouse = null; } @@ -349,7 +384,12 @@ } public void grabMouse(boolean grab) { - mouse.grab(grab); + mouse.grab(grab, shouldGrab()); + try { + updateCursor(); + } catch (LWJGLException e) { + LWJGLUtil.log("Failed to update cursor: " + e); + } } public int getNativeCursorCapabilities() { @@ -357,12 +397,27 @@ } public void setCursorPosition(int x, int y) { - nSetCursorPosition(x, y, isFullscreen); + getGlobalClientRect(getHwnd(), rect); + int transformed_x = rect.left + x; + int transformed_y = rect.bottom - 1 - y; + nSetCursorPosition(transformed_x, transformed_y); + setMousePosition(x, y); } - private static native void nSetCursorPosition(int x, int y, boolean fullscreen); + private static native void nSetCursorPosition(int x, int y); - public native void setNativeCursor(Object handle) throws LWJGLException; + public void setNativeCursor(Object handle) throws LWJGLException { + current_cursor = handle; + updateCursor(); + } + private void updateCursor() throws LWJGLException { + if (mouse != null && mouse.isGrabbed()) + nSetNativeCursor(getHwnd(), mouse.getBlankCursor()); + else + nSetNativeCursor(getHwnd(), current_cursor); + } + static native void nSetNativeCursor(long hwnd, Object handle) throws LWJGLException; + public int getMinCursorSize() { return getSystemMetrics(SM_CXCURSOR); } @@ -371,11 +426,31 @@ return getSystemMetrics(SM_CXCURSOR); } - public native int getSystemMetrics(int index); + static native int getSystemMetrics(int index); private static native long getDllInstance(); private static native long getHwnd(); + private static native long getDesktopWindow(); + static void centerCursor(long hwnd) { + getGlobalClientRect(getHwnd(), rect); + int local_offset_x = rect.left; + int local_offset_y = rect.top; + getGlobalClientRect(getDesktopWindow(), rect2); + Rect.intersect(rect, rect2, rect); + int center_x = (rect.left + rect.right)/2; + int center_y = (rect.top + rect.bottom)/2; + nSetCursorPosition(center_x, center_y); + int local_x = center_x - local_offset_x; + int local_y = center_y - local_offset_y; + if (current_display != null) + current_display.setMousePosition(local_x, transformY(getHwnd(), local_y)); + } + private void setMousePosition(int x, int y) { + if (mouse != null) + mouse.setPosition(x, y); + } + /* Keyboard */ public void createKeyboard() throws LWJGLException { keyboard = new WindowsKeyboard(createDirectInput(), getHwnd()); @@ -398,13 +473,21 @@ // public native int isStateKeySet(int key); - public native ByteBuffer nCreateCursor(int width, int height, int xHotspot, int yHotspot, int numImages, IntBuffer images, int images_offset, IntBuffer delays, int delays_offset) throws LWJGLException; + public static native ByteBuffer nCreateCursor(int width, int height, int xHotspot, int yHotspot, int numImages, IntBuffer images, int images_offset, IntBuffer delays, int delays_offset) throws LWJGLException; public Object createCursor(int width, int height, int xHotspot, int yHotspot, int numImages, IntBuffer images, IntBuffer delays) throws LWJGLException { + return doCreateCursor(width, height, xHotspot, yHotspot, numImages, images, delays); + } + + static Object doCreateCursor(int width, int height, int xHotspot, int yHotspot, int numImages, IntBuffer images, IntBuffer delays) throws LWJGLException { return nCreateCursor(width, height, xHotspot, yHotspot, numImages, images, images.position(), delays, delays != null ? delays.position() : -1); } - public native void destroyCursor(Object cursorHandle); + public void destroyCursor(Object cursorHandle) { + doDestroyCursor(cursorHandle); + } + static native void doDestroyCursor(Object cursorHandle); + public int getPbufferCapabilities() { try { // Return the capabilities of a minimum pixel format @@ -483,9 +566,13 @@ mouse.handleMouseButton((byte)button, (byte)state, millis); } + private boolean shouldGrab() { + return !isMinimized && isFocused; + } + private void handleMouseMoved(int x, int y, long millis) { if (mouse != null) - mouse.handleMouseMoved(x, y, millis); + mouse.handleMouseMoved(x, y, millis, shouldGrab()); } private void handleMouseScrolled(int amount, long millis) { @@ -493,8 +580,16 @@ mouse.handleMouseScrolled(amount, millis); } - private static native int transformY(long hwnd, int y); + private static native void getClientRect(long hwnd, IntBuffer rect); + private static int transformY(long hwnd, int y) { + getClientRect(hwnd, rect_buffer); + rect.copyFromBuffer(rect_buffer); + return (rect.bottom - rect.top) - 1 - y; + } + + private static native void clientToScreen(long hwnd, IntBuffer point); + private static boolean handleMessage(long hwnd, int msg, long wParam, long lParam, long millis) { if (current_display != null) return current_display.doHandleMessage(hwnd, msg, wParam, lParam, millis); @@ -503,12 +598,14 @@ } private boolean doHandleMessage(long hwnd, int msg, long wParam, long lParam, long millis) { - if (isFullscreen && !isMinimized && isFocused) { + if ((isFullscreen || (mouse != null && mouse.isGrabbed())) && !isMinimized && isFocused) { try { setupCursorClipping(getHwnd()); } catch (LWJGLException e) { LWJGLUtil.log("setupCursorClipping failed: " + e.getMessage()); } + } else { + resetCursorClipping(); } switch (msg) { // disable screen saver and monitor power down messages which wreak havoc @@ -602,4 +699,40 @@ public int getHeight() { return Display.getDisplayMode().getHeight(); } + + private static final class Rect { + public int top; + public int bottom; + public int left; + public int right; + + public void copyToBuffer(IntBuffer buffer) { + buffer.put(0, top).put(1, bottom).put(2, left).put(3, right); + } + + public void copyFromBuffer(IntBuffer buffer) { + top = buffer.get(0); + bottom = buffer.get(1); + left = buffer.get(2); + right = buffer.get(3); + } + + public void offset(int offset_x, int offset_y) { + left += offset_x; + right += offset_x; + top += offset_y; + bottom += offset_y; + } + + public static void intersect(Rect r1, Rect r2, Rect dst) { + dst.top = Math.max(r1.top, r2.top); + dst.bottom = Math.min(r1.bottom, r2.bottom); + dst.left = Math.max(r1.left, r2.left); + dst.right = Math.min(r1.right, r2.right); + } + + public String toString() { + return "Rect: top = " + top + " bottom = " + bottom + " left = " + left + " right = " + right; + } + } } Modified: trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsMouse.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsMouse.java 2007-04-23 20:50:44 UTC (rev 2798) +++ trunk/LWJGL/src/java/org/lwjgl/opengl/WindowsMouse.java 2007-04-24 09:30:03 UTC (rev 2799) @@ -44,65 +44,46 @@ import org.lwjgl.LWJGLUtil; import org.lwjgl.BufferUtils; import org.lwjgl.input.Mouse; +import org.lwjgl.input.Cursor; final class WindowsMouse { - private final static int BUFFER_SIZE = 50; - private final static int BUTTON_STATES_SIZE = 7; - - private final static int DIMOFS_X = 0; - private final static int DIMOFS_Y = 4; - private final static int DIMOFS_Z = 8; - private final static int DIMOFS_BUTTON0 = 12; - private final static int DIMOFS_BUTTON1 = 13; - private final static int DIMOFS_BUTTON2 = 14; - private final static int DIMOFS_BUTTON3 = 15; - private final long hwnd; - private final WindowsDirectInput dinput; - private final WindowsDirectInputDevice mouse; private final int mouse_button_count; private final boolean has_wheel; private final EventQueue event_queue = new EventQueue(Mouse.EVENT_SIZE); - /* Buffer to hold a DIMOUSESTATE */ - private final ByteBuffer mouse_state; - private final IntBuffer temp_data_buffer; private final ByteBuffer mouse_event = ByteBuffer.allocate(Mouse.EVENT_SIZE); + private final Object blank_cursor; private boolean mouse_grabbed; - private byte[] win32_message_button_states = new byte[BUTTON_STATES_SIZE]; + private byte[] button_states; + private int accum_dx; + private int accum_dy; private int accum_dwheel; private int last_x; private int last_y; - public WindowsMouse(WindowsDirectInput dinput, long hwnd) throws LWJGLException { + public WindowsMouse(long hwnd) throws LWJGLException { this.hwnd = hwnd; - this.dinput = dinput; - try { - mouse = dinput.createDevice(WindowsDirectInput.MOUSE_TYPE); - try { - mouse.setDataFormat(WindowsDirectInput.MOUSE_TYPE); - mouse.setBufferSize(BUFFER_SIZE); - if (!acquireNonExclusive()) - throw new LWJGLException("Failed to acquire mouse non-exclusive"); - } catch (LWJGLException e) { - mouse.release(); - throw e; - } - } catch (LWJGLException e) { - dinput.release(); - throw e; - } - MouseEnumerator enumerator = new MouseEnumerator(); - mouse.enumObjects(enumerator); - this.mouse_button_count = Math.min(enumerator.getButtonCount(), 4); - this.has_wheel = enumerator.hasWheel(); - mouse_state = BufferUtils.createByteBuffer(3*4 + 4); - temp_data_buffer = BufferUtils.createIntBuffer(BUFFER_SIZE*WindowsDirectInputDevice.DATA_SIZE); + this.mouse_button_count = WindowsDisplay.getSystemMetrics(WindowsDisplay.SM_CMOUSEBUTTONS); + this.has_wheel = WindowsDisplay.getSystemMetrics(WindowsDisplay.SM_MOUSEWHEELPRESENT) != 0; + this.blank_cursor = createBlankCursor(); + this.button_states = new byte[mouse_button_count]; } + private Object createBlankCursor() throws LWJGLException { + int width = WindowsDisplay.getSystemMetrics(WindowsDisplay.SM_CXCURSOR); + int height = WindowsDisplay.getSystemMetrics(WindowsDisplay.SM_CYCURSOR); + IntBuffer pixels = BufferUtils.createIntBuffer(width*height); + return WindowsDisplay.doCreateCursor(width, height, 0, 0, 1, pixels, null); + } + + public boolean isGrabbed() { + return mouse_grabbed; + } + public boolean hasWheel() { return has_wheel; } @@ -111,73 +92,24 @@ return mouse_button_count; } - private boolean acquire(int flags) { - try { - mouse.setCooperateLevel(hwnd, flags); - mouse.acquire(); - return true; - } catch (LWJGLException e) { - LWJGLUtil.log("Failed to acquire mouse: " + e); - return false; - } - } - - private boolean acquireNonExclusive() { - return acquire(WindowsDirectInputDevice.DISCL_NONEXCLUSIVE | WindowsDirectInputDevice.DISCL_FOREGROUND) || - acquire(WindowsDirectInputDevice.DISCL_NONEXCLUSIVE | WindowsDirectInputDevice.DISCL_BACKGROUND); - } - - public void destroy() { - mouse.unacquire(); - mouse.release(); - dinput.release(); - } - public void poll(IntBuffer coord_buffer, ByteBuffer buttons) { - int ret = mouse.acquire(); - if (ret != WindowsDirectInput.DI_OK && ret != WindowsDirectInput.DI_NOEFFECT) - return; - mouse.poll(); for (int i = 0; i < coord_buffer.remaining(); i++) coord_buffer.put(coord_buffer.position() + i, 0); - mouse_state.clear(); - ret = mouse.getDeviceState(mouse_state); - int mouse_state_lx = mouse_state.getInt(); - int mouse_state_ly = mouse_state.getInt(); - int mouse_state_lz = mouse_state.getInt(); int num_buttons = mouse_button_count; - if (mouse_grabbed || ret == WindowsDirectInput.DI_OK) { - if (ret != WindowsDirectInput.DI_OK) { - LWJGLUtil.log("Error getting mouse state: (0x" + Integer.toHexString(ret) + ")"); - return; - } - - coord_buffer.put(coord_buffer.position() + 2, mouse_state_lz); - if (num_buttons > buttons.remaining()) - num_buttons = buttons.remaining(); - for (int j = 0; j < num_buttons; j++) { - byte button_state = (mouse_state.get() & 0x80) != 0 ? (byte)1 : (byte)0; - buttons.put(buttons.position() + j, button_state); - // track the button state in the windows message buffer state array - // to get accurate button information when releasing a grab - win32_message_button_states[j] = button_state; - } - } else { - coord_buffer.put(coord_buffer.position() + 2, accum_dwheel); - if (num_buttons > win32_message_button_states.length) - num_buttons = win32_message_button_states.length; - for (int j = 0; j < num_buttons; j++) { - buttons.put(buttons.position() + j, win32_message_button_states[j]); - } + coord_buffer.put(coord_buffer.position() + 2, accum_dwheel); + if (num_buttons > button_states.length) + num_buttons = button_states.length; + for (int j = 0; j < num_buttons; j++) { + buttons.put(buttons.position() + j, button_states[j]); } - accum_dwheel = 0; - if (mouse_grabbed) { - coord_buffer.put(coord_buffer.position() + 0, mouse_state_lx); - coord_buffer.put(coord_buffer.position() + 1, -mouse_state_ly); + if (isGrabbed()) { + coord_buffer.put(coord_buffer.position() + 0, accum_dx); + coord_buffer.put(coord_buffer.position() + 1, accum_dy); } else { coord_buffer.put(coord_buffer.position() + 0, last_x); coord_buffer.put(coord_buffer.position() + 1, last_y); } + accum_dx = accum_dy = accum_dwheel = 0; } private void putMouseEventWithCoords(byte button, byte state, int coord1, int coord2, int dz, long nanos) { @@ -194,104 +126,30 @@ putMouseEventWithCoords(button, state, last_x, last_y, dz, nanos); } - private void copyDXEvents(IntBuffer buffer) { - int buffer_index = 0; - 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, nanos); - dx = dy = dwheel = 0; - break; - case DIMOFS_BUTTON1: - 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, nanos); - dx = dy = dwheel = 0; - break; - case DIMOFS_BUTTON3: - putMouseEventWithCoords((byte)3, button_state, dx, -dy, dwheel, nanos); - dx = dy = dwheel = 0; - break; - case DIMOFS_X: - dx += dwData; - break; - case DIMOFS_Y: - dy += dwData; - break; - case DIMOFS_Z: - dwheel += dwData; - break; - } - } - if (dx != 0 || dy != 0 || dwheel != 0) - putMouseEventWithCoords((byte)-1, (byte)0, dx, -dy, dwheel, nanos); + public void read(ByteBuffer buffer) { + event_queue.copyEvents(buffer); } - private void readDXBuffer() { - int ret = mouse.acquire(); - if (ret != WindowsDirectInput.DI_OK && ret != WindowsDirectInput.DI_NOEFFECT) - return; - mouse.poll(); - temp_data_buffer.clear(); - ret = mouse.getDeviceData(temp_data_buffer); - - 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 Object getBlankCursor() { + return blank_cursor; } - 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) { + public void grab(boolean grab, boolean should_center) { + if (grab) { if (!mouse_grabbed) { - flush(); mouse_grabbed = true; - mouse.unacquire(); - if (!acquire(WindowsDirectInputDevice.DISCL_EXCLUSIVE | WindowsDirectInputDevice.DISCL_FOREGROUND)) - LWJGLUtil.log("Failed to reset cooperative mode"); + try { + WindowsDisplay.setupCursorClipping(hwnd); + } catch (LWJGLException e) { + LWJGLUtil.log("Failed to setup cursor clipping: " + e); + } + if (should_center) + centerCursor(); } } else { if (mouse_grabbed) { mouse_grabbed = false; - mouse.unacquire(); - acquireNonExclusive(); + WindowsDisplay.resetCursorClipping(); } } event_queue.clearEvents(); @@ -302,52 +160,41 @@ putMouseEvent((byte)-1, (byte)0, event_dwheel, millis*1000000); } - 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, nanos); - } else { - putMouseEventWithCoords((byte)-1, (byte)0, x, y, 0, nanos); - } + private void centerCursor() { + WindowsDisplay.centerCursor(hwnd); } - 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; + public void setPosition(int x, int y) { + this.last_x = x; + this.last_y = y; } - private static class MouseEnumerator implements WindowsDirectInputDeviceObjectCallback { - private int button_count; - private boolean has_wheel; + public void destroy() { + WindowsDisplay.doDestroyCursor(blank_cursor); + } - public int getButtonCount() { - return button_count; - } - - public boolean hasWheel() { - return has_wheel; - } - - public boolean nextObject(int type, String name) { - LWJGLUtil.log("Found mouse object: " + name); - switch (type) { - case WindowsDirectInputDevice.GUID_ZAxis: - has_wheel = true; - break; - case WindowsDirectInputDevice.GUID_Button: - button_count++; - break; - default: - break; + public void handleMouseMoved(int x, int y, long millis, boolean should_center) { + int dx = x - last_x; + int dy = y - last_y; + if (dx != 0 || dy != 0) { + accum_dx += dx; + accum_dy += dy; + last_x = x; + last_y = y; + long nanos = millis*1000000; + if (mouse_grabbed) { + putMouseEventWithCoords((byte)-1, (byte)0, dx, dy, 0, nanos); + if (should_center) + centerCursor(); + } else { + putMouseEventWithCoords((byte)-1, (byte)0, x, y, 0, nanos); } - return true; } } + + public void handleMouseButton(byte button, byte state, long millis) { + putMouseEvent(button, state, 0, millis*1000000); + if (button < button_states.length) + button_states[button] = state != 0 ? (byte)1 : (byte)0; + } } Modified: trunk/LWJGL/src/native/common/common_tools.c =================================================================== --- trunk/LWJGL/src/native/common/common_tools.c 2007-04-23 20:50:44 UTC (rev 2798) +++ trunk/LWJGL/src/native/common/common_tools.c 2007-04-24 09:30:03 UTC (rev 2799) @@ -141,6 +141,13 @@ throwGeneralException(env, "org/lwjgl/fmod3/FMODException", err); } +void throwFormattedRuntimeException(JNIEnv * env, const char *format, ...) { + va_list ap; + va_start(ap, format); + throwFormattedGeneralException(env, "java/lang/RuntimeException", format, ap); + va_end(ap); +} + void throwFormattedException(JNIEnv * env, const char *format, ...) { va_list ap; va_start(ap, format); Modified: trunk/LWJGL/src/native/common/common_tools.h =================================================================== --- trunk/LWJGL/src/native/common/common_tools.h 2007-04-23 20:50:44 UTC (rev 2798) +++ trunk/LWJGL/src/native/common/common_tools.h 2007-04-24 09:30:03 UTC (rev 2799) @@ -130,6 +130,7 @@ extern bool isDebugEnabled(void); extern jstring getVersionString(JNIEnv *env); extern void throwGeneralException(JNIEnv * env, const char *exception_name, const char * err); +extern void throwFormattedRuntimeException(JNIEnv * env, const char *format, ...); extern void throwException(JNIEnv *env, const char *msg); extern void throwFormattedException(JNIEnv * env, const char *format, ...); extern void throwFMODException(JNIEnv * env, const char * err); Modified: trunk/LWJGL/src/native/windows/org_lwjgl_input_Cursor.c =================================================================== --- trunk/LWJGL/src/native/windows/org_lwjgl_input_Cursor.c 2007-04-23 20:50:44 UTC (rev 2798) +++ trunk/LWJGL/src/native/windows/org_lwjgl_input_Cursor.c 2007-04-24 09:30:03 UTC (rev 2799) @@ -45,7 +45,7 @@ #include "common_tools.h" JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_WindowsDisplay_nCreateCursor -(JNIEnv *env, jobject self, jint width, jint height, jint x_hotspot, jint y_hotspot, jint num_images, jobject image_buffer, jint images_offset, jobject delay_buffer, jint delays_offset) +(JNIEnv *env, jclass unused, jint width, jint height, jint x_hotspot, jint y_hotspot, jint num_images, jobject image_buffer, jint images_offset, jobject delay_buffer, jint delays_offset) { unsigned char col0, col1, col2, col3, col4, col5, col6, col7; unsigned char mask; @@ -154,8 +154,8 @@ return handle_buffer; } -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_destroyCursor -(JNIEnv *env, jobject self, jobject handle_buffer) +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_doDestroyCursor +(JNIEnv *env, jclass unused, jobject handle_buffer) { HCURSOR *cursor_handle = (HCURSOR *)(*env)->GetDirectBufferAddress(env, handle_buffer); DestroyCursor(*cursor_handle); Modified: trunk/LWJGL/src/native/windows/org_lwjgl_opengl_Display.c =================================================================== --- trunk/LWJGL/src/native/windows/org_lwjgl_opengl_Display.c 2007-04-23 20:50:44 UTC (rev 2798) +++ trunk/LWJGL/src/native/windows/org_lwjgl_opengl_Display.c 2007-04-24 09:30:03 UTC (rev 2799) @@ -210,19 +210,65 @@ freeSmallIcon(); } -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_resetCursorClipping(JNIEnv *env, jclass unused) { - ClipCursor(NULL); +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_clientToScreen(JNIEnv *env, jclass unused, jlong hwnd_int, jobject buffer_handle) { + HWND hwnd = (HWND)(INT_PTR)hwnd_int; + POINT point; + jint *buffer = (jint *)(*env)->GetDirectBufferAddress(env, buffer_handle); + jlong size = (*env)->GetDirectBufferCapacity(env, buffer_handle); + if (size < 2) { + throwFormattedRuntimeException(env, "Buffer size < 2", size); + return; + } + point.x = buffer[0]; + point.y = buffer[1]; + ClientToScreen(hwnd, &point); + buffer[0] = point.x; + buffer[1] = point.y; } -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_setupCursorClipping(JNIEnv *env, jclass unused, jlong hwnd_ptr) { - HWND hwnd = (HWND)(INT_PTR)hwnd_ptr; - RECT hwnd_client; - if (hwnd != NULL && GetWindowRect(hwnd, &hwnd_client) != 0) { - if (ClipCursor(&hwnd_client) == 0) - throwFormattedException(env, "ClipCursor failed (%d)", GetLastError()); +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_WindowsDisplay_getDesktopWindow(JNIEnv *env, jclass unused) { + return (INT_PTR)GetDesktopWindow(); +} + +static void copyBufferToRect(JNIEnv *env, jobject buffer_handle, RECT *rect) { + jint *buffer = (jint *)(*env)->GetDirectBufferAddress(env, buffer_handle); + jlong size = (*env)->GetDirectBufferCapacity(env, buffer_handle); + if (size < 4) { + throwFormattedRuntimeException(env, "Buffer size < 4", size); + return; } + rect->top = buffer[0]; + rect->bottom = buffer[1]; + rect->left = buffer[2]; + rect->right = buffer[3]; } +static void copyRectToBuffer(JNIEnv *env, RECT *rect, jobject buffer_handle) { + jint *buffer = (jint *)(*env)->GetDirectBufferAddress(env, buffer_handle); + jlong size = (*env)->GetDirectBufferCapacity(env, buffer_handle); + if (size < 4) { + throwFormattedRuntimeException(env, "Buffer size < 4", size); + return; + } + buffer[0] = rect->top; + buffer[1] = rect->bottom; + buffer[2] = rect->left; + buffer[3] = rect->right; +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_clipCursor(JNIEnv *env, jclass unused, jlong hwnd_ptr, jobject handle_buffer) { + HWND hwnd = (HWND)(INT_PTR)hwnd_ptr; + RECT clip_rect; + LPRECT clip_rect_ptr; + if (handle_buffer != NULL) { + copyBufferToRect(env, handle_buffer, &clip_rect); + clip_rect_ptr = &clip_rect; + } else + clip_rect_ptr = NULL; + if (ClipCursor(clip_rect_ptr) == 0) + throwFormattedException(env, "ClipCursor failed (%d)", GetLastError()); +} + JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_nSwitchDisplayMode(JNIEnv *env, jobject self, jobject mode) { switchDisplayMode(env, mode); } @@ -452,64 +498,36 @@ } JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_nSetCursorPosition -(JNIEnv * env, jclass unused, jint x, jint y, jboolean fullscreen) { - DWORD windowflags, exstyle; - int transformed_x, transformed_y; - RECT window_rect; - RECT client_rect; - RECT adjusted_client_rect; - - int left_border_width; - int bottom_border_width; - - getWindowFlags(&windowflags, &exstyle, fullscreen, getBooleanProperty(env, "org.lwjgl.opengl.Window.undecorated")); - if (!GetClientRect(getCurrentHWND(), &client_rect)) { - printfDebugJava(env, "GetClientRect failed"); - return; - } - - adjusted_client_rect = client_rect; - if (!AdjustWindowRectEx(&adjusted_client_rect, windowflags, FALSE, exstyle)) { - printfDebugJava(env, "AdjustWindowRectEx failed"); - return; - } - - if (!GetWindowRect(getCurrentHWND(), &window_rect)) { - printfDebugJava(env, "GetWindowRect failed"); - return; - } - left_border_width = -adjusted_client_rect.left; - bottom_border_width = adjusted_client_rect.bottom - client_rect.bottom; - - transformed_x = window_rect.left + left_border_width + x; - transformed_y = window_rect.bottom - bottom_border_width - 1 - y; - if (!SetCursorPos(transformed_x, transformed_y)) +(JNIEnv * env, jclass unused, jint x, jint y) { + if (!SetCursorPos(x, y)) printfDebugJava(env, "SetCursorPos failed"); } -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_setNativeCursor - (JNIEnv *env, jobject self, jobject handle_buffer) +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_getClientRect + (JNIEnv *env, jclass unused, jlong hwnd_int, jobject rect_buffer) { + HWND hwnd = (HWND)(INT_PTR)hwnd_int; + RECT clientRect; + GetClientRect(hwnd, &clientRect); + copyRectToBuffer(env, &clientRect, rect_buffer); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDisplay_nSetNativeCursor + (JNIEnv *env, jclass unused, jlong hwnd_int, jobject handle_buffer) { + HWND hwnd = (HWND)(INT_PTR)hwnd_int; HCURSOR *cursor_handle; HCURSOR cursor; if (handle_buffer != NULL) { cursor_handle = (HCURSOR *)(*env)->GetDirectBufferAddress(env, handle_buffer); cursor = *cursor_handle; - SetClassLongPtr(getCurrentHWND(), GCL_HCURSOR, (LONG_PTR)cursor); + SetClassLongPtr(hwnd, GCL_HCURSOR, (LONG_PTR)cursor); SetCursor(cursor); } else { - SetClassLongPtr(getCurrentHWND(), GCL_HCURSOR, (LONG_PTR)NULL); + SetClassLongPtr(hwnd, GCL_HCURSOR, (LONG_PTR)NULL); SetCursor(LoadCursor(NULL, IDC_ARROW)); } } -JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDisplay_transformY(JNIEnv *env, jclass unused, jlong hwnd_int, jint y) { - HWND hwnd = (HWND)(INT_PTR)hwnd_int; - RECT clientRect; - GetClientRect(hwnd, &clientRect); - return (clientRect.bottom - clientRect.top) - 1 - y; -} - JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDisplay_getSystemMetrics(JNIEnv *env, jclass unused, jint index) { return GetSystemMetrics(index); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |