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