summaryrefslogtreecommitdiffstats
path: root/src/newt/native/X11Display.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/newt/native/X11Display.c')
-rw-r--r--src/newt/native/X11Display.c171
1 files changed, 123 insertions, 48 deletions
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)