Make read() and poll() return absolute coordinates when the mouse is not grabbed

This commit is contained in:
Elias Naur 2004-11-12 15:01:29 +00:00
parent 47c8343728
commit 9741a99c64
2 changed files with 95 additions and 175 deletions

View File

@ -68,13 +68,6 @@ public class Mouse {
/** animation native cursor */
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 */
private static int width, height;
@ -84,18 +77,12 @@ public class Mouse {
/** The mouse buttons status from the last poll */
private static ByteBuffer buttons;
/** Mouse absolute X position in 16:16FP */
/** Mouse absolute X position in pixels */
private static int x;
/** Mouse absolute Y position in 16:16FP */
/** Mouse absolute Y position in pixels */
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 */
private static IntBuffer coord_buffer;
@ -139,6 +126,9 @@ public class Mouse {
private static int event_dx;
private static int event_dy;
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 */
private final static int BUFFER_SIZE = 50;
@ -147,9 +137,6 @@ public class Mouse {
private static boolean isGrabbed;
/** Whether absolute mouse tracking is enabled */
private static boolean trackingEnabled = true;
/**
* Mouse cannot be constructed.
*/
@ -248,10 +235,12 @@ public class Mouse {
private static void resetMouse() {
dx = dy = dwheel = 0;
width = Display.getDisplayMode().getWidth() << 16;
height = Display.getDisplayMode().getHeight() << 16;
width = Display.getDisplayMode().getWidth();
height = Display.getDisplayMode().getHeight();
x = width / 2;
y = height / 2;
if (readBuffer != null)
readBuffer.clear();
}
/**
@ -266,7 +255,7 @@ public class Mouse {
if (!initialized)
initialize();
if (created) { return; }
if (created) return;
Display.getImplementation().createMouse();
hasWheel = Display.getImplementation().hasWheel();
created = true;
@ -334,47 +323,26 @@ public class Mouse {
if (!created) throw new IllegalStateException("Mouse must be created before you can poll it");
Display.getImplementation().pollMouse(coord_buffer, buttons);
int poll_dx = coord_buffer.get(0);
int poll_dy = coord_buffer.get(1);
/* If we're grabbed, poll returns mouse deltas, if not it returns absolute coordinates */
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);
dx += poll_dx;
dy += poll_dy;
dwheel += poll_dwheel;
// Calculate the new absolute position unless tracking is disabled
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;
}
if (isGrabbed()) {
dx += poll_coord1;
dy += poll_coord2;
x += poll_coord1;
y += poll_coord2;
} else {
scrollX = 0;
scrollY = 0;
x = poll_coord1;
y = poll_coord2;
}
if (readBuffer != null) {
x = Math.min(width - 1, Math.max(0, x));
y = Math.min(height - 1, Math.max(0, y));
dwheel += poll_dwheel;
if (readBuffer != null)
read();
}
}
private static void read() {
@ -449,8 +417,17 @@ public class Mouse {
if (readBuffer.hasRemaining()) {
eventButton = readBuffer.get();
eventState = readBuffer.get() != 0;
event_dx = readBuffer.get();
event_dy = readBuffer.get();
if (isGrabbed()) {
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();
return true;
} 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() {
if (!isGrabbed())
throw new IllegalStateException("X, Y deltas are only available when the mouse is grabbed. Use getEventX()/getEventY() instead.");
return event_dx;
}
/**
* @return Current events delta y
* @return Current events delta y. Only valid when the mouse is grabbed.
*/
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 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
*/
@ -503,7 +498,7 @@ public class Mouse {
* @return Absolute x axis position of mouse
*/
public static int getX() {
return x >> 16;
return x;
}
/**
@ -513,22 +508,26 @@ public class Mouse {
* @return Absolute y axis position of mouse
*/
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() {
if (!isGrabbed())
throw new IllegalStateException("X, Y deltas are only available when the mouse is grabbed. Use getEventX()/getEventY() instead.");
int result = dx;
dx = 0;
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() {
if (!isGrabbed())
throw new IllegalStateException("X, Y deltas are only available when the mouse is grabbed. Use getEventX()/getEventY() instead.");
int result = dy;
dy = 0;
return result;
@ -550,20 +549,6 @@ public class Mouse {
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
*/
@ -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;
}
}

View File

@ -65,10 +65,8 @@ static bool created;
static int accum_dx;
static int accum_dy;
static int accum_dz;
static int last_poll_x;
static int last_poll_y;
static int last_event_x;
static int last_event_y;
static int last_x;
static int last_y;
static jbyte buttons[NUM_BUTTONS];
static event_queue_t event_queue;
static bool buffer_enabled;
@ -76,35 +74,32 @@ static bool buffer_enabled;
static Cursor blank_cursor;
static Cursor current_cursor;
static bool putMouseEvent(jint button, jint state, jint dx, jint dy, jint dz) {
jint event[] = {button, state, dx, dy, dz};
static bool putMouseEvent(jint button, jint state, jint coord1, jint coord2, jint dz) {
jint event[] = {button, state, coord1, coord2, dz};
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) {
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) {
last_poll_x = x;
last_poll_y = y;
last_event_x = x;
last_event_y = y;
last_x = x;
last_y = y;
}
static bool blankCursor(void) {
@ -241,8 +236,7 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_getButtonCount(JNIEnv
return NUM_BUTTONS;
}
static void resetCursorToCenter(void) {
resetCursor(getWindowWidth()/2, transformY(getWindowHeight()/2));
static void reset(void) {
initEventQueue(&event_queue, EVENT_SIZE);
}
@ -253,8 +247,8 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_createMouse
if (disp == NULL)
return;
int i;
last_poll_y = last_poll_x = last_event_x = last_event_y = accum_dx = accum_dy = accum_dz = 0;
resetCursorToCenter();
last_y = last_x = accum_dx = accum_dy = accum_dz = 0;
reset();
for (i = 0; i < NUM_BUTTONS; i++)
buttons[i] = 0;
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);
return;
}
coords[0] = accum_dx;
coords[1] = -accum_dy;
if (pointer_grabbed) {
coords[0] = accum_dx;
coords[1] = -accum_dy;
} else {
coords[0] = last_x;
coords[1] = transformY(last_y);
}
coords[2] = accum_dz;
accum_dx = accum_dy = accum_dz = 0;
int num_buttons = NUM_BUTTONS;
@ -397,7 +396,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_grabMouse(JNIEnv * env
unsigned int mask_return;
setGrab(new_grab == JNI_TRUE ? true : false);
resetCursorToCenter();
reset();
accum_dx = accum_dy = 0;
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);