summaryrefslogtreecommitdiffstats
path: root/src/newt/native
diff options
context:
space:
mode:
Diffstat (limited to 'src/newt/native')
-rw-r--r--src/newt/native/KDWindow.c11
-rw-r--r--src/newt/native/NewtMacWindow.m23
-rw-r--r--src/newt/native/WindowsWindow.c379
-rw-r--r--src/newt/native/X11Window.c507
4 files changed, 539 insertions, 381 deletions
diff --git a/src/newt/native/KDWindow.c b/src/newt/native/KDWindow.c
index 75a2fe1a1..b574731c2 100644
--- a/src/newt/native/KDWindow.c
+++ b/src/newt/native/KDWindow.c
@@ -93,6 +93,7 @@ typedef struct {
static jmethodID windowCreatedID = NULL;
static jmethodID sizeChangedID = NULL;
+static jmethodID visibleChangedID = NULL;
static jmethodID windowDestroyNotifyID = NULL;
static jmethodID windowDestroyedID = NULL;
static jmethodID sendMouseEventID = NULL;
@@ -150,7 +151,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_opengl_kd_KDDisplay_DispatchMes
KDint32 v[2];
if(!kdGetWindowPropertyiv(kdWindow, KD_WINDOWPROPERTY_SIZE, v)) {
DBG_PRINT( "event window size change : src: %p %dx%d\n", userData, v[0], v[1]);
- (*env)->CallVoidMethod(env, javaWindow, sizeChangedID, (jint) v[0], (jint) v[1]);
+ (*env)->CallVoidMethod(env, javaWindow, sizeChangedID, (jint) v[0], (jint) v[1], JNI_FALSE);
} else {
DBG_PRINT( "event window size change error: src: %p %dx%d\n", userData, v[0], v[1]);
}
@@ -164,6 +165,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_opengl_kd_KDDisplay_DispatchMes
KDboolean visible;
kdGetWindowPropertybv(kdWindow, KD_WINDOWPROPERTY_VISIBILITY, &visible);
DBG_PRINT( "event window visibility: src: %p, v:%d\n", userData, visible);
+ (*env)->CallVoidMethod(env, javaWindow, visibleChangedID, visible?JNI_TRUE:JNI_FALSE);
}
break;
default:
@@ -209,13 +211,15 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_opengl_kd_KDWindow_initIDs
#endif
#endif
windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(J)V");
- sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V");
+ sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(IIZ)V");
+ visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V");
windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V");
sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V");
sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
if (windowCreatedID == NULL ||
sizeChangedID == NULL ||
+ visibleChangedID == NULL ||
windowDestroyNotifyID == NULL ||
windowDestroyedID == NULL ||
sendMouseEventID == NULL ||
@@ -309,6 +313,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_opengl_kd_KDWindow_setVisible0
KDboolean v = (visible==JNI_TRUE)?KD_TRUE:KD_FALSE;
kdSetWindowPropertybv(w, KD_WINDOWPROPERTY_VISIBILITY, &v);
DBG_PRINT( "[setVisible] v=%d\n", visible);
+ (*env)->CallVoidMethod(env, obj, visibleChangedID, visible); // FIXME: or send via event ?
}
JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_opengl_kd_KDWindow_setFullScreen0
@@ -332,6 +337,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_opengl_kd_KDWindow_setSize0
DBG_PRINT( "[setSize] v=%dx%d, res=%d\n", width, height, res);
(void)res;
- (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height);
+ (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height, JNI_FALSE);
}
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m
index da31a686e..9f9442e9d 100644
--- a/src/newt/native/NewtMacWindow.m
+++ b/src/newt/native/NewtMacWindow.m
@@ -100,12 +100,23 @@ jint GetDeltaY(NSEvent *event, jint javaMods) {
}
}
-/** FIXME: Tried child window: message reception ..
- (void)viewWillDraw
{
fprintf(stderr, "*************** viewWillDraw: 0x%p", javaWindowObject); fflush(stderr);
[super viewWillDraw];
-} */
+}
+
+- (void)viewDidHide
+{
+ (*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, JNI_FALSE);
+ [super viewDidHide];
+}
+
+- (void)viewDidUnhide
+{
+ (*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, JNI_TRUE);
+ [super viewDidUnhide];
+}
@end
@@ -113,6 +124,7 @@ static jmethodID sendMouseEventID = NULL;
static jmethodID sendKeyEventID = NULL;
static jmethodID insetsChangedID = NULL;
static jmethodID sizeChangedID = NULL;
+static jmethodID visibleChangedID = NULL;
static jmethodID positionChangedID = NULL;
static jmethodID focusChangedID = NULL;
static jmethodID windowDestroyNotifyID = NULL;
@@ -124,13 +136,14 @@ static jmethodID windowDestroyedID = NULL;
{
sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V");
sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
- sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V");
+ sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(IIZ)V");
+ visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V");
insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(IIII)V");
positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V");
focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(Z)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V");
windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V");
- if (sendMouseEventID && sendKeyEventID && sizeChangedID && insetsChangedID &&
+ if (sendMouseEventID && sendKeyEventID && sizeChangedID && visibleChangedID && insetsChangedID &&
positionChangedID && focusChangedID && windowDestroyedID && windowDestroyNotifyID)
{
return YES;
@@ -398,7 +411,7 @@ static jint mods2JavaMods(NSUInteger mods)
(*env)->CallVoidMethod(env, javaWindowObject, sizeChangedID,
(jint) contentRect.size.width,
- (jint) contentRect.size.height);
+ (jint) contentRect.size.height, JNI_FALSE);
}
- (void)windowDidMove: (NSNotification*) notification
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index e1250811c..44f90bc0e 100644
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -109,6 +109,26 @@
#define STD_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+static void _FatalError(JNIEnv *env, const char* msg, ...)
+{
+ char buffer[512];
+ va_list ap;
+
+ va_start(ap, msg);
+ vsnprintf(buffer, sizeof(buffer), msg, ap);
+ va_end(ap);
+
+ fprintf(stderr, "%s\n", buffer);
+ (*env)->FatalError(env, buffer);
+}
+
+static const char * const ClazzNamePoint = "javax/media/nativewindow/util/Point";
+static const char * const ClazzAnyCstrName = "<init>";
+static const char * const ClazzNamePointCstrSignature = "(II)V";
+
+static jclass pointClz = NULL;
+static jmethodID pointCstr = NULL;
+
static jmethodID insetsChangedID = NULL;
static jmethodID sizeChangedID = NULL;
static jmethodID positionChangedID = NULL;
@@ -124,7 +144,7 @@ static jmethodID sendKeyEventID = NULL;
static jmethodID focusActionID = NULL;
static jmethodID enqueueRequestFocusID = NULL;
-static RECT* UpdateInsets(JNIEnv *env, HWND hwnd, jobject window);
+static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd);
typedef struct {
JNIEnv* jenv;
@@ -600,18 +620,15 @@ static int WmKeyUp(JNIEnv *env, jobject window, UINT wkey, UINT repCnt,
return 0;
}
-static void NewtWindows_requestFocus (JNIEnv *env, jobject window, HWND hwnd, BOOL reparented) {
+static void NewtWindows_requestFocus (JNIEnv *env, jobject window, HWND hwnd, jboolean force) {
HWND pHwnd, current;
pHwnd = GetParent(hwnd);
current = GetFocus();
- DBG_PRINT("*** WindowsWindow: requestFocus.S parent %p, window %p, isCurrent %d, reparented %d\n",
- (void*) pHwnd, (void*)hwnd, current==hwnd, (int) reparented);
- if(reparented || current!=hwnd) {
- if( reparented || JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) {
+ DBG_PRINT("*** WindowsWindow: requestFocus.S parent %p, window %p, isCurrent %d\n",
+ (void*) pHwnd, (void*)hwnd, current==hwnd);
+ if( JNI_TRUE==force || current!=hwnd) {
+ if( JNI_TRUE==force || JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) {
UINT flags = SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
- if(reparented) {
- flags |= SWP_FRAMECHANGED;
- }
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, flags);
SetForegroundWindow(hwnd); // Slightly Higher Priority
SetFocus(hwnd);// Sets Keyboard Focus To Window
@@ -626,7 +643,64 @@ static void NewtWindows_requestFocus (JNIEnv *env, jobject window, HWND hwnd, BO
DBG_PRINT("*** WindowsWindow: requestFocus.XX\n");
}
-static RECT * UpdateInsets(JNIEnv *env, HWND hwnd, jobject window)
+#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,
+ m_insets.left, m_insets.top,
+ m_insets.right, 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 };
@@ -690,13 +764,16 @@ static RECT * UpdateInsets(JNIEnv *env, HWND hwnd, jobject window)
return &m_insets;
}
-static void WmSize(JNIEnv *env, HWND wnd, jobject window, UINT type)
+#endif
+
+static void WmSize(JNIEnv *env, jobject window, HWND wnd, UINT type)
{
RECT rc;
int w, h;
+ BOOL isVisible = IsWindowVisible(wnd);
// make sure insets are up to date
- (void)UpdateInsets(env, wnd, window);
+ (void)UpdateInsets(env, window, wnd);
if (type == SIZE_MINIMIZED) {
// TODO: deal with minimized window sizing
@@ -709,9 +786,11 @@ static void WmSize(JNIEnv *env, HWND wnd, jobject window, UINT type)
w = rc.right - rc.left;
h = rc.bottom - rc.top;
- DBG_PRINT("*** WindowsWindow: WmSize window %p, %dx%d\n", (void*)wnd, w, h);
+ DBG_PRINT("*** WindowsWindow: WmSize window %p, %dx%d, visible %d\n", (void*)wnd, w, h, isVisible);
- (*env)->CallVoidMethod(env, window, sizeChangedID, w, h);
+ if(isVisible) {
+ (*env)->CallVoidMethod(env, window, sizeChangedID, w, h, JNI_FALSE);
+ }
}
static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
@@ -795,14 +874,14 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
break;
case WM_SIZE:
- WmSize(env, wnd, window, (UINT)wParam);
+ WmSize(env, window, wnd, (UINT)wParam);
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, wnd, window);
+ (void)UpdateInsets(env, window, wnd);
} else {
useDefWindowProc = 1;
}
@@ -935,7 +1014,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
// ignore erase background
(*env)->CallVoidMethod(env, window, windowRepaintID, 0, 0, -1, -1);
useDefWindowProc = 0;
- res = 1;
+ res = 1; // OpenGL, etc .. erases the background, hence we claim to have just done this
break;
@@ -1073,8 +1152,25 @@ JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_getHeight
JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_initIDs0
(JNIEnv *env, jclass clazz)
{
+ if(NULL==pointClz) {
+ jclass c = (*env)->FindClass(env, ClazzNamePoint);
+ if(NULL==c) {
+ _FatalError(env, "NEWT WindowsWindows: can't find %s", ClazzNamePoint);
+ }
+ pointClz = (jclass)(*env)->NewGlobalRef(env, c);
+ (*env)->DeleteLocalRef(env, c);
+ if(NULL==pointClz) {
+ _FatalError(env, "NEWT WindowsWindows: can't use %s", ClazzNamePoint);
+ }
+ pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature);
+ if(NULL==pointCstr) {
+ _FatalError(env, "NEWT WindowsWindows: can't fetch %s.%s %s",
+ ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature);
+ }
+ }
+
insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(IIII)V");
- sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V");
+ sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(IIZ)V");
positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V");
focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(Z)V");
visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V");
@@ -1170,7 +1266,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_CreateWi
SetWindowLongPtr(window, GWLP_USERDATA, (intptr_t) wud);
#endif
- UpdateInsets(env, window, obj);
+ UpdateInsets(env, obj, window);
}
#ifdef UNICODE
@@ -1232,109 +1328,115 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_MonitorF
#endif
}
-/*
- * Class: com_jogamp_newt_impl_windows_WindowsWindow
- * Method: setVisible0
- * Signature: (JZ)V
+/***
+ * returns bits: 1: size change, 2: pos change
*/
-JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setVisible0
- (JNIEnv *_env, jclass clazz, jlong window, jboolean visible)
+int NewtWindow_setVisiblePosSize(JNIEnv *env, jobject obj, HWND hwnd, jboolean top, jboolean visible,
+ int x, int y, int width, int height)
{
- HWND hwnd = (HWND) (intptr_t) window;
- DBG_PRINT("*** WindowsWindow: setVisible window %p, visible: %d\n", hwnd, (int)visible);
- if (visible) {
- SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE);
- ShowWindow(hwnd, SW_SHOW);
+ UINT flags;
+ HWND hWndInsertAfter;
+ BOOL bRes;
+ int iRes=0;
+ int wwidth = width; // final window width
+ int wheight = height; // final window height
+
+ DBG_PRINT("*** WindowsWindow: NewtWindow_setVisiblePosSize %d/%d %dx%d, top %d, visible %d\n",
+ x, y, width, height, (int)top, (int)visible);
+
+ if(JNI_TRUE == visible) {
+ flags = SWP_SHOWWINDOW;
} else {
- ShowWindow(hwnd, SW_HIDE);
+ flags = SWP_NOACTIVATE | SWP_NOZORDER;
}
-}
-/*
- * Class: com_jogamp_newt_impl_windows_WindowsWindow
- * Method: setSize0
- * Signature: (JIIII)V
- */
-JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setSize0
- (JNIEnv *env, jobject obj, jlong parent, jlong window, jint x, jint y, jint width, jint height)
-{
- HWND hwndP = (HWND) (intptr_t) parent;
- HWND hwnd = (HWND) (intptr_t) window;
- int nWidth=width, nHeight=height;
- int nX=x, nY=y;
+ if(0>x || 0>y ) {
+ flags |= SWP_NOMOVE;
+ } else {
+ iRes |= 2;
+ }
+ if(0>=width || 0>=height ) {
+ flags |= SWP_NOSIZE;
+ } else {
+ iRes |= 1;
+ }
- if(NULL==hwndP) {
- // since width, height are the size of the client area, we need to add
- // insets
- RECT *pInsets = UpdateInsets(env, hwnd, obj);
+ if(JNI_TRUE == top) {
+ hWndInsertAfter = HWND_TOPMOST;
+ if ( 0 == ( flags & SWP_NOSIZE ) ) {
- RECT r;
- GetWindowRect(hwnd, &r);
+ // since width, height are the size of the client area, we need to add insets
+ RECT *pInsets = UpdateInsets(env, obj, hwnd);
- nWidth = width + pInsets->left + pInsets->right;
- nHeight = height + pInsets->top + pInsets->bottom;
- nX=r.left; nY=r.top; // FIXME: really ?
+ wwidth += pInsets->left + pInsets->right;
+ wheight += pInsets->top + pInsets->bottom;
+ }
+ DBG_PRINT("*** WindowsWindow: NewtWindow_setVisiblePosSize top size w/ insets: %d/%d %dx%d\n", x, y, wwidth, wheight);
+ } else {
+ hWndInsertAfter = HWND_TOP;
+ DBG_PRINT("*** WindowsWindow: NewtWindow_setVisiblePosSize client size: %d/%d %dx%d\n", x, y, wwidth, wheight);
}
- DBG_PRINT("*** WindowsWindow: setSize parent %p, window %p, %d/%d %dx%d -> %d/%d %dx%d\n",
- hwndP, hwnd, x, y, width, height, nX, nY, nWidth, nHeight);
+ SetWindowPos(hwnd, hWndInsertAfter, x, y, wwidth, wheight, flags);
- MoveWindow(hwnd, nX, nY, nWidth, nHeight, TRUE);
+ InvalidateRect(hwnd, NULL, TRUE);
+ UpdateWindow(hwnd);
// we report back the size of client area
- (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height);
+ (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height, JNI_FALSE);
+
+ return iRes;
}
/*
* Class: com_jogamp_newt_impl_windows_WindowsWindow
- * Method: setPosition0
- * Signature: (JJII)V
+ * Method: setVisible0
+ * Signature: (JZ)V
*/
-JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setPosition0
- (JNIEnv *env, jclass clazz, jlong parent, jlong window, jint x, jint y/*, jint width, jint height*/)
+JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setVisible0
+ (JNIEnv *env, jobject obj, jlong window, jboolean visible, jboolean top, jint x, jint y, jint width, jint height)
{
- HWND hwndP = (HWND) (intptr_t) parent;
HWND hwnd = (HWND) (intptr_t) window;
-
- if(NULL==hwndP) {
- DBG_PRINT("*** WindowsWindow: setPosition.1 parent %p, window %p, %d/%d\n", hwndP, hwnd, x, y);
-
- // Top Level Window .. SetWindowPos -> no need to do insets ..
- SetWindowPos(hwnd, hwndP, x, y, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
+ DBG_PRINT("*** WindowsWindow: setVisible window %p, visible: %d, top %d, %d/%d %dx%d\n",
+ hwnd, (int)visible, (int)top, x, y, width, height);
+ if (visible) {
+ NewtWindow_setVisiblePosSize(env, obj, hwnd, top, visible, x, y, width, height);
+ ShowWindow(hwnd, SW_SHOW);
} else {
- RECT rc;
- int w, h;
-
- GetClientRect(hwnd, &rc);
- w = rc.right - rc.left;
- h = rc.bottom - rc.top;
-
- DBG_PRINT("*** WindowsWindow: setPosition.2 parent %p, window %p, %d/%d, %dx%d\n",
- hwndP, hwnd, x, y, /* width, height,*/ w, h);
-
- // Child Window .. must use MoveWindow, no insets (no decoration)
- MoveWindow(hwnd, x, y, w, h, FALSE);
+ ShowWindow(hwnd, SW_HIDE);
}
}
-static void NewtWindows_reparentWindow(JNIEnv *env, jobject obj, HWND hwndP, HWND hwnd, BOOL visible,
- jint x, jint y, jint width, jint height, jboolean bIsUndecorated)
+/*
+ * Class: com_jogamp_newt_impl_windows_WindowsWindow
+ * Method: reconfigureWindow0
+ * Signature: (JIIIIZZII)V
+ */
+JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_reconfigureWindow0
+ (JNIEnv *env, jobject obj, jlong parent, jlong window, jint x, jint y, jint width, jint height,
+ jboolean visible, jboolean parentChange, jint fullScreenChange, jint decorationChange)
{
- UINT flags;
- HWND hWndInsertAfter;
+ HWND hwndP = (HWND) (intptr_t) parent;
+ HWND hwnd = (HWND) (intptr_t) window;
DWORD windowStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN ;
+ BOOL styleChange = ( 0 != decorationChange || 0 != fullScreenChange || JNI_TRUE == parentChange ) ? TRUE : FALSE ;
+ UINT flags = SWP_SHOWWINDOW;
+ HWND hWndInsertAfter;
+
+ DBG_PRINT("*** WindowsWindow: reconfigureWindow0 parent %p, window %p, %d/%d %dx%d, parentChange %d, fullScreenChange %d, visible %d, decorationChange %d -> styleChange %d\n",
+ parent, window, x, y, width, height, parentChange, fullScreenChange, visible, decorationChange, styleChange);
- DBG_PRINT("*** WindowsWindow: reparentWindow.1 parent %p, window %p, %d/%d %dx%d undeco %d\n", (void*)hwndP, (void*)hwnd, x, y, width, height, bIsUndecorated);
if (!IsWindow(hwnd)) {
- DBG_PRINT("*** WindowsWindow: reparentWindow failure: Passed window %p is invalid\n", (void*)hwnd);
+ DBG_PRINT("*** WindowsWindow: reconfigureWindow0 failure: Passed window %p is invalid\n", (void*)hwnd);
return;
}
+
if (NULL!=hwndP && !IsWindow(hwndP)) {
- DBG_PRINT("*** WindowsWindow: reparentWindow failure: Passed parent window %p is invalid\n", (void*)hwndP);
+ DBG_PRINT("*** WindowsWindow: reconfigureWindow0 failure: Passed parent window %p is invalid\n", (void*)hwndP);
return;
}
- if(visible) {
+ if(JNI_TRUE == visible) {
windowStyle |= WS_VISIBLE ;
}
@@ -1342,74 +1444,30 @@ static void NewtWindows_reparentWindow(JNIEnv *env, jobject obj, HWND hwndP, HWN
// TOP: SetParent(.., NULL); Clear WS_CHILD [, Set WS_POPUP]
// CHILD: Set WS_CHILD [, Clear WS_POPUP]; SetParent(.., PARENT)
//
- if ( NULL == hwndP ) {
+ if ( JNI_TRUE == parentChange && NULL == hwndP ) {
SetParent(hwnd, NULL);
- DBG_PRINT("*** WindowsWindow: reparentWindow.2\n");
}
- if(NULL!=hwndP) {
- windowStyle |= WS_CHILD ;
- } else if (bIsUndecorated) {
- windowStyle |= WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
- } else {
- windowStyle |= WS_OVERLAPPEDWINDOW;
+ if ( styleChange ) {
+ if(NULL!=hwndP) {
+ windowStyle |= WS_CHILD ;
+ } else if ( decorationChange < 0 || 0 < fullScreenChange ) {
+ windowStyle |= WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
+ } else {
+ windowStyle |= WS_OVERLAPPEDWINDOW;
+ }
+ SetWindowLong(hwnd, GWL_STYLE, windowStyle);
+ SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );
}
- SetWindowLong(hwnd, GWL_STYLE, windowStyle);
- DBG_PRINT("*** WindowsWindow: reparentWindow.3\n");
- if ( NULL != hwndP ) {
+ if ( JNI_TRUE == parentChange && NULL != hwndP ) {
SetParent(hwnd, hwndP );
- DBG_PRINT("*** WindowsWindow: reparentWindow.4\n");
}
- DBG_PRINT("*** WindowsWindow: reparentWindow.X\n");
-}
-
-/*
- * Class: com_jogamp_newt_impl_windows_WindowsWindow
- * Method: reconfigureWindow0
- * Signature: (JIIIIZ)V
- */
-JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_reconfigureWindow0
- (JNIEnv *env, jobject obj, jlong parent, jlong window, jint x, jint y, jint width, jint height, jboolean bIsUndecorated)
-{
- UINT flags;
- HWND hwndP = (HWND) (intptr_t) parent;
- HWND hwnd = (HWND) (intptr_t) window;
- HWND hWndInsertAfter;
- BOOL isVisible = IsWindowVisible(hwnd);
-
- DBG_PRINT("*** WindowsWindow: reconfigureWindow0.1 parent %p, window %p, %d/%d %dx%d undeco %d visible\n",
- parent, window, x, y, width, height, bIsUndecorated, isVisible);
-
- NewtWindows_reparentWindow(env, obj, hwndP, hwnd, FALSE, x, y, width, height, bIsUndecorated);
-
- if ( NULL == hwndP ) {
- flags = SWP_SHOWWINDOW;
- hWndInsertAfter = HWND_TOPMOST;
- } else {
- flags = SWP_NOACTIVATE | SWP_NOZORDER;
- hWndInsertAfter = 0;
- }
- SetWindowPos(hwnd, hWndInsertAfter, x, y, width, height, flags);
+ NewtWindow_setVisiblePosSize(env, obj, hwnd, (NULL == hwndP) ? JNI_TRUE : JNI_FALSE /* top */, visible,
+ x, y, width, height);
DBG_PRINT("*** WindowsWindow: reconfigureWindow0.X\n");
- (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height); // resize necessary ..
-}
-
-/*
- * Class: com_jogamp_newt_impl_windows_WindowsWindow
- * Method: reparentWindow0
- * Signature: (JIIIIZ)V
- */
-JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_reparentWindow0
- (JNIEnv *env, jobject obj, jlong parent, jlong window, jint x, jint y, jint width, jint height, jboolean bIsUndecorated)
-{
- HWND hwndP = (HWND) (intptr_t) parent;
- HWND hwnd = (HWND) (intptr_t) window;
- BOOL isVisible = IsWindowVisible(hwnd);
-
- NewtWindows_reparentWindow(env, obj, hwndP, hwnd, FALSE, x, y, width, height, bIsUndecorated);
}
/*
@@ -1433,12 +1491,33 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setTitle0
/*
* Class: com_jogamp_newt_impl_windows_WindowsWindow
* Method: requestFocus
- * Signature: (J)V
+ * Signature: (JZ)V
*/
JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_requestFocus0
- (JNIEnv *env, jobject obj, jlong window, jboolean bReparented)
+ (JNIEnv *env, jobject obj, jlong window, jboolean force)
{
- DBG_PRINT("*** WindowsWindow: RequestFocus0: reparented %d\n", (int)bReparented);
- NewtWindows_requestFocus ( env, obj, (HWND) (intptr_t) window, bReparented ) ;
+ DBG_PRINT("*** WindowsWindow: RequestFocus0\n");
+ NewtWindows_requestFocus ( env, obj, (HWND) (intptr_t) window, force) ;
+}
+
+/*
+ * Class: com_jogamp_newt_impl_windows_WindowsWindows
+ * Method: getRelativeLocation0
+ * Signature: (JJII)Ljavax/media/nativewindow/util/Point;
+ */
+JNIEXPORT jobject JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_getRelativeLocation0
+ (JNIEnv *env, jobject obj, jlong jsrc_win, jlong jdest_win, jint src_x, jint src_y)
+{
+ HWND src_win = (HWND) (intptr_t) jsrc_win;
+ HWND dest_win = (HWND) (intptr_t) jdest_win;
+ POINT dest = { src_x, src_y } ;
+ int res;
+
+ res = MapWindowPoints(src_win, dest_win, &dest, 1);
+
+ DBG_PRINT("*** WindowsWindow: getRelativeLocation0: %p %d/%d -> %p %d/%d - ok: %d\n",
+ (void*)src_win, src_x, src_y, (void*)dest_win, (int)dest.x, (int)dest.y, res);
+
+ return (*env)->NewObject(env, pointClz, pointCstr, (jint)dest.x, (jint)dest.y);
}
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index 1394b5410..0cdf6ae57 100644
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -146,12 +146,20 @@ static void _FatalError(JNIEnv *env, const char* msg, ...)
}
static const char * const ClazzNameRuntimeException = "java/lang/RuntimeException";
+
+static const char * const ClazzNameNewtWindow = "com/jogamp/newt/Window";
+
+static const char * const ClazzNamePoint = "javax/media/nativewindow/util/Point";
+static const char * const ClazzAnyCstrName = "<init>";
+static const char * const ClazzNamePointCstrSignature = "(II)V";
+
static jclass runtimeExceptionClz=NULL;
-static const char * const ClazzNameNewtWindow =
- "com/jogamp/newt/Window";
static jclass newtWindowClz=NULL;
+static jclass pointClz = NULL;
+static jmethodID pointCstr = NULL;
+
static jmethodID sizeChangedID = NULL;
static jmethodID positionChangedID = NULL;
static jmethodID focusChangedID = NULL;
@@ -159,7 +167,7 @@ static jmethodID visibleChangedID = NULL;
static jmethodID windowDestroyNotifyID = NULL;
static jmethodID windowDestroyedID = NULL;
static jmethodID windowRepaintID = NULL;
-static jmethodID windowCreatedID = NULL;
+static jmethodID windowReparentedID = NULL;
static jmethodID enqueueMouseEventID = NULL;
static jmethodID sendMouseEventID = NULL;
static jmethodID enqueueKeyEventID = NULL;
@@ -169,6 +177,7 @@ static jmethodID enqueueRequestFocusID = NULL;
static jmethodID displayCompletedID = NULL;
+
static void _throwNewRuntimeException(Display * unlockDisplay, JNIEnv *env, const char* msg, ...)
{
char buffer[512];
@@ -256,6 +265,22 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Display_initIDs0
}
}
+ if(NULL==pointClz) {
+ c = (*env)->FindClass(env, ClazzNamePoint);
+ if(NULL==c) {
+ _FatalError(env, "NEWT X11Windows: can't find %s", ClazzNamePoint);
+ }
+ pointClz = (jclass)(*env)->NewGlobalRef(env, c);
+ (*env)->DeleteLocalRef(env, c);
+ if(NULL==pointClz) {
+ _FatalError(env, "NEWT X11Windows: can't use %s", ClazzNamePoint);
+ }
+ pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature);
+ if(NULL==pointCstr) {
+ _FatalError(env, "NEWT X11Windows: can't fetch %s.%s %s",
+ ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature);
+ }
+ }
return JNI_TRUE;
}
@@ -298,7 +323,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_CompleteDisplay0
* Window
*/
-#define WINDOW_EVENT_MASK ( FocusChangeMask | StructureNotifyMask | ExposureMask )
+#define WINDOW_EVENT_MASK ( FocusChangeMask | SubstructureNotifyMask | StructureNotifyMask | ExposureMask )
static int putPtrIn32Long(unsigned long * dst, uintptr_t src) {
int i=0;
@@ -377,32 +402,43 @@ static jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, j
return jwindow;
}
-/**
-static Window NewtWindows_getParent (Display *dpy, Window w) {
- Window root_return=0;
- Window parent_return=0;
+/** @return zero if fails, non zero if OK */
+static Status NewtWindows_getRootAndParent (Display *dpy, Window w, Window * root_return, Window * parent_return) {
Window *children_return=NULL;
unsigned int nchildren_return=0;
- Status res = XQueryTree(dpy, w, &root_return, &parent_return, &children_return, &nchildren_return);
+ Status res = XQueryTree(dpy, w, root_return, parent_return, &children_return, &nchildren_return);
if(NULL!=children_return) {
XFree(children_return);
}
- if(0!=res) {
+ return res;
+}
+static Window NewtWindows_getRoot (Display *dpy, Window w) {
+ Window root_return;
+ Window parent_return;
+ if( 0 != NewtWindows_getRootAndParent(dpy, w, &root_return, &parent_return) ) {
+ return root_return;
+ }
+ return 0;
+}
+static Window NewtWindows_getParent (Display *dpy, Window w) {
+ Window root_return;
+ Window parent_return;
+ if( 0 != NewtWindows_getRootAndParent(dpy, w, &root_return, &parent_return) ) {
return parent_return;
}
return 0;
-} */
+}
+
-static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy, Window w,
- Bool reparented) {
+static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy, Window w, jboolean force) {
XWindowAttributes xwa;
Window focus_return;
int revert_to_return;
XGetInputFocus(dpy, &focus_return, &revert_to_return);
- if(reparented || focus_return!=w) {
- if( reparented || JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) {
+ if( JNI_TRUE==force || focus_return!=w) {
+ if( JNI_TRUE==force || JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) {
XRaiseWindow(dpy, w);
// Avoid 'BadMatch' errors from XSetInputFocus, ie if window is not viewable
XGetWindowAttributes(dpy, w, &xwa);
@@ -414,32 +450,6 @@ static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy,
XSync(dpy, False);
}
-/**
- * Changing this attribute while a window is established,
- * returns the previous value.
- */
-static Bool NewtWindows_setOverrideRedirect0 (Display *dpy, Window w, XWindowAttributes *xwa, Bool newVal) {
- Bool oldVal = xwa->override_redirect;
- XSetWindowAttributes xswa;
-
- if(oldVal != newVal) {
- memset(&xswa, 0, sizeof(XSetWindowAttributes));
- xswa.override_redirect = newVal;
- XChangeWindowAttributes(dpy, w, CWOverrideRedirect, &xswa);
- }
- return oldVal;
-}
-
-static Bool NewtWindows_setOverrideRedirect1 (Display *dpy, Window w, Bool newVal) {
- XWindowAttributes xwa;
- Bool oldVal;
-
- XSync(dpy, False);
- XGetWindowAttributes(dpy, w, &xwa);
-
- return NewtWindows_setOverrideRedirect0 (dpy, w, &xwa, newVal);
-}
-
#define MWM_HINTS_DECORATIONS (1L << 1)
#define PROP_MWM_HINTS_ELEMENTS 5
@@ -466,7 +476,7 @@ static void NewtWindows_setDecorations (Display *dpy, Window w, Bool decorated)
#define _NET_WM_STATE_REMOVE 0
#define _NET_WM_STATE_ADD 1
-static void NewtWindows_setFullscreen (Display *dpy, Window w, Bool fullscreen) {
+static void NewtWindows_setFullscreen (Display *dpy, Window root, Window w, Bool fullscreen) {
Atom _NET_WM_STATE = XInternAtom( dpy, "_NET_WM_STATE", False );
Atom _NET_WM_STATE_ABOVE = XInternAtom( dpy, "_NET_WM_STATE_ABOVE", False );
Atom _NET_WM_STATE_FULLSCREEN = XInternAtom( dpy, "_NET_WM_STATE_FULLSCREEN", False );
@@ -496,11 +506,13 @@ static void NewtWindows_setFullscreen (Display *dpy, Window w, Bool fullscreen)
xev.xclient.data.l[2] = _NET_WM_STATE_ABOVE;
xev.xclient.data.l[3] = 1; //source indication for normal applications
}
-
XChangeProperty( dpy, w, _NET_WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&types, ntypes);
- XSendEvent (dpy, DefaultRootWindow(dpy), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev );
+ XSync(dpy, False);
+ XSendEvent (dpy, root, False, SubstructureRedirectMask | SubstructureNotifyMask, &xev );
}
+#define USE_SENDIO_DIRECT 1
+
/*
* Class: com_jogamp_newt_impl_x11_X11Display
* Method: DispatchMessages
@@ -545,7 +557,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages
return ;
}
- DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, evt.type);
+ // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, evt.type);
displayDispatchErrorHandlerEnable(1, env);
@@ -581,30 +593,64 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages
switch(evt.type) {
case ButtonPress:
(*env)->CallVoidMethod(env, jwindow, enqueueRequestFocusID, JNI_FALSE);
+ #ifdef USE_SENDIO_DIRECT
(*env)->CallVoidMethod(env, jwindow, sendMouseEventID,
(jint) EVENT_MOUSE_PRESSED,
(jint) evt.xbutton.state,
(jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID,
+ JNI_FALSE,
+ (jint) EVENT_MOUSE_PRESSED,
+ (jint) evt.xbutton.state,
+ (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
+ #endif
break;
case ButtonRelease:
+ #ifdef USE_SENDIO_DIRECT
(*env)->CallVoidMethod(env, jwindow, sendMouseEventID,
(jint) EVENT_MOUSE_RELEASED,
(jint) evt.xbutton.state,
(jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID,
+ JNI_FALSE,
+ (jint) EVENT_MOUSE_RELEASED,
+ (jint) evt.xbutton.state,
+ (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
+ #endif
break;
case MotionNotify:
+ #ifdef USE_SENDIO_DIRECT
(*env)->CallVoidMethod(env, jwindow, sendMouseEventID,
(jint) EVENT_MOUSE_MOVED,
(jint) evt.xmotion.state,
(jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0 /*rotation*/);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID,
+ JNI_FALSE,
+ (jint) EVENT_MOUSE_MOVED,
+ (jint) evt.xmotion.state,
+ (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0 /*rotation*/);
+ #endif
break;
case KeyPress:
+ #ifdef USE_SENDIO_DIRECT
(*env)->CallVoidMethod(env, jwindow, sendKeyEventID,
(jint) EVENT_KEY_PRESSED,
(jint) evt.xkey.state,
X11KeySym2NewtVKey(keySym), (jchar) keyChar);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID,
+ JNI_FALSE,
+ (jint) EVENT_KEY_PRESSED,
+ (jint) evt.xkey.state,
+ X11KeySym2NewtVKey(keySym), (jchar) keyChar);
+ #endif
+
break;
case KeyRelease:
+ #ifdef USE_SENDIO_DIRECT
(*env)->CallVoidMethod(env, jwindow, sendKeyEventID,
(jint) EVENT_KEY_RELEASED,
(jint) evt.xkey.state,
@@ -614,69 +660,132 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages
(jint) EVENT_KEY_TYPED,
(jint) evt.xkey.state,
(jint) -1, (jchar) keyChar);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID,
+ JNI_FALSE,
+ (jint) EVENT_KEY_RELEASED,
+ (jint) evt.xkey.state,
+ X11KeySym2NewtVKey(keySym), (jchar) keyChar);
+
+ (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID,
+ JNI_FALSE,
+ (jint) EVENT_KEY_TYPED,
+ (jint) evt.xkey.state,
+ (jint) -1, (jchar) keyChar);
+ #endif
+
break;
case DestroyNotify:
- DBG_PRINT( "X11: event . DestroyNotify call 0x%X\n", (unsigned int)evt.xdestroywindow.window);
- (*env)->CallVoidMethod(env, jwindow, windowDestroyedID);
+ DBG_PRINT( "X11: event . DestroyNotify call %p, parent %p, child-event: %d\n",
+ (void*)evt.xdestroywindow.window, (void*)evt.xdestroywindow.event, evt.xdestroywindow.window != evt.xdestroywindow.event);
+ if ( evt.xdestroywindow.window == evt.xdestroywindow.event ) {
+ // ignore child destroy notification
+ (*env)->CallVoidMethod(env, jwindow, windowDestroyedID);
+ }
break;
case CreateNotify:
- DBG_PRINT( "X11: event . CreateNotify call 0x%X\n", (unsigned int)evt.xcreatewindow.window);
- (*env)->CallVoidMethod(env, jwindow, windowCreatedID);
+ DBG_PRINT( "X11: event . CreateNotify call %p, parent %p, child-event: 1\n",
+ (void*)evt.xcreatewindow.window, (void*) evt.xcreatewindow.parent);
break;
case ConfigureNotify:
- DBG_PRINT( "X11: event . ConfigureNotify call 0x%X (parent 0x%X, above 0x%X) %d/%d %dx%d %d\n",
- (unsigned int)evt.xconfigure.window, (unsigned int)evt.xconfigure.event, (unsigned int)evt.xconfigure.above,
+ DBG_PRINT( "X11: event . ConfigureNotify call %p (parent %p, above %p) %d/%d %dx%d %d, child-event: %d\n",
+ (void*)evt.xconfigure.window, (void*)evt.xconfigure.event, (void*)evt.xconfigure.above,
evt.xconfigure.x, evt.xconfigure.y, evt.xconfigure.width, evt.xconfigure.height,
- evt.xconfigure.override_redirect);
- (*env)->CallVoidMethod(env, jwindow, sizeChangedID,
- (jint) evt.xconfigure.width, (jint) evt.xconfigure.height);
- (*env)->CallVoidMethod(env, jwindow, positionChangedID,
- (jint) evt.xconfigure.x, (jint) evt.xconfigure.y);
+ evt.xconfigure.override_redirect, evt.xconfigure.window != evt.xconfigure.event);
+ if ( evt.xconfigure.window == evt.xconfigure.event ) {
+ // ignore child window change notification
+ (*env)->CallVoidMethod(env, jwindow, sizeChangedID,
+ (jint) evt.xconfigure.width, (jint) evt.xconfigure.height, JNI_FALSE);
+ (*env)->CallVoidMethod(env, jwindow, positionChangedID,
+ (jint) evt.xconfigure.x, (jint) evt.xconfigure.y);
+ }
break;
case ClientMessage:
if (evt.xclient.send_event==True && evt.xclient.data.l[0]==(Atom)wmDeleteAtom) {
- DBG_PRINT( "X11: event . ClientMessage call 0x%X type 0x%X !!!\n", (unsigned int)evt.xclient.window, (unsigned int)evt.xclient.message_type);
+ DBG_PRINT( "X11: event . ClientMessage call %p type 0x%X !!!\n",
+ (void*)evt.xclient.window, (unsigned int)evt.xclient.message_type);
(*env)->CallVoidMethod(env, jwindow, windowDestroyNotifyID);
// Called by Window.java: CloseWindow();
}
break;
case FocusIn:
- DBG_PRINT( "X11: event . FocusIn call 0x%X\n", (unsigned int)evt.xvisibility.window);
+ DBG_PRINT( "X11: event . FocusIn call %p\n", (void*)evt.xvisibility.window);
(*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_TRUE);
break;
case FocusOut:
- DBG_PRINT( "X11: event . FocusOut call 0x%X\n", (unsigned int)evt.xvisibility.window);
+ DBG_PRINT( "X11: event . FocusOut call %p\n", (void*)evt.xvisibility.window);
(*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_FALSE);
break;
case Expose:
- DBG_PRINT( "X11: event . Expose call 0x%X %d/%d %dx%d\n", (unsigned int)evt.xexpose.window,
- evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height);
+ 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.width > 0 && evt.xexpose.height > 0) {
+ if (evt.xexpose.count == 0 && evt.xexpose.width > 0 && evt.xexpose.height > 0) {
(*env)->CallVoidMethod(env, jwindow, windowRepaintID,
evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height);
}
break;
case MapNotify:
- DBG_PRINT( "X11: event . MapNotify call Event 0x%X, Window 0x%X, override_redirect %d\n",
- (unsigned int)evt.xmap.event, (unsigned int)evt.xmap.window, (int)evt.xmap.override_redirect);
- (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_TRUE);
+ 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,
+ evt.xmap.event!=evt.xmap.window);
+ if( evt.xmap.event == evt.xmap.window ) {
+ // ignore child window notification
+ (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_TRUE);
+ }
break;
case UnmapNotify:
- DBG_PRINT( "X11: event . UnmapNotify call Event 0x%X, Window 0x%X, from_configure %d\n",
- (unsigned int)evt.xunmap.event, (unsigned int)evt.xunmap.window, (int)evt.xunmap.from_configure);
- (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE);
+ 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,
+ evt.xunmap.event!=evt.xunmap.window);
+ if( evt.xunmap.event == evt.xunmap.window ) {
+ // ignore child window notification
+ (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE);
+ }
+ break;
+
+ case ReparentNotify:
+ {
+ jlong parentResult; // 0 if root, otherwise proper value
+ Window winRoot, winTopParent;
+ #ifdef VERBOSE_ON
+ Window oldParentRoot, oldParentTopParent;
+ Window parentRoot, parentTopParent;
+ if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.event, &oldParentRoot, &oldParentTopParent) ) {
+ oldParentRoot=0; oldParentTopParent = 0;
+ }
+ if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.parent, &parentRoot, &parentTopParent) ) {
+ parentRoot=0; parentTopParent = 0;
+ }
+ #endif
+ if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.window, &winRoot, &winTopParent) ) {
+ winRoot=0; winTopParent = 0;
+ }
+ if(evt.xreparent.parent == winRoot) {
+ parentResult = 0; // our java indicator for root window
+ } else {
+ parentResult = (jlong) (intptr_t) evt.xreparent.parent;
+ }
+ #ifdef VERBOSE_ON
+ DBG_PRINT( "X11: event . ReparentNotify: call OldParent %p (root %p, top %p), NewParent %p (root %p, top %p), Window %p (root %p, top %p)\n",
+ (void*)evt.xreparent.event, (void*)oldParentRoot, (void*)oldParentTopParent,
+ (void*)evt.xreparent.parent, (void*)parentRoot, (void*)parentTopParent,
+ (void*)evt.xreparent.window, (void*)winRoot, (void*)winTopParent);
+ #endif
+
+ (*env)->CallVoidMethod(env, jwindow, windowReparentedID, parentResult);
+ }
break;
// unhandled events .. yet ..
default:
- DBG_PRINT("X11: event . unhandled %d 0x%X call 0x%X\n", evt.type, evt.type, (unsigned int)evt.xunmap.window);
+ DBG_PRINT("X11: event . unhandled %d 0x%X call %p\n", (int)evt.type, (unsigned int)evt.type, (void*)evt.xunmap.window);
}
}
}
@@ -741,14 +850,14 @@ JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getHeight0
JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Window_initIDs0
(JNIEnv *env, jclass clazz)
{
- sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V");
+ sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(IIZ)V");
positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V");
focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(Z)V");
visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V");
windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V");
windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(IIII)V");
- windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(J)V");
+ windowReparentedID = (*env)->GetMethodID(env, clazz, "windowReparented", "(J)V");
enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(ZIIIIII)V");
sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V");
enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZIIIC)V");
@@ -763,7 +872,7 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Window_initIDs0
windowDestroyNotifyID == NULL ||
windowDestroyedID == NULL ||
windowRepaintID == NULL ||
- windowCreatedID == NULL ||
+ windowReparentedID == NULL ||
enqueueMouseEventID == NULL ||
sendMouseEventID == NULL ||
enqueueKeyEventID == NULL ||
@@ -819,6 +928,9 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0
if(0==windowParent) {
windowParent = XRootWindowOfScreen(scrn);
}
+ if( XRootWindowOfScreen(scrn) != XRootWindow(dpy, scrn_idx) ) {
+ _FatalError(env, "XRoot Malfunction: %p != %p"+XRootWindowOfScreen(scrn), XRootWindow(dpy, scrn_idx));
+ }
DBG_PRINT( "X11: CreateWindow dpy %p, parent %p, %x/%d %dx%d, undeco %d\n",
(void*)dpy, (void*)windowParent, x, y, width, height, undecorated);
@@ -853,7 +965,8 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0
CWBorderPixel | CWColormap | CWOverrideRedirect ) ;
memset(&xswa, 0, sizeof(xswa));
- xswa.override_redirect = ( 0 != parent ) ? True : False ;
+ // xswa.override_redirect = ( 0 != parent ) ? False : True;
+ xswa.override_redirect = False; // use the window manager, always
xswa.border_pixel = 0;
xswa.background_pixel = 0;
xswa.backing_store=NotUseful; /* NotUseful, WhenMapped, Always */
@@ -861,7 +974,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0
xswa.backing_pixel=0; /* value to use in restoring planes */
xswa.colormap = XCreateColormap(dpy,
- windowParent, // XRootWindow(dpy, scrn_idx),
+ windowParent,
visual,
AllocNone);
@@ -900,9 +1013,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0
NewtWindows_setDecorations(dpy, window, ( JNI_TRUE == undecorated ) ? False : True );
XSync(dpy, False);
- DBG_PRINT( "X11: [CreateWindow] created window 0x%X on display %p\n", (unsigned int)window, dpy);
- (*env)->CallVoidMethod(env, obj, windowCreatedID, (jlong) window);
-
+ DBG_PRINT( "X11: [CreateWindow] created window %p on display %p\n", (void*)window, dpy);
return (jlong) window;
}
@@ -951,13 +1062,30 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CloseWindow0
(*env)->CallVoidMethod(env, obj, windowDestroyedID);
}
+static void NewtWindows_setPosSize(Display *dpy, Window w, jint x, jint y, jint width, jint height)
+{
+ if(width>0 && height>0 || x>=0 && y>=0) { // resize/position if requested
+ XWindowChanges xwc;
+ unsigned int mod_flags = ( (x>=0)?CWX:0 ) | ( (y>=0)?CWY:0 ) |
+ ( (width>0)?CWWidth:0 ) | ( (height>0)?CWHeight:0 ) ;
+ DBG_PRINT( "X11: reconfigureWindow0 pos/size mod: 0x%X\n", mod_flags);
+ memset(&xwc, 0, sizeof(XWindowChanges));
+ xwc.x=x;
+ xwc.y=y;
+ xwc.width=width;
+ xwc.height=height;
+ XConfigureWindow(dpy, w, mod_flags, &xwc);
+ XSync(dpy, False);
+ }
+}
+
/*
* Class: com_jogamp_newt_impl_x11_X11Window
* Method: setVisible0
- * Signature: (JJZ)V
+ * Signature: (JJZIIII)V
*/
JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setVisible0
- (JNIEnv *env, jobject obj, jlong display, jlong window, jboolean visible)
+ (JNIEnv *env, jobject obj, jlong display, jlong window, jboolean visible, jint x, jint y, jint width, jint height)
{
Display * dpy = (Display *) (intptr_t) display;
Window w = (Window)window;
@@ -973,178 +1101,77 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setVisible0
XUnmapWindow(dpy, w);
}
XSync(dpy, False);
-}
-
-/*
- * Class: com_jogamp_newt_impl_x11_X11Window
- * Method: setSize0
- * Signature: (JJII)V
- */
-JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setSize0
- (JNIEnv *env, jobject obj, jlong display, jlong window, jint width, jint height)
-{
- Display * dpy = (Display *) (intptr_t) display;
- Window w = (Window)window;
- XWindowChanges xwc;
-
- DBG_PRINT( "X11: setSize0 %dx%d\n", width, height);
- if(dpy==NULL) {
- _FatalError(env, "invalid display connection..");
- }
-
- memset(&xwc, 0, sizeof(XWindowChanges));
- xwc.width=width;
- xwc.height=height;
- XConfigureWindow(dpy, w, CWWidth|CWHeight, &xwc);
-
- XSync(dpy, False);
+ NewtWindows_setPosSize(dpy, w, x, y, width, height);
}
/*
* Class: com_jogamp_newt_impl_x11_X11Window
- * Method: setPosition0
- * Signature: (JJII)V
+ * Method: reconfigureWindow0
+ * Signature: (JIJJIIIIZZII)V
*/
-JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosition0
- (JNIEnv *env, jobject obj, jlong parent, jlong display, jlong window, jint x, jint y)
+JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_reconfigureWindow0
+ (JNIEnv *env, jobject obj, jlong jdisplay, jint screen_index, jlong jparent, jlong jwindow,
+ jint x, jint y, jint width, jint height, jboolean isVisible, jboolean parentChange, jint fullscreenChange, jint decorationChange)
{
- Display * dpy = (Display *) (intptr_t) display;
- Window w = (Window)window;
- XWindowChanges xwc;
-
- DBG_PRINT( "X11: setPos0 . XConfigureWindow %d/%d\n", x, y);
- if(dpy==NULL) {
- _FatalError(env, "invalid display connection..");
- }
+ Display * dpy = (Display *) (intptr_t) jdisplay;
+ Screen * scrn = ScreenOfDisplay(dpy, (int)screen_index);
+ Window w = (Window)jwindow;
+ Window root = XRootWindowOfScreen(scrn);
+ Window parent = (0!=jparent)?(Window)jparent:root;
+ Window topParentParent;
+ Window topParentWindow;
+ Bool moveIntoParent = False;
- memset(&xwc, 0, sizeof(XWindowChanges));
- xwc.x=x;
- xwc.y=y;
- XConfigureWindow(dpy, w, CWX|CWY, &xwc);
- XSync(dpy, False);
-}
+ displayDispatchErrorHandlerEnable(1, env);
-static void NewtWindows_reparentWindow
- (JNIEnv *env, jobject obj,
- Display * dpy, Screen * scrn, Window w, XWindowAttributes *xwa, jlong jparent,
- jint x, jint y, jboolean undecorated, jboolean isVisible)
-{
- Window parent = (0!=jparent)?(Window)jparent:XRootWindowOfScreen(scrn);
+ topParentParent = NewtWindows_getParent (dpy, parent);
+ topParentWindow = NewtWindows_getParent (dpy, w);
- DBG_PRINT( "X11: reparentWindow dpy %p, parent %p/%p, win %p, %d/%d undec %d\n",
- (void*)dpy, (void*) jparent, (void*)parent, (void*)w, x, y, undecorated);
+ DBG_PRINT( "X11: reconfigureWindow0 dpy %p, scrn %d/%p, parent %p/%p (top %p), win %p (top %p), %d/%d %dx%d visible %d, parentChange %d, fullscreenChange %d, decorationChange %d\n",
+ (void*)dpy, screen_index, (void*)scrn, (void*) jparent, (void*)parent, (void*) topParentParent, (void*)w, (void*)topParentWindow,
+ x, y, width, height, isVisible, parentChange, fullscreenChange, decorationChange);
- if(JNI_TRUE == isVisible) {
+ if(parentChange && JNI_TRUE == isVisible) { // unmap window if visible, reduce X11 internal signaling (WM unmap)
XUnmapWindow(dpy, w);
XSync(dpy, False);
}
- if(0 != jparent) {
- // move into parent ..
- NewtWindows_setDecorations (dpy, w, False);
- XSync(dpy, False);
- NewtWindows_setOverrideRedirect0 (dpy, w, xwa, True);
+ if(0 > fullscreenChange ) { // FS off
+ NewtWindows_setFullscreen(dpy, root, w, False );
XSync(dpy, False);
}
- XReparentWindow( dpy, w, parent, x, y );
- XSync(dpy, False);
-
- if(0 == jparent)
- {
- // move out of parent ..
- NewtWindows_setOverrideRedirect0 (dpy, w, xwa, False);
- XSync(dpy, False);
- NewtWindows_setDecorations (dpy, w, (JNI_TRUE == undecorated) ? False : True);
+ if(parentChange) {
+ if(0 != jparent) { // move into parent ..
+ moveIntoParent = True;
+ NewtWindows_setDecorations (dpy, w, False);
+ XSync(dpy, False);
+ }
+ XReparentWindow( dpy, w, parent, x, y ); // actual reparent call
XSync(dpy, False);
}
- if(JNI_TRUE == isVisible) {
- XMapRaised(dpy, w);
+ if(!moveIntoParent && 0!=decorationChange) {
+ NewtWindows_setDecorations (dpy, w, (0 < decorationChange) ? True : False);
XSync(dpy, False);
}
- DBG_PRINT( "X11: reparentWindow X\n");
-}
-
-/*
- * Class: com_jogamp_newt_impl_x11_X11Window
- * Method: reconfigureWindow0
- * Signature: (JJIJIIIIZ)V
- */
-JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_reconfigureWindow0
- (JNIEnv *env, jobject obj, jlong jparent, jlong display, jint screen_index, jlong window,
- jint x, jint y, jint width, jint height, jboolean undecorated, jboolean isVisible, jboolean isFullscreen)
-{
- Display * dpy = (Display *) (intptr_t) display;
- Window w = (Window)window;
- Screen * scrn = ScreenOfDisplay(dpy, (int)screen_index);
-
- XWindowChanges xwc;
- XWindowAttributes xwa;
-
- DBG_PRINT( "X11: reconfigureWindow0 dpy %p, parent %p, win %p, %d/%d %dx%d undec %d, visible %d, fullscreen %d\n",
- (void*)dpy, (void*) jparent, (void*)w, x, y, width, height, undecorated, isVisible,isFullscreen);
-
- if(dpy==NULL) {
- _FatalError(env, "invalid display connection..");
- }
+ NewtWindows_setPosSize(dpy, w, x, y, width, height);
-
- XSync(dpy, False);
- XGetWindowAttributes(dpy, w, &xwa);
-
- if(JNI_FALSE == isFullscreen ) {
- NewtWindows_setFullscreen(dpy, w, False );
- XSync(dpy, False);
+ if(0 < fullscreenChange ) { // FS on
+ NewtWindows_setFullscreen(dpy, root, w, True );
+ XSync(dpy, False);
}
- NewtWindows_reparentWindow(env, obj, dpy, scrn, w, &xwa, jparent, x, y, undecorated, isVisible);
- XSync(dpy, False);
-
- memset(&xwc, 0, sizeof(XWindowChanges));
- xwc.x=x;
- xwc.y=y;
- xwc.width=width;
- xwc.height=height;
- XConfigureWindow(dpy, w, CWX|CWY|CWWidth|CWHeight, &xwc);
- XSync(dpy, False);
-
- if(JNI_TRUE == isFullscreen ) {
- NewtWindows_setFullscreen(dpy, w, True );
- XSync(dpy, False);
- }
-}
-
-/*
- * Class: com_jogamp_newt_impl_x11_X11Window
- * Method: reparentWindow0
- * Signature: (JJIJIIZ)V
- */
-JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_reparentWindow0
- (JNIEnv *env, jobject obj, jlong jparent, jlong display, jint screen_index, jlong window, jint x, jint y,
- jboolean undecorated, jboolean isVisible)
-{
- Display * dpy = (Display *) (intptr_t) display;
- Window w = (Window)window;
- Screen * scrn = ScreenOfDisplay(dpy, (int)screen_index);
- XWindowAttributes xwa;
-
- DBG_PRINT( "X11: reparentWindow0 dpy %p, parent %p, win %p, %d/%d undec %d, visible %d\n",
- (void*)dpy, (void*) jparent, (void*)w, x, y, undecorated, isVisible);
-
- if(dpy==NULL) {
- _FatalError(env, "invalid display connection..");
+ if(parentChange && JNI_TRUE == isVisible) { // map window
+ XMapRaised(dpy, w);
+ XSync(dpy, False);
}
- XSync(dpy, False);
- XGetWindowAttributes(dpy, w, &xwa);
-
- NewtWindows_reparentWindow(env, obj, dpy, scrn, w, &xwa, jparent, x, y, undecorated, isVisible);
- XSync(dpy, False);
+ displayDispatchErrorHandlerEnable(0, env);
- DBG_PRINT( "X11: reparentWindow0 X\n");
+ DBG_PRINT( "X11: reconfigureWindow0 X\n");
}
/*
@@ -1153,9 +1180,9 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_reparentWindow0
* Signature: (JJ)V
*/
JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_requestFocus0
- (JNIEnv *env, jobject obj, jlong display, jlong window, jboolean bReparented)
+ (JNIEnv *env, jobject obj, jlong display, jlong window, jboolean force)
{
- NewtWindows_requestFocus ( env, obj, (Display *) (intptr_t) display, (Window)window, bReparented ) ;
+ NewtWindows_requestFocus ( env, obj, (Display *) (intptr_t) display, (Window)window, force ) ;
}
/*
@@ -1210,3 +1237,37 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setTitle0
}
+
+/*
+ * Class: com_jogamp_newt_impl_x11_X11Window
+ * Method: getRelativeLocation0
+ * Signature: (JIJJII)Ljavax/media/nativewindow/util/Point;
+ */
+JNIEXPORT jobject JNICALL Java_com_jogamp_newt_impl_x11_X11Window_getRelativeLocation0
+ (JNIEnv *env, jobject obj, jlong jdisplay, jint screen_index, jlong jsrc_win, jlong jdest_win, jint src_x, jint src_y)
+{
+ Display * dpy = (Display *) (intptr_t) jdisplay;
+ Screen * scrn = ScreenOfDisplay(dpy, (int)screen_index);
+ Window root = XRootWindowOfScreen(scrn);
+ Window src_win = (Window)jsrc_win;
+ Window dest_win = (Window)jdest_win;
+ int dest_x=-1;
+ int dest_y=-1;
+ Window child;
+ Bool res;
+
+ if( 0 == jdest_win ) { dest_win = root; }
+ if( 0 == jsrc_win ) { src_win = root; }
+
+ displayDispatchErrorHandlerEnable(1, env);
+
+ res = XTranslateCoordinates(dpy, src_win, dest_win, src_x, src_y, &dest_x, &dest_y, &child);
+
+ displayDispatchErrorHandlerEnable(0, env);
+
+ DBG_PRINT( "X11: getRelativeLocation0: %p %d/%d -> %p %d/%d - ok: %d\n",
+ (void*)src_win, src_x, src_y, (void*)dest_win, dest_x, dest_y, (int)res);
+
+ return (*env)->NewObject(env, pointClz, pointCstr, (jint)dest_x, (jint)dest_y);
+}
+