diff --git a/ChangeLog b/ChangeLog index 361672e..aa5c964 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2964,3 +2964,15 @@ Wed Dec 29 12:32:19 PST 1999 Michael Jennings move themselves if needed, and exposes are now handled properly. ------------------------------------------------------------------------------- +Thu Dec 30 14:55:59 PST 1999 Michael Jennings + + Finally fixed the seg fault pointed out by Tom Gilbert + 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. + +------------------------------------------------------------------------------- diff --git a/acconfig.h b/acconfig.h index 15a8048..e255a7e 100644 --- a/acconfig.h +++ b/acconfig.h @@ -324,6 +324,7 @@ #undef MULTICHAR_ENCODING #undef IOTRACE #undef HAVE_UTEMPTER +#undef PTY_GRP_NAME /* Leave that blank line there!! Autoheader needs it. diff --git a/configure.in b/configure.in index d737d4a..3c8ad8c 100644 --- a/configure.in +++ b/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 diff --git a/libmej/mem.h b/libmej/mem.h index 118548d..1d94e0c 100644 --- a/libmej/mem.h +++ b/libmej/mem.h @@ -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); diff --git a/src/command.c b/src/command.c index 5d8d5fc..5f37601 100644 --- a/src/command.c +++ b/src/command.c @@ -66,7 +66,7 @@ static const char cvs_ident[] = "$Id$"; #include #include #include -#ifdef USE_GETGRNAME +#ifdef PTY_GRP_NAME # include #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)) { diff --git a/src/feature.h b/src/feature.h index c74df6e..b766fb8 100644 --- a/src/feature.h +++ b/src/feature.h @@ -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 diff --git a/src/options.c b/src/options.c index c919fb7..ddf1147 100644 --- a/src/options.c +++ b/src/options.c @@ -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); diff --git a/src/screen.c b/src/screen.c index 7ee9b55..2690ed4 100644 --- a/src/screen.c +++ b/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); } } diff --git a/src/screen.h b/src/screen.h index e7aea31..160aa70 100644 --- a/src/screen.h +++ b/src/screen.h @@ -42,16 +42,15 @@ * CLEAR_CHARS: clear chars starting from pixel position * ERASE_ROWS : set rows starting from 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)