@@ -776,30 +776,6 @@ curses_getcchar(const cchar_t *wcval, wchar_t *wstr, attr_t *attrs, int *pair)
776776 return rtn ;
777777}
778778
779- /* winch() returns the low 8 bits of the character's code point with no locale
780- conversion, unlike instr(), so recover the locale byte from the wide cell
781- when the character maps to exactly one byte, keeping the attribute and color
782- bits in RTN. A character with no single-byte form is left to winch(). */
783- static chtype
784- curses_cell_locale_byte (chtype rtn , const cchar_t * cell )
785- {
786- wchar_t wstr [CCHARW_MAX + 1 ];
787- attr_t attrs ;
788- int pair ;
789- if (curses_getcchar (cell , wstr , & attrs , & pair ) == ERR
790- || wstr [0 ] == L'\0' || wstr [1 ] != L'\0' )
791- {
792- return rtn ;
793- }
794- /* wctob() mirrors ncurses' own _nc_to_char(): the single-byte form, or EOF
795- when the character has none in this locale. */
796- int byte = wctob (wstr [0 ]);
797- if (byte != EOF ) {
798- rtn = (rtn & ~(chtype )A_CHARTEXT ) | (unsigned char )byte ;
799- }
800- return rtn ;
801- }
802-
803779/* Hash one cell by value (text, attributes, pair) -- consistent with the
804780 equality comparison, not the raw cchar_t whose padding and unused text tail
805781 it ignores. Zero the key first so those bytes are deterministic, then
@@ -3650,7 +3626,40 @@ _curses_window_inch_impl(PyCursesWindowObject *self, int group_right_1,
36503626{
36513627 chtype rtn ;
36523628 const char * funcname ;
3653-
3629+ #ifdef HAVE_NCURSESW
3630+ /* ncursesw's winch() returns the character's whole code point instead of
3631+ its locale byte, overflowing the chtype's 8-bit character field into the
3632+ color and attribute bits; read the wide cell and rebuild it instead. */
3633+ cchar_t cell = {0 };
3634+ int rc ;
3635+ if (!group_right_1 ) {
3636+ rc = win_wch (self -> win , & cell );
3637+ funcname = "win_wch" ;
3638+ }
3639+ else {
3640+ rc = mvwin_wch (self -> win , y , x , & cell );
3641+ funcname = "mvwin_wch" ;
3642+ }
3643+ if (rc == ERR ) {
3644+ curses_window_set_error (self , funcname , "inch" );
3645+ return NULL ;
3646+ }
3647+ wchar_t wstr [CCHARW_MAX + 1 ];
3648+ attr_t attrs ;
3649+ int pair ;
3650+ if (curses_getcchar (& cell , wstr , & attrs , & pair ) == ERR ) {
3651+ curses_window_set_error (self , "getcchar" , "inch" );
3652+ return NULL ;
3653+ }
3654+ int byte = 0 ;
3655+ if (wstr [0 ] != L'\0' && wstr [1 ] == L'\0' ) {
3656+ byte = wctob (wstr [0 ]);
3657+ if (byte == EOF ) {
3658+ byte = 0 ;
3659+ }
3660+ }
3661+ rtn = (chtype )byte | (attrs & ~(attr_t )A_COLOR ) | COLOR_PAIR (pair );
3662+ #else
36543663 if (!group_right_1 ) {
36553664 rtn = winch (self -> win );
36563665 funcname = "winch" ;
@@ -3663,13 +3672,6 @@ _curses_window_inch_impl(PyCursesWindowObject *self, int group_right_1,
36633672 curses_window_set_error (self , funcname , "inch" );
36643673 return NULL ;
36653674 }
3666- #ifdef HAVE_NCURSESW
3667- curses_cell_t cell = {0 };
3668- if ((group_right_1 ? mvwin_wch (self -> win , y , x , & cell )
3669- : win_wch (self -> win , & cell )) != ERR )
3670- {
3671- rtn = curses_cell_locale_byte (rtn , & cell );
3672- }
36733675#endif
36743676 return PyLong_FromUnsignedLong (rtn );
36753677}
0 commit comments