/****************************************\ * This file controls the display (dpy.c) * \****************************************/ #include #include #include #include #include #include #include extern struct IntuitionBase *IntuitionBase; extern struct GfxBase *GfxBase; extern Beep(); static short x, y, mode, parse, saved_arg, dpytype, autocr; static struct RastPort *rp; static struct Window *w; #define ctrl 0x1F /* turns letter into ctrl char */ #define INVIS 0x80 /* returned by Emit for non-printed chars */ /* Screen dimensions */ #define LEFT 0 #define RIGHT LEFT+8*80-1 #define TOP 4 /* overlapped by menu stripe, but so what */ #define BOTTOM TOP+8*24-1 /* Mode bits */ #define EMPH (1<<0) /* emphasis (implemented as alternate background) */ #define BLINK (1<<1) /* blinking (implemented as colored text) */ #define INSDEL (1<<2) /* insert/delete mode */ #define ROLL (1<<3) /* what to do when cursor moves down from last line */ /* Parse-state bits */ #define NORMAL 0 #define QUOTING 1 /* next char is displayed even if special */ #define CURSOR 2 /* next 2 chars specify new cursor loc */ #define CURSOR2 3 /* first cursor-loc char is in saved_arg */ /* Display types */ #define GLASS 0 /* vanilla, handles BS, FF, and BEL specially */ #define SAIL 1 /* DM with blink/bold swapped & 128 possible chars */ #define MAX_TYPE 1 /* * Initialisation */ SetUpDisplay(window, type) struct Window *window; int type; { if (type >= 0 && type <= MAX_TYPE) dpytype = type; if (window) { Move(rp=((w=window)->RPort), x=LEFT, (y=TOP)+6); ClearScreen(rp); Cursor(); } parse = NORMAL; mode = ROLL; autocr = FALSE; } /* * Querying re special SAIL chars * * Certain control chars have special effects when sent to the Stanford host. * Since these special effects are being provided by certain function keys, * the control chars themselves can be interpreted as ordinary type-in. To * do this, you have to ship Stanford a special prefix char. This function * lets the main loop test whether such a prefix is needed. */ NeedQuote(c) char c; { if (dpytype == SAIL) switch (c) { case ctrl&'C': case ctrl&'^': case ctrl&'_': return(TRUE); } return(FALSE); } /* * The Guts * * Process one output char; returns char to go into log file (INVIS if none) */ static char RealEmit(c) char c; { if (autocr) switch (c) { /* suppress explicit CR/LF after wrapping around */ case ctrl&'M': return(INVIS); case ctrl&'J': {autocr = FALSE; return(c);}; default: autocr = FALSE; } if (parse == CURSOR || parse == CURSOR2) { switch (c) { case ctrl&'B': case ctrl&'L': case ctrl&'Q': case ctrl&'R': case ctrl&'X': case ctrl&'^': case ctrl&'_': parse = NORMAL; /* new control char overrides cursor command */ break; default: if (parse == CURSOR) { saved_arg = c^0x60; parse = CURSOR2; return(INVIS); } x = min(79, saved_arg&0xFF) * 8 + LEFT; y = min(23, (c^0x60)&0xFF) * 8 + TOP; parse = NORMAL; return(INVIS); } } if ((c >= ' ' && c <= '~') || parse == QUOTING) { /* display this char */ if (mode & INSDEL && x < RIGHT-8) ScrollRaster(rp, -8, 0, x, y, RIGHT, y+7); Show(c); parse = NORMAL; return(c); } switch (c) { case ctrl&'B': /* home cursor */ if (dpytype == SAIL) {x = LEFT; y = TOP;} break; case ctrl&'G': /* beep */ if (Beep()) DisplayBeep(w->WScreen); break; case ctrl&'H': /* backspace */ if (! (mode & INSDEL)) x = max(x-8, LEFT); else if (x < RIGHT-8) ScrollRaster(rp, 8, 0, x, y, RIGHT, y+7); else {Move(rp, x, y+6); ClearEOL(rp);} break; case ctrl&'I': /* tab */ x = ((x-LEFT) / 64 + 1) * 64 + LEFT; if (x <= RIGHT) return(c); x = LEFT; case ctrl&'J': /* line feed (or tab overflow) */ if (! (mode & INSDEL)) {DownLine(); return(c);} if (y < BOTTOM-8) ScrollRaster(rp, 0, -8, LEFT, y, RIGHT, BOTTOM); else {Move(rp, LEFT, y+6); ClearEOL(rp);} break; case ctrl&'L': /* clear screen or set cursor */ if (dpytype == SAIL) parse = CURSOR; else { Move(rp, x=LEFT, (y=TOP)+6); ClearScreen(rp); } break; case ctrl&'M': /* carriage return (or excess tab) */ x = LEFT; break; case ctrl&'N': /* turn on bold */ if (dpytype == SAIL) mode |= EMPH; break; case ctrl&'O': /* turn on blinking */ if (dpytype == SAIL) mode |= BLINK; break; case ctrl&'P': /* turn on insert/delete mode */ if (dpytype == SAIL) mode |= INSDEL; break; case ctrl&'W': /* erase to EOL */ if (dpytype == SAIL) { Move(rp, x, y+6); ClearEOL(rp); } break; case ctrl&'X': /* cancel modes */ if (dpytype == SAIL) mode = 0; break; case ctrl&'Z': /* cursor up */ if (dpytype != SAIL) break; if (! (mode & INSDEL)) y = max(TOP, y-8); else if (y < BOTTOM-8) ScrollRaster(rp, 0, 8, LEFT, y, RIGHT, BOTTOM); else {Move(rp, LEFT, y+6); ClearEOL(rp);} break; case ctrl&'[': /* quote next character */ if (dpytype == SAIL) parse = QUOTING; break; case ctrl&'\\': /* cursor right */ if (dpytype != SAIL) break; if (mode & INSDEL) { if (x < RIGHT-8) ScrollRaster(rp, -8, 0, x, y, RIGHT, y+7); else {Move(rp, x, y+6); ClearEOL(rp);} } else if ((x += 8) > RIGHT) { x = LEFT; if ((y += 8) > BOTTOM) y = TOP; } break; case ctrl&']': /* turn on roll mode */ if (dpytype == SAIL) mode |= ROLL; break; case ctrl&'^': /* master clear */ case ctrl&'_': /* clear unprotected text */ if (dpytype != SAIL) break; mode &= ~(BLINK | EMPH | INSDEL); Move(rp, x=LEFT, (y=TOP)+6); ClearScreen(rp); break; } /* end of switch (c) for control chars */ return(INVIS); } /* end of RealEmit */ /* * Various screen-action functions */ static Show(c) char c; { Move(rp, x, y+6); if (c < ' ') c += 0x80; /* chars 00-1F are hidden in 80-9F in the font */ if (mode & EMPH) SetBPen(rp, 2); /* emphasis by changing background */ if (mode & BLINK) SetAPen(rp, 3); /* "blink" by changing foreground */ Text(rp, &c, 1); if (mode & EMPH) SetBPen(rp, 0); if (mode & BLINK) SetAPen(rp, 1); if ((x += 8) > RIGHT) { x = LEFT; DownLine(); autocr = TRUE; } } static DownLine() { if ((y += 8) > BOTTOM) { y -= 8; if (mode & ROLL) ScrollRaster(rp, 0, 8, LEFT, TOP, RIGHT, BOTTOM); else y = TOP; } } static Cursor() { SetAPen(rp, 3); SetDrMd(rp, COMPLEMENT); RectFill(rp, x, y, x+7, y+7); SetDrMd(rp, JAM2); SetAPen(rp, 1); } /* * Public function to process one char */ char Emit(c) char c; { Cursor(); c = RealEmit(c & 0x7F); Cursor(); return(c); } /* * Public function to process a string of chars (not currently used) */ Emits(string) char *string; { Cursor(); while (*string) RealEmit(*string++ & 0x7F); Cursor(); }