Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Curses(3) inch(3) seems broken in NetBSD 5

On Fri 11 Sep 2009 at 17:41:45 +0200, Rhialto wrote:
> Up to NetBSD 4.0, this worked fine. In 5.0.1, it seems that it has
> broken. I put ACS_PLUS on the screen, and I get back a different value,
> seemingly ACS_PLUS & 0xFF.

This seems to be contrary to the manual page curs_inch(3X) which says

       The following bit-masks may  be  AND-ed  with  characters  returned  by

       A_CHARTEXT     Bit-mask to extract character
       A_ATTRIBUTES   Bit-mask to extract attributes
       A_COLOR        Bit-mask to extract color-pair field information

where A_ATTRIBUTES appears to include A_ALTCHARSET. (Not that I should
know that ACS characters have A_ALTCHARSET set; this is not documented
so I should not need to care)

The problem appears to be that addch() ultimately does

#define HAVE_WCHAR 1

        cc.vals[0] = ch & __CHARTEXT;
        cc.elements = 1;
        cc.attributes = ch & __ATTRIBUTES;

        return (wadd_wch(win, &cc));

to separate "text" and "attribute", where inch() ultimately does

/* lib/libcurses/inch.c */
winch(WINDOW *win)
#ifndef HAVE_WCHAR
        chtype   ch;

        ch = (chtype) (((win)->alines[(win)->cury]->line[(win)->curx].ch & 
          (chtype) ((win)->alines[(win)->cury]->line[(win)->curx].attr & 
        return (ch);
        return ( chtype )win->alines[ win->cury ]->line[ win->curx ].ch;
#endif /* HAVE_WCHAR */

where the attributes are dropped.

I seem to have found a workaround for this regression though.

Since the attributes apparently never overlap even with wide characters
(as evidenced by addch() splitting them from a chartype) I can do this

    /* See curs_in_wch(3X) */
    cchar_t wch;

    mvwin_wch(stdscr, pos.y, pos.x, &wch);
    ch = wch.vals[0] | (wch.attributes & WA_ALTCHARSET);

but I think that winch(3X) should do that of course (probably using
__ATTRIBUTES like its non-HAVE_WCHAR version).

If, for whatever reason, wide characters get mangled that way, they
could not have been placed on the screen with addch() in the first
place, so inch() mishandling them would not be a problem.

Something like this (untested) (wich, on reflection, makes both parts of
the #ifdef essentially identical):

--- inch.c.dist 2009-07-25 21:49:49.000000000 +0200
+++  2009-09-11 23:59:32.000000000 +0200
@@ -87,7 +87,10 @@
        ch = (chtype) (((win)->alines[(win)->cury]->line[(win)->curx].ch & 
          (chtype) ((win)->alines[(win)->cury]->line[(win)->curx].attr & 
        return (ch);
-       return ( chtype )win->alines[ win->cury ]->line[ win->curx ].ch;
+       chtype   ch;
+       cchar_t *wchp = &win->alines[ win->cury ]->line[ win->curx ];
+       ch = (wchp->ch & __CHARTEXT) | (wchp->attr & __ATTRIBUTES);
+       return ch;
 #endif /* HAVE_WCHAR */

___ Olaf 'Rhialto' Seibert    -- You author it, and I'll reader it.
\X/ rhialto/at/      -- Cetero censeo "authored" delendum esse.

Home | Main Index | Thread Index | Old Index