ed.init.c revision 59415
198943Sluigi/* $Header: /src/pub/tcsh/ed.init.c,v 3.42 2000/01/14 22:57:26 christos Exp $ */
2117328Sluigi/*
398943Sluigi * ed.init.c: Editor initializations
498943Sluigi */
598943Sluigi/*-
698943Sluigi * Copyright (c) 1980, 1991 The Regents of the University of California.
798943Sluigi * All rights reserved.
898943Sluigi *
998943Sluigi * Redistribution and use in source and binary forms, with or without
1098943Sluigi * modification, are permitted provided that the following conditions
1198943Sluigi * are met:
1298943Sluigi * 1. Redistributions of source code must retain the above copyright
1398943Sluigi *    notice, this list of conditions and the following disclaimer.
1498943Sluigi * 2. Redistributions in binary form must reproduce the above copyright
1598943Sluigi *    notice, this list of conditions and the following disclaimer in the
1698943Sluigi *    documentation and/or other materials provided with the distribution.
1798943Sluigi * 3. All advertising materials mentioning features or use of this software
1898943Sluigi *    must display the following acknowledgement:
1998943Sluigi *	This product includes software developed by the University of
2098943Sluigi *	California, Berkeley and its contributors.
2198943Sluigi * 4. Neither the name of the University nor the names of its contributors
2298943Sluigi *    may be used to endorse or promote products derived from this software
2398943Sluigi *    without specific prior written permission.
2498943Sluigi *
2598943Sluigi * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2698943Sluigi * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2798943Sluigi * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2898943Sluigi * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2998943Sluigi * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30136071Sgreen * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3198943Sluigi * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTS_ION)
3298943Sluigi * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3398943Sluigi * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3498943Sluigi * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3598943Sluigi * SUCH DAMAGE.
3698943Sluigi */
3798943Sluigi#include "sh.h"
3898943Sluigi
3998943SluigiRCSID("$Id: ed.init.c,v 3.42 2000/01/14 22:57:26 christos Exp $")
4098943Sluigi
4198943Sluigi#include "ed.h"
4298943Sluigi#include "ed.term.h"
4398943Sluigi#include "tc.h"
44117469Sluigi#include "ed.defns.h"
4598943Sluigi
4698943Sluigi/* ed.init.c -- init routines for the line editor */
47136071Sgreen/* #define DEBUG_TTY */
48136071Sgreen
4998943Sluigiint     Tty_raw_mode = 0;	/* Last tty change was to raw mode */
5098943Sluigiint     MacroLvl = -1;		/* pointer to current macro nesting level; */
51165648Spiso				/* (-1 == none) */
52136071Sgreenstatic int Tty_quote_mode = 0;	/* Last tty change was to quote mode */
53145246Sbrooksstatic unsigned char vdisable;	/* The value of _POSIX_VDISABLE from
5498943Sluigi				 * pathconf(2) */
5598943Sluigi
5698943Sluigiint     Tty_eight_bit = -1;	/* does the tty handle eight bits */
5798943Sluigi
58145246Sbrooksextern bool GotTermCaps;
5998943Sluigi
6098943Sluigistatic ttydata_t extty, edtty, tstty;
6198943Sluigi#define qutty tstty
6298943Sluigi
63165648Spisoextern int insource;
6498943Sluigi#define SHTTY (insource ? OLDSTD : SHIN)
65117328Sluigi
6698943Sluigi#define uc unsigned char
6798943Sluigistatic unsigned char ttychars[NN_IO][C_NCC] = {
6898943Sluigi    {
6998943Sluigi	(uc)CINTR,	(uc)CQUIT, 	 (uc)CERASE, 	   (uc)CKILL,
70165648Spiso	(uc)CEOF, 	(uc)CEOL, 	 (uc)CEOL2, 	   (uc)CSWTCH,
7198943Sluigi	(uc)CDSWTCH,	(uc)CERASE2,	 (uc)CSTART, 	   (uc)CSTOP,
7298943Sluigi	(uc)CWERASE, 	(uc)CSUSP, 	 (uc)CDSUSP, 	   (uc)CREPRINT,
7398943Sluigi	(uc)CDISCARD, 	(uc)CLNEXT,	 (uc)CSTATUS,	   (uc)CPAGE,
74102098Sluigi	(uc)CPGOFF,	(uc)CKILL2, 	 (uc)CBRK, 	   (uc)CMIN,
75123804Smaxim	(uc)CTIME
76101628Sluigi    },
77117328Sluigi    {
78123495Sluigi	CINTR, 		 CQUIT, 	  CERASE, 	   CKILL,
7998943Sluigi	_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
8098943Sluigi	_POSIX_VDISABLE, CERASE2,	  CSTART, 	   CSTOP,
8198943Sluigi	_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
82130013Scsjp	CDISCARD, 	 _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
83130013Scsjp	_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
84130013Scsjp	0
85130013Scsjp    },
86130013Scsjp    {
8798943Sluigi	0,		 0,		  0,		   0,
88159636Soleg	0,		 0,		  0,		   0,
89159636Soleg	0,		 0,		  0,		   0,
90159636Soleg	0,		 0,		  0,		   0,
91159636Soleg	0,		 0,		  0,		   0,
92159636Soleg	0,		 0,		  0,		   0,
93159636Soleg	0
94159636Soleg    }
95159636Soleg};
96159636Soleg
97159636Soleg#ifdef SIG_WINDOW
98159636Solegvoid
99159636Solegcheck_window_size(force)
100159636Soleg    int     force;
101159636Soleg{
102159636Soleg#ifdef BSDSIGS
103159636Soleg    sigmask_t omask;
104159636Soleg#endif /* BSDSIGS */
105159636Soleg    int     lins, cols;
106159636Soleg
107159636Soleg    /* don't want to confuse things here */
108159636Soleg#ifdef BSDSIGS
109159636Soleg    omask = sigblock(sigmask(SIG_WINDOW)) & ~sigmask(SIG_WINDOW);
110159636Soleg#else /* BSDSIGS */
111159636Soleg    (void) sighold(SIG_WINDOW);
112159636Soleg#endif /* BSDSIGS */
113159636Soleg    /*
114159636Soleg     * From: bret@shark.agps.lanl.gov (Bret Thaeler) Avoid sunview bug, where a
115158879Soleg     * partially hidden window gets a SIG_WINDOW every time the text is
116158879Soleg     * scrolled
117159636Soleg     */
118159636Soleg    if (GetSize(&lins, &cols) || force) {
119159636Soleg	if (GettingInput) {
120159636Soleg	    ClearLines();
121159636Soleg	    ClearDisp();
122159636Soleg	    MoveToLine(0);
123159636Soleg	    MoveToChar(0);
124159636Soleg	    ChangeSize(lins, cols);
125159636Soleg	    Refresh();
12698943Sluigi	}
127117328Sluigi	else
128117328Sluigi	    ChangeSize(lins, cols);
129117328Sluigi    }
130117328Sluigi#ifdef BSDSIGS
131117328Sluigi    (void) sigsetmask(omask);	/* can change it again */
13298943Sluigi#else				/* BSDSIGS */
13398943Sluigi    (void) sigrelse(SIG_WINDOW);
13498943Sluigi#endif /* BSDSIGS */
135117469Sluigi}
13698943Sluigi
13798943Sluigisigret_t
13898943Sluigi/*ARGSUSED*/
13998943Sluigiwindow_change(snum)
14098943Sluigiint snum;
14198943Sluigi{
14298943Sluigi    USE(snum);
14398943Sluigi#ifdef UNRELSIGS
14498943Sluigi    /* If we were called as a signal handler, restore it. */
14598943Sluigi    if (snum > 0)
14698943Sluigi      sigset(snum, window_change);
14798943Sluigi#endif /* UNRELSIGS */
14898943Sluigi    check_window_size(0);
14998943Sluigi#ifndef SIGVOID
15098943Sluigi    return (snum);
15198943Sluigi#endif
15298943Sluigi}
15398943Sluigi
15498943Sluigi#endif /* SIG_WINDOW */
15598943Sluigi
15698943Sluigivoid
15798943Sluigied_set_tty_eight_bit()
15898943Sluigi{
15998943Sluigi    if (tty_getty(SHTTY, &extty) == -1) {
16098943Sluigi#ifdef DEBUG_TTY
16198943Sluigi	xprintf("ed_set_tty_eight_bit: tty_getty: %s\n", strerror(errno));
16298943Sluigi#endif /* DEBUG_TTY */
16398943Sluigi	return;
16498943Sluigi    }
16598943Sluigi    Tty_eight_bit = tty_geteightbit(&extty);
16698943Sluigi}
16798943Sluigi
16898943Sluigi
16998943Sluigiint
17098943Sluigied_Setup(rst)
17198943Sluigi    int rst;
17298943Sluigi{
17398943Sluigi    static int havesetup = 0;
17498943Sluigi    struct varent *imode;
17598943Sluigi
17698943Sluigi    if (havesetup) 	/* if we have never been called */
17798943Sluigi	return(0);
17898943Sluigi
17998943Sluigi#if defined(POSIX) && defined(_PC_VDISABLE) && !defined(BSD4_4) && \
18098943Sluigi    !defined(WINNT)
18198943Sluigi    {
18298943Sluigi	long pcret;
18398943Sluigi
18498943Sluigi	if ((pcret = fpathconf(SHTTY, _PC_VDISABLE)) == -1L)
18598943Sluigi	    vdisable = (unsigned char) _POSIX_VDISABLE;
18698943Sluigi	else
18798943Sluigi	    vdisable = (unsigned char) pcret;
18898943Sluigi	if (vdisable != (unsigned char) _POSIX_VDISABLE && rst != 0)
18998943Sluigi	    for (rst = 0; rst < C_NCC; rst++) {
19098943Sluigi		if (ttychars[ED_IO][rst] == (unsigned char) _POSIX_VDISABLE)
19198943Sluigi		    ttychars[ED_IO][rst] = vdisable;
19298943Sluigi		if (ttychars[EX_IO][rst] == (unsigned char) _POSIX_VDISABLE)
19398943Sluigi		    ttychars[EX_IO][rst] = vdisable;
19498943Sluigi	    }
19598943Sluigi    }
19698943Sluigi#else /* ! POSIX || !_PC_VDISABLE || BSD4_4 || WINNT */
19798943Sluigi    vdisable = (unsigned char) _POSIX_VDISABLE;
19898943Sluigi#endif /* POSIX && _PC_VDISABLE && !BSD4_4 && !WINNT */
19998943Sluigi
20098943Sluigi    if ((imode = adrof(STRinputmode)) != NULL) {
20198943Sluigi	if (!Strcmp(*(imode->vec), STRinsert))
20298943Sluigi	    inputmode = MODE_INSERT;
20398943Sluigi	else if (!Strcmp(*(imode->vec), STRoverwrite))
20498943Sluigi	    inputmode = MODE_REPLACE;
20598943Sluigi    }
20698943Sluigi    else
20798943Sluigi	inputmode = MODE_INSERT;
20898943Sluigi    ed_InitMaps();
20998943Sluigi    Hist_num = 0;
21098943Sluigi    Expand = 0;
21198943Sluigi
21298943Sluigi#ifndef WINNT
21398943Sluigi    if (tty_getty(SHTTY, &extty) == -1) {
21498943Sluigi# ifdef DEBUG_TTY
21598943Sluigi	xprintf("ed_Setup: tty_getty: %s\n", strerror(errno));
21698943Sluigi# endif /* DEBUG_TTY */
21798943Sluigi	return(-1);
21898943Sluigi    }
21998943Sluigi
22098943Sluigi    tstty = edtty = extty;
22198943Sluigi
22298943Sluigi    T_Speed = tty_getspeed(&extty);
22398943Sluigi    T_Tabs = tty_gettabs(&extty);
22498943Sluigi    Tty_eight_bit = tty_geteightbit(&extty);
22598943Sluigi
22698943Sluigi# if defined(POSIX) || defined(TERMIO)
22798943Sluigi    extty.d_t.c_iflag &= ~ttylist[EX_IO][M_INPUT].t_clrmask;
22898943Sluigi    extty.d_t.c_iflag |=  ttylist[EX_IO][M_INPUT].t_setmask;
22998943Sluigi
23098943Sluigi    extty.d_t.c_oflag &= ~ttylist[EX_IO][M_OUTPUT].t_clrmask;
23198943Sluigi    extty.d_t.c_oflag |=  ttylist[EX_IO][M_OUTPUT].t_setmask;
23298943Sluigi
23398943Sluigi    extty.d_t.c_cflag &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
23498943Sluigi    extty.d_t.c_cflag |=  ttylist[EX_IO][M_CONTROL].t_setmask;
235101641Sluigi
236101641Sluigi    extty.d_t.c_lflag &= ~ttylist[EX_IO][M_LINED].t_clrmask;
23798943Sluigi    extty.d_t.c_lflag |=  ttylist[EX_IO][M_LINED].t_setmask;
23898943Sluigi
23998943Sluigi#  if defined(IRIX3_3) && SYSVREL < 4
24098943Sluigi    extty.d_t.c_line = NTTYDISC;
24198943Sluigi#  endif /* IRIX3_3 && SYSVREL < 4 */
24298943Sluigi
24398943Sluigi# else	/* GSTTY */		/* V7, Berkeley style tty */
244141351Sglebius
245141351Sglebius    if (T_Tabs) {	/* order of &= and |= is important to XTABS */
24698943Sluigi	extty.d_t.sg_flags &= ~(ttylist[EX_IO][M_CONTROL].t_clrmask|XTABS);
24798943Sluigi	extty.d_t.sg_flags |=   ttylist[EX_IO][M_CONTROL].t_setmask;
24898943Sluigi    }
24998943Sluigi    else {
25098943Sluigi	extty.d_t.sg_flags &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
25198943Sluigi	extty.d_t.sg_flags |= (ttylist[EX_IO][M_CONTROL].t_setmask|XTABS);
25298943Sluigi    }
253165648Spiso
25498943Sluigi    extty.d_lb &= ~ttylist[EX_IO][M_LOCAL].t_clrmask;
255136071Sgreen    extty.d_lb |=  ttylist[EX_IO][M_LOCAL].t_setmask;
256136071Sgreen
257158879Soleg# endif /* GSTTY */
258158879Soleg    /*
259136071Sgreen     * Reset the tty chars to reasonable defaults
260158879Soleg     * If they are disabled, then enable them.
26198943Sluigi     */
26298943Sluigi    if (rst) {
263133600Scsjp	if (tty_cooked_mode(&tstty)) {
26498943Sluigi	    tty_getchar(&tstty, ttychars[TS_IO]);
26598943Sluigi	    /*
26698943Sluigi	     * Don't affect CMIN and CTIME for the editor mode
26798943Sluigi	     */
26898943Sluigi	    for (rst = 0; rst < C_NCC - 2; rst++)
269136073Sgreen		if (ttychars[TS_IO][rst] != vdisable &&
270136073Sgreen		    ttychars[ED_IO][rst] != vdisable)
271136073Sgreen		    ttychars[ED_IO][rst] = ttychars[TS_IO][rst];
27298943Sluigi	    for (rst = 0; rst < C_NCC; rst++)
27398943Sluigi		if (ttychars[TS_IO][rst] != vdisable &&
27498943Sluigi		    ttychars[EX_IO][rst] != vdisable)
27598943Sluigi		    ttychars[EX_IO][rst] = ttychars[TS_IO][rst];
27698943Sluigi	}
27798943Sluigi	tty_setchar(&extty, ttychars[EX_IO]);
27898943Sluigi	if (tty_setty(SHTTY, &extty) == -1) {
27998943Sluigi# ifdef DEBUG_TTY
28098943Sluigi	    xprintf("ed_Setup: tty_setty: %s\n", strerror(errno));
28198943Sluigi# endif /* DEBUG_TTY */
28298943Sluigi	    return(-1);
28398943Sluigi	}
28498943Sluigi    }
285136075Sgreen    else
28698943Sluigi	tty_setchar(&extty, ttychars[EX_IO]);
28798943Sluigi
28898943Sluigi# ifdef SIG_WINDOW
28998943Sluigi    (void) sigset(SIG_WINDOW, window_change);	/* for window systems */
29098943Sluigi# endif
29198943Sluigi#else /* WINNT */
292102087Sluigi# ifdef DEBUG
293102087Sluigi    if (rst)
294112250Scjc	xprintf("rst received in ed_Setup() %d\n", rst);
295128575Sandre# endif
296133387Sandre#endif /* WINNT */
297117241Sluigi    havesetup = 1;
298117469Sluigi    return(0);
29998943Sluigi}
30098943Sluigi
301101978Sluigivoid
30298943Sluigied_Init()
30398943Sluigi{
30498943Sluigi    ResetInLine(1);		/* reset the input pointers */
30598943Sluigi    GettingInput = 0;		/* just in case */
30698943Sluigi    LastKill = KillBuf;		/* no kill buffer */
30798943Sluigi
30898943Sluigi#ifdef DEBUG_EDIT
30998943Sluigi    CheckMaps();		/* do a little error checking on key maps */
31098943Sluigi#endif
31198943Sluigi
31298943Sluigi    if (ed_Setup(0) == -1)
31398943Sluigi	return;
31498943Sluigi
31598943Sluigi    /*
316165648Spiso     * if we have been called before but GotTermCaps isn't set, our TERM has
317165648Spiso     * changed, so get new termcaps and try again
318165648Spiso     */
319165648Spiso
320165648Spiso    if (!GotTermCaps)
321165648Spiso	GetTermCaps();		/* does the obvious, but gets term type each
322165648Spiso				 * time */
323165648Spiso
324165648Spiso#ifndef WINNT
325165648Spiso# if defined(TERMIO) || defined(POSIX)
326165648Spiso    edtty.d_t.c_iflag &= ~ttylist[ED_IO][M_INPUT].t_clrmask;
327165648Spiso    edtty.d_t.c_iflag |=  ttylist[ED_IO][M_INPUT].t_setmask;
328145246Sbrooks
329145246Sbrooks    edtty.d_t.c_oflag &= ~ttylist[ED_IO][M_OUTPUT].t_clrmask;
330145246Sbrooks    edtty.d_t.c_oflag |=  ttylist[ED_IO][M_OUTPUT].t_setmask;
331145246Sbrooks
332145246Sbrooks    edtty.d_t.c_cflag &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
333145246Sbrooks    edtty.d_t.c_cflag |=  ttylist[ED_IO][M_CONTROL].t_setmask;
334145246Sbrooks
335146894Smlaier    edtty.d_t.c_lflag &= ~ttylist[ED_IO][M_LINED].t_clrmask;
336146894Smlaier    edtty.d_t.c_lflag |=  ttylist[ED_IO][M_LINED].t_setmask;
337149020Sbz
338149020Sbz
33998943Sluigi#  if defined(IRIX3_3) && SYSVREL < 4
34098943Sluigi    edtty.d_t.c_line = NTTYDISC;
34198943Sluigi#  endif /* IRIX3_3 && SYSVREL < 4 */
34298943Sluigi
343101978Sluigi# else /* GSTTY */
34498943Sluigi
34598943Sluigi    if (T_Tabs) {	/* order of &= and |= is important to XTABS */
34698943Sluigi	edtty.d_t.sg_flags &= ~(ttylist[ED_IO][M_CONTROL].t_clrmask | XTABS);
34798943Sluigi	edtty.d_t.sg_flags |=   ttylist[ED_IO][M_CONTROL].t_setmask;
34898943Sluigi    }
34998943Sluigi    else {
35098943Sluigi	edtty.d_t.sg_flags &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
35198943Sluigi	edtty.d_t.sg_flags |= (ttylist[ED_IO][M_CONTROL].t_setmask | XTABS);
35298943Sluigi    }
35398943Sluigi
35498943Sluigi    edtty.d_lb &= ~ttylist[ED_IO][M_LOCAL].t_clrmask;
35598943Sluigi    edtty.d_lb |=  ttylist[ED_IO][M_LOCAL].t_setmask;
35698943Sluigi# endif /* POSIX || TERMIO */
35798943Sluigi
35898943Sluigi    tty_setchar(&edtty, ttychars[ED_IO]);
35999475Sluigi#endif /* WINNT */
36098943Sluigi}
361145246Sbrooks
362145246Sbrooks/*
363145246Sbrooks * Check and re-init the line. set the terminal into 1 char at a time mode.
364145246Sbrooks */
365145246Sbrooksint
36698943SluigiRawmode()
367117328Sluigi{
36898943Sluigi    if (Tty_raw_mode)
36998943Sluigi	return (0);
370165648Spiso
371165648Spiso#ifdef WINNT
372165648Spiso    do_nt_raw_mode();
373165648Spiso#else /* !WINNT */
374165648Spiso# ifdef _IBMR2
375165648Spiso    tty_setdisc(SHTTY, ED_IO);
376165648Spiso# endif /* _IBMR2 */
377165648Spiso
378165648Spiso    if (tty_getty(SHTTY, &tstty) == -1) {
379165648Spiso# ifdef DEBUG_TTY
380165648Spiso	xprintf("Rawmode: tty_getty: %s\n", strerror(errno));
381165648Spiso# endif /* DEBUG_TTY */
382165648Spiso	return(-1);
383165648Spiso    }
384165648Spiso
385165648Spiso    /*
38698943Sluigi     * We always keep up with the eight bit setting and the speed of the
38798943Sluigi     * tty. But only we only believe changes that are made to cooked mode!
38898943Sluigi     */
38998943Sluigi# if defined(POSIX) || defined(TERMIO)
39098943Sluigi    Tty_eight_bit = tty_geteightbit(&tstty);
39198943Sluigi    T_Speed = tty_getspeed(&tstty);
39298943Sluigi
39398943Sluigi#  ifdef POSIX
39498943Sluigi    /*
39598943Sluigi     * Fix from: Steven (Steve) B. Green <xrsbg@charney.gsfc.nasa.gov>
396141351Sglebius     * Speed was not being set up correctly under POSIX.
397141351Sglebius     */
39898943Sluigi    if (tty_getspeed(&extty) != T_Speed || tty_getspeed(&edtty) != T_Speed) {
39998943Sluigi	(void) cfsetispeed(&extty.d_t, T_Speed);
40098943Sluigi	(void) cfsetospeed(&extty.d_t, T_Speed);
40198943Sluigi	(void) cfsetispeed(&edtty.d_t, T_Speed);
40298943Sluigi	(void) cfsetospeed(&edtty.d_t, T_Speed);
40398943Sluigi    }
404149020Sbz#  endif /* POSIX */
40598943Sluigi# else /* GSTTY */
406149020Sbz
40799475Sluigi    T_Speed = tty_getspeed(&tstty);
40898943Sluigi    Tty_eight_bit = tty_geteightbit(&tstty);
409117469Sluigi
410165648Spiso    if (extty.d_t.sg_ispeed != tstty.d_t.sg_ispeed) {
411117328Sluigi	extty.d_t.sg_ispeed = tstty.d_t.sg_ispeed;
41298943Sluigi	edtty.d_t.sg_ispeed = tstty.d_t.sg_ispeed;
41398943Sluigi    }
414136071Sgreen
415136071Sgreen    if (extty.d_t.sg_ospeed != tstty.d_t.sg_ospeed) {
416136071Sgreen	extty.d_t.sg_ospeed = tstty.d_t.sg_ospeed;
417158879Soleg	edtty.d_t.sg_ospeed = tstty.d_t.sg_ospeed;
418158879Soleg    }
419136071Sgreen# endif /* POSIX || TERMIO */
420136071Sgreen
421136071Sgreen    if (tty_cooked_mode(&tstty)) {
42298943Sluigi	/*
423158879Soleg	 * re-test for some things here (like maybe the user typed
42498943Sluigi	 * "stty -tabs"
42598943Sluigi	 */
426133600Scsjp	if (tty_gettabs(&tstty) == 0)
42798943Sluigi	    T_Tabs = 0;
42898943Sluigi	else
42998943Sluigi	    T_Tabs = CanWeTab();
43098943Sluigi
43198943Sluigi# if defined(POSIX) || defined(TERMIO)
43298943Sluigi	extty.d_t.c_cflag  = tstty.d_t.c_cflag;
433136073Sgreen	extty.d_t.c_cflag &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
434136073Sgreen	extty.d_t.c_cflag |=  ttylist[EX_IO][M_CONTROL].t_setmask;
435136073Sgreen
43698943Sluigi	edtty.d_t.c_cflag  = tstty.d_t.c_cflag;
43798943Sluigi	edtty.d_t.c_cflag &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
43898943Sluigi	edtty.d_t.c_cflag |=  ttylist[ED_IO][M_CONTROL].t_setmask;
43998943Sluigi
44098943Sluigi	extty.d_t.c_lflag = tstty.d_t.c_lflag;
44198943Sluigi	extty.d_t.c_lflag &= ~ttylist[EX_IO][M_LINED].t_clrmask;
44298943Sluigi	extty.d_t.c_lflag |=  ttylist[EX_IO][M_LINED].t_setmask;
44398943Sluigi
44498943Sluigi	edtty.d_t.c_lflag = tstty.d_t.c_lflag;
44598943Sluigi	edtty.d_t.c_lflag &= ~ttylist[ED_IO][M_LINED].t_clrmask;
44698943Sluigi	edtty.d_t.c_lflag |=  ttylist[ED_IO][M_LINED].t_setmask;
44798943Sluigi
44898943Sluigi	extty.d_t.c_iflag = tstty.d_t.c_iflag;
44998943Sluigi	extty.d_t.c_iflag &= ~ttylist[EX_IO][M_INPUT].t_clrmask;
45098943Sluigi	extty.d_t.c_iflag |=  ttylist[EX_IO][M_INPUT].t_setmask;
45198943Sluigi
45298943Sluigi	edtty.d_t.c_iflag = tstty.d_t.c_iflag;
453136075Sgreen	edtty.d_t.c_iflag &= ~ttylist[ED_IO][M_INPUT].t_clrmask;
45498943Sluigi	edtty.d_t.c_iflag |=  ttylist[ED_IO][M_INPUT].t_setmask;
45598943Sluigi
45698943Sluigi	extty.d_t.c_oflag = tstty.d_t.c_oflag;
45798943Sluigi	extty.d_t.c_oflag &= ~ttylist[EX_IO][M_OUTPUT].t_clrmask;
45898943Sluigi	extty.d_t.c_oflag |=  ttylist[EX_IO][M_OUTPUT].t_setmask;
45998943Sluigi
46098943Sluigi	edtty.d_t.c_oflag = tstty.d_t.c_oflag;
46199909Sluigi	edtty.d_t.c_oflag &= ~ttylist[ED_IO][M_OUTPUT].t_clrmask;
46298943Sluigi	edtty.d_t.c_oflag |=  ttylist[ED_IO][M_OUTPUT].t_setmask;
463102087Sluigi
464102087Sluigi# else /* GSTTY */
465102087Sluigi
466102087Sluigi	extty.d_t.sg_flags = tstty.d_t.sg_flags;
467102087Sluigi
468102087Sluigi	extty.d_t.sg_flags &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
469102087Sluigi	extty.d_t.sg_flags |=  ttylist[EX_IO][M_CONTROL].t_setmask;
470102087Sluigi
471112250Scjc	if (T_Tabs)		/* order of &= and |= is important to XTABS */
472128575Sandre	    extty.d_t.sg_flags &= ~XTABS;
473133387Sandre	else
474117241Sluigi	    extty.d_t.sg_flags |= XTABS;
475145246Sbrooks
476145246Sbrooks	extty.d_lb = tstty.d_lb;
477145246Sbrooks	extty.d_lb &= ~ttylist[EX_IO][M_LOCAL].t_clrmask;
478145246Sbrooks	extty.d_lb |= ttylist[EX_IO][M_LOCAL].t_setmask;
479145246Sbrooks
480145246Sbrooks	edtty.d_t.sg_flags = extty.d_t.sg_flags;
481146894Smlaier	if (T_Tabs) {	/* order of &= and |= is important to XTABS */
482146894Smlaier	    edtty.d_t.sg_flags &=
483145246Sbrooks		    ~(ttylist[ED_IO][M_CONTROL].t_clrmask|XTABS);
484145246Sbrooks	    edtty.d_t.sg_flags |=   ttylist[ED_IO][M_CONTROL].t_setmask;
485145246Sbrooks	}
486145246Sbrooks	else {
487117469Sluigi	    edtty.d_t.sg_flags &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
48898943Sluigi	    edtty.d_t.sg_flags |=
48998943Sluigi		    (ttylist[ED_IO][M_CONTROL].t_setmask|XTABS);
49098943Sluigi	}
49198943Sluigi
49298943Sluigi	edtty.d_lb = tstty.d_lb;
493101641Sluigi	edtty.d_lb &= ~ttylist[ED_IO][M_LOCAL].t_clrmask;
494101641Sluigi	edtty.d_lb |= ttylist[ED_IO][M_LOCAL].t_setmask;
495101641Sluigi
496101641Sluigi# endif /* TERMIO || POSIX */
497117328Sluigi
49898943Sluigi	{
49998943Sluigi	    extern int didsetty;
500153374Sglebius	    int i;
501153374Sglebius
502117328Sluigi	    tty_getchar(&tstty, ttychars[TS_IO]);
503117328Sluigi	    /*
504117328Sluigi	     * Check if the user made any changes.
505115793Sticso	     * If he did, then propagate the changes to the
506115793Sticso	     * edit and execute data structures.
507115793Sticso	     */
508129389Sstefanf	    for (i = 0; i < C_NCC; i++)
509115793Sticso		if (ttychars[TS_IO][i] != ttychars[EX_IO][i])
510117328Sluigi		    break;
511117328Sluigi
512117328Sluigi	    if (i != C_NCC || didsetty) {
513117469Sluigi		didsetty = 0;
514119740Stmm		/*
515117328Sluigi		 * Propagate changes only to the unprotected chars
516117328Sluigi		 * that have been modified just now.
517117328Sluigi		 */
518117577Sluigi		for (i = 0; i < C_NCC; i++) {
519117328Sluigi		    if (!((ttylist[ED_IO][M_CHAR].t_setmask & C_SH(i))) &&
520117328Sluigi			(ttychars[TS_IO][i] != ttychars[EX_IO][i]))
521117328Sluigi			ttychars[ED_IO][i] = ttychars[TS_IO][i];
522117328Sluigi		    if (ttylist[ED_IO][M_CHAR].t_clrmask & C_SH(i))
523117328Sluigi			ttychars[ED_IO][i] = vdisable;
524117328Sluigi		}
525117328Sluigi		tty_setchar(&edtty, ttychars[ED_IO]);
526117328Sluigi
527117328Sluigi		for (i = 0; i < C_NCC; i++) {
528130281Sru		    if (!((ttylist[EX_IO][M_CHAR].t_setmask & C_SH(i))) &&
529165648Spiso			(ttychars[TS_IO][i] != ttychars[EX_IO][i]))
530165648Spiso			ttychars[EX_IO][i] = ttychars[TS_IO][i];
531165648Spiso		    if (ttylist[EX_IO][M_CHAR].t_clrmask & C_SH(i))
532117328Sluigi			ttychars[EX_IO][i] = vdisable;
533117328Sluigi		}
534117328Sluigi		tty_setchar(&extty, ttychars[EX_IO]);
535117328Sluigi	    }
536117328Sluigi
537117328Sluigi	}
538117328Sluigi    }
53998943Sluigi    if (tty_setty(SHTTY, &edtty) == -1) {
54098943Sluigi# ifdef DEBUG_TTY
541117328Sluigi	xprintf("Rawmode: tty_setty: %s\n", strerror(errno));
54298943Sluigi# endif /* DEBUG_TTY */
54398943Sluigi	return(-1);
54498943Sluigi    }
54598943Sluigi#endif /* WINNT */
54698943Sluigi    Tty_raw_mode = 1;
547117469Sluigi    flush();			/* flush any buffered output */
54898943Sluigi    return (0);
54998943Sluigi}
55098943Sluigi
55198943Sluigiint
55298943SluigiCookedmode()
553129389Sstefanf{				/* set tty in normal setup */
55498943Sluigi#ifdef WINNT
555117328Sluigi    do_nt_cooked_mode();
556117328Sluigi#else
557117328Sluigi    signalfun_t orig_intr;
558117328Sluigi
559117469Sluigi# ifdef _IBMR2
560117469Sluigi    tty_setdisc(SHTTY, EX_IO);
56198943Sluigi# endif /* _IBMR2 */
56298943Sluigi
56398943Sluigi    if (!Tty_raw_mode)
56498943Sluigi	return (0);
56598943Sluigi
56698943Sluigi    /* hold this for reseting tty */
56798943Sluigi# ifdef BSDSIGS
56898943Sluigi    orig_intr = (signalfun_t) signal(SIGINT, SIG_IGN);
569140271Sbrooks# else
570140271Sbrooks#  ifdef SIG_HOLD
571140271Sbrooks    /*
572140271Sbrooks     * sigset doesn't return the previous handler if the signal is held,
573140271Sbrooks     * it will return SIG_HOLD instead. So instead of restoring the
574140271Sbrooks     * the signal we would end up installing a blocked SIGINT with a
575140271Sbrooks     * SIG_IGN signal handler. This is what happened when Cookedmode
576140271Sbrooks     * was called from sched_run, disabling interrupt for the rest
577140271Sbrooks     * of your session.
578140271Sbrooks     *
579140271Sbrooks     * This is what we do:
580140271Sbrooks     * - if the signal is blocked, keep it that way
581140271Sbrooks     * - else set it to SIG_IGN
582140271Sbrooks     *
583140271Sbrooks     * Casper Dik (casper@fwi.uva.nl)
584140271Sbrooks     */
585140271Sbrooks    orig_intr = (signalfun_t) sigset(SIGINT, SIG_HOLD);
586140271Sbrooks    if (orig_intr != SIG_HOLD)
587140271Sbrooks	(void) sigset(SIGINT, SIG_IGN); /* returns SIG_HOLD */
588140271Sbrooks#  else /* !SIG_HOLD */
589140271Sbrooks    /*
590140271Sbrooks     * No SIG_HOLD; probably no reliable signals as well.
591140271Sbrooks     */
592140271Sbrooks    orig_intr = (signalfun_t) sigset(SIGINT, SIG_IGN);
593140271Sbrooks#  endif /* SIG_HOLD */
594140271Sbrooks# endif /* BSDSIGS */
595140271Sbrooks    if (tty_setty(SHTTY, &extty) == -1) {
596140271Sbrooks# ifdef DEBUG_TTY
597140271Sbrooks	xprintf("Cookedmode: tty_setty: %s\n", strerror(errno));
598140271Sbrooks# endif /* DEBUG_TTY */
599140271Sbrooks	return -1;
600140271Sbrooks    }
601140271Sbrooks# ifdef BSDSIGS
602140271Sbrooks    (void) signal(SIGINT, orig_intr);	/* take these again */
603140271Sbrooks# else
604140271Sbrooks    (void) sigset(SIGINT, orig_intr);	/* take these again */
605140271Sbrooks# endif /* BSDSIGS */
606140271Sbrooks#endif /* WINNT */
607140271Sbrooks
608140271Sbrooks    Tty_raw_mode = 0;
609140271Sbrooks    return (0);
610140271Sbrooks}
611140271Sbrooks
612140271Sbrooksvoid
613140271SbrooksResetInLine(macro)
614140271Sbrooks    int macro;
615140271Sbrooks{
616140271Sbrooks    Cursor = InputBuf;		/* reset cursor */
617140271Sbrooks    LastChar = InputBuf;
618140271Sbrooks    InputLim = &InputBuf[INBUFSIZE - 2];
61998943Sluigi    Mark = InputBuf;
62098943Sluigi    MetaNext = 0;
62198943Sluigi    CurrentKeyMap = CcKeyMap;
622117328Sluigi    AltKeyMap = 0;
62398943Sluigi    Hist_num = 0;
62498943Sluigi    DoingArg = 0;
62598943Sluigi    Argument = 1;
626117469Sluigi#ifdef notdef
62798943Sluigi    LastKill = KillBuf;		/* no kill buffer */
62898943Sluigi#endif
62998943Sluigi    LastCmd = F_UNASSIGNED;	/* previous command executed */
63098943Sluigi    if (macro)
63198943Sluigi	MacroLvl = -1;		/* no currently active macros */
63298943Sluigi}
63398943Sluigi
63498943Sluigistatic Char *Input_Line = NULL;
63598943Sluigiint
63698943SluigiLoad_input_line()
63798943Sluigi{
63898943Sluigi#ifdef SUNOS4
63998943Sluigi    long chrs = 0;
64098943Sluigi#else /* !SUNOS4 */
64198943Sluigi    /*
64298943Sluigi     * *Everyone* else has an int, but SunOS wants long!
64398943Sluigi     * This breaks where int != long (alpha)
64498943Sluigi     */
64598943Sluigi    int chrs = 0;
646117328Sluigi#endif /* SUNOS4 */
647117328Sluigi
648117328Sluigi    if (Input_Line)
649117328Sluigi	xfree((ptr_t) Input_Line);
650117328Sluigi    Input_Line = NULL;
651117328Sluigi
652117328Sluigi    if (Tty_raw_mode)
653136075Sgreen	return 0;
654158879Soleg
655117328Sluigi#if defined(FIONREAD) && !defined(OREO)
656117328Sluigi    (void) ioctl(SHIN, FIONREAD, (ioctl_t) &chrs);
657117328Sluigi    if (chrs > 0) {
65898943Sluigi	char    buf[BUFSIZE];
659117328Sluigi
66098943Sluigi	chrs = read(SHIN, buf, (size_t) min(chrs, BUFSIZE - 1));
66198943Sluigi	if (chrs > 0) {
66298943Sluigi	    buf[chrs] = '\0';
663102087Sluigi	    Input_Line = Strsave(str2short(buf));
66498943Sluigi	    PushMacro(Input_Line);
665117328Sluigi	}
66698943Sluigi#ifdef convex
667117469Sluigi        /* need to print errno message in case file is migrated */
66898943Sluigi        if (chrs < 0)
66998943Sluigi            stderror(ERR_SYSTEM, progname, strerror(errno));
67098943Sluigi#endif
671116690Sluigi    }
672117328Sluigi#endif  /* FIONREAD && !OREO */
673117328Sluigi    return chrs > 0;
674116690Sluigi}
675116690Sluigi
676116690Sluigi/*
677116690Sluigi * Bugfix (in Swedish) by:
67898943Sluigi * Johan Widen
67998943Sluigi * SICS, PO Box 1263, S-163 13 SPANGA, SWEDEN
68098943Sluigi * {mcvax,munnari,cernvax,diku,inria,prlb2,penet,ukc,unido}!enea!sics.se!jw
68198943Sluigi * Internet: jw@sics.se
68298943Sluigi *
68398943Sluigi * (via Hans J Albertsson (thanks))
68498943Sluigi */
68598943Sluigivoid
68698943SluigiQuoteModeOn()
68798943Sluigi{
68898943Sluigi    if (MacroLvl >= 0)
68998943Sluigi	return;
69098943Sluigi
69198943Sluigi#ifndef WINNT
69298943Sluigi    qutty = edtty;
69398943Sluigi
69498943Sluigi#if defined(TERMIO) || defined(POSIX)
69598943Sluigi    qutty.d_t.c_iflag &= ~ttylist[QU_IO][M_INPUT].t_clrmask;
696101628Sluigi    qutty.d_t.c_iflag |=  ttylist[QU_IO][M_INPUT].t_setmask;
69798943Sluigi
69898943Sluigi    qutty.d_t.c_oflag &= ~ttylist[QU_IO][M_OUTPUT].t_clrmask;
69998943Sluigi    qutty.d_t.c_oflag |=  ttylist[QU_IO][M_OUTPUT].t_setmask;
70098943Sluigi
701101628Sluigi    qutty.d_t.c_cflag &= ~ttylist[QU_IO][M_CONTROL].t_clrmask;
702101628Sluigi    qutty.d_t.c_cflag |=  ttylist[QU_IO][M_CONTROL].t_setmask;
70398943Sluigi
70498943Sluigi    qutty.d_t.c_lflag &= ~ttylist[QU_IO][M_LINED].t_clrmask;
705101628Sluigi    qutty.d_t.c_lflag |=  ttylist[QU_IO][M_LINED].t_setmask;
706117577Sluigi#else /* GSTTY */
707101628Sluigi    qutty.d_t.sg_flags &= ~ttylist[QU_IO][M_CONTROL].t_clrmask;
708106505Smaxim    qutty.d_t.sg_flags |= ttylist[QU_IO][M_CONTROL].t_setmask;
70998943Sluigi    qutty.d_lb &= ~ttylist[QU_IO][M_LOCAL].t_clrmask;
71098943Sluigi    qutty.d_lb |= ttylist[QU_IO][M_LOCAL].t_setmask;
71198943Sluigi
71298943Sluigi#endif /* TERMIO || POSIX */
713101628Sluigi    if (tty_setty(SHTTY, &qutty) == -1) {
71498943Sluigi#ifdef DEBUG_TTY
715101628Sluigi	xprintf("QuoteModeOn: tty_setty: %s\n", strerror(errno));
716101628Sluigi#endif /* DEBUG_TTY */
717101628Sluigi	return;
71898943Sluigi    }
719101628Sluigi#endif /* !WINNT */
720101628Sluigi    Tty_quote_mode = 1;
721101628Sluigi    return;
722101628Sluigi}
723101628Sluigi
724101628Sluigivoid
725101628SluigiQuoteModeOff()
726101628Sluigi{
727117577Sluigi    if (!Tty_quote_mode)
728101628Sluigi	return;
729101628Sluigi    Tty_quote_mode = 0;
730101628Sluigi    if (tty_setty(SHTTY, &edtty) == -1) {
73198943Sluigi#ifdef DEBUG_TTY
732101628Sluigi	xprintf("QuoteModeOff: tty_setty: %s\n", strerror(errno));
733101628Sluigi#endif /* DEBUG_TTY */
734101628Sluigi	return;
73598943Sluigi    }
73698943Sluigi    return;
73798943Sluigi}
73898943Sluigi