aboutsummaryrefslogtreecommitdiffstats
path: root/src/newt/native
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2023-10-02 19:42:42 +0200
committerSven Gothel <[email protected]>2023-10-02 19:42:42 +0200
commitf842843df2c77f5badaace6858d3336151ce0827 (patch)
tree1e0e9c6b689fccc580507f9a2809f785986466b1 /src/newt/native
parentb0893eda1035bcb1c6a88e52dac6cd00dfedf696 (diff)
Bug 1468 - SIGSEGV on use after free when destroying NEWT Window/Display via a native dispatch'ed event like key/mouse/touch input
SIGSEGV on use after free of native X11 Display* at XEventsQueued in DisplayDriver.DispatchMessages0. This potentially happens when an application destroys the NEWT Window/Display from an action being called directly from DisplayDriver.DispatchMessages0 (itself), i.e. keyboard or mouse input. DisplayDriver.DispatchMessages0 stays in the event loop and the next XEventsQueued call causes a SIGSEGV due to already deleted display driver connection and hence invalid native X11 Display*. This issue also exist for other Windowing System drivers, where the native (dispatch) method sticks to a loop and still (re)uses the window or display handle. One is WindowsWindow, where touch events are looped, but such handler could have closed the window. Querying the status of a window / display instance before dispatching is not be good enough - resource could already be GC'ed, so we also would need to query jobject status - would imply an addition Java callback +++ This fix: Having the Java callbacks return a boolean with the value Window.isNativeValid(). This way the dispatch logic - can bail out right away w/o using the resource anymore - must be reviewed by myself due to changed Call{Void->Boolean}*(..) invocation change. This review shall resolve potential similar issues. +++ Tested on X11/Linux/GNU, Windows and MacOS with new TestDestroyGLAutoDrawableNewtAWT, which tests all destruction invocation variants.
Diffstat (limited to 'src/newt/native')
-rw-r--r--src/newt/native/IOSNewtUIWindow.m40
-rw-r--r--src/newt/native/KDWindow.c41
-rw-r--r--src/newt/native/MacNewtNSWindow.m60
-rw-r--r--src/newt/native/WindowsWindow.c207
-rw-r--r--src/newt/native/X11Display.c221
-rw-r--r--src/newt/native/X11Window.c23
-rw-r--r--src/newt/native/bcm_vc_iv.c4
-rw-r--r--src/newt/native/drm_gbm.c2
8 files changed, 362 insertions, 236 deletions
diff --git a/src/newt/native/IOSNewtUIWindow.m b/src/newt/native/IOSNewtUIWindow.m
index 6e3e362a7..2efd7a25c 100644
--- a/src/newt/native/IOSNewtUIWindow.m
+++ b/src/newt/native/IOSNewtUIWindow.m
@@ -1,5 +1,5 @@
/**
- * Copyright 2019 JogAmp Community. All rights reserved.
+ * Copyright 2019-2023 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:
@@ -219,7 +219,7 @@ static jmethodID windowRepaintID = NULL;
CGRect viewFrame = [self frame];
- (*env)->CallVoidMethod(env, javaWindowObject, windowRepaintID, JNI_TRUE /* defer */,
+ (*env)->CallBooleanMethod(env, javaWindowObject, windowRepaintID, JNI_TRUE /* defer */,
(int)dirtyRect.origin.x, (int)viewFrame.size.height - (int)dirtyRect.origin.y,
(int)dirtyRect.size.width, (int)dirtyRect.size.height);
@@ -440,16 +440,16 @@ static jmethodID windowRepaintID = NULL;
+ (BOOL) initNatives: (JNIEnv*) env forClass: (jclass) clazz
{
- sendTouchScreenEventID = (*env)->GetMethodID(env, clazz, "sendTouchScreenEvent", "(SI[I[S[I[I[I[FF)V");
+ sendTouchScreenEventID = (*env)->GetMethodID(env, clazz, "sendTouchScreenEvent", "(SI[I[S[I[I[I[FF)Z");
sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZZIIZ)Z");
updatePixelScaleID = (*env)->GetMethodID(env, clazz, "updatePixelScale", "(ZFFFZ)V");
- visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V");
- insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)V");
- sizeScreenPosInsetsChangedID = (*env)->GetMethodID(env, clazz, "sizeScreenPosInsetsChanged", "(ZIIIIIIIIZZ)V");
- screenPositionChangedID = (*env)->GetMethodID(env, clazz, "screenPositionChanged", "(ZII)V");
- focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)V");
+ visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)Z");
+ insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)Z");
+ sizeScreenPosInsetsChangedID = (*env)->GetMethodID(env, clazz, "sizeScreenPosInsetsChanged", "(ZIIIIIIIIZZ)Z");
+ screenPositionChangedID = (*env)->GetMethodID(env, clazz, "screenPositionChanged", "(ZII)Z");
+ focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)Z");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
- windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V");
+ windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)Z");
requestFocusID = (*env)->GetMethodID(env, clazz, "requestFocus", "(Z)V");
if (sendTouchScreenEventID && sizeChangedID && updatePixelScaleID && visibleChangedID &&
insetsChangedID && sizeScreenPosInsetsChangedID &&
@@ -691,7 +691,7 @@ static jmethodID windowRepaintID = NULL;
DBG_PRINT( "updateInsets: [ l %d, r %d, t %d, b %d ]\n", cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3]);
if( NULL != env && NULL != javaWin ) {
- (*env)->CallVoidMethod(env, javaWin, insetsChangedID, JNI_FALSE, cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3]);
+ (*env)->CallBooleanMethod(env, javaWin, insetsChangedID, JNI_FALSE, cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3]);
}
}
@@ -709,13 +709,13 @@ static jmethodID windowRepaintID = NULL;
DBG_PRINT( "updatePos: [ x %d, y %d ]\n", (jint) pS.x, (jint) pS.y);
if( NULL != env && NULL != javaWin ) {
- (*env)->CallVoidMethod(env, javaWin, sizeScreenPosInsetsChangedID, defer,
- (jint) pS.x, (jint) pS.y,
- (jint) frameRect.size.width, (jint) frameRect.size.height,
- cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3],
- JNI_FALSE, // force
- withinLiveResize
- );
+ (*env)->CallBooleanMethod(env, javaWin, sizeScreenPosInsetsChangedID, defer,
+ (jint) pS.x, (jint) pS.y,
+ (jint) frameRect.size.width, (jint) frameRect.size.height,
+ cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3],
+ JNI_FALSE, // force
+ withinLiveResize
+ );
}
}
@@ -799,7 +799,7 @@ static jmethodID windowRepaintID = NULL;
return;
}
- (*env)->CallVoidMethod(env, javaWindowObject, focusChangedID, JNI_FALSE, (gained == YES) ? JNI_TRUE : JNI_FALSE);
+ (*env)->CallBooleanMethod(env, javaWindowObject, focusChangedID, JNI_FALSE, (gained == YES) ? JNI_TRUE : JNI_FALSE);
// detaching thread not required - daemon
// NewtCommon_ReleaseJNIEnv(shallBeDetached);
@@ -823,7 +823,7 @@ static jmethodID windowRepaintID = NULL;
DBG_PRINT("visibilityChanged: null JNIEnv\n");
return;
}
- (*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, (visible == YES) ? JNI_TRUE : JNI_FALSE);
+ (*env)->CallBooleanMethod(env, javaWindowObject, visibleChangedID, (visible == YES) ? JNI_TRUE : JNI_FALSE);
// detaching thread not required - daemon
// NewtCommon_ReleaseJNIEnv(shallBeDetached);
@@ -922,7 +922,7 @@ static jmethodID windowRepaintID = NULL;
CGPoint p0 = { 0, 0 };
p0 = [self getLocationOnScreen: p0];
DBG_PRINT( "windowDidMove: [ x %d, y %d ]\n", (jint) p0.x, (jint) p0.y);
- (*env)->CallVoidMethod(env, javaWindowObject, screenPositionChangedID, JNI_TRUE, (jint) p0.x, (jint) p0.y);
+ (*env)->CallBooleanMethod(env, javaWindowObject, screenPositionChangedID, JNI_TRUE, (jint) p0.x, (jint) p0.y);
// detaching thread not required - daemon
// NewtCommon_ReleaseJNIEnv(shallBeDetached);
diff --git a/src/newt/native/KDWindow.c b/src/newt/native/KDWindow.c
index 972267088..db34560a8 100644
--- a/src/newt/native/KDWindow.c
+++ b/src/newt/native/KDWindow.c
@@ -87,10 +87,10 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_DisplayDriver_DispatchMessages
(JNIEnv *env, jobject obj)
{
const KDEvent * evt;
- int numEvents = 0;
+ int num_events = 100;
// Periodically take a break
- while( numEvents<100 && NULL!=(evt=kdWaitEvent(0)) ) {
+ while( num_events > 0 && NULL!=(evt=kdWaitEvent(0)) ) {
KDWindow *kdWindow;
jobject javaWindow;
JOGLKDUserdata * userData = (JOGLKDUserdata *)(intptr_t)evt->userptr;
@@ -102,7 +102,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_DisplayDriver_DispatchMessages
javaWindow = userData->javaWindow;
DBG_PRINT( "[DispatchMessages]: userData %p, evt type: 0x%X\n", userData, evt->type);
- numEvents++;
+ num_events--;
// FIXME: support resize and window re-positioning events
@@ -120,6 +120,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_DisplayDriver_DispatchMessages
DBG_PRINT( "event window close : src: %p .. \n", userData);
closed = (*env)->CallBooleanMethod(env, javaWindow, windowDestroyNotifyID, JNI_FALSE);
DBG_PRINT( "event window close : src: %p, closed %d\n", userData, (int)closed);
+ num_events=0; // end loop
}
break;
case KD_EVENT_WINDOWPROPERTY_CHANGE:
@@ -131,7 +132,9 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_DisplayDriver_DispatchMessages
KDint32 v[2];
if(!kdGetWindowPropertyiv(kdWindow, KD_WINDOWPROPERTY_SIZE, v)) {
DBG_PRINT( "event window size change : src: %p %dx%d\n", userData, v[0], v[1]);
- (*env)->CallBooleanMethod(env, javaWindow, sizeChangedID, JNI_FALSE, JNI_FALSE, (jint) v[0], (jint) v[1], JNI_FALSE);
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, javaWindow, sizeChangedID, JNI_FALSE, JNI_FALSE, (jint) v[0], (jint) v[1], JNI_FALSE) ) {
+ num_events=0; // end loop
+ }
} else {
DBG_PRINT( "event window size change error: src: %p %dx%d\n", userData, v[0], v[1]);
}
@@ -145,7 +148,9 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_DisplayDriver_DispatchMessages
KDboolean visible;
kdGetWindowPropertybv(kdWindow, KD_WINDOWPROPERTY_VISIBILITY, &visible);
DBG_PRINT( "event window visibility: src: %p, v:%d\n", userData, visible);
- (*env)->CallVoidMethod(env, javaWindow, visibleChangedID, visible?JNI_TRUE:JNI_FALSE);
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, javaWindow, visibleChangedID, visible?JNI_TRUE:JNI_FALSE) ) {
+ num_events=0; // end loop
+ }
}
break;
default:
@@ -161,15 +166,19 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_DisplayDriver_DispatchMessages
// time = ev->timestamp
if(KD_INPUT_POINTER_SELECT==ptr->index) {
DBG_PRINT( "event mouse click: src: %p, s:%d, (%d,%d)\n", userData, ptr->select, ptr->x, ptr->y);
- (*env)->CallVoidMethod(env, javaWindow, sendMouseEventID,
- (ptr->select==0) ? (jshort) EVENT_MOUSE_RELEASED : (jshort) EVENT_MOUSE_PRESSED,
- (jint) 0,
- (jint) ptr->x, (jint) ptr->y, (short)1, 0.0f);
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, javaWindow, sendMouseEventID,
+ (ptr->select==0) ? (jshort) EVENT_MOUSE_RELEASED : (jshort) EVENT_MOUSE_PRESSED,
+ (jint) 0,
+ (jint) ptr->x, (jint) ptr->y, (short)1, 0.0f) ) {
+ num_events=0; // end loop
+ }
} else {
DBG_PRINT( "event mouse: src: %d, s:%p, i:0x%X (%d,%d)\n", userData, ptr->select, ptr->index, ptr->x, ptr->y);
- (*env)->CallVoidMethod(env, javaWindow, sendMouseEventID, (jshort) EVENT_MOUSE_MOVED,
- 0,
- (jint) ptr->x, (jint) ptr->y, (jshort)0, 0.0f);
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, javaWindow, sendMouseEventID, (jshort) EVENT_MOUSE_MOVED,
+ 0,
+ (jint) ptr->x, (jint) ptr->y, (jshort)0, 0.0f) ) {
+ num_events=0; // end loop
+ }
}
}
break;
@@ -192,10 +201,10 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_kd_WindowDriver_initIDs
#endif
windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(J)V");
sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZZIIZ)Z");
- visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V");
+ visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)Z");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
- sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(SIIISF)V");
- sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(SISSC)V");
+ sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(SIIISF)Z");
+ sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(SISSC)Z");
if (windowCreatedID == NULL ||
sizeChangedID == NULL ||
visibleChangedID == NULL ||
@@ -277,7 +286,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_WindowDriver_setVisible0
KDboolean v = (visible==JNI_TRUE)?KD_TRUE:KD_FALSE;
kdSetWindowPropertybv(w, KD_WINDOWPROPERTY_VISIBILITY, &v);
DBG_PRINT( "[setVisible] v=%d\n", visible);
- (*env)->CallVoidMethod(env, obj, visibleChangedID, visible);
+ (*env)->CallBooleanMethod(env, obj, visibleChangedID, visible);
}
JNIEXPORT void JNICALL Java_jogamp_newt_driver_kd_WindowDriver_setFullScreen0
diff --git a/src/newt/native/MacNewtNSWindow.m b/src/newt/native/MacNewtNSWindow.m
index e543f96e1..73bcaddcc 100644
--- a/src/newt/native/MacNewtNSWindow.m
+++ b/src/newt/native/MacNewtNSWindow.m
@@ -1,6 +1,6 @@
/*
+ * Copyright (c) 2011-2023 JogAmp Community. All rights reserved.
* Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
- * Copyright (c) 2011 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
@@ -377,7 +377,7 @@ static jmethodID windowRepaintID = NULL;
NSRect viewFrame = [self frame];
- (*env)->CallVoidMethod(env, javaWindowObject, windowRepaintID, JNI_TRUE /* defer */,
+ (*env)->CallBooleanMethod(env, javaWindowObject, windowRepaintID, JNI_TRUE /* defer */,
(int)dirtyRect.origin.x, (int)viewFrame.size.height - (int)dirtyRect.origin.y,
(int)dirtyRect.size.width, (int)dirtyRect.size.height);
@@ -398,7 +398,7 @@ static jmethodID windowRepaintID = NULL;
return;
}
- (*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, JNI_FALSE);
+ (*env)->CallBooleanMethod(env, javaWindowObject, visibleChangedID, JNI_FALSE);
// detaching thread not required - daemon
// NewtCommon_ReleaseJNIEnv(shallBeDetached);
@@ -419,7 +419,7 @@ static jmethodID windowRepaintID = NULL;
return;
}
- (*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, JNI_TRUE);
+ (*env)->CallBooleanMethod(env, javaWindowObject, visibleChangedID, JNI_TRUE);
// detaching thread not required - daemon
// NewtCommon_ReleaseJNIEnv(shallBeDetached);
@@ -727,10 +727,10 @@ static jmethodID windowRepaintID = NULL;
NSPoint location = [self screenPos2NewtClientWinPos: [NSEvent mouseLocation]];
- (*env)->CallVoidMethod(env, javaWindowObject, enqueueMouseEventID, JNI_FALSE,
- evType, javaMods[0],
- (jint) location.x, (jint) location.y,
- javaButtonNum, scrollDeltaY);
+ (*env)->CallBooleanMethod(env, javaWindowObject, enqueueMouseEventID, JNI_FALSE,
+ evType, javaMods[0],
+ (jint) location.x, (jint) location.y,
+ javaButtonNum, scrollDeltaY);
// detaching thread not required - daemon
// NewtCommon_ReleaseJNIEnv(shallBeDetached);
@@ -809,8 +809,8 @@ static jmethodID windowRepaintID = NULL;
DBG_PRINT("sendKeyEvent: %d/%d code 0x%X, char 0x%X, mods 0x%X/0x%X -> keySymChar 0x%X\n", i, len, (int)keyCode, (int)keyChar,
(int)mods, (int)javaMods, (int)keySymChar);
- (*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE,
- evType, javaMods, keyCode, (jchar)keyChar, (jchar)keySymChar);
+ (*env)->CallBooleanMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE,
+ evType, javaMods, keyCode, (jchar)keyChar, (jchar)keySymChar);
}
} else {
// non-printable chars
@@ -818,8 +818,8 @@ static jmethodID windowRepaintID = NULL;
DBG_PRINT("sendKeyEvent: code 0x%X\n", (int)keyCode);
- (*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE,
- evType, javaMods, keyCode, keyChar, keyChar);
+ (*env)->CallBooleanMethod(env, javaWindowObject, enqueueKeyEventID, JNI_FALSE,
+ evType, javaMods, keyCode, keyChar, keyChar);
}
// detaching thread not required - daemon
@@ -875,17 +875,17 @@ NS_ENDHANDLER
+ (BOOL) initNatives: (JNIEnv*) env forClass: (jclass) clazz
{
- enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(ZSIIISF)V");
- enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZSISCC)V");
+ enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(ZSIIISF)Z");
+ enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZSISCC)Z");
sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZZIIZ)Z");
updatePixelScaleID = (*env)->GetMethodID(env, clazz, "updatePixelScale", "(ZFFFZ)V");
- visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V");
- insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)V");
- sizeScreenPosInsetsChangedID = (*env)->GetMethodID(env, clazz, "sizeScreenPosInsetsChanged", "(ZIIIIIIIIZZ)V");
- screenPositionChangedID = (*env)->GetMethodID(env, clazz, "screenPositionChanged", "(ZII)V");
- focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)V");
+ visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)Z");
+ insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)Z");
+ sizeScreenPosInsetsChangedID = (*env)->GetMethodID(env, clazz, "sizeScreenPosInsetsChanged", "(ZIIIIIIIIZZ)Z");
+ screenPositionChangedID = (*env)->GetMethodID(env, clazz, "screenPositionChanged", "(ZII)Z");
+ focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)Z");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
- windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V");
+ windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)Z");
requestFocusID = (*env)->GetMethodID(env, clazz, "requestFocus", "(Z)V");
if (enqueueMouseEventID && enqueueKeyEventID && sizeChangedID && updatePixelScaleID && visibleChangedID &&
insetsChangedID && sizeScreenPosInsetsChangedID &&
@@ -1015,7 +1015,7 @@ NS_ENDHANDLER
DBG_PRINT( "updateInsets: [ l %d, r %d, t %d, b %d ]\n", cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3]);
if( NULL != env && NULL != javaWin ) {
- (*env)->CallVoidMethod(env, javaWin, insetsChangedID, JNI_FALSE, cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3]);
+ (*env)->CallBooleanMethod(env, javaWin, insetsChangedID, JNI_FALSE, cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3]);
}
}
@@ -1035,13 +1035,13 @@ NS_ENDHANDLER
DBG_PRINT( "updatePos: [ x %d, y %d ]\n", (jint) p0.x, (jint) p0.y);
if( NULL != env && NULL != javaWin ) {
- (*env)->CallVoidMethod(env, javaWin, sizeScreenPosInsetsChangedID, defer,
- (jint) p0.x, (jint) p0.y,
- (jint) contentRect.size.width, (jint) contentRect.size.height,
- cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3],
- JNI_FALSE, // force
- withinLiveResize
- );
+ (*env)->CallBooleanMethod(env, javaWin, sizeScreenPosInsetsChangedID, defer,
+ (jint) p0.x, (jint) p0.y,
+ (jint) contentRect.size.width, (jint) contentRect.size.height,
+ cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3],
+ JNI_FALSE, // force
+ withinLiveResize
+ );
}
}
@@ -1214,7 +1214,7 @@ NS_ENDHANDLER
return;
}
- (*env)->CallVoidMethod(env, javaWindowObject, focusChangedID, JNI_FALSE, (gained == YES) ? JNI_TRUE : JNI_FALSE);
+ (*env)->CallBooleanMethod(env, javaWindowObject, focusChangedID, JNI_FALSE, (gained == YES) ? JNI_TRUE : JNI_FALSE);
// detaching thread not required - daemon
// NewtCommon_ReleaseJNIEnv(shallBeDetached);
@@ -1373,7 +1373,7 @@ NS_ENDHANDLER
NSPoint p0 = { 0, 0 };
p0 = [self getLocationOnScreen: p0];
DBG_PRINT( "windowDidMove: [ x %d, y %d ]\n", (jint) p0.x, (jint) p0.y);
- (*env)->CallVoidMethod(env, javaWindowObject, screenPositionChangedID, JNI_TRUE, (jint) p0.x, (jint) p0.y);
+ (*env)->CallBooleanMethod(env, javaWindowObject, screenPositionChangedID, JNI_TRUE, (jint) p0.x, (jint) p0.y);
// detaching thread not required - daemon
// NewtCommon_ReleaseJNIEnv(shallBeDetached);
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index 4ce5567e1..201304dd9 100644
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -1,6 +1,6 @@
/*
+ * Copyright (c) 2010-2023 JogAmp Community. All rights reserved.
* Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
- * Copyright (c) 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
@@ -246,7 +246,7 @@ typedef struct {
int supportsMTouch;
} WindowUserData;
-static void UpdateInsets(JNIEnv *env, WindowUserData *wud, HWND hwnd);
+static jboolean UpdateInsets(JNIEnv *env, WindowUserData *wud, HWND hwnd);
typedef struct {
USHORT javaKey;
@@ -594,9 +594,9 @@ static int WmKeyDown(JNIEnv *env, jobject window, USHORT wkey, WORD repCnt, BYTE
modifiers = GetModifiers( javaVKeyUS );
- (*env)->CallVoidMethod(env, window, sendKeyEventID,
- (jshort) EVENT_KEY_PRESSED,
- (jint) modifiers, (jshort) javaVKeyUS, (jshort) javaVKeyXX, (jchar) utf16Char);
+ (*env)->CallBooleanMethod(env, window, sendKeyEventID,
+ (jshort) EVENT_KEY_PRESSED,
+ (jint) modifiers, (jshort) javaVKeyUS, (jshort) javaVKeyXX, (jchar) utf16Char);
return 0;
}
@@ -612,9 +612,9 @@ static int WmKeyUp(JNIEnv *env, jobject window, USHORT wkey, WORD repCnt, BYTE s
modifiers = GetModifiers( javaVKeyUS );
- (*env)->CallVoidMethod(env, window, sendKeyEventID,
- (jshort) EVENT_KEY_RELEASED,
- (jint) modifiers, (jshort) javaVKeyUS, (jshort) javaVKeyXX, (jchar) utf16Char);
+ (*env)->CallBooleanMethod(env, window, sendKeyEventID,
+ (jshort) EVENT_KEY_RELEASED,
+ (jint) modifiers, (jshort) javaVKeyUS, (jshort) javaVKeyXX, (jchar) utf16Char);
return 0;
}
@@ -700,7 +700,7 @@ static jboolean NewtWindows_setFullScreen(jboolean fullscreen)
return ( DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettings(&dm, flags) ) ? JNI_TRUE : JNI_FALSE;
}
-static void UpdateInsets(JNIEnv *env, WindowUserData *wud, HWND hwnd) {
+static jboolean UpdateInsets(JNIEnv *env, WindowUserData *wud, HWND hwnd) {
jobject window = wud->jinstance;
RECT outside;
RECT inside;
@@ -708,7 +708,7 @@ static void UpdateInsets(JNIEnv *env, WindowUserData *wud, HWND hwnd) {
if (IsIconic(hwnd)) {
wud->insets.left = wud->insets.top = wud->insets.right = wud->insets.bottom = -1;
- return;
+ return JNI_TRUE;
}
wud->insets.left = wud->insets.top = wud->insets.right = wud->insets.bottom = 0;
@@ -760,9 +760,10 @@ static void UpdateInsets(JNIEnv *env, WindowUserData *wud, HWND hwnd) {
(void*)hwnd, strategy, (int)wud->insets.left, (int)wud->insets.right, (int)wud->insets.top, (int)wud->insets.bottom,
(int) ( wud->insets.left + wud->insets.right ), (int) (wud->insets.top + wud->insets.bottom), wud->isInCreation);
if( !wud->isInCreation ) {
- (*env)->CallVoidMethod(env, window, insetsChangedID,
- JNI_FALSE, (int)wud->insets.left, (int)wud->insets.right, (int)wud->insets.top, (int)wud->insets.bottom);
+ return (*env)->CallBooleanMethod(env, window, insetsChangedID,
+ JNI_FALSE, (int)wud->insets.left, (int)wud->insets.right, (int)wud->insets.top, (int)wud->insets.bottom);
}
+ return JNI_TRUE;
}
static void WmSize(JNIEnv *env, WindowUserData * wud, HWND wnd, UINT type)
@@ -793,7 +794,10 @@ static void WmSize(JNIEnv *env, WindowUserData * wud, HWND wnd, UINT type)
}
// make sure insets are up to date
- UpdateInsets(env, wud, wnd);
+ if( JNI_FALSE == UpdateInsets(env, wud, wnd) ) {
+ DBG_PRINT( "WindowsWindow: WmSize.X window %p - Leave J, UpdateInsets\n", (void*)wnd);
+ return;
+ }
GetClientRect(wnd, &rc);
@@ -807,9 +811,15 @@ static void WmSize(JNIEnv *env, WindowUserData * wud, HWND wnd, UINT type)
if( !wud->isInCreation ) {
if( maxChanged ) {
jboolean v = wud->isMaximized ? JNI_TRUE : JNI_FALSE;
- (*env)->CallVoidMethod(env, window, maximizedChangedID, v, v);
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, window, maximizedChangedID, v, v) ) {
+ DBG_PRINT( "WindowsWindow: WmSize.X window %p - Leave J, maximized\n", (void*)wnd);
+ return;
+ }
+ }
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, window, sizeChangedID, JNI_FALSE, JNI_FALSE, wud->width, wud->height, JNI_FALSE) ) {
+ DBG_PRINT( "WindowsWindow: WmSize.X window %p - Leave J, sizeChanged\n", (void*)wnd);
+ return;
}
- (*env)->CallBooleanMethod(env, window, sizeChangedID, JNI_FALSE, JNI_FALSE, wud->width, wud->height, JNI_FALSE);
}
}
@@ -904,9 +914,9 @@ static BOOL SafeShowCursor(BOOL show) {
return b;
}
-static void sendTouchScreenEvent(JNIEnv *env, jobject window,
- short eventType, int modifiers, int actionIdx,
- int count, jshort* pointerNames, jint* x, jint* y, jfloat* pressure, float maxPressure) {
+static jboolean sendTouchScreenEvent(JNIEnv *env, jobject window,
+ short eventType, int modifiers, int actionIdx,
+ int count, jshort* pointerNames, jint* x, jint* y, jfloat* pressure, float maxPressure) {
jshortArray jNames = (*env)->NewShortArray(env, count);
if (jNames == NULL) {
NewtCommon_throwNewRuntimeException(env, "Could not allocate short array (names) of size %d", count);
@@ -931,9 +941,9 @@ static void sendTouchScreenEvent(JNIEnv *env, jobject window,
}
(*env)->SetFloatArrayRegion(env, jPressure, 0, count, pressure);
- (*env)->CallVoidMethod(env, window, sendTouchScreenEventID,
- (jshort)eventType, (jint)modifiers, (jint)actionIdx,
- jNames, jX, jY, jPressure, (jfloat)maxPressure);
+ return (*env)->CallBooleanMethod(env, window, sendTouchScreenEventID,
+ (jshort)eventType, (jint)modifiers, (jint)actionIdx,
+ jNames, jX, jY, jPressure, (jfloat)maxPressure);
}
// #define DO_ERASEBKGND 1
@@ -1062,7 +1072,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
DBG_PRINT("*** WindowsWindow: WM_SHOWWINDOW window %p: %d, at-init %d\n", wnd, wParam==TRUE, wud->isInCreation);
wud->visible = wParam==TRUE;
if( !wud->isInCreation ) {
- (*env)->CallVoidMethod(env, window, visibleChangedID, wParam==TRUE?JNI_TRUE:JNI_FALSE);
+ (*env)->CallBooleanMethod(env, window, visibleChangedID, wParam==TRUE?JNI_TRUE:JNI_FALSE);
}
break;
@@ -1082,12 +1092,14 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
if (GetUpdateRect(wnd, NULL, TRUE /* erase background */)) {
DBG_PRINT("*** WindowsWindow: WM_PAINT.0 (dirty)\n");
// WM_ERASEBKGND sent!
+ }
#else
if (GetUpdateRect(wnd, NULL, FALSE /* do not erase background */)) {
DBG_PRINT("*** WindowsWindow: WM_PAINT.0 (dirty)\n");
ValidateRect(wnd, NULL); // clear all!
+ }
#endif
- } else {
+ else {
DBG_PRINT("*** WindowsWindow: WM_PAINT.0 (clean)\n");
}
} else {
@@ -1095,7 +1107,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
DBG_PRINT("*** WindowsWindow: WM_PAINT.1 (dirty)\n");
// Let NEWT render the whole client area by issueing repaint for it, w/o looping through erase background
ValidateRect(wnd, NULL); // clear all!
- (*env)->CallVoidMethod(env, window, windowRepaintID, JNI_FALSE, 0, 0, -1, -1);
+ (*env)->CallBooleanMethod(env, window, windowRepaintID, JNI_FALSE, 0, 0, -1, -1);
} else {
DBG_PRINT("*** WindowsWindow: WM_PAINT.1 (clean)\n");
// shall not happen ?
@@ -1129,7 +1141,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
// ignore erase background, but let NEWT render the whole client area
DBG_PRINT("*** WindowsWindow: WM_ERASEBKGND.1 (repaint)\n");
ValidateRect(wnd, NULL); // clear all!
- (*env)->CallVoidMethod(env, window, windowRepaintID, JNI_FALSE, 0, 0, -1, -1);
+ (*env)->CallBooleanMethod(env, window, windowRepaintID, JNI_FALSE, 0, 0, -1, -1);
res = 1; // return 1 == done, OpenGL, etc .. erases the background, hence we claim to have just done this
}
break;
@@ -1183,7 +1195,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
DBG_PRINT("*** WindowsWindow: WM_SETFOCUS window %p, lost %p, at-init %d\n", wnd, (HWND)wParam, wud->isInCreation);
wud->focused = TRUE;
if( !wud->isInCreation ) {
- (*env)->CallVoidMethod(env, window, focusChangedID, JNI_FALSE, JNI_TRUE);
+ (*env)->CallBooleanMethod(env, window, focusChangedID, JNI_FALSE, JNI_TRUE);
}
useDefWindowProc = 1;
break;
@@ -1199,7 +1211,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
}
wud->focused = FALSE;
if( !wud->isInCreation ) {
- (*env)->CallVoidMethod(env, window, focusChangedID, JNI_FALSE, JNI_FALSE);
+ (*env)->CallBooleanMethod(env, window, focusChangedID, JNI_FALSE, JNI_FALSE);
}
useDefWindowProc = 1;
} else {
@@ -1261,11 +1273,11 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
NewtWindows_trackPointerLeave(wnd);
}
(*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
- (*env)->CallVoidMethod(env, window, sendMouseEventID,
- (jshort) EVENT_MOUSE_PRESSED,
- GetModifiers( 0 ),
- (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
- (jshort) 1, (jfloat) 0.0f);
+ (*env)->CallBooleanMethod(env, window, sendMouseEventID,
+ (jshort) EVENT_MOUSE_PRESSED,
+ GetModifiers( 0 ),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
+ (jshort) 1, (jfloat) 0.0f);
useDefWindowProc = 1;
}
}
@@ -1288,11 +1300,11 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
wud->pointerInside = 1;
NewtWindows_trackPointerLeave(wnd);
}
- (*env)->CallVoidMethod(env, window, sendMouseEventID,
- (jshort) EVENT_MOUSE_RELEASED,
- GetModifiers( 0 ),
- (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
- (jshort) 1, (jfloat) 0.0f);
+ (*env)->CallBooleanMethod(env, window, sendMouseEventID,
+ (jshort) EVENT_MOUSE_RELEASED,
+ GetModifiers( 0 ),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
+ (jshort) 1, (jfloat) 0.0f);
useDefWindowProc = 1;
}
}
@@ -1308,11 +1320,11 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
NewtWindows_trackPointerLeave(wnd);
}
(*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
- (*env)->CallVoidMethod(env, window, sendMouseEventID,
- (jshort) EVENT_MOUSE_PRESSED,
- GetModifiers( 0 ),
- (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
- (jshort) 2, (jfloat) 0.0f);
+ (*env)->CallBooleanMethod(env, window, sendMouseEventID,
+ (jshort) EVENT_MOUSE_PRESSED,
+ GetModifiers( 0 ),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
+ (jshort) 2, (jfloat) 0.0f);
useDefWindowProc = 1;
}
}
@@ -1332,11 +1344,11 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
wud->pointerInside = 1;
NewtWindows_trackPointerLeave(wnd);
}
- (*env)->CallVoidMethod(env, window, sendMouseEventID,
- (jshort) EVENT_MOUSE_RELEASED,
- GetModifiers( 0 ),
- (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
- (jshort) 2, (jfloat) 0.0f);
+ (*env)->CallBooleanMethod(env, window, sendMouseEventID,
+ (jshort) EVENT_MOUSE_RELEASED,
+ GetModifiers( 0 ),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
+ (jshort) 2, (jfloat) 0.0f);
useDefWindowProc = 1;
}
}
@@ -1352,11 +1364,11 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
NewtWindows_trackPointerLeave(wnd);
}
(*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
- (*env)->CallVoidMethod(env, window, sendMouseEventID,
- (jshort) EVENT_MOUSE_PRESSED,
- GetModifiers( 0 ),
- (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
- (jshort) 3, (jfloat) 0.0f);
+ (*env)->CallBooleanMethod(env, window, sendMouseEventID,
+ (jshort) EVENT_MOUSE_PRESSED,
+ GetModifiers( 0 ),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
+ (jshort) 3, (jfloat) 0.0f);
useDefWindowProc = 1;
}
}
@@ -1376,11 +1388,11 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
wud->pointerInside = 1;
NewtWindows_trackPointerLeave(wnd);
}
- (*env)->CallVoidMethod(env, window, sendMouseEventID,
- (jshort) EVENT_MOUSE_RELEASED,
- GetModifiers( 0 ),
- (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
- (jshort) 3, (jfloat) 0.0f);
+ (*env)->CallBooleanMethod(env, window, sendMouseEventID,
+ (jshort) EVENT_MOUSE_RELEASED,
+ GetModifiers( 0 ),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
+ (jshort) 3, (jfloat) 0.0f);
useDefWindowProc = 1;
}
}
@@ -1401,11 +1413,11 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
NewtWindows_trackPointerLeave(wnd);
SetCursor(wud->setPointerHandle);
}
- (*env)->CallVoidMethod(env, window, sendMouseEventID,
- (jshort) EVENT_MOUSE_MOVED,
- modifiers,
- (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
- (jshort) 0, (jfloat) 0.0f);
+ (*env)->CallBooleanMethod(env, window, sendMouseEventID,
+ (jshort) EVENT_MOUSE_MOVED,
+ modifiers,
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
+ (jshort) 0, (jfloat) 0.0f);
}
useDefWindowProc = 1;
}
@@ -1416,11 +1428,11 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
wud->width, wud->height, wud->pointerInside, wud->pointerCaptured, wud->touchDownCount, wud->touchDownLastUp);
if( 0 == wud->touchDownCount ) {
wud->pointerInside = 0;
- (*env)->CallVoidMethod(env, window, sendMouseEventID,
- (jshort) EVENT_MOUSE_EXITED,
- 0,
- (jint) -1, (jint) -1, // fake
- (jshort) 0, (jfloat) 0.0f);
+ (*env)->CallBooleanMethod(env, window, sendMouseEventID,
+ (jshort) EVENT_MOUSE_EXITED,
+ 0,
+ (jint) -1, (jint) -1, // fake
+ (jshort) 0, (jfloat) 0.0f);
useDefWindowProc = 1;
}
}
@@ -1446,11 +1458,11 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
break;
}
DBG_PRINT("*** WindowsWindow: WM_HSCROLL 0x%X, rotation %f, mods 0x%X\n", sb, rotation, modifiers);
- (*env)->CallVoidMethod(env, window, sendMouseEventID,
- (jshort) EVENT_MOUSE_WHEEL_MOVED,
- modifiers,
- (jint) 0, (jint) 0,
- (jshort) 1, (jfloat) rotation);
+ (*env)->CallBooleanMethod(env, window, sendMouseEventID,
+ (jshort) EVENT_MOUSE_WHEEL_MOVED,
+ modifiers,
+ (jint) 0, (jint) 0,
+ (jshort) 1, (jfloat) rotation);
useDefWindowProc = 1;
break;
}
@@ -1475,11 +1487,11 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
DBG_PRINT("*** WindowsWindow: WM_MOUSEWHEEL %d/%d, rotation %f, vKeys 0x%X, mods 0x%X\n",
(int)eventPt.x, (int)eventPt.y, rotationOrTilt, vKeys, modifiers);
}
- (*env)->CallVoidMethod(env, window, sendMouseEventID,
- (jshort) EVENT_MOUSE_WHEEL_MOVED,
- modifiers,
- (jint) eventPt.x, (jint) eventPt.y,
- (jshort) 1, (jfloat) rotationOrTilt);
+ (*env)->CallBooleanMethod(env, window, sendMouseEventID,
+ (jshort) EVENT_MOUSE_WHEEL_MOVED,
+ modifiers,
+ (jint) eventPt.x, (jint) eventPt.y,
+ (jshort) 1, (jfloat) rotationOrTilt);
useDefWindowProc = 1;
break;
}
@@ -1563,35 +1575,37 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
#endif
}
wud->pointerInside = allPInside;
+ jboolean winOK = JNI_TRUE;
+
if( sendFocus ) {
(*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
}
int sentCount = 0, updownCount=0, moveCount=0;
// Primary first, if available!
if( 0 <= actionIdx ) {
- sendTouchScreenEvent(env, window, eventType[actionIdx], modifiers, actionIdx,
- cInputs, pointerNames, x, y, pressure, maxPressure);
+ winOK = sendTouchScreenEvent(env, window, eventType[actionIdx], modifiers, actionIdx,
+ cInputs, pointerNames, x, y, pressure, maxPressure);
sentCount++;
}
// 1 Move second ..
- for (i=0; i < cInputs; i++) {
+ for (i=0; i < cInputs && JNI_TRUE == winOK; i++) {
short et = eventType[i];
if( (jshort) EVENT_MOUSE_MOVED == et ) {
if( i != actionIdx && 0 == moveCount ) {
- sendTouchScreenEvent(env, window, et, modifiers, i,
- cInputs, pointerNames, x, y, pressure, maxPressure);
+ winOK = sendTouchScreenEvent(env, window, et, modifiers, i,
+ cInputs, pointerNames, x, y, pressure, maxPressure);
sentCount++;
}
moveCount++;
}
}
// Up and downs last
- for (i=0; i < cInputs; i++) {
+ for (i=0; i < cInputs && JNI_TRUE == winOK; i++) {
short et = eventType[i];
if( (jshort) EVENT_MOUSE_MOVED != et ) {
if( i != actionIdx ) {
- sendTouchScreenEvent(env, window, et, modifiers, i,
- cInputs, pointerNames, x, y, pressure, maxPressure);
+ winOK = sendTouchScreenEvent(env, window, et, modifiers, i,
+ cInputs, pointerNames, x, y, pressure, maxPressure);
sentCount++;
}
updownCount++;
@@ -1614,7 +1628,6 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
useDefWindowProc = 1;
}
-
if (useDefWindowProc) {
return DefWindowProc(wnd, message, wParam, lParam);
}
@@ -2162,18 +2175,18 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowDriver_initIDs0
{
NewtCommon_init(env);
- insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)V");
+ insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)Z");
sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZZIIZ)Z");
- maximizedChangedID = (*env)->GetMethodID(env, clazz, "maximizedChanged", "(ZZ)V");
+ maximizedChangedID = (*env)->GetMethodID(env, clazz, "maximizedChanged", "(ZZ)Z");
positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(ZZII)Z");
- focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)V");
- visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V");
- sizePosInsetsFocusVisibleChangedID = (*env)->GetMethodID(env, clazz, "sizePosInsetsFocusVisibleChanged", "(ZZIIIIIIIIIIZ)V");
+ focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)Z");
+ visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)Z");
+ sizePosInsetsFocusVisibleChangedID = (*env)->GetMethodID(env, clazz, "sizePosInsetsFocusVisibleChanged", "(ZZIIIIIIIIIIZ)Z");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
- windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V");
- sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(SIIISF)V");
- sendTouchScreenEventID = (*env)->GetMethodID(env, clazz, "sendTouchScreenEvent", "(SII[S[I[I[FF)V");
- sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(SISSC)V");
+ windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)Z");
+ sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(SIIISF)Z");
+ sendTouchScreenEventID = (*env)->GetMethodID(env, clazz, "sendTouchScreenEvent", "(SII[S[I[I[FF)Z");
+ sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(SISSC)Z");
requestFocusID = (*env)->GetMethodID(env, clazz, "requestFocus", "(Z)V");
if (insetsChangedID == NULL ||
@@ -2448,9 +2461,9 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_InitWindow0
wud->xpos, wud->ypos, wud->width, wud->height, wud->focused, wud->visible);
if( wud->isMaximized ) {
- (*env)->CallVoidMethod(env, wud->jinstance, maximizedChangedID, JNI_TRUE, JNI_TRUE);
+ (*env)->CallBooleanMethod(env, wud->jinstance, maximizedChangedID, JNI_TRUE, JNI_TRUE);
}
- (*env)->CallVoidMethod(env, wud->jinstance, sizePosInsetsFocusVisibleChangedID, JNI_FALSE, JNI_FALSE,
+ (*env)->CallBooleanMethod(env, wud->jinstance, sizePosInsetsFocusVisibleChangedID, JNI_FALSE, JNI_FALSE,
(jint)wud->xpos, (jint)wud->ypos,
(jint)wud->width, (jint)wud->height,
(jint)wud->insets.left, (jint)wud->insets.right, (jint)wud->insets.top, (jint)wud->insets.bottom,
diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c
index a2fba9b7f..9ab49088a 100644
--- a/src/newt/native/X11Display.c
+++ b/src/newt/native/X11Display.c
@@ -40,6 +40,7 @@ jmethodID insetsVisibleChangedID = NULL;
static const char * const ClazzNameX11NewtWindow = "jogamp/newt/driver/x11/WindowDriver";
static jmethodID displayCompletedID = NULL;
+static jmethodID isNativeValidID = NULL;
static jmethodID sendRRScreenChangeNotifyID = NULL;
static jmethodID getCurrentThreadNameID = NULL;
@@ -250,27 +251,29 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0
// displayCompletedID = (*env)->GetMethodID(env, clazz, "displayCompleted", "(JJJIII)V"); // Variant using XKB
displayCompletedID = (*env)->GetMethodID(env, clazz, "displayCompleted", "(JJIII)V");
- sendRRScreenChangeNotifyID = (*env)->GetMethodID(env, clazz, "sendRRScreenChangeNotify", "(J)V");
+ isNativeValidID = (*env)->GetMethodID(env, clazz, "isNativeValidAsync", "()Z");
+ sendRRScreenChangeNotifyID = (*env)->GetMethodID(env, clazz, "sendRRScreenChangeNotify", "(J)Z");
getCurrentThreadNameID = (*env)->GetStaticMethodID(env, X11NewtWindowClazz, "getCurrentThreadName", "()Ljava/lang/String;");
dumpStackID = (*env)->GetStaticMethodID(env, X11NewtWindowClazz, "dumpStack", "()V");
- insetsChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "insetsChanged", "(ZIIII)V");
+ insetsChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "insetsChanged", "(ZIIII)Z");
sizeChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sizeChanged", "(ZZIIZ)Z");
positionChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "positionChanged", "(ZZII)Z");
- focusVisibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "focusVisibleChanged", "(ZII)V");
- visibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "visibleChanged", "(Z)V");
- insetsVisibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "insetsVisibleChanged", "(ZIIIII)V");
- sizePosMaxInsetsVisibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sizePosMaxInsetsVisibleChanged", "(ZZIIIIIIIIIIIZ)V");
- reparentNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "reparentNotify", "(J)V");
+ focusVisibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "focusVisibleChanged", "(ZII)Z");
+ visibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "visibleChanged", "(Z)Z");
+ insetsVisibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "insetsVisibleChanged", "(ZIIIII)Z");
+ sizePosMaxInsetsVisibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sizePosMaxInsetsVisibleChanged", "(ZZIIIIIIIIIIIZ)Z");
+ reparentNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "reparentNotify", "(J)Z");
windowDestroyNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowDestroyNotify", "(Z)Z");
- windowRepaintID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowRepaint", "(ZIIII)V");
- visibleChangedWindowRepaintID = (*env)->GetMethodID(env, X11NewtWindowClazz, "visibleChangedWindowRepaint", "(ZIIIII)V");
- sendMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEvent", "(SIIISF)V");
- sendMouseEventRequestFocusID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEventRequestFocus", "(SIIISF)V");
- visibleChangedSendMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "visibleChangedSendMouseEvent", "(ZISIIISF)V");
- sendTouchScreenEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendTouchScreenEvent", "(SII[S[I[I[FF)V");
- sendKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendKeyEvent", "(SISSCLjava/lang/String;)V");
+ windowRepaintID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowRepaint", "(ZIIII)Z");
+ visibleChangedWindowRepaintID = (*env)->GetMethodID(env, X11NewtWindowClazz, "visibleChangedWindowRepaint", "(ZIIIII)Z");
+ sendMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEvent", "(SIIISF)Z");
+ sendMouseEventRequestFocusID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEventRequestFocus", "(SIIISF)Z");
+ visibleChangedSendMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "visibleChangedSendMouseEvent", "(ZISIIISF)Z");
+ sendTouchScreenEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendTouchScreenEvent", "(SII[S[I[I[FF)Z");
+ sendKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendKeyEvent", "(SISSCLjava/lang/String;)Z");
if (displayCompletedID == NULL ||
+ isNativeValidID == NULL ||
sendRRScreenChangeNotifyID == NULL ||
getCurrentThreadNameID == NULL ||
dumpStackID == NULL ||
@@ -391,10 +394,10 @@ static int NewtWindows_updateVisibility(JNIEnv *env, Display *dpy, JavaWindow *j
return visibleChange;
}
-static void sendTouchScreenEvent(JNIEnv *env, JavaWindow *jw,
- short eventType, // MouseEvent.EVENT_MOUSE_PRESSED, MouseEvent.EVENT_MOUSE_RELEASED, MouseEvent.EVENT_MOUSE_MOVED
- int modifiers, // 0!
- int actionId) // index of multiple-pointer arrays representing the pointer which triggered the event
+static jboolean sendTouchScreenEvent(JNIEnv *env, JavaWindow *jw,
+ short eventType, // MouseEvent.EVENT_MOUSE_PRESSED, MouseEvent.EVENT_MOUSE_RELEASED, MouseEvent.EVENT_MOUSE_MOVED
+ int modifiers, // 0!
+ int actionId) // index of multiple-pointer arrays representing the pointer which triggered the event
{
jshort pointerNames[XI_TOUCHCOORD_COUNT];
jint x[XI_TOUCHCOORD_COUNT];
@@ -445,10 +448,11 @@ static void sendTouchScreenEvent(JNIEnv *env, JavaWindow *jw,
}
(*env)->SetFloatArrayRegion(env, jPressure, 0, cnt, pressure);
- (*env)->CallVoidMethod(env, jw->jwindow, sendTouchScreenEventID,
- (jshort)eventType, (jint)modifiers, (jint)actionIdx,
- jNames, jX, jY, jPressure, (jfloat)1.0f);
+ jboolean res = (*env)->CallBooleanMethod(env, jw->jwindow, sendTouchScreenEventID,
+ (jshort)eventType, (jint)modifiers, (jint)actionIdx,
+ jNames, jX, jY, jPressure, (jfloat)1.0f);
NewtCommon_ExceptionCheck1_throwNewRuntimeException(env, "X11Display.DispatchMessages0: XI: Exception occured at sendTouchScreenEvent(..)");
+ return res;
}
/*
@@ -467,6 +471,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
int autoRepeatModifiers = 0;
if ( NULL == dpy ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave 0\n", dpy);
return;
}
@@ -489,12 +494,25 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
jstring keyString = NULL;
char text[255];
+ // Don't use explicit Java callback, we simply break loop if regular Java callback on event returns JNI_FALSE
+ #if 0
+ if( JNIInvalidRefType == (*env)->GetObjectRefType(env, obj) ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave 1, invalidated DisplayDriver Object %p\n", dpy, obj);
+ return;
+ }
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, obj, isNativeValidID) ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave 2, closed DisplayDriver %p\n", dpy, obj);
+ return;
+ }
+ NewtCommon_ExceptionCheck1_throwNewRuntimeException(env, "X11Display.DispatchMessages0: Exception occured at isNativeValid()");
+ #endif
+
// XEventsQueued(dpy, X):
// QueuedAlready == XQLength(): No I/O Flush or system call doesn't work on some cards (eg ATI) ?)
// QueuedAfterFlush == XPending(): I/O Flush only if no already queued events are available
// QueuedAfterReading : QueuedAlready + if queue==0, attempt to read more ..
if ( 0 >= XEventsQueued(dpy, QueuedAfterFlush) ) {
- // DBG_PRINT( "X11: DispatchMessages 0x%X - Leave 1\n", dpy);
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave 3\n", dpy);
return;
}
@@ -502,13 +520,17 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
num_events--;
if(dpy!=evt.xany.display) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave 4, wrong display\n", dpy);
NewtCommon_throwNewRuntimeException(env, "wrong display, bail out!");
return ;
}
if( randr_event_base > 0 && RRScreenChangeNotify == ( evt.type - randr_event_base ) ) {
DBG_PRINT( "X11: DispatchMessages dpy %p, Event RRScreenChangeNotify %p\n", (void*)dpy, (void*)&evt);
- (*env)->CallVoidMethod(env, obj, sendRRScreenChangeNotifyID, (jlong)(intptr_t)&evt);
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, obj, sendRRScreenChangeNotifyID, (jlong)(intptr_t)&evt) ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave J, RRScreen\n", dpy);
+ num_events = 0; // end loop in case of destroyed display
+ }
NewtCommon_ExceptionCheck1_throwNewRuntimeException(env, "X11Display.DispatchMessages0: RR: Exception occured at sendRRScreenChangeNotify(..)");
continue; // next event
}
@@ -523,13 +545,16 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
XGenericEventCookie *evtCookie = &evt.xcookie; // hacks: https://keithp.com/blogs/Cursor_tracking/
int isXiEvent = GenericEvent == evtCookie->type && xi_opcode == evtCookie->extension && XGetEventData(dpy, evtCookie);
XIDeviceEvent *xiDevEv;
+ int xiDetail;
Window windowPointer;
if( !isXiEvent ) {
xiDevEv = NULL;
+ xiDetail = 0;
windowPointer = evt.xany.window;
DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)windowPointer, (int)evt.type);
} else {
xiDevEv = evtCookie->data;
+ xiDetail = xiDevEv->detail;
windowPointer = xiDevEv->event;
}
@@ -563,7 +588,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
}
DBG_PRINT( "X11: XI event - XI_TouchBegin Window %p, devid %d, touchid[%d] %d @ %d/%d\n", (void*)windowPointer, xiDevEv->deviceid,
i, jw->xiTouchCoords[i].id, jw->xiTouchCoords[i].x, jw->xiTouchCoords[i].y);
- sendTouchScreenEvent(env, jw, EVENT_MOUSE_PRESSED, 0, xiDevEv->detail % 32767);
+ XFreeEventData(dpy, evtCookie);
+ if( JNI_FALSE == sendTouchScreenEvent(env, jw, EVENT_MOUSE_PRESSED, 0, xiDetail % 32767) ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave J, touch-begin\n", dpy);
+ num_events = 0; // end loop in case of destroyed display
+ }
break;
case XI_TouchUpdate:
@@ -576,7 +605,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
}
DBG_PRINT( "X11: XI event - XI_TouchUpdate: Window %p, devid %d, touchid[%d] %d @ %d/%d\n", (void*)windowPointer, xiDevEv->deviceid,
i, jw->xiTouchCoords[i].id, jw->xiTouchCoords[i].x, jw->xiTouchCoords[i].y);
- sendTouchScreenEvent(env, jw, EVENT_MOUSE_MOVED, 0, xiDevEv->detail % 32767);
+ XFreeEventData(dpy, evtCookie);
+ if( JNI_FALSE == sendTouchScreenEvent(env, jw, EVENT_MOUSE_MOVED, 0, xiDetail % 32767) ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave J, touch-update\n", dpy);
+ num_events = 0; // end loop in case of destroyed display
+ }
break;
case XI_TouchEnd:
@@ -587,14 +620,20 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
}
DBG_PRINT( "X11: XI event - XI_TouchEnd: Window %p, devid %d, touchid[%d] %d @ %d/%d\n", (void*)windowPointer, xiDevEv->deviceid,
i, jw->xiTouchCoords[i].id, jw->xiTouchCoords[i].x, jw->xiTouchCoords[i].y);
- sendTouchScreenEvent(env, jw, EVENT_MOUSE_RELEASED, 0, xiDevEv->detail % 32767);
+ XFreeEventData(dpy, evtCookie);
+ if( JNI_FALSE == sendTouchScreenEvent(env, jw, EVENT_MOUSE_RELEASED, 0, xiDetail % 32767) ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave J, touch-end\n", dpy);
+ num_events = 0; // end loop in case of destroyed display
+ }
if ( i < XI_TOUCHCOORD_COUNT ) {
jw->xiTouchCoords[i].id = -1;
}
break;
+
+ default:
+ XFreeEventData(dpy, evtCookie);
}
}
- XFreeEventData(dpy, evtCookie);
continue; // next event, skip evt.type handling below
}
@@ -686,21 +725,30 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
switch(evt.type) {
case ButtonPress:
- (*env)->CallVoidMethod(env, jw->jwindow, sendMouseEventRequestFocusID, (jshort) EVENT_MOUSE_PRESSED,
- modifiers,
- (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jshort) evt.xbutton.button, 0.0f /*rotation*/);
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, jw->jwindow, sendMouseEventRequestFocusID, (jshort) EVENT_MOUSE_PRESSED,
+ modifiers,
+ (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jshort) evt.xbutton.button, 0.0f /*rotation*/) ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave J, press-mouseEvent\n", dpy);
+ num_events = 0; // end loop in case of destroyed display
+ }
NewtCommon_ExceptionCheck1_throwNewRuntimeException(env, "X11Display.DispatchMessages0: ButtonPress: Exception occured at sendMouseEventRequestFocus(..)");
break;
case ButtonRelease:
- (*env)->CallVoidMethod(env, jw->jwindow, sendMouseEventID, (jshort) EVENT_MOUSE_RELEASED,
- modifiers,
- (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jshort) evt.xbutton.button, 0.0f /*rotation*/);
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, jw->jwindow, sendMouseEventID, (jshort) EVENT_MOUSE_RELEASED,
+ modifiers,
+ (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jshort) evt.xbutton.button, 0.0f /*rotation*/) ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave J, release-mouseEvent\n", dpy);
+ num_events = 0; // end loop in case of destroyed display
+ }
NewtCommon_ExceptionCheck1_throwNewRuntimeException(env, "X11Display.DispatchMessages0: ButtonRelease: Exception occured at sendMouseEvent(..)");
break;
case MotionNotify:
- (*env)->CallVoidMethod(env, jw->jwindow, sendMouseEventID, (jshort) EVENT_MOUSE_MOVED,
- modifiers,
- (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jshort) 0, 0.0f /*rotation*/);
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, jw->jwindow, sendMouseEventID, (jshort) EVENT_MOUSE_MOVED,
+ modifiers,
+ (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jshort) 0, 0.0f /*rotation*/) ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave J, motion-mouseEvent\n", dpy);
+ num_events = 0; // end loop in case of destroyed display
+ }
NewtCommon_ExceptionCheck1_throwNewRuntimeException(env, "X11Display.DispatchMessages0: MotionNotify: Exception occured at sendMouseEvent(..)");
break;
case EnterNotify:
@@ -708,9 +756,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
{
uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw);
int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "EnterNotify");
- (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedSendMouseEventID, JNI_FALSE, (jint)visibleChange,
- (jshort) EVENT_MOUSE_ENTERED, modifiers,
- (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jshort) 0, 0.0f /*rotation*/);
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, jw->jwindow, visibleChangedSendMouseEventID, JNI_FALSE, (jint)visibleChange,
+ (jshort) EVENT_MOUSE_ENTERED, modifiers,
+ (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jshort) 0, 0.0f /*rotation*/) ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave J, enter-mouseEvent\n", dpy);
+ num_events = 0; // end loop in case of destroyed display
+ }
NewtCommon_ExceptionCheck1_throwNewRuntimeException(env, "X11Display.DispatchMessages0: EnterNotify: Exception occured at visibleChangedSendMouseEvent(..)");
}
break;
@@ -719,9 +770,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
{
uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw);
int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "LeaveNotify");
- (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedSendMouseEventID, JNI_FALSE, (jint)visibleChange,
- (jshort) EVENT_MOUSE_EXITED, modifiers,
- (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jshort) 0, 0.0f /*rotation*/);
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, jw->jwindow, visibleChangedSendMouseEventID, JNI_FALSE, (jint)visibleChange,
+ (jshort) EVENT_MOUSE_EXITED, modifiers,
+ (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jshort) 0, 0.0f /*rotation*/) ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave J, leave-mouseEvent\n", dpy);
+ num_events = 0; // end loop in case of destroyed display
+ }
NewtCommon_ExceptionCheck1_throwNewRuntimeException(env, "X11Display.DispatchMessages0: LeaveNotify: Exception occured at visibleChangedSendMouseEvent(..)");
}
break;
@@ -730,13 +784,19 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
XRefreshKeyboardMapping(&evt.xmapping);
break;
case KeyPress:
- (*env)->CallVoidMethod(env, jw->jwindow, sendKeyEventID, (jshort) EVENT_KEY_PRESSED,
- modifiers, javaVKeyUS, javaVKeyNN, (jchar) keyChar, keyString);
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, jw->jwindow, sendKeyEventID, (jshort) EVENT_KEY_PRESSED,
+ modifiers, javaVKeyUS, javaVKeyNN, (jchar) keyChar, keyString) ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave J, press-keyEvent\n", dpy);
+ num_events = 0; // end loop in case of destroyed display
+ }
NewtCommon_ExceptionCheck1_throwNewRuntimeException(env, "X11Display.DispatchMessages0: KeyPress: Exception occured at sendKeyEvent(..)");
break;
case KeyRelease:
- (*env)->CallVoidMethod(env, jw->jwindow, sendKeyEventID, (jshort) EVENT_KEY_RELEASED,
- modifiers, javaVKeyUS, javaVKeyNN, (jchar) keyChar, keyString);
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, jw->jwindow, sendKeyEventID, (jshort) EVENT_KEY_RELEASED,
+ modifiers, javaVKeyUS, javaVKeyNN, (jchar) keyChar, keyString) ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave J, release-keyEvent\n", dpy);
+ num_events = 0; // end loop in case of destroyed display
+ }
NewtCommon_ExceptionCheck1_throwNewRuntimeException(env, "X11Display.DispatchMessages0: KeyRelease: Exception occured at sendKeyEvent(..)");
break;
case DestroyNotify:
@@ -787,14 +847,17 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "ConfigureNotify");
NewtWindows_updateInsets(dpy, jw, False /* wait */, &left, &right, &top, &bottom);
Bool maxChanged = NewtWindows_updateMaximized(dpy, jw, netWMState);
- (*env)->CallVoidMethod(env, jw->jwindow, sizePosMaxInsetsVisibleChangedID, JNI_FALSE, JNI_FALSE,
- (jint) x_pos, (jint) y_pos,
- (jint) evt.xconfigure.width, (jint) evt.xconfigure.height,
- (jint)(maxChanged ? ( jw->maxHorz ? 1 : 0 ) : -1),
- (jint)(maxChanged ? ( jw->maxVert ? 1 : 0 ) : -1),
- (jint)left, (jint)right, (jint)top, (jint)bottom,
- (jint)visibleChange,
- JNI_FALSE);
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, jw->jwindow, sizePosMaxInsetsVisibleChangedID, JNI_FALSE, JNI_FALSE,
+ (jint) x_pos, (jint) y_pos,
+ (jint) evt.xconfigure.width, (jint) evt.xconfigure.height,
+ (jint)(maxChanged ? ( jw->maxHorz ? 1 : 0 ) : -1),
+ (jint)(maxChanged ? ( jw->maxVert ? 1 : 0 ) : -1),
+ (jint)left, (jint)right, (jint)top, (jint)bottom,
+ (jint)visibleChange,
+ JNI_FALSE) ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave J, sizePosMaxInsetsVis\n", dpy);
+ num_events = 0; // end loop in case of destroyed display
+ }
NewtCommon_ExceptionCheck1_throwNewRuntimeException(env, "X11Display.DispatchMessages0: ConfigureNotify: Exception occured at sizePosMaxInsetsVisibleChanged(..)");
}
break;
@@ -808,6 +871,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
closed = (*env)->CallBooleanMethod(env, jw->jwindow, windowDestroyNotifyID, JNI_FALSE);
DBG_PRINT( "X11: event . ClientMessage call %p type 0x%X, closed: %d\n",
(void*)evt.xclient.window, (unsigned int)evt.xclient.message_type, (int)closed);
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave 5, windowDeleteAtom received\n", dpy);
// Called by Window.java: CloseWindow();
num_events = 0; // end loop in case of destroyed display
}
@@ -818,7 +882,10 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
{
uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw);
int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "FocusIn");
- (*env)->CallVoidMethod(env, jw->jwindow, focusVisibleChangedID, JNI_FALSE, (jint)1, (jint)visibleChange);
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, jw->jwindow, focusVisibleChangedID, JNI_FALSE, (jint)1, (jint)visibleChange) ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave J, focus-in\n", dpy);
+ num_events = 0; // end loop in case of destroyed display
+ }
NewtCommon_ExceptionCheck1_throwNewRuntimeException(env, "X11Display.DispatchMessages0: FocusIn: Exception occured at focusVisibleChanged(..)");
}
break;
@@ -828,7 +895,10 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
{
uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw);
int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "FocusOut");
- (*env)->CallVoidMethod(env, jw->jwindow, focusVisibleChangedID, JNI_FALSE, (jint)0, (jint)visibleChange);
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, jw->jwindow, focusVisibleChangedID, JNI_FALSE, (jint)0, (jint)visibleChange) ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave J, focus-out\n", dpy);
+ num_events = 0; // end loop in case of destroyed display
+ }
NewtCommon_ExceptionCheck1_throwNewRuntimeException(env, "X11Display.DispatchMessages0: FocusOut: Exception occured at focusVisibleChanged(..)");
}
break;
@@ -840,7 +910,10 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw);
int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "VisibilityNotify");
if( 0 <= visibleChange ) {
- (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedID, 0 < visibleChange ? JNI_TRUE : JNI_FALSE);
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, jw->jwindow, visibleChangedID, 0 < visibleChange ? JNI_TRUE : JNI_FALSE) ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave J, vis-notify\n", dpy);
+ num_events = 0; // end loop in case of destroyed display
+ }
NewtCommon_ExceptionCheck1_throwNewRuntimeException(env, "X11Display.DispatchMessages0: VisibilityNotify: Exception occured at visibleChanged(..)");
}
#endif
@@ -852,14 +925,20 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
DBG_PRINT( "X11: event . Expose call %p %d/%d %dx%d count %d\n", (void*)evt.xexpose.window,
evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height, evt.xexpose.count);
if (evt.xexpose.count == 0 && evt.xexpose.width > 0 && evt.xexpose.height > 0) {
- (*env)->CallVoidMethod(env, jw->jwindow, windowRepaintID, JNI_FALSE,
- evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height);
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, jw->jwindow, windowRepaintID, JNI_FALSE,
+ evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height) ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave J, expose\n", dpy);
+ num_events = 0; // end loop in case of destroyed display
+ }
NewtCommon_ExceptionCheck1_throwNewRuntimeException(env, "X11Display.DispatchMessages0: Expose: Exception occured at windowRepaint(..)");
#if 0
uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw);
int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "Expose");
- (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedWindowRepaintID, JNI_FALSE, (jint)visibleChange,
- evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height);
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, jw->jwindow, visibleChangedWindowRepaintID, JNI_FALSE, (jint)visibleChange,
+ evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height) ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave J, focus-in-vis-repaint\n", dpy);
+ num_events = 0; // end loop in case of destroyed display
+ }
#endif
}
break;
@@ -874,10 +953,16 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
// insets: negative values are ignored
int left=-1, right=-1, top=-1, bottom=-1;
if( NewtWindows_updateInsets(dpy, jw, False /* wait */, &left, &right, &top, &bottom) ) {
- (*env)->CallVoidMethod(env, jw->jwindow, insetsVisibleChangedID, JNI_FALSE, left, right, top, bottom, 1);
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, jw->jwindow, insetsVisibleChangedID, JNI_FALSE, left, right, top, bottom, 1) ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave J, map-insets\n", dpy);
+ num_events = 0; // end loop in case of destroyed display
+ }
NewtCommon_ExceptionCheck1_throwNewRuntimeException(env, "X11Display.DispatchMessages0: MapNotify: Exception occured at insetsVisibleChanged(..)");
} else {
- (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedID, JNI_TRUE);
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, jw->jwindow, visibleChangedID, JNI_TRUE) ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave J, map\n", dpy);
+ num_events = 0; // end loop in case of destroyed display
+ }
NewtCommon_ExceptionCheck1_throwNewRuntimeException(env, "X11Display.DispatchMessages0: MapNotify: Exception occured at visibleChanged(..)");
}
}
@@ -890,7 +975,10 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
if( evt.xunmap.event == evt.xunmap.window ) {
// ignore child window notification
jw->isMapped = False;
- (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedID, JNI_FALSE);
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, jw->jwindow, visibleChangedID, JNI_FALSE) ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave J, unmap\n", dpy);
+ num_events = 0; // end loop in case of destroyed display
+ }
NewtCommon_ExceptionCheck1_throwNewRuntimeException(env, "X11Display.DispatchMessages0: UnmapNotify: Exception occured at visibleChanged(..)");
}
break;
@@ -924,7 +1012,10 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
(void*)evt.xreparent.parent, (void*)parentRoot, (void*)parentTopParent,
(void*)evt.xreparent.window, (void*)winRoot, (void*)winTopParent);
#endif
- (*env)->CallVoidMethod(env, jw->jwindow, reparentNotifyID, (jlong)evt.xreparent.parent);
+ if( JNI_FALSE == (*env)->CallBooleanMethod(env, jw->jwindow, reparentNotifyID, (jlong)evt.xreparent.parent) ) {
+ DBG_PRINT( "X11: DispatchMessages 0x%X - Leave J, reparent-notify\n", dpy);
+ num_events = 0; // end loop in case of destroyed display
+ }
NewtCommon_ExceptionCheck1_throwNewRuntimeException(env, "X11Display.DispatchMessages0: ReparentNotify: Exception occured at reparentNotify(..)");
}
break;
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index b53b596cc..142c59137 100644
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -382,16 +382,15 @@ static Status NewtWindows_getFrameExtends(Display *dpy, JavaWindow *javaWin, Boo
}
if( wait && tD < TIMEOUT_MS && evtCount < MAX_ATTEMPTS ) {
// wait for next X event to arrive, then we may try again
+ evtCount++;
#if 0
XEvent e;
XPeekEvent(dpy, &e); // FIXME: Blocks if queue is empty
- evtCount++;
DBG_PRINT( "NEWT FrameExtends: Waiting: #%d %ldms: evt %d, window %p (this=%d)\n",
evtCount, tD, e.type, (void*)e.xany.window, (javaWin->window == e.xany.window));
#else
struct timespec req = { .tv_sec = 0, .tv_nsec = 1000000L }; // 1ms
nanosleep(&req, NULL);
- evtCount++;
DBG_PRINT( "NEWT FrameExtends: Waiting: #%d %ldms ...\n", evtCount, tD );
#endif
} else {
@@ -635,6 +634,19 @@ static void NewtWindows_sendNET_WM_DESKTOP(Display *dpy, Window root, JavaWindow
XSendEvent ( dpy, root, False, SubstructureNotifyMask | SubstructureRedirectMask, &xev );
}
+static void NewtWindows_sendDeleteAtom(Display *dpy, JavaWindow * w) {
+ XEvent xev;
+ memset ( &xev, 0, sizeof(xev) );
+
+ xev.type = ClientMessage;
+ xev.xclient.window = w->window;
+ xev.xclient.message_type = w->javaObjectAtom;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = w->windowDeleteAtom;
+ xev.xclient.data.l[1] = 1; //source indication for normal applications
+ XSendEvent ( dpy, w->window, False, 0, &xev );
+}
+
/**
* Set fullscreen using Extended Window Manager Hints (EWMH)
@@ -1099,7 +1111,7 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_WindowDriver_GetSupportedReco
* Signature: (JJ)V
*/
JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0
- (JNIEnv *env, jobject obj, jlong display, jlong javaWindow /*, jlong kbdHandle*/, // XKB disabled for now
+ (JNIEnv *env, jobject obj, jobject displayDriver, jlong display, jlong javaWindow /*, jlong kbdHandle*/, // XKB disabled for now
jint randr_event_base, jint randr_error_base, jint xi_opcode)
{
Display * dpy = (Display *) (intptr_t) display;
@@ -1135,8 +1147,9 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0
XUnmapWindow(dpy, jw->window);
jw->isMapped=False;
- // Drain all events related to this window ..
- Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0(env, obj, display,
+ // Notify potential running dispatcher and drain all events related to this window ..
+ NewtWindows_sendDeleteAtom(dpy, jw);
+ Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0(env, displayDriver, display,
(jlong)(intptr_t)jw->javaObjectAtom, (jlong)(intptr_t)jw->windowDeleteAtom /*, kbdHandle */, // XKB disabled for now
randr_event_base, randr_error_base, xi_opcode);
diff --git a/src/newt/native/bcm_vc_iv.c b/src/newt/native/bcm_vc_iv.c
index 03a52c787..3a853fc5c 100644
--- a/src/newt/native/bcm_vc_iv.c
+++ b/src/newt/native/bcm_vc_iv.c
@@ -332,7 +332,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_initID
{
sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZZIIZ)Z");
positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(ZZII)Z");
- visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V");
+ visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)Z");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
if (sizeChangedID == NULL ||
positionChangedID == NULL ||
@@ -397,7 +397,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_CreateWin
vc_dispmanx_update_submit_sync( dispman_update );
- (*env)->CallVoidMethod(env, obj, visibleChangedID, JNI_TRUE);
+ (*env)->CallBooleanMethod(env, obj, visibleChangedID, JNI_TRUE);
DBG_PRINT( "BCM.Display Window.Create.X %p, element %p\n",
(void*)(intptr_t)dispman_display, (void*)(intptr_t)p->handle);
diff --git a/src/newt/native/drm_gbm.c b/src/newt/native/drm_gbm.c
index 7f2b7de88..722c11a49 100644
--- a/src/newt/native/drm_gbm.c
+++ b/src/newt/native/drm_gbm.c
@@ -223,7 +223,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_egl_gbm_WindowDriver_initIDs
{
sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZZIIZ)Z");
positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(ZZII)Z");
- visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V");
+ visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)Z");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
if (sizeChangedID == NULL ||
positionChangedID == NULL ||