diff --git a/src/native/linux/org_lwjgl_Display.cpp b/src/native/linux/org_lwjgl_Display.cpp index 7c878060..24fef078 100644 --- a/src/native/linux/org_lwjgl_Display.cpp +++ b/src/native/linux/org_lwjgl_Display.cpp @@ -55,6 +55,7 @@ Display * disp; int screen; Window win; +static jfieldID fid_close; static bool current_fullscreen; static bool current_focused; static bool current_minimized; @@ -62,7 +63,15 @@ static int win_width; static int win_height; static XF86VidModeModeInfo **avail_modes; static XVisualInfo * vis_info; +static Atom delete_atom; static bool gl_loaded = false; +static JNIEnv *saved_env; +static jclass saved_clazz; + +extern void handlePointerMotion(XMotionEvent *); +extern void handleButtonPress(XButtonEvent *); +extern void handleButtonRelease(XButtonEvent *); +extern void handleKeyEvent(XKeyEvent *); struct pixelformat { int bpp; @@ -192,8 +201,13 @@ void waitMapped(Display *disp, Window win) { void handleMessages(void) { XEvent event; - while (XCheckMaskEvent(disp, EnterWindowMask | LeaveWindowMask | StructureNotifyMask, &event)) { + while (XPending(disp) > 0) { + XNextEvent(disp, &event); switch (event.type) { + case ClientMessage: + if ((event.xclient.format == 32) && (event.xclient.data.l[0] == delete_atom)) + saved_env->SetStaticBooleanField(saved_clazz, fid_close, JNI_TRUE); + break; case EnterNotify: current_focused = true; break; @@ -206,6 +220,19 @@ void handleMessages(void) { case UnmapNotify: current_minimized = true; break; + case ButtonPress: + handleButtonPress(&(event.xbutton)); + break; + case ButtonRelease: + handleButtonRelease(&(event.xbutton)); + break; + case MotionNotify: + handlePointerMotion(&(event.xmotion)); + break; + case KeyPress: + case KeyRelease: + handleKeyEvent(&(event.xkey)); + break; } } } @@ -249,12 +276,12 @@ bool isFullscreen(void) { return current_fullscreen; } -bool isFocused(void) { +bool isFocused() { handleMessages(); return current_focused; } -bool isMinimized(void) { +bool isMinimized() { handleMessages(); return current_minimized; } @@ -281,6 +308,10 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_Display_isMinimized(JNIEnv *env, jclas } JNIEXPORT jboolean JNICALL Java_org_lwjgl_Display_nCreate(JNIEnv * env, jclass clazz, jint width, jint height, jint bpp, jint freq, jint alpha_bits, jint depth_bits, jint stencil_bits, jboolean fullscreen, jstring title) { + saved_env = env; + saved_clazz = clazz; + fid_close = env->GetStaticFieldID(clazz, "closeRequested", "Z"); + Window root_win; XSetWindowAttributes attribs; Colormap cmap; @@ -350,6 +381,8 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_Display_nCreate(JNIEnv * env, jclass c size_hints->max_height = height; XSetWMNormalHints(disp, win, size_hints); XFree(size_hints); + delete_atom = XInternAtom(disp, "WM_DELETE_WINDOW", False); + XSetWMProtocols(disp, win, &delete_atom, 1); XMapRaised(disp, win); waitMapped(disp, win); if (fullscreen) { diff --git a/src/native/linux/org_lwjgl_input_Keyboard.cpp b/src/native/linux/org_lwjgl_input_Keyboard.cpp index 2ba297a6..97d1429f 100644 --- a/src/native/linux/org_lwjgl_input_Keyboard.cpp +++ b/src/native/linux/org_lwjgl_input_Keyboard.cpp @@ -48,7 +48,7 @@ #define KEYBOARD_BUFFER_SIZE 50 #define KEYBOARD_SIZE 256 -#define KEY_EVENT_BACKLOG 20 +#define KEY_EVENT_BACKLOG 40 static unsigned char readBuffer[KEYBOARD_BUFFER_SIZE * 2]; static jfieldID fid_readBuffer; @@ -69,6 +69,7 @@ extern Window win; extern bool isFullscreen(void); extern bool isFocused(void); +extern void handleMessages(void); /* * Class: org_lwjgl_input_Keyboard @@ -100,7 +101,7 @@ void ungrabKeyboard(void) { XUngrabKeyboard(disp, CurrentTime); } -int updateKeyboardGrab(void) { +int updateKeyboardGrab() { if (isFullscreen()) { if (!keyboard_grabbed) return grabKeyboard(); @@ -233,6 +234,14 @@ unsigned char eventState(XKeyEvent *event) { assert(0); } +void handleKeyEvent(XKeyEvent *event) { + unsigned char keycode = getKeycode(event); + unsigned char state = eventState(event); + key_buf[keycode] = state; + if (buffer_enabled) + putEventElement(event); +} + /* * Class: org_lwjgl_input_Keyboard * Method: nPoll @@ -245,14 +254,8 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Keyboard_nPoll unsigned char state; updateKeyboardGrab(); + handleMessages(); - while (XCheckMaskEvent(disp, KeyPressMask | KeyReleaseMask, &event)) { - unsigned char keycode = getKeycode(&(event.xkey)); - state = eventState(&(event.xkey)); - key_buf[keycode] = state; - if (buffer_enabled) - putEventElement(&(event.xkey)); - } memcpy((unsigned char*)buf, key_buf, KEYBOARD_SIZE*sizeof(unsigned char)); } @@ -271,6 +274,7 @@ JNIEXPORT int JNICALL Java_org_lwjgl_input_Keyboard_nRead int num_events = 0; updateKeyboardGrab(); + handleMessages(); while (buf_count < KEYBOARD_BUFFER_SIZE * 2 && (key_event = nextEventElement()) != NULL) { num_events++; @@ -283,17 +287,6 @@ JNIEXPORT int JNICALL Java_org_lwjgl_input_Keyboard_nRead num_events += translateEvent(&buf_count, key_event); } - while (buf_count < KEYBOARD_BUFFER_SIZE * 2 && XCheckMaskEvent(disp, KeyPressMask | KeyReleaseMask, &event)) { - num_events++; - unsigned char keycode = getKeycode(&(event.xkey)); - unsigned char state = eventState(&(event.xkey)); -// printf("Reading a key %d %d count %d\n", (int)keycode, (int)state, num_events); - key_buf[keycode] = state; - readBuffer[buf_count++] = keycode; - readBuffer[buf_count++] = state; - if (translation_enabled) - num_events += translateEvent(&buf_count, &(event.xkey)); - } return num_events; } diff --git a/src/native/linux/org_lwjgl_input_Mouse.cpp b/src/native/linux/org_lwjgl_input_Mouse.cpp index 7c31375a..94aa5f4d 100644 --- a/src/native/linux/org_lwjgl_input_Mouse.cpp +++ b/src/native/linux/org_lwjgl_input_Mouse.cpp @@ -59,6 +59,7 @@ extern bool isFullscreen(void); extern bool isFocused(void); extern int getWindowWidth(void); extern int getWindowHeight(void); +extern void handleMessages(void); static bool pointer_grabbed; @@ -140,7 +141,7 @@ void ungrabPointer(void) { XUngrabPointer(disp, CurrentTime); } -int updatePointerGrab(void) { +int updatePointerGrab(JNIEnv *env, jclass clazz) { if (isFullscreen()) { if (!pointer_grabbed) return grabPointer(); @@ -179,7 +180,7 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_input_Mouse_nCreate #endif return JNI_FALSE; } - if (updatePointerGrab() != GrabSuccess) { + if (updatePointerGrab(env, clazz) != GrabSuccess) { #ifdef _DEBUG printf("Could not grab pointer\n"); #endif @@ -201,58 +202,48 @@ JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nDestroy XFreeCursor(disp, blank_cursor); } -int checkPointer() { - XEvent event; - int count = 0; - updatePointerGrab(); - while (XCheckMaskEvent(disp, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, &event)) { - count++; - switch (event.type) { - case ButtonPress: - switch (event.xbutton.button) { - case Button1: - buttons[0] = JNI_TRUE; - break; - case Button2: - buttons[1] = JNI_TRUE; - break; - case Button3: - buttons[2] = JNI_TRUE; - break; - case Button4: - current_z--; - break; - case Button5: - current_z++; - break; - default: assert(0); - } - break; - case ButtonRelease: - switch (event.xbutton.button) { - case Button1: - buttons[0] = JNI_FALSE; - break; - case Button2: - buttons[1] = JNI_FALSE; - break; - case Button3: - buttons[2] = JNI_FALSE; - break; - case Button4: /* Fall through */ - case Button5: - break; - default: assert(0); - } - break; - case MotionNotify: - current_x = event.xmotion.x; - current_y = event.xmotion.y; - break; - default: assert(0); - } +void handleButtonPress(XButtonEvent *event) { + switch (event->button) { + case Button1: + buttons[0] = JNI_TRUE; + break; + case Button2: + buttons[1] = JNI_TRUE; + break; + case Button3: + buttons[2] = JNI_TRUE; + break; + case Button4: + current_z--; + break; + case Button5: + current_z++; + break; + default: assert(0); } - return count; +} + +void handleButtonRelease(XButtonEvent *event) { + switch (event->button) { + case Button1: + buttons[0] = JNI_FALSE; + break; + case Button2: + buttons[1] = JNI_FALSE; + break; + case Button3: + buttons[2] = JNI_FALSE; + break; + case Button4: /* Fall through */ + case Button5: + break; + default: assert(0); + } +} + +void handlePointerMotion(XMotionEvent *event) { + current_x = event->x; + current_y = event->y; } void warpPointer(void) { @@ -291,7 +282,8 @@ void warpPointer(void) { JNIEXPORT void JNICALL Java_org_lwjgl_input_Mouse_nPoll (JNIEnv * env, jclass clazz) { - checkPointer(); + updatePointerGrab(env, clazz); + handleMessages(); int moved_x = current_x - last_x; int moved_y = current_y - last_y; int moved_z = current_z - last_z; diff --git a/src/native/linux/org_lwjgl_opengl_BaseGL.cpp b/src/native/linux/org_lwjgl_opengl_BaseGL.cpp index 91c12c65..1fc00303 100644 --- a/src/native/linux/org_lwjgl_opengl_BaseGL.cpp +++ b/src/native/linux/org_lwjgl_opengl_BaseGL.cpp @@ -42,11 +42,13 @@ #include "extgl.h" #include "org_lwjgl_opengl_BaseGL.h" -GLXContext context = NULL; // OpenGL rendering context +static GLXContext context = NULL; // OpenGL rendering context extern XVisualInfo * getVisualInfo(void); extern Window win; extern Display * disp; +extern void handleMessages(); + void makeCurrent(void) { glXMakeCurrent(disp, win, context); } @@ -113,6 +115,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_BaseGL_nDestroy */ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_BaseGL_swapBuffers(JNIEnv * env, jobject obj) { + handleMessages(); glXSwapBuffers(disp, win); }