diff options
Diffstat (limited to 'src/newt/native/X11Window.c')
-rw-r--r-- | src/newt/native/X11Window.c | 300 |
1 files changed, 185 insertions, 115 deletions
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 6fa3cc195..1c2c8e80f 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -85,53 +85,7 @@ static uintptr_t getPtrOut32Long(unsigned long * src) { #define _NET_WM_STATE_REMOVE 0 #define _NET_WM_STATE_ADD 1 -#define _MASK_NET_WM_STATE ( 1 << 0 ) -#define _MASK_NET_WM_STATE_MODAL ( 1 << 1 ) -#define _MASK_NET_WM_STATE_STICKY ( 1 << 2 ) -#define _MASK_NET_WM_STATE_MAXIMIZED_VERT ( 1 << 3 ) -#define _MASK_NET_WM_STATE_MAXIMIZED_HORZ ( 1 << 4 ) -#define _MASK_NET_WM_STATE_SHADED ( 1 << 5 ) -#define _MASK_NET_WM_STATE_HIDDEN ( 1 << 8 ) -#define _MASK_NET_WM_STATE_FULLSCREEN ( 1 << 9 ) -#define _MASK_NET_WM_STATE_ABOVE ( 1 << 10 ) -#define _MASK_NET_WM_STATE_BELOW ( 1 << 11 ) -#define _MASK_NET_WM_STATE_DEMANDS_ATTENTION ( 1 << 12 ) -#define _MASK_NET_WM_STATE_FOCUSED ( 1 << 13 ) -#define _MASK_NET_WM_BYPASS_COMPOSITOR ( 1 << 14 ) -#define _MASK_NET_WM_DESKTOP ( 1 << 15 ) -#define _MASK_NET_CURRENT_DESKTOP ( 1 << 16 ) -#define _MASK_NET_WM_WINDOW_TYPE ( 1 << 17 ) -#define _MASK_NET_WM_WINDOW_TYPE_NORMAL ( 1 << 18 ) -#define _MASK_NET_WM_WINDOW_TYPE_POPUP_MENU ( 1 << 19 ) -#define _MASK_NET_FRAME_EXTENTS ( 1 << 20 ) -#define _MASK_NET_SUPPORTED ( 1 << 21 ) -#define _MASK_WM_CHANGE_STATE ( 1 << 22 ) -#define _MASK_MOTIF_WM_HINTS ( 1 << 23 ) - -#define _NET_WM_STATE_IDX 0 -#define _NET_WM_STATE_MODAL_IDX 1 -#define _NET_WM_STATE_STICKY_IDX 2 -#define _NET_WM_STATE_MAXIMIZED_VERT_IDX 3 -#define _NET_WM_STATE_MAXIMIZED_HORZ_IDX 4 -#define _NET_WM_STATE_SHADED_IDX 5 -#define _NET_WM_STATE_SKIP_TASKBAR_IDX 6 -#define _NET_WM_STATE_SKIP_PAGER_IDX 7 -#define _NET_WM_STATE_HIDDEN_IDX 8 -#define _NET_WM_STATE_FULLSCREEN_IDX 9 -#define _NET_WM_STATE_ABOVE_IDX 10 -#define _NET_WM_STATE_BELOW_IDX 11 -#define _NET_WM_STATE_DEMANDS_ATTENTION_IDX 12 -#define _NET_WM_STATE_FOCUSED_IDX 13 -#define _NET_WM_BYPASS_COMPOSITOR_IDX 14 -#define _NET_WM_DESKTOP_IDX 15 -#define _NET_CURRENT_DESKTOP_IDX 16 -#define _NET_WM_WINDOW_TYPE_IDX 17 -#define _NET_WM_WINDOW_TYPE_NORMAL_IDX 18 -#define _NET_WM_WINDOW_TYPE_POPUP_MENU_IDX 19 -#define _NET_FRAME_EXTENTS_IDX 20 -#define _NET_SUPPORTED_IDX 21 -#define _WM_CHANGE_STATE_IDX 22 -#define _MOTIF_WM_HINTS_IDX 23 +/** Sync w/ X11Common.h MASK and IDX */ static const char * _ALL_ATOM_NAMES[] = { /* 0 */ "_NET_WM_STATE", /* 1 */ "_NET_WM_STATE_MODAL", @@ -155,8 +109,9 @@ static const char * _ALL_ATOM_NAMES[] = { /* 19 */ "_NET_WM_WINDOW_TYPE_POPUP_MENU", /* 20 */ "_NET_FRAME_EXTENTS", /* 21 */ "_NET_SUPPORTED", - /* 22 */ "WM_CHANGE_STATE", - /* 23 */ "_MOTIF_WM_HINTS" + /* 22 */ "_NET_ACTIVE_WINDOW", + /* 23 */ "WM_CHANGE_STATE", + /* 24 */ "_MOTIF_WM_HINTS" }; static const uint32_t _ALL_ATOM_COUNT = (uint32_t)(sizeof(_ALL_ATOM_NAMES)/sizeof(const char *)); @@ -185,7 +140,6 @@ static uint32_t NewtWindows_getSupportedFeaturesEWMH(Display *dpy, Window root, uint32_t res = 0; Status s; - XSync(dpy, False); if ( Success == (s = XGetWindowProperty(dpy, root, allAtoms[_NET_SUPPORTED_IDX], 0, 1024, False, AnyPropertyType, &type, &form, &props_count, &remain, (unsigned char**)&properties)) ) { if( NULL != properties ) { @@ -202,7 +156,16 @@ static uint32_t NewtWindows_getSupportedFeaturesEWMH(Display *dpy, Window root, } return res; } -static uint32_t NewtWindows_getNET_WM_STATE(Display *dpy, Window window, Atom * allAtoms, Bool verbose) { +uint32_t NewtWindows_getNET_WM_STATE(Display *dpy, JavaWindow *w) { + Bool verbose = +#ifdef VERBOSE_ON + True +#else + False +#endif + ; + Window window = w->window; + Atom * allAtoms = w->allAtoms; Atom * properties = NULL; Atom type = 0; unsigned long props_count = 0, remain = 0; @@ -210,7 +173,6 @@ static uint32_t NewtWindows_getNET_WM_STATE(Display *dpy, Window window, Atom * uint32_t res = 0; Status s; - XSync(dpy, False); if ( Success == (s = XGetWindowProperty(dpy, window, allAtoms[_NET_WM_STATE_IDX], 0, 1024, False, AnyPropertyType, &type, &form, &props_count, &remain, (unsigned char**)&properties)) ) { if( NULL != properties ) { @@ -220,7 +182,7 @@ static uint32_t NewtWindows_getNET_WM_STATE(Display *dpy, Window window, Atom * XFree(properties); } if(verbose) { - fprintf(stderr, "**************** X11: WM_STATE of %p: 0x%X\n", (void*)window, res); + fprintf(stderr, "**************** X11: WM_STATE of %p: %d props -> 0x%X\n", (void*)window, (int)props_count, res); } } else if(verbose) { fprintf(stderr, "**************** X11: WM_STATE of %p: XGetWindowProperty failed: %d\n", (void*)window, s); @@ -249,6 +211,12 @@ static JavaWindow* createJavaWindowProperty(JNIEnv *env, Display *dpy, Window ro res->lastDesktop = 0; //undef res->maxHorz = False; res->maxVert = False; + res->isMapped = False; + int i; + for (i = 0; i < XI_TOUCHCOORD_COUNT; i++) { + res->xiTouchCoords[i].id = -1; + } + res->xiTouchDeviceId = -1; } unsigned long jogl_java_object_data[2]; // X11 is based on 'unsigned long' int nitems_32 = putPtrIn32Long( jogl_java_object_data, (uintptr_t) res); @@ -292,7 +260,7 @@ JavaWindow * getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlo if ( Success != res ) { if(True==showWarning) { - fprintf(stderr, "Warning: NEWT X11Window: Could not fetch Atom NEWT_JAVA_OBJECT window property (res %d) nitems %ld, bytes_after %ld, result 0!\n", res, nitems, bytes_after); + fprintf(stderr, "Warning: NEWT X11Window: Could not fetch Atom NEWT_JAVA_OBJECT window %p property (res %d) nitems %ld, bytes_after %ld, result 0!\n", (void*)window, res, nitems, bytes_after); } return NULL; } @@ -302,8 +270,8 @@ JavaWindow * getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlo 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); + fprintf(stderr, "Warning: NEWT X11Window: Fetched invalid Atom NEWT_JAVA_OBJECT window %p property (res %d) nitems %ld, bytes_after %ld, actual_type %ld, NEWT_JAVA_OBJECT %ld, result 0!\n", + (void *)window, res, nitems, bytes_after, (long)actual_type, (long)javaObjectAtom); } return NULL; } @@ -352,7 +320,6 @@ static void NewtWindows_setCWAbove(Display *dpy, Window w) { memset(&xwc, 0, sizeof(XWindowChanges)); xwc.stack_mode = Above; XConfigureWindow(dpy, w, CWStackMode, &xwc); - XSync(dpy, False); } static Status NewtWindows_getWindowPositionRelative2Parent (Display *dpy, Window w, int *x_return, int *y_return) { Window root_return; @@ -440,8 +407,7 @@ static void NewtWindows_setDecorations (Display *dpy, JavaWindow *w, Bool decora #ifdef DECOR_USE_EWMH XChangeProperty( dpy, w->window, w->allAtoms[_NET_WM_WINDOW_TYPE_IDX], XA_ATOM, 32, PropModeReplace, (unsigned char *)&types, ntypes); #endif - - XSync(dpy, False); + XFlush(dpy); } static Bool NewtWindows_hasDecorations (Display *dpy, JavaWindow * w) { @@ -473,7 +439,6 @@ static void NewtWindows_requestFocus (Display *dpy, JavaWindow * jw, Bool force) Window focus_return; int revert_to_return; - XSync(dpy, False); XGetInputFocus(dpy, &focus_return, &revert_to_return); DBG_PRINT( "X11: requestFocus dpy %p,win %p, force %d, hasFocus %d\n", dpy, (void*)jw->window, force, focus_return==jw->window); @@ -488,8 +453,8 @@ static void NewtWindows_requestFocus (Display *dpy, JavaWindow * jw, Bool force) XSetInputFocus(dpy, jw->window, RevertToParent, CurrentTime); } } + XFlush(dpy); DBG_PRINT( "X11: requestFocus dpy %p,win %p, force %d - FIN\n", dpy, (void*)jw->window, force); - XSync(dpy, False); } Bool NewtWindows_updateInsets(Display *dpy, JavaWindow * w, int *left, int *right, int *top, int *bottom) { @@ -513,16 +478,9 @@ Bool NewtWindows_updateInsets(Display *dpy, JavaWindow * w, int *left, int *righ return False; // Error } -Bool NewtWindows_updateMaximized(Display *dpy, JavaWindow * w) { - uint32_t state = NewtWindows_getNET_WM_STATE(dpy, w->window, w->allAtoms, -#ifdef VERBOSE_ON - True -#else - False -#endif - ); - Bool maxHorz = 0 != ( _MASK_NET_WM_STATE_MAXIMIZED_HORZ & state ) ; - Bool maxVert = 0 != ( _MASK_NET_WM_STATE_MAXIMIZED_VERT & state ) ; +Bool NewtWindows_updateMaximized(Display *dpy, JavaWindow * w, uint32_t netWMState) { + Bool maxHorz = 0 != ( _MASK_NET_WM_STATE_MAXIMIZED_HORZ & netWMState ) ; + Bool maxVert = 0 != ( _MASK_NET_WM_STATE_MAXIMIZED_VERT & netWMState ) ; if( w->maxHorz != maxHorz || w->maxVert != maxVert ) { w->maxHorz = maxHorz; w->maxVert = maxVert; @@ -558,11 +516,20 @@ static void NewtWindows_setWindowTypeEWMH (Display *dpy, JavaWindow * w, int typ } // else { } if( 0 != types[0] ) { XChangeProperty( dpy, w->window, w->allAtoms[_NET_WM_WINDOW_TYPE_IDX], XA_ATOM, 32, PropModeReplace, (unsigned char *)&types, 1); - XSync(dpy, False); + XFlush(dpy); } } -static void NewtWindows_sendNET_WM_STATE(Display *dpy, Window root, JavaWindow *w, int prop1Idx, int prop2Idx, Bool enable) { +void NewtWindows_setUrgency(Display *dpy, Window window, Bool enable) { + XWMHints wmh; + memset ( &wmh, 0, sizeof(wmh) ); + if( enable ) { + wmh.flags = XUrgencyHint; + } + XSetWMHints(dpy, window, &wmh); +} + +void NewtWindows_sendNET_WM_STATE(Display *dpy, Window root, JavaWindow *w, int prop1Idx, int prop2Idx, Bool enable) { XEvent xev; int i=0; @@ -694,7 +661,7 @@ static void NewtWindows_setStackingEWMHFlags (Display *dpy, Window root, JavaWin changeMaxVert ? _NET_WM_STATE_MAXIMIZED_VERT_IDX : 0, enable); } - XSync(dpy, False); + XFlush(dpy); DBG_PRINT( "X11: setStackingEWMHFlags ON %d, change[Sticky %d, Fullscreen %d, Above %d, Below %d, MaxV %d, MaxH %d]\n", enable, changeSticky, changeFullscreen, changeAbove, changeBelow, changeMaxVert, changeMaxHorz); } @@ -709,35 +676,47 @@ static Bool WaitForUnmapNotify( Display *dpy, XEvent *event, XPointer arg ) { static void NewtWindows_setVisible(Display *dpy, Window root, JavaWindow* jw, Bool visible, Bool useWM, Bool waitForNotify) { XEvent event; - if( !visible && useWM && 0 != ( _MASK_NET_WM_STATE_HIDDEN & jw->supportedAtoms ) ) { - DBG_PRINT( "X11: setVisible -> %d, method: IconicState, wait %d, window %p\n", (int)visible, (int)waitForNotify, (void*)jw->window); - // It has been experienced that UnmapNotify is not sent for child windows when using IconicState! + DBG_PRINT( "X11: setVisible -> %d, useWM: %d, wait %d, window %p\n", (int)visible, (int)useWM, (int)waitForNotify, (void*)jw->window); + if( useWM && jw->isMapped && 0 != ( _MASK_NET_WM_STATE_HIDDEN & jw->supportedAtoms ) ) { + // It has been experienced that MapNotify/UnmapNotify is not sent for windows when using NormalState/IconicState! + // See X11Display.c::Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0 case ConfigureNotify + // NewtWindows_sendNET_WM_STATE(dpy, root, jw, _NET_WM_STATE_DEMANDS_ATTENTION_IDX, 0, True); + // NewtWindows_setUrgency(dpy, jw->window, True); XEvent xev; memset ( &xev, 0, sizeof(xev) ); - xev.type = ClientMessage; - xev.xclient.window = jw->window; - xev.xclient.message_type = jw->allAtoms[_WM_CHANGE_STATE_IDX]; - xev.xclient.format = 32; - xev.xclient.data.l[0] = IconicState; - XSendEvent ( dpy, root, False, SubstructureNotifyMask | SubstructureRedirectMask, &xev ); - // NewtWindows_sendNET_WM_STATE(dpy, root, jw, _NET_WM_STATE_HIDDEN_IDX, 0, !visible); - if(waitForNotify) { - XIfEvent( dpy, &event, WaitForUnmapNotify, (XPointer) jw->window ); + if( visible ) { + // NormalState does not work on some WMs (Gnome, KDE) + xev.type = ClientMessage; + xev.xclient.window = jw->window; + xev.xclient.message_type = jw->allAtoms[_NET_ACTIVE_WINDOW_IDX]; + xev.xclient.format = 32; + xev.xclient.data.l[0] = 1; //source indication for normal applications + xev.xclient.data.l[1] = CurrentTime; + XSendEvent ( dpy, root, False, SubstructureNotifyMask | SubstructureRedirectMask, &xev ); + } else { + xev.type = ClientMessage; + xev.xclient.window = jw->window; + xev.xclient.message_type = jw->allAtoms[_WM_CHANGE_STATE_IDX]; + xev.xclient.format = 32; + xev.xclient.data.l[0] = IconicState; + XSendEvent ( dpy, root, False, SubstructureNotifyMask | SubstructureRedirectMask, &xev ); } } else { - DBG_PRINT( "X11: setVisible -> %d, method: Map/Unmap, wait %d, window %p\n", (int)visible, (int)waitForNotify, (void*)jw->window); if( visible ) { XMapRaised(dpy, jw->window); if(waitForNotify) { XIfEvent( dpy, &event, WaitForMapNotify, (XPointer) jw->window ); } + jw->isMapped=True; } else { XUnmapWindow(dpy, jw->window); if(waitForNotify) { XIfEvent( dpy, &event, WaitForUnmapNotify, (XPointer) jw->window ); } + jw->isMapped=False; } } + XFlush(dpy); } @@ -771,7 +750,7 @@ static void NewtWindows_setPosSize(Display *dpy, JavaWindow* w, jint x, jint y, xwc.height=height; } XConfigureWindow(dpy, w->window, flags, &xwc); - XSync(dpy, False); + XFlush(dpy); } } @@ -787,7 +766,7 @@ static void NewtWindows_setIcon(Display *dpy, Window w, int data_size, const uns JNIEXPORT jlongArray 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, + jlong javaObjectAtom, jlong windowDeleteAtom, jint xi_opcode, jint x, jint y, jint width, jint height, int flags, jint pixelDataSize, jobject pixels, jint pixels_byte_offset, jboolean pixels_is_direct, jboolean verbose) @@ -858,24 +837,23 @@ JNIEXPORT jlongArray JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWind pVisualQuery=NULL; } - attrMask = ( CWBackingStore | CWBackingPlanes | CWBackingPixel | CWBackPixmap | - CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask ) ; + attrMask = ( CWBackingStore | CWBackingPlanes | CWBackingPixel | + CWBackPixmap | CWBackPixel | CWBorderPixel | CWColormap | + CWOverrideRedirect | CWEventMask ) ; memset(&xswa, 0, sizeof(xswa)); - xswa.override_redirect = False; // use the window manager, always (default) - xswa.border_pixel = 0; - xswa.background_pixmap = None; 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 */ + xswa.background_pixmap = None; + xswa.background_pixel = BlackPixel(dpy, scrn_idx); + xswa.border_pixel = 0; + xswa.colormap = XCreateColormap(dpy, windowParent, visual, AllocNone); + xswa.override_redirect = False; // use the window manager, always (default) xswa.event_mask = X11_MOUSE_EVENT_MASK; xswa.event_mask |= KeyPressMask | KeyReleaseMask ; - xswa.event_mask |= FocusChangeMask | SubstructureNotifyMask | StructureNotifyMask | ExposureMask ; - - xswa.colormap = XCreateColormap(dpy, - windowParent, - visual, - AllocNone); + xswa.event_mask |= FocusChangeMask | SubstructureNotifyMask | StructureNotifyMask | ExposureMask; + // xswa.event_mask |= VisibilityChangeMask; { int _x = x, _y = y; // pos for CreateWindow, might be tweaked @@ -900,6 +878,7 @@ JNIEXPORT jlongArray JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWind NewtCommon_throwNewRuntimeException(env, "could not create Window, bail out!"); return 0; } + // XClearWindow(dpy, window); XSetWMProtocols(dpy, window, &wm_delete_atom, 1); // windowDeleteAtom javaWindow = createJavaWindowProperty(env, dpy, root, window, javaObjectAtom, windowDeleteAtom, obj, verbose); @@ -911,7 +890,8 @@ JNIEXPORT jlongArray JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWind // we can pre-map the window here to be able to gather the insets and position. { XEvent event; - int left=0, right=0, top=0, bottom=0; + // insets: negative values are ignored + int left=-1, right=-1, top=-1, bottom=-1; const unsigned char * pixelPtr = NULL; // NOTE: MUST BE DIRECT BUFFER, since _NET_WM_ICON Atom uses buffer directly! @@ -926,18 +906,20 @@ JNIEXPORT jlongArray JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWind XMapWindow(dpy, window); XIfEvent( dpy, &event, WaitForMapNotify, (XPointer) window ); // wait to get proper insets values - - XSync(dpy, False); + javaWindow->isMapped=True; 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! + XSync(dpy, False); if( NewtWindows_updateInsets(dpy, javaWindow, &left, &right, &top, &bottom) ) { - (*env)->CallVoidMethod(env, javaWindow->jwindow, insetsChangedID, JNI_FALSE, left, right, top, bottom); + (*env)->CallVoidMethod(env, javaWindow->jwindow, insetsVisibleChangedID, JNI_FALSE, left, right, top, bottom, 1); + } else { + (*env)->CallVoidMethod(env, javaWindow->jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE); + left=0; right=0; top=0; bottom=0; } - (*env)->CallVoidMethod(env, javaWindow->jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE); if( TST_FLAG_IS_AUTOPOSITION(flags) ) { // get position from WM @@ -975,6 +957,59 @@ JNIEXPORT jlongArray JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWind NewtWindows_setMinMaxSize(dpy, javaWindow, width, height, width, height); } } + + // Register X11 Multitouch Events for new Window + // https://www.x.org/wiki/Development/Documentation/Multitouch/ + if( 0 <= xi_opcode ) { + XIDeviceInfo *di; + int cnt = 0; + + DBG_PRINT( "X11: [CreateWindow]: XI: Window %p, Extension %d\n", (void*)window, xi_opcode); + di = XIQueryDevice(dpy, XIAllDevices, &cnt); + + if( NULL != di && 0 < cnt ) { + int devid = -1; + int i, j; + + // find the 1st XITouchClass device available + for (i = 0; i < cnt && -1 == devid; i ++) { + XIDeviceInfo *dev = &di[i]; + for (j = 0; j < dev->num_classes; j ++) { + XITouchClassInfo *class = (XITouchClassInfo*)(dev->classes[j]); + DBG_PRINT( "X11: [CreateWindow]: XI: Scan Window %p, device[%d/%d].class[%d/%d]: devid %d, type %d (is XITouchClass %d)\n", + (void*)window, (i+1), cnt, (j+1), dev->num_classes, dev->deviceid, class->type, (XITouchClass == class->type)); + if ( XITouchClass == class->type ) { + devid = dev->deviceid; + break; + } + } + } + XIFreeDeviceInfo(di); + di = NULL; + + if( -1 != devid ) { + // register 1st XITouchClass device if available + XIEventMask mask = { + .deviceid = devid, + .mask_len = XIMaskLen(XI_TouchEnd) // in bytes + }; + + mask.mask = (unsigned char*)calloc(mask.mask_len, sizeof(unsigned char)); + XISetMask(mask.mask, XI_TouchBegin); + XISetMask(mask.mask, XI_TouchUpdate); + XISetMask(mask.mask, XI_TouchEnd); + + XISelectEvents(dpy, window, &mask, 1); + + free(mask.mask); + + javaWindow->xiTouchDeviceId = devid; + DBG_PRINT( "X11: [CreateWindow]: XI: Window %p, XITouchClass devid %d\n", (void*)window, devid); + } + } + } + + XFlush(dpy); handles[0] = (jlong)(intptr_t)window; handles[1] = (jlong)(intptr_t)javaWindow; jhandles = (*env)->NewLongArray(env, 2); @@ -988,12 +1023,40 @@ JNIEXPORT jlongArray JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWind /* * Class: jogamp_newt_driver_x11_WindowDriver + * Method: GetSupportedReconfigMask0 + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_WindowDriver_GetSupportedReconfigMask0 + (JNIEnv *env, jclass clazz, jlong javaWindow) +{ + JavaWindow * jw = (JavaWindow*)(intptr_t)javaWindow; + uint32_t supported = jw->supportedAtoms; + return + FLAG_IS_VISIBLE | + FLAG_IS_AUTOPOSITION | + FLAG_IS_CHILD | + FLAG_IS_FOCUSED | + FLAG_IS_UNDECORATED | + ( ( 0 != ( _MASK_NET_WM_STATE_ABOVE & supported ) ) ? FLAG_IS_ALWAYSONTOP : 0 ) | + ( ( 0 != ( _MASK_NET_WM_STATE_BELOW & supported ) ) ? FLAG_IS_ALWAYSONBOTTOM : 0 ) | + ( ( 0 != ( _MASK_NET_WM_DESKTOP & supported ) ) ? FLAG_IS_STICKY : 0 ) | + FLAG_IS_RESIZABLE | + ( ( 0 != ( _MASK_NET_WM_STATE_MAXIMIZED_VERT & supported ) ) ? FLAG_IS_MAXIMIZED_VERT : 0 ) | + ( ( 0 != ( _MASK_NET_WM_STATE_MAXIMIZED_HORZ & supported ) ) ? FLAG_IS_MAXIMIZED_HORZ : 0 ) | + FLAG_IS_FULLSCREEN | + FLAG_IS_POINTERVISIBLE | + FLAG_IS_POINTERCONFINED | + FLAG_IS_FULLSCREEN_SPAN; +} + +/* + * Class: jogamp_newt_driver_x11_WindowDriver * Method: CloseWindow * 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 - jint randr_event_base, jint randr_error_base) + jint randr_event_base, jint randr_error_base, jint xi_opcode) { Display * dpy = (Display *) (intptr_t) display; JavaWindow * jw, * jw0; @@ -1008,7 +1071,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0 NewtCommon_FatalError(env, "invalid JavaWindow connection.."); } jw0 = getJavaWindowProperty(env, dpy, jw->window, jw->javaObjectAtom, True); - if(NULL==jw) { + if(NULL==jw0) { NewtCommon_throwNewRuntimeException(env, "could not fetch Java Window object, bail out!"); return; } @@ -1026,11 +1089,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CloseWindow0 XGetWindowAttributes(dpy, jw->window, &xwa); // prefetch colormap to be destroyed after window destruction XSelectInput(dpy, jw->window, 0); XUnmapWindow(dpy, jw->window); + jw->isMapped=False; // Drain all events related to this window .. Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0(env, obj, display, (jlong)(intptr_t)jw->javaObjectAtom, (jlong)(intptr_t)jw->windowDeleteAtom /*, kbdHandle */, // XKB disabled for now - randr_event_base, randr_error_base); + randr_event_base, randr_error_base, xi_opcode); XDestroyWindow(dpy, jw->window); if( None != xwa.colormap ) { @@ -1065,7 +1129,7 @@ static Bool WaitForReparentNotify( Display *dpy, XEvent *event, XPointer arg ) { * Signature: (JIJJIIIII)V */ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindow0 - (JNIEnv *env, jobject obj, jlong jdisplay, jint screen_index, + (JNIEnv *env, jclass clazz, jlong jdisplay, jint screen_index, jlong jparent, jlong javaWindow, jint x, jint y, jint width, jint height, jint flags) { @@ -1121,6 +1185,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo TST_FLAG_CHANGE_STICKY(flags), TST_FLAG_IS_STICKY(flags), fsEWMHFlags); + XSync(dpy, False); + // 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 @@ -1162,8 +1228,9 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo XReparentWindow( dpy, jw->window, parent, x, y ); // actual reparent call #ifdef REPARENT_WAIT_FOR_REPARENT_NOTIFY XIfEvent( dpy, &event, WaitForReparentNotify, (XPointer) jw->window ); + #else + XSync(dpy, False); #endif - XSync(dpy, False); XSetWMProtocols(dpy, jw->window, &wm_delete_atom, 1); // windowDeleteAtom // Fix for Unity WM, i.e. _remove_ persistent previous states NewtWindows_setStackingEWMHFlags(dpy, root, jw, fsEWMHFlags, False); @@ -1205,10 +1272,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo // CHILD: out -> in DBG_PRINT( "X11: reconfigureWindow0 PARENTING out->in\n"); XReparentWindow( dpy, jw->window, parent, x, y ); // actual reparent call + XFlush(dpy); #ifdef REPARENT_WAIT_FOR_REPARENT_NOTIFY XIfEvent( dpy, &event, WaitForReparentNotify, (XPointer) jw->window ); + #else + XSync(dpy, False); #endif - XSync(dpy, False); } if( tempInvisible ) { @@ -1220,7 +1289,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo if( TST_FLAG_IS_VISIBLE(flags) ) { DBG_PRINT( "X11: reconfigureWindow0 VISIBLE ON\n"); NewtWindows_setVisible(dpy, root, jw, True /* visible */, useWM, False /* wait */); - XSync(dpy, False); if( !TST_FLAG_IS_MAXIMIZED_ANY(flags) ) { // 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); @@ -1229,7 +1297,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo } else { DBG_PRINT( "X11: reconfigureWindow0 VISIBLE OFF\n"); NewtWindows_setVisible(dpy, root, jw, False /* visible */, useWM, False /* wait */); - XSync(dpy, False); } } @@ -1250,6 +1317,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo NewtWindows_setMinMaxSize(dpy, jw, -1, -1, -1, -1); // FIXME: .. } } + XFlush(dpy); DBG_PRINT( "X11: reconfigureWindow0 X (full)\n"); } @@ -1259,9 +1327,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo * Signature: (JJZ)V */ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_requestFocus0 - (JNIEnv *env, jobject obj, jlong display, jlong javaWindow, jboolean force) + (JNIEnv *env, jclass clazz, jlong display, jlong javaWindow, jboolean force) { - NewtWindows_requestFocus ( (Display *) (intptr_t) display, (JavaWindow*)(intptr_t)javaWindow, JNI_TRUE==force?True:False ) ; + Display * dpy = (Display *) (intptr_t) display; + XSync(dpy, False); + NewtWindows_requestFocus ( dpy, (JavaWindow*)(intptr_t)javaWindow, JNI_TRUE==force?True:False ) ; } /* |