home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / dirs / fileio_393.lzh / FileIO / FileIO.doc < prev    next >
Text File  |  1990-10-28  |  85KB  |  1,965 lines

  1. Set your editor's TAB width to 3
  2.  
  3. FileIO Requester
  4. Programmer Manual
  5. Adapted from the Amiga Programmer's Suite Book 1, by RJ Mical
  6. Copyright (C) 1987, Robert J. Mical
  7.  
  8. Additional notes concerning the requester library have been added by
  9. Jeff Glatt who converted the original C into an assembly language library.
  10.  
  11. This section is for the programmer who wants to use the FileIO Requester 
  12. library routines in her or his program.
  13.  
  14. The Workbench names for DOS objects have been used in the FileIO Requester, 
  15. and are used throughout this document for simplicity.  For your reference, 
  16. a directory is referred to as a "drawer" and volumes, or DOS filesystem 
  17. devices, are referred to as "disks".
  18.  
  19. These are the subsections of this section:
  20.  
  21.     o  Basic Operation
  22.  
  23.     o  Multiple FileIO Structures
  24.  
  25.     o  Workbench-style Filename Operations
  26.  
  27.     o  Filtering by Extension
  28.  
  29.     o  No Icon (.info) files
  30.  
  31.     o  FileIO Flags
  32.  
  33.     o  DoFileIO() and DoFileIOWindow() are non-reentrant
  34.  
  35.     o  Procedure for Opening and Using the FileIO Requester library
  36.  
  37.     o  Displaying Lists of Strings (non-disk operation)
  38.  
  39.  
  40. ========================== Basic Operation ============================
  41.  
  42. The FileIO routines base all of their work on a data structure called 
  43. the FileIO structure.  You are allocated one of these structures when you
  44. call the GetFileIO() routine.  The structure is initialized with reasonable
  45. default values for you. Conversely, you can declare and pre-initialize a
  46. FileIO structure as long as all fields are set to zero or an appropriate
  47. value. At the very least, you must set the FileIO's Buffer field to point to
  48. where you want string input stored, and initialize the DrawMode, PenA, and
  49. PenB fields to desired values. The buffer size should be > = 202 bytes.
  50.  
  51. The FileIO structure is used when calling the DoFileIO() and DoFileIOWindow()
  52. routines, which are the routines that actually present the requester to
  53. the user and get the user's filename selection. DoFileIOWindow() is the same
  54. as DoFileIO() except that the former opens a window for the requester. With
  55. DoFileIO(), you must already have a window open.
  56.  
  57. There are several flags and data fields in the FileIO structure that you
  58. may choose to initialize before calling DoFileIO(). By setting or clearing
  59. these flags, you define how information is to be presented to the user.
  60. These flags are described below in "FileIO Flags". Also, the user can
  61. change these flags for each FileIO via the function keys.
  62.  
  63. The DoFileIO() function returns one of 2 values:
  64.  
  65. 1). The address of the buffer where the complete pathname (disk, drawer,
  66.      and filename as one, NULL-terminated string) has been stored. This
  67.      buffer will be the one that you supply in the FileIO's buffer field.
  68. 2). A -1 if the user selected the cancel gadget.
  69.  
  70. The DoFileIOWindow() function may return this additional value:
  71.  
  72. 3). A zero if the window didn't open.
  73.  
  74. You can call these routines any number of times with the same FileIO
  75. structure. Also, your program can have more than one FileIO structure at a
  76. time. An example of why you would want more than one FileIO structure: you
  77. might want to have separate structures for getting input filenames and
  78. output filenames from the user.  Another example:  you might have one
  79. structure for letting the user select text files and another for the
  80. selection of graphics files each with different options/features. Also,
  81. there are some lib routines that do not deal with disk file IO, but use the
  82. FileIO structure nonetheless and you might want a FileIO with a special
  83. string buffer for these routines.
  84.  
  85. Finally, when you're finished with your FileIO structure (usually not until
  86. your program is terminating) then you call ReleaseFileIO() to deallocate all
  87. the resources that it's accumulated. If the FileIO was obtained via
  88. GetFileIO(), this routine also frees it for you.
  89.  
  90.  
  91. ====================== DoFileIO() is non-reentrant ========================
  92.  
  93. The DoFileIO() routine is non-reentrant.  For the sake of memory efficiency,
  94. it uses global data and variables rather than creating local copies of these
  95. for each caller. What this means is that only 1 task can use the library
  96. functions DoFileIO() or DoFileIOWindow() at a time, though all other lib
  97. functions are re-entrant. If you attempt to call DoFileIO() or DoFileIOWindow()
  98. while another task is using it, the library will automatically prompt the
  99. user to type in the complete filename, instead of displaying the requester.
  100. The area where the user types in the filename is in the title bar of the
  101. window where the requester opened. The prompt
  102.  
  103.     Filename >
  104.  
  105.  will be displayed in the window's titlebar, along with a cursor. Several
  106. line editing features are supported including cursor key movement (with the
  107. ability to insert characters), backspace, delete, shift-right and shift-left
  108. cursor to the start and end of the string, and escape. The window's title is
  109. later restored. In fact, this feature of being able to use the title bar for
  110. getting user input can be used with your own prompts. It is a handy alterna-
  111. tive to having a string gadget (which takes up window space and also requires
  112. allocating several structures), plus allows for displaying custom prompts.
  113. The newest version of the lib lets the user scroll to any test beyond the
  114. boundaries of the window title bar borders.
  115.  Note that many tasks can open the library simultaneously, but only 1 can be
  116. displaying the FileIO requester at a given moment.
  117.   This redirection to entering the filename via the title bar is completely
  118. invisible to your application. Upon return from DoFileIO() or DoFileIOWindow()
  119. you will receive one of the 2 (or 3), previously described return values.
  120.  
  121.  
  122. ========== Interpreting the return value of DoFileIO() ================
  123.  
  124.   As mentioned before, there are 3 possible return values from DoFileIOWindow
  125. and 2 returns from DoFileIO(). If there is not enough memory for the window
  126. to open with DoFileIOWindow(), then the return value is 0 and the FileIO's
  127. Errno field = ERR_WINDOW. If this happens, you will have to find another way
  128. to get the filename. If you already have a window open, use DoFileIO(). This
  129. routine will never fail. Alternately, you might have the user type the path
  130. as he would from the CLI, and call ParseString() to put it in the FileIO.
  131.   If the user selects the CANCEL gadget, (or hits ESCAPE when entering the
  132. filename in the titlebar, or RETURN with no chars input), both routines will
  133. return -1.
  134.   In all other cases, the address of the FileIO's Buffer will be returned.
  135. This indicates that the user selected OK, or typed something in the string
  136. gadgets or title bar. This does not mean that the filename is valid for
  137. your purpose though. Let's assume that you called DoFileIO() from a load
  138. routine. Naturally, you want the user to select an existing file to load,
  139. but let's say that he types a non-existant file in the Name gadget or just
  140. selects a disk or drawer without eventually choosing a file before selecting
  141. OK. You can determine what the user did by examining 2 FileIO fields. The
  142. FileIO's Filename buffer contains just the filename portion of the complete
  143. path (separated from all the drawer and disk names). If this buffer is NULL,
  144. then the user did not select a filename. If the buffer is not NULL, then he
  145. either selected a filename, or typed one in. If he typed one in, how do
  146. you know if the filename exists? The FileIO's FileSize field will be 0 if
  147. the filename doesn't exist (or couldn't be examined because the user refused
  148. to mount the file's disk). In this case, you would abort the load. If the
  149. FileSize is not 0, then the file exists and this is how large it is in bytes.
  150. In conclusion, here are the steps you should take for a load routine:
  151.  
  152. 1). Call DoFileIO() with the FileIO's Buffer set to the address of your
  153.      path buffer, and the DrawMode, PenA, and PenB fields initialized.
  154. 2). Examine the return. If -1, then CANCEL. (If 0 for DoFileIOWindow, then
  155.      get the filename another way).
  156. 3). Check the FileIO's filename buffer for NULL. If NULL, then abort load
  157.      posting "This is not a loadable file."
  158. 4). Check the FileIO's FileSize field. If zero, post "File doesn't exist."
  159. 5). Otherwise, use the path buffer to open the file for reading.
  160.  
  161.  Here are the steps you should take for a save routine:
  162.  
  163. 1). Same as load routine step 1
  164. 2). Same as load routine step 2
  165. 3). Check the filename buffer for NULL. If NULL, then abort posting
  166.      "Did not supply a filename."
  167. 4). Check the FileSize field. If it's not 0, then the user must have selected
  168.      a filename that already exists on the chosen disk and in the specified
  169.      drawer. Post "File exists. Should we overwrite it?" Get a yes or no
  170.      response from the user to continue or abort.
  171. 5). Otherwise, use the path buffer to open the file for writing.
  172.  
  173.  
  174. ======================== Internal Error Handling ==========================
  175.  
  176.   The requester is set up so that if the user types in a non-existant disk
  177. name or refuses to mount the chosen disk, the req will default to any other
  178. mounted disk. If no disks mounted, then the default FILEIO_DISKNAME is ":".
  179. For example, assume that the user types "Leroy:" in the disk string gadget, 
  180. but the disk is not in any drive. AmigaDOS will prompt for that disk. If
  181. the user then CANCELs the system prompt, the FileIO req will display the
  182. contents of some other disk that is mounted, adjusting the string gadgets
  183. accordingly. In the case where no disks are mounted, the pathname buffer
  184. that is returned will not contain any disk name.
  185.   If the user types a drawer name that is not in the current dir level, the
  186. req will knock him back to the root of the current dir. For example, assume
  187. that the user is looking inside of a drawer called "TireBiter". There is no
  188. drawer called "George" inside here, but the user types this in the drawer
  189. string gadget nonetheless. The requester will clear ALL the drawer names,
  190. defaulting to the root of the disk.
  191.   The library will not return non-existant disk or drawer names. If you needed
  192. the requester to do this though (maybe you want to pass the path buffer to
  193. CreateDir) then the user should type the "new" drawer name by itself in the
  194. Name gadget. Conversely he could enter the string via the titlebar like so:
  195.  
  196.   WorkBench:Demos/Blort
  197.  
  198.  where you simply treat Blort as a dir name instead of a filename. The lib
  199. will copy Blort to the FileIO's Filename field nonetheless. Just check the
  200. FileSize field to make sure that there isn't a file already named this.
  201.   If there is some error in obtaining the disk name and it defaults to ":",
  202. then the returned pathname will not have a drawer name prepended to it.
  203. For example, say the user typed "df0:" in the drawer string gadget, but the
  204. drive was empty. The requester will automatically default to another mounted
  205. disk/device, etc, until one can be examined, or finally ":" is used. If the
  206. user then types "Papoon" in the Filename Gadget, the returned path will be:
  207.  
  208.   Papoon
  209.  
  210. which will be stored in the FileIO's Filename buffer if its a Filename, or
  211. the FileIO's Drawername buffer if it's a drawer. If it is a Filename that
  212. exists in the current dir, the FileSize will be its size in bytes.
  213.  
  214.  
  215. ================= Quick Display (NO_CARE_REDRAW) ================
  216.  
  217.   The data in the FileIO structure often remains valid between calls to
  218. DoFileIO(), so with subsequent calls a flag has been provided to avoid
  219. reconstructing the filename list. This allows the requester to appear very
  220. quickly because the usually-lengthy process of accessing the disk is avoided.
  221. Other times, it may be necessary to have the requester reconstruct its list
  222. of filenames (i.e. when a disk is changed or a file created/deleted by an
  223. application which does not communicate with the FileIO requester). Perhaps,
  224. as in a save routine, it may not be important to show the user what other
  225. recent files are on the disk as long as proper file protection is provided.
  226. The library uses the NO_CARE_REDRAW flag to discern whether to reconstruct
  227. the list, or simply to use the FileIO's previous names. If you set this flag,
  228. the old list is simply redrawn. Once you set this flag, the list will not
  229. be reconstructed on subsequent calls until you explicitly clear NO_CARE_REDRAW.
  230. (i.e. you always get the same, non-updated list unless the user changes dirs
  231. or disables the feature himself via the Function keys).
  232.     When GetFileIO() creates a FileIO structure for you, this flag is cleared
  233. to specify that the structure doesn't contain an updated list of filenames.
  234. Thus the first call to DoFileIO() causes the filename list to be constructed.
  235. After the call to DoFileIO() is the time to set the flag. You must do a bit
  236. of work if you wish to make use of this feature. You are obliged to watch
  237. for IDCMP events of class DISKINSERTED and to clear the NO_CARE_REDRAW flag
  238. in any of your FileIO structures whenever you see this event. The
  239. DISKINSERTED event occurs when the user has switched around the disks. When
  240. the user has changed disks, you can't be sure that your FileIO's filename
  241. list is still valid, so as a courtesy to the user you must cause the filename
  242. list to be reconstructed. In the case that some disk activity occurs in a
  243. program that doesn't use the FileIO library, you will never know about this
  244. activity. Also, if the disk is changed or files are created/deleted by some
  245. other task using the library, you will have no way to determine this. For
  246. these reasons, you may elect to forgo this feature entirely. If you don't use
  247. this feature, you need not bother looking for DISKINSERTED events. Because
  248. the library has been completely rewritten in optimized assembly, it doesn't
  249. take too long for the requester to construct its list anew. Also, the user
  250. can toggle this feature ON/OFF using function key 6 if he wants. The example
  251. applications don't use this feature. You can use the FileIO Requester library
  252. to get the name of a file to be used for output.  If you do, and the
  253. specified file doesn't currently exist, AmigaDOS will create it anew when
  254. you open it (mode NEWFILE). From the FileIO Requester point of view, this
  255. means that a file now exists that isn't in your FileIO list.  To get the name
  256. in the list, clear the NO_CARE_REDRAW (if it was SET). The next time that
  257. the FileIO structure is used for a call to DoFileIO() or DoFileIOWindow(),
  258. the new file name will appear alphabetized in with the other file names.
  259. Once again, this is not applicable if you don't ever set NO_CARE_REDRAW.
  260.     If you have more than one FileIO structure, remember that you must clear
  261. the NO_CARE_REDRAW flag in all of them whenever you see Intuition's
  262. DISKINSERTED IDCMP event class (if you're using the NO_CARE_REDRAW feature).  
  263. Also, regarding new disks, there's an extra procedure that you must follow.  
  264. If the user changes the disk while you've called DoFileIO() or DoFileIOWindow(),
  265. you won't actually see a DISKINSERTED event (as the event will have been 
  266. processed by the library before control is returned to you). So how will you
  267. know to clear the NO_CARE_REDRAW flag in your other structures?  Well, the
  268. library records the fact that a DISKINSERTED event was handled by setting
  269. the DISK_HAS_CHANGED flag in your FileIO structure. So on return from a call
  270. to DoFileIO() or DoFileIOWindow you should check to see whether your FileIO
  271. structure has the DISK_HAS_CHANGED flag set. If it does, you should clear
  272. the DISK_HAS_CHANGED flag in the structure and then clear the NO_CARE_REDRAW
  273. flag in all of your other FileIO structures.  This assures that when you
  274. call DoFileIO() with any of your other support structures, the filename lists
  275. will be reconstructed, as they should. Please note that all this needs to be
  276. done ONLY IF YOU'RE SETTING NO_CARE_REDRAW.
  277.  
  278.  
  279. =============== Workbench-style Filename Operations ====================
  280.  
  281. You can have file names appear in the FileIO Requester using the same rules
  282. that govern how files appear on the Workbench display, by using the Workbench
  283. .info file mechanism.  
  284.  
  285. To attempt to match Workbench patterns, you must set the WBENCH_MATCH flag
  286. in your FileIO structure, as described below.
  287.  
  288. The Workbench .info file mechanism is a detailed topic that will not be 
  289. delved into here.  Please read the Amiga ROM Kernel Manual for a description
  290. of the Workbench operation and data types.  What follows is a cursory
  291. description of the Workbench technique, which is described only well enough
  292. to explain how you can interact with it via your FileIO structure.  
  293.  
  294. The Workbench program examines the directory of a disk and displays icons
  295. for the files it finds that end with a ".info" suffix (hereafter referred to
  296. as .info files).  The file names displayed beneath the icons have the
  297. ".info" suffix removed.  The Workbench .info files contain information
  298. regarding what type of data is contained in the file (executable program,
  299. project data, et cetera).
  300.  
  301. You can choose to have only .info files displayed to the user (with the
  302. ".info" removed) in the same way that the Workbench does. You get this
  303. by setting the WBENCH_MATCH flag. Any executables without icons (.info files
  304. ) will not be displayed. The same is true of drawers.
  305.  
  306. If you wish, you can further filter the names that appear. There are two
  307. techniques that you can employ for filtering which file names will be added
  308. to the list:  you can ask for only those files that match a particular
  309. Workbench object type and only those files that match a particular tool type.  
  310.  
  311. You elect to match the object type by setting the MATCH_OBJECTTYPE flag in
  312. your FileIO structure.  The object types typically of interest are WBTOOL
  313. and WBPROJECT.  By selecting one of these 2 types, your filename list will
  314. consist only of executable files or data files respectively (except that all
  315. .info drawer names are always displayed). If this is confusing, refer to the
  316. ROM Kernel manual for a discussion of object types.  
  317.  
  318. You can also request to match a Workbench tool type.  By matching tool types,
  319. you can, for instance, have your file list display only those data files
  320. that were created by a specific application.  See the section entitled
  321. "The ToolTypes Array" in the Workbench chapter of the ROM Kernel manual for
  322. a description of how tool types work.  You elect to match tool types by
  323. placing a pointer to the ToolTypes text in the ToolTypes field of your FileIO
  324. structure. If this field is left zero, then the TOOLTYPES will be ignored.
  325.  
  326.  
  327. =========================== No Info Files ============================
  328.  
  329.   Setting the INFO_SUPPRESS flag is exactly the opposite of Workbench
  330. matching. All files that end in .info will be ignored, and not displayed.
  331. This is handy if the user doesn't have a .info file to go with every file
  332. that he wishes to peruse. With WB MATCH, those files would not be displayed.
  333. With INFO_SUPPRESS set, they would be displayed but no .info files would
  334. clutter the display. This gives the impression of WB MATCH while enabling
  335. files without icons to also be seen. On the down side, that means that the
  336. user will see ALL files without icons including those that are best left
  337. alone (i.e. translator.library). All drawers are displayed regardless.
  338. When the user makes his selection, the .info is not added to the pathname.
  339.  
  340.  
  341. ==================== Filtering by Extension =====================
  342.  
  343.     Sometimes, you may have an application that only wants to see filenames
  344. that end with a certain string (i.e. ".iff"). You can specify an extension
  345. by storing the address of this string in the Extension field of the
  346. FileIO. Also, you need to specify the length (don't count the terminating
  347. NULL byte) and store this value in the ExtSize field. For the preceding
  348. example, the length would be 4 (counting the .). Finally, you must set the
  349. EXTENSION_MATCH flag. If the EXTENSION_MATCH flag is clear, the extension
  350. fields will be ignored. In this way, you can quickly enable and disable the
  351. feature with the one flag. Only the files that END with this extension (case
  352. insensitive) will be displayed. Incidentally, this need not be a real exten-
  353. sion. You can match any ending at all. For example, you could only display
  354. those files that end with the string "picture". In this case, the length
  355. would be 7. If you set the EXTENSION_MATCH flag, then clear the INFO_SUPPRESS
  356. flag. Because only those files that end in your specified extension are seen,
  357. .info files won't be displayed anyway (unless your specified extension is
  358. ".info" in which case you'll get nothing but .info files. An icon editor,
  359. maybe?) All drawers will be displayed regardless. Please note that the
  360. extension string that you supply MUST HAVE ALL LETTERS IN LOWER CASE.
  361.   In order for the user to take advantage of this feature via the F4 key,
  362. you must set up the FileIO for it. First you must supply a buffer for the
  363. user's typed extension. Place the address in the FileIO's Extension field.
  364. The buffer must be at least 20 bytes long. Don't enable the EXTENSION_MATCH
  365. flag.
  366.   If you don't want the user to take advantage of extension match, then
  367. clear the EXTENSION_MATCH flag AND zero the Extension pointer field. There
  368. is the possibility that you may have supplied an Extension to be matched
  369. and while the requester was displayed, the user changed the match string.
  370. For this reason, the buffer should always be at least 20 bytes if you use
  371. this feature. Also, don't assume that the returned filename is definitely
  372. ending with the extension you initially passed. If the user changed the
  373. match string, it won't be the same extension. Also, you should re-initialize
  374. your extension buffer string each time before you call DoFileIO(). The
  375. returned pathname and FILEIO_FILENAME buffer have the extension added.
  376.   For SPECIAL_REQ, the extention is ignored.
  377.  
  378. ========================== FileIO Flags ===========================
  379.  
  380.  Remember that the user can always adjust these himself with the function
  381.  keys. For this reason, you might simply go with the defaults.
  382.  
  383. NO_CARE_REDRAW
  384.      This flag designates whether the filename data contained in the 
  385.      FileIO is to be reconstructed before initially drawing the requester.
  386.  
  387. USE_DEVICE_NAMES
  388.      When you leave this flag CLEAR, the AmigaDOS volume names will
  389.      be used for the disk names in the requester.  If you SET
  390.      this flag, the device names will be used instead. The default is to
  391.      follow the Workbench convention and use volume names.
  392.  
  393. DISK_HAS_CHANGED
  394.      If the user changes the disk while the FileIO Requester is being
  395.      displayed, this flag is set in the FileIO structure. The only time you
  396.      must pay attention to this flag is when you have set the NO_CARE_REDRAW
  397.      flag. If you find that DISK_HAS_CHANGED has been set, you must clear
  398.      that flag in this FileIO structure and then clear the NO_CARE_REDRAW
  399.      flag in all of your FileIO structures.
  400.  
  401. DOUBLECLICK_OFF
  402.      Normally, the user can double-click on a filename to select it.  
  403.      You may choose to disable this feature, for instance, when you want the
  404.      user to be very certain about the filename selection (perhaps if the
  405.      file is about to be destroyed, or something equally drastic). To disable
  406.      double-clicking, set the DOUBLECLICK_OFF flag.  Then the user will have
  407.      to explicitly select OK! or type the filename and hit return for the
  408.      selection to be made. Affects SPECIAL_REQ
  409.  
  410. WBENCH_MATCH
  411.      You set this flag to specify that you want Workbench-style .info file
  412.      logic to be used when constructing the filename list. This flag is
  413.      cleared when your FileIO structure is first created.
  414.  
  415. MATCH_OBJECTTYPE
  416.      When you set this flag (and the WBENCH_MATCH flag), the MatchType field
  417.      of your FileIO structure will be compared with the do_Type field of the
  418.      .info file's DiskObject structure.  If they match, the file will be 
  419.      displayed.  Both the MATCH_TOOLTYPE and the MATCH_OBJECTTYPE flags can
  420.      be set at the same time.
  421.  
  422. MULTIPLE_FILES
  423.      Set this flag for multiple filename selection. All selections must be in
  424.      the same directory. You must examine the EntryFlags (selected bit) of
  425.      each Entry structure to determine which files were selected. This flag
  426.      cannot be changed by the user unless an application allows him to do so.
  427.      Affects SPECIAL_REQ
  428.  
  429. INFO_SUPPRESS
  430.      All .info files are suppressed from the display if you SET this.
  431.  
  432. EXTENSION_MATCH
  433.      Filters filenames that end with a certain string if you SET this.
  434.  
  435. CUSTOM_HANDLERS
  436.                  Allows adding custom handlers to the internal library
  437. handlers of GADGETUP, GADGETDOWN, MOUSEMOVE, RAWKEY, DISKINSERTED,
  438. and initial REQSET. You can supply an additional handler for any and all of
  439. these events that will be invoked along with the internal library handler
  440. (or in place of it). Once you call DoFileIO(), the handlers will be installed
  441. and active until the requester ends. Set or Clear this flag before calling
  442. DoFileIO(). If the requester can't open or is being used by another task,
  443. the user will get titlebar entry, and your handlers will be ignored.
  444. Cannot be changed by the user. Affects SPECIAL_REQ
  445.  
  446. NO_ALPHA
  447.       When clear, the filenames are alphabetized in the display. When SET,
  448. newer files are listed at the top of the display. Affects SPECIAL_REQ
  449.  
  450. SPECIAL_REQ
  451.       Allows using the FileIO requester to display lists of strings not
  452. relating to disk drive operations. Cannot be changed by the user.
  453.  
  454.  
  455. ======================= RAM DISK bug ============================
  456.  
  457.     There seems to be a bug in 1.2 AmigaDOS. For some reason, whenever one
  458.     attempts to get an AmigaDOS Lock on the volume named "RAM DISK:" a
  459.     software error occurs.  The problem doesn't necessarily lie in AmigaDOS, 
  460.     but the truth is that the error occurs with little provocation 
  461.     of AmigaDOS (for instance:
  462.           dir "RAM DISK:"
  463.     can and does crash the Amiga).  Though 1.3 resolves this bug, the FileIO
  464.     code provides a work-around for 1.2 by changing "RAM DISK:" to "RAM:"
  465.     which locks successfully and does not crash the machine. This solution
  466.     has a problem:  if the user has given the name  "RAM DISK:" to some
  467.     non-RAM: disk (such as a floppy) then this fix will fail and the floppy
  468.     named "RAM DISK:" wouldn't be seen. This isn't too bad of a problem,
  469.     because if the user has been silly enough to name a floppy "RAM DISK:"
  470.     the user is probably experiencing lots of other problems already and this
  471.     will provide just one more reason why one shouldn't name a floppy 
  472.     "RAM DISK:" don'cha know.
  473.  
  474.  
  475. ======================= Free Disk Space ================================
  476.  
  477.   The FileIO's FREEBYTES field indicates how many free bytes remain on the
  478. disk that the user has chosen. This is useful for a save routine. After all,
  479. you wouldn't want to start saving a 230K file to a disc that only has 229K
  480. free. Unfortunately, AmigaDOG always says that the RAM DISK: has 0 bytes
  481. free. Actually, it has as many bytes free as mem that is available. Whenever
  482. the user selects RAM: or RAM DISK:, the FileIO's FREEBYTES is set to
  483. 0xFFFFFFFF (the largest size possible). If you encounter this condition, you
  484. may wish to use Exec's AvailMem to determine if you can do the save.
  485.  
  486.  
  487. ========== Procedure for Using the FileIO Requester library ===========
  488.  
  489. This section presents a step-by-step procedure for utilizing the FileIO
  490. Requester library with your own program.
  491.  
  492. Copy the requester.library into the libs directory of your boot disk. For
  493. workbench users, double-click on the inclosed program "CopyLib" and place
  494. your Workbench disk in the drive when you see the DOS requester. CopyLib
  495. will display the FileIO requester if all went well. Select the requester's
  496. CANCEL and exit the program by closing the window.
  497.  
  498. You have to include FileIO.h in every C module that refers to your FileIO
  499. structure.
  500.  
  501.      #include "FileIO.h"
  502.  
  503.  For assembly language users, (WOW! We hardly ever get real support for
  504.  programming on the Amiga), include FileIO.i
  505.  
  506. Open the library via a call to exec's OpenLibrary and store the pointer at
  507. a variable called RequesterBase (MUST BE CALLED THIS FOR C PROGRAMMERS).
  508.  
  509.     if (!(RequesterBase = (APTR) OpenLibrary("requester.library", 1L)))
  510.     exit(0);
  511.  
  512. Declare a pointer to a FileIO structure (initialized to 0), and then fill
  513. that pointer with the address of one of the structures.
  514.  
  515.      struct FileIO *myFileIO = 0;
  516.  
  517.      myFileIO = GetFileIO();
  518.  
  519.                      <<<< IF USING NO_CARE_REDRAW >>>>>
  520. Your NewWindow structure should have the DISKINSERTED flag set along with 
  521. your other IDCMP flags.  Whenever you receive a DISKINSERTED event, you 
  522. should clear the NO_CARE_REDRAW flag (if SET) in every FileIO structure you
  523. control.  The following code could be added to the case switch where you 
  524. handle IDCMP events.
  525.  
  526.      switch (imessageclass)
  527.           {
  528.           case DISKINSERTED:
  529.                 /* You should clear the NO_CARE_REDRAW flag
  530.                  * whenever you detect that a new disk was 
  531.                  * inserted.
  532.                  */
  533.                 if (myFileIO)
  534.                      ClearFlag(myFileIO->Flags, NO_CARE_REDRAW);
  535.                 break;
  536.           }
  537.  
  538. Alternately, you may elect to leave NO_CARE_REDRAW clear in which case the
  539. requester display will be updated every time it is used and you won't need
  540. to bother with receiving DISKINSERTED events.
  541.  
  542.   Set the FileIO's Buffer field to the address of a buffer that you have
  543. allocated. This is where the complete path will be constructed for you.
  544. (i.e  Disk:drawer1/drawer2...etc/filename ) Also initialize the FileIO's
  545. DrawMode, PenA, and PenB. You might also want to set the FileIO's X and Y
  546. fields where the requester will open within your window (relative upper left).
  547.  
  548. When you want to present the FileIO Requester to the user, call DoFileIO() or
  549. DoFileIOWindow(). If these routines return the address of the passed buffer
  550. where you want the full path name to be stored, the user did not cancel the
  551. operation, nor was there an error in opening the window (for DoFileIOWindow
  552. only). A -1 and 0 will be returned respectively for the two error conditions.
  553. The following code is an example of presenting the FileIO Requester to the
  554. user and then reacting to the result.
  555.  
  556.   /* This set-up need only be done once, though you can change them later */
  557.  
  558.     UBYTE buffer[204];
  559.  
  560.     myFileIO->Buffer = buffer;
  561.     myFileIO->DrawMode = JAM1;
  562.     myFileIO->PenA = 1;
  563.     myFileIO->PenB = 0;
  564.  
  565.   /* ================================================================ */
  566.  
  567.     if (myFileIO)
  568.     {
  569.          result = (DoFileIO(myFileIO, window));
  570.      if (result==&buffer[0])
  571.          {
  572.                 /* Here, do something like read or write the file.
  573.                  */
  574.               if (writefile)
  575.               {
  576.                 if (myFileIO->FileName[0])
  577.                   {
  578.                     if (!myFileIO->FileSize)
  579.                     {
  580.                      /* Open the file (MODE_NEWFILE) */
  581.                      /* Write the file */
  582.                      /* Close the file */
  583.                     }
  584.                      /* Otherwise, tell the user that he's about to overwrite */
  585.                   }
  586.                      /* Error in entering filename */
  587.               }
  588.               if (readfile)
  589.               {
  590.                 if (myFileIO->FileName[0])
  591.                   {
  592.                   if (myFileIO->FileSize)
  593.                     {
  594.                      /* Open the file (MODE_OLDFILE) */
  595.                      /* Read the file */
  596.                      /* Close the file */
  597.                     }
  598.                      /* Otherwise, tell the user that the file doesn't exist */
  599.                   }
  600.                     /* Not a loadable file */
  601.               }
  602.          }
  603.       if (result==0)
  604.          {
  605.              /* This only happens if DoFileIOWindow() bombs. Call DoFileIO() */
  606.          }
  607.     /* Otherwise, CANCEL must have been selected. Never mind. */
  608.     }
  609.  
  610. Finally, when you're done with your FileIO structure (usually when
  611. your program is exiting), you can free up the structure and its resources
  612. with a simple call to ReleaseFileIO(), like this:
  613.  
  614.      if( RequesterBase ) ReleaseFileIO(myFileIO);
  615.  
  616. Also, you need to close the library upon exit.
  617.  
  618.      if( RequesterBase ) CloseLibrary( RequesterBase );
  619.  
  620.   When you link your C program, you'll need to assemble and link with
  621. FileInterface.asm. This is the usual assembly poot needed by C programs in
  622. order to call assembly language libraries. You want efficiency, write in
  623. assembly. Assembly programmers can simply use the _LVO library offsets as
  624. provided in FileIO.i. See the example applications for details.
  625.  
  626.   ONE FINAL NOTE: The lib needs to trap RIGHT MOUSE buttons for displaying
  627.   the list of disk names. When exiting, the lib clears the RMBTRAP bit of
  628.   your window's flags, so if you had it set before calling DoFileIO(), then
  629.   you'll have to set it again upon return by going to the Flags field of
  630.   your window structure and setting bit #16.
  631.  
  632.  
  633. ============ USING THE REQUESTER TO DISPLAY LISTS OF STRINGS =============
  634.  
  635.     There may be times when you need to display a list of strings in a
  636. requester so that a user can scroll around the list via the mouse and
  637. choose an item in the list. The amount of code and IDCMP hassle of construct-
  638. ing such a requester can certainly be considerable, especially if you want to
  639. include a Prop scroll bar, scroll arrows, a string gadget, CANCEL and OK
  640. gadgets, etc.
  641.     The latest version of the FileIO requester library has a feature whereby
  642. you can use the lib's requester to display your list of strings. The lib
  643. handles all user interaction, list display, and IDCMP. You simply set the
  644. SPECIAL_REQ flag of the FileIO before calling DoFileIO() or DoFileIOWindow()
  645. and the requester will display your list of strings. The requester is no
  646. longer a disk I/O tool. In fact, the Disk and Drawer string gadgets are re-
  647. moved from the display, and the NextDisk gadget no longer has anything to do
  648. with switching dirs.
  649.     The user can employ the Prop and Arrow gadgets (with auto-scroll) to scroll
  650. through the list of strings. The size of the Prop's knob reflects the per-
  651. centage of visible strings just like in the disk I/O version.
  652.     The user can click on any string to make it the currently selected one,
  653. and it will be highlighted and copied to a string gadget below. Or the user
  654. can type his selection directly into the string gadget. A double-click on
  655. a string will end the requester with that string as the chosen one.
  656.     The chosen string will be copied to the FileIO's Filename buffer. Note
  657. that with SPECIAL_REQ, you do not need a Pathname buffer. (In fact, the
  658. FileIO's BUFFER field will be overwritten.)
  659.     With SPECIAL_REQ, DoFileIO() or DoFileIOWindow will return the following:
  660.  
  661.   1). A -1 if the user selected the CANCEL gadget.
  662.   2). A -2 if the library was being used by another task (i.e. the same
  663.         note about non-reentrant code applies here).
  664.   3). A 0 if there is a problem opening the FileIO window (if DoFileIOWindow
  665.         doesn't open, or the requester doesn't open).
  666.   4). The address of the FileIO's Filename buffer (i.e. where the selected
  667.         string is copied) if all went well and the user selected OK, or double-
  668.         clicked on a string, or typed in his selection in the Name gadget.
  669.  
  670.     So how do you give your list of strings to the lib? There are 2 functions,
  671. NewEntryList() and AddEntry() that you use to make the list.
  672. Here are the passed parameters.
  673.  
  674.     EntryNum = AddEntry(ID_num, StringAddress, FileIO);
  675.         d0                         d1            a0                a1
  676.  
  677.     NewEntryList(FileIO);
  678.                         a1
  679.  
  680.     Each FileIO can have its own list attached to it. NewEntryList frees
  681. any previous list (if one exists) that was made for the passed FileIO. For
  682. this reason, you should call NewEntryList first before using AddEntry to
  683. add strings. You can then add strings to the list by subsequent calls
  684. to AddEntry. (AddEntry adds the one passed string into the list. The list is
  685. alphabetized as each string is added to it so that the strings are always
  686. displayed in alphabetical order, unless you set the NO_ALPHA flag. With
  687. NO_ALPHA, each entry is added to the tail of the list.) ID_num is some value
  688. that you want associated with the string. When the user selects that string,
  689. it is copied into the FileIO's Filename buffer and the ID is copied into the
  690. FileIO's FileSize field. This ID is a LONG, and can be any value you desire
  691. (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).
  692.     The returned EntryNum is where the string has been alphabetically placed
  693. in the list (i.e. the first string in the list returns 0). If you receive
  694. a negative number from AddEntry(), this means that there wasn't enough memory
  695. to add the string to the list. Actually, AddEntry copies the string, and
  696. adds the copy to the list, so you need not keep the original string after it
  697. is added to the list.
  698.     When you finally call ReleaseFileIO(), any list associated with the FileIO
  699. is freed.
  700.     Here is how you might create a list with the following 3 items and display
  701. it in the FileIO requester:
  702.  
  703.     /* You should have opened the requester lib and allocated a FileIO */
  704.  
  705.     if (myFileIO)
  706.     {
  707.          NewEntryList(myFileIO);
  708.          error = AddEntry(1L, "This is One", myFileIO);
  709.          if (error<0) break;
  710.          error = AddEntry(2L, "Two", myFileIO);
  711.          if (error<0) break;
  712.          error = AddEntry(3L, "Three", myFileIO);
  713.          if (error<0) break;
  714.  
  715.          result = (DoFileIO(myFileIO, window));
  716.      if (result==myFileIO->FileName)
  717.          {
  718.                 /*  FileName buffer contains the string, and FileSize the ID
  719.                  */
  720.          }
  721.       if (result==0)
  722.          {
  723.              /* This only happens if DoFileIOWindow() bombs. Call DoFileIO() */
  724.          }
  725.       if (result==-2)
  726.          {
  727.              /* This happens if someone is using the library. Come back later */
  728.          }
  729.     /* Otherwise, CANCEL must have been selected. Never mind. */
  730.     }     
  731.  
  732.     There is a possibility that the user may type a string that is not in the
  733. list, directly into the Name gadget. Before exiting, the requester lib will
  734. check if the string is in the list. If not, the string is copied to the
  735. FileIO FileName buffer as before, but the FileSize field is set to -1. A
  736. FileSize of -1 means "this string isn't in the list". That is why you should
  737. not assign an ID of -1 to any string. The lib ignores the case of the string
  738. when comparing items in the list (i.e. "Amiga" and "amIGA" are the same),
  739. but it does not trim away any leading or trailing spaces.
  740.  
  741.     With SPECIAL_REQ, the "Next Disk" gadget can be a custom gadget for your
  742. use. You place into the FileIO's FileIOText field a pointer to the string
  743. that you want displayed in the gadget. This string should be no more than 11
  744. characters (not counting the end NULL). You should pad the head of the
  745. string with spaces to properly center inside the gadget. You should also
  746. store in the FileIO's FileIORoutine field a pointer to a routine that is to
  747. be executed everytime the user releases the mouse over the custom gadget.
  748. The library calls this routine passing the FileIO and Window (that the
  749. requester opened in), and the Requester Structure.
  750.  
  751.     BOOL  yourRoutine(Requester, Window, FileIO)
  752.                               a5             a3        a2
  753.  
  754.     This function should return TRUE to end the requester, or FALSE to continue.
  755. If FALSE, the FileIO display will be refreshed when your function returns. (In
  756. case your custom routine added/removed something from the list, or changed
  757. lists). If you return TRUE, the requester will end with the FileIO's Errno
  758. field set to ERR_APPGADG.
  759.     If your FileIO's FileIORoutine field is set to NULL when you call DoFileIO,
  760. the custom gadget is removed from the display.
  761.  
  762.     Finally, there is a routine that you can use to determine if a certain
  763. string is in the list.
  764.  
  765.     entryNum = IsEntryThere(String, FileIO)
  766.       d0                              a0         a1
  767.     where String is the address of the string you wish to check for.
  768.     This returns the entryNum (like AddEntry) of the string if it is found
  769.     in the list, or a -1 if it is not in the list. For assembly programmers,
  770.     if found, the address of the Remember structure is returned in a0.
  771.  
  772.  
  773. ====================== Filename and Custom Lists =====================
  774.  
  775.     The list of filenames (or custom list created via AddEntry) is created using
  776.     the Intuition function, AllocRemember. The "anchor" of the list is the
  777.     FileIO's FileList field. So each string has its own Remember structure. The
  778.     Remember's rm_Memory points to my own Entry structure. An Entry structure
  779.     looks like this:
  780.  
  781. struct Entry    {
  782.     LONG     EntryID;
  783.     UBYTE  EntryFlags;  /* Don't alter this! */
  784.     UBYTE  EntryString[size of the string not counting end NULL];
  785.     };
  786.  
  787.     In asm,
  788.  
  789. EntryID        dc.l 0
  790. EntryFlags  dc.b 6
  791. EntryString dc.b [the bytes comprising the NULL-terminated string]
  792.  
  793.       I have redefined the Remember structure as a FileEntry structure since
  794. that is easier to reference:
  795.  
  796. struct FileEntry {
  797.     struct FileEntry  *nextEntry;
  798.     ULONG  EntrySize;
  799.     struct Entry      *filePart;
  800.     };
  801.  
  802.  Don't use sizeof on these structures. The library makes them for you. The 3rd
  803.  field of the Entry structure is a variable length, NULL-terminated string.
  804.  This structure has been defined simply so that you can get access to the
  805.  EntryID, EntryFlags, and EntryString. These structures are used for both
  806.  custom lists and the list of filenames. For filenames, each filename has a
  807.  FileEntry structure. Its EntryID is the filesize. Bit #7 of the EntryFlags
  808.  is set if the filename was selected by the user. The EntryString is the
  809.  NULL-terminated filename (separated from its dir). When the SPECIAL_REQ
  810.  flag is set, the Entry's EntryID is your passed ID to AddEntry().
  811.  All the FileEntry structures are linked together, and the FileIO's
  812.  FileList field points to the first FileEntry in the list.
  813.  
  814.     You can use one FileIO to alternately display several custom lists. The key
  815. is to properly set the FileIO's NameCount, NameStart, CurrentPick, and FileList
  816. fields before calling DoFileIO(). You should make a list as in the above
  817. example, and then copy the FileList field to some global. Then zero out the
  818. FileList field. Do this for all your lists. Now when you want to display one
  819. list, pass the appropriate global to a routine that does the following:
  820.     1). Clear the FileList field.
  821.     2). Call NewEntryList() (to initialize the NameStart and CurrentPick)
  822.     3). Set the FileIO's NameCount to the number of items in the list
  823.     4). Set the FileIO's FileList to the passed global.
  824.     5). Set the SPECIAL_REQ flag. (If it wasn't set previously.)
  825.     6). Call DoFileIO()
  826.     7). Clear the FileList field.
  827.  
  828.   Here's a C function to implement the above. It returns TRUE if all went
  829. well, and FALSE if error or user cancel.
  830.  
  831. BOOL ShowList(ListAddr,NumOfItems,window,fileio)
  832. struct Remember *ListAddr; /* the contents of the FileIO's FileList field
  833.                                         after you made the list with AddEntry(). */
  834. SHORT NumOfItems;                /* number of entries in Remember List */  
  835. struct Window *window;
  836. struct FileIO *fileio;
  837. {
  838.     UBYTE *address;
  839.  
  840.     fileio->FileList = 0;  /* you stored the original value in the global ListAddr
  841.                                       after making the list */
  842.     NewEntryList(fileio);
  843.     fileio->NameCount = NumOfItems;
  844.     fileio->FileList = ListAddr;
  845.     SetFlag(fileio->Flags, SPECIAL_REQ);
  846.     address = DoFileIO(fileio, window);
  847.     fileio->FileList = 0; 
  848.     if( address <= 0 )
  849.          return( FALSE );
  850.     else
  851.         return( TRUE );
  852. }
  853.  
  854.     When exiting your program, you must de-Allocate all the lists. For each,
  855.     1). Set the FileIO's FileList to the passed global.
  856.     2). Call NewEntryList()
  857.  
  858.  
  859. void FreeProgList(fileio, filelist)
  860. struct FileIO *fileio;
  861. struct Remember *filelist;
  862. {
  863.     fileio->FileList = filelist;  /* original value you previously stored in global
  864.                                               after making the list */
  865.     NewEntryList(fileio);
  866.     fileio->FileList = 0;
  867. }
  868.  
  869.     Consult the examples, CustomList, for how to use SPECIAL_REQ.
  870.  
  871.  
  872. ========================= Multiple Selections ===========================
  873.  
  874.   You can allow the user to make multiple selections from a custom list or the
  875. filename list by setting the FileIO's MULTIPLE_FILES flag. When the user
  876. clicks on a name, it will be highlighted. The user can then select more
  877. filenames, with all of them simultaneously selected. The library sets bit
  878. #7 of each selected file's Entry structure's EntryFlags. If a user clicks on
  879. a filename that is already selected, then the filename is de-selected. Note
  880. that double-clicking on a filename still can terminate the requester. The
  881. last selected name is the one that appears in the FileIO's FileName buffer.
  882.   When the user double-clicks, or selects CANCEL or OK, the requester ends.
  883. At this point, you must go through the FileIO's FileList, examining each
  884. Entry structure's EntryFlags for bit #7 set to determine which files were
  885. selected. The caveat is that all files must be in the same directory because
  886. the EntryString does not contain the full path, only the filename. (The path
  887. can be constructed with the FileIO's Disk and Drawer buffers.)
  888.   There is a library function to aid in locating the selected files:
  889.  
  890.   FileEntry = RetrieveEntry( FileEntryPtr, FileIO );
  891.         d0                                     a0            a1
  892.  
  893.   FileEntryPtr should point to a FileEntry structure in the FileIO's FileList
  894. or be set to 0. If 0, this routine locates the first selected FileEntry
  895. structure in the FileList, updates the passed FileEntryPtr to point to that
  896. structure, and returns that address. The next time that this function is
  897. called, FileEntryPtr will not be 0, and so this function will return the next
  898. selected FileEntry structure, etc. When there are no more selected files, a 0
  899. is returned and the FileEntryPtr is cleared.
  900.  
  901.   Another function:
  902.  
  903.   ClearEntries(FileIO);
  904.                       a1
  905.  
  906.   clears the selected bit of all EntryFlags in the FileIO's FileList. This is
  907. useful for clearing selections after a custom list has been presented to the
  908. user (especially if the user has set NO_CARE_REDRAW).
  909.  
  910.   If the user types a filename directly into the Filename gadget, the library
  911. will NOT check if the filename is in the current list and set its selected
  912. bit if so. You can determine whether the filename exists in the current dir
  913. by the value of the FILEIO_FILESIZE field as before. For SPECIAL_REQ, the
  914. library DOES set the selected bit if the entered text is one of the displayed
  915. choices.
  916.  
  917.     Consult the examples for how to use MULTIPLE_FILES.
  918.  
  919. =============================================================================
  920. === DEMO PROGRAM NOTES ======================================================
  921. =============================================================================
  922.  
  923. This section briefly describes the demo programs that drive some of the
  924. FileIO Requester library's features. There is a C demo, an assembly demo,
  925. and an AmigaBasic demo (no joke).
  926.  
  927. If you invoke the C or asm demos without a second argument, a window will be
  928. opened in the Workbench screen.  If you invoke these demos with any second
  929. argument, a hi-res screen will be opened for the requester window.
  930.  
  931. The C demo uses two FileIO structures to demonstrate the techniques that you
  932. should use when managing multiple FileIOs. These techniques include processing
  933. DISKINSERTED events and discovering on return from DoFileIO() that the
  934. DISK_HAS_CHANGED flag is set. (As long as you're using the NO_CARE_REDRAW
  935. feature). The first support structure, fileio1, is used in its vanilla state
  936. as created by GetFileIO().  The other support structure, fileio2, is
  937. initialized to do Workbench-style .info file handling where the filename
  938. list will consist of only .info objects of type WBPROJECT. Also, fileio1
  939. uses volume names and the other uses device names. You activate fileio1 when
  940. you click the right mouse button. You activate fileio2 when you press any
  941. key. Finally, when you do any of the selection techniques where you accept 
  942. your selection, the pathname to your selection is displayed in a FileIO
  943. autorequester. If you choose CANCEL to end the FileIO process, nothing happens.
  944. To stop the program, click on the window close gadget (when the requester
  945. is not displayed).
  946.  
  947. The assembly demo only uses 1 FileIO structure. There is a menu to
  948. demonstrate various features. You should manually deselect the features
  949. you want disabled, and select those that you want enabled. For example,
  950. select CUSTOM to see how a custom handler is installed for the REQSET event.
  951. Also, this program can look for files that only end in certain strings if
  952. you select the EXTENSION menu item. When you enable the extension feature,
  953. the application uses the PromptUserEntry() function. Notice how the prompt
  954. appears in the window titlebar with a cursor. You can type in the string
  955. that you want to match, and hit return. Now when you call up the requester,
  956. only those filenames that end in that extension will be displayed (along
  957. with any dirs). This works just like the F4 Function key option.
  958.     Also of interest is the Multiple menu item which toggles MULTIPLE_FILES.
  959. With this on, note how several files can be clicked and selected. When you
  960. select OK, the asm example then prints out the pathbuffer, followed by all
  961. files selected. Note that the selected files do not contain the full path.
  962.  
  963.  
  964. The amigabasic demo asks the user if he wants to display only those files
  965. with a certain extension, and inputs the extension. Otherwise, it suppresses
  966. all .info files. It then copies the pathname to a string variable which can
  967. be better utilized for basic manipulation. Also this demos a few of the
  968. library's autorequester functions. When running this program, the included
  969. bmap for the FileIO requester library must be in the same directory.
  970.  
  971. Additionally, there are examples to demonstrate using the requester to dis-
  972. play custom lists of strings.
  973.  
  974.  
  975. ========================================================================
  976.                          INSTALLING CUSTOM HANDLERS
  977.  
  978.  You can install custom handlers for any of several events that might occur
  979. in the requester. You need to set the CUSTOM_HANDLERS flag of the FileIO, and
  980. fill the FileIO's HandlerBlockPtr field with the address of a HandlerBlock
  981. structure. The HandlerBlock structure (defined in FileIO.h) holds the
  982. addresses of the handlers for REQSET, DISKINSERTED, GADGETDOWN (and UP),
  983. RAWKEY, and MOUSEMOVE. If you have no handler for a particular event, NULL
  984. its HandlerBlock field. Each FileIO can have its own custom handlers.
  985.   For REQSET, and DISKINSERTED, if your handler returns a 1, then the
  986. library's internal handler will be skipped. Otherwise, the library routine
  987. will be executed if you return a 0.
  988.   For GADGETDOWN and GADGETUP, your handler will be called only if the Gadget
  989. ID is not one of the requester's gadgets. Your handler will be passed the ID
  990. in d0 (as well as other parameters). Your handler should return a 0 in order
  991. to continue, or a 1 if you wish to end the requester. (You can check that
  992. your custom handler ended the requester if the FileIO's Errno = ERR_APPGADG).
  993. The only two requester gadgets that the library no longer controls are the CANCEL
  994. and OK gadgets. Control of these two is passed to your custom handler. These
  995. two gadgets have IDs of 32672 and 32673 respectively. If you receive either
  996. of these IDs, you should return a 1. On the other hand, you could simply
  997. cause these gadgets to be ignored by returning a 0. In any event, your
  998. handler will have to return a 1 eventually in order to exit the requester,
  999. or the user would have to type the Filename in the Filename string Gadget.
  1000. Do not use gadget IDs between 32672 to 32682 as these are reserved by the
  1001. library.
  1002.   For MOUSEMOVE, the events are "collected" (i.e. you only receive one event
  1003. when the user stops moving the mouse). Also, you won't receive MOUSEMOVE when
  1004. the user is operating the requester's scroll (prop) gadget. Your handler
  1005. doesn't need a return value.
  1006.   For RAWKEY, you won't receive any function keys. No return value is needed.
  1007.  
  1008.  The requester calls your handler with the following items in these
  1009. registers:
  1010.  
  1011.     a2 - the address of your FileIO
  1012.     a3 - the address of the window in which the requester is open
  1013.     a4 - the IAddress of the event (not valid for REQSET or DISKINSERTED)
  1014.     d6 - MouseX position (for RAWKEY handler, this is the Code instead)
  1015.     d7 - MouseY position (for RAWKEY handler, this is the Qualifier)
  1016.     d2 - Seconds
  1017.     d5 - Micros
  1018.     d0 - (need not be saved) For GADGETUP and DOWN, the gadgetID
  1019.           For RAWKEY handler, the ascii value as returned from DecodeRawkey()
  1020.  
  1021.  You MUST save these registers if you plan on altering them.
  1022.      If your handler is written in C (yech!), I've provided a mechanism for
  1023. receiving these parameters passed on the stack like all good, inefficient C
  1024. programs should. Let's face it, C just doesn't have enough power to do the
  1025. sophisticated, efficient things that we do in assembly. But if you'd like to
  1026. fool yourself into thinking otherwise, I've tried to accomodate your
  1027. delusions. After filling in the HandlerBlock's pointers to the desired
  1028. routines, you must call SetFileIOHandlers(HandlerBlock). This routine
  1029. will see to it that your handler receives the following parameters except
  1030. where previously noted.
  1031.  
  1032.  BOOL yourHandler(IAddress,Window,FileIO,MouseY,MouseX,Micros,Seconds,GadgID);
  1033.  
  1034.   Note that GadgID is the ascii value (UWORD) for the RAWKEY handler.
  1035.  
  1036.   Unfortunately, unlike the assembly implementation, if you want to have
  1037. different FileIO's with unique custom handler routines, you'll have to
  1038. call SetFileIOHandlers() before each call to DoFileIO(). Hey, you're writing
  1039. in C, so you should be used to giving up some flexibility.
  1040.   If you're using Manx small data model, you'll probably have to call geta4
  1041. or savea4 (whatever). a4 will definitely not have the base of your program's
  1042. data section. These are the types of problems you should expect if you allow
  1043. a C compiler to determine 68000 register usage. Also, since register a6 is
  1044. "reserved" for library base vectoring on the Amiga, the C interface to the
  1045. library does not save this register. If your compiled program crashes because
  1046. of this, its time to buy a better compiler, or perhaps solve these headaches
  1047. once and for all with an assembler.
  1048.  
  1049. struct HandlerBlock {
  1050.     APTR  StartUpCode;         /* Called when the requester first opens */
  1051.     APTR  DiskInsertedCode;  /* Called whenever a disk is inserted */
  1052.     APTR  GadgetCode;             /* Called whenever a gadget UP or DOWN */
  1053.     APTR  KeyCode;                 /* Called whenever a rawkey occurs */
  1054.     APTR  MouseMoveCode;         /* Called when the mouse is moved */
  1055.     };
  1056.  
  1057. assembly:
  1058.   dc.l AddrOfStartCode
  1059.   dc.l AddrOfDiskInsertCode
  1060.   dc.l AddrOfGadgetCode
  1061.   dc.l AddrOfRawkeyCode
  1062.   dc.l AddrOfMouseMoveCode
  1063.  
  1064.  
  1065. =============================================================================
  1066. === TECHNICAL REFERENCE =====================================================
  1067. =============================================================================
  1068.  
  1069. The FileIO files include:
  1070.  
  1071.     requester.library          the actual library (slightly < 10K in size)
  1072.     FileIO.doc                  The documentation. You've obviously found it.
  1073.     FileIO.h                      includes for an C application using the library
  1074.     FileInterface.asm          glue routines for a C application to use the
  1075.                                   library. (poot) Expects all integers passed 32bit
  1076.     FileInterface.lobj      A BLink-able object for Lattice C users
  1077.     FileIO.i                      assembly programmer's include file
  1078.     main.c                      an application in C
  1079.     CustomList.c              an C demo using SPECIAL_REQ
  1080.     Test.asm                      an application in assembly
  1081.     CustomList.asm              an asm application using SPECIAL_REQ
  1082.     StartUp.asm                  the startup code for the assembly examples
  1083.     TestFileIO                  an executable of the assembly application
  1084.     MakeTest                      execute this script file to make the asm example
  1085.     BasicFileIO                  an AmigaBasic application (do you believe me now?)
  1086.     BasicString                  an AmigaBasic demo of SPECIAL_REQ
  1087.     requester.bmap              the bmap file for AmigaBasic
  1088.     requester_lib.fd          the fd file used to make the bmap file
  1089.     CopyLib                      a utility to copy libraries to a boot disk
  1090.  
  1091.   Not all of these files are included with this update. Only those files
  1092. which have changed since an earlier PD release have been included.
  1093.  
  1094.  
  1095. ================= USING THE AMIGA PROGRAMMER'S SUITE =======================
  1096.  The following is the message that appeared with RJ Mical's ProSuite code
  1097. on Fred Fish Disc #107. That version of FileIO was not a library. It was a
  1098. C code module that needed to be compiled and linked with your application.
  1099. At this point, the code for this library is significantly different than
  1100. the original, and quite incompatible with R.J's Includes and Defines. Also,
  1101. there are differences in both functionality and features. But R.J. started
  1102. the ball rolling so....
  1103.  
  1104. The Amiga Programmer's Suite Book 1 is copyrighted but freely distributable.
  1105. All copyright notices and all file headers must be retained intact.
  1106. The Amiga Programmer's Suite Book 1 may be compiled and assembled, and the 
  1107. resultant object code may be included in any software product.  However, no 
  1108. portion of the source listings or documentation of the Amiga Programmer's 
  1109. Suite Book 1 may be distributed or sold for profit or in a for-profit
  1110. product without the written authorization of the author, RJ Mical.
  1111.  
  1112. If you use the Amiga Programmer's Suite, I wouldn't mind if you gave me 
  1113. some mention somewhere.
  1114. Good luck!  Program hard, program well.     -RJ Mical
  1115.  
  1116. Make lots of money and become a arrogant, self-serving pain-in-the-ass.
  1117. -Jeff Glatt (my personal philosophy is a bit more philanthropic than RJ's)
  1118.  
  1119.  
  1120. === APPENDIX A:  FileIO Function Calls ======================================
  1121.  
  1122. CONTENTS:
  1123.     AddEntry()
  1124.     AddFileGadgs()
  1125.     AutoMessage()
  1126.     AutoMessageLen()
  1127.     AutoPrompt3()
  1128.     AutoFileMessage()
  1129.     BW_Restore()
  1130.     ClearEntries()
  1131.     DecodeRawkey()
  1132.     DeleteEntry()
  1133.     DoFileIO()            ;only 1 task at a time
  1134.     DoFileIOWindow()  ;only 1 task at a time
  1135.     FindDeleteEntry()
  1136.     GetFullPathname()
  1137.     GetFileIO()
  1138.     GetRawkey()
  1139.     IsEntryThere()
  1140.     NewEntryList()
  1141.     ParseString()
  1142.     PromptUserEntry()
  1143.     PutProjIcon()
  1144.     ReleaseFileIO()
  1145.     ResetBuffer()
  1146.     RetrieveEntry()
  1147.     SetWaitPointer()
  1148.     TypeFilename()
  1149.     UserEntry()
  1150.     Window_BW()
  1151.  
  1152. ««««««««««««««««««««««««««« FILENAME FUNCTIONS »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  1153.  
  1154. *********************** DoFileIO(), DoFileIOWindow() **********************
  1155.  
  1156. NAME
  1157.      DoFileIO  --  Gets a file name for input/output from the user
  1158.      DoFileIOWindow() -- The same, but opens a window for the requester.
  1159.  
  1160. SYNOPSIS
  1161.      ULONG address = DoFileIO(fileio, window);
  1162.                 d0                        a0          a1
  1163.      ULONG address = DoFileIOWindow(fileio, screen);
  1164.                 d0                                a0          a1
  1165.  
  1166. FUNCTION
  1167.      This routine creates a filename requester which allows the user to browse
  1168.      through the AmigaDOS filesystem and select one of the filenames found
  1169.      there.
  1170.  
  1171.      The fileio argument is a pointer to a FileIO structure, which is allo-
  1172.      cated and initialized via a call to GetFileIO(), or declared in your
  1173.      application.
  1174.      You may preset the FileIO parameters before calling this routine, 
  1175.      or you may leave them set at their default values.  See the FileIO
  1176.      documentation and include files for complete details.
  1177.  
  1178.      The window argument is the pointer to the window structure returned
  1179.      by a call to Intuition's OpenWindow() function.  As this routine
  1180.      opens a requester and requesters open in windows, you must have
  1181.      already opened a window before calling this routine, even if it's
  1182.      a window opened for no other purpose than to call this routine.
  1183.      DoFileIOWindow() is provided to circumvent this problem. It simply opens
  1184.      a window on the passed screen before calling DoFileIO, and closes it
  1185.      upon exit. By setting screen to NULL, the window opens on the WorkBench
  1186.      screen. Also, you might use DoFileIOWindow if you wanted a requester
  1187.      that could be moved or depth arranged by the user in an existing screen.
  1188.      The title that appears in the window will be gotten from the address in
  1189.      the FileIO's Title field.
  1190.  
  1191.      You must initialize the FileIO's Buffer field to hold the address of a
  1192.      buffer where the full pathname string (i.e. disk:drawer.../filename) will
  1193.      be constructed. The size should be no less than 202 bytes. Also, the
  1194.      FileIO's DrawMode, PenA, and PenB fields should be set to the values
  1195.      you want restored when the requester closes.
  1196.  
  1197.      This routine returns a 0 if DoFileIOWindow's window couldn't open, a -1
  1198.      if the user selected CANCEL, or the address of the FileIO's Buffer if
  1199.      all went well and the user selected a filename. The full path name will
  1200.      have been constructed in the buffer. The filename itself will have
  1201.      all leading and trailing blanks removed (in case the user typed in a
  1202.      filename with extraneous spaces) and stored in the FileIO's FileName[].
  1203.      Likewise, the disk and drawer names can be found in the text
  1204.      fields DiskName[] and DrawerName[] of the FileIO. You can always call
  1205.      GetFullPathname() to build the pathname from the separate fields of the
  1206.      FileIO.
  1207.  
  1208.      There's a *lot* more to be said about this function.  Please 
  1209.      read the documentation.
  1210.  
  1211.      NOTE:  This routine is not re-entrant.  What this means is that if some
  1212.      other task is calling DoFileIO() or DoFileIOWindow(), this routine
  1213.      will automatically call TypeFilename() for the 2nd application.
  1214.  
  1215. INPUTS (for DoFileIO)
  1216.      fileio = pointer to a FileIO structure, as allocated
  1217.           via a call to GetFileIO()
  1218.  
  1219.      window = pointer to a Window structure, as created via a call
  1220.           to Intuition's OpenWindow()
  1221.  
  1222. RESULT
  1223.      0 if an error in opening DoFileIOWindow() window. You will not get this
  1224.         error for DoFileIO()
  1225.     -1 if the user selected CANCEL
  1226.      the address of the Buffer if all went well and a file was selected. Also
  1227.      for assembly programmers the end of the string is in a1 like GetFullPathname.
  1228.  
  1229. BUGS
  1230.      Clears the RMBTRAP bit of Window's Flags.
  1231.  
  1232.  
  1233. ********************* GetFileIO() ************************
  1234.  
  1235. NAME
  1236.      GetFileIO  --  Allocate and initialize a FileIO structure
  1237.  
  1238.  
  1239. SYNOPSIS
  1240.      struct FileIO *GetFileIO();
  1241.  
  1242.  
  1243. FUNCTION
  1244.      Allocates and initializes a FileIO structure for use with
  1245.      calls to DoFileIO(), DoFileIOWindow(), TypeFileName(), PromptUserEntry().
  1246.  
  1247.      You may want to further initialize the structure before calling these
  1248.      routines. At least the FileIO's Buffer, DrawMode, PenA, and PenB fields
  1249.      should be initialized. Instead of allocating a FileIO via this routine,
  1250.      you may declare one globally or statically as long as all fields are
  1251.      initialized to zero or an approprite value.
  1252.  
  1253.      When you're done with the structure, call ReleaseFileIO() regardless of
  1254.      whether it was allocated or declared to free up resources.
  1255.  
  1256. INPUTS
  1257.      None
  1258.  
  1259. RESULT
  1260.      If all goes well, returns the address of a FileIO structure.
  1261.      If anything goes wrong (out of memory), returns NULL.
  1262.  
  1263.  
  1264. *********************** GetFullPathname() *********************
  1265.  
  1266. NAME
  1267.      GetFullPathname  --  Build a file pathname using a FileIO struct
  1268.  
  1269.  
  1270. SYNOPSIS
  1271.      Buffer = GetFullPathname(FileIO, Buffer);
  1272.       d0                                a0            a1
  1273.  
  1274. FUNCTION
  1275.      Builds the text for a pathname using the FileName[], DrawerName[] and
  1276.      DiskName[] fields of the specified FileIO structure after the structure
  1277.      has been used in a successful call to DoFileIO(), DoFileIOWindow(), or
  1278.      TypeFilename(). Writes the text into the Buffer. 
  1279.  
  1280. INPUTS
  1281.      FileIO = the address of a FileIO structure
  1282.      Buffer = address of the buffer to receive the file pathname
  1283.  
  1284. RESULT
  1285.      The address of the passed buffer. Also, for assembly programmers the
  1286.      address of the terminating NULL is in a1 so you can quickly determine
  1287.      the string length by subtracting d0 from a1 with the result in a1.
  1288.  
  1289.  
  1290. *********************** ParseString() *******************************
  1291.  
  1292. NAME
  1293.   ParseString - Separate a path string into separate components
  1294.  
  1295. SYNOPSIS
  1296.   ParseString(FileIO,String)
  1297.                      a0      a1
  1298.  
  1299. INPUTS
  1300.     The FileIO structure
  1301.     The address of the NULL-terminated path
  1302.  
  1303. FUNCTION
  1304.     This takes the NULL-terminated path as it would be typed on a CLI line
  1305.  
  1306.     Diskname:TopDrawer/....etc.../BottomDrawer/Filename
  1307.  
  1308.     and parses it for "weird" typos or non-existant disk or drawer names.
  1309.     Of course, there may not be any Disk or Drawer names. It then copies the
  1310.     individual components of the Disk, drawer, and filename to the FileIO's
  1311.     respective buffers, and sets the FILEIO_FILESIZE and FILEIO_FREEBYTES
  1312.     fields accordingly. (i.e. If the path turns out to be a drawer or disk
  1313.     only, then FileIO's Filename is NULLED and FileSize = 0. If a non-existant
  1314.     file, it copies the Filename to FileIO, but FileSize = 0. If it is a
  1315.     loadable file, it copies the Filename and sets FileSize accordingly.)
  1316.     The parsed result is placed into the FileIO's Buffer (cannot be the same
  1317.     buffer as the passed string).
  1318.         This is useful for processing the initial argv argument passed to
  1319.     _main for the StartUp code. It will initialize the FileIO buffers to
  1320.     this passed name, and set-up the FileSize and Filename buffer so that
  1321.     it can be determined what kind of object this is. Also, it makes it
  1322.     possible to use the same load routine for the initial passed argv as
  1323.     you would for DoFileIO() or TypeFilename(). For Basic programmer's this
  1324.     can be used to set up the FileIO based upon a string gotten via an Input
  1325.     statement.
  1326.  
  1327.  
  1328. ************************* ReleaseFileIO() **************************
  1329.  
  1330. NAME
  1331.      ReleaseFileIO  --  Release the FileIO structure and all local memory
  1332.  
  1333.  
  1334. SYNOPSIS
  1335.      ReleaseFileIO(fileio);
  1336.                           a1
  1337.  
  1338. FUNCTION
  1339.      Releases the FileIO structure by freeing all local memory attached
  1340.      to the structure and then freeing the structure itself if it is an
  1341.      ALLOCATED_FILEIO (i.e. not pre-initialized in your application).
  1342.      Restores the directory that was established when the FileIO was first
  1343.      sent to DoFileIO() or DoFileIOWindow(). (You should not unlock the
  1344.      initial dir that is contained in the FileIO's originalLock field.)
  1345.  
  1346. INPUTS
  1347.      fileio = the address of a FileIO structure
  1348.  
  1349. RESULT
  1350.      None
  1351.  
  1352.  
  1353. ;********************* TypeFilename() ***************************
  1354.  
  1355. NAME
  1356.      TypeFilename - Uses the window's titlebar to obtain the path name instead
  1357.                          of the file requester (an alternative). Displays the prompt
  1358.                          "Filename >"
  1359.  
  1360. SYNOPSIS
  1361.      buffer =TypeFilename(FileIO, Window);
  1362.                                      a0      a1
  1363.  
  1364. FUNCTION
  1365.     If you really don't like the requester, and would prefer to have the
  1366.     user type in the full path via the window's title bar, then use this.
  1367.     Also, you might use this within a save routine so that the user has to
  1368.     deliberately type his choice. The pathname contained within the FileIO's
  1369.     Disk, Drawer, and Filename fields is what is initially presented to the
  1370.     user. This routine is automatically called if an application tries to
  1371.     call DoFileIO() or DoFileIOWindow() when another task is displaying the
  1372.     FileIO requester. Also called if there is not enough mem to open/display
  1373.     the requester. This routine sets up the FileIO's Disk, Drawer, Filename,
  1374.     FileSize, and FreeBytes fields in the same manner as DoFileIO so that
  1375.     you can interpret the results in exactly the same manner.
  1376.  
  1377. INPUTS
  1378.      Window = the address of a window
  1379.      FileIO = the FileIO structure
  1380.  
  1381. RESULT
  1382.   Returns the address of the FileIO's Buffer or a -1 if the user bailed
  1383.   out without entering anything. An ESC will return -1, but will store an
  1384.   ESC char ($1B) and then NULL char in the buffer.
  1385.  
  1386.  
  1387.  
  1388. «««««««««««««««««««««««««« RAWKEY STRING INPUT »»»»»»»»»»»»»»»»»»»»»»»»»»»»
  1389.  
  1390. ;*************************** DecodeRawkey() ***************************
  1391.  
  1392. NAME
  1393.      DecodeRawkey() - Takes the passed RAWKEY Code and Qualifier and returns
  1394.                             an ascii value based on the System KeyMap.
  1395.  
  1396. SYNOPSIS
  1397.      value = DecodeRawkey(Qualifier, Code);
  1398.                                     d0             a1
  1399.  
  1400. FUNCTION
  1401.      Because there exists different Amiga keyboard configurations and alternate
  1402. keymaps, there are only 2 proper methods for your program to translate user
  1403. keystrokes into ascii chars:
  1404.  
  1405. 1). Use the console device.
  1406. 2). Use VANILLA_KEY IDCMP.
  1407.  
  1408.      The problem with #1 is that you have to deal with the console.device,
  1409. IO blocks, and Function, cursor, and other keys being translated as character
  1410. strings. Very UGLY!!!! The problem with #2 is that you don't receive Function,
  1411. cursor, or Help keystrokes. Very unfriendly!!! This routine solves both pro-
  1412. blems by managing the console device for you, and by "extending" the ascii
  1413. char set, it defines single ascii values for each Function, cursor, and Help
  1414. key.
  1415.  
  1416. INPUTS
  1417.   Code - the code field of a RAWKEY IntuiMessage
  1418.   Qualifier - the qualifier field of a RAWKEY IntuiMessage
  1419.  
  1420. RESULT
  1421.  The return is a UWORD (not a byte as is usually the case with ascii chars).
  1422.  This is because I have "extended" the ascii char set beyond hex FF in order
  1423.  to define values for the Function, cursor, and Help keys. A zero is returned
  1424.  if the key is undefined or if it is a KEYUP event.
  1425.  
  1426.  Plain Function keys return hex 100 to 109 for the 10 keys.
  1427.  The 4 cursor keys are hex 10A to 10D for UP, DOWN, RIGHT, and LEFT
  1428.       respectively.
  1429.  The Help key returns hex 10e.
  1430.  Shifted Function keys return hex 200 to 209.
  1431.  Shifted cursor keys are hex 20A to 20D.
  1432.  Shifted Help key is 20E.
  1433.  Alt Function keys are hex 400 to 409.
  1434.  
  1435.  All other keys (and combos) return whatever value the System KeyMap contains
  1436. (except that all char strings are ignored and return 0).
  1437.  
  1438.  
  1439. ;*************************** UserEntry() ***************************
  1440.  
  1441. NAME
  1442.     UserEntry - Uses the window's titlebar to obtain user input.
  1443.  
  1444. SYNOPSIS
  1445.     buffer = UserEntry(charlimit, initBuffer, FileIO, Window);
  1446.                                     d0              a1            a2          a3
  1447.  
  1448. FUNCTION
  1449.     This clears the window's titlebar, displays a cursor, and allows the user
  1450.     to type in chars up to the limit, or until CR or ESC is pressed. The NULL
  1451.     terminated result is placed in the FileIO's Buffer. When the charlimit is
  1452.     reached, the routine automatically terminates.  You must set the FileIO's
  1453.     PenA, PenB, and DrawMode fields so that these may be restored by the lib
  1454.     when the function is finished.
  1455.     The initBuffer string is what is presented to the user (and what he may
  1456.     edit). The passed window must have RAWKEY IDCMP set, and the FileIO's
  1457.     RawCode field set to 0 in order to use the default decoding routine,
  1458.     GetRawkey(). Otherwise, decoding will be redirected to the routine specified
  1459.     in the FileIO's RawCode field. (Maybe you want VANILLAKEY instead. Or
  1460.     maybe you also want to handle other IDCMP events while "inside" of UserEntry.
  1461.     GetRawkey disposes of all but RAWKEY events. Or maybe you've set up your
  1462.     own custom IDCMP port and RAW handling routine.) Regardless, your RawCode
  1463.     routine must go to the window's IDCMP port to get a message or wait if
  1464.     there is no message. It should handle all IDCMP messages except RAWKEY or
  1465.     VANILLAKEY. If one of these messages, exit with an UWORD representing the
  1466.     character as follows:
  1467.     $20 to $7F for ascii chars, $7F for delete, $08 for BACKSPACE, $0D for
  1468.     RETURN, $1B for ESCAPE, $010C for LEFT Cursor, $010D for Right Cursor,
  1469.     $020C for SHIFT-LEFT Cursor, and $020D for SHIFT-RIGHT Cursor.
  1470.     UserEntry will continue calling your RawCode for each char, and terminate
  1471.     upon receiving an $0D or $1B, or reaching the charlimit.
  1472.     Since the titlebar can hold approx 70 chars between the CLOSEGADGET and
  1473.     FRONT/BACK, the FileIO's Buffer might be set to 70 bytes. It must be at
  1474.     least as big as charlimit. Upon return, your window's title is restored.
  1475.  
  1476. INPUTS
  1477.     Window = the address of a window
  1478.     FileIO = the FileIO structure
  1479.     charlimit = the number of characters to accept from the user
  1480.     initBuffer = the NULL-terminated string to initialize the FileIO's
  1481.                  buffer to, or NULL if no initialization desired
  1482.  
  1483. RESULT
  1484.     Returns the address of the FileIO's Buffer or a 0 if the user bailed
  1485.     out without entering anything. An ESC will return 0, but will store an
  1486.     ESC char ($1B) and then NULL char in the buffer.
  1487.  
  1488.  
  1489. ;******************** PromptUserEntry() ***************************
  1490.  
  1491. NAME
  1492.     PromptUserEntry - Uses the window's titlebar to obtain user input.
  1493.  
  1494. SYNOPSIS
  1495.     buffer = PromptUserEntry(charlimit,prompt,initBuffer,FileIO,Window);
  1496.                                             d0          a0         a1          a2        a3
  1497.  
  1498. FUNCTION
  1499.     This works just like UserEntry except that it first displays the
  1500.     passed prompt string in the titlebar. The FileIO's Buffer should always
  1501.     be greater than the number of chars in the prompt plus charlimit.
  1502.  
  1503. INPUTS
  1504.     Window = the address of a window
  1505.     FileIO = the FileIO structure
  1506.     charlimit = the number of characters to accept from the user
  1507.     buffer = the buffer where the user's input is placed
  1508.     prompt = NULL-terminated prompt to display
  1509.     initBuffer = the NULL-terminated string to initialize the FileIO's
  1510.                 buffer to, or 0 if no initialization desired
  1511.  
  1512. RESULT
  1513.     Returns the address of the FileIO's Buffer or a 0 if the user bailed
  1514.     out without entering anything. An ESC will return 0, but will store an
  1515.     ESC char ($1B) and NULL char in the buffer.
  1516.  
  1517.  
  1518. ******************* SetTitle() ********************************
  1519.  
  1520. NAME
  1521.     SetTitle - Uses the window's titlebar to display 1 or 2 strings.
  1522.  
  1523. SYNOPSIS
  1524.     SetTitle(String1,String2,FileIO,Window);
  1525.                     a0          a1         a2      a3
  1526.  
  1527. INPUTS
  1528.     Window = the address of a window
  1529.     FileIO = the FileIO structure
  1530.     String1 = the NULL-terminated string to the left
  1531.     String2 = NULL-terminated string placed to the right of String1. If you
  1532.                 pass a zero instead, no 2nd string displayed.
  1533.  
  1534. FUNCTION
  1535.     This will display the 2 strings in the window's titlebar (saving the
  1536.     initial title to the FileIO's Title field), and return immediately with
  1537.     the strings still displayed. Subsequent calls can be made to display
  1538.     different strings, but when ResetTitle() is finally called, the initial
  1539.     titlebar is restored. This routine is useful for displaying error msgs to
  1540.     the user without halting program execution (like a requester does), and
  1541.     allows the msg to remain visible for as long as it is needed. Furthermore,
  1542.     it doesn't require that the user respond to it. This function makes temp-
  1543.     orary use of the FileIO's Buffer, so you must supply a buffer whose address
  1544.     is stored at the FileIO Buffer field. This buffer must be large enough to
  1545.     contain both Strings.
  1546.  
  1547.  
  1548. ******************* ResetTitle() ********************************
  1549.  
  1550. NAME
  1551.     ResetTitle - Restores the window's titlebar after calls to SetTitle
  1552.                     (if any calls were made at all)
  1553.  
  1554. SYNOPSIS
  1555.     ResetTitle(FileIO,Window);
  1556.                      a2        a3
  1557.  
  1558. INPUTS
  1559.     Window = the address of a window
  1560.     FileIO = the FileIO structure
  1561.  
  1562. FUNCTION
  1563.     Resets the initial title (stored in FileIO's Title field) if it detects
  1564.     that any calls were made to SetTitle. Otherwise, it does nothing.
  1565.  
  1566.  
  1567. ««««««««««««««««««««««««««««««« CUSTOM LISTS »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  1568.  
  1569. ******************* AddEntry() ***********************
  1570.  
  1571. NAME
  1572.     AddEntry - For adding a string to be displayed in the FileIO's FileList
  1573.  
  1574. SYNOPSIS
  1575.     ID_num = AddEntry(ID_num, String, FileIO);
  1576.         d0                        d1        a0            a1
  1577.  
  1578. INPUTS
  1579.     The FileIO structure
  1580.     The address of a NULL-terminated string to become the EntryString.
  1581.     A ULONG (or LONG if you define it that way) that is associated with the
  1582.         string.
  1583.  
  1584. FUNCTION
  1585.     When the SPECIAL_REQ flag of the FileIO is set, then DoFileIO() and DoFile-
  1586. IOWindow() no longer do disk operations. Instead, the FileIO's FileList is
  1587. list of FileEntry structures which you create via AddEntry(). The passed
  1588. string becomes the EntryString and the passed ID_num is the EntryID.
  1589.  
  1590. RETURN
  1591.     This returns the passed ID_num if the string was added to the FileIO's
  1592. FileList, or a -2 if no mem to add the string.
  1593.  
  1594.  
  1595. ******************* ClearEntries() ***********************
  1596.  
  1597. NAME
  1598.     ClearEntries - For de-selecting all of the FileIO FileList's FileEntries
  1599.  
  1600. SYNOPSIS
  1601.     ClearEntries(FileIO);
  1602.                         a1
  1603.  
  1604. INPUTS
  1605.     The FileIO structure
  1606.  
  1607. FUNCTION
  1608.     This clears bit #7 of EntryFlags for all the FileEntry structures in the
  1609.     FileIO's FileList. This may be useful for clearing selections after you
  1610.     have processed MULTIPLE_FILES within a custom list (SPECIAL_REQ).
  1611.  
  1612. RETURN
  1613.     NONE
  1614.  
  1615.  
  1616. ************************ DeleteEntry() **************************
  1617.  
  1618. SYNOPSIS
  1619.     DeleteEntry( PrevEntry, DeleteEntry, FileIO)
  1620.                         d1                a0                a1
  1621.  
  1622. INPUTS
  1623.     The FileIO structure
  1624.     Pointer to the entry (Remember structure) to remove
  1625.     Pointer to the entry before the entry to remove (Previous entry)
  1626.  
  1627. FUNCTION
  1628.     Removes DeleteEntry from the list. Needs the PrevEntry which is the
  1629.     Remember struct preceding the one to be deleted from the linked list. This
  1630.     is used mostly in conjunction with RetrieveEntry() or IsEntryThere().
  1631.  
  1632. RETURN
  1633.     NONE
  1634.  
  1635.  
  1636. ************************ FindDeleteEntry() **************************
  1637.  
  1638. SYNOPSIS
  1639.     FindDeleteEntry(String, FileIO)
  1640.                             a0            a1
  1641.  
  1642. INPUTS
  1643.     The FileIO structure
  1644.     Pointer to the null-terminated string to find in the list and remove
  1645.  
  1646. FUNCTION
  1647.     Searches the FileIO's list for the first instance of the string. Case-
  1648.     insensitive match. If found, it removes that Remember structure.
  1649.  
  1650. RETURN
  1651.     NONE
  1652.  
  1653.  
  1654. ******************* IsEntryThere() **********************
  1655.  
  1656. SYNOPSIS
  1657.     entrynum = IsEntryThere(String, FileIO)
  1658.         d0                                a0        a1
  1659.  
  1660. INPUTS
  1661.     The FileIO structure
  1662.     Pointer to null-terminated string to find in the list
  1663.  
  1664. RETURN
  1665.     Returns the FileEntry number whose string matches the passed string. (Case-
  1666.     insensitive). The numbers start from 0 with the first FileEntry structure
  1667.     in the FileList being 0. For example, if your string matches the third
  1668.     entry in the list, a 2 will be returned. A -1 is returned if the string is
  1669.     not in the list. Also, the address of the matching Remember structure is
  1670.     stored at the variable ThisEntry (in FileInterface.asm), and the previous
  1671.     Remember struct in the list is stored at the variable PrevEntry (or 0 if
  1672.     this is the head of the list). These two variables are used with
  1673.     DeleteEntry(). For asm programmers, these 2 are returned in a0 and d1.
  1674.  
  1675.  
  1676. ******************* NewEntryList() ***********************
  1677.  
  1678. NAME
  1679.     NewEntryList - For freeing any previous FileIO FileList and resetting the
  1680.                         FileIO variables.
  1681.  
  1682. SYNOPSIS
  1683.     NewEntryList(FileIO);
  1684.                         a1
  1685.  
  1686. INPUTS
  1687.     The FileIO structure
  1688.  
  1689. FUNCTION
  1690.     This deletes the FileIO's FileList (i.e. all of the FileEntry and Remember
  1691.     structures created with AddEntry).
  1692.  
  1693. RETURN
  1694.     NONE
  1695.  
  1696.  
  1697. ******************* RetrieveEntry() ***********************
  1698.  
  1699. NAME
  1700.     RetrieveEntry - For locating the next selected FileEntry structure within
  1701.                         the FileIO's FileList. (Used with MULTIPLE_FILES selection).
  1702.  
  1703. SYNOPSIS
  1704.     FileEntry = RetrieveEntry(FileEntryPtr, FileIO);
  1705.         d0                                    a0                a1
  1706.  
  1707. INPUTS
  1708.     The FileIO structure
  1709.     A PTR (the address) to a FileEntry structure within the FileIO's FileList
  1710.     or a cleared PTR.
  1711.  
  1712. FUNCTION
  1713.     When the MULTIPLE_FILES flag of the FileIO is set, then the library sets
  1714. bit #7 of the EntryFlags of every FileEntry that the user selected. This
  1715. routine helps you locate which files were selected, one at a time. The first
  1716. time that you call this function, FileEntryPtr should be cleared so that the
  1717. function will start at the first FileEntry in the FileIO's FileList.
  1718.  
  1719. RETURN
  1720.     This routine updates FileEntryPtr to point to the next selected FileEntry
  1721. structure, and returns this address. If there is no next selected file, a 0 is
  1722. returned, and FileEntryPtr is cleared. If a FileEntryPtr not equal to 0 is
  1723. returned, you can access the FileEntry's Entry structure to get the EntryID and
  1724. EntryString. This are the FileSize and Filename, respectively. If SPECIAL_REQ
  1725. set, these are the ID and string, respectively. Also, if the returned FileEntry
  1726. is not the first in the list, the variable PrevEntry (in the module FileInter-
  1727. face.asm which you link with your C code) is the address of the previous
  1728. FileEntry. This may be used for DeleteEntry(). If the returned FileEntry is
  1729. the head of the list, PrevEntry will be 0. For asm programmers, the PrevEntry
  1730. address is returned in d1.
  1731.  
  1732.  
  1733.  
  1734. «««««««««««««««««««««««««««««« MISC ROUTINES »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  1735.  
  1736. ************************* AutoFileMessage() ****************************
  1737.  
  1738. NAME
  1739.     AutoFilemessage - AutoMessage with preset strings to choose from
  1740.  
  1741.  
  1742. SYNOPSIS
  1743.     BOOL AutoFileMessage(messagenumber, window);
  1744.                                     d1                 a0
  1745.  
  1746. FUNCTION
  1747.      The requester library has several messages it uses for internal use.
  1748.      You can have one of these messages displayed just by passing the number
  1749.      of the message you want. See Include file for available messages.
  1750.      Some of the messages have two responses "YES" and "OK". Others have just
  1751.      the "OK".
  1752.  
  1753. INPUTS
  1754.     window = the address of a window structure
  1755.     messagenumber = number of the string to be displayed
  1756.  
  1757. RESULT
  1758.     Returns FALSE (d0 = 0) if the user selects "NO" or TRUE (d0 = 1) if the
  1759.     user selects "OK".
  1760.  
  1761.  
  1762. ******************** AutoMessage(), AutoMessageLen() ********************
  1763.  
  1764. NAME
  1765.     Automessage - an easy implementation of an AutoRequester
  1766.  
  1767. SYNOPSIS
  1768.     AutoMessage(message, window);
  1769.                         d0         a0
  1770.     AutoMessageLen(message, window, length);
  1771.                             d0         a0        d1
  1772.  
  1773. FUNCTION
  1774.     This displays the passed string (whose address is in d0) in a simple
  1775.     AutoRequester. It manages the dimensions (automatically sizes to the
  1776.     passed message) and the IntuiText structure for you. Use AutoMessageLen
  1777.     if you know the length of the string to be displayed.
  1778.  
  1779. INPUTS
  1780.     window = the address of a window structure
  1781.     message = address of the string to be displayed
  1782.  
  1783. RESULT
  1784.     None
  1785.  
  1786.  
  1787. ************************ AutoPrompt3() **************************
  1788.  
  1789. NAME
  1790.     AutoPrompt3 - AutoRequester with up to 3 lines of Text
  1791.  
  1792. SYNOPSIS
  1793.     BOOL AutoPrompt3(message1, message2, message3, window);
  1794.                                 a1             a2         a3          a0
  1795.  
  1796. FUNCTION
  1797.     Displays up to 3 passed strings in an autorequester. Automatically
  1798.     dimensions the requester to the size of the longest string, and
  1799.     positions the other strings for a symmetrical display. Returns with
  1800.     user's response to "YES" or "NO". You can also display only 2 or even
  1801.     1 string if you pass NULL for the other messages.
  1802.  
  1803. INPUTS
  1804.     window = the address of a window structure
  1805.     message1 = address of the top string to be displayed
  1806.     message2 = address of the 2nd string to be displayed or NULL if none
  1807.     message3 = address of the 3nd string to be displayed or NULL if none
  1808.  
  1809. RESULT
  1810.     Returns FALSE (d0 = 0) if the user selects "NO" or TRUE (d0 = 1) if the
  1811.     user selects "YES".
  1812.  
  1813.  
  1814. ************************ PutProjIcon() **************************
  1815.  
  1816. NAME
  1817.     PutProjIcon - Like icon lib's PutIcon, but for image PROJECT icons only
  1818.  
  1819.  
  1820. SYNOPSIS
  1821.     error = PutProjIcon(name, DiskObject);
  1822.                                 a0          a1
  1823.  
  1824. FUNCTION
  1825.      Most applications only need to save PROJECT icons as opposed to TOOL, or
  1826. DRAWER icons. Furthermore, most programs save image as opposed to border icons.
  1827. This routine is meant to replace the icon.library's PutIcon or PutDiskObject
  1828. for those icons. If the only function in the icon library you use is PutIcon
  1829. or PutDiskObject, you'll definitely want to get rid of your calls to an ugly,
  1830. 6K C library and use this. You need to declare a DiskObject structure.
  1831. Set the GADGHIMAGE bit of the imbedded Gadget's Flags field. The GadgetRender
  1832. and SelectRender should point to initialized Image structs that point to
  1833. the icon data and define its Width, Height, and Depth. Set do_DefaultTool to
  1834. point to your NULL-terminated tool name, or NULL if no default tool. The
  1835. do_ToolTypes and do_DrawerData must be 0.
  1836.  
  1837. INPUTS
  1838.     name - the name of the icon file to create (the .info will be added later)
  1839.     DiskObject - an amigaDOS DiskObject structure
  1840.  
  1841. RESULT
  1842.     Returns zero if successful. -1 if the icon couldn't be created. -2 if
  1843.     a write error (i.e. ran out of space on the disk).
  1844.     If an error occurs, the icon file is deleted.
  1845.  
  1846.  
  1847. ************************ ResetBuffer() *********************************
  1848.  
  1849. NAME
  1850.     ResetBuffer - Resets the cursor within a StringInfo's buffer to the
  1851.                         first position. Also, can NULL out the buffer itself and
  1852.                         reset the number of chars to 0.
  1853.  
  1854.  
  1855. SYNOPSIS
  1856.     ResetBuffer(stringinfo, resetFlag);
  1857.                          a0              d0
  1858.  
  1859. FUNCTION
  1860.     If you have a String gadget whose cursor you'd like to set back at the
  1861.     first position, you can use this function. Also, if resetFlag is TRUE
  1862.     (1) then the gadget's buffer will be NULLED. You must refresh the gadget
  1863.     yourself after this call.
  1864.  
  1865. INPUTS
  1866.     stringinfo = the address of a StringInfo structure
  1867.     resetFlag = whether to NULL or not
  1868.  
  1869. RESULT
  1870.     NONE
  1871.  
  1872.  
  1873. ************************** SetWaitPointer() *************************
  1874.  
  1875. NAME
  1876.      SetWaitPointer - Sets the zzz cloud pointer in the passed window.
  1877.  
  1878. SYNOPSIS
  1879.      SetWaitPointer(window);
  1880.                           a0
  1881.  
  1882. FUNCTION
  1883.      If you want to have a wait pointer appear in a window, you can use this
  1884.      function which already has set up the pointer data in CHIP mem. Then
  1885.      when you want to restore the pointer, call Intuition's ClearPointer().
  1886.  
  1887. INPUTS
  1888.      window = the address of a window structure
  1889.  
  1890. RESULT
  1891.      None
  1892.  
  1893.  
  1894. ************************** Window_BW() *************************
  1895.  
  1896. NAME
  1897.     Window_BW - Sets colors 0 and 1 to black and white
  1898.  
  1899. SYNOPSIS
  1900.     origColors = Window_BW(window);
  1901.         d0                                a0
  1902.  
  1903. FUNCTION
  1904.     Sometimes, as in loading an IFF picture that has colors 0 and 1 of similiar
  1905.     intensities, it will be difficult to distinguish the text in a requester
  1906.     from the background. Whenever you have an application where this may occur,
  1907.     you should call this routine before DoFileIO() or DoFileIOWindow, or before
  1908.     using any of the auto requester routines. This will set the screen's colors
  1909.     0 and 1 to black and white so that the requester text will be readily visi-
  1910.     ble. This function returns the original colors 0 and 1 as a ULONG. This will
  1911.     be used to restore the original colors later with BW_Restore().
  1912.  
  1913. INPUTS
  1914.     window = the address of a window structure
  1915.  
  1916. RESULT
  1917.     None
  1918.  
  1919. ************************** BW_Restore() *************************
  1920.  
  1921. NAME
  1922.     BW_Restore - Resets colors 0 and 1 to original values
  1923.  
  1924. SYNOPSIS
  1925.     BW_Restore(origColors, window);
  1926.                     d0                a0
  1927.  
  1928. FUNCTION
  1929.     This function restores the original colors altered by Window_BW().
  1930.  
  1931. INPUTS
  1932.     origColors = the return of Window_BW()
  1933.     window = the address of a window structure
  1934.  
  1935. RESULT
  1936.     None
  1937.  
  1938.  
  1939. ************************** AddFileGadgs() *************************
  1940.  
  1941. NAME
  1942.     AddFileGadgs - Allows adding more gadgets to the file/list requester
  1943.  
  1944. SYNOPSIS
  1945.     AddFileGadgs(gadgetPtr, window, req);
  1946.                         a0                a3        a5
  1947.  
  1948. FUNCTION
  1949.     This function allows you to add (or change) gadgets to the file requester
  1950.     once it is open. This is intended to be used from within a CUSTOM_HANDLERS
  1951.     routine, usually the StartHandler. The args window and req are the same
  1952.     args that are passed to your custom handler by the lib. The gadgetPtr is
  1953.     a pointer to the first gadget of the list to be added. When gadget msgs
  1954.     are received by these gadgets (don't use the same ID #'s that the lib gadgs
  1955.     use - see FileIO.h), your custom GadgetHandler will receive that gadget ID
  1956.     #.
  1957.  
  1958. INPUTS
  1959.     gadgetPtr = ptr to the first gadget
  1960.     window = the address of a window structure
  1961.     req = the fileio req structure
  1962.  
  1963. RESULT
  1964.     None
  1965.