Moved native cursor origin to middle of the window
This commit is contained in:
parent
9c427cd029
commit
43b2d67a71
|
@ -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.
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include <X11/extensions/xf86vmode.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <Window.h>
|
||||
#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;
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#define WIN32_LEAN_AND_MEAN
|
||||
#include "org_lwjgl_input_Mouse.h"
|
||||
#include <windows.h>
|
||||
#include <math.h>
|
||||
#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");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue