Commit 11d3f59f authored by rswindell's avatar rswindell
Browse files

Initial support for UTF-8 terminals. At this time, just performs charset

translation from CP437 -> UTF-8 and only when using high-level text output
functions - so the output from native/DOS doors and scripts that use low-level
output methods won't be translated.
UTF-8 is auto-detected (only) at this time during answer (before login) by
sending a ZWNBSP and checking (via ANSI) if the cursor position moved - an
idea "borrowed" from Ozz Nixon (aka SqZ).

This commit requires the new "encode" library (src/encode), so you may need
to perform a cvs checkout to get that module!
parent d88d7240
......@@ -105,12 +105,12 @@ else
endif
endif
CFLAGS += $(JS_CFLAGS) $(CRYPT_CFLAGS) $(UIFC-MT_CFLAGS) $(XPDEV-MT_CFLAGS) $(SMBLIB_CFLAGS) $(CIOLIB-MT_CFLAGS)
CFLAGS += $(JS_CFLAGS) $(CRYPT_CFLAGS) $(UIFC-MT_CFLAGS) $(XPDEV-MT_CFLAGS) $(SMBLIB_CFLAGS) $(CIOLIB-MT_CFLAGS) $(ENCODE_CFLAGS) $(HASH_CFLAGS)
CFLAGS += -I../comio
vpath %.c ../comio
OBJS += $(MTOBJODIR)$(DIRSEP)comio_nix$(OFILE)
JSDOOR_OBJS += $(MTOBJODIR)$(DIRSEP)comio_nix$(OFILE)
LDFLAGS += $(UIFC-MT_LDFLAGS) $(XPDEV-MT_LDFLAGS) $(SMBLIB_LDFLAGS) $(CIOLIB-MT_LDFLAGS) $(JS_LDFLAGS) $(CRYPT_LDFLAGS)
LDFLAGS += $(UIFC-MT_LDFLAGS) $(XPDEV-MT_LDFLAGS) $(SMBLIB_LDFLAGS) $(ENCODE_LDFLAGS) $(HASH_LDFLAGS) $(CIOLIB-MT_LDFLAGS) $(JS_LDFLAGS) $(CRYPT_LDFLAGS)
# Monolithic Synchronet executable Build Rule
$(SBBSMONO): $(MONO_OBJS) $(OBJS)
......@@ -118,9 +118,10 @@ $(SBBSMONO): $(MONO_OBJS) $(OBJS)
$(QUIET)$(CXX) -o $@ $(LDFLAGS) $(MT_LDFLAGS) $(MONO_OBJS) $(OBJS) $(SBBS_LIBS) $(SMBLIB_LIBS) $(XPDEV-MT_LIBS) $(JS_LIBS) $(CRYPT_LIBS)
# Synchronet BBS library Link Rule
$(SBBS): $(JS_DEPS) $(CRYPT_DEPS) $(OBJS) $(LIBS) $(EXTRA_SBBS_DEPENDS) | $(LIBODIR)
$(SBBS): $(JS_DEPS) $(CRYPT_DEPS) $(OBJS) $(LIBS) $(EXTRA_SBBS_DEPENDS) $(ENCODE_LIB) | $(LIBODIR)
@echo Linking $@
$(QUIET)$(MKSHPPLIB) $(LDFLAGS) -o $@ $(OBJS) $(SBBS_LIBS) $(SMBLIB_LIBS) $(LIBS) $(SHLIBOPTS) $(JS_LIBS) $(CRYPT_LIBS) $(XPDEV-MT_LIBS)
@echo $(ENCODE_LIB)
$(QUIET)$(MKSHPPLIB) $(LDFLAGS) -o $@ $(OBJS) $(SBBS_LIBS) $(SMBLIB_LIBS) $(LIBS) $(SHLIBOPTS) $(JS_LIBS) $(CRYPT_LIBS) $(ENCODE_LIBS) $(XPDEV-MT_LIBS)
# FTP Server Link Rule
$(FTPSRVR): $(MTOBJODIR)/ftpsrvr.o
......
......@@ -282,13 +282,16 @@ bool sbbs_t::answer()
"\x1b[0c" /* Request CTerm version */
"\x1b[255B" /* locate cursor as far down as possible */
"\x1b[255C" /* locate cursor as far right as possible */
"\b_" /* need a printable at this location to actually move cursor */
"\b_" /* need a printable char at this location to actually move cursor */
"\x1b[6n" /* Get cursor position */
"\x1b[u" /* restore cursor position */
"\x1b[!_" /* RIP? */
#ifdef SUPPORT_ZUULTERM
"\x1b[30;40m\xc2\x9f""Zuul.connection.write('\\x1b""Are you the gatekeeper?')\xc2\x9c" /* ZuulTerm? */
#endif
"\r" /* Move cursor left */
"\xef\xbb\xbf" // UTF-8 Zero-width non-breaking space
"\x1b[6n" /* Get cursor position (again) */
"\x1b[0m_" /* "Normal" colors */
"\x1b[2J" /* clear screen */
"\x1b[H" /* home cursor */
......@@ -340,6 +343,7 @@ bool sbbs_t::answer()
char* tokenizer = NULL;
char* p = strtok_r(str, "\x1b", &tokenizer);
unsigned cursor_pos_report = 0;
while(p != NULL) {
int x,y;
......@@ -347,10 +351,17 @@ bool sbbs_t::answer()
SAFECOPY(terminal,"ANSI");
autoterm|=(ANSI|COLOR);
if(sscanf(p, "[%u;%uR", &y, &x) == 2) {
lprintf(LOG_DEBUG,"received ANSI cursor position report: %ux%u", x, y);
/* Sanity check the coordinates in the response: */
if(x >= TERM_COLS_MIN && x <= TERM_COLS_MAX) cols=x;
if(y >= TERM_ROWS_MIN && y <= TERM_ROWS_MAX) rows=y;
cursor_pos_report++;
lprintf(LOG_DEBUG,"received ANSI cursor position report [%u]: %ux%u"
,cursor_pos_report, x, y);
if(cursor_pos_report == 1) {
/* Sanity check the coordinates in the response: */
if(x >= TERM_COLS_MIN && x <= TERM_COLS_MAX) cols=x;
if(y >= TERM_ROWS_MIN && y <= TERM_ROWS_MAX) rows=y;
} else { // second report
if(x == 1) // ZWNBSP didn't move cursor
autoterm |= UTF8;
}
} else if(sscanf(p, "[=67;84;101;114;109;%u;%u", &x, &y) == 2 && *lastchar(p) == 'c') {
lprintf(LOG_INFO,"received CTerm version report: %u.%u", x, y);
cterm_version = (x*1000) + y;
......
......@@ -41,6 +41,7 @@
/**********************************************************************/
#include "sbbs.h"
#include "cp437_utf8_tbl.h"
/****************************************************************************/
/* Outputs a NULL terminated string locally and remotely (if applicable) */
......@@ -402,8 +403,13 @@ int sbbs_t::outchar(char ch)
else
outchar_esc=0;
long term = term_supports();
if((term&(PETSCII|NO_EXASCII)) == NO_EXASCII && ch&0x80)
ch=exascii_to_ascii_char(ch); /* seven bit table */
const char* utf8 = NULL;
if(!(term&PETSCII)) {
if((term&NO_EXASCII) && (ch&0x80))
ch = exascii_to_ascii_char(ch); /* seven bit table */
else if(term&UTF8)
utf8 = cp437_utf8_tbl[(uchar)ch];
}
if(ch==FF && lncntr > 0 && !tos) {
lncntr=0;
......@@ -452,8 +458,12 @@ int sbbs_t::outchar(char ch)
outcom(PETSCII_REVERSE_OFF);
if(ch == '\r' && (curatr&0xf0) != 0) // reverse video is disabled upon CR
curatr >>= 4;
} else
outcom(ch);
} else {
if(utf8 != NULL)
putcom(utf8);
else
outcom(ch);
}
}
if(!outchar_esc) {
/* Track cursor position locally */
......
......@@ -656,8 +656,9 @@ typedef enum { /* Values for xtrn_t.event */
#define PETSCII (1L<<26) /* Commodore PET/CBM terminal */
#define SWAP_DELETE (1L<<27) /* Swap Delete and Backspace keys */
#define ICE_COLOR (1L<<28) /* Bright background color support */
#define UTF8 (1L<<29) /* UTF-8 terminal */
#define TERM_FLAGS (ANSI|COLOR|NO_EXASCII|RIP|WIP|HTML|CTERM_FONTS|PETSCII|SWAP_DELETE|ICE_COLOR)
#define TERM_FLAGS (ANSI|COLOR|NO_EXASCII|RIP|WIP|HTML|CTERM_FONTS|PETSCII|SWAP_DELETE|ICE_COLOR|UTF8)
/* Special terminal key mappings */
#define TERM_KEY_HOME CTRL_B
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment