Home | History | Annotate | Line # | Download | only in cl
      1  1.4       rin /*	$NetBSD: cl_bsd.c,v 1.4 2017/11/06 03:08:41 rin Exp $ */
      2  1.1  christos /*-
      3  1.1  christos  * Copyright (c) 1995, 1996
      4  1.1  christos  *	Keith Bostic.  All rights reserved.
      5  1.1  christos  *
      6  1.1  christos  * See the LICENSE file for redistribution information.
      7  1.1  christos  */
      8  1.1  christos 
      9  1.1  christos #include "config.h"
     10  1.1  christos 
     11  1.3  christos #include <sys/cdefs.h>
     12  1.3  christos #if 0
     13  1.1  christos #ifndef lint
     14  1.1  christos static const char sccsid[] = "Id: cl_bsd.c,v 8.32 2000/12/01 13:56:17 skimo Exp  (Berkeley) Date: 2000/12/01 13:56:17 ";
     15  1.1  christos #endif /* not lint */
     16  1.3  christos #else
     17  1.4       rin __RCSID("$NetBSD: cl_bsd.c,v 1.4 2017/11/06 03:08:41 rin Exp $");
     18  1.3  christos #endif
     19  1.1  christos 
     20  1.1  christos #include <sys/types.h>
     21  1.1  christos #include <sys/queue.h>
     22  1.1  christos #include <sys/time.h>
     23  1.1  christos 
     24  1.1  christos #include <bitstring.h>
     25  1.1  christos #include <ctype.h>
     26  1.1  christos #include <signal.h>
     27  1.1  christos #include <stdio.h>
     28  1.1  christos #include <stdlib.h>
     29  1.1  christos #include <string.h>
     30  1.1  christos #include <termios.h>
     31  1.1  christos #include <unistd.h>
     32  1.1  christos 
     33  1.1  christos #include "../common/common.h"
     34  1.1  christos #include "../vi/vi.h"
     35  1.1  christos #include "cl.h"
     36  1.1  christos 
     37  1.2  christos #ifndef HAVE_CURSES_SETUPTERM
     38  1.1  christos static char	*ke;				/* Keypad on. */
     39  1.1  christos static char	*ks;				/* Keypad off. */
     40  1.1  christos static char	*vb;				/* Visible bell string. */
     41  1.2  christos #endif
     42  1.1  christos 
     43  1.1  christos /*
     44  1.1  christos  * HP's support the entire System V curses package except for the tigetstr
     45  1.1  christos  * and tigetnum functions.  Ultrix supports the BSD curses package except
     46  1.1  christos  * for the idlok function.  Cthulu only knows why.  Break things up into a
     47  1.1  christos  * minimal set of functions.
     48  1.1  christos  */
     49  1.1  christos 
     50  1.1  christos #ifndef HAVE_CURSES_WADDNSTR
     51  1.1  christos /*
     52  1.1  christos  * waddnstr --
     53  1.1  christos  *
     54  1.1  christos  * PUBLIC: #ifndef HAVE_CURSES_WADDNSTR
     55  1.1  christos  * PUBLIC: int waddnstr __P((WINDOW*, char *, int));
     56  1.1  christos  * PUBLIC: #endif
     57  1.1  christos  */
     58  1.1  christos int
     59  1.1  christos waddnstr(w, s, n)
     60  1.1  christos 	WINDOW *w;
     61  1.1  christos 	char *s;
     62  1.1  christos 	int n;
     63  1.1  christos {
     64  1.1  christos 	int ch;
     65  1.1  christos 
     66  1.1  christos 	while (n-- && (ch = *s++))
     67  1.1  christos 		waddch(w, ch);
     68  1.1  christos 	return (OK);
     69  1.1  christos }
     70  1.1  christos #endif
     71  1.1  christos 
     72  1.1  christos #ifndef	HAVE_CURSES_BEEP
     73  1.1  christos /*
     74  1.1  christos  * beep --
     75  1.1  christos  *
     76  1.1  christos  * PUBLIC: #ifndef HAVE_CURSES_BEEP
     77  1.1  christos  * PUBLIC: void beep __P((void));
     78  1.1  christos  * PUBLIC: #endif
     79  1.1  christos  */
     80  1.1  christos void
     81  1.1  christos beep()
     82  1.1  christos {
     83  1.1  christos 	(void)write(1, "\007", 1);	/* '\a' */
     84  1.1  christos }
     85  1.1  christos #endif /* !HAVE_CURSES_BEEP */
     86  1.1  christos 
     87  1.1  christos #ifndef	HAVE_CURSES_FLASH
     88  1.1  christos /*
     89  1.1  christos  * flash --
     90  1.1  christos  *	Flash the screen.
     91  1.1  christos  *
     92  1.1  christos  * PUBLIC: #ifndef HAVE_CURSES_FLASH
     93  1.1  christos  * PUBLIC: void flash __P((void));
     94  1.1  christos  * PUBLIC: #endif
     95  1.1  christos  */
     96  1.1  christos void
     97  1.1  christos flash()
     98  1.1  christos {
     99  1.1  christos 	if (vb != NULL) {
    100  1.1  christos 		(void)tputs(vb, 1, cl_putchar);
    101  1.1  christos 		(void)fflush(stdout);
    102  1.1  christos 	} else
    103  1.1  christos 		beep();
    104  1.1  christos }
    105  1.1  christos #endif /* !HAVE_CURSES_FLASH */
    106  1.1  christos 
    107  1.1  christos #ifndef	HAVE_CURSES_IDLOK
    108  1.1  christos /*
    109  1.1  christos  * idlok --
    110  1.1  christos  *	Turn on/off hardware line insert/delete.
    111  1.1  christos  *
    112  1.1  christos  * PUBLIC: #ifndef HAVE_CURSES_IDLOK
    113  1.1  christos  * PUBLIC: void idlok __P((WINDOW *, int));
    114  1.1  christos  * PUBLIC: #endif
    115  1.1  christos  */
    116  1.1  christos void
    117  1.1  christos idlok(win, bf)
    118  1.1  christos 	WINDOW *win;
    119  1.1  christos 	int bf;
    120  1.1  christos {
    121  1.1  christos 	return;
    122  1.1  christos }
    123  1.1  christos #endif /* !HAVE_CURSES_IDLOK */
    124  1.1  christos 
    125  1.1  christos #ifndef	HAVE_CURSES_KEYPAD
    126  1.1  christos /*
    127  1.1  christos  * keypad --
    128  1.1  christos  *	Put the keypad/cursor arrows into or out of application mode.
    129  1.1  christos  *
    130  1.1  christos  * PUBLIC: #ifndef HAVE_CURSES_KEYPAD
    131  1.1  christos  * PUBLIC: int keypad __P((void *, int));
    132  1.1  christos  * PUBLIC: #endif
    133  1.1  christos  */
    134  1.1  christos int
    135  1.1  christos keypad(a, on)
    136  1.1  christos 	void *a;
    137  1.1  christos 	int on;
    138  1.1  christos {
    139  1.1  christos 	char *p;
    140  1.1  christos 
    141  1.1  christos 	if ((p = tigetstr(on ? "smkx" : "rmkx")) != (char *)-1) {
    142  1.1  christos 		(void)tputs(p, 0, cl_putchar);
    143  1.1  christos 		(void)fflush(stdout);
    144  1.1  christos 	}
    145  1.1  christos 	return (0);
    146  1.1  christos }
    147  1.1  christos #endif /* !HAVE_CURSES_KEYPAD */
    148  1.1  christos 
    149  1.1  christos #ifndef	HAVE_CURSES_NEWTERM
    150  1.1  christos /*
    151  1.1  christos  * newterm --
    152  1.1  christos  *	Create a new curses screen.
    153  1.1  christos  *
    154  1.1  christos  * PUBLIC: #ifndef HAVE_CURSES_NEWTERM
    155  1.1  christos  * PUBLIC: void *newterm __P((const char *, FILE *, FILE *));
    156  1.1  christos  * PUBLIC: #endif
    157  1.1  christos  */
    158  1.1  christos void *
    159  1.1  christos newterm(a, b, c)
    160  1.1  christos 	const char *a;
    161  1.1  christos 	FILE *b, *c;
    162  1.1  christos {
    163  1.1  christos 	return (initscr());
    164  1.1  christos }
    165  1.1  christos #endif /* !HAVE_CURSES_NEWTERM */
    166  1.1  christos 
    167  1.1  christos #ifndef	HAVE_CURSES_SETUPTERM
    168  1.1  christos /*
    169  1.1  christos  * setupterm --
    170  1.1  christos  *	Set up terminal.
    171  1.1  christos  *
    172  1.1  christos  * PUBLIC: #ifndef HAVE_CURSES_SETUPTERM
    173  1.1  christos  * PUBLIC: void setupterm __P((char *, int, int *));
    174  1.1  christos  * PUBLIC: #endif
    175  1.1  christos  */
    176  1.1  christos void
    177  1.1  christos setupterm(ttype, fno, errp)
    178  1.1  christos 	char *ttype;
    179  1.1  christos 	int fno, *errp;
    180  1.1  christos {
    181  1.1  christos 	static char buf[2048];
    182  1.1  christos 	char *p;
    183  1.1  christos 
    184  1.1  christos 	if ((*errp = tgetent(buf, ttype)) > 0) {
    185  1.1  christos 		if (ke != NULL)
    186  1.1  christos 			free(ke);
    187  1.1  christos 		ke = ((p = tigetstr("rmkx")) == (char *)-1) ?
    188  1.1  christos 		    NULL : strdup(p);
    189  1.1  christos 		if (ks != NULL)
    190  1.1  christos 			free(ks);
    191  1.1  christos 		ks = ((p = tigetstr("smkx")) == (char *)-1) ?
    192  1.1  christos 		    NULL : strdup(p);
    193  1.1  christos 		if (vb != NULL)
    194  1.1  christos 			free(vb);
    195  1.1  christos 		vb = ((p = tigetstr("flash")) == (char *)-1) ?
    196  1.1  christos 		    NULL : strdup(p);
    197  1.1  christos 	}
    198  1.1  christos }
    199  1.1  christos #endif /* !HAVE_CURSES_SETUPTERM */
    200  1.1  christos 
    201  1.1  christos #ifndef	HAVE_CURSES_TIGETSTR
    202  1.1  christos /* Terminfo-to-termcap translation table. */
    203  1.1  christos typedef struct _tl {
    204  1.2  christos 	const char *terminfo;		/* Terminfo name. */
    205  1.2  christos 	const char *termcap;		/* Termcap name. */
    206  1.1  christos } TL;
    207  1.1  christos static const TL list[] = {
    208  1.2  christos 	{ "cols",	"co", },	/* Terminal columns. */
    209  1.2  christos 	{ "cup",	"cm", },	/* Cursor up. */
    210  1.2  christos 	{ "cuu1",	"up", },	/* Cursor up. */
    211  1.2  christos 	{ "el",		"ce", },	/* Clear to end-of-line. */
    212  1.2  christos 	{ "flash",	"vb", },	/* Visible bell. */
    213  1.2  christos 	{ "kcub1",  	"kl", },	/* Cursor left. */
    214  1.2  christos 	{ "kcud1",	"kd", },	/* Cursor down. */
    215  1.2  christos 	{ "kcuf1",	"kr", },	/* Cursor right. */
    216  1.2  christos 	{ "kcuu1",  	"ku", },	/* Cursor up. */
    217  1.2  christos 	{ "kdch1",	"kD", },	/* Delete character. */
    218  1.2  christos 	{ "kdl1",	"kL", },	/* Delete line. */
    219  1.2  christos 	{ "ked",	"kS", },	/* Delete to end of screen. */
    220  1.2  christos 	{ "kel",	"kE", },	/* Delete to eol. */
    221  1.2  christos 	{ "kend",	"@7", },	/* Go to eol. */
    222  1.2  christos 	{ "khome",	"kh", },	/* Go to sol. */
    223  1.2  christos 	{ "kich1",	"kI", },	/* Insert at cursor. */
    224  1.2  christos 	{ "kil1",	"kA", },	/* Insert line. */
    225  1.2  christos 	{ "kind",	"kF", },	/* Scroll down. */
    226  1.2  christos 	{ "kll",	"kH", },	/* Go to eol. */
    227  1.2  christos 	{ "knp",	"kN", },	/* Page down. */
    228  1.2  christos 	{ "kpp",	"kP", },	/* Page up. */
    229  1.2  christos 	{ "kri",	"kR", },	/* Scroll up. */
    230  1.2  christos 	{ "lines",	"li", },	/* Terminal lines. */
    231  1.2  christos 	{ "rmcup",	"te", },	/* Terminal end string. */
    232  1.2  christos 	{ "rmkx",	"ke", },	/* Exit "keypad-transmit" mode. */
    233  1.2  christos 	{ "rmso",	"se", },	/* Standout end. */
    234  1.2  christos 	{ "smcup",	"ti", },	/* Terminal initialization string. */
    235  1.2  christos 	{ "smkx",	"ks", },	/* Enter "keypad-transmit" mode. */
    236  1.2  christos 	{ "smso",	"so", },	/* Standout begin. */
    237  1.1  christos };
    238  1.1  christos 
    239  1.1  christos #ifdef _AIX
    240  1.1  christos /*
    241  1.1  christos  * AIX's implementation for function keys greater than 10 is different and
    242  1.1  christos  * only goes as far as 36.
    243  1.1  christos  */
    244  1.1  christos static const char codes[] = {
    245  1.1  christos /*  0-10 */ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ';',
    246  1.1  christos /* 11-20 */ '<', '>', '!', '@', '#', '$', '%', '^', '&', '*',
    247  1.1  christos /* 21-30 */ '(', ')', '-', '_', '+', ',', ':', '?', '[', ']',
    248  1.1  christos /* 31-36 */ '{', '}', '|', '~', '/', '='
    249  1.1  christos };
    250  1.1  christos 
    251  1.1  christos #else
    252  1.1  christos 
    253  1.1  christos /*
    254  1.1  christos  * !!!
    255  1.1  christos  * Historically, the 4BSD termcap code didn't support functions keys greater
    256  1.1  christos  * than 9.  This was silently enforced -- asking for key k12 would return the
    257  1.1  christos  * value for k1.  We try and get around this by using the tables specified in
    258  1.1  christos  * the terminfo(TI_ENV) man page from the 3rd Edition SVID.  This assumes the
    259  1.1  christos  * implementors of any System V compatibility code or an extended termcap used
    260  1.1  christos  * those codes.
    261  1.1  christos  */
    262  1.1  christos static const char codes[] = {
    263  1.1  christos /*  0-10 */ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ';',
    264  1.1  christos /* 11-19 */ '1', '2', '3', '4', '5', '6', '7', '8', '9',
    265  1.1  christos /* 20-63 */ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
    266  1.1  christos 	    'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
    267  1.1  christos 	    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
    268  1.1  christos 	    'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
    269  1.1  christos };
    270  1.1  christos #endif /* _AIX */
    271  1.1  christos 
    272  1.1  christos /*
    273  1.1  christos  * lcmp --
    274  1.1  christos  *	list comparison routine for bsearch.
    275  1.1  christos  */
    276  1.1  christos static int
    277  1.2  christos lcmp(const void *a, const void *b)
    278  1.1  christos {
    279  1.2  christos 	return (strcmp(a, ((const TL *)b)->terminfo));
    280  1.1  christos }
    281  1.1  christos 
    282  1.1  christos /*
    283  1.1  christos  * tigetstr --
    284  1.1  christos  *
    285  1.1  christos  * Vendors put the prototype for tigetstr into random include files, including
    286  1.1  christos  * <term.h>, which we can't include because it makes other systems unhappy.
    287  1.1  christos  * Try and work around the problem, since we only care about the return value.
    288  1.1  christos  *
    289  1.1  christos  * PUBLIC: #ifdef HAVE_CURSES_TIGETSTR
    290  1.4       rin  * PUBLIC: #if 0
    291  1.2  christos  * PUBLIC: char *tigetstr __P((const char *));
    292  1.4       rin  * PUBLIC: #endif
    293  1.1  christos  * PUBLIC: #else
    294  1.1  christos  * PUBLIC: char *tigetstr __P((char *));
    295  1.1  christos  * PUBLIC: #endif
    296  1.1  christos  */
    297  1.1  christos char *
    298  1.1  christos tigetstr(name)
    299  1.2  christos 	const char *name;
    300  1.1  christos {
    301  1.1  christos 	static char sbuf[256];
    302  1.1  christos 	TL *tlp;
    303  1.1  christos 	int n;
    304  1.2  christos 	char *p, mykeyname[3];
    305  1.1  christos 
    306  1.1  christos 	if ((tlp = bsearch(name,
    307  1.1  christos 	    list, sizeof(list) / sizeof(TL), sizeof(TL), lcmp)) == NULL) {
    308  1.1  christos #ifdef _AIX
    309  1.1  christos 		if (name[0] == 'k' &&
    310  1.1  christos 		    name[1] == 'f' && (n = atoi(name + 2)) <= 36) {
    311  1.2  christos 			mykeyname[0] = 'k';
    312  1.2  christos 			mykeyname[1] = codes[n];
    313  1.2  christos 			mykeyname[2] = '\0';
    314  1.1  christos #else
    315  1.1  christos 		if (name[0] == 'k' &&
    316  1.1  christos 		    name[1] == 'f' && (n = atoi(name + 2)) <= 63) {
    317  1.2  christos 			mykeyname[0] = n <= 10 ? 'k' : 'F';
    318  1.2  christos 			mykeyname[1] = codes[n];
    319  1.2  christos 			mykeyname[2] = '\0';
    320  1.1  christos #endif
    321  1.2  christos 			name = mykeyname;
    322  1.1  christos 		}
    323  1.1  christos 	} else
    324  1.1  christos 		name = tlp->termcap;
    325  1.1  christos 
    326  1.1  christos 	p = sbuf;
    327  1.1  christos #ifdef _AIX
    328  1.1  christos 	return ((p = tgetstr(name, &p)) == NULL ? (char *)-1 : strcpy(sbuf, p));
    329  1.1  christos #else
    330  1.1  christos 	return (tgetstr(name, &p) == NULL ? (char *)-1 : sbuf);
    331  1.1  christos #endif
    332  1.1  christos }
    333  1.1  christos 
    334  1.1  christos /*
    335  1.1  christos  * tigetnum --
    336  1.1  christos  *
    337  1.1  christos  * PUBLIC: #ifndef HAVE_CURSES_TIGETSTR
    338  1.1  christos  * PUBLIC: int tigetnum __P((char *));
    339  1.1  christos  * PUBLIC: #endif
    340  1.1  christos  */
    341  1.1  christos int
    342  1.1  christos tigetnum(name)
    343  1.2  christos 	const char *name;
    344  1.1  christos {
    345  1.1  christos 	TL *tlp;
    346  1.1  christos 	int val;
    347  1.1  christos 
    348  1.1  christos 	if ((tlp = bsearch(name,
    349  1.1  christos 	    list, sizeof(list) / sizeof(TL), sizeof(TL), lcmp)) != NULL) {
    350  1.1  christos 		name = tlp->termcap;
    351  1.1  christos 	}
    352  1.1  christos 
    353  1.1  christos 	return ((val = tgetnum(name)) == -1 ? -2 : val);
    354  1.1  christos }
    355  1.1  christos #endif /* !HAVE_CURSES_TIGETSTR */
    356  1.2  christos 
    357