diff options
Diffstat (limited to 'src/newt/native/X11Window.c')
-rwxr-xr-x | src/newt/native/X11Window.c | 230 |
1 files changed, 171 insertions, 59 deletions
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"); } /* |