From: <eli...@us...> - 2008-04-13 08:34:42
|
Revision: 3013 http://java-game-lib.svn.sourceforge.net/java-game-lib/?rev=3013&view=rev Author: elias_naur Date: 2008-04-13 01:34:39 -0700 (Sun, 13 Apr 2008) Log Message: ----------- Linux: Moved X error handling to java Modified Paths: -------------- trunk/LWJGL/src/java/org/lwjgl/opengl/LinuxDisplay.java trunk/LWJGL/src/native/linux/lwjgl.map trunk/LWJGL/src/native/linux/org_lwjgl_opengl_Display.c Modified: trunk/LWJGL/src/java/org/lwjgl/opengl/LinuxDisplay.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/opengl/LinuxDisplay.java 2008-04-12 23:09:47 UTC (rev 3012) +++ trunk/LWJGL/src/java/org/lwjgl/opengl/LinuxDisplay.java 2008-04-13 08:34:39 UTC (rev 3013) @@ -90,6 +90,7 @@ /** Current X11 Display pointer */ private static long display; private static long current_window; + private static long saved_error_handler; private static int display_connection_usage_count = 0; @@ -268,22 +269,39 @@ static void incDisplay() throws LWJGLException { if (display_connection_usage_count == 0) { GLContext.loadOpenGLLibrary(); + saved_error_handler = setErrorHandler(); display = openDisplay(); +// synchronize(display, true); } display_connection_usage_count++; } - + private static native int callErrorHandler(long handler, long display, long error_ptr); + private static native long setErrorHandler(); + private static native long resetErrorHandler(long handler); + private static native void synchronize(long display, boolean synchronize); + + private static int globalErrorHandler(long display, long event_ptr, long error_display, long serial, long error_code, long request_code, long minor_code) throws LWJGLException { + if (display == getDisplay()) { + String error_msg = getErrorText(display, error_code); + throw new LWJGLException("X Error - disp: 0x" + Long.toHexString(error_display) + " serial: " + serial + " error: " + error_msg + " request_code: " + request_code + " minor_code: " + minor_code); + } else if (saved_error_handler != 0) + callErrorHandler(saved_error_handler, display, event_ptr); + return 0; + } + private static native String getErrorText(long display, long error_code); + static void decDisplay() { + display_connection_usage_count--; + if (display_connection_usage_count < 0) + throw new InternalError("display_connection_usage_count < 0: " + display_connection_usage_count); /* * Some drivers (at least some versions of the radeon dri driver) * don't like it when the display is closed and later re-opened, * so we'll just let the singleton display connection leak. */ -/* display_connection_usage_count--; - if (display_connection_usage_count < 0) - throw new InternalError("display_connection_usage_count < 0: " + display_connection_usage_count); - if (display_connection_usage_count == 0) { +/* if (display_connection_usage_count == 0) { closeDisplay(display); + resetErrorHandler(saved_error_handler); display = 0; GLContext.unloadOpenGLLibrary(); }*/ @@ -870,15 +888,15 @@ static native long nGetInputFocus(long display); private void setInputFocusUnsafe(long window) { - setInputFocus(getDisplay(), window, CurrentTime); try { - checkXError(getDisplay()); + setInputFocus(getDisplay(), window, CurrentTime); + sync(getDisplay(), false); } catch (LWJGLException e) { // Since we don't have any event timings for XSetInputFocus, a race condition might give a BadMatch, which we'll catch and ignore LWJGLUtil.log("Got exception while trying to focus: " + e); } } - private static native void checkXError(long display) throws LWJGLException; + private static native void sync(long display, boolean throw_away_events) throws LWJGLException; private void releaseInput() { if (isLegacyFullscreen() || input_released) Modified: trunk/LWJGL/src/native/linux/lwjgl.map =================================================================== --- trunk/LWJGL/src/native/linux/lwjgl.map 2008-04-12 23:09:47 UTC (rev 3012) +++ trunk/LWJGL/src/native/linux/lwjgl.map 2008-04-13 08:34:39 UTC (rev 3013) @@ -1,4 +1,7 @@ { - global: Java_*; + global: + Java_*; + JNI_OnLoad; + JNI_OnUnload; local: *; }; Modified: trunk/LWJGL/src/native/linux/org_lwjgl_opengl_Display.c =================================================================== --- trunk/LWJGL/src/native/linux/org_lwjgl_opengl_Display.c 2008-04-12 23:09:47 UTC (rev 3012) +++ trunk/LWJGL/src/native/linux/org_lwjgl_opengl_Display.c 2008-04-13 08:34:39 UTC (rev 3013) @@ -76,35 +76,27 @@ static Visual *current_visual; -static bool async_x_error; -static char error_message[ERR_MSG_SIZE]; - static bool checkXError(JNIEnv *env, Display *disp) { XSync(disp, False); - if (async_x_error) { - async_x_error = false; - if (env != NULL) - throwException(env, error_message); - else - printfDebug(error_message); - return false; - } else - return true; + return (*env)->ExceptionCheck(env) == JNI_FALSE; } -static int errorHandler(Display *disp, XErrorEvent *error) { - char err_msg_buffer[ERR_MSG_SIZE]; - XGetErrorText(disp, error->error_code, err_msg_buffer, ERR_MSG_SIZE); - err_msg_buffer[ERR_MSG_SIZE - 1] = '\0'; - snprintf(error_message, ERR_MSG_SIZE, "X Error - serial: %d, error_code: %s, request_code: %d, minor_code: %d", (int)error->serial, err_msg_buffer, (int)error->request_code, (int)error->minor_code); - error_message[ERR_MSG_SIZE - 1] = '\0'; - async_x_error = true; - return 0; +static int global_error_handler(Display *disp, XErrorEvent *error) { + JNIEnv *env = getThreadEnv(); + if (env != NULL) { + jclass org_lwjgl_LinuxDisplay_class = (*env)->FindClass(env, "org/lwjgl/opengl/LinuxDisplay"); + if (org_lwjgl_LinuxDisplay_class == NULL) + return 0; + jmethodID handler_method = (*env)->GetStaticMethodID(env, org_lwjgl_LinuxDisplay_class, "globalErrorHandler", "(JJJJJJJ)I"); + if (handler_method == NULL) + return 0; + return (*env)->CallStaticIntMethod(env, org_lwjgl_LinuxDisplay_class, handler_method, (jlong)(intptr_t)disp, (jlong)(intptr_t)error, + (jlong)(intptr_t)error->display, (jlong)error->serial, (jlong)error->error_code, (jlong)error->request_code, (jlong)error->minor_code); + } else + return 0; } static jlong openDisplay(JNIEnv *env) { - async_x_error = false; - XSetErrorHandler(errorHandler); Display *display_connection = XOpenDisplay(NULL); if (display_connection == NULL) { throwException(env, "Could not open X display connection"); @@ -113,12 +105,35 @@ return (intptr_t)display_connection; } -JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_checkXError(JNIEnv *env, jclass unused, jlong display_ptr) { +JNIEXPORT jstring JNICALL Java_org_lwjgl_opengl_LinuxDisplay_getErrorText(JNIEnv *env, jclass unused, jlong display_ptr, jlong error_code) { Display *disp = (Display *)(intptr_t)display_ptr; - XSync(disp, False); - checkXError(env, disp); + char err_msg_buffer[ERR_MSG_SIZE]; + XGetErrorText(disp, error_code, err_msg_buffer, ERR_MSG_SIZE); + err_msg_buffer[ERR_MSG_SIZE - 1] = '\0'; + return NewStringNativeWithLength(env, err_msg_buffer, strlen(err_msg_buffer)); } +JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_callErrorHandler(JNIEnv *env, jclass unused, jlong handler_ptr, jlong display_ptr, jlong event_ptr) { + XErrorHandler handler = (XErrorHandler)(intptr_t)handler_ptr; + Display *disp = (Display *)(intptr_t)display_ptr; + XErrorEvent *event = (XErrorEvent *)(intptr_t)event_ptr; + return (jint)handler(disp, event); +} + +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxDisplay_setErrorHandler(JNIEnv *env, jclass unused) { + return (intptr_t)XSetErrorHandler(global_error_handler); +} + +JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxDisplay_resetErrorHandler(JNIEnv *env, jclass unused, jlong handler_ptr) { + XErrorHandler handler = (XErrorHandler)(intptr_t)handler_ptr; + return (intptr_t)XSetErrorHandler(handler); +} + +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_sync(JNIEnv *env, jclass unused, jlong display_ptr, jboolean throw_away_events) { + Display *disp = (Display *)(intptr_t)display_ptr; + XSync(disp, throw_away_events ? True : False); +} + JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_LinuxDisplay_nGetDefaultScreen(JNIEnv *env, jclass unused, jlong display_ptr) { Display *disp = (Display *)(intptr_t)display_ptr; return XDefaultScreen(disp); @@ -238,6 +253,11 @@ XResizeWindow(disp, window, width, height); } +JNIEXPORT void JNICALL Java_org_lwjgl_opengl_LinuxDisplay_synchronize(JNIEnv *env, jclass clazz, jlong display, jboolean synchronize) { + Display *disp = (Display *)(intptr_t)display; + XSynchronize(disp, synchronize ? True : False); +} + JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_LinuxDisplay_getRootWindow(JNIEnv *env, jclass clazz, jlong display, jint screen) { Display *disp = (Display *)(intptr_t)display; return RootWindow(disp, screen); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |