summaryrefslogtreecommitdiffstats
path: root/src/newt/native
diff options
context:
space:
mode:
Diffstat (limited to 'src/newt/native')
-rw-r--r--src/newt/native/MacWindow.m149
-rw-r--r--src/newt/native/NewtMacWindow.h9
-rw-r--r--src/newt/native/NewtMacWindow.m135
-rw-r--r--src/newt/native/Window.h4
-rw-r--r--src/newt/native/WindowsEDID.c10
-rw-r--r--src/newt/native/WindowsWindow.c588
-rw-r--r--src/newt/native/X11Common.h64
-rw-r--r--src/newt/native/X11Display.c171
-rw-r--r--src/newt/native/X11RandR13.c8
-rw-r--r--src/newt/native/X11Window.c313
10 files changed, 957 insertions, 494 deletions
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m
index b59e19e4e..ee012add3 100644
--- a/src/newt/native/MacWindow.m
+++ b/src/newt/native/MacWindow.m
@@ -832,8 +832,12 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow
}
JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_getDisplayID0(JNIEnv *env, jobject jthis, jlong window) {
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtMacWindow* myWindow = (NewtMacWindow*) ((intptr_t) window);
+ if( NULL == myWindow ) {
+ DBG_PRINT( "getDisplayID0 - NULL NEWT win - abort\n");
+ return 0;
+ }
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSScreen *screen = [myWindow screen];
int32_t displayID = (int32_t)NewtScreen_getCGDirectDisplayIDByNSScreen(screen);
[pool release];
@@ -849,16 +853,16 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_getDisplayID0
*/
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_initWindow0
(JNIEnv *env, jobject jthis, jlong parent, jlong window, jint x, jint y, jint w, jint h, jfloat reqPixelScale,
- jboolean opaque, jboolean visible, jlong jview)
+ jboolean opaque, jboolean atop, jboolean abottom, jboolean visible, jlong jview)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtMacWindow* myWindow = (NewtMacWindow*) ((intptr_t) window);
NewtView* myView = (NewtView*) (intptr_t) jview ;
BOOL fullscreen = myWindow->isFullscreenWindow;
- DBG_PRINT( "initWindow0 - %p (this), %p (parent), %p (window), %d/%d %dx%d, reqPixScale %f, opaque %d, fs %d, visible %d, view %p (START)\n",
+ DBG_PRINT( "initWindow0 - %p (this), %p (parent), %p (window), %d/%d %dx%d, reqPixScale %f, opaque %d, atop %d, abottom %d, fs %d, visible %d, view %p (START)\n",
(void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, (int)x, (int)y, (int)w, (int)h, (float)reqPixelScale,
- (int) opaque, (int)fullscreen, (int)visible, myView);
+ (int) opaque, (int)atop, (int)abottom, (int)fullscreen, (int)visible, myView);
NS_DURING
// HiDPI scaling: Setup - Available >= 10.7
@@ -921,6 +925,7 @@ NS_ENDHANDLER
[myWindow setOpaque: NO];
[myWindow setBackgroundColor: [NSColor clearColor]];
}
+ [myWindow setAlwaysOn: atop bottom:abottom];
// specify we want mouse-moved events
[myWindow setAcceptsMouseMovedEvents:YES];
@@ -1035,8 +1040,12 @@ NS_ENDHANDLER
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPixelScale0
(JNIEnv *env, jobject jthis, jlong window, jlong view, jfloat reqPixelScale)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtMacWindow* myWindow = (NewtMacWindow*) ((intptr_t) window);
+ if( NULL == myWindow ) {
+ DBG_PRINT( "setPixelScale0 - NULL NEWT win - abort\n");
+ return;
+ }
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtView* myView = (NewtView*) (intptr_t) view ;
#ifdef VERBOSE_ON
int dbgIdx = 1;
@@ -1195,8 +1204,12 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_unlockSur
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_requestFocus0
(JNIEnv *env, jobject window, jlong w, jboolean force)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSWindow* mWin = (NSWindow*) ((intptr_t) w);
+ if( NULL == mWin ) {
+ DBG_PRINT( "requestFocus - NULL NEWT win - abort\n");
+ return;
+ }
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
#ifdef VERBOSE_ON
BOOL hasFocus = [mWin isKeyWindow];
#endif
@@ -1220,12 +1233,16 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_requestFocus0
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_resignFocus0
(JNIEnv *env, jobject window, jlong w)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSWindow* mWin = (NSWindow*) ((intptr_t) w);
+ if( NULL == mWin ) {
+ DBG_PRINT( "resignFocus0 - NULL NEWT win - abort\n");
+ return;
+ }
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSWindow* pWin = [mWin parentWindow];
BOOL hasFocus = [mWin isKeyWindow];
- DBG_PRINT( "requestFocusParent0 - window: %p, parent %p, hasFocus %d (START)\n", mWin, pWin, hasFocus );
+ DBG_PRINT( "resignFocus0 - window: %p, parent %p, hasFocus %d (START)\n", mWin, pWin, hasFocus );
if( hasFocus ) {
if(NULL != pWin) {
// [mWin makeFirstResponder: pWin];
@@ -1234,7 +1251,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_resignFocus0
[pWin resignKeyWindow];
}
}
- DBG_PRINT( "requestFocusParent0 - window: %p (END)\n", mWin);
+ DBG_PRINT( "resignFocus0 - window: %p (END)\n", mWin);
[pool release];
}
@@ -1247,8 +1264,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_resignFocus0
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_orderFront0
(JNIEnv *env, jobject unused, jlong window)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSWindow* mWin = (NSWindow*) ((intptr_t) window);
+ if( NULL == mWin ) {
+ DBG_PRINT( "orderFront0 - NULL NEWT win - abort\n");
+ return;
+ }
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSWindow* pWin = [mWin parentWindow];
DBG_PRINT( "orderFront0 - window: (parent %p) %p visible %d (START)\n", pWin, mWin, [mWin isVisible]);
@@ -1272,8 +1293,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_orderFront0
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_orderOut0
(JNIEnv *env, jobject unused, jlong window)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSWindow* mWin = (NSWindow*) ((intptr_t) window);
+ if( NULL == mWin ) {
+ DBG_PRINT( "orderOut0 - NULL NEWT win - abort\n");
+ return;
+ }
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSWindow* pWin = [mWin parentWindow];
DBG_PRINT( "orderOut0 - window: (parent %p) %p visible %d (START)\n", pWin, mWin, [mWin isVisible]);
@@ -1297,8 +1322,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_orderOut0
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setTitle0
(JNIEnv *env, jobject unused, jlong window, jstring title)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSWindow* win = (NSWindow*) ((intptr_t) window);
+ if( NULL == win ) {
+ DBG_PRINT( "setTitle0 - NULL NEWT win - abort\n");
+ return;
+ }
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
DBG_PRINT( "setTitle0 - window: %p (START)\n", win);
@@ -1374,88 +1403,64 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_changeContent
/*
* Class: jogamp_newt_driver_macosx_WindowDriver
- * Method: setWindowClientTopLeftPointAndSize0
- * Signature: (JIIIIZ)V
+ * Method: updateSizePosInsets0
+ * Signature: (JZ)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setWindowClientTopLeftPointAndSize0
- (JNIEnv *env, jobject unused, jlong window, jint x, jint y, jint w, jint h, jboolean display)
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_updateSizePosInsets0
+ (JNIEnv *env, jobject jthis, jlong window, jboolean defer)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtMacWindow* mWin = (NewtMacWindow*) ((intptr_t) window);
- DBG_PRINT( "setWindowClientTopLeftPointAndSize - window: %p (START)\n", mWin);
+ DBG_PRINT( "updateSizePosInsets - window: %p, defer %d (START)\n", mWin, (int)defer);
- setWindowClientTopLeftPointAndSize(mWin, x, y, w, h, display);
+ [mWin updateSizePosInsets: env jwin:jthis defer:defer];
- DBG_PRINT( "setWindowClientTopLeftPointAndSize - window: %p (END)\n", mWin);
+ DBG_PRINT( "updateSizePosInsets - window: %p, defer %d (END)\n", mWin, (int)defer);
[pool release];
}
/*
* Class: jogamp_newt_driver_macosx_WindowDriver
- * Method: setWindowClientTopLeftPoint0
- * Signature: (JIIZ)V
+ * Method: setWindowClientTopLeftPointAndSize0
+ * Signature: (JIIIIZ)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setWindowClientTopLeftPoint0
- (JNIEnv *env, jobject unused, jlong window, jint x, jint y, jboolean display)
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setWindowClientTopLeftPointAndSize0
+ (JNIEnv *env, jobject unused, jlong window, jint x, jint y, jint w, jint h, jboolean display)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtMacWindow* mWin = (NewtMacWindow*) ((intptr_t) window);
- DBG_PRINT( "setWindowClientTopLeftPoint - window: %p (START)\n", mWin);
+ DBG_PRINT( "setWindowClientTopLeftPointAndSize - window: %p (START)\n", mWin);
- setWindowClientTopLeftPoint(mWin, x, y, display);
+ setWindowClientTopLeftPointAndSize(mWin, x, y, w, h, display);
- DBG_PRINT( "setWindowClientTopLeftPoint - window: %p (END)\n", mWin);
+ DBG_PRINT( "setWindowClientTopLeftPointAndSize - window: %p (END)\n", mWin);
[pool release];
}
/*
* Class: jogamp_newt_driver_macosx_WindowDriver
- * Method: setAlwaysOnTop0
- * Signature: (JZ)V
+ * Method: setWindowClientTopLeftPoint0
+ * Signature: (JIIZ)V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setAlwaysOnTop0
- (JNIEnv *env, jobject unused, jlong window, jboolean atop)
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setWindowClientTopLeftPoint0
+ (JNIEnv *env, jobject unused, jlong window, jint x, jint y, jboolean display)
{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSWindow* win = (NSWindow*) ((intptr_t) window);
-
- DBG_PRINT( "setAlwaysOnTop0 - window: %p, atop %d (START)\n", win, (int)atop);
-
- if(atop) {
- [win setLevel:NSFloatingWindowLevel];
- } else {
- [win setLevel:NSNormalWindowLevel];
+ NewtMacWindow* mWin = (NewtMacWindow*) ((intptr_t) window);
+ if( NULL == mWin ) {
+ DBG_PRINT( "setWindowClientTopLeftPoint - NULL NEWT win - abort\n");
+ return;
}
-
- DBG_PRINT( "setAlwaysOnTop0 - window: %p, atop %d (END)\n", win, (int)atop);
-
- [pool release];
-}
-
-/*
- * Class: jogamp_newt_driver_macosx_WindowDriver
- * Method: setAlwaysOnBottom0
- * Signature: (JZ)V
- */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setAlwaysOnBottom0
- (JNIEnv *env, jobject unused, jlong window, jboolean abottom)
-{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSWindow* win = (NSWindow*) ((intptr_t) window);
- DBG_PRINT( "setAlwaysOnBottom0 - window: %p, abottom %d (START)\n", win, (int)abottom);
+ DBG_PRINT( "setWindowClientTopLeftPoint - window: %p (START)\n", mWin);
- if(abottom) {
- [win setLevel:NSScreenSaverWindowLevel]; // ??
- } else {
- [win setLevel:NSNormalWindowLevel];
- }
+ setWindowClientTopLeftPoint(mWin, x, y, display);
- DBG_PRINT( "setAlwaysOnBottom0 - window: %p, abottom %d (END)\n", win, (int)abottom);
+ DBG_PRINT( "setWindowClientTopLeftPoint - window: %p (END)\n", mWin);
[pool release];
}
@@ -1469,6 +1474,10 @@ JNIEXPORT jobject JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_getLocatio
(JNIEnv *env, jclass unused, jlong win, jint src_x, jint src_y)
{
NewtMacWindow *mWin = (NewtMacWindow*) (intptr_t) win;
+ if( NULL == mWin ) {
+ DBG_PRINT( "getLocationOnScreen0 - NULL NEWT win - abort\n");
+ return NULL;
+ }
if( ![mWin isKindOfClass:[NewtMacWindow class]] ) {
NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin);
return NULL;
@@ -1480,12 +1489,16 @@ JNIEXPORT jobject JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_getLocatio
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerIcon0
(JNIEnv *env, jobject unused, jlong window, jlong handle)
{
+ NewtMacWindow *mWin = (NewtMacWindow*) (intptr_t) window;
+ if( NULL == mWin ) {
+ DBG_PRINT( "setPointerIcon0 - NULL NEWT win - abort\n");
+ return;
+ }
NSCursor *c = (NSCursor*) (intptr_t) handle ;
if ( NULL != c && NO == [c isKindOfClass:[NSCursor class]] ) {
NewtCommon_throwNewRuntimeException(env, "Not a NSCursor %p", c);
return;
}
- NewtMacWindow *mWin = (NewtMacWindow*) (intptr_t) window;
if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin);
return;
@@ -1509,6 +1522,10 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPointerVis
(JNIEnv *env, jclass clazz, jlong window, jboolean hasFocus, jboolean mouseVisible)
{
NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
+ if( NULL == mWin ) {
+ DBG_PRINT( "setPointerVisible0 - NULL NEWT win - abort\n");
+ return;
+ }
if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin);
return;
@@ -1533,6 +1550,10 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_confinePointe
(JNIEnv *env, jclass clazz, jlong window, jboolean confine)
{
NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
+ if( NULL == mWin ) {
+ DBG_PRINT( "confinePointer0 - NULL NEWT win - abort\n");
+ return;
+ }
if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin);
return;
@@ -1556,6 +1577,10 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_warpPointer0
(JNIEnv *env, jclass clazz, jlong window, jint x, jint y)
{
NewtMacWindow *mWin = (NewtMacWindow*) ((intptr_t) window);
+ if( NULL == mWin ) {
+ DBG_PRINT( "warpPointer0 - NULL NEWT win - abort\n");
+ return;
+ }
if( ! [mWin isKindOfClass:[NewtMacWindow class]] ) {
NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin);
return;
diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h
index 7dc5c6e19..14474bc10 100644
--- a/src/newt/native/NewtMacWindow.h
+++ b/src/newt/native/NewtMacWindow.h
@@ -142,6 +142,7 @@ CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen);
#endif
{
BOOL realized;
+ jboolean withinLiveResize;
@public
BOOL hasPresentationSwitch;
NSUInteger defaultPresentationOptions;
@@ -164,7 +165,10 @@ CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen);
- (void) setRealized: (BOOL)v;
- (BOOL) isRealized;
+- (void) setAlwaysOn: (BOOL)top bottom:(BOOL)bottom;
+
- (void) updateInsets: (JNIEnv*) env jwin: (jobject) javaWin;
+- (void) updateSizePosInsets: (JNIEnv*) env jwin: (jobject) javaWin defer: (jboolean)defer;
- (void) attachToParent: (NSWindow*) parent;
- (void) detachFromParent: (NSWindow*) parent;
@@ -189,7 +193,12 @@ CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen);
- (void) windowDidBecomeKey: (NSNotification *) notification;
- (void) windowDidResignKey: (NSNotification *) notification;
+- (void) windowWillStartLiveResize: (NSNotification *) notification;
+- (void) windowDidEndLiveResize: (NSNotification *) notification;
+- (NSSize) windowWillResize: (NSWindow *)sender toSize:(NSSize)frameSize;
- (void) windowDidResize: (NSNotification*) notification;
+- (void) sendResizeEvent;
+
- (void) windowDidMove: (NSNotification*) notification;
- (BOOL) windowClosingImpl: (BOOL) force;
- (BOOL) windowShouldClose: (id) sender;
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m
index 7b3df391d..6024a90d4 100644
--- a/src/newt/native/NewtMacWindow.m
+++ b/src/newt/native/NewtMacWindow.m
@@ -54,7 +54,7 @@ static jfloat GetDelta(NSEvent *event, jint javaMods[]) {
deltaX = CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis2);
deltaY = CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis1);
// fprintf(stderr, "WHEEL/PAD: %lf/%lf - 0x%X\n", (double)deltaX, (double)deltaY, javaMods[0]);
- if( fabsf(deltaX) > fabsf(deltaY) ) {
+ if( fabs(deltaX) > fabs(deltaY) ) {
javaMods[0] |= EVENT_SHIFT_MASK;
delta = deltaX;
} else {
@@ -179,9 +179,10 @@ static jmethodID requestFocusID = NULL;
static jmethodID insetsChangedID = NULL;
static jmethodID sizeChangedID = NULL;
+static jmethodID sizeScreenPosInsetsChangedID = NULL;
static jmethodID updatePixelScaleID = NULL;
static jmethodID visibleChangedID = NULL;
-static jmethodID positionChangedID = NULL;
+static jmethodID screenPositionChangedID = NULL;
static jmethodID focusChangedID = NULL;
static jmethodID windowDestroyNotifyID = NULL;
static jmethodID windowRepaintID = NULL;
@@ -649,31 +650,32 @@ static jmethodID windowRepaintID = NULL;
// convert to 1-based button number (or use zero if no button is involved)
// TODO: detect mouse button when mouse wheel scrolled
- jshort javaButtonNum = 0;
+ jshort javaButtonNum;
jfloat scrollDeltaY = 0.0f;
switch ([event type]) {
- case NSScrollWheel: {
- scrollDeltaY = GetDelta(event, javaMods);
- javaButtonNum = 1;
- break;
- }
- case NSLeftMouseDown:
- case NSLeftMouseUp:
- case NSLeftMouseDragged:
- javaButtonNum = 1;
- break;
- case NSRightMouseDown:
- case NSRightMouseUp:
- case NSRightMouseDragged:
- javaButtonNum = 3;
- break;
- case NSOtherMouseDown:
- case NSOtherMouseUp:
- case NSOtherMouseDragged:
- javaButtonNum = 2;
- break;
+ case NSScrollWheel:
+ scrollDeltaY = GetDelta(event, javaMods);
+ javaButtonNum = 1;
+ break;
+ case NSLeftMouseDown:
+ case NSLeftMouseUp:
+ case NSLeftMouseDragged:
+ javaButtonNum = 1;
+ break;
+ case NSRightMouseDown:
+ case NSRightMouseUp:
+ case NSRightMouseDragged:
+ javaButtonNum = 3;
+ break;
+ case NSOtherMouseDown:
+ case NSOtherMouseUp:
+ case NSOtherMouseDragged:
+ javaButtonNum = 2;
+ break;
+ default:
+ javaButtonNum = 0;
+ break;
}
-
if (evType == EVENT_MOUSE_WHEEL_MOVED && scrollDeltaY == 0) {
// ignore 0 increment wheel scroll events
return;
@@ -830,13 +832,15 @@ NS_ENDHANDLER
updatePixelScaleID = (*env)->GetMethodID(env, clazz, "updatePixelScale", "(ZFF)V");
visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V");
insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)V");
- positionChangedID = (*env)->GetMethodID(env, clazz, "screenPositionChanged", "(ZII)V");
+ sizeScreenPosInsetsChangedID = (*env)->GetMethodID(env, clazz, "sizeScreenPosInsetsChanged", "(ZIIIIIIIIZZ)V");
+ screenPositionChangedID = (*env)->GetMethodID(env, clazz, "screenPositionChanged", "(ZII)V");
focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V");
requestFocusID = (*env)->GetMethodID(env, clazz, "requestFocus", "(Z)V");
- if (enqueueMouseEventID && enqueueKeyEventID && sizeChangedID && updatePixelScaleID && visibleChangedID && insetsChangedID &&
- positionChangedID && focusChangedID && windowDestroyNotifyID && requestFocusID && windowRepaintID)
+ if (enqueueMouseEventID && enqueueKeyEventID && sizeChangedID && updatePixelScaleID && visibleChangedID &&
+ insetsChangedID && sizeScreenPosInsetsChangedID &&
+ screenPositionChangedID && focusChangedID && windowDestroyNotifyID && requestFocusID && windowRepaintID)
{
CKCH_CreateDictionaries();
return YES;
@@ -889,6 +893,7 @@ NS_ENDHANDLER
cachedInsets[3] = 0; // b
realized = YES;
+ withinLiveResize = JNI_FALSE;
DBG_PRINT("NewtWindow::create: %p, realized %d, hasPresentationSwitch %d[defaultOptions 0x%X, fullscreenOptions 0x%X], (refcnt %d)\n",
res, realized, (int)hasPresentationSwitch, (int)defaultPresentationOptions, (int)fullscreenPresentationOptions, (int)[res retainCount]);
return res;
@@ -928,6 +933,20 @@ NS_ENDHANDLER
return realized;
}
+- (void) setAlwaysOn: (BOOL)top bottom:(BOOL)bottom
+{
+ if( top ) {
+ DBG_PRINT( "*************** setAlwaysOn -> top\n");
+ [self setLevel: kCGMaximumWindowLevel];
+ } else if ( bottom ) {
+ DBG_PRINT( "*************** setAlwaysOn -> bottom\n");
+ [self setLevel: kCGDesktopIconWindowLevel]; // w/ input
+ } else {
+ DBG_PRINT( "*************** setAlwaysOn -> normal\n");
+ [self setLevel:NSNormalWindowLevel];
+ }
+}
+
- (void) updateInsets: (JNIEnv*) env jwin: (jobject) javaWin
{
NSRect frameRect = [self frame];
@@ -948,6 +967,33 @@ NS_ENDHANDLER
}
}
+- (void) updateSizePosInsets: (JNIEnv*) env jwin: (jobject) javaWin defer: (jboolean)defer
+{
+ // update insets on every window resize for lack of better hook place
+ [self updateInsets: NULL jwin:NULL];
+
+ NSRect frameRect = [self frame];
+ NSRect contentRect = [self contentRectForFrameRect: frameRect];
+
+ DBG_PRINT( "updateSize: [ w %d, h %d ], liveResize %d\n", (jint) contentRect.size.width, (jint) contentRect.size.height, (jint)withinLiveResize);
+
+ NSPoint p0 = { 0, 0 };
+ p0 = [self getLocationOnScreen: p0];
+
+ DBG_PRINT( "updatePos: [ x %d, y %d ]\n", (jint) p0.x, (jint) p0.y);
+
+ if( NULL != env && NULL != javaWin ) {
+ (*env)->CallVoidMethod(env, javaWin, sizeScreenPosInsetsChangedID, defer,
+ (jint) p0.x, (jint) p0.y,
+ (jint) contentRect.size.width, (jint) contentRect.size.height,
+ cachedInsets[0], cachedInsets[1], cachedInsets[2], cachedInsets[3],
+ JNI_FALSE, // force
+ withinLiveResize
+ );
+ }
+}
+
+
- (void) attachToParent: (NSWindow*) parent
{
DBG_PRINT( "attachToParent.1\n");
@@ -1183,8 +1229,30 @@ NS_ENDHANDLER
[self focusChanged: NO];
}
+- (void) windowWillStartLiveResize: (NSNotification *) notification
+{
+ DBG_PRINT( "*************** windowWillStartLiveResize\n");
+ withinLiveResize = JNI_TRUE;
+}
+- (void) windowDidEndLiveResize: (NSNotification *) notification
+{
+ DBG_PRINT( "*************** windowDidEndLiveResize\n");
+ withinLiveResize = JNI_FALSE;
+ [self sendResizeEvent];
+}
+- (NSSize) windowWillResize: (NSWindow *)sender toSize:(NSSize)frameSize
+{
+ DBG_PRINT( "*************** windowWillResize %lfx%lf\n", frameSize.width, frameSize.height);
+ return frameSize;
+}
- (void)windowDidResize: (NSNotification*) notification
{
+ DBG_PRINT( "*************** windowDidResize\n");
+ [self sendResizeEvent];
+}
+
+- (void) sendResizeEvent
+{
jobject javaWindowObject = NULL;
int shallBeDetached = 0;
JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached);
@@ -1198,15 +1266,7 @@ NS_ENDHANDLER
javaWindowObject = [newtView getJavaWindowObject];
}
if( NULL != javaWindowObject ) {
- // update insets on every window resize for lack of better hook place
- [self updateInsets: env jwin:javaWindowObject];
-
- NSRect frameRect = [self frame];
- NSRect contentRect = [self contentRectForFrameRect: frameRect];
-
- (*env)->CallVoidMethod(env, javaWindowObject, sizeChangedID, JNI_TRUE, // defer
- (jint) contentRect.size.width,
- (jint) contentRect.size.height, JNI_FALSE);
+ [self updateSizePosInsets: env jwin: javaWindowObject defer:JNI_TRUE];
}
// detaching thread not required - daemon
// NewtCommon_ReleaseJNIEnv(shallBeDetached);
@@ -1232,7 +1292,8 @@ NS_ENDHANDLER
NSPoint p0 = { 0, 0 };
p0 = [self getLocationOnScreen: p0];
- (*env)->CallVoidMethod(env, javaWindowObject, positionChangedID, JNI_FALSE, (jint) p0.x, (jint) p0.y);
+ DBG_PRINT( "windowDidMove: [ x %d, y %d ]\n", (jint) p0.x, (jint) p0.y);
+ (*env)->CallVoidMethod(env, javaWindowObject, screenPositionChangedID, JNI_TRUE, (jint) p0.x, (jint) p0.y);
// detaching thread not required - daemon
// NewtCommon_ReleaseJNIEnv(shallBeDetached);
diff --git a/src/newt/native/Window.h b/src/newt/native/Window.h
index ada886d24..f6aba4c83 100644
--- a/src/newt/native/Window.h
+++ b/src/newt/native/Window.h
@@ -53,7 +53,9 @@
#define FLAG_IS_MAXIMIZED_VERT ( 1 << 9 )
#define FLAG_IS_MAXIMIZED_HORZ ( 1 << 10 )
#define FLAG_IS_FULLSCREEN ( 1 << 11 )
-#define FLAG_IS_FULLSCREEN_SPAN ( 1 << 12 )
+#define FLAG_IS_POINTERVISIBLE ( 1 << 12 )
+#define FLAG_IS_POINTERCONFINED ( 1 << 13 )
+#define FLAG_IS_FULLSCREEN_SPAN ( 1 << 14 )
#define TST_FLAG_CHANGE_VISIBILITY(f) ( 0 != ( (f) & FLAG_CHANGE_VISIBILITY ) )
#define TST_FLAG_CHANGE_VISIBILITY_FAST(f) ( 0 != ( (f) & FLAG_CHANGE_VISIBILITY_FAST ) )
diff --git a/src/newt/native/WindowsEDID.c b/src/newt/native/WindowsEDID.c
index d84773dc6..5fc410a91 100644
--- a/src/newt/native/WindowsEDID.c
+++ b/src/newt/native/WindowsEDID.c
@@ -144,8 +144,14 @@ static _TCHAR* Get2ndSlashBlock(const _TCHAR* sIn, _TCHAR* sOut, size_t sOutLen)
size_t len = t - s;
if( len > 0 ) {
if( sOutLen >= len ) {
- _tcsncpy_s(sOut, sOutLen, s, len);
- return sOut;
+ // Bug 1196: Unresolved strncpy_s (MSVCRT) on WinXP.
+ // Mapped: _tcsncpy_s -> strncpy_s (!UNICODE).
+ // On WinXP MSVCRT has no strncpy_s.
+ // _tcsncpy_s(sOut, sOutLen, s, len);
+ if( len <= sOutLen-1 ) {
+ _tcsncpy(sOut, s, len);
+ return sOut;
+ }
}
}
}
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index ad4111ec7..59e054516 100644
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -177,9 +177,11 @@
static jmethodID insetsChangedID = NULL;
static jmethodID sizeChangedID = NULL;
+static jmethodID maximizedChangedID = NULL;
static jmethodID positionChangedID = NULL;
static jmethodID focusChangedID = NULL;
static jmethodID visibleChangedID = NULL;
+static jmethodID sizePosInsetsFocusVisibleChangedID = NULL;
static jmethodID windowDestroyNotifyID = NULL;
static jmethodID windowRepaintID = NULL;
static jmethodID sendMouseEventID = NULL;
@@ -202,15 +204,23 @@ static UnregisterTouchWindowPROCADDR WinTouch_UnregisterTouchWindow = NULL;
static int NewtEDID_avail = 0;
-static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd);
-
typedef struct {
JNIEnv* jenv;
jobject jinstance;
+ /* client x-pos */
+ int xpos;
+ /* client y-pos */
+ int ypos;
/* client size width */
int width;
/* client size height */
int height;
+ /* visible state */
+ BOOL visible;
+ /* focused state */
+ BOOL focused;
+ /* Insets left, right, top, bottom */
+ RECT insets;
/** Tristate: -1 HIDE, 0 NOP, 1 SHOW */
int setPointerVisible;
/** Tristate: -1 RESET, 0 NOP, 1 SET-NEW */
@@ -218,9 +228,17 @@ typedef struct {
HCURSOR setPointerHandle;
HCURSOR defPointerHandle;
/** Bool: 0 NOP, 1 FULLSCREEN */
- int isFullscreen;
+ BOOL isFullscreen;
/** Bool: 0 TOP, 1 CHILD */
- int isChildWindow;
+ BOOL isChildWindow;
+ /** Bool: 0 NOP, 1 minimized/iconic */
+ BOOL isMinimized;
+ /** Bool: 0 NOP, 1 maximized */
+ BOOL isMaximized;
+ BOOL isOnBottom;
+ BOOL isOnTop;
+ /** Bug 1205: Clear Window Background -> security! */
+ BOOL isInCreation;
int pointerCaptured;
int pointerInside;
int touchDownCount;
@@ -228,6 +246,8 @@ typedef struct {
int supportsMTouch;
} WindowUserData;
+static void UpdateInsets(JNIEnv *env, WindowUserData *wud, HWND hwnd);
+
typedef struct {
USHORT javaKey;
USHORT windowsKey;
@@ -601,21 +621,41 @@ static int WmKeyUp(JNIEnv *env, jobject window, USHORT wkey, WORD repCnt, BYTE s
static void NewtWindows_requestFocus (JNIEnv *env, jobject window, HWND hwnd, jboolean force) {
HWND pHwnd, current;
+ WindowUserData * wud;
BOOL isEnabled = IsWindowEnabled(hwnd);
pHwnd = GetParent(hwnd);
current = GetFocus();
- DBG_PRINT("*** WindowsWindow: requestFocus.S force %d, parent %p, window %p, isEnabled %d, isCurrent %d\n",
- (int)force, (void*)pHwnd, (void*)hwnd, isEnabled, current==hwnd);
+#if !defined(__MINGW64__) && ( defined(UNDER_CE) || _MSC_VER <= 1200 )
+ wud = (WindowUserData *) GetWindowLong(hwnd, GWL_USERDATA);
+#else
+ wud = (WindowUserData *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+#endif
+
+ DBG_PRINT("*** WindowsWindow: requestFocus.S force %d, parent %p, window %p, isEnabled %d, isCurrent %d, isOn[Top %d, Bottom %d]\n",
+ (int)force, (void*)pHwnd, (void*)hwnd, isEnabled, current==hwnd,
+ wud->isOnTop, wud->isOnBottom);
if( JNI_TRUE==force || current!=hwnd || !isEnabled ) {
UINT flags = SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
if(!isEnabled) {
EnableWindow(hwnd, TRUE);
}
- SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, flags);
- SetForegroundWindow(hwnd); // Slightly Higher Priority
+ BOOL frontWindow;
+ if( wud->isOnBottom ) {
+ SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
+ frontWindow = FALSE;
+ } else if( wud->isOnTop ) {
+ SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, flags);
+ frontWindow = TRUE;
+ } else {
+ SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, flags);
+ frontWindow = TRUE;
+ }
+ if( frontWindow ) {
+ SetForegroundWindow(hwnd); // Slightly Higher Priority
+ }
SetFocus(hwnd);// Sets Keyboard Focus To Window (activates parent window if exist, or this window)
- if(NULL!=pHwnd) {
+ if( frontWindow && NULL!=pHwnd ) {
SetActiveWindow(hwnd);
}
current = GetFocus();
@@ -660,91 +700,34 @@ static jboolean NewtWindows_setFullScreen(jboolean fullscreen)
return ( DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettings(&dm, flags) ) ? JNI_TRUE : JNI_FALSE;
}
-#if 0
-
-static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd)
-{
- // being naughty here
- static RECT m_insets = { 0, 0, 0, 0 };
- RECT outside;
- RECT inside;
- POINT *rp_inside = (POINT *) (void *) &inside;
- int dx, dy, dw, dh;
-
- if (IsIconic(hwnd)) {
- m_insets.left = m_insets.top = m_insets.right = m_insets.bottom = -1;
- return FALSE;
- }
-
- m_insets.left = m_insets.top = m_insets.right = m_insets.bottom = 0;
-
- GetClientRect(hwnd, &inside);
- GetWindowRect(hwnd, &outside);
-
- DBG_PRINT("*** WindowsWindow: UpdateInsets (a1) window %p, Inside CC: %d/%d - %d/%d %dx%d\n",
- (void*)hwnd,
- (int)inside.left, (int)inside.top, (int)inside.right, (int)inside.bottom,
- (int)(inside.right - inside.left), (int)(inside.bottom - inside.top));
- DBG_PRINT("*** WindowsWindow: UpdateInsets (a1) window %p, Outside SC: %d/%d - %d/%d %dx%d\n",
- (void*)hwnd,
- (int)outside.left, (int)outside.top, (int)outside.right, (int)outside.bottom,
- (int)(outside.right - outside.left), (int)(outside.bottom - outside.top));
-
- // xform client -> screen coord
- ClientToScreen(hwnd, rp_inside);
- ClientToScreen(hwnd, rp_inside+1);
-
- DBG_PRINT("*** WindowsWindow: UpdateInsets (a2) window %p, Inside SC: %d/%d - %d/%d %dx%d\n",
- (void*)hwnd,
- (int)inside.left, (int)inside.top, (int)inside.right, (int)inside.bottom,
- (int)(inside.right - inside.left), (int)(inside.bottom - inside.top));
-
- m_insets.top = inside.top - outside.top;
- m_insets.bottom = outside.bottom - inside.bottom;
- m_insets.left = inside.left - outside.left;
- m_insets.right = outside.right - inside.right;
-
- DBG_PRINT("*** WindowsWindow: UpdateInsets (1.0) window %p, %d/%d - %d/%d %dx%d\n",
- (void*)hwnd,
- (int)m_insets.left, (int)m_insets.top, (int)m_insets.right, (int)m_insets.bottom,
- (int)(m_insets.right-m_insets.left), (int)(m_insets.top-m_insets.bottom));
-
- (*env)->CallVoidMethod(env, window, insetsChangedID, JNI_FALSE,
- m_insets.left, m_insets.right,
- m_insets.top, m_insets.bottom);
- return &m_insets;
-}
-
-#else
-
-static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd)
-{
- // being naughty here
- static RECT m_insets = { 0, 0, 0, 0 };
+static void UpdateInsets(JNIEnv *env, WindowUserData *wud, HWND hwnd) {
+ jobject window = wud->jinstance;
RECT outside;
RECT inside;
+ int strategy = 0;
if (IsIconic(hwnd)) {
- m_insets.left = m_insets.top = m_insets.right = m_insets.bottom = -1;
- return FALSE;
+ wud->insets.left = wud->insets.top = wud->insets.right = wud->insets.bottom = -1;
+ return;
}
- m_insets.left = m_insets.top = m_insets.right = m_insets.bottom = 0;
+ wud->insets.left = wud->insets.top = wud->insets.right = wud->insets.bottom = 0;
GetClientRect(hwnd, &inside);
GetWindowRect(hwnd, &outside);
if (outside.right - outside.left > 0 && outside.bottom - outside.top > 0) {
MapWindowPoints(hwnd, 0, (LPPOINT)&inside, 2);
- m_insets.top = inside.top - outside.top;
- m_insets.bottom = outside.bottom - inside.bottom;
- m_insets.left = inside.left - outside.left;
- m_insets.right = outside.right - inside.right;
+ wud->insets.top = inside.top - outside.top;
+ wud->insets.bottom = outside.bottom - inside.bottom;
+ wud->insets.left = inside.left - outside.left;
+ wud->insets.right = outside.right - inside.right;
+ strategy = 1;
} else {
- m_insets.top = -1;
+ wud->insets.top = -1;
}
- if (m_insets.left < 0 || m_insets.top < 0 ||
- m_insets.right < 0 || m_insets.bottom < 0)
+ if (wud->insets.left < 0 || wud->insets.top < 0 ||
+ wud->insets.right < 0 || wud->insets.bottom < 0)
{
LONG style = GetWindowLong(hwnd, GWL_STYLE);
@@ -752,49 +735,65 @@ static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd)
if (!bIsUndecorated) {
/* Get outer frame sizes. */
if (style & WS_THICKFRAME) {
- m_insets.left = m_insets.right =
+ wud->insets.left = wud->insets.right =
GetSystemMetrics(SM_CXSIZEFRAME);
- m_insets.top = m_insets.bottom =
+ wud->insets.top = wud->insets.bottom =
GetSystemMetrics(SM_CYSIZEFRAME);
} else {
- m_insets.left = m_insets.right =
+ wud->insets.left = wud->insets.right =
GetSystemMetrics(SM_CXDLGFRAME);
- m_insets.top = m_insets.bottom =
+ wud->insets.top = wud->insets.bottom =
GetSystemMetrics(SM_CYDLGFRAME);
}
/* Add in title. */
- m_insets.top += GetSystemMetrics(SM_CYCAPTION);
+ wud->insets.top += GetSystemMetrics(SM_CYCAPTION);
+ strategy += 10;
} else {
/* undo the -1 set above */
- m_insets.left = m_insets.top = m_insets.right = m_insets.bottom = 0;
+ wud->insets.left = wud->insets.top = wud->insets.right = wud->insets.bottom = 0;
+ strategy += 20;
}
}
- DBG_PRINT("*** WindowsWindow: UpdateInsets window %p, [l %d, r %d - t %d, b %d - %dx%d]\n",
- (void*)hwnd, (int)m_insets.left, (int)m_insets.right, (int)m_insets.top, (int)m_insets.bottom,
- (int) ( m_insets.left + m_insets.right ), (int) (m_insets.top + m_insets.bottom));
-
- (*env)->CallVoidMethod(env, window, insetsChangedID, JNI_FALSE,
- (int)m_insets.left, (int)m_insets.right, (int)m_insets.top, (int)m_insets.bottom);
- return &m_insets;
+ DBG_PRINT("*** WindowsWindow: UpdateInsets window %p, s %d, [l %d, r %d - t %d, b %d - %dx%d], at-init %d\n",
+ (void*)hwnd, strategy, (int)wud->insets.left, (int)wud->insets.right, (int)wud->insets.top, (int)wud->insets.bottom,
+ (int) ( wud->insets.left + wud->insets.right ), (int) (wud->insets.top + wud->insets.bottom), wud->isInCreation);
+ if( !wud->isInCreation ) {
+ (*env)->CallVoidMethod(env, window, insetsChangedID, JNI_FALSE,
+ (int)wud->insets.left, (int)wud->insets.right, (int)wud->insets.top, (int)wud->insets.bottom);
+ }
}
-#endif
-
static void WmSize(JNIEnv *env, WindowUserData * wud, HWND wnd, UINT type)
{
RECT rc;
BOOL isVisible = IsWindowVisible(wnd);
jobject window = wud->jinstance;
+ BOOL maxChanged = FALSE;
+
+ DBG_PRINT("*** WindowsWindow: WmSize.0 window %p, %dx%d, isMinimized %d, isMaximized %d, visible %d\n",
+ (void*)wnd, wud->width, wud->height, wud->isMinimized, wud->isMaximized, isVisible);
if (type == SIZE_MINIMIZED) {
- // TODO: deal with minimized window sizing
+ wud->isMinimized = TRUE;
return;
}
+ if (type == SIZE_MAXIMIZED) {
+ if( !wud->isMaximized ) {
+ wud->isMaximized = 1;
+ maxChanged = TRUE;
+ }
+ } else if (type == SIZE_RESTORED) {
+ wud->isMinimized = FALSE;
+ if( wud->isMaximized ) {
+ wud->isMaximized = FALSE;
+ maxChanged = TRUE;
+ }
+ }
// make sure insets are up to date
- (void)UpdateInsets(env, window, wnd);
+ UpdateInsets(env, wud, wnd);
GetClientRect(wnd, &rc);
@@ -802,9 +801,16 @@ static void WmSize(JNIEnv *env, WindowUserData * wud, HWND wnd, UINT type)
wud->width = (int) ( rc.right - rc.left );
wud->height = (int) ( rc.bottom - rc.top );
- DBG_PRINT("*** WindowsWindow: WmSize window %p, %dx%d, visible %d\n", (void*)wnd, wud->width, wud->height, isVisible);
+ DBG_PRINT("*** WindowsWindow: WmSize.X window %p, %dx%d, isMinimized %d, isMaximized %d (changed %d), visible %d, at-init %d\n",
+ (void*)wnd, wud->width, wud->height, wud->isMinimized, wud->isMaximized, maxChanged, isVisible, wud->isInCreation);
- (*env)->CallVoidMethod(env, window, sizeChangedID, JNI_FALSE, wud->width, wud->height, JNI_FALSE);
+ if( !wud->isInCreation ) {
+ if( maxChanged ) {
+ jboolean v = wud->isMaximized ? JNI_TRUE : JNI_FALSE;
+ (*env)->CallVoidMethod(env, window, maximizedChangedID, v, v);
+ }
+ (*env)->CallVoidMethod(env, window, sizeChangedID, JNI_FALSE, wud->width, wud->height, JNI_FALSE);
+ }
}
#ifdef TEST_MOUSE_HOOKS
@@ -930,6 +936,7 @@ static void sendTouchScreenEvent(JNIEnv *env, jobject window,
jNames, jX, jY, jPressure, (jfloat)maxPressure);
}
+// #define DO_ERASEBKGND 1
static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam) {
LRESULT res = 0;
@@ -993,11 +1000,15 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
// Bug 916 - NEWT Fullscreen Mode on Windows ALT-TAB doesn't allow Application Switching
// Remedy for 'some' display drivers, i.e. Intel HD:
// Explicitly push fullscreen window to BOTTOM when inactive (ALT-TAB)
- UINT flags = SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
- if( inactive ) {
- SetWindowPos(wnd, HWND_BOTTOM, 0, 0, 0, 0, flags);
+ if( inactive || wud->isOnBottom ) {
+ SetWindowPos(wnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
} else {
- SetWindowPos(wnd, HWND_TOP, 0, 0, 0, 0, flags);
+ UINT flags = SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
+ if( wud->isOnTop ) {
+ SetWindowPos(wnd, HWND_TOPMOST, 0, 0, 0, 0, flags);
+ } else {
+ SetWindowPos(wnd, HWND_TOP, 0, 0, 0, 0, flags);
+ }
SetForegroundWindow(wnd); // Slightly Higher Priority
}
}
@@ -1005,11 +1016,39 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
}
break;
+ case WM_WINDOWPOSCHANGING: {
+ WINDOWPOS *p = (WINDOWPOS*)lParam;
+ BOOL isThis = wnd == p->hwnd;
+ BOOL isBottom = HWND_BOTTOM == p->hwndInsertAfter;
+ BOOL isTopMost = HWND_TOPMOST == p->hwndInsertAfter;
+ BOOL forceBottom = isThis && wud->isOnBottom && !isBottom;
+ BOOL forceTop = isThis && wud->isOnTop && !isTopMost;
+ #ifdef VERBOSE_ON
+ BOOL isNoTopMost = HWND_NOTOPMOST == p->hwndInsertAfter;
+ BOOL isTop = HWND_TOP == p->hwndInsertAfter;
+ BOOL isNoZ = 0 != ( SWP_NOZORDER & p->flags );
+ DBG_PRINT("*** WindowsWindow: WM_WINDOWPOSCHANGING window %p / %p (= %d), %p[bottom %d, notop %d, top %d, topmost %d, noZ %d, force[Top %d, Bottom %d], %d/%d %dx%d 0x%X\n",
+ wnd, p->hwnd, isThis,
+ p->hwndInsertAfter, isBottom, isNoTopMost, isTop, isTopMost, isNoZ,
+ forceTop, forceBottom,
+ p->x, p->y, p->cx, p->cy, p->flags);
+ #endif
+ if( forceTop ) {
+ p->hwndInsertAfter = HWND_TOPMOST;
+ p->flags &= ~SWP_NOZORDER;
+ } else if( forceBottom ) {
+ p->hwndInsertAfter = HWND_BOTTOM;
+ p->flags &= ~SWP_NOZORDER;
+ }
+ useDefWindowProc = 1;
+ }
+ break;
+
case WM_SETTINGCHANGE:
if (wParam == SPI_SETNONCLIENTMETRICS) {
// make sure insets are updated, we don't need to resize the window
// because the size of the client area doesn't change
- (void)UpdateInsets(env, window, wnd);
+ UpdateInsets(env, wud, wnd);
} else {
useDefWindowProc = 1;
}
@@ -1020,32 +1059,79 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
break;
case WM_SHOWWINDOW:
- (*env)->CallVoidMethod(env, window, visibleChangedID, JNI_FALSE, wParam==TRUE?JNI_TRUE:JNI_FALSE);
+ DBG_PRINT("*** WindowsWindow: WM_SHOWWINDOW window %p: %d, at-init %d\n", wnd, wParam==TRUE, wud->isInCreation);
+ wud->visible = wParam==TRUE;
+ if( !wud->isInCreation ) {
+ (*env)->CallVoidMethod(env, window, visibleChangedID, JNI_FALSE, wParam==TRUE?JNI_TRUE:JNI_FALSE);
+ }
break;
case WM_MOVE:
- DBG_PRINT("*** WindowsWindow: WM_MOVE window %p, %d/%d\n", wnd, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
- (*env)->CallVoidMethod(env, window, positionChangedID, JNI_FALSE, (jint)GET_X_LPARAM(lParam), (jint)GET_Y_LPARAM(lParam));
+ wud->xpos = (int)GET_X_LPARAM(lParam);
+ wud->ypos = (int)GET_Y_LPARAM(lParam);
+ DBG_PRINT("*** WindowsWindow: WM_MOVE window %p, %d/%d, at-init %d\n", wnd, wud->xpos, wud->ypos, wud->isInCreation);
+ if( !wud->isInCreation ) {
+ (*env)->CallVoidMethod(env, window, positionChangedID, JNI_FALSE, (jint)wud->xpos, (jint)wud->ypos);
+ }
useDefWindowProc = 1;
break;
case WM_PAINT: {
- RECT r;
- if (GetUpdateRect(wnd, &r, FALSE /* do not erase background */)) {
- // clear the whole client area and issue repaint for it, w/o looping through erase background
- ValidateRect(wnd, NULL); // clear all!
- (*env)->CallVoidMethod(env, window, windowRepaintID, JNI_FALSE, 0, 0, -1, -1);
+ if( wud->isInCreation ) {
+ #ifdef DO_ERASEBKGND
+ if (GetUpdateRect(wnd, NULL, TRUE /* erase background */)) {
+ DBG_PRINT("*** WindowsWindow: WM_PAINT.0 (dirty)\n");
+ // WM_ERASEBKGND sent!
+ #else
+ if (GetUpdateRect(wnd, NULL, FALSE /* do not erase background */)) {
+ DBG_PRINT("*** WindowsWindow: WM_PAINT.0 (dirty)\n");
+ ValidateRect(wnd, NULL); // clear all!
+ #endif
+ } else {
+ DBG_PRINT("*** WindowsWindow: WM_PAINT.0 (clean)\n");
+ }
} else {
- // shall not happen ?
- ValidateRect(wnd, NULL); // clear all!
+ if (GetUpdateRect(wnd, NULL, FALSE /* do not erase background */)) {
+ DBG_PRINT("*** WindowsWindow: WM_PAINT.1 (dirty)\n");
+ // Let NEWT render the whole client area by issueing repaint for it, w/o looping through erase background
+ ValidateRect(wnd, NULL); // clear all!
+ (*env)->CallVoidMethod(env, window, windowRepaintID, JNI_FALSE, 0, 0, -1, -1);
+ } else {
+ DBG_PRINT("*** WindowsWindow: WM_PAINT.1 (clean)\n");
+ // shall not happen ?
+ ValidateRect(wnd, NULL); // clear all!
+ }
+ // return 0 == done
}
- // return 0 == done
break;
}
case WM_ERASEBKGND:
- // ignore erase background
- (*env)->CallVoidMethod(env, window, windowRepaintID, JNI_FALSE, 0, 0, -1, -1);
- res = 1; // return 1 == done, OpenGL, etc .. erases the background, hence we claim to have just done this
+ if( wud->isInCreation ) {
+ #ifdef DO_ERASEBKGND
+ // On Windows the initial window is clean?!
+ // This fill destroys translucency on Windows 10
+ // (which only seem to work on undecorated windows)
+ PAINTSTRUCT ps;
+ HDC hdc;
+ hdc = BeginPaint(wnd, &ps);
+ DBG_PRINT("*** WindowsWindow: WM_ERASEBKGND.0 (erasure) l/b %d/%d r/t %d/%d\n",
+ ps.rcPaint.left, ps.rcPaint.bottom, ps.rcPaint.right, ps.rcPaint.top);
+ // FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW+1));
+ // FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_APPWORKSPACE+1));
+ // A black color also sets alpha to zero for translucency!
+ FillRect(hdc, &ps.rcPaint, (HBRUSH)GetStockObject(BLACK_PEN));
+ EndPaint(wnd, &ps);
+ #else
+ ValidateRect(wnd, NULL); // clear all!
+ #endif
+ res = 1; // return 1 == done
+ } else {
+ // ignore erase background, but let NEWT render the whole client area
+ DBG_PRINT("*** WindowsWindow: WM_ERASEBKGND.1 (repaint)\n");
+ ValidateRect(wnd, NULL); // clear all!
+ (*env)->CallVoidMethod(env, window, windowRepaintID, JNI_FALSE, 0, 0, -1, -1);
+ res = 1; // return 1 == done, OpenGL, etc .. erases the background, hence we claim to have just done this
+ }
break;
case WM_SETCURSOR :
@@ -1094,8 +1180,11 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
break;
case WM_SETFOCUS:
- DBG_PRINT("*** WindowsWindow: WM_SETFOCUS window %p, lost %p\n", wnd, (HWND)wParam);
- (*env)->CallVoidMethod(env, window, focusChangedID, JNI_FALSE, JNI_TRUE);
+ DBG_PRINT("*** WindowsWindow: WM_SETFOCUS window %p, lost %p, at-init %d\n", wnd, (HWND)wParam, wud->isInCreation);
+ wud->focused = TRUE;
+ if( !wud->isInCreation ) {
+ (*env)->CallVoidMethod(env, window, focusChangedID, JNI_FALSE, JNI_TRUE);
+ }
useDefWindowProc = 1;
break;
@@ -1108,7 +1197,10 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lP
wud->pointerCaptured = 0;
ReleaseCapture();
}
- (*env)->CallVoidMethod(env, window, focusChangedID, JNI_FALSE, JNI_FALSE);
+ wud->focused = FALSE;
+ if( !wud->isInCreation ) {
+ (*env)->CallVoidMethod(env, window, focusChangedID, JNI_FALSE, JNI_FALSE);
+ }
useDefWindowProc = 1;
} else {
// quick focus .. we had it already, are enabled ..
@@ -2032,9 +2124,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowDriver_initIDs0
insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)V");
sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZIIZ)V");
+ maximizedChangedID = (*env)->GetMethodID(env, clazz, "maximizedChanged", "(ZZ)V");
positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(ZII)V");
focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)V");
visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V");
+ sizePosInsetsFocusVisibleChangedID = (*env)->GetMethodID(env, clazz, "sizePosInsetsFocusVisibleChanged", "(ZIIIIIIIIIIZ)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V");
sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(SIIISF)V");
@@ -2044,9 +2138,11 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowDriver_initIDs0
if (insetsChangedID == NULL ||
sizeChangedID == NULL ||
+ maximizedChangedID == NULL ||
positionChangedID == NULL ||
focusChangedID == NULL ||
visibleChangedID == NULL ||
+ sizePosInsetsFocusVisibleChangedID == NULL ||
windowDestroyNotifyID == NULL ||
windowRepaintID == NULL ||
sendMouseEventID == NULL ||
@@ -2088,32 +2184,61 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_getNewtWndP
return (jlong) (intptr_t) wndProc;
}
-static void NewtWindow_setVisiblePosSize(HWND hwnd, BOOL atop, BOOL visible,
+static void NewtWindow_setVisiblePosSize(WindowUserData *wud, HWND hwnd, int jflags, BOOL visible,
int x, int y, int width, int height)
{
- UINT flags;
- BOOL bRes;
-
- DBG_PRINT("*** WindowsWindow: NewtWindow_setVisiblePosSize %d/%d %dx%d, atop %d, visible %d\n",
- x, y, width, height, atop, visible);
+ BOOL atop = TST_FLAG_IS_ALWAYSONTOP(jflags);
+ BOOL abottom = TST_FLAG_IS_ALWAYSONBOTTOM(jflags);
+ UINT wflags;
+
+ DBG_PRINT("*** WindowsWindow: NewtWindow_setVisiblePosSize client %d/%d %dx%d, atop %d, abottom %d, max[change[%d %d], is[%d %d]], visible %d\n",
+ x, y, width, height, atop, abottom,
+ TST_FLAG_CHANGE_MAXIMIZED_VERT(jflags), TST_FLAG_CHANGE_MAXIMIZED_HORZ(jflags),
+ TST_FLAG_IS_MAXIMIZED_VERT(jflags), TST_FLAG_IS_MAXIMIZED_HORZ(jflags),
+ visible);
+
+ x -= wud->insets.left; // top-level
+ y -= wud->insets.top; // top-level
+ width += wud->insets.left + wud->insets.right; // top-level
+ height += wud->insets.top + wud->insets.bottom; // top-level
+ DBG_PRINT("*** WindowsWindow: NewtWindow_setVisiblePosSize top-level %d/%d %dx%d\n", x, y, width, height);
if(visible) {
- flags = SWP_SHOWWINDOW;
+ wflags = SWP_SHOWWINDOW;
+ if( abottom ) {
+ wflags |= SWP_NOACTIVATE;
+ }
} else {
- flags = SWP_NOACTIVATE | SWP_NOZORDER;
+ wflags = SWP_NOACTIVATE | SWP_NOZORDER;
}
if(0>=width || 0>=height ) {
- flags |= SWP_NOSIZE;
+ wflags |= SWP_NOSIZE;
}
+ wud->isOnTop = atop;
+ wud->isOnBottom = abottom;
if(atop) {
- SetWindowPos(hwnd, HWND_TOP, x, y, width, height, flags);
- SetWindowPos(hwnd, HWND_TOPMOST, x, y, width, height, flags);
+ SetWindowPos(hwnd, HWND_TOP, x, y, width, height, wflags);
+ SetWindowPos(hwnd, HWND_TOPMOST, x, y, width, height, wflags);
+ } else if(abottom) {
+ SetWindowPos(hwnd, HWND_NOTOPMOST, x, y, width, height, wflags);
+ SetWindowPos(hwnd, HWND_BOTTOM, x, y, width, height, wflags);
} else {
- SetWindowPos(hwnd, HWND_NOTOPMOST, x, y, width, height, flags);
- SetWindowPos(hwnd, HWND_TOP, x, y, width, height, flags);
+ SetWindowPos(hwnd, HWND_NOTOPMOST, x, y, width, height, wflags);
+ SetWindowPos(hwnd, HWND_TOP, x, y, width, height, wflags);
+ }
+
+ if( TST_FLAG_CHANGE_MAXIMIZED_ANY(jflags) ) {
+ if( TST_FLAG_IS_MAXIMIZED_VERT(jflags) && TST_FLAG_IS_MAXIMIZED_HORZ(jflags) ) {
+ wud->isMaximized = 1;
+ ShowWindow(hwnd, SW_MAXIMIZE);
+ } else if( !TST_FLAG_IS_MAXIMIZED_VERT(jflags) && !TST_FLAG_IS_MAXIMIZED_HORZ(jflags) ) {
+ if( wud->isMaximized ) {
+ ShowWindow(hwnd, SW_RESTORE);
+ wud->isMaximized = 0;
+ }
+ }
}
- // SetWindowPos(hwnd, atop ? HWND_TOPMOST : HWND_TOP, x, y, width, height, flags);
InvalidateRect(hwnd, NULL, TRUE);
UpdateWindow(hwnd);
@@ -2128,16 +2253,15 @@ static void NewtWindow_setVisiblePosSize(HWND hwnd, BOOL atop, BOOL visible,
JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindow0
(JNIEnv *env, jobject obj,
jlong hInstance, jstring jWndClassName, jstring jWndName, jint winMajor, jint winMinor,
- jlong parent, jint jx, jint jy, jint defaultWidth, jint defaultHeight, jboolean autoPosition, jint flags)
+ jlong parent, jint jxpos, jint jypos, jint defaultWidth, jint defaultHeight, jint flags)
{
HWND parentWindow = (HWND) (intptr_t) parent;
const TCHAR* wndClassName = NULL;
const TCHAR* wndName = NULL;
- DWORD windowStyle = WS_DEFAULT_STYLES | WS_VISIBLE;
- int x=(int)jx, y=(int)jy;
+ DWORD windowStyle = WS_DEFAULT_STYLES;
+ int xpos=(int)jxpos, ypos=(int)jypos;
int width=(int)defaultWidth, height=(int)defaultHeight;
- HWND window = NULL;
- int _x = x, _y = y; // pos for CreateWindow, might be tweaked
+ HWND hwnd = NULL;
#ifdef UNICODE
wndClassName = NewtCommon_GetNullTerminatedStringChars(env, jWndClassName);
@@ -2153,43 +2277,54 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindo
return 0;
}
windowStyle |= WS_CHILD ;
- } else if ( TST_FLAG_IS_UNDECORATED(flags) ) {
- windowStyle |= WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
} else {
- windowStyle |= WS_OVERLAPPEDWINDOW;
- if(JNI_TRUE == autoPosition) {
+ if ( TST_FLAG_IS_UNDECORATED(flags) ) {
+ windowStyle |= WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
+ } else if ( TST_FLAG_IS_RESIZABLE(flags) ) {
+ // WS_OVERLAPPEDWINDOW = (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
+ windowStyle |= WS_OVERLAPPEDWINDOW;
+ } else {
+ windowStyle |= WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
+ }
+ if( TST_FLAG_IS_AUTOPOSITION(flags) ) {
// user didn't requested specific position, use WM default
- _x = CW_USEDEFAULT;
- _y = 0;
+ xpos = CW_USEDEFAULT;
+ ypos = 0;
}
}
- window = CreateWindow(wndClassName, wndName, windowStyle,
- _x, _y, width, height,
- parentWindow, NULL,
- (HINSTANCE) (intptr_t) hInstance,
- NULL);
+ hwnd = CreateWindow(wndClassName, wndName, windowStyle,
+ xpos, ypos, width, height,
+ parentWindow, NULL, (HINSTANCE) (intptr_t) hInstance, NULL);
- DBG_PRINT("*** WindowsWindow: CreateWindow thread 0x%X, win %d.%d parent %p, window %p, %d/%d %dx%d, undeco %d, alwaysOnTop %d, autoPosition %d\n",
- (int)GetCurrentThreadId(), winMajor, winMinor, parentWindow, window, x, y, width, height,
- TST_FLAG_IS_UNDECORATED(flags), TST_FLAG_IS_ALWAYSONTOP(flags), autoPosition);
+ DBG_PRINT("*** WindowsWindow: CreateWindow thread 0x%X, win %d.%d parent %p, window %p, %d/%d -> %d/%d %dx%d, undeco %d, alwaysOnTop %d, autoPosition %d\n",
+ (int)GetCurrentThreadId(), winMajor, winMinor, parentWindow, hwnd, jxpos, jypos, xpos, ypos, width, height,
+ TST_FLAG_IS_UNDECORATED(flags), TST_FLAG_IS_ALWAYSONTOP(flags), TST_FLAG_IS_AUTOPOSITION(flags));
- if (NULL == window) {
+ if (NULL == hwnd) {
int lastError = (int) GetLastError();
DBG_PRINT("*** WindowsWindow: CreateWindow failure: 0x%X %d\n", lastError, lastError);
- return 0;
} else {
WindowUserData * wud = (WindowUserData *) malloc(sizeof(WindowUserData));
wud->jinstance = (*env)->NewGlobalRef(env, obj);
wud->jenv = env;
+ wud->xpos = xpos;
+ wud->ypos = ypos;
wud->width = width;
wud->height = height;
+ wud->visible = TRUE;
+ wud->focused = TRUE;
wud->setPointerVisible = 0;
wud->setPointerAction = 0;
wud->defPointerHandle = LoadCursor( NULL, IDC_ARROW);
wud->setPointerHandle = wud->defPointerHandle;
- wud->isFullscreen = 0;
+ wud->isFullscreen = FALSE;
wud->isChildWindow = NULL!=parentWindow;
+ wud->isMinimized = FALSE;
+ wud->isMaximized = FALSE;
+ wud->isOnBottom = FALSE;
+ wud->isOnTop = FALSE;
+ wud->isInCreation = TRUE;
wud->pointerCaptured = 0;
wud->pointerInside = 0;
wud->touchDownCount = 0;
@@ -2208,40 +2343,26 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindo
DBG_PRINT("*** WindowsWindow: CreateWindow winTouchFuncAvail %d, supportsMTouch %d\n", WinTouch_func_avail, wud->supportsMTouch);
#if !defined(__MINGW64__) && ( defined(UNDER_CE) || _MSC_VER <= 1200 )
- SetWindowLong(window, GWL_USERDATA, (intptr_t) wud);
+ SetWindowLong(hwnd, GWL_USERDATA, (intptr_t) wud);
#else
- SetWindowLongPtr(window, GWLP_USERDATA, (intptr_t) wud);
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, (intptr_t) wud);
#endif
- // gather and adjust position and size
- {
- RECT rc;
- RECT * insets;
-
- ShowWindow(window, SW_SHOW);
-
- // send insets before visibility, allowing java code a proper sync point!
- insets = UpdateInsets(env, wud->jinstance, window);
- (*env)->CallVoidMethod(env, wud->jinstance, visibleChangedID, JNI_FALSE, JNI_TRUE);
-
- if(JNI_TRUE == autoPosition) {
- GetWindowRect(window, &rc);
- x = rc.left + insets->left; // client coords
- y = rc.top + insets->top; // client coords
- }
- DBG_PRINT("*** WindowsWindow: CreateWindow client: %d/%d %dx%d (autoPosition %d)\n", x, y, width, height, autoPosition);
+ // send insets before visibility, allowing java code a proper sync point!
+ UpdateInsets(env, wud, hwnd);
- x -= insets->left; // top-level
- y -= insets->top; // top-level
- width += insets->left + insets->right; // top-level
- height += insets->top + insets->bottom; // top-level
- DBG_PRINT("*** WindowsWindow: CreateWindow top-level %d/%d %dx%d\n", x, y, width, height);
-
- NewtWindow_setVisiblePosSize(window, TST_FLAG_IS_ALWAYSONTOP(flags), TRUE, x, y, width, height);
- }
- if( wud->supportsMTouch ) {
- WinTouch_RegisterTouchWindow(window, 0);
+ if( TST_FLAG_IS_AUTOPOSITION(flags) ) {
+ RECT rc;
+ GetWindowRect(hwnd, &rc);
+ xpos = rc.left + wud->insets.left; // client coords
+ ypos = rc.top + wud->insets.top; // client coords
+ wud->xpos = xpos;
+ wud->ypos = ypos;
}
+ DBG_PRINT("*** WindowsWindow: CreateWindow client: %d/%d %dx%d -> %d/%d %dx%d (autoPosition %d)\n",
+ xpos, ypos, width, height,
+ wud->xpos, wud->ypos, wud->width, wud->height,
+ TST_FLAG_IS_AUTOPOSITION(flags));
}
#ifdef UNICODE
@@ -2258,7 +2379,49 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowDriver_CreateWindo
DBG_PRINT("**** LLMP Hook %p, MP Hook %p\n", hookLLMP, hookMP);
#endif
- return (jlong) (intptr_t) window;
+ DBG_PRINT("*** WindowsWindow: CreateWindow done\n");
+ return (jlong) (intptr_t) hwnd;
+}
+
+/*
+ * Class: jogamp_newt_driver_windows_WindowDriver
+ * Method: InitWindow
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_InitWindow0
+ (JNIEnv *env, jobject obj, jlong window, jint flags)
+{
+ HWND hwnd = (HWND) (intptr_t) window;
+ WindowUserData * wud;
+#if !defined(__MINGW64__) && ( defined(UNDER_CE) || _MSC_VER <= 1200 )
+ wud = (WindowUserData *) GetWindowLong(hwnd, GWL_USERDATA);
+#else
+ wud = (WindowUserData *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+#endif
+
+ DBG_PRINT("*** WindowsWindow: InitWindow start %d/%d %dx%d, focused %d, visible %d\n",
+ wud->xpos, wud->ypos, wud->width, wud->height, wud->focused, wud->visible);
+
+ NewtWindow_setVisiblePosSize(wud, hwnd, flags, TRUE, wud->xpos, wud->ypos, wud->width, wud->height);
+ wud->isInCreation = FALSE;
+
+ DBG_PRINT("*** WindowsWindow: InitWindow pos/size set: %d/%d %dx%d, focused %d, visible %d\n",
+ wud->xpos, wud->ypos, wud->width, wud->height, wud->focused, wud->visible);
+
+ if( wud->isMaximized ) {
+ (*env)->CallVoidMethod(env, wud->jinstance, maximizedChangedID, JNI_TRUE, JNI_TRUE);
+ }
+ (*env)->CallVoidMethod(env, wud->jinstance, sizePosInsetsFocusVisibleChangedID, JNI_FALSE,
+ (jint)wud->xpos, (jint)wud->ypos,
+ (jint)wud->width, (jint)wud->height,
+ (jint)wud->insets.left, (jint)wud->insets.right, (jint)wud->insets.top, (jint)wud->insets.bottom,
+ (jint)(wud->focused ? 1 : 0),
+ (jint)(wud->visible ? 1 : 0),
+ JNI_FALSE);
+ DBG_PRINT("*** WindowsWindow: InitWindow JNI callbacks done\n");
+
+ if( wud->supportsMTouch ) {
+ WinTouch_RegisterTouchWindow(hwnd, 0);
+ }
}
/*
@@ -2288,7 +2451,10 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_reconfigureW
HWND hwndP = (HWND) (intptr_t) parent;
HWND hwnd = (HWND) (intptr_t) window;
DWORD windowStyle = WS_DEFAULT_STYLES;
- BOOL styleChange = TST_FLAG_CHANGE_DECORATION(flags) || TST_FLAG_CHANGE_FULLSCREEN(flags) || TST_FLAG_CHANGE_PARENTING(flags) ;
+ BOOL styleChange = TST_FLAG_CHANGE_DECORATION(flags) || TST_FLAG_CHANGE_FULLSCREEN(flags) ||
+ TST_FLAG_CHANGE_PARENTING(flags) || TST_FLAG_CHANGE_RESIZABLE(flags);
+ BOOL atop = TST_FLAG_IS_ALWAYSONTOP(flags);
+ BOOL abottom = TST_FLAG_IS_ALWAYSONBOTTOM(flags);
WindowUserData * wud;
#if !defined(__MINGW64__) && ( defined(UNDER_CE) || _MSC_VER <= 1200 )
wud = (WindowUserData *) GetWindowLong(hwnd, GWL_USERDATA);
@@ -2296,20 +2462,25 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_reconfigureW
wud = (WindowUserData *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
#endif
-
- DBG_PRINT( "*** WindowsWindow: reconfigureWindow0 parent %p, window %p, %d/%d %dx%d, parentChange %d, isChild %d, decorationChange %d, undecorated %d, fullscreenChange %d, fullscreen %d, alwaysOnTopChange %d, alwaysOnTop %d, visibleChange %d, visible %d -> styleChange %d, isChild %d, isFullscreen %d\n",
+ DBG_PRINT( "*** WindowsWindow: reconfigureWindow0 parent %p, window %p, %d/%d %dx%d, parentChange %d, isChild %d, undecoration[change %d, val %d], fullscreen[change %d, val %d], alwaysOnTop[change %d, val %d], alwaysOnBottom[change %d, val %d], visible[change %d, val %d], resizable[change %d, val %d] -> styleChange %d, isChild %d, isMinimized %d, isMaximized %d, isFullscreen %d\n",
parent, window, x, y, width, height,
TST_FLAG_CHANGE_PARENTING(flags), TST_FLAG_IS_CHILD(flags),
TST_FLAG_CHANGE_DECORATION(flags), TST_FLAG_IS_UNDECORATED(flags),
TST_FLAG_CHANGE_FULLSCREEN(flags), TST_FLAG_IS_FULLSCREEN(flags),
TST_FLAG_CHANGE_ALWAYSONTOP(flags), TST_FLAG_IS_ALWAYSONTOP(flags),
- TST_FLAG_CHANGE_VISIBILITY(flags), TST_FLAG_IS_VISIBLE(flags), styleChange, wud->isChildWindow, wud->isFullscreen);
+ TST_FLAG_CHANGE_ALWAYSONBOTTOM(flags), TST_FLAG_IS_ALWAYSONBOTTOM(flags),
+ TST_FLAG_CHANGE_VISIBILITY(flags), TST_FLAG_IS_VISIBLE(flags),
+ TST_FLAG_CHANGE_RESIZABLE(flags), TST_FLAG_CHANGE_RESIZABLE(flags), styleChange,
+ wud->isChildWindow, wud->isMinimized, wud->isMaximized, wud->isFullscreen);
if (!IsWindow(hwnd)) {
DBG_PRINT("*** WindowsWindow: reconfigureWindow0 failure: Passed window %p is invalid\n", (void*)hwnd);
return;
}
+ wud->isOnTop = atop;
+ wud->isOnBottom = abottom;
+
if (NULL!=hwndP && !IsWindow(hwndP)) {
DBG_PRINT("*** WindowsWindow: reconfigureWindow0 failure: Passed parent window %p is invalid\n", (void*)hwndP);
return;
@@ -2334,10 +2505,15 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_reconfigureW
SetParent(hwnd, NULL);
}
- if( TST_FLAG_CHANGE_FULLSCREEN(flags) && TST_FLAG_IS_FULLSCREEN(flags) ) { // FS on
- // TOP: in -> out
- wud->isFullscreen = 1;
- NewtWindows_setFullScreen(JNI_TRUE);
+ if( TST_FLAG_IS_FULLSCREEN(flags) ) {
+ if( TST_FLAG_CHANGE_FULLSCREEN(flags) ) { // FS on
+ wud->isFullscreen = TRUE;
+ if( !abottom ) {
+ NewtWindows_setFullScreen(JNI_TRUE);
+ }
+ } else if( TST_FLAG_CHANGE_ALWAYSONBOTTOM(flags) ) { // FS BOTTOM toggle
+ NewtWindows_setFullScreen( abottom ? JNI_FALSE : JNI_TRUE);
+ }
}
if ( styleChange ) {
@@ -2345,16 +2521,18 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_reconfigureW
windowStyle |= WS_CHILD ;
} else if ( TST_FLAG_IS_UNDECORATED(flags) ) {
windowStyle |= WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
- } else {
+ } else if ( TST_FLAG_IS_RESIZABLE(flags) ) {
+ // WS_OVERLAPPEDWINDOW = (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
windowStyle |= WS_OVERLAPPEDWINDOW;
+ } else {
+ windowStyle |= WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
}
SetWindowLong(hwnd, GWL_STYLE, windowStyle);
SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );
}
if( TST_FLAG_CHANGE_FULLSCREEN(flags) && !TST_FLAG_IS_FULLSCREEN(flags) ) { // FS off
- // CHILD: out -> in
- wud->isFullscreen = 0;
+ wud->isFullscreen = FALSE;
NewtWindows_setFullScreen(JNI_FALSE);
}
@@ -2363,17 +2541,25 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowDriver_reconfigureW
SetParent(hwnd, hwndP );
}
- NewtWindow_setVisiblePosSize(hwnd, TST_FLAG_IS_ALWAYSONTOP(flags), TST_FLAG_IS_VISIBLE(flags), x, y, width, height);
+ NewtWindow_setVisiblePosSize(wud, hwnd, flags, TST_FLAG_IS_VISIBLE(flags), x, y, width, height);
if( TST_FLAG_CHANGE_VISIBILITY(flags) ) {
if( TST_FLAG_IS_VISIBLE(flags) ) {
- ShowWindow(hwnd, SW_SHOW);
+ int cmd = wud->isMinimized ? SW_RESTORE : ( abottom ? SW_SHOWNA : SW_SHOW );
+ wud->isMinimized = FALSE;
+ ShowWindow(hwnd, cmd);
+ if( abottom ) {
+ SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
+ }
+ } else if( !TST_FLAG_CHANGE_VISIBILITY_FAST(flags) && !TST_FLAG_IS_CHILD(flags) ) {
+ wud->isMinimized = TRUE;
+ ShowWindow(hwnd, SW_MINIMIZE);
} else {
ShowWindow(hwnd, SW_HIDE);
}
}
- DBG_PRINT("*** WindowsWindow: reconfigureWindow0.X isChild %d, isFullscreen %d\n", wud->isChildWindow, wud->isFullscreen);
+ DBG_PRINT("*** WindowsWindow: reconfigureWindow0.X isChild %d, isMinimized %d, isFullscreen %d\n", wud->isChildWindow, wud->isMinimized, wud->isFullscreen);
}
/*
diff --git a/src/newt/native/X11Common.h b/src/newt/native/X11Common.h
index 309e62683..f9254ab76 100644
--- a/src/newt/native/X11Common.h
+++ b/src/newt/native/X11Common.h
@@ -71,7 +71,7 @@
extern jclass X11NewtWindowClazz;
extern jmethodID insetsChangedID;
extern jmethodID visibleChangedID;
-extern jmethodID minMaxSizeChangedID;
+extern jmethodID insetsVisibleChangedID;
typedef struct {
Window window;
@@ -81,13 +81,71 @@ typedef struct {
Atom windowDeleteAtom;
uint32_t supportedAtoms;
uint32_t lastDesktop;
+ Bool maxHorz;
+ Bool maxVert;
+ /** flag whether window is mapped */
+ Bool isMapped;
} JavaWindow;
JavaWindow * getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning);
Status NewtWindows_getRootAndParent (Display *dpy, Window w, Window * root_return, Window * parent_return);
-Status NewtWindows_updateInsets(JNIEnv *env, Display *dpy, JavaWindow * w, int *left, int *right, int *top, int *bottom);
-void NewtWindows_updateMinMaxSize(JNIEnv *env, Display *dpy, JavaWindow * w);
+Bool NewtWindows_updateInsets(Display *dpy, JavaWindow * w, int *left, int *right, int *top, int *bottom);
+Bool NewtWindows_updateMaximized(Display *dpy, JavaWindow * w, uint32_t netWMState);
+
+#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_NET_ACTIVE_WINDOW ( 1 << 22 )
+#define _MASK_WM_CHANGE_STATE ( 1 << 23 )
+#define _MASK_MOTIF_WM_HINTS ( 1 << 24 )
+
+#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 _NET_ACTIVE_WINDOW_IDX 22
+#define _WM_CHANGE_STATE_IDX 23
+#define _MOTIF_WM_HINTS_IDX 24
+
+void NewtWindows_setUrgency(Display *dpy, Window window, Bool enable);
+void NewtWindows_sendNET_WM_STATE(Display *dpy, Window root, JavaWindow *w, int prop1Idx, int prop2Idx, Bool enable);
+uint32_t NewtWindows_getNET_WM_STATE(Display *dpy, JavaWindow *w);
#endif /* _X11COMMON_H_ */
diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c
index 0ba454a00..32e0f8786 100644
--- a/src/newt/native/X11Display.c
+++ b/src/newt/native/X11Display.c
@@ -35,7 +35,7 @@
jclass X11NewtWindowClazz = NULL;
jmethodID insetsChangedID = NULL;
jmethodID visibleChangedID = NULL;
-jmethodID minMaxSizeChangedID = NULL;
+jmethodID insetsVisibleChangedID = NULL;
static const char * const ClazzNameX11NewtWindow = "jogamp/newt/driver/x11/WindowDriver";
@@ -46,13 +46,16 @@ static jmethodID getCurrentThreadNameID = NULL;
static jmethodID dumpStackID = NULL;
static jmethodID sizeChangedID = NULL;
static jmethodID positionChangedID = NULL;
-static jmethodID focusChangedID = NULL;
+static jmethodID focusVisibleChangedID = NULL;
static jmethodID reparentNotifyID = NULL;
static jmethodID windowDestroyNotifyID = NULL;
static jmethodID windowRepaintID = NULL;
static jmethodID sendMouseEventID = NULL;
static jmethodID sendKeyEventID = NULL;
-static jmethodID requestFocusID = NULL;
+static jmethodID sendMouseEventRequestFocusID = NULL;
+static jmethodID visibleChangedWindowRepaintID = NULL;
+static jmethodID visibleChangedSendMouseEventID = NULL;
+static jmethodID sizePosMaxInsetsVisibleChangedID = NULL;
/**
* Keycode
@@ -222,7 +225,7 @@ static jint X11InputState2NewtModifiers(unsigned int xstate, jshort javaVKey, jb
/*
* Class: jogamp_newt_driver_x11_DisplayDriver
- * Method: initIDs
+ * Method: initIDs0
* Signature: (Z)Z
*/
JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0
@@ -252,15 +255,18 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0
insetsChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "insetsChanged", "(ZIIII)V");
sizeChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sizeChanged", "(ZIIZ)V");
positionChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "positionChanged", "(ZII)V");
- focusChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "focusChanged", "(ZZ)V");
+ focusVisibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "focusVisibleChanged", "(ZII)V");
visibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "visibleChanged", "(ZZ)V");
- minMaxSizeChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "minMaxSizeChanged", "(IIII)V");
+ insetsVisibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "insetsVisibleChanged", "(ZIIIII)V");
+ sizePosMaxInsetsVisibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sizePosMaxInsetsVisibleChanged", "(ZIIIIIIIIIIIZ)V");
reparentNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "reparentNotify", "(J)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowDestroyNotify", "(Z)Z");
windowRepaintID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowRepaint", "(ZIIII)V");
+ visibleChangedWindowRepaintID = (*env)->GetMethodID(env, X11NewtWindowClazz, "visibleChangedWindowRepaint", "(ZIIIII)V");
sendMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEvent", "(SIIISF)V");
+ sendMouseEventRequestFocusID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEventRequestFocus", "(SIIISF)V");
+ visibleChangedSendMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "visibleChangedSendMouseEvent", "(ZISIIISF)V");
sendKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendKeyEvent", "(SISSCLjava/lang/String;)V");
- requestFocusID = (*env)->GetMethodID(env, X11NewtWindowClazz, "requestFocus", "(Z)V");
if (displayCompletedID == NULL ||
sendRRScreenChangeNotifyID == NULL ||
@@ -269,15 +275,18 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0
insetsChangedID == NULL ||
sizeChangedID == NULL ||
positionChangedID == NULL ||
- focusChangedID == NULL ||
+ focusVisibleChangedID == NULL ||
visibleChangedID == NULL ||
- minMaxSizeChangedID == NULL ||
+ insetsVisibleChangedID == NULL ||
+ sizePosMaxInsetsVisibleChangedID == NULL ||
reparentNotifyID == NULL ||
windowDestroyNotifyID == NULL ||
windowRepaintID == NULL ||
+ visibleChangedWindowRepaintID == NULL ||
sendMouseEventID == NULL ||
- sendKeyEventID == NULL ||
- requestFocusID == NULL) {
+ sendMouseEventRequestFocusID == NULL ||
+ visibleChangedSendMouseEventID == NULL ||
+ sendKeyEventID == NULL) {
return JNI_FALSE;
}
@@ -287,7 +296,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0
/*
* Class: jogamp_newt_driver_x11_DisplayDriver
- * Method: CompleteDisplay
+ * Method: CompleteDisplay0
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_CompleteDisplay0
@@ -353,10 +362,33 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DisplayRelease0
DBG_PRINT("X11: X11Display_DisplayRelease dpy %p\n", dpy);
}
+static int NewtWindows_updateVisibility(JNIEnv *env, Display *dpy, JavaWindow *jw, uint32_t netWMState, const char *dbgs) {
+ int visibleChange;
+ if( jw->isMapped && 0 != ( _MASK_NET_WM_STATE_HIDDEN & jw->supportedAtoms ) ) {
+ if( 0 != ( _MASK_NET_WM_STATE_HIDDEN & netWMState ) ) {
+ visibleChange = 0;
+ } else {
+ visibleChange = 1;
+ }
+ } else {
+ visibleChange = -1;
+ }
+ #ifdef VERBOSE_ON
+ XWindowAttributes xwa;
+ memset(&xwa, 0, sizeof(XWindowAttributes));
+ XGetWindowAttributes(dpy, jw->window, &xwa);
+
+ // map_state: IsUnmapped(0), IsUnviewable(1), IsViewable(2)
+ DBG_PRINT( "X11: event . %s call %p - isMapped %d, visibleChanged %d, map_state %d\n",
+ dbgs, (void*)jw->window, jw->isMapped, visibleChange, xwa.map_state);
+ #endif
+ return visibleChange;
+}
+
/*
* Class: jogamp_newt_driver_x11_DisplayDriver
- * Method: DispatchMessages
- * Signature: (JJJ)V
+ * Method: DispatchMessages0
+ * Signature: (JJJII)V
*/
JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0
(JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom /*, jlong kbdHandle*/,
@@ -522,8 +554,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
switch(evt.type) {
case ButtonPress:
- (*env)->CallVoidMethod(env, jw->jwindow, requestFocusID, JNI_FALSE);
- (*env)->CallVoidMethod(env, jw->jwindow, sendMouseEventID, (jshort) EVENT_MOUSE_PRESSED,
+ (*env)->CallVoidMethod(env, jw->jwindow, sendMouseEventRequestFocusID, (jshort) EVENT_MOUSE_PRESSED,
modifiers,
(jint) evt.xbutton.x, (jint) evt.xbutton.y, (jshort) evt.xbutton.button, 0.0f /*rotation*/);
break;
@@ -539,15 +570,23 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
break;
case EnterNotify:
DBG_PRINT( "X11: event . EnterNotify call %p %d/%d\n", (void*)evt.xcrossing.window, evt.xcrossing.x, evt.xcrossing.y);
- (*env)->CallVoidMethod(env, jw->jwindow, sendMouseEventID, (jshort) EVENT_MOUSE_ENTERED,
- modifiers,
- (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jshort) 0, 0.0f /*rotation*/);
+ {
+ uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw);
+ int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "EnterNotify");
+ (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedSendMouseEventID, JNI_FALSE, (jint)visibleChange,
+ (jshort) EVENT_MOUSE_ENTERED, modifiers,
+ (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jshort) 0, 0.0f /*rotation*/);
+ }
break;
case LeaveNotify:
DBG_PRINT( "X11: event . LeaveNotify call %p %d/%d\n", (void*)evt.xcrossing.window, evt.xcrossing.x, evt.xcrossing.y);
- (*env)->CallVoidMethod(env, jw->jwindow, sendMouseEventID, (jshort) EVENT_MOUSE_EXITED,
- modifiers,
- (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jshort) 0, 0.0f /*rotation*/);
+ {
+ uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw);
+ int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "LeaveNotify");
+ (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedSendMouseEventID, JNI_FALSE, (jint)visibleChange,
+ (jshort) EVENT_MOUSE_EXITED, modifiers,
+ (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jshort) 0, 0.0f /*rotation*/);
+ }
break;
case MappingNotify:
DBG_PRINT( "X11: event . MappingNotify call %p type %d\n", (void*)evt.xmapping.window, evt.xmapping.type);
@@ -579,19 +618,25 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
evt.xconfigure.override_redirect, evt.xconfigure.window != evt.xconfigure.event);
if ( evt.xconfigure.window == evt.xconfigure.event ) {
// ignore child window change notification
- {
- // update insets
- int left, right, top, bottom;
- NewtWindows_updateInsets(env, dpy, jw, &left, &right, &top, &bottom);
- }
- NewtWindows_updateMinMaxSize(env, dpy, jw);
- (*env)->CallVoidMethod(env, jw->jwindow, sizeChangedID, JNI_FALSE,
- (jint) evt.xconfigure.width, (jint) evt.xconfigure.height, JNI_FALSE);
- (*env)->CallVoidMethod(env, jw->jwindow, positionChangedID, JNI_FALSE,
- (jint) evt.xconfigure.x, (jint) evt.xconfigure.y);
+ // insets: negative values are ignored
+ int left=-1, right=-1, top=-1, bottom=-1;
+ uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw);
+ int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "ConfigureNotify");
+ NewtWindows_updateInsets(dpy, jw, &left, &right, &top, &bottom);
+ Bool maxChanged = NewtWindows_updateMaximized(dpy, jw, netWMState);
+ (*env)->CallVoidMethod(env, jw->jwindow, sizePosMaxInsetsVisibleChangedID, JNI_FALSE,
+ (jint) evt.xconfigure.x, (jint) evt.xconfigure.y,
+ (jint) evt.xconfigure.width, (jint) evt.xconfigure.height,
+ (jint)(maxChanged ? ( jw->maxHorz ? 1 : 0 ) : -1),
+ (jint)(maxChanged ? ( jw->maxVert ? 1 : 0 ) : -1),
+ (jint)left, (jint)right, (jint)top, (jint)bottom,
+ (jint)visibleChange,
+ JNI_FALSE);
}
break;
case ClientMessage:
+ DBG_PRINT( "X11: event . ClientMessage call %p type 0x%X, sendEvent %d\n",
+ (void*)evt.xclient.window, (unsigned int)evt.xclient.message_type, evt.xclient.send_event);
if (evt.xclient.send_event==True && evt.xclient.data.l[0]==wm_delete_atom) { // windowDeleteAtom
jboolean closed;
DBG_PRINT( "X11: event . ClientMessage call %p type 0x%X ..\n",
@@ -605,46 +650,76 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
break;
case FocusIn:
- DBG_PRINT( "X11: event . FocusIn call %p\n", (void*)evt.xvisibility.window);
- (*env)->CallVoidMethod(env, jw->jwindow, focusChangedID, JNI_FALSE, JNI_TRUE);
+ DBG_PRINT( "X11: event . FocusIn call %p\n", (void*)evt.xfocus.window);
+ {
+ uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw);
+ int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "FocusIn");
+ (*env)->CallVoidMethod(env, jw->jwindow, focusVisibleChangedID, JNI_FALSE, (jint)1, (jint)visibleChange);
+ }
break;
case FocusOut:
- DBG_PRINT( "X11: event . FocusOut call %p\n", (void*)evt.xvisibility.window);
- (*env)->CallVoidMethod(env, jw->jwindow, focusChangedID, JNI_FALSE, JNI_FALSE);
+ DBG_PRINT( "X11: event . FocusOut call %p\n", (void*)evt.xfocus.window);
+ {
+ uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw);
+ int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "FocusOut");
+ (*env)->CallVoidMethod(env, jw->jwindow, focusVisibleChangedID, JNI_FALSE, (jint)0, (jint)visibleChange);
+ }
+ break;
+
+ case VisibilityNotify:
+ DBG_PRINT( "X11: event . VisibilityNotify call %p\n", (void*)evt.xvisibility.window);
+ {
+ #if 0
+ uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw);
+ int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "VisibilityNotify");
+ if( 0 <= visibleChange ) {
+ (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedID, JNI_FALSE, 0 < visibleChange ? JNI_TRUE : JNI_FALSE);
+ }
+ #endif
+ }
break;
+
case Expose:
DBG_PRINT( "X11: event . Expose call %p %d/%d %dx%d count %d\n", (void*)evt.xexpose.window,
evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height, evt.xexpose.count);
-
if (evt.xexpose.count == 0 && evt.xexpose.width > 0 && evt.xexpose.height > 0) {
(*env)->CallVoidMethod(env, jw->jwindow, windowRepaintID, JNI_FALSE,
evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height);
+ #if 0
+ uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw);
+ int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "Expose");
+ (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedWindowRepaintID, JNI_FALSE, (jint)visibleChange,
+ evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height);
+ #endif
}
break;
case MapNotify:
- DBG_PRINT( "X11: event . MapNotify call Event %p, Window %p, override_redirect %d, child-event: %d\n",
- (void*)evt.xmap.event, (void*)evt.xmap.window, (int)evt.xmap.override_redirect,
+ DBG_PRINT( "X11: event . MapNotify call Event %p, Window %p, isMapped %d -> 1, override_redirect %d, child-event: %d\n",
+ (void*)evt.xmap.event, (void*)evt.xmap.window, jw->isMapped, (int)evt.xmap.override_redirect,
evt.xmap.event!=evt.xmap.window);
if( evt.xmap.event == evt.xmap.window ) {
// ignore child window notification
- {
- // update insets
- int left, right, top, bottom;
- NewtWindows_updateInsets(env, dpy, jw, &left, &right, &top, &bottom);
+ jw->isMapped = True;
+ // insets: negative values are ignored
+ int left=-1, right=-1, top=-1, bottom=-1;
+ if( NewtWindows_updateInsets(dpy, jw, &left, &right, &top, &bottom) ) {
+ (*env)->CallVoidMethod(env, jw->jwindow, insetsVisibleChangedID, JNI_FALSE, left, right, top, bottom, 1);
+ } else {
+ (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE);
}
- (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE);
}
break;
case UnmapNotify:
- DBG_PRINT( "X11: event . UnmapNotify call Event %p, Window %p, from_configure %d, child-event: %d\n",
- (void*)evt.xunmap.event, (void*)evt.xunmap.window, (int)evt.xunmap.from_configure,
+ DBG_PRINT( "X11: event . UnmapNotify call Event %p, Window %p, isMapped %d -> 0, from_configure %d, child-event: %d\n",
+ (void*)evt.xunmap.event, (void*)evt.xunmap.window, jw->isMapped, (int)evt.xunmap.from_configure,
evt.xunmap.event!=evt.xunmap.window);
if( evt.xunmap.event == evt.xunmap.window ) {
// ignore child window notification
+ jw->isMapped = False;
(*env)->CallVoidMethod(env, jw->jwindow, visibleChangedID, JNI_FALSE, JNI_FALSE);
}
break;
@@ -693,7 +768,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage
/*
* Class: Java_jogamp_newt_driver_x11_DisplayDriver
* Method: createPointerIcon0
- * Signature: (JJILjava/lang/Object;I)V
+ * Signature: (JJIZIIII)J
*/
JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_createPointerIcon0
(JNIEnv *env, jclass clazz, jlong display, jobject pixels, jint pixels_byte_offset, jboolean pixels_is_direct, jint width, jint height, jint hotX, jint hotY)
@@ -731,7 +806,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_createPointerI
/*
* Class: Java_jogamp_newt_driver_x11_DisplayDriver
* Method: destroyPointerIcon0
- * Signature: (JJILjava/lang/Object;I)V
+ * Signature: (JJ)V
*/
JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_destroyPointerIcon0
(JNIEnv *env, jclass clazz, jlong display, jlong handle)
diff --git a/src/newt/native/X11RandR13.c b/src/newt/native/X11RandR13.c
index 0dd53feb8..3f9dff289 100644
--- a/src/newt/native/X11RandR13.c
+++ b/src/newt/native/X11RandR13.c
@@ -39,6 +39,14 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_RandR13_getScreenResources0
Display *dpy = (Display *) (intptr_t) display;
Window root = RootWindow(dpy, (int)screen_idx);
+ /* Bug 1183
+ * XRRGetScreenResourcesCurrent (or XRRGetScreenResources)
+ * _occasionally_ reports empty data
+ * unless XRRGetScreenSizeRange has been called once.
+ */
+ int minWidth, minHeight, maxWidth, maxHeight;
+ XRRGetScreenSizeRange ( dpy, root, &minWidth, &minHeight, &maxWidth, &maxHeight);
+
XRRScreenResources *res = XRRGetScreenResourcesCurrent( dpy, root); // 1.3
// XRRScreenResources *res = XRRGetScreenResources( dpy, root); // 1.2
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index 778b71cc5..de2bddc86 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 *));
@@ -178,21 +133,20 @@ static uint32_t NewtWindows_getSupportedFeatureEWMH(Display *dpy, const Atom * a
return 0;
}
static uint32_t NewtWindows_getSupportedFeaturesEWMH(Display *dpy, Window root, Atom * allAtoms, Bool verbose) {
- Atom * actions = NULL;
+ Atom * properties = NULL;
Atom type = 0;
- unsigned long action_len = 0, remain = 0;
+ unsigned long props_count = 0, remain = 0;
int form = 0, i = 0;
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, &action_len, &remain, (unsigned char**)&actions)) ) {
- if( NULL != actions ) {
- for(i=0; i<action_len; i++) {
- res |= NewtWindows_getSupportedFeatureEWMH(dpy, allAtoms, actions[i], i, verbose);
+ &type, &form, &props_count, &remain, (unsigned char**)&properties)) ) {
+ if( NULL != properties ) {
+ for(i=0; i<props_count; i++) {
+ res |= NewtWindows_getSupportedFeatureEWMH(dpy, allAtoms, properties[i], i, verbose);
}
- XFree(actions);
+ XFree(properties);
}
if(verbose) {
fprintf(stderr, "**************** X11: Feature EWMH CHECK: 0x%X\n", res);
@@ -202,6 +156,39 @@ static uint32_t NewtWindows_getSupportedFeaturesEWMH(Display *dpy, Window root,
}
return res;
}
+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;
+ int form = 0, i = 0;
+ uint32_t res = 0;
+ Status s;
+
+ 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 ) {
+ for(i=0; i<props_count; i++) {
+ res |= NewtWindows_getSupportedFeatureEWMH(dpy, allAtoms, properties[i], i, verbose);
+ }
+ XFree(properties);
+ }
+ if(verbose) {
+ 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);
+ }
+ return res;
+}
static JavaWindow* createJavaWindowProperty(JNIEnv *env, Display *dpy, Window root, Window window,
jlong javaObjectAtom, jlong windowDeleteAtom, jobject obj, Bool verbose) {
@@ -222,6 +209,9 @@ static JavaWindow* createJavaWindowProperty(JNIEnv *env, Display *dpy, Window ro
res->windowDeleteAtom = (Atom)windowDeleteAtom;
res->supportedAtoms = NewtWindows_getSupportedFeaturesEWMH(dpy, root, allAtoms, verbose);
res->lastDesktop = 0; //undef
+ res->maxHorz = False;
+ res->maxVert = False;
+ res->isMapped = False;
}
unsigned long jogl_java_object_data[2]; // X11 is based on 'unsigned long'
int nitems_32 = putPtrIn32Long( jogl_java_object_data, (uintptr_t) res);
@@ -325,7 +315,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;
@@ -413,8 +402,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) {
@@ -446,7 +434,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);
@@ -461,16 +448,14 @@ 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);
}
-Status NewtWindows_updateInsets(JNIEnv *env, Display *dpy, JavaWindow * w, int *left, int *right, int *top, int *bottom) {
+Bool NewtWindows_updateInsets(Display *dpy, JavaWindow * w, int *left, int *right, int *top, int *bottom) {
if(0 != NewtWindows_getFrameExtends(dpy, w, left, right, top, bottom)) {
- DBG_PRINT( "NewtWindows_updateInsets: insets by _NET_FRAME_EXTENTS [ l %d, r %d, t %d, b %d ]\n",
- *left, *right, *top, *bottom);
- (*env)->CallVoidMethod(env, w->jwindow, insetsChangedID, JNI_FALSE, *left, *right, *top, *bottom);
- return 1; // OK
+ DBG_PRINT( "NewtWindows_updateInsets: insets by _NET_FRAME_EXTENTS [ l %d, r %d, t %d, b %d ]\n", *left, *right, *top, *bottom);
+ return True; // OK
}
Bool hasDecor = NewtWindows_hasDecorations (dpy, w);
@@ -480,43 +465,23 @@ Status NewtWindows_updateInsets(JNIEnv *env, Display *dpy, JavaWindow * w, int *
Window parent = NewtWindows_getParent(dpy, w->window);
if(0 != NewtWindows_getWindowPositionRelative2Parent (dpy, parent, left, top)) {
*right = *left; *bottom = *top;
- DBG_PRINT( "NewtWindows_updateInsets: insets by parent position [ l %d, r %d, t %d, b %d ]\n",
- *left, *right, *top, *bottom);
- (*env)->CallVoidMethod(env, w->jwindow, insetsChangedID, JNI_FALSE, *left, *right, *top, *bottom);
- return 1; // OK
+ DBG_PRINT( "NewtWindows_updateInsets: insets by parent position [ l %d, r %d, t %d, b %d ]\n", *left, *right, *top, *bottom);
+ return True; // OK
}
}
DBG_PRINT( "NewtWindows_updateInsets: cannot determine insets - hasDecor %d\n", hasDecor);
- return 0; // Error
+ return False; // Error
}
-void NewtWindows_updateMinMaxSize(JNIEnv *env, Display *dpy, JavaWindow * w) {
- XSizeHints * xsh = XAllocSizeHints();
- long xsh_bits = 0;
- int min_width=-1, min_height=-1;
- int max_width=-1, max_height=-1;
- if( NULL != xsh ) {
- xsh->flags = 0;
- xsh->min_width=0;
- xsh->min_height=0;
- xsh->max_width=0;
- xsh->max_height=0;
- if( 0 != XGetWMNormalHints(dpy, w->window, xsh, &xsh_bits) ) {
- // OK
- if( 0 != ( xsh_bits & PMinSize ) ) {
- min_width = xsh->min_width;
- min_height = xsh->min_height;
- }
- if( 0 != ( xsh_bits & PMaxSize ) ) {
- max_width = xsh->max_width;
- max_height = xsh->max_height;
- }
- DBG_PRINT( "NewtWindows_updateMinMaxSize: XGetWMNormalHints 0x%X / 0x%X for window %p on display %p\n", xsh_bits, xsh->flags, (void*)w->window, dpy);
- (*env)->CallVoidMethod(env, w->jwindow, minMaxSizeChangedID, min_width, min_height, max_width, max_height);
- } else {
- DBG_PRINT( "NewtWindows_updateMinMaxSize: XGetWMNormalHints failed (0x%X / 0x%X) for window %p on display %p\n", xsh_bits, xsh->flags, (void*)w->window, dpy);
- }
- XFree(xsh);
+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;
+ return True;
+ } else {
+ return False;
}
}
@@ -546,11 +511,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);
+ }
+}
+
+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);
}
-static void NewtWindows_sendNET_WM_STATE(Display *dpy, Window root, JavaWindow *w, int prop1Idx, int prop2Idx, Bool enable) {
+void NewtWindows_sendNET_WM_STATE(Display *dpy, Window root, JavaWindow *w, int prop1Idx, int prop2Idx, Bool enable) {
XEvent xev;
int i=0;
@@ -671,12 +645,18 @@ static void NewtWindows_setStackingEWMHFlags (Display *dpy, Window root, JavaWin
XChangeProperty( dpy, w->window, w->allAtoms[_NET_WM_BYPASS_COMPOSITOR_IDX], XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&value, 1);
}
} else if( changeMaxVert || changeMaxHorz ) {
+ if( changeMaxHorz ) {
+ w->maxHorz = enable;
+ }
+ if( changeMaxVert ) {
+ w->maxVert = enable;
+ }
NewtWindows_sendNET_WM_STATE(dpy, root, w,
- changeMaxVert ? _NET_WM_STATE_MAXIMIZED_VERT_IDX : 0,
changeMaxHorz ? _NET_WM_STATE_MAXIMIZED_HORZ_IDX : 0,
+ 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);
}
@@ -691,35 +671,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);
}
@@ -753,7 +745,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);
}
}
@@ -840,24 +832,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
@@ -882,6 +873,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);
@@ -893,7 +885,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!
@@ -908,16 +901,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!
- NewtWindows_updateInsets(env, dpy, javaWindow, &left, &right, &top, &bottom);
- (*env)->CallVoidMethod(env, javaWindow->jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE);
+ XSync(dpy, False);
+ if( NewtWindows_updateInsets(dpy, javaWindow, &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;
+ }
if( TST_FLAG_IS_AUTOPOSITION(flags) ) {
// get position from WM
@@ -955,6 +952,7 @@ JNIEXPORT jlongArray JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWind
NewtWindows_setMinMaxSize(dpy, javaWindow, width, height, width, height);
}
}
+ XFlush(dpy);
handles[0] = (jlong)(intptr_t)window;
handles[1] = (jlong)(intptr_t)javaWindow;
jhandles = (*env)->NewLongArray(env, 2);
@@ -968,6 +966,34 @@ 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
*/
@@ -1006,6 +1032,7 @@ 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,
@@ -1045,7 +1072,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)
{
@@ -1101,6 +1128,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
@@ -1142,8 +1171,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);
@@ -1185,10 +1215,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 ) {
@@ -1200,7 +1232,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);
@@ -1209,7 +1240,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);
}
}
@@ -1230,6 +1260,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");
}
@@ -1239,9 +1270,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 ) ;
}
/*