| 
      
      
      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.
 |