📄 kbd.c
字号:
#include "links.h"#define OUT_BUF_SIZE 16384#define IN_BUF_SIZE 16#define USE_TWIN_MOUSE 1#define TW_BUTT_LEFT 1#define TW_BUTT_MIDDLE 2#define TW_BUTT_RIGHT 4struct itrm { int std_in; int std_out; int sock_in; int sock_out; int ctl_in; int blocked; struct termios t; int flags; unsigned char kqueue[IN_BUF_SIZE]; int qlen; int tm; unsigned char *ev_queue; int eqlen; void *mouse_h; unsigned char *orig_title;};void free_trm(struct itrm *);void in_kbd(struct itrm *);void in_sock(struct itrm *);struct itrm *ditrm = NULL;int is_blocked(){ return ditrm && ditrm->blocked;}void free_all_itrms(){ if (ditrm) free_trm(ditrm);}void write_ev_queue(struct itrm *itrm){ int l; if (!itrm->eqlen) internal("event queue empty"); if ((l = write(itrm->sock_out, itrm->ev_queue, itrm->eqlen > 128 ? 128 : itrm->eqlen)) == -1) { free_trm(itrm); return; } memmove(itrm->ev_queue, itrm->ev_queue + l, itrm->eqlen -= l); if (!itrm->eqlen) set_handlers(itrm->sock_out, get_handler(itrm->sock_out, H_READ), NULL, get_handler(itrm->sock_out, H_ERROR), get_handler(itrm->sock_out, H_DATA));}void queue_event(struct itrm *itrm, unsigned char *data, int len);void mouse_queue_event(struct itrm *itrm, unsigned char *data, int len){ if (itrm->blocked) return; queue_event(itrm, data, len);}void queue_event(struct itrm *itrm, unsigned char *data, int len){ int w = 0; if (!len) return; if (!itrm->eqlen && can_write(itrm->sock_out) && (w = write(itrm->sock_out, data, len)) <= 0) { /*free_trm(itrm);*/ register_bottom_half((void (*)(void *))free_trm, itrm); return; } if (w < len) { if ((unsigned)itrm->eqlen + (unsigned)(len - w) > MAXINT) overalloc(); itrm->ev_queue = mem_realloc(itrm->ev_queue, itrm->eqlen + len - w); memcpy(itrm->ev_queue + itrm->eqlen, data + w, len - w); itrm->eqlen += len - w; set_handlers(itrm->sock_out, get_handler(itrm->sock_out, H_READ), (void (*)(void *))write_ev_queue, (void (*)(void *))free_trm, itrm); }}void kbd_ctrl_c(){ struct event ev = { EV_KBD, KBD_CTRL_C, 0, 0 }; if (ditrm) queue_event(ditrm, (unsigned char *)&ev, sizeof(struct event));}/*unsigned char *init_seq = "\033[?1000h\033[?47h\0337";unsigned char *term_seq = "\033[2J\033[?1000l\033[?47l\0338\b \b";*/unsigned char init_seq[] = "\033)0\0337";unsigned char init_seq_x_mouse[] = "\033[?1000h";unsigned char init_seq_tw_mouse[] = "\033[?9h";unsigned char term_seq[] = "\033[2J\0338\r \b";unsigned char term_seq_x_mouse[] = "\033[?1000l\015 \015";unsigned char term_seq_tw_mouse[] = "\033[?9l";/*unsigned char *term_seq = "\033[2J\033[?1000l\0338\b \b";*/void send_init_sequence(int h, int flags){ want_draw(); hard_write(h, init_seq, strlen(init_seq)); if (flags & USE_TWIN_MOUSE) { hard_write(h, init_seq_tw_mouse, strlen(init_seq_tw_mouse)); } else { hard_write(h, init_seq_x_mouse, strlen(init_seq_x_mouse)); } done_draw();}void send_term_sequence(int h,int flags){ want_draw(); hard_write(h, term_seq, strlen(term_seq)); if (flags & USE_TWIN_MOUSE) { hard_write(h, term_seq_tw_mouse, strlen(term_seq_tw_mouse)); } else { hard_write(h, term_seq_x_mouse, strlen(term_seq_x_mouse)); } done_draw();}void resize_terminal(){ struct event ev = { EV_RESIZE, 0, 0, 0 }; int x, y; if (get_terminal_size(ditrm->std_out, &x, &y)) return; ev.x = x; ev.y = y; queue_event(ditrm, (char *)&ev, sizeof(struct event));}int ttcgetattr(int fd, struct termios *t){ int r;#ifdef SIGTTOU interruptible_signal(SIGTTOU, 1);#endif#ifdef SIGTTIN interruptible_signal(SIGTTIN, 1);#endif r = tcgetattr(fd, t);#ifdef SIGTTOU interruptible_signal(SIGTTOU, 0);#endif#ifdef SIGTTIN interruptible_signal(SIGTTIN, 0);#endif return r;}int ttcsetattr(int fd, int a, struct termios *t){ int r;#ifdef SIGTTOU interruptible_signal(SIGTTOU, 1);#endif#ifdef SIGTTIN interruptible_signal(SIGTTIN, 1);#endif r = tcsetattr(fd, a, t);#ifdef SIGTTOU interruptible_signal(SIGTTOU, 0);#endif#ifdef SIGTTIN interruptible_signal(SIGTTIN, 0);#endif return r;}int setraw(int fd, struct termios *p){ struct termios t; memset(&t, 0, sizeof(struct termios)); if (ttcgetattr(fd, &t)) return -1; if (p) memcpy(p, &t, sizeof(struct termios)); os_cfmakeraw(&t); t.c_lflag |= ISIG;#ifdef TOSTOP t.c_lflag |= TOSTOP;#endif t.c_oflag |= OPOST; if (ttcsetattr(fd, TCSANOW, &t)) return -1; return 0;}void handle_trm(int std_in, int std_out, int sock_in, int sock_out, int ctl_in, void *init_string, int init_len){ int x, y; struct itrm *itrm; struct event ev = { EV_INIT, 80, 24, 0 }; unsigned char *ts; int xwin; if (get_terminal_size(ctl_in, &x, &y)) { error("ERROR: could not get terminal size"); return; } itrm = mem_alloc(sizeof(struct itrm)); ditrm = itrm; itrm->std_in = std_in; itrm->std_out = std_out; itrm->sock_in = sock_in; itrm->sock_out = sock_out; itrm->ctl_in = ctl_in; itrm->blocked = 0; itrm->qlen = 0; itrm->tm = -1; itrm->ev_queue = DUMMY; itrm->eqlen = 0; if (ctl_in >= 0) setraw(ctl_in, &itrm->t); set_handlers(std_in, (void (*)(void *))in_kbd, NULL, (void (*)(void *))free_trm, itrm); if (sock_in != std_out) set_handlers(sock_in, (void (*)(void *))in_sock, NULL, (void (*)(void *))free_trm, itrm); ev.x = x; ev.y = y; handle_terminal_resize(ctl_in, resize_terminal); queue_event(itrm, (char *)&ev, sizeof(struct event)); xwin = is_xterm() * ENV_XWIN + can_twterm() * ENV_TWIN + (!!getenv("STY")) * ENV_SCREEN + get_system_env(); itrm->flags = 0; if (!(ts = getenv("TERM"))) ts = ""; if ((xwin & ENV_TWIN) && !strcmp(ts,"linux")) itrm->flags |= USE_TWIN_MOUSE; if (strlen(ts) >= MAX_TERM_LEN) queue_event(itrm, ts, MAX_TERM_LEN); else { unsigned char *mm; int ll = MAX_TERM_LEN - strlen(ts); queue_event(itrm, ts, strlen(ts)); mm = mem_alloc(ll); memset(mm, 0, ll); queue_event(itrm, mm, ll); mem_free(mm); } if (!(ts = get_cwd())) ts = stracpy(""); if (strlen(ts) >= MAX_CWD_LEN) queue_event(itrm, ts, MAX_CWD_LEN); else { unsigned char *mm; int ll = MAX_CWD_LEN - strlen(ts); queue_event(itrm, ts, strlen(ts)); mm = mem_alloc(ll); memset(mm, 0, ll); queue_event(itrm, mm, ll); mem_free(mm); } mem_free(ts); queue_event(itrm, (char *)&xwin, sizeof(int)); queue_event(itrm, (char *)&init_len, sizeof(int)); queue_event(itrm, (char *)init_string, init_len); itrm->mouse_h = handle_mouse(0, (void (*)(void *, unsigned char *, int))mouse_queue_event, itrm); itrm->orig_title = get_window_title(); set_window_title("Links"); send_init_sequence(std_out,itrm->flags);}void unblock_itrm_x(void *h){ close_handle(h); if (!ditrm) return; unblock_itrm(0);}int unblock_itrm(int fd){ struct itrm *itrm = ditrm; if (!itrm) return -1; if (itrm->ctl_in >= 0 && setraw(itrm->ctl_in, NULL)) return -1; if (itrm->blocked != fd + 1) return -2; itrm->blocked = 0; send_init_sequence(itrm->std_out,itrm->flags); set_handlers(itrm->std_in, (void (*)(void *))in_kbd, NULL, (void (*)(void *))free_trm, itrm); handle_terminal_resize(itrm->ctl_in, resize_terminal); unblock_stdin(); resize_terminal(); return 0;}void block_itrm(int fd){ struct itrm *itrm = ditrm; if (!itrm) return; if (itrm->blocked) return; itrm->blocked = fd + 1; block_stdin(); unhandle_terminal_resize(itrm->ctl_in); send_term_sequence(itrm->std_out,itrm->flags); ttcsetattr(itrm->ctl_in, TCSANOW, &itrm->t); set_handlers(itrm->std_in, NULL, NULL, (void (*)(void *))free_trm, itrm);}void free_trm(struct itrm *itrm){ if (!itrm) return; set_window_title(itrm->orig_title); if (itrm->orig_title) mem_free(itrm->orig_title), itrm->orig_title = NULL; unhandle_terminal_resize(itrm->ctl_in); send_term_sequence(itrm->std_out,itrm->flags); ttcsetattr(itrm->ctl_in, TCSANOW, &itrm->t); if (itrm->mouse_h) unhandle_mouse(itrm->mouse_h); set_handlers(itrm->std_in, NULL, NULL, NULL, NULL); set_handlers(itrm->sock_in, NULL, NULL, NULL, NULL); set_handlers(itrm->std_out, NULL, NULL, NULL, NULL); set_handlers(itrm->sock_out, NULL, NULL, NULL, NULL); if (itrm->tm != -1) kill_timer(itrm->tm); mem_free(itrm->ev_queue); mem_free(itrm); if (itrm == ditrm) ditrm = NULL;}void fatal_tty_exit(void){ if (ditrm) ttcsetattr(ditrm->ctl_in, TCSANOW, &ditrm->t);}void resize_terminal_x(unsigned char *text){ int x, y; unsigned char *p; if (!(p = strchr(text, ','))) return; *p++ = 0; x = atoi(text); y = atoi(p); resize_window(x, y); resize_terminal();}void dispatch_special(unsigned char *text){ switch (text[0]) { case TERM_FN_TITLE: set_window_title(text + 1); break; case TERM_FN_RESIZE: resize_terminal_x(text + 1); break; }}unsigned char buf[OUT_BUF_SIZE];/*#define RD ({ char cc; if (p < c) cc = buf[p++]; else if ((dl = hard_read(itrm->sock_in, &cc, 1)) <= 0) {debug("%d %d", dl, errno);goto fr;} cc; })*//*udefine RD ({ char cc; if (p < c) cc = buf[p++]; else if ((hard_read(itrm->sock_in, &cc, 1)) <= 0) goto fr; cc; })*/#define RD(xx) { unsigned char cc; if (p < c) cc = buf[p++]; else if ((hard_read(itrm->sock_in, &cc, 1)) <= 0) goto fr; xx = cc; }void in_sock(struct itrm *itrm){ unsigned char *path, *delete; int pl, dl; char ch; int fg; int c, i, p; if ((c = read(itrm->sock_in, buf, OUT_BUF_SIZE)) <= 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -