diff src/w32console.c @ 91204:53108e6cea98

Merge from emacs--devo--0 Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-294
author Miles Bader <miles@gnu.org>
date Thu, 06 Dec 2007 09:51:45 +0000
parents bdb3fe0ba9fa 0f135bf21932
children 606f2d163a64
line wrap: on
line diff
--- a/src/w32console.c	Thu Dec 06 07:36:30 2007 +0000
+++ b/src/w32console.c	Thu Dec 06 09:51:45 2007 +0000
@@ -35,8 +35,6 @@
 #include "character.h"
 #include "coding.h"
 #include "disptab.h"
-/* Disable features in frame.h that require a Window System.  */
-#undef HAVE_WINDOW_SYSTEM
 #include "frame.h"
 #include "termhooks.h"
 #include "termchar.h"
@@ -76,6 +74,8 @@
 static CONSOLE_CURSOR_INFO prev_console_cursor;
 #endif
 
+extern Lisp_Object Vtty_defined_color_alist;
+
 /* Determine whether to make frame dimensions match the screen buffer,
    or the current window size.  The former is desirable when running
    over telnet, while the latter is more useful when working directly at
@@ -164,6 +164,7 @@
 {
   int	     i, nb;
   SMALL_RECT scroll;
+  SMALL_RECT clip;
   COORD	     dest;
   CHAR_INFO  fill;
 
@@ -179,15 +180,16 @@
       scroll.Bottom = FRAME_LINES (f) - n;
       dest.Y = vpos + n;
     }
-  scroll.Left = 0;
-  scroll.Right = FRAME_COLS (f);
+  clip.Top = clip.Left = scroll.Left = 0;
+  clip.Right = scroll.Right = FRAME_COLS (f);
+  clip.Bottom = FRAME_LINES (f);
 
   dest.X = 0;
 
   fill.Char.AsciiChar = 0x20;
   fill.Attributes = char_attr_normal;
 
-  ScrollConsoleScreenBuffer (cur_screen, &scroll, NULL, dest, &fill);
+  ScrollConsoleScreenBuffer (cur_screen, &scroll, &clip, dest, &fill);
 
   /* Here we have to deal with a w32 console flake: If the scroll
      region looks like abc and we scroll c to a and fill with d we get
@@ -235,12 +237,13 @@
 {
   /* The idea here is to implement a horizontal scroll in one line to
      implement delete and half of insert.  */
-  SMALL_RECT scroll;
+  SMALL_RECT scroll, clip;
   COORD	     dest;
   CHAR_INFO  fill;
 
-  scroll.Top = cursor_coords.Y;
-  scroll.Bottom = cursor_coords.Y;
+  clip.Top = scroll.Top = clip.Bottom = scroll.Bottom = cursor_coords.Y;
+  clip.Left = 0;
+  clip.Right = FRAME_COLS (f);
 
   if (direction == LEFT)
     {
@@ -259,7 +262,7 @@
   fill.Char.AsciiChar = 0x20;
   fill.Attributes = char_attr_normal;
 
-  ScrollConsoleScreenBuffer (cur_screen, &scroll, NULL, dest, &fill);
+  ScrollConsoleScreenBuffer (cur_screen, &scroll, &clip, dest, &fill);
 }
 
 
@@ -290,7 +293,6 @@
 w32con_write_glyphs (struct frame *f, register struct glyph *string,
                      register int len)
 {
-  int produced, consumed;
   DWORD r;
   WORD char_attr;
   unsigned char *conversion_buffer;
@@ -418,11 +420,31 @@
 static void
 w32con_reset_terminal_modes (struct terminal *t)
 {
+  COORD dest;
+  CONSOLE_SCREEN_BUFFER_INFO info;
+  int n;
+  DWORD r;
+
+  /* Clear the complete screen buffer.  This is required because Emacs
+     sets the cursor position to the top of the buffer, but there might
+     be other output below the bottom of the Emacs frame if the screen buffer
+     is larger than the window size.  */
+  GetConsoleScreenBufferInfo (cur_screen, &info);
+  dest.X = 0;
+  dest.Y = 0;
+  n = info.dwSize.X * info.dwSize.Y;
+
+  FillConsoleOutputAttribute (cur_screen, char_attr_normal, n, dest, &r);
+  FillConsoleOutputCharacter (cur_screen, ' ', n, dest, &r);
+  /* Now that the screen is clear, put the cursor at the top.  */
+  SetConsoleCursorPosition (cur_screen, dest);
+  
 #ifdef USE_SEPARATE_SCREEN
   SetConsoleActiveScreenBuffer (prev_screen);
 #else
   SetConsoleCursorInfo (prev_screen, &prev_console_cursor);
 #endif
+
   SetConsoleMode (keyboard_handle, prev_console_mode);
 }
 
@@ -484,33 +506,32 @@
 
   char_attr = char_attr_normal;
 
-  if (face->foreground != FACE_TTY_DEFAULT_FG_COLOR
-      && face->foreground != FACE_TTY_DEFAULT_COLOR)
-    char_attr = (char_attr & 0xfff0) + (face->foreground % 16);
-
-  if (face->background != FACE_TTY_DEFAULT_BG_COLOR
-      && face->background != FACE_TTY_DEFAULT_COLOR)
-    char_attr = (char_attr & 0xff0f) + ((face->background % 16) << 4);
-
-
-  /* NTEMACS_TODO: Faces defined during startup get both foreground
-     and background of 0. Need a better way around this - for now detect
-     the problem and invert one of the faces to make the text readable. */
-  if (((char_attr & 0x00f0) >> 4) == (char_attr & 0x000f))
-    char_attr ^= 0x0007;
-
+  /* Reverse the default color if requested. If background and
+     foreground are specified, then they have been reversed already.  */
   if (face->tty_reverse_p)
     char_attr = (char_attr & 0xff00) + ((char_attr & 0x000f) << 4)
       + ((char_attr & 0x00f0) >> 4);
 
+  /* Before the terminal is properly initialized, all colors map to 0.
+     Don't try to resolve them.  */
+  if (NILP (Vtty_defined_color_alist))
+    return char_attr;
+
+  /* Colors should be in the range 0...15 unless they are one of
+     FACE_TTY_DEFAULT_COLOR, FACE_TTY_DEFAULT_FG_COLOR or
+     FACE_TTY_DEFAULT_BG_COLOR.  Other out of range colors are
+     invalid, so it is better to use the default color if they ever
+     get through to here.  */
+  if (face->foreground >= 0 && face->foreground < 16)
+    char_attr = (char_attr & 0xfff0) + face->foreground;
+
+  if (face->background >= 0 && face->background < 16)
+    char_attr = (char_attr & 0xff0f) + (face->background << 4);
+
   return char_attr;
 }
 
 
-/* Emulation of some X window features from xfns.c and xfaces.c.  */
-
-extern char unspecified_fg[], unspecified_bg[];
-
 
 /* Given a color index, return its standard name.  */
 Lisp_Object