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

📄 screen.c

📁 一个很有名的浏览器
💻 C
📖 第 1 页 / 共 2 页
字号:
}/* Time critical section. */static inline voidadd_char16(struct string *screen, struct screen_driver *driver,	   struct screen_char *ch, struct screen_state *state){	unsigned char border = (ch->attr & SCREEN_ATTR_FRAME);	unsigned char underline = (ch->attr & SCREEN_ATTR_UNDERLINE);	unsigned char bold = (ch->attr & SCREEN_ATTR_BOLD);	if (border != state->border && driver->frame_seqs) {		state->border = border;		add_term_string(screen, driver->frame_seqs[!!border]);	}	if (underline != state->underline && driver->underline) {		state->underline = underline;		add_term_string(screen, driver->underline[!!underline]);	}	if (bold != state->bold) {		state->bold = bold;		if (bold) {			add_bytes_to_string(screen, "\033[1m", 4);		} else {			/* Force repainting of the other attributes. */			state->color[0] = ch->color[0] + 1;		}	}	if (!compare_color(ch->color, state->color)) {		copy_color(state->color, ch->color);		add_bytes_to_string(screen, "\033[0", 3);		if (driver->color_mode == COLOR_MODE_16) {			unsigned char code[6] = ";30;40";			unsigned char bgcolor = TERM_COLOR_BACKGROUND(ch->color);			code[2] += TERM_COLOR_FOREGROUND(ch->color);			if (!driver->transparent || bgcolor != 0) {				code[5] += bgcolor;				add_bytes_to_string(screen, code, 6);			} else {				add_bytes_to_string(screen, code, 3);			}		} else if (ch->attr & SCREEN_ATTR_STANDOUT) {			/* Flip the fore- and background colors for highlighing			 * purposes. */			add_bytes_to_string(screen, ";7", 2);		}		if (underline && driver->underline) {			add_bytes_to_string(screen, ";4", 2);		}		/* Check if the char should be rendered bold. */		if (bold) {			add_bytes_to_string(screen, ";1", 2);		}		add_bytes_to_string(screen, "m", 1);	}	add_char_data(screen, driver, ch->data, border);}#ifdef CONFIG_256_COLORSstatic struct string color256_seqs[] = {	/* foreground: */	TERM_STRING("\033[0;38;5;%dm"),	/* background: */	TERM_STRING("\033[48;5;%dm"),};static inline voidadd_char_color(struct string *screen, struct string *seq, unsigned char color){	unsigned char color_buf[3];	unsigned char *color_pos = color_buf;	int seq_pos = 0;       	int color_len = 1;	check_string_magic(seq);	for (; seq->source[seq_pos] != '%'; seq_pos++) ;	add_bytes_to_string(screen, seq->source, seq_pos);	if (color < 10) {		color_pos += 2;	} else {		int color2;		++color_len;		if (color < 100) {			++color_pos;		} else {			++color_len;			if (color < 200) {				color_buf[0] = '1';				color -= 100;			} else {				color_buf[0] = '2';				color -= 200;			}		}		color2 = (color % 10);		color /= 10;		color_buf[1] = '0' + color;		color = color2;	}	color_buf[2] = '0' + color;	add_bytes_to_string(screen, color_pos, color_len);	seq_pos += 2; /* Skip "%d" */	add_bytes_to_string(screen, &seq->source[seq_pos], seq->length - seq_pos);}#define add_background_color(str, seq, chr) add_char_color(str, &(seq)[1], (chr)->color[1])#define add_foreground_color(str, seq, chr) add_char_color(str, &(seq)[0], (chr)->color[0])/* Time critical section. */static inline voidadd_char256(struct string *screen, struct screen_driver *driver,	    struct screen_char *ch, struct screen_state *state){	unsigned char attr_delta = (ch->attr ^ state->attr);	if (attr_delta) {		if ((attr_delta & SCREEN_ATTR_FRAME) && driver->frame_seqs) {			state->border = !!(ch->attr & SCREEN_ATTR_FRAME);			add_term_string(screen, driver->frame_seqs[state->border]);		}		if ((attr_delta & SCREEN_ATTR_UNDERLINE) && driver->underline) {			state->underline = !!(ch->attr & SCREEN_ATTR_UNDERLINE);			add_term_string(screen, driver->underline[state->underline]);		}		if (attr_delta & SCREEN_ATTR_BOLD) {			if (ch->attr & SCREEN_ATTR_BOLD) {				add_bytes_to_string(screen, "\033[1m", 4);			} else {				/* Force repainting of the other attributes. */				state->color[0] = ch->color[0] + 1;			}		}		state->attr = ch->attr;	}	if (!compare_color(ch->color, state->color)) {		copy_color(state->color, ch->color);		add_foreground_color(screen, color256_seqs, ch);		if (!driver->transparent || ch->color[1] != 0) {			add_background_color(screen, color256_seqs, ch);		}		if (ch->attr & SCREEN_ATTR_BOLD)			add_bytes_to_string(screen, "\033[1m", 4);		if (ch->attr & SCREEN_ATTR_UNDERLINE && driver->underline) {			state->underline = !!(ch->attr & SCREEN_ATTR_UNDERLINE);			add_term_string(screen, driver->underline[state->underline]);		}	}	add_char_data(screen, driver, ch->data, ch->attr & SCREEN_ATTR_FRAME);}#endif#define add_chars(image_, term_, driver_, state_, ADD_CHAR)			\{										\	struct terminal_screen *screen = (term_)->screen;			\	int y = screen->dirty_from;					\	int ypos = y * (term_)->width;						\	int prev_y = -1;							\	int xmax = (term_)->width - 1;						\	int ymax = (term_)->height - 1;						\	struct screen_char *current = &screen->last_image[ypos];	\	struct screen_char *pos = &screen->image[ypos];		\	struct screen_char *prev_pos = NULL; /* Warning prevention. */	\										\	int_upper_bound(&screen->dirty_to, ymax);				\										\	for (; y <= screen->dirty_to; y++) {					\		int is_last_line = (y == ymax);					\		int x = 0;						\										\		for (; x <= xmax; x++, current++, pos++) {			\			/*  Workaround for terminals without			 *  "eat_newline_glitch (xn)", e.g., the cons25 family			 *  of terminals and cygwin terminal.			 *  It prevents display distortion, but char at bottom			 *  right of terminal will not be drawn.			 *  A better fix would be to correctly detects			 *  terminal type, and/or add a terminal option for			 *  this purpose. */					\										\			if (is_last_line && x == xmax)				\				break;						\										\			if (compare_bg_color(pos->color, current->color)) {	\				/* No update for exact match. */		\				if (compare_fg_color(pos->color, current->color)\				    && pos->data == current->data		\				    && pos->attr == current->attr)		\					continue;				\										\				/* Else if the color match and the data is				 * ``space''. */				\				if (pos->data <= ' ' && current->data <= ' '	\				    && pos->attr == current->attr)		\					continue;				\			}							\										\			/* Move the cursor when @prev_pos is more than 10 chars			 * away. */						\			if (prev_y != y || prev_pos + 10 <= pos) {		\				add_cursor_move_to_string(image_, y + 1, x + 1);\				prev_pos = pos;					\				prev_y = y;					\			}							\				 						\			for (; prev_pos <= pos ; prev_pos++)			\				ADD_CHAR(image_, driver_, prev_pos, state_);	\		}								\	}									\}/* Updating of the terminal screen is done by checking what needs to be updated * using the last screen. */voidredraw_screen(struct terminal *term){	struct screen_driver *driver;	struct string image;	struct screen_state state = { 0xFF, 0xFF, 0xFF, 0, { 0xFF, 0xFF } };	struct terminal_screen *screen = term->screen;	if (!screen || screen->dirty_from > screen->dirty_to) return;	if (term->master && is_blocked()) return;	driver = get_screen_driver(term);	if (!driver) return;	if (!init_string(&image)) return;	switch (driver->color_mode) {	case COLOR_MODE_MONO:	case COLOR_MODE_16:		add_chars(&image, term, driver, &state, add_char16);		break;#ifdef CONFIG_256_COLORS	case COLOR_MODE_256:		add_chars(&image, term, driver, &state, add_char256);		break;#endif	case COLOR_MODES:	case COLOR_MODE_DUMP:	default:		INTERNAL("Invalid color mode (%d).", driver->color_mode);		return;	}	if (image.length) {		if (driver->color_mode)			add_bytes_to_string(&image, "\033[37;40m", 8);		add_bytes_to_string(&image, "\033[0m", 4);		/* If we ended in border state end the frame mode. */		if (state.border && driver->frame_seqs)			add_term_string(&image, driver->frame_seqs[0]);	}	/* Even if nothing was redrawn, we possibly still need to move	 * cursor. */	if (image.length	    || screen->cx != screen->lcx	    || screen->cy != screen->lcy) {		screen->lcx = screen->cx;		screen->lcy = screen->cy;		add_cursor_move_to_string(&image, screen->cy + 1,						  screen->cx + 1);	}	if (image.length) {		if (term->master) want_draw();		hard_write(term->fdout, image.source, image.length);		if (term->master) done_draw();	}	done_string(&image);	copy_screen_chars(screen->last_image, screen->image, term->width * term->height);	screen->dirty_from = term->height;	screen->dirty_to = 0;}voiderase_screen(struct terminal *term){	if (term->master) {		if (is_blocked()) return;		want_draw();	}	hard_write(term->fdout, "\033[2J\033[1;1H", 10);	if (term->master) done_draw();}voidbeep_terminal(struct terminal *term){#ifdef CONFIG_WIN32	MessageBeep(MB_ICONEXCLAMATION);#else	hard_write(term->fdout, "\a", 1);#endif}struct terminal_screen *init_screen(void){	struct terminal_screen *screen;	screen = mem_calloc(1, sizeof(*screen));	if (!screen) return NULL;	screen->lcx = -1;	screen->lcy = -1;	return screen;}/* The two images are allocated in one chunk. *//* TODO: It seems allocation failure here is fatal. We should do something! */voidresize_screen(struct terminal *term, int width, int height){	struct terminal_screen *screen;	struct screen_char *image;	size_t size, bsize;	assert(term && term->screen);	screen = term->screen;	assert(width >= 0);	assert(height >= 0);	size = width * height;	if (size <= 0) return;	bsize = size * sizeof(*image);	image = mem_realloc(screen->image, bsize * 2);	if (!image) return;	screen->image = image;	screen->last_image = image + size;	memset(screen->image, 0, bsize);	memset(screen->last_image, 0xFF, bsize);	term->width = width;	term->height = height;	set_screen_dirty(screen, 0, height);}voiddone_screen(struct terminal_screen *screen){	mem_free_if(screen->image);	mem_free(screen);}

⌨️ 快捷键说明

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