Track event mouse deltas even when the event queue overflows

This commit is contained in:
Elias Naur 2004-09-27 13:20:27 +00:00
parent 0609cd371a
commit 468502cb00
4 changed files with 95 additions and 74 deletions

View file

@ -78,46 +78,64 @@ void printfDebug(const char *format, ...) {
va_end(ap);
}
static void incListStart(event_queue_t *queue) {
queue->list_start = (queue->list_start + 1)%EVENT_BUFFER_SIZE;
int getElementCapacity(event_queue_t *queue) {
return queue->limit - queue->position;
}
void initEventQueue(event_queue_t *event_queue) {
event_queue->list_start = 0;
event_queue->list_end = 0;
void initEventQueue(event_queue_t *queue, int event_size) {
queue->position = 0;
queue->limit = EVENT_BUFFER_SIZE;
queue->event_size = event_size;
}
void putEventElement(event_queue_t *queue, jint s) {
int next_index = (queue->list_end + 1)%EVENT_BUFFER_SIZE;
if (next_index == queue->list_start) {
printfDebug("Event buffer overflow!\n");
return;
}
queue->input_event_buffer[queue->list_end] = s;
queue->list_end = next_index;
}
static bool hasMoreEvents(event_queue_t *queue) {
return queue->list_start != queue->list_end;
}
static void copyEvent(event_queue_t *queue, jint *output_event_buffer, int output_index, int event_size) {
bool putEvent(event_queue_t *queue, jint *event) {
int i;
for (i = 0; i < event_size; i++) {
output_event_buffer[output_index] = queue->input_event_buffer[queue->list_start];
incListStart(queue);
if (getElementCapacity(queue) < queue->event_size) {
printfDebug("Event buffer overflow!\n");
return false;
}
for (i = 0; i < queue->event_size; i++) {
queue->input_event_buffer[queue->position] = event[i];
queue->position++;
}
return true;
}
static void flip(event_queue_t *queue) {
queue->limit = queue->position;
queue->position = 0;
}
static void compact(event_queue_t *queue) {
int new_position = 0;
while (getElementCapacity(queue) > 0) {
queue->input_event_buffer[new_position] = queue->input_event_buffer[queue->position];
queue->position++;
new_position++;
}
queue->position = new_position;
queue->limit = EVENT_BUFFER_SIZE;
}
static void copyEvent(event_queue_t *queue, jint *output_event_buffer, int output_index) {
int i;
for (i = 0; i < queue->event_size; i++) {
output_event_buffer[output_index] = queue->input_event_buffer[queue->position];
queue->position++;
output_index++;
}
}
int copyEvents(event_queue_t *event_queue, jint *output_event_buffer, int buffer_size, int event_size) {
int copyEvents(event_queue_t *queue, jint *output_event_buffer, int buffer_size) {
int num_events = 0;
int index = 0;
while (index + event_size <= buffer_size && hasMoreEvents(event_queue)) {
copyEvent(event_queue, output_event_buffer, index, event_size);
flip(queue);
while (index + queue->event_size <= buffer_size && getElementCapacity(queue) >= queue->event_size) {
copyEvent(queue, output_event_buffer, index);
num_events++;
index += event_size;
index += queue->event_size;
}
compact(queue);
return num_events;
}

View file

@ -46,15 +46,14 @@
// shared VM instance
extern JavaVM *jvm;
// Must be x * max_event_size + 1
#define EVENT_BUFFER_SIZE (25 * 4 + 1)
#define EVENT_BUFFER_SIZE 256
#define ATTRIB_LIST_SIZE (256)
typedef struct {
int event_size;
int position;
int limit;
jint input_event_buffer[EVENT_BUFFER_SIZE];
int list_start;
int list_end;
} event_queue_t;
typedef struct {
@ -124,9 +123,9 @@ extern void putAttrib(attrib_list_t *list, int attrib);
extern bool isDebugEnabled(void);
extern jstring getVersionString(JNIEnv *env);
extern void initEventQueue(event_queue_t *event_queue);
extern int copyEvents(event_queue_t *event_queue, jint *output_event_buffer, int buffer_size, int event_size);
extern void putEventElement(event_queue_t *queue, jint byte);
extern void initEventQueue(event_queue_t *event_queue, int event_size);
extern int copyEvents(event_queue_t *event_queue, jint *output_event_buffer, int buffer_size);
extern bool putEvent(event_queue_t *queue, jint *event);
extern void throwException(JNIEnv *env, const char *msg);
extern void throwOpenALException(JNIEnv * env, const char * err);
extern void throwFMODException(JNIEnv * env, const char * err);

View file

@ -120,7 +120,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nCreate
keyboard_grabbed = false;
translation_enabled = false;
buffer_enabled = false;
initEventQueue(&event_queue);
initEventQueue(&event_queue, 3);
updateKeyboardGrab();
}
@ -138,14 +138,19 @@ static unsigned char getKeycode(XKeyEvent *event) {
return keycode;
}
static int translateEvent(XKeyEvent *event) {
static void putKeyboardEvent(jint keycode, jint state, jint ch) {
int event_list[] = {keycode, state, ch};
putEvent(&event_queue, event_list);
}
static int translateEvent(XKeyEvent *event, jint keycode, jint state) {
static char temp_translation_buffer[KEYBOARD_BUFFER_SIZE];
static XComposeStatus status;
int num_chars, i;
jint ch;
if (!translation_enabled || event->type == KeyRelease) {
putEventElement(&event_queue, 0);
putKeyboardEvent(keycode, state, 0);
return 0;
}
num_chars = XLookupString(event, temp_translation_buffer, KEYBOARD_BUFFER_SIZE, NULL, &status);
@ -153,15 +158,13 @@ static int translateEvent(XKeyEvent *event) {
num_chars--;
/* Assume little endian byte order */
ch = (jint)temp_translation_buffer[0] & 0xFF;
putEventElement(&event_queue, ch);
putKeyboardEvent(keycode, state, ch);
for (i = 0; i < num_chars; i++) {
putEventElement(&event_queue, 0);
putEventElement(&event_queue, 0);
ch = ((jint)temp_translation_buffer[i + 1]) & 0xFF;
putEventElement(&event_queue, ch);
putKeyboardEvent(0, 0, ch);
}
} else {
putEventElement(&event_queue, 0);
putKeyboardEvent(keycode, state, 0);
}
return num_chars;
}
@ -179,9 +182,7 @@ static void bufferEvent(XKeyEvent *key_event) {
unsigned char keycode = getKeycode(key_event);
unsigned char state = eventState(key_event);
//printf("Reading a key %d %d count %d\n", (int)keycode, (int)state, num_events);
putEventElement(&event_queue, keycode);
putEventElement(&event_queue, state);
translateEvent(key_event);
translateEvent(key_event, keycode, state);
}
void handleKeyEvent(XKeyEvent *event) {
@ -199,11 +200,10 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nPoll(JNIEnv * env, jclass
}
JNIEXPORT int JNICALL Java_org_lwjgl_input_Keyboard_nRead(JNIEnv * env, jclass clazz, jobject buffer, jint buffer_position) {
int event_size = 3;
handleMessages();
jint* buffer_ptr = (jint *)(*env)->GetDirectBufferAddress(env, buffer);
int buffer_size = ((*env)->GetDirectBufferCapacity(env, buffer))/sizeof(jint) - buffer_position;
return copyEvents(&event_queue, buffer_ptr + buffer_position, buffer_size, event_size);
return copyEvents(&event_queue, buffer_ptr + buffer_position, buffer_size);
}
JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nEnableTranslation(JNIEnv *env, jclass clazz) {

View file

@ -53,7 +53,6 @@
#define NUM_BUTTONS 3
#define POINTER_WARP_BORDER 10
#define WARP_RETRY 5
// scale the mouse wheel according to win32
#define WHEEL_SCALE 120
@ -63,8 +62,11 @@ static bool created;
static int accum_dx;
static int accum_dy;
static int accum_dz;
static int last_x;
static int last_y;
static int last_poll_x;
static int last_poll_y;
static int last_event_x;
static int last_event_y;
static int last_z;
static jbyte buttons[NUM_BUTTONS];
static event_queue_t event_queue;
static bool buffer_enabled;
@ -72,24 +74,24 @@ static bool buffer_enabled;
static Cursor blank_cursor;
static Cursor current_cursor;
static void putEvent(jint button, jint state, jint dx, jint dy, jint dz) {
if (buffer_enabled) {
putEventElement(&event_queue, button);
putEventElement(&event_queue, state);
putEventElement(&event_queue, dx);
putEventElement(&event_queue, -dy);
putEventElement(&event_queue, dz);
}
static bool putMouseEvent(jint button, jint state, jint dx, jint dy, jint dz) {
jint event[] = {button, state, dx, dy, dz};
return putEvent(&event_queue, event);
}
static void setCursorPos(int x, int y) {
jint event_dx = x - last_x;
jint event_dy = y - last_y;
accum_dx += event_dx;
accum_dy += event_dy;
last_x = x;
last_y = y;
putEvent(-1, 0, event_dx, event_dy, 0);
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) {
@ -97,8 +99,10 @@ static int transformY(int y) {
}
static void resetCursor(int x, int y) {
last_x = x;
last_y = y;
last_poll_x = x;
last_poll_y = y;
last_event_x = x;
last_event_y = y;
}
static bool blankCursor(void) {
@ -242,7 +246,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nCreate
if (disp == NULL)
return;
int i;
last_y = last_x = accum_dx = accum_dy = accum_dz = 0;
last_z = last_poll_y = last_poll_x = last_event_x = last_event_y = accum_dx = accum_dy = accum_dz = 0;
for (i = 0; i < NUM_BUTTONS; i++)
buttons[i] = 0;
if (!blankCursor()) {
@ -255,7 +259,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nCreate
pointer_grabbed = false;
buffer_enabled = false;
updatePointerGrab();
initEventQueue(&event_queue);
initEventQueue(&event_queue, 5);
doWarpPointer(getWindowWidth()/2, getWindowHeight()/2);
}
@ -285,7 +289,7 @@ static void handleButton(XButtonEvent *event, unsigned char state) {
if (button_num == NUM_BUTTONS)
return;
buttons[button_num] = state;
putEvent(button_num, state, 0, 0, 0);
putMouseEvent(button_num, state, 0, 0, 0);
}
void handleButtonPress(XButtonEvent *event) {
@ -293,11 +297,11 @@ void handleButtonPress(XButtonEvent *event) {
switch (event->button) {
case Button4:
delta = WHEEL_SCALE;
putEvent(-1, 0, 0, 0, delta);
putMouseEvent(-1, 0, 0, 0, delta);
break;
case Button5:
delta = -WHEEL_SCALE;
putEvent(-1, 0, 0, 0, delta);
putMouseEvent(-1, 0, 0, 0, delta);
break;
default:
break;
@ -377,7 +381,7 @@ JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nRead(JNIEnv *env, jclass claz
jint* buffer_ptr = (jint *)(*env)->GetDirectBufferAddress(env, buffer);
int buffer_size = ((*env)->GetDirectBufferCapacity(env, buffer))/sizeof(jint) - buffer_position;
handleMessages();
return copyEvents(&event_queue, buffer_ptr + buffer_position, buffer_size, 5);
return copyEvents(&event_queue, buffer_ptr + buffer_position, buffer_size);
}
JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nGrabMouse(JNIEnv * env, jclass clazz, jboolean new_grab) {