Mercurial > emacs
annotate src/dispnew.c @ 981:49a539ef702f
*** empty log message ***
author | Roland McGrath <roland@gnu.org> |
---|---|
date | Wed, 12 Aug 1992 18:48:38 +0000 |
parents | 17986889d3b6 |
children | 83605f96f58e |
rev | line source |
---|---|
314 | 1 /* Updating of data structures for redisplay. |
587 | 2 Copyright (C) 1985, 1986, 1987, 1988, 1990, 1992 Free Software Foundation, Inc. |
314 | 3 |
4 This file is part of GNU Emacs. | |
5 | |
6 GNU Emacs is free software; you can redistribute it and/or modify | |
7 it under the terms of the GNU General Public License as published by | |
8 the Free Software Foundation; either version 1, or (at your option) | |
9 any later version. | |
10 | |
11 GNU Emacs is distributed in the hope that it will be useful, | |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 GNU General Public License for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with GNU Emacs; see the file COPYING. If not, write to | |
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
19 | |
20 | |
21 #include <signal.h> | |
22 | |
23 #include "config.h" | |
24 #include <stdio.h> | |
25 #include <ctype.h> | |
26 | |
27 #include "termchar.h" | |
28 #include "termopts.h" | |
29 #include "cm.h" | |
30 #include "lisp.h" | |
31 #include "dispextern.h" | |
32 #include "buffer.h" | |
764 | 33 #include "frame.h" |
314 | 34 #include "window.h" |
35 #include "commands.h" | |
36 #include "disptab.h" | |
37 #include "indent.h" | |
38 | |
554 | 39 #include "systerm.h" |
40 #include "systime.h" | |
41 | |
314 | 42 #ifdef HAVE_X_WINDOWS |
43 #include "xterm.h" | |
44 #endif /* HAVE_X_WINDOWS */ | |
45 | |
46 #define max(a, b) ((a) > (b) ? (a) : (b)) | |
47 #define min(a, b) ((a) < (b) ? (a) : (b)) | |
48 | |
49 #ifndef PENDING_OUTPUT_COUNT | |
50 /* Get number of chars of output now in the buffer of a stdio stream. | |
51 This ought to be built in in stdio, but it isn't. | |
52 Some s- files override this because their stdio internals differ. */ | |
53 #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base) | |
54 #endif | |
55 | |
554 | 56 /* Nonzero upon entry to redisplay means do not assume anything about |
764 | 57 current contents of actual terminal frame; clear and redraw it. */ |
314 | 58 |
764 | 59 int frame_garbaged; |
314 | 60 |
61 /* Nonzero means last display completed. Zero means it was preempted. */ | |
62 | |
63 int display_completed; | |
64 | |
65 /* Lisp variable visible-bell; enables use of screen-flash | |
66 instead of audible bell. */ | |
67 | |
68 int visible_bell; | |
69 | |
764 | 70 /* Invert the color of the whole frame, at a low level. */ |
314 | 71 |
72 int inverse_video; | |
73 | |
74 /* Line speed of the terminal. */ | |
75 | |
76 int baud_rate; | |
77 | |
78 /* nil or a symbol naming the window system under which emacs is | |
79 running ('x is the only current possibility). */ | |
80 | |
81 Lisp_Object Vwindow_system; | |
82 | |
83 /* Version number of X windows: 10, 11 or nil. */ | |
84 Lisp_Object Vwindow_system_version; | |
85 | |
86 /* Vector of glyph definitions. Indexed by glyph number, | |
87 the contents are a string which is how to output the glyph. | |
88 | |
89 If Vglyph_table is nil, a glyph is output by using its low 8 bits | |
90 as a character code. */ | |
91 | |
92 Lisp_Object Vglyph_table; | |
93 | |
94 /* Display table to use for vectors that don't specify their own. */ | |
95 | |
96 Lisp_Object Vstandard_display_table; | |
97 | |
98 /* Nonzero means reading single-character input with prompt | |
708 | 99 so put cursor on minibuffer after the prompt. |
100 positive means at end of text in echo area; | |
101 negative means at beginning of line. */ | |
314 | 102 int cursor_in_echo_area; |
103 | |
764 | 104 /* The currently selected frame. |
105 In a single-frame version, this variable always remains 0. */ | |
314 | 106 |
764 | 107 FRAME_PTR selected_frame; |
314 | 108 |
764 | 109 /* A frame which is not just a minibuffer, or 0 if there are no such |
110 frames. This is usually the most recent such frame that was | |
111 selected. In a single-frame version, this variable always remains 0. */ | |
112 FRAME_PTR last_nonminibuf_frame; | |
732 | 113 |
764 | 114 /* In a single-frame version, the information that would otherwise |
115 exist inside frame objects lives in the following structure instead. */ | |
314 | 116 |
764 | 117 #ifndef MULTI_FRAME |
118 struct frame the_only_frame; | |
732 | 119 #endif |
314 | 120 |
121 /* This is a vector, made larger whenever it isn't large enough, | |
764 | 122 which is used inside `update_frame' to hold the old contents |
123 of the FRAME_PHYS_LINES of the frame being updated. */ | |
124 struct frame_glyphs **ophys_lines; | |
314 | 125 /* Length of vector currently allocated. */ |
126 int ophys_lines_length; | |
127 | |
128 FILE *termscript; /* Stdio stream being used for copy of all output. */ | |
129 | |
130 struct cm Wcm; /* Structure for info on cursor positioning */ | |
131 | |
132 extern short ospeed; /* Output speed (from sg_ospeed) */ | |
133 | |
134 int delayed_size_change; /* 1 means SIGWINCH happened when not safe. */ | |
135 | |
764 | 136 #ifdef MULTI_FRAME |
314 | 137 |
764 | 138 DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0, |
139 "Clear frame FRAME and output again what is supposed to appear on it.") | |
140 (frame) | |
141 Lisp_Object frame; | |
314 | 142 { |
764 | 143 FRAME_PTR f; |
314 | 144 |
764 | 145 CHECK_LIVE_FRAME (frame, 0); |
146 f = XFRAME (frame); | |
147 update_begin (f); | |
314 | 148 /* set_terminal_modes (); */ |
764 | 149 clear_frame (); |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
150 clear_frame_records (f); |
764 | 151 update_end (f); |
314 | 152 fflush (stdout); |
153 windows_or_buffers_changed++; | |
154 /* Mark all windows as INaccurate, | |
155 so that every window will have its redisplay done. */ | |
764 | 156 mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0); |
157 f->garbaged = 0; | |
314 | 158 return Qnil; |
159 } | |
160 | |
161 DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "", | |
764 | 162 "Redraw all frames marked as having their images garbled.") |
314 | 163 () |
164 { | |
764 | 165 Lisp_Object frame, tail; |
314 | 166 |
764 | 167 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr) |
314 | 168 { |
764 | 169 frame = XCONS (tail)->car; |
170 if (XFRAME (frame)->garbaged && XFRAME (frame)->visible) | |
171 Fredraw_frame (frame); | |
314 | 172 } |
173 return Qnil; | |
174 } | |
175 | |
764 | 176 redraw_frame (f) |
177 FRAME_PTR f; | |
314 | 178 { |
764 | 179 Lisp_Object frame; |
180 XSET (frame, Lisp_Frame, f); | |
181 Fredraw_frame (frame); | |
314 | 182 } |
183 | |
764 | 184 #else /* not MULTI_FRAME */ |
314 | 185 |
186 DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, 0, | |
187 "Clear screen and output again what is supposed to appear on it.") | |
188 () | |
189 { | |
190 update_begin (0); | |
191 set_terminal_modes (); | |
764 | 192 clear_frame (); |
314 | 193 update_end (0); |
194 fflush (stdout); | |
764 | 195 clear_frame_records (0); |
314 | 196 windows_or_buffers_changed++; |
197 /* Mark all windows as INaccurate, | |
198 so that every window will have its redisplay done. */ | |
199 mark_window_display_accurate (XWINDOW (minibuf_window)->prev, 0); | |
200 return Qnil; | |
201 } | |
202 | |
764 | 203 #endif /* not MULTI_FRAME */ |
314 | 204 |
764 | 205 static struct frame_glyphs * |
206 make_frame_glyphs (frame, empty) | |
207 register FRAME_PTR frame; | |
314 | 208 int empty; |
209 { | |
210 register int i; | |
764 | 211 register width = FRAME_WIDTH (frame); |
212 register height = FRAME_HEIGHT (frame); | |
213 register struct frame_glyphs *new = | |
214 (struct frame_glyphs *) xmalloc (sizeof (struct frame_glyphs)); | |
314 | 215 |
764 | 216 SET_GLYPHS_FRAME (new, frame); |
314 | 217 new->height = height; |
218 new->width = width; | |
219 new->used = (int *) xmalloc (height * sizeof (int)); | |
220 new->glyphs = (GLYPH **) xmalloc (height * sizeof (GLYPH *)); | |
221 new->highlight = (char *) xmalloc (height * sizeof (char)); | |
222 new->enable = (char *) xmalloc (height * sizeof (char)); | |
223 bzero (new->enable, height * sizeof (char)); | |
224 new->bufp = (int *) xmalloc (height * sizeof (int)); | |
225 | |
226 #ifdef HAVE_X_WINDOWS | |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
227 if (FRAME_X_P (frame)) |
314 | 228 { |
229 new->nruns = (int *) xmalloc (height * sizeof (int)); | |
230 new->face_list | |
231 = (struct run **) xmalloc (height * sizeof (struct run *)); | |
232 new->top_left_x = (short *) xmalloc (height * sizeof (short)); | |
233 new->top_left_y = (short *) xmalloc (height * sizeof (short)); | |
234 new->pix_width = (short *) xmalloc (height * sizeof (short)); | |
235 new->pix_height = (short *) xmalloc (height * sizeof (short)); | |
236 } | |
237 #endif | |
238 | |
239 if (empty) | |
240 { | |
241 /* Make the buffer used by decode_mode_spec. This buffer is also | |
764 | 242 used as temporary storage when updating the frame. See scroll.c. */ |
314 | 243 unsigned int total_glyphs = (width + 2) * sizeof (GLYPH); |
244 | |
245 new->total_contents = (GLYPH *) xmalloc (total_glyphs); | |
246 bzero (new->total_contents, total_glyphs); | |
247 } | |
248 else | |
249 { | |
250 unsigned int total_glyphs = height * (width + 2) * sizeof (GLYPH); | |
251 | |
252 new->total_contents = (GLYPH *) xmalloc (total_glyphs); | |
253 bzero (new->total_contents, total_glyphs); | |
254 for (i = 0; i < height; i++) | |
255 new->glyphs[i] = new->total_contents + i * (width + 2) + 1; | |
256 } | |
257 | |
258 return new; | |
259 } | |
260 | |
261 static void | |
764 | 262 free_frame_glyphs (frame, glyphs) |
263 FRAME_PTR frame; | |
264 struct frame_glyphs *glyphs; | |
314 | 265 { |
266 if (glyphs->total_contents) | |
267 free (glyphs->total_contents); | |
268 | |
269 free (glyphs->used); | |
270 free (glyphs->glyphs); | |
271 free (glyphs->highlight); | |
272 free (glyphs->enable); | |
273 free (glyphs->bufp); | |
274 | |
275 #ifdef HAVE_X_WINDOWS | |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
276 if (FRAME_X_P (frame)) |
314 | 277 { |
278 free (glyphs->nruns); | |
279 free (glyphs->face_list); | |
280 free (glyphs->top_left_x); | |
281 free (glyphs->top_left_y); | |
282 free (glyphs->pix_width); | |
283 free (glyphs->pix_height); | |
284 } | |
285 #endif | |
286 | |
287 free (glyphs); | |
288 } | |
289 | |
290 static void | |
764 | 291 remake_frame_glyphs (frame) |
292 FRAME_PTR frame; | |
314 | 293 { |
764 | 294 if (FRAME_CURRENT_GLYPHS (frame)) |
295 free_frame_glyphs (frame, FRAME_CURRENT_GLYPHS (frame)); | |
296 if (FRAME_DESIRED_GLYPHS (frame)) | |
297 free_frame_glyphs (frame, FRAME_DESIRED_GLYPHS (frame)); | |
298 if (FRAME_TEMP_GLYPHS (frame)) | |
299 free_frame_glyphs (frame, FRAME_TEMP_GLYPHS (frame)); | |
314 | 300 |
764 | 301 if (FRAME_MESSAGE_BUF (frame)) |
302 FRAME_MESSAGE_BUF (frame) | |
303 = (char *) xrealloc (FRAME_MESSAGE_BUF (frame), | |
304 FRAME_WIDTH (frame) + 1); | |
314 | 305 else |
764 | 306 FRAME_MESSAGE_BUF (frame) |
307 = (char *) xmalloc (FRAME_WIDTH (frame) + 1); | |
314 | 308 |
764 | 309 FRAME_CURRENT_GLYPHS (frame) = make_frame_glyphs (frame, 0); |
310 FRAME_DESIRED_GLYPHS (frame) = make_frame_glyphs (frame, 0); | |
311 FRAME_TEMP_GLYPHS (frame) = make_frame_glyphs (frame, 1); | |
312 SET_FRAME_GARBAGED (frame); | |
314 | 313 } |
314 | |
764 | 315 /* Return the hash code of contents of line VPOS in frame-matrix M. */ |
314 | 316 |
317 static int | |
318 line_hash_code (m, vpos) | |
764 | 319 register struct frame_glyphs *m; |
314 | 320 int vpos; |
321 { | |
322 register GLYPH *body, *end; | |
323 register int h = 0; | |
324 | |
325 if (!m->enable[vpos]) | |
326 return 0; | |
327 | |
328 /* Give all lighlighted lines the same hash code | |
329 so as to encourage scrolling to leave them in place. */ | |
330 if (m->highlight[vpos]) | |
331 return -1; | |
332 | |
333 body = m->glyphs[vpos]; | |
334 | |
335 if (must_write_spaces) | |
336 while (1) | |
337 { | |
338 GLYPH g = *body++; | |
339 | |
340 if (g == 0) | |
341 break; | |
342 h = (((h << 4) + (h >> 24)) & 0x0fffffff) + g - SPACEGLYPH; | |
343 } | |
344 else | |
345 while (1) | |
346 { | |
347 GLYPH g = *body++; | |
348 | |
349 if (g == 0) | |
350 break; | |
351 h = (((h << 4) + (h >> 24)) & 0x0fffffff) + g; | |
352 } | |
353 | |
354 if (h) | |
355 return h; | |
356 return 1; | |
357 } | |
358 | |
359 /* Return number of characters in line in M at vpos VPOS, | |
360 except don't count leading and trailing spaces | |
361 unless the terminal requires those to be explicitly output. */ | |
362 | |
363 static unsigned int | |
364 line_draw_cost (m, vpos) | |
764 | 365 struct frame_glyphs *m; |
314 | 366 int vpos; |
367 { | |
368 register GLYPH *beg = m->glyphs[vpos]; | |
369 register GLYPH *end = m->glyphs[vpos] + m->used[vpos]; | |
370 register int i; | |
371 register int tlen = GLYPH_TABLE_LENGTH; | |
372 register Lisp_Object *tbase = GLYPH_TABLE_BASE; | |
373 | |
374 /* Ignore trailing and leading spaces if we can. */ | |
375 if (!must_write_spaces) | |
376 { | |
377 while ((end != beg) && (*end == SPACEGLYPH)) | |
378 --end; | |
379 if (end == beg) | |
380 return (0); /* All blank line. */ | |
381 | |
382 while (*beg == SPACEGLYPH) | |
383 ++beg; | |
384 } | |
385 | |
386 /* If we don't have a glyph-table, each glyph is one character, | |
387 so return the number of glyphs. */ | |
388 if (tbase == 0) | |
389 return end - beg; | |
390 | |
391 /* Otherwise, scan the glyphs and accumulate their total size in I. */ | |
392 i = 0; | |
393 while ((beg <= end) && *beg) | |
394 { | |
395 register GLYPH g = *beg++; | |
396 | |
397 if (GLYPH_SIMPLE_P (tbase, tlen, g)) | |
398 i += 1; | |
399 else | |
400 i += GLYPH_LENGTH (tbase, g); | |
401 } | |
402 return i; | |
403 } | |
404 | |
405 /* The functions on this page are the interface from xdisp.c to redisplay. | |
406 | |
407 The only other interface into redisplay is through setting | |
764 | 408 FRAME_CURSOR_X (frame) and FRAME_CURSOR_Y (frame) |
409 and SET_FRAME_GARBAGED (frame). */ | |
314 | 410 |
411 /* cancel_line eliminates any request to display a line at position `vpos' */ | |
412 | |
764 | 413 cancel_line (vpos, frame) |
314 | 414 int vpos; |
764 | 415 register FRAME_PTR frame; |
314 | 416 { |
764 | 417 FRAME_DESIRED_GLYPHS (frame)->enable[vpos] = 0; |
314 | 418 } |
419 | |
764 | 420 clear_frame_records (frame) |
421 register FRAME_PTR frame; | |
314 | 422 { |
764 | 423 bzero (FRAME_CURRENT_GLYPHS (frame)->enable, FRAME_HEIGHT (frame)); |
314 | 424 } |
425 | |
426 /* Prepare to display on line VPOS starting at HPOS within it. */ | |
427 | |
428 void | |
764 | 429 get_display_line (frame, vpos, hpos) |
430 register FRAME_PTR frame; | |
314 | 431 int vpos; |
432 register int hpos; | |
433 { | |
764 | 434 register struct frame_glyphs *glyphs; |
435 register struct frame_glyphs *desired_glyphs = FRAME_DESIRED_GLYPHS (frame); | |
314 | 436 register GLYPH *p; |
437 | |
764 | 438 if (vpos < 0 || (! FRAME_VISIBLE_P (frame))) |
314 | 439 abort (); |
440 | |
441 if ((desired_glyphs->enable[vpos]) && desired_glyphs->used[vpos] > hpos) | |
442 abort (); | |
443 | |
444 if (! desired_glyphs->enable[vpos]) | |
445 { | |
446 desired_glyphs->used[vpos] = 0; | |
447 desired_glyphs->highlight[vpos] = 0; | |
448 desired_glyphs->enable[vpos] = 1; | |
449 } | |
450 | |
451 if (hpos > desired_glyphs->used[vpos]) | |
452 { | |
453 GLYPH *g = desired_glyphs->glyphs[vpos] + desired_glyphs->used[vpos]; | |
454 GLYPH *end = desired_glyphs->glyphs[vpos] + hpos; | |
455 | |
456 desired_glyphs->used[vpos] = hpos; | |
457 while (g != end) | |
458 *g++ = SPACEGLYPH; | |
459 } | |
460 } | |
461 | |
462 /* Like bcopy except never gets confused by overlap. */ | |
463 | |
464 void | |
465 safe_bcopy (from, to, size) | |
466 char *from, *to; | |
467 int size; | |
468 { | |
469 register char *endf; | |
470 register char *endt; | |
471 | |
472 if (size == 0) | |
473 return; | |
474 | |
475 /* If destination is higher in memory, and overlaps source zone, | |
476 copy from the end. */ | |
477 if (from < to && from + size > to) | |
478 { | |
479 endf = from + size; | |
480 endt = to + size; | |
481 | |
482 /* If TO - FROM is large, then we should break the copy into | |
483 nonoverlapping chunks of TO - FROM bytes each. However, if | |
484 TO - FROM is small, then the bcopy function call overhead | |
485 makes this not worth it. The crossover point could be about | |
486 anywhere. Since I don't think the obvious copy loop is ever | |
487 too bad, I'm trying to err in its favor. */ | |
488 if (to - from < 64) | |
489 { | |
490 do | |
491 *--endt = *--endf; | |
492 while (endf != from); | |
493 } | |
494 else | |
495 { | |
352 | 496 /* Since TO - FROM >= 64, the overlap is less than SIZE, |
497 so we can always safely do this loop once. */ | |
314 | 498 while (endt > to) |
499 { | |
500 endt -= (to - from); | |
501 endf -= (to - from); | |
502 | |
503 bcopy (endf, endt, to - from); | |
504 } | |
505 | |
506 /* If TO - FROM wasn't a multiple of SIZE, there will be a | |
507 little left over. The amount left over is | |
508 (endt + (to - from)) - to, which is endt - from. */ | |
509 bcopy (from, to, endt - from); | |
510 } | |
511 } | |
512 else | |
513 bcopy (from, to, size); | |
514 } | |
515 | |
516 #if 0 | |
517 void | |
518 safe_bcopy (from, to, size) | |
519 char *from, *to; | |
520 int size; | |
521 { | |
522 register char *endf; | |
523 register char *endt; | |
524 | |
525 if (size == 0) | |
526 return; | |
527 | |
528 /* If destination is higher in memory, and overlaps source zone, | |
529 copy from the end. */ | |
530 if (from < to && from + size > to) | |
531 { | |
532 endf = from + size; | |
533 endt = to + size; | |
534 | |
535 do | |
536 *--endt = *--endf; | |
537 while (endf != from); | |
538 | |
539 return; | |
540 } | |
541 | |
542 bcopy (from, to, size); | |
543 } | |
544 #endif | |
545 | |
352 | 546 /* Rotate a vector of SIZE bytes right, by DISTANCE bytes. |
314 | 547 DISTANCE may be negative. */ |
548 | |
549 static void | |
550 rotate_vector (vector, size, distance) | |
551 char *vector; | |
552 int size; | |
553 int distance; | |
554 { | |
555 char *temp = (char *) alloca (size); | |
556 | |
557 if (distance < 0) | |
558 distance += size; | |
559 | |
560 bcopy (vector, temp + distance, size - distance); | |
561 bcopy (vector + size - distance, temp, distance); | |
562 bcopy (temp, vector, size); | |
563 } | |
564 | |
565 /* Scroll lines from vpos FROM up to but not including vpos END | |
566 down by AMOUNT lines (AMOUNT may be negative). | |
567 Returns nonzero if done, zero if terminal cannot scroll them. */ | |
568 | |
569 int | |
764 | 570 scroll_frame_lines (frame, from, end, amount) |
571 register FRAME_PTR frame; | |
314 | 572 int from, end, amount; |
573 { | |
574 register int i; | |
764 | 575 register struct frame_glyphs *current_frame |
576 = FRAME_CURRENT_GLYPHS (frame); | |
314 | 577 |
578 if (!line_ins_del_ok) | |
579 return 0; | |
580 | |
581 if (amount == 0) | |
582 return 1; | |
583 | |
584 if (amount > 0) | |
585 { | |
764 | 586 update_begin (frame); |
314 | 587 set_terminal_window (end + amount); |
588 if (!scroll_region_ok) | |
589 ins_del_lines (end, -amount); | |
590 ins_del_lines (from, amount); | |
591 set_terminal_window (0); | |
592 | |
764 | 593 rotate_vector (current_frame->glyphs + from, |
314 | 594 sizeof (GLYPH *) * (end + amount - from), |
595 amount * sizeof (GLYPH *)); | |
596 | |
764 | 597 safe_bcopy (current_frame->used + from, |
598 current_frame->used + from + amount, | |
599 (end - from) * sizeof current_frame->used[0]); | |
314 | 600 |
764 | 601 safe_bcopy (current_frame->highlight + from, |
602 current_frame->highlight + from + amount, | |
603 (end - from) * sizeof current_frame->highlight[0]); | |
314 | 604 |
764 | 605 safe_bcopy (current_frame->enable + from, |
606 current_frame->enable + from + amount, | |
607 (end - from) * sizeof current_frame->enable[0]); | |
314 | 608 |
609 /* Mark the lines made empty by scrolling as enabled, empty and | |
610 normal video. */ | |
764 | 611 bzero (current_frame->used + from, |
612 amount * sizeof current_frame->used[0]); | |
613 bzero (current_frame->highlight + from, | |
614 amount * sizeof current_frame->highlight[0]); | |
314 | 615 for (i = from; i < from + amount; i++) |
616 { | |
764 | 617 current_frame->glyphs[i][0] = '\0'; |
618 current_frame->enable[i] = 1; | |
314 | 619 } |
620 | |
764 | 621 safe_bcopy (current_frame->bufp + from, |
622 current_frame->bufp + from + amount, | |
623 (end - from) * sizeof current_frame->bufp[0]); | |
314 | 624 |
625 #ifdef HAVE_X_WINDOWS | |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
626 if (FRAME_X_P (frame)) |
314 | 627 { |
764 | 628 safe_bcopy (current_frame->nruns + from, |
629 current_frame->nruns + from + amount, | |
630 (end - from) * sizeof current_frame->nruns[0]); | |
314 | 631 |
764 | 632 safe_bcopy (current_frame->face_list + from, |
633 current_frame->face_list + from + amount, | |
634 (end - from) * sizeof current_frame->face_list[0]); | |
314 | 635 |
764 | 636 safe_bcopy (current_frame->top_left_x + from, |
637 current_frame->top_left_x + from + amount, | |
638 (end - from) * sizeof current_frame->top_left_x[0]); | |
314 | 639 |
764 | 640 safe_bcopy (current_frame->top_left_y + from, |
641 current_frame->top_left_y + from + amount, | |
642 (end - from) * sizeof current_frame->top_left_y[0]); | |
314 | 643 |
764 | 644 safe_bcopy (current_frame->pix_width + from, |
645 current_frame->pix_width + from + amount, | |
646 (end - from) * sizeof current_frame->pix_width[0]); | |
314 | 647 |
764 | 648 safe_bcopy (current_frame->pix_height + from, |
649 current_frame->pix_height + from + amount, | |
650 (end - from) * sizeof current_frame->pix_height[0]); | |
314 | 651 } |
652 #endif /* HAVE_X_WINDOWS */ | |
653 | |
764 | 654 update_end (frame); |
314 | 655 } |
656 if (amount < 0) | |
657 { | |
764 | 658 update_begin (frame); |
314 | 659 set_terminal_window (end); |
660 ins_del_lines (from + amount, amount); | |
661 if (!scroll_region_ok) | |
662 ins_del_lines (end + amount, -amount); | |
663 set_terminal_window (0); | |
664 | |
764 | 665 rotate_vector (current_frame->glyphs + from + amount, |
314 | 666 sizeof (GLYPH *) * (end - from - amount), |
667 amount * sizeof (GLYPH *)); | |
668 | |
764 | 669 safe_bcopy (current_frame->used + from, |
670 current_frame->used + from + amount, | |
671 (end - from) * sizeof current_frame->used[0]); | |
314 | 672 |
764 | 673 safe_bcopy (current_frame->highlight + from, |
674 current_frame->highlight + from + amount, | |
675 (end - from) * sizeof current_frame->highlight[0]); | |
314 | 676 |
764 | 677 safe_bcopy (current_frame->enable + from, |
678 current_frame->enable + from + amount, | |
679 (end - from) * sizeof current_frame->enable[0]); | |
314 | 680 |
681 /* Mark the lines made empty by scrolling as enabled, empty and | |
682 normal video. */ | |
764 | 683 bzero (current_frame->used + end + amount, |
684 - amount * sizeof current_frame->used[0]); | |
685 bzero (current_frame->highlight + end + amount, | |
686 - amount * sizeof current_frame->highlight[0]); | |
314 | 687 for (i = end + amount; i < end; i++) |
688 { | |
764 | 689 current_frame->glyphs[i][0] = '\0'; |
690 current_frame->enable[i] = 1; | |
314 | 691 } |
692 | |
764 | 693 safe_bcopy (current_frame->bufp + from, |
694 current_frame->bufp + from + amount, | |
695 (end - from) * sizeof current_frame->bufp[0]); | |
314 | 696 |
697 #ifdef HAVE_X_WINDOWS | |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
698 if (FRAME_X_P (frame)) |
314 | 699 { |
764 | 700 safe_bcopy (current_frame->nruns + from, |
701 current_frame->nruns + from + amount, | |
702 (end - from) * sizeof current_frame->nruns[0]); | |
314 | 703 |
764 | 704 safe_bcopy (current_frame->face_list + from, |
705 current_frame->face_list + from + amount, | |
706 (end - from) * sizeof current_frame->face_list[0]); | |
314 | 707 |
764 | 708 safe_bcopy (current_frame->top_left_x + from, |
709 current_frame->top_left_x + from + amount, | |
710 (end - from) * sizeof current_frame->top_left_x[0]); | |
314 | 711 |
764 | 712 safe_bcopy (current_frame->top_left_y + from, |
713 current_frame->top_left_y + from + amount, | |
714 (end - from) * sizeof current_frame->top_left_y[0]); | |
314 | 715 |
764 | 716 safe_bcopy (current_frame->pix_width + from, |
717 current_frame->pix_width + from + amount, | |
718 (end - from) * sizeof current_frame->pix_width[0]); | |
314 | 719 |
764 | 720 safe_bcopy (current_frame->pix_height + from, |
721 current_frame->pix_height + from + amount, | |
722 (end - from) * sizeof current_frame->pix_height[0]); | |
314 | 723 } |
724 #endif /* HAVE_X_WINDOWS */ | |
725 | |
764 | 726 update_end (frame); |
314 | 727 } |
728 return 1; | |
729 } | |
730 | |
764 | 731 /* After updating a window W that isn't the full frame wide, |
314 | 732 copy all the columns that W does not occupy |
764 | 733 into the FRAME_DESIRED_GLYPHS (frame) from the FRAME_PHYS_GLYPHS (frame) |
734 so that update_frame will not change those columns. */ | |
314 | 735 |
736 preserve_other_columns (w) | |
737 struct window *w; | |
738 { | |
739 register int vpos; | |
764 | 740 register struct frame_glyphs *current_frame, *desired_frame; |
741 register FRAME_PTR frame = XFRAME (w->frame); | |
314 | 742 int start = XFASTINT (w->left); |
743 int end = XFASTINT (w->left) + XFASTINT (w->width); | |
744 int bot = XFASTINT (w->top) + XFASTINT (w->height); | |
745 | |
764 | 746 current_frame = FRAME_CURRENT_GLYPHS (frame); |
747 desired_frame = FRAME_DESIRED_GLYPHS (frame); | |
314 | 748 |
749 for (vpos = XFASTINT (w->top); vpos < bot; vpos++) | |
750 { | |
764 | 751 if (current_frame->enable[vpos] && desired_frame->enable[vpos]) |
314 | 752 { |
753 if (start > 0) | |
754 { | |
755 int len; | |
756 | |
764 | 757 bcopy (current_frame->glyphs[vpos], |
758 desired_frame->glyphs[vpos], start); | |
759 len = min (start, current_frame->used[vpos]); | |
760 if (desired_frame->used[vpos] < len) | |
761 desired_frame->used[vpos] = len; | |
314 | 762 } |
764 | 763 if (current_frame->used[vpos] > end |
764 && desired_frame->used[vpos] < current_frame->used[vpos]) | |
314 | 765 { |
764 | 766 while (desired_frame->used[vpos] < end) |
767 desired_frame->glyphs[vpos][desired_frame->used[vpos]++] | |
314 | 768 = SPACEGLYPH; |
764 | 769 bcopy (current_frame->glyphs[vpos] + end, |
770 desired_frame->glyphs[vpos] + end, | |
771 current_frame->used[vpos] - end); | |
772 desired_frame->used[vpos] = current_frame->used[vpos]; | |
314 | 773 } |
774 } | |
775 } | |
776 } | |
777 | |
778 #if 0 | |
779 | |
764 | 780 /* If window w does not need to be updated and isn't the full frame wide, |
314 | 781 copy all the columns that w does occupy |
764 | 782 into the FRAME_DESIRED_LINES (frame) from the FRAME_PHYS_LINES (frame) |
783 so that update_frame will not change those columns. | |
314 | 784 |
785 Have not been able to figure out how to use this correctly. */ | |
786 | |
787 preserve_my_columns (w) | |
788 struct window *w; | |
789 { | |
790 register int vpos, fin; | |
764 | 791 register struct frame_glyphs *l1, *l2; |
792 register FRAME_PTR frame = XFRAME (w->frame); | |
314 | 793 int start = XFASTINT (w->left); |
794 int end = XFASTINT (w->left) + XFASTINT (w->width); | |
795 int bot = XFASTINT (w->top) + XFASTINT (w->height); | |
796 | |
797 for (vpos = XFASTINT (w->top); vpos < bot; vpos++) | |
798 { | |
764 | 799 if ((l1 = FRAME_DESIRED_GLYPHS (frame)->glyphs[vpos + 1]) |
800 && (l2 = FRAME_PHYS_GLYPHS (frame)->glyphs[vpos + 1])) | |
314 | 801 { |
802 if (l2->length > start && l1->length < l2->length) | |
803 { | |
804 fin = l2->length; | |
805 if (fin > end) fin = end; | |
806 while (l1->length < start) | |
807 l1->body[l1->length++] = ' '; | |
808 bcopy (l2->body + start, l1->body + start, fin - start); | |
809 l1->length = fin; | |
810 } | |
811 } | |
812 } | |
813 } | |
814 | |
815 #endif | |
816 | |
817 /* On discovering that the redisplay for a window was no good, | |
818 cancel the columns of that window, so that when the window is | |
819 displayed over again get_display_line will not complain. */ | |
820 | |
821 cancel_my_columns (w) | |
822 struct window *w; | |
823 { | |
824 register int vpos; | |
764 | 825 register struct frame_glyphs *desired_glyphs = |
826 FRAME_DESIRED_GLYPHS (XFRAME (w->frame)); | |
314 | 827 register int start = XFASTINT (w->left); |
828 register int bot = XFASTINT (w->top) + XFASTINT (w->height); | |
829 | |
830 for (vpos = XFASTINT (w->top); vpos < bot; vpos++) | |
831 if (desired_glyphs->enable[vpos] | |
832 && desired_glyphs->used[vpos] >= start) | |
833 desired_glyphs->used[vpos] = start; | |
834 } | |
835 | |
764 | 836 /* These functions try to perform directly and immediately on the frame |
314 | 837 the necessary output for one change in the buffer. |
838 They may return 0 meaning nothing was done if anything is difficult, | |
839 or 1 meaning the output was performed properly. | |
764 | 840 They assume that the frame was up to date before the buffer |
314 | 841 change being displayed. THey make various other assumptions too; |
842 see command_loop_1 where these are called. */ | |
843 | |
844 int | |
845 direct_output_for_insert (g) | |
846 int g; | |
847 { | |
764 | 848 register FRAME_PTR frame = selected_frame; |
849 register struct frame_glyphs *current_frame | |
850 = FRAME_CURRENT_GLYPHS (frame); | |
314 | 851 |
852 #ifndef COMPILER_REGISTER_BUG | |
853 register | |
854 #endif /* COMPILER_REGISTER_BUG */ | |
855 struct window *w = XWINDOW (selected_window); | |
856 #ifndef COMPILER_REGISTER_BUG | |
857 register | |
858 #endif /* COMPILER_REGISTER_BUG */ | |
764 | 859 int hpos = FRAME_CURSOR_X (frame); |
314 | 860 #ifndef COMPILER_REGISTER_BUG |
861 register | |
862 #endif /* COMPILER_REGISTER_BUG */ | |
764 | 863 int vpos = FRAME_CURSOR_Y (frame); |
314 | 864 |
865 /* Give up if about to continue line */ | |
866 if (hpos - XFASTINT (w->left) + 1 + 1 >= XFASTINT (w->width) | |
867 | |
868 /* Avoid losing if cursor is in invisible text off left margin */ | |
869 || (XINT (w->hscroll) && hpos == XFASTINT (w->left)) | |
870 | |
871 /* Give up if cursor outside window (in minibuf, probably) */ | |
764 | 872 || FRAME_CURSOR_Y (frame) < XFASTINT (w->top) |
873 || FRAME_CURSOR_Y (frame) >= XFASTINT (w->top) + XFASTINT (w->height) | |
314 | 874 |
764 | 875 /* Give up if cursor not really at FRAME_CURSOR_X, FRAME_CURSOR_Y */ |
314 | 876 || !display_completed |
877 | |
878 /* Give up if buffer appears in two places. */ | |
879 || buffer_shared > 1 | |
880 | |
881 /* Give up if w is minibuffer and a message is being displayed there */ | |
882 || (MINI_WINDOW_P (w) && echo_area_glyphs)) | |
883 return 0; | |
884 | |
764 | 885 current_frame->glyphs[vpos][hpos] = g; |
314 | 886 unchanged_modified = MODIFF; |
887 beg_unchanged = GPT - BEG; | |
888 XFASTINT (w->last_point) = point; | |
889 XFASTINT (w->last_point_x) = hpos; | |
890 XFASTINT (w->last_modified) = MODIFF; | |
891 | |
892 reassert_line_highlight (0, vpos); | |
764 | 893 write_glyphs (¤t_frame->glyphs[vpos][hpos], 1); |
314 | 894 fflush (stdout); |
764 | 895 ++FRAME_CURSOR_X (frame); |
896 if (hpos == current_frame->used[vpos]) | |
314 | 897 { |
764 | 898 current_frame->used[vpos] = hpos + 1; |
899 current_frame->glyphs[vpos][hpos + 1] = 0; | |
314 | 900 } |
901 | |
902 return 1; | |
903 } | |
904 | |
905 int | |
906 direct_output_forward_char (n) | |
907 int n; | |
908 { | |
764 | 909 register FRAME_PTR frame = selected_frame; |
314 | 910 register struct window *w = XWINDOW (selected_window); |
911 | |
543 | 912 /* Avoid losing if cursor is in invisible text off left margin |
913 or about to go off either side of window. */ | |
764 | 914 if ((FRAME_CURSOR_X (frame) == XFASTINT (w->left) |
543 | 915 && (XINT (w->hscroll) || n < 0)) |
916 || (n > 0 | |
764 | 917 && (FRAME_CURSOR_X (frame) + 1 |
543 | 918 >= (XFASTINT (w->left) + XFASTINT (w->width) |
764 | 919 - (XFASTINT (w->width) < FRAME_WIDTH (frame)) |
543 | 920 - 1)))) |
314 | 921 return 0; |
922 | |
764 | 923 FRAME_CURSOR_X (frame) += n; |
924 XFASTINT (w->last_point_x) = FRAME_CURSOR_X (frame); | |
314 | 925 XFASTINT (w->last_point) = point; |
764 | 926 cursor_to (FRAME_CURSOR_Y (frame), FRAME_CURSOR_X (frame)); |
314 | 927 fflush (stdout); |
928 return 1; | |
929 } | |
930 | |
931 static void update_line (); | |
932 | |
764 | 933 /* Update frame F based on the data in FRAME_DESIRED_GLYPHS. |
314 | 934 Value is nonzero if redisplay stopped due to pending input. |
935 FORCE nonzero means do not stop for pending input. */ | |
936 | |
937 int | |
764 | 938 update_frame (f, force, inhibit_hairy_id) |
939 FRAME_PTR f; | |
314 | 940 int force; |
941 int inhibit_hairy_id; | |
942 { | |
764 | 943 register struct frame_glyphs *current_frame = FRAME_CURRENT_GLYPHS (f); |
944 register struct frame_glyphs *desired_frame = FRAME_DESIRED_GLYPHS (f); | |
314 | 945 register int i; |
946 int pause; | |
947 int preempt_count = baud_rate / 2400 + 1; | |
948 extern input_pending; | |
949 #ifdef HAVE_X_WINDOWS | |
950 register int downto, leftmost; | |
951 #endif | |
952 | |
764 | 953 if (FRAME_HEIGHT (f) == 0) abort (); /* Some bug zeros some core */ |
314 | 954 |
955 detect_input_pending (); | |
956 if (input_pending && !force) | |
957 { | |
958 pause = 1; | |
959 goto do_pause; | |
960 } | |
961 | |
764 | 962 update_begin (f); |
314 | 963 |
964 if (!line_ins_del_ok) | |
965 inhibit_hairy_id = 1; | |
966 | |
493 | 967 /* See if any of the desired lines are enabled; don't compute for |
968 i/d line if just want cursor motion. */ | |
764 | 969 for (i = 0; i < FRAME_HEIGHT (f); i++) |
970 if (desired_frame->enable[i]) | |
314 | 971 break; |
972 | |
973 /* Try doing i/d line, if not yet inhibited. */ | |
764 | 974 if (!inhibit_hairy_id && i < FRAME_HEIGHT (f)) |
975 force |= scrolling (f); | |
314 | 976 |
977 /* Update the individual lines as needed. Do bottom line first. */ | |
978 | |
764 | 979 if (desired_frame->enable[FRAME_HEIGHT (f) - 1]) |
980 update_line (f, FRAME_HEIGHT (f) - 1); | |
314 | 981 |
982 #ifdef HAVE_X_WINDOWS | |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
983 if (FRAME_X_P (f)) |
314 | 984 { |
764 | 985 leftmost = downto = f->display.x->internal_border_width; |
986 if (desired_frame->enable[0]) | |
314 | 987 { |
764 | 988 current_frame->top_left_x[FRAME_HEIGHT (f) - 1] = leftmost; |
989 current_frame->top_left_y[FRAME_HEIGHT (f) - 1] | |
990 = PIXEL_HEIGHT (f) - f->display.x->internal_border_width | |
991 - LINE_HEIGHT(f, FRAME_HEIGHT (f) - 1); | |
992 current_frame->top_left_x[0] = leftmost; | |
993 current_frame->top_left_y[0] = downto; | |
314 | 994 } |
995 } | |
996 #endif /* HAVE_X_WINDOWS */ | |
997 | |
998 /* Now update the rest of the lines. */ | |
764 | 999 for (i = 0; i < FRAME_HEIGHT (f) - 1 && (force || !input_pending); i++) |
314 | 1000 { |
764 | 1001 if (desired_frame->enable[i]) |
314 | 1002 { |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1003 if (FRAME_TERMCAP_P (f)) |
314 | 1004 { |
1005 /* Flush out every so many lines. | |
1006 Also flush out if likely to have more than 1k buffered | |
1007 otherwise. I'm told that some telnet connections get | |
1008 really screwed by more than 1k output at once. */ | |
1009 int outq = PENDING_OUTPUT_COUNT (stdout); | |
1010 if (outq > 900 | |
1011 || (outq > 20 && ((i - 1) % preempt_count == 0))) | |
1012 { | |
1013 fflush (stdout); | |
1014 if (preempt_count == 1) | |
1015 { | |
554 | 1016 #ifdef EMACS_OUTQSIZE |
1017 if (EMACS_OUTQSIZE (0, &outq) < 0) | |
314 | 1018 /* Probably not a tty. Ignore the error and reset |
1019 * the outq count. */ | |
1020 outq = PENDING_OUTPUT_COUNT (stdout); | |
1021 #endif | |
1022 outq *= 10; | |
1023 sleep (outq / baud_rate); | |
1024 } | |
1025 } | |
1026 if ((i - 1) % preempt_count == 0) | |
1027 detect_input_pending (); | |
1028 } | |
1029 | |
764 | 1030 update_line (f, i); |
314 | 1031 #ifdef HAVE_X_WINDOWS |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1032 if (FRAME_X_P (f)) |
314 | 1033 { |
764 | 1034 current_frame->top_left_y[i] = downto; |
1035 current_frame->top_left_x[i] = leftmost; | |
314 | 1036 } |
1037 #endif /* HAVE_X_WINDOWS */ | |
1038 } | |
1039 | |
732 | 1040 #ifdef HAVE_X_WINDOWS |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1041 if (FRAME_X_P (f)) |
764 | 1042 downto += LINE_HEIGHT(f, i); |
732 | 1043 #endif |
314 | 1044 } |
764 | 1045 pause = (i < FRAME_HEIGHT (f) - 1) ? i : 0; |
314 | 1046 |
1047 /* Now just clean up termcap drivers and set cursor, etc. */ | |
1048 if (!pause) | |
1049 { | |
708 | 1050 if (cursor_in_echo_area) |
1051 { | |
764 | 1052 if (f == selected_frame |
708 | 1053 && cursor_in_echo_area < 0) |
764 | 1054 cursor_to (FRAME_HEIGHT (f) - 1, 0); |
1055 else if (f == selected_frame | |
1056 && ! current_frame->enable[FRAME_HEIGHT (f) - 1]) | |
1057 cursor_to (FRAME_HEIGHT (f) - 1, 0); | |
708 | 1058 else |
764 | 1059 cursor_to (FRAME_HEIGHT (f) - 1, |
1060 min (FRAME_WIDTH (f) - 1, | |
1061 current_frame->used[FRAME_HEIGHT (f) - 1])); | |
708 | 1062 } |
314 | 1063 else |
764 | 1064 cursor_to (FRAME_CURSOR_Y (f), max (min (FRAME_CURSOR_X (f), |
1065 FRAME_WIDTH (f) - 1), 0)); | |
314 | 1066 } |
1067 | |
764 | 1068 update_end (f); |
314 | 1069 |
1070 if (termscript) | |
1071 fflush (termscript); | |
1072 fflush (stdout); | |
1073 | |
1074 /* Here if output is preempted because input is detected. */ | |
1075 do_pause: | |
1076 | |
764 | 1077 if (FRAME_HEIGHT (f) == 0) abort (); /* Some bug zeros some core */ |
314 | 1078 display_completed = !pause; |
1079 | |
764 | 1080 bzero (desired_frame->enable, FRAME_HEIGHT (f)); |
314 | 1081 return pause; |
1082 } | |
1083 | |
1084 /* Called when about to quit, to check for doing so | |
1085 at an improper time. */ | |
1086 | |
1087 void | |
1088 quit_error_check () | |
1089 { | |
764 | 1090 if (FRAME_DESIRED_GLYPHS (selected_frame) == 0) |
314 | 1091 return; |
764 | 1092 if (FRAME_DESIRED_GLYPHS (selected_frame)->enable[0]) |
314 | 1093 abort (); |
764 | 1094 if (FRAME_DESIRED_GLYPHS (selected_frame)->enable[FRAME_HEIGHT (selected_frame) - 1]) |
314 | 1095 abort (); |
1096 } | |
1097 | |
1098 /* Decide what insert/delete line to do, and do it */ | |
1099 | |
1100 extern void scrolling_1 (); | |
1101 | |
764 | 1102 scrolling (frame) |
1103 FRAME_PTR frame; | |
314 | 1104 { |
1105 int unchanged_at_top, unchanged_at_bottom; | |
1106 int window_size; | |
1107 int changed_lines; | |
764 | 1108 int *old_hash = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int)); |
1109 int *new_hash = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int)); | |
1110 int *draw_cost = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int)); | |
314 | 1111 register int i; |
764 | 1112 int free_at_end_vpos = FRAME_HEIGHT (frame); |
1113 register struct frame_glyphs *current_frame = FRAME_CURRENT_GLYPHS (frame); | |
1114 register struct frame_glyphs *desired_frame = FRAME_DESIRED_GLYPHS (frame); | |
314 | 1115 |
1116 /* Compute hash codes of all the lines. | |
1117 Also calculate number of changed lines, | |
1118 number of unchanged lines at the beginning, | |
1119 and number of unchanged lines at the end. */ | |
1120 | |
1121 changed_lines = 0; | |
1122 unchanged_at_top = 0; | |
764 | 1123 unchanged_at_bottom = FRAME_HEIGHT (frame); |
1124 for (i = 0; i < FRAME_HEIGHT (frame); i++) | |
314 | 1125 { |
1126 /* Give up on this scrolling if some old lines are not enabled. */ | |
764 | 1127 if (!current_frame->enable[i]) |
314 | 1128 return 0; |
764 | 1129 old_hash[i] = line_hash_code (current_frame, i); |
1130 if (! desired_frame->enable[i]) | |
314 | 1131 new_hash[i] = old_hash[i]; |
1132 else | |
764 | 1133 new_hash[i] = line_hash_code (desired_frame, i); |
314 | 1134 |
1135 if (old_hash[i] != new_hash[i]) | |
1136 { | |
1137 changed_lines++; | |
764 | 1138 unchanged_at_bottom = FRAME_HEIGHT (frame) - i - 1; |
314 | 1139 } |
1140 else if (i == unchanged_at_top) | |
1141 unchanged_at_top++; | |
764 | 1142 draw_cost[i] = line_draw_cost (desired_frame, i); |
314 | 1143 } |
1144 | |
1145 /* If changed lines are few, don't allow preemption, don't scroll. */ | |
1146 if (changed_lines < baud_rate / 2400 | |
764 | 1147 || unchanged_at_bottom == FRAME_HEIGHT (frame)) |
314 | 1148 return 1; |
1149 | |
764 | 1150 window_size = (FRAME_HEIGHT (frame) - unchanged_at_top |
314 | 1151 - unchanged_at_bottom); |
1152 | |
1153 if (scroll_region_ok) | |
1154 free_at_end_vpos -= unchanged_at_bottom; | |
764 | 1155 else if (memory_below_frame) |
314 | 1156 free_at_end_vpos = -1; |
1157 | |
1158 /* If large window, fast terminal and few lines in common between | |
764 | 1159 current frame and desired frame, don't bother with i/d calc. */ |
314 | 1160 if (window_size >= 18 && baud_rate > 2400 |
1161 && (window_size >= | |
1162 10 * scrolling_max_lines_saved (unchanged_at_top, | |
764 | 1163 FRAME_HEIGHT (frame) - unchanged_at_bottom, |
314 | 1164 old_hash, new_hash, draw_cost))) |
1165 return 0; | |
1166 | |
764 | 1167 scrolling_1 (frame, window_size, unchanged_at_top, unchanged_at_bottom, |
314 | 1168 draw_cost + unchanged_at_top - 1, |
1169 old_hash + unchanged_at_top - 1, | |
1170 new_hash + unchanged_at_top - 1, | |
1171 free_at_end_vpos - unchanged_at_top); | |
1172 | |
1173 return 0; | |
1174 } | |
1175 | |
1176 /* Return the offset in its buffer of the character at location col, line | |
1177 in the given window. */ | |
1178 int | |
1179 buffer_posn_from_coords (window, col, line) | |
1180 struct window *window; | |
1181 int col, line; | |
1182 { | |
1183 int window_left = XFASTINT (window->left); | |
1184 | |
1185 /* The actual width of the window is window->width less one for the | |
493 | 1186 DISP_CONTINUE_GLYPH, and less one if it's not the rightmost |
1187 window. */ | |
314 | 1188 int window_width = (XFASTINT (window->width) - 1 |
1189 - (XFASTINT (window->width) + window_left | |
764 | 1190 != FRAME_WIDTH (XFRAME (window->frame)))); |
314 | 1191 |
493 | 1192 int startp = marker_position (window->start); |
314 | 1193 |
1194 /* Since compute_motion will only operate on the current buffer, | |
1195 we need to save the old one and restore it when we're done. */ | |
1196 struct buffer *old_current_buffer = current_buffer; | |
493 | 1197 struct position *posn; |
314 | 1198 |
1199 current_buffer = XBUFFER (window->buffer); | |
1200 | |
764 | 1201 /* It would be nice if we could use FRAME_CURRENT_GLYPHS (XFRAME |
1202 (window->frame))->bufp to avoid scanning from the very top of | |
493 | 1203 the window, but it isn't maintained correctly, and I'm not even |
1204 sure I will keep it. */ | |
1205 posn = compute_motion (startp, 0, | |
1206 (window == XWINDOW (minibuf_window) && startp == 1 | |
1207 ? minibuf_prompt_width : 0), | |
1208 ZV, line, col - window_left, | |
1209 window_width, XINT (window->hscroll), 0); | |
314 | 1210 |
1211 current_buffer = old_current_buffer; | |
1212 | |
764 | 1213 /* compute_motion considers frame points past the end of a line |
493 | 1214 to be *after* the newline, i.e. at the start of the next line. |
1215 This is reasonable, but not really what we want. So if the | |
1216 result is on a line below LINE, back it up one character. */ | |
1217 if (posn->vpos > line) | |
1218 return posn->bufpos - 1; | |
1219 else | |
1220 return posn->bufpos; | |
314 | 1221 } |
1222 | |
1223 static int | |
1224 count_blanks (r) | |
1225 register GLYPH *r; | |
1226 { | |
1227 register GLYPH *p = r; | |
1228 while (*r++ == SPACEGLYPH); | |
1229 return r - p - 1; | |
1230 } | |
1231 | |
1232 static int | |
1233 count_match (str1, str2) | |
1234 GLYPH *str1, *str2; | |
1235 { | |
1236 register GLYPH *p1 = str1; | |
1237 register GLYPH *p2 = str2; | |
1238 while (*p1++ == *p2++); | |
1239 return p1 - str1 - 1; | |
1240 } | |
1241 | |
1242 /* Char insertion/deletion cost vector, from term.c */ | |
1243 extern int *char_ins_del_vector; | |
1244 | |
764 | 1245 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_HEIGHT((f))]) |
314 | 1246 |
1247 static void | |
764 | 1248 update_line (frame, vpos) |
1249 register FRAME_PTR frame; | |
314 | 1250 int vpos; |
1251 { | |
1252 register GLYPH *obody, *nbody, *op1, *op2, *np1, *temp; | |
1253 int tem; | |
1254 int osp, nsp, begmatch, endmatch, olen, nlen; | |
1255 int save; | |
764 | 1256 register struct frame_glyphs *current_frame |
1257 = FRAME_CURRENT_GLYPHS (frame); | |
1258 register struct frame_glyphs *desired_frame | |
1259 = FRAME_DESIRED_GLYPHS (frame); | |
314 | 1260 |
764 | 1261 if (desired_frame->highlight[vpos] |
1262 != (current_frame->enable[vpos] && current_frame->highlight[vpos])) | |
314 | 1263 { |
764 | 1264 change_line_highlight (desired_frame->highlight[vpos], vpos, |
1265 (current_frame->enable[vpos] ? | |
1266 current_frame->used[vpos] : 0)); | |
1267 current_frame->enable[vpos] = 0; | |
314 | 1268 } |
1269 else | |
764 | 1270 reassert_line_highlight (desired_frame->highlight[vpos], vpos); |
314 | 1271 |
764 | 1272 if (! current_frame->enable[vpos]) |
314 | 1273 { |
1274 olen = 0; | |
1275 } | |
1276 else | |
1277 { | |
764 | 1278 obody = current_frame->glyphs[vpos]; |
1279 olen = current_frame->used[vpos]; | |
1280 if (! current_frame->highlight[vpos]) | |
314 | 1281 { |
1282 if (!must_write_spaces) | |
1283 while (obody[olen - 1] == SPACEGLYPH && olen > 0) | |
1284 olen--; | |
1285 } | |
1286 else | |
1287 { | |
1288 /* For an inverse-video line, remember we gave it | |
764 | 1289 spaces all the way to the frame edge |
314 | 1290 so that the reverse video extends all the way across. */ |
1291 | |
764 | 1292 while (olen < FRAME_WIDTH (frame) - 1) |
314 | 1293 obody[olen++] = SPACEGLYPH; |
1294 } | |
1295 } | |
1296 | |
1297 /* One way or another, this will enable the line being updated. */ | |
764 | 1298 current_frame->enable[vpos] = 1; |
1299 current_frame->used[vpos] = desired_frame->used[vpos]; | |
1300 current_frame->highlight[vpos] = desired_frame->highlight[vpos]; | |
1301 current_frame->bufp[vpos] = desired_frame->bufp[vpos]; | |
314 | 1302 |
1303 #ifdef HAVE_X_WINDOWS | |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1304 if (FRAME_X_P (frame)) |
314 | 1305 { |
764 | 1306 current_frame->pix_width[vpos] |
1307 = current_frame->used[vpos] | |
1308 * FONT_WIDTH (frame->display.x->font); | |
1309 current_frame->pix_height[vpos] | |
1310 = FONT_HEIGHT (frame->display.x->font); | |
314 | 1311 } |
1312 #endif /* HAVE_X_WINDOWS */ | |
1313 | |
764 | 1314 if (!desired_frame->enable[vpos]) |
314 | 1315 { |
1316 nlen = 0; | |
1317 goto just_erase; | |
1318 } | |
1319 | |
764 | 1320 nbody = desired_frame->glyphs[vpos]; |
1321 nlen = desired_frame->used[vpos]; | |
314 | 1322 |
1323 /* Pretend trailing spaces are not there at all, | |
1324 unless for one reason or another we must write all spaces. */ | |
764 | 1325 if (! desired_frame->highlight[vpos]) |
314 | 1326 { |
1327 if (!must_write_spaces) | |
1328 /* We know that the previous character byte contains 0. */ | |
1329 while (nbody[nlen - 1] == SPACEGLYPH) | |
1330 nlen--; | |
1331 } | |
1332 else | |
1333 { | |
1334 /* For an inverse-video line, give it extra trailing spaces | |
764 | 1335 all the way to the frame edge |
314 | 1336 so that the reverse video extends all the way across. */ |
1337 | |
764 | 1338 while (nlen < FRAME_WIDTH (frame) - 1) |
314 | 1339 nbody[nlen++] = SPACEGLYPH; |
1340 } | |
1341 | |
1342 /* If there's no i/d char, quickly do the best we can without it. */ | |
1343 if (!char_ins_del_ok) | |
1344 { | |
1345 int i,j; | |
1346 | |
1347 for (i = 0; i < nlen; i++) | |
1348 { | |
1349 if (i >= olen || nbody[i] != obody[i]) /* A non-matching char. */ | |
1350 { | |
1351 cursor_to (vpos, i); | |
1352 for (j = 1; (i + j < nlen && | |
1353 (i + j >= olen || nbody[i+j] != obody[i+j])); | |
1354 j++); | |
1355 | |
1356 /* Output this run of non-matching chars. */ | |
1357 write_glyphs (nbody + i, j); | |
1358 i += j - 1; | |
1359 | |
1360 /* Now find the next non-match. */ | |
1361 } | |
1362 } | |
1363 | |
1364 /* Clear the rest of the line, or the non-clear part of it. */ | |
1365 if (olen > nlen) | |
1366 { | |
1367 cursor_to (vpos, nlen); | |
1368 clear_end_of_line (olen); | |
1369 } | |
1370 | |
764 | 1371 /* Exchange contents between current_frame and new_frame. */ |
1372 temp = desired_frame->glyphs[vpos]; | |
1373 desired_frame->glyphs[vpos] = current_frame->glyphs[vpos]; | |
1374 current_frame->glyphs[vpos] = temp; | |
314 | 1375 |
1376 return; | |
1377 } | |
1378 | |
1379 if (!olen) | |
1380 { | |
764 | 1381 nsp = (must_write_spaces || desired_frame->highlight[vpos]) |
314 | 1382 ? 0 : count_blanks (nbody); |
1383 if (nlen > nsp) | |
1384 { | |
1385 cursor_to (vpos, nsp); | |
1386 write_glyphs (nbody + nsp, nlen - nsp); | |
1387 } | |
1388 | |
764 | 1389 /* Exchange contents between current_frame and new_frame. */ |
1390 temp = desired_frame->glyphs[vpos]; | |
1391 desired_frame->glyphs[vpos] = current_frame->glyphs[vpos]; | |
1392 current_frame->glyphs[vpos] = temp; | |
314 | 1393 |
1394 return; | |
1395 } | |
1396 | |
1397 obody[olen] = 1; | |
1398 save = nbody[nlen]; | |
1399 nbody[nlen] = 0; | |
1400 | |
1401 /* Compute number of leading blanks in old and new contents. */ | |
1402 osp = count_blanks (obody); | |
764 | 1403 if (!desired_frame->highlight[vpos]) |
314 | 1404 nsp = count_blanks (nbody); |
1405 else | |
1406 nsp = 0; | |
1407 | |
1408 /* Compute number of matching chars starting with first nonblank. */ | |
1409 begmatch = count_match (obody + osp, nbody + nsp); | |
1410 | |
1411 /* Spaces in new match implicit space past the end of old. */ | |
1412 /* A bug causing this to be a no-op was fixed in 18.29. */ | |
1413 if (!must_write_spaces && osp + begmatch == olen) | |
1414 { | |
1415 np1 = nbody + nsp; | |
1416 while (np1[begmatch] == SPACEGLYPH) | |
1417 begmatch++; | |
1418 } | |
1419 | |
1420 /* Avoid doing insert/delete char | |
1421 just cause number of leading spaces differs | |
1422 when the following text does not match. */ | |
1423 if (begmatch == 0 && osp != nsp) | |
1424 osp = nsp = min (osp, nsp); | |
1425 | |
1426 /* Find matching characters at end of line */ | |
1427 op1 = obody + olen; | |
1428 np1 = nbody + nlen; | |
1429 op2 = op1 + begmatch - min (olen - osp, nlen - nsp); | |
1430 while (op1 > op2 && op1[-1] == np1[-1]) | |
1431 { | |
1432 op1--; | |
1433 np1--; | |
1434 } | |
1435 endmatch = obody + olen - op1; | |
1436 | |
1437 /* Put correct value back in nbody[nlen]. | |
1438 This is important because direct_output_for_insert | |
1439 can write into the line at a later point. | |
1440 If this screws up the zero at the end of the line, re-establish it. */ | |
1441 nbody[nlen] = save; | |
1442 obody[olen] = 0; | |
1443 | |
1444 /* tem gets the distance to insert or delete. | |
1445 endmatch is how many characters we save by doing so. | |
1446 Is it worth it? */ | |
1447 | |
1448 tem = (nlen - nsp) - (olen - osp); | |
1449 if (endmatch && tem | |
764 | 1450 && (!char_ins_del_ok || endmatch <= char_ins_del_cost (frame)[tem])) |
314 | 1451 endmatch = 0; |
1452 | |
1453 /* nsp - osp is the distance to insert or delete. | |
1454 If that is nonzero, begmatch is known to be nonzero also. | |
1455 begmatch + endmatch is how much we save by doing the ins/del. | |
1456 Is it worth it? */ | |
1457 | |
1458 if (nsp != osp | |
1459 && (!char_ins_del_ok | |
764 | 1460 || begmatch + endmatch <= char_ins_del_cost (frame)[nsp - osp])) |
314 | 1461 { |
1462 begmatch = 0; | |
1463 endmatch = 0; | |
1464 osp = nsp = min (osp, nsp); | |
1465 } | |
1466 | |
1467 /* Now go through the line, inserting, writing and | |
1468 deleting as appropriate. */ | |
1469 | |
1470 if (osp > nsp) | |
1471 { | |
1472 cursor_to (vpos, nsp); | |
1473 delete_glyphs (osp - nsp); | |
1474 } | |
1475 else if (nsp > osp) | |
1476 { | |
1477 /* If going to delete chars later in line | |
1478 and insert earlier in the line, | |
1479 must delete first to avoid losing data in the insert */ | |
1480 if (endmatch && nlen < olen + nsp - osp) | |
1481 { | |
1482 cursor_to (vpos, nlen - endmatch + osp - nsp); | |
1483 delete_glyphs (olen + nsp - osp - nlen); | |
1484 olen = nlen - (nsp - osp); | |
1485 } | |
1486 cursor_to (vpos, osp); | |
1487 insert_glyphs ((char *)0, nsp - osp); | |
1488 } | |
1489 olen += nsp - osp; | |
1490 | |
1491 tem = nsp + begmatch + endmatch; | |
1492 if (nlen != tem || olen != tem) | |
1493 { | |
1494 cursor_to (vpos, nsp + begmatch); | |
1495 if (!endmatch || nlen == olen) | |
1496 { | |
1497 /* If new text being written reaches right margin, | |
1498 there is no need to do clear-to-eol at the end. | |
1499 (and it would not be safe, since cursor is not | |
1500 going to be "at the margin" after the text is done) */ | |
764 | 1501 if (nlen == FRAME_WIDTH (frame)) |
314 | 1502 olen = 0; |
1503 write_glyphs (nbody + nsp + begmatch, nlen - tem); | |
1504 | |
1505 #ifdef obsolete | |
1506 | |
1507 /* the following code loses disastrously if tem == nlen. | |
1508 Rather than trying to fix that case, I am trying the simpler | |
1509 solution found above. */ | |
1510 | |
1511 /* If the text reaches to the right margin, | |
1512 it will lose one way or another (depending on AutoWrap) | |
1513 to clear to end of line after outputting all the text. | |
1514 So pause with one character to go and clear the line then. */ | |
764 | 1515 if (nlen == FRAME_WIDTH (frame) && fast_clear_end_of_line && olen > nlen) |
314 | 1516 { |
1517 /* endmatch must be zero, and tem must equal nsp + begmatch */ | |
1518 write_glyphs (nbody + tem, nlen - tem - 1); | |
1519 clear_end_of_line (olen); | |
1520 olen = 0; /* Don't let it be cleared again later */ | |
1521 write_glyphs (nbody + nlen - 1, 1); | |
1522 } | |
1523 else | |
1524 write_glyphs (nbody + nsp + begmatch, nlen - tem); | |
1525 #endif /* OBSOLETE */ | |
1526 | |
1527 } | |
1528 else if (nlen > olen) | |
1529 { | |
1530 write_glyphs (nbody + nsp + begmatch, olen - tem); | |
1531 insert_glyphs (nbody + nsp + begmatch + olen - tem, nlen - olen); | |
1532 olen = nlen; | |
1533 } | |
1534 else if (olen > nlen) | |
1535 { | |
1536 write_glyphs (nbody + nsp + begmatch, nlen - tem); | |
1537 delete_glyphs (olen - nlen); | |
1538 olen = nlen; | |
1539 } | |
1540 } | |
1541 | |
1542 just_erase: | |
1543 /* If any unerased characters remain after the new line, erase them. */ | |
1544 if (olen > nlen) | |
1545 { | |
1546 cursor_to (vpos, nlen); | |
1547 clear_end_of_line (olen); | |
1548 } | |
1549 | |
764 | 1550 /* Exchange contents between current_frame and new_frame. */ |
1551 temp = desired_frame->glyphs[vpos]; | |
1552 desired_frame->glyphs[vpos] = current_frame->glyphs[vpos]; | |
1553 current_frame->glyphs[vpos] = temp; | |
314 | 1554 } |
1555 | |
1556 DEFUN ("open-termscript", Fopen_termscript, Sopen_termscript, | |
1557 1, 1, "FOpen termscript file: ", | |
1558 "Start writing all terminal output to FILE as well as the terminal.\n\ | |
1559 FILE = nil means just close any termscript file currently open.") | |
1560 (file) | |
1561 Lisp_Object file; | |
1562 { | |
1563 if (termscript != 0) fclose (termscript); | |
1564 termscript = 0; | |
1565 | |
493 | 1566 if (! NILP (file)) |
314 | 1567 { |
1568 file = Fexpand_file_name (file, Qnil); | |
1569 termscript = fopen (XSTRING (file)->data, "w"); | |
1570 if (termscript == 0) | |
1571 report_file_error ("Opening termscript", Fcons (file, Qnil)); | |
1572 } | |
1573 return Qnil; | |
1574 } | |
1575 | |
1576 | |
1577 #ifdef SIGWINCH | |
493 | 1578 SIGTYPE |
314 | 1579 window_change_signal () |
1580 { | |
1581 int width, height; | |
1582 extern int errno; | |
1583 int old_errno = errno; | |
1584 | |
764 | 1585 get_frame_size (&width, &height); |
314 | 1586 |
764 | 1587 /* The frame size change obviously applies to a termcap-controlled |
1588 frame. Find such a frame in the list, and assume it's the only | |
314 | 1589 one (since the redisplay code always writes to stdout, not a |
764 | 1590 FILE * specified in the frame structure). Record the new size, |
314 | 1591 but don't reallocate the data structures now. Let that be done |
1592 later outside of the signal handler. */ | |
1593 | |
1594 { | |
1595 Lisp_Object tail; | |
764 | 1596 FRAME_PTR f; |
314 | 1597 |
764 | 1598 FOR_EACH_FRAME (tail, f) |
314 | 1599 { |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1600 if (FRAME_TERMCAP_P (f)) |
314 | 1601 { |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1602 change_frame_size (f, height, width, 0, 1); |
314 | 1603 break; |
1604 } | |
1605 } | |
1606 } | |
1607 | |
1608 signal (SIGWINCH, window_change_signal); | |
1609 errno = old_errno; | |
1610 } | |
1611 #endif /* SIGWINCH */ | |
1612 | |
1613 | |
764 | 1614 /* Do any change in frame size that was requested by a signal. */ |
314 | 1615 |
1616 do_pending_window_change () | |
1617 { | |
1618 /* If window_change_signal should have run before, run it now. */ | |
1619 while (delayed_size_change) | |
1620 { | |
1621 Lisp_Object tail; | |
764 | 1622 FRAME_PTR f; |
314 | 1623 |
1624 delayed_size_change = 0; | |
1625 | |
764 | 1626 FOR_EACH_FRAME (tail, f) |
314 | 1627 { |
764 | 1628 int height = FRAME_NEW_HEIGHT (f); |
1629 int width = FRAME_NEW_WIDTH (f); | |
314 | 1630 |
764 | 1631 FRAME_NEW_HEIGHT (f) = 0; |
1632 FRAME_NEW_WIDTH (f) = 0; | |
314 | 1633 |
1634 if (height != 0) | |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1635 change_frame_size (f, height, width, 0, 0); |
314 | 1636 } |
1637 } | |
1638 } | |
1639 | |
1640 | |
764 | 1641 /* Change the frame height and/or width. Values may be given as zero to |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1642 indicate no change is to take place. |
314 | 1643 |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1644 If DELAY is non-zero, then assume we're being called from a signal |
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1645 handler, and queue the change for later - perhaps the next |
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1646 redisplay. Since this tries to resize windows, we can't call it |
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1647 from a signal handler. */ |
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1648 |
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1649 change_frame_size (frame, newheight, newwidth, pretend, delay) |
764 | 1650 register FRAME_PTR frame; |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1651 int newheight, newwidth, pretend; |
314 | 1652 { |
1653 /* If we can't deal with the change now, queue it for later. */ | |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1654 if (delay) |
314 | 1655 { |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1656 FRAME_NEW_HEIGHT (frame) = newheight; |
764 | 1657 FRAME_NEW_WIDTH (frame) = newwidth; |
314 | 1658 delayed_size_change = 1; |
1659 return; | |
1660 } | |
1661 | |
764 | 1662 /* This size-change overrides any pending one for this frame. */ |
1663 FRAME_NEW_HEIGHT (frame) = 0; | |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1664 FRAME_NEW_WIDTH (frame) = 0; |
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1665 |
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1666 /* If an arguments is zero, set it to the current value. */ |
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1667 newheight || (newheight = FRAME_HEIGHT (frame)); |
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1668 newwidth || (newwidth = FRAME_WIDTH (frame)); |
314 | 1669 |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1670 /* Round up to the smallest acceptable size. */ |
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1671 check_frame_size (frame, &newheight, &newwidth); |
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1672 |
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1673 /* If we're not changing the frame size, quit now. */ |
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1674 if (newheight == FRAME_HEIGHT (frame) |
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1675 && newwidth == FRAME_WIDTH (frame)) |
314 | 1676 return; |
1677 | |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1678 if (newheight != FRAME_HEIGHT (frame)) |
314 | 1679 { |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1680 if (FRAME_HAS_MINIBUF_P (frame) |
764 | 1681 && ! FRAME_MINIBUF_ONLY_P (frame)) |
314 | 1682 { |
764 | 1683 /* Frame has both root and minibuffer. */ |
1684 set_window_height (FRAME_ROOT_WINDOW (frame), | |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1685 newheight - 1, 0); |
764 | 1686 XFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (frame))->top) |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1687 = newheight - 1; |
764 | 1688 set_window_height (FRAME_MINIBUF_WINDOW (frame), 1, 0); |
314 | 1689 } |
1690 else | |
764 | 1691 /* Frame has just one top-level window. */ |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1692 set_window_height (FRAME_ROOT_WINDOW (frame), newheight, 0); |
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1693 |
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1694 if (FRAME_TERMCAP_P (frame) && !pretend) |
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1695 FrameRows = newheight; |
314 | 1696 |
1697 #if 0 | |
764 | 1698 if (frame->output_method == output_termcap) |
314 | 1699 { |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1700 frame_height = newheight; |
314 | 1701 if (!pretend) |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1702 FrameRows = newheight; |
314 | 1703 } |
1704 #endif | |
1705 } | |
1706 | |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1707 if (newwidth != FRAME_WIDTH (frame)) |
314 | 1708 { |
764 | 1709 set_window_width (FRAME_ROOT_WINDOW (frame), newwidth, 0); |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1710 if (FRAME_HAS_MINIBUF_P (frame)) |
764 | 1711 set_window_width (FRAME_MINIBUF_WINDOW (frame), newwidth, 0); |
314 | 1712 |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1713 if (FRAME_TERMCAP_P (frame) && !pretend) |
764 | 1714 FrameCols = newwidth; |
314 | 1715 #if 0 |
764 | 1716 if (frame->output_method == output_termcap) |
314 | 1717 { |
764 | 1718 frame_width = newwidth; |
314 | 1719 if (!pretend) |
764 | 1720 FrameCols = newwidth; |
314 | 1721 } |
1722 #endif | |
1723 } | |
1724 | |
960
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1725 FRAME_HEIGHT (frame) = newheight; |
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1726 FRAME_WIDTH (frame) = newwidth; |
17986889d3b6
* dispnew.c (Fredraw_frame): Call clear_frame_records before
Jim Blandy <jimb@redhat.com>
parents:
764
diff
changeset
|
1727 |
764 | 1728 remake_frame_glyphs (frame); |
1729 calculate_costs (frame); | |
314 | 1730 } |
1731 | |
1732 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal, | |
1733 Ssend_string_to_terminal, 1, 1, 0, | |
1734 "Send STRING to the terminal without alteration.\n\ | |
1735 Control characters in STRING will have terminal-dependent effects.") | |
1736 (str) | |
1737 Lisp_Object str; | |
1738 { | |
1739 CHECK_STRING (str, 0); | |
1740 fwrite (XSTRING (str)->data, 1, XSTRING (str)->size, stdout); | |
1741 fflush (stdout); | |
1742 if (termscript) | |
1743 { | |
1744 fwrite (XSTRING (str)->data, 1, XSTRING (str)->size, termscript); | |
1745 fflush (termscript); | |
1746 } | |
1747 return Qnil; | |
1748 } | |
1749 | |
1750 DEFUN ("ding", Fding, Sding, 0, 1, 0, | |
1751 "Beep, or flash the screen.\n\ | |
1752 Also, unless an argument is given,\n\ | |
1753 terminate any keyboard macro currently executing.") | |
1754 (arg) | |
1755 Lisp_Object arg; | |
1756 { | |
493 | 1757 if (!NILP (arg)) |
314 | 1758 { |
649
61deba7b73b6
*** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents:
587
diff
changeset
|
1759 if (noninteractive) |
61deba7b73b6
*** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents:
587
diff
changeset
|
1760 putchar (07); |
61deba7b73b6
*** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents:
587
diff
changeset
|
1761 else |
61deba7b73b6
*** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents:
587
diff
changeset
|
1762 ring_bell (); |
314 | 1763 fflush (stdout); |
1764 } | |
1765 else | |
1766 bitch_at_user (); | |
1767 | |
1768 return Qnil; | |
1769 } | |
1770 | |
1771 bitch_at_user () | |
1772 { | |
1773 if (noninteractive) | |
1774 putchar (07); | |
1775 else if (!INTERACTIVE) /* Stop executing a keyboard macro. */ | |
1776 error ("Keyboard macro terminated by a command ringing the bell"); | |
1777 else | |
1778 ring_bell (); | |
1779 fflush (stdout); | |
1780 } | |
1781 | |
1782 DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 2, 0, | |
1783 "Pause, without updating display, for ARG seconds.\n\ | |
1784 Optional second arg non-nil means ARG is measured in milliseconds.\n\ | |
1785 \(Not all operating systems support milliseconds.)") | |
650 | 1786 (arg, millisec) |
1787 Lisp_Object arg, millisec; | |
314 | 1788 { |
1789 int usec = 0; | |
1790 int sec; | |
1791 | |
650 | 1792 CHECK_NUMBER (arg, 0); |
1793 sec = XINT (arg); | |
314 | 1794 if (sec <= 0) |
1795 return Qnil; | |
1796 | |
493 | 1797 if (!NILP (millisec)) |
314 | 1798 { |
554 | 1799 #ifndef EMACS_HAS_USECS |
687
e2b747dd6a6e
*** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents:
673
diff
changeset
|
1800 error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE); |
314 | 1801 #else |
1802 usec = sec % 1000 * 1000; | |
1803 sec /= 1000; | |
1804 #endif | |
1805 } | |
1806 | |
650 | 1807 { |
1808 Lisp_Object zero; | |
1809 | |
1810 XFASTINT (zero) = 0; | |
1811 wait_reading_process_input (sec, usec, zero, 0); | |
1812 } | |
587 | 1813 |
1814 #if 0 /* No wait_reading_process_input */ | |
314 | 1815 immediate_quit = 1; |
1816 QUIT; | |
1817 | |
1818 #ifdef VMS | |
1819 sys_sleep (sec); | |
1820 #else /* not VMS */ | |
1821 /* The reason this is done this way | |
1822 (rather than defined (H_S) && defined (H_T)) | |
1823 is because the VMS preprocessor doesn't grok `defined' */ | |
1824 #ifdef HAVE_SELECT | |
554 | 1825 EMACS_GET_TIME (end_time); |
1826 EMACS_SET_SECS_USECS (timeout, sec, usec); | |
587 | 1827 EMACS_ADD_TIME (end_time, end_time, timeout); |
554 | 1828 |
314 | 1829 while (1) |
1830 { | |
554 | 1831 EMACS_GET_TIME (timeout); |
1832 EMACS_SUB_TIME (timeout, end_time, timeout); | |
1833 if (EMACS_TIME_NEG_P (timeout) | |
1834 || !select (1, 0, 0, 0, &timeout)) | |
314 | 1835 break; |
1836 } | |
1837 #else /* not HAVE_SELECT */ | |
1838 sleep (sec); | |
1839 #endif /* HAVE_SELECT */ | |
1840 #endif /* not VMS */ | |
1841 | |
1842 immediate_quit = 0; | |
1843 #endif /* no subprocesses */ | |
1844 | |
1845 return Qnil; | |
1846 } | |
1847 | |
650 | 1848 /* This is just like wait_reading_process_input, except that |
1849 it does the redisplay. | |
1850 | |
1851 It's also just like Fsit_for, except that it can be used for | |
1852 waiting for input as well. */ | |
1853 | |
1854 Lisp_Object | |
1855 sit_for (sec, usec, reading, display) | |
1856 int sec, usec, reading, display; | |
314 | 1857 { |
650 | 1858 Lisp_Object read_kbd; |
314 | 1859 |
1860 if (detect_input_pending ()) | |
1861 return Qnil; | |
650 | 1862 |
1863 if (display) | |
314 | 1864 redisplay_preserve_echo_area (); |
1865 | |
673 | 1866 if (sec == 0 && usec == 0) |
1867 return Qt; | |
1868 | |
314 | 1869 #ifdef SIGIO |
1870 gobble_input (); | |
650 | 1871 #endif |
1872 | |
1873 XSET (read_kbd, Lisp_Int, reading ? -1 : 1); | |
1874 wait_reading_process_input (sec, usec, read_kbd, display); | |
1875 | |
587 | 1876 |
1877 #if 0 /* No wait_reading_process_input available. */ | |
314 | 1878 immediate_quit = 1; |
1879 QUIT; | |
1880 | |
1881 waitchannels = 1; | |
1882 #ifdef VMS | |
650 | 1883 input_wait_timeout (XINT (arg)); |
314 | 1884 #else /* not VMS */ |
587 | 1885 #ifndef HAVE_TIMEVAL |
1886 timeout_sec = sec; | |
1887 select (1, &waitchannels, 0, 0, &timeout_sec); | |
1888 #else /* HAVE_TIMEVAL */ | |
1889 timeout.tv_sec = sec; | |
1890 timeout.tv_usec = usec; | |
314 | 1891 select (1, &waitchannels, 0, 0, &timeout); |
587 | 1892 #endif /* HAVE_TIMEVAL */ |
314 | 1893 #endif /* not VMS */ |
1894 | |
1895 immediate_quit = 0; | |
587 | 1896 #endif |
314 | 1897 |
1898 return detect_input_pending () ? Qnil : Qt; | |
1899 } | |
1900 | |
650 | 1901 DEFUN ("sit-for", Fsit_for, Ssit_for, 1, 3, 0, |
1902 "Perform redisplay, then wait for ARG seconds or until input is available.\n\ | |
1903 Optional second arg non-nil means ARG counts in milliseconds.\n\ | |
1904 Optional third arg non-nil means don't redisplay, just wait for input.\n\ | |
1905 Redisplay is preempted as always if input arrives, and does not happen\n\ | |
1906 if input is available before it starts.\n\ | |
1907 Value is t if waited the full time with no input arriving.") | |
1908 (arg, millisec, nodisp) | |
1909 Lisp_Object arg, millisec, nodisp; | |
1910 { | |
1911 int usec = 0; | |
708 | 1912 int sec; |
650 | 1913 |
1914 CHECK_NUMBER (arg, 0); | |
708 | 1915 sec = XINT (arg); |
650 | 1916 |
1917 if (!NILP (millisec)) | |
1918 { | |
1919 #ifndef EMACS_HAS_USECS | |
687
e2b747dd6a6e
*** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents:
673
diff
changeset
|
1920 error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE); |
650 | 1921 #else |
1922 usec = (sec % 1000) * 1000; | |
1923 sec /= 1000; | |
1924 #endif | |
1925 } | |
1926 | |
1927 return sit_for (sec, usec, 0, NILP (nodisp)); | |
1928 } | |
1929 | |
314 | 1930 DEFUN ("sleep-for-millisecs", Fsleep_for_millisecs, Ssleep_for_millisecs, |
1931 1, 1, 0, | |
1932 "Pause, without updating display, for ARG milliseconds.") | |
650 | 1933 (arg) |
1934 Lisp_Object arg; | |
314 | 1935 { |
650 | 1936 Lisp_Object zero; |
1937 | |
554 | 1938 #ifndef EMACS_HAS_USECS |
314 | 1939 error ("sleep-for-millisecs not supported on %s", SYSTEM_TYPE); |
1940 #else | |
650 | 1941 CHECK_NUMBER (arg, 0); |
1942 | |
1943 XFASTINT (zero) = 0; | |
1944 wait_reading_process_input (XINT (arg) / 1000, XINT (arg) % 1000 * 1000, | |
1945 zero, 0); | |
314 | 1946 return Qnil; |
554 | 1947 #endif /* EMACS_HAS_USECS */ |
314 | 1948 } |
1949 | |
1950 char *terminal_type; | |
1951 | |
1952 /* Initialization done when Emacs fork is started, before doing stty. */ | |
1953 /* Determine terminal type and set terminal_driver */ | |
1954 /* Then invoke its decoding routine to set up variables | |
1955 in the terminal package */ | |
1956 | |
1957 init_display () | |
1958 { | |
1959 #ifdef HAVE_X_WINDOWS | |
1960 extern int display_arg; | |
1961 #endif | |
1962 | |
1963 meta_key = 0; | |
1964 inverse_video = 0; | |
1965 cursor_in_echo_area = 0; | |
1966 terminal_type = (char *) 0; | |
1967 | |
1968 /* If the DISPLAY environment variable is set, try to use X, and | |
1969 die with an error message if that doesn't work. */ | |
1970 | |
1971 /* Check if we're using a window system here before trying to | |
1972 initialize the terminal. If we check the terminal first, | |
1973 | |
1974 If someone has indicated that they want | |
1975 to use a window system, we shouldn't bother initializing the | |
1976 terminal. This is especially important when the terminal is so | |
1977 dumb that emacs gives up before and doesn't bother using the window | |
1978 system. */ | |
1979 | |
1980 #ifdef HAVE_X_WINDOWS | |
493 | 1981 if (!inhibit_window_system && (display_arg || getenv ("DISPLAY"))) |
314 | 1982 { |
1983 Vwindow_system = intern ("x"); | |
1984 #ifdef HAVE_X11 | |
1985 Vwindow_system_version = make_number (11); | |
1986 #else | |
1987 Vwindow_system_version = make_number (10); | |
1988 #endif | |
1989 return; | |
1990 } | |
1991 #endif /* HAVE_X_WINDOWS */ | |
1992 | |
1993 /* If no window system has been specified, try to use the terminal. */ | |
1994 if (! isatty (0)) | |
1995 { | |
1996 fprintf (stderr, "emacs: standard input is not a tty\n"); | |
1997 exit (1); | |
1998 } | |
1999 | |
2000 /* Look at the TERM variable */ | |
2001 terminal_type = (char *) getenv ("TERM"); | |
2002 if (!terminal_type) | |
2003 { | |
2004 #ifdef VMS | |
2005 fprintf (stderr, "Please specify your terminal type.\n\ | |
2006 For types defined in VMS, use set term /device=TYPE.\n\ | |
2007 For types not defined in VMS, use define emacs_term \"TYPE\".\n\ | |
2008 \(The quotation marks are necessary since terminal types are lower case.)\n"); | |
2009 #else | |
2010 fprintf (stderr, "Please set the environment variable TERM; see tset(1).\n"); | |
2011 #endif | |
2012 exit (1); | |
2013 } | |
2014 | |
2015 #ifdef VMS | |
2016 /* VMS DCL tends to upcase things, so downcase term type. | |
2017 Hardly any uppercase letters in terminal types; should be none. */ | |
2018 { | |
2019 char *new = (char *) xmalloc (strlen (terminal_type) + 1); | |
2020 char *p; | |
2021 | |
2022 strcpy (new, terminal_type); | |
2023 | |
2024 for (p = new; *p; p++) | |
2025 if (isupper (*p)) | |
2026 *p = tolower (*p); | |
2027 | |
2028 terminal_type = new; | |
2029 } | |
2030 #endif | |
2031 | |
2032 term_init (terminal_type); | |
2033 | |
764 | 2034 remake_frame_glyphs (selected_frame); |
2035 calculate_costs (selected_frame); | |
314 | 2036 |
2037 /* X and Y coordinates of the cursor between updates. */ | |
764 | 2038 FRAME_CURSOR_X (selected_frame) = 0; |
2039 FRAME_CURSOR_Y (selected_frame) = 0; | |
314 | 2040 |
2041 #ifdef SIGWINCH | |
2042 #ifndef CANNOT_DUMP | |
2043 if (initialized) | |
2044 #endif /* CANNOT_DUMP */ | |
2045 signal (SIGWINCH, window_change_signal); | |
2046 #endif /* SIGWINCH */ | |
2047 } | |
2048 | |
2049 syms_of_display () | |
2050 { | |
764 | 2051 #ifdef MULTI_FRAME |
2052 defsubr (&Sredraw_frame); | |
314 | 2053 #endif |
2054 defsubr (&Sredraw_display); | |
2055 defsubr (&Sopen_termscript); | |
2056 defsubr (&Sding); | |
2057 defsubr (&Ssit_for); | |
2058 defsubr (&Ssleep_for); | |
2059 defsubr (&Ssend_string_to_terminal); | |
2060 | |
2061 DEFVAR_INT ("baud-rate", &baud_rate, | |
2062 "The output baud rate of the terminal.\n\ | |
2063 On most systems, changing this value will affect the amount of padding\n\ | |
2064 and the other strategic decisions made during redisplay."); | |
2065 DEFVAR_BOOL ("inverse-video", &inverse_video, | |
764 | 2066 "*Non-nil means invert the entire frame display.\n\ |
314 | 2067 This means everything is in inverse video which otherwise would not be."); |
2068 DEFVAR_BOOL ("visible-bell", &visible_bell, | |
764 | 2069 "*Non-nil means try to flash the frame to represent a bell."); |
314 | 2070 DEFVAR_BOOL ("no-redraw-on-reenter", &no_redraw_on_reenter, |
764 | 2071 "*Non-nil means no need to redraw entire frame after suspending.\n\ |
314 | 2072 A non-nil value is useful if the terminal can automatically preserve\n\ |
764 | 2073 Emacs's frame display when you reenter Emacs.\n\ |
314 | 2074 It is up to you to set this variable if your terminal can do that."); |
2075 DEFVAR_LISP ("window-system", &Vwindow_system, | |
2076 "A symbol naming the window-system under which Emacs is running\n\ | |
2077 \(such as `x'), or nil if emacs is running on an ordinary terminal."); | |
2078 DEFVAR_LISP ("window-system-version", &Vwindow_system_version, | |
2079 "The version number of the window system in use.\n\ | |
2080 For X windows, this is 10 or 11."); | |
2081 DEFVAR_BOOL ("cursor-in-echo-area", &cursor_in_echo_area, | |
2082 "Non-nil means put cursor in minibuffer, at end of any message there."); | |
2083 DEFVAR_LISP ("glyph-table", &Vglyph_table, | |
764 | 2084 "Table defining how to output a glyph code to the frame.\n\ |
314 | 2085 If not nil, this is a vector indexed by glyph code to define the glyph.\n\ |
2086 Each element can be:\n\ | |
2087 integer: a glyph code which this glyph is an alias for.\n\ | |
2088 string: output this glyph using that string (not impl. in X windows).\n\ | |
2089 nil: this glyph mod 256 is char code to output,\n\ | |
2090 and this glyph / 256 is face code for X windows (see `x-set-face')."); | |
2091 Vglyph_table = Qnil; | |
2092 | |
2093 DEFVAR_LISP ("standard-display-table", &Vstandard_display_table, | |
2094 "Display table to use for buffers that specify none.\n\ | |
2095 See `buffer-display-table' for more information."); | |
2096 Vstandard_display_table = Qnil; | |
2097 | |
2098 /* Initialize `window-system', unless init_display already decided it. */ | |
2099 #ifdef CANNOT_DUMP | |
2100 if (noninteractive) | |
2101 #endif | |
2102 { | |
2103 Vwindow_system = Qnil; | |
2104 Vwindow_system_version = Qnil; | |
2105 } | |
2106 } | |
2107 |