home *** CD-ROM | disk | FTP | other *** search
- /**** REVISION HEADER **************************************************\
- * *
- * Filename : MegaView.c *
- * Source Rev : $VER: MegaView.c 2.001 (24 Nov 1993) : See documentation *
- * *
- * Revision History: *
- * Date Revision Comment *
- * --------------------------------------------------------------- *
- * 12-Jul-93 1.0 First public release *
- * 22-Jul-93 1.01 Added REQ commandline switch to allow *
- * File Requester from the Shell *
- * 22-Jul-93 1.02 Added 'loop' mode for SELECT button in *
- * Popup requester to select more than one *
- * file for viewing until cancel is pressed *
- * 30-Jul-93 1.03 File requester is now "multi-select", i.e. *
- * you can select more than one file to view *
- * 06-Oct-93 1.1 Back from Holliday. Just adding a new *
- * options which allows the user to recursively*
- * collect files from a directory or volume *
- * Suggested by Richard Ludwig. *
- * 10-Oct-93 1.2 Started work on the XPK Interface. *
- * Suggested by Arne Hinrichsen. *
- * 11-Oct-93 1.2 Added some new command line switches. The *
- * XPK Interface took me some two hours. Great *
- * stuff! And easy to use. *
- * 26-Oct-93 2.0 New Version. Major bug fixes, lots of new *
- * features planned. *
- * 13-Nov-93 2.0 Implemented the MAN switch *
- * 23-Nov-93 2.0 Added Localization! *
- * *
- \***********************************************************************/
-
- #include "global.h"
- #include "locale.h"
-
- struct Library *WhatIsBase;
- struct Library *IntuitionBase;
- struct Library *WorkbenchBase;
- struct Library *IconBase;
- struct Library *AslBase;
- struct Library *XpkBase;
- struct Library *LocaleBase;
-
- #define REVISION "2.0"
- static char *version = "$VER: MegaView " REVISION ;
-
- /* The FileActions Template */
- #define CONFIG_TEMPLATE (APTR)"TYPE/K/A,ACTION/K/A,QUOTES/S"
- #define CT_TYPE 0
- #define CT_ACTION 1
- #define CT_QUOTES 2
- #define CT_LENGTH 3
- LONG ConfigLine[CT_LENGTH];
-
-
- /* The Command Line Template */
- #define COMMAND_TEMPLATE (APTR)"FILE,ICON/S,MENU/S,ICONNAME/K,MENUNAME/K,REQUESTER=REQ/S,"\
- "ALL/S,PACK/K,AFILE/K,TMPDIR/K,KEEPFILES=KF/S,SC=SHORTCUT/S,"\
- "MAN/K"
- #define CO_FILE 0
- #define CO_ICON 1
- #define CO_MENU 2
- #define CO_ICONNAME 3
- #define CO_MENUNAME 4
- #define CO_REQ 5
- #define CO_ALL 6
- #define CO_PACK 7
- #define CO_AFILE 8
- #define CO_TMPDIR 9
- #define CO_KEEPFILES 10
- #define CO_SHORTCUT 11
- #define CO_MAN 12
- #define CO_LENGTH 13
- LONG CommandLine[CO_LENGTH];
-
- #define BUFSIZE 512
- #define PNAME "MegaView"
- #define ABOUT PNAME " V" REVISION "\n© 1993 DIgital DImensions\nVersion " REVISION
-
- char win[256];
-
- char pbuf[512];
- BOOL wbrun=FALSE;
- BOOL IconMode=FALSE, MenuMode=FALSE;
- char IconName[50];
- char MenuName[50];
- BOOL Recurse=FALSE;
- char XPKName[50];
- char ftstring[50];
- char ACTIONFILE[50];
- char TEMPDIR[50];
- char EDITOR[50];
- BOOL KeepFiles=FALSE;
- BOOL ShortCut=FALSE;
-
- LONG ix=0,iy=0;
-
- #define ICONID 4711L
-
- char FileName[256]="";
- int NumArgs=0;
- struct FileRequester *request=NULL;
-
- struct TagItem witags[] = {
- WI_Deep, DEEPTYPE,
- WI_FIB, 0,
- TAG_DONE, 0L
- };
-
- struct TagItem atags[] = {
- ASL_Hail, 0L,
- ASL_Dir, 0L,
- TAG_DONE, 0L
- };
-
- struct TagItem atags2[] = {
- ASL_FuncFlags, FILF_MULTISELECT,
- TAG_DONE, 0L
- };
-
- /* This is the icon data. You can remove the stuff and replace it
- * with an image done with the IconEdit program (Save as C...)
- */
- UWORD MegaViewI1Data[] =
- {
- /* Plane 0 */
- 0x0000,0x0000,0x0000,0x3F80,0x0000,0x0000,0x0000,0x60E0,
- 0x0000,0x0000,0x0001,0xF830,0x0000,0x0000,0x001F,0xFF98,
- 0x0000,0x0000,0x0020,0x0058,0x0000,0x0000,0x0027,0x9E58,
- 0x0AAA,0xAAFE,0xAAA7,0x9E58,0x2822,0xAAEE,0xAAA7,0x9E70,
- 0x22A8,0x0000,0x02A0,0x0060,0x2AA8,0x0000,0x03A0,0x0040,
- 0x2AA8,0x00E0,0x03A0,0x0040,0x2AA8,0x07F8,0x03A0,0x0040,
- 0x2AA8,0x3FF0,0x03A0,0x0040,0x2AA8,0x7FEF,0x03A0,0x0040,
- 0x2AA8,0xFFFF,0x03A2,0xAA40,0x2AA8,0x73FE,0x03AA,0xAAC0,
- 0x2AA8,0x01DF,0xC3AA,0xAAC0,0x2AA8,0x000F,0xE3AA,0xAC00,
- 0x2AA8,0x0000,0x63AA,0xAC00,0x2AA8,0x0000,0x03AA,0xAC00,
- 0x2AA8,0x0000,0x03AA,0xAC00,0x2AA7,0xFFFF,0xFFCA,0xAC00,
- 0x0AAA,0xBEAA,0xBEAA,0x8C00,0x0000,0x0000,0x0000,0x0C00,
- 0x0000,0x0000,0x0000,0x0C00,0x7FFF,0xFFFF,0xFFFF,0xFC00,
- 0x0000,0x0000,0x0000,0x0000,
- /* Plane 1 */
- 0x0000,0x0000,0x0000,0x4000,0x0000,0x0000,0x0000,0x8100,
- 0x0000,0x0000,0x0002,0x0040,0x0000,0x0000,0x0000,0x0020,
- 0xFFFF,0xFFFF,0xFFDF,0xFFA0,0xD555,0x5555,0x5558,0x61A0,
- 0xD000,0x0100,0x0018,0x61A0,0xC7D8,0x0110,0x0018,0x6180,
- 0xCC03,0xFFFF,0xFC1F,0xFF80,0xC003,0xFFFF,0xFC1F,0xFF80,
- 0xC003,0xFFDF,0xFC1F,0xFF80,0xC003,0xFFE7,0xFC1F,0xFF80,
- 0xC003,0xFCCF,0xFC1F,0xFF80,0xC003,0xF19E,0xFC1F,0xFF80,
- 0xC003,0xE76C,0xFC1D,0x5580,0xC003,0x8F99,0xFC15,0x5500,
- 0xC003,0xFE3F,0xBC15,0x5500,0xC003,0xFFF0,0xDC00,0x1000,
- 0xC003,0xFFFF,0x9C00,0x1000,0xC003,0xFFFF,0xFC00,0x1000,
- 0xC003,0xFFFF,0xFC00,0x1000,0xC008,0x0000,0x0000,0x1000,
- 0xD000,0x4000,0x4000,0x5000,0xD555,0x5555,0x5555,0x5000,
- 0xD555,0x5555,0x5555,0x5000,0x8000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,
- };
-
- struct Image MegaViewI1 =
- {
- 0, 0, /* Upper left corner */
- 61, 27, 2, /* Width, Height, Depth */
- MegaViewI1Data, /* Image data */
- 0x0003, 0x0000, /* PlanePick, PlaneOnOff */
- NULL /* Next image */
- };
-
- struct DiskObject MegaView =
- {
- WB_DISKMAGIC, /* Magic Number */
- WB_DISKVERSION, /* Version */
- { /* Embedded Gadget Structure */
- NULL, /* Next Gadget Pointer */
- 0, 0, 61, 27, /* Left,Top,Width,Height */
- GADGIMAGE | GADGHCOMP, /* Flags */
- RELVERIFY, /* Activation Flags */
- BOOLGADGET, /* Gadget Type */
- (APTR)&MegaViewI1, /* Render Image */
- NULL, /* Select Image */
- NULL, /* Gadget Text */
- NULL, /* Mutual Exclude */
- NULL, /* Special Info */
- 100, /* Gadget ID */
- (APTR) 0x0001, /* User Data (Revision) */
- },
- WBTOOL, /* Icon Type */
- NULL, /* Default Tool */
- NULL, /* Tool Type Array */
- NO_ICON_POSITION, /* Current X */
- NO_ICON_POSITION, /* Current Y */
- NULL, /* Drawer Structure */
- NULL, /* Tool Window */
- 4096 /* Stack Size */
- };
-
-
- BOOL FileRequest(void) {
- /*
- * Call an ASL File Requester. This one is multi-selectable. The return
- * value indicates if cancel (=FALSE) was pressed, or it was terminated
- * OK (=TRUE)
- */
- static char dir[256] = "\0";
- BOOL result;
-
- NumArgs = 0;
-
- if (!request) request=(struct FileRequester *)
- AllocAslRequestTags(ASL_FileRequest,
- ASL_Hail, "MegaView V" REVISION,
- ASL_Dir, dir,
- TAG_DONE);
- if (request==NULL) return FALSE ;
- result = AslRequest(request,atags2);
- if (result==FALSE) return FALSE;
- strcpy(dir,(char *)(request->rf_Dir));
- NumArgs=request->rf_NumArgs;
- /* if only one file was selected, copy this to the global variable
- * FileName.
- */
- if (NumArgs == 0) {
- strncpy(FileName,(char *)(request->rf_Dir),256);
- AddPart((STRPTR)FileName,(STRPTR)request->rf_File,256);
- } else {
- /* Otherwise just copy the directory name and let the caller
- * tag on the rest
- */
- strncpy(FileName,(char *)(request->rf_Dir),256);
- }
- return TRUE;
- }
-
- long ShowRequest(STRPTR text, STRPTR gads) {
- /* Show a standard intuition EasyRequest. The first argument is
- * the text of the request, while the second is used to label
- * the gadgets. Note that you may have any number of gadgets
- * by just putting in a bar ("|") character between the labels,
- * e.g. "OK|Break|Cancel". The return value will be the number of
- * the gadget that was pressed. Note however, that the first gadget
- * is number 1, the second is 2, etc. upto the last, which will
- * be number 0! OK in the above example would be 1, Break would be
- * 2 and Cancel WOULD BE 0!
- */
- struct EasyStruct es;
- es.es_StructSize=sizeof(struct EasyStruct);
- es.es_Flags=0;
- es.es_Title=(UBYTE *)PNAME "V" REVISION;
- es.es_TextFormat=(UBYTE *)text;
- es.es_GadgetFormat=(UBYTE *)gads;
- return EasyRequestArgs(NULL,&es,NULL,NULL);
- }
-
- void print(STRPTR s) {
- if (wbrun==TRUE && IntuitionBase) ShowRequest(s,GetString(msgOK));
- else printf("%s\n",(char *)s);
- }
-
- void CloseAll(STRPTR s) {
- /* This routine is used to panic out of the program, cleaning up
- * as much of the mess as possible. If called with a text as
- * parameter, this text is printed on the console, if MegaView
- * was run from shell, or pop up a requester if it was launched
- * from WB.
- */
- if (s) print(s);
- CloseMegaViewCatalog();
- if (request) FreeAslRequest(request);
- if (XpkBase) CloseLibrary(XpkBase);
- if (WhatIsBase) CloseLibrary(WhatIsBase);
- if (IntuitionBase) CloseLibrary(IntuitionBase);
- if (WorkbenchBase) CloseLibrary(WorkbenchBase);
- if (IconBase) CloseLibrary(IconBase);
- if (AslBase) CloseLibrary(AslBase);
- if (LocaleBase) CloseLibrary(LocaleBase);
- exit(0L);
- }
-
- void OpenAll(void) {
- /* This is the reverse of the above, opening all resources we need
- * globally for MegaView, and doing some global initialization.
- */
- strcpy(FileName,"\0");
- XpkBase = OpenLibrary((APTR)"xpkmaster.library",2L);
- LocaleBase = OpenLibrary((APTR)"locale.library",38L);
- WhatIsBase = OpenLibrary((APTR)"whatis.library",0L);
- if (!WhatIsBase) CloseAll(GetString(msgNeedWhatIs));
- IntuitionBase = OpenLibrary((APTR)"intuition.library",37L);
- if (!IntuitionBase) CloseAll(GetString(msgNeedIntuition));
- WorkbenchBase = OpenLibrary((APTR)"workbench.library",37L);
- if (!WorkbenchBase) CloseAll(GetString(msgNeedWorkbench));
- IconBase = OpenLibrary((APTR)"icon.library",37L);
- if (!IconBase) CloseAll(GetString(msgNeedIcon));
- AslBase = OpenLibrary((APTR)"asl.library",37L);
- if (!AslBase) CloseAll(GetString(msgNeedASL));
- OpenMegaViewCatalog(NULL,NULL);
- }
-
- BOOL Scan(char *type, APTR buf, ULONG bufsize, BOOL *quotes) {
- /* This routine scans the FileActions file, trying to find an action
- * for the file type given in <file>. If it is successfull, it returns
- * TRUE and fills the buffer pointed at by <buf> with the action template
- * from the file. <quotes> is set if the actions wished to have its filename
- * enclosed with quotes. If unsuccessful, it returns FALSE.
- */
- BPTR fh=NULL;
- APTR cs;
- int line=0;
- int c=0;
- UBYTE *cur;
- BOOL res=TRUE;
- struct RDArgs *myargs=NULL,*ap;
- fh=Open((APTR) ACTIONFILE,MODE_OLDFILE);
- if (!fh) CloseAll(GetString(msgNeedActionfile));
- /* try to set up a ReadArgs structure. We want the input to come
- * from a filehanle, not from the command line.
- */
- cs= AllocVec(BUFSIZE,MEMF_CLEAR);
- if (!cs) {
- if (fh) Close(fh);
- fh=NULL;
- return FALSE;
- }
- myargs=(struct RDArgs *)AllocDosObject(DOS_RDARGS,TAG_DONE);
- if (!myargs) {
- if (fh) Close(fh);
- fh = NULL;
- FreeVec(cs);
- return FALSE;
- }
- /* Main loop starts here */
- do {
- line++;
- /* Read a line from the file */
- cur=(UBYTE *)FGets(fh,(STRPTR)cs,BUFSIZE);
- if (!cur) {
- res=FALSE;
- break;
- }
- c=0;
- c=strlen(cur);
- /* skip empty and comment lines */
- if (*cur==';') continue;
- if (*cur=='\n') continue;
- if (cur[c-1]!='\n') {
- print(GetString(msgMissingNewline));
- res=FALSE;
- break;
- }
- /* Parse the line, using the ReadArgs call and the Template */
- myargs->RDA_Flags |= RDAF_NOPROMPT;
- myargs->RDA_Source.CS_Buffer = cs;
- myargs->RDA_Source.CS_Length = c;
- myargs->RDA_Source.CS_CurChr = 0L;
- ap=ReadArgs(CONFIG_TEMPLATE,ConfigLine,myargs);
- if (!ap) {
- /* We had an error while parsing, so bail out here and
- * tell the user
- */
- res=FALSE;
- Fault(IoErr(),NULL, cs, BUFSIZE);
- sprintf(pbuf,GetString(msgParseError), line, (char *)cs);
- print((STRPTR)pbuf);
- break;
- }
- /* The Parse was successful if we reach here. Look what filetype
- * is this entry for. If it is the one we seek, prepare to leave
- */
- if (stricmp(type,(char *)ConfigLine[CT_TYPE])==0) {
- strncpy((char *)buf,(char *)ConfigLine[CT_ACTION],bufsize);
- res=TRUE;
- if (bufsize<strlen((char *)ConfigLine[CT_ACTION])) res=FALSE;
- if (ConfigLine[CT_QUOTES]) *quotes=TRUE; else *quotes=FALSE;
- break;
- }
- FreeArgs(ap);
- } while (1);
- /* Clean up behind us */
- if (fh) Close(fh);
- fh = NULL;
- if (cs) FreeVec(cs);
- if (myargs) FreeDosObject(DOS_RDARGS,myargs);
- return res;
- }
-
- void HandleFile(char *fname) {
- /* The heart of the matter. This routine takes a filename as its argument
- * and tries to find a matching action for it. If successful, this action
- * is performed on the file.
- */
- BOOL bl,ok,quote;
- char cln[512];
- char clx[512];
- BPTR lock;
- APTR Buffer;
- BPTR window;
- LONG err;
- BPTR CLock, NLock;
- FileType DirType,VolType,ft;
- struct FileInfoBlock *fib,*bif;
- int i;
- Buffer=AllocVec(BUFSIZE,MEMF_CLEAR);
- if (Buffer) {
- /* We have 'nuff memory to do it, so lock the file, and we will
- * try to get more info on it.
- */
- lock=Lock((APTR)fname, SHARED_LOCK);
- if (lock) {
- /* The lock was ok, get the file's FileInfoBlock. First, we
- * must allocate this (via AllocDosObject).
- */
- fib=(struct FileInfoBlock *)AllocDosObject(DOS_FIB,NULL);
- if (fib) {
- /* Examine the file. We need this info for the filetype
- * examination. */
- Examine(lock,fib);
- witags[1].ti_Data=(ULONG)fib;
- /* Now, what type is this file? WhatIs will check this for us*/
- ft=WhatIs(fname,witags);
- /* Do we know this file? */
- if (CmpFileType(ft,TYPE_UNKNOWNFILETYPE)==0) {
- print(GetString(msgUnknownFiletype));
- } else {
- DirType = GetIDType("Dir");
- VolType = GetIDType("Volume");
- /* Check if the "file" was a directory or volume, and
- * the Recurse flag was set. If yes, go down into the
- * directory and scan ALL files there, recursively.
- */
- if (Recurse==TRUE && (CmpFileType(DirType,ft)==0 || CmpFileType(VolType,ft)==0)) {
- NLock=Lock((APTR)fname,SHARED_LOCK);
- if (NLock) {
- CLock=CurrentDir(NLock);
- if (CLock) {
- /* We tried to enter the directory, and we
- * were successful. Examine the directory
- * recursively, and HandleFile() every entry
- * we find, thus descending into subdirs
- * using the same mechanism. This could
- * eat up a lot of stack!
- */
- bif=(struct FileInfoBlock *)AllocDosObject(DOS_FIB,NULL);
- if (bif) {
- ok=Examine(NLock,bif);
- while (ok!=FALSE) {
- ok=ExNext(NLock,bif);
- if (ok) HandleFile(bif->fib_FileName);
- /* Recursion Alert! Watch yer stack! */
- }
- if (IoErr()!=ERROR_NO_MORE_ENTRIES) {
- print(GetString(msgErrorReadingDir));
- }
- FreeDosObject(DOS_FIB,bif);
- } else print(GetString(msgErrorFileInfoBlock));
- } else print(GetString(msgErrorCurrentDir));
- CurrentDir(CLock);
- UnLock(NLock);
- } else print(GetString(msgErrorLockDirectory));
- } else {
- /* We reach here if we are to examine the file(s)
- * normally. First, we do look if the file is one
- * of the "crunched" types.
- */
- strcpy(ftstring,GetIDString(ft));
- if (XPKName[0]!='\0' && MatchToolValue((STRPTR)XPKName,(STRPTR)ftstring)) {
- /* The file is packed. We use the TEMPDIR value
- * from the environment and decrunch it there.
- * We HandleFile() the result again. Note that
- * if the crunched file was crunched more than
- * once (quite silly, but not impossible), we
- * will decrunch it until we have it complete.
- */
- strcpy(cln,TEMPDIR);
- AddPart((STRPTR)cln,FilePart((STRPTR)fname),512);
- err=XpkUnpackTags(XPK_InName,fname,
- XPK_OutName,cln,
- TAG_DONE);
- if (err!=XPKERR_OK) {
- sprintf(cln,"XPK Error %d\n",err);
- print((STRPTR)cln);
- } else {
- HandleFile(cln);
- /* Recursion Alert! Watch yer stack! */
- if (KeepFiles==FALSE) DeleteFile((STRPTR)cln);
- }
- } else {
- /* The final stage, this is where files get
- * finally handled if they are neither crunched
- * nor directory/volumes. We get the ACTION via
- * the Scan() routine, and perform it, possibly
- * enclosing the filename with quotes if desired.
- */
- bl=Scan(ftstring,Buffer,BUFSIZE,"e);
- if (bl==FALSE) {
- sprintf(cln,GetString(msgNoAction),ftstring);
- print((STRPTR)cln);
- } else {
- if (quote==TRUE) sprintf(clx,"\042%s\042",fname);
- else strcpy(clx,fname);
- sprintf(cln,(char *)Buffer,clx);
- window=Open((STRPTR)win,MODE_READWRITE);
- /* Call the program */
- SystemTags((STRPTR)cln,
- SYS_Output, window,
- TAG_DONE);
- Close(window);
- }
- }
- }
- }
- /* Clean up after us */
- FreeDosObject(DOS_FIB,fib);
- } else print(GetString(msgErrorFileInfoBlock));
- UnLock(lock);
- } else print(GetString(msgErrorLockFile));
- FreeVec(Buffer);
- } else print(GetString(msgErrorAllocateBuffer));
- }
-
- void SetUpAndHandleIcon(char *IconName) {
- /* This routine, as the name implies, sets up the icon and does the
- * handling thereof. It is the routine that gets executed the most
- * if you are running MegaView in Icon mode.
- */
- struct DiskObject *dobj;
- struct AppIcon *ai;
- struct MsgPort *port;
- struct AppMessage *msg;
- char fname[512];
- int i;
- BOOL loaded=FALSE;
- BPTR oldlock;
- BOOL running=TRUE;
- BOOL flg=FALSE;
- /* GetDiskObject() tries to find an Icon with the name specified
- * in the command line/ToolTypes. If no name was given, this is
- * the name of the Icon MegaView was started with. If none is
- * found, the default icon (struct DiskObject MegaView above) is
- * used to represent us on the workbench.
- */
- dobj=GetDiskObject((STRPTR)IconName);
- if (dobj==NULL) dobj=&MegaView;
- else loaded=TRUE;
- /* ix and iy contain the x/y coordinate pair we want out icon to
- * appear. If none was specified, we let workbench decide were
- * to put the icon, by setting the x/y coordinates to the constant
- * NO_ICON_POSITION. Note that the same thing is done with icons
- * on disk: When they are created, the get their coordinates set
- * to the above constant. Doing a SNAPSHOT on those will overwrite
- * the coordinates with real values.
- */
- if (ix==0) dobj->do_CurrentX=NO_ICON_POSITION; else dobj->do_CurrentX=ix;
- if (iy==0) dobj->do_CurrentY=NO_ICON_POSITION; else dobj->do_CurrentY=iy;
- /* We need a message port for the Icon. It is created using the routine
- * from the C/Amiga.lib
- */
- port=CreatePort(NULL,0L);
- if (port) {
- /* If we got our port, we can add our Icon to the workbench's
- * AppIcon list.
- */
- ai=AddAppIconA(ICONID,0L,(STRPTR)IconName,port,
- NULL,dobj,NULL);
- if (ai) {
- while (running) {
- /* Wait for anything to happen. 'Anything' can either mean
- * that someone dropped (an) Icon(s) on us, or that someone
- * double-stabbed us with the mouse.
- * In either case, this should be a message of type
- * MTYPE_APPICON, every other message will simply
- * bounce off.
- */
- Wait(1<<port->mp_SigBit);
- while (msg=(struct AppMessage *)GetMsg(port)) {
- if (msg->am_Type!=MTYPE_APPICON) {
- ReplyMsg((struct Message *)msg);
- continue;
- }
- if (msg->am_NumArgs==0) {
- /* A NumArgs of zero means that our icon was
- * double clicked. Every value greater than
- * that means there was this number of icons
- * for us to handle.
- */
- if (ShortCut==TRUE) i=2;
- else i=ShowRequest((STRPTR)ABOUT,GetString(msgReqText));
- switch(i) {
- case 0:
- break;
- case 1:
- running=FALSE;
- break;
- case 2:
- flg=TRUE;
- while (flg==TRUE) {
- flg=FileRequest();
- if (flg==FALSE) break;
- if (NumArgs==0) HandleFile(FileName);
- else {
- int i;
- char buffer[256];
- for (i=0; i<NumArgs; i++) {
- strncpy(buffer,FileName,256);
- AddPart((STRPTR)buffer,(STRPTR)(request->rf_ArgList[i].wa_Name),256);
- HandleFile(buffer);
- }
- }
- if (flg==TRUE) Delay(1L);
- }
- break;
- case 3:
- SystemTagList((STRPTR)EDITOR,NULL);
- break;
- }
- } else {
- /* We got one or more icons. The WBArg structure array
- * contains the file name, and the lock to the
- * files directory. We CurrentDir() (=CD) into this
- * dir and HandleFile() the file.
- */
- for (i=0; i<msg->am_NumArgs; i++) {
- strcpy(fname,(char *)(msg->am_ArgList[i].wa_Name));
- oldlock=CurrentDir(msg->am_ArgList[i].wa_Lock);
- HandleFile(fname);
- CurrentDir(oldlock);
- }
- }
- /* Messages MUST ALWAYS be sent back, or the system
- * will lock.
- */
- ReplyMsg((struct Message *)msg);
- }
- }
- /* Make sure there is no pending message at our port,
- * by replying everything that is still queued up.
- */
- while (msg=(struct AppMessage *)GetMsg(port)) {
- ReplyMsg((struct Message *)msg);
- }
- /* Remove the icon from the Workbench */
- RemoveAppIcon(ai);
- } else print(GetString(msgErrorAppIcon));
- DeletePort(port);
- } else print(GetString(msgErrorCreatePort));
- /* If out Icon was loaded from disk, free the memory space */
- if (loaded==TRUE) {
- FreeDiskObject(dobj);
- }
- }
-
-
- void SetUpAndHandleMenu(char *MenuName) {
- /* This routine does the same as the above icon handler, except that there
- * is no need to load an icon image. Everything is handled exactly the
- * same way as above.
- */
- struct AppMenuItem *ai;
- struct MsgPort *port;
- struct AppMessage *msg;
- char fname[512];
- int i;
- BPTR oldlock;
- BOOL running=TRUE;
- BOOL flg=FALSE;
- port=CreatePort(NULL,0L);
- if (port) {
- ai=AddAppMenuItemA(ICONID,0L,(STRPTR)MenuName,port,NULL);
- if (ai) {
- while (running) {
- Wait(1<<port->mp_SigBit);
- while (msg=(struct AppMessage *)GetMsg(port)) {
- if (msg->am_Type!=MTYPE_APPMENUITEM) {
- ReplyMsg((struct Message *)msg);
- continue;
- }
- if (msg->am_NumArgs==0) {
- if (ShortCut==TRUE) i=2;
- else i=ShowRequest((STRPTR)ABOUT,GetString(msgReqText));
- switch(i) {
- case 0:
- break;
- case 1:
- running=FALSE;
- break;
- case 2:
- flg=TRUE;
- while (flg==TRUE) {
- flg=FileRequest();
- if (flg==FALSE) break;
- if (NumArgs==0) HandleFile(FileName);
- else {
- int i;
- char buffer[256];
- for (i=0; i<NumArgs; i++) {
- strncpy(buffer,FileName,256);
- AddPart((STRPTR)buffer,(STRPTR)(request->rf_ArgList[i].wa_Name),256);
- HandleFile(buffer);
- }
- }
- if (flg==TRUE) Delay(1L); /* this is here to fix an optimzer bug in Aztec 5.0 */
- }
- break;
- case 3:
- SystemTagList((STRPTR)EDITOR,NULL);
- break;
- }
- } else {
- for (i=0; i<msg->am_NumArgs; i++) {
- strcpy(fname,(char *)(msg->am_ArgList[i].wa_Name));
- oldlock=CurrentDir(msg->am_ArgList[i].wa_Lock);
- HandleFile(fname);
- CurrentDir(oldlock);
- }
- }
- ReplyMsg((struct Message *)msg);
- }
- }
- while (msg=(struct AppMessage *)GetMsg(port)) {
- ReplyMsg((struct Message *)msg);
- }
- RemoveAppMenuItem(ai);
- } else print(GetString(msgErrorAppMenu));
- DeletePort(port);
- } else print(GetString(msgErrorCreatePort));
- }
-
- void HandleWBStartup(char **argv) {
- /* What we do here is to handle startup via the workbench. This routine does
- * also handle the tooltypes, and processes files that were selected when
- * our program icon was double clicked, or which had us as there default
- * tool. Please note that being multi-select-started (i.e. being started
- * with some projects selected simultaneously) or being started as a
- * default tool makes not much difference for a program.
- */
- int i;
- BPTR oldlock;
- struct WBStartup *wbs;
- char fname[256];
- UBYTE **ta, *s;
- struct DiskObject *dob;
- struct WBArg *wba;
- /* C startup code stores the WBStartup message in argv if argc is zero */
- wbs=(struct WBStartup *)argv;
- wbrun=TRUE;
- wba=wbs->sm_ArgList;
- strcpy(IconName,PNAME);
- strcpy(MenuName,PNAME);
- /* If there is more than one icon selected when we were launched, we
- * want them to be displayed. This works much the same way as with the
- * AppIcon messages. The AppIcon message supplied us with an array
- * of WBArg structures. The WBStartup message does the same.
- */
- if (wbs->sm_NumArgs>1) { /* Display Files */
- if (wba->wa_Name) {
- /* We load the project's icon to examine its tooltypes */
- dob=GetDiskObject((STRPTR)(wba->wa_Name));
- if (dob) {
- ta = (UBYTE **)dob->do_ToolTypes;
- /* There are two ToolType handling functions, FindToolType()
- * and MatchToolValue(). The first searches for a line
- * <VARIABLE>=<value> in the tooltype array and returns
- * the <value> part. MatchToolValue() checks if there is
- * a string in the <value> which matches the string we
- * search, e.g. you can look for a "YES" in a value of
- * "YES|JA|OUI|SI", or you can check if you need to
- * set styles like "BOLD|ITALIC". See RKM's for details
- */
- if (s=FindToolType(ta,(UBYTE *)"WINDOW")) strcpy(win,s);
- if (s=FindToolType(ta,(UBYTE *)"RECURSE")) Recurse=TRUE;
- else Recurse=FALSE;
- if (s=FindToolType(ta,(UBYTE *)"PACK")) strcpy(XPKName,s);
- if (s=FindToolType(ta,(UBYTE *)"AFILE")) strcpy(ACTIONFILE,s);
- if (s=FindToolType(ta,(UBYTE *)"TMPDIR")) strcpy(TEMPDIR,s);
- if (s=FindToolType(ta,(UBYTE *)"KEEPFILES"))KeepFiles=TRUE;
- if (s=FindToolType(ta,(UBYTE *)"EDITOR")) strcpy(EDITOR,s);
- FreeDiskObject(dob);
- }
- }
- /* Do the showing. This is, as I said, exactly as in the icon handler */
- for (i=1; i<wbs->sm_NumArgs; i++) {
- strcpy(fname,(char *)(wbs->sm_ArgList[i].wa_Name));
- oldlock=CurrentDir(wbs->sm_ArgList[i].wa_Lock);
- HandleFile(fname);
- CurrentDir(oldlock);
- }
- } else {
- /* We were started as a tool, without arguments. Look into the
- * tooltype array what exactly we are supposed to do, or tell
- * the user that we need more info on something
- */
- if (wba->wa_Name) {
- dob=GetDiskObject((STRPTR)(wba->wa_Name));
- if (dob) {
- ta = (UBYTE **)dob->do_ToolTypes;
- if (s=FindToolType(ta,(UBYTE *)"SHORTCUT")) ShortCut=TRUE;
- if (s=FindToolType(ta,(UBYTE *)"WINDOW")) strcpy(win,s);
- if (s=FindToolType(ta,(UBYTE *)"ICONNAME")) strcpy(IconName,s);
- if (s=FindToolType(ta,(UBYTE *)"MENUNAME")) strcpy(MenuName,s);
- if (s=FindToolType(ta,(UBYTE *)"MODE")) {
- /* Decide if we should stay resident. Either
- * MODE=Icon or MODE=Menu must be specified, or
- * we will exit with a short requester. Icon and Menu
- * are mutually exclusive, you can only specify one
- */
- if (MatchToolValue(s,(UBYTE *)"Icon")) IconMode=TRUE;
- if (MatchToolValue(s,(UBYTE *)"Menu")) MenuMode=TRUE;
- /* Note that the above would make it possible to
- * specify MODE=Icon|Menu, resulting in both modes
- * to be set. We check below if this happened, and
- * if yes, refuse to run.
- */
- }
- if (s=FindToolType(ta,(UBYTE *)"RECURSE")) Recurse=TRUE;
- else Recurse=FALSE;
- if (s=FindToolType(ta,(UBYTE *)"ICON_X")) ix=atoi(s);
- if (s=FindToolType(ta,(UBYTE *)"ICON_Y")) iy=atoi(s);
- if (s=FindToolType(ta,(UBYTE *)"PACK")) strcpy(XPKName,s);
- if (s=FindToolType(ta,(UBYTE *)"AFILE")) strcpy(ACTIONFILE,s);
- if (s=FindToolType(ta,(UBYTE *)"TMPDIR")) strcpy(TEMPDIR,s);
- if (s=FindToolType(ta,(UBYTE *)"KEEPFILES"))KeepFiles=TRUE;
- if (s=FindToolType(ta,(UBYTE *)"EDITOR")) strcpy(EDITOR,s);
- FreeDiskObject(dob);
- if (IconMode && MenuMode) {
- print(GetString(msgErrorMenuIcon));
- } else {
- if (IconMode==TRUE) SetUpAndHandleIcon(IconName);
- if (MenuMode==TRUE) SetUpAndHandleMenu(MenuName);
- if (MenuMode==FALSE && IconMode==FALSE) {
- print(GetString(msgWorkbenchUsage));
- }
- }
- } else print(GetString(msgErrorIcon));
- } else print(GetString(msgNoIcon));
- /* this funny error message means that the user has shift-clicked
- * an icon which does not exists, and this should not happen at all.
- */
- }
- }
-
- void SearchMan(char *name) {
- /* Simulate the UN*X 'MAN' command. We get a list of paths, seperated
- * with commas, and search a file which starts with the name specified
- * but does not end with '.info'.
- */
- char NewName[512];
- char dir[512];
- char paths[512];
- struct AnchorPath *ap;
- int i,j,k;
- LONG err;
- BPTR lock,oldlock;
- BOOL ok=FALSE;
- i=GetVar((STRPTR)"MegaViewPATHS",(STRPTR)paths,512,0L);
- if (i==-1) strcpy(paths,".");
- i=0; k=strlen(paths);
- ap=(struct AnchorPath *)AllocMem(sizeof(struct AnchorPath), MEMF_ANY|MEMF_CLEAR);
- if (ap) {
- while (i<k) {
- j=0;
- /* Extract a path. Treat '.' as the current dir. */
- while (paths[i]!=',' && paths[i]!=0)
- dir[j++]=paths[i++];
- ++i;
- dir[j]=0;
- if (strcmp(dir,".")==0) lock=Lock((STRPTR)"",ACCESS_READ);
- else lock=Lock((STRPTR)dir,ACCESS_READ);
- if (lock) {
- /* Change into the directory and try to find a file
- * we can use. MatchFirst will give us the name of
- * this file, if it exists. In fact, the file is
- * matched as (name~(#?.info)|name). This would
- * match things like name, name.doc, name.dok,
- * name.documentation.txt, but not things like
- * name.info or name.documentation.txt.info
- */
- oldlock=CurrentDir(lock);
- sprintf(NewName, "(%s~(#?.info)|%s)", name, name);
- err=MatchFirst((STRPTR)NewName,ap);
- if (err==0) {
- strcpy(name, (char *)ap->ap_Info.fib_FileName);
- HandleFile(name);
- ok=TRUE;
- }
- MatchEnd(ap);
- UnLock(lock);
- lock=NULL;
- CurrentDir(oldlock);
- oldlock=NULL;
- if (ok==TRUE) break;
- } else print(GetString(msgErrorManDir));
- }
- FreeMem((APTR)ap,sizeof(struct AnchorPath));
- } else print(GetString(msgErrorAnchor));
- }
-
- void main(int argc, char **argv) {
- /* The main routine. */
- struct RDArgs *rda;
- char fname[256];
- int i;
- /* Get us the resources we need. If this routine returns at all,
- * the we have everything up and running. If not, it has
- * wimped out of the program, leaving an error message to
- * the user.
- */
- OpenAll();
- /* Get some variables. These could be environment variables
- * (from the ENV: dir) or shell variables. If they don't exist
- * fill the fields with default values.
- */
- i=GetVar((STRPTR)"MegaViewPACK",(STRPTR)XPKName,49,0L);
- if (i==-1) XPKName[0]=0;
- i=GetVar((STRPTR)"MegaViewACTION",(STRPTR)ACTIONFILE,49,0L);
- if (i==-1) strcpy(ACTIONFILE,"s:FileActions");
- i=GetVar((STRPTR)"MegaViewTEMP",(STRPTR)TEMPDIR,49,0L);
- if (i==-1) strcpy(TEMPDIR,"T:");
- i=GetVar((STRPTR)"MegaViewEDIT",(STRPTR)EDITOR,49,0L);
- if (i==-1) strcpy(EDITOR,"FAEdit");
- /* Check if we are run from Workbench (argc is zero) */
- if (argc==0) {
- HandleWBStartup(argv);
- CloseAll(NULL);
- }
- /* Parse the command line. We use the Command template from the
- * beginning of this file. These templates are also used for
- * the system commands, which essentially use the same function
- * for their command line parsing. Calling this function will
- * also display the template if we enter 'MegaView ?', and
- * will prompt for input after that, without our program
- * knowing that.
- */
- rda=ReadArgs(COMMAND_TEMPLATE,CommandLine,NULL);
- /* The result if NULL if the command line was invalid. We print an
- * error message about what was wrong with it, and panic out of the
- * program.
- */
- if (rda==NULL) {
- PrintFault(IoErr(),NULL);
- CloseAll(NULL);
- }
- /* We were given a valid command line. Take out the info we need
- * and store it for later use.
- */
- if (CommandLine[CO_SHORTCUT]) ShortCut=TRUE;
- else ShortCut=FALSE;
- if (CommandLine[CO_FILE]) strcpy(fname,(char *)CommandLine[CO_FILE]);
- else strcpy(fname,"");
- if (CommandLine[CO_PACK]) strcpy(XPKName,(char *)CommandLine[CO_PACK]);
- if (CommandLine[CO_AFILE]) strcpy(ACTIONFILE,(char *)CommandLine[CO_AFILE]);
- if (CommandLine[CO_TMPDIR]) strcpy(TEMPDIR,(char *)CommandLine[CO_TMPDIR]);
- if (CommandLine[CO_KEEPFILES]) KeepFiles=TRUE;
- else KeepFiles=FALSE;
- if (CommandLine[CO_REQ]) {
- /* This loop asks for files via the file requester until the user
- * pressed cancel
- */
- BOOL flg;
- for (i=0; i<7; i++) {
- Delay(1L);
- if (!request) request=(struct FileRequester *)AllocAslRequest(ASL_FileRequest,atags);
- if (request) break;
- }
- flg=TRUE;
- while (flg==TRUE) {
- flg=FileRequest();
- if (flg==FALSE) break;
- if (NumArgs==0) HandleFile(FileName);
- else {
- int i;
- char buffer[256];
- for (i=0; i<NumArgs; i++) {
- strncpy(buffer,FileName,256);
- AddPart((STRPTR)buffer,(STRPTR)(request->rf_ArgList[i].wa_Name),256);
- HandleFile(buffer);
- }
- }
- if (flg==TRUE) Delay(1L); /* this is here to fix an optimzer bug in Aztec 5.0 */
- }
- FreeArgs(rda);
- CloseAll(NULL);
- }
- if (CommandLine[CO_ICON]) {
- if (CommandLine[CO_ICONNAME]) strncpy(IconName,(char *)CommandLine[CO_ICONNAME],50);
- else strcpy(IconName,"MegaView");
- SetUpAndHandleIcon(IconName);
- FreeArgs(rda);
- CloseAll(NULL);
- }
- if (CommandLine[CO_MENU]) {
- if (CommandLine[CO_MENUNAME]) strncpy(MenuName,(char *)CommandLine[CO_MENUNAME],50);
- else strcpy(MenuName,"MegaView");
- SetUpAndHandleMenu(MenuName);
- FreeArgs(rda);
- CloseAll(NULL);
- }
- if (CommandLine[CO_ALL]) {
- Recurse=TRUE;
- } else {
- Recurse=FALSE;
- }
- if (CommandLine[CO_MAN]) {
- strcpy(fname, (char *)CommandLine[CO_MAN]);
- SearchMan(fname);
- } else {
- if (fname[0]=='\0') {
- if (CommandLine[CO_ICON]==0 || CommandLine[CO_MENU]==0) {
- print(GetString(msgNeedFilename));
- }
- } else HandleFile(fname);
- }
- FreeArgs(rda);
- CloseAll(NULL);
- }
-
-