"Fossies" - the Fresh Open Source Software Archive

Member "ghostview-1.5/Draw.c" (24 Jul 1993, 16936 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 #include <stdio.h>
   28 #include "SFinternal.h"
   29 #include "xstat.h"
   30 #include <X11/StringDefs.h>
   31 #include <X11/Xaw/Scrollbar.h>
   32 #include <X11/Xaw/Cardinals.h>
   33 
   34 #define SF_DEFAULT_FONT "9x15"
   35 
   36 #ifdef ABS
   37 #undef ABS
   38 #endif
   39 #define ABS(x) (((x) < 0) ? (-(x)) : (x))
   40 
   41 typedef struct {
   42     char *fontname;
   43 } TextData, *textPtr;
   44 
   45 int SFcharWidth, SFcharAscent, SFcharHeight;
   46 
   47 int SFcurrentInvert[3] = { -1, -1, -1 };
   48 
   49 static GC SFlineGC, SFscrollGC, SFinvertGC, SFtextGC;
   50 
   51 static XtResource textResources[] = {
   52     {XtNfont, XtCFont, XtRString, sizeof (char *),
   53         XtOffset(textPtr, fontname), XtRString, SF_DEFAULT_FONT},
   54 };
   55 
   56 static XFontStruct *SFfont;
   57 
   58 static int SFcurrentListY;
   59 
   60 static XtIntervalId SFscrollTimerId;
   61 
   62 SFinitFont()
   63 {
   64     TextData    *data;
   65 
   66     data = XtNew(TextData);
   67 
   68     XtGetApplicationResources(selFileForm, (XtPointer) data, textResources,
   69         XtNumber(textResources), (Arg *) NULL, ZERO);
   70 
   71     SFfont = XLoadQueryFont(SFdisplay, data->fontname);
   72     if (!SFfont) {
   73         SFfont = XLoadQueryFont(SFdisplay, SF_DEFAULT_FONT);
   74         if (!SFfont) {
   75             char    sbuf[256];
   76 
   77             (void) sprintf(sbuf, "XsraSelFile: can't get font %s",
   78                 SF_DEFAULT_FONT);
   79 
   80             XtAppError(SFapp, sbuf);
   81         }
   82     }
   83 
   84     SFcharWidth = (SFfont->max_bounds.width + SFfont->min_bounds.width) / 2;
   85     SFcharAscent = SFfont->max_bounds.ascent;
   86     SFcharHeight = SFcharAscent + SFfont->max_bounds.descent;
   87 }
   88 
   89 SFcreateGC()
   90 {
   91     XGCValues   gcValues;
   92     XRectangle  rectangles[1];
   93 
   94     gcValues.foreground = SFfore;
   95 
   96     SFlineGC = XtGetGC(
   97         selFileLists[0],
   98         (XtGCMask)
   99             GCForeground        |
  100             0,
  101         &gcValues
  102     );
  103 
  104     SFscrollGC = XtGetGC(
  105         selFileLists[0],
  106         (XtGCMask)
  107             0,
  108         &gcValues
  109     );
  110 
  111     gcValues.function = GXinvert;
  112     gcValues.plane_mask = (SFfore ^ SFback);
  113 
  114     SFinvertGC = XtGetGC(
  115         selFileLists[0],
  116         (XtGCMask)
  117             GCFunction      |
  118             GCPlaneMask     |
  119             0,
  120         &gcValues
  121     );
  122 
  123     gcValues.foreground = SFfore;
  124     gcValues.background = SFback;
  125     gcValues.font = SFfont->fid;
  126 
  127     SFtextGC = XCreateGC(
  128         SFdisplay,
  129         XtWindow(selFileLists[0]),
  130         (unsigned long)
  131             GCForeground        |
  132             GCBackground        |
  133             GCFont          |
  134             0,
  135         &gcValues
  136     );
  137 
  138     rectangles[0].x = SFlineToTextH + SFbesideText;
  139     rectangles[0].y = 0;
  140     rectangles[0].width = SFcharsPerEntry * SFcharWidth;
  141     rectangles[0].height = SFupperY + 1;
  142 
  143     XSetClipRectangles(
  144         SFdisplay,
  145         SFtextGC,
  146         0,
  147         0,
  148         rectangles,
  149         1,
  150         Unsorted
  151     );
  152 }
  153 
  154 SFclearList(n, doScroll)
  155     int n;
  156     int doScroll;
  157 {
  158     SFDir   *dir;
  159 
  160     SFcurrentInvert[n] = -1;
  161 
  162     XClearWindow(SFdisplay, XtWindow(selFileLists[n]));
  163 
  164     XDrawSegments(SFdisplay, XtWindow(selFileLists[n]), SFlineGC, SFsegs,
  165         2);
  166 
  167     if (doScroll) {
  168         dir = &(SFdirs[SFdirPtr + n]);
  169 
  170         if ((SFdirPtr + n < SFdirEnd) && dir->nEntries && dir->nChars) {
  171             XawScrollbarSetThumb(
  172                 selFileVScrolls[n],
  173                 (float) (((double) dir->vOrigin) /
  174                     dir->nEntries),
  175                 (float) (((double) ((dir->nEntries < SFlistSize)
  176                     ? dir->nEntries : SFlistSize)) /
  177                     dir->nEntries)
  178             );
  179 
  180             XawScrollbarSetThumb(
  181                 selFileHScrolls[n],
  182                 (float) (((double) dir->hOrigin) / dir->nChars),
  183                 (float) (((double) ((dir->nChars <
  184                     SFcharsPerEntry) ? dir->nChars :
  185                     SFcharsPerEntry)) / dir->nChars)
  186             );
  187         } else {
  188             XawScrollbarSetThumb(selFileVScrolls[n], (float) 0.0,
  189                 (float) 1.0);
  190             XawScrollbarSetThumb(selFileHScrolls[n], (float) 0.0,
  191                 (float) 1.0);
  192         }
  193     }
  194 }
  195 
  196 static
  197 SFdeleteEntry(dir, entry)
  198     SFDir   *dir;
  199     SFEntry *entry;
  200 {
  201     register SFEntry    *e;
  202     register SFEntry    *end;
  203     int         n;
  204     int         idx;
  205 
  206     idx = entry - dir->entries;
  207 
  208     if (idx < dir->beginSelection) {
  209         dir->beginSelection--;
  210     }
  211     if (idx <= dir->endSelection) {
  212         dir->endSelection--;
  213     }
  214     if (dir->beginSelection > dir->endSelection) {
  215         dir->beginSelection = dir->endSelection = -1;
  216     }
  217 
  218     if (idx < dir->vOrigin) {
  219         dir->vOrigin--;
  220     }
  221 
  222     XtFree(entry->real);
  223 
  224     end = &(dir->entries[dir->nEntries - 1]);
  225 
  226     for (e = entry; e < end; e++) {
  227         *e = *(e + 1);
  228     }
  229 
  230     if (!(--dir->nEntries)) {
  231         return;
  232     }
  233 
  234     n = dir - &(SFdirs[SFdirPtr]);
  235     if ((n < 0) || (n > 2)) {
  236         return;
  237     }
  238 
  239     XawScrollbarSetThumb(
  240         selFileVScrolls[n],
  241         (float) (((double) dir->vOrigin) / dir->nEntries),
  242         (float) (((double) ((dir->nEntries < SFlistSize) ?
  243             dir->nEntries : SFlistSize)) / dir->nEntries)
  244     );
  245 }
  246 
  247 static
  248 SFwriteStatChar(name, last, statBuf)
  249     char        *name;
  250     int     last;
  251     struct stat *statBuf;
  252 {
  253     name[last] = SFstatChar(statBuf);
  254 }
  255 
  256 static int
  257 SFstatAndCheck(dir, entry)
  258     SFDir   *dir;
  259     SFEntry *entry;
  260 {
  261     struct stat statBuf;
  262     char        save;
  263     int     last;
  264 
  265     /*
  266      * must be restored before returning
  267      */
  268     save = *(dir->path);
  269     *(dir->path) = 0;
  270 
  271     if (!SFchdir(SFcurrentPath)) {
  272         last = strlen(entry->real) - 1;
  273         entry->real[last] = 0;
  274         entry->statDone = 1;
  275         if (
  276             (!stat(entry->real, &statBuf))
  277 
  278 #ifdef S_IFLNK
  279 
  280              || (!lstat(entry->real, &statBuf))
  281 
  282 #endif /* ndef S_IFLNK */
  283 
  284         ) {
  285             if (SFfunc) {
  286                 char *shown;
  287 
  288                 shown = NULL;
  289                 if (SFfunc(entry->real, &shown, &statBuf)) {
  290                     if (shown) {
  291                         int len;
  292 
  293                         len = strlen(shown);
  294                         entry->shown = XtMalloc(
  295                             (unsigned) (len + 2)
  296                         );
  297                         (void) strcpy(entry->shown,
  298                             shown);
  299                         SFwriteStatChar(
  300                             entry->shown,
  301                             len,
  302                             &statBuf
  303                         );
  304                         entry->shown[len + 1] = 0;
  305                     }
  306                 } else {
  307                     SFdeleteEntry(dir, entry);
  308 
  309                     *(dir->path) = save;
  310                     return 1;
  311                 }
  312             }
  313             SFwriteStatChar(entry->real, last, &statBuf);
  314         } else {
  315             entry->real[last] = ' ';
  316         }
  317     }
  318 
  319     *(dir->path) = save;
  320     return 0;
  321 }
  322 
  323 static
  324 SFdrawStrings(w, dir, from, to)
  325     register Window w;
  326     register SFDir  *dir;
  327     register int    from;
  328     register int    to;
  329 {
  330     register int        i;
  331     register SFEntry    *entry;
  332     int         x;
  333 
  334     x = SFtextX - dir->hOrigin * SFcharWidth;
  335 
  336     if (dir->vOrigin + to >= dir->nEntries) {
  337         to = dir->nEntries - dir->vOrigin - 1;
  338     }
  339     for (i = from; i <= to; i++) {
  340         entry = &(dir->entries[dir->vOrigin + i]);
  341         if (!(entry->statDone)) {
  342             if (SFstatAndCheck(dir, entry)) {
  343                 if (dir->vOrigin + to >= dir->nEntries) {
  344                     to = dir->nEntries - dir->vOrigin - 1;
  345                 }
  346                 i--;
  347                 continue;
  348             }
  349         }
  350         XDrawImageString(
  351             SFdisplay,
  352             w,
  353             SFtextGC,
  354             x,
  355             SFtextYoffset + i * SFentryHeight,
  356             entry->shown,
  357             strlen(entry->shown)
  358         );
  359         if (dir->vOrigin + i == dir->beginSelection) {
  360             XDrawLine(
  361                 SFdisplay,
  362                 w,
  363                 SFlineGC,
  364                 SFlineToTextH + 1,
  365                 SFlowerY + i * SFentryHeight,
  366                 SFlineToTextH + SFentryWidth - 2,
  367                 SFlowerY + i * SFentryHeight
  368             );
  369         }
  370         if (
  371             (dir->vOrigin + i >= dir->beginSelection) &&
  372             (dir->vOrigin + i <= dir->endSelection)
  373         ) {
  374             SFcompletionSegs[0].y1 = SFcompletionSegs[1].y1 =
  375                 SFlowerY + i * SFentryHeight;
  376             SFcompletionSegs[0].y2 = SFcompletionSegs[1].y2 =
  377                 SFlowerY + (i + 1) * SFentryHeight - 1;
  378             XDrawSegments(
  379                 SFdisplay,
  380                 w,
  381                 SFlineGC,
  382                 SFcompletionSegs,
  383                 2
  384             );
  385         }
  386         if (dir->vOrigin + i == dir->endSelection) {
  387             XDrawLine(
  388                 SFdisplay,
  389                 w,
  390                 SFlineGC,
  391                 SFlineToTextH + 1,
  392                 SFlowerY + (i + 1) * SFentryHeight - 1,
  393                 SFlineToTextH + SFentryWidth - 2,
  394                 SFlowerY + (i + 1) * SFentryHeight - 1
  395             );
  396         }
  397     }
  398 }
  399 
  400 SFdrawList(n, doScroll)
  401     int n;
  402     int doScroll;
  403 {
  404     SFDir   *dir;
  405     Window  w;
  406 
  407     SFclearList(n, doScroll);
  408 
  409     if (SFdirPtr + n < SFdirEnd) {
  410         dir = &(SFdirs[SFdirPtr + n]);
  411         w = XtWindow(selFileLists[n]);
  412         XDrawImageString(
  413             SFdisplay,
  414             w,
  415             SFtextGC,
  416             SFtextX - dir->hOrigin * SFcharWidth,
  417             SFlineToTextV + SFaboveAndBelowText + SFcharAscent,
  418             dir->dir,
  419             strlen(dir->dir)
  420         );
  421         SFdrawStrings(w, dir, 0, SFlistSize - 1);
  422     }
  423 }
  424 
  425 SFdrawLists(doScroll)
  426     int doScroll;
  427 {
  428     int i;
  429 
  430     for (i = 0; i < 3; i++) {
  431         SFdrawList(i, doScroll);
  432     }
  433 }
  434 
  435 static
  436 SFinvertEntry(n)
  437     register int    n;
  438 {
  439     XFillRectangle(
  440         SFdisplay,
  441         XtWindow(selFileLists[n]),
  442         SFinvertGC,
  443         SFlineToTextH,
  444         SFcurrentInvert[n] * SFentryHeight + SFlowerY,
  445         SFentryWidth,
  446         SFentryHeight
  447     );
  448 }
  449 
  450 static unsigned long
  451 SFscrollTimerInterval()
  452 {
  453     static int  maxVal = 200;
  454     static int  varyDist = 50;
  455     static int  minDist = 50;
  456     int     t;
  457     int     dist;
  458 
  459     if (SFcurrentListY < SFlowerY) {
  460         dist = SFlowerY - SFcurrentListY;
  461     } else if (SFcurrentListY > SFupperY) {
  462         dist = SFcurrentListY - SFupperY;
  463     } else {
  464         return (unsigned long) 1;
  465     }
  466 
  467     t = maxVal - ((maxVal / varyDist) * (dist - minDist));
  468 
  469     if (t < 1) {
  470         t = 1;
  471     }
  472 
  473     if (t > maxVal) {
  474         t = maxVal;
  475     }
  476 
  477     return (unsigned long) t;
  478 }
  479 
  480 static void
  481 SFscrollTimer(p, id)
  482     XtPointer   p;
  483         XtIntervalId    *id;
  484 {
  485     SFDir   *dir;
  486     int save;
  487     int     n;
  488 
  489         n = (int) p;
  490 
  491     dir = &(SFdirs[SFdirPtr + n]);
  492     save = dir->vOrigin;
  493 
  494     if (SFcurrentListY < SFlowerY) {
  495         if (dir->vOrigin > 0) {
  496             SFvSliderMovedCallback(selFileVScrolls[n], n,
  497                 dir->vOrigin - 1);
  498         }
  499     } else if (SFcurrentListY > SFupperY) {
  500         if (dir->vOrigin < dir->nEntries - SFlistSize) {
  501             SFvSliderMovedCallback(selFileVScrolls[n], n,
  502                 dir->vOrigin + 1);
  503         }
  504     }
  505 
  506     if (dir->vOrigin != save) {
  507         if (dir->nEntries) {
  508             XawScrollbarSetThumb(
  509             selFileVScrolls[n],
  510             (float) (((double) dir->vOrigin) / dir->nEntries),
  511             (float) (((double) ((dir->nEntries < SFlistSize) ?
  512                 dir->nEntries : SFlistSize)) / dir->nEntries)
  513             );
  514         }
  515     }
  516 
  517     if (SFbuttonPressed) {
  518         SFscrollTimerId = XtAppAddTimeOut(SFapp,
  519             SFscrollTimerInterval(), SFscrollTimer, (XtPointer) n);
  520     }
  521 }
  522 
  523 static int
  524 SFnewInvertEntry(n, event)
  525     register int        n;
  526     register XMotionEvent   *event;
  527 {
  528     register int    x, y;
  529     register int    new;
  530     static int  SFscrollTimerAdded = 0;
  531 
  532     x = event->x;
  533     y = event->y;
  534 
  535     if (SFdirPtr + n >= SFdirEnd) {
  536         return -1;
  537     } else if (
  538         (x >= 0)    && (x <= SFupperX) &&
  539         (y >= SFlowerY) && (y <= SFupperY)
  540     ) {
  541         register SFDir *dir = &(SFdirs[SFdirPtr + n]);
  542 
  543         if (SFscrollTimerAdded) {
  544             SFscrollTimerAdded = 0;
  545             XtRemoveTimeOut(SFscrollTimerId);
  546         }
  547 
  548         new = (y - SFlowerY) / SFentryHeight;
  549         if (dir->vOrigin + new >= dir->nEntries) {
  550             return -1;
  551         }
  552         return new;
  553     } else {
  554         if (SFbuttonPressed) {
  555             SFcurrentListY = y;
  556             if (!SFscrollTimerAdded) {
  557                 SFscrollTimerAdded = 1;
  558                 SFscrollTimerId = XtAppAddTimeOut(SFapp,
  559                     SFscrollTimerInterval(), SFscrollTimer,
  560                     (XtPointer) n);
  561             }
  562         }
  563 
  564         return -1;
  565     }
  566 }
  567 
  568 /* ARGSUSED */
  569 void
  570 SFenterList(w, n, event)
  571     Widget              w;
  572     register int            n;
  573     register XEnterWindowEvent  *event;
  574 {
  575     register int    new;
  576 
  577     /* sanity */
  578     if (SFcurrentInvert[n] != -1) {
  579         SFinvertEntry(n);
  580         SFcurrentInvert[n] = -1;
  581     }
  582 
  583     new = SFnewInvertEntry(n, (XMotionEvent *) event);
  584     if (new != -1) {
  585         SFcurrentInvert[n] = new;
  586         SFinvertEntry(n);
  587     }
  588 }
  589 
  590 /* ARGSUSED */
  591 void
  592 SFleaveList(w, n, event)
  593     Widget      w;
  594     register int    n;
  595     XEvent      *event;
  596 {
  597     if (SFcurrentInvert[n] != -1) {
  598         SFinvertEntry(n);
  599         SFcurrentInvert[n] = -1;
  600     }
  601 }
  602 
  603 /* ARGSUSED */
  604 void
  605 SFmotionList(w, n, event)
  606     Widget          w;
  607     register int        n;
  608     register XMotionEvent   *event;
  609 {
  610     register int    new;
  611 
  612     new = SFnewInvertEntry(n, event);
  613 
  614     if (new != SFcurrentInvert[n]) {
  615         if (SFcurrentInvert[n] != -1) {
  616             SFinvertEntry(n);
  617         }
  618         SFcurrentInvert[n] = new;
  619         if (new != -1) {
  620             SFinvertEntry(n);
  621         }
  622     }
  623 }
  624 
  625 /* ARGSUSED */
  626 void
  627 SFvFloatSliderMovedCallback(w, n, fnew)
  628     Widget  w;
  629     int n;
  630     float   *fnew;
  631 {
  632     int new;
  633 
  634     new = (*fnew) * SFdirs[SFdirPtr + n].nEntries;
  635 
  636     SFvSliderMovedCallback(w, n, new);
  637 }
  638 
  639 /* ARGSUSED */
  640 void
  641 SFvSliderMovedCallback(w, n, new)
  642     Widget  w;
  643     int n;
  644     int new;
  645 {
  646     int     old;
  647     register Window win;
  648     SFDir       *dir;
  649 
  650     dir = &(SFdirs[SFdirPtr + n]);
  651 
  652     old = dir->vOrigin;
  653     dir->vOrigin = new;
  654 
  655     if (old == new) {
  656         return;
  657     }
  658 
  659     win = XtWindow(selFileLists[n]);
  660 
  661     if (ABS(new - old) < SFlistSize) {
  662         if (new > old) {
  663             XCopyArea(
  664                 SFdisplay,
  665                 win,
  666                 win,
  667                 SFscrollGC,
  668                 SFlineToTextH,
  669                 SFlowerY + (new - old) * SFentryHeight,
  670                 SFentryWidth + SFlineToTextH,
  671                 (SFlistSize - (new - old)) * SFentryHeight,
  672                 SFlineToTextH,
  673                 SFlowerY
  674             );
  675             XClearArea(
  676                 SFdisplay,
  677                 win,
  678                 SFlineToTextH,
  679                 SFlowerY + (SFlistSize - (new - old)) *
  680                     SFentryHeight,
  681                 SFentryWidth + SFlineToTextH,
  682                 (new - old) * SFentryHeight,
  683                 False
  684             );
  685             SFdrawStrings(win, dir, SFlistSize - (new - old),
  686                 SFlistSize - 1);
  687         } else {
  688             XCopyArea(
  689                 SFdisplay,
  690                 win,
  691                 win,
  692                 SFscrollGC,
  693                 SFlineToTextH,
  694                 SFlowerY,
  695                 SFentryWidth + SFlineToTextH,
  696                 (SFlistSize - (old - new)) * SFentryHeight,
  697                 SFlineToTextH,
  698                 SFlowerY + (old - new) * SFentryHeight
  699             );
  700             XClearArea(
  701                 SFdisplay,
  702                 win,
  703                 SFlineToTextH,
  704                 SFlowerY,
  705                 SFentryWidth + SFlineToTextH,
  706                 (old - new) * SFentryHeight,
  707                 False
  708             );
  709             SFdrawStrings(win, dir, 0, old - new);
  710         }
  711     } else {
  712         XClearArea(
  713             SFdisplay,
  714             win,
  715             SFlineToTextH,
  716             SFlowerY,
  717             SFentryWidth + SFlineToTextH,
  718             SFlistSize * SFentryHeight,
  719             False
  720         );
  721         SFdrawStrings(win, dir, 0, SFlistSize - 1);
  722     }
  723 }
  724 
  725 /* ARGSUSED */
  726 void
  727 SFvAreaSelectedCallback(w, n, pnew)
  728     Widget  w;
  729     int n;
  730     int pnew;
  731 {
  732     SFDir   *dir;
  733     int new;
  734 
  735     dir = &(SFdirs[SFdirPtr + n]);
  736 
  737     new = dir->vOrigin +
  738         (((double) pnew) / SFvScrollHeight) * dir->nEntries;
  739 
  740     if (new > dir->nEntries - SFlistSize) {
  741         new = dir->nEntries - SFlistSize;
  742     }
  743 
  744     if (new < 0) {
  745         new = 0;
  746     }
  747 
  748     if (dir->nEntries) {
  749         float   f;
  750 
  751         f = ((double) new) / dir->nEntries;
  752 
  753         XawScrollbarSetThumb(
  754             w,
  755             f,
  756             (float) (((double) ((dir->nEntries < SFlistSize) ?
  757                 dir->nEntries : SFlistSize)) / dir->nEntries)
  758         );
  759     }
  760 
  761     SFvSliderMovedCallback(w, n, new);
  762 }
  763 
  764 /* ARGSUSED */
  765 void
  766 SFhSliderMovedCallback(w, n, new)
  767     Widget  w;
  768     int n;
  769     float   *new;
  770 {
  771     SFDir   *dir;
  772     int save;
  773 
  774     dir = &(SFdirs[SFdirPtr + n]);
  775     save = dir->hOrigin;
  776     dir->hOrigin = (*new) * dir->nChars;
  777     if (dir->hOrigin == save) {
  778         return;
  779     }
  780 
  781     SFdrawList(n, SF_DO_NOT_SCROLL);
  782 }
  783 
  784 /* ARGSUSED */
  785 void
  786 SFhAreaSelectedCallback(w, n, pnew)
  787     Widget  w;
  788     int n;
  789     int pnew;
  790 {
  791     SFDir   *dir;
  792     int new;
  793 
  794     dir = &(SFdirs[SFdirPtr + n]);
  795 
  796     new = dir->hOrigin +
  797         (((double) pnew) / SFhScrollWidth) * dir->nChars;
  798 
  799     if (new > dir->nChars - SFcharsPerEntry) {
  800         new = dir->nChars - SFcharsPerEntry;
  801     }
  802 
  803     if (new < 0) {
  804         new = 0;
  805     }
  806 
  807     if (dir->nChars) {
  808         float   f;
  809 
  810         f = ((double) new) / dir->nChars;
  811 
  812         XawScrollbarSetThumb(
  813             w,
  814             f,
  815             (float) (((double) ((dir->nChars < SFcharsPerEntry) ?
  816                 dir->nChars : SFcharsPerEntry)) / dir->nChars)
  817         );
  818 
  819         SFhSliderMovedCallback(w, n, &f);
  820     }
  821 }
  822 
  823 /* ARGSUSED */
  824 void
  825 SFpathSliderMovedCallback(w, client_data, new)
  826     Widget      w;
  827     XtPointer   client_data;
  828     float   *new;
  829 {
  830     SFDir       *dir;
  831     int     n;
  832     XawTextPosition pos;
  833     int SFdirPtrSave;
  834 
  835     SFdirPtrSave = SFdirPtr;
  836     SFdirPtr = (*new) * SFdirEnd;
  837     if (SFdirPtr == SFdirPtrSave) {
  838         return;
  839     }
  840 
  841     SFdrawLists(SF_DO_SCROLL);
  842 
  843     n = 2;
  844     while (SFdirPtr + n >= SFdirEnd) {
  845         n--;
  846     }
  847 
  848     dir = &(SFdirs[SFdirPtr + n]);
  849 
  850     pos = dir->path - SFcurrentPath;
  851 
  852     if (!strncmp(SFcurrentPath, SFstartDir, strlen(SFstartDir))) {
  853         pos -= strlen(SFstartDir);
  854         if (pos < 0) {
  855             pos = 0;
  856         }
  857     }
  858 
  859     XawTextSetInsertionPoint(selFileField, pos);
  860 }
  861 
  862 /* ARGSUSED */
  863 
  864 void
  865 SFpathAreaSelectedCallback(w, client_data, pnew)
  866     Widget      w;
  867     XtPointer   client_data;
  868     int     pnew;
  869 {
  870     int new;
  871     float   f;
  872 
  873     new = SFdirPtr + (((double) pnew) / SFpathScrollWidth) * SFdirEnd;
  874 
  875     if (new > SFdirEnd - 3) {
  876         new = SFdirEnd - 3;
  877     }
  878 
  879     if (new < 0) {
  880         new = 0;
  881     }
  882 
  883     f = ((double) new) / SFdirEnd;
  884 
  885     XawScrollbarSetThumb(
  886         w,
  887         f,
  888         (float) (((double) ((SFdirEnd < 3) ? SFdirEnd : 3)) /
  889             SFdirEnd)
  890     );
  891 
  892     SFpathSliderMovedCallback(w, (XtPointer) NULL, &f);
  893 }
  894 
  895 Boolean
  896 SFworkProc()
  897 {
  898     register SFDir      *dir;
  899     register SFEntry    *entry;
  900 
  901     for (dir = &(SFdirs[SFdirEnd - 1]); dir >= SFdirs; dir--) {
  902         if (!(dir->nEntries)) {
  903             continue;
  904         }
  905         for (
  906             entry = &(dir->entries[dir->nEntries - 1]);
  907             entry >= dir->entries;
  908             entry--
  909         ) {
  910             if (!(entry->statDone)) {
  911                 (void) SFstatAndCheck(dir, entry);
  912                 return False;
  913             }
  914         }
  915     }
  916 
  917     SFworkProcAdded = 0;
  918 
  919     return True;
  920 }