diff --git a/build.xml b/build.xml index c9263b78..1dcd46f3 100644 --- a/build.xml +++ b/build.xml @@ -420,6 +420,11 @@ + + + + + diff --git a/platform_build/win32_ms_cmdline/build.bat b/platform_build/win32_ms_cmdline/build.bat index 840b8f38..def3b9f0 100644 --- a/platform_build/win32_ms_cmdline/build.bat +++ b/platform_build/win32_ms_cmdline/build.bat @@ -9,7 +9,7 @@ if "%DXSDK_DIR%" == "" goto errordxhome set COPTIONS=/Wp64 /I"%CHOME%\include" /I"%PLTSDKHOME%\include" /I"%DXSDK_DIR%\include" /I"%JAVA_HOME%\include" /I"%JAVA_HOME%\include\win32" /I"%ALHOME%\include" /I"..\..\src\native\common" /Ox /Ob2 /Oi /Ot /Oy /FD /EHsc /MT /Gy /W2 /nologo /c /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "LWJGL_EXPORTS" /D "_WINDLL" set LINKEROPTS=/link /LIBPATH:"%JAVA_HOME%\lib" /LIBPATH:"%ALHOME%\libs" /LIBPATH:"%DXSDK_DIR%\Lib\x86" /LIBPATH:"%PLTSDKHOME%\Lib" /LIBPATH:"%CHOME%\Lib" /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /MACHINE:X86 /NOLOGO /DLL /DELAYLOAD:jawt.dll -set LIBS=Kernel32.lib dinput.lib dxguid.lib OpenGL32.Lib Version.lib user32.lib Gdi32.lib Advapi32.lib jawt.lib delayimp.lib winmm.lib +set LIBS=Kernel32.lib ole32.lib dinput.lib dxguid.lib OpenGL32.Lib Version.lib user32.lib Gdi32.lib Advapi32.lib jawt.lib delayimp.lib winmm.lib for %%x in (..\..\src\native\win32\*.c) do cl %COPTIONS% %%x for %%x in (..\..\src\native\common\*.c) do cl %COPTIONS% %%x diff --git a/src/java/org/lwjgl/BufferUtils.java b/src/java/org/lwjgl/BufferUtils.java index 8d75b1bb..e429613b 100644 --- a/src/java/org/lwjgl/BufferUtils.java +++ b/src/java/org/lwjgl/BufferUtils.java @@ -70,6 +70,16 @@ public final class BufferUtils { return createByteBuffer(size << 1).asShortBuffer(); } + /** + * Construct a direct native-order charbuffer with the specified number + * of elements. + * @param size The size, in chars + * @return an CharBuffer + */ + public static CharBuffer createCharBuffer(int size) { + return createByteBuffer(size << 1).asCharBuffer(); + } + /** * Construct a direct native-order intbuffer with the specified number * of elements. @@ -81,10 +91,10 @@ public final class BufferUtils { } /** - * Construct a direct native-order intbuffer with the specified number + * Construct a direct native-order longbuffer with the specified number * of elements. - * @param size The size, in ints - * @return an IntBuffer + * @param size The size, in longs + * @return an LongBuffer */ public static LongBuffer createLongBuffer(int size) { return createByteBuffer(size << 3).asLongBuffer(); diff --git a/src/java/org/lwjgl/input/Keyboard.java b/src/java/org/lwjgl/input/Keyboard.java index 55c18ea7..96f7b61e 100644 --- a/src/java/org/lwjgl/input/Keyboard.java +++ b/src/java/org/lwjgl/input/Keyboard.java @@ -348,7 +348,7 @@ public class Keyboard { private static void read() { readBuffer.compact(); - int numEvents = Display.getImplementation().readKeyboard(readBuffer, readBuffer.position()); + int numEvents = Display.getImplementation().readKeyboard(readBuffer); readBuffer.position(readBuffer.position() + numEvents*EVENT_SIZE); readBuffer.flip(); } diff --git a/src/java/org/lwjgl/input/Mouse.java b/src/java/org/lwjgl/input/Mouse.java index 612238af..af4e8c91 100644 --- a/src/java/org/lwjgl/input/Mouse.java +++ b/src/java/org/lwjgl/input/Mouse.java @@ -306,7 +306,7 @@ public class Mouse { private static void read() { readBuffer.compact(); - int numEvents = Display.getImplementation().readMouse(readBuffer, readBuffer.position()); + int numEvents = Display.getImplementation().readMouse(readBuffer); readBuffer.position(readBuffer.position() + numEvents * EVENT_SIZE); readBuffer.flip(); } diff --git a/src/java/org/lwjgl/opengl/DisplayImplementation.java b/src/java/org/lwjgl/opengl/DisplayImplementation.java index a9633ec1..9a17e1f3 100644 --- a/src/java/org/lwjgl/opengl/DisplayImplementation.java +++ b/src/java/org/lwjgl/opengl/DisplayImplementation.java @@ -153,8 +153,7 @@ public interface DisplayImplementation { * * @return the total number of events read. */ - int readMouse(IntBuffer buffer, int buffer_position); - + int readMouse(IntBuffer buffer); void grabMouse(boolean grab); @@ -201,7 +200,7 @@ public interface DisplayImplementation { * Method to read the keyboard buffer * @return the total number of events read. */ - int readKeyboard(IntBuffer buffer, int buffer_position); + int readKeyboard(IntBuffer buffer); // int isStateKeySet(int key); diff --git a/src/java/org/lwjgl/opengl/EventQueue.java b/src/java/org/lwjgl/opengl/EventQueue.java index bea0adaf..7a3c64d6 100644 --- a/src/java/org/lwjgl/opengl/EventQueue.java +++ b/src/java/org/lwjgl/opengl/EventQueue.java @@ -40,7 +40,7 @@ package org.lwjgl.opengl; import java.nio.ByteBuffer; import java.nio.IntBuffer; -abstract class EventQueue { +class EventQueue { private static final int QUEUE_SIZE = 200; diff --git a/src/java/org/lwjgl/opengl/LinuxDisplay.java b/src/java/org/lwjgl/opengl/LinuxDisplay.java index 213e3eae..6b180642 100644 --- a/src/java/org/lwjgl/opengl/LinuxDisplay.java +++ b/src/java/org/lwjgl/opengl/LinuxDisplay.java @@ -513,10 +513,10 @@ final class LinuxDisplay implements DisplayImplementation { } private static native void nPollMouse(IntBuffer coord_buffer, ByteBuffer buttons); - public int readMouse(IntBuffer buffer, int buffer_position) { + public int readMouse(IntBuffer buffer) { update(); lockAWT(); - int count = nReadMouse(buffer, buffer_position); + int count = nReadMouse(buffer, buffer.position()); unlockAWT(); return count; } @@ -616,10 +616,10 @@ final class LinuxDisplay implements DisplayImplementation { } private static native void nPollKeyboard(ByteBuffer keyDownBuffer); - public int readKeyboard(IntBuffer buffer, int buffer_position) { + public int readKeyboard(IntBuffer buffer) { update(); lockAWT(); - int count = nReadKeyboard(buffer, buffer_position); + int count = nReadKeyboard(buffer, buffer.position()); unlockAWT(); return count; } diff --git a/src/java/org/lwjgl/opengl/MacOSXDisplay.java b/src/java/org/lwjgl/opengl/MacOSXDisplay.java index 69790f0b..91847990 100644 --- a/src/java/org/lwjgl/opengl/MacOSXDisplay.java +++ b/src/java/org/lwjgl/opengl/MacOSXDisplay.java @@ -321,8 +321,7 @@ final class MacOSXDisplay implements DisplayImplementation { mouse_queue.poll(coord_buffer, buttons_buffer); } - public int readMouse(IntBuffer buffer, int buffer_position) { - assert buffer_position == buffer.position(); + public int readMouse(IntBuffer buffer) { return mouse_queue.copyEvents(buffer); } @@ -408,8 +407,7 @@ final class MacOSXDisplay implements DisplayImplementation { keyboard_queue.poll(keyDownBuffer); } - public int readKeyboard(IntBuffer buffer, int buffer_position) { - assert buffer_position == buffer.position(); + public int readKeyboard(IntBuffer buffer) { return keyboard_queue.copyEvents(buffer); } diff --git a/src/java/org/lwjgl/opengl/Win32Display.java b/src/java/org/lwjgl/opengl/Win32Display.java index b506b392..24a6b5ad 100644 --- a/src/java/org/lwjgl/opengl/Win32Display.java +++ b/src/java/org/lwjgl/opengl/Win32Display.java @@ -48,9 +48,23 @@ import org.lwjgl.input.Cursor; final class Win32Display implements DisplayImplementation { private final static int GAMMA_LENGTH = 256; + private final static int WM_MOUSEMOVE = 0x0200; + private final static int WM_LBUTTONDOWN = 0x0201; + private final static int WM_LBUTTONUP = 0x0202; + private final static int WM_LBUTTONDBLCLK = 0x0203; + private final static int WM_RBUTTONDOWN = 0x0204; + private final static int WM_RBUTTONUP = 0x0205; + private final static int WM_RBUTTONDBLCLK = 0x0206; + private final static int WM_MBUTTONDOWN = 0x0207; + private final static int WM_MBUTTONUP = 0x0208; + private final static int WM_MBUTTONDBLCLK = 0x0209; + private final static int WM_MOUSEWHEEL = 0x020A; private static Win32DisplayPeerInfo peer_info; + private static WindowsKeyboard keyboard; + private static WindowsMouse mouse; + public void createWindow(DisplayMode mode, boolean fullscreen, int x, int y) throws LWJGLException { nCreateWindow(mode, fullscreen, x, y); peer_info.initDC(); @@ -126,47 +140,70 @@ final class Win32Display implements DisplayImplementation { public native DisplayMode[] getAvailableDisplayModes() throws LWJGLException; /* Mouse */ - public native boolean hasWheel(); - public native int getButtonCount(); - public native void createMouse() throws LWJGLException; - public native void destroyMouse(); + public boolean hasWheel() { + return mouse.hasWheel(); + } + + public int getButtonCount() { + return mouse.getButtonCount(); + } + + public void createMouse() throws LWJGLException { + mouse = new WindowsMouse(createDirectInput(), getHwnd()); + } + + public void destroyMouse() { + mouse.destroy(); + mouse = null; + } + public void pollMouse(IntBuffer coord_buffer, ByteBuffer buttons) { update(); - nPollMouse(coord_buffer, buttons); + mouse.poll(coord_buffer, buttons); } - private native void nPollMouse(IntBuffer coord_buffer, ByteBuffer buttons); - public int readMouse(IntBuffer buffer, int buffer_position) { + public int readMouse(IntBuffer buffer) { update(); - return nReadMouse(buffer, buffer_position); + return mouse.read(buffer); } - private native int nReadMouse(IntBuffer buffer, int buffer_position); - public native void grabMouse(boolean grab); + public void grabMouse(boolean grab) { + mouse.grab(grab); + } + public int getNativeCursorCapabilities() { return Cursor.CURSOR_ONE_BIT_TRANSPARENCY; } public native void setCursorPosition(int x, int y); + public native void setNativeCursor(Object handle) throws LWJGLException; + public native int getMinCursorSize(); public native int getMaxCursorSize(); + private static native long getDllInstance(); + private static native long getHwnd(); + /* Keyboard */ - public native void createKeyboard() throws LWJGLException; - public native void destroyKeyboard(); + public void createKeyboard() throws LWJGLException { + keyboard = new WindowsKeyboard(createDirectInput(), getHwnd()); + } + + public void destroyKeyboard() { + keyboard.destroy(); + keyboard = null; + } public void pollKeyboard(ByteBuffer keyDownBuffer) { update(); - nPollKeyboard(keyDownBuffer); + keyboard.poll(keyDownBuffer); } - private native void nPollKeyboard(ByteBuffer keyDownBuffer); - public int readKeyboard(IntBuffer buffer, int buffer_position) { + public int readKeyboard(IntBuffer buffer) { update(); - return nReadKeyboard(buffer, buffer_position); + return keyboard.read(buffer); } - private native int nReadKeyboard(IntBuffer buffer, int buffer_position); // public native int isStateKeySet(int key); @@ -249,4 +286,64 @@ final class Win32Display implements DisplayImplementation { private static native int nSetWindowIcon16(IntBuffer icon); private static native int nSetWindowIcon32(IntBuffer icon); + + private static void handleMouseButton(int button, int state) { + if (mouse != null) + mouse.handleMouseButton(button, state); + } + + private static void handleMouseMoved(int x, int y) { + if (mouse != null) + mouse.handleMouseMoved(x, y); + } + + private static void handleMouseScrolled(int amount) { + if (mouse != null) + mouse.handleMouseScrolled(amount); + } + + private static native int transformY(long hwnd, int y); + + private static boolean handleMessage(long hwnd, int msg, long wParam, long lParam) { + switch (msg) { + case WM_MOUSEMOVE: + int xPos = (int)(short)(lParam & 0xFFFF); + int yPos = transformY(getHwnd(), (int)(short)((lParam >> 16) & 0xFFFF)); + handleMouseMoved(xPos, yPos); + return true; + case WM_MOUSEWHEEL: + int dwheel = (int)(short)((wParam >> 16) & 0xFFFF); + handleMouseScrolled(dwheel); + return true; + case WM_LBUTTONDOWN: + handleMouseButton(0, 1); + return true; + case WM_LBUTTONUP: + handleMouseButton(0, 0); + return true; + case WM_RBUTTONDOWN: + handleMouseButton(1, 1); + return true; + case WM_RBUTTONUP: + handleMouseButton(1, 0); + return true; + case WM_MBUTTONDOWN: + handleMouseButton(2, 1); + return true; + case WM_MBUTTONUP: + handleMouseButton(2, 0); + return true; + default: + return false; + } + } + + private static WindowsDirectInput createDirectInput() throws LWJGLException { + try { + return new WindowsDirectInput8(getDllInstance()); + } catch (LWJGLException e) { + LWJGLUtil.log("Failed to create DirectInput 8 interface, falling back to DirectInput 3"); + return new WindowsDirectInput3(getDllInstance()); + } + } } diff --git a/src/java/org/lwjgl/opengl/WindowsDirectInput.java b/src/java/org/lwjgl/opengl/WindowsDirectInput.java new file mode 100755 index 00000000..ee1e56f2 --- /dev/null +++ b/src/java/org/lwjgl/opengl/WindowsDirectInput.java @@ -0,0 +1,77 @@ +/* + * 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 DirectInput base class + * @author elias_naur + */ + +import org.lwjgl.LWJGLException; + +abstract class WindowsDirectInput { + public final static int KEYBOARD_TYPE = 1; + public final static int MOUSE_TYPE = 2; + + /* DirectInput constants */ + public final static int DI_OK = 0x00000000; + public final static int DI_NOEFFECT = 0x00000001; + public final static int DI_PROPNOEFFECT = 0x00000001; + + public final static int DI_DOWNLOADSKIPPED = 0x00000003; + public final static int DI_EFFECTRESTARTED = 0x00000004; + public final static int DI_TRUNCATED = 0x00000008; + public final static int DI_SETTINGSNOTSAVED = 0x0000000B; + public final static int DI_TRUNCATEDANDRESTARTED = 0x0000000C; + + public final static int DI_BUFFEROVERFLOW = 0x00000001; + public final static int DIERR_INPUTLOST = 0x8007001E; + public final static int DIERR_NOTACQUIRED = 0x8007001C; + public final static int DIERR_OTHERAPPHASPRIO = 0x80070005; + + private final long di_interface; + + public WindowsDirectInput(long hinst) throws LWJGLException { + di_interface = createDirectInput(hinst); + } + protected abstract long createDirectInput(long hinst) throws LWJGLException; + + public WindowsDirectInputDevice createDevice(int type) throws LWJGLException { + return createDevice(di_interface, type); + } + protected abstract WindowsDirectInputDevice createDevice(long di_interface, int type) throws LWJGLException; + + public void release() { + release(di_interface); + } + protected abstract void release(long di_interface); +} diff --git a/src/java/org/lwjgl/opengl/WindowsDirectInput3.java b/src/java/org/lwjgl/opengl/WindowsDirectInput3.java new file mode 100755 index 00000000..639e10bd --- /dev/null +++ b/src/java/org/lwjgl/opengl/WindowsDirectInput3.java @@ -0,0 +1,59 @@ +/* + * 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 DirectInput3 interface + * @author elias_naur + */ + +import org.lwjgl.LWJGLException; + +final class WindowsDirectInput3 extends WindowsDirectInput { + /* Re-define device types to get them included in the native headers */ + public final static int KEYBOARD_TYPE = WindowsDirectInput.KEYBOARD_TYPE; + public final static int MOUSE_TYPE = WindowsDirectInput.MOUSE_TYPE; + + public WindowsDirectInput3(long hinst) throws LWJGLException { + super(hinst); + } + + protected native long createDirectInput(long hinst) throws LWJGLException; + + protected WindowsDirectInputDevice createDevice(long di_interface, int type) throws LWJGLException { + long device = nCreateDevice(di_interface, type); + return new WindowsDirectInputDevice3(device); + } + private static native long nCreateDevice(long di_interface, int type) throws LWJGLException; + + protected native void release(long di_interface); +} diff --git a/src/java/org/lwjgl/opengl/WindowsDirectInput8.java b/src/java/org/lwjgl/opengl/WindowsDirectInput8.java new file mode 100755 index 00000000..09088c29 --- /dev/null +++ b/src/java/org/lwjgl/opengl/WindowsDirectInput8.java @@ -0,0 +1,59 @@ +/* + * 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 DirectInput8 interface + * @author elias_naur + */ + +import org.lwjgl.LWJGLException; + +final class WindowsDirectInput8 extends WindowsDirectInput { + /* Re-define device types to get them included in the native headers */ + public final static int KEYBOARD_TYPE = WindowsDirectInput.KEYBOARD_TYPE; + public final static int MOUSE_TYPE = WindowsDirectInput.MOUSE_TYPE; + + public WindowsDirectInput8(long hinst) throws LWJGLException { + super(hinst); + } + + protected native long createDirectInput(long hinst) throws LWJGLException; + + protected WindowsDirectInputDevice createDevice(long di_interface, int type) throws LWJGLException { + long device = nCreateDevice(di_interface, type); + return new WindowsDirectInputDevice8(device); + } + private static native long nCreateDevice(long di_interface, int type) throws LWJGLException; + + protected native void release(long di_interface); +} diff --git a/src/java/org/lwjgl/opengl/WindowsDirectInputDevice.java b/src/java/org/lwjgl/opengl/WindowsDirectInputDevice.java new file mode 100755 index 00000000..1e1ec464 --- /dev/null +++ b/src/java/org/lwjgl/opengl/WindowsDirectInputDevice.java @@ -0,0 +1,130 @@ +/* + * 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 DirectInputDevice interface + * @author elias_naur + */ + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; +import org.lwjgl.LWJGLException; +import org.lwjgl.BufferUtils; + +abstract class WindowsDirectInputDevice { + public final static int DISCL_EXCLUSIVE = 0x00000001; + public final static int DISCL_NONEXCLUSIVE = 0x00000002; + public final static int DISCL_FOREGROUND = 0x00000004; + public final static int DISCL_BACKGROUND = 0x00000008; + public final static int DISCL_NOWINKEY = 0x00000010; + + public final static int GUID_XAxis = 1; + public final static int GUID_YAxis = 2; + public final static int GUID_ZAxis = 3; + public final static int GUID_Button = 4; + public final static int GUID_Unknown = 5; + + private final long di_device; + private ByteBuffer event_buffer; + + public WindowsDirectInputDevice(long di_device) { + this.di_device = di_device; + } + + public void release() { + release(di_device); + } + protected abstract void release(long di_device); + + public int poll() { + return poll(di_device); + } + protected abstract int poll(long di_device); + + public void setDataFormat(int type) throws LWJGLException { + int ret = setDataFormat(di_device, type); + if (ret != WindowsDirectInput.DI_OK) + throw new LWJGLException("Failed to set data format (" + ret + ")"); + } + protected abstract int setDataFormat(long di_device, int type); + + public void setCooperateLevel(long hwnd, int flags) throws LWJGLException { + int ret = setCooperativeLevel(di_device, hwnd, flags); + if (ret != WindowsDirectInput.DI_OK) + throw new LWJGLException("Failed to set cooperative level (" + ret + ")"); + } + protected abstract int setCooperativeLevel(long di_device, long hwnd, int flags); + + public int acquire() { + return acquire(di_device); + } + protected abstract int acquire(long di_device); + + public void setBufferSize(int buffer_size) throws LWJGLException { + int ret = setBufferSize(di_device, buffer_size); + if (ret != WindowsDirectInput.DI_OK) + throw new LWJGLException("Failed to set buffer size (" + ret + ")"); + int event_buffer_size = getEventSize()*buffer_size; + event_buffer = BufferUtils.createByteBuffer(event_buffer_size); + } + protected abstract int setBufferSize(long di_device, int buffer_size); + + public int getDeviceData(IntBuffer buffer) { + int events_remaining = buffer.remaining()/2; + 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()); + } + protected abstract int getDeviceData(long di_device, ByteBuffer event_buffer, int event_buffer_size, IntBuffer buffer, int position, int size); + + /** + * Device data is returned in tuples of the form . + * buffer position() is moved accordingly to number of events. + */ + public int getDeviceState(ByteBuffer buffer) { + return getDeviceState(di_device, buffer, buffer.position(), buffer.remaining()); + } + protected abstract int getDeviceState(long di_device, ByteBuffer buffer, int position, int size); + + public void unacquire() { + unacquire(di_device); + } + protected abstract int unacquire(long di_device); + + public int enumObjects(WindowsDirectInputDeviceObjectCallback enumerator) { + return enumObjects(di_device, enumerator); + } + protected abstract int enumObjects(long di_device, WindowsDirectInputDeviceObjectCallback enumerator); + + protected abstract int getEventSize(); +} diff --git a/src/java/org/lwjgl/opengl/WindowsDirectInputDevice3.java b/src/java/org/lwjgl/opengl/WindowsDirectInputDevice3.java new file mode 100755 index 00000000..88d796be --- /dev/null +++ b/src/java/org/lwjgl/opengl/WindowsDirectInputDevice3.java @@ -0,0 +1,77 @@ +/* + * 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 DirectInputDevice3 interface + * @author elias_naur + */ + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; +import org.lwjgl.LWJGLException; + +final class WindowsDirectInputDevice3 extends WindowsDirectInputDevice { + /** Re-declare to get the constants into the native headers */ + public final static int GUID_XAxis = WindowsDirectInputDevice.GUID_XAxis; + public final static int GUID_YAxis = WindowsDirectInputDevice.GUID_YAxis; + public final static int GUID_ZAxis = WindowsDirectInputDevice.GUID_ZAxis; + public final static int GUID_Button = WindowsDirectInputDevice.GUID_Button; + public final static int GUID_Unknown = WindowsDirectInputDevice.GUID_Unknown; + + public WindowsDirectInputDevice3(long di_device) { + super(di_device); + } + + protected native int setDataFormat(long di_device, int type); + + protected native int setCooperativeLevel(long di_device, long hwnd, int flags); + + protected native int acquire(long di_device); + + protected native int getDeviceState(long di_device, ByteBuffer buffer, int position, int size); + + protected native int getDeviceData(long di_device, ByteBuffer event_buffer, int event_buffer_size, IntBuffer buffer, int position, int size); + + protected native int unacquire(long di_device); + + protected int poll(long di_device) { + return WindowsDirectInput.DI_OK; + } + + protected native int setBufferSize(long di_device, int buffer_size); + protected native int getEventSize(); + + protected native void release(long di_device); + + protected native int enumObjects(long di_device, WindowsDirectInputDeviceObjectCallback enumerator); +} diff --git a/src/java/org/lwjgl/opengl/WindowsDirectInputDevice8.java b/src/java/org/lwjgl/opengl/WindowsDirectInputDevice8.java new file mode 100755 index 00000000..92cafce3 --- /dev/null +++ b/src/java/org/lwjgl/opengl/WindowsDirectInputDevice8.java @@ -0,0 +1,75 @@ +/* + * 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 DirectInputDevice3 interface + * @author elias_naur + */ + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; +import org.lwjgl.LWJGLException; + +final class WindowsDirectInputDevice8 extends WindowsDirectInputDevice { + /** Re-declare to get the constants into the native headers */ + public final static int GUID_XAxis = WindowsDirectInputDevice.GUID_XAxis; + public final static int GUID_YAxis = WindowsDirectInputDevice.GUID_YAxis; + public final static int GUID_ZAxis = WindowsDirectInputDevice.GUID_ZAxis; + public final static int GUID_Button = WindowsDirectInputDevice.GUID_Button; + public final static int GUID_Unknown = WindowsDirectInputDevice.GUID_Unknown; + + public WindowsDirectInputDevice8(long di_device) { + super(di_device); + } + + protected native int setDataFormat(long di_device, int type); + + protected native int setCooperativeLevel(long di_device, long hwnd, int flags); + + protected native int acquire(long di_device); + + protected native int getDeviceState(long di_device, ByteBuffer buffer, int position, int size); + + protected native int getDeviceData(long di_device, ByteBuffer event_buffer, int event_buffer_size, IntBuffer buffer, int position, int size); + + protected native int unacquire(long di_device); + + protected native int poll(long di_device); + + protected native int setBufferSize(long di_device, int buffer_size); + protected native int getEventSize(); + + protected native void release(long di_device); + + protected native int enumObjects(long di_device, WindowsDirectInputDeviceObjectCallback enumerator); +} diff --git a/src/java/org/lwjgl/opengl/WindowsDirectInputDeviceObjectCallback.java b/src/java/org/lwjgl/opengl/WindowsDirectInputDeviceObjectCallback.java new file mode 100755 index 00000000..3608345b --- /dev/null +++ b/src/java/org/lwjgl/opengl/WindowsDirectInputDeviceObjectCallback.java @@ -0,0 +1,41 @@ +/* + * 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 DirectInputDevice callback interface + * @author elias_naur + */ + +interface WindowsDirectInputDeviceObjectCallback { + public boolean nextObject(int type, String name); +} diff --git a/src/java/org/lwjgl/opengl/WindowsKeyboard.java b/src/java/org/lwjgl/opengl/WindowsKeyboard.java new file mode 100644 index 00000000..eb069d8d --- /dev/null +++ b/src/java/org/lwjgl/opengl/WindowsKeyboard.java @@ -0,0 +1,178 @@ +/* + * 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 Keyboard. + * @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; + +final class WindowsKeyboard { + private final static int BUFFER_SIZE = 50; + + private final WindowsDirectInput dinput; + private final WindowsDirectInputDevice keyboard; + private final IntBuffer temp_data_buffer; + private final ByteBuffer keyboard_state; + private final CharBuffer unicode_buffer; + + public WindowsKeyboard(WindowsDirectInput dinput, long hwnd) throws LWJGLException { + 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); + } catch (LWJGLException e) { + keyboard.release(); + throw e; + } + } catch (LWJGLException e) { + dinput.release(); + throw e; + } + keyboard.acquire(); + temp_data_buffer = BufferUtils.createIntBuffer(BUFFER_SIZE*2); + keyboard_state = BufferUtils.createByteBuffer(256); + unicode_buffer = BufferUtils.createCharBuffer(BUFFER_SIZE); + } + + public void destroy() { + keyboard.unacquire(); + keyboard.release(); + dinput.release(); + } + + public void poll(ByteBuffer keyDownBuffer) { + int ret = keyboard.acquire(); + if (ret != WindowsDirectInput.DI_OK && ret != WindowsDirectInput.DI_NOEFFECT) + return; + keyboard.poll(); + ret = keyboard.getDeviceState(keyDownBuffer); + switch (ret) { + case WindowsDirectInput.DI_OK: + break; + case WindowsDirectInput.DI_BUFFEROVERFLOW: + LWJGLUtil.log("Keyboard buffer overflow"); + break; + case WindowsDirectInput.DIERR_INPUTLOST: + break; + case WindowsDirectInput.DIERR_NOTACQUIRED: + break; + default: + LWJGLUtil.log("Failed to poll keyboard (0x" + Integer.toHexString(ret) + ")"); + break; + } + } + + private int translateData(IntBuffer src, IntBuffer dst) { + int dst_index = dst.position(); + int num_events = 0; + while (dst_index < dst.limit() && src.hasRemaining()) { + num_events++; + int dwOfs = src.get(); + dst.put(dst_index++, dwOfs); + int dwData = src.get(); + dst.put(dst_index++, dwData); + boolean key_down = (dwData & 0x80) != 0; + if (key_down) { + int virt_key = MapVirtualKey(dwOfs, 1); + if (virt_key != 0 && GetKeyboardState(keyboard_state) != 0) { + // Mark key down in the scan code + dwOfs = dwOfs & 0x7fff; + unicode_buffer.clear(); + int num_chars = ToUnicode(virt_key, + dwOfs, + keyboard_state, + unicode_buffer, + unicode_buffer.capacity(), 0); + if (num_chars > 0) { + int current_char = 0; + do { + if (current_char >= 1) { + num_events++; + dst.put(dst_index++, 0); + dst.put(dst_index++, 0); + } + int char_int = ((int)unicode_buffer.get()) & 0xFFFF; + dst.put(dst_index++, char_int); + current_char++; + } while (dst_index < dst.limit() && current_char < num_chars); + } else { + dst.put(dst_index++, 0); + } + } else { + dst.put(dst_index++, 0); + } + } else + dst.put(dst_index++, 0); + } + return num_events; + } + private static native int MapVirtualKey(int uCode, int uMapType); + private static native int ToUnicode(int wVirtKey, int wScanCode, ByteBuffer lpKeyState, CharBuffer pwszBuff, int cchBuff, int flags); + private static native int GetKeyboardState(ByteBuffer lpKeyState); + + public int read(IntBuffer buffer) { + int ret = keyboard.acquire(); + if (ret != WindowsDirectInput.DI_OK && ret != WindowsDirectInput.DI_NOEFFECT) + return 0; + keyboard.poll(); + temp_data_buffer.clear(); + ret = keyboard.getDeviceData(temp_data_buffer); + switch (ret) { + case WindowsDirectInput.DI_OK: + break; + case WindowsDirectInput.DI_BUFFEROVERFLOW: + LWJGLUtil.log("Keyboard buffer overflow"); + break; + case WindowsDirectInput.DIERR_INPUTLOST: + break; + case WindowsDirectInput.DIERR_NOTACQUIRED: + break; + default: + LWJGLUtil.log("Failed to read keyboard (0x" + Integer.toHexString(ret) + ")"); + break; + } + temp_data_buffer.flip(); + return translateData(temp_data_buffer, buffer); + } +} diff --git a/src/java/org/lwjgl/opengl/WindowsMouse.java b/src/java/org/lwjgl/opengl/WindowsMouse.java new file mode 100755 index 00000000..9902a8cf --- /dev/null +++ b/src/java/org/lwjgl/opengl/WindowsMouse.java @@ -0,0 +1,341 @@ +/* + * 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; + +final class WindowsMouse { + private final static int BUFFER_SIZE = 50; + private final static int BUTTON_STATES_SIZE = 7; + private final static int MOUSE_EVENT_SIZE = 5; + + 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 int[] mouse_event = new int[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 WindowsMouse(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*2); + } + + 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 boolean putMouseEventWithCoords(int button, int state, int coord1, int coord2, int dz) { + mouse_event[0] = button; + mouse_event[1] = state; + mouse_event[2] = coord1; + mouse_event[3] = coord2; + mouse_event[4] = dz; + return event_queue.putEvent(mouse_event); + } + + private boolean putMouseEvent(int button, int state, int dz) { + if (mouse_grabbed) + return putMouseEventWithCoords(button, state, 0, 0, dz); + else + return putMouseEventWithCoords(button, state, last_x, last_y, dz); + } + + private void copyDXEvents(IntBuffer buffer) { + int buffer_index = 0; + int dx = 0, dy = 0, dwheel = 0; + int button_state; + int i; + while (buffer.hasRemaining()) { + int dwOfs = buffer.get(); + int dwData = buffer.get(); + button_state = (dwData & 0x80) != 0 ? 1 : 0; + switch (dwOfs) { + case DIMOFS_BUTTON0: + putMouseEventWithCoords(0, button_state, dx, -dy, dwheel); + dx = dy = dwheel = 0; + break; + case DIMOFS_BUTTON1: + putMouseEventWithCoords(1, button_state, dx, -dy, dwheel); + dx = dy = dwheel = 0; + break; + case DIMOFS_BUTTON2: + putMouseEventWithCoords(2, button_state, dx, -dy, dwheel); + dx = dy = dwheel = 0; + break; + case DIMOFS_BUTTON3: + putMouseEventWithCoords(3, button_state, dx, -dy, dwheel); + 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(-1, 0, dx, -dy, dwheel); + } + + 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); + + 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) + ")"); + } + } + + public int read(IntBuffer buffer) { + readDXBuffer(); + return event_queue.copyEvents(buffer); + } + + public void grab(boolean grab) { + if(grab) { + if (!mouse_grabbed) { + // flush DX event buffer + readDXBuffer(); + 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) { + accum_dwheel += event_dwheel; + putMouseEvent(-1, 0, event_dwheel); + } + + public void handleMouseMoved(int x, int y) { + int dx; + int dy; + dx = x - last_x; + dy = y - last_y; + last_x = x; + last_y = y; + if (mouse_grabbed) { + putMouseEventWithCoords(-1, 0, dx, dy, 0); + } else { + putMouseEventWithCoords(-1, 0, x, y, 0); + } + } + + public void handleMouseButton(int button, int state) { + putMouseEvent(button, state, 0); + 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; + } + } +} diff --git a/src/native/common/common_tools.c b/src/native/common/common_tools.c index 7b2355b9..6370dfd0 100644 --- a/src/native/common/common_tools.c +++ b/src/native/common/common_tools.c @@ -97,12 +97,16 @@ void printfDebugJava(JNIEnv *env, const char *format, ...) { jclass org_lwjgl_LWJGLUtil_class; jmethodID log_method; va_list ap; - if (isDebugEnabled()) { + if (isDebugEnabled() && !(*env)->ExceptionOccurred(env)) { va_start(ap, format); str = sprintfJavaString(env, format, ap); va_end(ap); org_lwjgl_LWJGLUtil_class = (*env)->FindClass(env, "org/lwjgl/LWJGLUtil"); + if (org_lwjgl_LWJGLUtil_class == NULL) + return; log_method = (*env)->GetStaticMethodID(env, org_lwjgl_LWJGLUtil_class, "log", "(Ljava/lang/String;)V"); + if (log_method == NULL) + return; (*env)->CallStaticVoidMethod(env, org_lwjgl_LWJGLUtil_class, log_method, str); } } diff --git a/src/native/common/common_tools.h b/src/native/common/common_tools.h index dff4bfdb..23e8dafc 100644 --- a/src/native/common/common_tools.h +++ b/src/native/common/common_tools.h @@ -68,7 +68,6 @@ typedef enum {false, true} bool; #ifdef _WIN32 #define inline __inline #include -typedef INT_PTR intptr_t; #else #include #endif diff --git a/src/native/win32/LWJGL.c b/src/native/win32/LWJGL.c index 491d2a7a..1b8f6188 100644 --- a/src/native/win32/LWJGL.c +++ b/src/native/win32/LWJGL.c @@ -42,6 +42,7 @@ #define WIN32_LEAN_AND_MEAN #include #include +#include HINSTANCE dll_handle; @@ -56,4 +57,8 @@ BOOL WINAPI DllMain( { dll_handle = hinstDLL; return TRUE; // Success -} \ No newline at end of file +} + +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_Win32Display_getDllInstance(JNIEnv *env, jclass unused) { + return (LONG_PTR)dll_handle; +} diff --git a/src/native/win32/Window.h b/src/native/win32/Window.h index 6efe1d6f..2a4d91ab 100644 --- a/src/native/win32/Window.h +++ b/src/native/win32/Window.h @@ -60,16 +60,5 @@ WINDOW_H_API HDC getCurrentHDC(); - WINDOW_H_API void handleMouseMoved(int x, int y); - - WINDOW_H_API void handleMouseScrolled(int dwheel); - - WINDOW_H_API void handleMouseButton(int button, int state); - WINDOW_H_API bool getCurrentFullscreen(); - /* - * Handle native Win32 messages - */ - WINDOW_H_API void handleMessage(JNIEnv * env, jobject obj); - #endif /* _LWJGL_WINDOW_H_INCLUDED_ */ diff --git a/src/native/win32/dinputhelper.c b/src/native/win32/dinputhelper.c new file mode 100644 index 00000000..e8b85f61 --- /dev/null +++ b/src/native/win32/dinputhelper.c @@ -0,0 +1,77 @@ +/* + * 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. + */ + +/** + * $Id: org_lwjgl_input_Keyboard.c 2385 2006-06-23 16:45:21Z elias_naur $ + * + * @author elias_naue + * @version $Revision: 2385 $ + */ + +#include "common_tools.h" +#include "dinputhelper.h" +#include + +HRESULT objectCallback(JNIEnv *env, jobject enumerator, jint object_type, const char *tszName) { + jstring name; + jclass enum_class; + jmethodID nextObject_method; + jboolean should_continue; + + name = NewStringNative(env, tszName); + if (name == NULL) + return false; + enum_class = (*env)->GetObjectClass(env, enumerator); + if (enum_class == NULL) + return false; + nextObject_method = (*env)->GetMethodID(env, enum_class, "nextObject", "(ILjava/lang/String;)Z"); + if (nextObject_method == NULL) + return false; + should_continue = (*env)->CallBooleanMethod(env, enumerator, nextObject_method, object_type, name); + (*env)->DeleteLocalRef(env, name); + return should_continue == JNI_TRUE ? true : false; +} + +bool positionBuffer(JNIEnv *env, jobject buffer, jint position) { + jclass buffer_class; + jmethodID position_method; + + buffer_class = (*env)->GetObjectClass(env, buffer); + if (buffer_class == NULL) + return false; + position_method = (*env)->GetMethodID(env, buffer_class, "position", "(I)Ljava/nio/Buffer;"); + if (position_method == NULL) + return false; + (*env)->CallObjectMethod(env, buffer, position_method, position); + return true; +} + diff --git a/src/native/win32/dinputhelper.h b/src/native/win32/dinputhelper.h new file mode 100755 index 00000000..e544f65d --- /dev/null +++ b/src/native/win32/dinputhelper.h @@ -0,0 +1,54 @@ +/* + * 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. + */ + +/** + * $Id: context.c 2370 2006-06-15 15:03:29Z elias_naur $ + * + * @author elias_naur + * @version $Revision: 2370 $ + */ + +#ifndef __DIRECTINPUT_HELPER_H +#define __DIRECTINPUT_HELPER_H + +#include +#include + +typedef struct { + JNIEnv *env; + jobject enumerator; +} enum_context_t; + +HRESULT objectCallback(JNIEnv *env, jobject enumerator, jint object_type, const char *tszName); +bool positionBuffer(JNIEnv *env, jobject buffer, jint position); + +#endif diff --git a/src/native/win32/org_lwjgl_input_Keyboard.c b/src/native/win32/org_lwjgl_input_Keyboard.c deleted file mode 100644 index 060922b5..00000000 --- a/src/native/win32/org_lwjgl_input_Keyboard.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * 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. - */ - -/** - * $Id$ - * - * Win32 keyboard handling. - * - * @author cix_foo - * @version $Revision$ - */ - -#undef DIRECTINPUT_VERSION -#define DIRECTINPUT_VERSION 0x0300 -#include "Window.h" -#include -#include "org_lwjgl_opengl_Win32Display.h" -#include "org_lwjgl_input_Keyboard.h" - -#include "common_tools.h" - -#define KEYBOARD_BUFFER_SIZE 50 - -extern HINSTANCE dll_handle; // Handle to the LWJGL dll - -static LPDIRECTINPUT lpdi = NULL; // DirectInput -static LPDIRECTINPUTDEVICE lpdiKeyboard = NULL; - -static bool useUnicode; - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_createKeyboard - (JNIEnv * env, jobject self) -{ - OSVERSIONINFO osvi; - DIPROPDWORD dipropdw; - // Create input - HRESULT ret = DirectInputCreate(dll_handle, DIRECTINPUT_VERSION, &lpdi, NULL); - if (ret != DI_OK && ret != DIERR_BETADIRECTINPUTVERSION) { - throwException(env, "Failed to create DirectInput"); - return; - } - - // Create a keyboard device - if (IDirectInput_CreateDevice(lpdi, &GUID_SysKeyboard, &lpdiKeyboard, NULL) != DI_OK) { - throwException(env, "Failed to create keyboard."); - return; - } - - if (IDirectInputDevice_SetCooperativeLevel(lpdiKeyboard, getCurrentHWND(), DISCL_NONEXCLUSIVE | DISCL_FOREGROUND) != DI_OK) { - throwException(env, "Failed to set keyboard cooperation mode."); - return; - } - - // Tell 'em wot format to be in (the default "you are a mouse and keyboard" format) - IDirectInputDevice_SetDataFormat(lpdiKeyboard, &c_dfDIKeyboard); - - dipropdw.diph.dwSize = sizeof(DIPROPDWORD); - dipropdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); - dipropdw.diph.dwObj = 0; - dipropdw.diph.dwHow = DIPH_DEVICE; - dipropdw.dwData = KEYBOARD_BUFFER_SIZE; - IDirectInputDevice_SetProperty(lpdiKeyboard, DIPROP_BUFFERSIZE, &dipropdw.diph); - - ret = IDirectInputDevice_Acquire(lpdiKeyboard); - if(FAILED(ret)) { - printfDebugJava(env, "Failed to acquire keyboard"); - } - osvi.dwOSVersionInfoSize = sizeof(osvi); - GetVersionEx(&osvi); - - if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) { - useUnicode = true; - } else { - useUnicode = false; - } -} - -/* - * Class: org_lwjgl_input_Keyboard - * Method: nDestroy - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_destroyKeyboard - (JNIEnv * env, jobject self) -{ - // Release keyboard - if (lpdiKeyboard != NULL) { - IDirectInputDevice_Unacquire(lpdiKeyboard); - IDirectInputDevice_Release(lpdiKeyboard); - lpdiKeyboard = NULL; - } - // Release DirectInput - if (lpdi != NULL) { - printfDebugJava(env, "Destroying directinput"); - IDirectInput_Release(lpdi); - lpdi = NULL; - } -} - -/* - * Class: org_lwjgl_input_Keyboard - * Method: nPoll - * Signature: (I)V - */ -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_nPollKeyboard - (JNIEnv * env, jobject self, jobject buffer) -{ - void *keyboardBuffer; - jlong buffer_size; - HRESULT ret = IDirectInputDevice_Acquire(lpdiKeyboard); - if (ret != DI_OK && ret != S_FALSE) { -// printfDebugJava(env, "Failed to acquire keyboard (%x)\n", ret); - return; - } - - keyboardBuffer = (void *)(*env)->GetDirectBufferAddress(env, buffer); - buffer_size = (*env)->GetDirectBufferCapacity(env, buffer); - IDirectInputDevice_GetDeviceState(lpdiKeyboard, (DWORD)buffer_size, keyboardBuffer); -} - -JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Win32Display_nReadKeyboard - (JNIEnv * env, jobject self, jobject buffer_obj, jint buffer_position) -{ - UINT scan_code; - UINT virt_key; - bool key_down; - jint * buf; - jint ch_int; - int buffer_size; - int index = 0; - int event_size = 3; - DWORD current_di_event = 0; - DIDEVICEOBJECTDATA rgdod[KEYBOARD_BUFFER_SIZE]; - wchar_t transBufUnicode[KEYBOARD_BUFFER_SIZE]; - WORD transBufAscii[KEYBOARD_BUFFER_SIZE]; - - BYTE state[256]; - DWORD num_di_events = KEYBOARD_BUFFER_SIZE; - - HRESULT ret; - int num_chars; - int num_events = 0; - - ret = IDirectInputDevice_Acquire(lpdiKeyboard); - if (ret != DI_OK && ret != S_FALSE) - return 0; - - ret = IDirectInputDevice_GetDeviceData(lpdiKeyboard, - sizeof(DIDEVICEOBJECTDATA), - rgdod, - &num_di_events, - 0); - - if (ret == DI_OK) { - buf = buffer_position + (jint *)(*env)->GetDirectBufferAddress(env, buffer_obj); - buffer_size = ((int)(*env)->GetDirectBufferCapacity(env, buffer_obj))/sizeof(jint) - buffer_position; - while (index + event_size <= buffer_size && current_di_event < num_di_events) { - num_events++; - buf[index++] = (unsigned char) rgdod[current_di_event].dwOfs; - buf[index++] = (unsigned char) rgdod[current_di_event].dwData; - key_down = (rgdod[current_di_event].dwData & 0x80) != 0; - if (key_down) { - scan_code = rgdod[current_di_event].dwOfs; - virt_key = MapVirtualKey(scan_code, 1); - if (virt_key != 0 && GetKeyboardState(state)) { - // Mark key down in the scan code - scan_code = scan_code & 0x7fff; - if (useUnicode) { - num_chars = ToUnicode(virt_key, - scan_code, - state, - transBufUnicode, - KEYBOARD_BUFFER_SIZE, 0); - } else { - num_chars = ToAscii(virt_key, - scan_code, - state, - transBufAscii, - 0); - } - if (num_chars > 0) { - int current_char = 0; - do { - if (current_char >= 1) { - num_events++; - buf[index++] = 0; - buf[index++] = 0; - } - if (useUnicode) { - wchar_t ch = transBufUnicode[current_char]; - ch_int = ((int)ch) & 0xFFFF; - } else { - unsigned char ch = (unsigned char)transBufAscii[current_char]; - ch_int = ((int)ch) & 0xFF; - } - buf[index++] = ch_int; - current_char++; - } while (index + event_size <= buffer_size && current_char < num_chars); - } else { - buf[index++] = 0; - } - } else { - buf[index++] = 0; - } - } else - buf[index++] = 0; - current_di_event++; - } - } else if (ret == DI_BUFFEROVERFLOW) { - printfDebugJava(env, "Keyboard buffer overflowed"); - } else if (ret == DIERR_INPUTLOST) { - printfDebugJava(env, "Input lost"); - } else if (ret == DIERR_NOTACQUIRED) { - printfDebugJava(env, "not acquired"); - } else if (ret == DIERR_INVALIDPARAM) { - printfDebugJava(env, "invalid parameter"); - } else if (ret == DIERR_NOTBUFFERED) { - printfDebugJava(env, "not buffered"); - } else if (ret == DIERR_NOTINITIALIZED) { - printfDebugJava(env, "not inited"); - } else { - printfDebugJava(env, "unknown keyboard error"); - } - return num_events; -} - -/*JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Win32Display_isStateKeySet(JNIEnv *env, jobject self, jint key) -{ - int state = org_lwjgl_input_Keyboard_STATE_UNKNOWN; - switch(key) { - case org_lwjgl_input_Keyboard_KEY_CAPITAL: - state = GetKeyState(VK_CAPITAL) ? org_lwjgl_input_Keyboard_STATE_ON : org_lwjgl_input_Keyboard_STATE_OFF; - break; - case org_lwjgl_input_Keyboard_KEY_NUMLOCK: - state = GetKeyState(VK_NUMLOCK) ? org_lwjgl_input_Keyboard_STATE_ON : org_lwjgl_input_Keyboard_STATE_OFF; - break; - case org_lwjgl_input_Keyboard_KEY_SCROLL: - state = GetKeyState(VK_SCROLL) ? org_lwjgl_input_Keyboard_STATE_ON : org_lwjgl_input_Keyboard_STATE_OFF; - break; - } - - return state; -}*/ diff --git a/src/native/win32/org_lwjgl_input_Mouse.c b/src/native/win32/org_lwjgl_input_Mouse.c deleted file mode 100644 index 4cbbc44c..00000000 --- a/src/native/win32/org_lwjgl_input_Mouse.c +++ /dev/null @@ -1,523 +0,0 @@ -/* - * 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. - */ - -/** - * $Id$ - * - * Win32 mouse handling. - * - * @author Brian Matzon - * @version $Revision$ - */ - -#undef DIRECTINPUT_VERSION -#define DIRECTINPUT_VERSION 0x0300 -#include "Window.h" -#include -#include "common_tools.h" -#include "org_lwjgl_opengl_Win32Display.h" -#include "org_lwjgl_input_Mouse.h" - -#define EVENT_SIZE 5 - -#define BUTTON_STATES_SIZE 7 - -extern HINSTANCE dll_handle; // Handle to the LWJGL dll -static LPDIRECTINPUT lpdi = NULL; // DirectInput -static LPDIRECTINPUTDEVICE mDIDevice; // DI Device instance -static int mButtoncount = 0; // Temporary buttoncount -static bool mHaswheel; // Temporary wheel check - -static bool mFirstTimeInitialization = true; // boolean to determine first time initialization -static bool created = false; - -static jboolean win32_message_button_states[BUTTON_STATES_SIZE]; - -static bool mouse_grabbed; - -/* These accumulated deltas track the cursor position from Windows messages */ -static int accum_dwheel; -static int last_x; -static int last_y; - -static event_queue_t event_queue; - -// Function prototypes (defined in the cpp file, since header file is generic across platforms -BOOL CALLBACK EnumMouseObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef); -void ShutdownMouse(JNIEnv *env); -void InitializeMouseFields(); -void UpdateMouseFields(JNIEnv *env, jobject coord_buffer_obj, jobject button_buffer_obj); - -static int transformY(int y) { - RECT clientRect; - GetClientRect(getCurrentHWND(), &clientRect); - return (clientRect.bottom - clientRect.top) - 1 - y; -} - -static bool putMouseEventWithCoords(jint button, jint state, jint coord1, jint coord2, jint dz) { - jint event[] = {button, state, coord1, coord2, dz}; - return putEvent(&event_queue, event); -} - -static bool putMouseEvent(jint button, jint state, jint dz) { - if (mouse_grabbed) - return putMouseEventWithCoords(button, state, 0, 0, dz); - else - return putMouseEventWithCoords(button, state, last_x, last_y, dz); -} - -JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_Win32Display_hasWheel(JNIEnv *env, jobject self) { - return mHaswheel; -} - -JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Win32Display_getButtonCount(JNIEnv *env, jobject self) { - return mButtoncount; -} - -/** - * Enumerates the capabilities of the Mouse attached to the system - */ -static bool EnumerateMouseCapabilities(JNIEnv *env) { - HRESULT hr; - hr = IDirectInputDevice_EnumObjects(mDIDevice, EnumMouseObjectsCallback, NULL, DIDFT_ALL); - if FAILED(hr) { - throwException(env, "EnumObjects failed"); - return false; - } - - //check for > 4 buttons - need to clamp since we're using dx 5 - if(mButtoncount > 4) { - mButtoncount = 4; - printfDebugJava(env, "WARNING: Clamping to 4 mouse buttons\n"); - } - return true; -} - -/** - * Creates the specified device as a Mouse - */ -static bool CreateMouse(JNIEnv *env) { - HRESULT hr; - hr = IDirectInput_CreateDevice(lpdi, &GUID_SysMouse, &mDIDevice, NULL); - if FAILED(hr) { - throwException(env, "CreateDevice failed"); - return false; - } else - return true; -} - -static bool acquireMouse(DWORD flags) { - if (IDirectInputDevice_SetCooperativeLevel(mDIDevice, getCurrentHWND(), flags) == DI_OK) { - IDirectInputDevice_Acquire(mDIDevice); - return true; - } else - return false; -} - -static bool acquireMouseNonExclusive() { - return acquireMouse(DISCL_NONEXCLUSIVE | DISCL_FOREGROUND) || acquireMouse(DISCL_NONEXCLUSIVE | DISCL_BACKGROUND); -} - -/** - * Sets up the Mouse properties - */ -static bool SetupMouse(JNIEnv *env) { - DIPROPDWORD dipropdw; - // set Mouse data format - if(IDirectInputDevice_SetDataFormat(mDIDevice, &c_dfDIMouse) != DI_OK) { - throwException(env, "SetDataFormat failed"); - return false; - } - - dipropdw.diph.dwSize = sizeof(DIPROPDWORD); - dipropdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); - dipropdw.diph.dwObj = 0; - dipropdw.diph.dwHow = DIPH_DEVICE; - dipropdw.dwData = EVENT_BUFFER_SIZE; - IDirectInputDevice_SetProperty(mDIDevice, DIPROP_BUFFERSIZE, &dipropdw.diph); - - // set the cooperative level - if (!acquireMouseNonExclusive()) { - printfDebugJava(env, "SetCooperativeLevel failed"); - return false; - } - return true; -} - -/** - * Called when the Mouse instance is to be created - */ -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_createMouse(JNIEnv *env, jobject self) { - HRESULT ret; - - initEventQueue(&event_queue, EVENT_SIZE); - - last_x = last_y = accum_dwheel = 0; - mouse_grabbed = false; - - // Create input - ret = DirectInputCreate(dll_handle, DIRECTINPUT_VERSION, &lpdi, NULL); - if (ret != DI_OK && ret != DIERR_BETADIRECTINPUTVERSION) { - throwException(env, "Failed to create DirectInput"); - return; - } - - /* skip enumeration, since we only want system mouse */ - if (!CreateMouse(env)) - return; - - //check for first time initialization - need to detect capabilities - if (mFirstTimeInitialization) { - /* Enumerate capabilities of Mouse */ - if (!EnumerateMouseCapabilities(env)) { - ShutdownMouse(env); - return; - } - mFirstTimeInitialization = false; - } - /* Do setup of Mouse */ - if (!SetupMouse(env)) { - ShutdownMouse(env); - return; - } - created = true; -} - -void handleMouseScrolled(int event_dwheel) { - if(created) { - accum_dwheel += event_dwheel; - putMouseEvent(-1, 0, event_dwheel); - } -} - -void handleMouseMoved(int x, int y) { - int dx; - int dy; - if(created) { - y = transformY(y); - dx = x - last_x; - dy = y - last_y; - last_x = x; - last_y = y; - if (mouse_grabbed) { - putMouseEventWithCoords(-1, 0, dx, dy, 0); - } else { - putMouseEventWithCoords(-1, 0, x, y, 0); - } - } -} - -void handleMouseButton(int button, int state) { - if(created) { - putMouseEvent(button, state, 0); - if (button < BUTTON_STATES_SIZE) - win32_message_button_states[button] = state != 0 ? JNI_TRUE: JNI_FALSE; - } -} - -static void copyDXEvents(int num_di_events, DIDEVICEOBJECTDATA *di_buffer) { - int buffer_index = 0; - int dx = 0, dy = 0, dwheel = 0; - int button_state; - int i; - for (i = 0; i < num_di_events; i++) { - button_state = (di_buffer[i].dwData & 0x80) != 0 ? 1 : 0; - switch (di_buffer[i].dwOfs) { - case DIMOFS_BUTTON0: - putMouseEventWithCoords(0, button_state, dx, -dy, dwheel); - dx = dy = dwheel = 0; - break; - case DIMOFS_BUTTON1: - putMouseEventWithCoords(1, button_state, dx, -dy, dwheel); - dx = dy = dwheel = 0; - break; - case DIMOFS_BUTTON2: - putMouseEventWithCoords(2, button_state, dx, -dy, dwheel); - dx = dy = dwheel = 0; - break; - case DIMOFS_BUTTON3: - putMouseEventWithCoords(3, button_state, dx, -dy, dwheel); - dx = dy = dwheel = 0; - break; - case DIMOFS_X: - dx += di_buffer[i].dwData; - break; - case DIMOFS_Y: - dy += di_buffer[i].dwData; - break; - case DIMOFS_Z: - dwheel += di_buffer[i].dwData; - break; - } - } - if (dx != 0 || dy != 0 || dwheel != 0) - putMouseEventWithCoords(-1, 0, dx, -dy, dwheel); -} - -static void readDXBuffer(JNIEnv *env) { - DIDEVICEOBJECTDATA rgdod[EVENT_BUFFER_SIZE]; - DWORD num_di_events = EVENT_BUFFER_SIZE; - - HRESULT ret; - - ret = IDirectInputDevice_Acquire(mDIDevice); - if (ret != DI_OK && ret != S_FALSE) - return; - - ret = IDirectInputDevice_GetDeviceData(mDIDevice, - sizeof(DIDEVICEOBJECTDATA), - rgdod, - &num_di_events, - 0); - - if (ret == DI_OK) { - if (mouse_grabbed) - copyDXEvents(num_di_events, rgdod); - } else if (ret == DI_BUFFEROVERFLOW) { - printfDebugJava(env, "Buffer overflowed"); - } else if (ret == DIERR_INPUTLOST) { - printfDebugJava(env, "Input lost"); - } else if (ret == DIERR_NOTACQUIRED) { - printfDebugJava(env, "not acquired"); - } else if (ret == DIERR_INVALIDPARAM) { - printfDebugJava(env, "invalid parameter"); - } else if (ret == DIERR_NOTBUFFERED) { - printfDebugJava(env, "not buffered"); - } else if (ret == DIERR_NOTINITIALIZED) { - printfDebugJava(env, "not inited"); - } else { - printfDebugJava(env, "unknown mouse error (%d)", ret); - } -} - -JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Win32Display_nReadMouse - (JNIEnv * env, jobject self, jobject buffer_obj, jint buffer_position) -{ - jint* buffer_ptr = (jint *)(*env)->GetDirectBufferAddress(env, buffer_obj) + buffer_position; - int buffer_size = ((*env)->GetDirectBufferCapacity(env, buffer_obj))/sizeof(jint) - buffer_position; - readDXBuffer(env); - return copyEvents(&event_queue, buffer_ptr, buffer_size); -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_setNativeCursor - (JNIEnv *env, jobject self, jobject handle_buffer) -{ - 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); - SetCursor(cursor); - } else { - SetClassLongPtr(getCurrentHWND(), GCL_HCURSOR, (LONG_PTR)NULL); - SetCursor(LoadCursor(NULL, IDC_ARROW)); - } -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_destroyMouse(JNIEnv *env, jobject self) { - ShutdownMouse(env); -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_nPollMouse(JNIEnv * env, jobject self, jobject coord_buffer_obj, jobject button_buffer_obj) { - UpdateMouseFields(env, coord_buffer_obj, button_buffer_obj); -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_setCursorPosition -(JNIEnv * env, jobject self, jint x, jint y) { - 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, getCurrentFullscreen(), 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)) - printfDebugJava(env, "SetCursorPos failed"); -} - -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_grabMouse -(JNIEnv * env, jobject self, jboolean grab) { - HRESULT di_res; - if(grab) { - if (!mouse_grabbed) { - // flush DX event buffer - readDXBuffer(env); - mouse_grabbed = true; - IDirectInputDevice_Unacquire(mDIDevice); - if (!acquireMouse(DISCL_EXCLUSIVE | DISCL_FOREGROUND)) - printfDebugJava(env, "Failed to reset cooperative mode"); - } - } else { - if (mouse_grabbed) { - mouse_grabbed = false; - IDirectInputDevice_Unacquire(mDIDevice); - acquireMouseNonExclusive(); - } - } - initEventQueue(&event_queue, EVENT_SIZE); -} - -/** - * Shutdown DI - */ -static void ShutdownMouse(JNIEnv *env) { - // release device - if (mDIDevice != NULL) { - printfDebugJava(env, "Releasing mouse DI device"); - IDirectInputDevice_Unacquire(mDIDevice); - IDirectInputDevice_Release(mDIDevice); - mDIDevice = NULL; - } - // Release DirectInput - if (lpdi != NULL) { - printfDebugJava(env, "Releasing directinput"); - IDirectInput_Release(lpdi); - lpdi = NULL; - } - created = false; -} - -/** - * Callback from EnumObjects. Called for each "object" on the Mouse. - */ -static BOOL CALLBACK EnumMouseObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef) { - printfDebug("found %s\n", lpddoi->tszName); - if(IsEqualGUID(&lpddoi->guidType, &GUID_Button)) { - mButtoncount++; - } else if(IsEqualGUID(&lpddoi->guidType, &GUID_XAxis)) { - } else if(IsEqualGUID(&lpddoi->guidType, &GUID_YAxis)) { - } else if(IsEqualGUID(&lpddoi->guidType, &GUID_ZAxis)) { - mHaswheel = true; - } else { - printfDebug("Unhandled object found: %s\n", lpddoi->tszName); - } - return DIENUM_CONTINUE; -} - -/** - * Updates the fields on the Mouse - */ -static void UpdateMouseFields(JNIEnv *env, jobject coord_buffer_obj, jobject button_buffer_obj) { - HRESULT hRes; - DIMOUSESTATE diMouseState; // State of Mouse - int i, j; - - int *coords = (int *)(*env)->GetDirectBufferAddress(env, coord_buffer_obj); - int coords_length = (int)(*env)->GetDirectBufferCapacity(env, coord_buffer_obj); - unsigned char *buttons_buffer = (unsigned char *)(*env)->GetDirectBufferAddress(env, button_buffer_obj); - int num_buttons; - int buttons_length = (int)(*env)->GetDirectBufferCapacity(env, button_buffer_obj); - if (coords_length < 3) { - printfDebugJava(env, "ERROR: Not enough space in coords array: %d < 3", coords_length); - return; - } - - hRes = IDirectInputDevice_GetDeviceState(mDIDevice, sizeof(DIMOUSESTATE), &diMouseState); - if (mouse_grabbed || hRes == DI_OK) { - if (hRes != DI_OK) { - // Don't allow the mouse to drift when failed - diMouseState.lX = 0; - diMouseState.lY = 0; - diMouseState.lZ = 0; - // did the read fail because we lost input for some reason? - // if so, then attempt to reacquire. - if(hRes == DIERR_INPUTLOST || hRes == DIERR_NOTACQUIRED) { - hRes = IDirectInputDevice_Acquire(mDIDevice); - if (hRes != DI_OK) { - return; - } else { - hRes = IDirectInputDevice_GetDeviceState(mDIDevice, sizeof(DIMOUSESTATE), &diMouseState); - if (hRes != DI_OK) { - printfDebugJava(env, "Error getting mouse state #2: %d", hRes); - return; - } - } - } else { - printfDebugJava(env, "Error getting mouse state #2: %d", hRes); - return; - } - } - - coords[2] = diMouseState.lZ; - num_buttons = mButtoncount; - if (num_buttons > buttons_length) { - num_buttons = buttons_length; - } - for (j = 0; j < num_buttons; j++) { - buttons_buffer[j] = diMouseState.rgbButtons[j] != 0 ? JNI_TRUE : JNI_FALSE; - // 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] = buttons_buffer[j]; - } - } else { - coords[2] = accum_dwheel; - num_buttons = mButtoncount; - if (num_buttons > BUTTON_STATES_SIZE) { - num_buttons = BUTTON_STATES_SIZE; - } - for (j = 0; j < num_buttons; j++) { - buttons_buffer[j] = win32_message_button_states[j]; - } - } - accum_dwheel = 0; - if (mouse_grabbed) { - coords[0] = diMouseState.lX; - coords[1] = -diMouseState.lY; - } else { - coords[0] = last_x; - coords[1] = last_y; - } -} diff --git a/src/native/win32/org_lwjgl_opengl_Display.c b/src/native/win32/org_lwjgl_opengl_Display.c index f6c094d7..e39016e1 100644 --- a/src/native/win32/org_lwjgl_opengl_Display.c +++ b/src/native/win32/org_lwjgl_opengl_Display.c @@ -129,9 +129,9 @@ static LRESULT CALLBACK lwjglWindowProc(HWND hWnd, WPARAM wParam, LPARAM lParam) { - int xPos; - int yPos; - int dwheel; + JNIEnv *env; + jclass display_class; + jmethodID handleMessage_method; if (isFullScreen && !isMinimized && isFocused) setupCursorClipping(); switch (msg) { @@ -176,50 +176,6 @@ static LRESULT CALLBACK lwjglWindowProc(HWND hWnd, break; } break; - case WM_MOUSEMOVE: - { - xPos = GET_X_LPARAM(lParam); - yPos = GET_Y_LPARAM(lParam); - handleMouseMoved(xPos, yPos); - return 0; - } - case WM_MOUSEWHEEL: - { - dwheel = GET_WHEEL_DELTA_WPARAM(wParam); - handleMouseScrolled(dwheel); - return 0; - } - case WM_LBUTTONDOWN: - { - handleMouseButton(0, 1); - return 0; - } - case WM_LBUTTONUP: - { - handleMouseButton(0, 0); - return 0; - } - case WM_RBUTTONDOWN: - { - handleMouseButton(1, 1); - return 0; - } - case WM_RBUTTONUP: - { - handleMouseButton(1, 0); - return 0; - } - case WM_MBUTTONDOWN: - { - handleMouseButton(2, 1); - return 0; - } - case WM_MBUTTONUP: - { - handleMouseButton(2, 0); - return 0; - } - break; case WM_QUIT: { closerequested = true; @@ -231,6 +187,17 @@ static LRESULT CALLBACK lwjglWindowProc(HWND hWnd, } } + env = (JNIEnv *)(LONG_PTR)GetWindowLongPtr(hWnd, GWLP_USERDATA); + 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"); + if (handleMessage_method != NULL) + if ((*env)->CallStaticBooleanMethod(env, NULL, handleMessage_method, (jlong)hWnd, (jint)msg, (jlong)wParam, (jlong)lParam)) + return 0; + } + } + // default action return DefWindowProc(hWnd, msg, wParam, lParam); } @@ -238,7 +205,7 @@ static LRESULT CALLBACK lwjglWindowProc(HWND hWnd, /* * Handle native Win32 messages */ -static void handleMessages(void) { +static void handleMessages(JNIEnv *env) { /* * Now's our chance to deal with Windows messages that are * otherwise just piling up and causing everything not to @@ -246,7 +213,7 @@ static void handleMessages(void) { */ MSG msg; if (display_hwnd != NULL) { - while (PeekMessage( + while (!(*env)->ExceptionOccurred(env) && PeekMessage( &msg, // message information NULL, // handle to window 0, // first message @@ -267,6 +234,10 @@ static void handleMessages(void) { } } +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_Win32Display_getHwnd(JNIEnv *env, jclass unused) { + return (INT_PTR)display_hwnd; +} + /* * Class: org_lwjgl_Window * Method: nSetTitle @@ -283,7 +254,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_setTitle JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_nUpdate (JNIEnv * env, jobject self) { - handleMessages(); + handleMessages(env); } @@ -342,6 +313,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_nCreateWindow(JNIEnv * throwException(env, "Failed to create the window."); return; } + SetWindowLongPtr(display_hwnd, GWLP_USERDATA, (LONG_PTR)env); display_hdc = GetDC(display_hwnd); ShowWindow(display_hwnd, SW_SHOWDEFAULT); UpdateWindow(display_hwnd); @@ -564,3 +536,62 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Win32Display_nSetWindowIcon32 return -1; } + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_setCursorPosition +(JNIEnv * env, jobject self, jint x, jint y) { + 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, getCurrentFullscreen(), 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)) + printfDebugJava(env, "SetCursorPos failed"); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32Display_setNativeCursor + (JNIEnv *env, jobject self, jobject handle_buffer) +{ + 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); + SetCursor(cursor); + } else { + SetClassLongPtr(getCurrentHWND(), GCL_HCURSOR, (LONG_PTR)NULL); + SetCursor(LoadCursor(NULL, IDC_ARROW)); + } +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_Win32Display_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; +} diff --git a/src/native/win32/org_lwjgl_opengl_WindowsDirectInput3.c b/src/native/win32/org_lwjgl_opengl_WindowsDirectInput3.c new file mode 100644 index 00000000..271f33f8 --- /dev/null +++ b/src/native/win32/org_lwjgl_opengl_WindowsDirectInput3.c @@ -0,0 +1,88 @@ +/* + * 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. + */ + +/** + * $Id: org_lwjgl_input_Keyboard.c 2385 2006-06-23 16:45:21Z elias_naur $ + * + * @author elias_naur + * @version $Revision: 2385 $ + */ + +#undef DIRECTINPUT_VERSION +#define DIRECTINPUT_VERSION 0x0300 +#include "Window.h" +#include +#include +#include "org_lwjgl_opengl_WindowsDirectInput3.h" + +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_WindowsDirectInput3_createDirectInput(JNIEnv *env, jobject unused, jlong hinst_int) { + HINSTANCE hinst = (HINSTANCE)(LONG_PTR)hinst_int; + LPDIRECTINPUT lpdi; + HRESULT ret; + + ret = DirectInputCreate(hinst, DIRECTINPUT_VERSION, &lpdi, NULL); + if (ret != DI_OK) { + throwFormattedException(env, "Failed to create DirectInput (%x)", ret); + return (LONG_PTR)NULL; + } + return (LONG_PTR)lpdi; +} + +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_WindowsDirectInput3_nCreateDevice(JNIEnv *env, jclass unused, jlong di_interface, jint type) { + LPDIRECTINPUT lpdi = (LPDIRECTINPUT)(LONG_PTR)di_interface; + LPDIRECTINPUTDEVICE lpdevice; + GUID device_guid; + HRESULT ret; + + switch (type) { + case org_lwjgl_opengl_WindowsDirectInput3_KEYBOARD_TYPE: + device_guid = GUID_SysKeyboard; + break; + case org_lwjgl_opengl_WindowsDirectInput3_MOUSE_TYPE: + device_guid = GUID_SysMouse; + break; + default: + throwFormattedException(env, "Unknown device type (%d)", type); + return (LONG_PTR)NULL; + } + ret = IDirectInput_CreateDevice(lpdi, &device_guid, &lpdevice, NULL); + if (ret != DI_OK) { + throwFormattedException(env, "Failed to create keyboard (%x).", ret); + return (LONG_PTR)NULL; + } + return (LONG_PTR)lpdevice; +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDirectInput3_release(JNIEnv *env, jobject unused, jlong di_interface) { + LPDIRECTINPUT lpdi = (LPDIRECTINPUT)(LONG_PTR)di_interface; + IDirectInput_Release(lpdi); +} diff --git a/src/native/win32/org_lwjgl_opengl_WindowsDirectInput8.c b/src/native/win32/org_lwjgl_opengl_WindowsDirectInput8.c new file mode 100644 index 00000000..35551fc5 --- /dev/null +++ b/src/native/win32/org_lwjgl_opengl_WindowsDirectInput8.c @@ -0,0 +1,100 @@ +/* + * 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. + */ + +/** + * $Id: org_lwjgl_input_Keyboard.c 2385 2006-06-23 16:45:21Z elias_naur $ + * + * @author elias_naur + * @version $Revision: 2385 $ + */ + +#undef DIRECTINPUT_VERSION +#define DIRECTINPUT_VERSION 0x0800 +#include "Window.h" +#include +#include +#include "org_lwjgl_opengl_WindowsDirectInput8.h" + +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_WindowsDirectInput8_createDirectInput(JNIEnv *env, jobject unused, jlong hinst_int) { + HINSTANCE hinst = (HINSTANCE)(LONG_PTR)hinst_int; + LPDIRECTINPUT8 lpdi; + HRESULT ret; + + ret = CoInitializeEx(NULL, COINIT_MULTITHREADED); + if (ret != S_OK && ret != S_FALSE && ret != RPC_E_CHANGED_MODE) { + throwFormattedException(env, "CoInitializeEx failed (%x)", ret); + return (LONG_PTR)NULL; + } + ret = CoCreateInstance(&CLSID_DirectInput8, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInput8, &lpdi); + if (ret != DI_OK && ret != DIERR_BETADIRECTINPUTVERSION) { + throwFormattedException(env, "Failed to create DirectInput (%x)", ret); + return (LONG_PTR)NULL; + } + + ret = IDirectInput8_Initialize(lpdi, hinst, DIRECTINPUT_VERSION); + if (FAILED(ret)) { + throwFormattedException(env, "Failed to initialize DirectInput (%x)", ret); + IDirectInput8_Release(lpdi); + return (LONG_PTR)NULL; + } + return (LONG_PTR)lpdi; +} + +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_WindowsDirectInput8_nCreateDevice(JNIEnv *env, jclass unused, jlong di_interface, jint type) { + LPDIRECTINPUT8 lpdi = (LPDIRECTINPUT8)(LONG_PTR)di_interface; + LPDIRECTINPUTDEVICE8 lpdevice; + GUID device_guid; + HRESULT ret; + + switch (type) { + case org_lwjgl_opengl_WindowsDirectInput8_KEYBOARD_TYPE: + device_guid = GUID_SysKeyboard; + break; + case org_lwjgl_opengl_WindowsDirectInput8_MOUSE_TYPE: + device_guid = GUID_SysMouse; + break; + default: + throwFormattedException(env, "Unknown device type (%d)", type); + return (LONG_PTR)NULL; + } + ret = IDirectInput8_CreateDevice(lpdi, &device_guid, &lpdevice, NULL); + if (ret != DI_OK) { + throwFormattedException(env, "Failed to create keyboard (%x).", ret); + return (LONG_PTR)NULL; + } + return (LONG_PTR)lpdevice; +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDirectInput8_release(JNIEnv *env, jobject unused, jlong di_interface) { + LPDIRECTINPUT8 lpdi = (LPDIRECTINPUT8)(LONG_PTR)di_interface; + IDirectInput8_Release(lpdi); +} diff --git a/src/native/win32/org_lwjgl_opengl_WindowsDirectInputDevice3.c b/src/native/win32/org_lwjgl_opengl_WindowsDirectInputDevice3.c new file mode 100644 index 00000000..f880c1e0 --- /dev/null +++ b/src/native/win32/org_lwjgl_opengl_WindowsDirectInputDevice3.c @@ -0,0 +1,159 @@ +/* + * 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. + */ + +/** + * $Id: org_lwjgl_input_Keyboard.c 2385 2006-06-23 16:45:21Z elias_naur $ + * + * @author elias_naur + * @version $Revision: 2385 $ + */ + +#undef DIRECTINPUT_VERSION +#define DIRECTINPUT_VERSION 0x0300 +#include "Window.h" +#include "dinputhelper.h" +#include +#include +#include "org_lwjgl_opengl_WindowsDirectInput3.h" +#include "org_lwjgl_opengl_WindowsDirectInputDevice3.h" + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice3_unacquire(JNIEnv *env, jobject unused, jlong di_device) { + LPDIRECTINPUTDEVICE lpdevice = (LPDIRECTINPUTDEVICE)(LONG_PTR)di_device; + return IDirectInputDevice_Unacquire(lpdevice); +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice3_setDataFormat(JNIEnv *env, jobject unused, jlong di_device, jint type) { + LPDIRECTINPUTDEVICE lpdevice = (LPDIRECTINPUTDEVICE)(LONG_PTR)di_device; + LPCDIDATAFORMAT format; + + switch (type) { + case org_lwjgl_opengl_WindowsDirectInput3_KEYBOARD_TYPE: + format = &c_dfDIKeyboard; + break; + case org_lwjgl_opengl_WindowsDirectInput3_MOUSE_TYPE: + format = &c_dfDIMouse; + break; + default: + throwFormattedException(env, "Unknown device type (%d)", type); + return DIERR_INVALIDPARAM; + } + return IDirectInputDevice_SetDataFormat(lpdevice, format); +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice3_getDeviceState(JNIEnv *env, jobject unused, jlong di_device, jobject buffer_obj, jint pos, jint size) { + LPDIRECTINPUTDEVICE lpdevice = (LPDIRECTINPUTDEVICE)(LONG_PTR)di_device; + jbyte *buffer = pos + (jbyte *)(*env)->GetDirectBufferAddress(env, buffer_obj); + return IDirectInputDevice_GetDeviceState(lpdevice, size, buffer); +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice3_getEventSize(JNIEnv *env, jobject unused) { + return sizeof(DIDEVICEOBJECTDATA); +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice3_getDeviceData(JNIEnv *env, jobject unused, jlong di_device, jobject event_buffer_obj, jint event_buffer_size, jobject buffer_obj, jint buffer_pos, jint buffer_size) { + LPDIRECTINPUTDEVICE lpdevice = (LPDIRECTINPUTDEVICE)(LONG_PTR)di_device; + jint *buffer = buffer_pos + (jint *)(*env)->GetDirectBufferAddress(env, buffer_obj); + DIDEVICEOBJECTDATA *event_buffer = (*env)->GetDirectBufferAddress(env, event_buffer_obj); + 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 i; + if (ret != DI_OK && ret != DI_BUFFEROVERFLOW) + return ret; + + if (num_buffer_events < num_events) { + num_events = num_buffer_events; + ret = DI_BUFFEROVERFLOW; + } + for (i = 0; i < num_events; i++) { + current_event = event_buffer + i; + buffer[buffer_pos++] = current_event->dwOfs; + buffer[buffer_pos++] = current_event->dwData; + } + positionBuffer(env, buffer_obj, buffer_pos); + return ret; +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice3_acquire(JNIEnv *env, jobject unused, jlong di_device) { + LPDIRECTINPUTDEVICE lpdevice = (LPDIRECTINPUTDEVICE)(LONG_PTR)di_device; + return IDirectInputDevice_Acquire(lpdevice); +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice3_setBufferSize(JNIEnv *env, jobject unused, jlong di_device, jint buffer_size) { + LPDIRECTINPUTDEVICE lpdevice = (LPDIRECTINPUTDEVICE)(LONG_PTR)di_device; + DIPROPDWORD dipropdw; + dipropdw.diph.dwSize = sizeof(DIPROPDWORD); + dipropdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dipropdw.diph.dwObj = 0; + dipropdw.diph.dwHow = DIPH_DEVICE; + dipropdw.dwData = buffer_size; + return IDirectInputDevice_SetProperty(lpdevice, DIPROP_BUFFERSIZE, &dipropdw.diph); +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice3_setCooperativeLevel(JNIEnv *env, jobject unused, jlong di_device, jlong hwnd_int, jint flags) { + LPDIRECTINPUTDEVICE lpdevice = (LPDIRECTINPUTDEVICE)(LONG_PTR)di_device; + HWND hwnd = (HWND)(LONG_PTR)hwnd_int; + return IDirectInputDevice_SetCooperativeLevel(lpdevice, hwnd, flags); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice3_release(JNIEnv *env, jobject unused, jlong di_device) { + LPDIRECTINPUTDEVICE lpdevice = (LPDIRECTINPUTDEVICE)(LONG_PTR)di_device; + IDirectInputDevice_Release(lpdevice); +} + +static BOOL CALLBACK EnumMouseObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef) { + enum_context_t *enum_context = (enum_context_t *)pvRef; + jint object_type; + + if (IsEqualGUID(&lpddoi->guidType, &GUID_Button)) { + object_type = org_lwjgl_opengl_WindowsDirectInputDevice3_GUID_Button; + } else if(IsEqualGUID(&lpddoi->guidType, &GUID_XAxis)) { + object_type = org_lwjgl_opengl_WindowsDirectInputDevice3_GUID_XAxis; + } else if(IsEqualGUID(&lpddoi->guidType, &GUID_YAxis)) { + object_type = org_lwjgl_opengl_WindowsDirectInputDevice3_GUID_YAxis; + } else if(IsEqualGUID(&lpddoi->guidType, &GUID_ZAxis)) { + object_type = org_lwjgl_opengl_WindowsDirectInputDevice3_GUID_ZAxis; + } else { + object_type = org_lwjgl_opengl_WindowsDirectInputDevice3_GUID_Unknown; + } + + return objectCallback(enum_context->env, enum_context->enumerator, object_type, lpddoi->tszName) ? DIENUM_CONTINUE : DIENUM_STOP; +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice3_enumObjects(JNIEnv *env, jobject unused, jlong di_device, jobject enumerator) { + LPDIRECTINPUTDEVICE lpdevice = (LPDIRECTINPUTDEVICE)(LONG_PTR)di_device; + enum_context_t enum_context; + enum_context.env = env; + enum_context.enumerator = enumerator; + return IDirectInputDevice_EnumObjects(lpdevice, EnumMouseObjectsCallback, &enum_context, DIDFT_ALL); +} diff --git a/src/native/win32/org_lwjgl_opengl_WindowsDirectInputDevice8.c b/src/native/win32/org_lwjgl_opengl_WindowsDirectInputDevice8.c new file mode 100644 index 00000000..83d57f79 --- /dev/null +++ b/src/native/win32/org_lwjgl_opengl_WindowsDirectInputDevice8.c @@ -0,0 +1,164 @@ +/* + * 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. + */ + +/** + * $Id: org_lwjgl_input_Keyboard.c 2385 2006-06-23 16:45:21Z elias_naur $ + * + * @author elias_naur + * @version $Revision: 2385 $ + */ + +#undef DIRECTINPUT_VERSION +#define DIRECTINPUT_VERSION 0x0800 +#include "Window.h" +#include "dinputhelper.h" +#include +#include +#include "org_lwjgl_opengl_WindowsDirectInput8.h" +#include "org_lwjgl_opengl_WindowsDirectInputDevice8.h" + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice8_unacquire(JNIEnv *env, jobject unused, jlong di_device) { + LPDIRECTINPUTDEVICE8 lpdevice = (LPDIRECTINPUTDEVICE8)(LONG_PTR)di_device; + return IDirectInputDevice8_Unacquire(lpdevice); +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice8_poll(JNIEnv *env, jobject unused, jlong di_device) { + LPDIRECTINPUTDEVICE8 lpdevice = (LPDIRECTINPUTDEVICE8)(LONG_PTR)di_device; + return IDirectInputDevice8_Poll(lpdevice); +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice8_setDataFormat(JNIEnv *env, jobject unused, jlong di_device, jint type) { + LPDIRECTINPUTDEVICE8 lpdevice = (LPDIRECTINPUTDEVICE8)(LONG_PTR)di_device; + LPCDIDATAFORMAT format; + + switch (type) { + case org_lwjgl_opengl_WindowsDirectInput8_KEYBOARD_TYPE: + format = &c_dfDIKeyboard; + break; + case org_lwjgl_opengl_WindowsDirectInput8_MOUSE_TYPE: + format = &c_dfDIMouse; + break; + default: + throwFormattedException(env, "Unknown device type (%d)", type); + return DIERR_INVALIDPARAM; + } + return IDirectInputDevice8_SetDataFormat(lpdevice, format); +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice8_getDeviceState(JNIEnv *env, jobject unused, jlong di_device, jobject buffer_obj, jint pos, jint size) { + LPDIRECTINPUTDEVICE8 lpdevice = (LPDIRECTINPUTDEVICE8)(LONG_PTR)di_device; + jbyte *buffer = pos + (jbyte *)(*env)->GetDirectBufferAddress(env, buffer_obj); + return IDirectInputDevice8_GetDeviceState(lpdevice, size, buffer); +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice8_getEventSize(JNIEnv *env, jobject unused) { + return sizeof(DIDEVICEOBJECTDATA); +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice8_getDeviceData(JNIEnv *env, jobject unused, jlong di_device, jobject event_buffer_obj, jint event_buffer_size, jobject buffer_obj, jint buffer_pos, jint buffer_size) { + LPDIRECTINPUTDEVICE8 lpdevice = (LPDIRECTINPUTDEVICE8)(LONG_PTR)di_device; + jint *buffer = buffer_pos + (jint *)(*env)->GetDirectBufferAddress(env, buffer_obj); + DIDEVICEOBJECTDATA *event_buffer = (*env)->GetDirectBufferAddress(env, event_buffer_obj); + 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 i; + if (ret != DI_OK && ret != DI_BUFFEROVERFLOW) + return ret; + + if (num_buffer_events < num_events) { + num_events = num_buffer_events; + ret = DI_BUFFEROVERFLOW; + } + for (i = 0; i < num_events; i++) { + current_event = event_buffer + i; + buffer[buffer_pos++] = current_event->dwOfs; + buffer[buffer_pos++] = current_event->dwData; + } + positionBuffer(env, buffer_obj, buffer_pos); + return ret; +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice8_acquire(JNIEnv *env, jobject unused, jlong di_device) { + LPDIRECTINPUTDEVICE8 lpdevice = (LPDIRECTINPUTDEVICE8)(LONG_PTR)di_device; + return IDirectInputDevice8_Acquire(lpdevice); +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice8_setBufferSize(JNIEnv *env, jobject unused, jlong di_device, jint buffer_size) { + LPDIRECTINPUTDEVICE8 lpdevice = (LPDIRECTINPUTDEVICE8)(LONG_PTR)di_device; + DIPROPDWORD dipropdw; + dipropdw.diph.dwSize = sizeof(DIPROPDWORD); + dipropdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dipropdw.diph.dwObj = 0; + dipropdw.diph.dwHow = DIPH_DEVICE; + dipropdw.dwData = buffer_size; + return IDirectInputDevice8_SetProperty(lpdevice, DIPROP_BUFFERSIZE, &dipropdw.diph); +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice8_setCooperativeLevel(JNIEnv *env, jobject unused, jlong di_device, jlong hwnd_int, jint flags) { + LPDIRECTINPUTDEVICE8 lpdevice = (LPDIRECTINPUTDEVICE8)(LONG_PTR)di_device; + HWND hwnd = (HWND)(LONG_PTR)hwnd_int; + return IDirectInputDevice8_SetCooperativeLevel(lpdevice, hwnd, flags); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice8_release(JNIEnv *env, jobject unused, jlong di_device) { + LPDIRECTINPUTDEVICE8 lpdevice = (LPDIRECTINPUTDEVICE8)(LONG_PTR)di_device; + IDirectInputDevice8_Release(lpdevice); +} + +static BOOL CALLBACK EnumMouseObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef) { + enum_context_t *enum_context = (enum_context_t *)pvRef; + jint object_type; + + if (IsEqualGUID(&lpddoi->guidType, &GUID_Button)) { + object_type = org_lwjgl_opengl_WindowsDirectInputDevice8_GUID_Button; + } else if(IsEqualGUID(&lpddoi->guidType, &GUID_XAxis)) { + object_type = org_lwjgl_opengl_WindowsDirectInputDevice8_GUID_XAxis; + } else if(IsEqualGUID(&lpddoi->guidType, &GUID_YAxis)) { + object_type = org_lwjgl_opengl_WindowsDirectInputDevice8_GUID_YAxis; + } else if(IsEqualGUID(&lpddoi->guidType, &GUID_ZAxis)) { + object_type = org_lwjgl_opengl_WindowsDirectInputDevice8_GUID_ZAxis; + } else { + object_type = org_lwjgl_opengl_WindowsDirectInputDevice8_GUID_Unknown; + } + + return objectCallback(enum_context->env, enum_context->enumerator, object_type, lpddoi->tszName) ? DIENUM_CONTINUE : DIENUM_STOP; +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsDirectInputDevice8_enumObjects(JNIEnv *env, jobject unused, jlong di_device, jobject enumerator) { + LPDIRECTINPUTDEVICE8 lpdevice = (LPDIRECTINPUTDEVICE8)(LONG_PTR)di_device; + enum_context_t enum_context; + enum_context.env = env; + enum_context.enumerator = enumerator; + return IDirectInputDevice8_EnumObjects(lpdevice, EnumMouseObjectsCallback, &enum_context, DIDFT_ALL); +} diff --git a/src/native/win32/org_lwjgl_opengl_WindowsKeyboard.c b/src/native/win32/org_lwjgl_opengl_WindowsKeyboard.c new file mode 100644 index 00000000..09a01e35 --- /dev/null +++ b/src/native/win32/org_lwjgl_opengl_WindowsKeyboard.c @@ -0,0 +1,57 @@ +/* + * 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. + */ + +/** + * $Id: org_lwjgl_input_Keyboard.c 2385 2006-06-23 16:45:21Z elias_naur $ + * + * @author elias_naue + * @version $Revision: 2385 $ + */ + +#include "Window.h" +#include +#include "org_lwjgl_opengl_WindowsKeyboard.h" + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsKeyboard_MapVirtualKey(JNIEnv *env, jclass unused, jint uCode, jint uMapType) { + return MapVirtualKey(uCode, uMapType); +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsKeyboard_ToUnicode(JNIEnv *env, jclass unused, jint wVirtKey, jint wScanCode, jobject lpKeyState_obj, jobject pwszBuff_obj, jint cchBuff, jint flags) { + const PBYTE lpKeyState = (*env)->GetDirectBufferAddress(env, lpKeyState_obj); + LPWSTR pwszBuff = (*env)->GetDirectBufferAddress(env, pwszBuff_obj); + return ToUnicode(wVirtKey, wScanCode, lpKeyState, pwszBuff, cchBuff, flags); +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_WindowsKeyboard_GetKeyboardState(JNIEnv *env, jclass unused, jobject lpKeyState_obj) { + PBYTE lpKeyState = (*env)->GetDirectBufferAddress(env, lpKeyState_obj); + return GetKeyboardState(lpKeyState); +}