/************************************************************************* *** win.c (JJB TEMPLAR) *** *** Date begun: 8/8/89. *** *** Last modified: 26/8/89. *** *************************************************************************/ /*** Intuition/Console device stuff for ty. These functions are *** *** currently used by io.c, ttyin.c, and output.c. *** *** Most of the console code is lifted directly from the chapter on *** *** the console.device in the RKM:L&D. *** *** Too easy to use IDCMP rather than console for input, so console *** *** input has been dropped. At the moment, this means multi-char *** *** commands have also been dropped. *** *************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include "cmd.h" #include "gadg.h" #define SHIFT (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT) #define CONTROL (IEQUALIFIER_CONTROL) #define MAXHORIZ 60 /* Max value for l_start */ extern char version[],sc_lower_left[]; extern struct Gadget *fgadg; extern int tty; /* Use as flag that cons is open */ extern int sc_width,sc_height; /* Resize them here. */ extern int l_start; /* Change this one here too. */ extern int has_resized; /* Set if getc() notices NEWSIZE */ extern int maxim; extern BPTR file; extern struct cmdmap uraw[]; extern struct cmdmap lraw[]; extern struct cmdmap lgad[]; extern struct cmdmap rgad[]; extern void flush(); extern void cleanup(char *,int); extern int mapcmd(UBYTE,struct cmdmap *); extern int rbut(struct IntuiMessage *); struct Window *Window; struct NewWindow NewWindow = { 1,1,639,199,0,1,CLOSEWINDOW|RAWKEY|GADGETUP|NEWSIZE|MOUSEBUTTONS, WINDOWSIZING|WINDOWDEPTH|WINDOWCLOSE|WINDOWDRAG|SMART_REFRESH|ACTIVATE|RMBTRAP, NULL,NULL,&version[0],NULL,NULL,250,109,1024,1024,WBENCHSCREEN}; struct IOStdReq *conWmsg; struct MsgPort *conWport; struct ConUnit *cunit; /* Get at console parameters */ int opencon(); void tOpen(); void tWrite(UBYTE *,int); void tClose(); void texit(int,char *); int getcmd(); void resize(); void doboom(); void movewin(int,int,int,int,int); void horiz(int); int linecount(); int conpos(); /* Return console x pos */ int getclick(struct IntuiMessage *); int opencon() /*=====================================================*/ { register int ret; conWmsg->io_Data = (APTR)Window; conWmsg->io_Length = sizeof(struct Window); ret = OpenDevice("console.device",0,conWmsg,0); return(ret); } void tOpen() /*=======================================================*/ { if (!(conWport = CreatePort("ty.conW",0))) texit(0,"ERROR: failed to open write port!\n"); if (!(conWmsg = CreateStdIO(conWport))) texit(1,"ERROR: failed to open write message!\n"); NewWindow.FirstGadget = fgadg; if (!(Window = OpenWindow(&NewWindow))) texit(2,"ERROR: failed to open window!\n"); if (opencon()) texit(3,"ERROR: failed to open console.device!\n"); cunit = (struct ConUnit *)conWmsg->io_Unit; cunit->cu_Modes[2] = 0x30; /* Turn off auto-wrap */ tty = 123L; /* Used as flag, until other code updated */ tWrite("[0 p",5); /* Turn off cursor */ SetWindowTitles(Window,(char *)-1L,version); } void tWrite(cp,sz) /*=================================================*/ UBYTE *cp; int sz; { conWmsg->io_Command = CMD_WRITE; conWmsg->io_Data = (APTR)cp; conWmsg->io_Length = sz; DoIO(conWmsg); } void tClose() /*======================================================*/ { if (!tty) return; /* Check flag */ tty = NULL; /* Reset flag. */ CloseDevice(conWmsg); /* In reverse order to that in which */ CloseWindow(Window); /* they were procured. */ DeleteStdIO(conWmsg); DeletePort(conWport); } void texit(bra,cp) /*=================================================*/ int bra; char *cp; { switch (bra) { case (3): CloseWindow(Window); case (2): DeleteStdIO(conWmsg); case (1): DeletePort(conWport); case (0): break; } cleanup(cp,20); } int getcmd() /*======================================================*/ { /* Get a command from the IDCMP. */ struct IntuiMessage mvl; register struct IntuiMessage *msg; register int ret = C_UNKNOWN; register int loop = 1; if (maxim) { /* Do here in case maxim set by file icon */ maxim = 0; /* check instead of when ty started. */ return(C_BOOM); } flush(); /* Sync display */ while (loop) { loop = 0; /* Set back to one, to loop again. */ Wait(1 << Window->UserPort->mp_SigBit); while (msg = (struct IntuiMessage *)GetMsg(Window->UserPort)) { mvl = *msg; ReplyMsg((struct Message *)msg); switch (mvl.Class) { case (CLOSEWINDOW): ret = C_QUIT; break; case (RAWKEY): if (mvl.Qualifier & CONTROL) switch (mvl.Code) { case (0x28): ret = C_RESIZE; break; /* L */ default: loop = 1; } else if (mvl.Qualifier & SHIFT) { if ((ret = mapcmd((UBYTE)mvl.Code,uraw)) == C_UNKNOWN) loop = 1; } else { if ((ret = mapcmd((UBYTE)mvl.Code,lraw)) == C_UNKNOWN) loop = 1; } break; case (GADGETUP): ret = mapcmd((UBYTE)(((struct Gadget *)(mvl.IAddress))->GadgetID),lgad); break; case (MOUSEBUTTONS): if (mvl.Code == MENUUP) { if ((ret = mapcmd((UBYTE)rbut(&mvl),rgad)) == C_UNKNOWN) loop = 1; } else if (mvl.Code == SELECTDOWN) { ret = getclick(&mvl); if (ret == C_UNKNOWN) loop = 1; } else loop = 1; /* REST */ break; case (NEWSIZE): ret = C_RESIZE; break; } } } return(ret); } int getc() /*========================================================*/ { /* Get a key from the IDCMP. */ register struct IntuiMessage *msg; register int ret = -1; while (ret < 0) { Wait(1 << Window->UserPort->mp_SigBit); while (msg = (struct IntuiMessage *)GetMsg(Window->UserPort)) { if (msg->Class == RAWKEY) ret = msg->Code; /* So clicking a gadget will be equiv to ... (press RETURN) */ else if (msg->Class & (GADGETUP|GADGETDOWN|CLOSEWINDOW)) ret = 0x44; else if (msg->Class == NEWSIZE) has_resized = 1; ReplyMsg((struct Message *)msg); } if ((ret >= 0x80) && (ret <= 0xf8)) ret = -1; /* Ignore up trans */ } return(ret); } void resize() /*======================================================*/ { tWrite("",5); /* Get console to resize */ sc_width = (int)cunit->cu_XMax + 1; /* Then get from there */ sc_height = (int)cunit->cu_YMax + 2; /* Update control string to go to lower left. Much faster if it's updated * only once every screen resize. */ sprintf(sc_lower_left,"[%d;1H",sc_height); SetAPen(Window->RPort,0); RectFill(Window->RPort,2,11,Window->Width - 17,Window->Height - 10); } void movewin(x,y,w,h,s) /*============================================*/ int x,y,w,h,s; { int tx,ty,tw,th; tx = x - Window->LeftEdge; ty = y - Window->TopEdge; tw = w - Window->Width; th = h - Window->Height; if (s) { MoveWindow(Window,tx,ty); SizeWindow(Window,tw,th); } else { SizeWindow(Window,tw,th); MoveWindow(Window,tx,ty); } } void doboom() /*======================================================*/ { static int state = 0,x,y,w,h; if (!state) { state = 1; x = Window->LeftEdge; y = Window->TopEdge; w = Window->Width; h = Window->Height; movewin(0,0,Window->WScreen->Width,Window->WScreen->Height,state); } else { state = 0; movewin(x,y,w,h,state); } } void horiz(f) /*======================================================*/ int f; { if (f) { /* Move right. */ if (l_start < MAXHORIZ-10) l_start += 10; else l_start = MAXHORIZ; } else { if (l_start > 10) l_start -= 10; else l_start = 0; } sethbar(); } int linecount() /*===================================================*/ { /* Return number of lines in "file". */ char buf[512]; /* Can I spare ½ K of stack at this point? Hope so. */ register int ret = 0,j; register char *cp,*e; ULONG oldpos; if (!file) return(0); oldpos = Seek(file,0,OFFSET_BEGINNING); while ((j = Read(file,buf,512)) > 0) for (cp = buf,e = buf + j; cp < e; cp++) if (*cp == '\n') ret++; Seek(file,oldpos,OFFSET_BEGINNING); return(ret); } int conpos() /*======================================================*/ { return((int)cunit->cu_XCCP); } int getclick(msg) /*=================================================*/ struct IntuiMessage *msg; { register int x,y; x = msg->MouseX; y = msg->MouseY; if ((x < 2) || (x > Window->Width-18) || (y < 11) || (y > Window->Height-10)) return(C_UNKNOWN); return((y < (Window->Height >> 1))? C_BACK_PAGE: C_FORW_PAGE); }