/*- - - - - - - - - - YAFR - Yet Another File Requester - - - - - - - - -*/ /*- - - - - - - - - - - - - - Version 1.10 - - - - - - - - - - - - - - -*/ /*YAFR V1.1 Copyright ©1989 by Dave Schreiber. All rights reserved. */ /*YAFR may be freely distributed, but may not be sold. Exceptions to */ /*are reasonable copying, media, and shipping fees. This copyright */ /*message must be included (including when YAFR is used as a part of */ /*another program). */ /*Compiled under Lattice C V5.02 */ /*Command line: 1> lc -cw -j30 yafr */ /*Generates YAFR.o which is linked into the host program */ /*You must assign YAFR: to the directory where the YAFR source is stored */ /*If you have any comments, suggestions, etc. I can be reached at: */ /*Dave Schreiber */ /*1234 Collins Lane */ /*San Jose, CA 95129-4208 */ /*Usenet: davids@ucscb.ucsc.edu (during the school year) */ #include /*^^^^system includes, structure definitions, etc.*/ #define CRNT header.current->fib /*Parameters are: fn-string for filename (33 characters) */ /*dn-string for directory name (150 characters) */ /*en-string for filename extension (.c, .pic, etc. 18 characters) */ /*cn-string for combined directory and filename (183 characters) */ /*(NULL if you don't want the combined filename) */ /*X,Y-YAFR's window's X,Y location (relative to the screen */ /*wn-text for YAFR's window's title bar */ /*scr-Pointer to screen that window should appear on (NULL for */ /*Workbench) filepen-Pen color that filenames should be displayed in */ /*dirpen-Pen color that directory names should be displayed in */ /*DisableInfo-Boolean; TRUE-files ending in .info aren't displayed */ /* FALSE-.info files are displayed */ /*Version 1.1, completed October 30, 1989*/ /*Directory and filename string gadgets now auto-activate and appropriate*/ /*times. A bug that caused an incorrect filename to be returned when the*/ /*user pressed CANCEL has been fixed */ GetFilename(fn,dn,en,cn,X,Y,wn,scr,filepen,dirpen,DisableInfo) char *fn,*dn,*en,*cn,*wn; USHORT X,Y,filepen,dirpen; BYTE DisableInfo; struct Screen *scr; { int status=GN_NEWDIR; struct FileLock *DirLock; if(DisableInfo) yf_Info.Flags|=SELECTED; else yf_Info.Flags=GADGHIMAGE|GADGIMAGE; yafr_e_FilenamePenColor = filepen; yafr_e_DirnamePenColor = dirpen; DirLock=(struct FileLock *)Lock(dn,ACCESS_READ); strcpy(yf_DirNameSIBuff,dn); strcpy(yf_ExtNameSIBuff,en); strcpy(yf_filenameSIBuff,fn); NewFNWindow.LeftEdge=X; NewFNWindow.TopEdge=Y; NewFNWindow.Title=(char *)wn; NewFNWindow.Screen=(struct Screen *) scr; NewFNWindow.Type= (scr) ? CUSTOMSCREEN : WBENCHSCREEN; if((FNWindow=(struct Window *)OpenWindow(&NewFNWindow))==NULL) { UnLock(DirLock); return(FALSE); } SetWindowTitles(FNWindow,-1,"YAFR V1.10 ©1989 by Dave Schreiber"); SetAPen(FNWindow->RPort,1); Move(FNWindow->RPort,6,19); Text(FNWindow->RPort,"Directory",9); Move(FNWindow->RPort,6,154); Text(FNWindow->RPort,"Extension",9); Move(FNWindow->RPort,6,165); Text(FNWindow->RPort,"Filename",8); ActivateGadget(&yf_DirName,FNWindow,NULL); while((status = yf_GetName(DirLock)) == GN_NEWDIR) { UnLock(DirLock); DirLock=(struct FileLock *)Lock(yf_DirNameSIBuff,ACCESS_READ); ActivateGadget(&yf_filename,FNWindow,NULL); } UnLock(DirLock); if(status) { strcpy(fn,yf_filenameSIBuff); strcpy(dn,yf_DirNameSIBuff); strcpy(en,yf_ExtNameSIBuff); if(cn) { strcpy(cn,yf_DirNameSIBuff); if( (dn[strlen(dn)-1] != ':') && strlen(dn) ) strcat(cn,"/"); strcat(cn,yf_filenameSIBuff); } } CloseWindow(FNWindow); return(status); } yf_GetName(Lock) struct FileLock *Lock; { struct fibHeader header; int status3,status2,status; USHORT FNNumber=0; header.first=header.directory=NULL; if(yf_GetFib(&header)==FALSE) return(FALSE); yf_SliderSInfo.VertPot=0; yf_UpdateSlider(1,&yf_SliderSInfo,&yf_Slider); yf_ClearFileBox(); if(!yf_ispipedevice(yf_DirNameSIBuff)) /*Check for pipe: device*/ if(Lock!=NULL) { Examine(Lock,&(CRNT)); if(yf_GetFib(&header)==FALSE) /*Get next node*/ return(NULL); while((status3=ExNext(Lock,&(CRNT)))) { if((status2=((yf_CheckExt(CRNT.fib_FileName,yf_ExtNameSIBuff) || CRNT.fib_DirEntryType > 0) && yf_CheckInfo(CRNT.fib_FileName)) )) { if(FNNumber<10) yf_PrintFileName(&(CRNT),Rp,XBorder,YBorder+(10*FNNumber++)); else yf_UpdateSlider(++FNNumber,&yf_SliderSInfo,&yf_Slider); } while((status=yf_CheckIntuiMessages(FNNumber,&header))!=GN_DONE) { if(status==GN_PARENT) { yf_Parentize(yf_DirNameSIBuff); yf_RefreshGadget(&yf_DirName,FNWindow,NULL); yf_FreeFuncMemory(header.directory); return(GN_NEWDIR); } if(status < GN_PARENT) { yf_FreeFuncMemory(header.directory); return(status); /*For OK,NEWDIR, & CANCEL*/ } } if(status2) if(yf_GetFib(&header)==FALSE) return(NULL); } header.current->prev->next=NULL; if(header.directory->next == header.current) /*If no files*/ header.directory->next=header.first=header.last= header.top=NULL; /*NULL certain pointers*/ FreeMem(header.current,sizeof(struct fibNode)); } for(;;) /*FOREVER*/ { Wait(1<UserPort->mp_SigBit); while((status=yf_CheckIntuiMessages(FNNumber,&header))!=GN_DONE) { if(status==GN_PARENT) if(yf_Parentize(yf_DirNameSIBuff)) { yf_RefreshGadget(&yf_DirName,FNWindow,NULL); yf_FreeFuncMemory(header.directory); return(GN_NEWDIR); } if(status < GN_PARENT) { yf_FreeFuncMemory(header.directory); return(status); /*For OK,NEWDIR, & CANCEL*/ } } } } yf_CheckInfo(name) /*Check to see if .info's should be printed*/ char *name; { if(!(yf_Info.Flags & SELECTED)) return(TRUE); return(!(strcmp(&name[strlen(name)-5],".info")==0)); } yf_ClearFileBox() { SetAPen(Rp,0); RectFill(Rp,XBorder,YBorder-6,(25*8)+XBorder,YBorder+(100)-4); SetAPen(Rp,1); } yf_Parentize(str) char *str; { int c; if(str[strlen(str)-1]==':') return(FALSE); for(c=strlen(str)-1;c >= 0;c--) if(str[c]=='/') { str[c]=NULL; c=0; } else if(str[c]==':') { str[c+1]=NULL; c=0; } return(TRUE); } yf_UpdateSlider(Amt,Info,Gadgt) USHORT Amt; struct PropInfo *Info; struct Gadget *Gadgt; { Info->VertBody=((0xFFFF*10)/Amt); RefreshGadgets(Gadgt,FNWindow,NULL); } yf_CheckIntuiMessages(Max,header) USHORT Max; struct fibHeader *header; { struct fibNode *cur; UBYTE c,line; struct IntuiMessage *mesg; struct Gadget *InUse; ULONG Class; USHORT Code; SHORT X,Y; while((mesg=(struct IntuiMessage *)GetMsg(FNWindow->UserPort))!=NULL) { InUse=(struct Gadget *)mesg->IAddress; X=mesg->MouseX; Y=mesg->MouseY; Class=mesg->Class; Code=mesg->Code; ReplyMsg(mesg); switch(Class) { case MOUSEMOVE: if(Max > 10) yf_UpdateList(yf_SliderSInfo.VertPot,Max,header); break; case GADGETUP: if(InUse->GadgetID <= 10) { strcpy(yf_DirNameSIBuff,InUse->GadgetText->IText); yf_RefreshGadget(&yf_DirName,FNWindow,NULL); return(GN_NEWDIR); } switch(InUse->GadgetID) { case 14: return(GN_CANCEL); case 12: case 13: return(GN_OK); case 15: return(GN_PARENT); case 11: case 18: return(GN_NEWDIR); } return(GN_RIEN); /*Nothing important*/ break; case GADGETDOWN: if(InUse->GadgetID == 18) return(GN_NEWDIR); if((strcmp(yf_DirNameSIBuff,"PIPE:")!=0) && /*Don't try & get files*/ (strcmp(yf_DirNameSIBuff,"pipe:")!=0) && /*from PIPE: (most combos*/ (strcmp(yf_DirNameSIBuff,"Pipe:") != 0)) /*of upper & lower case)*/ { line=(Y-YBorder+7)/10; /*Get line clicked on*/ for(c=0,cur=(struct fibNode *)header->top;c!=line && cur!=NULL;c++) cur=(struct fibNode *)cur->next; if(cur != NULL) if(cur->fib.fib_DirEntryType > 0) { if(yf_DirNameSIBuff[strlen(yf_DirNameSIBuff)-1] != ':') strcat(yf_DirNameSIBuff,"/"); strcat(yf_DirNameSIBuff,cur->fib.fib_FileName); yf_RefreshGadget(&yf_DirName,FNWindow,NULL); return(GN_NEWDIR); } else /*Filename clicked upon*/ { strcpy(yf_filenameSIBuff,cur->fib.fib_FileName); yf_RefreshGadget(&yf_filename,FNWindow,NULL); } } } } return(GN_DONE); } yf_UpdateList(Pos,Num,header) USHORT Pos; USHORT Num; struct fibHeader *header; { static USHORT LastFirstItem=30000; ULONG FirstItem; FirstItem=((Pos)*(Num-10)) >> 16 ; if( FirstItem != LastFirstItem) yf_RewriteList(FirstItem,header); LastFirstItem=FirstItem; } yf_RewriteList(First,header) USHORT First; struct fibHeader *header; { register struct fibNode *node; register USHORT c,Y; if(First) for(c=0,node=(struct fibNode *)header->first;c <= First;c++) node=(struct fibNode *)node->next; else node=(struct fibNode *)header->first; header->top=(struct fibNode *)node; for(c=0,Y=YBorder;(c < 10) && (node!=NULL); c++,Y+=10,node=(struct fibNode *)node->next) yf_PrintFileName(&(node->fib),Rp,XBorder,Y); } yf_CheckExt(name,ext) char *name,*ext; { if(strlen(name) >= strlen(ext)) if(strcmp(&name[strlen(name)-strlen(ext)],ext)==0) return(TRUE); return(FALSE); } yf_GetFib(header) struct fibHeader *header; { header->last=(struct fibNode *)header->current; if((header->current=(struct fibNode *) AllocMem(sizeof(struct fibNode),MEMF_PUBLIC|MEMF_CLEAR))==NULL) { yf_FreeFuncMemory(header->current); return(FALSE); } if(header->directory==NULL) header->directory=(struct fibNode *)header->current; else { if(header->first==NULL) { header->directory->next=header->first=header->last=header->top= (struct fibNode *)header->current; yf_CopyFIB(&(header->directory->fib),&(header->current->fib)); } else { yf_CopyFIB(&(header->last->fib),&(header->current->fib)); header->last->next=(struct fibNode *)header->current; header->current->prev=(struct fibNode *)header->last; } } return(TRUE); } yf_CopyFIB(from,to) struct FileInfoBlock *from,*to; { to->fib_DiskKey=from->fib_DiskKey; to->fib_DirEntryType=from->fib_DirEntryType; to->fib_Protection=from->fib_Protection; to->fib_EntryType=from->fib_EntryType; to->fib_Size=from->fib_Size; to->fib_NumBlocks=from->fib_NumBlocks; strcpy(to->fib_FileName,from->fib_FileName); strcpy(to->fib_Comment,from->fib_Comment); to->fib_Date.ds_Days=from->fib_Date.ds_Days; to->fib_Date.ds_Minute=from->fib_Date.ds_Minute; to->fib_Date.ds_Tick=from->fib_Date.ds_Tick; return(TRUE); } yf_PrintFileName(fib,RPrt,X,Y) struct FileInfoBlock *fib; struct RPort *RPrt; USHORT X,Y; { UWORD len; if(fib->fib_DirEntryType > 0) SetAPen(RPrt,yafr_e_DirnamePenColor); else SetAPen(RPrt,yafr_e_FilenamePenColor); Move(RPrt,X,Y); Text(RPrt," ",25); Move(RPrt,X,Y); len = (strlen(fib->fib_FileName)<=25) ? strlen(fib->fib_FileName) : 25; Text(RPrt,fib->fib_FileName,len); if(fib->fib_DirEntryType > 0) Text(RPrt," (dir)",7); } yf_RefreshGadget(Gadg,Wdw,Req) struct Gadget *Gadg; struct Window *Wdw; struct Req *Req; { struct Gadget *next; next=(struct Gadget *)Gadg->NextGadget; Gadg->NextGadget=NULL; RefreshGadgets(Gadg,Wdw,Req); Gadg->NextGadget=(struct Gadget *)next; return(TRUE); } yf_FreeFuncMemory(first) /*Free a fib list*/ register struct fibNode *first; { register struct fibNode *next,*current; next=(struct fibNode *)first->next; FreeMem(first,sizeof(struct fibNode)); while((current=(struct fibNode *)next)!=NULL) { next=(struct fibNode *)current->next; FreeMem(current,sizeof(struct fibNode)); } } yf_ispipedevice(device) /*Checks to see if the device is the PIPE:*/ char *device; { char temp[6]; int c; for(c=0;c<5;c++) /*Convert weird capitalization (pIPe:) to pipe:*/ temp[c]=tolower(device[c]); /*So as to make it easy to check*/ temp[5]=NULL; if(strcmp(device,"pipe:")==0) return(TRUE); else return(FALSE); }