home *** CD-ROM | disk | FTP | other *** search
-
- /* *** fileio.c *************************************************************
- *
- * File IO Suite -- Primary FileIO Requester 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"
-
-
- /* These routines can be found in filesupp.c */
- extern HandleGadget();
- extern StartOpenRequester();
- extern DiskInserted();
- extern PropMouseMoves();
-
-
-
- /* *** GetFileIOSupport() ***************************************************
- *
- * NAME
- * GetFileIOSupport -- Allocate and initialize a FileIOSupport structure
- *
- *
- * SYNOPSIS
- * struct FileIOSupport *GetFileIOSupport();
- *
- *
- * FUNCTION
- * Allocates and initializes a FileIOSupport structure for use with
- * calls to GetFileIOName().
- *
- * You may want to further initialize the structure before calling
- * GetFileIOName(). Refer to the FileIO documentation for more
- * information.
- *
- * When you're done with the structure, call ReleaseFileIO().
- *
- *
- * INPUTS
- * None
- *
- *
- * RESULT
- * If all goes well, returns the address of a FileIOSupport structure.
- * If anything goes wrong (usually out of memory), returns NULL.
- *
- *
- * EXAMPLE
- * struct FileIOSupport *fileio;
- * fileio = GetFileIOSupport();
- * GetFileIOName(fileio, window);
- * ReleaseFileIO(fileio);
- *
- *
- * BUGS
- * None known
- *
- *
- * SEE ALSO
- * GetFileIOName(), ReleaseFileIO()
- */
- struct FileIOSupport *GetFileIOSupport()
- {
- struct FileIOSupport *fileio;
-
- if (fileio = (struct FileIOSupport *)AllocMem(
- sizeof(struct FileIOSupport), MEMF_CLEAR))
- {
- /* Anything special to initialize? */
- SetFlag(fileio->Flags, USE_VOLUME_NAMES);
- }
- return(fileio);
- }
-
-
-
- /* *** GetFileIOName() ******************************************************
- *
- * NAME
- * GetFileIOName -- Gets a file name for input/output from the user
- *
- *
- * SYNOPSIS
- * BOOL GetFileIOName(FileIO, Window);
- *
- *
- * FUNCTION
- * This routine creates a filename requester which allows the user
- * to browse through the AmigaDOS filesystem and select one of
- * the filenames found there.
- *
- * The FileIO argument is a pointer to a FileIOSupport structure,
- * which is allocated and initialized for you via a call to
- * GetFileIOSupport().
- * You may preset the FileIO parameters before calling this routine,
- * or you may leave them set at their default values. See the FileIO
- * documentation for complete details.
- *
- * The Window argument is the pointer to the window structure returned
- * by a call to Intuition's OpenWindow() function. As this routine
- * opens a requester and requesters open in windows, you must have
- * already opened a window before calling this routine, even if it's
- * a window opened for no other purpose than to call this routine.
- *
- * This routine returns a BOOL value of TRUE or FALSE, depending on
- * whether the user chose to accept or cancel the filename selection
- * operation. If TRUE, the filename selected by the user can be
- * found in the FileIO structure FileName[] field. This filename
- * will have all leading and trailing blanks removed (in case the
- * user typed in a filename with extraneous spaces). Likewise,
- * the pathname to the disk and drawer can be found in the text
- * fields DiskName[] and DrawerName[]. You can construct
- * the pathname using these text strings. Also, you can call
- * BuildFileIOPathname() to build the pathname automatically.
- *
- * There's a *lot* more to be said about this function. Please
- * read the documentation.
- *
- * NOTE: This routine is not re-entrant. What this means
- * is that if you have created a program that has more than one task,
- * this routine cannot be called by more than one task at a time.
- * This is not a problem for the grand majority of programs.
- * But if you have some application that would require calling this
- * routine asynchronously from multiple tasks, you'll have to
- * implement some quick semaphore arrangement to avoid collisions.
- * No big deal, actually. See Exec semaphores for everything you need.
- *
- *
- * INPUTS
- * FileIO = pointer to a FileIOSupport structure, as allocated
- * via a call to GetFileIOSupport()
- * Window = pointer to a Window structure, as created via a call
- * to Intuition's OpenWindow()
- *
- *
- * RESULT
- * TRUE if the user decided that the filename selection was successful,
- * FALSE if the user chose to cancel the operation
- *
- *
- * EXAMPLE
- * if (GetFileIOName(fileio, window))
- * ProcessFileName(&fileio->FileName[0]);
- *
- *
- * BUGS
- * None known, though there could be some, and the disk selection
- * subsystem logic is not perfectly polished (though it's believed
- * to be bug-free).
- *
- *
- * SEE ALSO
- * BuildFileIOPathname(), GetFileIOSupport(), ReleaseFileIO()
- */
- BOOL GetFileIOName(fileio, window)
- struct FileIOSupport *fileio;
- struct Window *window;
- {
- UBYTE *newtext;
-
- if ((fileio == NULL) || (window == NULL)) return(FALSE);
-
- OpenSaveLock = CurrentDir(NULL);
- CurrentDir(OpenSaveLock);
- fileio->DOSLock = OpenSaveLock;
-
- /* Get easily-accessible copies of the values that are referenced
- * most often
- */
- OpenReq = &OpenReqSupport.Requester;
- OpenReqWindow = OpenReqSupport.Window = window;
- OpenReqFileIO = fileio;
-
- /* Set up the DoRequest() handlers */
- OpenReqSupport.GadgetHandler = HandleGadget;
- OpenReqSupport.StartRequest = StartOpenRequester;
- OpenReqSupport.NewDiskHandler = DiskInserted;
- OpenReqSupport.MouseMoveHandler = PropMouseMoves;
-
- /* Init the string gadget buffers */
- OpenNameTextInfo.Buffer = &fileio->FileName[0];
- OpenDrawerTextInfo.Buffer = &fileio->DrawerName[0];
- OpenDiskTextInfo.Buffer = &fileio->DiskName[0];
-
- /* Initialize the requester title */
- if ((ReqTitleText.IText = fileio->ReqTitle) == NULL)
- ReqTitleText.IText = DefaultReqTitle;
- ReqTitleText.LeftEdge
- = (OPEN_WIDTH - IntuiTextLength(&ReqTitleText)) >> 1;
-
- /* If this fileio doesn't have valid filenames,
- * then refresh the whole thing
- */
- if (FlagIsClear(fileio->Flags, GOOD_FILENAMES))
- {
- ResetNameText(TRUE);
- ResetDrawerText(TRUE);
- BuildVolumeTable(fileio);
- CopyString(&OpenReqFileIO->DiskName[0], CurrentVolumeName());
- }
-
- ResetNameText(FALSE);
- ResetDrawerText(FALSE);
- ResetDiskText(FALSE);
-
- StuffSelectNames(0);
- InitOpenProp(TRUE);
-
- /* Reset the double-click time variables */
- OpenClickSeconds = OpenClickMicros = 0;
-
-
- /* And now, do that requester. */
- DoRequest(&OpenReqSupport);
- /* Back, eh? Wasn't that easy? */
-
-
- if (FlagIsSet(fileio->Flags, LOCK_GOTTEN))
- {
- UnLock(fileio->DOSLock);
- ClearFlag(fileio->Flags, LOCK_GOTTEN);
- }
-
- CurrentDir(OpenSaveLock);
- OpenReqFileIO = NULL;
-
- /* Strip any excess leading and trailing blanks off the final name */
- newtext = StripOuterSpace(&fileio->FileName[0], " ");
- CopyString(&fileio->FileName[0], newtext);
-
- if (OpenReqSupport.SelectedGadgetID != OPENGADGET_CANCEL)
- return(TRUE);
- return(FALSE);
- }
-
-
-
- /* *** BuildFileIOPathname() ************************************************
- *
- * NAME
- * BuildFileIOPathname -- Build a file pathname using a FileIO struct
- *
- *
- * SYNOPSIS
- * BuildFileIOPathname(FileIOSupport, Buffer);
- *
- *
- * FUNCTION
- * Builds the text for a pathname using the FileName[], DrawerName[] and
- * DiskName[] fields of the specified FileIOSupport structure
- * after the support structure has been used in a successful call
- * to GetFileIOName(). Writes the text into the Buffer.
- *
- *
- * INPUTS
- * FileIOSupport = the address of a FileIOSupport structure
- * Buffer = address of the buffer to receive the file pathname
- *
- *
- * RESULT
- * None
- *
- *
- * SEE ALSO
- * GetFileIOName()
- */
- VOID BuildFileIOPathname(fileio, buffer)
- struct FileIOSupport *fileio;
- UBYTE *buffer;
- {
- StripOuterSpace(&fileio->DiskName[0], " ");
- StripOuterSpace(&fileio->DrawerName[0], " ");
- StripOuterSpace(&fileio->FileName[0], " ");
-
- CopyString(buffer, &fileio->DiskName[0]);
- if (StringLength(&fileio->DrawerName[0]))
- {
- ConcatString(buffer, &fileio->DrawerName[0]);
- ConcatString(buffer, "/");
- }
- ConcatString(buffer, &fileio->FileName[0]);
- }
-
-
-
- /* *** AddFileIOName() ******************************************************
- *
- * NAME
- * AddFileIOName -- Add a file name to the names in a FileIOSupport
- *
- *
- * SYNOPSIS
- * AddFileIOName(FileIOSupport, FileName);
- *
- *
- * FUNCTION
- * This routine adds a file name to the list of file names currently
- * in the specified FileIOSupport structure. The next time the
- * FileIOSupport structure is used for a call to GetFileIOName(), the
- * new file name will apppear alphabetized in with the other file names.
- *
- * This routine will most often be used after a call to GetFileIOName()
- * or some other routine where the user is allowed to specify the name
- * of a file to be opened for output. If the file is opened
- * successfully, this routine will make sure that the name of the file
- * is in the FileIOSupport structure. This is important if the output
- * file has been newly created; otherwise, without calling this
- * routine, the next time the FileIOSupport structure is used the new
- * file name would not appear even though the file exists. If the name
- * is already in the list when you call AddFileIOName() then nothing
- * happens. This allows you to call AddFileIOName() without worrying
- * about duplicate name redundancy.
- *
- * Here's a typical sequence of events leading up to a call to
- * AddFileIOName():
- *
- * First, get a FileIOSupport structure:
- * fileio = GetFileIOSupport(...);
- *
- * When the user wants to write data, use GetFileIOName()
- * to provide a convenient and consistent interface to
- * the filesystem:
- * goodfile = GetFileIOName(...);
- *
- * If the user has selected a name for output (in this example,
- * goodfile will equal TRUE if the user selected a name), then
- * open the file (possibly creating it) and then call
- * AddFileIOName() to make sure the name is in the FileIOSupport
- * structure's list:
- * if (goodfile)
- * {
- * UBYTE filename[80];
- *
- * BuildFileIOPathname(fileio, &filename[0]);
- * ... open filename, write it, close it ...
- * if (filename opened successfully)
- * AddFileIOName(fileio, &filename[0]);
- * }
- *
- *
- * INPUTS
- * FileIOSupport = the address of a FileIOSupport structure
- * FileName = the address of null-terminated text that is
- * either a simple file name or a valid AmigaDOS pathname.
- *
- *
- * RESULT
- * None
- *
- *
- * SEE ALSO
- * GetFileIOName()
- * GetFileIOSupport()
- */
- VOID AddFileIOName(fileio, filename)
- struct FileIOSupport *fileio;
- UBYTE *filename;
- {
- SHORT index, i, length;
- struct Remember *remember, *oldremember;
- UBYTE *nextentry;
- struct Remember *namekey;
-
- /* Does the filename start with a volume name? If so, skip over it */
- index = IndexString(filename, ":");
- if (index >= 0) filename += index + 1;
-
- /* Does the filename start with a directory name? If so, skip over it */
- do
- {
- index = IndexString(filename, "/");
- if (index >= 0) filename += index + 1;
- }
- while (index >= 0);
-
- if (*filename == 0) return;
-
- /* Here, filename points to what is presumed to be a valid file name.
- * If it's found among the FileIOSupport's names, exit.
- * If it's not found in the list, add it.
- *
- * The current file names are stored in the fileio's Remember list.
- */
- remember = fileio->NameKey;
- oldremember = NULL;
- while (remember)
- {
- i = CompareUpperStrings(filename, remember->Memory);
- if (i < 0) goto ADD_FILENAME;
- if (i == 0) return;
- oldremember = remember;
- remember = remember->NextRemember;
- }
-
- ADD_FILENAME:
- /* Name not on list, so add it now */
- length = StringLength(filename);
-
- namekey = NULL;
- if (nextentry = AllocRemember(&namekey, length + 1 + 1, NULL))
- {
- CopyString(nextentry, filename);
- *(nextentry + length + 1) = 0;
- if (oldremember) oldremember->NextRemember = namekey;
- else fileio->NameKey = namekey;
- /* This assignment is valid whether or not remember is NULL */
- namekey->NextRemember = remember;
- fileio->NameCount++;
- }
- }
-
-
-
- /* *** ReleaseFileIO() ******************************************************
- *
- * NAME
- * ReleaseFileIO -- Release the FileIO structure and all local memory
- *
- *
- * SYNOPSIS
- * ReleaseFileIO(FileIO);
- *
- *
- * FUNCTION
- * Releases the FileIO structure by freeing all local memory attached
- * to the structure and then freeing the structure itself.
- *
- *
- * INPUTS
- * FileIO = the address of a FileIO structure
- *
- *
- * RESULT
- * None
- *
- *
- * SEE ALSO
- * GetFileIOSupport()
- */
- VOID ReleaseFileIO(fileio)
- struct FileIOSupport *fileio;
- {
- if (fileio)
- {
- FreeRemember(&fileio->VolumeKey, TRUE);
- FreeRemember(&fileio->NameKey, TRUE);
- FreeMem(fileio, sizeof(struct FileIOSupport));
- }
- }
-
-
-