www.riscos.com Technical Support: |
|
This chapter describes the interface to the ResourceFS module, which provides the hooks necessary for modules to include files in the Resources: filing system.
This facility is useful because it allows the resource files associated with a particular module to be included in the same file as the binary image, which helps with release control.
It also has an important application for expansion card modules, since it allows them to *IconSprites a sprite file which they put into Resources:. This is important as there is no other way to introduce a sprite into the Wimp's sprite pool other than from a file.
Another application is for certain resource files to be replaced on a selective basis, which is an additional technique to the path mechanism already in use (e.g. Wimp$Path can be set up to reference a resource directory).
ResourceFS is not available in RISC OS 2.
In order to avoid possible name clashes, it is important that a well-defined directory structure is adhered to by all concerned. This is:
$.Apps.!appname | ; applications |
$.Fonts | ; fonts |
$.Resources.modulename | ; resources for system modules |
$.Resources.appname | ; resources for applications |
where appname is the name of the application concerned, without the '!' on the front (e.g. Draw, Paint, Edit).
The above all indicate directories, which normally contain files called !Sprites, Templates, Messages and so on.
Where third party software is involved, the actual appname used must be registered with Acorn, to avoid clashes. See Appendix H: Registering names.
The Fonts directory contains the ROM-based fonts, and are accessed by the ROMFonts module setting up Font$Path as follows:
*SetMacro Font$Path <Font$Prefix>.,Resources:$.Fonts.
(It only does this if Font$Path was previously set to '<Font$Prefix>.'.)
All the Desktop Filer modules (ADFSFiler, NetFiler etc) access their resource files (Messages and Templates) via path variables, eg: 'NetFiler:Messages'. On initialisation, they check for the existence of the relevant path variable and set up the appropriate default if it is not defined, eg:
*Set NetFiler$Path Resources:$.Resources.NetFiler.
You can set up any or all of these path variables to point to your own message files.
Note that the Wimp uses 'WindowManager$Path' rather than 'Wimp$Path', to allow Wimp$Path to remain separate. Its resources are:
Resources:$.Resources.Wimp.Messages Resources:$.Resources.Wimp.Sprites Resources:$.Resources.Wimp.Templates Resources:$.Resources.Wimp.Tools
The Sprites files contain the Wimp's ROM sprite pool, and cannot be redirected (since the Wimp needs direct access to their ROM addresses).
The Apps directory contains the ROM applications, which each have a !App directory, and can be started up by '/Resources:$.Apps.!App'. The Desktop module will automatically start the applications using such commands, if the corresponding bits in CMOS RAM are set (see the chapter entitled Non-volatile memory (CMOS RAM)), by issuing *Filer_Run commands as appropriate. It does this on *Desktop after the normal modules have been started, and before any parameters to the *Desktop command have been decoded.
By default, no applications are auto-started.
Note that !Chars is not auto-started, since it has no iconbar icon of its own; instead it is put onto the iconbar using the *AddTinyDir command.
Note that this auto-starting procedure does not occur if the *Desktop command has a filename parameter, since in this case it is assumed that the Desktop Boot file will start any applications that are required. The configuration options are provided to allow discless operation of the machine.
The ROM applications do not contain the entire application, but simply the !Boot, !Help and !Run files. The !Run file then sets up a path variable, consisting of the current value of <Obey$Dir> (ie the application directory itself) and another directory in Resources:$ (eg Resources:$.Resources.Alarm).
Because each application uses a path variable to access its resource files, you can copy it to disc and add an updated copy of the 'Messages' file to the application directory. This will take precedence over the version in the ROM directory, which is accessed via the second path element.
In order to register a group of files with ResourceFS, a module must have the files included in their image, with appropriate header information, and then call the SWIs ResourceFS_RegisterFiles and ResourceFS_DeregisterFiles to register and deregister this area as appropriate.
The format of the (word-aligned) resource file data is as follows:
Offset | Size | Meaning | ||
---|---|---|---|---|
0 | 4 | offset from here to the next file (contiguous), or 0 for end of list (no data follows) | ||
4 | 4 | load address of file | as returned by OS_File 5 | |
8 | 4 | exec address of file | ||
12 | 4 | size of file | ||
16 | 4 | attributes of file | ||
20 | n | full filename, excluding '$.', null terminated | ||
20+n | 0 - 3 | padded with 0s until word-aligned | ||
4 | size of file + 4 | |||
s | file data | |||
0 - 3 | padded with 0s until word-aligned, followed by more data in the same format |
The resource file data is terminated by a single 0 word.
The resource file data should be contiguous. If this is not possible, then ResourceFS_RegisterFiles must be called once for each of the areas of resource file data to be used (and an equivalent set of ResourceFS_DeRegisterFiles's later on). Note that each area of resource file data must be terminated by a single word containing 0.
There are no directory objects, since the directory structure can be determined from the full filenames supplied.
Note that where name clashes occur, the first occurrence of the filename in the most recently registered area will be used.
R1 = &59 (Reason code)
All registers preserved (do not claim the service)
This service call is issued by ResourceFS to tell any programs relying on ResourceFS files that the structure has changed.
Applications making use of ResourceFS should note that they have to look again to see if things have changed. For example, the Wimp responds to this service call by looking for its default sprite pool again.
R1 = &5A (reason code)
All registers preserved (do not claim the service)
This call is issued by ResourceFS just before it removes itself as a filing system. The expected uses are similar to Service_ResourceFSStarted.
R1 = &60 (reason code)
R2 = code address to call
R3 = workspace pointer for ResourceFS module
All registers preserved (do not claim the service)
When the ResourceFS module is reloaded or reinitialised, it issues this service call so that modules that provide ResourceFS files can put them back into the structure.
Unfortunately the ResourceFS module is not linked into the module chain at this point, so it is not possible to call ResourceFS_RegisterFiles. Instead, the application should execute the following code:
STMFD r13!, {r0, r14} ADR r0, ResourceFSfiles ; R0 -> ResourceFS file structure (Resource file data) MOV r14, pc ; R14 -> return address MOV pc, r2 ; call ResourceFS routine LDMFD r13!, {r0, pc}^
Note that the value of R3 passed in the service call must be given to the ResourceFS routine intact, so it can find its workspace.
This call is subtly different from SWI ResourceFS_RegisterFiles, in that it will not cause a Service_ResourceFSStarted to be issued. This is because the ResourceFS module waits until all modules have received the Service_ResourceFSStarting before issuing a Service_ResourceFSStarted to let the 'clients' of ResourceFS know about it.
R0 = pointer to resource file data
R0 corrupted
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This call should be made by a module adding files to the ResourceFS structure when the module is initialised.
ResourceFS will link the file(s) into its structure, and issue Service_ResourceFSStarted (not to be confused with Service_ResourceFSStarting), which tells any programs relying on ResourceFS files that the structure has changed.
None
R0 = pointer to resource file data
R0 corrupted
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This call should be made when the area of memory containing the files is about to be deallocated (e.g. when the module containing them is killed).
ResourceFS will unlink the file(s) from its structure, and issue Service_ResourceFSStarted (not to be confused with Service_ResourceFSStarting), which tells any programs relying on ResourceFS files that the structure has changed.
Note that it is not necessary to call this SWI on receipt of a Service_ResourceFSDying, since the ResourceFS module 'loses' all
references to ResourceFS files when it dies anyway.
None
Selects the Resource Filing System as the current filing system
*ResourceFS
None
*ResourceFS selects the Resource Filing System as the filing system for subsequent operations. Remember that it is not necessary to switch filing systems if you use the full pathnames of objects. For example, you can refer to ADFS objects when ResourceFS is the current filing system.
*ResourceFS
*ADFS, *Net, *RAM
None