jdk/src/solaris/native/sun/awt/awt_FileDialog.c
changeset 1192 715cf9378c53
parent 1051 90cf935adb35
parent 1191 f142c1da78c2
child 1193 41afb8ee8f45
equal deleted inserted replaced
1051:90cf935adb35 1192:715cf9378c53
     1 /*
       
     2  * Copyright 1995-2004 Sun Microsystems, Inc.  All Rights Reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 
       
    26 #ifdef HEADLESS
       
    27     #error This file should not be included in headless library
       
    28 #endif
       
    29 
       
    30 #include "awt_p.h"
       
    31 #include <Xm/AtomMgr.h>
       
    32 #include <Xm/Protocols.h>
       
    33 #include <sys/param.h>
       
    34 #include <string.h>
       
    35 #include <stdlib.h>
       
    36 #include "awt_p.h"
       
    37 #include "java_awt_FileDialog.h"
       
    38 #include "java_awt_event_MouseWheelEvent.h"
       
    39 #include "sun_awt_motif_MFileDialogPeer.h"
       
    40 #include "sun_awt_motif_MComponentPeer.h"
       
    41 #include "multi_font.h"
       
    42 
       
    43 #include "awt_Component.h"
       
    44 
       
    45 #include <jni.h>
       
    46 #include <jni_util.h>
       
    47 #include <Xm/FileSB.h>
       
    48 
       
    49 #define MAX_DIR_PATH_LEN    1024
       
    50 
       
    51 extern void Text_handlePaste(Widget w, XtPointer client_data, XEvent * event,
       
    52                              Boolean * cont);
       
    53 
       
    54 extern struct MComponentPeerIDs mComponentPeerIDs;
       
    55 
       
    56 extern AwtGraphicsConfigDataPtr
       
    57     copyGraphicsConfigToPeer(JNIEnv *env, jobject this);
       
    58 
       
    59 /* fieldIDs for FileDialog fields and methods that may be accessed from C */
       
    60 static struct FileDialogIDs {
       
    61     jfieldID mode;
       
    62     jfieldID file;
       
    63 } fileDialogIDs;
       
    64 
       
    65 /* the field to store the default search procedure */
       
    66 static XmSearchProc DefaultSearchProc = NULL;
       
    67 
       
    68 /* mouse wheel handler for scrolling */
       
    69 void File_handleWheel(Widget w, XtPointer client_data, XEvent* event, Boolean* cont);
       
    70 
       
    71 /*
       
    72  * Class:     java_awt_FileDialog
       
    73  * Method:    initIDs
       
    74  * Signature: ()V
       
    75  */
       
    76 
       
    77 /* This function gets called from the static initializer for FileDialog.java
       
    78    to initialize the fieldIDs for fields that may be accessed from C */
       
    79 
       
    80 JNIEXPORT void JNICALL
       
    81 Java_java_awt_FileDialog_initIDs
       
    82   (JNIEnv *env, jclass cls)
       
    83 {
       
    84     fileDialogIDs.mode = (*env)->GetFieldID(env, cls, "mode", "I");
       
    85     fileDialogIDs.file =
       
    86       (*env)->GetFieldID(env, cls, "file", "Ljava/lang/String;");
       
    87 
       
    88     DASSERT(fileDialogIDs.mode != NULL);
       
    89     DASSERT(fileDialogIDs.file != NULL);
       
    90 }
       
    91 
       
    92 /*
       
    93  * client_data is MFileDialogPeer instance pointer
       
    94  */
       
    95 static void
       
    96 FileDialog_OK(Widget w,
       
    97               void *client_data,
       
    98               XmFileSelectionBoxCallbackStruct * call_data)
       
    99 {
       
   100     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
   101     jobject this = (jobject) client_data;
       
   102     struct FrameData *fdata;
       
   103     char *file;
       
   104     jstring jstr;
       
   105     XmStringContext   stringContext;
       
   106     XmStringDirection direction;
       
   107     XmStringCharSet   charset;
       
   108     Boolean           separator;
       
   109 
       
   110     fdata = (struct FrameData *)JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
       
   111 
       
   112     if ((*env)->EnsureLocalCapacity(env, 1) < 0)
       
   113         return;
       
   114 
       
   115     if (!XmStringInitContext(&stringContext, call_data->value))
       
   116         return;
       
   117 
       
   118     if (!XmStringGetNextSegment(stringContext, &file, &charset,
       
   119                                 &direction, &separator))
       
   120         file = NULL;
       
   121 
       
   122     if (file == NULL)
       
   123         jstr = NULL;
       
   124     else
       
   125         jstr = JNU_NewStringPlatform(env, (const char *) file);
       
   126 
       
   127     if (jstr != 0) {
       
   128         JNU_CallMethodByName(env, NULL, this, "handleSelected",
       
   129                              "(Ljava/lang/String;)V", jstr);
       
   130         (*env)->DeleteLocalRef(env, jstr);
       
   131     }
       
   132     if ((*env)->ExceptionOccurred(env)) {
       
   133         (*env)->ExceptionDescribe(env);
       
   134         (*env)->ExceptionClear(env);
       
   135     }
       
   136 
       
   137     XmStringFreeContext(stringContext);
       
   138     if (file != NULL)
       
   139         XtFree(file);
       
   140 }
       
   141 
       
   142 /*
       
   143  * client_data is MFileDialogPeer instance pointer
       
   144  */
       
   145 static void
       
   146 FileDialog_CANCEL(Widget w,
       
   147                   void *client_data,
       
   148                   XmFileSelectionBoxCallbackStruct * call_data)
       
   149 {
       
   150     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
   151     jobject this = (jobject) client_data;
       
   152     struct FrameData *fdata;
       
   153 
       
   154     fdata = (struct FrameData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
       
   155 
       
   156     JNU_CallMethodByName(env, NULL, (jobject) client_data, "handleCancel", "()V");
       
   157     if ((*env)->ExceptionOccurred(env)) {
       
   158         (*env)->ExceptionDescribe(env);
       
   159         (*env)->ExceptionClear(env);
       
   160     }
       
   161 }
       
   162 
       
   163 
       
   164 /*
       
   165  * client_data is MFileDialogPeer instance pointer
       
   166  */
       
   167 static void
       
   168 FileDialog_quit(Widget w,
       
   169                 XtPointer client_data,
       
   170                 XtPointer call_data)
       
   171 {
       
   172     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
   173 
       
   174     JNU_CallMethodByName(env, NULL, (jobject) client_data, "handleQuit", "()V");
       
   175     if ((*env)->ExceptionOccurred(env)) {
       
   176         (*env)->ExceptionDescribe(env);
       
   177         (*env)->ExceptionClear(env);
       
   178     }
       
   179 }
       
   180 
       
   181 static void
       
   182 setDeleteCallback(jobject this, struct FrameData *wdata)
       
   183 {
       
   184     Atom xa_WM_DELETE_WINDOW;
       
   185     Atom xa_WM_PROTOCOLS;
       
   186 
       
   187     XtVaSetValues(wdata->winData.shell,
       
   188                   XmNdeleteResponse, XmDO_NOTHING,
       
   189                   NULL);
       
   190     xa_WM_DELETE_WINDOW = XmInternAtom(XtDisplay(wdata->winData.shell),
       
   191                                        "WM_DELETE_WINDOW", False);
       
   192     xa_WM_PROTOCOLS = XmInternAtom(XtDisplay(wdata->winData.shell),
       
   193                                    "WM_PROTOCOLS", False);
       
   194 
       
   195     XmAddProtocolCallback(wdata->winData.shell,
       
   196                           xa_WM_PROTOCOLS,
       
   197                           xa_WM_DELETE_WINDOW,
       
   198                           FileDialog_quit, (XtPointer) this);
       
   199 }
       
   200 
       
   201 void
       
   202 setFSBDirAndFile(Widget w, char *dir, char *file,
       
   203                  XmString *ffiles, int count)
       
   204 {
       
   205     Widget textField, list;
       
   206     char dirbuf[MAX_DIR_PATH_LEN];
       
   207     XmString xim, item;
       
   208     size_t lastSelect;
       
   209 
       
   210     dirbuf[0] = (char) '\0';
       
   211 
       
   212     if (dir != NULL && strlen(dir) < MAX_DIR_PATH_LEN)
       
   213         strcpy(dirbuf, dir);
       
   214 
       
   215     /* -----> make sure dir ends in '/' */
       
   216     if (dirbuf[0] != (char) '\0') {
       
   217         if (dirbuf[strlen(dirbuf) - 1] != (char) '/')
       
   218             strcat(dirbuf, "/");
       
   219     } else {
       
   220         getcwd(dirbuf, MAX_DIR_PATH_LEN - 16);
       
   221         strcat(dirbuf, "/");
       
   222     }
       
   223 
       
   224     strcat(dirbuf, "[^.]*");
       
   225     xim = XmStringCreate(dirbuf, XmSTRING_DEFAULT_CHARSET);
       
   226     XtVaSetValues(w, XmNdirMask, xim, NULL);
       
   227 
       
   228     if (ffiles != NULL)
       
   229       XtVaSetValues(w,
       
   230                     XmNfileListItems, (count > 0) ? ffiles : NULL,
       
   231                     XmNfileListItemCount, count,
       
   232                     XmNlistUpdated, True, NULL);
       
   233 
       
   234     XmStringFree(xim);
       
   235 
       
   236     /*
       
   237      * Select the filename from the filelist if it exists.
       
   238      */
       
   239 
       
   240     textField = XmFileSelectionBoxGetChild(w, XmDIALOG_TEXT);
       
   241     list = XmFileSelectionBoxGetChild(w, XmDIALOG_LIST);
       
   242 
       
   243     if (textField != 0 && file != 0) {
       
   244         lastSelect = strlen(file);
       
   245         XtVaSetValues(textField, XmNvalue, file, NULL);
       
   246         XmTextFieldSetSelection(textField, 0, lastSelect, CurrentTime);
       
   247 
       
   248         item = XmStringCreateLocalized(file);
       
   249         XmListSelectItem(list, item, NULL);
       
   250         XmStringFree(item);
       
   251     }
       
   252 }
       
   253 
       
   254 static void
       
   255 changeBackground(Widget w, void *bg)
       
   256 {
       
   257     /*
       
   258     ** This is a work-around for bug 4325443, caused by motif bug 4345559,
       
   259     ** XmCombobox dosn't return all children, so give it some help ...
       
   260     */
       
   261     Widget grabShell;
       
   262     grabShell = XtNameToWidget(w, "GrabShell");
       
   263     if (grabShell != NULL) {
       
   264         awt_util_mapChildren(grabShell, changeBackground, 0, (void *) bg);
       
   265     }
       
   266 
       
   267     XmChangeColor(w, (Pixel) bg);
       
   268 }
       
   269 
       
   270 void
       
   271 ourSearchProc(Widget w, XtPointer p) {
       
   272     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
   273     struct FrameData *wdata;
       
   274     XtPointer peer;
       
   275     jobject this;
       
   276     jboolean res;
       
   277     char * dir = NULL;
       
   278     jstring dir_o;
       
   279     int32_t i, filecount = 0;
       
   280     XmString * filelist = NULL;
       
   281     jobjectArray nffiles = NULL;
       
   282     jclass clazz = NULL;
       
   283     jstring jfilename = NULL;
       
   284     char * cfilename = NULL;
       
   285     XmFileSelectionBoxCallbackStruct * vals = (XmFileSelectionBoxCallbackStruct *)p;
       
   286 
       
   287     XtVaGetValues(w, XmNuserData, &peer, NULL);
       
   288     this = (jobject)peer;
       
   289     if (JNU_IsNull(env, this) ) {
       
   290         return;
       
   291     }
       
   292     wdata = (struct FrameData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
       
   293     if (wdata == 0 ||
       
   294         wdata->winData.comp.widget == 0 ||
       
   295         wdata->winData.shell == 0 || p == NULL ) {
       
   296         return;
       
   297     }
       
   298 
       
   299     if ((*env)->EnsureLocalCapacity(env, 1) < 0) {
       
   300         return;
       
   301     }
       
   302 
       
   303     if (DefaultSearchProc != NULL) {
       
   304         /* Unmap the widget temporary. If it takes a long time to generate
       
   305            the list items some visual artifacts may be caused. However,
       
   306            we need to do this to have the widget that works as we expect.
       
   307          */
       
   308         XtSetMappedWhenManaged(w, False);
       
   309         /* Call the default Motif search procedure to take the
       
   310            native filtered file list.
       
   311          */
       
   312         DefaultSearchProc(w, vals);
       
   313         XtSetMappedWhenManaged(w, True);
       
   314         XtVaGetValues(w,
       
   315                       XmNlistItemCount, &filecount,
       
   316                       XmNlistItems, &filelist,
       
   317                       NULL);
       
   318         /* We need to construct the new String array to pass it to
       
   319            the Java code.
       
   320          */
       
   321         clazz = (*env)->FindClass(env, "java/lang/String");
       
   322         /* It is ok if filecount is 0. */
       
   323         nffiles = (*env)->NewObjectArray(env, filecount, clazz, NULL);
       
   324         if (JNU_IsNull(env, nffiles)) {
       
   325             nffiles = NULL;
       
   326             JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
       
   327         } else {
       
   328             for (i = 0; i < filecount; i++) {
       
   329                 DASSERT(filelist[i] != NULL);
       
   330 
       
   331                 XmStringGetLtoR(filelist[i], XmFONTLIST_DEFAULT_TAG, &cfilename);
       
   332                 jfilename = JNU_NewStringPlatform(env, cfilename);
       
   333 
       
   334                 if (JNU_IsNull(env, jfilename)) {
       
   335                     XtFree(cfilename);
       
   336                     nffiles = NULL;
       
   337                     JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
       
   338                     break;
       
   339                 }
       
   340 
       
   341                 (*env)->SetObjectArrayElement(env, nffiles, i, jfilename);
       
   342 
       
   343                 (*env)->DeleteLocalRef(env, jfilename);
       
   344                 XtFree(cfilename);
       
   345             }
       
   346         }
       
   347     }
       
   348 
       
   349     XmStringGetLtoR(vals->dir, XmFONTLIST_DEFAULT_TAG, &dir);
       
   350     dir_o = JNU_NewStringPlatform(env, dir);
       
   351     res = JNU_CallMethodByName(env, NULL, this,
       
   352                                "proceedFiltering",
       
   353                                "(Ljava/lang/String;[Ljava/lang/String;Z)Z",
       
   354                                dir_o, nffiles,
       
   355                                awt_currentThreadIsPrivileged(env)).z;
       
   356 
       
   357     if ((*env)->ExceptionOccurred(env)) {
       
   358         (*env)->ExceptionDescribe(env);
       
   359         (*env)->ExceptionClear(env);
       
   360     }
       
   361 
       
   362     XtVaSetValues(w,
       
   363                   XmNlistUpdated, res,
       
   364                   NULL);
       
   365     (*env)->DeleteLocalRef(env, dir_o);
       
   366     free(dir);
       
   367 }
       
   368 
       
   369 /*
       
   370  * Class:     sun_awt_motif_MFileDialogPeer
       
   371  * Method:    create
       
   372  * Signature: (Lsun/awt/motif/MComponentPeer;)V
       
   373  */
       
   374 JNIEXPORT void JNICALL Java_sun_awt_motif_MFileDialogPeer_create
       
   375   (JNIEnv *env, jobject this, jobject parent)
       
   376 {
       
   377     struct FrameData *fdata;
       
   378     struct CanvasData *wdata;
       
   379     int32_t argc;
       
   380 #define MAX_ARGC 20
       
   381     Arg args[MAX_ARGC];
       
   382     Widget child, textField, dirList, fileList;
       
   383     XmString xim;
       
   384     Pixel bg;
       
   385     jobject target;
       
   386     jstring file;
       
   387     jobject globalRef = awtJNI_CreateAndSetGlobalRef(env, this);
       
   388     AwtGraphicsConfigDataPtr adata;
       
   389 #ifndef NOMODALFIX
       
   390     extern void awt_shellPoppedUp(Widget shell, XtPointer c, XtPointer d);
       
   391     extern void awt_shellPoppedDown(Widget shell, XtPointer c, XtPointer d);
       
   392 #endif NOMODALFIX
       
   393 
       
   394     target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target);
       
   395 
       
   396     if (JNU_IsNull(env, parent) || JNU_IsNull(env, target)) {
       
   397         JNU_ThrowNullPointerException(env, "NullPointerException");
       
   398         return;
       
   399     }
       
   400     AWT_LOCK();
       
   401 
       
   402     adata = copyGraphicsConfigToPeer(env, this);
       
   403 
       
   404     wdata = (struct CanvasData *) JNU_GetLongFieldAsPtr(env,parent,mComponentPeerIDs.pData);
       
   405 
       
   406     fdata = ZALLOC(FrameData);
       
   407     JNU_SetLongFieldFromPtr(env,this,mComponentPeerIDs.pData,fdata);
       
   408 
       
   409     if (fdata == NULL) {
       
   410         JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
       
   411         AWT_UNLOCK();
       
   412         return;
       
   413     }
       
   414     XtVaGetValues(wdata->comp.widget, XmNbackground, &bg, NULL);
       
   415 
       
   416     /*
       
   417      * XXX: this code uses FrameData but doesn't bother to init a lot
       
   418      * of its memebers.  This confuses the hell out of the code in
       
   419      * awt_TopLevel.c that gets passes such half-inited FrameData.
       
   420      */
       
   421     fdata->decor = MWM_DECOR_ALL;
       
   422 
       
   423     argc = 0;
       
   424     XtSetArg(args[argc], XmNmustMatch, False);
       
   425     argc++;
       
   426     XtSetArg(args[argc], XmNautoUnmanage, False);
       
   427     argc++;
       
   428     XtSetArg(args[argc], XmNbackground, bg);
       
   429     argc++;
       
   430     XtSetArg(args[argc], XmNvisual, adata->awt_visInfo.visual);
       
   431     argc++;
       
   432     XtSetArg(args[argc], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL);
       
   433     argc++;
       
   434     XtSetArg (args[argc], XmNscreen,
       
   435               ScreenOfDisplay(awt_display, adata->awt_visInfo.screen));
       
   436     argc++;
       
   437     XtSetArg(args[argc], XmNuserData, (XtPointer)globalRef);
       
   438     argc++;
       
   439     XtSetArg(args[argc], XmNresizePolicy, XmRESIZE_NONE);
       
   440     argc++;
       
   441 
       
   442     XtSetArg(args[argc], XmNbuttonFontList,  getMotifFontList());
       
   443     argc++;
       
   444     XtSetArg(args[argc], XmNlabelFontList,   getMotifFontList());
       
   445     argc++;
       
   446     XtSetArg(args[argc], XmNtextFontList,    getMotifFontList());
       
   447     argc++;
       
   448 
       
   449     DASSERT(!(argc > MAX_ARGC));
       
   450 
       
   451     fdata->winData.comp.widget = XmCreateFileSelectionDialog(wdata->shell,
       
   452                                                              "",
       
   453                                                              args,
       
   454                                                              argc);
       
   455     fdata->winData.shell = XtParent(fdata->winData.comp.widget);
       
   456     awt_util_mapChildren(fdata->winData.shell, changeBackground, 0,
       
   457                          (void *) bg);
       
   458     child = XmFileSelectionBoxGetChild(fdata->winData.comp.widget,
       
   459                                        XmDIALOG_HELP_BUTTON);
       
   460 
       
   461     /* We should save a pointer to the default search procedure
       
   462        to do some things that we cannot do else. For instance,
       
   463        apply the native pattern.
       
   464      */
       
   465     XtVaGetValues(fdata->winData.comp.widget,
       
   466                   XmNfileSearchProc, &DefaultSearchProc,
       
   467                   NULL);
       
   468     XtVaSetValues(fdata->winData.comp.widget,
       
   469                   XmNfileSearchProc, ourSearchProc,
       
   470                   NULL);
       
   471 
       
   472     /*
       
   473      * Get textfield in FileDialog.
       
   474      */
       
   475     textField = XmFileSelectionBoxGetChild(fdata->winData.comp.widget,
       
   476                                            XmDIALOG_TEXT);
       
   477     if (child != NULL) {
       
   478         /*
       
   479          * Workaround for Bug Id 4415659.
       
   480          * If the dialog child is unmanaged before the dialog is managed,
       
   481          * the Motif drop site hierarchy may be broken if we associate
       
   482          * a drop target with the dialog before it is shown.
       
   483          */
       
   484         XtSetMappedWhenManaged(fdata->winData.shell, False);
       
   485         XtManageChild(fdata->winData.comp.widget);
       
   486         XtUnmanageChild(fdata->winData.comp.widget);
       
   487         XtSetMappedWhenManaged(fdata->winData.shell, True);
       
   488         XtUnmanageChild(child);
       
   489     }
       
   490     if (!awtJNI_IsMultiFont(env, awtJNI_GetFont(env, this))) {
       
   491         /* This process should not be done other than English language
       
   492            locale. */
       
   493         child = XmFileSelectionBoxGetChild(fdata->winData.comp.widget,
       
   494                                            XmDIALOG_DEFAULT_BUTTON);
       
   495         if (child != NULL) {
       
   496             XmString xim;
       
   497 
       
   498             switch ((*env)->GetIntField(env, target, fileDialogIDs.mode)) {
       
   499                 case java_awt_FileDialog_LOAD:
       
   500                     xim = XmStringCreate("Open", "labelFont");
       
   501                     XtVaSetValues(child, XmNlabelString, xim, NULL);
       
   502                     XmStringFree(xim);
       
   503                     break;
       
   504 
       
   505                 case java_awt_FileDialog_SAVE:
       
   506                     xim = XmStringCreate("Save", "labelFont");
       
   507                     XtVaSetValues(child, XmNlabelString, xim, NULL);
       
   508                     XmStringFree(xim);
       
   509                     break;
       
   510 
       
   511                 default:
       
   512                     break;
       
   513             }
       
   514         }
       
   515     }
       
   516     XtAddCallback(fdata->winData.comp.widget,
       
   517                   XmNokCallback,
       
   518                   (XtCallbackProc) FileDialog_OK,
       
   519                   (XtPointer) globalRef);
       
   520     XtAddCallback(fdata->winData.comp.widget,
       
   521                   XmNcancelCallback,
       
   522                   (XtCallbackProc) FileDialog_CANCEL,
       
   523                   (XtPointer) globalRef);
       
   524 
       
   525 #ifndef NOMODALFIX
       
   526     XtAddCallback(fdata->winData.shell,
       
   527                       XtNpopupCallback,
       
   528                       awt_shellPoppedUp,
       
   529                       NULL);
       
   530     XtAddCallback(fdata->winData.shell,
       
   531                       XtNpopdownCallback,
       
   532                       awt_shellPoppedDown,
       
   533                       NULL);
       
   534 #endif NOMODALFIX
       
   535 
       
   536     setDeleteCallback(globalRef, fdata);
       
   537 
       
   538     if (textField != NULL)  {
       
   539         /*
       
   540          * Insert event handler to correctly process cut/copy/paste keys
       
   541          * such that interaction with our own clipboard mechanism will work
       
   542          * properly.
       
   543          *
       
   544          * The Text_handlePaste() event handler is also used by both
       
   545          * TextField/TextArea.
       
   546          */
       
   547         XtInsertEventHandler(textField,
       
   548                          KeyPressMask,
       
   549                          False, Text_handlePaste, (XtPointer) globalRef,
       
   550                          XtListHead);
       
   551     }
       
   552 
       
   553     /* To get wheel scrolling, we add an event handler to the directory list and
       
   554      * file list widgets to handle mouse wheels */
       
   555     dirList = XmFileSelectionBoxGetChild(fdata->winData.comp.widget, XmDIALOG_DIR_LIST);
       
   556     if (dirList != NULL) {
       
   557         XtAddEventHandler(dirList, ButtonPressMask, False, File_handleWheel,
       
   558                           (XtPointer) globalRef);
       
   559     }
       
   560 
       
   561     fileList = XmFileSelectionBoxGetChild(fdata->winData.comp.widget, XmDIALOG_LIST);
       
   562     if (fileList != NULL) {
       
   563         XtAddEventHandler(fileList, ButtonPressMask, False, File_handleWheel,
       
   564                           (XtPointer) globalRef);
       
   565     }
       
   566 
       
   567     file = (*env)->GetObjectField(env, target, fileDialogIDs.file);
       
   568     if (JNU_IsNull(env, file)) {
       
   569         setFSBDirAndFile(fdata->winData.comp.widget, ".", "", NULL, -1);
       
   570     } else {
       
   571         char *fileString;
       
   572 
       
   573         fileString = (char *) JNU_GetStringPlatformChars(env, file, NULL);
       
   574         setFSBDirAndFile(fdata->winData.comp.widget, ".", fileString, NULL, -1);
       
   575         JNU_ReleaseStringPlatformChars(env, file, (const char *) fileString);
       
   576     }
       
   577     AWT_UNLOCK();
       
   578 }
       
   579 
       
   580 /* Event handler for making scrolling happen when the mouse wheel is rotated */
       
   581 void File_handleWheel(Widget w, XtPointer client_data, XEvent* event, Boolean* cont) {
       
   582     unsigned int btn;
       
   583     Widget scrolledWindow = NULL;
       
   584 
       
   585     /* only registered for ButtonPress, so don't need to check event type  */
       
   586     btn = event->xbutton.button;
       
   587     /* wheel up and wheel down show up as button 4 and 5, respectively */
       
   588     if (btn == 4 || btn == 5) {
       
   589         scrolledWindow = XtParent(w);
       
   590         if (scrolledWindow == NULL) {
       
   591             return;
       
   592         }
       
   593         awt_util_do_wheel_scroll(scrolledWindow,
       
   594                              java_awt_event_MouseWheelEvent_WHEEL_UNIT_SCROLL,
       
   595                              3,
       
   596                              btn == 4 ? -1 : 1);
       
   597     }
       
   598 }
       
   599 
       
   600 
       
   601 /*
       
   602  * Class:     sun_awt_motif_MFileDialogPeer
       
   603  * Method:    pReshape
       
   604  * Signature: (IIII)V
       
   605  */
       
   606 JNIEXPORT void JNICALL Java_sun_awt_motif_MFileDialogPeer_pReshape
       
   607   (JNIEnv *env, jobject this, jint x, jint y, jint w, jint h)
       
   608 {
       
   609     struct FrameData *wdata;
       
   610 
       
   611     AWT_LOCK();
       
   612     wdata = (struct FrameData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
       
   613     if (wdata == NULL || wdata->winData.shell == NULL) {
       
   614         JNU_ThrowNullPointerException(env, "NullPointerException");
       
   615         AWT_UNLOCK();
       
   616         return;
       
   617     }
       
   618     /* GES: AVH's hack from awt_util.c:
       
   619      * Motif ignores attempts to move a toplevel window to 0,0.
       
   620      * Instead we set the position to 1,1. The expected value is
       
   621      * returned by Frame.getBounds() since it uses the internally
       
   622      * held rectangle rather than querying the peer.
       
   623      */
       
   624 
       
   625     if ((x == 0) && (y == 0)) {
       
   626         XtVaSetValues(wdata->winData.shell, XmNx, 1, XmNy, 1, NULL);
       
   627     }
       
   628     XtVaSetValues(wdata->winData.shell,
       
   629                   XtNx, (XtArgVal) x,
       
   630                   XtNy, (XtArgVal) y,
       
   631                   NULL);
       
   632 
       
   633     AWT_FLUSH_UNLOCK();
       
   634 }
       
   635 
       
   636 /*
       
   637  * Class:     sun_awt_motif_MFileDialogPeer
       
   638  * Method:    pDispose
       
   639  * Signature: ()V
       
   640  */
       
   641 JNIEXPORT void JNICALL Java_sun_awt_motif_MFileDialogPeer_pDispose
       
   642   (JNIEnv *env, jobject this)
       
   643 {
       
   644     struct FrameData *wdata;
       
   645 
       
   646     AWT_LOCK();
       
   647     wdata = (struct FrameData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
       
   648     if (wdata == NULL ||
       
   649         wdata->winData.comp.widget == NULL ||
       
   650         wdata->winData.shell == NULL) {
       
   651         JNU_ThrowNullPointerException(env, "NullPointerException");
       
   652         AWT_UNLOCK();
       
   653         return;
       
   654     }
       
   655     XtUnmanageChild(wdata->winData.shell);
       
   656     awt_util_consumeAllXEvents(wdata->winData.shell);
       
   657     XtDestroyWidget(wdata->winData.shell);
       
   658     free((void *) wdata);
       
   659     JNU_SetLongFieldFromPtr(env,this,mComponentPeerIDs.pData,NULL);
       
   660     awtJNI_DeleteGlobalRef(env, this);
       
   661 
       
   662     AWT_UNLOCK();
       
   663 }
       
   664 
       
   665 /*
       
   666  * Class:     sun_awt_motif_MFileDialogPeer
       
   667  * Method:    pShow
       
   668  * Signature: ()V
       
   669  */
       
   670 JNIEXPORT void JNICALL Java_sun_awt_motif_MFileDialogPeer_pShow
       
   671   (JNIEnv *env, jobject this)
       
   672 {
       
   673     struct FrameData *wdata;
       
   674     XmString dirMask = NULL;
       
   675 
       
   676     AWT_LOCK();
       
   677     wdata = (struct FrameData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
       
   678     if (wdata == NULL ||
       
   679         wdata->winData.comp.widget == NULL ||
       
   680         wdata->winData.shell == NULL) {
       
   681         JNU_ThrowNullPointerException(env, "NullPointerException");
       
   682         AWT_UNLOCK();
       
   683         return;
       
   684     }
       
   685     XtManageChild(wdata->winData.comp.widget);
       
   686 
       
   687     AWT_FLUSH_UNLOCK();
       
   688 }
       
   689 
       
   690 /*
       
   691  * Class:     sun_awt_motif_MFileDialogPeer
       
   692  * Method:    pHide
       
   693  * Signature: ()V
       
   694  */
       
   695 JNIEXPORT void JNICALL Java_sun_awt_motif_MFileDialogPeer_pHide
       
   696   (JNIEnv *env, jobject this)
       
   697 {
       
   698     struct FrameData *wdata;
       
   699 
       
   700     AWT_LOCK();
       
   701     wdata = (struct FrameData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
       
   702     if (wdata == NULL ||
       
   703         wdata->winData.comp.widget == NULL ||
       
   704         wdata->winData.shell == NULL) {
       
   705         JNU_ThrowNullPointerException(env, "NullPointerException");
       
   706         AWT_UNLOCK();
       
   707         return;
       
   708     }
       
   709     if (XtIsManaged(wdata->winData.comp.widget)) {
       
   710         XtUnmanageChild(wdata->winData.comp.widget);
       
   711     }
       
   712 
       
   713     AWT_FLUSH_UNLOCK();
       
   714 }
       
   715 
       
   716 /*
       
   717  * Class:     sun_awt_motif_MFileDialogPeer
       
   718  * Method:    setFileEntry
       
   719  * Signature: (Ljava/lang/String;Ljava/lang/String;)V
       
   720  */
       
   721 JNIEXPORT void JNICALL Java_sun_awt_motif_MFileDialogPeer_setFileEntry
       
   722   (JNIEnv *env, jobject this, jstring dir, jstring file, jobjectArray ffiles)
       
   723 {
       
   724     struct ComponentData *cdata;
       
   725     char *cdir;
       
   726     char *cfile;
       
   727     char *cf;
       
   728     struct FrameData *wdata;
       
   729     int32_t length, i;
       
   730     XmString * files = NULL;
       
   731     jstring jf;
       
   732 
       
   733     AWT_LOCK();
       
   734     wdata = (struct FrameData *)
       
   735         JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
       
   736     if (wdata == NULL || wdata->winData.comp.widget == NULL) {
       
   737         JNU_ThrowNullPointerException(env, "NullPointerException");
       
   738         return;
       
   739     }
       
   740 
       
   741     cdir = (JNU_IsNull(env, dir))
       
   742                ? NULL
       
   743                : (char *) JNU_GetStringPlatformChars(env, dir, NULL);
       
   744 
       
   745     cfile = (JNU_IsNull(env, file))
       
   746                ? NULL
       
   747                : (char *) JNU_GetStringPlatformChars(env, file, NULL);
       
   748 
       
   749     if (ffiles != NULL) {
       
   750         length = (*env)->GetArrayLength(env, ffiles);
       
   751         files = (XmString*)calloc(length, sizeof(XmString));
       
   752 
       
   753         for (i = 0; i < length; i++) {
       
   754             jf = (jstring)(*env)->GetObjectArrayElement(env, ffiles, i);
       
   755             cf = (char *) JNU_GetStringPlatformChars(env, jf, NULL);
       
   756 
       
   757             if ((*env)->GetStringLength(env, jf) == 0 && length == 1) {
       
   758               length = 0;
       
   759               files[0] = NULL;
       
   760             }
       
   761             else
       
   762               files[i] = XmStringCreateLocalized(cf);
       
   763 
       
   764             if (cf)
       
   765                 JNU_ReleaseStringPlatformChars(env, jf, (const char *) cf);
       
   766         }
       
   767 
       
   768         setFSBDirAndFile(wdata->winData.comp.widget, (cdir) ? cdir : "",
       
   769                          (cfile) ? cfile : "", files, length);
       
   770         while(i > 0) {
       
   771             XmStringFree(files[--i]);
       
   772         }
       
   773         if (files != NULL) {
       
   774             free(files);
       
   775         }
       
   776     }
       
   777     else
       
   778       setFSBDirAndFile(wdata->winData.comp.widget, (cdir) ? cdir : "",
       
   779                        (cfile) ? cfile : "", NULL, -1);
       
   780 
       
   781     if (cdir) {
       
   782         JNU_ReleaseStringPlatformChars(env, dir, (const char *) cdir);
       
   783     }
       
   784 
       
   785     if (cfile) {
       
   786         JNU_ReleaseStringPlatformChars(env, file, (const char *) cfile);
       
   787     }
       
   788 
       
   789     AWT_FLUSH_UNLOCK();
       
   790 }
       
   791 
       
   792 static void
       
   793 changeFont(Widget w, void *fontList)
       
   794 {
       
   795     XtVaSetValues(w, XmNfontList, fontList, NULL);
       
   796 }
       
   797 
       
   798 /*
       
   799  * Class:     sun_awt_motif_MFileDialogPeer
       
   800  * Method:    setFont
       
   801  * Signature: (Ljava/awt/Font;)V
       
   802  */
       
   803 JNIEXPORT void JNICALL Java_sun_awt_motif_MFileDialogPeer_setFont
       
   804   (JNIEnv *env, jobject this, jobject f)
       
   805 {
       
   806     struct ComponentData *tdata;
       
   807     struct FontData *fdata;
       
   808     XmFontListEntry fontentry;
       
   809     XmFontList fontlist;
       
   810     char *err;
       
   811 
       
   812     if (JNU_IsNull(env, f)) {
       
   813         JNU_ThrowNullPointerException(env, "NullPointerException");
       
   814         return;
       
   815     }
       
   816     AWT_LOCK();
       
   817     fdata = awtJNI_GetFontData(env, f, &err);
       
   818     if (fdata == NULL) {
       
   819         JNU_ThrowInternalError(env, err);
       
   820         AWT_UNLOCK();
       
   821         return;
       
   822     }
       
   823     tdata = (struct ComponentData *) JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
       
   824     if (tdata == NULL || tdata->widget == NULL) {
       
   825         JNU_ThrowNullPointerException(env, "NullPointerException");
       
   826         AWT_UNLOCK();
       
   827         return;
       
   828     }
       
   829     if (awtJNI_IsMultiFont(env, f)) {
       
   830         if (fdata->xfs == NULL) {
       
   831             fdata->xfs = awtJNI_MakeFontSet(env, f);
       
   832         }
       
   833         if (fdata->xfs != NULL) {
       
   834             fontentry = XmFontListEntryCreate("labelFont",
       
   835                                               XmFONT_IS_FONTSET,
       
   836                                               (XtPointer) (fdata->xfs));
       
   837             fontlist = XmFontListAppendEntry(NULL, fontentry);
       
   838             /*
       
   839              * Some versions of motif have a bug in
       
   840              * XmFontListEntryFree() which causes it to free more than it
       
   841              * should.  Use XtFree() instead.  See O'Reilly's
       
   842              * Motif Reference Manual for more information.
       
   843              */
       
   844             XmFontListEntryFree(&fontentry);
       
   845         } else {
       
   846             fontlist = XmFontListCreate(fdata->xfont, "labelFont");
       
   847         }
       
   848     } else {
       
   849         fontlist = XmFontListCreate(fdata->xfont, "labelFont");
       
   850     }
       
   851 
       
   852     if (fontlist != NULL) {
       
   853      /* setting the fontlist in the FileSelectionBox is not good enough --
       
   854         you have to set the resource for all the descendants individually */
       
   855         awt_util_mapChildren(tdata->widget, changeFont, 1, (void *)fontlist);
       
   856         XmFontListFree(fontlist);
       
   857     } else {
       
   858         JNU_ThrowNullPointerException(env, "NullPointerException");
       
   859     }
       
   860 
       
   861     AWT_UNLOCK();
       
   862 }
       
   863 
       
   864 /*
       
   865  * Class:     sun_awt_motif_MFileDialogPeer
       
   866  * Method:    insertReplaceFileDialogText
       
   867  * Signature: (Ljava/lang/String;)V
       
   868  */
       
   869 JNIEXPORT void JNICALL Java_sun_awt_motif_MFileDialogPeer_insertReplaceFileDialogText
       
   870   (JNIEnv *env, jobject this, jstring l)
       
   871 {
       
   872     struct ComponentData *cdata;
       
   873     char *cl;
       
   874     XmTextPosition start, end;
       
   875     Widget textField;
       
   876     jobject font;
       
   877 
       
   878     /*
       
   879      * Replaces the text in the FileDialog's textfield with the passed
       
   880      * string.
       
   881      */
       
   882 
       
   883     AWT_LOCK();
       
   884     cdata = (struct ComponentData *)
       
   885       JNU_GetLongFieldAsPtr(env,this,mComponentPeerIDs.pData);
       
   886     if (cdata == NULL || cdata->widget == NULL) {
       
   887         JNU_ThrowNullPointerException(env, "NullPointerException");
       
   888         AWT_UNLOCK();
       
   889         return;
       
   890     }
       
   891 
       
   892     textField = XmFileSelectionBoxGetChild(cdata->widget, XmDIALOG_TEXT);
       
   893 
       
   894     if (textField == NULL)  {
       
   895         JNU_ThrowNullPointerException(env, "Null TextField in FileDialog");
       
   896         AWT_UNLOCK();
       
   897         return;
       
   898     }
       
   899 
       
   900     font = awtJNI_GetFont(env, this);
       
   901 
       
   902     if (JNU_IsNull(env, l)) {
       
   903         cl = NULL;
       
   904     } else {
       
   905         /*
       
   906          * We use makePlatformCString() to convert unicode to EUC here,
       
   907          * although output only components (Label/Button/Menu..)
       
   908          * is not using make/allocCString() functions anymore.
       
   909          * Because Motif TextFiled widget does not support multi-font
       
   910          * compound string.
       
   911          */
       
   912 
       
   913         cl = (char *) JNU_GetStringPlatformChars(env, l, NULL);
       
   914     }
       
   915 
       
   916     if (!XmTextGetSelectionPosition(textField, &start, &end)) {
       
   917         start = end = XmTextGetInsertionPosition(textField);
       
   918     }
       
   919     XmTextReplace(textField, start, end, cl);
       
   920 
       
   921     if (cl != NULL && cl !="") {
       
   922         JNU_ReleaseStringPlatformChars(env, l, cl);
       
   923     }
       
   924     AWT_FLUSH_UNLOCK();
       
   925 }