diff options
author | Sven Gothel <[email protected]> | 2010-05-28 16:53:08 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-05-28 16:53:08 +0200 |
commit | 811bd23ed37e392abb349f850a0b1dac635d021e (patch) | |
tree | c4faf8f5728eabd0fd9ed8a28816ab361984a9b7 /src/newt/native | |
parent | c787f50d77e2491eb0d8201d534a6fa4885a929e (diff) |
NEWT: Fix AWT Parenting ; Multithreading Issues ; Semantics: destroy(), .. ; Misc.
Due to incapabilities of the previous AWT/NEWT reparenting
the implementation and spec had to be changed to support this feature.
See the first 2 comments below.
- Tested on GNU/Linux (OK), Windows (a few bugs left)
-
TODO:
- Clarify the size/layout issue, ie who is responsible etc
In the test, incl AWT/NEWT, we set the size on the GLWindow
and ie pack the AWT Frame.
- Fix remaining [Windows] bugs ..
- Fix/Implement MacOSX port ..
Fix AWT/NEWT reparenting:
===========================
- Now NewtFactory's createWindow() method for parenting handles NativeWindow only
and is no more responsible for creating a child window upon an AWT Component.
See class com.jogamp.newt.awt.NewtCanvasAWT for NEWT/AWT parenting.
- New com.jogamp.newt.awt.NewtCanvasAWT, responsible for handling
AWT's reparent events via addNotify/removeNotify.
Reparenting is implemented via the new NEWT Window's reparentWindow() method.
Also sets the background erase to false, if supported.
- Fix zero size semantics in Window (setSize/setVisible)
Since a zero size window is not supported by many compoenent (Windowing system, OpenGL, ..)
we use the visibility methodology to not show a 0x0 window. See Javadoc.
AWT components may start with zero size.
- New NEWT Window: reparentWindow(NativeWindow newParent, Screen newScreen)
Allowing to change the parent of a window. Similar with the fullscreen toggle,
but without size/position change.
Native reparenting allows to keep alive the native
window while changing the container, hence it is preferred to a destroy/create cycle.
To benefit from the native reparenting, a NEWT implementation has to implement
'protected boolean reparentWindowImpl(long newWindowHandle)'
and return true, otherwise reparenting will be 'emulated' via
the expensive destroy/create cycle.
- NEWT's Window references all of it's children, if any
- NEWT's Window propagates setVisible/destroy actions to it's children.
- Fix NEWT's destroy() semantics.
A call of destroy() or destroy(false) shall only result in the destruction of the
native window (handle) nothing more. A subsequent setVisible(true) shall allow
the complete recreation of the Window into a usable state.
A call of destroy(true) destroys all resources the Window holds,
may include Screen/Display and OpenGL resources in case of GLWindow.
This is necessary to allow proper reparenting, where a native window may become
destroyed, but should be recreated via setVisible(true) later on.
- Fix NEWT set[Size|Position|Fullscreen|Visible] synchronization.
Use a recursive lock instead of the Window instance, otherwise arbitrary Window access
via AWT's EDT, NEWT's EDT or other threads can block.
Also removed a use pattern like:
key.lock()
try {
EDT.invoke(action());
} finally {
key.unlock();
}
Where action() itself uses the same lock object (here key), the result is a deadlock.
NativeWindow Changes:
======================
- We can use XInitThreads() now (concurrent threading support)
in combination with AWT.
Might have been some async in our NEWT locking in regards to AWT (sync()),
and the X11 Display changes made in c787f50d77e2491eb0d8201d534a6fa4885a929e.
- NativeWindow's window handle is _not_ transient like surface handle,
fixed documentation.
JOGL Changes:
=============
- New 'isRealized()' method in GLDrawable.
-
Misc Fixes
============
- Fix NEWT set[Size|Position|Fullscreen|Visible] duplicate code
Due to pure abstract signatures, the set[Size|Position|Fullscreen|Visible]
implementations of X11, OSX, .. contained duplicate code and state handling (size, pos, ..).
These are now decoupled, ie generic set[Size|Position|Fullscreen|Visible] implementations
calling simple set[Size|Position|Fullscreen|Visible]Impl implementations.
- Fix NEWT: Renamed setAutoDrawableClient(boolean) to setHandleDestroyNotify(boolean)
The semantic of
setAutoDrawableClient(boolean) defaults to false
was too complicated and specific, hence changed to
setHandleDestroyNotify(boolean) defaults to true
since its more clear and the name refers the window itself..
- Fix NEWT: Removed GLWindow's unused global window list
- Fix NEWT: Remove Window's unused event mask
- Rename com.jogamp.newt.impl.awt.AWTNewtFactory -> com.jogamp.newt.awt.NewtFactoryAWT
Diffstat (limited to 'src/newt/native')
-rw-r--r-- | src/newt/native/MacWindow.m | 31 | ||||
-rwxr-xr-x | src/newt/native/WindowsWindow.c | 63 | ||||
-rwxr-xr-x | src/newt/native/X11Window.c | 230 |
3 files changed, 252 insertions, 72 deletions
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m index 1956b6899..6e8599d92 100644 --- a/src/newt/native/MacWindow.m +++ b/src/newt/native/MacWindow.m @@ -60,15 +60,28 @@ void setFrameTopLeftPoint(NSWindow* pwin, NSWindow* win, jint x, jint y) NSRect visibleRect; // either screen or parent-window NSPoint pt; int d_pty=0; // parent titlebar height + int d_ptx=0; if(NULL==pwin) { visibleRect = [screen frame]; } else { visibleRect = [pwin frame]; - NSView* pview = [pwin contentView]; NSRect viewRect = [pview frame]; d_pty = visibleRect.size.height - viewRect.size.height; + //d_pty = visibleRect.origin.y - viewRect.size.height; + //d_ptx = visibleRect.size.height - viewRect.size.height; + fprintf(stderr, "pwin %lf/%lf %lfx%lf, pview %lf/%lf %lfx%lf -> %d/%d\n", + visibleRect.origin.x, + visibleRect.origin.y, + visibleRect.size.width, + visibleRect.size.height, + viewRect.origin.x, + viewRect.origin.y, + viewRect.size.width, + viewRect.size.height, + x, y); + } pt = NSMakePoint(visibleRect.origin.x + x, visibleRect.origin.y + visibleRect.size.height - y - d_pty); @@ -167,8 +180,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_macosx_MacDisplay_dispatchMessa NS_DURING - NSWindow* win = NULL; - NewtView* view = NULL; int num_events = 0; // Periodically take a break @@ -287,7 +298,17 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_macosx_MacWindow_createWindow0 backing: (NSBackingStoreType) bufferingType screen: screen] retain]; - NSWindow* parentWindow = (NSWindow*) ((intptr_t) parent); + NSObject *nsParentObj = (NSObject*) ((intptr_t) parent); + NSWindow* parentWindow = NULL; + if( nsParentObj != NULL && [nsParentObj isKindOfClass:[NSWindow class]] ) { + parentWindow = (NSWindow*) nsParentObj; + } else if( nsParentObj != NULL && [nsParentObj isKindOfClass:[NSView class]] ) { + NSView* view = (NSView*) nsParentObj; + parentWindow = [view window]; + fprintf(stderr, "createWindow0 - Parent is NSView : %p -> %p (win) \n", nsParentObj, parentWindow); + } else { + fprintf(stderr, "createWindow0 - Parent is neither NSWindow nor NSView : %p\n", nsParentObj); + } if(NULL!=parentWindow) { [parentWindow addChildWindow: window ordered: NSWindowAbove]; [window setParentWindow: parentWindow]; @@ -448,7 +469,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_macosx_MacWindow_changeContent [pool release]; - return oldView; + return (jlong) ((intptr_t) oldView); } /* diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index fabcab1c7..37fd9c621 100755 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -1034,7 +1034,7 @@ JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_getHeight /* * Class: com_jogamp_newt_impl_windows_WindowsWindow - * Method: initIDs + * Method: initIDs0 * Signature: ()Z */ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_initIDs0 @@ -1282,10 +1282,10 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setPositi /* * Class: com_jogamp_newt_impl_windows_WindowsWindow * Method: setFullscreen - * Signature: (JIIIIZZ)V + * Signature: (JIIIIZ)V */ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setFullscreen0 - (JNIEnv *env, jobject obj, jlong parent, jlong window, jint x, jint y, jint width, jint height, jboolean bIsUndecorated, jboolean on) + (JNIEnv *env, jobject obj, jlong parent, jlong window, jint x, jint y, jint width, jint height, jboolean bIsUndecorated) { UINT flags; HWND hwndP = (HWND) (intptr_t) parent; @@ -1293,10 +1293,55 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setFullsc HWND hWndInsertAfter; DWORD windowStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; - if ( JNI_TRUE == on ) { - hwndP = NULL; // full-screen is top level + // order of call sequence: (MS documentation) + // SetParent(.., NULL), SetWindowLong ( WS_POPUP ) + // SetParent(.., PARENT), SetWindowLong ( WS_CHILD ) + if ( NULL == hwndP ) { + SetParent(hwnd, NULL); + } + + if(NULL!=hwndP) { + windowStyle |= WS_CHILD ; + } else if (bIsUndecorated) { + windowStyle |= WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX; + } else { + windowStyle |= WS_OVERLAPPEDWINDOW; + } + SetWindowLong(hwnd, GWL_STYLE, windowStyle); + + if ( NULL != hwndP ) { + SetParent(hwnd, hwndP ); + } + + if ( NULL == hwndP ) { + flags = SWP_SHOWWINDOW; + hWndInsertAfter = HWND_TOPMOST; + } else { + flags = SWP_NOACTIVATE | SWP_NOZORDER; + hWndInsertAfter = 0; } + SetWindowPos(hwnd, hWndInsertAfter, x, y, width, height, flags); + + NewtWindows_requestFocus ( hwnd ); + + (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height); +} + +/* + * Class: com_jogamp_newt_impl_windows_WindowsWindow + * Method: reparentWindow0 + * Signature: (JIIIIZ)V + */ +JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_reparentWindow0 + (JNIEnv *env, jobject obj, jlong parent, jlong window, jint x, jint y, jint width, jint height, jboolean bIsUndecorated) +{ + UINT flags; + HWND hwndP = (HWND) (intptr_t) parent; + HWND hwnd = (HWND) (intptr_t) window; + HWND hWndInsertAfter; + DWORD windowStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; + // order of call sequence: (MS documentation) // SetParent(.., NULL), SetWindowLong ( WS_POPUP ) // SetParent(.., PARENT), SetWindowLong ( WS_CHILD ) @@ -1306,7 +1351,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setFullsc if(NULL!=hwndP) { windowStyle |= WS_CHILD ; - } else if (bIsUndecorated || on) { + } else if (bIsUndecorated) { windowStyle |= WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX; } else { windowStyle |= WS_OVERLAPPEDWINDOW; @@ -1317,7 +1362,8 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setFullsc SetParent(hwnd, hwndP ); } - if(on==JNI_TRUE) { + /** + if ( NULL == hwndP ) { flags = SWP_SHOWWINDOW; hWndInsertAfter = HWND_TOPMOST; } else { @@ -1326,10 +1372,11 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setFullsc } SetWindowPos(hwnd, hWndInsertAfter, x, y, width, height, flags); + */ NewtWindows_requestFocus ( hwnd ); - (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height); + // (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height); } /* diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index abaa3594f..f77f54cd1 100755 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -69,6 +69,7 @@ #define DBG_PRINT6(str, arg1, arg2, arg3, arg4, arg5, arg6) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5, arg6); #define DBG_PRINT7(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5, arg6, arg7); #define DBG_PRINT8(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + #define DBG_PRINT9(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); #define DUMP_VISUAL_INFO(a,b) _dumpVisualInfo((a),(b)) @@ -105,6 +106,7 @@ #define DBG_PRINT6(str, arg1, arg2, arg3, arg4, arg5, arg6) #define DBG_PRINT7(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7) #define DBG_PRINT8(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) + #define DBG_PRINT9(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) #define DUMP_VISUAL_INFO(a,b) @@ -173,6 +175,7 @@ static jclass newtWindowClz=NULL; static jmethodID windowChangedID = NULL; static jmethodID focusChangedID = NULL; +static jmethodID visibleChangedID = NULL; static jmethodID windowDestroyNotifyID = NULL; static jmethodID windowDestroyedID = NULL; static jmethodID windowCreatedID = NULL; @@ -312,6 +315,13 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_CompleteDisplay0 (*env)->CallVoidMethod(env, obj, displayCompletedID, javaObjectAtom, windowDeleteAtom); } +/** + * Window + */ + +// #define WINDOW_EVENT_MASK ( FocusChangeMask | StructureNotifyMask | ExposureMask | VisibilityNotify ) +#define WINDOW_EVENT_MASK ( FocusChangeMask | StructureNotifyMask | VisibilityNotify ) + static int putPtrIn32Long(unsigned long * dst, uintptr_t src) { int i=0; dst[i++] = (unsigned long) ( ( src >> 0 ) & 0xFFFFFFFF ) ; @@ -344,7 +354,7 @@ static void setJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlon (unsigned char *)&jogl_java_object_data, nitems_32); } -static jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom) { +static jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning) { Atom actual_type_return; int actual_format_return; int nitems_32 = ( sizeof(uintptr_t) == 8 ) ? 2 : 1 ; @@ -362,14 +372,18 @@ static jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, j &nitems_return, &bytes_after_return, &jogl_java_object_data_pp); if ( Success != res ) { - fprintf(stderr, "Warning: NEWT X11Window: Could not fetch Atom JOGL_JAVA_OBJECT window property (res %d) nitems_return %ld, bytes_after_return %ld, result 0!\n", res, nitems_return, bytes_after_return); + if(True==showWarning) { + fprintf(stderr, "Warning: NEWT X11Window: Could not fetch Atom JOGL_JAVA_OBJECT window property (res %d) nitems_return %ld, bytes_after_return %ld, result 0!\n", res, nitems_return, bytes_after_return); + } return NULL; } if(actual_type_return!=(Atom)javaObjectAtom || nitems_return<nitems_32 || NULL==jogl_java_object_data_pp) { XFree(jogl_java_object_data_pp); - fprintf(stderr, "Warning: NEWT X11Window: Fetched invalid Atom JOGL_JAVA_OBJECT window property (res %d) nitems_return %ld, bytes_after_return %ld, actual_type_return %ld, JOGL_JAVA_OBJECT %ld, result 0!\n", + if(True==showWarning) { + fprintf(stderr, "Warning: NEWT X11Window: Fetched invalid Atom JOGL_JAVA_OBJECT window property (res %d) nitems_return %ld, bytes_after_return %ld, actual_type_return %ld, JOGL_JAVA_OBJECT %ld, result 0!\n", res, nitems_return, bytes_after_return, (long)actual_type_return, javaObjectAtom); + } return NULL; } } @@ -385,29 +399,50 @@ static jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, j return jwindow; } -static void NewtWindows_requestFocus (Display *dpy, Window w) { - XWindowAttributes attributes; - - XLockDisplay(dpy) ; - +static void NewtWindows_requestFocus0 (Display *dpy, Window w, XWindowAttributes *xwa) { // Avoid 'BadMatch' errors from XSetInputFocus, ie if window is not viewable - XGetWindowAttributes(dpy, w, &attributes); - if(attributes.map_state == IsViewable) { + if(xwa->map_state == IsViewable) { XSetInputFocus(dpy, w, RevertToParent, CurrentTime); - XSync(dpy, False); } +} + +static void NewtWindows_requestFocus1 (Display *dpy, Window w) { + XWindowAttributes xwa; + + XLockDisplay(dpy) ; + + XGetWindowAttributes(dpy, w, &xwa); + NewtWindows_requestFocus0 (dpy, w, &xwa); + XSync(dpy, False); XUnlockDisplay(dpy) ; } -/** changing this attribute while a window is established, - * didn't impact the decoration - only at window creation time. -static void NewtWindows_setOverrideRedirect (Display *dpy, Window w, Bool val) { +/** + * Changing this attribute while a window is established, + * returns the previous value. + */ +static Bool NewtWindows_setOverrideRedirect0 (Display *dpy, Window w, XWindowAttributes *xwa, Bool newVal) { + Bool oldVal = xwa->override_redirect; XSetWindowAttributes xswa; - memset(&xswa, 0, sizeof(XSetWindowAttributes)); - xswa.override_redirect = val; - XChangeWindowAttributes(dpy, w, CWOverrideRedirect, &xswa); -} */ + + if(oldVal != newVal) { + memset(&xswa, 0, sizeof(XSetWindowAttributes)); + xswa.override_redirect = newVal; + XChangeWindowAttributes(dpy, w, CWOverrideRedirect, &xswa); + } + return oldVal; +} + +static Bool NewtWindows_setOverrideRedirect1 (Display *dpy, Window w, Bool newVal) { + XWindowAttributes xwa; + Bool oldVal; + + XSync(dpy, False); + XGetWindowAttributes(dpy, w, &xwa); + + return NewtWindows_setOverrideRedirect0 (dpy, w, &xwa, newVal); +} #define MWM_HINTS_DECORATIONS (1L << 1) #define PROP_MWM_HINTS_ELEMENTS 5 @@ -469,18 +504,26 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages return ; } + DBG_PRINT3( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, evt.type); + displayDispatchErrorHandlerEnable(1, env); - jwindow = getJavaWindowProperty(env, dpy, evt.xany.window, javaObjectAtom); + jwindow = getJavaWindowProperty(env, dpy, evt.xany.window, javaObjectAtom, + #ifdef VERBOSE_ON + True + #else + False + #endif + ); displayDispatchErrorHandlerEnable(0, env); if(NULL==jwindow) { - fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for invalid X11 window %p\n", + fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for X11 window %p\n", (void*)dpy, evt.type, (void*)evt.xany.window); + XUnlockDisplay(dpy) ; - // DBG_PRINT1( "X11: DispatchMessages 0x%X - Leave 2\n", dpy); - return; + continue; } switch(evt.type) { @@ -497,11 +540,10 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages } XUnlockDisplay(dpy) ; - // DBG_PRINT3( "X11: DispatchMessages 0x%X - Window %p, Event %d\n", dpy, jwindow, evt.type); switch(evt.type) { case ButtonPress: - NewtWindows_requestFocus ( dpy, evt.xany.window ); + NewtWindows_requestFocus1 ( dpy, evt.xany.window ); (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED, (jint) evt.xbutton.state, (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/); @@ -565,6 +607,16 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_FALSE); break; + case MapNotify: + DBG_PRINT1( "X11: event . MapNotify call 0x%X\n", (unsigned int)evt.xunmap.window); + // FIXME (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_TRUE); + break; + + case UnmapNotify: + DBG_PRINT1( "X11: event . UnmapNotify call 0x%X\n", (unsigned int)evt.xunmap.window); + // FIXME (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE); + break; + // unhandled events .. yet .. case VisibilityNotify: @@ -574,9 +626,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages DBG_PRINT1( "X11: event . Expose call 0x%X\n", (unsigned int)evt.xexpose.window); /* FIXME: Might want to send a repaint event .. */ break; - case UnmapNotify: - DBG_PRINT1( "X11: event . UnmapNotify call 0x%X\n", (unsigned int)evt.xunmap.window); - break; default: DBG_PRINT3("X11: event . unhandled %d 0x%X call 0x%X\n", evt.type, evt.type, (unsigned int)evt.xunmap.window); } @@ -644,6 +693,7 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Window_initIDs0 { windowChangedID = (*env)->GetMethodID(env, clazz, "windowChanged", "(IIII)V"); focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(Z)V"); + visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V"); windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V"); windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V"); windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(J)V"); @@ -652,6 +702,7 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Window_initIDs0 if (windowChangedID == NULL || focusChangedID == NULL || + visibleChangedID == NULL || windowDestroyNotifyID == NULL || windowDestroyedID == NULL || windowCreatedID == NULL || @@ -691,8 +742,6 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0 Screen* scrn; Atom wm_delete_atom; - DBG_PRINT5( "X11: CreateWindow %x/%d %dx%d, undeco %d\n", x, y, width, height, undecorated); - if(dpy==NULL) { _FatalError(env, "invalid display connection.."); } @@ -707,6 +756,11 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0 XSync(dpy, False); scrn = ScreenOfDisplay(dpy, scrn_idx); + if(0==windowParent) { + windowParent = XRootWindowOfScreen(scrn); + } + DBG_PRINT7( "X11: CreateWindow dpy %p, parent %p, %x/%d %dx%d, undeco %d\n", + (void*)dpy, (void*)windowParent, x, y, width, height, undecorated); // try given VisualID on screen memset(&visualTemplate, 0, sizeof(XVisualInfo)); @@ -721,8 +775,8 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0 XFree(pVisualQuery); pVisualQuery=NULL; } - DBG_PRINT5( "X11: [CreateWindow] trying given (dpy %p, screen %d, visualID: %d, parent 0x%X) found: %p\n", - dpy, scrn_idx, (int)visualID, (unsigned int)windowParent, visual); + DBG_PRINT5( "X11: [CreateWindow] trying given (dpy %p, screen %d, visualID: %d, parent %p) found: %p\n", + dpy, scrn_idx, (int)visualID, (void*)windowParent, visual); if (visual==NULL) { @@ -735,17 +789,12 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0 pVisualQuery=NULL; } - if(0==windowParent) { - windowParent = XRootWindowOfScreen(scrn); - } - - attrMask = ( CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect ) ; + attrMask = ( CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect ) ; memset(&xswa, 0, sizeof(xswa)); - xswa.override_redirect = ( JNI_TRUE == undecorated || 0 != parent ) ? True : False ; + xswa.override_redirect = ( 0 != parent ) ? True : False ; xswa.border_pixel = 0; xswa.background_pixel = 0; - xswa.event_mask = FocusChangeMask | ExposureMask | StructureNotifyMask | KeyPressMask | KeyReleaseMask; xswa.colormap = XCreateColormap(dpy, windowParent, // XRootWindow(dpy, scrn_idx), visual, @@ -778,10 +827,12 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0 long xevent_mask = 0; xevent_mask |= ButtonPressMask | ButtonReleaseMask | PointerMotionMask; xevent_mask |= KeyPressMask | KeyReleaseMask; - xevent_mask |= FocusChangeMask | ExposureMask | StructureNotifyMask | VisibilityNotify ; + xevent_mask |= WINDOW_EVENT_MASK ; XSelectInput(dpy, window, xevent_mask); } + NewtWindows_setDecorations (dpy, window, ( JNI_TRUE == undecorated ) ? False : True ); + XSync(dpy, False); XUnlockDisplay(dpy) ; @@ -808,7 +859,9 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CloseWindow0 } XLockDisplay(dpy) ; - jwindow = getJavaWindowProperty(env, dpy, w, javaObjectAtom); + DBG_PRINT2( "X11: CloseWindow START dpy %p, win %p\n", (void*)dpy, (void*)w); + + jwindow = getJavaWindowProperty(env, dpy, w, javaObjectAtom, True); if(NULL==jwindow) { _throwNewRuntimeException(dpy, env, "could not fetch Java Window object, bail out!"); return; @@ -825,6 +878,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CloseWindow0 XDestroyWindow(dpy, w); XSync(dpy, False); + DBG_PRINT0( "X11: CloseWindow END\n"); XUnlockDisplay(dpy) ; (*env)->CallVoidMethod(env, obj, windowDestroyedID); @@ -886,8 +940,63 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setSize0 /* * Class: com_jogamp_newt_impl_x11_X11Window + * Method: setPosition0 + * Signature: (JJII)V + */ +JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosition0 + (JNIEnv *env, jobject obj, jlong parent, jlong display, jlong window, jint x, jint y) +{ + Display * dpy = (Display *) (intptr_t) display; + Window w = (Window)window; + XWindowChanges xwc; + + DBG_PRINT2( "X11: setPos0 . XConfigureWindow %d/%d\n", x, y); + if(dpy==NULL) { + _FatalError(env, "invalid display connection.."); + } + XLockDisplay(dpy) ; + + memset(&xwc, 0, sizeof(XWindowChanges)); + xwc.x=x; + xwc.y=y; + XConfigureWindow(dpy, w, CWX|CWY, &xwc); + XSync(dpy, False); + + XUnlockDisplay(dpy) ; +} + +static void NewtWindows_reparentWindow + (Display * dpy, Screen * scrn, Window w, XWindowAttributes *xwa, jlong jparent, jint x, jint y, jboolean undecorated) +{ + Window parent = (0!=jparent)?(Window)jparent:XRootWindowOfScreen(scrn); + + DBG_PRINT7( "X11: reparentWindow dpy %p, parent %p/%p, win %p, %d/%d undec %d\n", + (void*)dpy, (void*) jparent, (void*)parent, (void*)w, x, y, undecorated); + + // let parent ignore reparent request + NewtWindows_setOverrideRedirect0 (dpy, w, xwa, True); + if(JNI_TRUE == undecorated) { + NewtWindows_setDecorations (dpy, w, False); + } + XSync(dpy, False); + + XReparentWindow( dpy, w, parent, x, y ); + XRaiseWindow(dpy, w); + XSync(dpy, False); + + NewtWindows_setOverrideRedirect0 (dpy, w, xwa, ( 0 != jparent ) ? True : False ); + if(JNI_FALSE == undecorated) { + NewtWindows_setDecorations (dpy, w, True); + } + XSync(dpy, False); + + DBG_PRINT0( "X11: reparentWindow X\n"); +} + +/* + * Class: com_jogamp_newt_impl_x11_X11Window * Method: setPosSizeDecor0 - * Signature: (JIJIIIIIZ)V + * Signature: (JJIJIIIIZ)V */ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosSizeDecor0 (JNIEnv *env, jobject obj, jlong jparent, jlong display, jint screen_index, jlong window, @@ -896,23 +1005,22 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosSizeDecor0 Display * dpy = (Display *) (intptr_t) display; Window w = (Window)window; Screen * scrn = ScreenOfDisplay(dpy, (int)screen_index); - Window parent = (0!=jparent)?(Window)jparent:XRootWindowOfScreen(scrn); XWindowChanges xwc; + XWindowAttributes xwa; - DBG_PRINT5( "X11: setPosSizeDecor0 %d/%d %dx%d, undec %d\n", x, y, width, height, undecorated); + DBG_PRINT8( "X11: setPosSizeDecor0 dpy %p, parent %p, win %p, %d/%d %dx%d undec %d\n", + (void*)dpy, (void*) jparent, (void*)w, x, y, width, height, undecorated); if(dpy==NULL) { _FatalError(env, "invalid display connection.."); } XLockDisplay(dpy) ; - // we need to reparent the window, - // to allow a child window to go fullscreen and back. - XReparentWindow( dpy, w, parent, x, y ); - XRaiseWindow(dpy, w); + XSync(dpy, False); + XGetWindowAttributes(dpy, w, &xwa); - NewtWindows_setDecorations (dpy, w, ( JNI_TRUE == undecorated ) ? False : True ); + NewtWindows_reparentWindow(dpy, scrn, w, &xwa, jparent, x, y, undecorated); memset(&xwc, 0, sizeof(XWindowChanges)); xwc.x=x; @@ -922,35 +1030,39 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosSizeDecor0 XConfigureWindow(dpy, w, CWX|CWY|CWWidth|CWHeight, &xwc); XSync(dpy, False); - NewtWindows_requestFocus ( dpy, w ); + NewtWindows_requestFocus0 ( dpy, w, &xwa ); + XSync(dpy, False); XUnlockDisplay(dpy) ; } /* * Class: com_jogamp_newt_impl_x11_X11Window - * Method: setPosition0 - * Signature: (JJII)V + * Method: reparentWindow0 + * Signature: (JJIJIIZ)V */ -JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosition0 - (JNIEnv *env, jobject obj, jlong parent, jlong display, jlong window, jint x, jint y) +JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_reparentWindow0 + (JNIEnv *env, jobject obj, jlong jparent, jlong display, jint screen_index, jlong window, jint x, jint y, jboolean undecorated) { Display * dpy = (Display *) (intptr_t) display; Window w = (Window)window; - XWindowChanges xwc; + Screen * scrn = ScreenOfDisplay(dpy, (int)screen_index); + XWindowAttributes xwa; + + DBG_PRINT6( "X11: reparentWindow0 dpy %p, parent %p, win %p, %d/%d undec %d\n", + (void*)dpy, (void*) jparent, (void*)w, x, y, undecorated); - DBG_PRINT2( "X11: setPos0 . XConfigureWindow %d/%d\n", x, y); if(dpy==NULL) { _FatalError(env, "invalid display connection.."); } XLockDisplay(dpy) ; - memset(&xwc, 0, sizeof(XWindowChanges)); - xwc.x=x; - xwc.y=y; - XConfigureWindow(dpy, w, CWX|CWY, &xwc); XSync(dpy, False); + XGetWindowAttributes(dpy, w, &xwa); + + NewtWindows_reparentWindow(dpy, scrn, w, &xwa, jparent, x, y, undecorated); XUnlockDisplay(dpy) ; + DBG_PRINT0( "X11: reparentWindow0 X\n"); } /* |