/**************************** * dispmod.c * Display module for ROBBS. *****************************/ #include #include #include #include #include #include #include #include #include #include "ConsoleIO.h" #include "Rexx.h" #include "defs.h" char portname[17] = "ROBBS_ctrl"; char macroport[17] = "ROBBS_ctrl"; char command[10] = "SEND"; char keystring[255]; char status[100]; char normaltext[] = "\x9Bm"; char redtext[] = "\x9B33m"; UBYTE titlestring[77] = VERSION; STRPTR Token; int connected; int outstanding_rexx_commands = 0; int CRPending = 0; struct RexxLib *RexxSysBase; struct MsgPort RexxPort; struct RexxMsg *rmptr, *OutMsg, *CreateRexxMsg(); BOOL KeepGoing = TRUE; void FreePort(); char nexttoken(); STRPTR CreateArgstring(); struct IntuitionBase *IntuitionBase = NULL; static struct IOStdReq *Console = NULL; /* see "ConsoleIO.h" */ static struct Window *mywindow = NULL; /* ptr to applications window */ static struct IntuiMessage *NewMessage; /* msg structure for GetMsg() */ static struct IOStdReq *rd = NULL, *wr = NULL; static char *validargs[] = { "TEXT", /* 0 */ "LTEXT", /* 1 */ "HTEXT", /* 2 highlighted text, one colour only for now */ "LHTEXT", /* 3 same, with linefeed appended */ "CRSR", /* 4 cursor row, column */ "GETLINE", /* 5 getline [prompt] */ "STATUS", /* 6 */ "CONNECT", /* 7 */ "CTRL", /* 8 */ "TITLE", /* 9 */ "DIE", /* 10 */ NULL }; static int numcmds = 11; /* my window structure */ static struct NewWindow NewWindow = { 0,0,640,200, /* left, top, width, height */ 0,1, /* detail, block pens */ CLOSEWINDOW | GADGETUP, WINDOWCLOSE | SMART_REFRESH | ACTIVATE | WINDOWDEPTH | BORDERLESS , NULL, /* firstgadget */ NULL, /* checkmark */ titlestring, /* title */ 0, /* screen */ NULL, /* bitmap */ 0,0, /* min x,y */ 640, 200, /* max x,y */ WBENCHSCREEN /* type */ }; /*--------------------------------------------------------------*/ /* cleanup: all done so close up and prepare to exit */ /*--------------------------------------------------------------*/ static void cleanup() { if (RexxSysBase != NULL) { RemPort(&RexxPort); /* unlink it */ FreePort(&RexxPort); /* release the port resources */ CloseLibrary(RexxSysBase); } if ( mywindow != NULL ) CloseWindow( mywindow ); if ( Console != NULL ) CloseConsoleIO(); if ( IntuitionBase != NULL ) CloseLibrary(IntuitionBase); } /*-------------------------------------------------------*/ /* init: initialize dispmod - set defaults */ /*-------------------------------------------------------*/ static void init() { IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", INTUITION_REV); if( IntuitionBase == NULL ) { puts("can't open intuition\n"); goto badopen; } if(( mywindow = OpenWindow(&NewWindow) ) == NULL) { puts("Can't open a window.\n"); goto badopen; } if(( Console = InitConsoleIO( mywindow, &rd, &wr ) ) == NULL) { puts("Can't open the console.\n"); goto badopen; } RexxSysBase = (struct RexxLib *)OpenLibrary("rexxsyslib.library",0L); if (RexxSysBase == NULL) { printf("Can't open rexxsyslib.library.\n"); goto badopen; } InitPort(&RexxPort,"ROBBS_disp"); /* Initialize our message port */ AddPort(&RexxPort); /* Make the port public */ return; badopen: cleanup(); exit( 4 ); } /*--------------------------------------------------------------*/ /* buildstatus: build status string from variables */ /*--------------------------------------------------------------*/ void buildstatus() { int j; sprintf(status, "%s %s %lx %lx",portname, macroport, mywindow, wr); } /*-----------------------------------------------------------------*/ /* send_rexx_msg: send a message to a port */ /*-----------------------------------------------------------------*/ send_rexx_msg(port, cmd, s) char *port; char *cmd; char *s; { struct MsgPort *localport; /* RexxPort is reply port. look for reply there */ OutMsg = CreateRexxMsg(&RexxPort, "dccs", "DCCS" ); if (OutMsg != NULL) { OutMsg->rm_Args[0] = CreateArgstring( cmd, (long) strlen( cmd )); OutMsg->rm_Args[1] = CreateArgstring( s, (long) strlen( s )); OutMsg->rm_Action = RXFUNC | 1; /* FillRexxMsg(OutMsg, 1L, 0L); */ Forbid(); localport = FindPort(port); if (localport != 0) PutMsg(localport, OutMsg); Permit(); }; outstanding_rexx_commands++; return(0); /* ya, I know, I need error checking. */ } /*-----------------------------------------------------------------*/ /* free_rexx_command: free the message we sent and decrement count */ /*-----------------------------------------------------------------*/ free_rexx_command(rexxmsg) register struct RexxMsg *rexxmsg; { /* delete the argument that we originally sent */ DeleteArgstring(rexxmsg->rm_Args[0]); DeleteArgstring(rexxmsg->rm_Args[1]); /* delete the extended message */ DeleteRexxMsg(rexxmsg); /* decrement the count of outstanding messages */ outstanding_rexx_commands--; } /*-----------------------------------------------------------------*/ /* sendfkey(number): inform of function key usage */ /*-----------------------------------------------------------------*/ sendfkey( num ) short num; { char message[8]; sprintf( message, "%c", num ); send_rexx_msg(macroport, "FKEY", message); } /*-----------------------------------------------------------------*/ /* sendhelp(number): inform of HELP key usage */ /*-----------------------------------------------------------------*/ sendhelp() { send_rexx_msg(macroport, "HELP", NULL); } /*-----------------------------------------------------------------*/ /* nexttoken(): search for next space or NULL in token string */ /*-----------------------------------------------------------------*/ char nexttoken() { for ( ;(*Token != ' ' && *Token != '\0'); Token++ ); if (*Token == ' ') { Token++; return(' '); } else return('\0'); } /*-----------------------------------------------------------------*/ /* cr2lf(s): convert all instances of CR in string s to linefeeds */ /* : leave cr/lf combination alone */ /*-----------------------------------------------------------------*/ cr2lf ( s ) char *s; { if ( CRPending ) if ( *s != '\n' ) PutString("\n"); CRPending = 0; for (; *s; s++) { if ( (*s == '\r') && (*(s+1) != '\n') ) if ( *(s+1) = '\0' ) CRPending = 1; else *s = '\n'; } } /******************************************************/ /* Main Program */ /* */ /* This is the main body of the program. */ /******************************************************/ main() { ULONG class, waitmask; int c, i, j, x, y, code, keycount ; UBYTE character; init(); waitmask = (1L << mywindow->UserPort->mp_SigBit) | (1L << Console->io_Message.mn_ReplyPort->mp_SigBit) | (1L << RexxPort.mp_SigBit); KeepGoing = TRUE; while( KeepGoing ) { if (( rmptr = (struct RexxMsg *) GetMsg(&RexxPort)) == NULL ) { Wait( waitmask ); rmptr = (struct RexxMsg *) GetMsg(&RexxPort); } if (rmptr) { if (rmptr->rm_Node.mn_Node.ln_Type == NT_REPLYMSG ) free_rexx_command(rmptr); else { Token = rmptr->rm_Args[0]; for (i=0; i < numcmds; i++) if ( StrcmpN(rmptr->rm_Args[0], validargs[i], 3L) == NULL) break; if (rmptr->rm_Action & 15L) { Token = rmptr->rm_Args[1]; } else { nexttoken(); } /* Set 'normal result codes'. these are set here, */ /* and only changed in case of error or when */ /* returning a result string (as in STATUS). */ rmptr->rm_Result1 = 0; /* return code */ rmptr->rm_Result2 = 0; /* secondary result */ switch (i) { case 0: /* TEXT */ case 1: /* LTEXT */ /* cr2lf(Token); */ PutString(normaltext); PutString(Token); if (i == 1) PutString("\n"); break; case 2: /* HTEXT */ case 3: /* LHTEXT */ /* cr2lf(Token); */ PutString(redtext); PutString(Token); PutString(normaltext); if (i == 3) PutString("\n"); break; case 4: /* CURSOR */ for (j=0; Token[j] != ' '; j++); Token[j] = '\0'; j++; y = atoi(Token); x = atoi(&Token[j]); CursorXY(x,y); break; case 5: /* GETLINE */ if (*Token) GetLine(Token, keystring); else GetLine(NULL, keystring); if (rmptr->rm_Action & (RXFF_RESULT)) rmptr->rm_Result2 = (long)CreateArgstring(keystring, (long)strlen(keystring)); break; case 6: /* STATUS */ buildstatus(); if (rmptr->rm_Action & (RXFF_RESULT)) rmptr->rm_Result2 = (long)CreateArgstring(status, (long)strlen(status)); break; case 7: /* CONNECT */ if (*Token) { for (j=0; Token[j] != ' '; j++) { portname[j] = Token[j]; } portname[j] = '\0'; nexttoken(); for (j=0; Token[j] != ' ' && Token[j]; j++) { command[j] = Token[j]; } command[j] = '\0'; connected = 1; } else connected = 0; break; case 8: /* CTRL */ if (*Token) strcpy(macroport, Token); break; case 9: /* TITLE */ strcpy(titlestring, Token); SetWindowTitles(mywindow, titlestring, 0L); break; case 10: /* DIE */ KeepGoing = FALSE; break; default: rmptr->rm_Result1 = 5; /* return code */ break; } ReplyMsg(rmptr); /* send it back */ } } /*----- Drain the keyboard buffer--------------*/ keystring[0] = '\0'; keycount = 0; while ( c = CheckKey() ) { if (c != CSI) { keystring[keycount++] = c; keystring[keycount] = '\0'; } else /* here if c == CSI */ { character = GetKey(); if ( ('A' <= character) && (character <= 'D') ); if ( ('0' <= character) && (character <= '9') ) { sendfkey(character); character = GetKey(); } if (character == '?') { sendhelp(); } if (((character < 'A') || (character > 'D')) && ((character != 'T') && (character != 'S') && (character != '~') && (character != ' '))) while ( GetKey() != '~'); if (character == ' ') { GetKey(); } } /* end if CSI */ } /* end while CheckKey() */ if (keycount && connected) { send_rexx_msg(portname, command, keystring); } /* ---------------- Handle all Messages --------------------*/ while( NewMessage=(struct IntuiMessage *)GetMsg(mywindow->UserPort) ) { class = NewMessage->Class; code = NewMessage->Code; ReplyMsg( NewMessage ); switch( class ) { case CLOSEWINDOW: KeepGoing = FALSE; break; } /* end of switch (class) */ } /* end of while ( newmessage )*/ } /* end while ( keepgoing ) */ while (outstanding_rexx_commands) { printf("dispmod: Outstanding commands: %d\n",outstanding_rexx_commands ); if (( rmptr = (struct RexxMsg *) GetMsg(&RexxPort)) == NULL ) { Wait( 1L << RexxPort.mp_SigBit ); rmptr = (struct RexxMsg *) GetMsg(&RexxPort); } if (rmptr) { if( rmptr->rm_Node.mn_Node.ln_Type == NT_REPLYMSG ) { free_rexx_command(rmptr); } else { if (StrcmpN( rmptr->rm_Args[0], "REALLY_DIE", 10L) == NULL) ReplyMsg(rmptr); break; } } } cleanup(); exit( 0 ); } /* end of main */