10e3d5408SPeter Wemm /****************************************************************************
206bfebdeSXin LI  * Copyright (c) 1998-2009,2010 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>                         *
325d08fb1fSRong-En Fan  *     and: Thomas E. Dickey                        1996-on                 *
3306bfebdeSXin LI  *     and: Juergen Pfeifer                         2009                    *
340e3d5408SPeter Wemm  ****************************************************************************/
350e3d5408SPeter Wemm 
360e3d5408SPeter Wemm /*
370e3d5408SPeter Wemm  *	tputs.c
380e3d5408SPeter Wemm  *		delay_output()
390e3d5408SPeter Wemm  *		_nc_outch()
400e3d5408SPeter Wemm  *		tputs()
410e3d5408SPeter Wemm  *
420e3d5408SPeter Wemm  */
430e3d5408SPeter Wemm 
440e3d5408SPeter Wemm #include <curses.priv.h>
4506bfebdeSXin LI 
4606bfebdeSXin LI #ifndef CUR
4706bfebdeSXin LI #define CUR SP_TERMTYPE
4806bfebdeSXin LI #endif
4906bfebdeSXin LI 
500e3d5408SPeter Wemm #include <ctype.h>
510e3d5408SPeter Wemm #include <termcap.h>		/* ospeed */
520e3d5408SPeter Wemm #include <tic.h>
530e3d5408SPeter Wemm 
5406bfebdeSXin LI MODULE_ID("$Id: lib_tputs.c,v 1.81 2010/12/20 00:42:50 tom Exp $")
550e3d5408SPeter Wemm 
564a1a9510SRong-En Fan NCURSES_EXPORT_VAR(char) PC = 0;              /* used by termcap library */
577a69bbfbSPeter Wemm NCURSES_EXPORT_VAR(NCURSES_OSPEED) ospeed = 0;        /* used by termcap library */
580e3d5408SPeter Wemm 
594a1a9510SRong-En Fan NCURSES_EXPORT_VAR(int) _nc_nulls_sent = 0;   /* used by 'tack' program */
600e3d5408SPeter Wemm 
615d08fb1fSRong-En Fan #if NCURSES_NO_PADDING
625d08fb1fSRong-En Fan NCURSES_EXPORT(void)
635d08fb1fSRong-En Fan _nc_set_no_padding(SCREEN *sp)
645d08fb1fSRong-En Fan {
655d08fb1fSRong-En Fan     bool no_padding = (getenv("NCURSES_NO_PADDING") != 0);
665d08fb1fSRong-En Fan 
675d08fb1fSRong-En Fan     if (sp)
685d08fb1fSRong-En Fan 	sp->_no_padding = no_padding;
695d08fb1fSRong-En Fan     else
705d08fb1fSRong-En Fan 	_nc_prescreen._no_padding = no_padding;
715d08fb1fSRong-En Fan 
725d08fb1fSRong-En Fan     TR(TRACE_CHARPUT | TRACE_MOVE, ("padding will%s be used",
735d08fb1fSRong-En Fan 				    GetNoPadding(sp) ? " not" : ""));
745d08fb1fSRong-En Fan }
755d08fb1fSRong-En Fan #endif
765d08fb1fSRong-En Fan 
7706bfebdeSXin LI #if NCURSES_SP_FUNCS
7806bfebdeSXin LI #define SetOutCh(func) if (SP_PARM) SP_PARM->_outch = func; else _nc_prescreen._outch = func
7906bfebdeSXin LI #define GetOutCh()     (SP_PARM ? SP_PARM->_outch : _nc_prescreen._outch)
8006bfebdeSXin LI #else
8106bfebdeSXin LI #define SetOutCh(func) static_outch = func
8206bfebdeSXin LI #define GetOutCh()     static_outch
8306bfebdeSXin LI static NCURSES_SP_OUTC static_outch = NCURSES_SP_NAME(_nc_outch);
8406bfebdeSXin LI #endif
850e3d5408SPeter Wemm 
867a69bbfbSPeter Wemm NCURSES_EXPORT(int)
8706bfebdeSXin LI NCURSES_SP_NAME(delay_output) (NCURSES_SP_DCLx int ms)
880e3d5408SPeter Wemm {
8906bfebdeSXin LI     T((T_CALLED("delay_output(%p,%d)"), (void *) SP_PARM, ms));
9006bfebdeSXin LI 
9106bfebdeSXin LI     if (!HasTInfoTerminal(SP_PARM))
9206bfebdeSXin LI 	returnCode(ERR);
930e3d5408SPeter Wemm 
9415589c42SPeter Wemm     if (no_pad_char) {
9506bfebdeSXin LI 	NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_ARG);
960e3d5408SPeter Wemm 	napms(ms);
9715589c42SPeter Wemm     } else {
9806bfebdeSXin LI 	NCURSES_SP_OUTC my_outch = GetOutCh();
990e3d5408SPeter Wemm 	register int nullcount;
1000e3d5408SPeter Wemm 
1014a1a9510SRong-En Fan 	nullcount = (ms * _nc_baudrate(ospeed)) / (BAUDBYTE * 1000);
1020e3d5408SPeter Wemm 	for (_nc_nulls_sent += nullcount; nullcount > 0; nullcount--)
10306bfebdeSXin LI 	    my_outch(NCURSES_SP_ARGx PC);
10406bfebdeSXin LI 	if (my_outch == NCURSES_SP_NAME(_nc_outch))
10506bfebdeSXin LI 	    NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_ARG);
1060e3d5408SPeter Wemm     }
1070e3d5408SPeter Wemm 
1080e3d5408SPeter Wemm     returnCode(OK);
1090e3d5408SPeter Wemm }
1100e3d5408SPeter Wemm 
11106bfebdeSXin LI #if NCURSES_SP_FUNCS
11206bfebdeSXin LI NCURSES_EXPORT(int)
11306bfebdeSXin LI delay_output(int ms)
11406bfebdeSXin LI {
11506bfebdeSXin LI     return NCURSES_SP_NAME(delay_output) (CURRENT_SCREEN, ms);
11606bfebdeSXin LI }
11706bfebdeSXin LI #endif
11806bfebdeSXin LI 
11906bfebdeSXin LI NCURSES_EXPORT(void)
12006bfebdeSXin LI NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_DCL0)
12106bfebdeSXin LI {
12206bfebdeSXin LI     (void) fflush(NC_OUTPUT(SP_PARM));
12306bfebdeSXin LI }
12406bfebdeSXin LI 
12506bfebdeSXin LI #if NCURSES_SP_FUNCS
1267a69bbfbSPeter Wemm NCURSES_EXPORT(void)
12715589c42SPeter Wemm _nc_flush(void)
12815589c42SPeter Wemm {
12906bfebdeSXin LI     NCURSES_SP_NAME(_nc_flush) (CURRENT_SCREEN);
13015589c42SPeter Wemm }
13106bfebdeSXin LI #endif
13215589c42SPeter Wemm 
1337a69bbfbSPeter Wemm NCURSES_EXPORT(int)
13406bfebdeSXin LI NCURSES_SP_NAME(_nc_outch) (NCURSES_SP_DCLx int ch)
1350e3d5408SPeter Wemm {
13606bfebdeSXin LI     int rc = OK;
13706bfebdeSXin LI 
1385ca44d1cSRong-En Fan     COUNT_OUTCHARS(1);
1390e3d5408SPeter Wemm 
14006bfebdeSXin LI     if (HasTInfoTerminal(SP_PARM)
14106bfebdeSXin LI 	&& SP_PARM != 0
14206bfebdeSXin LI 	&& SP_PARM->_cleanup) {
14306bfebdeSXin LI 	char tmp = (char) ch;
1441759abf3SPeter Wemm 	/*
1451759abf3SPeter Wemm 	 * POSIX says write() is safe in a signal handler, but the
1461759abf3SPeter Wemm 	 * buffered I/O is not.
1471759abf3SPeter Wemm 	 */
14806bfebdeSXin LI 	if (write(fileno(NC_OUTPUT(SP_PARM)), &tmp, 1) == -1)
14906bfebdeSXin LI 	    rc = ERR;
1501759abf3SPeter Wemm     } else {
15106bfebdeSXin LI 	if (putc(ch, NC_OUTPUT(SP_PARM)) == EOF)
15206bfebdeSXin LI 	    rc = ERR;
1531759abf3SPeter Wemm     }
15406bfebdeSXin LI     return rc;
1550e3d5408SPeter Wemm }
1560e3d5408SPeter Wemm 
15706bfebdeSXin LI #if NCURSES_SP_FUNCS
15806bfebdeSXin LI NCURSES_EXPORT(int)
15906bfebdeSXin LI _nc_outch(int ch)
16006bfebdeSXin LI {
16106bfebdeSXin LI     return NCURSES_SP_NAME(_nc_outch) (CURRENT_SCREEN, ch);
16206bfebdeSXin LI }
16306bfebdeSXin LI #endif
16406bfebdeSXin LI 
16506bfebdeSXin LI NCURSES_EXPORT(int)
16606bfebdeSXin LI NCURSES_SP_NAME(putp) (NCURSES_SP_DCLx const char *string)
16706bfebdeSXin LI {
16806bfebdeSXin LI     return NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
16906bfebdeSXin LI 				   string, 1, NCURSES_SP_NAME(_nc_outch));
17006bfebdeSXin LI }
17106bfebdeSXin LI 
17206bfebdeSXin LI NCURSES_EXPORT(int)
17306bfebdeSXin LI NCURSES_SP_NAME(_nc_putp) (NCURSES_SP_DCLx
17406bfebdeSXin LI 			   const char *name GCC_UNUSED,
17506bfebdeSXin LI 			   const char *string)
17606bfebdeSXin LI {
17706bfebdeSXin LI     int rc = ERR;
17806bfebdeSXin LI 
17906bfebdeSXin LI     if (string != 0) {
18006bfebdeSXin LI 	TPUTS_TRACE(name);
18106bfebdeSXin LI 	rc = NCURSES_SP_NAME(putp) (NCURSES_SP_ARGx string);
18206bfebdeSXin LI     }
18306bfebdeSXin LI     return rc;
18406bfebdeSXin LI }
18506bfebdeSXin LI 
18606bfebdeSXin LI #if NCURSES_SP_FUNCS
1877a69bbfbSPeter Wemm NCURSES_EXPORT(int)
18815589c42SPeter Wemm putp(const char *string)
1890e3d5408SPeter Wemm {
19006bfebdeSXin LI     return NCURSES_SP_NAME(putp) (CURRENT_SCREEN, string);
1910e3d5408SPeter Wemm }
1920e3d5408SPeter Wemm 
1937a69bbfbSPeter Wemm NCURSES_EXPORT(int)
19406bfebdeSXin LI _nc_putp(const char *name, const char *string)
1950e3d5408SPeter Wemm {
19606bfebdeSXin LI     return NCURSES_SP_NAME(_nc_putp) (CURRENT_SCREEN, name, string);
19706bfebdeSXin LI }
19806bfebdeSXin LI #endif
19906bfebdeSXin LI 
20006bfebdeSXin LI NCURSES_EXPORT(int)
20106bfebdeSXin LI NCURSES_SP_NAME(tputs) (NCURSES_SP_DCLx
20206bfebdeSXin LI 			const char *string,
20306bfebdeSXin LI 			int affcnt,
20406bfebdeSXin LI 			NCURSES_SP_OUTC outc)
20506bfebdeSXin LI {
20606bfebdeSXin LI     NCURSES_SP_OUTC my_outch = GetOutCh();
2070e3d5408SPeter Wemm     bool always_delay;
2080e3d5408SPeter Wemm     bool normal_delay;
2090e3d5408SPeter Wemm     int number;
21018259542SPeter Wemm #if BSD_TPUTS
2110e3d5408SPeter Wemm     int trailpad;
2120e3d5408SPeter Wemm #endif /* BSD_TPUTS */
2130e3d5408SPeter Wemm 
2140e3d5408SPeter Wemm #ifdef TRACE
2150e3d5408SPeter Wemm     char addrbuf[32];
2160e3d5408SPeter Wemm 
2175ca44d1cSRong-En Fan     if (USE_TRACEF(TRACE_TPUTS)) {
21806bfebdeSXin LI 	if (outc == NCURSES_SP_NAME(_nc_outch))
2190e3d5408SPeter Wemm 	    (void) strcpy(addrbuf, "_nc_outch");
2200e3d5408SPeter Wemm 	else
2210e3d5408SPeter Wemm 	    (void) sprintf(addrbuf, "%p", outc);
2220e3d5408SPeter Wemm 	if (_nc_tputs_trace) {
22315589c42SPeter Wemm 	    _tracef("tputs(%s = %s, %d, %s) called", _nc_tputs_trace,
22415589c42SPeter Wemm 		    _nc_visbuf(string), affcnt, addrbuf);
22515589c42SPeter Wemm 	} else {
22615589c42SPeter Wemm 	    _tracef("tputs(%s, %d, %s) called", _nc_visbuf(string), affcnt, addrbuf);
2270e3d5408SPeter Wemm 	}
2285ca44d1cSRong-En Fan 	TPUTS_TRACE(NULL);
2295ca44d1cSRong-En Fan 	_nc_unlock_global(tracef);
2300e3d5408SPeter Wemm     }
2310e3d5408SPeter Wemm #endif /* TRACE */
2320e3d5408SPeter Wemm 
23306bfebdeSXin LI     if (SP_PARM != 0 && !HasTInfoTerminal(SP_PARM))
23406bfebdeSXin LI 	return ERR;
23506bfebdeSXin LI 
2360e3d5408SPeter Wemm     if (!VALID_STRING(string))
2370e3d5408SPeter Wemm 	return ERR;
2380e3d5408SPeter Wemm 
23906bfebdeSXin LI     if (
24006bfebdeSXin LI #if NCURSES_SP_FUNCS
24106bfebdeSXin LI 	   (SP_PARM != 0 && SP_PARM->_term == 0)
24206bfebdeSXin LI #else
24306bfebdeSXin LI 	   cur_term == 0
24406bfebdeSXin LI #endif
24506bfebdeSXin LI 	) {
2460e3d5408SPeter Wemm 	always_delay = FALSE;
2470e3d5408SPeter Wemm 	normal_delay = TRUE;
2480e3d5408SPeter Wemm     } else {
2490e3d5408SPeter Wemm 	always_delay = (string == bell) || (string == flash_screen);
2500e3d5408SPeter Wemm 	normal_delay =
2510e3d5408SPeter Wemm 	    !xon_xoff
2520e3d5408SPeter Wemm 	    && padding_baud_rate
25318259542SPeter Wemm #if NCURSES_NO_PADDING
25406bfebdeSXin LI 	    && !GetNoPadding(SP_PARM)
2550e3d5408SPeter Wemm #endif
2560e3d5408SPeter Wemm 	    && (_nc_baudrate(ospeed) >= padding_baud_rate);
2570e3d5408SPeter Wemm     }
2580e3d5408SPeter Wemm 
25918259542SPeter Wemm #if BSD_TPUTS
2600e3d5408SPeter Wemm     /*
2610e3d5408SPeter Wemm      * This ugly kluge deals with the fact that some ancient BSD programs
2620e3d5408SPeter Wemm      * (like nethack) actually do the likes of tputs("50") to get delays.
2630e3d5408SPeter Wemm      */
2640e3d5408SPeter Wemm     trailpad = 0;
26539f2269fSPeter Wemm     if (isdigit(UChar(*string))) {
26639f2269fSPeter Wemm 	while (isdigit(UChar(*string))) {
2670e3d5408SPeter Wemm 	    trailpad = trailpad * 10 + (*string - '0');
2680e3d5408SPeter Wemm 	    string++;
2690e3d5408SPeter Wemm 	}
2700e3d5408SPeter Wemm 	trailpad *= 10;
2710e3d5408SPeter Wemm 	if (*string == '.') {
2720e3d5408SPeter Wemm 	    string++;
27339f2269fSPeter Wemm 	    if (isdigit(UChar(*string))) {
2740e3d5408SPeter Wemm 		trailpad += (*string - '0');
2750e3d5408SPeter Wemm 		string++;
2760e3d5408SPeter Wemm 	    }
27739f2269fSPeter Wemm 	    while (isdigit(UChar(*string)))
2780e3d5408SPeter Wemm 		string++;
2790e3d5408SPeter Wemm 	}
2800e3d5408SPeter Wemm 
2810e3d5408SPeter Wemm 	if (*string == '*') {
2820e3d5408SPeter Wemm 	    trailpad *= affcnt;
2830e3d5408SPeter Wemm 	    string++;
2840e3d5408SPeter Wemm 	}
2850e3d5408SPeter Wemm     }
2860e3d5408SPeter Wemm #endif /* BSD_TPUTS */
2870e3d5408SPeter Wemm 
28806bfebdeSXin LI     SetOutCh(outc);		/* redirect delay_output() */
2890e3d5408SPeter Wemm     while (*string) {
2900e3d5408SPeter Wemm 	if (*string != '$')
29106bfebdeSXin LI 	    (*outc) (NCURSES_SP_ARGx *string);
2920e3d5408SPeter Wemm 	else {
2930e3d5408SPeter Wemm 	    string++;
2940e3d5408SPeter Wemm 	    if (*string != '<') {
29506bfebdeSXin LI 		(*outc) (NCURSES_SP_ARGx '$');
2960e3d5408SPeter Wemm 		if (*string)
29706bfebdeSXin LI 		    (*outc) (NCURSES_SP_ARGx *string);
2980e3d5408SPeter Wemm 	    } else {
2990e3d5408SPeter Wemm 		bool mandatory;
3000e3d5408SPeter Wemm 
3010e3d5408SPeter Wemm 		string++;
30239f2269fSPeter Wemm 		if ((!isdigit(UChar(*string)) && *string != '.')
3037a69bbfbSPeter Wemm 		    || !strchr(string, '>')) {
30406bfebdeSXin LI 		    (*outc) (NCURSES_SP_ARGx '$');
30506bfebdeSXin LI 		    (*outc) (NCURSES_SP_ARGx '<');
3060e3d5408SPeter Wemm 		    continue;
3070e3d5408SPeter Wemm 		}
3080e3d5408SPeter Wemm 
3090e3d5408SPeter Wemm 		number = 0;
31039f2269fSPeter Wemm 		while (isdigit(UChar(*string))) {
3110e3d5408SPeter Wemm 		    number = number * 10 + (*string - '0');
3120e3d5408SPeter Wemm 		    string++;
3130e3d5408SPeter Wemm 		}
3140e3d5408SPeter Wemm 		number *= 10;
3150e3d5408SPeter Wemm 		if (*string == '.') {
3160e3d5408SPeter Wemm 		    string++;
31739f2269fSPeter Wemm 		    if (isdigit(UChar(*string))) {
3180e3d5408SPeter Wemm 			number += (*string - '0');
3190e3d5408SPeter Wemm 			string++;
3200e3d5408SPeter Wemm 		    }
32139f2269fSPeter Wemm 		    while (isdigit(UChar(*string)))
3220e3d5408SPeter Wemm 			string++;
3230e3d5408SPeter Wemm 		}
3240e3d5408SPeter Wemm 
3250e3d5408SPeter Wemm 		mandatory = FALSE;
32615589c42SPeter Wemm 		while (*string == '*' || *string == '/') {
3270e3d5408SPeter Wemm 		    if (*string == '*') {
3280e3d5408SPeter Wemm 			number *= affcnt;
3290e3d5408SPeter Wemm 			string++;
33015589c42SPeter Wemm 		    } else {	/* if (*string == '/') */
3310e3d5408SPeter Wemm 			mandatory = TRUE;
3320e3d5408SPeter Wemm 			string++;
3330e3d5408SPeter Wemm 		    }
3340e3d5408SPeter Wemm 		}
3350e3d5408SPeter Wemm 
3360e3d5408SPeter Wemm 		if (number > 0
3370e3d5408SPeter Wemm 		    && (always_delay
3380e3d5408SPeter Wemm 			|| normal_delay
3390e3d5408SPeter Wemm 			|| mandatory))
34006bfebdeSXin LI 		    NCURSES_SP_NAME(delay_output) (NCURSES_SP_ARGx number / 10);
3410e3d5408SPeter Wemm 
3420e3d5408SPeter Wemm 	    }			/* endelse (*string == '<') */
3430e3d5408SPeter Wemm 	}			/* endelse (*string == '$') */
3440e3d5408SPeter Wemm 
3450e3d5408SPeter Wemm 	if (*string == '\0')
3460e3d5408SPeter Wemm 	    break;
3470e3d5408SPeter Wemm 
3480e3d5408SPeter Wemm 	string++;
3490e3d5408SPeter Wemm     }
3500e3d5408SPeter Wemm 
35118259542SPeter Wemm #if BSD_TPUTS
3520e3d5408SPeter Wemm     /*
3530e3d5408SPeter Wemm      * Emit any BSD-style prefix padding that we've accumulated now.
3540e3d5408SPeter Wemm      */
3550e3d5408SPeter Wemm     if (trailpad > 0
3560e3d5408SPeter Wemm 	&& (always_delay || normal_delay))
3570e3d5408SPeter Wemm 	delay_output(trailpad / 10);
3580e3d5408SPeter Wemm #endif /* BSD_TPUTS */
3590e3d5408SPeter Wemm 
36006bfebdeSXin LI     SetOutCh(my_outch);
3610e3d5408SPeter Wemm     return OK;
3620e3d5408SPeter Wemm }
36306bfebdeSXin LI 
36406bfebdeSXin LI #if NCURSES_SP_FUNCS
36506bfebdeSXin LI NCURSES_EXPORT(int)
36606bfebdeSXin LI _nc_outc_wrapper(SCREEN *sp, int c)
36706bfebdeSXin LI {
36806bfebdeSXin LI     if (0 == sp) {
36906bfebdeSXin LI 	return (ERR);
37006bfebdeSXin LI     } else {
37106bfebdeSXin LI 	return sp->jump(c);
37206bfebdeSXin LI     }
37306bfebdeSXin LI }
37406bfebdeSXin LI 
37506bfebdeSXin LI NCURSES_EXPORT(int)
37606bfebdeSXin LI tputs(const char *string, int affcnt, int (*outc) (int))
37706bfebdeSXin LI {
37806bfebdeSXin LI     SetSafeOutcWrapper(outc);
37906bfebdeSXin LI     return NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx string, affcnt, _nc_outc_wrapper);
38006bfebdeSXin LI }
38106bfebdeSXin LI #endif
382