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

📄 kbd.c

📁 一个很有名的浏览器
💻 C
📖 第 1 页 / 共 2 页
字号:
#define RD(xx) {							\		unsigned char cc;					\									\		if (p < bytes_read)					\			cc = buf[p++];					\		else if ((hard_read(itrm->sock_in, &cc, 1)) <= 0)	\			goto free_and_return;				\		xx = cc;						\	}	RD(fg);	if (!init_string(&path)) goto free_and_return;	while (1) {		RD(ch);		if (!ch) break;		add_char_to_string(&path, ch);	}	if (!init_string(&delete)) {		done_string(&path);		goto free_and_return;	}	while (1) {		RD(ch);		if (!ch) break;		add_char_to_string(&delete, ch);	}#undef RD	if (!*path.source) {		dispatch_special(delete.source);	} else {		int blockh;		unsigned char *param;		int path_len, del_len, param_len;		if (is_blocked() && fg) {			if (*delete.source) unlink(delete.source);			goto nasty_thing;		}		path_len = path.length;		del_len = delete.length;		param_len = path_len + del_len + 3;		param = mem_alloc(param_len);		if (!param) goto nasty_thing;		param[0] = fg;		memcpy(param + 1, path.source, path_len + 1);		memcpy(param + 1 + path_len + 1, delete.source, del_len + 1);		if (fg == 1) block_itrm(itrm->ctl_in);		blockh = start_thread((void (*)(void *, int)) exec_thread,				      param, param_len);		if (blockh == -1) {			if (fg == 1)				unblock_itrm(itrm->ctl_in);			mem_free(param);			goto nasty_thing;		}		mem_free(param);		if (fg == 1) {			set_handlers(blockh, (void (*)(void *)) unblock_itrm_x,				     NULL, (void (*)(void *)) unblock_itrm_x,				     (void *) (long) blockh);			/* block_itrm(itrm->ctl_in); */		} else {			set_handlers(blockh, close_handle, NULL, close_handle,				     (void *) (long) blockh);		}	}nasty_thing:	done_string(&path);	done_string(&delete);	assert(OUT_BUF_SIZE - p > 0);	memmove(buf, buf + p, OUT_BUF_SIZE - p);	bytes_read -= p;	goto qwerty;free_and_return:	free_trm(itrm);}static voidkbd_timeout(struct itrm *itrm){	struct term_event ev = INIT_TERM_EVENT(EVENT_KBD, KBD_ESC, 0, 0);	itrm->timer = -1;	if (can_read(itrm->std_in)) {		in_kbd(itrm);		return;	}	assertm(itrm->qlen, "timeout on empty queue");	if_assert_failed return;	queue_event(itrm, (char *) &ev, sizeof(ev));	if (--itrm->qlen)		memmove(itrm->kqueue, itrm->kqueue + 1, itrm->qlen);	while (process_queue(itrm));}/* Returns the length of the escape sequence */static inline intget_esc_code(unsigned char *str, int len, unsigned char *code, int *num){	int pos;	*num = 0;	*code = '\0';	for (pos = 2; pos < len; pos++) {		if (!isdigit(str[pos]) || pos > 7) {			*code = str[pos];			return pos + 1;		}		*num = *num * 10 + str[pos] - '0';	}	return 0;}/* Define it to dump queue content in a readable form, * it may help to determine terminal sequences, and see what goes on. --Zas *//* #define DEBUG_ITRM_QUEUE */#ifdef DEBUG_ITRM_QUEUE#include <ctype.h>	/* isprint() isspace() */#endif#ifdef CONFIG_MOUSEstatic intdecode_mouse_position(struct itrm *itrm, int from){	int position;	position = (unsigned char) (itrm->kqueue[from]) - ' ' - 1		 + ((int) ((unsigned char) (itrm->kqueue[from + 1]) - ' ' - 1) << 7);	return (position & (1 << 13)) ? 0 : position;}#define get_mouse_x_position(itrm, esclen) decode_mouse_position(itrm, (esclen) + 1)#define get_mouse_y_position(itrm, esclen) decode_mouse_position(itrm, (esclen) + 3)/* Returns length of the escape sequence or -1 if the caller needs to set up * the ESC delay timer. */static intdecode_terminal_mouse_escape_sequence(struct itrm *itrm, struct term_event *ev,				      int el, int v){	static int xterm_button = -1;	struct term_event_mouse *mouse = &ev->info.mouse;	if (itrm->qlen - el < 3)		return -1;	if (v == 5) {		if (xterm_button == -1)			xterm_button = 0;		if (itrm->qlen - el < 5)			return -1;		mouse->x = get_mouse_x_position(itrm, el);		mouse->y = get_mouse_y_position(itrm, el);		switch ((itrm->kqueue[el] - ' ') ^ xterm_button) { /* Every event changes only one bit */		    case TW_BUTT_LEFT:   mouse->button = B_LEFT | ( (xterm_button & TW_BUTT_LEFT) ? B_UP : B_DOWN ); break;		    case TW_BUTT_MIDDLE: mouse->button = B_MIDDLE | ( (xterm_button & TW_BUTT_MIDDLE) ? B_UP : B_DOWN ); break;		    case TW_BUTT_RIGHT:  mouse->button = B_RIGHT | ( (xterm_button & TW_BUTT_RIGHT) ? B_UP : B_DOWN ); break;		    case 0: mouse->button = B_DRAG;		    /* default : Twin protocol error */		}		xterm_button = itrm->kqueue[el] - ' ';		el += 5;	} else {		/* See terminal/mouse.h about details of the mouse reporting		 * protocol and {struct term_event_mouse->button} bitmask		 * structure. */		mouse->x = itrm->kqueue[el+1] - ' ' - 1;		mouse->y = itrm->kqueue[el+2] - ' ' - 1;		/* There are rumours arising from remnants of code dating to		 * the ancient Mikulas' times that bit 4 indicated B_DRAG.		 * However, I didn't find on what terminal it should be ever		 * supposed to work and it conflicts with wheels. So I removed		 * the last remnants of the code as well. --pasky */		mouse->button = (itrm->kqueue[el] & 7) | B_DOWN;		/* smartglasses1 - rxvt wheel: */		if (mouse->button == 3 && xterm_button != -1) {			mouse->button = xterm_button | B_UP;		}		/* xterm wheel: */		if ((itrm->kqueue[el] & 96) == 96) {			mouse->button = (itrm->kqueue[el] & 1) ? B_WHEEL_DOWN : B_WHEEL_UP;		}		xterm_button = -1;		/* XXX: Eterm/aterm uses rxvt-like reporting, but sends the		 * release sequence for wheel. rxvt itself sends only press		 * sequence. Since we can't reliably guess what we're talking		 * with from $TERM, we will rather support Eterm/aterm, as in		 * rxvt, at least each second wheel up move will work. */		if (check_mouse_action(ev, B_DOWN))#if 0			    && !(getenv("TERM") && strstr("rxvt", getenv("TERM"))				 && (ev->b & BM_BUTT) >= B_WHEEL_UP))#endif			xterm_button = get_mouse_button(ev);		el += 3;	}	/* Postpone changing of the event type until all sanity	 * checks have been done. */	ev->ev = EVENT_MOUSE;	return el;}#endif /* CONFIG_MOUSE *//* Returns length of the escape sequence or -1 if the caller needs to set up * the ESC delay timer. */static intdecode_terminal_escape_sequence(struct itrm *itrm, struct term_event *ev){	unsigned char c;	int key = -1, modifier = 0;	int v;	int el;	if (itrm->qlen < 3) return -1;	if (itrm->kqueue[2] == '[') {		if (itrm->qlen >= 4		    && itrm->kqueue[3] >= 'A'		    && itrm->kqueue[3] <= 'L') {			ev->info.keyboard.key = KBD_F1 + itrm->kqueue[3] - 'A';			return 4;		}		return -1;	}	el = get_esc_code(itrm->kqueue, itrm->qlen, &c, &v);#ifdef DEBUG_ITRM_QUEUE	fprintf(stderr, "esc code: %c v=%d c=%c el=%d\n", itrm->kqueue[1], v, c, el);	fflush(stderr);#endif	switch (c) {	case 0: return -1;	case 'A': key = KBD_UP; break;	case 'B': key = KBD_DOWN; break;	case 'C': key = KBD_RIGHT; break;	case 'D': key = KBD_LEFT; break;	case 'F':	case 'e': key = KBD_END; break;	case 'H': key = KBD_HOME; break;	case 'I': key = KBD_PAGE_UP; break;	case 'G': key = KBD_PAGE_DOWN; break;	case 'z': switch (v) {		case 247: key = KBD_INS; break;		case 214: key = KBD_HOME; break;		case 220: key = KBD_END; break;		case 216: key = KBD_PAGE_UP; break;		case 222: key = KBD_PAGE_DOWN; break;		case 249: key = KBD_DEL; break;		} break;	case '~': switch (v) {		case 1: key = KBD_HOME; break;		case 2: key = KBD_INS; break;		case 3: key = KBD_DEL; break;		case 4: key = KBD_END; break;		case 5: key = KBD_PAGE_UP; break;		case 6: key = KBD_PAGE_DOWN; break;		case 7: key = KBD_HOME; break;		case 8: key = KBD_END; break;		case 11: key = KBD_F1; break;		case 12: key = KBD_F2; break;		case 13: key = KBD_F3; break;		case 14: key = KBD_F4; break;		case 15: key = KBD_F5; break;		case 17: key = KBD_F6; break;		case 18: key = KBD_F7; break;		case 19: key = KBD_F8; break;		case 20: key = KBD_F9; break;		case 21: key = KBD_F10; break;		case 23: key = KBD_F11; break;		case 24: key = KBD_F12; break;		/* Give preference to F11 and F12 over shifted F1 and F2. */		/*		case 23: key = KBD_F1; modifier = KBD_SHIFT; break;		case 24: key = KBD_F2; modifier = KBD_SHIFT; break;		*/		case 25: key = KBD_F3; modifier = KBD_SHIFT; break;		case 26: key = KBD_F4; modifier = KBD_SHIFT; break;		case 28: key = KBD_F5; modifier = KBD_SHIFT; break;		case 29: key = KBD_F6; modifier = KBD_SHIFT; break;		case 31: key = KBD_F7; modifier = KBD_SHIFT; break;		case 32: key = KBD_F8; modifier = KBD_SHIFT; break;		case 33: key = KBD_F9; modifier = KBD_SHIFT; break;		case 34: key = KBD_F10; modifier = KBD_SHIFT; break;		} break;	case 'R': resize_terminal(); break;	case 'M':#ifdef CONFIG_MOUSE		el = decode_terminal_mouse_escape_sequence(itrm, ev, el, v);#endif /* CONFIG_MOUSE */		break;	}	/* The event might have been changed to a mouse event */	if (ev->ev == EVENT_KBD && key != -1) {		ev->info.keyboard.key = key;		ev->info.keyboard.modifier = modifier;	}	return el;}static voidset_kbd_event(struct term_event *ev, int key, int modifier){	switch (key) {	case ASCII_TAB:		key = KBD_TAB;		break;	case ASCII_BS:	case ASCII_DEL:		key = KBD_BS;		break;	case ASCII_LF:	case ASCII_CR:		key = KBD_ENTER;		break;	default:		if (key < ' ') {			key += 'A' - 1;			modifier = KBD_CTRL;		}	}	ev->info.keyboard.key = key;	ev->info.keyboard.modifier = modifier;}/* I feeeeeel the neeeed ... to rewrite this ... --pasky *//* Just Do it ! --Zas */static intprocess_queue(struct itrm *itrm){	struct term_event ev = INIT_TERM_EVENT(EVENT_KBD, -1, 0, 0);	int el = 0;	if (!itrm->qlen) goto end;#ifdef DEBUG_ITRM_QUEUE	{		int i;		/* Dump current queue in a readable form to stderr. */		for (i = 0; i < itrm->qlen; i++)			if (itrm->kqueue[i] == ASCII_ESC)				fprintf(stderr, "ESC ");			else if (isprint(itrm->kqueue[i]) && !isspace(itrm->kqueue[i]))				fprintf(stderr, "%c ", itrm->kqueue[i]);			else				fprintf(stderr, "0x%02x ", itrm->kqueue[i]);		fprintf(stderr, "\n");		fflush(stderr);	}#endif /* DEBUG_ITRM_QUEUE */	if (itrm->kqueue[0] == ASCII_ESC) {		if (itrm->qlen < 2) goto ret;		if (itrm->kqueue[1] == '[' || itrm->kqueue[1] == 'O') {			el = decode_terminal_escape_sequence(itrm, &ev);			if (el == -1) goto ret;		} else {			el = 2;			if (itrm->kqueue[1] == ASCII_ESC) {				if (itrm->qlen >= 3 &&				    (itrm->kqueue[2] == '[' ||				     itrm->kqueue[2] == 'O')) {					el = 1;				}				set_kbd_event(&ev, KBD_ESC, 0);			} else {				set_kbd_event(&ev, itrm->kqueue[1], KBD_ALT);			}		}	} else if (itrm->kqueue[0] == 0) {		static const struct { int key, modifier; } os2xtd[256] = {#include "terminal/key.inc"		};		if (itrm->qlen < 2) goto ret;		ev.info.keyboard.key = os2xtd[itrm->kqueue[1]].key;		if (!ev.info.keyboard.key)			ev.info.keyboard.key = -1;		ev.info.keyboard.modifier = os2xtd[itrm->kqueue[1]].modifier;		el = 2;	} else {		el = 1;		set_kbd_event(&ev, itrm->kqueue[0], 0);	}	assertm(itrm->qlen >= el, "event queue underflow");	if_assert_failed { itrm->qlen = el; }	itrm->qlen -= el;	/* The call to decode_terminal_escape_sequence() might have changed the	 * keyboard event to a mouse event. */	if (ev.ev == EVENT_MOUSE || ev.info.keyboard.key != -1)		queue_event(itrm, (char *) &ev, sizeof(ev));	if (itrm->qlen)		memmove(itrm->kqueue, itrm->kqueue + el, itrm->qlen);end:	if (itrm->qlen < IN_BUF_SIZE)		set_handlers(itrm->std_in, (void (*)(void *)) in_kbd, NULL,			     (void (*)(void *)) free_trm, itrm);	return el;ret:	itrm->timer = install_timer(ESC_TIMEOUT, (void (*)(void *)) kbd_timeout,				    itrm);	return 0;}static voidin_kbd(struct itrm *itrm){	int r;	if (!can_read(itrm->std_in)) return;	if (itrm->timer != -1) {		kill_timer(itrm->timer);		itrm->timer = -1;	}	if (itrm->qlen >= IN_BUF_SIZE) {		set_handlers(itrm->std_in, NULL, NULL,			     (void (*)(void *)) free_trm, itrm);		while (process_queue(itrm));		return;	}	r = safe_read(itrm->std_in, itrm->kqueue + itrm->qlen,		      IN_BUF_SIZE - itrm->qlen);	if (r <= 0) {		free_trm(itrm);		return;	}	itrm->qlen += r;	if (itrm->qlen > IN_BUF_SIZE) {		ERROR(gettext("Too many bytes read from the itrm!"));		itrm->qlen = IN_BUF_SIZE;	}	while (process_queue(itrm));}

⌨️ 快捷键说明

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