Fix bug #18331 with "C-h k C-g" not showing documentation on Windows.
[emacs.git] / src / w32console.c
blobe3ca2f86b8da44bd1671a07a18cbb8dc095e103e
1 /* Terminal hooks for GNU Emacs on the Microsoft Windows API.
2 Copyright (C) 1992, 1999, 2001-2014 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 "character.h"
32 #include "coding.h"
33 #include "disptab.h"
34 #include "frame.h"
35 #include "window.h"
36 #include "termhooks.h"
37 #include "termchar.h"
38 #include "dispextern.h"
39 #include "w32term.h"
40 #include "w32common.h" /* for os_subtype */
41 #include "w32inevt.h"
43 /* from window.c */
44 extern Lisp_Object Frecenter (Lisp_Object);
46 static void w32con_move_cursor (struct frame *f, int row, int col);
47 static void w32con_clear_to_end (struct frame *f);
48 static void w32con_clear_frame (struct frame *f);
49 static void w32con_clear_end_of_line (struct frame *f, int);
50 static void w32con_ins_del_lines (struct frame *f, int vpos, int n);
51 static void w32con_insert_glyphs (struct frame *f, struct glyph *start, int len);
52 static void w32con_write_glyphs (struct frame *f, struct glyph *string, int len);
53 static void w32con_delete_glyphs (struct frame *f, int n);
54 static void w32con_reset_terminal_modes (struct terminal *t);
55 static void w32con_set_terminal_modes (struct terminal *t);
56 static void w32con_update_begin (struct frame * f);
57 static void w32con_update_end (struct frame * f);
58 static WORD w32_face_attributes (struct frame *f, int face_id);
60 static COORD cursor_coords;
61 static HANDLE prev_screen, cur_screen;
62 static WORD char_attr_normal;
63 static DWORD prev_console_mode;
65 static CONSOLE_CURSOR_INFO console_cursor_info;
66 #ifndef USE_SEPARATE_SCREEN
67 static CONSOLE_CURSOR_INFO prev_console_cursor;
68 #endif
70 HANDLE keyboard_handle;
71 int w32_console_unicode_input;
74 /* Setting this as the ctrl handler prevents emacs from being killed when
75 someone hits ^C in a 'suspended' session (child shell).
76 Also ignore Ctrl-Break signals. */
78 BOOL
79 ctrl_c_handler (unsigned long type)
81 /* Only ignore "interrupt" events when running interactively. */
82 return (!noninteractive
83 && (type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT));
87 /* Move the cursor to (ROW, COL) on FRAME. */
88 static void
89 w32con_move_cursor (struct frame *f, int row, int col)
91 cursor_coords.X = col;
92 cursor_coords.Y = row;
94 /* TODO: for multi-tty support, cur_screen should be replaced with a
95 reference to the terminal for this frame. */
96 SetConsoleCursorPosition (cur_screen, cursor_coords);
99 void
100 w32con_hide_cursor (void)
102 GetConsoleCursorInfo (cur_screen, &console_cursor_info);
103 console_cursor_info.bVisible = FALSE;
104 SetConsoleCursorInfo (cur_screen, &console_cursor_info);
107 void
108 w32con_show_cursor (void)
110 GetConsoleCursorInfo (cur_screen, &console_cursor_info);
111 console_cursor_info.bVisible = TRUE;
112 SetConsoleCursorInfo (cur_screen, &console_cursor_info);
115 /* Clear from cursor to end of screen. */
116 static void
117 w32con_clear_to_end (struct frame *f)
119 w32con_clear_end_of_line (f, FRAME_COLS (f) - 1);
120 w32con_ins_del_lines (f, cursor_coords.Y, FRAME_LINES (f) - cursor_coords.Y - 1);
123 /* Clear the frame. */
124 static void
125 w32con_clear_frame (struct frame *f)
127 COORD dest;
128 int n;
129 DWORD r;
130 CONSOLE_SCREEN_BUFFER_INFO info;
132 GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &info);
134 /* Remember that the screen buffer might be wider than the window. */
135 n = FRAME_LINES (f) * info.dwSize.X;
136 dest.X = dest.Y = 0;
138 FillConsoleOutputAttribute (cur_screen, char_attr_normal, n, dest, &r);
139 FillConsoleOutputCharacter (cur_screen, ' ', n, dest, &r);
141 w32con_move_cursor (f, 0, 0);
145 static struct glyph glyph_base[256];
146 static BOOL ceol_initialized = FALSE;
148 /* Clear from Cursor to end (what's "standout marker"?). */
149 static void
150 w32con_clear_end_of_line (struct frame *f, int end)
152 if (!ceol_initialized)
154 int i;
155 for (i = 0; i < 256; i++)
157 memcpy (&glyph_base[i], &space_glyph, sizeof (struct glyph));
159 ceol_initialized = TRUE;
161 w32con_write_glyphs (f, glyph_base, end - cursor_coords.X); /* fencepost ? */
164 /* Insert n lines at vpos. if n is negative delete -n lines. */
165 static void
166 w32con_ins_del_lines (struct frame *f, int vpos, int n)
168 int i, nb;
169 SMALL_RECT scroll;
170 SMALL_RECT clip;
171 COORD dest;
172 CHAR_INFO fill;
174 if (n < 0)
176 scroll.Top = vpos - n;
177 scroll.Bottom = FRAME_LINES (f);
178 dest.Y = vpos;
180 else
182 scroll.Top = vpos;
183 scroll.Bottom = FRAME_LINES (f) - n;
184 dest.Y = vpos + n;
186 clip.Top = clip.Left = scroll.Left = 0;
187 clip.Right = scroll.Right = FRAME_COLS (f);
188 clip.Bottom = FRAME_LINES (f);
190 dest.X = 0;
192 fill.Char.AsciiChar = 0x20;
193 fill.Attributes = char_attr_normal;
195 ScrollConsoleScreenBuffer (cur_screen, &scroll, &clip, dest, &fill);
197 /* Here we have to deal with a w32 console flake: If the scroll
198 region looks like abc and we scroll c to a and fill with d we get
199 cbd... if we scroll block c one line at a time to a, we get cdd...
200 Emacs expects cdd consistently... So we have to deal with that
201 here... (this also occurs scrolling the same way in the other
202 direction. */
204 if (n > 0)
206 if (scroll.Bottom < dest.Y)
208 for (i = scroll.Bottom; i < dest.Y; i++)
210 w32con_move_cursor (f, i, 0);
211 w32con_clear_end_of_line (f, FRAME_COLS (f));
215 else
217 nb = dest.Y + (scroll.Bottom - scroll.Top) + 1;
219 if (nb < scroll.Top)
221 for (i = nb; i < scroll.Top; i++)
223 w32con_move_cursor (f, i, 0);
224 w32con_clear_end_of_line (f, FRAME_COLS (f));
229 cursor_coords.X = 0;
230 cursor_coords.Y = vpos;
233 #undef LEFT
234 #undef RIGHT
235 #define LEFT 1
236 #define RIGHT 0
238 static void
239 scroll_line (struct frame *f, int dist, int direction)
241 /* The idea here is to implement a horizontal scroll in one line to
242 implement delete and half of insert. */
243 SMALL_RECT scroll, clip;
244 COORD dest;
245 CHAR_INFO fill;
247 clip.Top = scroll.Top = clip.Bottom = scroll.Bottom = cursor_coords.Y;
248 clip.Left = 0;
249 clip.Right = FRAME_COLS (f);
251 if (direction == LEFT)
253 scroll.Left = cursor_coords.X + dist;
254 scroll.Right = FRAME_COLS (f) - 1;
256 else
258 scroll.Left = cursor_coords.X;
259 scroll.Right = FRAME_COLS (f) - dist - 1;
262 dest.X = cursor_coords.X;
263 dest.Y = cursor_coords.Y;
265 fill.Char.AsciiChar = 0x20;
266 fill.Attributes = char_attr_normal;
268 ScrollConsoleScreenBuffer (cur_screen, &scroll, &clip, dest, &fill);
272 /* If start is zero insert blanks instead of a string at start ?. */
273 static void
274 w32con_insert_glyphs (struct frame *f, register struct glyph *start,
275 register int len)
277 scroll_line (f, len, RIGHT);
279 /* Move len chars to the right starting at cursor_coords, fill with blanks */
280 if (start)
282 /* Print the first len characters of start, cursor_coords.X adjusted
283 by write_glyphs. */
285 w32con_write_glyphs (f, start, len);
287 else
289 w32con_clear_end_of_line (f, cursor_coords.X + len);
293 static void
294 w32con_write_glyphs (struct frame *f, register struct glyph *string,
295 register int len)
297 DWORD r;
298 WORD char_attr;
299 unsigned char *conversion_buffer;
300 struct coding_system *coding;
302 if (len <= 0)
303 return;
305 /* If terminal_coding does any conversion, use it, otherwise use
306 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
307 because it always return 1 if the member src_multibyte is 1. */
308 coding = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK
309 ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding);
310 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
311 the tail. */
312 coding->mode &= ~CODING_MODE_LAST_BLOCK;
314 while (len > 0)
316 /* Identify a run of glyphs with the same face. */
317 int face_id = string->face_id;
318 int n;
320 for (n = 1; n < len; ++n)
321 if (string[n].face_id != face_id)
322 break;
324 /* Turn appearance modes of the face of the run on. */
325 char_attr = w32_face_attributes (f, face_id);
327 if (n == len)
328 /* This is the last run. */
329 coding->mode |= CODING_MODE_LAST_BLOCK;
330 conversion_buffer = encode_terminal_code (string, n, coding);
331 if (coding->produced > 0)
333 /* Set the attribute for these characters. */
334 if (!FillConsoleOutputAttribute (cur_screen, char_attr,
335 coding->produced, cursor_coords,
336 &r))
338 printf ("Failed writing console attributes: %d\n",
339 GetLastError ());
340 fflush (stdout);
343 /* Write the characters. */
344 if (!WriteConsoleOutputCharacter (cur_screen, conversion_buffer,
345 coding->produced, cursor_coords,
346 &r))
348 printf ("Failed writing console characters: %d\n",
349 GetLastError ());
350 fflush (stdout);
353 cursor_coords.X += coding->produced;
354 w32con_move_cursor (f, cursor_coords.Y, cursor_coords.X);
356 len -= n;
357 string += n;
361 /* Used for mouse highlight. */
362 static void
363 w32con_write_glyphs_with_face (struct frame *f, register int x, register int y,
364 register struct glyph *string, register int len,
365 register int face_id)
367 unsigned char *conversion_buffer;
368 struct coding_system *coding;
370 if (len <= 0)
371 return;
373 /* If terminal_coding does any conversion, use it, otherwise use
374 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
375 because it always return 1 if the member src_multibyte is 1. */
376 coding = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK
377 ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding);
378 /* We are going to write the entire block of glyphs in one go, as
379 they all have the same face. So this _is_ the last block. */
380 coding->mode |= CODING_MODE_LAST_BLOCK;
382 conversion_buffer = encode_terminal_code (string, len, coding);
383 if (coding->produced > 0)
385 DWORD filled, written;
386 /* Compute the character attributes corresponding to the face. */
387 DWORD char_attr = w32_face_attributes (f, face_id);
388 COORD start_coords;
390 start_coords.X = x;
391 start_coords.Y = y;
392 /* Set the attribute for these characters. */
393 if (!FillConsoleOutputAttribute (cur_screen, char_attr,
394 coding->produced, start_coords,
395 &filled))
396 DebPrint (("Failed writing console attributes: %d\n", GetLastError ()));
397 else
399 /* Write the characters. */
400 if (!WriteConsoleOutputCharacter (cur_screen, conversion_buffer,
401 filled, start_coords, &written))
402 DebPrint (("Failed writing console characters: %d\n",
403 GetLastError ()));
408 /* Implementation of draw_row_with_mouse_face for W32 console. */
409 void
410 tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row,
411 int start_hpos, int end_hpos,
412 enum draw_glyphs_face draw)
414 int nglyphs = end_hpos - start_hpos;
415 struct frame *f = XFRAME (WINDOW_FRAME (w));
416 struct tty_display_info *tty = FRAME_TTY (f);
417 int face_id = tty->mouse_highlight.mouse_face_face_id;
418 int pos_x, pos_y;
420 if (end_hpos >= row->used[TEXT_AREA])
421 nglyphs = row->used[TEXT_AREA] - start_hpos;
423 pos_y = row->y + WINDOW_TOP_EDGE_Y (w);
424 pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos + WINDOW_LEFT_EDGE_X (w);
426 if (draw == DRAW_MOUSE_FACE)
427 w32con_write_glyphs_with_face (f, pos_x, pos_y,
428 row->glyphs[TEXT_AREA] + start_hpos,
429 nglyphs, face_id);
430 else if (draw == DRAW_NORMAL_TEXT)
432 COORD save_coords = cursor_coords;
434 w32con_move_cursor (f, pos_y, pos_x);
435 write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
436 w32con_move_cursor (f, save_coords.Y, save_coords.X);
440 static void
441 w32con_delete_glyphs (struct frame *f, int n)
443 /* delete chars means scroll chars from cursor_coords.X + n to
444 cursor_coords.X, anything beyond the edge of the screen should
445 come out empty... */
447 scroll_line (f, n, LEFT);
451 static void
452 w32con_reset_terminal_modes (struct terminal *t)
454 COORD dest;
455 CONSOLE_SCREEN_BUFFER_INFO info;
456 int n;
457 DWORD r;
459 /* Clear the complete screen buffer. This is required because Emacs
460 sets the cursor position to the top of the buffer, but there might
461 be other output below the bottom of the Emacs frame if the screen buffer
462 is larger than the window size. */
463 GetConsoleScreenBufferInfo (cur_screen, &info);
464 dest.X = 0;
465 dest.Y = 0;
466 n = info.dwSize.X * info.dwSize.Y;
468 FillConsoleOutputAttribute (cur_screen, char_attr_normal, n, dest, &r);
469 FillConsoleOutputCharacter (cur_screen, ' ', n, dest, &r);
470 /* Now that the screen is clear, put the cursor at the top. */
471 SetConsoleCursorPosition (cur_screen, dest);
473 #ifdef USE_SEPARATE_SCREEN
474 SetConsoleActiveScreenBuffer (prev_screen);
475 #else
476 SetConsoleCursorInfo (prev_screen, &prev_console_cursor);
477 #endif
479 SetConsoleMode (keyboard_handle, prev_console_mode);
482 static void
483 w32con_set_terminal_modes (struct terminal *t)
485 CONSOLE_CURSOR_INFO cci;
487 /* make cursor big and visible (100 on Windows 95 makes it disappear) */
488 cci.dwSize = 99;
489 cci.bVisible = TRUE;
490 (void) SetConsoleCursorInfo (cur_screen, &cci);
492 SetConsoleActiveScreenBuffer (cur_screen);
494 SetConsoleMode (keyboard_handle, ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT);
496 /* Initialize input mode: interrupt_input off, no flow control, allow
497 8 bit character input, standard quit char. */
498 Fset_input_mode (Qnil, Qnil, make_number (2), Qnil);
501 /* hmmm... perhaps these let us bracket screen changes so that we can flush
502 clumps rather than one-character-at-a-time...
504 we'll start with not moving the cursor while an update is in progress. */
505 static void
506 w32con_update_begin (struct frame * f)
510 static void
511 w32con_update_end (struct frame * f)
513 SetConsoleCursorPosition (cur_screen, cursor_coords);
516 /***********************************************************************
517 stubs from termcap.c
518 ***********************************************************************/
520 void
521 sys_tputs (char *str, int nlines, int (*outfun) (int))
525 char *
526 sys_tgetstr (char *cap, char **area)
528 return NULL;
532 /***********************************************************************
533 stubs from cm.c
534 ***********************************************************************/
536 struct tty_display_info *current_tty = NULL;
537 int cost = 0;
540 evalcost (int c)
542 return c;
546 cmputc (int c)
548 return c;
551 void
552 cmcheckmagic (struct tty_display_info *tty)
556 void
557 cmcostinit (struct tty_display_info *tty)
561 void
562 cmgoto (struct tty_display_info *tty, int row, int col)
566 void
567 Wcm_clear (struct tty_display_info *tty)
572 /* Report the current cursor position. The following two functions
573 are used in term.c's tty menu code, so they are not really
574 "stubs". */
576 cursorX (struct tty_display_info *tty)
578 return cursor_coords.X;
582 cursorY (struct tty_display_info *tty)
584 return cursor_coords.Y;
587 /***********************************************************************
588 Faces
589 ***********************************************************************/
592 /* Turn appearances of face FACE_ID on tty frame F on. */
594 static WORD
595 w32_face_attributes (struct frame *f, int face_id)
597 WORD char_attr;
598 struct face *face = FACE_FROM_ID (f, face_id);
600 eassert (face != NULL);
602 char_attr = char_attr_normal;
604 /* Reverse the default color if requested. If background and
605 foreground are specified, then they have been reversed already. */
606 if (face->tty_reverse_p)
607 char_attr = (char_attr & 0xff00) + ((char_attr & 0x000f) << 4)
608 + ((char_attr & 0x00f0) >> 4);
610 /* Before the terminal is properly initialized, all colors map to 0.
611 Don't try to resolve them. */
612 if (NILP (Vtty_defined_color_alist))
613 return char_attr;
615 /* Colors should be in the range 0...15 unless they are one of
616 FACE_TTY_DEFAULT_COLOR, FACE_TTY_DEFAULT_FG_COLOR or
617 FACE_TTY_DEFAULT_BG_COLOR. Other out of range colors are
618 invalid, so it is better to use the default color if they ever
619 get through to here. */
620 if (face->foreground >= 0 && face->foreground < 16)
621 char_attr = (char_attr & 0xfff0) + face->foreground;
623 if (face->background >= 0 && face->background < 16)
624 char_attr = (char_attr & 0xff0f) + (face->background << 4);
626 return char_attr;
629 void
630 initialize_w32_display (struct terminal *term, int *width, int *height)
632 CONSOLE_SCREEN_BUFFER_INFO info;
634 term->rif = 0; /* No window based redisplay on the console. */
635 term->cursor_to_hook = w32con_move_cursor;
636 term->raw_cursor_to_hook = w32con_move_cursor;
637 term->clear_to_end_hook = w32con_clear_to_end;
638 term->clear_frame_hook = w32con_clear_frame;
639 term->clear_end_of_line_hook = w32con_clear_end_of_line;
640 term->ins_del_lines_hook = w32con_ins_del_lines;
641 term->insert_glyphs_hook = w32con_insert_glyphs;
642 term->write_glyphs_hook = w32con_write_glyphs;
643 term->delete_glyphs_hook = w32con_delete_glyphs;
644 term->ring_bell_hook = w32_sys_ring_bell;
645 term->reset_terminal_modes_hook = w32con_reset_terminal_modes;
646 term->set_terminal_modes_hook = w32con_set_terminal_modes;
647 term->set_terminal_window_hook = NULL;
648 term->update_begin_hook = w32con_update_begin;
649 term->update_end_hook = w32con_update_end;
651 term->read_socket_hook = w32_console_read_socket;
652 term->mouse_position_hook = w32_console_mouse_position;
654 /* The following are not used on the console. */
655 term->frame_rehighlight_hook = 0;
656 term->frame_raise_lower_hook = 0;
657 term->set_vertical_scroll_bar_hook = 0;
658 term->condemn_scroll_bars_hook = 0;
659 term->redeem_scroll_bar_hook = 0;
660 term->judge_scroll_bars_hook = 0;
661 term->frame_up_to_date_hook = 0;
663 /* Initialize the mouse-highlight data. */
664 reset_mouse_highlight (&term->display_info.tty->mouse_highlight);
666 /* Initialize interrupt_handle. */
667 init_crit ();
669 /* Remember original console settings. */
670 keyboard_handle = GetStdHandle (STD_INPUT_HANDLE);
671 GetConsoleMode (keyboard_handle, &prev_console_mode);
673 prev_screen = GetStdHandle (STD_OUTPUT_HANDLE);
675 #ifdef USE_SEPARATE_SCREEN
676 cur_screen = CreateConsoleScreenBuffer (GENERIC_READ | GENERIC_WRITE,
677 0, NULL,
678 CONSOLE_TEXTMODE_BUFFER,
679 NULL);
681 if (cur_screen == INVALID_HANDLE_VALUE)
683 printf ("CreateConsoleScreenBuffer failed in ResetTerm\n");
684 printf ("LastError = 0x%lx\n", GetLastError ());
685 fflush (stdout);
686 exit (0);
688 #else
689 cur_screen = prev_screen;
690 GetConsoleCursorInfo (prev_screen, &prev_console_cursor);
691 #endif
693 /* Respect setting of LINES and COLUMNS environment variables. */
695 char * lines = getenv ("LINES");
696 char * columns = getenv ("COLUMNS");
698 if (lines != NULL && columns != NULL)
700 SMALL_RECT new_win_dims;
701 COORD new_size;
703 new_size.X = atoi (columns);
704 new_size.Y = atoi (lines);
706 GetConsoleScreenBufferInfo (cur_screen, &info);
708 /* Shrink the window first, so the buffer dimensions can be
709 reduced if necessary. */
710 new_win_dims.Top = 0;
711 new_win_dims.Left = 0;
712 new_win_dims.Bottom = min (new_size.Y, info.dwSize.Y) - 1;
713 new_win_dims.Right = min (new_size.X, info.dwSize.X) - 1;
714 SetConsoleWindowInfo (cur_screen, TRUE, &new_win_dims);
716 SetConsoleScreenBufferSize (cur_screen, new_size);
718 /* Set the window size to match the buffer dimension. */
719 new_win_dims.Top = 0;
720 new_win_dims.Left = 0;
721 new_win_dims.Bottom = new_size.Y - 1;
722 new_win_dims.Right = new_size.X - 1;
723 SetConsoleWindowInfo (cur_screen, TRUE, &new_win_dims);
727 GetConsoleScreenBufferInfo (cur_screen, &info);
729 char_attr_normal = info.wAttributes;
731 /* Determine if the info returned by GetConsoleScreenBufferInfo
732 is realistic. Old MS Telnet servers used to only fill out
733 the dwSize portion, even modern one fill the whole struct with
734 garbage when using non-MS telnet clients. */
735 if ((w32_use_full_screen_buffer
736 && (info.dwSize.Y < 20 || info.dwSize.Y > 100
737 || info.dwSize.X < 40 || info.dwSize.X > 200))
738 || (!w32_use_full_screen_buffer
739 && (info.srWindow.Bottom - info.srWindow.Top < 20
740 || info.srWindow.Bottom - info.srWindow.Top > 100
741 || info.srWindow.Right - info.srWindow.Left < 40
742 || info.srWindow.Right - info.srWindow.Left > 100)))
744 *height = 25;
745 *width = 80;
748 else if (w32_use_full_screen_buffer)
750 *height = info.dwSize.Y; /* lines per page */
751 *width = info.dwSize.X; /* characters per line */
753 else
755 /* Lines per page. Use buffer coords instead of buffer size. */
756 *height = 1 + info.srWindow.Bottom - info.srWindow.Top;
757 /* Characters per line. Use buffer coords instead of buffer size. */
758 *width = 1 + info.srWindow.Right - info.srWindow.Left;
761 if (os_subtype == OS_NT)
762 w32_console_unicode_input = 1;
763 else
764 w32_console_unicode_input = 0;
766 /* This is needed by w32notify.c:send_notifications. */
767 dwMainThreadId = GetCurrentThreadId ();
769 /* Setup w32_display_info structure for this frame. */
771 w32_initialize_display_info (build_string ("Console"));
776 DEFUN ("set-screen-color", Fset_screen_color, Sset_screen_color, 2, 2, 0,
777 doc: /* Set screen foreground and background colors.
779 Arguments should be indices between 0 and 15, see w32console.el. */)
780 (Lisp_Object foreground, Lisp_Object background)
782 char_attr_normal = XFASTINT (foreground) + (XFASTINT (background) << 4);
784 Frecenter (Qnil);
785 return Qt;
788 DEFUN ("get-screen-color", Fget_screen_color, Sget_screen_color, 0, 0, 0,
789 doc: /* Get color indices of the current screen foreground and background.
791 The colors are returned as a list of 2 indices (FOREGROUND BACKGROUND).
792 See w32console.el and `tty-defined-color-alist' for mapping of indices
793 to colors. */)
794 (void)
796 return Fcons (make_number (char_attr_normal & 0x000f),
797 Fcons (make_number ((char_attr_normal >> 4) & 0x000f), Qnil));
800 DEFUN ("set-cursor-size", Fset_cursor_size, Sset_cursor_size, 1, 1, 0,
801 doc: /* Set cursor size. */)
802 (Lisp_Object size)
804 CONSOLE_CURSOR_INFO cci;
805 cci.dwSize = XFASTINT (size);
806 cci.bVisible = TRUE;
807 (void) SetConsoleCursorInfo (cur_screen, &cci);
809 return Qt;
812 void
813 syms_of_ntterm (void)
815 DEFVAR_BOOL ("w32-use-full-screen-buffer",
816 w32_use_full_screen_buffer,
817 doc: /* Non-nil means make terminal frames use the full screen buffer dimensions.
818 This is desirable when running Emacs over telnet.
819 A value of nil means use the current console window dimensions; this
820 may be preferable when working directly at the console with a large
821 scroll-back buffer. */);
822 w32_use_full_screen_buffer = 0;
824 defsubr (&Sset_screen_color);
825 defsubr (&Sget_screen_color);
826 defsubr (&Sset_cursor_size);