Home ProtocolsProtocols Virtual Screen protocolVirtual Screen protocol xFSL interfacexFSL interface

15.13 XAcc

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 (1) 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.


15.13.1 Purpose of XAcc

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:

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

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.

15.13.2 Classic XAcc

The 'classic' XAcc protocoll was finally defined on November 28, 1992. All known XAcc applications implement the protocol this way.


15.13.2.1 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 XAcc 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.

15.13.2.2 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.


15.13.2.2.1 Basic XAcc 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.


15.13.2.2.1.1 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 desk 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:
     

         msg[0]:  ACC_ID (0x400)
         msg[1]:  Sender's apID
         msg[2]:  Length of the message - 16, giving 0
         msg[3]:  Program version number and message groups
         msg[4]  and
         msg[5]:  Pointer to sender's name
         msg[6]:  Menu number (menu_id) as returned by menu_register
         msg[7]:  Reserved (see ACC_ACC)
    

    The low byte of msg[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 initialization. As the version number is stored in msg[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 msg[1] and msg[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 is no menu number and thus msg[6] can be used for any other purpose if neccessary. The same applies to msg[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
     

         msg[0]:  ACC_ACC (0x403)
         msg[3]:  Program version number and message groups
         msg[4]  and
         msg[5]:  Pointer to accessory's name
         msg[6]:  Accessory's menu number (menu_id)
         msg[7]:  Accessory's apID
    

  4. A desk 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:
    msg[0]: ACC_OPEN
    Just before the accessory returns control to another program, it sends the message
    msg[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 windowless 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).

15.13.2.2.1.2 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:

  msg[0]:  ACC_ID (0x400)
  msg[1]:  Sender's apID
  msg[2]:  Length of the message - 16, giving 0
  msg[3]:  Program version number and message groups
  msg[4]  and
  msg[5]:  Pointer to sender's name
  msg[6]:  Menu number (menu_id) as returned by menu_register
  msg[7]:  Reserved

The low byte of msg[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 processor-dependent format. The name itself is a string of characters terminated by two zero bytes. 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 msg[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

  msg[0]:  ACC_EXIT (0x404)
  msg[1]:  Sender's apID
  msg[2]:  Length of the message - 16, giving 0

to all applications that have ever registered themselves by sending ACC_ID or ACC_ACC.

15.13.2.2.2 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 just 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.)

15.13.2.2.3 Message group 1
ACC_ACK  = 0x500
ACC_TEXT = 0x501
ACC_KEY  = 0x502
  1. Transmitting text data:
     

         msg[0]:  ACC_TEXT (0x501)
         msg[4]  and
         msg[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
     
         msg[0]:  ACC_ACK (0x500)
         msg[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 acknowledgement.
     
    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:
     

         msg[0]:  ACC_KEY (0x502)
         msg[3]:  Scancode of the simulated key and corresponding
                  ASCII-code (as returned by evnt_keybd)
         msg[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 only the scancode, or both of them.
     
    This message is acknowledged after its interpretation with:
     
         msg[0]:  ACC_ACK (0x500)
         msg[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.

15.13.2.2.4 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:
     

         msg[0]:  ACC_META (0x503)
         msg[3]:  1 for the final part, 0 otherwise
         msg[4]  and
         msg[5]:  Pointer to data
         msg[6]  and
         msg[7]:  Length of data (32 bit longword)
    

    The metafile data is sent in the same format as it would be stored on disk. As metafiles can become quite large, and often accessories in particular do not have sufficient memory free 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 msg[3]=1. The sender may send no other data between the parts of a file. msg[6] and msg[7] contain the length of the part being sent, not the total length.
     
    The receiver acknowledges each part as described for group 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:
     
    msg[0]: ACC_IMG (0x504)
     
    otherwise identical to 1.
     

15.13.2.3 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 interprets 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.

15.13.3 Extended XAcc

This chapter describes developments of the XAcc protocol after "Classic XAcc" (11/28/92). Last changes have been made on June 15, 1995.

Since the last official documentation for the XAcc protocol, some extensions have appeared, which are now summarized here. Some of these extensions have arisen from the special forms of data interchange between the text processor That's Write and the address manager That's Address or its successor no|Address. However, these extensions are also accessible for any other applications, and the use of these application names in the following documentation is only for purposes of serving as examples (That's Address = TA and That's Write= TW). The extensions comprise:


15.13.3.1 MailMerge protocol

This protocol works with ACC_TEXT messages for historical reasons. The TW sends to TA first an ACC_TEXT message with a string that starts with '#I' and contains after the 'I' the SDF format string which tells the TA which parts of an address data-set are to be transferred.

Example: '#IA1,A2,A3,A4,T1' (the first 4 address fields and the first lelephone number).

After successful receipt of this message, an ACC_TEXT message with the string '0' is returned to TW, else an empty string ''.

Now TW can start to request individual address data with the ACC_TEXT message '#N'. at the receipt of such a message, TA sends for each address field of an address an ACC_TEXT message and at the end of the data set an empty string ''.

15.13.3.2 Remote-Mailmerge protocol

For this protocol there are two new XAcc message types, namely:

#define ACC_FORCESDF        0x520
#define ACC_GETSDF          0x521

TA sends to TW an ACC_FORCESDF when an address or an address-list is to be sent to TW. If it is dealing only with an address, msg[4]+[5] contains a pointer to the keyword of the address; for an address-list msg[4]+[5] contains a pointer to '#L'. The ACC_FORCESDF message must be conirmed with an ACC_ACK (msg[3]==1 -> OK and msg[3]==0 -> ERROR).

When TW receves a '#L', then TW runs a normal MailMerge protocol. If TW receives a keyword (max. 20 characters long), then TW requests this address from TA with ACC_GETSDF. The ACC_GETSDF message must have a pointer in msg[4]+[5] to a buffer that first contains the keyword with a terminating '\0' followed by the XDF format string (e.g.: 'JÖRG\0A1,A2,A3\0').

If TA can understand the ACC_GETSDF message, then it sends an ACC_ACK with msg[3]==1, else an ACC_ACK with msg[3]==0. Subsequently TW will receive the data of this single address as with the normal MailMerge protocol.

TW must have in its XDSC string an 'XRM', so that TA itself will start a Remote-Mailmerge protocol.

TA now has the following XDSC features (e.g. ACC):

const char ta2Ident[] = "That's Address ACC\0XDSC\0"
                        "1Adressverwaltung\0"
                        "2DB\0"
                        "XMM\0XSU\0XDI\0XRM\0NnoAddress ACC\0";
XMM MailMerge
 
XSU Keyword passing (optional with following '?')
 
XDI Inquiry protocol
 
XRM Remote-MailMerge
 

15.13.3.3 Inquiry protocol

In principle the whole Inquiry protocol proceeds in 2 steps. First the data of the available databases are obtained, and subsequently (completely independent of each other timewise) the individual fields of a selected database are inquired for.

So part 1 (as example of TA and TW):

            TA                  |                   TW
--------------------------------+------------------------------------
                            ACC_GETDSI
            <----------------------------------------

                            ACC_DSINFO
            ---------------------------------------->

                            ACC_ACK
            <----------------------------------------

    {
                            ACC_FILEINFO
            ---------------------------------------->

                            ACC_ACK
            <----------------------------------------

    }   /* 'n' times, where n was passed at ACC_DSINFO */

Explanation of the individual protocol elements:

ACC_GETDSI
 
This initiates the Inquiry protocol. This message contains a pointer to a variable of the type Xacc_Dsi_Request, containing coding of which fields of what type are desired.
 
        msg[0]            = ACC_GETDSI (0x510)
        msg[1]            = Application ID
        msg[4] and msg[5] = Pointer to the desired
                            field types (see XACC.H)
ACC_DSINFO
 
The inquired application replies to an ACC_GETDSI with this message, in which a pointer is passed to the inquiring application to a variable of the type Xacc_Dsinfo if the inquiry could be answered, or a NULL-pointer if the inquiry could not be answered.
 
        msg[0]            = ACC_DSINFO (0x511)
        msg[4] and msg[5] = Pointer to Xacc_Dsinfo structure
                            (see XACC.H), or NULL

The inquired application in turn answers all its replies with an ACC_ACK message:
 
        msg[0]            = ACC_ACK
        msg[3]            = 1     If all is OK
                          = 0     If an error has arisen (this terminates
                                  the protocol)
ACC_FILEINFO
 
When the ACC_DSINFO message from the inquiring application has been confirmed, then for each available file an ACC_FILEINFO message with a pointer to a variable of the type Xacc_File_Info, or a NULL- pointer for an error, is sent to the inquiring application.
 
As mentioned above, each of these messages must be confirmed with ACC_ACK from the inquiring application.
 
        msg[0]            = ACC_FILEINFO (0x512)
        msg[4] and msg[5] = Pointer to Xacc_File_Info structure (see
                            XACC.H), or NULL

When the first part of the Inquiry protocol has been completed successfully, then the inquiring application can present the user with a list of the available databases and the information they contain, and let him make a selection.

If the user does this, then the second part of the Inquiry protocol proceeds (again an example of TA and TW):

            TA                  |                   TW
--------------------------------+------------------------------------
                            ACC_GETFIELDS
            <----------------------------------------

    {
                            ACC_FIELDINFO
            ---------------------------------------->

                            ACC_ACK
            <----------------------------------------

    }   /* 'n' times, wher n was passed at ACC_FILEINFO */

Explanation of the individual protocol elements:

ACC_GETFIELDS
 
With this the inquiring application selects a database (the relevant database ID was received in the ACC_FILEINFO message in the structure Xacc_File_Info)) and now tells the inquired application that it should now transmit the individual field information.
 
        msg[0]            = ACC_GETFIELDS (0x513)
        msg[1]            = Application ID
        msg[3]            = ID of the desired database
ACC_FIELDINFO
 
When the ACC_GETFIELDS message has been confirmed by the inquiring application, then for each field an ACC_FIELDINFO message with a pointer to a variable of the type Xacc_Field_Info, or a NULL- pointer at an error, is sent to the inquiring application.
 
As mentioned above, each of these messages must be confirmed with ACC_ACK from the inquiring application.
 
        msg[0]            = ACC_FIELDINFO (0x514)
        msg[4] and msg[5] = Pointer to Xacc_Field_Info structure (see
                            XACC.H), or NULL

In That's/no|Address at present the field types FT_CHAR, FT_DATE and FT_TIME are implemented.

15.13.3.4 Request/Reply protocol

Two further messages were introduced to enable a general data exchange:

#define ACC_REQUEST     0x480
#define ACC_REPLY       0x481
ACC_REQUEST
 
With this message one requests a service from another application. The makeup of this message is as follows:
 
      msg[0]:     ACC_REQUEST (0x480)
      msg[1]:     Application ID of the sender
      msg[2]:     0
      msg[3]:     The high-byte is free for application-specific
                  information, and in the low-byte the type of the
                  data is coded that are sent with this message:
                  0x01  String, i.e. msg[4]+msg[5] is a
                        pointer to the string
                  0x02  EEnv-string, i.e. msg[4]+msg[5] is
                        a pointer to the Env-string (multiple
                        strings separated by '\0', with a
                        terminating double '\0'-bytes)
                  0x03  Binary data, i.e. msg[4]+msg[5] is
                        a pointer to the binary data. In this
                        case the receiver naturally has to be
                        aware of the data structure! (Local
                        type differentiation is possible by means
                        of the high-byte, for instance)
                  0x04  Code, i.e. msg[4] to msg[7] directly
                        contain the data (useful for transmission
                        of data amounts up to 8 bytes)
      msg[4,5]:   Pointer to the data (except type 0x04)
      msg[6,7]:   Length of data area, incl. possible '\0'-bytes
                  (except type 0x04)

There are two different options for replying to this message:
 
  • ACC_ACK with msg[3]=0, if the receiving application cannot process this message
     

  • ACC_REPLY, if the message could be processed and a reply has been sent back
     

ACC_REPLY
 
A successful ACC_REQUEST request is answered with this message. The makeup of this message is as follows:
 
            msg[0]:     ACC_REPLY (0x481)
            msg[1]:
                .
                .       see ACC_REQUEST!
                .
            msg[7]:

Applications that support the protocol elements described above have to contain the Extended feature 'RQ' in their XDSC description.

15.13.4 Example: no|Link's XAcc protocol

The no|Link accessory was conceived for the control of infra-red devices and contains an XAcc communication layer for the control by special applications. At present the Media-Link interface of Catch Computer is supported. A further adaptation for the no|Remote interface of no|Software is in preparation (at the time this was written).

The no|Link accessory administers all information required for the control of the infra-red or other hardware. Each hardware-dependent code (e.g. an infra-red signal) is assigned a command, and for each device (e.g. a video recorder) there exists a list of such commands.

For example, if an application for the remote control of a video recorder wants to send an infra-red signal for the 'Play' key, then it sends no|Link an XAcc message, in which the command 'send', the device <VIDEORECORDER> and the command <PLAY> are coded.

So that an application can communicate completely with no|Link, it must support the Request/Reply protocol, which is made known by an Extended feature 'RQ' in the XDSC description. Only in this way is it possible to maintain the list of the no|Link registered devices.

If the application also wants to receive codes from the accessory (only possible with suitable hardware), then the XDSC description must contain additionally an Extended feature 'RR' (Remote Receive). All applications that want to work with no|Link have to support the XAcc Level/Message group 1.

As application type the no|Link accessory receives in XDSC '\2RC' (Remote Control).

The complete XAcc identification of no|Link at present is as follows (in C-syntax, using the original German):

    char xaccNoLinkIdent[] =    "Infrarot Manager\0"
                                "XDSC\0"
                                "1Fernsteuerschnittstelle\0"
                                "2RC\0"
                                "XRQ\0"
                                "NnoRci\0";

A possible XAcc identification for a no|Link application could look like this:

    char xaccIdentstring[] =    "VideoControl\0"
                                "XDSC\0"
                                "1Video Fernbedienung\0"
                                "XRQ\0"
                                "Nno|Video ACC\0";

The communication between the application and the no|Link accessory is mainly via ACC_TEXT messages.

The accessory at present understands the following commands, which have to be sent as a string by means of an ACC_TEXT message (where <X> := <device>:<command>):

"S <X>" Sending of a command, e.g: 'S VIDEO:PLAY'.
 
"P <X>" Preparation of a command, e.g: 'P VIDEO:PLAY'. With this the infra red hardware is informed of the code for this command, but it is not yet sent
 
"S" Sending of the last prepared command
 
"T <X>" Test of the existence of a command
 
Particularly at a new installation of a remote control application, all devices and commands that this application uses should be communicated to the accessory!
 
If no|Link does not know the supplied command, the user is invited to activate the required 'learning procedure', or to assign the new command to one already present.
 
Each remote control application should contain a function that allows the user to 'test' all supported commands - preferably via an 'Install' button.
 

The test function is the only one that may lead to interaction with the user in some circumstances. All others issue no output.

As reply the application receives an ACC_ACK message, in which the success or otherwise of handling the command is noted in msg[3]:

1 Operation was successful
 
0 Device/command is not present, or error in the handling
 

Device and command names may be up to 32 characters long and may not contain a ':'. No regard is paid to case, i.e. capitals and lower case characters are not differentiated.

An application can request a list of registered devices from the accessory. For this the application has to understand the new XAcc Request/Reply protocol (see above, or XACC.H).

To request the list, the application sends a ACC_REQUEST to the accessory, where the message must be constructed as follows:

    msg[0] = ACC_REQUEST (0x480)
    msg[1] = apid
    msg[2] = 0
    msg[3] = 0x04       /* Data-type: Code */
    msg[4] = 'D'        /* 'D' represents 'devices' */
    msg[5] = 0
    msg[6] = 0
    msg[7] = 0

As reply the application receives an ACC_ACK message with msg[3] == 0 if an error has occured, or on success an ACC_REPLY message:

    msg[0] = ACC_REPLY (0x481)
    msg[1] = apID of no|Link
    msg[2] = 0
    msg[3] = 0x02       /* Data-type: Environment string */
    msg[4]+msg[5] = Pointer to globally accessible memory containing the
                    list of the devices in the following format:
                           "DEVICEINFOS:\0device1\0device2\0"
    msg[6]+msg[7] = LONG value, specifying the size of the buffer
                    (inclusive of the terminating two NULL-bytes)

The receipt of an ACC_REPLY message must be confirmed subsequently with an ACC_ACK message, so that the no|Link accessory can release its resources again!

15.13.5 XACC.H

/*==================================================================*/
/*                                                                  */
/*                XAcc definitions (Pure-C syntax)                  */
/*                                                                  */
/*==================================================================*/

#ifndef __XACC__
# define __XACC__

/*--------------------------------------------------------------------
    XAcc message types
--------------------------------------------------------------------*/
/* Level 0 */
# define ACC_ID             0x400
# define ACC_OPEN           0x401
# define ACC_CLOSE          0x402
# define ACC_ACC            0x403
# define ACC_EXIT           0x404

/* Level/Message group 1 */
##6# 'Message group' eingefuegt
# define ACC_ACK            0x500
# define ACC_TEXT           0x501
# define ACC_KEY            0x502

/* Level/Message group 2 */
# define ACC_META           0x503
# define ACC_IMG            0x504

/*
 * Extended XACC message types:
 * These messages are relatively 'independent' of the XACC-level
 * of the applications, i.e. they should be used only if the
 * communication partner in its XDSC description signals that it
 * participates in the relevant Extended feature!
 */

/* Reuest/Reply protocol: (Extended feature 'RQ')      */
/*        ACC_ACK messages are a part of the protocol  */
/*        and therefore must be understood!            */
# define ACC_REQUEST        0x480
# define ACC_REPLY          0x481

/* Inquiry protocol: (Extended feature 'DI')           */
/*        ACC_ACK messages are a part of the protocol  */
/*        and therefore must be understood!            */
#define ACC_GETDSI          0x510
#define ACC_DSINFO          0x511
#define ACC_FILEINFO        0x512
#define ACC_GETFIELDS       0x513
#define ACC_FIELDINFO       0x514

/* Remote MailMerge protocol: (Extended feature 'RM')  */
/*        ACC_ACK messages are a part of the protocol  */
/*        and therefore must be understood!            */
#define ACC_FORCESDF        0x520
#define ACC_GETSDF          0x521


/*----------------------------------------------------------------------
    Definitions for the Request/Reply protocol
----------------------------------------------------------------------*/
/* Data-types of the Request/Reply: */
#define RQREP_TYPE_STRING   1
#define RQREP_TYPE_ENVSTR   2
#define RQREP_TYPE_BIN      3
#define RQREP_TYPE_CODE     4


/*----------------------------------------------------------------------
    Definitions for the Inquiry protocol
----------------------------------------------------------------------*/
#define DSI_VERSION         0x0100


/* Field data-types:
 *    Values lower than 128 are 'human-readable types' and
 *    values greater/equal 128 are 'machine-readable types'
 */
#define FT_CHAR        0x00  /* String                                */
#define FT_DATE        0x02  /* String in _IDT format                 */
                             /* Deflt: DD.MM.YY if no _IDT available; */
                             /* for more about _IDT see MINT          */
#define FT_TIME        0x03  /* String: HH:MM:SS                      */

#define FT_BYTE        0x80  /* 2-byte HEX-string                     */
#define FT_UBYTE       0x81  /* 2-byte HEX-string, unsigned           */
#define FT_SHORT       0x82  /* 4-byte HEX-string                     */
#define FT_USHORT      0x83  /* 4-byte HEX-string, unsigned           */
#define FT_LONG        0x84  /* 8-byte HEX-string                     */
#define FT_ULONG       0x85  /* 8-byte HEX-string, unsigned           */
#define FT_FLOAT       0x86  /* 8-byte HEX-string                     */
#define FT_DOUBLE      0x87  /* 20-byte HEX-string                    */
#define FT_ENUM        0x88  /* 4-byte HEX-string                     */
#define FT_BOOL        0x89  /* String: 'T' or 'F'                    */
#define FT_BITFLD      0x8A  /* An 8-bit aligned HEX-string           */
#define FT_TIME_T      0x90  /* 8-byte HEX-string (time_t, see UNIX)  */


typedef struct {
    int     version;
    char    field_types[32]; /* Max. count of 256 field-types are     */
                             /* available (see definements above);    */
                             /* each bit in this field represents a   */
                             /* valid field-type, where type 0 is     */
                             /* the lowest bit of the first character */
                             /* and type 255 the highest bit of the   */
                             /* last character */
} Xacc_Dsi_Request;

typedef struct {
    int     db_anz;          /* Count of available databases          */
##6# Hier und spaeter 'data base' -> 'database'

} Xacc_Dsinfo;

typedef struct {
    long    db_id;           /* ID of the database                    */
    char    fname[32];       /* Filename of the database; if you      */
                             /* are using a GEMDOS or DOS filesystem  */
                             /* it must have a <8.3> format.          */
    char    title[32];       /* A max. 32 byte long description of    */
                             /* the database                          */
    time_t  crea_time;       /* The creation date/time of the         */
                             /* database file                         */
    time_t  mod_time;        /* The last modification date/time of    */
                             /* the database structure                */
    int     n_fields;        /* The number of fields that are         */
                             /* available corresponding to the        */
                             /* requested field types given by the    */
                             /* ACC_GETDSI message                    */
} Xacc_File_Info;

typedef struct {
    int     fld_size;        /* The count of bits in the field        */
    int     n_fields;        /* The count of field elements           */
    int     elem_size;       /* The length of one field element       */
    char    field_buff[0];   /* From here the list of the n_fields    */
                             /* elements follows in this format:      */
                             /* 2 byte bitno and elem_size byte-      */
                             /* description, e.g. (elem_size=10):     */
                             /*    "\0\1private\0\0\0"                */
                             /*    "\0\2sex\0\0\0\0\0\0\0"            */
                             /*    "\0\4dealer\0\0\0\0"               */
                             /* The value '06' identifies the 2nd     */
                             /* and the 3rd element;                  */
                             /* NOTE that you can't use sizeof        */
                             /* because of this declaration           */
} Bitfld_Info;

typedef struct {
    int     n_enums;         /* The count of enum-elements            */
    int     elem_size;       /* The length of one enum element        */
    char    enum_buff[0];    /* From here the list of the n_enums     */
                             /* elements follows in this format:      */
                             /* 2 byte id and elem_size byte-         */
                             /* description, e.g. (elem_size=10):     */
                             /*    "\0Aprivate\0\0\0"                 */
                             /*    "\0Bsex\0\0\0\0\0\0\0"             */
                             /*    "\0Edealer\0\0\0\0"                */
                             /* The value '0042' identifies the 2nd   */
                             /* element;                              */
                             /* NOTE that you can't use sizeof        */
                             /* because of this declaration           */
} Enum_Info;

typedef union {
    ulong        n_elems;      /* For types like char, uchar this is  */
                               /* the length of the field             */
    Enum_Info    *enum_info;   /* enum is a special type, which needs */
                               /* more description than the length!   */
    Bitfld_Info  *bitfld_info; /* A bitfield like used in TA2 for the */
                               /* info-flags                          */
} Type_Desc;

typedef struct {
    char         id[8];      /* The export-identifier of the corres-  */
                             /* ponding field, i.e. 'A1' for the      */
                             /* first address field of Clever or TA2  */
    char         name[16];   /* A short description                   */
    char         desc[32];   /* A long description                    */
    int          type;       /* The data-type; must be one of the     */
                             /* constants defined at the top of this  */
                             /* file                                  */
    Type_Desc    t_desc;     /* This union contains either the length */
                             /* of the field or a pointer to an info- */
                             /* struct if the type is a special one   */
                             /* like enum or other user-defined types */
} Xacc_Field_Info;


#endif    /* #ifndef __XACC__ */

Home ProtocolsProtocols Virtual Screen protocolVirtual Screen protocol xFSL interfacexFSL interface