From b942ce9760728fb49779bf935c37cd771591179f Mon Sep 17 00:00:00 2001 From: ache Date: Sun, 28 Aug 1994 21:47:13 +0000 Subject: newwin.c o __FULLINE added for AL/DL/CS optimization with __noqch. refresh.c o Attributes does not turned off before clearing screen, cause highlighted screen. o Proper usage of 'affcnt' tputs parameter, affects terminals with padding. o make AL/DL/CS optimize not only for __FULLWIN but for __FULLLINE. ATTENTION: original code works _only_for_ FULLWIN, i.e. if you use two FULLLINE windows like in 'talk', you have full slow repaint with original code, I enhance this thing. All other fixes marked with phrase 'wrong for non-full windows' or WFNFW is continue of this fix. I rewrite scroll code too for proper working (see below and tty.c changes). o DEBUG code always use 'i' index from 0 to curscr->maxy instead of 'i - win->begy', fixed o check added into DEBUG to be shure that index inside current window. o ->hash assigment code is WFNFW (forget win->begy). o when CE usage required, and last spaces number counted, code don't check attributes, so last standouted space will be incorrectly cleared. o cep (start pointer) forget to add win->begy/win->begx, code WFNFW. o clsp (last space) wrong in two places at once: forget to add win->begy (WFNFW) and incorrectly use 'win->begx * __LDATASIZE' in pointer arithmetics. o clsp check incorrect: was 'clsp < win->maxx * __LDATASIZE', need to be 'clsp < win->maxx o Attributes does not turned off before clearing end of line, cause highlighted end of line. o When find how many lines from the top/bottom of the screen are unchanged, code always forget '- win->begy', WFNFW. o NO_JERKINESS code forgets to add win->begy, WFNFW. o Curw & Curs changed in comment description o In search for the largest block of text not changed forget to add '- win->begy' (several places), WFNFW. o Forget to add '- win->begy' for non-dirty lines, WFNFW. o touchline forget to add '- win->begy', WFNFW. o rewrite scrolln(): * remove win parameter, we deal with whole screen (curscr) now; * use NL or '\n' instead of sf, it is faster in any case; (imagine: cat written on curses now use '\n' for scroll like standard cat, no ugly escapes) * use dl (if present) instead of DL, if abs(n) == 1, the same about al/sr, it is faster; * change win->maxy to 'curscr->maxy - 1', we deal with whole screen here, WFNFW. * SF can be correctly issued only if cursor at bottom of scroll region (whole screen region included too), fix this; * sr/SR can be correctly issued only if cursor at top of scroll region (whole screen region included too), fix this; * use pre-calculaded (in setterm.c) __usecs variable to determine usage of CS or AL/DL; * completely rewrite scroll region stuff using __set_scroll_region from tty.c (see below); tty.c o Added __set_scroll_region function which set CS region and stays back in old position. Use SC/RC (save/restore cursor) if possible, else use HO and __mvcur. o __startwin: added __set_scroll_region(whole screen) at program startup, if __usecs; o endwin: added __set_scroll_region(whole screen) at program exit, if __usecs; o Fix all tc{set/get}attrs to works properly, when stdin redirected, use /dev/tty in this case (needed for some applications). setterm.c o Add new variable __usecs, if (!AL/al || !Dl/dl) && CS && (SC && RC || HO) (save/restore cursor used in __set_scroll_region in tty.c). o Set __noqch, if !__usecs && (!AL/al || !DL/dl). o Proper ospeed initialization for tputs, i.e. if speed == B9600, ospeed = 13 curses.c o Add __usecs variable that indicates usage of CS (if AL/DL absent). curses.h o Allow translation with applications which includes , undef BXXX manually to avoid redefinition and include termios to define proper ones. o Define old-style names curx/begx/maxx/etc. for old applications. Define _tty like __baset too. o Typedef SGTTY type for old applications (SGTTY == struct termios). o wstandout/wstandend should be int and not char*, some old applications relay on this fact. See standout.c too. o __FULLINE added indicated line width == terminal width, needed for refresh using AL/DL/CS with __noqch, see refresh.c changes. o Add extern __usecs variable that indicates usage of CS (if AL/DL absent). o Add __set_scroll_region() prototype, see tty.c and refresh.c changes for details. o Change winch() character mask from 0177 to 0377, we don't need to strip high bit on national characters. o Allow translate on systems with _BSD_VA_LIST_ undefined, such as FreeBSD 1.1.5.1 o __tty_fileno added to allows work with stdin redirected, see tty.c o Privately declare tputs (..., void) and externally tputs(..., int), many applications require this. Maybe not nice thing, but needed. o Remove _putchar definition and replace it to proper _putchar prototype, some old apps declares: 'extern int _putchar()' and don't even include curses.h in such modules. See putchar.c cr_put.c o __mvcur: if destline == destcol && outline == outcol do nothing, i.e. don't issue any escapes. o Proper usage of 'affcnt' tputs parameter, affects terminals with padding. cur_hash.c o Change char->unsigned char for proper sum 8-bit national characters. getch.c o check for inp == EOF added, don't add EOF to window. getstr.c o check for EOF added, don't add EOF to str. insertln.c o add cast to (int) in comparation of y and win->cury, this produce big number (cast to (unsigned)) if y < 0 tstp.c o Fix all tc{set/get}attrs to works properly, when stdin redirected, use /dev/tty in this case (needed for some applications). o add tstp() function for compatibility, some applications wants it. standout.c o Some old applications relay in fact that wstandout/wstandend returns int instead of char*, change return type to OK/ERR. putchar.c o Add _putchar function (which calls __cputchar), some old apps declares: 'extern int _putchar()' and don't even include curses.h in such modules. --- lib/libcurses/cr_put.c | 23 ++-- lib/libcurses/cur_hash.c | 4 +- lib/libcurses/curses.c | 6 + lib/libcurses/curses.h | 69 +++++++++-- lib/libcurses/getch.c | 12 +- lib/libcurses/getstr.c | 14 +-- lib/libcurses/insertln.c | 2 +- lib/libcurses/newwin.c | 9 +- lib/libcurses/putchar.c | 8 ++ lib/libcurses/refresh.c | 296 ++++++++++++++++++++++++++--------------------- lib/libcurses/setterm.c | 42 ++++++- lib/libcurses/standout.c | 12 +- lib/libcurses/tstp.c | 10 +- lib/libcurses/tty.c | 56 ++++++--- 14 files changed, 373 insertions(+), 190 deletions(-) (limited to 'lib/libcurses') diff --git a/lib/libcurses/cr_put.c b/lib/libcurses/cr_put.c index ada2df5..e6a790e 100644 --- a/lib/libcurses/cr_put.c +++ b/lib/libcurses/cr_put.c @@ -79,7 +79,8 @@ __mvcur(ly, lx, y, x, in_refresh) destline = y; outcol = lx; outline = ly; - fgoto(in_refresh); + if (destline != destcol || outline != outcol) + fgoto(in_refresh); return (OK); } @@ -102,11 +103,11 @@ fgoto(in_refresh) while (l > 0) { if (__pfast) if (CR) - tputs(CR, 0, __cputchar); + tputs(CR, 1, __cputchar); else putchar('\r'); if (NL) - tputs(NL, 0, __cputchar); + tputs(NL, 1, __cputchar); else putchar('\n'); l--; @@ -147,7 +148,7 @@ fgoto(in_refresh) * Eggert's Superbee description which wins better. */ if (NL /* && !XB */ && __pfast) - tputs(NL, 0, __cputchar); + tputs(NL, 1, __cputchar); else putchar('\n'); l--; @@ -167,7 +168,7 @@ fgoto(in_refresh) if (outcol != COLS - 1 && plod(strlen(cgp), in_refresh) > 0) plod(0, in_refresh); else - tputs(cgp, 0, __cputchar); + tputs(cgp, 1, __cputchar); } else plod(0, in_refresh); outline = destline; @@ -244,7 +245,7 @@ plod(cnt, in_refresh) * Cheaper to home. Do it now and pretend it's a * regular local motion. */ - tputs(HO, 0, plodput); + tputs(HO, 1, plodput); outcol = outline = 0; } else if (LL) { /* @@ -253,7 +254,7 @@ plod(cnt, in_refresh) */ k = (LINES - 1) - destline; if (i + k + 2 < j && (k <= 0 || UP)) { - tputs(LL, 0, plodput); + tputs(LL, 1, plodput); outcol = 0; outline = LINES - 1; } @@ -303,12 +304,12 @@ plod(cnt, in_refresh) * into account. */ if (CR) - tputs(CR, 0, plodput); + tputs(CR, 1, plodput); else plodput('\r'); if (NC) { if (NL) - tputs(NL, 0, plodput); + tputs(NL, 1, plodput); else plodput('\n'); outline++; @@ -319,7 +320,7 @@ plod(cnt, in_refresh) dontcr: while (outline < destline) { outline++; if (NL) - tputs(NL, 0, plodput); + tputs(NL, 1, plodput); else plodput('\n'); if (plodcnt < 0) @@ -348,7 +349,7 @@ dontcr: while (outline < destline) { } while (outline > destline) { outline--; - tputs(UP, 0, plodput); + tputs(UP, 1, plodput); if (plodcnt < 0) goto out; } diff --git a/lib/libcurses/cur_hash.c b/lib/libcurses/cur_hash.c index ed47fe3..de6ab11 100644 --- a/lib/libcurses/cur_hash.c +++ b/lib/libcurses/cur_hash.c @@ -43,7 +43,7 @@ static char sccsid[] = "@(#)cur_hash.c 8.1 (Berkeley) 6/4/93"; */ u_int __hash(s, len) - char *s; + unsigned char *s; int len; { register u_int h, g, i; @@ -51,7 +51,7 @@ __hash(s, len) h = 0; i = 0; while (i < len) { - h = (h << 4) + s[i]; + h = (h << 4) + s[i]; if (g = h & 0xf0000000) { h = h ^ (g >> 24); h = h ^ g; diff --git a/lib/libcurses/curses.c b/lib/libcurses/curses.c index 07cbb5b..e3081c0 100644 --- a/lib/libcurses/curses.c +++ b/lib/libcurses/curses.c @@ -44,8 +44,14 @@ int __rawmode = 0; /* If stty indicates RAW mode. */ int __noqch = 0; /* * If terminal doesn't have * insert/delete line capabilities + * or change scroll capabilities * for quick change on refresh. */ +int __usecs = 0; /* + * If terminal able to change scroll + * region (used only if insert/delete + * line capabilities absent) + */ char AM, BS, CA, DA, EO, HC, IN, MI, MS, NC, NS, OS, PC, UL, XB, XN, XT, XS, XX; char *AL, *BC, *BT, *CD, *CE, *CL, *CM, *CR, *CS, *DC, *DL, diff --git a/lib/libcurses/curses.h b/lib/libcurses/curses.h index 3c585e6..9e18183 100644 --- a/lib/libcurses/curses.h +++ b/lib/libcurses/curses.h @@ -41,6 +41,10 @@ #include +#ifndef _BSD_VA_LIST_ +#define _BSD_VA_LIST_ char * +#endif + /* * The following #defines and #includes are present for backward * compatibility only. They should not be used in future code. @@ -48,6 +52,34 @@ * START BACKWARD COMPATIBILITY ONLY. */ #ifndef _CURSES_PRIVATE + +/* This stuff needed for those pgms which include */ +/* Undef things manually to avoid redefinition */ + +#undef USE_OLD_TTY +#undef B0 +#undef B50 +#undef B75 +#undef B110 +#undef B134 +#undef B150 +#undef B200 +#undef B300 +#undef B600 +#undef B1200 +#undef B1800 +#undef B2400 +#undef B4800 +#undef B9600 +#undef EXTA +#undef EXTB +#undef B57600 +#undef B115200 + +#include +#include +#include /* For sgttyb and related */ + #define bool char #define reg register @@ -59,7 +91,6 @@ #endif #define _puts(s) tputs(s, 0, __cputchar) -#define _putchar(c) __cputchar(c) /* Old-style terminal modes access. */ #define baudrate() (cfgetospeed(&__baset)) @@ -68,6 +99,17 @@ #define killchar() (__baset.c_cc[VKILL]) #define nocrmode() nocbreak() #define ospeed (cfgetospeed(&__baset)) + +/* WINDOW structure members name compatibility */ +#define _curx curx +#define _cury cury +#define _begx begx +#define _begy begy +#define _maxx maxx +#define _maxy maxy + +#define _tty __baset + #endif /* _CURSES_PRIVATE */ extern char GT; /* Gtty indicates tabs. */ @@ -147,6 +189,7 @@ typedef struct __window { /* Window structure. */ #define __CLEAROK 0x040 /* Clear on next refresh. */ #define __WSTANDOUT 0x080 /* Standout window */ #define __LEAVEOK 0x100 /* If curser left */ +#define __FULLLINE 0x200 /* Line width = terminal width. */ u_int flags; } WINDOW; @@ -154,9 +197,12 @@ typedef struct __window { /* Window structure. */ extern WINDOW *curscr; /* Current screen. */ extern WINDOW *stdscr; /* Standard screen. */ -extern struct termios __orig_termios; /* Terminal state before curses */ -extern struct termios __baset; /* Our base terminal state */ +typedef struct termios SGTTY; + +extern SGTTY __orig_termios; /* Terminal state before curses */ +extern SGTTY __baset; /* Our base terminal state */ extern int __tcaction; /* If terminal hardware set. */ +extern int __tty_fileno; /* Terminal file descriptor */ extern int COLS; /* Columns on the screen. */ extern int LINES; /* Lines on the screen. */ @@ -230,7 +276,7 @@ extern char *ttytype; /* Full name of current terminal. */ #define scrollok(w, bf) \ ((bf) ? ((w)->flags |= __SCROLLOK) : ((w)->flags &= ~__SCROLLOK)) #define winch(w) \ - ((w)->lines[(w)->cury]->line[(w)->curx].ch & 0177) + ((w)->lines[(w)->cury]->line[(w)->curx].ch & 0377) /* Public function prototypes. */ int box __P((WINDOW *, int, int)); @@ -289,12 +335,13 @@ int wmove __P((WINDOW *, int, int)); int wprintw __P((WINDOW *, const char *, ...)); int wrefresh __P((WINDOW *)); int wscanw __P((WINDOW *, const char *, ...)); -char *wstandend __P((WINDOW *)); -char *wstandout __P((WINDOW *)); +int wstandend __P((WINDOW *)); +int wstandout __P((WINDOW *)); int vwprintw __P((WINDOW *, const char *, _BSD_VA_LIST_)); /* Private functions that are needed for user programs prototypes. */ void __cputchar __P((int)); +int _putchar __P((int)); int __waddbytes __P((WINDOW *, const char *, int, int)); /* Private functions. */ @@ -306,6 +353,7 @@ int __mvcur __P((int, int, int, int, int)); void __restore_stophandler __P((void)); void __set_stophandler __P((void)); void __set_subwin __P((WINDOW *, WINDOW *)); +void __set_scroll_region __P((int, int, int, int)); void __startwin __P((void)); void __stop_signal_handler __P((int)); void __swflags __P((WINDOW *)); @@ -324,6 +372,14 @@ extern int __endwin; extern int __pfast; extern int __rawmode; extern int __noqch; +extern int __usecs; + +int tputs __P((char *, int, void (*)(int))); + +#else + +int tputs __P((char *, int, int (*)(int))); + #endif /* Termcap functions. */ @@ -332,6 +388,5 @@ int tgetnum __P((char *)); int tgetflag __P((char *)); char *tgetstr __P((char *, char **)); char *tgoto __P((char *, int, int)); -int tputs __P((char *, int, void (*)(int))); #endif /* !_CURSES_H_ */ diff --git a/lib/libcurses/getch.c b/lib/libcurses/getch.c index 6108229..31dd2b6 100644 --- a/lib/libcurses/getch.c +++ b/lib/libcurses/getch.c @@ -61,13 +61,15 @@ wgetch(win) weset = 0; inp = getchar(); + if (inp != EOF) { #ifdef DEBUG - __CTRACE("wgetch got '%s'\n", unctrl(inp)); + __CTRACE("wgetch got '%s'\n", unctrl(inp)); #endif - if (__echoit) { - mvwaddch(curscr, - win->cury + win->begy, win->curx + win->begx, inp); - waddch(win, inp); + if (__echoit) { + mvwaddch(curscr, + win->cury + win->begy, win->curx + win->begx, inp); + waddch(win, inp); + } } if (weset) nocbreak(); diff --git a/lib/libcurses/getstr.c b/lib/libcurses/getstr.c index daf8e61..2536999 100644 --- a/lib/libcurses/getstr.c +++ b/lib/libcurses/getstr.c @@ -46,12 +46,12 @@ wgetstr(win, str) register WINDOW *win; register char *str; { - while ((*str = wgetch(win)) != ERR && *str != '\n') - str++; - if (*str == ERR) { - *str = '\0'; - return (ERR); - } - *str = '\0'; + int c; + + while ((c = wgetch(win)) != ERR && c != EOF && c != '\n') + *str++ = c; + *str = '\0'; + if (c == ERR) + return (ERR); return (OK); } diff --git a/lib/libcurses/insertln.c b/lib/libcurses/insertln.c index c2179f0..4de367e 100644 --- a/lib/libcurses/insertln.c +++ b/lib/libcurses/insertln.c @@ -56,7 +56,7 @@ winsertln(win) #endif if (win->orig == NULL) temp = win->lines[win->maxy - 1]; - for (y = win->maxy - 1; y > win->cury; --y) { + for (y = win->maxy - 1; y > (int) win->cury; --y) { win->lines[y]->flags &= ~__ISPASTEOL; win->lines[y - 1]->flags &= ~__ISPASTEOL; if (win->orig == NULL) diff --git a/lib/libcurses/newwin.c b/lib/libcurses/newwin.c index 161b5d9..79e5f2a 100644 --- a/lib/libcurses/newwin.c +++ b/lib/libcurses/newwin.c @@ -233,11 +233,16 @@ void __swflags(win) register WINDOW *win; { - win->flags &= ~(__ENDLINE | __FULLWIN | __SCROLLWIN | __LEAVEOK); + win->flags &= + ~(__ENDLINE | __FULLLINE | __FULLWIN | __SCROLLWIN | __LEAVEOK); if (win->begx + win->maxx == COLS) { win->flags |= __ENDLINE; - if (win->begx == 0 && win->maxy == LINES && win->begy == 0) + if (win->begx == 0) { + if (!__noqch) + win->flags |= __FULLLINE; + if (win->maxy == LINES && win->begy == 0) win->flags |= __FULLWIN; + } if (win->begy + win->maxy == LINES) win->flags |= __SCROLLWIN; } diff --git a/lib/libcurses/putchar.c b/lib/libcurses/putchar.c index 2ed5bb4..0a629ce 100644 --- a/lib/libcurses/putchar.c +++ b/lib/libcurses/putchar.c @@ -47,3 +47,11 @@ __cputchar(ch) #endif (void)putchar(ch); } + +int +_putchar(ch) + int ch; +{ + __cputchar(ch); + return 0; +} diff --git a/lib/libcurses/refresh.c b/lib/libcurses/refresh.c index d2f5ca6..93e80d3 100644 --- a/lib/libcurses/refresh.c +++ b/lib/libcurses/refresh.c @@ -45,7 +45,7 @@ static short ly, lx; static void domvcur __P((int, int, int, int)); static int makech __P((WINDOW *, int)); static void quickch __P((WINDOW *)); -static void scrolln __P((WINDOW *, int, int, int, int, int)); +static void scrolln __P((int, int, int, int, int)); /* * wrefresh -- @@ -77,7 +77,11 @@ wrefresh(win) if (win->flags & __CLEAROK || curscr->flags & __CLEAROK || curwin) { if ((win->flags & __FULLWIN) || curscr->flags & __CLEAROK) { - tputs(CL, 0, __cputchar); + if (curscr->flags & __WSTANDOUT) { + tputs(SE, 0, __cputchar); + curscr->flags &= ~__WSTANDOUT; + } + tputs(CL, win->maxy, __cputchar); ly = 0; lx = 0; if (!curwin) { @@ -102,7 +106,7 @@ wrefresh(win) #endif #ifndef NOQCH - if ((win->flags & __FULLWIN) && !curwin) { + if ((win->flags & __FULLLINE) && !curwin) { /* * Invoke quickch() only if more than a quarter of the lines * in the window are dirty. @@ -110,7 +114,8 @@ wrefresh(win) for (wy = 0, dnum = 0; wy < win->maxy; wy++) if (win->lines[wy]->flags & (__ISDIRTY | __FORCEPAINT)) dnum++; - if (!__noqch && dnum > (int) win->maxy / 4) + /* __noqch already == 0 when __FULLLINE */ + if (dnum > (int) win->maxy / 4) quickch(win); } #endif @@ -129,16 +134,18 @@ wrefresh(win) __CTRACE("%x", curscr->lines[i]->line[j].attr); __CTRACE("\n"); - __CTRACE("W: %d:", i); - __CTRACE(" 0x%x \n", win->lines[i]->hash); - __CTRACE(" 0x%x ", win->lines[i]->flags); + if (i < win->begy || i > win->begy + win->maxy - 1) + continue; + __CTRACE("W: %d:", i - win->begy); + __CTRACE(" 0x%x \n", win->lines[i - win->begy]->hash); + __CTRACE(" 0x%x ", win->lines[i - win->begy]->flags); for (j = 0; j < win->maxx; j++) __CTRACE("%c", - win->lines[i]->line[j].ch); + win->lines[i - win->begy]->line[j].ch); __CTRACE("\n"); for (j = 0; j < win->maxx; j++) __CTRACE("%x", - win->lines[i]->line[j].attr); + win->lines[i - win->begy]->line[j].attr); __CTRACE("\n"); } } @@ -150,7 +157,7 @@ wrefresh(win) wy, *win->lines[wy]->firstchp, *win->lines[wy]->lastchp); #endif if (!curwin) - curscr->lines[wy]->hash = win->lines[wy]->hash; + curscr->lines[win->begy + wy]->hash = win->lines[wy]->hash; if (win->lines[wy]->flags & (__ISDIRTY | __FORCEPAINT)) { if (makech(win, wy) == ERR) return (ERR); @@ -264,9 +271,9 @@ makech(win, wy) if (force) { if (CM) - tputs(tgoto(CM, lx, ly), 0, __cputchar); + tputs(tgoto(CM, lx, ly), 1, __cputchar); else { - tputs(HO, 0, __cputchar); + tputs(HO, 1, __cputchar); __mvcur(0, 0, ly, lx, 1); } } @@ -296,24 +303,28 @@ makech(win, wy) && wx <= lch) { if (ce != NULL && win->maxx + win->begx == - curscr->maxx && wx >= nlsp && nsp->ch == ' ') { + curscr->maxx && wx >= nlsp && nsp->ch == ' ' && nsp->attr == 0) { /* Check for clear to end-of-line. */ - cep = &curscr->lines[wy]->line[win->maxx - 1]; + cep = &curscr->lines[win->begy + wy]->line[win->begx + win->maxx - 1]; while (cep->ch == ' ' && cep->attr == 0) if (cep-- <= csp) break; - clsp = cep - curscr->lines[wy]->line - - win->begx * __LDATASIZE; + clsp = cep - curscr->lines[win->begy + wy]->line - + win->begx; #ifdef DEBUG __CTRACE("makech: clsp = %d, nlsp = %d\n", clsp, nlsp); #endif if ((clsp - nlsp >= strlen(CE) - && clsp < win->maxx * __LDATASIZE) || + && clsp < win->maxx) || wy == win->maxy - 1) { #ifdef DEBUG __CTRACE("makech: using CE\n"); #endif - tputs(CE, 0, __cputchar); + if (curscr->flags & __WSTANDOUT) { + tputs(SE, 0, __cputchar); + curscr->flags &= ~__WSTANDOUT; + } + tputs(CE, 1, __cputchar); lx = wx + win->begx; while (wx++ <= clsp) { csp->ch = ' '; @@ -439,27 +450,27 @@ quickch(win) /* * Find how many lines from the top of the screen are unchanged. */ - for (top = 0; top < win->maxy; top++) - if (win->lines[top]->flags & __FORCEPAINT || - win->lines[top]->hash != curscr->lines[top]->hash - || memcmp(win->lines[top]->line, + for (top = win->begy; top < win->begy + win->maxy; top++) + if (win->lines[top - win->begy]->flags & __FORCEPAINT || + win->lines[top - win->begy]->hash != curscr->lines[top]->hash + || memcmp(win->lines[top - win->begy]->line, curscr->lines[top]->line, win->maxx * __LDATASIZE) != 0) break; else - win->lines[top]->flags &= ~__ISDIRTY; + win->lines[top - win->begy]->flags &= ~__ISDIRTY; /* * Find how many lines from bottom of screen are unchanged. */ - for (bot = win->maxy - 1; bot >= 0; bot--) - if (win->lines[bot]->flags & __FORCEPAINT || - win->lines[bot]->hash != curscr->lines[bot]->hash - || memcmp(win->lines[bot]->line, + for (bot = win->begy + win->maxy - 1; bot >= (int) win->begy; bot--) + if (win->lines[bot - win->begy]->flags & __FORCEPAINT || + win->lines[bot - win->begy]->hash != curscr->lines[bot]->hash + || memcmp(win->lines[bot - win->begy]->line, curscr->lines[bot]->line, win->maxx * __LDATASIZE) != 0) break; else - win->lines[bot]->flags &= ~__ISDIRTY; + win->lines[bot - win->begy]->flags &= ~__ISDIRTY; #ifdef NO_JERKINESS /* @@ -468,7 +479,7 @@ quickch(win) * This will increase the number of characters sent to the screen * but it looks better. */ - if (bot < win->maxy - 1) + if (bot < (int) win->begy + win->maxy - 1) return; #endif /* NO_JERKINESS */ @@ -478,8 +489,8 @@ quickch(win) * - Startw is the index of the beginning of the examined block in win. * - Starts is the index of the beginning of the examined block in * curscr. - * - Curs is the index of one past the end of the exmined block in win. - * - Curw is the index of one past the end of the exmined block in + * - Curw is the index of one past the end of the exmined block in win. + * - Curs is the index of one past the end of the exmined block in * curscr. * - bsize is the current size of the examined block. */ @@ -489,11 +500,11 @@ quickch(win) starts++) { for (curw = startw, curs = starts; curs < starts + bsize; curw++, curs++) - if (win->lines[curw]->flags & + if (win->lines[curw - win->begy]->flags & __FORCEPAINT || - (win->lines[curw]->hash != + (win->lines[curw - win->begy]->hash != curscr->lines[curs]->hash || - memcmp(win->lines[curw]->line, + memcmp(win->lines[curw - win->begy]->line, curscr->lines[curs]->line, win->maxx * __LDATASIZE) != 0)) break; @@ -535,16 +546,18 @@ quickch(win) __CTRACE("%x", curscr->lines[i]->line[j].attr); __CTRACE("\n"); - __CTRACE("W: %d:", i); - __CTRACE(" 0x%x \n", win->lines[i]->hash); - __CTRACE(" 0x%x ", win->lines[i]->flags); + if (i < win->begy || i > win->begy + win->maxy - 1) + continue; + __CTRACE("W: %d:", i - win->begy); + __CTRACE(" 0x%x \n", win->lines[i - win->begy]->hash); + __CTRACE(" 0x%x ", win->lines[i - win->begy]->flags); for (j = 0; j < win->maxx; j++) __CTRACE("%c", - win->lines[i]->line[j].ch); + win->lines[i - win->begy]->line[j].ch); __CTRACE("\n"); for (j = 0; j < win->maxx; j++) __CTRACE("%x", - win->lines[i]->line[j].attr); + win->lines[i - win->begy]->line[j].attr); __CTRACE("\n"); } #endif @@ -607,7 +620,7 @@ quickch(win) #ifdef DEBUG __CTRACE("-- notdirty"); #endif - win->lines[target]->flags &= ~__ISDIRTY; + win->lines[target - win->begy]->flags &= ~__ISDIRTY; } else if ((n > 0 && target >= top && target < top + n) || (n < 0 && target <= bot && target > bot + n)) { if (clp->hash != blank_hash || memcmp(clp->line, @@ -618,9 +631,9 @@ quickch(win) __CTRACE("-- blanked out: dirty"); #endif clp->hash = blank_hash; - __touchline(win, target, 0, win->maxx - 1, 0); + __touchline(win, target - win->begy, 0, win->maxx - 1, 0); } else { - __touchline(win, target, 0, win->maxx - 1, 0); + __touchline(win, target - win->begy, 0, win->maxx - 1, 0); #ifdef DEBUG __CTRACE(" -- blank line already: dirty"); #endif @@ -629,7 +642,7 @@ quickch(win) #ifdef DEBUG __CTRACE(" -- dirty"); #endif - __touchline(win, target, 0, win->maxx - 1, 0); + __touchline(win, target - win->begy, 0, win->maxx - 1, 0); } #ifdef DEBUG __CTRACE("\n"); @@ -651,15 +664,18 @@ quickch(win) __CTRACE("%c", curscr->lines[i]->line[j].ch); __CTRACE("\n"); - __CTRACE("W: %d:", i); + if (i < win->begy || i > win->begy + win->maxy - 1) + continue; + __CTRACE("W: %d:", i - win->begy); for (j = 0; j < win->maxx; j++) - __CTRACE("%c", win->lines[i]->line[j].ch); + __CTRACE("%c", + win->lines[i - win->begy]->line[j].ch); __CTRACE("\n"); } #endif if (n != 0) { WINDOW *wp; - scrolln(win, starts, startw, curs, bot, top); + scrolln(starts, startw, curs, bot, top); /* * Need to repoint any subwindow lines to the rotated * line structured. @@ -674,8 +690,7 @@ quickch(win) * Scroll n lines, where n is starts - startw. */ static void -scrolln(win, starts, startw, curs, bot, top) - WINDOW *win; +scrolln(starts, startw, curs, bot, top) int starts, startw, curs, bot, top; { int i, oy, ox, n; @@ -685,19 +700,6 @@ scrolln(win, starts, startw, curs, bot, top) n = starts - startw; /* - * XXX - * The initial tests that set __noqch don't let us reach here unless - * we have either CS + HO + SF/sf/SR/sr, or AL + DL. SF/sf and SR/sr - * scrolling can only shift the entire scrolling region, not just a - * part of it, which means that the quickch() routine is going to be - * sadly disappointed in us if we don't have CS as well. - * - * If CS, HO and SF/sf are set, can use the scrolling region. Because - * the cursor position after CS is undefined, we need HO which gives us - * the ability to move to somewhere without knowledge of the current - * location of the cursor. Still call __mvcur() anyway, to update its - * idea of where the cursor is. - * * When the scrolling region has been set, the cursor has to be at the * last line of the region to make the scroll happen. * @@ -707,48 +709,86 @@ scrolln(win, starts, startw, curs, bot, top) * AL/DL, otherwise use the scrolling region. The "almost all" is a * shameless hack for vi. */ - if (n > 0) { - if (CS != NULL && HO != NULL && (SF != NULL || - (AL == NULL || DL == NULL || - top > 3 || bot + 3 < win->maxy) && sf != NULL)) { - tputs(__tscroll(CS, top, bot + 1), 0, __cputchar); - __mvcur(oy, ox, 0, 0, 1); - tputs(HO, 0, __cputchar); - __mvcur(0, 0, bot, 0, 1); - if (SF != NULL) - tputs(__tscroll(SF, n, 0), 0, __cputchar); - else - for (i = 0; i < n; i++) - tputs(sf, 0, __cputchar); - tputs(__tscroll(CS, 0, win->maxy), 0, __cputchar); - __mvcur(bot, 0, 0, 0, 1); - tputs(HO, 0, __cputchar); - __mvcur(0, 0, oy, ox, 1); - return; + + if (__usecs) { /* Use change scroll region */ + if (bot != curscr->maxy - 1 || top != 0) + __set_scroll_region(top, bot, ox, oy); + if (n > 0) { + __mvcur(oy, ox, bot, 0, 1); + /* Scroll up the block */ + if (SF != NULL && n > 1) + tputs(__tscroll(SF, n, 0), n, __cputchar); + else + /* newline seems faster than sf */ + for(i = 0; i < n; i++) + if (NL && __pfast) + tputs(NL, 1, __cputchar); + else + putchar('\n'); + __mvcur(bot, 0, oy, ox, 1); + } else { + __mvcur(oy, ox, top, 0, 1); + /* Scroll the block down */ + if (SR != NULL && (sr == NULL || -n > 1)) + tputs(__tscroll(SR, -n, 0), -n, __cputchar); + else + for(i = n; i < 0; i++) + tputs(sr, 1, __cputchar); + __mvcur(top, 0, oy, ox, 1); } + if (bot != curscr->maxy - 1 || top != 0) + __set_scroll_region(0, curscr->maxy - 1, ox, oy); + return; + } + if (n > 0) { /* Scroll up the block. */ - __mvcur(oy, ox, top, 0, 1); - if (SF != NULL && top == 0) - tputs(__tscroll(SF, n, 0), 0, __cputchar); - else if (DL != NULL) - tputs(__tscroll(DL, n, 0), 0, __cputchar); - else if (dl != NULL) - for (i = 0; i < n; i++) - tputs(dl, 0, __cputchar); - else if (sf != NULL && top == 0) + if (SF != NULL && top == 0) { + __mvcur(oy, ox, curscr->maxy - 1, 0, 1); + if (n == 1) + goto f_nl1; + tputs(__tscroll(SF, n, 0), n, __cputchar); + __mvcur(curscr->maxy - 1, 0, bot - n + 1, 0, 1); + } + else if (DL != NULL && top != 0) { + __mvcur(oy, ox, top, 0, 1); + if (dl != NULL && n == 1) + goto f_dl1; + tputs(__tscroll(DL, n, 0), n, __cputchar); + __mvcur(top, 0, bot - n + 1, 0, 1); + } + else if (dl != NULL && top != 0) { + __mvcur(oy, ox, top, 0, 1); + f_dl1: for (i = 0; i < n; i++) - tputs(sf, 0, __cputchar); + tputs(dl, 1, __cputchar); + __mvcur(top, 0, bot - n + 1, 0, 1); + } + else if (top == 0) { + __mvcur(oy, ox, curscr->maxy - 1, 0, 1); + f_nl1: + /* newline seems faster than sf */ + for(i = 0; i < n; i++) + if (NL && __pfast) + tputs(NL, 1, __cputchar); + else + putchar('\n'); + __mvcur(curscr->maxy - 1, 0, bot - n + 1, 0, 1); + } else abort(); /* Push down the bottom region. */ - __mvcur(top, 0, bot - n + 1, 0, 1); - if (AL != NULL) - tputs(__tscroll(AL, n, 0), 0, __cputchar); - else if (al != NULL) + if (AL != NULL) { + if (al != NULL && n == 1) + goto f_al1; + tputs(__tscroll(AL, n, 0), n, __cputchar); + } + else if (al != NULL) { + f_al1: for (i = 0; i < n; i++) - tputs(al, 0, __cputchar); + tputs(al, 1, __cputchar); + } else abort(); __mvcur(bot - n + 1, 0, oy, ox, 1); @@ -756,52 +796,50 @@ scrolln(win, starts, startw, curs, bot, top) /* * !!! * n < 0 - * - * If CS, HO and SR/sr are set, can use the scrolling region. - * See the above comments for details. */ - if (CS != NULL && HO != NULL && (SR != NULL || - (AL == NULL || DL == NULL || - top > 3 || bot + 3 < win->maxy) && sr != NULL)) { - tputs(__tscroll(CS, top, bot + 1), 0, __cputchar); + /* Preserve the bottom lines. */ + if (SR != NULL && bot == curscr->maxy - 1) { __mvcur(oy, ox, 0, 0, 1); - tputs(HO, 0, __cputchar); + if (sr != NULL && -n == 1) + goto b_sr1; + tputs(__tscroll(SR, -n, 0), -n, __cputchar); __mvcur(0, 0, top, 0, 1); - - if (SR != NULL) - tputs(__tscroll(SR, -n, 0), 0, __cputchar); - else - for (i = n; i < 0; i++) - tputs(sr, 0, __cputchar); - tputs(__tscroll(CS, 0, win->maxy), 0, __cputchar); - __mvcur(top, 0, 0, 0, 1); - tputs(HO, 0, __cputchar); - __mvcur(0, 0, oy, ox, 1); - return; } - - /* Preserve the bottom lines. */ - __mvcur(oy, ox, bot + n + 1, 0, 1); - if (SR != NULL && bot == win->maxy) - tputs(__tscroll(SR, -n, 0), 0, __cputchar); - else if (DL != NULL) - tputs(__tscroll(DL, -n, 0), 0, __cputchar); - else if (dl != NULL) + else if (DL != NULL) { + __mvcur(oy, ox, bot + n + 1, 0, 1); + if (dl != NULL && -n == 1) + goto b_dl1; + tputs(__tscroll(DL, -n, 0), -n, __cputchar); + __mvcur(bot + n + 1, 0, top, 0, 1); + } + else if (dl != NULL) { + __mvcur(oy, ox, bot + n + 1, 0, 1); + b_dl1: for (i = n; i < 0; i++) - tputs(dl, 0, __cputchar); - else if (sr != NULL && bot == win->maxy) + tputs(dl, 1, __cputchar); + __mvcur(bot + n + 1, 0, top, 0, 1); + } + else if (sr != NULL && bot == curscr->maxy - 1) { + __mvcur(oy, ox, 0, 0, 1); + b_sr1: for (i = n; i < 0; i++) - tputs(sr, 0, __cputchar); + tputs(sr, 1, __cputchar); + __mvcur(0, 0, top, 0, 1); + } else abort(); /* Scroll the block down. */ - __mvcur(bot + n + 1, 0, top, 0, 1); - if (AL != NULL) - tputs(__tscroll(AL, -n, 0), 0, __cputchar); - else if (al != NULL) + if (AL != NULL) { + if (al != NULL && -n == 1) + goto b_al1; + tputs(__tscroll(AL, -n, 0), -n, __cputchar); + } + else if (al != NULL) { + b_al1: for (i = n; i < 0; i++) - tputs(al, 0, __cputchar); + tputs(al, 1, __cputchar); + } else abort(); __mvcur(top, 0, oy, ox, 1); diff --git a/lib/libcurses/setterm.c b/lib/libcurses/setterm.c index 1d13490..ab84e9d 100644 --- a/lib/libcurses/setterm.c +++ b/lib/libcurses/setterm.c @@ -44,6 +44,9 @@ static char sccsid[] = "@(#)setterm.c 8.7 (Berkeley) 7/27/94"; #include "curses.h" +#undef ospeed +extern short ospeed; + static void zap __P((void)); static char *sflags[] = { @@ -151,13 +154,46 @@ setterm(type) CA = 1; PC = _PC ? _PC[0] : 0; + + switch(cfgetospeed(&__baset)) { + case B0: ospeed = 0; break; + case B50: ospeed = 1; break; + case B75: ospeed = 2; break; + case B110: ospeed = 3; break; + case B134: ospeed = 4; break; + case B150: ospeed = 5; break; + case B200: ospeed = 6; break; + case B300: ospeed = 7; break; + case B600: ospeed = 8; break; + case B1200: ospeed = 9; break; + case B1800: ospeed = 10; break; + case B2400: ospeed = 11; break; + case B4800: ospeed = 12; break; + case B9600: ospeed = 13; break; +#ifdef EXTA + case EXTA: ospeed = 14; break; +#endif +#ifdef EXTB + case EXTB: ospeed = 15; break; +#endif +#ifdef B57600 + case B57600: ospeed = 16; break; +#endif +#ifdef B115200 + case B115200: ospeed = 17; break; +#endif + } + aoftspace = tspace; ttytype = longname(genbuf, __ttytype); + __usecs = + (AL == NULL && al == NULL || DL == NULL && dl == NULL) && + !NS && (SC != NULL && RC != NULL || HO != NULL) && + CS != NULL && (SR != NULL || sr != NULL); + /* If no scrolling commands, no quick change. */ - __noqch = - (CS == NULL || HO == NULL || - SF == NULL && sf == NULL || SR == NULL && sr == NULL) && + __noqch = !__usecs && (AL == NULL && al == NULL || DL == NULL && dl == NULL); return (unknown ? ERR : OK); diff --git a/lib/libcurses/standout.c b/lib/libcurses/standout.c index 754b423..903400a 100644 --- a/lib/libcurses/standout.c +++ b/lib/libcurses/standout.c @@ -41,28 +41,28 @@ static char sccsid[] = "@(#)standout.c 8.2 (Berkeley) 5/4/94"; * wstandout * Enter standout mode. */ -char * +int wstandout(win) register WINDOW *win; { if (!SO && !UC) - return (0); + return (ERR); win->flags |= __WSTANDOUT; - return (SO ? SO : UC); + return (OK); } /* * wstandend -- * Exit standout mode. */ -char * +int wstandend(win) register WINDOW *win; { if (!SO && !UC) - return (0); + return (ERR); win->flags &= ~__WSTANDOUT; - return (SE ? SE : UC); + return (OK); } diff --git a/lib/libcurses/tstp.c b/lib/libcurses/tstp.c index 07debf4..f16a46c 100644 --- a/lib/libcurses/tstp.c +++ b/lib/libcurses/tstp.c @@ -54,7 +54,7 @@ __stop_signal_handler(signo) sigset_t oset, set; /* Get the current terminal state (which the user may have changed). */ - if (tcgetattr(STDIN_FILENO, &save)) + if (tcgetattr(__tty_fileno, &save)) return; /* @@ -87,10 +87,10 @@ __stop_signal_handler(signo) __set_stophandler(); /* save the new "default" terminal state */ - (void)tcgetattr(STDIN_FILENO, &__orig_termios); + (void)tcgetattr(__tty_fileno, &__orig_termios); /* Reset the terminal state to the mode just before we stopped. */ - (void)tcsetattr(STDIN_FILENO, __tcaction ? + (void)tcsetattr(__tty_fileno, __tcaction ? TCSASOFT | TCSADRAIN : TCSADRAIN, &save); /* Restart the screen. */ @@ -122,3 +122,7 @@ __restore_stophandler() { (void)signal(SIGTSTP, otstpfn); } + +/* For compatibility */ + +void tstp() { __stop_signal_handler(SIGTSTP); } diff --git a/lib/libcurses/tty.c b/lib/libcurses/tty.c index 346b850..6525539 100644 --- a/lib/libcurses/tty.c +++ b/lib/libcurses/tty.c @@ -37,6 +37,7 @@ static char sccsid[] = "@(#)tty.c 8.4 (Berkeley) 5/18/94"; #include #include +#include #include "curses.h" @@ -53,6 +54,7 @@ int __tcaction = 1; /* Ignore hardware settings. */ int __tcaction = 0; #endif +int __tty_fileno; struct termios __orig_termios, __baset; static struct termios cbreakt, rawt, *curt; static int useraw; @@ -64,6 +66,9 @@ static int useraw; #define OXTABS 0 #endif #endif +#ifndef _PATH_TTY +#define _PATH_TTY "/dev/tty" +#endif /* * gettmode -- @@ -74,8 +79,12 @@ gettmode() { useraw = 0; - if (tcgetattr(STDIN_FILENO, &__orig_termios)) - return (ERR); + if (tcgetattr(__tty_fileno = STDIN_FILENO, &__orig_termios)) { + if ((__tty_fileno = open(_PATH_TTY, O_RDONLY, 0)) < 0) + return (ERR); + else if (tcgetattr(__tty_fileno, &__orig_termios)) + return (ERR); + } __baset = __orig_termios; __baset.c_oflag &= ~OXTABS; @@ -115,7 +124,7 @@ gettmode() } curt = &__baset; - return (tcsetattr(STDIN_FILENO, __tcaction ? + return (tcsetattr(__tty_fileno, __tcaction ? TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK); } @@ -124,7 +133,7 @@ raw() { useraw = __pfast = __rawmode = 1; curt = &rawt; - return (tcsetattr(STDIN_FILENO, __tcaction ? + return (tcsetattr(__tty_fileno, __tcaction ? TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK); } @@ -133,7 +142,7 @@ noraw() { useraw = __pfast = __rawmode = 0; curt = &__baset; - return (tcsetattr(STDIN_FILENO, __tcaction ? + return (tcsetattr(__tty_fileno, __tcaction ? TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK); } @@ -143,7 +152,7 @@ cbreak() __rawmode = 1; curt = useraw ? &rawt : &cbreakt; - return (tcsetattr(STDIN_FILENO, __tcaction ? + return (tcsetattr(__tty_fileno, __tcaction ? TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK); } @@ -153,7 +162,7 @@ nocbreak() __rawmode = 0; curt = useraw ? &rawt : &__baset; - return (tcsetattr(STDIN_FILENO, __tcaction ? + return (tcsetattr(__tty_fileno, __tcaction ? TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK); } @@ -165,7 +174,7 @@ echo() __baset.c_lflag |= ECHO; __echoit = 1; - return (tcsetattr(STDIN_FILENO, __tcaction ? + return (tcsetattr(__tty_fileno, __tcaction ? TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK); } @@ -177,7 +186,7 @@ noecho() __baset.c_lflag &= ~ECHO; __echoit = 0; - return (tcsetattr(STDIN_FILENO, __tcaction ? + return (tcsetattr(__tty_fileno, __tcaction ? TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK); } @@ -192,7 +201,7 @@ nl() __baset.c_oflag |= ONLCR; __pfast = __rawmode; - return (tcsetattr(STDIN_FILENO, __tcaction ? + return (tcsetattr(__tty_fileno, __tcaction ? TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK); } @@ -207,7 +216,7 @@ nonl() __baset.c_oflag &= ~ONLCR; __pfast = 1; - return (tcsetattr(STDIN_FILENO, __tcaction ? + return (tcsetattr(__tty_fileno, __tcaction ? TCSASOFT | TCSADRAIN : TCSADRAIN, curt) ? ERR : OK); } @@ -219,6 +228,23 @@ __startwin() tputs(TI, 0, __cputchar); tputs(VS, 0, __cputchar); + if (curscr != NULL && __usecs) + __set_scroll_region(0, curscr->maxx - 1, 0, 0); +} + +void +__set_scroll_region(top, bot, ox, oy) +int top, bot, ox, oy; +{ + if (SC != NULL && RC != NULL) + tputs(SC, 0, __cputchar); + tputs(__tscroll(CS, top, bot), 1, __cputchar); + if (SC != NULL && RC != NULL) + tputs(RC, 0, __cputchar); + else { + tputs(HO, 1, __cputchar); + __mvcur(0, 0, oy, ox, 1); + } } int @@ -231,6 +257,8 @@ endwin() tputs(SE, 0, __cputchar); curscr->flags &= ~__WSTANDOUT; } + if (__usecs) + __set_scroll_region(0, curscr->maxx - 1, 0, 0); __mvcur(curscr->cury, curscr->cury, curscr->maxy - 1, 0, 0); } @@ -239,7 +267,7 @@ endwin() (void)fflush(stdout); (void)setvbuf(stdout, NULL, _IOLBF, 0); - return (tcsetattr(STDIN_FILENO, __tcaction ? + return (tcsetattr(__tty_fileno, __tcaction ? TCSASOFT | TCSADRAIN : TCSADRAIN, &__orig_termios) ? ERR : OK); } @@ -252,12 +280,12 @@ static struct termios savedtty; int savetty() { - return (tcgetattr(STDIN_FILENO, &savedtty) ? ERR : OK); + return (tcgetattr(__tty_fileno, &savedtty) ? ERR : OK); } int resetty() { - return (tcsetattr(STDIN_FILENO, __tcaction ? + return (tcsetattr(__tty_fileno, __tcaction ? TCSASOFT | TCSADRAIN : TCSADRAIN, &savedtty) ? ERR : OK); } -- cgit v1.1