"Fossies" - the Fresh Open Source Software Archive

Member "ghostview-1.4.1/SelFile.c" (15 Apr 1992, 21244 Bytes) of package /linux/misc/old/ghost/gnu/ghostview/ghostview-1.4.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2  * Copyright 1989 Software Research Associates, Inc., Tokyo, Japan
    3  *
    4  * Permission to use, copy, modify, and distribute this software and its
    5  * documentation for any purpose and without fee is hereby granted, provided
    6  * that the above copyright notice appear in all copies and that both that
    7  * copyright notice and this permission notice appear in supporting
    8  * documentation, and that the name of Software Research Associates not be used
    9  * in advertising or publicity pertaining to distribution of the software
   10  * without specific, written prior permission.  Software Research Associates
   11  * makes no representations about the suitability of this software for any
   12  * purpose.  It is provided "as is" without express or implied warranty.
   13  *
   14  * SOFTWARE RESEARCH ASSOCIATES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
   15  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
   16  * IN NO EVENT SHALL SOFTWARE RESEARCH ASSOCIATES BE LIABLE FOR ANY SPECIAL,
   17  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
   18  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
   19  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
   20  * PERFORMANCE OF THIS SOFTWARE.
   21  *
   22  * Author: Erik M. van der Poel
   23  *         Software Research Associates, Inc., Tokyo, Japan
   24  *         erik@sra.co.jp
   25  */
   26 
   27 /*
   28  * Author's address:
   29  *
   30  *     erik@sra.co.jp
   31  *                                            OR
   32  *     erik%sra.co.jp@uunet.uu.net
   33  *                                            OR
   34  *     erik%sra.co.jp@mcvax.uucp
   35  *                                            OR
   36  *     try junet instead of co.jp
   37  *                                            OR
   38  *     Erik M. van der Poel
   39  *     Software Research Associates, Inc.
   40  *     1-1-1 Hirakawa-cho, Chiyoda-ku
   41  *     Tokyo 102 Japan. TEL +81-3-234-2692
   42  */
   43 
   44 #include <stdio.h>
   45 #include <errno.h>
   46 /* BSD 4.3 errno.h does not declare errno */
   47 extern int errno;
   48 extern int sys_nerr;
   49 extern char *sys_errlist[];
   50 
   51 #include <sys/param.h>
   52 #include <X11/cursorfont.h>
   53 #include <X11/Intrinsic.h>
   54 #include <X11/StringDefs.h>
   55 #include <X11/Composite.h>
   56 #include <X11/Shell.h>
   57 #include <X11/Xaw/Form.h>
   58 #include <X11/Xaw/Command.h>
   59 #include <X11/Xaw/Scrollbar.h>
   60 #include <X11/Xaw/Label.h>
   61 
   62 #include "SFinternal.h"
   63 
   64 #ifndef MAXPATHLEN
   65 #define MAXPATHLEN 1024
   66 #endif /* ndef MAXPATHLEN */
   67 
   68 #if !defined(SVR4) && !defined(SYSV) && !defined(USG)
   69 extern char *getwd();
   70 #endif /* !defined(SVR4) && !defined(SYSV) && !defined(USG) */
   71 
   72 int SFstatus = SEL_FILE_NULL;
   73 
   74 char
   75     SFstartDir[MAXPATHLEN],
   76     SFcurrentPath[MAXPATHLEN],
   77     SFcurrentDir[MAXPATHLEN];
   78 
   79 Widget
   80     selFile,
   81     selFileCancel,
   82     selFileField,
   83     selFileForm,
   84     selFileHScroll,
   85     selFileHScrolls[3],
   86     selFileLists[3],
   87     selFileOK,
   88     selFilePrompt,
   89     selFileVScrolls[3];
   90 
   91 Display *SFdisplay;
   92 
   93 Pixel SFfore, SFback;
   94 
   95 Atom    SFwmDeleteWindow;
   96 
   97 XSegment SFsegs[2], SFcompletionSegs[2];
   98 
   99 XawTextPosition SFtextPos;
  100 
  101 int SFupperX, SFlowerY, SFupperY;
  102 
  103 int SFtextX, SFtextYoffset;
  104 
  105 int SFentryWidth, SFentryHeight;
  106 
  107 int SFlineToTextH = 3;
  108 
  109 int SFlineToTextV = 3;
  110 
  111 int SFbesideText = 3;
  112 
  113 int SFaboveAndBelowText = 2;
  114 
  115 int SFcharsPerEntry = 15;
  116 
  117 int SFlistSize = 10;
  118 
  119 int SFworkProcAdded = 0;
  120 
  121 XtAppContext SFapp;
  122 
  123 int SFpathScrollWidth, SFvScrollHeight, SFhScrollWidth;
  124 
  125 char SFtextBuffer[MAXPATHLEN];
  126 
  127 XtIntervalId SFdirModTimerId;
  128 
  129 int (*SFfunc)();
  130 
  131 static char *oneLineTextEditTranslations = "\
  132     <Key>Return:    redraw-display()\n\
  133     Ctrl<Key>M: redraw-display()\n\
  134 ";
  135 
  136 /* ARGSUSED */
  137 static void
  138 SFexposeList(w, n, event)
  139     Widget      w;
  140     int     n;
  141     XExposeEvent    *event;
  142 {
  143     if ((event->type == NoExpose) || event->count) {
  144         return;
  145     }
  146 
  147     SFdrawList(n, SF_DO_NOT_SCROLL);
  148 }
  149 
  150 /* ARGSUSED */
  151 static void
  152 SFmodVerifyCallback(w, client_data, event)
  153     Widget          w;
  154     XtPointer       client_data;
  155     XKeyPressedEvent    *event;
  156 {
  157     char    buf[2];
  158 
  159     if (
  160         (XLookupString(event, buf, 2, NULL, NULL) == 1) &&
  161         ((*buf) == '\r')
  162     ) {
  163         SFstatus = SEL_FILE_OK;
  164     } else {
  165         SFstatus = SEL_FILE_TEXT;
  166     }
  167 }
  168 
  169 /* ARGSUSED */
  170 static void
  171 SFokCallback(w)
  172     Widget  w;
  173 {
  174     SFstatus = SEL_FILE_OK;
  175 }
  176 
  177 static XtCallbackRec SFokSelect[] = {
  178     { SFokCallback, (XtPointer) NULL },
  179     { NULL, (XtPointer) NULL },
  180 };
  181 
  182 /* ARGSUSED */
  183 static void
  184 SFcancelCallback(w)
  185     Widget  w;
  186 {
  187     SFstatus = SEL_FILE_CANCEL;
  188 }
  189 
  190 static XtCallbackRec SFcancelSelect[] = {
  191     { SFcancelCallback, (XtPointer) NULL },
  192     { NULL, (XtPointer) NULL },
  193 };
  194 
  195 /* ARGSUSED */
  196 static void
  197 SFdismissAction(w, event, params, num_params)
  198     Widget  w;
  199     XEvent *event;
  200     String *params;
  201     Cardinal *num_params;
  202 {
  203     if (event->type == ClientMessage &&
  204         event->xclient.data.l[0] != SFwmDeleteWindow) return;
  205 
  206     SFstatus = SEL_FILE_CANCEL;
  207 }
  208 
  209 static char *wmDeleteWindowTranslation = "\
  210     <Message>WM_PROTOCOLS:  SelFileDismiss()\n\
  211 ";
  212 
  213 static XtActionsRec actions[] = {
  214     {"SelFileDismiss",  SFdismissAction},
  215 };
  216 
  217 static void
  218 SFcreateWidgets(toplevel, prompt, ok, cancel)
  219     Widget  toplevel;
  220     char    *prompt;
  221     char    *ok;
  222     char    *cancel;
  223 {
  224     int     i, n;
  225     int     listWidth, listHeight;
  226     int     listSpacing = 10;
  227     int     scrollThickness = 15;
  228     int     hScrollX, hScrollY;
  229     int     vScrollX, vScrollY;
  230     Cursor
  231             xtermCursor,
  232             sbRightArrowCursor,
  233             dotCursor;
  234     Arg     arglist[20];
  235 
  236     i = 0;
  237     XtSetArg(arglist[i], XtNtransientFor, toplevel);        i++;
  238 
  239     selFile = XtAppCreateShell("selFile", "SelFile",
  240         transientShellWidgetClass, SFdisplay, arglist, i);
  241 
  242     /* Add WM_DELETE_WINDOW protocol */
  243     XtAppAddActions(XtWidgetToApplicationContext(selFile),
  244         actions, XtNumber(actions));
  245     XtOverrideTranslations(selFile,
  246         XtParseTranslationTable(wmDeleteWindowTranslation));
  247 
  248     i = 0;
  249     XtSetArg(arglist[i], XtNdefaultDistance, 30);           i++;
  250     selFileForm = XtCreateManagedWidget("selFileForm",
  251         formWidgetClass, selFile, arglist, i);
  252 
  253     i = 0;
  254     XtSetArg(arglist[i], XtNlabel, prompt);             i++;
  255     XtSetArg(arglist[i], XtNresizable, True);           i++;
  256     XtSetArg(arglist[i], XtNtop, XtChainTop);           i++;
  257     XtSetArg(arglist[i], XtNbottom, XtChainTop);            i++;
  258     XtSetArg(arglist[i], XtNleft, XtChainLeft);         i++;
  259     XtSetArg(arglist[i], XtNright, XtChainLeft);            i++;
  260     XtSetArg(arglist[i], XtNborderWidth, 0);            i++;
  261     selFilePrompt = XtCreateManagedWidget("selFilePrompt",
  262         labelWidgetClass, selFileForm, arglist, i);
  263 
  264     i = 0;
  265     XtSetArg(arglist[i], XtNforeground, &SFfore);           i++;
  266     XtSetArg(arglist[i], XtNbackground, &SFback);           i++;
  267     XtGetValues(selFilePrompt, arglist, i);
  268 
  269     SFinitFont();
  270 
  271     SFentryWidth = SFbesideText + SFcharsPerEntry * SFcharWidth +
  272             SFbesideText;
  273     SFentryHeight = SFaboveAndBelowText + SFcharHeight +
  274             SFaboveAndBelowText;
  275 
  276     listWidth = SFlineToTextH + SFentryWidth + SFlineToTextH + 1 +
  277             scrollThickness;
  278     listHeight = SFlineToTextV + SFentryHeight + SFlineToTextV + 1 +
  279             SFlineToTextV + SFlistSize * SFentryHeight +
  280             SFlineToTextV + 1 + scrollThickness;
  281 
  282     SFpathScrollWidth = 3 * listWidth + 2 * listSpacing + 4;
  283 
  284     hScrollX = -1;
  285     hScrollY = SFlineToTextV + SFentryHeight + SFlineToTextV + 1 +
  286             SFlineToTextV + SFlistSize * SFentryHeight +
  287             SFlineToTextV;
  288     SFhScrollWidth = SFlineToTextH + SFentryWidth + SFlineToTextH;
  289 
  290     vScrollX = SFlineToTextH + SFentryWidth + SFlineToTextH;
  291     vScrollY = SFlineToTextV + SFentryHeight + SFlineToTextV;
  292     SFvScrollHeight = SFlineToTextV + SFlistSize * SFentryHeight +
  293             SFlineToTextV;
  294 
  295     SFupperX = SFlineToTextH + SFentryWidth + SFlineToTextH - 1;
  296     SFlowerY = SFlineToTextV + SFentryHeight + SFlineToTextV + 1 +
  297             SFlineToTextV;
  298     SFupperY = SFlineToTextV + SFentryHeight + SFlineToTextV + 1 +
  299             SFlineToTextV + SFlistSize * SFentryHeight - 1;
  300 
  301     SFtextX = SFlineToTextH + SFbesideText;
  302     SFtextYoffset = SFlowerY + SFaboveAndBelowText + SFcharAscent;
  303 
  304     SFsegs[0].x1 = 0;
  305     SFsegs[0].y1 = vScrollY;
  306     SFsegs[0].x2 = vScrollX - 1;
  307     SFsegs[0].y2 = vScrollY;
  308     SFsegs[1].x1 = vScrollX;
  309     SFsegs[1].y1 = 0;
  310     SFsegs[1].x2 = vScrollX;
  311     SFsegs[1].y2 = vScrollY - 1;
  312 
  313     SFcompletionSegs[0].x1 = SFcompletionSegs[0].x2 = SFlineToTextH;
  314     SFcompletionSegs[1].x1 = SFcompletionSegs[1].x2 =
  315         SFlineToTextH + SFentryWidth - 1;
  316 
  317     i = 0;
  318     XtSetArg(arglist[i], XtNwidth, 3 * listWidth + 2 * listSpacing + 4);
  319                                     i++;
  320     XtSetArg(arglist[i], XtNborderColor, SFfore);           i++;
  321 
  322     XtSetArg(arglist[i], XtNfromVert, selFilePrompt);       i++;
  323     XtSetArg(arglist[i], XtNvertDistance, 10);          i++;
  324     XtSetArg(arglist[i], XtNresizable, True);           i++;
  325     XtSetArg(arglist[i], XtNtop, XtChainTop);           i++;
  326     XtSetArg(arglist[i], XtNbottom, XtChainTop);            i++;
  327     XtSetArg(arglist[i], XtNleft, XtChainLeft);         i++;
  328     XtSetArg(arglist[i], XtNright, XtChainLeft);            i++;
  329     XtSetArg(arglist[i], XtNstring, SFtextBuffer);          i++;
  330     XtSetArg(arglist[i], XtNlength, MAXPATHLEN);            i++;
  331     XtSetArg(arglist[i], XtNeditType, XawtextEdit);         i++;
  332     XtSetArg(arglist[i], XtNwrap, XawtextWrapWord);         i++;
  333     XtSetArg(arglist[i], XtNresize, XawtextResizeHeight);       i++;
  334     XtSetArg(arglist[i], XtNuseStringInPlace, True);        i++;
  335     selFileField = XtCreateManagedWidget("selFileField",
  336         asciiTextWidgetClass, selFileForm, arglist, i);
  337 
  338     XtOverrideTranslations(selFileField,
  339         XtParseTranslationTable(oneLineTextEditTranslations));
  340     XtSetKeyboardFocus(selFileForm, selFileField);
  341 
  342     i = 0;
  343     XtSetArg(arglist[i], XtNorientation, XtorientHorizontal);   i++;
  344     XtSetArg(arglist[i], XtNwidth, SFpathScrollWidth);      i++;
  345     XtSetArg(arglist[i], XtNheight, scrollThickness);       i++;
  346     XtSetArg(arglist[i], XtNborderColor, SFfore);           i++;
  347     XtSetArg(arglist[i], XtNfromVert, selFileField);        i++;
  348     XtSetArg(arglist[i], XtNvertDistance, 30);          i++;
  349     XtSetArg(arglist[i], XtNtop, XtChainTop);           i++;
  350     XtSetArg(arglist[i], XtNbottom, XtChainTop);            i++;
  351     XtSetArg(arglist[i], XtNleft, XtChainLeft);         i++;
  352     XtSetArg(arglist[i], XtNright, XtChainLeft);            i++;
  353     selFileHScroll = XtCreateManagedWidget("selFileHScroll",
  354         scrollbarWidgetClass, selFileForm, arglist, i);
  355 
  356     XtAddCallback(selFileHScroll, XtNjumpProc,
  357         SFpathSliderMovedCallback, (XtPointer) NULL);
  358     XtAddCallback(selFileHScroll, XtNscrollProc,
  359         SFpathAreaSelectedCallback, (XtPointer) NULL);
  360 
  361     i = 0;
  362     XtSetArg(arglist[i], XtNwidth, listWidth);          i++;
  363     XtSetArg(arglist[i], XtNheight, listHeight);            i++;
  364     XtSetArg(arglist[i], XtNborderColor, SFfore);           i++;
  365     XtSetArg(arglist[i], XtNfromVert, selFileHScroll);      i++;
  366     XtSetArg(arglist[i], XtNvertDistance, 10);          i++;
  367     XtSetArg(arglist[i], XtNtop, XtChainTop);           i++;
  368     XtSetArg(arglist[i], XtNbottom, XtChainTop);            i++;
  369     XtSetArg(arglist[i], XtNleft, XtChainLeft);         i++;
  370     XtSetArg(arglist[i], XtNright, XtChainLeft);            i++;
  371     selFileLists[0] = XtCreateManagedWidget("selFileList1",
  372         compositeWidgetClass, selFileForm, arglist, i);
  373 
  374     i = 0;
  375     XtSetArg(arglist[i], XtNwidth, listWidth);          i++;
  376     XtSetArg(arglist[i], XtNheight, listHeight);            i++;
  377     XtSetArg(arglist[i], XtNborderColor, SFfore);           i++;
  378     XtSetArg(arglist[i], XtNfromHoriz, selFileLists[0]);        i++;
  379     XtSetArg(arglist[i], XtNfromVert, selFileHScroll);      i++;
  380     XtSetArg(arglist[i], XtNhorizDistance, listSpacing);        i++;
  381     XtSetArg(arglist[i], XtNvertDistance, 10);          i++;
  382     XtSetArg(arglist[i], XtNtop, XtChainTop);           i++;
  383     XtSetArg(arglist[i], XtNbottom, XtChainTop);            i++;
  384     XtSetArg(arglist[i], XtNleft, XtChainLeft);         i++;
  385     XtSetArg(arglist[i], XtNright, XtChainLeft);            i++;
  386     selFileLists[1] = XtCreateManagedWidget("selFileList2",
  387         compositeWidgetClass, selFileForm, arglist, i);
  388 
  389     i = 0;
  390     XtSetArg(arglist[i], XtNwidth, listWidth);          i++;
  391     XtSetArg(arglist[i], XtNheight, listHeight);            i++;
  392     XtSetArg(arglist[i], XtNborderColor, SFfore);           i++;
  393     XtSetArg(arglist[i], XtNfromHoriz, selFileLists[1]);        i++;
  394     XtSetArg(arglist[i], XtNfromVert, selFileHScroll);      i++;
  395     XtSetArg(arglist[i], XtNhorizDistance, listSpacing);        i++;
  396     XtSetArg(arglist[i], XtNvertDistance, 10);          i++;
  397     XtSetArg(arglist[i], XtNtop, XtChainTop);           i++;
  398     XtSetArg(arglist[i], XtNbottom, XtChainTop);            i++;
  399     XtSetArg(arglist[i], XtNleft, XtChainLeft);         i++;
  400     XtSetArg(arglist[i], XtNright, XtChainLeft);            i++;
  401     selFileLists[2] = XtCreateManagedWidget("selFileList3",
  402         compositeWidgetClass, selFileForm, arglist, i);
  403 
  404     for (n = 0; n < 3; n++) {
  405 
  406         i = 0;
  407         XtSetArg(arglist[i], XtNx, vScrollX);           i++;
  408         XtSetArg(arglist[i], XtNy, vScrollY);           i++;
  409         XtSetArg(arglist[i], XtNwidth, scrollThickness);    i++;
  410         XtSetArg(arglist[i], XtNheight, SFvScrollHeight);   i++;
  411         XtSetArg(arglist[i], XtNborderColor, SFfore);       i++;
  412         selFileVScrolls[n] = XtCreateManagedWidget("selFileVScroll",
  413             scrollbarWidgetClass, selFileLists[n], arglist, i);
  414 
  415         XtAddCallback(selFileVScrolls[n], XtNjumpProc,
  416             SFvFloatSliderMovedCallback, (XtPointer) n);
  417         XtAddCallback(selFileVScrolls[n], XtNscrollProc,
  418             SFvAreaSelectedCallback, (XtPointer) n);
  419 
  420         i = 0;
  421 
  422         XtSetArg(arglist[i], XtNorientation, XtorientHorizontal);
  423                                     i++;
  424         XtSetArg(arglist[i], XtNx, hScrollX);           i++;
  425         XtSetArg(arglist[i], XtNy, hScrollY);           i++;
  426         XtSetArg(arglist[i], XtNwidth, SFhScrollWidth);     i++;
  427         XtSetArg(arglist[i], XtNheight, scrollThickness);   i++;
  428         XtSetArg(arglist[i], XtNborderColor, SFfore);       i++;
  429         selFileHScrolls[n] = XtCreateManagedWidget("selFileHScroll",
  430             scrollbarWidgetClass, selFileLists[n], arglist, i);
  431 
  432         XtAddCallback(selFileHScrolls[n], XtNjumpProc,
  433             SFhSliderMovedCallback, (XtPointer) n);
  434         XtAddCallback(selFileHScrolls[n], XtNscrollProc,
  435             SFhAreaSelectedCallback, (XtPointer) n);
  436     }
  437 
  438     i = 0;
  439     XtSetArg(arglist[i], XtNlabel, ok);             i++;
  440     XtSetArg(arglist[i], XtNresizable, True);           i++;
  441     XtSetArg(arglist[i], XtNcallback, SFokSelect);          i++;
  442     XtSetArg(arglist[i], XtNborderColor, SFfore);           i++;
  443     XtSetArg(arglist[i], XtNfromVert, selFileLists[0]);     i++;
  444     XtSetArg(arglist[i], XtNvertDistance, 30);          i++;
  445     XtSetArg(arglist[i], XtNtop, XtChainTop);           i++;
  446     XtSetArg(arglist[i], XtNbottom, XtChainTop);            i++;
  447     XtSetArg(arglist[i], XtNleft, XtChainLeft);         i++;
  448     XtSetArg(arglist[i], XtNright, XtChainLeft);            i++;
  449     selFileOK = XtCreateManagedWidget("selFileOK", commandWidgetClass,
  450         selFileForm, arglist, i);
  451 
  452     i = 0;
  453     XtSetArg(arglist[i], XtNlabel, cancel);             i++;
  454     XtSetArg(arglist[i], XtNresizable, True);           i++;
  455     XtSetArg(arglist[i], XtNcallback, SFcancelSelect);      i++;
  456     XtSetArg(arglist[i], XtNborderColor, SFfore);           i++;
  457     XtSetArg(arglist[i], XtNfromHoriz, selFileOK);          i++;
  458     XtSetArg(arglist[i], XtNfromVert, selFileLists[0]);     i++;
  459     XtSetArg(arglist[i], XtNhorizDistance, 30);         i++;
  460     XtSetArg(arglist[i], XtNvertDistance, 30);          i++;
  461     XtSetArg(arglist[i], XtNtop, XtChainTop);           i++;
  462     XtSetArg(arglist[i], XtNbottom, XtChainTop);            i++;
  463     XtSetArg(arglist[i], XtNleft, XtChainLeft);         i++;
  464     XtSetArg(arglist[i], XtNright, XtChainLeft);            i++;
  465     selFileCancel = XtCreateManagedWidget("selFileCancel",
  466         commandWidgetClass, selFileForm, arglist, i);
  467 
  468     XtSetMappedWhenManaged(selFile, False);
  469     XtRealizeWidget(selFile);
  470 
  471     /* Add WM_DELETE_WINDOW protocol */
  472     SFwmDeleteWindow = XInternAtom(SFdisplay, "WM_DELETE_WINDOW", False);
  473     XSetWMProtocols(SFdisplay, XtWindow(selFile), &SFwmDeleteWindow, 1);
  474 
  475     SFcreateGC();
  476 
  477     xtermCursor = XCreateFontCursor(SFdisplay, XC_xterm);
  478 
  479     sbRightArrowCursor = XCreateFontCursor(SFdisplay, XC_sb_right_arrow);
  480     dotCursor = XCreateFontCursor(SFdisplay, XC_dot);
  481 
  482     XDefineCursor(SFdisplay, XtWindow(selFileForm), xtermCursor);
  483     XDefineCursor(SFdisplay, XtWindow(selFileField), xtermCursor);
  484 
  485     for (n = 0; n < 3; n++) {
  486         XDefineCursor(SFdisplay, XtWindow(selFileLists[n]),
  487             sbRightArrowCursor);
  488     }
  489     XDefineCursor(SFdisplay, XtWindow(selFileOK), dotCursor);
  490     XDefineCursor(SFdisplay, XtWindow(selFileCancel), dotCursor);
  491 
  492     for (n = 0; n < 3; n++) {
  493         XtAddEventHandler(selFileLists[n], ExposureMask, True,
  494             SFexposeList, (XtPointer) n);
  495         XtAddEventHandler(selFileLists[n], EnterWindowMask, False,
  496             SFenterList, (XtPointer) n);
  497         XtAddEventHandler(selFileLists[n], LeaveWindowMask, False,
  498             SFleaveList, (XtPointer) n);
  499         XtAddEventHandler(selFileLists[n], PointerMotionMask, False,
  500             SFmotionList, (XtPointer) n);
  501         XtAddEventHandler(selFileLists[n], ButtonPressMask, False,
  502             SFbuttonPressList, (XtPointer) n);
  503         XtAddEventHandler(selFileLists[n], ButtonReleaseMask, False,
  504             SFbuttonReleaseList, (XtPointer) n);
  505     }
  506 
  507     XtAddEventHandler(selFileField, KeyPressMask, False,
  508         SFmodVerifyCallback, (XtPointer) NULL);
  509 
  510     SFapp = XtWidgetToApplicationContext(selFile);
  511 
  512 }
  513 
  514 /* position widget under the cursor */
  515 void
  516 SFpositionWidget(w)
  517     Widget w;
  518 {
  519     Arg args[3];
  520     Cardinal num_args;
  521     Dimension width, height, b_width;
  522     int x, y, max_x, max_y;
  523     Window root, child;
  524     int dummyx, dummyy;
  525     unsigned int dummymask;
  526     
  527     XQueryPointer(XtDisplay(w), XtWindow(w), &root, &child, &x, &y,
  528           &dummyx, &dummyy, &dummymask);
  529     num_args = 0;
  530     XtSetArg(args[num_args], XtNwidth, &width); num_args++;
  531     XtSetArg(args[num_args], XtNheight, &height); num_args++;
  532     XtSetArg(args[num_args], XtNborderWidth, &b_width); num_args++;
  533     XtGetValues(w, args, num_args);
  534 
  535     width += 2 * b_width;
  536     height += 2 * b_width;
  537 
  538     x -= ( (Position) width/2 );
  539     if (x < 0) x = 0;
  540     if ( x > (max_x = (Position) (XtScreen(w)->width - width)) ) x = max_x;
  541 
  542     y -= ( (Position) height/2 );
  543     if (y < 0) y = 0;
  544     if ( y > (max_y = (Position) (XtScreen(w)->height - height)) ) y = max_y;
  545     
  546     num_args = 0;
  547     XtSetArg(args[num_args], XtNx, x); num_args++;
  548     XtSetArg(args[num_args], XtNy, y); num_args++;
  549     XtSetValues(w, args, num_args);
  550 }
  551 
  552 FILE *
  553 SFopenFile(name, mode, prompt, failed)
  554     char *name;
  555     char *mode;
  556     char *prompt;
  557     char *failed;
  558 {
  559     Arg args[1];
  560     FILE *fp;
  561 
  562     SFchdir(SFstartDir);
  563     if ((fp = fopen(name, mode)) == NULL) {
  564     char *buf;
  565     if (errno <= sys_nerr) {
  566         buf = XtMalloc(strlen(failed) + strlen(sys_errlist[errno]) + 
  567                strlen(prompt) + 2);
  568         strcpy(buf, failed);
  569         strcat(buf, sys_errlist[errno]);
  570         strcat(buf, "\n");
  571         strcat(buf, prompt);
  572     } else {
  573         buf = XtMalloc(strlen(failed) + strlen(prompt) + 2);
  574         strcpy(buf, failed);
  575         strcat(buf, "\n");
  576         strcat(buf, prompt);
  577     }
  578     XtSetArg(args[0], XtNlabel, buf);
  579     XtSetValues(selFilePrompt, args, 1);
  580     XtFree(buf);
  581     return NULL;
  582     }
  583     return fp;
  584 }
  585 
  586 SFtextChanged()
  587 {
  588 
  589     if ((SFtextBuffer[0] == '/') || (SFtextBuffer[0] == '~')) {
  590         (void) strcpy(SFcurrentPath, SFtextBuffer);
  591 
  592         SFtextPos = XawTextGetInsertionPoint(selFileField);
  593     } else {
  594         (void) strcat(strcpy(SFcurrentPath, SFstartDir), SFtextBuffer);
  595 
  596         SFtextPos = XawTextGetInsertionPoint(selFileField) +
  597             strlen(SFstartDir);
  598     }
  599 
  600     if (!SFworkProcAdded) {
  601         (void) XtAppAddWorkProc(SFapp, SFworkProc, NULL);
  602         SFworkProcAdded = 1;
  603     }
  604 
  605     SFupdatePath();
  606 }
  607 
  608 static char *
  609 SFgetText()
  610 {
  611     return strcpy(XtMalloc((unsigned) (strlen(SFtextBuffer) + 1)),
  612         SFtextBuffer);
  613 }
  614 
  615 static
  616 SFprepareToReturn()
  617 {
  618     SFstatus = SEL_FILE_NULL;
  619     XtRemoveGrab(selFile);
  620     XtUnmapWidget(selFile);
  621     XtRemoveTimeOut(SFdirModTimerId);
  622     if (SFchdir(SFstartDir)) {
  623         XtAppError(
  624             SFapp,
  625             "XsraSelFile: can't return to current directory"
  626         );
  627     }
  628 }
  629 
  630 FILE *
  631 XsraSelFile(toplevel, prompt, ok, cancel, failed,
  632         init_path, mode, show_entry, name_return)
  633     Widget      toplevel;
  634     char        *prompt;
  635     char        *ok;
  636     char        *cancel;
  637     char        *failed;
  638     char        *init_path;
  639     char        *mode;
  640     int     (*show_entry)();
  641     char        **name_return;
  642 {
  643     static int  firstTime = 1;
  644     int     i;
  645     Arg     arglist[20];
  646     XEvent      event;
  647     FILE        *fp;
  648 
  649     if (!prompt) {
  650         prompt = "Pathname:";
  651     }
  652 
  653     if (!ok) {
  654         ok = "OK";
  655     }
  656 
  657     if (!cancel) {
  658         cancel = "Cancel";
  659     }
  660 
  661     if (firstTime) {
  662         firstTime = 0;
  663         SFdisplay = XtDisplay(toplevel);
  664         SFcreateWidgets(toplevel, prompt, ok, cancel);
  665     } else {
  666         i = 0;
  667 
  668         XtSetArg(arglist[i], XtNlabel, prompt);         i++;
  669         XtSetValues(selFilePrompt, arglist, i);
  670 
  671         i = 0;
  672         XtSetArg(arglist[i], XtNlabel, ok);         i++;
  673         XtSetValues(selFileOK, arglist, i);
  674 
  675         i = 0;
  676         XtSetArg(arglist[i], XtNlabel, cancel);         i++;
  677         XtSetValues(selFileCancel, arglist, i);
  678     }
  679 
  680     SFpositionWidget(selFile);
  681     XtMapWidget(selFile);
  682 
  683 #if defined(SVR4) || defined(SYSV) || defined(USG)
  684     if (!getcwd(SFstartDir, MAXPATHLEN)) {
  685 #else /* defined(SVR4) || defined(SYSV) || defined(USG) */
  686     if (!getwd(SFstartDir)) {
  687 #endif /* defined(SVR4) || defined(SYSV) || defined(USG) */
  688 
  689         XtAppError(SFapp, "XsraSelFile: can't get current directory");
  690     }
  691     (void) strcat(SFstartDir, "/");
  692     (void) strcpy(SFcurrentDir, SFstartDir);
  693 
  694     if (init_path) {
  695         if (init_path[0] == '/') {
  696             (void) strcpy(SFcurrentPath, init_path);
  697             if (strncmp(
  698                 SFcurrentPath,
  699                 SFstartDir,
  700                 strlen(SFstartDir)
  701             )) {
  702                 SFsetText(SFcurrentPath);
  703             } else {
  704                 SFsetText(&(SFcurrentPath[strlen(SFstartDir)]));
  705             }
  706         } else {
  707             (void) strcat(strcpy(SFcurrentPath, SFstartDir),
  708                 init_path);
  709             SFsetText(&(SFcurrentPath[strlen(SFstartDir)]));
  710         }
  711     } else {
  712         (void) strcpy(SFcurrentPath, SFstartDir);
  713     }
  714 
  715     SFfunc = show_entry;
  716 
  717     SFtextChanged();
  718 
  719     XtAddGrab(selFile, True, True);
  720 
  721     SFdirModTimerId = XtAppAddTimeOut(SFapp, (unsigned long) 1000,
  722         SFdirModTimer, (XtPointer) NULL);
  723 
  724     while (1) {
  725         XtAppNextEvent(SFapp, &event);
  726         XtDispatchEvent(&event);
  727         switch (SFstatus) {
  728         case SEL_FILE_TEXT:
  729             SFstatus = SEL_FILE_NULL;
  730             SFtextChanged();
  731             break;
  732         case SEL_FILE_OK:
  733             *name_return = SFgetText();
  734             if (fp = SFopenFile(*name_return, mode,
  735                         prompt, failed)) {
  736                 SFprepareToReturn();
  737                 return fp;
  738             }
  739             SFstatus = SEL_FILE_NULL;
  740             break;
  741         case SEL_FILE_CANCEL:
  742             SFprepareToReturn();
  743             return NULL;
  744         case SEL_FILE_NULL:
  745             break;
  746         }
  747     }
  748 }