/* Terminal hooks for GNU Emacs on the Microsoft W32 API.
- Copyright (C) 1992 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1999 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <stdio.h>
#include <windows.h>
+/* Disable features in headers that require a Window System for
+ console mode. */
+#undef HAVE_WINDOW_SYSTEM
+
#include "lisp.h"
#include "charset.h"
+#include "coding.h"
#include "frame.h"
#include "disptab.h"
#include "termhooks.h"
#include "w32inevt.h"
+#include "dispextern.h"
/* from window.c */
extern Lisp_Object Frecenter ();
/* from sysdep.c */
extern int read_input_pending ();
-extern FRAME_PTR updating_frame;
+extern struct frame * updating_frame;
extern int meta_key;
static void move_cursor (int row, int col);
static void clear_frame (void);
static void clear_end_of_line (int);
static void ins_del_lines (int vpos, int n);
-static void change_line_highlight (int, int, int);
+static void change_line_highlight (int, int, int, int);
static void reassert_line_highlight (int, int);
-static void insert_glyphs (GLYPH *start, int len);
-static void write_glyphs (GLYPH *string, int len);
+static void insert_glyphs (struct glyph *start, int len);
+static void write_glyphs (struct glyph *string, int len);
static void delete_glyphs (int n);
void w32_sys_ring_bell (void);
static void reset_terminal_modes (void);
static void set_terminal_modes (void);
static void set_terminal_window (int size);
-static void update_begin (FRAME_PTR f);
-static void update_end (FRAME_PTR f);
+static void update_begin (struct frame * f);
+static void update_end (struct frame * f);
static int hl_mode (int new_highlight);
+static void turn_on_face P_ ((struct frame *, int face_id));
+static void turn_off_face P_ ((struct frame *, int face_id));
COORD cursor_coords;
HANDLE prev_screen, cur_screen;
/* If we're updating a frame, use it as the current frame
Otherwise, use the selected frame. */
-#define PICK_FRAME() (updating_frame ? updating_frame : selected_frame)
+#define PICK_FRAME() (updating_frame ? updating_frame : SELECTED_FRAME ())
/* Move the cursor to (row, col). */
void
cursor_coords.X = col;
cursor_coords.Y = row;
- if (updating_frame == (FRAME_PTR) NULL)
+ if (updating_frame == (struct frame *) NULL)
{
SetConsoleCursorPosition (cur_screen, cursor_coords);
}
void
clear_to_end (void)
{
- FRAME_PTR f = PICK_FRAME ();
+ struct frame * f = PICK_FRAME ();
clear_end_of_line (FRAME_WIDTH (f) - 1);
ins_del_lines (cursor_coords.Y, FRAME_HEIGHT (f) - cursor_coords.Y - 1);
void
clear_frame (void)
{
- FRAME_PTR f = PICK_FRAME ();
+ struct frame * f = PICK_FRAME ();
COORD dest;
int n, r;
CONSOLE_SCREEN_BUFFER_INFO info;
}
-static GLYPH glyph_base[256];
+static struct glyph glyph_base[256];
static BOOL ceol_initialized = FALSE;
/* Clear from Cursor to end (what's "standout marker"?). */
int i;
for (i = 0; i < 256; i++)
{
- glyph_base[i] = SPACEGLYPH; /* empty space */
+ memcpy (&glyph_base[i], &space_glyph, sizeof (struct glyph));
}
ceol_initialized = TRUE;
}
SMALL_RECT scroll;
COORD dest;
CHAR_INFO fill;
- FRAME_PTR f = PICK_FRAME ();
+ struct frame * f = PICK_FRAME ();
if (n < 0)
{
/* Call this when about to modify line at position VPOS and change whether it
is highlighted. */
void
-change_line_highlight (int new_highlight, int vpos, int first_unused_hpos)
+change_line_highlight (int new_highlight, int vpos, int y,
+ int first_unused_hpos)
{
hl_mode (new_highlight);
move_cursor (vpos, 0);
SMALL_RECT scroll;
COORD dest;
CHAR_INFO fill;
- FRAME_PTR f = PICK_FRAME ();
+ struct frame * f = PICK_FRAME ();
scroll.Top = cursor_coords.Y;
scroll.Bottom = cursor_coords.Y;
/* If start is zero insert blanks instead of a string at start ?. */
void
-insert_glyphs (register GLYPH *start, register int len)
+insert_glyphs (register struct glyph *start, register int len)
{
scroll_line (len, RIGHT);
}
void
-write_glyphs (register GLYPH *string, register int len)
+write_glyphs (register struct glyph *string, register int len)
{
- register unsigned int glyph_len = GLYPH_TABLE_LENGTH;
- Lisp_Object *glyph_table = GLYPH_TABLE_BASE;
- FRAME_PTR f = PICK_FRAME ();
- register char *ptr;
- GLYPH glyph;
- char *chars;
- int i;
-
- if (len <= 0)
- return;
+ int produced, consumed, i;
+ struct frame * f = PICK_FRAME ();
- chars = alloca (len * sizeof (*chars));
- if (chars == NULL)
- {
- printf ("alloca failed in write_glyphs\n");
- return;
- }
-
- /* We have to deal with the glyph indirection...go over the glyph
- buffer and extract the characters. */
- ptr = chars;
- while (--len >= 0)
- {
- glyph = *string++;
+ /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
+ the tail. */
+ terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK;
- if (glyph > glyph_len)
- {
- *ptr++ = glyph & 0xFF;
- continue;
- }
- GLYPH_FOLLOW_ALIASES (glyph_table, glyph_len, glyph);
-#ifndef HAVE_NTGUI
- if (GLYPH_FACE (fixfix, glyph) != 0)
- printf ("Glyph face is %d\n", GLYPH_FACE (fixfix, glyph));
-#endif /* !HAVE_NTGUI */
- if (GLYPH_SIMPLE_P (glyph_table, glyph_len, glyph))
- {
- *ptr++ = glyph & 0xFF;
- continue;
- }
- for (i = 0; i < GLYPH_LENGTH (glyph_table, glyph); i++)
- {
- *ptr++ = (GLYPH_STRING (glyph_table, glyph))[i];
- }
- }
-
- /* Number of characters we have in the buffer. */
- len = ptr-chars;
-
- /* Set the attribute for these characters. */
- if (!FillConsoleOutputAttribute (cur_screen, char_attr, len, cursor_coords, &i))
+ while (len > 0)
{
- printf ("Failed writing console attributes: %d\n", GetLastError ());
- fflush (stdout);
+ /* Identify a run of glyphs with the same face. */
+ int face_id = string->face_id;
+ int n;
+
+ for (n = 1; n < len; ++n)
+ if (string[n].face_id != face_id)
+ break;
+
+ /* Turn appearance modes of the face of the run on. */
+ turn_on_face (f, face_id);
+
+ while (n > 0)
+ {
+ /* We use a shared conversion buffer of the current size
+ (1024 bytes at least). Usually it is sufficient, but if
+ not, we just repeat the loop. */
+ produced = encode_terminal_code (string, conversion_buffer,
+ n, conversion_buffer_size,
+ &consumed);
+ if (produced > 0)
+ {
+ /* Set the attribute for these characters. */
+ if (!FillConsoleOutputAttribute (cur_screen, char_attr,
+ produced, cursor_coords, &i))
+ {
+ printf ("Failed writing console attributes: %d\n",
+ GetLastError ());
+ fflush (stdout);
+ }
+
+ /* Write the characters. */
+ if (!WriteConsoleOutputCharacter (cur_screen, conversion_buffer,
+ produced, cursor_coords, &i))
+ {
+ printf ("Failed writing console characters: %d\n",
+ GetLastError ());
+ fflush (stdout);
+ }
+
+ cursor_coords.X += produced;
+ move_cursor (cursor_coords.Y, cursor_coords.X);
+ }
+ len -= consumed;
+ n -= consumed;
+ string += consumed;
+ }
+
+ /* Turn appearance modes off. */
+ turn_off_face (f, face_id);
}
- /* Write the characters. */
- if (!WriteConsoleOutputCharacter (cur_screen, chars, len, cursor_coords, &i))
+ /* We may have to output some codes to terminate the writing. */
+ if (CODING_REQUIRE_FLUSHING (&terminal_coding))
{
- printf ("Failed writing console characters: %d\n", GetLastError ());
- fflush (stdout);
+ terminal_coding.mode |= CODING_MODE_LAST_BLOCK;
+ encode_coding (&terminal_coding, "", conversion_buffer,
+ 0, conversion_buffer_size);
+ if (terminal_coding.produced > 0)
+ {
+ if (!FillConsoleOutputAttribute (cur_screen, char_attr,
+ terminal_coding.produced,
+ cursor_coords, &i))
+ {
+ printf ("Failed writing console attributes: %d\n",
+ GetLastError ());
+ fflush (stdout);
+ }
+
+ /* Write the characters. */
+ if (!WriteConsoleOutputCharacter (cur_screen, conversion_buffer,
+ produced, cursor_coords, &i))
+ {
+ printf ("Failed writing console characters: %d\n",
+ GetLastError ());
+ fflush (stdout);
+ }
+ }
}
-
- cursor_coords.X += len;
- move_cursor (cursor_coords.Y, cursor_coords.X);
}
+
void
delete_glyphs (int n)
{
we'll start with not moving the cursor while an update is in progress. */
void
-update_begin (FRAME_PTR f)
+update_begin (struct frame * f)
{
}
void
-update_end (FRAME_PTR f)
+update_end (struct frame * f)
{
SetConsoleCursorPosition (cur_screen, cursor_coords);
}
{
}
+/***********************************************************************
+ Faces
+ ***********************************************************************/
+
+
+/* Turn appearances of face FACE_ID on tty frame F on. */
+
+static void
+turn_on_face (f, face_id)
+ struct frame *f;
+ int face_id;
+{
+ struct face *face = FACE_FROM_ID (f, face_id);
+
+ xassert (face != NULL);
+
+ char_attr = char_attr_normal;
+
+ if (face->foreground != FACE_TTY_DEFAULT_COLOR)
+ char_attr = (char_attr & 0xf0) + face->foreground;
+
+ if (face->background != FACE_TTY_DEFAULT_COLOR)
+ char_attr = (face->background << 4) + char_attr & 0x0f;
+
+ if (face->tty_reverse_p)
+ char_attr = ((char_attr & 0x0f) << 4) + ((char_attr & 0xf0) >> 4);
+
+ /* Ensure readability */
+ if (((char_attr & 0xf0) >> 4) == (char_attr * 0x0f))
+ char_attr ^= 0x0f;
+}
+
+
+/* Turn off appearances of face FACE_ID on tty frame F. */
+
+static void
+turn_off_face (f, face_id)
+ struct frame *f;
+ int face_id;
+{
+ if (hl_mode (0))
+ hl_mode (1);
+}
+
typedef int (*term_hook) ();
void
read_socket_hook = w32_console_read_socket;
mouse_position_hook = w32_console_mouse_position;
+ estimate_mode_line_height_hook = 0;
/* Initialize interrupt_handle. */
init_crit ();
if (w32_use_full_screen_buffer)
{
- FRAME_HEIGHT (selected_frame) = info.dwSize.Y; /* lines per page */
- SET_FRAME_WIDTH (selected_frame, info.dwSize.X); /* characters per line */
+ FRAME_HEIGHT (SELECTED_FRAME ()) = info.dwSize.Y; /* lines per page */
+ SET_FRAME_WIDTH (SELECTED_FRAME (), info.dwSize.X); /* characters per line */
}
else
{
/* Lines per page. Use buffer coords instead of buffer size. */
- FRAME_HEIGHT (selected_frame) = 1 + info.srWindow.Bottom -
+ FRAME_HEIGHT (SELECTED_FRAME ()) = 1 + info.srWindow.Bottom -
info.srWindow.Top;
/* Characters per line. Use buffer coords instead of buffer size. */
- SET_FRAME_WIDTH (selected_frame, 1 + info.srWindow.Right -
+ SET_FRAME_WIDTH (SELECTED_FRAME (), 1 + info.srWindow.Right -
info.srWindow.Left);
}
}
#ifndef HAVE_NTGUI
void
-pixel_to_glyph_coords (FRAME_PTR f, int pix_x, int pix_y, int *x, int *y,
+pixel_to_glyph_coords (struct frame * f, int pix_x, int pix_y, int *x, int *y,
void *bounds, int noclip)
{
*x = pix_x;
}
void
-glyph_to_pixel_coords (FRAME_PTR f, int x, int y, int *pix_x, int *pix_y)
+glyph_to_pixel_coords (struct frame * f, int x, int y, int *pix_x, int *pix_y)
{
*pix_x = x;
*pix_y = y;