External data editing protocol
Designed by Jason Williams

NOTES

Document version 1.00, 25 November, 1992.

This protocol is FreeWare.
Anybody may use it for virtually any purpose, so long as that purpose is the one for which it was designed! I wish the protocol to be useful to the user, which means that it needs widespread support. Please do not design "in-house" protocols along similar lines: We need universal compatability with this protocol.

You may NOT alter or augment this protocol in any way or form, though any suggestions forwarded to the address at the bottom of this text will be given consideration for inclusion in a future update to the protocol.

Introduction

The right idea:
Those people who have used command-line UNIX a bit will have encountered a very useful feature of it - when any program needs to edit a text document, it simply saves that document to a temporary file, and invokes a text editor on the file. When the text editor finishes, the application re-loads the (changed) temp. file, and continues.

The wrong idea:
Using Macromind Director and Hypercard on the Macintosh, I noticed that they *both* include their *own* bitmap editor sections. These editors are *both* very bad. SuperPaint 3 is very good, however: It would be nice if Superpaint could be installed as the "bitmap editor section" of the other programs. Superpaint could then be used as a shared bitmap-editor resource, and the user gets a *good* bitmap editor for use within the other programs.

This is the story of a new protocol for the Archimedes that allows us to do something very similar to the UNIX-based idea mentioned above, only on the desktop...

Using a separate editor has distinct advantages-

On the Archimedes, a similar concept would be useful: if you have some data in a standard format (text, sprite, drawfile, etc) that needs to be edited (or just displayed), then you should just be able to invoke another application to go away and edit that data, and return the data to you when the editing is finished.

This is *similar* to hotlinking, but much simpler - the data is set out as a single chunk, and _some_time_later_ is brought back in as a single chunk. Examples of use might be:

Some of this can be achieved at present through the use of rather messy and "hacky" trickery with Data Transfer messages and file-watching. However, a proper protocol is very simple to implement, and yet exceedingly useful and powerful.

To supply more integrated hotlinking than the above requires large alterations and/or additions to the operating system and very complicated protocols. However, the following protocol gives a very passable base level of 'hotlinking' that is exceedingly quick and easy to support in RISC OS applications, but which can increase the usability of the desktop for certain operations immensely. Aside: With any application, a very simple editor could be built in or
(preferably) be supplied as a small, separate application, so that even if the user hasn't got a correct editor to handle the external-edit data, an editor is at least available.

The message protocol

Two applications are involved in the process: An 'editor' (which supplies the window and editing functions), and a 'client' (which initiates the edit, and supplies data to the editor and/or expects data back from the editor later). The 'user' is the person using the computer.

Example sequence:

The Messages

There are 5 messages defined for this protocol. They are:

  Message Name          Description                            Number

  Message_EditRq        Request external editing session       &45D80
  Message_EditAck       Acknowledge external edit              &45D81
Message_EditReturn Request return of external edit data &45D82
  Message_EditAbort     Close editing session completely       &45D83
Message_EditDataSave External edit equivalent of DataSave &45D84

Protocol details

Initiating an external data editing session

When the client decides to tender some data for external-editing, they broadcast an EditRq message to all other applications.

This message should be broadcast with an event-type 18 (message should be acknowledged). This will then return the message back to you if nobody replied to it, which makes it easy to modify the message body and re-try. If your editor supports both client and editor sides of the protocol, be sure to check whether a request originated from yourself!!

The message should contain the most specific data-type word needed. Example: if you wish to export text containing RTF commands, you

	       should broadcast a message with the text/RTF data type in order
	       to allow editors to supply a WYSIWYG editing window, or as
	       text/000 if you want it to be edited as a generic textfile.

If the client does not recieve an EditAck, then they can:

Loading initial data

Client:
After recieving a valid EditAck for the data (check the bottom 16 bits of the job handle to see if it matches your request):

You will need to remember where (which window/icon/frame/object/file) the source data came from, along with the job handle and accepted data type, so that they can replace the current version of the data with the data returned by the editor later.

If the client wishes to start editing a 'blank' file: Do nothing. The window is already open and the external-edit job is under way.

If the client wishes to supply the data to be edited, the client should initiate a data transfer with the EditLoad and/or EditTransfer messages.

Editor:
When recieving any EditDataSave message, it can be treated as a normal DataSave message, EXCEPT, of course, that you must treat the job handle field slightly differently to the window-handle field of the DataSave message.
In many cases, you can simply replace the job-handle field with the appropriate window handle and then allow your code to treat the message as it would any normal DataSave message, to intitate a RAM or Wimp$Scrap transfer of the data.

Saving data back to client

Editor:
If the user closes the window:
If the file is changed, Ask the user (as normal) if they wish to discard
the file, and save (as detailed below) back if necessary.
Close the window (end the external editing session)

(i.e. if the file is unchanged, simply close the window and forget the external-edit session)

If the user clicks "Save" on the menu or "OK" in the save box, etc: Save the file back (as detailed below) If flagword bit 0 (continue) == 0, close the window (end the external

				       editing session)
if flagword bit 0 (continue) == 1, do nothing more (continue editing)

If the user drags the file icon to another window: treat it as a normal save operation, but do not forget that this is still an external edit window. Continue editing as if nothing had happened. The window title should *not* be changed to indicate that the file is unmodified. The title should also continue to show the "(Parent) LeafName" format rather than the newly saved filename, though the leaf-name should be changed to reflect the name the user saved under.

In case of fatal error:
Don't return the file to the client: It may be corrupted. Save the file as Edit and Paint do, in the Scrap directory, if possible. You should not tell the client anything about the problem. Client:
Recieves EditDataSave:
Treat exactly as a normal DataSave message, except you must replace the old
data with the new data, rather than loading the data as a new file as
would happen with a normal DataSave.

Client request for data return

If the client wishes to initiate the return of the data (e.g. a mail-reader might have a button 'Send letter' which sucks the data back out of the editor and sends it), they send a Message_EditReturn to the editor. This initiates the EditTransfer/EditLoad data transfer operations as normal.

Closing the connection

Client:
Either:
      Request the data back (if you want it) with EditReturn, with the Continue
      bit of the flagword set to 0,
or
      Send an EditAbort message.

Editor:
If you wish to return the data first,

      Initiate an EditDataSave data transfer to the client as detailed above
      for saving. Once this is complete, you can then...
Send an EditAbort message.

Problems?

If either party appears to ignore messages from the other, then NO action should be taken: Abort the operation, and assume that the external edit is finished ("no correspondence shall be entered into"!). All future correspondence relating to this job handle should be ignored.

If the editor fails to return data when expected to, this means:

If the client fails to communicate, this means: -it is obvious that in any of these cases, there is nothing to do.

If your program suffers any error that compromises its ability to return or recieve the data intact, or gets confused in any way, it should break off communications (by ignoring everything to do with this job) QUIETLY (i.e. NO error boxes!)
If possible, let the other application know that the session has been aborted

Message definitions

Message_EditRq (Request external edit, number &45D80) This is sent by a client as a broadcast. Any editor recieving it should check the data type, and if they can supply the service needed, they should claim the message with an EditAck, and open a blank, appropriate editing window.

R0 = 19
R1 + 20 Data type word.

	      The least significant 16 bits of this word will contain a RISC
	      OS file type (e.g. text = 0x0fff).
	      The most significant  16 bits will contain an allocated
	      sub-type number which further describes the file contents.
	      The sub-type number 0x0000 is allocated for all data types
	      and indicates that the file-type is all the information
	      that is necessary/available for the editor.
	      e.g. a "text" file (0x0fff) could contain normal text,
		   an RTF document description, or a drawfile text-area.
		   Each of these types of 'text' will be allocated their
		   own subtype number. (See below)
	      Special/Allocated sub-type numbers currently are:
0x0000 No special subtype. The file-type gives enough info. 0x0001 }
to } User values. But please request a proper allocation 0x04ff }
	      Special numbers for internal use by an application must be
	      registered: These will be allocated a subtype number of the
	      file-type 0x0000.

R1 + 24 Job handle

	      The client should place a unique, non-zero integer "job handle"
	      into the least significant 16 bits of this word. The most
	      significant bits should all be set to zero.
	      (i.e. 0x0000xxxx where xxxx is > 0)
	      (see below for more details)

R1 + 28 Flag word

	      This word contains a set of 'extra options' flags which should
	      be remembered by the editor. These flags are also used in
	      some of the following messages. Unrecognised flags should be
	      set to zero by clients, ignored by editors.
	      Defined flags at present are:
	      
	      bit(s):
		0     Continuous editing (&01)
		      Normally, all actions by the user to save the data
		      back to the client will result in the edit session
		      (and window) being closed.
		      If this flag is set and the user saves the file back to
		      the client through the save-as window or by clicking
		      "Save" on the menu, then the edit window will NOT be
		      closed.
		      However, if the window is closed, then the data will be
		      sent back to the client, and the window closed as normal.
		1     Whole file flag (&02)
		      This bit should be set to zero, and ignored. It is only
		      used by the EditReturn message (below).
		2     Read-only (&04)
		      This flag is set to indicate that the editor should not
		      allow editing of the data, i.e. the editor provides
		      display functions only.
		      The editor may not be capable of supporting this flag.
		      In return of the flags, the editor will set this flag
		      to indicate the actual status.
		3     Immediate playback (&08)
		      This allows the client to request that (e.g) a sound
		      sample is played immediately and is NOT displayed in a
		      window at all.
		      Another example is the request of 'editing' an ARMovie
		      file: Normally, this would appear in a window, waiting
		      for the user to press 'play', but with this flag bit
		      set, the movie should begin playback immediately that
		      the data transfer is completed.
		      At completion of playback, the session is considered
		      aborted, so no extra messages need be sent.
		      An abort message may be sent at any time to cease
		      playback and abort the session.
		      This flag does not apply to all types of data. For types
		      to which it does not apply, it will be ignored.
		      This flag has no effect until data is sent to be played!

4-31 Reserved: Must be set to 0

R1 + 32 A 20-character 0-terminated string identifying the parent

	      document/app (it's file leaf-name, generally). The editor should
	      change the edit-window title to read "(Parent) Filename" to
	      indicate that the file is a temporary edit of data from the
	      document/application "parent".
	      If this entry is blank (the byte at block+32 == 0), then
	      use the normal "Filename" title-bar layout.

R1 + 52 A 20-character suggested leaf-name for the edited file.

	      This will be displayed by the editor in the titlebar of
	      the edit-window, and will appear as the default in the
	      save-as box. If this entry is blank (the byte at
	      R1 + 52 == 0) then use the default name for this filetype
	      (e.g. Edit would use "TextFile" for a text file)

---

Message_EditAck (Acknowledge external edit, number &45D81) If an editor can supply the requested service it opens an appropriate editing window, and then replies to the client, indicating in the message:

R0 = 17
R1 + 20 Data type word

	      Copied from EditRq message.

R1 + 24 Job handle

	      The editor fills in the top 16 bits with a unique, non-zero
	      integer identifier, and the bottom 16 bits with the number
	      given by the client in the EditRq message. Both applications
	      will use the resulting word as a unique job handle.

R1 + 28 FlagWord

	      Copied from EditRq message, with some bits perhaps modified
	      to indicate current status. (See above for a description)
	      Note that if the 'editor' cannot supply editing functions,
	      but only displays the data, it should set the 'read-only'
	      bit to inform the client of it's abilities: If this is
	      unacceptable to the client, it should warn the user, and then
	      abort the session.(see below)

---

Message_EditReturn (Request return of external edit data, number &45D82) This message is sent by the client to the editor, to request the return of the data. This allows the client to provide a menu option or a button somewhere that will retrieve the data or retrieve it and begin some operation upon it.

R0 = 17
R1 + 20 Data type word

	      Included to allow the client to request the data back in a
	      specific format, not necessarily the original format.
	      If no reply is recieved, then the editor is unable to supply
	      the data as requested: Re-try with a request for the original
	      data type, and if this fails, assume that the editor is dead
	      or indisposed and forget it.

R1 + 24 Job handle

R1 + 28 Flag word

	     As for the other messages:
	       Continue bit   - {0 = Don't/1 = do} continue editing session
						   after transfer.
	       Whole file bit - 0 = Send whole file, 1 = send selection
	       Read-only/Immediate-playback are ignored.

---

Message_EditAbort (Close editing session completely, number &45D83) R0 = 17
R1 + 20 reserved (should be 0)
R1 + 24 Job handle

This message can be sent by either party. If this message is recieved, then mark this job handle as defunct - From now on, any correspondance relating to the job handle should be ignored.

The editor should also close the window and stop editing. Note that this should be done in ALL circumstances, even if the data has been modified. It is up to the client to warn the user and ensure that it's OK to lose the data. The client should always treat external data as modified data.

Note that the SENDER of the message is responsible for any error report that may indicate to the user that the edit has failed. Thus, the reciever should not take any error-reporting action.

EditAbort should be sent whenever a job must be aborted (fatal error, task quitting, etc.) in order to allow the other party to release workspace allocated to the editing session; however, if you fail to Abort for whatever reason, ignore all further messages relating to this job, and eventually the other party will give up.

Note, however, that in some fatal cases, it is better to NOT send an abort, as this will allow the user to save their edited data and retrieve at least some of the data which would otherwise be lost when your application unexpectedly quits.

If playback of any type is running due to use of the 'immediate playback' flag bit, then playback should cease immediately.

---

Message_EditDataSave (Equivalent of DataSave, number &45D84) This message is almost identical to Message_DataSave. It is used in exactly the same manner, except instead of specifying a window/icon destination, it supplies a job-handle to indicate the destination. All fields can/should be filled in as for a normal DataSave message, except for the job handle field.

R0 = 17
R1 + 20 job handle (normally window handle) R1 + 24 reserved (normally icon handle) R1 + 28 reserved (normally X position) R1 + 32 reserved (normally Y position) R1 + 36 estimated size of data, in bytes R1 + 40 file type of data

	       NOT data-type, just base file-type, as in normal DataSave msg.
R1 + 44 proposed leaf-name of file, 0-terminated

NOTE:
Normally, this message will follow EditRq, as soon as the client recieves the EditAck, in order to supply the initial data for editing. However, it should be noted that the message need not be sent if the client wants only a 'blank' editing window.

Also, it is possible that the client will send this message more than once, in which case the first message will indicate the data to load, and subsequent messages will indicate data to be *inserted* as if dragged into the editing window. In this case, how insertion works is up to the discretion of the editor's writer, but here are some examples to indicate my intentions with this usage:

      Text Editor:
This would insert the text at the current cursor position. In our mail-reader example, this would allow the user to click on a line of text in a letter, and then click on a 'quote' button in order to copy the line of text to the current cursor position in their reply.
      Drawfile editor:
This type of editor has no notion of 'current cursor position', so a reasonable thing to do would be to add the new data to the data being edited, and position the new draw objects so that they are at least partially visible in the window.

If the editor cannot supply this service, either due to limited support for this protocol, or due to difficulties presented by the data type, the EditDataSave should be ignored and an error should be reported, along the lines of "This operation is not supported".

If the 'immediate playback' flag-bit was set in the initial EditRq, and the data is 'playable', then playback should be commenced as soon as this data transfer is complete. As soon as playback finishes, the session should be considered aborted (no extra messages need be sent).

---

Extra Notes

Although each application should be prepared for a communications breakdown and treat such breakdown as an abort operation, it is polite to send an abort message whenever you wish to cancel an editing session.

If you wish to quit or close a document containing data that is currently tendered out for external editing, then the external data should be treated as modified/unsaved data, i.e. you should inform the user "There is unsaved (external) data in this document", and allow them to initiate a return of the data, or discard the data, much as you would with normal unsaved data. Please ensure that you send an abort in the latter case, as it is undesirable to have unattached editing windows floating around.

---

As you hopefully realise by now, this is a very simple protocol to implement for a client (it involves sending && recieving 2 messages at a minimum, plus passing of EditDataSave messages to a slightly augmented DataSave handler), and reasonably simple for an editor to implement (depending on the level of support provided). However, despite it's simplicity, it provides a bidirectional communications protocol that enables several powerful abilities which are markedly absent from current protocols (or available only through rather dubious 'hacks').
The main point I have to make here is that this protocol will only reach it's most useful potential when it has a reasonable level of support from applications. It will only take support for this protocol in about 5 different editors (sounds, drawfiles, sprites, text, etc) before it will be possible to get much much more out of virtually any application with client-end support.
PLEASE support this protocol!

---

Although this protocol has been given an official message-number allocation, it should be noted that this protocol is not _officially_ endorsed by Acorn, and has nothing to do with them whatsoever, except that it is for use on their operating system.

All messages and flags depicted in this document are entirely non-fictional. Any resemblance to messages or protocols (living or dead), is entirely coincidental and completely unintentional. ;-)

---

ALL correspondence relating to this protocol, including suggestions/requests for flag-bit and data-type number allocations should be directed to: Jason Williams,
R.D.2, Manuel Road,
Silverdale,
North Auckland,
NEW ZEALAND.

email address: jwil1@cs.aukuni.ac.nz - valid only until March 1993. --
_________________ "I'd like to answer this question in two ways:

  /____ _ _/_ __       First in my normal voice, and then
 // / //_//_ /_/       in a silly, high-pitched whine." (Monty Python)