/* Modified to work with Manx 3.4b; probably won't work with Lattice. Based on: */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* |_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 FILES * * * * * * * * * * * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "functions.h" /* * * * * * * * * * * CONSTANTS * * * * * * * * * * * * */ #define PORTNAME "Mackie.port" #define TIMEINTERVAL 1L /* in seconds */ #define DEFTIME 300 /* two minute timeout */ #define MAXCMD 200 #define DEFKEY 0x45 #define DEFCMD "NEWCLI >NIL: ie_NextEvent) { if ((ep->ie_Class == IECLASS_RAWKEY) && (ep->ie_Qualifier & IEQUALIFIER_LCOMMAND) && ((ep->ie_Code == gptr->key) || ((ep->ie_Qualifier & IEQUALIFIER_LSHIFT) && (ep->ie_Code & 128) == 0))) { if (ep->ie_Qualifier & IEQUALIFIER_LSHIFT) gptr->frontkey = key = ep->ie_Code ; else key = -1 ; /* we can handle this event so take it off the chain */ if (laste == NULL) ev = ep->ie_NextEvent; else laste->ie_NextEvent = ep->ie_NextEvent; /* now tell him to create the new cli */ if (key == -1) Signal(gptr->buddy, gptr->creatclisig); else Signal(gptr->buddy, gptr->frontsig); } else laste = ep; if (ep->ie_Class != IECLASS_TIMER) { gptr->noevents = 0; if (gptr->blankscreen != NULL) Signal(gptr->buddy, gptr->unblanksig); } } /* pass on the pointer to the event */ return(ev); } /* * * * * * * * * * * EXTERNAL ROUTINES * * * * * * * * * */ struct IntuitionBase *IntuitionBase; struct GfxBase *GfxBase; struct DosLibrary *DosBase; struct NewScreen NewScreen = { 0, 0, 320, 30, 1, 0, 1, NULL, CUSTOMSCREEN, NULL, NULL, NULL, NULL }; extern struct MsgPort *CreatePort(); struct IOStdReq *CreateIOReq(); void DeleteIOReq(); /************************************************************************/ /* Queue a timer to go off in a given number of seconds */ /************************************************************************/ void QueueTimer(tr,seconds) struct timerequest *tr; ULONG seconds; { tr->tr_node.io_Command = TR_ADDREQUEST; /* add a new timer request */ tr->tr_time.tv_secs = seconds; /* seconds */ tr->tr_time.tv_micro = 0; SendIO( (struct IORequest *)tr ); } /************************************************************************/ /* the main program to do the popcli stuff */ /************************************************************************/ GLOBAL_DATA global; main(argc, argv) int argc ; char *argv[] ; { struct MsgPort *port; int stay = 0; struct OURMSG *msg; char cmdstr[MAXCMD]; short key, timeout; struct FileHandle *nullfh = NULL ; ULONG sig, timersig; struct timerequest *timerreq; struct MsgPort *timerport; struct MsgPort *inputDevPort; struct IOStdReq *inputRequestBlock; struct Interrupt handlerStuff; char *cmd ; int draw = 0 ; _Backstdout = Output() ; SetTaskPri(FindTask(0L), 20L) ; global.creatsignum = -1; global.blanksignum = -1; global.replysignum = -1; global.frontsignum = -1; global.blankscreen = NULL; global.key = DEFKEY ; global.draw = 1 ; timerreq = NULL; timerport = NULL; inputDevPort = NULL; inputRequestBlock = NULL; /* now see if we are already installed */ if ((port = FindPort(PORTNAME)) == NULL) { stay = 1; /* remember to hang around when we are done */ /* not installed, we need to install our own port */ if ((port = CreatePort(PORTNAME,0L)) == NULL) goto abort; } /* now send the parameter to the waiting program */ if ((msg = (struct OURMSG *) AllocMem((long)sizeof(struct OURMSG), MEMF_CLEAR|MEMF_PUBLIC)) == NULL) goto abort; /* fill in the message information */ msg->msgpart.mn_Length = sizeof(struct OURMSG); strcpy(cmdstr, DEFCMD); timeout = 0 ; key = 0 ; msg->cmd[0] = 0; /* if we were run from CLI then output our banner and process parameters */ if (argc > 0) { /* display our copyright */ if (stay && _Backstdout) Write(_Backstdout, BANNER, (long)sizeof(BANNER)); if (argc == 1 && _Backstdout) Write(_Backstdout, USAGE, (long)sizeof(USAGE)); argc-- ; argv++ ; while (argc > 0) { cmd = argv[0] ; if (*cmd == '-') { cmd++ ; switch (*cmd) { case 'q' : case 'Q' : key = -1 ; if (_Backstdout) Write(_Backstdout, KILLMSG, (long)sizeof(KILLMSG)); break ; case 'l' : case 'L' : draw = 1 ; break ; case 'b' : case 'B' : draw = -1 ; break ; default : if (_Backstdout) Write(_Backstdout, PARAMMSG, (long)sizeof(PARAMMSG)); } } else if ('0' <= *cmd && *cmd <= '9') { timeout = 0; while ((*cmd >= '0') && (*cmd <= '9')) timeout = (timeout*10) + *cmd++ - '0'; if (timeout <= 0) timeout = DEFTIME; } else { strcpy(msg->cmd, cmd) ; } argc-- ; argv++ ; } } if (draw) global.draw = draw ; msg->interval = timeout; msg->key = key; msg->draw = draw ; PutMsg(port,(struct Message *)msg); if (!stay) goto abort; if (timeout == 0) timeout = DEFTIME ; global.blankscreen = NULL; global.buddy = FindTask(0L); global.noevents = 0; nullfh = Open("NIL:", MODE_NEWFILE); if (((inputDevPort = CreatePort(0L,0L)) == NULL) || ((inputRequestBlock = CreateIOReq(inputDevPort, (long)sizeof(struct IOStdReq))) == NULL) || ((timerport = CreatePort(0L,0L)) == NULL) || ((timerreq = (struct timerequest *) CreateIOReq(timerport, (long)sizeof(struct timerequest))) == NULL) || ((global.creatsignum = AllocSignal(-1L)) == -1) || ((global.blanksignum = AllocSignal(-1L)) == -1) || ((global.replysignum = AllocSignal(-1L)) == -1) || ((global.frontsignum = AllocSignal(-1L)) == -1) || ((GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0L)) == NULL) || ((IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0L)) == NULL) || OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)timerreq, 0L) || OpenDevice("input.device",0L,(struct IORequest *)inputRequestBlock,0L)) goto abort; handlerStuff.is_Data = (APTR)&global; handlerStuff.is_Code = HandlerInterface; handlerStuff.is_Node.ln_Pri = 51; timersig = (1L << timerport->mp_SigBit); global.creatclisig = 1L << global.creatsignum; global.unblanksig = 1L << global.blanksignum; global.frontsig = 1L << global.frontsignum; inputRequestBlock->io_Command = IND_ADDHANDLER; inputRequestBlock->io_Data = (APTR)&handlerStuff; DoIO((struct IORequest *)inputRequestBlock); QueueTimer(timerreq, TIMEINTERVAL); for(;;) { /* FOREVER */ sig = Wait( global.creatclisig | global.unblanksig | timersig | global.frontsig); /* see if they asked us to change the interval */ if ((msg = (struct OURMSG *)GetMsg(port)) != NULL) { if (msg->cmd[0]) strcpy(cmdstr, msg->cmd); if (msg->key) global.key = msg->key; if (msg->interval) timeout = msg->interval; if (msg->draw) global.draw = msg->draw ; FreeMem((char *)msg, (long)msg->msgpart.mn_Length); if (msg->key == -1) goto abort; } if ((sig & global.unblanksig) && global.blankscreen) screenunblank() ; if (sig & global.creatclisig) { WBenchToFront(); (void)Execute(cmdstr,nullfh,nullfh); } if ((sig & global.frontsig) && (key = global.frontkey)) { global.frontkey = 0 ; if ((16 <= key && key <= 25) || (32 <= key && key <= 40) || (49 <= key && key <= 55)) { key = "qwertyuiop......asdfghjkl........zxcvbnm"[key-16] ; /* * Now we have a key, so we have to find a process with that name and * bring her to front. */ } } if (sig & timersig) { /* get rid of the message */ (void)GetMsg(timerport); QueueTimer(timerreq, TIMEINTERVAL); if (task) SetTaskPri(task, 10L) ; if ((global.noevents++ >= timeout) && (global.blankscreen == NULL)) blankscreen() ; } } abort: if (timerreq != NULL) { if (timerreq->tr_node.io_Device != NULL) CloseDevice((struct IORequest *)timerreq); DeleteIOReq((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(inputRequestBlock); } screenunblank() ; if (timerport != NULL) DeletePort(timerport); if (global.creatsignum != -1) FreeSignal(global.creatsignum); if (global.blanksignum != -1) FreeSignal(global.blanksignum); if (global.replysignum != -1) FreeSignal(global.replysignum); if (global.frontsignum != -1) FreeSignal(global.frontsignum); if (IntuitionBase != NULL) CloseLibrary((struct Library *)IntuitionBase); if (GfxBase != NULL) CloseLibrary((struct Library *)GfxBase); if (inputDevPort != NULL) DeletePort(inputDevPort); if (stay && (port != NULL)) DeletePort(port); if (nullfh) Close(nullfh); SetTaskPri(FindTask(0L), 0L) ; } struct IOStdReq * CreateIOReq(port, size) struct MsgPort *port; long size; { struct IOStdReq *ioReq; if ((ioReq = (struct IOStdReq *) AllocMem(size, MEMF_CLEAR | MEMF_PUBLIC)) != NULL) { ioReq->io_Message.mn_Node.ln_Type = NT_MESSAGE; ioReq->io_Message.mn_Node.ln_Pri = 0; ioReq->io_Message.mn_Length = size; ioReq->io_Message.mn_ReplyPort = port; } return(ioReq); } void DeleteIOReq(ioReq) struct IOStdReq *ioReq; { ioReq->io_Message.mn_Node.ln_Type = 0xff; ioReq->io_Device = (struct Device *) -1; ioReq->io_Unit = (struct Unit *) -1; FreeMem( (char *)ioReq, (long)ioReq->io_Message.mn_Length); } /* * All of this stuff down here was written by Tomas Rokicki. * (C) Copyright 1987, Radical Eye Software. */ #include "graphics/gfxbase.h" /* * The maximum number of lines on the screen at once. */ #define MAXLINES (100) /* * The external variables we access. */ struct RastPort *rastport ; short screenheight, screenwidth ; /* * Some locals to this file. */ static struct NewScreen newscreen = { 0, 0, 640, 400, 1, 0, 1, HIRES | LACE | SCREENQUIET, CUSTOMSCREEN, NULL, NULL, NULL, NULL } ; /* * This routine opens a screen and fires off the task if apropriate. */ void taskrout() ; blankscreen() { screenheight = 2 * GfxBase->NormalDisplayRows ; screenwidth = GfxBase->NormalDisplayColumns ; newscreen.Height = screenheight ; newscreen.Width = screenwidth ; if (global.draw == -1 || AvailMem(MEMF_CHIP) < 70000L || (global.blankscreen = OpenScreen(&newscreen)) == NULL) { if ((global.blankscreen = OpenScreen(&NewScreen)) != NULL) { SetRGB4(&(global.blankscreen->ViewPort), 0L, 0L, 0L, 0L); OFF_DISPLAY ; } } else { if (global.blankscreen == NULL && (global.blankscreen = OpenScreen(&newscreen))==NULL) return ; /* * Turning off the sprites is a little bit tricky. A simple OFF_SPRITE * will continue to display the data in the current sprite registers. * This happens most often with the cursor. To fix, we simply clear out * the sprite control registers after turning the sprites off. This * might break all of the sprites when the system comes back up . . . */ OFF_SPRITE ; custom.spr[0].ctl = 0 ; custom.spr[1].ctl = 0 ; custom.spr[2].ctl = 0 ; custom.spr[3].ctl = 0 ; custom.spr[4].ctl = 0 ; custom.spr[5].ctl = 0 ; custom.spr[6].ctl = 0 ; custom.spr[7].ctl = 0 ; SetRGB4(&(global.blankscreen->ViewPort), 0L, 0L, 0L, 0L) ; rastport = &(global.blankscreen->RastPort) ; SetAPen(rastport, 0L) ; Forbid() ; RectFill(rastport, 0L, 0L, (long)screenwidth-1, 30L) ; Permit() ; SetAPen(rastport, 1L) ; task = (struct Task *)AllocMem((long)sizeof(struct Task), MEMF_CLEAR | MEMF_PUBLIC) ; if (task != NULL) { task->tc_Node.ln_Pri = 10 ; task->tc_Node.ln_Type = NT_TASK ; task->tc_Node.ln_Name = "ri.Lines" ; task->tc_SPLower = (APTR)stackmem ; task->tc_SPUpper = task->tc_SPReg = (APTR)(stackmem + STACKSIZE/4 - 8) ; AddTask(task, taskrout, 0L) ; } } } /* * Unblank the screen. We kill the task with the standard ^C kill signal. */ screenunblank() { if (task != NULL) { Signal(task, 1L << SIGBREAKB_CTRL_C) ; SetTaskPri(task, 11L) ; Wait(1L << global.replysignum) ; RemTask(task); FreeMem(task, (long)sizeof(struct Task)) ; task = NULL ; } if (global.blankscreen != NULL) { CloseScreen(global.blankscreen); global.blankscreen = NULL ; ON_DISPLAY ; ON_SPRITE ; } } /* * This routine returns a random value from 0 to n-1. */ int randm(i) int i ; { static long seed ; long rval ; if (seed == 0) seed = 323214521 + global.blankscreen->MouseX + global.blankscreen->MouseY ; seed = seed * 123213 + 121 ; rval = (seed >> 5) & 65535 ; return ((i * rval) >> 16) ; } /* * This routine sets x and y values to a random number. */ static long x, y ; randomxy() { x = randm(screenwidth) ; y = randm(screenheight) ; } /* * Main routines are always fun. */ short x1store[MAXLINES], y1store[MAXLINES] ; short x2store[MAXLINES], y2store[MAXLINES] ; short ptr ; short dx1, dy1, dx2, dy2 ; short ox1, oy1, ox2, oy2 ; short nx1, ny1, nx2, ny2 ; short dr, dg, db ; short or, og, ob ; short nr, ng, nb ; /* * Initialize things for the first lines. */ startlines() { ptr = 0 ; if (dx1 == 0) { ox1 = randm(screenwidth) ; ox2 = randm(screenwidth) ; oy1 = randm(screenheight) ; oy2 = randm(screenheight) ; dx1 = 3 ; dx2 = 4 ; dy1 = 1 ; dy2 = 6 ; nr = 53 ; ng = 33 ; nb = 35 ; dr = -3 ; dg = 5 ; db = 7 ; } SetRGB4(&(global.blankscreen->ViewPort), 0L, 0L, 0L, 0L) ; SetRGB4(&(global.blankscreen->ViewPort), 1L, (long)(nr >> 3), (long)(ng >> 3), (long)(nb >> 3)) ; } /* * Advance the number by the delta, and check the boundaries. */ adv(o, d, n, w) short *o, *d, *n ; short w ; { *n = *o + *d ; if (*n < 0) { *n = 0 ; *d = randm(6) + 1 ; } else if (*n >= w) { *n = w - 1 ; *d = - randm(6) - 1 ; } } /* * Advance the two points which make up the lines. */ advancelines() { adv(&ox1, &dx1, &nx1, screenwidth) ; adv(&ox2, &dx2, &nx2, screenwidth) ; adv(&oy1, &dy1, &ny1, screenheight) ; adv(&oy2, &dy2, &ny2, screenheight) ; } /* * Draw a new set of lines. */ drawnew() { x1store[ptr] = ox1 = nx1 ; x2store[ptr] = ox2 = nx2 ; y1store[ptr] = oy1 = ny1 ; y2store[ptr] = oy2 = ny2 ; Move(rastport, (long)ox1, (long)oy1) ; Draw(rastport, (long)ox2, (long)oy2) ; Draw(rastport, (long)(screenwidth-ox1-1), (long)(screenheight-oy1-1)) ; Draw(rastport, (long)(screenwidth-ox2-1), (long)(screenheight-oy2-1)) ; Draw(rastport, (long)ox1, (long)oy1) ; ptr++ ; if (ptr == MAXLINES) ptr = 0 ; } /* * Erase the old line. */ eraseold() { short oldpen ; oldpen = rastport->FgPen ; SetAPen(rastport, 0L) ; Move(rastport, (long)x1store[ptr], (long)y1store[ptr]) ; Draw(rastport, (long)x2store[ptr], (long)y2store[ptr]) ; Draw(rastport, (long)(screenwidth-x1store[ptr]-1), (long)(screenheight-y1store[ptr]-1)) ; Draw(rastport, (long)(screenwidth-x2store[ptr]-1), (long)(screenheight-y2store[ptr]-1)) ; Draw(rastport, (long)x1store[ptr], (long)y1store[ptr]) ; SetAPen(rastport, (long)oldpen) ; } /* * This routine mucks with the colors. */ colors() { or = nr ; og = ng ; ob = nb ; adv(&or, &dr, &nr, 128) ; adv(&og, &dg, &ng, 128) ; adv(&ob, &db, &nb, 128) ; SetRGB4(&(global.blankscreen->ViewPort), 1L, (long)(nr >> 3), (long)(ng >> 3), (long)(nb >> 3)) ; } /* * Our actual task, in an infinite loop. */ void taskrout() { long i ; struct Task *task ; geta4() ; task = FindTask(0L) ; startlines() ; for (i=0; itc_Node.ln_Pri == 10) SetTaskPri(task, -20L) ; eraseold() ; advancelines() ; drawnew() ; eraseold() ; advancelines() ; drawnew() ; if (task->tc_Node.ln_Pri == 10) SetTaskPri(task, -20L) ; eraseold() ; advancelines() ; drawnew() ; eraseold() ; advancelines() ; drawnew() ; if (task->tc_Node.ln_Pri == 10) SetTaskPri(task, -20L) ; eraseold() ; advancelines() ; drawnew() ; eraseold() ; advancelines() ; drawnew() ; colors() ; } done: Signal(global.buddy, 1L << global.replysignum) ; Wait(0L) ; }