Initial import of binutils 2.22 on the new vendor branch
[dragonfly.git] / usr.bin / talk / init_disp.c
1 /*
2  * Copyright (c) 1983, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by the University of
16  *      California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * @(#)init_disp.c      8.2 (Berkeley) 2/16/94
34  * $FreeBSD: src/usr.bin/talk/init_disp.c,v 1.11.2.1 2001/07/30 10:31:29 dd Exp $
35  */
36
37 /*
38  * Initialization code for the display package,
39  * as well as the signal handling routines.
40  */
41
42 #include <err.h>
43 #include <signal.h>
44 #include <stdlib.h>
45 #include <sys/stat.h>
46 #include <unistd.h>
47 #include <termios.h>
48 #include "talk.h"
49
50 /*
51  * Make sure the callee can write to the screen
52  */
53 void
54 check_writeable(void)
55 {
56         char *tty;
57         struct stat sb;
58
59         if ((tty = ttyname(STDERR_FILENO)) == NULL)
60                 err(1, "ttyname");
61         if (stat(tty, &sb) < 0)
62                 err(1, "%s", tty);
63         if (!(sb.st_mode & S_IWGRP))
64                 errx(1, "The callee cannot write to this terminal, use \"mesg y\".");
65 }
66
67 /*
68  * Set up curses, catch the appropriate signals,
69  * and build the various windows.
70  */
71 void
72 init_display(void)
73 {
74         struct sigaction sa;
75
76         if (initscr() == NULL)
77                 errx(1, "Terminal type unset or lacking necessary features.");
78         (void) sigaction(SIGTSTP, NULL, &sa);
79         sigaddset(&sa.sa_mask, SIGALRM);
80         (void) sigaction(SIGTSTP, &sa, NULL);
81         curses_initialized = 1;
82         clear();
83         refresh();
84         noecho();
85         crmode();
86         signal(SIGINT, sig_sent);
87         signal(SIGPIPE, sig_sent);
88         /* curses takes care of ^Z */
89         my_win.x_nlines = LINES / 2;
90         my_win.x_ncols = COLS;
91         my_win.x_win = newwin(my_win.x_nlines, my_win.x_ncols, 0, 0);
92         idlok(my_win.x_win, TRUE);
93         scrollok(my_win.x_win, TRUE);
94         wclear(my_win.x_win);
95
96         his_win.x_nlines = LINES / 2 - 1;
97         his_win.x_ncols = COLS;
98         his_win.x_win = newwin(his_win.x_nlines, his_win.x_ncols,
99             my_win.x_nlines+1, 0);
100         idlok(my_win.x_win, TRUE);
101         scrollok(his_win.x_win, TRUE);
102         wclear(his_win.x_win);
103
104         line_win = newwin(1, COLS, my_win.x_nlines, 0);
105 #if defined(hline) || defined(whline) || defined(NCURSES_VERSION)
106         whline(line_win, 0, COLS);
107 #else
108         box(line_win, '-', '-');
109 #endif
110         wrefresh(line_win);
111         /* let them know we are working on it */
112         current_state = "No connection yet";
113 }
114
115 /*
116  * Trade edit characters with the other talk. By agreement
117  * the first three characters each talk transmits after
118  * connection are the three edit characters.
119  */
120 void
121 set_edit_chars(void)
122 {
123         char buf[3];
124         int cc;
125         struct termios tio;
126
127         tcgetattr(0, &tio);
128         my_win.cerase = tio.c_cc[VERASE];
129         my_win.kill = tio.c_cc[VKILL];
130         my_win.werase = tio.c_cc[VWERASE];
131         if (my_win.cerase == (char)_POSIX_VDISABLE)
132                 my_win.kill = CERASE;
133         if (my_win.kill == (char)_POSIX_VDISABLE)
134                 my_win.kill = CKILL;
135         if (my_win.werase == (char)_POSIX_VDISABLE)
136                 my_win.werase = CWERASE;
137         buf[0] = my_win.cerase;
138         buf[1] = my_win.kill;
139         buf[2] = my_win.werase;
140         cc = write(sockt, buf, sizeof(buf));
141         if (cc != sizeof(buf) )
142                 p_error("Lost the connection");
143         cc = read(sockt, buf, sizeof(buf));
144         if (cc != sizeof(buf) )
145                 p_error("Lost the connection");
146         his_win.cerase = buf[0];
147         his_win.kill = buf[1];
148         his_win.werase = buf[2];
149 }
150
151 /* ARGSUSED */
152 void
153 sig_sent(int signo __unused)
154 {
155
156         message("Connection closing. Exiting");
157         quit();
158 }
159
160 /*
161  * All done talking...hang up the phone and reset terminal thingy's
162  */
163 void
164 quit(void)
165 {
166
167         if (curses_initialized) {
168                 wmove(his_win.x_win, his_win.x_nlines-1, 0);
169                 wclrtoeol(his_win.x_win);
170                 wrefresh(his_win.x_win);
171                 endwin();
172         }
173         if (invitation_waiting)
174                 send_delete();
175         exit(0);
176 }