home *** CD-ROM | disk | FTP | other *** search
-
- /* *** filename.c ***********************************************************
- *
- * File IO Suite -- File Name Construction Routines
- * from Book 1 of the Amiga Programmers' Suite by RJ Mical
- *
- * Copyright (C) 1986, 1987, Robert J. Mical
- * All Rights Reserved.
- *
- * Created for Amiga developers.
- * Any or all of this code can be used in any program as long as this
- * entire copyright notice is retained, ok? Thanks.
- *
- * HISTORY NAME DESCRIPTION
- * ----------- -------------- --------------------------------------------
- * 4 Feb 87 RJ Real release
- * 12 Aug 86 RJ >:-{)* Prepare (clean house) for release
- * 3 May 86 =RJ Mical= Fix prop gadget for both 1.1 and 1.2
- * 1 Feb 86 =RJ Mical= Created this file.
- *
- * *********************************************************************** */
-
-
- #define FILEIO_SOURCEFILE
- #include "fileio.h"
- #include <libraries\dosextens.h>
-
-
- #define FRIENDLY_NOT 0
- #define FRIENDLY_DRAWER 1
- #define FRIENDLY_OTHER 2
-
-
-
- VOID BuildNameTable(fileio)
- struct FileIOSupport *fileio;
- /* This routine searches through the fileio lock for all file entries,
- * and builds a list of the names found.
- * If the user wants Workbench-style pattern matching, filenames are
- * passed through a filter before being added to the list.
- * All directory entries are added to the list.
- */
- {
- struct FileInfoBlock *fileinfo;
- UBYTE *ptr;
- UBYTE workname[MAX_NAME_LENGTH + 5]; /* the extra 5 are for the ".info" */
- struct Remember **key;
- ULONG lock;
- SHORT i, flags, type;
- SHORT pick;
-
- fileio->NameCount = 0;
- lock = fileio->DOSLock;
- key = &fileio->NameKey;
- FreeRemember(key, TRUE);
- ClearFlag(fileio->Flags, GOOD_FILENAMES);
-
- if ((fileinfo = (struct FileInfoBlock *)AllocMem(
- sizeof(struct FileInfoBlock), MEMF_CLEAR)) == NULL)
- goto BUILD_EXIT;
-
- SetWaitPointer(OpenReqWindow);
-
- /* Now, first, before we might be interrupted by MessageInterrupt(),
- * check whether or not we're looking in a drawer and, if so, add the
- * entry that allows the user to ascend one drawer.
- */
- if (StringLength(&OpenReqFileIO->DrawerName[0]))
- {
- MakeEntry("\253\253 PRIOR DRAWER", &fileio->NameKey, NAMED_PREVIOUS);
- /* bump the master count */
- fileio->NameCount++;
- }
-
- /* starting from Examine() until ExNext() is NULL */
- if (Examine(lock, fileinfo))
- while (ExNext(lock, fileinfo))
- {
- /* Default: this entry is a normal file */
- flags = NULL;
- CopyString(&workname[0], fileinfo->fib_FileName);
-
- #ifdef WBENCH_CODE
- /* Now, does the caller want Workbench-style pattern matching? */
- if (FlagIsSet(fileio->Flags, WBENCH_MATCH))
- {
- /* start from location 1 to avoid matching the ".info" file */
- if (ptr = FindSuffix(&workname[1], ".info"))
- {
- *ptr = '\0'; /* strip the suffix off that baby */
-
- /* Get the friendliness quotient of this .info file */
- type = FriendlyInfoType(&workname[0], fileio);
-
- /* If just not friendly, forget about it */
- if (type == FRIENDLY_NOT) goto NEXT_LOCK;
-
- /* If this was a drawer, set the fileinfo as a directory */
- if (type == FRIENDLY_DRAWER)
- fileinfo->fib_DirEntryType = 1;
- }
- else goto NEXT_LOCK;
- }
- #endif /* ... of WBENCH_CODE conditional */
-
- if (fileinfo->fib_DirEntryType >= 0)
- {
- /* This entry is a directory */
- flags = NAMED_DIRECTORY;
-
- /* If you change the following text, change DIR_TEXT_SIZE too */
- for (i = StringLength(&workname[0]); i >= 0; i--)
- workname[i + DIR_TEXT_SIZE] = workname[i];
- workname[0] = '\273';
- workname[1] = '\273';
- workname[2] = ' ';
- }
-
- pick = MakeEntry(&workname[0], &fileio->NameKey, flags);
- /* bump the master count */
- fileio->NameCount++;
-
- if (pick <= fileio->CurrentPick)
- fileio->CurrentPick++;
-
- InitOpenProp(FALSE);
- StuffSelectNames(2);
-
- NEXT_LOCK:
- /* If there's a message pending, split with what we've got */
- if (MessageInterrupt()) goto EXAMINE_DONE;
- }
-
- SetFlag(fileio->Flags, GOOD_FILENAMES);
-
-
- EXAMINE_DONE:
-
- if (OpenReqWindow) ClearPointer(OpenReqWindow);
- FreeMem(fileinfo, sizeof(struct FileInfoBlock));
-
-
- BUILD_EXIT: ;
- }
-
-
-
- VOID PropInterrupt()
- /* This routine is called by MessageInterrupt() if the prop gadget
- * is played with while the file name table is being built.
- * As long as the user is using the proportional gadget, hang around here.
- */
- {
- struct IntuiMessage *message;
- struct Gadget *gadget;
- BOOL mousemove;
-
- FOREVER
- {
- WaitPort(OpenReqWindow->UserPort);
- mousemove = FALSE;
-
- while (message = GetMsg(OpenReqWindow->UserPort))
- {
- switch (message->Class)
- {
- case GADGETUP:
- gadget = (struct Gadget *)message->IAddress;
- switch (gadget->GadgetID)
- {
- case OPENGADGET_PROPGADGET:
- ReplyMsg(message);
- HandleGadget(gadget, 0, 0, 0, 0);
- return;
-
- default:
- goto MESSAGE_RETURN;
- }
- break;
-
- case MOUSEMOVE:
- ReplyMsg(message);
- mousemove = TRUE;
- break;
-
- default:
- goto MESSAGE_RETURN;
-
- }
- }
-
- if (mousemove) PropMouseMoves();
- }
-
- MESSAGE_RETURN:
- /* Pretend we didn't see this message */
- AddHead(&OpenReqWindow->UserPort->mp_MsgList, message);
- }
-
-
-
- BOOL MessageInterruptGrunt(message)
- struct IntuiMessage *message;
- /* Test if there's a gadget type of message at the window port,
- * react to it if there is one, and return TRUE if the message is
- * one that should interrupt the building of the file name list.
- */
- {
- ULONG class;
- SHORT x, y;
- struct Gadget *gadget;
- LONG seconds, micros;
-
- class = message->Class;
- if ((class == GADGETDOWN) || (class == GADGETUP))
- {
- gadget = (struct Gadget *)message->IAddress;
- x = message->MouseX;
- y = message->MouseY;
- seconds = message->Seconds;
- micros = message->Micros;
- OpenReqSupport.SelectedGadgetID = gadget->GadgetID;
-
- switch (gadget->GadgetID)
- {
- case OPENGADGET_SELECTNAME:
- y = HandleSelect(y, seconds, micros);
- if ((y == -1) || (y == 1))
- {
- /* Pretend we didn't see this message */
- AddHead(&OpenReqWindow->UserPort->mp_MsgList, message);
- return(TRUE);
- }
-
- StuffFileName();
- StuffSelectNames(5);
- goto REPLY_AND_RETURN_FALSE;
-
- case OPENGADGET_UPGADGET:
- case OPENGADGET_DOWNGADGET:
- goto REPLY_AND_RETURN_FALSE;
-
- case OPENGADGET_PROPGADGET:
- HandleGadget(gadget, x, y, seconds, micros);
- if (class == GADGETDOWN) PropInterrupt();
- goto REPLY_AND_RETURN_FALSE;
-
- default:
- /* Do nothing, fall into the message's AddHead() below.
- * This includes the gadgets OK, CANCEL, NEXTDISK,
- * DISKNAME, DRAWERNAME, FILENAME, and BACKDROP.
- */
- break;
- }
- }
-
- /* Pretend we didn't see this message */
- AddHead(&OpenReqWindow->UserPort->mp_MsgList, message);
- return(TRUE);
-
- REPLY_AND_RETURN_FALSE:
- ReplyMsg(message);
- return(FALSE);
- }
-
-
-
- BOOL MessageInterrupt()
- /* Call MessageInterruptGrunt() with each message.
- * Return TRUE if the message is one that should interrupt the building
- * of the file name list, else return FALSE.
- */
- {
- struct IntuiMessage *message;
-
- while (message = GetMsg(OpenReqWindow->UserPort))
- {
- if (MessageInterruptGrunt(message))
- return(TRUE);
- }
- return(FALSE);
- }
-
-
-
- SHORT MakeEntry(name, startkey, flags)
- UBYTE *name;
- struct Remember **startkey;
- UBYTE flags;
- {
- SHORT length, pos;
- struct Remember *localkey, *nextkey, *oldkey;
- UBYTE *ptr;
-
- /* length equals the length of the text plus one for the
- * terminating NULL
- */
- length = StringLength(name) + 1;
- localkey = NULL;
- /* Alloc one larger than length to make room for the flag byte */
- ptr = AllocRemember(&localkey, length + 1, NULL);
- if (ptr == NULL) return;
- CopyString(ptr, name);
- *(ptr + length) = flags;
- nextkey = *startkey;
- pos = 0;
- oldkey = NULL;
- while (nextkey)
- {
- if (CompareUpperStrings(nextkey->Memory, name) >= 0)
- goto DONE;
-
- oldkey = nextkey;
- nextkey = nextkey->NextRemember;
- pos++;
- }
-
- DONE:
- if (oldkey) oldkey->NextRemember = localkey;
- else *startkey = localkey;
- localkey->NextRemember = nextkey;
- return(pos);
- }
-
-
-
-
- #ifdef WBENCH_CODE
-
- SHORT FriendlyInfoType(infoname, fileio)
- UBYTE *infoname;
- struct FileIOSupport *fileio;
- /* This routine looks at the .info file that's named infoname and
- * tests to see if its object type and tool type match the specifications
- * in the fileio structure. Returns TRUE if everything matches.
- * If the .info file couldn't be opened or if the requirements don't
- * match, FALSE is returned.
- */
- {
- struct DiskObject *object;
- SHORT result;
-
- result = FRIENDLY_NOT;
- if (object = GetDiskObject(infoname))
- {
- if ((object->do_Type == WBDRAWER) || (object->do_Type == WBGARBAGE))
- result = FRIENDLY_DRAWER;
- else if (object->do_Type == WBDISK)
- result = FRIENDLY_NOT;
- else
- {
- if (FlagIsSet(fileio->Flags, MATCH_OBJECTTYPE))
- if (object->do_Type != fileio->DiskObjectType) goto FRIEND_DONE;
-
- result = FRIENDLY_OTHER;
-
- if (FlagIsSet(fileio->Flags, MATCH_TOOLTYPE))
- {
- if (NOT MatchToolValue(
- FindToolType(object->do_ToolTypes, "FILETYPE"),
- &fileio->ToolType[0]))
- result = FRIENDLY_NOT;
- }
- }
- }
-
- FRIEND_DONE:
- if (object) FreeDiskObject(object);
- return(result);
- }
-
- #endif /* ... of WBENCH_CODE conditional */
-
-
-
-