diff --git a/src/java/org/lwjgl/input/Keyboard.java b/src/java/org/lwjgl/input/Keyboard.java index 367c340c..628a35b5 100644 --- a/src/java/org/lwjgl/input/Keyboard.java +++ b/src/java/org/lwjgl/input/Keyboard.java @@ -377,18 +377,18 @@ public class Keyboard { */ public static int enableBuffer() throws Exception { assert created : "The keyboard has not been created."; - int buf_len = nEnableBuffer(); + readBuffer = nEnableBuffer(); if (readBuffer != null) readBuffer.order(ByteOrder.nativeOrder()); - return buf_len; + return readBuffer.capacity()/2; } /** * Native method to enable the buffer - * @return the size of the buffer allocated, in events (1 event is 2 bytes), - * or 0 if no buffer can be allocated + * @return the event buffer, + * or null if no buffer can be allocated */ - private static native int nEnableBuffer() throws Exception; + private static native ByteBuffer nEnableBuffer() throws Exception; /** * Checks to see if a key is down. diff --git a/src/java/org/lwjgl/input/Mouse.java b/src/java/org/lwjgl/input/Mouse.java index e5e9140c..aebb3ecf 100644 --- a/src/java/org/lwjgl/input/Mouse.java +++ b/src/java/org/lwjgl/input/Mouse.java @@ -34,6 +34,8 @@ package org.lwjgl.input; import java.util.HashMap; import java.util.Map; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; import org.lwjgl.*; @@ -59,7 +61,7 @@ public class Mouse { private static boolean created; /** The mouse buttons status from the last poll */ - private static boolean[] buttons; + private static byte[] buttons; /** Delta X */ public static int dx; @@ -86,6 +88,18 @@ public class Mouse { /** Lazy initialization */ private static boolean initialized; + /** + * The mouse button events from the last read: a sequence of pairs of button number, + * followed by state. + */ + private static ByteBuffer readBuffer; + + /** The current mouse event button being examined */ + public static int button; + + /** The current state of the button being examined in the event queue */ + public static boolean state; + /** * Mouse cannot be constructed. */ @@ -218,7 +232,7 @@ public class Mouse { // set mouse buttons buttonCount = nGetButtonCount(); - buttons = new boolean[buttonCount]; + buttons = new byte[buttonCount]; } private static native boolean nHasWheel(); @@ -283,7 +297,7 @@ public class Mouse { if (button >= buttonCount) return false; else - return buttons[button]; + return buttons[button] == 1; } /** @@ -310,4 +324,57 @@ public class Mouse { return ret.intValue(); } + /** + * Enable mouse button buffering. Must be called after the mouse is created. + * @return the size of the mouse buffer in events, or 0 if no buffering + * can be enabled for any reason + */ + public static int enableBuffer() throws Exception { + assert created : "The mouse has not been created."; + readBuffer = nEnableBuffer(); + if (readBuffer != null) + readBuffer.order(ByteOrder.nativeOrder()); + return readBuffer.capacity()/2; + } + + /** + * Native method to enable the buffer + * @return the event buffer, + * or null if no buffer can be allocated + */ + private static native ByteBuffer nEnableBuffer() throws Exception; + + /** + * Reads the mouse buffer. + */ + public static void read() { + assert created : "The mouse has not been created."; + assert readBuffer != null : "Mouse buffering has not been enabled."; + int numEvents = nRead(); + readBuffer.clear(); + readBuffer.limit(numEvents << 1); + } + + /** + * Native method to read the keyboard buffer + * @return the total number of events read. + */ + private static native int nRead(); + + /** + * Gets the next mouse event. This is stored in the publicly accessible + * static fields button and state. + * @return true if a mouse event was read, false otherwise + */ + public static boolean next() { + assert created : "The mouse has not been created."; + assert readBuffer != null : "Mouse buffering has not been enabled."; + + if (readBuffer.hasRemaining()) { + button = readBuffer.get() & 0xFF; + state = readBuffer.get() != 0; + return true; + } else + return false; + } } diff --git a/src/native/common/Makefile.am b/src/native/common/Makefile.am index d587d188..028d1246 100644 --- a/src/native/common/Makefile.am +++ b/src/native/common/Makefile.am @@ -7,6 +7,8 @@ COMMON = \ extal.h \ extgl.cpp \ extgl.h \ + common_tools.cpp \ + common_tools.h \ org_lwjgl_Display.h \ org_lwjgl_Sys.h \ org_lwjgl_input_GamePad.h \ diff --git a/src/native/common/common_tools.cpp b/src/native/common/common_tools.cpp new file mode 100644 index 00000000..8bb80fc3 --- /dev/null +++ b/src/native/common/common_tools.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2002 Light Weight Java Game Library Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'Light Weight Java Game Library' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * $Id$ + * + * @author elias_naur + * @version $Revision$ + */ + +#include "common_tools.h" + +void initEventQueue(event_queue_t *event_queue) { + event_queue->list_start = 0; + event_queue->list_end = 0; +} + +void putEventElement(event_queue_t *queue, unsigned char byte) { + int next_index = (queue->list_end + 1)%EVENT_BUFFER_SIZE; + if (next_index == queue->list_start) { +#ifdef _DEBUG + printf("Keyboard buffer overflow!\n"); +#endif + return; + } + queue->input_event_buffer[queue->list_end] = byte; + 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, int event_size, int event_index) { + int output_index = event_index*event_size; + for (int i = 0; i < event_size; i++) { + queue->output_event_buffer[output_index] = queue->input_event_buffer[queue->list_start]; + queue->list_start = (queue->list_start + 1)%EVENT_BUFFER_SIZE; + output_index++; + } +} + +int copyEvents(event_queue_t *event_queue, int event_size) { + int num_events = 0; + while (hasMoreEvents(event_queue)) { + copyEvent(event_queue, event_size, num_events); + num_events++; + } + return num_events; +} + +unsigned char *getOutputList(event_queue_t *queue) { + return queue->output_event_buffer; +} + +int getEventBufferSize(event_queue_t *event_queue) { + return EVENT_BUFFER_SIZE; +} + +void throwException(JNIEnv * env, const char * err) { + jclass cls = env->FindClass("java/lang/Exception"); + env->ThrowNew(cls, err); + env->DeleteLocalRef(cls); +} diff --git a/src/native/common/common_tools.h b/src/native/common/common_tools.h new file mode 100644 index 00000000..377d4f7d --- /dev/null +++ b/src/native/common/common_tools.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2002 Light Weight Java Game Library Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'Light Weight Java Game Library' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * $Id$ + * + * @author elias_naur + * @version $Revision$ + */ + +#ifndef _COMMON_TOOLS_H +#define _COMMON_TOOLS_H + +#include + +#define EVENT_BUFFER_SIZE 100 + +typedef struct { + unsigned char input_event_buffer[EVENT_BUFFER_SIZE]; + unsigned char output_event_buffer[EVENT_BUFFER_SIZE]; + + int list_start; + int list_end; +} event_queue_t; + +extern void initEventQueue(event_queue_t *event_queue); +extern int copyEvents(event_queue_t *event_queue, int event_size); +extern void putEventElement(event_queue_t *queue, unsigned char byte); +extern unsigned char *getOutputList(event_queue_t *queue); +extern int getEventBufferSize(event_queue_t *event_queue); +extern void throwException(JNIEnv *env, const char *msg); + +#endif diff --git a/src/native/common/org_lwjgl_input_Keyboard.h b/src/native/common/org_lwjgl_input_Keyboard.h index 380a007e..815d94ac 100644 --- a/src/native/common/org_lwjgl_input_Keyboard.h +++ b/src/native/common/org_lwjgl_input_Keyboard.h @@ -329,9 +329,9 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nEnableTranslation /* * Class: org_lwjgl_input_Keyboard * Method: nEnableBuffer - * Signature: ()I + * Signature: ()Ljava/nio/ByteBuffer; */ -JNIEXPORT jint JNICALL Java_org_lwjgl_input_Keyboard_nEnableBuffer +JNIEXPORT jobject JNICALL Java_org_lwjgl_input_Keyboard_nEnableBuffer (JNIEnv *, jclass); /* diff --git a/src/native/common/org_lwjgl_input_Mouse.h b/src/native/common/org_lwjgl_input_Mouse.h index 64520c16..36505324 100644 --- a/src/native/common/org_lwjgl_input_Mouse.h +++ b/src/native/common/org_lwjgl_input_Mouse.h @@ -25,6 +25,9 @@ extern "C" { /* Inaccessible static: buttonName */ /* Inaccessible static: buttonMap */ /* Inaccessible static: initialized */ +/* Inaccessible static: readBuffer */ +/* Inaccessible static: button */ +/* Inaccessible static: state */ /* Inaccessible static: class_00024org_00024lwjgl_00024input_00024Mouse */ /* * Class: org_lwjgl_input_Mouse @@ -106,6 +109,22 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nDestroy JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nPoll (JNIEnv *, jclass); +/* + * Class: org_lwjgl_input_Mouse + * Method: nEnableBuffer + * Signature: ()Ljava/nio/ByteBuffer; + */ +JNIEXPORT jobject JNICALL Java_org_lwjgl_input_Mouse_nEnableBuffer + (JNIEnv *, jclass); + +/* + * Class: org_lwjgl_input_Mouse + * Method: nRead + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nRead + (JNIEnv *, jclass); + #ifdef __cplusplus } #endif diff --git a/src/native/linux/Window.h b/src/native/linux/Window.h index fb5728be..7954a4aa 100644 --- a/src/native/linux/Window.h +++ b/src/native/linux/Window.h @@ -105,16 +105,6 @@ */ extern bool isFullscreen(void); - /* - * Utility function to throw an Exception - */ - extern void throwException(JNIEnv * env, const char * err); - - /* - * Utility function to throw a RuntimeException - */ - extern void throwRuntimeException(JNIEnv * env, const char * err); - /* * convert bit-per-pixel to bits-per-element */ diff --git a/src/native/linux/org_lwjgl_input_Controller.cpp b/src/native/linux/org_lwjgl_input_Controller.cpp index 85f0bc83..96e7b46c 100644 --- a/src/native/linux/org_lwjgl_input_Controller.cpp +++ b/src/native/linux/org_lwjgl_input_Controller.cpp @@ -38,7 +38,8 @@ * @version $Revision$ */ #include -#include +#include "Window.h" +#include "common_tools.h" #include "org_lwjgl_input_Controller.h" /** diff --git a/src/native/linux/org_lwjgl_input_Cursor.cpp b/src/native/linux/org_lwjgl_input_Cursor.cpp index faad405f..d087eab4 100644 --- a/src/native/linux/org_lwjgl_input_Cursor.cpp +++ b/src/native/linux/org_lwjgl_input_Cursor.cpp @@ -1,6 +1,7 @@ #include "org_lwjgl_input_Cursor.h" #include "extxcursor.h" #include "Window.h" +#include "common_tools.h" /* * Class: org_lwjgl_input_Cursor diff --git a/src/native/linux/org_lwjgl_input_Keyboard.cpp b/src/native/linux/org_lwjgl_input_Keyboard.cpp index f94851a7..af416e1b 100644 --- a/src/native/linux/org_lwjgl_input_Keyboard.cpp +++ b/src/native/linux/org_lwjgl_input_Keyboard.cpp @@ -44,21 +44,18 @@ #include #include #include -#include +#include "Window.h" +#include "common_tools.h" #include "org_lwjgl_input_Keyboard.h" #define KEYBOARD_BUFFER_SIZE 50 #define KEYBOARD_SIZE 256 #define KEY_EVENT_BACKLOG 40 -static unsigned char readBuffer[KEYBOARD_BUFFER_SIZE * 2]; -static jfieldID fid_readBuffer; static unsigned char key_buf[KEYBOARD_SIZE]; static unsigned char key_map[KEYBOARD_SIZE]; -static XKeyEvent saved_key_events[KEY_EVENT_BACKLOG]; -static int list_start = 0; -static int list_end = 0; +static event_queue_t event_queue; static bool keyboard_grabbed; static bool buffer_enabled; @@ -71,10 +68,7 @@ static bool should_grab = false; * Method: initIDs * Signature: ()V */ -JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_initIDs - (JNIEnv * env, jclass clazz) -{ - fid_readBuffer = env->GetStaticFieldID(clazz, "readBuffer", "Ljava/nio/ByteBuffer;"); +JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_initIDs(JNIEnv * env, jclass clazz) { } static void setRepeatMode(int mode) { @@ -161,8 +155,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nCreate translation_enabled = false; buffer_enabled = false; should_grab = true; - list_start = 0; - list_end = 0; + initEventQueue(&event_queue); updateGrab(); } @@ -178,55 +171,37 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nDestroy created = false; } -static XKeyEvent *nextEventElement(void) { - if (list_start == list_end) - return NULL; - XKeyEvent *result = &(saved_key_events[list_start]); - list_start = (list_start + 1)%KEY_EVENT_BACKLOG; - return result; -} - -static void putEventElement(XKeyEvent *event) { - int next_index = (list_end + 1)%KEY_EVENT_BACKLOG; - if (next_index == list_start) - return; - saved_key_events[list_end] = *event; - list_end = next_index; -} - static unsigned char getKeycode(XKeyEvent *event) { unsigned char keycode = (unsigned char)((event->keycode - 8) & 0xff); keycode = key_map[keycode]; return keycode; } -static int translateEvent(int *position, XKeyEvent *event) { +static int translateEvent(XKeyEvent *event) { static char temp_translation_buffer[KEYBOARD_BUFFER_SIZE]; static XComposeStatus status; int num_chars, i; - if (*position >= KEYBOARD_BUFFER_SIZE * 2) - return 0; if (event->type == KeyRelease) { - readBuffer[(*position)++] = 0; - readBuffer[(*position)++] = 0; + putEventElement(&event_queue, 0); + putEventElement(&event_queue, 0); return 0; } num_chars = XLookupString(event, temp_translation_buffer, KEYBOARD_BUFFER_SIZE, NULL, &status); if (num_chars > 0) { num_chars--; /* Assume little endian byte order */ - readBuffer[(*position)++] = temp_translation_buffer[0]; - readBuffer[(*position)++] = 0; + putEventElement(&event_queue, temp_translation_buffer[0]); + putEventElement(&event_queue, 0); for (i = 0; i < num_chars; i++) { - readBuffer[(*position)++] = 0; - readBuffer[(*position)++] = 0; - readBuffer[(*position)++] = temp_translation_buffer[i + 1]; - readBuffer[(*position)++] = 0; + putEventElement(&event_queue, 0); + putEventElement(&event_queue, 0); + putEventElement(&event_queue, temp_translation_buffer[i + 1]); + putEventElement(&event_queue, 0); } } else { - readBuffer[(*position)++] = 0; - readBuffer[(*position)++] = 0; + putEventElement(&event_queue, 0); + putEventElement(&event_queue, 0); } return num_chars; } @@ -240,6 +215,16 @@ static unsigned char eventState(XKeyEvent *event) { assert(0); } +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); + if (translation_enabled) + translateEvent(key_event); +} + void handleKeyEvent(XKeyEvent *event) { unsigned char keycode = getKeycode(event); unsigned char state = eventState(event); @@ -256,77 +241,33 @@ void handleKeyEvent(XKeyEvent *event) { } } if (buffer_enabled) - putEventElement(event); + bufferEvent(event); } -/* - * Class: org_lwjgl_input_Keyboard - * Method: nPoll - * Signature: (I)V - */ -JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nPoll - (JNIEnv * env, jclass clazz, jobject buffer) -{ +JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nPoll(JNIEnv * env, jclass clazz, jobject buffer) { unsigned char *new_keyboard_buffer = (unsigned char *)env->GetDirectBufferAddress(buffer); memcpy(new_keyboard_buffer, key_buf, KEYBOARD_SIZE*sizeof(unsigned char)); } -/* - * Class: org_lwjgl_input_Keyboard - * Method: nRead - * Signature: (I)V - */ -JNIEXPORT int JNICALL Java_org_lwjgl_input_Keyboard_nRead - (JNIEnv * env, jclass clazz) -{ - XKeyEvent *key_event; - int buf_count = 0; - int num_events = 0; - - while (buf_count < KEYBOARD_BUFFER_SIZE * 2 && (key_event = nextEventElement()) != NULL) { - num_events++; - 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); - readBuffer[buf_count++] = keycode; - readBuffer[buf_count++] = state; - if (translation_enabled) - num_events += translateEvent(&buf_count, key_event); - } - return num_events; +JNIEXPORT int JNICALL Java_org_lwjgl_input_Keyboard_nRead(JNIEnv * env, jclass clazz) { + int event_size; + if (translation_enabled) + event_size = 4; + else + event_size = 2; + return copyEvents(&event_queue, event_size); } -/* - * Class: org_lwjgl_input_Keyboard - * Method: nEnableTranslation - * Signature: ()I - */ -JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nEnableTranslation - (JNIEnv *env, jclass clazz) -{ +JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nEnableTranslation(JNIEnv *env, jclass clazz) { translation_enabled = true; } -/* - * Class: org_lwjgl_input_Keyboard - * Method: nEnableBuffer - * Signature: ()I - */ -JNIEXPORT jint JNICALL Java_org_lwjgl_input_Keyboard_nEnableBuffer - (JNIEnv * env, jclass clazz) -{ - jobject newBuffer = env->NewDirectByteBuffer(&readBuffer, KEYBOARD_BUFFER_SIZE * 2); - env->SetStaticObjectField(clazz, fid_readBuffer, newBuffer); +JNIEXPORT jobject JNICALL Java_org_lwjgl_input_Keyboard_nEnableBuffer(JNIEnv * env, jclass clazz) { + jobject newBuffer = env->NewDirectByteBuffer(getOutputList(&event_queue), getEventBufferSize(&event_queue)); buffer_enabled = true; - return KEYBOARD_BUFFER_SIZE; + return newBuffer; } -/* - * Class: org_lwjgl_input_Keyboard - * Method: nisStateKeySet - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_org_lwjgl_input_Keyboard_nisStateKeySet(JNIEnv *env, jclass clazz, jint key) -{ +JNIEXPORT jint JNICALL Java_org_lwjgl_input_Keyboard_nisStateKeySet(JNIEnv *env, jclass clazz, jint key) { return org_lwjgl_input_Keyboard_STATE_UNKNOWN; } diff --git a/src/native/linux/org_lwjgl_input_Mouse.cpp b/src/native/linux/org_lwjgl_input_Mouse.cpp index 6fb9de42..4a802ae9 100644 --- a/src/native/linux/org_lwjgl_input_Mouse.cpp +++ b/src/native/linux/org_lwjgl_input_Mouse.cpp @@ -45,7 +45,8 @@ #include #include #include -#include +#include "Window.h" +#include "common_tools.h" #include "org_lwjgl_input_Mouse.h" #include "extxcursor.h" @@ -72,7 +73,9 @@ static int last_z; static int current_x; static int current_y; static int current_z; -static unsigned char buttons[NUM_BUTTONS]; +static jbyte buttons[NUM_BUTTONS]; +static event_queue_t event_queue; +static bool buffer_enabled; static Cursor blank_cursor; static Cursor current_cursor; @@ -112,7 +115,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_initIDs (JNIEnv * env, jclass clazz) { if (fid_buttons == NULL) - fid_buttons = env->GetStaticFieldID(clazz, "buttons", "[Z"); + fid_buttons = env->GetStaticFieldID(clazz, "buttons", "[B"); if (fid_dx == NULL) fid_dx = env->GetStaticFieldID(clazz, "dx", "I"); if (fid_dy == NULL) @@ -191,11 +194,12 @@ void releasePointer(void) { } static void doWarpPointer(void ) { - centerCursor(); + int i; + 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++) { + 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 && @@ -228,12 +232,12 @@ static void warpPointer(void) { */ JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nGetNativeCursorCaps (JNIEnv *env, jclass clazz) { - int caps = 0; + int caps = 0; if (!isXcursorLoaded()) return caps; XcursorBool argb_supported = XcursorSupportsARGB(getCurrentDisplay()); XcursorBool anim_supported = XcursorSupportsAnim(getCurrentDisplay()); - if (argb_supported) + if (argb_supported) caps |= org_lwjgl_input_Mouse_CURSOR_8_BIT_ALPHA | org_lwjgl_input_Mouse_CURSOR_ONE_BIT_TRANSPARENCY; if (anim_supported) caps |= org_lwjgl_input_Mouse_CURSOR_ANIMATION; @@ -315,17 +319,19 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nCreate centerCursor(); current_z = last_z = 0; for (i = 0; i < NUM_BUTTONS; i++) - buttons[i] = JNI_FALSE; + buttons[i] = 0; if (!blankCursor()) { throwException(env, "Could not create blank cursor"); return; } current_cursor = blank_cursor; - native_cursor = false; + native_cursor = false; created = true; should_grab = true; - pointer_grabbed = false; + pointer_grabbed = false; + buffer_enabled = false; updateGrab(); + initEventQueue(&event_queue); loadXcursor(); } @@ -344,72 +350,76 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nDestroy should_grab = false; } +static unsigned char mapButton(XButtonEvent *event) { + switch (event->button) { + case Button1: + return 0; + case Button2: + return 2; + case Button3: + return 1; + default: return NUM_BUTTONS; + } +} + +static void handleButton(XButtonEvent *event, unsigned char state) { + unsigned char button_num = mapButton(event); + if (button_num == NUM_BUTTONS) + return; + buttons[button_num] = state; + if (buffer_enabled) { + putEventElement(&event_queue, button_num); + putEventElement(&event_queue, state); + } +} + void handleButtonPress(XButtonEvent *event) { if (pointer_grabbed || native_cursor) { switch (event->button) { - case Button1: - buttons[0] = JNI_TRUE; - break; - case Button2: - buttons[2] = JNI_TRUE; - break; - case Button3: - buttons[1] = JNI_TRUE; - break; case Button4: current_z += WHEEL_SCALE; break; case Button5: current_z -= WHEEL_SCALE; break; - default: assert(0); + default: break; } + handleButton(event, 1); } } void handleButtonRelease(XButtonEvent *event) { if (pointer_grabbed || native_cursor) { - switch (event->button) { - case Button1: - buttons[0] = JNI_FALSE; - break; - case Button2: - buttons[2] = JNI_FALSE; - break; - case Button3: - buttons[1] = JNI_FALSE; - break; - case Button4: /* Fall through */ - case Button5: - break; - default: assert(0); - } + handleButton(event, 0); } } void handlePointerMotion(XMotionEvent *event) { if (pointer_grabbed || native_cursor) - setCursorPos(event->x, event->y); + setCursorPos(event->x, event->y); } -/* - * Class: org_lwjgl_input_Mouse - * Method: nPoll - * Signature: ()V - */ -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) { int moved_x = current_x - last_x; - int moved_y = current_y - last_y; + 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; last_z = current_z; - jbooleanArray buttons_array = (jbooleanArray)env->GetStaticObjectField(clazz, fid_buttons); - env->SetBooleanArrayRegion(buttons_array, 0, NUM_BUTTONS, buttons); + jbyteArray buttons_array = (jbyteArray)env->GetStaticObjectField(clazz, fid_buttons); + env->SetByteArrayRegion(buttons_array, 0, NUM_BUTTONS, buttons); warpPointer(); } + +JNIEXPORT jobject JNICALL Java_org_lwjgl_input_Mouse_nEnableBuffer(JNIEnv *env, jclass clazz) { + jobject newBuffer = env->NewDirectByteBuffer(getOutputList(&event_queue), getEventBufferSize(&event_queue)); + buffer_enabled = true; + return newBuffer; +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nRead(JNIEnv *env, jclass clazz) { + return copyEvents(&event_queue, 2); +} diff --git a/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp b/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp index f1276e7f..56ebbcd7 100644 --- a/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp +++ b/src/native/linux/org_lwjgl_opengl_Pbuffer.cpp @@ -2,6 +2,7 @@ #include "org_lwjgl_opengl_Pbuffer.h" #include "extgl.h" #include "Window.h" +#include "common_tools.h" typedef struct _PbufferInfo { GLXPbuffer buffer; diff --git a/src/native/linux/org_lwjgl_opengl_Window.cpp b/src/native/linux/org_lwjgl_opengl_Window.cpp index b2a18ee9..0541944b 100644 --- a/src/native/linux/org_lwjgl_opengl_Window.cpp +++ b/src/native/linux/org_lwjgl_opengl_Window.cpp @@ -47,6 +47,7 @@ #include #include #include +#include "common_tools.h" #include "extgl.h" #include "Window.h" #include "org_lwjgl_opengl_Window.h" @@ -265,26 +266,6 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Window_update handleMessages(); } -/* - * Utility function to throw an Exception - */ -void throwException(JNIEnv * env, const char * err) -{ - jclass cls = env->FindClass("java/lang/Exception"); - env->ThrowNew(cls, err); - env->DeleteLocalRef(cls); -} - -/* - * Utility function to throw a RuntimeException - */ -void throwRuntimeException(JNIEnv * env, const char * err) -{ - jclass cls = env->FindClass("java/lang/RuntimeException"); - env->ThrowNew(cls, err); - env->DeleteLocalRef(cls); -} - void makeCurrent(void) { if (USEGLX13) glXMakeContextCurrent(getCurrentDisplay(), glx_window, glx_window, context); diff --git a/src/native/macosx/tools.cpp b/src/native/macosx/tools.cpp index 11423ca5..7503b3a9 100644 --- a/src/native/macosx/tools.cpp +++ b/src/native/macosx/tools.cpp @@ -3,11 +3,6 @@ MPCriticalRegionID critical_region; -void throwException(JNIEnv* env, const char* msg) { - jclass cls = env->FindClass("java/lang/Exception"); - env->ThrowNew(cls, msg); -} - bool registerHandler(JNIEnv* env, WindowRef win_ref, EventHandlerProcPtr func, UInt32 event_class, UInt32 event_kind) { EventTypeSpec event_type; EventHandlerUPP handler_upp = NewEventHandlerUPP(func); diff --git a/src/native/macosx/tools.h b/src/native/macosx/tools.h index 0db821fc..fd9b4a8a 100644 --- a/src/native/macosx/tools.h +++ b/src/native/macosx/tools.h @@ -7,7 +7,6 @@ #define lock() {lockLWJGL(); #define unlock() unlockLWJGL();} -extern void throwException(JNIEnv* env, const char* msg); extern bool registerHandler(JNIEnv* env, WindowRef win_ref, EventHandlerProcPtr func, UInt32 event_class, UInt32 event_kind); extern bool initLock(JNIEnv* env); extern void destroyLock(void); diff --git a/src/native/win32/Window.h b/src/native/win32/Window.h index 9231e455..27199f7f 100644 --- a/src/native/win32/Window.h +++ b/src/native/win32/Window.h @@ -85,14 +85,4 @@ */ WINDOW_H_API void closeWindow(); - /* - * Utility function to throw an Exception - */ - WINDOW_H_API void throwException(JNIEnv * env, const char * err); - - /* - * Utility function to throw a RuntimeException - */ - WINDOW_H_API void throwRuntimeException(JNIEnv * env, const char * err); - #endif /* _LWJGL_WINDOW_H_INCLUDED_ */ diff --git a/src/native/win32/org_lwjgl_Display.cpp b/src/native/win32/org_lwjgl_Display.cpp index b78dd454..6f727384 100644 --- a/src/native/win32/org_lwjgl_Display.cpp +++ b/src/native/win32/org_lwjgl_Display.cpp @@ -41,6 +41,7 @@ #include "Window.h" #include "org_lwjgl_Display.h" +#include "common_tools.h" #define WINDOWCLASSNAME "LWJGLWINDOW" diff --git a/src/native/win32/org_lwjgl_input_Controller.cpp b/src/native/win32/org_lwjgl_input_Controller.cpp index 43888e69..477e6cc0 100644 --- a/src/native/win32/org_lwjgl_input_Controller.cpp +++ b/src/native/win32/org_lwjgl_input_Controller.cpp @@ -45,7 +45,8 @@ #undef DIRECTINPUT_VERSION #define DIRECTINPUT_VERSION 0x0500 #include -#include +#include "Window.h" +#include "common_tools.h" #define CONTROLLER_AXISMAX 1000 // Maxmimum range to which we'll gauge the swing #define CONTROLLER_AXISMIN -1000 // Minimum range to which we'll gauge the swing @@ -67,13 +68,10 @@ static bool cHasrz; // Temporary rotational zaxis check static bool cHaspov; // Temporary pov check static bool cHasslider; // Temporary slider check -static JNIEnv* cEnvironment; // JNIEnvironment copy - static bool cCreate_success; // bool used to determine successfull creation static bool cFirstTimeInitialization = true; // boolean to determine first time initialization // Cached fields of Controller.java -static jclass clsController; static jfieldID fidCButtonCount; static jfieldID fidCHasXAxis; static jfieldID fidCHasRXAxis; @@ -101,20 +99,17 @@ BOOL CALLBACK EnumControllerObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LP void ShutdownController(); void CreateController(LPCDIDEVICEINSTANCE lpddi); void SetupController(); -void InitializeControllerFields(); -void CacheControllerFields(); -void UpdateControllerFields(); -void SetControllerCapabilities(); +void InitializeControllerFields(JNIEnv *env, jclass clsController); +void CacheControllerFields(JNIEnv *env, jclass clsController); +void UpdateControllerFields(JNIEnv *env, jclass clsController); +void SetControllerCapabilities(JNIEnv *env, jclass clsController); /** * Initializes any field ids */ JNIEXPORT void JNICALL Java_org_lwjgl_input_Controller_initIDs(JNIEnv * env, jclass clazz) { - cEnvironment = env; - clsController = clazz; - /* Cache fields in Controller */ - CacheControllerFields(); + CacheControllerFields(env, clazz); } /** @@ -164,17 +159,17 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Controller_nCreate(JNIEnv *env, jcla SetupController(); /* Initialize any fields on the Controller */ - InitializeControllerFields(); + InitializeControllerFields(env, clazz); /* Set capabilities */ - SetControllerCapabilities(); + SetControllerCapabilities(env, clazz); } else { if(cCreate_success) { /* Do setup of Controller */ SetupController(); /* Initialize any fields on the Controller */ - InitializeControllerFields(); + InitializeControllerFields(env, clazz); } } @@ -221,7 +216,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Controller_nPoll(JNIEnv * env, jclas return; } - UpdateControllerFields(); + UpdateControllerFields(env, clazz); } /** @@ -453,18 +448,18 @@ static void SetupController() { /** * Sets the fields on the Controller */ -static void InitializeControllerFields() { +static void InitializeControllerFields(JNIEnv *env, jclass clsController) { //create buttons array - jbooleanArray cButtonsArray = cEnvironment->NewBooleanArray(cButtoncount); + jbooleanArray cButtonsArray = env->NewBooleanArray(cButtoncount); //set buttons array - cEnvironment->SetStaticObjectField(clsController, fidCButtons, cButtonsArray); + env->SetStaticObjectField(clsController, fidCButtons, cButtonsArray); } /** * Updates the fields on the Controller */ -static void UpdateControllerFields() { +static void UpdateControllerFields(JNIEnv *env, jclass clsController) { HRESULT hRes; // get data from the Controller @@ -487,96 +482,96 @@ static void UpdateControllerFields() { //axis's if(cHasx) { - cEnvironment->SetStaticIntField(clsController, fidCX, cJS.lX); + env->SetStaticIntField(clsController, fidCX, cJS.lX); } if(cHasy) { - cEnvironment->SetStaticIntField(clsController, fidCY, cJS.lY); + env->SetStaticIntField(clsController, fidCY, cJS.lY); } if(cHasz) { - cEnvironment->SetStaticIntField(clsController, fidCZ, cJS.lZ); + env->SetStaticIntField(clsController, fidCZ, cJS.lZ); } //rotational axis if(cHasrx) { - cEnvironment->SetStaticIntField(clsController, fidCRX, cJS.lRx); + env->SetStaticIntField(clsController, fidCRX, cJS.lRx); } if(cHasry) { - cEnvironment->SetStaticIntField(clsController, fidCRY, cJS.lRy); + env->SetStaticIntField(clsController, fidCRY, cJS.lRy); } if(cHasrz) { - cEnvironment->SetStaticIntField(clsController, fidCRZ, cJS.lRz); + env->SetStaticIntField(clsController, fidCRZ, cJS.lRz); } //buttons for (int i = 0; i < cButtoncount; i++) { if (cJS.rgbButtons[i] != 0) { - cJS.rgbButtons[i] = JNI_TRUE; + cJS.rgbButtons[i] = 1; } else { - cJS.rgbButtons[i] = JNI_FALSE; + cJS.rgbButtons[i] = 0; } } - jbooleanArray buttonsArray = (jbooleanArray) cEnvironment->GetStaticObjectField(clsController, fidCButtons); - cEnvironment->SetBooleanArrayRegion(buttonsArray, 0, cButtoncount, cJS.rgbButtons); + jbyteArray buttonsArray = (jbyteArray) env->GetStaticObjectField(clsController, fidCButtons); + env->SetByteArrayRegion(buttonsArray, 0, cButtoncount, (jbyte *)cJS.rgbButtons); //pov if(cHaspov) { - cEnvironment->SetStaticIntField(clsController, fidCPOV, cJS.rgdwPOV[0]); + env->SetStaticIntField(clsController, fidCPOV, cJS.rgdwPOV[0]); } //slider if(cHasslider) { - cEnvironment->SetStaticIntField(clsController, fidCSlider, cJS.lZ); + env->SetStaticIntField(clsController, fidCSlider, cJS.lZ); } } /** * Sets the capabilities of the Controller */ -static void SetControllerCapabilities() { +static void SetControllerCapabilities(JNIEnv *env, jclass clsController) { //set buttoncount - cEnvironment->SetStaticIntField(clsController, fidCButtonCount, cButtoncount); + env->SetStaticIntField(clsController, fidCButtonCount, cButtoncount); //set axis - cEnvironment->SetStaticBooleanField(clsController, fidCHasXAxis, cHasx); - cEnvironment->SetStaticBooleanField(clsController, fidCHasYAxis, cHasy); - cEnvironment->SetStaticBooleanField(clsController, fidCHasZAxis, cHasz); + env->SetStaticBooleanField(clsController, fidCHasXAxis, cHasx); + env->SetStaticBooleanField(clsController, fidCHasYAxis, cHasy); + env->SetStaticBooleanField(clsController, fidCHasZAxis, cHasz); //set rotational axis - cEnvironment->SetStaticBooleanField(clsController, fidCHasRXAxis, cHasrx); - cEnvironment->SetStaticBooleanField(clsController, fidCHasRYAxis, cHasry); - cEnvironment->SetStaticBooleanField(clsController, fidCHasRZAxis, cHasrz); + env->SetStaticBooleanField(clsController, fidCHasRXAxis, cHasrx); + env->SetStaticBooleanField(clsController, fidCHasRYAxis, cHasry); + env->SetStaticBooleanField(clsController, fidCHasRZAxis, cHasrz); //set pov - cEnvironment->SetStaticBooleanField(clsController, fidCHasPOV, cHaspov); + env->SetStaticBooleanField(clsController, fidCHasPOV, cHaspov); //set slider - cEnvironment->SetStaticBooleanField(clsController, fidCHasSlider, cHasslider); + env->SetStaticBooleanField(clsController, fidCHasSlider, cHasslider); } /** * Caches the field ids for quicker access */ -static void CacheControllerFields() { - fidCButtonCount = cEnvironment->GetStaticFieldID(clsController, "buttonCount", "I"); - fidCHasXAxis = cEnvironment->GetStaticFieldID(clsController, "hasXAxis", "Z"); - fidCHasRXAxis = cEnvironment->GetStaticFieldID(clsController, "hasRXAxis", "Z"); - fidCHasYAxis = cEnvironment->GetStaticFieldID(clsController, "hasYAxis", "Z"); - fidCHasRYAxis = cEnvironment->GetStaticFieldID(clsController, "hasRYAxis", "Z"); - fidCHasZAxis = cEnvironment->GetStaticFieldID(clsController, "hasZAxis", "Z"); - fidCHasRZAxis = cEnvironment->GetStaticFieldID(clsController, "hasRZAxis", "Z"); - fidCHasPOV = cEnvironment->GetStaticFieldID(clsController, "hasPOV", "Z"); - fidCHasSlider = cEnvironment->GetStaticFieldID(clsController, "hasSlider", "Z"); - fidCButtons = cEnvironment->GetStaticFieldID(clsController, "buttons", "[Z"); - fidCX = cEnvironment->GetStaticFieldID(clsController, "x", "I"); - fidCRX = cEnvironment->GetStaticFieldID(clsController, "rx", "I"); - fidCY = cEnvironment->GetStaticFieldID(clsController, "y", "I"); - fidCRY = cEnvironment->GetStaticFieldID(clsController, "ry", "I"); - fidCZ = cEnvironment->GetStaticFieldID(clsController, "z", "I"); - fidCRZ = cEnvironment->GetStaticFieldID(clsController, "rz", "I"); - fidCPOV = cEnvironment->GetStaticFieldID(clsController, "pov", "I"); - fidCSlider = cEnvironment->GetStaticFieldID(clsController, "slider", "I"); +static void CacheControllerFields(JNIEnv *env, jclass clsController) { + fidCButtonCount = env->GetStaticFieldID(clsController, "buttonCount", "I"); + fidCHasXAxis = env->GetStaticFieldID(clsController, "hasXAxis", "Z"); + fidCHasRXAxis = env->GetStaticFieldID(clsController, "hasRXAxis", "Z"); + fidCHasYAxis = env->GetStaticFieldID(clsController, "hasYAxis", "Z"); + fidCHasRYAxis = env->GetStaticFieldID(clsController, "hasRYAxis", "Z"); + fidCHasZAxis = env->GetStaticFieldID(clsController, "hasZAxis", "Z"); + fidCHasRZAxis = env->GetStaticFieldID(clsController, "hasRZAxis", "Z"); + fidCHasPOV = env->GetStaticFieldID(clsController, "hasPOV", "Z"); + fidCHasSlider = env->GetStaticFieldID(clsController, "hasSlider", "Z"); + fidCButtons = env->GetStaticFieldID(clsController, "buttons", "[Z"); + fidCX = env->GetStaticFieldID(clsController, "x", "I"); + fidCRX = env->GetStaticFieldID(clsController, "rx", "I"); + fidCY = env->GetStaticFieldID(clsController, "y", "I"); + fidCRY = env->GetStaticFieldID(clsController, "ry", "I"); + fidCZ = env->GetStaticFieldID(clsController, "z", "I"); + fidCRZ = env->GetStaticFieldID(clsController, "rz", "I"); + fidCPOV = env->GetStaticFieldID(clsController, "pov", "I"); + fidCSlider = env->GetStaticFieldID(clsController, "slider", "I"); } diff --git a/src/native/win32/org_lwjgl_input_Cursor.cpp b/src/native/win32/org_lwjgl_input_Cursor.cpp index f97ece51..9983efcb 100755 --- a/src/native/win32/org_lwjgl_input_Cursor.cpp +++ b/src/native/win32/org_lwjgl_input_Cursor.cpp @@ -1,6 +1,7 @@ #include #include "org_lwjgl_input_Cursor.h" #include "Window.h" +#include "common_tools.h" /* * Class: org_lwjgl_input_Cursor diff --git a/src/native/win32/org_lwjgl_input_Keyboard.cpp b/src/native/win32/org_lwjgl_input_Keyboard.cpp index 8979985d..ebe0bd8b 100644 --- a/src/native/win32/org_lwjgl_input_Keyboard.cpp +++ b/src/native/win32/org_lwjgl_input_Keyboard.cpp @@ -46,12 +46,12 @@ #include #include "org_lwjgl_input_Keyboard.h" #include "Window.h" +#include "common_tools.h" #define KEYBOARD_BUFFER_SIZE 50 static BYTE readBuffer[KEYBOARD_BUFFER_SIZE*4]; static LPDIRECTINPUTDEVICE lpdiKeyboard = NULL; -static jfieldID fid_readBuffer; static bool translationEnabled; static bool useUnicode; @@ -64,15 +64,6 @@ static bool useUnicode; JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_initIDs (JNIEnv * env, jclass clazz) { - /* - // Get a global class instance, just to be sure - static jobject globalClassLock = NULL; - - if (globalClassLock == NULL) { - globalClassLock = env->NewGlobalRef(clazz); - } - */ - fid_readBuffer = env->GetStaticFieldID(clazz, "readBuffer", "Ljava/nio/ByteBuffer;"); } /* @@ -320,12 +311,11 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nEnableTranslation * Method: nEnableBuffer * Signature: ()I */ -JNIEXPORT jint JNICALL Java_org_lwjgl_input_Keyboard_nEnableBuffer +JNIEXPORT jobject JNICALL Java_org_lwjgl_input_Keyboard_nEnableBuffer (JNIEnv * env, jclass clazz) { jobject newBuffer = env->NewDirectByteBuffer(&readBuffer, KEYBOARD_BUFFER_SIZE*4); - env->SetStaticObjectField(clazz, fid_readBuffer, newBuffer); - return KEYBOARD_BUFFER_SIZE; + return newBuffer; } /* diff --git a/src/native/win32/org_lwjgl_input_Mouse.cpp b/src/native/win32/org_lwjgl_input_Mouse.cpp index fe5e66db..d30e527f 100644 --- a/src/native/win32/org_lwjgl_input_Mouse.cpp +++ b/src/native/win32/org_lwjgl_input_Mouse.cpp @@ -44,8 +44,11 @@ #undef DIRECTINPUT_VERSION #define DIRECTINPUT_VERSION 0x0300 #include "Window.h" +#include "common_tools.h" #include +static BYTE readBuffer[EVENT_BUFFER_SIZE]; + static LPDIRECTINPUTDEVICE mDIDevice; // DI Device instance static int mButtoncount = 0; // Temporary buttoncount static bool mHaswheel; // Temporary wheel check @@ -138,6 +141,95 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nCreate(JNIEnv *env, jclass cl } } +JNIEXPORT jobject JNICALL Java_org_lwjgl_input_Mouse_nEnableBuffer(JNIEnv * env, jclass clazz) { + jobject newBuffer = env->NewDirectByteBuffer(&readBuffer, EVENT_BUFFER_SIZE); + return newBuffer; +} + +static unsigned char mapButton(DWORD button_id) { + switch (button_id) { + case DIMOFS_BUTTON0: return 0; + case DIMOFS_BUTTON1: return 1; + case DIMOFS_BUTTON2: return 2; + case DIMOFS_BUTTON3: return 3; +/* case DIMOFS_BUTTON4: return 4; + case DIMOFS_BUTTON5: return 5; + case DIMOFS_BUTTON6: return 6; + case DIMOFS_BUTTON7: return 7;*/ + default: return mButtoncount; + } +} + +static int bufferButtons(int count, DIDEVICEOBJECTDATA *di_buffer) { + int buffer_index = 0; + for (int i = 0; i < count; i++) { + unsigned char button = mapButton(di_buffer[i].dwOfs); + if (button >= 0 && button < mButtoncount) { + unsigned char state = (unsigned char)di_buffer[i].dwData & 0x80; + if (state != 0) + state = 1; + readBuffer[buffer_index++] = button; + readBuffer[buffer_index++] = state; + if (buffer_index == EVENT_BUFFER_SIZE) + break; + } + } + return buffer_index/2; +} + +JNIEXPORT jint JNICALL Java_org_lwjgl_input_Mouse_nRead + (JNIEnv * env, jclass clazz) +{ + + static DIDEVICEOBJECTDATA rgdod[EVENT_BUFFER_SIZE]; + DWORD bufsize = EVENT_BUFFER_SIZE; + + HRESULT ret; + + ret = mDIDevice->Acquire(); + if (ret != DI_OK && ret != S_FALSE) + return 0; + + ret = mDIDevice->GetDeviceData( + sizeof(DIDEVICEOBJECTDATA), + rgdod, + &bufsize, + 0); + + if (ret == DI_OK) { + return bufferButtons(bufsize, rgdod); + } else if (ret == DI_BUFFEROVERFLOW) { +#ifdef _DEBUG + printf("Buffer overflowed\n"); +#endif + } else if (ret == DIERR_INPUTLOST) { +#ifdef _DEBUG + printf("Input lost\n"); +#endif + } else if (ret == DIERR_NOTACQUIRED) { +#ifdef _DEBUG + printf("not acquired\n"); +#endif + } else if (ret == DIERR_INVALIDPARAM) { +#ifdef _DEBUG + printf("invalid parameter\n"); +#endif + } else if (ret == DIERR_NOTBUFFERED) { +#ifdef _DEBUG + printf("not buffered\n"); +#endif + } else if (ret == DIERR_NOTINITIALIZED) { +#ifdef _DEBUG + printf("not inited\n"); +#endif + } else { +#ifdef _DEBUG + printf("unknown keyboard error\n"); +#endif + } + return 0; +} + /* * Class: org_lwjgl_input_Mouse * Method: nIsNativeCursorSupported @@ -322,7 +414,15 @@ void SetupMouse() { return; } - // set the cooperative level + DIPROPDWORD dipropdw; + dipropdw.diph.dwSize = sizeof(DIPROPDWORD); + dipropdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dipropdw.diph.dwObj = 0; + dipropdw.diph.dwHow = DIPH_DEVICE; + dipropdw.dwData = EVENT_BUFFER_SIZE; + mDIDevice->SetProperty(DIPROP_BUFFERSIZE, &dipropdw.diph); + + // set the cooperative level if(mDIDevice->SetCooperativeLevel(hwnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND) != DI_OK) { #if _DEBUG printf("SetCooperativeLevel failed\n"); @@ -425,7 +525,7 @@ static void UpdateMouseFields(JNIEnv *env, jclass clsMouse) { * Caches the field ids for quicker access */ void CacheMouseFields(JNIEnv* env, jclass clsMouse) { - fidMButtons = env->GetStaticFieldID(clsMouse, "buttons", "[Z"); + fidMButtons = env->GetStaticFieldID(clsMouse, "buttons", "[B"); fidMDX = env->GetStaticFieldID(clsMouse, "dx", "I"); fidMDY = env->GetStaticFieldID(clsMouse, "dy", "I"); fidMDWheel = env->GetStaticFieldID(clsMouse, "dwheel", "I"); diff --git a/src/native/win32/org_lwjgl_opengl_Pbuffer.cpp b/src/native/win32/org_lwjgl_opengl_Pbuffer.cpp index e36ed1ef..484469b6 100755 --- a/src/native/win32/org_lwjgl_opengl_Pbuffer.cpp +++ b/src/native/win32/org_lwjgl_opengl_Pbuffer.cpp @@ -2,6 +2,7 @@ #include "org_lwjgl_opengl_Pbuffer.h" #include "Window.h" #include "extgl.h" +#include "common_tools.h" typedef struct _PbufferInfo { HGLRC Pbuffer_context; diff --git a/src/native/win32/org_lwjgl_opengl_Window.cpp b/src/native/win32/org_lwjgl_opengl_Window.cpp index fd50c347..14c5bb58 100755 --- a/src/native/win32/org_lwjgl_opengl_Window.cpp +++ b/src/native/win32/org_lwjgl_opengl_Window.cpp @@ -41,6 +41,7 @@ #define _PRIVATE_WINDOW_H_ #include "Window.h" +#include "common_tools.h" #include "org_lwjgl_opengl_Window.h" static bool oneShotInitialised = false; // Registers the LWJGL window class @@ -64,26 +65,6 @@ static bool dirty; #define WINDOWCLASSNAME "LWJGL" -/* - * Utility function to throw an Exception - */ -void throwException(JNIEnv * env, const char * err) -{ - jclass cls = env->FindClass("java/lang/Exception"); - env->ThrowNew(cls, err); - env->DeleteLocalRef(cls); -} - -/* - * Utility function to throw a RuntimeException - */ -void throwRuntimeException(JNIEnv * env, const char * err) -{ - jclass cls = env->FindClass("java/lang/RuntimeException"); - env->ThrowNew(cls, err); - env->DeleteLocalRef(cls); -} - /* * Find an appropriate pixel format */