/********************************************************************/
/* Functionprototypes for functions which are used to simplify the
   communication with programs which understand the VA-Protocol.

   (c) 1990,91,92 by Stephan Gerle

   E-Mail: Maus Net: Stephan Gerle @ DO
           Internet: sg@do.maus.de

   Stand: 9.3.92
   Draft english version.

   You get the result 1 from all functions if the main program
   understand the required protocol message. Otherwise the functions
   return 0 as the result.

   See VAPROTO.H for further informations and the definitions of the
   message numbers.

*/

#ifndef __VAFUNC_H
#define __VAFUNC_H

#include <sg\vaprotoe.h>

/*** Macros **********************************************************/

/* AVSTR2MSG converts the value of a string pointer into the two Words of
   a message array.
       msg    : Name of the Word-Array
       offset : Smaller index of the two Word-Entries.
       str    : Pointer to string
*/
#define  AVSTR2MSG(msg,offset,str)  (*(char **)(msg+offset) = str)

/* AVMSG2STR converts two Words into one String-Pointer.
       msg    : Name of the Word-Array
       offset : Smaller inex of the two Word-Entries
*/
#define  AVMSG2STR(msg,offset)         ((char
 *)(((long)msg[offset]<<16)|(((long)msg[offset+1])&0xffff)))

/* AVHasProto() tests if the main program understands a particular
   VA-Protocol message.
   Parameters are the number of the word (0-2) and the bitnumber of
   message (used by VA_PROTOSTATUS).
   See also VAPROTO.H at VA_PROTOSTATUS */

#define  AVHasProto(word,bit)       (AVStatus[word]&(1<<bit))


/* Result is TRUE, if a multi AES is installed (PC or TC only).
*/

#define  MultiAES()  (_GemParBlk.global[1]!=1)

#define	AP_TERM	50

/*** Global variables for this library. Don't set any Variable directly. **********/



/* AVName is a pointer to a string. This String is a NULL-String or the
   name of the main program is in the string.*/

extern char AVName[];

/* AVStatus[3] are the 3 Words returned from the main program by the
   message VA_PROTOSTATUS. You can test the particular message by
   AVHasProto() rather than testing directly.*/

extern int  AVStatus[3];


/*** General purpose functions for implementing the VA-Protocol *******************/

/* You must call AVInit ones at the beginning of your Acc. This function
   stores the parameters for later use by the VA-Protocol functions und sends
   a AV_PROTOCOL message to the main program.
      myapid   must be the ap_id (returned by appl_init) of the Acc.
      myname   must be the name of the Acc. Same conventions as for
               appl_find
      myprotostatus is a bit-vector. You must tell the main program which
               messages you understand. See AV_PROTOCOL for valid bits.*/

void  AVInit(int myapid,char *myname,int myprotostatus);


/* This function results non zero, if the main program understands the
   VA-Protocol.
   If the lib dosn't know the protocol status of the main program, this
   functions sends a request to the main program.*/

int   AVActive(void);


/* This function invalids the internal stored protocol status and request
   the new protocol status from the main program.
   This function is called by AVProcessMsg(), when AC_CLOSED is
   received.*/

void  AVGetNewProtoStatus(void);


/* Sends a status string to the main program. */

int   AVSendStatus(char *status);


/* Requests the stored status from the main program.
   The status comes later with the message VA_SETSTATUS. msg[3/4] is the
   pointer to the status string.*/

void  AVReceiveStatus(void);


/* You must call AVProcessMsg() for every received message. AVProcessMsg()
   results nonzero, if the protocolstatus has changed. This doesn't mean,
   that VA_PROTOSTATUS has been received. */

int   AVProcessMsg(int *msg);



/*** Special purpose functions **************************************************/



/* Requests the font id and the font point height of the Font in the
   directory window in Venus or Gemini. This should be the normal used font.
   The font id and font point hight is send with VA_FILEFONT by the main
   program. */

int   AVAskFileFont(void);


/* Same as AVAskFileFont but for the font used in the console window. The
   informations comes with the message VA_CONFONT. */

int   AVAskConsoleFont(void);


/* Request a list of the selected objects in the main program. The list
   comes as a string. All objects are seperated by a blank (' '). The message
   VA_OBJECT is used for sending the result.*/

void  AVAskSelectedObjects(void);


/* Opens the console window in Gemini. */

int   AVOpenConsole(void);


/* Opens a directory window with given path and filemask. */

int   AVOpenWindow(char *pfad,char *mask);


/* Starts a "program" indirectly. path is the full path and filename of
   the program. In Gemini the started object can be any file if Gemini knows
   the program which must be started for this file. */

int   AVStartProgram(char *path,char *cmdline);


/* Tells the main program that the Acc has opened a window.
 */

int   AVAccOpenedWindow(int winhandle);


/* Tells the main program that the Acc has closed a window. Don't use this
   message, if you receive AC_CLOSE! */

int   AVAccClosedWindow(int winhandle);


/* Sends a keyboard event to the main program. This is useful, if the Acc
   owns the top window and don't use the received keyboard event.*/

int   AVSendKeyEvent(int state,int key);


/* AVCopyDragged sends the message AV_COPY_DRAGGED to the main program.
   The main program should then copy the dragged icons to the destination
   path.
   kstate ist the keyboard state (got from evnt_multi()).
   The main program sends VA_COPY_COMPLETE if the copy command completes.
   The Acc should release requested memory when VA_COPY_COMPLETE is
   received.
   This function must only be used as a answer of VA_DRAGACCWIND.*/

int   AVCopyDragged(int kstate,char *dest);



/*** Sample ***********************************************************************/

#ifdef __DO_NOT_DEFINE

/* This is a minial skeleton for using this lib.*/

void  HandleMessage(int kstate,int *msg)
{
   int   FontId,FontPointsHeight;
   char  *status;

   if (AVProcessMsg(msg))
   {
      /* Protocolstatus has changed */

      if ("own open windows")
         for ("for all open windows")
            AVAccOpenedWindow(winhandle);
      AVAskFileFont();
      AVReceiveStatus();
      ...
   }
   switch (msg[0])
   {
      case  WM_FULLED:  ...
      case  WM_SIZED:      ...
      case  WM_MOVED:      ...
      case  WM_REDRAW:  ...
      case  WM_TOPPED:  ...
      case  WM_ARROWED: ...
      case WM_VSLID:    ...
      case WM_HSLID:    ...

      case  VA_SETSTATUS:
               /* msg[3] and msg[4] together are a pointer to the string
               with the status. This stringpointer can be NULL.*/
               ...
               break;
      case  VA_FILEFONT:
               /* msg[3] and msg[4] are used for the fond data
                  (see VAPROTO.H) */
               ...
               break:
      case  VA_START:
               /* msg[3] and msg[4] together are a pointer to the
               commandline. */
               ...
               break;
      case  VA_DRAGACCWIND:
               /* msg[6] and msg[7] together are a pointer to the string
               with the list of the objects dragged on the Acc window.*/
               ...
               break;
      case  VA_COPY_COMPLETE:
               /* copy command completed. Release eventually allocated
               memory. */
               break;
      ...
   }
}

void  HandleKey(int ks,int kb)
{
   switch (kb)
   {
      ...
      default: AVSendKeyEvent(ks,kb);
            break;
   }
}

void  EventLoop(void)
{
   int   event,msg[8],kb,ks;

   do
   {
      event = evnt_multi(MU_MESAG|MU_KEYBD...,...,msg,...,ks,kb,...);
      if (event&MU_MESAG)
         HandleMessage(ks,msg);
      if (event&MU_KEYBD)
         HandleKey(ks,kb);
      ...
   } while (!QuitFlg);
}

/* This lib must be initializied by AVInit() ones at the beginning of the
   program. */

int   gl_apid;

void  main(void)
{
   if ((gl_apid = appl_init())>=0)
   {
      ...
      AVInit(gl_apid,"ACCNAME ",1|2);
      if (MultiAES())
         "Wait until status comes or user acts."
      else
      {
         "open window or do something else"
         EventLoop();
      }
      ...
      appl_exit();
   }
}
#endif
#endif
