diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index a7a5e5a12..47ed0a0ad 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,38 @@ +2001-02-27 Egor Duda + + * fhandler.h (class fhandler_console): Make all variables that + describe "state" of console to be members of fhandler_console. + default_color is now the color which is set when console recieves + reset command. + * fhandler_console.cc (fhandler_console::fhandler_console): Turn + mouse handling and raw keyboard mode off by default. Initialize + state information. + * fhandler.cc (fhandler_console::set_raw_win32_keyboard_mode): New + function. + * fhandler_console.cc (fhandler_console::set_default_attr): New + function. Reset console attributes to default values. + * fhandler_console.cc (fhandler_console::open): Reset attributes. + * fhandler_console.cc (fhandler_console::get_win32_attr): New function. + Calculate win32-style console attribute based on terminal attributes. + * fhandler_console.cc (fhandler_console::set_cursor_maybe): Use + member variable. + * fhandler_console.cc (fhandler_console::read): If in raw-win32 + keyboard mode, encode win32 keyboard events in \033{x;y;z;t;u;wK + sequences. + * fhandler_console.cc (fhandler_console::dup): Copy all state + information to the dup()ed handle. + * fhandler_console.cc (fhandler_console::scroll_screen): Use current + fill-in attribute. + * fhandler_console.cc (fhandler_console::clear_screen): Ditto. + * fhandler_console.cc (fhandler_console::char_command): Check if we + saw '?' symbol by member variable. Set terminal attributes on \033[Xm + commands. \033[24m - turn off underline mode, \033[27m - turn off + reverse mode, \033[39m - restore default foreground color. + \033[49m - restore default background color. \033[2000h - turn on raw + keyboard mode, \033[2000l - turn off raw keyboard mode. + * fhandler_console.cc (fhandler_console::write): Set attribues to + default values on reset command. + 2001-02-26 Mike Simons * times.cc (settimeofday): Replace function stub with working code. diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 92cf8c300..99321a10e 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -575,14 +575,14 @@ public: virtual void __release_output_mutex (const char *fn, int ln) {} }; -/* This is a input and output console handle */ -class fhandler_console: public fhandler_termios +enum ansi_intensity { -private: + INTENSITY_INVISIBLE, + INTENSITY_DIM, + INTENSITY_NORMAL, + INTENSITY_BOLD +}; -/* Output state */ - - // enum {normal, gotesc, gotsquare, gotarg1, gotcommand} state; #define normal 1 #define gotesc 2 #define gotsquare 3 @@ -592,13 +592,55 @@ private: #define gettitle 7 #define eattitle 8 #define MAXARGS 10 + +/* This is a input and output console handle */ +class fhandler_console: public fhandler_termios +{ +private: + + WORD default_color, underline_color, dim_color; + +/* Output state */ int state_; int args_[MAXARGS]; int nargs_; + unsigned rarg; + BOOL saw_question_mark; - DWORD default_color; + char my_title_buf [TITLESIZE + 1]; + + WORD current_win32_attr; + ansi_intensity intensity; + BOOL underline, blink, reverse; + WORD fg, bg; + + /* saved cursor coordinates */ + int savex, savey; + + struct + { + short Top, Bottom; + } scroll_region; + struct + { + SHORT winTop; + SHORT winBottom; + COORD dwWinSize; + COORD dwBufferSize; + COORD dwCursorPosition; + WORD wAttributes; + } info; + + COORD dwLastCursorPosition; + DWORD dwLastButtonState; + int nModifiers; + + BOOL use_mouse; + BOOL raw_win32_keyboard_mode; /* Output calls */ + void set_default_attr (); + WORD get_win32_attr (); BOOL fillin_info (); void clear_screen (int, int, int, int); @@ -607,7 +649,8 @@ private: void cursor_get (int *, int *); void cursor_rel (int, int); const unsigned char * write_normal (unsigned const char*, unsigned const char *); - void char_command (char, bool); + void char_command (char); + BOOL set_raw_win32_keyboard_mode (BOOL); int output_tcsetattr (int a, const struct termios *t); /* Input calls */ diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 788dff3d8..91804011c 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -36,10 +36,6 @@ details. */ * xn, yn - new ul corner * Negative values represents current screen dimensions */ -static struct - { - short Top, Bottom; - } scroll_region = {0, -1}; #define srTop (info.winTop + scroll_region.Top) #define srBottom ((scroll_region.Bottom < 0) ? info.winBottom : info.winTop + scroll_region.Bottom) @@ -48,8 +44,6 @@ static struct const char * get_nonascii_key (INPUT_RECORD&, char *); -static BOOL use_mouse = FALSE; - static tty_min NO_COPY *shared_console_info = NULL; /* Allocate and initialize the shared record for the current console. @@ -116,20 +110,28 @@ set_console_state_for_spawn () return 1; } +BOOL +fhandler_console::set_raw_win32_keyboard_mode (BOOL new_mode) +{ + BOOL old_mode = raw_win32_keyboard_mode; + raw_win32_keyboard_mode = new_mode; + syscall_printf ("raw keyboard mode %sabled", raw_win32_keyboard_mode ? "en" : "dis"); + return old_mode; +}; + void fhandler_console::set_cursor_maybe () { CONSOLE_SCREEN_BUFFER_INFO now; - static CONSOLE_SCREEN_BUFFER_INFO last = {{0, 0}, {-1, -1}, 0, {0, 0}, {0, 0}}; if (!GetConsoleScreenBufferInfo (get_output_handle(), &now)) return; - if (last.dwCursorPosition.X != now.dwCursorPosition.X || - last.dwCursorPosition.Y != now.dwCursorPosition.Y) + if (dwLastCursorPosition.X != now.dwCursorPosition.X || + dwLastCursorPosition.Y != now.dwCursorPosition.Y) { SetConsoleCursorPosition (get_output_handle (), now.dwCursorPosition); - last.dwCursorPosition = now.dwCursorPosition; + dwLastCursorPosition = now.dwCursorPosition; } } @@ -153,7 +155,7 @@ fhandler_console::read (void *pv, size_t buflen) HANDLE w4[2]; DWORD nwait; - char tmp[17]; + char tmp[60]; w4[0] = h; if (iscygthread ()) @@ -198,6 +200,35 @@ fhandler_console::read (void *pv, size_t buflen) switch (input_rec.EventType) { case KEY_EVENT: +#define virtual_key_code (input_rec.Event.KeyEvent.wVirtualKeyCode) +#define control_key_state (input_rec.Event.KeyEvent.dwControlKeyState) + +#ifdef DEBUGGING + /* allow manual switching to/from raw mode via ctrl-alt-scrolllock */ + if (input_rec.Event.KeyEvent.bKeyDown && + virtual_key_code == VK_SCROLL && + control_key_state & (LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED) == LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED + ) + { + set_raw_win32_keyboard_mode ( !raw_win32_keyboard_mode ); + continue; + } +#endif + + if (raw_win32_keyboard_mode) + { + __small_sprintf(tmp, "\033{%u;%u;%u;%u;%u;%luK", + input_rec.Event.KeyEvent.bKeyDown, + input_rec.Event.KeyEvent.wRepeatCount, + input_rec.Event.KeyEvent.wVirtualKeyCode, + input_rec.Event.KeyEvent.wVirtualScanCode, + input_rec.Event.KeyEvent.uChar.UnicodeChar, + input_rec.Event.KeyEvent.dwControlKeyState ); + toadd = tmp; + nread = strlen (toadd); + break; + } + if (!input_rec.Event.KeyEvent.bKeyDown) continue; @@ -265,7 +296,6 @@ fhandler_console::read (void *pv, size_t buflen) /* This code assumes Windows never reports multiple button events at the same time. */ - static DWORD dwLastButtonState = 0; int b = 0; char sz[32]; if (mouse_event.dwButtonState == dwLastButtonState) @@ -297,7 +327,6 @@ fhandler_console::read (void *pv, size_t buflen) /* Remember the current button state */ dwLastButtonState = mouse_event.dwButtonState; - static int nModifiers = 0; /* If a button was pressed, remember the modifiers */ if (b != 3) { @@ -354,16 +383,6 @@ fhandler_console::set_input_state () input_tcsetattr (0, &tc->ti); } -static struct - { - SHORT winTop; - SHORT winBottom; - COORD dwWinSize; - COORD dwBufferSize; - COORD dwCursorPosition; - WORD wAttributes; - } info; - BOOL fhandler_console::fillin_info (void) { @@ -421,7 +440,7 @@ fhandler_console::scroll_screen (int x1, int y1, int x2, int y2, int xn, int yn) else dest.Y = yn > 0 ? yn : info.winBottom; fill.Char.AsciiChar = ' '; - fill.Attributes = default_color; + fill.Attributes = current_win32_attr; ScrollConsoleScreenBuffer (get_output_handle (), &sr1, &sr2, dest, &fill); /* ScrollConsoleScreenBuffer on Windows 95 is buggy - when scroll distance @@ -473,6 +492,8 @@ fhandler_console::open (const char *, int flags, mode_t) if (fillin_info ()) default_color = info.wAttributes; + set_default_attr (); + DWORD cflags; if (GetConsoleMode (get_io_handle (), &cflags)) { @@ -511,8 +532,36 @@ fhandler_console::dup (fhandler_base *child) if (!fhc->open(get_name (), get_flags (), 0)) system_printf ("error opening console, %E"); - fhc->state_ = state_; fhc->default_color = default_color; + fhc->underline_color = underline_color; + fhc->dim_color = dim_color; + fhc->state_ = state_; + fhc->nargs_ = nargs_; + for ( int i = 0; i < MAXARGS; i++ ) + fhc->args_[i] = args_[i]; + fhc->rarg = rarg; + fhc->saw_question_mark = saw_question_mark; + + strncpy ( fhc->my_title_buf, my_title_buf, TITLESIZE + 1) ; + + fhc->current_win32_attr = current_win32_attr; + fhc->intensity = intensity; + fhc->underline = underline; + fhc->blink = blink; + fhc->reverse = reverse; + fhc->fg = fg; + fhc->bg = bg; + + fhc->savex = savex; + fhc->savey = savey; + + fhc->scroll_region = scroll_region; + fhc->dwLastCursorPosition = dwLastCursorPosition; + fhc->dwLastButtonState = dwLastButtonState; + fhc->nModifiers = nModifiers; + + fhc->use_mouse = use_mouse; + fhc->raw_win32_keyboard_mode = raw_win32_keyboard_mode; return 0; } @@ -719,10 +768,62 @@ fhandler_console::fhandler_console (const char *name) : fhandler_termios (FH_CONSOLE, name, -1) { set_cb (sizeof *this); + default_color = dim_color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; + underline_color = FOREGROUND_GREEN | FOREGROUND_BLUE; state_ = normal; + nargs_ = 0; + for ( int i = 0; i < MAXARGS; i++ ) args_ [i] = 0; + savex = savey = 0; + scroll_region.Top = 0; + scroll_region.Bottom = -1; + dwLastCursorPosition.X = -1; + dwLastCursorPosition.Y = -1; + dwLastButtonState = 0; + nModifiers = 0; + use_mouse = raw_win32_keyboard_mode = FALSE; set_need_fork_fixup (); } +#define FOREGROUND_ATTR_MASK (FOREGROUND_RED | FOREGROUND_GREEN | \ + FOREGROUND_BLUE | FOREGROUND_INTENSITY) +#define BACKGROUND_ATTR_MASK (BACKGROUND_RED | BACKGROUND_GREEN | \ + BACKGROUND_BLUE | BACKGROUND_INTENSITY) +void +fhandler_console::set_default_attr () +{ + blink = underline = reverse = FALSE; + intensity = INTENSITY_NORMAL; + fg = default_color & FOREGROUND_ATTR_MASK; + bg = default_color & BACKGROUND_ATTR_MASK; +} + +WORD +fhandler_console::get_win32_attr () +{ + WORD win_fg = fg; + WORD win_bg = bg; + if ( reverse ) + { + 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 ); + } + if ( underline ) win_fg = underline_color; + /* emulate blink with bright background */ + if ( blink ) win_bg |= BACKGROUND_INTENSITY; + if ( intensity == INTENSITY_INVISIBLE ) + win_fg = win_bg; + else if ( intensity == INTENSITY_BOLD ) + win_fg |= FOREGROUND_INTENSITY; + return ( win_fg | win_bg ); +} + /* * Clear the screen context from x1/y1 to x2/y2 cell. * Negative values represents current screen dimensions @@ -762,7 +863,7 @@ fhandler_console::clear_screen (int x1, int y1, int x2, int y2) tlc, &done); FillConsoleOutputAttribute (get_output_handle (), - default_color, + current_win32_attr, num, tlc, &done); @@ -858,20 +959,9 @@ static const char base_chars[256] = /*F0 F1 F2 F3 F4 F5 F6 F7 */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR, /*F8 F9 FA FB FC FD FE FF */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR }; -/*#define syscall_printf small_printf*/ - -static int savex, savey; /* for CSI s, CSI u */ - void -fhandler_console::char_command (char c, bool saw_question_mark) +fhandler_console::char_command (char c) { - // Keep the background intensity with the colr since there doesn't seem - // to be a way to set this with termcap/terminfo. - static int fg = default_color & (FOREGROUND_BLUE | FOREGROUND_GREEN | - FOREGROUND_RED), - bg = default_color & (BACKGROUND_BLUE | BACKGROUND_GREEN | - BACKGROUND_RED | BACKGROUND_INTENSITY), - bold = default_color & FOREGROUND_INTENSITY; int x, y; char buf[40]; @@ -884,60 +974,32 @@ fhandler_console::char_command (char c, bool saw_question_mark) switch (args_[i]) { case 0: /* normal color */ - fg = default_color & (FOREGROUND_BLUE | FOREGROUND_GREEN | - FOREGROUND_RED); - bg = default_color & (BACKGROUND_BLUE | BACKGROUND_GREEN | - BACKGROUND_RED | BACKGROUND_INTENSITY); - bold = default_color & FOREGROUND_INTENSITY; + set_default_attr (); break; case 1: /* bold */ - fg = default_color & (FOREGROUND_BLUE | FOREGROUND_GREEN | - FOREGROUND_RED); - bg = default_color & (BACKGROUND_BLUE | BACKGROUND_GREEN | - BACKGROUND_RED | BACKGROUND_INTENSITY); - bold = FOREGROUND_INTENSITY; + intensity = INTENSITY_BOLD; break; - case 4: /* underline - simulate with cyan */ - fg = FOREGROUND_BLUE | FOREGROUND_GREEN; - bg = default_color & (BACKGROUND_BLUE | BACKGROUND_GREEN | - BACKGROUND_RED | BACKGROUND_INTENSITY); - bold = default_color & FOREGROUND_INTENSITY; + case 4: + underline = 1; break; case 5: /* blink mode */ - fg = default_color & (FOREGROUND_BLUE | FOREGROUND_GREEN | - FOREGROUND_RED); - bg = default_color & (BACKGROUND_BLUE | BACKGROUND_GREEN | - BACKGROUND_RED | BACKGROUND_INTENSITY); - bold = default_color & FOREGROUND_INTENSITY; + blink = TRUE; break; case 7: /* reverse */ - fg = (default_color & BACKGROUND_BLUE) ? FOREGROUND_BLUE : 0; - fg |= (default_color & BACKGROUND_GREEN) ? FOREGROUND_GREEN : 0; - fg |= (default_color & BACKGROUND_RED) ? FOREGROUND_RED : 0; - fg |= (default_color & BACKGROUND_INTENSITY) ? - FOREGROUND_INTENSITY : 0; - bg = (default_color & FOREGROUND_BLUE) ? BACKGROUND_BLUE : 0; - bg |= (default_color & FOREGROUND_GREEN) ? BACKGROUND_GREEN : 0; - bg |= (default_color & FOREGROUND_RED) ? BACKGROUND_RED : 0; - bg |= (default_color & FOREGROUND_INTENSITY) ? - BACKGROUND_INTENSITY : 0; + reverse = TRUE; break; case 8: /* invisible */ - fg = (default_color & BACKGROUND_BLUE) ? FOREGROUND_BLUE : 0; - fg |= (default_color & BACKGROUND_GREEN) ? FOREGROUND_GREEN : 0; - fg |= (default_color & BACKGROUND_RED) ? FOREGROUND_RED : 0; - bg = default_color & (BACKGROUND_BLUE | BACKGROUND_GREEN | - BACKGROUND_RED | BACKGROUND_INTENSITY); - bold = (default_color & BACKGROUND_INTENSITY) ? - FOREGROUND_INTENSITY : 0; + intensity = INTENSITY_INVISIBLE; break; case 9: /* dim */ - fg = default_color & (FOREGROUND_BLUE | FOREGROUND_GREEN | - FOREGROUND_RED); - bg = default_color & (BACKGROUND_BLUE | BACKGROUND_GREEN | - BACKGROUND_RED | BACKGROUND_INTENSITY); - bold = (fg == 0) ? FOREGROUND_INTENSITY : 0; + intensity = INTENSITY_DIM; break; + case 24: + underline = FALSE; + break; + case 27: + reverse = FALSE; + break; case 30: /* BLACK foreground */ fg = 0; break; @@ -962,6 +1024,9 @@ fhandler_console::char_command (char c, bool saw_question_mark) case 37: /* WHITE foreg */ fg = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; break; + case 39: + fg = default_color & FOREGROUND_ATTR_MASK; + break; case 40: /* BLACK background */ bg = 0; break; @@ -986,8 +1051,12 @@ fhandler_console::char_command (char c, bool saw_question_mark) case 47: /* WHITE background */ bg = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED; break; + case 49: + bg = default_color & BACKGROUND_ATTR_MASK; + break; } - SetConsoleTextAttribute (get_output_handle (), fg | bg | bold); + current_win32_attr = get_win32_attr (); + SetConsoleTextAttribute (get_output_handle (), current_win32_attr); break; case 'h': case 'l': @@ -1000,6 +1069,10 @@ fhandler_console::char_command (char c, bool saw_question_mark) syscall_printf("mouse support %sabled", use_mouse ? "en" : "dis"); break; + case 2000: /* Raw keyboard mode */ + set_raw_win32_keyboard_mode ( (c == 'h') ? TRUE : FALSE ); + break; + default: /* Ignore */ syscall_printf("unknown h/l command: %d", args_[0]); break; @@ -1244,9 +1317,6 @@ fhandler_console::write (const void *vsrc, size_t len) /* Run and check for ansi sequences */ unsigned const char *src = (unsigned char *) vsrc; unsigned const char *end = src + len; - static NO_COPY unsigned rarg; - static NO_COPY char my_title_buf[TITLESIZE + 1]; - bool saw_question_mark = 0; debug_printf ("%x, %d", vsrc, len); @@ -1265,6 +1335,7 @@ fhandler_console::write (const void *vsrc, size_t len) if (*src == '[') { state_ = gotsquare; + saw_question_mark = FALSE; for (nargs_ = 0; nargs_ < MAXARGS; nargs_++) args_[nargs_] = 0; nargs_ = 0; @@ -1283,6 +1354,7 @@ fhandler_console::write (const void *vsrc, size_t len) } else if (*src == 'c') /* Reset Linux terminal */ { + set_default_attr (); clear_screen (0, 0, -1, -1); cursor_set (TRUE, 0, 0); state_ = normal; @@ -1324,7 +1396,7 @@ fhandler_console::write (const void *vsrc, size_t len) } break; case gotcommand: - char_command (*src++, saw_question_mark); + char_command (*src++); state_ = normal; break; case gotrsquare: @@ -1372,7 +1444,7 @@ fhandler_console::write (const void *vsrc, size_t len) else if (*src != '@' && !isalpha (*src) && !isdigit (*src)) { if (*src == '?') - saw_question_mark = 1; + saw_question_mark = TRUE; /* ignore any extra chars between [ and first arg or command */ src++; }