Logo Search packages:      
Sourcecode: vile version File versions

ansi.c

/*
 * The routines in this file provide support for ANSI style terminals
 * over a serial line. The serial I/O services are provided by routines in
 * "termio.c". It compiles into nothing if not an ANSI device.
 *
 *
 * $Header: /usr/build/vile/vile/RCS/ansi.c,v 1.44 2003/05/27 00:21:58 tom Exp $
 */

#include    "estruct.h"
#include    "edef.h"

#if   DISP_ANSI

#define SCROLL_REG 1


#if   SYS_MSDOS
#define NROW    25
#define NCOL    80
#define MAXNROW   60
#define MAXNCOL   132
#undef SCROLL_REG             /* ANSI.SYS can't do scrolling */
#define SCROLL_REG 0
#endif

#ifdef ANSI_RESIZE
#define NROW    77
#define NCOL    132
#endif

#if    !defined NROW && defined(linux)
#define NROW      25                /* Screen size.               */
#define NCOL      80                /* Edit if you want to.       */
#endif

#ifndef NROW
#define NROW      24                /* Screen size.               */
#define NCOL      80                /* Edit if you want to.       */
#endif
#ifndef MAXNROW
#define MAXNROW   NROW
#define MAXNCOL   NCOL
#endif

#define NPAUSE    100               /* # times thru update to pause */

static      void  ansimove   (int row, int col);
static      void  ansieeol   (void);
static      void  ansieeop   (void);
static      void  ansibeep   (void);
static      void  ansiopen   (void);
static      void  ansirev    (UINT state);
static      void  ansiclose  (void);
static      void  ansiscroll (int from, int to, int n);

#if   OPT_COLOR
static      void  ansifcol (int color);
static      void  ansibcol (int color);

static      int   cfcolor = -1;           /* current forground color */
static      int   cbcolor = -1;           /* current background color */

#endif

/*
 * Standard terminal interface dispatch table. Most of the fields point into
 * "termio" code.
 */
TERM  term  = {
      MAXNROW,    /* max */
      NROW,       /* current */
      MAXNCOL,    /* max */
      NCOL,       /* current */
      NPAUSE,
      ansiopen,
      nullterm_kopen,
      nullterm_kclose,
      ansiclose,
      ttgetc,
      ttputc,
      tttypahead,
      ttflush,
      ansimove,
      ansieeol,
      ansieeop,
      ansibeep,
      ansirev,
      nullterm_setdescrip,
#if   OPT_COLOR
      ansifcol,
      ansibcol,
#else
      nullterm_setfore,
      nullterm_setback,
#endif
      nullterm_setpal,              /* no palette */
      nullterm_setccol,
      ansiscroll,
      nullterm_pflush,
      nullterm_icursor,
      nullterm_settitle,
      nullterm_watchfd,
      nullterm_unwatchfd,
      nullterm_cursorvis,
};

static      void  ansiparm (int n);
#if SCROLL_REG
static      void  ansiscrollregion (int top, int bot);
#endif

static void
csi (void)
{
      ttputc(ESC);
      ttputc('[');
}

#if   OPT_COLOR
static void
ansifcol(int color)     /* set the current output color */
{
      if (color < 0)
            color = C_WHITE;
      if (color == cfcolor)
            return;
      csi();
      ansiparm(color+30);
      ttputc('m');
      cfcolor = color;
}

static void
ansibcol(int color)     /* set the current background color */
{
      if (color < 0)
            color = C_BLACK;
      if (color == cbcolor)
            return;
      csi();
      ansiparm(color+40);
      ttputc('m');
      cbcolor = color;
}
#endif

static void
ansimove(int row, int col)
{
      csi();
      ansiparm(row+1);
      ttputc(';');
      ansiparm(col+1);
      ttputc('H');
}

static void
ansieeol(void)
{
      csi();
      ttputc('K');
}

static void
ansieeop(void)
{
#if   OPT_COLOR
      ansifcol(gfcolor);
      ansibcol(gbcolor);
#endif
      csi();
      ttputc('2');
      ttputc('J');
}

#if OPT_COLOR
static void
force_colors(int fc, int bc)
{
      cfcolor =
      cbcolor = -1;
      ansifcol(fc);
      ansibcol(bc);
}
#endif

#ifdef BROKEN_REVERSE_VIDEO
/* there was something wrong with this "fix".  the "else" of
            the ifdef just uses "ESC [ 7 m" to set reverse
            video, and it works under DOS for me....  but then, i
            use an "after-market" ansi driver -- nnansi593.zip, from
            oak.oakland.edu, or any simtel mirror. */
static void
ansirev(    /* change reverse video state */
UINT state) /* TRUE = reverse, FALSE = normal */
{
#if   !OPT_COLOR
      static UINT revstate = SORTOFTRUE;
      if (state == revstate)
            return;
      revstate = state;
#endif

      csi();
#if OPT_COLOR && SYS_MSDOS
      ttputc('1');      /* bold-on */
#else
      if (state) ttputc('7'); /* reverse-video on */
#endif
      ttputc('m');

#if   OPT_COLOR
#if   SYS_MSDOS
      /*
       * Setting reverse-video with ANSI.SYS seems to reset the colors to
       * monochrome.  Using the colors directly to simulate reverse video
       * works better. Bold-face makes the foreground colors "look" right.
       */
      if (state)
            force_colors(cbcolor, cfcolor);
      else
            force_colors(cfcolor, cbcolor);
#else /* normal ANSI-reverse */
      if (state == FALSE) {
            force_colors(cfcolor, cbcolor);
      }
#endif      /* MSDOS vs ANSI-reverse */
#endif      /* OPT_COLOR */
}

#else

static void
ansirev(    /* change reverse video state */
UINT state) /* TRUE = reverse, FALSE = normal */
{
      static UINT revstate = SORTOFTRUE;
      if (state == revstate)
            return;
      revstate = state;

      csi();
      if (state) ttputc('7'); /* reverse-video on */
      ttputc('m');
#if OPT_COLOR
      force_colors(cfcolor, cbcolor);
#endif
}

#endif


static void
ansibeep(void)
{
      ttputc(BEL);
      ttflush();
}


/* if your ansi terminal can scroll regions, like the vt100, then define
      SCROLL_REG.  If not, you can use delete/insert line code, which
      is prettier but slower if you do it a line at a time instead of
      all at once.
*/

/* move howmany lines starting at from to to */
static void
ansiscroll(int from, int to, int n)
{
      int i;
      if (to == from) return;
#if SCROLL_REG
      if (to < from) {
            ansiscrollregion(to, from + n - 1);
            ansimove(from + n - 1,0);
            for (i = from - to; i > 0; i--)
                  ttputc('\n');
      } else { /* from < to */
            ansiscrollregion(from, to + n - 1);
            ansimove(from,0);
            for (i = to - from; i > 0; i--) {
                  ttputc(ESC);
                  ttputc('M');
            }
      }
      ansiscrollregion(0, term.maxrows-1);

#else /* use insert and delete line */
#if OPT_PRETTIER_SCROLL
      if (absol(from-to) > 1) {
            ansiscroll(from, (from<to) ? to-1:to+1, n);
            if (from < to)
                  from = to-1;
            else
                  from = to+1;
      }
#endif
      if (to < from) {
            ansimove(to,0);
            csi();
            ansiparm(from - to);
            ttputc('M'); /* delete */
            ansimove(to+n,0);
            csi();
            ansiparm(from - to);
            ttputc('L'); /* insert */
      } else {
            ansimove(from+n,0);
            csi();
            ansiparm(to - from);
            ttputc('M'); /* delete */
            ansimove(from,0);
            csi();
            ansiparm(to - from);
            ttputc('L'); /* insert */
      }
#endif
}

#if SCROLL_REG
static void
ansiscrollregion(int top, int bot)
{
      csi();
      ansiparm(top + 1);
      ttputc(';');
      if (bot != term.rows-1) ansiparm(bot + 1);
      ttputc('r');
}
#endif


static void
ansiparm(register int n)
{
      register int q,r;

#ifdef optimize_works /* i don't think it does, although it should, to be ANSI */
      if (n == 1) return;
#endif

      q = n/10;
      if (q != 0) {
            r = q/10;
            if (r != 0) {
                  ttputc((r%10)+'0');
            }
            ttputc((q%10) + '0');
      }
      ttputc((n%10) + '0');
}

static void
ansiopen(void)
{
      static int already_open = FALSE;
      if (!already_open) {
            already_open = TRUE;
            strcpy(screen_desc, "NORMAL");
            revexist = TRUE;
#if ! SYS_MSDOS
            /* Get screen size from system */
            getscreensize(&term.cols, &term.rows);
            if (term.rows <= 1)
                term.rows = 24;

            if (term.cols <= 1)
                term.cols = 80;
            /* we won't resize, but need the measured size */
            term.maxrows = term.rows;
            term.maxcols = term.cols;
#endif
            ttopen();
      }
}

static void
ansiclose(void)
{
      term.curmove(term.rows-1, 0); /* cf: dumbterm.c */
      ansieeol();
#if   OPT_COLOR
      ansifcol(C_WHITE);
      ansibcol(C_BLACK);
#endif
}

#endif      /* DISP_ANSI */

Generated by  Doxygen 1.6.0   Back to index