home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume4 / se / part4 / term.c < prev   
Encoding:
C/C++ Source or Header  |  1986-11-30  |  32.3 KB  |  1,884 lines

  1. /*
  2. ** term.c
  3. **
  4. ** provide terminal functions for se
  5. **
  6. ** If HARD_TERMS is *not* defined, which is the default, se will
  7. ** use the termlib library, which provides terminal independant operations.
  8. ** This makes se both smaller, and more flexible.
  9. **
  10. ** If HARD_TERMS is defined, then se will use the original code, which
  11. ** had terminal types hard-wired into the code.  This would be useful for
  12. ** a system which does not have the termlib library.
  13. **
  14. ** On System V systems, we have two possibilities.  Release 1 did not have
  15. ** the terminfo package, so we assume that if it is Release 1, someone will
  16. ** have ported the BSD termlib library.  If it is Release 2, then the new
  17. ** terminfo package is there, and we wil use it.
  18. */
  19.  
  20. #include "se.h"
  21. #include "extern.h"
  22.  
  23. #ifndef HARD_TERMS
  24.  
  25. int outc ();    /* defined later */
  26.  
  27. #if defined (BSD) || !defined (S5R2)
  28. /*
  29.  * code for using BSD termlib -- getting capabilities, and writing them out.
  30.  */
  31.  
  32. /* capabilities from termcap */
  33.  
  34. static int AM;        /* automatic margins, i.e. wraps at column 80 */
  35.  
  36. static char *VS;    /* visual start -- e.g. clear status line */
  37. static char *VE;    /* visual end -- e.g. restore status line */
  38. static char *TI;    /* terminal init -- whatever needed for screen ops */
  39. static char *TE;    /* terminal ops end */
  40. static char *CM;    /* cursor motion, used by tgoto() */
  41. static char *CE;    /* clear to end of line */
  42. static char *DL;    /* hardware delete line */
  43. static char *AL;    /* hardware add (insert) line */
  44. static char *CL;    /* clear screen */
  45.  
  46. extern char PC;        /* Pad character, usually '\0' */
  47.  
  48. static char *pcstr;
  49. extern char *tgoto (), *tgetstr ();    /* termlib routines */
  50.  
  51. static char caps[128];        /* space for decoded capability strings */
  52. static char *addr_caps;        /* address of caps for relocation */
  53.  
  54. #define TERMBUFSIZ    1024+1
  55. static char termbuf[TERMBUFSIZ];
  56.  
  57.  
  58.  
  59. /* setterm -- initialize terminal parameters and actual capabilities */
  60.  
  61. static setterm (type)
  62. char *type; 
  63. {
  64.     if (type[0] == EOS)
  65.     {
  66.         ttynormal ();
  67.         fprintf (stderr, "in setterm: can't happen.\n");
  68.         exit (1);
  69.     }
  70.  
  71.     Ncols = Nrows = 0;
  72.  
  73.     /*
  74.      * we used to set certain mininum and maximum screen sizes,
  75.      * but since we could end up on things like ATT 5620s, with big
  76.      * screens, we just do it dynamically, but add some error
  77.      * checking, and exit if can't do it.
  78.      */
  79.     Nrows = tgetnum ("li");
  80.     Ncols = tgetnum ("co");
  81.  
  82.     if (Nrows == -1)
  83.     {
  84.         ttynormal ();
  85.         fprintf (stderr, "se: could not determine number of rows\n");
  86.         exit (1);
  87.     }
  88.  
  89.     if (Ncols == -1)
  90.     {
  91.         ttynormal ();
  92.         fprintf (stderr, "se: could not determine number of columns\n");
  93.         exit (1);
  94.     }
  95.  
  96.     
  97.     addr_caps = caps;
  98.  
  99.     getdescrip ();            /* get terminal description */
  100.  
  101.     if (*tgoto (CM, 0, 0) == 'O')    /* OOPS returned.. */
  102.         CM = 0;
  103.  
  104.     PC = pcstr ? pcstr[0] : EOS;
  105.  
  106.     if (CM == 0)
  107.     {
  108.         ttynormal ();
  109.         fprintf (stderr, "se: terminal does not have cursor motion.\n");
  110.         exit (2);
  111.     }
  112.  
  113.     return OK;
  114. }
  115.  
  116. /* getdescrip --- get descriptions out of termcap entry */
  117.  
  118. static getdescrip ()
  119. {
  120.     int i;
  121.     static struct _table {
  122.         char *name;
  123.         char **ptr_to_cap;
  124.         } table[] = {
  125.             "vs",    & VS,
  126.             "ve",    & VE,
  127.             "ti",    & TI,
  128.             "te",    & TE,
  129.             "cm",    & CM,
  130.             "ce",    & CE,
  131.             "dl",    & DL,
  132.             "al",    & AL,
  133.             "cl",    & CL,
  134.             "pc",    & pcstr,
  135.             NULL,    NULL
  136.             };
  137.  
  138.     AM = tgetflag ("am");        /* only boolean se needs */
  139.  
  140.     /* get string values */
  141.  
  142.     for (i = 0; table[i].name != NULL; i++)
  143.         *(table[i].ptr_to_cap) = tgetstr (table[i].name, & addr_caps);
  144. }
  145.  
  146.  
  147. /* setcaps -- get the capabilities from termcap file into termbuf */
  148.  
  149. setcaps (term)
  150. char *term;
  151. {
  152.     switch (tgetent (termbuf, term)) {
  153.     case -1:
  154.         ttynormal ();
  155.         fprintf (stderr, "se: couldn't open termcap file.\n");
  156.         return (ERR);
  157.  
  158.     case 0:
  159.         ttynormal ();
  160.         fprintf (stderr, "se: no termcap entry for %s terminals.\n", term);
  161.         return (ERR);
  162.  
  163.     case 1:
  164.         break;
  165.  
  166.     default:
  167.         error ("in setcaps: can't happen.\n");
  168.     }
  169.  
  170.     return (OK);
  171. }
  172.  
  173. #else
  174.  
  175. /* use the new terminfo package */
  176. /*
  177.  * Do NOT include <curses.h>, since it redefines
  178.  * USG, ERR, and OK, to values inconsisten with what
  179.  * we use.
  180.  */
  181.  
  182. /* fix a problem in /usr/include/term.h */
  183. #include <termio.h>
  184. typedef struct termio SGTTY;
  185.  
  186. #include <term.h>    /* should be all we really need */
  187.  
  188. #define AM    auto_right_margin
  189. #define TI    enter_ca_mode
  190. #define TE    exit_ca_mode
  191. #define VS    cursor_visible
  192. #define VE    cursor_normal
  193. #define CL    clear_screen
  194. #define CE    clr_eol
  195. #define DL    delete_line
  196. #define AL    insert_line
  197.  
  198. /* setcaps --- called from main() to get capabilities */
  199.  
  200. setcaps (term)
  201. char *term;
  202. {
  203.     int ret = 0;
  204.  
  205.     setupterm (term, 1, & ret);
  206.     if (ret != 1)
  207.         return (ERR);
  208.     Nrows = lines;
  209.     Ncols = columns;
  210.     return (OK);
  211. }
  212.  
  213. #endif
  214.  
  215. /* outc -- write a character to the terminal */
  216.  
  217. int outc (c)
  218. char c;
  219. {
  220.     twrite (1, &c, 1);
  221. }
  222.  
  223. /* t_init -- put out terminal initialization string */
  224.  
  225. t_init ()
  226. {
  227.     if (VS)
  228.         tputs (VS, 1, outc);
  229.     if (TI)
  230.         tputs (TI, 1, outc);    /* terminal initializations */
  231. }
  232.  
  233. /* t_exit -- put out strings to turn off whatever modes we had turned on */
  234.  
  235. t_exit ()
  236. {
  237.     /* terminal exiting strings */
  238.     if (TE)
  239.         tputs (TE, 1, outc);
  240.     if (VE)
  241.         tputs (VE, 1, outc);
  242.     tflush ();    /* force it out */
  243. }
  244. #endif
  245.  
  246. /* send --- send a printable character, predict cursor position */
  247.  
  248. send (chr)
  249. char chr;
  250. {
  251.     if (Currow == Nrows - 1 && Curcol == Ncols - 1)
  252.         return;         /* anything in corner causes scroll... */
  253.  
  254. #ifndef HARD_TERMS
  255.     outc (chr);
  256. #else
  257.     twrite (1, &chr, 1);
  258. #endif
  259.  
  260.     if (Curcol == Ncols - 1)
  261.     {
  262. #ifndef HARD_TERMS
  263.         if (AM)        /* terminal wraps when hits last column */
  264. #else
  265.         if (Term_type != TVT && Term_type != NETRON
  266.             && Term_type != ESPRIT && Term_type != VI300)
  267. #endif
  268.         {
  269.             Curcol = 0;
  270.             Currow++;
  271.         }
  272.     }
  273.     else        /* cursor not at extreme right */
  274.         Curcol++;
  275. }
  276.  
  277. /* terminal handling functions used throughout the editor */
  278.  
  279. /* clrscreen --- clear entire screen */
  280.  
  281. clrscreen ()
  282. {
  283.     Curcol = Currow = 0;
  284.     /* clearing screen homes cursor to upper left corner */
  285.     /* on all terminals */
  286.  
  287. #ifndef HARD_TERMS
  288.     tputs (CL, 1, outc);
  289. #else
  290.     switch (Term_type) {
  291.     case ADDS980:
  292.     case ADDS100:
  293.     case GT40:
  294.     case CG:
  295.     case ISC8001:
  296.     case ANP:
  297.     case NETRON:
  298.         twrite (1, "\014", 1);
  299.         break;
  300.     case FOX:
  301.         twrite (1, "\033K", 2);        /* clear display and all tabs */
  302.         break;
  303.     case TVT:
  304.         twrite (1, "\014\017", 2);    /* home, erase to end of screen */
  305.         break;
  306.     case BEE150:
  307.     case BEE200:
  308.     case SBEE:
  309.     case SOL:
  310.     case H19:
  311.         twrite (1, "\033E", 2);
  312.         break;
  313.     case HAZ1510:
  314.     case ESPRIT:
  315.         twrite (1, "\033\034", 2);
  316.         break;
  317.     case ADM3A:
  318.     case VC4404:
  319.     case TVI950:
  320.         twrite (1, "\032", 1);
  321.         break;
  322.     case TS1:
  323.         twrite (1, "\033*", 2);
  324.         break;
  325.     case ADM31:
  326.         twrite (1, "\033+", 2);
  327.         break;
  328.     case IBM:
  329.         twrite (1, "\033L", 2);
  330.         break;
  331.     case HP21:
  332.         twrite (1, "\033H\033J", 4);    /* home cursor, erase to end of screen */
  333.         break;
  334.     case TRS80:
  335.         twrite (1, "\034\037", 2);
  336.         break;
  337.     case VI200:
  338.         twrite (1, "\033v", 2);
  339.         break;
  340.     case VI300:
  341.         twrite (1, "\033[H\033[J", 6);
  342.         /* home cursor, clear screen */
  343.         break;
  344.     case VI50:
  345.         twrite (1, "\033v", 2);
  346.         senddelay (30);
  347.         break;
  348.     }
  349.  
  350.     senddelay (20);
  351. #endif
  352. }
  353.  
  354.  
  355. /* position_cursor --- position terminal's cursor to (row, col) */
  356.  
  357. position_cursor (row, col)
  358. int row, col;
  359. {
  360.     if (row < Nrows && row >= 0        /* within vertical range? */
  361.         && col < Ncols && col >= 0        /* within horizontal range? */
  362.         && (row != Currow || col != Curcol))/* not already there? */
  363. #ifndef HARD_TERMS
  364.     {
  365.         if (row == Currow && abs (Curcol - col) <= 4)
  366.         {
  367.             /* short motion in current line */
  368.             if (Curcol < col)
  369.                 for (; Curcol != col; Curcol++)
  370.                     twrite (1, &Screen_image[Currow][Curcol], 1);
  371.             else
  372.                 for (; Curcol != col; Curcol--)
  373.                     twrite (1, "\b", 1);
  374.         }
  375.         else
  376.         {
  377. #if defined (USG) && defined(S5R2)
  378.             tputs (tparm (cursor_address, row, col), 1, outc);
  379. #else
  380.             tputs (tgoto (CM, col, row), 1, outc);
  381. #endif
  382.             Currow = row;
  383.             Curcol = col;
  384.         }
  385.     }
  386. #else
  387.         switch (Term_type) {
  388.         case ADDS980:
  389.             addspos (row, col);
  390.             break;
  391.         case ADDS100:
  392.             regentpos (row, col);
  393.             break;
  394.         case HP21:
  395.             hp21pos (row, col);
  396.             break;
  397.         case FOX:
  398.             pepos (row, col);
  399.             break;
  400.         case TVT:
  401.             tvtpos (row, col);
  402.             break;
  403.         case GT40:
  404.             gt40pos (row, col);
  405.             break;
  406.         case BEE150:
  407.         case BEE200:
  408.         case SBEE:
  409.         case SOL:
  410.             beepos (row, col);
  411.             break;
  412.         case VC4404:
  413.             vcpos (row, col);
  414.             break;
  415.         case HAZ1510:
  416.             hazpos (row, col);
  417.             break;
  418.         case ESPRIT:
  419.             espritpos (row, col);
  420.             break;
  421.         case CG:
  422.             cgpos (row, col);
  423.             break;
  424.         case ISC8001:
  425.             iscpos (row, col);
  426.             break;
  427.         case ADM3A:
  428.         case ADM31:
  429.         case TS1:
  430.         case TVI950:
  431.             admpos (row, col);
  432.             break;
  433.         case IBM:
  434.             ibmpos (row, col);
  435.             break;
  436.         case ANP:
  437.             anppos (row, col);
  438.             break;
  439.         case NETRON:
  440.             netpos (row, col);
  441.             break;
  442.         case H19:
  443.             h19pos (row, col);
  444.             break;
  445.         case TRS80:
  446.             trspos (row, col);
  447.             break;
  448.         case VI200:  
  449.         case VI50:
  450.             vipos (row, col);
  451.             break;
  452.         case VI300:
  453.             ansipos (row, col);
  454.             break;
  455.         }
  456. #endif
  457. }
  458.  
  459.  
  460. /* setscreen --- initialize screen and associated descriptive variables */
  461.  
  462. setscreen ()
  463. {
  464.     register int row, col;
  465.  
  466. #ifndef HARD_TERMS
  467.     char *getenv ();
  468.  
  469. #if defined (BSD) || !defined (S5R2)
  470.     setterm (getenv ("TERM"));
  471. #endif
  472.  
  473.     t_init ();    /* put out the 'ti' and 'vs' capabilities */
  474. #else
  475.     switch (Term_type) {
  476.     case ADDS980: 
  477.     case FOX: 
  478.     case HAZ1510: 
  479.     case ADDS100:
  480.     case BEE150: 
  481.     case ADM3A: 
  482.     case IBM: 
  483.     case HP21: 
  484.     case H19:
  485.     case ADM31: 
  486.     case VI200: 
  487.     case VC4404: 
  488.     case ESPRIT: 
  489.     case TS1:
  490.     case TVI950: 
  491.     case VI50: 
  492.     case VI300:
  493.         Nrows = 24;
  494.         Ncols = 80;
  495.         break;
  496.     case ANP:
  497.         Nrows = 24;
  498.         Ncols = 96;
  499.         break;
  500.     case SOL: 
  501.     case NETRON: 
  502.     case TRS80:
  503.         Nrows = 16;
  504.         Ncols = 64;
  505.         break;
  506.     case TVT:
  507.         Nrows = 16;
  508.         Ncols = 63;
  509.         break;
  510.     case GT40:
  511.         Nrows = 32;
  512.         Ncols = 73;
  513.         break;
  514.     case CG:
  515.         Nrows = 51;
  516.         Ncols = 85;
  517.         break;
  518.     case ISC8001:
  519.         Nrows = 48;
  520.         Ncols = 80;
  521.         break;
  522.     case BEE200: 
  523.     case SBEE:
  524.         Nrows = 25;
  525.         Ncols = 80;
  526.         break;
  527.     }
  528. #endif
  529.     clrscreen ();    /* clear physical screen, set cursor position */
  530.  
  531.     Toprow = 0;
  532.     Botrow = Nrows - 3; /* 1 for 0-origin, 1 for status, 1 for cmd */
  533.     Cmdrow = Botrow + 1;
  534.     Topln = 1;
  535.     Sclen = -1;         /* make sure we assume nothing on the screen */
  536.  
  537.     for (row = 0; row < Nrows; row++)    /* now clear virtual screen */
  538.         for (col = 0; col < Ncols; col++)
  539.             Screen_image[row][col] = ' ';
  540.  
  541.     for (col = 0; col < Ncols; col++)    /* and clear out status line */
  542.         Msgalloc[col] = NOMSG;
  543.  
  544.     Insert_mode = NO;
  545. }
  546.  
  547.  
  548. /* inslines --- insert 'n' lines on the screen at 'row' */
  549.  
  550. inslines (row, n)
  551. int row, n;
  552. {
  553.     register int i;
  554.     int delay;
  555.  
  556.     position_cursor (row, 0);
  557. #ifdef HARD_TERMS
  558.     if (Term_type == VI300)
  559.     {
  560.         char pseq[10];
  561.         register int pp = 0;
  562.         pseq[pp++] = '\033';
  563.         pseq[pp++] = '[';
  564.         if (n >= 10)
  565.             pseq[pp++] = '0' + n / 10;
  566.         pseq[pp++] = '0' + n % 10;
  567.         pseq[pp++] = 'L';
  568.         twrite (1, pseq, pp);
  569.         delay = 0;
  570.     }
  571.     else
  572. #endif
  573.         for (i = 0; i < n; i++)
  574.         {
  575. #ifndef HARD_TERMS
  576.             tputs (AL, n, outc);
  577.             tflush ();
  578. #else
  579.             switch (Term_type) {
  580.             case VI200:
  581.                 twrite (1, "\033L", 2);
  582.                 delay = 0;
  583.                 break;
  584.             case VI50:
  585.             case H19:
  586.                 twrite (1, "\033L", 2);
  587.                 delay = 32;
  588.                 break;
  589.             case ESPRIT:
  590.                 twrite (1, "\033\032", 2);
  591.                 delay = 32;
  592.                 break;
  593.             case TS1:
  594.             case TVI950:
  595.                 twrite (1, "\033E", 2);
  596.                 delay = 0;
  597.                 break;
  598.             case ADDS100:
  599.                 twrite (1, "\033M", 2);
  600.                 delay = 96;
  601.                 break;
  602.             default:
  603.                 error ("in inslines: shouldn't happen");
  604.             }
  605.  
  606.             if (delay != 0)
  607.                 senddelay (delay);
  608. #endif
  609.         }
  610.  
  611.     for (i = Nrows - 1; i - n >= Currow; i--)
  612.         move_ (Screen_image[i - n], Screen_image[i], Ncols);
  613.  
  614.     for (; i >= Currow; i--)
  615.         move_ (Blanks, Screen_image[i], Ncols);
  616. }
  617.  
  618.  
  619. /* dellines --- delete 'n' lines beginning at 'row' */
  620.  
  621. dellines (row, n)
  622. int row, n;
  623. {
  624.     register int i;
  625.     int delay;
  626.  
  627.     position_cursor (row, 0);
  628. #ifdef HARD_TERMS
  629.     if (Term_type == VI300)
  630.     {
  631.         char pseq[10];
  632.         register int pp = 0;
  633.         pseq[pp++] = '\033';
  634.         pseq[pp++] = '[';
  635.         if (n >= 10)
  636.             pseq[pp++] = '0' + n / 10;
  637.         pseq[pp++] = '0' + n % 10;
  638.         pseq[pp++] = 'M';
  639.         twrite (1, pseq, pp);
  640.         delay = 0;
  641.     }
  642.     else
  643. #endif
  644.         for (i = 0; i < n; i++)
  645.         {
  646. #ifndef HARD_TERMS
  647.             tputs (DL, n, outc);
  648.             tflush ();
  649. #else
  650.             switch (Term_type) {
  651.             case VI200:
  652.                 twrite (1, "\033M", 2);
  653.                 delay = 0;
  654.                 break;
  655.             case VI50:
  656.                 twrite (1, "\033M", 2);
  657.                 delay = 32;
  658.                 break;
  659.             case H19:
  660.                 twrite (1, "\033M", 2);
  661.                 delay = 32;
  662.                 break;
  663.             case TS1:
  664.             case TVI950:
  665.                 twrite (1, "\033R", 2);
  666.                 delay = 0;
  667.                 break;
  668.             case ESPRIT:
  669.                 twrite (1, "\033\023", 2);
  670.                 delay = 32;
  671.                 break;
  672.             case ADDS100:
  673.                 twrite (1, "\033l", 2);
  674.                 delay = 96;
  675.                 break;
  676.             default:
  677.                 error ("in dellines: shouldn't happen");
  678.             }
  679.  
  680.             if (delay != 0)
  681.                 senddelay (delay);
  682. #endif
  683.         }
  684.  
  685.     for (i = Currow; i + n < Nrows; i++)
  686.         move_ (Screen_image[i + n], Screen_image[i], Ncols);
  687.  
  688.     for (; i < Nrows; i++)
  689.         move_ (Blanks, Screen_image[i], Ncols);
  690. }
  691.  
  692.  
  693. /* hwinsdel --- return 1 if the terminal has hardware insert/delete */
  694.  
  695. int hwinsdel ()
  696. {
  697.     if (No_hardware == YES)
  698.         return (NO);
  699.  
  700. #ifndef HARD_TERMS
  701.     return (AL != NULL && DL != NULL);
  702. #else
  703.     switch (Term_type) {
  704.     case VI300:
  705.     case VI200:
  706.     case VI50:
  707.     case ESPRIT:
  708.     case H19:
  709.     case TS1:
  710.     case TVI950:
  711.     case ADDS100:
  712.         return 1;
  713.     }
  714.     return 0;
  715. #endif
  716. }
  717.  
  718.  
  719. /* clear_to_eol --- clear screen to end-of-line */
  720.  
  721. clear_to_eol (row, col)
  722. int row, col;
  723. {
  724.     register int c, flag; 
  725. #ifdef HARD_TERMS
  726.     register int hardware;
  727.  
  728.     switch (Term_type) {
  729.     case BEE200:
  730.     case BEE150:
  731.     case FOX:
  732.     case SBEE:
  733.     case ADDS100:
  734.     case HP21:
  735.     case IBM:
  736.     case ANP:
  737.     case NETRON:
  738.     case H19:
  739.     case TS1:
  740.     case TRS80:
  741.     case ADM31:
  742.     case VI200:
  743.     case VI300:
  744.     case VI50:
  745.     case VC4404:
  746.     case ESPRIT:
  747.     case TVI950:
  748.         hardware = YES;
  749.         break;
  750.     default:
  751.         hardware = NO;
  752.         if (Term_type == ADDS980 && row < Nrows - 1)
  753.             hardware = YES;
  754.         if (Term_type == TVT && row > 0)
  755.             hardware = YES;
  756.     }
  757. #endif
  758.  
  759.     flag = NO;
  760.  
  761.     for (c = col; c < Ncols; c++)
  762.         if (Screen_image[row][c] != ' ')
  763.         {
  764.             Screen_image[row][c] = ' ';
  765. #ifndef HARD_TERMS
  766.             if (CE != NULL)        /* there is hardware */
  767. #else
  768.             if (hardware == YES)
  769. #endif
  770.                 flag = YES;
  771.             else
  772.             {
  773.                 position_cursor (row, c);
  774.                 send (' ');
  775.             }
  776.         }
  777.  
  778.     if (flag == YES)
  779.     {
  780.         position_cursor (row, col);
  781. #ifndef HARD_TERMS
  782.         tputs (CE, 1, outc);
  783. #else
  784.         switch (Term_type) {
  785.         case BEE200: 
  786.         case BEE150:
  787.         case SBEE:
  788.         case ADDS100:
  789.         case HP21:
  790.         case H19:
  791.         case VC4404:
  792.         case TS1:
  793.         case TVI950:
  794.         case VI50:
  795.             twrite (1, "\033K", 2);
  796.             break;
  797.         case FOX:
  798.         case IBM:
  799.             twrite (1, "\033I", 2);
  800.             break;
  801.         case ADDS980:
  802.             twrite (1, "\n", 1);
  803.             Currow++;
  804.             Curcol = 0;
  805.             break;
  806.         case ANP:
  807.             twrite (1, "\033L", 2);
  808.             break;
  809.         case NETRON:
  810.             twrite (1, "\005", 1);
  811.             break;
  812.         case TRS80:
  813.             twrite (1, "\036", 1);
  814.             break;
  815.         case ADM31:
  816.             twrite (1, "\033T", 2);
  817.             break;
  818.         case VI200:
  819.             twrite (1, "\033x", 2);
  820.             break;
  821.         case VI300:
  822.             twrite (1, "\033[K", 3);
  823.             break;
  824.         case ESPRIT:
  825.             twrite (1, "\033\017", 2);
  826.             break;
  827.         case TVT:
  828.             twrite (1, "\013\012", 2);
  829.             break;
  830.         } /* end switch */
  831. #endif
  832.     } /* end if (flag == YES) */
  833. } /* end clear_to_eol */
  834.  
  835.  
  836. #ifdef HARD_TERMS
  837.  
  838. /* begin terminal dependant routines */
  839.  
  840. /* addspos --- position cursor to (row, col) on ADDS Consul 980 */
  841.  
  842. static addspos (row, col)
  843. int row, col;
  844. {
  845.     char coord;
  846.     int ntabs, where;
  847.  
  848.     if (Currow != row || col < Curcol - 7)
  849.     {
  850.         twrite (1, "\013", 1);    /* VT */
  851.         coord = '@' + row;
  852.         twrite (1, &coord, 1);
  853.         Currow = row;
  854.         Curcol = 0;
  855.     }
  856.  
  857.     if (col > Curcol + 2)
  858.     {
  859.         ntabs = (col + 2) / 5;    /* from beginning */
  860.         where = ntabs * 5;
  861.         ntabs -= Curcol / 5;    /* from Curcol */
  862.         if (ntabs + abs (where - col) <= 4)
  863.         {
  864.             for (; ntabs > 0; ntabs--)
  865.                 twrite (1, "\t", 1);
  866.             Curcol = where;
  867.         }
  868.     }
  869.  
  870.     if (col > Curcol + 4)
  871.     {
  872.         where = col - Curcol;
  873.         twrite (1, "\033\005", 2);    /* ESC ENQ */
  874.         coord = '0' + (where / 10);
  875.         twrite (1, &coord, 1);
  876.         coord = '0' + (where % 10);
  877.         twrite (1, &coord, 1);
  878.         Curcol = col;
  879.     }
  880.  
  881.     while (Curcol < col)
  882.     {
  883.         twrite (1, &Screen_image[Currow][Curcol], 1);
  884.         Curcol++;
  885.     }
  886.  
  887.     while (Curcol > col)
  888.     {
  889.         twrite (1, "\b", 1);
  890.         Curcol--;
  891.     }
  892. }
  893.  
  894. /* admpos --- position cursor to (row, col) on ADM-3A and ADM-31 terminals */
  895.  
  896. static admpos (row, col)
  897. int row, col;
  898. {
  899.     int dist;
  900.     char coord;
  901.  
  902.     dist = col - Curcol;
  903.     if (dist < 0)
  904.         dist = -dist;
  905.     if (row == Currow && dist < 4)  /* 4 chars for abs. position */
  906.     {
  907.         while (Curcol < col)
  908.         {
  909.             twrite (1, &Screen_image[Currow][Curcol], 1);
  910.             Curcol++;
  911.         }
  912.         while (Curcol > col)
  913.         {
  914.             twrite (1, "\b", 1);
  915.             Curcol--;
  916.         }
  917.     }
  918.     else
  919.     {
  920.         twrite (1, "\033=", 2);
  921.         coord = row + ' ';
  922.         twrite (1, &coord, 1);
  923.         coord = col + ' ';
  924.         twrite (1, &coord, 1);
  925.         Currow = row;
  926.         Curcol = col;
  927.     }
  928. }
  929.  
  930.  
  931.  
  932. /* ansipos --- position cursor on ANSI X something-or-other terminals */
  933.  
  934. static ansipos (row, col)
  935. register int row, col;
  936. {
  937.     register int dist;
  938.  
  939.     char absseq[20], relseq[50];
  940.     int absp = 0;
  941.     register int relp = 0;
  942.     register int trow, tcol;
  943.  
  944.     /*** Build relative positioning string--handle row first ***/
  945.     trow = Currow; 
  946.     tcol = Curcol;
  947.     if (row >= trow && row <= trow + 3)
  948.         for (; trow < row; trow++)
  949.             relseq[relp++] = '\012';
  950.     else if (row < trow && row >= trow - 1)
  951.         for (; trow > row; trow--)
  952.         { 
  953.             relseq[relp++] = '\033'; 
  954.             relseq[relp++] = 'M'; 
  955.         }
  956.     else if (row >= trow)
  957.     {
  958.         relseq[relp++] = '\033';
  959.         relseq[relp++] = '[';
  960.         dist = row - trow;
  961.         if (dist >= 10)
  962.             relseq[relp++] = '0' + dist / 10;
  963.         relseq[relp++] = '0' + dist % 10;
  964.         relseq[relp++] = 'B';
  965.         trow = row;
  966.     }
  967.     else /* row < trow */
  968.     {
  969.         relseq[relp++] = '\033';
  970.         relseq[relp++] = '[';
  971.         dist = trow - row;
  972.         if (dist >= 10)
  973.             relseq[relp++] = '0' + dist / 10;
  974.         relseq[relp++] = '0' + dist % 10;
  975.         relseq[relp++] = 'A';
  976.         trow = row;
  977.     }
  978.  
  979.     /*** Now do the column part of relative positioning ***/
  980.     if (col >= tcol - 2 && col <= tcol + 2)
  981.         ;       /* skip coarse positioning -- just do the fine stuff */
  982.     else
  983.     {
  984.         if (col <= 4)
  985.         {
  986.             relseq[relp++] = '\015';
  987.             tcol = 0;
  988.         }
  989.         dist = col - tcol;
  990.         if (col < 72 && dist > 2
  991.             && dist < 8 && (col + 1) % 8 <= 2)
  992.         {
  993.             relseq[relp++] = '\t';
  994.             tcol = ((tcol + 8) / 8) * 8;
  995.         }
  996.     }
  997.     dist = col - tcol;
  998.     if (dist < 0)
  999.         dist = -dist;
  1000.     if (dist == 0)
  1001.         ;
  1002.     else if (dist < 4)  /* 4 chars for abs. position */
  1003.     {
  1004.         while (tcol < col)
  1005.         {
  1006.             relseq[relp++] = Screen_image[trow][tcol];
  1007.             tcol++;
  1008.         }
  1009.         while (tcol > col)
  1010.         {
  1011.             relseq[relp++] = '\b';
  1012.             tcol--;
  1013.         }
  1014.     }
  1015.     else if (col >= tcol)
  1016.     {
  1017.         relseq[relp++] = '\033';
  1018.         relseq[relp++] = '[';
  1019.         if (dist >= 10)
  1020.             relseq[relp++] = '0' + dist / 10;
  1021.         relseq[relp++] = '0' + dist % 10;
  1022.         relseq[relp++] = 'C';
  1023.         tcol = col;
  1024.     }
  1025.     else /* if (col < tcol) */
  1026.     {
  1027.         relseq[relp++] = '\033';
  1028.         relseq[relp++] = '[';
  1029.         if (dist >= 10)
  1030.             relseq[relp++] = '0' + dist / 10;
  1031.         relseq[relp++] = '0' + dist % 10;
  1032.         relseq[relp++] = 'D';
  1033.         tcol = col;
  1034.     }
  1035.  
  1036.     /*** If relative positioning will do it, forget absolute ***/
  1037.     if (relp <= 5)
  1038.         twrite (1, relseq, relp);
  1039.     else
  1040.     {
  1041.         absseq[absp++] = '\033';
  1042.         absseq[absp++] = '[';
  1043.         if (row >= 9)
  1044.             absseq[absp++] = '0' + (row + 1) / 10;
  1045.         absseq[absp++] = '0' + (row + 1) % 10;
  1046.         absseq[absp++] = ';';
  1047.         if (col >= 9)
  1048.             absseq[absp++] = '0' + (col + 1) / 10;
  1049.         absseq[absp++] = '0' + (col + 1) % 10;
  1050.         absseq[absp++] = 'H';
  1051.         if (absp >= relp)
  1052.             twrite (1, relseq, relp);
  1053.         else
  1054.             twrite (1, absseq, absp);
  1055.     }
  1056.     Curcol = col;
  1057.     Currow = row;
  1058. }
  1059.  
  1060.  
  1061.  
  1062. /* anppos --- position cursor on Allen & Paul model 1 */
  1063.  
  1064. static anppos (row, col)
  1065. int row, col;
  1066. {
  1067.     register char coord;
  1068.  
  1069.     if (row == Currow)      /* if close, just sneak right or left */
  1070.     {
  1071.         if (col == Curcol + 1)
  1072.             twrite (1, "\t", 1);
  1073.         else if (col == Curcol + 2)
  1074.             twrite (1, "\t\t", 2);
  1075.         else if (col == Curcol - 1)
  1076.             twrite (1, "\b", 1);
  1077.         else if (col == Curcol - 2)
  1078.             twrite (1, "\b\b", 2);
  1079.         else
  1080.         {
  1081.             twrite (1, "\033C", 2);
  1082.             coord = col + ' ';
  1083.             twrite (1, &coord, 1);
  1084.         }
  1085.     }
  1086.  
  1087.     else if (col == Curcol) /* if close, sneak up or down */
  1088.     {
  1089.         if (row == Currow + 1)
  1090.             twrite (1, "\012", 1);
  1091.         else if (row == Currow + 2)
  1092.             twrite (1, "\012\012", 2);
  1093.         else if (row == Currow - 1)
  1094.             twrite (1, "\013", 1);
  1095.         else if (row == Currow - 2)
  1096.             twrite (1, "\013\013", 2);
  1097.         else
  1098.         {
  1099.         /* because of bug in anp software, abs row pos is not working.
  1100.          * the following code was replaced to compensate:
  1101.          *
  1102.          *          twrite (1, "\033R", 2);
  1103.          *          coord = row + ' ';
  1104.          *          twrite (1, &coord, 1);
  1105.          */
  1106.             twrite (1, "\033P", 2);
  1107.             coord = row + ' ';
  1108.             twrite (1, &coord, 1);
  1109.             coord = col + ' ';
  1110.             twrite (1, &coord, 1);
  1111.         }
  1112.     }
  1113.     else    /* resort to absolute positioning */
  1114.     {
  1115.         twrite (1, "\033P", 2);
  1116.         coord = row + ' ';
  1117.         twrite (1, &coord, 1);
  1118.         coord = col + ' ';
  1119.         twrite (1, &coord, 1);
  1120.     }
  1121.  
  1122.     Currow = row;
  1123.     Curcol = col;
  1124. }
  1125.  
  1126. /* b200coord --- transmit a coordinate for Beehive 200 cursor addressing */
  1127.  
  1128. static b200coord (coord)
  1129. int coord;
  1130. {
  1131.     char acc;
  1132.     int tens, units;
  1133.  
  1134.     tens = coord / 10;
  1135.     units = coord - 10 * tens;
  1136.     acc = units + 16 * tens;
  1137.  
  1138.     twrite (1, & acc, 1);
  1139. }
  1140.  
  1141. /* beepos --- position cursor on Beehive terminal */
  1142.  
  1143. static beepos (row, col)
  1144. int row, col;
  1145. {
  1146.     if (row == Currow + 1 && col == 0 && Term_type != SBEE)
  1147.     {
  1148.         twrite (1, "\r\n", 2);        /*  CR LF */
  1149.         Curcol = 0;
  1150.         Currow++;
  1151.     }
  1152.     else if (row == 0 && col == 0)        /* home cursor */
  1153.     {
  1154.         twrite (1, "\033H", 2);
  1155.         Currow = Curcol = 0;
  1156.     }
  1157.     else if (row == Currow && col > Curcol && col <= Curcol + 4)
  1158.         while (Curcol != col)
  1159.         {
  1160.             twrite (1, &Screen_image[Currow][Curcol], 1);
  1161.             Curcol++;
  1162.         }
  1163.     else if (row == Currow && col < Curcol && col >= Curcol - 4)
  1164.         while (Curcol != col)
  1165.         {
  1166.             twrite (1, "\b", 1);
  1167.             Curcol--;
  1168.         }
  1169.     else        /* resort to absolute addressing */
  1170.     {
  1171.         twrite (1, "\033F", 2);
  1172.         if (Term_type == BEE200 || Term_type == SOL)
  1173.         {
  1174.             b200coord (row);
  1175.             b200coord (col);
  1176.         }
  1177.         else if (Term_type == BEE150)
  1178.         {
  1179.             char r, c;
  1180.  
  1181.             r = row + ' ';
  1182.             c = col + ' ';
  1183.             twrite (1, &r, 1);
  1184.             twrite (1, &c, 1);
  1185.         }
  1186.         else        /* is superbee */
  1187.         {
  1188.             sbeecoord (col);
  1189.             sbeecoord (row);
  1190.         }
  1191.  
  1192.         Currow = row;
  1193.         Curcol = col;
  1194.     }
  1195. }
  1196.  
  1197. /* cgpos --- position cursor on Chromatics CG */
  1198.  
  1199. static cgpos (row, col)
  1200. int row, col;
  1201. {
  1202.     char i, j;
  1203.  
  1204.     if (row == Currow + 1 && col == 0)
  1205.     {
  1206.         twrite (1, "\r\n", 2);        /* CR LF */
  1207.         Curcol = 0;
  1208.         Currow++;
  1209.     }
  1210.     else if (row == 0 && col == 0)        /* home cursor */
  1211.     {
  1212.         twrite (1, "\034", 1);    /* FS */
  1213.         Currow = Curcol = 0;
  1214.     }
  1215.     else if (row == Currow && col > Curcol && col <= Curcol + 7)
  1216.         while (Curcol != col)
  1217.         {
  1218.             twrite (1, "\035", 1);    /* GS */
  1219.             Curcol++;
  1220.         }
  1221.     else if (row == Currow && col < Curcol && col >= Curcol - 7)
  1222.         while (Curcol != col)
  1223.         {
  1224.             twrite (1, "\b", 1);
  1225.             Curcol--;
  1226.         }
  1227.     else
  1228.     {
  1229.         /* resort to absolute addressing */
  1230.         twrite (1, "\001U", 2);        /* SOH U */
  1231.         i = 511 - (10 * row);
  1232.         j = 6 * col;
  1233.         cgcoord (j);
  1234.         cgcoord (i);
  1235.         Currow = row;
  1236.         Curcol = col;
  1237.     }
  1238.  
  1239. }
  1240.  
  1241.  
  1242. /* cgcoord --- output a decimal coordinate for Chromatics CG */
  1243.  
  1244. static cgcoord (i)
  1245. int i;
  1246. {
  1247.     int units, tens, hundreds;
  1248.     char coords[4];
  1249.  
  1250.     units = i % 10;
  1251.     i /= 10;
  1252.     tens = i % 10;
  1253.     i /= 10;
  1254.     hundreds = i % 10;
  1255.  
  1256.     coords[0] = hundreds + 16 + ' ';
  1257.     coords[1] = tens + 16 + ' ';
  1258.     coords[2] = units + 16 + ' ';
  1259.     coords[3] = EOS;
  1260.     twrite (1, coords, 3);
  1261. }
  1262.  
  1263.  
  1264.  
  1265. /* gt40pos --- position cursor to (row, col) on DEC GT40 with Waugh software */
  1266.  
  1267. static gt40pos (row, col)
  1268. int row, col;
  1269. {
  1270.     char coord;
  1271.  
  1272.     if (row != Currow && col != Curcol)    /* absolute positioning */
  1273.     {
  1274.         twrite (1, "\033", 1);
  1275.         coord = row + ' ';
  1276.         twrite (1, &coord, 1);
  1277.         coord = col + ' ';
  1278.         twrite (1, &coord, 1);
  1279.         Currow = row;
  1280.         Curcol = col;
  1281.     }
  1282.     else if (row != Currow)        /* col must = Curcol */
  1283.     {                /* vertical positioning */
  1284.         twrite (1, "\006", 1);    /* ACK */
  1285.         coord = row + ' ';
  1286.         twrite (1, &coord, 1);
  1287.         Currow = row;
  1288.     }
  1289.     else if (abs (col - Curcol) < 2)
  1290.         uhcm (col);
  1291.     else
  1292.     {
  1293.         twrite (1, "\025", 1);    /* NACK */
  1294.         coord = col + ' ';
  1295.         twrite (1, &coord, 1);
  1296.         Curcol = col;
  1297.     }
  1298. }
  1299.  
  1300.  
  1301.  
  1302. /* h19pos --- position cursor on Heath H19 (DEC VT52 compatible, supposedly) */
  1303.  
  1304. static h19pos (row, col)
  1305. int row, col;
  1306. {
  1307.     int dist;
  1308.     char coord;
  1309.  
  1310.     dist = col - Curcol;
  1311.     if (dist < 0)
  1312.         dist = -dist;
  1313.     if (row == Currow && dist < 4)  /* 4 chars for abs. position */
  1314.     {
  1315.         while (Curcol < col)
  1316.         {
  1317.             twrite (1, &Screen_image[Currow][Curcol], 1);
  1318.             Curcol++;
  1319.         }
  1320.         while (Curcol > col)
  1321.         {
  1322.             twrite (1, "\b", 1);
  1323.             Curcol--;
  1324.         }
  1325.     }
  1326.     else
  1327.     {
  1328.         twrite (1, "\033Y", 2);
  1329.         coord = row + ' ';
  1330.         twrite (1, &coord, 1);
  1331.         coord = col + ' ';
  1332.         twrite (1, &coord, 1);
  1333.         Currow = row;
  1334.         Curcol = col;
  1335.     }
  1336. }
  1337.  
  1338. /* hp21pos --- position cursor on HP 2621 terminal */
  1339.  
  1340. static hp21pos (row, col)
  1341. int row, col;
  1342. {
  1343.     int units, tens;
  1344.  
  1345.     if (row == Currow && col == 0)
  1346.     {
  1347.         twrite (1, "\r\n", 2);        /* CR LF */
  1348.         Curcol = 0;
  1349.         Currow++;
  1350.     }
  1351.     else if (row == 0 && col == 0)        /* home cursor */
  1352.     {
  1353.         twrite (1, "\033H", 2);
  1354.         Currow = Curcol = 0;
  1355.     }
  1356.     else if (row == Currow && col > Curcol && col <= Curcol + 4)
  1357.         while (Curcol != col)
  1358.         {
  1359.             twrite (1, &Screen_image[Currow][Curcol], 1);
  1360.             Curcol++;
  1361.         }
  1362.     else if (row == Currow && col < Curcol && col >= Curcol - 4)
  1363.         while (Curcol != col)
  1364.         {
  1365.             twrite (1, "\b", 1);
  1366.             Curcol--;
  1367.         }
  1368.     else if (2 * abs (Currow - row) + abs (Curcol - col) <= 7)
  1369.     {
  1370.         while (Currow < row)
  1371.         {
  1372.             twrite (1, "\033B", 2);
  1373.             Currow++;
  1374.         }
  1375.         while (Currow > row)
  1376.         {
  1377.             twrite (1, "\033A", 2);
  1378.             Currow--;
  1379.         }
  1380.         while (Curcol > col)
  1381.         {
  1382.             twrite (1, "\b", 1);
  1383.             Curcol--;
  1384.         }
  1385.         while (Curcol < col)
  1386.         {
  1387.             twrite (1, & Screen_image[Currow][Curcol], 1);
  1388.             Curcol++;
  1389.         }
  1390.     }
  1391.     else
  1392.     {
  1393.         /* resort to absolute addressing */
  1394.         char c;
  1395.  
  1396.         twrite (1, "\033&a", 3);
  1397.         units = row % 10;
  1398.         tens = row / 10;
  1399.         if (tens != 0)
  1400.         {
  1401.             c = tens + '0';
  1402.             twrite (1, &c, 1);
  1403.         }
  1404.         c = units + '0';
  1405.         twrite (1, &c, 1);
  1406.         twrite (1, "y", 1);
  1407.         units = col % 10;
  1408.         tens = col / 10;
  1409.         if (tens != 0)
  1410.         {
  1411.             c = tens + '0';
  1412.             twrite (1, &c, 1);
  1413.         }
  1414.         c = units + '0';
  1415.         twrite (1, &c, 1);
  1416.         twrite (1, "C", 1);
  1417.         Currow = row;
  1418.         Curcol = col;
  1419.     }
  1420. }
  1421.  
  1422.  
  1423. /* hazpos --- position cursor on Hazeltine 1510 */
  1424.  
  1425. static hazpos (row, col)
  1426. int row, col;
  1427. {
  1428.     int dist;
  1429.     char c;
  1430.  
  1431.     dist = col - Curcol;
  1432.     if (dist < 0)
  1433.         dist = -dist;
  1434.     if (row == Currow && dist < 4)  /* 4 chars for abs. position */
  1435.     {
  1436.         while (Curcol < col)
  1437.         {
  1438.             twrite (1, &Screen_image[Currow][Curcol], 1);
  1439.             Curcol++;
  1440.         }
  1441.         while (Curcol > col)
  1442.         {
  1443.             twrite (1, "\b", 1);
  1444.             Curcol--;
  1445.         }
  1446.     }
  1447.     else
  1448.     {
  1449.         twrite (1, "\033\021", 2);
  1450.         c = col;
  1451.         twrite (1, &c, 1);
  1452.         c = row;
  1453.         twrite (1, &c, 1);
  1454.         Currow = row;
  1455.         Curcol = col;
  1456.     }
  1457. }
  1458.  
  1459.  
  1460. /* ibmpos --- position cursor on IBM 3101 terminal */
  1461.  
  1462. static ibmpos (row, col)
  1463. int row, col;
  1464. {
  1465.     int dist;
  1466.     static char abspos[] = "\033\Y\0\0";
  1467.  
  1468.     dist = col - Curcol;
  1469.     if (dist < 0)
  1470.         dist = -dist;
  1471.     
  1472.     if (row == Currow && dist < 4)        /* 4 chars for abs pos */
  1473.     {
  1474.         while (Curcol < col)
  1475.         {
  1476.             twrite (1, & Screen_image[Currow][Curcol], 1);
  1477.             Curcol++;
  1478.         }
  1479.         while (Curcol > col)
  1480.         {
  1481.             twrite (1, "\b", 1);
  1482.             Curcol--;
  1483.         }
  1484.     }
  1485.     else
  1486.     {
  1487.         abspos[2] = row + ' ';
  1488.         abspos[3] = col + ' ';
  1489.         twrite (1, abspos, 4);
  1490.         Currow = row;
  1491.         Curcol = col;
  1492.     }
  1493. }
  1494.  
  1495.  
  1496.  
  1497. /* iscpos --- position cursor on ISC 8001 color terminal */
  1498.  
  1499. static iscpos (row, col)
  1500. int row, col;
  1501. {
  1502.     char r, c;
  1503.  
  1504.     if (row == 0 && col == 0)
  1505.         twrite (1, "\b", 1);
  1506.     else
  1507.     {
  1508.         twrite (1, "\003", 1);        /* ETX */
  1509.         r = row;
  1510.         c = col;
  1511.         twrite (1, & r, 1);
  1512.         twrite (1, & c, 1);
  1513.     }
  1514.  
  1515.     Currow = row;
  1516.     Curcol = col;
  1517. }
  1518.  
  1519. /* netpos --- position cursor on Netron terminal */
  1520.  
  1521. static netpos (row, col)
  1522. int row, col;
  1523. {
  1524.     static char abspos[] = "\033=\0\0";
  1525.  
  1526.     abspos[2] = (char) row;
  1527.     abspos[3] = (char) col;
  1528.     twrite (1, abspos, 4);
  1529.     Currow = row;
  1530.     Curcol = col;
  1531. }
  1532.  
  1533. /* pepos --- position cursor on Perkin-Elmer 550 & 1100 terminals */
  1534.  
  1535. static pepos (row, col)
  1536. int row, col;
  1537. {
  1538.     char coord;
  1539.  
  1540.     /* get on correct row first */
  1541.     if (Currow == row)
  1542.         ;        /* already on correct row; nothing to do */
  1543.     else if (row == Currow - 1)
  1544.     {
  1545.         twrite (1, "\033A", 2);        /* cursor up */
  1546.         Currow--;
  1547.     }
  1548.     else if (row == Currow + 1)
  1549.     {
  1550.         twrite (1, "\033B", 2);        /* cursor down */
  1551.         Currow++;
  1552.     }
  1553.     else
  1554.     {
  1555.         /* vertical absolute positioning */
  1556.         twrite (1, "\033X", 2);
  1557.         coord = row + ' ';
  1558.         twrite (1, & coord, 1);
  1559.     }
  1560.  
  1561.     /* now perform horizontal motion */
  1562.     if (abs (col - Curcol) > 3)    /* do absolute horizontal position */
  1563.     {
  1564.         twrite (1, "\033Y", 2);
  1565.         coord = col + ' ';
  1566.         twrite (1, &coord, 1);
  1567.         Curcol = col;
  1568.     }
  1569.     else
  1570.         uhcm (col);
  1571. }
  1572.  
  1573. /* sbeecoord --- transmit a coordinate for Superbee terminal */
  1574.  
  1575. static sbeecoord (coord)
  1576. int coord;
  1577. {
  1578.     char r, c;
  1579.  
  1580.     r = (coord / 10) + ' ';
  1581.     c = (coord % 10) + ' ';
  1582.     twrite (1, & r, 1);
  1583.     twrite (1, & c, 1);
  1584. }
  1585.  
  1586. /* trspos --- position cursor on TRS80 Model 1 */
  1587.  
  1588. static trspos (row, col)
  1589. int row, col;
  1590. {
  1591.     while (Currow != row)
  1592.     {
  1593.         if (Currow > row)
  1594.         {
  1595.             twrite (1, "\033", 1);
  1596.             Currow--;
  1597.         }
  1598.         else
  1599.         {
  1600.             twrite (1, "\032", 1);        /* SUB */
  1601.             Currow++;
  1602.         }
  1603.     }
  1604.  
  1605.     if (Curcol != col)
  1606.     {
  1607.         if (col > Curcol)
  1608.             while (col > Curcol)
  1609.             {
  1610.                 twrite (1, "\031", 1);    /* EM */
  1611.                 Curcol++;
  1612.             }
  1613.         else if (col < Curcol / 2)
  1614.         {
  1615.             twrite (1, "\035", 1);    /* GS */
  1616.             Curcol = 0;
  1617.             while (Curcol < col)
  1618.             {
  1619.                 twrite (1, "\031", 1);    /* EM */
  1620.                 Curcol++;
  1621.             }
  1622.         }
  1623.         else
  1624.             while (col < Curcol)
  1625.             {
  1626.                 twrite (1, "\030", 1);    /* CAN */
  1627.                 Curcol--;
  1628.             }
  1629.     }
  1630. }
  1631.  
  1632.  
  1633.  
  1634. /* tvtpos --- position cursor on Allen's TV Typetwriter II */
  1635.  
  1636. static tvtpos (row, col)
  1637. int row, col;
  1638. {
  1639.     register int horirel, horiabs, vertrel, vertabs;
  1640.  
  1641.     horirel = col - Curcol;
  1642.     if (horirel < 0)
  1643.         horirel = -horirel;
  1644.  
  1645.     horiabs = col;
  1646.  
  1647.     if (row <= Currow)
  1648.         vertrel = Currow - row;
  1649.     else
  1650.         vertrel = Nrows - (row - Currow);
  1651.  
  1652.     if (row == 0)
  1653.         vertabs = 0;
  1654.     else
  1655.         vertabs = Nrows - row;
  1656.  
  1657.     if (1 + horiabs + vertabs <= horirel + vertrel)
  1658.     {
  1659.         twrite (1, "\014", 1);
  1660.         Currow = Curcol = 0;
  1661.     }
  1662.  
  1663.     while (Currow != row)
  1664.     {
  1665.         twrite (1, "\013", 1);
  1666.         Currow--;
  1667.         if (Currow < 0)
  1668.             Currow = Nrows - 1;
  1669.     }
  1670.  
  1671.     if (Curcol > col)
  1672.         for (; Curcol != col; Curcol--)
  1673.             twrite (1, "\b", 1);
  1674.     else
  1675.         for (; Curcol != col; Curcol++)
  1676.             twrite (1, "\t", 1);
  1677. }
  1678.  
  1679.  
  1680.  
  1681. /* regentpos --- position cursor on ADDS Regent 100 */
  1682.  
  1683. static regentpos (row, col)
  1684. int row, col;
  1685. {
  1686.     int dist;
  1687.     char coord;
  1688.  
  1689.     dist = col - Curcol;
  1690.     if (dist < 0)
  1691.         dist = -dist;
  1692.     
  1693.     if (dist > 4 || Currow != row)
  1694.     {
  1695.         twrite (1, "\033Y", 2);
  1696.         coord = ' ' + row;
  1697.         twrite (1, &coord, 1);
  1698.         coord = ' ' + col;
  1699.         twrite (1, &coord, 1);
  1700.         Currow = row;
  1701.         Curcol = col;
  1702.     }
  1703.     else
  1704.     {
  1705.         while (row < Currow)
  1706.         {
  1707.             twrite (1, "\032", 1);    /* SUB, cursor up */
  1708.             Currow--;
  1709.         }
  1710.         while (row > Currow)
  1711.         {
  1712.             twrite (1, "\n", 1);
  1713.             Currow++;
  1714.             Curcol = 1;
  1715.         }
  1716.         if (col > Curcol)
  1717.             while (col != Curcol)
  1718.             {
  1719.                 twrite (1, &Screen_image[Currow][Curcol], 1);
  1720.                 Curcol++;
  1721.             }
  1722.         else if ((Curcol - col) * 2 >= Ncols)
  1723.             while (col != Curcol)
  1724.             {
  1725.                 twrite (1, "\006", 1);    /* ACK, cursor right */
  1726.                 if (Curcol == Ncols)
  1727.                     Curcol = 1;
  1728.                 else
  1729.                     Curcol++;
  1730.             }
  1731.         else
  1732.             while (col != Curcol)
  1733.             {
  1734.                 twrite (1, "\b", 1);
  1735.                 Curcol--;
  1736.             }
  1737.     }
  1738. }
  1739.  
  1740.  
  1741.  
  1742. /* vipos --- position cursor on Visual 200 & 50 */
  1743.  
  1744. static vipos (row, col)
  1745. register int row, col;
  1746. {
  1747.     register int dist;
  1748.     register char coord;
  1749.  
  1750.     if (row == Currow + 1 && col < 3)
  1751.     {
  1752.         twrite (1, "\015\012", 2);
  1753.         Currow++;
  1754.         Curcol = 0;
  1755.     }
  1756.     dist = col - Curcol;
  1757.     if (Term_type == VI200 && row == Currow && col < 72 && dist > 2
  1758.         && dist < 8 && (col + 1) % 8 < 2)
  1759.     {
  1760.         twrite (1, "\t", 1);
  1761.         Curcol = ((Curcol + 7) / 8) * 8;
  1762.         dist = col - Curcol;
  1763.     }
  1764.     if (dist < 0)
  1765.         dist = -dist;
  1766.     if (row == Currow && dist < 4)  /* 4 chars for abs. position */
  1767.     {
  1768.         while (Curcol < col)
  1769.         {
  1770.             twrite (1, &Screen_image[Currow][Curcol], 1);
  1771.             Curcol++;
  1772.         }
  1773.         while (Curcol > col)
  1774.         {
  1775.             twrite (1, "\b", 1);
  1776.             Curcol--;
  1777.         }
  1778.     }
  1779.     else
  1780.     {
  1781.         twrite (1, "\033Y", 2);
  1782.         coord = row + ' ';
  1783.         twrite (1, &coord, 1);
  1784.         coord = col + ' ';
  1785.         twrite (1, &coord, 1);
  1786.         Currow = row;
  1787.         Curcol = col;
  1788.     }
  1789. }
  1790.  
  1791.  
  1792.  
  1793. /* vcpos --- position cursor Volker-Craig 4404 (ADM3A mode) */
  1794.  
  1795. static vcpos (row, col)
  1796. int row, col;
  1797. {
  1798.     int dist;
  1799.     char coord;
  1800.  
  1801.     dist = col - Curcol;
  1802.     if (dist < 0)
  1803.         dist = -dist;
  1804.     if (row == Currow && dist < 4)  /* 4 chars for abs. position */
  1805.     {
  1806.         while (Curcol < col)
  1807.         {
  1808.             twrite (1, &Screen_image[Currow][Curcol], 1);
  1809.             Curcol++;
  1810.         }
  1811.         while (Curcol > col)
  1812.         {
  1813.             twrite (1, "\b", 1);
  1814.             Curcol--;
  1815.         }
  1816.     }
  1817.     else
  1818.     {
  1819.         twrite (1, "\033=", 2);
  1820.         coord = row + ' ';
  1821.         twrite (1, &coord, 1);
  1822.         coord = col + ' ';
  1823.         twrite (1, &coord, 1);
  1824.         Currow = row;
  1825.         Curcol = col;
  1826.     }
  1827. }
  1828.  
  1829.  
  1830. /* espritpos --- position cursor on Hazeltine Esprit */
  1831.  
  1832. static espritpos (row, col)
  1833. int row, col;
  1834. {
  1835.     int dist;
  1836.     char c;
  1837.  
  1838.     dist = col - Curcol;
  1839.     if (dist < 0)
  1840.         dist = -dist;
  1841.     if (row == Currow && dist < 4)  /* 4 chars for abs. position */
  1842.     {
  1843.         while (Curcol < col)
  1844.         {
  1845.             twrite (1, &Screen_image[Currow][Curcol], 1);
  1846.             Curcol++;
  1847.         }
  1848.         while (Curcol > col)
  1849.         {
  1850.             twrite (1, "\b", 1);
  1851.             Curcol--;
  1852.         }
  1853.     }
  1854.     else
  1855.     {
  1856.         twrite (1, "\033\021", 2);
  1857.         c = col >= 32 ? col : col + '`';
  1858.         twrite (1, &c, 1);
  1859.         c = row >= 32 ? row : row + '`';
  1860.         twrite (1, &c, 1);
  1861.         Currow = row;
  1862.         Curcol = col;
  1863.     }
  1864. }
  1865.  
  1866. /* uhcm --- universal horizontal cursor motion */
  1867.  
  1868. static uhcm (col)
  1869. int col;
  1870. {
  1871.     while (Curcol < col)
  1872.     {
  1873.         twrite (1, &Screen_image[Currow][Curcol], 1);
  1874.         Curcol++;
  1875.     }
  1876.  
  1877.     while (Curcol > col)
  1878.     {
  1879.         twrite (1, "\b", 1);
  1880.         Curcol--;
  1881.     }
  1882. }
  1883. #endif
  1884.