/* Terminal hooks for GNU Emacs on the Microsoft W32 API.
- Copyright (C) 1992, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1999, 2002, 2003, 2004,
+ 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Emacs.
You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.
Tim Fleehart (apollo@online.com) 1-17-92
Geoff Voelker (voelker@cs.washington.edu) 9-12-93
}
}
-extern unsigned char *terminal_encode_buffer;
+extern unsigned char *encode_terminal_code P_ ((struct glyph *, int,
+ struct coding_system *));
static void
w32con_write_glyphs (register struct glyph *string, register int len)
DWORD r;
struct frame * f = PICK_FRAME ();
WORD char_attr;
+ unsigned char *conversion_buffer;
+ struct coding_system *coding;
if (len <= 0)
return;
+ /* If terminal_coding does any conversion, use it, otherwise use
+ safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
+ because it always return 1 if the member src_multibyte is 1. */
+ coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK
+ ? &terminal_coding : &safe_terminal_coding);
/* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
the tail. */
terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK;
/* Turn appearance modes of the face of the run on. */
char_attr = w32_face_attributes (f, face_id);
- while (n > 0)
- {
- produced = encode_terminal_code (string,
- n,
- &consumed);
- if (produced > 0)
+ if (n == len)
+ /* This is the last run. */
+ coding->mode |= CODING_MODE_LAST_BLOCK;
+ conversion_buffer = encode_terminal_code (string, n, coding);
+ if (coding->produced > 0)
+ {
+ /* Set the attribute for these characters. */
+ if (!FillConsoleOutputAttribute (cur_screen, char_attr,
+ coding->produced, cursor_coords,
+ &r))
{
- /* Set the attribute for these characters. */
- if (!FillConsoleOutputAttribute (cur_screen, char_attr,
- produced, cursor_coords, &r))
- {
- printf ("Failed writing console attributes: %d\n",
- GetLastError ());
- fflush (stdout);
- }
-
- /* Write the characters. */
- if (!WriteConsoleOutputCharacter (cur_screen, terminal_encode_buffer,
- produced, cursor_coords, &r))
- {
- printf ("Failed writing console characters: %d\n",
- GetLastError ());
- fflush (stdout);
- }
-
- cursor_coords.X += produced;
- w32con_move_cursor (cursor_coords.Y, cursor_coords.X);
- }
- len -= consumed;
- n -= consumed;
- string += consumed;
- }
- }
-
- /* We may have to output some codes to terminate the writing. */
- if (CODING_REQUIRE_FLUSHING (&terminal_coding))
- {
- Lisp_Object blank_string = build_string ("");
- int conversion_buffer_size = 1024;
-
- terminal_coding.mode |= CODING_MODE_LAST_BLOCK;
- terminal_coding.destination = (unsigned char *) xmalloc (conversion_buffer_size);
- encode_coding_object (&terminal_coding, blank_string, 0, 0,
- 0, conversion_buffer_size, Qnil);
- if (terminal_coding.produced > 0)
- {
- if (!FillConsoleOutputAttribute (cur_screen, char_attr_normal,
- terminal_coding.produced,
- cursor_coords, &r))
- {
- printf ("Failed writing console attributes: %d\n",
- GetLastError ());
- fflush (stdout);
- }
-
- /* Write the characters. */
- if (!WriteConsoleOutputCharacter (cur_screen, terminal_coding.destination,
- produced, cursor_coords, &r))
- {
- printf ("Failed writing console characters: %d\n",
- GetLastError ());
- fflush (stdout);
- }
- }
- xfree (terminal_coding.destination);
+ printf ("Failed writing console attributes: %d\n",
+ GetLastError ());
+ fflush (stdout);
+ }
+
+ /* Write the characters. */
+ if (!WriteConsoleOutputCharacter (cur_screen, conversion_buffer,
+ coding->produced, cursor_coords,
+ &r))
+ {
+ printf ("Failed writing console characters: %d\n",
+ GetLastError ());
+ fflush (stdout);
+ }
+
+ cursor_coords.X += coding->produced;
+ w32con_move_cursor (cursor_coords.Y, cursor_coords.X);
+ }
+ len -= n;
+ string += n;
}
}
meta_key = 1;
char_attr_normal = info.wAttributes;
- if (w32_use_full_screen_buffer)
+ /* Determine if the info returned by GetConsoleScreenBufferInfo
+ is realistic. Old MS Telnet servers used to only fill out
+ the dwSize portion, even modern one fill the whole struct with
+ garbage when using non-MS telnet clients. */
+ if ((w32_use_full_screen_buffer
+ && (info.dwSize.Y < 20 || info.dwSize.Y > 100
+ || info.dwSize.X < 40 || info.dwSize.X > 200))
+ || (!w32_use_full_screen_buffer
+ && (info.srWindow.Bottom - info.srWindow.Top < 20
+ || info.srWindow.Bottom - info.srWindow.Top > 100
+ || info.srWindow.Right - info.srWindow.Left < 40
+ || info.srWindow.Right - info.srWindow.Left > 100)))
+ {
+ FRAME_LINES (SELECTED_FRAME ()) = 25;
+ SET_FRAME_COLS (SELECTED_FRAME (), 80);
+ }
+
+ else if (w32_use_full_screen_buffer)
{
FRAME_LINES (SELECTED_FRAME ()) = info.dwSize.Y; /* lines per page */
SET_FRAME_COLS (SELECTED_FRAME (), info.dwSize.X); /* characters per line */
A value of nil means use the current console window dimensions; this
may be preferrable when working directly at the console with a large
scroll-back buffer. */);
- w32_use_full_screen_buffer = 1;
+ w32_use_full_screen_buffer = 0;
defsubr (&Sset_screen_color);
defsubr (&Sset_cursor_size);