1*0a6a1f1dSLionel Sambuc /* $NetBSD: cl_term.c,v 1.4 2014/01/26 21:43:45 christos Exp $ */
284d9c625SLionel Sambuc /*-
384d9c625SLionel Sambuc * Copyright (c) 1993, 1994
484d9c625SLionel Sambuc * The Regents of the University of California. All rights reserved.
584d9c625SLionel Sambuc * Copyright (c) 1993, 1994, 1995, 1996
684d9c625SLionel Sambuc * Keith Bostic. All rights reserved.
784d9c625SLionel Sambuc *
884d9c625SLionel Sambuc * See the LICENSE file for redistribution information.
984d9c625SLionel Sambuc */
1084d9c625SLionel Sambuc
1184d9c625SLionel Sambuc #include "config.h"
1284d9c625SLionel Sambuc
13*0a6a1f1dSLionel Sambuc #include <sys/cdefs.h>
14*0a6a1f1dSLionel Sambuc #if 0
1584d9c625SLionel Sambuc #ifndef lint
1684d9c625SLionel Sambuc static const char sccsid[] = "Id: cl_term.c,v 10.31 2001/07/08 13:06:56 skimo Exp (Berkeley) Date: 2001/07/08 13:06:56 ";
1784d9c625SLionel Sambuc #endif /* not lint */
18*0a6a1f1dSLionel Sambuc #else
19*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: cl_term.c,v 1.4 2014/01/26 21:43:45 christos Exp $");
20*0a6a1f1dSLionel Sambuc #endif
2184d9c625SLionel Sambuc
2284d9c625SLionel Sambuc #include <sys/types.h>
2384d9c625SLionel Sambuc #include <sys/ioctl.h>
2484d9c625SLionel Sambuc #include <sys/queue.h>
2584d9c625SLionel Sambuc #include <sys/stat.h>
2684d9c625SLionel Sambuc
2784d9c625SLionel Sambuc #include <bitstring.h>
2884d9c625SLionel Sambuc #include <errno.h>
2984d9c625SLionel Sambuc #include <limits.h>
3084d9c625SLionel Sambuc #include <signal.h>
3184d9c625SLionel Sambuc #include <stdio.h>
3284d9c625SLionel Sambuc #include <stdlib.h>
3384d9c625SLionel Sambuc #include <string.h>
3484d9c625SLionel Sambuc #include <termios.h>
3584d9c625SLionel Sambuc #include <unistd.h>
3684d9c625SLionel Sambuc
3784d9c625SLionel Sambuc #include "../common/common.h"
3884d9c625SLionel Sambuc #include "cl.h"
3984d9c625SLionel Sambuc
4084d9c625SLionel Sambuc static int cl_pfmap __P((SCR *, seq_t, CHAR_T *, size_t, CHAR_T *, size_t));
4184d9c625SLionel Sambuc
4284d9c625SLionel Sambuc /*
4384d9c625SLionel Sambuc * XXX
4484d9c625SLionel Sambuc * THIS REQUIRES THAT ALL SCREENS SHARE A TERMINAL TYPE.
4584d9c625SLionel Sambuc */
4684d9c625SLionel Sambuc typedef struct _tklist {
4784d9c625SLionel Sambuc const char *ts; /* Key's termcap string. */
4884d9c625SLionel Sambuc const char *output; /* Corresponding vi command. */
4984d9c625SLionel Sambuc const char *name; /* Name. */
5084d9c625SLionel Sambuc u_char value; /* Special value (for lookup). */
5184d9c625SLionel Sambuc } TKLIST;
5284d9c625SLionel Sambuc
5384d9c625SLionel Sambuc #define TKINIT(a, b, c) { a, b, c, 0 }
5484d9c625SLionel Sambuc
5584d9c625SLionel Sambuc static TKLIST const c_tklist[] = { /* Command mappings. */
5684d9c625SLionel Sambuc TKINIT("kil1", "O", "insert line"),
5784d9c625SLionel Sambuc TKINIT("kdch1", "x", "delete character"),
5884d9c625SLionel Sambuc TKINIT("kcud1", "j", "cursor down"),
5984d9c625SLionel Sambuc TKINIT("kel", "D", "delete to eol"),
6084d9c625SLionel Sambuc TKINIT("kind", "\004", "scroll down"), /* ^D */
6184d9c625SLionel Sambuc TKINIT("kll", "$", "go to eol"),
6284d9c625SLionel Sambuc TKINIT("kend", "$", "go to eol"),
6384d9c625SLionel Sambuc TKINIT("khome", "^", "go to sol"),
6484d9c625SLionel Sambuc TKINIT("kich1", "i", "insert at cursor"),
6584d9c625SLionel Sambuc TKINIT("kdl1", "dd", "delete line"),
6684d9c625SLionel Sambuc TKINIT("kcub1", "h", "cursor left"),
6784d9c625SLionel Sambuc TKINIT("knp", "\006", "page down"), /* ^F */
6884d9c625SLionel Sambuc TKINIT("kpp", "\002", "page up"), /* ^B */
6984d9c625SLionel Sambuc TKINIT("kri", "\025", "scroll up"), /* ^U */
7084d9c625SLionel Sambuc TKINIT("ked", "dG", "delete to end of screen"),
7184d9c625SLionel Sambuc TKINIT("kcuf1", "l", "cursor right"),
7284d9c625SLionel Sambuc TKINIT("kcuu1", "k", "cursor up"),
7384d9c625SLionel Sambuc TKINIT(NULL, NULL, NULL),
7484d9c625SLionel Sambuc };
7584d9c625SLionel Sambuc static TKLIST const m1_tklist[] = { /* Input mappings (lookup). */
7684d9c625SLionel Sambuc TKINIT(NULL, NULL, NULL),
7784d9c625SLionel Sambuc };
7884d9c625SLionel Sambuc static TKLIST const m2_tklist[] = { /* Input mappings (set or delete). */
7984d9c625SLionel Sambuc TKINIT("kcud1", "\033ja", "cursor down"), /* ^[ja */
8084d9c625SLionel Sambuc TKINIT("kcub1", "\033ha", "cursor left"), /* ^[ha */
8184d9c625SLionel Sambuc TKINIT("kcuu1", "\033ka", "cursor up"), /* ^[ka */
8284d9c625SLionel Sambuc TKINIT("kcuf1", "\033la", "cursor right"), /* ^[la */
8384d9c625SLionel Sambuc TKINIT(NULL, NULL, NULL),
8484d9c625SLionel Sambuc };
8584d9c625SLionel Sambuc
8684d9c625SLionel Sambuc /*
8784d9c625SLionel Sambuc * cl_term_init --
8884d9c625SLionel Sambuc * Initialize the special keys defined by the termcap/terminfo entry.
8984d9c625SLionel Sambuc *
9084d9c625SLionel Sambuc * PUBLIC: int cl_term_init __P((SCR *));
9184d9c625SLionel Sambuc */
9284d9c625SLionel Sambuc int
cl_term_init(SCR * sp)9384d9c625SLionel Sambuc cl_term_init(SCR *sp)
9484d9c625SLionel Sambuc {
9584d9c625SLionel Sambuc KEYLIST *kp;
9684d9c625SLionel Sambuc SEQ *qp;
9784d9c625SLionel Sambuc TKLIST const *tkp;
9884d9c625SLionel Sambuc char *t;
9984d9c625SLionel Sambuc CHAR_T name[60];
10084d9c625SLionel Sambuc CHAR_T output[5];
10184d9c625SLionel Sambuc CHAR_T ts[20];
10284d9c625SLionel Sambuc const CHAR_T *wp;
10384d9c625SLionel Sambuc size_t wlen;
10484d9c625SLionel Sambuc
10584d9c625SLionel Sambuc /* Command mappings. */
10684d9c625SLionel Sambuc for (tkp = c_tklist; tkp->name != NULL; ++tkp) {
10784d9c625SLionel Sambuc if ((t = tigetstr(tkp->ts)) == NULL || t == (char *)-1)
10884d9c625SLionel Sambuc continue;
10984d9c625SLionel Sambuc CHAR2INT(sp, tkp->name, strlen(tkp->name), wp, wlen);
11084d9c625SLionel Sambuc MEMCPYW(name, wp, wlen);
11184d9c625SLionel Sambuc CHAR2INT(sp, t, strlen(t), wp, wlen);
11284d9c625SLionel Sambuc MEMCPYW(ts, wp, wlen);
11384d9c625SLionel Sambuc CHAR2INT(sp, tkp->output, strlen(tkp->output), wp, wlen);
11484d9c625SLionel Sambuc MEMCPYW(output, wp, wlen);
11584d9c625SLionel Sambuc if (seq_set(sp, name, strlen(tkp->name), ts, strlen(t),
11684d9c625SLionel Sambuc output, strlen(tkp->output), SEQ_COMMAND,
11784d9c625SLionel Sambuc SEQ_NOOVERWRITE | SEQ_SCREEN))
11884d9c625SLionel Sambuc return (1);
11984d9c625SLionel Sambuc }
12084d9c625SLionel Sambuc
12184d9c625SLionel Sambuc /* Input mappings needing to be looked up. */
12284d9c625SLionel Sambuc for (tkp = m1_tklist; tkp->name != NULL; ++tkp) {
12384d9c625SLionel Sambuc if ((t = tigetstr(tkp->ts)) == NULL || t == (char *)-1)
12484d9c625SLionel Sambuc continue;
12584d9c625SLionel Sambuc for (kp = keylist;; ++kp)
12684d9c625SLionel Sambuc if (kp->value == tkp->value)
12784d9c625SLionel Sambuc break;
12884d9c625SLionel Sambuc if (kp == NULL)
12984d9c625SLionel Sambuc continue;
13084d9c625SLionel Sambuc CHAR2INT(sp, tkp->name, strlen(tkp->name), wp, wlen);
13184d9c625SLionel Sambuc MEMCPYW(name, wp, wlen);
13284d9c625SLionel Sambuc CHAR2INT(sp, t, strlen(t), wp, wlen);
13384d9c625SLionel Sambuc MEMCPYW(ts, wp, wlen);
13484d9c625SLionel Sambuc output[0] = (UCHAR_T)kp->ch;
13584d9c625SLionel Sambuc if (seq_set(sp, name, strlen(tkp->name), ts, strlen(t),
13684d9c625SLionel Sambuc output, 1, SEQ_INPUT, SEQ_NOOVERWRITE | SEQ_SCREEN))
13784d9c625SLionel Sambuc return (1);
13884d9c625SLionel Sambuc }
13984d9c625SLionel Sambuc
14084d9c625SLionel Sambuc /* Input mappings that are already set or are text deletions. */
14184d9c625SLionel Sambuc for (tkp = m2_tklist; tkp->name != NULL; ++tkp) {
14284d9c625SLionel Sambuc if ((t = tigetstr(tkp->ts)) == NULL || t == (char *)-1)
14384d9c625SLionel Sambuc continue;
14484d9c625SLionel Sambuc /*
14584d9c625SLionel Sambuc * !!!
14684d9c625SLionel Sambuc * Some terminals' <cursor_left> keys send single <backspace>
14784d9c625SLionel Sambuc * characters. This is okay in command mapping, but not okay
14884d9c625SLionel Sambuc * in input mapping. That combination is the only one we'll
14984d9c625SLionel Sambuc * ever see, hopefully, so kluge it here for now.
15084d9c625SLionel Sambuc */
15184d9c625SLionel Sambuc if (!strcmp(t, "\b"))
15284d9c625SLionel Sambuc continue;
15384d9c625SLionel Sambuc if (tkp->output == NULL) {
15484d9c625SLionel Sambuc CHAR2INT(sp, tkp->name, strlen(tkp->name), wp, wlen);
15584d9c625SLionel Sambuc MEMCPYW(name, wp, wlen);
15684d9c625SLionel Sambuc CHAR2INT(sp, t, strlen(t), wp, wlen);
15784d9c625SLionel Sambuc MEMCPYW(ts, wp, wlen);
15884d9c625SLionel Sambuc if (seq_set(sp, name, strlen(tkp->name),
15984d9c625SLionel Sambuc ts, strlen(t), NULL, 0,
16084d9c625SLionel Sambuc SEQ_INPUT, SEQ_NOOVERWRITE | SEQ_SCREEN))
16184d9c625SLionel Sambuc return (1);
16284d9c625SLionel Sambuc } else {
16384d9c625SLionel Sambuc CHAR2INT(sp, tkp->name, strlen(tkp->name), wp, wlen);
16484d9c625SLionel Sambuc MEMCPYW(name, wp, wlen);
16584d9c625SLionel Sambuc CHAR2INT(sp, t, strlen(t), wp, wlen);
16684d9c625SLionel Sambuc MEMCPYW(ts, wp, wlen);
16784d9c625SLionel Sambuc CHAR2INT(sp, tkp->output, strlen(tkp->output), wp, wlen);
16884d9c625SLionel Sambuc MEMCPYW(output, wp, wlen);
16984d9c625SLionel Sambuc if (seq_set(sp, name, strlen(tkp->name),
17084d9c625SLionel Sambuc ts, strlen(t), output, strlen(tkp->output),
17184d9c625SLionel Sambuc SEQ_INPUT, SEQ_NOOVERWRITE | SEQ_SCREEN))
17284d9c625SLionel Sambuc return (1);
17384d9c625SLionel Sambuc }
17484d9c625SLionel Sambuc }
17584d9c625SLionel Sambuc
17684d9c625SLionel Sambuc /*
17784d9c625SLionel Sambuc * Rework any function key mappings that were set before the
17884d9c625SLionel Sambuc * screen was initialized.
17984d9c625SLionel Sambuc */
18084d9c625SLionel Sambuc LIST_FOREACH(qp, &sp->gp->seqq, q)
18184d9c625SLionel Sambuc if (F_ISSET(qp, SEQ_FUNCMAP))
18284d9c625SLionel Sambuc (void)cl_pfmap(sp, qp->stype,
18384d9c625SLionel Sambuc qp->input, qp->ilen, qp->output, qp->olen);
18484d9c625SLionel Sambuc return (0);
18584d9c625SLionel Sambuc }
18684d9c625SLionel Sambuc
18784d9c625SLionel Sambuc /*
18884d9c625SLionel Sambuc * cl_term_end --
18984d9c625SLionel Sambuc * End the special keys defined by the termcap/terminfo entry.
19084d9c625SLionel Sambuc *
19184d9c625SLionel Sambuc * PUBLIC: int cl_term_end __P((GS *));
19284d9c625SLionel Sambuc */
19384d9c625SLionel Sambuc int
cl_term_end(GS * gp)19484d9c625SLionel Sambuc cl_term_end(GS *gp)
19584d9c625SLionel Sambuc {
19684d9c625SLionel Sambuc SEQ *qp, *nqp;
19784d9c625SLionel Sambuc
19884d9c625SLionel Sambuc /* Delete screen specific mappings. */
19984d9c625SLionel Sambuc LIST_FOREACH_SAFE(qp, &gp->seqq, q, nqp)
20084d9c625SLionel Sambuc if (F_ISSET(qp, SEQ_SCREEN))
20184d9c625SLionel Sambuc (void)seq_mdel(qp);
20284d9c625SLionel Sambuc return (0);
20384d9c625SLionel Sambuc }
20484d9c625SLionel Sambuc
20584d9c625SLionel Sambuc /*
20684d9c625SLionel Sambuc * cl_fmap --
20784d9c625SLionel Sambuc * Map a function key.
20884d9c625SLionel Sambuc *
20984d9c625SLionel Sambuc * PUBLIC: int cl_fmap __P((SCR *, seq_t, CHAR_T *, size_t, CHAR_T *, size_t));
21084d9c625SLionel Sambuc */
21184d9c625SLionel Sambuc int
cl_fmap(SCR * sp,seq_t stype,CHAR_T * from,size_t flen,CHAR_T * to,size_t tlen)21284d9c625SLionel Sambuc cl_fmap(SCR *sp, seq_t stype, CHAR_T *from, size_t flen, CHAR_T *to, size_t tlen)
21384d9c625SLionel Sambuc {
21484d9c625SLionel Sambuc /* Ignore until the screen is running, do the real work then. */
21584d9c625SLionel Sambuc if (F_ISSET(sp, SC_VI) && !F_ISSET(sp, SC_SCR_VI))
21684d9c625SLionel Sambuc return (0);
21784d9c625SLionel Sambuc if (F_ISSET(sp, SC_EX) && !F_ISSET(sp, SC_SCR_EX))
21884d9c625SLionel Sambuc return (0);
21984d9c625SLionel Sambuc
22084d9c625SLionel Sambuc return (cl_pfmap(sp, stype, from, flen, to, tlen));
22184d9c625SLionel Sambuc }
22284d9c625SLionel Sambuc
22384d9c625SLionel Sambuc /*
22484d9c625SLionel Sambuc * cl_pfmap --
22584d9c625SLionel Sambuc * Map a function key (private version).
22684d9c625SLionel Sambuc */
22784d9c625SLionel Sambuc static int
cl_pfmap(SCR * sp,seq_t stype,CHAR_T * from,size_t flen,CHAR_T * to,size_t tlen)22884d9c625SLionel Sambuc cl_pfmap(SCR *sp, seq_t stype, CHAR_T *from, size_t flen, CHAR_T *to, size_t tlen)
22984d9c625SLionel Sambuc {
23084d9c625SLionel Sambuc size_t nlen;
23184d9c625SLionel Sambuc char *p;
23284d9c625SLionel Sambuc char name[64];
23384d9c625SLionel Sambuc CHAR_T mykeyname[64];
23484d9c625SLionel Sambuc CHAR_T ts[20];
23584d9c625SLionel Sambuc const CHAR_T *wp;
23684d9c625SLionel Sambuc size_t wlen;
23784d9c625SLionel Sambuc
23884d9c625SLionel Sambuc (void)snprintf(name, sizeof(name), "kf%d",
23984d9c625SLionel Sambuc (int)STRTOL(from+1,NULL,10));
24084d9c625SLionel Sambuc if ((p = tigetstr(name)) == NULL ||
24184d9c625SLionel Sambuc p == (char *)-1 || strlen(p) == 0)
24284d9c625SLionel Sambuc p = NULL;
24384d9c625SLionel Sambuc if (p == NULL) {
24484d9c625SLionel Sambuc msgq_wstr(sp, M_ERR, from, "233|This terminal has no %s key");
24584d9c625SLionel Sambuc return (1);
24684d9c625SLionel Sambuc }
24784d9c625SLionel Sambuc
24884d9c625SLionel Sambuc nlen = SPRINTF(mykeyname,
24984d9c625SLionel Sambuc SIZE(mykeyname), L("function key %d"),
25084d9c625SLionel Sambuc (int)STRTOL(from+1,NULL,10));
25184d9c625SLionel Sambuc CHAR2INT(sp, p, strlen(p), wp, wlen);
25284d9c625SLionel Sambuc MEMCPYW(ts, wp, wlen);
25384d9c625SLionel Sambuc return (seq_set(sp, mykeyname, nlen,
25484d9c625SLionel Sambuc ts, strlen(p), to, tlen, stype, SEQ_NOOVERWRITE | SEQ_SCREEN));
25584d9c625SLionel Sambuc }
25684d9c625SLionel Sambuc
25784d9c625SLionel Sambuc /*
25884d9c625SLionel Sambuc * cl_optchange --
25984d9c625SLionel Sambuc * Curses screen specific "option changed" routine.
26084d9c625SLionel Sambuc *
26184d9c625SLionel Sambuc * PUBLIC: int cl_optchange __P((SCR *, int, const char *, u_long *));
26284d9c625SLionel Sambuc */
26384d9c625SLionel Sambuc int
cl_optchange(SCR * sp,int opt,const char * str,u_long * valp)26484d9c625SLionel Sambuc cl_optchange(SCR *sp, int opt, const char *str, u_long *valp)
26584d9c625SLionel Sambuc {
26684d9c625SLionel Sambuc CL_PRIVATE *clp;
26784d9c625SLionel Sambuc
26884d9c625SLionel Sambuc clp = CLP(sp);
26984d9c625SLionel Sambuc
27084d9c625SLionel Sambuc switch (opt) {
27184d9c625SLionel Sambuc case O_COLUMNS:
27284d9c625SLionel Sambuc case O_LINES:
27384d9c625SLionel Sambuc case O_TERM:
27484d9c625SLionel Sambuc /*
27584d9c625SLionel Sambuc * Changing the columns, lines or terminal require that
27684d9c625SLionel Sambuc * we restart the screen.
27784d9c625SLionel Sambuc */
27884d9c625SLionel Sambuc F_SET(sp->gp, G_SRESTART);
27984d9c625SLionel Sambuc F_CLR(sp, SC_SCR_EX | SC_SCR_VI);
28084d9c625SLionel Sambuc break;
28184d9c625SLionel Sambuc case O_MESG:
28284d9c625SLionel Sambuc (void)cl_omesg(sp, clp, *valp);
28384d9c625SLionel Sambuc break;
28484d9c625SLionel Sambuc case O_WINDOWNAME:
28584d9c625SLionel Sambuc if (*valp) {
28684d9c625SLionel Sambuc F_SET(clp, CL_RENAME_OK);
28784d9c625SLionel Sambuc
28884d9c625SLionel Sambuc /*
28984d9c625SLionel Sambuc * If the screen is live, i.e. we're not reading the
29084d9c625SLionel Sambuc * .exrc file, update the window.
29184d9c625SLionel Sambuc */
29284d9c625SLionel Sambuc if (sp->frp != NULL && sp->frp->name != NULL)
29384d9c625SLionel Sambuc (void)cl_rename(sp, sp->frp->name, 1);
29484d9c625SLionel Sambuc } else {
29584d9c625SLionel Sambuc F_CLR(clp, CL_RENAME_OK);
29684d9c625SLionel Sambuc
29784d9c625SLionel Sambuc (void)cl_rename(sp, NULL, 0);
29884d9c625SLionel Sambuc }
29984d9c625SLionel Sambuc break;
30084d9c625SLionel Sambuc }
30184d9c625SLionel Sambuc return (0);
30284d9c625SLionel Sambuc }
30384d9c625SLionel Sambuc
30484d9c625SLionel Sambuc /*
30584d9c625SLionel Sambuc * cl_omesg --
30684d9c625SLionel Sambuc * Turn the tty write permission on or off.
30784d9c625SLionel Sambuc *
30884d9c625SLionel Sambuc * PUBLIC: int cl_omesg __P((SCR *, CL_PRIVATE *, int));
30984d9c625SLionel Sambuc */
31084d9c625SLionel Sambuc int
cl_omesg(SCR * sp,CL_PRIVATE * clp,int on)31184d9c625SLionel Sambuc cl_omesg(SCR *sp, CL_PRIVATE *clp, int on)
31284d9c625SLionel Sambuc {
31384d9c625SLionel Sambuc struct stat sb;
31484d9c625SLionel Sambuc char *tty;
31584d9c625SLionel Sambuc
31684d9c625SLionel Sambuc /* Find the tty, get the current permissions. */
31784d9c625SLionel Sambuc if ((tty = ttyname(STDERR_FILENO)) == NULL) {
31884d9c625SLionel Sambuc if (sp != NULL)
31984d9c625SLionel Sambuc msgq(sp, M_SYSERR, "stderr");
32084d9c625SLionel Sambuc return (1);
32184d9c625SLionel Sambuc }
32284d9c625SLionel Sambuc if (stat(tty, &sb) < 0) {
32384d9c625SLionel Sambuc if (sp != NULL)
32484d9c625SLionel Sambuc msgq(sp, M_SYSERR, "%s", tty);
32584d9c625SLionel Sambuc return (1);
32684d9c625SLionel Sambuc }
32784d9c625SLionel Sambuc
32884d9c625SLionel Sambuc /* Save the original status if it's unknown. */
32984d9c625SLionel Sambuc if (clp->tgw == TGW_UNKNOWN)
33084d9c625SLionel Sambuc clp->tgw = sb.st_mode & S_IWGRP ? TGW_SET : TGW_UNSET;
33184d9c625SLionel Sambuc
33284d9c625SLionel Sambuc /* Toggle the permissions. */
33384d9c625SLionel Sambuc if (on) {
33484d9c625SLionel Sambuc if (chmod(tty, sb.st_mode | S_IWGRP) < 0) {
33584d9c625SLionel Sambuc if (sp != NULL)
33684d9c625SLionel Sambuc msgq(sp, M_SYSERR,
33784d9c625SLionel Sambuc "046|messages not turned on: %s", tty);
33884d9c625SLionel Sambuc return (1);
33984d9c625SLionel Sambuc }
34084d9c625SLionel Sambuc } else
34184d9c625SLionel Sambuc if (chmod(tty, sb.st_mode & ~S_IWGRP) < 0) {
34284d9c625SLionel Sambuc if (sp != NULL)
34384d9c625SLionel Sambuc msgq(sp, M_SYSERR,
34484d9c625SLionel Sambuc "045|messages not turned off: %s", tty);
34584d9c625SLionel Sambuc return (1);
34684d9c625SLionel Sambuc }
34784d9c625SLionel Sambuc return (0);
34884d9c625SLionel Sambuc }
34984d9c625SLionel Sambuc
35084d9c625SLionel Sambuc /*
35184d9c625SLionel Sambuc * cl_ssize --
35284d9c625SLionel Sambuc * Return the terminal size.
35384d9c625SLionel Sambuc *
35484d9c625SLionel Sambuc * PUBLIC: int cl_ssize __P((SCR *, int, size_t *, size_t *, int *));
35584d9c625SLionel Sambuc */
35684d9c625SLionel Sambuc int
cl_ssize(SCR * sp,int sigwinch,size_t * rowp,size_t * colp,int * changedp)35784d9c625SLionel Sambuc cl_ssize(SCR *sp, int sigwinch, size_t *rowp, size_t *colp, int *changedp)
35884d9c625SLionel Sambuc {
35984d9c625SLionel Sambuc #ifdef TIOCGWINSZ
36084d9c625SLionel Sambuc struct winsize win;
36184d9c625SLionel Sambuc #endif
36284d9c625SLionel Sambuc size_t col, row;
36384d9c625SLionel Sambuc int rval;
36484d9c625SLionel Sambuc char *p;
36584d9c625SLionel Sambuc
36684d9c625SLionel Sambuc /* Assume it's changed. */
36784d9c625SLionel Sambuc if (changedp != NULL)
36884d9c625SLionel Sambuc *changedp = 1;
36984d9c625SLionel Sambuc
37084d9c625SLionel Sambuc /*
37184d9c625SLionel Sambuc * !!!
37284d9c625SLionel Sambuc * sp may be NULL.
37384d9c625SLionel Sambuc *
37484d9c625SLionel Sambuc * Get the screen rows and columns. If the values are wrong, it's
37584d9c625SLionel Sambuc * not a big deal -- as soon as the user sets them explicitly the
37684d9c625SLionel Sambuc * environment will be set and the screen package will use the new
37784d9c625SLionel Sambuc * values.
37884d9c625SLionel Sambuc *
37984d9c625SLionel Sambuc * Try TIOCGWINSZ.
38084d9c625SLionel Sambuc */
38184d9c625SLionel Sambuc row = col = 0;
38284d9c625SLionel Sambuc #ifdef TIOCGWINSZ
38384d9c625SLionel Sambuc if (ioctl(STDERR_FILENO, TIOCGWINSZ, &win) != -1) {
38484d9c625SLionel Sambuc row = win.ws_row;
38584d9c625SLionel Sambuc col = win.ws_col;
38684d9c625SLionel Sambuc }
38784d9c625SLionel Sambuc #endif
38884d9c625SLionel Sambuc /* If here because of suspend or a signal, only trust TIOCGWINSZ. */
38984d9c625SLionel Sambuc if (sigwinch) {
39084d9c625SLionel Sambuc /*
39184d9c625SLionel Sambuc * Somebody didn't get TIOCGWINSZ right, or has suspend
39284d9c625SLionel Sambuc * without window resizing support. The user just lost,
39384d9c625SLionel Sambuc * but there's nothing we can do.
39484d9c625SLionel Sambuc */
39584d9c625SLionel Sambuc if (row == 0 || col == 0) {
39684d9c625SLionel Sambuc if (changedp != NULL)
39784d9c625SLionel Sambuc *changedp = 0;
39884d9c625SLionel Sambuc return (0);
39984d9c625SLionel Sambuc }
40084d9c625SLionel Sambuc
40184d9c625SLionel Sambuc /*
40284d9c625SLionel Sambuc * SunOS systems deliver SIGWINCH when windows are uncovered
40384d9c625SLionel Sambuc * as well as when they change size. In addition, we call
40484d9c625SLionel Sambuc * here when continuing after being suspended since the window
40584d9c625SLionel Sambuc * may have changed size. Since we don't want to background
40684d9c625SLionel Sambuc * all of the screens just because the window was uncovered,
40784d9c625SLionel Sambuc * ignore the signal if there's no change.
40884d9c625SLionel Sambuc */
40984d9c625SLionel Sambuc if (sp != NULL &&
41084d9c625SLionel Sambuc row == O_VAL(sp, O_LINES) && col == O_VAL(sp, O_COLUMNS)) {
41184d9c625SLionel Sambuc if (changedp != NULL)
41284d9c625SLionel Sambuc *changedp = 0;
41384d9c625SLionel Sambuc return (0);
41484d9c625SLionel Sambuc }
41584d9c625SLionel Sambuc
41684d9c625SLionel Sambuc if (rowp != NULL)
41784d9c625SLionel Sambuc *rowp = row;
41884d9c625SLionel Sambuc if (colp != NULL)
41984d9c625SLionel Sambuc *colp = col;
42084d9c625SLionel Sambuc resizeterm(row, col);
42184d9c625SLionel Sambuc return (0);
42284d9c625SLionel Sambuc }
42384d9c625SLionel Sambuc
42484d9c625SLionel Sambuc /*
42584d9c625SLionel Sambuc * !!!
42684d9c625SLionel Sambuc * If TIOCGWINSZ failed, or had entries of 0, try termcap. This
42784d9c625SLionel Sambuc * routine is called before any termcap or terminal information
42884d9c625SLionel Sambuc * has been set up. If there's no TERM environmental variable set,
42984d9c625SLionel Sambuc * let it go, at least ex can run.
43084d9c625SLionel Sambuc */
43184d9c625SLionel Sambuc if (row == 0 || col == 0) {
43284d9c625SLionel Sambuc if ((p = getenv("TERM")) == NULL)
43384d9c625SLionel Sambuc goto noterm;
43484d9c625SLionel Sambuc if (row == 0) {
43584d9c625SLionel Sambuc if ((rval = tigetnum("lines")) < 0)
43684d9c625SLionel Sambuc msgq(sp, M_SYSERR, "tigetnum: lines");
43784d9c625SLionel Sambuc else
43884d9c625SLionel Sambuc row = rval;
43984d9c625SLionel Sambuc }
44084d9c625SLionel Sambuc if (col == 0) {
44184d9c625SLionel Sambuc if ((rval = tigetnum("cols")) < 0)
44284d9c625SLionel Sambuc msgq(sp, M_SYSERR, "tigetnum: cols");
44384d9c625SLionel Sambuc else
44484d9c625SLionel Sambuc col = rval;
44584d9c625SLionel Sambuc }
44684d9c625SLionel Sambuc }
44784d9c625SLionel Sambuc
44884d9c625SLionel Sambuc /* If nothing else, well, it's probably a VT100. */
44984d9c625SLionel Sambuc noterm: if (row == 0)
45084d9c625SLionel Sambuc row = 24;
45184d9c625SLionel Sambuc if (col == 0)
45284d9c625SLionel Sambuc col = 80;
45384d9c625SLionel Sambuc
45484d9c625SLionel Sambuc /*
45584d9c625SLionel Sambuc * !!!
45684d9c625SLionel Sambuc * POSIX 1003.2 requires the environment to override everything.
45784d9c625SLionel Sambuc * Often, people can get nvi to stop messing up their screen by
45884d9c625SLionel Sambuc * deleting the LINES and COLUMNS environment variables from their
45984d9c625SLionel Sambuc * dot-files.
46084d9c625SLionel Sambuc */
46184d9c625SLionel Sambuc if ((p = getenv("LINES")) != NULL)
46284d9c625SLionel Sambuc row = strtol(p, NULL, 10);
46384d9c625SLionel Sambuc if ((p = getenv("COLUMNS")) != NULL)
46484d9c625SLionel Sambuc col = strtol(p, NULL, 10);
46584d9c625SLionel Sambuc
46684d9c625SLionel Sambuc if (rowp != NULL)
46784d9c625SLionel Sambuc *rowp = row;
46884d9c625SLionel Sambuc if (colp != NULL)
46984d9c625SLionel Sambuc *colp = col;
47084d9c625SLionel Sambuc return (0);
47184d9c625SLionel Sambuc }
47284d9c625SLionel Sambuc
47384d9c625SLionel Sambuc /*
47484d9c625SLionel Sambuc * cl_putchar --
47584d9c625SLionel Sambuc * Function version of putchar, for tputs.
47684d9c625SLionel Sambuc *
47784d9c625SLionel Sambuc * PUBLIC: int cl_putchar __P((int));
47884d9c625SLionel Sambuc */
47984d9c625SLionel Sambuc int
cl_putchar(int ch)48084d9c625SLionel Sambuc cl_putchar(int ch)
48184d9c625SLionel Sambuc {
48284d9c625SLionel Sambuc return (putchar(ch));
48384d9c625SLionel Sambuc }
484