📄 keyboard.c
字号:
head 2.1;access;symbols;locks; strict;comment @ * @;2.1date 95.10.24.15.46.14; author tsurace; state Release;branches;next 1.1;1.1date 95.10.12.19.24.58; author tsurace; state Beta;branches;next ;desc@Responses to keyboard input.@2.1log@Roll.@text@/* keyboard.c: Handle keyboard input */
/* $Id: keyboard.c 1.1 1995/10/12 19:24:58 tsurace Beta tsurace $ */
#include "vt.h"
#ifdef PROTOTYPES
static 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);
#else
static 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 18
static 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);
}
@1.1log@Initial revision@text@d2 1a2 1/* $Id$ */@
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -