Message protocol used by Schema 2

Author: C J Bazley (for APDL)
Date: 07 Feb 2007
Revision: 2


This document describes a message protocol used by the RISC OS spreadsheet application Schema 2 and its supporting programs. Whilst the method described is flexible enough to be used for other applications where file format conversion may be required, at the time of writing no other software is known to use it.

Schema 2 can import (and in some cases export) data in various file formats such as 'Sheet' (from Schema), 'WK1' (from Lotus 1-2-3) and SID. This requires support from external applications to do the hard work of converting foreign file formats to its native file type 'ASheet' (&C26) and vice-versa. This approach of farming out file format conversions has the advantage of making the code more modular and reducing the memory requirements of the main program.

Because the protocol described is fairly generic, Schema 2 will henceforth be described as the 'client' and any application providing file format conversion as the 'converter'.

It is assumed that the reader is already familiar with the data transfer protocol described in the RISC OS 3 PRM (volume 3, chapter 53). This document defines a preamble to that protocol which consists of three extra messages; one to request a conversion and specify the output destination (PleaseConvert), another to signal willingness to do a conversion (WillConvert) and a third by which a converter can notify its client that it is ready for use (ConverterReady). A fourth message (DataLoadEnd) serves only to aid client tasks in processing a batch of consecutive DataLoad messages, for example when the user drags a selection of files from a directory display.

If a converter application has been 'seen' by the Filer then client tasks can automatically load it as required. To this end, a naming convention for system variables and the command line syntax for invoking converters are also described.


There are two situations in which a client task may require help from an external converter; one where the user tries to import a file of unrecognised type and the other where they wish to export data in a foreign file format. Whilst the final destination is different in each case, they are described together here for the sake of brevity.

To start a conversion operation, the client task broadcasts message PleaseConvert as recorded delivery. The message data consists of the RISC OS file types to convert from and to, a task handle and then data in the same format as for a DataSave message. The task handle and embedded DataSave message data are for use only after a successful conversion.

If importing data, the client should include its own task handle and copy the destination coordinates, window & icon handle from the DataLoad message it received. The leafname may be extracted from the full path in the DataLoad message.

If exporting data, the client should set the task handle to 0 and call SWI Wimp_GetPointerInfo to get the coordinates, window & icon handle at the drag destination. The leafname should be that specified by the user.

The filetype at +56 should be the same as the type to convert to (at +24). The estimated size (of the converted data) at +52 is unlikely to be accurate but since many converters use it verbatim in their DataSave message, a nominal value such as 1024 should be provided by the client.

If a converter receives Message_PleaseConvert and can handle the requested conversion then it should retain the message data and reply with Message_WillConvert (also sent as recorded delivery). If the client's PleaseConvert message returns undelivered then it may try to start a suitable converter; see below.

If exporting data, the client should reply to a WillConvert message with a recorded DataSave message. The leaf name is conventionally the same as in the PleaseConvert message.

If importing data, the client should reply to a WillConvert message with a recorded DataLoad message. The file path must be that of the file to be loaded (as received in the original DataLoad message).

In either case the destination coordinates, window & icon handle are unimportant (conventionally 0). The file type and estimated size should be those of the data in its original format. However current versions of Schema 2 provide a garbage value for the estimated size so converters should not rely on this.

Thereafter, communication between client and converter follows the standard data transfer protocol (as described in the RISC OS 3 PRM), until all the data to be converted has been sent. The converter may request in-memory data transfer by replying to DataSave with a RAMFetch message, but the client task is not obliged to support this.

Once a converter has received all the data and converted it to the requested format, it should send a recorded DataSave message using the destination coordinates, window & icon handle, file type and leaf name from the PleaseConvert message. The estimated size may be replaced with that of the output data. If the destination task handle (at +32) was 0 then the DataSave should instead be sent to the specified window and icon handle.

Thereafter, all message communication between converter and destination task (which may be the client, if importing data) follows the standard data transfer protocol, until all the converted data has been sent.

Starting a converter

If a PleaseConvert message broadcast returns undelivered then this indicates that no running task is willing to perform the specified conversion. However the client may be able to locate a suitable converter by reading the value of system variable Conversion$IIIToOOO, where III is the RISC OS file type of the input data and OOO is the file type to convert to (both are three digit hexadecimal values).

The !Boot file of an application is a good place to set system variables for supported conversions. Each must be named according to the convention described above and assigned as its value a file path by which the converter can be invoked (additional command line arguments may be included). If an application can convert both ways then it should set one system variable for A->B and another for B->A.

If the system variable corresponding to the required conversion does not exist then the client may report an error to the user, e.g. 'Cannot import/export file of that type'. Otherwise the client should use SWI Wimp_StartTask to start the converter task using the following syntax:

*Run <Conversion$%XTo%X> -quit -reply(%x,%x).

The command line arguments -quit and -reply must be supported by all converters. If specified, -quit means that the converter should quit once it has completed its task and -reply means that it should send a ConverterReady message once it has initialised. Both values inside the brackets are lower case hexadecimal. The first is the client's task handle and the second is the message ID to quote as your_ref (conventionally the my_ref of a failed PleaseConvert broadcast).

The client may report an error if it does not receive a ConverterReady message after starting a converter. For example, Schema 2 gives up waiting for a ConverterReady message after four Null events or another non-message event has been returned by Wimp_Poll.

Upon receiving a ConverterReady message, the client should check that the your_ref field matches that passed on the command line and then re-send its recorded PleaseConvert message in reply. If this message returns undelivered again then the client must give up.


Message_PleaseConvert (&82640)

R1 + 0 64 - 256 (size of block in bytes)
R1 + 4 task handle of client
R1 + 16 &82640 (message action code)
R1 + 20 file type to convert from
R1 + 24 file type to convert to
R1 + 28 0 (unused)
R1 + 32 destination task handle for DataSave message, or 0 to use window and icon handles
R1 + 36 destination window handle
R1 + 40 destination icon handle
R1 + 44 destination x coordinate
R1 + 48 destination y coordinate (screen coordinates)
R1 + 52 estimated size of data in bytes
R1 + 56 file type of data (should be same as at +24)
R1 + 60 proposed leafname of data, zero-terminated

This message is always sent as recorded delivery (code 18). It is initially broadcast by the client task to discover whether there is another task already running which can do the requested conversion. It may subsequently be sent to a specific task in reply to a ConverterReady message.

The message data from +36 onwards is equivalent to that for DataSave. An application that is capable of doing the specified conversion should retain this data and reply with message WillConvert.

Message_WillConvert (&82641)

R1 + 0 20 (size of block in bytes)
R1 + 4 task handle of converter
R1 + 12 'my_ref' copied from PleaseConvert message
R1 + 16 &82641 (message action code)

This message is sent by a converter task as a recorded delivery (code 18), in reply to a PleaseConvert message. It indicates that the sender is willing to carry out the requested conversion operation.

There is no data in the message block except the header.

Message_ConverterReady (&82642)

R1 + 0 20 (size of block in bytes)
R1 + 4 task handle of converter
R1 + 12 message ID specified on the command line
R1 + 16 &82642 (message action code)

This message is sent by a converter task when it is started using the special -reply command line argument described earlier. It is sent to the client task, quoting the specified message reference as your_ref (usually the my_ref of a failed PleaseConvert broadcast).

There is no data in the message block except the header.

Message_ConverterMinimise (&82643)

This message action code has been allocated but is not currently used.

Message_DataLoadEnd (&82644)

R1 + 0 20 (size of block in bytes)
R1 + 4 task handle of client
R1 + 12 0 (not a reply)
R1 + 16 &82644 (message action code)

This message is sent by the client task to itself after it has queued an incoming DataLoad message for a file type that can only be loaded with assistance from a converter. Because it will not be delivered until after any further DataLoad messages in the same batch, receipt of this message is used to trigger processing of the queued DataLoad messages.

There is no data in the message block except the header.