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 + -
显示快捷键?