summaryrefslogtreecommitdiffstats
path: root/src/newt/native/X11Window.c
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-02-23 14:51:06 +0100
committerSven Gothel <[email protected]>2014-02-23 14:51:06 +0100
commit3352601e0860584509adf2b76f993d03893ded4b (patch)
tree974fccc8c0eb2f5ad9d4ffd741dfc35869ed67b5 /src/newt/native/X11Window.c
parentf51933f0ebe9ae030c26c066e59a728ce08b8559 (diff)
parentc67de337a8aaf52e36104c3f13e273aa19d21f1f (diff)
Merge branch 'master' into stash_glyphcache
Conflicts: make/scripts/tests.sh src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java src/jogl/classes/com/jogamp/graph/curve/Region.java src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java src/jogl/classes/com/jogamp/graph/font/Font.java src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java src/jogl/classes/jogamp/graph/curve/text/GlyphString.java src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java
Diffstat (limited to 'src/newt/native/X11Window.c')
-rw-r--r--src/newt/native/X11Window.c402
1 files changed, 231 insertions, 171 deletions
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index 0f93b3e76..2cc66c78d 100644
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -98,11 +98,11 @@ static void setJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlon
}
jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning) {
- Atom actual_type;
- int actual_format;
+ Atom actual_type = 0;
+ int actual_format = 0;
int nitems_32 = ( sizeof(uintptr_t) == 8 ) ? 2 : 1 ;
unsigned char * jogl_java_object_data_pp = NULL;
- jobject jwindow;
+ jobject jwindow = 0;
{
unsigned long nitems= 0;
@@ -122,7 +122,9 @@ jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong ja
}
if(actual_type!=(Atom)javaObjectAtom || nitems<nitems_32 || NULL==jogl_java_object_data_pp) {
- XFree(jogl_java_object_data_pp);
+ if( NULL != jogl_java_object_data_pp ) {
+ XFree(jogl_java_object_data_pp);
+ }
if(True==showWarning) {
fprintf(stderr, "Warning: NEWT X11Window: Fetched invalid Atom NEWT_JAVA_OBJECT window property (res %d) nitems %ld, bytes_after %ld, actual_type %ld, NEWT_JAVA_OBJECT %ld, result 0!\n",
res, nitems, bytes_after, (long)actual_type, (long)javaObjectAtom);
@@ -189,8 +191,8 @@ static Status NewtWindows_getWindowPositionRelative2Parent (Display *dpy, Window
return 0; // Error
}
static Status NewtWindows_getFrameExtends(Display *dpy, Window window, int *left, int *right, int *top, int *bottom) {
- Atom actual_type;
- int actual_format;
+ Atom actual_type = 0;
+ int actual_format = 0;
int nitems_32 = 4; // l, r, t, b
unsigned char * frame_extends_data_pp = NULL;
@@ -210,7 +212,9 @@ static Status NewtWindows_getFrameExtends(Display *dpy, Window window, int *left
}
if(nitems<nitems_32 || NULL==frame_extends_data_pp) {
- XFree(frame_extends_data_pp);
+ if( NULL != frame_extends_data_pp ) {
+ XFree(frame_extends_data_pp);
+ }
// DBG_PRINT( "Warning: NEWT X11Window: Fetched invalid Atom _NET_FRAME_EXTENTS window property (res %d) nitems %ld, bytes_after %ld, actual_type %ld, actual_format %d, _NET_FRAME_EXTENTS %ld, result 0!\n",
// res, nitems, bytes_after, (long)actual_type, actual_format, _NET_FRAME_EXTENTS);
return 0; // Error, but ok - ie window not mapped
@@ -271,18 +275,21 @@ static Bool NewtWindows_hasDecorations (Display *dpy, Window w) {
#ifdef DECOR_USE_MWM
Atom _MOTIF_WM_HINTS = XInternAtom( dpy, "_MOTIF_WM_HINTS", False );
- unsigned char *wm_data;
- Atom wm_type;
- int wm_format;
- unsigned long wm_nitems, wm_bytes_after;
+ unsigned char *wm_data = NULL;
+ Atom wm_type = 0;
+ int wm_format = 0;
+ unsigned long wm_nitems = 0, wm_bytes_after = 0;
if( Success == XGetWindowProperty(dpy, w, _MOTIF_WM_HINTS, 0, PROP_MWM_HINTS_ELEMENTS, False, AnyPropertyType,
&wm_type, &wm_format, &wm_nitems, &wm_bytes_after, &wm_data) ) {
- if(wm_type != None) {
+ if(wm_type != None && NULL != wm_data && wm_nitems >= PROP_MWM_HINTS_ELEMENTS) {
// unsigned long mwmhints[PROP_MWM_HINTS_ELEMENTS] = { MWM_HINTS_DECORATIONS, 0, decorated, 0, 0 }; // flags, functions, decorations, input_mode, status
unsigned long *hints = (unsigned long *) wm_data;
decor = ( 0 != (hints[0] & MWM_HINTS_DECORATIONS) ) && ( 0 != hints[2] );
}
+ if( NULL != wm_data ) {
+ XFree(wm_data);
+ }
}
#endif
@@ -299,9 +306,8 @@ static void NewtWindows_setNormalWindowEWMH (Display *dpy, Window w) {
#define _NET_WM_STATE_REMOVE 0
#define _NET_WM_STATE_ADD 1
-
-#define _NET_WM_FULLSCREEN ( 1 << 0 )
-#define _NET_WM_ABOVE ( 1 << 1 )
+#define _NET_WM_STATE_FLAG_FULLSCREEN ( 1 << 0 )
+#define _NET_WM_STATE_FLAG_ABOVE ( 1 << 1 )
/**
* Set fullscreen using Extended Window Manager Hints (EWMH)
@@ -314,101 +320,98 @@ static void NewtWindows_setNormalWindowEWMH (Display *dpy, Window w) {
* and resets it when leaving FS.
* The same is assumed for the decoration state.
*/
-static int NewtWindows_isFullscreenEWMHSupported (Display *dpy, Window w) {
+static int NewtWindows_getSupportedStackingEWMHFlags(Display *dpy, Window w) {
+#ifdef VERBOSE_ON
+ // Code doesn't work reliable on KDE4 ...
Atom _NET_WM_ALLOWED_ACTIONS = XInternAtom( dpy, "_NET_WM_ALLOWED_ACTIONS", False );
Atom _NET_WM_ACTION_FULLSCREEN = XInternAtom( dpy, "_NET_WM_ACTION_FULLSCREEN", False );
Atom _NET_WM_ACTION_ABOVE = XInternAtom( dpy, "_NET_WM_ACTION_ABOVE", False );
- Atom * actions;
- Atom type;
- unsigned long action_len, remain;
- int res = 0, form, i;
+ Atom * actions = NULL;
+ Atom type = 0;
+ unsigned long action_len = 0, remain = 0;
+ int res = 0, form = 0, i = 0;
Status s;
if ( Success == (s = XGetWindowProperty(dpy, w, _NET_WM_ALLOWED_ACTIONS, 0, 1024, False, AnyPropertyType,
&type, &form, &action_len, &remain, (unsigned char**)&actions)) ) {
- for(i=0; i<action_len; i++) {
- if(_NET_WM_ACTION_FULLSCREEN == actions[i]) {
- DBG_PRINT( "**************** X11: FS EWMH CHECK[%d]: _NET_WM_ACTION_FULLSCREEN (*)\n", i);
- res |= _NET_WM_FULLSCREEN ;
- } else if(_NET_WM_ACTION_ABOVE == actions[i]) {
- DBG_PRINT( "**************** X11: FS EWMH CHECK[%d]: _NET_WM_ACTION_ABOVE (*)\n", i);
- res |= _NET_WM_ABOVE ;
- }
-#ifdef VERBOSE_ON
- else {
- char * astr = XGetAtomName(dpy, actions[i]);
- DBG_PRINT( "**************** X11: FS EWMH CHECK[%d]: %s (unused)\n", i, astr);
- XFree(astr);
+ if( NULL != actions ) {
+ for(i=0; i<action_len; i++) {
+ if(_NET_WM_ACTION_FULLSCREEN == actions[i]) {
+ DBG_PRINT( "**************** X11: FS EWMH CHECK[%d]: _NET_WM_ACTION_FULLSCREEN (*)\n", i);
+ res |= _NET_WM_STATE_FLAG_FULLSCREEN ;
+ } else if(_NET_WM_ACTION_ABOVE == actions[i]) {
+ DBG_PRINT( "**************** X11: FS EWMH CHECK[%d]: _NET_WM_ACTION_ABOVE (*)\n", i);
+ res |= _NET_WM_STATE_FLAG_ABOVE ;
+ }
+ else {
+ char * astr = XGetAtomName(dpy, actions[i]);
+ DBG_PRINT( "**************** X11: FS EWMH CHECK[%d]: %s (unused)\n", i, astr);
+ XFree(astr);
+ }
}
-#endif
+ XFree(actions);
}
DBG_PRINT( "**************** X11: FS EWMH CHECK: 0x%X\n", res);
} else {
DBG_PRINT( "**************** X11: FS EWMH CHECK: XGetWindowProperty failed: %d\n", s);
}
- // above code doesn't work reliable on KDE4 ...
- res = _NET_WM_FULLSCREEN | _NET_WM_ABOVE ;
- return res;
+#endif
+ return _NET_WM_STATE_FLAG_FULLSCREEN | _NET_WM_STATE_FLAG_ABOVE ;
}
-static Bool NewtWindows_setFullscreenEWMH (Display *dpy, Window root, Window w, int ewmhFlags, Bool isVisible, Bool enable) {
+static Bool NewtWindows_setStackingEWMHFlags (Display *dpy, Window root, Window w, int ewmhFlags, Bool isVisible, Bool enable) {
Atom _NET_WM_STATE = XInternAtom( dpy, "_NET_WM_STATE", False );
Atom _NET_WM_STATE_ABOVE = XInternAtom( dpy, "_NET_WM_STATE_ABOVE", False );
Atom _NET_WM_STATE_FULLSCREEN = XInternAtom( dpy, "_NET_WM_STATE_FULLSCREEN", False );
- int ewmhMask = NewtWindows_isFullscreenEWMHSupported(dpy, w);
+ int ewmhMask = NewtWindows_getSupportedStackingEWMHFlags(dpy, w);
+ Bool changeFullscreen = 0 != ( ( _NET_WM_STATE_FLAG_FULLSCREEN & ewmhMask ) & ewmhFlags ) ;
+ Bool changeAbove = 0 != ( ( _NET_WM_STATE_FLAG_ABOVE & ewmhMask ) & ewmhFlags ) ;
Bool res = False;
if(0 == ewmhMask) {
return res;
}
- if(!isVisible && True==enable) {
- Atom types[2]={0};
- int ntypes=0;
-
- if( 0 != ( ( _NET_WM_FULLSCREEN & ewmhMask ) & ewmhFlags ) ) {
- types[ntypes++] = _NET_WM_STATE_FULLSCREEN;
- }
- if( 0 != ( ( _NET_WM_ABOVE & ewmhMask ) & ewmhFlags ) ) {
- types[ntypes++] = _NET_WM_STATE_ABOVE;
- }
- if(ntypes>0) {
- XChangeProperty( dpy, w, _NET_WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&types, ntypes);
- XSync(dpy, False);
- res = True;
- }
- } else {
- if(enable) {
- NewtWindows_setCWAbove(dpy, w);
- }
- XEvent xev;
- long mask = SubstructureNotifyMask | SubstructureRedirectMask ;
- int i=0;
-
- memset ( &xev, 0, sizeof(xev) );
-
- xev.type = ClientMessage;
- xev.xclient.window = w;
- xev.xclient.message_type = _NET_WM_STATE;
- xev.xclient.format = 32;
+ // _NET_WM_STATE: fullscreen and/or above
+ if( changeFullscreen || changeAbove ) {
+ {
+ // _NET_WM_STATE as event to root window
+ XEvent xev;
+ long mask = SubstructureNotifyMask | SubstructureRedirectMask ;
+ int i=0;
- xev.xclient.data.l[i++] = ( True == enable ) ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE ;
- if( 0 != ( ( _NET_WM_FULLSCREEN & ewmhMask ) & ewmhFlags ) ) {
- xev.xclient.data.l[i++] = _NET_WM_STATE_FULLSCREEN;
- }
- if( 0 != ( ( _NET_WM_ABOVE & ewmhMask ) & ewmhFlags ) ) {
- xev.xclient.data.l[i++] = _NET_WM_STATE_ABOVE;
- }
- xev.xclient.data.l[3] = 1; //source indication for normal applications
+ memset ( &xev, 0, sizeof(xev) );
+
+ xev.type = ClientMessage;
+ xev.xclient.window = w;
+ xev.xclient.message_type = _NET_WM_STATE;
+ xev.xclient.format = 32;
+
+ xev.xclient.data.l[i++] = enable ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE ;
+ if( changeFullscreen ) {
+ xev.xclient.data.l[i++] = _NET_WM_STATE_FULLSCREEN;
+ }
+ if( changeAbove ) {
+ xev.xclient.data.l[i++] = _NET_WM_STATE_ABOVE;
+ }
+ xev.xclient.data.l[3] = 1; //source indication for normal applications
- if(i>0) {
XSendEvent ( dpy, root, False, mask, &xev );
- res = True;
}
+ // Also change _NET_WM_BYPASS_COMPOSITOR!
+ // A value of 0 indicates no preference.
+ // A value of 1 hints the compositor to disabling compositing of this window.
+ // A value of 2 hints the compositor to not disabling compositing of this window
+ {
+ Atom _NET_WM_BYPASS_COMPOSITOR = XInternAtom( dpy, "_NET_WM_BYPASS_COMPOSITOR", False );
+ unsigned long value = enable ? 1 : 0;
+ XChangeProperty( dpy, w, _NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&value, 1);
+ }
+ XSync(dpy, False);
+ res = True;
}
- XSync(dpy, False);
- DBG_PRINT( "X11: reconfigureWindow0 FULLSCREEN EWMH ON %d, ewmhMask 0x%X, ewmhFlags 0x%X, visible %d: %d\n",
- enable, ewmhMask, ewmhFlags, isVisible, res);
+ DBG_PRINT( "X11: setStackingEWMHFlags ON %d, changeFullscreen %d, changeAbove %d, visible %d: %d\n",
+ enable, changeFullscreen, changeAbove, isVisible, res);
return res;
}
@@ -438,7 +441,7 @@ Status NewtWindows_updateInsets(JNIEnv *env, jobject jwindow, Display *dpy, Wind
return 0; // Error
}
-static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy, Window w, jboolean force) {
+static void NewtWindows_requestFocus (Display *dpy, Window w, Bool force) {
XWindowAttributes xwa;
Window focus_return;
int revert_to_return;
@@ -447,7 +450,7 @@ static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy,
XGetInputFocus(dpy, &focus_return, &revert_to_return);
DBG_PRINT( "X11: requestFocus dpy %p,win %p, force %d, hasFocus %d\n", dpy, (void*)w, force, focus_return==w);
- if( JNI_TRUE==force || focus_return!=w) {
+ if( True==force || focus_return!=w) {
DBG_PRINT( "X11: XRaiseWindow dpy %p, win %p\n", dpy, (void*)w);
XRaiseWindow(dpy, w);
NewtWindows_setCWAbove(dpy, w);
@@ -467,11 +470,11 @@ static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy,
*/
/*
- * Class: jogamp_newt_driver_x11_X11Window
+ * Class: jogamp_newt_driver_x11_WindowDriver
* Method: initIDs
* Signature: ()Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_initIDs0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_WindowDriver_initIDs0
(JNIEnv *env, jclass clazz)
{
return JNI_TRUE;
@@ -504,15 +507,22 @@ static void NewtWindows_setPosSize(Display *dpy, Window w, jint x, jint y, jint
}
}
+static void NewtWindows_setIcon(Display *dpy, Window w, int data_size, const unsigned char * data_ptr) {
+ Atom _NET_WM_ICON = XInternAtom(dpy, "_NET_WM_ICON", False);
+ Atom CARDINAL = XInternAtom(dpy, "CARDINAL", False);
+ XChangeProperty(dpy, w, _NET_WM_ICON, CARDINAL, 32, PropModeReplace, data_ptr, data_size);
+}
+
/*
- * Class: jogamp_newt_driver_x11_X11Window
+ * Class: jogamp_newt_driver_x11_WindowDriver
* Method: CreateWindow
*/
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWindow0
(JNIEnv *env, jobject obj, jlong parent, jlong display, jint screen_index,
jint visualID,
jlong javaObjectAtom, jlong windowDeleteAtom,
- jint x, jint y, jint width, jint height, jboolean autoPosition, int flags)
+ jint x, jint y, jint width, jint height, jboolean autoPosition, int flags,
+ jint pixelDataSize, jobject pixels, jint pixels_byte_offset, jboolean pixels_is_direct)
{
Display * dpy = (Display *)(intptr_t)display;
Atom wm_delete_atom = (Atom)windowDeleteAtom;
@@ -632,12 +642,27 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
{
XEvent event;
int left=0, right=0, top=0, bottom=0;
+ const unsigned char * pixelPtr = NULL;
+
+ // NOTE: MUST BE DIRECT BUFFER, since _NET_WM_ICON Atom uses buffer directly!
+ DBG_PRINT("X11: CreateWindow icon: size %d, pixels %p, offset %d, direct %d\n", pixelDataSize, (void*)pixels, pixels_byte_offset, pixels_is_direct);
+ if( 0 < pixelDataSize && NULL != pixels ) {
+ pixelPtr = (const unsigned char *) ( JNI_TRUE == pixels_is_direct ?
+ (*env)->GetDirectBufferAddress(env, pixels) :
+ (*env)->GetPrimitiveArrayCritical(env, pixels, NULL) );
+ DBG_PRINT("X11: CreateWindow icon: NIO %p\n", pixelPtr);
+ NewtWindows_setIcon(dpy, window, (int)pixelDataSize, pixelPtr+pixels_byte_offset);
+ }
XMapWindow(dpy, window);
XIfEvent( dpy, &event, WaitForMapNotify, (XPointer) window ); // wait to get proper insets values
XSync(dpy, False);
+ if( JNI_FALSE == pixels_is_direct && NULL != pixelPtr ) {
+ (*env)->ReleasePrimitiveArrayCritical(env, pixels, (void*)pixelPtr, JNI_ABORT);
+ }
+
// send insets before visibility, allowing java code a proper sync point!
NewtWindows_updateInsets(env, jwindow, dpy, window, &left, &right, &top, &bottom);
(*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE);
@@ -657,7 +682,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
NewtWindows_setPosSize(dpy, window, x, y, width, height);
if( TST_FLAG_IS_ALWAYSONTOP(flags) ) {
- NewtWindows_setFullscreenEWMH(dpy, root, window, _NET_WM_ABOVE, True, True);
+ NewtWindows_setStackingEWMHFlags(dpy, root, window, _NET_WM_STATE_FLAG_ABOVE, True, True);
}
}
@@ -666,16 +691,17 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
}
/*
- * Class: jogamp_newt_driver_x11_X11Window
+ * Class: jogamp_newt_driver_x11_WindowDriver
* Method: CloseWindow
* Signature: (JJ)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_CloseWindow0
- (JNIEnv *env, jobject obj, jlong display, jlong window, jlong javaObjectAtom, jlong windowDeleteAtom)
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0
+ (JNIEnv *env, jobject obj, jlong display, jlong window, jlong javaObjectAtom, jlong windowDeleteAtom /*, jlong kbdHandle*/) // XKB disabled for now
{
Display * dpy = (Display *) (intptr_t) display;
Window w = (Window)window;
jobject jwindow;
+ XWindowAttributes xwa;
if(dpy==NULL) {
NewtCommon_FatalError(env, "invalid display connection..");
@@ -694,42 +720,47 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_CloseWindow0
}
XSync(dpy, False);
+ memset(&xwa, 0, sizeof(XWindowAttributes));
+ XGetWindowAttributes(dpy, w, &xwa); // prefetch colormap to be destroyed after window destruction
XSelectInput(dpy, w, 0);
XUnmapWindow(dpy, w);
- XSync(dpy, False);
// Drain all events related to this window ..
- Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0(env, obj, display, javaObjectAtom, windowDeleteAtom);
+ Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0(env, obj, display, javaObjectAtom, windowDeleteAtom /*, kbdHandle */); // XKB disabled for now
XDestroyWindow(dpy, w);
- XSync(dpy, False);
+ if( None != xwa.colormap ) {
+ XFreeColormap(dpy, xwa.colormap);
+ }
+ XSync(dpy, True); // discard all events now, no more handler
(*env)->DeleteGlobalRef(env, jwindow);
DBG_PRINT( "X11: CloseWindow END\n");
}
-#if 0
+// #define REPARENT_WAIT_FOR_REPARENT_NOTIFY 1
+
+#ifdef REPARENT_WAIT_FOR_REPARENT_NOTIFY
static Bool WaitForReparentNotify( Display *dpy, XEvent *event, XPointer arg ) {
- return (event->type == ReparentNotify) && (event->xreparent.window == (Window) arg);
+ Bool res = (event->type == ReparentNotify) && (event->xreparent.window == (Window) arg);
+ #ifdef VERBOSE_ON
+ if( event->type == ReparentNotify ) {
+ DBG_PRINT( "X11.WaitForReparentNotify: Event ReparentNotify: Result %d, exp %p, has %p\n", (int)res, arg, event->xreparent.window);
+ } else {
+ DBG_PRINT( "X11.WaitForReparentNotify: Event 0x%X: Result %d, exp %p, has %p\n", (int)event->type, (int)res, arg, event->xreparent.window);
+ }
+ #endif
+ return res;
}
#endif
-/**
- * KDE cause lost input focus in fullscreen mode.
- * Using 'XGrabKeyboard(..)' would prevent the loss,
- * but also would disable WM task switcher etc.
- *
- * #define FS_GRAB_KEYBOARD 1
- *
- */
-
/*
- * Class: jogamp_newt_driver_x11_X11Window
+ * Class: jogamp_newt_driver_x11_WindowDriver
* Method: reconfigureWindow0
* Signature: (JIJJIIIII)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindow0
(JNIEnv *env, jobject obj, jlong jdisplay, jint screen_index,
jlong jparent, jlong jwindow, jlong windowDeleteAtom,
jint x, jint y, jint width, jint height, jint flags)
@@ -742,51 +773,60 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0
XEvent event;
Bool isVisible = !TST_FLAG_CHANGE_VISIBILITY(flags) && TST_FLAG_IS_VISIBLE(flags) ;
Bool tempInvisible = ( TST_FLAG_CHANGE_FULLSCREEN(flags) || TST_FLAG_CHANGE_PARENTING(flags) ) && isVisible ;
+ // Bool tempInvisible = TST_FLAG_CHANGE_PARENTING(flags) && isVisible ;
int fsEWMHFlags = 0;
if( TST_FLAG_CHANGE_FULLSCREEN(flags) ) {
- fsEWMHFlags |= _NET_WM_FULLSCREEN;
+ if( !TST_FLAG_IS_FULLSCREEN_SPAN(flags) ) { // doesn't work w/ spanning across monitors. See also Bug 770 & Bug 771
+ fsEWMHFlags |= _NET_WM_STATE_FLAG_FULLSCREEN;
+ }
if( TST_FLAG_IS_FULLSCREEN(flags) ) {
if( TST_FLAG_IS_ALWAYSONTOP(flags) ) {
- fsEWMHFlags |= _NET_WM_ABOVE; // fs on, above on
- } // else { } // fs on, above off
+ fsEWMHFlags |= _NET_WM_STATE_FLAG_ABOVE; // fs on, above on
+ } // else { } // fs on, above off
} else if( !TST_FLAG_IS_ALWAYSONTOP(flags) ) {
- fsEWMHFlags |= _NET_WM_ABOVE; // fs off, above off
- } // else { } // fs off, above on
- }
- if( TST_FLAG_CHANGE_ALWAYSONTOP(flags) ) {
- fsEWMHFlags |= _NET_WM_ABOVE; // toggle above
+ fsEWMHFlags |= _NET_WM_STATE_FLAG_ABOVE; // fs off, above off
+ } // else { } // fs off, above on
+ } else if( TST_FLAG_CHANGE_PARENTING(flags) ) {
+ // Fix for Unity WM, i.e. _remove_ persistent previous states
+ fsEWMHFlags |= _NET_WM_STATE_FLAG_FULLSCREEN; // fs off
+ if( !TST_FLAG_IS_ALWAYSONTOP(flags) ) {
+ fsEWMHFlags |= _NET_WM_STATE_FLAG_ABOVE; // above off
+ }
+ } else if( TST_FLAG_CHANGE_ALWAYSONTOP(flags) ) {
+ fsEWMHFlags |= _NET_WM_STATE_FLAG_ABOVE; // toggle above
}
- NewtDisplay_displayDispatchErrorHandlerEnable(1, env);
-
- DBG_PRINT( "X11: reconfigureWindow0 dpy %p, scrn %d, parent %p/%p, win %p, %d/%d %dx%d, parentChange %d, hasParent %d, decorationChange %d, undecorated %d, fullscreenChange %d, fullscreen %d, alwaysOnTopChange %d, alwaysOnTop %d, visibleChange %d, visible %d, tempInvisible %d, fsEWMHFlags %d\n",
+ DBG_PRINT( "X11: reconfigureWindow0 dpy %p, scrn %d, parent %p/%p, win %p, %d/%d %dx%d, parentChange %d, hasParent %d, decorationChange %d, undecorated %d, fullscreenChange %d, fullscreen %d (span %d), alwaysOnTopChange %d, alwaysOnTop %d, visibleChange %d, visible %d, tempInvisible %d, fsEWMHFlags %d\n",
(void*)dpy, screen_index, (void*) jparent, (void*)parent, (void*)w,
x, y, width, height,
TST_FLAG_CHANGE_PARENTING(flags), TST_FLAG_HAS_PARENT(flags),
TST_FLAG_CHANGE_DECORATION(flags), TST_FLAG_IS_UNDECORATED(flags),
- TST_FLAG_CHANGE_FULLSCREEN(flags), TST_FLAG_IS_FULLSCREEN(flags),
+ TST_FLAG_CHANGE_FULLSCREEN(flags), TST_FLAG_IS_FULLSCREEN(flags), TST_FLAG_IS_FULLSCREEN_SPAN(flags),
TST_FLAG_CHANGE_ALWAYSONTOP(flags), TST_FLAG_IS_ALWAYSONTOP(flags),
- TST_FLAG_CHANGE_VISIBILITY(flags), TST_FLAG_IS_VISIBLE(flags), tempInvisible, fsEWMHFlags);
+ TST_FLAG_CHANGE_VISIBILITY(flags), TST_FLAG_IS_VISIBLE(flags),
+ tempInvisible, fsEWMHFlags);
- // FS Note: To toggle FS, utilizing the _NET_WM_STATE_FULLSCREEN WM state shall be enough.
+ // FS Note: To toggle FS, utilizing the _NET_WM_STATE_FULLSCREEN WM state should be enough.
// However, we have to consider other cases like reparenting and WM which don't support it.
-
+ #if 0 // Also doesn't work work properly w/ Unity WM
if( fsEWMHFlags && !TST_FLAG_CHANGE_PARENTING(flags) && isVisible &&
+ !TST_FLAG_IS_FULLSCREEN_SPAN(flags) &&
( TST_FLAG_CHANGE_FULLSCREEN(flags) || TST_FLAG_CHANGE_ALWAYSONTOP(flags) ) ) {
Bool enable = TST_FLAG_CHANGE_FULLSCREEN(flags) ? TST_FLAG_IS_FULLSCREEN(flags) : TST_FLAG_IS_ALWAYSONTOP(flags) ;
- if( NewtWindows_setFullscreenEWMH(dpy, root, w, fsEWMHFlags, isVisible, enable) ) {
- NewtDisplay_displayDispatchErrorHandlerEnable(0, env);
- #ifdef FS_GRAB_KEYBOARD
- if(TST_FLAG_CHANGE_FULLSCREEN(flags)) {
- if(TST_FLAG_IS_FULLSCREEN(flags)) {
- XGrabKeyboard(dpy, w, True, GrabModeAsync, GrabModeAsync, CurrentTime);
- } else {
- XUngrabKeyboard(dpy, CurrentTime);
- }
- } else if(TST_FLAG_CHANGE_ALWAYSONTOP(flags) && !TST_FLAG_IS_ALWAYSONTOP(flags)) {
- XUngrabKeyboard(dpy, CurrentTime);
+ if( NewtWindows_setStackingEWMHFlags(dpy, root, w, fsEWMHFlags, isVisible, enable) ) {
+ if ( TST_FLAG_CHANGE_FULLSCREEN(flags) && !TST_FLAG_IS_FULLSCREEN(flags) ) { // FS off - restore decoration
+ NewtWindows_setDecorations (dpy, w, TST_FLAG_IS_UNDECORATED(flags) ? False : True);
}
- #endif
+ DBG_PRINT( "X11: reconfigureWindow0 X (fs.atop.fast)\n");
+ return;
+ }
+ }
+ #endif
+ // Toggle ALWAYSONTOP (only) w/o visibility or window stacking sideffects
+ if( isVisible && fsEWMHFlags && TST_FLAG_CHANGE_ALWAYSONTOP(flags) &&
+ !TST_FLAG_CHANGE_PARENTING(flags) && !TST_FLAG_CHANGE_FULLSCREEN(flags) ) {
+ if( NewtWindows_setStackingEWMHFlags(dpy, root, w, fsEWMHFlags, isVisible, TST_FLAG_IS_ALWAYSONTOP(flags)) ) {
+ DBG_PRINT( "X11: reconfigureWindow0 X (atop.fast)\n");
return;
}
}
@@ -798,21 +838,22 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0
// no need to notify the java side .. just temp change
}
- if( fsEWMHFlags && ( ( TST_FLAG_CHANGE_FULLSCREEN(flags) && !TST_FLAG_IS_FULLSCREEN(flags) ) ||
- ( TST_FLAG_CHANGE_ALWAYSONTOP(flags) && !TST_FLAG_IS_ALWAYSONTOP(flags) ) ) ) { // FS off
- NewtWindows_setFullscreenEWMH(dpy, root, w, fsEWMHFlags, isVisible, False);
- #ifdef FS_GRAB_KEYBOARD
- XUngrabKeyboard(dpy, CurrentTime);
- #endif
+ if( fsEWMHFlags && ( ( TST_FLAG_CHANGE_FULLSCREEN(flags) && !TST_FLAG_IS_FULLSCREEN(flags) ) || // FS off
+ ( TST_FLAG_CHANGE_ALWAYSONTOP(flags) && !TST_FLAG_IS_ALWAYSONTOP(flags) ) ) ) { // AlwaysOnTop off
+ NewtWindows_setStackingEWMHFlags(dpy, root, w, fsEWMHFlags, isVisible, False);
}
if( TST_FLAG_CHANGE_PARENTING(flags) && !TST_FLAG_HAS_PARENT(flags) ) {
// TOP: in -> out
DBG_PRINT( "X11: reconfigureWindow0 PARENTING in->out\n");
XReparentWindow( dpy, w, parent, x, y ); // actual reparent call
- // XIfEvent( dpy, &event, WaitForReparentNotify, (XPointer) w );
+ #ifdef REPARENT_WAIT_FOR_REPARENT_NOTIFY
+ XIfEvent( dpy, &event, WaitForReparentNotify, (XPointer) w );
+ #endif
XSync(dpy, False);
XSetWMProtocols(dpy, w, &wm_delete_atom, 1); // windowDeleteAtom
+ // Fix for Unity WM, i.e. _remove_ persistent previous states
+ NewtWindows_setStackingEWMHFlags(dpy, root, w, fsEWMHFlags, isVisible, False);
}
if( TST_FLAG_CHANGE_DECORATION(flags) ) {
@@ -827,7 +868,9 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0
// CHILD: out -> in
DBG_PRINT( "X11: reconfigureWindow0 PARENTING out->in\n");
XReparentWindow( dpy, w, parent, x, y ); // actual reparent call
- // XIfEvent( dpy, &event, WaitForReparentNotify, (XPointer) w );
+ #ifdef REPARENT_WAIT_FOR_REPARENT_NOTIFY
+ XIfEvent( dpy, &event, WaitForReparentNotify, (XPointer) w );
+ #endif
XSync(dpy, False);
}
@@ -836,62 +879,58 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0
XMapRaised(dpy, w);
XIfEvent( dpy, &event, WaitForMapNotify, (XPointer) w );
// no need to notify the java side .. just temp change
- }
-
- if( TST_FLAG_CHANGE_VISIBILITY(flags) ) {
+ } else if( TST_FLAG_CHANGE_VISIBILITY(flags) ) {
if( TST_FLAG_IS_VISIBLE(flags) ) {
DBG_PRINT( "X11: reconfigureWindow0 VISIBLE ON\n");
XMapRaised(dpy, w);
+ XSync(dpy, False);
+ // WM may disregard pos/size XConfigureWindow requests for invisible windows!
+ DBG_PRINT( "X11: reconfigureWindow0 setPosSize.2 %d/%d %dx%d\n", x, y, width, height);
+ NewtWindows_setPosSize(dpy, w, x, y, width, height);
} else {
DBG_PRINT( "X11: reconfigureWindow0 VISIBLE OFF\n");
XUnmapWindow(dpy, w);
+ XSync(dpy, False);
}
- XSync(dpy, False);
}
- if( fsEWMHFlags && ( ( TST_FLAG_CHANGE_FULLSCREEN(flags) && TST_FLAG_IS_FULLSCREEN(flags) ) ||
- ( TST_FLAG_CHANGE_ALWAYSONTOP(flags) && TST_FLAG_IS_ALWAYSONTOP(flags) ) ) ) { // FS on
- NewtWindows_setFullscreenEWMH(dpy, root, w, fsEWMHFlags, isVisible, True);
- #ifdef FS_GRAB_KEYBOARD
- if(TST_FLAG_CHANGE_FULLSCREEN(flags) && TST_FLAG_IS_FULLSCREEN(flags)) {
- XGrabKeyboard(dpy, w, True, GrabModeAsync, GrabModeAsync, CurrentTime);
- }
- #endif
+ if( fsEWMHFlags && ( ( TST_FLAG_CHANGE_FULLSCREEN(flags) && TST_FLAG_IS_FULLSCREEN(flags) ) || // FS on
+ ( TST_FLAG_CHANGE_ALWAYSONTOP(flags) && TST_FLAG_IS_ALWAYSONTOP(flags) ) ) ) { // AlwaysOnTop on
+ NewtWindows_requestFocus (dpy, w, True);
+ NewtWindows_setStackingEWMHFlags(dpy, root, w, fsEWMHFlags, isVisible, True);
}
- NewtDisplay_displayDispatchErrorHandlerEnable(0, env);
-
- DBG_PRINT( "X11: reconfigureWindow0 X\n");
+ DBG_PRINT( "X11: reconfigureWindow0 X (full)\n");
}
/*
- * Class: jogamp_newt_driver_x11_X11Window
+ * Class: jogamp_newt_driver_x11_WindowDriver
* Method: requestFocus0
* Signature: (JJZ)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_requestFocus0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_requestFocus0
(JNIEnv *env, jobject obj, jlong display, jlong window, jboolean force)
{
- NewtWindows_requestFocus ( env, obj, (Display *) (intptr_t) display, (Window)window, force ) ;
+ NewtWindows_requestFocus ( (Display *) (intptr_t) display, (Window)window, JNI_TRUE==force?True:False ) ;
}
/*
- * Class: jogamp_newt_driver_x11_X11Window
+ * Class: jogamp_newt_driver_x11_WindowDriver
* Method: getParentWindow0
* Signature: (JJ)J
*/
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_getParentWindow0
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_WindowDriver_getParentWindow0
(JNIEnv *env, jclass clazz, jlong display, jlong window)
{
return (jlong) NewtWindows_getParent ((Display *) (intptr_t) display, (Window)window);
}
/*
- * Class: Java_jogamp_newt_driver_x11_X11Window
+ * Class: Java_jogamp_newt_driver_x11_WindowDriver
* Method: setTitle0
* Signature: (JJLjava/lang/String;)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_setTitle0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_setTitle0
(JNIEnv *env, jclass clazz, jlong display, jlong window, jstring title)
{
Display * dpy = (Display *) (intptr_t) display;
@@ -938,11 +977,32 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_setTitle0
}
/*
- * Class: Java_jogamp_newt_driver_x11_X11Window
+ * Class: Java_jogamp_newt_driver_x11_WindowDriver
+ * Method: setPointerIcon0
+ * Signature: (JJILjava/lang/Object;I)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_setPointerIcon0
+ (JNIEnv *env, jclass clazz, jlong display, jlong window, jlong handle)
+{
+ Display * dpy = (Display *) (intptr_t) display;
+ Window w = (Window)window;
+
+ if( 0 == handle ) {
+ DBG_PRINT( "X11: setPointerIcon0: reset\n");
+ XUndefineCursor(dpy, w);
+ } else {
+ Cursor c = (Cursor) (intptr_t) handle;
+ DBG_PRINT( "X11: setPointerIcon0: %p\n", (void*)c);
+ XDefineCursor(dpy, w, c);
+ }
+}
+
+/*
+ * Class: Java_jogamp_newt_driver_x11_WindowDriver
* Method: setPointerVisible0
* Signature: (JJZ)Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_setPointerVisible0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_WindowDriver_setPointerVisible0
(JNIEnv *env, jclass clazz, jlong display, jlong window, jboolean mouseVisible)
{
static char noData[] = { 0,0,0,0,0,0,0,0 };
@@ -972,11 +1032,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_setPointerVisib
}
/*
- * Class: Java_jogamp_newt_driver_x11_X11Window
+ * Class: Java_jogamp_newt_driver_x11_WindowDriver
* Method: confinePointer0
* Signature: (JJZ)Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_confinePointer0
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_WindowDriver_confinePointer0
(JNIEnv *env, jclass clazz, jlong display, jlong window, jboolean confine)
{
Display * dpy = (Display *) (intptr_t) display;
@@ -995,11 +1055,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_confinePointer0
}
/*
- * Class: Java_jogamp_newt_driver_x11_X11Window
+ * Class: Java_jogamp_newt_driver_x11_WindowDriver
* Method: warpPointer0
* Signature: (JJII)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_warpPointer0
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_warpPointer0
(JNIEnv *env, jclass clazz, jlong display, jlong window, jint x, jint y)
{
Display * dpy = (Display *) (intptr_t) display;