home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 4 / DATAFILE_PDCD4.iso / utilities / utilsf / jfshared / Modules / TextCopy / AllWCD / WSWI-Help < prev   
Encoding:
Text File  |  1995-09-23  |  13.6 KB  |  268 lines

  1. WimpSWIVe       0.04 (27 Apr 1995)
  2. ==================================
  3.  
  4.  
  5.  NewerLook needs to trap Wimp_ SWIs in order to provide its new error
  6. windows. The only official way to trap SWIs is to trap the SWI hardware
  7. vector, but even this is not recommended. It takes much code to implement
  8. properly in all circumstances (about 30K of source code for Desktop Hacker),
  9. and can slow the machine down, quite considerably when there are multiple
  10. claimants.
  11.  
  12.  It is, however, possible to trap Wimp_ SWIs by providing another module
  13. with the same SWI chunk and names. This method is much quicker and easier,
  14. but is rather dodgy. One of the problems is that only one module can do this
  15. at a time. So if NewerLook had a module that used this method, it wouldn’t
  16. work properly when another program tried to do the same thing.
  17.  
  18.  Thus, I have separated the trapping code from the action code (which resides
  19. in another module), and released this module separately. It can manage SWI
  20. claims and releases dynamically, a bit like vectors. You can use it in your
  21. own programs if you like. Here’s how.
  22.  
  23.  Because WimpSWIVe uses the Wimp’s SWI chunk, it cannot provide its own
  24. SWIs. Instead, it communicates using a Wimp SWI, namely Wimp_RegisterFilter.
  25. Here is the WimpSWIVe specification for Wimp_RegisterFilter.
  26.  
  27.  
  28.             |                                             Wimp_RegisterFilter
  29.             |                                                    (SWI &400F5)
  30.             |
  31.             | Used by the Filter Manager to register or deregister a filter
  32.             | OR used to register SWI claims and releases with WimpSWIVe
  33.             |
  34.   On entry: | R0 = reason code:
  35.             |         &49575357 (“WSWI”) for WimpSWIVe operation (see below)
  36.             |         anything else for filter operation (see RISC OS 3
  37.             |         Programmers’ Reference Manual, page 3-224)
  38.             | R1 = SWI word:
  39.             |         bits 0-5 : offset in SWI chunk of SWI to claim/release
  40.             |         bits 6-29: undefined, leave unset
  41.             |         bit  30  : high priority if set, else low priority
  42.             |         bit  31  : claim if set, else release
  43.             | R2 = value to be passed in R12 on entry to code
  44.             | R3 = address of SWI pre-trapping code, or 0 if none needed
  45.             | R4 = address of SWI post-trapping code, or 0 if none needed
  46.             |
  47.    On exit: | Registers preserved
  48.             |
  49. Interrupts: | Interrupts may be enabled
  50.             | Fast interrupts may be enabled
  51.             |
  52.  Processor: | Processor is in SVC mode
  53.             |
  54. Reentrancy: | SWI is not re-entrant
  55.             |
  56.        Use: | In WimpSWIVe usage, this SWI is used to claim or release SWIs.
  57.             | The pre-trapping code specified is called before the SWI is
  58.             | called, and the post-trapping code afterwards.
  59.             |
  60.             | High-priority pre-code is called before low priority pre-code.
  61.             | (And high-priority post-code is called after low priority
  62.             | post-code.) This is important because one piece of pre-code
  63.             | could intercept a SWI call before another bit got a look in.
  64.             | You should use high-priority code for monitoring and register-
  65.             | altering code. If your pre-code is at all likely to intercept
  66.             | a SWI, you must use low-priority code. In effect, low-priority
  67.             | code is 'closer' to the real SWI.
  68.             |
  69.             | Pre-trapping code conditions:
  70.             |
  71.             | On entry: R0-R8 = registers passed to SWI
  72.             |           R9    = offset into chunk of SWI called
  73.             |           R12   = value specified when RegisterFilter called
  74.             |           R13   = full, descending stack
  75.             |           R14   = return address
  76.             |  On exit: R0-R8 = may be altered to change effect of SWI
  77.             |           R9    = preserved, or -1 to intercept SWI
  78.             |
  79.             | Pre-trapping code is entered in SVC mode, with interrupts
  80.             | disabled. If R9=-1 on exit, the SWI is not called. Instead,
  81.             | any outstanding post-code is called, and the caller is returned
  82.             | to with the supplied R0-R8 and PSR flags. An error may be
  83.             | signified by pointing R0 to an error block and setting the V
  84.             | flag on return as normal, when intercepting. (See footnote 1.)
  85.             |
  86.             | If more than one client has claimed a SWI, it is the earliest
  87.             | claimant’s pre-trapping code that is called last - new
  88.             | claimants take priority (though high-priority always beats low-
  89.             | priority, of course). If interception occurs, any post-trapping
  90.             | code for claims where the pre-trapping code (if any) has
  91.             | already been executed are also executed. In effect, you are
  92.             | guaranteed that you will get a post-trap event if you have had
  93.             | a pre-trap. (See footnote 2.)
  94.             |
  95.             |
  96.             | Post-trapping code conditions:
  97.             |
  98.             | On entry: R0-R8 = registers passed back from SWI
  99.             |           R9    = offset into chunk of SWI called
  100.             |           R12   = value specified when RegisterFilter called
  101.             |           R13   = full, descending stack
  102.             |           R14   = return address
  103.             |  On exit: R0-R8 = may be altered to change perceived results
  104.             |           PSR flags may be altered to change perceived results
  105.             |           (for example to flag an error).
  106.             |
  107.             | Post-trapping code is entered in SVC mode, with interrupts
  108.             | disabled.
  109.             |
  110.             | If more than one client has claimed a SWI, it is the earliest
  111.             | claimant’s post-trapping code that is called first, subject
  112.             | to priority. (See footnote 2.)
  113.             |
  114.             | Remember that your post-trapping code may well be entered in an
  115.             | error condition. So check whether the V flag is set on entry,
  116.             | and return if it is (if you return with the S flag (MovS Pc,R14
  117.             | or LdmFd R13!,{...,Pc}^, the flags are unaffected). Never
  118.             | change the PSR flags by accident.
  119.             |
  120.             |
  121.             | Unlike OS_Claim, this SWI will not remove previous instances of
  122.             | claims with the same values. The release routine also only
  123.             | removes one instance of the values at a time.
  124.             |
  125.             | Claiming the Wimp_RegisterFilter SWI only traps the normal
  126.             | filter-based use of the SWI. Under no circumstances should you
  127.             | call Wimp_RegisterFilter with WimpSWIVe usage in your trapping
  128.             | code. If you really must claim or release a SWI when some other
  129.             | SWI is executed, use a CallBack to do it. (See the RISC OS 3
  130.             | Programmers’ Reference Manual, page 1-319.)
  131.             |
  132.             | NB: You should NOT post-trap Wimp_Poll or Wimp_StartTask.
  133.             | (Or Wimp_PollIdle.) Trapping Wimp_Poll is easy anyway, using
  134.             | the old filter system.
  135.             |
  136.     Errors: | Bad value passed to WIMP in R0
  137.             |    if WimpSWIVe is not loaded, the attempt to use this SWI in
  138.             |    the WimpSWIVe manner will cause this error
  139.             | Bad WimpSWIVe release
  140.             |    releasing a SWI you had not claimed generates this error
  141.             | No room in RMA
  142.             |    is also possible but highly unlikely.
  143.             |
  144.  
  145.  
  146.  Footnote 1 - Re-entrancy issues:
  147.  
  148.  Re-entrancy is nae problem if you only use pre-trapping or only use post-
  149. trapping - you can either be re-entrant by using a stack to store stuff, or
  150. prevent re-entering using a threaded flag (and unless you call a SWI, you
  151. cannot be re-entered anyway). If you use both, but the post-code always does
  152. the same regardless of the pre-code, you're all right too.
  153.  
  154.  But if you use both at once and the action of post depends on something
  155. that happened in pre (for example if you have pre to check the reason code
  156. is worth bothering with in the post-trap code), it is slightly more complex.
  157. It's quite possible that calling a Wimp SWI may cause another Wimp SWI to be
  158. called, especially when you consider there can be many WimpSWIVe claimants.
  159. Consider:
  160.  
  161.      SWI Wimp_Thing called
  162.        WimpSWIVe claimant 1 pre-traps SWI
  163.          Claimant 1 store data for SWI 1 in workspace
  164.        WimpSWIVe claimant 2 pre-traps SWI
  165.          Claimant 2 executes Wimp_Gubbins
  166.            Wimp_Gubbins causes Wimp_Thing to be called
  167.              WimpSWIVe claimant 1 pre-traps SWI
  168.                Claimant 1 stores data for SWI 2 in workspace
  169.              WimpSWIVe claimant 2 pre-traps SWI
  170.                Claimant 2 is threaded, and so does nothing
  171.              WimpSWIVe executes real SWI Wimp_Thing
  172.              WimpSWIVe claimant 2 post-traps SWI
  173.                Claimant 2 is threaded, and so does nothing
  174.              WimpSWIVe claimant 1 post-traps SWI
  175.                Claimant 1 performs action on results, dependent on workspace
  176.                which holds data for SWI 2
  177.              WimpSWIVe returns
  178.        WimpSWIVe executes real Wimp_Thing SWI
  179.        WimpSWIVe claimant 2 post-traps SWI
  180.          Claimant 2 does whatever it needs to with results
  181.        WimpSWIVe claimant 1 post-traps SWI
  182.          Claimant 1 performs action on results, dependent on workspace
  183.          which holds data for SWI *2*
  184.        WimpSWIVe returns
  185.  
  186.  As you can see, there is a lot of scope here for things going wrong, and
  187. horrible clashes where one WimpSWIVe program may make another go wrong,
  188. potentially rather messily.
  189.  
  190.  There are two things you can do about it. Perhaps the best is to store a
  191. 'count' of post-traps to ignore. This count should be zero initially, and
  192. should be incremented first when your pre-trap code detects that post-
  193. trapping should do something effective. It should also be incremented every
  194. time the pre-trap code is entered with the count non-zero. The post trap code
  195. then checks the count on entry. If the count is zero, it returns doing
  196. nothing. If the count is one or greater, the count is decremented. If the
  197. count is one exactly one, the effect of the post-trap is activated. There's
  198. an example of this in the EigenSysInfo source.
  199.  
  200.  This is fine normally, but it makes the trapping code only affect the first
  201. SWI to be affected (the "outermost" affected SWI). If you want to be truly
  202. re-entrant, you'd have to store values on the stack to indicate whether to
  203. post-trap on each call. And you couldn't use the SVC stack, so you'd have to
  204. use a private stack. And you'd have to revert to the above behaviour if the
  205. stack was filled up. Therefore, I don't reckon it's worth bothering with,
  206. especially as allowing true re-entrancy opens the door to recursive problems
  207. (Wimp_Thing calls Wimp_Gubbins calls Wimp_Thing calls Wimp_Gubbins etc.) too.
  208.  
  209.  Sorry about the complexity of this footnote. Relax. You don't need to
  210. bother about all this horrid stuff, usually. :-)
  211.  
  212.  
  213.  Footnote 2:
  214.  
  215.  Your post-trap code will only be called if the SWI does return. This might
  216. not happen if the SWI is one that doesn't return (but I can't think of any
  217. Wimp_ SWIs that don't), or if a serious error happens. The latter should
  218. never happen in a perfect system, but bugs happen and the SWI being trapped
  219. might branch through zero or something. With the Wimp, though, a crash at
  220. this stage often means there is something very wrong with the whole desktop
  221. and everything is going to die anyway, so your module failing to post-trap
  222. is unlikely to annoy the user much. :-)
  223.  
  224. -----------------------------------------------------------------------------
  225.  
  226.  This module is supplied with some example programs:
  227.  
  228.  - 3DErrorWindow. This is a useful module that replaces the WIMP’s error
  229.    windows with its own Risc PCable 3D ones (it needs 3DErrorWindow$Path to
  230.    point to a directory containing Templates and Messages - you can find one
  231.    in Sources.ErrorWind) using pre-trapping (usually with interception). The
  232.    windows could do with the NewerLook 'titlejoint' sprite in the wimp pool,
  233.    along with the Risc PC error system sprites.
  234.  - EigenSysInfo. This is a pretty useless one that changes Wimp_ReadSysInfo
  235.    2 always to return 24 or 22, and return the latter if Log2YEig<2 (the
  236.    WIMP returns 22 if Log2YEig==Log2XEig, which is silly). It also goes
  237.    'beep' if the Wimp returned a different value to it (try mode 22 and the
  238.    like). It’s not particularly great because most programs don’t take any
  239.    notice of ReadSysInfo (partly because of its aforementioned bobbinsness)
  240.    but it shows you how to pre-trap and post-trap SWIs at the same time (as
  241.    in footnote 1).
  242.  
  243.  The source for these programs, along with the full source to WimpSWIVe and
  244. some resources for 3DErrorWindow are to be found in the Sources directory.
  245. However, these programs require BAX to be loaded for them to compile. BAX is
  246. DoggySoft’s Basic Assembler Extension, which provides all ARM3, ARM6, FPA10
  247. and coprocessor instructions, along with many useful pseudo-instructions.
  248. You can get BAX from good PD libraries and Arcade, Digital Databank and
  249. Furzefield Hq BBSs. It’s essential for Basic assembler programmers!
  250.  
  251.  If you use this module in a program, be sure to RMEnsure version 0.04 or
  252. later - versions 0.01 and 0.02 are NewerLook quick releases with bugs in
  253. post-trapping, and version 0.03 do not feature high-priority SWI trapping,
  254. as well as sometimes entering pre-code with interrupts enabled.
  255.  
  256.  This module is freeware. Free free to distribute and use. To contact me -
  257. for praise, to suggest new bits to add, or (heaven forbid) to report a bug,
  258. please write to:
  259.  
  260.   Andrew Clover,
  261.    7 Blackhorse Crescent,
  262.     Amersham,
  263.      Bucks.,
  264.       HP6 6HP.
  265.  
  266.  Or phone me on 01494-431916, send a fax on 01494-675878, send some email to
  267. ajc@doggysft.demon.co.uk or even telex on 83675 Brit G.
  268.