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