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

📄 terminal.c

📁 ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks
💻 C
📖 第 1 页 / 共 3 页
字号:
	win->data = data;	win->term = term;	win->xp = win->yp = 0;	add_at_pos(at, win);	win->handler(win, &ev, 0);}void add_window(struct terminal *term, void (*handler)(struct window *, struct event *, int), void *data){	add_window_at_pos(term, handler, data, (struct window *)(void *)&term->windows);}void delete_window(struct window *win){	struct event ev = {EV_ABORT, 0, 0, 0};	win->handler(win, &ev, 1);	del_from_list(win);	if (win->data) mem_free(win->data);	if (!F) redraw_terminal(win->term);#ifdef G	else {		struct window *w;		for (w = win->next; w != (void *)&win->term->windows; w = w->next) unite_rect(&w->redr, &win->pos, &w->redr);		register_bottom_half((void (*)(void *))redraw_windows, win->term);	}#endif	mem_free(win);}void delete_window_ev(struct window *win, struct event *ev){	struct window *w = win->next;	if ((void *)w == &win->term->windows) w = NULL;	delete_window(win);	if (ev && w && w->next != w) w->handler(w, ev, 1);}void set_window_ptr(struct window *win, int x, int y){	if (win->xp == x && win->yp == y) return;	win->xp = x;	win->yp = y;#ifdef G	if (F && win->prev != (void *)&win->term->windows) {		memcpy(&win->prev->redr, &win->term->dev->size, sizeof(struct rect));		register_bottom_half((void (*)(void *))redraw_windows, win->term);	}#endif}void get_parent_ptr(struct window *win, int *x, int *y){	if ((void *)win->next != &win->term->windows) {		*x = win->next->xp;		*y = win->next->yp;	} else {		*x = *y = 0;	}}struct ewd {	void (*fn)(void *);	void *data;	int b;};void empty_window_handler(struct window *win, struct event *ev, int fwd){	struct window *n;	struct ewd *ewd = win->data;	int x, y;	void (*fn)(void *) = ewd->fn;	void *data = ewd->data;	if (ewd->b) return;	switch ((int)ev->ev) {		case EV_INIT:		case EV_RESIZE:		case EV_REDRAW:			get_parent_ptr(win, &x, &y);			set_window_ptr(win, x, y);			return;		case EV_ABORT:			fn(data);			return;	}	ewd->b = 1;	n = win->next;	delete_window(win);	fn(data);	if (n->next != n) n->handler(n, ev, fwd);}void add_empty_window(struct terminal *term, void (*fn)(void *), void *data){	struct ewd *ewd;	ewd = mem_alloc(sizeof(struct ewd));	ewd->fn = fn;	ewd->data = data;	ewd->b = 0;	add_window(term, empty_window_handler, ewd);}void free_term_specs(void){	free_list(term_specs);}struct list_head term_specs = {&term_specs, &term_specs};struct term_spec dumb_term = { NULL, NULL, "", 0, 1, 0, 0, 0, 0, 0 };struct term_spec *get_term_spec(unsigned char *term){	struct term_spec *t;	NO_GFX;	foreach(t, term_specs) if (!strcasecmp(t->term, term)) return t;	return &dumb_term;}struct term_spec *new_term_spec(unsigned char *term){	struct term_spec *t;	foreach(t, term_specs) if (!strcasecmp(t->term, term)) return t;	t = mem_alloc(sizeof(struct term_spec));	memcpy(t, &dumb_term, sizeof(struct term_spec));	if (strlen(term) < MAX_TERM_LEN) strcpy(t->term, term);	else memcpy(t->term, term, MAX_TERM_LEN - 1), t->term[MAX_TERM_LEN - 1] = 0;	add_to_list(term_specs, t);	sync_term_specs();	return t;}void sync_term_specs(void){	struct terminal *term;	foreach(term, terminals) term->spec = get_term_spec(term->term);}struct terminal *init_term(int fdin, int fdout, void (*root_window)(struct window *, struct event *, int)){	static tcount terminal_count = 0;	struct terminal *term;	struct window *win;	NO_GFX;	term = mem_calloc(sizeof (struct terminal));	term->count = terminal_count++;	term->fdin = fdin;	term->fdout = fdout;	term->master = term->fdout == get_output_handle();	term->lcx = -1;	term->lcy = -1;	term->dirty = 1;	term->blocked = -1;	term->screen = DUMMY;	term->last_screen = DUMMY;	term->spec = &dumb_term;	term->input_queue = DUMMY;	init_list(term->windows);	win = mem_calloc(sizeof(struct window));	win->handler = root_window;	win->term = term;	add_to_list(term->windows, win);	/*alloc_term_screen(term, 80, 25);*/	add_to_list(terminals, term);	set_handlers(fdin, (void (*)(void *))in_term, NULL, (void (*)(void *))destroy_terminal, term);	return term;}#ifdef Gstruct term_spec gfx_term = { NULL, NULL, "", 0, 0, 0, 0, 0, 0, 0 };struct terminal *init_gfx_term(void (*root_window)(struct window *, struct event *, int), void *info, int len){	static tcount terminal_count = 0;	struct terminal *term;	struct graphics_device *dev;	struct window *win;	unsigned char *cwd;	NO_TXT;	term = mem_calloc(sizeof (struct terminal));	term->count = terminal_count++;	term->fdin = -1;	if (!(term->dev = dev = drv->init_device())) {		mem_free(term);		check_if_no_terminal();		return NULL;	}	dev->user_data = term;	term->master = 1;	term->blocked = -1;	term->x = dev->size.x2;	term->y = dev->size.y2;	term->environment = !(drv->flags & GD_ONLY_1_WINDOW) ? ENV_G : 0;	if (!strcasecmp(drv->name, "x")) term->environment |= ENV_XWIN;	term->spec = &gfx_term;	if ((cwd = get_cwd())) {		safe_strncpy(term->cwd, cwd, MAX_CWD_LEN);		mem_free(cwd);	}	gfx_term.charset = get_cp_index("utf-8");	if (gfx_term.charset == -1) gfx_term.charset = 0;	init_list(term->windows);	win = mem_calloc(sizeof (struct window));	win->handler = root_window;	win->term = term;	win->pos.x2 = dev->size.x2;	win->pos.y2 = dev->size.y2;	add_to_list(term->windows, win);	add_to_list(terminals, term);	dev->redraw_handler = t_redraw;	dev->resize_handler = t_resize;	dev->keyboard_handler = t_kbd;	dev->mouse_handler = t_mouse;	{		int *ptr;		struct event ev = { EV_INIT, 0, 0, 0 };		ev.x = dev->size.x2;		ev.y = dev->size.y2;		if ((unsigned)len > MAXINT - sizeof(int)) overalloc();		ptr = mem_alloc(sizeof(int) + len);		*ptr = len;		memcpy(ptr + 1, info, len);		ev.b = (long)ptr;		root_window(win, &ev, 0);		mem_free(ptr);	}	return term;}void t_redraw(struct graphics_device *dev, struct rect *r){	struct terminal *term = dev->user_data;	struct window *win;	/*debug("%d %d %d %d", r->x1, r->x2, r->y1, r->y2);*/	/*fprintf(stderr, "t_redraw: %d,%d %d,%d\n", r->x1, r->y1, r->x2, r->y2);*/	foreach(win, term->windows) unite_rect(&win->redr, r, &win->redr);	register_bottom_half((void (*)(void *))redraw_windows, term);}void t_resize(struct graphics_device *dev){	struct terminal *term = dev->user_data;	struct window *win;	struct event ev = {EV_RESIZE, 0, 0, 0};	term->x = ev.x = dev->size.x2;	term->y = ev.y = dev->size.y2;	drv->set_clip_area(dev, &dev->size);	foreach(win, term->windows) {		win->handler(win, &ev, 0);	}	drv->set_clip_area(dev, &dev->size);}void t_kbd(struct graphics_device *dev, int key, int flags){	struct terminal *term = dev->user_data;	struct event ev = {EV_KBD, 0, 0, 0};	struct rect r = {0, 0, 0, 0};	r.x2 = dev->size.x2, r.y2 = dev->size.y2;	ev.x = key;	ev.y = flags;	if (upcase(key) == 'L' && flags == KBD_CTRL) {		t_redraw(dev, &r);		return;	} else {		drv->set_clip_area(dev, &r);		if (list_empty(term->windows)) return;		if (ev.x == KBD_CTRL_C || ev.x == KBD_CLOSE) ((struct window *)(void *)&term->windows)->prev->handler(term->windows.prev, &ev, 0);		else ((struct window *)(void *)&term->windows)->next->handler(term->windows.next, &ev, 0);	}}void t_mouse(struct graphics_device *dev, int x, int y, int b){	struct terminal *term = dev->user_data;	struct event ev = {EV_MOUSE, 0, 0, 0};	struct rect r = {0, 0, 0, 0};	r.x2 = dev->size.x2, r.y2 = dev->size.y2;	ev.x = x, ev.y = y, ev.b = b;	drv->set_clip_area(dev, &r);	if (list_empty(term->windows)) return;	((struct window *)(void *)&term->windows)->next->handler(term->windows.next, &ev, 0);}#endifvoid in_term(struct terminal *term){	struct event *ev;	int r;	unsigned char *iq;	NO_GFX;	if ((unsigned)term->qlen + ALLOC_GR > MAXINT) overalloc();	iq = mem_realloc(term->input_queue, term->qlen + ALLOC_GR);	term->input_queue = iq;	if ((r = read(term->fdin, iq + term->qlen, ALLOC_GR)) <= 0) {		if (r == -1 && errno != ECONNRESET) error("ERROR: error %d on terminal: could not read event", errno);		destroy_terminal(term);		return;	}	term->qlen += r;	test_queue:	if ((size_t)term->qlen < sizeof(struct event)) return;	ev = (struct event *)iq;	r = sizeof(struct event);	if (ev->ev != EV_INIT && ev->ev != EV_RESIZE && ev->ev != EV_REDRAW && ev->ev != EV_KBD && ev->ev != EV_MOUSE && ev->ev != EV_ABORT) {		error("ERROR: error on terminal: bad event %d", ev->ev);		goto mm;	}	if (ev->ev == EV_INIT) {		int init_len;		if ((size_t)term->qlen < sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN + 2 * sizeof(int)) return;		init_len = *(int *)(iq + sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN + sizeof(int));		if ((size_t)term->qlen < sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN + 2 * sizeof(int) + init_len) return;		memcpy(term->term, iq + sizeof(struct event), MAX_TERM_LEN);		term->term[MAX_TERM_LEN - 1] = 0;		memcpy(term->cwd, iq + sizeof(struct event) + MAX_TERM_LEN, MAX_CWD_LEN);		term->cwd[MAX_CWD_LEN - 1] = 0;		term->environment = *(int *)(iq + sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN);		ev->b = (long)(iq + sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN + sizeof(int));		r = sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN + 2 * sizeof(int) + init_len;		sync_term_specs();	}	if (ev->ev == EV_REDRAW || ev->ev == EV_RESIZE || ev->ev == EV_INIT) {		struct window *win;		send_redraw:		if (ev->x < 0 || ev->y < 0) {			error("ERROR: bad terminal size: %d, %d", (int)ev->x, (int)ev->y);			goto mm;		}		alloc_term_screen(term, ev->x, ev->y);		clear_terminal(term);		erase_screen(term);		term->redrawing = 1;		foreachback(win, term->windows) win->handler(win, ev, 0);		term->redrawing = 0;	}	if (ev->ev == EV_KBD || ev->ev == EV_MOUSE) {		if (ev->ev == EV_KBD && upcase(ev->x) == 'L' && ev->y & KBD_CTRL) {			ev->ev = EV_REDRAW;			ev->x = term->x;			ev->y = term->y;			goto send_redraw;		}		else if (ev->ev == EV_KBD && ev->x == KBD_CTRL_C) ((struct window *)(void *)&term->windows)->prev->handler(term->windows.prev, ev, 0);		else ((struct window *)(void *)&term->windows)->next->handler(term->windows.next, ev, 0);	}	if (ev->ev == EV_ABORT) {		destroy_terminal(term);		return;	}	/*redraw_screen(term);*/	mm:	if (term->qlen == r) term->qlen = 0;	else memmove(iq, iq + r, term->qlen -= r);	goto test_queue;}static inline int getcompcode(int c){	return (c<<1 | (c&4)>>2) & 7;}unsigned char frame_dumb[48] =	"   ||||++||++++++--|-+||++--|-+----++++++++     ";unsigned char frame_vt100[48] =	"aaaxuuukkuxkjjjkmvwtqnttmlvwtqnvvwwmmllnnjla    ";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,};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,};unsigned char frame_restrict[48] = {	0, 0, 0, 0, 0, 179, 186, 186,	205, 0, 0, 0, 0, 186, 205, 0,	0, 0, 0, 0, 0, 0, 179, 186,	0, 0, 0, 0, 0, 0, 0, 205,	196, 205, 196, 186, 205, 205, 186, 186,	179, 0, 0, 0, 0, 0, 0, 0,};#define PRINT_CHAR(p)									\{											\	unsigned ch = term->screen[p];							\	unsigned char c = ch & 0xff;							\

⌨️ 快捷键说明

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