| 1 |  |  | /*	$OpenBSD: init_disp.c,v 1.22 2016/02/01 07:29:25 mestre 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 |  |  |  */ | 
    
    | 51 |  |  | void | 
    
    | 52 |  |  | init_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 |  |  |  */ | 
    
    | 99 |  |  | void | 
    
    | 100 |  |  | set_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 |  |  |  | 
    
    | 124 |  |  | void | 
    
    | 125 |  |  | sig_sent(int dummy) | 
    
    | 126 |  |  | { | 
    
    | 127 |  |  |  | 
    
    | 128 |  |  | 	quit("Connection closing.  Exiting", 0); | 
    
    | 129 |  |  | } | 
    
    | 130 |  |  |  | 
    
    | 131 |  |  | void | 
    
    | 132 |  |  | sig_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 |  |  |  */ | 
    
    | 141 |  |  | void | 
    
    | 142 |  |  | quit(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 |  |  |  */ | 
    
    | 165 |  |  | void | 
    
    | 166 |  |  | resize_display(void) | 
    
    | 167 |  |  | { | 
    
    | 168 |  |  | 	struct winsize ws; | 
    
    | 169 |  |  |  | 
    
    | 170 |  |  | 	if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) < 0 || | 
    
    | 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 |  |  | } |