diff options
author | peter <peter@FreeBSD.org> | 2013-08-11 20:03:12 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2013-08-11 20:03:12 +0000 |
commit | 5f2a1d653696ec5457bfd044f0ebcd873bfc3c80 (patch) | |
tree | 7c1ae67d07b93aea05bfea51c590c1112b65042b /contrib/nvi/cl | |
parent | 324febaf01918418f99998aa5537126ac98c9df0 (diff) | |
download | FreeBSD-src-5f2a1d653696ec5457bfd044f0ebcd873bfc3c80.zip FreeBSD-src-5f2a1d653696ec5457bfd044f0ebcd873bfc3c80.tar.gz |
Update nvi-1.79 to 2.1.1-4334a8297f
This is the gsoc-2011 project to clean up and backport multibyte support
from other nvi forks in a form we can use.
USE_WIDECHAR is on unless building for the rescue crunchgen. This should
allow editing in the native locale encoding.
USE_ICONV depends on make.conf having 'WITH_ICONV=YES' for now. This
adds the ability to do things like edit a KOI8-R file while having $LANG
set to (say) en_US.UTF-8. iconv is used to transcode the characters for
display.
Other points:
* It uses gencat and catopen/etc instead of homegrown msg catalog stuff.
* A lot of stuff has been trimmed out, eg: the perl and tcl bindings which
we could never use in base anyway.
* It uses ncursesw when in widechar mode. This could be interesting.
GSoC info: http://www.google-melange.com/gsoc/proposal/review/google/gsoc2011/zy/1
Repo at: https://github.com/lichray/nvi2
Obtained from: Zhihao Yuan <lichray@gmail.com>
Diffstat (limited to 'contrib/nvi/cl')
-rw-r--r-- | contrib/nvi/cl/README.signal | 2 | ||||
-rw-r--r-- | contrib/nvi/cl/cl.h | 51 | ||||
-rw-r--r-- | contrib/nvi/cl/cl_bsd.c | 346 | ||||
-rw-r--r-- | contrib/nvi/cl/cl_funcs.c | 408 | ||||
-rw-r--r-- | contrib/nvi/cl/cl_main.c | 96 | ||||
-rw-r--r-- | contrib/nvi/cl/cl_read.c | 83 | ||||
-rw-r--r-- | contrib/nvi/cl/cl_screen.c | 66 | ||||
-rw-r--r-- | contrib/nvi/cl/cl_term.c | 140 | ||||
-rw-r--r-- | contrib/nvi/cl/extern.h | 31 |
9 files changed, 520 insertions, 703 deletions
diff --git a/contrib/nvi/cl/README.signal b/contrib/nvi/cl/README.signal index 7faa456..18b3d14 100644 --- a/contrib/nvi/cl/README.signal +++ b/contrib/nvi/cl/README.signal @@ -1,4 +1,4 @@ -# @(#)README.signal 10.1 (Berkeley) 6/23/95 +# $Id: README.signal,v 10.1 1995/06/23 10:28:17 bostic Exp $ There are six (normally) asynchronous actions about which vi cares: SIGHUP, SIGINT, SIGQUIT, SIGTERM, SIGTSTP and SIGWINCH. diff --git a/contrib/nvi/cl/cl.h b/contrib/nvi/cl/cl.h index 2ef2b8d..c84ef88 100644 --- a/contrib/nvi/cl/cl.h +++ b/contrib/nvi/cl/cl.h @@ -6,11 +6,24 @@ * * See the LICENSE file for redistribution information. * - * @(#)cl.h 10.19 (Berkeley) 9/24/96 + * $Id: cl.h,v 10.34 2011/08/15 20:07:32 zy Exp $ */ +#ifdef USE_WIDECHAR +#define _XOPEN_SOURCE_EXTENDED +#endif +#ifdef HAVE_NCURSES_H +#include <ncurses.h> +#else +#include <curses.h> +#endif + typedef struct _cl_private { - CHAR_T ibuf[256]; /* Input keys. */ + char ibuf[256]; /* Input keys. */ + + size_t skip; /* Remaining keys. */ + + CONVWIN cw; /* Conversion buffer. */ int eof_count; /* EOF count. */ @@ -24,6 +37,10 @@ typedef struct _cl_private { char *rmso, *smso; /* Inverse video terminal strings. */ char *smcup, *rmcup; /* Terminal start/stop strings. */ + char *oname; /* Original screen window name. */ + + SCR *focus; /* Screen that has the "focus". */ + int killersig; /* Killer signal. */ #define INDX_HUP 0 #define INDX_INT 1 @@ -39,29 +56,29 @@ typedef struct _cl_private { TE_SENT=0, TI_SENT } ti_te; #define CL_IN_EX 0x0001 /* Currently running ex. */ -#define CL_RENAME 0x0002 /* X11 xterm icon/window renamed. */ -#define CL_RENAME_OK 0x0004 /* User wants the windows renamed. */ -#define CL_SCR_EX_INIT 0x0008 /* Ex screen initialized. */ -#define CL_SCR_VI_INIT 0x0010 /* Vi screen initialized. */ -#define CL_SIGHUP 0x0020 /* SIGHUP arrived. */ -#define CL_SIGINT 0x0040 /* SIGINT arrived. */ -#define CL_SIGTERM 0x0080 /* SIGTERM arrived. */ -#define CL_SIGWINCH 0x0100 /* SIGWINCH arrived. */ -#define CL_STDIN_TTY 0x0200 /* Talking to a terminal. */ +#define CL_LAYOUT 0x0002 /* Screen layout changed. */ +#define CL_RENAME 0x0004 /* X11 xterm icon/window renamed. */ +#define CL_RENAME_OK 0x0008 /* User wants the windows renamed. */ +#define CL_SCR_EX_INIT 0x0010 /* Ex screen initialized. */ +#define CL_SCR_VI_INIT 0x0020 /* Vi screen initialized. */ +#define CL_SIGHUP 0x0040 /* SIGHUP arrived. */ +#define CL_SIGINT 0x0080 /* SIGINT arrived. */ +#define CL_SIGTERM 0x0100 /* SIGTERM arrived. */ +#define CL_SIGWINCH 0x0200 /* SIGWINCH arrived. */ +#define CL_STDIN_TTY 0x0400 /* Talking to a terminal. */ u_int32_t flags; } CL_PRIVATE; #define CLP(sp) ((CL_PRIVATE *)((sp)->gp->cl_private)) #define GCLP(gp) ((CL_PRIVATE *)gp->cl_private) +#define CLSP(sp) ((WINDOW *)((sp)->cl_private)) /* Return possibilities from the keyboard read routine. */ typedef enum { INP_OK=0, INP_EOF, INP_ERR, INP_INTR, INP_TIMEOUT } input_t; -/* The screen line relative to a specific window. */ -#define RLNO(sp, lno) (sp)->woff + (lno) - -/* X11 xterm escape sequence to rename the icon/window. */ -#define XTERM_RENAME "\033]0;%s\007" +/* The screen position relative to a specific window. */ +#define RCNO(sp, cno) (cno) +#define RLNO(sp, lno) (lno) /* * XXX @@ -75,4 +92,4 @@ typedef enum { INP_OK=0, INP_EOF, INP_ERR, INP_INTR, INP_TIMEOUT } input_t; #define FALSE 0 #endif -#include "cl_extern.h" +#include "extern.h" diff --git a/contrib/nvi/cl/cl_bsd.c b/contrib/nvi/cl/cl_bsd.c deleted file mode 100644 index 22124e5..0000000 --- a/contrib/nvi/cl/cl_bsd.c +++ /dev/null @@ -1,346 +0,0 @@ -/*- - * Copyright (c) 1995, 1996 - * Keith Bostic. All rights reserved. - * - * See the LICENSE file for redistribution information. - */ - -#include "config.h" - -#ifndef lint -static const char sccsid[] = "@(#)cl_bsd.c 8.29 (Berkeley) 7/1/96"; -#endif /* not lint */ - -#include <sys/types.h> -#include <sys/queue.h> -#include <sys/time.h> - -#include <bitstring.h> -#include <ctype.h> -#include <curses.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <termios.h> -#include <unistd.h> - -#include "../common/common.h" -#include "../vi/vi.h" -#include "cl.h" - -static char *ke; /* Keypad on. */ -static char *ks; /* Keypad off. */ -static char *vb; /* Visible bell string. */ - -/* - * HP's support the entire System V curses package except for the tigetstr - * and tigetnum functions. Ultrix supports the BSD curses package except - * for the idlok function. Cthulu only knows why. Break things up into a - * minimal set of functions. - */ - -#ifndef HAVE_CURSES_ADDNSTR -/* - * addnstr -- - * - * PUBLIC: #ifndef HAVE_CURSES_ADDNSTR - * PUBLIC: int addnstr __P((char *, int)); - * PUBLIC: #endif - */ -int -addnstr(s, n) - char *s; - int n; -{ - int ch; - - while (n-- && (ch = *s++)) - addch(ch); - return (OK); -} -#endif - -#ifndef HAVE_CURSES_BEEP -/* - * beep -- - * - * PUBLIC: #ifndef HAVE_CURSES_BEEP - * PUBLIC: void beep __P((void)); - * PUBLIC: #endif - */ -void -beep() -{ - (void)write(1, "\007", 1); /* '\a' */ -} -#endif /* !HAVE_CURSES_BEEP */ - -#ifndef HAVE_CURSES_FLASH -/* - * flash -- - * Flash the screen. - * - * PUBLIC: #ifndef HAVE_CURSES_FLASH - * PUBLIC: void flash __P((void)); - * PUBLIC: #endif - */ -void -flash() -{ - if (vb != NULL) { - (void)tputs(vb, 1, cl_putchar); - (void)fflush(stdout); - } else - beep(); -} -#endif /* !HAVE_CURSES_FLASH */ - -#ifndef HAVE_CURSES_IDLOK -/* - * idlok -- - * Turn on/off hardware line insert/delete. - * - * PUBLIC: #ifndef HAVE_CURSES_IDLOK - * PUBLIC: void idlok __P((WINDOW *, int)); - * PUBLIC: #endif - */ -void -idlok(win, bf) - WINDOW *win; - int bf; -{ - return; -} -#endif /* !HAVE_CURSES_IDLOK */ - -#ifndef HAVE_CURSES_KEYPAD -/* - * keypad -- - * Put the keypad/cursor arrows into or out of application mode. - * - * PUBLIC: #ifndef HAVE_CURSES_KEYPAD - * PUBLIC: int keypad __P((void *, int)); - * PUBLIC: #endif - */ -int -keypad(a, on) - void *a; - int on; -{ - char *p; - - if ((p = tigetstr(on ? "smkx" : "rmkx")) != (char *)-1) { - (void)tputs(p, 0, cl_putchar); - (void)fflush(stdout); - } - return (0); -} -#endif /* !HAVE_CURSES_KEYPAD */ - -#ifndef HAVE_CURSES_NEWTERM -/* - * newterm -- - * Create a new curses screen. - * - * PUBLIC: #ifndef HAVE_CURSES_NEWTERM - * PUBLIC: void *newterm __P((const char *, FILE *, FILE *)); - * PUBLIC: #endif - */ -void * -newterm(a, b, c) - const char *a; - FILE *b, *c; -{ - return (initscr()); -} -#endif /* !HAVE_CURSES_NEWTERM */ - -#ifndef HAVE_CURSES_SETUPTERM -/* - * setupterm -- - * Set up terminal. - * - * PUBLIC: #ifndef HAVE_CURSES_SETUPTERM - * PUBLIC: void setupterm __P((char *, int, int *)); - * PUBLIC: #endif - */ -void -setupterm(ttype, fno, errp) - char *ttype; - int fno, *errp; -{ - static char buf[2048]; - char *p; - - if ((*errp = tgetent(buf, ttype)) > 0) { - if (ke != NULL) - free(ke); - ke = ((p = tigetstr("rmkx")) == (char *)-1) ? - NULL : strdup(p); - if (ks != NULL) - free(ks); - ks = ((p = tigetstr("smkx")) == (char *)-1) ? - NULL : strdup(p); - if (vb != NULL) - free(vb); - vb = ((p = tigetstr("flash")) == (char *)-1) ? - NULL : strdup(p); - } -} -#endif /* !HAVE_CURSES_SETUPTERM */ - -#ifndef HAVE_CURSES_TIGETSTR -/* Terminfo-to-termcap translation table. */ -typedef struct _tl { - char *terminfo; /* Terminfo name. */ - char *termcap; /* Termcap name. */ -} TL; -static const TL list[] = { - "cols", "co", /* Terminal columns. */ - "cup", "cm", /* Cursor up. */ - "cuu1", "up", /* Cursor up. */ - "el", "ce", /* Clear to end-of-line. */ - "flash", "vb", /* Visible bell. */ - "kcub1", "kl", /* Cursor left. */ - "kcud1", "kd", /* Cursor down. */ - "kcuf1", "kr", /* Cursor right. */ - "kcuu1", "ku", /* Cursor up. */ - "kdch1", "kD", /* Delete character. */ - "kdl1", "kL", /* Delete line. */ - "ked", "kS", /* Delete to end of screen. */ - "kel", "kE", /* Delete to eol. */ - "kend", "@7", /* Go to eol. */ - "khome", "kh", /* Go to sol. */ - "kich1", "kI", /* Insert at cursor. */ - "kil1", "kA", /* Insert line. */ - "kind", "kF", /* Scroll down. */ - "kll", "kH", /* Go to eol. */ - "knp", "kN", /* Page down. */ - "kpp", "kP", /* Page up. */ - "kri", "kR", /* Scroll up. */ - "lines", "li", /* Terminal lines. */ - "rmcup", "te", /* Terminal end string. */ - "rmkx", "ke", /* Exit "keypad-transmit" mode. */ - "rmso", "se", /* Standout end. */ - "smcup", "ti", /* Terminal initialization string. */ - "smkx", "ks", /* Enter "keypad-transmit" mode. */ - "smso", "so", /* Standout begin. */ -}; - -#ifdef _AIX -/* - * AIX's implementation for function keys greater than 10 is different and - * only goes as far as 36. - */ -static const char codes[] = { -/* 0-10 */ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ';', -/* 11-20 */ '<', '>', '!', '@', '#', '$', '%', '^', '&', '*', -/* 21-30 */ '(', ')', '-', '_', '+', ',', ':', '?', '[', ']', -/* 31-36 */ '{', '}', '|', '~', '/', '=' -}; - -#else - -/* - * !!! - * Historically, the 4BSD termcap code didn't support functions keys greater - * than 9. This was silently enforced -- asking for key k12 would return the - * value for k1. We try and get around this by using the tables specified in - * the terminfo(TI_ENV) man page from the 3rd Edition SVID. This assumes the - * implementors of any System V compatibility code or an extended termcap used - * those codes. - */ -static const char codes[] = { -/* 0-10 */ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ';', -/* 11-19 */ '1', '2', '3', '4', '5', '6', '7', '8', '9', -/* 20-63 */ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', -}; -#endif /* _AIX */ - -/* - * lcmp -- - * list comparison routine for bsearch. - */ -static int -lcmp(a, b) - const void *a, *b; -{ - return (strcmp(a, ((TL *)b)->terminfo)); -} - -/* - * tigetstr -- - * - * Vendors put the prototype for tigetstr into random include files, including - * <term.h>, which we can't include because it makes other systems unhappy. - * Try and work around the problem, since we only care about the return value. - * - * PUBLIC: #ifdef HAVE_CURSES_TIGETSTR - * PUBLIC: char *tigetstr(); - * PUBLIC: #else - * PUBLIC: char *tigetstr __P((char *)); - * PUBLIC: #endif - */ -char * -tigetstr(name) - char *name; -{ - static char sbuf[256]; - TL *tlp; - int n; - char *p, keyname[3]; - - if ((tlp = bsearch(name, - list, sizeof(list) / sizeof(TL), sizeof(TL), lcmp)) == NULL) { -#ifdef _AIX - if (name[0] == 'k' && - name[1] == 'f' && (n = atoi(name + 2)) <= 36) { - keyname[0] = 'k'; - keyname[1] = codes[n]; - keyname[2] = '\0'; -#else - if (name[0] == 'k' && - name[1] == 'f' && (n = atoi(name + 2)) <= 63) { - keyname[0] = n <= 10 ? 'k' : 'F'; - keyname[1] = codes[n]; - keyname[2] = '\0'; -#endif - name = keyname; - } - } else - name = tlp->termcap; - - p = sbuf; -#ifdef _AIX - return ((p = tgetstr(name, &p)) == NULL ? (char *)-1 : strcpy(sbuf, p)); -#else - return (tgetstr(name, &p) == NULL ? (char *)-1 : sbuf); -#endif -} - -/* - * tigetnum -- - * - * PUBLIC: #ifndef HAVE_CURSES_TIGETSTR - * PUBLIC: int tigetnum __P((char *)); - * PUBLIC: #endif - */ -int -tigetnum(name) - char *name; -{ - TL *tlp; - int val; - - if ((tlp = bsearch(name, - list, sizeof(list) / sizeof(TL), sizeof(TL), lcmp)) != NULL) { - name = tlp->termcap; - } - - return ((val = tgetnum(name)) == -1 ? -2 : val); -} -#endif /* !HAVE_CURSES_TIGETSTR */ diff --git a/contrib/nvi/cl/cl_funcs.c b/contrib/nvi/cl/cl_funcs.c index 40315ee..8b14e8d 100644 --- a/contrib/nvi/cl/cl_funcs.c +++ b/contrib/nvi/cl/cl_funcs.c @@ -10,7 +10,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)cl_funcs.c 10.50 (Berkeley) 9/24/96"; +static const char sccsid[] = "$Id: cl_funcs.c,v 10.74 2012/10/11 10:30:16 zy Exp $"; #endif /* not lint */ #include <sys/types.h> @@ -19,11 +19,13 @@ static const char sccsid[] = "@(#)cl_funcs.c 10.50 (Berkeley) 9/24/96"; #include <bitstring.h> #include <ctype.h> -#include <curses.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#ifdef HAVE_TERM_H +#include <term.h> +#endif #include <termios.h> #include <unistd.h> @@ -31,59 +33,83 @@ static const char sccsid[] = "@(#)cl_funcs.c 10.50 (Berkeley) 9/24/96"; #include "../vi/vi.h" #include "cl.h" -/* - * cl_addstr -- - * Add len bytes from the string at the cursor, advancing the cursor. - * - * PUBLIC: int cl_addstr __P((SCR *, const char *, size_t)); - */ -int -cl_addstr(sp, str, len) - SCR *sp; - const char *str; - size_t len; +static void cl_rdiv __P((SCR *)); + +static int +addstr4(SCR *sp, void *str, size_t len, int wide) { CL_PRIVATE *clp; - size_t oldy, oldx; + WINDOW *win; + size_t y, x; int iv; clp = CLP(sp); + win = CLSP(sp) ? CLSP(sp) : stdscr; /* * If ex isn't in control, it's the last line of the screen and * it's a split screen, use inverse video. */ iv = 0; - getyx(stdscr, oldy, oldx); + getyx(win, y, x); if (!F_ISSET(sp, SC_SCR_EXWROTE) && - oldy == RLNO(sp, LASTLINE(sp)) && IS_SPLIT(sp)) { + y == RLNO(sp, LASTLINE(sp)) && IS_SPLIT(sp)) { iv = 1; - (void)standout(); + (void)wstandout(win); } - if (addnstr(str, len) == ERR) +#ifdef USE_WIDECHAR + if (wide) { + if (waddnwstr(win, str, len) == ERR) return (1); + } else +#endif + if (waddnstr(win, str, len) == ERR) + return (1); if (iv) - (void)standend(); + (void)wstandend(win); return (0); } /* + * cl_waddstr -- + * Add len bytes from the string at the cursor, advancing the cursor. + * + * PUBLIC: int cl_waddstr __P((SCR *, const CHAR_T *, size_t)); + */ +int +cl_waddstr(SCR *sp, const CHAR_T *str, size_t len) +{ + return addstr4(sp, (void *)str, len, 1); +} + +/* + * cl_addstr -- + * Add len bytes from the string at the cursor, advancing the cursor. + * + * PUBLIC: int cl_addstr __P((SCR *, const char *, size_t)); + */ +int +cl_addstr(SCR *sp, const char *str, size_t len) +{ + return addstr4(sp, (void *)str, len, 0); +} + +/* * cl_attr -- * Toggle a screen attribute on/off. * * PUBLIC: int cl_attr __P((SCR *, scr_attr_t, int)); */ int -cl_attr(sp, attribute, on) - SCR *sp; - scr_attr_t attribute; - int on; +cl_attr(SCR *sp, scr_attr_t attribute, int on) { CL_PRIVATE *clp; + WINDOW *win; clp = CLP(sp); + win = CLSP(sp) ? CLSP(sp) : stdscr; switch (attribute) { case SA_ALTERNATE: @@ -146,9 +172,9 @@ cl_attr(sp, attribute, on) (void)fflush(stdout); } else { if (on) - (void)standout(); + (void)wstandout(win); else - (void)standend(); + (void)wstandend(win); } break; default: @@ -164,9 +190,7 @@ cl_attr(sp, attribute, on) * PUBLIC: int cl_baud __P((SCR *, u_long *)); */ int -cl_baud(sp, ratep) - SCR *sp; - u_long *ratep; +cl_baud(SCR *sp, u_long *ratep) { CL_PRIVATE *clp; @@ -207,10 +231,9 @@ cl_baud(sp, ratep) * PUBLIC: int cl_bell __P((SCR *)); */ int -cl_bell(sp) - SCR *sp; +cl_bell(SCR *sp) { - if (F_ISSET(sp, SC_EX | SC_SCR_EXWROTE)) + if (F_ISSET(sp, SC_EX | SC_SCR_EXWROTE | SC_SCR_EX)) (void)write(STDOUT_FILENO, "\07", 1); /* \a */ else { /* @@ -232,10 +255,26 @@ cl_bell(sp) * PUBLIC: int cl_clrtoeol __P((SCR *)); */ int -cl_clrtoeol(sp) - SCR *sp; +cl_clrtoeol(SCR *sp) { - return (clrtoeol() == ERR); + WINDOW *win; +#if 0 + size_t spcnt, y, x; +#endif + + win = CLSP(sp) ? CLSP(sp) : stdscr; + +#if 0 + if (IS_VSPLIT(sp)) { + /* The cursor must be returned to its original position. */ + getyx(win, y, x); + for (spcnt = (sp->coff + sp->cols) - x; spcnt > 0; --spcnt) + (void)waddch(win, ' '); + (void)wmove(win, y, x); + return (0); + } else +#endif + return (wclrtoeol(win) == ERR); } /* @@ -245,10 +284,10 @@ cl_clrtoeol(sp) * PUBLIC: int cl_cursor __P((SCR *, size_t *, size_t *)); */ int -cl_cursor(sp, yp, xp) - SCR *sp; - size_t *yp, *xp; +cl_cursor(SCR *sp, size_t *yp, size_t *xp) { + WINDOW *win; + win = CLSP(sp) ? CLSP(sp) : stdscr; /* * The curses screen support splits a single underlying curses screen * into multiple screens to support split screen semantics. For this @@ -256,8 +295,11 @@ cl_cursor(sp, yp, xp) * current screen, and not absolute. Screens that implement the split * using physically distinct screens won't need this hack. */ - getyx(stdscr, *yp, *xp); - *yp -= sp->woff; + getyx(win, *yp, *xp); + /* + *yp -= sp->roff; + *xp -= sp->coff; + */ return (0); } @@ -268,14 +310,14 @@ cl_cursor(sp, yp, xp) * PUBLIC: int cl_deleteln __P((SCR *)); */ int -cl_deleteln(sp) - SCR *sp; +cl_deleteln(SCR *sp) { - CHAR_T ch; CL_PRIVATE *clp; - size_t col, lno, spcnt, oldy, oldx; + WINDOW *win; + size_t y, x; clp = CLP(sp); + win = CLSP(sp) ? CLSP(sp) : stdscr; /* * This clause is required because the curses screen uses reverse @@ -284,45 +326,58 @@ cl_deleteln(sp) * * If the bottom line was in reverse video, rewrite it in normal * video before it's scrolled. - * - * Check for the existence of a chgat function; XSI requires it, but - * historic implementations of System V curses don't. If it's not - * a #define, we'll fall back to doing it by hand, which is slow but - * acceptable. - * - * By hand means walking through the line, retrieving and rewriting - * each character. Curses has no EOL marker, so track strings of - * spaces, and copy the trailing spaces only if there's a non-space - * character following. */ if (!F_ISSET(sp, SC_SCR_EXWROTE) && IS_SPLIT(sp)) { - getyx(stdscr, oldy, oldx); -#ifdef mvchgat - mvchgat(RLNO(sp, LASTLINE(sp)), 0, -1, A_NORMAL, 0, NULL); -#else - for (lno = RLNO(sp, LASTLINE(sp)), col = spcnt = 0;;) { - (void)move(lno, col); - ch = winch(stdscr); - if (isblank(ch)) - ++spcnt; - else { - (void)move(lno, col - spcnt); - for (; spcnt > 0; --spcnt) - (void)addch(' '); - (void)addch(ch); - } - if (++col >= sp->cols) - break; - } -#endif - (void)move(oldy, oldx); + getyx(win, y, x); + mvwchgat(win, RLNO(sp, LASTLINE(sp)), 0, -1, A_NORMAL, 0, NULL); + (void)wmove(win, y, x); } /* * The bottom line is expected to be blank after this operation, * and other screens must support that semantic. */ - return (deleteln() == ERR); + return (wdeleteln(win) == ERR); +} + +/* + * cl_discard -- + * Discard a screen. + * + * PUBLIC: int cl_discard __P((SCR *, SCR **)); + */ +int +cl_discard(SCR *discardp, SCR **acquirep) +{ + CL_PRIVATE *clp; + SCR* tsp; + + if (discardp) { + clp = CLP(discardp); + F_SET(clp, CL_LAYOUT); + + if (CLSP(discardp)) { + delwin(CLSP(discardp)); + discardp->cl_private = NULL; + } + } + + /* no screens got a piece; we're done */ + if (!acquirep) + return 0; + + for (; (tsp = *acquirep) != NULL; ++acquirep) { + clp = CLP(tsp); + F_SET(clp, CL_LAYOUT); + + if (CLSP(tsp)) + delwin(CLSP(tsp)); + tsp->cl_private = subwin(stdscr, tsp->rows, tsp->cols, + tsp->roff, tsp->coff); + } + + /* discardp is going away, acquirep is taking up its space. */ + return (0); } /* @@ -333,9 +388,7 @@ cl_deleteln(sp) * PUBLIC: int cl_ex_adjust __P((SCR *, exadj_t)); */ int -cl_ex_adjust(sp, action) - SCR *sp; - exadj_t action; +cl_ex_adjust(SCR *sp, exadj_t action) { CL_PRIVATE *clp; int cnt; @@ -390,14 +443,15 @@ cl_ex_adjust(sp, action) * PUBLIC: int cl_insertln __P((SCR *)); */ int -cl_insertln(sp) - SCR *sp; +cl_insertln(SCR *sp) { + WINDOW *win; + win = CLSP(sp) ? CLSP(sp) : stdscr; /* * The current line is expected to be blank after this operation, * and the screen must support that semantic. */ - return (insertln() == ERR); + return (winsertln(win) == ERR); } /* @@ -407,11 +461,7 @@ cl_insertln(sp) * PUBLIC: int cl_keyval __P((SCR *, scr_keyval_t, CHAR_T *, int *)); */ int -cl_keyval(sp, val, chp, dnep) - SCR *sp; - scr_keyval_t val; - CHAR_T *chp; - int *dnep; +cl_keyval(SCR *sp, scr_keyval_t val, CHAR_T *chp, int *dnep) { CL_PRIVATE *clp; @@ -449,14 +499,14 @@ cl_keyval(sp, val, chp, dnep) * PUBLIC: int cl_move __P((SCR *, size_t, size_t)); */ int -cl_move(sp, lno, cno) - SCR *sp; - size_t lno, cno; +cl_move(SCR *sp, size_t lno, size_t cno) { + WINDOW *win; + win = CLSP(sp) ? CLSP(sp) : stdscr; /* See the comment in cl_cursor. */ - if (move(RLNO(sp, lno), cno) == ERR) { - msgq(sp, M_ERR, - "Error: move: l(%u) c(%u) o(%u)", lno, cno, sp->woff); + if (wmove(win, RLNO(sp, lno), RCNO(sp, cno)) == ERR) { + msgq(sp, M_ERR, "Error: move: l(%zu + %zu) c(%zu + %zu)", + lno, sp->roff, cno, sp->coff); return (1); } return (0); @@ -469,13 +519,17 @@ cl_move(sp, lno, cno) * PUBLIC: int cl_refresh __P((SCR *, int)); */ int -cl_refresh(sp, repaint) - SCR *sp; - int repaint; +cl_refresh(SCR *sp, int repaint) { + GS *gp; CL_PRIVATE *clp; + WINDOW *win; + SCR *psp, *tsp; + size_t y, x; + gp = sp->gp; clp = CLP(sp); + win = CLSP(sp) ? CLSP(sp) : stdscr; /* * If we received a killer signal, we're done, there's no point @@ -488,13 +542,57 @@ cl_refresh(sp, repaint) * If repaint is set, the editor is telling us that we don't know * what's on the screen, so we have to repaint from scratch. * + * If repaint set or the screen layout changed, we need to redraw + * any lines separating vertically split screens. If the horizontal + * offsets are the same, then the split was vertical, and need to + * draw a dividing line. + */ + if (repaint || F_ISSET(clp, CL_LAYOUT)) { + getyx(stdscr, y, x); + for (psp = sp; psp != NULL; psp = TAILQ_NEXT(psp, q)) + for (tsp = TAILQ_NEXT(psp, q); tsp != NULL; + tsp = TAILQ_NEXT(tsp, q)) + if (psp->roff == tsp->roff) { + if (psp->coff + psp->cols + 1 == tsp->coff) + cl_rdiv(psp); + else + if (tsp->coff + tsp->cols + 1 == psp->coff) + cl_rdiv(tsp); + } + (void)wmove(stdscr, y, x); + F_CLR(clp, CL_LAYOUT); + } + + /* * In the curses library, doing wrefresh(curscr) is okay, but the * screen flashes when we then apply the refresh() to bring it up * to date. So, use clearok(). */ if (repaint) clearok(curscr, 1); - return (refresh() == ERR); + /* + * Only do an actual refresh, when this is the focus window, + * i.e. the one holding the cursor. This assumes that refresh + * is called for that window after refreshing the others. + * This prevents the cursor being drawn in the other windows. + */ + return (wnoutrefresh(stdscr) == ERR || + wnoutrefresh(win) == ERR || + (sp == clp->focus && doupdate() == ERR)); +} + +/* + * cl_rdiv -- + * Draw a dividing line between two vertically split screens. + */ +static void +cl_rdiv(SCR *sp) +{ +#ifdef __NetBSD__ + mvvline(sp->roff, sp->cols + sp->coff, '|', sp->rows); +#else + mvvline(sp->roff, sp->cols + sp->coff, ACS_VLINE, sp->rows); +#endif } /* @@ -504,59 +602,116 @@ cl_refresh(sp, repaint) * PUBLIC: int cl_rename __P((SCR *, char *, int)); */ int -cl_rename(sp, name, on) - SCR *sp; - char *name; - int on; +cl_rename(SCR *sp, char *name, int on) { GS *gp; CL_PRIVATE *clp; - char *ttype; + FILE *pfp; + char buf[256], *s, *e; + char * wid; + char cmd[64]; gp = sp->gp; clp = CLP(sp); - ttype = OG_STR(gp, GO_TERM); - /* * XXX * We can only rename windows for xterm. */ if (on) { - if (F_ISSET(clp, CL_RENAME_OK) && - !strncmp(ttype, "xterm", sizeof("xterm") - 1)) { - F_SET(clp, CL_RENAME); - (void)printf(XTERM_RENAME, name); - (void)fflush(stdout); + clp->focus = sp; + if (!F_ISSET(clp, CL_RENAME_OK) || + strncmp(OG_STR(gp, GO_TERM), "xterm", 5)) + return (0); + + if (clp->oname == NULL && (wid = getenv("WINDOWID"))) { + snprintf(cmd, sizeof(cmd), "xprop -id %s WM_NAME", wid); + if ((pfp = popen(cmd, "r")) == NULL) + goto rename; + if (fgets(buf, sizeof(buf), pfp) == NULL) { + pclose(pfp); + goto rename; + } + pclose(pfp); + if ((s = strchr(buf, '"')) != NULL && + (e = strrchr(buf, '"')) != NULL) + clp->oname = strndup(s + 1, e - s - 1); } + +rename: cl_setname(gp, name); + + F_SET(clp, CL_RENAME); } else if (F_ISSET(clp, CL_RENAME)) { + cl_setname(gp, clp->oname); + F_CLR(clp, CL_RENAME); - (void)printf(XTERM_RENAME, ttype); - (void)fflush(stdout); } return (0); } /* + * cl_setname -- + * Set a X11 icon/window name. + * + * PUBLIC: void cl_setname __P((GS *, char *)); + */ +void +cl_setname(GS *gp, char *name) +{ +/* X11 xterm escape sequence to rename the icon/window. */ +#define XTERM_RENAME "\033]0;%s\007" + + (void)printf(XTERM_RENAME, name == NULL ? OG_STR(gp, GO_TERM) : name); + (void)fflush(stdout); +#undef XTERM_RENAME +} + +/* + * cl_split -- + * Split a screen. + * + * PUBLIC: int cl_split __P((SCR *, SCR *)); + */ +int +cl_split(SCR *origp, SCR *newp) +{ + CL_PRIVATE *clp; + + clp = CLP(origp); + F_SET(clp, CL_LAYOUT); + + if (CLSP(origp)) + delwin(CLSP(origp)); + + origp->cl_private = subwin(stdscr, origp->rows, origp->cols, + origp->roff, origp->coff); + newp->cl_private = subwin(stdscr, newp->rows, newp->cols, + newp->roff, newp->coff); + + /* origp is the original screen, giving up space to newp. */ + return (0); +} + +/* * cl_suspend -- * Suspend a screen. * * PUBLIC: int cl_suspend __P((SCR *, int *)); */ int -cl_suspend(sp, allowedp) - SCR *sp; - int *allowedp; +cl_suspend(SCR *sp, int *allowedp) { struct termios t; CL_PRIVATE *clp; + WINDOW *win; GS *gp; - size_t oldy, oldx; + size_t y, x; int changed; gp = sp->gp; clp = CLP(sp); + win = CLSP(sp) ? CLSP(sp) : stdscr; *allowedp = 1; /* @@ -596,9 +751,9 @@ cl_suspend(sp, allowedp) * Not sure this is necessary in System V implementations, but it * shouldn't hurt. */ - getyx(stdscr, oldy, oldx); - (void)move(LINES - 1, 0); - (void)refresh(); + getyx(win, y, x); + (void)wmove(win, LINES - 1, 0); + (void)wrefresh(win); /* * Temporarily end the screen. System V introduced a semantic where @@ -607,10 +762,8 @@ cl_suspend(sp, allowedp) * restarting after endwin(), so we have to do what clean up we can * without calling it. */ -#ifdef HAVE_BSD_CURSES /* Save the terminal settings. */ (void)tcgetattr(STDIN_FILENO, &t); -#endif /* Restore the cursor keys to normal mode. */ (void)keypad(stdscr, FALSE); @@ -618,11 +771,8 @@ cl_suspend(sp, allowedp) /* Restore the window name. */ (void)cl_rename(sp, NULL, 0); -#ifdef HAVE_BSD_CURSES - (void)cl_attr(sp, SA_ALTERNATE, 0); -#else (void)endwin(); -#endif + /* * XXX * Restore the original terminal settings. This is bad -- the @@ -647,14 +797,11 @@ cl_suspend(sp, allowedp) return (0); } -#ifdef HAVE_BSD_CURSES /* Restore terminal settings. */ + wrefresh(win); /* Needed on SunOs/Solaris ? */ if (F_ISSET(clp, CL_STDIN_TTY)) (void)tcsetattr(STDIN_FILENO, TCSASOFT | TCSADRAIN, &t); - (void)cl_attr(sp, SA_ALTERNATE, 1); -#endif - /* Set the window name. */ (void)cl_rename(sp, sp->frp->name, 1); @@ -662,7 +809,7 @@ cl_suspend(sp, allowedp) (void)keypad(stdscr, TRUE); /* Refresh and repaint the screen. */ - (void)move(oldy, oldx); + (void)wmove(win, y, x); (void)cl_refresh(sp, 1); /* If the screen changed size, set the SIGWINCH bit. */ @@ -681,7 +828,7 @@ cl_suspend(sp, allowedp) * PUBLIC: void cl_usage __P((void)); */ void -cl_usage() +cl_usage(void) { #define USAGE "\ usage: ex [-eFRrSsv] [-c command] [-t tag] [-w size] [file ...]\n\ @@ -695,8 +842,9 @@ usage: vi [-eFlRrSv] [-c command] [-t tag] [-w size] [file ...]\n" * gdbrefresh -- * Stub routine so can flush out curses screen changes using gdb. */ -int -gdbrefresh() +static int + __attribute__((unused)) +gdbrefresh(void) { refresh(); return (0); /* XXX Convince gdb to run it. */ diff --git a/contrib/nvi/cl/cl_main.c b/contrib/nvi/cl/cl_main.c index 2889f70..98f1313 100644 --- a/contrib/nvi/cl/cl_main.c +++ b/contrib/nvi/cl/cl_main.c @@ -10,27 +10,26 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)cl_main.c 10.36 (Berkeley) 10/14/96"; +static const char sccsid[] = "$Id: cl_main.c,v 10.55 2011/08/15 19:52:28 zy Exp $"; #endif /* not lint */ #include <sys/types.h> #include <sys/queue.h> #include <bitstring.h> -#include <curses.h> #include <errno.h> #include <fcntl.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#ifdef HAVE_TERM_H +#include <term.h> +#endif #include <termios.h> #include <unistd.h> #include "../common/common.h" -#ifdef RUNNING_IP -#include "../ip/ip.h" -#endif #include "cl.h" #include "pathnames.h" @@ -50,16 +49,14 @@ static void term_init __P((char *, char *)); * This is the main loop for the standalone curses editor. */ int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char **argv) { static int reenter; CL_PRIVATE *clp; GS *gp; size_t rows, cols; int rval; - char *ip_arg, **p_av, **t_av, *ttype; + char **p_av, **t_av, *ttype; /* If loaded at 0 and jumping through a NULL pointer, stop. */ if (reenter++) @@ -73,8 +70,6 @@ main(argc, argv) * no way to portably call getopt twice, so arguments parsed here must * be removed from the argument list. */ -#ifdef RUNNING_IP - ip_arg = NULL; for (p_av = t_av = argv;;) { if (*t_av == NULL) { *p_av = NULL; @@ -84,33 +79,9 @@ main(argc, argv) while ((*p_av++ = *t_av++) != NULL); break; } - if (!memcmp(*t_av, "-I", sizeof("-I") - 1)) { - if (t_av[0][2] != '\0') { - ip_arg = t_av[0] + 2; - ++t_av; - --argc; - continue; - } - if (t_av[1] != NULL) { - ip_arg = t_av[1]; - t_av += 2; - argc -= 2; - continue; - } - } *p_av++ = *t_av++; } - /* - * If we're being called as an editor library, we're done here, we - * get loaded with the curses screen, we don't share much code. - */ - if (ip_arg != NULL) - exit (ip_main(argc, argv, gp, ip_arg)); -#else - ip_arg = argv[0]; -#endif - /* Create and initialize the CL_PRIVATE structure. */ clp = cl_init(gp); @@ -164,10 +135,8 @@ main(argc, argv) * XXX * Reset the X11 xterm icon/window name. */ - if (F_ISSET(clp, CL_RENAME)) { - (void)printf(XTERM_RENAME, ttype); - (void)fflush(stdout); - } + if (F_ISSET(clp, CL_RENAME)) + cl_setname(gp, clp->oname); /* If a killer signal arrived, pretend we just got it. */ if (clp->killersig) { @@ -178,7 +147,10 @@ main(argc, argv) /* Free the global and CL private areas. */ #if defined(DEBUG) || defined(PURIFY) || defined(LIBRARY) + if (clp->oname != NULL) + free(clp->oname); free(clp); + free(OG_STR(gp, GO_TERM)); free(gp); #endif @@ -190,10 +162,8 @@ main(argc, argv) * Create and partially initialize the GS structure. */ static GS * -gs_init(name) - char *name; +gs_init(char *name) { - CL_PRIVATE *clp; GS *gp; char *p; @@ -206,7 +176,6 @@ gs_init(name) if (gp == NULL) perr(name, NULL); - gp->progname = name; return (gp); } @@ -216,8 +185,7 @@ gs_init(name) * Create and partially initialize the CL structure. */ static CL_PRIVATE * -cl_init(gp) - GS *gp; +cl_init(GS *gp) { CL_PRIVATE *clp; int fd; @@ -265,8 +233,7 @@ tcfail: perr(gp->progname, "tcgetattr"); * Initialize terminal information. */ static void -term_init(name, ttype) - char *name, *ttype; +term_init(char *name, char *ttype) { int err; @@ -287,8 +254,7 @@ term_init(name, ttype) #define GLOBAL_CLP \ CL_PRIVATE *clp = GCLP(__global_list); static void -h_hup(signo) - int signo; +h_hup(int signo) { GLOBAL_CLP; @@ -297,8 +263,7 @@ h_hup(signo) } static void -h_int(signo) - int signo; +h_int(int signo) { GLOBAL_CLP; @@ -306,8 +271,7 @@ h_int(signo) } static void -h_term(signo) - int signo; +h_term(int signo) { GLOBAL_CLP; @@ -316,8 +280,7 @@ h_term(signo) } static void -h_winch(signo) - int signo; +h_winch(int signo) { GLOBAL_CLP; @@ -332,9 +295,7 @@ h_winch(signo) * PUBLIC: int sig_init __P((GS *, SCR *)); */ int -sig_init(gp, sp) - GS *gp; - SCR *sp; +sig_init(GS *gp, SCR *sp) { CL_PRIVATE *clp; @@ -376,10 +337,7 @@ sig_init(gp, sp) * Set a signal handler. */ static int -setsig(signo, oactp, handler) - int signo; - struct sigaction *oactp; - void (*handler) __P((int)); +setsig(int signo, struct sigaction *oactp, void (*handler) (int)) { struct sigaction act; @@ -410,8 +368,7 @@ setsig(signo, oactp, handler) * End signal setup. */ static void -sig_end(gp) - GS *gp; +sig_end(GS *gp) { CL_PRIVATE *clp; @@ -429,17 +386,20 @@ sig_end(gp) * Initialize the standard curses functions. */ static void -cl_func_std(gp) - GS *gp; +cl_func_std(GS *gp) { gp->scr_addstr = cl_addstr; + gp->scr_waddstr = cl_waddstr; gp->scr_attr = cl_attr; gp->scr_baud = cl_baud; gp->scr_bell = cl_bell; gp->scr_busy = NULL; + gp->scr_child = NULL; gp->scr_clrtoeol = cl_clrtoeol; gp->scr_cursor = cl_cursor; gp->scr_deleteln = cl_deleteln; + gp->scr_reply = NULL; + gp->scr_discard = cl_discard; gp->scr_event = cl_event; gp->scr_ex_adjust = cl_ex_adjust; gp->scr_fmap = cl_fmap; @@ -451,6 +411,7 @@ cl_func_std(gp) gp->scr_refresh = cl_refresh; gp->scr_rename = cl_rename; gp->scr_screen = cl_screen; + gp->scr_split = cl_split; gp->scr_suspend = cl_suspend; gp->scr_usage = cl_usage; } @@ -460,8 +421,7 @@ cl_func_std(gp) * Print system error. */ static void -perr(name, msg) - char *name, *msg; +perr(char *name, char *msg) { (void)fprintf(stderr, "%s:", name); if (msg != NULL) diff --git a/contrib/nvi/cl/cl_read.c b/contrib/nvi/cl/cl_read.c index 8a95a77..410cdd4 100644 --- a/contrib/nvi/cl/cl_read.c +++ b/contrib/nvi/cl/cl_read.c @@ -10,18 +10,14 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)cl_read.c 10.15 (Berkeley) 9/24/96"; +static const char sccsid[] = "$Id: cl_read.c,v 10.30 2012/07/12 18:28:58 zy Exp $"; #endif /* not lint */ #include <sys/types.h> #include <sys/queue.h> -#ifdef HAVE_SYS_SELECT_H #include <sys/select.h> -#endif -#include <sys/time.h> #include <bitstring.h> -#include <curses.h> #include <errno.h> #include <fcntl.h> #include <signal.h> @@ -35,8 +31,12 @@ static const char sccsid[] = "@(#)cl_read.c 10.15 (Berkeley) 9/24/96"; #include "../ex/script.h" #include "cl.h" +/* Pollution by Solaris curses. */ +#undef columns +#undef lines + static input_t cl_read __P((SCR *, - u_int32_t, CHAR_T *, size_t, int *, struct timeval *)); + u_int32_t, char *, size_t, int *, struct timeval *)); static int cl_resize __P((SCR *, size_t, size_t)); /* @@ -46,16 +46,15 @@ static int cl_resize __P((SCR *, size_t, size_t)); * PUBLIC: int cl_event __P((SCR *, EVENT *, u_int32_t, int)); */ int -cl_event(sp, evp, flags, ms) - SCR *sp; - EVENT *evp; - u_int32_t flags; - int ms; +cl_event(SCR *sp, EVENT *evp, u_int32_t flags, int ms) { struct timeval t, *tp; CL_PRIVATE *clp; size_t lines, columns; - int changed, nr; + int changed, nr = 0; + CHAR_T *wp; + size_t wlen; + int rc; /* * Queue signal based events. We never clear SIGHUP or SIGTERM events, @@ -102,12 +101,25 @@ retest: if (LF_ISSET(EC_INTERRUPT) || F_ISSET(clp, CL_SIGINT)) { } /* Read input characters. */ +read: switch (cl_read(sp, LF_ISSET(EC_QUOTED | EC_RAW), - clp->ibuf, sizeof(clp->ibuf), &nr, tp)) { + clp->ibuf + clp->skip, SIZE(clp->ibuf) - clp->skip, &nr, tp)) { case INP_OK: - evp->e_csp = clp->ibuf; - evp->e_len = nr; + rc = INPUT2INT5(sp, clp->cw, clp->ibuf, nr + clp->skip, + wp, wlen); + evp->e_csp = wp; + evp->e_len = wlen; evp->e_event = E_STRING; + if (rc < 0) { + int n = -rc; + memmove(clp->ibuf, clp->ibuf + nr + clp->skip - n, n); + clp->skip = n; + if (wlen == 0) + goto read; + } else if (rc == 0) + clp->skip = 0; + else + msgq(sp, M_ERR, "323|Invalid input. Truncated."); break; case INP_EOF: evp->e_event = E_EOF; @@ -131,19 +143,11 @@ retest: if (LF_ISSET(EC_INTERRUPT) || F_ISSET(clp, CL_SIGINT)) { * Read characters from the input. */ static input_t -cl_read(sp, flags, bp, blen, nrp, tp) - SCR *sp; - u_int32_t flags; - CHAR_T *bp; - size_t blen; - int *nrp; - struct timeval *tp; +cl_read(SCR *sp, u_int32_t flags, char *bp, size_t blen, int *nrp, struct timeval *tp) { struct termios term1, term2; - struct timeval poll; CL_PRIVATE *clp; GS *gp; - SCR *tsp; fd_set rdfd; input_t rval; int maxfd, nr, term_reset; @@ -175,13 +179,10 @@ cl_read(sp, flags, bp, blen, nrp, tp) * 2: A read with an associated timeout, e.g., trying to complete * a map sequence. If input exists, we fall into #3. */ - FD_ZERO(&rdfd); - poll.tv_sec = 0; - poll.tv_usec = 0; if (tp != NULL) { + FD_ZERO(&rdfd); FD_SET(STDIN_FILENO, &rdfd); - switch (select(STDIN_FILENO + 1, - &rdfd, NULL, NULL, tp == NULL ? &poll : tp)) { + switch (select(STDIN_FILENO + 1, &rdfd, NULL, NULL, tp)) { case 0: return (INP_TIMEOUT); case -1: @@ -225,13 +226,11 @@ cl_read(sp, flags, bp, blen, nrp, tp) loop: FD_ZERO(&rdfd); FD_SET(STDIN_FILENO, &rdfd); maxfd = STDIN_FILENO; - for (tsp = gp->dq.cqh_first; - tsp != (void *)&gp->dq; tsp = tsp->q.cqe_next) - if (F_ISSET(sp, SC_SCRIPT)) { - FD_SET(sp->script->sh_master, &rdfd); - if (sp->script->sh_master > maxfd) - maxfd = sp->script->sh_master; - } + if (F_ISSET(sp, SC_SCRIPT)) { + FD_SET(sp->script->sh_master, &rdfd); + if (sp->script->sh_master > maxfd) + maxfd = sp->script->sh_master; + } switch (select(maxfd + 1, &rdfd, NULL, NULL, NULL)) { case 0: abort(); @@ -309,12 +308,10 @@ err: if (errno == EINTR) * Reset the options for a resize event. */ static int -cl_resize(sp, lines, columns) - SCR *sp; - size_t lines, columns; +cl_resize(SCR *sp, size_t lines, size_t columns) { ARGS *argv[2], a, b; - char b1[1024]; + CHAR_T b1[1024]; a.bp = b1; b.bp = NULL; @@ -322,12 +319,10 @@ cl_resize(sp, lines, columns) argv[0] = &a; argv[1] = &b; - (void)snprintf(b1, sizeof(b1), "lines=%lu", (u_long)lines); - a.len = strlen(b1); + a.len = SPRINTF(b1, sizeof(b1), L("lines=%lu"), (u_long)lines); if (opts_set(sp, argv, NULL)) return (1); - (void)snprintf(b1, sizeof(b1), "columns=%lu", (u_long)columns); - a.len = strlen(b1); + a.len = SPRINTF(b1, sizeof(b1), L("columns=%lu"), (u_long)columns); if (opts_set(sp, argv, NULL)) return (1); return (0); diff --git a/contrib/nvi/cl/cl_screen.c b/contrib/nvi/cl/cl_screen.c index bfb9199..91ff278 100644 --- a/contrib/nvi/cl/cl_screen.c +++ b/contrib/nvi/cl/cl_screen.c @@ -5,27 +5,27 @@ * Keith Bostic. All rights reserved. * * See the LICENSE file for redistribution information. - * - * $FreeBSD$ */ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)cl_screen.c 10.49 (Berkeley) 9/24/96"; +static const char sccsid[] = "$Id: cl_screen.c,v 10.56 2002/05/03 19:59:44 skimo Exp $"; #endif /* not lint */ #include <sys/types.h> #include <sys/queue.h> +#include <sys/time.h> #include <bitstring.h> -#include <curses.h> #include <errno.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#ifdef HAVE_TERM_H #include <term.h> +#endif #include <termios.h> #include <unistd.h> @@ -46,26 +46,30 @@ static int cl_putenv __P((char *, char *, u_long)); * PUBLIC: int cl_screen __P((SCR *, u_int32_t)); */ int -cl_screen(sp, flags) - SCR *sp; - u_int32_t flags; +cl_screen(SCR *sp, u_int32_t flags) { CL_PRIVATE *clp; + WINDOW *win; GS *gp; gp = sp->gp; clp = CLP(sp); + win = CLSP(sp) ? CLSP(sp) : stdscr; /* See if the current information is incorrect. */ if (F_ISSET(gp, G_SRESTART)) { + if (CLSP(sp)) { + delwin(CLSP(sp)); + sp->cl_private = NULL; + } if (cl_quit(gp)) return (1); F_CLR(gp, G_SRESTART); } /* See if we're already in the right mode. */ - if (LF_ISSET(SC_EX) && F_ISSET(sp, SC_SCR_EX) || - LF_ISSET(SC_VI) && F_ISSET(sp, SC_SCR_VI)) + if ((LF_ISSET(SC_EX) && F_ISSET(sp, SC_SCR_EX)) || + (LF_ISSET(SC_VI) && F_ISSET(sp, SC_SCR_VI))) return (0); /* @@ -93,12 +97,12 @@ cl_screen(sp, flags) if (F_ISSET(sp, SC_SCR_VI)) { F_CLR(sp, SC_SCR_VI); - if (sp->q.cqe_next != (void *)&gp->dq) { - (void)move(RLNO(sp, sp->rows), 0); - clrtobot(); + if (TAILQ_NEXT(sp, q) != NULL) { + (void)wmove(win, RLNO(sp, sp->rows), 0); + wclrtobot(win); } - (void)move(RLNO(sp, sp->rows) - 1, 0); - refresh(); + (void)wmove(win, RLNO(sp, sp->rows) - 1, 0); + wrefresh(win); } /* Enter the requested mode. */ @@ -130,8 +134,7 @@ cl_screen(sp, flags) * PUBLIC: int cl_quit __P((GS *)); */ int -cl_quit(gp) - GS *gp; +cl_quit(GS *gp) { CL_PRIVATE *clp; int rval; @@ -181,8 +184,7 @@ cl_quit(gp) * Initialize the curses vi screen. */ static int -cl_vi_init(sp) - SCR *sp; +cl_vi_init(SCR *sp) { CL_PRIVATE *clp; GS *gp; @@ -245,6 +247,7 @@ cl_vi_init(sp) * The HP/UX newterm doesn't support the NULL first argument, so we * have to specify the terminal type. */ + (void)del_curterm(cur_term); errno = 0; if (newterm(ttype, stdout, stdin) == NULL) { if (errno) @@ -385,8 +388,7 @@ err: (void)cl_vi_end(sp->gp); * Shutdown the vi screen. */ static int -cl_vi_end(gp) - GS *gp; +cl_vi_end(GS *gp) { CL_PRIVATE *clp; @@ -429,8 +431,7 @@ cl_vi_end(gp) * Initialize the ex screen. */ static int -cl_ex_init(sp) - SCR *sp; +cl_ex_init(SCR *sp) { CL_PRIVATE *clp; @@ -504,8 +505,7 @@ fast: if (tcsetattr(STDIN_FILENO, TCSADRAIN | TCSASOFT, &clp->ex_enter)) { * Shutdown the ex screen. */ static int -cl_ex_end(gp) - GS *gp; +cl_ex_end(GS *gp) { CL_PRIVATE *clp; @@ -523,9 +523,7 @@ cl_ex_end(gp) * PUBLIC: int cl_getcap __P((SCR *, char *, char **)); */ int -cl_getcap(sp, name, elementp) - SCR *sp; - char *name, **elementp; +cl_getcap(SCR *sp, char *name, char **elementp) { size_t len; char *t; @@ -543,8 +541,7 @@ cl_getcap(sp, name, elementp) * Free any allocated termcap/terminfo strings. */ static void -cl_freecap(clp) - CL_PRIVATE *clp; +cl_freecap(CL_PRIVATE *clp) { if (clp->el != NULL) { free(clp->el); @@ -566,6 +563,12 @@ cl_freecap(clp) free(clp->smso); clp->smso = NULL; } + /* Required by libcursesw :) */ + if (clp->cw.bp1.c != NULL) { + free(clp->cw.bp1.c); + clp->cw.bp1.c = NULL; + clp->cw.blen1 = 0; + } } /* @@ -573,10 +576,7 @@ cl_freecap(clp) * Put a value into the environment. */ static int -cl_putenv(name, str, value) - char *name, *str; - u_long value; - +cl_putenv(char *name, char *str, u_long value) { char buf[40]; diff --git a/contrib/nvi/cl/cl_term.c b/contrib/nvi/cl/cl_term.c index c36bb38..3d8cdb2 100644 --- a/contrib/nvi/cl/cl_term.c +++ b/contrib/nvi/cl/cl_term.c @@ -10,7 +10,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)cl_term.c 10.22 (Berkeley) 9/15/96"; +static const char sccsid[] = "$Id: cl_term.c,v 10.33 2012/04/21 23:51:46 zy Exp $"; #endif /* not lint */ #include <sys/types.h> @@ -19,13 +19,15 @@ static const char sccsid[] = "@(#)cl_term.c 10.22 (Berkeley) 9/15/96"; #include <sys/stat.h> #include <bitstring.h> -#include <curses.h> #include <errno.h> #include <limits.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#ifdef HAVE_TERM_H +#include <term.h> +#endif #include <termios.h> #include <unistd.h> @@ -82,20 +84,30 @@ static TKLIST const m2_tklist[] = { /* Input mappings (set or delete). */ * PUBLIC: int cl_term_init __P((SCR *)); */ int -cl_term_init(sp) - SCR *sp; +cl_term_init(SCR *sp) { KEYLIST *kp; SEQ *qp; TKLIST const *tkp; char *t; + CHAR_T name[60]; + CHAR_T output[5]; + CHAR_T ts[20]; + CHAR_T *wp; + size_t wlen; /* Command mappings. */ for (tkp = c_tklist; tkp->name != NULL; ++tkp) { if ((t = tigetstr(tkp->ts)) == NULL || t == (char *)-1) continue; - if (seq_set(sp, tkp->name, strlen(tkp->name), t, strlen(t), - tkp->output, strlen(tkp->output), SEQ_COMMAND, + CHAR2INT(sp, tkp->name, strlen(tkp->name), wp, wlen); + MEMCPY(name, wp, wlen); + CHAR2INT(sp, t, strlen(t), wp, wlen); + MEMCPY(ts, wp, wlen); + CHAR2INT(sp, tkp->output, strlen(tkp->output), wp, wlen); + MEMCPY(output, wp, wlen); + if (seq_set(sp, name, strlen(tkp->name), ts, strlen(t), + output, strlen(tkp->output), SEQ_COMMAND, SEQ_NOOVERWRITE | SEQ_SCREEN)) return (1); } @@ -109,8 +121,13 @@ cl_term_init(sp) break; if (kp == NULL) continue; - if (seq_set(sp, tkp->name, strlen(tkp->name), t, strlen(t), - &kp->ch, 1, SEQ_INPUT, SEQ_NOOVERWRITE | SEQ_SCREEN)) + CHAR2INT(sp, tkp->name, strlen(tkp->name), wp, wlen); + MEMCPY(name, wp, wlen); + CHAR2INT(sp, t, strlen(t), wp, wlen); + MEMCPY(ts, wp, wlen); + output[0] = (UCHAR_T)kp->ch; + if (seq_set(sp, name, strlen(tkp->name), ts, strlen(t), + output, 1, SEQ_INPUT, SEQ_NOOVERWRITE | SEQ_SCREEN)) return (1); } @@ -128,22 +145,33 @@ cl_term_init(sp) if (!strcmp(t, "\b")) continue; if (tkp->output == NULL) { - if (seq_set(sp, tkp->name, strlen(tkp->name), - t, strlen(t), NULL, 0, + CHAR2INT(sp, tkp->name, strlen(tkp->name), wp, wlen); + MEMCPY(name, wp, wlen); + CHAR2INT(sp, t, strlen(t), wp, wlen); + MEMCPY(ts, wp, wlen); + if (seq_set(sp, name, strlen(tkp->name), + ts, strlen(t), NULL, 0, SEQ_INPUT, SEQ_NOOVERWRITE | SEQ_SCREEN)) return (1); - } else - if (seq_set(sp, tkp->name, strlen(tkp->name), - t, strlen(t), tkp->output, strlen(tkp->output), + } else { + CHAR2INT(sp, tkp->name, strlen(tkp->name), wp, wlen); + MEMCPY(name, wp, wlen); + CHAR2INT(sp, t, strlen(t), wp, wlen); + MEMCPY(ts, wp, wlen); + CHAR2INT(sp, tkp->output, strlen(tkp->output), wp, wlen); + MEMCPY(output, wp, wlen); + if (seq_set(sp, name, strlen(tkp->name), + ts, strlen(t), output, strlen(tkp->output), SEQ_INPUT, SEQ_NOOVERWRITE | SEQ_SCREEN)) return (1); + } } /* * Rework any function key mappings that were set before the * screen was initialized. */ - for (qp = sp->gp->seqq.lh_first; qp != NULL; qp = qp->q.le_next) + SLIST_FOREACH(qp, sp->gp->seqq, q) if (F_ISSET(qp, SEQ_FUNCMAP)) (void)cl_pfmap(sp, qp->stype, qp->input, qp->ilen, qp->output, qp->olen); @@ -157,17 +185,16 @@ cl_term_init(sp) * PUBLIC: int cl_term_end __P((GS *)); */ int -cl_term_end(gp) - GS *gp; +cl_term_end(GS *gp) { SEQ *qp, *nqp; /* Delete screen specific mappings. */ - for (qp = gp->seqq.lh_first; qp != NULL; qp = nqp) { - nqp = qp->q.le_next; - if (F_ISSET(qp, SEQ_SCREEN)) - (void)seq_mdel(qp); - } + SLIST_FOREACH_SAFE(qp, gp->seqq, q, nqp) + if (F_ISSET(qp, SEQ_SCREEN)) { + SLIST_REMOVE_HEAD(gp->seqq, q); + (void)seq_free(qp); + } return (0); } @@ -178,11 +205,7 @@ cl_term_end(gp) * PUBLIC: int cl_fmap __P((SCR *, seq_t, CHAR_T *, size_t, CHAR_T *, size_t)); */ int -cl_fmap(sp, stype, from, flen, to, tlen) - SCR *sp; - seq_t stype; - CHAR_T *from, *to; - size_t flen, tlen; +cl_fmap(SCR *sp, seq_t stype, CHAR_T *from, size_t flen, CHAR_T *to, size_t tlen) { /* Ignore until the screen is running, do the real work then. */ if (F_ISSET(sp, SC_VI) && !F_ISSET(sp, SC_SCR_VI)) @@ -198,28 +221,33 @@ cl_fmap(sp, stype, from, flen, to, tlen) * Map a function key (private version). */ static int -cl_pfmap(sp, stype, from, flen, to, tlen) - SCR *sp; - seq_t stype; - CHAR_T *from, *to; - size_t flen, tlen; +cl_pfmap(SCR *sp, seq_t stype, CHAR_T *from, size_t flen, CHAR_T *to, size_t tlen) { size_t nlen; - char *p, keyname[64]; - - (void)snprintf(keyname, sizeof(keyname), "kf%d", atoi(from + 1)); - if ((p = tigetstr(keyname)) == NULL || + char *p; + char name[64]; + CHAR_T keyname[64]; + CHAR_T ts[20]; + CHAR_T *wp; + size_t wlen; + + (void)snprintf(name, sizeof(name), "kf%d", + (int)STRTOL(from+1,NULL,10)); + if ((p = tigetstr(name)) == NULL || p == (char *)-1 || strlen(p) == 0) p = NULL; if (p == NULL) { - msgq_str(sp, M_ERR, from, "233|This terminal has no %s key"); + msgq_wstr(sp, M_ERR, from, "233|This terminal has no %s key"); return (1); } - nlen = snprintf(keyname, - sizeof(keyname), "function key %d", atoi(from + 1)); + nlen = SPRINTF(keyname, + SIZE(keyname), L("function key %d"), + (int)STRTOL(from+1,NULL,10)); + CHAR2INT(sp, p, strlen(p), wp, wlen); + MEMCPY(ts, wp, wlen); return (seq_set(sp, keyname, nlen, - p, strlen(p), to, tlen, stype, SEQ_NOOVERWRITE | SEQ_SCREEN)); + ts, strlen(p), to, tlen, stype, SEQ_NOOVERWRITE | SEQ_SCREEN)); } /* @@ -229,11 +257,7 @@ cl_pfmap(sp, stype, from, flen, to, tlen) * PUBLIC: int cl_optchange __P((SCR *, int, char *, u_long *)); */ int -cl_optchange(sp, opt, str, valp) - SCR *sp; - int opt; - char *str; - u_long *valp; +cl_optchange(SCR *sp, int opt, char *str, u_long *valp) { CL_PRIVATE *clp; @@ -251,14 +275,10 @@ cl_optchange(sp, opt, str, valp) F_CLR(sp, SC_SCR_EX | SC_SCR_VI); break; case O_MESG: - (void)cl_omesg(sp, clp, !*valp); + (void)cl_omesg(sp, clp, *valp); break; case O_WINDOWNAME: if (*valp) { - F_CLR(clp, CL_RENAME_OK); - - (void)cl_rename(sp, NULL, 0); - } else { F_SET(clp, CL_RENAME_OK); /* @@ -267,6 +287,10 @@ cl_optchange(sp, opt, str, valp) */ if (sp->frp != NULL && sp->frp->name != NULL) (void)cl_rename(sp, sp->frp->name, 1); + } else { + F_CLR(clp, CL_RENAME_OK); + + (void)cl_rename(sp, NULL, 0); } break; } @@ -280,10 +304,7 @@ cl_optchange(sp, opt, str, valp) * PUBLIC: int cl_omesg __P((SCR *, CL_PRIVATE *, int)); */ int -cl_omesg(sp, clp, on) - SCR *sp; - CL_PRIVATE *clp; - int on; +cl_omesg(SCR *sp, CL_PRIVATE *clp, int on) { struct stat sb; char *tty; @@ -329,15 +350,9 @@ cl_omesg(sp, clp, on) * PUBLIC: int cl_ssize __P((SCR *, int, size_t *, size_t *, int *)); */ int -cl_ssize(sp, sigwinch, rowp, colp, changedp) - SCR *sp; - int sigwinch; - size_t *rowp, *colp; - int *changedp; +cl_ssize(SCR *sp, int sigwinch, size_t *rowp, size_t *colp, int *changedp) { -#ifdef TIOCGWINSZ struct winsize win; -#endif size_t col, row; int rval; char *p; @@ -358,12 +373,10 @@ cl_ssize(sp, sigwinch, rowp, colp, changedp) * Try TIOCGWINSZ. */ row = col = 0; -#ifdef TIOCGWINSZ if (ioctl(STDERR_FILENO, TIOCGWINSZ, &win) != -1) { row = win.ws_row; col = win.ws_col; } -#endif /* If here because of suspend or a signal, only trust TIOCGWINSZ. */ if (sigwinch) { /* @@ -453,8 +466,7 @@ noterm: if (row == 0) * PUBLIC: int cl_putchar __P((int)); */ int -cl_putchar(ch) - int ch; +cl_putchar(int ch) { return (putchar(ch)); } diff --git a/contrib/nvi/cl/extern.h b/contrib/nvi/cl/extern.h new file mode 100644 index 0000000..626f4fb --- /dev/null +++ b/contrib/nvi/cl/extern.h @@ -0,0 +1,31 @@ +int cl_waddstr __P((SCR *, const CHAR_T *, size_t)); +int cl_addstr __P((SCR *, const char *, size_t)); +int cl_attr __P((SCR *, scr_attr_t, int)); +int cl_baud __P((SCR *, u_long *)); +int cl_bell __P((SCR *)); +int cl_clrtoeol __P((SCR *)); +int cl_cursor __P((SCR *, size_t *, size_t *)); +int cl_deleteln __P((SCR *)); +int cl_discard __P((SCR *, SCR **)); +int cl_ex_adjust __P((SCR *, exadj_t)); +int cl_insertln __P((SCR *)); +int cl_keyval __P((SCR *, scr_keyval_t, CHAR_T *, int *)); +int cl_move __P((SCR *, size_t, size_t)); +int cl_refresh __P((SCR *, int)); +int cl_rename __P((SCR *, char *, int)); +void cl_setname __P((GS *, char *)); +int cl_split __P((SCR *, SCR *)); +int cl_suspend __P((SCR *, int *)); +void cl_usage __P((void)); +int sig_init __P((GS *, SCR *)); +int cl_event __P((SCR *, EVENT *, u_int32_t, int)); +int cl_screen __P((SCR *, u_int32_t)); +int cl_quit __P((GS *)); +int cl_getcap __P((SCR *, char *, char **)); +int cl_term_init __P((SCR *)); +int cl_term_end __P((GS *)); +int cl_fmap __P((SCR *, seq_t, CHAR_T *, size_t, CHAR_T *, size_t)); +int cl_optchange __P((SCR *, int, char *, u_long *)); +int cl_omesg __P((SCR *, CL_PRIVATE *, int)); +int cl_ssize __P((SCR *, int, size_t *, size_t *, int *)); +int cl_putchar __P((int)); |