diff -rup cygwin-1.7.0-68.orig/winsup/cygwin/ChangeLog cygwin-1.7.0-68/winsup/cygwin/ChangeLog --- cygwin-1.7.0-68.orig/winsup/cygwin/ChangeLog 2009-12-04 16:53:56.000000000 +0100 +++ cygwin-1.7.0-68/winsup/cygwin/ChangeLog 2009-12-05 14:02:42.000000000 +0100 @@ -1,3 +1,76 @@ +2009-12-04 Thomas Wolff + + * fhandler_console.cc (write): Detect ">" while parsing ESC [ + sequences to distinguish specific requests. + (char_command): Distinguish Secondary from Primary Device Attribute + request to report more details about cygwin console terminal version. + * fhandler.h: Flag to note ">" in ESC [ sequences. + +2009-12-04 Thomas Wolff + + * fhandler_console.cc (c_rabuf, c_puts_readahead, c_peek_readahead, + c_get_readahead_into_buffer): Static readahead buffer specific + for fhandler_console (independent from fhandler_base buffer) + to fix terminal status requests / escape sequence reporting. + (read): Check c_rabuf to deliver status report strings. + * select.cc (peek_console): Check peek_c_readahead() to detect + console terminal reports. + +2009-12-04 Thomas Wolff + + * fhandler_console.cc (read): Allow combined Alt-AltGr modifiers + to also produce an ESC prefix like a plain Alt modifier, e.g. to make + Alt-@ work on a keyboard where @ is AltGr-q. + +2009-12-04 Thomas Wolff + + * fhandler_console.cc (get_nonascii_key): Generate ESC prefix + for Alt modifier generically for function keys and keypad keys. + (keytable): Add escape sequences for remaining modified function keys as + a compatible extension using rxvt escape codes. + Also distinguish keypad keys modified with Ctrl, Shift, Ctrl-Shift using + xterm-style modifier coding. + +2009-12-04 Thomas Wolff + + * fhandler_console.cc (__vt100_conv): Table to transform small ASCII + letters to line drawing graphics for use in VT100 graphics mode. + (write_console): Check for VT100 graphics mode and transform wide + characters in ASCII small letter range to corresponding graphics. + (write_normal): Check for SO/SI control characters to + enable/disable VT100 graphics mode. + (base_chars): Enable SO/SI control characters for detection. + (write): Check for ESC ( 0 / ESC ( B escape sequences to + enable/disable VT100 graphics mode. + * fhandler.h: New flag vt100_graphics_mode_active, state value + gotparen to parse ESC ( escape sequences. + +2009-12-04 Thomas Wolff + + * fhandler_console.cc (read): Detect and handle mouse wheel scrolling + events (for completion of mouse reporting mode 1000) and mouse + movement events (for additional mouse reporting modes 1002 and 1003). + Use mouse_aware() as a guard and only condition for mouse + reporting in order to enforce consistence of read() and select(). + Add focus reports (for additional focus reporting mode 1004). + (mouse_aware): Enable detection of additional mouse events for select. + Tune function to precisely match actual reporting criteria. + Move adjustment of mouse position (by window scroll offset) + here to avoid duplicate code. + (char_command): Initialization of enhanced mouse reporting modes. + Initialization of focus reports. + * fhandler.h (use_mouse): Flag for additional mouse modes (bool->int). + (mouse_aware): Move enhanced function into fhandler_console.cc. + * select.cc (peek_console): Use modified mouse_aware() for more + general detection of mouse events. Also check for focus reports. + +2009-12-04 Thomas Wolff + + * fhandler_console.cc (char_command): Fix code to select dim mode + to usual 2 (not leaving previous 9 for compatibility because it + doesn't work anyway); also add entries for mode 22 (normal, not bold) + 28 (visible, not invisible), 25 (not blinking). + 2009-12-02 Corinna Vinschen * fhandler_socket.cc (send_internal): Don't split datagram messages diff -rup cygwin-1.7.0-68.orig/winsup/cygwin/fhandler.h cygwin-1.7.0-68/winsup/cygwin/fhandler.h --- cygwin-1.7.0-68.orig/winsup/cygwin/fhandler.h 2009-11-19 09:55:58.000000000 +0100 +++ cygwin-1.7.0-68/winsup/cygwin/fhandler.h 2009-12-04 17:45:02.000000000 +0100 @@ -889,6 +889,8 @@ enum ansi_intensity #define gotcommand 5 #define gettitle 6 #define eattitle 7 +#define gotparen 8 +#define gotrparen 9 #define MAXARGS 10 class dev_console @@ -904,6 +906,8 @@ class dev_console int nargs_; unsigned rarg; bool saw_question_mark; + bool saw_greater_than_sign; + bool vt100_graphics_mode_active; bool alternate_charset_active; bool metabit; @@ -936,11 +940,15 @@ class dev_console } info; COORD dwLastCursorPosition; - DWORD dwLastButtonState; + COORD dwMousePosition; /* scroll-adjusted coord of mouse event */ + COORD dwLastMousePosition; /* scroll-adjusted coord of previous mouse event */ + DWORD dwLastButtonState; /* (not noting mouse wheel events) */ + int last_button_code; /* transformed mouse report button code */ int nModifiers; bool insert_mode; - bool use_mouse; + int use_mouse; + bool use_focus; bool raw_win32_keyboard_mode; inline UINT get_console_cp (); @@ -1012,7 +1020,8 @@ class fhandler_console: public fhandler_ int ioctl (unsigned int cmd, void *); int init (HANDLE, DWORD, mode_t); - bool mouse_aware () {return dev_state->use_mouse;} + bool mouse_aware (MOUSE_EVENT_RECORD& mouse_event); + bool focus_aware () {return dev_state->use_focus;} select_record *select_read (select_stuff *); select_record *select_write (select_stuff *); diff -rup cygwin-1.7.0-68.orig/winsup/cygwin/fhandler_console.cc cygwin-1.7.0-68/winsup/cygwin/fhandler_console.cc --- cygwin-1.7.0-68.orig/winsup/cygwin/fhandler_console.cc 2009-11-19 09:55:58.000000000 +0100 +++ cygwin-1.7.0-68/winsup/cygwin/fhandler_console.cc 2009-12-04 18:03:56.000000000 +0100 @@ -100,6 +100,10 @@ fhandler_console::get_tty_stuff (int fla dev_state->scroll_region.Bottom = -1; dev_state->dwLastCursorPosition.X = -1; dev_state->dwLastCursorPosition.Y = -1; + dev_state->dwLastMousePosition.X = -1; + dev_state->dwLastMousePosition.Y = -1; + dev_state->dwLastButtonState = 0; /* none pressed */ + dev_state->last_button_code = 3; /* released */ dev_state->underline_color = FOREGROUND_GREEN | FOREGROUND_BLUE; dev_state->dim_color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; dev_state->meta_mask = LEFT_ALT_PRESSED; @@ -206,6 +210,78 @@ fhandler_console::send_winch_maybe () } } +/* Check whether a mouse event is to be reported as an escape sequence */ +bool +fhandler_console::mouse_aware (MOUSE_EVENT_RECORD& mouse_event) +{ + if (! dev_state->use_mouse) + return 0; + + /* Adjust mouse position by window scroll buffer offset + and remember adjusted position in state for use by read() */ + CONSOLE_SCREEN_BUFFER_INFO now; + if (GetConsoleScreenBufferInfo (get_output_handle (), &now)) + { + dev_state->dwMousePosition.X = mouse_event.dwMousePosition.X - now.srWindow.Left; + dev_state->dwMousePosition.Y = mouse_event.dwMousePosition.Y - now.srWindow.Top; + } + else + { + /* Cannot adjust position by window scroll buffer offset */ + return 0; + } + + /* Check whether adjusted mouse position can be reported */ + if (dev_state->dwMousePosition.X > 0xFF - ' ' - 1 + || dev_state->dwMousePosition.Y > 0xFF - ' ' - 1) + { + /* Mouse position out of reporting range */ + return 0; + } + + return ((mouse_event.dwEventFlags == 0 || mouse_event.dwEventFlags == DOUBLE_CLICK) + && mouse_event.dwButtonState != dev_state->dwLastButtonState) + || mouse_event.dwEventFlags == MOUSE_WHEELED + || (mouse_event.dwEventFlags == MOUSE_MOVED + && (dev_state->dwMousePosition.X != dev_state->dwLastMousePosition.X + || dev_state->dwMousePosition.Y != dev_state->dwLastMousePosition.Y) + && ((dev_state->use_mouse >= 2 && mouse_event.dwButtonState) + || dev_state->use_mouse >= 3)); +} + +static char c_rabuf[40]; +static char * c_rabufpoi = 0; + +static void +c_puts_readahead (char *buf) +{ + strcpy (c_rabuf, buf); + c_rabufpoi = c_rabuf; +} + +static int +c_get_readahead_into_buffer (char *buf, size_t buflen) +{ + int copied_chars = 0; + + while (buflen && c_rabufpoi && *c_rabufpoi) + { + buf[copied_chars++] = (unsigned char) (*c_rabufpoi++ & 0xff); + buflen--; + } + + return copied_chars; +} + +int +c_peek_readahead () +{ + if (c_rabufpoi) + return (unsigned char) *c_rabufpoi; + else + return -1; +} + void __stdcall fhandler_console::read (void *pv, size_t& buflen) { @@ -216,7 +292,11 @@ fhandler_console::read (void *pv, size_t int ch; set_input_state (); - int copied_chars = get_readahead_into_buffer (buf, buflen); + int copied_chars = c_get_readahead_into_buffer (buf, buflen); + if (!copied_chars) + { + copied_chars = get_readahead_into_buffer (buf, buflen); + } if (copied_chars) { @@ -362,9 +442,12 @@ fhandler_console::read (void *pv, size_t /* Determine if the keystroke is modified by META. The tricky part is to distinguish whether the right Alt key should be recognized as Alt, or as AltGr. */ - bool meta; - meta = (control_key_state & ALT_PRESSED) != 0 + bool meta = + /* Alt but not AltGr (= left ctrl + right alt)? */ + (control_key_state & ALT_PRESSED) != 0 && ((control_key_state & CTRL_PRESSED) == 0 + /* but also allow Alt-AltGr: */ + || (control_key_state & ALT_PRESSED) == ALT_PRESSED || (wch <= 0x1f || wch == 0x7f)); if (!meta) { @@ -400,10 +483,18 @@ fhandler_console::read (void *pv, size_t break; case MOUSE_EVENT: - send_winch_maybe (); - if (dev_state->use_mouse) + send_winch_maybe (); + { + MOUSE_EVENT_RECORD& mouse_event = input_rec.Event.MouseEvent; + /* As a unique guard for mouse report generation, + call mouse_aware() which is common with select(), so the result + of select() and the actual read() will be consistent on the + issue of whether input (i.e. a mouse escape sequence) will + be available or not */ + if (mouse_aware (mouse_event)) { - MOUSE_EVENT_RECORD& mouse_event = input_rec.Event.MouseEvent; + /* Note: Reported mouse position was already retrieved by + mouse_aware() and adjusted by window scroll buffer offset */ /* Treat the double-click event like a regular button press */ if (mouse_event.dwEventFlags == DOUBLE_CLICK) @@ -412,95 +503,106 @@ fhandler_console::read (void *pv, size_t mouse_event.dwEventFlags = 0; } - /* Did something other than a click occur? */ - if (mouse_event.dwEventFlags) - continue; - - /* Retrieve reported mouse position */ - int x = mouse_event.dwMousePosition.X; - int y = mouse_event.dwMousePosition.Y; - - /* Adjust mouse position by scroll buffer offset */ - CONSOLE_SCREEN_BUFFER_INFO now; - if (GetConsoleScreenBufferInfo (get_output_handle (), &now)) - { - y -= now.srWindow.Top; - x -= now.srWindow.Left; - } - else - { - syscall_printf ("mouse: cannot adjust position by scroll buffer offset"); - continue; - } - - /* If the mouse event occurred out of the area we can handle, - ignore it. */ - if ((x + ' ' + 1 > 0xFF) || (y + ' ' + 1 > 0xFF)) - { - syscall_printf ("mouse: position out of range"); - continue; - } - - /* Ignore unimportant mouse buttons */ - mouse_event.dwButtonState &= 0x7; - /* This code assumes Windows never reports multiple button events at the same time. */ int b = 0; char sz[32]; - if (mouse_event.dwButtonState == dev_state->dwLastButtonState) - { - syscall_printf ("mouse: button state unchanged"); - continue; - } - else if (mouse_event.dwButtonState < dev_state->dwLastButtonState) - { - b = 3; - strcpy (sz, "btn up"); - } - else if ((mouse_event.dwButtonState & 1) != (dev_state->dwLastButtonState & 1)) - { - b = 0; - strcpy (sz, "btn1 down"); - } - else if ((mouse_event.dwButtonState & 2) != (dev_state->dwLastButtonState & 2)) + + if (mouse_event.dwEventFlags == MOUSE_WHEELED) { - b = 2; - strcpy (sz, "btn2 down"); + if (mouse_event.dwButtonState & 0xFF800000) + { + b = 0x41; + strcpy (sz, "wheel down"); + } + else + { + b = 0x40; + strcpy (sz, "wheel up"); + } } - else if ((mouse_event.dwButtonState & 4) != (dev_state->dwLastButtonState & 4)) + else { - b = 1; - strcpy (sz, "btn3 down"); - } - - /* Remember the current button state */ - dev_state->dwLastButtonState = mouse_event.dwButtonState; + /* Ignore unimportant mouse buttons */ + mouse_event.dwButtonState &= 0x7; - /* If a button was pressed, remember the modifiers */ - if (b != 3) - { - dev_state->nModifiers = 0; - if (mouse_event.dwControlKeyState & SHIFT_PRESSED) - dev_state->nModifiers |= 0x4; - if (mouse_event.dwControlKeyState & (RIGHT_ALT_PRESSED|LEFT_ALT_PRESSED)) - dev_state->nModifiers |= 0x8; - if (mouse_event.dwControlKeyState & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED)) - dev_state->nModifiers |= 0x10; - } + if (mouse_event.dwEventFlags == MOUSE_MOVED) + { + b = dev_state->last_button_code; + } + else if (mouse_event.dwButtonState < dev_state->dwLastButtonState) + { + b = 3; + strcpy (sz, "btn up"); + } + else if ((mouse_event.dwButtonState & 1) != (dev_state->dwLastButtonState & 1)) + { + b = 0; + strcpy (sz, "btn1 down"); + } + else if ((mouse_event.dwButtonState & 2) != (dev_state->dwLastButtonState & 2)) + { + b = 2; + strcpy (sz, "btn2 down"); + } + else if ((mouse_event.dwButtonState & 4) != (dev_state->dwLastButtonState & 4)) + { + b = 1; + strcpy (sz, "btn3 down"); + } + + dev_state->last_button_code = b; + + if (mouse_event.dwEventFlags == MOUSE_MOVED) + { + b += 32; + strcpy (sz, "move"); + } + else + { + /* Remember the modified button state */ + dev_state->dwLastButtonState = mouse_event.dwButtonState; + } + } + + /* Remember mouse position */ + dev_state->dwLastMousePosition.X = dev_state->dwMousePosition.X; + dev_state->dwLastMousePosition.Y = dev_state->dwMousePosition.Y; + + /* Remember the modifiers */ + dev_state->nModifiers = 0; + if (mouse_event.dwControlKeyState & SHIFT_PRESSED) + dev_state->nModifiers |= 0x4; + if (mouse_event.dwControlKeyState & (RIGHT_ALT_PRESSED|LEFT_ALT_PRESSED)) + dev_state->nModifiers |= 0x8; + if (mouse_event.dwControlKeyState & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED)) + dev_state->nModifiers |= 0x10; + /* Indicate the modifiers */ b |= dev_state->nModifiers; /* We can now create the code. */ - sprintf (tmp, "\033[M%c%c%c", b + ' ', x + ' ' + 1, y + ' ' + 1); - syscall_printf ("mouse: %s at (%d,%d)", sz, x, y); + sprintf (tmp, "\033[M%c%c%c", b + ' ', dev_state->dwMousePosition.X + ' ' + 1, dev_state->dwMousePosition.Y + ' ' + 1); + syscall_printf ("mouse: %s at (%d,%d)", sz, dev_state->dwMousePosition.X, dev_state->dwMousePosition.Y); toadd = tmp; nread = 6; } - break; + } + break; case FOCUS_EVENT: + if (dev_state->use_focus) { + if (input_rec.Event.FocusEvent.bSetFocus) + sprintf (tmp, "\033[I"); + else + sprintf (tmp, "\033[O"); + + toadd = tmp; + nread = 3; + } + break; + case WINDOW_BUFFER_SIZE_EVENT: send_winch_maybe (); /* fall through */ @@ -1051,9 +1153,53 @@ fhandler_console::cursor_get (int *x, in *x = dev_state->info.dwCursorPosition.X; } +static wchar_t __vt100_conv [31] = { +/* VT100 line drawing graphics mode maps + `abcdefghijklmnopqrstuvwxyz{|}~ + to + ◆▒␉␌␍␊°±␤␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π≠£· +*/ + 0x25C6 /* ◆ */, + 0x2592 /* ▒ */, + 0x2409 /* ␉ */, + 0x240C /* ␌ */, + 0x240D /* ␍ */, + 0x240A /* ␊ */, + 0x00B0 /* ° */, + 0x00B1 /* ± */, + 0x2424 /* ␤ */, + 0x240B /* ␋ */, + 0x2518 /* ┘ */, + 0x2510 /* ┐ */, + 0x250C /* ┌ */, + 0x2514 /* └ */, + 0x253C /* ┼ */, + 0x23BA /* ⎺ */, + 0x23BB /* ⎻ */, + 0x2500 /* ─ */, + 0x23BC /* ⎼ */, + 0x23BD /* ⎽ */, + 0x251C /* ├ */, + 0x2524 /* ┤ */, + 0x2534 /* ┴ */, + 0x252C /* ┬ */, + 0x2502 /* │ */, + 0x2264 /* ≤ */, + 0x2265 /* ≥ */, + 0x03C0 /* π */, + 0x2260 /* ≠ */, + 0x00A3 /* £ */, + 0x00B7 /* · */, +}; + inline bool fhandler_console::write_console (PWCHAR buf, DWORD len, DWORD& done) { + if (dev_state->vt100_graphics_mode_active) + for (DWORD i = 0; i < len; i ++) + if (buf[i] >= (unsigned char) '`' && buf[i] <= (unsigned char) '~') + buf[i] = __vt100_conv[buf[i] - (unsigned char) '`']; + while (len > 0) { DWORD nbytes = len > MAX_WRITE_CHARS ? MAX_WRITE_CHARS : len; @@ -1082,11 +1228,13 @@ bool fhandler_console::write_console (PW #define TAB 8 /* We should't let the console deal with these */ #define CR 13 #define LF 10 +#define SO 14 +#define SI 15 static const char base_chars[256] = { /*00 01 02 03 04 05 06 07 */ IGN, ERR, ERR, NOR, NOR, NOR, NOR, BEL, -/*08 09 0A 0B 0C 0D 0E 0F */ BAK, TAB, DWN, ERR, ERR, CR, ERR, IGN, +/*08 09 0A 0B 0C 0D 0E 0F */ BAK, TAB, DWN, ERR, ERR, CR, SO, SI, /*10 11 12 13 14 15 16 17 */ NOR, NOR, ERR, ERR, ERR, ERR, ERR, ERR, /*18 19 1A 1B 1C 1D 1E 1F */ NOR, NOR, ERR, ESC, ERR, ERR, ERR, ERR, /* ! " # $ % & ' */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR, @@ -1136,7 +1284,10 @@ fhandler_console::char_command (char c) case 1: /* bold */ dev_state->intensity = INTENSITY_BOLD; break; - case 4: + case 2: /* dim */ + dev_state->intensity = INTENSITY_DIM; + break; + case 4: /* underlined */ dev_state->underline = 1; break; case 5: /* blink mode */ @@ -1148,18 +1299,22 @@ fhandler_console::char_command (char c) case 8: /* invisible */ dev_state->intensity = INTENSITY_INVISIBLE; break; - case 9: /* dim */ - dev_state->intensity = INTENSITY_DIM; - break; case 10: /* end alternate charset */ dev_state->alternate_charset_active = false; break; case 11: /* start alternate charset */ dev_state->alternate_charset_active = true; break; + case 22: + case 28: + dev_state->intensity = INTENSITY_NORMAL; + break; case 24: dev_state->underline = false; break; + case 25: + dev_state->blink = false; + break; case 27: dev_state->reverse = false; break; @@ -1275,9 +1430,24 @@ fhandler_console::char_command (char c) } break; - case 1000: /* Mouse support */ - dev_state->use_mouse = (c == 'h') ? true : false; - syscall_printf ("mouse support %sabled", dev_state->use_mouse ? "en" : "dis"); + case 1000: /* Mouse tracking */ + dev_state->use_mouse = (c == 'h') ? 1 : 0; + syscall_printf ("mouse support set to mode %d", dev_state->use_mouse); + break; + + case 1002: /* Mouse button event tracking */ + dev_state->use_mouse = (c == 'h') ? 2 : 0; + syscall_printf ("mouse support set to mode %d", dev_state->use_mouse); + break; + + case 1003: /* Mouse any event tracking */ + dev_state->use_mouse = (c == 'h') ? 3 : 0; + syscall_printf ("mouse support set to mode %d", dev_state->use_mouse); + break; + + case 1004: /* Focus in/out event reporting */ + dev_state->use_focus = (c == 'h') ? true : false; + syscall_printf ("focus reporting set to %d", dev_state->use_focus); break; case 2000: /* Raw keyboard mode */ @@ -1413,8 +1583,11 @@ fhandler_console::char_command (char c) WriteFile (get_output_handle (), &dev_state->args_[0], 1, (DWORD *) &x, 0); break; case 'c': /* u9 - Terminal enquire string */ - strcpy (buf, "\033[?6c"); - puts_readahead (buf); + if (dev_state->saw_greater_than_sign) + __small_sprintf (buf, "\033[>67;%d%02d;0c", CYGWIN_VERSION_DLL_MAJOR, CYGWIN_VERSION_DLL_MINOR); + else + strcpy (buf, "\033[?6c"); + c_puts_readahead (buf); break; case 'n': switch (dev_state->args_[0]) @@ -1424,7 +1597,7 @@ fhandler_console::char_command (char c) y -= dev_state->info.winTop; /* x -= dev_state->info.winLeft; // not available yet */ __small_sprintf (buf, "\033[%d;%dR", y + 1, x + 1); - puts_readahead (buf); + c_puts_readahead (buf); break; default: goto bad_escape; @@ -1589,6 +1762,12 @@ fhandler_console::write_normal (const un int x, y; switch (base_chars[*found]) { + case SO: + dev_state->vt100_graphics_mode_active = true; + break; + case SI: + dev_state->vt100_graphics_mode_active = false; + break; case BEL: beep (); break; @@ -1679,45 +1858,54 @@ fhandler_console::write (const void *vsr return -1; break; case gotesc: - if (*src == '[') + if (*src == '[') /* CSI Control Sequence Introducer */ { dev_state->state_ = gotsquare; dev_state->saw_question_mark = false; + dev_state->saw_greater_than_sign = false; for (dev_state->nargs_ = 0; dev_state->nargs_ < MAXARGS; dev_state->nargs_++) dev_state->args_[dev_state->nargs_] = 0; dev_state->nargs_ = 0; } - else if (*src == ']') + else if (*src == ']') /* OSC Operating System Command */ { dev_state->rarg = 0; dev_state->my_title_buf[0] = '\0'; dev_state->state_ = gotrsquare; } - else if (*src == 'M') /* Reverse Index */ + else if (*src == '(') /* Designate G0 character set */ + { + dev_state->state_ = gotparen; + } + else if (*src == ')') /* Designate G1 character set */ + { + dev_state->state_ = gotrparen; + } + else if (*src == 'M') /* Reverse Index (scroll down) */ { dev_state->fillin_info (get_output_handle ()); scroll_screen (0, 0, -1, -1, 0, dev_state->info.winTop + 1); dev_state->state_ = normal; } - else if (*src == 'c') /* Reset Linux terminal */ + else if (*src == 'c') /* RIS Full Reset */ { dev_state->set_default_attr (); clear_screen (0, 0, -1, -1); cursor_set (true, 0, 0); dev_state->state_ = normal; } - else if (*src == '8') /* Restore cursor position */ + else if (*src == '8') /* DECRC Restore cursor position */ { cursor_set (true, dev_state->savex, dev_state->savey); dev_state->state_ = normal; } - else if (*src == '7') /* Save cursor position */ + else if (*src == '7') /* DECSC Save cursor position */ { cursor_get (&dev_state->savex, &dev_state->savey); dev_state->savey -= dev_state->info.winTop; dev_state->state_ = normal; } - else if (*src == 'R') + else if (*src == 'R') /* ? */ dev_state->state_ = normal; else { @@ -1791,12 +1979,31 @@ fhandler_console::write (const void *vsr { if (*src == '?') dev_state->saw_question_mark = true; + else if (*src == '>') + dev_state->saw_greater_than_sign = true; /* ignore any extra chars between [ and first arg or command */ src++; } else dev_state->state_ = gotarg1; break; + case gotparen: + if (*src == '0') + dev_state->vt100_graphics_mode_active = true; + else + dev_state->vt100_graphics_mode_active = false; + dev_state->state_ = normal; + src++; + break; + case gotrparen: + /* This is not strictly needed, ^N/^O can just always be enabled */ + if (*src == '0') + /*dev_state->vt100_graphics_mode_SOSI_enabled = true*/; + else + /*dev_state->vt100_graphics_mode_SOSI_enabled = false*/; + dev_state->state_ = normal; + src++; + break; } } @@ -1809,33 +2016,39 @@ static struct { int vk; const char *val[4]; } keytable[] NO_COPY = { - /* NORMAL */ /* SHIFT */ /* CTRL */ /* ALT */ - {VK_LEFT, {"\033[D", "\033[D", "\033[D", "\033\033[D"}}, - {VK_RIGHT, {"\033[C", "\033[C", "\033[C", "\033\033[C"}}, - {VK_UP, {"\033[A", "\033[A", "\033[A", "\033\033[A"}}, - {VK_DOWN, {"\033[B", "\033[B", "\033[B", "\033\033[B"}}, - {VK_PRIOR, {"\033[5~", "\033[5~", "\033[5~", "\033\033[5~"}}, - {VK_NEXT, {"\033[6~", "\033[6~", "\033[6~", "\033\033[6~"}}, - {VK_HOME, {"\033[1~", "\033[1~", "\033[1~", "\033\033[1~"}}, - {VK_END, {"\033[4~", "\033[4~", "\033[4~", "\033\033[4~"}}, - {VK_INSERT, {"\033[2~", "\033[2~", "\033[2~", "\033\033[2~"}}, - {VK_DELETE, {"\033[3~", "\033[3~", "\033[3~", "\033\033[3~"}}, - {VK_F1, {"\033[[A", "\033[23~", NULL, NULL}}, - {VK_F2, {"\033[[B", "\033[24~", NULL, NULL}}, - {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}}, - {VK_F10, {"\033[21~", "\033[34~", NULL, NULL}}, - {VK_F11, {"\033[23~", NULL, NULL, NULL}}, - {VK_F12, {"\033[24~", NULL, NULL, NULL}}, - {VK_NUMPAD5, {"\033[G", NULL, NULL, NULL}}, - {VK_CLEAR, {"\033[G", NULL, NULL, NULL}}, + /* NORMAL */ /* SHIFT */ /* CTRL */ /* CTRL-SHIFT */ + /* Unmodified and Alt-modified keypad keys comply with linux console + SHIFT, CTRL, CTRL-SHIFT modifiers comply with xterm modifier usage */ + {VK_NUMPAD5, {"\033[G", "\033[1;2G", "\033[1;5G", "\033[1;6G"}}, + {VK_CLEAR, {"\033[G", "\033[1;2G", "\033[1;5G", "\033[1;6G"}}, + {VK_LEFT, {"\033[D", "\033[1;2D", "\033[1;5D", "\033[1;6D"}}, + {VK_RIGHT, {"\033[C", "\033[1;2C", "\033[1;5C", "\033[1;6C"}}, + {VK_UP, {"\033[A", "\033[1;2A", "\033[1;5A", "\033[1;6A"}}, + {VK_DOWN, {"\033[B", "\033[1;2B", "\033[1;5B", "\033[1;6B"}}, + {VK_PRIOR, {"\033[5~", "\033[5;2~", "\033[5;5~", "\033[5;6~"}}, + {VK_NEXT, {"\033[6~", "\033[6;2~", "\033[6;5~", "\033[6;6~"}}, + {VK_HOME, {"\033[1~", "\033[1;2~", "\033[1;5~", "\033[1;6~"}}, + {VK_END, {"\033[4~", "\033[4;2~", "\033[4;5~", "\033[4;6~"}}, + {VK_INSERT, {"\033[2~", "\033[2;2~", "\033[2;5~", "\033[2;6~"}}, + {VK_DELETE, {"\033[3~", "\033[3;2~", "\033[3;5~", "\033[3;6~"}}, + /* F1...F12, SHIFT-F1...SHIFT-F10 comply with linux console + F6...F12, and all modified F-keys comply with rxvt (compatible extension) */ + {VK_F1, {"\033[[A", "\033[23~", "\033[11^", "\033[23^"}}, + {VK_F2, {"\033[[B", "\033[24~", "\033[12^", "\033[24^"}}, + {VK_F3, {"\033[[C", "\033[25~", "\033[13^", "\033[25^"}}, + {VK_F4, {"\033[[D", "\033[26~", "\033[14^", "\033[26^"}}, + {VK_F5, {"\033[[E", "\033[28~", "\033[15^", "\033[28^"}}, + {VK_F6, {"\033[17~", "\033[29~", "\033[17^", "\033[29^"}}, + {VK_F7, {"\033[18~", "\033[31~", "\033[18^", "\033[31^"}}, + {VK_F8, {"\033[19~", "\033[32~", "\033[19^", "\033[32^"}}, + {VK_F9, {"\033[20~", "\033[33~", "\033[20^", "\033[33^"}}, + {VK_F10, {"\033[21~", "\033[34~", "\033[21^", "\033[34^"}}, + {VK_F11, {"\033[23~", "\033[23$", "\033[23^", "\033[23@"}}, + {VK_F12, {"\033[24~", "\033[24$", "\033[24^", "\033[24@"}}, + /* CTRL-6 complies with Windows cmd console but should be fixed */ {'6', {NULL, NULL, "\036", NULL}}, - {0, {"", NULL, NULL, NULL}} + /* Table end marker */ + {0} }; const char * @@ -1844,21 +2057,29 @@ get_nonascii_key (INPUT_RECORD& input_re #define NORMAL 0 #define SHIFT 1 #define CONTROL 2 -#define ALT 3 - int modifier_index = NORMAL; +/*#define CONTROLSHIFT 3*/ + int modifier_index = NORMAL; if (input_rec.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED) modifier_index = SHIFT; - else if (input_rec.Event.KeyEvent.dwControlKeyState & + if (input_rec.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) - modifier_index = CONTROL; - else if (input_rec.Event.KeyEvent.dwControlKeyState & - (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) - modifier_index = ALT; + modifier_index += CONTROL; for (int i = 0; keytable[i].vk; i++) if (input_rec.Event.KeyEvent.wVirtualKeyCode == keytable[i].vk) - return keytable[i].val[modifier_index]; + { + if ((input_rec.Event.KeyEvent.dwControlKeyState & + (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) + && keytable[i].val[modifier_index] != NULL) + { /* Generic ESC prefixing if Alt is pressed */ + tmp[0] = '\033'; + strcpy (tmp + 1, keytable[i].val[modifier_index]); + return tmp; + } + else + return keytable[i].val[modifier_index]; + } if (input_rec.Event.KeyEvent.uChar.AsciiChar) { diff -rup cygwin-1.7.0-68.orig/winsup/cygwin/select.cc cygwin-1.7.0-68/winsup/cygwin/select.cc --- cygwin-1.7.0-68.orig/winsup/cygwin/select.cc 2009-10-03 14:28:06.000000000 +0200 +++ cygwin-1.7.0-68/winsup/cygwin/select.cc 2009-12-04 18:36:06.000000000 +0100 @@ -781,6 +781,7 @@ fhandler_fifo::select_except (select_stu static int peek_console (select_record *me, bool) { + extern int c_peek_readahead (); extern const char * get_nonascii_key (INPUT_RECORD& input_rec, char *); fhandler_console *fh = (fhandler_console *) me->fh; @@ -815,6 +816,8 @@ peek_console (select_record *me, bool) fh->send_winch_maybe (); if (irec.EventType == KEY_EVENT) { + if (c_peek_readahead () >= 0) + return me->read_ready = true; if (irec.Event.KeyEvent.bKeyDown && (irec.Event.KeyEvent.uChar.AsciiChar || get_nonascii_key (irec, tmpbuf))) @@ -823,9 +826,9 @@ peek_console (select_record *me, bool) else { if (irec.EventType == MOUSE_EVENT - && fh->mouse_aware () - && (irec.Event.MouseEvent.dwEventFlags == 0 - || irec.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK)) + && fh->mouse_aware (irec.Event.MouseEvent)) + return me->read_ready = true; + if (irec.EventType == FOCUS_EVENT && fh->focus_aware ()) return me->read_ready = true; }