summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/libbbsutil.h1
-rw-r--r--include/uflags.h10
-rw-r--r--mbbsd/screen.c28
-rw-r--r--mbbsd/user.c2
-rw-r--r--src/libbbsutil/string.c61
5 files changed, 98 insertions, 4 deletions
diff --git a/include/libbbsutil.h b/include/libbbsutil.h
index 5b877f52..f2e31a53 100644
--- a/include/libbbsutil.h
+++ b/include/libbbsutil.h
@@ -63,6 +63,7 @@ extern int strip_blank(char *cbuf, char *buf);
extern int strip_ansi(char *buf, const char *str, enum STRIP_FLAG flag);
extern int strlen_noansi(const char *s);
extern void strip_nonebig5(unsigned char *str, int maxlen);
+extern int DBCS_RemoveIntrEscape(unsigned char *buf, int *len);
extern int invalid_pname(const char *str);
extern int is_number(const char *p);
extern unsigned StringHash(const char *s);
diff --git a/include/uflags.h b/include/uflags.h
index 752dc73a..ea27bee5 100644
--- a/include/uflags.h
+++ b/include/uflags.h
@@ -4,6 +4,12 @@
#ifndef INCLUDE_UFLAGS_H
#define INCLUDE_UFLAGS_H
+// TODO in order to prevent masking with wrong variables
+// (since we have 2 flags), it is better to rename the
+// masks with their flag index, eg:
+// UF_PAGER,
+// UF2_WATER_ORIG,
+
/* -------------------- userec_t.uflag (unsigned int) */
/* UNKNOWN */
@@ -21,9 +27,9 @@
//#define MIND_FLAG 0x00000100 /* true if mind search mode open <-Heat*/
/* DBCS CONFIG */
+/* please keep these even if you don't have DBCSAWARE features turned on */
#define DBCSAWARE_FLAG 0x00000200 /* true if DBCS-aware enabled. */
-/* please keep this even if you don't have DBCSAWARE features turned on */
-// #define DBCS__??? 0x00000400
+#define DBCS_NOINTRESC 0x00000400 /* no Escapes interupting DBCS characters */
// #define DBCS__??? 0x00000800
/* Modification Mark (~) */
diff --git a/mbbsd/screen.c b/mbbsd/screen.c
index 8256ba5e..59e0addb 100644
--- a/mbbsd/screen.c
+++ b/mbbsd/screen.c
@@ -121,7 +121,8 @@ void
redoscr(void)
{
register screenline_t *bp;
- register int i, j, len;
+ register int i, j;
+ int len;
o_clear();
for (tc_col = tc_line = i = 0, j = roll; i < scr_lns; i++, j++) {
@@ -130,6 +131,17 @@ redoscr(void)
bp = &big_picture[j];
if ((len = bp->len)) {
rel_move(tc_col, tc_line, 0, i);
+
+#ifdef DBCSAWARE
+ if (!(bp->mode & STANDOUT) &&
+ (cuser.uflag & DBCS_NOINTRESC) &&
+ DBCS_RemoveIntrEscape(bp->data, &len))
+ {
+ // if anything changed, dirty whole line.
+ bp->len = len;
+ }
+#endif // DBCSAWARE
+
if (bp->mode & STANDOUT) {
standoutput((char *)bp->data, 0, len, bp->sso, bp->eso);
}
@@ -188,7 +200,8 @@ refresh(void)
{
/* TODO remove unnecessary refresh() call, to save CPU time */
register screenline_t *bp = big_picture;
- register int i, j, len;
+ register int i, j;
+ int len;
if (num_in_buf())
return;
@@ -221,6 +234,17 @@ refresh(void)
{
bp->mode &= ~(MODIFIED);
+#ifdef DBCSAWARE
+ if (!(bp->mode & STANDOUT) &&
+ (cuser.uflag & DBCS_NOINTRESC) &&
+ DBCS_RemoveIntrEscape(bp->data, &len))
+ {
+ // if anything changed, dirty whole line.
+ bp->len = len;
+ bp->smod = 0; bp->emod = len;
+ }
+#endif // DBCSAWARE
+
// more effort to determine ANSI smod
if (bp->smod > 0)
{
diff --git a/mbbsd/user.c b/mbbsd/user.c
index f2475e95..05289ef6 100644
--- a/mbbsd/user.c
+++ b/mbbsd/user.c
@@ -335,6 +335,7 @@ void Customize(void)
COLORED_MODMARK,
#ifdef DBCSAWARE
DBCSAWARE_FLAG,
+ DBCS_NOINTRESC,
#endif
0,
};
@@ -345,6 +346,7 @@ void Customize(void)
"改用色彩代替修改符號 (+)",
#ifdef DBCSAWARE
"自動偵測雙位元字集(如全型中文)",
+ "禁止插入雙位元的色碼(一字雙色)",
#endif
0,
};
diff --git a/src/libbbsutil/string.c b/src/libbbsutil/string.c
index 695d65ab..b2e7612e 100644
--- a/src/libbbsutil/string.c
+++ b/src/libbbsutil/string.c
@@ -206,6 +206,67 @@ strip_nonebig5(unsigned char *str, int maxlen)
str[len]='\0';
}
+int DBCS_RemoveIntrEscape(unsigned char *buf, int *len)
+{
+ register int isInAnsi = 0, isInDBCS = 0;
+ int l = 0, i = 0, oldl, iansi = 0;
+
+ if (len) l = *len; else l = strlen((const char*)buf);
+ oldl = l;
+
+ for (i = 0; i < l; i++)
+ {
+ if (buf[i] == ESC_CHR && !isInAnsi)
+ {
+ // new escape
+ isInAnsi = 1;
+ iansi = i;
+ continue;
+ }
+
+ // character
+ if (isInAnsi)
+ {
+ // closing ANSI section?
+ switch (isInAnsi)
+ {
+ case 1: // normal ANSI
+ if (buf[i] == '[')
+ isInAnsi = 2;
+ else
+ isInAnsi = 0; // unknown command
+ break;
+
+ case 2:
+ if (isEscapeParam(buf[i]))
+ break;
+ else
+ isInAnsi = 0;
+ break;
+ }
+ if (isInAnsi == 0 && isInDBCS && i+1 < l)
+ {
+ // interupting ANSI closed, let's modify the string
+ int sz = i + 1 - iansi; // size to move
+ memmove(buf+iansi, buf+i+1, l-i-1);
+ l -= sz;
+ i = iansi-1; // for the ++ in loop
+ }
+ } else if (isInDBCS) {
+ // not ANSI but in DBCS. finished one char.
+ isInDBCS = 0;
+ } else if (buf[i] >= 0x80) {
+ // DBCS lead.
+ isInDBCS = 1;
+ } else {
+ // normal character.
+ }
+ }
+
+ if(len) *len = l;
+ return (oldl != l) ? 1 : 0;
+}
+
/* ----------------------------------------------------- */
/* 字串檢查函數:英文、數字、檔名、E-mail address */
/* ----------------------------------------------------- */