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

📄 termout.c

📁 早期freebsd实现
💻 C
字号:
/*- * 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 */#include <stdio.h>#include <dos.h>#include "../general/general.h"#include "../telnet.ext"#include "../api/disp_asc.h"#include "../ascii/map3270.ext"#include "../ctlr/hostctlr.h"#include "../ctlr/externs.h"#include "../ctlr/declare.h"#include "../ctlr/oia.h"#include "../ctlr/screen.h"#include "../general/globals.h"#include "video.h"extern void EmptyTerminal();#define CorrectTerminalCursor() ((TransparentClock == OutputClock)? \		terminalCursorAddress: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 needToRing;			/* need to ring terinal bell */typedef struct {    char	data,		/* The data for this position */	attr;		/* The attributes for this position */} ScreenBuffer;ScreenBuffer Screen[MAXNUMBERLINES*MAXNUMBERCOLUMNS];ScreenBuffer saveScreen[sizeof Screen/sizeof Screen[0]];/* OurExitString - designed to keep us from going through infinite recursion */static voidOurExitString(file, string, value)FILE	*file;char	*string;int	value;{    static int recursion = 0;    if (!recursion) {	recursion = 1;	ExitString(file, string, value);    }}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(stderr, foo, 1);	/* NOTREACHED */}/* * Routines to deal with the screen.  These routines are lifted * from mskermit. */#define	CRT_STATUS	0x3da		/* Color card */#define	DISPLAY_ENABLE	0x08		/* Enable */#define	scrseg()	((crt_mode == 7)? 0xb000 : 0xb800)#define	scrwait()	if (crt_mode != 7) { \			    while ((inp(CRT_STATUS)&DISPLAY_ENABLE) == 0) { \				; \			    } \			}static int    		crt_mode,		crt_cols,		crt_lins,		curpage;/* * Set the cursor position to where it belongs. */static voidsetcursor(row, column, page)int    row,    column,    page;{    union REGS inregs, outregs;    inregs.h.dh = row;    inregs.h.dl = column;    inregs.h.bh = page;    inregs.h.ah = SetCursorPosition;    int86(BIOS_VIDEO, &inregs, &outregs);}/* * Read the state of the video system.  Put the cursor somewhere * reasonable. */static voidscrini(){    union REGS inregs, outregs;    inregs.h.ah = CurrentVideoState;    int86(BIOS_VIDEO, &inregs, &outregs);    crt_mode = outregs.h.al;    crt_cols = outregs.h.ah;    crt_lins = 25;    curpage = outregs.h.bh;    inregs.h.ah = ReadCursorPosition;    inregs.h.bh = curpage;    int86(BIOS_VIDEO, &inregs, &outregs);    if (outregs.h.dh > crt_lins) {	outregs.h.dh = crt_lins;    }    if (outregs.h.dl > crt_cols) {	outregs.h.dl = crt_cols;    }    inregs.h.dh = outregs.h.dh;    inregs.h.dl = outregs.h.dl;    inregs.h.bh = curpage;    inregs.h.ah = SetCursorPosition;    int86(BIOS_VIDEO, &inregs, &outregs);}static voidscrwrite(source, length, offset)ScreenBuffer *source;int	length,	offset;{    struct SREGS segregs;    segread(&segregs);		/* read the current segment register */    scrwait();    movedata(segregs.ds, source, scrseg(), sizeof *source*offset,						sizeof *source*length);}static voidscrsave(buffer)ScreenBuffer *buffer;{    struct SREGS segregs;    segread(&segregs);		/* read the current segment register */    scrwait();    movedata(scrseg(), 0, segregs.ds, buffer, crt_cols*crt_lins*2);}static voidscrrest(buffer)ScreenBuffer *buffer;{    scrwrite(buffer, crt_cols*crt_lins, 0);}static voidTryToSend(){#define	STANDOUT	0x0a	/* Highlighted mode */#define	NORMAL		0x02	/* Normal mode */#define	NONDISPLAY	0x00	/* Don't display */#define	DoAttribute(a) 	    \			    if (screenIsFormatted) { \				if (IsNonDisplayAttr(a)) { \				    a = NONDISPLAY; 	/* don't display */ \				} else if (IsHighlightedAttr(a)) { \				    a = STANDOUT; \				} else { \				    a = NORMAL; \				} \			    } else  { \				a = NORMAL;	/* do display on unformatted */\			    }    ScreenImage *p, *upper;    ScreenBuffer *sp;    int fieldattr;		/* spends most of its time == 0 or 1 */    int screenIsFormatted = FormattedScreen();/* OK.  We want to do this a quickly as possible.  So, we assume we * only need to go from Lowest to Highest.  However, if we find a * field in the middle, we do the whole screen. * * In particular, we separate out the two cases from the beginning. */    if ((Highest != HighestScreen()) || (Lowest != LowestScreen())) {	sp = &Screen[Lowest];	p = &Host[Lowest];	upper = &Host[Highest];	fieldattr = FieldAttributes(Lowest);	DoAttribute(fieldattr);	/* Set standout, non-display status */	while (p <= upper) {	    if (IsStartFieldPointer(p)) {	/* New field? */		Highest = HighestScreen();		Lowest = LowestScreen();		TryToSend();		/* Recurse */		return;	    } else if (fieldattr) {	/* Should we display? */				/* Display translated data */		sp->data = disp_asc[GetHostPointer(p)];	    } else {		sp->data = ' ';	    }	    sp->attr = fieldattr;	    p++;	    sp++;	}    } else {		/* Going from Lowest to Highest */	ScreenImage *End = &Host[ScreenSize]-1;	sp = Screen;	p = Host;	fieldattr = FieldAttributes(LowestScreen());	DoAttribute(fieldattr);	/* Set standout, non-display status */	while (p <= End) {	    if (IsStartFieldPointer(p)) {	/* New field? */		fieldattr = FieldAttributesPointer(p);	/* Get attributes */		DoAttribute(fieldattr);	/* Set standout, non-display */	    }	    if (fieldattr) {	/* Should we display? */			    /* Display translated data */		sp->data = disp_asc[GetHostPointer(p)];	    } else {		sp->data = ' ';	    }	    sp->attr = fieldattr;	    p++;	    sp++;	}    }    terminalCursorAddress = CorrectTerminalCursor();    /*     * We might be here just to update the cursor address.     */    if (Highest >= Lowest) {	scrwrite(Screen+Lowest, (1+Highest-Lowest), Lowest);    }    setcursor(ScreenLine(terminalCursorAddress),		    ScreenLineOffset(terminalCursorAddress), 0);    Lowest = HighestScreen()+1;    Highest = LowestScreen()-1;    if (needToRing) {	DataToTerminal("\7", 1);	needToRing = 0;    }    return;}/* InitTerminal - called to initialize the screen, etc. */voidInitTerminal(){    InitMapping();		/* Go do mapping file (MAP3270) first */    if (!screenInitd) { 	/* not initialized */	MaxNumberLines = 24;	/* XXX */	MaxNumberColumns = 80;	/* XXX */	scrini();	scrsave(saveScreen);	/* Save the screen buffer away */	ClearArray(Screen);	terminalCursorAddress = SetBufferAddress(0,0);	screenInitd = 1;	screenStopped = 0;		/* Not stopped */    }}/* StopScreen - called when we are going away... */voidStopScreen(doNewLine)int doNewLine;{    if (screenInitd && !screenStopped) {	scrrest(saveScreen);	setcursor(NumberLines-1, 1, 0);	if (doNewLine) {	    StringToTerminal("\r\n");	}	EmptyTerminal();	screenStopped = 1;    }}/* RefreshScreen - called to cause the screen to be refreshed */voidRefreshScreen(){    Highest = HighestScreen();    Lowest = LowestScreen();    TryToSend();}/* ConnectScreen - called to reconnect to the screen */voidConnectScreen(){    if (screenInitd) {	RefreshScreen();	screenStopped = 0;    }}/* LocalClearScreen() - clear the whole ball of wax, cheaply */voidLocalClearScreen(){    Clear3270();    Lowest = LowestScreen(); /* everything in sync... */    Highest = HighestScreen();    TryToSend();}/* * Implement the bell/error message function. */int	bellwinup = 0;		/* If != 0, length of bell message */static int	bell_len = 0;		/* Length of error message */voidBellOff(){    ScreenBuffer a[100];    int i;    if (bellwinup) {	unsigned char blank = ' ';	for (i = 0; i < bell_len; i++) {	    a[i].attr = NORMAL;	    a[i].data = ' ';	}    }    scrwrite(a, bell_len, 24*80);		/* XXX */}voidRingBell(s)char *s;{    needToRing = 1;    if (s) {	int i;	ScreenBuffer bellstring[100];	bell_len = strlen(s);	bellwinup = 1;	if (bell_len > sizeof bellstring-1) {	    OurExitString(stderr, "Bell string too long.", 1);	}	for (i = 0; i < bell_len; i++) {	    bellstring[i].attr = STANDOUT;	    bellstring[i].data = s[i];	}	scrwrite(bellstring, bell_len, 24*80);		/* XXX */    }}/* * Update the OIA area. */voidScreenOIA(oia)OIA *oia;{}/* returns a 1 if no more output available (so, go ahead and block),    or a 0 if there is more output available (so, just poll the other    sources/destinations, don't block). */intDoTerminalOutput(){	/* called just before a select to conserve IO to terminal */    if (!(screenInitd||screenStopped)) {	return 1;		/* No output if not initialized */    }    if ((Lowest <= Highest) || needToRing ||			(terminalCursorAddress != CorrectTerminalCursor())) {	TryToSend();    }    if (Lowest > Highest) {	return 1;		/* no more output now */    } else {	return 0;		/* more output for future */    }}/* * The following are defined to handle transparent data. */voidTransStop(){    RefreshScreen();}voidTransOut(buffer, count, kind, control)unsigned char	*buffer;int		count;int		kind;		/* 0 or 5 */int		control;	/* To see if we are done */{    char *ptr;    while (DoTerminalOutput() == 0) {	;    }    for (ptr = buffer; ptr < buffer+count; ptr++) {	*ptr &= 0x7f;		/* Turn off parity bit */    }    (void) DataToTerminal(buffer, count);    if (control && (kind == 0)) {		/* Send in AID byte */	SendToIBM();    } else {	TransInput(1, kind);			/* Go get some data */    }}/* * init_screen() * * Initialize variables used by screen. */voidinit_screen(){    bellwinup = 0;}

⌨️ 快捷键说明

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