home *** CD-ROM | disk | FTP | other *** search
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- /* |_o_o|\\ Copyright (c) 1986 The Software Distillery. All Rights Reserved */
- /* |. o.| || This program may not be distributed without the permission of */
- /* | . | || the authors. */
- /* | o | || Dave Baker Ed Burnette Stan Chow Jay Denebeim */
- /* | . |// Gordon Keener Jack Rouse John Toebes Doug Walker */
- /* ====== BBS:(919)-471-6436 VOICE:(919)-469-4210 */
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- /*
- * VERY loosely based on the input.device example by Rob Peck, 12/1/85
- */
-
- #include "popcli.h"
- #include "popbug.h"
- #include "cback.h"
-
-
- #ifdef BUGMACROS
- #define __BugWindow (*(BPTR *)"BUG") /* 4 bytes, big enuf for a BPTR */
- #endif
-
- /************************************************************************/
- /* the main program to do the popcli stuff */
- /************************************************************************/
-
- #undef global /* Since it really is local in this routine */
-
- void _main()
- {
- struct cbackstr *cback;
-
- struct MsgPort *port;
- int stay = 0;
- int shutdown;
- short timeout;
- struct OURMSG *msg;
- register CommandBlock *cb;
- int key;
- struct Process *us;
- #ifdef BUGMACROS
- BPTR bugwindow;
- #endif
-
- BPTR nullfh;
- ULONG sig, portsig, timersig;
- struct timerequest *timerreq;
- struct MsgPort *timerport;
- struct MsgPort *inputDevPort;
- struct IOStdReq *inputRequestBlock;
- struct Interrupt handlerStuff;
- GLOBAL_DATA global;
- struct Process *SyncProcess;
- int SyncSignal;
- char *cmd;
- int cmdlen;
- struct RexxMsg *amsg;
- struct OURMSG pmsg; /* for AREXX message parsing */
-
- int rc;
-
- memset( (char *)&global, 0, sizeof(global) );
-
- DOSBase = (struct DosBase *)OpenLibrary("dos.library",0);
-
- global.blanksignum = -1;
- timerreq = NULL;
- timerport = NULL;
- inputDevPort = NULL;
- inputRequestBlock = NULL;
- msg = NULL;
-
- timeout = DEFTIME;
-
- /* Fetch our arguments from the wild blue yonder */
- us = (struct Process *)FindTask(0);
- us->pr_ConsoleTask = NULL;
- WaitPort( &(us->pr_MsgPort) );
- cback = (struct cbackstr *)GetMsg( &(us->pr_MsgPort) );
-
- global.stdout = cback->stdout;
-
- /* now see if we are already installed */
- if ((port = FindPort(PORTNAME)) == NULL)
- {
- stay = 1; /* remember to hang around when we are done */
- #ifdef BUGMACROS
- bugwindow = Open(BUGWINDOW,MODE_NEWFILE);
- memcpy( "BUG", (char *)&bugwindow, 4 );/* __BugWindow = bugwindow; */
- #endif
- BUG(("Setting stay to 1 - first time here\n"));
-
- /* not installed, we need to install our own port */
- if ((port = MyCreatePort(&global, PORTNAME)) == NULL)
- goto abort;
-
- /* Tell everybody we're here... */
- popbanner( &global );
- }
- #ifdef BUGMACROS
- else
- {
- memcpy( "BUG", (char *)&global.stdout, 4 );
- }
- #endif
-
- /* Bit of a kludge... remove the trailing "\n" so we don't have to */
- /* muck with it in popparse(). Put a null on, too; and we can't */
- /* overwrite because there may not be enough room. */
- cmdlen = cback->cmdlen;
- cmd = AllocMem( cmdlen + 1, 0 );
- memcpy( cmd, cback->cmd, cmdlen );
-
- if (cmd[cmdlen-1] == '\n')
- cmd[cmdlen-1] = '\0';
- else
- cmd[cmdlen] = '\0';
-
- SyncProcess = cback->SyncProcess;
- SyncSignal = cback->SyncSignal;
-
- FreeMem( (char *)cback, cback->msgpart.mn_Length );
-
- /* Save port for handler to use */
- global.execport = port;
-
- /* now send the parameter to the waiting program */
- if ((msg = (struct OURMSG *)
- AllocMem(sizeof(struct OURMSG), MEMF_CLEAR|MEMF_PUBLIC)) == NULL)
- goto abort;
- /* fill in the message information */
- msg->msgpart.mn_Length = sizeof(struct OURMSG);
-
- BUG(("Command to parse: `%s'\n", cmd));
- rc = popparse( &global, cmd, msg );
-
- /* We're done with the command line */
- FreeMem( cmd, cmdlen+1 );
-
- if (rc == SHUTDOWN)
- {
- /* Print shutting down message */
- poptrailer( &global );
- }
-
- /* Get stack size and stuff from our parent, if we're the server */
- if (stay)
- copyproc( &global, us, SyncProcess );
-
- /* Let the original window go away */
- if (global.stdout)
- Close(global.stdout);
- global.stdout = 0;
-
- /* We got everything, so it's safe to let the parent go away */
- if (SyncSignal != -1)
- {
- Signal((struct Task *)SyncProcess, 1<<SyncSignal);
- SyncSignal = -1;
- }
-
- global.blankscreen = NULL;
- if (stay && msg->interval == 0)
- msg->interval = DEFTIME;
-
- BUG(("MSG TO SEND:\n"));
- BUG((" Type = %d\n", msg->type));
- BUG((" Key = %d\n", msg->key));
- BUG((" Interval = %d\n", msg->interval));
- BUG((" minmem = %d\n", msg->minmem << 10));
- BUG((" minchip = %d\n", msg->minchip << 10));
- BUG((" CmdFlags = %02X\n", msg->cmdflags));
- BUG((" Command = `%s'\n", msg->command));
-
-
- PutMsg(port,(struct Message *)msg);
-
- msg = NULL;
-
- /* If we're told to go away */
- if ((rc == SHUTDOWN) || (rc == LEAVE) || !stay)
- {
- goto abort;
- }
-
- global.noevents = 0;
-
- /* set the input and output streams to 0 so execute doen't complain */
- nullfh = Open("NIL:", MODE_NEWFILE);
-
- if (((inputDevPort = MyCreatePort(&global,NULL)) == NULL) ||
-
- ((inputRequestBlock =
- CreateIOReq(&global, inputDevPort, sizeof(struct IOStdReq))) == NULL) ||
-
- ((timerport = MyCreatePort(&global,NULL)) == NULL) ||
-
- ((timerreq = (struct timerequest *)
- CreateIOReq(&global,timerport, sizeof(struct timerequest))) == NULL) ||
-
- ((global.blanksignum = AllocSignal(-1)) == -1) ||
-
- ((GfxBase = (GBasePtr)
- OpenLibrary("graphics.library", 0)) == NULL) ||
-
- ((IntuitionBase = (IBasePtr)
- OpenLibrary("intuition.library", 0)) == NULL) ||
- OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)timerreq, 0) ||
-
- OpenDevice("input.device",0,(struct IORequest *)inputRequestBlock,0))
-
- goto abort;
-
- handlerStuff.is_Data = (APTR)&global;
- handlerStuff.is_Code = (VOID(*)())myhandler;
- handlerStuff.is_Node.ln_Pri = 51;
-
- timersig = (1 << timerport->mp_SigBit);
- portsig = (1 << port->mp_SigBit);
- global.unblanksig = 1 << global.blanksignum;
-
- inputRequestBlock->io_Command = IND_ADDHANDLER;
- inputRequestBlock->io_Data = (APTR)&handlerStuff;
-
- DoIO((struct IORequest *)inputRequestBlock);
-
- global.buddy = (struct Task *)us;
-
- QueueTimer(&global, timerreq, TIMEINTERVAL);
-
- /* All other fields in newscreen are 0 */
- global.newscreen.Width = 320;
- global.newscreen.Height = 30;
- global.newscreen.Depth = 1;
- global.newscreen.BlockPen = 1;
- global.newscreen.Type = CUSTOMSCREEN;
-
- shutdown = 0;
- while(!shutdown)
- {
- sig = Wait( portsig | global.unblanksig | timersig );
-
- /* see if we have anything to do */
- while ((msg = (struct OURMSG *)GetMsg(port)) != NULL)
- {
- if ((msg->msgpart.mn_Node.ln_Name) &&
- !strcmp(msg->msgpart.mn_Node.ln_Name, "REXX"))
- {
- /* we've got an ARexx message to parse. */
- amsg = (struct RexxMsg *)msg;
- BUG(("AREXX!! Command = `%s'\n", amsg->rm_Args[0]));
-
- rc = popparse( &global, amsg->rm_Args[0], &pmsg );
- amsg->rm_Result1 = (rc == LEAVE) ? 5 : 0;
- amsg->rm_Result2 = 0;
- ReplyMsg( (struct Message *)amsg );
-
- /* So our normal msg processing code can handle it */
- msg = &pmsg;
- }
- else
- amsg = NULL;
-
- /* See which type of message we have */
- switch( msg->type ) {
-
- /*----------------------------------------------------*/
- case MSG_ADDKEY:
- BUG(("*Add Key %d\n", msg->key));
-
- /* Because of parsing, we stick the interval information */
- /* in with the MSG_ADDKEY. There should be a better way */
- /* to do this. */
- if (msg->interval)
- {
- timeout = msg->interval;
- BUG((" Interval == %d ticks\n", timeout));
- }
-
- /* If we already have defined this key, then we can */
- /* update its command, else add the key. */
- cb = global.keytab[msg->key];
-
- if (!cb)
- {
- /* Its not there, we need to add the key */
- if (cb = (CommandBlock *)
- AllocMem(sizeof(CommandBlock),MEMF_PUBLIC))
- {
-
- /* Give new key the default command, if message has */
- /* no command. */
- if (msg->command[0] == '\0')
- strcpy(cb->command, DEFCMD);
-
- BUG((" creating <%d> at 0x%08lx\n", msg->key, (long)cb));
- }
- else
- BUG((" !!!! Can't alloc command block!!!\n"));
-
- global.keytab[msg->key] = cb;
- }
-
- /* Update the key command, for new or old key */
- if (cb)
- {
- cb->minmem = msg->minmem;
- cb->minchip = msg->minchip;
- cb->cmdflags = msg->cmdflags;
-
- if (cb && msg->command[0])
- {
- strcpy(cb->command, msg->command);
- }
-
- BUG((" New command = `%s'\n", cb->command));
- }
-
- break;
-
- /*----------------------------------------------------*/
- case MSG_DELKEY:
- BUG(("*Delete Key %d\n", msg->key));
-
- cb = global.keytab[msg->key];
- if (cb)
- {
- BUG((" killing <%d> at 0x%08lx\n", msg->key, (long)cb));
-
- global.keytab[msg->key] = NULL;
- FreeMem( (char *)cb, sizeof(CommandBlock) );
- }
- break;
-
- /*----------------------------------------------------*/
- case MSG_EXECUTE:
- BUG(("*Execute for key %d\n", msg->key));
- cb = global.keytab[msg->key];
-
- if (cb)
- {
- BUG((" Executing `%s'\n", cb->command));
-
- if (cb->minmem)
- {
- BUG(("Public memory: REQ: %8d, AVAIL: %8d\n",
- cb->minmem << 10,
- AvailMem(MEMF_PUBLIC)));
- }
-
- if (cb->minchip)
- {
- BUG(("Chip memory: REQ: %7d, AVAIL: %7d\n",
- cb->minchip << 10,
- AvailMem(MEMF_CHIP)));
- }
-
- if (((cb->minmem == 0) ||
- ((AvailMem(MEMF_PUBLIC)>>10) >= cb->minmem )) &&
- ((cb->minchip == 0) ||
- ((AvailMem(MEMF_CHIP )>>10) >= cb->minchip)))
- {
- if (!(cb->cmdflags & FLAG_NOWB2F))
- WBenchToFront();
-
- if (! Execute(cb->command, nullfh, nullfh))
- DisplayBeep(NULL);
- }
- else
- DisplayBeep(NULL);
- }
- break;
-
- /*----------------------------------------------------*/
- case MSG_SHUTDOWN:
- BUG(("*Quit: Shut UP!!\n"));
-
- /* Cause us to drop out of loop when we're thru */
- shutdown = 1;
- break;
-
- /*----------------------------------------------------*/
- case MSG_BLANK:
- BUG(("*BLANK it out!\n"));
- if (global.blankscreen == NULL)
- {
- if ( (global.blankscreen = OpenScreen(&global.newscreen)) != NULL)
- {
- BUG(("Screen OFF!!!!!\n"));
- SetRGB4(&(global.blankscreen->ViewPort), 0, 0, 0, 0);
- OFF_DISPLAY
- }
- }
- break;
-
- /*----------------------------------------------------*/
- case MSG_UNBLANK:
- BUG(("*UNBLANK it back!\n"));
- if (global.blankscreen)
- {
- CloseScreen(global.blankscreen);
- ON_DISPLAY
- global.blankscreen = NULL;
- global.noevents = 0;
- }
- break;
-
- /*----------------------------------------------------*/
- case MSG_SETTIME:
- BUG(("*Timeout set to %d\n", msg->interval));
- timeout = msg->interval;
- break;
-
- /*----------------------------------------------------*/
- default:
- BUG(("HEY, I got an unknown message at %08lx!!!!!\n", msg));
- }
-
- if (!amsg)
- FreeMem((char *)msg, msg->msgpart.mn_Length);
- }
-
- if ((sig & global.unblanksig) && global.blankscreen)
- {
- BUG(("Screen On\n"));
-
- CloseScreen(global.blankscreen);
- ON_DISPLAY
- global.blankscreen = NULL;
- }
-
- if (sig & timersig)
- {
- /* get rid of the message */
- (void)GetMsg(timerport);
- QueueTimer(&global, timerreq, TIMEINTERVAL);
-
- if ((global.noevents++ >= timeout) && (global.blankscreen == NULL))
- {
- if ( (global.blankscreen = OpenScreen(&global.newscreen)) != NULL)
- {
- BUG(("Screen OFF!!!!!\n"));
- SetRGB4(&(global.blankscreen->ViewPort), 0, 0, 0, 0);
- OFF_DISPLAY
- }
- }
- }
-
- /* Force our screen to front on a regular basis to handle something */
- /* that might put their stuff in front of us while we are supposed to */
- /* Be blanking the screen. */
- if (global.blankscreen)
- {
- BUG(("Screen still off\n"));
- #if 1
- if (((IBasePtr)IntuitionBase)->FirstScreen != global.blankscreen)
- ScreenToFront(global.blankscreen);
- #endif
- OFF_DISPLAY
- }
- }
-
- BUG(("Normal POPCLI shutdown beginning...\n"));
-
- abort:
-
- if (stay)
- BUG(("At `abort'...\n"));
-
- if (msg) FreeMem((char *)msg, msg->msgpart.mn_Length);
- if (timerreq != NULL)
- {
- if (timerreq->tr_node.io_Device != NULL)
- {
- AbortIO( (struct IORequest *)timerreq );
- CloseDevice((struct IORequest *)timerreq);
- }
- DeleteIOReq(&global, (struct IOStdReq *)timerreq);
- }
-
- if (inputRequestBlock != NULL)
- {
- if (inputRequestBlock->io_Device != NULL)
- {
- inputRequestBlock->io_Command = IND_REMHANDLER;
- inputRequestBlock->io_Data = (APTR)&handlerStuff;
- DoIO((struct IORequest *)inputRequestBlock);
-
- CloseDevice((struct IORequest *)inputRequestBlock);
- }
- DeleteIOReq(&global, inputRequestBlock);
- }
-
- if (timerport != NULL) MyDeletePort(&global, timerport);
- if (global.blanksignum != -1) FreeSignal(global.blanksignum);
- if (global.blankscreen != NULL) CloseScreen(global.blankscreen);
- if (IntuitionBase != NULL) CloseLibrary((struct Library *)IntuitionBase);
- if (GfxBase != NULL) CloseLibrary((struct Library *)GfxBase);
- if (inputDevPort != NULL) MyDeletePort(&global, inputDevPort);
- if (stay && (port != NULL))
- {
- /* Empty the port before we trash it */
- while (msg = (struct OURMSG *)GetMsg(port)) /* assign */
- FreeMem( (char *)msg, msg->msgpart.mn_Length );
-
- MyDeletePort(&global, port);
- BUG(("Port gone...\n"));
- }
-
- if (global.stdout)
- Close(global.stdout);
- if (SyncSignal != -1)
- Signal((struct Task *)SyncProcess, 1<<SyncSignal);
-
- if (stay)
- {
- /* NOTE: "prev" is really used as a "next" here */
- for (key = 0; key < 256; key++)
- {
- if (cb = global.keytab[key])
- {
- BUG(("Deleting key <%d> at 0x%08lx\n", key, cb));
-
- FreeMem( (char *)cb, sizeof(CommandBlock) );
- }
- }
- }
-
- if (nullfh) Close(nullfh);
-
- #ifdef BUGMACROS
- if (stay)
- {
- int paws = 1000000;
-
- BUG(("..bye bye"));
- while(--paws>0);
- Close(__BugWindow);
- }
- #endif
-
- /* Free all our copyproc() stuff, if we were the server */
- if (stay)
- termproc( &global, (struct Process *)FindTask(NULL) );
-
- if (DOSBase)
- CloseLibrary( (struct Library *)DOSBase );
- }
-
- #ifdef BUGMACROS
- #undef DOSBase
-
- void __stdargs myprintf(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
- char *fmt;
- long a1, a2, a3, a4, a5, a6, a7, a8, a9;
- {
- int bytes;
- char buff[512];
- struct DosLibrary *DOSBase;
-
- if (__BugWindow <= 0) return(0);
-
- bytes = sprintf(buff, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
-
- DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",0);
-
- if (bytes < sizeof(buff))
- Write(__BugWindow, buff, bytes);
- else
- Write(__BugWindow, "!!! msg too big - prepare to die\n",
- strlen("!!! msg too big - prepare to die\n"));
-
- CloseLibrary( (struct Library *)DOSBase );
- return(0);
- }
- #endif
-
-