]> pd.if.org Git - pd_readline/blobdiff - mg/tty.c
Getting close to a basic working readline now.
[pd_readline] / mg / tty.c
diff --git a/mg/tty.c b/mg/tty.c
deleted file mode 100644 (file)
index f803cc7..0000000
--- a/mg/tty.c
+++ /dev/null
@@ -1,447 +0,0 @@
-/*     $OpenBSD: tty.c,v 1.30 2008/09/15 16:11:35 kjell Exp $  */
-
-/* This file is in the public domain. */
-
-/*
- * Terminfo display driver
- *
- * Terminfo is a terminal information database and routines to describe
- * terminals on most modern UNIX systems.  Many other systems have adopted
- * this as a reasonable way to allow for widely varying and ever changing
- * varieties of terminal types.         This should be used where practical.
- */
-/*
- * Known problems: If you have a terminal with no clear to end of screen and
- * memory of lines below the ones visible on the screen, display will be
- * wrong in some cases.  I doubt that any such terminal was ever made, but I
- * thought everyone with delete line would have clear to end of screen too...
- *
- * Code for terminals without clear to end of screen and/or clear to end of line
- * has not been extensively tested.
- *
- * Cost calculations are very rough.  Costs of insert/delete line may be far
- * from the truth.  This is accentuated by display.c not knowing about
- * multi-line insert/delete.
- *
- * Using scrolling region vs insert/delete line should probably be based on cost
- * rather than the assumption that scrolling region operations look better.
- */
-
-#include "def.h"
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-
-#include <term.h>
-
-static int      charcost(char *);
-
-static int      cci;
-static int      insdel;        /* Do we have both insert & delete line? */
-static char    *scroll_fwd;    /* How to scroll forward. */
-
-static void     winchhandler(int);
-
-/* ARGSUSED */
-static void
-winchhandler(int sig)
-{
-       winch_flag = 1;
-}
-
-/*
- * Initialize the terminal when the editor
- * gets started up.
- */
-void
-ttinit(void)
-{
-       int errret;
-
-       if (setupterm(NULL, 1, &errret))
-               panic("Terminal setup failed");
-
-       signal(SIGWINCH, winchhandler);
-       signal(SIGCONT, winchhandler);
-       siginterrupt(SIGWINCH, 1);
-
-       scroll_fwd = scroll_forward;
-       if (scroll_fwd == NULL || *scroll_fwd == '\0') {
-               /* this is what GNU Emacs does */
-               scroll_fwd = parm_down_cursor;
-               if (scroll_fwd == NULL || *scroll_fwd == '\0')
-                       scroll_fwd = "\n";
-       }
-
-       if (cursor_address == NULL || cursor_up == NULL)
-               panic("This terminal is too stupid to run mg");
-
-       /* set nrow & ncol */
-       ttresize();
-
-       if (!clr_eol)
-               tceeol = ncol;
-       else
-               tceeol = charcost(clr_eol);
-
-       /* Estimate cost of inserting a line */
-       if (change_scroll_region && scroll_reverse)
-               tcinsl = charcost(change_scroll_region) * 2 +
-                   charcost(scroll_reverse);
-       else if (parm_insert_line)
-               tcinsl = charcost(parm_insert_line);
-       else if (insert_line)
-               tcinsl = charcost(insert_line);
-       else
-               /* make this cost high enough */
-               tcinsl = nrow * ncol;
-
-       /* Estimate cost of deleting a line */
-       if (change_scroll_region)
-               tcdell = charcost(change_scroll_region) * 2 +
-                   charcost(scroll_fwd);
-       else if (parm_delete_line)
-               tcdell = charcost(parm_delete_line);
-       else if (delete_line)
-               tcdell = charcost(delete_line);
-       else
-               /* make this cost high enough */
-               tcdell = nrow * ncol;
-
-       /* Flag to indicate that we can both insert and delete lines */
-       insdel = (insert_line || parm_insert_line) &&
-           (delete_line || parm_delete_line);
-
-       if (enter_ca_mode)
-               /* enter application mode */
-               putpad(enter_ca_mode, 1);
-
-       ttresize();
-}
-
-/*
- * Re-initialize the terminal when the editor is resumed.
- * The keypad_xmit doesn't really belong here but...
- */
-void
-ttreinit(void)
-{
-       /* check if file was modified while we were gone */
-       if (fchecktime(curbp) != TRUE) {
-               curbp->b_flag |= BFDIRTY;
-       }
-
-       if (enter_ca_mode)
-               /* enter application mode */
-               putpad(enter_ca_mode, 1);
-
-       if (keypad_xmit)
-               /* turn on keypad */
-               putpad(keypad_xmit, 1);
-
-       ttresize();
-}
-
-/*
- * Clean up the terminal, in anticipation of a return to the command
- * interpreter. This is a no-op on the ANSI display. On the SCALD display,
- * it sets the window back to half screen scrolling. Perhaps it should
- * query the display for the increment, and put it back to what it was.
- */
-void
-tttidy(void)
-{
-#ifdef XKEYS
-       ttykeymaptidy();
-#endif /* XKEYS */
-
-       /* set the term back to normal mode */
-       if (exit_ca_mode)
-               putpad(exit_ca_mode, 1);
-}
-
-/*
- * Move the cursor to the specified origin 0 row and column position. Try to
- * optimize out extra moves; redisplay may have left the cursor in the right
- * location last time!
- */
-void
-ttmove(int row, int col)
-{
-       if (ttrow != row || ttcol != col) {
-               putpad(tgoto(cursor_address, col, row), 1);
-               ttrow = row;
-               ttcol = col;
-       }
-}
-
-/*
- * Erase to end of line.
- */
-void
-tteeol(void)
-{
-       int     i;
-
-       if (clr_eol)
-               putpad(clr_eol, 1);
-       else {
-               i = ncol - ttcol;
-               while (i--)
-                       ttputc(' ');
-               ttrow = ttcol = HUGE;
-       }
-}
-
-/*
- * Erase to end of page.
- */
-void
-tteeop(void)
-{
-       int     line;
-
-       if (clr_eos)
-               putpad(clr_eos, nrow - ttrow);
-       else {
-               putpad(clr_eol, 1);
-               if (insdel)
-                       ttdell(ttrow + 1, lines, lines - ttrow - 1);
-               else {
-                       /* do it by hand */
-                       for (line = ttrow + 1; line <= lines; ++line) {
-                               ttmove(line, 0);
-                               tteeol();
-                       }
-               }
-               ttrow = ttcol = HUGE;
-       }
-}
-
-/*
- * Make a noise.
- */
-void
-ttbeep(void)
-{
-       putpad(bell, 1);
-       ttflush();
-}
-
-/*
- * Insert nchunk blank line(s) onto the screen, scrolling the last line on
- * the screen off the bottom.  Use the scrolling region if possible for a
- * smoother display.  If there is no scrolling region, use a set of insert
- * and delete line sequences.
- */
-void
-ttinsl(int row, int bot, int nchunk)
-{
-       int     i, nl;
-
-       /* Case of one line insert is special. */
-       if (row == bot) {
-               ttmove(row, 0);
-               tteeol();
-               return;
-       }
-       if (change_scroll_region && scroll_reverse) {
-               /* Use scroll region and back index      */
-               nl = bot - row;
-               ttwindow(row, bot);
-               ttmove(row, 0);
-               while (nchunk--)
-                       putpad(scroll_reverse, nl);
-               ttnowindow();
-               return;
-       } else if (insdel) {
-               ttmove(1 + bot - nchunk, 0);
-               nl = nrow - ttrow;
-               if (parm_delete_line)
-                       putpad(tgoto(parm_delete_line, 0, nchunk), nl);
-               else
-                       /* For all lines in the chunk... */
-                       for (i = 0; i < nchunk; i++)
-                               putpad(delete_line, nl);
-               ttmove(row, 0);
-
-               /* ttmove() changes ttrow */
-               nl = nrow - ttrow;
-
-               if (parm_insert_line)
-                       putpad(tgoto(parm_insert_line, 0, nchunk), nl);
-               else
-                       /* For all lines in the chunk */
-                       for (i = 0; i < nchunk; i++)
-                               putpad(insert_line, nl);
-               ttrow = HUGE;
-               ttcol = HUGE;
-       } else
-               panic("ttinsl: Can't insert/delete line");
-}
-
-/*
- * Delete nchunk line(s) from "row", replacing the bottom line on the
- * screen with a blank line.  Unless we're using the scrolling region,
- * this is done with crafty sequences of insert and delete lines.  The
- * presence of the echo area makes a boundary condition go away.
- */
-void
-ttdell(int row, int bot, int nchunk)
-{
-       int     i, nl;
-
-       /* One line special cases */
-       if (row == bot) {
-               ttmove(row, 0);
-               tteeol();
-               return;
-       }
-       /* scrolling region */
-       if (change_scroll_region) {
-               nl = bot - row;
-               ttwindow(row, bot);
-               ttmove(bot, 0);
-               while (nchunk--)
-                       putpad(scroll_fwd, nl);
-               ttnowindow();
-       /* else use insert/delete line */
-       } else if (insdel) {
-               ttmove(row, 0);
-               nl = nrow - ttrow;
-               if (parm_delete_line)
-                       putpad(tgoto(parm_delete_line, 0, nchunk), nl);
-               else
-                       /* For all lines in the chunk    */
-                       for (i = 0; i < nchunk; i++)
-                               putpad(delete_line, nl);
-               ttmove(1 + bot - nchunk, 0);
-
-               /* ttmove() changes ttrow */
-               nl = nrow - ttrow;
-               if (parm_insert_line)
-                       putpad(tgoto(parm_insert_line, 0, nchunk), nl);
-               else
-                       /* For all lines in the chunk */
-                       for (i = 0; i < nchunk; i++)
-                               putpad(insert_line, nl);
-               ttrow = HUGE;
-               ttcol = HUGE;
-       } else
-               panic("ttdell: Can't insert/delete line");
-}
-
-/*
- * This routine sets the scrolling window on the display to go from line
- * "top" to line "bot" (origin 0, inclusive).  The caller checks for the
- * pathological 1-line scroll window which doesn't work right and avoids
- * it.  The "ttrow" and "ttcol" variables are set to a crazy value to
- * ensure that the next call to "ttmove" does not turn into a no-op (the
- * window adjustment moves the cursor).
- */
-void
-ttwindow(int top, int bot)
-{
-       if (change_scroll_region && (tttop != top || ttbot != bot)) {
-               putpad(tgoto(change_scroll_region, bot, top), nrow - ttrow);
-               ttrow = HUGE;   /* Unknown.              */
-               ttcol = HUGE;
-               tttop = top;    /* Remember region.      */
-               ttbot = bot;
-       }
-}
-
-/*
- * Switch to full screen scroll. This is used by "spawn.c" just before it
- * suspends the editor and by "display.c" when it is getting ready to
- * exit.  This function does a full screen scroll by telling the terminal
- * to set a scrolling region that is lines or nrow rows high, whichever is
- * larger.  This behavior seems to work right on systems where you can set
- * your terminal size.
- */
-void
-ttnowindow(void)
-{
-       if (change_scroll_region) {
-               putpad(tgoto(change_scroll_region,
-                   (nrow > lines ? nrow : lines) - 1, 0), nrow - ttrow);
-               ttrow = HUGE;   /* Unknown.              */
-               ttcol = HUGE;
-               tttop = HUGE;   /* No scroll region.     */
-               ttbot = HUGE;
-       }
-}
-
-/*
- * Set the current writing color to the specified color. Watch for color
- * changes that are not going to do anything (the color is already right)
- * and don't send anything to the display.  The rainbow version does this
- * in putline.s on a line by line basis, so don't bother sending out the
- * color shift.
- */
-void
-ttcolor(int color)
-{
-       if (color != tthue) {
-               if (color == CTEXT)
-                       /* normal video */
-                       putpad(exit_standout_mode, 1);
-               else if (color == CMODE)
-                       /* reverse video */
-                       putpad(enter_standout_mode, 1);
-               /* save the color */
-               tthue = color;
-       }
-}
-
-/*
- * This routine is called by the "refresh the screen" command to try
- * to resize the display. Look in "window.c" to see how
- * the caller deals with a change.
- *
- * We use `newrow' and `newcol' so vtresize() know the difference between the
- * new and old settings.
- */
-void
-ttresize(void)
-{
-       int newrow = 0, newcol = 0;
-
-#ifdef TIOCGWINSZ
-       struct  winsize winsize;
-
-       if (ioctl(0, TIOCGWINSZ, &winsize) == 0) {
-               newrow = winsize.ws_row;
-               newcol = winsize.ws_col;
-       }
-#endif
-       if ((newrow <= 0 || newcol <= 0) &&
-           ((newrow = lines) <= 0 || (newcol = columns) <= 0)) {
-               newrow = 24;
-               newcol = 80;
-       }
-       if (vtresize(1, newrow, newcol) != TRUE)
-               panic("vtresize failed");
-}
-
-/*
- * fake char output for charcost()
- */
-/* ARGSUSED */
-static int
-fakec(int c)
-{
-       cci++;
-       return (0);
-}
-
-/* calculate the cost of doing string s */
-static int
-charcost(char *s)
-{
-       cci = 0;
-
-       tputs(s, nrow, fakec);
-       return (cci);
-}