/* @(#)tputs.c	1.4 97/11/08 Copyright 1986 J. Schilling */
#ifndef lint
static	char sccsid[] =
	"@(#)tputs.c	1.4 97/11/08 Copyright 1986 J. Schilling";
#endif
/*
 *	Copyright (c) 1986 J. Schilling
 */
/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING.  If not, write to
 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <mconfig.h>
#include <standard.h>
#include <termcap.h>
#include <ctype.h>
#include <utypes.h>

EXPORT	int	tputs	__PR((char *sp, int affcnt, int (*outc)(int c)));

/*
 * Define exported variables.
 */
EXPORT	short	ospeed;	/* Line speed from sgtty to compute padding	*/
EXPORT	char	PC;	/* Pad Character				*/

/*
 * Table to convert the speed returned by cfgetospeed() into tens of
 * milliseconds (duration) per char.
 * B50 is 1, B75 is 2, B110 is 3 ...
 * One character at 110 baud is 90.9 ms.
 */
LOCAL short
tmspch[] = {
	0, 2000, 1333, 909, 743, 667, 500, 333, 167, 83, 56, 42, 21, 10, 5,
	3,    2,    1,   1,   1,   0,   0,   0,   0,  0,  0,  0,  0,  0, 0,
};
#define	maxspeed	(sizeof (tmspch) / sizeof (tmspch[0]))

/*
 * Output the string pointed to by 'sp', insert padding if desired.
 * 'affcnt' is the number used to multiply with the delay.
 * 'outc' is a pointer to a function to really output the char.
 */ 
EXPORT int
tputs(sp, affcnt, outc)
		 char	*sp;
		 int	affcnt;
		 int	(*outc) __PR((int c));
{
	register Uchar	*cp = (Uchar *)sp;
	register int	cdelay;		/* Delay value in # of chars */
	register int	delay = 0;	/* Delay value in tens of ms */

	if (cp == 0 || *cp == '\0')
		return (0);

	/*
	 * Convert the ms delay value (number before decimal point).
	 */
	while (isdigit(*cp)) {
		delay *= 10;
		delay += (*cp++ - '0');
	}
	delay *= 10;		/* Make it tens of milliseconds		*/

	if (*cp == '.') {	/* found decimal point			*/
		cp++;
		if (isdigit(*cp)) {
			delay += (*cp - '0');
		}
		/*
		 * Ignore the rest, only one digit past decimal point allowed.
		 */
		while (isdigit(*cp)) {
			cp++;
		}
	}
	if (*cp == '*') {	/* '*' means multiply by 'affcnt'.	*/
		cp++;
		delay *= affcnt;
	}
	while (*cp) {		/* Now outout the string		*/
		(*outc)(*cp++);
	}

	if (delay == 0)		/* No delay needed			*/
		return (0);
	/*
	 * Check if 'ospeed' is out of known range.
	 */
	if (ospeed <= 0 || ospeed >= maxspeed)
		return (0);

	/*
	 * XXX Hack: 'delay' by writing pad characters.
	 * XXX Writing pad chars may not work on all terminals.
	 * XXX If the terminal's interrupt routine is not designed for
	 * XXX delays, the effect may even be worse than without delay.
	 * XXX There should be a way to use real delays.
	 * XXX 'usleep()' is not usable because there might be characters
	 * XXX in the terminal's output queue.
	 */
	cdelay = tmspch[ospeed];/* Get delay value for actual speed	*/
	delay += cdelay / 2;	/* Round up to the next half character	*/
	delay /= cdelay;	/* Compute # of characters for delay	*/

	while (--delay >= 0) {
		(*outc)(PC);
	}
	return (0);
}
