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

📄 screen.c

📁 早期freebsd实现
💻 C
字号:
/* * Copyright (c) 1988 Mark Nudleman * 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[] = "@(#)screen.c	8.2 (Berkeley) 4/20/94";#endif /* not lint *//* * Routines which deal with the characteristics of the terminal. * Uses termcap to be as terminal-independent as possible. * * {{ Someday this should be rewritten to use curses. }} */#include <stdio.h>#include <less.h>#define TERMIOS 1#if TERMIO#include <termio.h>#else#if TERMIOS#include <termios.h>#define TAB3 0#include <sys/ioctl.h>#else#include <sgtty.h>#endif#endif#ifdef TIOCGWINSZ#include <sys/ioctl.h>#else/* * For the Unix PC (ATT 7300 & 3B1): * Since WIOCGETD is defined in sys/window.h, we can't use that to decide * whether to include sys/window.h.  Use SIGPHONE from sys/signal.h instead. */#include <sys/signal.h>#ifdef SIGPHONE#include <sys/window.h>#endif#endif/* * Strings passed to tputs() to do various terminal functions. */static char	*sc_pad,		/* Pad string */	*sc_home,		/* Cursor home */	*sc_addline,		/* Add line, scroll down following lines */	*sc_lower_left,		/* Cursor to last line, first column */	*sc_move,		/* General cursor positioning */	*sc_clear,		/* Clear screen */	*sc_eol_clear,		/* Clear to end of line */	*sc_s_in,		/* Enter standout (highlighted) mode */	*sc_s_out,		/* Exit standout mode */	*sc_u_in,		/* Enter underline mode */	*sc_u_out,		/* Exit underline mode */	*sc_b_in,		/* Enter bold mode */	*sc_b_out,		/* Exit bold mode */	*sc_backspace,		/* Backspace cursor */	*sc_init,		/* Startup terminal initialization */	*sc_deinit;		/* Exit terminal de-intialization */int auto_wrap;			/* Terminal does \r\n when write past margin */int ignaw;			/* Terminal ignores \n immediately after wrap */				/* The user's erase and line-kill chars */int retain_below;		/* Terminal retains text below the screen */int erase_char, kill_char, werase_char;int sc_width, sc_height = -1;	/* Height & width of screen */int sc_window = -1;		/* window size for forward and backward */int bo_width, be_width;		/* Printing width of boldface sequences */int ul_width, ue_width;		/* Printing width of underline sequences */int so_width, se_width;		/* Printing width of standout sequences *//* * These two variables are sometimes defined in, * and needed by, the termcap library. * It may be necessary on some systems to declare them extern here. *//*extern*/ short ospeed;	/* Terminal output baud rate *//*extern*/ char PC;		/* Pad character */extern int back_scroll;char *tgetstr();char *tgoto();/* * Change terminal to "raw mode", or restore to "normal" mode. * "Raw mode" means  *	1. An outstanding read will complete on receipt of a single keystroke. *	2. Input is not echoed.   *	3. On output, \n is mapped to \r\n. *	4. \t is NOT expanded into spaces. *	5. Signal-causing characters such as ctrl-C (interrupt), *	   etc. are NOT disabled. * It doesn't matter whether an input \n is mapped to \r, or vice versa. */raw_mode(on)	int on;{#if TERMIO || TERMIOS#if TERMIO	struct termio s;	static struct termio save_term;#else	struct termios s;	static struct termios save_term;#endif	if (on)	{		/*		 * Get terminal modes.		 */#if TERMIO		(void)ioctl(2, TCGETA, &s);#else		tcgetattr(2, &s);#endif		/*		 * Save modes and set certain variables dependent on modes.		 */		save_term = s;#if TERMIO		ospeed = s.c_cflag & CBAUD;#else		ospeed = cfgetospeed(&s);#endif		erase_char = s.c_cc[VERASE];		kill_char = s.c_cc[VKILL];		werase_char = s.c_cc[VWERASE];		/*		 * Set the modes to the way we want them.		 */		s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);		s.c_oflag |=  (OPOST|ONLCR|TAB3);#if TERMIO		s.c_oflag &= ~(OCRNL|ONOCR|ONLRET);#endif		s.c_cc[VMIN] = 1;		s.c_cc[VTIME] = 0;	} else	{		/*		 * Restore saved modes.		 */		s = save_term;	}#if TERMIO	(void)ioctl(2, TCSETAW, &s);#else	tcsetattr(2, TCSADRAIN, &s);#endif#else	struct sgttyb s;	struct ltchars l;	static struct sgttyb save_term;	if (on)	{		/*		 * Get terminal modes.		 */		(void)ioctl(2, TIOCGETP, &s);		(void)ioctl(2, TIOCGLTC, &l);		/*		 * Save modes and set certain variables dependent on modes.		 */		save_term = s;		ospeed = s.sg_ospeed;		erase_char = s.sg_erase;		kill_char = s.sg_kill;		werase_char = l.t_werasc;		/*		 * Set the modes to the way we want them.		 */		s.sg_flags |= CBREAK;		s.sg_flags &= ~(ECHO|XTABS);	} else	{		/*		 * Restore saved modes.		 */		s = save_term;	}	(void)ioctl(2, TIOCSETN, &s);#endif}/* * Get terminal capabilities via termcap. */get_term(){	char termbuf[2048];	char *sp;	char *term;	int hard;#ifdef TIOCGWINSZ	struct winsize w;#else#ifdef WIOCGETD	struct uwdata w;#endif#endif	static char sbuf[1024];	char *getenv(), *strcpy();	/*	 * Find out what kind of terminal this is.	 */ 	if ((term = getenv("TERM")) == NULL) 		term = "unknown"; 	if (tgetent(termbuf, term) <= 0) 		(void)strcpy(termbuf, "dumb:co#80:hc:");	/*	 * Get size of the screen.	 */#ifdef TIOCGWINSZ	if (ioctl(2, TIOCGWINSZ, &w) == 0 && w.ws_row > 0)		sc_height = w.ws_row;#else#ifdef WIOCGETD	if (ioctl(2, WIOCGETD, &w) == 0 && w.uw_height > 0)		sc_height = w.uw_height/w.uw_vs;#endif#endif	else		sc_height = tgetnum("li");	hard = (sc_height < 0 || tgetflag("hc"));	if (hard) {		/* Oh no, this is a hardcopy terminal. */		sc_height = 24;	}#ifdef TIOCGWINSZ 	if (ioctl(2, TIOCGWINSZ, &w) == 0 && w.ws_col > 0)		sc_width = w.ws_col;	else#ifdef WIOCGETD	if (ioctl(2, WIOCGETD, &w) == 0 && w.uw_width > 0)		sc_width = w.uw_width/w.uw_hs;	else#endif#endif 		sc_width = tgetnum("co"); 	if (sc_width < 0)  		sc_width = 80;	auto_wrap = tgetflag("am");	ignaw = tgetflag("xn");	retain_below = tgetflag("db");	/*	 * Assumes termcap variable "sg" is the printing width of	 * the standout sequence, the end standout sequence,	 * the underline sequence, the end underline sequence,	 * the boldface sequence, and the end boldface sequence.	 */	if ((so_width = tgetnum("sg")) < 0)		so_width = 0;	be_width = bo_width = ue_width = ul_width = se_width = so_width;	/*	 * Get various string-valued capabilities.	 */	sp = sbuf;	sc_pad = tgetstr("pc", &sp);	if (sc_pad != NULL)		PC = *sc_pad;	sc_init = tgetstr("ti", &sp);	if (sc_init == NULL)		sc_init = "";	sc_deinit= tgetstr("te", &sp);	if (sc_deinit == NULL)		sc_deinit = "";	sc_eol_clear = tgetstr("ce", &sp);	if (hard || sc_eol_clear == NULL || *sc_eol_clear == '\0')	{		sc_eol_clear = "";	}	sc_clear = tgetstr("cl", &sp);	if (hard || sc_clear == NULL || *sc_clear == '\0')	{		sc_clear = "\n\n";	}	sc_move = tgetstr("cm", &sp);	if (hard || sc_move == NULL || *sc_move == '\0')	{		/*		 * This is not an error here, because we don't 		 * always need sc_move.		 * We need it only if we don't have home or lower-left.		 */		sc_move = "";	}	sc_s_in = tgetstr("so", &sp);	if (hard || sc_s_in == NULL)		sc_s_in = "";	sc_s_out = tgetstr("se", &sp);	if (hard || sc_s_out == NULL)		sc_s_out = "";	sc_u_in = tgetstr("us", &sp);	if (hard || sc_u_in == NULL)		sc_u_in = sc_s_in;	sc_u_out = tgetstr("ue", &sp);	if (hard || sc_u_out == NULL)		sc_u_out = sc_s_out;	sc_b_in = tgetstr("md", &sp);	if (hard || sc_b_in == NULL)	{		sc_b_in = sc_s_in;		sc_b_out = sc_s_out;	} else	{		sc_b_out = tgetstr("me", &sp);		if (hard || sc_b_out == NULL)			sc_b_out = "";	}	sc_home = tgetstr("ho", &sp);	if (hard || sc_home == NULL || *sc_home == '\0')	{		if (*sc_move == '\0')		{			/*			 * This last resort for sc_home is supposed to			 * be an up-arrow suggesting moving to the 			 * top of the "virtual screen". (The one in			 * your imagination as you try to use this on			 * a hard copy terminal.)			 */			sc_home = "|\b^";		} else		{			/* 			 * No "home" string,			 * but we can use "move(0,0)".			 */			(void)strcpy(sp, tgoto(sc_move, 0, 0));			sc_home = sp;			sp += strlen(sp) + 1;		}	}	sc_lower_left = tgetstr("ll", &sp);	if (hard || sc_lower_left == NULL || *sc_lower_left == '\0')	{		if (*sc_move == '\0')		{			sc_lower_left = "\r";		} else		{			/*			 * No "lower-left" string, 			 * but we can use "move(0,last-line)".			 */			(void)strcpy(sp, tgoto(sc_move, 0, sc_height-1));			sc_lower_left = sp;			sp += strlen(sp) + 1;		}	}	/*	 * To add a line at top of screen and scroll the display down,	 * we use "al" (add line) or "sr" (scroll reverse).	 */	if ((sc_addline = tgetstr("al", &sp)) == NULL || 		 *sc_addline == '\0')		sc_addline = tgetstr("sr", &sp);	if (hard || sc_addline == NULL || *sc_addline == '\0')	{		sc_addline = "";		/* Force repaint on any backward movement */		back_scroll = 0;	}	if (tgetflag("bs"))		sc_backspace = "\b";	else	{		sc_backspace = tgetstr("bc", &sp);		if (sc_backspace == NULL || *sc_backspace == '\0')			sc_backspace = "\b";	}}/* * Below are the functions which perform all the  * terminal-specific screen manipulation. */int putchr();/* * Initialize terminal */init(){	tputs(sc_init, sc_height, putchr);}/* * Deinitialize terminal */deinit(){	tputs(sc_deinit, sc_height, putchr);}/* * Home cursor (move to upper left corner of screen). */home(){	tputs(sc_home, 1, putchr);}/* * Add a blank line (called with cursor at home). * Should scroll the display down. */add_line(){	tputs(sc_addline, sc_height, putchr);}int short_file;				/* if file less than a screen */lower_left(){	if (short_file) {		putchr('\r');		flush();	}	else		tputs(sc_lower_left, 1, putchr);}/* * Ring the terminal bell. */bell(){	putchr('\7');}/* * Clear the screen. */clear(){	tputs(sc_clear, sc_height, putchr);}/* * Clear from the cursor to the end of the cursor's line. * {{ This must not move the cursor. }} */clear_eol(){	tputs(sc_eol_clear, 1, putchr);}/* * Begin "standout" (bold, underline, or whatever). */so_enter(){	tputs(sc_s_in, 1, putchr);}/* * End "standout". */so_exit(){	tputs(sc_s_out, 1, putchr);}/* * Begin "underline" (hopefully real underlining,  * otherwise whatever the terminal provides). */ul_enter(){	tputs(sc_u_in, 1, putchr);}/* * End "underline". */ul_exit(){	tputs(sc_u_out, 1, putchr);}/* * Begin "bold" */bo_enter(){	tputs(sc_b_in, 1, putchr);}/* * End "bold". */bo_exit(){	tputs(sc_b_out, 1, putchr);}/* * Erase the character to the left of the cursor  * and move the cursor left. */backspace(){	/* 	 * Try to erase the previous character by overstriking with a space.	 */	tputs(sc_backspace, 1, putchr);	putchr(' ');	tputs(sc_backspace, 1, putchr);}/* * Output a plain backspace, without erasing the previous char. */putbs(){	tputs(sc_backspace, 1, putchr);}

⌨️ 快捷键说明

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