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

📄 display.c

📁 TCPIP源代码C语言版本
💻 C
📖 第 1 页 / 共 2 页
字号:
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':
		/* Collect decimal number */
		dp->arg[dp->argi] = 10*dp->arg[dp->argi] + (c - '0');
		return;
	case ';':	/* Next argument is beginning */
		if(dp->argi <= MAXARGS - 1)
			dp->argi++;
		dp->arg[dp->argi] = 0;
		return;
	case '@':	/* Open up space for character */
		dinsert(dp);
		break;
	case 'A':	/* Cursor up */
		if(dp->arg[0] == 0)
			dp->arg[0] = 1;	/* Default is one line */
		if(dp->arg[0] <= dp->row)
			dp->row -= dp->arg[0];
		else
			dp->row = 0;
		dp->flags.dirty_cursor = 1;
		break;
	case 'B':	/* Cursor down */
		if(dp->arg[0] == 0)
			dp->arg[0] = 1;	/* Default is one line */
		dp->row += dp->arg[0];
		if(dp->row > dp->slast)
			dp->row = dp->slast;
		dp->flags.dirty_cursor = 1; 
		break;
	case 'C':	/* Cursor right */
		if(dp->arg[0] == 0)
			dp->arg[0] = 1;	/* Default is one column */
		dp->col += dp->arg[0];
		if(dp->col >= dp->cols)
			dp->col = dp->cols - 1;
		dp->flags.dirty_cursor = 1;
		break;
	case 'D':	/* Cursor left */
		if(dp->arg[0] == 0)
			dp->arg[0] = 1;	/* Default is one column */
		if(dp->arg[0] <= dp->col)
			dp->col -= dp->arg[0];
		else
			dp->col = 0;
		dp->flags.dirty_cursor = 1;
		break;
	case 'f':
	case 'H':	/* Cursor motion - limit to scrolled region */
		i = (dp->arg[0] == 0) ? 0 : dp->arg[0] - 1;
		if(i > dp->slast)
			i = dp->slast;
		dp->row = i;

		i = (dp->arg[1] == 0) ? 0 : dp->arg[1] - 1;
		if(i >= dp->cols)
			i = dp->cols - 1;
		dp->col = i;
		dp->state = DISP_NORMAL;
		dp->flags.dirty_cursor = 1;
		break;
	case 'h':	/* Set mode */
		switch(dp->arg[0]){
		case 7:	/* Turn on wrap mode */
			dp->flags.no_line_wrap = 0;
			break;
		}
		break;
	case 'J':	/* Clear screen */
		switch(dp->arg[0]){
		case 2:
			dclrscr(dp);	/* Clear entire screen, home cursor */
			break;
		case 0:
			dclreod(dp,dp->row,dp->col);	/* Clear to end of screen (VT-100) */
			break;
		}
		break;
	case 'K':	/* Erase to end of current line */
		dclreol(dp,dp->row,dp->col);
		break;
	case 'L':	/* Add blank line */
		dinsline(dp);
		break;		
	case 'l':	/* Clear mode */
		switch(dp->arg[0]){
		case 7:	/* Turn off wrap mode */
			dp->flags.no_line_wrap = 1;
			break;
		}
		break;
	case 'M':	/* Delete line */
		ddelline(dp);
		break;
	case 'm':	/* Set screen attributes */
		for(i=0;i<=dp->argi;i++){
			dattrib(dp,dp->arg[i]);
		}
		break;
	case 'P':	/* Delete character */
		ddelchar(dp);
		break;
	case 's':	/* Save cursor position */
		dp->savcol = dp->col;
		dp->savrow = dp->row;
		break;
	case 'u':	/* Restore cursor position */
		dp->col = dp->savcol;
		dp->row = dp->savrow;
		dp->flags.dirty_cursor = 1;
		break;
	case 'g':
		switch(dp->arg[0]){
		case 0:
			dp->tabstops[dp->col] = 0;
			break;
		case 3:
			memset(dp->tabstops,0,dp->cols);
			break;
		}
		break;
	}
	dp->state = DISP_NORMAL;
}
/* Clear from specified location to end of screen, leaving cursor as is */
static void
dclreod(dp,row,col)
struct display *dp;
int row,col;
{
	dclreol(dp,row,col);	/* Clear current line */
	for(row = row + 1;row <= dp->slast;row++)
		dclreol(dp,row,0);	/* Clear all lines below */
}
/* Insert space at cursor, moving all chars on right to right one position */
static void
dinsert(dp)
struct display *dp;
{
	int i = 2*(dp->cols - dp->col - 1);
	uint8 *cp = bufloc(dp,dp->row,dp->col);
	struct dirty *dirtp = &dp->dirty[dp->row];

	if(i != 0)
		memmove(cp+2,cp,i);	/* handles overlapping blocks */
	*cp++ = ' ';
	*cp = dp->attrib;
	/* Dirty everything from the cursor to the right edge */
	if(dp->col < dirtp->lcol)
		dirtp->lcol = dp->col;
	dirtp->rcol = dp->cols-1;
}
/* Delete character at cursor, moving chars to right left one position */
static void
ddelchar(dp)
struct display *dp;
{
	uint8 *cp = bufloc(dp,dp->row,dp->col);
	int i = 2*(dp->cols-dp->col-1);
	struct dirty *dirtp = &dp->dirty[dp->row];

	/* Copy characters to right one space left */
	if(i != 0)
		memmove(cp,cp+2,i);	/* memmove handles overlapping blocks */
	/* Clear right most character on line */
	cp[i] = ' ';
	cp[i+1] = dp->attrib;
	/* Dirty everything from the cursor to the right edge */
	if(dp->col < dirtp->lcol)
		dirtp->lcol = dp->col;
	dirtp->rcol = dp->cols-1;
}
/* Delete line containing cursor, moving lines below up one line */
static void
ddelline(dp)
struct display *dp;
{
	uint8 *cp1,*cp2;
	int row;
	struct dirty *dirtp;

	for(row=dp->row,dirtp = &dp->dirty[row];row < dp->slast;row++,dirtp++){
		cp1 = bufloc(dp,row,0);
		cp2 = bufloc(dp,row+1,0);
		memcpy(cp1,cp2,dp->cols*2);
		/* Dirty entire line */
		dirtp->lcol = 0;
		dirtp->rcol = dp->cols-1;
	}
	/* Clear bottom line */
	dclreol(dp,dp->slast,0);
}		
/* Insert blank line where cursor is. Push existing lines down one */
static void
dinsline(dp)
struct display *dp;
{
	uint8 *cp1,*cp2;
	int row;
	struct dirty *dirtp;

	/* Copy lines down */
	for(row = dp->slast,dirtp = &dp->dirty[row];row > dp->row;row--){
		cp1 = bufloc(dp,row-1,0);
		cp2 = bufloc(dp,row,0);
		memcpy(cp2,cp1,2*dp->cols);
		/* Dirty entire line */
		dirtp->lcol = 0;
		dirtp->rcol = dp->cols-1;
	}
	/* Clear current line */
	dclreol(dp,dp->row,0);
}

/* Process an argument to an attribute set command */
static void
dattrib(dp,val)
struct display *dp;
int val;
{
	switch(val){
	case 0:	/* Normal white on black */
		dp->attrib = 0x7;
		break;
	case 1:	/* High intensity */
		dp->attrib |= 0x8;
		break;
	case 5:	/* Blink on */
		dp->attrib |= 0x80;
		break;
	case 7:	/* Reverse video (black on white) */
		dp->attrib = 0x70;
		break;
	default:
		if(val >= 30 && val < 38){
			/* Set foreground color */
			dp->attrib = (dp->attrib & ~0x7) | fgattr[val - 30];
		} else if(val >= 40 && val < 48){
			/* Set background color */
			dp->attrib = (dp->attrib & ~0x70) | ((bgattr[val - 40]) << 4);
		}
		break;
	}
 }
/* Display character */
static void
dchar(dp,c)
struct display *dp;
uint8 c;
{
	uint8 *cp;
	int row,rowchange;
	struct dirty *dirtp;

	rowchange = 0;
	switch(c){
	case ESC:
		dp->state = DISP_ESCAPE;
		return;
	case CTLQ:	/*****/
	case '\0':	/* Ignore nulls and bells */
	case BELL:
		break;
	case '\b':	/* Backspace */
		if(dp->col > 0){
			dp->col--;
			dp->flags.dirty_cursor = 1;
		}
		break;
	case FF:	/* Page feed */
		dclrscr(dp);
		break;
	case '\t':	/* Tab */
		while(dp->col < dp->cols-1){
			if(dp->tabstops[++dp->col])
				break;
		}
		dp->flags.dirty_cursor = 1;
		break;
	case '\n':	/* Move cursor down one row */
		dp->row++;
		rowchange = 1;
		dp->flags.dirty_cursor = 1;
		break;
	case '\r':	/* Move cursor to beginning of current row */
		dp->col = 0;
		dp->flags.dirty_cursor = 1;
		break;
	default:	/* Display character on screen */
		/* Compute location in screen buffer memory */
		cp = bufloc(dp,dp->row,dp->col);
		/* Normal display */
		if(c != *cp || cp[1] != dp->attrib){
			dirtp = &dp->dirty[dp->row];
			if(dp->col < dirtp->lcol)
				dirtp->lcol = dp->col;
			if(dp->col > dirtp->rcol)
				dirtp->rcol = dp->col;
		}
		*cp++ = c;
		*cp = dp->attrib;
		dp->flags.dirty_cursor = 1;
		/* Update cursor position, wrapping if necessary */
		if(++dp->col == dp->cols){
			if(dp->flags.no_line_wrap){
				dp->col--;
			} else {
				dp->col = 0;
				dp->row++;
				rowchange = 1;
			}
		}
	}
	/* Scroll screen if necessary */
	if(rowchange && dp->row > dp->slast){
		dp->row--;
		/* Scroll screen up */
		dp->scroll = (dp->scroll + 1) % (dp->slast + 1);
		if(!dp->flags.no_scroll){
			for(row=0,dirtp=&dp->dirty[row];row <=dp->slast;row++,dirtp++){
				dirtp->lcol = 0;
				dirtp->rcol = dp->cols-1;
			}
		}
		if(dp->sfile != NULL){
			uint8 *cp;

			/* When scrolled back, leave screen stationary */
			if(dp->flags.scrollbk && dp->sfoffs != dp->sflimit)
				dp->sfoffs++;

			/* Copy scrolled line to scrollback file */
			cp = bufloc(dp,dp->row,0);
			fseek(dp->sfile,dp->sfseek,SEEK_SET);
			fwrite(cp,2,dp->cols,dp->sfile);
			dp->sfseek += 2*dp->cols;
			if(dp->sfseek >= 2*dp->cols*dp->sflimit)
				dp->sfseek = 0;
			if(dp->sfsize < dp->sflimit)
				dp->sfsize++;
		}
		dclreol(dp,dp->row,0);
	}
}

/* Clear from specified location to end of line. Cursor is not moved */
static void
dclreol(dp,row,col)
struct display *dp;
int row,col;
{
	uint8 *cp = bufloc(dp,row,col);
	struct dirty *dirtp = &dp->dirty[row];
	int i;

	for(i=dp->cols - col;i!=0;i--){
		*cp++ = ' ';
		*cp++ = dp->attrib;
	}
	/* Dirty from current column to right edge */
	if(col < dirtp->lcol)
		dirtp->lcol = col;
	dirtp->rcol = dp->cols-1;
}
/* Move cursor to top left corner, clear screen */
static void
dclrscr(dp)
struct display *dp;
{
	dclreod(dp,0,0);
	dp->row = dp->col = 0;
	dp->scroll = 0;
	dp->flags.dirty_cursor = 1;
}
/* Return pointer into screen buffer for specified cursor location.
 * Not guaranteed to be valid past the end of the current line due to
 * scrolling
 */
static uint8 *
bufloc(dp,row,col)
struct display *dp;
int row,col;
{
#ifndef	notdef
	if(row < 0 || row >= dp->rows || col < 0 || col >= dp->cols){
		stktrace();
		cprintf("panic: bufloc(%p,%d,%d)\n",dp,row,col);
		exit(1);
	}
#endif
	if(row <= dp->slast)
		row = (row + dp->scroll) % (dp->slast + 1);
	return dp->buf + 2*(col + dp->cols*row);
}
/* Immediately display short debug string on lower right corner of display */
void
debug(s)
char *s;
{
	int i;
	static uint8 msg[2*DSIZ];

	if(msg[1] != 0x7){
		/* One time initialization to blanks with white-on-black */
		for(i=0;i<DSIZ;i++){
			msg[2*i] = ' ';
			msg[2*i+1] = 0x7;
		}
	}
	if(s == NULL)
		return;
	for(i=0;i<DSIZ && *s != '\0';i++)
		msg[2*i] = (uint8) *s++;

	for(;i<DSIZ;i++)
		msg[2*i] = ' ';

	puttext(DCOL,25,80,25,msg);
}

⌨️ 快捷键说明

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