home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / COMM / MISC / SRC26_2.ZIP / SRC / ANSI.C next >
Encoding:
C/C++ Source or Header  |  1990-07-12  |  24.0 KB  |  1,135 lines

  1. /*
  2.  * ansi.c: hterm escape sequence decoder
  3.  *
  4.  * Author: HIRANO Satoshi
  5.  * (C) 1989  Halca Computer Science Laboratory TM
  6.  *           University of Tokyo
  7.  *
  8.  * 1.1 86/10/17 Halca.Hirano
  9.  * 1.2 89/05/16 Halca.Hirano add RCS control
  10.  * 2.2 89/05/16 Halca.Hirano 
  11.  *    ----- V2.2 distribution ----
  12.  * 2.3 89/07/20 Halca.Hirano 
  13.  *    add EUC/SJIS/JIS (Thank you ohta@ricoh)
  14.  *    add UOP_GRAPHICS (Thank you mik@uop)
  15.  *    tab editor
  16.  *    ---- V2.3.-1 distribution ----
  17.  * 2.4 89/09/01 Halca.Hirano
  18.  *    extend UOP_GRAPHICS
  19.  * 2.5 89/09/14 Halca.Hirano
  20.  *    fix UOP_GRAPHICS label bug by mik@uop
  21.  *    fix binary logging bug
  22.  *     ---- V2.4.0 distribution ----
  23.  * 2.6 89/10/10 Halca.Hirano
  24.  *    fix CSI bug -> CSI is usable only if JIS mode
  25.  * 2.7 89/11/10 Tominaga@Titech port to J3100
  26.  * 2.8 89/11/19 Halca.Hirano add cursor position reporting (Thanks Tominaga@Titech)
  27.  * 2.9 89/11/30 mik@uop add ACOS kanji code
  28.  * 3.0 89/12/08 Shikita@titech we can read JIS from EUC/SJIS mode
  29.  * 3.1 89/12/24 Halca.Hirano don't display non-supported escape sequences
  30.  * 3.2 90/07/09 Halca.Hirano locate() after receiving non graphic character
  31.  *  change IBM-PC character color table
  32.  * 
  33.  * $Header: ansi.cv  1.14  90/07/05 08:37:26  hirano  Exp $"
  34.  *
  35.  */
  36.  
  37. #include <stdio.h>
  38. #include <ctype.h>
  39. #include "config.h"
  40. #include "hterm.h"
  41. #include "option.h"
  42. #include "default.h"
  43. #include "global.h"
  44.  
  45. #define MAX_PARAM    20    /* number of parameter in escape seq.    */
  46.  
  47. static short    ai;
  48. static short    val[MAX_PARAM];    /* parameter value            */
  49. static int    state;        /* sequence state            */
  50. static int    pageSaved;    /* page is saved flag for ESC [ ? 47 h    */
  51.  
  52. #ifdef PC98
  53. #define    CMASK    0x1b
  54. static short ctab[8] = { 0x00, 0x40, 0x80, 0xc0, 0x20, 0x60, 0xa0, 0xe0 };
  55.                     /*   black red   green yellow blue vioret magenta white */
  56. #endif /* PC98 */
  57. #ifdef IBMPC
  58. #define FMASK    0xf8
  59. #define BMASK    0x8f
  60. static short fColor[8] = {0x00, 0x04, 0x02, 0x06, 0x01, 0x03, 0x05, 0x07};
  61.                     /*   black  red   green brown blue  cyan  magenta white */
  62. static short bColor[8] = {0x00, 0x40, 0x20, 0x60, 0x10, 0x30, 0x50, 0x70};
  63. #endif /* IBMPC */
  64.  
  65. /*
  66.  * DEC special character conversion table
  67.  */
  68. #ifdef J3100
  69. static unsigned char decConv[128] = {
  70.     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  71.     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  72.     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  73.     0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  74.     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
  75.     0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  76.     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  77.     0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  78.     0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
  79.     0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
  80.     0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
  81.     0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x20,
  82.     0x04, 0xff, 0x1a, 0x18, 0x1b, 0x19, 0xdf, 0xff,
  83.     0x19, 0x19, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x7e,
  84.     0x2d, 0x2d, 0x2d, 0x5f, 0x2b, 0x2b, 0x2b, 0x2b,
  85.     0x7c, 0x11, 0x10, 0x14, 0xff, 0xff, 0xa5, 0x7f
  86. };
  87. #else /* J3100 */
  88. static unsigned char decConv[128] = {
  89.     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  90.     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  91.     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  92.     0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  93.     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
  94.     0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  95.     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  96.     0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  97.     0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
  98.     0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
  99.     0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
  100.     0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x20,
  101.     0xea, 0x87, 0x09, 0x87, 0x0d, 0x0a, 0xdf, 0x87,
  102.     0x87, 0x87, 0x9b, 0x99, 0x98, 0x9a, 0x8f, 0x95,
  103.     0x95, 0x95, 0x95, 0x95, 0x93, 0x92, 0x90, 0x91,
  104.     0x96, 0x87, 0x87, 0x87, 0x87, 0x87, 0xa5, 0x7f
  105. };
  106. #endif /* J3100 */
  107.  
  108. void state1(unsigned short c);
  109. void state2(unsigned short c);
  110. void state3(unsigned short c);
  111. void state5(void );
  112. void state8(unsigned short c);
  113. void state16(u_short c);
  114. void state17(u_short c);
  115. void state100(unsigned short c);
  116. void state101(unsigned short c);
  117. void state102(unsigned short c);
  118. void state103(void );
  119. void state104(void );
  120. void state110(unsigned short c);
  121. void saveCursor(void );
  122. void restCursor(void );
  123. void setAttribute(void );
  124. void eraseScreen(void );
  125. void eraseLine(void );
  126. void cursorPosition(void );
  127. void scrollRegion(void );
  128. void downLine(void );
  129. void upLine(void );
  130. void cursorReport(void );
  131.  
  132. void ansiInit()
  133. {
  134.     setTabs(8);
  135. }
  136.  
  137. void ansiSetup()
  138. {
  139.     kfirstSave = kstateSave = state = ai = kstate = kfirst = saveX = saveY = 0;
  140.     saveAttr = eraseAttr;
  141.     spaceTab = pageSaved = originMode = NO;
  142.     kanjiSave = kanjiCode;
  143. }
  144.  
  145. void conPrint(p)
  146. /*
  147.  * print a string on console with ANSI decoding
  148.  */
  149. register char *p;
  150. {
  151.     while (*p)
  152.         decodeAnsi((u_short)(*p++) & 0xff);
  153. }
  154.  
  155. void decodeAnsi(c)
  156. /*
  157.  * decode ANSI escape sequence and reflect it to console
  158.  * in:
  159.  *    c    if online, char from the remote system
  160.  */
  161. register u_short c;
  162. {
  163.     if (logging == LOG_NO_CONVERT)
  164.         logPut(c);
  165.     if (intControl == NO) {
  166.         if (c == CR) {
  167.             wrapPending = NO;
  168.             conWrite(c);
  169.             locate(0, cursorY);
  170.             if (printMode) 
  171.                 outPrinter(CR);
  172.             if (logging == LOG_CONVERT)
  173.                 logPut(c);
  174.         } else if (c == LF) {
  175.             conWrite(c);
  176.             downLine();
  177.             if (printMode) 
  178.                 outPrinter(LF);
  179. #ifdef MSDOS
  180.             if (logging == LOG_CONVERT)
  181.                 logPut(c);
  182. #endif
  183.         } else
  184. #ifdef KANJI
  185.             goto kconvert;
  186. #else
  187.             conWrite(c);
  188. #endif /* KANJI */
  189.         return;
  190.     }
  191.     /* short cut */
  192.     if (state == 0 && kstate == 0 && kfirst == 0 && isAscii(c)) {
  193.         conWrite(c);
  194.         return;
  195.     }
  196.     switch(c) {
  197.     case CR: 
  198.         locate(0, cursorY); 
  199.         wrapPending = NO;
  200.         if (printMode) 
  201.             outPrinter(CR);
  202.         if (logging == LOG_CONVERT)
  203.             logPut(c);
  204.         return;
  205.     case FF: 
  206.         if (formfeed == YES) {
  207.         clearLine(0, bottomLine);
  208.         locate(0, 0);
  209.         if (printMode) 
  210.             outPrinter(FF);
  211.         return;
  212.          } /* else LF */
  213.     case VT:
  214.     case LF: 
  215.         downLine();
  216.         if (printMode) 
  217.             outPrinter(LF);
  218. #ifdef MSDOS
  219.         if (logging == LOG_CONVERT)
  220.             logPut(c);
  221. #endif
  222.         return;
  223.     case BS: 
  224.         wrapPending = NO;
  225.         if (cursorX > 0) 
  226.             locate(cursorX-1, cursorY);
  227.         if (printMode) 
  228.             outPrinter(BS);
  229.         if (logging == LOG_CONVERT)
  230.             logPut(c);
  231.         return;
  232.     case BEL: 
  233.         bell(); 
  234.         if (logging == LOG_CONVERT)
  235.             logPut(c);
  236.         return;
  237.     case HT: 
  238.         if (cursorX >= LAST_COLUMN)
  239.             return;
  240.         if (spaceTab) {
  241.             int x = cursorX;
  242.             conWrite(SPACE);
  243.             cursorX = x;
  244.         }
  245.         for (cursorX++; cursorX < LAST_COLUMN && tabTable[cursorX] == 0; cursorX++)
  246.             if (spaceTab) { 
  247.                 int x = cursorX;
  248.                 conWrite(SPACE);
  249.                 locate(x, cursorY);
  250.             }
  251.         locate(cursorX, cursorY);
  252.         if (printMode) 
  253.             outPrinter(c);
  254.         if (logging == LOG_CONVERT)
  255.             logPut(c);
  256.         return;
  257.     case NUL:
  258.     case DEL:
  259.         return;
  260. #ifdef KANJI
  261.     case SI:                /* invoke G0 to GL    */
  262.         kstate = 0;            /* enter roman mode    */
  263.         return;
  264.     case SO:                /* invoke G1 to GL    */
  265.         kstate = 1;            /* enter kana mode    */
  266.         return;
  267. #else
  268.     case SI:
  269.     case SO:
  270.         return;                /* ignored        */
  271. #endif /* KANJI */
  272. #ifdef NEC_KANJI
  273.     case CAN:                /* CAN             */
  274.         state = 0;
  275.         return;
  276.     case SUB:                /* SUB; NEC kanji in/out marker    */
  277.         if (kanjiCode == NECKANJI)
  278.             state = 110;
  279.         else
  280.             state = 0;
  281.         return;
  282. #else
  283.     case CAN:                /* CAN             */
  284.     case SUB:                /* SUB             */
  285.         state = 0;
  286.         return;
  287. #endif /* NEC_KANJI */
  288. #ifdef KANJI
  289.     case CSI:                /* CSI (ESC [) */
  290.         if (kanjiCode == EUC || kanjiCode == SJIS) 
  291.             goto kconvert;
  292.         for (ai = 0; ai < MAX_PARAM; ai++)  val[ai] = 0;
  293.         ai = 0;
  294.         state = 2;
  295.         return;
  296. #endif /* KANJI */
  297.     case ESC:
  298.         for (ai = 0; ai < MAX_PARAM; ai++) val[ai] = 0;
  299.         ai = 0;
  300.         state = 1;
  301.         return;
  302. #ifdef UOP_GRAPHICS
  303.     case SOH:
  304.         if (state == 17) state17(c);
  305.         return;
  306. #endif /* UOP_GRAPHICS */
  307.     default: 
  308.         if (c < SPACE)            /* discard ctrl char    */
  309.             return;
  310. #ifndef KANJI
  311.         if (state == 0) {
  312.             conWrite(c);
  313.             return;
  314.         }
  315. #else
  316.         if (state)
  317.             break;
  318. kconvert:
  319.         switch (kstate) {
  320.         case 0:                /* roman        */
  321.             switch (kanjiCode) {
  322.             case EUC:
  323.                 if (kfirst) {        /* kfirst = kanji1 or SS2 */
  324.                     if (kfirst == SS2)
  325.                         conWrite(c);    /* kana 00xx    */
  326.                     else
  327.                         conWrite(((kfirst << 8) | c) & 0x7f7f);
  328.                     kfirst = 0;
  329.                     return;
  330.                 } 
  331.                 if (c & 0x80) {        /* kanji 1st or SS2    */
  332.                     kfirst = c;
  333.                     return;
  334.                 }
  335.                 conWrite(c);        /* ASCII        */
  336.                  return;
  337.             case SJIS:
  338.                 if (isSJIS1(c) && kfirst == 0) {
  339.                     kfirst = c;
  340.                     return;
  341.                 }
  342.                 if (isSJIS1(kfirst) && isSJIS2(c)) {
  343.                     c = SJIStoJIS(kfirst, c);
  344.                     kfirst = 0;
  345.                 }
  346.                 if (isKana(c))
  347.                     kfirst = 0;
  348.                 conWrite(c);
  349.                 return;
  350.             default:        /* NJIS, OJIS, NEC */
  351.                 conWrite(c);
  352.                 return;
  353.             }
  354.         case 1:                /* kana            */
  355.             conWrite(c | 0x80);    /* note: no SS2        */
  356.             return;
  357.         case 2:                /* kanji        */
  358.             if (kfirst) {
  359.                 conWrite((kfirst << 8) | c);
  360.                 kfirst = 0;
  361.                 return;
  362.             }
  363.             kfirst = c;
  364.             return;
  365.         case 3:                /* DEC special        */
  366.             conWrite(decConv[c & 0x7f]);
  367.             return;
  368.         }
  369. #endif /* KANJI */
  370.     }
  371.     /* if in the state sequence and not controll character */
  372.     switch (state) {
  373.     case 1:    /* ESC */
  374.         state1(c);
  375.         break;
  376.     case 2:    /* ESC [ */
  377.         state2(c);
  378.         break;
  379.     case 3:    /* ESC [ >    */
  380.         state3(c);
  381.         break;
  382.     case 5: /* ESC #    */
  383.         state5();
  384.         break;
  385.     case 8:    /* ESC [ ? */
  386.         state8(c);
  387.         break;
  388. #ifdef UOP_GRAPHICS
  389.     /* expand for graphics */
  390.     case 16: /* ESC R */
  391.         state16(c);
  392.         break;
  393.     case 17: /* ESC R t */
  394.         state17(c); 
  395.         break;
  396. #endif /* UOP_GRAPHICS */
  397. #ifdef KANJI
  398.     case 100:    /* ESC $ */
  399.         state100(c);
  400.         break;
  401.     case 101:    /* ESC $ ( */
  402.         state101(c);
  403.         break;
  404.     case 102:    /* ESC ( */
  405.         state102(c);
  406.         break;
  407.     case 103:    /* ESC $ ) */
  408.         state103();
  409.         break;
  410.     case 104:    /* ESC ) */
  411.         state104();
  412.         break;
  413. #ifdef NEC_KANJI
  414.     case 110:    /* SUB */
  415.         state110(c);
  416.         break;
  417. #endif /* NEC_KANJI */
  418. #endif /* KANJI */
  419.     }
  420. }
  421.  
  422. /*
  423.  * after ESC 
  424.  */
  425. static void state1(c)
  426. register u_short c;
  427. {
  428.     switch(c) {
  429.         case '[':  state = 2; break;
  430.         case '#':  state = 5; break;
  431.         case '>':  state = 0; applKeypad = NO; break;
  432.         case '=':  state = 0; applKeypad = YES; break;
  433.         case '7':  saveCursor();    /* ESC 7    cursor save */
  434.             state = 0;
  435.             locate(cursorX, cursorY);
  436.             break;
  437.         case '8':  restCursor();    /* ESC 8    cursor restore */
  438.             wrapPending = NO;
  439.             state = 0;
  440.             break;
  441.         case 'H':  /*    ESC H set horizontal tab stop    */
  442.             if (cursorX < MAX_COLUMN)
  443.                 tabTable[cursorX] = 1; 
  444.             state = 0; 
  445.             break;
  446.         case 'D':  downLine(); state = 0; break;    /* IND    */
  447.         case 'M':  upLine(); state = 0; break;        /* RI    */
  448.         case 'E':  locate(0, cursorY);            /* NEL    */
  449.             downLine();
  450.             state = 0;
  451.             break;
  452. #ifdef UOP_GRAPHICS
  453.         case 'R':  state = 16; break;
  454. #endif /* UOP_GRAPHICS */
  455. #ifdef KANJI 
  456.         case '$':  state = 100; break;
  457.         case '(':  state = 102; break;
  458.         case ')':  state = 103; break;
  459. #endif /* KANJI */
  460.         default: state = 0;     /* undefined sequence */
  461.     }
  462. }
  463.  
  464. static void state2(c)
  465. /* ESC [   or   CSI */
  466. register u_short c;
  467. {
  468.     if (isdigit(c)) {    /* ESC [ Pn        */
  469.         if (ai < MAX_PARAM)
  470.             val[ai] = val[ai]*10+c-'0';
  471.         else
  472.             state = 0;
  473.         return;
  474.     } else if (c == ';') {    /* ESC [ Pn ;        */
  475.         ai++;
  476.         return;
  477.     } else {
  478.         switch(c) {    /* ESC [ Pm ; Pn c    */
  479.         case '=':
  480.         case '?':
  481.             state = 8;
  482.             return;
  483.         case 'H':    /* Horizontal and vertical positioning (not recommended */
  484.         case 'f':    /* cursor position        */
  485.             cursorPosition();
  486.             break;
  487.         case 'm':        /* set attribute    */
  488.             setAttribute();
  489.             locate(cursorX, cursorY);
  490.             break;
  491.         case 'K':        /* erase within line    */
  492.             eraseLine();
  493.             break;
  494.         case 'J':        /* erase within screen    */
  495.             eraseScreen();
  496.             break;
  497.         case 'M':        /* delete line        */
  498.             if (val[0] == 0) val[0]++;
  499.             wrapPending = NO;
  500.             deleteLine(val[0]);
  501.             locate(0, cursorY);
  502.             break;
  503.         case 'L':        /* insert line        */
  504.             if (val[0] == 0) val[0]++;
  505.             wrapPending = NO;
  506.             insertLine(val[0]);
  507.             locate(0, cursorY);
  508.             break;
  509.         case 's':        /* save cursor pos.    */
  510.             saveCursor();
  511.             break;
  512.         case 'u':         /* restore cursor position */
  513.             restCursor();
  514.             break;
  515.         case 'P':        /* ESC [ val P    del char    */
  516.             if (val[0] == 0) val[0] = 1;
  517.             wrapPending = NO;
  518.             deleteChar(cursorX, val[0]);
  519.             locate(cursorX, cursorY);
  520.             wrapPending = NO;
  521.             break;
  522.         case '@':        /* ESC [ val @   insert char    */
  523.             if (val[0] == 0) val[0] = 1;
  524.             wrapPending = NO;
  525.             insertChar(cursorX, val[0]);
  526.             locate(cursorX, cursorY);
  527.             wrapPending = NO;
  528.             break;
  529.         case 'A':        /* cursor up            */
  530.             moveCursor(UP, val[0]);
  531.             break;
  532.         case 'B':        /* cursor down            */
  533.             moveCursor(DOWN, val[0]);
  534.             break;
  535.         case 'C':        /* cursor right            */
  536.             moveCursor(RIGHT, val[0]);
  537.             break;
  538.         case 'D':        /* cursor left            */
  539.             moveCursor(LEFT, val[0]);
  540.             break;
  541.         case 'r':        /* set scrole region        */
  542.             scrollRegion();
  543.             break;
  544.         case '>':        /* set/reset mode    */
  545.             val[0] = 0;
  546.             state = 3;
  547.             return;
  548.         case 'g':    /* clear tab stops        */
  549.             if (val[0] == 0 && cursorX < MAX_COLUMN)
  550.                 tabTable[cursorX] = 0;
  551.             else if (val[0] == 3)
  552.                 clearAllTabs();
  553.             break;
  554.         case 'n':    /* cursor reporting function */
  555.             cursorReport();
  556.             break;
  557.         }
  558.     }
  559.     state = 0;
  560. }
  561.  
  562. static void state3(c)
  563. /* ESC [ > */
  564. register u_short c;
  565. {
  566.     if (isdigit(c)) {
  567.         if (ai < MAX_PARAM)
  568.             val[ai] = val[ai]*10+c-'0';
  569.         else
  570.             state = 0;
  571.         return;
  572.     }
  573.     switch (val[0]) {
  574.     case 1:
  575. #if 0
  576.         if (c == 'h')
  577.             enable25();    /* enable bottom line    */
  578.         else if (c == 'l')
  579.             disable25();    /* disable bottom line    */
  580. #endif
  581.         break;
  582.     }
  583.     state = 0;
  584. }
  585.  
  586. static void state5()
  587. /* ESC # */
  588. {
  589.     /* do nothing */
  590.     state = 0;
  591. }
  592.  
  593. static void state8(c)
  594. /* ESC [ ? */
  595. register u_short c;
  596. {
  597.     if (isdigit(c)) {    /* ESC [ ? Pn            */
  598.         if (ai < MAX_PARAM)
  599.             val[ai] = val[ai]*10+c-'0';
  600.         else
  601.             state = 0;
  602.         return;
  603.     }
  604.     switch (val[0]) {
  605.     case 1:    
  606.         if (c == 'h')            /* ESC [ ? 1 h    */
  607.             applCursor = YES;    /* appl. curosr mode    */
  608.         else if (c == 'l')
  609.             applCursor = NO;    /* normal curosr mode    */
  610.         break;
  611.     /* case 2: vt52mode(); break;*/
  612.     /* case 3: 132/80column(); break;*/
  613.     case 4: 
  614.         switch (c) {        /* ESC [ ? 4 h */
  615.         case 'h': /* smoothMode(YES); */ break; /* smooth scroll */
  616.         case 'l': /* smoothMode(NO); */ break; /* jump scroll */
  617.         case 'i': printMode = NO; break;
  618.         }
  619.         break;
  620.     case 5: 
  621.         switch (c) {
  622.         case 'h':     /* reverseScreen(); */
  623.             break;
  624.         case 'l':     /* normalScreen(); */
  625.             break;
  626.         case 'i':    /* auto print mode */
  627.             printMode = YES;
  628.             printOn();
  629.             break; 
  630.         }
  631.         break;
  632.     case 6: 
  633.         if (c == 'h')            /* ESC [ ? 6 h */
  634.             originMode = YES;
  635.         else if (c == 'l')
  636.             originMode = NO;
  637.         break;
  638.     case 7: 
  639.         if (c == 'h')            /* ESC [ ? 7 h */
  640.             awMode(YES);        /* auto wrap    */
  641.         else if (c == 'l')
  642.             awMode(NO);        /* no auto wrap    */
  643.         break;
  644.     /* case 8: autoRepeatMode(); break;*/
  645.     case 25: 
  646.         if (c == 'h') {        /* ESC [ ? 25 h    */
  647.             cursor = YES;
  648.             cursorOnOff(YES);        /* cursor on    */
  649.          } else if (c == 'l') {        /* ESC [ ? 25 l */
  650.             cursor = NO;
  651.             cursorOnOff(NO);        /* cursor off    */
  652.         }
  653.         break;
  654.     case 47: 
  655.         if (c == 'h') {    /* ESC [ ? 47 h */
  656.             if (pageSaved == NO)
  657.                 savePage(ansiVramSave);
  658.             pageSaved = YES;
  659.         } else if (c == 'l') {
  660.             if (pageSaved)
  661.                 restorePage(ansiVramSave);
  662.             pageSaved = NO;
  663.         }
  664.         break;
  665. #ifdef FEP
  666.     case 98: 
  667.         if (c == 'h')        /* ESC [ ? 98 h */
  668.             fep_force_on();
  669.         else if (c == 'l')
  670.              fep_force_off();
  671.         break;
  672.     case 99: 
  673.         if (c == 'h')        /* ESC [ ? 99 h */
  674.             fep_on();
  675.         else if (c == 'l')
  676.              fep_off();
  677.         break;
  678. #endif /* FEP */
  679.     }
  680.     locate(cursorX, cursorY);
  681.     state = 0;
  682. }
  683.  
  684. #ifdef UOP_GRAPHICS
  685. /* expand for graphics */
  686. static void state16(c)
  687. /* after ESC R */
  688. u_short c;
  689. {
  690.     if (isdigit((char)c)) {    /* ESC R Pn        */
  691.         if (ai < MAX_PARAM)
  692.             val[ai] = val[ai]*10+(char)c-'0';
  693.         else
  694.             state = 0;
  695.         return;
  696.     } else if (c == ';') {    /* ESC R Pn ;        */
  697.         ai++;
  698.         return;
  699.     } else {
  700.         switch(c) {    /* ESC R Pm ; Pn c    */
  701.         case 't':    /* plot label */
  702.             state = 17;
  703.             return;
  704.         case 'm':    /* plot move */
  705.             plot_move(val[0],val[1]);
  706.             break;
  707.         case 'n':    /* plot cont */
  708.             plot_cont(val[0],val[1]);
  709.             break;
  710.         case 'p':    /* plot point */
  711.             plot_point(val[0],val[1]);
  712.             break;
  713.         case 'l':    /* plot line */
  714.             plot_line(val[0],val[1],val[2],val[3]);
  715.             break;
  716.         case 'b':    /* plot box */
  717.             plot_box(val[0],val[1],val[2],val[3]);
  718.             break;
  719.         case 'r':    /* plot box fill */
  720.             plot_boxfill(val[0],val[1],val[2],val[3]);
  721.             break;
  722.         case 'a':    /* plot arc */
  723.             plot_arc(val[0],val[1],val[2],val[3],val[4],val[5]);
  724.             break;
  725.         case 'c':    /* plot circle */
  726.             plot_circle(val[0],val[1],val[2]);
  727.             break;
  728.         case 'f':    /* plot linemod */
  729.             plot_linemod(val[0]);
  730.             break;
  731.         case 'x':    /* plot change color */
  732.             plot_colormod(val[0]);
  733.             break;
  734.         case 's':    /* plot space */
  735.             plot_space(val[0],val[1],val[2],val[3]);
  736.             break;
  737.         case 'e':    /* plot erase */
  738.             plot_erase();
  739.             break;
  740.         }
  741.         ai = 0;
  742.     }
  743.     state = 0;
  744. }
  745.  
  746. static void state17(c)
  747. /* after ESC R t */
  748. u_short c;
  749. {
  750.     static    int    i = 0;
  751.     static    u_char    buff[256];
  752.  
  753.     if(c == 0x01) {
  754. force:
  755.         buff[i] = (u_char)'\0';
  756.         plot_label(buff);
  757.         state = 0;
  758.         i = 0;
  759.     } else {
  760.         if (i > 254)
  761.             goto force;
  762.         buff[i++] = (u_char)c;
  763.     }
  764. }
  765.  
  766. #endif /* UOP_GRAPHICS */
  767.  
  768. #ifdef KANJI
  769.  
  770. static void state100(c)
  771. /* ESC $ */
  772. register u_short c;
  773. {
  774.     switch (c) {
  775.     case '@':            /* designate jis kanji 78 to G0    */
  776.     case 'B':            /* designate jis kanji 83 to G0    */
  777.     case '1':            /* designate DEC kanji to G0    */
  778.         state = 0;
  779.         kstate = 2;        /* enter kanji mode        */
  780.         kfirst = 0;        /* clear first byte of kanji    */
  781.         break;
  782.     case '(':
  783.         state = 101;
  784.         break;
  785.     case ')':
  786.         state = 103;
  787.         break;
  788.     default:
  789.         state = 0;
  790.         break;
  791.     }
  792. }
  793.  
  794. static void state101(c)
  795. /* ESC $ ( */
  796. register u_short c;
  797. {
  798.     switch (c) {
  799.     case '@':            /* designate jis kanji 78 to G0    */
  800.     case 'B':            /* designate jis kanji 83 to G0    */
  801.     case '1':            /* designate DEC kanji to G0    */
  802.         kstate = 2;        /* enter kanji mode        */
  803.         kfirst = 0;        /* clear first byte of kanji    */
  804.         break;
  805.     }
  806.     state = 0;
  807.     locate(cursorX, cursorY);
  808. }
  809.  
  810. static void state102(c)
  811. /* ESC ( */
  812. register u_short c;
  813. {
  814.     switch (c) {
  815.     case 'H':            /* designate Swedish to G0    */
  816.     case 'J':            /* designate jis roman to G0    */
  817.     case 'B':            /* designate ascii to G0    */
  818.         kstate = 0;        /* enter alpha mode        */
  819.         break;
  820.     case 'I':            /* designate jis kana to G0    */
  821.         kstate = 1;        /* enter kana mode        */
  822.         break;
  823.     case '0':            /* designate DEC special to G0    */
  824.         kstate = 3;        /* enter DEC special mode    */
  825.         break;
  826.     }
  827.     locate(cursorX, cursorY);
  828.     state = 0;
  829. }
  830.  
  831. static void state103()
  832. /* ESC $ ) */
  833. {
  834.     /* designate 2byte code to G1 (ignored) */
  835.     state = 0;
  836. }
  837.  
  838. static void state104()
  839. /* ESC ) */
  840. {
  841.     /* designate 1byte code to G1 (ignored) */
  842.     state = 0;
  843. }
  844.  
  845. #ifdef NEC_KANJI
  846.  
  847. static void state110(c)
  848. /* SUB */
  849. register u_short c;
  850. {
  851.     switch (c) {
  852.     case 'p':            /* designate nec kanji        */
  853.         kstate = 2;        /* enter kanji mode        */
  854.         kfirst = 0;        /* clear first byte of kanji    */
  855.         break;
  856.     case 'q':            /* designate nec alpha        */
  857.         kstate = 0;        /* enter alpha mode        */
  858.         break;
  859.     }
  860.     state = 0;
  861. }
  862. #endif /* NEC_KANJI */
  863.  
  864. #endif /* KANJI */
  865.  
  866. static void saveCursor()
  867. /* save Cursor position */
  868. {
  869.     saveX = cursorX;
  870.     saveY = cursorY;
  871.     saveAttr = attrib;
  872.     locate(cursorX, cursorY);
  873. }
  874.  
  875. static void restCursor()
  876.  /* restore cursor pos.    */
  877. {
  878.     attrib = saveAttr;
  879.     locate(saveX, saveY);
  880. }
  881.  
  882. static void setAttribute()
  883. {    
  884.     register int i, c;
  885.  
  886.     for (i = ai + 1, ai = 0; i > 0; --i) {
  887.         switch(c = val[ai++]) {
  888.         case 0:    /* normal mode        */
  889.             normalMode();
  890.             break;
  891.         case 1: /* high mode        */
  892. #ifdef PC98
  893.             attrib &= 0xcf;
  894.             attrib |= 0xc0;
  895. #else
  896.             attrib |= _HIGH;
  897. #endif
  898.             break;
  899.         case 4: /* underlined        */
  900. #ifdef PC98
  901.             attrib |= B_UNDER;
  902. #else
  903.             attrib |= _UNDER;
  904. #endif
  905.             break;
  906.         case 5: /* blink        */
  907. #ifdef PC98
  908.             attrib |= B_BLINK;
  909. #else
  910.             attrib |= _BLINK;
  911. #endif
  912.             break;
  913.         case 7:    /* reverse mode     */
  914.             reverseMode();
  915.             break;
  916.         default:
  917.             if (softFont)
  918.                 break;
  919. #ifdef PC98
  920.             if (30 <= c && c <= 37) { /* set foreground color */
  921.                 attrib &= CMASK;
  922.                 attrib |= ctab[c - 30];
  923.                 break;
  924.             }
  925.             if (40 <= c && c <= 47) { /* set background color */
  926.                 attrib &= CMASK;
  927.                 attrib |= ctab[c - 40] | _REVER;
  928.                 break;
  929.             }
  930. #endif /* PC98 */
  931. #ifdef IBMPC
  932.             if (30 <= c && c <= 37) { /* set foreground color */
  933.                 attrib &= FMASK;
  934.                 attrib |= fColor[c - 30];
  935.                 break;
  936.             }
  937.             if (40 <= c && c <= 47) { /* set background color */
  938.                 attrib &= BMASK;
  939.                 attrib |= bColor[c - 40];
  940.                 break;
  941.             }
  942. #endif /* IBMPC */
  943.             /*
  944.              * else ignore
  945.              */
  946.              break;
  947.         }
  948.     }
  949. }
  950.  
  951. /*
  952. ** normalMode()
  953.  *
  954.  * set attribute normal mode
  955.  */
  956. void normalMode()
  957. {
  958.     attrib = eraseAttr;
  959. }
  960.  
  961. /*
  962. ** reverseMode()
  963.  *
  964.  * set attribute reverse mode
  965.  */
  966. void reverseMode()
  967. {
  968. #ifdef IBMPC
  969.     /*
  970.      * back color to foreground color, foreground color to back ground color
  971.      */
  972.     if (softFont)
  973.         attrib |= 0x10;
  974.     else {
  975.         attrib &= 0x88;
  976.         attrib |= ((eraseAttr & 0x70)>>4 | (eraseAttr & 0x07) << 4);
  977.     }
  978. #endif /* IBMPC */
  979. #ifdef J3100
  980.     attrib |= _REVER;
  981. #endif /* J3100 */
  982. #ifdef PC98
  983.     if (eraseAttr & B_REVER)
  984.         attrib &= ~B_REVER;
  985.     else
  986.         attrib |= B_REVER;
  987. #endif /* PC98 */
  988. }
  989.  
  990. static void eraseScreen()
  991. /*
  992.  * erase within screen 
  993.  */
  994. {
  995.     register u_short tmpX, tmpY;
  996.     
  997.     wrapPending = NO;
  998.     tmpX = cursorX;
  999.     tmpY = cursorY;
  1000.     switch(val[0]) {
  1001.     case 0:        /* erase from cursor to end of screen    */
  1002.         clearColumn(cursorX, MAX_COLUMN);
  1003.         if (cursorY < bottomLine)
  1004.             clearLine(cursorY+1, bottomLine);
  1005.         break;
  1006.     case 1:     /* erase from top of screen to cursor    */
  1007.         if (cursorY > 0)
  1008.             clearLine(0, cursorY-1);
  1009.         clearColumn(0, cursorX+1);    /* erase column on cursor too    */
  1010.         break;
  1011.     case 2:     /* erase entire screen            */
  1012.         clearLine(0, bottomLine);
  1013.         tmpX = tmpY = 0;
  1014.         break;
  1015.     }
  1016.     locate(tmpX, tmpY);
  1017. }
  1018.  
  1019. static void eraseLine()
  1020. /*
  1021.  * erase within line 
  1022.  */
  1023. {            
  1024.     register u_short tmpX, tmpY;
  1025.     
  1026.     wrapPending = NO;
  1027.     tmpX = cursorX;
  1028.     tmpY = cursorY;
  1029.     switch(val[0]) {
  1030.     case 0:        /* erase from cursor to end of line    */
  1031.         clearColumn(cursorX, MAX_COLUMN);
  1032.         break;
  1033.     case 1:        /* erase from start of line to cursor    */
  1034.         clearColumn(0, cursorX+1);
  1035.         break;
  1036.     case 2:        /* erase entire line            */
  1037.         clearColumn(0, MAX_COLUMN);
  1038.         break;
  1039.     }
  1040.     locate(tmpX, tmpY);
  1041. }
  1042.  
  1043. static void cursorPosition()
  1044. /* set direct cursor position */
  1045. {
  1046.     register short x = val[1] - 1;
  1047.     register short y = val[0] - 1;
  1048.     
  1049.     wrapPending = NO;
  1050.     if (x <= 0)
  1051.         x = 0;
  1052.     if (x > LAST_COLUMN)
  1053.         x = LAST_COLUMN;
  1054.     if (y <= 0)
  1055.         y = 0;
  1056.     if (originMode) {
  1057.         if ((y += upScrRegion) > lowScrRegion)
  1058.             y = lowScrRegion;
  1059.     } else {
  1060.         if (y > bottomLine)
  1061.             y = bottomLine;
  1062.     }
  1063.     locate(x, y);
  1064. }
  1065.  
  1066. static void scrollRegion()
  1067. /* set scroll region */
  1068. {
  1069.     register short up = val[0] - 1;
  1070.     register short low = val[1] - 1;
  1071.  
  1072.     if (up <= 0)
  1073.         up = 0;
  1074.     else if (up > bottomLine)
  1075.         up = bottomLine;
  1076.     if (low < 0 || low > bottomLine)
  1077.         low = bottomLine;
  1078.     if (low < up)
  1079.         return;            /* illegal request, ignore ???    */
  1080.     upScrRegion = up; lowScrRegion = low;
  1081.     savePage(page0Save);
  1082.     restorePage(page0Save);
  1083.     if (originMode) 
  1084.         locate(upScrRegion, 0);
  1085.     else
  1086.         locate(0, 0);
  1087.     cursorOnOff(cursor);
  1088. }
  1089.  
  1090. static void downLine()
  1091. {
  1092.     wrapPending = NO;
  1093.     if (cursorX > LAST_COLUMN)
  1094.         cursorX = 0;
  1095.     if (cursorY < lowScrRegion)
  1096.         cursorY++;
  1097.     else if (cursorY == lowScrRegion)
  1098.         scrlUp();
  1099.     else if (cursorY < bottomLine)
  1100.         cursorY++;
  1101.     locate(cursorX, cursorY);
  1102. }
  1103.  
  1104. static void upLine()
  1105. {
  1106.     wrapPending = NO;
  1107.     if (cursorX > LAST_COLUMN)
  1108.         cursorX = 0;
  1109.     if (cursorY > upScrRegion)
  1110.         cursorY--;
  1111.     else if (cursorY == upScrRegion) {
  1112.         insertLine(1);
  1113.     } else if (cursorY > 0)
  1114.         cursorY--;
  1115.     locate(cursorX, cursorY);
  1116. }
  1117.  
  1118. static void cursorReport()
  1119. {
  1120.     int i;
  1121.  
  1122.     for (i = ai + 1, ai = 0; i > 0; --i) {
  1123.         switch (val[ai++]) {
  1124.         case 5:        /* are you OK? */
  1125.             outESC("[0n");    /* always OK */
  1126.             break;
  1127.         case 6:        /* cursor position report */
  1128.             sprintf(tmpBuf, "[%d;%dR", cursorY+1, cursorX+1);
  1129.             outESC(tmpBuf);
  1130.             break;
  1131.         }
  1132.         /* else ignore */
  1133.     }
  1134. }
  1135.