This is the mail archive of the cygwin-developers@sourceware.cygnus.com mailing list for the Cygwin project. See the Cygwin home page for more information.
Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

proposed patch: fix console attribute glitching



I've made a change that fixes various glitching problems with
attributes (highlight, bold, colors, etc) in the console window.
The problem has been there since I started using cygwin at b18.
It manifests as attributes changing when other output goes to the
screen, attributes not being turned off properly (like chunks of
a file being highlighed when viewing with less), etc.

The problem seemed to mostly happen when a newline was written.
For example, the underlined section of my prompt would turn off
when I hit ENTER.  So I modified the code to never output a
newline or CR character; it uses cursor motion instead.  I've
been running it for over a week now and have seen no glitches or
other problems.

There are, however, a couple things that I didn't fully grok
about the code, so the diffs should be examined by someone who's
familiar with how the console works.  The two specific areas are:

The old code contained the lines:

	if (get_w_binary())
	  cursorl_rel (x, 0);

This undoes the fact that writing a newline with WriteFile()
outputs a CR also.  What I don't know is whether the code is like
this because (a) WriteFile doesn't add a CR if get_w_binary() is
false, or (b) the CR should be there if get_w_binary() is false.
If the latter is true, then the cursor_rel call in the new code
should be changed to (something like):

	if (get_w_binary())
	  cursor_set (FALSE, 0, y+1);
	else
	  cursor_rel (0, 1);

I'm guessing that this might be necessary if $CYGWIN doesn't
contain "tty"; I didn't test that case.

The second thing I didn't understand was why the test:

	if (y == srBottom && y < info.winBottom)

requires that y be less than info.winBottom in order to scroll
the screen.  This didn't work at all in my testing after making
the other change, so I futzed with various permutations until
arriving at the code below.  There may be some cases I didn't
encounter that break.

The basic idea of using cursor motion works fine, and fixes the
glitching, but the two areas above may need some tweaking to make
the code deal with all cases.  It's been working for me for a
week or so, using vim and less and ssh'ing around to various
UNIX boxes and using similar things there.  Copy and paste also
work fine; newlines are copied even though no actual newlines
are ever written to the screen.

The last two diffs below are a feature request: on various UNIX
flavours I use, control-6 maps to ^^, which is ASCII value 30.
Vi/vim map this to "switch to the previous file", which I use all
the time and have sorely missed when using cygwin.  This change
adds that keystroke.  It also maps control-F6 to the same thing,
which is the "switch window" command in Word and other Windows
apps, which (God help me) I've also gotten used to using.  Again,
this change has been working for me for a week or so.

Keith R.

*** fhandler_console.cc-	Mon Nov 30 17:35:54 1998
--- fhandler_console.cc	Fri Mar 19 13:33:30 1999
*************** fhandler_console::write_normal (const un
*** 881,895 ****
  	case ESC:
  	  state_ = gotesc;
  	  break;
! 	case DWN:		/* WriteFile("\n") always adds CR... */
  	  cursor_get (&x, &y);
! 	  WriteFile (get_output_handle (), "\n", 1, &done, 0);
! 	  if (get_w_binary ())
! 	    cursor_rel (x, 0);
! 	  if (y == srBottom && y < info.winBottom)
  	    {
  	      scroll_screen (0, srTop + 1, -1, srBottom, 0, srTop);
- 	      cursor_set (FALSE, x, y);
  	    }
  	  break;
  	case BAK:
--- 881,892 ----
  	case ESC:
  	  state_ = gotesc;
  	  break;
! 	case DWN:
  	  cursor_get (&x, &y);
! 	  cursor_rel (0, 1);
! 	  if (y == srBottom || y == info.winBottom)
  	    {
  	      scroll_screen (0, srTop + 1, -1, srBottom, 0, srTop);
  	    }
  	  break;
  	case BAK:
*************** fhandler_console::write_normal (const un
*** 899,904 ****
--- 896,904 ----
  	  cursor_rel (1, 0);
  	  break;
  	case CR:
+ 	  cursor_get (&x, &y);
+ 	  cursor_set (FALSE, 0, y);
+ 	  break;
  	case ERR:
  	  WriteFile (get_output_handle (), src, 1, &done, 0);
  	  break;
*************** get_nonascii_key (INPUT_RECORD& input_re
*** 1104,1110 ****
      {VK_F3,      {"\033[[C",	"\033[25~",	NULL,		NULL}},
      {VK_F4,      {"\033[[D",	"\033[26~",	NULL,		NULL}},
      {VK_F5,      {"\033[[E",	"\033[28~",	NULL,		NULL}},
!     {VK_F6,      {"\033[17~",	"\033[29~",	NULL,		NULL}},
      {VK_F7,      {"\033[18~",	"\033[31~",	NULL,		NULL}},
      {VK_F8,      {"\033[19~",	"\033[32~",	NULL,		NULL}},
      {VK_F9,      {"\033[20~",	"\033[33~",	NULL,		NULL}},
--- 1104,1110 ----
      {VK_F3,      {"\033[[C",	"\033[25~",	NULL,		NULL}},
      {VK_F4,      {"\033[[D",	"\033[26~",	NULL,		NULL}},
      {VK_F5,      {"\033[[E",	"\033[28~",	NULL,		NULL}},
!     {VK_F6,      {"\033[17~",	"\033[29~",	"\036",		NULL}},
      {VK_F7,      {"\033[18~",	"\033[31~",	NULL,		NULL}},
      {VK_F8,      {"\033[19~",	"\033[32~",	NULL,		NULL}},
      {VK_F9,      {"\033[20~",	"\033[33~",	NULL,		NULL}},
*************** get_nonascii_key (INPUT_RECORD& input_re
*** 1112,1117 ****
--- 1112,1118 ----
      {VK_F11,     {"\033[23~",	NULL,		NULL,		NULL}},
      {VK_F12,     {"\033[24~",	NULL,		NULL,		NULL}},
      {VK_NUMPAD5, {"\033[G",	NULL,		NULL,		NULL}},
+     {VK_6, 	 {NULL,		NULL,		"\036",		NULL}},
      {0,		 {"",		NULL,		NULL,		NULL}}
    };