comparison src/w32console.c @ 83573:b77b83741308

(w32con_move_cursor, w32con_clear_to_end): (w32con_clear_frame, w32con_clear_end_of_line): (w32con_ins_del_lines, w32con_insert_glyphs, w32con_write_glyphs): (w32con_delete_glyphs, w32con_set_terminal_window): (scroll_line, w32_sys_ring_bell): Add frame arg. (w32con_set_terminal_modes, w32con_reset_terminal_modes): Add terminal arg. (PICK_FRAME): Remove. (w32con_write_glyphs): Use frame specific terminal coding. (one_and_only_w32cons): New global variable. (initialize_w32_display): Use it for storing hooks. (create_w32cons_output): New function.
author Jason Rumney <jasonr@gnu.org>
date Tue, 15 May 2007 23:03:04 +0000
parents e90d04cd455a
children 65663fcd2caa
comparison
equal deleted inserted replaced
83572:244d6216c056 83573:b77b83741308
33 33
34 #include "lisp.h" 34 #include "lisp.h"
35 #include "charset.h" 35 #include "charset.h"
36 #include "coding.h" 36 #include "coding.h"
37 #include "disptab.h" 37 #include "disptab.h"
38 #include "termhooks.h"
39 #include "dispextern.h"
40 /* Disable features in frame.h that require a Window System. */ 38 /* Disable features in frame.h that require a Window System. */
41 #undef HAVE_WINDOW_SYSTEM 39 #undef HAVE_WINDOW_SYSTEM
42 #include "frame.h" 40 #include "frame.h"
41 #include "termhooks.h"
42 #include "termchar.h"
43 #include "dispextern.h"
43 #include "w32inevt.h" 44 #include "w32inevt.h"
44 45
45 /* from window.c */ 46 /* from window.c */
46 extern Lisp_Object Frecenter (); 47 extern Lisp_Object Frecenter ();
47 48
49 extern int detect_input_pending (); 50 extern int detect_input_pending ();
50 51
51 /* from sysdep.c */ 52 /* from sysdep.c */
52 extern int read_input_pending (); 53 extern int read_input_pending ();
53 54
54 extern struct frame * updating_frame; 55 static void w32con_move_cursor (struct frame *f, int row, int col);
55 extern int meta_key; 56 static void w32con_clear_to_end (struct frame *f);
56 57 static void w32con_clear_frame (struct frame *f);
57 static void w32con_move_cursor (int row, int col); 58 static void w32con_clear_end_of_line (struct frame *f, int);
58 static void w32con_clear_to_end (void); 59 static void w32con_ins_del_lines (struct frame *f, int vpos, int n);
59 static void w32con_clear_frame (void); 60 static void w32con_insert_glyphs (struct frame *f, struct glyph *start, int len);
60 static void w32con_clear_end_of_line (int); 61 static void w32con_write_glyphs (struct frame *f, struct glyph *string, int len);
61 static void w32con_ins_del_lines (int vpos, int n); 62 static void w32con_delete_glyphs (struct frame *f, int n);
62 static void w32con_insert_glyphs (struct glyph *start, int len); 63 static void w32con_reset_terminal_modes (struct terminal *t);
63 static void w32con_write_glyphs (struct glyph *string, int len); 64 static void w32con_set_terminal_modes (struct terminal *t);
64 static void w32con_delete_glyphs (int n); 65 static void w32con_set_terminal_window (struct frame *f, int size);
65 void w32_sys_ring_bell (void);
66 static void w32con_reset_terminal_modes (void);
67 static void w32con_set_terminal_modes (void);
68 static void w32con_set_terminal_window (int size);
69 static void w32con_update_begin (struct frame * f); 66 static void w32con_update_begin (struct frame * f);
70 static void w32con_update_end (struct frame * f); 67 static void w32con_update_end (struct frame * f);
71 static WORD w32_face_attributes (struct frame *f, int face_id); 68 static WORD w32_face_attributes (struct frame *f, int face_id);
72 69
73 static COORD cursor_coords; 70 static COORD cursor_coords;
97 /* Only ignore "interrupt" events when running interactively. */ 94 /* Only ignore "interrupt" events when running interactively. */
98 return (!noninteractive 95 return (!noninteractive
99 && (type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT)); 96 && (type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT));
100 } 97 }
101 98
102 /* If we're updating a frame, use it as the current frame 99
103 Otherwise, use the selected frame. */ 100 /* Move the cursor to (ROW, COL) on FRAME. */
104 #define PICK_FRAME() (updating_frame ? updating_frame : SELECTED_FRAME ()) 101 static void
105 102 w32con_move_cursor (struct frame *f, int row, int col)
106 /* Move the cursor to (row, col). */
107 static void
108 w32con_move_cursor (int row, int col)
109 { 103 {
110 cursor_coords.X = col; 104 cursor_coords.X = col;
111 cursor_coords.Y = row; 105 cursor_coords.Y = row;
112 106
113 if (updating_frame == (struct frame *) NULL) 107 /* TODO: for multi-tty support, cur_screen should be replaced with a
114 { 108 reference to the terminal for this frame. */
115 SetConsoleCursorPosition (cur_screen, cursor_coords); 109 SetConsoleCursorPosition (cur_screen, cursor_coords);
116 }
117 } 110 }
118 111
119 /* Clear from cursor to end of screen. */ 112 /* Clear from cursor to end of screen. */
120 static void 113 static void
121 w32con_clear_to_end (void) 114 w32con_clear_to_end (struct frame *f)
122 { 115 {
123 struct frame * f = PICK_FRAME (); 116 w32con_clear_end_of_line (f, FRAME_COLS (f) - 1);
124 117 w32con_ins_del_lines (f, cursor_coords.Y, FRAME_LINES (f) - cursor_coords.Y - 1);
125 w32con_clear_end_of_line (FRAME_COLS (f) - 1);
126 w32con_ins_del_lines (cursor_coords.Y, FRAME_LINES (f) - cursor_coords.Y - 1);
127 } 118 }
128 119
129 /* Clear the frame. */ 120 /* Clear the frame. */
130 static void 121 static void
131 w32con_clear_frame (void) 122 w32con_clear_frame (struct frame *f)
132 { 123 {
133 struct frame * f = PICK_FRAME ();
134 COORD dest; 124 COORD dest;
135 int n; 125 int n;
136 DWORD r; 126 DWORD r;
137 CONSOLE_SCREEN_BUFFER_INFO info; 127 CONSOLE_SCREEN_BUFFER_INFO info;
138 128
143 dest.X = dest.Y = 0; 133 dest.X = dest.Y = 0;
144 134
145 FillConsoleOutputAttribute (cur_screen, char_attr_normal, n, dest, &r); 135 FillConsoleOutputAttribute (cur_screen, char_attr_normal, n, dest, &r);
146 FillConsoleOutputCharacter (cur_screen, ' ', n, dest, &r); 136 FillConsoleOutputCharacter (cur_screen, ' ', n, dest, &r);
147 137
148 w32con_move_cursor (0, 0); 138 w32con_move_cursor (f, 0, 0);
149 } 139 }
150 140
151 141
152 static struct glyph glyph_base[256]; 142 static struct glyph glyph_base[256];
153 static BOOL ceol_initialized = FALSE; 143 static BOOL ceol_initialized = FALSE;
154 144
155 /* Clear from Cursor to end (what's "standout marker"?). */ 145 /* Clear from Cursor to end (what's "standout marker"?). */
156 static void 146 static void
157 w32con_clear_end_of_line (int end) 147 w32con_clear_end_of_line (struct frame *f, int end)
158 { 148 {
159 if (!ceol_initialized) 149 if (!ceol_initialized)
160 { 150 {
161 int i; 151 int i;
162 for (i = 0; i < 256; i++) 152 for (i = 0; i < 256; i++)
163 { 153 {
164 memcpy (&glyph_base[i], &space_glyph, sizeof (struct glyph)); 154 memcpy (&glyph_base[i], &space_glyph, sizeof (struct glyph));
165 } 155 }
166 ceol_initialized = TRUE; 156 ceol_initialized = TRUE;
167 } 157 }
168 w32con_write_glyphs (glyph_base, end - cursor_coords.X); /* fencepost ? */ 158 w32con_write_glyphs (f, glyph_base, end - cursor_coords.X); /* fencepost ? */
169 } 159 }
170 160
171 /* Insert n lines at vpos. if n is negative delete -n lines. */ 161 /* Insert n lines at vpos. if n is negative delete -n lines. */
172 static void 162 static void
173 w32con_ins_del_lines (int vpos, int n) 163 w32con_ins_del_lines (struct frame *f, int vpos, int n)
174 { 164 {
175 int i, nb; 165 int i, nb;
176 SMALL_RECT scroll; 166 SMALL_RECT scroll;
177 COORD dest; 167 COORD dest;
178 CHAR_INFO fill; 168 CHAR_INFO fill;
179 struct frame * f = PICK_FRAME ();
180 169
181 if (n < 0) 170 if (n < 0)
182 { 171 {
183 scroll.Top = vpos - n; 172 scroll.Top = vpos - n;
184 scroll.Bottom = FRAME_LINES (f); 173 scroll.Bottom = FRAME_LINES (f);
211 { 200 {
212 if (scroll.Bottom < dest.Y) 201 if (scroll.Bottom < dest.Y)
213 { 202 {
214 for (i = scroll.Bottom; i < dest.Y; i++) 203 for (i = scroll.Bottom; i < dest.Y; i++)
215 { 204 {
216 w32con_move_cursor (i, 0); 205 w32con_move_cursor (f, i, 0);
217 w32con_clear_end_of_line (FRAME_COLS (f)); 206 w32con_clear_end_of_line (f, FRAME_COLS (f));
218 } 207 }
219 } 208 }
220 } 209 }
221 else 210 else
222 { 211 {
224 213
225 if (nb < scroll.Top) 214 if (nb < scroll.Top)
226 { 215 {
227 for (i = nb; i < scroll.Top; i++) 216 for (i = nb; i < scroll.Top; i++)
228 { 217 {
229 w32con_move_cursor (i, 0); 218 w32con_move_cursor (f, i, 0);
230 w32con_clear_end_of_line (FRAME_COLS (f)); 219 w32con_clear_end_of_line (f, FRAME_COLS (f));
231 } 220 }
232 } 221 }
233 } 222 }
234 223
235 cursor_coords.X = 0; 224 cursor_coords.X = 0;
240 #undef RIGHT 229 #undef RIGHT
241 #define LEFT 1 230 #define LEFT 1
242 #define RIGHT 0 231 #define RIGHT 0
243 232
244 static void 233 static void
245 scroll_line (int dist, int direction) 234 scroll_line (struct frame *f, int dist, int direction)
246 { 235 {
247 /* The idea here is to implement a horizontal scroll in one line to 236 /* The idea here is to implement a horizontal scroll in one line to
248 implement delete and half of insert. */ 237 implement delete and half of insert. */
249 SMALL_RECT scroll; 238 SMALL_RECT scroll;
250 COORD dest; 239 COORD dest;
251 CHAR_INFO fill; 240 CHAR_INFO fill;
252 struct frame * f = PICK_FRAME ();
253 241
254 scroll.Top = cursor_coords.Y; 242 scroll.Top = cursor_coords.Y;
255 scroll.Bottom = cursor_coords.Y; 243 scroll.Bottom = cursor_coords.Y;
256 244
257 if (direction == LEFT) 245 if (direction == LEFT)
275 } 263 }
276 264
277 265
278 /* If start is zero insert blanks instead of a string at start ?. */ 266 /* If start is zero insert blanks instead of a string at start ?. */
279 static void 267 static void
280 w32con_insert_glyphs (register struct glyph *start, register int len) 268 w32con_insert_glyphs (struct frame *f, register struct glyph *start, register int len)
281 { 269 {
282 scroll_line (len, RIGHT); 270 scroll_line (f, len, RIGHT);
283 271
284 /* Move len chars to the right starting at cursor_coords, fill with blanks */ 272 /* Move len chars to the right starting at cursor_coords, fill with blanks */
285 if (start) 273 if (start)
286 { 274 {
287 /* Print the first len characters of start, cursor_coords.X adjusted 275 /* Print the first len characters of start, cursor_coords.X adjusted
288 by write_glyphs. */ 276 by write_glyphs. */
289 277
290 w32con_write_glyphs (start, len); 278 w32con_write_glyphs (f, start, len);
291 } 279 }
292 else 280 else
293 { 281 {
294 w32con_clear_end_of_line (cursor_coords.X + len); 282 w32con_clear_end_of_line (f, cursor_coords.X + len);
295 } 283 }
296 } 284 }
297 285
298 extern unsigned char *encode_terminal_code P_ ((struct glyph *, int, 286 extern unsigned char *encode_terminal_code P_ ((struct glyph *, int,
299 struct coding_system *)); 287 struct coding_system *));
300 288
301 static void 289 static void
302 w32con_write_glyphs (register struct glyph *string, register int len) 290 w32con_write_glyphs (struct frame *f, register struct glyph *string,
291 register int len)
303 { 292 {
304 int produced, consumed; 293 int produced, consumed;
305 DWORD r; 294 DWORD r;
306 struct frame * f = PICK_FRAME ();
307 WORD char_attr; 295 WORD char_attr;
308 unsigned char *conversion_buffer; 296 unsigned char *conversion_buffer;
309 struct coding_system *coding; 297 struct coding_system *coding;
310 298
311 if (len <= 0) 299 if (len <= 0)
312 return; 300 return;
313 301
314 /* If terminal_coding does any conversion, use it, otherwise use 302 /* If terminal_coding does any conversion, use it, otherwise use
315 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here 303 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
316 because it always return 1 if the member src_multibyte is 1. */ 304 because it always return 1 if the member src_multibyte is 1. */
317 coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK 305 coding = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK
318 ? &terminal_coding : &safe_terminal_coding); 306 ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding);
319 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at 307 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
320 the tail. */ 308 the tail. */
321 terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK; 309 coding->mode &= ~CODING_MODE_LAST_BLOCK;
322 310
323 while (len > 0) 311 while (len > 0)
324 { 312 {
325 /* Identify a run of glyphs with the same face. */ 313 /* Identify a run of glyphs with the same face. */
326 int face_id = string->face_id; 314 int face_id = string->face_id;
358 GetLastError ()); 346 GetLastError ());
359 fflush (stdout); 347 fflush (stdout);
360 } 348 }
361 349
362 cursor_coords.X += coding->produced; 350 cursor_coords.X += coding->produced;
363 w32con_move_cursor (cursor_coords.Y, cursor_coords.X); 351 w32con_move_cursor (f, cursor_coords.Y, cursor_coords.X);
364 } 352 }
365 len -= n; 353 len -= n;
366 string += n; 354 string += n;
367 } 355 }
368 } 356 }
369 357
370 358
371 static void 359 static void
372 w32con_delete_glyphs (int n) 360 w32con_delete_glyphs (struct frame *f, int n)
373 { 361 {
374 /* delete chars means scroll chars from cursor_coords.X + n to 362 /* delete chars means scroll chars from cursor_coords.X + n to
375 cursor_coords.X, anything beyond the edge of the screen should 363 cursor_coords.X, anything beyond the edge of the screen should
376 come out empty... */ 364 come out empty... */
377 365
378 scroll_line (n, LEFT); 366 scroll_line (f, n, LEFT);
379 } 367 }
380 368
381 static unsigned int sound_type = 0xFFFFFFFF; 369 static unsigned int sound_type = 0xFFFFFFFF;
382 #define MB_EMACS_SILENT (0xFFFFFFFF - 1) 370 #define MB_EMACS_SILENT (0xFFFFFFFF - 1)
383 371
384 void 372 void
385 w32_sys_ring_bell (void) 373 w32_sys_ring_bell (struct frame *f)
386 { 374 {
387 if (sound_type == 0xFFFFFFFF) 375 if (sound_type == 0xFFFFFFFF)
388 { 376 {
389 Beep (666, 100); 377 Beep (666, 100);
390 } 378 }
426 414
427 return sound; 415 return sound;
428 } 416 }
429 417
430 static void 418 static void
431 w32con_reset_terminal_modes (void) 419 w32con_reset_terminal_modes (struct terminal *t)
432 { 420 {
433 #ifdef USE_SEPARATE_SCREEN 421 #ifdef USE_SEPARATE_SCREEN
434 SetConsoleActiveScreenBuffer (prev_screen); 422 SetConsoleActiveScreenBuffer (prev_screen);
435 #else 423 #else
436 SetConsoleCursorInfo (prev_screen, &prev_console_cursor); 424 SetConsoleCursorInfo (prev_screen, &prev_console_cursor);
437 #endif 425 #endif
438 SetConsoleMode (keyboard_handle, prev_console_mode); 426 SetConsoleMode (keyboard_handle, prev_console_mode);
439 } 427 }
440 428
441 static void 429 static void
442 w32con_set_terminal_modes (void) 430 w32con_set_terminal_modes (struct terminal *t)
443 { 431 {
444 CONSOLE_CURSOR_INFO cci; 432 CONSOLE_CURSOR_INFO cci;
445 433
446 /* make cursor big and visible (100 on Win95 makes it disappear) */ 434 /* make cursor big and visible (100 on Win95 makes it disappear) */
447 cci.dwSize = 99; 435 cci.dwSize = 99;
471 { 459 {
472 SetConsoleCursorPosition (cur_screen, cursor_coords); 460 SetConsoleCursorPosition (cur_screen, cursor_coords);
473 } 461 }
474 462
475 static void 463 static void
476 w32con_set_terminal_window (int size) 464 w32con_set_terminal_window (struct frame *f, int size)
477 { 465 {
478 } 466 }
479 467
480 /*********************************************************************** 468 /***********************************************************************
481 Faces 469 Faces
544 return Qunspecified; /* meaning the default */ 532 return Qunspecified; /* meaning the default */
545 } 533 }
546 534
547 typedef int (*term_hook) (); 535 typedef int (*term_hook) ();
548 536
537 /* TEMPORARY HACK to get w32console compiling. To support multiple consoles,
538 this needs to go! */
539 struct terminal one_and_only_w32cons;
540
549 void 541 void
550 initialize_w32_display (void) 542 initialize_w32_display (void)
551 { 543 {
552 CONSOLE_SCREEN_BUFFER_INFO info; 544 CONSOLE_SCREEN_BUFFER_INFO info;
553 545 struct terminal *term = &one_and_only_w32cons;
554 cursor_to_hook = w32con_move_cursor; 546
555 raw_cursor_to_hook = w32con_move_cursor; 547 term->cursor_to_hook = w32con_move_cursor;
556 clear_to_end_hook = w32con_clear_to_end; 548 term->raw_cursor_to_hook = w32con_move_cursor;
557 clear_frame_hook = w32con_clear_frame; 549 term->clear_to_end_hook = w32con_clear_to_end;
558 clear_end_of_line_hook = w32con_clear_end_of_line; 550 term->clear_frame_hook = w32con_clear_frame;
559 ins_del_lines_hook = w32con_ins_del_lines; 551 term->clear_end_of_line_hook = w32con_clear_end_of_line;
560 insert_glyphs_hook = w32con_insert_glyphs; 552 term->ins_del_lines_hook = w32con_ins_del_lines;
561 write_glyphs_hook = w32con_write_glyphs; 553 term->insert_glyphs_hook = w32con_insert_glyphs;
562 delete_glyphs_hook = w32con_delete_glyphs; 554 term->write_glyphs_hook = w32con_write_glyphs;
563 ring_bell_hook = w32_sys_ring_bell; 555 term->delete_glyphs_hook = w32con_delete_glyphs;
564 reset_terminal_modes_hook = w32con_reset_terminal_modes; 556 term->ring_bell_hook = w32_sys_ring_bell;
565 set_terminal_modes_hook = w32con_set_terminal_modes; 557 term->reset_terminal_modes_hook = w32con_reset_terminal_modes;
566 set_terminal_window_hook = w32con_set_terminal_window; 558 term->set_terminal_modes_hook = w32con_set_terminal_modes;
567 update_begin_hook = w32con_update_begin; 559 term->set_terminal_window_hook = w32con_set_terminal_window;
568 update_end_hook = w32con_update_end; 560 term->update_begin_hook = w32con_update_begin;
569 561 term->update_end_hook = w32con_update_end;
570 read_socket_hook = w32_console_read_socket; 562
571 mouse_position_hook = w32_console_mouse_position; 563 term->read_socket_hook = w32_console_read_socket;
564 term->mouse_position_hook = w32_console_mouse_position;
572 565
573 /* Initialize interrupt_handle. */ 566 /* Initialize interrupt_handle. */
574 init_crit (); 567 init_crit ();
575 568
576 /* Remember original console settings. */ 569 /* Remember original console settings. */
631 } 624 }
632 } 625 }
633 626
634 GetConsoleScreenBufferInfo (cur_screen, &info); 627 GetConsoleScreenBufferInfo (cur_screen, &info);
635 628
636 meta_key = 1;
637 char_attr_normal = info.wAttributes; 629 char_attr_normal = info.wAttributes;
638 630
639 /* Determine if the info returned by GetConsoleScreenBufferInfo 631 /* Determine if the info returned by GetConsoleScreenBufferInfo
640 is realistic. Old MS Telnet servers used to only fill out 632 is realistic. Old MS Telnet servers used to only fill out
641 the dwSize portion, even modern one fill the whole struct with 633 the dwSize portion, even modern one fill the whole struct with
672 664
673 w32_initialize_display_info (build_string ("Console")); 665 w32_initialize_display_info (build_string ("Console"));
674 666
675 } 667 }
676 668
669 /* Initialize the tty-dependent part of frame F. The frame must
670 already have its device initialized. */
671 void
672 create_w32cons_output(struct frame *f)
673 {
674 struct tty_output *tty;
675
676 if (! FRAME_TERMCAP_P (f))
677 abort ();
678
679 tty = xmalloc (sizeof (struct tty_output));
680 bzero (tty, sizeof (struct tty_output));
681
682 tty->display_info = FRAME_TERMINAL (f)->display_info.tty;
683 tty->display_info->meta_key = 1;
684
685 f->output_data.tty = tty;
686 }
687
677 DEFUN ("set-screen-color", Fset_screen_color, Sset_screen_color, 2, 2, 0, 688 DEFUN ("set-screen-color", Fset_screen_color, Sset_screen_color, 2, 2, 0,
678 doc: /* Set screen colors. */) 689 doc: /* Set screen colors. */)
679 (foreground, background) 690 (foreground, background)
680 Lisp_Object foreground; 691 Lisp_Object foreground;
681 Lisp_Object background; 692 Lisp_Object background;