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