Пример #1
0
int TestSetClip(JNIEnv *env, D3DContext *d3dContext,
                DDrawSurface *lpPlainSurface)
{
    int testRes = J2D_D3D_FAILURE;

    if (SUCCEEDED(d3dContext->SetRenderTarget(lpPlainSurface))) {
        jobject clip =
            JNU_CallStaticMethodByName(env, NULL,
                                       "sun/java2d/pipe/Region",
                                       "getInstanceXYWH",
                                       "(IIII)Lsun/java2d/pipe/Region;",
                                       0, 0, D3D_TEST_RASTER_W, D3D_TEST_RASTER_H).l;
        if (!JNU_IsNull(env, clip)) {
            if (SUCCEEDED(d3dContext->SetClip(env, clip, JNI_TRUE,
                                              0, 0,
                                              D3D_TEST_RASTER_W,
                                              D3D_TEST_RASTER_H)))
            {
                testRes |= J2D_D3D_DEPTH_SURFACE_OK;
            }
            env->DeleteLocalRef(clip);
        }
    }
    return testRes;
}
Пример #2
0
// static
void D3DPipelineManager::NotifyAdapterEventListeners(UINT adapter,
                                                     jint eventType)
{
    HMONITOR hMon;
    int gdiScreen;
    D3DPipelineManager *pMgr;

    // fix for 6946559: if d3d preloading fails jmv may be NULL
    if (jvm == NULL) {
        return;
    }

    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    RETURN_IF_NULL(env);

    pMgr = D3DPipelineManager::GetInstance();
    RETURN_IF_NULL(pMgr);
    hMon = pMgr->pd3d9->GetAdapterMonitor(adapter);

    /*
     * If we don't have devices initialized yet, no sense to clear them.
     */
    if (!Devices::GetInstance()){
         return;
    }

    gdiScreen = AwtWin32GraphicsDevice::GetScreenFromHMONITOR(hMon);

    JNU_CallStaticMethodByName(env, NULL,
        "sun/java2d/pipe/hw/AccelDeviceEventNotifier",
        "eventOccured", "(II)V",
        gdiScreen, eventType);
}
JNIEXPORT jobject JNICALL
    awt_GetComponent(JNIEnv* env, void* platformInfo)
{
    Window window = (Window)platformInfo;
    jobject peer = NULL;
    jobject target = NULL;

    AWT_LOCK();

    if (window != None) {
        peer = JNU_CallStaticMethodByName(env, NULL, "sun/awt/X11/XToolkit",
            "windowToXWindow", "(J)Lsun/awt/X11/XBaseWindow;", (jlong)window).l;
    }
    if ((peer != NULL) &&
        (JNU_IsInstanceOfByName(env, peer, "sun/awt/X11/XWindow") == 1)) {
        target = (*env)->GetObjectField(env, peer, targetID);
    }

    if (target == NULL) {
        JNU_ThrowNullPointerException(env, "NullPointerException");
        AWT_UNLOCK();
        return (jobject)NULL;
    }

    AWT_UNLOCK();

    return target;
}
Пример #4
0
BOOL WINAPI Monitor_XXXPort(char* procname,LPWSTR servername,HWND hWnd,LPWSTR name){
  if(name==NULL){return false;}

  JNIEnv* env=NULL;
  jvm->AttachCurrentThread((void**)&env,NULL);
  if(env->ExceptionCheck()){env->ExceptionClear();}
  jboolean   res         = false;
  jstring    jname       = NULL;
  jstring    jservername = NULL;
  jclass     clazz = env->FindClass(jprintmonitor);
  if(clazz==NULL){goto cleanup;}
  if(servername!=NULL){
    jservername=env->NewString((jchar*)servername,(jsize)wcslen(servername));
    if(jservername==NULL){goto cleanup;}
  }
  jname=env->NewString((jchar*)name,(jsize)wcslen(name));
  if(jname==NULL){goto cleanup;}
  res=JNU_CallStaticMethodByName(env,NULL,clazz,procname,"(Ljava/lang/String;ILjava/lang/String;)Z",jservername,hWnd,jname).z;
cleanup:
  if(env->ExceptionCheck()){env->ExceptionClear();}
  if(clazz!=NULL){env->DeleteLocalRef(clazz);}
  if((jservername!=NULL)&&(servername!=NULL)){env->ReleaseStringChars(jservername,(jchar*)servername);}
  if(jname!=NULL){env->ReleaseStringChars(jname,(jchar*)name);}
  return res;
}
Пример #5
0
BOOL WINAPI Monitor_OpenPort(LPWSTR portname,PHANDLE porthandle){
	(*porthandle)=NULL;

//  Util_showMessage(L"Open Port: portname = %s",portname);

  if(portname==NULL){return false;}

  jstring jportname = NULL;
  jobject port      = NULL;

  JNIEnv* env=NULL;
  jvm->AttachCurrentThread((void**)&env,NULL);
  if(env->ExceptionCheck()){env->ExceptionClear();}
  jclass clazz = env->FindClass(jprintmonitor);
  if(clazz==NULL){goto cleanup;}
  jportname=env->NewString((jchar*)portname,(jsize)wcslen(portname));
  if(jportname==NULL){goto cleanup;}
  port=JNU_CallStaticMethodByName(env,NULL,clazz,"openPort","(Ljava/lang/String;)Luk/co/mmscomputing/device/printmonitor/Port;",jportname).l;
  port=env->NewGlobalRef(port);                                       // need global reference
cleanup:
  if(env->ExceptionCheck()){env->ExceptionClear();}
  env->DeleteLocalRef(clazz);
  if(jportname!=NULL){env->ReleaseStringChars(jportname,(jchar*)portname);}
	(*porthandle)=(HANDLE)port;                                         // need this handle for startdoc,write,read
  return port!=NULL;
}
Пример #6
0
void
D3DSD_Dispose(JNIEnv *env, SurfaceDataOps *ops)
{
    D3DSDOps *d3dsdo = (D3DSDOps *)ops;
    RETURN_IF_NULL(d3dsdo);

    JNU_CallStaticMethodByName(env, NULL, "sun/java2d/d3d/D3DSurfaceData",
                               "dispose", "(J)V",
                               ptr_to_jlong(ops));
}
Пример #7
0
/**
 * This is the implementation of the general DisposeFunc defined in
 * SurfaceData.h and used by the Disposer mechanism.  It first flushes all
 * native OpenGL resources and then frees any memory allocated within the
 * native OGLSDOps structure.
 */
void
OGLSD_Dispose(JNIEnv *env, SurfaceDataOps *ops)
{
    OGLSDOps *oglsdo = (OGLSDOps *)ops;
    jlong pConfigInfo = OGLSD_GetNativeConfigInfo(oglsdo);

    JNU_CallStaticMethodByName(env, NULL, "sun/java2d/opengl/OGLSurfaceData",
                               "dispose", "(JJ)V",
                               ptr_to_jlong(ops), pConfigInfo);
}
Пример #8
0
BOOL WINAPI Monitor_EnumPorts(LPWSTR servername,DWORD dwLevel,LPBYTE pPorts,DWORD cbBuf,LPDWORD pdwNeeded,LPDWORD numberOfPorts){
  (*numberOfPorts)=0;                                            // seems that we need to set this even if cbBuf < (*pdwNeeded)

  if((dwLevel!=1)&&(dwLevel!=2)){                                // support only level 1 and 2
    Util_showMessage(L"Enum Port: Level = %d",dwLevel);
    SetLastError(ERROR_INVALID_LEVEL);return false;
  }

  JNIEnv* env      = NULL;                                       // get java environment
  jvm->AttachCurrentThread((void**)&env,NULL);
  if(env->ExceptionCheck()){env->ExceptionClear();}

  bool       res   = false;                         
  jclass     clazz = env->FindClass(jprintmonitor);              // get jprintmonitor class
  jbyteArray jbuf  = NULL;
  if(clazz==NULL){goto cleanup;}

  (*pdwNeeded)=JNU_CallStaticMethodByName(env,NULL,clazz,"getPortInfoSize","(I)I",dwLevel).i;
  if(env->ExceptionCheck()){goto cleanup;}                   

  if(((*pdwNeeded)<=cbBuf)&&(pPorts!=NULL)){                     // if spooler offers enough buffer space
    jbuf  = env->NewByteArray(cbBuf);                            // get java byte buffer
    if(jbuf==NULL){goto cleanup;}                                // OutOfMemoryError
                                                                 // call java enum ports; prepare Port_Info buffer  
                                                                 // tell spooler how many ports we have
    (*numberOfPorts)=JNU_CallStaticMethodByName(env,NULL,clazz,"enumPorts","(Ljava/lang/String;II[B)I",NULL,dwLevel,pPorts,jbuf).i;
    if(env->ExceptionCheck()){goto cleanup;}
    env->GetByteArrayRegion(jbuf,0,cbBuf,(jbyte*)pPorts);        // copy java array to c array
    if(env->ExceptionCheck()){goto cleanup;}                     // ArrayIndexOutOfBoundsException
    res=true;
  }else{
    SetLastError(ERROR_INSUFFICIENT_BUFFER);
  }
cleanup:
  if(env->ExceptionCheck()){env->ExceptionClear();}
  env->DeleteLocalRef(jbuf);
  env->DeleteLocalRef(clazz);
  return res;
}
/*
 * Returns True if display is local, False of it's remote.
 */
jboolean isDisplayLocal(JNIEnv *env) {
    static jboolean isLocal = False;
    static jboolean isLocalSet = False;
    jboolean ret;

    if (isLocalSet) {
        return isLocal;
    }

    isLocal = JNU_CallStaticMethodByName(env, NULL,
                                         "sun/awt/X11GraphicsEnvironment",
                                         "isDisplayLocal",
                                         "()Z").z;
    isLocalSet = True;
    return isLocal;
}
Пример #10
0
// static
void D3DPipelineManager::NotifyAdapterEventListeners(UINT adapter,
                                                     jint eventType)
{
    HMONITOR hMon;
    int gdiScreen;
    D3DPipelineManager *pMgr;
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    pMgr = D3DPipelineManager::GetInstance();
    RETURN_IF_NULL(pMgr);
    hMon = pMgr->pd3d9->GetAdapterMonitor(adapter);
    gdiScreen = AwtWin32GraphicsDevice::GetScreenFromHMONITOR(hMon);

    JNU_CallStaticMethodByName(env, NULL,
        "sun/java2d/pipe/hw/AccelDeviceEventNotifier",
        "eventOccured", "(II)V",
        gdiScreen, eventType);
}
Пример #11
0
jint
AWT_OnLoad(JavaVM *vm, void *reserved)
{
    Dl_info dlinfo;
    char buf[MAXPATHLEN];
    int32_t len;
    char *p, *tk = 0;
    JNI_OnLoad_type *JNI_OnLoad_ptr;
    struct utsname name;
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(vm, JNI_VERSION_1_2);
    void *v;
    char *envvar;
    jstring toolkit = NULL, grenv = NULL, fmanager = NULL;
    jstring tkProp = NULL, geProp = NULL, fmProp = NULL;

    if (awtHandle != NULL) {
        /* Avoid several loading attempts */
        return JNI_VERSION_1_2;
    }

    jvm = vm;

    /* Get address of this library and the directory containing it. */
    dladdr((void *)JNI_OnLoad, &dlinfo);
    realpath((char *)dlinfo.dli_fname, buf);
    len = strlen(buf);
    p = strrchr(buf, '/');

    /*
     * The code below is responsible for:
     * 1. Loading appropriate awt library, i.e. xawt/libmawt or headless/libwawt
     * 2. Setting "awt.toolkit" system property to use the appropriate Java toolkit class,
     *    (if user has specified the toolkit in env varialble)
     */

    tkProp = (*env)->NewStringUTF(env, "awt.toolkit");
    geProp = (*env)->NewStringUTF(env, "java.awt.graphicsenv");
    fmProp = (*env)->NewStringUTF(env, "sun.font.fontmanager");
    /* Check if toolkit is specified in env variable */
#ifdef MACOSX
    envvar = getenv("AWT_TOOLKIT");
    if (envvar && strstr(envvar, "XToolkit")) {
#endif
    toolkit = (*env)->NewStringUTF(env, "sun.awt.X11.XToolkit");
	grenv = (*env)->NewStringUTF(env, "sun.awt.X11GraphicsEnvironment");
	fmanager = (*env)->NewStringUTF(env, "sun.awt.X11FontManager");
	tk = "/xawt/libmawt";
#ifdef MACOSX
    } else {
    toolkit = (*env)->NewStringUTF(env, "sun.lwawt.macosx.LWCToolkit");
	grenv = (*env)->NewStringUTF(env, "sun.awt.CGraphicsEnvironment");
	fmanager = (*env)->NewStringUTF(env, "sun.font.CFontManager");
	tk = "/lwawt/liblwawt";
    }
#endif
    if (toolkit && tkProp) {
        JNU_CallStaticMethodByName(env, NULL, "java/lang/System", "setProperty",
	                           "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
                                   tkProp, toolkit);
    }
    if (grenv && geProp) {
        JNU_CallStaticMethodByName(env, NULL, "java/lang/System", "setProperty",
                                   "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
                                   geProp, grenv);
    }
    if (fmanager && fmProp) {
        JNU_CallStaticMethodByName(env, NULL, "java/lang/System", "setProperty",
                                   "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
                                   fmProp, fmanager);
    }

    /* Calculate library name to load */
#ifndef MACOSX
    if (AWTIsHeadless()) {
        strcpy(p, "/headless/libmawt");
    } else if (tk) {
#endif
        strcpy(p, tk);
#ifndef MACOSX
    }
#endif

    if (toolkit) {
        (*env)->DeleteLocalRef(env, toolkit);
    }
    if (tkProp) {
        (*env)->DeleteLocalRef(env, tkProp);
    }
    if (grenv) {
        (*env)->DeleteLocalRef(env, grenv);
    }
    if (geProp) {
        (*env)->DeleteLocalRef(env, geProp);
    }

#ifdef MACOSX
    strcat(p, ".dylib");
#else
    strcat(p, ".so");
#endif

    if (tk) {
        JNU_CallStaticMethodByName(env, NULL, "java/lang/System", "load",
				   "(Ljava/lang/String;)V",
				   JNU_NewStringPlatform(env, buf));
	    awtHandle = dlopen(buf, RTLD_LAZY | RTLD_GLOBAL);
    }

    return JNI_VERSION_1_2;
}
Пример #12
0
/**
 * Initializes a new OGLContext, which includes the native WGL context handle
 * and some other important information such as the associated pixel format.
 * If sharedctx is non-null, its texture objects will be shared with the newly
 * created HGLRC.  If useDisposer is JNI_TRUE, a new DisposerTarget
 * (with the current Java-level thread object as the referent) will be
 * created and enqueued in the Disposer, so that this OGLContext will be
 * disposed of properly when its associated thread exits.  Contexts that are
 * intended to remain for the lifetime of the app (such as the sharedContext)
 * should specify JNI_FALSE for useDisposer.
 */
OGLContext *
WGLGC_InitOGLContext(JNIEnv *env, WGLGraphicsConfigInfo *wglinfo,
                     jboolean useDisposer)
{
    OGLContext *oglc;
    WGLCtxInfo *ctxinfo;
    HGLRC context;
    static jboolean firstTime = JNI_TRUE;

    J2dTraceLn(J2D_TRACE_INFO, "in WGLGC_InitOGLContext");

    oglc = (OGLContext *)malloc(sizeof(OGLContext));
    if (oglc == NULL) {
        J2dTraceLn(J2D_TRACE_ERROR, "could not allocate memory for oglc");
        return NULL;
    }

    memset(oglc, 0, sizeof(OGLContext));

    ctxinfo = (WGLCtxInfo *)malloc(sizeof(WGLCtxInfo));
    if (ctxinfo == NULL) {
        J2dTraceLn(J2D_TRACE_ERROR, "could not allocate memory for ctxinfo");
        free(oglc);
        return NULL;
    }

    context = WGLGC_CreateContext(wglinfo->screen, wglinfo->pixfmt);
    if (context == 0) {
        J2dTraceLn(J2D_TRACE_ERROR, "could not create new WGL context");
        free(oglc);
        free(ctxinfo);
        return NULL;
    }

    // REMIND: when using wglShareLists, the two contexts must use an
    //         identical pixel format...
    if (sharedContext != NULL) {
        WGLCtxInfo *sharedCtxInfo = (WGLCtxInfo *)sharedContext->ctxInfo;
        if (!j2d_wglShareLists(sharedCtxInfo->context, context)) {
            J2dTraceLn(J2D_TRACE_WARNING, "unable to share lists");
        }
    }

    ctxinfo->context = context;
    ctxinfo->configInfo = wglinfo;
    oglc->ctxInfo = ctxinfo;
    oglc->extInfo = &wglinfo->extInfo;

    // initialize this value to 1.0f as it is sometimes used when uploading
    // textures (see OGLBlitLoops_Blit()), and in the case of the shared
    // context, we skip the InitComposite() step that would otherwise
    // initialize the oglc->extraAlpha value...
    oglc->extraAlpha = 1.0f;

    /**
     * REMIND: The following is a total hack.  The first time we enter
     * this method, we must be on the main thread attempting to initialize
     * the default GraphicsConfig.  Each time we enter this method, we would
     * like to upcall to the static EventQueue.isDispatchThread() method.
     * But the first time we call that static method, we may end up implicitly
     * loading WToolkit, which will also attempt to call getDefaultConfig().
     * But since we still haven't fully initialized the default config, we
     * re-enter the getDefaultConfig() method (in the same thread), and then
     * come down through this same method.  JNI doesn't seem to like this
     * situation, and we end up with a seg fault.  This may be a JNI bug,
     * but for now we'll work around it, by avoiding the upcall the first
     * time around.  After that, we should be able to make this upcall without
     * the nasty side effects.
     */
    if (firstTime) {
        oglc->onJED = JNI_FALSE;
        firstTime = JNI_FALSE;
    } else {
        oglc->onJED = JNU_CallStaticMethodByName(env, NULL,
                                                 "java/awt/EventQueue",
                                                 "isDispatchThread",
                                                 "()Z").z;
    }

    if (useDisposer) {
        // initialize a new Disposer target (when the Java-level thread object
        // is about to go away, Disposer will invoke our native dispose
        // method, which destroys this OGLContext and its associated entries)
        jobject thread = JNU_CallStaticMethodByName(env, NULL,
                                                    "java/lang/Thread",
                                                    "currentThread",
                                                    "()Ljava/lang/Thread;").l;
        if (thread == NULL) {
            J2dTraceLn(J2D_TRACE_ERROR, "could not fetch current thread");
            j2d_wglDeleteContext(context);
            free(oglc);
            free(ctxinfo);
            return NULL;
        }

        Disposer_AddRecord(env, thread,
                           WGLGC_DisposeOGLContext, ptr_to_jlong(oglc));
    }

    return oglc;
}
jint
AWT_OnLoad(JavaVM *vm, void *reserved)
{
    Dl_info dlinfo;
    char buf[MAXPATHLEN];
    int32_t len;
    char *p, *tk = 0;
    JNI_OnLoad_type *JNI_OnLoad_ptr;
    struct utsname name;
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(vm, JNI_VERSION_1_2);
    void *v;
    char *envvar;
    jstring fmanager = NULL;
    jstring fmProp = NULL;

    if (awtHandle != NULL) {
        /* Avoid several loading attempts */
        return JNI_VERSION_1_2;
    }

    jvm = vm;

    /* Get address of this library and the directory containing it. */
    dladdr((void *)AWT_OnLoad, &dlinfo);
    realpath((char *)dlinfo.dli_fname, buf);
    len = strlen(buf);
    p = strrchr(buf, '/');

    /*
     * 1. Set the "sun.font.fontmanager" system property,
     * 2. Choose the library image name.
     */

    fmProp = (*env)->NewStringUTF(env, "sun.font.fontmanager");
    /* Check if toolkit is specified in env variable */
#ifdef MACOSX
    envvar = getenv("AWT_TOOLKIT");
    if (envvar && strstr(envvar, "XToolkit")) {
#endif
        fmanager = (*env)->NewStringUTF(env, "sun.awt.X11FontManager");
        tk = "/xawt/libmawt";
#ifdef MACOSX
    } else {
        fmanager = (*env)->NewStringUTF(env, "sun.font.CFontManager");
        tk = "/lwawt/liblwawt";
    }
#endif
    if (fmanager && fmProp) {
        JNU_CallStaticMethodByName(env, NULL, "java/lang/System", "setProperty",
                                   "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
                                   fmProp, fmanager);
    }

    /* Calculate library name to load */
#ifndef MACOSX
    if (AWTIsHeadless()) {
        strcpy(p, "/headless/libmawt");
    } else if (tk) {
#endif
        strcpy(p, tk);
#ifndef MACOSX
    }
#endif

#ifdef MACOSX
    strcat(p, ".dylib");
#else
    strcat(p, ".so");
#endif

    if (tk) {
        JNU_CallStaticMethodByName(env, NULL, "java/lang/System", "load",
                                   "(Ljava/lang/String;)V",
                                   JNU_NewStringPlatform(env, buf));
            awtHandle = dlopen(buf, RTLD_LAZY | RTLD_GLOBAL);
    }

    return JNI_VERSION_1_2;
}
Пример #14
0
/**
 * Initializes a new OGLContext, which includes the native GLXContext handle
 * and some other important information such as the associated GLXFBConfig.
 * If sharedctx is non-null, its texture objects will be shared with the newly
 * created GLXContext.  If useDisposer is JNI_TRUE, a new DisposerTarget
 * (with the current Java-level thread object as the referent) will be
 * created and enqueued in the Disposer, so that this OGLContext will be
 * disposed of properly when its associated thread exits.  Contexts that are
 * intended to remain for the lifetime of the app (such as the sharedContext)
 * should specify JNI_FALSE for useDisposer.
 */
OGLContext *
GLXGC_InitOGLContext(JNIEnv *env, GLXGraphicsConfigInfo *glxinfo,
                     GLXContext sharedctx, jboolean useDisposer)
{
    OGLContext *oglc;
    GLXCtxInfo *ctxinfo;
    GLXFBConfig fbconfig;
    GLXContext context;
    static jboolean firstTime = JNI_TRUE;

    J2dTraceLn(J2D_TRACE_INFO, "in GLXGC_InitOGLContext");

    oglc = (OGLContext *)malloc(sizeof(OGLContext));
    if (oglc == NULL) {
        J2dTraceLn(J2D_TRACE_ERROR, "could not allocate memory for oglc");
        return NULL;
    }

    memset(oglc, 0, sizeof(OGLContext));

    ctxinfo = (GLXCtxInfo *)malloc(sizeof(GLXCtxInfo));
    if (ctxinfo == NULL) {
        J2dTraceLn(J2D_TRACE_ERROR, "could not allocate memory for ctxinfo");
        free(oglc);
        return NULL;
    }

    fbconfig = GLXGC_InitFBConfig(env, glxinfo->screen, glxinfo->visual);
    if (fbconfig == 0) {
        J2dTraceLn(J2D_TRACE_ERROR, "could not create new GLX fbconfig");
        free(oglc);
        free(ctxinfo);
        return NULL;
    }

    // REMIND: we cannot rely on direct contexts when rendering to pixmaps
    context = j2d_glXCreateNewContext(awt_display, fbconfig,
                                      GLX_RGBA_TYPE, sharedctx, GL_TRUE);
    if (context == 0) {
        J2dTraceLn(J2D_TRACE_ERROR, "could not create new GLX context");
        free(oglc);
        free(ctxinfo);
        return NULL;
    }

    ctxinfo->fbconfig = fbconfig;
    ctxinfo->context = context;
    oglc->ctxInfo = ctxinfo;
    oglc->extInfo = &glxinfo->extInfo;

    // initialize this value to 1.0f as it is sometimes used when uploading
    // textures (see OGLBlitLoops_Blit()), and in the case of the shared
    // context, we skip the InitComposite() step that would otherwise
    // initialize the oglc->extraAlpha value...
    oglc->extraAlpha = 1.0f;

    /**
     * REMIND: The following is a total hack.  The first time we enter
     * this method, we must be on the main thread attempting to initialize
     * the default GraphicsConfig.  Each time we enter this method, we would
     * like to upcall to the static EventQueue.isDispatchThread() method.
     * But the first time we call that static method, we may end up implicitly
     * loading MToolkit, which will also attempt to call getDefaultConfig().
     * But since we still haven't fully initialized the default config, we
     * re-enter the getDefaultConfig() method (in the same thread), and then
     * come down through this same method.  JNI doesn't seem to like this
     * situation, and we end up with a seg fault.  This may be a JNI bug,
     * but for now we'll work around it, by avoiding the upcall the first
     * time around.  After that, we should be able to make this upcall without
     * the nasty side effects.
     */
    if (firstTime) {
        oglc->onJED = JNI_FALSE;
        firstTime = JNI_FALSE;
    } else {
        oglc->onJED = JNU_CallStaticMethodByName(env, NULL,
                                                 "java/awt/EventQueue",
                                                 "isDispatchThread",
                                                 "()Z").z;
    }

    if (useDisposer) {
        // initialize a new Disposer target (when the Java-level thread object
        // is about to go away, Disposer will invoke our native dispose
        // method, which destroys this OGLContext and its associated entries)
        jobject thread = awtJNI_GetCurrentThread(env);
        if (thread == NULL) {
            J2dTraceLn(J2D_TRACE_ERROR, "could not fetch current thread");
            free(oglc);
            free(ctxinfo);
            return NULL;
        }

        Disposer_AddRecord(env, thread,
                           GLXGC_DisposeOGLContext, ptr_to_jlong(oglc));
    }

    return oglc;
}