xref: /openbsd-src/distrib/special/more/tputs.c (revision 434c844085c815c2d64647b8d0907d1d2df11b1f)
1*434c8440Sderaadt /*	$OpenBSD: tputs.c,v 1.2 2015/11/15 07:12:50 deraadt Exp $	*/
2226e3677Sderaadt /*	$NetBSD: tputs.c,v 1.5 1995/06/06 08:14:37 pk Exp $	*/
3226e3677Sderaadt 
4226e3677Sderaadt /*
5226e3677Sderaadt  * Copyright (c) 1980, 1993
6226e3677Sderaadt  *	The Regents of the University of California.  All rights reserved.
7226e3677Sderaadt  *
8226e3677Sderaadt  * Redistribution and use in source and binary forms, with or without
9226e3677Sderaadt  * modification, are permitted provided that the following conditions
10226e3677Sderaadt  * are met:
11226e3677Sderaadt  * 1. Redistributions of source code must retain the above copyright
12226e3677Sderaadt  *    notice, this list of conditions and the following disclaimer.
13226e3677Sderaadt  * 2. Redistributions in binary form must reproduce the above copyright
14226e3677Sderaadt  *    notice, this list of conditions and the following disclaimer in the
15226e3677Sderaadt  *    documentation and/or other materials provided with the distribution.
16226e3677Sderaadt  * 3. Neither the name of the University nor the names of its contributors
17226e3677Sderaadt  *    may be used to endorse or promote products derived from this software
18226e3677Sderaadt  *    without specific prior written permission.
19226e3677Sderaadt  *
20226e3677Sderaadt  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21226e3677Sderaadt  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22226e3677Sderaadt  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23226e3677Sderaadt  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24226e3677Sderaadt  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25226e3677Sderaadt  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26226e3677Sderaadt  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27226e3677Sderaadt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28226e3677Sderaadt  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29226e3677Sderaadt  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30226e3677Sderaadt  * SUCH DAMAGE.
31226e3677Sderaadt  */
32226e3677Sderaadt 
33226e3677Sderaadt #include <ctype.h>
34226e3677Sderaadt #include <curses.h>
35226e3677Sderaadt #undef ospeed
36226e3677Sderaadt 
37226e3677Sderaadt /*
38226e3677Sderaadt  * The following array gives the number of tens of milliseconds per
39226e3677Sderaadt  * character for each speed as returned by gtty.  Thus since 300
40226e3677Sderaadt  * baud returns a 7, there are 33.3 milliseconds per char at 300 baud.
41226e3677Sderaadt  */
42226e3677Sderaadt static
43226e3677Sderaadt short	tmspc10[] = {
44226e3677Sderaadt 	0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5
45226e3677Sderaadt };
46226e3677Sderaadt 
47226e3677Sderaadt short	ospeed;
48226e3677Sderaadt char	PC;
49226e3677Sderaadt 
50226e3677Sderaadt /*
51226e3677Sderaadt  * Put the character string cp out, with padding.
52226e3677Sderaadt  * The number of affected lines is affcnt, and the routine
53226e3677Sderaadt  * used to output one character is outc.
54226e3677Sderaadt  */
55226e3677Sderaadt void
tputs(char * cp,int affcnt,void (* outc)(int))56*434c8440Sderaadt tputs(char *cp, int affcnt, void (*outc)(int))
57226e3677Sderaadt {
58*434c8440Sderaadt 	int i = 0, mspc10;
59226e3677Sderaadt 
60226e3677Sderaadt 	if (cp == 0)
61226e3677Sderaadt 		return;
62226e3677Sderaadt 
63226e3677Sderaadt 	/*
64226e3677Sderaadt 	 * Convert the number representing the delay.
65226e3677Sderaadt 	 */
66226e3677Sderaadt 	if (isdigit(*cp)) {
67*434c8440Sderaadt 		do {
68226e3677Sderaadt 			i = i * 10 + *cp++ - '0';
69*434c8440Sderaadt 		} while (isdigit(*cp));
70226e3677Sderaadt 	}
71226e3677Sderaadt 	i *= 10;
72226e3677Sderaadt 	if (*cp == '.') {
73226e3677Sderaadt 		cp++;
74226e3677Sderaadt 		if (isdigit(*cp))
75226e3677Sderaadt 			i += *cp - '0';
76226e3677Sderaadt 		/*
77226e3677Sderaadt 		 * Only one digit to the right of the decimal point.
78226e3677Sderaadt 		 */
79226e3677Sderaadt 		while (isdigit(*cp))
80226e3677Sderaadt 			cp++;
81226e3677Sderaadt 	}
82226e3677Sderaadt 
83226e3677Sderaadt 	/*
84226e3677Sderaadt 	 * If the delay is followed by a `*', then
85226e3677Sderaadt 	 * multiply by the affected lines count.
86226e3677Sderaadt 	 */
87226e3677Sderaadt 	if (*cp == '*')
88226e3677Sderaadt 		cp++, i *= affcnt;
89226e3677Sderaadt 
90226e3677Sderaadt 	/*
91226e3677Sderaadt 	 * The guts of the string.
92226e3677Sderaadt 	 */
93226e3677Sderaadt 	while (*cp)
94226e3677Sderaadt 		(*outc)(*cp++);
95226e3677Sderaadt 
96226e3677Sderaadt 	/*
97226e3677Sderaadt 	 * If no delay needed, or output speed is
98226e3677Sderaadt 	 * not comprehensible, then don't try to delay.
99226e3677Sderaadt 	 */
100226e3677Sderaadt 	if (i == 0)
101226e3677Sderaadt 		return;
102226e3677Sderaadt 	if (ospeed <= 0 || ospeed >= (sizeof tmspc10 / sizeof tmspc10[0]))
103226e3677Sderaadt 		return;
104226e3677Sderaadt 
105226e3677Sderaadt 	/*
106226e3677Sderaadt 	 * Round up by a half a character frame,
107226e3677Sderaadt 	 * and then do the delay.
108226e3677Sderaadt 	 * Too bad there are no user program accessible programmed delays.
109226e3677Sderaadt 	 * Transmitting pad characters slows many
110226e3677Sderaadt 	 * terminals down and also loads the system.
111226e3677Sderaadt 	 */
112226e3677Sderaadt 	mspc10 = tmspc10[ospeed];
113226e3677Sderaadt 	i += mspc10 / 2;
114226e3677Sderaadt 	for (i /= mspc10; i > 0; i--)
115226e3677Sderaadt 		(*outc)(PC);
116226e3677Sderaadt }
117