⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 termout.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * Copyright (c) 1988, 1993 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)termout.c	8.1 (Berkeley) 6/6/93";#endif /* not lint */#if defined(unix)#include <signal.h>#include <sgtty.h>#endif#include <stdio.h>#include <curses.h>#if	defined(ultrix)/* Some version of this OS has a bad definition for nonl() */#undef	nl#undef	nonl#define nl()	 (_tty.sg_flags |= CRMOD,_pfast = _rawmode,stty(_tty_ch, &_tty))#define nonl()	 (_tty.sg_flags &= ~CRMOD, _pfast = TRUE, stty(_tty_ch, &_tty))#endif	/* defined(ultrix) */#include "../general/general.h"#include "terminal.h"#include "../api/disp_asc.h"#include "../ctlr/hostctlr.h"#include "../ctlr/externs.h"#include "../ctlr/declare.h"#include "../ctlr/oia.h"#include "../ctlr/screen.h"#include "../ctlr/scrnctlr.h"#include "../general/globals.h"#include "telextrn.h"#define CorrectTerminalCursor() ((TransparentClock == OutputClock)? \		CursorAddress:UnLocked? CursorAddress: HighestScreen())static int terminalCursorAddress;	/* where the cursor is on term */static int screenInitd; 		/* the screen has been initialized */static int screenStopped;		/* the screen has been stopped */static int max_changes_before_poll;	/* how many characters before looking */					/* at terminal and net again */static int needToRing;			/* need to ring terinal bell */static char *bellSequence = "\07";	/* bell sequence (may be replaced by					 * VB during initialization)					 */static WINDOW *bellwin = 0;		/* The window the bell message is in */int	bellwinup = 0;			/* Are we up with it or not */#if	defined(unix)static char *myKS, *myKE;#endif	/* defined(unix) */static int inHighlightMode = 0;ScreenImage Terminal[MAXSCREENSIZE];/* Variables for transparent mode */#if	defined(unix)static int tcflag = -1;			/* transparent mode command flag */static int savefd[2];			/* for storing fds during transcom */extern int	tin, tout;		/* file descriptors */#endif	/* defined(unix) *//* * init_screen() * * Initialize variables used by screen. */voidinit_screen(){    bellwinup = 0;    inHighlightMode = 0;    ClearArray(Terminal);}/* OurExitString - designed to keep us from going through infinite recursion */static voidOurExitString(string, value)char	*string;int	value;{    static int recursion = 0;    if (!recursion) {	recursion = 1;	ExitString(string, value);    }}/* DoARefresh */static voidDoARefresh(){    if (ERR == refresh()) {	OurExitString("ERR from refresh\n", 1);    }}static voidGoAway(from, where)char *from;		/* routine that gave error */int	where;		/* cursor address */{	char foo[100];	sprintf(foo, "ERR from %s at %d (%d, %d)\n",		from, where, ScreenLine(where), ScreenLineOffset(where));	OurExitString(foo, 1);	/* NOTREACHED */}/* What is the screen address of the attribute byte for the terminal */static intWhereTermAttrByte(p)register int	p;{    register int i;    i = p;    do {	if (TermIsStartField(i)) {	    return(i);	}	i = ScreenDec(i);    } while (i != p);    return(LowestScreen());	/* unformatted screen... */}/* *	There are two algorithms for updating the screen. *  The first, SlowScreen() optimizes the line between the *  computer and the screen (say a 9600 baud line).  To do *  this, we break out of the loop every so often to look *  at any pending input from the network (so that successive *  screens will only partially print until the final screen, *  the one the user possibly wants to see, is displayed *  in its entirety). * *	The second algorithm tries to optimize CPU time (by *  being simpler) at the cost of the bandwidth to the *  screen. * *	Of course, curses(3X) gets in here also. */#if	defined(NOT43)static int#else	/* defined(NOT43) */static void#endif	/* defined(NOT43) */SlowScreen(){    register int is, shouldbe, isattr, shouldattr;    register int pointer;    register int fieldattr, termattr;    register int columnsleft;#define	NORMAL		0		#define	HIGHLIGHT	1		/* Mask bits */#define	NONDISPLAY	4		/* Mask bits */#define	UNDETERMINED	8		/* Mask bits */#define	DoAttributes(x) \	    switch (x&ATTR_DSPD_MASK) { \	    case ATTR_DSPD_NONDISPLAY: \		x = NONDISPLAY; \		break; \	    case ATTR_DSPD_HIGH: \		x = HIGHLIGHT; \		break; \	    default: \		x = 0; \		break; \	    }#   define  SetHighlightMode(x) \	    { \		if ((x)&HIGHLIGHT) { \		    if (!inHighlightMode) { \			inHighlightMode = HIGHLIGHT; \			standout(); \		    } \		} else { \		    if (inHighlightMode) { \			inHighlightMode = 0; \			standend(); \		    } \		} \	    }#   define  DoCharacterAt(c,p) { \		if (p != HighestScreen()) { \		    c = disp_asc[c&0xff]; \		    if (terminalCursorAddress != p) { \			if (ERR == mvaddch(ScreenLine(p), \						ScreenLineOffset(p), c)) {\			    GoAway("mvaddch", p); \			} \		    } else { \			if (ERR == addch(c)) {\			    GoAway("addch", p); \			} \		    } \		    terminalCursorAddress = ScreenInc(p); \		} \	    }    /* run through screen, printing out non-null lines */    /* There are two separate reasons for wanting to terminate this     * loop early.  One is to respond to new input (either from     * the terminal or from the network [host]).  For this reason,     * we expect to see 'HaveInput' come true when new input comes in.     *     * The second reason is a bit more difficult (for me) to understand.     * Basically, we don't want to get too far ahead of the characters that     * appear on the screen.  Ideally, we would type out a few characters,     * wait until they appeared on the screen, then type out a few more.     * The reason for this is that the user, on seeing some characters     * appear on the screen may then start to type something.  We would     * like to look at what the user types at about the same 'time'     * (measured by characters being sent to the terminal) that the     * user types them.  For this reason, what we would like to do     * is update a bit, then call curses to do a refresh, flush the     * output to the terminal, then wait until the terminal data     * has been sent.     *     * Note that curses is useful for, among other things, deciding whether     * or not to send :ce: (clear to end of line), so we should call curses     * at end of lines (beginning of next lines).     *     * The problems here are the following:  If we do lots of write(2)s,     * we will be doing lots of context switches, thus lots of overhead     * (which we have already).  Second, if we do a select to wait for     * the output to drain, we have to contend with the fact that NOW     * we are scheduled to run, but who knows what the scheduler will     * decide when the output has caught up.     */    if (Highest >= HighestScreen()) {	/* Could be > if screen shrunk... */	Highest = ScreenDec(Highest);	/* else, while loop will never end */    }    if (Lowest < LowestScreen()) {	Lowest = LowestScreen();	/* could be -1 in some cases with					 * unformatted screens.					 */    }    if (Highest >= (pointer = Lowest)) {		/* if there is anything to do, do it.  We won't terminate		 * the loop until we've gone at least to Highest.		 */	while ((pointer <= Highest) && !HaveInput) {		/* point at the next place of disagreement */	    pointer += (bunequal(Host+pointer, Terminal+pointer,			(Highest-pointer+1)*sizeof Host[0])/sizeof Host[0]);		/*		 * How many characters to change until the end of the		 * current line		 */	    columnsleft = NumberColumns - ScreenLineOffset(pointer);		/*		 * Make sure we are where we think we are.		 */	    move(ScreenLine(pointer), ScreenLineOffset(pointer));		/* what is the field attribute of the current position */	    if (FormattedScreen()) {		fieldattr = FieldAttributes(pointer);		DoAttributes(fieldattr);	    } else {		fieldattr = NORMAL;	    }	    if (TerminalFormattedScreen()) {		termattr = TermAttributes(pointer);		DoAttributes(termattr);	    } else {		termattr = NORMAL;	    }	    SetHighlightMode(fieldattr);	    /*	     * The following will terminate at least when we get back	     * to the original 'pointer' location (since we force	     * things to be equal).	     */	    for (;;) {		if (IsStartField(pointer)) {		    shouldbe = DISP_BLANK;		    shouldattr = 0;		    fieldattr = GetHost(pointer);		    DoAttributes(fieldattr);		} else {		    if (fieldattr&NONDISPLAY) {			shouldbe = DISP_BLANK;		    } else {			shouldbe = GetHost(pointer);		    }		    shouldattr = fieldattr;		}		if (TermIsStartField(pointer)) {		    is = DISP_BLANK;		    isattr = 0;		    termattr = UNDETERMINED; /* Need to find out AFTER update */		} else {		    if (termattr&NONDISPLAY) {			is = DISP_BLANK;		    } else {			is = GetTerminal(pointer);		    }		    isattr = termattr;		}		if ((shouldbe == is) && (shouldattr == isattr)			&& (GetHost(pointer) == GetTerminal(pointer))			&& (GetHost(ScreenInc(pointer))					== GetTerminal(ScreenInc(pointer)))) {		    break;		}		if (shouldattr^inHighlightMode) {		    SetHighlightMode(shouldattr);		}		DoCharacterAt(shouldbe, pointer);		if (IsStartField(pointer)) {		    TermNewField(pointer, FieldAttributes(pointer));		    termattr = GetTerminal(pointer);		    DoAttributes(termattr);		} else {		    SetTerminal(pointer, GetHost(pointer));		    /*		     * If this USED to be a start field location,		     * recompute the terminal attributes.		     */		    if (termattr == UNDETERMINED) {			termattr = WhereTermAttrByte(pointer);			if ((termattr != 0) || TermIsStartField(0)) {			    termattr = GetTerminal(termattr);			    DoAttributes(termattr);			} else {	/* Unformatted screen */			    termattr = NORMAL;			}		    }		}		pointer = ScreenInc(pointer);		if (!(--columnsleft)) {		    DoARefresh();		    EmptyTerminal();		    if (HaveInput) {	/* if input came in, take it */			int c, j;			/*			 * We need to start a new terminal field			 * at this location iff the terminal attributes			 * of this location are not what we have had			 * them as (ie: we've overwritten the terminal			 * start field, a the previous field had different			 * display characteristics).			 */			isattr = TermAttributes(pointer);			DoAttributes(isattr);			if ((!TermIsStartField(pointer)) &&					(isattr != termattr)) {			    /*			     * Since we are going to leave a new field			     * at this terminal position, we			     * need to make sure that we get an actual			     * non-highlighted blank on the screen.			     */			    if ((is != DISP_BLANK) || (termattr&HIGHLIGHT)) {				SetHighlightMode(0);	/* Turn off highlight */				c = ScreenInc(pointer);				j = DISP_BLANK;				DoCharacterAt(j, c);			    }			    if (termattr&HIGHLIGHT) {				termattr = ATTR_DSPD_HIGH;			    } else if (termattr&NONDISPLAY) {				termattr = ATTR_DSPD_NONDISPLAY;			    } else {				termattr = 0;			    }			    TermNewField(pointer, termattr);			}			break;		    }		    move(ScreenLine(pointer), 0);		    columnsleft = NumberColumns;		}	    }	/* end of for (;;) */	} /* end of while (...) */    }    DoARefresh();    Lowest = pointer;    if (Lowest > Highest) {		/* if we finished input... */	Lowest = HighestScreen()+1;	Highest = LowestScreen()-1;	terminalCursorAddress = CorrectTerminalCursor();	if (ERR == move(ScreenLine(terminalCursorAddress),			ScreenLineOffset(terminalCursorAddress))) {	    GoAway("move", terminalCursorAddress);	}	DoARefresh();	if (needToRing) {	    StringToTerminal(bellSequence);	    needToRing = 0;	}    }    EmptyTerminal();			/* move data along */    return;}#if	defined(NOT43)static int#else	/* defined(NOT43) */static void#endif	/* defined(NOT43) */FastScreen(){#if	defined(MSDOS)#define	SaveCorner	0#else	/* defined(MSDOS) */#define	SaveCorner	1#endif	/* defined(MSDOS) */#define	DoAttribute(a) 	    if (IsHighlightedAttr(a)) { \				standout(); \

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -