callback.dispose ();
okCallback.dispose (); cancelCallback.dispose ();
public String open () {	/* Get the parent */	boolean destroyContext;	Display appContext = Display.getCurrent ();	if (destroyContext = (appContext == null)) appContext = new Display ();	int display = appContext.xDisplay;	int parentHandle = appContext.shellHandle;	if ((parent != null) && (parent.getDisplay () == appContext))		parentHandle = parent.shellHandle;	/* Compute the dialog title */		/*	* Feature in Motif.  It is not possible to set a shell	* title to an empty string.  The fix is to set the title	* to be a single space.	*/	String string = title;	if (string.length () == 0) string = " ";	/* Use the character encoding for the default locale */	byte [] buffer1 = Converter.wcsToMbcs (null, string, true);	int xmStringPtr1 = OS.XmStringParseText (		buffer1,		0,		OS.XmFONTLIST_DEFAULT_TAG, 		OS.XmCHARSET_TEXT, 		null,		0,		0);	/* Compute the filter */	String mask = FILTER;	if (filterExtensions == null) filterExtensions = new String [0];	if (filterNames == null) filterNames = new String [0];	if (filterExtensions.length != 0) {		/* Motif does not support multiple filters, so ignore them		 * if there are more than one, or if there is a ; separator.		 */		if (filterExtensions.length == 1) {			String filter = filterExtensions [0];			if (filter.indexOf (';', 0) == -1) mask = filter;		}	}	/* Use the character encoding for the default locale */	byte [] buffer2 = Converter.wcsToMbcs (null, mask, true);	int xmStringPtr2 = OS.XmStringParseText (		buffer2,		0,		OS.XmFONTLIST_DEFAULT_TAG, 		OS.XmCHARSET_TEXT, 		null,		0,		0);	/* Compute the filter path */	if (filterPath == null) filterPath = "";	/* Use the character encoding for the default locale */	byte [] buffer3 = Converter.wcsToMbcs (null, filterPath, true);	int xmStringPtr3 = OS.XmStringParseText (		buffer3,		0,		OS.XmFONTLIST_DEFAULT_TAG, 		OS.XmCHARSET_TEXT, 		null,		0,		0);	/* Create the dialog */	int [] argList1 = {		OS.XmNresizePolicy, OS.XmRESIZE_NONE,		OS.XmNdialogStyle, OS.XmDIALOG_PRIMARY_APPLICATION_MODAL,		OS.XmNwidth, OS.XDisplayWidth (display, OS.XDefaultScreen (display)) * 4 / 9,		OS.XmNdialogTitle, xmStringPtr1,		OS.XmNpattern, xmStringPtr2,		OS.XmNdirectory, xmStringPtr3,	};	/*	* Feature in Linux.  For some reason, the XmCreateFileSelectionDialog()	* will not accept NULL for the widget name.  This works fine on the other	* Motif platforms and in the other XmCreate calls on Linux.  The fix is	* to pass in a NULL terminated string, not a NULL pointer.	*/	byte [] name = new byte [] {0};	int dialog = OS.XmCreateFileSelectionDialog (parentHandle, name, argList1, argList1.length / 2);	int child = OS.XmFileSelectionBoxGetChild (dialog, OS.XmDIALOG_HELP_BUTTON);	if (child != 0) OS.XtUnmanageChild (child);	OS.XmStringFree (xmStringPtr1);	OS.XmStringFree (xmStringPtr2);	OS.XmStringFree (xmStringPtr3);/*	string := OSWidget xmStringAt: XmNdirectory handle: dialog.	OSWidget xmStringAt: XmNdirSpec put: string, fileName handle: dialog.	"Select the matching file in the list and scroll to show it."	child := dialog xmFileSelectionBoxGetChild: XmDIALOGLIST.	child isNull ifFalse: [		string := OSWidget xmStringAt: XmNdirSpec handle: dialog.		string := PlatformConverter wcsToMbcs: 0 buffer: string.		xmString := OSXmString xmStringCreateLocalized: string asPSZ.		child			xmListSelectItem: xmString notify: false;			xmListSetItem: xmString.		xmString xmStringFree.		"Bug in Solaris.  For some reason, the horizontal scroll bar in the dialog		list refuses to be displayed.  This stops the dialog list from scrolling		horizontally and displaying the file names.  This does not happen on other		Motif platforms.  The fix is to force the horizontal scroll bar to be displayed		by explicitly setting the scroll bar display policy."		OSWidget resourceAt: XmNscrollBarDisplayPolicy put: XmSTATIC handle: child].*/	/* Hook the callbacks. */	Callback callback = new Callback (this, "activate", 3);	int address = callback.getAddress ();	OS.XtAddCallback (dialog, OS.XmNokCallback, address, OS.XmDIALOG_OK_BUTTON);	OS.XtAddCallback (dialog, OS.XmNcancelCallback, address, OS.XmDIALOG_CANCEL_BUTTON);	/* Open the dialog and dispatch events. */	cancel = true;/*	shell == nil ifFalse: [		shell minimized ifTrue: [shell minimized: false]].*/	OS.XtManageChild (dialog);	//BOGUS - should be a pure OS message loop (no SWT AppContext)	while (OS.XtIsRealized (dialog) && OS.XtIsManaged (dialog))		if (!appContext.readAndDispatch ()) appContext.sleep ();	/* Set the new path, file name and filter. */	fullPath = "";	if (!cancel) {		filterPath = fullPath = "";		int [] argList2 = {OS.XmNdirectory, 0, OS.XmNdirSpec, 0};		OS.XtGetValues (dialog, argList2, argList2.length / 2);		int xmString3 = argList2 [1];		int ptr = OS.XmStringUnparse (			xmString3,			null,			OS.XmCHARSET_TEXT,			OS.XmCHARSET_TEXT,			null,			0,			OS.XmOUTPUT_ALL);		if (ptr != 0) {			int length = OS.strlen (ptr);			byte [] buffer = new byte [length];			OS.memmove (buffer, ptr, length);			OS.XtFree (ptr);			/* Use the character encoding for the default locale */			filterPath = new String (Converter.mbcsToWcs (null, buffer));		}		OS.XmStringFree (xmString3);		int xmString4 = argList2 [3];		ptr = OS.XmStringUnparse (			xmString4,			null,			OS.XmCHARSET_TEXT,			OS.XmCHARSET_TEXT,			null,			0,			OS.XmOUTPUT_ALL);		if (ptr != 0) {			int length = OS.strlen (ptr);			byte [] buffer = new byte [length];			OS.memmove (buffer, ptr, length);			OS.XtFree (ptr);			/* Use the character encoding for the default locale */			fullPath = new String (Converter.mbcsToWcs (null, buffer));		}		OS.XmStringFree (xmString4);		int length = filterPath.length ();		if (length != 0 && filterPath.charAt (length - 1) == '/') {			filterPath = filterPath.substring (0, length - 1);			int index = fullPath.lastIndexOf ('/');			fileName = fullPath.substring (index + 1, fullPath.length ());		}	}	/* Destroy the dialog and update the display. */	if (OS.XtIsRealized (dialog)) OS.XtDestroyWidget (dialog);	if (destroyContext) appContext.dispose ();	callback.dispose ();	//	(shell == nil or: [shell isDestroyed not]) ifTrue: [dialog xtDestroyWidget].//	OSWidget updateDisplay.//	entryPoint unbind.	if (cancel) return null;	return fullPath;}