home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / disks / disk463.lzh / FileIO / FileIO.doc < prev    next >
Text File  |  1991-03-09  |  105KB  |  2,321 lines

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