home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-03-09 | 102.4 KB | 2,321 lines |
- Set your editor's TAB width to 3
-
- FileIO Requester
- User and Programmer Manual
- From the Amiga Programmer's Suite Book 1, by RJ Mical
- Copyright (C) 1987, Robert J. Mical
-
- Additional notes concerning the requester library have been added by
- Jeff Glatt who converted the original C into an assembly language library.
-
- This document describes the FileIO Requester library, both for users of
- the requester and for programmers who will utilize the library.
- The main sections of this document are:
-
- o FROM THE USER'S POINT OF VIEW
-
- o PROGRAMMER'S REFERENCE
-
- o DEMO PROGRAM NOTES
-
- o TECHNICAL REFERENCE
-
- o USING THE AMIGA PROGRAMMER'S SUITE
-
- o APPENDIX A: FileIO Library Function Calls
-
-
-
- ============================================================================
- === FROM THE USER'S POINT OF VIEW ==========================================
- ============================================================================
-
- This section presents the FileIO Requester from the user's point of view.
- This is a example of the sort of documentation that might be supplied to the
- end user of this FileIO Requester. Simply clip from here to the Programmer's
- section, and include this as a chapter in the user manual.
-
-
-
- === The FileIO Requester ========================================
-
- This program employs a file requester based upon R.J. Mical's ProSuite unit,
- though this library implementation has been modified extensively.
- The FileIO Requester allows you an easy way to select which file you want to
- use for input or output. The following describes how you go about using the
- FileIO Requester.
-
- The FileIO Requester consists of several parts:
-
- o the "Select a Name" list which allows you to choose a file name simply by
- scrolling through a list of names until you find the one you want, point-
- ing at the name and clicking the left mouse button
-
- o the OK! gadget which you use to acknowledge that the name you've chosen
- is the one that you wanted
-
- o 3 string gadgets which allow you to type in the name directly rather than
- using the "Select a Name" list to choose the file that you want
-
- o a NEXT DISK gadget which allows you to examine one disk after another
-
- o the CANCEL gadget, which you use when you've decided that you don't want
- to select a file after all
-
- The "Select a Name" list presents you with a list of file names in the current
- drawer. You use the mouse to scan easily through the list and select one of the
- filenames simply by pointing at it and clicking.
-
- The "Select a Name" feature consists of:
-
- o a box of where some of the list of file names are displayed
-
- o a slider (to the right of the box) which lets you quickly scan through
- the list of files
-
- o an up arrow gadget and a down arrow gadget (above and below the slider)
- which allow you to move through the list one filename at a time
-
-
- There are 3 types of entries in the list of file names.
-
- At the top of the list are the file names that you can choose. These names are
- listed in alphabetical order (case insensitive).
-
- At the bottom of the list there are special entries which allow you to move
- around through the drawers of a disk, much like you move around through drawers
- on the Workbench display.
-
- The entries that start with the ">>>>" characters allow you to "open" a drawer
- and examine the names of the files in that drawer. For example, when examining
- a Workbench disk, at the bottom of the list you would find an entry that looked
- like ">>>> Devs" which means that you can go into the drawer named "Devs". If
- you selected ">>>> Devs" you would see, after a short pause, a new list of file
- names: the names of the files that are in the "Devs" drawer.
-
- In the "Devs" drawer you would also find a special entry, "<<<< PRIOR DRAWER".
- If you select this entry, you will move back to the drawer that contained your
- current drawer.
-
- An alternate way to change drawers is to type the name of the drawer you want
- in the string gadget labeled "Drawer". It is located beneath the filename list.
- You select the gadget, type in the name, and hit return. If you type the name
- of a drawer which does not exist, the FileIO will send you back to the root
- directory of that disk. The length of the string that you type into the drawer
- gadget is limited to 132 characters. Since AmigaDOS limits the length of all
- file, drawer, and disk names to 30 characters, this means that you can safely
- nest drawers (one inside of another) up to four drawers deep. Beyond that, you
- should make sure that you name your drawers less than 30 characters each. The
- FileIO will not allow you to go any deeper after the drawer gadget has 132
- chars in it.
-
- Once you have a list of file names to choose from in the file name box, there's
- a slider gadget to help you scroll around through the names. The slider is to
- the right of the file names. It has a knob which you move to scroll through the
- names. The knob will be different sizes depending on the number of names in the
- file list. If the knob is small, this means that you can see only a small
- number of the total file names. The smaller the knob, the more names there are
- to see. On the other hand, if you can see all the names in the list, the knob
- will fill up the entire slider and you won't be able to move it.
-
- To view the file names, you "grab" the slider's knob and move it up and down.
- You grab the knob by pointing at it and pressing and HOLDING the left mouse
- button. When you have grabbed the knob, you can move the pointer and scan
- quickly through the list of file names.
-
- Also, you can view the list of names one page at a time by clicking to either
- side (but not on) the slider's knob. If you want fine control of your movement
- through the file list, the up and down arrows let you adjust the list of names
- one name at a time. If you hold the mouse button down while on top of either
- arrow, the filenames will scroll in that direction. When you release the
- button, scrolling stops, but if instead you move off the arrow before releas-
- ing, the scrolling continues. Auto-scroll will continue until you click on a
- scrolling filename, or until the end of the list is reached.
-
- Once you have found the file name that you want to choose, you select it by
- pointing at it and clicking. When you do this, the name will be highlighted
- and it will appear in a box labeled "Name" beneath the list. When you've
- decided that this is really the name you wanted to choose, click on the OK!
- gadget. Another way to tell the program that you're sure you want to select
- a certain file name is by double-clicking on the file name in the same way
- that you double-click on a Workbench icon. Double-clicking is exactly the
- same as selecting a name and then OK!
-
- If you don't want to use the "Select a Name" feature, you can select a name
- by clicking on the string gadget labeled "Name", typing the desired filename,
- and then hitting return or clicking on the OK! gadget. Hitting return after
- typing the name you want is the same as selecting OK! You can select and type
- into the string gadgets at any time. You don't have to wait for the wait
- pointer to change before you hit return! If you type in the name of a disk that
- is not mounted, and then refuse to insert it into the drive when AmigaDOS asks
- you for it, the FileIO switches to another disk that is mounted (if another
- floppy exists).
-
- To view the files of a different disk, select the NEXT DISK gadget. When you
- do, the name of the next disk is displayed in the Disk string gadget and the
- disk is then searched. If this disk isn't the one you wanted, you can press
- NEXT DISK again even though you may be seeing the wait pointer. You can press
- NEXT DISK quickly as many times as you want until you see the name of the disk
- you want in the Disk gadget. If you prefer, you can also type the name of the
- disk you want directly into the Disk string gadget. If the disk you want to
- examine is not in the drive, you may remove the disk that the requester has
- last examined (after the light goes out of course), and insert the desired disk
- in that drive. Now wait for the requester to automatically update its display.
- After inserting a disk, the requester will automatically redraw the list.
- Alternately, you may select a new disk by clicking the RIGHT MOUSE button.
- The filenames will be replaced by a list of all the mounted volumes (or
- devices). The name of the disk that you are currently examining will be
- highlighted. You can scroll through this list of disk names using the slider.
- When you see the disk name that you would like to examine, click the LEFT
- MOUSE button on it. The FileIO will then display the contents of that disk.
- Note that all of your logical assigns are also displayed (i.e. LIBS, FONTS,
- etc.) If you wish to only see the actual disk names, press function key #5
- while the requester is open.
-
- You might notice that the ZZZ-cloud wait pointer looks a little different
- from the ones you're used to on the Amiga. The FileIO Requester's ZZZ-cloud
- pointer has a small tab at the top left which allows you to continue pointing
- and making selections even though the ZZZ-cloud is displayed. The FileIO
- Requester's ZZZ-cloud tells you that it's working, but it doesn't make you
- wait.
-
- You might notice also that the file names start appearing one by one
- alphabetically in the list. You can select one of these names even before all
- of the names have been added to the list, although this can be a bit tricky as
- they move around a lot. While the list is being built, you can use the slider
- to look at what names have already been added. If you see the name that you
- want to select, you can stop the building of the file name list by clicking on
- a spot inside the requester but outside of all of the gadgets. For instance, if
- you click above (but not on) the OK! gadget, this will stop the list from being
- constructed. Then you can select the name you want as usual. To restart the
- building of the file name list, click on either the Drawer or Disk string
- gadget and hit return. You can also stop the display of filenames temporarily
- by grabbing and holding the scroll gadget. When you release, the display will
- continue.
-
- For some reason, the requester may not be able to open. Maybe another
- program is already displaying it. Only one program can be displaying it at a
- time. Or perhaps you have used up too much memory. In either case, instead
- of a requester, you will see this prompt in the title bar of the window.
-
- Filename >
-
- This will be followed by a cursor and whatever filename you last chose with
- the requester. You must now type in the complete name (including the drive and
- drawer names) as you would in the CLI. For example,
-
- Extras:BasicDemos/ConvertFD
-
- If the window is not full size, you should move it to the upper left corner
- of the monitor display, and resize it to fully open. Then press any cursor key
- to redisplay the cursor. If there was no previous filename, then you will see
- the ":" current directory sign. Move the cursor past this and type in the
- filename that you wish to save or load if it is on the current disk. Otherwise,
- you need to type the name of the disk upon which the file can be found. The
- disk name goes in front of the ":", and the drawers and filename go after the
- ":". (If the file is on the current disk, and in the current drawer, you only
- need to type the filename. Otherwise, you must specify which disk and drawer
- you really want.) If the filename that is initially displayed is the one that
- you want, simply press RETURN.
- You can use the cursor keys to move about in the filename, deleting charac-
- ters with the delete or backspace keys. If there is any text extending beyond
- the border of the window, you can scroll to it using the cursor keys.
- Holding the ALT key while pressing the cursor keys will move to the
- beginning and end of the typed filename.
- When you are satisfied with your choice, hit RETURN. Otherwise, hit the
- escape key to cancel.
-
- You have the facility to "customize" the requester for each application.
- After the requester comes up, the function keys have the following purposes:
-
- F1 - Operates the same as selecting the Next Disk gadget.
- F2 - Toggles between using the volume name or the device name of the floppy.
- For example, if you place your WorkBench disk in the internal drive
- and you are using volume names, "WorkBench 1.3:" will appear for the
- Disk name. If using device names, "DF0:" will appear instead.
- F3 - Any filename that ends in ".info" will not be displayed. To disable
- this feature, select F3 again.
- F4 - Only displays filenames that end with a phrase that you provide.
- You will be prompted to enter a string in the title bar of the window.
- If for example, you typed .library, then the requester would display
- all drawers, but only those files that end with .library. The word
- need not be an extension. You could also specify that only files that
- end with the word, picture, be displayed. To disable this feature,
- select F4 again. The program that you are using must support this
- feature for it to work. If the program doesn't support it, F4 will do
- nothing. When you type any string into the NAME gadget, the extention
- will automatically be added.
- F5 - This toggles ON/OFF the facility for displaying the logical assigns
- in your system. A logical assign is the C: directory for example. This
- directory might be on your hard drive DH0:. If you toggle the assigns
- OFF, then you'll just see DH0: in the list of devices when you click
- the right mouse button. If you toggle assigns ON, then you'll see both
- C: and DH0: in the list. Remember that you can also choose to use the
- volume or device names (as toggled by F2).
- F6 - This will cause the requester not to initially reconstruct the filename
- list on subsequent uses. The advantage is that the next time the req-
- uester comes up, the names will appear immediately. The disadvantage is
- that if you save a file, it will not appear in the list until you turn
- this feature back on (momentarily anyway). Turn it on/off by pressing F6.
- F7 - WorkBench matching ON/OFF. If ON, this only displays those names that
- end in .info (just like WorkBench does). Also, a prompt asks you whether
- you want only those names that are TOOLS, PROJECTS, or any kind. An example
- of a TOOL is a program that you can run, like NotePad. An example of a
- PROJECT is a data file, like a note you might write using NotePad. The
- names of disks are never displayed in the filename list.
- F8 - Alphabetize feature ON/OFF. When ON, the filenames are alphabetized in
- the display. When OFF, newer files are listed at the top of the display.
- F9 - Same as the CANCEL gadget.
- F10 - Same as the OK! gadget.
-
- When you customize the requester, it only affects that one application, so
- different programs can have different "customized" requesters.
-
-
-
- ============================================================================
- === PROGRAMMER'S REFERENCE =================================================
- ============================================================================
-
- This section is for the programmer who wants to use the FileIO Requester
- library routines in her or his program.
-
- The Workbench names for DOS objects have been used in the FileIO Requester,
- and are used throughout this document for simplicity. For your reference, a
- directory is referred to as a "drawer" and volumes, or DOS filesystem devices,
- are referred to as "disks".
-
- These are the subsections of this section:
-
- o Basic Operation
-
- o DoFileIO() is non-reentrant
-
- o Interpreting the return values of DoFileIO()
-
- o Internal Error Handling
-
- o Quick Display (NO_CARE_REDRAW)
-
- o Workbench-style Filename Operations
-
- o .Info File Suppression
-
- o Filtering by Extension
-
- o No Icon (.info) files
-
- o FileIO Flags
-
- o RAM Disk Bug
-
- o Free Disk Space
-
- o Procedure for Opening and Using the FileIO Requester library
-
- o Using the requester to display lists of strings
-
- o Filename and Custom Lists
-
- o Multiple Filenames
-
- o Installing Custom Handlers
-
-
- ========================== Basic Operation ============================
-
- The FileIO routines base all of their work on a data structure called the
- FileIO structure. You are allocated one of these structures when you call the
- GetFileIO() routine. The structure is initialized with reasonable default
- values for you. Conversely, you can declare and pre-initialize a FileIO
- structure as long as all fields are set to zero or an appropriate value. At
- the very least, you must set the FileIO's Buffer field to point to where you
- want string input stored, and initialize the DrawMode, PenA, and PenB fields
- to desired values. The buffer size should be > = 202 bytes.
-
- The FileIO structure is used when calling the DoFileIO() and DoFileIOWindow()
- routines, which are the routines that actually present the requester to the
- user and get the user's filename selection. DoFileIOWindow() is the same as
- DoFileIO() except that the former opens a window for the requester. With
- DoFileIO(), you must already have a window open.
-
- There are several flags and data fields in the FileIO structure that you may
- choose to initialize before calling DoFileIO(). By setting or clearing these
- flags, you define how information is to be presented to the user. These flags
- are described below in "FileIO Flags". Also, the user can change these flags
- for each FileIO via the function keys.
-
- The DoFileIO() function returns one of 2 values:
-
- 1). The address of the buffer where the complete pathname (disk, drawer,
- and filename as one, NULL-terminated string) has been stored. This
- buffer will be the one that you supply in the FileIO's buffer field.
- 2). A -1 if the user selected the cancel gadget.
-
- The DoFileIOWindow() function may return this additional value:
-
- 3). A zero if the window didn't open.
-
- You can call these routines any number of times with the same FileIO structure.
- Also, your program can have more than one FileIO structure at a time. An
- example of why you would want more than one FileIO structure: you might want
- to have separate structures for getting input filenames and output filenames
- from the user. Another example: you might have one structure for letting the
- user select text files and another for the selection of graphics files each
- with different options/features. Also, there are some lib routines that do not
- deal with disk file IO, but use the FileIO structure nonetheless and you might
- want a FileIO with a special string buffer for these routines.
-
- Finally, when you're finished with your FileIO structure (usually not until
- your program is terminating) then you call ReleaseFileIO() to deallocate all
- the resources that it's accumulated. If the FileIO was obtained via
- GetFileIO(), this routine also frees it for you. If you use multiple FileIOs,
- when you go to free them, free the FileIO that you first used for disk IO last.
- (ie The first FileIO to be used with DoFileIO, DoFileIOWindow, ParseString,
- ParentPath, or ParentLock, without the SPECIAL_REQ flag set).
-
-
- ====================== DoFileIO() is non-reentrant ========================
-
- The DoFileIO() routine is non-reentrant. For the sake of memory efficiency,
- it uses global data and variables rather than creating local copies of these
- for each caller. What this means is that only 1 task can use the library
- functions DoFileIO() or DoFileIOWindow() at a time, although all other lib
- functions are re-entrant. If you attempt to call DoFileIO() or DoFileIOWindow()
- while another task is using it, the library will automatically prompt the
- user to type in the complete filename, instead of displaying the requester.
- The area where the user types in the filename is in the title bar of the
- window where the requester opened. The prompt
-
- Filename >
-
- will be displayed in the window's titlebar, along with a cursor. Several line
- editing features are supported including cursor key movement (with the ability
- to insert characters), backspace, delete, alt-right and alt-left cursor to the
- start and end of the string, and escape. The window's title is later restored.
- In fact, this feature of being able to use the title bar for getting user input
- can be used with your own prompts. It is a handy alternative to having a string
- gadget (which takes up window space and also requires allocating several
- structures), plus allows for displaying custom prompts. The user can scroll to
- any text beyond the boundaries of the window title bar borders.
- Note that many tasks can open the library simultaneously, but only 1 can be
- displaying the FileIO requester at a given moment.
- This redirection to entering the filename via the title bar is COMPLETELY
- INVISIBLE to your application. Upon return from DoFileIO() or DoFileIOWindow()
- you will receive one of the 2 (or 3) previously described return values.
-
-
- ========== Interpreting the return values of DoFileIO() ================
-
- As mentioned before, there are 3 possible return values from DoFileIOWindow
- and 2 returns from DoFileIO. If there is not enough memory for the window to
- open with DoFileIOWindow(), then the return value is 0 and the FileIO's Errno
- field = ERR_WINDOW. If this happens, you will have to find another way to get
- the filename. If you already have a window open, use DoFileIO(). This routine
- will never fail. Alternately, you might have the user type the path as he would
- from the CLI, and call ParseString() to put it in the FileIO.
- If the user selects the CANCEL gadget, (or hits ESCAPE when entering the
- filename in the titlebar, or RETURN with no chars input), both routines will
- return -1.
- In all other cases, the address of the FileIO's Buffer will be returned.
- This indicates that the user selected OK, or typed something in the string
- gadgets or title bar. This does not mean that the filename is valid for your
- purpose though. Let's assume that you called DoFileIO() from a load routine.
- Naturally, you want the user to select an existing file to load, but let's say
- that he types a non-existant file in the Name gadget or just selects a disk or
- drawer without eventually choosing a file before selecting OK. You can deter-
- mine what the user did by examining 2 FileIO fields. The FileIO's Filename
- buffer contains just the filename portion of the complete path (separated from
- all the drawer and disk names). If this buffer is NULL, then the user did not
- select a filename. If the buffer is not NULL, then he either selected a file-
- name, or typed one in. If he typed one in, how do you know if the filename
- exists? The FileIO's FileSize field will be 0 if the filename doesn't exist (or
- couldn't be examined because the user refused to mount the file's disk). In
- this case, you would abort the load. If the FileSize is not 0, then the file
- exists and this is how large it is in bytes. In conclusion, here are the steps
- you should take for a load routine:
-
- 1). Call DoFileIO() with the FileIO's Buffer set to the address of your path
- buffer, and the DrawMode, PenA, and PenB fields initialized.
- 2). Examine the return. If -1, then CANCEL. (If 0 for DoFileIOWindow, then get
- the filename another way, via DoFileIO perhaps).
- 3). Check the FileIO's filename buffer for NULL. If NULL, then abort load
- posting "This is not a loadable file."
- 4). Check the FileIO's FileSize field. If zero, post "File doesn't exist."
- 5). Otherwise, use the path buffer to open the file for reading.
-
- Here are the steps you should take for a save routine:
-
- 1). Same as load routine step 1
- 2). Same as load routine step 2
- 3). Check the filename buffer for NULL. If NULL, then abort posting "Did not
- supply a filename."
- 4). Check the FileSize field. If it's not 0, then the user must have selected
- a filename that already exists on the chosen disk and in the specified
- drawer. Post "File exists. Should I overwrite it?" Get a yes or no response
- from the user to continue or abort.
- 5). Otherwise, use the path buffer to open the file for writing.
-
-
- ======================== Internal Error Handling ==========================
-
- The requester is set up so that if the user types in a non-existant disk
- name or refuses to mount the chosen disk, the req will default to any other
- mounted disk. If no disks mounted, then the default FILEIO_DISKNAME is ":".
- For example, assume that the user types "Leroy:" in the disk string gadget,
- but the disk is not in any drive. AmigaDOS will prompt for that disk. If the
- user then CANCELs the system prompt, the FileIO req will display the contents
- of some other disk that is mounted, adjusting the string gadgets accordingly.
- In the case where no disks are mounted, the pathname buffer that is returned
- will not contain any disk name.
- If the user types a drawer name that is not in the current dir level, the
- req will knock him back to the root of the current dir. For example, assume
- that the user is looking inside of a drawer called "TireBiter". There is no
- drawer called "George" inside here, but the user types this in the drawer
- string gadget nonetheless. The requester will clear ALL the drawer names,
- defaulting to the root of the disk.
- The library will not return non-existant disk or drawer names. If you needed
- the requester to do this though (maybe you want to pass the path buffer to
- CreateDir) then the user should type the "new" drawer name by itself in the
- Name gadget. Conversely he could enter the string via the titlebar like so:
-
- WorkBench:Demos/Blort
-
- where you simply treat Blort as a dir name instead of a filename. The lib will
- copy Blort to the FileIO's Filename field nonetheless. Just check the FileSize
- field to make sure that there isn't a file already named this.
- If there is some error in obtaining the disk name and it defaults to ":",
- then the returned pathname will not have a drawer name prepended to it. For
- example, say the user typed "df0:" in the drawer string gadget, but the drive
- was empty. The requester will automatically default to another mounted disk/
- device, etc, until one can be examined, or finally ":" is used. If the user
- then types "Papoon" in the Filename Gadget, the returned path will be:
-
- Papoon
-
- which will be stored in the FileIO's Filename buffer if its a Filename, or the
- FileIO's Drawername buffer if it's a drawer. If it is a Filename that exists in
- the current dir, the FileSize will be its size in bytes.
-
-
- ===================== Quick Display (NO_CARE_REDRAW) =====================
-
- The data in the FileIO structure often remains valid between calls to
- DoFileIO(), so with subsequent calls a flag has been provided to avoid
- reconstructing the filename list. This allows the requester to appear very
- quickly because the usually-lengthy process of accessing the disk is avoided.
- Other times, it may be necessary to have the requester reconstruct its list
- of filenames (i.e. when a disk is changed or a file created/deleted by an
- application which does not communicate with the FileIO requester). Perhaps,
- as in a save routine, it may not be important to show the user what other
- recent files are on the disk as long as proper file protection is provided.
- The library uses the NO_CARE_REDRAW flag to discern whether to reconstruct
- the list, or simply to use the FileIO's previous names. If you set this flag,
- the old list is simply redrawn. Once you set this flag, the list will not
- be reconstructed on subsequent calls until you explicitly clear NO_CARE_REDRAW.
- (i.e. you always get the same, non-updated list unless the user changes dirs
- or disables the feature himself via the Function keys).
- When GetFileIO() creates a FileIO structure for you, this flag is cleared
- to specify that the structure doesn't contain an updated list of filenames.
- Thus the first call to DoFileIO() causes the filename list to be constructed.
- After the call to DoFileIO() is the time to set the flag. You must do a bit
- of work if you wish to make use of this feature. You are obliged to watch
- for IDCMP events of class DISKINSERTED and to clear the NO_CARE_REDRAW flag
- in any of your FileIO structures whenever you see this event. The DISKINSERTED
- event occurs when the user has switched around the disks. When the user has
- changed disks, you can't be sure that your FileIO's filename list is still
- valid, so as a courtesy to the user you must cause the filename list to be
- reconstructed. In the case that some disk activity occurs in a program that
- doesn't use the FileIO library, you will never know about this activity. Also,
- if the disk is changed or files are created/deleted by some other task using
- the library, you will have no way to determine this. For these reasons, you may
- elect to forgo this feature entirely. If you don't use this feature, you need
- not bother looking for DISKINSERTED events. Because the library has been
- completely rewritten in optimized assembly, it doesn't take too long for the
- requester to construct its list anew. Also, the user can toggle this feature
- ON/OFF using function key 6 if he wants. The example applications don't use
- this feature. You can use the FileIO Requester library to get the name of a
- file to be used for output. If you do, and the specified file doesn't currently
- exist, AmigaDOS will create it anew when you open it (mode NEWFILE). From the
- FileIO Requester point of view, this means that a file now exists that isn't in
- your FileIO list. To get the name in the list, clear the NO_CARE_REDRAW (if it
- was SET). The next time that the FileIO structure is used for a call to
- DoFileIO() or DoFileIOWindow(), the new file name will appear alphabetized in
- with the other file names. Once again, this is not applicable if you don't ever
- set NO_CARE_REDRAW.
- If you have more than one FileIO structure, remember that you must clear
- the NO_CARE_REDRAW flag in all of them whenever you see Intuition's
- DISKINSERTED IDCMP event class (if you're using the NO_CARE_REDRAW feature).
- Also, regarding new disks, there's an extra procedure that you must follow.
- If the user changes the disk while you've called DoFileIO() or DoFileIOWindow(),
- you won't actually see a DISKINSERTED event (as the event will have been
- processed by the library before control is returned to you). So how will you
- know to clear the NO_CARE_REDRAW flag in your other structures? Well, you'll
- need to install a custom handler for DISKINSERTED events (see the section
- on Custom Handlers), and within this function you should clear the
- NO_CARE_REDRAW flag in all of your FileIO structures. This assures that when
- you call DoFileIO() with any of your other support structures, the filename
- lists will be reconstructed, as they should. Please note that all this needs
- to be done ONLY IF YOU'RE SETTING NO_CARE_REDRAW.
-
-
- ================= Workbench-style Filename Operations ====================
-
- You can have file names appear in the FileIO Requester using the same rules
- that govern how files appear on the Workbench display, by using the Workbench
- .info file mechanism.
-
- To attempt to match Workbench patterns, you must set the WBENCH_MATCH flag
- in your FileIO structure, as described below.
-
- The Workbench .info file mechanism is a detailed topic that will not be delved
- into here. Please read the Amiga ROM Kernel Manual for a description of the
- Workbench operation and data types. What follows is a cursory description of
- the Workbench technique, which is described only well enough to explain how you
- can interact with it via your FileIO structure.
-
- The Workbench program examines the directory of a disk and displays icons for
- the files it finds that end with a ".info" suffix (hereafter referred to as
- .info files). The file names displayed beneath the icons have the ".info"
- suffix removed. The Workbench .info files contain information regarding what
- type of data is contained in the file (executable program, project data, etc).
-
- You can choose to have only .info files displayed to the user (with the ".info"
- removed) in the same way that the Workbench does. You get this by setting the
- WBENCH_MATCH flag. Any executables without icons (.info files) will not be
- displayed. The same is true of drawers.
-
- If you wish, you can further filter the names that appear. There are two
- techniques that you can employ for filtering which file names will be added
- to the list: you can ask for only those files that match a particular
- Workbench object type and only those files that match a particular tool type.
-
- You elect to match the object type by setting the MATCH_OBJECTTYPE flag in
- your FileIO structure. The object types typically of interest are WBTOOL and
- WBPROJECT. By selecting one of these 2 types, your filename list will consist
- only of executable files or data files respectively (except that all .info
- drawer names are always displayed). If this is confusing, refer to the ROM
- Kernel manual for a discussion of object types.
-
- You can also request to match a Workbench tool type. By matching tool types,
- you can, for instance, have your file list display only those data files that
- were created by a specific application. See the section entitled "The
- ToolTypes Array" in the Workbench chapter of the ROM Kernel manual for a
- description of how tool types work. You elect to match tool types by placing
- a pointer to the ToolTypes text in the ToolTypes field of your FileIO
- structure. If this field is left zero, then the TOOLTYPES will be ignored.
-
-
- ====================== .Info File Suppression =========================
-
- Setting the INFO_SUPPRESS flag is exactly the opposite of Workbench
- matching. All files that end in .info will be ignored, and are not displayed.
- This is handy if the user doesn't have a .info file to go with every file
- that he wishes to peruse. With WB MATCH, those files would not be displayed.
- With INFO_SUPPRESS set, they would be displayed but no .info files would
- clutter the display. This gives the impression of WB MATCH while enabling
- files without icons to also be seen. On the down side, that means that the
- user will see ALL files without icons including those that are best left
- alone (i.e. translator.library). All drawers are displayed regardless. When
- the user makes his selection, the .info is not added to the pathname.
-
-
- ==================== Filtering by Extension =====================
-
- Sometimes, you may have an application that only wants to see filenames
- that end with a certain string (i.e. ".iff"). You can specify an extension
- by storing the address of this string in the Extension field of the
- FileIO. Also, you need to specify the length (don't count the terminating
- NULL byte) and store this value in the ExtSize field. For the preceding
- example, the length would be 4 (counting the .). Finally, you must set the
- EXTENSION_MATCH flag. If the EXTENSION_MATCH flag is clear, the extension
- fields will be ignored. In this way, you can quickly enable and disable the
- feature with the one flag. Only the files that END with this extension (case
- insensitive) will be displayed. Incidentally, this need not be a real exten-
- sion. You can match any ending at all. For example, you could only display
- those files that end with the string "picture". In this case, the length
- would be 7. If you set the EXTENSION_MATCH flag, then clear the INFO_SUPPRESS
- flag. Because only those files that end in your specified extension are seen,
- .info files won't be displayed anyway (unless your specified extension is
- ".info" in which case you'll get nothing but .info files. An icon editor,
- maybe?) All drawers will be displayed regardless. Please note that the
- extension string that you supply MUST HAVE ALL LETTERS IN LOWER CASE.
- In order for the user to take advantage of this feature via the F4 key,
- you must set up the FileIO for it. First you must supply a buffer for the
- user's typed extension. Place the address in the FileIO's Extension field.
- The buffer must be at least 20 bytes long. Don't enable the EXTENSION_MATCH
- flag.
- If you don't want the user to take advantage of extension match, then
- clear the EXTENSION_MATCH flag AND zero the Extension pointer field. There
- is the possibility that you may have supplied an Extension to be matched
- and while the requester was displayed, the user changed the match string.
- For this reason, the buffer should always be at least 20 bytes if you use
- this feature. Also, don't assume that the returned filename is definitely
- ending with the extension you initially passed. If the user changed the
- match string, it won't be the same extension. Also, you should re-initialize
- your extension buffer string each time before you call DoFileIO(). The
- returned pathname and FILEIO_FILENAME buffer have the extension added.
- For SPECIAL_REQ, the extention is ignored.
-
-
- ========================== FileIO Flags ===========================
-
- Remember that the user can always adjust these himself with the function
- keys. For this reason, you might simply go with the defaults.
-
- NO_CARE_REDRAW
- Setting this means that the filename data is NOT to be reconstructed before
- initially drawing the requester. The previous list is instead redrawn.
-
- USE_DEVICE_NAMES
- When you leave this flag CLEAR, the AmigaDOS volume names will be used for
- the disk names in the requester. If you SET this flag, the device names
- will be used instead. The default is to follow the Workbench convention and
- use volume names.
-
- EXCLUDE_ASSIGNS
- If set, then when the list of device or volume names is displayed, no
- logical assigns appear in the list. Only the actual disk device names
- appear. The default is to allow logical assignments. Note that when you
- pre-initialize the fileIO's DiskName[], you should set the USE_DEVICE_NAMES
- and EXCLUDE_ASSIGNS to the desired values before calling DoFileIO(). For
- example, if you wish the file requester to open up displaying all of the
- files on DF0:, then set USE_DEVICE_NAMES, copy the string "df0:" into
- the DiskName[] buffer, clear the Drawer and FileName[], and call DoFileIO.
- If you want to display all the files in the LIBS: drawer, make sure that
- EXCLUDE_ASSIGNS is clear, copy "libs:" into the DiskName[], clear the
- Drawer and Filenames, and call DoFileIO. (USE_DEVICE_NAMES won't matter
- since logical assigns are added whether device or volumes names are
- displayed.)
-
- DOUBLECLICK_OFF
- Normally, the user can double-click on a filename to select it. You may
- choose to disable this feature, for instance, when you want the user to be
- very certain about the filename selection (perhaps if the file is about to
- be destroyed, or something equally drastic). To disable double-clicking,
- set the DOUBLECLICK_OFF flag. Then the user will have to explicitly select
- OK! or type the filename and hit return for the selection to be made.
- Affects SPECIAL_REQ
-
- WBENCH_MATCH
- You set this flag to specify that you want Workbench-style .info file logic
- to be used when constructing the filename list. This flag is cleared when
- your FileIO structure is first created.
-
- MATCH_OBJECTTYPE
- When you set this flag (and the WBENCH_MATCH flag), the MatchType field
- of your FileIO structure will be compared with the do_Type field of the
- .info file's DiskObject structure. If they match, the file will be
- displayed. The WBENCH_MATCH flag must also be set.
-
- MULTIPLE_FILES
- Set this flag for multiple filename selection. All selections must be in
- the same directory. You must examine the EntryFlags (selected bit) of each
- Entry structure to determine which files were selected. This flag cannot be
- changed by the user unless an application allows him to do so. Affects
- SPECIAL_REQ
-
- INFO_SUPPRESS
- All .info files are suppressed from the display if you SET this.
-
- EXTENSION_MATCH
- Filters filenames that end with a certain string if you SET this.
-
- CUSTOM_HANDLERS
- Allows adding custom handlers to the internal library handlers of GADGETUP,
- GADGETDOWN, MOUSEMOVE, RAWKEY, DISKINSERTED, and initial REQSET. You can
- supply an additional handler for any and all of these events that will be
- invoked along with the internal library handler (or in place of it). Once
- you call DoFileIO(), the handlers will be installed and active until the
- requester ends. Set or Clear this flag before calling DoFileIO(). If the
- requester can't open or is being used by another task, the user will get
- titlebar entry, and your handlers will be ignored. Cannot be changed by the
- user. Affects SPECIAL_REQ
-
- NO_ALPHA
- When clear, the filenames are alphabetized in the display. When SET, newer
- files are listed at the top of the display. Affects SPECIAL_REQ
-
- SPECIAL_REQ
- Allows using the FileIO requester to display lists of strings not relating
- to disk drive operations. Cannot be changed by the user.
-
-
- =========================== RAM Disk Bug ===============================
-
- There seems to be a bug in 1.2 AmigaDOS. For some reason, whenever one attempts
- to get an AmigaDOS Lock on the volume named "RAM DISK:" a software error
- occurs. The problem doesn't necessarily lie in AmigaDOS, but the truth is that
- the error occurs with little provocation of AmigaDOS (for instance:
-
- dir "RAM DISK:"
-
- can and does crash the Amiga). Though 1.3 resolves this bug, the FileIO code
- provides a work-around for 1.2 by changing "RAM DISK:" to "RAM:" which locks
- successfully and does not crash the machine. This solution has a problem: if
- the user has given the name "RAM DISK:" to some non-RAM: disk (such as a
- floppy) then this fix will fail and the floppy named "RAM DISK:" wouldn't be
- seen. This isn't too bad of a problem, because if the user has been silly
- enough to name a floppy "RAM DISK:" the user is probably experiencing lots of
- other problems already and this will provide just one more reason why one
- shouldn't name a floppy "RAM DISK:" don'cha know.
-
-
- ========================== Free Disk Space ==============================
-
- The FileIO's FREEBYTES field indicates how many free bytes remain on the
- disk that the user has chosen. This is useful for a save routine. After all,
- you wouldn't want to start saving a 230K file to a disc that only has 229K
- free. Unfortunately, AmigaDOG always says that the RAM DISK: has 0 bytes
- free. Actually, it has as many bytes free as mem that is available. Whenever
- the user selects RAM: or RAM DISK:, the FileIO's FREEBYTES is set to
- 0xFFFFFFFF (the largest size possible). If you encounter this condition, you
- may wish to use Exec's AvailMem to determine if you can do the save.
-
-
- ========== Procedure for Using the FileIO Requester library ===========
-
- This section presents a step-by-step procedure for utilizing the FileIO
- Requester library with your own program.
-
- Copy the requester.library into the libs directory of your boot disk.
-
- You have to include FileIO.h in every C module that refers to your FileIO
- structure.
-
- #include "FileIO.h"
-
- For assembly language users, (WOW! We hardly ever get real support for
- programming on the Amiga), include FileIO.i
-
- Open the library via a call to exec's OpenLibrary and store the pointer at
- a variable called RequesterBase (MUST BE CALLED THIS FOR C PROGRAMMERS).
-
- if (!(RequesterBase = (APTR) OpenLibrary("requester.library", 1L)))
- exit(0);
-
- Declare a pointer to a FileIO structure (initialized to 0), and then fill that
- pointer with the address of one of the structures.
-
- struct FileIO *myFileIO = 0;
-
- myFileIO = GetFileIO();
-
- <<<< IF USING NO_CARE_REDRAW >>>>>
- Your NewWindow structure should have the DISKINSERTED flag set along with your
- other IDCMP flags. Whenever you receive a DISKINSERTED event, you should clear
- the NO_CARE_REDRAW flag (if SET) in every FileIO structure you control. The
- following code could be added to the case switch where you handle IDCMP events.
-
- switch (imessageclass) /* the class field from an Intui Message */
- {
- case DISKINSERTED:
- /* You should clear the NO_CARE_REDRAW flag whenever you detect that
- a new disk was inserted.
- */
- if (myFileIO)
- ClearFlag(myFileIO->Flags, NO_CARE_REDRAW);
- break;
- }
-
- Alternately, you may elect to leave NO_CARE_REDRAW clear in which case the
- requester display will be updated every time it is used and you won't need
- to bother with receiving DISKINSERTED events.
-
- Set the FileIO's Buffer field to the address of a buffer that you have
- allocated. This is where the complete path will be constructed for you. (i.e
- Disk:drawer1/drawer2...etc/filename ) Also initialize the FileIO's DrawMode,
- PenA, and PenB. You might also want to set the FileIO's X and Y fields where
- the requester will open within your window (relative upper left) if you intend
- to use DoFileIO().
-
- Initially, you might want to set the FileIO to open in the directory from
- where your application was invoked. You do this by passing a 0 to ParentLock().
- Alternately, if you expect to receive an argument filename from the user (via
- Workbench or the CLI), you would use ParentPath() to set up the FileIO to that
- filename and complete path.
-
- When you want to present the FileIO Requester to the user, call DoFileIO() or
- DoFileIOWindow(). If these routines return the address of the passed buffer
- where you want the full path name to be stored, the user did not cancel the
- operation, nor was there an error in opening the window (for DoFileIOWindow
- only). A -1 and 0 will be returned respectively for those two error conditions.
- The following code is an example of presenting the FileIO Requester to the
- user and then reacting to the result.
-
- /* This set-up need only be done once, though you can change them later */
- UBYTE buffer[204];
- myFileIO->Buffer = buffer;
- myFileIO->DrawMode = JAM2;
- myFileIO->PenA = 1;
- myFileIO->PenB = 0;
-
- /* ================================================================ */
- if (myFileIO)
- {
- result = (DoFileIO(myFileIO, window));
- if (result==&buffer[0])
- {
- /* Here, do something like read or write the file */
- if (writefile)
- {
- if (myFileIO->FileName[0])
- {
- if (!myFileIO->FileSize)
- {
- /* Open the file (MODE_NEWFILE) */
- /* Write the file */
- /* Close the file */
- }
- /* Else tell the user that he's about to overwrite */
- }
- /* Error in entering filename (i.e. did not enter a filename) */
- }
- if (readfile)
- {
- if (myFileIO->FileName[0])
- {
- if (myFileIO->FileSize)
- {
- /* Open the file (MODE_OLDFILE) */
- /* Read the file */
- /* Close the file */
- }
- /* Otherwise, tell the user that the file doesn't exist */
- }
- /* Not a loadable file */
- }
- }
- if (result==0)
- {
- /* This only happens if DoFileIOWindow() bombs. Call DoFileIO() */
- }
- /* Otherwise, CANCEL must have been selected. Never mind. */
- }
-
- Finally, when you're done with your FileIO structure (usually when your program
- is exiting), you can free up the structure and its resources with a simple call
- to ReleaseFileIO(), like this:
-
- if( RequesterBase ) ReleaseFileIO(myFileIO);
-
- Also, you need to close the library upon exit.
-
- if( RequesterBase ) CloseLibrary( RequesterBase );
-
- When you link your C program, you'll need to assemble and link with
- FileInterface.asm. This is the usual assembly poot needed by C programs in
- order to call assembly language libraries. You want efficiency, write in
- assembly. Assembly programmers can simply use the _LVO library offsets as
- provided in FileIO.i. See the example applications for details.
-
- ONE FINAL NOTE: The lib needs to trap RIGHT MOUSE buttons for displaying
- the list of disk names. When exiting, the lib clears the RMBTRAP bit of
- your window's flags, so if you had it set before calling DoFileIO(), then
- you'll have to set it again upon return by going to the Flags field of
- your window structure and setting bit #16.
-
-
- ============ Using the requester to display lists of strings =============
-
- There may be times when you need to display a list of strings in a requester
- so that a user can scroll around the list via the mouse and choose an item in
- the list. The amount of code and IDCMP hassle of constructing such a requester
- can certainly be considerable, especially if you want to include a Prop scroll
- bar, scroll arrows, a string gadget, CANCEL and OK gadgets, etc.
- The FileIO requester library has a feature whereby you can use the lib's
- requester to display your list of strings. The lib handles all user inter-
- action, list display, and IDCMP. You simply set the SPECIAL_REQ flag of the
- FileIO before calling DoFileIO() or DoFileIOWindow() and the requester will
- display your list of strings. The requester is no longer a disk I/O tool. In
- fact, the Disk and Drawer string gadgets are removed from the display, and the
- NextDisk gadget no longer has anything to do with switching dirs.
- The user can employ the Prop and Arrow gadgets (with auto-scroll) to scroll
- through the list of strings. The size of the Prop's knob reflects the per-
- centage of visible strings just like in the disk I/O version.
- The user can click on any string to make it the currently selected one, and
- it will be highlighted and copied to a string gadget below. Or the user can
- type his selection directly into the string gadget. A double-click on a string
- will end the requester with that string as the chosen one.
- The chosen string will be copied to the FileIO's Filename buffer. Note that
- with SPECIAL_REQ, you do not need a Pathname buffer. (In fact, the FileIO's
- BUFFER field will be overwritten.)
- With SPECIAL_REQ, DoFileIO() or DoFileIOWindow will return the following:
-
- 1). A -1 if the user selected the CANCEL gadget.
- 2). A -2 if the library was being used by another task (i.e. the same
- note about non-reentrant code applies here).
- 3). A 0 if there is a problem opening the FileIO window (if DoFileIOWindow
- doesn't open, or the requester doesn't open).
- 4). The address of the FileIO's Filename buffer (i.e. where the selected
- string is copied) if all went well and the user selected OK, or double-
- clicked on a string, or typed in his selection in the Name gadget.
-
- So how do you give your list of strings to the lib? There are 2 functions,
- NewEntryList() and AddEntry() that you use to make the list.
- Here are the passed parameters.
-
- EntryNum = AddEntry(ID_num, StringAddress, FileIO);
- d0 d1 a0 a1
-
- NewEntryList(FileIO);
- a1
-
- Each FileIO can have its own list attached to it. NewEntryList frees any
- previous list (if one exists) that was made for the passed FileIO. For this
- reason, you should call NewEntryList first before using AddEntry to add
- strings. You can then add strings to the list by subsequent calls to AddEntry.
- (AddEntry adds the one passed string into the list. The list is alphabetized as
- each string is added to it so that the strings are always displayed in alpha-
- betical order, unless you set the NO_ALPHA flag. With NO_ALPHA, each entry is
- added to the tail of the list.) ID_num is some value that you want associated
- with the string. When the user selects that string, it is copied into the
- FileIO's Filename buffer and the ID is copied into the FileIO's FileSize field.
- This ID is a LONG, and can be any value you desire (i.e. maybe even a pointer
- to some data structure associated with that string). The only restriction is
- that ID cannot be -1 (i.e. 0xFFFFFFFF).
- NOTE: Your strings must be limited to 192 bytes (counting the final null).
- The file requester only displays the first 29 bytes of the string. Furthermore,
- when the string is copied to the FileIO's Filename buffer, the size of that
- buffer is 192 bytes (ie Filename[192]) instead of 30 as with normal disk I/O.
- The returned EntryNum is where the string has been alphabetically placed
- in the list (i.e. the first string in the list returns 0). If you receive a
- negative number from AddEntry(), this means that there wasn't enough memory to
- add the string to the list. Actually, AddEntry copies the string, and adds the
- copy to the list, so you need not keep the original string after it is added to
- the list.
- Once you setup a FileIO's list, it remains this way until you perform
- NewEntryList, or use that FileIO for disk IO. You do not have to remake the
- same list everytime that you call DoFileIO.
- When you finally call ReleaseFileIO(), any list associated with the FileIO
- is freed.
- Here is how you might create a list with the following 3 items and display
- it in the FileIO requester:
-
- /* You should have opened the requester lib and allocated a FileIO */
-
- if (myFileIO)
- {
- NewEntryList(myFileIO);
- error = AddEntry(1L, "This is One", myFileIO);
- if (error<0) break;
- error = AddEntry(2L, "Two", myFileIO);
- if (error<0) break;
- error = AddEntry(3L, "Three", myFileIO);
- if (error<0) break;
-
- result = (DoFileIO(myFileIO, window));
- if (result==myFileIO->FileName)
- {
- /* FileName buffer contains the string, and FileSize the ID
- */
- }
- if (result==0)
- {
- /* This only happens if DoFileIOWindow() bombs. Call DoFileIO() */
- }
- if (result==-2)
- {
- /* This happens if someone is using the library. Come back later */
- }
- /* Otherwise, CANCEL must have been selected. Never mind. */
- }
-
- There is a possibility that the user may type a string that is not in the
- list, directly into the Name gadget. Before exiting, the requester lib will
- check if the string is in the list. If not, the string is copied to the FileIO
- FileName buffer as before, but the FileSize field is set to -1. A FileSize of
- -1 means "this string isn't in the list". That is why you should not assign an
- ID of -1 to any string. The lib ignores the case of the string when comparing
- items in the list (i.e. "Amiga" and "amIGA" are the same), but it does not trim
- away any leading or trailing spaces.
-
- With SPECIAL_REQ, the "Next Disk" gadget can be a custom gadget for your
- use. You place into the FileIO's FileIOText field a pointer to the string
- that you want displayed in the gadget. This string should be no more than 11
- characters (not counting the end NULL). You should pad the head of the string
- with spaces to properly center inside the gadget. You should also store in the
- FileIO's FileIORoutine field a pointer to a routine that is to be executed
- everytime the user releases the mouse over the custom gadget. The library calls
- this routine passing the FileIO and Window (that the requester opened in), and
- the Requester Structure.
-
- BOOL yourRoutine(Requester, Window, FileIO)
- a5 a3 a2
-
- This function should return TRUE to end the requester, or FALSE to continue.
- If FALSE, the FileIO display will be refreshed when your function returns. (In
- case your custom routine added/removed something from the list, or changed
- lists). If you return TRUE, the requester will end with the FileIO's Errno
- field set to ERR_APPGADG.
- If your FileIO's FileIORoutine field is set to NULL when you call DoFileIO,
- the custom gadget is removed from the display.
-
- Finally, there is a routine that you can use to determine if a certain
- string is in the list.
-
- entryNum = IsEntryThere(String, FileIO)
- d0 a0 a1
- where String is the address of the string you wish to check for.
- This returns the entryNum (like AddEntry) of the string if it is found
- in the list, or a -1 if it is not in the list. For assembly programmers,
- if found, the address of the Remember structure is returned in a0.
-
-
- ====================== Filename and Custom Lists =====================
-
- The list of filenames (or custom list created via AddEntry) is created using
- the Intuition function, AllocRemember. The "anchor" of the list is the FileIO's
- FileList field. So each string has its own Remember structure. The Remember's
- rm_Memory points to my own Entry structure. An Entry structure looks like this:
-
- struct Entry {
- LONG EntryID;
- UBYTE EntryFlags; /* Don't alter this! */
- UBYTE EntryString[size of the string not counting end NULL];
- };
-
- In asm,
-
- EntryID dc.l 0
- EntryFlags dc.b 6
- EntryString dc.b [the bytes comprising the NULL-terminated string]
-
- I have redefined the Remember structure as a FileEntry structure since
- that is easier to reference:
-
- struct FileEntry {
- struct FileEntry *nextEntry;
- ULONG EntrySize;
- struct Entry *filePart;
- };
-
- Don't use sizeof on these structures. The library makes them for you. The 3rd
- field of the Entry structure is a variable length, NULL-terminated string. This
- structure has been defined simply so that you can get access to the EntryID,
- EntryFlags, and EntryString. These structures are used for both custom lists
- and the list of filenames. For filenames, each filename has a FileEntry
- structure. Its EntryID is the filesize. Bit #7 of the EntryFlags is set if the
- filename was selected by the user. The EntryString is the NULL-terminated
- filename (separated from its dir). When the SPECIAL_REQ flag is set, the
- Entry's EntryID is your passed ID to AddEntry(). All the FileEntry structures
- are linked together, and the FileIO's FileList field points to the first
- FileEntry in the list.
-
- You can use one FileIO to alternately display several custom lists. The key
- is to properly set the FileIO's NameCount, NameStart, CurrentPick, and FileList
- fields before calling DoFileIO(). You should make a list as in the above
- example, and then copy the FileList field to some global. Then zero out the
- FileList field. Do this for all your lists. Now when you want to display one
- list, pass the appropriate global to a routine that does the following:
- 1). Clear the FileList field.
- 2). Call NewEntryList() (to initialize the NameStart and CurrentPick)
- 3). Set the FileIO's NameCount to the number of items in the list
- 4). Set the FileIO's FileList to the passed global.
- 5). Set the SPECIAL_REQ flag. (If it wasn't set previously.)
- 6). Call DoFileIO()
- 7). Clear the FileList field.
-
- Here's a C function to implement the above. It returns TRUE if all went
- well, and FALSE if error or user cancel.
-
- BOOL ShowList(ListAddr,NumOfItems,window,fileio)
- struct Remember *ListAddr; /* the contents of the FileIO's FileList field
- after you made the list with AddEntry(). */
- SHORT NumOfItems; /* number of entries in Remember List */
- struct Window *window;
- struct FileIO *fileio;
- {
- UBYTE *address;
-
- fileio->FileList = 0; /* you stored the original value in the global ListAddr
- after making the list */
- NewEntryList(fileio);
- fileio->NameCount = NumOfItems;
- fileio->FileList = ListAddr;
- SetFlag(fileio->Flags, SPECIAL_REQ);
- address = DoFileIO(fileio, window);
- fileio->FileList = 0;
- if( address <= 0 )
- return( FALSE );
- else
- return( TRUE );
- }
-
- When exiting your program, you must de-Allocate all the lists. For each,
- 1). Set the FileIO's FileList to the passed global.
- 2). Call NewEntryList()
-
-
- void FreeProgList(fileio, filelist)
- struct FileIO *fileio;
- struct Remember *filelist;
- {
- fileio->FileList = filelist; /* original value you previously stored in global
- after making the list */
- NewEntryList(fileio);
- fileio->FileList = 0;
- }
-
- Consult the examples, CustomList, for how to use SPECIAL_REQ.
-
-
- ========================= Multiple Selections ===========================
-
- You can allow the user to make multiple selections from a custom list or the
- filename list by setting the FileIO's MULTIPLE_FILES flag. When the user clicks
- on a name, it will be highlighted. The user can then select more filenames,
- with all of them simultaneously selected. The library sets bit #7 of each
- selected file's Entry structure's EntryFlags. If a user clicks on a filename
- that is already selected, then the filename is de-selected. Note that double-
- clicking on a filename still can terminate the requester. The last selected
- name is the one that appears in the FileIO's FileName buffer.
- When the user double-clicks, or selects CANCEL or OK, the requester ends. At
- this point, you must go through the FileIO's FileList, examining each Entry
- structure's EntryFlags for bit #7 set to determine which files were selected.
- The caveat is that all files must be in the same directory because the Entry-
- String does not contain the full path, only the filename. (The path can be
- constructed with the FileIO's Disk and Drawer buffers. The best approach is to
- copy the filename to the FileIO's FileName buffer and then call GetFullPathname
- to add the FileIO's Disk and Drawers.)
- There is a library function to aid in locating the selected files:
-
- FileEntry = RetrieveEntry( FileEntryPtr, FileIO );
- d0 a0 a1
-
- FileEntryPtr should point to a FileEntry structure in the FileIO's FileList
- or be set to 0. If 0, this routine locates the first selected FileEntry
- structure in the FileList, updates the passed FileEntryPtr to point to that
- structure, and returns that address. The next time that this function is
- called, FileEntryPtr will not be 0, and so this function will return the next
- selected FileEntry structure, etc. When there are no more selected files, a 0
- is returned and the FileEntryPtr is cleared.
-
- Another function:
-
- ClearEntries(FileIO);
- a1
-
- clears the selected bit of all EntryFlags in the FileIO's FileList. This is
- useful for clearing selections after a custom list has been presented to the
- user, or for when the user has set NO_CARE_REDRAW.
-
- If the user types a filename directly into the Filename gadget, the library
- will NOT check if the filename is in the current list and set its selected
- bit if so. You can determine whether the filename exists in the current dir
- by the value of the FILEIO_FILESIZE field as before. For SPECIAL_REQ, the
- library DOES set the selected bit if the entered text is one of the displayed
- choises.
-
- Consult the examples for how to use MULTIPLE_FILES.
-
-
- ========================== Installing Custom Handlers =======================
-
- You can install custom handlers for any of several events that might occur
- in the requester. You need to set the CUSTOM_HANDLERS flag of the FileIO, and
- fill the FileIO's HandlerBlockPtr field with the address of a HandlerBlock
- structure. The HandlerBlock structure (defined in FileIO.h) holds the addresses
- of the handlers for REQSET, DISKINSERTED, GADGETDOWN (and UP), RAWKEY, and
- MOUSEMOVE. If you have no handler for a particular event, NULL its HandlerBlock
- field. Each FileIO can have its own custom handlers.
- For REQSET, and DISKINSERTED, if your handler returns a 1, then the library's
- internal handler will be skipped. Otherwise, the library routine will be
- executed if you return a 0.
- For GADGETDOWN and GADGETUP, your handler will be called only if the Gadget
- ID is not one of the requester's gadgets. Your handler will be passed the ID
- in d0 (as well as other parameters). Your handler should return a 0 in order
- to continue, or a 1 if you wish to end the requester. (You can check that your
- custom handler ended the requester if the FileIO's Errno = ERR_APPGADG). The
- only two requester gadgets that the library no longer controls are the CANCEL
- and OK gadgets. Control of these two is passed to your custom handler. These
- two gadgets have IDs of 32672 and 32673 respectively. If you receive either of
- these IDs, you should return a 1. On the other hand, you could simply cause
- these gadgets to be ignored by returning a 0. In any event, your handler will
- have to return a 1 eventually in order to exit the requester, or the user would
- have to type the Filename in the Filename string Gadget. Do not use gadget IDs
- between 32672 to 32682 as these are reserved by the library.
- For MOUSEMOVE, the events are "collected" (i.e. you only receive one event
- when the user stops moving the mouse). Also, you won't receive MOUSEMOVE when
- the user is operating the requester's scroll (prop) gadget. Your handler
- doesn't need a return value.
- For RAWKEY, you won't receive any function keys. No return value is needed.
-
- The requester calls your handler with the following items in these registers:
-
- a2 - the address of your FileIO
- a3 - the address of the window in which the requester is open
- a4 - the IAddress of the event (not valid for REQSET or DISKINSERTED)
- d6 - MouseX position (for RAWKEY handler, this is the Code instead)
- d7 - MouseY position (for RAWKEY handler, this is the Qualifier)
- d2 - Seconds
- d5 - Micros
- d0 - (need not be saved) For GADGETUP and DOWN, the gadgetID
- For RAWKEY handler, the ascii value as returned from DecodeRawkey()
-
- You MUST save these registers if you plan on altering them.
- If your handler is written in C (yech!), I've provided a mechanism for
- receiving these parameters passed on the stack like all good, inefficient C
- programs should. Let's face it, C just doesn't have enough power to do the
- sophisticated, efficient things that we do in assembly. But if you'd like to
- fool yourself into thinking otherwise, I've tried to accomodate your delusions.
- After filling in the HandlerBlock's pointers to the desired routines, you must
- call SetFileIOHandlers(HandlerBlock). This routine will see to it that your
- handler receives the following parameters except where previously noted.
-
- BOOL yourHandler(IAddress,Window,FileIO,MouseY,MouseX,Micros,Seconds,GadgID);
-
- Note that GadgID is the ascii value (UWORD) for the RAWKEY handler.
-
- Unfortunately, unlike the assembly implementation, if you want to have
- different FileIO's with unique custom handler routines, you'll have to call
- SetFileIOHandlers() before each call to DoFileIO(). Hey, you're writing in C,
- so you should be used to giving up some flexibility.
- If you're using Manx small data model, you'll probably have to call geta4
- or savea4 (whatever). a4 will definitely not have the base of your program's
- data section. These are the types of problems you should expect if you allow
- a C compiler to determine 68000 register usage. Also, since register a6 is
- "reserved" for library base vectoring on the Amiga, the C interface to the
- library does not save this register. If your compiled program crashes because
- of this, its time to buy a better compiler, or perhaps solve these headaches
- once and for all with an assembler.
-
- struct HandlerBlock {
- APTR StartUpCode; /* Called when the requester first opens */
- APTR DiskInsertedCode; /* Called whenever a disk is inserted */
- APTR GadgetCode; /* Called whenever a gadget UP or DOWN */
- APTR KeyCode; /* Called whenever a rawkey occurs */
- APTR MouseMoveCode; /* Called when the mouse is moved */
- };
-
- In assembly:
-
- HandlerBlock
- dc.l AddrOfStartCode
- dc.l AddrOfDiskInsertCode
- dc.l AddrOfGadgetCode
- dc.l AddrOfRawkeyCode
- dc.l AddrOfMouseMoveCode
-
-
- =============================================================================
- === DEMO PROGRAM NOTES ======================================================
- =============================================================================
-
- This section briefly describes the demo programs that drive some of the FileIO
- Requester library's features. There are C, assembly, and AmigaBasic demos (no
- joke).
-
- If you invoke some of the C or asm demos without a second argument on the CLI,
- a window will be opened in the Workbench screen. If you invoke these demos with
- any second argument, a hi-res screen will be opened for the requester window.
-
- The C demo, TestFileIO.c, uses two FileIO structures to demonstrate the tech-
- niques that you should use when managing multiple FileIOs. The first FileIO
- structure, fileio1, is used in its default state as created by GetFileIO(). The
- other one, fileio2, is initialized to do Workbench-style .info file handling
- where the filename list will consist of only .info objects of type WBPROJECT.
- Also, fileio1 uses volume names and the other uses device names. You activate
- fileio1 when you click the right mouse button. You activate fileio2 when you
- press any key. Finally, when you do any of the selection techniques where you
- accept your selection, the pathname to your selection is displayed in a FileIO
- autorequester. If you choose CANCEL to end the FileIO process, nothing happens.
- To stop the program, click on the window close gadget (when the requester is
- not displayed). CustomList.c demos setting up a custom list of strings.
-
- The assembly demo only uses 1 FileIO structure. There is a menu to demonstrate
- various features. You should manually deselect the features you want disabled,
- and select those that you want enabled. For example, select CUSTOM to see how
- a custom handler is installed for the REQSET event. Also, this program can look
- for files that only end in certain strings if you select the EXTENSION menu
- item. When you enable the extension feature, the application uses the Prompt-
- UserEntry() function. Notice how the prompt appears in the window titlebar with
- a cursor. You can type in the string that you want to match, and hit return.
- Now that when you call up the requester, only those filenames that end in that
- extension will be displayed (along with any dirs). This works just like the F4
- Function key option.
- Also of interest is the Multiple menu item which toggles MULTIPLE_FILES.
- With this on, note how several files can be clicked and selected. When you
- select OK, the asm example then prints out the pathbuffer, followed by all
- files selected. Note that the selected files do not contain the full path.
-
- The amigabasic demo, BasicFileIO asks the user if he wants to display only
- those files with a certain extension, and inputs the extension. Otherwise, it
- suppresses all .info files. It then copies the pathname to a string variable
- which can be better utilized for basic manipulation. Also this demos a few of
- the library's autorequester functions. When running this program, the included
- bmap for the FileIO requester library must be in the same directory. BasicList
- demos how to use the FileIO to display a list of your own strings. MultipleList
- and MultipleFile demo how to handle multiple selections for both filename and
- custom lists in BASIC.
-
-
- =============================================================================
- === TECHNICAL REFERENCE =====================================================
- =============================================================================
-
- The FileIO files include:
-
- requester.library the actual library (slightly < 11K in size)
- FileIO.doc The documentation. You've obviously found it.
- FileIO.h includes for an C application using the library
- FileInterface.asm glue routines for a C application to use the
- library. (poot) Expects all integers passed 32bit
- FileIO.i assembly programmer's include file
- TestFileIO.c a C example of filename selection
- CustomList.c a C example using SPECIAL_REQ
- TestFileIO.asm an assembly example of filename selection
- CustomList.asm an assembly example using SPECIAL_REQ
- StartUp.asm the startup code for the assembly examples
- TestFileIO an executable of the assembly filename example
- CustomList an executable of the assembly SPECIAL_REQ example
- BasicFileIO an AmigaBasic application of single filename selection
- BasicList an AmigaBasic demo of SPECIAL_REQ
- MultipleFileIO an AmigaBasic application of multiple filenames
- MultipleList an AmigaBasic demo of SPECIAL_REQ with multiple select
- requester.bmap the bmap file for AmigaBasic
- requester_lib.fd the fd file used to make the bmap file
-
-
- ================= USING THE AMIGA PROGRAMMER'S SUITE =======================
-
- The following is the message that appeared with RJ Mical's ProSuite code
- on Fred Fish Disc #107. That version of FileIO was not a library. It was a C
- code module that needed to be compiled and linked with your application. At
- this point, the code for this library is SIGNIFICANTLY DIFFERENT THAN THE
- ORIGINAL, and quite incompatible with R.J's Includes and Defines. Also, there
- are differences in both functionality and features. But R.J. started the ball
- rolling so....
-
- The Amiga Programmer's Suite Book 1 is copyrighted but freely distributable.
- All copyright notices and all file headers must be retained intact. The Amiga
- Programmer's Suite Book 1 may be compiled and assembled, and the resultant
- object code may be included in any software product. However, no portion of the
- source listings or documentation of the Amiga Programmer's Suite Book 1 may be
- distributed or sold for profit or in a for-profit product without the written
- authorization of the author, RJ Mical.
-
- If you use the Amiga Programmer's Suite, I wouldn't mind if you gave me some
- mention somewhere. Good luck! Program hard, program well. -RJ Mical
-
- Make lots of money and become a arrogant, self-serving pain-in-the-ass.
- -Jeff Glatt (my personal philosophy is a bit more philanthropic than RJ's)
-
-
- === APPENDIX A: FileIO Function Calls ======================================
-
- CONTENTS:
- AddEntry()
- AddFileGadgs()
- AutoMessage()
- AutoMessageLen()
- AutoPrompt3()
- AutoFileMessage()
- BW_Restore()
- ClearEntries()
- DecodeRawkey()
- DoFileIO() ;only 1 task at a time
- DoFileIOWindow() ;only 1 task at a time
- FindName()
- GetFullPathname()
- GetFileIO()
- GetRawkey()
- IsEntryThere()
- NewEntryList()
- ParentLock()
- ParentPath()
- ParseString()
- PromptUserEntry()
- PutProjIcon()
- ReleaseFileIO()
- ResetBuffer()
- RetrieveEntry()
- SetWaitPointer()
- TypeFilename()
- UserEntry()
- Window_BW()
-
- ««««««««««««««««««««««««««« FILENAME FUNCTIONS »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
-
- *********************** DoFileIO(), DoFileIOWindow() **********************
-
- NAME
- DoFileIO -- Gets a file name for input/output from the user
- DoFileIOWindow() -- The same, but opens a window for the requester.
-
- SYNOPSIS
- ULONG address = DoFileIO(fileio, window);
- d0 a0 a1
- ULONG address = DoFileIOWindow(fileio, screen);
- d0 a0 a1
-
- 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 FileIO structure, which is allo-
- cated and initialized via a call to GetFileIO(), or declared in your
- application.
- You may preset the FileIO parameters before calling this routine,
- or you may leave them set at their default values. See the FileIO
- documentation and include files 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.
- DoFileIOWindow() is provided to circumvent this problem. It simply opens
- a window on the passed screen before calling DoFileIO, and closes it
- upon exit. By setting screen to NULL, the window opens on the WorkBench
- screen. Also, you might use DoFileIOWindow if you wanted a requester
- that could be moved or depth arranged by the user in an existing screen.
- The title that appears in the window will be gotten from the address in
- the FileIO's Title field.
-
- You must initialize the FileIO's Buffer field to hold the address of a
- buffer where the full pathname string (i.e. disk:drawer.../filename) will
- be constructed. The size should be no less than 202 bytes. Also, the
- FileIO's DrawMode, PenA, and PenB fields should be set to the values
- you want restored when the requester closes.
-
- This routine returns a 0 if DoFileIOWindow's window couldn't open, a -1
- if the user selected CANCEL, or the address of the FileIO's Buffer if
- all went well and the user selected a filename. The full path name will
- have been constructed in the buffer. The filename itself will have
- all leading and trailing blanks removed (in case the user typed in a
- filename with extraneous spaces) and stored in the FileIO's FileName[].
- Likewise, the disk and drawer names can be found in the text
- fields DiskName[] and DrawerName[] of the FileIO. You can always call
- GetFullPathname() to build the pathname from the separate fields of the
- FileIO.
-
- 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 some
- other task is calling DoFileIO() or DoFileIOWindow(), this routine
- will automatically call TypeFilename() for the 2nd application.
-
- INPUTS (for DoFileIO)
- fileio = pointer to a FileIO structure, as allocated
- via a call to GetFileIO()
-
- window = pointer to a Window structure, as created via a call
- to Intuition's OpenWindow()
-
- RESULT
- 0 if an error in opening DoFileIOWindow() window. You will not get this
- error for DoFileIO()
- -1 if the user selected CANCEL
- the address of the Buffer if all went well and a file was selected. Also
- for assembly programmers the end of the string is in a1 like GetFullPathname.
-
- BUGS
- Clears the RMBTRAP bit of Window's Flags.
-
-
- ********************* FindName() ************************
-
- NAME
- FindName -- Isolate the filename part from a complete pathname
-
- SYNOPSIS
- pathend = FindName(buffer,pathname);
- d0 a0 a1
-
- FUNCTION
- Separates the filename part from the passed, complete pathname string. The
- pathname may contain drawer and disk names (i.e. df0:someDrawer/filename).
- The filename part is then copied to the passed buffer, and this is stripped
- from the pathname.
-
- INPUTS
- FileIO
- pathname - a pointer to a null-terminated path string
-
- RESULT
- Returns the address of the terminating null byte of pathname so that you
- can quickly append a new filename to this path (dir)
-
-
- ********************* GetFileIO() ************************
-
- NAME
- GetFileIO -- Allocate and initialize a FileIO structure
-
- SYNOPSIS
- struct FileIO *GetFileIO();
-
- FUNCTION
- Allocates and initializes a FileIO structure for use with
- calls to DoFileIO(), DoFileIOWindow(), TypeFileName(), PromptUserEntry().
-
- You may want to further initialize the structure before calling these
- routines. At least the FileIO's Buffer, DrawMode, PenA, and PenB fields
- should be initialized. Instead of allocating a FileIO via this routine,
- you may declare one globally or statically as long as all fields are
- initialized to zero or an approprite value.
-
- When you're done with the structure, call ReleaseFileIO() regardless of
- whether it was allocated or declared to free up resources.
-
- INPUTS
- None
-
- RESULT
- If all goes well, returns the address of a FileIO structure.
- If anything goes wrong (out of memory), returns NULL.
-
-
- *********************** GetFullPathname() *********************
-
- NAME
- GetFullPathname -- Build a file pathname using a FileIO struct
-
- SYNOPSIS
- Buffer = GetFullPathname(FileIO, Buffer);
- d0 a0 a1
-
- FUNCTION
- Builds the text for a pathname using the FileName[], DrawerName[] and
- DiskName[] fields of the specified FileIO structure after the structure
- has been used in a successful call to DoFileIO(), DoFileIOWindow(), or
- TypeFilename(). Writes the text into the Buffer.
-
- INPUTS
- FileIO = the address of a FileIO structure
- Buffer = address of the buffer to receive the file pathname
-
- RESULT
- The address of the passed buffer. Also, for assembly programmers the
- address of the terminating NULL is in a1 so you can quickly determine
- the string length by subtracting d0 from a1 with the result in a1.
-
-
- *********************** ParentLock(), ParentPath() *************************
-
- NAME
- ParentPath, ParentLock - Create an entire path from a filename or lock
- and parse it into the FileIO
-
- SYNOPSIS
- ParentPath(FileIO,Name)
- a0 a1
-
- ParentLock(FileIO,Lock)
- a0 a1
-
- INPUTS
- The FileIO structure
- The address of the NULL-terminated filename (for ParentPath)
- An amigaDOS lock (for ParentLock)
-
- FUNCTION
- These 2 functions recreate an entire path from just a filename or a lock.
- They are very useful for interpreting the args from Workbench or the CLI
- when your program is started. They create the entire path in the FileIO's
- Buffer, then call ParseString() to separate the components into the FileIO
- Filename, Drawername, and Diskname buffers, and set the FILEIO_FILESIZE and
- FREEBYTES. For example, assume that your program takes the following file-
- name arg from the CLI:
-
- 1> MyProg <some data filename>
-
- Let's assume that the user's current directory is a drawer in RAM: called
- "Blort". He runs your program as so:
-
- 1> MyProg MyName
-
- Now, how do you know where MyName is if the user didn't specify the entire
- path of RAM:blort/MyName? Well, you can pass the string that he did type to
- ParentPath() and your fileio buffer will be returned with that complete path
- (and the FILESIZE and FREEBYTES set accordingly). The fileIO FileName will
- contain "MyName", the DrawerName will be "blort", and the DiskName will be
- "RAM:". When the user calls up the file requester, this is how it will open.
- ParentLock() creates the entire path based upon a Lock. For example, some
- program sends you a lock on a file. You can create the entire path and parse
- it into the FileIO with this function.
- From WB, the user may click on the icon for the data file. You simply
- get the wa_Name from the arg for the data file and call ParentPath().
- As a third example, you may wish to obtain the complete pathname for
- your program (ie tool name) since the user may have renamed it. You'll want
- to save icons with this tool name string. This is done with ParentPath in
- the same manner as with the data file examples.
- This is useful for processing the initial argv argument passed to
- _main for the StartUp code. It will initialize the FileIO buffers to
- this passed name, and set-up the FileSize and Filename buffer so that
- it can be determined what kind of object this is. Also, it makes it
- possible to use the same load routine for the initial passed argv as
- you would for DoFileIO() or TypeFilename(). For Basic programmer's this
- can be used to set up the FileIO based upon a string gotten via an Input
- statement.
- Note that for non-existant paths or filenames, this will NULL out the
- path buffer. In such a case, it may be necessary to strip off the filename
- part using FindName, and call ParentPath with this new path. Then, you
- can reappend the filename part by copying it back to the FileIO FILENAME
- buffer, and calling GetFullPathname to finally recreate the complete path.
- All of this hassle is due to the fact that AmigaDOS, a very inadequate DOS,
- has no facility to easily obtain the complete working path of a CLI's
- current directory. (When is CBM going to fix this???)
-
-
- *********************** ParseString() *******************************
-
- NAME
- ParseString - Separate a path string into separate components
-
- SYNOPSIS
- ParseString(FileIO,String)
- a0 a1
-
- INPUTS
- The FileIO structure
- The address of the NULL-terminated path
-
- FUNCTION
- This takes the NULL-terminated path as it would be typed on a CLI line
-
- Diskname:TopDrawer/....etc.../BottomDrawer/Filename
-
- and parses it for "weird" typos or non-existant disk or drawer names.
- Of course, there may not be any Disk or Drawer names. It then copies the
- individual components of the Disk, drawer, and filename to the FileIO's
- respective buffers, and sets the FILEIO_FILESIZE and FILEIO_FREEBYTES
- fields accordingly. (i.e. If the path turns out to be a drawer or disk
- only, then FileIO's Filename is NULLED and FileSize = 0. If a non-existant
- file, it copies the Filename to FileIO, but FileSize = 0. If it is a
- loadable file, it copies the Filename and sets FileSize accordingly.)
- The parsed result is placed into the FileIO's Buffer (cannot be the same
- buffer as the passed string).
- This can be used in place of the slower ParentPath() as long as you're
- sure that the complete path (including all dir levels) is part of the
- string. Otherwise, the FileIO is set up to default to the current directory.
- For example, if you wanted to check for the existance of a file without
- bringing up the requester, and you know the complete path, use this.
-
-
- ************************* ReleaseFileIO() **************************
-
- NAME
- ReleaseFileIO -- Release the FileIO structure and all local memory
-
-
- SYNOPSIS
- ReleaseFileIO(fileio);
- a1
-
- FUNCTION
- Releases the FileIO structure by freeing all local memory attached
- to the structure and then freeing the structure itself if it is an
- ALLOCATED_FILEIO (i.e. not pre-initialized in your application).
- Restores the directory that was established when the FileIO was first
- sent to DoFileIO() or DoFileIOWindow(). (You should not unlock the
- initial dir that is contained in the FileIO's originalLock field.)
-
- INPUTS
- fileio = the address of a FileIO structure
-
- RESULT
- None
-
-
- ;********************* TypeFilename() ***************************
-
- NAME
- TypeFilename - Uses the window's titlebar to obtain the path name instead
- of the file requester (an alternative). Displays the prompt
- "Filename >"
-
- SYNOPSIS
- buffer =TypeFilename(FileIO, Window);
- a0 a1
-
- FUNCTION
- If you really don't like the requester, and would prefer to have the
- user type in the full path via the window's title bar, then use this.
- Also, you might use this within a save routine so that the user has to
- deliberately type his choice. The pathname contained within the FileIO's
- Disk, Drawer, and Filename fields is what is initially presented to the
- user. This routine is automatically called if an application tries to
- call DoFileIO() or DoFileIOWindow() when another task is displaying the
- FileIO requester. Also called if there is not enough mem to open/display
- the requester. This routine sets up the FileIO's Disk, Drawer, Filename,
- FileSize, and FreeBytes fields in the same manner as DoFileIO so that
- you can interpret the results in exactly the same manner.
-
- INPUTS
- Window = the address of a window
- FileIO = the FileIO structure
-
- RESULT
- Returns the address of the FileIO's Buffer or a -1 if the user bailed
- out without entering anything. An ESC will return -1, but will store an
- ESC char ($1B) and then NULL char in the buffer.
-
-
-
- «««««««««««««««««««««««««« RAWKEY STRING INPUT »»»»»»»»»»»»»»»»»»»»»»»»»»»»
-
- ;*************************** DecodeRawkey() ***************************
-
- NAME
- DecodeRawkey() - Takes the passed RAWKEY Code and Qualifier and returns
- an ascii value based on the System KeyMap.
-
- SYNOPSIS
- value = DecodeRawkey(Qualifier, Code);
- d0 a1
-
- FUNCTION
- Because there exists different Amiga keyboard configurations and alternate
- keymaps, there are only 2 proper methods for your program to translate user
- keystrokes into ascii chars:
-
- 1). Use the console device.
- 2). Use VANILLA_KEY IDCMP.
-
- The problem with #1 is that you have to deal with the console.device,
- IO blocks, and Function, cursor, and other keys being translated as character
- strings. Very UGLY!!!! The problem with #2 is that you don't receive Function,
- cursor, or Help keystrokes. Very unfriendly!!! This routine solves both pro-
- blems by managing the console device for you, and by "extending" the ascii
- char set, it defines single ascii values for each Function, cursor, and Help
- key.
-
- INPUTS
- Code - the code field of a RAWKEY IntuiMessage
- Qualifier - the qualifier field of a RAWKEY IntuiMessage
-
- RESULT
- The return is a UWORD (not a byte as is usually the case with ascii chars).
- This is because I have "extended" the ascii char set beyond hex FF in order
- to define values for the Function, cursor, and Help keys. A zero is returned
- if the key is undefined or if it is a KEYUP event.
-
- Plain Function keys return hex 100 to 109 for the 10 keys.
- The 4 cursor keys are hex 10A to 10D for UP, DOWN, RIGHT, and LEFT
- respectively.
- The Help key returns hex 10e.
- Shifted Function keys return hex 200 to 209.
- Shifted cursor keys are hex 20A to 20D.
- Shifted Help key is 20E.
- Alt Function keys are hex 400 to 409.
-
- All other keys (and combos) return whatever value the System KeyMap contains
- (except that all char strings are ignored and return 0).
-
-
- ;*************************** UserEntry() ***************************
-
- NAME
- UserEntry - Uses the window's titlebar to obtain user input.
-
- SYNOPSIS
- buffer = UserEntry(charlimit, initBuffer, FileIO, Window);
- d0 a1 a2 a3
-
- FUNCTION
- This clears the window's titlebar, displays a cursor, and allows the user
- to type in chars up to the limit, or until CR or ESC is pressed. The NULL
- terminated result is placed in the FileIO's Buffer. When the charlimit is
- reached, the routine automatically terminates. You must set the FileIO's
- PenA, PenB, and DrawMode fields so that these may be restored by the lib
- when the function is finished.
- The initBuffer string is what is presented to the user (and what he may
- edit). The passed window must have RAWKEY IDCMP set, and the FileIO's
- RawCode field set to 0 in order to use the default decoding routine,
- GetRawkey(). Otherwise, decoding will be redirected to the routine specified
- in the FileIO's RawCode field. (Maybe you want VANILLAKEY instead. Or
- maybe you also want to handle other IDCMP events while "inside" of UserEntry.
- GetRawkey disposes of all but RAWKEY events. Or maybe you've set up your
- own custom IDCMP port and RAW handling routine.) Regardless, your RawCode
- routine must go to the window's IDCMP port to get a message or wait if
- there is no message. It should handle all IDCMP messages except RAWKEY or
- VANILLAKEY. If one of these messages, exit with an UWORD representing the
- character as follows:
- $20 to $7F for ascii chars, $7F for delete, $08 for BACKSPACE, $0D for
- RETURN, $1B for ESCAPE, $010C for LEFT Cursor, $010D for Right Cursor,
- $020C for SHIFT-LEFT Cursor, and $020D for SHIFT-RIGHT Cursor.
- UserEntry will continue calling your RawCode for each char, and terminate
- upon receiving an $0D or $1B, or reaching the charlimit.
- Since the titlebar can hold approx 70 chars between the CLOSEGADGET and
- FRONT/BACK, the FileIO's Buffer might be set to 70 bytes. It must be at
- least as big as charlimit. Upon return, your window's title is restored.
-
- INPUTS
- Window = the address of a window
- FileIO = the FileIO structure
- charlimit = the number of characters to accept from the user
- initBuffer = the NULL-terminated string to initialize the FileIO's
- buffer to, or NULL if no initialization desired
-
- RESULT
- Returns the address of the FileIO's Buffer or a 0 if the user bailed
- out without entering anything. An ESC will return 0, but will store an
- ESC char ($1B) and then NULL char in the buffer.
-
-
- ;******************** PromptUserEntry() ***************************
-
- NAME
- PromptUserEntry - Uses the window's titlebar to obtain user input.
-
- SYNOPSIS
- buffer = PromptUserEntry(charlimit,prompt,initBuffer,FileIO,Window);
- d0 a0 a1 a2 a3
-
- FUNCTION
- This works just like UserEntry except that it first displays the
- passed prompt string in the titlebar. The FileIO's Buffer should always
- be greater than the number of chars in the prompt plus charlimit.
-
- INPUTS
- Window = the address of a window
- FileIO = the FileIO structure
- charlimit = the number of characters to accept from the user
- prompt = NULL-terminated prompt to display
- initBuffer = the NULL-terminated string to initialize the FileIO's
- buffer to, or 0 if no initialization desired
-
- RESULT
- Returns the address of the FileIO's Buffer or a 0 if the user bailed
- out without entering anything. An ESC will return 0, but will store an
- ESC char ($1B) and NULL char in the buffer.
-
-
- ******************* SetTitle() ********************************
-
- NAME
- SetTitle - Uses the window's titlebar to display 1 or 2 strings.
-
- SYNOPSIS
- SetTitle(String1,String2,FileIO,Window);
- a0 a1 a2 a3
-
- INPUTS
- Window = the address of a window
- FileIO = the FileIO structure
- String1 = the NULL-terminated string to the left
- String2 = NULL-terminated string placed to the right of String1. If you
- pass a zero instead, no 2nd string displayed.
-
- FUNCTION
- This will display the 2 strings in the window's titlebar (saving the
- initial title to the FileIO's Title field), and return immediately with
- the strings still displayed. Subsequent calls can be made to display
- different strings, but when ResetTitle() is finally called, the initial
- titlebar is restored. This routine is useful for displaying error msgs to
- the user without halting program execution (like a requester does), and
- allows the msg to remain visible for as long as it is needed. Furthermore,
- it doesn't require that the user respond to it. This function makes temp-
- orary use of the FileIO's Buffer, so you must supply a buffer whose address
- is stored at the FileIO Buffer field. This buffer must be large enough to
- contain both Strings.
-
-
- ******************* ResetTitle() ********************************
-
- NAME
- ResetTitle - Restores the window's titlebar after calls to SetTitle
- (if any calls were made at all)
-
- SYNOPSIS
- ResetTitle(FileIO,Window);
- a2 a3
-
- INPUTS
- Window = the address of a window
- FileIO = the FileIO structure
-
- FUNCTION
- Resets the initial title (stored in FileIO's Title field) if it detects
- that any calls were made to SetTitle. Otherwise, it does nothing.
-
-
- ««««««««««««««««««««««««««««««« CUSTOM LISTS »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
-
- ******************* AddEntry() ***********************
-
- NAME
- AddEntry - For adding a string to be displayed in the FileIO's FileList
-
- SYNOPSIS
- ID_num = AddEntry(ID_num, String, FileIO);
- d0 d1 a0 a1
-
- INPUTS
- The FileIO structure
- The address of a NULL-terminated string to become the EntryString.
- A ULONG (or LONG if you define it that way) that is associated with the
- string.
-
- FUNCTION
- When the SPECIAL_REQ flag of the FileIO is set, then DoFileIO() and DoFile-
- IOWindow() no longer do disk operations. Instead, the FileIO's FileList is
- list of FileEntry structures which you create via AddEntry(). The passed
- string becomes the EntryString and the passed ID_num is the EntryID.
-
- RETURN
- This returns the passed ID_num if the string was added to the FileIO's
- FileList, or a -2 if no mem to add the string.
-
-
- ******************* ClearEntries() ***********************
-
- NAME
- ClearEntries - For de-selecting all of the FileIO FileList's FileEntries
-
- SYNOPSIS
- ClearEntries(FileIO);
- a1
-
- INPUTS
- The FileIO structure
-
- FUNCTION
- This clears bit #7 of EntryFlags for all the FileEntry structures in the
- FileIO's FileList. This may be useful for clearing selections after you
- have processed MULTIPLE_FILES within a custom list (SPECIAL_REQ).
-
- RETURN
- NONE
-
-
- ************************ DeleteEntry() **************************
-
- SYNOPSIS
- DeleteEntry( PrevEntry, DeleteEntry, FileIO)
- d1 a0 a1
-
- INPUTS
- The FileIO structure
- Pointer to the entry (Remember structure) to remove
- Pointer to the entry before the entry to remove (Previous entry)
-
- FUNCTION
- Removes DeleteEntry from the list. Needs the PrevEntry which is the
- Remember struct preceding the one to be deleted from the linked list. This
- is used mostly in conjunction with RetrieveEntry() or IsEntryThere().
-
- RETURN
- NONE
-
-
- ************************ FindDeleteEntry() **************************
-
- SYNOPSIS
- FindDeleteEntry(String, FileIO)
- a0 a1
-
- INPUTS
- The FileIO structure
- Pointer to the null-terminated string to find in the list and remove
-
- FUNCTION
- Searches the FileIO's list for the first instance of the string. Case-
- insensitive match. If found, it removes that Remember structure.
-
- RETURN
- NONE
-
-
- ******************* IsEntryThere() **********************
-
- SYNOPSIS
- entrynum = IsEntryThere(String, FileIO)
- d0 a0 a1
-
- INPUTS
- The FileIO structure
- Pointer to null-terminated string to find in the list
-
- RETURN
- Returns the FileEntry number whose string matches the passed string. (Case-
- insensitive). The numbers start from 0 with the first FileEntry structure
- in the FileList being 0. For example, if your string matches the third
- entry in the list, a 2 will be returned. A -1 is returned if the string is
- not in the list. Also, the address of the matching Remember structure is
- stored at the variable ThisEntry (in FileInterface.asm), and the previous
- Remember struct in the list is stored at the variable PrevEntry (or 0 if
- this is the head of the list). These two variables are used with
- DeleteEntry(). For asm programmers, these 2 are returned in a0 and d1.
-
-
- ******************* NewEntryList() ***********************
-
- NAME
- NewEntryList - For freeing any previous FileIO FileList and resetting the
- FileIO variables.
-
- SYNOPSIS
- NewEntryList(FileIO);
- a1
-
- INPUTS
- The FileIO structure
-
- FUNCTION
- This deletes the FileIO's FileList (i.e. all of the FileEntry and Remember
- structures created with AddEntry).
-
- RETURN
- NONE
-
-
- ******************* RetrieveEntry() ***********************
-
- NAME
- RetrieveEntry - For locating the next selected FileEntry structure within
- the FileIO's FileList. (Used with MULTIPLE_FILES selection).
-
- SYNOPSIS
- FileEntry = RetrieveEntry(FileEntryPtr, FileIO);
- d0 a0 a1
-
- INPUTS
- The FileIO structure
- A PTR (the address) to a FileEntry structure within the FileIO's FileList
- or a cleared PTR.
-
- FUNCTION
- When the MULTIPLE_FILES flag of the FileIO is set, then the library sets
- bit #7 of the EntryFlags of every FileEntry that the user selected. This
- routine helps you locate which files were selected, one at a time. The first
- time that you call this function, FileEntryPtr should be cleared so that the
- function will start at the first FileEntry in the FileIO's FileList.
-
- RETURN
- This routine updates FileEntryPtr to point to the next selected FileEntry
- structure, and returns this address. If there is no next selected file, a 0 is
- returned, and FileEntryPtr is cleared. If a FileEntryPtr not equal to 0 is
- returned, you can access the FileEntry's Entry structure to get the EntryID and
- EntryString. This are the FileSize and Filename, respectively. If SPECIAL_REQ
- set, these are the ID and string, respectively. Also, if the returned FileEntry
- is not the first in the list, the variable PrevEntry (in the module FileInter-
- face.asm which you link with your C code) is the address of the previous
- FileEntry. This may be used for DeleteEntry(). If the returned FileEntry is
- the head of the list, PrevEntry will be 0. For asm programmers, the PrevEntry
- address is returned in d1.
-
-
-
- «««««««««««««««««««««««««««««« MISC ROUTINES »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
-
- ************************* AddFileGadgs() ****************************
-
- NAME
- AddFileGadgs - Adds file gadgets to the requester (while opened)
-
-
- SYNOPSIS
- AddFileGadgs(Gadgets, window, requester);
- a0 a2 a5
-
- FUNCTION
- This is used to add gadgets to the requester after it has opened. The most
- logical place to do this would be in a call to your custom StartHandler. To
- remove those gadgets later (while the requester is still open), pass a null
- (0) for Gadgets. The requester and window parameters are the same as the
- library passes to your custom vectors.
- NOTE: The library automatically removes any gadgets that you added when
- the requester disappears.
-
-
- ************************* AutoFileMessage() ****************************
-
- NAME
- AutoFilemessage - AutoMessage with preset strings to choose from
-
-
- SYNOPSIS
- BOOL AutoFileMessage(messagenumber, window);
- d1 a0
-
- FUNCTION
- The requester library has several messages it uses for internal use.
- You can have one of these messages displayed just by passing the number
- of the message you want. See Include file for available messages.
- Some of the messages have two responses "YES" and "OK". Others have just
- the "OK".
-
- INPUTS
- window = the address of a window structure
- messagenumber = number of the string to be displayed
-
- RESULT
- Returns FALSE (d0 = 0) if the user selects "NO" or TRUE (d0 = 1) if the
- user selects "OK".
-
-
- ******************** AutoMessage(), AutoMessageLen() ********************
-
- NAME
- Automessage - an easy implementation of an AutoRequester
-
-
- SYNOPSIS
- AutoMessage(message, window);
- d0 a0
- AutoMessageLen(message, window, length);
- d0 a0 d1
-
- FUNCTION
- This displays the passed string (whose address is in d0) in a simple
- AutoRequester. It manages the dimensions (automatically sizes to the
- passed message) and the IntuiText structure for you. Use AutoMessageLen
- if you know the length of the string to be displayed.
-
- INPUTS
- window = the address of a window structure
- message = address of the string to be displayed
-
- RESULT
- None
-
-
- ************************ AutoPrompt3() **************************
-
- NAME
- AutoPrompt3 - AutoRequester with up to 3 lines of Text
-
-
- SYNOPSIS
- BOOL AutoPrompt3(message1, message2, message3, window);
- a1 a2 a3 a0
-
- FUNCTION
- Displays up to 3 passed strings in an autorequester. Automatically
- dimensions the requester to the size of the longest string, and
- positions the other strings for a symmetrical display. Returns with
- user's response to "YES" or "NO". You can also display only 2 or even
- 1 string if you pass NULL for the other messages.
-
- INPUTS
- window = the address of a window structure
- message1 = address of the top string to be displayed
- message2 = address of the 2nd string to be displayed or NULL if none
- message3 = address of the 3nd string to be displayed or NULL if none
-
- RESULT
- Returns FALSE (d0 = 0) if the user selects "NO" or TRUE (d0 = 1) if the
- user selects "YES".
-
-
- ************************ PutProjIcon() **************************
-
- NAME
- PutProjIcon - Like icon lib's PutIcon, but for image PROJECT icons only
-
-
- SYNOPSIS
- error = PutProjIcon(name, DiskObject);
- a0 a1
-
- FUNCTION
- Most applications only need to save PROJECT icons as opposed to TOOL, or
- DRAWER icons. Furthermore, most programs save image as opposed to border icons.
- This routine is meant to replace the icon.library's PutIcon or PutDiskObject
- for those icons. If the only function in the icon library you use is PutIcon
- or PutDiskObject, you'll definitely want to get rid of your calls to an ugly,
- 6K C library and use this. You need to declare a DiskObject structure.
- Set the GADGHIMAGE bit of the imbedded Gadget's Flags field. The GadgetRender
- and SelectRender should point to initialized Image structs that point to
- the icon data and define its Width, Height, and Depth. Set do_DefaultTool to
- point to your NULL-terminated tool name, or NULL if no default tool. The
- do_ToolTypes and do_DrawerData must be 0.
-
- INPUTS
- name - the name of the icon file to create (the .info will be added later)
- DiskObject - an amigaDOS DiskObject structure
-
- RESULT
- Returns zero if successful. -1 if the icon couldn't be created. -2 if
- a write error (i.e. ran out of space on the disk).
- If an error occurs, the icon file is deleted.
-
-
- ************************ ResetBuffer() *********************************
-
- NAME
- ResetBuffer - Resets the cursor within a StringInfo's buffer to the
- first position. Also, can NULL out the buffer itself and
- reset the number of chars to 0.
-
-
- SYNOPSIS
- ResetBuffer(stringinfo, resetFlag);
- a0 d0
-
- FUNCTION
- If you have a String gadget whose cursor you'd like to set back at the
- first position, you can use this function. Also, if resetFlag is TRUE
- (1) then the gadget's buffer will be NULLED. You must refresh the gadget
- yourself after this call.
-
- INPUTS
- stringinfo = the address of a StringInfo structure
- resetFlag = whether to NULL or not
-
- RESULT
- NONE
-
-
- ************************** SetWaitPointer() *************************
-
- NAME
- SetWaitPointer - Sets the zzz cloud pointer in the passed window.
-
-
- SYNOPSIS
- SetWaitPointer(window);
- a0
-
- FUNCTION
- If you want to have a wait pointer appear in a window, you can use this
- function which already has set up the pointer data in CHIP mem. Then
- when you want to restore the pointer, call Intuition's ClearPointer().
-
- INPUTS
- window = the address of a window structure
-
- RESULT
- None
-
- ************************** Window_BW() *************************
-
- NAME
- Window_BW - Changes the window's colors 0 and 1 to black and white
-
-
- SYNOPSIS
- oldColors = Window_BW(window)
- d0 a0
-
- SYNOPSIS
- If you present the file requester (or any of the auto-requesters) in a
- window where color #0 and #1 are very similiar, the text and graphics for
- the requester will be very difficult to distinguish from the background.
- This scenario is quite possible when loading an ILBM picture into a window
- and then bringing up the requester. Calling this function before DoFileIO()
- will result in your window colors #0 and #1 being changed to black and
- white. When the requester appears, it will be rendered in a satisfactory
- manner. Upon return from DoFileIO, you can then call BW_Restore to restore
- those colors to the original state. Basic users note that these functions
- are called Window.BW and BW.Restore for your use.
-
- RESULTS
- ULONG oldColors - the previous colors as a ULONG
-
-
- ************************** BW_Restore() *************************
-
- NAME
- BW_Restore - Restores the window's colors 0 and 1 to oldColors
-
-
- SYNOPSIS
- BW_Restore(oldColors, window)
- d0 a0
-