argv@island.uu.net (Dan Heller) (06/04/89)
Submitted-by: Erik M. van der Poel <erik@sra.co.jp> Posting-number: Volume 4, Issue 15 Archive-name: xdir/part02 #!/bin/sh # to extract, remove the header and type "sh filename" if `test ! -s ./Dir.c` then echo "writing ./Dir.c" cat > ./Dir.c << '\End\Of\File\' #ifndef lint static char rcsid[] = "$Header: Dir.c,v 1.3 89/05/29 15:03:50 erik Exp $"; #endif /* * 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 */ #include <stdio.h> #ifdef SEL_FILE_IGNORE_CASE #include <ctype.h> #endif /* def SEL_FILE_IGNORE_CASE */ #include "SFinternal.h" #ifdef SYSV #include <dirent.h> #else /* def SYSV */ #include <sys/dir.h> #endif /* def SYSV */ #include <sys/stat.h> #ifdef SYSV extern void qsort(); #endif /* def SYSV */ #ifdef SEL_FILE_IGNORE_CASE int SFcompareEntries(p, q) SFEntry *p; SFEntry *q; { register char *r, *s; register char c1, c2; r = p->real; s = q->real; c1 = *r++; if (islower(c1)) { c1 = toupper(c1); } c2 = *s++; if (islower(c2)) { c2 = toupper(c2); } while (c1 == c2) { if (!c1) { return strcmp(p->real, q->real); } c1 = *r++; if (islower(c1)) { c1 = toupper(c1); } c2 = *s++; if (islower(c2)) { c2 = toupper(c2); } } return c1 - c2; } #else /* def SEL_FILE_IGNORE_CASE */ int SFcompareEntries(p, q) SFEntry *p; SFEntry *q; { return strcmp(p->real, q->real); } #endif /* def SEL_FILE_IGNORE_CASE */ int SFgetDir(dir) SFDir *dir; { SFEntry *result = NULL; int alloc = 0; int i; DIR *dirp; #ifdef SYSV struct dirent *dp; #else /* def SYSV */ struct direct *dp; #endif /* def SYSV */ char *str; int len; int maxChars; struct stat statBuf; maxChars = strlen(dir->dir) - 1; dir->entries = NULL; dir->nEntries = 0; dir->nChars = 0; result = NULL; i = 0; dirp = opendir("."); if (!dirp) { return 1; } (void) fstat(dirp->dd_fd, &statBuf); dir->st_mtime = statBuf.st_mtime; (void) readdir(dirp); /* throw away "." */ #ifndef S_IFLNK (void) readdir(dirp); /* throw away ".." */ #endif /* ndef S_IFLNK */ while (dp = readdir(dirp)) { if (i >= alloc) { alloc = 2 * (alloc + 1); result = (SFEntry *) XtRealloc((char *) result, (unsigned) (alloc * sizeof(SFEntry))); } result[i].statDone = 0; str = dp->d_name; len = strlen(str); result[i].real = XtMalloc((unsigned) (len + 2)); (void) strcat(strcpy(result[i].real, str), " "); if (len > maxChars) { maxChars = len; } result[i].shown = result[i].real; i++; } #ifdef SYSV qsort((char *) result, (unsigned) i, sizeof(SFEntry), SFcompareEntries); #else /* def SYSV */ qsort((char *) result, i, sizeof(SFEntry), SFcompareEntries); #endif /* def SYSV */ dir->entries = result; dir->nEntries = i; dir->nChars = maxChars + 1; closedir(dirp); return 0; } \End\Of\File\ else echo "will not over write ./Dir.c" fi if `test ! -s ./Draw.c` then echo "writing ./Draw.c" cat > ./Draw.c << '\End\Of\File\' #ifndef lint static char rcsid[] = "$Header: Draw.c,v 1.6 89/05/29 15:04:26 erik Exp $"; #endif /* * 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 */ #include <stdio.h> #include "SFinternal.h" #include <sys/stat.h> #include <X11/StringDefs.h> #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) #include <Xw/Xw.h> #include <Xw/ScrollBar.h> #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ #include <X11/Scroll.h> #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ #define SF_DEFAULT_FONT "9x15" #define ABS(x) (((x) < 0) ? (-(x)) : (x)) typedef struct { char *fontname; } TextData, *textPtr; int SFcharWidth, SFcharAscent, SFcharHeight; int SFcurrentInvert[3] = { -1, -1, -1 }; static GC SFlineGC, SFscrollGC, SFinvertGC, SFtextGC; static XtResource textResources[] = { {XtNfont, XtCFont, XtRString, sizeof (char *), XtOffset(textPtr, fontname), XtRString, SF_DEFAULT_FONT}, }; static XFontStruct *SFfont; static int SFcurrentListY; static XtIntervalId SFscrollTimerId; SFinitFont() { TextData *data; data = XtNew(TextData); XtGetApplicationResources(selFileForm, (caddr_t) data, textResources, XtNumber(textResources), (Arg *) NULL, 0); SFfont = XLoadQueryFont(SFdisplay, data->fontname); if (!SFfont) { SFfont = XLoadQueryFont(SFdisplay, SF_DEFAULT_FONT); if (!SFfont) { char sbuf[256]; (void) sprintf(sbuf, "XsraSelFile: can't get font %s", SF_DEFAULT_FONT); XtAppError(SFapp, sbuf); } } SFcharWidth = (SFfont->max_bounds.width + SFfont->min_bounds.width) / 2; SFcharAscent = SFfont->max_bounds.ascent; SFcharHeight = SFcharAscent + SFfont->max_bounds.descent; } SFcreateGC() { XGCValues gcValues; XRectangle rectangles[1]; gcValues.foreground = SFfore; SFlineGC = XtGetGC( selFileLists[0], (XtGCMask) GCForeground | 0, &gcValues ); SFscrollGC = XtGetGC( selFileLists[0], (XtGCMask) 0, &gcValues ); gcValues.function = GXinvert; gcValues.plane_mask = (SFfore ^ SFback); SFinvertGC = XtGetGC( selFileLists[0], (XtGCMask) GCFunction | GCPlaneMask | 0, &gcValues ); gcValues.foreground = SFfore; gcValues.background = SFback; gcValues.font = SFfont->fid; SFtextGC = XCreateGC( SFdisplay, XtWindow(selFileLists[0]), (u_long) GCForeground | GCBackground | GCFont | 0, &gcValues ); rectangles[0].x = SFlineToTextH + SFbesideText; rectangles[0].y = 0; rectangles[0].width = SFcharsPerEntry * SFcharWidth; rectangles[0].height = SFupperY + 1; XSetClipRectangles( SFdisplay, SFtextGC, 0, 0, rectangles, 1, Unsorted ); } SFclearList(n, doScroll) int n; int doScroll; { SFDir *dir; #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) int i; Arg arglist[20]; #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ SFcurrentInvert[n] = -1; XClearWindow(SFdisplay, XtWindow(selFileLists[n])); XDrawSegments(SFdisplay, XtWindow(selFileLists[n]), SFlineGC, SFsegs, 2); if (doScroll) { dir = &(SFdirs[SFdirPtr + n]); #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) i = 0; if (SFdirPtr + n < SFdirEnd) { XtSetArg(arglist[i], XtNsliderMax, dir->nEntries); i++; XtSetArg(arglist[i], XtNsliderExtent, dir->nEntries < SFlistSize ? dir->nEntries : SFlistSize); i++; XtSetArg(arglist[i], XtNsliderOrigin, dir->vOrigin); i++; } else { XtSetArg(arglist[i], XtNsliderMax, SFlistSize); i++; XtSetArg(arglist[i], XtNsliderExtent, SFlistSize); i++; XtSetArg(arglist[i], XtNsliderOrigin, 0); i++; } XtSetValues(selFileVScrolls[n], arglist, i); i = 0; if (SFdirPtr + n < SFdirEnd) { XtSetArg(arglist[i], XtNsliderMax, dir->nChars);i++; XtSetArg(arglist[i], XtNsliderExtent, dir->nChars < SFcharsPerEntry ? dir->nChars : SFcharsPerEntry); i++; XtSetArg(arglist[i], XtNsliderOrigin, dir->hOrigin); i++; } else { XtSetArg(arglist[i], XtNsliderMax, SFcharsPerEntry); i++; XtSetArg(arglist[i], XtNsliderExtent, SFcharsPerEntry); i++; XtSetArg(arglist[i], XtNsliderOrigin, 0); i++; } XtSetValues(selFileHScrolls[n], arglist, i); #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ if (SFdirPtr + n < SFdirEnd) { XtScrollBarSetThumb( selFileVScrolls[n], (float) (((double) dir->vOrigin) / dir->nEntries), (float) (((double) ((dir->nEntries < SFlistSize) ? dir->nEntries : SFlistSize)) / dir->nEntries) ); XtScrollBarSetThumb( selFileHScrolls[n], (float) (((double) dir->hOrigin) / dir->nChars), (float) (((double) ((dir->nChars < SFcharsPerEntry) ? dir->nChars : SFcharsPerEntry)) / dir->nChars) ); } else { XtScrollBarSetThumb(selFileVScrolls[n], (float) 0.0, (float) 1.0); XtScrollBarSetThumb(selFileHScrolls[n], (float) 0.0, (float) 1.0); } #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ } } static SFdeleteEntry(dir, entry) SFDir *dir; SFEntry *entry; { register SFEntry *e; register SFEntry *end; int n; #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) int i; Arg arglist[20]; #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ XtFree(entry->real); end = &(dir->entries[dir->nEntries - 1]); for (e = entry; e < end; e++) { *e = *(e + 1); } dir->nEntries--; n = dir - &(SFdirs[SFdirPtr]); if ((n < 0) || (n > 2)) { return; } #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) i = 0; XtSetArg(arglist[i], XtNsliderMax, dir->nEntries); i++; XtSetArg(arglist[i], XtNsliderExtent, dir->nEntries < SFlistSize ? dir->nEntries : SFlistSize); i++; XtSetValues(selFileVScrolls[n], arglist, i); #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ XtScrollBarSetThumb( selFileVScrolls[n], (float) (((double) dir->vOrigin) / dir->nEntries), (float) (((double) ((dir->nEntries < SFlistSize) ? dir->nEntries : SFlistSize)) / dir->nEntries) ); #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ } static SFwriteStatChar(name, last, statBuf) char *name; int last; struct stat *statBuf; { switch (statBuf->st_mode & S_IFMT) { case S_IFDIR: name[last] = '/'; break; case S_IFREG: if (statBuf->st_mode & 0111) { name[last] = '*'; } else { name[last] = ' '; } break; #ifdef S_IFSOCK case S_IFSOCK: name[last] = '='; break; #endif /* def S_IFSOCK */ default: name[last] = ' '; break; } } static int SFstatAndCheck(dir, entry) SFDir *dir; SFEntry *entry; { struct stat statBuf; char save; int last; /* * must be restored before returning */ save = *(dir->path); *(dir->path) = 0; if (!SFchdir(SFcurrentPath)) { last = strlen(entry->real) - 1; entry->real[last] = 0; entry->statDone = 1; if (!stat(entry->real, &statBuf)) { if (SFfunc) { char *shown; shown = NULL; if (SFfunc(entry->real, &shown, &statBuf)) { if (shown) { int len; len = strlen(shown); entry->shown = XtMalloc( (unsigned) (len + 2) ); (void) strcpy(entry->shown, shown); SFwriteStatChar( entry->shown, len, &statBuf ); entry->shown[len + 1] = 0; } } else { SFdeleteEntry(dir, entry); *(dir->path) = save; return 1; } } SFwriteStatChar(entry->real, last, &statBuf); } else { entry->real[last] = ' '; } } *(dir->path) = save; return 0; } static SFdrawStrings(w, dir, from, to) register Window w; register SFDir *dir; register int from; register int to; { register int i; register SFEntry *entry; int x; x = SFtextX - dir->hOrigin * SFcharWidth; if (dir->vOrigin + to >= dir->nEntries) { to = dir->nEntries - dir->vOrigin - 1; } for (i = from; i <= to; i++) { entry = &(dir->entries[dir->vOrigin + i]); if (!(entry->statDone)) { if (SFstatAndCheck(dir, entry)) { if (dir->vOrigin + to >= dir->nEntries) { to = dir->nEntries - dir->vOrigin - 1; } i--; continue; } } XDrawImageString( SFdisplay, w, SFtextGC, x, SFtextYoffset + i * SFentryHeight, entry->shown, strlen(entry->shown) ); if (dir->vOrigin + i == dir->beginSelection) { XDrawLine( SFdisplay, w, SFlineGC, SFlineToTextH + 1, SFlowerY + i * SFentryHeight, SFlineToTextH + SFentryWidth - 2, SFlowerY + i * SFentryHeight ); } if ( (dir->vOrigin + i >= dir->beginSelection) && (dir->vOrigin + i <= dir->endSelection) ) { SFcompletionSegs[0].y1 = SFcompletionSegs[1].y1 = SFlowerY + i * SFentryHeight; SFcompletionSegs[0].y2 = SFcompletionSegs[1].y2 = SFlowerY + (i + 1) * SFentryHeight - 1; XDrawSegments( SFdisplay, w, SFlineGC, SFcompletionSegs, 2 ); } if (dir->vOrigin + i == dir->endSelection) { XDrawLine( SFdisplay, w, SFlineGC, SFlineToTextH + 1, SFlowerY + (i + 1) * SFentryHeight - 1, SFlineToTextH + SFentryWidth - 2, SFlowerY + (i + 1) * SFentryHeight - 1 ); } } } SFdrawList(n, doScroll) int n; int doScroll; { SFDir *dir; Window w; SFclearList(n, doScroll); if (SFdirPtr + n < SFdirEnd) { dir = &(SFdirs[SFdirPtr + n]); w = XtWindow(selFileLists[n]); XDrawImageString( SFdisplay, w, SFtextGC, SFtextX - dir->hOrigin * SFcharWidth, SFlineToTextV + SFaboveAndBelowText + SFcharAscent, dir->dir, strlen(dir->dir) ); SFdrawStrings(w, dir, 0, SFlistSize - 1); } } SFdrawLists(doScroll) int doScroll; { int i; for (i = 0; i < 3; i++) { SFdrawList(i, doScroll); } } static SFinvertEntry(n) register int n; { XFillRectangle( SFdisplay, XtWindow(selFileLists[n]), SFinvertGC, SFlineToTextH, SFcurrentInvert[n] * SFentryHeight + SFlowerY, SFentryWidth, SFentryHeight ); } static unsigned long SFscrollTimerInterval() { static int maxVal = 200; static int varyDist = 50; static int minDist = 50; int t; int dist; if (SFcurrentListY < SFlowerY) { dist = SFlowerY - SFcurrentListY; } else if (SFcurrentListY > SFupperY) { dist = SFcurrentListY - SFupperY; } else { return (unsigned long) 1; } t = maxVal - ((maxVal / varyDist) * (dist - minDist)); if (t < 1) { t = 1; } if (t > maxVal) { t = maxVal; } return (unsigned long) t; } static SFscrollTimer(n) int n; { SFDir *dir; int save; #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) int i; Arg arglist[20]; #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ dir = &(SFdirs[SFdirPtr + n]); save = dir->vOrigin; if (SFcurrentListY < SFlowerY) { if (dir->vOrigin > 0) { SFvSliderMovedCallback(selFileVScrolls[n], n, dir->vOrigin - 1); } } else if (SFcurrentListY > SFupperY) { if (dir->vOrigin < dir->nEntries - SFlistSize) { SFvSliderMovedCallback(selFileVScrolls[n], n, dir->vOrigin + 1); } } if (dir->vOrigin != save) { #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) i = 0; XtSetArg(arglist[i], XtNsliderOrigin, dir->vOrigin); i++; XtSetValues(selFileVScrolls[n], arglist, i); #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ XtScrollBarSetThumb( selFileVScrolls[n], (float) (((double) dir->vOrigin) / dir->nEntries), (float) (((double) ((dir->nEntries < SFlistSize) ? dir->nEntries : SFlistSize)) / dir->nEntries) ); #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ } if (SFbuttonPressed) { SFscrollTimerId = XtAppAddTimeOut(SFapp, SFscrollTimerInterval(), SFscrollTimer, (caddr_t) n); } } static int SFnewInvertEntry(n, event) register int n; register XMotionEvent *event; { register int x, y; register int new; static int SFscrollTimerAdded = 0; x = event->x; y = event->y; if (SFdirPtr + n >= SFdirEnd) { return -1; } else if ( (x >= 0) && (x <= SFupperX) && (y >= SFlowerY) && (y <= SFupperY) ) { register SFDir *dir = &(SFdirs[SFdirPtr + n]); if (SFscrollTimerAdded) { SFscrollTimerAdded = 0; XtRemoveTimeOut(SFscrollTimerId); } new = (y - SFlowerY) / SFentryHeight; if (dir->vOrigin + new >= dir->nEntries) { return -1; } return new; } else { if (SFbuttonPressed) { SFcurrentListY = y; if (!SFscrollTimerAdded) { SFscrollTimerAdded = 1; SFscrollTimerId = XtAppAddTimeOut(SFapp, SFscrollTimerInterval(), SFscrollTimer, (caddr_t) n); } } return -1; } } /* ARGSUSED */ void SFenterList(w, n, event) Widget w; register int n; register XEnterWindowEvent *event; { register int new; /* sanity */ if (SFcurrentInvert[n] != -1) { SFinvertEntry(n); SFcurrentInvert[n] = -1; } new = SFnewInvertEntry(n, (XMotionEvent *) event); if (new != -1) { SFcurrentInvert[n] = new; SFinvertEntry(n); } } /* ARGSUSED */ void SFleaveList(w, n, event) Widget w; register int n; XEvent *event; { if (SFcurrentInvert[n] != -1) { SFinvertEntry(n); SFcurrentInvert[n] = -1; } } /* ARGSUSED */ void SFmotionList(w, n, event) Widget w; register int n; register XMotionEvent *event; { register int new; new = SFnewInvertEntry(n, event); if (new != SFcurrentInvert[n]) { if (SFcurrentInvert[n] != -1) { SFinvertEntry(n); } SFcurrentInvert[n] = new; if (new != -1) { SFinvertEntry(n); } } } /* ARGSUSED */ #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ SFvFloatSliderMovedCallback(w, n, fnew) Widget w; int n; float *fnew; { int new; new = (*fnew) * SFdirs[SFdirPtr + n].nEntries; SFvSliderMovedCallback(w, n, new); } #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ /* ARGSUSED */ SFvSliderMovedCallback(w, n, new) Widget w; int n; int new; { int old; register Window win; SFDir *dir; dir = &(SFdirs[SFdirPtr + n]); old = dir->vOrigin; dir->vOrigin = new; #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ if (old == new) { return; } #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ win = XtWindow(selFileLists[n]); if (ABS(new - old) < SFlistSize) { if (new > old) { XCopyArea( SFdisplay, win, win, SFscrollGC, SFlineToTextH, SFlowerY + (new - old) * SFentryHeight, SFentryWidth + SFlineToTextH, (SFlistSize - (new - old)) * SFentryHeight, SFlineToTextH, SFlowerY ); XClearArea( SFdisplay, win, SFlineToTextH, SFlowerY + (SFlistSize - (new - old)) * SFentryHeight, SFentryWidth + SFlineToTextH, (new - old) * SFentryHeight, False ); SFdrawStrings(win, dir, SFlistSize - (new - old), SFlistSize - 1); } else { XCopyArea( SFdisplay, win, win, SFscrollGC, SFlineToTextH, SFlowerY, SFentryWidth + SFlineToTextH, (SFlistSize - (old - new)) * SFentryHeight, SFlineToTextH, SFlowerY + (old - new) * SFentryHeight ); XClearArea( SFdisplay, win, SFlineToTextH, SFlowerY, SFentryWidth + SFlineToTextH, (old - new) * SFentryHeight, False ); SFdrawStrings(win, dir, 0, old - new); } } else { XClearArea( SFdisplay, win, SFlineToTextH, SFlowerY, SFentryWidth + SFlineToTextH, SFlistSize * SFentryHeight, False ); SFdrawStrings(win, dir, 0, SFlistSize - 1); } } /* ARGSUSED */ #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) SFvAreaSelectedCallback(w, n, new) Widget w; int n; int new; #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ SFvAreaSelectedCallback(w, n, pnew) Widget w; int n; int pnew; #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ { SFDir *dir; #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) int i; Arg arglist[20]; #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ int new; #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ dir = &(SFdirs[SFdirPtr + n]); #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) new -= (SFlistSize / 2); #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ new = dir->vOrigin + (((double) pnew) / SFvScrollHeight) * dir->nEntries; #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ if (new > dir->nEntries - SFlistSize) { new = dir->nEntries - SFlistSize; } if (new < 0) { new = 0; } #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) i = 0; XtSetArg(arglist[i], XtNsliderOrigin, new); i++; XtSetValues(w, arglist, i); #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ { float f; f = ((double) new) / dir->nEntries; XtScrollBarSetThumb( w, f, (float) (((double) ((dir->nEntries < SFlistSize) ? dir->nEntries : SFlistSize)) / dir->nEntries) ); } #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ SFvSliderMovedCallback(w, n, new); } /* ARGSUSED */ SFhSliderMovedCallback(w, n, new) Widget w; int n; #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) int new; #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ float *new; #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ { #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) SFdirs[SFdirPtr + n].hOrigin = new; #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ { SFDir *dir; int save; dir = &(SFdirs[SFdirPtr + n]); save = dir->hOrigin; dir->hOrigin = (*new) * dir->nChars; if (dir->hOrigin == save) { return; } } #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ SFdrawList(n, SF_DO_NOT_SCROLL); } /* ARGSUSED */ #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) SFhAreaSelectedCallback(w, n, new) Widget w; int n; int new; #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ SFhAreaSelectedCallback(w, n, pnew) Widget w; int n; int pnew; #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ { SFDir *dir; #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) int i; Arg arglist[20]; #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ int new; #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ dir = &(SFdirs[SFdirPtr + n]); #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) new -= (SFcharsPerEntry / 2); #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ new = dir->hOrigin + (((double) pnew) / SFhScrollWidth) * dir->nChars; #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ if (new > dir->nChars - SFcharsPerEntry) { new = dir->nChars - SFcharsPerEntry; } if (new < 0) { new = 0; } #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) i = 0; XtSetArg(arglist[i], XtNsliderOrigin, new); i++; XtSetValues(w, arglist, i); SFhSliderMovedCallback(w, n, new); #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ { float f; f = ((double) new) / dir->nChars; XtScrollBarSetThumb( w, f, (float) (((double) ((dir->nChars < SFcharsPerEntry) ? dir->nChars : SFcharsPerEntry)) / dir->nChars) ); SFhSliderMovedCallback(w, n, &f); } #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ } /* ARGSUSED */ SFpathSliderMovedCallback(w, client_data, new) Widget w; caddr_t client_data; #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) int new; #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ float *new; #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ { SFDir *dir; int n; #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWTEXTEDIT) XwTextPosition pos; #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWTEXTEDIT) */ XtTextPosition pos; #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWTEXTEDIT) */ #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) SFdirPtr = new; #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ { int SFdirPtrSave; SFdirPtrSave = SFdirPtr; SFdirPtr = (*new) * SFdirEnd; if (SFdirPtr == SFdirPtrSave) { return; } } #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ SFdrawLists(SF_DO_SCROLL); n = 2; while (SFdirPtr + n >= SFdirEnd) { n--; } dir = &(SFdirs[SFdirPtr + n]); pos = dir->path - SFcurrentPath; if (!strncmp(SFcurrentPath, SFstartDir, strlen(SFstartDir))) { pos -= strlen(SFstartDir); if (pos < 0) { pos = 0; } } #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWTEXTEDIT) XwTextSetInsertPos(selFileField, pos); #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWTEXTEDIT) */ XtTextSetInsertionPoint(selFileField, pos); #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWTEXTEDIT) */ } /* ARGSUSED */ #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) SFpathAreaSelectedCallback(w, client_data, new) Widget w; caddr_t client_data; int new; #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ SFpathAreaSelectedCallback(w, client_data, pnew) Widget w; caddr_t client_data; int pnew; #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ { #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) int i; Arg arglist[20]; #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ int new; #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) new -= (3 / 2); #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ new = SFdirPtr + (((double) pnew) / SFpathScrollWidth) * SFdirEnd; #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ if (new > SFdirEnd - 3) { new = SFdirEnd - 3; } if (new < 0) { new = 0; } #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) i = 0; XtSetArg(arglist[i], XtNsliderOrigin, new); i++; XtSetValues(w, arglist, i); SFpathSliderMovedCallback(w, client_data, new); #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ { float f; f = ((double) new) / SFdirEnd; XtScrollBarSetThumb( w, f, (float) (((double) ((SFdirEnd < 3) ? SFdirEnd : 3)) / SFdirEnd) ); SFpathSliderMovedCallback(w, (caddr_t) NULL, &f); } #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ } Boolean SFworkProc() { register SFDir *dir; register SFEntry *entry; for (dir = &(SFdirs[SFdirEnd - 1]); dir >= SFdirs; dir--) { for ( entry = &(dir->entries[dir->nEntries - 1]); entry >= dir->entries; entry-- ) { if (!(entry->statDone)) { (void) SFstatAndCheck(dir, entry); return False; } } } SFworkProcAdded = 0; return True; } \End\Of\File\ else echo "will not over write ./Draw.c" fi if `test ! -s ./FILES` then echo "writing ./FILES" cat > ./FILES << '\End\Of\File\' Dir.c Draw.c FILES Imakefile Path.c README SFinternal.h SelFile.c SelFile.man TODO callback.c xdir.c \End\Of\File\ else echo "will not over write ./FILES" fi if `test ! -s ./Imakefile` then echo "writing ./Imakefile" cat > ./Imakefile << '\End\Of\File\' # # This file describes how to build xdir, a simple application that uses the # XsraSelFile file selection dialog package. # # The program is linked with Athena widgets (Xaw) by default. It can be linked # with Hewlett-Packard widgets (Xw) by defining one or more of the defines below # and adding Xw to the list of libraries. Defining `SEL_FILE_XW' is equivalent # to defining all of them. # # -DSEL_FILE_XWFORM # -DSEL_FILE_XWPUSHBUTTON # -DSEL_FILE_XWSCROLLBAR # -DSEL_FILE_XWSTATICTEXT # -DSEL_FILE_XWTEXTEDIT # # -DSEL_FILE_XW # # DEFINES = -DSEL_FILE_XW SRCS = xdir.c SelFile.c Dir.c Path.c Draw.c OBJS = xdir.o SelFile.o Dir.o Path.o Draw.o XWLIB = $(CONTRIBSRC)/widgets/Xhp/lib/libXw.a LOCAL_LIBRARIES = $(XAWLIB) $(XMULIB) $(XTOOLLIB) $(XLIB) #LOCAL_LIBRARIES = $(XWLIB) $(XAWLIB) $(XMULIB) $(XTOOLLIB) $(XLIB) ComplexProgramTarget(xdir) NormalLintTarget($(SRCS)) \End\Of\File\ else echo "will not over write ./Imakefile" fi if `test ! -s ./Path.c` then echo "writing ./Path.c" cat > ./Path.c << '\End\Of\File\' #ifndef lint static char rcsid[] = "$Header: Path.c,v 1.5 89/05/29 15:05:30 erik Exp $"; #endif /* * 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 */ #include <stdio.h> #ifdef SEL_FILE_IGNORE_CASE #include <ctype.h> #endif /* def SEL_FILE_IGNORE_CASE */ #include <pwd.h> #include "SFinternal.h" #include <sys/stat.h> #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) #include <Xw/Xw.h> #include <Xw/ScrollBar.h> #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ #include <X11/Scroll.h> #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ #ifdef SYSV extern unsigned short getuid(); extern void qsort(); #endif /* def SYSV */ typedef struct { char *name; char *dir; } SFLogin; SFDir *SFdirs = NULL; int SFdirEnd; int SFdirPtr; int SFbuttonPressed = 0; static int SFdoNotTouchDirPtr = 0; static int SFdoNotTouchVorigin = 0; static SFDir SFrootDir, SFhomeDir; static SFLogin *SFlogins; static int SFtwiddle = 0; int SFchdir(path) char *path; { int result; result = 0; if (strcmp(path, SFcurrentDir)) { result = chdir(path); if (!result) { (void) strcpy(SFcurrentDir, path); } } return result; } static SFfree(i) int i; { register SFDir *dir; register int j; dir = &(SFdirs[i]); for (j = dir->nEntries - 1; j >= 0; j--) { if (dir->entries[j].shown != dir->entries[j].real) { XtFree(dir->entries[j].shown); } XtFree(dir->entries[j].real); } XtFree((char *) dir->entries); XtFree(dir->dir); dir->dir = NULL; } static SFunreadableDir(dir) SFDir *dir; { char *cannotOpen = "<cannot open> "; dir->entries = (SFEntry *) XtMalloc(sizeof(SFEntry)); dir->entries[0].statDone = 1; dir->entries[0].real = XtMalloc((unsigned) (strlen(cannotOpen) + 1)); (void) strcpy(dir->entries[0].real, cannotOpen); dir->entries[0].shown = dir->entries[0].real; dir->nEntries = 1; dir->nChars = strlen(cannotOpen); } #ifdef SEL_FILE_IGNORE_CASE static SFstrncmp(p, q, n) register char *p, *q; register int n; { register char c1, c2; char *psave, *qsave; int nsave; psave = p; qsave = q; nsave = n; c1 = *p++; if (islower(c1)) { c1 = toupper(c1); } c2 = *q++; if (islower(c2)) { c2 = toupper(c2); } while ((--n >= 0) && (c1 == c2)) { if (!c1) { return strncmp(psave, qsave, nsave); } c1 = *p++; if (islower(c1)) { c1 = toupper(c1); } c2 = *q++; if (islower(c2)) { c2 = toupper(c2); } } if (n < 0) { return strncmp(psave, qsave, nsave); } return c1 - c2; } #endif /* def SEL_FILE_IGNORE_CASE */ static SFreplaceText(dir, str) SFDir *dir; char *str; { int len; *(dir->path) = 0; len = strlen(str); if (str[len - 1] == '/') { (void) strcat(SFcurrentPath, str); } else { (void) strncat(SFcurrentPath, str, len - 1); } if (strncmp(SFcurrentPath, SFstartDir, strlen(SFstartDir))) { SFsetText(SFcurrentPath); } else { SFsetText(&(SFcurrentPath[strlen(SFstartDir)])); } SFtextChanged(); } static int SFexpand(str) char *str; { int len; int cmp; char *name, *growing; SFDir *dir; SFEntry *entry, *max; len = strlen(str); dir = &(SFdirs[SFdirEnd - 1]); if (dir->beginSelection == -1) { str = strcpy(XtMalloc((unsigned) (strlen(str) + 1)), str); SFreplaceText(dir, str); XtFree(str); return; } else if (dir->beginSelection == dir->endSelection) { SFreplaceText(dir, dir->entries[dir->beginSelection].shown); return; } max = &(dir->entries[dir->endSelection + 1]); name = dir->entries[dir->beginSelection].shown; (void) strcpy((growing = XtMalloc((unsigned) (strlen(name) + 1))), name); cmp = 0; while (!cmp) { entry = &(dir->entries[dir->beginSelection]); while (entry < max) { if (cmp = strncmp(growing, entry->shown, len)) { break; } entry++; } len++; } /* * SFreplaceText() expects filename */ growing[len - 2] = ' '; growing[len - 1] = 0; SFreplaceText(dir, growing); XtFree(growing); } static int SFfindFile(dir, str) SFDir *dir; register char *str; { register int i, last, max; register char *name, save; SFEntry *entries; int len; int begin, end; int result; len = strlen(str); if (str[len - 1] == ' ') { SFexpand(str); return 1; } else if (str[len - 1] == '/') { len--; } max = dir->nEntries; entries = dir->entries; i = 0; while (i < max) { name = entries[i].shown; last = strlen(name) - 1; save = name[last]; name[last] = 0; #ifdef SEL_FILE_IGNORE_CASE result = SFstrncmp(str, name, len); #else /* def SEL_FILE_IGNORE_CASE */ result = strncmp(str, name, len); #endif /* def SEL_FILE_IGNORE_CASE */ name[last] = save; if (result <= 0) { break; } i++; } begin = i; while (i < max) { name = entries[i].shown; last = strlen(name) - 1; save = name[last]; name[last] = 0; #ifdef SEL_FILE_IGNORE_CASE result = SFstrncmp(str, name, len); #else /* def SEL_FILE_IGNORE_CASE */ result = strncmp(str, name, len); #endif /* def SEL_FILE_IGNORE_CASE */ name[last] = save; if (result) { break; } i++; } end = i; if (begin != end) { if ( (dir->beginSelection != begin) || (dir->endSelection != end - 1) ) { dir->changed = 1; dir->beginSelection = begin; if (str[strlen(str) - 1] == '/') { dir->endSelection = begin; } else { dir->endSelection = end - 1; } } } else { if (dir->beginSelection != -1) { dir->changed = 1; dir->beginSelection = -1; dir->endSelection = -1; } } if ( SFdoNotTouchVorigin || ((begin > dir->vOrigin) && (end < dir->vOrigin + SFlistSize)) ) { SFdoNotTouchVorigin = 0; return 0; } i = begin - 1; if (i > max - SFlistSize) { i = max - SFlistSize; } if (i < 0) { i = 0; } if (dir->vOrigin != i) { dir->vOrigin = i; dir->changed = 1; } return 0; } static SFunselect() { SFDir *dir; dir = &(SFdirs[SFdirEnd - 1]); if (dir->beginSelection != -1) { dir->changed = 1; } dir->beginSelection = -1; dir->endSelection = -1; } static int SFcompareLogins(p, q) SFLogin *p, *q; { return strcmp(p->name, q->name); } static SFgetHomeDirs() { struct passwd *pw; struct stat statBuf; int alloc; int i; SFEntry *entries; int len; int maxChars; alloc = 0; i = 0; maxChars = -1; if (pw = getpwuid((int) getuid())) { if ( (!stat(pw->pw_dir, &statBuf)) && ((statBuf.st_mode & S_IFMT) == S_IFDIR) ) { alloc = 1; i = 1; entries = (SFEntry *) XtMalloc(sizeof(SFEntry)); SFlogins = (SFLogin *) XtMalloc(sizeof(SFLogin)); entries[0].real = XtMalloc(2); (void) strcpy(entries[0].real, "~"); entries[0].shown = entries[0].real; entries[0].statDone = 1; SFlogins[0].name = ""; SFlogins[0].dir = XtMalloc((unsigned) (strlen(pw->pw_dir) + 1)); (void) strcpy(SFlogins[0].dir, pw->pw_dir); } } (void) setpwent(); while ((pw = getpwent()) && (*(pw->pw_name))) { if ( (!stat(pw->pw_dir, &statBuf)) && ((statBuf.st_mode & S_IFMT) == S_IFDIR) ) { if (i >= alloc) { alloc *= 2; entries = (SFEntry *) XtRealloc( (char *) entries, (unsigned) (alloc * sizeof(SFEntry)) ); SFlogins = (SFLogin *) XtRealloc( (char *) SFlogins, (unsigned) (alloc * sizeof(SFLogin)) ); } len = strlen(pw->pw_name); entries[i].real = XtMalloc((unsigned) (len + 3)); (void) strcat(strcpy(entries[i].real, "~"), pw->pw_name); entries[i].shown = entries[i].real; entries[i].statDone = 1; if (len > maxChars) { maxChars = len; } SFlogins[i].name = XtMalloc((unsigned) (strlen(pw->pw_name) + 1)); (void) strcpy(SFlogins[i].name, pw->pw_name); SFlogins[i].dir = XtMalloc((unsigned) (strlen(pw->pw_dir) + 1)); (void) strcpy(SFlogins[i].dir, pw->pw_dir); i++; } } SFhomeDir.dir = XtMalloc(1) ; SFhomeDir.dir[0] = 0 ; SFhomeDir.path = SFcurrentPath ; SFhomeDir.entries = entries ; SFhomeDir.nEntries = i ; SFhomeDir.vOrigin = 0 ; /* :-) */ SFhomeDir.nChars = maxChars + 2 ; SFhomeDir.hOrigin = 0 ; SFhomeDir.changed = 1 ; SFhomeDir.beginSelection = -1 ; SFhomeDir.endSelection = -1 ; #ifdef SYSV qsort((char *) entries, (unsigned)i, sizeof(SFEntry), SFcompareEntries); qsort((char *) SFlogins, (unsigned)i, sizeof(SFLogin), SFcompareLogins); #else /* def SYSV */ qsort((char *) entries, i, sizeof(SFEntry), SFcompareEntries); qsort((char *) SFlogins, i, sizeof(SFLogin), SFcompareLogins); #endif /* def SYSV */ for (i--; i >= 0; i--) { (void) strcat(entries[i].real, "/"); } } static int SFfindHomeDir(begin, end) char *begin, *end; { char save; char *theRest; int i; save = *end; *end = 0; for (i = SFhomeDir.nEntries - 1; i >= 0; i--) { if (!strcmp(SFhomeDir.entries[i].real, begin)) { *end = save; theRest = XtMalloc((unsigned) (strlen(end) + 1)); (void) strcpy(theRest, end); (void) strcat(strcat(strcpy(SFcurrentPath, SFlogins[i].dir), "/"), theRest); XtFree(theRest); SFsetText(SFcurrentPath); SFtextChanged(); return 1; } } *end = save; return 0; } SFupdatePath() { static int alloc; static int wasTwiddle = 0; char *begin, *end; int i, j; int len; int prevChange; int SFdirPtrSave, SFdirEndSave; SFDir *dir; #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) Arg arglist[20]; #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ if (!SFdirs) { SFdirs = (SFDir *) XtMalloc((alloc = 10) * sizeof(SFDir)); dir = &(SFdirs[0]); dir->dir = XtMalloc(2); (void) strcpy(dir->dir, "/"); (void) SFchdir("/"); (void) SFgetDir(dir); for (j = 1; j < alloc; j++) { SFdirs[j].dir = NULL; } dir->path = SFcurrentPath + 1; dir->vOrigin = 0; dir->hOrigin = 0; dir->changed = 1; dir->beginSelection = -1; dir->endSelection = -1; SFrootDir = *dir; SFgetHomeDirs(); } SFdirEndSave = SFdirEnd; SFdirEnd = 1; SFdirPtrSave = SFdirPtr; SFdirPtr = 0; begin = NULL; if (SFcurrentPath[0] == '~') { if (!SFtwiddle) { SFtwiddle = 1; dir = &(SFdirs[0]); *dir = SFhomeDir; dir->changed = 1; } end = SFcurrentPath; SFdoNotTouchDirPtr = 1; wasTwiddle = 1; } else { if (SFtwiddle) { SFtwiddle = 0; dir = &(SFdirs[0]); *dir = SFrootDir; dir->changed = 1; } end = SFcurrentPath + 1; } i = 0; prevChange = 0; while (*end) { while (*end++ == '/') { ; } end--; begin = end; while ((*end) && (*end++ != '/')) { ; } if ((end - SFcurrentPath <= SFtextPos) && (*(end - 1) == '/')) { SFdirPtr = i - 1; if (SFdirPtr < 0) { SFdirPtr = 0; } } if (*begin) { if (*(end - 1) == '/') { char save = *end; if (SFtwiddle) { if (SFfindHomeDir(begin, end)) { return; } } *end = 0; i++; SFdirEnd++; if (i >= alloc) { SFdirs = (SFDir *) XtRealloc( (char *) SFdirs, (unsigned) ((alloc *= 2) * sizeof(SFDir)) ); for (j = alloc / 2; j < alloc; j++) { SFdirs[j].dir = NULL; } } dir = &(SFdirs[i]); if ( (!(dir->dir)) || prevChange || strcmp(dir->dir, begin) ) { if (dir->dir) { SFfree(i); } prevChange = 1; len = strlen(begin) + 1; dir->dir = XtMalloc((unsigned) len); (void) strcpy(dir->dir, begin); dir->path = end; dir->vOrigin = 0; dir->hOrigin = 0; dir->changed = 1; dir->beginSelection = -1; dir->endSelection = -1; (void) SFfindFile(dir - 1, begin); if ( SFchdir(SFcurrentPath) || SFgetDir(dir) ) { SFunreadableDir(dir); break; } } *end = save; if (!save) { SFunselect(); } } else { if (SFfindFile(&(SFdirs[SFdirEnd-1]), begin)) { return; } } } else { SFunselect(); } } if ((end == SFcurrentPath + 1) && (!SFtwiddle)) { SFunselect(); } for (i = SFdirEnd; i < alloc; i++) { if (SFdirs[i].dir) { SFfree(i); } } if (SFdoNotTouchDirPtr) { if (wasTwiddle) { wasTwiddle = 0; SFdirPtr = SFdirEnd - 2; if (SFdirPtr < 0) { SFdirPtr = 0; } } else { SFdirPtr = SFdirPtrSave; } SFdoNotTouchDirPtr = 0; } if ((SFdirPtr != SFdirPtrSave) || (SFdirEnd != SFdirEndSave)) { #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) i = 0; XtSetArg(arglist[i], XtNsliderMax, SFdirEnd + 3 - 1); i++; XtSetArg(arglist[i], XtNsliderOrigin, SFdirPtr); i++; XtSetValues(selFileHScroll, arglist, i); #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ XtScrollBarSetThumb( selFileHScroll, (float) (((double) SFdirPtr) / SFdirEnd), (float) (((double) ((SFdirEnd < 3) ? SFdirEnd : 3)) / SFdirEnd) ); #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWSCROLLBAR) */ } if (SFdirPtr != SFdirPtrSave) { SFdrawLists(SF_DO_SCROLL); } else { for (i = 0; i < 3; i++) { if (SFdirPtr + i < SFdirEnd) { if (SFdirs[SFdirPtr + i].changed) { SFdirs[SFdirPtr + i].changed = 0; SFdrawList(i, SF_DO_SCROLL); } } else { SFclearList(i, SF_DO_SCROLL); } } } } SFsetText(path) char *path; { #if defined(SEL_FILE_XW) || defined(SEL_FILE_XWTEXTEDIT) #ifdef SEL_FILE_JAPANESE static wchar_t *wstr = NULL; static int alloc = 0; int len; len = convEUCtoWS((unsigned char *) path, (wchar_t *) NULL); while (len + 1 > alloc) { alloc = 2 * (alloc + 1); wstr = (wchar_t *) XtRealloc((char *) wstr, (unsigned) (alloc * sizeof(wchar_t))); } (void) convEUCtoWS((unsigned char *) path, wstr); XwTextClearBuffer(selFileField); XwTextInsert(selFileField, wstr); #else /* def SEL_FILE_JAPANESE */ XwTextClearBuffer(selFileField); XwTextInsert(selFileField, path); #endif /* def SEL_FILE_JAPANESE */ #else /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWTEXTEDIT) */ { XtTextBlock text; text.firstPos = 0; text.length = strlen(path); text.ptr = path; text.format = FMT8BIT; XtTextReplace(selFileField, 0, strlen(SFtextBuffer), &text); } #endif /* defined(SEL_FILE_XW) || defined(SEL_FILE_XWTEXTEDIT) */ } /* ARGSUSED */ void SFbuttonPressList(w, n, event) Widget w; int n; XButtonPressedEvent *event; { SFbuttonPressed = 1; } /* ARGSUSED */ void SFbuttonReleaseList(w, n, event) Widget w; int n; XButtonReleasedEvent *event; { SFDir *dir; SFbuttonPressed = 0; if (SFcurrentInvert[n] != -1) { if (n < 2) { SFdoNotTouchDirPtr = 1; } SFdoNotTouchVorigin = 1; dir = &(SFdirs[SFdirPtr + n]); SFreplaceText( dir, dir->entries[dir->vOrigin + SFcurrentInvert[n]].shown ); SFmotionList(w, n, event); } } static int SFcheckDir(n, dir) int n; SFDir *dir; { struct stat statBuf; int i; if ( (!stat(".", &statBuf)) && (statBuf.st_mtime != dir->st_mtime) ) { /* * If the pointer is currently in the window that we are about * to update, we must warp it to prevent the user from * accidentally selecting the wrong file. */ if (SFcurrentInvert[n] != -1) { XWarpPointer( SFdisplay, None, XtWindow(selFileLists[n]), 0, 0, 0, 0, 0, 0 ); } for (i = dir->nEntries - 1; i >= 0; i--) { if (dir->entries[i].shown != dir->entries[i].real) { XtFree(dir->entries[i].shown); } XtFree(dir->entries[i].real); } XtFree((char *) dir->entries); if (SFgetDir(dir)) { SFunreadableDir(dir); } if (dir->vOrigin > dir->nEntries - SFlistSize) { dir->vOrigin = dir->nEntries - SFlistSize; } if (dir->vOrigin < 0) { dir->vOrigin = 0; } if (dir->hOrigin > dir->nChars - SFcharsPerEntry) { dir->hOrigin = dir->nChars - SFcharsPerEntry; } if (dir->hOrigin < 0) { dir->hOrigin = 0; } dir->beginSelection = -1; dir->endSelection = -1; SFdoNotTouchVorigin = 1; if ((dir + 1)->dir) { (void) SFfindFile(dir, (dir + 1)->dir); } else { (void) SFfindFile(dir, dir->path); } return 1; } return 0; } static int SFcheckFiles(dir) SFDir *dir; { int from, to; int result; char old, new; int i; char *str; int last; struct stat statBuf; result = 0; from = dir->vOrigin; to = dir->vOrigin + SFlistSize; if (to > dir->nEntries) { to = dir->nEntries; } for (i = from; i < to; i++) { str = dir->entries[i].real; last = strlen(str) - 1; old = str[last]; str[last] = 0; if (stat(str, &statBuf)) { new = ' '; } else { switch (statBuf.st_mode & S_IFMT) { case S_IFDIR: new = '/'; break; case S_IFREG: if (statBuf.st_mode & 0111) { new = '*'; } else { new = ' '; } break; #ifdef S_IFSOCK case S_IFSOCK: new = '='; break; #endif /* def S_IFSOCK */ default: new = ' '; break; } } str[last] = new; if (new != old) { result = 1; } } return result; } SFdirModTimer() { static int n = -1; static int f = 0; char save; SFDir *dir; if ((!SFtwiddle) && (SFdirPtr < SFdirEnd)) { n++; if ((n > 2) || (SFdirPtr + n >= SFdirEnd)) { n = 0; f++; if ((f > 2) || (SFdirPtr + f >= SFdirEnd)) { f = 0; } } dir = &(SFdirs[SFdirPtr + n]); save = *(dir->path); *(dir->path) = 0; if (SFchdir(SFcurrentPath)) { *(dir->path) = save; /* * force a re-read */ *(dir->dir) = 0; SFupdatePath(); } else { *(dir->path) = save; if ( SFcheckDir(n, dir) || ((f == n) && SFcheckFiles(dir)) ) { SFdrawList(n, SF_DO_SCROLL); } } } SFdirModTimerId = XtAppAddTimeOut(SFapp, (unsigned long) 1000, SFdirModTimer, (caddr_t) NULL); } \End\Of\File\ else echo "will not over write ./Path.c" fi echo "Finished archive 2 of 2" exit -- Erik M. van der Poel erik@sra.co.jp (Japan) SRA, 1-1-1 Hirakawa-cho, Chiyoda-ku erik%sra.co.jp@uunet.uu.net (USA) Tokyo 102 Japan. TEL +81-3-234-2692 erik%sra.co.jp@mcvax.uucp (Europe)