]> git.cameronkatri.com Git - apple_cmds.git/blob - remote_cmds/talk.tproj/init_disp.c
download.sh: Fix tar extract
[apple_cmds.git] / remote_cmds / talk.tproj / 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
34 #include <sys/cdefs.h>
35
36 #ifndef __APPLE__
37 __FBSDID("$FreeBSD: src/usr.bin/talk/init_disp.c,v 1.14 2004/04/19 21:37:28 cognet Exp $");
38
39 #ifndef lint
40 static const char sccsid[] = "@(#)init_disp.c 8.2 (Berkeley) 2/16/94";
41 #endif
42 #endif /* __APPLE__ */
43
44 /*
45 * Initialization code for the display package,
46 * as well as the signal handling routines.
47 */
48
49 #include <sys/stat.h>
50 #ifdef __APPLE__
51 #include <sys/ioctl.h>
52 #endif
53
54 #include <err.h>
55 #include <signal.h>
56 #include <stdlib.h>
57 #include <unistd.h>
58 #include <termios.h>
59
60 #include "talk.h"
61
62 extern volatile sig_atomic_t gotwinch;
63
64 /*
65 * Make sure the callee can write to the screen
66 */
67 void
68 check_writeable()
69 {
70 char *tty;
71 struct stat sb;
72
73 if ((tty = ttyname(STDERR_FILENO)) == NULL)
74 err(1, "ttyname");
75 if (stat(tty, &sb) < 0)
76 err(1, "%s", tty);
77 if (!(sb.st_mode & S_IWGRP))
78 errx(1, "The callee cannot write to this terminal, use \"mesg y\".");
79 }
80
81 /*
82 * Set up curses, catch the appropriate signals,
83 * and build the various windows.
84 */
85 void
86 init_display()
87 {
88 struct sigaction sa;
89
90 if (initscr() == NULL)
91 errx(1, "Terminal type unset or lacking necessary features.");
92 (void) sigaction(SIGTSTP, (struct sigaction *)0, &sa);
93 sigaddset(&sa.sa_mask, SIGALRM);
94 (void) sigaction(SIGTSTP, &sa, (struct sigaction *)0);
95 curses_initialized = 1;
96 clear();
97 refresh();
98 noecho();
99 crmode();
100 signal(SIGINT, sig_sent);
101 signal(SIGPIPE, sig_sent);
102 signal(SIGWINCH, sig_winch);
103 /* curses takes care of ^Z */
104 my_win.x_nlines = LINES / 2;
105 my_win.x_ncols = COLS;
106 my_win.x_win = newwin(my_win.x_nlines, my_win.x_ncols, 0, 0);
107 idlok(my_win.x_win, TRUE);
108 scrollok(my_win.x_win, TRUE);
109 wclear(my_win.x_win);
110
111 his_win.x_nlines = LINES / 2 - 1;
112 his_win.x_ncols = COLS;
113 his_win.x_win = newwin(his_win.x_nlines, his_win.x_ncols,
114 my_win.x_nlines+1, 0);
115 idlok(my_win.x_win, TRUE);
116 scrollok(his_win.x_win, TRUE);
117 wclear(his_win.x_win);
118
119 line_win = newwin(1, COLS, my_win.x_nlines, 0);
120 #if defined(hline) || defined(whline) || defined(NCURSES_VERSION)
121 whline(line_win, 0, COLS);
122 #else
123 box(line_win, '-', '-');
124 #endif
125 wrefresh(line_win);
126 /* let them know we are working on it */
127 current_state = "No connection yet";
128 }
129
130 /*
131 * Trade edit characters with the other talk. By agreement
132 * the first three characters each talk transmits after
133 * connection are the three edit characters.
134 */
135 void
136 set_edit_chars()
137 {
138 char buf[3];
139 int cc;
140 struct termios tio;
141
142 tcgetattr(0, &tio);
143 my_win.cerase = tio.c_cc[VERASE];
144 my_win.kill = tio.c_cc[VKILL];
145 my_win.werase = tio.c_cc[VWERASE];
146 if (my_win.cerase == (char)_POSIX_VDISABLE)
147 my_win.kill = CERASE;
148 if (my_win.kill == (char)_POSIX_VDISABLE)
149 my_win.kill = CKILL;
150 if (my_win.werase == (char)_POSIX_VDISABLE)
151 my_win.werase = CWERASE;
152 buf[0] = my_win.cerase;
153 buf[1] = my_win.kill;
154 buf[2] = my_win.werase;
155 cc = write(sockt, buf, sizeof(buf));
156 if (cc != sizeof(buf) )
157 p_error("Lost the connection");
158 cc = read(sockt, buf, sizeof(buf));
159 if (cc != sizeof(buf) )
160 p_error("Lost the connection");
161 his_win.cerase = buf[0];
162 his_win.kill = buf[1];
163 his_win.werase = buf[2];
164 }
165
166 /* ARGSUSED */
167 void
168 sig_sent(signo)
169 int signo __unused;
170 {
171
172 message("Connection closing. Exiting");
173 quit();
174 }
175
176 void
177 sig_winch(int dummy)
178 {
179
180 gotwinch = 1;
181 }
182
183 /*
184 * All done talking...hang up the phone and reset terminal thingy's
185 */
186 void
187 quit()
188 {
189
190 if (curses_initialized) {
191 wmove(his_win.x_win, his_win.x_nlines-1, 0);
192 wclrtoeol(his_win.x_win);
193 wrefresh(his_win.x_win);
194 endwin();
195 }
196 if (invitation_waiting)
197 send_delete();
198 exit(0);
199 }
200
201 /*
202 * If we get SIGWINCH, recompute both window sizes and refresh things.
203 */
204 void
205 resize_display(void)
206 {
207 struct winsize ws;
208
209 if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) < 0 ||
210 (ws.ws_row == LINES && ws.ws_col == COLS))
211 return;
212
213 /* Update curses' internal state with new window size. */
214 resizeterm(ws.ws_row, ws.ws_col);
215
216 /*
217 * Resize each window but wait to refresh the screen until
218 * everything has been drawn so the cursor is in the right spot.
219 */
220 my_win.x_nlines = LINES / 2;
221 my_win.x_ncols = COLS;
222 wresize(my_win.x_win, my_win.x_nlines, my_win.x_ncols);
223 mvwin(my_win.x_win, 0, 0);
224 clearok(my_win.x_win, TRUE);
225
226 his_win.x_nlines = LINES / 2 - 1;
227 his_win.x_ncols = COLS;
228 wresize(his_win.x_win, his_win.x_nlines, his_win.x_ncols);
229 mvwin(his_win.x_win, my_win.x_nlines + 1, 0);
230 clearok(his_win.x_win, TRUE);
231
232 wresize(line_win, 1, COLS);
233 mvwin(line_win, my_win.x_nlines, 0);
234 #if defined(NCURSES_VERSION) || defined(whline)
235 whline(line_win, '-', COLS);
236 #else
237 wmove(line_win, my_win.x_nlines, 0);
238 box(line_win, '-', '-');
239 #endif
240
241 /* Now redraw the screen. */
242 wrefresh(his_win.x_win);
243 wrefresh(line_win);
244 wrefresh(my_win.x_win);
245 }