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
32 #include "termchar.h" /* for FRAME_TTY */
33 #include "menu.h" /* for tty_menu_show */
35 #include "w32common.h" /* for os_subtype */
39 #include "w32.h" /* for syms_of_ntterm */
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
;
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);
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. */
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
);
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
);
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. */
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. */
123 w32con_clear_frame (struct frame
*f
)
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
;
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"?). */
148 w32con_clear_end_of_line (struct frame
*f
, int end
)
150 if (!ceol_initialized
)
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. */
164 w32con_ins_del_lines (struct frame
*f
, int vpos
, int n
)
174 scroll
.Top
= vpos
- n
;
175 scroll
.Bottom
= FRAME_TOTAL_LINES (f
);
181 scroll
.Bottom
= FRAME_TOTAL_LINES (f
) - n
;
184 clip
.Top
= clip
.Left
= scroll
.Left
= 0;
185 clip
.Right
= scroll
.Right
= FRAME_COLS (f
);
186 clip
.Bottom
= FRAME_TOTAL_LINES (f
);
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
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
));
215 nb
= dest
.Y
+ (scroll
.Bottom
- scroll
.Top
) + 1;
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
));
228 cursor_coords
.Y
= vpos
;
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
;
245 clip
.Top
= scroll
.Top
= clip
.Bottom
= scroll
.Bottom
= cursor_coords
.Y
;
247 clip
.Right
= FRAME_COLS (f
);
249 if (direction
== LEFT
)
251 scroll
.Left
= cursor_coords
.X
+ dist
;
252 scroll
.Right
= FRAME_COLS (f
) - 1;
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 ?. */
272 w32con_insert_glyphs (struct frame
*f
, register struct glyph
*start
,
275 scroll_line (f
, len
, RIGHT
);
277 /* Move len chars to the right starting at cursor_coords, fill with blanks */
280 /* Print the first len characters of start, cursor_coords.X adjusted
283 w32con_write_glyphs (f
, start
, len
);
287 w32con_clear_end_of_line (f
, cursor_coords
.X
+ len
);
292 w32con_write_glyphs (struct frame
*f
, register struct glyph
*string
,
297 LPCSTR conversion_buffer
;
298 struct coding_system
*coding
;
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
310 coding
->mode
&= ~CODING_MODE_LAST_BLOCK
;
314 /* Identify a run of glyphs with the same face. */
315 int face_id
= string
->face_id
;
318 for (n
= 1; n
< len
; ++n
)
319 if (string
[n
].face_id
!= face_id
)
322 /* Turn appearance modes of the face of the run on. */
323 char_attr
= w32_face_attributes (f
, face_id
);
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
,
336 printf ("Failed writing console attributes: %d\n",
341 /* Write the characters. */
342 if (!WriteConsoleOutputCharacter (cur_screen
, conversion_buffer
,
343 coding
->produced
, cursor_coords
,
346 printf ("Failed writing console characters: %d\n",
351 cursor_coords
.X
+= coding
->produced
;
352 w32con_move_cursor (f
, cursor_coords
.Y
, cursor_coords
.X
);
359 /* Used for mouse highlight. */
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
;
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
);
390 /* Set the attribute for these characters. */
391 if (!FillConsoleOutputAttribute (cur_screen
, char_attr
,
392 coding
->produced
, start_coords
,
394 DebPrint (("Failed writing console attributes: %d\n", GetLastError ()));
397 /* Write the characters. */
398 if (!WriteConsoleOutputCharacter (cur_screen
, conversion_buffer
,
399 filled
, start_coords
, &written
))
400 DebPrint (("Failed writing console characters: %d\n",
406 /* Implementation of draw_row_with_mouse_face for W32 console. */
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
;
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
,
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
);
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
445 scroll_line (f
, n
, LEFT
);
450 w32con_reset_terminal_modes (struct terminal
*t
)
453 CONSOLE_SCREEN_BUFFER_INFO info
;
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
);
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
);
474 SetConsoleCursorInfo (prev_screen
, &prev_console_cursor
);
477 SetConsoleMode (keyboard_handle
, prev_console_mode
);
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) */
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. */
504 w32con_update_begin (struct frame
* f
)
509 w32con_update_end (struct frame
* f
)
511 SetConsoleCursorPosition (cur_screen
, cursor_coords
);
514 /***********************************************************************
516 ***********************************************************************/
518 void sys_tputs (char *, int, int (*) (int));
521 sys_tputs (char *str
, int nlines
, int (*outfun
) (int))
525 char *sys_tgetstr (char *, char **);
528 sys_tgetstr (char *cap
, char **area
)
534 /***********************************************************************
536 ***********************************************************************/
538 struct tty_display_info
*current_tty
= NULL
;
557 void cmcheckmagic (struct tty_display_info
*);
560 cmcheckmagic (struct tty_display_info
*tty
)
564 void cmcostinit (struct tty_display_info
*);
567 cmcostinit (struct tty_display_info
*tty
)
571 void cmgoto (struct tty_display_info
*, int, int);
574 cmgoto (struct tty_display_info
*tty
, int row
, int col
)
578 void Wcm_clear (struct tty_display_info
*);
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
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 /***********************************************************************
603 ***********************************************************************/
606 /* Turn appearances of face FACE_ID on tty frame F on. */
609 w32_face_attributes (struct frame
*f
, int face_id
)
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
))
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);
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. */
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
,
694 CONSOLE_TEXTMODE_BUFFER
,
697 if (cur_screen
== INVALID_HANDLE_VALUE
)
699 printf ("CreateConsoleScreenBuffer failed in ResetTerm\n");
700 printf ("LastError = 0x%lx\n", GetLastError ());
705 cur_screen
= prev_screen
;
706 GetConsoleCursorInfo (prev_screen
, &prev_console_cursor
);
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
;
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)))
764 else if (w32_use_full_screen_buffer
)
766 *height
= info
.dwSize
.Y
; /* lines per page */
767 *width
= info
.dwSize
.X
; /* characters per line */
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;
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);
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
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. */)
818 CONSOLE_CURSOR_INFO cci
;
819 cci
.dwSize
= XFASTINT (size
);
821 (void) SetConsoleCursorInfo (cur_screen
, &cci
);
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
);