aboutsummaryrefslogtreecommitdiffstats
path: root/src/nativewindow/native/win32/GDImisc.c
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-02-23 14:51:06 +0100
committerSven Gothel <[email protected]>2014-02-23 14:51:06 +0100
commit3352601e0860584509adf2b76f993d03893ded4b (patch)
tree974fccc8c0eb2f5ad9d4ffd741dfc35869ed67b5 /src/nativewindow/native/win32/GDImisc.c
parentf51933f0ebe9ae030c26c066e59a728ce08b8559 (diff)
parentc67de337a8aaf52e36104c3f13e273aa19d21f1f (diff)
Merge branch 'master' into stash_glyphcache
Conflicts: make/scripts/tests.sh src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java src/jogl/classes/com/jogamp/graph/curve/Region.java src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java src/jogl/classes/com/jogamp/graph/font/Font.java src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java src/jogl/classes/jogamp/graph/curve/text/GlyphString.java src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java
Diffstat (limited to 'src/nativewindow/native/win32/GDImisc.c')
-rw-r--r--src/nativewindow/native/win32/GDImisc.c438
1 files changed, 393 insertions, 45 deletions
diff --git a/src/nativewindow/native/win32/GDImisc.c b/src/nativewindow/native/win32/GDImisc.c
index 3ab7f9859..bec1d4922 100644
--- a/src/nativewindow/native/win32/GDImisc.c
+++ b/src/nativewindow/native/win32/GDImisc.c
@@ -20,8 +20,10 @@
#ifdef VERBOSE_ON
#define DBG_PRINT(args...) fprintf(stderr, args);
+ #define DBG_PRINT_FLUSH(args...) fprintf(stderr, args); fflush(stderr);
#else
#define DBG_PRINT(args...)
+ #define DBG_PRINT_FLUSH(args...)
#endif
static const char * const ClazzNamePoint = "javax/media/nativewindow/util/Point";
@@ -30,6 +32,162 @@ static const char * const ClazzNamePointCstrSignature = "(II)V";
static jclass pointClz = NULL;
static jmethodID pointCstr = NULL;
+static jmethodID dumpStackID = NULL;
+
+typedef struct {
+ HANDLE threadHandle;
+ DWORD threadId;
+ volatile BOOL threadReady;
+ volatile BOOL threadDead;
+} DummyThreadContext;
+
+typedef struct {
+ HINSTANCE hInstance;
+ const TCHAR* wndClassName;
+ const TCHAR* wndName;
+ jint x;
+ jint y;
+ jint width;
+ jint height;
+ volatile HWND hWnd;
+ volatile BOOL threadReady;
+} DummyThreadCommand;
+
+#define TM_OPENWIN WM_APP+1
+#define TM_CLOSEWIN WM_APP+2
+#define TM_STOP WM_APP+3
+
+static const char * sTM_OPENWIN = "TM_OPENWIN";
+static const char * sTM_CLOSEWIN = "TM_CLOSEWIN";
+static const char * sTM_STOP = "TM_STOP";
+
+/** 3s timeout */
+static const int64_t TIME_OUT = 3000000;
+
+static jboolean DDT_CheckAlive(JNIEnv *env, const char *msg, DummyThreadContext *ctx) {
+ if( ctx->threadDead ) {
+ NativewindowCommon_throwNewRuntimeException(env, "DDT is dead at %s", msg);
+ return JNI_FALSE;
+ } else {
+ DBG_PRINT_FLUSH("*** DDT-Check ALIVE @ %s\n", msg);
+ return JNI_TRUE;
+ }
+}
+
+static jboolean DDT_WaitUntilCreated(JNIEnv *env, DummyThreadContext *ctx, BOOL created) {
+ const int64_t t0 = NativewindowCommon_CurrentTimeMillis();
+ int64_t t1 = t0;
+ if( created ) {
+ while( !ctx->threadReady && t1-t0 < TIME_OUT ) {
+ t1 = NativewindowCommon_CurrentTimeMillis();
+ }
+ if( !ctx->threadReady ) {
+ NativewindowCommon_throwNewRuntimeException(env, "TIMEOUT (%d ms) while waiting for DDT CREATED", (int)(t1-t0));
+ return JNI_FALSE;
+ }
+ DBG_PRINT_FLUSH("*** DDT-Check CREATED\n");
+ } else {
+ while( !ctx->threadDead && t1-t0 < TIME_OUT ) {
+ t1 = NativewindowCommon_CurrentTimeMillis();
+ }
+ if( !ctx->threadDead ) {
+ NativewindowCommon_throwNewRuntimeException(env, "TIMEOUT (%d ms) while waiting for DDT DESTROYED", (int)(t1-t0));
+ return JNI_FALSE;
+ }
+ DBG_PRINT_FLUSH("*** DDT-Check DEAD\n");
+ }
+ return JNI_TRUE;
+}
+
+static jboolean DDT_WaitUntilReady(JNIEnv *env, const char *msg, DummyThreadCommand *cmd) {
+ const int64_t t0 = NativewindowCommon_CurrentTimeMillis();
+ int64_t t1 = t0;
+ while( !cmd->threadReady && t1-t0 < TIME_OUT ) {
+ t1 = NativewindowCommon_CurrentTimeMillis();
+ }
+ if( !cmd->threadReady ) {
+ NativewindowCommon_throwNewRuntimeException(env, "TIMEOUT (%d ms) while waiting for DDT %s", (int)(t1-t0), msg);
+ return JNI_FALSE;
+ }
+ DBG_PRINT_FLUSH("*** DDT-Check READY @ %s\n", msg);
+ return JNI_TRUE;
+}
+
+static HWND DummyWindowCreate
+ (HINSTANCE hInstance, const TCHAR* wndClassName, const TCHAR* wndName, jint x, jint y, jint width, jint height)
+{
+ DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
+ DWORD dwStyle = WS_OVERLAPPEDWINDOW;
+ HWND hWnd = CreateWindowEx( dwExStyle,
+ wndClassName,
+ wndName,
+ dwStyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
+ x, y, width, height,
+ NULL, NULL, hInstance, NULL );
+ return hWnd;
+}
+
+static DWORD WINAPI DummyDispatchThreadFunc(LPVOID param)
+{
+ MSG msg;
+ BOOL bRet;
+ BOOL bEOL=FALSE;
+ DummyThreadContext *threadContext = (DummyThreadContext*)param;
+
+ /* there can not be any messages for us now, as the creator waits for
+ threadReady before continuing, but we must use this PeekMessage() to
+ create the thread message queue */
+ PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
+
+ /* now we can safely say: we have a qeue and are ready to receive messages */
+ // threadContext->threadId = GetCurrentThreadId();
+ threadContext->threadDead = FALSE;
+ threadContext->threadReady = TRUE;
+
+ while( !bEOL && (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0 ) {
+ if ( -1 == bRet ) {
+ fprintf(stderr, "DummyDispatchThread (id %d): GetMessage Error %d, werr %d\n",
+ (int)threadContext->threadId, (int)bRet, (int)GetLastError());
+ fflush(stderr);
+ bEOL = TRUE;
+ break; // EOL
+ } else {
+ switch(msg.message) {
+ case TM_OPENWIN: {
+ DummyThreadCommand *tParam = (DummyThreadCommand*)msg.wParam;
+ DBG_PRINT_FLUSH("*** DDT-Dispatch OPENWIN\n");
+ tParam->hWnd = DummyWindowCreate(tParam->hInstance, tParam->wndClassName, tParam->wndName, tParam->x, tParam->y, tParam->width, tParam->height);
+ tParam->threadReady = TRUE;
+ }
+ break;
+ case TM_CLOSEWIN: {
+ DummyThreadCommand *tParam = (DummyThreadCommand*)msg.wParam;
+ DBG_PRINT_FLUSH("*** DDT-Dispatch CLOSEWIN\n");
+ DestroyWindow(tParam->hWnd);
+ tParam->threadReady = TRUE;
+ }
+ break;
+ case TM_STOP: {
+ DummyThreadCommand *tParam = (DummyThreadCommand*)msg.wParam;
+ DBG_PRINT_FLUSH("*** DDT-Dispatch STOP -> DEAD\n");
+ tParam->threadReady = TRUE;
+ bEOL = TRUE;
+ }
+ break; // EOL
+ default:
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ break;
+ }
+ }
+ }
+ /* dead */
+ DBG_PRINT_FLUSH("*** DDT-Dispatch DEAD\n");
+ threadContext->threadDead = TRUE;
+ ExitThread(0);
+ return 0;
+}
+
HINSTANCE GetApplicationHandle() {
return GetModuleHandle(NULL);
@@ -37,16 +195,54 @@ HINSTANCE GetApplicationHandle() {
/* Java->C glue code:
* Java package: jogamp.nativewindow.windows.GDIUtil
- * Java method: boolean CreateWindowClass(long hInstance, java.lang.String clazzName, long wndProc)
- * C function: BOOL CreateWindowClass(HANDLE hInstance, LPCSTR clazzName, HANDLE wndProc);
+ * Java method: long CreateDummyDispatchThread0()
+ */
+JNIEXPORT jlong JNICALL
+Java_jogamp_nativewindow_windows_GDIUtil_CreateDummyDispatchThread0
+ (JNIEnv *env, jclass _unused)
+{
+ DWORD threadId = 0;
+ DummyThreadContext * dispThreadCtx = calloc(1, sizeof(DummyThreadContext));
+
+ dispThreadCtx->threadHandle = CreateThread(NULL, 0, DummyDispatchThreadFunc, (LPVOID)dispThreadCtx, 0, &threadId);
+ if( NULL == dispThreadCtx->threadHandle || 0 == threadId ) {
+ const HANDLE threadHandle = dispThreadCtx->threadHandle;
+ if( NULL != threadHandle ) {
+ TerminateThread(threadHandle, 0);
+ }
+ free(dispThreadCtx);
+ NativewindowCommon_throwNewRuntimeException(env, "DDT CREATE failed handle %p, id %d, werr %d",
+ (void*)threadHandle, (int)threadId, (int)GetLastError());
+ return (jlong)0;
+ }
+ if( JNI_FALSE == DDT_WaitUntilCreated(env, dispThreadCtx, TRUE) ) {
+ const HANDLE threadHandle = dispThreadCtx->threadHandle;
+ if( NULL != threadHandle ) {
+ TerminateThread(threadHandle, 0);
+ }
+ free(dispThreadCtx);
+ NativewindowCommon_throwNewRuntimeException(env, "DDT CREATE (ack) failed handle %p, id %d, werr %d",
+ (void*)threadHandle, (int)threadId, (int)GetLastError());
+ return (jlong)0;
+ }
+ DBG_PRINT_FLUSH("*** DDT Created %d\n", (int)threadId);
+ dispThreadCtx->threadId = threadId;
+ return (jlong) (intptr_t) dispThreadCtx;
+}
+
+/* Java->C glue code:
+ * Java package: jogamp.nativewindow.windows.GDIUtil
+ * Java method: boolean CreateWindowClass0(long hInstance, java.lang.String clazzName, long wndProc)
+ * C function: BOOL CreateWindowClass0(HANDLE hInstance, LPCSTR clazzName, HANDLE wndProc);
*/
JNIEXPORT jboolean JNICALL
-Java_jogamp_nativewindow_windows_GDIUtil_CreateWindowClass
- (JNIEnv *env, jclass _unused, jlong jHInstance, jstring jClazzName, jlong wndProc)
+Java_jogamp_nativewindow_windows_GDIUtil_CreateWindowClass0
+ (JNIEnv *env, jclass _unused, jlong jHInstance, jstring jClazzName, jlong wndProc,
+ jlong iconSmallHandle, jlong iconBigHandle)
{
HINSTANCE hInstance = (HINSTANCE) (intptr_t) jHInstance;
const TCHAR* clazzName = NULL;
- WNDCLASS wc;
+ WNDCLASSEX wc;
jboolean res;
#ifdef UNICODE
@@ -56,23 +252,25 @@ Java_jogamp_nativewindow_windows_GDIUtil_CreateWindowClass
#endif
ZeroMemory( &wc, sizeof( wc ) );
- if( GetClassInfo( hInstance, clazzName, &wc ) ) {
+ if( GetClassInfoEx( hInstance, clazzName, &wc ) ) {
// registered already
res = JNI_TRUE;
} else {
// register now
ZeroMemory( &wc, sizeof( wc ) );
+ wc.cbSize = sizeof(WNDCLASSEX);
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 = LoadCursor( NULL, IDC_ARROW);
+ wc.hIcon = (HICON) (intptr_t) iconBigHandle;
+ wc.hCursor = NULL;
wc.hbrBackground = NULL; // no background paint - GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = clazzName;
- res = ( 0 != RegisterClass( &wc ) ) ? JNI_TRUE : JNI_FALSE ;
+ wc.hIconSm = (HICON) (intptr_t) iconSmallHandle;
+ res = ( 0 != RegisterClassEx( &wc ) ) ? JNI_TRUE : JNI_FALSE ;
}
#ifdef UNICODE
@@ -86,15 +284,15 @@ Java_jogamp_nativewindow_windows_GDIUtil_CreateWindowClass
/* Java->C glue code:
* Java package: jogamp.nativewindow.windows.GDIUtil
- * Java method: boolean DestroyWindowClass(long hInstance, java.lang.String className)
- * C function: BOOL DestroyWindowClass(HANDLE hInstance, LPCSTR className);
+ * Java method: boolean DestroyWindowClass0(long hInstance, java.lang.String className, long dispThreadCtx)
*/
JNIEXPORT jboolean JNICALL
-Java_jogamp_nativewindow_windows_GDIUtil_DestroyWindowClass
- (JNIEnv *env, jclass _unused, jlong jHInstance, jstring jClazzName)
+Java_jogamp_nativewindow_windows_GDIUtil_DestroyWindowClass0
+ (JNIEnv *env, jclass gdiClazz, jlong jHInstance, jstring jClazzName, jlong jDispThreadCtx)
{
HINSTANCE hInstance = (HINSTANCE) (intptr_t) jHInstance;
const TCHAR* clazzName = NULL;
+ DummyThreadContext * dispThreadCtx = (DummyThreadContext *) (intptr_t) jDispThreadCtx;
jboolean res;
#ifdef UNICODE
@@ -111,55 +309,175 @@ Java_jogamp_nativewindow_windows_GDIUtil_DestroyWindowClass
(*env)->ReleaseStringUTFChars(env, jClazzName, clazzName);
#endif
+ if( NULL != dispThreadCtx) {
+ const HANDLE threadHandle = dispThreadCtx->threadHandle;
+ const DWORD threadId = dispThreadCtx->threadId;
+ DummyThreadCommand tParam = {0};
+ tParam.threadReady = FALSE;
+ DBG_PRINT_FLUSH("*** DDT Destroy %d\n", (int)threadId);
+#ifdef VERBOSE_ON
+ (*env)->CallStaticVoidMethod(env, gdiClazz, dumpStackID);
+#endif
+
+ if( JNI_FALSE == DDT_CheckAlive(env, sTM_STOP, dispThreadCtx) ) {
+ free(dispThreadCtx);
+ NativewindowCommon_throwNewRuntimeException(env, "DDT %s (alive) failed handle %p, id %d, werr %d",
+ sTM_STOP, (void*)threadHandle, (int)threadId, (int)GetLastError());
+ return JNI_FALSE;
+ }
+ if ( 0 != PostThreadMessage(dispThreadCtx->threadId, TM_STOP, (WPARAM)&tParam, 0) ) {
+ if( JNI_FALSE == DDT_WaitUntilReady(env, sTM_STOP, &tParam) ) {
+ if( NULL != threadHandle ) {
+ TerminateThread(threadHandle, 0);
+ }
+ free(dispThreadCtx);
+ NativewindowCommon_throwNewRuntimeException(env, "DDT Post %s (ack) failed handle %p, id %d, werr %d",
+ sTM_STOP, (void*)threadHandle, (int)threadId, (int)GetLastError());
+ return JNI_FALSE;
+ }
+ if( JNI_FALSE == DDT_WaitUntilCreated(env, dispThreadCtx, FALSE) ) {
+ if( NULL != threadHandle ) {
+ TerminateThread(threadHandle, 0);
+ }
+ free(dispThreadCtx);
+ NativewindowCommon_throwNewRuntimeException(env, "DDT KILL %s (ack) failed handle %p, id %d, werr %d",
+ sTM_STOP, (void*)threadHandle, (int)threadId, (int)GetLastError());
+ return JNI_FALSE;
+ }
+ free(dispThreadCtx); // free after proper DDT shutdown!
+ } else {
+ if( NULL != threadHandle ) {
+ TerminateThread(threadHandle, 0);
+ }
+ free(dispThreadCtx);
+ NativewindowCommon_throwNewRuntimeException(env, "DDT Post %s failed handle %p, id %d, werr %d",
+ sTM_STOP, (void*)threadHandle, (int)threadId, (int)GetLastError());
+ return JNI_FALSE;
+ }
+ }
+
return res;
}
-
/* Java->C glue code:
* Java package: jogamp.nativewindow.windows.GDIUtil
- * 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);
+ * Java method: long CreateDummyWindow0(long hInstance, java.lang.String className, jlong dispThreadCtx, java.lang.String windowName, int x, int y, int width, int height)
*/
JNIEXPORT jlong JNICALL
Java_jogamp_nativewindow_windows_GDIUtil_CreateDummyWindow0
- (JNIEnv *env, jclass _unused, jlong jHInstance, jstring jWndClassName, jstring jWndName, jint x, jint y, jint width, jint height)
+ (JNIEnv *env, jclass _unused, jlong jHInstance, jstring jWndClassName, jlong jDispThreadCtx, 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;
+ DummyThreadContext * dispThreadCtx = (DummyThreadContext *) (intptr_t) jDispThreadCtx;
+ DummyThreadCommand tParam = {0};
+
+ tParam.hInstance = (HINSTANCE) (intptr_t) jHInstance;
+ tParam.x = x;
+ tParam.y = y;
+ tParam.width = width;
+ tParam.height = height;
+ tParam.hWnd = 0;
+ tParam.threadReady = FALSE;
#ifdef UNICODE
- wndClassName = NewtCommon_GetNullTerminatedStringChars(env, jWndClassName);
- wndName = NewtCommon_GetNullTerminatedStringChars(env, jWndName);
+ tParam.wndClassName = NewtCommon_GetNullTerminatedStringChars(env, jWndClassName);
+ tParam.wndName = NewtCommon_GetNullTerminatedStringChars(env, jWndName);
#else
- wndClassName = (*env)->GetStringUTFChars(env, jWndClassName, NULL);
- wndName = (*env)->GetStringUTFChars(env, jWndName, NULL);
+ tParam.wndClassName = (*env)->GetStringUTFChars(env, jWndClassName, NULL);
+ tParam.wndName = (*env)->GetStringUTFChars(env, jWndName, NULL);
#endif
- dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
- dwStyle = WS_OVERLAPPEDWINDOW;
-
- hWnd = CreateWindowEx( dwExStyle,
- wndClassName,
- wndName,
- dwStyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
- x, y, width, height,
- NULL, NULL, hInstance, NULL );
+ if( NULL == dispThreadCtx ) {
+ tParam.hWnd = DummyWindowCreate(tParam.hInstance, tParam.wndClassName, tParam.wndName, tParam.x, tParam.y, tParam.width, tParam.height);
+ } else {
+ const HANDLE threadHandle = dispThreadCtx->threadHandle;
+ const DWORD threadId = dispThreadCtx->threadId;
+ if( JNI_FALSE == DDT_CheckAlive(env, sTM_OPENWIN, dispThreadCtx) ) {
+ free(dispThreadCtx);
+ NativewindowCommon_throwNewRuntimeException(env, "DDT %s (alive) failed handle %p, id %d, werr %d",
+ sTM_OPENWIN, (void*)threadHandle, (int)threadId, (int)GetLastError());
+ } else {
+ if( 0 != PostThreadMessage(dispThreadCtx->threadId, TM_OPENWIN, (WPARAM)&tParam, 0) ) {
+ if( JNI_FALSE == DDT_WaitUntilReady(env, sTM_OPENWIN, &tParam) ) {
+ if( NULL != threadHandle ) {
+ TerminateThread(threadHandle, 0);
+ }
+ free(dispThreadCtx);
+ tParam.hWnd = 0;
+ NativewindowCommon_throwNewRuntimeException(env, "DDT Post %s (ack) failed handle %p, id %d, werr %d",
+ sTM_OPENWIN, (void*)threadHandle, (int)threadId, (int)GetLastError());
+ }
+ } else {
+ if( NULL != threadHandle ) {
+ TerminateThread(threadHandle, 0);
+ }
+ free(dispThreadCtx);
+ tParam.hWnd = 0;
+ NativewindowCommon_throwNewRuntimeException(env, "DDT Post %s to handle %p, id %d failed, werr %d",
+ sTM_OPENWIN, (void*)threadHandle, (int)threadId, (int)GetLastError());
+ }
+ }
+ }
#ifdef UNICODE
- free((void*) wndClassName);
- free((void*) wndName);
+ free((void*) tParam.wndClassName);
+ free((void*) tParam.wndName);
#else
- (*env)->ReleaseStringUTFChars(env, jWndClassName, wndClassName);
- (*env)->ReleaseStringUTFChars(env, jWndName, wndName);
+ (*env)->ReleaseStringUTFChars(env, jWndClassName, tParam.wndClassName);
+ (*env)->ReleaseStringUTFChars(env, jWndName, tParam.wndName);
#endif
- return (jlong) (intptr_t) hWnd;
+ return (jlong) (intptr_t) tParam.hWnd;
}
+/*
+ * Class: jogamp_nativewindow_windows_GDIUtil
+ * Method: DestroyWindow0
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_windows_GDIUtil_DestroyWindow0
+(JNIEnv *env, jclass unused, jlong jDispThreadCtx, jlong jwin)
+{
+ jboolean res = JNI_TRUE;
+ DummyThreadContext * dispThreadCtx = (DummyThreadContext *) (intptr_t) jDispThreadCtx;
+ HWND hWnd = (HWND) (intptr_t) jwin;
+ if( NULL == dispThreadCtx ) {
+ DestroyWindow(hWnd);
+ } else {
+ const HANDLE threadHandle = dispThreadCtx->threadHandle;
+ const DWORD threadId = dispThreadCtx->threadId;
+ DummyThreadCommand tParam = {0};
+
+ tParam.hWnd = hWnd;
+ tParam.threadReady = FALSE;
+
+ if( JNI_FALSE == DDT_CheckAlive(env, sTM_CLOSEWIN, dispThreadCtx) ) {
+ free(dispThreadCtx);
+ res = JNI_FALSE;
+ NativewindowCommon_throwNewRuntimeException(env, "DDT %s (alive) failed handle %p, id %d, werr %d",
+ sTM_CLOSEWIN, (void*)threadHandle, (int)threadId, (int)GetLastError());
+ } else {
+ if ( 0 != PostThreadMessage(dispThreadCtx->threadId, TM_CLOSEWIN, (WPARAM)&tParam, 0) ) {
+ if( JNI_FALSE == DDT_WaitUntilReady(env, sTM_CLOSEWIN, &tParam) ) {
+ if( NULL != threadHandle ) {
+ TerminateThread(threadHandle, 0);
+ }
+ free(dispThreadCtx);
+ res = JNI_FALSE;
+ NativewindowCommon_throwNewRuntimeException(env, "DDT Post %s (ack) failed handle %p, id %d, werr %d",
+ sTM_CLOSEWIN, (void*)threadHandle, (int)threadId, (int)GetLastError());
+ }
+ } else {
+ if( NULL != threadHandle ) {
+ TerminateThread(threadHandle, 0);
+ }
+ free(dispThreadCtx);
+ res = JNI_FALSE;
+ NativewindowCommon_throwNewRuntimeException(env, "DDT Post %s to handle %p, id %d failed, werr %d",
+ sTM_CLOSEWIN, (void*)threadHandle, (int)threadId, (int)GetLastError());
+ }
+ }
+ }
+ return res;
+}
/*
* Class: jogamp_nativewindow_windows_GDIUtil
@@ -167,9 +485,9 @@ Java_jogamp_nativewindow_windows_GDIUtil_CreateDummyWindow0
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_windows_GDIUtil_initIDs0
- (JNIEnv *env, jclass clazz)
+ (JNIEnv *env, jclass gdiClazz)
{
- if(NativewindowCommon_init(env)) {
+ if( NativewindowCommon_init(env) ) {
jclass c = (*env)->FindClass(env, ClazzNamePoint);
if(NULL==c) {
NativewindowCommon_FatalError(env, "FatalError jogamp_nativewindow_windows_GDIUtil: can't find %s", ClazzNamePoint);
@@ -184,12 +502,16 @@ JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_windows_GDIUtil_initIDs0
NativewindowCommon_FatalError(env, "FatalError jogamp_nativewindow_windows_GDIUtil: can't fetch %s.%s %s",
ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature);
}
+ dumpStackID = (*env)->GetStaticMethodID(env, gdiClazz, "dumpStack", "()V");
+ if(NULL==dumpStackID) {
+ NativewindowCommon_FatalError(env, "FatalError jogamp_nativewindow_windows_GDIUtil: can't get method dumpStack");
+ }
}
return JNI_TRUE;
}
-LRESULT CALLBACK DummyWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- return DefWindowProc(hWnd,uMsg,wParam,lParam);
+static LRESULT CALLBACK DummyWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
+ return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
/*
@@ -224,3 +546,29 @@ JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_windows_GDIUtil_GetRelativeLo
return (*env)->NewObject(env, pointClz, pointCstr, (jint)dest.x, (jint)dest.y);
}
+/*
+ * Class: jogamp_nativewindow_windows_GDIUtil
+ * Method: IsChild0
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_windows_GDIUtil_IsChild0
+ (JNIEnv *env, jclass unused, jlong jwin)
+{
+ HWND hWnd = (HWND) (intptr_t) jwin;
+ LONG style = GetWindowLong(hWnd, GWL_STYLE);
+ BOOL bIsChild = 0 != (style & WS_CHILD) ;
+ return bIsChild ? JNI_TRUE : JNI_FALSE;
+}
+
+/*
+ * Class: jogamp_nativewindow_windows_GDIUtil
+ * Method: IsUndecorated0
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_windows_GDIUtil_IsUndecorated0
+ (JNIEnv *env, jclass unused, jlong jwin)
+{
+ HWND hWnd = (HWND) (intptr_t) jwin;
+ LONG style = GetWindowLong(hWnd, GWL_STYLE);
+ BOOL bIsUndecorated = 0 != (style & (WS_CHILD|WS_POPUP)) ;
+ return bIsUndecorated ? JNI_TRUE : JNI_FALSE;
+}
+