home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 230.lha / FileIO_II / manual < prev    next >
Text File  |  1989-04-05  |  75KB  |  1,563 lines

  1. FileIO Requester
  2. User and Programmer Manual
  3. From the Amiga Programmer's Suite Book 1, by RJ Mical
  4. Copyright (C) 1987, Robert J. Mical
  5.  
  6. Additional notes concerning the requester library have been added by
  7. Jeff Glatt who converted the original C into an assembly language library.
  8.  
  9. This document describes the FileIO Requester library, both for users of
  10. the requester and for programmers who will utilize the library.
  11. The main sections of this document are:
  12.  
  13.    o  FROM THE USER'S POINT OF VIEW
  14.  
  15.    o  PROGRAMMER'S REFERENCE
  16.  
  17.    o  DEMO PROGRAM NOTES
  18.  
  19.    o  TECHNICAL REFERENCE
  20.  
  21.    o  USING THE AMIGA PROGRAMMER'S SUITE
  22.  
  23.    o  APPENDIX A:  FileIO Library Function Calls
  24.  
  25.  
  26.  
  27. ============================================================================
  28. === FROM THE USER'S POINT OF VIEW ==========================================
  29. ============================================================================
  30.  
  31. This section presents the FileIO Requester from the user's point of view.  
  32. This is a example of the sort of documentation that might be supplied to the
  33. end user of this FileIO Requester. Simply clip from here to the Programmer's
  34. section, and include this as a chapter in the user manual.
  35.  
  36.  
  37.  
  38. === The FileIO Requester ========================================
  39.  
  40.   This program employs a file requester based upon R.J. Mical's ProSuite
  41. unit, though this library implementation has been modified extensively.
  42.   The FileIO Requester allows you an easy way to select which file you want 
  43. to use for input or output.  The following describes how you go about using 
  44. the FileIO Requester.
  45.  
  46. The FileIO Requester consists of several parts:  
  47.  
  48.    o  the "Select a Name" list which allows you to choose a file name
  49.       simply by scrolling through a list of names until you find the one
  50.       you want, pointing at the name and clicking the left mouse button
  51.  
  52.    o  the OK! gadget which you use to acknowledge that the name you've 
  53.       chosen is the one you wanted
  54.  
  55.    o  3 string gadgets which allow you to type in the name directly rather
  56.       than using the "Select a Name" gadgets to find the file you want 
  57.  
  58.    o  a NEXT DISK gadget which allows you to examine one disk after another 
  59.  
  60.    o  the CANCEL gadget, which you use when you've decided that you don't
  61.       want to select a file after all
  62.  
  63. The "Select a Name" list presents you with a list of file names in the 
  64. current drawer. You use the mouse to scan easily through the list and select
  65. one of the filenames simply by pointing at it and clicking.  
  66.  
  67. The "Select a Name" feature consists of:
  68.  
  69.    o  a box of where some of the list of file names are displayed
  70.  
  71.    o  a slider which lets you scan quickly through the list of files
  72.  
  73.    o  an up gadget and a down gadget which allow you to move through the
  74.       list one filename at a time
  75.  
  76.  
  77. There are 3 types of entries in the list of file names.
  78.  
  79. At the top of the list are the file names that you can choose.  These names
  80. are listed in alphabetical order (case insensitive).  
  81.  
  82. At the bottom of the list there are special entries which allow you to move 
  83. around through the drawers of a disk, much like you move around through 
  84. drawers on the Workbench display.  
  85.  
  86. The entries that start with the ">>>>" characters allow you to "open" a 
  87. drawer and examine the names of the files in that drawer.  For example, when
  88. examining a Workbench disk, at the bottom of the list you would find an
  89. entry that looked like ">>>> Demos" which means that you can go into the
  90. drawer named "Demos".  If you selected ">>>> Demos" you would see, after a
  91. short pause, a new list of file names:  the names of the files that are in
  92. the "Demos" drawer.  
  93.  
  94. In the "Demos" drawer you would also find a special entry,
  95. "<<<< PRIOR DRAWER".  If you select this entry, you will move back to 
  96. the drawer that contained your current drawer.  
  97.  
  98. An alternate way to change drawers is to type the name of the drawer you 
  99. want in the string gadget labeled "Drawer". It is located beneath the 
  100. filename list.  You select the gadget, type in the name, and hit return.
  101. If you type the name of a drawer which does not exist, the FileIO will send
  102. you back to the root directory of that disk. The length of the string that
  103. you type into the drawer gadget is limited to 132 characters. Since AmigaDOS
  104. limits the length of all file, drawer, and disk names to 30 characters, this
  105. means that you can safely nest drawers (one inside of another) up to four
  106. drawers deep. Beyond that, you should make sure that your drawer names are
  107. less than 30 chars each. The FileIO will not allow you to go any deeper after
  108. the drawer gadget has 132 chars in it.
  109.  
  110. Once you have a list of file names to choose from in the file name box, 
  111. there's a slider gadget to help you scroll around through the names. The
  112. slider is to the right of the file names.  It has a knob which you move to
  113. scroll through the names.  The knob will be different sizes depending on the
  114. number of names in the file list.  If the knob is small, this means that you 
  115. can see only a small number of the total file names. The smaller the knob,
  116. the more names there are to see.  On the other hand, if you can see all the
  117. names in the list, the knob will fill up the entire slider and you won't be
  118. able to move it.
  119.  
  120. To view the file names, you "grab" the slider's knob and move it up and down.  
  121. You grab the knob by pointing at it and pressing and HOLDING the left mouse
  122. button.  When you have grabbed the knob, you can move the pointer and scan
  123. quickly through the list of file names.
  124.  
  125. Also, you can view the list of names one page at a time by clicking to either
  126. side (but not on) the slider's knob.  If you want fine control of your
  127. movement through the file list, the up and down arrows let you adjust the
  128. list of names one name at a time. If you hold the mouse button down while on
  129. top of either arrow, the filenames will scroll in that direction. When you
  130. release the button, scrolling stops, but if instead you move off the arrow
  131. before releasing, the scrolling continues. Auto-scroll will continue until
  132. you click on a scrolling filename, or until the end of the list is reached.
  133.  
  134. Once you have found the file name that you want to choose, you select it by
  135. pointing at it and clicking.  When you do this, the name will be highlighted
  136. and it will appear in a box labeled "Name" beneath the list.  When you've
  137. decided that this is really the name you wanted to choose, click on the OK!
  138. gadget.  Another way to tell the program that you're sure you want to select
  139. a certain file name is by double-clicking on the file name in the same way
  140. that you double-click on a Workbench icon.  Double-clicking is exactly the
  141. same as selecting a name and then OK!
  142.  
  143. If you don't want to use the "Select a Name" feature, you can select a name
  144. by clicking on the string gadget labeled "Name", typing the desired filename, 
  145. and then hitting return or clicking on the OK! gadget.  Hitting return after
  146. typing the name you want is the same as selecting OK! You can select and
  147. type into the string gadgets at any time. You don't have to wait for the
  148. wait pointer to change before you hit return! If you type in the name of a
  149. disk that is not mounted, and then refuse to insert it into the drive when
  150. AmigaDOS asks you for it, the FileIO switches to another disk that is
  151. mounted (if another floppy exists).
  152.  
  153. To view the files of a different disk, select the NEXT DISK gadget. When you
  154. do, the name of the next disk is displayed in the Disk string gadget and the
  155. disk is then searched.  If this disk isn't the one you wanted, you can press
  156. NEXT DISK again even though you may be seeing the wait pointer.  You can
  157. press NEXT DISK quickly as many times as you want until you see the name of
  158. the disk you want in the Disk gadget. If you prefer, you can also type the
  159. name of the disk you want directly into the Disk string gadget. If the disk
  160. you want to examine is not in the drive, you may remove the disk that the
  161. requester has last examined (after the light goes out of course), and insert
  162. the desired disk in that drive. Now wait for the requester to automatically
  163. update its display. You should not change disks while the file requester is
  164. drawing the list of filenames. Wait until the requester "settles down" before
  165. removing and inserting disks. After inserting a disk, always wait for the
  166. requester to automatically redraw the list before you click on "Next Disk".
  167. If you do not follow this procedure, the requester may ignore the newly
  168. inserted disk. If this happens, simply remove and reinsert the disk, or type
  169. the name of the drive into the Disk string gadget.
  170.  
  171.  You might notice that the ZZZ-cloud wait pointer looks a little different 
  172. from ones you're used to on the Amiga.  The FileIO Requester's ZZZ-cloud
  173. pointer has a small tab at the top left which allows you to continue 
  174. pointing and making selections even though the ZZZ-cloud is displayed.  
  175. The FileIO Requester's ZZZ-cloud tells you that it's working, but it
  176. doesn't make you wait.
  177.  
  178.   You might notice also that the file names start appearing one by one 
  179. alphabetically in the list.  You can select one of these names even before
  180. all of the names have been added to the list, though this can be a bit
  181. tricky as they move around a lot.  While the list is being built, you can
  182. use the slider to look at what names have already been added. If you see the
  183. name that you want to select, you can stop the building of the file name
  184. list by clicking on a spot inside the requester but outside of all the
  185. gadgets. For instance, if you click above (but not on) the OK! gadget, this
  186. will stop the list from being constructed. Then you can select the name you
  187. want as usual.  To restart the building of the file name list, click on
  188. either the Drawer or Disk string gadget and hit return. You can also stop
  189. the display of filenames temporarily by grabbing and holding the scroll
  190. gadget. When you release, the display will continue.
  191.  
  192.   For some reason, the requester may not be able to open. Maybe another
  193. program is already displaying it. Only one program can be displaying it at a
  194. time. Or perhaps you have used up too much memory. In either case, instead
  195. of a requester, you will see this prompt in the title bar of the window.
  196.  
  197.   Filename >
  198.  
  199.   This will be followed by a cursor and whatever filename you last chose
  200. with the requester. You must now type in the complete name (including the
  201. drive and drawer names) as you would in the CLI. For example,
  202.  
  203.   Extras:BasicDemos/ConvertFD
  204.  
  205.   If the window is not full size, you should move it to the upper left
  206. corner of the monitor display, and resize it to fully open. Then press any
  207. cursor key to redisplay the cursor. If there was no previous filename, then
  208. you will see the ":" current directory sign. Move the cursor past this and
  209. type in the filename that you wish to save or load if it is on the current
  210. disk. Otherwise, you need to type the name of the disk upon which the file
  211. can be found. The disk name goes in front of the ":", and the drawers and
  212. filename go after the ":". (If the file is on the current disk, and in the
  213. current drawer, you only need to type the filename. Otherwise, you must
  214. specify which disk and drawer you really want.) If the filename that is
  215. initially displayed is the one that you want, simply press RETURN.
  216.  
  217.   You can use the cursor keys to move about in the filename, deleting charac-
  218. ters with the delete or backspace keys. Holding the shift key while pressing
  219. the cursor keys will move to the beginning and end of the typed filename.
  220. When you are satisfied with your choice, hit RETURN. Otherwise, hit the
  221. escape key to cancel.
  222.  
  223.   You have the facility to "customize" the requester for each application.
  224. After the requester comes up, the function keys have the following purposes:
  225.  
  226. F1 - Operates the same as selecting the Next Disk gadget.
  227. F2 - Toggles between using the volume name or the device name of the floppy.
  228.      For example, if you place your WorkBench disk in the internal drive
  229.      and you are using volume names, "WorkBench 1.3:" will appear for the
  230.      Disk name. If using device names, "DF0:" will appear instead.
  231. F3 - Any filename that ends in ".info" will not be displayed. To disable
  232.      this feature, select F3 again.
  233. F4 - Only displays filenames that end with a phrase that you provide.
  234.      You will be prompted to enter a string in the title bar of the window.
  235.      If for example, you typed .library, then the requester would display
  236.      all drawers, but only those files that end with .library. The word
  237.      need not be an extension. You could also specify that only files that
  238.      end with the word, picture, be displayed. To disable this feature,
  239.      select F4 again. The program that you are using must support this
  240.      feature for it to work. If the program doesn't support it, F4 will do
  241.      nothing.
  242. F5 - This toggles ON/OFF the facility for double-clicking on a filename to
  243.      select it as your final choise. If OFF, you must click on the
  244.      filename, and then select OK! before the requester will accept your
  245.      choise as final. Otherwise, 2 quick clicks will be the same thing.
  246. F6 - This will cause the requester not to initially reconstruct the filename
  247.      list on subsequent uses. The advantage is that the next time the req-
  248.      uester comes up, the names will appear immediately. The disadvantage is
  249.      that if you save a file, it will not appear in the list until you turn
  250.      this feature back on (momentarily anyway). Turn it on/off by pressing F6.
  251. F7 - WorkBench matching ON/OFF. If ON, this only displays those names that
  252.      end in .info (just like WorkBench does). Also, a prompt asks you whether
  253.      you want only those names that are TOOLS, PROJECTS, or any kind. An example
  254.      of a TOOL is a program that you can run, like NotePad. An example of a
  255.      PROJECT is a data file, like a note you might write using NotePad.
  256.      The names of disks are never displayed in the filename list.
  257. F8 - Not implemented at this point.
  258. F9 - Same as the CANCEL gadget.
  259. F10 - Same as the OK! gadget.
  260.  
  261.  When you customize the requester, it only affects that one application, so
  262. different programs can have different "customized" requesters.
  263.  
  264.  
  265.  
  266. ============================================================================
  267. === PROGRAMMER'S REFERENCE =================================================
  268. ============================================================================
  269.  
  270. This section is for the programmer who wants to use the FileIO Requester 
  271. library routines in her or his program.
  272.  
  273. The Workbench names for DOS objects have been used in the FileIO Requester, 
  274. and are used throughout this document for simplicity.  For your reference, 
  275. a directory is referred to as a "drawer" and volumes, or DOS filesystem 
  276. devices, are referred to as "disks".
  277.  
  278. These are the subsections of this section:
  279.  
  280.    o  Basic Operation
  281.  
  282.    o  Multiple FileIO Structures
  283.  
  284.    o  Workbench-style Filename Operations
  285.  
  286.    o  Filtering by Extension
  287.  
  288.    o  No Icon (.info) files
  289.  
  290.    o  FileIO Flags
  291.  
  292.    o  DoFileIO() and DoFileIOWindow() are non-reentrant
  293.  
  294.    o  Procedure for Opening and Using the FileIO Requester library
  295.  
  296.  
  297. ========================== Basic Operation ============================
  298.  
  299. The FileIO routines base all of their work on a data structure called 
  300. the FileIO structure.  You are allocated one of these structures when you
  301. call the GetFileIO() routine.  The structure is initialized with reasonable
  302. default values for you. Conversely, you can declare and pre-initialize a
  303. FileIO structure as long as all fields are set to zero or an appropriate
  304. value. At the very least, you must set the FileIO's Buffer field to point to
  305. where you want string input stored, and initialize the DrawMode, PenA, and
  306. PenB fields to desired values. The buffer size should be > = 202 bytes.
  307.  
  308. The FileIO structure is used when calling the DoFileIO() and DoFileIOWindow()
  309. routines, which are the routines that actually present the requester to
  310. the user and get the user's filename selection. DoFileIOWindow() is the same
  311. as DoFileIO() except that the former opens a window for the requester. With
  312. DoFileIO(), you must already have a window open.
  313.  
  314. There are several flags and data fields in the FileIO structure that you
  315. may choose to initialize before calling DoFileIO(). By setting or clearing
  316. these flags, you define how information is to be presented to the user.
  317. These flags are described below in "FileIO Flags". Also, the user can
  318. change these flags for each FileIO via the function keys.
  319.  
  320. The DoFileIO() function returns one of 2 values:
  321.  
  322. 1). The address of the buffer where the complete pathname (disk, drawer,
  323.     and filename as one, NULL-terminated string) has been stored. This
  324.     buffer will be the one that you supply in the FileIO's buffer field.
  325. 2). A -1 if the user selected the cancel gadget.
  326.  
  327. The DoFileIOWindow() function may return this additional value:
  328.  
  329. 3). A zero if the window didn't open.
  330.  
  331. You can call these routines any number of times with the same FileIO
  332. structure. Also, your program can have more than one FileIO structure at a
  333. time. An example of why you would want more than one FileIO structure: you
  334. might want to have separate structures for getting input filenames and
  335. output filenames from the user.  Another example:  you might have one
  336. structure for letting the user select text files and another for the
  337. selection of graphics files each with different options/features. Also,
  338. there are some lib routines that do not deal with disk file IO, but use the
  339. FileIO structure nonetheless and you might want a FileIO with a special
  340. string buffer for these routines.
  341.  
  342. Finally, when you're finished with your FileIO structure (usually not until
  343. your program is terminating) then you call ReleaseFileIO() to deallocate all
  344. the resources that it's accumulated. If the FileIO was obtained via
  345. GetFileIO(), this routine also frees it for you.
  346.  
  347. ====================== DoFileIO() is non-reentrant ========================
  348.  
  349. The DoFileIO() routine is non-reentrant.  For the sake of memory efficiency,
  350. it uses global data and variables rather than creating local copies of these
  351. for each caller. What this means is that only 1 task can use the library
  352. functions DoFileIO() or DoFileIOWindow() at a time, though all other lib
  353. functions are re-entrant. If you attempt to call DoFileIO() or DoFileIOWindow()
  354. while another task is using it, the library will automatically prompt the
  355. user to type in the complete filename, instead of displaying the requester.
  356. The area where the user types in the filename is in the title bar of the
  357. window where the requester opened. The prompt
  358.  
  359.    Filename >
  360.  
  361.  will be displayed in the window's titlebar, along with a cursor. Several
  362. line editing features are supported including cursor key movement (with the
  363. ability to insert characters), backspace, delete, shift-right and shift-left
  364. cursor to the start and end of the string, and escape. The window's title is
  365. later restored. In fact, this feature of being able to use the title bar for
  366. getting user input can be used with your own prompts. It is a handy alterna-
  367. tive to having a string gadget (which takes up window space and also requires
  368. allocating several structures), plus allows for displaying custom prompts.
  369.  Note that many tasks can open the library simultaneously, but only 1 can be
  370. displaying the FileIO requester at a given moment.
  371.   This redirection to entering the filename via the title bar is completely
  372. invisible to your application. Upon return from DoFileIO() or DoFileIOWindow()
  373. you will receive one of the 2 (or 3), previously described return values.
  374.  
  375. ========== Interpreting the return value of DoFileIO() ================
  376.  
  377.   As mentioned before, there are 3 possible return values from DoFileIOWindow
  378. and 2 returns from DoFileIO(). If there is not enough memory for the window
  379. to open with DoFileIOWindow(), then the return value is 0 and the FileIO's
  380. Errno field = ERR_WINDOW. If this happens, you will have to find another way
  381. to get the filename. If you already have a window open, use DoFileIO(). This
  382. routine will never fail. Alternately, you might have the user type the path
  383. as he would from the CLI, and call ParseString() to put it in the FileIO.
  384.   If the user selects the CANCEL gadget, (or hits ESCAPE when entering the
  385. filename in the titlebar, or RETURN with no chars input), both routines will
  386. return -1.
  387.   In all other cases, the address of the FileIO's Buffer will be returned.
  388. This indicates that the user selected OK, or typed something in the string
  389. gadgets or title bar. This does not mean that the filename is valid for
  390. your purpose though. Let's assume that you called DoFileIO() from a load
  391. routine. Naturally, you want the user to select an existing file to load,
  392. but let's say that he types a non-existant file in the Name gadget or just
  393. selects a disk or drawer without eventually choosing a file before selecting
  394. OK. You can determine what the user did by examining 2 FileIO fields. The
  395. FileIO's Filename buffer contains just the filename portion of the complete
  396. path (separated from all the drawer and disk names). If this buffer is NULL,
  397. then the user did not select a filename. If the buffer is not NULL, then he
  398. either selected a filename, or typed one in. If he typed one in, how do
  399. you know if the filename exists? The FileIO's FileSize field will be 0 if
  400. the filename doesn't exist (or couldn't be examined because the user refused
  401. to mount the file's disk). In this case, you would abort the load. If the
  402. FileSize is not 0, then the file exists and this is how large it is in bytes.
  403. In conclusion, here are the steps you should take for a load routine:
  404.  
  405. 1). Call DoFileIO() with the FileIO's Buffer set to the address of your
  406.     path buffer, and the DrawMode, PenA, and PenB fields initialized.
  407. 2). Examine the return. If -1, then CANCEL. (If 0 for DoFileIOWindow, then
  408.     get the filename another way).
  409. 3). Check the FileIO's filename buffer for NULL. If NULL, then abort load
  410.     posting "This is not a loadable file."
  411. 4). Check the FileIO's FileSize field. If zero, post "File doesn't exist."
  412. 5). Otherwise, use the path buffer to open the file for reading.
  413.  
  414.  Here are the steps you should take for a save routine:
  415.  
  416. 1). Same as load routine step 1
  417. 2). Same as load routine step 2
  418. 3). Check the filename buffer for NULL. If NULL, then abort posting
  419.     "Did not supply a filename."
  420. 4). Check the FileSize field. If it's not 0, then the user must have selected
  421.     a filename that already exists on the chosen disk and in the specified
  422.     drawer. Post "File exists. Should we overwrite it?" Get a yes or no
  423.     response from the user to continue or abort.
  424. 5). Otherwise, use the path buffer to open the file for writing.
  425.  
  426. ======================== Internal Error Handling ==========================
  427.  
  428. The requester is set up so that if the user types in a non-existant disk
  429. name or refuses to mount the chosen disk, the req will default to any other
  430. mounted disk. If no disks mounted, then the default FILEIO_DISKNAME is ":".
  431. For example, assume that the user types "Leroy:" in the disk string gadget, 
  432. but the disk is not in any drive. AmigaDOS will prompt for that disk. If
  433. the user then CANCELs the system prompt, the FileIO req will display the
  434. contents of some other disk that is mounted, adjusting the string gadgets
  435. accordingly. In the case where no disks are mounted, the pathname buffer
  436. that is returned will not contain any disk name.
  437.   If the user types a drawer name that is not in the current dir level, the
  438. req will knock him back to the root of the current dir. For example, assume
  439. that the user is looking inside of a drawer called "TireBiter". There is no
  440. drawer called "George" inside here, but the user types this in the drawer
  441. string gadget nonetheless. The requester will clear ALL the drawer names,
  442. defaulting to the root of the disk.
  443.   The library will not return non-existant disk or drawer names. If you needed
  444. the requester to do this though (maybe you want to pass the path buffer to
  445. CreateDir) then the user should type the "new" drawer name by itself in the
  446. Name gadget. Conversely he could enter the string via the titlebar like so:
  447.  
  448.   WorkBench:Demos/Blort
  449.  
  450.  where you simply treat Blort as a dir name instead of a filename. The lib
  451. will copy Blort to the FileIO's Filename field nonetheless. Just check the
  452. FileSize field to make sure that there isn't a file already named this.
  453.   If there is some error in obtaining the disk name and it defaults to ":",
  454. then the returned pathname will not have a drawer name prepended to it.
  455. For example, say the user typed "df0:" in the drawer string gadget, but the
  456. drive was empty. The requester will automatically default to another mounted
  457. disk/device, etc, until one can be examined, or finally ":" is used. If the
  458. user then types "Papoon" in the Filename Gadget, the returned path will be:
  459.  
  460.   Papoon
  461.  
  462. which will be stored in the FileIO's Filename buffer if its a Filename, or
  463. the FileIO's Drawername buffer if it's a drawer. If it is a Filename that
  464. exists in the current dir, the FileSize will be its size in bytes.
  465.  
  466. ================= Quick Display (NO_CARE_REDRAW) ================
  467.  
  468. The data in the FileIO structure often remains valid between calls to
  469. DoFileIO(), so with subsequent calls a flag has been provided to avoid
  470. reconstructing the filename list. This allows the requester to appear very
  471. quickly because the usually-lengthy process of accessing the disk is avoided.
  472. Other times, it may be necessary to have the requester reconstruct its list
  473. of filenames (i.e. when a disk is changed or a file created/deleted by an
  474. application which does not communicate with the FileIO requester). Perhaps,
  475. as in a save routine, it may not be important to show the user what other
  476. recent files are on the disk as long as proper file protection is provided.
  477. The library uses the NO_CARE_REDRAW flag to discern whether to reconstruct
  478. the list, or simply to use the FileIO's previous names. If you set this flag,
  479. the old list is simply redrawn. Once you set this flag, the list will not
  480. be reconstructed on subsequent calls until you explicitly clear NO_CARE_REDRAW.
  481. (i.e. you always get the same, non-updated list unless the user changes dirs
  482. or disables the feature himself via the Function keys).
  483.    When GetFileIO() creates a FileIO structure for you, this flag is cleared
  484. to specify that the structure doesn't contain an updated list of filenames.
  485. Thus the first call to DoFileIO() causes the filename list to be constructed.
  486. After the call to DoFileIO() is the time to set the flag. You must do a bit
  487. of work if you wish to make use of this feature. You are obliged to watch
  488. for IDCMP events of class DISKINSERTED and to clear the NO_CARE_REDRAW flag
  489. in any of your FileIO structures whenever you see this event. The
  490. DISKINSERTED event occurs when the user has switched around the disks. When
  491. the user has changed disks, you can't be sure that your FileIO's filename
  492. list is still valid, so as a courtesy to the user you must cause the filename
  493. list to be reconstructed. In the case that some disk activity occurs in a
  494. program that doesn't use the FileIO library, you will never know about this
  495. activity. Also, if the disk is changed or files are created/deleted by some
  496. other task using the library, you will have no way to determine this. For
  497. these reasons, you may elect to forgo this feature entirely. If you don't use
  498. this feature, you need not bother looking for DISKINSERTED events. Because
  499. the library has been completely rewritten in optimized assembly, it doesn't
  500. take too long for the requester to construct its list anew. Also, the user
  501. can toggle this feature ON/OFF using function key 6 if he wants. The example
  502. applications don't use this feature. You can use the FileIO Requester library
  503. to get the name of a file to be used for output.  If you do, and the
  504. specified file doesn't currently exist, AmigaDOS will create it anew when
  505. you open it (mode NEWFILE). From the FileIO Requester point of view, this
  506. means that a file now exists that isn't in your FileIO list.  To get the name
  507. in the list, clear the NO_CARE_REDRAW (if it was SET). The next time that
  508. the FileIO structure is used for a call to DoFileIO() or DoFileIOWindow(),
  509. the new file name will appear alphabetized in with the other file names.
  510. Once again, this is not applicable if you don't ever set NO_CARE_REDRAW.
  511.    If you have more than one FileIO structure, remember that you must clear
  512. the NO_CARE_REDRAW flag in all of them whenever you see Intuition's
  513. DISKINSERTED IDCMP event class (if you're using the NO_CARE_REDRAW feature).  
  514. Also, regarding new disks, there's an extra procedure that you must follow.  
  515. If the user changes the disk while you've called DoFileIO() or DoFileIOWindow(),
  516. you won't actually see a DISKINSERTED event (as the event will have been 
  517. processed by the library before control is returned to you). So how will you
  518. know to clear the NO_CARE_REDRAW flag in your other structures?  Well, the
  519. library records the fact that a DISKINSERTED event was handled by setting
  520. the DISK_HAS_CHANGED flag in your FileIO structure. So on return from a call
  521. to DoFileIO() or DoFileIOWindow you should check to see whether your FileIO
  522. structure has the DISK_HAS_CHANGED flag set. If it does, you should clear
  523. the DISK_HAS_CHANGED flag in the structure and then clear the NO_CARE_REDRAW
  524. flag in all of your other FileIO structures.  This assures that when you
  525. call DoFileIO() with any of your other support structures, the filename lists
  526. will be reconstructed, as they should. Please note that all this needs to be
  527. done ONLY IF YOU'RE SETTING NO_CARE_REDRAW.
  528.  
  529. =============== Workbench-style Filename Operations ====================
  530.  
  531. You can have file names appear in the FileIO Requester using the same rules
  532. that govern how files appear on the Workbench display, by using the Workbench
  533. .info file mechanism.  
  534.  
  535. To attempt to match Workbench patterns, you must set the WBENCH_MATCH flag
  536. in your FileIO structure, as described below.
  537.  
  538. The Workbench .info file mechanism is a detailed topic that will not be 
  539. delved into here.  Please read the Amiga ROM Kernel Manual for a description
  540. of the Workbench operation and data types.  What follows is a cursory
  541. description of the Workbench technique, which is described only well enough
  542. to explain how you can interact with it via your FileIO structure.  
  543.  
  544. The Workbench program examines the directory of a disk and displays icons
  545. for the files it finds that end with a ".info" suffix (hereafter referred to
  546. as .info files).  The file names displayed beneath the icons have the
  547. ".info" suffix removed.  The Workbench .info files contain information
  548. regarding what type of data is contained in the file (executable program,
  549. project data, et cetera).
  550.  
  551. You can choose to have only .info files displayed to the user (with the
  552. ".info" removed) in the same way that the Workbench does. You get this
  553. by setting the WBENCH_MATCH flag. Any executables without icons (.info files
  554. ) will not be displayed. The same is true of drawers.
  555.  
  556. If you wish, you can further filter the names that appear. There are two
  557. techniques that you can employ for filtering which file names will be added
  558. to the list:  you can ask for only those files that match a particular
  559. Workbench object type and only those files that match a particular tool type.  
  560.  
  561. You elect to match the object type by setting the MATCH_OBJECTTYPE flag in
  562. your FileIO structure.  The object types typically of interest are WBTOOL
  563. and WBPROJECT.  By selecting one of these 2 types, your filename list will
  564. consist only of executable files or data files respectively (except that all
  565. .info drawer names are always displayed). If this is confusing, refer to the
  566. ROM Kernel manual for a discussion of object types.  
  567.  
  568. You can also request to match a Workbench tool type.  By matching tool types,
  569. you can, for instance, have your file list display only those data files
  570. that were created by a specific application.  See the section entitled
  571. "The ToolTypes Array" in the Workbench chapter of the ROM Kernel manual for
  572. a description of how tool types work.  You elect to match tool types by
  573. setting the MATCH_TOOLTYPES flag in your FileIO structure.  A pointer to the
  574. ToolTypes text that you must supply should be stored in the ToolTypesText
  575. field of your FileIO structure.
  576.  
  577. =========================== No Info Files ============================
  578.  
  579.   Setting the INFO_SUPPRESS flag is exactly the opposite of Workbench
  580. matching. All files that end in .info will be ignored, and not displayed.
  581. This is handy if the user doesn't have a .info file to go with every file
  582. that he wishes to peruse. With WB MATCH, those files would not be displayed.
  583. With INFO_SUPPRESS set, they would be displayed but no .info files would
  584. clutter the display. This gives the impression of WB MATCH while enabling
  585. files without icons to also be seen. On the down side, that means that the
  586. user will see ALL files without icons including those that are best left
  587. alone (i.e. translator.library). All drawers are displayed regardless.
  588. When the user makes his selection, the .info is not added to the pathname.
  589.  
  590. ==================== Filtering by Extension =====================
  591.  
  592.    Sometimes, you may have an application that only wants to see filenames
  593. that end with a certain string (i.e. ".iff"). You can specify an extension
  594. by storing the address of this string in the Extension field of the
  595. FileIO. Also, you need to specify the length (don't count the terminating
  596. NULL byte) and store this value in the ExtSize field. For the preceding
  597. example, the length would be 4 (counting the .). Finally, you must set the
  598. EXTENSION_MATCH flag. If the EXTENSION_MATCH flag is clear, the extension
  599. fields will be ignored. In this way, you can quickly enable and disable the
  600. feature with the one flag. Only the files that END with this extension (case
  601. insensitive) will be displayed. Incidentally, this need not be a real exten-
  602. sion. You can match any ending at all. For example, you could only display
  603. those files that end with the string "picture". In this case, the length
  604. would be 7. If you set the EXTENSION_MATCH flag, then clear the INFO_SUPPRESS
  605. flag. Because only those files that end in your specified extension are seen,
  606. .info files won't be displayed anyway (unless your specified extension is
  607. ".INFO" in which case you'll get nothing but .info files. An icon editor,
  608. maybe?) All drawers will be displayed regardless. Please note that the
  609. extension string that you supply MUST HAVE ALL LETTERS IN LOWER CASE.
  610.   In order for the user to take advantage of this feature via the F4 key,
  611. you must set up the FileIO for it. First you must supply a buffer for the
  612. user's typed extension. Place the address in the FileIO's Extension field.
  613. The buffer must be at least 20 bytes long. Don't enable the EXTENSION_MATCH
  614. flag.
  615.   If you don't want the user to take advantage of extension match, then
  616. clear the EXTENSION_MATCH flag AND zero the Extension pointer field. There
  617. is the possibility that you may have supplied an Extension to be matched
  618. and while the requester was displayed, the user changed the match string.
  619. For this reason, the buffer should always be at least 20 bytes if you use
  620. this feature. Also, don't assume that the returned filename is definitely
  621. ending with the extension you initially passed. If the user changed the
  622. match string, it won't be the same extension. Also, you should re-initialize
  623. your extension buffer string each time that you call DoFileIO(). The
  624. returned pathname and FILEIO_FILENAME buffer have the extension added.
  625.  
  626. ========================== FileIO Flags ===========================
  627.  
  628.  Remember that the user can always adjust these himself with the function
  629.  keys. For this reason, you might simply go with the defaults.
  630.  
  631. NO_CARE_REDRAW
  632.     This flag designates whether the filename data contained in the 
  633.     FileIO is to be reconstructed before initially drawing the requester.
  634.  
  635. USE_DEVICE_NAMES
  636.     When you leave this flag CLEAR, the AmigaDOS volume names will
  637.     be used for the disk names in the requester.  If you SET
  638.     this flag, the device names will be used instead. The default is to
  639.     follow the Workbench convention and use volume names.
  640.  
  641. DISK_HAS_CHANGED
  642.     If the user changes the disk while the FileIO Requester is being
  643.     displayed, this flag is set in the FileIO structure. The only time you
  644.     must pay attention to this flag is when you have set the NO_CARE_REDRAW
  645.     flag. If you find that DISK_HAS_CHANGED has been set, you must clear
  646.     that flag in this FileIO structure and then clear the NO_CARE_REDRAW
  647.     flag in all of your FileIO structures.
  648.  
  649. DOUBLECLICK_OFF
  650.     Normally, the user can double-click on a filename to select it.  
  651.     You may choose to disable this feature, for instance, when you want the
  652.     user to be very certain about the filename selection (perhaps if the
  653.     file is about to be destroyed, or something equally drastic). To disable
  654.     double-clicking, set the DOUBLECLICK_OFF flag.  Then the user will have
  655.     to explicitly select OK! or type the filename and hit return for the
  656.     selection to be made.
  657.  
  658. WBENCH_MATCH
  659.     You set this flag to specify that you want Workbench-style .info file
  660.     logic to be used when constructing the filename list. This flag is
  661.     cleared when your FileIO structure is first created.
  662.  
  663. MATCH_OBJECTTYPE
  664.     When you set this flag (and the WBENCH_MATCH flag), the MatchType field
  665.     of your FileIO structure will be compared with the do_Type field of the
  666.     .info file's DiskObject structure.  If they match, the file will be 
  667.     displayed.  Both the MATCH_TOOLTYPE and the MATCH_OBJECTTYPE flags can
  668.     be set at the same time.
  669.  
  670. MATCH_TOOLTYPE
  671.     If you set this flag (and the WBENCH_MATCH flag), then Workbench-style
  672.     ToolType pattern matching will be performed and must be successful
  673.     before the filename will be included in the list.  You specify your
  674.     selection of ToolType in the FileIO structure's ToolType pointer field.
  675.     Both the MATCH_TOOLTYPE and the MATCH_OBJECTTYPE flags can be set at 
  676.     the same time.
  677.  
  678. INFO_SUPPRESS
  679.     All .info files are suppressed from the display if you SET this.
  680.  
  681. EXTENSION_MATCH
  682.     Filters filenames that end with a certain string if you SET this.
  683.  
  684. CUSTOM_HANDLERS
  685.              Allows adding custom handlers to the internal, library
  686. handlers of GADGETUP, GADGETDOWN, MOUSEBUTTON, RAWKEY, DISKINSERTED,
  687. and initial REQSET. You can supply an additional handler for any and all of
  688. these events that will be invoked along with the internal library handler
  689. (or in place of it). Once you call DoFileIO(), the handlers will be installed
  690. and active until the requester ends. Set or Clear this flag before calling
  691. DoFileIO(). If the requester can't open or is being used by another task,
  692. the user will get titlebar entry, and your handlers will be ignored.
  693.  
  694. ======================= RAM DISK bug ============================
  695.  
  696.    There seems to be a bug in 1.2 AmigaDOS. For some reason, whenever one
  697.    attempts to get an AmigaDOS Lock on the volume named "RAM DISK:" a
  698.    software error occurs.  The problem doesn't necessarily lie in AmigaDOS, 
  699.    but the truth is that the error occurs with little provocation 
  700.    of AmigaDOS (for instance:
  701.         dir "RAM DISK:"
  702.    can and does crash the Amiga).  Though 1.3 resolves this bug, the FileIO
  703.    code provides a work-around for 1.2 by changing "RAM DISK:" to "RAM:"
  704.    which locks successfully and does not crash the machine. This solution
  705.    has a problem:  if the user has given the name  "RAM DISK:" to some
  706.    non-RAM: disk (such as a floppy) then this fix will fail and the floppy
  707.    named "RAM DISK:" wouldn't be seen. This isn't too bad of a problem,
  708.    because if the user has been silly enough to name a floppy "RAM DISK:"
  709.    the user is probably experiencing lots of other problems already and this
  710.    will provide just one more reason why one shouldn't name a floppy 
  711.    "RAM DISK:" don'cha know.
  712.  
  713. ======================= Free Disk Space ================================
  714.  
  715.   The FileIO's FREEBYTES field indicates how many free bytes remain on the
  716. disk that the user has chosen. This is useful for a save routine. After all,
  717. you wouldn't want to start saving a 230K file to a disc that only has 229K
  718. free. Unfortunately, AmigaDOG always says that the RAM DISK: has 0 bytes
  719. free. Actually, it has as many bytes free as mem that is available. Whenever
  720. the user selects RAM: or RAM DISK:, the FileIO's FREEBYTES is set to
  721. 0xFFFFFFFF (the largest size possible). If you encounter this condition, you
  722. may wish to use Exec's AvailMem to determine if you can do the save.
  723.  
  724. ========== Procedure for Using the FileIO Requester library ===========
  725.  
  726. This section presents a step-by-step procedure for utilizing the FileIO
  727. Requester library with your own program.
  728.  
  729. Copy the requester.library into the libs directory of your boot disk. For
  730. workbench users, double-click on the inclosed program "CopyLib" and place
  731. your Workbench disk in the drive when you see the DOS requester. CopyLib
  732. will display the FileIO requester if all went well. Select the requester's
  733. CANCEL and exit the program by closing the window.
  734.  
  735. You have to include FileIO.h in every C module that refers to your FileIO
  736. structure.
  737.  
  738.     #include "FileIO.h"
  739.  
  740.  For assembly language users, (WOW! We hardly ever get real support for
  741.  programming on the Amiga), include FileIO.i
  742.  
  743. Open the library via a call to exec's OpenLibrary and store the pointer at
  744. a variable called RequesterBase (MUST BE CALLED THIS FOR C PROGRAMMERS).
  745.  
  746.    if (!(RequesterBase = (APTR) OpenLibrary("requester.library", 0L)))
  747.    exit(0);
  748.  
  749. Declare a pointer to a FileIO structure (initialized to 0), and then fill
  750. that pointer with the address of one of the structures.
  751.  
  752.     struct FileIO *myFileIO = 0;
  753.  
  754.     myFileIO = GetFileIO();
  755.  
  756.                 <<<< IF USING NO_CARE_REDRAW >>>>>
  757. Your NewWindow structure should have the DISKINSERTED flag set along with 
  758. your other IDCMP flags.  Whenever you receive a DISKINSERTED event, you 
  759. should clear the NO_CARE_REDRAW flag (if SET) in every FileIO structure you
  760. control.  The following code could be added to the case switch where you 
  761. handle IDCMP events.
  762.  
  763.     switch (imessageclass)
  764.         {
  765.         case DISKINSERTED:
  766.             /* You should clear the NO_CARE_REDRAW flag
  767.              * whenever you detect that a new disk was 
  768.              * inserted.
  769.              */
  770.             if (myFileIO)
  771.                 ClearFlag(myFileIO->Flags, NO_CARE_REDRAW);
  772.             break;
  773.         }
  774.  
  775. Alternately, you may elect to leave NO_CARE_REDRAW clear in which case the
  776. requester display will be updated every time it is used and you won't need
  777. to bother with receiving DISKINSERTED events.
  778.  
  779.   Set the FileIO's Buffer field to the address of a buffer that you have
  780. allocated. This is where the complete path will be constructed for you.
  781. (i.e  Disk:drawer1/drawer2...etc/filename ) Also initialize the FileIO's
  782. DrawMode, PenA, and PenB. You might also want to set the FileIO's X and Y
  783. fields where the requester will open within your window (relative upper left).
  784. If using DoFileIO(), and your window is not full size, include a sizing
  785. gadget so that if the user needs to type via the title bar he can expand it.
  786.  
  787. When you want to present the FileIO Requester to the user, call DoFileIO() or
  788. DoFileIOWindow(). If these routines return the address of the passed buffer
  789. where you want the full path name to be stored, the user did not cancel the
  790. operation, nor was there an error in opening the window (for DoFileIOWindow
  791. only). A -1 and 0 will be returned respectively for the two error conditions.
  792. The following code is an example of presenting the FileIO Requester to the
  793. user and then reacting to the result.
  794.  
  795.   /* This set-up need only be done once, though you can change them later */
  796.  
  797.    UBYTE buffer[204];
  798.  
  799.    myFileIO->Buffer = buffer;
  800.    myFileIO->DrawMode = JAM1;
  801.    myFileIO->PenA = 1;
  802.    myFileIO->PenB = 0;
  803.  
  804.   /* ================================================================ */
  805.  
  806.    if (myFileIO)
  807.    {
  808.        result = (DoFileIO(myFileIO, window));
  809.     if (result==&buffer[0])
  810.        {
  811.             /* Here, do something like read or write the file.
  812.              */
  813.            if (writefile)
  814.            {
  815.             if (myFileIO->Filename[0])
  816.               {
  817.                if (!myFileIO->filesize)
  818.                {
  819.                 /* Open the file (MODE_NEWFILE) */
  820.                 /* Write the file */
  821.                 /* Close the file */
  822.                }
  823.                 /* Otherwise, tell the user that he's about to overwrite */
  824.               }
  825.                 /* Error in entering filename */
  826.            }
  827.            if (readfile)
  828.            {
  829.             if (myFileIO->Filename[0])
  830.               {
  831.               if (myFileIO->filesize)
  832.                {
  833.                 /* Open the file (MODE_OLDFILE) */
  834.                 /* Read the file */
  835.                 /* Close the file */
  836.                }
  837.                 /* Otherwise, tell the user that the file doesn't exist */
  838.               }
  839.                /* Not a loadable file */
  840.            }
  841.        }
  842.      if (result==0)
  843.        {
  844.           /* This only happens if DoFileIOWindow() bombs. Call DoFileIO() */
  845.        }
  846.    /* Otherwise, CANCEL must have been selected. Never mind. */
  847.    }
  848.  
  849. Finally, when you're done with your FileIO structure (usually when
  850. your program is exiting), you can free up the structure and its resources
  851. with a simple call to ReleaseFileIO(), like this:
  852.  
  853.     if( RequesterBase ) ReleaseFileIO(myFileIO);
  854.  
  855. Also, you need to close the library upon exit.
  856.  
  857.     if( RequesterBase ) CloseLibrary( RequesterBase );
  858.  
  859.   When you link your C program, you'll need to assemble and link with
  860. CInterface.asm. This is the usual assembly poot needed by C programs in
  861. order to call assembly language libraries. You want efficiency, write in
  862. assembly. Assembly programmers can simply use the _LVO library offsets as
  863. provided in FileIO.i. See the example applications for details.
  864.  
  865. =============================================================================
  866. === DEMO PROGRAM NOTES ======================================================
  867. =============================================================================
  868.  
  869. This section briefly describes the demo programs that drive some of the
  870. FileIO Requester library's features. There is a C demo, an assembly demo,
  871. and an AmigaBasic demo (no joke).
  872.  
  873. If you invoke the C or asm demos without a second argument, a window will be
  874. opened in the Workbench screen.  If you invoke these demos with any second
  875. argument, a hi-res screen will be opened for the requester window.
  876.  
  877. The C demo uses two FileIO structures to demonstrate the techniques that you
  878. should use when managing multiple FileIOs. These techniques include processing
  879. DISKINSERTED events and discovering on return from DoFileIO() that the
  880. DISK_HAS_CHANGED flag is set. (As long as you're using the NO_CARE_REDRAW
  881. feature). The first support structure, fileio1, is used in its vanilla state
  882. as created by GetFileIO().  The other support structure, fileio2, is
  883. initialized to do Workbench-style .info file handling where the filename
  884. list will consist of only .info objects of type WBPROJECT. Also, fileio1
  885. uses volume names and the other uses device names. You activate fileio1 when
  886. you click the right mouse button. You activate fileio2 when you press any
  887. key. Finally, when you do any of the selection techniques where you accept 
  888. your selection, the pathname to your selection is displayed in a FileIO
  889. autorequester. If you choose CANCEL to end the FileIO process, nothing happens.
  890. To stop the program, click on the window close gadget (when the requester
  891. is not displayed).
  892.  
  893. The assembly demo only uses 1 FileIO structure. There is a menu to
  894. demonstrate various features. You should manually deselect the features
  895. you want disabled, and select those that you want enabled. For example,
  896. select CUSTOM to see how a custom handler is installed for the REQSET event.
  897. Also, this program can look for files that only end in certain strings if
  898. you select the EXTENSION menu item. When you enable the extension feature,
  899. the application uses the PromptUserEntry() function. Notice how the prompt
  900. appears in the window titlebar with a cursor. You can type in the string
  901. that you want to match, and hit return. Now when you call up the requester,
  902. only those filenames that end in that extension will be displayed (along
  903. with any dirs). This works just like the F4 Function key option.
  904.  
  905. The amigabasic demo asks the user if he wants to display only those files
  906. with a certain extension, and inputs the extension. Otherwise, it suppresses
  907. all .info files. It then copies the pathname to a string variable which can
  908. be better utilized for basic manipulation. Also this demos a few of the
  909. library's autorequester functions. When running this program, the included
  910. bmap for the FileIO requester library must be in the same directory.
  911.  
  912. ========================================================================
  913.                    INSTALLING CUSTOM HANDLERS
  914.  
  915.  You can install custom handlers for any of several events that might occur
  916. in the requester. You need to set the CUSTOM_HANDLERS flag of the FileIO, and
  917. fill the FileIO's HandlerBlockPtr field with the address of a HandlerBlock
  918. structure. The HandlerBlock structure (defined in FileIO.h) holds the
  919. addresses of the handlers for REQSET, DISKINSERTED, GADGETDOWN (and UP),
  920. RAWKEY, and MOUSEMOVE. If you have no handler for a particular event, NULL
  921. its HandlerBlock field. Each FileIO can have its own custom handlers.
  922.   For REQSET, and DISKINSERTED, if your handler returns a 1, then the
  923. library's internal handler will be skipped. Otherwise, the library routine
  924. will be executed if you return a 0.
  925.   For GADGETDOWN and GADGETUP, your handler will be called only if the Gadget
  926. ID is not one of the requester's gadgets. Your handler will be passed the ID
  927. in d0 (as well as other parameters). Your handler should return a 0 in order
  928. to continue, or a 1 if you wish to end the requester. (You can check that
  929. your custom handler ended the requester if the FileIO's Errno = ERR_APPGADG).
  930. The only two requester gadgets that the library no longer controls are the CANCEL
  931. and OK gadgets. Control of these two is passed to your custom handler. These
  932. two gadgets have IDs of 32672 and 32673 respectively. If you receive either
  933. of these IDs, you should return a 1. On the other hand, you could simply
  934. cause these gadgets to be ignored by returning a 0. In any event, your
  935. handler will have to return a 1 eventually in order to exit the requester,
  936. or the user would have to type the Filename in the Filename string Gadget.
  937. Do not use gadget IDs between 32672 to 32682 as these are reserved by the
  938. library.
  939.   For MOUSEMOVE, the events are "collected" (i.e. you only receive one event
  940. when the user stops moving the mouse). Also, you won't receive MOUSEMOVE when
  941. the user is operating the requester's scroll (prop) gadget. Your handler
  942. doesn't need a return value.
  943.   For RAWKEY, you won't receive any function keys. No return value is needed.
  944.  
  945.  The requester calls your handler with the following items in these
  946. registers:
  947.  
  948.    a2 - the address of your FileIO
  949.    a3 - the address of the window in which the requester is open
  950.    a4 - the IAddress of the event (not valid for REQSET or DISKINSERTED)
  951.    d6 - MouseX position (for RAWKEY handler, this is the Code instead)
  952.    d7 - MouseY position (for RAWKEY handler, this is the Qualifier)
  953.    d2 - Seconds
  954.    d5 - Micros
  955.    d0 - for GADGETUP and DOWN only, the gadgetID (need not be saved)
  956.  
  957.  You MUST save these registers if you plan on altering them.
  958.     If your handler is written in C (yech!), I've provided a mechanism for
  959. receiving these parameters passed on the stack like all good, inefficient C
  960. programs should. Let's face it, C just doesn't have enough power to do the
  961. sophisticated, efficient things that we do in assembly. But if you'd like to
  962. fool yourself into thinking otherwise, I've tried to accomodate your
  963. delusions. After filling in the HandlerBlock's pointers to the desired
  964. routines, you must call SetFileIOHandlers(HandlerBlock). This routine
  965. will see to it that your handler receives the following parameters except
  966. where previously noted.
  967.  
  968.  yourHandler(IAddress,Window,FileIO,MouseY,MouseX,Micros,Seconds,GadgID)
  969.  
  970.   Unfortunately, unlike the assembly implementation, if you want to have
  971. different FileIO's with unique custom handler routines, you'll have to
  972. call SetFileIOHandlers() before each call to DoFileIO(). Hey, you're writing
  973. in C, so you should be used to giving up some flexibility.
  974.   If you're using Manx small data model, you'll probably have to call geta4
  975. or savea4 (whatever). a4 will definitely not have the base of your program's
  976. data section. These are the types of problems you should expect if you allow
  977. a C compiler to determine 68000 register usage. Also, since register a6 is
  978. "reserved" for library base vectoring on the Amiga, the C interface to the
  979. library does not save this register. If your compiled program crashes because
  980. of this, its time to buy a better compiler, or perhaps solve these headaches
  981. once and for all with an assembler.
  982.  
  983. struct HandlerBlock {
  984.    APTR  StartUpCode;       /* Called when the requester first opens */
  985.    APTR  DiskInsertedCode;  /* Called whenever a disk is inserted */
  986.    APTR  GadgetCode;        /* Called whenever a gadget UP or DOWN */
  987.    APTR  KeyCode;           /* Called whenever a rawkey occurs */
  988.    APTR  MouseMoveCode;     /* Called when the mouse is moved */
  989.    };
  990.  
  991. assembly:
  992.   dc.l AddrOfStartCode
  993.   dc.l AddrOfDiskInsertCode
  994.   dc.l AddrOfGadgetCode
  995.   dc.l AddrOfRawkeyCode
  996.   dc.l AddrOfMouseMoveCode
  997.  
  998. =============================================================================
  999. === TECHNICAL REFERENCE =====================================================
  1000. =============================================================================
  1001.  
  1002. The FileIO files include:
  1003.  
  1004.    requester.library      the actual library (slightly < 10K in size)
  1005.    manual                 The documentation. You've obviously found it.
  1006.    FileIO.h               includes for an C application using the library
  1007.    CInterface.asm         glue routines for a C application to use the
  1008.                           library. (poot) Expects all integers passed 32bit
  1009.    FileIO.i               assembly programmer's include file
  1010.    main.c                 an application in C
  1011.    Test.asm               an application in assembly
  1012.    StartUp.asm            the startup code for the assembly example
  1013.    TestFileIO             an executable of the assembly application
  1014.    MakeTest               execute this script file to make the asm example
  1015.    BasicFileIO            an AmigaBasic application (do you believe me now?)
  1016.    requester.bmap         the bmap file for AmigaBasic
  1017.    requester_lib.fd       the fd file used to make the bmap file
  1018.    CopyLib                a utility to copy libraries to a boot disk
  1019.  
  1020. ================= USING THE AMIGA PROGRAMMER'S SUITE =======================
  1021.  The following is the message that appeared with RJ Mical's ProSuite code
  1022. on Fred Fish Disc #107. That version of FileIO was not a library. It was a
  1023. C code module that needed to be compiled and linked with your application.
  1024.  
  1025.  
  1026. The Amiga Programmer's Suite Book 1 is copyrighted but freely distributable.
  1027. All copyright notices and all file headers must be retained intact.
  1028. The Amiga Programmer's Suite Book 1 may be compiled and assembled, and the 
  1029. resultant object code may be included in any software product.  However, no 
  1030. portion of the source listings or documentation of the Amiga Programmer's 
  1031. Suite Book 1 may be distributed or sold for profit or in a for-profit 
  1032. product without the written authorization of the author, RJ Mical.
  1033.  
  1034. If you use the Amiga Programmer's Suite, I wouldn't mind if you gave me 
  1035. some mention somewhere.
  1036. Good luck!  Program hard, program well.    -RJ Mical
  1037.  
  1038. Make lots of money and become a arrogant, self-serving pain-in-the-ass.
  1039. -Jeff Glatt (my personal philosophy is a bit more philanthropic than RJ's)
  1040.  
  1041. === APPENDIX A:  FileIO Function Calls ======================================
  1042.  
  1043. CONTENTS:
  1044.    GetFullPathname()
  1045.    GetFileIO()
  1046.    DoFileIO()        ;only 1 task at a time
  1047.    DoFileIOWindow()  ;only 1 task at a time
  1048.    ReleaseFileIO()
  1049.    SetWaitPointer()
  1050.    ResetBuffer()
  1051.    AutoMessage()
  1052.    AutoFileMessage()
  1053.    AutoPrompt3()
  1054.    UserEntry()
  1055.    PromptUserEntry()
  1056.    TypeFilename()
  1057.    GetRawkey()
  1058.    DecodeRawkey()
  1059.    ParseString()
  1060.  
  1061. *********************** GetFullPathname() *********************
  1062.  
  1063. NAME
  1064.     GetFullPathname  --  Build a file pathname using a FileIO struct
  1065.  
  1066.  
  1067. SYNOPSIS
  1068.     Buffer = GetFullPathname(FileIO, Buffer);
  1069.      d0                       a0       a1
  1070.  
  1071. FUNCTION
  1072.     Builds the text for a pathname using the FileName[], DrawerName[] and
  1073.     DiskName[] fields of the specified FileIO structure after the structure
  1074.     has been used in a successful call to DoFileIO(), DoFileIOWindow(), or
  1075.     TypeFilename(). Writes the text into the Buffer. 
  1076.  
  1077.  
  1078. INPUTS
  1079.     FileIO = the address of a FileIO structure
  1080.  
  1081.     Buffer = address of the buffer to receive the file pathname
  1082.  
  1083.  
  1084. RESULT
  1085.     The address of the passed buffer. Also, for assembly programmers the
  1086.     address of the terminating NULL is in a1 so you can quickly determine
  1087.     the string length by subtracting d0 from a1 with the result in a1.
  1088.  
  1089.  
  1090. SEE ALSO
  1091.     DoFileIO()
  1092.  
  1093. ********************* GetFileIO() ************************
  1094.  
  1095. NAME
  1096.     GetFileIO  --  Allocate and initialize a FileIO structure
  1097.  
  1098.  
  1099. SYNOPSIS
  1100.     struct FileIO *GetFileIO();
  1101.  
  1102.  
  1103. FUNCTION
  1104.     Allocates and initializes a FileIO structure for use with
  1105.     calls to DoFileIO(), DoFileIOWindow(), TypeFileName(), PromptUserEntry().
  1106.  
  1107.     You may want to further initialize the structure before calling these
  1108.     routines. At least the FileIO's Buffer, DrawMode, PenA, and PenB fields
  1109.     should be initialized. Instead of allocating a FileIO via this routine,
  1110.     you may declare one globally or statically as long as all fields are
  1111.     initialized to zero or an approprite value.
  1112.  
  1113.     When you're done with the structure, call ReleaseFileIO() regardless of
  1114.     whether it was allocated or declared to free up resources.
  1115.  
  1116. INPUTS
  1117.     None
  1118.  
  1119. RESULT
  1120.     If all goes well, returns the address of a FileIO structure.
  1121.     If anything goes wrong (out of memory), returns NULL.
  1122.  
  1123. BUGS
  1124.     None known
  1125.  
  1126.  
  1127. SEE ALSO
  1128.     DoFileIO(), DoFileIOWindow, ReleaseFileIO()
  1129.  
  1130.  
  1131. *********************** DoFileIO() **********************************
  1132.  
  1133. NAME
  1134.     DoFileIO  --  Gets a file name for input/output from the user
  1135.     DoFileIOWindow() -- The same, but opens a window for the requester.
  1136.  
  1137. SYNOPSIS
  1138.     ULONG address = DoFileIO(fileio, window);
  1139.             d0                a0      a1
  1140.     ULONG address = DoFileIOWindow(fileio, screen);
  1141.             d0                      a0      a1
  1142.  
  1143. FUNCTION
  1144.     This routine creates a filename requester which allows the user to browse
  1145.     through the AmigaDOS filesystem and select one of the filenames found
  1146.     there.
  1147.  
  1148.     The fileio argument is a pointer to a FileIO structure, which is allo-
  1149.     cated and initialized via a call to GetFileIO(), or declared in your
  1150.     application.
  1151.     You may preset the FileIO parameters before calling this routine, 
  1152.     or you may leave them set at their default values.  See the FileIO
  1153.     documentation and include files for complete details.
  1154.  
  1155.     The window argument is the pointer to the window structure returned
  1156.     by a call to Intuition's OpenWindow() function.  As this routine
  1157.     opens a requester and requesters open in windows, you must have
  1158.     already opened a window before calling this routine, even if it's
  1159.     a window opened for no other purpose than to call this routine.
  1160.     DoFileIOWindow() is provided to circumvent this problem. It simply opens
  1161.     a window on the passed screen before calling DoFileIO, and closes it
  1162.     upon exit. By setting screen to NULL, the window opens on the WorkBench
  1163.     screen. Also, you might use DoFileIOWindow if you wanted a requester
  1164.     that could be moved or depth arranged by the user in an existing screen.
  1165.     The title that appears in the window will be gotten from the address in
  1166.     the FileIO's Title field.
  1167.  
  1168.     You must initialize the FileIO's Buffer field to hold the address of a
  1169.     buffer where the full pathname string (i.e. disk:drawer.../filename) will
  1170.     be constructed. The size should be no less than 202 bytes. Also, the
  1171.     FileIO's DrawMode, PenA, and PenB fields should be set to the values
  1172.     you want restored when the requester closes.
  1173.  
  1174.     This routine returns a 0 if DoFileIOWindow's window couldn't open, a -1
  1175.     if the user selected CANCEL, or the address of the FileIO's Buffer if
  1176.     all went well and the user selected a filename. The full path name will
  1177.     have been constructed in the buffer. The filename itself will have
  1178.     all leading and trailing blanks removed (in case the user typed in a
  1179.     filename with extraneous spaces) and stored in the FileIO's FileName[].
  1180.     Likewise, the disk and drawer names can be found in the text
  1181.     fields DiskName[] and DrawerName[] of the FileIO. You can always call
  1182.     GetFullPathname() to build the pathname from the separate fields of the
  1183.     FileIO.
  1184.  
  1185.     There's a *lot* more to be said about this function.  Please 
  1186.     read the documentation.
  1187.  
  1188.     NOTE:  This routine is not re-entrant.  What this means is that if some
  1189.     other task is calling DoFileIO() or DoFileIOWindow(), this routine
  1190.     will automatically call TypeFilename() for the 2nd application.
  1191.  
  1192. INPUTS (for DoFileIO)
  1193.     fileio = pointer to a FileIO structure, as allocated
  1194.         via a call to GetFileIO()
  1195.  
  1196.     window = pointer to a Window structure, as created via a call
  1197.         to Intuition's OpenWindow()
  1198.  
  1199. RESULT
  1200.     0 if an error in opening DoFileIOWindow() window. You will not get this
  1201.       error for DoFileIO()
  1202.    -1 if the user selected CANCEL
  1203.     the address of the Buffer if all went well and a file was selected. Also
  1204.     for assembly programmers the end of the string is in a1 like GetFullPathname.
  1205.  
  1206. BUGS
  1207.     None known
  1208.  
  1209. SEE ALSO
  1210.     GetFullPathname(), GetFileIO(), ReleaseFileIO()
  1211.  
  1212.  
  1213. ************************* ReleaseFileIO() **************************
  1214.  
  1215. NAME
  1216.     ReleaseFileIO  --  Release the FileIO structure and all local memory
  1217.  
  1218.  
  1219. SYNOPSIS
  1220.     ReleaseFileIO(fileio);
  1221.                     a1
  1222.  
  1223. FUNCTION
  1224.     Releases the FileIO structure by freeing all local memory attached
  1225.     to the structure and then freeing the structure itself if it is an
  1226.     ALLOCATED_FILEIO (i.e. not pre-initialized in your application).
  1227.     Restores the directory that was established when the FileIO was first
  1228.     sent to DoFileIO() or DoFileIOWindow(). (You should not unlock the
  1229.     initial dir that is contained in the FileIO's originalLock field.)
  1230.  
  1231. INPUTS
  1232.     fileio = the address of a FileIO structure
  1233.  
  1234.  
  1235. RESULT
  1236.     None
  1237.  
  1238.  
  1239. SEE ALSO
  1240.     GetFileIO()
  1241.  
  1242. ************************** SetWaitPointer() *************************
  1243.  
  1244. NAME
  1245.     SetWaitPointer - Sets the zzz cloud pointer in the passed window.
  1246.  
  1247.  
  1248. SYNOPSIS
  1249.     SetWaitPointer(window);
  1250.                     a0
  1251.  
  1252. FUNCTION
  1253.     If you want to have a wait pointer appear in a window, you can use this
  1254.     function which already has set up the pointer data in CHIP mem. Then
  1255.     when you want to restore the pointer, call Intuition's ClearPointer().
  1256.  
  1257. INPUTS
  1258.     window = the address of a window structure
  1259.  
  1260.  
  1261. RESULT
  1262.     None
  1263.  
  1264.  
  1265. ************************* AutoMessage() ************************
  1266.  
  1267. NAME
  1268.     Automessage - an easy implementation of an AutoRequester
  1269.  
  1270.  
  1271. SYNOPSIS
  1272.      AutoMessage(message, window);
  1273.                    d0       a0
  1274.      AutoMessageLen(message, window, length);
  1275.                       d0       a0      d1
  1276.  
  1277. FUNCTION
  1278.     This displays the passed string (whose address is in d0) in a simple
  1279.     AutoRequester. It manages the dimensions (automatically sizes to the
  1280.     passed message) and the IntuiText structure for you. Use AutoMessageLen
  1281.     if you know the length of the string to be displayed.
  1282.  
  1283. INPUTS
  1284.     window = the address of a window structure
  1285.     message = address of the string to be displayed
  1286.  
  1287. RESULT
  1288.     None
  1289.  
  1290. ************************* AutoFileMessage() ****************************
  1291.  
  1292. NAME
  1293.     AutoFilemessage - AutoMessage with preset strings to choose from
  1294.  
  1295.  
  1296. SYNOPSIS
  1297.     BOOL AutoFileMessage(messagenumber, window);
  1298.                             d1             a0
  1299.  
  1300. FUNCTION
  1301.     The requester library has several messages it uses for internal use.
  1302.     You can have one of these messages displayed just by passing the number
  1303.     of the message you want. See Include file for available messages.
  1304.     Some of the messages have two responses "YES" and "OK". Others have just
  1305.     the "OK".
  1306.  
  1307. INPUTS
  1308.     window = the address of a window structure
  1309.     messagenumber = number of the string to be displayed
  1310.  
  1311. RESULT
  1312.     Returns FALSE (d0 = 0) if the user selects "NO" or TRUE (d0 = 1) if the
  1313.     user selects "OK".
  1314.  
  1315. ************************ AutoPrompt3() **************************
  1316.  
  1317. NAME
  1318.     AutoPrompt3 - AutoRequester with up to 3 lines of Text
  1319.  
  1320.  
  1321. SYNOPSIS
  1322.     BOOL AutoPrompt3(message1, message2, message3, window);
  1323.                         a1        a2       a3        a0
  1324.  
  1325. FUNCTION
  1326.     Displays up to 3 passed strings in an autorequester. Automatically
  1327.     dimensions the requester to the size of the longest string, and
  1328.     positions the other strings for a symmetrical display. Returns with
  1329.     user's response to "YES" or "NO". You can also display only 2 or even
  1330.     1 string if you pass NULL for the other messages.
  1331.  
  1332. INPUTS
  1333.     window = the address of a window structure
  1334.     message1 = address of the top string to be displayed
  1335.     message2 = address of the 2nd string to be displayed or NULL if none
  1336.     message3 = address of the 3nd string to be displayed or NULL if none
  1337.  
  1338. RESULT
  1339.     Returns FALSE (d0 = 0) if the user selects "NO" or TRUE (d0 = 1) if the
  1340.     user selects "YES".
  1341.  
  1342. ************************ ResetBuffer() *********************************
  1343.  
  1344. NAME
  1345.     ResetBuffer - Resets the cursor within a StringInfo's buffer to the
  1346.                   first position. Also, can NULL out the buffer itself and
  1347.                   reset the number of chars to 0.
  1348.  
  1349.  
  1350. SYNOPSIS
  1351.     ResetBuffer(stringinfo, resetFlag);
  1352.                    a0           d0
  1353.  
  1354. FUNCTION
  1355.     If you have a String gadget whose cursor you'd like to set back at the
  1356.     first position, you can use this function. Also, if resetFlag is TRUE
  1357.     (1) then the gadget's buffer will be NULLED. You must refresh the gadget
  1358.     yourself after this call.
  1359.  
  1360. INPUTS
  1361.     stringinfo = the address of a StringInfo structure
  1362.     resetFlag = whether to NULL or not
  1363.  
  1364. RESULT
  1365.     NONE
  1366.  
  1367. ;********************* TypeFilename ***************************
  1368.  
  1369. NAME
  1370.     TypeFilename - Uses the window's titlebar to obtain the path name instead
  1371.                    of the file requester (an alternative). Displays the prompt
  1372.                    "Filename >"
  1373.  
  1374. SYNOPSIS
  1375.     buffer =TypeFilename(FileIO, Window);
  1376.                             a0     a1
  1377.  
  1378. FUNCTION
  1379.    If you really don't like the requester, and would prefer to have the
  1380.    user type in the full path via the window's title bar, then use this.
  1381.    Also, you might use this within a save routine so that the user has to
  1382.    deliberately type his choice. The pathname contained within the FileIO's
  1383.    Disk, Drawer, and Filename fields is what is initially presented to the
  1384.    user. This routine is automatically called if an application tries to
  1385.    call DoFileIO() or DoFileIOWindow() when another task is displaying the
  1386.    FileIO requester. Also called if there is not enough mem to open/display
  1387.    the requester. This routine sets up the FileIO's Disk, Drawer, Filename,
  1388.    FileSize, and FreeBytes fields in the same manner as DoFileIO so that
  1389.    you can interpret the results in exactly the same manner.
  1390.  
  1391. INPUTS
  1392.     Window = the address of a window
  1393.     FileIO = the FileIO structure
  1394.  
  1395. RESULT
  1396.   Returns the address of the FileIO's Buffer or a -1 if the user bailed
  1397.   out without entering anything. An ESC will return -1, but will store an
  1398.   ESC char ($1B) and then NULL char in the buffer.
  1399.  
  1400.  
  1401. ;*************************** UserEntry  ***************************
  1402.  
  1403. NAME
  1404.     UserEntry - Uses the window's titlebar to obtain user input.
  1405.  
  1406. SYNOPSIS
  1407.     buffer = UserEntry(charlimit, initBuffer, FileIO, Window);
  1408.                            d0         a1        a2      a3
  1409.  
  1410. FUNCTION
  1411.    This clears the window's titlebar, displays a cursor, and allows the user
  1412.    to type in chars up to the limit, or until CR or ESC is pressed. The NULL
  1413.    terminated result is placed in the FileIO's Buffer. When the charlimit is
  1414.    reached, the routine automatically terminates.  You must set the FileIO's
  1415.    PenA, PenB, and DrawMode fields so that these may be restored by the lib
  1416.    when the function is finished.
  1417.    The initBuffer string is what is presented to the user (and what he may
  1418.    edit). The passed window must have RAWKEY IDCMP set, and the FileIO's
  1419.    RawCode field set to 0 in order to use the default decoding routine,
  1420.    GetRawkey(). Otherwise, decoding will be redirected to the routine specified
  1421.    in the FileIO's RawCode field. (Maybe you want VANILLAKEY instead. Or
  1422.    maybe you also want to handle other IDCMP events while "inside" of UserEntry.
  1423.    GetRawkey disposes of all but RAWKEY events. Or maybe you've set up your
  1424.    own custom IDCMP port and RAW handling routine.) Regardless, your RawCode
  1425.    routine must go to the window's IDCMP port to get a message or wait if
  1426.    there is no message. It should handle all IDCMP messages except RAWKEY or
  1427.    VANILLAKEY. If one of these messages, exit with an UWORD representing the
  1428.    character as follows:
  1429.    $20 to $7F for ascii chars, $DF for delete, $08 for BACKSPACE, $0D for
  1430.    RETURN, $1B for ESCAPE, $010C for LEFT Cursor, $010D for Right Cursor,
  1431.    $020C for SHIFT-LEFT Cursor, and $020D for SHIFT-RIGHT Cursor.
  1432.    UserEntry will continue calling your RawCode for each char, and terminate
  1433.    upon receiving an $0D or $1B, or reaching the charlimit.
  1434.    Since the titlebar can hold approx 70 chars between the CLOSEGADGET and
  1435.    FRONT/BACK, the FileIO's Buffer might be set to 70 bytes. It must be at
  1436.    least as big as charlimit. If the charlimit is greater than 70 bytes, the
  1437.    user can still enter chars, but he will not see them. Upon return, your
  1438.    window's title is restored.
  1439.  
  1440. INPUTS
  1441.     Window = the address of a window
  1442.     FileIO = the FileIO structure
  1443.     charlimit = the number of characters to accept from the user
  1444.     initBuffer = the NULL-terminated string to initialize the FileIO's
  1445.              buffer to, or NULL if no initialization desired
  1446.  
  1447. RESULT
  1448.   Returns the address of the FileIO's Buffer or a 0 if the user bailed
  1449.   out without entering anything. An ESC will return 0, but will store an
  1450.   ESC char ($1B) and then NULL char in the buffer.
  1451.  
  1452. ;******************** PromptUserEntry  ***************************
  1453.  
  1454. NAME
  1455.     PromptUserEntry - Uses the window's titlebar to obtain user input.
  1456.  
  1457. SYNOPSIS
  1458.     buffer = PromptUserEntry(charlimit,prompt,initBuffer,FileIO,Window);
  1459.                                  d0      a0      a1        a2     a3
  1460.  
  1461. FUNCTION
  1462.    This works just like UserEntry except that it first displays the
  1463.    passed prompt string in the titlebar. The FileIO's Buffer should always
  1464.    be greater than the number of chars in the prompt plus charlimit.
  1465.  
  1466. INPUTS
  1467.     Window = the address of a window
  1468.     FileIO = the FileIO structure
  1469.     charlimit = the number of characters to accept from the user
  1470.     buffer = the buffer where the user's input is placed
  1471.     prompt = NULL-terminated prompt to display
  1472.     initBuffer = the NULL-terminated string to initialize the FileIO's
  1473.              buffer to, or 0 if no initialization desired
  1474.  
  1475. RESULT
  1476.   Returns the address of the FileIO's Buffer or a 0 if the user bailed
  1477.   out without entering anything. An ESC will return 0, but will store an
  1478.   ESC char ($1B) and NULL char in the buffer.
  1479.  
  1480. ******************* SetTitle() ********************************
  1481.  
  1482. NAME
  1483.    SetTitle - Uses the window's titlebar to display 1 or 2 strings.
  1484.  
  1485. SYNOPSIS
  1486.     SetTitle(String1,String2,FileIO,Window);
  1487.                a0      a1      a2     a3
  1488.  
  1489. INPUTS
  1490.     Window = the address of a window
  1491.     FileIO = the FileIO structure
  1492.     String1 = the NULL-terminated string to the left
  1493.     String2 = NULL-terminated string placed to the right of String1. If you
  1494.               pass a zero instead, no 2nd string displayed.
  1495.  
  1496. FUNCTION
  1497.   This will display the 2 strings in the window's titlebar (saving the
  1498.   initial title to the FileIO's Title field), and return immediately with
  1499.   the strings still displayed. Subsequent calls can be made to display
  1500.   different strings, but when ResetTitle() is finally called, the initial
  1501.   titlebar is restored. This routine is useful for displaying error msgs to
  1502.   the user without halting program execution (like a requester does), and
  1503.   allows the msg to remain visible for as long as it is needed. Furthermore,
  1504.   it doesn't require that the user respond to it. This function makes temp-
  1505.   orary use of the FileIO's Buffer, so you must supply a buffer whose address
  1506.   is stored at the FileIO Buffer field. This buffer must be large enough to
  1507.   contain both Strings.
  1508.  
  1509. ******************* ResetTitle() ********************************
  1510.  
  1511. NAME
  1512.    ResetTitle - Restores the window's titlebar after calls to SetTitle
  1513.                 (if any calls were made at all)
  1514.  
  1515. SYNOPSIS
  1516.     ResetTitle(FileIO,Window);
  1517.                  a2     a3
  1518.  
  1519. INPUTS
  1520.     Window = the address of a window
  1521.     FileIO = the FileIO structure
  1522.  
  1523. FUNCTION
  1524.     Resets the initial title (stored in FileIO's Title field) if it detects
  1525.     that any calls were made to SetTitle. Otherwise, it does nothing.
  1526.  
  1527. *********************** ParseString() *******************************
  1528.  
  1529. NAME
  1530.   ParseString - Separate a path string into separate components
  1531.  
  1532. SYNOPSIS
  1533.   ParseString(FileIO,String)
  1534.                 a0     a1
  1535.  
  1536. INPUTS
  1537.    The FileIO structure
  1538.    The address of the NULL-terminated path
  1539.  
  1540. FUNCTION
  1541.    This takes the NULL-terminated path as it would be typed on a CLI line
  1542.  
  1543.    Diskname:TopDrawer/....etc.../BottomDrawer/Filename
  1544.  
  1545.    and parses it for "weird" typos or non-existant disk or drawer names.
  1546.    Of course, there may not be any Disk or Drawer names. It then copies the
  1547.    individual components of the Disk, drawer, and filename to the FileIO's
  1548.    respective buffers, and sets the FILEIO_FILESIZE and FILEIO_FREEBYTES
  1549.    fields accordingly. (i.e. If the path turns out to be a drawer or disk
  1550.    only, then FileIO's Filename is NULLED and FileSize = 0. If a non-existant
  1551.    file, it copies the Filename to FileIO, but FileSize = 0. If it is a
  1552.    loadable file, it copies the Filename and sets FileSize accordingly.)
  1553.    The parsed result is placed into the FileIO's Buffer (cannot be the same
  1554.    buffer as the passed string).
  1555.       This is useful for processing the initial argv argument passed to
  1556.    _main for the StartUp code. It will initialize the FileIO buffers to
  1557.    this passed name, and set-up the FileSize and Filename buffer so that
  1558.    it can be determined what kind of object this is. Also, it makes it
  1559.    possible to use the same load routine for the initial passed argv as
  1560.    you would for DoFileIO() or TypeFilename(). For Basic programmer's this
  1561.    can be used to set up the FileIO based upon a string gotten via an Input
  1562.    statement.
  1563.