From 43b2d67a71573af4c70586cf2e00a0c7382dfd49 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Sat, 11 Oct 2003 11:03:06 +0000 Subject: [PATCH] Moved native cursor origin to middle of the window --- src/java/org/lwjgl/input/Mouse.java | 5 +- src/native/linux/org_lwjgl_input_Mouse.cpp | 82 ++++++++++++---------- src/native/win32/org_lwjgl_input_Mouse.cpp | 51 ++++++-------- 3 files changed, 68 insertions(+), 70 deletions(-) diff --git a/src/java/org/lwjgl/input/Mouse.java b/src/java/org/lwjgl/input/Mouse.java index bc62bd51..e5e9140c 100644 --- a/src/java/org/lwjgl/input/Mouse.java +++ b/src/java/org/lwjgl/input/Mouse.java @@ -125,8 +125,9 @@ public class Mouse { * * NOTE: The native cursor is not constrained to the window, but * relative events will not be generated if the cursor is outside. - * The initial position of the cursor is in the upper left corner of - * the window, and the cursor will be moved to this origin when a + * The initial position of the cursor is the middle of the window, + * that is, {window_width/2, window_height/2}. + * The cursor will be moved to this origin when a * native cursor is set and the previous cursor is null. * * @param cursor the native cursor object to bind. May be null. diff --git a/src/native/linux/org_lwjgl_input_Mouse.cpp b/src/native/linux/org_lwjgl_input_Mouse.cpp index 792c86d8..26b4a976 100644 --- a/src/native/linux/org_lwjgl_input_Mouse.cpp +++ b/src/native/linux/org_lwjgl_input_Mouse.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include "org_lwjgl_input_Mouse.h" #include "extxcursor.h" @@ -87,11 +88,19 @@ static int cap(int val, int min, int max) { } static void setCursorPos(int x, int y) { - y = getWindowHeight() - 1 - y; current_x = cap(x, 0, getWindowWidth() - 1); current_y = cap(y, 0, getWindowHeight() - 1); } +static void centerCursor() { + // transform to OpenGL coordinate system center + int x = getWindowWidth()/2; + int y = (int)ceil(getWindowHeight()/2.0f); + setCursorPos(x, y); + last_x = current_x; + last_y = current_y; +} + /* * Class: org_lwjgl_input_Mouse * Method: initIDs @@ -179,6 +188,37 @@ void releasePointer(void) { updateGrab(); } +static void doWarpPointer(void ) { + centerCursor(); + XWarpPointer(getCurrentDisplay(), None, getCurrentWindow(), 0, 0, 0, 0, current_x, current_y); + XEvent event; + // Try to catch the warp pointer event + for (int i = 0; i < WARP_RETRY; i++) { + XMaskEvent(getCurrentDisplay(), PointerMotionMask, &event); + if (event.xmotion.x > current_x - POINTER_WARP_BORDER && + event.xmotion.x < current_x + POINTER_WARP_BORDER && + event.xmotion.y > current_y - POINTER_WARP_BORDER && + event.xmotion.y < current_y + POINTER_WARP_BORDER) + break; +#ifdef _DEBUG + printf("Skipped event searching for warp event %d, %d\n", event.xmotion.x, event.xmotion.y); +#endif + } +#ifdef _DEBUG + if (i == WARP_RETRY) + printf("Never got warp event\n"); +#endif +} + +static void warpPointer(void) { + if (!pointer_grabbed || native_cursor) + return; + // Reset pointer to middle of screen if outside a certain inner border + if (current_x < POINTER_WARP_BORDER || current_y < POINTER_WARP_BORDER || + current_x > getWindowWidth() - POINTER_WARP_BORDER || current_y > getWindowHeight() - POINTER_WARP_BORDER) + doWarpPointer(); +} + /* * Class: org_lwjgl_input_Mouse * Method: nIsNativeCursorSupported @@ -209,8 +249,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nSetNativeCursor if (cursor_handle != 0) { Cursor cursor = (Cursor)cursor_handle; if (!native_cursor) { - setCursorPos(0, 0); - XWarpPointer(getCurrentDisplay(), None, getCurrentWindow(), 0, 0, 0, 0, current_x, current_y); + doWarpPointer(); native_cursor = true; } XDefineCursor(getCurrentDisplay(), getCurrentWindow(), cursor); @@ -271,8 +310,8 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nCreate (JNIEnv * env, jclass clazz) { int i; - setCursorPos(0, 0); - current_z = last_x = last_y = last_z = 0; + centerCursor(); + current_z = last_z = 0; for (i = 0; i < NUM_BUTTONS; i++) buttons[i] = JNI_FALSE; if (!blankCursor()) { @@ -351,37 +390,6 @@ void handlePointerMotion(XMotionEvent *event) { setCursorPos(event->x, event->y); } -static void warpPointer(void) { - int i; - if (!pointer_grabbed || native_cursor) - return; - // Reset pointer to middle of screen if inside a certain inner border - if (current_x < POINTER_WARP_BORDER || current_y < POINTER_WARP_BORDER || - current_x > getWindowWidth() - POINTER_WARP_BORDER || current_y > getWindowHeight() - POINTER_WARP_BORDER) { - setCursorPos(getWindowWidth()>>1, getWindowHeight()>>1); - last_x = current_x; - last_y = current_y; - XWarpPointer(getCurrentDisplay(), None, getCurrentWindow(), 0, 0, 0, 0, current_x, current_y); - XEvent event; - // Try to catch the warp pointer event - for (i = 0; i < WARP_RETRY; i++) { - XMaskEvent(getCurrentDisplay(), PointerMotionMask, &event); - if (event.xmotion.x > current_x - POINTER_WARP_BORDER && - event.xmotion.x < current_x + POINTER_WARP_BORDER && - event.xmotion.y > current_y - POINTER_WARP_BORDER && - event.xmotion.y < current_y + POINTER_WARP_BORDER) - break; -#ifdef _DEBUG - printf("Skipped event searching for warp event %d, %d\n", event.xmotion.x, event.xmotion.y); -#endif - } -#ifdef _DEBUG - if (i == WARP_RETRY) - printf("Never got warp event\n"); -#endif - } -} - /* * Class: org_lwjgl_input_Mouse * Method: nPoll @@ -394,7 +402,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nPoll int moved_y = current_y - last_y; int moved_z = current_z - last_z; env->SetStaticIntField(clazz, fid_dx, (jint)moved_x); - env->SetStaticIntField(clazz, fid_dy, (jint)moved_y); + env->SetStaticIntField(clazz, fid_dy, (jint)-moved_y); env->SetStaticIntField(clazz, fid_dwheel, (jint)moved_z); last_x = current_x; last_y = current_y; diff --git a/src/native/win32/org_lwjgl_input_Mouse.cpp b/src/native/win32/org_lwjgl_input_Mouse.cpp index 7ab86d83..0de461a6 100644 --- a/src/native/win32/org_lwjgl_input_Mouse.cpp +++ b/src/native/win32/org_lwjgl_input_Mouse.cpp @@ -41,6 +41,7 @@ #define WIN32_LEAN_AND_MEAN #include "org_lwjgl_input_Mouse.h" #include +#include #undef DIRECTINPUT_VERSION #define DIRECTINPUT_VERSION 0x0300 #include "Window.h" @@ -49,13 +50,11 @@ static LPDIRECTINPUTDEVICE mDIDevice; // DI Device instance static int mButtoncount = 0; // Temporary buttoncount static bool mHaswheel; // Temporary wheel check -static JNIEnv* mEnvironment; // JNIEnvironment copy static bool mCreate_success; // bool used to determine successfull creation static bool mFirstTimeInitialization = true; // boolean to determine first time initialization // Cached fields of Mouse.java -static jclass clsMouse; static jfieldID fidMButtons; static jfieldID fidMDX; static jfieldID fidMDY; @@ -72,8 +71,8 @@ void ShutdownMouse(); void CreateMouse(); void SetupMouse(); void InitializeMouseFields(); -void CacheMouseFields(); -void UpdateMouseFields(); +void CacheMouseFields(JNIEnv *env, jclass clsMouse); +void UpdateMouseFields(JNIEnv *env, jclass clsMouse); static void getScreenClientRect(RECT* clientRect, RECT* windowRect) { @@ -89,11 +88,8 @@ static void getScreenClientRect(RECT* clientRect, RECT* windowRect) * Initializes any field ids */ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_initIDs(JNIEnv * env, jclass clazz) { - mEnvironment = env; - clsMouse = clazz; - /* Cache fields in Mouse */ - CacheMouseFields(); + CacheMouseFields(env, clazz); } JNIEXPORT jboolean JNICALL Java_org_lwjgl_input_Mouse_nHasWheel(JNIEnv *, jclass) { @@ -110,11 +106,8 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nGetButtonCount(JNIEnv *, jcla JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nCreate(JNIEnv *env, jclass clazz) { HRESULT hr; - mEnvironment = env; - clsMouse = clazz; - ShowCursor(FALSE); - CacheMouseFields(); + CacheMouseFields(env, clazz); /* skip enumeration, since we only want system mouse */ CreateMouse(); @@ -177,12 +170,12 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nSetNativeCursor SetClassLong(hwnd, GCL_HCURSOR, (LONG)cursor); SetCursor(cursor); if (!usingNativeCursor) { - /* Reset cursor position to 0, 0 */ + /* Reset cursor position to middle of the window */ RECT clientRect; GetWindowRect(hwnd, &windowRect); getScreenClientRect(&clientRect, &windowRect); - cursorPos.x = clientRect.left; - cursorPos.y = clientRect.bottom - 1; + cursorPos.x = (clientRect.left + clientRect.right)/2; + cursorPos.y = (int)ceil((clientRect.top + clientRect.bottom)/2.0f); SetCursorPos(cursorPos.x, cursorPos.y); ShowCursor(TRUE); usingNativeCursor = true; @@ -230,8 +223,6 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nGetMinCursorSize * Signature: ()V */ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nDestroy(JNIEnv *env, jclass clazz) { - mEnvironment = env; - clsMouse = clazz; ShowCursor(TRUE); ShutdownMouse(); } @@ -243,9 +234,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nDestroy(JNIEnv *env, jclass c */ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nPoll(JNIEnv * env, jclass clazz) { mDIDevice->Acquire(); - mEnvironment = env; - clsMouse = clazz; - UpdateMouseFields(); + UpdateMouseFields(env, clazz); } /** @@ -381,7 +370,7 @@ static void getGDICursorDelta(int* return_dx, int* return_dy) { /** * Updates the fields on the Mouse */ -void UpdateMouseFields() { +static void UpdateMouseFields(JNIEnv *env, jclass clsMouse) { HRESULT hRes; DIMOUSESTATE diMouseState; // State of Mouse int dx, dy; @@ -418,9 +407,9 @@ void UpdateMouseFields() { } dy = -dy; - mEnvironment->SetStaticIntField(clsMouse, fidMDX, (jint)dx); - mEnvironment->SetStaticIntField(clsMouse, fidMDY, (jint)dy); - mEnvironment->SetStaticIntField(clsMouse, fidMDWheel, (jint)diMouseState.lZ); + env->SetStaticIntField(clsMouse, fidMDX, (jint)dx); + env->SetStaticIntField(clsMouse, fidMDY, (jint)dy); + env->SetStaticIntField(clsMouse, fidMDWheel, (jint)diMouseState.lZ); for (int i = 0; i < mButtoncount; i++) { if (diMouseState.rgbButtons[i] != 0) { @@ -429,16 +418,16 @@ void UpdateMouseFields() { diMouseState.rgbButtons[i] = JNI_FALSE; } } - jbooleanArray mButtonsArray = (jbooleanArray) mEnvironment->GetStaticObjectField(clsMouse, fidMButtons); - mEnvironment->SetBooleanArrayRegion(mButtonsArray, 0, mButtoncount, diMouseState.rgbButtons); + jbooleanArray mButtonsArray = (jbooleanArray) env->GetStaticObjectField(clsMouse, fidMButtons); + env->SetBooleanArrayRegion(mButtonsArray, 0, mButtoncount, diMouseState.rgbButtons); } /** * Caches the field ids for quicker access */ -void CacheMouseFields() { - fidMButtons = mEnvironment->GetStaticFieldID(clsMouse, "buttons", "[Z"); - fidMDX = mEnvironment->GetStaticFieldID(clsMouse, "dx", "I"); - fidMDY = mEnvironment->GetStaticFieldID(clsMouse, "dy", "I"); - fidMDWheel = mEnvironment->GetStaticFieldID(clsMouse, "dwheel", "I"); +void CacheMouseFields(JNIEnv* env, jclass clsMouse) { + fidMButtons = env->GetStaticFieldID(clsMouse, "buttons", "[Z"); + fidMDX = env->GetStaticFieldID(clsMouse, "dx", "I"); + fidMDY = env->GetStaticFieldID(clsMouse, "dy", "I"); + fidMDWheel = env->GetStaticFieldID(clsMouse, "dwheel", "I"); }