/* Terminal hooks for GNU Emacs on the Microsoft W32 API.
- Copyright (C) 1992, 1999, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+ 2008, 2009, 2010 Free Software Foundation, Inc.
This file is part of GNU Emacs.
-GNU Emacs is free software; you can redistribute it and/or modify
+GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.
+along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
+/*
Tim Fleehart (apollo@online.com) 1-17-92
Geoff Voelker (voelker@cs.washington.edu) 9-12-93
*/
#include <stdio.h>
#include <windows.h>
#include <string.h>
+#include <setjmp.h>
#include "lisp.h"
-#include "charset.h"
+#include "character.h"
#include "coding.h"
#include "disptab.h"
-/* Disable features in frame.h that require a Window System. */
-#undef HAVE_WINDOW_SYSTEM
#include "frame.h"
#include "termhooks.h"
#include "termchar.h"
#include "w32inevt.h"
/* from window.c */
-extern Lisp_Object Frecenter ();
+extern Lisp_Object Frecenter (Lisp_Object);
/* from keyboard.c */
-extern int detect_input_pending ();
+extern int detect_input_pending (void);
/* from sysdep.c */
-extern int read_input_pending ();
+extern int read_input_pending (void);
static void w32con_move_cursor (struct frame *f, int row, int col);
static void w32con_clear_to_end (struct frame *f);
static COORD cursor_coords;
static HANDLE prev_screen, cur_screen;
static WORD char_attr_normal;
-static DWORD prev_console_mode;
+static DWORD prev_console_mode;
#ifndef USE_SEPARATE_SCREEN
static CONSOLE_CURSOR_INFO prev_console_cursor;
#endif
+extern Lisp_Object Vtty_defined_color_alist;
+
/* Determine whether to make frame dimensions match the screen buffer,
or the current window size. The former is desirable when running
over telnet, while the latter is more useful when working directly at
{
int i, nb;
SMALL_RECT scroll;
+ SMALL_RECT clip;
COORD dest;
CHAR_INFO fill;
scroll.Bottom = FRAME_LINES (f) - n;
dest.Y = vpos + n;
}
- scroll.Left = 0;
- scroll.Right = FRAME_COLS (f);
+ clip.Top = clip.Left = scroll.Left = 0;
+ clip.Right = scroll.Right = FRAME_COLS (f);
+ clip.Bottom = FRAME_LINES (f);
dest.X = 0;
fill.Char.AsciiChar = 0x20;
fill.Attributes = char_attr_normal;
- ScrollConsoleScreenBuffer (cur_screen, &scroll, NULL, dest, &fill);
+ ScrollConsoleScreenBuffer (cur_screen, &scroll, &clip, dest, &fill);
/* Here we have to deal with a w32 console flake: If the scroll
region looks like abc and we scroll c to a and fill with d we get
{
/* The idea here is to implement a horizontal scroll in one line to
implement delete and half of insert. */
- SMALL_RECT scroll;
+ SMALL_RECT scroll, clip;
COORD dest;
CHAR_INFO fill;
- scroll.Top = cursor_coords.Y;
- scroll.Bottom = cursor_coords.Y;
+ clip.Top = scroll.Top = clip.Bottom = scroll.Bottom = cursor_coords.Y;
+ clip.Left = 0;
+ clip.Right = FRAME_COLS (f);
if (direction == LEFT)
{
fill.Char.AsciiChar = 0x20;
fill.Attributes = char_attr_normal;
- ScrollConsoleScreenBuffer (cur_screen, &scroll, NULL, dest, &fill);
+ ScrollConsoleScreenBuffer (cur_screen, &scroll, &clip, dest, &fill);
}
/* If start is zero insert blanks instead of a string at start ?. */
static void
-w32con_insert_glyphs (struct frame *f, register struct glyph *start, register int len)
+w32con_insert_glyphs (struct frame *f, register struct glyph *start,
+ register int len)
{
scroll_line (f, len, RIGHT);
}
}
-extern unsigned char *encode_terminal_code P_ ((struct glyph *, int,
- struct coding_system *));
+extern unsigned char *encode_terminal_code (struct glyph *, int,
+ struct coding_system *);
static void
w32con_write_glyphs (struct frame *f, register struct glyph *string,
register int len)
{
- int produced, consumed;
DWORD r;
WORD char_attr;
unsigned char *conversion_buffer;
to use the corresponding system sound for the bell. The 'silent sound
prevents Emacs from making any sound at all.
SOUND is nil to use the normal beep. */)
- (sound)
- Lisp_Object sound;
+ (Lisp_Object sound)
{
CHECK_SYMBOL (sound);
static void
w32con_reset_terminal_modes (struct terminal *t)
{
+ COORD dest;
+ CONSOLE_SCREEN_BUFFER_INFO info;
+ int n;
+ DWORD r;
+
+ /* Clear the complete screen buffer. This is required because Emacs
+ sets the cursor position to the top of the buffer, but there might
+ be other output below the bottom of the Emacs frame if the screen buffer
+ is larger than the window size. */
+ GetConsoleScreenBufferInfo (cur_screen, &info);
+ dest.X = 0;
+ dest.Y = 0;
+ n = info.dwSize.X * info.dwSize.Y;
+
+ FillConsoleOutputAttribute (cur_screen, char_attr_normal, n, dest, &r);
+ FillConsoleOutputCharacter (cur_screen, ' ', n, dest, &r);
+ /* Now that the screen is clear, put the cursor at the top. */
+ SetConsoleCursorPosition (cur_screen, dest);
+
#ifdef USE_SEPARATE_SCREEN
SetConsoleActiveScreenBuffer (prev_screen);
#else
SetConsoleCursorInfo (prev_screen, &prev_console_cursor);
#endif
+
SetConsoleMode (keyboard_handle, prev_console_mode);
}
{
}
+/***********************************************************************
+ stubs from termcap.c
+ ***********************************************************************/
+
+void
+sys_tputs (char *str, int nlines, int (*outfun) (int))
+{
+}
+
+char *
+sys_tgetstr (char *cap, char **area)
+{
+ return NULL;
+}
+
+
+/***********************************************************************
+ stubs from cm.c
+ ***********************************************************************/
+
+struct tty_display_info *current_tty = NULL;
+int cost = 0;
+
+int
+evalcost (int c)
+{
+ return c;
+}
+
+int
+cmputc (int c)
+{
+ return c;
+}
+
+void
+cmcheckmagic (struct tty_display_info *tty)
+{
+}
+
+void
+cmcostinit (struct tty_display_info *tty)
+{
+}
+
+void
+cmgoto (struct tty_display_info *tty, int row, int col)
+{
+}
+
+void
+Wcm_clear (struct tty_display_info *tty)
+{
+}
+
+
/***********************************************************************
Faces
***********************************************************************/
/* Turn appearances of face FACE_ID on tty frame F on. */
static WORD
-w32_face_attributes (f, face_id)
- struct frame *f;
- int face_id;
+w32_face_attributes (struct frame *f, int face_id)
{
WORD char_attr;
struct face *face = FACE_FROM_ID (f, face_id);
char_attr = char_attr_normal;
- if (face->foreground != FACE_TTY_DEFAULT_FG_COLOR
- && face->foreground != FACE_TTY_DEFAULT_COLOR)
- char_attr = (char_attr & 0xfff0) + (face->foreground % 16);
-
- if (face->background != FACE_TTY_DEFAULT_BG_COLOR
- && face->background != FACE_TTY_DEFAULT_COLOR)
- char_attr = (char_attr & 0xff0f) + ((face->background % 16) << 4);
-
-
- /* NTEMACS_TODO: Faces defined during startup get both foreground
- and background of 0. Need a better way around this - for now detect
- the problem and invert one of the faces to make the text readable. */
- if (((char_attr & 0x00f0) >> 4) == (char_attr & 0x000f))
- char_attr ^= 0x0007;
-
+ /* Reverse the default color if requested. If background and
+ foreground are specified, then they have been reversed already. */
if (face->tty_reverse_p)
char_attr = (char_attr & 0xff00) + ((char_attr & 0x000f) << 4)
+ ((char_attr & 0x00f0) >> 4);
- return char_attr;
-}
+ /* Before the terminal is properly initialized, all colors map to 0.
+ Don't try to resolve them. */
+ if (NILP (Vtty_defined_color_alist))
+ return char_attr;
+ /* Colors should be in the range 0...15 unless they are one of
+ FACE_TTY_DEFAULT_COLOR, FACE_TTY_DEFAULT_FG_COLOR or
+ FACE_TTY_DEFAULT_BG_COLOR. Other out of range colors are
+ invalid, so it is better to use the default color if they ever
+ get through to here. */
+ if (face->foreground >= 0 && face->foreground < 16)
+ char_attr = (char_attr & 0xfff0) + face->foreground;
-/* Emulation of some X window features from xfns.c and xfaces.c. */
+ if (face->background >= 0 && face->background < 16)
+ char_attr = (char_attr & 0xff0f) + (face->background << 4);
+
+ return char_attr;
+}
-extern char unspecified_fg[], unspecified_bg[];
/* Given a color index, return its standard name. */
return Qunspecified; /* meaning the default */
}
-typedef int (*term_hook) ();
-
void
initialize_w32_display (struct terminal *term)
{
term->rif = 0; /* No window based redisplay on the console. */
term->cursor_to_hook = w32con_move_cursor;
- term->raw_cursor_to_hook = w32con_move_cursor;
- term->clear_to_end_hook = w32con_clear_to_end;
- term->clear_frame_hook = w32con_clear_frame;
+ term->raw_cursor_to_hook = w32con_move_cursor;
+ term->clear_to_end_hook = w32con_clear_to_end;
+ term->clear_frame_hook = w32con_clear_frame;
term->clear_end_of_line_hook = w32con_clear_end_of_line;
- term->ins_del_lines_hook = w32con_ins_del_lines;
- term->insert_glyphs_hook = w32con_insert_glyphs;
- term->write_glyphs_hook = w32con_write_glyphs;
- term->delete_glyphs_hook = w32con_delete_glyphs;
+ term->ins_del_lines_hook = w32con_ins_del_lines;
+ term->insert_glyphs_hook = w32con_insert_glyphs;
+ term->write_glyphs_hook = w32con_write_glyphs;
+ term->delete_glyphs_hook = w32con_delete_glyphs;
term->ring_bell_hook = w32_sys_ring_bell;
- term->reset_terminal_modes_hook = w32con_reset_terminal_modes;
+ term->reset_terminal_modes_hook = w32con_reset_terminal_modes;
term->set_terminal_modes_hook = w32con_set_terminal_modes;
- term->set_terminal_window_hook = w32con_set_terminal_window;
- term->update_begin_hook = w32con_update_begin;
+ term->set_terminal_window_hook = w32con_set_terminal_window;
+ term->update_begin_hook = w32con_update_begin;
term->update_end_hook = w32con_update_end;
term->read_socket_hook = w32_console_read_socket;
/* Respect setting of LINES and COLUMNS environment variables. */
{
- char * lines = getenv("LINES");
- char * columns = getenv("COLUMNS");
+ char * lines = getenv ("LINES");
+ char * columns = getenv ("COLUMNS");
if (lines != NULL && columns != NULL)
{
DEFUN ("set-screen-color", Fset_screen_color, Sset_screen_color, 2, 2, 0,
doc: /* Set screen colors. */)
- (foreground, background)
- Lisp_Object foreground;
- Lisp_Object background;
+ (Lisp_Object foreground, Lisp_Object background)
{
char_attr_normal = XFASTINT (foreground) + (XFASTINT (background) << 4);
DEFUN ("set-cursor-size", Fset_cursor_size, Sset_cursor_size, 1, 1, 0,
doc: /* Set cursor size. */)
- (size)
- Lisp_Object size;
+ (Lisp_Object size)
{
CONSOLE_CURSOR_INFO cci;
cci.dwSize = XFASTINT (size);
}
void
-syms_of_ntterm ()
+syms_of_ntterm (void)
{
DEFVAR_BOOL ("w32-use-full-screen-buffer",
&w32_use_full_screen_buffer,