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