keyboard.c

来自「Unix下的MUD客户端程序」· C语言 代码 · 共 265 行

C
265
字号
/* keyboard.c: Handle keyboard input */#include "vt.h"#ifdef PROTOTYPESstatic void flush_out(void);static int match_key(char *, char *);static int check_keys(char *, Unode **);static int fword(void);static int bword(void);static void process_kbd_line(Cstr);#elsestatic void flush_out(), process_kbd_line();#endif#define margin (cols - 1)#define klen (kbuf.c.l)#define kptr (kbuf.c.s)/* Key matching results */#define KM_NONE	    0#define KM_PARTIAL  1#define KM_TOTAL    2/* Indexes to functions table */#define K_CUP	   0#define K_CDOWN	   1#define K_CLEFT	   2#define K_CRIGHT   3#define K_CHOME	   4#define K_CEND	   5#define K_CWLEFT   6#define K_CWRIGHT  7#define K_BSPC	   8#define K_BWORD	   9#define K_BHOME	  10#define K_DBUF	  11#define K_DCH	  12#define K_DWORD	  13#define K_DEND	  14#define K_REFRESH 15#define K_REDRAW  16#define K_MODE	  17#define K_PROCESS 18static String kout = { { "", 0 }, 0 };	/* Text to send to input_puts() */static String kkey = { { "", 0 }, 0 };	/* Text to match against keys	*/static String kproc = { { "", 0 }, 0 }; /* Temp buffer for processing	*/String kbuf = { { "", 0 }, 0 };		/* Main key buffer		*/int kpos = 0;int keyboard_input_waiting = 0;extern int cols, vtc_mode;extern Estate *gen_read, *gen_high, *gen_low;extern Unode *klookup[], *active_win;/* Feed the kout buffer to input_inputs() */static void flush_out(){	if (!kout.c.l)		return;	s_nt(&kout);	curs_input();	input_puts(kout.c);	s_insert(&kbuf, kout.c, kpos);	kpos += kout.c.l;	s_term(&kout, 0);}/* Compare a key sequence with a string */static int match_key(text, seq)	char *text, *seq;{	do		text++, seq++;	while (*text && lcase(*text) == lcase(*seq));	return *text ? KM_NONE : *seq ? KM_PARTIAL : KM_TOTAL;}/* Check the string s against all keys in clump */static int check_keys(text, rkey)	char *text;	Unode **rkey;{	Unode *kp;	int match;	int found_partial = 0;	kp = klookup[lcase(*text)];	if (!kp)		return KM_NONE;	for (; lcase(*kp->Kseq) == lcase(*text); kp = kp->next) {		match = match_key(text, kp->Kseq);		if (match == KM_TOTAL) {			*rkey = kp;			return KM_TOTAL;		} else if (match == KM_PARTIAL)			found_partial = 1;	}	return found_partial ? KM_PARTIAL : KM_NONE;}/* Return the position of the beginning of the next word */static int fword(){	int pos = kpos;	for (; pos < klen && kptr[pos] != ' '; pos++);	for (; pos < klen && kptr[pos] == ' '; pos++);	return pos;}/* Return the position of the beginning of the previous word */static int bword(){	int pos = kpos - 1;	for (; pos >= 0 && kptr[pos] == ' '; pos--);	for (; pos >= 0 && kptr[pos] != ' '; pos--);	return pos + 1;}/* Perform an editing function */void do_edit_func(func)	int func;{	int pos;	curs_input();	switch (func) {	    case K_BSPC:		if (kpos) {			input_bdel(1);			s_delete(&kbuf, --kpos, 1);		}	    Case K_BWORD:		pos = bword();		input_bdel(kpos - pos);		s_delete(&kbuf, pos, kpos - pos);		kpos = pos;	    Case K_BHOME:		input_bdel(kpos);		s_delete(&kbuf, 0, kpos);		kpos = 0;	    Case K_DBUF:		input_clear();		s_term(&kbuf, kpos = 0);	    Case K_DCH:		if (kpos < klen) {			input_fdel(1);			s_delete(&kbuf, kpos, 1);		}	    Case K_DWORD:		pos = fword();		input_fdel(pos - kpos);		s_delete(&kbuf, kpos, pos - kpos);	    Case K_DEND:		input_fdel(klen - kpos);		s_term(&kbuf, kpos);	    Case K_REFRESH:		input_clear();		input_draw();	    Case K_REDRAW:		redraw_screen();	    Case K_MODE:		toggle_imode();	    Case K_PROCESS:		input_newline();		s_cpy(&kproc, kbuf.c);		s_term(&kbuf, kpos = 0);		process_kbd_line(kproc.c);	    Default:		switch (func) {		    case K_CUP:		pos = kpos - margin;		    Case K_CDOWN:	pos = kpos + margin;		    Case K_CLEFT:	pos = kpos - 1;		    Case K_CRIGHT:	pos = kpos + 1;		    Case K_CHOME:	pos = 0;		    Case K_CEND:	pos = klen;		    Case K_CWLEFT:	pos = bword();		    Case K_CWRIGHT:	pos = fword();		    Default: return;	/* Putz */		}		pos = pos < 0 ? 0 : pos > klen ? klen : pos;		input_cmove(pos);		kpos = pos;	}}void process_incoming(s)	char *s;{	Unode *key;	int val;	char *temp;	if (*s)		keyboard_input_waiting++;	for (; *s; s++) {		if (!s[1])			keyboard_input_waiting--;		if (gen_high || active_win->Wghstack) {			flush_out();			resume_int(gen_high ? &gen_high					    : &active_win->Wghstack, *s);			continue;		}		s_add(&kkey, *s);		val = check_keys(kkey.c.s, &key);		if (val == KM_TOTAL) {			flush_out();			s_term(&kkey, 0);			if (key->Ktype == K_EFUNC)				do_edit_func(key->Kefunc);			else				run_prog(key->Kcmd->cmd);			continue;		}		if (val == KM_PARTIAL)			continue;		if (gen_low || active_win->Wglstack) {			flush_out();			resume_int(gen_low ? &gen_low					   : &active_win->Wglstack, *kkey.c.s);		} else if (isprint(*kkey.c.s))			s_fadd(&kout, *kkey.c.s);		if (kkey.c.l > 1) {			temp = vtstrdup(kkey.c.s + 1);			s_term(&kkey, 0);			process_incoming(temp);			Discardstring(temp);		} else			s_term(&kkey, 0);	}	flush_out();}static void process_kbd_line(line)	Cstr line;{	if (vtc_mode)		parse(line.s);	else		give_window(active_win, istr_c(line));}void give_window(win, is)	Unode *win;	Istr *is;{	is->refs++;	if (gen_read)		resume_istr(&gen_read, is);	else if (win->Wrstack)		resume_istr(&win->Wrstack, is);	else if (win->Wtermread)		run_prog_istr(win->Wtermread->cmd, is, win, NULL);	else if (win->Wrmt) {		transmit(win->Wrmt, is->rs->str.c);		if (win->Wrmt)			transmit(win->Wrmt, cstr_s("\n"));	}	dec_ref_istr(is);}

⌨️ 快捷键说明

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