blob: 889d82b718b13fa6c42914ab7b76f986bc35e32e [file] [log] [blame]
/*
* 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 <Xm/VirtKeys.h>
#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 <jni.h>
#include <jni_util.h>
#include <Xm/DropSMgr.h>
#include <Xm/TextFP.h> /* 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(<String>) 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, "<init>", "(IIII)V");
if (mid != NULL) {
rect = (*env)->NewObject(env, clazz, mid, x, y, w, h);
if ((*env)->ExceptionOccurred(env)) {
return NULL;
}
}
}
return rect;
}
*/