INTRODUCTION
This document is meant to explain how to proceed when initiating AV-server support in your applications. When I started using the protocol myself I found that the documentation in Thing is not really explaining much about the calls. You just get enough info to learn the syntax and that might be very confusing when you start to get into things like this.
This document is not meant to be a complete manual for the AV-protocol but might be useful if you quickly want to get an overview of functions and in what order things are supposed to be done. In short, the basics.
If you find errors or feel something should be added, please get in touch with me. I don't accept any responsibility for possible errors or mistypings in this document!
2001-07-03 Joakim Högberg (gokmase@bigfoot.com)
The AV-protocol was invented to allow the Gemini desktop and active clients to communicate. The graphical part of Gemini is called Venus, so AV refers to Application (the client) and Venus (the server).
These days there aren't that many still using Gemini but the most common desktops (Thing & Jinnee) for the Atari both support the protocol. For those using MagXdesk there is also a program called AV-SERVER available, that will make MagXdesk understand most of the AV-calls. However, this solution is not as solid as the ones provided by Thing and Jinnee, so it is recommended to update to one of these.
You could consider the additional functionality provided by these up-to-date desktops a bonus ;)
THE BASICS -How it works
The AV-protocol will allow communication to be passed in both directions and if you see a call starting with:
* AV_ it means the call is passed from (A) Application to (V) Venus/avserver
* VA_ it means the call is passed from (V) Venus/avserver to (A) application
NOTE: Some calls will work in both directions, for example VA_START
AV-calls are sent and recieved just like any other AES-message, so you use APPL_WRITE to send and EVNT_MULTI or EVNT_MESAG to check for incoming data. The data passed in the different AV-calls may differ but the number of bytes passed is always 16.
The first bytes are always following this pattern:
(assuming msg% is a pointer to a 16 byte buffer)
address: Contents:
msg%+0 The number of the AV-call (2 byte, signed integer)
msg%+2 The application ID of the calling client (2 byte, signed integer)
The remaining bytes contain various data, depending on what call is sent.
NOTE: Many of the AV-calls will contain zeros somewhere in the data buffer,
so it is adviced to always clear the buffer before filling it with data.
If you use an AV-call that involves sending data you must be aware that you can not assume it is safe to just reserve a buffer using private memory. The buffer you use to store the data must use globally allocated memory, else your program will run into trouble if a user wants to run it under memory protection! There are docs on how to check what memory allocation call to make. Anyone using GFA will probably find the docs found on my site useful. (http://gokmase.atari.org)
IMPLEMENTATION SUGGESTIONS -General descriptions and advice
To use the AV-protocol you need to find out the name of the AV-server. If the AV-server is properly installed you can find it be searching for the string "AV-SERVER" in the environment by using the call SHEL_ENVRN. Once you have retrieved the actual name you can find out its application id with the call APPL_FIND.
(If the name of the application is shorter than 8 characters you fill it with spaces, so if the av-server is "THING" you should look for "THING ")
If you wish to support the AV-protocol, the first call you need to explore is AV-PROTOKOLL. This call serves 2 purposes. Most importantly it will make the AV-server aware of your app, so make this call before trying to use any of the other calls. Secondly, this call also is used to ask the AV-server if it supports some specific AV-calls.
AV-server will reply to this call by sending VA_PROTOSTATUS When your app is about to be terminated (or if you want to tell AV-server you don't want to use AV-protocol functions anymore) you must send AV_EXIT. If you don't do that the AV-server will think your application is still active and thus ready to send and recieve data.
If you are writing a GEM-application that uses the AV-protocol you should report any windows you open to the AV-server with the call AV_ACCWINDOPEN. With this call you tell the AV-server that this window handle belongs to your app and the AV-server can later use that information when a user selects CLOSE ALL (in Thing's menubar) or when performing global window cycling.
When a window previously reported via AV_ACCWINDOWOPEN is closed, you must also report this to the AV-server by sending AV_ACCWINDCLOSED.
If your app supports AV-protocol it is strongly adviced that you support the global window cycling scheme. If your app recieves a CTRL+W from the keyboard you can pass the status of shiftkeys and scan code and ascii via AV_SENDKEY to the AV-server and let it cycle all windows that previously has been reported with AV_ACCWINDOPEN. This is a feature that will work fully only if all apps support it so even if you don't like this yourself, please consider supporting this, you can make it possible to disable it within your own app!
NOTE: The shiftkey value is always 4 (ctrl-key is pressed) but the scan code for the ascii character "w" might change between various keyboard mappings. If you read the key via evnt_multi you can just pass the keycode it generates, if so there will be no problems. The upper byte contains the scan code and the lower byte contains the ascii value.
If your application has modified an existing file or created or deleted one, it might be a neat thing to let the AV-server know about this by sending AV_PATH_UPDATE. If the desktop has opened a window viewing the directory where the changed file is located, it will refresh the contents of this directory to view the current data. This is neat! :)
If the present AV-server supports the font selector protocol and the environment variable FONTSELECT is set to the appname of the AV-server (eg. FONTSELECT=THING) you can call for the font selector whenever you want to change a font inside your application.
When an application wants to call the font selector it needs to send FONT_SELECT. In this call you will also tell the font selector what font ID, point size and attributes should be default when the selector is opened. You also need to pass the AES-handle of the window that is about to have its font changed.
When the font selector reports back about a font change (doesn't matter if the change is triggered by user clicking "OK" in the font selector window or if the font was drag/dropped from selector to a window belonging to your app) it will send VA_FONTCHANGED.