Thu Dec 30 14:55:59 PST 1999 Michael Jennings <mej@eterm.org>

Finally fixed the seg fault pointed out by Tom Gilbert
	<gilbertt@tomgilbert.freeserve.co.uk> back in mid-September where
	small Eterms with little or no scrollback would crash when receiving
	large amounts of data all at once.

	I also fixed a clearing issue with double buffering, and I worked
	around a really lame gdb/glibc2 bug that has prevented me from using
	gdb with Eterm for ages.


SVN revision: 1804
This commit is contained in:
Michael Jennings 1999-12-30 12:44:45 +00:00
parent b1d55e271d
commit 31afa9e2a8
9 changed files with 238 additions and 270 deletions

View File

@ -2964,3 +2964,15 @@ Wed Dec 29 12:32:19 PST 1999 Michael Jennings <mej@eterm.org>
move themselves if needed, and exposes are now handled properly.
-------------------------------------------------------------------------------
Thu Dec 30 14:55:59 PST 1999 Michael Jennings <mej@eterm.org>
Finally fixed the seg fault pointed out by Tom Gilbert
<gilbertt@tomgilbert.freeserve.co.uk> back in mid-September where
small Eterms with little or no scrollback would crash when receiving
large amounts of data all at once.
I also fixed a clearing issue with double buffering, and I worked
around a really lame gdb/glibc2 bug that has prevented me from using
gdb with Eterm for ages.
-------------------------------------------------------------------------------

View File

@ -324,6 +324,7 @@
#undef MULTICHAR_ENCODING
#undef IOTRACE
#undef HAVE_UTEMPTER
#undef PTY_GRP_NAME
/* Leave that blank line there!! Autoheader needs it.

View File

@ -204,6 +204,32 @@ if test "X$PTY_MECH" = "X"; then
else
AC_MSG_RESULT($PTY_MECH)
fi
AC_MSG_CHECKING(for pty group)
AC_ARG_WITH(pty-group,
[ --with-pty-group[=gid] specify the group that should own pty files],
if test "$withval" = "yes"; then
PTY_GRP_NAME=`ls -1l /dev/pty* 2>/dev/null | head -n 1 | awk '{print $4}'`
if test ! -z "$PTY_GRP_NAME"; then
AC_MSG_RESULT($PTY_GRP_NAME)
AC_DEFINE_UNQUOTED(PTY_GRP_NAME, "$PTY_GRP_NAME")
else
AC_MSG_RESULT(unable to determine. This feature will not be enabled.)
fi
elif test "$withval" = "no"; then
AC_MSG_RESULT(none)
else
AC_MSG_RESULT($withval)
AC_DEFINE_UNQUOTED(PTY_GRP_NAME, "$withval")
fi
,
PTY_GRP_NAME=`ls -1l /dev/pty* 2>/dev/null | head -n 1 | awk '{print $4}'`
if test ! -z "$PTY_GRP_NAME"; then
AC_MSG_RESULT($PTY_GRP_NAME)
AC_DEFINE_UNQUOTED(PTY_GRP_NAME, "$PTY_GRP_NAME")
else
AC_MSG_RESULT(none)
fi
)
dnl#
dnl# FEATURES

View File

@ -40,13 +40,13 @@ typedef struct memrec_struct {
# define MALLOC(sz) malloc(sz)
# define CALLOC(type,n) calloc((n),(sizeof(type)))
# define REALLOC(mem,sz) realloc((mem), (sz))
# define FREE(ptr) free(ptr)
# define FREE(ptr) do { free(ptr); ptr = NULL; } while (0)
#elif (DEBUG >= DEBUG_MALLOC)
# define MALLOC(sz) Malloc(sz)
# define CALLOC(type,n) Calloc((n),(sizeof(type)))
# define REALLOC(mem,sz) Realloc((mem),(sz))
/* # define FREE(ptr) Free(ptr) */
# define FREE(ptr) do { Free(ptr); ptr = NULL; } while(0)
# define FREE(ptr) do { Free(ptr); ptr = NULL; } while (0)
# define MALLOC_MOD 25
# define REALLOC_MOD 25
# define CALLOC_MOD 25
@ -55,7 +55,7 @@ typedef struct memrec_struct {
# define MALLOC(sz) malloc(sz)
# define CALLOC(type,n) calloc((n),(sizeof(type)))
# define REALLOC(mem,sz) ((sz) ? ((mem) ? (realloc((mem), (sz))) : (malloc(sz))) : ((mem) ? (free(mem)) : (NULL)))
# define FREE(ptr) do { free(ptr); ptr = NULL; } while(0)
# define FREE(ptr) do { free(ptr); ptr = NULL; } while (0)
#endif
extern char *SafeStr(char *, unsigned short);

View File

@ -66,7 +66,7 @@ static const char cvs_ident[] = "$Id$";
#include <X11/Xos.h>
#include <X11/Xproto.h>
#include <X11/IntrinsicP.h>
#ifdef USE_GETGRNAME
#ifdef PTY_GRP_NAME
# include <grp.h>
#endif
#ifdef TIME_WITH_SYS_TIME
@ -1297,6 +1297,7 @@ get_tty(void)
int fd;
pid_t pid;
D_TTY(("get_tty() called.\n"));
/*
* setsid() [or setpgrp] must be before open of the terminal,
* otherwise there is no controlling terminal (Solaris 2.4, HP-UX 9)
@ -1336,21 +1337,19 @@ get_tty(void)
ioctl(fd, I_PUSH, "ttcompat");
#else /* __svr4__ */
{
/* change ownership of tty to real uid and real group */
unsigned int mode = 0620;
gid_t gid = my_rgid;
# ifdef USE_GETGRNAME
# ifdef PTY_GRP_NAME
{
struct group *gr = getgrnam(TTY_GRP_NAME);
struct group *gr = getgrnam(PTY_GRP_NAME);
if (gr) {
/* change ownership of tty to real uid, "tty" gid */
gid = gr->gr_gid;
mode = 0620;
}
}
# endif /* USE_GETGRNAME */
# endif
privileges(INVOKE);
# ifndef __CYGWIN32__
@ -1368,10 +1367,12 @@ get_tty(void)
{
unsigned short i;
D_TTY(("get_tty() closing file descriptors 0-%d.\n", num_fds));
for (i = 0; i < num_fds; i++) {
if (i != fd)
close(i);
}
D_TTY(("...closed.\n"));
}
/* Reopen stdin, stdout and stderr over the tty file descriptor */
@ -1422,6 +1423,7 @@ get_tty(void)
privileges(REVERT);
D_TTY(("get_tty() done, fd is %d\n", fd));
return (fd);
}
@ -2084,21 +2086,31 @@ run_command(char *argv[])
print_error("fork(): %s", strerror(errno));
return (-1);
}
if (cmd_pid == 0) { /* child */
if (cmd_pid == 0) {
/* Child process. Reset the signal handlers right away. */
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
signal(SIGCHLD, SIG_DFL);
signal(SIGSEGV, SIG_DFL);
signal(SIGBUS, SIG_DFL);
signal(SIGABRT, SIG_DFL);
signal(SIGFPE, SIG_DFL);
signal(SIGILL, SIG_DFL);
signal(SIGSYS, SIG_DFL);
signal(SIGALRM, SIG_DFL);
#ifdef SIGTSTP
signal(SIGTSTP, SIG_IGN);
signal(SIGTTIN, SIG_IGN);
signal(SIGTTOU, SIG_IGN);
#endif
/* signal (SIGHUP, Exit_signal); */
/* signal (SIGINT, Exit_signal); */
#ifdef HAVE_UNSETENV
/* avoid passing old settings and confusing term size */
unsetenv("LINES");
unsetenv("COLUMNS");
/* avoid passing termcap since terminfo should be okay */
unsetenv("TERMCAP");
#endif /* HAVE_UNSETENV */
/* establish a controlling teletype for the new session */
#endif
get_tty();
/* initialize terminal attributes */
SET_TTYMODE(0, &tio);
/* become virtual console, fail silently */
@ -2138,28 +2150,6 @@ run_command(char *argv[])
my_euid = my_ruid;
my_egid = my_rgid;
/* reset signals and spin off the command interpreter */
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
signal(SIGCHLD, SIG_DFL);
signal(SIGSEGV, SIG_DFL);
signal(SIGBUS, SIG_DFL);
signal(SIGABRT, SIG_DFL);
signal(SIGFPE, SIG_DFL);
signal(SIGILL, SIG_DFL);
signal(SIGSYS, SIG_DFL);
signal(SIGALRM, SIG_DFL);
/*
* mimick login's behavior by disabling the job control signals
* a shell that wants them can turn them back on
*/
#ifdef SIGTSTP
signal(SIGTSTP, SIG_IGN);
signal(SIGTTIN, SIG_IGN);
signal(SIGTTOU, SIG_IGN);
#endif /* SIGTSTP */
/* command interpreter path */
D_CMD(("[%d] About to spawn shell\n", getpid()));
if (chdir(initial_dir)) {

View File

@ -243,13 +243,6 @@
* wrong! */
#define HAVE_SAVED_UIDS
/* Use getgrnam() to determine the group id of TTY_GRP_NAME, and chgrp tty
* device files to that group. This should be ok on SVR4 and Linux systems
* with group "tty" and on BSD systems with group "wheel"
*/
#define USE_GETGRNAME
#define TTY_GRP_NAME "tty"
/********************* Config file parser options *********************/
/* Allow evaluation of expressions like `echo hello` in config files. The
@ -286,10 +279,6 @@
# undef WATCH_DESKTOP_OPTION
#endif
#ifndef TTY_GRP_NAME
# undef USE_GETGRNAME
#endif
#ifndef HAVE_MEMMOVE
inline void *memmove(void *, const void *, size_t);
#endif

View File

@ -784,11 +784,6 @@ version(void)
#else
printf(" -HAVE_SAVED_UIDS");
#endif
#ifdef USE_GETGRNAME
printf(" +USE_GETGRNAME");
#else
printf(" -USE_GETGRNAME");
#endif
#ifdef ALLOW_BACKQUOTE_EXEC
printf(" +ALLOW_BACKQUOTE_EXEC");
#else
@ -862,10 +857,10 @@ version(void)
#else
printf(" -ESCZ_ANSWER\n");
#endif
#ifdef TTY_GRP_NAME
printf(" TTY_GRP_NAME=\"%s\"\n", TTY_GRP_NAME);
#ifdef PTY_GRP_NAME
printf(" PTY_GRP_NAME=\"%s\"\n", PTY_GRP_NAME);
#else
printf(" -TTY_GRP_NAME\n");
printf(" -PTY_GRP_NAME\n");
#endif
#ifdef CONFIG_SEARCH_PATH
printf(" CONFIG_SEARCH_PATH=\"%s\"\n", CONFIG_SEARCH_PATH);

View File

@ -89,6 +89,7 @@ static enum {
SBYTE, WBYTE
} chstat = SBYTE;
static short lost_multi = 0;
unsigned char refresh_all = 0;
#define RESET_CHSTAT if (chstat == WBYTE) chstat = SBYTE, lost_multi = 1
#else
@ -113,6 +114,24 @@ blank_line(text_t * et, rend_t * er, int width, rend_t efs)
*r++ = fs;
}
inline void blank_screen_mem(text_t **, rend_t **, int, rend_t);
inline void
blank_screen_mem(text_t **tp, rend_t **rp, int row, rend_t efs)
{
register unsigned int i = TermWin.ncol;
rend_t *r, fs = efs;
if (tp[row] == NULL) {
tp[row] = MALLOC(sizeof(text_t) * (TermWin.ncol + 1));
rp[row] = MALLOC(sizeof(rend_t) * TermWin.ncol);
}
MEMSET(tp[row], ' ', i);
tp[row][i] = 0;
for (r = rp[row]; i--;)
*r++ = fs;
}
/* ------------------------------------------------------------------------- */
/* allocate memory for this screen line */
void
@ -153,183 +172,148 @@ scr_reset(void)
screen.tscroll = 0;
screen.bscroll = (TermWin.nrow - 1);
/* *INDENT-OFF* */
if (prev_nrow == -1) {
/*
* A: first time called so just malloc everything : don't rely on realloc
* Note: this is still needed so that all the scrollback lines are NULL
*/
screen.text = CALLOC(text_t *, total_rows );
buf_text = CALLOC(text_t *, total_rows );
drawn_text = CALLOC(text_t *, TermWin.nrow);
swap.text = CALLOC(text_t *, TermWin.nrow);
if (prev_nrow == -1) {
/*
* A: first time called so just malloc everything : don't rely on realloc
* Note: this is still needed so that all the scrollback lines are NULL
*/
screen.text = CALLOC(text_t *, total_rows);
buf_text = CALLOC(text_t *, total_rows);
drawn_text = CALLOC(text_t *, TermWin.nrow);
swap.text = CALLOC(text_t *, TermWin.nrow);
screen.rend = CALLOC(rend_t *, total_rows );
buf_rend = CALLOC(rend_t *, total_rows );
drawn_rend = CALLOC(rend_t *, TermWin.nrow);
swap.rend = CALLOC(rend_t *, TermWin.nrow);
screen.rend = CALLOC(rend_t *, total_rows);
buf_rend = CALLOC(rend_t *, total_rows);
drawn_rend = CALLOC(rend_t *, TermWin.nrow);
swap.rend = CALLOC(rend_t *, TermWin.nrow);
for (i = 0; i < TermWin.nrow; i++) {
j = i + TermWin.saveLines;
make_screen_mem(screen.text, screen.rend, j);
make_screen_mem(swap.text, swap.rend, i);
drawn_text[i] = MALLOC(TermWin.ncol * sizeof(text_t));
drawn_rend[i] = CALLOC(rend_t, TermWin.ncol * sizeof(rend_t));
for (i = 0; i < TermWin.nrow; i++) {
j = i + TermWin.saveLines;
blank_screen_mem(screen.text, screen.rend, j, DEFAULT_RSTYLE);
blank_screen_mem(swap.text, swap.rend, i, DEFAULT_RSTYLE);
blank_screen_mem(drawn_text, drawn_rend, i, DEFAULT_RSTYLE);
}
TermWin.nscrolled = 0; /* no saved lines */
blank_line(screen.text[j], screen.rend[j], TermWin.ncol,
DEFAULT_RSTYLE);
blank_line(swap.text[i], swap.rend[i], TermWin.ncol,
DEFAULT_RSTYLE);
screen.text[j][TermWin.ncol] = 0;
swap.text[i][TermWin.ncol] = 0;
blank_line(drawn_text[i], drawn_rend[i], TermWin.ncol,
DEFAULT_RSTYLE);
}
TermWin.nscrolled = 0; /* no saved lines */
} else {
/*
} else {
/*
* B1: add or delete rows as appropriate
*/
if (TermWin.nrow < prev_nrow) {
/* delete rows */
k = min(TermWin.nscrolled, prev_nrow - TermWin.nrow);
scroll_text(0, prev_nrow - 1, k, 1);
if (TermWin.nrow < prev_nrow) {
/* delete rows */
k = MIN(TermWin.nscrolled, prev_nrow - TermWin.nrow);
scroll_text(0, prev_nrow - 1, k, 1);
/* FIXME: Looks like one of these FREEs can crash Eterm at
* times :( -vendu.
*/
for (i = TermWin.nrow; i < prev_nrow; i++) {
j = i + TermWin.saveLines;
if (screen.text[j])
FREE(screen.text[j]);
if (screen.rend[j])
FREE(screen.rend[j]);
if (swap.text[i])
FREE(swap.text[i]);
if (swap.rend[i])
FREE(swap.rend[i]);
#if 0
FREE(drawn_text[i]);
FREE(drawn_rend[i]);
#endif
/* Added checks. -vendu */
if (drawn_text[i])
FREE(drawn_text[i]);
if (drawn_rend[i])
FREE(drawn_rend[i]);
}
screen.text = REALLOC(screen.text, total_rows * sizeof(text_t*));
buf_text = REALLOC(buf_text , total_rows * sizeof(text_t*));
drawn_text = REALLOC(drawn_text , TermWin.nrow * sizeof(text_t*));
swap.text = REALLOC(swap.text , TermWin.nrow * sizeof(text_t*));
/* FIXME: Looks like one of these FREEs can crash Eterm at
* times :( -vendu.
*/
for (i = TermWin.nrow; i < prev_nrow; i++) {
j = i + TermWin.saveLines;
if (screen.text[j])
FREE(screen.text[j]);
if (screen.rend[j])
FREE(screen.rend[j]);
if (swap.text[i])
FREE(swap.text[i]);
if (swap.rend[i])
FREE(swap.rend[i]);
if (drawn_text[i])
FREE(drawn_text[i]);
if (drawn_rend[i])
FREE(drawn_rend[i]);
}
screen.text = REALLOC(screen.text, total_rows * sizeof(text_t*));
buf_text = REALLOC(buf_text , total_rows * sizeof(text_t*));
drawn_text = REALLOC(drawn_text , TermWin.nrow * sizeof(text_t*));
swap.text = REALLOC(swap.text , TermWin.nrow * sizeof(text_t*));
screen.rend = REALLOC(screen.rend, total_rows * sizeof(rend_t*));
buf_rend = REALLOC(buf_rend , total_rows * sizeof(rend_t*));
drawn_rend = REALLOC(drawn_rend , TermWin.nrow * sizeof(rend_t*));
swap.rend = REALLOC(swap.rend , TermWin.nrow * sizeof(rend_t*));
screen.rend = REALLOC(screen.rend, total_rows * sizeof(rend_t*));
buf_rend = REALLOC(buf_rend , total_rows * sizeof(rend_t*));
drawn_rend = REALLOC(drawn_rend , TermWin.nrow * sizeof(rend_t*));
swap.rend = REALLOC(swap.rend , TermWin.nrow * sizeof(rend_t*));
/* we have fewer rows so fix up number of scrolled lines */
MIN_IT(screen.row, TermWin.nrow - 1);
/* we have fewer rows so fix up number of scrolled lines */
MIN_IT(screen.row, TermWin.nrow - 1);
} else if (TermWin.nrow > prev_nrow) {
/* add rows */
screen.text = REALLOC(screen.text, total_rows * sizeof(text_t*));
buf_text = REALLOC(buf_text , total_rows * sizeof(text_t*));
drawn_text = REALLOC(drawn_text , TermWin.nrow * sizeof(text_t*));
swap.text = REALLOC(swap.text , TermWin.nrow * sizeof(text_t*));
} else if (TermWin.nrow > prev_nrow) {
/* add rows */
screen.text = REALLOC(screen.text, total_rows * sizeof(text_t*));
buf_text = REALLOC(buf_text , total_rows * sizeof(text_t*));
drawn_text = REALLOC(drawn_text , TermWin.nrow * sizeof(text_t*));
swap.text = REALLOC(swap.text , TermWin.nrow * sizeof(text_t*));
screen.rend = REALLOC(screen.rend, total_rows * sizeof(rend_t*));
buf_rend = REALLOC(buf_rend , total_rows * sizeof(rend_t*));
drawn_rend = REALLOC(drawn_rend , TermWin.nrow * sizeof(rend_t*));
swap.rend = REALLOC(swap.rend , TermWin.nrow * sizeof(rend_t*));
screen.rend = REALLOC(screen.rend, total_rows * sizeof(rend_t*));
buf_rend = REALLOC(buf_rend , total_rows * sizeof(rend_t*));
drawn_rend = REALLOC(drawn_rend , TermWin.nrow * sizeof(rend_t*));
swap.rend = REALLOC(swap.rend , TermWin.nrow * sizeof(rend_t*));
k = min(TermWin.nscrolled, TermWin.nrow - prev_nrow);
for (i = prev_total_rows; i < total_rows - k; i++) {
make_screen_mem(screen.text, screen.rend, i);
blank_line(screen.text[i], screen.rend[i], TermWin.ncol,
DEFAULT_RSTYLE);
screen.text[i][TermWin.ncol] = 0;
}
for (i = total_rows - k; i < total_rows; i++)
screen.text[i] = NULL, screen.rend[i] = NULL;
for (i = prev_nrow; i < TermWin.nrow; i++) {
make_screen_mem(swap.text, swap.rend, i);
blank_line(swap.text[i], swap.rend[i], TermWin.ncol,
DEFAULT_RSTYLE);
swap.text[i][TermWin.ncol] = 0;
}
for (i = prev_nrow; i < TermWin.nrow; i++) {
drawn_text[i] = MALLOC(TermWin.ncol * sizeof(text_t));
drawn_rend[i] = CALLOC(rend_t, TermWin.ncol * sizeof(rend_t));
blank_line(drawn_text[i], drawn_rend[i], TermWin.ncol,
DEFAULT_RSTYLE);
}
if (k > 0) {
scroll_text(0, TermWin.nrow - 1, -k, 1);
screen.row += k;
TermWin.nscrolled -= k;
for (i = TermWin.saveLines - TermWin.nscrolled; k--; i--) {
if (screen.text[i] == NULL) {
make_screen_mem(screen.text, screen.rend, i);
blank_line(screen.text[i], screen.rend[i],
TermWin.ncol, DEFAULT_RSTYLE);
screen.text[i][TermWin.ncol] = 0;
}
}
}
}
/* B2: resize columns */
if (TermWin.ncol != prev_ncol) {
for (i = 0; i < total_rows; i++) {
if (screen.text[i]) {
tc = screen.text[i][prev_ncol];
screen.text[i] = REALLOC(screen.text[i],
(TermWin.ncol+1)*sizeof(text_t));
screen.rend[i] = REALLOC(screen.rend[i],
TermWin.ncol*sizeof(rend_t));
screen.text[i][TermWin.ncol] = min(tc,TermWin.ncol);
if (TermWin.ncol > prev_ncol)
blank_line(&(screen.text[i][prev_ncol]),
&(screen.rend[i][prev_ncol]),
TermWin.ncol - prev_ncol, DEFAULT_RSTYLE);
}
}
for (i = 0; i < TermWin.nrow; i++) {
drawn_text[i] = REALLOC(drawn_text[i],
TermWin.ncol*sizeof(text_t));
drawn_rend[i] = REALLOC(drawn_rend[i],
TermWin.ncol*sizeof(rend_t));
if (swap.text[i]) {
tc = swap.text[i][prev_ncol];
swap.text[i] = REALLOC(swap.text[i],
(TermWin.ncol+1)*sizeof(text_t));
swap.rend[i] = REALLOC(swap.rend[i],
TermWin.ncol*sizeof(rend_t));
swap.text[i][TermWin.ncol] = min(tc,TermWin.ncol);
if (TermWin.ncol > prev_ncol)
blank_line(&(swap.text[i][prev_ncol]),
&(swap.rend[i][prev_ncol]),
TermWin.ncol - prev_ncol, DEFAULT_RSTYLE);
}
if (TermWin.ncol > prev_ncol)
blank_line(&(drawn_text[i][prev_ncol]),
&(drawn_rend[i][prev_ncol]),
TermWin.ncol - prev_ncol, DEFAULT_RSTYLE);
}
}
if (tabs)
FREE(tabs);
k = min(TermWin.nscrolled, TermWin.nrow - prev_nrow);
for (i = prev_total_rows; i < total_rows - k; i++) {
blank_screen_mem(screen.text, screen.rend, i, DEFAULT_RSTYLE);
}
for (i = total_rows - k; i < total_rows; i++) {
screen.text[i] = NULL;
screen.rend[i] = NULL;
}
for (i = prev_nrow; i < TermWin.nrow; i++) {
blank_screen_mem(swap.text, swap.rend, i, DEFAULT_RSTYLE);
}
for (i = prev_nrow; i < TermWin.nrow; i++) {
blank_screen_mem(drawn_text, drawn_rend, i, DEFAULT_RSTYLE);
}
if (k > 0) {
scroll_text(0, TermWin.nrow - 1, -k, 1);
screen.row += k;
TermWin.nscrolled -= k;
for (i = TermWin.saveLines - TermWin.nscrolled; k--; i--) {
if (screen.text[i] == NULL) {
blank_screen_mem(screen.text, screen.rend, i, DEFAULT_RSTYLE);
}
}
}
}
/* *INDENT-ON* */
/* B2: resize columns */
if (TermWin.ncol != prev_ncol) {
for (i = 0; i < total_rows; i++) {
if (screen.text[i]) {
tc = screen.text[i][prev_ncol];
screen.text[i] = REALLOC(screen.text[i],
(TermWin.ncol+1)*sizeof(text_t));
screen.rend[i] = REALLOC(screen.rend[i],
TermWin.ncol*sizeof(rend_t));
screen.text[i][TermWin.ncol] = min(tc,TermWin.ncol);
if (TermWin.ncol > prev_ncol)
blank_line(&(screen.text[i][prev_ncol]),
&(screen.rend[i][prev_ncol]),
TermWin.ncol - prev_ncol, DEFAULT_RSTYLE);
}
}
for (i = 0; i < TermWin.nrow; i++) {
drawn_text[i] = REALLOC(drawn_text[i],
TermWin.ncol*sizeof(text_t));
drawn_rend[i] = REALLOC(drawn_rend[i],
TermWin.ncol*sizeof(rend_t));
if (swap.text[i]) {
tc = swap.text[i][prev_ncol];
swap.text[i] = REALLOC(swap.text[i],
(TermWin.ncol+1)*sizeof(text_t));
swap.rend[i] = REALLOC(swap.rend[i],
TermWin.ncol*sizeof(rend_t));
swap.text[i][TermWin.ncol] = min(tc,TermWin.ncol);
if (TermWin.ncol > prev_ncol)
blank_line(&(swap.text[i][prev_ncol]),
&(swap.rend[i][prev_ncol]),
TermWin.ncol - prev_ncol, DEFAULT_RSTYLE);
}
if (TermWin.ncol > prev_ncol)
blank_line(&(drawn_text[i][prev_ncol]),
&(drawn_rend[i][prev_ncol]),
TermWin.ncol - prev_ncol, DEFAULT_RSTYLE);
}
}
if (tabs)
FREE(tabs);
}
tabs = MALLOC(TermWin.ncol * sizeof(char));
for (i = 0; i < TermWin.ncol; i++)
@ -489,9 +473,7 @@ scr_change_screen(int scrn)
scroll_text(0, (TermWin.nrow - 1), TermWin.nrow, 0);
for (i = TermWin.saveLines; i < TermWin.nrow + TermWin.saveLines; i++)
if (screen.text[i] == NULL) {
make_screen_mem(screen.text, screen.rend, i);
blank_line(screen.text[i], screen.rend[i], TermWin.ncol, DEFAULT_RSTYLE);
screen.text[i][TermWin.ncol] = 0;
blank_screen_mem(screen.text, screen.rend, i, DEFAULT_RSTYLE);
}
}
# endif
@ -753,19 +735,14 @@ scr_add_lines(const unsigned char *str, int nlines, int len)
ZERO_SCROLLBACK;
if (nlines > 0) {
nlines += (screen.row - screen.bscroll);
if ((nlines > 0)
&& (screen.tscroll == 0)
&& (screen.bscroll == (TermWin.nrow - 1))) {
D_SCREEN((" -> screen.row == %d, screen.bscroll == %d, new nlines == %d\n", screen.row, screen.bscroll, nlines));
if ((nlines > 0) && (screen.tscroll == 0) && (screen.bscroll == (TermWin.nrow - 1))) {
/* _at least_ this many lines need to be scrolled */
scroll_text(screen.tscroll, screen.bscroll, nlines, 0);
for (i = nlines, row = screen.bscroll + TermWin.saveLines + 1; i--;) {
for (i = nlines, row = screen.bscroll + TermWin.saveLines + 1; row > 0 && i--;) {
/* Move row-- to beginning of loop to avoid segfault. -- added by Sebastien van K */
row--;
if (screen.text[row] == NULL) {
make_screen_mem(screen.text, screen.rend, row);
}
blank_line(screen.text[row], screen.rend[row], TermWin.ncol, rstyle);
screen.text[row][TermWin.ncol] = 0;
blank_screen_mem(screen.text, screen.rend, row, rstyle);
}
screen.row -= nlines;
}
@ -777,7 +754,7 @@ scr_add_lines(const unsigned char *str, int nlines, int len)
row = screen.row + TermWin.saveLines;
if (screen.text[row] == NULL) {
make_screen_mem(screen.text, screen.rend, row);
blank_screen_mem(screen.text, screen.rend, row, DEFAULT_RSTYLE);
} /* avoid segfault -- added by Sebastien van K */
beg.row = screen.row;
beg.col = screen.col;
@ -820,11 +797,7 @@ scr_add_lines(const unsigned char *str, int nlines, int len)
if (screen.row == screen.bscroll) {
scroll_text(screen.tscroll, screen.bscroll, 1, 0);
j = screen.bscroll + TermWin.saveLines;
if (screen.text[j] == NULL)
make_screen_mem(screen.text, screen.rend, j);
blank_line(screen.text[j], screen.rend[j],
TermWin.ncol, DEFAULT_RSTYLE | ((rstyle & RS_RVid) ? (RS_RVid) : (0)));
screen.text[j][TermWin.ncol] = 0;
blank_screen_mem(screen.text, screen.rend, j, DEFAULT_RSTYLE | ((rstyle & RS_RVid) ? (RS_RVid) : (0)));
} else if (screen.row < (TermWin.nrow - 1)) {
screen.row++;
row = screen.row + TermWin.saveLines;
@ -848,14 +821,9 @@ scr_add_lines(const unsigned char *str, int nlines, int len)
if (screen.row == screen.bscroll) {
scroll_text(screen.tscroll, screen.bscroll, 1, 0);
j = screen.bscroll + TermWin.saveLines;
if (screen.text[j] == NULL)
make_screen_mem(screen.text, screen.rend, j);
/*
blank_line(screen.text[j], screen.rend[j], TermWin.ncol,
/* blank_line(screen.text[j], screen.rend[j], TermWin.ncol,
rstyle); Bug fix from John Ellison - need to reset rstyle */
blank_line(screen.text[j], screen.rend[j], TermWin.ncol,
DEFAULT_RSTYLE | ((rstyle & RS_RVid) ? (RS_RVid) : (0)));
screen.text[j][TermWin.ncol] = 0;
blank_screen_mem(screen.text, screen.rend, j, DEFAULT_RSTYLE | ((rstyle & RS_RVid) ? (RS_RVid) : (0)));
} else if (screen.row < (TermWin.nrow - 1)) {
screen.row++;
row = screen.row + TermWin.saveLines;
@ -892,9 +860,6 @@ scr_add_lines(const unsigned char *str, int nlines, int len)
&& selection.end.col >= beg.col))
&& ((selection.beg.row < end.row)
|| (selection.beg.row == end.row
/* FIXME: Changing this to < end.col might fix the no
* whole line selection at the bottom line bug :) -vendu
*/
&& selection.beg.col <= end.col)))
selection_reset();
}
@ -1023,10 +988,7 @@ scr_index(int direction)
dirn = screen.bscroll + TermWin.saveLines;
else
dirn = screen.tscroll + TermWin.saveLines;
if (screen.text[dirn] == NULL) /* then so is screen.rend[dirn] */
make_screen_mem(screen.text, screen.rend, dirn);
blank_line(screen.text[dirn], screen.rend[dirn], TermWin.ncol, rstyle);
screen.text[dirn][TermWin.ncol] = 0;
blank_screen_mem(screen.text, screen.rend, dirn, rstyle);
} else
screen.row += dirn;
MAX_IT(screen.row, 0);
@ -1142,11 +1104,8 @@ scr_erase_screen(int mode)
}
}
for (; num--; row++) {
blank_line(screen.text[row + row_offset],
screen.rend[row + row_offset], TermWin.ncol,
rstyle & ~(RS_RVid | RS_Uline));
screen.text[row + row_offset][TermWin.ncol] = 0;
blank_line(drawn_text[row], drawn_rend[row], TermWin.ncol, ren);
blank_screen_mem(screen.text, screen.rend, row + row_offset, rstyle & ~(RS_RVid | RS_Uline));
blank_screen_mem(drawn_text, drawn_rend, row, ren);
}
}
}
@ -1212,10 +1171,7 @@ scr_insdel_lines(int count, int insdel)
end = screen.row + count - 1 + TermWin.saveLines;
}
for (; count--; end--) {
if (screen.text[end] == NULL) /* then so is screen.rend[end] */
make_screen_mem(screen.text, screen.rend, end);
blank_line(screen.text[end], screen.rend[end], TermWin.ncol, rstyle);
screen.text[end][TermWin.ncol] = 0;
blank_screen_mem(screen.text, screen.rend, end, rstyle);
}
}

View File

@ -42,16 +42,15 @@
* CLEAR_CHARS: clear <num> chars starting from pixel position <x,y>
* ERASE_ROWS : set <num> rows starting from row <row> to the foreground color
*/
#define CLEAR_ROWS(row, num) ((buffer_pixmap) \
? (XCopyArea(Xdisplay, pmap, buffer_pixmap, TermWin.gc, Col2Pixel(0), Row2Pixel(row), TermWin.width, Height2Pixel(num), \
Col2Pixel(0), Row2Pixel(row))) \
: (XClearArea(Xdisplay, TermWin.vt, Col2Pixel(0), Row2Pixel(row), TermWin.width, Height2Pixel(num), 0)))
#define CLEAR_ROWS(row, num) do {if (buffer_pixmap) {XCopyArea(Xdisplay, pmap, buffer_pixmap, TermWin.gc, Col2Pixel(0), Row2Pixel(row), TermWin.width, Height2Pixel(num), \
Col2Pixel(0), Row2Pixel(row));} XClearArea(Xdisplay, TermWin.vt, Col2Pixel(0), Row2Pixel(row), TermWin.width, Height2Pixel(num), 0);} while (0)
#define CLEAR_CHARS(x, y, num) ((buffer_pixmap) \
? (XCopyArea(Xdisplay, pmap, buffer_pixmap, TermWin.gc, x, y, Width2Pixel(num), Height2Pixel(1), x, y)) \
: (XClearArea(Xdisplay, TermWin.vt, x, y, Width2Pixel(num), Height2Pixel(1), 0)))
#define UPDATE_BOX(x1, y1, x2, y2) do {if (buffer_pixmap) {if (x1 < low_x) low_x = x1; if (x2 > high_x) high_x = x2; \
if (y1 < low_y) low_y = y1; if (y2 > high_y) high_y = y2;}} while (0)
#define ERASE_ROWS(row, num) (XFillRectangle(Xdisplay, draw_buffer, TermWin.gc, Col2Pixel(0), Row2Pixel(row), TermWin.width, Height2Pixel(num)))
#define ERASE_ROWS(row, num) do {XFillRectangle(Xdisplay, draw_buffer, TermWin.gc, Col2Pixel(0), Row2Pixel(row), TermWin.width, Height2Pixel(num)); \
if (buffer_pixmap) {XClearArea(Xdisplay, TermWin.vt, Col2Pixel(0), Row2Pixel(row), TermWin.width, Height2Pixel(num), 0);}} while (0)
#define DRAW_STRING(Func, x, y, str, len) Func(Xdisplay, draw_buffer, TermWin.gc, x, y, str, len)
#ifndef NO_BRIGHTCOLOR
# define MONO_BOLD(x) (((x) & RS_Bold) && fore == fgColor)