/* * 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; }
/* * Class: jogamp_nativewindow_x11_X11Lib * Method: DestroyWindow * Signature: (JJ)V */ 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; } 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); if( None != xwa.colormap ) { XFreeColormap(dpy, xwa.colormap); } // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, errorHandlerQuiet, 1); }
static int x11ErrorHandler(Display *dpy, XErrorEvent *e) { if(!errorHandlerQuiet) { const char * errnoStr = strerror(errno); char threadName[80]; char errCodeStr[80]; char reqCodeStr[80]; int shallBeDetached = 0; JNIEnv *jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached); (void) NativewindowCommon_GetStaticStringMethod(jniEnv, X11UtilClazz, getCurrentThreadNameID, threadName, sizeof(threadName), "n/a"); 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 (Thread: %s): %d - %s, dpy %p, id %x, # %d: %d:%d %s\n", threadName, e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial, (int)e->request_code, (int)e->minor_code, reqCodeStr); if( errorHandlerDebug ) { (*jniEnv)->CallStaticVoidMethod(jniEnv, X11UtilClazz, dumpStackID); } if(errorHandlerThrowException) { if(NULL != jniEnv) { NativewindowCommon_throwNewRuntimeException(jniEnv, "Nativewindow X11 Error (Thread: %s): %d - %s, dpy %p, id %x, # %d: %d:%d %s\n", threadName, e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial, (int)e->request_code, (int)e->minor_code, reqCodeStr); } else { fprintf(stderr, "Nativewindow X11 Error: null JNIEnv"); #if 0 if(NULL!=origErrorHandler) { origErrorHandler(dpy, e); } #endif } } fflush(stderr); if (NULL != jniEnv && shallBeDetached) { (*jvmHandle)->DetachCurrentThread(jvmHandle); } } return 0; }
/* * Class: jogamp_nativewindow_x11_X11Lib * Method: DestroyDummyWindow * Signature: (JJ)V */ JNIEXPORT void JNICALL Java_jogamp_nativewindow_x11_X11Lib_DestroyDummyWindow (JNIEnv *env, jclass unused, jlong display, jlong window) { Display * dpy = (Display *)(intptr_t)display; Window w = (Window) window; if(NULL==dpy) { NativewindowCommon_throwNewRuntimeException(env, "invalid display connection.."); return; } NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 1, 0, 0); XUnmapWindow(dpy, w); XSync(dpy, False); XDestroyWindow(dpy, w); NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); }
static int x11ErrorHandler(Display *dpy, XErrorEvent *e) { 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); if( NULL != jvmHandle && ( errorHandlerDebug || errorHandlerThrowException ) ) { jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, 0 /* asDaemon */, &shallBeDetached); if(NULL == jniEnv) { fprintf(stderr, "Nativewindow X11 Error: null JNIEnv"); fflush(stderr); } } 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); } if (shallBeDetached) { (*jvmHandle)->DetachCurrentThread(jvmHandle); } } } return 0; }
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; } 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; }
/* * Class: jogamp_nativewindow_x11_X11Lib * Method: CreateWindow * Signature: (JJIIIIZZ)J */ 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 root = RootWindow(dpy, scrn_idx); Window windowParent = (Window) parent; Window window = 0; XVisualInfo visualTemplate; XVisualInfo *pVisualQuery = NULL; Visual *visual = NULL; int depth; XSetWindowAttributes xswa; unsigned long attrMask; int n; Screen* scrn; if(NULL==dpy) { NativewindowCommon_FatalError(env, "invalid display connection.."); return 0; } if(visualID<0) { NativewindowCommon_throwNewRuntimeException(env, "invalid VisualID .."); return 0; } 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)); visualTemplate.screen = scrn_idx; visualTemplate.visualid = (VisualID)visualID; pVisualQuery = XGetVisualInfo(dpy, VisualIDMask|VisualScreenMask, &visualTemplate,&n); if(pVisualQuery!=NULL) { visual = pVisualQuery->visual; depth = pVisualQuery->depth; visualID = (jint)pVisualQuery->visualid; XFree(pVisualQuery); pVisualQuery=NULL; } DBG_PRINT( "X11: [CreateWindow] trying given (dpy %p, screen %d, visualID: %d, parent %p) found: %p\n", dpy, scrn_idx, (int)visualID, windowParent, visual); if (visual==NULL) { // NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, errorHandlerQuiet, 1); NativewindowCommon_throwNewRuntimeException(env, "could not query Visual by given VisualID, bail out!"); return 0; } if(pVisualQuery!=NULL) { XFree(pVisualQuery); pVisualQuery=NULL; } attrMask = ( CWBackingStore | CWBackingPlanes | CWBackingPixel | CWBackPixmap | CWBorderPixel | CWColormap | CWOverrideRedirect ) ; memset(&xswa, 0, sizeof(xswa)); xswa.override_redirect = False; // use the window manager, always xswa.border_pixel = 0; xswa.background_pixmap = None; xswa.backing_store=NotUseful; /* NotUseful, WhenMapped, Always */ xswa.backing_planes=0; /* planes to be preserved if possible */ xswa.backing_pixel=0; /* value to use in restoring planes */ 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, windowParent, visual, AllocNone); window = XCreateWindow(dpy, windowParent, 0, 0, // only a hint, WM most likely will override width, height, 0, // border width depth, InputOutput, visual, attrMask, &xswa); if(0==window) { NativewindowCommon_throwNewRuntimeException(env, "could not create Window, bail out!"); return 0; } NativewindowX11_setNormalWindowEWMH(dpy, window); NativewindowX11_setDecorations(dpy, window, False); if( visible ) { XEvent event; XMapWindow(dpy, window); } XSync(dpy, False); 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); return (jlong) window; }
/* * Class: jogamp_nativewindow_x11_X11Lib * Method: CreateDummyWindow * Signature: (JIIII)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) { Display * dpy = (Display *)(intptr_t)display; int scrn_idx = (int)screen_index; Window windowParent = 0; Window window = 0; XVisualInfo visualTemplate; XVisualInfo *pVisualQuery = NULL; Visual *visual = NULL; int depth; XSetWindowAttributes xswa; unsigned long attrMask; int n; Screen* scrn; if(NULL==dpy) { NativewindowCommon_FatalError(env, "invalid display connection.."); return 0; } if(visualID<0) { NativewindowCommon_throwNewRuntimeException(env, "invalid VisualID .."); return 0; } NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 1, 0, 0); scrn = ScreenOfDisplay(dpy, scrn_idx); // try given VisualID on screen memset(&visualTemplate, 0, sizeof(XVisualInfo)); visualTemplate.screen = scrn_idx; visualTemplate.visualid = (VisualID)visualID; pVisualQuery = XGetVisualInfo(dpy, VisualIDMask|VisualScreenMask, &visualTemplate,&n); if(pVisualQuery!=NULL) { visual = pVisualQuery->visual; depth = pVisualQuery->depth; visualID = (jint)pVisualQuery->visualid; XFree(pVisualQuery); pVisualQuery=NULL; } DBG_PRINT( "X11: [CreateWindow] trying given (dpy %p, screen %d, visualID: %d, parent %p) found: %p\n", dpy, scrn_idx, (int)visualID, windowParent, visual); if (visual==NULL) { NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); NativewindowCommon_throwNewRuntimeException(env, "could not query Visual by given VisualID, bail out!"); return 0; } if(pVisualQuery!=NULL) { XFree(pVisualQuery); pVisualQuery=NULL; } if(0==windowParent) { windowParent = XRootWindowOfScreen(scrn); } attrMask = ( CWBackingStore | CWBackingPlanes | CWBackingPixel | CWBackPixmap | CWBorderPixel | CWColormap | CWOverrideRedirect ) ; memset(&xswa, 0, sizeof(xswa)); xswa.override_redirect = False; // use the window manager, always xswa.border_pixel = 0; xswa.background_pixmap = None; xswa.backing_store=NotUseful; /* NotUseful, WhenMapped, Always */ xswa.backing_planes=0; /* planes to be preserved if possible */ xswa.backing_pixel=0; /* value to use in restoring planes */ xswa.colormap = XCreateColormap(dpy, XRootWindow(dpy, scrn_idx), visual, AllocNone); window = XCreateWindow(dpy, windowParent, 0, 0, width, height, 0, // border width depth, InputOutput, visual, attrMask, &xswa); XSync(dpy, False); XSelectInput(dpy, window, 0); // no events NativewindowCommon_x11ErrorHandlerEnable(env, dpy, 0, 0, 1); DBG_PRINT( "X11: [CreateWindow] created window %p on display %p\n", window, dpy); return (jlong) window; }