diff options
author | Sven Gothel <[email protected]> | 2010-12-12 07:51:06 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-12-12 07:51:06 +0100 |
commit | 48f6568ebffdd557651460fb5f3f7f4abbca2440 (patch) | |
tree | 2cbd9cc815ab54fcd61fccae17e7d75ca6cc6d51 /src/nativewindow | |
parent | f3512c700b2b3161eb773e77d0d41567acb710be (diff) |
Windows RegisterClass: Use new RegisteredClassFactory (window class), Misc.
This solves the issue when an applet is started/stop and started again,
or another applet runs in the same JVM.
Also soves the issue for multiple JVMs.
RegisteredClassFactory can be instanced to manage one shared window class,
currently in use for GDI's dummy window and NEWT.
A class base name and a window proc handle must be passed in the factory cstr.
Before registering, the class is tested if already exists,
eg another applet in the same JVM.
If registration fails, the class name will iterate until successful or MAX_INT reached,
eg if multiple JVMs are running.
Added NativeWindow Common Native Code.
Diffstat (limited to 'src/nativewindow')
8 files changed, 433 insertions, 124 deletions
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java index f3b7f4a4e..c56f632d8 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/x11/X11Util.java @@ -34,10 +34,11 @@ package com.jogamp.nativewindow.impl.x11; import com.jogamp.common.util.LongObjectHashMap; +import com.jogamp.nativewindow.impl.Debug; +import com.jogamp.nativewindow.impl.NWJNILibLoader; import javax.media.nativewindow.*; -import com.jogamp.nativewindow.impl.*; import java.nio.Buffer; import java.nio.IntBuffer; import java.nio.ShortBuffer; diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java index a36440873..9e0aa28fa 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java @@ -80,6 +80,7 @@ public abstract class NativeWindowFactory { public static final String AWTComponentClassName = "java.awt.Component" ; public static final String JAWTUtilClassName = "com.jogamp.nativewindow.impl.jawt.JAWTUtil" ; public static final String X11UtilClassName = "com.jogamp.nativewindow.impl.x11.X11Util"; + public static final String GDIClassName = "com.jogamp.nativewindow.impl.windows.GDI"; public static final String X11JAWTToolkitLockClassName = "com.jogamp.nativewindow.impl.jawt.x11.X11JAWTToolkitLock" ; public static final String X11ToolkitLockClassName = "com.jogamp.nativewindow.impl.x11.X11ToolkitLock" ; private static Class jawtUtilClass; @@ -117,6 +118,20 @@ public abstract class NativeWindowFactory { static boolean initialized = false; + private static void initNativeImpl(final boolean firstUIActionOnProcess, final ClassLoader cl) { + String clazzName = null; + if( TYPE_X11.equals(nativeWindowingTypePure) ) { + clazzName = X11UtilClassName; + } else if( TYPE_WINDOWS.equals(nativeWindowingTypePure) ) { + clazzName = GDIClassName; + } + if( null != clazzName ) { + ReflectionUtil.callStaticMethod(clazzName, "initSingleton", + new Class[] { boolean.class }, + new Object[] { new Boolean(firstUIActionOnProcess) }, cl ); + } + } + /** * Static one time initialization of this factory.<br> * This initialization method <b>must be called</b> once by the program or utilizing modules!<br> @@ -144,15 +159,14 @@ public abstract class NativeWindowFactory { nativeWindowingTypeCustom = nativeOSNameCustom; } - ClassLoader cl = NativeWindowFactory.class.getClassLoader(); + final ClassLoader cl = NativeWindowFactory.class.getClassLoader(); - if( TYPE_X11.equals(nativeWindowingTypePure) ) { - // explicit initialization of X11Util - ReflectionUtil.callStaticMethod(X11UtilClassName, "initSingleton", - new Class[] { boolean.class }, - new Object[] { new Boolean(firstUIActionOnProcess) }, cl ); + if(firstUIActionOnProcess) { + // X11 initialization before possible AWT initialization + initNativeImpl(firstUIActionOnProcess, cl); } isFirstUIActionOnProcess = firstUIActionOnProcess; + isAWTAvailable = false; // may be set to true below if( !Debug.getBooleanProperty("java.awt.headless", true, acc) && ReflectionUtil.isClassAvailable(AWTComponentClassName, cl) && @@ -180,16 +194,13 @@ public abstract class NativeWindowFactory { // AWT is only available in case all above classes are available // and AWT is not int headless mode isAWTAvailable = ((Boolean)resO).equals(Boolean.FALSE); - } else { - isAWTAvailable = false; } - } else { - isAWTAvailable = false; } - } else { - isAWTAvailable = false; } - + if(!firstUIActionOnProcess) { + // X11 initialization after possible AWT initialization + initNativeImpl(firstUIActionOnProcess, cl); + } registeredFactories = Collections.synchronizedMap(new HashMap()); // register our default factory -> NativeWindow diff --git a/src/nativewindow/classes/javax/media/nativewindow/windows/RegisteredClass.java b/src/nativewindow/classes/javax/media/nativewindow/windows/RegisteredClass.java new file mode 100644 index 000000000..f42c2cbc0 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/windows/RegisteredClass.java @@ -0,0 +1,44 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community 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. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package javax.media.nativewindow.windows; + +public class RegisteredClass { + long hInstance; + String className; + + RegisteredClass(long hInst, String name) { + hInstance = hInst; + className = name; + } + + public final long getHandle() { return hInstance; } + public final String getName() { return className; } + + public final String toString() { return "RegisteredClass[handle 0x"+Long.toHexString(hInstance)+", "+className+"]"; } +} diff --git a/src/nativewindow/classes/javax/media/nativewindow/windows/RegisteredClassFactory.java b/src/nativewindow/classes/javax/media/nativewindow/windows/RegisteredClassFactory.java new file mode 100644 index 000000000..2378bb9a8 --- /dev/null +++ b/src/nativewindow/classes/javax/media/nativewindow/windows/RegisteredClassFactory.java @@ -0,0 +1,134 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community 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. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package javax.media.nativewindow.windows; + +import com.jogamp.nativewindow.impl.Debug; +import com.jogamp.nativewindow.impl.windows.GDI; +import java.util.ArrayList; +import javax.media.nativewindow.NativeWindowException; + +public class RegisteredClassFactory { + static final boolean DEBUG = Debug.debug("RegisteredClass"); + private static ArrayList sharedClasses = new ArrayList(); + private String classBaseName; + long wndProc; + + private RegisteredClass sharedClass = null; + private int classIter = 0; + private int sharedRefCount = 0; + private Object sync = new Object(); + + /** + * Intended for a JVM shutdown hook, hence little synchronization + */ + public static void shutdownSharedClasses() { + synchronized(sharedClasses) { + for(int i=0; i<sharedClasses.size(); i++) { + RegisteredClass sc = (RegisteredClass) sharedClasses.get(i); + GDI.DestroyWindowClass(sc.getHandle(), sc.getName()); + if(DEBUG) { + System.err.println("RegisteredClassFactory shutdownSharedClasses "+i+"/"+sharedClasses.size()+": "+sc); + } + } + sharedClasses.clear(); + } + } + + public RegisteredClassFactory(String classBaseName, long wndProc) { + this.classBaseName = classBaseName; + this.wndProc = wndProc; + } + + public RegisteredClass getSharedClass() throws NativeWindowException { + synchronized(sync) { + if( 0 == sharedRefCount ) { + if( null != sharedClass ) { + throw new InternalError("Error ("+sharedRefCount+"): SharedClass not null: "+sharedClass); + } + long hInstance = GDI.GetApplicationHandle(); + if( 0 == hInstance ) { + throw new NativeWindowException("Error: Null ModuleHandle for Application"); + } + String clazzName = null; + boolean registered = false; + while ( !registered && Integer.MAX_VALUE >= classIter ) { + // Retry with next clazz name, this could happen if more than one JVM is running + clazzName = classBaseName + classIter; + classIter++; + registered = GDI.CreateWindowClass(hInstance, clazzName, wndProc); + } + if( !registered ) { + throw new NativeWindowException("Error: Could not create WindowClass: "+clazzName); + } + sharedClass = new RegisteredClass(hInstance, clazzName); + synchronized(sharedClasses) { + sharedClasses.add(sharedClass); + } + if(DEBUG) { + System.err.println("RegisteredClassFactory getSharedClass ("+sharedRefCount+") initialized: "+sharedClass); + } + } else if ( null == sharedClass ) { + throw new InternalError("Error ("+sharedRefCount+"): SharedClass is null"); + } + sharedRefCount++; + } + return sharedClass; + } + + public void releaseSharedClass() { + synchronized(sync) { + if( 0 == sharedRefCount ) { + if( null != sharedClass ) { + throw new InternalError("Error ("+sharedRefCount+"): SharedClass not null: "+sharedClass); + } + return; + } + sharedRefCount--; + if( null == sharedClass ) { + throw new InternalError("Error ("+sharedRefCount+"): SharedClass is null"); + } + if( 0 == sharedRefCount ) { + GDI.DestroyWindowClass(sharedClass.getHandle(), sharedClass.getName()); + synchronized(sharedClasses) { + sharedClasses.remove(sharedClass); + } + if(DEBUG) { + System.err.println("RegisteredClassFactory releaseSharedClass ("+sharedRefCount+") released: "+sharedClass); + } + sharedClass = null; + sharedRefCount = 0; + classIter = 0; + } + } + } + + public int getSharedRefCount() { + return sharedRefCount; + } +} diff --git a/src/nativewindow/native/NativewindowCommon.c b/src/nativewindow/native/NativewindowCommon.c new file mode 100644 index 000000000..e357045d6 --- /dev/null +++ b/src/nativewindow/native/NativewindowCommon.c @@ -0,0 +1,57 @@ + +#include "NativewindowCommon.h" + +static const char * const ClazzNameRuntimeException = "java/lang/RuntimeException"; +static jclass runtimeExceptionClz=NULL; + +void NativewindowCommon_FatalError(JNIEnv *env, const char* msg, ...) +{ + char buffer[512]; + va_list ap; + + va_start(ap, msg); + vsnprintf(buffer, sizeof(buffer), msg, ap); + va_end(ap); + + fprintf(stderr, "%s\n", buffer); + (*env)->FatalError(env, buffer); +} + +void NativewindowCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...) +{ + char buffer[512]; + va_list ap; + + va_start(ap, msg); + vsnprintf(buffer, sizeof(buffer), msg, ap); + va_end(ap); + + (*env)->ThrowNew(env, runtimeExceptionClz, buffer); +} + +int NativewindowCommon_init(JNIEnv *env) { + if(NULL==runtimeExceptionClz) { + jclass c = (*env)->FindClass(env, ClazzNameRuntimeException); + if(NULL==c) { + NativewindowCommon_FatalError(env, "Nativewindow: can't find %s", ClazzNameRuntimeException); + } + runtimeExceptionClz = (jclass)(*env)->NewGlobalRef(env, c); + (*env)->DeleteLocalRef(env, c); + if(NULL==runtimeExceptionClz) { + NativewindowCommon_FatalError(env, "Nativewindow: can't use %s", ClazzNameRuntimeException); + } + return 1; + } + return 0; +} + +jchar* NativewindowCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str) +{ + jchar* strChars = NULL; + strChars = calloc((*env)->GetStringLength(env, str) + 1, sizeof(jchar)); + if (strChars != NULL) { + (*env)->GetStringRegion(env, str, 0, (*env)->GetStringLength(env, str), strChars); + } + return strChars; +} + diff --git a/src/nativewindow/native/NativewindowCommon.h b/src/nativewindow/native/NativewindowCommon.h new file mode 100644 index 000000000..5dc5debef --- /dev/null +++ b/src/nativewindow/native/NativewindowCommon.h @@ -0,0 +1,15 @@ + +#ifndef NATIVEWINDOW_COMMON_H +#define NATIVEWINDOW_COMMON_H 1 + +#include <jni.h> +#include <stdlib.h> + +int NativewindowCommon_init(JNIEnv *env); + +jchar* NativewindowCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str); + +void NativewindowCommon_FatalError(JNIEnv *env, const char* msg, ...); +void NativewindowCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...); + +#endif diff --git a/src/nativewindow/native/windows/GDImisc.c b/src/nativewindow/native/windows/GDImisc.c index 0de40cf50..798edcbbf 100644 --- a/src/nativewindow/native/windows/GDImisc.c +++ b/src/nativewindow/native/windows/GDImisc.c @@ -29,6 +29,7 @@ #include <stdio.h> +#include "NativewindowCommon.h" #include "com_jogamp_nativewindow_impl_windows_GDI.h" // #define VERBOSE_ON 1 @@ -39,19 +40,6 @@ #define DBG_PRINT(args...) #endif -static void _FatalError(JNIEnv *env, const char* msg, ...) -{ - char buffer[512]; - va_list ap; - - va_start(ap, msg); - vsnprintf(buffer, sizeof(buffer), msg, ap); - va_end(ap); - - fprintf(stderr, "%s\n", buffer); - (*env)->FatalError(env, buffer); -} - static const char * const ClazzNamePoint = "javax/media/nativewindow/util/Point"; static const char * const ClazzAnyCstrName = "<init>"; static const char * const ClazzNamePointCstrSignature = "(II)V"; @@ -59,52 +47,136 @@ static const char * const ClazzNamePointCstrSignature = "(II)V"; static jclass pointClz = NULL; static jmethodID pointCstr = NULL; -#define NATIVEWINDOW_DUMMY_WINDOW_NAME "__nativewindow_dummy_window" -static ATOM nativewindowClass = 0; -static HINSTANCE nativeHInstance = NULL; - -LRESULT CALLBACK DummyWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - return DefWindowProc(hWnd,uMsg,wParam,lParam); +HINSTANCE GetApplicationHandle() { + return GetModuleHandle(NULL); } -HWND CreateDummyWindow0(int x, int y, int width, int height ) { - DWORD dwExStyle; - DWORD dwStyle; - HWND hWnd; - HINSTANCE hInstance = GetModuleHandle(NULL); - if( nativeHInstance != hInstance || 0 == nativewindowClass ) { - nativeHInstance=hInstance; - WNDCLASS wc; +/* Java->C glue code: + * Java package: com.jogamp.nativewindow.impl.windows.GDI + * Java method: boolean CreateWindowClass(long hInstance, java.lang.String clazzName, long wndProc) + * C function: BOOL CreateWindowClass(HANDLE hInstance, LPCSTR clazzName, HANDLE wndProc); + */ +JNIEXPORT jboolean JNICALL +Java_com_jogamp_nativewindow_impl_windows_GDI_CreateWindowClass + (JNIEnv *env, jclass _unused, jlong jHInstance, jstring jClazzName, jlong wndProc) +{ + HINSTANCE hInstance = (HINSTANCE) (intptr_t) jHInstance; + const TCHAR* clazzName = NULL; + WNDCLASS wc; + jboolean res; + +#ifdef UNICODE + clazzName = NewtCommon_GetNullTerminatedStringChars(env, jClazzName); +#else + clazzName = (*env)->GetStringUTFChars(env, jClazzName, NULL); +#endif + + ZeroMemory( &wc, sizeof( wc ) ); + if( GetClassInfo( hInstance, clazzName, &wc ) ) { + // registered already + res = JNI_TRUE; + } else { + // register now ZeroMemory( &wc, sizeof( wc ) ); - wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; - wc.lpfnWndProc = (WNDPROC) DummyWndProc; + wc.style = CS_HREDRAW | CS_VREDRAW ; + wc.lpfnWndProc = (WNDPROC) (intptr_t) wndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = NULL; - wc.hCursor = NULL; - wc.hbrBackground = NULL; + wc.hCursor = LoadCursor( NULL, IDC_ARROW); + wc.hbrBackground = NULL; // no background paint - GetStockObject(BLACK_BRUSH); wc.lpszMenuName = NULL; - wc.lpszClassName = NATIVEWINDOW_DUMMY_WINDOW_NAME; - if( !(nativewindowClass = RegisterClass( &wc )) ) { - fprintf(stderr, "FatalError com_jogamp_nativewindow_impl_windows_GDI: RegisterClass Failed: %d\n", GetLastError() ); - return( 0 ); - } + wc.lpszClassName = clazzName; + res = ( 0 != RegisterClass( &wc ) ) ? JNI_TRUE : JNI_FALSE ; } +#ifdef UNICODE + free((void*) clazzName); +#else + (*env)->ReleaseStringUTFChars(env, jClazzName, clazzName); +#endif + + return res; +} + +/* Java->C glue code: + * Java package: com.jogamp.nativewindow.impl.windows.GDI + * Java method: boolean DestroyWindowClass(long hInstance, java.lang.String className) + * C function: BOOL DestroyWindowClass(HANDLE hInstance, LPCSTR className); + */ +JNIEXPORT jboolean JNICALL +Java_com_jogamp_nativewindow_impl_windows_GDI_DestroyWindowClass + (JNIEnv *env, jclass _unused, jlong jHInstance, jstring jClazzName) +{ + HINSTANCE hInstance = (HINSTANCE) (intptr_t) jHInstance; + const TCHAR* clazzName = NULL; + jboolean res; + +#ifdef UNICODE + clazzName = NewtCommon_GetNullTerminatedStringChars(env, jClazzName); +#else + clazzName = (*env)->GetStringUTFChars(env, jClazzName, NULL); +#endif + + res = ( 0 != UnregisterClass( clazzName, hInstance ) ) ? JNI_TRUE : JNI_FALSE ; + +#ifdef UNICODE + free((void*) clazzName); +#else + (*env)->ReleaseStringUTFChars(env, jClazzName, clazzName); +#endif + + return res; +} + + +/* Java->C glue code: + * Java package: com.jogamp.nativewindow.impl.windows.GDI + * Java method: long CreateDummyWindow0(long hInstance, java.lang.String className, java.lang.String windowName, int x, int y, int width, int height) + * C function: HANDLE CreateDummyWindow0(HANDLE hInstance, LPCSTR className, LPCSTR windowName, int x, int y, int width, int height); + */ +JNIEXPORT jlong JNICALL +Java_com_jogamp_nativewindow_impl_windows_GDI_CreateDummyWindow0 + (JNIEnv *env, jclass _unused, jlong jHInstance, jstring jWndClassName, jstring jWndName, jint x, jint y, jint width, jint height) +{ + HINSTANCE hInstance = (HINSTANCE) (intptr_t) jHInstance; + const TCHAR* wndClassName = NULL; + const TCHAR* wndName = NULL; + DWORD dwExStyle; + DWORD dwStyle; + HWND hWnd; + +#ifdef UNICODE + wndClassName = NewtCommon_GetNullTerminatedStringChars(env, jWndClassName); + wndName = NewtCommon_GetNullTerminatedStringChars(env, jWndName); +#else + wndClassName = (*env)->GetStringUTFChars(env, jWndClassName, NULL); + wndName = (*env)->GetStringUTFChars(env, jWndName, NULL); +#endif + dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; dwStyle = WS_OVERLAPPEDWINDOW; - if( !(hWnd=CreateWindowEx( dwExStyle, - NATIVEWINDOW_DUMMY_WINDOW_NAME, - NATIVEWINDOW_DUMMY_WINDOW_NAME, - dwStyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, - x, y, width, height, - NULL, NULL, hInstance, NULL ) ) ) { - return( 0 ); - } - return( hWnd ); + + hWnd = CreateWindowEx( dwExStyle, + wndClassName, + wndName, + dwStyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, + x, y, width, height, + NULL, NULL, hInstance, NULL ); + +#ifdef UNICODE + free((void*) wndClassName); + free((void*) wndName); +#else + (*env)->ReleaseStringUTFChars(env, jWndClassName, wndClassName); + (*env)->ReleaseStringUTFChars(env, jWndName, wndName); +#endif + + return (jlong) (intptr_t) hWnd; } + /* * Class: com_jogamp_nativewindow_impl_windows_GDI * Method: initIDs0 @@ -113,25 +185,40 @@ HWND CreateDummyWindow0(int x, int y, int width, int height ) { JNIEXPORT jboolean JNICALL Java_com_jogamp_nativewindow_impl_windows_GDI_initIDs0 (JNIEnv *env, jclass clazz) { - if(NULL==pointClz) { + if(NativewindowCommon_init(env)) { jclass c = (*env)->FindClass(env, ClazzNamePoint); if(NULL==c) { - _FatalError(env, "FatalError com_jogamp_nativewindow_impl_windows_GDI: can't find %s", ClazzNamePoint); + NativewindowCommon_FatalError(env, "FatalError com_jogamp_nativewindow_impl_windows_GDI: can't find %s", ClazzNamePoint); } pointClz = (jclass)(*env)->NewGlobalRef(env, c); (*env)->DeleteLocalRef(env, c); if(NULL==pointClz) { - _FatalError(env, "FatalError com_jogamp_nativewindow_impl_windows_GDI: can't use %s", ClazzNamePoint); + NativewindowCommon_FatalError(env, "FatalError com_jogamp_nativewindow_impl_windows_GDI: can't use %s", ClazzNamePoint); } pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature); if(NULL==pointCstr) { - _FatalError(env, "FatalError com_jogamp_nativewindow_impl_windows_GDI: can't fetch %s.%s %s", + NativewindowCommon_FatalError(env, "FatalError com_jogamp_nativewindow_impl_windows_GDI: can't fetch %s.%s %s", ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature); } } return JNI_TRUE; } +LRESULT CALLBACK DummyWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + return DefWindowProc(hWnd,uMsg,wParam,lParam); +} + +/* + * Class: com_jogamp_nativewindow_impl_windows_GDI + * Method: getDummyWndProc0 + * Signature: ()J + */ +JNIEXPORT jlong JNICALL Java_com_jogamp_nativewindow_impl_windows_GDI_getDummyWndProc0 + (JNIEnv *env, jclass clazz) +{ + return (jlong) (intptr_t) DummyWndProc; +} + /* * Class: com_jogamp_nativewindow_impl_windows_GDI * Method: GetRelativeLocation0 diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c index efb20c54e..0d92880b3 100644 --- a/src/nativewindow/native/x11/Xmisc.c +++ b/src/nativewindow/native/x11/Xmisc.c @@ -80,6 +80,7 @@ Bool XF86VidModeSetGammaRamp( #define RTLD_DEFAULT NULL #endif +#include "NativewindowCommon.h" #include "com_jogamp_nativewindow_impl_x11_X11Lib.h" // #define VERBOSE_ON 1 @@ -93,107 +94,66 @@ Bool XF86VidModeSetGammaRamp( /* Need to pull this in as we don't have a stub header for it */ extern Bool XineramaEnabled(Display* display); -static void _FatalError(JNIEnv *env, const char* msg, ...) -{ - char buffer[512]; - va_list ap; - - va_start(ap, msg); - vsnprintf(buffer, sizeof(buffer), msg, ap); - va_end(ap); - - fprintf(stderr, "%s\n", buffer); - (*env)->FatalError(env, buffer); -} - static const char * const ClazzNameBuffers = "com/jogamp/common/nio/Buffers"; static const char * const ClazzNameBuffersStaticCstrName = "copyByteBuffer"; static const char * const ClazzNameBuffersStaticCstrSignature = "(Ljava/nio/ByteBuffer;)Ljava/nio/ByteBuffer;"; static const char * const ClazzNameByteBuffer = "java/nio/ByteBuffer"; -static const char * const ClazzNameRuntimeException = "java/lang/RuntimeException"; static const char * const ClazzNamePoint = "javax/media/nativewindow/util/Point"; static const char * const ClazzAnyCstrName = "<init>"; static const char * const ClazzNamePointCstrSignature = "(II)V"; static jclass clazzBuffers = NULL; static jmethodID cstrBuffers = NULL; static jclass clazzByteBuffer = NULL; -static jclass clazzRuntimeException=NULL; static jclass pointClz = NULL; static jmethodID pointCstr = NULL; static void _initClazzAccess(JNIEnv *env) { jclass c; - if(NULL!=clazzRuntimeException) return ; - - c = (*env)->FindClass(env, ClazzNameRuntimeException); - if(NULL==c) { - _FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s", ClazzNameRuntimeException); - } - clazzRuntimeException = (jclass)(*env)->NewGlobalRef(env, c); - (*env)->DeleteLocalRef(env, c); - if(NULL==clazzRuntimeException) { - _FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s", ClazzNameRuntimeException); - } + if(!NativewindowCommon_init(env)) return; c = (*env)->FindClass(env, ClazzNameBuffers); if(NULL==c) { - _FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s", ClazzNameBuffers); + NativewindowCommon_FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s", ClazzNameBuffers); } clazzBuffers = (jclass)(*env)->NewGlobalRef(env, c); (*env)->DeleteLocalRef(env, c); if(NULL==clazzBuffers) { - _FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s", ClazzNameBuffers); + NativewindowCommon_FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s", ClazzNameBuffers); } c = (*env)->FindClass(env, ClazzNameByteBuffer); if(NULL==c) { - _FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s", ClazzNameByteBuffer); + NativewindowCommon_FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s", ClazzNameByteBuffer); } clazzByteBuffer = (jclass)(*env)->NewGlobalRef(env, c); (*env)->DeleteLocalRef(env, c); if(NULL==c) { - _FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s", ClazzNameByteBuffer); + NativewindowCommon_FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s", ClazzNameByteBuffer); } cstrBuffers = (*env)->GetStaticMethodID(env, clazzBuffers, ClazzNameBuffersStaticCstrName, ClazzNameBuffersStaticCstrSignature); if(NULL==cstrBuffers) { - _FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't create %s.%s %s", + NativewindowCommon_FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't create %s.%s %s", ClazzNameBuffers, ClazzNameBuffersStaticCstrName, ClazzNameBuffersStaticCstrSignature); } c = (*env)->FindClass(env, ClazzNamePoint); if(NULL==c) { - _FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s", ClazzNamePoint); + NativewindowCommon_FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't find %s", ClazzNamePoint); } pointClz = (jclass)(*env)->NewGlobalRef(env, c); (*env)->DeleteLocalRef(env, c); if(NULL==pointClz) { - _FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s", ClazzNamePoint); + NativewindowCommon_FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't use %s", ClazzNamePoint); } pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature); if(NULL==pointCstr) { - _FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't fetch %s.%s %s", + NativewindowCommon_FatalError(env, "FatalError Java_com_jogamp_nativewindow_impl_x11_X11Lib: can't fetch %s.%s %s", ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature); } } -static void _throwNewRuntimeException(Display * unlockDisplay, JNIEnv *env, const char* msg, ...) -{ - char buffer[512]; - va_list ap; - - if(NULL!=unlockDisplay) { - XUnlockDisplay(unlockDisplay); - } - - va_start(ap, msg); - vsnprintf(buffer, sizeof(buffer), msg, ap); - va_end(ap); - - (*env)->ThrowNew(env, clazzRuntimeException, buffer); -} - static JNIEnv * x11ErrorHandlerJNIEnv = NULL; static XErrorHandler origErrorHandler = NULL ; static int errorHandlerBlocked = 0 ; @@ -208,7 +168,7 @@ static int x11ErrorHandler(Display *dpy, XErrorEvent *e) // Since the X11 Error may happen anytime, a exception could mess up the JVM completely. // Experienced this for remote displays issuing non supported commands, eg. glXCreateContextAttribsARB(..) // - _throwNewRuntimeException(NULL, x11ErrorHandlerJNIEnv, "Info: Nativewindow X11 Error: Display %p, Code 0x%X, errno %s", + NativewindowCommon_throwNewRuntimeException(x11ErrorHandlerJNIEnv, "Info: Nativewindow X11 Error: Display %p, Code 0x%X, errno %s", dpy, e->error_code, strerror(errno)); #endif @@ -256,7 +216,7 @@ static XIOErrorHandler origIOErrorHandler = NULL; static int x11IOErrorHandler(Display *dpy) { fprintf(stderr, "Nativewindow X11 IOError: Display %p (%s): %s\n", dpy, XDisplayName(NULL), strerror(errno)); - // _FatalError(x11ErrorHandlerJNIEnv, "Nativewindow X11 IOError: Display %p (%s): %s", dpy, XDisplayName(NULL), strerror(errno)); + // NativewindowCommon_FatalError(x11ErrorHandlerJNIEnv, "Nativewindow X11 IOError: Display %p (%s): %s", dpy, XDisplayName(NULL), strerror(errno)); if(NULL!=origIOErrorHandler) { origIOErrorHandler(dpy); } @@ -315,7 +275,7 @@ Java_com_jogamp_nativewindow_impl_x11_X11Lib_XGetVisualInfo1__JJLjava_nio_ByteBu jobject jbyteSource; jobject jbyteCopy; if(0==arg0) { - _FatalError(env, "invalid display connection.."); + NativewindowCommon_FatalError(env, "invalid display connection.."); } if (arg2 != NULL) { _ptr2 = (XVisualInfo *) (((char*) (*env)->GetDirectBufferAddress(env, arg2)) + 0); @@ -344,7 +304,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_DefaultVisualID(JNIEnv *env, jclass _unused, jlong display, jint screen) { jlong r; if(0==display) { - _FatalError(env, "invalid display connection.."); + NativewindowCommon_FatalError(env, "invalid display connection.."); } x11ErrorHandlerEnable((Display *) (intptr_t) display, 1, env); r = (jlong) XVisualIDFromVisual( DefaultVisual( (Display*) (intptr_t) display, screen ) ); @@ -360,7 +320,7 @@ Java_com_jogamp_nativewindow_impl_x11_X11Lib_DefaultVisualID(JNIEnv *env, jclass JNIEXPORT void JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_XLockDisplay__J(JNIEnv *env, jclass _unused, jlong display) { if(0==display) { - _FatalError(env, "invalid display connection.."); + NativewindowCommon_FatalError(env, "invalid display connection.."); } XLockDisplay((Display *) (intptr_t) display); } @@ -373,7 +333,7 @@ Java_com_jogamp_nativewindow_impl_x11_X11Lib_XLockDisplay__J(JNIEnv *env, jclass JNIEXPORT void JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_XUnlockDisplay__J(JNIEnv *env, jclass _unused, jlong display) { if(0==display) { - _FatalError(env, "invalid display connection.."); + NativewindowCommon_FatalError(env, "invalid display connection.."); } XUnlockDisplay((Display *) (intptr_t) display); } @@ -387,7 +347,7 @@ JNIEXPORT jint JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_XCloseDisplay__J(JNIEnv *env, jclass _unused, jlong display) { int _res; if(0==display) { - _FatalError(env, "invalid display connection.."); + NativewindowCommon_FatalError(env, "invalid display connection.."); } x11ErrorHandlerEnable((Display *) (intptr_t) display, 1, env); _res = XCloseDisplay((Display *) (intptr_t) display); @@ -420,12 +380,12 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_CreateDummy Screen* scrn; if(NULL==dpy) { - _FatalError(env, "invalid display connection.."); + NativewindowCommon_FatalError(env, "invalid display connection.."); return 0; } if(visualID<0) { - _throwNewRuntimeException(NULL, env, "invalid VisualID .."); + NativewindowCommon_throwNewRuntimeException(env, "invalid VisualID .."); return 0; } @@ -450,7 +410,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_CreateDummy if (visual==NULL) { x11ErrorHandlerEnable(dpy, 0, env); - _throwNewRuntimeException(dpy, env, "could not query Visual by given VisualID, bail out!"); + NativewindowCommon_throwNewRuntimeException(env, "could not query Visual by given VisualID, bail out!"); return 0; } @@ -515,7 +475,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_nativewindow_impl_x11_X11Lib_DestroyDummy Window w = (Window) window; if(NULL==dpy) { - _throwNewRuntimeException(NULL, env, "invalid display connection.."); + NativewindowCommon_throwNewRuntimeException(env, "invalid display connection.."); return; } |