view.txt, V1.04, 14.11.1993

        T   H   E    V   I   E   W    P   R   O   T   O   C   O   L
     =================================================================

               0. Introduction
               I. The Purpose(s) Of The View Protocol
              II. Using The View Protocol
             III. Implementing The View Protocol
                  1. Who is the viewer?
                  2. What kinds of files can be displayed?
                  3. How can I tell the viewer what is to be shown?
                  4. What does the viewer do?
                  5. The VIEW_XXX Messages
                     a. View A File
                     b. Further Communication
                  6. The Messages


0. Introduction
===============

	The View Protocol was developed by Peter Seitz and Dieter Fiebelkorn 
to make it possible for a GEM application to display files (using an 
external viewer) without being forced to implement a viewer for the 
various file formats itself, and to provide a uniform method of 
communication between the application and the viewer (so that the 
application can use any viewer, rather than just one particular viewer).

	There are already several applications that can be used as viewers.
They are GEM-View (Dieter Fiebelkorn), 1st-View/1st-Guide (Guido 
Vollbending), and ShowImage (Peter Seitz).  When installed as accessories, 
these applications can be instructed (by other applications) to view files.

	This experimental version of the View Protocol is implemented in GEM-
View and ShowImage.  IT IS STRONGLY RECCOMMENDED THAT ALL PROGRAMMERS USE 
AND EXPERIMENT WITH THIS PROTOCOL!  We hope that eventually it will become 
a standard.  Suggestions and comments are welcome; please send them to 
Peter Seitz at one of the following addresses:

	Peter Seitz, Robert-Koch-Str.6, 63225 Langen, GERMANY
	E-Mail (Internet): seitz@rbg.informatik.th-darmstadt.de
	                or seitz@isa.informatik.th-darmstadt.de

	This protocol should be quite easy to implement for both the writers 
of viewers and the writes of applications.  It should provide 
substantial benefits for the user as well, since he will be able to use 
his favourite viewer with all applications.

--Peter Seitz


	In the following dicussion, "viewer" refers to the accessory or 
application that is used to display the file(s) and "application" 
always refers to the program that requests the services of the 
viewer.


I. The Purpose(s) Of The View Protocol
======================================

	The View Protocol was developed to allow an application to:

	* Determine if a viewer is already in memory (without knowing the 
	  name of the viewer).  If no viewer is available, the application can 
	  start the viewer itself (if the name is available).

	* Determine what type of files can be displayed by the available 
	  viewer.

	* View files in various formats (using the viewer) and receive 
	  feedback from the viewer (using a uniform message protocol).


II. Using The View Protocol
===========================

	It is very easy for the user to use the facilities of the View 
Protocol.  If there is a view-accessory (GEM-View, ShowImage) that 
supports the View Protocol, and the application supports the View 
Protocol, nothing needs to be done.  If there is no resident view-
accessory (or the desired viewer does not support the View Protocol) 
then the user should install an environment variable called "View" with 
the full pathname of the desired viewer as its value. The way that this 
can be done is described in section III.1 (below).


III. Implementing The View Protocol
===================================

	The View Protocol is based on parts of the XAcc-protocol, so a 
programmer planning to implement the View Protocol should obtain a copy 
of the XAcc-Protocol (xacc_mt.txt).


1. Who is the viewer?
=====================

	First, an application should determine if there is a viewer that the 
user prefers.  It does this by (in this order) looking for an environment 
variable called "View", looking for a cookie in the cookie jar called 
"View", and then looking for an environment variable called "SHSHOW" 
(which is used by the MultiTOS desktop, too).  In all cases, the case is 
significant.

	The value of each one of these variables is the full pathname of the 
viewer.

	The programmer can determine if one of the viewers is in memory 
(as an accessory, usually, but it is possible for the viewer to be an 
application with a multitasking operating system) using the appl_find() 
system call.

	To use the appl_find() system call, the path and the extension have to 
be removed from the name of the viewer and must be padded with spaces to 
a length of eight characters.  If this is not done, the appl_find() 
call will fail.  It should be noted that appl_find() is case sensitive, so 
normally the value MUST be all upper case.  It would not be wise to 
convert the name to upper case, however, as case sensitive file systems 
may be used under MiNT.

	If the viewer has not yet sent its XAcc-Identification (the ACC_ID
message), the application does this now.  This may be the case if the main-
application does not support the XAcc-Protocol.

	If no viewer is found, the application should check the extended 
name (introduced in version two of the XAcc-Protocol) of all applications 
and accessories that have sent XAcc-Identification messages for the 
string "2View" (this is the application type "viewer") or the string 
"NView" (this is the generic type "viewer").  If either of these strings 
is found, then the application/accessory in question supports the View 
Protocol and may be used as a viewer.  As in the case of the environment 
variables, the case of "2View" and "NView" is significant.

	If there is no viewer in memory, but the one of the environment 
variables (or the cookie) was found, the application can try to load the 
viewer itself (using the pathname given in the variable).  Please note 
that wildcards may be used in the extension of the viewer (a
view-accessory could be named "XXX.ACC" or "XXX.ACX").  If the "View" 
environment variable was found, the viewer may be started as an 
accessory as well using Chameleon or MultiTOS.  As a consequence of 
this, the viewer specified in the "View" environment variable must be 
able to run as both an application or an accessory.  If the viewer 
cannot run as an accessory, it should be specified using the "SHSHOW" 
environment variable.

	Normally, the user should use one of the enironment variables 
("View" or "SHSHOW").  These should be placed in the desktop environment, 
as all applications started by the desktop will inherit its environment. 
This can be done with special programs (ENVIRON.PRG, JCNBOOT.PRG) or, if 
MiNT is installed, by placing the following line in MINT.CNF:

	setenv View C:\GEM_VIEW\GEMVIEW.APP

	and/or

	setenv SHSHOW C:\GEM_VIEW\GEMSHOW.PRG

	Using Mag!X the environment can be set by putting a '#_ENV' - line 
in the MAGX.INF file, like the following:

	#_ENV View=F:\SHOW_IMG\SHOW_IMG.PRG 

	The cookie should no longer be used.


2. What kinds of files can be displayed?
========================================

	The XAcc-Extended Name of the viewer should contain an entry of the 
form "X.ext" for every supported file format, where "ext" may be one of 
the following:

	X.ART      - Art-Director
	X.ASC      - ASCII
		Parargraphs end with carriage return, and lines may end 
		with a linefeed.
	X.B&W      - Imagelab Image
	X.BLK      - GFA Bit-Block
		There is a three word header: width minus one, height 
		minus one, planes.
	X.BMP      - OS/2 Bitmap, MS-Windows Bitmap
	X.CFN      - Calamus Font
	X.CRG      - Calamus Raster
	X.CTX      - Calamus Text
	X.CVG      - Calamus Vektor
	X.DOC      - 1stWord Document
	X.DOO      - Doodle Mono
	X.ESM      - Enhanced Simplex
	X.FNT      - GDOS Font (and nothing else!)
	X.GEM      - GEM-Metafile
	X.GIF      - GIF Images
	X.GVW      - GEM-View Internal Format
		Used by GEM-View internally and should not be in this 
		list! (Hi, Dieter!)
	//X.HEX    - Hex-Dump
		This is obsolete.  It is now called "XDump"
	X.IFF      - IFF-File
		The .IFF format in general! This should be present if any
		IFF-file-types are supported.
	X.IFF.ILBM - IFF InterLeavedBitMap
	X.IFF.type - Other IFF-file types.
	X.IMC      - Signum!2 Image
	X.IMG      - GEM-Image, XIMG
	X.JPG      - JPEG Image
	X.MAC      - MacPaint Image
	X.NEO      - Neochrome Image
	X.OUT      - The GEM 'OUT' file format.
		SEE:  v_alpha_text()
	X.PAC      - STAD Image
	X.PC[123]  - Degas Compressed Image
	X.PCX      - PC Paintbrush
	X.P[BGP]M  - Portable Bitmap
	X.PIC      - Screen Dump (current resolution)
	X.PI[123]  - Degas Uncompressed Image
	X.RLE      - MS-Window Bitmap
	X.RSC      - GEM Resource File
	X.RTF      - Rich Text Format
	X.SDO      - Signum!2 Document
	X.SDK      - Signum!3 Document
	X.SNP      - Becker Snap Shot
		This has a three word header: width, height, planes.
	X.SP[CU]   - Spectrum 512 Image
	X.SUN      - Sun Raster File
	X.TGA      - Targa Image
	X.TIF      - TIFF Image
	X.TN[123Y] - Tiny Image
	X.TXT      - ASCII
		Lines end with a carriage return and a linefeed.  It would
		be nice if a single linefeed (Unix) or a single CR 
		(Macintosh) would also be accepted.
	X.XBM      - X-Bitmap File

	XDump      - hexdump
		This is not an extension, but means that the viewer is 
		able to show files as hexadecimal dumps.

NOTE: [abc] means one of the characters 'a', 'b', or 'c' and not 
      the string '[abc]'.

	All other entries starting with 'X.' are reserved for future 
versions!  If you would like to add other formats, please contact Peter 
Seitz.  It would be wise if the entries are unique.

	I recommend the support of X.IMG, X.GEM and X.OUT, as these are 
the standard formats for GEM-data-exchange!

	It should be noted that the file formats listed here that an 
application supports could be a clue as to which file formats the 
application will accept using the Drag & Drop protocol.


3. How can I tell the viewer what is to be shown?
=================================================

	Because of the XAcc2-Protocol, the application knows which 
message-groups are supported and these messages may be used for 
communication if the application has the data already in memory (and not 
within a file).

	Use the VIEW_xxx messages, discussed in III.5 (below) when that data 
to be viewed is contained in a file.  With these messages the application 
has the extensive control over what is happening.  These messages may be 
used if, and *ONLY* if, the strings '2View' or 'NView' are found in the 
viewer's extended XAcc-name.  This should normally be the case, though.

	This may be a problem if the viewer has been started by the 
application.  In this case I would suggest to try to send the 
messages and see what happens.  If the viewer does not support 
them, no reaction is given (as unknown messages should be ignored!).
Otherwise, the viewer will send a response.

	The viewer is *strongly* reccommended to support the VA_START-
message!  Of course this has to be tested in its protostatus (if 
possible, see above).

	There is no explicit support of the Drag & Drop protocol, as 
it is a MiNT-specific extension, but programs running under MiNT should 
understand this protocol!

	All other protocols, of course, may be used to communicate with the
viewer (as long as they provide some method to determine whether or not 
they are supported).

	PLEASE keep in mind that pointers to strings in AES messages have to 
point to global-readable memory (if running in an environment with 
memory protection)!


4. What does the viewer do?
===========================

	When the viewer is started, it should check the command line for a 
list of filenames to view.  To be consistant with the direction that the 
Atari is moving, the viewer should support the ARGV argument passing 
scheme developed by Atari.

	The viewer should support the XAcc-Protocol, and answer XAcc-
Protocol messages.

	The viewer should use the Alternate + X key combination to send data 
using the XAcc-Protocol messages.

	If the viewer receives the VA_START message, it should determine the 
type of the file and whether or not the type is supported by itself.  
The viewer does not have to send a reply to this message.  If a reply is 
needed, the application should send the message to the viewer using the 
VIEW_FILE message.


5. The VIEW_XXX Messages
========================

	This is a description of the View Protocol messages. In contrast to
to the VA_START and XAcc messages, these messages provide more refined
control of what happens to the viewed file.

	Please remember that these messages may be used if, and *ONLY* 
if, the strings '2View' or 'NView' are found in the viewer's extended
XAcc-name as described above.

	In general, there are four messages; VIEW_FILE, which may be sent to 
the viewer, and VIEW_FAILED, VIEW_OPEN and VIEW_CLOSED that are used to 
inform the application of what has happened to its file.

	The viewer is expected to answer *EVERY* VIEW_FILE message it
recieves.  At the very least, it should send a VIEW_FAILED(VIEWERR_ERROR)
message (see below).  However, if the viewer does not send an answer and the
application expects one, the application should recover by using a 
timeout value (ten seconds should be sufficient).

	It is possible for the viewer to send other messages (EX: 
AV_ACCWINDOPEN) before answering the VIEW_FILE message!

NOTE:  All strings are null terminated (as in the "C" programming language).


a) View A File

The VIEW_FILE message is used by the application to inform the viewer that
a file is to be displayed.

    msg[0]   = VIEW_FILE
    msg[3/4] = filename // Must be global-readable (due to MiNT's memory 
                        // protection)!
    msg[5/6] = 0        // reserved!
    msg[7]   = 0        // zero = new file, see below!

	Notes about "filename" (9.10.1993):

	- If "filename" ends with a slash/backslash or "filename" is a 
      directory, the fileselector should be opened with "filename"
      as the current path.

	- If the terminating byte (0) of "filename" is followed by another 
      string starting with an 'X' ($58), this string gives the file
      type that "filename" should be displayed as (using the strings from
      III.2 as a guide) if possible.  This could be used to show hex-dumps
      ("XDump").

This message is always answered by the viewer:

		If the file could not be displayed, respond with the 	
	VIEW_FAILED message:

    retmsg[0]   = VIEW_FAILED
    retmsg[3/4] = msg[3/4]  // Filename (same pointer!)
    retmsg[5]   = errcode   // See below.
    retmsg[6]   = 0         // Reserved!
    retmsg[7]   = msg[7]    // 0 or window identification.

	"filename" should *ALWAYS* be the pointer recieved in VIEW_FILE,
	as only this way the sender can recognize which file was meant, 
	in case msg[7] is zero (and - of cause - no new memory has to be 
	alloced).

	The "errcode" variable may be a GEMDOS error-code (<0) or one of 
	the following:

    VIEWERR_ERROR   - The error is unspecified.
    VIEWERR_SIZE    - The file is too large, or the wrong size.
    VIEWERR_COLOR   - Unsupported resolution or color.
    VIEWERR_WID     - Wrong window identification.
    VIEWERR_MEM     - Not enough memory

    	It is expected that the viewer inform the user about the error (by 
	printing a message or displaying an alert box), since it will know 
	what the problem is much better than the application.

		If the file has been displayed, but NO further communication 
	is possible, the viewer sends the VIEW_OPEN message:

    retmsg[0]   = VIEW_OPEN
    retmsg[3/4] = msg[3/4]          // Filename (the recieved pointer)
    retmsg[5]   = viewprot_version  // Currently 0
    retmsg[6]   = 0                 // Reserved!
    retmsg[7]   = 0                 // 0 = no further communication!

		If the file has been displayed, and further communication is 
	possible, the viewer sends the VIEW_OPEN message:

    retmsg[0]   = VIEW_OPEN
    retmsg[3/4] = msg[3/4]          // Filename (the recieved pointer)
    retmsg[5]   = viewprot_version  // Currently 0
    retmsg[6]   = 0                 // Reserved!
    retmsg[7]   = wid               // Not zero!

	The window identification "wid" refers to the AES identification of 
the window the file is being displayed in.  This seems to be a unique number 
representing the file, which is used in further communication as an 
identifier.

	The currently defined "viewprot_version" is 0.


b) Further Communication

	Once a file is displayed (in a window) and the viewer has returned a 
non-zero window identification in msg[7], both the application and the 
viewer may send each other messages refering to this file/window.

	The "msg[7]" variable will ALWAYS contain the (non-zero) window 
identification as an identifier!  As this is supposed to be unique, 
the "msg[3/4]" variable should NOT be used to identify the file (if 
the "msg[7]" variable is not zero).

	If the viewer receives a wrong window identification, it replies by 
sending a VIEW_FAILED message:

    retmsg[0]   = VIEW_FAILED
    retmsg[3/4] = msg[3/4]
    retmsg[5]   = VIEWERR_WID
    retmsg[6]   = 0
    retmsg[7]   = msg[7]    // The wrong window identification.

	The application receiving this message must NOT use this window 
identification again, since the case may be that the viewer simply did 
not send VIEW_CLOSED(wid).

	The application can perform some operations on the file being 
viewed:

* The window should be closed (and the memory used by the file freed):

    msg[0]   = VIEW_FILE
    msg[3/4] = NULL         // Remove File
    msg[5/6] = 0
    msg[7]   = wid          // This (obviously) cannot be 0.

* If the application knows that the file has been changed, or wants 
  another file to be displayed in the same window, it can send the 
  following message:

    msg[0]   = VIEW_FILE
    msg[3/4] = filename     // This may be different.
    msg[5/6] = 0
    msg[7]   = wid          // The identification of the window.

	On the other side, the viewer should inform the application of what 
is happening to its file:

* If the window is closed (the user closed it or the viewer 
  received AC_CLOSE or VIEW_FILE(NULL, wid)), then the viewer should send 
  the following message:

    msg[0]   = VIEW_CLOSED
    msg[3/4] = filename     // This may be NULL and should be ignored!
    msg[5/6] = 0
    msg[7]   = wid

	The "filename" should be the one from the VIEW_FILE message, otherwise 
it may be NULL, as no new global memory should be allocated.

* If the window was closed due to an error, the VIEW_FAILED message 
  may be sent instead:

    msg[0]   = VIEW_FAILED
    msg[3/4] = filename     // This may be NULL and should be ignored!
    msg[5]   = errcode      // See above.
    msg[6]   = 0
    msg[7]   = wid

	If the viewer does not have the ability to store the identification 
of the application, it may not inform the application when a window was 
closed without a message from the application.  This is very easy to 
implement, but may lead to unexpected results.  Please send your 
experiences to Peter Seitz (the addresses he can be contacted at are 
shown above).


c) View Data from memory

	In Version 1.04 of the View Protocol a new message (VIEW_DATA) has been 
added, which is used to view data, that has already been read into memory.

	To indicate the support of this new message, the string 'XViewData' 
must be within the viewer's extended XAcc-name.

    msg[0]   = VIEW_DATA
    msg[3/4] = data		// pointer to data, incl. header (see below)
    msg[5/6] = length		// total length of header + data
    msg[7]   = wid		// same as with VIEW_FILE (see above)

where "data" points to:
LONG	type;		// eg '.IMG'
WORD	head_length;	// offset to beginning of data, word alligned!
CHAR[]  name;		// 0-terminated name of variable length

If the type is 0, the viewer should try to figure it out hisself. Other 
possible value for "type" are all file-types listed in III.2, but without 
the 'X' at the beginning (eg 'Dump' means, that beginning at "data + 
head_length" "length - head_length" bytes should be displayed as hex-dump).

Please note that:
  * "data" has to point to an even adress,
  * "data" has to point to global readable memory,
  * "head_length" is even,
  * the data of the file is found at "data + head_length" and is 
    in the same form, as it would be in a file of type "type".

The viewer recieving VIEW_DATA answers the same way as VIEW_FILE, but 
'filename' (= msg[3/4]) should be set to the value of 'data'.
The application MUST NOT free the memory pointed to by 'data', 
before recieving the answer from the viewer; in case of a timeout it 
should ask the user what to do.



6. The Messages
===============

	At last, the definitions for the messages:

	#define VIEW_FILE    0x5600
	#define VIEW_FAILED  0x5601
	#define VIEW_OPEN    0x5602
	#define VIEW_CLOSED  0x5603
	#define VIEW_DATA    0x5604

	#define VIEWERR_ERROR 0
	#define VIEWERR_SIZE  1
	#define VIEWERR_COLOR 2
	#define VIEWERR_WID   3
	#define VIEWERR_MEM   4

	// 0x56xx = 'V' as in 'View'!

	All other message values ranging from 0x5600 to 0x56FF are reserved 
for future extensions of the View Protocol and should be ignored for now.

