bug-ncurses
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

tty_update.c (part 2)


From: Philippe Blain
Subject: tty_update.c (part 2)
Date: Wed, 27 Nov 2002 07:49:43 +0100

>From Philippe Blain, Bordeaux, FRANCE.
My old computer: P133 - 8,4 Go - 32 Mo Red Hat Linux 7.0

To maintainers of 'ncurses'.(and to Mr Dickey)
Subject: Corrections for ncurses-5.3-20021123+

Here are some problems I found :

===========================================================================
This is some ideas about modifying tty_update.c
Characters are emitted ONLY in TransformLine() by PutChar().

Acceleration is used with terminfo clear sequences when terminal and
blank character permit it by looking for blank lines.

I search for blank lines at top and bottom of screen.
That code is an example. tty_update.c requires lot of work.
===========================================================================

ClrBlank returns space with background attributes (color and modes).
It's the comparison character for screen lines.
Undependant of terminal type (bce/non-bce).

static inline NCURSES_CH_T ClrBlank (WINDOW * win)
{
 NCURSES_CH_T blank = NewChar (BLANK_TEXT);
 AddAttr (blank, (AttrOf (BCE_BKGD (win))));
 return blank;
}

---------------------------------------------------------------------------
ClrToEOL hard-clears the current line and returns an error code.

static int ClrToEOL (NCURSES_CH_T blank)
{
 TR (TRACE_UPDATE, ("ClrToEOL() called"));

 if (clr_eol && can_clear_with (CHREF (blank))) {
  int j, row, col;

  row = SP->_cursrow;
  col = SP->_curscol;

  UpdateAttrs (AttrOf (blank));
  TPUTS_TRACE ("clr_eol");
  putp (clr_eol);
  for (j = col; j < screen_columns; j++)
   curscr->_line[row].text[j] = blank;
  returnCode (OK);
 }
 else returnCode (ERR);
}

---------------------------------------------------------------------------
New function used for clearing top of screen when possible.

static int ClrToLine (int top, NCURSES_CH_T blank)
{
 TR (TRACE_UPDATE, ("ClrToLine() called"));

 if (top < 0)  returnCode (ERR);
 if (clr_eol && can_clear_with (CHREF (blank))) {
  int i, j, row, col;

  row = SP->_cursrow;
  col = SP->_curscol;

  UpdateAttrs (AttrOf (blank));
  TPUTS_TRACE ("clr_eol");
  putp (clr_eol);
  for (i = 0; i <= top && i < screen_lines; i++) {
   GoTo (i, 0);
   putp (clr_eol);
   for (j = 0; j < screen_columns; j++)
    curscr->_line[i].text[j] = blank;
  }
  GoTo (row, col);
  returnCode (OK);
 }
 else returnCode (ERR);
}

---------------------------------------------------------------------------
ClrToEOS clears from (y, x).

static int ClrToEOS (int y, int x, NCURSES_CH_T blank)
{
 TR (TRACE_UPDATE, ("ClrToEOS() called"));

 if ((clr_eos || clr_eol) && can_clear_with (CHREF (blank))) {
  int i, j, row, col;

  row = SP->_cursrow;
  col = SP->_curscol;

  GoTo (y, x);
  UpdateAttrs (AttrOf (blank));
  if (clr_eos) {
   TPUTS_TRACE ("clr_eos");
   tputs (clr_eos, screen_lines - row, _nc_outch);
  }
  else if (clr_eol) {
   TPUTS_TRACE ("clr_eol");
   putp (clr_eol);
   for (i = row + 1; i < screen_lines; i++) {
    GoTo (i, 0);
    putp (clr_eol);
   }
  }
  GoTo (row, col);

  for (j = x; j < screen_columns; j++)
   curscr->_line[y].text[j] = blank;

  for (i = y + 1; i < screen_lines; i++) {
   for (j = 0; j < screen_columns; j++)
    curscr->_line[i].text[j] = blank;
  }
  returnCode (OK);
 }
 else returnCode (ERR);
}

---------------------------------------------------------------------------
Hard-clear the whole screen without the lower corner bug.
The soft-clear of the screen is done by clear() or erase() calls.

static int ClearScreen (NCURSES_CH_T blank)
{
 int i, j;
 bool fast_clear = (clear_screen || clr_eos || clr_eol);

 TR (TRACE_UPDATE, ("ClearScreen() called"));

 if (fast_clear && can_clear_with (blank)) {
  UpdateAttrs (AttrOf (blank));
  if (clear_screen) {
   TPUTS_TRACE ("clear_screen");
   putp (clear_screen);
   SP->_cursrow = SP->_curscol = 0;
   position_check (SP->_cursrow, SP->_curscol, "ClearScreen");
  }
  else if (clr_eos) {
   SP->_cursrow = SP->_curscol = -1;

   GoTo (0, 0);
   TPUTS_TRACE ("clr_eos");
   tputs (clr_eos, screen_lines, _nc_outch);
  }
  else if (clr_eol) {
   SP->_cursrow = SP->_curscol = -1;

   TPUTS_TRACE ("clr_eol");
   for (i = 0; i < screen_lines; i++) {
    GoTo (i, 0);
    putp (clr_eol);
   }
   GoTo (0, 0);
  }

  for (i = 0; i < screen_lines; i++) {
   for (j = 0; j < screen_columns; j++)
    curscr->_line[i].text[j] = blank;
  }
  TR (TRACE_UPDATE, ("screen cleared"));
  returnCode (OK);
 }
 else returnCode (ERR);
}

---------------------------------------------------------------------------
New function, replace ClrBottom().
Clears top and bottom if blank lines.
Use the return values of clear functions to ensure the clear has
well been done.
Returns the lines indices where TransformLine() will be used.
Tested and ok for me.

static void ClrTopAndBottom (int *top, int *bottom)
{
 int i, j, top_empty, bottom_empty;
 int total = screen_lines;
 bool ok = TRUE;
 NCURSES_CH_T blank = ClrBlank (newscr);

 TR (TRACE_UPDATE, ("ClrTopAndBottom() called"));

 /* Default values */
 *top = top_empty = - 1;
 *bottom = bottom_empty = total;

 if (can_clear_with (blank)) {
  for (i = total - 1; i >= 0; i--) {
   for (j = 0; ok && (j < CT_SP->_newscr->width); j++) {
    ok = (CharEq (newscr->_line[i].text[j], blank));
   }
   if (!ok) break;
   bottom_empty = i;
  }

  if (bottom_empty == 0) {
   if (ClearScreen (blank) == OK) *bottom = 0;
   return;
  }
  else if (bottom_empty < total) {
   if (ClearToEOS (0, bottom_empty, blank) == OK)
    *bottom = bottom_empty;
  }

  for (i = 0; i < bottom_empty; i++) {
   for (j = 0; ok && (j < CT_SP->_newscr->width); j++) {
    ok = (CharEq (newscr->_line[i].text[j], blank));
   }
   if (!ok) break;
   top_empty = i;
  }

  if (top_empty >= 0) {
   if (ClrToLine (top_empty, blank) == OK)
    *top = top_empty;
  }
 }
}

---------------------------------------------------------------------------
Top and bottom of screen are cleared and values returned used by
TransformLine().

static void ClrUpdate (void)
{
 int i, top_empty, bottom_empty;
 NCURSES_CH_T blank = ClrBlank (newscr);

 TR (TRACE_UPDATE, ("ClrUpdate() called"));

 /* Try to hard-clear physical screen */
 ClearScreen (blank);

 TR (TRACE_UPDATE, ("updating screen from scratch"));

 /* Try to hard-clear blanklines at top and bottom of newscr */
 ClrTopAndBottom (&top_empty, &bottom_empty);

 for (i = top_empty + 1; i < bottom_empty; i++)
  TransformLine (i);
}

---------------------------------------------------------------------------
Same thing.

NCURSES_EXPORT (int) doupdate (void)
{
 int i;
 int top_empty, bottom_empty;

 ......................
 T ((T_CALLED ("doupdate()")));
 ......................
  /* Try to hard-clear blanklines at top and bottom of newscr */
  ClrTopAndBottom (&top_empty, &bottom_empty);

  for (i = top_empty + 1; i < bottom_empty; i++) {
   ......................
   if (newscr->_line[i].firstchar != _NOCHANGE
    || curscr->_line[i].firstchar != _NOCHANGE) {
    TransformLine (i);
    changedlines++;
   }
  }
 }

 /* put everything back in sync */
 for (i = 0; i <= newscr->_maxy; i++) {
  MARK_NOCHANGE (newscr, i);
 }
 for (i = 0; i <= curscr->_maxy; i++) {
  MARK_NOCHANGE (curscr, i);
 }
 ......................
 returnCode (OK);
}
----------------------------------------------------------------------------
- Philippe






reply via email to

[Prev in Thread] Current Thread [Next in Thread]