*
*-----------------------------------------------------------------*/
+#ifdef __BEOS__
+#include <OS.h>
+#endif
+
#include <curses.priv.h>
#if defined(TRACE) && HAVE_SYS_TIMES_H && HAVE_TIMES
#endif
#endif
-#ifdef __BEOS__
-/* BeOS select() only works on sockets. Use the tty hack instead */
-#include <socket.h>
-#define select check_select
-#endif
-
#include <term.h>
-MODULE_ID("$Id: lib_doupdate.c,v 1.98 1998/02/11 12:14:00 tom Exp $")
+MODULE_ID("$Id: tty_update.c,v 1.117 1999/10/22 23:28:46 tom Exp $")
/*
* This define controls the line-breakout optimization. Every once in a
static inline chtype ClrBlank ( WINDOW *win );
static int ClrBottom(int total);
-static int InsStr( chtype *line, int count );
static void ClearScreen( chtype blank );
-static void ClrUpdate( WINDOW *win );
+static void ClrUpdate( void );
static void DelChar( int count );
+static void InsStr( chtype *line, int count );
static void TransformLine( int const lineno );
#ifdef POSITION_DEBUG
*
****************************************************************************/
-void position_check(int expected_y, int expected_x, char *legend)
+static void position_check(int expected_y, int expected_x, char *legend)
/* check to see if the real cursor position matches the virtual */
{
- static char buf[9];
+ char buf[20];
int y, x;
- if (_nc_tracing)
+ if (!_nc_tracing || (expected_y < 0 && expected_x < 0))
return;
memset(buf, '\0', sizeof(buf));
- (void) write(1, "\033[6n", 4); /* only works on ANSI-compatibles */
- (void) read(0, (void *)buf, 8);
+ putp("\033[6n"); /* only works on ANSI-compatibles */
+ _nc_flush();
+ (void) read(0, buf, sizeof(buf)-1);
_tracef("probe returned %s", _nc_visbuf(buf));
/* try to interpret as a position report */
- if (sscanf(buf, "\033[%d;%dR", &y, &x) != 2)
+ if (sscanf(buf, "\033[%d;%dR", &y, &x) != 2) {
_tracef("position probe failed in %s", legend);
- else if (y - 1 != expected_y || x - 1 != expected_x)
- _tracef("position seen (%d, %d) doesn't match expected one (%d, %d) in %s",
- y-1, x-1, expected_y, expected_x, legend);
- else
- _tracef("position matches OK in %s", legend);
+ } else {
+ if (expected_x < 0)
+ expected_x = x - 1;
+ if (expected_y < 0)
+ expected_y = y - 1;
+ if (y - 1 != expected_y || x - 1 != expected_x) {
+ beep();
+ _tracef("position seen (%d, %d) doesn't match expected one (%d, %d) in %s",
+ y-1, x-1, expected_y, expected_x, legend);
+ } else {
+ _tracef("position matches OK in %s", legend);
+ }
+ }
}
+#else
+#define position_check(expected_y, expected_x, legend) /* nothing */
#endif /* POSITION_DEBUG */
/****************************************************************************
TR(TRACE_MOVE, ("GoTo(%d, %d) from (%d, %d)",
row, col, SP->_cursrow, SP->_curscol));
-#ifdef POSITION_DEBUG
position_check(SP->_cursrow, SP->_curscol, "GoTo");
-#endif /* POSITION_DEBUG */
/*
* Force restore even if msgr is on when we're in an alternate
mvcur(SP->_cursrow, SP->_curscol, row, col);
SP->_cursrow = row;
SP->_curscol = col;
+ position_check(SP->_cursrow, SP->_curscol, "GoTo2");
}
static inline void PutAttrChar(chtype ch)
_tracechtype(ch),
SP->_cursrow, SP->_curscol));
UpdateAttrs(ch);
- putc((int)TextOf(ch), SP->_ofp);
+ if (SP->_cleanup) {
+ _nc_outch((int)TextOf(ch));
+ } else {
+ putc((int)TextOf(ch), SP->_ofp); /* macro's fastest... */
#ifdef TRACE
- _nc_outchars++;
+ _nc_outchars++;
#endif /* TRACE */
+ }
SP->_curscol++;
if (char_padding) {
TPUTS_TRACE("char_padding");
{
have_pending = TRUE;
}
+#elif defined(__BEOS__)
+ /*
+ * BeOS's select() is declared in socket.h, so the configure script does
+ * not see it. That's just as well, since that function works only for
+ * sockets. This (using snooze and ioctl) was distilled from Be's patch
+ * for ncurses which uses a separate thread to simulate select().
+ *
+ * FIXME: the return values from the ioctl aren't very clear if we get
+ * interrupted.
+ */
+ int n = 0;
+ int howmany = ioctl(0, 'ichr', &n);
+ if (howmany >= 0 && n > 0) {
+ have_pending = TRUE;
+ }
#elif HAVE_SELECT
fd_set fdset;
struct timeval ktimeout;
FD_ZERO(&fdset);
FD_SET(SP->_checkfd, &fdset);
- if (select(SP->_checkfd+1, &fdset, NULL, NULL, &ktimeout) > 0)
+ if (select(SP->_checkfd+1, &fdset, NULL, NULL, &ktimeout) != 0)
{
have_pending = TRUE;
}
}
if (have_pending) {
SP->_fifohold = 5;
- fflush(SP->_ofp);
+ _nc_flush();
}
return FALSE;
}
putp(exit_am_mode);
PutAttrChar(ch);
+ SP->_curscol--;
+ position_check(SP->_cursrow, SP->_curscol, "exit_am_mode");
TPUTS_TRACE("enter_am_mode");
putp(enter_am_mode);
{
SP->_curscol--;
}
+ position_check(SP->_cursrow, SP->_curscol, "wrap_cursor");
}
static inline void PutChar(chtype const ch)
if (SP->_curscol >= screen_columns)
wrap_cursor();
-#ifdef POSITION_DEBUG
position_check(SP->_cursrow, SP->_curscol, "PutChar");
-#endif /* POSITION_DEBUG */
}
/*
#endif /* USE_XMC_SUPPORT */
nonempty = 0;
- if (curscr->_clear) { /* force refresh ? */
- /* yes, clear all & update */
- T(("clearing and updating curscr"));
- if (is_wintouched(newscr))
- ClrUpdate(newscr);
- else
- ClrUpdate(curscr);
+ if (curscr->_clear || newscr->_clear) { /* force refresh ? */
+ T(("clearing and updating from scratch"));
+ ClrUpdate();
curscr->_clear = FALSE; /* reset flag */
newscr->_clear = FALSE; /* reset flag */
- } else if (newscr->_clear) {
- T(("clearing and updating newscr"));
- ClrUpdate(newscr);
- newscr->_clear = FALSE;
} else {
int changedlines = CHECK_INTERVAL;
nonempty = min(screen_lines, newscr->_maxy+1);
if (SP->_scrolling) {
-#if USE_HASHMAP
-#if defined(TRACE) || defined(NCURSES_TEST)
- if (_nc_optimize_enable & OPTIMIZE_HASHMAP)
-#endif /*TRACE */
- _nc_hash_map();
-#elif !USE_SCROLL_HINTS
- _nc_setup_scroll();
-#endif
-#if defined(TRACE) || defined(NCURSES_TEST)
- if (_nc_optimize_enable & OPTIMIZE_SCROLL)
-#endif /*TRACE */
-#if USE_SCROLL_HINTS || USE_HASHMAP
_nc_scroll_optimize();
-#else
- _nc_perform_scroll();
-#endif
}
nonempty = ClrBottom(nonempty);
for (i = nonempty; i <= curscr->_maxy; i++)
MARK_NOCHANGE(curscr,i)
- curscr->_curx = newscr->_curx;
- curscr->_cury = newscr->_cury;
+ if (!newscr->_leaveok)
+ {
+ curscr->_curx = newscr->_curx;
+ curscr->_cury = newscr->_cury;
- GoTo(curscr->_cury, curscr->_curx);
+ GoTo(curscr->_cury, curscr->_curx);
+ }
cleanup:
/*
*/
UpdateAttrs(A_NORMAL);
- fflush(SP->_ofp);
+ _nc_flush();
curscr->_attrs = newscr->_attrs;
/* curscr->_bkgd = newscr->_bkgd; */
}
/*
-** ClrUpdate(win)
+** ClrUpdate()
**
** Update by clearing and redrawing the entire screen.
**
*/
-static void ClrUpdate(WINDOW *win)
+static void ClrUpdate(void)
{
int i;
- chtype blank = ClrBlank(win);
+ chtype blank = ClrBlank(stdscr);
int nonempty = min(screen_lines, newscr->_maxy+1);
T(("ClrUpdate() called"));
- if (win == curscr) {
- /* discard updates */
- for (i = 0; i < screen_lines ; i++) {
- memcpy( newscr->_line[i].text,
- curscr->_line[i].text,
- screen_columns * sizeof(chtype));
- }
- }
-
ClearScreen(blank);
T(("updating screen from scratch"));
if(!clr_eos || !can_clear_with(blank))
return total;
- if (tstLine == 0)
- tstLine = (chtype *)malloc(length);
- else if (length > lenLine)
- tstLine = (chtype *)realloc(tstLine, length);
+ if ((tstLine == 0) || (last > (int)lenLine)) {
+ tstLine = typeRealloc(chtype, last, tstLine);
+ if (tstLine != 0) {
+ lenLine = last;
+ for (col = 0; col < last; col++)
+ tstLine[col] = blank;
+ }
+ }
if (tstLine != 0) {
- lenLine = length;
- for (col = 0; col < last; col++)
- tstLine[col] = blank;
-
for (row = total-1; row >= 0; row--) {
if (memcmp(tstLine, newscr->_line[row].text, length))
break;
GoTo(top,0);
ClrToEOS(blank);
total = top;
+ if (SP->oldhash && SP->newhash)
+ {
+ for (row = top; row < screen_lines; row++)
+ SP->oldhash[row] = SP->newhash[row];
+ }
}
}
#if NO_LEAKS
- FreeAndNull(tstLine);
+ if (tstLine != 0)
+ FreeAndNull(tstLine);
#endif
return total;
}
T(("TransformLine(%d) called", lineno));
+ /* copy new hash value to old one */
+ if (SP->oldhash && SP->newhash)
+ SP->oldhash[lineno] = SP->newhash[lineno];
+
if(ceol_standout_glitch && clr_eol) {
firstChar = 0;
while(firstChar < screen_columns) {
if(newLine[firstChar] != blank )
PutChar(newLine[firstChar]);
ClrToEOL(blank);
- } else if( newLine[nLastChar] != oldLine[oLastChar]
- || !(_nc_idcok && has_ic()) ) {
+ } else if( (nLastChar != oLastChar)
+ && (newLine[nLastChar] != oldLine[oLastChar]
+ || !(_nc_idcok && has_ic())) ) {
GoTo(lineno, firstChar);
if ((oLastChar - nLastChar) > SP->_el_cost) {
if(PutRange(oldLine, newLine, lineno, firstChar, nLastChar))
GoTo(lineno, firstChar);
PutRange(oldLine, newLine, lineno, firstChar, n);
}
- GoTo(lineno, n+1);
if (oLastChar < nLastChar) {
int m = max(nLastNonblank, oLastNonblank);
+ GoTo(lineno, n+1);
if (InsCharCost(nLastChar - oLastChar)
> (m - n)) {
PutRange(oldLine, newLine, lineno, n+1, m);
InsStr(&newLine[n+1], nLastChar - oLastChar);
}
} else if (oLastChar > nLastChar ) {
+ GoTo(lineno, n+1);
if (DelCharCost(oLastChar - nLastChar)
> SP->_el_cost + nLastNonblank - (n+1)) {
if(PutRange(oldLine, newLine, lineno,
TPUTS_TRACE("clear_screen");
putp(clear_screen);
SP->_cursrow = SP->_curscol = 0;
-#ifdef POSITION_DEBUG
position_check(SP->_cursrow, SP->_curscol, "ClearScreen");
-#endif /* POSITION_DEBUG */
} else if (clr_eos) {
SP->_cursrow = SP->_curscol = -1;
GoTo(0,0);
**
*/
-static int InsStr(chtype *line, int count)
+static void InsStr(chtype *line, int count)
{
T(("InsStr(%p,%d) called", line, count));
- if (enter_insert_mode && exit_insert_mode) {
- TPUTS_TRACE("enter_insert_mode");
- putp(enter_insert_mode);
+ /* Prefer parm_ich as it has the smallest cost - no need to shift
+ * the whole line on each character. */
+ /* The order must match that of InsCharCost. */
+ if (parm_ich) {
+ TPUTS_TRACE("parm_ich");
+ tputs(tparm(parm_ich, count), count, _nc_outch);
while (count) {
PutAttrChar(*line);
line++;
count--;
}
- TPUTS_TRACE("exit_insert_mode");
- putp(exit_insert_mode);
- return(OK);
- } else if (parm_ich) {
- TPUTS_TRACE("parm_ich");
- tputs(tparm(parm_ich, count), count, _nc_outch);
+ } else if (enter_insert_mode && exit_insert_mode) {
+ TPUTS_TRACE("enter_insert_mode");
+ putp(enter_insert_mode);
while (count) {
PutAttrChar(*line);
+ if (insert_padding)
+ {
+ TPUTS_TRACE("insert_padding");
+ putp(insert_padding);
+ }
line++;
count--;
}
- return(OK);
+ TPUTS_TRACE("exit_insert_mode");
+ putp(exit_insert_mode);
} else {
while (count) {
TPUTS_TRACE("insert_character");
line++;
count--;
}
- return(OK);
}
+ position_check(SP->_cursrow, SP->_curscol, "InsStr");
}
/*
void _nc_outstr(const char *str)
{
- FILE *ofp = SP ? SP->_ofp : stdout;
-
- (void) fputs(str, ofp);
- (void) fflush(ofp);
-
-#ifdef TRACE
- _nc_outchars += strlen(str);
-#endif /* TRACE */
+ (void) putp(str);
+ _nc_flush();
}
/*
if (res == ERR && change_scroll_region)
{
if (top != 0 && (SP->_cursrow == top || SP->_cursrow == top-1)
- && save_cursor && restore_cursor)
+ && save_cursor && restore_cursor)
{
cursor_saved=TRUE;
- TPUTS_TRACE("save_cursor");
+ TPUTS_TRACE("save_cursor");
tputs(save_cursor, 0, _nc_outch);
}
TPUTS_TRACE("change_scroll_region");
tputs(tparm(change_scroll_region, top, bot), 0, _nc_outch);
if (cursor_saved)
{
- TPUTS_TRACE("restore_cursor");
+ TPUTS_TRACE("restore_cursor");
tputs(restore_cursor, 0, _nc_outch);
}
else
_nc_scroll_window(curscr, n, top, bot, blank);
+ /* shift hash values too - they can be reused */
+ _nc_scroll_oldhash(n, top, bot);
+
return(OK);
}