From 7cb6cf2a9708d3f4e06f2215eb0d06b00fa6cd15 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Tue, 4 Dec 2012 07:10:59 +0100 Subject: SWT GLCanvas: Fix sporadic drop of redraw on X11 _and_ allow using custom GLCapabilities on X11 (feature complete) To allow custom GLCapabilities, we had to use native parenting on X11 w/ a new child window. The desired visualID chosen by the users GLCapabilities is passed to the new child window. The redraw drops must be caused by the original GDK or the new child GDK window. Now we use a plain X11 child window similar to NEWT's X11 window and NewtCanvasSWT, which doesn't expose this bug. (Note: SWTAccessor/GLCanvas still contains the uncommented GDK code path for further inspection, if desired) Also added SWTNewtEventFactory to test event handling on the SWT GLCanvas w/ GearsES2. TestSWTJOGLGLCanvas01GLn tests custom GLCapabilities now. SWTEDTUtil has been moved to private: com.jogamp.newt.swt -> jogamp.newt.swt. --- src/nativewindow/native/x11/Xmisc.c | 123 ++++++++++++++++++++++++++++++++---- 1 file changed, 110 insertions(+), 13 deletions(-) (limited to 'src/nativewindow/native') diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c index c73952693..a8d45f288 100644 --- a/src/nativewindow/native/x11/Xmisc.c +++ b/src/nativewindow/native/x11/Xmisc.c @@ -31,6 +31,8 @@ #include "jogamp_nativewindow_x11_X11Lib.h" #include "jogamp_nativewindow_x11_X11Util.h" +#include + // #define VERBOSE_ON 1 #ifdef VERBOSE_ON @@ -85,6 +87,8 @@ Bool XF86VidModeSetGammaRamp( #define RTLD_DEFAULT NULL #endif +#define X11_MOUSE_EVENT_MASK (ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask) + static const char * const ClazzNameBuffers = "com/jogamp/common/nio/Buffers"; static const char * const ClazzNameBuffersStaticCstrName = "copyByteBuffer"; static const char * const ClazzNameBuffersStaticCstrSignature = "(Ljava/nio/ByteBuffer;)Ljava/nio/ByteBuffer;"; @@ -436,17 +440,62 @@ Java_jogamp_nativewindow_x11_X11Lib_XCloseDisplay__J(JNIEnv *env, jclass _unused return _res; } +static void NativewindowX11_setNormalWindowEWMH (Display *dpy, Window w) { + Atom _NET_WM_WINDOW_TYPE = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE", False ); + Atom types[1]={0}; + types[0] = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE_NORMAL", False ); + XChangeProperty( dpy, w, _NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&types, 1); + XSync(dpy, False); +} + +#define DECOR_USE_MWM 1 // works for known WMs +// #define DECOR_USE_EWMH 1 // haven't seen this to work (NORMAL->POPUP, never gets undecorated) + +/* see */ +#define MWM_HINTS_DECORATIONS (1L << 1) +#define PROP_MWM_HINTS_ELEMENTS 5 + +static void NativewindowX11_setDecorations (Display *dpy, Window w, Bool decorated) { + +#ifdef DECOR_USE_MWM + unsigned long mwmhints[PROP_MWM_HINTS_ELEMENTS] = { MWM_HINTS_DECORATIONS, 0, decorated, 0, 0 }; // flags, functions, decorations, input_mode, status + Atom _MOTIF_WM_HINTS = XInternAtom( dpy, "_MOTIF_WM_HINTS", False ); +#endif + +#ifdef DECOR_USE_EWMH + Atom _NET_WM_WINDOW_TYPE = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE", False ); + Atom types[3]={0}; + int ntypes=0; + if(True==decorated) { + types[ntypes++] = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE_NORMAL", False ); + } else { + types[ntypes++] = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE_POPUP_MENU", False ); + } +#endif + +#ifdef DECOR_USE_MWM + XChangeProperty( dpy, w, _MOTIF_WM_HINTS, _MOTIF_WM_HINTS, 32, PropModeReplace, (unsigned char *)&mwmhints, PROP_MWM_HINTS_ELEMENTS); +#endif + +#ifdef DECOR_USE_EWMH + XChangeProperty( dpy, w, _NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&types, ntypes); +#endif + + XSync(dpy, False); +} + /* * Class: jogamp_nativewindow_x11_X11Lib - * Method: CreateDummyWindow - * Signature: (JIIII)J + * Method: CreateWindow + * Signature: (JJIIIIZZ)J */ -JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow - (JNIEnv *env, jclass unused, jlong display, jint screen_index, jint visualID, jint width, jint height) +JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateWindow + (JNIEnv *env, jclass unused, jlong parent, jlong display, jint screen_index, jint visualID, jint width, jint height, jboolean input, jboolean visible) { Display * dpy = (Display *)(intptr_t)display; int scrn_idx = (int)screen_index; - Window windowParent = 0; + Window root = RootWindow(dpy, scrn_idx); + Window windowParent = (Window) parent; Window window = 0; XVisualInfo visualTemplate; @@ -473,6 +522,9 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 1, 0, 0); scrn = ScreenOfDisplay(dpy, scrn_idx); + if(0==windowParent) { + windowParent = root; + } // try given VisualID on screen memset(&visualTemplate, 0, sizeof(XVisualInfo)); @@ -500,9 +552,6 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow pVisualQuery=NULL; } - if(0==windowParent) { - windowParent = XRootWindowOfScreen(scrn); - } attrMask = ( CWBackingStore | CWBackingPlanes | CWBackingPixel | CWBackPixmap | CWBorderPixel | CWColormap | CWOverrideRedirect ) ; @@ -514,15 +563,22 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow xswa.backing_store=NotUseful; /* NotUseful, WhenMapped, Always */ xswa.backing_planes=0; /* planes to be preserved if possible */ xswa.backing_pixel=0; /* value to use in restoring planes */ + if( input ) { + xswa.event_mask = X11_MOUSE_EVENT_MASK; + xswa.event_mask |= KeyPressMask | KeyReleaseMask ; + } + if( visible ) { + xswa.event_mask |= FocusChangeMask | SubstructureNotifyMask | StructureNotifyMask | ExposureMask ; + } xswa.colormap = XCreateColormap(dpy, - XRootWindow(dpy, scrn_idx), + windowParent, visual, AllocNone); window = XCreateWindow(dpy, windowParent, - 0, 0, + 0, 0, // only a hint, WM most likely will override width, height, 0, // border width depth, @@ -530,9 +586,25 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow visual, attrMask, &xswa); + if(0==window) { + NativewindowCommon_throwNewRuntimeException(env, "could not create Window, bail out!"); + return 0; + } + + NativewindowX11_setNormalWindowEWMH(dpy, window); + NativewindowX11_setDecorations(dpy, window, False); + + if( visible ) { + XEvent event; + + XMapWindow(dpy, window); + } + XSync(dpy, False); - XSelectInput(dpy, window, 0); // no events + if( !input ) { + XSelectInput(dpy, window, 0); // no events + } // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 0, 1); @@ -544,10 +616,10 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow /* * Class: jogamp_nativewindow_x11_X11Lib - * Method: DestroyDummyWindow + * Method: DestroyWindow * Signature: (JJ)V */ -JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_DestroyDummyWindow +JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_DestroyWindow (JNIEnv *env, jclass unused, jlong display, jlong window) { Display * dpy = (Display *)(intptr_t)display; @@ -559,12 +631,37 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_DestroyDummyWindow } NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 1, 0, 0); + XSelectInput(dpy, w, 0); XUnmapWindow(dpy, w); XSync(dpy, False); XDestroyWindow(dpy, w); // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 0, 1); } +JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_SetWindowPosSize + (JNIEnv *env, jclass unused, jlong display, jlong window, jint x, jint y, jint width, jint height) { + Display * dpy = (Display *)(intptr_t)display; + Window w = (Window) window; + XWindowChanges xwc; + int flags = 0; + + memset(&xwc, 0, sizeof(XWindowChanges)); + + if(0<=x && 0<=y) { + flags |= CWX | CWY; + xwc.x=x; + xwc.y=y; + } + + if(0