Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm Sender: cygwin-developers-owner AT sourceware DOT cygnus DOT com Delivered-To: mailing list cygwin-developers AT sourceware DOT cygnus DOT com From: Keith Reynolds X-Mailer: SCO OpenServer Mail Release 5.0 To: cygwin-developers AT sourceware DOT cygnus DOT com Subject: proposed patch: fix console attribute glitching Date: Mon, 22 Mar 99 16:43:49 PST Message-ID: <9903221643.aa28637@shoshin.armory.COM> 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}} };