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