; Auto-commit of ChangeLog files.
[emacs.git] / src / w32console.c
blobec54f83129f4cd4c5b81333ed2de8ab0a7498eed
1 /* Terminal hooks for GNU Emacs on the Microsoft Windows API.
2 Copyright (C) 1992, 1999, 2001-2015 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
9 (at 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 static void w32con_move_cursor (struct frame *f, int row, int col);
39 static void w32con_clear_to_end (struct frame *f);
40 static void w32con_clear_frame (struct frame *f);
41 static void w32con_clear_end_of_line (struct frame *f, int);
42 static void w32con_ins_del_lines (struct frame *f, int vpos, int n);
43 static void w32con_insert_glyphs (struct frame *f, struct glyph *start, int len);
44 static void w32con_write_glyphs (struct frame *f, struct glyph *string, int len);
45 static void w32con_delete_glyphs (struct frame *f, int n);
46 static void w32con_reset_terminal_modes (struct terminal *t);
47 static void w32con_set_terminal_modes (struct terminal *t);
48 static void w32con_update_begin (struct frame * f);
49 static void w32con_update_end (struct frame * f);
50 static WORD w32_face_attributes (struct frame *f, int face_id);
52 static COORD cursor_coords;
53 static HANDLE prev_screen, cur_screen;
54 static WORD char_attr_normal;
55 static DWORD prev_console_mode;
57 static CONSOLE_CURSOR_INFO console_cursor_info;
58 #ifndef USE_SEPARATE_SCREEN
59 static CONSOLE_CURSOR_INFO prev_console_cursor;
60 #endif
62 HANDLE keyboard_handle;
63 int w32_console_unicode_input;
66 /* Setting this as the ctrl handler prevents emacs from being killed when
67 someone hits ^C in a 'suspended' session (child shell).
68 Also ignore Ctrl-Break signals. */
70 BOOL
71 ctrl_c_handler (unsigned long type)
73 /* Only ignore "interrupt" events when running interactively. */
74 return (!noninteractive
75 && (type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT));
79 /* Move the cursor to (ROW, COL) on FRAME. */
80 static void
81 w32con_move_cursor (struct frame *f, int row, int col)
83 cursor_coords.X = col;
84 cursor_coords.Y = row;
86 /* TODO: for multi-tty support, cur_screen should be replaced with a
87 reference to the terminal for this frame. */
88 SetConsoleCursorPosition (cur_screen, cursor_coords);
91 void
92 w32con_hide_cursor (void)
94 GetConsoleCursorInfo (cur_screen, &console_cursor_info);
95 console_cursor_info.bVisible = FALSE;
96 SetConsoleCursorInfo (cur_screen, &console_cursor_info);
99 void
100 w32con_show_cursor (void)
102 GetConsoleCursorInfo (cur_screen, &console_cursor_info);
103 console_cursor_info.bVisible = TRUE;
104 SetConsoleCursorInfo (cur_screen, &console_cursor_info);
107 /* Clear from cursor to end of screen. */
108 static void
109 w32con_clear_to_end (struct frame *f)
111 w32con_clear_end_of_line (f, FRAME_COLS (f) - 1);
112 w32con_ins_del_lines (f, cursor_coords.Y, FRAME_TOTAL_LINES (f) - cursor_coords.Y - 1);
115 /* Clear the frame. */
116 static void
117 w32con_clear_frame (struct frame *f)
119 COORD dest;
120 int n;
121 DWORD r;
122 CONSOLE_SCREEN_BUFFER_INFO info;
124 GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &info);
126 /* Remember that the screen buffer might be wider than the window. */
127 n = FRAME_TOTAL_LINES (f) * info.dwSize.X;
128 dest.X = dest.Y = 0;
130 FillConsoleOutputAttribute (cur_screen, char_attr_normal, n, dest, &r);
131 FillConsoleOutputCharacter (cur_screen, ' ', n, dest, &r);
133 w32con_move_cursor (f, 0, 0);
137 static struct glyph glyph_base[256];
138 static BOOL ceol_initialized = FALSE;
140 /* Clear from Cursor to end (what's "standout marker"?). */
141 static void
142 w32con_clear_end_of_line (struct frame *f, int end)
144 if (!ceol_initialized)
146 int i;
147 for (i = 0; i < 256; i++)
149 memcpy (&glyph_base[i], &space_glyph, sizeof (struct glyph));
151 ceol_initialized = TRUE;
153 w32con_write_glyphs (f, glyph_base, end - cursor_coords.X); /* fencepost ? */
156 /* Insert n lines at vpos. if n is negative delete -n lines. */
157 static void
158 w32con_ins_del_lines (struct frame *f, int vpos, int n)
160 int i, nb;
161 SMALL_RECT scroll;
162 SMALL_RECT clip;
163 COORD dest;
164 CHAR_INFO fill;
166 if (n < 0)
168 scroll.Top = vpos - n;
169 scroll.Bottom = FRAME_TOTAL_LINES (f);
170 dest.Y = vpos;
172 else
174 scroll.Top = vpos;
175 scroll.Bottom = FRAME_TOTAL_LINES (f) - n;
176 dest.Y = vpos + n;
178 clip.Top = clip.Left = scroll.Left = 0;
179 clip.Right = scroll.Right = FRAME_COLS (f);
180 clip.Bottom = FRAME_TOTAL_LINES (f);
182 dest.X = 0;
184 fill.Char.AsciiChar = 0x20;
185 fill.Attributes = char_attr_normal;
187 ScrollConsoleScreenBuffer (cur_screen, &scroll, &clip, dest, &fill);
189 /* Here we have to deal with a w32 console flake: If the scroll
190 region looks like abc and we scroll c to a and fill with d we get
191 cbd... if we scroll block c one line at a time to a, we get cdd...
192 Emacs expects cdd consistently... So we have to deal with that
193 here... (this also occurs scrolling the same way in the other
194 direction. */
196 if (n > 0)
198 if (scroll.Bottom < dest.Y)
200 for (i = scroll.Bottom; i < dest.Y; i++)
202 w32con_move_cursor (f, i, 0);
203 w32con_clear_end_of_line (f, FRAME_COLS (f));
207 else
209 nb = dest.Y + (scroll.Bottom - scroll.Top) + 1;
211 if (nb < scroll.Top)
213 for (i = nb; i < scroll.Top; i++)
215 w32con_move_cursor (f, i, 0);
216 w32con_clear_end_of_line (f, FRAME_COLS (f));
221 cursor_coords.X = 0;
222 cursor_coords.Y = vpos;
225 #undef LEFT
226 #undef RIGHT
227 #define LEFT 1
228 #define RIGHT 0
230 static void
231 scroll_line (struct frame *f, int dist, int direction)
233 /* The idea here is to implement a horizontal scroll in one line to
234 implement delete and half of insert. */
235 SMALL_RECT scroll, clip;
236 COORD dest;
237 CHAR_INFO fill;
239 clip.Top = scroll.Top = clip.Bottom = scroll.Bottom = cursor_coords.Y;
240 clip.Left = 0;
241 clip.Right = FRAME_COLS (f);
243 if (direction == LEFT)
245 scroll.Left = cursor_coords.X + dist;
246 scroll.Right = FRAME_COLS (f) - 1;
248 else
250 scroll.Left = cursor_coords.X;
251 scroll.Right = FRAME_COLS (f) - dist - 1;
254 dest.X = cursor_coords.X;
255 dest.Y = cursor_coords.Y;
257 fill.Char.AsciiChar = 0x20;
258 fill.Attributes = char_attr_normal;
260 ScrollConsoleScreenBuffer (cur_screen, &scroll, &clip, dest, &fill);
264 /* If start is zero insert blanks instead of a string at start ?. */
265 static void
266 w32con_insert_glyphs (struct frame *f, register struct glyph *start,
267 register int len)
269 scroll_line (f, len, RIGHT);
271 /* Move len chars to the right starting at cursor_coords, fill with blanks */
272 if (start)
274 /* Print the first len characters of start, cursor_coords.X adjusted
275 by write_glyphs. */
277 w32con_write_glyphs (f, start, len);
279 else
281 w32con_clear_end_of_line (f, cursor_coords.X + len);
285 static void
286 w32con_write_glyphs (struct frame *f, register struct glyph *string,
287 register int len)
289 DWORD r;
290 WORD char_attr;
291 LPCSTR conversion_buffer;
292 struct coding_system *coding;
294 if (len <= 0)
295 return;
297 /* If terminal_coding does any conversion, use it, otherwise use
298 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
299 because it always return 1 if the member src_multibyte is 1. */
300 coding = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK
301 ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding);
302 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
303 the tail. */
304 coding->mode &= ~CODING_MODE_LAST_BLOCK;
306 while (len > 0)
308 /* Identify a run of glyphs with the same face. */
309 int face_id = string->face_id;
310 int n;
312 for (n = 1; n < len; ++n)
313 if (string[n].face_id != face_id)
314 break;
316 /* Turn appearance modes of the face of the run on. */
317 char_attr = w32_face_attributes (f, face_id);
319 if (n == len)
320 /* This is the last run. */
321 coding->mode |= CODING_MODE_LAST_BLOCK;
322 conversion_buffer = (LPCSTR) encode_terminal_code (string, n, coding);
323 if (coding->produced > 0)
325 /* Set the attribute for these characters. */
326 if (!FillConsoleOutputAttribute (cur_screen, char_attr,
327 coding->produced, cursor_coords,
328 &r))
330 printf ("Failed writing console attributes: %d\n",
331 GetLastError ());
332 fflush (stdout);
335 /* Write the characters. */
336 if (!WriteConsoleOutputCharacter (cur_screen, conversion_buffer,
337 coding->produced, cursor_coords,
338 &r))
340 printf ("Failed writing console characters: %d\n",
341 GetLastError ());
342 fflush (stdout);
345 cursor_coords.X += coding->produced;
346 w32con_move_cursor (f, cursor_coords.Y, cursor_coords.X);
348 len -= n;
349 string += n;
353 /* Used for mouse highlight. */
354 static void
355 w32con_write_glyphs_with_face (struct frame *f, register int x, register int y,
356 register struct glyph *string, register int len,
357 register int face_id)
359 LPCSTR conversion_buffer;
360 struct coding_system *coding;
362 if (len <= 0)
363 return;
365 /* If terminal_coding does any conversion, use it, otherwise use
366 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
367 because it always return 1 if the member src_multibyte is 1. */
368 coding = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK
369 ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding);
370 /* We are going to write the entire block of glyphs in one go, as
371 they all have the same face. So this _is_ the last block. */
372 coding->mode |= CODING_MODE_LAST_BLOCK;
374 conversion_buffer = (LPCSTR) encode_terminal_code (string, len, coding);
375 if (coding->produced > 0)
377 DWORD filled, written;
378 /* Compute the character attributes corresponding to the face. */
379 DWORD char_attr = w32_face_attributes (f, face_id);
380 COORD start_coords;
382 start_coords.X = x;
383 start_coords.Y = y;
384 /* Set the attribute for these characters. */
385 if (!FillConsoleOutputAttribute (cur_screen, char_attr,
386 coding->produced, start_coords,
387 &filled))
388 DebPrint (("Failed writing console attributes: %d\n", GetLastError ()));
389 else
391 /* Write the characters. */
392 if (!WriteConsoleOutputCharacter (cur_screen, conversion_buffer,
393 filled, start_coords, &written))
394 DebPrint (("Failed writing console characters: %d\n",
395 GetLastError ()));
400 /* Implementation of draw_row_with_mouse_face for W32 console. */
401 void
402 tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row,
403 int start_hpos, int end_hpos,
404 enum draw_glyphs_face draw)
406 int nglyphs = end_hpos - start_hpos;
407 struct frame *f = XFRAME (WINDOW_FRAME (w));
408 struct tty_display_info *tty = FRAME_TTY (f);
409 int face_id = tty->mouse_highlight.mouse_face_face_id;
410 int pos_x, pos_y;
412 if (end_hpos >= row->used[TEXT_AREA])
413 nglyphs = row->used[TEXT_AREA] - start_hpos;
415 pos_y = row->y + WINDOW_TOP_EDGE_Y (w);
416 pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos + WINDOW_LEFT_EDGE_X (w);
418 if (draw == DRAW_MOUSE_FACE)
419 w32con_write_glyphs_with_face (f, pos_x, pos_y,
420 row->glyphs[TEXT_AREA] + start_hpos,
421 nglyphs, face_id);
422 else if (draw == DRAW_NORMAL_TEXT)
424 COORD save_coords = cursor_coords;
426 w32con_move_cursor (f, pos_y, pos_x);
427 write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
428 w32con_move_cursor (f, save_coords.Y, save_coords.X);
432 static void
433 w32con_delete_glyphs (struct frame *f, int n)
435 /* delete chars means scroll chars from cursor_coords.X + n to
436 cursor_coords.X, anything beyond the edge of the screen should
437 come out empty... */
439 scroll_line (f, n, LEFT);
443 static void
444 w32con_reset_terminal_modes (struct terminal *t)
446 COORD dest;
447 CONSOLE_SCREEN_BUFFER_INFO info;
448 int n;
449 DWORD r;
451 /* Clear the complete screen buffer. This is required because Emacs
452 sets the cursor position to the top of the buffer, but there might
453 be other output below the bottom of the Emacs frame if the screen buffer
454 is larger than the window size. */
455 GetConsoleScreenBufferInfo (cur_screen, &info);
456 dest.X = 0;
457 dest.Y = 0;
458 n = info.dwSize.X * info.dwSize.Y;
460 FillConsoleOutputAttribute (cur_screen, char_attr_normal, n, dest, &r);
461 FillConsoleOutputCharacter (cur_screen, ' ', n, dest, &r);
462 /* Now that the screen is clear, put the cursor at the top. */
463 SetConsoleCursorPosition (cur_screen, dest);
465 #ifdef USE_SEPARATE_SCREEN
466 SetConsoleActiveScreenBuffer (prev_screen);
467 #else
468 SetConsoleCursorInfo (prev_screen, &prev_console_cursor);
469 #endif
471 SetConsoleMode (keyboard_handle, prev_console_mode);
474 static void
475 w32con_set_terminal_modes (struct terminal *t)
477 CONSOLE_CURSOR_INFO cci;
479 /* make cursor big and visible (100 on Windows 95 makes it disappear) */
480 cci.dwSize = 99;
481 cci.bVisible = TRUE;
482 (void) SetConsoleCursorInfo (cur_screen, &cci);
484 SetConsoleActiveScreenBuffer (cur_screen);
486 SetConsoleMode (keyboard_handle, ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT);
488 /* Initialize input mode: interrupt_input off, no flow control, allow
489 8 bit character input, standard quit char. */
490 Fset_input_mode (Qnil, Qnil, make_number (2), Qnil);
493 /* hmmm... perhaps these let us bracket screen changes so that we can flush
494 clumps rather than one-character-at-a-time...
496 we'll start with not moving the cursor while an update is in progress. */
497 static void
498 w32con_update_begin (struct frame * f)
502 static void
503 w32con_update_end (struct frame * f)
505 SetConsoleCursorPosition (cur_screen, cursor_coords);
508 /***********************************************************************
509 stubs from termcap.c
510 ***********************************************************************/
512 void
513 sys_tputs (char *str, int nlines, int (*outfun) (int))
517 char *
518 sys_tgetstr (char *cap, char **area)
520 return NULL;
524 /***********************************************************************
525 stubs from cm.c
526 ***********************************************************************/
528 struct tty_display_info *current_tty = NULL;
529 int cost = 0;
532 evalcost (int c)
534 return c;
538 cmputc (int c)
540 return c;
543 void
544 cmcheckmagic (struct tty_display_info *tty)
548 void
549 cmcostinit (struct tty_display_info *tty)
553 void
554 cmgoto (struct tty_display_info *tty, int row, int col)
558 void
559 Wcm_clear (struct tty_display_info *tty)
564 /* Report the current cursor position. The following two functions
565 are used in term.c's tty menu code, so they are not really
566 "stubs". */
568 cursorX (struct tty_display_info *tty)
570 return cursor_coords.X;
574 cursorY (struct tty_display_info *tty)
576 return cursor_coords.Y;
579 /***********************************************************************
580 Faces
581 ***********************************************************************/
584 /* Turn appearances of face FACE_ID on tty frame F on. */
586 static WORD
587 w32_face_attributes (struct frame *f, int face_id)
589 WORD char_attr;
590 struct face *face = FACE_FROM_ID (f, face_id);
592 eassert (face != NULL);
594 char_attr = char_attr_normal;
596 /* Reverse the default color if requested. If background and
597 foreground are specified, then they have been reversed already. */
598 if (face->tty_reverse_p)
599 char_attr = (char_attr & 0xff00) + ((char_attr & 0x000f) << 4)
600 + ((char_attr & 0x00f0) >> 4);
602 /* Before the terminal is properly initialized, all colors map to 0.
603 Don't try to resolve them. */
604 if (NILP (Vtty_defined_color_alist))
605 return char_attr;
607 /* Colors should be in the range 0...15 unless they are one of
608 FACE_TTY_DEFAULT_COLOR, FACE_TTY_DEFAULT_FG_COLOR or
609 FACE_TTY_DEFAULT_BG_COLOR. Other out of range colors are
610 invalid, so it is better to use the default color if they ever
611 get through to here. */
612 if (face->foreground >= 0 && face->foreground < 16)
613 char_attr = (char_attr & 0xfff0) + face->foreground;
615 if (face->background >= 0 && face->background < 16)
616 char_attr = (char_attr & 0xff0f) + (face->background << 4);
618 return char_attr;
621 void
622 initialize_w32_display (struct terminal *term, int *width, int *height)
624 CONSOLE_SCREEN_BUFFER_INFO info;
626 term->rif = 0; /* No window based redisplay on the console. */
627 term->cursor_to_hook = w32con_move_cursor;
628 term->raw_cursor_to_hook = w32con_move_cursor;
629 term->clear_to_end_hook = w32con_clear_to_end;
630 term->clear_frame_hook = w32con_clear_frame;
631 term->clear_end_of_line_hook = w32con_clear_end_of_line;
632 term->ins_del_lines_hook = w32con_ins_del_lines;
633 term->insert_glyphs_hook = w32con_insert_glyphs;
634 term->write_glyphs_hook = w32con_write_glyphs;
635 term->delete_glyphs_hook = w32con_delete_glyphs;
636 term->ring_bell_hook = w32_sys_ring_bell;
637 term->reset_terminal_modes_hook = w32con_reset_terminal_modes;
638 term->set_terminal_modes_hook = w32con_set_terminal_modes;
639 term->set_terminal_window_hook = NULL;
640 term->update_begin_hook = w32con_update_begin;
641 term->update_end_hook = w32con_update_end;
643 term->read_socket_hook = w32_console_read_socket;
644 term->mouse_position_hook = w32_console_mouse_position;
645 term->menu_show_hook = tty_menu_show;
647 /* The following are not used on the console. */
648 term->frame_rehighlight_hook = 0;
649 term->frame_raise_lower_hook = 0;
650 term->set_vertical_scroll_bar_hook = 0;
651 term->set_horizontal_scroll_bar_hook = 0;
652 term->condemn_scroll_bars_hook = 0;
653 term->redeem_scroll_bar_hook = 0;
654 term->judge_scroll_bars_hook = 0;
655 term->frame_up_to_date_hook = 0;
657 /* Initialize the mouse-highlight data. */
658 reset_mouse_highlight (&term->display_info.tty->mouse_highlight);
660 /* Initialize interrupt_handle. */
661 init_crit ();
663 /* Remember original console settings. */
664 keyboard_handle = GetStdHandle (STD_INPUT_HANDLE);
665 GetConsoleMode (keyboard_handle, &prev_console_mode);
667 prev_screen = GetStdHandle (STD_OUTPUT_HANDLE);
669 #ifdef USE_SEPARATE_SCREEN
670 cur_screen = CreateConsoleScreenBuffer (GENERIC_READ | GENERIC_WRITE,
671 0, NULL,
672 CONSOLE_TEXTMODE_BUFFER,
673 NULL);
675 if (cur_screen == INVALID_HANDLE_VALUE)
677 printf ("CreateConsoleScreenBuffer failed in ResetTerm\n");
678 printf ("LastError = 0x%lx\n", GetLastError ());
679 fflush (stdout);
680 exit (0);
682 #else
683 cur_screen = prev_screen;
684 GetConsoleCursorInfo (prev_screen, &prev_console_cursor);
685 #endif
687 /* Respect setting of LINES and COLUMNS environment variables. */
689 char * lines = getenv ("LINES");
690 char * columns = getenv ("COLUMNS");
692 if (lines != NULL && columns != NULL)
694 SMALL_RECT new_win_dims;
695 COORD new_size;
697 new_size.X = atoi (columns);
698 new_size.Y = atoi (lines);
700 GetConsoleScreenBufferInfo (cur_screen, &info);
702 /* Shrink the window first, so the buffer dimensions can be
703 reduced if necessary. */
704 new_win_dims.Top = 0;
705 new_win_dims.Left = 0;
706 new_win_dims.Bottom = min (new_size.Y, info.dwSize.Y) - 1;
707 new_win_dims.Right = min (new_size.X, info.dwSize.X) - 1;
708 SetConsoleWindowInfo (cur_screen, TRUE, &new_win_dims);
710 SetConsoleScreenBufferSize (cur_screen, new_size);
712 /* Set the window size to match the buffer dimension. */
713 new_win_dims.Top = 0;
714 new_win_dims.Left = 0;
715 new_win_dims.Bottom = new_size.Y - 1;
716 new_win_dims.Right = new_size.X - 1;
717 SetConsoleWindowInfo (cur_screen, TRUE, &new_win_dims);
721 GetConsoleScreenBufferInfo (cur_screen, &info);
723 char_attr_normal = info.wAttributes;
725 /* Determine if the info returned by GetConsoleScreenBufferInfo
726 is realistic. Old MS Telnet servers used to only fill out
727 the dwSize portion, even modern one fill the whole struct with
728 garbage when using non-MS telnet clients. */
729 if ((w32_use_full_screen_buffer
730 && (info.dwSize.Y < 20 || info.dwSize.Y > 100
731 || info.dwSize.X < 40 || info.dwSize.X > 200))
732 || (!w32_use_full_screen_buffer
733 && (info.srWindow.Bottom - info.srWindow.Top < 20
734 || info.srWindow.Bottom - info.srWindow.Top > 100
735 || info.srWindow.Right - info.srWindow.Left < 40
736 || info.srWindow.Right - info.srWindow.Left > 100)))
738 *height = 25;
739 *width = 80;
742 else if (w32_use_full_screen_buffer)
744 *height = info.dwSize.Y; /* lines per page */
745 *width = info.dwSize.X; /* characters per line */
747 else
749 /* Lines per page. Use buffer coords instead of buffer size. */
750 *height = 1 + info.srWindow.Bottom - info.srWindow.Top;
751 /* Characters per line. Use buffer coords instead of buffer size. */
752 *width = 1 + info.srWindow.Right - info.srWindow.Left;
755 if (os_subtype == OS_NT)
756 w32_console_unicode_input = 1;
757 else
758 w32_console_unicode_input = 0;
760 /* This is needed by w32notify.c:send_notifications. */
761 dwMainThreadId = GetCurrentThreadId ();
763 /* Setup w32_display_info structure for this frame. */
765 w32_initialize_display_info (build_string ("Console"));
770 DEFUN ("set-screen-color", Fset_screen_color, Sset_screen_color, 2, 2, 0,
771 doc: /* Set screen foreground and background colors.
773 Arguments should be indices between 0 and 15, see w32console.el. */)
774 (Lisp_Object foreground, Lisp_Object background)
776 char_attr_normal = XFASTINT (foreground) + (XFASTINT (background) << 4);
778 Frecenter (Qnil);
779 return Qt;
782 DEFUN ("get-screen-color", Fget_screen_color, Sget_screen_color, 0, 0, 0,
783 doc: /* Get color indices of the current screen foreground and background.
785 The colors are returned as a list of 2 indices (FOREGROUND BACKGROUND).
786 See w32console.el and `tty-defined-color-alist' for mapping of indices
787 to colors. */)
788 (void)
790 return Fcons (make_number (char_attr_normal & 0x000f),
791 Fcons (make_number ((char_attr_normal >> 4) & 0x000f), Qnil));
794 DEFUN ("set-cursor-size", Fset_cursor_size, Sset_cursor_size, 1, 1, 0,
795 doc: /* Set cursor size. */)
796 (Lisp_Object size)
798 CONSOLE_CURSOR_INFO cci;
799 cci.dwSize = XFASTINT (size);
800 cci.bVisible = TRUE;
801 (void) SetConsoleCursorInfo (cur_screen, &cci);
803 return Qt;
806 void
807 syms_of_ntterm (void)
809 DEFVAR_BOOL ("w32-use-full-screen-buffer",
810 w32_use_full_screen_buffer,
811 doc: /* Non-nil means make terminal frames use the full screen buffer dimensions.
812 This is desirable when running Emacs over telnet.
813 A value of nil means use the current console window dimensions; this
814 may be preferable when working directly at the console with a large
815 scroll-back buffer. */);
816 w32_use_full_screen_buffer = 0;
818 defsubr (&Sset_screen_color);
819 defsubr (&Sget_screen_color);
820 defsubr (&Sset_cursor_size);