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
|
* NOTE: The native cursor is not constrained to the window, but
|
||||||
* relative events will not be generated if the cursor is outside.
|
* 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 initial position of the cursor is the middle of the window,
|
||||||
* the window, and the cursor will be moved to this origin when a
|
* 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.
|
* native cursor is set and the previous cursor is null.
|
||||||
*
|
*
|
||||||
* @param cursor the native cursor object to bind. May be null.
|
* @param cursor the native cursor object to bind. May be null.
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include <X11/extensions/xf86vmode.h>
|
#include <X11/extensions/xf86vmode.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
#include <Window.h>
|
#include <Window.h>
|
||||||
#include "org_lwjgl_input_Mouse.h"
|
#include "org_lwjgl_input_Mouse.h"
|
||||||
#include "extxcursor.h"
|
#include "extxcursor.h"
|
||||||
|
@ -87,11 +88,19 @@ static int cap(int val, int min, int max) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setCursorPos(int x, int y) {
|
static void setCursorPos(int x, int y) {
|
||||||
y = getWindowHeight() - 1 - y;
|
|
||||||
current_x = cap(x, 0, getWindowWidth() - 1);
|
current_x = cap(x, 0, getWindowWidth() - 1);
|
||||||
current_y = cap(y, 0, getWindowHeight() - 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
|
* Class: org_lwjgl_input_Mouse
|
||||||
* Method: initIDs
|
* Method: initIDs
|
||||||
|
@ -179,6 +188,37 @@ void releasePointer(void) {
|
||||||
updateGrab();
|
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
|
* Class: org_lwjgl_input_Mouse
|
||||||
* Method: nIsNativeCursorSupported
|
* Method: nIsNativeCursorSupported
|
||||||
|
@ -209,8 +249,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nSetNativeCursor
|
||||||
if (cursor_handle != 0) {
|
if (cursor_handle != 0) {
|
||||||
Cursor cursor = (Cursor)cursor_handle;
|
Cursor cursor = (Cursor)cursor_handle;
|
||||||
if (!native_cursor) {
|
if (!native_cursor) {
|
||||||
setCursorPos(0, 0);
|
doWarpPointer();
|
||||||
XWarpPointer(getCurrentDisplay(), None, getCurrentWindow(), 0, 0, 0, 0, current_x, current_y);
|
|
||||||
native_cursor = true;
|
native_cursor = true;
|
||||||
}
|
}
|
||||||
XDefineCursor(getCurrentDisplay(), getCurrentWindow(), cursor);
|
XDefineCursor(getCurrentDisplay(), getCurrentWindow(), cursor);
|
||||||
|
@ -271,8 +310,8 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nCreate
|
||||||
(JNIEnv * env, jclass clazz)
|
(JNIEnv * env, jclass clazz)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
setCursorPos(0, 0);
|
centerCursor();
|
||||||
current_z = last_x = last_y = last_z = 0;
|
current_z = last_z = 0;
|
||||||
for (i = 0; i < NUM_BUTTONS; i++)
|
for (i = 0; i < NUM_BUTTONS; i++)
|
||||||
buttons[i] = JNI_FALSE;
|
buttons[i] = JNI_FALSE;
|
||||||
if (!blankCursor()) {
|
if (!blankCursor()) {
|
||||||
|
@ -351,37 +390,6 @@ void handlePointerMotion(XMotionEvent *event) {
|
||||||
setCursorPos(event->x, event->y);
|
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
|
* Class: org_lwjgl_input_Mouse
|
||||||
* Method: nPoll
|
* Method: nPoll
|
||||||
|
@ -394,7 +402,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nPoll
|
||||||
int moved_y = current_y - last_y;
|
int moved_y = current_y - last_y;
|
||||||
int moved_z = current_z - last_z;
|
int moved_z = current_z - last_z;
|
||||||
env->SetStaticIntField(clazz, fid_dx, (jint)moved_x);
|
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);
|
env->SetStaticIntField(clazz, fid_dwheel, (jint)moved_z);
|
||||||
last_x = current_x;
|
last_x = current_x;
|
||||||
last_y = current_y;
|
last_y = current_y;
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include "org_lwjgl_input_Mouse.h"
|
#include "org_lwjgl_input_Mouse.h"
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <math.h>
|
||||||
#undef DIRECTINPUT_VERSION
|
#undef DIRECTINPUT_VERSION
|
||||||
#define DIRECTINPUT_VERSION 0x0300
|
#define DIRECTINPUT_VERSION 0x0300
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
|
@ -49,13 +50,11 @@
|
||||||
static LPDIRECTINPUTDEVICE mDIDevice; // DI Device instance
|
static LPDIRECTINPUTDEVICE mDIDevice; // DI Device instance
|
||||||
static int mButtoncount = 0; // Temporary buttoncount
|
static int mButtoncount = 0; // Temporary buttoncount
|
||||||
static bool mHaswheel; // Temporary wheel check
|
static bool mHaswheel; // Temporary wheel check
|
||||||
static JNIEnv* mEnvironment; // JNIEnvironment copy
|
|
||||||
|
|
||||||
static bool mCreate_success; // bool used to determine successfull creation
|
static bool mCreate_success; // bool used to determine successfull creation
|
||||||
static bool mFirstTimeInitialization = true; // boolean to determine first time initialization
|
static bool mFirstTimeInitialization = true; // boolean to determine first time initialization
|
||||||
|
|
||||||
// Cached fields of Mouse.java
|
// Cached fields of Mouse.java
|
||||||
static jclass clsMouse;
|
|
||||||
static jfieldID fidMButtons;
|
static jfieldID fidMButtons;
|
||||||
static jfieldID fidMDX;
|
static jfieldID fidMDX;
|
||||||
static jfieldID fidMDY;
|
static jfieldID fidMDY;
|
||||||
|
@ -72,8 +71,8 @@ void ShutdownMouse();
|
||||||
void CreateMouse();
|
void CreateMouse();
|
||||||
void SetupMouse();
|
void SetupMouse();
|
||||||
void InitializeMouseFields();
|
void InitializeMouseFields();
|
||||||
void CacheMouseFields();
|
void CacheMouseFields(JNIEnv *env, jclass clsMouse);
|
||||||
void UpdateMouseFields();
|
void UpdateMouseFields(JNIEnv *env, jclass clsMouse);
|
||||||
|
|
||||||
static void getScreenClientRect(RECT* clientRect, RECT* windowRect)
|
static void getScreenClientRect(RECT* clientRect, RECT* windowRect)
|
||||||
{
|
{
|
||||||
|
@ -89,11 +88,8 @@ static void getScreenClientRect(RECT* clientRect, RECT* windowRect)
|
||||||
* Initializes any field ids
|
* Initializes any field ids
|
||||||
*/
|
*/
|
||||||
JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_initIDs(JNIEnv * env, jclass clazz) {
|
JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_initIDs(JNIEnv * env, jclass clazz) {
|
||||||
mEnvironment = env;
|
|
||||||
clsMouse = clazz;
|
|
||||||
|
|
||||||
/* Cache fields in Mouse */
|
/* Cache fields in Mouse */
|
||||||
CacheMouseFields();
|
CacheMouseFields(env, clazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jboolean JNICALL Java_org_lwjgl_input_Mouse_nHasWheel(JNIEnv *, jclass) {
|
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) {
|
JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nCreate(JNIEnv *env, jclass clazz) {
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
mEnvironment = env;
|
|
||||||
clsMouse = clazz;
|
|
||||||
|
|
||||||
ShowCursor(FALSE);
|
ShowCursor(FALSE);
|
||||||
CacheMouseFields();
|
CacheMouseFields(env, clazz);
|
||||||
|
|
||||||
/* skip enumeration, since we only want system mouse */
|
/* skip enumeration, since we only want system mouse */
|
||||||
CreateMouse();
|
CreateMouse();
|
||||||
|
@ -177,12 +170,12 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nSetNativeCursor
|
||||||
SetClassLong(hwnd, GCL_HCURSOR, (LONG)cursor);
|
SetClassLong(hwnd, GCL_HCURSOR, (LONG)cursor);
|
||||||
SetCursor(cursor);
|
SetCursor(cursor);
|
||||||
if (!usingNativeCursor) {
|
if (!usingNativeCursor) {
|
||||||
/* Reset cursor position to 0, 0 */
|
/* Reset cursor position to middle of the window */
|
||||||
RECT clientRect;
|
RECT clientRect;
|
||||||
GetWindowRect(hwnd, &windowRect);
|
GetWindowRect(hwnd, &windowRect);
|
||||||
getScreenClientRect(&clientRect, &windowRect);
|
getScreenClientRect(&clientRect, &windowRect);
|
||||||
cursorPos.x = clientRect.left;
|
cursorPos.x = (clientRect.left + clientRect.right)/2;
|
||||||
cursorPos.y = clientRect.bottom - 1;
|
cursorPos.y = (int)ceil((clientRect.top + clientRect.bottom)/2.0f);
|
||||||
SetCursorPos(cursorPos.x, cursorPos.y);
|
SetCursorPos(cursorPos.x, cursorPos.y);
|
||||||
ShowCursor(TRUE);
|
ShowCursor(TRUE);
|
||||||
usingNativeCursor = true;
|
usingNativeCursor = true;
|
||||||
|
@ -230,8 +223,6 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nGetMinCursorSize
|
||||||
* Signature: ()V
|
* Signature: ()V
|
||||||
*/
|
*/
|
||||||
JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nDestroy(JNIEnv *env, jclass clazz) {
|
JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nDestroy(JNIEnv *env, jclass clazz) {
|
||||||
mEnvironment = env;
|
|
||||||
clsMouse = clazz;
|
|
||||||
ShowCursor(TRUE);
|
ShowCursor(TRUE);
|
||||||
ShutdownMouse();
|
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) {
|
JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nPoll(JNIEnv * env, jclass clazz) {
|
||||||
mDIDevice->Acquire();
|
mDIDevice->Acquire();
|
||||||
mEnvironment = env;
|
UpdateMouseFields(env, clazz);
|
||||||
clsMouse = clazz;
|
|
||||||
UpdateMouseFields();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -381,7 +370,7 @@ static void getGDICursorDelta(int* return_dx, int* return_dy) {
|
||||||
/**
|
/**
|
||||||
* Updates the fields on the Mouse
|
* Updates the fields on the Mouse
|
||||||
*/
|
*/
|
||||||
void UpdateMouseFields() {
|
static void UpdateMouseFields(JNIEnv *env, jclass clsMouse) {
|
||||||
HRESULT hRes;
|
HRESULT hRes;
|
||||||
DIMOUSESTATE diMouseState; // State of Mouse
|
DIMOUSESTATE diMouseState; // State of Mouse
|
||||||
int dx, dy;
|
int dx, dy;
|
||||||
|
@ -418,9 +407,9 @@ void UpdateMouseFields() {
|
||||||
}
|
}
|
||||||
dy = -dy;
|
dy = -dy;
|
||||||
|
|
||||||
mEnvironment->SetStaticIntField(clsMouse, fidMDX, (jint)dx);
|
env->SetStaticIntField(clsMouse, fidMDX, (jint)dx);
|
||||||
mEnvironment->SetStaticIntField(clsMouse, fidMDY, (jint)dy);
|
env->SetStaticIntField(clsMouse, fidMDY, (jint)dy);
|
||||||
mEnvironment->SetStaticIntField(clsMouse, fidMDWheel, (jint)diMouseState.lZ);
|
env->SetStaticIntField(clsMouse, fidMDWheel, (jint)diMouseState.lZ);
|
||||||
|
|
||||||
for (int i = 0; i < mButtoncount; i++) {
|
for (int i = 0; i < mButtoncount; i++) {
|
||||||
if (diMouseState.rgbButtons[i] != 0) {
|
if (diMouseState.rgbButtons[i] != 0) {
|
||||||
|
@ -429,16 +418,16 @@ void UpdateMouseFields() {
|
||||||
diMouseState.rgbButtons[i] = JNI_FALSE;
|
diMouseState.rgbButtons[i] = JNI_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
jbooleanArray mButtonsArray = (jbooleanArray) mEnvironment->GetStaticObjectField(clsMouse, fidMButtons);
|
jbooleanArray mButtonsArray = (jbooleanArray) env->GetStaticObjectField(clsMouse, fidMButtons);
|
||||||
mEnvironment->SetBooleanArrayRegion(mButtonsArray, 0, mButtoncount, diMouseState.rgbButtons);
|
env->SetBooleanArrayRegion(mButtonsArray, 0, mButtoncount, diMouseState.rgbButtons);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Caches the field ids for quicker access
|
* Caches the field ids for quicker access
|
||||||
*/
|
*/
|
||||||
void CacheMouseFields() {
|
void CacheMouseFields(JNIEnv* env, jclass clsMouse) {
|
||||||
fidMButtons = mEnvironment->GetStaticFieldID(clsMouse, "buttons", "[Z");
|
fidMButtons = env->GetStaticFieldID(clsMouse, "buttons", "[Z");
|
||||||
fidMDX = mEnvironment->GetStaticFieldID(clsMouse, "dx", "I");
|
fidMDX = env->GetStaticFieldID(clsMouse, "dx", "I");
|
||||||
fidMDY = mEnvironment->GetStaticFieldID(clsMouse, "dy", "I");
|
fidMDY = env->GetStaticFieldID(clsMouse, "dy", "I");
|
||||||
fidMDWheel = mEnvironment->GetStaticFieldID(clsMouse, "dwheel", "I");
|
fidMDWheel = env->GetStaticFieldID(clsMouse, "dwheel", "I");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue