*** empty log message ***
[bpt/emacs.git] / src / w32console.c
CommitLineData
e6b20d65 1/* Terminal hooks for GNU Emacs on the Microsoft W32 API.
8c2ac482 2 Copyright (C) 1992, 1999 Free Software Foundation, Inc.
6cdfb6e6 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 30#include <windows.h>
338b1bb2 31#include <string.h>
6cdfb6e6
RS
32
33#include "lisp.h"
2091aeb2 34#include "charset.h"
8c2ac482 35#include "coding.h"
6cdfb6e6
RS
36#include "disptab.h"
37#include "termhooks.h"
b93b26cb
JR
38#include "dispextern.h"
39/* Disable features in frame.h that require a Window System. */
65fb143c
JR
40#undef HAVE_WINDOW_SYSTEM
41#include "frame.h"
489f9371 42#include "w32inevt.h"
6cdfb6e6 43
0534d577 44/* from window.c */
6cdfb6e6
RS
45extern Lisp_Object Frecenter ();
46
47/* from keyboard.c */
48extern int detect_input_pending ();
49
50/* from sysdep.c */
51extern int read_input_pending ();
52
8c2ac482 53extern struct frame * updating_frame;
6cdfb6e6
RS
54extern int meta_key;
55
56static void move_cursor (int row, int col);
57static void clear_to_end (void);
58static void clear_frame (void);
59static void clear_end_of_line (int);
60static void ins_del_lines (int vpos, int n);
8c2ac482
JR
61static void insert_glyphs (struct glyph *start, int len);
62static void write_glyphs (struct glyph *string, int len);
6cdfb6e6 63static void delete_glyphs (int n);
fbd6baed 64void w32_sys_ring_bell (void);
6cdfb6e6
RS
65static void reset_terminal_modes (void);
66static void set_terminal_modes (void);
67static void set_terminal_window (int size);
8c2ac482
JR
68static void update_begin (struct frame * f);
69static void update_end (struct frame * f);
338b1bb2 70static WORD w32_face_attributes (struct frame *f, int face_id);
6cdfb6e6 71
338b1bb2
JR
72static COORD cursor_coords;
73static HANDLE prev_screen, cur_screen;
74static WORD char_attr_normal;
75static DWORD prev_console_mode;
6cdfb6e6 76
3e671d90 77#ifndef USE_SEPARATE_SCREEN
338b1bb2 78static CONSOLE_CURSOR_INFO prev_console_cursor;
3e671d90
GV
79#endif
80
191100f2
AI
81/* Determine whether to make frame dimensions match the screen buffer,
82 or the current window size. The former is desirable when running
83 over telnet, while the latter is more useful when working directly at
84 the console with a large scroll-back buffer. */
85int w32_use_full_screen_buffer;
338b1bb2 86HANDLE keyboard_handle;
191100f2 87
6cdfb6e6
RS
88
89/* Setting this as the ctrl handler prevents emacs from being killed when
40d578c9
RS
90 someone hits ^C in a 'suspended' session (child shell).
91 Also ignore Ctrl-Break signals. */
92
6cdfb6e6
RS
93BOOL
94ctrl_c_handler (unsigned long type)
95{
3e671d90
GV
96 /* Only ignore "interrupt" events when running interactively. */
97 return (!noninteractive
98 && (type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT));
6cdfb6e6
RS
99}
100
101/* If we're updating a frame, use it as the current frame
102 Otherwise, use the selected frame. */
8c2ac482 103#define PICK_FRAME() (updating_frame ? updating_frame : SELECTED_FRAME ())
6cdfb6e6
RS
104
105/* Move the cursor to (row, col). */
106void
107move_cursor (int row, int col)
108{
109 cursor_coords.X = col;
110 cursor_coords.Y = row;
111
8c2ac482 112 if (updating_frame == (struct frame *) NULL)
6cdfb6e6
RS
113 {
114 SetConsoleCursorPosition (cur_screen, cursor_coords);
115 }
116}
117
118/* Clear from cursor to end of screen. */
119void
120clear_to_end (void)
121{
8c2ac482 122 struct frame * f = PICK_FRAME ();
6cdfb6e6
RS
123
124 clear_end_of_line (FRAME_WIDTH (f) - 1);
125 ins_del_lines (cursor_coords.Y, FRAME_HEIGHT (f) - cursor_coords.Y - 1);
126}
127
128/* Clear the frame. */
129void
130clear_frame (void)
131{
8c2ac482 132 struct frame * f = PICK_FRAME ();
b47278e1 133 COORD dest;
84f5bd81
AI
134 int n;
135 DWORD r;
a5404e3a
AI
136 CONSOLE_SCREEN_BUFFER_INFO info;
137
138 GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &info);
b47278e1 139
a5404e3a
AI
140 /* Remember that the screen buffer might be wider than the window. */
141 n = FRAME_HEIGHT (f) * info.dwSize.X;
b47278e1
GV
142 dest.X = dest.Y = 0;
143
338b1bb2 144 FillConsoleOutputAttribute (cur_screen, char_attr_normal, n, dest, &r);
b47278e1
GV
145 FillConsoleOutputCharacter (cur_screen, ' ', n, dest, &r);
146
6cdfb6e6
RS
147 move_cursor (0, 0);
148}
149
150
8c2ac482 151static struct glyph glyph_base[256];
6cdfb6e6
RS
152static BOOL ceol_initialized = FALSE;
153
154/* Clear from Cursor to end (what's "standout marker"?). */
155void
156clear_end_of_line (int end)
157{
158 if (!ceol_initialized)
159 {
160 int i;
161 for (i = 0; i < 256; i++)
162 {
8c2ac482 163 memcpy (&glyph_base[i], &space_glyph, sizeof (struct glyph));
6cdfb6e6
RS
164 }
165 ceol_initialized = TRUE;
166 }
167 write_glyphs (glyph_base, end - cursor_coords.X); /* fencepost ? */
168}
169
170/* Insert n lines at vpos. if n is negative delete -n lines. */
171void
172ins_del_lines (int vpos, int n)
173{
e850a615 174 int i, nb;
6cdfb6e6
RS
175 SMALL_RECT scroll;
176 COORD dest;
177 CHAR_INFO fill;
8c2ac482 178 struct frame * f = PICK_FRAME ();
6cdfb6e6
RS
179
180 if (n < 0)
181 {
182 scroll.Top = vpos - n;
183 scroll.Bottom = FRAME_HEIGHT (f);
184 dest.Y = vpos;
185 }
186 else
187 {
188 scroll.Top = vpos;
189 scroll.Bottom = FRAME_HEIGHT (f) - n;
190 dest.Y = vpos + n;
191 }
192 scroll.Left = 0;
193 scroll.Right = FRAME_WIDTH (f);
194
195 dest.X = 0;
196
6cdfb6e6 197 fill.Char.AsciiChar = 0x20;
338b1bb2 198 fill.Attributes = char_attr_normal;
6cdfb6e6
RS
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;
6cdfb6e6
RS
236}
237
238#undef LEFT
239#undef RIGHT
240#define LEFT 1
241#define RIGHT 0
242
243void
244scroll_line (int dist, int direction)
245{
246 /* The idea here is to implement a horizontal scroll in one line to
247 implement delete and half of insert. */
248 SMALL_RECT scroll;
249 COORD dest;
250 CHAR_INFO fill;
8c2ac482 251 struct frame * f = PICK_FRAME ();
6cdfb6e6
RS
252
253 scroll.Top = cursor_coords.Y;
254 scroll.Bottom = cursor_coords.Y;
255
256 if (direction == LEFT)
257 {
258 scroll.Left = cursor_coords.X + dist;
259 scroll.Right = FRAME_WIDTH (f) - 1;
260 }
261 else
262 {
263 scroll.Left = cursor_coords.X;
264 scroll.Right = FRAME_WIDTH (f) - dist - 1;
265 }
266
267 dest.X = cursor_coords.X;
268 dest.Y = cursor_coords.Y;
269
270 fill.Char.AsciiChar = 0x20;
338b1bb2
JR
271 fill.Attributes = char_attr_normal;
272
6cdfb6e6
RS
273 ScrollConsoleScreenBuffer (cur_screen, &scroll, NULL, dest, &fill);
274}
275
276
277/* If start is zero insert blanks instead of a string at start ?. */
278void
8c2ac482 279insert_glyphs (register struct glyph *start, register int len)
6cdfb6e6
RS
280{
281 scroll_line (len, RIGHT);
282
283 /* Move len chars to the right starting at cursor_coords, fill with blanks */
284 if (start)
285 {
286 /* Print the first len characters of start, cursor_coords.X adjusted
287 by write_glyphs. */
288
289 write_glyphs (start, len);
290 }
291 else
292 {
293 clear_end_of_line (cursor_coords.X + len);
294 }
295}
296
297void
8c2ac482 298write_glyphs (register struct glyph *string, register int len)
6cdfb6e6 299{
84f5bd81
AI
300 int produced, consumed;
301 DWORD r;
8c2ac482 302 struct frame * f = PICK_FRAME ();
338b1bb2 303 WORD char_attr;
4d5d6aab
KH
304 unsigned char conversion_buffer[1024];
305 int conversion_buffer_size = sizeof conversion_buffer;
338b1bb2
JR
306
307 if (len <= 0)
308 return;
b47278e1 309
8c2ac482
JR
310 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
311 the tail. */
312 terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK;
6cdfb6e6 313
8c2ac482 314 while (len > 0)
6cdfb6e6 315 {
8c2ac482
JR
316 /* Identify a run of glyphs with the same face. */
317 int face_id = string->face_id;
318 int n;
319
320 for (n = 1; n < len; ++n)
321 if (string[n].face_id != face_id)
322 break;
323
324 /* Turn appearance modes of the face of the run on. */
338b1bb2 325 char_attr = w32_face_attributes (f, face_id);
8c2ac482
JR
326
327 while (n > 0)
328 {
4d5d6aab
KH
329 /* We use a fixed size (1024 bytes) of conversion buffer.
330 Usually it is sufficient, but if not, we just repeat the
331 loop. */
8c2ac482
JR
332 produced = encode_terminal_code (string, conversion_buffer,
333 n, conversion_buffer_size,
334 &consumed);
335 if (produced > 0)
336 {
337 /* Set the attribute for these characters. */
338 if (!FillConsoleOutputAttribute (cur_screen, char_attr,
84f5bd81 339 produced, cursor_coords, &r))
8c2ac482
JR
340 {
341 printf ("Failed writing console attributes: %d\n",
342 GetLastError ());
343 fflush (stdout);
344 }
345
346 /* Write the characters. */
347 if (!WriteConsoleOutputCharacter (cur_screen, conversion_buffer,
84f5bd81 348 produced, cursor_coords, &r))
8c2ac482
JR
349 {
350 printf ("Failed writing console characters: %d\n",
351 GetLastError ());
352 fflush (stdout);
353 }
354
355 cursor_coords.X += produced;
356 move_cursor (cursor_coords.Y, cursor_coords.X);
357 }
358 len -= consumed;
359 n -= consumed;
360 string += consumed;
361 }
6cdfb6e6
RS
362 }
363
8c2ac482
JR
364 /* We may have to output some codes to terminate the writing. */
365 if (CODING_REQUIRE_FLUSHING (&terminal_coding))
6cdfb6e6 366 {
8c2ac482
JR
367 terminal_coding.mode |= CODING_MODE_LAST_BLOCK;
368 encode_coding (&terminal_coding, "", conversion_buffer,
369 0, conversion_buffer_size);
370 if (terminal_coding.produced > 0)
371 {
338b1bb2 372 if (!FillConsoleOutputAttribute (cur_screen, char_attr_normal,
8c2ac482 373 terminal_coding.produced,
84f5bd81 374 cursor_coords, &r))
8c2ac482
JR
375 {
376 printf ("Failed writing console attributes: %d\n",
377 GetLastError ());
378 fflush (stdout);
379 }
380
381 /* Write the characters. */
382 if (!WriteConsoleOutputCharacter (cur_screen, conversion_buffer,
84f5bd81 383 produced, cursor_coords, &r))
8c2ac482
JR
384 {
385 printf ("Failed writing console characters: %d\n",
386 GetLastError ());
387 fflush (stdout);
388 }
389 }
6cdfb6e6 390 }
6cdfb6e6
RS
391}
392
8c2ac482 393
6cdfb6e6
RS
394void
395delete_glyphs (int n)
396{
397 /* delete chars means scroll chars from cursor_coords.X + n to
398 cursor_coords.X, anything beyond the edge of the screen should
399 come out empty... */
400
401 scroll_line (n, LEFT);
402}
403
0534d577 404static unsigned int sound_type = 0xFFFFFFFF;
78859b80 405#define MB_EMACS_SILENT (0xFFFFFFFF - 1)
0534d577 406
6cdfb6e6 407void
fbd6baed 408w32_sys_ring_bell (void)
6cdfb6e6 409{
0534d577 410 if (sound_type == 0xFFFFFFFF)
78859b80 411 {
0534d577 412 Beep (666, 100);
78859b80
GV
413 }
414 else if (sound_type == MB_EMACS_SILENT)
415 {
416 /* Do nothing. */
417 }
0534d577 418 else
78859b80 419 MessageBeep (sound_type);
6cdfb6e6
RS
420}
421
0534d577
KH
422DEFUN ("set-message-beep", Fset_message_beep, Sset_message_beep, 1, 1, 0,
423 "Set the sound generated when the bell is rung.\n\
78859b80
GV
424SOUND is 'asterisk, 'exclamation, 'hand, 'question, 'ok, or 'silent\n\
425to use the corresponding system sound for the bell. The 'silent sound\n\
426prevents Emacs from making any sound at all.\n\
0534d577
KH
427SOUND is nil to use the normal beep.")
428 (sound)
429 Lisp_Object sound;
6cdfb6e6 430{
b7826503 431 CHECK_SYMBOL (sound);
0534d577
KH
432
433 if (NILP (sound))
434 sound_type = 0xFFFFFFFF;
435 else if (EQ (sound, intern ("asterisk")))
436 sound_type = MB_ICONASTERISK;
437 else if (EQ (sound, intern ("exclamation")))
438 sound_type = MB_ICONEXCLAMATION;
439 else if (EQ (sound, intern ("hand")))
440 sound_type = MB_ICONHAND;
441 else if (EQ (sound, intern ("question")))
442 sound_type = MB_ICONQUESTION;
443 else if (EQ (sound, intern ("ok")))
444 sound_type = MB_OK;
78859b80
GV
445 else if (EQ (sound, intern ("silent")))
446 sound_type = MB_EMACS_SILENT;
0534d577
KH
447 else
448 sound_type = 0xFFFFFFFF;
449
450 return sound;
6cdfb6e6 451}
6cdfb6e6
RS
452
453void
454reset_terminal_modes (void)
455{
3e671d90 456#ifdef USE_SEPARATE_SCREEN
6cdfb6e6 457 SetConsoleActiveScreenBuffer (prev_screen);
3e671d90
GV
458#else
459 SetConsoleCursorInfo (prev_screen, &prev_console_cursor);
460#endif
461 SetConsoleMode (keyboard_handle, prev_console_mode);
6cdfb6e6
RS
462}
463
464void
465set_terminal_modes (void)
466{
467 CONSOLE_CURSOR_INFO cci;
468
3e671d90
GV
469 /* make cursor big and visible (100 on Win95 makes it disappear) */
470 cci.dwSize = 99;
471 cci.bVisible = TRUE;
472 (void) SetConsoleCursorInfo (cur_screen, &cci);
6cdfb6e6 473
3e671d90 474 SetConsoleActiveScreenBuffer (cur_screen);
6cdfb6e6 475
3e671d90 476 SetConsoleMode (keyboard_handle, ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT);
6cdfb6e6 477
3e671d90
GV
478 /* Initialize input mode: interrupt_input off, no flow control, allow
479 8 bit character input, standard quit char. */
480 Fset_input_mode (Qnil, Qnil, make_number (2), Qnil);
6cdfb6e6
RS
481}
482
483/* hmmm... perhaps these let us bracket screen changes so that we can flush
484 clumps rather than one-character-at-a-time...
485
486 we'll start with not moving the cursor while an update is in progress. */
487void
8c2ac482 488update_begin (struct frame * f)
6cdfb6e6
RS
489{
490}
491
492void
8c2ac482 493update_end (struct frame * f)
6cdfb6e6
RS
494{
495 SetConsoleCursorPosition (cur_screen, cursor_coords);
496}
497
498void
499set_terminal_window (int size)
500{
501}
502
8c2ac482
JR
503/***********************************************************************
504 Faces
505 ***********************************************************************/
506
507
508/* Turn appearances of face FACE_ID on tty frame F on. */
509
338b1bb2
JR
510static WORD
511w32_face_attributes (f, face_id)
8c2ac482
JR
512 struct frame *f;
513 int face_id;
514{
338b1bb2 515 WORD char_attr;
8c2ac482
JR
516 struct face *face = FACE_FROM_ID (f, face_id);
517
518 xassert (face != NULL);
519
520 char_attr = char_attr_normal;
521
338b1bb2
JR
522 if (face->foreground != FACE_TTY_DEFAULT_FG_COLOR
523 && face->foreground != FACE_TTY_DEFAULT_COLOR)
524 char_attr = (char_attr & 0xfff0) + (face->foreground % 16);
525
526 if (face->background != FACE_TTY_DEFAULT_BG_COLOR
527 && face->background != FACE_TTY_DEFAULT_COLOR)
b93b26cb 528 char_attr = (char_attr & 0xff0f) + ((face->background % 16) << 4);
338b1bb2 529
8c2ac482 530
b93b26cb
JR
531 /* NTEMACS_TODO: Faces defined during startup get both foreground
532 and background of 0. Need a better way around this - for now detect
533 the problem and invert one of the faces to make the text readable. */
338b1bb2
JR
534 if (((char_attr & 0x00f0) >> 4) == (char_attr & 0x000f))
535 char_attr ^= 0x0007;
8c2ac482 536
e850a615 537 if (face->tty_reverse_p)
338b1bb2
JR
538 char_attr = (char_attr & 0xff00) + ((char_attr & 0x000f) << 4)
539 + ((char_attr & 0x00f0) >> 4);
8c2ac482 540
338b1bb2 541 return char_attr;
8c2ac482
JR
542}
543
544
338b1bb2 545/* Emulation of some X window features from xfns.c and xfaces.c. */
8c2ac482 546
338b1bb2
JR
547extern char unspecified_fg[], unspecified_bg[];
548
549
550/* Given a color index, return its standard name. */
551Lisp_Object
552vga_stdcolor_name (int idx)
8c2ac482 553{
338b1bb2
JR
554 /* Standard VGA colors, in the order of their standard numbering
555 in the default VGA palette. */
556 static char *vga_colors[16] = {
557 "black", "blue", "green", "cyan", "red", "magenta", "brown",
558 "lightgray", "darkgray", "lightblue", "lightgreen", "lightcyan",
559 "lightred", "lightmagenta", "yellow", "white"
560 };
561
562 extern Lisp_Object Qunspecified;
563
564 if (idx >= 0 && idx < sizeof (vga_colors) / sizeof (vga_colors[0]))
565 return build_string (vga_colors[idx]);
566 else
567 return Qunspecified; /* meaning the default */
8c2ac482 568}
338b1bb2 569
6cdfb6e6
RS
570typedef int (*term_hook) ();
571
572void
e6b20d65 573initialize_w32_display (void)
6cdfb6e6
RS
574{
575 CONSOLE_SCREEN_BUFFER_INFO info;
576
f3d268f9
GV
577 cursor_to_hook = move_cursor;
578 raw_cursor_to_hook = move_cursor;
579 clear_to_end_hook = clear_to_end;
580 clear_frame_hook = clear_frame;
581 clear_end_of_line_hook = clear_end_of_line;
582 ins_del_lines_hook = ins_del_lines;
f3d268f9
GV
583 insert_glyphs_hook = insert_glyphs;
584 write_glyphs_hook = write_glyphs;
585 delete_glyphs_hook = delete_glyphs;
586 ring_bell_hook = w32_sys_ring_bell;
587 reset_terminal_modes_hook = reset_terminal_modes;
588 set_terminal_modes_hook = set_terminal_modes;
589 set_terminal_window_hook = set_terminal_window;
590 update_begin_hook = update_begin;
591 update_end_hook = update_end;
6cdfb6e6 592
fbd6baed 593 read_socket_hook = w32_console_read_socket;
f3d268f9 594 mouse_position_hook = w32_console_mouse_position;
8c2ac482 595 estimate_mode_line_height_hook = 0;
3e671d90 596
c1e06681
AI
597 /* Initialize interrupt_handle. */
598 init_crit ();
599
3e671d90
GV
600 /* Remember original console settings. */
601 keyboard_handle = GetStdHandle (STD_INPUT_HANDLE);
602 GetConsoleMode (keyboard_handle, &prev_console_mode);
603
6cdfb6e6
RS
604 prev_screen = GetStdHandle (STD_OUTPUT_HANDLE);
605
3e671d90
GV
606#ifdef USE_SEPARATE_SCREEN
607 cur_screen = CreateConsoleScreenBuffer (GENERIC_READ | GENERIC_WRITE,
608 0, NULL,
609 CONSOLE_TEXTMODE_BUFFER,
610 NULL);
611
612 if (cur_screen == INVALID_HANDLE_VALUE)
613 {
614 printf ("CreateConsoleScreenBuffer failed in ResetTerm\n");
615 printf ("LastError = 0x%lx\n", GetLastError ());
616 fflush (stdout);
617 exit (0);
618 }
619#else
620 cur_screen = prev_screen;
621 GetConsoleCursorInfo (prev_screen, &prev_console_cursor);
622#endif
623
191100f2
AI
624 /* Respect setting of LINES and COLUMNS environment variables. */
625 {
626 char * lines = getenv("LINES");
627 char * columns = getenv("COLUMNS");
628
629 if (lines != NULL && columns != NULL)
630 {
631 SMALL_RECT new_win_dims;
632 COORD new_size;
633
634 new_size.X = atoi (columns);
635 new_size.Y = atoi (lines);
636
637 GetConsoleScreenBufferInfo (cur_screen, &info);
638
639 /* Shrink the window first, so the buffer dimensions can be
640 reduced if necessary. */
641 new_win_dims.Top = 0;
642 new_win_dims.Left = 0;
643 new_win_dims.Bottom = min (new_size.Y, info.dwSize.Y) - 1;
644 new_win_dims.Right = min (new_size.X, info.dwSize.X) - 1;
645 SetConsoleWindowInfo (cur_screen, TRUE, &new_win_dims);
646
647 SetConsoleScreenBufferSize (cur_screen, new_size);
648
649 /* Set the window size to match the buffer dimension. */
650 new_win_dims.Top = 0;
651 new_win_dims.Left = 0;
652 new_win_dims.Bottom = new_size.Y - 1;
653 new_win_dims.Right = new_size.X - 1;
654 SetConsoleWindowInfo (cur_screen, TRUE, &new_win_dims);
655 }
656 }
657
6cdfb6e6
RS
658 GetConsoleScreenBufferInfo (cur_screen, &info);
659
660 meta_key = 1;
338b1bb2 661 char_attr_normal = info.wAttributes;
938469f2 662
191100f2
AI
663 if (w32_use_full_screen_buffer)
664 {
8c2ac482
JR
665 FRAME_HEIGHT (SELECTED_FRAME ()) = info.dwSize.Y; /* lines per page */
666 SET_FRAME_WIDTH (SELECTED_FRAME (), info.dwSize.X); /* characters per line */
191100f2
AI
667 }
668 else
669 {
670 /* Lines per page. Use buffer coords instead of buffer size. */
8c2ac482 671 FRAME_HEIGHT (SELECTED_FRAME ()) = 1 + info.srWindow.Bottom -
191100f2
AI
672 info.srWindow.Top;
673 /* Characters per line. Use buffer coords instead of buffer size. */
8c2ac482 674 SET_FRAME_WIDTH (SELECTED_FRAME (), 1 + info.srWindow.Right -
191100f2
AI
675 info.srWindow.Left);
676 }
65fb143c
JR
677
678 /* Setup w32_display_info structure for this frame. */
679
680 w32_initialize_display_info (build_string ("Console"));
681
6cdfb6e6
RS
682}
683
684DEFUN ("set-screen-color", Fset_screen_color, Sset_screen_color, 2, 2, 0,
685 "Set screen colors.")
686 (foreground, background)
687 Lisp_Object foreground;
688 Lisp_Object background;
689{
690 char_attr_normal = XFASTINT (foreground) + (XFASTINT (background) << 4);
6cdfb6e6
RS
691
692 Frecenter (Qnil);
693 return Qt;
694}
695
696DEFUN ("set-cursor-size", Fset_cursor_size, Sset_cursor_size, 1, 1, 0,
697 "Set cursor size.")
698 (size)
699 Lisp_Object size;
700{
701 CONSOLE_CURSOR_INFO cci;
702 cci.dwSize = XFASTINT (size);
703 cci.bVisible = TRUE;
704 (void) SetConsoleCursorInfo (cur_screen, &cci);
705
706 return Qt;
707}
708
6e72ba86 709#ifndef HAVE_NTGUI
6cdfb6e6 710void
8c2ac482 711pixel_to_glyph_coords (struct frame * f, int pix_x, int pix_y, int *x, int *y,
6cdfb6e6
RS
712 void *bounds, int noclip)
713{
714 *x = pix_x;
715 *y = pix_y;
716}
717
718void
5101dbdf 719glyph_to_pixel_coords (struct window * f, int x, int y, int *pix_x, int *pix_y)
6cdfb6e6
RS
720{
721 *pix_x = x;
722 *pix_y = y;
723}
6e72ba86 724#endif /* !HAVE_NTGUI */
6cdfb6e6 725
0534d577 726void
6cdfb6e6
RS
727syms_of_ntterm ()
728{
191100f2
AI
729 DEFVAR_BOOL ("w32-use-full-screen-buffer",
730 &w32_use_full_screen_buffer,
731 "Non-nil means make terminal frames use the full screen buffer dimensions.\n\
732This is desirable when running Emacs over telnet, and is the default.\n\
733A value of nil means use the current console window dimensions; this\n\
734may be preferrable when working directly at the console with a large\n\
735scroll-back buffer.");
736 w32_use_full_screen_buffer = 1;
737
6cdfb6e6
RS
738 defsubr (&Sset_screen_color);
739 defsubr (&Sset_cursor_size);
0534d577 740 defsubr (&Sset_message_beep);
6cdfb6e6 741}