/* @(#)tvout.c 17.1.1.1 (ES0-DMD) 01/25/02 17:36:57 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) 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 of the License, 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; if not, write to the Free Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .TYPE Module .IDENTIFICATION tvout.c .AUTHOR Francois Ochsenbein [ESO-IPG] .LANGUAGE C .KEYWORDS Terminal Independant Window Package. .ENVIRONMENT TermWindows .COMMENTS This module groups direct output to terminal (interfaces to ost), without checks on the validity of the output or cursor positionning. \begin{TeX} Used Capabilities: $$\begin{tabular}{|lp{30em}|}\hline {\tt pc=} & Padding char (for delays) \\ {\tt G0{\rm...}G4=} & Corners \\ {\tt Gu,Gd,Gl,Gr=} & Tees \\ {\tt Gg=} & ``Rubbish'' character \\ \hline \end{tabular}$$ \end{TeX} .VERSION 2.1 11-Jun-1987 Version '2' of TermWindows. Extracted from previous ZTOUT. .VERSION 3.0 20-Mar-1988 Version '3' of TermWindows. ----------------------------------------------------------------------------*/ #define DEBUG 0 /* For debugging */ #define PM_LEVEL LEVEL_TV #define TW_MACROS 0 /* Don't use TermWindows Macros */ #define TW_import 0 #define TW_STRUCT 0 /* Do not use window Structures */ #include #define ms_to_pad(ms) ((terms->baud/100) * ms)/(unsigned)100 MID_EXTERN TERM *terms ; MID_STATIC char delay_flag = EOS; #if DEBUG #define ENTER_DEBUG(x) ENTER(x) #define EXIT_DEBUG(x) EXIT(x) #else #define ENTER_DEBUG(x) #define EXIT_DEBUG(x) return(x) #endif #define TERMTEST #define ENTER_TV(x) static int state_buffer; \ ENTER(x); TERMTEST; \ state_buffer = tv_buffer(1); #define EXIT_TV(f) FIN: \ tv_buffer(state_buffer); \ EXIT(f) /* Macros just to improve readibility */ #define BUFW (terms->bufw) #define BUFS (terms->bufs) MONITOR (TVOUT); /*========================================================================== * tv_feed *==========================================================================*/ static int tv_feed() /*+++ .PURPOSE Write the current buffer to the terminal, and reset buffer. .RETURNS OK / NOK .REMARKS -------*/ { register int s; ENTER_DEBUG("tv_feed"); TRACE_STR2(BUFW, terms->iw); s = OK; if (terms->iw) /* Only if there is something in the buffer */ { if (terms->flags & TERM_NOWRITE) ; else { #if (TW_LEVEL == 0) /* Minimal Implementation */ s = ostwrite(BUFW, terms->iw); #else if (terms->term_type) /* No terminal */ s = osdwrite(1, BUFW, terms->iw); else { s = ostwrite(BUFW, terms->iw); if (terms->msw) tv_wms(terms->msw); } } } #endif if (s < 0) ERROR(osmsg()), s = NOK; else s = OK; terms->iw = 0; EXIT_DEBUG(s); } /*========================================================================== * tv_buffer *==========================================================================*/ int tv_buffer (buffered) /*+++ .PURPOSE Start (buffered!=0) or Stop (buffered==0) terminal buffering .RETURNS The previous state, i.e. 0 if terminal was unbuffered, not-zero if terminal was buffered. .REMARKS If unbuffering is asked for, the contents of the buffer is sent to the terminal. NOT TRACED. ---*/ int buffered; /* IN: 1 to start, 0 to stop buffering */ { register int returned; returned = (terms->flags) & (TERM_buffered); if(buffered) terms->flags |= TERM_buffered; else { if (terms->iw) /* If there is something in the buffer */ tv_feed(); /* Send the buffer contents */ terms->flags &= ~(TERM_buffered); } return(returned); } /*========================================================================== * compute_delay *==========================================================================*/ static int compute_delay(str) /* .PURPOSE Compute the delay required by a sequence. .RETURNS The delay converted into a number of padding chars. .REMARKS Not Traced. -----------------------------------------------------------------------*/ char *str; /* IN: The capability string */ { register int delay; delay = 0; delay_flag = *(str+3); if (delay_flag != '=') /* A delay is required */ { delay = (unsigned char)*(str+4+ *(unsigned char *)str); /* Delay in ms */ delay = ms_to_pad(delay); /* Delay in number of padding chars */ } return(delay); } /*========================================================================== * tv_delay *==========================================================================*/ int tv_delay(str) /*++++++++++ .PURPOSE Send the delay (only) of a sequence, in principle made of NUL characters. .RETURNS OK / NOK .REMARKS -----------------------------------------------------------------------*/ char *str; /* IN: The capability string */ { register int delay; ENTER_DEBUG("tv_delay"); status = OK; delay = compute_delay(str); /* Delay in number of padding chars */ if(delay) { if (delay > terms->buf_size) delay = terms->buf_size; oscfill(BUFS,delay,terms->pad_char); status = tv_out(BUFS,delay); } EXIT_DEBUG(status); } /*========================================================================== * tv_out *==========================================================================*/ int tv_out(str,len) /*++++++++++++ .PURPOSE Write any string of characters to the terminal, with buffering. No care taken about control characters, cursor position, etc. .RETURNS OK / NOK .REMARKS The buffer is only filled, and sent to terminal when full. Use tv_feed to output the buffer. --------------*/ char *str; /* IN: String to display on the terminal */ int len; /* IN: Length of String */ { register int i, l; char *p, *q; ENTER_DEBUG("tv_out"); status = OK; TRACE_ED_STR2("tv_out of: ", str, len); for (l = len, p = str, i = 0; (l > 0) && (status); l -= i, p += i) { i = terms->buf_size - terms->iw; i = MIN(l, i); q = BUFW + terms->iw; terms->iw += oscopy(q, p, i); if (terms->iw >= terms->buf_size) status = tv_feed(); } EXIT_DEBUG(status); } /*========================================================================== * tv_send *==========================================================================*/ int tv_send(str, times) /*++++++++++ .PURPOSE Send a sequence n times. This sequence has the encoded form of a capability (see tu_encode) .RETURNS OK / NOK .REMARKS The delay is made by sending additional padding chars. ----------*/ char *str; /* IN: The string to send */ int times; /* IN: Number of times to send the string */ { int ls, n; int delay; ENTER_TV("tv_send"); #if DEBUG TRACE_ED_I("Sending sequence times: ", times); #endif status = OK; if(times <= 0) FINISH; /* Nothing to send ... */ if(!str) FINISH; ls = *str; if(ls == 0) FINISH; delay = compute_delay(str); /* Delay in number of padding chars */ /* Output the text in a loop */ if (delay) /* A delay is required */ { if (delay > terms->buf_size) delay = terms->buf_size; oscfill(BUFS, delay, terms->pad_char); } for (n=times; --n>=0; ) { if (!(status = tv_out(str+4,ls))) FINISH; if(delay_flag == 'D') if (!(status = tv_out(BUFS,delay))) FINISH; } if (delay_flag == 'd') status = tv_out(BUFS,delay); EXIT_TV(status); } /*========================================================================== * tv_wms(ms) *==========================================================================*/ int tv_wms(ms) /*++++++ .PURPOSE Simulate a waiting time (by sending padding chars) .RETURNS OK .REMARKS Send directly the padding chars to terminal (no buffering) ------------*/ short unsigned int ms; /* IN: Number of ms waiting time to simulate */ { register int delay, n; ENTER("tv_wms"); if (terms->term_type) FINISH; /* No terminal */ delay = ms_to_pad((int)ms); oscfill(BUFS, MIN(delay, terms->buf_size), terms->pad_char); status = 0; while ( (delay > 0) && (status >= 0) ) { n = MIN(delay, terms->buf_size); status = ostwrite(BUFS, n); delay -= n; } if (status < 0) ERROR(osmsg()); FIN: EXIT(OK); }