1/*	$OpenBSD: init_disp.c,v 1.23 2019/06/28 13:35:04 deraadt Exp $	*/
2/*	$NetBSD: init_disp.c,v 1.6 1994/12/09 02:14:17 jtc Exp $	*/
3
4/*
5 * Copyright (c) 1983, 1993
6 *	The Regents of the University of California.  All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33/*
34 * Initialization code for the display package,
35 * as well as the signal handling routines.
36 */
37
38#include <sys/ioctl.h>
39
40#include <err.h>
41#include <stdlib.h>
42#include <termios.h>
43#include <unistd.h>
44
45#include "talk.h"
46
47/*
48 * Set up curses, catch the appropriate signals,
49 * and build the various windows.
50 */
51void
52init_display(void)
53{
54	struct sigaction sa;
55
56	if (initscr() == NULL)
57		errx(1, "Terminal type unset or lacking necessary features.");
58	(void) sigaction(SIGTSTP, NULL, &sa);
59	sigaddset(&sa.sa_mask, SIGALRM);
60	(void) sigaction(SIGTSTP, &sa, NULL);
61	curses_initialized = 1;
62	clear();
63	refresh();
64	noecho();
65	cbreak();
66	signal(SIGINT, sig_sent);
67	signal(SIGPIPE, sig_sent);
68	signal(SIGWINCH, sig_winch);
69	/* curses takes care of ^Z */
70	my_win.x_nlines = LINES / 2;
71	my_win.x_ncols = COLS;
72	my_win.x_win = newwin(my_win.x_nlines, my_win.x_ncols, 0, 0);
73	scrollok(my_win.x_win, smooth_scroll);
74	wclear(my_win.x_win);
75
76	his_win.x_nlines = LINES / 2 - 1;
77	his_win.x_ncols = COLS;
78	his_win.x_win = newwin(his_win.x_nlines, his_win.x_ncols,
79	    my_win.x_nlines+1, 0);
80	scrollok(his_win.x_win, smooth_scroll);
81	wclear(his_win.x_win);
82
83	line_win = newwin(1, COLS, my_win.x_nlines, 0);
84#if defined(NCURSES_VERSION) || defined(whline)
85	whline(line_win, '-', COLS);
86#else
87	box(line_win, '-', '-');
88#endif
89	wrefresh(line_win);
90	/* let them know we are working on it */
91	current_state = "No connection yet";
92}
93
94/*
95 * Trade edit characters with the other talk. By agreement
96 * the first three characters each talk transmits after
97 * connection are the three edit characters.
98 */
99void
100set_edit_chars(void)
101{
102	u_char buf[3];
103	int cc;
104	struct termios tty;
105
106	tcgetattr(STDIN_FILENO, &tty);
107	buf[0] = my_win.cerase = (tty.c_cc[VERASE] == (u_char)_POSIX_VDISABLE)
108	    ? CERASE : tty.c_cc[VERASE];
109	buf[1] = my_win.kill = (tty.c_cc[VKILL] == (u_char)_POSIX_VDISABLE)
110	    ? CKILL : tty.c_cc[VKILL];
111	buf[2] = my_win.werase = (tty.c_cc[VWERASE] == (u_char)_POSIX_VDISABLE)
112	    ? CWERASE : tty.c_cc[VWERASE];
113	cc = write(sockt, buf, sizeof(buf));
114	if (cc != sizeof(buf) )
115		quit("Lost the connection", 1);
116	cc = read(sockt, buf, sizeof(buf));
117	if (cc != sizeof(buf) )
118		quit("Lost the connection", 1);
119	his_win.cerase = buf[0];
120	his_win.kill = buf[1];
121	his_win.werase = buf[2];
122}
123
124void
125sig_sent(int dummy)
126{
127
128	quit("Connection closing.  Exiting", 0);
129}
130
131void
132sig_winch(int dummy)
133{
134
135	gotwinch = 1;
136}
137
138/*
139 * All done talking...hang up the phone and reset terminal thingy's
140 */
141void
142quit(char *warning, int do_perror)
143{
144
145	if (curses_initialized) {
146		wmove(his_win.x_win, his_win.x_nlines-1, 0);
147		wclrtoeol(his_win.x_win);
148		wrefresh(his_win.x_win);
149		endwin();
150	}
151	if (invitation_waiting)
152		send_delete();
153	if (warning) {
154		if (do_perror)
155			warn("%s", warning);
156		else
157			warnx("%s", warning);
158	}
159	exit(0);
160}
161
162/*
163 * If we get SIGWINCH, recompute both window sizes and refresh things.
164 */
165void
166resize_display(void)
167{
168	struct winsize ws;
169
170	if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1 ||
171	    (ws.ws_row == LINES && ws.ws_col == COLS))
172		return;
173
174	/* Update curses' internal state with new window size. */
175	resizeterm(ws.ws_row, ws.ws_col);
176
177	/*
178	 * Resize each window but wait to refresh the screen until
179	 * everything has been drawn so the cursor is in the right spot.
180	 */
181	my_win.x_nlines = LINES / 2;
182	my_win.x_ncols = COLS;
183	wresize(my_win.x_win, my_win.x_nlines, my_win.x_ncols);
184	mvwin(my_win.x_win, 0, 0);
185	clearok(my_win.x_win, TRUE);
186
187	his_win.x_nlines = LINES / 2 - 1;
188	his_win.x_ncols = COLS;
189	wresize(his_win.x_win, his_win.x_nlines, his_win.x_ncols);
190	mvwin(his_win.x_win, my_win.x_nlines + 1, 0);
191	clearok(his_win.x_win, TRUE);
192
193	wresize(line_win, 1, COLS);
194	mvwin(line_win, my_win.x_nlines, 0);
195#if defined(NCURSES_VERSION) || defined(whline)
196	whline(line_win, '-', COLS);
197#else
198	wmove(line_win, my_win.x_nlines, 0);
199	box(line_win, '-', '-');
200#endif
201
202	/* Now redraw the screen. */
203	wrefresh(his_win.x_win);
204	wrefresh(line_win);
205	wrefresh(my_win.x_win);
206}
207