1 /***********************************************************************/
2 /* Open Visualization Data Explorer                                    */
3 /* (C) Copyright IBM Corp. 1989,1999                                   */
4 /* ALL RIGHTS RESERVED                                                 */
5 /* This code licensed under the                                        */
6 /*    "IBM PUBLIC LICENSE - Open Visualization Data Explorer"          */
7 /***********************************************************************/
8 
9 #include <dxconfig.h>
10 #include "../base/defines.h"
11 
12 
13 
14 
15 #ifdef OS2
16 #define INCL_DOS
17 #include <os2.h>
18 #endif
19 
20 
21 #include <Xm/Xm.h>
22 #include <Xm/FileSB.h>
23 #include <Xm/DialogS.h>
24 #include <Xm/Text.h>
25 #include <Xm/SelectioB.h>
26 #include <Xm/Protocols.h>
27 #include <Xm/AtomMgr.h>
28 
29 #include "FileDialog.h"
30 #include "Application.h"
31 #include "DXStrings.h"
32 #include "ErrorDialogManager.h"
33 
34 #ifdef	DXD_WIN   /*   ajay    */
35 #include <direct.h>
36 #include <io.h>
37 #include "DXStrings.h"
38 #endif
39 
40 #if 0             //SMH define local X routine
41 extern "C" { extern void ForceUpdate(Widget); }
42 #endif
43 
44 #ifdef DXD_NON_UNIX_DIR_SEPARATOR
45 extern "C" {
46 char *KillRelPaths(char *p);
47 void NonUnixQualifySearchProc(Widget w, XtPointer *in_data, XtPointer *out_data);
48 void NonUnixSearchProc(Widget w, XtPointer search_data);
49 void NonUnixDirSearchProc(Widget w, XtPointer search_data);
50 const char *GetNullStr(XmString str);
51 }
52 #endif
53 
54 //
55 // These are never installed by this class (on instances of this class)
56 // as this is an abstract class.  The subclasses are responsible for
57 // installing these resources, using setDefaultResources().
58 //
59 String FileDialog::DefaultResources[] =
60 {
61         ".dialogStyle:     XmDIALOG_FULL_APPLICATION_MODAL",
62 	"*pathMode:	   XmPATH_MODE_FULL",
63         NULL
64 };
65 
66 boolean FileDialog::ClassInitialized = FALSE;
67 
FileDialog(const char * name,Widget parent)68 FileDialog::FileDialog(const char *name, Widget parent) :
69                        Dialog(name, parent)
70 {
71     this->hasCommentButton = FALSE;
72     this->readOnlyDirectory = NULL;
73 }
74 
~FileDialog()75 FileDialog::~FileDialog()
76 {
77     if (this->readOnlyDirectory)
78 	delete this->readOnlyDirectory;
79 }
80 
installDefaultResources(Widget baseWidget)81 void FileDialog::installDefaultResources(Widget  baseWidget)
82 {
83     this->setDefaultResources(baseWidget, FileDialog::DefaultResources);
84     this->Dialog::installDefaultResources( baseWidget);
85 }
post()86 void FileDialog::post()
87 {
88     Widget text;
89 
90     theApplication->setBusyCursor(TRUE);
91     if (this->getRootWidget() == NULL)
92     {
93 	this->initialize();
94 	this->setRootWidget(this->createDialog(this->parent));
95 
96 	Widget shell = XtParent(this->getRootWidget());
97 	XtVaSetValues(shell, XmNdeleteResponse, XmDO_NOTHING, NULL);
98 	Atom WM_DELETE_WINDOW = XmInternAtom(XtDisplay(shell),
99 					    "WM_DELETE_WINDOW", False);
100 	XmAddWMProtocolCallback(shell, WM_DELETE_WINDOW,
101 				    (XtCallbackProc)Dialog_CancelCB,
102 				    (void *)(this));
103 
104 	XtAddCallback(this->fsb,
105 		      XmNokCallback,
106 		      (XtCallbackProc)Dialog_OkCB,
107 		      (XtPointer)this);
108 
109 	XtAddCallback(this->fsb,
110 		      XmNcancelCallback,
111 		      (XtCallbackProc)Dialog_CancelCB,
112 		      (XtPointer)this);
113 
114 	Widget helpButton =
115 	    XmFileSelectionBoxGetChild(this->fsb, XmDIALOG_HELP_BUTTON);
116 	XtRemoveAllCallbacks(helpButton, XmNactivateCallback);
117 	XtAddCallback(helpButton,
118 		      XmNactivateCallback,
119 		      (XtCallbackProc)Dialog_HelpCB,
120 		      (XtPointer)this);
121 
122 
123 	text  = XmFileSelectionBoxGetChild(this->fsb, XmDIALOG_TEXT);
124     	this->manage();
125 	XmProcessTraversal(text, XmTRAVERSE_CURRENT);
126 	XmProcessTraversal(text, XmTRAVERSE_CURRENT);
127 
128     }
129     this->manage();
130     theApplication->setBusyCursor(FALSE);
131 }
132 
133 //
134 // Set the name of the current file.
135 //
setFileName(const char * file)136 void FileDialog::setFileName(const char *file)
137 {
138     ASSERT(this->fsb);
139     XmString xmdir = NULL;
140     char *path = NULL, *dir = NULL;
141 
142 #ifdef DXD_NON_UNIX_DIR_SEPARATOR
143     if (!(file[0] == '\\' || file[0] == '/' || (STRLEN(file) > 1 && file[1] == ':'))) {
144     /* if (!strrchr(file, '\\') && !strrchr(file, ':') && !strrchr(file, '/')) { */
145 #else
146     if (file[0] != '/') {
147 #endif
148 	XtVaGetValues(this->fsb,XmNdirectory, &xmdir, NULL);
149 	XmStringGetLtoR(xmdir,XmSTRING_DEFAULT_CHARSET, &dir);
150 
151 	path = new char [STRLEN(dir) + 2 + STRLEN(file)];
152 
153 	sprintf(path,"%s%s",dir,file);
154 	file = path;
155     }
156 
157     Widget dialog_text  = XmSelectionBoxGetChild(this->fsb, XmDIALOG_TEXT);
158 
159 
160     //	DOS2UNIXPATH((char *) file);
161     XmTextSetString(dialog_text, (char*)file);
162 
163     //
164     // Right justify the text in the text window.
165     //
166     int len = STRLEN(file);
167     XmTextShowPosition(dialog_text,len);
168     XmTextSetInsertionPosition(dialog_text,len);
169 
170 
171 
172     if (path) delete path;
173     if (dir)  XtFree(dir);
174     if (xmdir) XmStringFree(xmdir);
175 
176 }
177 //
178 // Get the name of the currently selected file.
179 // The returned string must be freed by the caller.
180 // If a filename is not currently selected, then return NULL.
181 //
182 char *FileDialog::getSelectedFileName()
183 {
184     ASSERT(this->fsb);
185     char *p, *s = XmTextGetString(XmSelectionBoxGetChild(this->fsb,
186 					XmDIALOG_TEXT));
187 #ifdef DXD_NON_UNIX_DIR_SEPARATOR
188     char *q = strrchr(s,'\\');
189     p = strrchr(s,'/');
190     if (q && q>p)
191 	p = q;
192 #else
193     p = strrchr(s,'/');
194 #endif
195     if (p) {
196 	p++;
197 	if (!*p) {
198 	    XtFree(s);
199 	    s = NULL;
200 	}
201     }
202     return s;
203 }
204 
205 //
206 // Get the name of the current directory (without a trailing '/').
207 // The returned string must be freed by the caller.
208 //
209 char *FileDialog::getCurrentDirectory()
210 {
211     ASSERT(this->fsb);
212     char *dir = NULL;
213     XmString xmdir;
214 
215     XtVaGetValues(this->fsb,XmNdirectory, &xmdir, NULL);
216     if (xmdir) {
217 	XmStringGetLtoR(xmdir,XmSTRING_DEFAULT_CHARSET, &dir);
218 	char* cp = DuplicateString(dir);
219 	XtFree(dir);
220 	dir = cp;
221 	XmStringFree(xmdir);
222 	int last = STRLEN(dir) - 1;
223 #ifdef DXD_NON_UNIX_DIR_SEPARATOR
224 	if ((last >= 0) && ((dir[last] == '\\') || (dir[last] == '/')))
225 #else
226 	if ((last >= 0) && (dir[last] == '/'))
227 #endif
228 	    dir[last] = '\0';
229     } else {
230 	dir = DuplicateString(".");
231     }
232 
233     //	DOS2UNIXPATH(dir);
234     return dir;
235 }
236 
237 boolean FileDialog::okCallback(Dialog *d)
238 {
239     char *string;
240 
241     string = this->getSelectedFileName();
242 
243     if (!string) {
244 	ModalErrorMessage(this->getRootWidget(),"A filename must be given");
245 	return FALSE;
246     }
247 
248     this->unmanage();
249     theApplication->setBusyCursor(TRUE);
250     this->okFileWork(string);
251     theApplication->setBusyCursor(FALSE);
252     XtFree(string);
253     return FALSE;	// Already unmanaged above
254 }
255 
256 Widget FileDialog::createDialog(Widget parent)
257 {
258     Widget shell;
259     Arg    wargs[10];
260     int    n;
261     char shellname[512];
262 
263     n = 0;
264     XtSetArg(wargs[n], XmNallowShellResize, True); n++;
265     sprintf(shellname,"%sShell",this->name);
266     shell = XmCreateDialogShell(parent, shellname, wargs, n);
267 
268     //
269     // Motif FileSelection dialogs don't tolerate being sized to tiny
270     // dimensions.  They're not able to lay themselves out following
271     // such a resize.  So impose min sizes.  It might be better to
272     // make a virtual method in Dialog.
273     //
274     XtVaSetValues (shell, XmNminWidth, 130, XmNminHeight, 320, NULL);
275 
276     this->fsb =  this->createFileSelectionBox(shell, this->name);
277 
278     return this->fsb;
279 }
280 
281 //
282 // Create the file selection box (i.e. the part with the filter, directory
283 // and file list boxes, and the 4 buttons, ok, comment, cancel, apply).
284 // The four buttons are set the have a width of 120
285 //
286 
287 Widget FileDialog::createFileSelectionBox(Widget parent, const char *name)
288 {
289     Widget button;
290     Dimension width;
291 
292     Widget fsb = XtVaCreateWidget(name,
293                                   xmFileSelectionBoxWidgetClass, parent,
294 #if 0
295 #ifdef DXD_NON_UNIX_DIR_SEPARATOR
296                                   XmNfileSearchProc,        NonUnixSearchProc,
297                                   XmNdirSearchProc,         NonUnixDirSearchProc,
298                                   XmNqualifySearchDataProc, NonUnixQualifySearchProc,
299 #endif
300 #endif
301                                   NULL);
302 
303     if (!this->hasCommentButton) {
304         button = XmFileSelectionBoxGetChild(fsb, XmDIALOG_HELP_BUTTON);
305         XtUnmanageChild(button);
306     }
307 
308     //
309     // Ensure the buttons are at least 120 wide
310     //
311     button = XmFileSelectionBoxGetChild(fsb, XmDIALOG_OK_BUTTON);
312     XtVaGetValues(button, XmNwidth, &width, NULL);
313     if (width < 120)
314     {
315 	XtVaSetValues(button, XmNwidth, 120, XmNrecomputeSize, False, NULL);
316 
317 	button = XmFileSelectionBoxGetChild(fsb, XmDIALOG_CANCEL_BUTTON);
318 	XtVaSetValues(button, XmNwidth, 120, XmNrecomputeSize, False, NULL);
319 
320 	button = XmFileSelectionBoxGetChild(fsb, XmDIALOG_APPLY_BUTTON);
321 	XtVaSetValues(button, XmNwidth, 120, XmNrecomputeSize, False, NULL);
322 
323 	button = XmFileSelectionBoxGetChild(fsb, XmDIALOG_HELP_BUTTON);
324 	XtVaSetValues(button, XmNwidth, 120, XmNrecomputeSize, False, NULL);
325     }
326 
327     return fsb;
328 }
329 
330 void FileDialog::manage()
331 {
332     XmFileSelectionDoSearch(this->getFileSelectionBox(), NULL);
333 #if 0             // SMH hack the loop away
334     ForceUpdate(this->fsb);
335 #endif
336     this->displayLimitedMode(this->readOnlyDirectory != NULL);
337     this->Dialog::manage();
338     char *file = this->getDefaultFileName();
339     if (file) {
340 	this->setFileName(file);
341 	delete file;
342     }
343 
344 
345 }
346 
347 //
348 // If dirname is not NULL, then set the dialog so that the directory is
349 // fixed.  If dirname is NULL, then the fixed directory is turned off.
350 //
351 void FileDialog::setReadOnlyDirectory(const char *dirname)
352 {
353     if (this->readOnlyDirectory)
354 	delete this->readOnlyDirectory;
355 
356     if (dirname) {
357 	this->readOnlyDirectory = DuplicateString(dirname);
358     } else {
359 	this->readOnlyDirectory = NULL;
360     }
361 
362 
363     if (this->isManaged())  {
364 	XmString string = XmStringCreate((char*)dirname,
365 						XmSTRING_DEFAULT_CHARSET);
366 	XtVaSetValues(this->fsb, XmNdirectory,string, NULL);
367 	XmStringFree(string);
368 	this->displayLimitedMode(TRUE);
369     }
370 
371 }
372 
373 //
374 // If 'limit' is true, change the dialog box so that it operates in
375 // limited mode, that is, the user can only select file from the
376 // current directory specified by XmNdirectory.
377 //
378 void FileDialog::displayLimitedMode(boolean limit)
379 {
380     Widget w[10];
381     int	n = 0;
382 
383     ASSERT(this->fsb);
384     w[n++] = XmFileSelectionBoxGetChild(this->fsb,XmDIALOG_APPLY_BUTTON);
385     w[n++] = XmFileSelectionBoxGetChild(this->fsb,XmDIALOG_FILTER_LABEL);
386     w[n++] = XmFileSelectionBoxGetChild(this->fsb,XmDIALOG_FILTER_TEXT);
387     w[n++] = XmFileSelectionBoxGetChild(this->fsb,XmDIALOG_DIR_LIST_LABEL);
388     w[n++] = XmFileSelectionBoxGetChild(this->fsb,XmDIALOG_DIR_LIST);
389     w[n] = XtParent(w[n-1]); n++;
390     w[n++] = XmFileSelectionBoxGetChild(this->fsb,XmDIALOG_TEXT);
391     w[n++] = XmFileSelectionBoxGetChild(this->fsb,XmDIALOG_SELECTION_LABEL);
392     w[n++] = XmFileSelectionBoxGetChild(this->fsb,XmDIALOG_LIST_LABEL);
393 
394     if (limit) {
395 	while (n--)
396 	    XtUnmanageChild(w[n]);
397     } else {
398 	while (n--)
399 	    XtManageChild(w[n]);
400     }
401 }
402 
403 //
404 // Get the default file name that is to be placed in the filename text
405 // each time this is FileDialog::manage()'d.  By default this returns
406 // NULL and nothing happens.  Subclasses can implement this to acquire
407 // the described behavior.
408 //
409 char *FileDialog::getDefaultFileName()
410 {
411     return NULL;
412 }
413 
414 
415 #ifdef DXD_NON_UNIX_DIR_SEPARATOR
416 
417 extern "C" char *KillRelPaths(char *p)
418 {
419   char *s,*p1;
420 
421   if (p)
422     {
423     while (!strncmp(p,"/../",4))
424       memmove(p, &p[3], strlen(&p[3])+1);
425     while ((p1=s=strstr(p,"/../")) && s!=p)
426       {
427         s--;
428         while (s!=p && *s != '/')
429           s--;
430         if (*s == '/')
431           memmove(s, &p1[3], strlen(&p1[3])+1);
432       }
433     while (s=strstr(p,"/./"))
434       memmove(s, &s[2], strlen(&s[2])+1);
435    }
436   return p;
437 }
438 
439 extern "C" void NonUnixQualifySearchProc(Widget w, XtPointer *in_data, XtPointer *out_data)
440 {
441   Widget u;
442   char *s1,*s2,*s3,*s4;
443   char dir[_MAX_PATH];
444   char mask[_MAX_PATH];
445   char value[_MAX_PATH];
446   char buff[_MAX_PATH];
447   char filter[_MAX_PATH];
448   ULONG PathLength;
449   char *ptr;
450   XmString	ext;
451   int i;
452 
453 
454 #ifndef	DXD_WIN
455   APIRET rc;
456 #endif
457 
458   XmFileSelectionBoxCallbackStruct *cbs =
459         (XmFileSelectionBoxCallbackStruct *) in_data;
460   XmFileSelectionBoxCallbackStruct *cbs2 =
461         (XmFileSelectionBoxCallbackStruct *) out_data;
462 
463   u = XmFileSelectionBoxGetChild(w, XmDIALOG_FILTER_TEXT);
464   s1 = XmTextGetString(u);
465 
466   if (s1 && *s1)
467     i = ((*s1 == '/') || (*s1 == '\\') || (strlen(s1)>1 && s1[1] == ':'));
468   else
469     i = 0;
470 
471   if (!i)
472     {
473 	PathLength=sizeof(mask);
474 #ifdef  os2 //  ajay
475 	rc = DosQueryCurrentDir(0, mask, &PathLength);
476 #endif
477 #ifdef  DXD_WIN
478 	_getdcwd(0, mask, PathLength - 1);
479 #endif
480 	if (mask[strlen(mask)-1] != '\\')
481 	    strcat(mask, "\\");
482 	strcpy(filter, GetNullStr(cbs->mask));
483 	strcat(mask, filter);
484     }
485    else
486 	strcpy(mask, s1);
487 
488   XtFree(s1);
489   DOS2UNIXPATH(mask);
490   if (*mask != '/' && !strchr(mask,':'))   /* put leading /       */
491     {
492       PathLength=sizeof(buff);
493       strcat(buff,mask);
494       strcpy(mask,buff);
495     }
496   strcpy(dir,mask);                        /* get dir from mask    */
497 
498   ptr=strrchr(dir,'/');
499   if(!ptr) ptr = strrchr(dir, ':');
500 
501   if (ptr)
502     {
503       strcpy(filter,&ptr[1]);              /* get filter from filter text */
504       ptr[1]='\0';
505     }
506    else
507     {
508       strcpy(filter,"*");
509       strcat(dir,"/");
510     }
511 
512   if (!cbs->event && cbs->dir)       /* clicked on dir selection */
513     {
514       XmStringGetLtoR(cbs->dir, XmFONTLIST_DEFAULT_TAG, &s1);
515       strcpy(mask,s1);
516       XtFree(s1);
517       DOS2UNIXPATH(mask);
518       strcat(mask,"/");
519       if (*mask != '/' && !strchr(mask,':'))
520         {
521           strcpy(buff,"/");
522           strcat(buff,mask);
523           strcpy(mask,buff);
524         }
525       strcpy(dir,mask);
526       strcat(mask, filter);
527     }
528 
529   u = XmFileSelectionBoxGetChild(w, XmDIALOG_TEXT);
530   s2 = XmTextGetString(u);
531   if (!s2 || !strlen(s2))
532     strcpy(value,mask);
533    else
534     strcpy(value,s2);
535   XtFree(s2);
536 
537   KillRelPaths(mask);
538   KillRelPaths(dir);
539   KillRelPaths(value);
540 
541   cbs2->reason = cbs->reason;
542   cbs2->event = cbs->event;
543   cbs2->value = XmStringCreateLocalized(value);
544   cbs2->length = XmStringLength(cbs2->value);
545   cbs2->mask = XmStringCreateLocalized(mask);
546   cbs2->mask_length = XmStringLength(cbs2->mask);
547   cbs2->dir = XmStringCreateLocalized(dir);
548   cbs2->dir_length = XmStringLength(cbs2->dir);
549   cbs2->pattern = XmStringCreateLocalized(filter);
550   cbs2->pattern_length = XmStringLength(cbs2->pattern);
551 
552 }
553 
554 #ifdef DXD_WIN
555 
556 #define MAX_DIR_LIST 256
557 
558 extern "C" static int LocalFileCmp(const void *a, const void *b)
559 {
560     return strcmp(*(char **)a, *(char **)b);
561 }
562 
563 extern "C" static int GetSortedList(char *mask, char *dir, char **list, int max, int dirs)
564 {
565     struct _finddata_t  DirHandle;
566     long HFile;
567     long rc;
568     char *p;
569     int k = 0;
570 
571     HFile = _findfirst(mask, &DirHandle );
572     if (HFile == -1L)
573 	rc = -1;
574     else
575 	rc = 0;
576 
577     while (!rc) {
578 	if ((dirs == 0) != ((DirHandle.attrib & _A_SUBDIR) == 0)){
579 	    rc = _findnext(HFile, &DirHandle);
580 	    continue;
581 	}
582 	list[k] = (char *)malloc(_MAX_PATH * sizeof(char));
583 	p = list[k++];
584 
585 	strcpy(p, dir);
586 	strcat(p, DirHandle.name);
587 
588 	DOS2UNIXPATH(p);
589 
590 	rc = _findnext(HFile, &DirHandle);
591     }
592     if (k>1)
593 	qsort(list, k, sizeof(char *), LocalFileCmp);
594 
595     return k;
596 }
597 #endif  // DXD_WIN
598 
599 extern "C" void NonUnixSearchProc(Widget w, XtPointer search_data)
600 {
601   char          *mask;
602   char          fullname[300];
603   char          *dir;
604   XmString      names[MAX_DIR_LIST];
605   int           i=0;
606 #ifndef	DXD_WIN   /*   ajay   */
607   HDIR          DirHandle=1;
608   FILEFINDBUF3  FindBuffer;
609   APIRET        rc;
610 #endif
611 #ifdef	DXD_WIN	/*   ajay   */
612   long	rc;
613   char *list[MAX_DIR_LIST];
614   int knt;
615 #endif
616   int         FindCount = 0;
617   XmFileSelectionBoxCallbackStruct *cbs =
618         (XmFileSelectionBoxCallbackStruct *) search_data;
619 
620   malloc(28);
621 
622   if (!XmStringGetLtoR(cbs->mask, XmFONTLIST_DEFAULT_TAG, &mask))
623     return;
624   if (!XmStringGetLtoR(cbs->dir, XmFONTLIST_DEFAULT_TAG, &dir))
625     return;
626 
627   UNIX2DOSPATH(mask);
628 
629 #ifdef  os2 //  ajay
630   rc = DosFindFirst(mask, &DirHandle, FILE_READONLY, (PVOID) &FindBuffer,
631          sizeof(FindBuffer), &FindCount, FIL_STANDARD);
632 
633   XtFree(mask);
634   while(!rc && i<MAX_DIR_LIST){
635     /* DosQueryPathInfo(Findbuffer.achName, FIL_QUERYFULLNAME,
636       fullname, sizeof(fullname)); */
637     strcpy(fullname,dir);
638     strcat(fullname,FindBuffer.achName);
639 
640     DOS2UNIXPATH(fullname);
641     names[i++] = XmStringCreateLocalized(fullname);
642     FindCount = 1;
643 
644     rc = DosFindNext(DirHandle, &FindBuffer, sizeof(FindBuffer), &FindCount);
645 #endif
646 
647 #ifdef  DXD_WIN //  ajay
648   FindCount = GetSortedList(mask, dir, list, MAX_DIR_LIST, 0);
649   XtFree(mask);
650   for (i=0; i<FindCount; i++) {
651     names[i] = XmStringCreateLocalized(list[i]);
652     free(list[i]);
653   }
654 
655 #endif
656 
657   if (!FindCount)
658       names[FindCount++] = XmStringCreateLocalized("       [      ] ");
659 
660   XtVaSetValues(w,
661     XmNfileListItems,         names,
662     XmNfileListItemCount,     FindCount,
663     XmNdirSpec,               names[0],
664     XmNlistUpdated,           True,
665     NULL);
666 
667   while (FindCount > 0)
668     XmStringFree(names[--FindCount]);
669 
670   XtFree(dir);
671 }
672 
673 extern "C" void NonUnixDirSearchProc(Widget w, XtPointer search_data)
674 {
675   char          dirmask[_MAX_PATH];
676   char		*list[MAX_DIR_LIST];
677   char          fullname[_MAX_PATH];
678   char          *dir;
679   XmString      names[MAX_DIR_LIST];
680   int           i=0;
681 #ifdef  os2
682   HDIR          DirHandle=1;
683   FILEFINDBUF3  FindBuffer;
684   APIRET        rc;
685 #endif
686 #ifdef  DXD_WIN
687     long        rc;
688 #endif
689   int FindCount = 0;
690 
691 
692   XmFileSelectionBoxCallbackStruct *cbs =
693         (XmFileSelectionBoxCallbackStruct *) search_data;
694 
695   if (!XmStringGetLtoR(cbs->dir, XmFONTLIST_DEFAULT_TAG, &dir))
696     return;
697 
698   UNIX2DOSPATH(dir);
699   strcpy(dirmask, dir);
700   strcat(dirmask, "*");
701 
702 #ifdef  os2
703   rc = DosFindFirst(dirmask, &DirHandle, MUST_HAVE_DIRECTORY | FILE_READONLY, (PVOID) &FindBuffer,
704          sizeof(FindBuffer), &FindCount, FIL_STANDARD);
705 
706   while(!rc && i<MAX_DIR_LIST){
707     strcpy(fullname,dir);
708     strcat(fullname,FindBuffer.achName);
709 
710     DOS2UNIXPATH(fullname);
711     names[i++] = XmStringCreateLocalized(fullname);
712     FindCount = 1;
713 
714     rc = DosFindNext(DirHandle, &FindBuffer, sizeof(FindBuffer), &FindCount);
715 #endif
716 
717 #ifdef  DXD_WIN //  ajay
718   FindCount = GetSortedList(dirmask, dir, list, MAX_DIR_LIST, 1);
719   XtFree(dir);
720   for (i=0; i<FindCount; i++) {
721     names[i] = XmStringCreateLocalized(list[i]);
722     free(list[i]);
723   }
724 
725 #endif
726 
727   if (!FindCount) {
728       names[FindCount++] = XmStringCreateLocalized("/.");
729       names[FindCount++] = XmStringCreateLocalized("/..");
730   }
731 
732   XtVaSetValues(w,
733     XmNdirListItems,         names,
734     XmNdirListItemCount,     FindCount,
735     XmNlistUpdated,          True,
736     XmNdirectoryValid,       True,
737     NULL);
738 
739   while (FindCount > 0)
740     XmStringFree(names[--FindCount]);
741 
742   XtFree(dir);
743 }
744 
745 
746 
747 extern "C" const char *GetNullStr(XmString str)
748 {
749     XmStringContext cxt;
750     char *text, *tag;
751     static char buf[1024];
752     XmStringDirection dir;
753     Boolean sep;
754     int os;
755 
756     if (!str) return "";
757     if (!XmStringInitContext (&cxt, str)) {
758 	XtWarning ("Can't convert compound string.");
759 	return "";
760     }
761     os = 0;
762     while (XmStringGetNextSegment (cxt, &text, &tag, &dir, &sep)) {
763 	strcpy (&buf[os], text);
764 	os+= strlen(text);
765 	if (sep) {
766 	    buf[os++] = '\n';
767 	}
768 	// unsure about this line. The motif manual doesn't do this
769 	// but purify complains about memory loss
770 	if (tag) XtFree(tag);
771 	XtFree(text);
772     }
773 
774     buf[os] = '\0';
775     ASSERT(os<sizeof(buf));
776     XmStringFreeContext(cxt);
777     return buf;
778 }
779 
780 #endif
781 
782 
783 
784 
785