112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*	$NetBSD: terminal.c,v 1.14 2012/05/30 18:21:14 christos Exp $	*/
212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*-
412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Copyright (c) 1992, 1993
512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	The Regents of the University of California.  All rights reserved.
612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *
712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * This code is derived from software contributed to Berkeley by
812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Christos Zoulas of Cornell University.
912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *
1012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Redistribution and use in source and binary forms, with or without
1112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * modification, are permitted provided that the following conditions
1212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * are met:
1312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 1. Redistributions of source code must retain the above copyright
1412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    notice, this list of conditions and the following disclaimer.
1512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 2. Redistributions in binary form must reproduce the above copyright
1612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    notice, this list of conditions and the following disclaimer in the
1712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    documentation and/or other materials provided with the distribution.
1812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 3. Neither the name of the University nor the names of its contributors
1912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    may be used to endorse or promote products derived from this software
2012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    without specific prior written permission.
2112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *
2212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * SUCH DAMAGE.
3312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
3412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
3512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include "config.h"
3612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#if !defined(lint) && !defined(SCCSID)
3712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#if 0
3812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialastatic char sccsid[] = "@(#)term.c	8.2 (Berkeley) 4/30/95";
3912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#else
4012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala__RCSID("$NetBSD: terminal.c,v 1.14 2012/05/30 18:21:14 christos Exp $");
4112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif
4212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* not lint && not SCCSID */
4312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
4412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*
4512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * terminal.c: Editor/termcap-curses interface
4612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	       We have to declare a static variable here, since the
4712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	       termcap putchar routine does not take an argument!
4812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
4912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <stdio.h>
5012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <signal.h>
5112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <string.h>
5212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <stdlib.h>
5312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <unistd.h>
5412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <limits.h>
5512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef HAVE_TERMCAP_H
5612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <termcap.h>
5712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif
5812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef HAVE_CURSES_H
5912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <curses.h>
6012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#elif HAVE_NCURSES_H
6112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <ncurses.h>
6212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif
6312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
6412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* Solaris's term.h does horrid things. */
6512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#if defined(HAVE_TERM_H) && !defined(__sun) && !defined(HAVE_TERMCAP_H)
6612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <term.h>
6712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif
6812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
6912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <sys/types.h>
7012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <sys/ioctl.h>
7112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
7212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef _REENTRANT
7312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <pthread.h>
7412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif
7512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
7612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include "el.h"
7712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
7812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*
7912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * IMPORTANT NOTE: these routines are allowed to look at the current screen
8012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * and the current position assuming that it is correct.  If this is not
8112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * true, then the update will be WRONG!  This is (should be) a valid
8212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * assumption...
8312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
8412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
8512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	TC_BUFSIZE	((size_t)2048)
8612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
8712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	GoodStr(a)	(el->el_terminal.t_str[a] != NULL && \
8812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			    el->el_terminal.t_str[a][0] != '\0')
8912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	Str(a)		el->el_terminal.t_str[a]
9012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	Val(a)		el->el_terminal.t_val[a]
9112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
9212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate const struct termcapstr {
9312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	const char *name;
9412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	const char *long_name;
9512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} tstr[] = {
9612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_al	0
9712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "al", "add new blank line" },
9812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_bl	1
9912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "bl", "audible bell" },
10012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_cd	2
10112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "cd", "clear to bottom" },
10212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_ce	3
10312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "ce", "clear to end of line" },
10412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_ch	4
10512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "ch", "cursor to horiz pos" },
10612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_cl	5
10712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "cl", "clear screen" },
10812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_dc	6
10912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "dc", "delete a character" },
11012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_dl	7
11112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "dl", "delete a line" },
11212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_dm	8
11312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "dm", "start delete mode" },
11412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_ed	9
11512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "ed", "end delete mode" },
11612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_ei	10
11712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "ei", "end insert mode" },
11812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_fs	11
11912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "fs", "cursor from status line" },
12012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_ho	12
12112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "ho", "home cursor" },
12212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_ic	13
12312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "ic", "insert character" },
12412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_im	14
12512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "im", "start insert mode" },
12612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_ip	15
12712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "ip", "insert padding" },
12812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_kd	16
12912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "kd", "sends cursor down" },
13012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_kl	17
13112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "kl", "sends cursor left" },
13212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_kr	18
13312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "kr", "sends cursor right" },
13412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_ku	19
13512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "ku", "sends cursor up" },
13612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_md	20
13712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "md", "begin bold" },
13812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_me	21
13912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "me", "end attributes" },
14012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_nd	22
14112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "nd", "non destructive space" },
14212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_se	23
14312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "se", "end standout" },
14412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_so	24
14512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "so", "begin standout" },
14612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_ts	25
14712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "ts", "cursor to status line" },
14812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_up	26
14912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "up", "cursor up one" },
15012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_us	27
15112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "us", "begin underline" },
15212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_ue	28
15312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "ue", "end underline" },
15412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_vb	29
15512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "vb", "visible bell" },
15612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_DC	30
15712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "DC", "delete multiple chars" },
15812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_DO	31
15912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "DO", "cursor down multiple" },
16012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_IC	32
16112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "IC", "insert multiple chars" },
16212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_LE	33
16312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "LE", "cursor left multiple" },
16412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_RI	34
16512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "RI", "cursor right multiple" },
16612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_UP	35
16712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "UP", "cursor up multiple" },
16812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_kh	36
16912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "kh", "send cursor home" },
17012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_at7	37
17112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "@7", "send cursor end" },
17212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_kD	38
17312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "kD", "send cursor delete" },
17412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_str	39
17512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ NULL, NULL }
17612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala};
17712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
17812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate const struct termcapval {
17912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	const char *name;
18012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	const char *long_name;
18112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala} tval[] = {
18212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_am	0
18312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "am", "has automatic margins" },
18412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_pt	1
18512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "pt", "has physical tabs" },
18612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_li	2
18712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "li", "Number of lines" },
18812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_co	3
18912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "co", "Number of columns" },
19012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_km	4
19112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "km", "Has meta key" },
19212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_xt	5
19312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "xt", "Tab chars destructive" },
19412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_xn	6
19512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "xn", "newline ignored at right margin" },
19612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_MT	7
19712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ "MT", "Has meta key" },			/* XXX? */
19812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	T_val	8
19912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{ NULL, NULL, }
20012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala};
20112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* do two or more of the attributes use me */
20212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
20312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void	terminal_setflags(EditLine *);
20412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate int	terminal_rebuffer_display(EditLine *);
20512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void	terminal_free_display(EditLine *);
20612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate int	terminal_alloc_display(EditLine *);
20712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void	terminal_alloc(EditLine *, const struct termcapstr *,
20812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala    const char *);
20912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void	terminal_init_arrow(EditLine *);
21012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void	terminal_reset_arrow(EditLine *);
21112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate int	terminal_putc(int);
21212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void	terminal_tputs(EditLine *, const char *, int);
21312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
21412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef _REENTRANT
21512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate pthread_mutex_t terminal_mutex = PTHREAD_MUTEX_INITIALIZER;
21612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif
21712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate FILE *terminal_outfile = NULL;
21812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
21912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
22012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_setflags():
22112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Set the terminal capability flags
22212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
22312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void
22412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_setflags(EditLine *el)
22512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
22612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	EL_FLAGS = 0;
22712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (el->el_tty.t_tabs)
22812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		EL_FLAGS |= (Val(T_pt) && !Val(T_xt)) ? TERM_CAN_TAB : 0;
22912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
23012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	EL_FLAGS |= (Val(T_km) || Val(T_MT)) ? TERM_HAS_META : 0;
23112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	EL_FLAGS |= GoodStr(T_ce) ? TERM_CAN_CEOL : 0;
23212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	EL_FLAGS |= (GoodStr(T_dc) || GoodStr(T_DC)) ? TERM_CAN_DELETE : 0;
23312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	EL_FLAGS |= (GoodStr(T_im) || GoodStr(T_ic) || GoodStr(T_IC)) ?
23412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    TERM_CAN_INSERT : 0;
23512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	EL_FLAGS |= (GoodStr(T_up) || GoodStr(T_UP)) ? TERM_CAN_UP : 0;
23612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	EL_FLAGS |= Val(T_am) ? TERM_HAS_AUTO_MARGINS : 0;
23712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	EL_FLAGS |= Val(T_xn) ? TERM_HAS_MAGIC_MARGINS : 0;
23812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
23912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (GoodStr(T_me) && GoodStr(T_ue))
24012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		EL_FLAGS |= (strcmp(Str(T_me), Str(T_ue)) == 0) ?
24112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    TERM_CAN_ME : 0;
24212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	else
24312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		EL_FLAGS &= ~TERM_CAN_ME;
24412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (GoodStr(T_me) && GoodStr(T_se))
24512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		EL_FLAGS |= (strcmp(Str(T_me), Str(T_se)) == 0) ?
24612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    TERM_CAN_ME : 0;
24712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
24812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
24912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef DEBUG_SCREEN
25012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (!EL_CAN_UP) {
25112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) fprintf(el->el_errfile,
25212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    "WARNING: Your terminal cannot move up.\n");
25312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) fprintf(el->el_errfile,
25412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    "Editing may be odd for long lines.\n");
25512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
25612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (!EL_CAN_CEOL)
25712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) fprintf(el->el_errfile, "no clear EOL capability.\n");
25812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (!EL_CAN_DELETE)
25912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) fprintf(el->el_errfile, "no delete char capability.\n");
26012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (!EL_CAN_INSERT)
26112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) fprintf(el->el_errfile, "no insert char capability.\n");
26212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* DEBUG_SCREEN */
26312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
26412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
26512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_init():
26612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Initialize the terminal stuff
26712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
26812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected int
26912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_init(EditLine *el)
27012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
27112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
27212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_terminal.t_buf = el_malloc(TC_BUFSIZE *
27312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    sizeof(*el->el_terminal.t_buf));
27412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (el->el_terminal.t_buf == NULL)
27512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return -1;
27612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_terminal.t_cap = el_malloc(TC_BUFSIZE *
27712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    sizeof(*el->el_terminal.t_cap));
27812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (el->el_terminal.t_cap == NULL)
27912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return -1;
28012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_terminal.t_fkey = el_malloc(A_K_NKEYS *
28112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    sizeof(*el->el_terminal.t_fkey));
28212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (el->el_terminal.t_fkey == NULL)
28312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return -1;
28412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_terminal.t_loc = 0;
28512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_terminal.t_str = el_malloc(T_str *
28612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    sizeof(*el->el_terminal.t_str));
28712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (el->el_terminal.t_str == NULL)
28812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return -1;
28912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) memset(el->el_terminal.t_str, 0, T_str *
29012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    sizeof(*el->el_terminal.t_str));
29112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_terminal.t_val = el_malloc(T_val *
29212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    sizeof(*el->el_terminal.t_val));
29312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (el->el_terminal.t_val == NULL)
29412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return -1;
29512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) memset(el->el_terminal.t_val, 0, T_val *
29612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    sizeof(*el->el_terminal.t_val));
29712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) terminal_set(el, NULL);
29812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	terminal_init_arrow(el);
29912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return 0;
30012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
30112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
30212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_end():
30312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Clean up the terminal stuff
30412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
30512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
30612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_end(EditLine *el)
30712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
30812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
30912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el_free(el->el_terminal.t_buf);
31012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_terminal.t_buf = NULL;
31112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el_free(el->el_terminal.t_cap);
31212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_terminal.t_cap = NULL;
31312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_terminal.t_loc = 0;
31412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el_free(el->el_terminal.t_str);
31512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_terminal.t_str = NULL;
31612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el_free(el->el_terminal.t_val);
31712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_terminal.t_val = NULL;
31812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el_free(el->el_terminal.t_fkey);
31912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_terminal.t_fkey = NULL;
32012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	terminal_free_display(el);
32112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
32212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
32312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
32412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_alloc():
32512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Maintain a string pool for termcap strings
32612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
32712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void
32812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_alloc(EditLine *el, const struct termcapstr *t, const char *cap)
32912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
33012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	char termbuf[TC_BUFSIZE];
33112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	size_t tlen, clen;
33212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	char **tlist = el->el_terminal.t_str;
33312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	char **tmp, **str = &tlist[t - tstr];
33412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
33512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) memset(termbuf, 0, sizeof(termbuf));
33612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (cap == NULL || *cap == '\0') {
33712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		*str = NULL;
33812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
33912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	} else
34012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		clen = strlen(cap);
34112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
34212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	tlen = *str == NULL ? 0 : strlen(*str);
34312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
34412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
34512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * New string is shorter; no need to allocate space
34612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
34712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (clen <= tlen) {
34812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (*str)
34912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			(void) strcpy(*str, cap);	/* XXX strcpy is safe */
35012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
35112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
35212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
35312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * New string is longer; see if we have enough space to append
35412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
35512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (el->el_terminal.t_loc + 3 < TC_BUFSIZE) {
35612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala						/* XXX strcpy is safe */
35712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) strcpy(*str = &el->el_terminal.t_buf[
35812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    el->el_terminal.t_loc], cap);
35912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_terminal.t_loc += clen + 1;	/* one for \0 */
36012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
36112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
36212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
36312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * Compact our buffer; no need to check compaction, cause we know it
36412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * fits...
36512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
36612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	tlen = 0;
36712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (tmp = tlist; tmp < &tlist[T_str]; tmp++)
36812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (*tmp != NULL && *tmp != '\0' && *tmp != *str) {
36912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			char *ptr;
37012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
37112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			for (ptr = *tmp; *ptr != '\0'; termbuf[tlen++] = *ptr++)
37212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				continue;
37312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			termbuf[tlen++] = '\0';
37412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
37512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	memcpy(el->el_terminal.t_buf, termbuf, TC_BUFSIZE);
37612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_terminal.t_loc = tlen;
37712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (el->el_terminal.t_loc + 3 >= TC_BUFSIZE) {
37812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) fprintf(el->el_errfile,
37912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    "Out of termcap string space.\n");
38012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
38112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
38212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					/* XXX strcpy is safe */
38312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) strcpy(*str = &el->el_terminal.t_buf[el->el_terminal.t_loc],
38412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    cap);
38512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_terminal.t_loc += (size_t)clen + 1;	/* one for \0 */
38612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return;
38712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
38812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
38912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
39012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_rebuffer_display():
39112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Rebuffer the display after the screen changed size
39212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
39312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate int
39412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_rebuffer_display(EditLine *el)
39512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
39612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	coord_t *c = &el->el_terminal.t_size;
39712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
39812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	terminal_free_display(el);
39912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
40012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	c->h = Val(T_co);
40112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	c->v = Val(T_li);
40212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
40312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (terminal_alloc_display(el) == -1)
40412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return -1;
40512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return 0;
40612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
40712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
40812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
40912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_alloc_display():
41012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Allocate a new display.
41112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
41212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate int
41312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_alloc_display(EditLine *el)
41412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
41512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int i;
41612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	Char **b;
41712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	coord_t *c = &el->el_terminal.t_size;
41812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
41912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	b =  el_malloc(sizeof(*b) * (size_t)(c->v + 1));
42012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (b == NULL)
42112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return -1;
42212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (i = 0; i < c->v; i++) {
42312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		b[i] = el_malloc(sizeof(**b) * (size_t)(c->h + 1));
42412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (b[i] == NULL) {
42512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			while (--i >= 0)
42612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				el_free(b[i]);
42712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			el_free(b);
42812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return -1;
42912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
43012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
43112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	b[c->v] = NULL;
43212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_display = b;
43312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
43412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	b = el_malloc(sizeof(*b) * (size_t)(c->v + 1));
43512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (b == NULL)
43612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return -1;
43712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (i = 0; i < c->v; i++) {
43812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		b[i] = el_malloc(sizeof(**b) * (size_t)(c->h + 1));
43912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (b[i] == NULL) {
44012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			while (--i >= 0)
44112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				el_free(b[i]);
44212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			el_free(b);
44312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return -1;
44412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
44512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
44612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	b[c->v] = NULL;
44712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_vdisplay = b;
44812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return 0;
44912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
45012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
45112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
45212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_free_display():
45312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Free the display buffers
45412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
45512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void
45612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_free_display(EditLine *el)
45712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
45812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	Char **b;
45912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	Char **bufp;
46012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
46112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	b = el->el_display;
46212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_display = NULL;
46312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (b != NULL) {
46412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		for (bufp = b; *bufp != NULL; bufp++)
46512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			el_free(*bufp);
46612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el_free(b);
46712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
46812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	b = el->el_vdisplay;
46912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_vdisplay = NULL;
47012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (b != NULL) {
47112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		for (bufp = b; *bufp != NULL; bufp++)
47212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			el_free(*bufp);
47312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el_free(b);
47412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
47512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
47612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
47712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
47812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_move_to_line():
47912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	move to line <where> (first line == 0)
48012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 	as efficiently as possible
48112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
48212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
48312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_move_to_line(EditLine *el, int where)
48412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
48512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int del;
48612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
48712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (where == el->el_cursor.v)
48812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
48912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
49012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (where > el->el_terminal.t_size.v) {
49112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef DEBUG_SCREEN
49212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) fprintf(el->el_errfile,
49312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    "terminal_move_to_line: where is ridiculous: %d\r\n",
49412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    where);
49512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* DEBUG_SCREEN */
49612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
49712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
49812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if ((del = where - el->el_cursor.v) > 0) {
49912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		while (del > 0) {
50012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (EL_HAS_AUTO_MARGINS &&
50112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			    el->el_display[el->el_cursor.v][0] != '\0') {
50212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                                size_t h = (size_t)
50312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    (el->el_terminal.t_size.h - 1);
50412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef WIDECHAR
50512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                                for (; h > 0 &&
50612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                                         el->el_display[el->el_cursor.v][h] ==
50712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                                                 MB_FILL_CHAR;
50812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                                         h--)
50912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                                                continue;
51012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif
51112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				/* move without newline */
51212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				terminal_move_to_char(el, (int)h);
51312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				terminal_overwrite(el, &el->el_display
51412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    [el->el_cursor.v][el->el_cursor.h],
51512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    (size_t)(el->el_terminal.t_size.h -
51612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    el->el_cursor.h));
51712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				/* updates Cursor */
51812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				del--;
51912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			} else {
52012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				if ((del > 1) && GoodStr(T_DO)) {
52112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					terminal_tputs(el, tgoto(Str(T_DO), del,
52212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					    del), del);
52312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					del = 0;
52412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				} else {
52512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					for (; del > 0; del--)
52612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala						terminal__putc(el, '\n');
52712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					/* because the \n will become \r\n */
52812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					el->el_cursor.h = 0;
52912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				}
53012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			}
53112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
53212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	} else {		/* del < 0 */
53312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (GoodStr(T_UP) && (-del > 1 || !GoodStr(T_up)))
53412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_tputs(el, tgoto(Str(T_UP), -del, -del), -del);
53512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		else {
53612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (GoodStr(T_up))
53712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				for (; del < 0; del++)
53812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					terminal_tputs(el, Str(T_up), 1);
53912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
54012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
54112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_cursor.v = where;/* now where is here */
54212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
54312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
54412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
54512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_move_to_char():
54612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Move to the character position specified
54712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
54812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
54912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_move_to_char(EditLine *el, int where)
55012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
55112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int del, i;
55212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
55312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialamc_again:
55412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (where == el->el_cursor.h)
55512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
55612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
55712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (where > el->el_terminal.t_size.h) {
55812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef DEBUG_SCREEN
55912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) fprintf(el->el_errfile,
56012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    "terminal_move_to_char: where is riduculous: %d\r\n",
56112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    where);
56212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* DEBUG_SCREEN */
56312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
56412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
56512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (!where) {		/* if where is first column */
56612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal__putc(el, '\r');	/* do a CR */
56712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_cursor.h = 0;
56812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
56912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
57012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	del = where - el->el_cursor.h;
57112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
57212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if ((del < -4 || del > 4) && GoodStr(T_ch))
57312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/* go there directly */
57412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal_tputs(el, tgoto(Str(T_ch), where, where), where);
57512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	else {
57612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (del > 0) {	/* moving forward */
57712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if ((del > 4) && GoodStr(T_RI))
57812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				terminal_tputs(el, tgoto(Str(T_RI), del, del),
57912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    del);
58012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			else {
58112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					/* if I can do tabs, use them */
58212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				if (EL_CAN_TAB) {
58312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					if ((el->el_cursor.h & 0370) !=
58412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					    (where & ~0x7)
58512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef WIDECHAR
58612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					    && (el->el_display[
58712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					    el->el_cursor.v][where & 0370] !=
58812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					    MB_FILL_CHAR)
58912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif
59012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					    ) {
59112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala						/* if not within tab stop */
59212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala						for (i =
59312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala						    (el->el_cursor.h & 0370);
59412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala						    i < (where & ~0x7);
59512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala						    i += 8)
59612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala							terminal__putc(el,
59712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala							    '\t');
59812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala							/* then tab over */
59912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala						el->el_cursor.h = where & ~0x7;
60012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					}
60112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				}
60212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				/*
60312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				 * it's usually cheaper to just write the
60412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				 * chars, so we do.
60512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				 */
60612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				/*
60712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				 * NOTE THAT terminal_overwrite() WILL CHANGE
60812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				 * el->el_cursor.h!!!
60912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				 */
61012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				terminal_overwrite(el, &el->el_display[
61112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    el->el_cursor.v][el->el_cursor.h],
61212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    (size_t)(where - el->el_cursor.h));
61312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
61412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			}
61512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		} else {	/* del < 0 := moving backward */
61612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if ((-del > 4) && GoodStr(T_LE))
61712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				terminal_tputs(el, tgoto(Str(T_LE), -del, -del),
61812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    -del);
61912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			else {	/* can't go directly there */
62012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				/*
62112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				 * if the "cost" is greater than the "cost"
62212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				 * from col 0
62312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				 */
62412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				if (EL_CAN_TAB ?
62512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    ((unsigned int)-del >
62612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    (((unsigned int) where >> 3) +
62712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				     (where & 07)))
62812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    : (-del > where)) {
62912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					terminal__putc(el, '\r');/* do a CR */
63012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					el->el_cursor.h = 0;
63112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					goto mc_again;	/* and try again */
63212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				}
63312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				for (i = 0; i < -del; i++)
63412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					terminal__putc(el, '\b');
63512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			}
63612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
63712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
63812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_cursor.h = where;		/* now where is here */
63912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
64012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
64112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
64212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_overwrite():
64312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Overstrike num characters
64412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Assumes MB_FILL_CHARs are present to keep the column count correct
64512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
64612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
64712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_overwrite(EditLine *el, const Char *cp, size_t n)
64812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
64912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (n == 0)
65012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
65112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
65212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (n > (size_t)el->el_terminal.t_size.h) {
65312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef DEBUG_SCREEN
65412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) fprintf(el->el_errfile,
65512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    "terminal_overwrite: n is riduculous: %d\r\n", n);
65612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* DEBUG_SCREEN */
65712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
65812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
65912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
66012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala        do {
66112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                /* terminal__putc() ignores any MB_FILL_CHARs */
66212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                terminal__putc(el, *cp++);
66312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                el->el_cursor.h++;
66412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala        } while (--n);
66512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
66612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (el->el_cursor.h >= el->el_terminal.t_size.h) {	/* wrap? */
66712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (EL_HAS_AUTO_MARGINS) {	/* yes */
66812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			el->el_cursor.h = 0;
66912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			el->el_cursor.v++;
67012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (EL_HAS_MAGIC_MARGINS) {
67112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				/* force the wrap to avoid the "magic"
67212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				 * situation */
67312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				Char c;
67412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				if ((c = el->el_display[el->el_cursor.v]
67512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    [el->el_cursor.h]) != '\0') {
67612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					terminal_overwrite(el, &c, (size_t)1);
67712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef WIDECHAR
67812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					while (el->el_display[el->el_cursor.v]
67912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					    [el->el_cursor.h] == MB_FILL_CHAR)
68012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala						el->el_cursor.h++;
68112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif
68212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				} else {
68312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					terminal__putc(el, ' ');
68412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					el->el_cursor.h = 1;
68512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				}
68612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			}
68712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		} else		/* no wrap, but cursor stays on screen */
68812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			el->el_cursor.h = el->el_terminal.t_size.h - 1;
68912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
69012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
69112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
69212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
69312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_deletechars():
69412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Delete num characters
69512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
69612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
69712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_deletechars(EditLine *el, int num)
69812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
69912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (num <= 0)
70012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
70112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
70212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (!EL_CAN_DELETE) {
70312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef DEBUG_EDIT
70412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) fprintf(el->el_errfile, "   ERROR: cannot delete   \n");
70512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* DEBUG_EDIT */
70612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
70712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
70812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (num > el->el_terminal.t_size.h) {
70912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef DEBUG_SCREEN
71012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) fprintf(el->el_errfile,
71112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    "terminal_deletechars: num is riduculous: %d\r\n", num);
71212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* DEBUG_SCREEN */
71312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
71412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
71512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (GoodStr(T_DC))	/* if I have multiple delete */
71612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if ((num > 1) || !GoodStr(T_dc)) {	/* if dc would be more
71712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala							 * expen. */
71812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_tputs(el, tgoto(Str(T_DC), num, num), num);
71912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return;
72012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
72112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (GoodStr(T_dm))	/* if I have delete mode */
72212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal_tputs(el, Str(T_dm), 1);
72312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
72412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (GoodStr(T_dc))	/* else do one at a time */
72512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		while (num--)
72612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_tputs(el, Str(T_dc), 1);
72712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
72812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (GoodStr(T_ed))	/* if I have delete mode */
72912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal_tputs(el, Str(T_ed), 1);
73012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
73112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
73212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
73312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_insertwrite():
73412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Puts terminal in insert character mode or inserts num
73512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	characters in the line
73612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *      Assumes MB_FILL_CHARs are present to keep column count correct
73712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
73812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
73912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_insertwrite(EditLine *el, Char *cp, int num)
74012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
74112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (num <= 0)
74212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
74312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (!EL_CAN_INSERT) {
74412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef DEBUG_EDIT
74512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) fprintf(el->el_errfile, "   ERROR: cannot insert   \n");
74612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* DEBUG_EDIT */
74712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
74812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
74912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (num > el->el_terminal.t_size.h) {
75012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef DEBUG_SCREEN
75112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) fprintf(el->el_errfile,
75212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    "StartInsert: num is riduculous: %d\r\n", num);
75312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* DEBUG_SCREEN */
75412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
75512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
75612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (GoodStr(T_IC))	/* if I have multiple insert */
75712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if ((num > 1) || !GoodStr(T_ic)) {
75812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				/* if ic would be more expensive */
75912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_tputs(el, tgoto(Str(T_IC), num, num), num);
76012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_overwrite(el, cp, (size_t)num);
76112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				/* this updates el_cursor.h */
76212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return;
76312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
76412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (GoodStr(T_im) && GoodStr(T_ei)) {	/* if I have insert mode */
76512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal_tputs(el, Str(T_im), 1);
76612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
76712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_cursor.h += num;
76812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		do
76912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal__putc(el, *cp++);
77012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		while (--num);
77112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
77212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (GoodStr(T_ip))	/* have to make num chars insert */
77312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_tputs(el, Str(T_ip), 1);
77412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
77512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal_tputs(el, Str(T_ei), 1);
77612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
77712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
77812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	do {
77912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (GoodStr(T_ic))	/* have to make num chars insert */
78012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_tputs(el, Str(T_ic), 1);
78112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
78212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal__putc(el, *cp++);
78312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
78412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_cursor.h++;
78512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
78612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (GoodStr(T_ip))	/* have to make num chars insert */
78712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_tputs(el, Str(T_ip), 1);
78812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					/* pad the inserted char */
78912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
79012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	} while (--num);
79112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
79212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
79312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
79412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_clear_EOL():
79512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	clear to end of line.  There are num characters to clear
79612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
79712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
79812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_clear_EOL(EditLine *el, int num)
79912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
80012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int i;
80112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
80212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (EL_CAN_CEOL && GoodStr(T_ce))
80312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal_tputs(el, Str(T_ce), 1);
80412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	else {
80512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		for (i = 0; i < num; i++)
80612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal__putc(el, ' ');
80712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_cursor.h += num;	/* have written num spaces */
80812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
80912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
81012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
81112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
81212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_clear_screen():
81312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Clear the screen
81412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
81512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
81612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_clear_screen(EditLine *el)
81712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{				/* clear the whole screen and home */
81812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
81912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (GoodStr(T_cl))
82012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/* send the clear screen code */
82112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal_tputs(el, Str(T_cl), Val(T_li));
82212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	else if (GoodStr(T_ho) && GoodStr(T_cd)) {
82312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal_tputs(el, Str(T_ho), Val(T_li));	/* home */
82412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/* clear to bottom of screen */
82512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal_tputs(el, Str(T_cd), Val(T_li));
82612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	} else {
82712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal__putc(el, '\r');
82812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal__putc(el, '\n');
82912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
83012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
83112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
83212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
83312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_beep():
83412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Beep the way the terminal wants us
83512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
83612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
83712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_beep(EditLine *el)
83812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
83912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (GoodStr(T_bl))
84012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/* what termcap says we should use */
84112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal_tputs(el, Str(T_bl), 1);
84212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	else
84312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal__putc(el, '\007');	/* an ASCII bell; ^G */
84412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
84512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
84612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
84712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
84812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_get(EditLine *el, const char **term)
84912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
85012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	*term = el->el_terminal.t_name;
85112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
85212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
85312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
85412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_set():
85512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Read in the terminal capabilities from the requested terminal
85612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
85712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected int
85812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_set(EditLine *el, const char *term)
85912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
86012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int i;
86112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	char buf[TC_BUFSIZE];
86212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	char *area;
86312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	const struct termcapstr *t;
86412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	sigset_t oset, nset;
86512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int lins, cols;
86612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
86712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) sigemptyset(&nset);
86812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) sigaddset(&nset, SIGWINCH);
86912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) sigprocmask(SIG_BLOCK, &nset, &oset);
87012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
87112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	area = buf;
87212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
87312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
87412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (term == NULL)
87512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		term = getenv("TERM");
87612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
87712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (!term || !term[0])
87812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		term = "dumb";
87912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
88012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (strcmp(term, "emacs") == 0)
88112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_flags |= EDIT_DISABLED;
88212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
88312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) memset(el->el_terminal.t_cap, 0, TC_BUFSIZE);
88412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
88512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	i = tgetent(el->el_terminal.t_cap, term);
88612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
88712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (i <= 0) {
88812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (i == -1)
88912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			(void) fprintf(el->el_errfile,
89012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			    "Cannot read termcap database;\n");
89112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		else if (i == 0)
89212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			(void) fprintf(el->el_errfile,
89312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			    "No entry for terminal type \"%s\";\n", term);
89412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) fprintf(el->el_errfile,
89512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    "using dumb terminal settings.\n");
89612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		Val(T_co) = 80;	/* do a dumb terminal */
89712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		Val(T_pt) = Val(T_km) = Val(T_li) = 0;
89812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		Val(T_xt) = Val(T_MT);
89912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		for (t = tstr; t->name != NULL; t++)
90012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_alloc(el, t, NULL);
90112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	} else {
90212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/* auto/magic margins */
90312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		Val(T_am) = tgetflag("am");
90412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		Val(T_xn) = tgetflag("xn");
90512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/* Can we tab */
90612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		Val(T_pt) = tgetflag("pt");
90712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		Val(T_xt) = tgetflag("xt");
90812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/* do we have a meta? */
90912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		Val(T_km) = tgetflag("km");
91012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		Val(T_MT) = tgetflag("MT");
91112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/* Get the size */
91212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		Val(T_co) = tgetnum("co");
91312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		Val(T_li) = tgetnum("li");
91412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		for (t = tstr; t->name != NULL; t++) {
91512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			/* XXX: some systems' tgetstr needs non const */
91612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			terminal_alloc(el, t, tgetstr(strchr(t->name, *t->name),
91712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			    &area));
91812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
91912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
92012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
92112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (Val(T_co) < 2)
92212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		Val(T_co) = 80;	/* just in case */
92312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (Val(T_li) < 1)
92412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		Val(T_li) = 24;
92512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
92612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_terminal.t_size.v = Val(T_co);
92712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_terminal.t_size.h = Val(T_li);
92812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
92912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	terminal_setflags(el);
93012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
93112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				/* get the correct window size */
93212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) terminal_get_size(el, &lins, &cols);
93312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (terminal_change_size(el, lins, cols) == -1)
93412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return -1;
93512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
93612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	terminal_bind_arrow(el);
93712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_terminal.t_name = term;
93812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return i <= 0 ? -1 : 0;
93912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
94012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
94112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
94212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_get_size():
94312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Return the new window size in lines and cols, and
94412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	true if the size was changed.
94512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
94612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected int
94712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_get_size(EditLine *el, int *lins, int *cols)
94812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
94912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
95012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	*cols = Val(T_co);
95112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	*lins = Val(T_li);
95212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
95312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef TIOCGWINSZ
95412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{
95512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		struct winsize ws;
95612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (ioctl(el->el_infd, TIOCGWINSZ, &ws) != -1) {
95712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (ws.ws_col)
95812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				*cols = ws.ws_col;
95912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (ws.ws_row)
96012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				*lins = ws.ws_row;
96112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
96212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
96312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif
96412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef TIOCGSIZE
96512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	{
96612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		struct ttysize ts;
96712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (ioctl(el->el_infd, TIOCGSIZE, &ts) != -1) {
96812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (ts.ts_cols)
96912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				*cols = ts.ts_cols;
97012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (ts.ts_lines)
97112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				*lins = ts.ts_lines;
97212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
97312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
97412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif
97512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return Val(T_co) != *cols || Val(T_li) != *lins;
97612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
97712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
97812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
97912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_change_size():
98012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Change the size of the terminal
98112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
98212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected int
98312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_change_size(EditLine *el, int lins, int cols)
98412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
98512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
98612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * Just in case
98712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
98812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	Val(T_co) = (cols < 2) ? 80 : cols;
98912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	Val(T_li) = (lins < 1) ? 24 : lins;
99012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
99112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/* re-make display buffers */
99212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (terminal_rebuffer_display(el) == -1)
99312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return -1;
99412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	re_clear_display(el);
99512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return 0;
99612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
99712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
99812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
99912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_init_arrow():
100012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Initialize the arrow key bindings from termcap
100112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
100212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void
100312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_init_arrow(EditLine *el)
100412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
100512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	funckey_t *arrow = el->el_terminal.t_fkey;
100612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
100712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_DN].name = STR("down");
100812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_DN].key = T_kd;
100912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_DN].fun.cmd = ED_NEXT_HISTORY;
101012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_DN].type = XK_CMD;
101112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
101212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_UP].name = STR("up");
101312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_UP].key = T_ku;
101412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_UP].fun.cmd = ED_PREV_HISTORY;
101512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_UP].type = XK_CMD;
101612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
101712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_LT].name = STR("left");
101812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_LT].key = T_kl;
101912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_LT].fun.cmd = ED_PREV_CHAR;
102012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_LT].type = XK_CMD;
102112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
102212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_RT].name = STR("right");
102312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_RT].key = T_kr;
102412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_RT].fun.cmd = ED_NEXT_CHAR;
102512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_RT].type = XK_CMD;
102612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
102712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_HO].name = STR("home");
102812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_HO].key = T_kh;
102912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_HO].fun.cmd = ED_MOVE_TO_BEG;
103012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_HO].type = XK_CMD;
103112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
103212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_EN].name = STR("end");
103312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_EN].key = T_at7;
103412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_EN].fun.cmd = ED_MOVE_TO_END;
103512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_EN].type = XK_CMD;
103612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
103712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_DE].name = STR("delete");
103812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_DE].key = T_kD;
103912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_DE].fun.cmd = ED_DELETE_NEXT_CHAR;
104012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	arrow[A_K_DE].type = XK_CMD;
104112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
104212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
104312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
104412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_reset_arrow():
104512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Reset arrow key bindings
104612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
104712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void
104812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_reset_arrow(EditLine *el)
104912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
105012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	funckey_t *arrow = el->el_terminal.t_fkey;
105112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	static const Char strA[] = {033, '[', 'A', '\0'};
105212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	static const Char strB[] = {033, '[', 'B', '\0'};
105312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	static const Char strC[] = {033, '[', 'C', '\0'};
105412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	static const Char strD[] = {033, '[', 'D', '\0'};
105512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	static const Char strH[] = {033, '[', 'H', '\0'};
105612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	static const Char strF[] = {033, '[', 'F', '\0'};
105712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	static const Char stOA[] = {033, 'O', 'A', '\0'};
105812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	static const Char stOB[] = {033, 'O', 'B', '\0'};
105912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	static const Char stOC[] = {033, 'O', 'C', '\0'};
106012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	static const Char stOD[] = {033, 'O', 'D', '\0'};
106112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	static const Char stOH[] = {033, 'O', 'H', '\0'};
106212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	static const Char stOF[] = {033, 'O', 'F', '\0'};
106312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
106412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, strA, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
106512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, strB, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
106612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, strC, &arrow[A_K_RT].fun, arrow[A_K_RT].type);
106712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, strD, &arrow[A_K_LT].fun, arrow[A_K_LT].type);
106812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, strH, &arrow[A_K_HO].fun, arrow[A_K_HO].type);
106912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, strF, &arrow[A_K_EN].fun, arrow[A_K_EN].type);
107012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, stOA, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
107112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, stOB, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
107212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, stOC, &arrow[A_K_RT].fun, arrow[A_K_RT].type);
107312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, stOD, &arrow[A_K_LT].fun, arrow[A_K_LT].type);
107412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, stOH, &arrow[A_K_HO].fun, arrow[A_K_HO].type);
107512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, stOF, &arrow[A_K_EN].fun, arrow[A_K_EN].type);
107612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
107712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (el->el_map.type != MAP_VI)
107812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
107912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, &strA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type);
108012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, &strB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type);
108112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, &strC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type);
108212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, &strD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type);
108312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, &strH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type);
108412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, &strF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type);
108512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, &stOA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type);
108612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, &stOB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type);
108712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, &stOC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type);
108812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, &stOD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type);
108912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, &stOH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type);
109012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	keymacro_add(el, &stOF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type);
109112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
109212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
109312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
109412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_set_arrow():
109512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Set an arrow key binding
109612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
109712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected int
109812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_set_arrow(EditLine *el, const Char *name, keymacro_value_t *fun,
109912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala    int type)
110012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
110112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	funckey_t *arrow = el->el_terminal.t_fkey;
110212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int i;
110312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
110412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (i = 0; i < A_K_NKEYS; i++)
110512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (Strcmp(name, arrow[i].name) == 0) {
110612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			arrow[i].fun = *fun;
110712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			arrow[i].type = type;
110812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return 0;
110912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
111012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return -1;
111112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
111212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
111312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
111412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_clear_arrow():
111512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Clear an arrow key binding
111612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
111712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected int
111812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_clear_arrow(EditLine *el, const Char *name)
111912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
112012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	funckey_t *arrow = el->el_terminal.t_fkey;
112112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int i;
112212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
112312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (i = 0; i < A_K_NKEYS; i++)
112412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (Strcmp(name, arrow[i].name) == 0) {
112512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			arrow[i].type = XK_NOD;
112612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return 0;
112712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
112812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return -1;
112912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
113012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
113112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
113212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_print_arrow():
113312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Print the arrow key bindings
113412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
113512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
113612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_print_arrow(EditLine *el, const Char *name)
113712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
113812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int i;
113912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	funckey_t *arrow = el->el_terminal.t_fkey;
114012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
114112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (i = 0; i < A_K_NKEYS; i++)
114212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (*name == '\0' || Strcmp(name, arrow[i].name) == 0)
114312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (arrow[i].type != XK_NOD)
114412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				keymacro_kprint(el, arrow[i].name,
114512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    &arrow[i].fun, arrow[i].type);
114612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
114712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
114812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
114912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_bind_arrow():
115012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Bind the arrow keys
115112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
115212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
115312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_bind_arrow(EditLine *el)
115412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
115512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el_action_t *map;
115612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	const el_action_t *dmap;
115712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int i, j;
115812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	char *p;
115912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	funckey_t *arrow = el->el_terminal.t_fkey;
116012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
116112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/* Check if the components needed are initialized */
116212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (el->el_terminal.t_buf == NULL || el->el_map.key == NULL)
116312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return;
116412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
116512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	map = el->el_map.type == MAP_VI ? el->el_map.alt : el->el_map.key;
116612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	dmap = el->el_map.type == MAP_VI ? el->el_map.vic : el->el_map.emacs;
116712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
116812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	terminal_reset_arrow(el);
116912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
117012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (i = 0; i < A_K_NKEYS; i++) {
117112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		Char wt_str[VISUAL_WIDTH_MAX];
117212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		Char *px;
117312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		size_t n;
117412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
117512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		p = el->el_terminal.t_str[arrow[i].key];
117612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (!p || !*p)
117712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			continue;
117812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		for (n = 0; n < VISUAL_WIDTH_MAX && p[n]; ++n)
117912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			wt_str[n] = p[n];
118012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		while (n < VISUAL_WIDTH_MAX)
118112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			wt_str[n++] = '\0';
118212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		px = wt_str;
118312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		j = (unsigned char) *p;
118412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/*
118512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * Assign the arrow keys only if:
118612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 *
118712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * 1. They are multi-character arrow keys and the user
118812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 *    has not re-assigned the leading character, or
118912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 *    has re-assigned the leading character to be
119012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 *	  ED_SEQUENCE_LEAD_IN
119112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 * 2. They are single arrow keys pointing to an
119212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 *    unassigned key.
119312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		 */
119412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (arrow[i].type == XK_NOD)
119512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			keymacro_clear(el, map, px);
119612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		else {
119712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (p[1] && (dmap[j] == map[j] ||
119812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				map[j] == ED_SEQUENCE_LEAD_IN)) {
119912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				keymacro_add(el, px, &arrow[i].fun,
120012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    arrow[i].type);
120112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				map[j] = ED_SEQUENCE_LEAD_IN;
120212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			} else if (map[j] == ED_UNASSIGNED) {
120312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				keymacro_clear(el, map, px);
120412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				if (arrow[i].type == XK_CMD)
120512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					map[j] = arrow[i].fun.cmd;
120612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				else
120712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					keymacro_add(el, px, &arrow[i].fun,
120812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					    arrow[i].type);
120912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			}
121012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
121112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
121212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
121312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
121412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_putc():
121512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Add a character
121612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
121712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate int
121812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_putc(int c)
121912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
122012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (terminal_outfile == NULL)
122112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return -1;
122212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return fputc(c, terminal_outfile);
122312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
122412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
122512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void
122612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_tputs(EditLine *el, const char *cap, int affcnt)
122712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
122812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef _REENTRANT
122912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	pthread_mutex_lock(&terminal_mutex);
123012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif
123112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	terminal_outfile = el->el_outfile;
123212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void)tputs(cap, affcnt, terminal_putc);
123312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#ifdef _REENTRANT
123412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	pthread_mutex_unlock(&terminal_mutex);
123512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif
123612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
123712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
123812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal__putc():
123912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Add a character
124012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
124112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected int
124212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal__putc(EditLine *el, Int c)
124312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
124412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	char buf[MB_LEN_MAX +1];
124512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ssize_t i;
124612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (c == (Int)MB_FILL_CHAR)
124712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return 0;
124812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	i = ct_encode_char(buf, (size_t)MB_LEN_MAX, c);
124912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (i <= 0)
125012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return (int)i;
125112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	buf[i] = '\0';
125212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return fputs(buf, el->el_outfile);
125312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
125412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
125512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal__flush():
125612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Flush output
125712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
125812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
125912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal__flush(EditLine *el)
126012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
126112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
126212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) fflush(el->el_outfile);
126312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
126412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
126512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_writec():
126612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Write the given character out, in a human readable form
126712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
126812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
126912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_writec(EditLine *el, Int c)
127012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
127112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	Char visbuf[VISUAL_WIDTH_MAX +1];
127212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ssize_t vcnt = ct_visual_char(visbuf, VISUAL_WIDTH_MAX, c);
127312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (vcnt < 0)
127412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		vcnt = 0;
127512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	visbuf[vcnt] = '\0';
127612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	terminal_overwrite(el, visbuf, (size_t)vcnt);
127712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	terminal__flush(el);
127812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
127912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
128012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
128112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_telltc():
128212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Print the current termcap characteristics
128312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
128412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected int
128512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*ARGSUSED*/
128612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_telltc(EditLine *el, int argc __attribute__((__unused__)),
128712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala    const Char **argv __attribute__((__unused__)))
128812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
128912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	const struct termcapstr *t;
129012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	char **ts;
129112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
129212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) fprintf(el->el_outfile, "\n\tYour terminal has the\n");
129312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) fprintf(el->el_outfile, "\tfollowing characteristics:\n\n");
129412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) fprintf(el->el_outfile, "\tIt has %d columns and %d lines\n",
129512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    Val(T_co), Val(T_li));
129612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) fprintf(el->el_outfile,
129712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    "\tIt has %s meta key\n", EL_HAS_META ? "a" : "no");
129812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) fprintf(el->el_outfile,
129912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    "\tIt can%suse tabs\n", EL_CAN_TAB ? " " : "not ");
130012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) fprintf(el->el_outfile, "\tIt %s automatic margins\n",
130112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    EL_HAS_AUTO_MARGINS ? "has" : "does not have");
130212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (EL_HAS_AUTO_MARGINS)
130312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) fprintf(el->el_outfile, "\tIt %s magic margins\n",
130412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    EL_HAS_MAGIC_MARGINS ? "has" : "does not have");
130512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
130612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (t = tstr, ts = el->el_terminal.t_str; t->name != NULL; t++, ts++) {
130712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		const char *ub;
130812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (*ts && **ts) {
130912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ub = ct_encode_string(ct_visual_string(
131012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			    ct_decode_string(*ts, &el->el_scratch)),
131112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			    &el->el_scratch);
131212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		} else {
131312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			ub = "(empty)";
131412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
131512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) fprintf(el->el_outfile, "\t%25s (%s) == %s\n",
131612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    t->long_name, t->name, ub);
131712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
131812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) fputc('\n', el->el_outfile);
131912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return 0;
132012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
132112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
132212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
132312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_settc():
132412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Change the current terminal characteristics
132512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
132612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected int
132712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*ARGSUSED*/
132812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_settc(EditLine *el, int argc __attribute__((__unused__)),
132912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala    const Char **argv)
133012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
133112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	const struct termcapstr *ts;
133212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	const struct termcapval *tv;
133312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	char what[8], how[8];
133412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
133512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (argv == NULL || argv[1] == NULL || argv[2] == NULL)
133612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return -1;
133712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
133812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	strncpy(what, ct_encode_string(argv[1], &el->el_scratch), sizeof(what));
133912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	what[sizeof(what) - 1] = '\0';
134012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	strncpy(how,  ct_encode_string(argv[2], &el->el_scratch), sizeof(how));
134112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	how[sizeof(how) - 1] = '\0';
134212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
134312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
134412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * Do the strings first
134512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
134612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (ts = tstr; ts->name != NULL; ts++)
134712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (strcmp(ts->name, what) == 0)
134812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
134912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
135012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (ts->name != NULL) {
135112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal_alloc(el, ts, how);
135212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal_setflags(el);
135312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return 0;
135412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
135512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
135612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * Do the numeric ones second
135712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
135812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (tv = tval; tv->name != NULL; tv++)
135912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (strcmp(tv->name, what) == 0)
136012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
136112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
136212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (tv->name != NULL)
136312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return -1;
136412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
136512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (tv == &tval[T_pt] || tv == &tval[T_km] ||
136612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    tv == &tval[T_am] || tv == &tval[T_xn]) {
136712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (strcmp(how, "yes") == 0)
136812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			el->el_terminal.t_val[tv - tval] = 1;
136912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		else if (strcmp(how, "no") == 0)
137012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			el->el_terminal.t_val[tv - tval] = 0;
137112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		else {
137212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			(void) fprintf(el->el_errfile,
137312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			    "" FSTR ": Bad value `%s'.\n", argv[0], how);
137412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return -1;
137512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
137612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal_setflags(el);
137712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (terminal_change_size(el, Val(T_li), Val(T_co)) == -1)
137812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return -1;
137912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return 0;
138012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	} else {
138112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		long i;
138212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		char *ep;
138312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
138412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		i = strtol(how, &ep, 10);
138512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (*ep != '\0') {
138612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			(void) fprintf(el->el_errfile,
138712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			    "" FSTR ": Bad value `%s'.\n", argv[0], how);
138812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return -1;
138912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
139012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_terminal.t_val[tv - tval] = (int) i;
139112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_terminal.t_size.v = Val(T_co);
139212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_terminal.t_size.h = Val(T_li);
139312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (tv == &tval[T_co] || tv == &tval[T_li])
139412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (terminal_change_size(el, Val(T_li), Val(T_co))
139512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			    == -1)
139612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				return -1;
139712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return 0;
139812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
139912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
140012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
140112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
140212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_gettc():
140312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Get the current terminal characteristics
140412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
140512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected int
140612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*ARGSUSED*/
140712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv)
140812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
140912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	const struct termcapstr *ts;
141012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	const struct termcapval *tv;
141112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	char *what;
141212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	void *how;
141312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
141412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (argv == NULL || argv[1] == NULL || argv[2] == NULL)
141512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return -1;
141612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
141712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	what = argv[1];
141812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	how = argv[2];
141912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
142012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
142112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * Do the strings first
142212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
142312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (ts = tstr; ts->name != NULL; ts++)
142412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (strcmp(ts->name, what) == 0)
142512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
142612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
142712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (ts->name != NULL) {
142812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		*(char **)how = el->el_terminal.t_str[ts - tstr];
142912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return 0;
143012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
143112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
143212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * Do the numeric ones second
143312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
143412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (tv = tval; tv->name != NULL; tv++)
143512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (strcmp(tv->name, what) == 0)
143612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
143712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
143812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (tv->name == NULL)
143912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return -1;
144012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
144112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (tv == &tval[T_pt] || tv == &tval[T_km] ||
144212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	    tv == &tval[T_am] || tv == &tval[T_xn]) {
144312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		static char yes[] = "yes";
144412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		static char no[] = "no";
144512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (el->el_terminal.t_val[tv - tval])
144612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			*(char **)how = yes;
144712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		else
144812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			*(char **)how = no;
144912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return 0;
145012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	} else {
145112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		*(int *)how = el->el_terminal.t_val[tv - tval];
145212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return 0;
145312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
145412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
145512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
145612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* terminal_echotc():
145712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Print the termcap string out with variable substitution
145812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
145912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected int
146012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*ARGSUSED*/
146112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaterminal_echotc(EditLine *el, int argc __attribute__((__unused__)),
146212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala    const Char **argv)
146312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
146412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	char *cap, *scap;
146512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	Char *ep;
146612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int arg_need, arg_cols, arg_rows;
146712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int verbose = 0, silent = 0;
146812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	char *area;
146912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	static const char fmts[] = "%s\n", fmtd[] = "%d\n";
147012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	const struct termcapstr *t;
147112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	char buf[TC_BUFSIZE];
147212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	long i;
147312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
147412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	area = buf;
147512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
147612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (argv == NULL || argv[1] == NULL)
147712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return -1;
147812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	argv++;
147912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
148012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (argv[0][0] == '-') {
148112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		switch (argv[0][1]) {
148212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case 'v':
148312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			verbose = 1;
148412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
148512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		case 's':
148612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			silent = 1;
148712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
148812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		default:
148912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			/* stderror(ERR_NAME | ERR_TCUSAGE); */
149012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
149112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
149212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		argv++;
149312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
149412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (!*argv || *argv[0] == '\0')
149512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return 0;
149612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (Strcmp(*argv, STR("tabs")) == 0) {
149712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) fprintf(el->el_outfile, fmts, EL_CAN_TAB ? "yes" : "no");
149812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return 0;
149912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	} else if (Strcmp(*argv, STR("meta")) == 0) {
150012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) fprintf(el->el_outfile, fmts, Val(T_km) ? "yes" : "no");
150112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return 0;
150212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	} else if (Strcmp(*argv, STR("xn")) == 0) {
150312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) fprintf(el->el_outfile, fmts, EL_HAS_MAGIC_MARGINS ?
150412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    "yes" : "no");
150512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return 0;
150612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	} else if (Strcmp(*argv, STR("am")) == 0) {
150712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) fprintf(el->el_outfile, fmts, EL_HAS_AUTO_MARGINS ?
150812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    "yes" : "no");
150912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return 0;
151012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	} else if (Strcmp(*argv, STR("baud")) == 0) {
151112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) fprintf(el->el_outfile, fmtd, (int)el->el_tty.t_speed);
151212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return 0;
151312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	} else if (Strcmp(*argv, STR("rows")) == 0 ||
151412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                   Strcmp(*argv, STR("lines")) == 0) {
151512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) fprintf(el->el_outfile, fmtd, Val(T_li));
151612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return 0;
151712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	} else if (Strcmp(*argv, STR("cols")) == 0) {
151812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		(void) fprintf(el->el_outfile, fmtd, Val(T_co));
151912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return 0;
152012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
152112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
152212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * Try to use our local definition first
152312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
152412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	scap = NULL;
152512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (t = tstr; t->name != NULL; t++)
152612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (strcmp(t->name,
152712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    ct_encode_string(*argv, &el->el_scratch)) == 0) {
152812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			scap = el->el_terminal.t_str[t - tstr];
152912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
153012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
153112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (t->name == NULL) {
153212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/* XXX: some systems' tgetstr needs non const */
153312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala                scap = tgetstr(ct_encode_string((Char*)*argv, &el->el_scratch), &area);
153412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
153512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (!scap || scap[0] == '\0') {
153612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (!silent)
153712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			(void) fprintf(el->el_errfile,
153812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			    "echotc: Termcap parameter `" FSTR "' not found.\n",
153912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			    *argv);
154012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return -1;
154112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
154212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	/*
154312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         * Count home many values we need for this capability.
154412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala         */
154512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (cap = scap, arg_need = 0; *cap; cap++)
154612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (*cap == '%')
154712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			switch (*++cap) {
154812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			case 'd':
154912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			case '2':
155012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			case '3':
155112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			case '.':
155212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			case '+':
155312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				arg_need++;
155412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				break;
155512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			case '%':
155612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			case '>':
155712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			case 'i':
155812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			case 'r':
155912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			case 'n':
156012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			case 'B':
156112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			case 'D':
156212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				break;
156312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			default:
156412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				/*
156512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				 * hpux has lot's of them...
156612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				 */
156712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				if (verbose)
156812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					(void) fprintf(el->el_errfile,
156912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				"echotc: Warning: unknown termcap %% `%c'.\n",
157012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala					    *cap);
157112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				/* This is bad, but I won't complain */
157212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				break;
157312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			}
157412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
157512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	switch (arg_need) {
157612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case 0:
157712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		argv++;
157812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (*argv && *argv[0]) {
157912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (!silent)
158012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				(void) fprintf(el->el_errfile,
158112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    "echotc: Warning: Extra argument `" FSTR "'.\n",
158212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    *argv);
158312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return -1;
158412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
158512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal_tputs(el, scap, 1);
158612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
158712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case 1:
158812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		argv++;
158912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (!*argv || *argv[0] == '\0') {
159012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (!silent)
159112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				(void) fprintf(el->el_errfile,
159212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    "echotc: Warning: Missing argument.\n");
159312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return -1;
159412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
159512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		arg_cols = 0;
159612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		i = Strtol(*argv, &ep, 10);
159712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (*ep != '\0' || i < 0) {
159812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (!silent)
159912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				(void) fprintf(el->el_errfile,
160012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    "echotc: Bad value `" FSTR "' for rows.\n",
160112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    *argv);
160212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return -1;
160312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
160412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		arg_rows = (int) i;
160512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		argv++;
160612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (*argv && *argv[0]) {
160712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (!silent)
160812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				(void) fprintf(el->el_errfile,
160912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    "echotc: Warning: Extra argument `" FSTR
161012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    "'.\n", *argv);
161112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return -1;
161212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
161312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal_tputs(el, tgoto(scap, arg_cols, arg_rows), 1);
161412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
161512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	default:
161612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/* This is wrong, but I will ignore it... */
161712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (verbose)
161812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			(void) fprintf(el->el_errfile,
161912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			 "echotc: Warning: Too many required arguments (%d).\n",
162012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			    arg_need);
162112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/* FALLTHROUGH */
162212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case 2:
162312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		argv++;
162412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (!*argv || *argv[0] == '\0') {
162512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (!silent)
162612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				(void) fprintf(el->el_errfile,
162712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    "echotc: Warning: Missing argument.\n");
162812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return -1;
162912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
163012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		i = Strtol(*argv, &ep, 10);
163112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (*ep != '\0' || i < 0) {
163212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (!silent)
163312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				(void) fprintf(el->el_errfile,
163412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    "echotc: Bad value `" FSTR "' for cols.\n",
163512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    *argv);
163612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return -1;
163712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
163812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		arg_cols = (int) i;
163912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		argv++;
164012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (!*argv || *argv[0] == '\0') {
164112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (!silent)
164212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				(void) fprintf(el->el_errfile,
164312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    "echotc: Warning: Missing argument.\n");
164412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return -1;
164512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
164612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		i = Strtol(*argv, &ep, 10);
164712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (*ep != '\0' || i < 0) {
164812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (!silent)
164912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				(void) fprintf(el->el_errfile,
165012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    "echotc: Bad value `" FSTR "' for rows.\n",
165112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    *argv);
165212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return -1;
165312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
165412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		arg_rows = (int) i;
165512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (*ep != '\0') {
165612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (!silent)
165712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				(void) fprintf(el->el_errfile,
165812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    "echotc: Bad value `" FSTR "'.\n", *argv);
165912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return -1;
166012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
166112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		argv++;
166212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (*argv && *argv[0]) {
166312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			if (!silent)
166412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				(void) fprintf(el->el_errfile,
166512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    "echotc: Warning: Extra argument `" FSTR
166612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				    "'.\n", *argv);
166712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			return -1;
166812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		}
166912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal_tputs(el, tgoto(scap, arg_cols, arg_rows), arg_rows);
167012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
167112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
167212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return 0;
167312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
1674