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

📄 screen.c

📁 一个很有名的浏览器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Terminal screen drawing routines. *//* $Id: screen.c,v 1.152.6.5 2005/04/05 21:08:43 jonas Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdlib.h>#include <string.h>#include "elinks.h"#include "config/options.h"#include "intl/charsets.h"#include "osdep/ascii.h"#include "osdep/osdep.h"#include "terminal/color.h"#include "terminal/draw.h"#include "terminal/hardio.h"#include "terminal/kbd.h"#include "terminal/screen.h"#include "terminal/terminal.h"#include "util/conv.h"#include "util/error.h"#include "util/memory.h"#include "util/string.h"/* TODO: We must use termcap/terminfo if available! --pasky */unsigned char frame_dumb[48] =	"   ||||++||++++++--|-+||++--|-+----++++++++     ";static unsigned char frame_vt100[48] =	"aaaxuuukkuxkjjjkmvwtqnttmlvwtqnvvwwmmllnnjla    ";/* For UTF8 I/O */static unsigned char frame_vt100_u[48] = {	177, 177, 177, 179, 180, 180, 180, 191,	191, 180, 179, 191, 217, 217, 217, 191,	192, 193, 194, 195, 196, 197, 195, 195,	192, 218, 193, 194, 195, 196, 197, 193,	193, 194, 194, 192, 192, 218, 218, 197,	197, 217, 218, 177,  32, 32,  32,  32};static unsigned char frame_freebsd[48] = {	130, 138, 128, 153, 150, 150, 150, 140,	140, 150, 153, 140, 139, 139, 139, 140,	142, 151, 152, 149, 146, 143, 149, 149,	142, 141, 151, 152, 149, 146, 143, 151,	151, 152, 152, 142, 142, 141, 141, 143,	143, 139, 141, 128, 128, 128, 128, 128,};static unsigned char frame_koi[48] = {	144, 145, 146, 129, 135, 178, 180, 167,	166, 181, 161, 168, 174, 173, 172, 131,	132, 137, 136, 134, 128, 138, 175, 176,	171, 165, 187, 184, 177, 160, 190, 185,	186, 182, 183, 170, 169, 162, 164, 189,	188, 133, 130, 141, 140, 142, 143, 139,};/* Most of this table is just 176 + <index in table>. */static unsigned char frame_restrict[48] = {	176, 177, 178, 179, 180, 179, 186, 186,	205, 185, 186, 187, 188, 186, 205, 191,	192, 193, 194, 195, 196, 197, 179, 186,	200, 201, 202, 203, 204, 205, 206, 205,	196, 205, 196, 186, 205, 205, 186, 186,	179, 217, 218, 219, 220, 221, 222, 223,};#define TERM_STRING(str) INIT_STRING(str, sizeof(str) - 1)#define add_term_string(str, tstr) \	add_bytes_to_string(str, (tstr).source, (tstr).length)static struct string m11_hack_frame_seqs[] = {	/* end border: */	TERM_STRING("\033[10m"),	/* begin border: */	TERM_STRING("\033[11m"),};static struct string vt100_frame_seqs[] = {	/* end border: */	TERM_STRING("\x0f"),	/* begin border: */	TERM_STRING("\x0e"),};static struct string underline_seqs[] = {	/* begin underline: */	TERM_STRING("\033[24m"),	/* end underline: */	TERM_STRING("\033[4m"),};/* Used in {add_char*()} and {redraw_screen()} to reduce the logic. It is * updated from terminal._template_.* using option change_hooks. *//* TODO: termcap/terminfo can maybe gradually be introduced via this *	 structure. We'll see. --jonas */struct screen_driver {	LIST_HEAD(struct screen_driver);	/* The terminal._template_.type. Together with the @name member the	 * uniquely identify the screen_driver. */	enum term_mode_type type;	/* Charsets when doing UTF8 I/O. */	/* [0] is the common charset and [1] is the frame charset.	 * Test wether to use UTF8 I/O using the use_utf8_io() macro. */	int charsets[2];	/* The frame translation table. May be NULL. */	unsigned char *frame;	/* The frame mode setup and teardown sequences. May be NULL. */	struct string *frame_seqs;	/* The underline mode setup and teardown sequences. May be NULL. */	struct string *underline;	/* The color mode */	enum color_mode color_mode;	/* These are directly derived from the terminal options. */	unsigned int transparent:1;	/* The terminal._template_ name. */	unsigned char name[1]; /* XXX: Keep last! */};static struct screen_driver dumb_screen_driver = {				NULL_LIST_HEAD,	/* type: */		TERM_DUMB,	/* charsets: */		{ -1, -1 },	/* No UTF8 I/O */	/* frame: */		frame_dumb,	/* frame_seqs: */	NULL,	/* underline: */	underline_seqs,	/* color_mode: */	COLOR_MODE_16,	/* transparent: */	1,};static struct screen_driver vt100_screen_driver = {				NULL_LIST_HEAD,	/* type: */		TERM_VT100,	/* charsets: */		{ -1, -1 },	/* No UTF8 I/O */	/* frame: */		frame_vt100,	/* frame_seqs: */	vt100_frame_seqs,	/* underline: */	underline_seqs,	/* color_mode: */	COLOR_MODE_16,	/* transparent: */	1,};static struct screen_driver linux_screen_driver = {				NULL_LIST_HEAD,	/* type: */		TERM_LINUX,	/* charsets: */		{ -1, -1 },	/* No UTF8 I/O */	/* frame: */		NULL,		/* No restrict_852 */	/* frame_seqs: */	NULL,		/* No m11_hack */	/* underline: */	underline_seqs,	/* color_mode: */	COLOR_MODE_16,	/* transparent: */	1,};static struct screen_driver koi8_screen_driver = {				NULL_LIST_HEAD,	/* type: */		TERM_KOI8,	/* charsets: */		{ -1, -1 },	/* No UTF8 I/O */	/* frame: */		frame_koi,	/* frame_seqs: */	NULL,	/* underline: */	underline_seqs,	/* color_mode: */	COLOR_MODE_16,	/* transparent: */	1,};static struct screen_driver freebsd_screen_driver = {				NULL_LIST_HEAD,	/* type: */		TERM_FREEBSD,	/* charsets: */		{ -1, -1 },	/* No UTF8 I/O */	/* frame: */		frame_freebsd,	/* frame_seqs: */	NULL,		/* No m11_hack */	/* underline: */	underline_seqs,	/* color_mode: */	COLOR_MODE_16,	/* transparent: */	1,};/* XXX: Keep in sync with enum term_mode_type. */static struct screen_driver *screen_drivers[] = {	/* TERM_DUMB: */	&dumb_screen_driver,	/* TERM_VT100: */	&vt100_screen_driver,	/* TERM_LINUX: */	&linux_screen_driver,	/* TERM_KOI8: */	&koi8_screen_driver,	/* TERM_FREEBSD: */	&freebsd_screen_driver,};static INIT_LIST_HEAD(active_screen_drivers);static voidupdate_screen_driver(struct screen_driver *driver, struct option *term_spec){	int utf8_io = get_opt_bool_tree(term_spec, "utf_8_io");	driver->color_mode = get_opt_int_tree(term_spec, "colors");	driver->transparent = get_opt_bool_tree(term_spec, "transparency");	if (get_opt_bool_tree(term_spec, "underline")) {		driver->underline = underline_seqs;	} else {		driver->underline = NULL;	}	if (utf8_io) {		driver->charsets[0] = get_opt_int_tree(term_spec, "charset");		if (driver->type == TERM_LINUX) {			if (get_opt_bool_tree(term_spec, "restrict_852"))				driver->frame = frame_restrict;			driver->charsets[1] = get_cp_index("cp437");		} else if (driver->type == TERM_FREEBSD) {			driver->charsets[1] = get_cp_index("cp437");		} else if (driver->type == TERM_VT100) {			driver->frame = frame_vt100_u;			driver->charsets[1] = get_cp_index("cp437");		} else if (driver->type == TERM_KOI8) {			driver->charsets[1] = get_cp_index("koi8-r");		} else {			driver->charsets[1] = driver->charsets[0];		}	} else {		driver->charsets[0] = -1;		if (driver->type == TERM_LINUX) {			if (get_opt_bool_tree(term_spec, "restrict_852"))				driver->frame = frame_restrict;			if (get_opt_bool_tree(term_spec, "m11_hack"))				driver->frame_seqs = m11_hack_frame_seqs;		} else if (driver->type == TERM_FREEBSD) {			if (get_opt_bool_tree(term_spec, "m11_hack"))				driver->frame_seqs = m11_hack_frame_seqs;		} else if (driver->type == TERM_VT100) {			driver->frame = frame_vt100;		}	}}static intscreen_driver_change_hook(struct session *ses, struct option *term_spec,			  struct option *changed){	enum term_mode_type type = get_opt_int_tree(term_spec, "type");	struct screen_driver *driver;	unsigned char *name = term_spec->name;	int len = strlen(name);	foreach (driver, active_screen_drivers)		if (driver->type == type && !memcmp(driver->name, name, len)) {			update_screen_driver(driver, term_spec);			break;		}	return 0;}static inline struct screen_driver *add_screen_driver(enum term_mode_type type, struct terminal *term, int env_len){	struct screen_driver *driver;	/* One byte is reserved for name in struct screen_driver. */	driver = mem_alloc(sizeof(*driver) + env_len);	if (!driver) return NULL;	memcpy(driver, screen_drivers[type], sizeof(*driver) - 1);	memcpy(driver->name, term->spec->name, env_len + 1);	add_to_list(active_screen_drivers, driver);	update_screen_driver(driver, term->spec);	term->spec->change_hook = screen_driver_change_hook;	return driver;}static inline struct screen_driver *get_screen_driver(struct terminal *term){	enum term_mode_type type = get_opt_int_tree(term->spec, "type");	unsigned char *name = term->spec->name;	int len = strlen(name);	struct screen_driver *driver;	foreach (driver, active_screen_drivers) {		if (driver->type != type) continue;		if (memcmp(driver->name, name, len + 1)) continue;		/* Some simple probably useless MRU ;) */		if (driver != active_screen_drivers.next) {			del_from_list(driver);			add_to_list(active_screen_drivers, driver);		}		return driver;	}	return add_screen_driver(type, term, len);}voiddone_screen_drivers(void){	free_list(active_screen_drivers);}/* Adds the term code for positioning the cursor at @x and @y to @string. * The template term code is: "\033[<@y>;<@x>H" */static inline struct string *add_cursor_move_to_string(struct string *screen, int y, int x){	/* 28 chars for both of the @y and @x numbers should be enough. */	unsigned char code[32];	int length = 2;	int ret;	code[0] = '\033';	code[1] = '[';	ret = longcat(code, &length, y, 30, 0);	/* Make sure theres atleast room for ';' and `some' number ;) */	if (ret < 0 || length > 30) return NULL;	code[length++] = ';';	ret = longcat(code, &length, x, sizeof(code) - length, 0);	if (ret < 0 || length > 31) return NULL;	code[length++] = 'H';	return add_bytes_to_string(screen, code, length);}struct screen_state {	unsigned char border;	unsigned char underline;	unsigned char bold;	unsigned char attr;	unsigned char color[2];};#ifdef CONFIG_256_COLORS#define compare_color(a, b)	(!memcmp((a), (b), 2))#define copy_color(a, b)	memcpy((a), (b), 2)#else#define compare_color(a, b)	((a)[0] == (b)[0])#define copy_color(a, b)	((a)[0] = (b)[0])#endif#define compare_bg_color(a, b)	(TERM_COLOR_BACKGROUND(a) == TERM_COLOR_BACKGROUND(b))#define compare_fg_color(a, b)	(TERM_COLOR_FOREGROUND(a) == TERM_COLOR_FOREGROUND(b))#define use_utf8_io(driver)	((driver)->charsets[0] != -1)static inline voidadd_char_data(struct string *screen, struct screen_driver *driver,	      unsigned char data, unsigned char border){	if (!isscreensafe(data)) {		add_char_to_string(screen, ' ');		return;	}	if (border && driver->frame && data >= 176 && data < 224)		data = driver->frame[data - 176];	if (use_utf8_io(driver)) {		int charset = driver->charsets[!!border];		add_to_string(screen, cp2utf_8(charset, data));		return;	}	add_char_to_string(screen, data);

⌨️ 快捷键说明

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