home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 339.lha / DispMod / source / dispmod.c < prev    next >
C/C++ Source or Header  |  1990-02-07  |  13KB  |  485 lines

  1. /****************************
  2. *  dispmod.c
  3. *  Display module for ROBBS.
  4. *****************************/
  5.  
  6. #include <libraries/dos.h>
  7. #include <fcntl.h>
  8. #include <functions.h>
  9. #include <exec/types.h>
  10. #include <stdio.h>
  11. #include <intuition/intuition.h>
  12. #include <exec/memory.h>
  13. #include <rexx/storage.h>
  14. #include <rexx/rxslib.h>
  15. #include "ConsoleIO.h"
  16. #include "Rexx.h"
  17. #include "defs.h"
  18.  
  19. char  portname[17]     = "ROBBS_ctrl";
  20. char  macroport[17]    = "ROBBS_ctrl";
  21. char  command[10]      = "SEND";
  22. char  keystring[255];
  23. char  status[100];
  24. char  normaltext[]     = "\x9Bm";
  25. char  redtext[]        = "\x9B33m";
  26. UBYTE  titlestring[77] = VERSION;
  27. STRPTR  Token;
  28.  
  29. int  connected;
  30. int  outstanding_rexx_commands = 0;
  31. int  CRPending = 0;
  32.  
  33. struct  RexxLib  *RexxSysBase;
  34. struct  MsgPort  RexxPort;
  35. struct  RexxMsg  *rmptr, *OutMsg, *CreateRexxMsg();
  36.  
  37. BOOL KeepGoing = TRUE;
  38.  
  39. void    FreePort();
  40. char    nexttoken();
  41. STRPTR  CreateArgstring();
  42.  
  43. struct IntuitionBase *IntuitionBase = NULL;
  44. static struct  IOStdReq *Console = NULL;      /* see "ConsoleIO.h"  */
  45.  
  46. static  struct  Window *mywindow = NULL;      /* ptr to applications window */
  47. static  struct  IntuiMessage *NewMessage;     /* msg structure for GetMsg() */
  48. static struct IOStdReq *rd = NULL, *wr = NULL;
  49.  
  50. static char *validargs[] =
  51.   {
  52.   "TEXT",     /* 0  */ 
  53.   "LTEXT",    /* 1  */ 
  54.   "HTEXT",    /* 2    highlighted text, one colour only for now */
  55.   "LHTEXT",   /* 3     same, with linefeed appended */
  56.   "CRSR",     /* 4     cursor row, column */
  57.   "GETLINE",  /* 5     getline [prompt]   */
  58.   "STATUS",   /* 6  */
  59.   "CONNECT",  /* 7  */
  60.   "CTRL",     /* 8  */
  61.   "TITLE",    /* 9  */
  62.   "DIE",     /* 10 */
  63.   NULL
  64.   };
  65.  
  66. static  int    numcmds = 11;
  67.  
  68. /* my window structure */
  69. static struct NewWindow NewWindow = {
  70.    0,0,640,200, /* left, top, width, height */
  71.    0,1,   /* detail, block pens */
  72.    CLOSEWINDOW | GADGETUP,
  73.    WINDOWCLOSE
  74.       | SMART_REFRESH
  75.       | ACTIVATE
  76.       | WINDOWDEPTH
  77.       | BORDERLESS
  78.       ,
  79.    NULL,       /* firstgadget */
  80.    NULL,       /* checkmark */
  81.    titlestring, /* title */
  82.    0,          /* screen */
  83.    NULL,       /* bitmap */
  84.    0,0,        /* min x,y */
  85.    640, 200,   /* max x,y */
  86.    WBENCHSCREEN  /* type */
  87. };
  88.  
  89. /*--------------------------------------------------------------*/
  90. /*      cleanup: all done so close up and prepare to exit       */
  91. /*--------------------------------------------------------------*/
  92.  
  93. static void cleanup()
  94.   {
  95.   if (RexxSysBase != NULL)
  96.     {
  97.     RemPort(&RexxPort);                   /* unlink it                     */
  98.     FreePort(&RexxPort);                  /* release the port resources    */
  99.     CloseLibrary(RexxSysBase);
  100.     }
  101.   if ( mywindow != NULL )
  102.     CloseWindow( mywindow );
  103.   if ( Console != NULL )
  104.     CloseConsoleIO();
  105.   if ( IntuitionBase != NULL )
  106.     CloseLibrary(IntuitionBase);
  107.   }
  108.  
  109. /*-------------------------------------------------------*/
  110. /*      init: initialize dispmod - set defaults          */
  111. /*-------------------------------------------------------*/
  112.  
  113. static void init()
  114.   {
  115.  
  116.   IntuitionBase = (struct IntuitionBase *)
  117.     OpenLibrary("intuition.library", INTUITION_REV);
  118.   if( IntuitionBase == NULL )
  119.     {
  120.     puts("can't open intuition\n");
  121.     goto badopen;
  122.     }
  123.  
  124.   if(( mywindow = OpenWindow(&NewWindow) ) == NULL)
  125.     {
  126.     puts("Can't open a window.\n");
  127.     goto badopen;
  128.     }
  129.  
  130.   if(( Console = InitConsoleIO( mywindow, &rd, &wr ) ) == NULL)
  131.     {
  132.     puts("Can't open the console.\n");
  133.     goto badopen;
  134.     }
  135.  
  136.   RexxSysBase = (struct RexxLib *)OpenLibrary("rexxsyslib.library",0L);
  137.   if (RexxSysBase == NULL)
  138.     {
  139.     printf("Can't open rexxsyslib.library.\n");
  140.     goto badopen;
  141.     }
  142.   InitPort(&RexxPort,"ROBBS_disp");    /* Initialize our message port   */
  143.   AddPort(&RexxPort);          /* Make the port public          */
  144.  
  145.   return;
  146.  
  147.   badopen:
  148.   cleanup();
  149.   exit( 4 );
  150.   }
  151.  
  152. /*--------------------------------------------------------------*/
  153. /*      buildstatus: build status string from variables         */
  154. /*--------------------------------------------------------------*/
  155.  
  156. void buildstatus()
  157. {
  158. int j;
  159.  
  160.   sprintf(status, "%s %s %lx %lx",portname, macroport, mywindow, wr);
  161. }
  162.  
  163. /*-----------------------------------------------------------------*/
  164. /*  send_rexx_msg: send a message to a port                       */
  165. /*-----------------------------------------------------------------*/
  166.  
  167. send_rexx_msg(port, cmd, s)
  168. char *port;
  169. char *cmd;
  170. char *s;
  171. {
  172.   struct MsgPort *localport;
  173.  
  174.   /* RexxPort is reply port. look for reply there */
  175.  
  176.   OutMsg = CreateRexxMsg(&RexxPort, "dccs", "DCCS" );
  177.   if (OutMsg != NULL)
  178.     {
  179.  
  180.     OutMsg->rm_Args[0] = CreateArgstring( cmd, (long) strlen( cmd ));
  181.     OutMsg->rm_Args[1] = CreateArgstring( s, (long) strlen( s ));
  182.  
  183.     OutMsg->rm_Action = RXFUNC | 1;
  184.   /*    FillRexxMsg(OutMsg, 1L, 0L);    */
  185.  
  186.     Forbid();
  187.     localport = FindPort(port);
  188.     if (localport != 0) PutMsg(localport, OutMsg);
  189.     Permit();
  190.     };
  191.  
  192.   outstanding_rexx_commands++;
  193.   return(0);              /* ya, I know, I need error checking. */
  194. }
  195.  
  196. /*-----------------------------------------------------------------*/
  197. /*  free_rexx_command: free the message we sent and decrement count */
  198. /*-----------------------------------------------------------------*/
  199.  
  200. free_rexx_command(rexxmsg)
  201. register struct RexxMsg *rexxmsg;
  202. {
  203.   /* delete the argument that we originally sent */
  204.  
  205.   DeleteArgstring(rexxmsg->rm_Args[0]);
  206.   DeleteArgstring(rexxmsg->rm_Args[1]);
  207.  
  208.   /* delete the extended message */
  209.  
  210.   DeleteRexxMsg(rexxmsg);
  211.  
  212.   /* decrement the count of outstanding messages */
  213.  
  214.   outstanding_rexx_commands--;
  215. }
  216.  
  217. /*-----------------------------------------------------------------*/
  218. /*  sendfkey(number): inform of function key usage                */
  219. /*-----------------------------------------------------------------*/
  220.  
  221. sendfkey( num )
  222. short num;
  223. {
  224. char message[8];
  225.  
  226.   sprintf( message, "%c", num );
  227.   send_rexx_msg(macroport, "FKEY", message);
  228. }
  229.  
  230. /*-----------------------------------------------------------------*/
  231. /*  sendhelp(number): inform of HELP key usage                      */
  232. /*-----------------------------------------------------------------*/
  233.  
  234. sendhelp()
  235. {
  236.   send_rexx_msg(macroport, "HELP", NULL);
  237. }
  238.  
  239. /*-----------------------------------------------------------------*/
  240. /*  nexttoken(): search for next space or NULL in token string      */
  241. /*-----------------------------------------------------------------*/
  242. char
  243. nexttoken()
  244. {
  245.   for ( ;(*Token != ' ' && *Token != '\0'); Token++ );
  246.   if (*Token == ' ') {
  247.     Token++;
  248.     return(' ');
  249.     }
  250.   else
  251.     return('\0');
  252. }
  253.  
  254. /*-----------------------------------------------------------------*/
  255. /*  cr2lf(s): convert all instances of CR in string s to linefeeds  */
  256. /*         : leave cr/lf combination alone                         */
  257. /*-----------------------------------------------------------------*/
  258.  
  259. cr2lf ( s )
  260. char *s;
  261. {
  262.  
  263.   if ( CRPending )
  264.     if ( *s != '\n' )
  265.       PutString("\n");
  266.   CRPending = 0;
  267.   for (; *s; s++) {
  268.     if ( (*s == '\r') && (*(s+1) != '\n') )
  269.       if ( *(s+1) = '\0' )
  270.         CRPending = 1;
  271.       else
  272.         *s = '\n';
  273.     }
  274. }
  275.  
  276. /******************************************************/
  277. /*             Main Program                            */
  278. /*                                                    */
  279. /*      This is the main body of the program.         */
  280. /******************************************************/
  281.  
  282. main()
  283. {
  284. ULONG class, waitmask;
  285. int c, i, j, x, y, code, keycount ;
  286. UBYTE character;
  287.  
  288.   init();
  289.  
  290.   waitmask = (1L << mywindow->UserPort->mp_SigBit)
  291.     |  (1L << Console->io_Message.mn_ReplyPort->mp_SigBit)
  292.     |  (1L << RexxPort.mp_SigBit);
  293.  
  294.   KeepGoing = TRUE;
  295.   while( KeepGoing )
  296.     {
  297.     if (( rmptr = (struct RexxMsg *) GetMsg(&RexxPort)) == NULL )
  298.       {
  299.       Wait( waitmask );
  300.       rmptr = (struct RexxMsg *) GetMsg(&RexxPort);
  301.       }
  302.     if (rmptr)
  303.       {
  304.       if (rmptr->rm_Node.mn_Node.ln_Type == NT_REPLYMSG )
  305.         free_rexx_command(rmptr);
  306.       else
  307.         {
  308.         Token = rmptr->rm_Args[0];
  309.         for (i=0; i < numcmds; i++)
  310.           if ( StrcmpN(rmptr->rm_Args[0], validargs[i], 3L) == NULL)
  311.             break;
  312.  
  313.         if (rmptr->rm_Action & 15L)  {
  314.           Token = rmptr->rm_Args[1];
  315.           }
  316.         else  {
  317.           nexttoken();
  318.           }
  319.  
  320.         /* Set 'normal result codes'. these are set here, */
  321.         /* and only changed in case of error or when      */
  322.         /* returning a result string (as in STATUS).      */
  323.  
  324.         rmptr->rm_Result1 = 0;           /* return code      */
  325.         rmptr->rm_Result2 = 0;           /* secondary result */
  326.  
  327.         switch (i)
  328.           {
  329.           case 0:    /* TEXT  */
  330.           case 1:    /* LTEXT  */
  331. /*            cr2lf(Token);        */
  332.             PutString(normaltext);
  333.             PutString(Token);
  334.             if (i == 1) PutString("\n");
  335.             break;
  336.           case 2:    /* HTEXT  */
  337.           case 3:    /* LHTEXT  */
  338. /*            cr2lf(Token);        */
  339.             PutString(redtext);
  340.             PutString(Token);
  341.             PutString(normaltext);
  342.             if (i == 3) PutString("\n");
  343.             break;
  344.           case 4:    /* CURSOR  */
  345.             for (j=0; Token[j] != ' '; j++);
  346.               Token[j] = '\0';
  347.             j++;
  348.             y = atoi(Token);
  349.             x = atoi(&Token[j]);
  350.             CursorXY(x,y);
  351.             break;
  352.           case 5:    /* GETLINE */
  353.             if (*Token)
  354.               GetLine(Token, keystring);
  355.             else
  356.               GetLine(NULL, keystring);
  357.             if (rmptr->rm_Action & (RXFF_RESULT))
  358.               rmptr->rm_Result2 = (long)CreateArgstring(keystring,
  359.                             (long)strlen(keystring));
  360.             break;
  361.           case 6:    /* STATUS  */
  362.             buildstatus();
  363.             if (rmptr->rm_Action & (RXFF_RESULT))
  364.               rmptr->rm_Result2 = (long)CreateArgstring(status,
  365.                             (long)strlen(status));
  366.             break;
  367.           case 7:    /* CONNECT */
  368.             if (*Token)  {
  369.               for (j=0; Token[j] != ' '; j++) {
  370.                 portname[j] = Token[j];
  371.                 }
  372.                 portname[j] = '\0';
  373.               nexttoken();
  374.               for (j=0; Token[j] != ' ' && Token[j]; j++) {
  375.                 command[j] = Token[j];
  376.                 }
  377.                 command[j] = '\0';
  378.               connected = 1;
  379.               }
  380.             else
  381.               connected = 0;
  382.             break;
  383.           case 8:    /* CTRL */
  384.             if (*Token)
  385.               strcpy(macroport, Token);
  386.             break;
  387.           case 9:    /* TITLE */
  388.             strcpy(titlestring, Token);
  389.             SetWindowTitles(mywindow, titlestring, 0L);
  390.             break;
  391.           case 10:    /* DIE */
  392.             KeepGoing = FALSE;
  393.             break;
  394.  
  395.           default:
  396.             rmptr->rm_Result1 = 5;           /* return code      */
  397.             break;
  398.           }
  399.         ReplyMsg(rmptr);                 /* send it back     */
  400.         }
  401.       }
  402.  
  403.     /*-----  Drain the keyboard buffer--------------*/
  404.  
  405.     keystring[0] = '\0';
  406.     keycount = 0;
  407.     while ( c = CheckKey() )
  408.       {
  409.       if (c != CSI)
  410.         {
  411.         keystring[keycount++] = c;
  412.         keystring[keycount] = '\0';
  413.         }
  414.       else    /* here if c == CSI */
  415.         {
  416.         character = GetKey();
  417.         if ( ('A' <= character) && (character <= 'D') );
  418.  
  419.         if ( ('0' <= character) && (character <= '9') ) {
  420.           sendfkey(character);
  421.           character = GetKey();
  422.           }
  423.  
  424.         if (character == '?') {
  425.           sendhelp();
  426.           }
  427.  
  428.         if  (((character  < 'A') || (character > 'D')) &&
  429.           ((character != 'T')
  430.           && (character != 'S')
  431.           && (character != '~')
  432.           && (character != ' ')))
  433.           while ( GetKey() != '~');
  434.  
  435.         if (character == ' ') {
  436.           GetKey();
  437.           }
  438.  
  439.         }    /* end if CSI */
  440.       }   /* end while CheckKey() */
  441.     if (keycount && connected) {
  442.       send_rexx_msg(portname, command, keystring);
  443.       }
  444.  
  445.      /* ---------------- Handle all Messages --------------------*/
  446.  
  447.     while( NewMessage=(struct IntuiMessage *)GetMsg(mywindow->UserPort) )
  448.       {
  449.       class = NewMessage->Class;
  450.       code = NewMessage->Code;
  451.       ReplyMsg( NewMessage );
  452.       switch( class )
  453.         {
  454.         case CLOSEWINDOW:
  455.           KeepGoing = FALSE;
  456.           break;
  457.         }      /* end of switch (class)    */
  458.       }        /* end of while ( newmessage )*/
  459.     
  460.     }          /* end while ( keepgoing )    */
  461.  
  462.   while (outstanding_rexx_commands)
  463.     {
  464.     printf("dispmod: Outstanding commands: %d\n",outstanding_rexx_commands );
  465.     if (( rmptr = (struct RexxMsg *) GetMsg(&RexxPort)) == NULL )
  466.       {
  467.       Wait( 1L << RexxPort.mp_SigBit );
  468.       rmptr = (struct RexxMsg *) GetMsg(&RexxPort);
  469.       }
  470.       if (rmptr) {
  471.       if( rmptr->rm_Node.mn_Node.ln_Type == NT_REPLYMSG ) {
  472.         free_rexx_command(rmptr);
  473.         }
  474.       else {
  475.         if (StrcmpN( rmptr->rm_Args[0], "REALLY_DIE", 10L) == NULL)
  476.           ReplyMsg(rmptr);
  477.         break;
  478.         }
  479.       }
  480.     }
  481.  
  482.   cleanup();
  483.   exit( 0 );
  484. } /* end of main */
  485.