📄 display.c
字号:
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->rows)
i = dp->rows-1;
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(
struct display *dp,
int row,
int col
){
dclreol(dp,row,col); /* Clear current line */
for(row = row + 1;row < dp->rows;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(struct display *dp)
{
int i = 2*(dp->cols - dp->col - 1);
uint8 *cp = vbufloc(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(struct display *dp)
{
uint8 *cp = vbufloc(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(struct display *dp)
{
uint8 *cp1,*cp2;
int row;
struct dirty *dirtp;
for(row=dp->row,dirtp = &dp->dirty[row];row < dp->rows-1;row++,dirtp++){
cp1 = vbufloc(dp,row,0);
cp2 = vbufloc(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->rows-1,0);
}
/* Insert blank line where cursor is. Push existing lines down one */
static void
dinsline(struct display *dp)
{
uint8 *cp1,*cp2;
int row;
struct dirty *dirtp;
/* Copy lines down */
for(row = dp->rows-1,dirtp = &dp->dirty[row];row > dp->row;row--){
cp1 = vbufloc(dp,row-1,0);
cp2 = vbufloc(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(
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(
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 = vbufloc(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->rows){
dp->row--;
/* Scroll screen up */
dp->virttop = (dp->virttop + 1) % dp->size;
if(dp->virttop > dp->maxtop)
dp->maxtop = dp->virttop;
if(!dp->flags.scrollbk)
dp->realtop = (dp->realtop + 1) % dp->size;
if(!dp->flags.no_scroll){
for(row=0,dirtp=dp->dirty;row <dp->rows;row++,dirtp++){
dirtp->lcol = 0;
dirtp->rcol = dp->cols-1;
}
}
dclreol(dp,dp->row,0);
}
}
/* Clear from specified location to end of line. Cursor is not moved */
static void
dclreol(
struct display *dp,
int row,
int col
){
uint8 *cp = vbufloc(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(struct display *dp)
{
dclreod(dp,0,0);
dp->row = dp->col = 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 *
rbufloc(
struct display *dp,
int row,
int col
){
row = (row + dp->realtop) % dp->size;
return dp->buf + 2*(col + dp->cols*row);
}
static uint8 *
vbufloc(
struct display *dp,
int row,
int col
){
row = (row + dp->virttop) % dp->size;
return dp->buf + 2*(col + dp->cols*row);
}
/* Immediately display short debug string on lower right corner of display */
void
debug(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,ROWS,COLS,ROWS,msg);
}
static int
sadjust(struct display *dp,int lines)
{
int curscroll,newscroll;
curscroll = (dp->size + dp->virttop - dp->realtop) % dp->size;
newscroll = curscroll + lines;
if(newscroll < 0)
newscroll = 0;
else if(newscroll > dp->maxtop)
newscroll = dp->maxtop;
else if(newscroll > dp->size - dp->rows)
newscroll = dp->size - dp->rows;
if(newscroll != curscroll){
dp->realtop -= newscroll - curscroll;
while(dp->realtop < 0)
dp->realtop += dp->size;
while(dp->realtop >= dp->size)
dp->realtop -= dp->size;
dp->flags.dirty_screen = 1;
alert(Display,1);
}
return newscroll;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -