aboutsummaryrefslogtreecommitdiffstats
path: root/src/nativewindow/native/x11/Xmisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nativewindow/native/x11/Xmisc.c')
-rw-r--r--src/nativewindow/native/x11/Xmisc.c553
1 files changed, 353 insertions, 200 deletions
diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c
index 439d9b334..247dc1311 100644
--- a/src/nativewindow/native/x11/Xmisc.c
+++ b/src/nativewindow/native/x11/Xmisc.c
@@ -26,15 +26,27 @@
* or implied, of JogAmp Community.
*/
+#include "NativewindowCommon.h"
+#include "Xmisc.h"
+#include "jogamp_nativewindow_x11_X11Lib.h"
+#include "jogamp_nativewindow_x11_X11Util.h"
+
+#include <X11/Xatom.h>
+
+#include <X11/extensions/Xrender.h>
+
+/** Remove memcpy GLIBC > 2.4 dependencies */
+#include <glibc-compat-symbols.h>
+
+// #define VERBOSE_ON 1
+
+#ifdef VERBOSE_ON
+ #define DBG_PRINT(args...) fprintf(stderr, args);
+#else
+ #define DBG_PRINT(args...)
+#endif
+
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <errno.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
/* Linux headers don't work properly */
#define __USE_GNU
#include <dlfcn.h>
@@ -80,16 +92,7 @@ Bool XF86VidModeSetGammaRamp(
#define RTLD_DEFAULT NULL
#endif
-#include "NativewindowCommon.h"
-#include "jogamp_nativewindow_x11_X11Lib.h"
-
-// #define VERBOSE_ON 1
-
-#ifdef VERBOSE_ON
- #define DBG_PRINT(args...) fprintf(stderr, args);
-#else
- #define DBG_PRINT(args...)
-#endif
+#define X11_MOUSE_EVENT_MASK (ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask)
static const char * const ClazzNameBuffers = "com/jogamp/common/nio/Buffers";
static const char * const ClazzNameBuffersStaticCstrName = "copyByteBuffer";
@@ -98,6 +101,9 @@ static const char * const ClazzNameByteBuffer = "java/nio/ByteBuffer";
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 X11UtilClazz = NULL;
+static jmethodID getCurrentThreadNameID = NULL;
+static jmethodID dumpStackID = NULL;
static jclass clazzBuffers = NULL;
static jmethodID cstrBuffers = NULL;
static jclass clazzByteBuffer = NULL;
@@ -107,121 +113,123 @@ static jmethodID pointCstr = NULL;
static void _initClazzAccess(JNIEnv *env) {
jclass c;
- if(!NativewindowCommon_init(env)) return;
-
- c = (*env)->FindClass(env, ClazzNameBuffers);
- if(NULL==c) {
- NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't find %s", ClazzNameBuffers);
- }
- clazzBuffers = (jclass)(*env)->NewGlobalRef(env, c);
- (*env)->DeleteLocalRef(env, c);
- if(NULL==clazzBuffers) {
- NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't use %s", ClazzNameBuffers);
- }
- c = (*env)->FindClass(env, ClazzNameByteBuffer);
- if(NULL==c) {
- NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't find %s", ClazzNameByteBuffer);
- }
- clazzByteBuffer = (jclass)(*env)->NewGlobalRef(env, c);
- (*env)->DeleteLocalRef(env, c);
- if(NULL==c) {
- NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't use %s", ClazzNameByteBuffer);
- }
-
- cstrBuffers = (*env)->GetStaticMethodID(env, clazzBuffers,
- ClazzNameBuffersStaticCstrName, ClazzNameBuffersStaticCstrSignature);
- if(NULL==cstrBuffers) {
- NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't create %s.%s %s",
- ClazzNameBuffers, ClazzNameBuffersStaticCstrName, ClazzNameBuffersStaticCstrSignature);
- }
+ if( NativewindowCommon_init(env) ) {
+ getCurrentThreadNameID = (*env)->GetStaticMethodID(env, X11UtilClazz, "getCurrentThreadName", "()Ljava/lang/String;");
+ if(NULL==getCurrentThreadNameID) {
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't get method getCurrentThreadName");
+ }
+ dumpStackID = (*env)->GetStaticMethodID(env, X11UtilClazz, "dumpStack", "()V");
+ if(NULL==dumpStackID) {
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't get method dumpStack");
+ }
- c = (*env)->FindClass(env, ClazzNamePoint);
- if(NULL==c) {
- NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't find %s", ClazzNamePoint);
- }
- pointClz = (jclass)(*env)->NewGlobalRef(env, c);
- (*env)->DeleteLocalRef(env, c);
- if(NULL==pointClz) {
- NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't use %s", ClazzNamePoint);
- }
- pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature);
- if(NULL==pointCstr) {
- NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't fetch %s.%s %s",
- ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature);
- }
-}
+ c = (*env)->FindClass(env, ClazzNameBuffers);
+ if(NULL==c) {
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't find %s", ClazzNameBuffers);
+ }
+ clazzBuffers = (jclass)(*env)->NewGlobalRef(env, c);
+ (*env)->DeleteLocalRef(env, c);
+ if(NULL==clazzBuffers) {
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't use %s", ClazzNameBuffers);
+ }
+ c = (*env)->FindClass(env, ClazzNameByteBuffer);
+ if(NULL==c) {
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't find %s", ClazzNameByteBuffer);
+ }
+ clazzByteBuffer = (jclass)(*env)->NewGlobalRef(env, c);
+ (*env)->DeleteLocalRef(env, c);
+ if(NULL==c) {
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't use %s", ClazzNameByteBuffer);
+ }
-static JavaVM *jvmHandle = NULL;
-static int jvmVersion = 0;
+ cstrBuffers = (*env)->GetStaticMethodID(env, clazzBuffers,
+ ClazzNameBuffersStaticCstrName, ClazzNameBuffersStaticCstrSignature);
+ if(NULL==cstrBuffers) {
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't create %s.%s %s",
+ ClazzNameBuffers, ClazzNameBuffersStaticCstrName, ClazzNameBuffersStaticCstrSignature);
+ }
-static void setupJVMVars(JNIEnv * env) {
- if(0 != (*env)->GetJavaVM(env, &jvmHandle)) {
- jvmHandle = NULL;
+ c = (*env)->FindClass(env, ClazzNamePoint);
+ if(NULL==c) {
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't find %s", ClazzNamePoint);
+ }
+ pointClz = (jclass)(*env)->NewGlobalRef(env, c);
+ (*env)->DeleteLocalRef(env, c);
+ if(NULL==pointClz) {
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't use %s", ClazzNamePoint);
+ }
+ pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature);
+ if(NULL==pointCstr) {
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't fetch %s.%s %s",
+ ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature);
+ }
}
- jvmVersion = (*env)->GetVersion(env);
}
static XErrorHandler origErrorHandler = NULL ;
-static int errorHandlerBlocked = 0 ;
-static int errorHandlerQuiet = 0 ;
+static int errorHandlerQuiet = 1 ;
+static int errorHandlerDebug = 0 ;
+static int errorHandlerThrowException = 0;
static int x11ErrorHandler(Display *dpy, XErrorEvent *e)
{
- if(!errorHandlerQuiet) {
- JNIEnv *curEnv = NULL;
- JNIEnv *newEnv = NULL;
- int envRes ;
- const char * errStr = strerror(errno);
-
- fprintf(stderr, "Info: Nativewindow X11 Error: Display %p, Code 0x%X, errno %s\n", dpy, e->error_code, errStr);
+ if( !errorHandlerQuiet || errorHandlerDebug ) {
+ const char * errnoStr = strerror(errno);
+ char errCodeStr[80];
+ char reqCodeStr[80];
+ int shallBeDetached = 0;
+ JNIEnv *jniEnv = NULL;
+
+ snprintf(errCodeStr, sizeof(errCodeStr), "%d", e->request_code);
+ XGetErrorDatabaseText(dpy, "XRequest", errCodeStr, "Unknown", reqCodeStr, sizeof(reqCodeStr));
+ XGetErrorText(dpy, e->error_code, errCodeStr, sizeof(errCodeStr));
+
+ fprintf(stderr, "Info: Nativewindow X11 Error: %d - %s, dpy %p, id %x, # %d: %d:%d %s\n",
+ e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
+ (int)e->request_code, (int)e->minor_code, reqCodeStr);
fflush(stderr);
- // retrieve this thread's JNIEnv curEnv - or detect it's detached
- envRes = (*jvmHandle)->GetEnv(jvmHandle, (void **) &curEnv, jvmVersion) ;
- if( JNI_EDETACHED == envRes ) {
- // detached thread - attach to JVM
- if( JNI_OK != ( envRes = (*jvmHandle)->AttachCurrentThread(jvmHandle, (void**) &newEnv, NULL) ) ) {
- fprintf(stderr, "Nativewindow X11 Error: can't attach thread: %d\n", envRes);
- return 0;
+ if( errorHandlerDebug || errorHandlerThrowException ) {
+ jniEnv = NativewindowCommon_GetJNIEnv(0 /* asDaemon */, &shallBeDetached);
+ if(NULL == jniEnv) {
+ fprintf(stderr, "Nativewindow X11 Error: null JNIEnv");
+ fflush(stderr);
}
- curEnv = newEnv;
- } else if( JNI_OK != envRes ) {
- // oops ..
- fprintf(stderr, "Nativewindow X11 Error: can't GetEnv: %d\n", envRes);
- return 0;
}
- NativewindowCommon_throwNewRuntimeException(curEnv, "Info: Nativewindow X11 Error: Display %p, Code 0x%X, errno %s",
- dpy, e->error_code, errStr);
- if( NULL != newEnv ) {
- // detached attached thread
- (*jvmHandle)->DetachCurrentThread(jvmHandle);
+ if( NULL != jniEnv ) {
+ if( errorHandlerDebug ) {
+ (*jniEnv)->CallStaticVoidMethod(jniEnv, X11UtilClazz, dumpStackID);
+ }
+
+ if(errorHandlerThrowException) {
+ NativewindowCommon_throwNewRuntimeException(jniEnv, "Nativewindow X11 Error: %d - %s, dpy %p, id %x, # %d: %d:%d %s\n",
+ e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial,
+ (int)e->request_code, (int)e->minor_code, reqCodeStr);
+ }
+ NativewindowCommon_ReleaseJNIEnv(shallBeDetached);
}
}
-#if 0
- if(NULL!=origErrorHandler) {
- origErrorHandler(dpy, e);
- }
-#endif
-
return 0;
}
-static void x11ErrorHandlerEnable(Display *dpy, int onoff, JNIEnv * env) {
- if(errorHandlerBlocked) return;
-
+static void NativewindowCommon_x11ErrorHandlerEnable(JNIEnv * env, Display *dpy, int force, int onoff, int quiet, int sync) {
+ errorHandlerQuiet = quiet;
if(onoff) {
- if(NULL==origErrorHandler) {
- setupJVMVars(env);
- if(NULL!=dpy) {
+ if(force || NULL==origErrorHandler) {
+ XErrorHandler prevErrorHandler;
+ prevErrorHandler = XSetErrorHandler(x11ErrorHandler);
+ if(x11ErrorHandler != prevErrorHandler) { // if forced don't overwrite w/ orig w/ our handler
+ origErrorHandler = prevErrorHandler;
+ }
+ if(sync && NULL!=dpy) {
XSync(dpy, False);
}
- origErrorHandler = XSetErrorHandler(x11ErrorHandler);
}
} else {
if(NULL!=origErrorHandler) {
- if(NULL!=dpy) {
+ if(sync && NULL!=dpy) {
XSync(dpy, False);
}
XSetErrorHandler(origErrorHandler);
@@ -230,46 +238,22 @@ static void x11ErrorHandlerEnable(Display *dpy, int onoff, JNIEnv * env) {
}
}
-static void x11ErrorHandlerEnableBlocking(JNIEnv * env, int onoff, int quiet) {
- errorHandlerBlocked = 0 ;
- x11ErrorHandlerEnable(NULL, onoff, env);
- errorHandlerBlocked = onoff ;
- errorHandlerQuiet = quiet;
-}
-
-
static XIOErrorHandler origIOErrorHandler = NULL;
static int x11IOErrorHandler(Display *dpy)
{
- JNIEnv *curEnv = NULL;
- JNIEnv *newEnv = NULL;
- int envRes ;
const char * dpyName = XDisplayName(NULL);
- const char * errStr = strerror(errno);
-
- fprintf(stderr, "Nativewindow X11 IOError: Display %p (%s): %s\n", dpy, dpyName, errStr);
-
- // retrieve this thread's JNIEnv curEnv - or detect it's detached
- envRes = (*jvmHandle)->GetEnv(jvmHandle, (void **) &curEnv, jvmVersion) ;
- if( JNI_EDETACHED == envRes ) {
- // detached thread - attach to JVM
- if( JNI_OK != ( envRes = (*jvmHandle)->AttachCurrentThread(jvmHandle, (void**) &newEnv, NULL) ) ) {
- fprintf(stderr, "Nativewindow X11 IOError: can't attach thread: %d\n", envRes);
- return;
- }
- curEnv = newEnv;
- } else if( JNI_OK != envRes ) {
- // oops ..
- fprintf(stderr, "Nativewindow X11 IOError: can't GetEnv: %d\n", envRes);
- return;
- }
+ const char * errnoStr = strerror(errno);
+ int shallBeDetached = 0;
+ JNIEnv *jniEnv = NULL;
- NativewindowCommon_FatalError(curEnv, "Nativewindow X11 IOError: Display %p (%s): %s", dpy, dpyName, errStr);
+ fprintf(stderr, "Nativewindow X11 IOError: Display %p (%s): %s\n", dpy, dpyName, errnoStr);
+ fflush(stderr);
- if( NULL != newEnv ) {
- // detached attached thread
- (*jvmHandle)->DetachCurrentThread(jvmHandle);
+ jniEnv = NativewindowCommon_GetJNIEnv(0 /* asDaemon */, &shallBeDetached);
+ if (NULL != jniEnv) {
+ NativewindowCommon_FatalError(jniEnv, "Nativewindow X11 IOError: Display %p (%s): %s", dpy, dpyName, errnoStr);
+ NativewindowCommon_ReleaseJNIEnv(shallBeDetached);
}
if(NULL!=origIOErrorHandler) {
origIOErrorHandler(dpy);
@@ -280,7 +264,6 @@ static int x11IOErrorHandler(Display *dpy)
static void x11IOErrorHandlerEnable(int onoff, JNIEnv * env) {
if(onoff) {
if(NULL==origIOErrorHandler) {
- setupJVMVars(env);
origIOErrorHandler = XSetIOErrorHandler(x11IOErrorHandler);
}
} else {
@@ -289,38 +272,49 @@ static void x11IOErrorHandlerEnable(int onoff, JNIEnv * env) {
}
}
-static int _initialized=0;
-static jboolean _xinitThreadsOK=JNI_FALSE;
+static int _initialized = 0;
JNIEXPORT jboolean JNICALL
-Java_jogamp_nativewindow_x11_X11Util_initialize0(JNIEnv *env, jclass _unused, jboolean firstUIActionOnProcess) {
- if(0==_initialized) {
- if( JNI_TRUE == firstUIActionOnProcess ) {
- if( 0 == XInitThreads() ) {
- fprintf(stderr, "Warning: XInitThreads() failed\n");
- } else {
- _xinitThreadsOK=JNI_TRUE;
- DBG_PRINT( "X11: XInitThreads() called for concurrent Thread support\n");
- }
- } else {
- DBG_PRINT( "X11: XInitThreads() _not_ called for concurrent Thread support\n");
+Java_jogamp_nativewindow_x11_X11Util_initialize0(JNIEnv *env, jclass clazz, jboolean debug) {
+ if( 0 == _initialized ) {
+ if(debug) {
+ errorHandlerDebug = 1;
}
+ X11UtilClazz = (jclass)(*env)->NewGlobalRef(env, clazz);
_initClazzAccess(env);
x11IOErrorHandlerEnable(1, env);
+ NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 1, 1, debug ? 0 : 1, 0 /* no dpy, force, no sync */);
_initialized=1;
+ if(JNI_TRUE == debug) {
+ fprintf(stderr, "Info: NativeWindow native init passed\n");
+ }
}
- return _xinitThreadsOK;
+ return JNI_TRUE;
}
JNIEXPORT void JNICALL
Java_jogamp_nativewindow_x11_X11Util_shutdown0(JNIEnv *env, jclass _unused) {
+ NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 0, 0, errorHandlerQuiet, 0 /* no dpy, no sync */);
x11IOErrorHandlerEnable(0, env);
}
JNIEXPORT void JNICALL
Java_jogamp_nativewindow_x11_X11Util_setX11ErrorHandler0(JNIEnv *env, jclass _unused, jboolean onoff, jboolean quiet) {
- x11ErrorHandlerEnableBlocking(env, ( JNI_TRUE == onoff ) ? 1 : 0, ( JNI_TRUE == quiet ) ? 1 : 0);
+ NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 1, onoff ? 1 : 0, quiet ? 1 : 0, 0 /* no dpy, force, no sync */);
+}
+
+/* Java->C glue code:
+ * Java package: jogamp.nativewindow.x11.X11Lib
+ * Java method: boolean XRenderFindVisualFormat(long dpy, long visual, XRenderPictFormat dest)
+ */
+JNIEXPORT jboolean JNICALL
+Java_jogamp_nativewindow_x11_X11Lib_XRenderFindVisualFormat1(JNIEnv *env, jclass _unused, jlong dpy, jlong visual, jobject xRenderPictFormat) {
+ XRenderPictFormat * dest = (XRenderPictFormat *) (*env)->GetDirectBufferAddress(env, xRenderPictFormat);
+ XRenderPictFormat * src = XRenderFindVisualFormat((Display *) (intptr_t) dpy, (Visual *) (intptr_t) visual);
+ if (NULL == src) return JNI_FALSE;
+ memcpy(dest, src, sizeof(XRenderPictFormat));
+ return JNI_TRUE;
}
/* Java->C glue code:
@@ -332,45 +326,71 @@ JNIEXPORT jobject JNICALL
Java_jogamp_nativewindow_x11_X11Lib_XGetVisualInfo1__JJLjava_nio_ByteBuffer_2Ljava_lang_Object_2I(JNIEnv *env, jclass _unused, jlong arg0, jlong arg1, jobject arg2, jobject arg3, jint arg3_byte_offset) {
XVisualInfo * _ptr2 = NULL;
int * _ptr3 = NULL;
- XVisualInfo * _res;
- int count;
- jobject jbyteSource;
- jobject jbyteCopy;
- if(0==arg0) {
- NativewindowCommon_FatalError(env, "invalid display connection..");
- }
- if (arg2 != NULL) {
- _ptr2 = (XVisualInfo *) (((char*) (*env)->GetDirectBufferAddress(env, arg2)) + 0);
- }
- if (arg3 != NULL) {
- _ptr3 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, arg3, NULL)) + arg3_byte_offset);
+ XVisualInfo * _res = NULL;
+ int count = 0;
+ jobject jbyteSource = NULL;
+ jobject jbyteCopy = NULL;
+ if( 0 == arg0 || 0 == arg2 || 0 == arg3 ) {
+ NativewindowCommon_FatalError(env, "invalid display connection, vinfo_template or nitems_return");
+ return NULL;
}
- x11ErrorHandlerEnable((Display *) (intptr_t) arg0, 1, env);
- _res = XGetVisualInfo((Display *) (intptr_t) arg0, (long) arg1, (XVisualInfo *) _ptr2, (int *) _ptr3);
- x11ErrorHandlerEnable((Display *) (intptr_t) arg0, 0, env);
- count = _ptr3[0];
- if (arg3 != NULL) {
- (*env)->ReleasePrimitiveArrayCritical(env, arg3, _ptr3, 0);
+ _ptr2 = (XVisualInfo *) (((char*) (*env)->GetDirectBufferAddress(env, arg2)) + 0);
+ if( NULL != _ptr2 ) {
+ _ptr3 = (int *) (((char*) (*env)->GetPrimitiveArrayCritical(env, arg3, NULL)) + arg3_byte_offset);
+ if( NULL != _ptr3 ) {
+ NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 0, 1, errorHandlerQuiet, 0);
+ _res = XGetVisualInfo((Display *) (intptr_t) arg0, (long) arg1, (XVisualInfo *) _ptr2, (int *) _ptr3);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) arg0, 0, 0, errorHandlerQuiet, 0);
+ count = _ptr3[0];
+ (*env)->ReleasePrimitiveArrayCritical(env, arg3, _ptr3, 0);
+ }
}
if (_res == NULL) return NULL;
jbyteSource = (*env)->NewDirectByteBuffer(env, _res, count * sizeof(XVisualInfo));
jbyteCopy = (*env)->CallStaticObjectMethod(env, clazzBuffers, cstrBuffers, jbyteSource);
+ (*env)->DeleteLocalRef(env, jbyteSource);
XFree(_res);
return jbyteCopy;
}
-JNIEXPORT jlong JNICALL
+JNIEXPORT jint JNICALL
+Java_jogamp_nativewindow_x11_X11Lib_GetVisualIDFromWindow(JNIEnv *env, jclass _unused, jlong display, jlong window) {
+ Display * dpy = (Display *)(intptr_t)display;
+ Window w = (Window) window;
+ XWindowAttributes xwa;
+ jlong r = 0; // undefinded
+
+ if(NULL==dpy) {
+ NativewindowCommon_throwNewRuntimeException(env, "invalid display connection..");
+ return 0;
+ }
+
+ NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 1, errorHandlerQuiet, 1);
+ memset(&xwa, 0, sizeof(XWindowAttributes));
+ XGetWindowAttributes(dpy, w, &xwa);
+ if(NULL != xwa.visual) {
+ r = (jint) XVisualIDFromVisual( xwa.visual );
+ } else {
+ r = 0;
+ }
+ // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, errorHandlerQuiet, 1);
+
+ return r;
+}
+
+
+JNIEXPORT jint JNICALL
Java_jogamp_nativewindow_x11_X11Lib_DefaultVisualID(JNIEnv *env, jclass _unused, jlong display, jint screen) {
jlong r;
if(0==display) {
NativewindowCommon_FatalError(env, "invalid display connection..");
}
- x11ErrorHandlerEnable((Display *) (intptr_t) display, 1, env);
- r = (jlong) XVisualIDFromVisual( DefaultVisual( (Display*) (intptr_t) display, screen ) );
- x11ErrorHandlerEnable((Display *) (intptr_t) display, 0, env);
+ NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) display, 0, 1, errorHandlerQuiet, 0);
+ r = (jint) XVisualIDFromVisual( DefaultVisual( (Display*) (intptr_t) display, screen ) );
+ // NativewindowCommon_x11ErrorHandlerEnable(env, (Display *) (intptr_t) display, 0, 0, errorHandlerQuiet, 0);
return r;
}
@@ -411,23 +431,68 @@ Java_jogamp_nativewindow_x11_X11Lib_XCloseDisplay__J(JNIEnv *env, jclass _unused
if(0==display) {
NativewindowCommon_FatalError(env, "invalid display connection..");
}
- x11ErrorHandlerEnable((Display *) (intptr_t) display, 1, env);
+ NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 0, 1, errorHandlerQuiet, 0);
_res = XCloseDisplay((Display *) (intptr_t) display);
- x11ErrorHandlerEnable(NULL, 0, env);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, NULL, 0, 0, errorHandlerQuiet, 0);
return _res;
}
+static void NativewindowX11_setNormalWindowEWMH (Display *dpy, Window w) {
+ Atom _NET_WM_WINDOW_TYPE = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE", False );
+ Atom types[1]={0};
+ types[0] = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE_NORMAL", False );
+ XChangeProperty( dpy, w, _NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&types, 1);
+ XSync(dpy, False);
+}
+
+#define DECOR_USE_MWM 1 // works for known WMs
+// #define DECOR_USE_EWMH 1 // haven't seen this to work (NORMAL->POPUP, never gets undecorated)
+
+/* see <http://tonyobryan.com/index.php?article=9> */
+#define MWM_HINTS_DECORATIONS (1L << 1)
+#define PROP_MWM_HINTS_ELEMENTS 5
+
+static void NativewindowX11_setDecorations (Display *dpy, Window w, Bool decorated) {
+
+#ifdef DECOR_USE_MWM
+ unsigned long mwmhints[PROP_MWM_HINTS_ELEMENTS] = { MWM_HINTS_DECORATIONS, 0, decorated, 0, 0 }; // flags, functions, decorations, input_mode, status
+ Atom _MOTIF_WM_HINTS = XInternAtom( dpy, "_MOTIF_WM_HINTS", False );
+#endif
+
+#ifdef DECOR_USE_EWMH
+ Atom _NET_WM_WINDOW_TYPE = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE", False );
+ Atom types[3]={0};
+ int ntypes=0;
+ if(True==decorated) {
+ types[ntypes++] = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE_NORMAL", False );
+ } else {
+ types[ntypes++] = XInternAtom( dpy, "_NET_WM_WINDOW_TYPE_POPUP_MENU", False );
+ }
+#endif
+
+#ifdef DECOR_USE_MWM
+ XChangeProperty( dpy, w, _MOTIF_WM_HINTS, _MOTIF_WM_HINTS, 32, PropModeReplace, (unsigned char *)&mwmhints, PROP_MWM_HINTS_ELEMENTS);
+#endif
+
+#ifdef DECOR_USE_EWMH
+ XChangeProperty( dpy, w, _NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&types, ntypes);
+#endif
+
+ XSync(dpy, False);
+}
+
/*
* Class: jogamp_nativewindow_x11_X11Lib
- * Method: CreateDummyWindow
- * Signature: (JIIII)J
+ * Method: CreateWindow
+ * Signature: (JJIIIIZZ)J
*/
-JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
- (JNIEnv *env, jclass unused, jlong display, jint screen_index, jint visualID, jint width, jint height)
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateWindow
+ (JNIEnv *env, jclass unused, jlong parent, jlong display, jint screen_index, jint visualID, jint width, jint height, jboolean input, jboolean visible)
{
Display * dpy = (Display *)(intptr_t)display;
int scrn_idx = (int)screen_index;
- Window windowParent = 0;
+ Window root = RootWindow(dpy, scrn_idx);
+ Window windowParent = (Window) parent;
Window window = 0;
XVisualInfo visualTemplate;
@@ -451,9 +516,12 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
return 0;
}
- x11ErrorHandlerEnable(dpy, 1, env);
+ NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 1, errorHandlerQuiet, 0);
scrn = ScreenOfDisplay(dpy, scrn_idx);
+ if(0==windowParent) {
+ windowParent = root;
+ }
// try given VisualID on screen
memset(&visualTemplate, 0, sizeof(XVisualInfo));
@@ -471,7 +539,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
if (visual==NULL)
{
- x11ErrorHandlerEnable(dpy, 0, env);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, errorHandlerQuiet, 1);
NativewindowCommon_throwNewRuntimeException(env, "could not query Visual by given VisualID, bail out!");
return 0;
}
@@ -481,9 +549,6 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
pVisualQuery=NULL;
}
- if(0==windowParent) {
- windowParent = XRootWindowOfScreen(scrn);
- }
attrMask = ( CWBackingStore | CWBackingPlanes | CWBackingPixel | CWBackPixmap |
CWBorderPixel | CWColormap | CWOverrideRedirect ) ;
@@ -495,15 +560,22 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
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 */
+ if( input ) {
+ xswa.event_mask = X11_MOUSE_EVENT_MASK;
+ xswa.event_mask |= KeyPressMask | KeyReleaseMask ;
+ }
+ if( visible ) {
+ xswa.event_mask |= FocusChangeMask | SubstructureNotifyMask | StructureNotifyMask | ExposureMask ;
+ }
xswa.colormap = XCreateColormap(dpy,
- XRootWindow(dpy, scrn_idx),
+ windowParent,
visual,
AllocNone);
window = XCreateWindow(dpy,
windowParent,
- 0, 0,
+ 0, 0, // only a hint, WM most likely will override
width, height,
0, // border width
depth,
@@ -511,13 +583,27 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
visual,
attrMask,
&xswa);
+ if(0==window) {
+ NativewindowCommon_throwNewRuntimeException(env, "could not create Window, bail out!");
+ return 0;
+ }
- XSync(dpy, False);
+ NativewindowX11_setNormalWindowEWMH(dpy, window);
+ NativewindowX11_setDecorations(dpy, window, False);
+
+ if( visible ) {
+ XEvent event;
+
+ XMapWindow(dpy, window);
+ }
- XSelectInput(dpy, window, 0); // no events
XSync(dpy, False);
- x11ErrorHandlerEnable(dpy, 0, env);
+ if( !input ) {
+ XSelectInput(dpy, window, 0); // no events
+ }
+
+ // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, errorHandlerQuiet, 1);
DBG_PRINT( "X11: [CreateWindow] created window %p on display %p\n", window, dpy);
@@ -527,25 +613,57 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_x11_X11Lib_CreateDummyWindow
/*
* Class: jogamp_nativewindow_x11_X11Lib
- * Method: DestroyDummyWindow
+ * Method: DestroyWindow
* Signature: (JJ)V
*/
-JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_DestroyDummyWindow
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_DestroyWindow
(JNIEnv *env, jclass unused, jlong display, jlong window)
{
Display * dpy = (Display *)(intptr_t)display;
Window w = (Window) window;
+ XWindowAttributes xwa;
if(NULL==dpy) {
NativewindowCommon_throwNewRuntimeException(env, "invalid display connection..");
return;
}
- x11ErrorHandlerEnable(dpy, 1, env);
+ NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 1, errorHandlerQuiet, 0);
+ XSync(dpy, False);
+ memset(&xwa, 0, sizeof(XWindowAttributes));
+ XGetWindowAttributes(dpy, w, &xwa); // prefetch colormap to be destroyed after window destruction
+ XSelectInput(dpy, w, 0);
XUnmapWindow(dpy, w);
XSync(dpy, False);
XDestroyWindow(dpy, w);
- x11ErrorHandlerEnable(dpy, 0, env);
+ if( None != xwa.colormap ) {
+ XFreeColormap(dpy, xwa.colormap);
+ }
+ // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, errorHandlerQuiet, 1);
+}
+
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_SetWindowPosSize
+ (JNIEnv *env, jclass unused, jlong display, jlong window, jint x, jint y, jint width, jint height) {
+ Display * dpy = (Display *)(intptr_t)display;
+ Window w = (Window) window;
+ XWindowChanges xwc;
+ int flags = 0;
+
+ memset(&xwc, 0, sizeof(XWindowChanges));
+
+ if(0<=x && 0<=y) {
+ flags |= CWX | CWY;
+ xwc.x=x;
+ xwc.y=y;
+ }
+
+ if(0<width && 0<height) {
+ flags |= CWWidth | CWHeight;
+ xwc.width=width;
+ xwc.height=height;
+ }
+ XConfigureWindow(dpy, w, flags, &xwc);
+ XSync(dpy, False);
}
/*
@@ -569,11 +687,11 @@ JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_x11_X11Lib_GetRelativeLocatio
if( 0 == jdest_win ) { dest_win = root; }
if( 0 == jsrc_win ) { src_win = root; }
- x11ErrorHandlerEnable(dpy, 1, env);
+ NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 1, errorHandlerQuiet, 0);
res = XTranslateCoordinates(dpy, src_win, dest_win, src_x, src_y, &dest_x, &dest_y, &child);
- x11ErrorHandlerEnable(dpy, 0, env);
+ // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, errorHandlerQuiet, 0);
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);
@@ -581,3 +699,38 @@ JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_x11_X11Lib_GetRelativeLocatio
return (*env)->NewObject(env, pointClz, pointCstr, (jint)dest_x, (jint)dest_y);
}
+/*
+ * Class: jogamp_nativewindow_x11_X11Lib
+ * Method: QueryExtension0
+ * Signature: (JLjava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_x11_X11Lib_QueryExtension0
+ (JNIEnv *env, jclass unused, jlong jdisplay, jstring jextensionName)
+{
+ int32_t major_opcode, first_event, first_error;
+ jboolean res = JNI_FALSE;
+ Display * display = (Display *) (intptr_t) jdisplay;
+ const char* extensionName = NULL;
+
+ if(NULL==display) {
+ NativewindowCommon_throwNewRuntimeException(env, "NULL argument \"display\"");
+ return res;
+ }
+ if ( NULL == jextensionName ) {
+ NativewindowCommon_throwNewRuntimeException(env, "NULL argument \"extensionName\"");
+ return res;
+ }
+ extensionName = (*env)->GetStringUTFChars(env, jextensionName, (jboolean*)NULL);
+ if ( NULL == extensionName ) {
+ NativewindowCommon_throwNewRuntimeException(env, "Failed to get UTF-8 chars for argument \"extensionName\"");
+ return res;
+ }
+
+ res = True == XQueryExtension(display, extensionName, &major_opcode, &first_event, &first_error) ? JNI_TRUE : JNI_FALSE;
+
+ if ( NULL != jextensionName ) {
+ (*env)->ReleaseStringUTFChars(env, jextensionName, extensionName);
+ }
+ return res;
+}
+