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:
parent
b1d55e271d
commit
31afa9e2a8
12
ChangeLog
12
ChangeLog
|
@ -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.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
|
|
@ -324,6 +324,7 @@
|
|||
#undef MULTICHAR_ENCODING
|
||||
#undef IOTRACE
|
||||
#undef HAVE_UTEMPTER
|
||||
#undef PTY_GRP_NAME
|
||||
|
||||
|
||||
/* Leave that blank line there!! Autoheader needs it.
|
||||
|
|
26
configure.in
26
configure.in
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
368
src/screen.c
368
src/screen.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue