ed.init.c revision 59243
159243Sobrien/* $Header: /src/pub/tcsh/ed.init.c,v 3.41 1999/02/06 15:01:16 christos Exp $ */
283098Smp/*
359243Sobrien * ed.init.c: Editor initializations
483098Smp */
583098Smp/*-
659243Sobrien * Copyright (c) 1980, 1991 The Regents of the University of California.
7131962Smp * All rights reserved.
8131962Smp *
9131962Smp * Redistribution and use in source and binary forms, with or without
10131962Smp * modification, are permitted provided that the following conditions
11131962Smp * are met:
12131962Smp * 1. Redistributions of source code must retain the above copyright
13131962Smp *    notice, this list of conditions and the following disclaimer.
14131962Smp * 2. Redistributions in binary form must reproduce the above copyright
15131962Smp *    notice, this list of conditions and the following disclaimer in the
16131962Smp *    documentation and/or other materials provided with the distribution.
17131962Smp * 3. All advertising materials mentioning features or use of this software
18131962Smp *    must display the following acknowledgement:
19131962Smp *	This product includes software developed by the University of
20131962Smp *	California, Berkeley and its contributors.
21131962Smp * 4. Neither the name of the University nor the names of its contributors
22131962Smp *    may be used to endorse or promote products derived from this software
23131962Smp *    without specific prior written permission.
24131962Smp *
25131962Smp * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26131962Smp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27131962Smp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28131962Smp * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29131962Smp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30131962Smp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31131962Smp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTS_ION)
32131962Smp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33131962Smp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34131962Smp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35131962Smp * SUCH DAMAGE.
36131962Smp */
37131962Smp#include "sh.h"
38131962Smp
39131962SmpRCSID("$Id: ed.init.c,v 3.41 1999/02/06 15:01:16 christos Exp $")
40131962Smp
41131962Smp#include "ed.h"
42131962Smp#include "ed.term.h"
43131962Smp#include "tc.h"
44131962Smp#include "ed.defns.h"
45131962Smp
46131962Smp/* ed.init.c -- init routines for the line editor */
47131962Smp/* #define DEBUG_TTY */
48131962Smp
49131962Smpint     Tty_raw_mode = 0;	/* Last tty change was to raw mode */
50131962Smpint     MacroLvl = -1;		/* pointer to current macro nesting level; */
51131962Smp				/* (-1 == none) */
52131962Smpstatic int Tty_quote_mode = 0;	/* Last tty change was to quote mode */
53131962Smpstatic unsigned char vdisable;	/* The value of _POSIX_VDISABLE from
54131962Smp				 * pathconf(2) */
55131962Smp
56131962Smpint     Tty_eight_bit = -1;	/* does the tty handle eight bits */
57131962Smp
58131962Smpextern bool GotTermCaps;
59131962Smp
60131962Smpstatic ttydata_t extty, edtty, tstty;
61131962Smp#define qutty tstty
62131962Smp
63131962Smpextern int insource;
64131962Smp#define SHTTY (insource ? OLDSTD : SHIN)
65131962Smp
66131962Smp#define uc unsigned char
67131962Smpstatic unsigned char ttychars[NN_IO][C_NCC] = {
68131962Smp    {
69131962Smp	(uc)CINTR,	(uc)CQUIT, 	 (uc)CERASE, 	   (uc)CKILL,
70131962Smp	(uc)CEOF, 	(uc)CEOL, 	 (uc)CEOL2, 	   (uc)CSWTCH,
71131962Smp	(uc)CDSWTCH,	(uc)CERASE2,	 (uc)CSTART, 	   (uc)CSTOP,
72131962Smp	(uc)CWERASE, 	(uc)CSUSP, 	 (uc)CDSUSP, 	   (uc)CREPRINT,
73131962Smp	(uc)CDISCARD, 	(uc)CLNEXT,	 (uc)CSTATUS,	   (uc)CPAGE,
74131962Smp	(uc)CPGOFF,	(uc)CKILL2, 	 (uc)CBRK, 	   (uc)CMIN,
75131962Smp	(uc)CTIME
76131962Smp    },
77131962Smp    {
78131962Smp	CINTR, 		 CQUIT, 	  CERASE, 	   CKILL,
79131962Smp	_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
80131962Smp	_POSIX_VDISABLE, CERASE2,	  CSTART, 	   CSTOP,
81131962Smp	_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
82131962Smp	CDISCARD, 	 _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
83131962Smp	_POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
84131962Smp	0
85131962Smp    },
86131962Smp    {
87131962Smp	0,		 0,		  0,		   0,
88131962Smp	0,		 0,		  0,		   0,
89131962Smp	0,		 0,		  0,		   0,
90131962Smp	0,		 0,		  0,		   0,
91131962Smp	0,		 0,		  0,		   0,
92131962Smp	0,		 0,		  0,		   0,
93131962Smp	0
94131962Smp    }
95131962Smp};
96131962Smp
97131962Smp#ifdef SIG_WINDOW
98131962Smpvoid
99131962Smpcheck_window_size(force)
100131962Smp    int     force;
101131962Smp{
102131962Smp#ifdef BSDSIGS
103131962Smp    sigmask_t omask;
104131962Smp#endif /* BSDSIGS */
105131962Smp    int     lins, cols;
106131962Smp
107131962Smp    /* don't want to confuse things here */
108131962Smp#ifdef BSDSIGS
109131962Smp    omask = sigblock(sigmask(SIG_WINDOW)) & ~sigmask(SIG_WINDOW);
110131962Smp#else /* BSDSIGS */
111131962Smp    (void) sighold(SIG_WINDOW);
11283098Smp#endif /* BSDSIGS */
11383098Smp    /*
11459243Sobrien     * From: bret@shark.agps.lanl.gov (Bret Thaeler) Avoid sunview bug, where a
11583098Smp     * partially hidden window gets a SIG_WINDOW every time the text is
11659243Sobrien     * scrolled
11783098Smp     */
11859243Sobrien    if (GetSize(&lins, &cols) || force) {
11983098Smp	if (GettingInput) {
12059243Sobrien	    ClearLines();
12183098Smp	    ClearDisp();
12283098Smp	    MoveToLine(0);
12383098Smp	    MoveToChar(0);
12483098Smp	    ChangeSize(lins, cols);
12559243Sobrien	    Refresh();
126131962Smp	}
127131962Smp	else
128131962Smp	    ChangeSize(lins, cols);
129131962Smp    }
130131962Smp#ifdef BSDSIGS
131131962Smp    (void) sigsetmask(omask);	/* can change it again */
132131962Smp#else				/* BSDSIGS */
133131962Smp    (void) sigrelse(SIG_WINDOW);
134131962Smp#endif /* BSDSIGS */
135131962Smp}
136131962Smp
137131962Smpsigret_t
138131962Smp/*ARGSUSED*/
139131962Smpwindow_change(snum)
140131962Smpint snum;
14183098Smp{
142131962Smp#ifdef UNRELSIGS
143131962Smp    /* If we were called as a signal handler, restore it. */
14483098Smp    if (snum > 0)
14583098Smp      sigset(snum, window_change);
14683098Smp#endif /* UNRELSIGS */
14783098Smp    check_window_size(0);
14883098Smp#ifndef SIGVOID
14983098Smp    return (snum);
15083098Smp#endif
15183098Smp}
15283098Smp
15383098Smp#endif /* SIG_WINDOW */
15483098Smp
15583098Smpvoid
15683098Smped_set_tty_eight_bit()
15783098Smp{
15883098Smp    if (tty_getty(SHTTY, &extty) == -1) {
159131962Smp#ifdef DEBUG_TTY
160131962Smp	xprintf("ed_set_tty_eight_bit: tty_getty: %s\n", strerror(errno));
161131962Smp#endif /* DEBUG_TTY */
162131962Smp	return;
163131962Smp    }
164131962Smp    Tty_eight_bit = tty_geteightbit(&extty);
165131962Smp}
166131962Smp
167131962Smp
168131962Smpint
169131962Smped_Setup(rst)
170131962Smp    int rst;
171131962Smp{
172131962Smp    static int havesetup = 0;
173131962Smp    struct varent *imode;
174131962Smp
175131962Smp    if (havesetup) 	/* if we have never been called */
176131962Smp	return(0);
177131962Smp
178131962Smp#if defined(POSIX) && defined(_PC_VDISABLE) && !defined(BSD4_4) && \
179131962Smp    !defined(WINNT)
180131962Smp    {
181131962Smp	long pcret;
182131962Smp
183131962Smp	if ((pcret = fpathconf(SHTTY, _PC_VDISABLE)) == -1L)
184131962Smp	    vdisable = (unsigned char) _POSIX_VDISABLE;
185131962Smp	else
186131962Smp	    vdisable = (unsigned char) pcret;
187131962Smp	if (vdisable != (unsigned char) _POSIX_VDISABLE && rst != 0)
188131962Smp	    for (rst = 0; rst < C_NCC; rst++) {
189131962Smp		if (ttychars[ED_IO][rst] == (unsigned char) _POSIX_VDISABLE)
190131962Smp		    ttychars[ED_IO][rst] = vdisable;
191131962Smp		if (ttychars[EX_IO][rst] == (unsigned char) _POSIX_VDISABLE)
192131962Smp		    ttychars[EX_IO][rst] = vdisable;
193131962Smp	    }
194131962Smp    }
195131962Smp#else /* ! POSIX || !_PC_VDISABLE || BSD4_4 || WINNT */
196131962Smp    vdisable = (unsigned char) _POSIX_VDISABLE;
197131962Smp#endif /* POSIX && _PC_VDISABLE && !BSD4_4 && !WINNT */
198131962Smp
199131962Smp    if ((imode = adrof(STRinputmode)) != NULL) {
200131962Smp	if (!Strcmp(*(imode->vec), STRinsert))
201131962Smp	    inputmode = MODE_INSERT;
202131962Smp	else if (!Strcmp(*(imode->vec), STRoverwrite))
203131962Smp	    inputmode = MODE_REPLACE;
204131962Smp    }
205131962Smp    else
206131962Smp	inputmode = MODE_INSERT;
207131962Smp    ed_InitMaps();
208131962Smp    Hist_num = 0;
209131962Smp    Expand = 0;
210131962Smp
211131962Smp#ifndef WINNT
212131962Smp    if (tty_getty(SHTTY, &extty) == -1) {
213131962Smp# ifdef DEBUG_TTY
214131962Smp	xprintf("ed_Setup: tty_getty: %s\n", strerror(errno));
215131962Smp# endif /* DEBUG_TTY */
216131962Smp	return(-1);
217131962Smp    }
218131962Smp
219131962Smp    tstty = edtty = extty;
220131962Smp
221131962Smp    T_Speed = tty_getspeed(&extty);
222131962Smp    T_Tabs = tty_gettabs(&extty);
223131962Smp    Tty_eight_bit = tty_geteightbit(&extty);
224131962Smp
225131962Smp# if defined(POSIX) || defined(TERMIO)
226131962Smp    extty.d_t.c_iflag &= ~ttylist[EX_IO][M_INPUT].t_clrmask;
227131962Smp    extty.d_t.c_iflag |=  ttylist[EX_IO][M_INPUT].t_setmask;
228131962Smp
229131962Smp    extty.d_t.c_oflag &= ~ttylist[EX_IO][M_OUTPUT].t_clrmask;
230131962Smp    extty.d_t.c_oflag |=  ttylist[EX_IO][M_OUTPUT].t_setmask;
231131962Smp
232131962Smp    extty.d_t.c_cflag &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
233131962Smp    extty.d_t.c_cflag |=  ttylist[EX_IO][M_CONTROL].t_setmask;
234131962Smp
235131962Smp    extty.d_t.c_lflag &= ~ttylist[EX_IO][M_LINED].t_clrmask;
236131962Smp    extty.d_t.c_lflag |=  ttylist[EX_IO][M_LINED].t_setmask;
237131962Smp
238131962Smp#  if defined(IRIX3_3) && SYSVREL < 4
239131962Smp    extty.d_t.c_line = NTTYDISC;
240131962Smp#  endif /* IRIX3_3 && SYSVREL < 4 */
241131962Smp
242131962Smp# else	/* GSTTY */		/* V7, Berkeley style tty */
243131962Smp
244131962Smp    if (T_Tabs) {	/* order of &= and |= is important to XTABS */
245131962Smp	extty.d_t.sg_flags &= ~(ttylist[EX_IO][M_CONTROL].t_clrmask|XTABS);
246131962Smp	extty.d_t.sg_flags |=   ttylist[EX_IO][M_CONTROL].t_setmask;
247131962Smp    }
248131962Smp    else {
249131962Smp	extty.d_t.sg_flags &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
250131962Smp	extty.d_t.sg_flags |= (ttylist[EX_IO][M_CONTROL].t_setmask|XTABS);
251131962Smp    }
252131962Smp
253131962Smp    extty.d_lb &= ~ttylist[EX_IO][M_LOCAL].t_clrmask;
254131962Smp    extty.d_lb |=  ttylist[EX_IO][M_LOCAL].t_setmask;
255131962Smp
256131962Smp# endif /* GSTTY */
257131962Smp    /*
258131962Smp     * Reset the tty chars to reasonable defaults
259131962Smp     * If they are disabled, then enable them.
26083098Smp     */
26183098Smp    if (rst) {
262131962Smp	if (tty_cooked_mode(&tstty)) {
263131962Smp	    tty_getchar(&tstty, ttychars[TS_IO]);
264131962Smp	    /*
265131962Smp	     * Don't affect CMIN and CTIME for the editor mode
266131962Smp	     */
267131962Smp	    for (rst = 0; rst < C_NCC - 2; rst++)
268131962Smp		if (ttychars[TS_IO][rst] != vdisable &&
269131962Smp		    ttychars[ED_IO][rst] != vdisable)
270131962Smp		    ttychars[ED_IO][rst] = ttychars[TS_IO][rst];
271131962Smp	    for (rst = 0; rst < C_NCC; rst++)
272131962Smp		if (ttychars[TS_IO][rst] != vdisable &&
273131962Smp		    ttychars[EX_IO][rst] != vdisable)
274131962Smp		    ttychars[EX_IO][rst] = ttychars[TS_IO][rst];
275131962Smp	}
276131962Smp	tty_setchar(&extty, ttychars[EX_IO]);
277131962Smp	if (tty_setty(SHTTY, &extty) == -1) {
278131962Smp# ifdef DEBUG_TTY
279131962Smp	    xprintf("ed_Setup: tty_setty: %s\n", strerror(errno));
280131962Smp# endif /* DEBUG_TTY */
281131962Smp	    return(-1);
282131962Smp	}
283131962Smp    }
284131962Smp    else
285131962Smp	tty_setchar(&extty, ttychars[EX_IO]);
286131962Smp
287131962Smp# ifdef SIG_WINDOW
288131962Smp    (void) sigset(SIG_WINDOW, window_change);	/* for window systems */
289131962Smp# endif
290131962Smp#else /* WINNT */
291131962Smp# ifdef DEBUG
292131962Smp    if (rst)
293131962Smp	xprintf("rst received in ed_Setup() %d\n", rst);
294131962Smp# endif
295131962Smp#endif /* WINNT */
296131962Smp    havesetup = 1;
297131962Smp    return(0);
298131962Smp}
299131962Smp
300131962Smpvoid
301131962Smped_Init()
302131962Smp{
303131962Smp    ResetInLine(1);		/* reset the input pointers */
304131962Smp    GettingInput = 0;		/* just in case */
305131962Smp    LastKill = KillBuf;		/* no kill buffer */
30683098Smp
30783098Smp#ifdef DEBUG_EDIT
308131962Smp    CheckMaps();		/* do a little error checking on key maps */
30983098Smp#endif
310
311    if (ed_Setup(0) == -1)
312	return;
313
314    /*
315     * if we have been called before but GotTermCaps isn't set, our TERM has
316     * changed, so get new termcaps and try again
317     */
318
319    if (!GotTermCaps)
320	GetTermCaps();		/* does the obvious, but gets term type each
321				 * time */
322
323#ifndef WINNT
324# if defined(TERMIO) || defined(POSIX)
325    edtty.d_t.c_iflag &= ~ttylist[ED_IO][M_INPUT].t_clrmask;
326    edtty.d_t.c_iflag |=  ttylist[ED_IO][M_INPUT].t_setmask;
327
328    edtty.d_t.c_oflag &= ~ttylist[ED_IO][M_OUTPUT].t_clrmask;
329    edtty.d_t.c_oflag |=  ttylist[ED_IO][M_OUTPUT].t_setmask;
330
331    edtty.d_t.c_cflag &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
332    edtty.d_t.c_cflag |=  ttylist[ED_IO][M_CONTROL].t_setmask;
333
334    edtty.d_t.c_lflag &= ~ttylist[ED_IO][M_LINED].t_clrmask;
335    edtty.d_t.c_lflag |=  ttylist[ED_IO][M_LINED].t_setmask;
336
337
338#  if defined(IRIX3_3) && SYSVREL < 4
339    edtty.d_t.c_line = NTTYDISC;
340#  endif /* IRIX3_3 && SYSVREL < 4 */
341
342# else /* GSTTY */
343
344    if (T_Tabs) {	/* order of &= and |= is important to XTABS */
345	edtty.d_t.sg_flags &= ~(ttylist[ED_IO][M_CONTROL].t_clrmask | XTABS);
346	edtty.d_t.sg_flags |=   ttylist[ED_IO][M_CONTROL].t_setmask;
347    }
348    else {
349	edtty.d_t.sg_flags &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
350	edtty.d_t.sg_flags |= (ttylist[ED_IO][M_CONTROL].t_setmask | XTABS);
351    }
352
353    edtty.d_lb &= ~ttylist[ED_IO][M_LOCAL].t_clrmask;
354    edtty.d_lb |=  ttylist[ED_IO][M_LOCAL].t_setmask;
355# endif /* POSIX || TERMIO */
356
357    tty_setchar(&edtty, ttychars[ED_IO]);
358#endif /* WINNT */
359}
360
361/*
362 * Check and re-init the line. set the terminal into 1 char at a time mode.
363 */
364int
365Rawmode()
366{
367    if (Tty_raw_mode)
368	return (0);
369
370#ifdef WINNT
371    do_nt_raw_mode();
372#else /* !WINNT */
373# ifdef _IBMR2
374    tty_setdisc(SHTTY, ED_IO);
375# endif /* _IBMR2 */
376
377    if (tty_getty(SHTTY, &tstty) == -1) {
378# ifdef DEBUG_TTY
379	xprintf("Rawmode: tty_getty: %s\n", strerror(errno));
380# endif /* DEBUG_TTY */
381	return(-1);
382    }
383
384    /*
385     * We always keep up with the eight bit setting and the speed of the
386     * tty. But only we only believe changes that are made to cooked mode!
387     */
388# if defined(POSIX) || defined(TERMIO)
389    Tty_eight_bit = tty_geteightbit(&tstty);
390    T_Speed = tty_getspeed(&tstty);
391
392#  ifdef POSIX
393    /*
394     * Fix from: Steven (Steve) B. Green <xrsbg@charney.gsfc.nasa.gov>
395     * Speed was not being set up correctly under POSIX.
396     */
397    if (tty_getspeed(&extty) != T_Speed || tty_getspeed(&edtty) != T_Speed) {
398	(void) cfsetispeed(&extty.d_t, T_Speed);
399	(void) cfsetospeed(&extty.d_t, T_Speed);
400	(void) cfsetispeed(&edtty.d_t, T_Speed);
401	(void) cfsetospeed(&edtty.d_t, T_Speed);
402    }
403#  endif /* POSIX */
404# else /* GSTTY */
405
406    T_Speed = tty_getspeed(&tstty);
407    Tty_eight_bit = tty_geteightbit(&tstty);
408
409    if (extty.d_t.sg_ispeed != tstty.d_t.sg_ispeed) {
410	extty.d_t.sg_ispeed = tstty.d_t.sg_ispeed;
411	edtty.d_t.sg_ispeed = tstty.d_t.sg_ispeed;
412    }
413
414    if (extty.d_t.sg_ospeed != tstty.d_t.sg_ospeed) {
415	extty.d_t.sg_ospeed = tstty.d_t.sg_ospeed;
416	edtty.d_t.sg_ospeed = tstty.d_t.sg_ospeed;
417    }
418# endif /* POSIX || TERMIO */
419
420    if (tty_cooked_mode(&tstty)) {
421	/*
422	 * re-test for some things here (like maybe the user typed
423	 * "stty -tabs"
424	 */
425	if (tty_gettabs(&tstty) == 0)
426	    T_Tabs = 0;
427	else
428	    T_Tabs = CanWeTab();
429
430# if defined(POSIX) || defined(TERMIO)
431	extty.d_t.c_cflag  = tstty.d_t.c_cflag;
432	extty.d_t.c_cflag &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
433	extty.d_t.c_cflag |=  ttylist[EX_IO][M_CONTROL].t_setmask;
434
435	edtty.d_t.c_cflag  = tstty.d_t.c_cflag;
436	edtty.d_t.c_cflag &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
437	edtty.d_t.c_cflag |=  ttylist[ED_IO][M_CONTROL].t_setmask;
438
439	extty.d_t.c_lflag = tstty.d_t.c_lflag;
440	extty.d_t.c_lflag &= ~ttylist[EX_IO][M_LINED].t_clrmask;
441	extty.d_t.c_lflag |=  ttylist[EX_IO][M_LINED].t_setmask;
442
443	edtty.d_t.c_lflag = tstty.d_t.c_lflag;
444	edtty.d_t.c_lflag &= ~ttylist[ED_IO][M_LINED].t_clrmask;
445	edtty.d_t.c_lflag |=  ttylist[ED_IO][M_LINED].t_setmask;
446
447	extty.d_t.c_iflag = tstty.d_t.c_iflag;
448	extty.d_t.c_iflag &= ~ttylist[EX_IO][M_INPUT].t_clrmask;
449	extty.d_t.c_iflag |=  ttylist[EX_IO][M_INPUT].t_setmask;
450
451	edtty.d_t.c_iflag = tstty.d_t.c_iflag;
452	edtty.d_t.c_iflag &= ~ttylist[ED_IO][M_INPUT].t_clrmask;
453	edtty.d_t.c_iflag |=  ttylist[ED_IO][M_INPUT].t_setmask;
454
455	extty.d_t.c_oflag = tstty.d_t.c_oflag;
456	extty.d_t.c_oflag &= ~ttylist[EX_IO][M_OUTPUT].t_clrmask;
457	extty.d_t.c_oflag |=  ttylist[EX_IO][M_OUTPUT].t_setmask;
458
459	edtty.d_t.c_oflag = tstty.d_t.c_oflag;
460	edtty.d_t.c_oflag &= ~ttylist[ED_IO][M_OUTPUT].t_clrmask;
461	edtty.d_t.c_oflag |=  ttylist[ED_IO][M_OUTPUT].t_setmask;
462
463# else /* GSTTY */
464
465	extty.d_t.sg_flags = tstty.d_t.sg_flags;
466
467	extty.d_t.sg_flags &= ~ttylist[EX_IO][M_CONTROL].t_clrmask;
468	extty.d_t.sg_flags |=  ttylist[EX_IO][M_CONTROL].t_setmask;
469
470	if (T_Tabs)		/* order of &= and |= is important to XTABS */
471	    extty.d_t.sg_flags &= ~XTABS;
472	else
473	    extty.d_t.sg_flags |= XTABS;
474
475	extty.d_lb = tstty.d_lb;
476	extty.d_lb &= ~ttylist[EX_IO][M_LOCAL].t_clrmask;
477	extty.d_lb |= ttylist[EX_IO][M_LOCAL].t_setmask;
478
479	edtty.d_t.sg_flags = extty.d_t.sg_flags;
480	if (T_Tabs) {	/* order of &= and |= is important to XTABS */
481	    edtty.d_t.sg_flags &=
482		    ~(ttylist[ED_IO][M_CONTROL].t_clrmask|XTABS);
483	    edtty.d_t.sg_flags |=   ttylist[ED_IO][M_CONTROL].t_setmask;
484	}
485	else {
486	    edtty.d_t.sg_flags &= ~ttylist[ED_IO][M_CONTROL].t_clrmask;
487	    edtty.d_t.sg_flags |=
488		    (ttylist[ED_IO][M_CONTROL].t_setmask|XTABS);
489	}
490
491	edtty.d_lb = tstty.d_lb;
492	edtty.d_lb &= ~ttylist[ED_IO][M_LOCAL].t_clrmask;
493	edtty.d_lb |= ttylist[ED_IO][M_LOCAL].t_setmask;
494
495# endif /* TERMIO || POSIX */
496
497	{
498	    extern int didsetty;
499	    int i;
500
501	    tty_getchar(&tstty, ttychars[TS_IO]);
502	    /*
503	     * Check if the user made any changes.
504	     * If he did, then propagate the changes to the
505	     * edit and execute data structures.
506	     */
507	    for (i = 0; i < C_NCC; i++)
508		if (ttychars[TS_IO][i] != ttychars[EX_IO][i])
509		    break;
510
511	    if (i != C_NCC || didsetty) {
512		didsetty = 0;
513		/*
514		 * Propagate changes only to the unprotected chars
515		 * that have been modified just now.
516		 */
517		for (i = 0; i < C_NCC; i++) {
518		    if (!((ttylist[ED_IO][M_CHAR].t_setmask & C_SH(i))) &&
519			(ttychars[TS_IO][i] != ttychars[EX_IO][i]))
520			ttychars[ED_IO][i] = ttychars[TS_IO][i];
521		    if (ttylist[ED_IO][M_CHAR].t_clrmask & C_SH(i))
522			ttychars[ED_IO][i] = vdisable;
523		}
524		tty_setchar(&edtty, ttychars[ED_IO]);
525
526		for (i = 0; i < C_NCC; i++) {
527		    if (!((ttylist[EX_IO][M_CHAR].t_setmask & C_SH(i))) &&
528			(ttychars[TS_IO][i] != ttychars[EX_IO][i]))
529			ttychars[EX_IO][i] = ttychars[TS_IO][i];
530		    if (ttylist[EX_IO][M_CHAR].t_clrmask & C_SH(i))
531			ttychars[EX_IO][i] = vdisable;
532		}
533		tty_setchar(&extty, ttychars[EX_IO]);
534	    }
535
536	}
537    }
538    if (tty_setty(SHTTY, &edtty) == -1) {
539# ifdef DEBUG_TTY
540	xprintf("Rawmode: tty_setty: %s\n", strerror(errno));
541# endif /* DEBUG_TTY */
542	return(-1);
543    }
544#endif /* WINNT */
545    Tty_raw_mode = 1;
546    flush();			/* flush any buffered output */
547    return (0);
548}
549
550int
551Cookedmode()
552{				/* set tty in normal setup */
553#ifdef WINNT
554    do_nt_cooked_mode();
555#else
556    signalfun_t orig_intr;
557
558# ifdef _IBMR2
559    tty_setdisc(SHTTY, EX_IO);
560# endif /* _IBMR2 */
561
562    if (!Tty_raw_mode)
563	return (0);
564
565    /* hold this for reseting tty */
566# ifdef BSDSIGS
567    orig_intr = (signalfun_t) signal(SIGINT, SIG_IGN);
568# else
569#  ifdef SIG_HOLD
570    /*
571     * sigset doesn't return the previous handler if the signal is held,
572     * it will return SIG_HOLD instead. So instead of restoring the
573     * the signal we would end up installing a blocked SIGINT with a
574     * SIG_IGN signal handler. This is what happened when Cookedmode
575     * was called from sched_run, disabling interrupt for the rest
576     * of your session.
577     *
578     * This is what we do:
579     * - if the signal is blocked, keep it that way
580     * - else set it to SIG_IGN
581     *
582     * Casper Dik (casper@fwi.uva.nl)
583     */
584    orig_intr = (signalfun_t) sigset(SIGINT, SIG_HOLD);
585    if (orig_intr != SIG_HOLD)
586	(void) sigset(SIGINT, SIG_IGN); /* returns SIG_HOLD */
587#  else /* !SIG_HOLD */
588    /*
589     * No SIG_HOLD; probably no reliable signals as well.
590     */
591    orig_intr = (signalfun_t) sigset(SIGINT, SIG_IGN);
592#  endif /* SIG_HOLD */
593# endif /* BSDSIGS */
594    if (tty_setty(SHTTY, &extty) == -1) {
595# ifdef DEBUG_TTY
596	xprintf("Cookedmode: tty_setty: %s\n", strerror(errno));
597# endif /* DEBUG_TTY */
598	return -1;
599    }
600# ifdef BSDSIGS
601    (void) signal(SIGINT, orig_intr);	/* take these again */
602# else
603    (void) sigset(SIGINT, orig_intr);	/* take these again */
604# endif /* BSDSIGS */
605#endif /* WINNT */
606
607    Tty_raw_mode = 0;
608    return (0);
609}
610
611void
612ResetInLine(macro)
613    int macro;
614{
615    Cursor = InputBuf;		/* reset cursor */
616    LastChar = InputBuf;
617    InputLim = &InputBuf[INBUFSIZE - 2];
618    Mark = InputBuf;
619    MetaNext = 0;
620    CurrentKeyMap = CcKeyMap;
621    AltKeyMap = 0;
622    Hist_num = 0;
623    DoingArg = 0;
624    Argument = 1;
625#ifdef notdef
626    LastKill = KillBuf;		/* no kill buffer */
627#endif
628    LastCmd = F_UNASSIGNED;	/* previous command executed */
629    if (macro)
630	MacroLvl = -1;		/* no currently active macros */
631}
632
633static Char *Input_Line = NULL;
634int
635Load_input_line()
636{
637#ifdef SUNOS4
638    long chrs = 0;
639#else /* !SUNOS4 */
640    /*
641     * *Everyone* else has an int, but SunOS wants long!
642     * This breaks where int != long (alpha)
643     */
644    int chrs = 0;
645#endif /* SUNOS4 */
646
647    if (Input_Line)
648	xfree((ptr_t) Input_Line);
649    Input_Line = NULL;
650
651    if (Tty_raw_mode)
652	return 0;
653
654#if defined(FIONREAD) && !defined(OREO)
655    (void) ioctl(SHIN, FIONREAD, (ioctl_t) &chrs);
656    if (chrs > 0) {
657	char    buf[BUFSIZE];
658
659	chrs = read(SHIN, buf, (size_t) min(chrs, BUFSIZE - 1));
660	if (chrs > 0) {
661	    buf[chrs] = '\0';
662	    Input_Line = Strsave(str2short(buf));
663	    PushMacro(Input_Line);
664	}
665#ifdef convex
666        /* need to print errno message in case file is migrated */
667        if (chrs < 0)
668            stderror(ERR_SYSTEM, progname, strerror(errno));
669#endif
670    }
671#endif  /* FIONREAD && !OREO */
672    return chrs > 0;
673}
674
675/*
676 * Bugfix (in Swedish) by:
677 * Johan Widen
678 * SICS, PO Box 1263, S-163 13 SPANGA, SWEDEN
679 * {mcvax,munnari,cernvax,diku,inria,prlb2,penet,ukc,unido}!enea!sics.se!jw
680 * Internet: jw@sics.se
681 *
682 * (via Hans J Albertsson (thanks))
683 */
684void
685QuoteModeOn()
686{
687    if (MacroLvl >= 0)
688	return;
689
690#ifndef WINNT
691    qutty = edtty;
692
693#if defined(TERMIO) || defined(POSIX)
694    qutty.d_t.c_iflag &= ~ttylist[QU_IO][M_INPUT].t_clrmask;
695    qutty.d_t.c_iflag |=  ttylist[QU_IO][M_INPUT].t_setmask;
696
697    qutty.d_t.c_oflag &= ~ttylist[QU_IO][M_OUTPUT].t_clrmask;
698    qutty.d_t.c_oflag |=  ttylist[QU_IO][M_OUTPUT].t_setmask;
699
700    qutty.d_t.c_cflag &= ~ttylist[QU_IO][M_CONTROL].t_clrmask;
701    qutty.d_t.c_cflag |=  ttylist[QU_IO][M_CONTROL].t_setmask;
702
703    qutty.d_t.c_lflag &= ~ttylist[QU_IO][M_LINED].t_clrmask;
704    qutty.d_t.c_lflag |=  ttylist[QU_IO][M_LINED].t_setmask;
705#else /* GSTTY */
706    qutty.d_t.sg_flags &= ~ttylist[QU_IO][M_CONTROL].t_clrmask;
707    qutty.d_t.sg_flags |= ttylist[QU_IO][M_CONTROL].t_setmask;
708    qutty.d_lb &= ~ttylist[QU_IO][M_LOCAL].t_clrmask;
709    qutty.d_lb |= ttylist[QU_IO][M_LOCAL].t_setmask;
710
711#endif /* TERMIO || POSIX */
712    if (tty_setty(SHTTY, &qutty) == -1) {
713#ifdef DEBUG_TTY
714	xprintf("QuoteModeOn: tty_setty: %s\n", strerror(errno));
715#endif /* DEBUG_TTY */
716	return;
717    }
718#endif /* !WINNT */
719    Tty_quote_mode = 1;
720    return;
721}
722
723void
724QuoteModeOff()
725{
726    if (!Tty_quote_mode)
727	return;
728    Tty_quote_mode = 0;
729    if (tty_setty(SHTTY, &edtty) == -1) {
730#ifdef DEBUG_TTY
731	xprintf("QuoteModeOff: tty_setty: %s\n", strerror(errno));
732#endif /* DEBUG_TTY */
733	return;
734    }
735    return;
736}
737