/* * Copyright 1995-2004 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 "awt_p.h" #include #include #include #include #include #include "awt_p.h" #include "java_awt_FileDialog.h" #include "java_awt_event_MouseWheelEvent.h" #include "sun_awt_motif_MFileDialogPeer.h" #include "sun_awt_motif_MComponentPeer.h" #include "multi_font.h" #include "awt_Component.h" #include #include #include #define MAX_DIR_PATH_LEN 1024 extern void Text_handlePaste(Widget w, XtPointer client_data, XEvent * event, Boolean * cont); extern struct MComponentPeerIDs mComponentPeerIDs; extern AwtGraphicsConfigDataPtr copyGraphicsConfigToPeer(JNIEnv *env, jobject this); /* fieldIDs for FileDialog fields and methods that may be accessed from C */ static struct FileDialogIDs { jfieldID mode; jfieldID file; } fileDialogIDs; /* the field to store the default search procedure */ static XmSearchProc DefaultSearchProc = NULL; /* mouse wheel handler for scrolling */ void File_handleWheel(Widget w, XtPointer client_data, XEvent* event, Boolean* cont); /* * Class: java_awt_FileDialog * Method: initIDs * Signature: ()V */ /* This function gets called from the static initializer for FileDialog.java to initialize the fieldIDs for fields that may be accessed from C */ JNIEXPORT void JNICALL Java_java_awt_FileDialog_initIDs (JNIEnv *env, jclass cls) { fileDialogIDs.mode = (*env)->GetFieldID(env, cls, "mode", "I"); fileDialogIDs.file = (*env)->GetFieldID(env, cls, "file", "Ljava/lang/String;"); DASSERT(fileDialogIDs.mode != NULL); DASSERT(fileDialogIDs.file != NULL); } /* * client_data is MFileDialogPeer instance pointer */ static void FileDialog_OK(Widget w, void *client_data, XmFileSelectionBoxCallbackStruct * call_data) { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); jobject this = (jobject) client_data; struct FrameData *fdata; char *file; jstring jstr; XmStringContext stringContext; XmStringDirection direction; XmStringCharSet charset; Boolean separator; fdata = (struct FrameData *)JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData); if ((*env)->EnsureLocalCapacity(env, 1) < 0) return; if (!XmStringInitContext(&stringContext, call_data->value)) return; if (!XmStringGetNextSegment(stringContext, &file, &charset, &direction, &separator)) file = NULL; if (file == NULL) jstr = NULL; else jstr = JNU_NewStringPlatform(env, (const char *) file); if (jstr != 0) { JNU_CallMethodByName(env, NULL, this, "handleSelected", "(Ljava/lang/String;)V", jstr); (*env)->DeleteLocalRef(env, jstr); } if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionDescribe(env); (*env)->ExceptionClear(env); } XmStringFreeContext(stringContext); if (file != NULL) XtFree(file); } /* * client_data is MFileDialogPeer instance pointer */ static void FileDialog_CANCEL(Widget w, void *client_data, XmFileSelectionBoxCallbackStruct * call_data) { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); jobject this = (jobject) client_data; struct FrameData *fdata; fdata = (struct FrameData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData); JNU_CallMethodByName(env, NULL, (jobject) client_data, "handleCancel", "()V"); if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionDescribe(env); (*env)->ExceptionClear(env); } } /* * client_data is MFileDialogPeer instance pointer */ static void FileDialog_quit(Widget w, XtPointer client_data, XtPointer call_data) { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); JNU_CallMethodByName(env, NULL, (jobject) client_data, "handleQuit", "()V"); if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionDescribe(env); (*env)->ExceptionClear(env); } } static void setDeleteCallback(jobject this, struct FrameData *wdata) { Atom xa_WM_DELETE_WINDOW; Atom xa_WM_PROTOCOLS; XtVaSetValues(wdata->winData.shell, XmNdeleteResponse, XmDO_NOTHING, NULL); xa_WM_DELETE_WINDOW = XmInternAtom(XtDisplay(wdata->winData.shell), "WM_DELETE_WINDOW", False); xa_WM_PROTOCOLS = XmInternAtom(XtDisplay(wdata->winData.shell), "WM_PROTOCOLS", False); XmAddProtocolCallback(wdata->winData.shell, xa_WM_PROTOCOLS, xa_WM_DELETE_WINDOW, FileDialog_quit, (XtPointer) this); } void setFSBDirAndFile(Widget w, char *dir, char *file, XmString *ffiles, int count) { Widget textField, list; char dirbuf[MAX_DIR_PATH_LEN]; XmString xim, item; size_t lastSelect; dirbuf[0] = (char) '\0'; if (dir != NULL && strlen(dir) < MAX_DIR_PATH_LEN) strcpy(dirbuf, dir); /* -----> make sure dir ends in '/' */ if (dirbuf[0] != (char) '\0') { if (dirbuf[strlen(dirbuf) - 1] != (char) '/') strcat(dirbuf, "/"); } else { getcwd(dirbuf, MAX_DIR_PATH_LEN - 16); strcat(dirbuf, "/"); } strcat(dirbuf, "[^.]*"); xim = XmStringCreate(dirbuf, XmSTRING_DEFAULT_CHARSET); XtVaSetValues(w, XmNdirMask, xim, NULL); if (ffiles != NULL) XtVaSetValues(w, XmNfileListItems, (count > 0) ? ffiles : NULL, XmNfileListItemCount, count, XmNlistUpdated, True, NULL); XmStringFree(xim); /* * Select the filename from the filelist if it exists. */ textField = XmFileSelectionBoxGetChild(w, XmDIALOG_TEXT); list = XmFileSelectionBoxGetChild(w, XmDIALOG_LIST); if (textField != 0 && file != 0) { lastSelect = strlen(file); XtVaSetValues(textField, XmNvalue, file, NULL); XmTextFieldSetSelection(textField, 0, lastSelect, CurrentTime); item = XmStringCreateLocalized(file); XmListSelectItem(list, item, NULL); XmStringFree(item); } } static void changeBackground(Widget w, void *bg) { /* ** This is a work-around for bug 4325443, caused by motif bug 4345559, ** XmCombobox dosn't return all children, so give it some help ... */ Widget grabShell; grabShell = XtNameToWidget(w, "GrabShell"); if (grabShell != NULL) { awt_util_mapChildren(grabShell, changeBackground, 0, (void *) bg); } XmChangeColor(w, (Pixel) bg); } void ourSearchProc(Widget w, XtPointer p) { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); struct FrameData *wdata; XtPointer peer; jobject this; jboolean res; char * dir = NULL; jstring dir_o; int32_t i, filecount = 0; XmString * filelist = NULL; jobjectArray nffiles = NULL; jclass clazz = NULL; jstring jfilename = NULL; char * cfilename = NULL; XmFileSelectionBoxCallbackStruct * vals = (XmFileSelectionBoxCallbackStruct *)p; XtVaGetValues(w, XmNuserData, &peer, NULL); this = (jobject)peer; if (JNU_IsNull(env, this) ) { return; } wdata = (struct FrameData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData); if (wdata == 0 || wdata->winData.comp.widget == 0 || wdata->winData.shell == 0 || p == NULL ) { return; } if ((*env)->EnsureLocalCapacity(env, 1) < 0) { return; } if (DefaultSearchProc != NULL) { /* Unmap the widget temporary. If it takes a long time to generate the list items some visual artifacts may be caused. However, we need to do this to have the widget that works as we expect. */ XtSetMappedWhenManaged(w, False); /* Call the default Motif search procedure to take the native filtered file list. */ DefaultSearchProc(w, vals); XtSetMappedWhenManaged(w, True); XtVaGetValues(w, XmNlistItemCount, &filecount, XmNlistItems, &filelist, NULL); /* We need to construct the new String array to pass it to the Java code. */ clazz = (*env)->FindClass(env, "java/lang/String"); /* It is ok if filecount is 0. */ nffiles = (*env)->NewObjectArray(env, filecount, clazz, NULL); if (JNU_IsNull(env, nffiles)) { nffiles = NULL; JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); } else { for (i = 0; i < filecount; i++) { DASSERT(filelist[i] != NULL); XmStringGetLtoR(filelist[i], XmFONTLIST_DEFAULT_TAG, &cfilename); jfilename = JNU_NewStringPlatform(env, cfilename); if (JNU_IsNull(env, jfilename)) { XtFree(cfilename); nffiles = NULL; JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); break; } (*env)->SetObjectArrayElement(env, nffiles, i, jfilename); (*env)->DeleteLocalRef(env, jfilename); XtFree(cfilename); } } } XmStringGetLtoR(vals->dir, XmFONTLIST_DEFAULT_TAG, &dir); dir_o = JNU_NewStringPlatform(env, dir); res = JNU_CallMethodByName(env, NULL, this, "proceedFiltering", "(Ljava/lang/String;[Ljava/lang/String;Z)Z", dir_o, nffiles, awt_currentThreadIsPrivileged(env)).z; if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionDescribe(env); (*env)->ExceptionClear(env); } XtVaSetValues(w, XmNlistUpdated, res, NULL); (*env)->DeleteLocalRef(env, dir_o); free(dir); } /* * Class: sun_awt_motif_MFileDialogPeer * Method: create * Signature: (Lsun/awt/motif/MComponentPeer;)V */ JNIEXPORT void JNICALL Java_sun_awt_motif_MFileDialogPeer_create (JNIEnv *env, jobject this, jobject parent) { struct FrameData *fdata; struct CanvasData *wdata; int32_t argc; #define MAX_ARGC 20 Arg args[MAX_ARGC]; Widget child, textField, dirList, fileList; XmString xim; Pixel bg; jobject target; jstring file; jobject globalRef = awtJNI_CreateAndSetGlobalRef(env, this); AwtGraphicsConfigDataPtr adata; #ifndef NOMODALFIX extern void awt_shellPoppedUp(Widget shell, XtPointer c, XtPointer d); extern void awt_shellPoppedDown(Widget shell, XtPointer c, XtPointer d); #endif NOMODALFIX target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target); if (JNU_IsNull(env, parent) || JNU_IsNull(env, target)) { JNU_ThrowNullPointerException(env, "NullPointerException"); return; } AWT_LOCK(); adata = copyGraphicsConfigToPeer(env, this); wdata = (struct CanvasData *) JNU_GetLongFieldAsPtr(env,parent,mComponentPeerIDs.pData); fdata = ZALLOC(FrameData); JNU_SetLongFieldFromPtr(env,this,mComponentPeerIDs.pData,fdata); if (fdata == NULL) { JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError"); AWT_UNLOCK(); return; } XtVaGetValues(wdata->comp.widget, XmNbackground, &bg, NULL); /* * XXX: this code uses FrameData but doesn't bother to init a lot * of its memebers. This confuses the hell out of the code in * awt_TopLevel.c that gets passes such half-inited FrameData. */ fdata->decor = MWM_DECOR_ALL; argc = 0; XtSetArg(args[argc], XmNmustMatch, False); argc++; XtSetArg(args[argc], XmNautoUnmanage, False); argc++; XtSetArg(args[argc], XmNbackground, bg); argc++; XtSetArg(args[argc], XmNvisual, adata->awt_visInfo.visual); argc++; XtSetArg(args[argc], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); argc++; XtSetArg (args[argc], XmNscreen, ScreenOfDisplay(awt_display, adata->awt_visInfo.screen)); argc++; XtSetArg(args[argc], XmNuserData, (XtPointer)globalRef); argc++; XtSetArg(args[argc], XmNresizePolicy, XmRESIZE_NONE); argc++; XtSetArg(args[argc], XmNbuttonFontList, getMotifFontList()); argc++; XtSetArg(args[argc], XmNlabelFontList, getMotifFontList()); argc++; XtSetArg(args[argc], XmNtextFontList, getMotifFontList()); argc++; DASSERT(!(argc > MAX_ARGC)); fdata->winData.comp.widget = XmCreateFileSelectionDialog(wdata->shell, "", args, argc); fdata->winData.shell = XtParent(fdata->winData.comp.widget); awt_util_mapChildren(fdata->winData.shell, changeBackground, 0, (void *) bg); child = XmFileSelectionBoxGetChild(fdata->winData.comp.widget, XmDIALOG_HELP_BUTTON); /* We should save a pointer to the default search procedure to do some things that we cannot do else. For instance, apply the native pattern. */ XtVaGetValues(fdata->winData.comp.widget, XmNfileSearchProc, &DefaultSearchProc, NULL); XtVaSetValues(fdata->winData.comp.widget, XmNfileSearchProc, ourSearchProc, NULL); /* * Get textfield in FileDialog. */ textField = XmFileSelectionBoxGetChild(fdata->winData.comp.widget, XmDIALOG_TEXT); if (child != NULL) { /* * Workaround for Bug Id 4415659. * If the dialog child is unmanaged before the dialog is managed, * the Motif drop site hierarchy may be broken if we associate * a drop target with the dialog before it is shown. */ XtSetMappedWhenManaged(fdata->winData.shell, False); XtManageChild(fdata->winData.comp.widget); XtUnmanageChild(fdata->winData.comp.widget); XtSetMappedWhenManaged(fdata->winData.shell, True); XtUnmanageChild(child); } if (!awtJNI_IsMultiFont(env, awtJNI_GetFont(env, this))) { /* This process should not be done other than English language locale. */ child = XmFileSelectionBoxGetChild(fdata->winData.comp.widget, XmDIALOG_DEFAULT_BUTTON); if (child != NULL) { XmString xim; switch ((*env)->GetIntField(env, target, fileDialogIDs.mode)) { case java_awt_FileDialog_LOAD: xim = XmStringCreate("Open", "labelFont"); XtVaSetValues(child, XmNlabelString, xim, NULL); XmStringFree(xim); break; case java_awt_FileDialog_SAVE: xim = XmStringCreate("Save", "labelFont"); XtVaSetValues(child, XmNlabelString, xim, NULL); XmStringFree(xim); break; default: break; } } } XtAddCallback(fdata->winData.comp.widget, XmNokCallback, (XtCallbackProc) FileDialog_OK, (XtPointer) globalRef); XtAddCallback(fdata->winData.comp.widget, XmNcancelCallback, (XtCallbackProc) FileDialog_CANCEL, (XtPointer) globalRef); #ifndef NOMODALFIX XtAddCallback(fdata->winData.shell, XtNpopupCallback, awt_shellPoppedUp, NULL); XtAddCallback(fdata->winData.shell, XtNpopdownCallback, awt_shellPoppedDown, NULL); #endif NOMODALFIX setDeleteCallback(globalRef, fdata); if (textField != NULL) { /* * Insert event handler to correctly process cut/copy/paste keys * such that interaction with our own clipboard mechanism will work * properly. * * The Text_handlePaste() event handler is also used by both * TextField/TextArea. */ XtInsertEventHandler(textField, KeyPressMask, False, Text_handlePaste, (XtPointer) globalRef, XtListHead); } /* To get wheel scrolling, we add an event handler to the directory list and * file list widgets to handle mouse wheels */ dirList = XmFileSelectionBoxGetChild(fdata->winData.comp.widget, XmDIALOG_DIR_LIST); if (dirList != NULL) { XtAddEventHandler(dirList, ButtonPressMask, False, File_handleWheel, (XtPointer) globalRef); } fileList = XmFileSelectionBoxGetChild(fdata->winData.comp.widget, XmDIALOG_LIST); if (fileList != NULL) { XtAddEventHandler(fileList, ButtonPressMask, False, File_handleWheel, (XtPointer) globalRef); } file = (*env)->GetObjectField(env, target, fileDialogIDs.file); if (JNU_IsNull(env, file)) { setFSBDirAndFile(fdata->winData.comp.widget, ".", "", NULL, -1); } else { char *fileString; fileString = (char *) JNU_GetStringPlatformChars(env, file, NULL); setFSBDirAndFile(fdata->winData.comp.widget, ".", fileString, NULL, -1); JNU_ReleaseStringPlatformChars(env, file, (const char *) fileString); } AWT_UNLOCK(); } /* Event handler for making scrolling happen when the mouse wheel is rotated */ void File_handleWheel(Widget w, XtPointer client_data, XEvent* event, Boolean* cont) { unsigned int btn; Widget scrolledWindow = NULL; /* only registered for ButtonPress, so don't need to check event type */ btn = event->xbutton.button; /* wheel up and wheel down show up as button 4 and 5, respectively */ if (btn == 4 || btn == 5) { scrolledWindow = XtParent(w); if (scrolledWindow == NULL) { return; } awt_util_do_wheel_scroll(scrolledWindow, java_awt_event_MouseWheelEvent_WHEEL_UNIT_SCROLL, 3, btn == 4 ? -1 : 1); } } /* * Class: sun_awt_motif_MFileDialogPeer * Method: pReshape * Signature: (IIII)V */ JNIEXPORT void JNICALL Java_sun_awt_motif_MFileDialogPeer_pReshape (JNIEnv *env, jobject this, jint x, jint y, jint w, jint h) { struct FrameData *wdata; AWT_LOCK(); wdata = (struct FrameData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData); if (wdata == NULL || wdata->winData.shell == NULL) { JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return; } /* GES: AVH's hack from awt_util.c: * Motif ignores attempts to move a toplevel window to 0,0. * Instead we set the position to 1,1. The expected value is * returned by Frame.getBounds() since it uses the internally * held rectangle rather than querying the peer. */ if ((x == 0) && (y == 0)) { XtVaSetValues(wdata->winData.shell, XmNx, 1, XmNy, 1, NULL); } XtVaSetValues(wdata->winData.shell, XtNx, (XtArgVal) x, XtNy, (XtArgVal) y, NULL); AWT_FLUSH_UNLOCK(); } /* * Class: sun_awt_motif_MFileDialogPeer * Method: pDispose * Signature: ()V */ JNIEXPORT void JNICALL Java_sun_awt_motif_MFileDialogPeer_pDispose (JNIEnv *env, jobject this) { struct FrameData *wdata; AWT_LOCK(); wdata = (struct FrameData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData); if (wdata == NULL || wdata->winData.comp.widget == NULL || wdata->winData.shell == NULL) { JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return; } XtUnmanageChild(wdata->winData.shell); awt_util_consumeAllXEvents(wdata->winData.shell); XtDestroyWidget(wdata->winData.shell); free((void *) wdata); JNU_SetLongFieldFromPtr(env,this,mComponentPeerIDs.pData,NULL); awtJNI_DeleteGlobalRef(env, this); AWT_UNLOCK(); } /* * Class: sun_awt_motif_MFileDialogPeer * Method: pShow * Signature: ()V */ JNIEXPORT void JNICALL Java_sun_awt_motif_MFileDialogPeer_pShow (JNIEnv *env, jobject this) { struct FrameData *wdata; XmString dirMask = NULL; AWT_LOCK(); wdata = (struct FrameData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData); if (wdata == NULL || wdata->winData.comp.widget == NULL || wdata->winData.shell == NULL) { JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return; } XtManageChild(wdata->winData.comp.widget); AWT_FLUSH_UNLOCK(); } /* * Class: sun_awt_motif_MFileDialogPeer * Method: pHide * Signature: ()V */ JNIEXPORT void JNICALL Java_sun_awt_motif_MFileDialogPeer_pHide (JNIEnv *env, jobject this) { struct FrameData *wdata; AWT_LOCK(); wdata = (struct FrameData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData); if (wdata == NULL || wdata->winData.comp.widget == NULL || wdata->winData.shell == NULL) { JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return; } if (XtIsManaged(wdata->winData.comp.widget)) { XtUnmanageChild(wdata->winData.comp.widget); } AWT_FLUSH_UNLOCK(); } /* * Class: sun_awt_motif_MFileDialogPeer * Method: setFileEntry * Signature: (Ljava/lang/String;Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_sun_awt_motif_MFileDialogPeer_setFileEntry (JNIEnv *env, jobject this, jstring dir, jstring file, jobjectArray ffiles) { struct ComponentData *cdata; char *cdir; char *cfile; char *cf; struct FrameData *wdata; int32_t length, i; XmString * files = NULL; jstring jf; AWT_LOCK(); wdata = (struct FrameData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData); if (wdata == NULL || wdata->winData.comp.widget == NULL) { JNU_ThrowNullPointerException(env, "NullPointerException"); return; } cdir = (JNU_IsNull(env, dir)) ? NULL : (char *) JNU_GetStringPlatformChars(env, dir, NULL); cfile = (JNU_IsNull(env, file)) ? NULL : (char *) JNU_GetStringPlatformChars(env, file, NULL); if (ffiles != NULL) { length = (*env)->GetArrayLength(env, ffiles); files = (XmString*)calloc(length, sizeof(XmString)); for (i = 0; i < length; i++) { jf = (jstring)(*env)->GetObjectArrayElement(env, ffiles, i); cf = (char *) JNU_GetStringPlatformChars(env, jf, NULL); if ((*env)->GetStringLength(env, jf) == 0 && length == 1) { length = 0; files[0] = NULL; } else files[i] = XmStringCreateLocalized(cf); if (cf) JNU_ReleaseStringPlatformChars(env, jf, (const char *) cf); } setFSBDirAndFile(wdata->winData.comp.widget, (cdir) ? cdir : "", (cfile) ? cfile : "", files, length); while(i > 0) { XmStringFree(files[--i]); } if (files != NULL) { free(files); } } else setFSBDirAndFile(wdata->winData.comp.widget, (cdir) ? cdir : "", (cfile) ? cfile : "", NULL, -1); if (cdir) { JNU_ReleaseStringPlatformChars(env, dir, (const char *) cdir); } if (cfile) { JNU_ReleaseStringPlatformChars(env, file, (const char *) cfile); } AWT_FLUSH_UNLOCK(); } static void changeFont(Widget w, void *fontList) { XtVaSetValues(w, XmNfontList, fontList, NULL); } /* * Class: sun_awt_motif_MFileDialogPeer * Method: setFont * Signature: (Ljava/awt/Font;)V */ JNIEXPORT void JNICALL Java_sun_awt_motif_MFileDialogPeer_setFont (JNIEnv *env, jobject this, jobject f) { struct ComponentData *tdata; struct FontData *fdata; XmFontListEntry fontentry; XmFontList fontlist; char *err; if (JNU_IsNull(env, f)) { JNU_ThrowNullPointerException(env, "NullPointerException"); return; } AWT_LOCK(); fdata = awtJNI_GetFontData(env, f, &err); if (fdata == NULL) { JNU_ThrowInternalError(env, err); AWT_UNLOCK(); return; } tdata = (struct ComponentData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData); if (tdata == NULL || tdata->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) { /* setting the fontlist in the FileSelectionBox is not good enough -- you have to set the resource for all the descendants individually */ awt_util_mapChildren(tdata->widget, changeFont, 1, (void *)fontlist); XmFontListFree(fontlist); } else { JNU_ThrowNullPointerException(env, "NullPointerException"); } AWT_UNLOCK(); } /* * Class: sun_awt_motif_MFileDialogPeer * Method: insertReplaceFileDialogText * Signature: (Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_sun_awt_motif_MFileDialogPeer_insertReplaceFileDialogText (JNIEnv *env, jobject this, jstring l) { struct ComponentData *cdata; char *cl; XmTextPosition start, end; Widget textField; jobject font; /* * Replaces the text in the FileDialog's textfield with the passed * string. */ AWT_LOCK(); cdata = (struct ComponentData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData); if (cdata == NULL || cdata->widget == NULL) { JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return; } textField = XmFileSelectionBoxGetChild(cdata->widget, XmDIALOG_TEXT); if (textField == NULL) { JNU_ThrowNullPointerException(env, "Null TextField in FileDialog"); AWT_UNLOCK(); return; } font = awtJNI_GetFont(env, this); if (JNU_IsNull(env, l)) { cl = NULL; } else { /* * We use makePlatformCString() to convert unicode to EUC here, * although output only components (Label/Button/Menu..) * is not using make/allocCString() functions anymore. * Because Motif TextFiled widget does not support multi-font * compound string. */ cl = (char *) JNU_GetStringPlatformChars(env, l, NULL); } if (!XmTextGetSelectionPosition(textField, &start, &end)) { start = end = XmTextGetInsertionPosition(textField); } XmTextReplace(textField, start, end, cl); if (cl != NULL && cl !="") { JNU_ReleaseStringPlatformChars(env, l, cl); } AWT_FLUSH_UNLOCK(); }