blob: a170deda9c40cece220ac48e63b9a72daefb011c [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
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
51extern void Text_handlePaste(Widget w, XtPointer client_data, XEvent * event,
52 Boolean * cont);
53
54extern struct MComponentPeerIDs mComponentPeerIDs;
55
56extern AwtGraphicsConfigDataPtr
57 copyGraphicsConfigToPeer(JNIEnv *env, jobject this);
58
59/* fieldIDs for FileDialog fields and methods that may be accessed from C */
60static struct FileDialogIDs {
61 jfieldID mode;
62 jfieldID file;
63} fileDialogIDs;
64
65/* the field to store the default search procedure */
66static XmSearchProc DefaultSearchProc = NULL;
67
68/* mouse wheel handler for scrolling */
69void 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
80JNIEXPORT void JNICALL
81Java_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 */
95static void
96FileDialog_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 */
145static void
146FileDialog_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 */
167static void
168FileDialog_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
181static void
182setDeleteCallback(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
201void
202setFSBDirAndFile(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
254static void
255changeBackground(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
270void
271ourSearchProc(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 */
374JNIEXPORT 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 */
581void 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 */
606JNIEXPORT 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 */
641JNIEXPORT 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 */
670JNIEXPORT 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 */
695JNIEXPORT 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 */
721JNIEXPORT 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
792static void
793changeFont(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 */
803JNIEXPORT 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 */
869JNIEXPORT 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}