/*
Demonstrates shared message ports in amarquee.library v.50+.
With this feature many sessions's qmessages can be sent to the same message port,
there by saving signal bits.
You figure out which session the qmessage comes from by looking at the qm_Session field
in the QMessage. Remember to add the right session to the FreeQMessage(), like this
FreeQMessage(qMsg->qm_Session,qMsg);

By Håkan Parting 2000
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <dos/dos.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>

#include <clib/AMarquee_protos.h>

#include <pragmas/AMarquee_pragmas.h>
#include <utility/tagitem.h>
#include <libraries/AMarquee.h>

struct Library * AMarqueeBase = NULL;
struct QSession * session     = NULL;
struct QSession * session2     = NULL;
struct QSharedMessagePort *smp=NULL;
#define ASYNC_CONNECT 1

/* New in version 50. Return error code in a variable */
LONG errid=0;
LONG errid2=0;

void CleanExit(void)
{
   printf("\nCleaning up...\n");
   if (session)      QFreeSession(session);        /* This MUST be done before we close the library! */
   if (session2)      QFreeSession(session2);        /* This MUST be done before we close the library! */
   if (smp) QDeleteSharedMessagePort(smp); /* This MUST be done AFTER all Sessions are freed */
   if (AMarqueeBase) CloseLibrary(AMarqueeBase);  
   printf("All done.\n");
}

/* Main program */
int main(int argc, char ** argv)
{
   char * connectTo;
   int port;
    
   printf("Usage Note:  AMarqueeSharedMP [hostname=localhost] [port=2957]\n");  
   atexit(CleanExit);
  
   connectTo = (argc>1) ? argv[1] : "localhost";
   port      = (argc>2) ? atoi(argv[2]) : 2957;

   if ((AMarqueeBase = OpenLibrary("amarquee.library",50L)) == NULL)
   {
      printf("Couldn't open amarquee.library v50!\n");
      exit(RETURN_ERROR);
   }

   /* Create shared message port */
   if (!(smp=QCreateSharedMessagePort())) {
      printf("Could not create message port!\n");
      exit(RETURN_WARN);
   }

#ifdef ASYNC_CONNECT
    printf("Connecting to %s:%i using progname Test1\n",connectTo, port);
    if ((session = QNewSessionAsyncTags(connectTo, port, "Test1",
        QSESSION_ERRORCODEPTR,(ULONG)&errid,
        QSESSION_SHAREDMSGPORT,(ULONG)smp,
        TAG_DONE)) == NULL)
    {
        printf("Couldn't connect to server %s:%i\nError: %s\n",connectTo, port, QErrorName(errid));
        exit(RETURN_WARN);
    }
    printf("Connecting to %s:%i using progname Test2\n",connectTo, port);
    if ((session2 = QNewSessionAsyncTags(connectTo, port, "Test2",
        QSESSION_ERRORCODEPTR,(ULONG)&errid2,
        QSESSION_SHAREDMSGPORT,(ULONG)smp,
        TAG_DONE)) == NULL)
    {
        printf("Couldn't connect to server %s:%i\nError: %s\n",connectTo, port, QErrorName(errid2));
        exit(RETURN_WARN);
    }
#else
    printf("Connecting to %s:%i using progname Test1\n",connectTo, port);
    if ((session = QNewSessionTags(connectTo, port, "Test1",
        QSESSION_ERRORCODEPTR,(ULONG)&errid,
        QSESSION_SHAREDMSGPORT,(ULONG)smp,
        TAG_DONE)) == NULL)
    {
        printf("Couldn't connect to server %s:%i\nError: %s\n",connectTo, port, QErrorName(errid));
        exit(RETURN_WARN);
    }
    printf("Connecting to %s:%i using progname Test2\n",connectTo, port);
    if ((session2 = QNewSessionTags(connectTo, port, "Test2",
        QSESSION_ERRORCODEPTR,(ULONG)&errid2,
        QSESSION_SHAREDMSGPORT,(ULONG)smp,
        TAG_DONE)) == NULL)
    {
        printf("Couldn't connect to server %s:%i\nError: %s\n",connectTo, port, QErrorName(errid2));
        exit(RETURN_WARN);
    }
#endif

    printf("Connected to server %s:%i\n",connectTo, port);

    QSetAccessOp(session,"/#?/#?");
    QSetAccessOp(session2,"/#?/#?");

    /* Get and subscribe on all keys from any progname and host*/
    QGetAndSubscribeOp(session,"/#?/#?/comment",100);
    QGetAndSubscribeOp(session2,"/#?/#?/comment",100);

    /* Set some data */
    QSetOp(session,"comment","Hello I'm test1",16);
    QSetOp(session2,"comment","Hello I'm test2",16);

    QGo(session,0L);
    QGo(session2,0L);



  
    while(1)
    {
        struct QMessage * qMsg;
        ULONG signals = (1L << smp->qs_mp->mp_SigBit) | (SIGBREAKF_CTRL_C);
        /* Wait for next message from the server */
        signals = Wait(signals);
    
        if (signals & (1L << smp->qs_mp->mp_SigBit))
        {
            while(qMsg = (struct QMessage *) GetMsg(smp->qs_mp))
            {
                if (qMsg->qm_Status==QERROR_NO_ERROR) {
                    if (qMsg->qm_ID!=0)
                        printf("Session %d Path=[%s] Data=[%s]\n",qMsg->qm_Session==session ? 1 : 2,qMsg->qm_Path?qMsg->qm_Path:"<NULL>",qMsg->qm_Data?qMsg->qm_Data:((UBYTE*)"<NULL>"));
                    else if (qMsg->qm_DataLen==0 && qMsg->qm_Path!=NULL)
                        printf("Session %d Connected! Path=[%s]\n",qMsg->qm_Session==session ? 1 : 2,qMsg->qm_Path);

                }
                else
                    printf("Session %d Error: %s\n",qMsg->qm_Session==session ? 1 : 2,QErrorName(qMsg->qm_Status));

                FreeQMessage(qMsg->qm_Session, qMsg);
           }
        }
        if (signals & SIGBREAKF_CTRL_C) break;  /* Quit if CTRL-C pressed */
    }
    /* CleanExit() called here! */
}
