From: HAC041@DJUKFA11.BITNET (Konrad Hinsen)
Newsgroups: comp.sys.atari.st.tech
Subject: XAcc protocol definition
Date: 21 Dec 92 09:45:33 GMT
Organization: Forschungszentrum Juelich

XAcc: a communication protocol for GEM applications
===================================================

(last revision: November 28, 1992)


The XAcc protocol was originally designed for non-multitasking versions of
GEM to allow data exchange between the main application and any number of
accessories. Since the AES did not provide a function to find the
application ids (apids) of other applications without knowing their names,
XAcc had to rely on the undocumented feature that the main application
always has the apid 0. Therefore XAcc in its present form does not work in
a multitasking environment. However, AES 4.0 provides the new function
appl_search(), which allows any application to find the apids of all other
applications running concurrently. This makes it possible to design a
modified XAcc that does not use any 'dirty tricks'. This document contains
a proposal for such a modified XAcc; the changes with respect to the
previous definition are small and modifying an existing XAcc-based
application should be a matter of minutes. Since single-tasking TOS will
still be with us for a while, applications are encouraged to implement both
'traditional' and 'modern' XAcc, depending on the version number of the AES.


Purpose
-------

The GEM AES functions appl_write() and appl_read() can be used to exchange
data between GEM applications running concurrently. In practice however,
some problems need to be solved to make good use of these two functions:

- There are no standard messages for exchanging data. Their definition is
  the main goal of XAcc.

- appl_write() needs the receiver's application identifier (apid). The
  only way to get this (before AES 4.0) is to call appl_find(), which
  needs the receiver's name. Thus communication is only possible if
  the sender knows the receiver's name.
  This problem is solved in AES 4.0 by the introduction of the function
  appl_search().

- The main application does not know when an accessory is activated or
  deactivated. This would often be useful, for example if the main
  application changes system variables that could affect the accessory's
  behaviour. If the main application were informed before the accessory
  gains control, it could reset those to their old values and change
  them back after the accessory is finished.
  Another advantage would be that after an accessory has been called,
  the main application could check if something has been written to the
  clipboard or if other changes to the environment have been made.

  With multitasking GEM, the situation has changed in several important
  ways. The possibility of using several 'main' applications in parallel
  makes it even more undesirable to let them directly manipulate system
  variables and the like; nevertheless there will probably always remain
  some purposes that require such methods. On the other hand, at least
  for applications using windows (the preferred method to get the most
  out of a multitasking system) it is now possible to detect changes
  of the active application by interpreting the new AES messages
  WM_ONTOP and WM_UNTOPPED. Therefore it is not considered necessary
  for XAcc to provide additional means to achieve this.

The communications protocol described in this document solves all these
problems. It was designed for two distinct purposes:

- Exchanging data of standard types between programs that have no
  information about each other.

- Exchanging data between specific applications known to each other.
  The standard protocol ensures that program combinations from
  different vendors do not interfere with each other.

A potential problem caused by this protocol should be mentioned at this
point: for single-tasking GEM versions, it relies on the currently
undocumented fact that the main application's apid is always zero. Without
this assumption there is no way to exchange data without using appl_find().
Although this fact is not documented, it holds for all single-tasking
versions of GEM in existence until now, both for MS-DOS and the Atari ST
(this information was confirmed by Digital Research Germany). Of course
the main application's apid may be different in future versions, although
there is no reason to change the current behaviour for single-tasking
systems. For AES 4.0 (and later) the above assumption is not needed anyway,
so no compatibility problems are to be expected in the future.

A further requirement is that all programs not using this protocol must
ignore its messages. This should not be a serious problem, as all GEM
applications should ignore messages they do not understand. At the time
of writing no programs are known to violate this rule.


XAcc message groups
-------------------

[Note: The "levels" used in previous XAcc versions have been replaced
 by this new concept. Compatibility issues are discussed in a special
 section at the end of this document.]

Both main applications and accessories can have widely different needs for
communication with other programs. Therefore XAcc defines several groups
of related messages that deal with a certain range of data types.
The message groups always indicate the messages understood by a
program, not the messages it might send to other ones. If a program
supports a certain message group, it must correctly respond to all
corresponding messages, whether it can actually use the supplied data
or not.

In addition to message groups, there are the so-called "basic messages",
which must be supported by any XAcc-aware program, and program-specific
so-called "special messages".

The basic messages deal solely with identification, but no real data
exchange. They are already sufficient for programs that either do not
exchange data with others at all or use only special messages to
communicate with a number of other specific programs.

Message group 1 specifies the exchange of ASCII-format character data.

Message group 2 deals with the exchange of drawings and pictures using
the GEM metafile format and the GEM bit-image file format.

Future extensions might include sound or spreadsheet data. In addition,
a message group could be defined to handle command interchange between
applications, e.g. for a "drag&drop" protocol.


XAcc messages
-------------

There are two kinds of XAcc messages: standard messages, which must be
understood by every participating program, and special messages intended
for communications between specific program combinations. The standard
messages have numbers ranging from 0x400 to 0x7ff, special messages start
from 0x800. The latter ones may only be sent after the receiver has been
identified and is known to understand them. The following description is
only concerned with standard messages.
In addition to XAcc standard messages, the AES messages normally sent
by the screen manager may be used. The most useful ones are AC_OPEN
and MN_SELECTED; the latter one requires a knowledge of the receiver
and therefore belongs to the special messages.


Basic messages
--------------

ACC_ID = 0x400
ACC_OPEN = 0x401
ACC_CLOSE = 0x402
ACC_ACC = 0x403
ACC_EXIT = 0x404

These messages provide XAcc initialization and organization. This is
the only part of XAcc which has to be implemented in a different way for
single- and multi-tasking GEM versions. Note that the procedure
described for 'multitasking' actually only depends on the existence of
appl_search() and hence on an AES version number >= 4.0. If some
future single-tasking AES supports appl_search(), the "multitasking"
initialization should be used. Multitasking AES versions with a version
number < 4.0 should never exist; to be on the safe side, applications
should not attempt to use XAcc if such a situation is detected.

I) Single-tasking GEM versions

The communication between the main application and the accessories is
initiated in the following way:

1) When a main application is started (or terminated), all accessories
   receive an AC_CLOSE message from the AES screen manager. In response
   they must send an identification to the main application according
   to the following format:
     msgbuf[0]:  ACC_ID
     msgbuf[1]:  sender's apid
     msgbuf[2]:  length of the message - 16, giving 0
     msgbuf[3]:  program version number and message groups
     msgbuf[4] and msgbuf[5]:   pointer to sender's name
     msgbuf[6]:  menu number (menu_id) as returned by menu_register()
     msgbuf[7]:  reserved (see ACC_ACC)
   The low byte of msgbuf[3] contains a bitmap indicating which message
   groups are understood by the sender. Bit zero is set for message
   group 1, bit one for message group 2, and so on. This is independent
   of the message types which the sender might itself send to others. The
   sender of a message must ensure that it is understood by the receiver.
   The high byte is used to indicate a program version number using an
   arbitrary encoding scheme.
   The pointer to the sender's name is stored in a machine-dependent
   format. The name itself is a character string following C conventions,
   i.e. a string of characters terminated by a zero byte. To avoid name
   conflicts, long names are preferred to short abbreviations. The name
   must be available at the given address at any time, it may not be
   removed after initialisation. As the version number is stored in
   msgbuf[3], it should not occur again in the name.
   [Note: see the section "Extended names" for more details on names.]
   Accessories using more than one menu entry must issue one ACC_ID
   message for each entry used. Accessories without a menu entry must
   use a number of -1.

Since msgbuf[1] and msgbuf[2] have the same meaning for all message
types, they are no longer mentioned from now on.

2) In response to an ACC_ID message the main application sends an
   identification back to the accessory. The format is identical, except
   that there ist no menu number and thus msgbuf[6] can be used for any
   other purpose if neccessary. The same applies to msgbuf[7].

3) In addition to the ACC_ID message, the main application informs all
   previously registered accessories about the new one by sending them
   the message
     msgbuf[0]:  ACC_ACC
     msgbuf[3]:  program version number and message groups
     msgbuf[4] and msgbuf[5]:   pointer to accessory's name
     msgbuf[6]:  accessory's menu number (menu_id)
     msgbuf[7]:  accessory's apid

4) An accessory receiving the ACC_ACC message from the main application
   sends an ACC_ID message to the thereby registered accessory, identical
   to the one previously sent to the main application.

5) When an accessory is activated by receiving an AC_OPEN message, it
   sends the following message to the main application:
     msgbuf[0]:  ACC_OPEN
   Just before the accessory returns control to another program, it
   sends the message
     msgbuf[0]:  ACC_CLOSE
   When receiving ACC_OPEN, the main application restores all system
   variables it has changed to their original values (if possible and
   neccessary). After receiving ACC_CLOSE, it may set them again to any
   desired value.
   Accessories should change system variables only after sending
   ACC_OPEN and restore them before ACC_CLOSE.

   There have been some problems with the implementation of ACC_OPEN and
   ACC_CLOSE that should be mentioned. The system was designed with
   window-less accessories in mind, i.e. accessories that only display
   a dialog box. For these accessories, the above procedure is
   well-defined. Accessories that use windows however have no way to
   find out if they have been activated or deactivated, because they
   do not receive a message to indicate this (starting from AES 4.0,
   this problem is solved). Therefore such accessories must be careful
   with ACC_OPEN and ACC_CLOSE. The most important thing is to guarantee
   that ACC_OPEN and ACC_CLOSE always occur in pairs, and that in between
   no other program gains control. How exactly this is implemented
   depends on the specific application. Sometimes the best implementation
   is not to use ACC_OPEN and ACC_CLOSE at all.

After initialization is completed, all participating programs know the
identity of all other ones, either by receiving an ACC_ID message or by
receiving an ACC_ACC message. The main application is always informed
about accessory activities. If in addition it proves neccessary to
inform one accessory about the activation of another one, this can be
accomplished by sending special messages (starting from 0x800).

II) Multitasking GEM versions

The initialization procedure is much simpler in this case. Any application,
i.e. both 'standard' applications and accessories, uses appl_search() to
detect all currently running AES processes when it is started. To each
application or accessory (i.e. everything but system processes) it sends
an ACC_ID message:
  msgbuf[0]:  ACC_ID
  msgbuf[1]:  sender's apid
  msgbuf[2]:  length of the message - 16, giving 0
  msgbuf[3]:  program version number and message groups
  msgbuf[4] and msgbuf[5]:   pointer to sender's name
  msgbuf[6]:  menu number (menu_id) as returned by menu_register()
  msgbuf[7]:  reserved
The low byte of msgbuf[3] contains a bitmap indicating which message
groups are understood by the sender. Bit zero is set for message
group 1, bit one for message group 2, and so on. This is independent
of the message types which the sender might itself send to others. The
sender of message must ensure that it is understood by the receiver. The
high byte is used to indicate a program version number using an
arbitrary encoding scheme.
The pointer to the sender's name is stored in a processor-dependent
format. The name itself is a string of characters terminated by two zero
byte. To avoid name conflicts, long names are preferred to short
abbreviations. The name must be available at the given address at any time,
it may not be removed after initialization. It must also reside in
globally accessible memory. As the version number is stored in msgbuf[3],
it should not occur again in the name.
[Note: see the section "Extended names" for more details on names.]
Applications using more than one menu entry must issue one ACC_ID
message for each entry used. Accessories without a menu entry must
use a number of -1.

When receiving an ACC_ID message, an application replies by sending a
message of the same format to the original sender, the only difference
being that ACC_ACC is used instead of ACC_ID. Applications with
several menu entries must again send one message for each entry.

The messages ACC_OPEN and ACC_CLOSE are not used in multitasking
systems.

Note: The only difference between ACC_ID and ACC_ACC for multitasking
systems is that an application receiving ACC_ID sends ACC_ACC as a
reply, whereas no reply is sent on receiving ACC_ACC. This prevents
applications from sending ACC_ID to each other indefinitely.
Obviously the name ACC_ACC has lost its original meaning and
probably should be changed. But since the symbolic names do not influence
the actual behaviour of any program, this is not really important at all.

Since in a multitasking environment every participating application
can terminate, some means must be provided to tell other applications
about this. Therefore the message ACC_EXIT has been added to the list
of level 0 messages. Before terminating, any application sends
  msgbuf[0]:  ACC_ID
  msgbuf[1]:  sender's apid
  msgbuf[2]:  length of the message - 16, giving 0
to all applications that have ever registered themselves by sending
ACC_ID or ACC_ACC.


Extended names
--------------

Experience with XAcc has shown that it would often be useful to have more
information about an application than specified with ACC_ID messages.
For example it is sometimes useful to check for a special feature that
is not unique to a single program, but to several similar ones. This
was the motivation for the introduction of "extended names".

An "extended name" is a character string of the format
'name'\0XDSC\0'string'\0'string'\0...'string'\0\0
i.e. a "standard" name followed by the string "XDSC" (for "eXtended
DeSCription"), followed by a list of strings containing additional
information. The end of the list is marked by an additional zero byte.

Each information string indicates by its first byte what kind of
information it contains. Currently the following types are defined:

'1' - application type (human-readable)
      The text following this byte (an ASCII-1, 0x31) should roughly
      specify the type of application, e.g. "word processor" or
      "spreadsheet". The purpose is for applications to present
      this information to the user to let him/her decide where data
      should go. This is not the place for advertising hype; a word
      processor should call itself "word processor" and not "document
      editing and design system".
      It should be clear that the text should be understandable for end
      users, especially it should be in the language used for the user
      interface.

'2' - application type (machine-readable)
      Currently defined are:
      "WP" - word processor
      "DP" - DTP
      "ED" - text editor
      "DB" - database
      "SS" - spreadsheet
      "RG" - raster graphics application
      "VG" - vector graphics application
      "GG" - general graphics application
      "MU" - music application
      "CD" - CAD
      "DC" - data communication
      "DT" - desktop
      "PE" - programming environment

'X' - extended features
      This string is used to indicate special communication capabilities
      of an application. It can be used to give more specific information
      than the message groups understood. Since this information is meant
      to be used by other applications rather than end users, short
      abbreviations are sufficient.

'N' - generic name
      Often several related, but not completely identical, applications
      have different names. Marketing requirements may even dictate
      changes of the "official" brand names, making them unsuitable
      for a "technical" identification. In such cases a "generic" name
      for all these programs can be specified, which is mainly used
      by other programs wishing to use special messages.

The "normal" name should be the "official" name of the program, just as it
is used on the package, in the manual, and in similar places. It should
be presentable to the user to let him/her decide where to send data.

Example: The address database "That's Address" identifies itself with the
extended name (in C syntax)
"That's Address\0XDSC\01database\02DB\0XMM\0XSU\0",
indicating that it is a database with features "MM" and "SU". The first
one indicates a special mail merge mode, the second one the possibility
of retrieving data by sending the key via ACC_TEXT.
(Further information on this program can be obtained from its manual.)


Message group 1
---------------

ACC_ACK = 0x500
ACC_TEXT = 0x501
ACC_KEY = 0x502


1) Transmitting text data:
     msgbuf[0]:  ACC_TEXT
     msgbuf[4] and msgbuf[5]:   pointer to text
   The text may contain all printable ASCII characters (code >= 32) and the
   following control codes:
     0x09  TAB (may be interpreted as a space by the receiver)
     0x0A  LF  (usually ignored by receiver)
     0x0D  CR  (used to mark an end-of-line (or end-of paragraph)
   Other control codes may only be used if the receiver is known to
   understand them. The text is terminated by a zero byte.
   After the text has been interpreted completely, the receiver
   acknowledges by sending
     msgbuf[0]:  ACC_ACK
     msgbuf[3]:  0 if the text was simply ignored, 1 if it was used in
                 some sensible way
   The sender of a text message may not change the text nor send any
   other text messages to the same receiver until is has received the
   acknowledge.
   The sender must make sure that the memory used to store the text
   is globally accessible.
   The receiver should normally interpret the text as if it were typed
   from the keyboard. A word processor would for example insert it into
   the currently edited document (this implies using CR as an end-of-
   paragraph mark), a command line interpreter would interpret the text
   as a command (which implies using CR as an end-of-line mark).

2) Simulation of a key press:
     msgbuf[0]:  ACC_KEY
     msgbuf[3]:  scan code of the simulated key and corresponding
                 ASCII code (as returned by evnt_keybd())
     msgbuf[4]:  state of the SHIFT keys (as returned by Kbshift())
   This message should be regarded identical to a keyboard event. It can
   be used to send control commands to a receiver which might have
   been issued from the keyboard. Of course this requires a knowledge
   of the receiver as no standard keyboard command sets exist. It should
   be noted that the receiver is free to use only the ASCII code or the
   scan code, or both of them.
   This message is acknowledged after its interpretation with
     msgbuf[0]:  ACC_ACK
     msgbuf[3]:  0 if ACC_KEY was ignored or a given command was not
                 understood, 1 if some action was taken.

To prevent a deadlock if a program does not properly acknowledge a
message, the sender should have some way to recover. An accessory
could for example stop waiting for an acknowledgement after the next
AC_OPEN, a main application might time out after a sufficiently long
period.


Message group 2
---------------

ACC_META = 0x503
ACC_IMG = 0x504

These message are used to exchange drawings and pictures. Only the file
formats defined in the GEM documentation are used; they are sufficient
to meet most requirements, and any GEM application should be able to
handle them anyway.

1) Sending a metafile:
     msgbuf[0]:  ACC_META
     msgbuf[3]:  1 for the final part, 0 otherwise
     msgbuf[4] and msgbuf[5]:   pointer to data
     msgbuf[6] and msgbuf[7]:   length of data (32 bit longword)
   The metafile data is sent in the same format as they would be stored
   on disk. As metafiles can become quite large and especially
   accessories often do not have sufficient memory to store them, a
   file can be sent in several pieces. The receiver has to take care
   of assembling all parts to restore the original data, if neccessary
   by writing the parts to a file. The last part of a file is marked
   by msgbuf[3]=1. The sender may send no other data between the parts
   of a file. msgbuf[6] and msgbuf[7] contain the length of the part
   being sent, not the total length.
   The receiver acknowledges each part as described for level 1.
   As for text messages, the sender must make sure that the data to
   be transferred is stored in globally accessible memory.

2) Sending a bit image file:
     msgbuf[0]: ACC_IMG
   otherwise identical to 1)



Compatibility considerations
----------------------------

There are two major changes with respect to the original XAcc definition:

1) "Levels" have been replaced by "message groups".
   The motivation for this change was that the classification according
   to exchangeable data types was not really a hierarchical one; there
   is no reason why a programm accepting graphics should also be able to
   understand text. The new scheme makes no such arbitrary assumptions.

   There is only one situation in which a possible incompatibility could
   occur: an application following the "old" convention encounters a
   "new" application and one of them indicates 2 in the level/message
   group byte. This would be interpretes as "graphics only" by one and
   as "graphics and text" by the other. Since the number of level-2
   applications was always extremely small (in fact, the author knows
   only of a single one), this should be no problem in practice.

2) Extended names have been introduced.
   This could lead to a problem in the extremely unlikely case of an
   "old" application using a name string which is accidentally followed
   by "XDSC".

In any case it is expected that most applications will be converted to
the new rules soon, if only to support MultiTOS.