* Copyright (c) 1993, 1994
* The Regents of the University of California. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
static char sccsid
[] = "@(#)svi_term.c 9.1 (Berkeley) 11/9/94";
* THIS REQUIRES THAT ALL SCREENS SHARE A TERMINAL TYPE.
char *ts
; /* Key's termcap string. */
char *output
; /* Corresponding vi command. */
u_char value
; /* Special value (for lookup). */
static TKLIST
const c_tklist
[] = { /* Command mappings. */
{"kil1", "O", "insert line"},
{"kdch1", "x", "delete character"},
{"kcud1", "j", "cursor down"},
{"kel", "D", "delete to eol"},
{"kind", "\004", "scroll down"},
{"kll", "$", "go to eol"},
{"khome", "^", "go to sol"},
{"kich1", "i", "insert at cursor"},
{"kdl1", "dd", "delete line"},
{"kcub1", "h", "cursor left"},
{"knp", "\006", "page down"},
{"kpp", "\002", "page up"},
{"kri", "\025", "scroll up"},
{"ked", "dG", "delete to end of screen"},
{"kcuf1", "l", "cursor right"},
{"kcuu1", "k", "cursor up"},
{"kA", "O", "insert line"},
{"kD", "x", "delete character"},
{"kd", "j", "cursor down"},
{"kE", "D", "delete to eol"},
{"kF", "\004", "scroll down"},
{"kH", "$", "go to eol"},
{"kh", "^", "go to sol"},
{"kI", "i", "insert at cursor"},
{"kL", "dd", "delete line"},
{"kl", "h", "cursor left"},
{"kN", "\006", "page down"},
{"kP", "\002", "page up"},
{"kR", "\025", "scroll up"},
{"kS", "dG", "delete to end of screen"},
{"kr", "l", "cursor right"},
{"ku", "k", "cursor up"},
static TKLIST
const m1_tklist
[] = { /* Input mappings (lookup). */
static TKLIST
const m2_tklist
[] = { /* Input mappings (set or delete). */
{"kcud1", "\033ja", "cursor down"},
{"kcub1", "\033ha", "cursor left"},
{"kcuu1", "\033ka", "cursor up"},
{"kcuf1", "\033la", "cursor right"},
{"kd", "\033ja", "cursor down"},
{"kl", "\033ha", "cursor left"},
{"ku", "\033ka", "cursor up"},
{"kr", "\033la", "cursor right"},
* Initialize the special keys defined by the termcap/terminfo entry.
char *sbp
, *s
, *t
, sbuf
[1024];
for (tkp
= c_tklist
; tkp
->name
!= NULL
; ++tkp
) {
if ((t
= tigetstr(tkp
->ts
)) == NULL
|| t
== (char *)-1)
if ((t
= tgetstr(tkp
->ts
, &sbp
)) == NULL
)
if (seq_set(sp
, tkp
->name
, strlen(tkp
->name
), t
, strlen(t
),
tkp
->output
, strlen(tkp
->output
), SEQ_COMMAND
,
SEQ_NOOVERWRITE
| SEQ_SCREEN
))
/* Input mappings needing to be looked up. */
for (tkp
= m1_tklist
; tkp
->name
!= NULL
; ++tkp
) {
if ((t
= tigetstr(tkp
->ts
)) == NULL
|| t
== (char *)-1)
if ((t
= tgetstr(tkp
->ts
, &sbp
)) == NULL
)
for (kp
= keylist
;; ++kp
)
if (kp
->value
== tkp
->value
)
if (seq_set(sp
, tkp
->name
, strlen(tkp
->name
), t
, strlen(t
),
&kp
->ch
, 1, SEQ_INPUT
, SEQ_NOOVERWRITE
| SEQ_SCREEN
))
/* Input mappings that are already set or are text deletions. */
for (tkp
= m2_tklist
; tkp
->name
!= NULL
; ++tkp
) {
if ((t
= tigetstr(tkp
->ts
)) == NULL
|| t
== (char *)-1)
if ((t
= tgetstr(tkp
->ts
, &sbp
)) == NULL
)
* Some terminals' <cursor_left> keys send single <backspace>
* characters. This is okay in command mapping, but not okay
* in input mapping. That combination is the only one we'll
* ever see, hopefully, so kluge it here for now.
if (tkp
->output
== NULL
) {
if (seq_set(sp
, tkp
->name
, strlen(tkp
->name
),
SEQ_INPUT
, SEQ_NOOVERWRITE
| SEQ_SCREEN
))
if (seq_set(sp
, tkp
->name
, strlen(tkp
->name
),
t
, strlen(t
), tkp
->output
, strlen(tkp
->output
),
SEQ_INPUT
, SEQ_NOOVERWRITE
| SEQ_SCREEN
))
/* Rework any function key mappings. */
for (qp
= sp
->gp
->seqq
.lh_first
; qp
!= NULL
; qp
= qp
->q
.le_next
) {
if (!F_ISSET(qp
, SEQ_FUNCMAP
))
(void)svi_fmap(sp
, qp
->stype
,
qp
->input
, qp
->ilen
, qp
->output
, qp
->olen
);
/* Set up the visual bell information. */
if (tgetstr("vb", &t
) != NULL
&& (len
= t
- sbuf
) != 0) {
MALLOC_RET(sp
, s
, char *, len
);
* End the special keys defined by the termcap/terminfo entry.
/* Delete screen specific mappings. */
for (qp
= sp
->gp
->seqq
.lh_first
; qp
!= NULL
; qp
= nqp
) {
if (!F_ISSET(qp
, SEQ_SCREEN
))
svi_fmap(sp
, stype
, from
, flen
, to
, tlen
)
char *p
, *t
, keyname
[64];
/* If the terminal isn't initialized, there's nothing to do. */
if (!F_ISSET(SVP(sp
), SVI_CURSES_INIT
))
(void)snprintf(keyname
, sizeof(keyname
), "kf%d", atoi(from
+ 1));
if ((t
= tigetstr(keyname
)) == NULL
|| t
== (char *)-1)
* Historically, the 4BSD termcap code didn't support functions keys
* greater than 9. This was silently enforced -- asking for key k12
* returned the value for k1. We try and get around this by using
* the tables specified in the terminfo(TI_ENV) man page from the 3rd
* Edition SVID. This assumes that the implementors of any System V
* compatibility code or an extended termcap used those codes.
{ int n
; char *sbp
, sbuf
[1024];
static const char codes
[] = {
/* 0-10 */ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ';',
/* 11-19 */ '1', '2', '3', '4', '5', '6', '7', '8', '9',
/* 20-63 */ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
if ((n
= atoi(from
+ 1)) > 63) {
p
= msg_print(sp
, from
, &nf
);
"228|Termcap has no code for the %s function key", p
);
(void)snprintf(keyname
, sizeof(keyname
),
"%c%c", n
<= 10 ? 'k' : 'F', codes
[n
]);
t
= tgetstr(keyname
, &sbp
);
p
= msg_print(sp
, from
, &nf
);
msgq(sp
, M_ERR
, "229|This terminal has no %s key", p
);
sizeof(keyname
), "function key %d", atoi(from
+ 1));
return (seq_set(sp
, keyname
, nlen
, t
, strlen(t
),
to
, tlen
, stype
, SEQ_NOOVERWRITE
| SEQ_SCREEN
| SEQ_USERDEF
));