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 desk 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 RECOMMENDED 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(at)rbg.informatik.th-darmstadt.de or seitz(at))isa.informatik.th-darmstadt.de
This protocol should be quite easy to implement for both the writers of viewers and the writers 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.
In the following dicussion, 'viewer' refers to the desk 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.
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).
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 environmental variable called 'View' with the full pathname of the desired viewer as its value. The way that this can be done is described in 'Who is the viewer?'.
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).
First, an application should determine if there is a viewer that the user prefers. It does this by (in this order) looking for an environmental variable called 'View', looking for a cookie in the cookie jar called 'View', and then looking for an environmental variable called 'SHSHOW' (which is used by the MultiTOS desktop, too). All these names are case-sensitive.
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 a desk accessory, usually, but it is possible for the viewer to be an application under 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 or MagiC.
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 one of these environmental 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' environmental 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' environmental 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' environmental variable.
Normally the user should use one of the enironmental 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
setenv SHSHOW C:\GEM_VIEW\GEMSHOW.PRG
Using MagiC the environment can be set by putting a '#_ENV' - line in the MAGX.INF file, like the following:
The cookie should no longer be used.
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 Paragraphs end with carriage return, and lines may end ##6# WAR: Parargraphs 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 vector 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 image 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-filetypes are supported. X.IFF.ILBM - IFF InterLeavedBitMap X.IFF.type - Other IFF-filetypes 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 - Degas compressed Image X.PCX - PC Paintbrush X.P[BGP]M - Portable Bitmap X.PIC - Screen-dump (current resolution) X.PI - Degas uncompressed image X.RLE - MS-Windows 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 - Hex-dump 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-exchanges!
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.
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 below) when the data to be viewed is contained in a file. With these messages the application has 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 recommended 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 was mainly a MiNT-specific extension (though it is included in MultiTOS and later in MagiC), 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)!
When the viewer is started, it should check the command line for a list of filenames to view. To be consistent 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.
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 receives. 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 (for example AV_ACCWINDOPEN) before answering the VIEW_FILE message!
Note: All strings are NULL-terminated (as in the 'C' programming language).
The VIEW_FILE message is used by the application to inform the viewer that a file is to be displayed.
msg = VIEW_FILE msg[3/4] = filename // Must be global-readable (due to MiNT's memory // protection)! msg[5/6] = 0 // Reserved! msg = 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 file-selector 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' (0x58), this string gives the file type that filename should be displayed as (using the strings from 'What kinds of files can be displayed?' 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 = VIEW_FAILED retmsg[3/4] = msg[3/4] // Filename (same pointer!) retmsg = errcode // See below. retmsg = 0 // Reserved! retmsg = msg // 0 or window identification.
filename should always be the pointer received in VIEW_FILE, as only this way can the sender recognize which file was meant in case msg is zero (and - of course - no new memory has to be allocated.
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 informs 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 = VIEW_OPEN retmsg[3/4] = msg[3/4] // Filename (the recieved pointer) retmsg = viewprot_version // Currently 0 retmsg = 0 // Reserved! retmsg = 0 // 0 = no further communication!
If the file has been displayed, and further communication is possible, the viewer sends the VIEW_OPEN message:
retmsg = VIEW_OPEN retmsg[3/4] = msg[3/4] // Filename (the recieved pointer) retmsg = viewprot_version // Currently 0 retmsg = 0 // Reserved! retmsg = wid // Window ID (non-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.
Once a file is displayed (in a window) and the viewer has returned a non-zero window identification in msg, both the application and the viewer may send each other messages refering to this file/window.
The 'msg' 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' variable is not zero).
If the viewer receives a wrong window identification, it replies by sending a VIEW_FAILED message:
retmsg = VIEW_FAILED retmsg[3/4] = msg[3/4] retmsg = VIEWERR_WID retmsg = 0 retmsg = msg // 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 = VIEW_FILE msg[3/4] = NULL // Remove File msg[5/6] = 0 msg = 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 = VIEW_FILE msg[3/4] = filename // This may be different. msg[5/6] = 0 msg = wid // The identification of the window.
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 = VIEW_CLOSED msg[3/4] = filename // This may be NULL and should be ignored! msg[5/6] = 0 msg = wid
If the window was closed due to an error, the VIEW_FAILED message may be sent instead:
msg = VIEW_FAILED msg[3/4] = filename // This may be NULL and should be ignored! msg = errcode // See above. msg = 0 msg = wid
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 = VIEW_DATA msg[3/4] = data // Pointer to data, incl. header (see below) msg[5/6] = length // Total length of header + data msg = 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 itself. Other possible value for type are all file-types listed in 'What kinds of files can be displayed?' but without the 'X' at the beginning (e.g. 'Dump' means that starting at 'data + head_length', 'length - head_length' bytes should be displayed as a hex-dump).
Please note that:
The viewer receiving 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 receiving the answer from the viewer; in case of a timeout it should ask the user what to do.
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 VIEW_GETMFDB 0x5610 #define VIEW_SETMFDB 0x5611 #define VIEW_MFDB 0x5612 #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.