Mercurial > hg > xemacs-beta
annotate src/redisplay-tty.c @ 5750:66d2f63df75f
Correct some spelling and formatting in behavior.el.
Mentioned in tracker issue 826, the third thing mentioned there (the file
name at the bottom of the file) had already been fixed.
lisp/ChangeLog addition:
2013-08-05 Aidan Kehoe <kehoea@parhasard.net>
* behavior.el:
(override-behavior):
Correct some spelling and formatting here, thank you Steven
Mitchell in tracker issue 826.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Mon, 05 Aug 2013 10:05:32 +0100 |
parents | 81fee4aee9b6 |
children |
rev | line source |
---|---|
428 | 1 /* Communication module for TTY terminals. |
2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. | |
3 Copyright (C) 1995 Sun Microsystems, Inc. | |
793 | 4 Copyright (C) 1995, 1996, 2002 Ben Wing. |
428 | 5 Copyright (C) 1996 Chuck Thompson. |
6 | |
7 This file is part of XEmacs. | |
8 | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5178
diff
changeset
|
9 XEmacs is free software: you can redistribute it and/or modify it |
428 | 10 under the terms of the GNU General Public License as published by the |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5178
diff
changeset
|
11 Free Software Foundation, either version 3 of the License, or (at your |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5178
diff
changeset
|
12 option) any later version. |
428 | 13 |
14 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
17 for more details. | |
18 | |
19 You should have received a copy of the GNU General Public License | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5178
diff
changeset
|
20 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */ |
428 | 21 |
22 /* Synched up with: Not completely synched with FSF. Mostly divergent | |
23 from FSF. */ | |
24 | |
25 /* This file has been Mule-ized. */ | |
26 | |
27 /* Written by Chuck Thompson. */ | |
28 /* Color support added by Ben Wing. */ | |
29 | |
30 #include <config.h> | |
31 #include "lisp.h" | |
32 | |
33 #include "buffer.h" | |
872 | 34 #include "device-impl.h" |
428 | 35 #include "events.h" |
36 #include "faces.h" | |
872 | 37 #include "frame-impl.h" |
428 | 38 #include "glyphs.h" |
39 #include "lstream.h" | |
40 #include "redisplay.h" | |
41 #include "sysdep.h" | |
42 #include "window.h" | |
43 | |
872 | 44 #include "console-tty-impl.h" |
5176
8b2f75cecb89
rename objects* (.c, .h and .el files) to fontcolor*
Ben Wing <ben@xemacs.org>
parents:
4967
diff
changeset
|
45 #include "fontcolor-tty-impl.h" |
800 | 46 |
859 | 47 #include "syssignal.h" |
48 | |
428 | 49 /* These headers #define all kinds of common words like "columns"... |
50 What a bunch of losers. If we were to include them, we'd have to | |
51 include them last to prevent them from messing up our own header | |
52 files (struct slot names, etc.). But it turns out that there are | |
53 other conflicts as well on some systems, so screw it: we'll just | |
54 re-declare the routines we use and assume the code in this file is | |
55 invoking them correctly. */ | |
56 /* # include <curses.h> */ | |
57 /* # include <term.h> */ | |
442 | 58 EXTERN_C int tgetent (const char *, const char *); |
59 EXTERN_C int tgetflag (const char *); | |
60 EXTERN_C int tgetnum (const char *); | |
61 EXTERN_C char *tgetstr (const char *, char **); | |
62 EXTERN_C void tputs (const char *, int, void (*)(int)); | |
63 | |
428 | 64 #define FORCE_CURSOR_UPDATE(c) send_string_to_tty_console (c, 0, 0) |
65 #define OUTPUTN(c, a, n) \ | |
66 do { \ | |
67 cmputc_console = c; \ | |
68 FORCE_CURSOR_UPDATE (c); \ | |
69 tputs (a, n, cmputc); \ | |
70 } while (0) | |
71 #define OUTPUT1(c, a) OUTPUTN (c, a, 1) | |
72 #define OUTPUTN_IF(c, a, n) \ | |
73 do { \ | |
74 cmputc_console = c; \ | |
75 FORCE_CURSOR_UPDATE (c); \ | |
76 if (a) \ | |
77 tputs (a, n, cmputc); \ | |
78 } while (0) | |
79 #define OUTPUT1_IF(c, a) OUTPUTN_IF (c, a, 1) | |
80 | |
867 | 81 static void tty_output_ichar_dynarr (struct window *w, |
428 | 82 struct display_line *dl, |
867 | 83 Ichar_dynarr *buf, int xpos, |
428 | 84 face_index findex, |
85 int cursor); | |
867 | 86 static void tty_output_ibyte_string (struct window *w, |
428 | 87 struct display_line *dl, |
867 | 88 Ibyte *str, Bytecount len, |
428 | 89 int xpos, face_index findex, |
90 int cursor); | |
91 static void tty_turn_on_face (struct window *w, face_index findex); | |
92 static void tty_turn_off_face (struct window *w, face_index findex); | |
93 static void tty_turn_on_frame_face (struct frame *f, Lisp_Object face); | |
94 static void tty_turn_off_frame_face (struct frame *f, Lisp_Object face); | |
95 | |
96 static void term_get_fkeys (Lisp_Object keymap, char **address); | |
97 | |
98 /***************************************************************************** | |
99 tty_text_width | |
100 | |
3571 | 101 Non-Mule TTYs don't have fonts (that we use at least), so everything |
428 | 102 is considered to be fixed width -- in other words, we return LEN. |
103 Under Mule, however, a character can still cover more than one | |
867 | 104 column, so we use ichar_string_displayed_columns(). |
428 | 105 ****************************************************************************/ |
106 static int | |
5628
81fee4aee9b6
text_width methods interface cleanup.
Didier Verna <didier@xemacs.org>
parents:
5565
diff
changeset
|
107 tty_text_width (struct frame *f, struct face_cachel *UNUSED (cachel), |
2286 | 108 const Ichar *str, Charcount len) |
428 | 109 { |
5628
81fee4aee9b6
text_width methods interface cleanup.
Didier Verna <didier@xemacs.org>
parents:
5565
diff
changeset
|
110 struct console *c = FRAME_XCONSOLE (f); |
3571 | 111 |
112 if (CONSOLE_TTY_MULTIPLE_WIDTH (c)) | |
113 { | |
114 return ichar_string_displayed_columns (str, len); | |
115 } | |
116 | |
117 return len; | |
428 | 118 } |
119 | |
120 /***************************************************************************** | |
121 tty_divider_height | |
122 | |
123 Return the width of the horizontal divider. This is a function | |
124 because divider_height is a console method. | |
125 ****************************************************************************/ | |
126 static int | |
127 tty_divider_height (void) | |
128 { | |
129 return 1; | |
130 } | |
131 | |
132 /***************************************************************************** | |
133 tty_eol_cursor_width | |
134 | |
135 Return the width of the end-of-line cursor. This is a function | |
136 because eol_cursor_width is a console method. | |
137 ****************************************************************************/ | |
138 static int | |
139 tty_eol_cursor_width (void) | |
140 { | |
141 return 1; | |
142 } | |
143 | |
144 /***************************************************************************** | |
442 | 145 tty_frame_output_begin |
428 | 146 |
147 Perform any necessary initialization prior to an update. | |
148 ****************************************************************************/ | |
2286 | 149 #ifdef HAVE_TERMIOS |
150 #define TERMIOS_MAYBE_UNUSED(decl) UNUSED(decl) | |
151 #else | |
152 #define TERMIOS_MAYBE_UNUSED(decl) decl | |
153 #endif | |
154 | |
428 | 155 #ifdef DEBUG_XEMACS |
2286 | 156 void tty_frame_output_begin (struct frame *TERMIOS_MAYBE_UNUSED(f)); |
428 | 157 void |
158 #else | |
159 static void | |
160 #endif | |
2286 | 161 tty_frame_output_begin (struct frame *TERMIOS_MAYBE_UNUSED(f)) |
428 | 162 { |
163 #ifndef HAVE_TERMIOS | |
164 /* Termcap requires `ospeed' to be a global variable so we have to | |
165 always set it for whatever tty console we are actually currently | |
166 working with. */ | |
442 | 167 ospeed = DEVICE_TTY_DATA (XDEVICE (FRAME_DEVICE (f)))->ospeed; |
428 | 168 #endif |
169 } | |
170 | |
171 /***************************************************************************** | |
442 | 172 tty_frame_output_end |
428 | 173 |
174 Perform any necessary flushing of queues when an update has completed. | |
175 ****************************************************************************/ | |
176 #ifdef DEBUG_XEMACS | |
442 | 177 void tty_frame_output_end (struct frame *f); |
428 | 178 void |
179 #else | |
180 static void | |
181 #endif | |
442 | 182 tty_frame_output_end (struct frame *f) |
428 | 183 { |
442 | 184 struct console *c = XCONSOLE (FRAME_CONSOLE (f)); |
428 | 185 |
186 CONSOLE_TTY_CURSOR_X (c) = CONSOLE_TTY_FINAL_CURSOR_X (c); | |
187 CONSOLE_TTY_CURSOR_Y (c) = CONSOLE_TTY_FINAL_CURSOR_Y (c); | |
188 FORCE_CURSOR_UPDATE (c); | |
189 Lstream_flush (XLSTREAM (CONSOLE_TTY_DATA (c)->outstream)); | |
190 } | |
191 | |
192 static void | |
193 tty_set_final_cursor_coords (struct frame *f, int y, int x) | |
194 { | |
195 struct console *c = XCONSOLE (FRAME_CONSOLE (f)); | |
196 | |
197 CONSOLE_TTY_FINAL_CURSOR_X (c) = x; | |
198 CONSOLE_TTY_FINAL_CURSOR_Y (c) = y; | |
199 } | |
200 | |
201 /***************************************************************************** | |
202 tty_output_display_block | |
203 | |
204 Given a display line, a block number for that start line, output all | |
205 runes between start and end in the specified display block. | |
206 ****************************************************************************/ | |
207 static void | |
208 tty_output_display_block (struct window *w, struct display_line *dl, int block, | |
209 int start, int end, int start_pixpos, | |
2286 | 210 int cursor_start, int UNUSED (cursor_width), |
211 int UNUSED (cursor_height)) | |
428 | 212 { |
213 struct frame *f = XFRAME (w->frame); | |
3479 | 214 Ichar_dynarr *buf; |
428 | 215 |
216 struct display_block *db = Dynarr_atp (dl->display_blocks, block); | |
217 rune_dynarr *rba = db->runes; | |
218 struct rune *rb; | |
219 | |
220 int elt = start; | |
221 face_index findex; | |
222 int xpos; | |
223 | |
224 rb = Dynarr_atp (rba, elt); | |
225 | |
226 if (!rb) | |
227 { | |
228 /* Nothing to do so don't do anything. */ | |
229 return; | |
230 } | |
231 else | |
232 { | |
233 findex = rb->findex; | |
234 xpos = rb->xpos; | |
235 } | |
236 | |
237 if (end < 0) | |
238 end = Dynarr_length (rba); | |
239 | |
3479 | 240 buf = Dynarr_new (Ichar); |
428 | 241 |
242 while (elt < end && Dynarr_atp (rba, elt)->xpos < start_pixpos) | |
243 { | |
244 elt++; | |
245 findex = Dynarr_atp (rba, elt)->findex; | |
246 xpos = Dynarr_atp (rba, elt)->xpos; | |
247 } | |
248 | |
249 while (elt < end) | |
250 { | |
251 rb = Dynarr_atp (rba, elt); | |
252 | |
253 if (rb->findex == findex && rb->type == RUNE_CHAR | |
254 && rb->object.chr.ch != '\n' | |
255 && (rb->cursor_type != CURSOR_ON | |
256 || NILP (w->text_cursor_visible_p))) | |
257 { | |
258 Dynarr_add (buf, rb->object.chr.ch); | |
259 elt++; | |
260 } | |
261 else | |
262 { | |
263 if (Dynarr_length (buf)) | |
264 { | |
867 | 265 tty_output_ichar_dynarr (w, dl, buf, xpos, findex, 0); |
428 | 266 xpos = rb->xpos; |
267 } | |
268 Dynarr_reset (buf); | |
269 | |
270 if (rb->type == RUNE_CHAR) | |
271 { | |
272 findex = rb->findex; | |
273 xpos = rb->xpos; | |
274 | |
275 if (rb->object.chr.ch == '\n') | |
276 { | |
277 /* Clear in case a cursor was formerly here. */ | |
278 | |
279 Dynarr_add (buf, ' '); | |
867 | 280 tty_output_ichar_dynarr (w, dl, buf, rb->xpos, |
428 | 281 DEFAULT_INDEX, 0); |
282 Dynarr_reset (buf); | |
283 | |
284 cmgoto (f, dl->ypos - 1, rb->xpos); | |
285 | |
286 elt++; | |
287 } | |
288 else if (rb->cursor_type == CURSOR_ON) | |
289 { | |
290 /* There is not a distinct eol cursor on tty's. */ | |
291 | |
292 Dynarr_add (buf, rb->object.chr.ch); | |
867 | 293 tty_output_ichar_dynarr (w, dl, buf, xpos, findex, 0); |
428 | 294 Dynarr_reset (buf); |
295 | |
296 cmgoto (f, dl->ypos - 1, xpos); | |
297 | |
298 xpos += rb->width; | |
299 elt++; | |
300 } | |
301 } | |
302 /* #### RUNE_HLINE is actually a little more complicated than this | |
303 but at the moment it is only used to draw a turned off | |
304 modeline and this will suffice for that. */ | |
305 else if (rb->type == RUNE_BLANK || rb->type == RUNE_HLINE) | |
306 { | |
867 | 307 Ichar ch_to_add; |
428 | 308 int size = rb->width; |
309 | |
310 if (rb->type == RUNE_BLANK) | |
311 ch_to_add = ' '; | |
312 else | |
313 ch_to_add = '-'; | |
314 | |
315 while (size--) | |
316 Dynarr_add (buf, ch_to_add); | |
867 | 317 tty_output_ichar_dynarr (w, dl, buf, rb->xpos, findex, 0); |
428 | 318 |
319 if (xpos >= cursor_start | |
320 && cursor_start < xpos + Dynarr_length (buf)) | |
321 { | |
322 cmgoto (f, dl->ypos - 1, cursor_start); | |
323 } | |
324 | |
325 Dynarr_reset (buf); | |
326 | |
327 elt++; | |
328 if (elt < end) | |
329 { | |
330 rb = Dynarr_atp (rba, elt); | |
331 | |
332 findex = rb->findex; | |
333 xpos = rb->xpos; | |
334 } | |
335 } | |
336 else if (rb->type == RUNE_DGLYPH) | |
337 { | |
338 Lisp_Object window; | |
339 Lisp_Object instance; | |
340 | |
793 | 341 window = wrap_window (w); |
428 | 342 instance = glyph_image_instance (rb->object.dglyph.glyph, |
793 | 343 window, ERROR_ME_DEBUG_WARN, 1); |
428 | 344 |
345 if (IMAGE_INSTANCEP (instance)) | |
442 | 346 { |
347 switch (XIMAGE_INSTANCE_TYPE (instance)) | |
428 | 348 { |
442 | 349 case IMAGE_MONO_PIXMAP: |
350 case IMAGE_COLOR_PIXMAP: | |
351 case IMAGE_SUBWINDOW: | |
352 case IMAGE_WIDGET: | |
353 /* just do nothing here */ | |
354 break; | |
428 | 355 |
442 | 356 case IMAGE_NOTHING: |
357 /* nothing is as nothing does */ | |
358 break; | |
428 | 359 |
442 | 360 case IMAGE_TEXT: |
361 case IMAGE_POINTER: | |
362 default: | |
2500 | 363 ABORT (); |
428 | 364 } |
442 | 365 IMAGE_INSTANCE_OPTIMIZE_OUTPUT |
366 (XIMAGE_INSTANCE (instance)) = 0; | |
367 } | |
428 | 368 |
369 xpos += rb->width; | |
370 elt++; | |
371 } | |
372 else | |
2500 | 373 ABORT (); |
428 | 374 } |
375 } | |
376 | |
377 if (Dynarr_length (buf)) | |
867 | 378 tty_output_ichar_dynarr (w, dl, buf, xpos, findex, 0); |
428 | 379 Dynarr_free (buf); |
380 | |
381 } | |
382 | |
383 | |
384 | |
385 /***************************************************************************** | |
386 tty_output_vertical_divider | |
387 | |
388 Draw a vertical divider down the right side of the given window. | |
389 ****************************************************************************/ | |
390 static void | |
2286 | 391 tty_output_vertical_divider (struct window *w, int UNUSED (clear)) |
428 | 392 { |
393 /* Divider width can either be 0 or 1 on TTYs */ | |
394 if (window_divider_width (w)) | |
395 { | |
396 struct frame *f = XFRAME (w->frame); | |
397 struct console *c = XCONSOLE (FRAME_CONSOLE (f)); | |
398 int line; | |
399 int y_top = WINDOW_TEXT_TOP (w); | |
400 int y_bot = WINDOW_TEXT_BOTTOM (w); | |
401 unsigned char divv = '|'; | |
402 | |
403 tty_turn_on_face (w, MODELINE_INDEX); | |
404 for (line = y_top; line < y_bot; line++) | |
405 { | |
406 cmgoto (f, line, WINDOW_TEXT_RIGHT (w)); | |
407 send_string_to_tty_console (c, &divv, 1); | |
408 TTY_INC_CURSOR_X (c, 1); | |
409 } | |
410 | |
411 /* Draw the divider in the modeline. */ | |
412 cmgoto (f, y_bot, WINDOW_TEXT_RIGHT (w)); | |
413 send_string_to_tty_console (c, &divv, 1); | |
414 TTY_INC_CURSOR_X (c, 1); | |
415 tty_turn_off_face (w, MODELINE_INDEX); | |
416 } | |
417 } | |
418 | |
419 /**************************************************************************** | |
420 tty_clear_region | |
421 | |
422 Clear the area in the box defined by the given parameters. | |
423 ****************************************************************************/ | |
424 static void | |
5515
f87be7ddd60d
Simplify clear_region interface.
Didier Verna <didier@lrde.epita.fr>
parents:
5475
diff
changeset
|
425 tty_clear_region (Lisp_Object window, struct frame *f, face_index findex, |
f87be7ddd60d
Simplify clear_region interface.
Didier Verna <didier@lrde.epita.fr>
parents:
5475
diff
changeset
|
426 int x, int y, int width, int height, |
f87be7ddd60d
Simplify clear_region interface.
Didier Verna <didier@lrde.epita.fr>
parents:
5475
diff
changeset
|
427 Lisp_Object UNUSED (fcolor), |
2286 | 428 Lisp_Object UNUSED (bcolor), |
5080
5502045ec510
The background-placement face property.
Didier Verna <didier@lrde.epita.fr>
parents:
4967
diff
changeset
|
429 Lisp_Object UNUSED (background_pixmap), |
5502045ec510
The background-placement face property.
Didier Verna <didier@lrde.epita.fr>
parents:
4967
diff
changeset
|
430 Lisp_Object UNUSED (background_placement)) |
428 | 431 { |
432 struct console *c = XCONSOLE (FRAME_CONSOLE (f)); | |
433 int line; | |
434 struct window* w = XWINDOW (window); | |
435 | |
436 tty_turn_on_face (w, findex); | |
437 for (line = y; line < y + height; line++) | |
438 { | |
439 int col; | |
440 | |
441 cmgoto (f, line, x); | |
442 | |
443 if (window_is_leftmost (w) | |
444 && window_is_rightmost (w) | |
445 && TTY_SE (c).clr_to_eol) | |
446 { | |
447 OUTPUT1 (c, TTY_SE (c).clr_to_eol); | |
448 } | |
449 else | |
450 { | |
451 unsigned char sp = ' '; | |
452 /* #### Of course, this is all complete and utter crap. */ | |
453 for (col = x; col < x + width; col++) | |
454 send_string_to_tty_console (c, &sp, 1); | |
455 TTY_INC_CURSOR_X (c, width); | |
456 } | |
457 } | |
458 tty_turn_off_face (w, findex); | |
459 cmgoto (f, y, x); | |
460 } | |
461 | |
462 /***************************************************************************** | |
463 tty_clear_to_window_end | |
464 | |
465 Clear the area between ypos1 and ypos2. Each margin area and the | |
466 text area is handled separately since they may each have their own | |
467 background color. | |
468 ****************************************************************************/ | |
469 static void | |
470 tty_clear_to_window_end (struct window *w, int ypos1, int ypos2) | |
471 { | |
472 struct frame *f = XFRAME (w->frame); | |
473 struct console *c = XCONSOLE (FRAME_CONSOLE (f)); | |
474 int x, width; | |
475 | |
476 x = WINDOW_TEXT_LEFT (w); | |
477 width = WINDOW_TEXT_WIDTH (w); | |
478 | |
479 if (window_is_rightmost (w)) | |
480 { | |
481 /* #### Optimize to use clr_to_eol function of tty if available, if | |
482 the window is the entire width of the frame. */ | |
483 /* #### Is this actually an optimization? */ | |
484 int line; | |
485 tty_turn_on_face (w, DEFAULT_INDEX); | |
486 for (line = ypos1; line < ypos2; line++) | |
487 { | |
488 cmgoto (XFRAME (w->frame), line, x); | |
489 OUTPUT1 (c, TTY_SE (c).clr_to_eol); | |
490 } | |
491 tty_turn_off_face (w, DEFAULT_INDEX); | |
492 } | |
493 else | |
494 { | |
793 | 495 Lisp_Object window = wrap_window (w); |
428 | 496 |
497 redisplay_clear_region (window, DEFAULT_INDEX, x, ypos1, width, ypos2 - ypos1); | |
498 } | |
499 } | |
500 | |
501 /**************************************************************************** | |
502 tty_clear_frame | |
503 | |
504 Clear the entire frame. | |
505 ****************************************************************************/ | |
506 static void | |
507 tty_clear_frame (struct frame *f) | |
508 { | |
509 struct console *c = XCONSOLE (FRAME_CONSOLE (f)); | |
510 | |
511 tty_turn_on_frame_face (f, Vdefault_face); | |
512 if (TTY_SE (c).clr_frame) | |
513 { | |
514 OUTPUT1 (c, TTY_SE (c).clr_frame); | |
515 CONSOLE_TTY_REAL_CURSOR_X (c) = 0; | |
516 CONSOLE_TTY_REAL_CURSOR_Y (c) = 0; | |
517 #ifdef NOT_SURE | |
518 FRAME_CURSOR_X (f) = 0; | |
519 FRAME_CURSOR_Y (f) = 0; | |
520 #endif | |
521 } | |
522 else | |
523 { | |
524 #ifdef NOT_SURE | |
525 internal_cursor_to (f, 0, 0); | |
526 clear_to_end (f); | |
527 #else | |
528 /* #### Not implemented. */ | |
442 | 529 stderr_out ("Not yet.\n"); |
428 | 530 #endif |
531 } | |
532 tty_turn_off_frame_face (f, Vdefault_face); | |
533 } | |
534 | |
535 static void | |
867 | 536 tty_output_ibyte_string (struct window *w, struct display_line *dl, |
2286 | 537 Ibyte *str, Bytecount len, int xpos, |
538 face_index findex, int UNUSED (cursor)) | |
428 | 539 { |
540 struct frame *f = XFRAME (w->frame); | |
541 struct console *c = XCONSOLE (FRAME_CONSOLE (f)); | |
3571 | 542 int incing = CONSOLE_TTY_MULTIPLE_WIDTH (c) ? |
543 ibyte_string_displayed_columns (str, len) : | |
544 bytecount_to_charcount(str, len); | |
428 | 545 |
546 /* First position the cursor. */ | |
547 cmgoto (f, dl->ypos - 1, xpos); | |
548 | |
549 /* Enable any face properties. */ | |
550 tty_turn_on_face (w, findex); | |
551 | |
552 send_string_to_tty_console (c, str, len); | |
3571 | 553 TTY_INC_CURSOR_X (c, incing); |
428 | 554 |
555 /* Turn the face properties back off. */ | |
556 tty_turn_off_face (w, findex); | |
557 } | |
558 | |
867 | 559 static Ibyte_dynarr *tty_output_ichar_dynarr_dynarr; |
428 | 560 |
561 /***************************************************************************** | |
867 | 562 tty_output_ichar_dynarr |
428 | 563 |
564 Given a string and a starting position, output that string in the | |
565 given face. If cursor is true, draw a cursor around the string. | |
566 ****************************************************************************/ | |
567 static void | |
867 | 568 tty_output_ichar_dynarr (struct window *w, struct display_line *dl, |
569 Ichar_dynarr *buf, int xpos, face_index findex, | |
428 | 570 int cursor) |
571 { | |
867 | 572 if (!tty_output_ichar_dynarr_dynarr) |
573 tty_output_ichar_dynarr_dynarr = Dynarr_new (Ibyte); | |
428 | 574 else |
867 | 575 Dynarr_reset (tty_output_ichar_dynarr_dynarr); |
428 | 576 |
4967 | 577 convert_ichar_string_into_ibyte_dynarr (Dynarr_begin (buf), |
428 | 578 Dynarr_length (buf), |
867 | 579 tty_output_ichar_dynarr_dynarr); |
428 | 580 |
867 | 581 tty_output_ibyte_string (w, dl, |
4967 | 582 Dynarr_begin (tty_output_ichar_dynarr_dynarr), |
867 | 583 Dynarr_length (tty_output_ichar_dynarr_dynarr), |
428 | 584 xpos, findex, cursor); |
585 } | |
586 | |
587 #if 0 | |
588 | |
867 | 589 static Ibyte_dynarr *sidcs_dynarr; |
428 | 590 |
591 static void | |
592 substitute_in_dynamic_color_string (Lisp_Object spec, Lisp_Object string) | |
593 { | |
594 int i; | |
867 | 595 Ibyte *specdata = XSTRING_DATA (spec); |
428 | 596 Bytecount speclen = XSTRING_LENGTH (spec); |
597 | |
598 if (!sidcs_dynarr) | |
867 | 599 sidcs_dynarr = Dynarr_new (Ibyte); |
428 | 600 else |
601 Dynarr_reset (sidcs_dynarr); | |
602 | |
603 for (i = 0; i < speclen; i++) | |
604 { | |
605 if (specdata[i] == '%' && specdata[i+1] == '%') | |
606 { | |
607 Dynarr_add (sidcs_dynarr, '%'); | |
608 i++; | |
609 } | |
610 else if (specdata[i] == '%' && specdata[i+1] == 's') | |
611 { | |
612 Dynarr_add_many (sidcs_dynarr, | |
613 XSTRING_DATA (string), | |
614 XSTRING_LENGTH (string)); | |
615 i++; | |
616 } | |
617 else | |
618 Dynarr_add (sidcs_dynarr, specdata[i]); | |
619 } | |
620 } | |
621 | |
622 #endif | |
623 | |
624 static void | |
625 set_foreground_to (struct console *c, Lisp_Object sym) | |
626 { | |
627 Lisp_Object result; | |
867 | 628 Ibyte *escseq = 0; |
428 | 629 Bytecount escseqlen = 0; |
630 | |
631 result = assq_no_quit (sym, Vtty_color_alist); | |
632 if (!NILP (result)) | |
633 { | |
634 Lisp_Object esc_seq = XCAR (XCDR (result)); | |
635 escseq = XSTRING_DATA (esc_seq); | |
636 escseqlen = XSTRING_LENGTH (esc_seq); | |
637 } | |
638 #if 0 | |
639 else if (STRINGP (Vtty_dynamic_color_fg)) | |
640 { | |
641 substitute_in_dynamic_color_string (Vtty_dynamic_color_fg, | |
642 Fsymbol_name (sym)); | |
4967 | 643 escseq = Dynarr_begin (sidcs_dynarr); |
428 | 644 escseqlen = Dynarr_length (sidcs_dynarr); |
645 } | |
646 #endif | |
647 | |
648 if (escseq) | |
649 { | |
650 send_string_to_tty_console (c, escseq, escseqlen); | |
651 } | |
652 } | |
653 | |
654 static void | |
655 set_background_to (struct console *c, Lisp_Object sym) | |
656 { | |
657 Lisp_Object result; | |
867 | 658 Ibyte *escseq = 0; |
428 | 659 Bytecount escseqlen = 0; |
660 | |
661 result = assq_no_quit (sym, Vtty_color_alist); | |
662 if (!NILP (result)) | |
663 { | |
664 Lisp_Object esc_seq = XCDR (XCDR (result)); | |
665 escseq = XSTRING_DATA (esc_seq); | |
666 escseqlen = XSTRING_LENGTH (esc_seq); | |
667 } | |
668 #if 0 | |
669 else if (STRINGP (Vtty_dynamic_color_bg)) | |
670 { | |
671 substitute_in_dynamic_color_string (Vtty_dynamic_color_bg, | |
672 Fsymbol_name (sym)); | |
4967 | 673 escseq = Dynarr_begin (sidcs_dynarr); |
428 | 674 escseqlen = Dynarr_length (sidcs_dynarr); |
675 } | |
676 #endif | |
677 | |
678 if (escseq) | |
679 { | |
680 send_string_to_tty_console (c, escseq, escseqlen); | |
681 } | |
682 } | |
683 | |
684 static void | |
685 tty_turn_on_face_1 (struct console *c, int highlight_p, | |
686 int blinking_p, int dim_p, int underline_p, | |
687 int reverse_p, Lisp_Object cinst_fore, | |
688 Lisp_Object cinst_back) | |
689 { | |
690 if (highlight_p) | |
691 { | |
692 OUTPUT1_IF (c, TTY_SD (c).turn_on_bold); | |
693 } | |
694 | |
695 if (blinking_p) | |
696 { | |
697 OUTPUT1_IF (c, TTY_SD (c).turn_on_blinking); | |
698 } | |
699 | |
700 if (dim_p) | |
701 { | |
702 OUTPUT1_IF (c, TTY_SD (c).turn_on_dim); | |
703 } | |
704 | |
705 if (underline_p) | |
706 { | |
707 /* #### punt for now if underline mode is glitchy */ | |
708 if (!TTY_FLAGS (c).underline_width) | |
709 { | |
710 OUTPUT1_IF (c, TTY_SD (c).begin_underline); | |
711 } | |
712 } | |
713 | |
714 if (reverse_p) | |
715 { | |
716 /* #### punt for now if standout mode is glitchy */ | |
717 if (!TTY_FLAGS (c).standout_width) | |
718 { | |
719 OUTPUT1_IF (c, TTY_SD (c).begin_standout); | |
720 } | |
721 else | |
722 reverse_p = 0; | |
723 } | |
724 | |
725 if (reverse_p) | |
726 { | |
727 Lisp_Object temp = cinst_fore; | |
728 cinst_fore = cinst_back; | |
729 cinst_back = temp; | |
730 } | |
731 | |
732 if (COLOR_INSTANCEP (cinst_fore) | |
733 && !EQ (cinst_fore, Vthe_null_color_instance)) | |
734 set_foreground_to (c, COLOR_INSTANCE_TTY_SYMBOL | |
735 (XCOLOR_INSTANCE (cinst_fore))); | |
736 | |
737 if (COLOR_INSTANCEP (cinst_back) | |
738 && !EQ (cinst_back, Vthe_null_color_instance)) | |
739 set_background_to (c, COLOR_INSTANCE_TTY_SYMBOL | |
740 (XCOLOR_INSTANCE (cinst_back))); | |
741 } | |
742 | |
743 /***************************************************************************** | |
744 tty_turn_on_face | |
745 | |
746 Turn on all set properties of the given face. | |
747 ****************************************************************************/ | |
748 static void | |
749 tty_turn_on_face (struct window *w, face_index findex) | |
750 { | |
751 struct frame *f = XFRAME (w->frame); | |
752 struct console *c = XCONSOLE (FRAME_CONSOLE (f)); | |
753 | |
754 tty_turn_on_face_1 (c, | |
755 WINDOW_FACE_CACHEL_HIGHLIGHT_P (w, findex), | |
756 WINDOW_FACE_CACHEL_BLINKING_P (w, findex), | |
757 WINDOW_FACE_CACHEL_DIM_P (w, findex), | |
758 WINDOW_FACE_CACHEL_UNDERLINE_P (w, findex), | |
759 WINDOW_FACE_CACHEL_REVERSE_P (w, findex), | |
760 WINDOW_FACE_CACHEL_FOREGROUND (w, findex), | |
761 WINDOW_FACE_CACHEL_BACKGROUND (w, findex)); | |
762 } | |
763 | |
764 /***************************************************************************** | |
765 tty_turn_off_face | |
766 | |
767 Turn off all set properties of the given face (revert to default | |
768 face). We assume that tty_turn_on_face has been called for the given | |
769 face so that its properties are actually active. | |
770 ****************************************************************************/ | |
771 static void | |
772 tty_turn_off_face (struct window *w, face_index findex) | |
773 { | |
774 struct frame *f = XFRAME (w->frame); | |
775 struct console *c = XCONSOLE (FRAME_CONSOLE (f)); | |
776 | |
777 if (WINDOW_FACE_CACHEL_REVERSE_P (w, findex)) | |
778 { | |
779 /* #### punt for now if standout mode is glitchy */ | |
780 if (!TTY_FLAGS (c).standout_width) | |
781 { | |
782 OUTPUT1_IF (c, TTY_SD (c).end_standout); | |
783 } | |
784 } | |
785 | |
786 if (WINDOW_FACE_CACHEL_UNDERLINE_P (w, findex)) | |
787 { | |
788 /* #### punt for now if underline mode is glitchy */ | |
789 if (!TTY_FLAGS (c).underline_width) | |
790 { | |
791 OUTPUT1_IF (c, TTY_SD (c).end_underline); | |
792 } | |
793 } | |
794 | |
795 if (WINDOW_FACE_CACHEL_HIGHLIGHT_P (w, findex) || | |
796 WINDOW_FACE_CACHEL_BLINKING_P (w, findex) || | |
797 WINDOW_FACE_CACHEL_DIM_P (w, findex) || | |
798 !EQ (WINDOW_FACE_CACHEL_FOREGROUND (w, findex), | |
799 Vthe_null_color_instance) || | |
800 !EQ (WINDOW_FACE_CACHEL_BACKGROUND (w, findex), | |
801 Vthe_null_color_instance)) | |
802 { | |
803 OUTPUT1_IF (c, TTY_SD (c).turn_off_attributes); | |
804 } | |
805 } | |
806 | |
807 /***************************************************************************** | |
808 tty_turn_on_frame_face | |
809 | |
810 Turn on all set properties of the given face. | |
811 ****************************************************************************/ | |
812 static void | |
813 tty_turn_on_frame_face (struct frame *f, Lisp_Object face) | |
814 { | |
815 Lisp_Object frame; | |
816 struct console *c = XCONSOLE (FRAME_CONSOLE (f)); | |
817 | |
793 | 818 frame = wrap_frame (f); |
428 | 819 tty_turn_on_face_1 (c, |
820 FACE_HIGHLIGHT_P (face, frame), | |
821 FACE_BLINKING_P (face, frame), | |
822 FACE_DIM_P (face, frame), | |
823 FACE_UNDERLINE_P (face, frame), | |
824 FACE_REVERSE_P (face, frame), | |
825 FACE_FOREGROUND (face, frame), | |
826 FACE_BACKGROUND (face, frame)); | |
827 } | |
828 | |
829 /***************************************************************************** | |
830 tty_turn_off_frame_face | |
831 | |
832 Turn off all set properties of the given face (revert to default | |
833 face). We assume that tty_turn_on_face has been called for the given | |
834 face so that its properties are actually active. | |
835 ****************************************************************************/ | |
836 static void | |
837 tty_turn_off_frame_face (struct frame *f, Lisp_Object face) | |
838 { | |
839 Lisp_Object frame; | |
840 struct console *c = XCONSOLE (FRAME_CONSOLE (f)); | |
841 | |
793 | 842 frame = wrap_frame (f); |
428 | 843 |
844 if (FACE_REVERSE_P (face, frame)) | |
845 { | |
846 /* #### punt for now if standout mode is glitchy */ | |
847 if (!TTY_FLAGS (c).standout_width) | |
848 { | |
849 OUTPUT1_IF (c, TTY_SD (c).end_standout); | |
850 } | |
851 } | |
852 | |
853 if (FACE_UNDERLINE_P (face, frame)) | |
854 { | |
855 /* #### punt for now if underline mode is glitchy */ | |
856 if (!TTY_FLAGS (c).underline_width) | |
857 { | |
858 OUTPUT1_IF (c, TTY_SD (c).end_underline); | |
859 } | |
860 } | |
861 | |
862 if (FACE_HIGHLIGHT_P (face, frame) || | |
863 FACE_BLINKING_P (face, frame) || | |
864 FACE_DIM_P (face, frame) || | |
865 !EQ (FACE_FOREGROUND (face, frame), Vthe_null_color_instance) || | |
866 !EQ (FACE_BACKGROUND (face, frame), Vthe_null_color_instance)) | |
867 { | |
868 OUTPUT1_IF (c, TTY_SD (c).turn_off_attributes); | |
869 } | |
870 } | |
871 | |
872 /***************************************************************************** | |
873 set_tty_modes | |
874 | |
875 Sets up various parameters on tty modes. | |
876 ****************************************************************************/ | |
877 void | |
878 set_tty_modes (struct console *c) | |
879 { | |
880 if (!CONSOLE_TTY_P (c)) | |
881 return; | |
882 | |
883 OUTPUT1_IF (c, TTY_SD (c).init_motion); | |
884 OUTPUT1_IF (c, TTY_SD (c).cursor_visible); | |
885 OUTPUT1_IF (c, TTY_SD (c).keypad_on); | |
886 } | |
887 | |
888 /***************************************************************************** | |
889 reset_tty_modes | |
890 | |
891 Restore default state of tty. | |
892 ****************************************************************************/ | |
893 void | |
894 reset_tty_modes (struct console *c) | |
895 { | |
896 if (!CONSOLE_TTY_P (c)) | |
897 return; | |
898 | |
899 OUTPUT1_IF (c, TTY_SD (c).orig_pair); | |
900 OUTPUT1_IF (c, TTY_SD (c).keypad_off); | |
901 OUTPUT1_IF (c, TTY_SD (c).cursor_normal); | |
902 OUTPUT1_IF (c, TTY_SD (c).end_motion); | |
442 | 903 |
904 { | |
905 Lisp_Object frm = CONSOLE_SELECTED_FRAME (c); | |
906 | |
907 if (!NILP (frm)) | |
908 tty_frame_output_end (XFRAME (frm)); | |
909 } | |
428 | 910 } |
911 | |
912 /***************************************************************************** | |
913 tty_redisplay_shutdown | |
914 | |
915 Clear the frame and position the cursor properly for exiting. | |
916 ****************************************************************************/ | |
917 void | |
918 tty_redisplay_shutdown (struct console *c) | |
919 { | |
920 Lisp_Object dev = CONSOLE_SELECTED_DEVICE (c); | |
921 | |
922 if (!NILP (dev)) | |
923 { | |
924 Lisp_Object frm = DEVICE_SELECTED_FRAME (XDEVICE (dev)); | |
925 | |
926 if (!NILP (frm)) | |
927 { | |
928 struct frame *f = XFRAME (frm); | |
929 | |
930 /* Clear the bottom line of the frame. */ | |
931 redisplay_clear_region (FRAME_SELECTED_WINDOW (f), DEFAULT_INDEX, 0, | |
932 f->height, f->width, 1); | |
933 | |
934 /* And then stick the cursor there. */ | |
935 tty_set_final_cursor_coords (f, f->height, 0); | |
442 | 936 tty_frame_output_end (f); |
428 | 937 } |
938 } | |
939 } | |
940 | |
941 | |
942 /* #### Everything below here is old shit. It should either be moved | |
943 up or removed. */ | |
944 | |
945 | |
444 | 946 #ifdef NOT_YET |
428 | 947 /* FLAGS - these don't need to be console local since only one console |
442 | 948 can be being updated at a time. */ |
428 | 949 static int insert_mode_on; /* nonzero if in insert mode */ |
950 static int standout_mode_on; /* nonzero if in standout mode */ | |
951 static int underline_mode_on; /* nonzero if in underline mode */ | |
952 static int alternate_mode_on; /* nonzero if in alternate char set */ | |
953 static int attributes_on; /* nonzero if any attributes on */ | |
954 | |
955 static void | |
956 turn_on_insert (struct frame *f) | |
957 { | |
958 struct console *c = XCONSOLE (FRAME_CONSOLE (f)); | |
959 | |
960 if (!insert_mode_on) | |
961 OUTPUT1_IF (c, TTY_SE (c).begin_ins_mode); | |
962 insert_mode_on = 1; | |
963 } | |
964 | |
965 static void | |
966 turn_off_insert (struct frame *f) | |
967 { | |
968 struct console *c = XCONSOLE (FRAME_CONSOLE (f)); | |
969 | |
970 if (insert_mode_on) | |
971 OUTPUT1 (c, TTY_SE (c).end_ins_mode); | |
972 insert_mode_on = 0; | |
973 } | |
974 | |
975 static void | |
976 internal_cursor_to (struct frame *f, int row, int col) | |
977 { | |
978 struct console *c = XCONSOLE (FRAME_CONSOLE (f)); | |
979 | |
980 if (!TTY_FLAGS (c).insert_mode_motion) | |
981 turn_off_insert (f); | |
982 if (!TTY_FLAGS (c).standout_motion) | |
983 { | |
984 turn_off_standout (f); | |
985 turn_off_underline (f); | |
986 turn_off_alternate (f); | |
987 } | |
988 | |
989 cmgoto (f, row, col); | |
990 } | |
991 | |
992 static void | |
993 clear_to_end (struct frame *f) | |
994 { | |
995 struct console *c = XCONSOLE (FRAME_CONSOLE (f)); | |
996 | |
997 /* assumes cursor is already positioned */ | |
998 if (TTY_SE (c).clr_from_cursor) | |
999 { | |
1000 OUTPUT1 (c, TTY_SE (c).clr_from_cursor); | |
1001 } | |
1002 else | |
1003 { | |
1004 int line = FRAME_CURSOR_Y (f); | |
1005 | |
1006 while (line < FRAME_HEIGHT (f)) | |
1007 { | |
1008 internal_cursor_to (f, line, 0); | |
1009 OUTPUT1 (c, TTY_SE (c).clr_to_eol); | |
1010 } | |
1011 } | |
1012 } | |
1013 #endif /* 0 */ | |
1014 | |
1015 #if 0 | |
1016 /* | |
1017 * clear from last visible line on window to window end (presumably | |
1018 * the line above window's modeline | |
1019 */ | |
1020 static void | |
1021 tty_clear_window_end (struct window *w, int ystart, int yend) | |
1022 { | |
1023 struct console *c = XCONSOLE (WINDOW_CONSOLE (w)); | |
1024 int line; | |
1025 | |
1026 for (line = ystart; line < yend; line++) | |
1027 { | |
1028 cmgoto (XFRAME (w->frame), line, 0); | |
1029 OUTPUT1 (c, TTY_SE (c).clr_to_eol); | |
1030 } | |
1031 } | |
1032 | |
1033 #endif /* 0 */ | |
1034 | |
1035 static int | |
1036 tty_flash (struct device *d) | |
1037 { | |
1038 struct console *c = XCONSOLE (DEVICE_CONSOLE (d)); | |
1039 if (TTY_SD (c).visual_bell) | |
1040 { | |
1041 OUTPUT1 (c, TTY_SD (c).visual_bell); | |
1042 Lstream_flush (XLSTREAM (CONSOLE_TTY_DATA (c)->outstream)); | |
1043 return 1; | |
1044 } | |
1045 else | |
1046 return 0; | |
1047 } | |
1048 | |
1049 /* | |
1050 * tty_ring_bell - sound an audio beep. | |
1051 */ | |
1052 static void | |
2286 | 1053 tty_ring_bell (struct device *d, int volume, int UNUSED (pitch), |
1054 int UNUSED (duration)) | |
428 | 1055 { |
1056 struct console *c = XCONSOLE (DEVICE_CONSOLE (d)); | |
1057 | |
1058 if (volume) | |
1059 { | |
1060 OUTPUT1 (c, TTY_SD (c).audio_bell); | |
1061 Lstream_flush (XLSTREAM (CONSOLE_TTY_DATA (c)->outstream)); | |
1062 } | |
1063 } | |
1064 | |
1065 | |
1066 int | |
1067 init_tty_for_redisplay (struct device *d, char *terminal_type) | |
1068 { | |
2367 | 1069 /* !!#### Mule-ize this */ |
428 | 1070 int status; |
1071 char entry_buffer[2044]; | |
1072 /* char temp_buffer[2044]; */ | |
1073 char *bufptr; | |
1074 struct console *c = XCONSOLE (DEVICE_CONSOLE (d)); | |
1075 | |
1076 /* What we should really do is allocate just enough space for | |
1077 the actual strings that are stored; but this would require | |
1078 doing this after all the tgetstr()s and adjusting all the | |
1079 pointers. */ | |
1080 CONSOLE_TTY_DATA (c)->term_entry_buffer = (char *) xmalloc (2044); | |
1081 bufptr = CONSOLE_TTY_DATA (c)->term_entry_buffer; | |
1082 | |
442 | 1083 #ifdef SIGTTOU |
428 | 1084 /* SIGTT* don't exist under win32 */ |
1085 EMACS_BLOCK_SIGNAL (SIGTTOU); | |
1086 #endif | |
1087 status = tgetent (entry_buffer, terminal_type); | |
442 | 1088 #ifdef SIGTTOU |
428 | 1089 EMACS_UNBLOCK_SIGNAL (SIGTTOU); |
1090 #endif | |
1091 #if 0 | |
1092 if (status < 0) | |
1093 return TTY_UNABLE_OPEN_DATABASE; | |
1094 else if (status == 0) | |
1095 return TTY_TYPE_UNDEFINED; | |
1096 #endif | |
1097 /* Under Linux at least, <0 is returned for TTY_TYPE_UNDEFINED. --ben */ | |
1098 if (status <= 0) | |
1099 return TTY_TYPE_UNDEFINED; | |
1100 | |
1101 /* | |
1102 * Establish the terminal size. | |
1103 */ | |
1104 /* First try to get the info from the system. If that fails, check | |
1105 the termcap entry. */ | |
1106 get_tty_device_size (d, &CONSOLE_TTY_DATA (c)->width, | |
1107 &CONSOLE_TTY_DATA (c)->height); | |
1108 | |
1109 if (CONSOLE_TTY_DATA (c)->width <= 0) | |
1110 CONSOLE_TTY_DATA (c)->width = tgetnum ("co"); | |
1111 if (CONSOLE_TTY_DATA (c)->height <= 0) | |
1112 CONSOLE_TTY_DATA (c)->height = tgetnum ("li"); | |
1113 | |
1114 if (CONSOLE_TTY_DATA (c)->width <= 0 || CONSOLE_TTY_DATA (c)->height <= 0) | |
1115 return TTY_SIZE_UNSPECIFIED; | |
1116 | |
5398
5256fedd50e6
issue 757 - tty device metric for num-color-cells
Jeff Sparkes <jsparkes@gmail.com>
parents:
5178
diff
changeset
|
1117 CONSOLE_TTY_DATA (c)->colors = tgetnum("Co"); |
5256fedd50e6
issue 757 - tty device metric for num-color-cells
Jeff Sparkes <jsparkes@gmail.com>
parents:
5178
diff
changeset
|
1118 if (CONSOLE_TTY_DATA (c)->colors == 0) |
5256fedd50e6
issue 757 - tty device metric for num-color-cells
Jeff Sparkes <jsparkes@gmail.com>
parents:
5178
diff
changeset
|
1119 CONSOLE_TTY_DATA (c)->colors = tgetnum("colors"); |
5256fedd50e6
issue 757 - tty device metric for num-color-cells
Jeff Sparkes <jsparkes@gmail.com>
parents:
5178
diff
changeset
|
1120 if (CONSOLE_TTY_DATA (c)->colors == 0) |
5256fedd50e6
issue 757 - tty device metric for num-color-cells
Jeff Sparkes <jsparkes@gmail.com>
parents:
5178
diff
changeset
|
1121 /* There is always foreground and background. */ |
5256fedd50e6
issue 757 - tty device metric for num-color-cells
Jeff Sparkes <jsparkes@gmail.com>
parents:
5178
diff
changeset
|
1122 CONSOLE_TTY_DATA (c)->colors = 2; |
5256fedd50e6
issue 757 - tty device metric for num-color-cells
Jeff Sparkes <jsparkes@gmail.com>
parents:
5178
diff
changeset
|
1123 |
428 | 1124 /* |
1125 * Initialize cursor motion information. | |
1126 */ | |
1127 | |
1128 /* local cursor movement */ | |
1129 TTY_CM (c).up = tgetstr ("up", &bufptr); | |
1130 TTY_CM (c).down = tgetstr ("do", &bufptr); | |
1131 TTY_CM (c).left = tgetstr ("le", &bufptr); | |
1132 TTY_CM (c).right = tgetstr ("nd", &bufptr); | |
1133 TTY_CM (c).home = tgetstr ("ho", &bufptr); | |
1134 TTY_CM (c).low_left = tgetstr ("ll", &bufptr); | |
1135 TTY_CM (c).car_return = tgetstr ("cr", &bufptr); | |
1136 | |
1137 /* absolute cursor motion */ | |
1138 TTY_CM (c).abs = tgetstr ("cm", &bufptr); | |
1139 TTY_CM (c).hor_abs = tgetstr ("ch", &bufptr); | |
1140 TTY_CM (c).ver_abs = tgetstr ("cv", &bufptr); | |
1141 | |
1142 /* Verify that the terminal is powerful enough to run Emacs */ | |
1143 if (!TTY_CM (c).abs) | |
1144 { | |
1145 if (!TTY_CM (c).up || !TTY_CM (c).down | |
1146 || !TTY_CM (c).left || !TTY_CM (c).right) | |
1147 return TTY_TYPE_INSUFFICIENT; | |
1148 } | |
1149 | |
1150 /* parameterized local cursor movement */ | |
1151 TTY_CM (c).multi_up = tgetstr ("UP", &bufptr); | |
1152 TTY_CM (c).multi_down = tgetstr ("DO", &bufptr); | |
1153 TTY_CM (c).multi_left = tgetstr ("LE", &bufptr); | |
1154 TTY_CM (c).multi_right = tgetstr ("RI", &bufptr); | |
1155 | |
1156 /* scrolling */ | |
1157 TTY_CM (c).scroll_forw = tgetstr ("sf", &bufptr); | |
1158 TTY_CM (c).scroll_back = tgetstr ("sr", &bufptr); | |
1159 TTY_CM (c).multi_scroll_forw = tgetstr ("SF", &bufptr); | |
1160 TTY_CM (c).multi_scroll_back = tgetstr ("SR", &bufptr); | |
1161 TTY_CM (c).set_scroll_region = tgetstr ("cs", &bufptr); | |
1162 | |
1163 | |
1164 /* | |
1165 * Initialize screen editing information. | |
1166 */ | |
1167 | |
1168 /* adding to the screen */ | |
1169 TTY_SE (c).ins_line = tgetstr ("al", &bufptr); | |
1170 TTY_SE (c).multi_ins_line = tgetstr ("AL", &bufptr); | |
1171 TTY_SE (c).repeat = tgetstr ("rp", &bufptr); | |
1172 TTY_SE (c).begin_ins_mode = tgetstr ("im", &bufptr); | |
1173 TTY_SE (c).end_ins_mode = tgetstr ("ei", &bufptr); | |
1174 TTY_SE (c).ins_char = tgetstr ("ic", &bufptr); | |
1175 TTY_SE (c).multi_ins_char = tgetstr ("IC", &bufptr); | |
1176 TTY_SE (c).insert_pad = tgetstr ("ip", &bufptr); | |
1177 | |
1178 /* deleting from the screen */ | |
1179 TTY_SE (c).clr_frame = tgetstr ("cl", &bufptr); | |
1180 TTY_SE (c).clr_from_cursor = tgetstr ("cd", &bufptr); | |
1181 TTY_SE (c).clr_to_eol = tgetstr ("ce", &bufptr); | |
1182 TTY_SE (c).del_line = tgetstr ("dl", &bufptr); | |
1183 TTY_SE (c).multi_del_line = tgetstr ("DL", &bufptr); | |
1184 TTY_SE (c).del_char = tgetstr ("dc", &bufptr); | |
1185 TTY_SE (c).multi_del_char = tgetstr ("DC", &bufptr); | |
1186 TTY_SE (c).begin_del_mode = tgetstr ("dm", &bufptr); | |
1187 TTY_SE (c).end_del_mode = tgetstr ("ed", &bufptr); | |
1188 TTY_SE (c).erase_at_cursor = tgetstr ("ec", &bufptr); | |
1189 | |
1190 | |
1191 /* | |
1192 * Initialize screen display information. | |
1193 */ | |
1194 TTY_SD (c).begin_standout = tgetstr ("so", &bufptr); | |
1195 TTY_SD (c).end_standout = tgetstr ("se", &bufptr); | |
1196 TTY_SD (c).begin_underline = tgetstr ("us", &bufptr); | |
1197 TTY_SD (c).end_underline = tgetstr ("ue", &bufptr); | |
1198 TTY_SD (c).begin_alternate = tgetstr ("as", &bufptr); | |
1199 TTY_SD (c).end_alternate = tgetstr ("ae", &bufptr); | |
1200 TTY_SD (c).turn_on_reverse = tgetstr ("mr", &bufptr); | |
1201 TTY_SD (c).turn_on_blinking = tgetstr ("mb", &bufptr); | |
1202 TTY_SD (c).turn_on_bold = tgetstr ("md", &bufptr); | |
1203 TTY_SD (c).turn_on_dim = tgetstr ("mh", &bufptr); | |
1204 TTY_SD (c).turn_off_attributes = tgetstr ("me", &bufptr); | |
1205 TTY_SD (c).orig_pair = tgetstr ("op", &bufptr); | |
1206 | |
1207 TTY_SD (c).visual_bell = tgetstr ("vb", &bufptr); | |
1208 TTY_SD (c).audio_bell = tgetstr ("bl", &bufptr); | |
1209 if (!TTY_SD (c).audio_bell) | |
1210 { | |
1211 /* If audio_bell doesn't get set, then assume C-g. This is gross and | |
1212 ugly but is what Emacs has done from time immortal. */ | |
1213 TTY_SD (c).audio_bell = "\07"; | |
1214 } | |
1215 | |
1216 TTY_SD (c).cursor_visible = tgetstr ("ve", &bufptr); | |
1217 TTY_SD (c).cursor_normal = tgetstr ("vs", &bufptr); | |
1218 TTY_SD (c).init_motion = tgetstr ("ti", &bufptr); | |
1219 TTY_SD (c).end_motion = tgetstr ("te", &bufptr); | |
1220 TTY_SD (c).keypad_on = tgetstr ("ks", &bufptr); | |
1221 TTY_SD (c).keypad_off = tgetstr ("ke", &bufptr); | |
1222 | |
1223 | |
1224 /* | |
1225 * Initialize additional terminal information. | |
1226 */ | |
1227 TTY_FLAGS (c).must_write_spaces = tgetflag ("in"); | |
1228 TTY_FLAGS (c).insert_mode_motion = tgetflag ("mi"); | |
1229 TTY_FLAGS (c).standout_motion = tgetflag ("ms"); | |
1230 TTY_FLAGS (c).memory_above_frame = tgetflag ("da"); | |
1231 TTY_FLAGS (c).memory_below_frame = tgetflag ("db"); | |
1232 TTY_FLAGS (c).standout_width = tgetnum ("sg"); | |
1233 TTY_FLAGS (c).underline_width = tgetnum ("ug"); | |
1234 | |
1235 if (TTY_FLAGS (c).standout_width == -1) | |
1236 TTY_FLAGS (c).standout_width = 0; | |
1237 if (TTY_FLAGS (c).underline_width == -1) | |
1238 TTY_FLAGS (c).underline_width = 0; | |
1239 | |
5565
48a3d3281b48
Pass eighth bit on TTY consoles to coding system if needed.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5515
diff
changeset
|
1240 if (eight_bit_tty (d)) |
48a3d3281b48
Pass eighth bit on TTY consoles to coding system if needed.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5515
diff
changeset
|
1241 { |
48a3d3281b48
Pass eighth bit on TTY consoles to coding system if needed.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5515
diff
changeset
|
1242 TTY_FLAGS (c).meta_key |
48a3d3281b48
Pass eighth bit on TTY consoles to coding system if needed.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5515
diff
changeset
|
1243 = (EQ (Qiso2022, Fcoding_system_type (Qnative)) |
48a3d3281b48
Pass eighth bit on TTY consoles to coding system if needed.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5515
diff
changeset
|
1244 && EQ (Qt, Fcoding_system_property (Qnative, Qseven)) |
48a3d3281b48
Pass eighth bit on TTY consoles to coding system if needed.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5515
diff
changeset
|
1245 && (tgetflag ("km") || tgetflag ("MT"))) ? 1 : 2; |
48a3d3281b48
Pass eighth bit on TTY consoles to coding system if needed.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5515
diff
changeset
|
1246 } |
48a3d3281b48
Pass eighth bit on TTY consoles to coding system if needed.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5515
diff
changeset
|
1247 else |
48a3d3281b48
Pass eighth bit on TTY consoles to coding system if needed.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5515
diff
changeset
|
1248 { |
48a3d3281b48
Pass eighth bit on TTY consoles to coding system if needed.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5515
diff
changeset
|
1249 TTY_FLAGS (c).meta_key = 0; |
48a3d3281b48
Pass eighth bit on TTY consoles to coding system if needed.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5515
diff
changeset
|
1250 } |
428 | 1251 |
1252 /* | |
1253 * Setup the costs tables for this tty console. | |
1254 */ | |
1255 cm_cost_init (c); | |
1256 | |
444 | 1257 #ifdef NOT_YET |
428 | 1258 /* |
1259 * Initialize local flags. | |
1260 */ | |
1261 insert_mode_on = 0; | |
1262 standout_mode_on = 0; | |
1263 underline_mode_on = 0; | |
1264 alternate_mode_on = 0; | |
1265 attributes_on = 0; | |
444 | 1266 #endif |
428 | 1267 |
1268 /* | |
1269 * Attempt to initialize the function_key_map to | |
1270 * some kind of sensible value | |
1271 */ | |
1272 | |
1273 term_get_fkeys (c->function_key_map, &bufptr); | |
1274 | |
1275 { | |
1276 /* check for ANSI set-foreground and set-background strings, | |
1277 and assume color if so. | |
1278 | |
1279 #### we should support the other (non-ANSI) ways of specifying | |
1280 color, too. */ | |
1281 char foobuf[500]; | |
1282 char *fooptr = foobuf; | |
1283 if ((tgetstr ("AB", &fooptr) && tgetstr ("AF", &fooptr)) || | |
1284 (tgetstr ("Sf", &fooptr) && tgetstr ("Sb", &fooptr)) || | |
1285 ((tgetnum ("Co") > 0) && (tgetnum ("pa") > 0))) | |
1286 DEVICE_CLASS (d) = Qcolor; | |
1287 else | |
1288 DEVICE_CLASS (d) = Qmono; | |
1289 } | |
1290 | |
1291 return TTY_INIT_SUCCESS; | |
1292 } | |
1293 | |
1294 struct fkey_table | |
1295 { | |
442 | 1296 const char *cap; |
1297 const char *name; | |
428 | 1298 }; |
1299 | |
1300 /* Termcap capability names that correspond directly to X keysyms. | |
1301 Some of these (marked "terminfo") aren't supplied by old-style | |
1302 (Berkeley) termcap entries. They're listed in X keysym order; | |
1303 except we put the keypad keys first, so that if they clash with | |
1304 other keys (as on the IBM PC keyboard) they get overridden. | |
1305 */ | |
1306 | |
1307 static struct fkey_table keys[] = | |
1308 { | |
1309 {"kh", "home"}, /* termcap */ | |
1310 {"kl", "left"}, /* termcap */ | |
1311 {"ku", "up"}, /* termcap */ | |
1312 {"kr", "right"}, /* termcap */ | |
1313 {"kd", "down"}, /* termcap */ | |
1314 {"%8", "prior"}, /* terminfo */ | |
1315 {"%5", "next"}, /* terminfo */ | |
1316 {"@7", "end"}, /* terminfo */ | |
1317 {"@1", "begin"}, /* terminfo */ | |
1318 {"*6", "select"}, /* terminfo */ | |
1319 {"%9", "print"}, /* terminfo */ | |
1320 {"@4", "execute"}, /* terminfo --- actually the `command' key */ | |
1321 /* | |
1322 * "insert" --- see below | |
1323 */ | |
1324 {"&8", "undo"}, /* terminfo */ | |
1325 {"%0", "redo"}, /* terminfo */ | |
1326 {"%7", "menu"}, /* terminfo --- actually the `options' key */ | |
1327 {"@0", "find"}, /* terminfo */ | |
1328 {"@2", "cancel"}, /* terminfo */ | |
1329 {"%1", "help"}, /* terminfo */ | |
1330 /* | |
1331 * "break" goes here, but can't be reliably intercepted with termcap | |
1332 */ | |
1333 {"&4", "reset"}, /* terminfo --- actually `restart' */ | |
1334 /* | |
1335 * "system" and "user" --- no termcaps | |
1336 */ | |
1337 {"kE", "clearline"}, /* terminfo */ | |
1338 {"kA", "insertline"}, /* terminfo */ | |
1339 {"kL", "deleteline"}, /* terminfo */ | |
1340 {"kI", "insertchar"}, /* terminfo */ | |
1341 {"kD", "delete"}, /* terminfo */ | |
1342 {"kB", "backtab"}, /* terminfo */ | |
1343 /* | |
1344 * "kp-backtab", "kp-space", "kp-tab" --- no termcaps | |
1345 */ | |
1346 {"@8", "kp-enter"}, /* terminfo */ | |
1347 /* | |
1348 * "kp-f1", "kp-f2", "kp-f3" "kp-f4", | |
1349 * "kp-multiply", "kp-add", "kp-separator", | |
1350 * "kp-subtract", "kp-decimal", "kp-divide", "kp-0"; | |
1351 * --- no termcaps for any of these. | |
1352 */ | |
1353 {"K4", "kp-1"}, /* terminfo */ | |
1354 /* | |
1355 * "kp-2" --- no termcap | |
1356 */ | |
1357 {"K5", "kp-3"}, /* terminfo */ | |
1358 /* | |
1359 * "kp-4" --- no termcap | |
1360 */ | |
1361 {"K2", "kp-5"}, /* terminfo */ | |
1362 /* | |
1363 * "kp-6" --- no termcap | |
1364 */ | |
1365 {"K1", "kp-7"}, /* terminfo */ | |
1366 /* | |
1367 * "kp-8" --- no termcap | |
1368 */ | |
1369 {"K3", "kp-9"}, /* terminfo */ | |
1370 /* | |
1371 * "kp-equal" --- no termcap | |
1372 */ | |
1373 {"k1", "f1"}, | |
1374 {"k2", "f2"}, | |
1375 {"k3", "f3"}, | |
1376 {"k4", "f4"}, | |
1377 {"k5", "f5"}, | |
1378 {"k6", "f6"}, | |
1379 {"k7", "f7"}, | |
1380 {"k8", "f8"}, | |
1381 {"k9", "f9"}, | |
1382 }; | |
1383 | |
1384 static char **term_get_fkeys_arg; | |
1385 | |
1386 static Lisp_Object term_get_fkeys_1 (Lisp_Object keymap); | |
1387 static Lisp_Object term_get_fkeys_error (Lisp_Object err, Lisp_Object arg); | |
1388 | |
1389 /* Find the escape codes sent by the function keys for Vfunction_key_map. | |
1390 This function scans the termcap function key sequence entries, and | |
1391 adds entries to Vfunction_key_map for each function key it finds. */ | |
1392 | |
1393 static void | |
1394 term_get_fkeys (Lisp_Object keymap, char **address) | |
1395 { | |
1396 /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp | |
1397 errors during the call. The only errors should be from Fdefine_key | |
1398 when given a key sequence containing an invalid prefix key. If the | |
1399 termcap defines function keys which use a prefix that is already bound | |
1400 to a command by the default bindings, we should silently ignore that | |
1401 function key specification, rather than giving the user an error and | |
1402 refusing to run at all on such a terminal. */ | |
1403 | |
1404 term_get_fkeys_arg = address; | |
1405 | |
1406 condition_case_1 (Qerror, | |
1407 term_get_fkeys_1, keymap, | |
1408 term_get_fkeys_error, Qnil); | |
1409 } | |
1410 | |
1411 static Lisp_Object | |
2286 | 1412 term_get_fkeys_error (Lisp_Object UNUSED (err), Lisp_Object arg) |
428 | 1413 { |
1414 return arg; | |
1415 } | |
1416 | |
1417 static Lisp_Object | |
1418 term_get_fkeys_1 (Lisp_Object function_key_map) | |
1419 { | |
1420 int i; | |
1421 | |
1422 char **address = term_get_fkeys_arg; | |
1423 | |
1424 for (i = 0; i < countof (keys); i++) | |
1425 { | |
1426 char *sequence = tgetstr (keys[i].cap, address); | |
1427 if (sequence) | |
1428 Fdefine_key (function_key_map, | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4928
diff
changeset
|
1429 build_extstring (sequence, Qbinary), |
428 | 1430 vector1 (intern (keys[i].name))); |
1431 } | |
1432 | |
1433 /* The uses of the "k0" capability are inconsistent; sometimes it | |
1434 describes F10, whereas othertimes it describes F0 and "k;" describes F10. | |
1435 We will attempt to politely accommodate both systems by testing for | |
1436 "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10. | |
1437 */ | |
1438 { | |
442 | 1439 const char *k_semi = tgetstr ("k;", address); |
1440 const char *k0 = tgetstr ("k0", address); | |
428 | 1441 |
1442 if (k_semi) | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4928
diff
changeset
|
1443 Fdefine_key (function_key_map, build_extstring (k_semi, Qbinary), |
428 | 1444 vector1 (intern ("f10"))); |
1445 | |
1446 if (k0) | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4928
diff
changeset
|
1447 Fdefine_key (function_key_map, build_extstring (k0, Qbinary), |
428 | 1448 vector1 (intern (k_semi ? "f0" : "f10"))); |
1449 } | |
1450 | |
1451 /* Set up cookies for numbered function keys above f10. */ | |
1452 { | |
1453 char fcap[3], fkey[4]; | |
1454 | |
1455 fcap[0] = 'F'; fcap[2] = '\0'; | |
1456 for (i = 11; i < 64; i++) | |
1457 { | |
1458 if (i <= 19) | |
1459 fcap[1] = '1' + i - 11; | |
1460 else if (i <= 45) | |
1461 fcap[1] = 'A' + i - 20; | |
1462 else | |
1463 fcap[1] = 'a' + i - 46; | |
1464 | |
1465 { | |
1466 char *sequence = tgetstr (fcap, address); | |
1467 if (sequence) | |
1468 { | |
1469 sprintf (fkey, "f%d", i); | |
1470 Fdefine_key (function_key_map, | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4928
diff
changeset
|
1471 build_extstring (sequence, Qbinary), |
428 | 1472 vector1 (intern (fkey))); |
1473 } | |
1474 } | |
1475 } | |
1476 } | |
1477 | |
1478 /* | |
1479 * Various mappings to try and get a better fit. | |
1480 */ | |
440 | 1481 #define CONDITIONAL_REASSIGN(cap1, cap2, keyname) do { \ |
1482 if (!tgetstr (cap1, address)) \ | |
1483 { \ | |
1484 char *sequence = tgetstr (cap2, address); \ | |
1485 if (sequence) \ | |
1486 Fdefine_key (function_key_map, \ | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4928
diff
changeset
|
1487 build_extstring (sequence, Qbinary), \ |
440 | 1488 vector1 (intern (keyname))); \ |
1489 } \ | |
1490 } while (0) | |
428 | 1491 |
1492 /* if there's no key_next keycap, map key_npage to `next' keysym */ | |
1493 CONDITIONAL_REASSIGN ("%5", "kN", "next"); | |
1494 /* if there's no key_prev keycap, map key_ppage to `previous' keysym */ | |
1495 CONDITIONAL_REASSIGN ("%8", "kP", "prior"); | |
1496 /* if there's no key_dc keycap, map key_ic to `insert' keysym */ | |
1497 CONDITIONAL_REASSIGN ("kD", "kI", "insert"); | |
1498 | |
1499 /* IBM has their own non-standard dialect of terminfo. | |
1500 If the standard name isn't found, try the IBM name. */ | |
1501 CONDITIONAL_REASSIGN ("kB", "KO", "backtab"); | |
1502 CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */ | |
1503 CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */ | |
1504 CONDITIONAL_REASSIGN ("%7", "ki", "menu"); | |
1505 CONDITIONAL_REASSIGN ("@7", "kw", "end"); | |
1506 CONDITIONAL_REASSIGN ("F1", "k<", "f11"); | |
1507 CONDITIONAL_REASSIGN ("F2", "k>", "f12"); | |
1508 CONDITIONAL_REASSIGN ("%1", "kq", "help"); | |
1509 CONDITIONAL_REASSIGN ("*6", "kU", "select"); | |
1510 #undef CONDITIONAL_REASSIGN | |
1511 | |
1512 return Qnil; | |
1513 } | |
1514 | |
1515 | |
1516 /************************************************************************/ | |
1517 /* initialization */ | |
1518 /************************************************************************/ | |
1519 | |
1520 void | |
1521 console_type_create_redisplay_tty (void) | |
1522 { | |
1523 /* redisplay methods */ | |
1524 CONSOLE_HAS_METHOD (tty, text_width); | |
1525 CONSOLE_HAS_METHOD (tty, output_display_block); | |
1526 CONSOLE_HAS_METHOD (tty, output_vertical_divider); | |
1527 CONSOLE_HAS_METHOD (tty, divider_height); | |
1528 CONSOLE_HAS_METHOD (tty, eol_cursor_width); | |
1529 CONSOLE_HAS_METHOD (tty, clear_to_window_end); | |
1530 CONSOLE_HAS_METHOD (tty, clear_region); | |
1531 CONSOLE_HAS_METHOD (tty, clear_frame); | |
442 | 1532 CONSOLE_HAS_METHOD (tty, frame_output_begin); |
1533 CONSOLE_HAS_METHOD (tty, frame_output_end); | |
428 | 1534 CONSOLE_HAS_METHOD (tty, flash); |
1535 CONSOLE_HAS_METHOD (tty, ring_bell); | |
1536 CONSOLE_HAS_METHOD (tty, set_final_cursor_coords); | |
1537 } |