From 747f0850a0388ec2e8e78278fa1544cbdce877f2 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Thu, 24 Nov 2005 11:31:26 +0000 Subject: [PATCH] Added support for native formatted exception messages --- src/native/common/common_tools.c | 51 ++++++++++++++----- src/native/win32/context.c | 8 +-- src/native/win32/context.h | 3 +- src/native/win32/org_lwjgl_opengl_Pbuffer.c | 3 +- .../org_lwjgl_opengl_Win32DisplayPeerInfo.c | 4 +- .../win32/org_lwjgl_opengl_Win32PeerInfo.c | 6 +-- 6 files changed, 51 insertions(+), 24 deletions(-) diff --git a/src/native/common/common_tools.c b/src/native/common/common_tools.c index 5f3ff942..69a3faab 100644 --- a/src/native/common/common_tools.c +++ b/src/native/common/common_tools.c @@ -78,27 +78,33 @@ bool isDebugEnabled(void) { return debug; } -void printfDebugJava(JNIEnv *env, const char *format, ...) { - #define BUFFER_SIZE 4000 +static jstring sprintfJavaString(JNIEnv *env, const char *format, va_list ap) { +#define BUFFER_SIZE 4000 char buffer[BUFFER_SIZE]; jstring str; +#ifdef WIN32 + _vsnprintf(buffer, BUFFER_SIZE, format, ap); +#else + vsnprintf(buffer, BUFFER_SIZE, format, ap); +#endif + buffer[BUFFER_SIZE - 1] = '\0'; + str = (*env)->NewStringUTF(env, buffer); + return str; +} + +void printfDebugJava(JNIEnv *env, const char *format, ...) { + jstring str; jclass org_lwjgl_LWJGLUtil_class; jmethodID log_method; va_list ap; - va_start(ap, format); if (isDebugEnabled()) { - #ifdef WIN32 - _vsnprintf(buffer, BUFFER_SIZE, format, ap); - #else - vsnprintf(buffer, BUFFER_SIZE, format, ap); - #endif - buffer[BUFFER_SIZE - 1] = '\0'; - str = (*env)->NewStringUTF(env, buffer); + va_start(ap, format); + str = sprintfJavaString(env, format, ap); + va_end(ap); org_lwjgl_LWJGLUtil_class = (*env)->FindClass(env, "org/lwjgl/LWJGLUtil"); log_method = (*env)->GetStaticMethodID(env, org_lwjgl_LWJGLUtil_class, "log", "(Ljava/lang/String;)V"); (*env)->CallStaticVoidMethod(env, org_lwjgl_LWJGLUtil_class, log_method, str); } - va_end(ap); } void printfDebug(const char *format, ...) { @@ -169,6 +175,21 @@ int copyEvents(event_queue_t *queue, jint *output_event_buffer, int buffer_size) return num_events; } +static void throwFormattedGeneralException(JNIEnv * env, const char *exception_name, const char *format, va_list ap) { + jclass cls; + jstring str; + jmethodID exception_constructor; + jobject exception; + + if ((*env)->ExceptionCheck(env) == JNI_TRUE) + return; // The JVM crashes if we try to throw two exceptions from one native call + str = sprintfJavaString(env, format, ap); + cls = (*env)->FindClass(env, exception_name); + exception_constructor = (*env)->GetMethodID(env, cls, "", "(Ljava/lang/String;)V"); + exception = (*env)->NewObject(env, cls, exception_constructor, str); + (*env)->Throw(env, exception); +} + void throwGeneralException(JNIEnv * env, const char *exception_name, const char * err) { jclass cls; @@ -176,13 +197,19 @@ void throwGeneralException(JNIEnv * env, const char *exception_name, const char return; // The JVM crashes if we try to throw two exceptions from one native call cls = (*env)->FindClass(env, exception_name); (*env)->ThrowNew(env, cls, err); - (*env)->DeleteLocalRef(env, cls); } void throwFMODException(JNIEnv * env, const char * err) { throwGeneralException(env, "org/lwjgl/fmod3/FMODException", err); } +void throwFormattedException(JNIEnv * env, const char *format, ...) { + va_list ap; + va_start(ap, format); + throwFormattedGeneralException(env, "org/lwjgl/LWJGLException", format, ap); + va_end(ap); +} + void throwException(JNIEnv * env, const char * err) { throwGeneralException(env, "org/lwjgl/LWJGLException", err); } diff --git a/src/native/win32/context.c b/src/native/win32/context.c index f9525145..1eb08815 100644 --- a/src/native/win32/context.c +++ b/src/native/win32/context.c @@ -40,6 +40,7 @@ */ #include +#include #include "common_tools.h" #include "extgl.h" #include "extgl_wgl.h" @@ -78,14 +79,16 @@ static LRESULT CALLBACK dummyWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR return DefWindowProc(hwnd, msg, wParam, lParam); } -bool applyPixelFormat(HDC hdc, int iPixelFormat) { +bool applyPixelFormat(JNIEnv *env, HDC hdc, int iPixelFormat) { PIXELFORMATDESCRIPTOR desc; if (DescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &desc) == 0) { + throwFormattedException(env, "DescribePixelFormat failed (%d)", GetLastError()); return false; } // make that the pixel format of the device context if (SetPixelFormat(hdc, iPixelFormat, &desc) == FALSE) { + throwFormattedException(env, "SetPixelFormat failed (%d)", GetLastError()); return false; } return true; @@ -358,8 +361,7 @@ int findPixelFormatOnDC(JNIEnv *env, HDC hdc, jobject pixel_format, jobject pixe bool use_arb_selection = samples > 0 || pbuffer || pixelFormatCaps != NULL; pixel_format_id = findPixelFormatDefault(env, hdc, pixel_format, use_hdc_bpp, double_buffer); if (use_arb_selection) { - if (!applyPixelFormat(hdc, pixel_format_id)) { - throwException(env, "Could not apply pixel format to window"); + if (!applyPixelFormat(env, hdc, pixel_format_id)) { return -1; } dummy_hglrc = wglCreateContext(hdc); diff --git a/src/native/win32/context.h b/src/native/win32/context.h index 0de000bd..453dc2f4 100644 --- a/src/native/win32/context.h +++ b/src/native/win32/context.h @@ -43,6 +43,7 @@ #define __LWJGL_CONTEXT_H #include +#include #include "common_tools.h" #include "extgl.h" #include "extgl_wgl.h" @@ -67,7 +68,7 @@ typedef struct { */ extern bool registerWindow(); -extern bool applyPixelFormat(HDC hdc, int iPixelFormat); +extern bool applyPixelFormat(JNIEnv *env, HDC hdc, int iPixelFormat); /* * Close the window diff --git a/src/native/win32/org_lwjgl_opengl_Pbuffer.c b/src/native/win32/org_lwjgl_opengl_Pbuffer.c index d315de89..bf376248 100644 --- a/src/native/win32/org_lwjgl_opengl_Pbuffer.c +++ b/src/native/win32/org_lwjgl_opengl_Pbuffer.c @@ -71,9 +71,8 @@ static bool getExtensions(JNIEnv *env, WGLExtensions *extensions, jobject pixel_ return false; } dummy_hdc = GetDC(dummy_hwnd); - if (!applyPixelFormat(dummy_hdc, pixel_format_id)) { + if (!applyPixelFormat(env, dummy_hdc, pixel_format_id)) { closeWindow(&dummy_hwnd, &dummy_hdc); - throwException(env, "Could not apply pixel format"); return false; } dummy_context = wglCreateContext(dummy_hdc); diff --git a/src/native/win32/org_lwjgl_opengl_Win32DisplayPeerInfo.c b/src/native/win32/org_lwjgl_opengl_Win32DisplayPeerInfo.c index a4888d45..ad5875e7 100644 --- a/src/native/win32/org_lwjgl_opengl_Win32DisplayPeerInfo.c +++ b/src/native/win32/org_lwjgl_opengl_Win32DisplayPeerInfo.c @@ -73,6 +73,6 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32DisplayPeerInfo_nInitDC throwException(env, "Could not get pixel format from dummy hdc"); return; } - if (!applyPixelFormat(peer_info->drawable_hdc, pixel_format)) - throwException(env, "Could not apply pixel format to drawable"); + // If applyPixelFormat fails, just let it throw + applyPixelFormat(env, peer_info->drawable_hdc, pixel_format); } diff --git a/src/native/win32/org_lwjgl_opengl_Win32PeerInfo.c b/src/native/win32/org_lwjgl_opengl_Win32PeerInfo.c index 40fd1714..681b542f 100644 --- a/src/native/win32/org_lwjgl_opengl_Win32PeerInfo.c +++ b/src/native/win32/org_lwjgl_opengl_Win32PeerInfo.c @@ -53,8 +53,6 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_Win32PeerInfo_nChoosePixelFormat int pixel_format_id = findPixelFormat(env, origin_x, origin_y, pixel_format, pixel_format_caps, use_hdc_bpp, window, pbuffer, double_buffer); if (pixel_format_id == -1) return; - if (!applyPixelFormat(peer_info->format_hdc, pixel_format_id)) { - throwException(env, "Could not apply pixel format"); - return; - } + // Let it throw + applyPixelFormat(env, peer_info->format_hdc, pixel_format_id); }