/* * Copyright 1989 Software Research Associates, Inc., Tokyo, Japan * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Software Research Associates not be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. Software Research Associates * makes no representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * SOFTWARE RESEARCH ASSOCIATES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, * IN NO EVENT SHALL SOFTWARE RESEARCH ASSOCIATES BE LIABLE FOR ANY SPECIAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * Author: Erik M. van der Poel * Software Research Associates, Inc., Tokyo, Japan * erik@sra.co.jp */ /* * Author's address: * * erik@sra.co.jp * OR * erik%sra.co.jp@uunet.uu.net * OR * erik%sra.co.jp@mcvax.uucp * OR * try junet instead of co.jp * OR * Erik M. van der Poel * Software Research Associates, Inc. * 1-1-1 Hirakawa-cho, Chiyoda-ku * Tokyo 102 Japan. TEL +81-3-234-2692 */ #include #include /* BSD 4.3 errno.h does not declare errno */ extern int errno; extern int sys_nerr; extern char *sys_errlist[]; #include #include #include #include #include #include #include #include #include #include #include #include "SFinternal.h" #ifndef MAXPATHLEN #define MAXPATHLEN 1024 #endif /* ndef MAXPATHLEN */ #if !defined(SVR4) && !defined(SYSV) && !defined(USG) extern char *getwd(); #endif /* !defined(SVR4) && !defined(SYSV) && !defined(USG) */ int SFstatus = SEL_FILE_NULL; char SFstartDir[MAXPATHLEN], SFcurrentPath[MAXPATHLEN], SFcurrentDir[MAXPATHLEN]; Widget selFile, selFileCancel, selFileField, selFileForm, selFileHScroll, selFileHScrolls[3], selFileLists[3], selFileOK, selFilePrompt, selFileVScrolls[3]; Display *SFdisplay; Pixel SFfore, SFback; Atom SFwmDeleteWindow; XSegment SFsegs[2], SFcompletionSegs[2]; XawTextPosition SFtextPos; int SFupperX, SFlowerY, SFupperY; int SFtextX, SFtextYoffset; int SFentryWidth, SFentryHeight; int SFlineToTextH = 3; int SFlineToTextV = 3; int SFbesideText = 3; int SFaboveAndBelowText = 2; int SFcharsPerEntry = 15; int SFlistSize = 10; int SFworkProcAdded = 0; XtAppContext SFapp; int SFpathScrollWidth, SFvScrollHeight, SFhScrollWidth; char SFtextBuffer[MAXPATHLEN]; XtIntervalId SFdirModTimerId; int (*SFfunc)(); static char *oneLineTextEditTranslations = "\ Return: redraw-display()\n\ CtrlM: redraw-display()\n\ "; /* ARGSUSED */ static void SFexposeList(w, n, event, cont) Widget w; XtPointer n; XEvent *event; Boolean *cont; { if ((event->type == NoExpose) || event->xexpose.count) { return; } SFdrawList(n, SF_DO_NOT_SCROLL); } /* ARGSUSED */ static void SFmodVerifyCallback(w, client_data, event, cont) Widget w; XtPointer client_data; XEvent *event; Boolean *cont; { char buf[2]; if ( (XLookupString(&(event->xkey), buf, 2, NULL, NULL) == 1) && ((*buf) == '\r') ) { SFstatus = SEL_FILE_OK; } else { SFstatus = SEL_FILE_TEXT; } } /* ARGSUSED */ static void SFokCallback(w, cl, cd) Widget w; XtPointer cl, cd; { SFstatus = SEL_FILE_OK; } static XtCallbackRec SFokSelect[] = { { SFokCallback, (XtPointer) NULL }, { NULL, (XtPointer) NULL }, }; /* ARGSUSED */ static void SFcancelCallback(w, cl, cd) Widget w; XtPointer cl, cd; { SFstatus = SEL_FILE_CANCEL; } static XtCallbackRec SFcancelSelect[] = { { SFcancelCallback, (XtPointer) NULL }, { NULL, (XtPointer) NULL }, }; /* ARGSUSED */ static void SFdismissAction(w, event, params, num_params) Widget w; XEvent *event; String *params; Cardinal *num_params; { if (event->type == ClientMessage && event->xclient.data.l[0] != SFwmDeleteWindow) return; SFstatus = SEL_FILE_CANCEL; } static char *wmDeleteWindowTranslation = "\ WM_PROTOCOLS: SelFileDismiss()\n\ "; static XtActionsRec actions[] = { {"SelFileDismiss", SFdismissAction}, }; static void SFcreateWidgets(toplevel, prompt, ok, cancel) Widget toplevel; char *prompt; char *ok; char *cancel; { Cardinal i, n; int listWidth, listHeight; int listSpacing = 10; int scrollThickness = 15; int hScrollX, hScrollY; int vScrollX, vScrollY; Cursor xtermCursor, sbRightArrowCursor, dotCursor; Arg arglist[20]; i = 0; XtSetArg(arglist[i], XtNtransientFor, toplevel); i++; selFile = XtAppCreateShell("selFile", "SelFile", transientShellWidgetClass, SFdisplay, arglist, i); /* Add WM_DELETE_WINDOW protocol */ XtAppAddActions(XtWidgetToApplicationContext(selFile), actions, XtNumber(actions)); XtOverrideTranslations(selFile, XtParseTranslationTable(wmDeleteWindowTranslation)); i = 0; XtSetArg(arglist[i], XtNdefaultDistance, 30); i++; selFileForm = XtCreateManagedWidget("selFileForm", formWidgetClass, selFile, arglist, i); i = 0; XtSetArg(arglist[i], XtNlabel, prompt); i++; XtSetArg(arglist[i], XtNresizable, True); i++; XtSetArg(arglist[i], XtNtop, XtChainTop); i++; XtSetArg(arglist[i], XtNbottom, XtChainTop); i++; XtSetArg(arglist[i], XtNleft, XtChainLeft); i++; XtSetArg(arglist[i], XtNright, XtChainLeft); i++; XtSetArg(arglist[i], XtNborderWidth, 0); i++; selFilePrompt = XtCreateManagedWidget("selFilePrompt", labelWidgetClass, selFileForm, arglist, i); i = 0; XtSetArg(arglist[i], XtNforeground, &SFfore); i++; XtSetArg(arglist[i], XtNbackground, &SFback); i++; XtGetValues(selFilePrompt, arglist, i); SFinitFont(); SFentryWidth = SFbesideText + SFcharsPerEntry * SFcharWidth + SFbesideText; SFentryHeight = SFaboveAndBelowText + SFcharHeight + SFaboveAndBelowText; listWidth = SFlineToTextH + SFentryWidth + SFlineToTextH + 1 + scrollThickness; listHeight = SFlineToTextV + SFentryHeight + SFlineToTextV + 1 + SFlineToTextV + SFlistSize * SFentryHeight + SFlineToTextV + 1 + scrollThickness; SFpathScrollWidth = 3 * listWidth + 2 * listSpacing + 4; hScrollX = -1; hScrollY = SFlineToTextV + SFentryHeight + SFlineToTextV + 1 + SFlineToTextV + SFlistSize * SFentryHeight + SFlineToTextV; SFhScrollWidth = SFlineToTextH + SFentryWidth + SFlineToTextH; vScrollX = SFlineToTextH + SFentryWidth + SFlineToTextH; vScrollY = SFlineToTextV + SFentryHeight + SFlineToTextV; SFvScrollHeight = SFlineToTextV + SFlistSize * SFentryHeight + SFlineToTextV; SFupperX = SFlineToTextH + SFentryWidth + SFlineToTextH - 1; SFlowerY = SFlineToTextV + SFentryHeight + SFlineToTextV + 1 + SFlineToTextV; SFupperY = SFlineToTextV + SFentryHeight + SFlineToTextV + 1 + SFlineToTextV + SFlistSize * SFentryHeight - 1; SFtextX = SFlineToTextH + SFbesideText; SFtextYoffset = SFlowerY + SFaboveAndBelowText + SFcharAscent; SFsegs[0].x1 = 0; SFsegs[0].y1 = vScrollY; SFsegs[0].x2 = vScrollX - 1; SFsegs[0].y2 = vScrollY; SFsegs[1].x1 = vScrollX; SFsegs[1].y1 = 0; SFsegs[1].x2 = vScrollX; SFsegs[1].y2 = vScrollY - 1; SFcompletionSegs[0].x1 = SFcompletionSegs[0].x2 = SFlineToTextH; SFcompletionSegs[1].x1 = SFcompletionSegs[1].x2 = SFlineToTextH + SFentryWidth - 1; i = 0; XtSetArg(arglist[i], XtNwidth, 3 * listWidth + 2 * listSpacing + 4); i++; XtSetArg(arglist[i], XtNborderColor, SFfore); i++; XtSetArg(arglist[i], XtNfromVert, selFilePrompt); i++; XtSetArg(arglist[i], XtNvertDistance, 10); i++; XtSetArg(arglist[i], XtNresizable, True); i++; XtSetArg(arglist[i], XtNtop, XtChainTop); i++; XtSetArg(arglist[i], XtNbottom, XtChainTop); i++; XtSetArg(arglist[i], XtNleft, XtChainLeft); i++; XtSetArg(arglist[i], XtNright, XtChainLeft); i++; XtSetArg(arglist[i], XtNstring, SFtextBuffer); i++; XtSetArg(arglist[i], XtNlength, MAXPATHLEN); i++; XtSetArg(arglist[i], XtNeditType, XawtextEdit); i++; XtSetArg(arglist[i], XtNwrap, XawtextWrapWord); i++; XtSetArg(arglist[i], XtNresize, XawtextResizeHeight); i++; XtSetArg(arglist[i], XtNuseStringInPlace, True); i++; selFileField = XtCreateManagedWidget("selFileField", asciiTextWidgetClass, selFileForm, arglist, i); XtOverrideTranslations(selFileField, XtParseTranslationTable(oneLineTextEditTranslations)); XtSetKeyboardFocus(selFileForm, selFileField); i = 0; XtSetArg(arglist[i], XtNorientation, XtorientHorizontal); i++; XtSetArg(arglist[i], XtNwidth, SFpathScrollWidth); i++; XtSetArg(arglist[i], XtNheight, scrollThickness); i++; XtSetArg(arglist[i], XtNborderColor, SFfore); i++; XtSetArg(arglist[i], XtNfromVert, selFileField); i++; XtSetArg(arglist[i], XtNvertDistance, 30); i++; XtSetArg(arglist[i], XtNtop, XtChainTop); i++; XtSetArg(arglist[i], XtNbottom, XtChainTop); i++; XtSetArg(arglist[i], XtNleft, XtChainLeft); i++; XtSetArg(arglist[i], XtNright, XtChainLeft); i++; selFileHScroll = XtCreateManagedWidget("selFileHScroll", scrollbarWidgetClass, selFileForm, arglist, i); XtAddCallback(selFileHScroll, XtNjumpProc, SFpathSliderMovedCallback, (XtPointer) NULL); XtAddCallback(selFileHScroll, XtNscrollProc, SFpathAreaSelectedCallback, (XtPointer) NULL); i = 0; XtSetArg(arglist[i], XtNwidth, listWidth); i++; XtSetArg(arglist[i], XtNheight, listHeight); i++; XtSetArg(arglist[i], XtNborderColor, SFfore); i++; XtSetArg(arglist[i], XtNfromVert, selFileHScroll); i++; XtSetArg(arglist[i], XtNvertDistance, 10); i++; XtSetArg(arglist[i], XtNtop, XtChainTop); i++; XtSetArg(arglist[i], XtNbottom, XtChainTop); i++; XtSetArg(arglist[i], XtNleft, XtChainLeft); i++; XtSetArg(arglist[i], XtNright, XtChainLeft); i++; selFileLists[0] = XtCreateManagedWidget("selFileList1", compositeWidgetClass, selFileForm, arglist, i); i = 0; XtSetArg(arglist[i], XtNwidth, listWidth); i++; XtSetArg(arglist[i], XtNheight, listHeight); i++; XtSetArg(arglist[i], XtNborderColor, SFfore); i++; XtSetArg(arglist[i], XtNfromHoriz, selFileLists[0]); i++; XtSetArg(arglist[i], XtNfromVert, selFileHScroll); i++; XtSetArg(arglist[i], XtNhorizDistance, listSpacing); i++; XtSetArg(arglist[i], XtNvertDistance, 10); i++; XtSetArg(arglist[i], XtNtop, XtChainTop); i++; XtSetArg(arglist[i], XtNbottom, XtChainTop); i++; XtSetArg(arglist[i], XtNleft, XtChainLeft); i++; XtSetArg(arglist[i], XtNright, XtChainLeft); i++; selFileLists[1] = XtCreateManagedWidget("selFileList2", compositeWidgetClass, selFileForm, arglist, i); i = 0; XtSetArg(arglist[i], XtNwidth, listWidth); i++; XtSetArg(arglist[i], XtNheight, listHeight); i++; XtSetArg(arglist[i], XtNborderColor, SFfore); i++; XtSetArg(arglist[i], XtNfromHoriz, selFileLists[1]); i++; XtSetArg(arglist[i], XtNfromVert, selFileHScroll); i++; XtSetArg(arglist[i], XtNhorizDistance, listSpacing); i++; XtSetArg(arglist[i], XtNvertDistance, 10); i++; XtSetArg(arglist[i], XtNtop, XtChainTop); i++; XtSetArg(arglist[i], XtNbottom, XtChainTop); i++; XtSetArg(arglist[i], XtNleft, XtChainLeft); i++; XtSetArg(arglist[i], XtNright, XtChainLeft); i++; selFileLists[2] = XtCreateManagedWidget("selFileList3", compositeWidgetClass, selFileForm, arglist, i); for (n = 0; n < 3; n++) { i = 0; XtSetArg(arglist[i], XtNx, vScrollX); i++; XtSetArg(arglist[i], XtNy, vScrollY); i++; XtSetArg(arglist[i], XtNwidth, scrollThickness); i++; XtSetArg(arglist[i], XtNheight, SFvScrollHeight); i++; XtSetArg(arglist[i], XtNborderColor, SFfore); i++; selFileVScrolls[n] = XtCreateManagedWidget("selFileVScroll", scrollbarWidgetClass, selFileLists[n], arglist, i); XtAddCallback(selFileVScrolls[n], XtNjumpProc, SFvFloatSliderMovedCallback, (XtPointer) n); XtAddCallback(selFileVScrolls[n], XtNscrollProc, SFvAreaSelectedCallback, (XtPointer) n); i = 0; XtSetArg(arglist[i], XtNorientation, XtorientHorizontal); i++; XtSetArg(arglist[i], XtNx, hScrollX); i++; XtSetArg(arglist[i], XtNy, hScrollY); i++; XtSetArg(arglist[i], XtNwidth, SFhScrollWidth); i++; XtSetArg(arglist[i], XtNheight, scrollThickness); i++; XtSetArg(arglist[i], XtNborderColor, SFfore); i++; selFileHScrolls[n] = XtCreateManagedWidget("selFileHScroll", scrollbarWidgetClass, selFileLists[n], arglist, i); XtAddCallback(selFileHScrolls[n], XtNjumpProc, SFhSliderMovedCallback, (XtPointer) n); XtAddCallback(selFileHScrolls[n], XtNscrollProc, SFhAreaSelectedCallback, (XtPointer) n); } i = 0; XtSetArg(arglist[i], XtNlabel, ok); i++; XtSetArg(arglist[i], XtNresizable, True); i++; XtSetArg(arglist[i], XtNcallback, SFokSelect); i++; XtSetArg(arglist[i], XtNborderColor, SFfore); i++; XtSetArg(arglist[i], XtNfromVert, selFileLists[0]); i++; XtSetArg(arglist[i], XtNvertDistance, 30); i++; XtSetArg(arglist[i], XtNtop, XtChainTop); i++; XtSetArg(arglist[i], XtNbottom, XtChainTop); i++; XtSetArg(arglist[i], XtNleft, XtChainLeft); i++; XtSetArg(arglist[i], XtNright, XtChainLeft); i++; selFileOK = XtCreateManagedWidget("selFileOK", commandWidgetClass, selFileForm, arglist, i); i = 0; XtSetArg(arglist[i], XtNlabel, cancel); i++; XtSetArg(arglist[i], XtNresizable, True); i++; XtSetArg(arglist[i], XtNcallback, SFcancelSelect); i++; XtSetArg(arglist[i], XtNborderColor, SFfore); i++; XtSetArg(arglist[i], XtNfromHoriz, selFileOK); i++; XtSetArg(arglist[i], XtNfromVert, selFileLists[0]); i++; XtSetArg(arglist[i], XtNhorizDistance, 30); i++; XtSetArg(arglist[i], XtNvertDistance, 30); i++; XtSetArg(arglist[i], XtNtop, XtChainTop); i++; XtSetArg(arglist[i], XtNbottom, XtChainTop); i++; XtSetArg(arglist[i], XtNleft, XtChainLeft); i++; XtSetArg(arglist[i], XtNright, XtChainLeft); i++; selFileCancel = XtCreateManagedWidget("selFileCancel", commandWidgetClass, selFileForm, arglist, i); XtSetMappedWhenManaged(selFile, False); XtRealizeWidget(selFile); /* Add WM_DELETE_WINDOW protocol */ SFwmDeleteWindow = XInternAtom(SFdisplay, "WM_DELETE_WINDOW", False); XSetWMProtocols(SFdisplay, XtWindow(selFile), &SFwmDeleteWindow, 1); SFcreateGC(); xtermCursor = XCreateFontCursor(SFdisplay, XC_xterm); sbRightArrowCursor = XCreateFontCursor(SFdisplay, XC_sb_right_arrow); dotCursor = XCreateFontCursor(SFdisplay, XC_dot); XDefineCursor(SFdisplay, XtWindow(selFileForm), xtermCursor); XDefineCursor(SFdisplay, XtWindow(selFileField), xtermCursor); for (n = 0; n < 3; n++) { XDefineCursor(SFdisplay, XtWindow(selFileLists[n]), sbRightArrowCursor); } XDefineCursor(SFdisplay, XtWindow(selFileOK), dotCursor); XDefineCursor(SFdisplay, XtWindow(selFileCancel), dotCursor); for (n = 0; n < 3; n++) { XtAddEventHandler(selFileLists[n], ExposureMask, True, SFexposeList, (XtPointer) n); XtAddEventHandler(selFileLists[n], EnterWindowMask, False, SFenterList, (XtPointer) n); XtAddEventHandler(selFileLists[n], LeaveWindowMask, False, SFleaveList, (XtPointer) n); XtAddEventHandler(selFileLists[n], PointerMotionMask, False, SFmotionList, (XtPointer) n); XtAddEventHandler(selFileLists[n], ButtonPressMask, False, SFbuttonPressList, (XtPointer) n); XtAddEventHandler(selFileLists[n], ButtonReleaseMask, False, SFbuttonReleaseList, (XtPointer) n); } XtAddEventHandler(selFileField, KeyPressMask, False, SFmodVerifyCallback, (XtPointer) NULL); SFapp = XtWidgetToApplicationContext(selFile); } /* position widget under the cursor */ void SFpositionWidget(w) Widget w; { Arg args[3]; Cardinal num_args; Dimension width, height, b_width; int x, y, max_x, max_y; Window root, child; int dummyx, dummyy; unsigned int dummymask; XQueryPointer(XtDisplay(w), XtWindow(w), &root, &child, &x, &y, &dummyx, &dummyy, &dummymask); num_args = 0; XtSetArg(args[num_args], XtNwidth, &width); num_args++; XtSetArg(args[num_args], XtNheight, &height); num_args++; XtSetArg(args[num_args], XtNborderWidth, &b_width); num_args++; XtGetValues(w, args, num_args); width += 2 * b_width; height += 2 * b_width; x -= ( (Position) width/2 ); if (x < 0) x = 0; if ( x > (max_x = (Position) (XtScreen(w)->width - width)) ) x = max_x; y -= ( (Position) height/2 ); if (y < 0) y = 0; if ( y > (max_y = (Position) (XtScreen(w)->height - height)) ) y = max_y; num_args = 0; XtSetArg(args[num_args], XtNx, x); num_args++; XtSetArg(args[num_args], XtNy, y); num_args++; XtSetValues(w, args, num_args); } FILE * SFopenFile(name, mode, prompt, failed) char *name; char *mode; char *prompt; char *failed; { Arg args[1]; FILE *fp; SFchdir(SFstartDir); if ((fp = fopen(name, mode)) == NULL) { char *buf; if (errno <= sys_nerr) { buf = XtMalloc(strlen(failed) + strlen(sys_errlist[errno]) + strlen(prompt) + 2); strcpy(buf, failed); strcat(buf, sys_errlist[errno]); strcat(buf, "\n"); strcat(buf, prompt); } else { buf = XtMalloc(strlen(failed) + strlen(prompt) + 2); strcpy(buf, failed); strcat(buf, "\n"); strcat(buf, prompt); } XtSetArg(args[0], XtNlabel, buf); XtSetValues(selFilePrompt, args, ONE); XtFree(buf); return NULL; } return fp; } SFtextChanged() { if ((SFtextBuffer[0] == '/') || (SFtextBuffer[0] == '~')) { (void) strcpy(SFcurrentPath, SFtextBuffer); SFtextPos = XawTextGetInsertionPoint(selFileField); } else { (void) strcat(strcpy(SFcurrentPath, SFstartDir), SFtextBuffer); SFtextPos = XawTextGetInsertionPoint(selFileField) + strlen(SFstartDir); } if (!SFworkProcAdded) { (void) XtAppAddWorkProc(SFapp, SFworkProc, NULL); SFworkProcAdded = 1; } SFupdatePath(); } static char * SFgetText() { return strcpy(XtMalloc((unsigned) (strlen(SFtextBuffer) + 1)), SFtextBuffer); } static SFprepareToReturn() { SFstatus = SEL_FILE_NULL; XtRemoveGrab(selFile); XtUnmapWidget(selFile); XtRemoveTimeOut(SFdirModTimerId); if (SFchdir(SFstartDir)) { XtAppError( SFapp, "XsraSelFile: can't return to current directory" ); } } FILE * XsraSelFile(toplevel, prompt, ok, cancel, failed, init_path, mode, show_entry, name_return) Widget toplevel; char *prompt; char *ok; char *cancel; char *failed; char *init_path; char *mode; int (*show_entry)(); char **name_return; { static int firstTime = 1; Cardinal i; Arg arglist[20]; XEvent event; FILE *fp; if (!prompt) { prompt = "Pathname:"; } if (!ok) { ok = "OK"; } if (!cancel) { cancel = "Cancel"; } if (firstTime) { firstTime = 0; SFdisplay = XtDisplay(toplevel); SFcreateWidgets(toplevel, prompt, ok, cancel); } else { i = 0; XtSetArg(arglist[i], XtNlabel, prompt); i++; XtSetValues(selFilePrompt, arglist, i); i = 0; XtSetArg(arglist[i], XtNlabel, ok); i++; XtSetValues(selFileOK, arglist, i); i = 0; XtSetArg(arglist[i], XtNlabel, cancel); i++; XtSetValues(selFileCancel, arglist, i); } SFpositionWidget(selFile); XtMapWidget(selFile); #if defined(SVR4) || defined(SYSV) || defined(USG) if (!getcwd(SFstartDir, MAXPATHLEN)) { #else /* defined(SVR4) || defined(SYSV) || defined(USG) */ if (!getwd(SFstartDir)) { #endif /* defined(SVR4) || defined(SYSV) || defined(USG) */ XtAppError(SFapp, "XsraSelFile: can't get current directory"); } (void) strcat(SFstartDir, "/"); (void) strcpy(SFcurrentDir, SFstartDir); if (init_path) { if (init_path[0] == '/') { (void) strcpy(SFcurrentPath, init_path); if (strncmp( SFcurrentPath, SFstartDir, strlen(SFstartDir) )) { SFsetText(SFcurrentPath); } else { SFsetText(&(SFcurrentPath[strlen(SFstartDir)])); } } else { (void) strcat(strcpy(SFcurrentPath, SFstartDir), init_path); SFsetText(&(SFcurrentPath[strlen(SFstartDir)])); } } else { (void) strcpy(SFcurrentPath, SFstartDir); } SFfunc = show_entry; SFtextChanged(); XtAddGrab(selFile, True, True); SFdirModTimerId = XtAppAddTimeOut(SFapp, (unsigned long) 1000, SFdirModTimer, (XtPointer) NULL); while (1) { XtAppNextEvent(SFapp, &event); XtDispatchEvent(&event); switch (SFstatus) { case SEL_FILE_TEXT: SFstatus = SEL_FILE_NULL; SFtextChanged(); break; case SEL_FILE_OK: *name_return = SFgetText(); if (fp = SFopenFile(*name_return, mode, prompt, failed)) { SFprepareToReturn(); return fp; } SFstatus = SEL_FILE_NULL; break; case SEL_FILE_CANCEL: SFprepareToReturn(); return NULL; case SEL_FILE_NULL: break; } } }