v04i015: xdir -- Directory Browser, Part02/02
Dan Heller
argv at island.uu.net
Sun Jun 4 07:26:06 AEST 1989
Submitted-by: Erik M. van der Poel <erik at 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 at sra.co.jp (Japan)
SRA, 1-1-1 Hirakawa-cho, Chiyoda-ku erik%sra.co.jp at uunet.uu.net (USA)
Tokyo 102 Japan. TEL +81-3-234-2692 erik%sra.co.jp at mcvax.uucp (Europe)
More information about the Comp.sources.x
mailing list