diff options
author | piaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2009-09-29 01:59:20 +0800 |
---|---|---|
committer | piaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2009-09-29 01:59:20 +0800 |
commit | c78d877d45496115e90c3584b063fd2bc72303b9 (patch) | |
tree | 2e855c83f3d3e4b3637644d0a60a2431e071b17e /mbbsd | |
parent | c0dd6835cc9f376ad6f195bad2daacff12b5efd9 (diff) | |
download | pttbbs-c78d877d45496115e90c3584b063fd2bc72303b9.tar pttbbs-c78d877d45496115e90c3584b063fd2bc72303b9.tar.gz pttbbs-c78d877d45496115e90c3584b063fd2bc72303b9.tar.bz2 pttbbs-c78d877d45496115e90c3584b063fd2bc72303b9.tar.lz pttbbs-c78d877d45496115e90c3584b063fd2bc72303b9.tar.xz pttbbs-c78d877d45496115e90c3584b063fd2bc72303b9.tar.zst pttbbs-c78d877d45496115e90c3584b063fd2bc72303b9.zip |
* refine kbd stack and move to common/bbs
* rename visio to vtuikit
git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@4888 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd')
-rw-r--r-- | mbbsd/Makefile | 4 | ||||
-rw-r--r-- | mbbsd/io.c | 61 | ||||
-rw-r--r-- | mbbsd/telnet.c | 71 | ||||
-rw-r--r-- | mbbsd/vtkbd.c | 279 | ||||
-rw-r--r-- | mbbsd/vtuikit.c (renamed from mbbsd/visio.c) | 14 |
5 files changed, 43 insertions, 386 deletions
diff --git a/mbbsd/Makefile b/mbbsd/Makefile index 98335987..fbaeb72c 100644 --- a/mbbsd/Makefile +++ b/mbbsd/Makefile @@ -10,14 +10,14 @@ SRCROOT= .. PROG= mbbsd COREOBJS = bbs.o announce.o read.o board.o cache.o cal.o brc.o mail.o record.o fav.o ACCOBJS = user.o register.o passwd.o emaildb.o -NETOBJS = mbbsd.o io.o term.o telnet.o vtkbd.o +NETOBJS = mbbsd.o io.o term.o telnet.o TALKOBJS = talk.o chat.o friend.o UTILOBJS = stuff.o kaede.o convert.o name.o syspost.o PAGEROBJS= more.o pmore.o PLUGOBJS = calendar.o ordersong.o gamble.o vice.o angel.o CHESSOBJS= chess.o chc.o chc_tab.o ch_go.o ch_gomo.o ch_dark.o ch_reversi.o GAMEOBJS = card.o chicken.o -OBJS:= admin.o assess.o edit.o menu.o xyz.o var.o visio.o \ +OBJS:= admin.o assess.o edit.o menu.o xyz.o var.o vtuikit.o \ vote.o voteboard.o \ $(COREOBJS) $(ACCOBJS) $(NETOBJS) $(TALKOBJS) $(UTILOBJS) \ $(PAGEROBJS) $(PLUGOBJS) \ @@ -158,7 +158,7 @@ static int i_newfd = 0; static struct timeval i_to, *i_top = NULL; static int (*flushf) () = NULL; -void +inline void add_io(int fd, int timeout) { i_newfd = fd; @@ -171,7 +171,7 @@ add_io(int fd, int timeout) i_top = NULL; } -int +inline int num_in_buf(void) { if (ibufsize <= icurrchar) @@ -179,12 +179,42 @@ num_in_buf(void) return ibufsize - icurrchar; } -int +inline int input_isfull(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)); + fsync(1); + } +#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 @@ -246,24 +276,7 @@ dogetch(void) STATINC(STAT_SYSREADSOCKET); do { - len = tty_read(inbuf, IBUFSIZE); - /* tty_read will handle abort_bbs. - * len <= 0: read more */ -#ifdef CONVERT - if(len > 0) - len = input_wrapper(inbuf, len); -#endif -#ifdef DBG_OUTRPT - // if (0) - { - static char xbuf[128]; - sprintf(xbuf, ESC_STR "[s" ESC_STR "[2;1H [%ld] " - ESC_STR "[u", len); - write(1, xbuf, strlen(xbuf)); - fsync(1); - } -#endif // DBG_OUTRPT - + len = wrapped_tty_read(inbuf, IBUFSIZE); } while (len <= 0); ibufsize = len; @@ -677,11 +690,7 @@ peek_input(float f, int c) if (wait_input(f, 1) && (IBUFSIZE > ibufsize)) { - int len = tty_read(inbuf + ibufsize, IBUFSIZE - ibufsize); -#ifdef CONVERT - if(len > 0) - len = input_wrapper(inbuf+ibufsize, len); -#endif + int len = wrapped_tty_read(inbuf + ibufsize, IBUFSIZE - ibufsize); if (len > 0) ibufsize += len; } diff --git a/mbbsd/telnet.c b/mbbsd/telnet.c index 4e7daf53..7cf1fee5 100644 --- a/mbbsd/telnet.c +++ b/mbbsd/telnet.c @@ -43,72 +43,6 @@ telnet_init(int do_init_cmd) telnet_ctx_send_init_cmds(ctx); } -#if defined(DBCSAWARE) -ssize_t -dbcs_detect_evil_repeats(unsigned char *buf, ssize_t l) -{ - // determine DBCS repeats by evil clients (ref: io.c) - if (l == 2) - { - // XXX l=2 is dangerous. hope we are not in telnet IAC state... - // BS: \b - // BS2: \x7f - // DEL2: Ctrl('D') (KKMan3 also treats Ctrl('D') as DBCS DEL) - if (buf[0] != buf[1]) - return l; - - // Note: BS/DEL behavior on different clients: - // screen/telnet:BS=0x7F, DEL=^[3~ - // PCMan2004: BS=0x7F, DEL=^[3~ - // KKMan3: BS=0x1b, DEL=0x7F - // WinXP telnet: BS=0x1b, DEL=0x7F - if (buf[0] == '\b' || - buf[0] == '\x7f' || - buf[0] == Ctrl('D')) - return l-1; - } - else if (l == 6) - { - // RIGHT: ESC_CHR "OC" or ESC_CHR "[C" - // LEFT: ESC_CHR "OD" or ESC_CHR "[D" - if (buf[2] != 'C' && buf[2] != 'D') - return l; - - if ( buf[0] == ESC_CHR && - (buf[1] == '[' || buf[1] == 'O') && - buf[0] == buf[3] && - buf[1] == buf[4] && - buf[2] == buf[5]) - return l-3; - } - else if (l == 8) - { - // RIGHT: ESC_CHR "[OC" - // LEFT: ESC_CHR "[OD" - // DEL: ESC_STR "[3~" // vt220 - if (buf[2] != '3' && buf[2] != 'O') - return l; - - if (buf[0] != ESC_CHR || - buf[1] != '[' || - buf[4] != buf[0] || - buf[5] != buf[1] || - buf[6] != buf[2] || - buf[7] != buf[3]) - return l; - - if (buf[2] == '3' && - buf[3] == '~') - return l-4; - - if ( buf[2] == 'O' && - (buf[3] == 'C' || buf[3] == 'D') ) - return l-4; - } - return l; -} -#endif - /* tty_read * read from tty, process telnet commands if raw connection. * return: >0 = length, <=0 means read more, abort/eof is automatically processed. @@ -122,11 +56,6 @@ tty_read(unsigned char *buf, size_t max) if(l == 0 || (l < 0 && !(errno == EINTR || errno == EAGAIN))) abort_bbs(0); -#if defined(DBCSAWARE) - if (ISDBCSAWARE() && HasUserFlag(UF_DBCS_DROP_REPEAT)) - l = dbcs_detect_evil_repeats(buf, l); -#endif - if(!raw_connection || l <= 0) return l; diff --git a/mbbsd/vtkbd.c b/mbbsd/vtkbd.c deleted file mode 100644 index 8a00671f..00000000 --- a/mbbsd/vtkbd.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * vtkbd.c - * Virtual Terminal Keyboard - * - * piaip's new re-implementation of xterm/VT100/220/ANSI key input - * escape sequence parser for BBS - * - * Author: Hung-Te Lin (piaip) - * Create: Wed Sep 23 15:06:43 CST 2009 - * --------------------------------------------------------------------------- - * Copyright (c) 2009 Hung-Te Lin <piaip@csie.org> - * All rights reserved. - * Distributed under BSD license (GPL compatible). - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * --------------------------------------------------------------------------- - * References: - * http://support.dell.com/support/edocs/systems/pe2650/en/ug/5g387ad0.htm - * http://aperiodic.net/phil/archives/Geekery/term-function-keys.html - * http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=/rzaiw/rzaiwvt220opmode.htm - * http://www.rebol.com/docs/core23/rebolcore-18.html - * http://ascii-table.com/ansi-escape-sequences-vt-100.php - * http://web.mit.edu/gnu/doc/html/screen_10.html - * http://vt100.net/docs/vt220-rm/chapter3.html - * http://inwap.com/pdp10/ansicode.txt - * http://www.connectrf.com/Documents/vt220.html - * http://www.ibb.net/~anne/keyboard.html - * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html - * PuTTY Source < terminal.c, term_key() > - * Termcap - * --------------------------------------------------------------------------- - * * BS/DEL Rules - * The BackSpace, Erase(<X]), and Delete keys are special due to history... - * - on vt220, BS=0x7F, Delete=ESC[3~ (screen/xterm/PuTTY) - * - on vt100, BS=0x7F - * - on vt100/xterm, BS=0x08, Delete=0x7F (Windows/VMX/DOS telnet) - * So we define - * KEY_BS = BACKSPACE/ERASE = 0x08, 0x7F - * KEY_DEL = DELETE = ESC[3~ - * - * * CR/LF Rules - * The traditional newline maps to following combination... - * - UNIX, LF - * - Win, CR+LF - * - Mac, CR - * When it comes to terminal,CR LF should be treated as one. - * There were reports that some users getting double ENTERs if we take LF - * as ENTER, so we decided reject LF. We are not sure if there is any - * clients sending LF only, but according the the compatibility test, - * most modern clients send only CR (or CR+LF). - * So we define - * KEY_CR = CR, CR+LF - * KEY_LF = ignored. - * --------------------------------------------------------------------------- - * * The complete list to support: - * - Up/Down/Right/Left: <Esc> [ <A-D> | <Esc> O <A-D> (app) - * - Home/Ins/Del/End/PgUp/PgDn: <Esc> [ <1~6> ~ - * - Shift-TAB: <Esc> [ Z | <Esc> [ 0 Z - * - F1~F4: <Esc> [ 1 <1234> ~ | <Esc> O <PQRS> - * - F5: <Esc> [ 1 <5> ~ - * - F6-F8: <Esc> [ 1 <789> ~ - * - F9-F12: <Esc> [ 2 <0134> ~ - * - Num 0-9 *+,-./=ENTER: <Esc> O <pqrstuvwxyjklmnoXM> - * - * Note: we don't support some rare terms like <Esc> O <TUVWXYZA> described - * in Dell 2650 in order to prevent confusion. - * Num pad is also always converted to digits. - */ - -#include "bbs.h" - -/* VtkbdCtx.state */ -typedef enum { - VKSTATE_NORMAL = 0, - VKSTATE_ESC, // <Esc> - VKSTATE_ESC_APP, // <Esc> O - VKSTATE_ESC_QUOTE, // <Esc> [ - VKSTATE_ZERO, // <Esc> [ 0 (wait Z) - VKSTATE_ONE, // <Esc> [ <1> - VKSTATE_TWO, // <Esc> [ <2> - VKSTATE_TLIDE, // <Esc> [ * (wait ~, return esc_arg) -} VKSTATES; - -/* the processor API */ -int -vtkbd_process(int c, VtkbdCtx *ctx) -{ - switch (ctx->state) - { - case VKSTATE_NORMAL: // original state - if (c == KEY_ESC) - { - ctx->state = VKSTATE_ESC; - return KEY_INCOMPLETE; - } - - // simple mappings - switch (c) { - // BS/ERASE/DEL Rules - case 0x7F: - case 0x08: - return KEY_BS; - } - return c; - - case VKSTATE_ESC: // <Esc> - switch (c) { - case '[': - ctx->state = VKSTATE_ESC_QUOTE; - return KEY_INCOMPLETE; - - case 'O': - ctx->state = VKSTATE_ESC_APP; - return KEY_INCOMPLETE; - - case '0': - ctx->state = VKSTATE_ZERO; - return KEY_INCOMPLETE; - } - - // XXX should we map this into another section of KEY_ESC_* ? - ctx->esc_arg = c; - ctx->state = VKSTATE_NORMAL; - return KEY_ESC; - - case VKSTATE_ZERO: // <Esc> 0 - if (c != 'Z') - break; - - ctx->state = VKSTATE_NORMAL; - return KEY_STAB; - - case VKSTATE_ESC_APP: // <Esc> O - - switch (c) { - case 'A': - case 'B': - case 'C': - case 'D': - ctx->state = VKSTATE_NORMAL; - return KEY_UP + (c - 'A'); - - case 'P': - case 'Q': - case 'R': - case 'S': - ctx->state = VKSTATE_NORMAL; - return KEY_F1 + (c - 'P'); - - // Num pads: always convert to NumLock=ON - case 'p': case 'q': case 'r': case 's': - case 't': case 'u': case 'v': case 'w': - case 'x': case 'y': - ctx->state = VKSTATE_NORMAL; - return '0' + (c - 'p'); - - case 'M': - ctx->state = VKSTATE_NORMAL; - return KEY_ENTER; - - case 'X': - ctx->state = VKSTATE_NORMAL; - return '='; - - case 'j': case 'k': case 'l': case 'm': - case 'n': case 'o': - { - static const char *numx = "*+,-./"; - assert( c >= 'j' && (c-'j') < strlen(numx)); - ctx->state = VKSTATE_NORMAL; - return numx[c-'j']; - } - } - break; - - case VKSTATE_ESC_QUOTE: // <Esc> [ - - switch(c) { - case 'A': - case 'B': - case 'C': - case 'D': - ctx->state = VKSTATE_NORMAL; - return KEY_UP + (c - 'A'); - - case '3': - case '4': - case '5': - case '6': - ctx->state = VKSTATE_TLIDE; - ctx->esc_arg = KEY_DEL + (c - '3'); - return KEY_INCOMPLETE; - - case 'Z': - ctx->state = VKSTATE_NORMAL; - return KEY_STAB; - - case '1': - ctx->state = VKSTATE_ONE; - return KEY_INCOMPLETE; - case '2': - ctx->state = VKSTATE_TWO; - return KEY_INCOMPLETE; - } - break; - - case VKSTATE_ONE: // <Esc> [ 1 - if (c == '~') - { - ctx->state = VKSTATE_NORMAL; - return KEY_HOME; - } - - switch(c) { - case '1': - case '2': - case '3': - case '4': - case '5': - ctx->state = VKSTATE_TLIDE; - ctx->esc_arg = KEY_F1 + c - '1'; // F1 .. F5 - return KEY_INCOMPLETE; - - case '7': - case '8': - case '9': - ctx->state = VKSTATE_TLIDE; - ctx->esc_arg = KEY_F6 + c - '7'; // F6 .. F8 - return KEY_INCOMPLETE; - } - break; - - case VKSTATE_TWO: // <Esc> [ 2 - if (c == '~') - { - ctx->state = VKSTATE_NORMAL; - return KEY_INS; // HOME+1 - } - - switch(c) { - case '0': - case '1': - ctx->state = VKSTATE_TLIDE; - ctx->esc_arg = KEY_F9 + c - '0'; // F9 .. F10 - return KEY_INCOMPLETE; - - case '3': - case '4': - ctx->state = VKSTATE_TLIDE; - ctx->esc_arg = KEY_F11 + c - '3'; // F11 .. F12 - return KEY_INCOMPLETE; - } - break; - - case VKSTATE_TLIDE: // Esc [ <12> <0-9> ~ - if (c != '~') - break; - - ctx->state = VKSTATE_NORMAL; - return ctx->esc_arg; - - default: - assert(!"unknown vkstate"); - break; - } - - // what to do now? - ctx->state = VKSTATE_NORMAL; - return KEY_UNKNOWN; -} - -// vim:sw=4:sw=4:et diff --git a/mbbsd/visio.c b/mbbsd/vtuikit.c index 38efcbc9..9dbcdf55 100644 --- a/mbbsd/visio.c +++ b/mbbsd/vtuikit.c @@ -1,10 +1,10 @@ /* $Id$ */ +#include "vtkbd.h" #include "bbs.h" /* - * visio.c - * piaip's new implementation of visio - * (visio: virtual screen input output, the name from Maple3) + * vtuikit.c (was: visio.c) + * piaip's new implementation of virtual terminal user interface toolkits * * This is not the original visio.c from Maple3. * We just borrowed its file name and few API names/prototypes @@ -14,13 +14,11 @@ * but won't stick to it. * Maybe at the end only 'vmsg' and 'vmsgf' will still be compatible.... * - * m3 visio = (ptt) visio+screen/term. + * m3 visio = (ptt) vtuikit+vtkbd+screen/term. * * Author: Hung-Te Lin (piaip), April 2008. * - * Copyright (c) 2008 Hung-Te Lin <piaip@csie.ntu.edu.tw> - * All rights reserved. - * + * Copyright (c) 2008-2009 Hung-Te Lin <piaip@csie.ntu.edu.tw> * Distributed under BSD license (GPL compatible). * * Redistribution and use in source and binary forms, with or without @@ -36,7 +34,7 @@ * (1) name the API in prefix of 'v'. * (2) use only screen.c APIs. * (3) take care of wide screen and DBCS. - * (4) utilize the colos in visio.h, and name asa VCLR_* (visio color) + * (4) utilize the colos in vtuikit.h, and name asa VCLR_* (vtuikit color) */ // ---- DEFINITION --------------------------------------------------- |