diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2009-12-19 15:37:10 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2009-12-19 15:37:10 +0000 |
commit | 8fd4bd2bf11094aaf8e227dbe6200bdb106b709e (patch) | |
tree | 8e76e33078e2d617c5aa3652eba141699c707b79 | |
parent | d954168ddbeb359a13a7afef082cbece33b289c0 (diff) | |
download | newlib-8fd4bd2bf11094aaf8e227dbe6200bdb106b709e.zip newlib-8fd4bd2bf11094aaf8e227dbe6200bdb106b709e.tar.gz newlib-8fd4bd2bf11094aaf8e227dbe6200bdb106b709e.tar.bz2 |
* fhandler_console.cc (write_console): Check for VT100
graphics mode and transform wide characters in ASCII small
letter range to corresponding graphics.
(__vt100_conv): Table to transform small ASCII letters to line
drawing graphics for use in VT100 graphics mode.
(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. Also 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 (vt100_graphics_mode_active): New flag to indicate mode.
(saw_greater_than_sign): New parse flag for ESC [ > sequences.
(gotparen, gotrparen): New state values to parse ESC ( / ) sequences.
* 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.
-rw-r--r-- | winsup/cygwin/ChangeLog | 23 | ||||
-rw-r--r-- | winsup/cygwin/fhandler.h | 4 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_console.cc | 111 |
3 files changed, 127 insertions, 11 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 9d0a8db..0f81c03 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,26 @@ +2009-12-19 Thomas Wolff <towo@towo.net> + + * fhandler_console.cc (write_console): Check for VT100 + graphics mode and transform wide characters in ASCII small + letter range to corresponding graphics. + (__vt100_conv): Table to transform small ASCII letters to line + drawing graphics for use in VT100 graphics mode. + (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. Also 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 (vt100_graphics_mode_active): New flag to indicate mode. + (saw_greater_than_sign): New parse flag for ESC [ > sequences. + (gotparen, gotrparen): New state values to parse ESC ( / ) sequences. + + * 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-18 Eric Blake <ebb9@byu.net> * signal.cc (nanosleep): Fix bug in previous patch. diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index db439f2..8cae118 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -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; diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 1e08e2c..ccac180 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -405,9 +405,12 @@ fhandler_console::read (void *pv, size_t& buflen) /* 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) { @@ -1113,9 +1116,50 @@ fhandler_console::cursor_get (int *x, int *y) *x = dev_state->info.dwCursorPosition.X; } +static wchar_t __vt100_conv [31] = { +/* VT100 line drawing graphics mode maps `abcdefghijklmnopqrstuvwxyz{|}~ to + graphical characters */ + 0x25C6, /* Black Diamond */ + 0x2592, /* Medium Shade */ + 0x2409, /* Symbol for Horizontal Tabulation */ + 0x240C, /* Symbol for Form Feed */ + 0x240D, /* Symbol for Carriage Return */ + 0x240A, /* Symbol for Line Feed */ + 0x00B0, /* Degree Sign */ + 0x00B1, /* Plus-Minus Sign */ + 0x2424, /* Symbol for Newline */ + 0x240B, /* Symbol for Vertical Tabulation */ + 0x2518, /* Box Drawings Light Up And Left */ + 0x2510, /* Box Drawings Light Down And Left */ + 0x250C, /* Box Drawings Light Down And Right */ + 0x2514, /* Box Drawings Light Up And Right */ + 0x253C, /* Box Drawings Light Vertical And Horizontal */ + 0x23BA, /* Horizontal Scan Line-1 */ + 0x23BB, /* Horizontal Scan Line-3 */ + 0x2500, /* Box Drawings Light Horizontal */ + 0x23BC, /* Horizontal Scan Line-7 */ + 0x23BD, /* Horizontal Scan Line-9 */ + 0x251C, /* Box Drawings Light Vertical And Right */ + 0x2524, /* Box Drawings Light Vertical And Left */ + 0x2534, /* Box Drawings Light Up And Horizontal */ + 0x252C, /* Box Drawings Light Down And Horizontal */ + 0x2502, /* Box Drawings Light Vertical */ + 0x2264, /* Less-Than Or Equal To */ + 0x2265, /* Greater-Than Or Equal To */ + 0x03C0, /* Greek Small Letter Pi */ + 0x2260, /* Not Equal To */ + 0x00A3, /* Pound Sign */ + 0x00B7, /* Middle Dot */ +}; + 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; @@ -1144,11 +1188,13 @@ bool fhandler_console::write_console (PWCHAR buf, DWORD len, DWORD& done) #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, @@ -1497,7 +1543,16 @@ 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"); + if (dev_state->saw_greater_than_sign) + /* Generate Secondary Device Attribute report, using 67 = ASCII 'C' + to indicate Cygwin (convention used by Rxvt, Urxvt, Screen, Mintty), + and cygwin version for terminal version. */ + __small_sprintf (buf, "\033[>67;%d%02d;0c", CYGWIN_VERSION_DLL_MAJOR, CYGWIN_VERSION_DLL_MINOR); + else + strcpy (buf, "\033[?6c"); + /* The generated report needs to be injected for read-ahead into the + fhandler_console object associated with standard input. + The current call does not work. */ puts_readahead (buf); break; case 'n': @@ -1673,6 +1728,12 @@ fhandler_console::write_normal (const unsigned char *src, 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; @@ -1763,45 +1824,54 @@ fhandler_console::write (const void *vsrc, size_t len) 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 { @@ -1875,12 +1945,31 @@ fhandler_console::write (const void *vsrc, size_t len) { 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; } } |