/* @(#)tvclear.c 17.1.1.1 (ES0-DMD) 01/25/02 17:48:04 */ /*=========================================================================== 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 tvclear.c .AUTHOR Francois Ochsenbein [ESO-IPG] .LANGUAGE C .KEYWORDS Terminal Independant i/o Package. .ENVIRONMENT TermWindows .COMMENTS This module includes clear functions. \begin{TeX} Used Capabilities: $$\begin{tabular}{|lp{30em}|} \hline {\tt cl=} & Clear whole screen (and cursor to home position) \\ {\tt cu=} & Clear Up (from top of screen to cursor inclusive) \\ {\tt cd=} & Clear Down (from cursor inclusive to bottom of screen)\\ {\tt ce=} & Clear from cursor to end of line \\ {\tt cs=} & Clear from start of line to cursor inclusive \\ \hline \end{tabular}$$ \end{TeX} .VERSION 1.0 07-Jul-1986: Creation .VERSION 1.1 12-Aug-1986: Clearing lines or screen also means stop insert mode. .VERSION 1.2 23-Oct-1986: Take care of possible existing scrolling region .VERSION 2.0 03-Dec-1986 New terminal-independant graphic characters with output buffering version. .VERSION 2.1 11-Jun-1987 Modify a bit for hard_copy terminals: Useless to clear characters!!! .VERSION 2.2 23-Jun-1987 Adapted to UNIX .VERSION 3.0 20-Mar-1988 Version '3' of TermWindows. ----------------------------------------------------------------------------*/ #define DEBUG 0 /* Only 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 MID_RSTATIC char clear_cap[] = "cucdcbce"; MID_STATIC short int old_pos[2] = {0,0}; #if DEBUG # define TERMTEST if(!terms->version) tv_gopen();\ tv_ed(terms) #else # define TERMTEST if(!terms->version) tv_gopen() #endif #define FIN_CURSOR goto RESET_CURSOR #define ENTER_TV(x) static int state_buffer; \ ENTER(x); TERMTEST; \ state_buffer = tv_buffer(TRUE); #define EXIT_TV(f) FIN: \ tv_buffer(state_buffer); \ EXIT(f) MID_EXTERN TERM *terms ; #define SEND(p) tv_send(p,1) /* Macros just to improve readibility */ #define oldl old_pos[0] #define oldc old_pos[1] #define curl (terms->pos[0]) #define curc (terms->pos[1]) #define diml (terms->dim[0]) #define dimc (terms->dim[1]) #define BUFS (terms->bufs) MONITOR (ZTCLEAR); /*========================================================================== * clear_h() *==========================================================================*/ static int clear_h(dir) /*++++++++++++++++++++++++ .DES Clear at left / right of cursor (inclusive) .RET OK / NOK .REM Not traced. Never called for hard-copy terminals. Cursor moves if blanks are sent. -----------------------*/ int dir; /* IN: Direction (left or right) */ { register char *p; register int i, s; /* Use TermCapabilities when possible */ p = SearchCap(&clear_cap[dir*2]); if (p) return(SEND(p)); s = OK; if (dir == _LEFT_) { tv_out("\r",1); i = curc + 1; curc = 0; } else i = dimc - curc; if (i > 0) { oscfill(BUFS,i,' '); s = tv_line(BUFS, i); } return(s); } /*========================================================================== * tv_cc *==========================================================================*/ int tv_cc(nchar) /*+++++++++++ .DES Clear n chars from the cursor inclusive. .RET OK .REM The cursor position remains unchanged. Simply write blanks --- or do nothing for hard_copy terminals! If nchar<0, clear chars at the left of the cursor. ----------*/ int nchar; /* IN: Number of chars to clear */ { register int n; unsigned char old_attr; ENTER_TV("tv_cc"); TRACE_ED_I("Clearing chars: ", nchar); status = OK; if (nchar == 0) FINISH; if (terms->flags & TERM_hard) FINISH; tv_where(old_pos); old_attr = terms->attr; tv_attr(terms->attr_init); n = 0; /* Number of blanks to issue */ if (nchar < 0) { if (oldc + nchar < 0) /* Optimize */ status = clear_h(_LEFT_); else tv_goto(oldl, oldc + nchar +1), n = -nchar; } else { if (oldc + n >= dimc) /* Optimize */ status = clear_h(_RIGHT_); else n = nchar; } /* Can't clear with optimized TermCapabilities; * issue blanks. */ if (n) { oscfill(BUFS,n,' '); status = tv_line(BUFS, n); } tv_goto(oldl,oldc); tv_attr(old_attr); EXIT_TV(status); } /*========================================================================== * tv_cl *==========================================================================*/ int tv_cl() /*+++++++++++++ .DES Clear the complete line; the cursor is moved to the left margin. .RET OK .REM --------------*/ { unsigned char old_attr; ENTER_TV("tv_cl"); #if (TW_LEVEL > 0) status = OK; /* For hard-copy terminals, issue a new line */ if (terms->flags & TERM_hard) { tv_nl(); curl--; /* ... but line unchanged */ FINISH; } #endif /* Simply go to line beginning, and clear it */ old_attr = terms->attr; tv_attr(terms->attr_init); tv_out("\r", 1); curc = 0; status = clear_h(_RIGHT_); tv_goto(curl,0); tv_attr(old_attr); EXIT_TV(status); } /*========================================================================== * tv_clear *==========================================================================*/ int tv_clear(direction) /*+++++++++++++++++ .DES Clear the terminal, according to the specified direction: \begin{TeX} \begin{itemize} \item \_UP\_ : from the top of the screen, to the cursor (inclusive). The cursor does not move. \item \_DOWN\_ : from the cursor (inclusive) to the end of the screen. The cursor does not move. \item \_LEFT\_ : from the left margin of the current line to the cursor (inclusive) . The cursor does not move. \item \_RIGHT\_ : from the cursor (inclusive) to the end of the line. The cursor does not move. \item \_WHOLE\_ : the complete screen (the cursor goes to home, \ie [0,0] position. \end{itemize} \end{TeX} .RET OK/NOK .REM Insert Mode turned off. For hard-copy terminals, only _WHOLE_ has some signification. -------------------*/ int direction; /* IN: Clearing direction _WHOLE_, _UP_, _DOWN_, etc */ { register char *p; unsigned char old_attr; ENTER_TV("tv_clear"); status = OK; terms->flags &= (~TERM_IMODE); tv_where(old_pos); /* Save present position */ curc = oldc; /* For wrap (cursor passed right margin) */ old_attr = terms->attr; tv_attr(terms->attr_init); if ( (direction < 0) || (direction > 3) ) { /* Whole screen is the default */ /* Reset the scrolling region to whole screen */ tv_sr0(); /* Look if "cl" cap exists (already stored in TERM) otherwise, simply put a new line */ p = terms->tt_clear; if (p) status = SEND(p); else status = tv_nl(); /* No cap: Simply go to newline ... */ oldc = 0; oldl = 0; /* New cursor position */ FIN_CURSOR; } if (terms->flags & TERM_hard) FINISH; /* Change the direction for optimisation */ switch(direction) { case _UP_ : if (curl != 0) break; case _LEFT_ : /* Cont. _UP_ */ status = clear_h(_LEFT_); FIN_CURSOR; case _DOWN_ : if (curl != diml-1) break; case _RIGHT_: /* Cont. _DOWN_ */ status = clear_h(_RIGHT_); FIN_CURSOR; } /* Here only in case of _UP_/_DOWN_ clearing */ /* Test if a scrolling region exists --- Use tv_sr0 */ if ( (terms->scregion[0] != 0) || (terms->scregion[1] < diml-1) ) { tv_sr0(); tv_goto(oldl, oldc); } /* Use TermCapabilities when possible */ p = SearchCap(&clear_cap[direction*2]); if (p) { status = SEND(p); FIN_CURSOR;} /* Simulate Clearing with blanks */ switch(direction) { case _UP_: /* Clear from top left corner */ tv_home(); /* ... Cursor position is updated */ while (curl < oldl) { clear_h(_RIGHT_); tv_nl(); } /* We are on original line... */ tv_goto(oldl, oldc); /* ... and continue with _LEFT_ */ status = clear_h(_LEFT_); break; case _DOWN_: /* `cd' capability doesn't exist */ status = clear_h(_RIGHT_); /* clear current line...*/ while (curl < diml-1) tv_nl(), clear_h(_RIGHT_); } RESET_CURSOR: tv_goto(oldl,oldc); tv_attr(old_attr); EXIT_TV(status); }