Make read() and poll() return absolute coordinates when the mouse is not grabbed
This commit is contained in:
parent
47c8343728
commit
9741a99c64
|
@ -68,13 +68,6 @@ public class Mouse {
|
||||||
/** animation native cursor */
|
/** animation native cursor */
|
||||||
public final static int CURSOR_ANIMATION = 4;
|
public final static int CURSOR_ANIMATION = 4;
|
||||||
|
|
||||||
/** Mouse minimum and maximum sensitivity */
|
|
||||||
public static final int MAX_SENSITIVITY = 8;
|
|
||||||
public static final int MIN_SENSITIVITY = 1;
|
|
||||||
|
|
||||||
/** Mouse sensitivity: 1...8 */
|
|
||||||
private static int sensitivity = MAX_SENSITIVITY;
|
|
||||||
|
|
||||||
/** Mouse constraint */
|
/** Mouse constraint */
|
||||||
private static int width, height;
|
private static int width, height;
|
||||||
|
|
||||||
|
@ -84,18 +77,12 @@ public class Mouse {
|
||||||
/** The mouse buttons status from the last poll */
|
/** The mouse buttons status from the last poll */
|
||||||
private static ByteBuffer buttons;
|
private static ByteBuffer buttons;
|
||||||
|
|
||||||
/** Mouse absolute X position in 16:16FP */
|
/** Mouse absolute X position in pixels */
|
||||||
private static int x;
|
private static int x;
|
||||||
|
|
||||||
/** Mouse absolute Y position in 16:16FP */
|
/** Mouse absolute Y position in pixels */
|
||||||
private static int y;
|
private static int y;
|
||||||
|
|
||||||
/** Mouse X scroll position in 16:16FP */
|
|
||||||
private static int scrollX;
|
|
||||||
|
|
||||||
/** Mouse Y scroll position in 16:16FP */
|
|
||||||
private static int scrollY;
|
|
||||||
|
|
||||||
/** Buffer to hold the deltas dx, dy and dwheel */
|
/** Buffer to hold the deltas dx, dy and dwheel */
|
||||||
private static IntBuffer coord_buffer;
|
private static IntBuffer coord_buffer;
|
||||||
|
|
||||||
|
@ -139,6 +126,9 @@ public class Mouse {
|
||||||
private static int event_dx;
|
private static int event_dx;
|
||||||
private static int event_dy;
|
private static int event_dy;
|
||||||
private static int event_dwheel;
|
private static int event_dwheel;
|
||||||
|
/** The current absolute position of the mouse in the event queue */
|
||||||
|
private static int event_x;
|
||||||
|
private static int event_y;
|
||||||
|
|
||||||
/** Buffer size in events */
|
/** Buffer size in events */
|
||||||
private final static int BUFFER_SIZE = 50;
|
private final static int BUFFER_SIZE = 50;
|
||||||
|
@ -147,9 +137,6 @@ public class Mouse {
|
||||||
|
|
||||||
private static boolean isGrabbed;
|
private static boolean isGrabbed;
|
||||||
|
|
||||||
/** Whether absolute mouse tracking is enabled */
|
|
||||||
private static boolean trackingEnabled = true;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mouse cannot be constructed.
|
* Mouse cannot be constructed.
|
||||||
*/
|
*/
|
||||||
|
@ -248,10 +235,12 @@ public class Mouse {
|
||||||
|
|
||||||
private static void resetMouse() {
|
private static void resetMouse() {
|
||||||
dx = dy = dwheel = 0;
|
dx = dy = dwheel = 0;
|
||||||
width = Display.getDisplayMode().getWidth() << 16;
|
width = Display.getDisplayMode().getWidth();
|
||||||
height = Display.getDisplayMode().getHeight() << 16;
|
height = Display.getDisplayMode().getHeight();
|
||||||
x = width / 2;
|
x = width / 2;
|
||||||
y = height / 2;
|
y = height / 2;
|
||||||
|
if (readBuffer != null)
|
||||||
|
readBuffer.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -266,7 +255,7 @@ public class Mouse {
|
||||||
|
|
||||||
if (!initialized)
|
if (!initialized)
|
||||||
initialize();
|
initialize();
|
||||||
if (created) { return; }
|
if (created) return;
|
||||||
Display.getImplementation().createMouse();
|
Display.getImplementation().createMouse();
|
||||||
hasWheel = Display.getImplementation().hasWheel();
|
hasWheel = Display.getImplementation().hasWheel();
|
||||||
created = true;
|
created = true;
|
||||||
|
@ -334,47 +323,26 @@ public class Mouse {
|
||||||
if (!created) throw new IllegalStateException("Mouse must be created before you can poll it");
|
if (!created) throw new IllegalStateException("Mouse must be created before you can poll it");
|
||||||
Display.getImplementation().pollMouse(coord_buffer, buttons);
|
Display.getImplementation().pollMouse(coord_buffer, buttons);
|
||||||
|
|
||||||
int poll_dx = coord_buffer.get(0);
|
/* If we're grabbed, poll returns mouse deltas, if not it returns absolute coordinates */
|
||||||
int poll_dy = coord_buffer.get(1);
|
int poll_coord1 = coord_buffer.get(0);
|
||||||
|
int poll_coord2 = coord_buffer.get(1);
|
||||||
|
/* The wheel is always relative */
|
||||||
int poll_dwheel = coord_buffer.get(2);
|
int poll_dwheel = coord_buffer.get(2);
|
||||||
|
|
||||||
dx += poll_dx;
|
if (isGrabbed()) {
|
||||||
dy += poll_dy;
|
dx += poll_coord1;
|
||||||
dwheel += poll_dwheel;
|
dy += poll_coord2;
|
||||||
|
x += poll_coord1;
|
||||||
// Calculate the new absolute position unless tracking is disabled
|
y += poll_coord2;
|
||||||
if (trackingEnabled) {
|
|
||||||
x += ((poll_dx * sensitivity) << 16) / MAX_SENSITIVITY;
|
|
||||||
y += ((poll_dy * sensitivity) << 16) / MAX_SENSITIVITY;
|
|
||||||
|
|
||||||
// clamp x, y
|
|
||||||
if (x < 0) {
|
|
||||||
scrollX = x;
|
|
||||||
x = 0;
|
|
||||||
} else if (x >= width) {
|
|
||||||
scrollX = x - width;
|
|
||||||
x = width - 1;
|
|
||||||
} else {
|
|
||||||
scrollX = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y < 0) {
|
|
||||||
scrollY = y;
|
|
||||||
y = 0;
|
|
||||||
} else if (y >= height) {
|
|
||||||
scrollY = y - height;
|
|
||||||
y = height - 1;
|
|
||||||
} else {
|
|
||||||
scrollY = 0;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
scrollX = 0;
|
x = poll_coord1;
|
||||||
scrollY = 0;
|
y = poll_coord2;
|
||||||
}
|
}
|
||||||
|
x = Math.min(width - 1, Math.max(0, x));
|
||||||
if (readBuffer != null) {
|
y = Math.min(height - 1, Math.max(0, y));
|
||||||
|
dwheel += poll_dwheel;
|
||||||
|
if (readBuffer != null)
|
||||||
read();
|
read();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void read() {
|
private static void read() {
|
||||||
|
@ -449,8 +417,17 @@ public class Mouse {
|
||||||
if (readBuffer.hasRemaining()) {
|
if (readBuffer.hasRemaining()) {
|
||||||
eventButton = readBuffer.get();
|
eventButton = readBuffer.get();
|
||||||
eventState = readBuffer.get() != 0;
|
eventState = readBuffer.get() != 0;
|
||||||
event_dx = readBuffer.get();
|
if (isGrabbed()) {
|
||||||
event_dy = readBuffer.get();
|
event_dx = readBuffer.get();
|
||||||
|
event_dy = readBuffer.get();
|
||||||
|
event_x += event_dx;
|
||||||
|
event_y += event_dy;
|
||||||
|
} else {
|
||||||
|
event_x = readBuffer.get();
|
||||||
|
event_y = readBuffer.get();
|
||||||
|
}
|
||||||
|
event_x = Math.min(width - 1, Math.max(0, event_x));
|
||||||
|
event_y = Math.min(height - 1, Math.max(0, event_y));
|
||||||
event_dwheel = readBuffer.get();
|
event_dwheel = readBuffer.get();
|
||||||
return true;
|
return true;
|
||||||
} else
|
} else
|
||||||
|
@ -476,19 +453,37 @@ public class Mouse {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Current events delta x
|
* @return Current events delta x. Only valid when the mouse is grabbed.
|
||||||
*/
|
*/
|
||||||
public static int getEventDX() {
|
public static int getEventDX() {
|
||||||
|
if (!isGrabbed())
|
||||||
|
throw new IllegalStateException("X, Y deltas are only available when the mouse is grabbed. Use getEventX()/getEventY() instead.");
|
||||||
return event_dx;
|
return event_dx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Current events delta y
|
* @return Current events delta y. Only valid when the mouse is grabbed.
|
||||||
*/
|
*/
|
||||||
public static int getEventDY() {
|
public static int getEventDY() {
|
||||||
|
if (!isGrabbed())
|
||||||
|
throw new IllegalStateException("X, Y deltas are only available when the mouse is grabbed. Use getEventX()/getEventY() instead.");
|
||||||
return event_dy;
|
return event_dy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Current events absolute x. Only valid when the mouse is not grabbed.
|
||||||
|
*/
|
||||||
|
public static int getEventX() {
|
||||||
|
return event_x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Current events absolute y. Only valid when the mouse is not grabbed.
|
||||||
|
*/
|
||||||
|
public static int getEventY() {
|
||||||
|
return event_y;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Current events delta z
|
* @return Current events delta z
|
||||||
*/
|
*/
|
||||||
|
@ -503,7 +498,7 @@ public class Mouse {
|
||||||
* @return Absolute x axis position of mouse
|
* @return Absolute x axis position of mouse
|
||||||
*/
|
*/
|
||||||
public static int getX() {
|
public static int getX() {
|
||||||
return x >> 16;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -513,22 +508,26 @@ public class Mouse {
|
||||||
* @return Absolute y axis position of mouse
|
* @return Absolute y axis position of mouse
|
||||||
*/
|
*/
|
||||||
public static int getY() {
|
public static int getY() {
|
||||||
return y >> 16;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Movement on the x axis since last time getDX() was called
|
* @return Movement on the x axis since last time getDX() was called. Only valid when the mouse is grabbed.
|
||||||
*/
|
*/
|
||||||
public static int getDX() {
|
public static int getDX() {
|
||||||
|
if (!isGrabbed())
|
||||||
|
throw new IllegalStateException("X, Y deltas are only available when the mouse is grabbed. Use getEventX()/getEventY() instead.");
|
||||||
int result = dx;
|
int result = dx;
|
||||||
dx = 0;
|
dx = 0;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Movement on the y axis since last time getDY() was called
|
* @return Movement on the y axis since last time getDY() was called. Only valid when the mouse is grabbed.
|
||||||
*/
|
*/
|
||||||
public static int getDY() {
|
public static int getDY() {
|
||||||
|
if (!isGrabbed())
|
||||||
|
throw new IllegalStateException("X, Y deltas are only available when the mouse is grabbed. Use getEventX()/getEventY() instead.");
|
||||||
int result = dy;
|
int result = dy;
|
||||||
dy = 0;
|
dy = 0;
|
||||||
return result;
|
return result;
|
||||||
|
@ -550,20 +549,6 @@ public class Mouse {
|
||||||
return buttonCount;
|
return buttonCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the amount the mouse tried to move past its constraints on the X axis since the last poll
|
|
||||||
*/
|
|
||||||
public static int getScrollX() {
|
|
||||||
return scrollX >> 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the amount the mouse tried to move past its constraints on the Y axis since the last poll
|
|
||||||
*/
|
|
||||||
public static int getScrollY() {
|
|
||||||
return scrollY >> 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Whether or not this mouse has wheel support
|
* @return Whether or not this mouse has wheel support
|
||||||
*/
|
*/
|
||||||
|
@ -609,68 +594,4 @@ public class Mouse {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the mouse sensitivity, which is expressed as a value from 1 to 8.
|
|
||||||
* Values outside this range are clamped to [1..8]. 8 is the most sensitive;
|
|
||||||
* other values slow down the mouse to a minimum of 1/8th its original speed.
|
|
||||||
* @param newSensitivity The mouse sensitivity
|
|
||||||
*/
|
|
||||||
public static void setSensitivity(int newSensitivity) {
|
|
||||||
sensitivity = Math.min(MAX_SENSITIVITY, Math.max(MIN_SENSITIVITY, newSensitivity));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the current mouse sensitivity (guaranteed in the range 1..8)
|
|
||||||
*/
|
|
||||||
public static int getSensitivity() {
|
|
||||||
return sensitivity;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the absolute position of the mouse. The position is capped to the
|
|
||||||
* current size.
|
|
||||||
*
|
|
||||||
* @param newx
|
|
||||||
* @param newy
|
|
||||||
*/
|
|
||||||
public static void setPosition(int newx, int newy) {
|
|
||||||
x = Math.min(Math.max(0, newx << 16), width - 1);
|
|
||||||
y = Math.min(Math.max(0, newy << 16), height - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the dimensions of the mouse's constraint.
|
|
||||||
* @param width
|
|
||||||
* @param height
|
|
||||||
*/
|
|
||||||
public static void setDimensions(int width, int height) {
|
|
||||||
Mouse.width = width << 16;
|
|
||||||
Mouse.height = height << 16;
|
|
||||||
|
|
||||||
// Clamp the mouse absolute coordinates just in case
|
|
||||||
if (x >= Mouse.width) {
|
|
||||||
x = Mouse.width - 1;
|
|
||||||
}
|
|
||||||
if (y >= Mouse.height) {
|
|
||||||
y = Mouse.height - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable or disable absolute mouse coordinate tracking.
|
|
||||||
* @param enabled
|
|
||||||
*/
|
|
||||||
public static void setTrackingEnabled(boolean enabled) {
|
|
||||||
Mouse.trackingEnabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if mouse coordinate tracking is enabled
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public static boolean isTrackingEnabled() {
|
|
||||||
return trackingEnabled;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,10 +65,8 @@ static bool created;
|
||||||
static int accum_dx;
|
static int accum_dx;
|
||||||
static int accum_dy;
|
static int accum_dy;
|
||||||
static int accum_dz;
|
static int accum_dz;
|
||||||
static int last_poll_x;
|
static int last_x;
|
||||||
static int last_poll_y;
|
static int last_y;
|
||||||
static int last_event_x;
|
|
||||||
static int last_event_y;
|
|
||||||
static jbyte buttons[NUM_BUTTONS];
|
static jbyte buttons[NUM_BUTTONS];
|
||||||
static event_queue_t event_queue;
|
static event_queue_t event_queue;
|
||||||
static bool buffer_enabled;
|
static bool buffer_enabled;
|
||||||
|
@ -76,35 +74,32 @@ static bool buffer_enabled;
|
||||||
static Cursor blank_cursor;
|
static Cursor blank_cursor;
|
||||||
static Cursor current_cursor;
|
static Cursor current_cursor;
|
||||||
|
|
||||||
static bool putMouseEvent(jint button, jint state, jint dx, jint dy, jint dz) {
|
static bool putMouseEvent(jint button, jint state, jint coord1, jint coord2, jint dz) {
|
||||||
jint event[] = {button, state, dx, dy, dz};
|
jint event[] = {button, state, coord1, coord2, dz};
|
||||||
return putEvent(&event_queue, event);
|
return putEvent(&event_queue, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setCursorPos(int x, int y) {
|
|
||||||
jint poll_dx = x - last_poll_x;
|
|
||||||
jint poll_dy = y - last_poll_y;
|
|
||||||
accum_dx += poll_dx;
|
|
||||||
accum_dy += poll_dy;
|
|
||||||
last_poll_x = x;
|
|
||||||
last_poll_y = y;
|
|
||||||
jint event_dx = x - last_event_x;
|
|
||||||
jint event_dy = y - last_event_y;
|
|
||||||
if (putMouseEvent(-1, 0, event_dx, -event_dy, 0)) {
|
|
||||||
last_event_x = x;
|
|
||||||
last_event_y = y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int transformY(int y) {
|
static int transformY(int y) {
|
||||||
return getWindowHeight() - 1 - y;
|
return getWindowHeight() - 1 - y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setCursorPos(int x, int y) {
|
||||||
|
jint dx = x - last_x;
|
||||||
|
jint dy = y - last_y;
|
||||||
|
accum_dx += dx;
|
||||||
|
accum_dy += dy;
|
||||||
|
last_x = x;
|
||||||
|
last_y = y;
|
||||||
|
if (pointer_grabbed) {
|
||||||
|
putMouseEvent(-1, 0, dx, -dy, 0);
|
||||||
|
} else {
|
||||||
|
putMouseEvent(-1, 0, x, transformY(y), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void resetCursor(int x, int y) {
|
static void resetCursor(int x, int y) {
|
||||||
last_poll_x = x;
|
last_x = x;
|
||||||
last_poll_y = y;
|
last_y = y;
|
||||||
last_event_x = x;
|
|
||||||
last_event_y = y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool blankCursor(void) {
|
static bool blankCursor(void) {
|
||||||
|
@ -241,8 +236,7 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_getButtonCount(JNIEnv
|
||||||
return NUM_BUTTONS;
|
return NUM_BUTTONS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void resetCursorToCenter(void) {
|
static void reset(void) {
|
||||||
resetCursor(getWindowWidth()/2, transformY(getWindowHeight()/2));
|
|
||||||
initEventQueue(&event_queue, EVENT_SIZE);
|
initEventQueue(&event_queue, EVENT_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,8 +247,8 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_createMouse
|
||||||
if (disp == NULL)
|
if (disp == NULL)
|
||||||
return;
|
return;
|
||||||
int i;
|
int i;
|
||||||
last_poll_y = last_poll_x = last_event_x = last_event_y = accum_dx = accum_dy = accum_dz = 0;
|
last_y = last_x = accum_dx = accum_dy = accum_dz = 0;
|
||||||
resetCursorToCenter();
|
reset();
|
||||||
for (i = 0; i < NUM_BUTTONS; i++)
|
for (i = 0; i < NUM_BUTTONS; i++)
|
||||||
buttons[i] = 0;
|
buttons[i] = 0;
|
||||||
if (!blankCursor()) {
|
if (!blankCursor()) {
|
||||||
|
@ -368,8 +362,13 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_pollMouse(JNIEnv * env
|
||||||
printfDebug("ERROR: Not enough space in coords array: %d < 3\n", coords_length);
|
printfDebug("ERROR: Not enough space in coords array: %d < 3\n", coords_length);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
coords[0] = accum_dx;
|
if (pointer_grabbed) {
|
||||||
coords[1] = -accum_dy;
|
coords[0] = accum_dx;
|
||||||
|
coords[1] = -accum_dy;
|
||||||
|
} else {
|
||||||
|
coords[0] = last_x;
|
||||||
|
coords[1] = transformY(last_y);
|
||||||
|
}
|
||||||
coords[2] = accum_dz;
|
coords[2] = accum_dz;
|
||||||
accum_dx = accum_dy = accum_dz = 0;
|
accum_dx = accum_dy = accum_dz = 0;
|
||||||
int num_buttons = NUM_BUTTONS;
|
int num_buttons = NUM_BUTTONS;
|
||||||
|
@ -397,7 +396,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_grabMouse(JNIEnv * env
|
||||||
unsigned int mask_return;
|
unsigned int mask_return;
|
||||||
|
|
||||||
setGrab(new_grab == JNI_TRUE ? true : false);
|
setGrab(new_grab == JNI_TRUE ? true : false);
|
||||||
resetCursorToCenter();
|
reset();
|
||||||
accum_dx = accum_dy = 0;
|
accum_dx = accum_dy = 0;
|
||||||
XQueryPointer(getDisplay(), getCurrentWindow(), &root_return, &child_return, &root_x, &root_y, &win_x, &win_y, &mask_return);
|
XQueryPointer(getDisplay(), getCurrentWindow(), &root_return, &child_return, &root_x, &root_y, &win_x, &win_y, &mask_return);
|
||||||
doHandlePointerMotion(root_x, root_y, win_x, win_y);
|
doHandlePointerMotion(root_x, root_y, win_x, win_y);
|
||||||
|
|
Loading…
Reference in New Issue