+++ This bug was initially created as a clone of Bug #519311 +++ See that attached testC.c file. Compiled with "#> gcc -o testC testC.c -lncursesw" With the codes, the second ncurses window "pWin1" will exactly cover the righ half of the second Chinese word in the string. But after popping up "pWin1", the "wnoutrefresh(pWin)" and "doupdate()" could not recover the content of string correctly. I have checked the codes and made a patch to fix the issue. Here attached the patches for both ncurses-5.4-15/RHEL4.8 and ncurses-5.5.26/RHEL5.3. The point with the patching is that: In doupdate()/TransformLine(), we have to re-print the whole wide char even though only half of the char was covered, cause the codes in PutAttrChar() always ignore the extended half of the wide char (and not print it to the stdout) ; and some terminal (eg. gnome-terminal) could not redraw the Wide Char if not the whole bytes of it were received from the pipe each time. --- Additional comment from frzhang on 2009-08-25 22:11:21 EDT --- Created an attachment (id=358657) Testing code --- Additional comment from frzhang on 2009-08-25 22:16:18 EDT --- Created an attachment (id=358658) patch for ncurses-5.4-15/RHEL4.7 --- Additional comment from frzhang on 2009-08-25 22:17:09 EDT --- Created an attachment (id=358659) patch for ncurses-5.5-26/RHEL5.3 --- Additional comment from mlichvar on 2009-08-26 06:51:12 EDT --- This seems to be fixed in upstream patches 20070630 and 20070707: 20070707 + improve fix for refresh of window on top of multi-column characters, taking into account some split characters on left/right window boundaries. 20070630 + partial fix for refresh of window on top of multi-column characters which are partly overwritten (report by Sadrul H Chowdhury).
Created attachment 358708 [details] fix for refresh of window on top of multi-column characters
This request was evaluated by Red Hat Product Management for inclusion, but this component is not scheduled to be updated in the current Red Hat Enterprise Linux release. If you would like this request to be reviewed for the next minor release, ask your support representative to set the next rhel-x.y flag to "?".
Several issues reported again by my customer, so a simple fix is not enough. I made a bigger patch for ncurses-5.5-26. The patch does the following: 1) added PutChar2() to print an isolated Wchar "Ext" as a blank 2) adjust in EmitRange() so that isolated Wchar "Base" and "Ext" be printed as blanks 3) adjust in TransformLine() so that Wchar "Base" right before "first char" and Wchar "Ext" right after "last char" be included into PutRange()
--- old/ncurses/tty/tty_update.c 2009-11-07 18:36:16.000000000 +0800 +++ new/ncurses/tty/tty_update.c 2009-11-07 19:02:36.000000000 +0800 @@ -439,6 +439,30 @@ position_check(SP->_cursrow, SP->_curscol, "PutChar"); } +#if USE_WIDEC_SUPPORT +/* need PutChar2() to print an isolated wide char "Ext" as a blank */ +static NCURSES_INLINE void +PutChar2(const ARG_CH_T ch, int lastIsWcharBase) +/* insert character, handling automargin stuff */ +{ + static const NCURSES_CH_T blank = NewChar(BLANK_TEXT); + + if ( !lastIsWcharBase && isWidecExt(CHDEREF(ch)) ) + ch = CHREF(blank) ; + + if (SP->_cursrow == screen_lines - 1 && SP->_curscol == screen_columns - 1) + PutCharLR(ch); + else + PutAttrChar(ch); + + if (SP->_curscol >= screen_columns) + wrap_cursor(); + + position_check(SP->_cursrow, SP->_curscol, "PutChar"); +} + +#endif + /* * Check whether the given character can be output by clearing commands. This * includes test for being a space and not including any 'bad' attributes, such @@ -487,6 +511,10 @@ EmitRange(const NCURSES_CH_T * ntext, int num) { int i; +#if USE_WIDEC_SUPPORT + int lastIsWcharBase=0; + static const NCURSES_CH_T myBlank = NewChar(BLANK_TEXT); +#endif TR(TRACE_CHARPUT, ("EmitRange %d:%s", num, _nc_viscbuf(ntext, num))); @@ -496,13 +524,38 @@ NCURSES_CH_T ntext0; while (num > 1 && !CharEq(ntext[0], ntext[1])) { - PutChar(CHREF(ntext[0])); +#if USE_WIDEC_SUPPORT + /* print isolated Wchar "Base" as a blank */ + if ( isWidecBase(ntext[0]) && ! isWidecExt(ntext[1]) ) + PutChar(CHREF(myBlank)); + else + PutChar2(CHREF(ntext[0]), lastIsWcharBase); + + if ( isWidecBase(ntext[0]) ) + lastIsWcharBase = 1; + else + lastIsWcharBase = 0; +#else + PutChar(CHREF(ntext[0])); +#endif ntext++; num--; } ntext0 = ntext[0]; if (num == 1) { - PutChar(CHREF(ntext0)); +#if USE_WIDEC_SUPPORT + /* print isolated Wchar "Base" as a blank */ + if ( isWidecBase(ntext[0]) ) + PutChar(CHREF(myBlank)); + else + PutChar2(CHREF(ntext[0]), lastIsWcharBase); + if ( isWidecBase(ntext[0]) ) + lastIsWcharBase = 1; + else + lastIsWcharBase = 0; +#else + PutChar(CHREF(ntext[0])); +#endif return 0; } runcount = 2; @@ -549,8 +602,22 @@ if (wrap_possible) PutChar(CHREF(ntext0)); } else { - for (i = 0; i < runcount; i++) - PutChar(CHREF(ntext[i])); + for (i = 0; i < runcount; i++) { +#if USE_WIDEC_SUPPORT + /* print isolated Wchar "Base" as a blank */ + if ( (i< runcount-1) && isWidecBase(ntext[i]) && ! isWidecExt(ntext[i+1]) ) + PutChar(CHREF(myBlank)); + else + PutChar2(CHREF(ntext[i]), lastIsWcharBase); + + if ( isWidecBase(ntext[i]) ) + lastIsWcharBase = 1; + else + lastIsWcharBase = 0; +#else + PutChar(CHREF(ntext[i])); +#endif + } } ntext += runcount; num -= runcount; @@ -558,8 +625,22 @@ return 0; } - for (i = 0; i < num; i++) + for (i = 0; i < num; i++) { +#if USE_WIDEC_SUPPORT + /* print isolated Wchar "Base" as a blank */ + if ( (i< num-1) && isWidecBase(ntext[i]) && ! isWidecExt(ntext[i+1]) ) + PutChar(CHREF(myBlank)); + else + PutChar2(CHREF(ntext[i]), lastIsWcharBase); + + if ( isWidecBase(ntext[i]) ) + lastIsWcharBase = 1; + else + lastIsWcharBase = 0; +#else PutChar(CHREF(ntext[i])); +#endif + } return 0; } @@ -1285,6 +1366,12 @@ return; } +#if USE_WIDEC_SUPPORT + /* don't let alone a Wchar "Base", even it may be isolated */ + if ( ( firstChar > 0 ) && isWidecBase(newLine[firstChar-1]) ) + firstChar--; +#endif + blank = newLine[screen_columns - 1]; if (!can_clear_with(CHREF(blank))) { @@ -1295,6 +1382,11 @@ && CharEq(newLine[nLastChar], oldLine[nLastChar])) nLastChar--; +#if USE_WIDEC_SUPPORT + /* don't let alone a Wchar "Ext", even it may be isolated */ + if ( ( nLastChar < screen_columns -1 ) && isWidecExt(newLine[nLastChar+1]) ) + nLastChar++; +#endif if (nLastChar >= firstChar) { GoTo(lineno, firstChar); PutRange(oldLine, newLine, lineno, firstChar, nLastChar);
Created attachment 374659 [details] testing examples codes that can demonstrate the issues The fixed packages have to make the attached examples work. The "chinese words" in the codes are in "GB18030" .
I made no fix for ncurses-5.4-15/RHEL4.7. But we can re-compiled the fixed ncurses-5.5-26 on RHEL4.7 and it works well.
I just noticed this followup last week. The test-cases appear to work with ncurses 5.7 (tested with 20100313). If there are remaining issues with current ncurses code, it would help to open a separate bug report to cover that.
This request was evaluated by Red Hat Product Management for inclusion in the current release of Red Hat Enterprise Linux. Because the affected component is not scheduled to be updated in the current release, Red Hat is unfortunately unable to address this request at this time. Red Hat invites you to ask your support representative to propose this request, if appropriate and relevant, in the next release of Red Hat Enterprise Linux.
This request was erroneously denied for the current release of Red Hat Enterprise Linux. The error has been fixed and this request has been re-proposed for the current release.