Exemple #1
0
/*
 * 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) {
      jclass geCls = (*env)->FindClass(env, "java/awt/GraphicsEnvironment");
      CHECK_NULL_RETURN(geCls, JNI_FALSE);
      jmethodID getLocalGE = (*env)->GetStaticMethodID(env, geCls,
                                                 "getLocalGraphicsEnvironment",
                                           "()Ljava/awt/GraphicsEnvironment;");
      CHECK_NULL_RETURN(getLocalGE, JNI_FALSE);
      jobject ge = (*env)->CallStaticObjectMethod(env, geCls, getLocalGE);
      JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);

      jclass sgeCls = (*env)->FindClass(env,
                                        "sun/java2d/SunGraphicsEnvironment");
      CHECK_NULL_RETURN(sgeCls, JNI_FALSE);
      if ((*env)->IsInstanceOf(env, ge, sgeCls)) {
        jmethodID isDisplayLocal = (*env)->GetMethodID(env, sgeCls,
                                                       "isDisplayLocal",
                                                       "()Z");
        JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
        isLocal = (*env)->CallBooleanMethod(env, ge, isDisplayLocal);
      } else {
        isLocal = True;
      }
      isLocalSet = True;
    }

    return isLocal;
}
Exemple #2
0
/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    parseDisplayName0
 * Signature: (JLjava/lang/String;)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_parseDisplayName0
    (JNIEnv* env, jclass cls, jlong jpIShellFolder, jstring jname)
{

    // Get desktop IShellFolder interface
    IShellFolder* pIShellFolder = (IShellFolder*)jpIShellFolder;
    if (pIShellFolder == NULL) {
        JNU_ThrowInternalError(env, "Desktop shell folder missing");
        return 0;
    }
    // Get relative PIDL for name
    LPITEMIDLIST pIDL;
    int nLength = env->GetStringLength(jname);
    const jchar* strPath = env->GetStringChars(jname, NULL);
    JNU_CHECK_EXCEPTION_RETURN(env, 0);
    jchar* wszPath = new jchar[nLength + 1];
    wcsncpy(reinterpret_cast<LPWSTR>(wszPath), reinterpret_cast<LPCWSTR>(strPath), nLength);
    wszPath[nLength] = 0;
    HRESULT res = pIShellFolder->ParseDisplayName(NULL, NULL,
                        reinterpret_cast<LPWSTR>(wszPath), NULL, &pIDL, NULL);
    if (res != S_OK) {
        JNU_ThrowIOException(env, "Could not parse name");
        pIDL = 0;
    }
    delete[] wszPath;
    env->ReleaseStringChars(jname, strPath);
    return (jlong)pIDL;
}
Exemple #3
0
/*
 * Helper function for creating Java column info object
 */
static jobject CreateColumnInfo(JNIEnv *pEnv,
                                jclass *pClass, jmethodID *pConstructor,
                                SHELLDETAILS *psd, ULONG visible)
{
    jstring str = jstringFromSTRRET(pEnv, NULL, &(psd->str));
    JNU_CHECK_EXCEPTION_RETURN(pEnv, NULL);

    return pEnv->NewObject(*pClass, *pConstructor,
                    str,
                    (jint)(psd->cxChar * 6), // TODO: is 6 OK for converting chars to pixels?
                    (jint)psd->fmt, (jboolean) visible);
}
static gboolean filenameFilterCallback(const GtkFileFilterInfo * filter_info, gpointer obj)
{
    JNIEnv *env;
    jstring filename;

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

    filename = (*env)->NewStringUTF(env, filter_info->filename);
    JNU_CHECK_EXCEPTION_RETURN(env, FALSE);

    return (*env)->CallBooleanMethod(env, obj, filenameFilterCallbackMethodID,
            filename);
}
Exemple #5
0
/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    getIcon
 * Signature: (Ljava/lang/String;Z)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIcon
    (JNIEnv* env, jclass cls, jstring absolutePath, jboolean getLargeIcon)
{
    HICON hIcon = NULL;
    SHFILEINFO fileInfo;
    LPCTSTR pathStr = JNU_GetStringPlatformChars(env, absolutePath, NULL);
    JNU_CHECK_EXCEPTION_RETURN(env, 0);
    if (fn_SHGetFileInfo(pathStr, 0L, &fileInfo, sizeof(fileInfo),
                         SHGFI_ICON | (getLargeIcon ? 0 : SHGFI_SMALLICON)) != 0) {
        hIcon = fileInfo.hIcon;
    }
    JNU_ReleaseStringPlatformChars(env, absolutePath, pathStr);
    return (jlong)hIcon;
}
Exemple #6
0
/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    getIconResource
 * Signature: (Ljava/lang/String;IIIZ)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIconResource
    (JNIEnv* env, jclass cls, jstring libName, jint iconID,
     jint cxDesired, jint cyDesired, jboolean useVGAColors)
{
    const char *pLibName = env->GetStringUTFChars(libName, NULL);
    JNU_CHECK_EXCEPTION_RETURN(env, 0);
    HINSTANCE libHandle = (HINSTANCE)JDK_LoadSystemLibrary(pLibName);
    if (libHandle != NULL) {
        UINT fuLoad = (useVGAColors && !IS_WINXP) ? LR_VGACOLOR : 0;
        return ptr_to_jlong(LoadImage(libHandle, MAKEINTRESOURCE(iconID),
                                      IMAGE_ICON, cxDesired, cyDesired,
                                      fuLoad));
    }
    return 0;
}
Exemple #7
0
struct FontData *
awtJNI_GetFontData(JNIEnv * env, jobject font, char **errmsg)
{
    /* We are going to create at most 4 outstanding local refs in this
     * function. */
    if ((*env)->EnsureLocalCapacity(env, 4) < 0) {
        return NULL;
    }

    if (!JNU_IsNull(env, font) && awtJNI_IsMultiFont(env, font)) {
        JNU_CHECK_EXCEPTION_RETURN(env, NULL);

        struct FontData *fdata = NULL;
        int32_t i, size;
        char *fontsetname = NULL;
        char *nativename = NULL;
        Boolean doFree = FALSE;
        jobjectArray componentFonts = NULL;
        jobject peer = NULL;
        jobject fontDescriptor = NULL;
        jstring fontDescriptorName = NULL;
        jstring charsetName = NULL;

        fdata = (struct FontData *) JNU_GetLongFieldAsPtr(env,font,
                                                         fontIDs.pData);

        if (fdata != NULL && fdata->flist != NULL) {
            return fdata;
        }
        size = (*env)->GetIntField(env, font, fontIDs.size);
        fdata = (struct FontData *) malloc(sizeof(struct FontData));

        peer = (*env)->CallObjectMethod(env, font, fontIDs.getPeer);

        componentFonts =
          (*env)->GetObjectField(env, peer, platformFontIDs.componentFonts);
        /* We no longer need peer */
        (*env)->DeleteLocalRef(env, peer);

        fdata->charset_num = (*env)->GetArrayLength(env, componentFonts);

        fdata->flist = (awtFontList *) malloc(sizeof(awtFontList)
                                              * fdata->charset_num);
        fdata->xfont = NULL;
        for (i = 0; i < fdata->charset_num; i++) {
            /*
             * set xlfd name
             */

            fontDescriptor = (*env)->GetObjectArrayElement(env, componentFonts, i);
            fontDescriptorName =
              (*env)->GetObjectField(env, fontDescriptor,
                                     fontDescriptorIDs.nativeName);

            if (!JNU_IsNull(env, fontDescriptorName)) {
                nativename = (char *) JNU_GetStringPlatformChars(env, fontDescriptorName, NULL);
                if (nativename == NULL) {
                    nativename = "";
                    doFree = FALSE;
                } else {
                    doFree = TRUE;
                }
            } else {
                nativename = "";
                doFree = FALSE;
            }

            fdata->flist[i].xlfd = malloc(strlen(nativename)
                                          + strlen(defaultXLFD));
            jio_snprintf(fdata->flist[i].xlfd, strlen(nativename) + 10,
                         nativename, size * 10);

            if (nativename != NULL && doFree)
                JNU_ReleaseStringPlatformChars(env, fontDescriptorName, (const char *) nativename);

            /*
             * set charset_name
             */

            charsetName =
              (*env)->GetObjectField(env, fontDescriptor,
                                     fontDescriptorIDs.charsetName);

            fdata->flist[i].charset_name = (char *)
                JNU_GetStringPlatformChars(env, charsetName, NULL);
            if (fdata->flist[i].charset_name == NULL) {
                (*env)->ExceptionClear(env);
                JNU_ThrowOutOfMemoryError(env, "Could not create charset name");
                return NULL;
            }

            /* We are done with the objects. */
            (*env)->DeleteLocalRef(env, fontDescriptor);
            (*env)->DeleteLocalRef(env, fontDescriptorName);
            (*env)->DeleteLocalRef(env, charsetName);

            /*
             * set load & XFontStruct
             */
            fdata->flist[i].load = 0;

            /*
             * This appears to be a bogus check.  The actual intent appears
             * to be to find out whether this is the "base" font in a set,
             * rather than iso8859_1 explicitly.  Note that iso8859_15 will
             * and must also pass this test.
             */

            if (fdata->xfont == NULL &&
                strstr(fdata->flist[i].charset_name, "8859_1")) {
                fdata->flist[i].xfont =
                    loadFont(awt_display, fdata->flist[i].xlfd, size * 10);
                if (fdata->flist[i].xfont != NULL) {
                    fdata->flist[i].load = 1;
                    fdata->xfont = fdata->flist[i].xfont;
                    fdata->flist[i].index_length = 1;
                } else {
                    /* Free any already allocated storage and fonts */
                    int j = i;
                    for (j = 0; j <= i; j++) {
                        free((void *)fdata->flist[j].xlfd);
                        JNU_ReleaseStringPlatformChars(env, NULL,
                            fdata->flist[j].charset_name);
                        if (fdata->flist[j].load) {
                            XFreeFont(awt_display, fdata->flist[j].xfont);
                        }
                    }
                    free((void *)fdata->flist);
                    free((void *)fdata);

                    if (errmsg != NULL) {
                        *errmsg = "java/lang" "NullPointerException";
                    }
                    (*env)->DeleteLocalRef(env, componentFonts);
                    return NULL;
                }
            }
        }
        (*env)->DeleteLocalRef(env, componentFonts);
        /*
         * XFontSet will create if the peer of TextField/TextArea
         * are used.
         */
        fdata->xfs = NULL;

        JNU_SetLongFieldFromPtr(env,font,fontIDs.pData,fdata);
        Disposer_AddRecord(env, font, pDataDisposeMethod, ptr_to_jlong(fdata));
        return fdata;
    } else {
        JNU_CHECK_EXCEPTION_RETURN(env, NULL);
        Display *display = NULL;
        struct FontData *fdata = NULL;
        char fontSpec[1024];
        int32_t height;
        int32_t oheight;
        int32_t above = 0;              /* tries above height */
        int32_t below = 0;              /* tries below height */
        char *foundry = NULL;
        char *name = NULL;
        char *encoding = NULL;
        char *style = NULL;
        XFontStruct *xfont = NULL;
        jstring family = NULL;

        if (JNU_IsNull(env, font)) {
            if (errmsg != NULL) {
                *errmsg = "java/lang" "NullPointerException";
            }
            return (struct FontData *) NULL;
        }
        display = XDISPLAY;

        fdata = (struct FontData *) JNU_GetLongFieldAsPtr(env,font,fontIDs.pData);
        if (fdata != NULL && fdata->xfont != NULL) {
            return fdata;
        }

        family = (*env)->CallObjectMethod(env, font, fontIDs.getFamily);

        if (!awtJNI_FontName(env, family, &foundry, &name, &encoding)) {
            if (errmsg != NULL) {
                *errmsg = "java/lang" "NullPointerException";
            }
            (*env)->DeleteLocalRef(env, family);
            return (struct FontData *) NULL;
        }
        style = Style((*env)->GetIntField(env, font, fontIDs.style));
        oheight = height = (*env)->GetIntField(env, font, fontIDs.size);

        while (1) {
            jio_snprintf(fontSpec, sizeof(fontSpec), "-%s-%s-%s-*-*-%d-*-*-*-*-*-%s",
                         foundry,
                         name,
                         style,
                         height,
                         encoding);

            /*fprintf(stderr,"LoadFont: %s\n", fontSpec); */
            xfont = XLoadQueryFont(display, fontSpec);

            /* XXX: sometimes XLoadQueryFont returns a bogus font structure */
            /* with negative ascent. */
            if (xfont == (Font) NULL || xfont->ascent < 0) {
                if (xfont != NULL) {
                    XFreeFont(display, xfont);
                }
                if (foundry != anyfoundry) {  /* Use ptr comparison here, not strcmp */
                    /* Try any other foundry before messing with the sizes */
                    foundry = anyfoundry;
                    continue;
                }
                /* We couldn't find the font. We'll try to find an */
                /* alternate by searching for heights above and below our */
                /* preferred height. We try for 4 heights above and below. */
                /* If we still can't find a font we repeat the algorithm */
                /* using misc-fixed as the font. If we then fail, then we */
                /* give up and signal an error. */
                if (above == below) {
                    above++;
                    height = oheight + above;
                } else {
                    below++;
                    if (below > 4) {
                        if (name != defaultfontname || style != anystyle) {
                            name = defaultfontname;
                            foundry = defaultfoundry;
                            height = oheight;
                            style = anystyle;
                            encoding = isolatin1;
                            above = below = 0;
                            continue;
                        } else {
                            if (errmsg != NULL) {
                                *errmsg = "java/io/" "FileNotFoundException";
                            }
                            (*env)->DeleteLocalRef(env, family);
                            return (struct FontData *) NULL;
                        }
                    }
                    height = oheight - below;
                }
                continue;
            } else {
                fdata = ZALLOC(FontData);

                if (fdata == NULL) {
                    if (errmsg != NULL) {
                        *errmsg = "java/lang" "OutOfMemoryError";
                    }
                } else {
                    fdata->xfont = xfont;
                    JNU_SetLongFieldFromPtr(env,font,fontIDs.pData,fdata);
                    Disposer_AddRecord(env, font, pDataDisposeMethod,
                                       ptr_to_jlong(fdata));
                }
                (*env)->DeleteLocalRef(env, family);
                return fdata;
            }
        }
        /* not reached */
    }
}
Exemple #8
0
/* This function gets called very early, before VM_CALLS are setup.
 * Do not use any of the VM_CALLS entries!!!
 */
java_props_t *
GetJavaProperties(JNIEnv *env)
{
    static java_props_t sprops;
    char *v; /* tmp var */

    if (sprops.user_dir) {
        return &sprops;
    }

    /* tmp dir */
    sprops.tmp_dir = P_tmpdir;
#ifdef MACOSX
    /* darwin has a per-user temp dir */
    static char tmp_path[PATH_MAX];
    int pathSize = confstr(_CS_DARWIN_USER_TEMP_DIR, tmp_path, PATH_MAX);
    if (pathSize > 0 && pathSize <= PATH_MAX) {
        sprops.tmp_dir = tmp_path;
    }
#endif /* MACOSX */

    /* Printing properties */
#ifdef MACOSX
    sprops.printerJob = "sun.lwawt.macosx.CPrinterJob";
#else
    sprops.printerJob = "sun.print.PSPrinterJob";
#endif

    /* patches/service packs installed */
    sprops.patch_level = "unknown";

    /* Java 2D/AWT properties */
#ifdef MACOSX
    // Always the same GraphicsEnvironment and Toolkit on Mac OS X
    sprops.graphics_env = "sun.awt.CGraphicsEnvironment";
    sprops.awt_toolkit = "sun.lwawt.macosx.LWCToolkit";

    // check if we're in a GUI login session and set java.awt.headless=true if not
    sprops.awt_headless = isInAquaSession() ? NULL : "true";
#else
    sprops.graphics_env = "sun.awt.X11GraphicsEnvironment";
#ifdef JAVASE_EMBEDDED
    sprops.awt_toolkit = getEmbeddedToolkit();
    if (sprops.awt_toolkit == NULL) // default as below
#endif
    sprops.awt_toolkit = "sun.awt.X11.XToolkit";
#endif

    /* This is used only for debugging of font problems. */
    v = getenv("JAVA2D_FONTPATH");
    sprops.font_dir = v ? v : NULL;

#ifdef SI_ISALIST
    /* supported instruction sets */
    {
        char list[258];
        sysinfo(SI_ISALIST, list, sizeof(list));
        sprops.cpu_isalist = strdup(list);
    }
#else
    sprops.cpu_isalist = NULL;
#endif

    /* endianness of platform */
    {
        unsigned int endianTest = 0xff000000;
        if (((char*)(&endianTest))[0] != 0)
            sprops.cpu_endian = "big";
        else
            sprops.cpu_endian = "little";
    }

    /* os properties */
    {
#ifdef MACOSX
        setOSNameAndVersion(&sprops);
#else
        struct utsname name;
        uname(&name);
        sprops.os_name = strdup(name.sysname);
        sprops.os_version = strdup(name.release);
#endif

        sprops.os_arch = ARCHPROPNAME;

        if (getenv("GNOME_DESKTOP_SESSION_ID") != NULL) {
            sprops.desktop = "gnome";
        }
        else {
            sprops.desktop = NULL;
        }
    }

    /* ABI property (optional) */
#ifdef JDK_ARCH_ABI_PROP_NAME
    sprops.sun_arch_abi = JDK_ARCH_ABI_PROP_NAME;
#endif

    /* Determine the language, country, variant, and encoding from the host,
     * and store these in the user.language, user.country, user.variant and
     * file.encoding system properties. */
    setlocale(LC_ALL, "");
    if (ParseLocale(env, LC_CTYPE,
                    &(sprops.format_language),
                    &(sprops.format_script),
                    &(sprops.format_country),
                    &(sprops.format_variant),
                    &(sprops.encoding))) {
        ParseLocale(env, LC_MESSAGES,
                    &(sprops.language),
                    &(sprops.script),
                    &(sprops.country),
                    &(sprops.variant),
                    NULL);
    } else {
        sprops.language = "en";
        sprops.encoding = "ISO8859-1";
    }
    sprops.display_language = sprops.language;
    sprops.display_script = sprops.script;
    sprops.display_country = sprops.country;
    sprops.display_variant = sprops.variant;

    /* ParseLocale failed with OOME */
    JNU_CHECK_EXCEPTION_RETURN(env, NULL);

#ifdef MACOSX
    sprops.sun_jnu_encoding = "UTF-8";
#else
    sprops.sun_jnu_encoding = sprops.encoding;
#endif

#ifdef _ALLBSD_SOURCE
#if BYTE_ORDER == _LITTLE_ENDIAN
     sprops.unicode_encoding = "UnicodeLittle";
 #else
     sprops.unicode_encoding = "UnicodeBig";
 #endif
#else /* !_ALLBSD_SOURCE */
#ifdef __linux__
#if __BYTE_ORDER == __LITTLE_ENDIAN
    sprops.unicode_encoding = "UnicodeLittle";
#else
    sprops.unicode_encoding = "UnicodeBig";
#endif
#else
    sprops.unicode_encoding = "UnicodeBig";
#endif
#endif /* _ALLBSD_SOURCE */

    /* user properties */
    {
        struct passwd *pwent = getpwuid(getuid());
        sprops.user_name = pwent ? strdup(pwent->pw_name) : "?";
#ifdef MACOSX
        setUserHome(&sprops);
#else
        sprops.user_home = pwent ? strdup(pwent->pw_dir) : NULL;
#endif
        if (sprops.user_home == NULL) {
            sprops.user_home = "?";
        }
    }

    /* User TIMEZONE */
    {
        /*
         * We defer setting up timezone until it's actually necessary.
         * Refer to TimeZone.getDefault(). However, the system
         * property is necessary to be able to be set by the command
         * line interface -D. Here temporarily set a null string to
         * timezone.
         */
        tzset();        /* for compatibility */
        sprops.timezone = "";
    }

    /* Current directory */
    {
        char buf[MAXPATHLEN];
        errno = 0;
        if (getcwd(buf, sizeof(buf))  == NULL)
            JNU_ThrowByName(env, "java/lang/Error",
             "Properties init: Could not determine current working directory.");
        else
            sprops.user_dir = strdup(buf);
    }

    sprops.file_separator = "/";
    sprops.path_separator = ":";
    sprops.line_separator = "\n";

#ifdef MACOSX
    setProxyProperties(&sprops);
#endif

    return &sprops;
}
/* Retrieve the context data from the current IMC.
   Params:
   HIMC hIMC - the input method context, must NOT be NULL
   LPARAMS flags - message param to WM_IME_COMPOSITION.
   Returns 0 if success.
*/
int
AwtInputTextInfor::GetContextData(HIMC hIMC, const LPARAM flags) {

    DASSERT(hIMC != 0);

    m_flags = flags;
    // Based on different flags received, we use different GCS_XXX from the
    // GCS_INDEX array.
    int startIndex = 0, endIndex = 0;

    if (flags & GCS_COMPSTR) {
        startIndex = START_COMPSTR;
        endIndex = END_COMPSTR;
        /* For some window input method such as Chinese QuanPing, when the user
         * commits some text, the IMM sends WM_IME_COMPOSITION with GCS_COMPSTR/GCS_RESULTSTR.
         * So we have to extract the result string from IMC. For most of other cases,
         * m_pResultTextInfor is NULL and this is why we choose to have a pointer as its member
         * rather than having a list of the result string information.
         */
        if (flags & GCS_RESULTSTR) {
            m_pResultTextInfor = new AwtInputTextInfor;
            m_pResultTextInfor->GetContextData(hIMC, GCS_RESULTSTR);
        }
    } else if (flags & GCS_RESULTSTR) {
        startIndex = START_RESULTSTR;
        endIndex = END_RESULTSTR;
    } else { // unknown flags.
        return -1;
    }

    /* Get the data from the input context */
    LONG   cbData[5] = {0};
    LPVOID lpData[5] = {NULL};
    for (int i = startIndex, j = 0; i <= endIndex; i++, j++) {
        cbData[j] = ::ImmGetCompositionString(hIMC, GCS_INDEX[i], NULL, 0);
        if (cbData[j] == 0) {
            lpData[j] = NULL;
        } else {
            LPBYTE lpTemp = new BYTE[cbData[j]];
            cbData[j] = ::ImmGetCompositionString(hIMC, GCS_INDEX[i], lpTemp, cbData[j]);
            if (IMM_ERROR_GENERAL != cbData[j]) {
                lpData[j] = (LPVOID)lpTemp;
            } else {
                lpData[j] = NULL;
                return -1;
            }
        }
    }

    // Assign the context data
    m_cStrW = cbData[0]/WCHAR_SZ;
    m_lpStrW = (LPWSTR)lpData[0];

    m_cReadStrW = cbData[1]/WCHAR_SZ;
    m_lpReadStrW = (LPWSTR)lpData[1];

    m_cClauseW = cbData[2]/DWORD_SZ - 1;
    m_lpClauseW = (LPDWORD)lpData[2];

    m_cReadClauseW = cbData[3]/DWORD_SZ - 1;
    m_lpReadClauseW = (LPDWORD)lpData[3];

    if (cbData[4] > 0) {
        m_cAttrW = cbData[4];
        m_lpAttrW = (LPBYTE)lpData[4];
    }

    // Get the cursor position
    if (flags & GCS_COMPSTR) {
        m_cursorPosW = ::ImmGetCompositionString(hIMC, GCS_CURSORPOS,
                                                NULL, 0);
    }

    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    if (m_cStrW > 0) {
        m_jtext = MakeJavaString(env, m_lpStrW, m_cStrW);
        JNU_CHECK_EXCEPTION_RETURN(env, -1);
    }

    // Merge the string if necessary
    if (m_pResultTextInfor != NULL) {
        jstring jresultText = m_pResultTextInfor->GetText();
        if (m_jtext != NULL && jresultText != NULL) {
            jstring jMergedtext = (jstring)JNU_CallMethodByName(env, NULL, jresultText,
                                                                "concat",
                                                                "(Ljava/lang/String;)Ljava/lang/String;",
                                                                m_jtext).l;
            DASSERT(!safe_ExceptionOccurred(env));
            DASSERT(jMergedtext != NULL);

            env->DeleteLocalRef(m_jtext);
            m_jtext = jMergedtext;
        }
        else if (m_jtext == NULL && jresultText != NULL) {
            /* No composing text, assign the committed text to m_jtext */
            m_jtext = (jstring)env->NewLocalRef(jresultText);
        }
    }

    return 0;
}