init_disp.c revision 87710
138451Smsmith/*
238451Smsmith * Copyright (c) 1983, 1993
338451Smsmith *	The Regents of the University of California.  All rights reserved.
438451Smsmith *
538451Smsmith * Redistribution and use in source and binary forms, with or without
638451Smsmith * modification, are permitted provided that the following conditions
738451Smsmith * are met:
838451Smsmith * 1. Redistributions of source code must retain the above copyright
938451Smsmith *    notice, this list of conditions and the following disclaimer.
1038451Smsmith * 2. Redistributions in binary form must reproduce the above copyright
1138451Smsmith *    notice, this list of conditions and the following disclaimer in the
1238451Smsmith *    documentation and/or other materials provided with the distribution.
1338451Smsmith * 3. All advertising materials mentioning features or use of this software
1438451Smsmith *    must display the following acknowledgement:
1538451Smsmith *	This product includes software developed by the University of
1638451Smsmith *	California, Berkeley and its contributors.
1738451Smsmith * 4. Neither the name of the University nor the names of its contributors
1838451Smsmith *    may be used to endorse or promote products derived from this software
1938451Smsmith *    without specific prior written permission.
2038451Smsmith *
2138451Smsmith * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2238451Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2338451Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2438451Smsmith * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2538451Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2638451Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2738451Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2838451Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2938451Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3038451Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3138451Smsmith * SUCH DAMAGE.
3238451Smsmith */
3338451Smsmith
3438451Smsmith#include <sys/cdefs.h>
3538451Smsmith
3638451Smsmith__FBSDID("$FreeBSD: head/usr.bin/talk/init_disp.c 87710 2001-12-11 23:51:14Z markm $");
3738451Smsmith
3884221Sdillon#ifndef lint
3984221Sdillonstatic const char sccsid[] = "@(#)init_disp.c	8.2 (Berkeley) 2/16/94";
4084221Sdillon#endif
4138451Smsmith
4238451Smsmith/*
4338451Smsmith * Initialization code for the display package,
4438451Smsmith * as well as the signal handling routines.
4538451Smsmith */
4638451Smsmith
4738451Smsmith#include <sys/stat.h>
4838451Smsmith
4938451Smsmith#include <err.h>
5038451Smsmith#include <signal.h>
51221364Srodrigc#include <stdlib.h>
5238451Smsmith#include <unistd.h>
5338451Smsmith#include <termios.h>
5438451Smsmith
5538451Smsmith#include "talk.h"
5638451Smsmith
5738451Smsmith/*
5838451Smsmith * Make sure the callee can write to the screen
5938451Smsmith */
6038451Smsmithvoid
6138451Smsmithcheck_writeable()
6238451Smsmith{
6338451Smsmith	char *tty;
6438451Smsmith	struct stat sb;
6538451Smsmith
6638451Smsmith	if ((tty = ttyname(STDERR_FILENO)) == NULL)
6738451Smsmith		err(1, "ttyname");
6838451Smsmith	if (stat(tty, &sb) < 0)
6938451Smsmith		err(1, "%s", tty);
7038451Smsmith	if (!(sb.st_mode & S_IWGRP))
7138451Smsmith		errx(1, "The callee cannot write to this terminal, use \"mesg y\".");
72197178Semaste}
73197178Semaste
74197178Semaste/*
75197178Semaste * Set up curses, catch the appropriate signals,
76197178Semaste * and build the various windows.
7738451Smsmith */
7892913Sobrienvoid
7992913Sobrieninit_display()
8038451Smsmith{
8138451Smsmith	struct sigaction sa;
8238451Smsmith
8338451Smsmith	if (initscr() == NULL)
8438451Smsmith		errx(1, "Terminal type unset or lacking necessary features.");
8538451Smsmith	(void) sigaction(SIGTSTP, (struct sigaction *)0, &sa);
8638451Smsmith	sigaddset(&sa.sa_mask, SIGALRM);
8738451Smsmith	(void) sigaction(SIGTSTP, &sa, (struct sigaction *)0);
88197178Semaste	curses_initialized = 1;
89197178Semaste	clear();
9038451Smsmith	refresh();
9138451Smsmith	noecho();
9238451Smsmith	crmode();
9338451Smsmith	signal(SIGINT, sig_sent);
9438451Smsmith	signal(SIGPIPE, sig_sent);
9538451Smsmith	/* curses takes care of ^Z */
9638451Smsmith	my_win.x_nlines = LINES / 2;
9738451Smsmith	my_win.x_ncols = COLS;
9838451Smsmith	my_win.x_win = newwin(my_win.x_nlines, my_win.x_ncols, 0, 0);
99146835Sjhb	idlok(my_win.x_win, TRUE);
10038451Smsmith	scrollok(my_win.x_win, TRUE);
10138451Smsmith	wclear(my_win.x_win);
10238451Smsmith
10338451Smsmith	his_win.x_nlines = LINES / 2 - 1;
10438451Smsmith	his_win.x_ncols = COLS;
10538451Smsmith	his_win.x_win = newwin(his_win.x_nlines, his_win.x_ncols,
10638451Smsmith	    my_win.x_nlines+1, 0);
10738451Smsmith	idlok(my_win.x_win, TRUE);
10838451Smsmith	scrollok(his_win.x_win, TRUE);
109197178Semaste	wclear(his_win.x_win);
110197178Semaste
11138451Smsmith	line_win = newwin(1, COLS, my_win.x_nlines, 0);
11238451Smsmith#if defined(hline) || defined(whline) || defined(NCURSES_VERSION)
11338451Smsmith	whline(line_win, 0, COLS);
11438451Smsmith#else
11538451Smsmith	box(line_win, '-', '-');
11638451Smsmith#endif
11738451Smsmith	wrefresh(line_win);
11838451Smsmith	/* let them know we are working on it */
11938451Smsmith	current_state = "No connection yet";
12038451Smsmith}
12138451Smsmith
12238451Smsmith/*
12338451Smsmith * Trade edit characters with the other talk. By agreement
12438451Smsmith * the first three characters each talk transmits after
12538451Smsmith * connection are the three edit characters.
12638451Smsmith */
12738451Smsmithvoid
12838451Smsmithset_edit_chars()
12938451Smsmith{
13038451Smsmith	char buf[3];
13138451Smsmith	int cc;
13238451Smsmith	struct termios tio;
13338451Smsmith
13438451Smsmith	tcgetattr(0, &tio);
13538451Smsmith	my_win.cerase = tio.c_cc[VERASE];
136197178Semaste	my_win.kill = tio.c_cc[VKILL];
13738451Smsmith	my_win.werase = tio.c_cc[VWERASE];
13892913Sobrien	if (my_win.cerase == (char)_POSIX_VDISABLE)
13992913Sobrien		my_win.kill = CERASE;
14092913Sobrien	if (my_win.kill == (char)_POSIX_VDISABLE)
14138451Smsmith		my_win.kill = CKILL;
14292913Sobrien	if (my_win.werase == (char)_POSIX_VDISABLE)
14338451Smsmith		my_win.werase = CWERASE;
14438451Smsmith	buf[0] = my_win.cerase;
14538451Smsmith	buf[1] = my_win.kill;
14638451Smsmith	buf[2] = my_win.werase;
14738451Smsmith	cc = write(sockt, buf, sizeof(buf));
14838451Smsmith	if (cc != sizeof(buf) )
14938451Smsmith		p_error("Lost the connection");
15038451Smsmith	cc = read(sockt, buf, sizeof(buf));
15138451Smsmith	if (cc != sizeof(buf) )
15238451Smsmith		p_error("Lost the connection");
15338451Smsmith	his_win.cerase = buf[0];
15438451Smsmith	his_win.kill = buf[1];
15538451Smsmith	his_win.werase = buf[2];
15638451Smsmith}
15738451Smsmith
15838451Smsmith/* ARGSUSED */
15938451Smsmithvoid
16038451Smsmithsig_sent(signo)
16138451Smsmith	int signo __unused;
16238451Smsmith{
16338451Smsmith
16438451Smsmith	message("Connection closing. Exiting");
16538451Smsmith	quit();
16638451Smsmith}
16738451Smsmith
16838451Smsmith/*
16938451Smsmith * All done talking...hang up the phone and reset terminal thingy's
17038451Smsmith */
17138451Smsmithvoid
17238451Smsmithquit()
17338451Smsmith{
17438451Smsmith
17538451Smsmith	if (curses_initialized) {
17638451Smsmith		wmove(his_win.x_win, his_win.x_nlines-1, 0);
17738451Smsmith		wclrtoeol(his_win.x_win);
17838451Smsmith		wrefresh(his_win.x_win);
17938451Smsmith		endwin();
18038451Smsmith	}
18138451Smsmith	if (invitation_waiting)
18238451Smsmith		send_delete();
18338451Smsmith	exit(0);
18438451Smsmith}
18538451Smsmith