home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Frameworks / Extension Shell 1.3 / Extension Shell 1.3 (Source) / Extension Shell (Source) ReadMe < prev    next >
Encoding:
Text File  |  1994-04-06  |  8.1 KB  |  173 lines  |  [TEXT/R*ch]

  1. Extension Shell (Source) ReadMe
  2. -------------------------------
  3.  
  4. This folder contains the current release of Extension Shell. THINK C source for all three code resources is
  5. supplied, and there's a ResEdit file containing the compiled versions. 
  6.  
  7. ExtensionShell.c is the main module, and control branches out of there to accomplish various tasks. The
  8. three projects in the folder (the Extension Shell INIT code, the RESP code, and the default address table
  9. code) are all discussed below. Also discussed is ParamBlock.h - which describes how your ES Handler
  10. interfaces with Extension Shell.
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17. Extension Shell.π
  18. -----------------
  19.  
  20. This project is the heart of Extension Shell. It generates the INIT code that's actually run at startup - it
  21. takes care of installing code, removing code, showing icons, posting Notification Manager notes, installing
  22. an address table, and calling your ES Handler. It compiles up as an 'INIT' resource, of ID 5000, with the
  23. System and Locked bits set. It calls your ES Handler, and tries to install what your handler requests. Do
  24. not change the System/Locked bits - the code depends on this, and makes no attempt to lock itself down.
  25.  
  26. If your handler wanted an address table installed, it is called again to initialise any extension specific fields
  27. it has added. If there's a problem your handler is called again when it can decide how it wants to handle
  28. errors (e.g., beep, post a message, show a different icon). Extension Shell then shows the icon(s) your
  29. handler requested, posts any messages, and exits.
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36. RESP.π
  37. ------
  38.  
  39. This project is used by Extension Shell to remove Notification Manager notes after the user has read them.
  40. It compiles up as a 'CODE' resource, of ID 5001. It can be omitted from your Extensions, but any notes you
  41. post (in NotifyMsg.c) won't be removed after the user has read them - they remain stuck in the System
  42. heap.
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49. AddrsTable.π
  50. ------------
  51.  
  52. This project is used by Extension Shell as a Gestalt selector function. It compiles up as a 'CODE' resource,
  53. of ID 5002. It can be removed if your Extension doesn't need an address table. If your Extension does need
  54. an address table you can either use this code, or supply your own. This code is called by Extension Shell to
  55. initialise one of its global variables, like so (from 'InstallCode.c'):
  56.  
  57.  
  58.     AddressTable        *gTheAddressTable;
  59.     …
  60.     theErr = Gestalt(theParamBlock.addressTableSelector, &gTheAddressTable);
  61.  
  62.  
  63. The Gestalt selector's purpose is to correct initialise gTheAddressTable. The address table structure itself is
  64. declared as a global in the selector's code, and so remains locked in the System heap with the selector.
  65. Your installed code can call Gestalt to get the address of this structure, and look up the address of the code
  66. it replaced.
  67.  
  68. The behaviour of this Gestalt selector can be extended by supplying your own ('CODE', 5002) selector
  69. instead. Your routine should have the same behaviour as the original routine - it should return the address
  70. of its global address table structure, in its parameter, and nothing else. If you are supplying your own
  71. routine,  be aware that Extension Shell expects the address table structure to start with an array of
  72. ProcPtrs. However, it only initialises as many ProcPtrs as it uses, and relies on your ES Handler code
  73. to initialise any further fields - provided the first N fields of your address table are the N ProcPtrs for
  74. the code resources you want installed, everyone will be happy.
  75.  
  76.  
  77.  
  78. Original
  79. --------
  80.     typedef struct {
  81.         ProcPtr            theTable[kMaxNumCodeResources+1];
  82.     } AddressTable;
  83.  
  84.  
  85. Extended
  86. --------
  87.     typedef struct {
  88.         ProcPtr            theTable[...];                    // Must be first
  89.         long                myFieldOne;
  90.         Boolean            myFieldTwo;
  91.         ProcPtr            myOtherProc;
  92.     } MyExtendedAddressTable;
  93.  
  94.  
  95.  
  96. This ability to extend the address table, and thus remove the need for another selector to communicate
  97. with any Control Panels, was the main reason for choosing this way to get addresses to the code that
  98. needed them. I've given some other alternatives that have been suggested below but, for now, I feel that
  99. going through Gestalt is probably the cleanest way. If you've got any other ideas, feel free to let me know.
  100.  
  101.  
  102.     • Search for a pre-initialised variable in the actual 'CODE' resource, and store the address
  103.       there. This relies on 'CODE' resources having their globals embedded in them, and would
  104.       involve flushing caches for every thing that was installed. Search times couldn't be
  105.       predicted in advance, which might be inefficient if somebody wanted to install something
  106.       huge.
  107.  
  108.     • Store the address at a fixed offset in the 'CODE' resource. This wouldn't be too much
  109.       hassle for people writing stuff in assembly, but it's too restrictive for high level
  110.       languages.
  111.         
  112.     • Store the address in a resource in our Extension's resource fork. If more than one 'CODE'
  113.       resource wanted to find an address, the resource would grow to become an AddressTable,
  114.       and the trap-patches/etc would have the extra work of finding their Extension (hoping it
  115.       hadn't been moved or renamed before the trap they patched was called), opening its resource
  116.       fork, etc, etc. It could also mean problems for people patching Resource Manager calls. The
  117.       address could also be stored in the preferences file, but the same problems apply.
  118.         
  119.     • Search the System heap for a block of the right size, which begins with a predefined
  120.       signature. The signature would have to be shared between 'CODE' resources (unless
  121.       Extension Shell read it from another resource), but this explicitly relies on the format of
  122.       memory blocks. You *could* just go ahead and search the whole System heap, but this
  123.       might be a bit excessive...
  124.         
  125.     • Add an assembly patch to a trap, copy the address of the original trap into it at a fixed
  126.       address, and use that trap as a sort of Gestalt selector. If its parameters are a certain value,
  127.       and one of them points to a unique signature, etc - then assume (gulp!) that we're being called
  128.       to return the value of an address table/old routine.
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135. ParamBlock.h
  136. ------------
  137.  
  138. Out of all the header files, this is probably the most important. This defines the structure that Extension
  139. Shell uses to communicate with your ES Handler. Each code resource that you want to install has an entry
  140. in the ‘theCodeResources’ array. The type specific details (trap number, gestalt selector, etc) are
  141. contained in a union within the structures of this array. The details required are commented inside
  142. ParamBlock.h, but to see them in practice look at the sample extensions.
  143.  
  144.  
  145.  
  146.  
  147.  
  148.  
  149. Other things...
  150. ---------------
  151.  
  152. • The “Extension Shell #includes” folder contains include files that all the Extension Shell projects require.
  153. Place an alias to it in your “THINK C:Mac #includes” folder before you try and compile things.
  154.  
  155. • Where arrays are used in the source code, valid indexes are from 1..kMaxNumSomeDescriptiveName. 
  156.  
  157. • If you have to share .h files between projects, don't make an alias and #include that. THINK C will open
  158. the alias file itself rather than resolving it... Put them in a shared directory.
  159.  
  160. • The logic in the sample Extensions isn't valid for Control Panels. They all assume that after testing for
  161. System 7 and shift/the mouse button being down then it's OK to install themselves. If you are using
  162. Extension Shell in a Control Panel, and your Control Panel has an on/off switch, you will need to test the
  163. status of your switch before checking to see if shift/the mouse button is down. Otherwise your Control
  164. Panel might be off, but holding down shift/the mouse button will make it show its disabled icon.
  165.  
  166. • There are four calls to DebugStr() in Extension Shell. While it's not a good idea to ship products with
  167. DebugStr calls in them, Extension Shell will only call them if something *very* serious has gone wrong... If
  168. it can't load your ES Handler then it calls DebugStr - presumably you'll notice this before you ship. ;-) It
  169. also calls DebugStr if your Extension has requested an address table, but the table couldn't be found or
  170. installed. If this happens, ES wouldn't be able to install your patches anyway (since you requested an
  171. address table, presumably they expect it to be there) - again, this is something you need to know before
  172. you ship: so the calls stay for now.
  173.