Annotation of src/lib/libterm/tputs.c, Revision 1.23
1.23 ! christos 1: /* $NetBSD: tputs.c,v 1.22 2005/02/04 15:52:08 perry Exp $ */
1.3 cgd 2:
1.1 cgd 3: /*
1.3 cgd 4: * Copyright (c) 1980, 1993
5: * The Regents of the University of California. All rights reserved.
1.1 cgd 6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
1.21 agc 15: * 3. Neither the name of the University nor the names of its contributors
1.1 cgd 16: * may be used to endorse or promote products derived from this software
17: * without specific prior written permission.
18: *
19: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29: * SUCH DAMAGE.
30: */
31:
1.6 lukem 32: #include <sys/cdefs.h>
1.1 cgd 33: #ifndef lint
1.3 cgd 34: #if 0
35: static char sccsid[] = "@(#)tputs.c 8.1 (Berkeley) 6/4/93";
36: #else
1.23 ! christos 37: __RCSID("$NetBSD: tputs.c,v 1.22 2005/02/04 15:52:08 perry Exp $");
1.3 cgd 38: #endif
1.1 cgd 39: #endif /* not lint */
40:
1.12 lukem 41: #include <assert.h>
1.1 cgd 42: #include <ctype.h>
1.7 lukem 43: #include <termcap.h>
1.10 blymn 44: #include <stdio.h>
1.15 itojun 45: #include <stdlib.h>
1.23 ! christos 46: #include "termcap_private.h"
1.4 pk 47: #undef ospeed
1.1 cgd 48:
1.10 blymn 49: /* internal functions */
1.22 perry 50: int _tputs_convert(const char **, int);
1.10 blymn 51:
1.1 cgd 52: /*
53: * The following array gives the number of tens of milliseconds per
54: * character for each speed as returned by gtty. Thus since 300
55: * baud returns a 7, there are 33.3 milliseconds per char at 300 baud.
56: */
1.23 ! christos 57: const short __tmspc10[TMSPC10SIZE] = {
1.1 cgd 58: 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5
59: };
60:
61: short ospeed;
62: char PC;
63:
1.10 blymn 64: int
1.22 perry 65: _tputs_convert(const char **ptr, int affcnt)
1.10 blymn 66: {
1.15 itojun 67: int i = 0;
68:
1.18 lukem 69: _DIAGASSERT(ptr != NULL);
70: _DIAGASSERT(*ptr != NULL);
71:
1.15 itojun 72: /*
73: * Convert the number representing the delay.
74: */
1.17 christos 75: if (isdigit(*(const unsigned char *)(*ptr))) {
1.10 blymn 76: do
77: i = i * 10 + *(*ptr)++ - '0';
1.17 christos 78: while (isdigit(*(const unsigned char *)(*ptr)));
1.10 blymn 79: }
80: i *= 10;
81: if (*(*ptr) == '.') {
82: (*ptr)++;
1.17 christos 83: if (isdigit(*(const unsigned char *)(*ptr)))
1.10 blymn 84: i += *(*ptr) - '0';
85: /*
86: * Only one digit to the right of the decimal point.
87: */
1.17 christos 88: while (isdigit(*(const unsigned char *)(*ptr)))
1.10 blymn 89: (*ptr)++;
90: }
91:
92: /*
93: * If the delay is followed by a `*', then
94: * multiply by the affected lines count.
95: */
96: if (*(*ptr) == '*')
97: (*ptr)++, i *= affcnt;
98:
1.15 itojun 99: return i;
1.10 blymn 100: }
101:
1.1 cgd 102: /*
103: * Put the character string cp out, with padding.
104: * The number of affected lines is affcnt, and the routine
105: * used to output one character is outc.
106: */
1.4 pk 107: void
1.22 perry 108: tputs(const char *cp, int affcnt, int (*outc)(int))
1.1 cgd 109: {
1.7 lukem 110: int i = 0;
111: int mspc10;
1.12 lukem 112:
113: _DIAGASSERT(outc != 0);
1.1 cgd 114:
115: if (cp == 0)
116: return;
117:
1.15 itojun 118: /* scan and convert delay digits (if any) */
119: i = _tputs_convert(&cp, affcnt);
120:
1.10 blymn 121: /*
122: * The guts of the string.
123: */
124: while (*cp)
1.14 lukem 125: (void)(*outc)(*cp++);
1.10 blymn 126:
1.1 cgd 127: /*
1.10 blymn 128: * If no delay needed, or output speed is
129: * not comprehensible, then don't try to delay.
1.1 cgd 130: */
1.10 blymn 131: if (i == 0)
132: return;
1.23 ! christos 133: if (ospeed <= 0 || ospeed >= TMSPC10SIZE)
1.10 blymn 134: return;
1.1 cgd 135:
136: /*
1.10 blymn 137: * Round up by a half a character frame,
138: * and then do the delay.
139: * Too bad there are no user program accessible programmed delays.
140: * Transmitting pad characters slows many
141: * terminals down and also loads the system.
1.1 cgd 142: */
1.23 ! christos 143: mspc10 = __tmspc10[ospeed];
1.10 blymn 144: i += mspc10 / 2;
145: for (i /= mspc10; i > 0; i--)
1.14 lukem 146: (void)(*outc)(PC);
1.10 blymn 147: }
148:
149:
150: int
1.22 perry 151: t_puts(struct tinfo *info, const char *cp, int affcnt,
152: void (*outc)(char, void *), void *args)
1.10 blymn 153: {
1.11 blymn 154: int i = 0;
1.15 itojun 155: size_t limit;
1.10 blymn 156: int mspc10;
1.15 itojun 157: char pad[2], *pptr;
158: char *pc;
159:
1.18 lukem 160: /* XXX: info may be NULL ? */
161: /* cp is handled below */
162: _DIAGASSERT(outc != NULL);
163: _DIAGASSERT(args != NULL);
164:
165: if (info != NULL) {
1.15 itojun 166: /*
167: * if we have info then get the pad char from the
168: * termcap entry if it exists, otherwise use the
169: * default NUL char.
170: */
171: pptr = pad;
172: limit = sizeof(pad);
173: pc = t_getstr(info, "pc", &pptr, &limit);
174: if (pc == NULL)
175: pad[0] = '\0';
176: else
177: free(pc);
178: }
1.1 cgd 179:
1.10 blymn 180: if (cp == 0)
181: return -1;
182:
1.15 itojun 183: /* scan and convert delay digits (if any) */
184: i = _tputs_convert(&cp, affcnt);
185:
1.1 cgd 186: /*
187: * The guts of the string.
188: */
189: while (*cp)
1.10 blymn 190: (*outc)(*cp++, args);
1.1 cgd 191:
192: /*
193: * If no delay needed, or output speed is
194: * not comprehensible, then don't try to delay.
195: */
196: if (i == 0)
1.10 blymn 197: return 0;
1.23 ! christos 198: if (ospeed <= 0 || ospeed >= TMSPC10SIZE)
1.10 blymn 199: return 0;
1.1 cgd 200:
201: /*
202: * Round up by a half a character frame,
203: * and then do the delay.
204: * Too bad there are no user program accessible programmed delays.
205: * Transmitting pad characters slows many
206: * terminals down and also loads the system.
207: */
1.23 ! christos 208: mspc10 = __tmspc10[ospeed];
1.1 cgd 209: i += mspc10 / 2;
210: for (i /= mspc10; i > 0; i--)
1.10 blymn 211: (*outc)(pad[0], args);
212:
1.15 itojun 213: return 0;
1.1 cgd 214: }
CVSweb <webmaster@jp.NetBSD.org>