Introduction
The External Edit protocol allows one application to delegate editing, display, or playback of a single data object to another application. The client application starts an external editing session, transfers an initial data object if required, and later requests the edited data back. The editor application opens an appropriate window or playback context for that object, allows the user to work with it, and returns the resulting data through the normal RISC OS data transfer mechanisms.
Overview
The protocol is intended to provide a simple, desktop-oriented alternative to embedding many specialised editors inside larger applications. It applies the same basic idea used by command-line systems, where an application saves data, invokes an external editor, and then reloads the result, but adapts that model to a multitasking desktop environment.
The protocol also exists as a reaction against monolithic applications that contain their own weak built-in editors for specialist data. Instead of forcing every application to carry a private bitmap editor, text editor, sound viewer, or palette chooser, the desktop can share one capable editor for each kind of data and let users choose which editor they prefer.
Using a separate data editor has several practical advantages:
- The main application does not need to contain all the editing code for every data type it wishes to support.
- The editor code need only be resident and executing while it is actually needed.
- The user can choose one preferred editor for each kind of data and use that choice consistently across applications.
- The main application can support data whose detailed format or editing semantics it does not fully understand.
- An editor does not have to be an editor in the narrow sense; it may simply display, play, or otherwise present the data.
The protocol therefore provides a lightweight form of hotlinking. The data is treated as a single transferable object, handed out to another task for work, and later returned as a single object. It does not try to provide continuous, system-wide live linking, but it does provide a simple and effective base level of inter-application cooperation with far less operating system support and far less implementation complexity.
An external edit session always involves three parties:
- The client, which requests the session and may later request the data back.
- The editor, which claims the request and provides the editing or playback environment.
- The user, who decides when to edit, save, discard, or close the external session.
The protocol is deliberately built around standard Wimp messages and the existing RAM transfer and file transfer protocols. This keeps client-side support small and allows editors to reuse existing data transfer code.
Typical uses
The original protocol document described a range of uses that motivated the design:
- A compiler can open a source file in a text editor, position the cursor at the error, and recompile when the user requests return of the edited text.
- A desktop publisher can hand a DrawFile illustration to a drawing package and later replace the embedded object with the returned result.
- A DrawFile editor can hand text areas to a text editor and sprites to a paint package.
- A music or sample editor can display and play individual sample data in a specialist sample editor.
- An adventure authoring system can use fully-featured external text and graphics editors while keeping only the game-specific location and object editing logic in-house.
- A hypermedia or browser-style application can ask the desktop to display or play file types that it does not itself understand.
- A configuration tool can centralise preference editing for multiple applications through a shared editor for the configuration data.
- Palette or true-colour chooser data can be delegated to a colour editor that returns the chosen values in a form the client can use.
Technical Details
Session model
The client starts a session by broadcasting . An editor that can handle the requested data type opens a blank editing context and replies with . The client may then send one or more messages to insert data, may use to set or inspect the current cursor or selection, and may use to request the edited data back. Either party may terminate the session with .
The editor may also initiate return of the data, for example when the user chooses a save action or closes the external edit window. The returned data is sent through followed by the normal Acorn data transfer messages.
Common data items
Data type word
Most protocol messages carry a 32-bit data type word in the form &eeee0ttt. The low 16 bits carry the base RISC OS file type. The high 16 bits carry an extension that refines the meaning of that file type when a plain file type is not precise enough.
An extension of &0000 means that no extra typing information is supplied beyond the base RISC OS file type. Values &0001 to &04FF are reserved for user allocation, although shared protocol use benefits from a single agreed allocation for each specialised data type.
Job handle
The job handle identifies one session throughout its lifetime. It has the form &eeeecccc, where the low 16 bits are chosen by the client and the high 16 bits are chosen by the editor. Both halves must be non-zero. Once established, the handle never changes for that session.
Each side should choose values that are unique across the lifetime of the task, rather than recycling handle values. A practical implementation is to use part of the local 16-bit half as a monotonically increasing session number and part as an array index, then validate the full 32-bit handle before acting on any message for an existing session.
Flag word
The protocol uses a single flag word layout across all messages. Some flags are only meaningful for particular messages; unsupported or irrelevant flags should be ignored.
| Bit(s) | Name | Meaning | |
|---|---|---|---|
| 0 | Continue editing | For messages that return data, this bit controls whether the session continues after the transfer completes. A set bit means that editing should continue; a clear bit means that the session should end once the data has been returned. | |
| 1 | Selection only | In , this bit requests that only the current selection be returned. When data is returned, the same bit reports whether the whole object or only the selection is being sent. | |
| 2 | Read-only | Requests that the editor treat the data as read-only. Editors that support read-only operation should prevent modification; clients must still be ready to ignore unexpected attempts to return changed data. | |
| 3 | Immediate execution | Requests that playable or executable data should start as soon as practical after receipt. If the data type has no playback concept, the editor ignores this flag. | |
| 4 | Adjust selection | For , adds the supplied selection range to the current selection rather than replacing it. | |
| 5-31 | Reserved, must be zero | ||
Data transfer
The protocol does not define a new payload transfer format. Instead, it uses as the session-scoped equivalent of Message_DataSave, then follows the normal RAM transfer or file transfer conventions already used elsewhere on the desktop.
The client typically sends one initial data transfer immediately after receiving , but a blank edit window is also valid. Additional transfers from the client are inserted at the current cursor position when that concept exists. Transfers from the editor return the current edited object or selection to the client.
Cursor and selection model
positions a cursor, selects a contiguous range of data units, or queries the current values. The smallest meaningful unit depends on the data type. If no specialised unit has been agreed for a type, byte offsets are the default.
The cursor position identifies a data unit counted from the start of the object. Unit 1 is the first item, unit 2 the second, and so on. For text-like data where a caret sits between units, the caret is positioned after the named unit; the special position 0 therefore places the caret before the first unit. For object-based formats such as DrawFile, position 0 should be treated as 1.
The value -1 (&FFFFFFFF) means "leave this position unchanged". The value -2 (&FFFFFFFE) means "end of data". Setting all three new position fields to -1 reads the current positions without moving them.
| Type | File type | Data unit |
|---|---|---|
| Text | &FFF | Character. |
| Command | &FFE | Character. |
| TaskObey | &FD7 | Character. |
| TaskExec | &FD6 | Character. |
| Obey | &FEB | Character. |
| Data | &FFD | Byte offset. |
| BASIC | &FFB | Byte offset in tokenised form, or character offset in text form. |
| Sprite | &FF9 | Sprite number or index. |
| Palette | &FED | Colour index in the standard file format. |
| DrawFile | &AFF | Draw object. |
| ARMovie | &AE7 | Animation frame number. |
Returning data
The client can explicitly request return of the edited data by sending . The editor can also return the data because of user actions within the editing session.
Common editor-side triggers are:
- The user chooses a save action or confirms the save-as dialogue, in which case the editor returns the data and then ends the session only if the Continue editing flag is clear.
- The user drags the save icon to a file destination, in which case the editor writes a copy to disc and continues editing.
- The user closes the external edit window, in which case the editor should offer the same Save, Discard, and Cancel choices that it would for an ordinary modified document.
Error handling and closure
Missing replies do not always indicate failure. Some protocol steps expect no response, and in particular is not a reliable heartbeat for session liveness. A session should only be assumed dead when a definitive failure occurs or when the surrounding data transfer protocols report a real breakdown.
When communication has genuinely failed, or when either task must abandon the session unexpectedly, it should send if at all possible and then release all local state for that handle. Clients should treat externally edited data as modified data when deciding whether a document may be closed.
If a document contains data currently being edited externally, closing that document should behave like closing a document with unsaved changes. The user should be able to request a return-and-save operation or discard the external session explicitly.
Multi-file and nested editing
ExtEdit exchanges a single data object. Document formats that consist of multiple files or directories must define their own representation for transporting that object as a single transferable entity. One workable approach is to avoid RAM transfer for such formats and rely on saved files on disc; another is to define a custom single-file transport form.
Editors should treat child external edits as separate sessions rather than automatically pulling those child results back into the parent object when the parent itself is returned. A parent editor may warn that child external edits remain unreturned, but it should not silently update its own return data from those child sessions.
Registered users and future extensions
The original document recorded current and planned users of the protocol to encourage adoption and interoperability. At that time, StrongEd 2 and StrongHlp already supported the protocol, and Zap, ZEdit, and DSEdit II were listed as intending to support it.
The protocol also reserved space for future extension. New flag bits, extended data types, and any extra messages or SWI-based support layered on top of the core protocol should be allocated in a coordinated way so that independent applications do not collide.
Wimp Messages
System Variables
Clients that receive no suitable reply to should first retry with less specific data types or with a read-only request if that is acceptable. If no editor is already running, the client may then attempt to start one by executing the most appropriate Alias$@EditType_xxx variable, where xxx is the three-digit hexadecimal base file type.
Editors should normally define these aliases in their boot sequence so that clients can run a suitable editor without hard-wiring any particular application name.
Examples
Boot-time alias definition
An editor for plain text might define both a normal run alias and an ExtEdit alias in its boot file:
Set Alias$@RunType_FFF Run <Obey$Dir>.!Run %%*0
Set Alias$@EditType_FFF Run <Obey$Dir>.!Run
Client fallback behaviour
A robust client follows this general policy:
- Broadcast for the preferred extended data type.
- If no editor replies, retry with a less specific type or with a read-only request if displaying the data would still be useful.
- If no running editor responds, execute the most appropriate Alias$@EditType_xxx variable and then retry the request.
- If every attempt fails, report to the user that no suitable editor is available.