10e3d5408SPeter Wemm /**************************************************************************** 20e3d5408SPeter Wemm * Copyright (c) 1998 Free Software Foundation, Inc. * 30e3d5408SPeter Wemm * * 40e3d5408SPeter Wemm * Permission is hereby granted, free of charge, to any person obtaining a * 50e3d5408SPeter Wemm * copy of this software and associated documentation files (the * 60e3d5408SPeter Wemm * "Software"), to deal in the Software without restriction, including * 70e3d5408SPeter Wemm * without limitation the rights to use, copy, modify, merge, publish, * 80e3d5408SPeter Wemm * distribute, distribute with modifications, sublicense, and/or sell * 90e3d5408SPeter Wemm * copies of the Software, and to permit persons to whom the Software is * 100e3d5408SPeter Wemm * furnished to do so, subject to the following conditions: * 110e3d5408SPeter Wemm * * 120e3d5408SPeter Wemm * The above copyright notice and this permission notice shall be included * 130e3d5408SPeter Wemm * in all copies or substantial portions of the Software. * 140e3d5408SPeter Wemm * * 150e3d5408SPeter Wemm * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 160e3d5408SPeter Wemm * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 170e3d5408SPeter Wemm * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 180e3d5408SPeter Wemm * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 190e3d5408SPeter Wemm * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 200e3d5408SPeter Wemm * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 210e3d5408SPeter Wemm * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 220e3d5408SPeter Wemm * * 230e3d5408SPeter Wemm * Except as contained in this notice, the name(s) of the above copyright * 240e3d5408SPeter Wemm * holders shall not be used in advertising or otherwise to promote the * 250e3d5408SPeter Wemm * sale, use or other dealings in this Software without prior written * 260e3d5408SPeter Wemm * authorization. * 270e3d5408SPeter Wemm ****************************************************************************/ 280e3d5408SPeter Wemm 290e3d5408SPeter Wemm /**************************************************************************** 300e3d5408SPeter Wemm * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * 310e3d5408SPeter Wemm * and: Eric S. Raymond <esr@snark.thyrsus.com> * 320e3d5408SPeter Wemm ****************************************************************************/ 330e3d5408SPeter Wemm 340e3d5408SPeter Wemm 350e3d5408SPeter Wemm /* 360e3d5408SPeter Wemm * tputs.c 370e3d5408SPeter Wemm * delay_output() 380e3d5408SPeter Wemm * _nc_outch() 390e3d5408SPeter Wemm * tputs() 400e3d5408SPeter Wemm * 410e3d5408SPeter Wemm */ 420e3d5408SPeter Wemm 430e3d5408SPeter Wemm #include <curses.priv.h> 440e3d5408SPeter Wemm #include <ctype.h> 450e3d5408SPeter Wemm #include <term.h> /* padding_baud_rate, xon_xoff */ 460e3d5408SPeter Wemm #include <termcap.h> /* ospeed */ 470e3d5408SPeter Wemm #include <tic.h> 480e3d5408SPeter Wemm 491759abf3SPeter Wemm MODULE_ID("$Id: lib_tputs.c,v 1.41 1999/10/22 23:31:24 tom Exp $") 500e3d5408SPeter Wemm 510e3d5408SPeter Wemm char PC; /* used by termcap library */ 520e3d5408SPeter Wemm speed_t ospeed; /* used by termcap library */ 530e3d5408SPeter Wemm 540e3d5408SPeter Wemm int _nc_nulls_sent; /* used by 'tack' program */ 550e3d5408SPeter Wemm 560e3d5408SPeter Wemm static int (*my_outch)(int c) = _nc_outch; 570e3d5408SPeter Wemm 580e3d5408SPeter Wemm int delay_output(int ms) 590e3d5408SPeter Wemm { 600e3d5408SPeter Wemm T((T_CALLED("delay_output(%d)"), ms)); 610e3d5408SPeter Wemm 620e3d5408SPeter Wemm if (no_pad_char) 630e3d5408SPeter Wemm napms(ms); 640e3d5408SPeter Wemm else { 650e3d5408SPeter Wemm register int nullcount; 660e3d5408SPeter Wemm 670e3d5408SPeter Wemm nullcount = (ms * _nc_baudrate(ospeed)) / 10000; 680e3d5408SPeter Wemm for (_nc_nulls_sent += nullcount; nullcount > 0; nullcount--) 690e3d5408SPeter Wemm my_outch(PC); 700e3d5408SPeter Wemm if (my_outch == _nc_outch) 711759abf3SPeter Wemm _nc_flush(); 720e3d5408SPeter Wemm } 730e3d5408SPeter Wemm 740e3d5408SPeter Wemm returnCode(OK); 750e3d5408SPeter Wemm } 760e3d5408SPeter Wemm 770e3d5408SPeter Wemm int _nc_outch(int ch) 780e3d5408SPeter Wemm { 790e3d5408SPeter Wemm #ifdef TRACE 800e3d5408SPeter Wemm _nc_outchars++; 810e3d5408SPeter Wemm #endif /* TRACE */ 820e3d5408SPeter Wemm 831759abf3SPeter Wemm if (SP != 0 841759abf3SPeter Wemm && SP->_cleanup) { 851759abf3SPeter Wemm char tmp = ch; 861759abf3SPeter Wemm /* 871759abf3SPeter Wemm * POSIX says write() is safe in a signal handler, but the 881759abf3SPeter Wemm * buffered I/O is not. 891759abf3SPeter Wemm */ 901759abf3SPeter Wemm write(fileno(NC_OUTPUT), &tmp, 1); 911759abf3SPeter Wemm } else { 921759abf3SPeter Wemm putc(ch, NC_OUTPUT); 931759abf3SPeter Wemm } 940e3d5408SPeter Wemm return OK; 950e3d5408SPeter Wemm } 960e3d5408SPeter Wemm 970e3d5408SPeter Wemm int putp(const char *string) 980e3d5408SPeter Wemm { 990e3d5408SPeter Wemm return tputs(string, 1, _nc_outch); 1000e3d5408SPeter Wemm } 1010e3d5408SPeter Wemm 1020e3d5408SPeter Wemm int tputs(const char *string, int affcnt, int (*outc)(int)) 1030e3d5408SPeter Wemm { 1040e3d5408SPeter Wemm bool always_delay; 1050e3d5408SPeter Wemm bool normal_delay; 1060e3d5408SPeter Wemm int number; 1070e3d5408SPeter Wemm #ifdef BSD_TPUTS 1080e3d5408SPeter Wemm int trailpad; 1090e3d5408SPeter Wemm #endif /* BSD_TPUTS */ 1100e3d5408SPeter Wemm 1110e3d5408SPeter Wemm #ifdef TRACE 1120e3d5408SPeter Wemm char addrbuf[32]; 1130e3d5408SPeter Wemm 1140e3d5408SPeter Wemm if (_nc_tracing & TRACE_TPUTS) 1150e3d5408SPeter Wemm { 1160e3d5408SPeter Wemm if (outc == _nc_outch) 1170e3d5408SPeter Wemm (void) strcpy(addrbuf, "_nc_outch"); 1180e3d5408SPeter Wemm else 1190e3d5408SPeter Wemm (void) sprintf(addrbuf, "%p", outc); 1200e3d5408SPeter Wemm if (_nc_tputs_trace) { 1210e3d5408SPeter Wemm TR(TRACE_MAXIMUM, ("tputs(%s = %s, %d, %s) called", _nc_tputs_trace, _nc_visbuf(string), affcnt, addrbuf)); 1220e3d5408SPeter Wemm } 1230e3d5408SPeter Wemm else { 1240e3d5408SPeter Wemm TR(TRACE_MAXIMUM, ("tputs(%s, %d, %s) called", _nc_visbuf(string), affcnt, addrbuf)); 1250e3d5408SPeter Wemm } 1260e3d5408SPeter Wemm _nc_tputs_trace = (char *)NULL; 1270e3d5408SPeter Wemm } 1280e3d5408SPeter Wemm #endif /* TRACE */ 1290e3d5408SPeter Wemm 1300e3d5408SPeter Wemm if (!VALID_STRING(string)) 1310e3d5408SPeter Wemm return ERR; 1320e3d5408SPeter Wemm 1330e3d5408SPeter Wemm if (cur_term == 0) { 1340e3d5408SPeter Wemm always_delay = FALSE; 1350e3d5408SPeter Wemm normal_delay = TRUE; 1360e3d5408SPeter Wemm } else { 1370e3d5408SPeter Wemm always_delay = (string == bell) || (string == flash_screen); 1380e3d5408SPeter Wemm normal_delay = 1390e3d5408SPeter Wemm !xon_xoff 1400e3d5408SPeter Wemm && padding_baud_rate 1410e3d5408SPeter Wemm #ifdef NCURSES_NO_PADDING 1420e3d5408SPeter Wemm && (SP == 0 || !(SP->_no_padding)) 1430e3d5408SPeter Wemm #endif 1440e3d5408SPeter Wemm && (_nc_baudrate(ospeed) >= padding_baud_rate); 1450e3d5408SPeter Wemm } 1460e3d5408SPeter Wemm 1470e3d5408SPeter Wemm #ifdef BSD_TPUTS 1480e3d5408SPeter Wemm /* 1490e3d5408SPeter Wemm * This ugly kluge deals with the fact that some ancient BSD programs 1500e3d5408SPeter Wemm * (like nethack) actually do the likes of tputs("50") to get delays. 1510e3d5408SPeter Wemm */ 1520e3d5408SPeter Wemm trailpad = 0; 1530e3d5408SPeter Wemm if (isdigit(*string)) { 1540e3d5408SPeter Wemm while (isdigit(*string)) { 1550e3d5408SPeter Wemm trailpad = trailpad * 10 + (*string - '0'); 1560e3d5408SPeter Wemm string++; 1570e3d5408SPeter Wemm } 1580e3d5408SPeter Wemm trailpad *= 10; 1590e3d5408SPeter Wemm if (*string == '.') { 1600e3d5408SPeter Wemm string++; 1610e3d5408SPeter Wemm if (isdigit(*string)) { 1620e3d5408SPeter Wemm trailpad += (*string - '0'); 1630e3d5408SPeter Wemm string++; 1640e3d5408SPeter Wemm } 1650e3d5408SPeter Wemm while (isdigit(*string)) 1660e3d5408SPeter Wemm string++; 1670e3d5408SPeter Wemm } 1680e3d5408SPeter Wemm 1690e3d5408SPeter Wemm if (*string == '*') { 1700e3d5408SPeter Wemm trailpad *= affcnt; 1710e3d5408SPeter Wemm string++; 1720e3d5408SPeter Wemm } 1730e3d5408SPeter Wemm } 1740e3d5408SPeter Wemm #endif /* BSD_TPUTS */ 1750e3d5408SPeter Wemm 1760e3d5408SPeter Wemm my_outch = outc; /* redirect delay_output() */ 1770e3d5408SPeter Wemm while (*string) { 1780e3d5408SPeter Wemm if (*string != '$') 1790e3d5408SPeter Wemm (*outc)(*string); 1800e3d5408SPeter Wemm else { 1810e3d5408SPeter Wemm string++; 1820e3d5408SPeter Wemm if (*string != '<') { 1830e3d5408SPeter Wemm (*outc)('$'); 1840e3d5408SPeter Wemm if (*string) 1850e3d5408SPeter Wemm (*outc)(*string); 1860e3d5408SPeter Wemm } else { 1870e3d5408SPeter Wemm bool mandatory; 1880e3d5408SPeter Wemm 1890e3d5408SPeter Wemm string++; 1900e3d5408SPeter Wemm if ((!isdigit(*string) && *string != '.') || !strchr(string, '>')) { 1910e3d5408SPeter Wemm (*outc)('$'); 1920e3d5408SPeter Wemm (*outc)('<'); 1930e3d5408SPeter Wemm continue; 1940e3d5408SPeter Wemm } 1950e3d5408SPeter Wemm 1960e3d5408SPeter Wemm number = 0; 1970e3d5408SPeter Wemm while (isdigit(*string)) { 1980e3d5408SPeter Wemm number = number * 10 + (*string - '0'); 1990e3d5408SPeter Wemm string++; 2000e3d5408SPeter Wemm } 2010e3d5408SPeter Wemm number *= 10; 2020e3d5408SPeter Wemm if (*string == '.') { 2030e3d5408SPeter Wemm string++; 2040e3d5408SPeter Wemm if (isdigit(*string)) { 2050e3d5408SPeter Wemm number += (*string - '0'); 2060e3d5408SPeter Wemm string++; 2070e3d5408SPeter Wemm } 2080e3d5408SPeter Wemm while (isdigit(*string)) 2090e3d5408SPeter Wemm string++; 2100e3d5408SPeter Wemm } 2110e3d5408SPeter Wemm 2120e3d5408SPeter Wemm mandatory = FALSE; 2130e3d5408SPeter Wemm while (*string == '*' || *string == '/') 2140e3d5408SPeter Wemm { 2150e3d5408SPeter Wemm if (*string == '*') { 2160e3d5408SPeter Wemm number *= affcnt; 2170e3d5408SPeter Wemm string++; 2180e3d5408SPeter Wemm } 2190e3d5408SPeter Wemm else /* if (*string == '/') */ { 2200e3d5408SPeter Wemm mandatory = TRUE; 2210e3d5408SPeter Wemm string++; 2220e3d5408SPeter Wemm } 2230e3d5408SPeter Wemm } 2240e3d5408SPeter Wemm 2250e3d5408SPeter Wemm if (number > 0 2260e3d5408SPeter Wemm && (always_delay 2270e3d5408SPeter Wemm || normal_delay 2280e3d5408SPeter Wemm || mandatory)) 2290e3d5408SPeter Wemm delay_output(number/10); 2300e3d5408SPeter Wemm 2310e3d5408SPeter Wemm } /* endelse (*string == '<') */ 2320e3d5408SPeter Wemm } /* endelse (*string == '$') */ 2330e3d5408SPeter Wemm 2340e3d5408SPeter Wemm if (*string == '\0') 2350e3d5408SPeter Wemm break; 2360e3d5408SPeter Wemm 2370e3d5408SPeter Wemm string++; 2380e3d5408SPeter Wemm } 2390e3d5408SPeter Wemm 2400e3d5408SPeter Wemm #ifdef BSD_TPUTS 2410e3d5408SPeter Wemm /* 2420e3d5408SPeter Wemm * Emit any BSD-style prefix padding that we've accumulated now. 2430e3d5408SPeter Wemm */ 2440e3d5408SPeter Wemm if (trailpad > 0 2450e3d5408SPeter Wemm && (always_delay || normal_delay)) 2460e3d5408SPeter Wemm delay_output(trailpad/10); 2470e3d5408SPeter Wemm #endif /* BSD_TPUTS */ 2480e3d5408SPeter Wemm 2490e3d5408SPeter Wemm my_outch = _nc_outch; 2500e3d5408SPeter Wemm return OK; 2510e3d5408SPeter Wemm } 252