diff options
author | piaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2009-10-28 00:28:10 +0800 |
---|---|---|
committer | piaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2009-10-28 00:28:10 +0800 |
commit | ac092d512c7e74a06eb70786f6c21c4734f9167d (patch) | |
tree | 69f467ba5953a0206e29fe28b63f8d38a907fd96 | |
parent | eb258a623def2ee130dc3fbfb71f0f3419a3eee7 (diff) | |
download | pttbbs-ac092d512c7e74a06eb70786f6c21c4734f9167d.tar pttbbs-ac092d512c7e74a06eb70786f6c21c4734f9167d.tar.gz pttbbs-ac092d512c7e74a06eb70786f6c21c4734f9167d.tar.bz2 pttbbs-ac092d512c7e74a06eb70786f6c21c4734f9167d.tar.lz pttbbs-ac092d512c7e74a06eb70786f6c21c4734f9167d.tar.xz pttbbs-ac092d512c7e74a06eb70786f6c21c4734f9167d.tar.zst pttbbs-ac092d512c7e74a06eb70786f6c21c4734f9167d.zip |
* change add_io(0,0) to vkey_detach()
* add_io(fd, n) [vkey_attach(fd)] requires more work (changing related vkey() calls) so it is not changed in this commit
* removed some debug helper API that we won't use in the future
git-svn-id: http://opensvn.csie.org/pttbbs/trunk@5002 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
-rw-r--r-- | pttbbs/include/proto.h | 9 | ||||
-rw-r--r-- | pttbbs/mbbsd/ccw.c | 12 | ||||
-rw-r--r-- | pttbbs/mbbsd/ch_dark.c | 4 | ||||
-rw-r--r-- | pttbbs/mbbsd/chess.c | 2 | ||||
-rw-r--r-- | pttbbs/mbbsd/chicken.c | 4 | ||||
-rw-r--r-- | pttbbs/mbbsd/io.c | 467 | ||||
-rw-r--r-- | pttbbs/mbbsd/menu.c | 4 | ||||
-rw-r--r-- | pttbbs/mbbsd/talk.c | 12 |
8 files changed, 247 insertions, 267 deletions
diff --git a/pttbbs/include/proto.h b/pttbbs/include/proto.h index 7a25c77b..0c20ff4e 100644 --- a/pttbbs/include/proto.h +++ b/pttbbs/include/proto.h @@ -277,18 +277,21 @@ void output(const char *s, int len); void oflush(void); // input api (old flavor) -int igetch(void); int num_in_buf(void); -int input_isfull(); int wait_input(float f, int bIgnoreBuf); int peek_input(float f, int c); -void drop_input(void); +// int igetch(void); +// int input_isfull(); +// void drop_input(void); void add_io(int fd, int timeout); // new input api int vkey(); // identical to igetch void vkey_flush(); // identical to drop_input int vkey_is_full(); // identical to input_isfull +int vkey_detach(void); // works like to add_io(0, 0) +// int vkey_attach(int fd); // works like add_io(fd, ...) +// int vkey_is_ready(); // works like (num_in_buf() > 0) /* kaede */ char*Ptt_prints(char *str, size_t size, int mode); diff --git a/pttbbs/mbbsd/ccw.c b/pttbbs/mbbsd/ccw.c index 5f7c4993..86f6cb0b 100644 --- a/pttbbs/mbbsd/ccw.c +++ b/pttbbs/mbbsd/ccw.c @@ -355,7 +355,7 @@ ccw_vgetcb_peek(int key, VGET_RUNTIME *prt GCC_UNUSED, void *instance) if (ctx->log && ctx->log_fpath) { VREFSCR scr = vscr_save(); - add_io(0, 0); + vkey_detach(); fflush(ctx->log); more(ctx->log_fpath, YEA); @@ -368,7 +368,7 @@ ccw_vgetcb_peek(int key, VGET_RUNTIME *prt GCC_UNUSED, void *instance) case Ctrl('C'): { VREFSCR scr = vscr_save(); - add_io(0, 0); + vkey_detach(); if (vans("確定要離開嗎? [y/N]: ") == 'y') ctx->abort = YEA; @@ -695,7 +695,7 @@ ccw_talk(int fd, int destuid) ccw_process(&ctx); // clean network resource - add_io(0, 0); + vkey_detach(); assert(fd == ctx.fd); close(fd); @@ -801,7 +801,7 @@ ccw_chat_footer(CCW_CTX *ctx) { // process ZA VREFSCR scr = vscr_save(); - add_io(0, 0); + vkey_detach(); ZA_Enter(); @@ -1143,7 +1143,7 @@ ccw_chat_peek_key(CCW_CTX *ctx, int key) { int za = 0; VREFCUR cur = vcur_save(); - add_io(0, 0); + vkey_detach(); za = ZA_Select(); ccw_footer(ctx); add_io(ctx->fd, 0); @@ -1241,7 +1241,7 @@ ccw_chat(int fd) ccw_process(&ctx); // clean network resource - add_io(0, 0); + vkey_detach(); close(fd); currutmp->in_chat = currutmp->chatid[0] = 0; diff --git a/pttbbs/mbbsd/ch_dark.c b/pttbbs/mbbsd/ch_dark.c index 2a85b51d..e6a16f6d 100644 --- a/pttbbs/mbbsd/ch_dark.c +++ b/pttbbs/mbbsd/ch_dark.c @@ -552,12 +552,12 @@ main_dark(int fd, userinfo_t * uin) mvouts(22, 0, ANSI_COLOR(1;31) "合棋唷!! 下次在分高下吧 ^_^" ANSI_RESET); break; default: - add_io(0, 0); + vkey_detach(); close(fd); pressanykey(); return 0; } - add_io(0, 0); + vkey_detach(); close(fd); pressanykey(); return 0; diff --git a/pttbbs/mbbsd/chess.c b/pttbbs/mbbsd/chess.c index 4ea194f0..6fa18627 100644 --- a/pttbbs/mbbsd/chess.c +++ b/pttbbs/mbbsd/chess.c @@ -24,7 +24,7 @@ #define CHESS_DRAWING_PHOTOED_WARN_ROW 22 #define CONNECT_PEER() add_io(info->sock, 0) -#define IGNORE_PEER() add_io(0, 0) +#define IGNORE_PEER() vkey_detach() #define DO_WITHOUT_PEER(TIMEOUT,ACT,ELSE) \ do { \ diff --git a/pttbbs/mbbsd/chicken.c b/pttbbs/mbbsd/chicken.c index 0e7eaf35..5699632e 100644 --- a/pttbbs/mbbsd/chicken.c +++ b/pttbbs/mbbsd/chicken.c @@ -1022,7 +1022,7 @@ chickenpk(int fd) free_live_chicken(ochicken); bell(); vmsg("有一方沒有寵物"); /* Ptt:妨止page時把寵物賣掉 */ - add_io(0, 0); + vkey_detach(); close(fd); unlockutmpmode(); return 0; @@ -1132,7 +1132,7 @@ chickenpk(int fd) break; } } - add_io(0, 0); /* 把vkey恢復回 */ + vkey_detach(); /* 把vkey恢復回 */ pressanykey(); close(fd); showdeadth(deadtype(mychicken, mychicken)); diff --git a/pttbbs/mbbsd/io.c b/pttbbs/mbbsd/io.c index a71a381f..f21afe7c 100644 --- a/pttbbs/mbbsd/io.c +++ b/pttbbs/mbbsd/io.c @@ -11,10 +11,11 @@ #ifdef DEBUG #define register +// #define DBG_OUTRPT #endif -static unsigned char real_outbuf[OBUFSIZE + CVTGAP*2] = " ", - real_inbuf [IBUFSIZE + CVTGAP*2] = " "; +static unsigned char real_outbuf[OBUFSIZE + CVTGAP*2] = " "; +static unsigned char real_inbuf [IBUFSIZE + CVTGAP*2] = " "; // we've seen such pattern - make it accessible for movie mode. #define CLIENT_ANTI_IDLE_STR ESC_STR "OA" ESC_STR "OB" @@ -25,8 +26,9 @@ static unsigned char real_outbuf[OBUFSIZE + CVTGAP*2] = " ", #define inbuf (real_inbuf +CVTGAP) #define outbuf (real_outbuf+CVTGAP) -static int obufsize = 0, ibufsize = 0; -static int icurrchar = 0; +static int obufsize = 0; +static int ibufsize = 0; +static int icurrchar = 0; #ifdef DBG_OUTRPT // output counter @@ -72,6 +74,46 @@ inline static int write_wrapper(int fd, void *buf, size_t count) { #endif /* ----------------------------------------------------- */ +/* debug reporting */ +/* ----------------------------------------------------- */ + +#if defined(DEBUG) || defined(DBG_OUTRPT) +void +debug_print_input_buffer(char *s, size_t len) +{ + int y, x, i; + if (!s || !len) + return; + + getyx_ansi(&y, &x); + move(b_lines, 0); clrtoeol(); + SOLVE_ANSI_CACHE(); + prints("Input Buffer (%d): [ ", (int)len); + for (i = 0; i < len; i++, s++) + { + int c = (unsigned char)*s; + if (!isascii(c) || !isprint(c) || c == ' ') + { + if (c == ESC_CHR) + outs(ANSI_COLOR(1;36) "Esc" ANSI_RESET); + else if (c == ' ') + outs(ANSI_COLOR(1;36) "Sp " ANSI_RESET); + else if (c == 0) + prints(ANSI_COLOR(1;31) "Nul" ANSI_RESET); + else if (c > 0 && c < ' ') + prints(ANSI_COLOR(1;32) "^%c", c + 'A' -1); + else + prints(ANSI_COLOR(1;33) "[%02X]" ANSI_RESET, c); + } else { + outc(c); + } + } + prints(" ] "); + move_ansi(y, x); +} +#endif + +/* ----------------------------------------------------- */ /* output routines */ /* ----------------------------------------------------- */ void @@ -153,247 +195,14 @@ ochar(int c) } /* ----------------------------------------------------- */ -/* input routines */ +/* pager processor */ /* ----------------------------------------------------- */ -static int i_newfd = 0; -static struct timeval i_to, *i_top = NULL; -static int (*flushf) () = NULL; - -inline void -add_io(int fd, int timeout) -{ - i_newfd = fd; - if (timeout) { - i_to.tv_sec = timeout; - i_to.tv_usec = 16384; /* Ptt: 改成16384 避免不按時for loop吃cpu - * time 16384 約每秒64次 */ - i_top = &i_to; - } else - i_top = NULL; -} - -inline int -num_in_buf(void) -{ - if (ibufsize <= icurrchar) - return 0; - return ibufsize - icurrchar; -} - -inline int -vkey_is_full(void) -{ - return ibufsize >= IBUFSIZE; -} - -inline static ssize_t -wrapped_tty_read(unsigned char *buf, size_t max) -{ - /* tty_read will handle abort_bbs. - * len <= 0: read more */ - ssize_t len = tty_read(buf, max); - if (len <= 0) - return len; - - // apply additional converts -#ifdef DBCSAWARE - if (ISDBCSAWARE() && HasUserFlag(UF_DBCS_DROP_REPEAT)) - len = vtkbd_ignore_dbcs_evil_repeats(buf, len); -#endif -#ifdef CONVERT - len = input_wrapper(inbuf, len); -#endif -#ifdef DBG_OUTRPT - { - static char xbuf[128]; - sprintf(xbuf, ESC_STR "[s" ESC_STR "[2;1H [%ld] " - ESC_STR "[u", len); - write(1, xbuf, strlen(xbuf)); - } -#endif // DBG_OUTRPT - return len; -} - - -/* - * dogetch() is not reentrant-safe. SIGUSR[12] might happen at any time, and - * dogetch() might be called again, and then ibufsize/icurrchar/inbuf might - * be inconsistent. We try to not segfault here... - */ - -static int -dogetch(void) -{ - ssize_t len; - static time4_t lastact; - if (ibufsize <= icurrchar) { - - if (flushf) - (*flushf) (); - - refresh(); - - if (i_newfd) { - - struct timeval timeout; - fd_set readfds; - - if (i_top) - timeout = *i_top; /* copy it because select() might - * change it */ - - FD_ZERO(&readfds); - FD_SET(0, &readfds); - FD_SET(i_newfd, &readfds); - - /* jochang: modify first argument of select from FD_SETSIZE */ - /* since we are only waiting input from fd 0 and i_newfd(>0) */ - - STATINC(STAT_SYSSELECT); - while ((len = select(i_newfd + 1, &readfds, NULL, NULL, - i_top ? &timeout : NULL)) < 0) { - if (errno != EINTR) - abort_bbs(0); - /* raise(SIGHUP); */ - } - - if (len == 0){ - syncnow(); - return I_TIMEOUT; - } - - if (i_newfd && FD_ISSET(i_newfd, &readfds)){ - syncnow(); - return I_OTHERDATA; - } - } - -#ifdef NOKILLWATERBALL - if( currutmp && currutmp->msgcount && !reentrant_write_request ) - write_request(1); -#endif - - STATINC(STAT_SYSREADSOCKET); - - do { - len = wrapped_tty_read(inbuf, IBUFSIZE); - } while (len <= 0); - - ibufsize = len; - icurrchar = 0; - } - - if (currutmp) { - syncnow(); - /* 3 秒內超過兩 byte 才算 active, anti-antiidle. - * 不過方向鍵等組合鍵不止 1 byte */ - if (now - lastact < 3) - currutmp->lastact = now; - lastact = now; - } - - // see vtkbd.c for CR/LF Rules - { - unsigned char c = (unsigned char) inbuf[icurrchar++]; - - // CR LF are treated as one. - if (c == KEY_CR) - { - // peak next character. - if (icurrchar < ibufsize && inbuf[icurrchar] == KEY_LF) - icurrchar ++; - return KEY_ENTER; - } - else if (c == KEY_LF) - { - return KEY_UNKNOWN; - } - - return c; - } -} - -#ifdef DEBUG -/* - * These are for terminal keys debug - */ -void -_debug_print_ibuffer() -{ - static int y = 0; - int i = 0; - - move(y % b_lines, 0); - for (i = 0; i < t_columns; i++) - outc(' '); - move(y % b_lines, 0); - prints("%d. Current Buffer: %d/%d, ", y+1, icurrchar, ibufsize); - outs(ANSI_COLOR(1) "[" ANSI_RESET); - for (i = 0; i < ibufsize; i++) - { - int c = (unsigned char)inbuf[i]; - if(c < ' ') - { - prints(ANSI_COLOR(1;33) "0x%02x" ANSI_RESET, c); - } else { - outc(c); - } - } - outs(ANSI_COLOR(1) "]" ANSI_RESET); - y++; - move(y % b_lines, 0); - for (i = 0; i < t_columns; i++) - outc(' '); -} - +static int i_newfd; int -_debug_check_keyinput() -{ - int dbcsaware = 0; - int flExit = 0; - - clear(); - while(!flExit) - { - int i = 0; - move(b_lines, 0); - for(i=0; i<t_columns; i++) - outc(' '); - move(b_lines, 0); - if(dbcsaware) - { - outs( ANSI_REVERSE "游標在此" ANSI_RESET - " 測試中文模式會不會亂送鍵。 'q' 離開, 'd' 回英文模式 "); - move(b_lines, 4); - } else { - outs("Waiting for key input. 'q' to exit, 'd' to try dbcs-aware"); - } - refresh(); - wait_input(-1, 0); - switch(dogetch()) - { - case 'd': - dbcsaware = !dbcsaware; - break; - case 'q': - flExit = 1; - break; - } - _debug_print_ibuffer(); - while(num_in_buf() > 0) - dogetch(); - } - return 0; -} - -#endif - -static int water_which_flag = 0; - -static int process_pager_keys(int ch) { + static int water_which_flag; assert(currutmp); switch (ch) { @@ -563,6 +372,170 @@ process_pager_keys(int ch) return ch; } +/* ----------------------------------------------------- */ +/* input routines */ +/* ----------------------------------------------------- */ + +static int i_newfd = 0; +static struct timeval i_to, *i_top = NULL; + +inline void +add_io(int fd, int timeout) +{ + i_newfd = fd; + if (timeout) { + i_to.tv_sec = timeout; + i_to.tv_usec = 16384; /* Ptt: 改成16384 避免不按時for loop吃cpu + * time 16384 約每秒64次 */ + i_top = &i_to; + } else + i_top = NULL; +} + +inline int +num_in_buf(void) +{ + if (ibufsize <= icurrchar) + return 0; + return ibufsize - icurrchar; +} + +inline int +vkey_is_full(void) +{ + return ibufsize >= IBUFSIZE; +} + +inline static ssize_t +wrapped_tty_read(unsigned char *buf, size_t max) +{ + /* tty_read will handle abort_bbs. + * len <= 0: read more */ + ssize_t len = tty_read(buf, max); + if (len <= 0) + return len; + + // apply additional converts +#ifdef DBCSAWARE + if (ISDBCSAWARE() && HasUserFlag(UF_DBCS_DROP_REPEAT)) + len = vtkbd_ignore_dbcs_evil_repeats(buf, len); +#endif +#ifdef CONVERT + len = input_wrapper(inbuf, len); +#endif +#ifdef DBG_OUTRPT + +#if 1 + if (len > 0) + debug_print_input_buffer((char*)inbuf, len); +#else + { + static char xbuf[128]; + sprintf(xbuf, ESC_STR "[s" ESC_STR "[2;1H [%ld] " + ESC_STR "[u", len); + write(1, xbuf, strlen(xbuf)); + } +#endif + +#endif // DBG_OUTRPT + return len; +} + +/* + * dogetch() is not reentrant-safe. SIGUSR[12] might happen at any time, and + * dogetch() might be called again, and then ibufsize/icurrchar/inbuf might + * be inconsistent. We try to not segfault here... + */ + +static int +dogetch(void) +{ + ssize_t len; + static time4_t lastact; + if (ibufsize <= icurrchar) { + + refresh(); + + if (i_newfd) { + + struct timeval timeout; + fd_set readfds; + + if (i_top) + timeout = *i_top; /* copy it because select() might + * change it */ + + FD_ZERO(&readfds); + FD_SET(0, &readfds); + FD_SET(i_newfd, &readfds); + + /* jochang: modify first argument of select from FD_SETSIZE */ + /* since we are only waiting input from fd 0 and i_newfd(>0) */ + + STATINC(STAT_SYSSELECT); + while ((len = select(i_newfd + 1, &readfds, NULL, NULL, + i_top ? &timeout : NULL)) < 0) { + if (errno != EINTR) + abort_bbs(0); + /* raise(SIGHUP); */ + } + + if (len == 0){ + syncnow(); + return I_TIMEOUT; + } + + if (i_newfd && FD_ISSET(i_newfd, &readfds)){ + syncnow(); + return I_OTHERDATA; + } + } + +#ifdef NOKILLWATERBALL + if( currutmp && currutmp->msgcount && !reentrant_write_request ) + write_request(1); +#endif + + STATINC(STAT_SYSREADSOCKET); + + do { + len = wrapped_tty_read(inbuf, IBUFSIZE); + } while (len <= 0); + + ibufsize = len; + icurrchar = 0; + } + + if (currutmp) { + syncnow(); + /* 3 秒內超過兩 byte 才算 active, anti-antiidle. + * 不過方向鍵等組合鍵不止 1 byte */ + if (now - lastact < 3) + currutmp->lastact = now; + lastact = now; + } + + // see vtkbd.c for CR/LF Rules + { + unsigned char c = (unsigned char) inbuf[icurrchar++]; + + // CR LF are treated as one. + if (c == KEY_CR) + { + // peak next character. + if (icurrchar < ibufsize && inbuf[icurrchar] == KEY_LF) + icurrchar ++; + return KEY_ENTER; + } + else if (c == KEY_LF) + { + return KEY_UNKNOWN; + } + + return c; + } +} + // virtual terminal keyboard context static VtkbdCtx vtkbd_ctx; @@ -627,7 +600,7 @@ vkey(void) * if f < 0, then wait forever. * Return 1 if anything available. */ -int +inline int wait_input(float f, int bIgnoreBuf) { int sel = 0; @@ -664,17 +637,25 @@ wait_input(float f, int bIgnoreBuf) return 1; } -void +inline void vkey_flush(void) { icurrchar = ibufsize = 0; } +int +vkey_detach(void) +{ + int r = i_newfd; + add_io(0, 0); + return r; +} + /* * wait user input for f seconds. * return 1 if control key c is available. */ -int +inline int peek_input(float f, int c) { int i = 0; diff --git a/pttbbs/mbbsd/menu.c b/pttbbs/mbbsd/menu.c index 352dcdba..226c6f0c 100644 --- a/pttbbs/mbbsd/menu.c +++ b/pttbbs/mbbsd/menu.c @@ -713,7 +713,6 @@ x_sys_updates(void) #endif #ifdef DEBUG -int _debug_check_keyinput(); int _debug_reportstruct() { clear(); @@ -784,9 +783,6 @@ static const commands_t xyzlist[] = { #endif #else // !DEBUG - - {_debug_check_keyinput, 0, - "MMKeycode 檢查按鍵控制碼工具"}, {_debug_reportstruct, 0, "RReportStruct 報告各種結構的大小"}, #endif // !DEBUG diff --git a/pttbbs/mbbsd/talk.c b/pttbbs/mbbsd/talk.c index 708c56ea..21f7fbea 100644 --- a/pttbbs/mbbsd/talk.c +++ b/pttbbs/mbbsd/talk.c @@ -1183,7 +1183,7 @@ int make_connection_to_somebody(userinfo_t *uin, int timeout){ ch == M_FIVE || ch == CHC || (!ch && (uin->chatid[0] == 1 || uin->chatid[0] == 3))) { - add_io(0, 0); + vkey_detach(); close(sock); currutmp->sockactive = currutmp->destuid = 0; vmsg("人家在忙啦"); @@ -1200,7 +1200,7 @@ int make_connection_to_somebody(userinfo_t *uin, int timeout){ if (pid <= 0 || kill(pid, SIGUSR1) == -1) { close(sock); currutmp->sockactive = currutmp->destuid = 0; - add_io(0, 0); + vkey_detach(); vmsg(msg_usr_left); unlockutmpmode(); return -1; @@ -1212,7 +1212,7 @@ int make_connection_to_somebody(userinfo_t *uin, int timeout){ break; if (ch == '\004') { - add_io(0, 0); + vkey_detach(); close(sock); currutmp->sockactive = currutmp->destuid = 0; unlockutmpmode(); @@ -1385,7 +1385,7 @@ my_talk(userinfo_t * uin, int fri_stat, char defact) unlockutmpmode(); return; } - add_io(0, 0); + vkey_detach(); close(sock); currutmp->sockactive = NA; @@ -1396,7 +1396,7 @@ my_talk(userinfo_t * uin, int fri_stat, char defact) add_io(msgsock, 0); while ((ch = vkey()) != I_OTHERDATA) { if (ch == Ctrl('D')) { - add_io(0, 0); + vkey_detach(); close(msgsock); unlockutmpmode(); return; @@ -1405,7 +1405,7 @@ my_talk(userinfo_t * uin, int fri_stat, char defact) if (read(msgsock, &c, sizeof(c)) != sizeof(c)) c = 'n'; - add_io(0, 0); + vkey_detach(); if (c == 'y') { switch (uin->sig) { |