/*
 *      Driver file for Cifer T2 (ansi)
 *      - Use with UMIST.def
 */

/*#define HANDSHAKE /* enable <cntl-q><cntl-s> handshake */

cfT2_setup()
{
extern char qread();
#ifdef HANDSHAKE
   extern struct tchars tchars;

   tchars.t_startc = 021;
   tchars.t_stopc = 023;
#endif /* HANDSHAKE */

   sendseq("\033[2h");     /* keyboard lock */
   sendseq("\033[1/m");    /* short scroll mode */
   sendseq("\033P");       /* get ready to program keys */
   sendseq("LE01B4F31.");  /* f1 sends <esc>O1 */
   sendseq("LE21B4F32.");  /* f2 sends <esc>O2 */
   sendseq("LE41B4F33.");  /* f3 sends <esc>O3 */
   sendseq("LE61B4F34.");  /* f4 sends <esc>O4 */
   sendseq("LE81B4F35.");  /* f5 sends <esc>O5 */
   sendseq("LEA1B4F36.");  /* f6 sends <esc>O6 */
   sendseq("LEC1B4F37.");  /* f7 sends <esc>O7 */
   sendseq("LEE1B4F38.");  /* f8 sends <esc>O8 */
   sendseq("LF01B4F39.");  /* f9 sends <esc>O9 */
   sendseq("LF21B4F30.");  /* f10 sends <esc>O0 */
   sendseq("X");           /* done keys */
   sendseq("\033=");       /* keypad application mode */
   sendseq("\033[5n");     /* are you ready yet? */
      qread(); qread(); qread(); qread(); /* replies <esc>[On */
   sendseq("\033[2l");     /* keyboard unlock */
}

cfT2_restore()
{
   sendseq("\033[0/m");    /* long scroll mode */
   sendseq("\033>");       /* keypad numeric mode */
}

cfT2_move(srow, scol)
register int srow, scol;
/* ESC [ row ; col H */
{
        ttyout('\033');
        ttyout('[');
        dedpnum(ttyout, srow+1, 10);
        ttyout(';');
        dedpnum(ttyout, scol+1, 10);
        ttyout('H');
}

int cfT2_special(typein,c)
int typein;
register char c;
/* returns the character type corresponding
 * to ansi keypad escape sequences
 */
{
   register char ch;

   if (c != '\033')
      editerror("character %o given to cfT2_special", c);
   else
   {
      if (typein)
      {
         ch = ttyin();
         switch(ch)
         {
         case '\033' : return(ENTERedit);
         case '[' :
            ch = ttyin();
            switch(ch)
            {
            case 'C' : return(RIGHT);
            case 'D' : return(LEFT);
            }
            if (mode==INMODE) switch (ch) {
            case 'A' : return(UP);
            case 'B' : return(DOWN);
            }
         break;
         case 'O':
            ch = ttyin();
            switch(ch) {
            case 'x': return(LEFT);
            case 'y': return(RIGHT);
            case 'Q': return(WLEFT);
            case 'R': return(WRIGHT);
            case 'u': return(LSTART);
            case 'v': return(LEND);
            case 'r': return(CONTROL);
            case 's': return(READPIPE);
            case 'l': return(OVER);
            case 'p': return(SEND);
            case 'n': return(CHMODE);
            case 'M': return(ENTERedit);
            case '3': return(HEADRUBOUT);
            case '4': return(TAILERASE);
            case '5': return(WRUBOUT);
            case '6': return(WERASE);
            case '7': return(RUBOUT);
            case '8': return(ERASE);
            }
            if (mode==INMODE) switch(ch) {
            case 'w': return(DOWN);
            case 'P': return(UP);
            case 'q': return(BOTSCREEN);
            case 't': return(TOPSCREEN);
            case 'm': return(NEXTPAGE);
            case 'S': return(LASTPAGE);
            case '1': return(LINEERASE);
            }
         }
         complain();
      }
      return(IGN);
   }
}

struct TERMINAL cfT2_ter =
 {  /* nrows, ncols - size of the screen */
    TER_ROWS, TER_COLS,

    /* up, left, c_MODIFY, c_CONTROL, c_BLOB - single characters */
    { 0, '\010', 0, 0200|'^', 0200|' ' },
        /* onechar */

    /* rollup, pushdown, pushup, pulldown, pullup STRINGS */
    /* and hardscroll boolean */
/* push down = insert line, pull up = delete line */
    /* you MUST have rollup */
    { "\n", "\033[L", 0, 0, "\033[M", true},
        /* scrseq */

    /* scrollup, scrolldown PROCEDURES */
    /* scr1_ is pushup, pulldown */
    /* scr2_ is pushdown, pullup */
    /* scr3_ is both */
    /* scr0_ is neither (and in that case hardscroll is false) */
    scr2_up, scr2_down,

    /* splitdown, splitup, joindown, joinup STRINGS */
    { 0, 0, 0, 0 },
        /* splitseq */

    /* split_row, join_row PROCEDURES */
    split0, join0,

    /* clearscreen, *clearhead, *cleartail STRINGS */
    /* I assume ^L for clear screen, but it isn't important */
    { "\033[2J\033[H", "\033[1K", "\033[K" },
        /* clrseq */

    /* clr_screen, clr_head, clr_tail PROCEDURES */
    /* I assume hardware support for clear screen at least */
    clrs1, clrh1, clrt1,

    /* inspace, makespace, rubout, erase STRINGS */
    /* inspace puts a space and moves the cursor right,
     * makespace doesn't move it. Likewise rubout moves the
     * cursor left, erase doesn't move it
     */
    { 0, "\033[@", 0, "\033[P" },
        /* charseq */

    /* ins_char, del_char PROCEDURES */
    /* insc1 uses inspace, insc2 makespace */
    /* delc1 uses rubout, delc2 erase */
    /* insc0, delc0 use neither */
    insc2, delc2,

    /* bright, normal STRINGS */
    { "\033[1;7m", "\033[m" },
        /* vidseq */

    /* in_two, out_two PROCEDURES */
    no_char, no_char,

    /* move PROCEDURE and nmove integer */
    cfT2_move, 8,

    /* setup, special, pad, restore PROCEDURES */
    cfT2_setup, cfT2_special, no_int, cfT2_restore

 };
