init_disp.c revision 128445
11590Srgrimes/* 21590Srgrimes * Copyright (c) 1983, 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 3. All advertising materials mentioning features or use of this software 141590Srgrimes * must display the following acknowledgement: 151590Srgrimes * This product includes software developed by the University of 161590Srgrimes * California, Berkeley and its contributors. 171590Srgrimes * 4. Neither the name of the University nor the names of its contributors 181590Srgrimes * may be used to endorse or promote products derived from this software 191590Srgrimes * without specific prior written permission. 201590Srgrimes * 211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311590Srgrimes * SUCH DAMAGE. 321590Srgrimes */ 331590Srgrimes 3487710Smarkm#include <sys/cdefs.h> 3587710Smarkm 3687710Smarkm__FBSDID("$FreeBSD: head/usr.bin/talk/init_disp.c 128445 2004-04-19 21:37:29Z cognet $"); 3787710Smarkm 381590Srgrimes#ifndef lint 3987710Smarkmstatic const char sccsid[] = "@(#)init_disp.c 8.2 (Berkeley) 2/16/94"; 4032503Scharnier#endif 411590Srgrimes 421590Srgrimes/* 431590Srgrimes * Initialization code for the display package, 441590Srgrimes * as well as the signal handling routines. 451590Srgrimes */ 461590Srgrimes 4787710Smarkm#include <sys/stat.h> 4887710Smarkm 4932503Scharnier#include <err.h> 5032503Scharnier#include <signal.h> 5178733Sdd#include <stdlib.h> 525297Sache#include <unistd.h> 5350636Speter#include <termios.h> 5487710Smarkm 551590Srgrimes#include "talk.h" 561590Srgrimes 57128445Scognetextern volatile sig_atomic_t gotwinch; 58128445Scognet 598874Srgrimes/* 605297Sache * Make sure the callee can write to the screen 615297Sache */ 6214443Sjoergvoid 6314443Sjoergcheck_writeable() 645297Sache{ 655297Sache char *tty; 665297Sache struct stat sb; 675297Sache 685297Sache if ((tty = ttyname(STDERR_FILENO)) == NULL) 695297Sache err(1, "ttyname"); 705297Sache if (stat(tty, &sb) < 0) 715297Sache err(1, "%s", tty); 725297Sache if (!(sb.st_mode & S_IWGRP)) 735297Sache errx(1, "The callee cannot write to this terminal, use \"mesg y\"."); 745297Sache} 755297Sache 768874Srgrimes/* 771590Srgrimes * Set up curses, catch the appropriate signals, 781590Srgrimes * and build the various windows. 791590Srgrimes */ 8014443Sjoergvoid 811590Srgrimesinit_display() 821590Srgrimes{ 8317676Speter struct sigaction sa; 841590Srgrimes 851590Srgrimes if (initscr() == NULL) 861590Srgrimes errx(1, "Terminal type unset or lacking necessary features."); 8717676Speter (void) sigaction(SIGTSTP, (struct sigaction *)0, &sa); 8817676Speter sigaddset(&sa.sa_mask, SIGALRM); 8917676Speter (void) sigaction(SIGTSTP, &sa, (struct sigaction *)0); 901590Srgrimes curses_initialized = 1; 911590Srgrimes clear(); 921590Srgrimes refresh(); 931590Srgrimes noecho(); 941590Srgrimes crmode(); 951590Srgrimes signal(SIGINT, sig_sent); 961590Srgrimes signal(SIGPIPE, sig_sent); 97128445Scognet signal(SIGWINCH, sig_winch); 981590Srgrimes /* curses takes care of ^Z */ 991590Srgrimes my_win.x_nlines = LINES / 2; 1001590Srgrimes my_win.x_ncols = COLS; 1011590Srgrimes my_win.x_win = newwin(my_win.x_nlines, my_win.x_ncols, 0, 0); 10220988Speter idlok(my_win.x_win, TRUE); 1032929Sache scrollok(my_win.x_win, TRUE); 1041590Srgrimes wclear(my_win.x_win); 1051590Srgrimes 1061590Srgrimes his_win.x_nlines = LINES / 2 - 1; 1071590Srgrimes his_win.x_ncols = COLS; 1081590Srgrimes his_win.x_win = newwin(his_win.x_nlines, his_win.x_ncols, 1091590Srgrimes my_win.x_nlines+1, 0); 11020988Speter idlok(my_win.x_win, TRUE); 1112929Sache scrollok(his_win.x_win, TRUE); 1121590Srgrimes wclear(his_win.x_win); 1131590Srgrimes 1141590Srgrimes line_win = newwin(1, COLS, my_win.x_nlines, 0); 11517698Speter#if defined(hline) || defined(whline) || defined(NCURSES_VERSION) 11617698Speter whline(line_win, 0, COLS); 11717698Speter#else 11817698Speter box(line_win, '-', '-'); 11917698Speter#endif 1201590Srgrimes wrefresh(line_win); 1211590Srgrimes /* let them know we are working on it */ 1221590Srgrimes current_state = "No connection yet"; 1231590Srgrimes} 1241590Srgrimes 1251590Srgrimes/* 1261590Srgrimes * Trade edit characters with the other talk. By agreement 1271590Srgrimes * the first three characters each talk transmits after 1281590Srgrimes * connection are the three edit characters. 1291590Srgrimes */ 13014443Sjoergvoid 1311590Srgrimesset_edit_chars() 1321590Srgrimes{ 1331590Srgrimes char buf[3]; 1341590Srgrimes int cc; 13517676Speter struct termios tio; 1368874Srgrimes 13717676Speter tcgetattr(0, &tio); 13817676Speter my_win.cerase = tio.c_cc[VERASE]; 13917676Speter my_win.kill = tio.c_cc[VKILL]; 14017676Speter my_win.werase = tio.c_cc[VWERASE]; 14117676Speter if (my_win.cerase == (char)_POSIX_VDISABLE) 14217676Speter my_win.kill = CERASE; 14317676Speter if (my_win.kill == (char)_POSIX_VDISABLE) 14417676Speter my_win.kill = CKILL; 14517676Speter if (my_win.werase == (char)_POSIX_VDISABLE) 14617676Speter my_win.werase = CWERASE; 1471590Srgrimes buf[0] = my_win.cerase; 1481590Srgrimes buf[1] = my_win.kill; 1491590Srgrimes buf[2] = my_win.werase; 1501590Srgrimes cc = write(sockt, buf, sizeof(buf)); 1511590Srgrimes if (cc != sizeof(buf) ) 1521590Srgrimes p_error("Lost the connection"); 1531590Srgrimes cc = read(sockt, buf, sizeof(buf)); 1541590Srgrimes if (cc != sizeof(buf) ) 1551590Srgrimes p_error("Lost the connection"); 1561590Srgrimes his_win.cerase = buf[0]; 1571590Srgrimes his_win.kill = buf[1]; 1581590Srgrimes his_win.werase = buf[2]; 1591590Srgrimes} 1601590Srgrimes 16114443Sjoerg/* ARGSUSED */ 1621590Srgrimesvoid 16314443Sjoergsig_sent(signo) 16487710Smarkm int signo __unused; 1651590Srgrimes{ 1661590Srgrimes 1671590Srgrimes message("Connection closing. Exiting"); 1681590Srgrimes quit(); 1691590Srgrimes} 1701590Srgrimes 171128445Scognetvoid 172128445Scognetsig_winch(int dummy) 173128445Scognet{ 174128445Scognet 175128445Scognet gotwinch = 1; 176128445Scognet} 177128445Scognet 1781590Srgrimes/* 1791590Srgrimes * All done talking...hang up the phone and reset terminal thingy's 1801590Srgrimes */ 18114443Sjoergvoid 1821590Srgrimesquit() 1831590Srgrimes{ 1841590Srgrimes 1851590Srgrimes if (curses_initialized) { 1861590Srgrimes wmove(his_win.x_win, his_win.x_nlines-1, 0); 1871590Srgrimes wclrtoeol(his_win.x_win); 1881590Srgrimes wrefresh(his_win.x_win); 1891590Srgrimes endwin(); 1901590Srgrimes } 1911590Srgrimes if (invitation_waiting) 1921590Srgrimes send_delete(); 1931590Srgrimes exit(0); 1941590Srgrimes} 195128445Scognet 196128445Scognet/* 197128445Scognet * If we get SIGWINCH, recompute both window sizes and refresh things. 198128445Scognet */ 199128445Scognetvoid 200128445Scognetresize_display(void) 201128445Scognet{ 202128445Scognet struct winsize ws; 203128445Scognet 204128445Scognet if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) < 0 || 205128445Scognet (ws.ws_row == LINES && ws.ws_col == COLS)) 206128445Scognet return; 207128445Scognet 208128445Scognet /* Update curses' internal state with new window size. */ 209128445Scognet resizeterm(ws.ws_row, ws.ws_col); 210128445Scognet 211128445Scognet /* 212128445Scognet * Resize each window but wait to refresh the screen until 213128445Scognet * everything has been drawn so the cursor is in the right spot. 214128445Scognet */ 215128445Scognet my_win.x_nlines = LINES / 2; 216128445Scognet my_win.x_ncols = COLS; 217128445Scognet wresize(my_win.x_win, my_win.x_nlines, my_win.x_ncols); 218128445Scognet mvwin(my_win.x_win, 0, 0); 219128445Scognet clearok(my_win.x_win, TRUE); 220128445Scognet 221128445Scognet his_win.x_nlines = LINES / 2 - 1; 222128445Scognet his_win.x_ncols = COLS; 223128445Scognet wresize(his_win.x_win, his_win.x_nlines, his_win.x_ncols); 224128445Scognet mvwin(his_win.x_win, my_win.x_nlines + 1, 0); 225128445Scognet clearok(his_win.x_win, TRUE); 226128445Scognet 227128445Scognet wresize(line_win, 1, COLS); 228128445Scognet mvwin(line_win, my_win.x_nlines, 0); 229128445Scognet#if defined(NCURSES_VERSION) || defined(whline) 230128445Scognet whline(line_win, '-', COLS); 231128445Scognet#else 232128445Scognet wmove(line_win, my_win.x_nlines, 0); 233128445Scognet box(line_win, '-', '-'); 234128445Scognet#endif 235128445Scognet 236128445Scognet /* Now redraw the screen. */ 237128445Scognet wrefresh(his_win.x_win); 238128445Scognet wrefresh(line_win); 239128445Scognet wrefresh(my_win.x_win); 240128445Scognet} 241