"Fossies" - the Fresh Open Source Software Archive

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