1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright (c) 1995, by Sun Microsystems, Inc. 24*7c478bd9Sstevel@tonic-gate * All rights reserved. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* 30*7c478bd9Sstevel@tonic-gate * newterm.c 31*7c478bd9Sstevel@tonic-gate * 32*7c478bd9Sstevel@tonic-gate * XCurses Library 33*7c478bd9Sstevel@tonic-gate * 34*7c478bd9Sstevel@tonic-gate * Copyright 1990, 1995 by Mortice Kern Systems Inc. All rights reserved. 35*7c478bd9Sstevel@tonic-gate * 36*7c478bd9Sstevel@tonic-gate */ 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate #ifdef M_RCSID 39*7c478bd9Sstevel@tonic-gate #ifndef lint 40*7c478bd9Sstevel@tonic-gate static char const rcsID[] = "$Header: /rd/src/libc/xcurses/rcs/newterm.c 1.15 1995/07/25 19:54:00 ant Exp $"; 41*7c478bd9Sstevel@tonic-gate #endif 42*7c478bd9Sstevel@tonic-gate #endif 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate #include <private.h> 45*7c478bd9Sstevel@tonic-gate #include <m_wio.h> 46*7c478bd9Sstevel@tonic-gate #include <errno.h> 47*7c478bd9Sstevel@tonic-gate #include <signal.h> 48*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 49*7c478bd9Sstevel@tonic-gate #include <string.h> 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate int LINES, COLS; 52*7c478bd9Sstevel@tonic-gate int COLORS, COLOR_PAIRS; 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate WINDOW *curscr; 55*7c478bd9Sstevel@tonic-gate WINDOW *stdscr; 56*7c478bd9Sstevel@tonic-gate SCREEN *__m_screen; 57*7c478bd9Sstevel@tonic-gate 58*7c478bd9Sstevel@tonic-gate static short assume_one_line = FALSE; 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate /* 61*7c478bd9Sstevel@tonic-gate * Assume terminal has only one screen line by restricting those 62*7c478bd9Sstevel@tonic-gate * capabilities that assume more than one line. This function must 63*7c478bd9Sstevel@tonic-gate * be called before initscr() or newterm(). 64*7c478bd9Sstevel@tonic-gate * 65*7c478bd9Sstevel@tonic-gate * This flag will reset after initscr() or newterm() so that subsequent 66*7c478bd9Sstevel@tonic-gate * calls to newterm(), without a preceding call to filter(), will load 67*7c478bd9Sstevel@tonic-gate * an unmodified terminal. THIS IS NOT HISTORICAL PRACTICE, BUT DEEMED 68*7c478bd9Sstevel@tonic-gate * USEFUL. 69*7c478bd9Sstevel@tonic-gate */ 70*7c478bd9Sstevel@tonic-gate void 71*7c478bd9Sstevel@tonic-gate filter(void) 72*7c478bd9Sstevel@tonic-gate { 73*7c478bd9Sstevel@tonic-gate #ifdef M_CURSES_TRACE 74*7c478bd9Sstevel@tonic-gate __m_trace("filter(void)"); 75*7c478bd9Sstevel@tonic-gate #endif 76*7c478bd9Sstevel@tonic-gate assume_one_line = TRUE; 77*7c478bd9Sstevel@tonic-gate __m_return_void("filter"); 78*7c478bd9Sstevel@tonic-gate } 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate /*f 81*7c478bd9Sstevel@tonic-gate * SIGTSTP Handler. 82*7c478bd9Sstevel@tonic-gate */ 83*7c478bd9Sstevel@tonic-gate void 84*7c478bd9Sstevel@tonic-gate tstp(signo) 85*7c478bd9Sstevel@tonic-gate int signo; 86*7c478bd9Sstevel@tonic-gate { 87*7c478bd9Sstevel@tonic-gate #ifdef SIGTSTP 88*7c478bd9Sstevel@tonic-gate /* Only permit SIGTSTP if the curent process is the process 89*7c478bd9Sstevel@tonic-gate * group leader. If the process is not the current group 90*7c478bd9Sstevel@tonic-gate * leader, then suspending the current process will suspend 91*7c478bd9Sstevel@tonic-gate * other members of the process group, such as the parent 92*7c478bd9Sstevel@tonic-gate * process. 93*7c478bd9Sstevel@tonic-gate */ 94*7c478bd9Sstevel@tonic-gate if (getpid() == getpgrp()) { 95*7c478bd9Sstevel@tonic-gate (void) endwin(); 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate #ifdef SIG_UNBLOCK 98*7c478bd9Sstevel@tonic-gate { 99*7c478bd9Sstevel@tonic-gate sigset_t unblock; 100*7c478bd9Sstevel@tonic-gate 101*7c478bd9Sstevel@tonic-gate (void) sigemptyset(&unblock); 102*7c478bd9Sstevel@tonic-gate (void) sigaddset(&unblock, SIGTSTP); 103*7c478bd9Sstevel@tonic-gate (void) sigprocmask(SIG_UNBLOCK, &unblock, (sigset_t *) 0); 104*7c478bd9Sstevel@tonic-gate } 105*7c478bd9Sstevel@tonic-gate #endif /* SIG_UNBLOCK */ 106*7c478bd9Sstevel@tonic-gate (void) signal(SIGTSTP, SIG_DFL); 107*7c478bd9Sstevel@tonic-gate (void) kill(0, SIGTSTP); 108*7c478bd9Sstevel@tonic-gate } else { 109*7c478bd9Sstevel@tonic-gate (void) beep(); 110*7c478bd9Sstevel@tonic-gate } 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate (void) signal(SIGTSTP, tstp); 113*7c478bd9Sstevel@tonic-gate (void) wrefresh(curscr); 114*7c478bd9Sstevel@tonic-gate #else /* no SIGTSTP */ 115*7c478bd9Sstevel@tonic-gate (void) beep(); 116*7c478bd9Sstevel@tonic-gate #endif /* SIGTSTP */ 117*7c478bd9Sstevel@tonic-gate } 118*7c478bd9Sstevel@tonic-gate 119*7c478bd9Sstevel@tonic-gate int __m_slk_format = -1; 120*7c478bd9Sstevel@tonic-gate 121*7c478bd9Sstevel@tonic-gate /* 122*7c478bd9Sstevel@tonic-gate * Do real soft label key initialisation once setupterm() have been called 123*7c478bd9Sstevel@tonic-gate * to load the current terminal. Determine whether the terminal supplies 124*7c478bd9Sstevel@tonic-gate * soft label keys, or whether we have to fake it by using the last line 125*7c478bd9Sstevel@tonic-gate * of a terminal screen. 126*7c478bd9Sstevel@tonic-gate */ 127*7c478bd9Sstevel@tonic-gate int 128*7c478bd9Sstevel@tonic-gate __m_slk_init(SCREEN *sp, int style) 129*7c478bd9Sstevel@tonic-gate { 130*7c478bd9Sstevel@tonic-gate int code; 131*7c478bd9Sstevel@tonic-gate 132*7c478bd9Sstevel@tonic-gate #ifdef M_CURSES_TRACE 133*7c478bd9Sstevel@tonic-gate __m_trace("__m_slk_init(%d)", style ); 134*7c478bd9Sstevel@tonic-gate #endif 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate code = ERR; 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate /* Does the terminal have a method to program the soft label key? */ 139*7c478bd9Sstevel@tonic-gate if (plab_norm != (char *) 0 || pkey_plab != (char *) 0) { 140*7c478bd9Sstevel@tonic-gate code = OK; 141*7c478bd9Sstevel@tonic-gate goto done; 142*7c478bd9Sstevel@tonic-gate } 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate /* We have to fake it. */ 145*7c478bd9Sstevel@tonic-gate if (lines < 2) 146*7c478bd9Sstevel@tonic-gate goto done; 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate sp->_slk._w = subwin(sp->_newscr, 1, 0, --lines, 0); 149*7c478bd9Sstevel@tonic-gate if (sp->_slk._w == (WINDOW *) 0) 150*7c478bd9Sstevel@tonic-gate goto done; 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate code = OK; 153*7c478bd9Sstevel@tonic-gate done: 154*7c478bd9Sstevel@tonic-gate return __m_return_code("__m_slk_init", code); 155*7c478bd9Sstevel@tonic-gate } 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate /* 158*7c478bd9Sstevel@tonic-gate * The XCurses specification is unclear how ripoffline() would 159*7c478bd9Sstevel@tonic-gate * affect newterm(). We assume that it can't be used with newterm() 160*7c478bd9Sstevel@tonic-gate * and that it only affects initscr(), which is responsible for 161*7c478bd9Sstevel@tonic-gate * creating stdscr. 162*7c478bd9Sstevel@tonic-gate */ 163*7c478bd9Sstevel@tonic-gate static t_rip rip = { 0 }; 164*7c478bd9Sstevel@tonic-gate 165*7c478bd9Sstevel@tonic-gate /* 166*7c478bd9Sstevel@tonic-gate * If line is positive (1), one line is removed from the beginning of 167*7c478bd9Sstevel@tonic-gate * stdscr; else if line is negative (-1), one line is removed from the end. 168*7c478bd9Sstevel@tonic-gate */ 169*7c478bd9Sstevel@tonic-gate int 170*7c478bd9Sstevel@tonic-gate ripoffline(int line, int (*init)(WINDOW *, int)) 171*7c478bd9Sstevel@tonic-gate { 172*7c478bd9Sstevel@tonic-gate int i; 173*7c478bd9Sstevel@tonic-gate 174*7c478bd9Sstevel@tonic-gate #ifdef M_CURSES_TRACE 175*7c478bd9Sstevel@tonic-gate __m_trace("ripoffline(%d, %p)", line, init); 176*7c478bd9Sstevel@tonic-gate #endif 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate i = rip.top - rip.bottom; 179*7c478bd9Sstevel@tonic-gate 180*7c478bd9Sstevel@tonic-gate if (line != 0 && i + 1 < M_CURSES_MAX_RIPOFFLINE) { 181*7c478bd9Sstevel@tonic-gate rip.line[i].init = init; 182*7c478bd9Sstevel@tonic-gate if (line < 0) 183*7c478bd9Sstevel@tonic-gate rip.line[i].dy = --rip.bottom; 184*7c478bd9Sstevel@tonic-gate else 185*7c478bd9Sstevel@tonic-gate rip.line[i].dy = ++rip.top; 186*7c478bd9Sstevel@tonic-gate } 187*7c478bd9Sstevel@tonic-gate 188*7c478bd9Sstevel@tonic-gate return __m_return_code("ripoffline", OK); 189*7c478bd9Sstevel@tonic-gate } 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate /*f 192*7c478bd9Sstevel@tonic-gate * Create a new terminal screen. Used if a program is going to be sending 193*7c478bd9Sstevel@tonic-gate * output to more than one terminal. It returns a SCREEN* for the terminal. 194*7c478bd9Sstevel@tonic-gate * The parameters are a terminal name, output FILE*, and input FILE*. If 195*7c478bd9Sstevel@tonic-gate * the terminal name is null then $TERM is used. The program must also 196*7c478bd9Sstevel@tonic-gate * call endwin() for each terminal being used before exiting from curses. 197*7c478bd9Sstevel@tonic-gate * If newterm() is called more than once for the same terminal, the first 198*7c478bd9Sstevel@tonic-gate * terminal referred to must be the last one for which endwin() is called. 199*7c478bd9Sstevel@tonic-gate */ 200*7c478bd9Sstevel@tonic-gate SCREEN * 201*7c478bd9Sstevel@tonic-gate newterm(term, out_fp, in_fp) 202*7c478bd9Sstevel@tonic-gate char *term; 203*7c478bd9Sstevel@tonic-gate FILE *out_fp, *in_fp; 204*7c478bd9Sstevel@tonic-gate { 205*7c478bd9Sstevel@tonic-gate WINDOW *w; 206*7c478bd9Sstevel@tonic-gate t_wide_io *wio; 207*7c478bd9Sstevel@tonic-gate SCREEN *sp, *osp; 208*7c478bd9Sstevel@tonic-gate int i, n, y, errret; 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate #ifdef M_CURSES_TRACE 211*7c478bd9Sstevel@tonic-gate __m_trace( 212*7c478bd9Sstevel@tonic-gate "newterm(%s, %p, %p)", 213*7c478bd9Sstevel@tonic-gate term == (char *) 0 ? "NULL" : term, out_fp, in_fp 214*7c478bd9Sstevel@tonic-gate ); 215*7c478bd9Sstevel@tonic-gate #endif 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate /* Input stream should be unbuffered so that m_tfgetc() works 218*7c478bd9Sstevel@tonic-gate * correctly on BSD and SUN systems. 219*7c478bd9Sstevel@tonic-gate */ 220*7c478bd9Sstevel@tonic-gate (void) SETVBUF(in_fp, (char *) 0, _IONBF, BUFSIZ); 221*7c478bd9Sstevel@tonic-gate #if 0 222*7c478bd9Sstevel@tonic-gate /* 223*7c478bd9Sstevel@tonic-gate * Not sure whether we really want to concern ourselves with the output 224*7c478bd9Sstevel@tonic-gate * buffer scheme. Might be best to leave it upto the application to 225*7c478bd9Sstevel@tonic-gate * deal with buffer schemes and when to perform flushes. 226*7c478bd9Sstevel@tonic-gate * 227*7c478bd9Sstevel@tonic-gate * MKS Vi uses MKS Curses and so must support the ability to switch in 228*7c478bd9Sstevel@tonic-gate * and out of Curses mode when switching from Vi to Ex and back. 229*7c478bd9Sstevel@tonic-gate * Problem is that in Vi mode you would prefer full buffered output to 230*7c478bd9Sstevel@tonic-gate * give updates a smoother appearance and Ex mode you require line 231*7c478bd9Sstevel@tonic-gate * buffered in order to see prompts and messages. 232*7c478bd9Sstevel@tonic-gate */ 233*7c478bd9Sstevel@tonic-gate (void) SETVBUF(out_fp, (char *) 0, _IOLBF, BUFSIZ); 234*7c478bd9Sstevel@tonic-gate #endif 235*7c478bd9Sstevel@tonic-gate errno = 0; 236*7c478bd9Sstevel@tonic-gate 237*7c478bd9Sstevel@tonic-gate if (__m_setupterm(term, fileno(in_fp), fileno(out_fp), &errret)==ERR) { 238*7c478bd9Sstevel@tonic-gate switch (errret) { 239*7c478bd9Sstevel@tonic-gate case -1: 240*7c478bd9Sstevel@tonic-gate errno = ENOMEM; 241*7c478bd9Sstevel@tonic-gate break; 242*7c478bd9Sstevel@tonic-gate case 2: 243*7c478bd9Sstevel@tonic-gate errno = ENAMETOOLONG; 244*7c478bd9Sstevel@tonic-gate break; 245*7c478bd9Sstevel@tonic-gate case 0: 246*7c478bd9Sstevel@tonic-gate default: 247*7c478bd9Sstevel@tonic-gate errno = ENOENT; 248*7c478bd9Sstevel@tonic-gate break; 249*7c478bd9Sstevel@tonic-gate } 250*7c478bd9Sstevel@tonic-gate goto error1; 251*7c478bd9Sstevel@tonic-gate } 252*7c478bd9Sstevel@tonic-gate 253*7c478bd9Sstevel@tonic-gate if (__m_doupdate_init()) 254*7c478bd9Sstevel@tonic-gate goto error1; 255*7c478bd9Sstevel@tonic-gate 256*7c478bd9Sstevel@tonic-gate if ((sp = (SCREEN *) calloc(1, sizeof *sp)) == (SCREEN *) 0) 257*7c478bd9Sstevel@tonic-gate goto error1; 258*7c478bd9Sstevel@tonic-gate 259*7c478bd9Sstevel@tonic-gate sp->_if = in_fp; 260*7c478bd9Sstevel@tonic-gate sp->_of = out_fp; 261*7c478bd9Sstevel@tonic-gate sp->_term = cur_term; 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate sp->_unget._size = __m_decode_init((t_decode **) &sp->_decode); 264*7c478bd9Sstevel@tonic-gate 265*7c478bd9Sstevel@tonic-gate /* Maximum length of a multbyte key sequence, including 266*7c478bd9Sstevel@tonic-gate * multibyte characters and terminal function keys. 267*7c478bd9Sstevel@tonic-gate */ 268*7c478bd9Sstevel@tonic-gate if (sp->_unget._size < MB_LEN_MAX) 269*7c478bd9Sstevel@tonic-gate sp->_unget._size = MB_LEN_MAX; 270*7c478bd9Sstevel@tonic-gate 271*7c478bd9Sstevel@tonic-gate sp->_unget._stack = calloc( 272*7c478bd9Sstevel@tonic-gate (size_t) sp->_unget._size, sizeof *sp->_unget._stack 273*7c478bd9Sstevel@tonic-gate ); 274*7c478bd9Sstevel@tonic-gate if (sp->_unget._stack == (void *) 0) 275*7c478bd9Sstevel@tonic-gate goto error2; 276*7c478bd9Sstevel@tonic-gate 277*7c478bd9Sstevel@tonic-gate if ((wio = (t_wide_io *) calloc(1, sizeof *wio)) == (t_wide_io *) 0) 278*7c478bd9Sstevel@tonic-gate goto error2; 279*7c478bd9Sstevel@tonic-gate 280*7c478bd9Sstevel@tonic-gate /* Setup wide input for XCurses. */ 281*7c478bd9Sstevel@tonic-gate wio->get = (int (*)(void *)) wgetch; 282*7c478bd9Sstevel@tonic-gate wio->unget = __xc_ungetc; 283*7c478bd9Sstevel@tonic-gate wio->reset = __xc_clearerr; 284*7c478bd9Sstevel@tonic-gate wio->iserror = __xc_ferror; 285*7c478bd9Sstevel@tonic-gate wio->iseof = __xc_feof; 286*7c478bd9Sstevel@tonic-gate sp->_in = wio; 287*7c478bd9Sstevel@tonic-gate 288*7c478bd9Sstevel@tonic-gate if (assume_one_line) { 289*7c478bd9Sstevel@tonic-gate /* Assume only one line. */ 290*7c478bd9Sstevel@tonic-gate lines = 1; 291*7c478bd9Sstevel@tonic-gate 292*7c478bd9Sstevel@tonic-gate /* Disable capabilities that assume more than one line. */ 293*7c478bd9Sstevel@tonic-gate clear_screen = 294*7c478bd9Sstevel@tonic-gate clr_eos = 295*7c478bd9Sstevel@tonic-gate cursor_up = 296*7c478bd9Sstevel@tonic-gate cursor_down = 297*7c478bd9Sstevel@tonic-gate cursor_home = 298*7c478bd9Sstevel@tonic-gate cursor_to_ll = 299*7c478bd9Sstevel@tonic-gate cursor_address = 300*7c478bd9Sstevel@tonic-gate row_address = 301*7c478bd9Sstevel@tonic-gate parm_up_cursor = 302*7c478bd9Sstevel@tonic-gate parm_down_cursor = (char *) 0; 303*7c478bd9Sstevel@tonic-gate 304*7c478bd9Sstevel@tonic-gate /* Re-evaluate the cursor motion costs. */ 305*7c478bd9Sstevel@tonic-gate __m_mvcur_cost(); 306*7c478bd9Sstevel@tonic-gate 307*7c478bd9Sstevel@tonic-gate /* Reset flag for subsequent calls to newterm(). */ 308*7c478bd9Sstevel@tonic-gate assume_one_line = FALSE; 309*7c478bd9Sstevel@tonic-gate } 310*7c478bd9Sstevel@tonic-gate 311*7c478bd9Sstevel@tonic-gate if ((sp->_curscr = newwin(lines, columns, 0, 0)) == (WINDOW *) 0) 312*7c478bd9Sstevel@tonic-gate goto error2; 313*7c478bd9Sstevel@tonic-gate 314*7c478bd9Sstevel@tonic-gate if ((sp->_newscr = newwin(lines, columns, 0, 0)) == (WINDOW *) 0) 315*7c478bd9Sstevel@tonic-gate goto error2; 316*7c478bd9Sstevel@tonic-gate 317*7c478bd9Sstevel@tonic-gate sp->_hash = (unsigned long *) calloc(lines, sizeof *sp->_hash); 318*7c478bd9Sstevel@tonic-gate if (sp->_hash == (unsigned long *) 0) 319*7c478bd9Sstevel@tonic-gate goto error2; 320*7c478bd9Sstevel@tonic-gate 321*7c478bd9Sstevel@tonic-gate if (0 <= __m_slk_format && __m_slk_init(sp, __m_slk_format) == ERR) 322*7c478bd9Sstevel@tonic-gate goto error2; 323*7c478bd9Sstevel@tonic-gate 324*7c478bd9Sstevel@tonic-gate /* doupdate() will perform the final screen preparations like 325*7c478bd9Sstevel@tonic-gate * enter_ca_mode, reset_prog_mode() (to assert the termios 326*7c478bd9Sstevel@tonic-gate * changes), etc. 327*7c478bd9Sstevel@tonic-gate */ 328*7c478bd9Sstevel@tonic-gate sp->_flags |= S_ENDWIN; 329*7c478bd9Sstevel@tonic-gate 330*7c478bd9Sstevel@tonic-gate #ifdef SIGTSTP 331*7c478bd9Sstevel@tonic-gate (void) signal(SIGTSTP, tstp); 332*7c478bd9Sstevel@tonic-gate #endif 333*7c478bd9Sstevel@tonic-gate /* Assert that __m_screen is set to the new terminal. */ 334*7c478bd9Sstevel@tonic-gate osp = set_term(sp); 335*7c478bd9Sstevel@tonic-gate 336*7c478bd9Sstevel@tonic-gate /* Disable echo in tty driver, Curses does software echo. */ 337*7c478bd9Sstevel@tonic-gate cur_term->_prog.c_lflag &= ~ECHO; 338*7c478bd9Sstevel@tonic-gate 339*7c478bd9Sstevel@tonic-gate /* Enable mappnig of cr -> nl on input and nl -> crlf on output. */ 340*7c478bd9Sstevel@tonic-gate cur_term->_prog.c_iflag |= ICRNL; 341*7c478bd9Sstevel@tonic-gate cur_term->_prog.c_oflag |= OPOST; 342*7c478bd9Sstevel@tonic-gate #ifdef ONLCR 343*7c478bd9Sstevel@tonic-gate cur_term->_prog.c_oflag |= ONLCR; 344*7c478bd9Sstevel@tonic-gate #endif 345*7c478bd9Sstevel@tonic-gate cur_term->_flags |= __TERM_NL_IS_CRLF; 346*7c478bd9Sstevel@tonic-gate 347*7c478bd9Sstevel@tonic-gate #ifdef TAB0 348*7c478bd9Sstevel@tonic-gate /* Use real tabs. */ 349*7c478bd9Sstevel@tonic-gate cur_term->_prog.c_oflag &= ~(TAB1|TAB2|TAB3); 350*7c478bd9Sstevel@tonic-gate #endif 351*7c478bd9Sstevel@tonic-gate 352*7c478bd9Sstevel@tonic-gate (void) __m_tty_set(&cur_term->_prog); 353*7c478bd9Sstevel@tonic-gate (void) __m_set_echo(1); 354*7c478bd9Sstevel@tonic-gate (void) typeahead(fileno(in_fp)); 355*7c478bd9Sstevel@tonic-gate 356*7c478bd9Sstevel@tonic-gate if (stdscr == (WINDOW *) 0) { 357*7c478bd9Sstevel@tonic-gate n = rip.top - rip.bottom; 358*7c478bd9Sstevel@tonic-gate stdscr = newwin(lines - n, 0, rip.top, 0); 359*7c478bd9Sstevel@tonic-gate if (stdscr == (WINDOW *) 0) 360*7c478bd9Sstevel@tonic-gate goto error3; 361*7c478bd9Sstevel@tonic-gate 362*7c478bd9Sstevel@tonic-gate /* Create and initialise ripped off line windows. 363*7c478bd9Sstevel@tonic-gate * It is the application's responsiblity to free the 364*7c478bd9Sstevel@tonic-gate * windows when the application terminates. 365*7c478bd9Sstevel@tonic-gate */ 366*7c478bd9Sstevel@tonic-gate for (i = 0; i < n; ++i) { 367*7c478bd9Sstevel@tonic-gate y = rip.line[i].dy; 368*7c478bd9Sstevel@tonic-gate if (y < 0) 369*7c478bd9Sstevel@tonic-gate y += lines; 370*7c478bd9Sstevel@tonic-gate 371*7c478bd9Sstevel@tonic-gate w = newwin(1, 0, y, 0); 372*7c478bd9Sstevel@tonic-gate if (rip.line[i].init != (int (*)(WINDOW *, int)) 0) 373*7c478bd9Sstevel@tonic-gate (void) (*rip.line[i].init)(w, columns); 374*7c478bd9Sstevel@tonic-gate } 375*7c478bd9Sstevel@tonic-gate } 376*7c478bd9Sstevel@tonic-gate 377*7c478bd9Sstevel@tonic-gate return __m_return_pointer("newterm", sp); 378*7c478bd9Sstevel@tonic-gate error3: 379*7c478bd9Sstevel@tonic-gate (void) set_term(osp); 380*7c478bd9Sstevel@tonic-gate error2: 381*7c478bd9Sstevel@tonic-gate delscreen(sp); 382*7c478bd9Sstevel@tonic-gate error1: 383*7c478bd9Sstevel@tonic-gate return __m_return_pointer("newterm", (SCREEN *) 0); 384*7c478bd9Sstevel@tonic-gate } 385*7c478bd9Sstevel@tonic-gate 386*7c478bd9Sstevel@tonic-gate /*f 387*7c478bd9Sstevel@tonic-gate * Free storage associated with a screen structure. 388*7c478bd9Sstevel@tonic-gate * NOTE endwin() does not do this. 389*7c478bd9Sstevel@tonic-gate */ 390*7c478bd9Sstevel@tonic-gate void 391*7c478bd9Sstevel@tonic-gate delscreen(sp) 392*7c478bd9Sstevel@tonic-gate SCREEN *sp; 393*7c478bd9Sstevel@tonic-gate { 394*7c478bd9Sstevel@tonic-gate #ifdef M_CURSES_TRACE 395*7c478bd9Sstevel@tonic-gate __m_trace("delscreen(%p)", sp); 396*7c478bd9Sstevel@tonic-gate #endif 397*7c478bd9Sstevel@tonic-gate 398*7c478bd9Sstevel@tonic-gate if (sp != (SCREEN *) 0) { 399*7c478bd9Sstevel@tonic-gate if (sp->_slk._w != (WINDOW *) 0) 400*7c478bd9Sstevel@tonic-gate (void) delwin(sp->_slk._w); 401*7c478bd9Sstevel@tonic-gate 402*7c478bd9Sstevel@tonic-gate (void) delwin(sp->_newscr); 403*7c478bd9Sstevel@tonic-gate (void) delwin(sp->_curscr); 404*7c478bd9Sstevel@tonic-gate (void) del_curterm(sp->_term); 405*7c478bd9Sstevel@tonic-gate 406*7c478bd9Sstevel@tonic-gate __m_decode_free((t_decode **) &sp->_decode); 407*7c478bd9Sstevel@tonic-gate 408*7c478bd9Sstevel@tonic-gate if (sp->_hash != (unsigned long *) 0) 409*7c478bd9Sstevel@tonic-gate free(sp->_hash); 410*7c478bd9Sstevel@tonic-gate 411*7c478bd9Sstevel@tonic-gate if (sp->_unget._stack != (int *) 0) 412*7c478bd9Sstevel@tonic-gate free(sp->_unget._stack); 413*7c478bd9Sstevel@tonic-gate 414*7c478bd9Sstevel@tonic-gate if (sp->_in != (void *) 0) 415*7c478bd9Sstevel@tonic-gate free(sp->_in); 416*7c478bd9Sstevel@tonic-gate 417*7c478bd9Sstevel@tonic-gate free(sp); 418*7c478bd9Sstevel@tonic-gate } 419*7c478bd9Sstevel@tonic-gate 420*7c478bd9Sstevel@tonic-gate __m_return_void("delscreen"); 421*7c478bd9Sstevel@tonic-gate } 422*7c478bd9Sstevel@tonic-gate 423*7c478bd9Sstevel@tonic-gate /*f 424*7c478bd9Sstevel@tonic-gate * Switch current terminal for Curses layer. 425*7c478bd9Sstevel@tonic-gate */ 426*7c478bd9Sstevel@tonic-gate SCREEN * 427*7c478bd9Sstevel@tonic-gate set_term(screen) 428*7c478bd9Sstevel@tonic-gate SCREEN *screen; 429*7c478bd9Sstevel@tonic-gate { 430*7c478bd9Sstevel@tonic-gate SCREEN *osp = __m_screen; 431*7c478bd9Sstevel@tonic-gate 432*7c478bd9Sstevel@tonic-gate #ifdef M_CURSES_TRACE 433*7c478bd9Sstevel@tonic-gate __m_trace("set_term(%p)", screen); 434*7c478bd9Sstevel@tonic-gate #endif 435*7c478bd9Sstevel@tonic-gate if (screen != (SCREEN *) 0) { 436*7c478bd9Sstevel@tonic-gate (void) set_curterm(screen->_term); 437*7c478bd9Sstevel@tonic-gate curscr = screen->_curscr; 438*7c478bd9Sstevel@tonic-gate __m_screen = screen; 439*7c478bd9Sstevel@tonic-gate 440*7c478bd9Sstevel@tonic-gate LINES = lines; 441*7c478bd9Sstevel@tonic-gate COLS = columns; 442*7c478bd9Sstevel@tonic-gate COLORS = max_colors; 443*7c478bd9Sstevel@tonic-gate COLOR_PAIRS = max_pairs; 444*7c478bd9Sstevel@tonic-gate } 445*7c478bd9Sstevel@tonic-gate 446*7c478bd9Sstevel@tonic-gate return __m_return_pointer("set_term", osp); 447*7c478bd9Sstevel@tonic-gate } 448*7c478bd9Sstevel@tonic-gate 449*7c478bd9Sstevel@tonic-gate int 450*7c478bd9Sstevel@tonic-gate typeahead(fd) 451*7c478bd9Sstevel@tonic-gate int fd; 452*7c478bd9Sstevel@tonic-gate { 453*7c478bd9Sstevel@tonic-gate #ifdef M_CURSES_TRACE 454*7c478bd9Sstevel@tonic-gate __m_trace("typeahead(%d)", fd); 455*7c478bd9Sstevel@tonic-gate #endif 456*7c478bd9Sstevel@tonic-gate 457*7c478bd9Sstevel@tonic-gate __m_screen->_kfd = fd; 458*7c478bd9Sstevel@tonic-gate __m_screen->_flags &= ~S_ISATTY; 459*7c478bd9Sstevel@tonic-gate 460*7c478bd9Sstevel@tonic-gate if (fd != -1 && isatty(fd)) 461*7c478bd9Sstevel@tonic-gate __m_screen->_flags |= S_ISATTY; 462*7c478bd9Sstevel@tonic-gate 463*7c478bd9Sstevel@tonic-gate return __m_return_code("typeahead", OK); 464*7c478bd9Sstevel@tonic-gate } 465*7c478bd9Sstevel@tonic-gate 466*7c478bd9Sstevel@tonic-gate int 467*7c478bd9Sstevel@tonic-gate __m_set_echo(bf) 468*7c478bd9Sstevel@tonic-gate int bf; 469*7c478bd9Sstevel@tonic-gate { 470*7c478bd9Sstevel@tonic-gate int old; 471*7c478bd9Sstevel@tonic-gate 472*7c478bd9Sstevel@tonic-gate old = (__m_screen->_flags & S_ECHO) == S_ECHO; 473*7c478bd9Sstevel@tonic-gate 474*7c478bd9Sstevel@tonic-gate __m_screen->_flags &= ~S_ECHO; 475*7c478bd9Sstevel@tonic-gate if (bf) 476*7c478bd9Sstevel@tonic-gate __m_screen->_flags |= S_ECHO; 477*7c478bd9Sstevel@tonic-gate 478*7c478bd9Sstevel@tonic-gate return old; 479*7c478bd9Sstevel@tonic-gate } 480*7c478bd9Sstevel@tonic-gate 481