Bug 514

Summary: cygwin terminal: wrong color handling in reverse display mode
Product: cygwin Reporter: Thomas Wolff <towo>
Component: Cygwin DLLAssignee: cygwin-bugzilla <cygwin-bugzilla>
Status: REOPENED ---    
Severity: normal    
Priority: P2    
Version: unspecified   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:

Description Thomas Wolff 2004-11-04 11:34:21 UTC
When screen attributes are set to reverse (ESC[7m), 
the cygwin terminal does not just swap foreground with background, 
but in addition it swaps bright/normal (within the 2*8 ANSI color range) 
for both of them.
So, e.g., if you set up your display to be bright green on black background, 
reverse display is not black on green as it should, 
but rather "bright black" (which is gray) on "dark green" (which is rather dim),
rendering the output almost unreadable.
Comment 1 Thomas Wolff 2004-11-11 11:00:04 UTC
The bug is in fhandler_console.cc, function get_win32_attr, where 
foreground and background intensity are explicitly preserved while 
exchanging color values:
      WORD save_fg = win_fg;
      win_fg = (win_bg & BACKGROUND_RED   ? FOREGROUND_RED   : 0) |
               (win_bg & BACKGROUND_GREEN ? FOREGROUND_GREEN : 0) |
               (win_bg & BACKGROUND_BLUE  ? FOREGROUND_BLUE  : 0) |
               (win_fg & FOREGROUND_INTENSITY);
      win_bg = (save_fg & FOREGROUND_RED   ? BACKGROUND_RED   : 0) |
               (save_fg & FOREGROUND_GREEN ? BACKGROUND_GREEN : 0) |
               (save_fg & FOREGROUND_BLUE  ? BACKGROUND_BLUE  : 0) |
               (win_bg & BACKGROUND_INTENSITY);

This approach is wrong (because it's causing unreadable display) 
and should probably be replaced with just:
      WORD save_fg = win_fg;
      win_fg = win_bg;
      win_bg = save_fg;
Comment 2 Thomas Wolff 2005-03-09 14:53:55 UTC
Fixed in cygwin 1.5.13, thanks for applying my updated patch (not the one shown
here).
Comment 3 Thomas Wolff 2006-11-22 18:22:50 UTC
This bug shows up again in recent cygwin1.dll updates. My previous patch 
is still in the source but additional code apparently has the same 
effect of rendering output unreadable; the effect is the following:
* foreground is set bright
* screen mode is set to reverse
* cygwin wrongly assumes that the reverse foreground colour (which 
  actually used to be the non-bright background color) should be 
  set to bright, which is obviously a wrong idea and often results 
  in a contrast that renders the output almost unreadable

The reason for the bug are the following two lines in function set_color:
 else if (intensity == INTENSITY_BOLD)
   win_fg |= FOREGROUND_INTENSITY;
which must not be applied in reverse mode.

I submitted a 
<a href=http://www.cygwin.com/ml/cygwin-patches/2006-q4/msg00016.html>patch</a>
which I could verify meanwhile.
The patch mail also includes a test script to demonstrate the bug.