Index: fhandler.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler.h,v
retrieving revision 1.40
diff -u -p -2 -r1.40 fhandler.h
--- fhandler.h	2001/01/17 14:57:09	1.40
+++ fhandler.h	2001/02/23 11:57:47
@@ -576,12 +576,12 @@ public:
 };
 
-/* This is a input and output console handle */
-class fhandler_console: public fhandler_termios
+enum ansi_intensity
 {
-private:
-
-/* Output state */
+  INTENSITY_INVISIBLE,
+  INTENSITY_DIM,
+  INTENSITY_NORMAL,
+  INTENSITY_BOLD
+};
 
-  // enum {normal, gotesc, gotsquare, gotarg1, gotcommand} state;
 #define normal 1
 #define gotesc 2
@@ -593,11 +593,53 @@ private:
 #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;
+
+  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;
 
-  DWORD default_color;
+  BOOL use_mouse;
+  BOOL raw_win32_keyboard_mode;
 
 /* Output calls */
+  void set_default_attr ();
+  WORD get_win32_attr ();
 
   BOOL fillin_info ();
@@ -608,5 +650,6 @@ private:
   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);
 
Index: fhandler_console.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler_console.cc,v
retrieving revision 1.37
diff -u -p -2 -r1.37 fhandler_console.cc
--- fhandler_console.cc	2001/02/14 22:00:09	1.37
+++ fhandler_console.cc	2001/02/23 11:57:48
@@ -37,8 +37,4 @@ details. */
  * Negative values represents current screen dimensions
  */
-static struct
-    {
-      short Top, Bottom;
-    } scroll_region = {0, -1};
 
 #define srTop (info.winTop + scroll_region.Top)
@@ -49,6 +45,4 @@ static struct
 const char * get_nonascii_key (INPUT_RECORD&, char *);
 
-static BOOL use_mouse = FALSE;
-
 static tty_min NO_COPY *shared_console_info = NULL;
 
@@ -117,18 +111,26 @@ set_console_state_for_spawn ()
 }
 
+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;
     }
 }
@@ -154,5 +156,5 @@ fhandler_console::read (void *pv, size_t
   HANDLE w4[2];
   DWORD nwait;
-  char tmp[17];
+  char tmp[60];
 
   w4[0] = h;
@@ -199,4 +201,33 @@ fhandler_console::read (void *pv, size_t
 	{
 	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;
@@ -266,5 +297,4 @@ fhandler_console::read (void *pv, size_t
 	      /* This code assumes Windows never reports multiple button
 		 events at the same time. */
-	      static DWORD dwLastButtonState = 0;
 	      int b = 0;
 	      char sz[32];
@@ -298,5 +328,4 @@ fhandler_console::read (void *pv, size_t
 	      dwLastButtonState = mouse_event.dwButtonState;
 	      
-	      static int nModifiers = 0;
 	      /* If a button was pressed, remember the modifiers */
 	      if (b != 3)
@@ -355,14 +384,4 @@ fhandler_console::set_input_state ()
 }
 
-static struct
-  {
-    SHORT winTop;
-    SHORT winBottom;
-    COORD dwWinSize;
-    COORD dwBufferSize;
-    COORD dwCursorPosition;
-    WORD wAttributes;
-  } info;
-
 BOOL
 fhandler_console::fillin_info (void)
@@ -422,5 +441,5 @@ fhandler_console::scroll_screen (int x1,
     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);
 
@@ -474,4 +493,6 @@ fhandler_console::open (const char *, in
     default_color = info.wAttributes;
 
+  set_default_attr ();
+
   DWORD cflags;
   if (GetConsoleMode (get_io_handle (), &cflags))
@@ -512,6 +533,34 @@ fhandler_console::dup (fhandler_base *ch
     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;
@@ -720,8 +769,60 @@ fhandler_console::fhandler_console (cons
 {
   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.
@@ -763,5 +864,5 @@ fhandler_console::clear_screen (int x1, 
 			       &done);
   FillConsoleOutputAttribute (get_output_handle (),
-			       default_color,
+			       current_win32_attr,
 			       num,
 			       tlc,
@@ -859,18 +960,7 @@ static const char base_chars[256] =
 /*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];
@@ -885,58 +975,30 @@ fhandler_console::char_command (char c, 
 	   {
 	     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;
@@ -963,4 +1025,7 @@ fhandler_console::char_command (char c, 
 	       fg = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
 	       break;
+             case 39:
+               fg = default_color & FOREGROUND_ATTR_MASK;
+               break;
 	     case 40:		/* BLACK background */
 	       bg = 0;
@@ -987,6 +1052,10 @@ fhandler_console::char_command (char c, 
 	       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':
@@ -1001,4 +1070,7 @@ fhandler_console::char_command (char c, 
 	  break;
 
+        case 2000: /* Raw keyboard mode */
+	  set_raw_win32_keyboard_mode ( (c == 'h') ? TRUE : FALSE );
+          
 	default: /* Ignore */
 	  syscall_printf("unknown h/l command: %d", args_[0]);
@@ -1245,7 +1317,4 @@ fhandler_console::write (const void *vsr
   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);
@@ -1266,4 +1335,5 @@ fhandler_console::write (const void *vsr
 	    {
 	      state_ = gotsquare;
+              saw_question_mark = FALSE;
 	      for (nargs_ = 0; nargs_ < MAXARGS; nargs_++)
 		args_[nargs_] = 0;
@@ -1284,4 +1354,5 @@ fhandler_console::write (const void *vsr
 	  else if (*src == 'c')		/* Reset Linux terminal */
 	    {
+              set_default_attr ();
 	      clear_screen (0, 0, -1, -1);
 	      cursor_set (TRUE, 0, 0);
@@ -1325,5 +1396,5 @@ fhandler_console::write (const void *vsr
 	  break;
 	case gotcommand:
-	  char_command (*src++, saw_question_mark);
+	  char_command (*src++);
 	  state_ = normal;
 	  break;
@@ -1373,5 +1444,5 @@ fhandler_console::write (const void *vsr
 	    {
 	      if (*src == '?')
-		saw_question_mark = 1;
+		saw_question_mark = TRUE;
 	      /* ignore any extra chars between [ and first arg or command */
 	      src++;
