/* * Copyright 1995-2003 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ #ifdef HEADLESS #error This file should not be included in headless library #endif #include #include "awt_p.h" #include "java_awt_TextField.h" #include "java_awt_Color.h" #include "java_awt_AWTEvent.h" #include "java_awt_Font.h" #include "java_awt_Canvas.h" #include "sun_awt_motif_MComponentPeer.h" #include "sun_awt_motif_MCanvasPeer.h" #include "sun_awt_motif_MTextFieldPeer.h" #include "awt_Component.h" #include "awt_TextField.h" #include "multi_font.h" #include #include #include #include /* Motif TextField private header. */ #define ECHO_BUFFER_LEN 1024 extern struct MComponentPeerIDs mComponentPeerIDs; extern AwtGraphicsConfigDataPtr copyGraphicsConfigToPeer(JNIEnv *env, jobject this); struct TextFieldIDs textFieldIDs; struct MTextFieldPeerIDs mTextFieldPeerIDs; /* * Class: java_awt_TextField * Method: initIDs * Signature: ()V */ /* This function gets called from the static initializer for TextField.java to initialize the fieldIDs for fields that may be accessed from C */ JNIEXPORT void JNICALL Java_java_awt_TextField_initIDs (JNIEnv *env, jclass cls) { textFieldIDs.echoChar = (*env)->GetFieldID(env, cls, "echoChar", "C"); } /* * Class: sun_awt_motif_MTextFieldPeer * Method: initIDs * Signature: ()V */ /* This function gets called from the static initializer for MTextFieldPeer.java to initialize the fieldIDs for fields that may be accessed from C */ JNIEXPORT void JNICALL Java_sun_awt_motif_MTextFieldPeer_initIDs (JNIEnv *env, jclass cls) { mTextFieldPeerIDs.firstChangeSkipped = (*env)->GetFieldID(env, cls, "firstChangeSkipped", "Z"); } static void echoChar(Widget text_w, XtPointer unused, XmTextVerifyCallbackStruct * cbs) { size_t len; int32_t c; char *val; struct DPos *dp; int32_t ret; jobject globalRef; int32_t i, numbytes; struct TextFieldData *tdata; JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); /* * Get the echoContextID from the globalRef which is stored in * the XmNuserData resource for the widget. */ XtVaGetValues(text_w,XmNuserData,&globalRef,NULL); tdata = (struct TextFieldData *) (*env)->GetLongField(env,globalRef,mComponentPeerIDs.pData); ret = XFindContext(XtDisplay(text_w), (XID)text_w, tdata->echoContextID, (XPointer *)&dp); if ((ret != 0) || (dp == NULL)) { /* no context found or DPos is NULL - shouldn't happen */ return; } c = dp->echoC; val = (char *) (dp->data); len = strlen(val); if (cbs->text->ptr == NULL) { if (cbs->text->length == 0 && cbs->startPos == 0) { val[0] = '\0'; return; } else if (cbs->startPos == (len - 1)) { /* handle deletion */ cbs->endPos = strlen(val); val[cbs->startPos] = '\0'; return; } else { /* disable deletes anywhere but at the end */ cbs->doit = False; return; } } if (cbs->startPos != len) { /* disable "paste" or inserts into the middle */ cbs->doit = False; return; } /* append the value typed in */ if ((cbs->endPos + cbs->text->length) > ECHO_BUFFER_LEN) { val = realloc(val, cbs->endPos + cbs->text->length + 10); } strncat(val, cbs->text->ptr, cbs->text->length); val[cbs->endPos + cbs->text->length] = '\0'; /* modify the output to be the echo character */ for (len = 0, i = 0; len < cbs->text->length; i++) { /* Write one echo character for each multibyte character. */ numbytes = mblen(cbs->text->ptr + len, cbs->text->length - len); cbs->text->ptr[i] = (char) c; len += numbytes; } cbs->text->length = i; } /* * Event handler used by both TextField/TextArea to correctly process * cut/copy/paste keys such that interaction with our own * clipboard mechanism will work properly. * * client_data is MTextFieldPeer instance */ void Text_handlePaste(Widget w, XtPointer client_data, XEvent * event, Boolean * cont) { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); KeySym keysym; Modifiers mods; /* Any event handlers which take peer instance pointers as * client_data should check to ensure the widget has not been * marked as destroyed as a result of a dispose() call on the peer * (which can result in the peer instance pointer already haven * been gc'd by the time this event is processed) */ if (event->type != KeyPress || w->core.being_destroyed) { return; } XtTranslateKeycode(event->xkey.display, (KeyCode) event->xkey.keycode, event->xkey.state, &mods, &keysym); /* Should be a temporary fix for 4052132 if a cleaner fix is found later */ if ((event->xkey.state & ControlMask) && (keysym == 'v' || keysym == 'V')) keysym = osfXK_Paste; if ((event->xkey.state & ShiftMask) && (keysym == osfXK_Insert)) keysym = osfXK_Paste; switch (keysym) { case osfXK_Paste: /* If we own the selection, then paste the data directly */ if (awtJNI_isSelectionOwner(env, "CLIPBOARD")) { JNU_CallMethodByName(env, NULL, (jobject) client_data, "pasteFromClipboard", "()V"); if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionDescribe(env); (*env)->ExceptionClear(env); } *cont = FALSE; } break; case osfXK_Cut: case osfXK_Copy: /* For some reason if we own the selection, our loseSelection * callback is not automatically called on cut/paste from * text widgets. */ if (awtJNI_isSelectionOwner(env, "CLIPBOARD")) { awtJNI_notifySelectionLost(env, "CLIPBOARD"); } break; default: break; } } /* * client_data is MTextFieldPeer instance */ void TextField_valueChanged(Widget w, XtPointer client_data, XtPointer call_data) { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); jboolean skipped; skipped = (*env)->GetBooleanField(env, (jobject) client_data, mTextFieldPeerIDs.firstChangeSkipped); if (!(*env)->ExceptionOccurred(env)) { if (skipped == JNI_FALSE) { (*env)->SetBooleanField(env, (jobject) client_data, mTextFieldPeerIDs.firstChangeSkipped, JNI_TRUE); } else { JNU_CallMethodByName(env, NULL, (jobject) client_data, "valueChanged", "()V"); } } if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionDescribe(env); (*env)->ExceptionClear(env); } } /* * client_data is MTextFieldPeer instance */ static void TextField_action(Widget w, XtPointer client_data, XmAnyCallbackStruct * s) { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); ConvertEventTimeAndModifiers converted; awt_util_convertEventTimeAndModifiers(s->event, &converted); JNU_CallMethodByName(env, NULL, (jobject) client_data, "action", "(JI)V", converted.when, converted.modifiers); if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionDescribe(env); (*env)->ExceptionClear(env); } } /* * Class: sun_awt_motif_MTextFieldPeer * Method: pCreate * Signature: (Lsun/awt/motif/MComponentPeer;)V */ JNIEXPORT void JNICALL Java_sun_awt_motif_MTextFieldPeer_pCreate (JNIEnv *env, jobject this, jobject parent) { struct ComponentData *wdata; struct TextFieldData *tdata; jobject globalRef = awtJNI_CreateAndSetGlobalRef(env, this); AwtGraphicsConfigDataPtr adata; AWT_LOCK(); adata = copyGraphicsConfigToPeer(env, this); if (JNU_IsNull(env, parent)) { JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return; } wdata = (struct ComponentData *) JNU_GetLongFieldAsPtr(env,parent,mComponentPeerIDs.pData); if (wdata == NULL) { JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return; } tdata = ZALLOC(TextFieldData); if (tdata == NULL) { JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); AWT_UNLOCK(); return; } JNU_SetLongFieldFromPtr(env,this,mComponentPeerIDs.pData,tdata); tdata->comp.widget = XtVaCreateManagedWidget("textfield", xmTextFieldWidgetClass, wdata->widget, XmNrecomputeSize, False, XmNhighlightThickness, 1, XmNshadowThickness, 2, XmNuserData, (XtPointer) globalRef, XmNscreen, ScreenOfDisplay(awt_display, adata->awt_visInfo.screen), XmNfontList, getMotifFontList(), NULL); tdata->echoContextIDInit = FALSE; XtSetMappedWhenManaged(tdata->comp.widget, False); XtAddCallback(tdata->comp.widget, XmNactivateCallback, (XtCallbackProc) TextField_action, (XtPointer) globalRef); XtAddCallback(tdata->comp.widget, XmNvalueChangedCallback, (XtCallbackProc) TextField_valueChanged, (XtPointer) globalRef); XtInsertEventHandler(tdata->comp.widget, KeyPressMask, False, Text_handlePaste, (XtPointer) globalRef, XtListHead); /* * Fix for BugTraq ID 4349615. * Unregister Motif drop site to prevent it from crash * when dropping java objects. */ XmDropSiteUnregister(tdata->comp.widget); AWT_UNLOCK(); } /* * Class sun_awt_motif_MTextFieldPeer * Method: pSetEditable * Signature: (Z)V */ JNIEXPORT void JNICALL Java_sun_awt_motif_MTextFieldPeer_pSetEditable (JNIEnv *env, jobject this, jboolean editable) { struct TextFieldData *tdata; AWT_LOCK(); tdata = (struct TextFieldData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData); if (tdata == NULL || tdata->comp.widget == NULL) { JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return; } XtVaSetValues(tdata->comp.widget, XmNeditable, (editable ? True : False), XmNcursorPositionVisible, (editable ? True : False), NULL); AWT_FLUSH_UNLOCK(); } /* * Class: sun_awt_motif_MTextFieldPeer * Method: select * Signature: (II)V */ JNIEXPORT void JNICALL Java_sun_awt_motif_MTextFieldPeer_select (JNIEnv *env, jobject this, jint start, jint end) { struct TextFieldData *tdata; AWT_LOCK(); tdata = (struct TextFieldData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData); if (tdata == NULL || tdata->comp.widget == NULL) { JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return; } XmTextSetSelection(tdata->comp.widget, (XmTextPosition) start, (XmTextPosition) end, 0); AWT_FLUSH_UNLOCK(); } /* * Class: sun_awt_motif_MTextFieldPeer * Method: getSelectionStart * Signature: ()I */ JNIEXPORT jint JNICALL Java_sun_awt_motif_MTextFieldPeer_getSelectionStart (JNIEnv *env, jobject this) { struct TextFieldData *tdata; XmTextPosition start, end, pos; AWT_LOCK(); tdata = (struct TextFieldData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData); if (tdata == NULL || tdata->comp.widget == NULL) { JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return 0; } if (XmTextGetSelectionPosition(tdata->comp.widget, &start, &end) && (start != end)) { pos = start; } else { pos = XmTextGetInsertionPosition(tdata->comp.widget); } AWT_UNLOCK(); return (jint) pos; } /* * Class: sun_awt_motif_MTextFieldPeer * Method: getSelectionEnd * Signature: ()I */ JNIEXPORT jint JNICALL Java_sun_awt_motif_MTextFieldPeer_getSelectionEnd (JNIEnv *env, jobject this) { struct TextFieldData *tdata; XmTextPosition start, end, pos; AWT_LOCK(); tdata = (struct TextFieldData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData); if (tdata == NULL || tdata->comp.widget == NULL) { JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return 0; } if (XmTextGetSelectionPosition(tdata->comp.widget, &start, &end) && (start != end)) { pos = end; } else { pos = XmTextGetInsertionPosition(tdata->comp.widget); } AWT_UNLOCK(); return (jint) pos; } /* * Class: sun_awt_motif_MTextFieldPeer * Method: setText * Signature: (Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_sun_awt_motif_MTextFieldPeer_setText (JNIEnv *env, jobject this, jstring l) { struct TextFieldData *tdata; char *cl; jobject target; AWT_LOCK(); tdata = (struct TextFieldData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData); if (tdata == NULL || tdata->comp.widget == NULL) { JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return; } if (JNU_IsNull(env, l)) { cl = ""; } else { /* * Note: Motif TextField widgets do not support multi-font * compound strings. */ cl = (char *) JNU_GetStringPlatformChars(env, l, NULL); } /* Fix for bug 4084454 : setText appears in clear */ target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target); if ((*env)->GetCharField(env, target, textFieldIDs.echoChar) != 0) { XtVaSetValues(tdata->comp.widget, XmNvalue, "", NULL); XmTextFieldInsert(tdata->comp.widget,0,cl); XmTextSetInsertionPosition(tdata->comp.widget, (XmTextPosition) strlen(cl)); } else { XtVaSetValues(tdata->comp.widget, XmNvalue, cl, NULL); } /* * Fix for BugTraq Id 4185654 - TextField.setText() incorrect justification * Comment out the next line. */ /* XmTextSetInsertionPosition(tdata->comp.widget, * (XmTextPosition) strlen(cl)); */ if (cl != NULL && cl != "") { JNU_ReleaseStringPlatformChars(env, l, cl); } AWT_FLUSH_UNLOCK(); } /* * Class: sun_awt_motif_MTextFieldPeer * Method: insertReplaceText * Signature: (Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_sun_awt_motif_MTextFieldPeer_insertReplaceText (JNIEnv *env, jobject this, jstring l) { struct TextFieldData *tdata; char *cl; XmTextPosition start, end; AWT_LOCK(); tdata = (struct TextFieldData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData); if (tdata == NULL || tdata->comp.widget == NULL) { JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return; } if (JNU_IsNull(env, l)) { cl = ""; } else { /* * Note: Motif TextField widgets do not support multi-font * compound strings. */ cl = (char *) JNU_GetStringPlatformChars(env, l, NULL); } if (!XmTextGetSelectionPosition(tdata->comp.widget, &start, &end)) { start = end = XmTextGetInsertionPosition(tdata->comp.widget); } XmTextReplace(tdata->comp.widget, start, end, cl); if (cl != NULL && cl != "") { JNU_ReleaseStringPlatformChars(env, l, cl); } AWT_FLUSH_UNLOCK(); } /* * Class: sun_awt_motif_MTextFieldPeer * Method: preDispose * Signature: ()V */ JNIEXPORT void JNICALL Java_sun_awt_motif_MTextFieldPeer_preDispose (JNIEnv *env, jobject this) { struct TextFieldData *tdata; struct DPos *dp; jobject target; int32_t ret; AWT_LOCK(); tdata = (struct TextFieldData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData); if (tdata == NULL || tdata->comp.widget == NULL) { JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return; } target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target); if ((*env)->GetCharField(env, target, textFieldIDs.echoChar) != 0) { ret = XFindContext(XtDisplay(tdata->comp.widget), (XID)(tdata->comp.widget), tdata->echoContextID, (XPointer *)&dp); if ((ret == 0) && dp != NULL) { /* Remove the X context associated with this textfield's * echo character. BugId #4225734 */ XDeleteContext(XtDisplay(tdata->comp.widget), (XID)(tdata->comp.widget), tdata->echoContextID); tdata->echoContextIDInit = FALSE; /* Free up the space allocated for the echo character data. */ if (dp->data) { free(dp->data); } free(dp); } } AWT_UNLOCK(); } /* * Class: sun_awt_motif_MTextFieldPeer * Method: getText * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_sun_awt_motif_MTextFieldPeer_getText (JNIEnv *env, jobject this) { struct TextFieldData *tdata; char *val; struct DPos *dp; jobject target; int32_t ret; jstring returnVal; AWT_LOCK(); tdata = (struct TextFieldData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData); if (tdata == NULL || tdata->comp.widget == NULL) { JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return NULL; } target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target); if ((*env)->GetCharField(env, target, textFieldIDs.echoChar) != 0) { ret = XFindContext(XtDisplay(tdata->comp.widget), (XID)tdata->comp.widget, tdata->echoContextID, (XPointer *)&dp); if ((ret == 0) && (dp != NULL)) { val = (char *)(dp->data); } else { val = ""; } } else { XtVaGetValues(tdata->comp.widget, XmNvalue, &val, NULL); } AWT_UNLOCK(); returnVal = JNU_NewStringPlatform(env, (const char *) val); if ((*env)->GetCharField(env, target, textFieldIDs.echoChar) == 0) { free(val); } return returnVal; } /* * Class: sun_awt_motif_MTextFieldPeer * Method: setEchoChar * Signature: (C)V */ JNIEXPORT void JNICALL Java_sun_awt_motif_MTextFieldPeer_setEchoChar (JNIEnv *env, jobject this, jchar c) { char *val; char *cval; struct TextFieldData *tdata; struct DPos *dp; int32_t i; size_t len; int32_t ret; AWT_LOCK(); tdata = (struct TextFieldData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData); if (tdata == NULL || tdata->comp.widget == NULL) { JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return; } XtVaGetValues(tdata->comp.widget, XmNvalue, &cval, NULL); DASSERT(c != 0 || tdata->echoContextIDInit); if (!tdata->echoContextIDInit) { tdata->echoContextID = XUniqueContext(); tdata->echoContextIDInit = TRUE; } ret = XFindContext(XtDisplay(tdata->comp.widget), (XID)(tdata->comp.widget), tdata->echoContextID, (XPointer *)&dp); /* * Fix for BugTraq ID 4307281. * Special case for setting echo char to 0: * - remove the callback and X context associated with echo character; * - restore the original text. */ if (c == 0) { XtRemoveCallback(tdata->comp.widget, XmNmodifyVerifyCallback, (XtCallbackProc) echoChar, NULL); if (ret == 0 && dp != NULL) { /* Remove the X context associated with echo character. */ XDeleteContext(XtDisplay(tdata->comp.widget), (XID)(tdata->comp.widget), tdata->echoContextID); tdata->echoContextIDInit = FALSE; /* Restore the original text. */ if (dp->data != NULL) { val = (char *)(dp->data); } else { val = ""; } XtVaSetValues(tdata->comp.widget, XmNvalue, val, NULL); /* Free up the space allocated for the echo character data. */ if (dp->data) { free(dp->data); } free(dp); } AWT_UNLOCK(); return; } if (ret != 0) { dp = NULL; } if (dp != NULL) { /* Fix bug 4124697: cannot change setEchoChar twice on Motif */ XtRemoveCallback(tdata->comp.widget, XmNmodifyVerifyCallback, (XtCallbackProc) echoChar, NULL); } else { if ((int32_t) strlen(cval) > ECHO_BUFFER_LEN) { val = (char *) malloc(strlen(cval) + 1); } else { val = (char *) malloc(ECHO_BUFFER_LEN + 1); } if (val == NULL) { JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); AWT_UNLOCK(); return; } if (cval != NULL) { strcpy(val, cval); } else { *val = '\0'; } dp = (struct DPos *) malloc(sizeof(struct DPos)); dp->x = -1; dp->data = (void *) val; } dp->echoC = c; len = strlen(cval); for (i = 0; i < len; i++) { cval[i] = (char) (c); } XtVaSetValues(tdata->comp.widget, XmNvalue, cval, NULL); ret = XSaveContext(XtDisplay(tdata->comp.widget), (XID)tdata->comp.widget, tdata->echoContextID, (XPointer)dp); if (ret == 0) { XtAddCallback(tdata->comp.widget, XmNmodifyVerifyCallback, (XtCallbackProc) echoChar, NULL); } AWT_UNLOCK(); } /* * Class: sun_awt_motif_MTextFieldPeer * Method: setFont * Signature: (Ljava/awt/Font;)V */ JNIEXPORT void JNICALL Java_sun_awt_motif_MTextFieldPeer_setFont (JNIEnv *env, jobject this, jobject f) { struct TextFieldData *tdata; struct FontData *fdata; XmFontListEntry fontentry; XmFontList fontlist; char *err; AWT_LOCK(); if (JNU_IsNull(env, f)) { JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return; } fdata = awtJNI_GetFontData(env, f, &err); if (fdata == NULL) { JNU_ThrowInternalError(env, err); AWT_UNLOCK(); return; } tdata = (struct TextFieldData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData); if (tdata == NULL || tdata->comp.widget == NULL) { JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return; } if (awtJNI_IsMultiFont(env, f)) { if (fdata->xfs == NULL) { fdata->xfs = awtJNI_MakeFontSet(env, f); } if (fdata->xfs != NULL) { fontentry = XmFontListEntryCreate("labelFont", XmFONT_IS_FONTSET, (XtPointer) (fdata->xfs)); fontlist = XmFontListAppendEntry(NULL, fontentry); /* * Some versions of motif have a bug in * XmFontListEntryFree() which causes it to free more than it * should. Use XtFree() instead. See O'Reilly's * Motif Reference Manual for more information. */ XmFontListEntryFree(&fontentry); } else { fontlist = XmFontListCreate(fdata->xfont, "labelFont"); } } else { fontlist = XmFontListCreate(fdata->xfont, "labelFont"); } if (fontlist != NULL) { XtVaSetValues(tdata->comp.widget, XmNfontList, fontlist, NULL); XmFontListFree(fontlist); } else { JNU_ThrowNullPointerException(env, "NullPointerException"); } AWT_UNLOCK(); } /* * Class: sun_awt_motif_MTextFieldPeer * Method: setCaretPosition * Signature: (I)V */ JNIEXPORT void JNICALL Java_sun_awt_motif_MTextFieldPeer_setCaretPosition (JNIEnv *env, jobject this, jint pos) { struct TextFieldData *tdata; AWT_LOCK(); tdata = (struct TextFieldData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData); if (tdata == NULL || tdata->comp.widget == NULL) { JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return; } XmTextSetInsertionPosition(tdata->comp.widget, (XmTextPosition) pos); AWT_FLUSH_UNLOCK(); } /* * Class: sun_awt_motif_MTextFieldPeer * Method: getCaretPosition * Signature: ()I */ JNIEXPORT jint JNICALL Java_sun_awt_motif_MTextFieldPeer_getCaretPosition (JNIEnv *env, jobject this) { struct TextFieldData *tdata; XmTextPosition pos; AWT_LOCK(); tdata = (struct TextFieldData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData); if (tdata == NULL || tdata->comp.widget == NULL) { JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return 0; } pos = XmTextGetInsertionPosition(tdata->comp.widget); AWT_UNLOCK(); return (jint) pos; } /* To be fully implemented in a future release * * Class: sun_awt_windows_MTextFieldPeer * Method: getIndexAtPoint * Signature: (Ljava/awt/Point;)I * JNIEXPORT jint JNICALL Java_sun_awt_motif_MTextFieldPeer_getIndexAtPoint(JNIEnv *env, jobject self, jint x, jint y) { struct ComponentData *tdata; XmTextPosition pos; AWT_LOCK(); tdata = (struct ComponentData *) JNU_GetLongFieldAsPtr(env,self,mComponentPeerIDs.pData); if (tdata == NULL || tdata->comp.widget == NULL) { JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return -1; } pos = XmTextFieldXYToPos(tdata->widget, x, y); AWT_UNLOCK(); return (jint) pos; } */ /* To be fully implemented in a future release * * Class: sun_awt_windows_MTextFieldPeer * Method: getCharacterBounds * Signature: (I)Ljava/awt/Rectangle; * JNIEXPORT jobject JNICALL Java_sun_awt_motif_MTextFieldPeer_getCharacterBounds(JNIEnv *env, jobject self, jint i) { #define TextF_FontAscent(tfg) (((XmTextFieldWidget)(tfg)) -> \ text.font_ascent) #define TextF_FontDescent(tfg) (((XmTextFieldWidget)(tfg)) -> \ text.font_descent) struct ComponentData *tdata; jobject rect=NULL; Position x=0, y=0; Position next_x=0, next_y=0; int32_t w=0, h=0; AWT_LOCK(); tdata = (struct ComponentData *) JNU_GetLongFieldAsPtr(env,self,mComponentPeerIDs.pData); if (tdata == NULL || tdata->widget == NULL) { JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return (jobject) NULL; } XmTextFieldPosToXY(tdata->widget, i, &x, &y); y -= TextF_FontAscent(tdata->widget); XmTextFieldPosToXY(tdata->widget, i+1, &next_x, &next_y); w = next_x - x; h = TextF_FontAscent(tdata->widget) + TextF_FontDescent(tdata->widget); AWT_UNLOCK(); if (w>0) { jclass clazz; jmethodID mid; clazz = (*env)->FindClass(env, "java/awt/Rectangle"); mid = (*env)->GetMethodID(env, clazz, "", "(IIII)V"); if (mid != NULL) { rect = (*env)->NewObject(env, clazz, mid, x, y, w, h); if ((*env)->ExceptionOccurred(env)) { return NULL; } } } return rect; } */