Don’t use only last protocol from getaddrinfo
[emacs.git] / src / w32console.c
blob98343a6c4ff0791359b420d68130df3116c873d4
1 /* Terminal hooks for GNU Emacs on the Microsoft Windows API.
2 Copyright (C) 1992, 1999, 2001-2016 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or (at
9 your option) any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 Tim Fleehart (apollo@online.com) 1-17-92
21 Geoff Voelker (voelker@cs.washington.edu) 9-12-93
25 #include <config.h>
27 #include <stdio.h>
28 #include <windows.h>
30 #include "lisp.h"
31 #include "coding.h"
32 #include "termchar.h" /* for FRAME_TTY */
33 #include "menu.h" /* for tty_menu_show */
34 #include "w32term.h"
35 #include "w32common.h" /* for os_subtype */
36 #include "w32inevt.h"
38 #ifdef WINDOWSNT
39 #include "w32.h" /* for syms_of_ntterm */
40 #endif
42 static void w32con_move_cursor (struct frame *f, int row, int col);
43 static void w32con_clear_to_end (struct frame *f);
44 static void w32con_clear_frame (struct frame *f);
45 static void w32con_clear_end_of_line (struct frame *f, int);
46 static void w32con_ins_del_lines (struct frame *f, int vpos, int n);
47 static void w32con_insert_glyphs (struct frame *f, struct glyph *start, int len);
48 static void w32con_write_glyphs (struct frame *f, struct glyph *string, int len);
49 static void w32con_delete_glyphs (struct frame *f, int n);
50 static void w32con_reset_terminal_modes (struct terminal *t);
51 static void w32con_set_terminal_modes (struct terminal *t);
52 static void w32con_update_begin (struct frame * f);
53 static void w32con_update_end (struct frame * f);
54 static WORD w32_face_attributes (struct frame *f, int face_id);
56 static COORD cursor_coords;
57 static HANDLE prev_screen, cur_screen;
58 static WORD char_attr_normal;
59 static DWORD prev_console_mode;
61 static CONSOLE_CURSOR_INFO console_cursor_info;
62 #ifndef USE_SEPARATE_SCREEN
63 static CONSOLE_CURSOR_INFO prev_console_cursor;
64 #endif
66 HANDLE keyboard_handle;
67 int w32_console_unicode_input;
70 /* Setting this as the ctrl handler prevents emacs from being killed when
71 someone hits ^C in a 'suspended' session (child shell).
72 Also ignore Ctrl-Break signals. */
74 BOOL ctrl_c_handler (unsigned long);
76 BOOL
77 ctrl_c_handler (unsigned long type)
79 /* Only ignore "interrupt" events when running interactively. */
80 return (!noninteractive
81 && (type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT));
85 /* Move the cursor to (ROW, COL) on FRAME. */
86 static void
87 w32con_move_cursor (struct frame *f, int row, int col)
89 cursor_coords.X = col;
90 cursor_coords.Y = row;
92 /* TODO: for multi-tty support, cur_screen should be replaced with a
93 reference to the terminal for this frame. */
94 SetConsoleCursorPosition (cur_screen, cursor_coords);
97 void
98 w32con_hide_cursor (void)
100 GetConsoleCursorInfo (cur_screen, &console_cursor_info);
101 console_cursor_info.bVisible = FALSE;
102 SetConsoleCursorInfo (cur_screen, &console_cursor_info);
105 void
106 w32con_show_cursor (void)
108 GetConsoleCursorInfo (cur_screen, &console_cursor_info);
109 console_cursor_info.bVisible = TRUE;
110 SetConsoleCursorInfo (cur_screen, &console_cursor_info);
113 /* Clear from cursor to end of screen. */
114 static void
115 w32con_clear_to_end (struct frame *f)
117 w32con_clear_end_of_line (f, FRAME_COLS (f) - 1);
118 w32con_ins_del_lines (f, cursor_coords.Y, FRAME_TOTAL_LINES (f) - cursor_coords.Y - 1);
121 /* Clear the frame. */
122 static void
123 w32con_clear_frame (struct frame *f)
125 COORD dest;
126 int n;
127 DWORD r;
128 CONSOLE_SCREEN_BUFFER_INFO info;
130 GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &info);
132 /* Remember that the screen buffer might be wider than the window. */
133 n = FRAME_TOTAL_LINES (f) * info.dwSize.X;
134 dest.X = dest.Y = 0;
136 FillConsoleOutputAttribute (cur_screen, char_attr_normal, n, dest, &r);
137 FillConsoleOutputCharacter (cur_screen, ' ', n, dest, &r);
139 w32con_move_cursor (f, 0, 0);
143 static struct glyph glyph_base[256];
144 static BOOL ceol_initialized = FALSE;
146 /* Clear from Cursor to end (what's "standout marker"?). */
147 static void
148 w32con_clear_end_of_line (struct frame *f, int end)
150 if (!ceol_initialized)
152 int i;
153 for (i = 0; i < 256; i++)
155 memcpy (&glyph_base[i], &space_glyph, sizeof (struct glyph));
157 ceol_initialized = TRUE;
159 w32con_write_glyphs (f, glyph_base, end - cursor_coords.X); /* fencepost ? */
162 /* Insert n lines at vpos. if n is negative delete -n lines. */
163 static void
164 w32con_ins_del_lines (struct frame *f, int vpos, int n)
166 int i, nb;
167 SMALL_RECT scroll;
168 SMALL_RECT clip;
169 COORD dest;
170 CHAR_INFO fill;
172 if (n < 0)
174 scroll.Top = vpos - n;
175 scroll.Bottom = FRAME_TOTAL_LINES (f);
176 dest.Y = vpos;
178 else
180 scroll.Top = vpos;
181 scroll.Bottom = FRAME_TOTAL_LINES (f) - n;
182 dest.Y = vpos + n;
184 clip.Top = clip.Left = scroll.Left = 0;
185 clip.Right = scroll.Right = FRAME_COLS (f);
186 clip.Bottom = FRAME_TOTAL_LINES (f);
188 dest.X = 0;
190 fill.Char.AsciiChar = 0x20;
191 fill.Attributes = char_attr_normal;
193 ScrollConsoleScreenBuffer (cur_screen, &scroll, &clip, dest, &fill);
195 /* Here we have to deal with a w32 console flake: If the scroll
196 region looks like abc and we scroll c to a and fill with d we get
197 cbd... if we scroll block c one line at a time to a, we get cdd...
198 Emacs expects cdd consistently... So we have to deal with that
199 here... (this also occurs scrolling the same way in the other
200 direction. */
202 if (n > 0)
204 if (scroll.Bottom < dest.Y)
206 for (i = scroll.Bottom; i < dest.Y; i++)
208 w32con_move_cursor (f, i, 0);
209 w32con_clear_end_of_line (f, FRAME_COLS (f));
213 else
215 nb = dest.Y + (scroll.Bottom - scroll.Top) + 1;
217 if (nb < scroll.Top)
219 for (i = nb; i < scroll.Top; i++)
221 w32con_move_cursor (f, i, 0);
222 w32con_clear_end_of_line (f, FRAME_COLS (f));
227 cursor_coords.X = 0;
228 cursor_coords.Y = vpos;
231 #undef LEFT
232 #undef RIGHT
233 #define LEFT 1
234 #define RIGHT 0
236 static void
237 scroll_line (struct frame *f, int dist, int direction)
239 /* The idea here is to implement a horizontal scroll in one line to
240 implement delete and half of insert. */
241 SMALL_RECT scroll, clip;
242 COORD dest;
243 CHAR_INFO fill;
245 clip.Top = scroll.Top = clip.Bottom = scroll.Bottom = cursor_coords.Y;
246 clip.Left = 0;
247 clip.Right = FRAME_COLS (f);
249 if (direction == LEFT)
251 scroll.Left = cursor_coords.X + dist;
252 scroll.Right = FRAME_COLS (f) - 1;
254 else
256 scroll.Left = cursor_coords.X;
257 scroll.Right = FRAME_COLS (f) - dist - 1;
260 dest.X = cursor_coords.X;
261 dest.Y = cursor_coords.Y;
263 fill.Char.AsciiChar = 0x20;
264 fill.Attributes = char_attr_normal;
266 ScrollConsoleScreenBuffer (cur_screen, &scroll, &clip, dest, &fill);
270 /* If start is zero insert blanks instead of a string at start ?. */
271 static void
272 w32con_insert_glyphs (struct frame *f, register struct glyph *start,
273 register int len)
275 scroll_line (f, len, RIGHT);
277 /* Move len chars to the right starting at cursor_coords, fill with blanks */
278 if (start)
280 /* Print the first len characters of start, cursor_coords.X adjusted
281 by write_glyphs. */
283 w32con_write_glyphs (f, start, len);
285 else
287 w32con_clear_end_of_line (f, cursor_coords.X + len);
291 static void
292 w32con_write_glyphs (struct frame *f, register struct glyph *string,
293 register int len)
295 DWORD r;
296 WORD char_attr;
297 LPCSTR conversion_buffer;
298 struct coding_system *coding;
300 if (len <= 0)
301 return;
303 /* If terminal_coding does any conversion, use it, otherwise use
304 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
305 because it always return 1 if the member src_multibyte is 1. */
306 coding = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK
307 ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding);
308 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
309 the tail. */
310 coding->mode &= ~CODING_MODE_LAST_BLOCK;
312 while (len > 0)
314 /* Identify a run of glyphs with the same face. */
315 int face_id = string->face_id;
316 int n;
318 for (n = 1; n < len; ++n)
319 if (string[n].face_id != face_id)
320 break;
322 /* Turn appearance modes of the face of the run on. */
323 char_attr = w32_face_attributes (f, face_id);
325 if (n == len)
326 /* This is the last run. */
327 coding->mode |= CODING_MODE_LAST_BLOCK;
328 conversion_buffer = (LPCSTR) encode_terminal_code (string, n, coding);
329 if (coding->produced > 0)
331 /* Set the attribute for these characters. */
332 if (!FillConsoleOutputAttribute (cur_screen, char_attr,
333 coding->produced, cursor_coords,
334 &r))
336 printf ("Failed writing console attributes: %d\n",
337 GetLastError ());
338 fflush (stdout);
341 /* Write the characters. */
342 if (!WriteConsoleOutputCharacter (cur_screen, conversion_buffer,
343 coding->produced, cursor_coords,
344 &r))
346 printf ("Failed writing console characters: %d\n",
347 GetLastError ());
348 fflush (stdout);
351 cursor_coords.X += coding->produced;
352 w32con_move_cursor (f, cursor_coords.Y, cursor_coords.X);
354 len -= n;
355 string += n;
359 /* Used for mouse highlight. */
360 static void
361 w32con_write_glyphs_with_face (struct frame *f, register int x, register int y,
362 register struct glyph *string, register int len,
363 register int face_id)
365 LPCSTR conversion_buffer;
366 struct coding_system *coding;
368 if (len <= 0)
369 return;
371 /* If terminal_coding does any conversion, use it, otherwise use
372 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
373 because it always return 1 if the member src_multibyte is 1. */
374 coding = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK
375 ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding);
376 /* We are going to write the entire block of glyphs in one go, as
377 they all have the same face. So this _is_ the last block. */
378 coding->mode |= CODING_MODE_LAST_BLOCK;
380 conversion_buffer = (LPCSTR) encode_terminal_code (string, len, coding);
381 if (coding->produced > 0)
383 DWORD filled, written;
384 /* Compute the character attributes corresponding to the face. */
385 DWORD char_attr = w32_face_attributes (f, face_id);
386 COORD start_coords;
388 start_coords.X = x;
389 start_coords.Y = y;
390 /* Set the attribute for these characters. */
391 if (!FillConsoleOutputAttribute (cur_screen, char_attr,
392 coding->produced, start_coords,
393 &filled))
394 DebPrint (("Failed writing console attributes: %d\n", GetLastError ()));
395 else
397 /* Write the characters. */
398 if (!WriteConsoleOutputCharacter (cur_screen, conversion_buffer,
399 filled, start_coords, &written))
400 DebPrint (("Failed writing console characters: %d\n",
401 GetLastError ()));
406 /* Implementation of draw_row_with_mouse_face for W32 console. */
407 void
408 tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row,
409 int start_hpos, int end_hpos,
410 enum draw_glyphs_face draw)
412 int nglyphs = end_hpos - start_hpos;
413 struct frame *f = XFRAME (WINDOW_FRAME (w));
414 struct tty_display_info *tty = FRAME_TTY (f);
415 int face_id = tty->mouse_highlight.mouse_face_face_id;
416 int pos_x, pos_y;
418 if (end_hpos >= row->used[TEXT_AREA])
419 nglyphs = row->used[TEXT_AREA] - start_hpos;
421 pos_y = row->y + WINDOW_TOP_EDGE_Y (w);
422 pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos + WINDOW_LEFT_EDGE_X (w);
424 if (draw == DRAW_MOUSE_FACE)
425 w32con_write_glyphs_with_face (f, pos_x, pos_y,
426 row->glyphs[TEXT_AREA] + start_hpos,
427 nglyphs, face_id);
428 else if (draw == DRAW_NORMAL_TEXT)
430 COORD save_coords = cursor_coords;
432 w32con_move_cursor (f, pos_y, pos_x);
433 write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
434 w32con_move_cursor (f, save_coords.Y, save_coords.X);
438 static void
439 w32con_delete_glyphs (struct frame *f, int n)
441 /* delete chars means scroll chars from cursor_coords.X + n to
442 cursor_coords.X, anything beyond the edge of the screen should
443 come out empty... */
445 scroll_line (f, n, LEFT);
449 static void
450 w32con_reset_terminal_modes (struct terminal *t)
452 COORD dest;
453 CONSOLE_SCREEN_BUFFER_INFO info;
454 int n;
455 DWORD r;
457 /* Clear the complete screen buffer. This is required because Emacs
458 sets the cursor position to the top of the buffer, but there might
459 be other output below the bottom of the Emacs frame if the screen buffer
460 is larger than the window size. */
461 GetConsoleScreenBufferInfo (cur_screen, &info);
462 dest.X = 0;
463 dest.Y = 0;
464 n = info.dwSize.X * info.dwSize.Y;
466 FillConsoleOutputAttribute (cur_screen, char_attr_normal, n, dest, &r);
467 FillConsoleOutputCharacter (cur_screen, ' ', n, dest, &r);
468 /* Now that the screen is clear, put the cursor at the top. */
469 SetConsoleCursorPosition (cur_screen, dest);
471 #ifdef USE_SEPARATE_SCREEN
472 SetConsoleActiveScreenBuffer (prev_screen);
473 #else
474 SetConsoleCursorInfo (prev_screen, &prev_console_cursor);
475 #endif
477 SetConsoleMode (keyboard_handle, prev_console_mode);
480 static void
481 w32con_set_terminal_modes (struct terminal *t)
483 CONSOLE_CURSOR_INFO cci;
485 /* make cursor big and visible (100 on Windows 95 makes it disappear) */
486 cci.dwSize = 99;
487 cci.bVisible = TRUE;
488 (void) SetConsoleCursorInfo (cur_screen, &cci);
490 SetConsoleActiveScreenBuffer (cur_screen);
492 SetConsoleMode (keyboard_handle, ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT);
494 /* Initialize input mode: interrupt_input off, no flow control, allow
495 8 bit character input, standard quit char. */
496 Fset_input_mode (Qnil, Qnil, make_number (2), Qnil);
499 /* hmmm... perhaps these let us bracket screen changes so that we can flush
500 clumps rather than one-character-at-a-time...
502 we'll start with not moving the cursor while an update is in progress. */
503 static void
504 w32con_update_begin (struct frame * f)
508 static void
509 w32con_update_end (struct frame * f)
511 SetConsoleCursorPosition (cur_screen, cursor_coords);
514 /***********************************************************************
515 stubs from termcap.c
516 ***********************************************************************/
518 void sys_tputs (char *, int, int (*) (int));
520 void
521 sys_tputs (char *str, int nlines, int (*outfun) (int))
525 char *sys_tgetstr (char *, char **);
527 char *
528 sys_tgetstr (char *cap, char **area)
530 return NULL;
534 /***********************************************************************
535 stubs from cm.c
536 ***********************************************************************/
538 struct tty_display_info *current_tty = NULL;
539 int cost = 0;
541 int evalcost (int);
544 evalcost (int c)
546 return c;
549 int cmputc (int);
552 cmputc (int c)
554 return c;
557 void cmcheckmagic (struct tty_display_info *);
559 void
560 cmcheckmagic (struct tty_display_info *tty)
564 void cmcostinit (struct tty_display_info *);
566 void
567 cmcostinit (struct tty_display_info *tty)
571 void cmgoto (struct tty_display_info *, int, int);
573 void
574 cmgoto (struct tty_display_info *tty, int row, int col)
578 void Wcm_clear (struct tty_display_info *);
580 void
581 Wcm_clear (struct tty_display_info *tty)
586 /* Report the current cursor position. The following two functions
587 are used in term.c's tty menu code, so they are not really
588 "stubs". */
590 cursorX (struct tty_display_info *tty)
592 return cursor_coords.X;
596 cursorY (struct tty_display_info *tty)
598 return cursor_coords.Y;
601 /***********************************************************************
602 Faces
603 ***********************************************************************/
606 /* Turn appearances of face FACE_ID on tty frame F on. */
608 static WORD
609 w32_face_attributes (struct frame *f, int face_id)
611 WORD char_attr;
612 struct face *face = FACE_FROM_ID (f, face_id);
614 eassert (face != NULL);
616 char_attr = char_attr_normal;
618 /* Reverse the default color if requested. If background and
619 foreground are specified, then they have been reversed already. */
620 if (face->tty_reverse_p)
621 char_attr = (char_attr & 0xff00) + ((char_attr & 0x000f) << 4)
622 + ((char_attr & 0x00f0) >> 4);
624 /* Before the terminal is properly initialized, all colors map to 0.
625 Don't try to resolve them. */
626 if (NILP (Vtty_defined_color_alist))
627 return char_attr;
629 /* Colors should be in the range 0...15 unless they are one of
630 FACE_TTY_DEFAULT_COLOR, FACE_TTY_DEFAULT_FG_COLOR or
631 FACE_TTY_DEFAULT_BG_COLOR. Other out of range colors are
632 invalid, so it is better to use the default color if they ever
633 get through to here. */
634 if (face->foreground >= 0 && face->foreground < 16)
635 char_attr = (char_attr & 0xfff0) + face->foreground;
637 if (face->background >= 0 && face->background < 16)
638 char_attr = (char_attr & 0xff0f) + (face->background << 4);
640 return char_attr;
643 void
644 initialize_w32_display (struct terminal *term, int *width, int *height)
646 CONSOLE_SCREEN_BUFFER_INFO info;
648 term->rif = 0; /* No window based redisplay on the console. */
649 term->cursor_to_hook = w32con_move_cursor;
650 term->raw_cursor_to_hook = w32con_move_cursor;
651 term->clear_to_end_hook = w32con_clear_to_end;
652 term->clear_frame_hook = w32con_clear_frame;
653 term->clear_end_of_line_hook = w32con_clear_end_of_line;
654 term->ins_del_lines_hook = w32con_ins_del_lines;
655 term->insert_glyphs_hook = w32con_insert_glyphs;
656 term->write_glyphs_hook = w32con_write_glyphs;
657 term->delete_glyphs_hook = w32con_delete_glyphs;
658 term->ring_bell_hook = w32_sys_ring_bell;
659 term->reset_terminal_modes_hook = w32con_reset_terminal_modes;
660 term->set_terminal_modes_hook = w32con_set_terminal_modes;
661 term->set_terminal_window_hook = NULL;
662 term->update_begin_hook = w32con_update_begin;
663 term->update_end_hook = w32con_update_end;
665 term->read_socket_hook = w32_console_read_socket;
666 term->mouse_position_hook = w32_console_mouse_position;
667 term->menu_show_hook = tty_menu_show;
669 /* The following are not used on the console. */
670 term->frame_rehighlight_hook = 0;
671 term->frame_raise_lower_hook = 0;
672 term->set_vertical_scroll_bar_hook = 0;
673 term->set_horizontal_scroll_bar_hook = 0;
674 term->condemn_scroll_bars_hook = 0;
675 term->redeem_scroll_bar_hook = 0;
676 term->judge_scroll_bars_hook = 0;
677 term->frame_up_to_date_hook = 0;
679 /* Initialize the mouse-highlight data. */
680 reset_mouse_highlight (&term->display_info.tty->mouse_highlight);
682 /* Initialize interrupt_handle. */
683 init_crit ();
685 /* Remember original console settings. */
686 keyboard_handle = GetStdHandle (STD_INPUT_HANDLE);
687 GetConsoleMode (keyboard_handle, &prev_console_mode);
689 prev_screen = GetStdHandle (STD_OUTPUT_HANDLE);
691 #ifdef USE_SEPARATE_SCREEN
692 cur_screen = CreateConsoleScreenBuffer (GENERIC_READ | GENERIC_WRITE,
693 0, NULL,
694 CONSOLE_TEXTMODE_BUFFER,
695 NULL);
697 if (cur_screen == INVALID_HANDLE_VALUE)
699 printf ("CreateConsoleScreenBuffer failed in ResetTerm\n");
700 printf ("LastError = 0x%lx\n", GetLastError ());
701 fflush (stdout);
702 exit (0);
704 #else
705 cur_screen = prev_screen;
706 GetConsoleCursorInfo (prev_screen, &prev_console_cursor);
707 #endif
709 /* Respect setting of LINES and COLUMNS environment variables. */
711 char * lines = getenv ("LINES");
712 char * columns = getenv ("COLUMNS");
714 if (lines != NULL && columns != NULL)
716 SMALL_RECT new_win_dims;
717 COORD new_size;
719 new_size.X = atoi (columns);
720 new_size.Y = atoi (lines);
722 GetConsoleScreenBufferInfo (cur_screen, &info);
724 /* Shrink the window first, so the buffer dimensions can be
725 reduced if necessary. */
726 new_win_dims.Top = 0;
727 new_win_dims.Left = 0;
728 new_win_dims.Bottom = min (new_size.Y, info.dwSize.Y) - 1;
729 new_win_dims.Right = min (new_size.X, info.dwSize.X) - 1;
730 SetConsoleWindowInfo (cur_screen, TRUE, &new_win_dims);
732 SetConsoleScreenBufferSize (cur_screen, new_size);
734 /* Set the window size to match the buffer dimension. */
735 new_win_dims.Top = 0;
736 new_win_dims.Left = 0;
737 new_win_dims.Bottom = new_size.Y - 1;
738 new_win_dims.Right = new_size.X - 1;
739 SetConsoleWindowInfo (cur_screen, TRUE, &new_win_dims);
743 GetConsoleScreenBufferInfo (cur_screen, &info);
745 char_attr_normal = info.wAttributes;
747 /* Determine if the info returned by GetConsoleScreenBufferInfo
748 is realistic. Old MS Telnet servers used to only fill out
749 the dwSize portion, even modern one fill the whole struct with
750 garbage when using non-MS telnet clients. */
751 if ((w32_use_full_screen_buffer
752 && (info.dwSize.Y < 20 || info.dwSize.Y > 100
753 || info.dwSize.X < 40 || info.dwSize.X > 200))
754 || (!w32_use_full_screen_buffer
755 && (info.srWindow.Bottom - info.srWindow.Top < 20
756 || info.srWindow.Bottom - info.srWindow.Top > 100
757 || info.srWindow.Right - info.srWindow.Left < 40
758 || info.srWindow.Right - info.srWindow.Left > 100)))
760 *height = 25;
761 *width = 80;
764 else if (w32_use_full_screen_buffer)
766 *height = info.dwSize.Y; /* lines per page */
767 *width = info.dwSize.X; /* characters per line */
769 else
771 /* Lines per page. Use buffer coords instead of buffer size. */
772 *height = 1 + info.srWindow.Bottom - info.srWindow.Top;
773 /* Characters per line. Use buffer coords instead of buffer size. */
774 *width = 1 + info.srWindow.Right - info.srWindow.Left;
777 if (os_subtype == OS_NT)
778 w32_console_unicode_input = 1;
779 else
780 w32_console_unicode_input = 0;
782 /* Setup w32_display_info structure for this frame. */
783 w32_initialize_display_info (build_string ("Console"));
785 /* Set up the keyboard hook. */
786 setup_w32_kbdhook ();
790 DEFUN ("set-screen-color", Fset_screen_color, Sset_screen_color, 2, 2, 0,
791 doc: /* Set screen foreground and background colors.
793 Arguments should be indices between 0 and 15, see w32console.el. */)
794 (Lisp_Object foreground, Lisp_Object background)
796 char_attr_normal = XFASTINT (foreground) + (XFASTINT (background) << 4);
798 Frecenter (Qnil);
799 return Qt;
802 DEFUN ("get-screen-color", Fget_screen_color, Sget_screen_color, 0, 0, 0,
803 doc: /* Get color indices of the current screen foreground and background.
805 The colors are returned as a list of 2 indices (FOREGROUND BACKGROUND).
806 See w32console.el and `tty-defined-color-alist' for mapping of indices
807 to colors. */)
808 (void)
810 return Fcons (make_number (char_attr_normal & 0x000f),
811 Fcons (make_number ((char_attr_normal >> 4) & 0x000f), Qnil));
814 DEFUN ("set-cursor-size", Fset_cursor_size, Sset_cursor_size, 1, 1, 0,
815 doc: /* Set cursor size. */)
816 (Lisp_Object size)
818 CONSOLE_CURSOR_INFO cci;
819 cci.dwSize = XFASTINT (size);
820 cci.bVisible = TRUE;
821 (void) SetConsoleCursorInfo (cur_screen, &cci);
823 return Qt;
826 void
827 syms_of_ntterm (void)
829 DEFVAR_BOOL ("w32-use-full-screen-buffer",
830 w32_use_full_screen_buffer,
831 doc: /* Non-nil means make terminal frames use the full screen buffer dimensions.
832 This is desirable when running Emacs over telnet.
833 A value of nil means use the current console window dimensions; this
834 may be preferable when working directly at the console with a large
835 scroll-back buffer. */);
836 w32_use_full_screen_buffer = 0;
838 defsubr (&Sset_screen_color);
839 defsubr (&Sget_screen_color);
840 defsubr (&Sset_cursor_size);