RISCOS.com

www.riscos.com Technical Support:
Programmer's Reference Manual

 

The Filer


Introduction and Overview

The Filer is responsible for providing a graphical representation of the filing system structure. It uses standard filing system calls to do its work, and so will work with any filing system.

The filing-system-specific desktop filers - such as ADFSFiler - cooperate with the Filer by issuing the command *Filer_OpenDir when their icon is clicked on, so that the Filer can open the appropriate directory display. They also provide other operations which are not sufficiently generic to be provided by the Filer: for example the Format and Verify operations provided by the ADFSFiler.

See the chapter entitled Filer messages for full details on messages used by the Filer.

Service Calls


Service_StartFiler
(Service Call &4B)

Request to filing-system-specific desktop filers to start up

On entry

R0 = Filer's task handle
R1 = &4B (reason code)

On exit

R1 = 0 to claim call
R0 = pointer to * Command to start module

Use

In order to ensure that filing-system-specific desktop filers are not started up without the Filer module, they are started by a different mechanism. Rather than responding to the Service_StartWimp service call, they wait for the Filer module to start them up, using Service_StartFiler. The Filer behaves in a similar way to the Desktop, issuing the Service_StartFiler service call, followed by Wimp_StartTask, if the service call is claimed.

The Filer will try to start up any resident filing-system-specific desktop filer tasks when it is started (by responding to Service_StartWimp). It does this by issuing a service call Service_StartFiler (&4B).

If this call is claimed, the Filer starts the task by passing to Wimp_StartTask the * Command returned by the module. It then issues the service again, and repeats this until no-one claims it.

A module's service call handler should deal with this reason code as follows:

serviceCode
        LDR     r12, [r12]               ; Load workspace pointer
        STMFD   r13!, {r14}              ; Save link and make R14 available
        TEQ     r1, #Service_StartFiler  ; Is it service &4B?
        BEQ     startFiler               ; Yes
        ...                              ; Otherwise try other services
        LDMFD   r13!, {pc}               ; Return
startFiler
        LDR     r14, taskHandle          ; Get task handle from workspace
        TEQ     r14, #0                  ; Am I already active?
        MOVEQ   r14, #-1                 ; No, so init handle to -1
        STREQ   r14, taskHandle          ; R12 relative
        ADREQ   r0, myCommand            ; Point R0 at command to start task
        MOVEQ   r1, #0                   ; (see earlier) and claim the service
        LDMFD   r13!, {pc}               ; Return

Note that the taskHandle word of the module's workspace must be zero before the task has been started. This word should therefore be cleared in the module's initialisation code. If the task is not already running, the StartFiler code should set the handle to -1, load the address of a command that can be used to start the module, and claim the call. Otherwise (if taskHandle is non-zero) it should ignore the call.

The automatic start-up process is made slightly more complex by the necessity to deal elegantly with errors that occur while a module is trying to start up. If the appropriate code is not executed, the Desktop can get into an infinite loop of trying to initialise unsuccessful modules.

This is avoided by the task setting its handle to -1 when it claims the StartFiler service. If the task fails to start, this will still be -1 the next time the Filer issues a Service_StartFiler, and so it will not claim the service.

Note that the Filer passes its own taskHandle to the module in R0 in the service call, to make it easier for the task to send it Message_FilerOpenDir messages later.


Service_StartedFiler
(Service Call &4C)


Service_Reset
(Service Call &27)

Request to filing-system-specific desktop filers to set taskHandle variable to zero

On entry

R1 = &4C or &27 (reason code)

On exit

Module's taskHandle variable set to zero

Use

A task which failed to initialise would have its taskHandle variable stuck at the value -1, which would prevent it from ever starting again (as Service_StartFiler would never be claimed). In order to avoid this, the two service calls should be recognised by the filing-system-specific desktop filers. On either of them, the task handle should be set to zero:

serviceCode
        ...
        TEQ     r1, #Service_StartedFiler  ; Service &4C?
        BNE     tryServiceReset            ; No
        LDR     r14, taskHandle            ; taskHandle = -1?
        CMN     r14, #1
        MOVEQ   r14, #0                    ; Yes, so zero it
        STREQ   r14, taskHandle
        LDMFD   r13!, {pc}                 ; Return
        
tryServiceReset
        TEQ     r1, #Service_Reset         ; Reset reason code?
        MOVEQ   r14, #0                    ; Yes, so zero handle
        STREQ   r14, taskHandle
        LDMFD   r13!, {pc}                 ; Return
        ...

Service_StartedFiler is issued when the last of the resident filing system task modules has been started, and Service_Reset is issued whenever the computer is soft reset.


Service_FilerDying
(Service Call &4F)

Notification that the Filer module is about to close down

On entry

R1 = &4F (reason code)

On exit

Module's taskHandle variable set to zero

Use

If the Filer module task is closed down (e.g. if the module is *RMKilled, or the Filer task is quitted from the TaskManager window) the Filer module tries to ensure that all the other filing-system-specific desktop filers are also closed down, by issuing this service call.

On receipt of this service call, a filing-system-specific desktop filers should check to see if it is active and if it is, it should close itself down by calling Wimp_CloseDown as follows:

serviceCode
        ...
        TEQ     r1, #Service_FilerDying
        BNE     tryNext
        STMFD   r13!, {r0-r1, r14}
        LDR     r0, taskHandle      ; in workspace
        CMP     r0, #0
        MOVNE   r14, #0
        STRNE   r14, taskHandle
        LDRGT   r1, taskID
        SWIGT   XWimp_CloseDown
        LDMFD   r13!, {r0-r1, pc}^  ; can't return errors from service call
tryNext
        ...
taskID  
        DCB     "TASK"              ; word-aligned


Service_EnumerateFormats
(Service Call &6A)

Enumerate available disc formats

On entry

R1 = &6A (reason code)
R2 = pointer to list of format specifications suitable for a menu (initially 0)

On exit

R1 preserved to pass on (do not claim)
R2 = pointer to extended list of format specifications suitable for a menu

Use

This service call is issued to get information about the available formats, and to support !Help for those formats.

  • This service call should be issued when the information is required, as formats can be dynamically added and removed by soft-loading or removing modules. If this service call is only issued once, it is likely many formats would not be available (they may finish initialising later, or be soft-loaded later); consequently it is not recommended.

Each image filing system responds by adding entries to a linked list of blocks held in the RMA, each of which describes a format:

Offset Meaning
0 Pointer to next of these blocks, or 0 to indicate end of list
4 Pointer to RMA block containing text suitable for inclusion in the Format submenu
8 Pointer to RMA block containing text which is a suitable response for !Help for this entry in the Format submenu
12 SWI number to call to obtain raw disc format information
16 Parameter in R3 to use when calling disc format SWI
20 SWI number to call to lay down disc structure
24 Parameter in R0 to use when calling disc structure SWI
28 Flags:
Bit Meaning when set
0 'This is a native (ADFS) format'
1-31 Reserved - must be zero

The image filing system must fill in each block in this order:

  1. Allocate a data block in the RMA to link into the linked list
  2. Fill in 0 in the fields of the data block holding pointers to text
  3. Link the data block to the list by filling in the pointer at offset 0
  4. Allocate the RMA block to hold the text for the submenu entry
  5. Attach that RMA block to the data block by filling in the pointer at offset 4
  6. Allocate the RMA block to hold the help text for the submenu entry
  7. Attach that RMA block to the data block by filling in the pointer at offset 8
  8. Copy the text for the submenu entry into its RMA block
  9. Copy the help text for the submenu entry into its RMA block
  10. Fill in the rest of the data block

The image filing system must not set the pointers at offsets 4 and 8 to point at text embedded inside its code, but must instead copy the text into individually allocated RMA blocks.

Once it has filled in each block, it must pass on the service call for other image filing systems to attach their own formats.

This sequence of actions has been carefully constructed such that any error can be returned by claiming the service and returning both the error and an intact list. It is then the responsibility of the issuer of the service call to free the list.

The client must also free the list when the user has chosen a format, and must then initiate the format using the given parameters.


Service_DiscDismounted
(Service Call &7D)

Disc dismounted

On entry

R1 = &7D (reason code)
R2 = pointer to description of disc which has been dismounted

On exit

All registers are preserved

Use

This call informs modules that a disc has just been dismounted so they can take appropriate action. For example the Filer might close any open directory displays for that disc.

The value in R2 should be a pointer to a null-terminated string of the following form:

filing_system::disc

where filing_system is the name of the filing system, and disc is the name of the disc. If the disc has no name then the drive number should be filled in instead. For example, ADFS would issue the service call with these parameters:

R1 = &7D, R2 = 'ADFS::MyFloppy'

or, for an unnamed disc:

R1 = &7D, R2 = 'ADFS::0'.

This service call should not be claimed.

* Commands


*Filer_Boot

Boots a desktop application

Syntax

*Filer_Boot application

Parameters

application - a valid pathname specifying an application, the !Boot file of which is to be run

Use

*Filer_Boot boots the specified desktop application by running its !Boot file. This command is most useful in Desktop boot files.

You can only use this command from within the desktop environment, or within a Desktop boot file.

Example

*Filer_Boot adfs::mhardy.$.Apps.!PrinterPS

Related commands

*Filer_Run

Related SWIs

None

Related vectors

None


*Filer_CloseDir

Closes a directory display on the Desktop

Syntax

*Filer_CloseDir directory

Parameter

directory - the pathname of a directory whose directory display is to be closed

Use

*Filer_CloseDir closes a directory display on the Desktop, and any of its sub-directories. The directory display will typically have been opened by an earlier *Filer_OpenDir command, but it could equally well have been opened some other way.

Under RISC OS 2 the directory pathname must exactly match a leading sub-string of the title of a directory display for it to be closed. To avoid problems, your directory pathname should always include the filing system, the drive name and a full path from $. The case of letters is not significant, but the Filer uses lower case for filing system names.

This call will close all directory displays that match the specified sub-string. Under RISC OS 2 the minimum substring you can pass is the filing system only, whereas under RISC OS 3 you must also specify the drive name.

You can only use this command from within the desktop environment, or within a Desktop boot file.

Example

*Filer_CloseDir adfs::applDisc.$.progs.basic

Related commands

*Filer_OpenDir

Related SWIs

None

Related vectors

None


*Filer_OpenDir

Opens a directory display on the Desktop

Syntax

*Filer_OpenDir directory [x y [width height]] [switches]

Parameters

directory - the pathname of a directory whose directory display is to be opened

x - the x-coordinate of the top left of the directory display, in OS units

y - the y-coordinate of the top left of the directory display, in OS units

width - the width of the directory display, in OS units

height - the height of the directory display, in OS units

switches - switches to control the display type of the directory display; there are alternatives; the case of the letters is not significant:

-SmallIcons (-si) - display small icons
-LargeIcons (-li) - display large icons
-FullInfo (-fi) - display full information
-SortByName (-sn) - display sorted by name
-SortByType (-st) - display sorted by type
-SortByDate (-sd) - display sorted by date
-SortBySize (-ss) - display sorted by size

Use

*Filer_OpenDir opens a directory display on the Desktop.

Under RISC OS 2, if the directory pathname exactly matches the title of a directory display that is already open, it simply stays open; no new display appears. However, if the pathname is even slightly different from a display's title (eg you omit the $. after the drive name), it will be treated as a different directory. This can result in two displays looking at the same directory.

To avoid such problems, your directory pathname should always include the filing system, the drive name and a full path from $. The case of letters is not significant, but the Filer uses lower case for filing system names. This also ensures that applications run correctly, since they use their pathnames to reference files within themselves.

RISC OS always ensures that the opened directory display is entirely visible on the desktop, and that its size is within the normal limits imposed by the Filer. Invalid parameters are rounded up/down until valid.

Each parameter - except for the switches - can be preceded by a keyword for the sake of clarity. This is especially useful when writing scripts. There are variants on the keywords; again, the case of the letters is not significant. Valid keywords are:

Keyword Alternative Precedes parameter
-dir -directory directory
-x0 -topleftx x
-y1 -toplefty y
-width -w width
-height -h height

You can only use this command from within the desktop environment, or within a Desktop boot file.

Example

*Filer_OpenDir adfs::applDisc.$.progs.basic

Related commands

*Filer_CloseDir

Related SWIs

None

Related vectors

None


*Filer_Run

Performs the equivalent of double-clicking on an object in a directory display

Syntax

*Filer_Run object

Parameters

object - a valid pathname specifying an object to be treated as if double-clicked on

Use

*Filer_Run performs the equivalent of double-clicking on an object in a directory display. For example an application would be run, a directory would be opened, and a file might be loaded into the relevant application. This command is most useful in Desktop boot files.

You can only use this command from within the desktop environment, or within a Desktop boot file.

Example

*Filer_Run adfs::mhardy.$.Apps.!PrinterPS

Related commands

*Filer_Boot

Related SWIs

None

Related vectors

None

This edition Copyright © 3QD Developments Ltd 2015
Last Edit: Tue,03 Nov 2015