; NEWS: Update Org version number
[emacs.git] / src / w32console.c
blob15d11d56ad799d489b0fb95e892442aa16231e67
1 /* Terminal hooks for GNU Emacs on the Microsoft Windows API.
2 Copyright (C) 1992, 1999, 2001-2017 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 <https://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: %lu\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: %lu\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 char_attr = char_attr_normal;
616 /* Reverse the default color if requested. If background and
617 foreground are specified, then they have been reversed already. */
618 if (face->tty_reverse_p)
619 char_attr = (char_attr & 0xff00) + ((char_attr & 0x000f) << 4)
620 + ((char_attr & 0x00f0) >> 4);
622 /* Before the terminal is properly initialized, all colors map to 0.
623 Don't try to resolve them. */
624 if (NILP (Vtty_defined_color_alist))
625 return char_attr;
627 /* Colors should be in the range 0...15 unless they are one of
628 FACE_TTY_DEFAULT_COLOR, FACE_TTY_DEFAULT_FG_COLOR or
629 FACE_TTY_DEFAULT_BG_COLOR. Other out of range colors are
630 invalid, so it is better to use the default color if they ever
631 get through to here. */
632 if (face->foreground >= 0 && face->foreground < 16)
633 char_attr = (char_attr & 0xfff0) + face->foreground;
635 if (face->background >= 0 && face->background < 16)
636 char_attr = (char_attr & 0xff0f) + (face->background << 4);
638 return char_attr;
641 void
642 initialize_w32_display (struct terminal *term, int *width, int *height)
644 CONSOLE_SCREEN_BUFFER_INFO info;
646 term->rif = 0; /* No window based redisplay on the console. */
647 term->cursor_to_hook = w32con_move_cursor;
648 term->raw_cursor_to_hook = w32con_move_cursor;
649 term->clear_to_end_hook = w32con_clear_to_end;
650 term->clear_frame_hook = w32con_clear_frame;
651 term->clear_end_of_line_hook = w32con_clear_end_of_line;
652 term->ins_del_lines_hook = w32con_ins_del_lines;
653 term->insert_glyphs_hook = w32con_insert_glyphs;
654 term->write_glyphs_hook = w32con_write_glyphs;
655 term->delete_glyphs_hook = w32con_delete_glyphs;
656 term->ring_bell_hook = w32_sys_ring_bell;
657 term->reset_terminal_modes_hook = w32con_reset_terminal_modes;
658 term->set_terminal_modes_hook = w32con_set_terminal_modes;
659 term->set_terminal_window_hook = NULL;
660 term->update_begin_hook = w32con_update_begin;
661 term->update_end_hook = w32con_update_end;
663 term->read_socket_hook = w32_console_read_socket;
664 term->mouse_position_hook = w32_console_mouse_position;
665 term->menu_show_hook = tty_menu_show;
667 /* The following are not used on the console. */
668 term->frame_rehighlight_hook = 0;
669 term->frame_raise_lower_hook = 0;
670 term->set_vertical_scroll_bar_hook = 0;
671 term->set_horizontal_scroll_bar_hook = 0;
672 term->condemn_scroll_bars_hook = 0;
673 term->redeem_scroll_bar_hook = 0;
674 term->judge_scroll_bars_hook = 0;
675 term->frame_up_to_date_hook = 0;
677 /* Initialize the mouse-highlight data. */
678 reset_mouse_highlight (&term->display_info.tty->mouse_highlight);
680 /* Initialize interrupt_handle. */
681 init_crit ();
683 /* Remember original console settings. */
684 keyboard_handle = GetStdHandle (STD_INPUT_HANDLE);
685 GetConsoleMode (keyboard_handle, &prev_console_mode);
687 prev_screen = GetStdHandle (STD_OUTPUT_HANDLE);
689 #ifdef USE_SEPARATE_SCREEN
690 cur_screen = CreateConsoleScreenBuffer (GENERIC_READ | GENERIC_WRITE,
691 0, NULL,
692 CONSOLE_TEXTMODE_BUFFER,
693 NULL);
695 if (cur_screen == INVALID_HANDLE_VALUE)
697 printf ("CreateConsoleScreenBuffer failed in ResetTerm\n");
698 printf ("LastError = 0x%lx\n", GetLastError ());
699 fflush (stdout);
700 exit (0);
702 #else
703 cur_screen = prev_screen;
704 GetConsoleCursorInfo (prev_screen, &prev_console_cursor);
705 #endif
707 /* Respect setting of LINES and COLUMNS environment variables. */
709 char * lines = getenv ("LINES");
710 char * columns = getenv ("COLUMNS");
712 if (lines != NULL && columns != NULL)
714 SMALL_RECT new_win_dims;
715 COORD new_size;
717 new_size.X = atoi (columns);
718 new_size.Y = atoi (lines);
720 GetConsoleScreenBufferInfo (cur_screen, &info);
722 /* Shrink the window first, so the buffer dimensions can be
723 reduced if necessary. */
724 new_win_dims.Top = 0;
725 new_win_dims.Left = 0;
726 new_win_dims.Bottom = min (new_size.Y, info.dwSize.Y) - 1;
727 new_win_dims.Right = min (new_size.X, info.dwSize.X) - 1;
728 SetConsoleWindowInfo (cur_screen, TRUE, &new_win_dims);
730 SetConsoleScreenBufferSize (cur_screen, new_size);
732 /* Set the window size to match the buffer dimension. */
733 new_win_dims.Top = 0;
734 new_win_dims.Left = 0;
735 new_win_dims.Bottom = new_size.Y - 1;
736 new_win_dims.Right = new_size.X - 1;
737 SetConsoleWindowInfo (cur_screen, TRUE, &new_win_dims);
741 GetConsoleScreenBufferInfo (cur_screen, &info);
743 char_attr_normal = info.wAttributes;
745 /* Determine if the info returned by GetConsoleScreenBufferInfo
746 is realistic. Old MS Telnet servers used to only fill out
747 the dwSize portion, even modern one fill the whole struct with
748 garbage when using non-MS telnet clients. */
749 if ((w32_use_full_screen_buffer
750 && (info.dwSize.Y < 20 || info.dwSize.Y > 100
751 || info.dwSize.X < 40 || info.dwSize.X > 200))
752 || (!w32_use_full_screen_buffer
753 && (info.srWindow.Bottom - info.srWindow.Top < 20
754 || info.srWindow.Bottom - info.srWindow.Top > 100
755 || info.srWindow.Right - info.srWindow.Left < 40
756 || info.srWindow.Right - info.srWindow.Left > 100)))
758 *height = 25;
759 *width = 80;
762 else if (w32_use_full_screen_buffer)
764 *height = info.dwSize.Y; /* lines per page */
765 *width = info.dwSize.X; /* characters per line */
767 else
769 /* Lines per page. Use buffer coords instead of buffer size. */
770 *height = 1 + info.srWindow.Bottom - info.srWindow.Top;
771 /* Characters per line. Use buffer coords instead of buffer size. */
772 *width = 1 + info.srWindow.Right - info.srWindow.Left;
775 if (os_subtype == OS_NT)
776 w32_console_unicode_input = 1;
777 else
778 w32_console_unicode_input = 0;
780 /* Setup w32_display_info structure for this frame. */
781 w32_initialize_display_info (build_string ("Console"));
783 /* Set up the keyboard hook. */
784 setup_w32_kbdhook ();
788 DEFUN ("set-screen-color", Fset_screen_color, Sset_screen_color, 2, 2, 0,
789 doc: /* Set screen foreground and background colors.
791 Arguments should be indices between 0 and 15, see w32console.el. */)
792 (Lisp_Object foreground, Lisp_Object background)
794 char_attr_normal = XFASTINT (foreground) + (XFASTINT (background) << 4);
796 Frecenter (Qnil);
797 return Qt;
800 DEFUN ("get-screen-color", Fget_screen_color, Sget_screen_color, 0, 0, 0,
801 doc: /* Get color indices of the current screen foreground and background.
803 The colors are returned as a list of 2 indices (FOREGROUND BACKGROUND).
804 See w32console.el and `tty-defined-color-alist' for mapping of indices
805 to colors. */)
806 (void)
808 return Fcons (make_number (char_attr_normal & 0x000f),
809 Fcons (make_number ((char_attr_normal >> 4) & 0x000f), Qnil));
812 DEFUN ("set-cursor-size", Fset_cursor_size, Sset_cursor_size, 1, 1, 0,
813 doc: /* Set cursor size. */)
814 (Lisp_Object size)
816 CONSOLE_CURSOR_INFO cci;
817 cci.dwSize = XFASTINT (size);
818 cci.bVisible = TRUE;
819 (void) SetConsoleCursorInfo (cur_screen, &cci);
821 return Qt;
824 void
825 syms_of_ntterm (void)
827 DEFVAR_BOOL ("w32-use-full-screen-buffer",
828 w32_use_full_screen_buffer,
829 doc: /* Non-nil means make terminal frames use the full screen buffer dimensions.
830 This is desirable when running Emacs over telnet.
831 A value of nil means use the current console window dimensions; this
832 may be preferable when working directly at the console with a large
833 scroll-back buffer. */);
834 w32_use_full_screen_buffer = 0;
836 defsubr (&Sset_screen_color);
837 defsubr (&Sget_screen_color);
838 defsubr (&Sset_cursor_size);