#include #include #include #include #include #include #include #include #include "main.h" char posreq[] = "\x9B%d;%dR"; char primda[] = "\x9B?62;9c"; char secda[] = "\x9B>1;10;0c"; char tstat[] = "\x9B""0n"; char pstat[] = "\x9B?13n"; char ustat[] = "\x9B?21n"; char klang[] = "\x9B?27;6n"; interpret(register struct console *con,register LONG len) { register SHORT cnt,lim; register char *scp; char c,com[16]; scp = con->buf; while (len--) { c = *scp++; if (con->stat) { cnt = con->stat; con->stat = 0; switch (cnt) { case SEQ_ESC: switch (c) { case '[': con->stat = SEQ_CSI; con->argi = 0; con->carg = 0; break; case '#': con->stat = SEQ_LWIDTH; break; case 'P': con->stat = SEQ_DCS; break; case ' ': con->stat = SEQ_SPC; break; case '(': con->stat = SEQ_G0; break; case ')': con->stat = SEQ_G1; break; case '*': con->stat = SEQ_G2; break; case '+': con->stat = SEQ_G3; break; case '~': setrset(con,1); break; case 'n': setlset(con,2); break; case '}': setrset(con,2); break; case 'o': setlset(con,3); break; case '|': setrset(con,3); break; case 'N': con->slset = con->lset; con->tstat |= GXGL; setlset(con,2); break; case 'O': con->slset = con->lset; con->tstat |= GXGL; setlset(con,3); break; case '<': case '=': keypadmode(TRUE); activate(&appl); break; case '>': keypadmode(FALSE); activate(&num); break; case 'D': cursordown(con,1); break; case 'M': cursorup(con,1); break; case 'E': cursornextline(con); break; case '7': con->s_row = con->row; con->s_col = con->col; con->s_attr = con->attr; for (cnt = 0; cnt < SETS; cnt++) { con->s_gset[cnt] = con->gset[cnt]; con->s_mset[cnt] = con->mset[cnt]; } con->s_lset = con->lset; con->s_rset = con->rset; con->s_tstat = con->tstat; break; case '8': if (con->ordc) textout(con); con->row = con->s_row; con->col = con->s_col; con->attr = con->s_attr; for (cnt = 0; cnt < SETS; cnt++) { con->gset[cnt] = con->s_gset[cnt]; con->mset[cnt] = con->s_mset[cnt]; } setlset(con,con->s_lset); setrset(con,con->s_rset); con->tstat = con->s_tstat & (WRAP | INSERT | NEWLINE | CONVERT | CURSOR); if (con->tstat & WRAP) activate(&wrap); else activate(&trunc); if (con->tstat & INSERT) activate(&ins); else activate(&over); if (con->tstat & NEWLINE) { entermode(TRUE); activate(&newl); } else { entermode(FALSE); activate(&cret); } if (con->tstat & CONVERT) activate(&bit_7); else activate(&bit_8); modifyattr(con); break; case 'H': con->tabs[con->col] = 1; break; case 'c': reset(con); break; case 'Z': sendstring(con,primda); break; default: ; } break; case SEQ_CSI: if (isdigit(c)) { con->carg = con->carg * 10; con->carg += (USHORT)(c - '0'); con->stat = SEQ_CSI; } else { switch (c) { case ';': con->args[con->argi] = con->carg; con->carg = 0; con->argi++; if (con->argi > ARGUMENTS) con->argi = ARGUMENTS; con->stat = SEQ_CSI; break; case '?': con->stat = SEQ_MOD; break; case '>': con->stat = SEQ_SEC; break; case '!': con->stat = SEQ_RES; break; case '"': con->stat = SEQ_SET; break; case '\x27': case '^': con->stat = SEQ_ONE; break; case 'h': switch (con->carg) { case 2: con->gstat |= LOCKED; break; case 4: if (con->ordc) textout(con); con->tstat |= INSERT; activate(&ins); break; case 20: entermode(TRUE); con->tstat |= NEWLINE; activate(&newl); break; default: ; } break; case 'l': switch (con->carg) { case 2: con->gstat &= (MASK - LOCKED); break; case 4: if (con->ordc) textout(con); con->tstat &= (MASK - INSERT); activate(&over); break; case 20: entermode(FALSE); con->tstat &= (MASK - NEWLINE); activate(&cret); break; default: ; } break; case 'A': cnt = con->carg; if (cnt == 0) cnt = 1; cursorup(con,cnt); break; case 'B': cnt = con->carg; if (cnt == 0) cnt = 1; cursordown(con,cnt); break; case 'C': cnt = con->carg; if (cnt == 0) cnt = 1; cursorright(con,cnt); break; case 'D': cnt = con->carg; if (cnt == 0) cnt = 1; cursorleft(con,cnt); break; case 'f': case 'H': if (con->ordc) textout(con); if (con->argi) con->row = con->args[0]; else con->row = con->carg; if (con->row == 0) con->row = 1; if (con->row > rows) con->row = rows; if ((con->argi)&&(con->carg)) { con->col = con->carg; if (con->col > COLUMNS) con->col = COLUMNS; } else con->col = 1; break; case 'g': if (con->carg == 0) con->tabs[con->col] = 0; if (con->carg == 3) setmem(con->tabs,COLUMNS,0); break; case 'm': if (con->ordc) textout(con); con->args[con->argi] = con->carg; con->argi++; for (cnt = 0; cnt < con->argi; cnt++) { switch(con->args[cnt]) { case 0: con->attr= 0; break; case 1: con->attr|=FSF_BOLD; break; case 3: con->attr|=FSF_ITALIC; break; case 4: con->attr|=FSF_UNDERLINED; break; case 7: con->attr|=NEGATIVE; break; case 22: con->attr&=(MASK-FSF_BOLD); break; case 23: con->attr&=(MASK-FSF_ITALIC); break; case 24: con->attr&=(MASK-FSF_UNDERLINED); break; case 27: con->attr&=(MASK-NEGATIVE); break; default: ; } } modifyattr(con); break; case 'L': cnt = con->carg; if (cnt == 0) cnt = 1; insertlines(con,cnt); break; case 'M': cnt = con->carg; if (cnt == 0) cnt = 1; deletelines(con,cnt); break; case '@': cnt = con->carg; if (cnt == 0) cnt = 1; insertchars(con,cnt); break; case 'P': cnt = con->carg; if (cnt == 0) cnt = 1; deletechars(con,cnt); break; case 'X': cnt = con->carg; if (cnt == 0) cnt = 1; erasechars(con,cnt); break; case 'K': switch (con->carg) { case 0: erasechars(con, (USHORT)((COLUMNS + 1) - con->col)); break; case 1: eraselinebeg(con); break; case 2: eraselinebeg(con); erasechars(con, (USHORT)((COLUMNS + 1) - con->col)); break; default: ; } break; case 'J': switch (con->carg) { case 0: if (con->row < rows) { if (con->ordc) textout(con); con->row++; eraselines(con, (USHORT)(rows - con->row)); con->row--; } erasechars(con, (USHORT)((COLUMNS + 1) - con->col)); break; case 1: erasescrbeg(con); eraselinebeg(con); break; case 2: SetRast(con->rp,BACKGROUND_PEN); for (cnt = 0; cnt < rows; cnt++) *(con->rows + cnt + 1) = 0; break; default: ; } break; case 'r': if (con->ordc) textout(con); if ((con->argi)&&(con->carg)) con->bot = con->carg; else con->bot = rows; if (con->argi) con->top = con->args[0]; else con->top = con->carg; if (con->top == 0) con->top = 1; con->row = 1; con->col = 1; break; case 'c': if (con->carg == 0) sendstring(con,primda); break; case 'n': switch (con->carg) { case 5: sendstring(con,tstat); break; case 6: sprintf(com,posreq,con->row,con->col); sendstring(con,com); break; default: ; } break; default: ; } } break; case SEQ_MOD: if (isdigit(c)) { con->carg = con->carg * 10; con->carg += (USHORT)(c - '0'); con->stat = SEQ_MOD; } else { switch (c) { case ';': con->args[con->argi] = con->carg; con->carg = 0; con->argi++; if (con->argi > ARGUMENTS) con->argi = ARGUMENTS; con->stat = SEQ_MOD; break; case 'h': switch (con->carg) { case 1: cursormode(FALSE); break; case 7: con->tstat |= WRAP; activate(&wrap); break; case 25: showcursor(con); activate(&curson); break; case 42: con->nstat |= NATIONAL; setlset(con,con->lset); setrset(con,con->rset); activate(&nat); modifyattr(con); break; default: ; } break; case 'l': switch (con->carg) { case 1: cursormode(TRUE); break; case 7: con->tstat &= (MASK - WRAP); activate(&trunc); break; case 25: hidecursor(con); activate(&cursoff); break; case 42: con->nstat &= (MASK - NATIONAL); setlset(con,con->lset); setrset(con,con->rset); activate(&mult); modifyattr(con); break; default: ; } break; case 'n': switch (con->carg) { case 15: sendstring(con,pstat); break; case 25: sendstring(con,ustat); break; case 26: sendstring(con,klang); break; default: ; } break; } } break; case SEQ_LWIDTH: if (*(con->rows + con->row)) break; switch (c) { case '3': *(con->rows + con->row) = UPPER_SIDE; break; case '4': *(con->rows + con->row) = LOWER_SIDE; break; case '6': *(con->rows + con->row) = HORIZ_ONLY; break; default: ; } if (*(con->rows + con->row)) { if (con->ordc) textout(con); stretch(con->rp,0,(con->row - 1) * YSIZE, WIDTH / 2,YSIZE,*(con->rows + con->row)); } break; case SEQ_SET: if (c == 'p') { if (con->args[0] == 62) { if (con->argi == 0) { con->tstat &= (MASK - CONVERT); activate(&bit_8); } else { if (con->args[1] == 1) { con->tstat |= CONVERT; activate(&bit_7); } else { con->tstat &= (MASK - CONVERT); activate(&bit_8); } } } else if (con->args[0] == 61) { con->tstat |= CONVERT; activate(&bit_7); } } break; case SEQ_DCS: if (c != ST) con->stat = SEQ_DCS; else if (c == ESC) con->stat = SEQ_ENDDCS; break; case SEQ_SPC: if (c == 'F') { con->tstat |= CONVERT; activate(&bit_7); } else if (c == 'G') { con->tstat &= (MASK - CONVERT); activate(&bit_8); } break; case SEQ_SEC: if (isdigit(c)) con->stat = SEQ_SEC; else if (c == 'c') sendstring(con,secda); break; case SEQ_RES: if (c == 'p') reset(con); break; case SEQ_G0: setset(con,cset(c),0); break; case SEQ_G1: setset(con,cset(c),1); break; case SEQ_G2: setset(con,cset(c),2); break; case SEQ_G3: setset(con,cset(c),3); break; case SEQ_ENDDCS: if (c != '/') con->stat = SEQ_DCS; break; default: ; } } else { cnt = 0; if (c & '\x80') { cnt = 4; if (con->tstat & DCONTHI) { if (con->ordc) textout(con); cnt |= 2; } if ((c >= '\xA0')&&(c < '\xFF')) { cnt |= 1; if (con->nstat & NATIONAL) c &= '\x7F'; } } else { if (con->tstat & DCONTLO) { if (con->ordc) textout(con); cnt = 2; } if ((c >= ' ')&&(c < '\x7F')) cnt |= 1; } if (cnt & 3) { if (*(con->rows + con->row)) lim = COLUMNS / 2; else lim = COLUMNS; if (con->col > lim) { if (con->ordc) textout(con); if (con->tstat & WRAP) cursornextline(con); else con->col = lim; } if (con->ordc == 0) con->ordcol = con->col; con->ordtext[con->ordc] = c; con->ordc++; if (!(cnt & 2)) con->col++; if (con->tstat & GXGL) { setlset(con,con->slset); con->tstat &= (MASK - GXGL); } } if (!(cnt & 1)) { if (con->ordc) textout(con); if (cnt & 4) { switch (c) { case CSI: con->stat = SEQ_CSI; con->argi = 0; con->carg = 0; break; case IND: cursordown(con,1); break; case NEL: cursornextline(con); break; case HTS: con->tabs[con->col] = 1; break; case RI: cursorup(con,1); break; case SS2: con->slset = con->lset; con->tstat |= GXGL; setlset(con,2); break; case SS3: con->slset = con->lset; con->tstat |= GXGL; setlset(con,3); break; case DCS: con->stat = SEQ_DCS; break; default: ; } } else { switch (c) { case ESC: con->stat = SEQ_ESC; break; case BEL: beep(con); DisplayBeep(NULL); break; case BS: if (con->col > 1) con->col--; break; case HT: while (con->col < COLUMNS) { con->col++; if (con->tabs[con->col]) break; } break; case VT: case FF: case LF: if (con->tstat & NEWLINE) newline(con); else cursordown(con,1); break; case CR: con->col = 1; break; case SI: setlset(con,0); break; case SO: setlset(con,1); break; default: ; } } } } } return(0); } setset(struct console *con,USHORT set,USHORT seq) { con->mset[seq] = set; switch(set) { case BRITISH: activate(&br_set); break; case DUTCH: activate(&du_set); break; case FINNISH: activate(&fi_set); break; case FRENCH: activate(&fr_set); break; case FRENCH_CANADIAN: activate(&fc_set); break; case GERMAN: activate(&ger_set); break; case ITALIAN: activate(&ita_set); break; case NORWEGIAN: activate(&nor_set); break; case SPANISH: activate(&spa_set); break; case SWEDISH: activate(&swe_set); break; case SWISS: activate(&swi_set); break; default: con->gset[seq] = set; } if (con->lset == seq) setlset(con,seq); if (con->rset == seq) setrset(con,seq); return(0); }