diff --git a/src/java/org/lwjgl/input/Cursor.java b/src/java/org/lwjgl/input/Cursor.java index 17ac6235..222e9173 100644 --- a/src/java/org/lwjgl/input/Cursor.java +++ b/src/java/org/lwjgl/input/Cursor.java @@ -36,6 +36,7 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.IntBuffer; +import org.lwjgl.Display; import org.lwjgl.Sys; import org.lwjgl.LWJGLException; @@ -100,22 +101,39 @@ public class Cursor { IntBuffer images_copy = ByteBuffer.allocateDirect(images.remaining()*4).order(ByteOrder.nativeOrder()).asIntBuffer(); flipImages(width, height, numImages, images, images_copy); - // create our cursor elements - cursors = new CursorElement[numImages]; - for(int i=0; i Window.getWidth()) { x = Window.getWidth(); } - + if (y < 0) { y = 0; } else if (y > Window.getHeight()) { y = Window.getHeight(); } } - if (readBuffer != null) - read(); + if (readBuffer != null) read(); } private static void read() { readBuffer.compact(); int numEvents = nRead(readBuffer, readBuffer.position()); - readBuffer.position(readBuffer.position() + numEvents*2); + readBuffer.position(readBuffer.position() + numEvents * 2); readBuffer.flip(); } @@ -393,14 +389,13 @@ public class Mouse { * @return true if the specified button is down */ public static boolean isButtonDown(int button) { - if (!created) - throw new IllegalStateException("Mouse must be created before you can poll the button state"); + if (!created) throw new IllegalStateException("Mouse must be created before you can poll the button state"); if (button >= buttonCount || button < 0) return false; else return buttons.get(button) == 1; } - + /** * Gets a button's name * @param button The button @@ -412,7 +407,7 @@ public class Mouse { else return buttonName[button]; } - + /** * Get's a button's index. If the button is unrecognised then -1 is returned. * @param buttonName The button name @@ -429,9 +424,8 @@ public class Mouse { * Enable mouse button buffering. Must be called after the mouse is created. */ public static void enableBuffer() throws LWJGLException { - if (!created) - throw new IllegalStateException("Mouse must be created before you can enable buffering"); - readBuffer = BufferUtils.createByteBuffer(2*BUFFER_SIZE); + if (!created) throw new IllegalStateException("Mouse must be created before you can enable buffering"); + readBuffer = BufferUtils.createByteBuffer(2 * BUFFER_SIZE); readBuffer.limit(0); nEnableBuffer(); } @@ -458,10 +452,9 @@ public class Mouse { * @return true if a mouse event was read, false otherwise */ public static boolean next() { - if (!created) - throw new IllegalStateException("Mouse must be created before you can read events"); + if (!created) throw new IllegalStateException("Mouse must be created before you can read events"); if (readBuffer == null) - throw new IllegalStateException("Event buffering must be enabled before you can read events"); + throw new IllegalStateException("Event buffering must be enabled before you can read events"); if (readBuffer.hasRemaining()) { eventButton = readBuffer.get() & 0xFF; @@ -470,14 +463,14 @@ public class Mouse { } else return false; } - + /** * @return Current events button */ public static int getEventButton() { return eventButton; } - + /** * @return Current events button state */ @@ -503,8 +496,8 @@ public class Mouse { */ public static int getY() { return y; - } - + } + /** * @return Movement on the x axis since last time getDX() was called */ @@ -540,19 +533,35 @@ public class Mouse { return hasWheel; } + /** + * @return whether or not the mouse has grabbed the cursor + */ + public static boolean isGrabbed() { + return isGrabbed; + } + + /** + * Sets whether or not the mouse has grabbed the cursor + * (and thus hidden). + */ + public static void setGrabbed(boolean grab) { + isGrabbed = grab; + nGrabMouse(isGrabbed); + } + private static native void nGrabMouse(boolean grab); + /** * Updates the cursor, so that animation can be changed if needed. * This method is called automatically by the window on its update. */ public static void updateCursor() { - if(currentCursor != null && currentCursor.hasTimedOut()) { + if (Display.getPlatform() == Display.PLATFORM_WGL && currentCursor != null && currentCursor.hasTimedOut()) { currentCursor.nextCursor(); try { setNativeCursor(currentCursor); } catch (LWJGLException e) { - if (Sys.DEBUG) - e.printStackTrace(); + if (Sys.DEBUG) e.printStackTrace(); } } } -} +} \ No newline at end of file diff --git a/src/java/org/lwjgl/test/input/HWCursorTest.java b/src/java/org/lwjgl/test/input/HWCursorTest.java index 8a5e87f8..ea53fc9b 100644 --- a/src/java/org/lwjgl/test/input/HWCursorTest.java +++ b/src/java/org/lwjgl/test/input/HWCursorTest.java @@ -346,6 +346,11 @@ public class HWCursorTest { e.printStackTrace(); } } + + if(Keyboard.isKeyDown(Keyboard.KEY_SPACE)) { + Mouse.setGrabbed(!Mouse.isGrabbed()); + System.out.println("Grabbed: " + Mouse.isGrabbed()); + } } /** diff --git a/src/java/org/lwjgl/test/input/MouseTest.java b/src/java/org/lwjgl/test/input/MouseTest.java index 2f5b9e4b..703e650e 100644 --- a/src/java/org/lwjgl/test/input/MouseTest.java +++ b/src/java/org/lwjgl/test/input/MouseTest.java @@ -242,6 +242,7 @@ public class MouseTest { if (Mouse.getDX() == Mouse.getDY() && Mouse.getDX() == 0 && Mouse.getDWheel() == 0) { return; } + // determine direction moved // ============================ if(Mouse.getDX() > 0) { @@ -259,8 +260,8 @@ public class MouseTest { if(Mouse.getDY() < 0) { direction = 2; } - // ---------------------------- + // ---------------------------- if(direction > -1) { // based on which button was last pushed, update model @@ -316,6 +317,10 @@ public class MouseTest { if(Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) { closing = true; } + + if(Keyboard.isKeyDown(Keyboard.KEY_SPACE)) { + Mouse.setGrabbed(!Mouse.isGrabbed()); + } } /** diff --git a/src/native/common/org_lwjgl_input_Cursor.h b/src/native/common/org_lwjgl_input_Cursor.h index 013e5a77..5c7a6b6c 100644 --- a/src/native/common/org_lwjgl_input_Cursor.h +++ b/src/native/common/org_lwjgl_input_Cursor.h @@ -16,7 +16,7 @@ extern "C" { * Signature: (IIIIILjava/nio/IntBuffer;I)J */ JNIEXPORT jlong JNICALL Java_org_lwjgl_input_Cursor_nCreateCursor - (JNIEnv *, jclass, jint, jint, jint, jint, jint, jobject, jint); + (JNIEnv *, jclass, jint, jint, jint, jint, jint, jobject, jint, jobject, jint); /* * Class: org_lwjgl_input_Cursor diff --git a/src/native/common/org_lwjgl_input_Mouse.h b/src/native/common/org_lwjgl_input_Mouse.h index 92b0bb28..65ef670d 100644 --- a/src/native/common/org_lwjgl_input_Mouse.h +++ b/src/native/common/org_lwjgl_input_Mouse.h @@ -103,6 +103,14 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nDestroy */ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nPoll (JNIEnv *, jclass, jobject, jobject); + +/* + * Class: org_lwjgl_input_Mouse + * Method: nGrabMouse + * Signature: (Z)Z + */ +JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nGrabMouse + (JNIEnv * env, jclass clazz, jboolean grab); /* * Class: org_lwjgl_input_Mouse diff --git a/src/native/linux/org_lwjgl_input_Cursor.cpp b/src/native/linux/org_lwjgl_input_Cursor.cpp index adc2f4a6..2d127f42 100644 --- a/src/native/linux/org_lwjgl_input_Cursor.cpp +++ b/src/native/linux/org_lwjgl_input_Cursor.cpp @@ -50,11 +50,14 @@ * Signature: (IIIIIII)I */ JNIEXPORT jlong JNICALL Java_org_lwjgl_input_Cursor_nCreateCursor - (JNIEnv *env, jclass clazz, jint width, jint height, jint x_hotspot, jint y_hotspot, jint num_images, jobject image_buffer, jint images_offset) + (JNIEnv *env, jclass clazz, jint width, jint height, jint x_hotspot, jint y_hotspot, jint num_images, jobject image_buffer, jint images_offset, jobject delay_buffer, jint delays_offset) { Display *disp = incDisplay(env); if (disp == NULL) return 0; + const int *delays = NULL; + if (delay_buffer != NULL) + delays = (const int *)env->GetDirectBufferAddress(delay_buffer) + delays_offset; XcursorPixel *pixels = (XcursorPixel *)env->GetDirectBufferAddress(image_buffer) + images_offset; int stride = width*height; XcursorImages *cursor_images = XcursorImagesCreate(num_images); @@ -66,6 +69,8 @@ JNIEXPORT jlong JNICALL Java_org_lwjgl_input_Cursor_nCreateCursor cursor_image->xhot = x_hotspot; cursor_image->yhot = y_hotspot; cursor_image->pixels = &(pixels[stride*i]); + if (num_images > 1) + cursor_image->delay = delays[i]; cursor_images->images[i] = cursor_image; } Cursor cursor = XcursorImagesLoadCursor(disp, cursor_images); diff --git a/src/native/linux/org_lwjgl_input_Mouse.cpp b/src/native/linux/org_lwjgl_input_Mouse.cpp index 32102819..d8547338 100644 --- a/src/native/linux/org_lwjgl_input_Mouse.cpp +++ b/src/native/linux/org_lwjgl_input_Mouse.cpp @@ -399,3 +399,17 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nRead(JNIEnv *env, jclass claz int buffer_size = env->GetDirectBufferCapacity(buffer) - buffer_position; return copyEvents(&event_queue, buffer_ptr + buffer_position, buffer_size, 2); } + +/* + * Class: org_lwjgl_input_Mouse + * Method: nGrabMouse + * Signature: (Z)Z + */ +JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nGrabMouse + (JNIEnv * env, jclass clazz, jboolean grab) { + if(native_cursor) { + return; + } + + // do it? +} \ No newline at end of file diff --git a/src/native/macosx/org_lwjgl_input_Cursor.cpp b/src/native/macosx/org_lwjgl_input_Cursor.cpp index c44ca570..14979aa9 100644 --- a/src/native/macosx/org_lwjgl_input_Cursor.cpp +++ b/src/native/macosx/org_lwjgl_input_Cursor.cpp @@ -41,7 +41,7 @@ #include "org_lwjgl_input_Cursor.h" -JNIEXPORT jlong JNICALL Java_org_lwjgl_input_Cursor_nCreateCursor(JNIEnv *env, jclass clazz, jint width, jint height, jint x_hotspot, jint y_hotspot, jint num_images, jobject image_buffer, jint images_offset) { +JNIEXPORT jlong JNICALL Java_org_lwjgl_input_Cursor_nCreateCursor(JNIEnv *env, jclass clazz, jint width, jint height, jint x_hotspot, jint y_hotspot, jint num_images, jobject image_buffer, jint images_offset, jobject delay_buffer, jint delays_offset) { } JNIEXPORT void JNICALL Java_org_lwjgl_input_Cursor_nDestroyCursor(JNIEnv *env, jclass clazz, jlong cursor_handle) { diff --git a/src/native/macosx/org_lwjgl_input_Mouse.cpp b/src/native/macosx/org_lwjgl_input_Mouse.cpp index 282e2656..3cbf348f 100644 --- a/src/native/macosx/org_lwjgl_input_Mouse.cpp +++ b/src/native/macosx/org_lwjgl_input_Mouse.cpp @@ -257,3 +257,13 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nRead(JNIEnv *env, jclass claz int buffer_size = env->GetDirectBufferCapacity(buffer) - buffer_position; return copyEvents(&event_queue, buffer_ptr + buffer_position, buffer_size, 2); } + +/* + * Class: org_lwjgl_input_Mouse + * Method: nGrabMouse + * Signature: (Z)Z + */ +JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nGrabMouse + (JNIEnv * env, jclass clazz, jboolean grab) { + // do it? +} \ No newline at end of file diff --git a/src/native/win32/org_lwjgl_input_Cursor.cpp b/src/native/win32/org_lwjgl_input_Cursor.cpp index 625375bd..12b6ee41 100755 --- a/src/native/win32/org_lwjgl_input_Cursor.cpp +++ b/src/native/win32/org_lwjgl_input_Cursor.cpp @@ -50,7 +50,7 @@ * Signature: (IIIIIIIII)I */ JNIEXPORT jlong JNICALL Java_org_lwjgl_input_Cursor_nCreateCursor - (JNIEnv *env, jclass clazz, jint width, jint height, jint x_hotspot, jint y_hotspot, jint num_images, jobject image_buffer, jint images_offset) + (JNIEnv *env, jclass clazz, jint width, jint height, jint x_hotspot, jint y_hotspot, jint num_images, jobject image_buffer, jint images_offset, jobject delay_buffer, jint delays_offset) { int *pixels = (int *)env->GetDirectBufferAddress(image_buffer) + images_offset; diff --git a/src/native/win32/org_lwjgl_input_Mouse.cpp b/src/native/win32/org_lwjgl_input_Mouse.cpp index 127f92ba..34f28848 100644 --- a/src/native/win32/org_lwjgl_input_Mouse.cpp +++ b/src/native/win32/org_lwjgl_input_Mouse.cpp @@ -57,6 +57,7 @@ static bool mFirstTimeInitialization = true; // boolean to determine first time static POINT cursorPos; static RECT windowRect; static bool usingNativeCursor; +static int mouseMask = DISCL_NONEXCLUSIVE | DISCL_FOREGROUND; // Function prototypes (defined in the cpp file, since header file is generic across platforms void EnumerateMouseCapabilities(); @@ -97,8 +98,6 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nCreate(JNIEnv *env, jclass cl return; } - ShowCursor(FALSE); - /* skip enumeration, since we only want system mouse */ CreateMouse(); @@ -240,19 +239,18 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nSetNativeCursor cursorPos.x = (clientRect.left + clientRect.right)/2; cursorPos.y = clientRect.bottom - 1 - (clientRect.bottom - clientRect.top)/2; SetCursorPos(cursorPos.x, cursorPos.y); - ShowCursor(TRUE); usingNativeCursor = true; } } else { if (usingNativeCursor) { SetClassLong(hwnd, GCL_HCURSOR, (LONG)NULL); SetCursor(NULL); + ShowCursor(TRUE); mDIDevice->Unacquire(); - if(mDIDevice->SetCooperativeLevel(hwnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND) != DI_OK) { + if(mDIDevice->SetCooperativeLevel(hwnd, mouseMask) != DI_OK) { throwException(env, "Could not set the CooperativeLevel."); return; } - ShowCursor(FALSE); usingNativeCursor = false; mDIDevice->Acquire(); } @@ -287,12 +285,11 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nGetMinCursorSize * Signature: ()V */ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nDestroy(JNIEnv *env, jclass clazz) { - ShowCursor(TRUE); ShutdownMouse(); } /* - * Class: org_lwjgl_input_Controller + * Class: org_lwjgl_input_Mouse * Method: nPoll * Signature: ()V */ @@ -301,6 +298,30 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nPoll(JNIEnv * env, jclass cla UpdateMouseFields(env, clazz, coord_buffer_obj, button_buffer_obj); } +/* + * Class: org_lwjgl_input_Mouse + * Method: nGrabMouse + * Signature: (Z)Z + */ +JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nGrabMouse + (JNIEnv * env, jclass clazz, jboolean grab) { + if(usingNativeCursor) { + return; + } + + if(grab) { + mouseMask = DISCL_EXCLUSIVE | DISCL_FOREGROUND; + } else { + mouseMask = DISCL_NONEXCLUSIVE | DISCL_FOREGROUND; + } + mDIDevice->Unacquire(); + if(mDIDevice->SetCooperativeLevel(hwnd, mouseMask) != DI_OK) { + throwException(env, "Could not set the CooperativeLevel."); + return; + } + mDIDevice->Acquire(); +} + /** * Shutdown DI */ @@ -384,7 +405,7 @@ void SetupMouse() { mDIDevice->SetProperty(DIPROP_BUFFERSIZE, &dipropdw.diph); // set the cooperative level - if(mDIDevice->SetCooperativeLevel(hwnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND) != DI_OK) { + if(mDIDevice->SetCooperativeLevel(hwnd, mouseMask) != DI_OK) { printfDebug("SetCooperativeLevel failed\n"); mCreate_success = false; return;