Back to index

tetex-bin  3.0
lib_tputs.c
Go to the documentation of this file.
00001 /****************************************************************************
00002  * Copyright (c) 1998-2002,2003 Free Software Foundation, Inc.              *
00003  *                                                                          *
00004  * Permission is hereby granted, free of charge, to any person obtaining a  *
00005  * copy of this software and associated documentation files (the            *
00006  * "Software"), to deal in the Software without restriction, including      *
00007  * without limitation the rights to use, copy, modify, merge, publish,      *
00008  * distribute, distribute with modifications, sublicense, and/or sell       *
00009  * copies of the Software, and to permit persons to whom the Software is    *
00010  * furnished to do so, subject to the following conditions:                 *
00011  *                                                                          *
00012  * The above copyright notice and this permission notice shall be included  *
00013  * in all copies or substantial portions of the Software.                   *
00014  *                                                                          *
00015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
00016  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
00017  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
00018  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
00019  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
00020  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
00021  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
00022  *                                                                          *
00023  * Except as contained in this notice, the name(s) of the above copyright   *
00024  * holders shall not be used in advertising or otherwise to promote the     *
00025  * sale, use or other dealings in this Software without prior written       *
00026  * authorization.                                                           *
00027  ****************************************************************************/
00028 
00029 /****************************************************************************
00030  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
00031  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
00032  ****************************************************************************/
00033 
00034 /*
00035  *     tputs.c
00036  *            delay_output()
00037  *            _nc_outch()
00038  *            tputs()
00039  *
00040  */
00041 
00042 #include <curses.priv.h>
00043 #include <ctype.h>
00044 #include <term.h>           /* padding_baud_rate, xon_xoff */
00045 #include <termcap.h>        /* ospeed */
00046 #include <tic.h>
00047 
00048 MODULE_ID("$Id: lib_tputs.c,v 1.62 2003/08/23 21:39:20 tom Exp $")
00049 
00050 NCURSES_EXPORT_VAR(char) PC = 0;          /* used by termcap library */
00051 NCURSES_EXPORT_VAR(NCURSES_OSPEED) ospeed = 0;   /* used by termcap library */
00052 
00053 NCURSES_EXPORT_VAR(int) _nc_nulls_sent = 0;      /* used by 'tack' program */
00054 
00055 static int (*my_outch) (int c) = _nc_outch;
00056 
00057 NCURSES_EXPORT(int)
00058 delay_output(int ms)
00059 {
00060     T((T_CALLED("delay_output(%d)"), ms));
00061 
00062     if (no_pad_char) {
00063        _nc_flush();
00064        napms(ms);
00065     } else {
00066        register int nullcount;
00067 
00068        nullcount = (ms * _nc_baudrate(ospeed)) / (BAUDBYTE * 1000);
00069        for (_nc_nulls_sent += nullcount; nullcount > 0; nullcount--)
00070            my_outch(PC);
00071        if (my_outch == _nc_outch)
00072            _nc_flush();
00073     }
00074 
00075     returnCode(OK);
00076 }
00077 
00078 NCURSES_EXPORT(void)
00079 _nc_flush(void)
00080 {
00081     (void) fflush(NC_OUTPUT);
00082 }
00083 
00084 NCURSES_EXPORT(int)
00085 _nc_outch(int ch)
00086 {
00087     TRACE_OUTCHARS(1);
00088 
00089     if (SP != 0
00090        && SP->_cleanup) {
00091        char tmp = ch;
00092        /*
00093         * POSIX says write() is safe in a signal handler, but the
00094         * buffered I/O is not.
00095         */
00096        write(fileno(NC_OUTPUT), &tmp, 1);
00097     } else {
00098        putc(ch, NC_OUTPUT);
00099     }
00100     return OK;
00101 }
00102 
00103 NCURSES_EXPORT(int)
00104 putp(const char *string)
00105 {
00106     return tputs(string, 1, _nc_outch);
00107 }
00108 
00109 NCURSES_EXPORT(int)
00110 tputs(const char *string, int affcnt, int (*outc) (int))
00111 {
00112     bool always_delay;
00113     bool normal_delay;
00114     int number;
00115 #if BSD_TPUTS
00116     int trailpad;
00117 #endif /* BSD_TPUTS */
00118 
00119 #ifdef TRACE
00120     char addrbuf[32];
00121 
00122     if (_nc_tracing & TRACE_TPUTS) {
00123        if (outc == _nc_outch)
00124            (void) strcpy(addrbuf, "_nc_outch");
00125        else
00126            (void) sprintf(addrbuf, "%p", outc);
00127        if (_nc_tputs_trace) {
00128            _tracef("tputs(%s = %s, %d, %s) called", _nc_tputs_trace,
00129                   _nc_visbuf(string), affcnt, addrbuf);
00130        } else {
00131            _tracef("tputs(%s, %d, %s) called", _nc_visbuf(string), affcnt, addrbuf);
00132        }
00133        _nc_tputs_trace = (char *) NULL;
00134     }
00135 #endif /* TRACE */
00136 
00137     if (!VALID_STRING(string))
00138        return ERR;
00139 
00140     if (cur_term == 0) {
00141        always_delay = FALSE;
00142        normal_delay = TRUE;
00143     } else {
00144        always_delay = (string == bell) || (string == flash_screen);
00145        normal_delay =
00146            !xon_xoff
00147            && padding_baud_rate
00148 #if NCURSES_NO_PADDING
00149            && (SP == 0 || !(SP->_no_padding))
00150 #endif
00151            && (_nc_baudrate(ospeed) >= padding_baud_rate);
00152     }
00153 
00154 #if BSD_TPUTS
00155     /*
00156      * This ugly kluge deals with the fact that some ancient BSD programs
00157      * (like nethack) actually do the likes of tputs("50") to get delays.
00158      */
00159     trailpad = 0;
00160     if (isdigit(UChar(*string))) {
00161        while (isdigit(UChar(*string))) {
00162            trailpad = trailpad * 10 + (*string - '0');
00163            string++;
00164        }
00165        trailpad *= 10;
00166        if (*string == '.') {
00167            string++;
00168            if (isdigit(UChar(*string))) {
00169               trailpad += (*string - '0');
00170               string++;
00171            }
00172            while (isdigit(UChar(*string)))
00173               string++;
00174        }
00175 
00176        if (*string == '*') {
00177            trailpad *= affcnt;
00178            string++;
00179        }
00180     }
00181 #endif /* BSD_TPUTS */
00182 
00183     my_outch = outc;        /* redirect delay_output() */
00184     while (*string) {
00185        if (*string != '$')
00186            (*outc) (*string);
00187        else {
00188            string++;
00189            if (*string != '<') {
00190               (*outc) ('$');
00191               if (*string)
00192                   (*outc) (*string);
00193            } else {
00194               bool mandatory;
00195 
00196               string++;
00197               if ((!isdigit(UChar(*string)) && *string != '.')
00198                   || !strchr(string, '>')) {
00199                   (*outc) ('$');
00200                   (*outc) ('<');
00201                   continue;
00202               }
00203 
00204               number = 0;
00205               while (isdigit(UChar(*string))) {
00206                   number = number * 10 + (*string - '0');
00207                   string++;
00208               }
00209               number *= 10;
00210               if (*string == '.') {
00211                   string++;
00212                   if (isdigit(UChar(*string))) {
00213                      number += (*string - '0');
00214                      string++;
00215                   }
00216                   while (isdigit(UChar(*string)))
00217                      string++;
00218               }
00219 
00220               mandatory = FALSE;
00221               while (*string == '*' || *string == '/') {
00222                   if (*string == '*') {
00223                      number *= affcnt;
00224                      string++;
00225                   } else {  /* if (*string == '/') */
00226                      mandatory = TRUE;
00227                      string++;
00228                   }
00229               }
00230 
00231               if (number > 0
00232                   && (always_delay
00233                      || normal_delay
00234                      || mandatory))
00235                   delay_output(number / 10);
00236 
00237            }                /* endelse (*string == '<') */
00238        }                    /* endelse (*string == '$') */
00239 
00240        if (*string == '\0')
00241            break;
00242 
00243        string++;
00244     }
00245 
00246 #if BSD_TPUTS
00247     /*
00248      * Emit any BSD-style prefix padding that we've accumulated now.
00249      */
00250     if (trailpad > 0
00251        && (always_delay || normal_delay))
00252        delay_output(trailpad / 10);
00253 #endif /* BSD_TPUTS */
00254 
00255     my_outch = _nc_outch;
00256     return OK;
00257 }