Added composite.obj and intervals.obj.
[bpt/emacs.git] / src / w32console.c
CommitLineData
e6b20d65 1/* Terminal hooks for GNU Emacs on the Microsoft W32 API.
6cdfb6e6
RS
2 Copyright (C) 1992 Free Software Foundation, Inc.
3
3b7ad313
EN
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA.
6cdfb6e6
RS
20
21 Tim Fleehart (apollo@online.com) 1-17-92
22 Geoff Voelker (voelker@cs.washington.edu) 9-12-93
23*/
24
25
6816efce
GV
26#include <config.h>
27
6cdfb6e6
RS
28#include <stdlib.h>
29#include <stdio.h>
6cdfb6e6
RS
30#include <windows.h>
31
32#include "lisp.h"
2091aeb2 33#include "charset.h"
6cdfb6e6
RS
34#include "frame.h"
35#include "disptab.h"
36#include "termhooks.h"
489f9371 37#include "w32inevt.h"
6cdfb6e6 38
0534d577 39/* from window.c */
6cdfb6e6
RS
40extern Lisp_Object Frecenter ();
41
42/* from keyboard.c */
43extern int detect_input_pending ();
44
45/* from sysdep.c */
46extern int read_input_pending ();
47
48extern FRAME_PTR updating_frame;
49extern int meta_key;
50
51static void move_cursor (int row, int col);
52static void clear_to_end (void);
53static void clear_frame (void);
54static void clear_end_of_line (int);
55static void ins_del_lines (int vpos, int n);
56static void change_line_highlight (int, int, int);
57static void reassert_line_highlight (int, int);
58static void insert_glyphs (GLYPH *start, int len);
59static void write_glyphs (GLYPH *string, int len);
60static void delete_glyphs (int n);
fbd6baed 61void w32_sys_ring_bell (void);
6cdfb6e6
RS
62static void reset_terminal_modes (void);
63static void set_terminal_modes (void);
64static void set_terminal_window (int size);
65static void update_begin (FRAME_PTR f);
66static void update_end (FRAME_PTR f);
6cdfb6e6
RS
67static int hl_mode (int new_highlight);
68
6cdfb6e6
RS
69COORD cursor_coords;
70HANDLE prev_screen, cur_screen;
71UCHAR char_attr, char_attr_normal, char_attr_reverse;
72HANDLE keyboard_handle;
b6823b27 73DWORD prev_console_mode;
6cdfb6e6 74
3e671d90
GV
75#ifndef USE_SEPARATE_SCREEN
76CONSOLE_CURSOR_INFO prev_console_cursor;
77#endif
78
191100f2
AI
79/* Determine whether to make frame dimensions match the screen buffer,
80 or the current window size. The former is desirable when running
81 over telnet, while the latter is more useful when working directly at
82 the console with a large scroll-back buffer. */
83int w32_use_full_screen_buffer;
84
6cdfb6e6
RS
85
86/* Setting this as the ctrl handler prevents emacs from being killed when
40d578c9
RS
87 someone hits ^C in a 'suspended' session (child shell).
88 Also ignore Ctrl-Break signals. */
89
6cdfb6e6
RS
90BOOL
91ctrl_c_handler (unsigned long type)
92{
3e671d90
GV
93 /* Only ignore "interrupt" events when running interactively. */
94 return (!noninteractive
95 && (type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT));
6cdfb6e6
RS
96}
97
98/* If we're updating a frame, use it as the current frame
99 Otherwise, use the selected frame. */
100#define PICK_FRAME() (updating_frame ? updating_frame : selected_frame)
101
102/* Move the cursor to (row, col). */
103void
104move_cursor (int row, int col)
105{
106 cursor_coords.X = col;
107 cursor_coords.Y = row;
108
0534d577 109 if (updating_frame == (FRAME_PTR) NULL)
6cdfb6e6
RS
110 {
111 SetConsoleCursorPosition (cur_screen, cursor_coords);
112 }
113}
114
115/* Clear from cursor to end of screen. */
116void
117clear_to_end (void)
118{
119 FRAME_PTR f = PICK_FRAME ();
120
121 clear_end_of_line (FRAME_WIDTH (f) - 1);
122 ins_del_lines (cursor_coords.Y, FRAME_HEIGHT (f) - cursor_coords.Y - 1);
123}
124
125/* Clear the frame. */
126void
127clear_frame (void)
128{
6cdfb6e6 129 FRAME_PTR f = PICK_FRAME ();
b47278e1
GV
130 COORD dest;
131 int n, r;
a5404e3a
AI
132 CONSOLE_SCREEN_BUFFER_INFO info;
133
134 GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &info);
b47278e1 135
6cdfb6e6
RS
136 hl_mode (0);
137
a5404e3a
AI
138 /* Remember that the screen buffer might be wider than the window. */
139 n = FRAME_HEIGHT (f) * info.dwSize.X;
b47278e1
GV
140 dest.X = dest.Y = 0;
141
142 FillConsoleOutputAttribute (cur_screen, char_attr, n, dest, &r);
143 FillConsoleOutputCharacter (cur_screen, ' ', n, dest, &r);
144
6cdfb6e6
RS
145 move_cursor (0, 0);
146}
147
148
149static GLYPH glyph_base[256];
150static BOOL ceol_initialized = FALSE;
151
152/* Clear from Cursor to end (what's "standout marker"?). */
153void
154clear_end_of_line (int end)
155{
156 if (!ceol_initialized)
157 {
158 int i;
159 for (i = 0; i < 256; i++)
160 {
161 glyph_base[i] = SPACEGLYPH; /* empty space */
162 }
163 ceol_initialized = TRUE;
164 }
165 write_glyphs (glyph_base, end - cursor_coords.X); /* fencepost ? */
166}
167
168/* Insert n lines at vpos. if n is negative delete -n lines. */
169void
170ins_del_lines (int vpos, int n)
171{
172 int i, nb, save_highlight;
173 SMALL_RECT scroll;
174 COORD dest;
175 CHAR_INFO fill;
176 FRAME_PTR f = PICK_FRAME ();
177
178 if (n < 0)
179 {
180 scroll.Top = vpos - n;
181 scroll.Bottom = FRAME_HEIGHT (f);
182 dest.Y = vpos;
183 }
184 else
185 {
186 scroll.Top = vpos;
187 scroll.Bottom = FRAME_HEIGHT (f) - n;
188 dest.Y = vpos + n;
189 }
190 scroll.Left = 0;
191 scroll.Right = FRAME_WIDTH (f);
192
193 dest.X = 0;
194
195 save_highlight = hl_mode (0);
196
197 fill.Char.AsciiChar = 0x20;
198 fill.Attributes = char_attr;
199
200 ScrollConsoleScreenBuffer (cur_screen, &scroll, NULL, dest, &fill);
201
fbd6baed 202 /* Here we have to deal with a w32 console flake: If the scroll
6cdfb6e6
RS
203 region looks like abc and we scroll c to a and fill with d we get
204 cbd... if we scroll block c one line at a time to a, we get cdd...
205 Emacs expects cdd consistently... So we have to deal with that
206 here... (this also occurs scrolling the same way in the other
207 direction. */
208
209 if (n > 0)
210 {
211 if (scroll.Bottom < dest.Y)
212 {
213 for (i = scroll.Bottom; i < dest.Y; i++)
214 {
215 move_cursor (i, 0);
216 clear_end_of_line (FRAME_WIDTH (f));
217 }
218 }
219 }
220 else
221 {
222 nb = dest.Y + (scroll.Bottom - scroll.Top) + 1;
223
224 if (nb < scroll.Top)
225 {
226 for (i = nb; i < scroll.Top; i++)
227 {
228 move_cursor (i, 0);
229 clear_end_of_line (FRAME_WIDTH (f));
230 }
231 }
232 }
233
234 cursor_coords.X = 0;
235 cursor_coords.Y = vpos;
236
237 hl_mode (save_highlight);
238}
239
240/* Changes attribute to use when drawing characters to control. */
241static int
242hl_mode (int new_highlight)
243{
244 static int highlight = 0;
245 int old_highlight;
246
247 old_highlight = highlight;
248 highlight = (new_highlight != 0);
249 if (highlight)
250 {
251 char_attr = char_attr_reverse;
252 }
253 else
254 {
255 char_attr = char_attr_normal;
256 }
257 return old_highlight;
258}
259
260/* Call this when about to modify line at position VPOS and change whether it
261 is highlighted. */
262void
263change_line_highlight (int new_highlight, int vpos, int first_unused_hpos)
264{
265 hl_mode (new_highlight);
266 move_cursor (vpos, 0);
267 clear_end_of_line (first_unused_hpos);
268}
269
270/* External interface to control of standout mode. Call this when about to
271 * modify line at position VPOS and not change whether it is highlighted. */
272void
273reassert_line_highlight (int highlight, int vpos)
274{
275 hl_mode (highlight);
276 vpos; /* pedantic compiler silencer */
277}
278
279#undef LEFT
280#undef RIGHT
281#define LEFT 1
282#define RIGHT 0
283
284void
285scroll_line (int dist, int direction)
286{
287 /* The idea here is to implement a horizontal scroll in one line to
288 implement delete and half of insert. */
289 SMALL_RECT scroll;
290 COORD dest;
291 CHAR_INFO fill;
292 FRAME_PTR f = PICK_FRAME ();
293
294 scroll.Top = cursor_coords.Y;
295 scroll.Bottom = cursor_coords.Y;
296
297 if (direction == LEFT)
298 {
299 scroll.Left = cursor_coords.X + dist;
300 scroll.Right = FRAME_WIDTH (f) - 1;
301 }
302 else
303 {
304 scroll.Left = cursor_coords.X;
305 scroll.Right = FRAME_WIDTH (f) - dist - 1;
306 }
307
308 dest.X = cursor_coords.X;
309 dest.Y = cursor_coords.Y;
310
311 fill.Char.AsciiChar = 0x20;
312 fill.Attributes = char_attr;
313
314 ScrollConsoleScreenBuffer (cur_screen, &scroll, NULL, dest, &fill);
315}
316
317
318/* If start is zero insert blanks instead of a string at start ?. */
319void
320insert_glyphs (register GLYPH *start, register int len)
321{
322 scroll_line (len, RIGHT);
323
324 /* Move len chars to the right starting at cursor_coords, fill with blanks */
325 if (start)
326 {
327 /* Print the first len characters of start, cursor_coords.X adjusted
328 by write_glyphs. */
329
330 write_glyphs (start, len);
331 }
332 else
333 {
334 clear_end_of_line (cursor_coords.X + len);
335 }
336}
337
338void
339write_glyphs (register GLYPH *string, register int len)
340{
341 register unsigned int glyph_len = GLYPH_TABLE_LENGTH;
342 Lisp_Object *glyph_table = GLYPH_TABLE_BASE;
343 FRAME_PTR f = PICK_FRAME ();
344 register char *ptr;
345 GLYPH glyph;
6cdfb6e6
RS
346 char *chars;
347 int i;
348
b47278e1
GV
349 if (len <= 0)
350 return;
351
6cdfb6e6 352 chars = alloca (len * sizeof (*chars));
a5404e3a 353 if (chars == NULL)
6cdfb6e6
RS
354 {
355 printf ("alloca failed in write_glyphs\n");
356 return;
357 }
358
359 /* We have to deal with the glyph indirection...go over the glyph
360 buffer and extract the characters. */
361 ptr = chars;
362 while (--len >= 0)
363 {
364 glyph = *string++;
365
366 if (glyph > glyph_len)
367 {
368 *ptr++ = glyph & 0xFF;
369 continue;
370 }
371 GLYPH_FOLLOW_ALIASES (glyph_table, glyph_len, glyph);
6e72ba86 372#ifndef HAVE_NTGUI
6cdfb6e6
RS
373 if (GLYPH_FACE (fixfix, glyph) != 0)
374 printf ("Glyph face is %d\n", GLYPH_FACE (fixfix, glyph));
6e72ba86 375#endif /* !HAVE_NTGUI */
6cdfb6e6
RS
376 if (GLYPH_SIMPLE_P (glyph_table, glyph_len, glyph))
377 {
378 *ptr++ = glyph & 0xFF;
379 continue;
380 }
381 for (i = 0; i < GLYPH_LENGTH (glyph_table, glyph); i++)
382 {
383 *ptr++ = (GLYPH_STRING (glyph_table, glyph))[i];
384 }
385 }
386
387 /* Number of characters we have in the buffer. */
388 len = ptr-chars;
389
a5404e3a
AI
390 /* Set the attribute for these characters. */
391 if (!FillConsoleOutputAttribute (cur_screen, char_attr, len, cursor_coords, &i))
6cdfb6e6 392 {
0534d577 393 printf ("Failed writing console attributes: %d\n", GetLastError ());
6cdfb6e6
RS
394 fflush (stdout);
395 }
396
397 /* Write the characters. */
398 if (!WriteConsoleOutputCharacter (cur_screen, chars, len, cursor_coords, &i))
399 {
0534d577 400 printf ("Failed writing console characters: %d\n", GetLastError ());
6cdfb6e6
RS
401 fflush (stdout);
402 }
403
404 cursor_coords.X += len;
405 move_cursor (cursor_coords.Y, cursor_coords.X);
406}
407
408void
409delete_glyphs (int n)
410{
411 /* delete chars means scroll chars from cursor_coords.X + n to
412 cursor_coords.X, anything beyond the edge of the screen should
413 come out empty... */
414
415 scroll_line (n, LEFT);
416}
417
0534d577 418static unsigned int sound_type = 0xFFFFFFFF;
78859b80 419#define MB_EMACS_SILENT (0xFFFFFFFF - 1)
0534d577 420
6cdfb6e6 421void
fbd6baed 422w32_sys_ring_bell (void)
6cdfb6e6 423{
0534d577 424 if (sound_type == 0xFFFFFFFF)
78859b80 425 {
0534d577 426 Beep (666, 100);
78859b80
GV
427 }
428 else if (sound_type == MB_EMACS_SILENT)
429 {
430 /* Do nothing. */
431 }
0534d577 432 else
78859b80 433 MessageBeep (sound_type);
6cdfb6e6
RS
434}
435
0534d577
KH
436DEFUN ("set-message-beep", Fset_message_beep, Sset_message_beep, 1, 1, 0,
437 "Set the sound generated when the bell is rung.\n\
78859b80
GV
438SOUND is 'asterisk, 'exclamation, 'hand, 'question, 'ok, or 'silent\n\
439to use the corresponding system sound for the bell. The 'silent sound\n\
440prevents Emacs from making any sound at all.\n\
0534d577
KH
441SOUND is nil to use the normal beep.")
442 (sound)
443 Lisp_Object sound;
6cdfb6e6 444{
0534d577
KH
445 CHECK_SYMBOL (sound, 0);
446
447 if (NILP (sound))
448 sound_type = 0xFFFFFFFF;
449 else if (EQ (sound, intern ("asterisk")))
450 sound_type = MB_ICONASTERISK;
451 else if (EQ (sound, intern ("exclamation")))
452 sound_type = MB_ICONEXCLAMATION;
453 else if (EQ (sound, intern ("hand")))
454 sound_type = MB_ICONHAND;
455 else if (EQ (sound, intern ("question")))
456 sound_type = MB_ICONQUESTION;
457 else if (EQ (sound, intern ("ok")))
458 sound_type = MB_OK;
78859b80
GV
459 else if (EQ (sound, intern ("silent")))
460 sound_type = MB_EMACS_SILENT;
0534d577
KH
461 else
462 sound_type = 0xFFFFFFFF;
463
464 return sound;
6cdfb6e6 465}
6cdfb6e6
RS
466
467void
468reset_terminal_modes (void)
469{
3e671d90 470#ifdef USE_SEPARATE_SCREEN
6cdfb6e6 471 SetConsoleActiveScreenBuffer (prev_screen);
3e671d90
GV
472#else
473 SetConsoleCursorInfo (prev_screen, &prev_console_cursor);
474#endif
475 SetConsoleMode (keyboard_handle, prev_console_mode);
6cdfb6e6
RS
476}
477
478void
479set_terminal_modes (void)
480{
481 CONSOLE_CURSOR_INFO cci;
482
3e671d90
GV
483 /* make cursor big and visible (100 on Win95 makes it disappear) */
484 cci.dwSize = 99;
485 cci.bVisible = TRUE;
486 (void) SetConsoleCursorInfo (cur_screen, &cci);
6cdfb6e6 487
3e671d90 488 SetConsoleActiveScreenBuffer (cur_screen);
6cdfb6e6 489
3e671d90 490 SetConsoleMode (keyboard_handle, ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT);
6cdfb6e6 491
3e671d90
GV
492 /* Initialize input mode: interrupt_input off, no flow control, allow
493 8 bit character input, standard quit char. */
494 Fset_input_mode (Qnil, Qnil, make_number (2), Qnil);
6cdfb6e6
RS
495}
496
497/* hmmm... perhaps these let us bracket screen changes so that we can flush
498 clumps rather than one-character-at-a-time...
499
500 we'll start with not moving the cursor while an update is in progress. */
501void
502update_begin (FRAME_PTR f)
503{
504}
505
506void
507update_end (FRAME_PTR f)
508{
509 SetConsoleCursorPosition (cur_screen, cursor_coords);
510}
511
512void
513set_terminal_window (int size)
514{
515}
516
6cdfb6e6
RS
517typedef int (*term_hook) ();
518
519void
e6b20d65 520initialize_w32_display (void)
6cdfb6e6
RS
521{
522 CONSOLE_SCREEN_BUFFER_INFO info;
523
f3d268f9
GV
524 cursor_to_hook = move_cursor;
525 raw_cursor_to_hook = move_cursor;
526 clear_to_end_hook = clear_to_end;
527 clear_frame_hook = clear_frame;
528 clear_end_of_line_hook = clear_end_of_line;
529 ins_del_lines_hook = ins_del_lines;
530 change_line_highlight_hook = change_line_highlight;
531 reassert_line_highlight_hook = reassert_line_highlight;
532 insert_glyphs_hook = insert_glyphs;
533 write_glyphs_hook = write_glyphs;
534 delete_glyphs_hook = delete_glyphs;
535 ring_bell_hook = w32_sys_ring_bell;
536 reset_terminal_modes_hook = reset_terminal_modes;
537 set_terminal_modes_hook = set_terminal_modes;
538 set_terminal_window_hook = set_terminal_window;
539 update_begin_hook = update_begin;
540 update_end_hook = update_end;
6cdfb6e6 541
fbd6baed 542 read_socket_hook = w32_console_read_socket;
f3d268f9 543 mouse_position_hook = w32_console_mouse_position;
3e671d90 544
c1e06681
AI
545 /* Initialize interrupt_handle. */
546 init_crit ();
547
3e671d90
GV
548 /* Remember original console settings. */
549 keyboard_handle = GetStdHandle (STD_INPUT_HANDLE);
550 GetConsoleMode (keyboard_handle, &prev_console_mode);
551
6cdfb6e6
RS
552 prev_screen = GetStdHandle (STD_OUTPUT_HANDLE);
553
3e671d90
GV
554#ifdef USE_SEPARATE_SCREEN
555 cur_screen = CreateConsoleScreenBuffer (GENERIC_READ | GENERIC_WRITE,
556 0, NULL,
557 CONSOLE_TEXTMODE_BUFFER,
558 NULL);
559
560 if (cur_screen == INVALID_HANDLE_VALUE)
561 {
562 printf ("CreateConsoleScreenBuffer failed in ResetTerm\n");
563 printf ("LastError = 0x%lx\n", GetLastError ());
564 fflush (stdout);
565 exit (0);
566 }
567#else
568 cur_screen = prev_screen;
569 GetConsoleCursorInfo (prev_screen, &prev_console_cursor);
570#endif
571
191100f2
AI
572 /* Respect setting of LINES and COLUMNS environment variables. */
573 {
574 char * lines = getenv("LINES");
575 char * columns = getenv("COLUMNS");
576
577 if (lines != NULL && columns != NULL)
578 {
579 SMALL_RECT new_win_dims;
580 COORD new_size;
581
582 new_size.X = atoi (columns);
583 new_size.Y = atoi (lines);
584
585 GetConsoleScreenBufferInfo (cur_screen, &info);
586
587 /* Shrink the window first, so the buffer dimensions can be
588 reduced if necessary. */
589 new_win_dims.Top = 0;
590 new_win_dims.Left = 0;
591 new_win_dims.Bottom = min (new_size.Y, info.dwSize.Y) - 1;
592 new_win_dims.Right = min (new_size.X, info.dwSize.X) - 1;
593 SetConsoleWindowInfo (cur_screen, TRUE, &new_win_dims);
594
595 SetConsoleScreenBufferSize (cur_screen, new_size);
596
597 /* Set the window size to match the buffer dimension. */
598 new_win_dims.Top = 0;
599 new_win_dims.Left = 0;
600 new_win_dims.Bottom = new_size.Y - 1;
601 new_win_dims.Right = new_size.X - 1;
602 SetConsoleWindowInfo (cur_screen, TRUE, &new_win_dims);
603 }
604 }
605
6cdfb6e6
RS
606 GetConsoleScreenBufferInfo (cur_screen, &info);
607
608 meta_key = 1;
609 char_attr = info.wAttributes & 0xFF;
610 char_attr_normal = char_attr;
611 char_attr_reverse = ((char_attr & 0xf) << 4) + ((char_attr & 0xf0) >> 4);
938469f2 612
191100f2
AI
613 if (w32_use_full_screen_buffer)
614 {
615 FRAME_HEIGHT (selected_frame) = info.dwSize.Y; /* lines per page */
616 SET_FRAME_WIDTH (selected_frame, info.dwSize.X); /* characters per line */
617 }
618 else
619 {
620 /* Lines per page. Use buffer coords instead of buffer size. */
621 FRAME_HEIGHT (selected_frame) = 1 + info.srWindow.Bottom -
622 info.srWindow.Top;
623 /* Characters per line. Use buffer coords instead of buffer size. */
624 SET_FRAME_WIDTH (selected_frame, 1 + info.srWindow.Right -
625 info.srWindow.Left);
626 }
6cdfb6e6
RS
627}
628
629DEFUN ("set-screen-color", Fset_screen_color, Sset_screen_color, 2, 2, 0,
630 "Set screen colors.")
631 (foreground, background)
632 Lisp_Object foreground;
633 Lisp_Object background;
634{
635 char_attr_normal = XFASTINT (foreground) + (XFASTINT (background) << 4);
636 char_attr_reverse = XFASTINT (background) + (XFASTINT (foreground) << 4);
637
638 Frecenter (Qnil);
639 return Qt;
640}
641
642DEFUN ("set-cursor-size", Fset_cursor_size, Sset_cursor_size, 1, 1, 0,
643 "Set cursor size.")
644 (size)
645 Lisp_Object size;
646{
647 CONSOLE_CURSOR_INFO cci;
648 cci.dwSize = XFASTINT (size);
649 cci.bVisible = TRUE;
650 (void) SetConsoleCursorInfo (cur_screen, &cci);
651
652 return Qt;
653}
654
6e72ba86 655#ifndef HAVE_NTGUI
6cdfb6e6
RS
656void
657pixel_to_glyph_coords (FRAME_PTR f, int pix_x, int pix_y, int *x, int *y,
658 void *bounds, int noclip)
659{
660 *x = pix_x;
661 *y = pix_y;
662}
663
664void
665glyph_to_pixel_coords (FRAME_PTR f, int x, int y, int *pix_x, int *pix_y)
666{
667 *pix_x = x;
668 *pix_y = y;
669}
6e72ba86 670#endif /* !HAVE_NTGUI */
6cdfb6e6 671
0534d577 672void
6cdfb6e6
RS
673syms_of_ntterm ()
674{
191100f2
AI
675 DEFVAR_BOOL ("w32-use-full-screen-buffer",
676 &w32_use_full_screen_buffer,
677 "Non-nil means make terminal frames use the full screen buffer dimensions.\n\
678This is desirable when running Emacs over telnet, and is the default.\n\
679A value of nil means use the current console window dimensions; this\n\
680may be preferrable when working directly at the console with a large\n\
681scroll-back buffer.");
682 w32_use_full_screen_buffer = 1;
683
6cdfb6e6
RS
684 defsubr (&Sset_screen_color);
685 defsubr (&Sset_cursor_size);
0534d577 686 defsubr (&Sset_message_beep);
6cdfb6e6 687}