WimpExtension document: Writing Libraries                             Doc 02
============================================================================


Note: You are expected to compile your libraries with a
'Single Library File' format header on the beginning. WimpExtension cannot
load these files directly, you should convert them into library files using
ExtLibMan.


Single Library File format
==========================

   00  WExt (recognition code)
   04  File code;    1 = single library file
   08  Version code; 0
   0C  reserved; must be 0
   10  reserved; must be 0
   14  reserved; must be 0
   18  reserved; must be 0
   1C  reserved; must be 0
   20  Length of library (multiple of 4 bytes)
   24  ...library starts here...


Library format
==============

   00  Library number
   04  Function identifier
   08  Version number * 100
   0C  Library format version number - currently 0
   10  Library name, padded with zeroes to 32 bytes
   30  Offset to null-terminated copyright message
   34  Offset to Initialise code, or 0
   38  Offset to Finalise code, or 0
   3C  Offset to NewTask code, or 0
   40  Offset to TaskDying code, or 0
   44  Offset to PrePoll code, or 0
   48  Offset to Action code, or 0
   4C  Offset to CallLibrary code, or 0
   50  Offset to Service code, or 0
   54  Offset to Redraw code, or 0
   58  Flags
          bit    meaning if set
           0     tasks do not need to be registered to use this library
           1     'not freely distributable'
           2     beta-release version of library
           3     don't unload when usage count reaches zero
          4-31   reserved; must be 0
   5C  No. of bytes workspace needed per task (0 is an acceptable value)
   60  Offset to table of dependencies, or 0
   64  Offset to table of commands, or 0
   68  Offset to table of validation commands, or 0


Notes on writing libraries
==========================

Libraries are stored in read/write memory, so it is safe for them to write to
themselves for variable storage. If you want larger amounts of storage then
you can request it from the RMA using OS_Module. Libraries are fixed in
memory for the duration of them being initialised - ie. they may be moved
before the Initialise entry is called or after the Finalise entry is called.
Do NOT rely on variables being initialised from the file, as the library may
be Initialised, Finalised and then re-Initialised many times.

Libraries may have a task workspace area, with one chunk per task. It is
recommended that you only use this if absolutely necessary, however, for
reasons of memory economy.



Creating your own library numbers and function identifiers
==========================================================

Library numbers are in the range 1 to &FFFF. Numbers in the range 1 to &0FFF
are reserved to DoggySoft. If you have a SWI chunk allocated to you by Acorn
in the range &40000 to &BFFFF then you may use the library number given by
dividing your SWI chunk base number by 64. e.g. If your SWIs start at &46C80
you may use library number &11B2. Numbers in the range &E000 and upwards may
be used for testing - do NOT distribute software which uses this range as
somebody else may be using the same number. Contact DoggySoft for a unique
allocation in the range &3000 to &DFFF.

The approach for choosing function identifiers is the same as for library
numbers. Currently allocated function identifiers are:
   1  SWI-providing Library
   2  DoggySoft support library
   3  General library

All library entries are called in SVC mode, with the following common
registers:
  R13-> supervisor stack
  R14 = return address

They should return errors by putting the address of the error block in R0 and
setting the V flag (ie. the normal method).



Notes on library file search method
===================================

The library file loader has the following aims, in order from highest
priority to lowest priority:

  * Get at least the version number specified (the load fails otherwise)
  * Don't access the disc
  * Get the highest version number possible
  * Don't swap discs

ie. If the library is already loaded, then a higher version existing on disc
won't be loaded unless you specifically ask for a higher version number. If
the same version exists on several discs then the load routine will first
attempt to load the library on the disc currently in the drive.



Initialise entry
================
R0 = version number of WimpExtension Kernel *100

Called to initialise the library. If this call returns an error then the
library will be removed from memory.



Finalise entry
==============

Called to finalise the library. If this call returns an error then the
library will not be removed from memory, but will be marked as dead.



Register entry
==============
R11-> library's task workspace, if used
R12-> WimpExtension's task workspace

Called when the task registers itself with your library.



DeRegister entry
================
R11-> library's task workspace, if used
R12-> WimpExtension's task workspace

Called when the task deregisters itself with your library. If this call
returns an error then the deregister will succeed, but the library's 'use'
count won't be decremented.



PrePoll entry
=============
R0  = original mask
R1 -> poll block (or -1 for non-WimpExt2 task)
R2  = time_to_return-time_now (unsigned)
R11-> library's task workspace, if used
R12-> WimpExtension's task workspace
Exit:
libraries may alter R0 (not bit 0) and R2, see below.

Called when the user calls WimpExt_PrePoll.

Pre-WimpExt2 tasks did not pass their PollIdle registers to PrePoll, if this
is the case then R1 will be set to -1. Do not increase the value in R2,
remember that it is unsigned and that you must not set bits in R0, only
clear them.

R2 will be added to the current time and then passed onto the task. If R2
remains &FFFFFFFF on exit from every library then R2 will be changed to 0
and bit 0 in the mask will be set so that no null events are generated. Do
not alter bit 0 in R0, this is done automatically for you if R2 is changed.



Action entry
============
R0  = reason code
R1 -> Wimp_Poll block
R7  = 0
R11-> library's task workspace, if used
R12-> WimpExtension's task workspace
Exit:
R7  = non-zero for altered poll action, if so R0=new reason code

Called when the user calls WimpExt_Action.



CallLibrary entry
=================
R0  = reason code (in the range 0-65535)
R11-> library's task workspace, if used
R12-> WimpExtension's task workspace

Called when the user calls WimpExt_CallLibrary. What the reason codes mean
depends on your library. Whether you ignore or fault unknown reason codes is
up to you.



Service entry
=============
R1 = service number
R0,R2-R8 depend on service call
Exit:
R1 = 0 to claim, preserved otherwise

Service numbers are allocated the same way as for the library numbers, so
you may use your library number as the service number for uniqueness.
Service numbers, like library numbers, must not be used above &FFFF. This
is to allow for future expansion on this entry.

It is usual to use R0 as a reason code, so as not to waste service numbers.

Current service numbers in use at the moment are:
  1 = Unknown MiscOp call, registers same as SWI (except R1 mapped to R8)
  2 = Mode change


Redraw entry
============
R1-> redraw block
R4 = current graphics window min x
R5 = current graphics window min y
R6 = current graphics window max x
R7 = current graphics window max y
R8 = X work area origin
R9 = Y work area origin

This is called after all the icons and validation strings have been dealt
with via the validation entry.


Command table
=============

The command table is a list of entries, one per command, and a zero-byte
terminator. Each entry is as follows:

    Zero-terminated command string
    ALIGN
    Offset from beginning of library of code to handle command
    Offset from beginning of library of command's help message

The help message is OS_PrettyPrinted with the special string being the
command name, so you can use the standard RISC OS dictionary tokens if you
like.

The command code is entered in exactly the same way as a normal *command.



Table of Dependencies
=====================

This is a list of entries exactly the same as required for LibraryOp 0. It
lists all the other libraries which this library requires. Note that
libraries which are only required for certain subfunctions which the library
provides need not be listed in the dependency table - it is up to the user to
ensure these libraries if they use the subfunction.



Table of Validation Commands
============================

This is a list of eight-words, terminated with a zero word. These specify
validation commands which the library recognises. All validation commands
must be prefixed in the icon data by a 'w' and are case sensitive. eg. a
table containing the commands 'b' and 'z' would match 'wb' and 'wz'. Each
block is laid out as follows:
  00  command character in lowest byte, next three bytes must be zero
  04  offset to redraw code, or 0
  08  offset to mouse-click code, or 0
  0C  offset to key-press code, or 0
  10  offset to pointer-entering-icon code, or 0
  14  offset to pointer-leaving-icon code, or 0
  18  reserved; must be 0
  1C  reserved; must be 0

The code entries are called with:
  R0= reason code (ie. 1 for redraw, 6 for mouse click, 8 for keypress
                       0 for pointer-entering-icon and pointer-leaving-icon)
  R1->poll block
  R2->icon block
  R3->rest of validation command
  R4= validation command character
  R5= window handle
  R6= icon handle
  R7= 0
Exit:
  R7 preserved or <>0 R0=new reason code

For pointer-entering-icon and pointering-leaving-icon a message is sent to
the task using Wimp_SendMessage (if R7<>0 on exit) so any action you take is
not immediate.  The poll block for these two validation messages belongs to
the WimpExtension task, and you may use it for temporary workspace (256 bytes
long).
