aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJason Rumney2000-01-23 03:16:02 +0000
committerJason Rumney2000-01-23 03:16:02 +0000
commit8c2ac482fb3aa53529d5c69c6b7b6306e0901932 (patch)
tree3f14db0103483e1bd49a6b3f4bfb0173dcf56442 /src
parent2e7aef9d1dee00727abdc8a9e9a9c14adaea1edb (diff)
downloademacs-8c2ac482fb3aa53529d5c69c6b7b6306e0901932.tar.gz
emacs-8c2ac482fb3aa53529d5c69c6b7b6306e0901932.zip
(turn_on_face, turn_off_face): New functions.
(change_line_highlight): New prototype for new redisplay. (write_glyphs): Support multibyte text. Support faces.
Diffstat (limited to 'src')
-rw-r--r--src/w32console.c245
1 files changed, 161 insertions, 84 deletions
diff --git a/src/w32console.c b/src/w32console.c
index 6b7331fbd3c..187e3e9852b 100644
--- a/src/w32console.c
+++ b/src/w32console.c
@@ -1,5 +1,5 @@
1/* Terminal hooks for GNU Emacs on the Microsoft W32 API. 1/* Terminal hooks for GNU Emacs on the Microsoft W32 API.
2 Copyright (C) 1992 Free Software Foundation, Inc. 2 Copyright (C) 1992, 1999 Free Software Foundation, Inc.
3 3
4This file is part of GNU Emacs. 4This file is part of GNU Emacs.
5 5
@@ -29,12 +29,18 @@ Boston, MA 02111-1307, USA.
29#include <stdio.h> 29#include <stdio.h>
30#include <windows.h> 30#include <windows.h>
31 31
32/* Disable features in headers that require a Window System for
33 console mode. */
34#undef HAVE_WINDOW_SYSTEM
35
32#include "lisp.h" 36#include "lisp.h"
33#include "charset.h" 37#include "charset.h"
38#include "coding.h"
34#include "frame.h" 39#include "frame.h"
35#include "disptab.h" 40#include "disptab.h"
36#include "termhooks.h" 41#include "termhooks.h"
37#include "w32inevt.h" 42#include "w32inevt.h"
43#include "dispextern.h"
38 44
39/* from window.c */ 45/* from window.c */
40extern Lisp_Object Frecenter (); 46extern Lisp_Object Frecenter ();
@@ -45,7 +51,7 @@ extern int detect_input_pending ();
45/* from sysdep.c */ 51/* from sysdep.c */
46extern int read_input_pending (); 52extern int read_input_pending ();
47 53
48extern FRAME_PTR updating_frame; 54extern struct frame * updating_frame;
49extern int meta_key; 55extern int meta_key;
50 56
51static void move_cursor (int row, int col); 57static void move_cursor (int row, int col);
@@ -53,18 +59,20 @@ static void clear_to_end (void);
53static void clear_frame (void); 59static void clear_frame (void);
54static void clear_end_of_line (int); 60static void clear_end_of_line (int);
55static void ins_del_lines (int vpos, int n); 61static void ins_del_lines (int vpos, int n);
56static void change_line_highlight (int, int, int); 62static void change_line_highlight (int, int, int, int);
57static void reassert_line_highlight (int, int); 63static void reassert_line_highlight (int, int);
58static void insert_glyphs (GLYPH *start, int len); 64static void insert_glyphs (struct glyph *start, int len);
59static void write_glyphs (GLYPH *string, int len); 65static void write_glyphs (struct glyph *string, int len);
60static void delete_glyphs (int n); 66static void delete_glyphs (int n);
61void w32_sys_ring_bell (void); 67void w32_sys_ring_bell (void);
62static void reset_terminal_modes (void); 68static void reset_terminal_modes (void);
63static void set_terminal_modes (void); 69static void set_terminal_modes (void);
64static void set_terminal_window (int size); 70static void set_terminal_window (int size);
65static void update_begin (FRAME_PTR f); 71static void update_begin (struct frame * f);
66static void update_end (FRAME_PTR f); 72static void update_end (struct frame * f);
67static int hl_mode (int new_highlight); 73static int hl_mode (int new_highlight);
74static void turn_on_face P_ ((struct frame *, int face_id));
75static void turn_off_face P_ ((struct frame *, int face_id));
68 76
69COORD cursor_coords; 77COORD cursor_coords;
70HANDLE prev_screen, cur_screen; 78HANDLE prev_screen, cur_screen;
@@ -97,7 +105,7 @@ ctrl_c_handler (unsigned long type)
97 105
98/* If we're updating a frame, use it as the current frame 106/* If we're updating a frame, use it as the current frame
99 Otherwise, use the selected frame. */ 107 Otherwise, use the selected frame. */
100#define PICK_FRAME() (updating_frame ? updating_frame : selected_frame) 108#define PICK_FRAME() (updating_frame ? updating_frame : SELECTED_FRAME ())
101 109
102/* Move the cursor to (row, col). */ 110/* Move the cursor to (row, col). */
103void 111void
@@ -106,7 +114,7 @@ move_cursor (int row, int col)
106 cursor_coords.X = col; 114 cursor_coords.X = col;
107 cursor_coords.Y = row; 115 cursor_coords.Y = row;
108 116
109 if (updating_frame == (FRAME_PTR) NULL) 117 if (updating_frame == (struct frame *) NULL)
110 { 118 {
111 SetConsoleCursorPosition (cur_screen, cursor_coords); 119 SetConsoleCursorPosition (cur_screen, cursor_coords);
112 } 120 }
@@ -116,7 +124,7 @@ move_cursor (int row, int col)
116void 124void
117clear_to_end (void) 125clear_to_end (void)
118{ 126{
119 FRAME_PTR f = PICK_FRAME (); 127 struct frame * f = PICK_FRAME ();
120 128
121 clear_end_of_line (FRAME_WIDTH (f) - 1); 129 clear_end_of_line (FRAME_WIDTH (f) - 1);
122 ins_del_lines (cursor_coords.Y, FRAME_HEIGHT (f) - cursor_coords.Y - 1); 130 ins_del_lines (cursor_coords.Y, FRAME_HEIGHT (f) - cursor_coords.Y - 1);
@@ -126,7 +134,7 @@ clear_to_end (void)
126void 134void
127clear_frame (void) 135clear_frame (void)
128{ 136{
129 FRAME_PTR f = PICK_FRAME (); 137 struct frame * f = PICK_FRAME ();
130 COORD dest; 138 COORD dest;
131 int n, r; 139 int n, r;
132 CONSOLE_SCREEN_BUFFER_INFO info; 140 CONSOLE_SCREEN_BUFFER_INFO info;
@@ -146,7 +154,7 @@ clear_frame (void)
146} 154}
147 155
148 156
149static GLYPH glyph_base[256]; 157static struct glyph glyph_base[256];
150static BOOL ceol_initialized = FALSE; 158static BOOL ceol_initialized = FALSE;
151 159
152/* Clear from Cursor to end (what's "standout marker"?). */ 160/* Clear from Cursor to end (what's "standout marker"?). */
@@ -158,7 +166,7 @@ clear_end_of_line (int end)
158 int i; 166 int i;
159 for (i = 0; i < 256; i++) 167 for (i = 0; i < 256; i++)
160 { 168 {
161 glyph_base[i] = SPACEGLYPH; /* empty space */ 169 memcpy (&glyph_base[i], &space_glyph, sizeof (struct glyph));
162 } 170 }
163 ceol_initialized = TRUE; 171 ceol_initialized = TRUE;
164 } 172 }
@@ -173,7 +181,7 @@ ins_del_lines (int vpos, int n)
173 SMALL_RECT scroll; 181 SMALL_RECT scroll;
174 COORD dest; 182 COORD dest;
175 CHAR_INFO fill; 183 CHAR_INFO fill;
176 FRAME_PTR f = PICK_FRAME (); 184 struct frame * f = PICK_FRAME ();
177 185
178 if (n < 0) 186 if (n < 0)
179 { 187 {
@@ -260,7 +268,8 @@ hl_mode (int new_highlight)
260/* Call this when about to modify line at position VPOS and change whether it 268/* Call this when about to modify line at position VPOS and change whether it
261 is highlighted. */ 269 is highlighted. */
262void 270void
263change_line_highlight (int new_highlight, int vpos, int first_unused_hpos) 271change_line_highlight (int new_highlight, int vpos, int y,
272 int first_unused_hpos)
264{ 273{
265 hl_mode (new_highlight); 274 hl_mode (new_highlight);
266 move_cursor (vpos, 0); 275 move_cursor (vpos, 0);
@@ -289,7 +298,7 @@ scroll_line (int dist, int direction)
289 SMALL_RECT scroll; 298 SMALL_RECT scroll;
290 COORD dest; 299 COORD dest;
291 CHAR_INFO fill; 300 CHAR_INFO fill;
292 FRAME_PTR f = PICK_FRAME (); 301 struct frame * f = PICK_FRAME ();
293 302
294 scroll.Top = cursor_coords.Y; 303 scroll.Top = cursor_coords.Y;
295 scroll.Bottom = cursor_coords.Y; 304 scroll.Bottom = cursor_coords.Y;
@@ -317,7 +326,7 @@ scroll_line (int dist, int direction)
317 326
318/* If start is zero insert blanks instead of a string at start ?. */ 327/* If start is zero insert blanks instead of a string at start ?. */
319void 328void
320insert_glyphs (register GLYPH *start, register int len) 329insert_glyphs (register struct glyph *start, register int len)
321{ 330{
322 scroll_line (len, RIGHT); 331 scroll_line (len, RIGHT);
323 332
@@ -336,75 +345,98 @@ insert_glyphs (register GLYPH *start, register int len)
336} 345}
337 346
338void 347void
339write_glyphs (register GLYPH *string, register int len) 348write_glyphs (register struct glyph *string, register int len)
340{ 349{
341 register unsigned int glyph_len = GLYPH_TABLE_LENGTH; 350 int produced, consumed, i;
342 Lisp_Object *glyph_table = GLYPH_TABLE_BASE; 351 struct frame * f = PICK_FRAME ();
343 FRAME_PTR f = PICK_FRAME ();
344 register char *ptr;
345 GLYPH glyph;
346 char *chars;
347 int i;
348
349 if (len <= 0)
350 return;
351 352
352 chars = alloca (len * sizeof (*chars)); 353 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
353 if (chars == NULL) 354 the tail. */
354 { 355 terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK;
355 printf ("alloca failed in write_glyphs\n");
356 return;
357 }
358
359 /* We have to deal with the glyph indirection...go over the glyph
360 buffer and extract the characters. */
361 ptr = chars;
362 while (--len >= 0)
363 {
364 glyph = *string++;
365 356
366 if (glyph > glyph_len) 357 while (len > 0)
367 {
368 *ptr++ = glyph & 0xFF;
369 continue;
370 }
371 GLYPH_FOLLOW_ALIASES (glyph_table, glyph_len, glyph);
372#ifndef HAVE_NTGUI
373 if (GLYPH_FACE (fixfix, glyph) != 0)
374 printf ("Glyph face is %d\n", GLYPH_FACE (fixfix, glyph));
375#endif /* !HAVE_NTGUI */
376 if (GLYPH_SIMPLE_P (glyph_table, glyph_len, glyph))
377 {
378 *ptr++ = glyph & 0xFF;
379 continue;
380 }
381 for (i = 0; i < GLYPH_LENGTH (glyph_table, glyph); i++)
382 {
383 *ptr++ = (GLYPH_STRING (glyph_table, glyph))[i];
384 }
385 }
386
387 /* Number of characters we have in the buffer. */
388 len = ptr-chars;
389
390 /* Set the attribute for these characters. */
391 if (!FillConsoleOutputAttribute (cur_screen, char_attr, len, cursor_coords, &i))
392 { 358 {
393 printf ("Failed writing console attributes: %d\n", GetLastError ()); 359 /* Identify a run of glyphs with the same face. */
394 fflush (stdout); 360 int face_id = string->face_id;
361 int n;
362
363 for (n = 1; n < len; ++n)
364 if (string[n].face_id != face_id)
365 break;
366
367 /* Turn appearance modes of the face of the run on. */
368 turn_on_face (f, face_id);
369
370 while (n > 0)
371 {
372 /* We use a shared conversion buffer of the current size
373 (1024 bytes at least). Usually it is sufficient, but if
374 not, we just repeat the loop. */
375 produced = encode_terminal_code (string, conversion_buffer,
376 n, conversion_buffer_size,
377 &consumed);
378 if (produced > 0)
379 {
380 /* Set the attribute for these characters. */
381 if (!FillConsoleOutputAttribute (cur_screen, char_attr,
382 produced, cursor_coords, &i))
383 {
384 printf ("Failed writing console attributes: %d\n",
385 GetLastError ());
386 fflush (stdout);
387 }
388
389 /* Write the characters. */
390 if (!WriteConsoleOutputCharacter (cur_screen, conversion_buffer,
391 produced, cursor_coords, &i))
392 {
393 printf ("Failed writing console characters: %d\n",
394 GetLastError ());
395 fflush (stdout);
396 }
397
398 cursor_coords.X += produced;
399 move_cursor (cursor_coords.Y, cursor_coords.X);
400 }
401 len -= consumed;
402 n -= consumed;
403 string += consumed;
404 }
405
406 /* Turn appearance modes off. */
407 turn_off_face (f, face_id);
395 } 408 }
396 409
397 /* Write the characters. */ 410 /* We may have to output some codes to terminate the writing. */
398 if (!WriteConsoleOutputCharacter (cur_screen, chars, len, cursor_coords, &i)) 411 if (CODING_REQUIRE_FLUSHING (&terminal_coding))
399 { 412 {
400 printf ("Failed writing console characters: %d\n", GetLastError ()); 413 terminal_coding.mode |= CODING_MODE_LAST_BLOCK;
401 fflush (stdout); 414 encode_coding (&terminal_coding, "", conversion_buffer,
415 0, conversion_buffer_size);
416 if (terminal_coding.produced > 0)
417 {
418 if (!FillConsoleOutputAttribute (cur_screen, char_attr,
419 terminal_coding.produced,
420 cursor_coords, &i))
421 {
422 printf ("Failed writing console attributes: %d\n",
423 GetLastError ());
424 fflush (stdout);
425 }
426
427 /* Write the characters. */
428 if (!WriteConsoleOutputCharacter (cur_screen, conversion_buffer,
429 produced, cursor_coords, &i))
430 {
431 printf ("Failed writing console characters: %d\n",
432 GetLastError ());
433 fflush (stdout);
434 }
435 }
402 } 436 }
403
404 cursor_coords.X += len;
405 move_cursor (cursor_coords.Y, cursor_coords.X);
406} 437}
407 438
439
408void 440void
409delete_glyphs (int n) 441delete_glyphs (int n)
410{ 442{
@@ -499,12 +531,12 @@ set_terminal_modes (void)
499 531
500 we'll start with not moving the cursor while an update is in progress. */ 532 we'll start with not moving the cursor while an update is in progress. */
501void 533void
502update_begin (FRAME_PTR f) 534update_begin (struct frame * f)
503{ 535{
504} 536}
505 537
506void 538void
507update_end (FRAME_PTR f) 539update_end (struct frame * f)
508{ 540{
509 SetConsoleCursorPosition (cur_screen, cursor_coords); 541 SetConsoleCursorPosition (cur_screen, cursor_coords);
510} 542}
@@ -514,6 +546,50 @@ set_terminal_window (int size)
514{ 546{
515} 547}
516 548
549/***********************************************************************
550 Faces
551 ***********************************************************************/
552
553
554/* Turn appearances of face FACE_ID on tty frame F on. */
555
556static void
557turn_on_face (f, face_id)
558 struct frame *f;
559 int face_id;
560{
561 struct face *face = FACE_FROM_ID (f, face_id);
562
563 xassert (face != NULL);
564
565 char_attr = char_attr_normal;
566
567 if (face->foreground != FACE_TTY_DEFAULT_COLOR)
568 char_attr = (char_attr & 0xf0) + face->foreground;
569
570 if (face->background != FACE_TTY_DEFAULT_COLOR)
571 char_attr = (face->background << 4) + char_attr & 0x0f;
572
573 if (face->tty_reverse_p)
574 char_attr = ((char_attr & 0x0f) << 4) + ((char_attr & 0xf0) >> 4);
575
576 /* Ensure readability */
577 if (((char_attr & 0xf0) >> 4) == (char_attr * 0x0f))
578 char_attr ^= 0x0f;
579}
580
581
582/* Turn off appearances of face FACE_ID on tty frame F. */
583
584static void
585turn_off_face (f, face_id)
586 struct frame *f;
587 int face_id;
588{
589 if (hl_mode (0))
590 hl_mode (1);
591}
592
517typedef int (*term_hook) (); 593typedef int (*term_hook) ();
518 594
519void 595void
@@ -541,6 +617,7 @@ initialize_w32_display (void)
541 617
542 read_socket_hook = w32_console_read_socket; 618 read_socket_hook = w32_console_read_socket;
543 mouse_position_hook = w32_console_mouse_position; 619 mouse_position_hook = w32_console_mouse_position;
620 estimate_mode_line_height_hook = 0;
544 621
545 /* Initialize interrupt_handle. */ 622 /* Initialize interrupt_handle. */
546 init_crit (); 623 init_crit ();
@@ -612,16 +689,16 @@ initialize_w32_display (void)
612 689
613 if (w32_use_full_screen_buffer) 690 if (w32_use_full_screen_buffer)
614 { 691 {
615 FRAME_HEIGHT (selected_frame) = info.dwSize.Y; /* lines per page */ 692 FRAME_HEIGHT (SELECTED_FRAME ()) = info.dwSize.Y; /* lines per page */
616 SET_FRAME_WIDTH (selected_frame, info.dwSize.X); /* characters per line */ 693 SET_FRAME_WIDTH (SELECTED_FRAME (), info.dwSize.X); /* characters per line */
617 } 694 }
618 else 695 else
619 { 696 {
620 /* Lines per page. Use buffer coords instead of buffer size. */ 697 /* Lines per page. Use buffer coords instead of buffer size. */
621 FRAME_HEIGHT (selected_frame) = 1 + info.srWindow.Bottom - 698 FRAME_HEIGHT (SELECTED_FRAME ()) = 1 + info.srWindow.Bottom -
622 info.srWindow.Top; 699 info.srWindow.Top;
623 /* Characters per line. Use buffer coords instead of buffer size. */ 700 /* Characters per line. Use buffer coords instead of buffer size. */
624 SET_FRAME_WIDTH (selected_frame, 1 + info.srWindow.Right - 701 SET_FRAME_WIDTH (SELECTED_FRAME (), 1 + info.srWindow.Right -
625 info.srWindow.Left); 702 info.srWindow.Left);
626 } 703 }
627} 704}
@@ -654,7 +731,7 @@ DEFUN ("set-cursor-size", Fset_cursor_size, Sset_cursor_size, 1, 1, 0,
654 731
655#ifndef HAVE_NTGUI 732#ifndef HAVE_NTGUI
656void 733void
657pixel_to_glyph_coords (FRAME_PTR f, int pix_x, int pix_y, int *x, int *y, 734pixel_to_glyph_coords (struct frame * f, int pix_x, int pix_y, int *x, int *y,
658 void *bounds, int noclip) 735 void *bounds, int noclip)
659{ 736{
660 *x = pix_x; 737 *x = pix_x;
@@ -662,7 +739,7 @@ pixel_to_glyph_coords (FRAME_PTR f, int pix_x, int pix_y, int *x, int *y,
662} 739}
663 740
664void 741void
665glyph_to_pixel_coords (FRAME_PTR f, int x, int y, int *pix_x, int *pix_y) 742glyph_to_pixel_coords (struct frame * f, int x, int y, int *pix_x, int *pix_y)
666{ 743{
667 *pix_x = x; 744 *pix_x = x;
668 *pix_y = y; 745 *pix_y = y;