This source file includes following definitions.
- add_window_display_history
- add_frame_display_history
- DEFUN
- __executable_start
- new_glyph_matrix
- free_glyph_matrix
- margin_glyphs_to_reserve
- verify_row_hash
- adjust_glyph_matrix
- reverse_rows
- rotate_matrix
- increment_matrix_positions
- clear_glyph_matrix_rows
- clear_glyph_matrix
- shift_glyph_matrix
- clear_current_matrices
- clear_desired_matrices
- clear_window_matrices
- clear_glyph_row
- blank_row
- increment_row_positions
- swap_glyphs_in_rows
- swap_glyph_pointers
- copy_row_except_pointers
- assign_row
- glyph_row_slice_p
- find_glyph_row_slice
- prepare_desired_row
- line_hash_code
- line_draw_cost
- row_equal_p
- new_glyph_pool
- free_glyph_pool
- realloc_glyph_pool
- flush_stdout
- check_matrix_pointer_lossage
- matrix_row
- check_matrix_invariants
- allocate_matrices_for_frame_redisplay
- required_matrix_height
- required_matrix_width
- allocate_matrices_for_window_redisplay
- adjust_frame_glyphs
- showing_window_margins_p
- fake_current_matrices
- save_current_matrix
- restore_current_matrix
- adjust_frame_glyphs_for_frame_redisplay
- adjust_frame_glyphs_for_window_redisplay
- adjust_decode_mode_spec_buffer
- free_glyphs
- free_window_matrices
- check_glyph_memory
- build_frame_matrix
- build_frame_matrix_from_window_tree
- build_frame_matrix_from_leaf_window
- spec_glyph_lookup_face
- fill_up_glyph_row_with_spaces
- fill_up_glyph_row_area_with_spaces
- fill_up_frame_row_with_spaces
- set_frame_matrix_frame
- make_current
- mirror_make_current
- mirrored_line_dance
- sync_window_with_frame_matrix_rows
- frame_row_to_window
- mirror_line_dance
- check_window_matrix_pointers
- check_matrix_pointers
- window_to_frame_vpos
- window_to_frame_hpos
- redraw_frame
- DEFUN
- DEFUN
- update_frame
- update_frame_with_menu
- update_mouse_position
- update_window_tree
- update_single_window
- redraw_overlapped_rows
- redraw_overlapping_rows
- check_current_matrix_flags
- update_window
- gui_update_window_begin
- gui_update_window_end
- update_marginal_area
- update_text_area
- update_window_line
- set_window_cursor_after_update
- set_window_update_flags
- add_row_entry
- scrolling_window
- update_frame_1
- scrolling
- count_blanks
- count_match
- update_frame_line
- buffer_posn_from_coords
- mode_line_string
- marginal_area_string
- handle_window_change_signal
- deliver_window_change_signal
- do_pending_window_change
- change_frame_size_1
- change_frame_size
- DEFUN
- DEFUN
- bitch_at_user
- sit_for
- DEFUN
- DEFUN
- init_faces_initial
- init_display_interactive
- init_display
- DEFUN
- syms_of_display
- syms_of_display_for_pdumper
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <config.h>
22
23 #include "sysstdio.h"
24 #include <stdlib.h>
25 #include <unistd.h>
26
27 #include "lisp.h"
28 #include "termchar.h"
29
30 #include "dispextern.h"
31 #include "cm.h"
32 #include "buffer.h"
33 #include "keyboard.h"
34 #include "frame.h"
35 #include "termhooks.h"
36 #include "window.h"
37 #include "commands.h"
38 #include "disptab.h"
39 #include "blockinput.h"
40 #include "syssignal.h"
41 #include "systime.h"
42 #include "tparam.h"
43 #include "xwidget.h"
44 #include "pdumper.h"
45
46 #ifdef HAVE_ANDROID
47 #include "android.h"
48 #endif
49
50 #ifdef HAVE_WINDOW_SYSTEM
51 #include TERM_HEADER
52 #endif
53
54 #include <errno.h>
55
56 #include <fpending.h>
57
58 #ifdef WINDOWSNT
59 #include "w32.h"
60 #endif
61
62
63
64
65 struct dim
66 {
67 int width;
68 int height;
69 };
70
71
72
73
74 static void update_frame_line (struct frame *, int, bool);
75 static int required_matrix_height (struct window *);
76 static int required_matrix_width (struct window *);
77 static void increment_row_positions (struct glyph_row *, ptrdiff_t, ptrdiff_t);
78 static void build_frame_matrix_from_window_tree (struct glyph_matrix *,
79 struct window *);
80 static void build_frame_matrix_from_leaf_window (struct glyph_matrix *,
81 struct window *);
82 static void adjust_decode_mode_spec_buffer (struct frame *);
83 static void fill_up_glyph_row_with_spaces (struct glyph_row *);
84 static void clear_window_matrices (struct window *, bool);
85 static void fill_up_glyph_row_area_with_spaces (struct glyph_row *, int);
86 static int scrolling_window (struct window *, int);
87 static bool update_window_line (struct window *, int, bool *);
88 static void mirror_make_current (struct window *, int);
89 #ifdef GLYPH_DEBUG
90 static void check_matrix_pointers (struct glyph_matrix *,
91 struct glyph_matrix *);
92 #endif
93 static void mirror_line_dance (struct window *, int, int, int *, char *);
94 static bool update_window_tree (struct window *, bool);
95 static bool update_window (struct window *, bool);
96 static bool update_frame_1 (struct frame *, bool, bool, bool, bool);
97 static bool scrolling (struct frame *);
98 static void set_window_cursor_after_update (struct window *);
99 static void adjust_frame_glyphs_for_window_redisplay (struct frame *);
100 static void adjust_frame_glyphs_for_frame_redisplay (struct frame *);
101 static void set_window_update_flags (struct window *w, bool on_p);
102
103
104
105 bool display_completed;
106
107
108
109 static bool delayed_size_change;
110
111
112
113 struct glyph space_glyph;
114
115 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
116
117
118
119
120 static int glyph_matrix_count;
121 static int glyph_pool_count;
122
123 #endif
124
125
126
127
128 static struct frame *frame_matrix_frame;
129
130
131
132
133 #ifdef GLYPH_DEBUG
134
135 static int window_to_frame_vpos (struct window *, int);
136 static int window_to_frame_hpos (struct window *, int);
137 #define WINDOW_TO_FRAME_VPOS(W, VPOS) window_to_frame_vpos ((W), (VPOS))
138 #define WINDOW_TO_FRAME_HPOS(W, HPOS) window_to_frame_hpos ((W), (HPOS))
139
140
141
142
143 struct redisplay_history
144 {
145 char trace[512 + 100];
146 };
147
148
149
150 #define REDISPLAY_HISTORY_SIZE 30
151
152
153
154 static struct redisplay_history redisplay_history[REDISPLAY_HISTORY_SIZE];
155
156
157
158 static int history_idx;
159
160
161
162
163 static uintmax_t history_tick;
164
165
166
167
168
169
170 static void
171 add_window_display_history (struct window *w, const char *msg, bool paused_p)
172 {
173 char *buf;
174 void *ptr = w;
175
176 if (history_idx >= REDISPLAY_HISTORY_SIZE)
177 history_idx = 0;
178 buf = redisplay_history[history_idx].trace;
179 ++history_idx;
180
181 snprintf (buf, sizeof redisplay_history[0].trace,
182 "%"PRIuMAX": window %p (%s)%s\n%s",
183 history_tick++,
184 ptr,
185 ((BUFFERP (w->contents)
186 && STRINGP (BVAR (XBUFFER (w->contents), name)))
187 ? SSDATA (BVAR (XBUFFER (w->contents), name))
188 : "???"),
189 paused_p ? " ***paused***" : "",
190 msg);
191 }
192
193
194
195
196
197
198 static void
199 add_frame_display_history (struct frame *f, bool paused_p)
200 {
201 char *buf;
202 void *ptr = f;
203
204 if (history_idx >= REDISPLAY_HISTORY_SIZE)
205 history_idx = 0;
206 buf = redisplay_history[history_idx].trace;
207 ++history_idx;
208
209 sprintf (buf, "%"PRIuMAX": update frame %p%s",
210 history_tick++,
211 ptr, paused_p ? " ***paused***" : "");
212 }
213
214
215 DEFUN ("dump-redisplay-history", Fdump_redisplay_history,
216 Sdump_redisplay_history, 0, 0, "",
217 doc: )
218 (void)
219 {
220 int i;
221
222 for (i = history_idx - 1; i != history_idx; --i)
223 {
224 if (i < 0)
225 i = REDISPLAY_HISTORY_SIZE - 1;
226 fprintf (stderr, "%s\n", redisplay_history[i].trace);
227 }
228
229 return Qnil;
230 }
231
232
233 #else
234
235 #define WINDOW_TO_FRAME_VPOS(W, VPOS) ((VPOS) + WINDOW_TOP_EDGE_LINE (W))
236 #define WINDOW_TO_FRAME_HPOS(W, HPOS) ((HPOS) + WINDOW_LEFT_EDGE_COL (W))
237
238 #endif
239
240
241 #if defined PROFILING && !HAVE___EXECUTABLE_START
242
243
244 void
245 __executable_start (void)
246 {
247 emacs_abort ();
248 }
249 #endif
250
251
252
253
254
255
256
257
258
259
260
261 static struct glyph_matrix *
262 new_glyph_matrix (struct glyph_pool *pool)
263 {
264 struct glyph_matrix *result = xzalloc (sizeof *result);
265
266 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
267
268
269 ++glyph_matrix_count;
270 #endif
271
272
273 result->pool = pool;
274 return result;
275 }
276
277
278
279
280
281
282
283
284
285
286
287
288
289 static void
290 free_glyph_matrix (struct glyph_matrix *matrix)
291 {
292 if (matrix)
293 {
294 int i;
295
296 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
297
298
299 --glyph_matrix_count;
300 eassert (glyph_matrix_count >= 0);
301 #endif
302
303
304 if (matrix->pool == NULL)
305 for (i = 0; i < matrix->rows_allocated; ++i)
306 xfree (matrix->rows[i].glyphs[LEFT_MARGIN_AREA]);
307
308
309 xfree (matrix->rows);
310 xfree (matrix);
311 }
312 }
313
314
315
316
317
318
319
320 static int
321 margin_glyphs_to_reserve (struct window *w, int total_glyphs, int margin)
322 {
323 if (margin > 0)
324 {
325 int width = w->total_cols;
326 double d = max (0, margin);
327 d = min (width / 2 - 1, d);
328
329
330 return max (1, (int) ((double) total_glyphs / width * d));
331 }
332 return 0;
333 }
334
335
336
337
338 static bool
339 verify_row_hash (struct glyph_row *row)
340 {
341 return row->hash == row_hash (row);
342 }
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366 static void
367 adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y, struct dim dim)
368 {
369 int i;
370 int new_rows;
371 bool marginal_areas_changed_p = 0;
372 bool tab_line_changed_p = 0;
373 bool tab_line_p = 0;
374 bool header_line_changed_p = 0;
375 bool header_line_p = 0;
376 int left = -1, right = -1;
377 int window_width = -1, window_height = -1;
378
379
380
381 if (w)
382 {
383 window_box (w, ANY_AREA, 0, 0, &window_width, &window_height);
384
385 tab_line_p = window_wants_tab_line (w);
386 tab_line_changed_p = tab_line_p != matrix->tab_line_p;
387
388 header_line_p = window_wants_header_line (w);
389 header_line_changed_p = header_line_p != matrix->header_line_p;
390 }
391 matrix->tab_line_p = tab_line_p;
392 matrix->header_line_p = header_line_p;
393
394
395
396
397
398 eassume (w != NULL || matrix->pool != NULL);
399 if (matrix->pool == NULL)
400 {
401 left = margin_glyphs_to_reserve (w, dim.width, w->left_margin_cols);
402 right = margin_glyphs_to_reserve (w, dim.width, w->right_margin_cols);
403 eassert (left >= 0 && right >= 0);
404 marginal_areas_changed_p = (left != matrix->left_margin_glyphs
405 || right != matrix->right_margin_glyphs);
406
407 if (!marginal_areas_changed_p
408 && !XFRAME (w->frame)->fonts_changed
409 && !tab_line_changed_p
410 && !header_line_changed_p
411 && matrix->window_pixel_left == WINDOW_LEFT_PIXEL_EDGE (w)
412 && matrix->window_pixel_top == WINDOW_TOP_PIXEL_EDGE (w)
413 && matrix->window_height == window_height
414 && matrix->window_vscroll == w->vscroll
415 && matrix->window_width == window_width)
416 return;
417 }
418
419
420 if (matrix->rows_allocated < dim.height)
421 {
422 int old_alloc = matrix->rows_allocated;
423 new_rows = dim.height - matrix->rows_allocated;
424 matrix->rows = xpalloc (matrix->rows, &matrix->rows_allocated,
425 new_rows, INT_MAX, sizeof *matrix->rows);
426 memset (matrix->rows + old_alloc, 0,
427 (matrix->rows_allocated - old_alloc) * sizeof *matrix->rows);
428 }
429 else
430 new_rows = 0;
431
432
433
434
435 if (matrix->pool)
436 {
437 eassert (matrix->pool->glyphs);
438
439 if (w)
440 {
441 left = margin_glyphs_to_reserve (w, dim.width,
442 w->left_margin_cols);
443 right = margin_glyphs_to_reserve (w, dim.width,
444 w->right_margin_cols);
445 }
446 else
447 left = right = 0;
448
449 for (i = 0; i < dim.height; ++i)
450 {
451 struct glyph_row *row = &matrix->rows[i];
452
453 row->glyphs[LEFT_MARGIN_AREA]
454 = (matrix->pool->glyphs
455 + (y + i) * matrix->pool->ncolumns
456 + x);
457
458 if (w == NULL
459 || (row == matrix->rows + dim.height - 1
460 && window_wants_mode_line (w))
461 || (row == matrix->rows && matrix->tab_line_p)
462 || (row == matrix->rows
463 && !matrix->tab_line_p && matrix->header_line_p)
464 || (row == (matrix->rows + 1)
465 && matrix->tab_line_p && matrix->header_line_p))
466 {
467 row->glyphs[TEXT_AREA]
468 = row->glyphs[LEFT_MARGIN_AREA];
469 row->glyphs[RIGHT_MARGIN_AREA]
470 = row->glyphs[TEXT_AREA] + dim.width;
471 row->glyphs[LAST_AREA]
472 = row->glyphs[RIGHT_MARGIN_AREA];
473 }
474 else
475 {
476 row->glyphs[TEXT_AREA]
477 = row->glyphs[LEFT_MARGIN_AREA] + left;
478 row->glyphs[RIGHT_MARGIN_AREA]
479 = row->glyphs[TEXT_AREA] + dim.width - left - right;
480
481 if (!FRAME_WINDOW_P (XFRAME (w->frame))
482 && !WINDOW_RIGHTMOST_P (w)
483 && right > 0)
484 row->glyphs[RIGHT_MARGIN_AREA] -= 1;
485 row->glyphs[LAST_AREA]
486 = row->glyphs[LEFT_MARGIN_AREA] + dim.width;
487 }
488 }
489
490 matrix->left_margin_glyphs = left;
491 matrix->right_margin_glyphs = right;
492 }
493 else
494 {
495
496
497
498 if (dim.width > matrix->matrix_w
499 || new_rows
500 || tab_line_changed_p
501 || header_line_changed_p
502 || marginal_areas_changed_p)
503 {
504 struct glyph_row *row = matrix->rows;
505 struct glyph_row *end = row + matrix->rows_allocated;
506
507 while (row < end)
508 {
509 row->glyphs[LEFT_MARGIN_AREA]
510 = xnrealloc (row->glyphs[LEFT_MARGIN_AREA],
511 dim.width, sizeof (struct glyph));
512
513
514 if ((row == matrix->rows + dim.height - 1
515 && !(w && window_wants_mode_line (w)))
516 || (row == matrix->rows && matrix->tab_line_p)
517 || (row == matrix->rows
518 && !matrix->tab_line_p && matrix->header_line_p)
519 || (row == (matrix->rows + 1)
520 && matrix->tab_line_p && matrix->header_line_p))
521 {
522 row->glyphs[TEXT_AREA]
523 = row->glyphs[LEFT_MARGIN_AREA];
524 row->glyphs[RIGHT_MARGIN_AREA]
525 = row->glyphs[TEXT_AREA] + dim.width;
526 row->glyphs[LAST_AREA]
527 = row->glyphs[RIGHT_MARGIN_AREA];
528 }
529 else
530 {
531 row->glyphs[TEXT_AREA]
532 = row->glyphs[LEFT_MARGIN_AREA] + left;
533 row->glyphs[RIGHT_MARGIN_AREA]
534 = row->glyphs[TEXT_AREA] + dim.width - left - right;
535 row->glyphs[LAST_AREA]
536 = row->glyphs[LEFT_MARGIN_AREA] + dim.width;
537 }
538 ++row;
539 }
540 }
541
542 eassert (left >= 0 && right >= 0);
543 matrix->left_margin_glyphs = left;
544 matrix->right_margin_glyphs = right;
545
546
547
548 if (w && matrix == w->current_matrix
549 && matrix->nrows > 0
550 && dim.height != matrix->nrows
551 && matrix->nrows <= matrix->rows_allocated)
552 MATRIX_MODE_LINE_ROW (matrix)->mode_line_p = false;
553 }
554
555
556 matrix->nrows = dim.height;
557 eassert (matrix->nrows >= 0);
558
559 if (w)
560 {
561 if (matrix == w->current_matrix)
562 {
563
564
565
566
567 if (window_width < 0)
568 window_width = window_box_width (w, -1);
569
570
571
572
573 if (!marginal_areas_changed_p
574 && !tab_line_changed_p
575 && !header_line_changed_p
576 && new_rows == 0
577 && dim.width == matrix->matrix_w
578 && matrix->window_pixel_left == WINDOW_LEFT_PIXEL_EDGE (w)
579 && matrix->window_pixel_top == WINDOW_TOP_PIXEL_EDGE (w)
580 && matrix->window_width == window_width)
581 {
582
583 for (i = 0; i < matrix->nrows && matrix->rows[i].enabled_p; ++i)
584 if (MATRIX_ROW_BOTTOM_Y (matrix->rows + i) >= window_height)
585 {
586 ++i;
587 break;
588 }
589
590
591
592 if (w->window_end_vpos >= i)
593 w->window_end_valid = 0;
594
595 while (i < matrix->nrows)
596 matrix->rows[i++].enabled_p = false;
597 }
598 else
599 {
600 for (i = 0; i < matrix->nrows; ++i)
601 matrix->rows[i].enabled_p = false;
602 }
603
604
605
606
607 if (window_wants_mode_line (w))
608 w->update_mode_line = 1;
609 }
610 else if (matrix == w->desired_matrix)
611 {
612
613
614
615
616 for (i = 0; i < matrix->nrows; ++i)
617 matrix->rows[i].enabled_p = false;
618 }
619 }
620
621
622
623 matrix->matrix_x = x;
624 matrix->matrix_y = y;
625 matrix->matrix_w = dim.width;
626 matrix->matrix_h = dim.height;
627
628
629
630 if (w)
631 {
632 matrix->window_pixel_left = WINDOW_LEFT_PIXEL_EDGE (w);
633 matrix->window_pixel_top = WINDOW_TOP_PIXEL_EDGE (w);
634 matrix->window_height = window_height;
635 matrix->window_width = window_width;
636 matrix->window_vscroll = w->vscroll;
637 }
638 }
639
640
641
642
643
644
645
646 static void
647 reverse_rows (struct glyph_matrix *matrix, int start, int end)
648 {
649 int i, j;
650
651 for (i = start, j = end - 1; i < j; ++i, --j)
652 {
653
654
655 struct glyph_row temp;
656 temp = matrix->rows[i];
657 matrix->rows[i] = matrix->rows[j];
658 matrix->rows[j] = temp;
659 }
660 }
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675 void
676 rotate_matrix (struct glyph_matrix *matrix, int first, int last, int by)
677 {
678 if (by < 0)
679 {
680
681 by = -by;
682 reverse_rows (matrix, first, first + by);
683 reverse_rows (matrix, first + by, last);
684 reverse_rows (matrix, first, last);
685 }
686 else if (by > 0)
687 {
688
689 reverse_rows (matrix, last - by, last);
690 reverse_rows (matrix, first, last - by);
691 reverse_rows (matrix, first, last);
692 }
693 }
694
695
696
697
698
699
700 void
701 increment_matrix_positions (struct glyph_matrix *matrix, int start, int end,
702 ptrdiff_t delta, ptrdiff_t delta_bytes)
703 {
704
705 eassert (start >= 0 && start <= matrix->nrows);
706 eassert (end >= 0 && end <= matrix->nrows);
707 eassert (start <= end);
708
709 for (; start < end; ++start)
710 increment_row_positions (matrix->rows + start, delta, delta_bytes);
711 }
712
713
714
715
716
717 void
718 clear_glyph_matrix_rows (struct glyph_matrix *matrix, int start, int end)
719 {
720 eassert (start <= end);
721 eassert (start >= 0 && (start < matrix->nrows
722
723 || (matrix->nrows == 0)));
724 eassert (end >= 0 && end <= matrix->nrows);
725
726 for (; start < end; ++start)
727 matrix->rows[start].enabled_p = false;
728 }
729
730
731
732
733
734
735
736
737
738
739
740 void
741 clear_glyph_matrix (struct glyph_matrix *matrix)
742 {
743 if (matrix)
744 {
745 clear_glyph_matrix_rows (matrix, 0, matrix->nrows);
746 matrix->no_scrolling_p = 0;
747 }
748 }
749
750
751
752
753
754
755 void
756 shift_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int start, int end, int dy)
757 {
758 int min_y, max_y;
759
760 eassert (start <= end);
761 eassert (start >= 0 && start < matrix->nrows);
762 eassert (end >= 0 && end <= matrix->nrows);
763
764 min_y = WINDOW_TAB_LINE_HEIGHT (w) + WINDOW_HEADER_LINE_HEIGHT (w);
765 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (w);
766
767 for (; start < end; ++start)
768 {
769 struct glyph_row *row = &matrix->rows[start];
770
771 row->y += dy;
772 row->visible_height = row->height;
773
774 if (row->y < min_y)
775 row->visible_height -= min_y - row->y;
776 if (row->y + row->height > max_y)
777 row->visible_height -= row->y + row->height - max_y;
778 if (row->fringe_bitmap_periodic_p)
779 row->redraw_fringe_bitmaps_p = 1;
780 }
781 }
782
783
784
785
786
787
788 void
789 clear_current_matrices (register struct frame *f)
790 {
791
792 if (f->current_matrix)
793 clear_glyph_matrix (f->current_matrix);
794
795 #if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
796
797
798
799 if (WINDOWP (f->menu_bar_window))
800 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->current_matrix);
801 #endif
802
803 #if defined (HAVE_WINDOW_SYSTEM)
804
805 if (WINDOWP (f->tab_bar_window))
806 clear_glyph_matrix (XWINDOW (f->tab_bar_window)->current_matrix);
807 #endif
808
809 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_TOOL_BAR)
810
811 if (WINDOWP (f->tool_bar_window))
812 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
813 #endif
814
815
816 eassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
817 clear_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f)), 0);
818 }
819
820
821
822
823 void
824 clear_desired_matrices (register struct frame *f)
825 {
826 if (f->desired_matrix)
827 clear_glyph_matrix (f->desired_matrix);
828
829 #if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
830 if (WINDOWP (f->menu_bar_window))
831 clear_glyph_matrix (XWINDOW (f->menu_bar_window)->desired_matrix);
832 #endif
833
834 #if defined (HAVE_WINDOW_SYSTEM)
835 if (WINDOWP (f->tab_bar_window))
836 clear_glyph_matrix (XWINDOW (f->tab_bar_window)->desired_matrix);
837 #endif
838
839 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_TOOL_BAR)
840 if (WINDOWP (f->tool_bar_window))
841 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->desired_matrix);
842 #endif
843
844
845 eassert (WINDOWP (FRAME_ROOT_WINDOW (f)));
846 clear_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f)), 1);
847 }
848
849
850
851
852
853 static void
854 clear_window_matrices (struct window *w, bool desired_p)
855 {
856 while (w)
857 {
858 if (WINDOWP (w->contents))
859 clear_window_matrices (XWINDOW (w->contents), desired_p);
860 else
861 {
862 if (desired_p)
863 clear_glyph_matrix (w->desired_matrix);
864 else
865 {
866 clear_glyph_matrix (w->current_matrix);
867 w->window_end_valid = 0;
868 }
869 }
870
871 w = NILP (w->next) ? 0 : XWINDOW (w->next);
872 }
873 }
874
875
876
877
878
879
880
881
882
883
884
885
886 void
887 clear_glyph_row (struct glyph_row *row)
888 {
889 enum { off = offsetof (struct glyph_row, used) };
890
891
892 memset ((char *) row + off, 0, sizeof *row - off);
893 }
894
895
896
897
898
899 void
900 blank_row (struct window *w, struct glyph_row *row, int y)
901 {
902 int min_y, max_y;
903
904 min_y = WINDOW_TAB_LINE_HEIGHT (w) + WINDOW_HEADER_LINE_HEIGHT (w);
905 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (w);
906
907 clear_glyph_row (row);
908 row->y = y;
909 row->ascent = row->phys_ascent = 0;
910 row->height = row->phys_height = FRAME_LINE_HEIGHT (XFRAME (w->frame));
911 row->visible_height = row->height;
912
913 if (row->y < min_y)
914 row->visible_height -= min_y - row->y;
915 if (row->y + row->height > max_y)
916 row->visible_height -= row->y + row->height - max_y;
917
918 row->enabled_p = true;
919 }
920
921
922
923
924
925
926
927
928 static void
929 increment_row_positions (struct glyph_row *row,
930 ptrdiff_t delta, ptrdiff_t delta_bytes)
931 {
932 int area, i;
933
934
935 MATRIX_ROW_START_CHARPOS (row) += delta;
936 MATRIX_ROW_START_BYTEPOS (row) += delta_bytes;
937 MATRIX_ROW_END_CHARPOS (row) += delta;
938 MATRIX_ROW_END_BYTEPOS (row) += delta_bytes;
939 CHARPOS (row->start.pos) += delta;
940 BYTEPOS (row->start.pos) += delta_bytes;
941 CHARPOS (row->end.pos) += delta;
942 BYTEPOS (row->end.pos) += delta_bytes;
943
944 if (!row->enabled_p)
945 return;
946
947
948 for (area = 0; area < LAST_AREA; ++area)
949 for (i = 0; i < row->used[area]; ++i)
950 if (BUFFERP (row->glyphs[area][i].object)
951 && row->glyphs[area][i].charpos > 0)
952 row->glyphs[area][i].charpos += delta;
953
954
955 if (row->used[TEXT_AREA] == 0
956 && MATRIX_ROW_DISPLAYS_TEXT_P (row))
957 row->glyphs[TEXT_AREA]->charpos += delta;
958 }
959
960
961 #if 0
962
963
964
965
966 static void
967 swap_glyphs_in_rows (struct glyph_row *a, struct glyph_row *b)
968 {
969 int area;
970
971 for (area = 0; area < LAST_AREA; ++area)
972 {
973
974 int max_used = max (a->used[area], b->used[area]);
975
976
977 struct glyph *glyph_a = a->glyphs[area];
978
979
980 struct glyph *glyph_a_end = a->glyphs[max_used];
981
982
983 struct glyph *glyph_b = b->glyphs[area];
984
985 while (glyph_a < glyph_a_end)
986 {
987
988
989 struct glyph temp;
990 temp = *glyph_a;
991 *glyph_a = *glyph_b;
992 *glyph_b = temp;
993 ++glyph_a;
994 ++glyph_b;
995 }
996 }
997 }
998
999 #endif
1000
1001
1002
1003
1004
1005
1006 static void
1007 swap_glyph_pointers (struct glyph_row *a, struct glyph_row *b)
1008 {
1009 int i;
1010 unsigned hash_tem = a->hash;
1011
1012 for (i = 0; i < LAST_AREA + 1; ++i)
1013 {
1014 struct glyph *temp = a->glyphs[i];
1015
1016 a->glyphs[i] = b->glyphs[i];
1017 b->glyphs[i] = temp;
1018 if (i < LAST_AREA)
1019 {
1020 short used_tem = a->used[i];
1021
1022 a->used[i] = b->used[i];
1023 b->used[i] = used_tem;
1024 }
1025 }
1026 a->hash = b->hash;
1027 b->hash = hash_tem;
1028 }
1029
1030
1031
1032
1033
1034
1035
1036 static void
1037 copy_row_except_pointers (struct glyph_row *to, struct glyph_row *from)
1038 {
1039 enum { off = offsetof (struct glyph_row, x) };
1040
1041 memcpy ((char *) to + off, (char *) from + off, sizeof *to - off);
1042 }
1043
1044
1045
1046
1047
1048
1049
1050 static void
1051 assign_row (struct glyph_row *to, struct glyph_row *from)
1052 {
1053 swap_glyph_pointers (to, from);
1054 copy_row_except_pointers (to, from);
1055 }
1056
1057
1058
1059
1060
1061
1062
1063
1064 #ifdef GLYPH_DEBUG
1065
1066 static bool
1067 glyph_row_slice_p (struct glyph_row *window_row, struct glyph_row *frame_row)
1068 {
1069 struct glyph *window_glyph_start = window_row->glyphs[0];
1070 struct glyph *frame_glyph_start = frame_row->glyphs[0];
1071 struct glyph *frame_glyph_end = frame_row->glyphs[LAST_AREA];
1072
1073 return (frame_glyph_start <= window_glyph_start
1074 && window_glyph_start < frame_glyph_end);
1075 }
1076
1077 #endif
1078
1079 #if 0
1080
1081
1082
1083
1084
1085 static struct glyph_row *
1086 find_glyph_row_slice (struct glyph_matrix *window_matrix,
1087 struct glyph_matrix *frame_matrix, int row)
1088 {
1089 int i;
1090
1091 eassert (row >= 0 && row < frame_matrix->nrows);
1092
1093 for (i = 0; i < window_matrix->nrows; ++i)
1094 if (glyph_row_slice_p (window_matrix->rows + i,
1095 frame_matrix->rows + row))
1096 break;
1097
1098 return i < window_matrix->nrows ? window_matrix->rows + i : 0;
1099 }
1100
1101 #endif
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111 void
1112 prepare_desired_row (struct window *w, struct glyph_row *row, bool mode_line_p)
1113 {
1114 if (!row->enabled_p)
1115 {
1116 bool rp = row->reversed_p;
1117
1118 clear_glyph_row (row);
1119 row->enabled_p = true;
1120 row->reversed_p = rp;
1121 }
1122 if (mode_line_p)
1123 {
1124
1125
1126
1127
1128
1129
1130 if (w->left_margin_cols > 0)
1131 row->glyphs[TEXT_AREA] = row->glyphs[LEFT_MARGIN_AREA];
1132 if (w->right_margin_cols > 0)
1133 row->glyphs[RIGHT_MARGIN_AREA] = row->glyphs[LAST_AREA];
1134 }
1135 else
1136 {
1137
1138
1139
1140
1141 int left = w->desired_matrix->left_margin_glyphs;
1142 int right = w->desired_matrix->right_margin_glyphs;
1143
1144
1145
1146
1147 if (w->left_margin_cols > 0
1148 && (left != row->glyphs[TEXT_AREA] - row->glyphs[LEFT_MARGIN_AREA]))
1149 row->glyphs[TEXT_AREA] = row->glyphs[LEFT_MARGIN_AREA] + left;
1150 if (w->right_margin_cols > 0
1151 && (right != row->glyphs[LAST_AREA] - row->glyphs[RIGHT_MARGIN_AREA]))
1152 {
1153 row->glyphs[RIGHT_MARGIN_AREA] = row->glyphs[LAST_AREA] - right;
1154
1155 if (!FRAME_WINDOW_P (XFRAME (w->frame))
1156 && !WINDOW_RIGHTMOST_P (w)
1157 && right > 0)
1158 row->glyphs[RIGHT_MARGIN_AREA] -= 1;
1159 }
1160 }
1161 }
1162
1163 #ifndef HAVE_ANDROID
1164
1165
1166
1167
1168 static unsigned
1169 line_hash_code (struct frame *f, struct glyph_row *row)
1170 {
1171 unsigned hash = 0;
1172
1173 if (row->enabled_p)
1174 {
1175 struct glyph *glyph = row->glyphs[TEXT_AREA];
1176 struct glyph *end = glyph + row->used[TEXT_AREA];
1177
1178 while (glyph < end)
1179 {
1180 int c = glyph->u.ch;
1181 int face_id = glyph->face_id;
1182 if (FRAME_MUST_WRITE_SPACES (f))
1183 c -= SPACEGLYPH;
1184 hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + c;
1185 hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + face_id;
1186 ++glyph;
1187 }
1188
1189 if (hash == 0)
1190 hash = 1;
1191 }
1192
1193 return hash;
1194 }
1195
1196
1197
1198
1199
1200
1201
1202 static int
1203 line_draw_cost (struct frame *f, struct glyph_matrix *matrix, int vpos)
1204 {
1205 struct glyph_row *row = matrix->rows + vpos;
1206 struct glyph *beg = row->glyphs[TEXT_AREA];
1207 struct glyph *end = beg + row->used[TEXT_AREA];
1208 int len;
1209 Lisp_Object *glyph_table_base = GLYPH_TABLE_BASE;
1210 ptrdiff_t glyph_table_len = GLYPH_TABLE_LENGTH;
1211
1212
1213 if (!FRAME_MUST_WRITE_SPACES (f))
1214 {
1215
1216 while (end > beg && CHAR_GLYPH_SPACE_P (*(end - 1)))
1217 --end;
1218
1219
1220 if (end == beg)
1221 return 0;
1222
1223
1224 while (CHAR_GLYPH_SPACE_P (*beg))
1225 ++beg;
1226 }
1227
1228
1229
1230 if (glyph_table_base == 0)
1231 len = end - beg;
1232 else
1233 {
1234
1235
1236 len = 0;
1237 while (beg < end)
1238 {
1239 GLYPH g;
1240
1241 SET_GLYPH_FROM_CHAR_GLYPH (g, *beg);
1242
1243 if (GLYPH_INVALID_P (g)
1244 || GLYPH_SIMPLE_P (glyph_table_base, glyph_table_len, g))
1245 len += 1;
1246 else
1247 len += GLYPH_LENGTH (glyph_table_base, g);
1248
1249 ++beg;
1250 }
1251 }
1252
1253 return len;
1254 }
1255
1256 #endif
1257
1258
1259
1260
1261 static bool
1262 row_equal_p (struct glyph_row *a, struct glyph_row *b, bool mouse_face_p)
1263 {
1264 eassert (verify_row_hash (a));
1265 eassert (verify_row_hash (b));
1266
1267 if (a == b)
1268 return 1;
1269 else if (a->hash != b->hash)
1270 return 0;
1271 else
1272 {
1273 struct glyph *a_glyph, *b_glyph, *a_end;
1274 int area;
1275
1276 if (mouse_face_p && a->mouse_face_p != b->mouse_face_p)
1277 return 0;
1278
1279
1280 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
1281 {
1282 if (a->used[area] != b->used[area])
1283 return 0;
1284
1285 a_glyph = a->glyphs[area];
1286 a_end = a_glyph + a->used[area];
1287 b_glyph = b->glyphs[area];
1288
1289 while (a_glyph < a_end
1290 && GLYPH_EQUAL_P (a_glyph, b_glyph))
1291 ++a_glyph, ++b_glyph;
1292
1293 if (a_glyph != a_end)
1294 return 0;
1295 }
1296
1297 if (a->fill_line_p != b->fill_line_p
1298 || a->cursor_in_fringe_p != b->cursor_in_fringe_p
1299 || a->left_fringe_bitmap != b->left_fringe_bitmap
1300 || a->left_fringe_face_id != b->left_fringe_face_id
1301 || a->left_fringe_offset != b->left_fringe_offset
1302 || a->right_fringe_bitmap != b->right_fringe_bitmap
1303 || a->right_fringe_face_id != b->right_fringe_face_id
1304 || a->right_fringe_offset != b->right_fringe_offset
1305 || a->fringe_bitmap_periodic_p != b->fringe_bitmap_periodic_p
1306 || a->overlay_arrow_bitmap != b->overlay_arrow_bitmap
1307 || a->exact_window_width_line_p != b->exact_window_width_line_p
1308 || a->overlapped_p != b->overlapped_p
1309 || (MATRIX_ROW_CONTINUATION_LINE_P (a)
1310 != MATRIX_ROW_CONTINUATION_LINE_P (b))
1311 || a->reversed_p != b->reversed_p
1312
1313 || a->x != b->x
1314
1315 || a->ascent != b->ascent
1316 || a->phys_ascent != b->phys_ascent
1317 || a->phys_height != b->phys_height
1318 || a->visible_height != b->visible_height)
1319 return 0;
1320 }
1321
1322 return 1;
1323 }
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337 static struct glyph_pool * ATTRIBUTE_MALLOC
1338 new_glyph_pool (void)
1339 {
1340 struct glyph_pool *result = xzalloc (sizeof *result);
1341
1342 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
1343
1344 ++glyph_pool_count;
1345 #endif
1346
1347 return result;
1348 }
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358 static void
1359 free_glyph_pool (struct glyph_pool *pool)
1360 {
1361 if (pool)
1362 {
1363 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
1364
1365 --glyph_pool_count;
1366 eassert (glyph_pool_count >= 0);
1367 #endif
1368 xfree (pool->glyphs);
1369 xfree (pool);
1370 }
1371 }
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383 static bool
1384 realloc_glyph_pool (struct glyph_pool *pool, struct dim matrix_dim)
1385 {
1386 ptrdiff_t needed;
1387 bool changed_p;
1388
1389 changed_p = (pool->glyphs == 0
1390 || matrix_dim.height != pool->nrows
1391 || matrix_dim.width != pool->ncolumns);
1392
1393
1394 if (ckd_mul (&needed, matrix_dim.height, matrix_dim.width))
1395 memory_full (SIZE_MAX);
1396 if (needed > pool->nglyphs)
1397 {
1398 ptrdiff_t old_nglyphs = pool->nglyphs;
1399 pool->glyphs = xpalloc (pool->glyphs, &pool->nglyphs,
1400 needed - old_nglyphs, -1, sizeof *pool->glyphs);
1401 memclear (pool->glyphs + old_nglyphs,
1402 (pool->nglyphs - old_nglyphs) * sizeof *pool->glyphs);
1403 }
1404
1405
1406
1407
1408
1409 pool->nrows = matrix_dim.height;
1410 pool->ncolumns = matrix_dim.width;
1411
1412 return changed_p;
1413 }
1414
1415
1416
1417
1418
1419
1420
1421 #ifdef GLYPH_DEBUG
1422
1423
1424
1425
1426
1427
1428
1429 void flush_stdout (void) EXTERNALLY_VISIBLE;
1430
1431 void
1432 flush_stdout (void)
1433 {
1434 fflush (stdout);
1435 }
1436
1437
1438
1439
1440
1441
1442
1443 void
1444 check_matrix_pointer_lossage (struct glyph_matrix *matrix)
1445 {
1446 int i, j;
1447
1448 for (i = 0; i < matrix->nrows; ++i)
1449 for (j = 0; j < matrix->nrows; ++j)
1450 eassert (i == j
1451 || (matrix->rows[i].glyphs[TEXT_AREA]
1452 != matrix->rows[j].glyphs[TEXT_AREA]));
1453 }
1454
1455
1456
1457
1458 struct glyph_row *
1459 matrix_row (struct glyph_matrix *matrix, int row)
1460 {
1461 eassert (matrix && matrix->rows);
1462 eassert (row >= 0 && row < matrix->nrows);
1463
1464
1465
1466
1467 #if 0
1468 check_matrix_pointer_lossage (matrix);
1469 #endif
1470
1471 return matrix->rows + row;
1472 }
1473
1474
1475 #if 0
1476
1477
1478
1479
1480
1481
1482 static void
1483 check_matrix_invariants (struct window *w)
1484 {
1485 struct glyph_matrix *matrix = w->current_matrix;
1486 int yb = window_text_bottom_y (w);
1487 struct glyph_row *row = matrix->rows;
1488 struct glyph_row *last_text_row = NULL;
1489 struct buffer *saved = current_buffer;
1490 struct buffer *buffer = XBUFFER (w->contents);
1491 int c;
1492
1493
1494 if (matrix->nrows < 2)
1495 return;
1496
1497 set_buffer_temp (buffer);
1498
1499
1500 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
1501 && MATRIX_ROW_BOTTOM_Y (row) < yb)
1502 {
1503 struct glyph_row *next = row + 1;
1504
1505 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
1506 last_text_row = row;
1507
1508
1509 eassert (MATRIX_ROW_START_BYTEPOS (row)
1510 == CHAR_TO_BYTE (MATRIX_ROW_START_CHARPOS (row)));
1511 eassert (BYTEPOS (row->start.pos)
1512 == CHAR_TO_BYTE (CHARPOS (row->start.pos)));
1513
1514
1515
1516
1517 if (MATRIX_ROW_END_CHARPOS (row) < BUF_ZV (current_buffer))
1518 {
1519 eassert (MATRIX_ROW_END_BYTEPOS (row)
1520 == CHAR_TO_BYTE (MATRIX_ROW_END_CHARPOS (row)));
1521 eassert (BYTEPOS (row->end.pos)
1522 == CHAR_TO_BYTE (CHARPOS (row->end.pos)));
1523 }
1524
1525
1526
1527 if (next->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (next))
1528 {
1529 eassert (MATRIX_ROW_END_CHARPOS (row)
1530 == MATRIX_ROW_START_CHARPOS (next));
1531 eassert (MATRIX_ROW_END_BYTEPOS (row)
1532 == MATRIX_ROW_START_BYTEPOS (next));
1533 eassert (CHARPOS (row->end.pos) == CHARPOS (next->start.pos));
1534 eassert (BYTEPOS (row->end.pos) == BYTEPOS (next->start.pos));
1535 }
1536 row = next;
1537 }
1538
1539 eassert (w->current_matrix->nrows == w->desired_matrix->nrows);
1540 eassert (w->desired_matrix->rows != NULL);
1541 set_buffer_temp (saved);
1542 }
1543
1544 #endif
1545
1546 #endif
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627 #define NEW_LEAF_MATRIX (1 << 0)
1628
1629
1630
1631
1632 #define CHANGED_LEAF_MATRIX (1 << 1)
1633
1634 static struct dim
1635 allocate_matrices_for_frame_redisplay (Lisp_Object window, int x, int y,
1636 bool dim_only_p, int *window_change_flags)
1637 {
1638 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
1639 int x0 = x, y0 = y;
1640 int wmax = 0, hmax = 0;
1641 struct dim total;
1642 struct dim dim;
1643 struct window *w;
1644 bool in_horz_combination_p;
1645
1646
1647
1648
1649
1650
1651
1652 in_horz_combination_p
1653 = (!NILP (XWINDOW (window)->parent)
1654 && WINDOW_HORIZONTAL_COMBINATION_P (XWINDOW (XWINDOW (window)->parent)));
1655
1656
1657 do
1658 {
1659 w = XWINDOW (window);
1660
1661
1662
1663 if (WINDOWP (w->contents))
1664 dim = allocate_matrices_for_frame_redisplay (w->contents, x, y,
1665 dim_only_p,
1666 window_change_flags);
1667 else
1668 {
1669
1670 if (w->desired_matrix == NULL)
1671 {
1672 w->desired_matrix = new_glyph_matrix (f->desired_pool);
1673 w->current_matrix = new_glyph_matrix (f->current_pool);
1674 *window_change_flags |= NEW_LEAF_MATRIX;
1675 }
1676
1677
1678
1679 dim.width = required_matrix_width (w);
1680 dim.height = required_matrix_height (w);
1681
1682
1683 if (x != w->desired_matrix->matrix_x
1684 || y != w->desired_matrix->matrix_y
1685 || dim.width != w->desired_matrix->matrix_w
1686 || dim.height != w->desired_matrix->matrix_h
1687 || (margin_glyphs_to_reserve (w, dim.width,
1688 w->left_margin_cols)
1689 != w->desired_matrix->left_margin_glyphs)
1690 || (margin_glyphs_to_reserve (w, dim.width,
1691 w->right_margin_cols)
1692 != w->desired_matrix->right_margin_glyphs))
1693 *window_change_flags |= CHANGED_LEAF_MATRIX;
1694
1695
1696
1697
1698
1699
1700 if (!dim_only_p)
1701 {
1702 adjust_glyph_matrix (w, w->desired_matrix, x, y, dim);
1703 adjust_glyph_matrix (w, w->current_matrix, x, y, dim);
1704 }
1705 }
1706
1707
1708
1709
1710 if (in_horz_combination_p)
1711 x += dim.width;
1712 else
1713 y += dim.height;
1714
1715
1716 wmax = max (wmax, dim.width);
1717 hmax = max (hmax, dim.height);
1718
1719
1720 window = w->next;
1721 }
1722 while (!NILP (window));
1723
1724
1725
1726
1727
1728
1729
1730 if (in_horz_combination_p)
1731 {
1732 total.width = x - x0;
1733 total.height = hmax;
1734 }
1735 else
1736 {
1737 total.width = wmax;
1738 total.height = y - y0;
1739 }
1740
1741 return total;
1742 }
1743
1744
1745
1746
1747 static int
1748 required_matrix_height (struct window *w)
1749 {
1750 #ifdef HAVE_WINDOW_SYSTEM
1751 struct frame *f = XFRAME (w->frame);
1752
1753 if (FRAME_WINDOW_P (f))
1754 {
1755
1756 int ch_height = max (FRAME_SMALLEST_FONT_HEIGHT (f), 1);
1757 int window_pixel_height = window_box_height (w) + eabs (w->vscroll);
1758
1759 return (((window_pixel_height + ch_height - 1)
1760 / ch_height) * w->nrows_scale_factor
1761
1762
1763 + 2
1764
1765 + 3);
1766 }
1767 #endif
1768
1769 return WINDOW_TOTAL_LINES (w);
1770 }
1771
1772
1773
1774
1775 static int
1776 required_matrix_width (struct window *w)
1777 {
1778 #ifdef HAVE_WINDOW_SYSTEM
1779 struct frame *f = XFRAME (w->frame);
1780 if (FRAME_WINDOW_P (f))
1781 {
1782
1783 int ch_width = max (FRAME_SMALLEST_CHAR_WIDTH (f), 1);
1784
1785
1786 return (((WINDOW_PIXEL_WIDTH (w) + ch_width - 1)
1787 / ch_width) * w->ncols_scale_factor
1788
1789 + 2
1790
1791
1792 + 1 + 1);
1793 }
1794 #endif
1795
1796 return w->total_cols;
1797 }
1798
1799
1800
1801
1802
1803 static void
1804 allocate_matrices_for_window_redisplay (struct window *w)
1805 {
1806 while (w)
1807 {
1808 if (WINDOWP (w->contents))
1809 allocate_matrices_for_window_redisplay (XWINDOW (w->contents));
1810 else
1811 {
1812
1813 struct dim dim;
1814
1815
1816 if (w->desired_matrix == NULL)
1817 {
1818 w->desired_matrix = new_glyph_matrix (NULL);
1819 eassert (w->current_matrix == NULL);
1820 }
1821
1822 if (w->current_matrix == NULL)
1823 w->current_matrix = new_glyph_matrix (NULL);
1824
1825 dim.width = required_matrix_width (w);
1826 dim.height = required_matrix_height (w);
1827 adjust_glyph_matrix (w, w->desired_matrix, 0, 0, dim);
1828 adjust_glyph_matrix (w, w->current_matrix, 0, 0, dim);
1829 }
1830
1831 w = NILP (w->next) ? NULL : XWINDOW (w->next);
1832 }
1833 }
1834
1835
1836
1837
1838
1839 void
1840 adjust_frame_glyphs (struct frame *f)
1841 {
1842
1843
1844 block_input ();
1845
1846 if (FRAME_WINDOW_P (f))
1847 adjust_frame_glyphs_for_window_redisplay (f);
1848 else
1849 {
1850 adjust_frame_glyphs_for_frame_redisplay (f);
1851 eassert (FRAME_INITIAL_P (f)
1852 || noninteractive
1853 || !initialized
1854 || (f->current_matrix
1855 && f->current_matrix->nrows > 0
1856 && f->current_matrix->rows
1857 && f->desired_matrix
1858 && f->desired_matrix->nrows > 0
1859 && f->desired_matrix->rows));
1860 }
1861
1862
1863 adjust_decode_mode_spec_buffer (f);
1864
1865 f->glyphs_initialized_p = true;
1866
1867 unblock_input ();
1868 }
1869
1870
1871
1872 static bool
1873 showing_window_margins_p (struct window *w)
1874 {
1875 while (w)
1876 {
1877 if (WINDOWP (w->contents))
1878 {
1879 if (showing_window_margins_p (XWINDOW (w->contents)))
1880 return 1;
1881 }
1882 else if (w->left_margin_cols > 0 || w->right_margin_cols > 0)
1883 return 1;
1884
1885 w = NILP (w->next) ? 0 : XWINDOW (w->next);
1886 }
1887 return 0;
1888 }
1889
1890
1891
1892
1893
1894 static void
1895 fake_current_matrices (Lisp_Object window)
1896 {
1897 struct window *w;
1898
1899 for (; !NILP (window); window = w->next)
1900 {
1901 w = XWINDOW (window);
1902
1903 if (WINDOWP (w->contents))
1904 fake_current_matrices (w->contents);
1905 else
1906 {
1907 int i;
1908 struct frame *f = XFRAME (w->frame);
1909 struct glyph_matrix *m = w->current_matrix;
1910 struct glyph_matrix *fm = f->current_matrix;
1911
1912 eassert (m->matrix_h == WINDOW_TOTAL_LINES (w));
1913 eassert (m->matrix_w == WINDOW_TOTAL_COLS (w));
1914
1915 for (i = 0; i < m->matrix_h; ++i)
1916 {
1917 struct glyph_row *r = m->rows + i;
1918 struct glyph_row *fr = fm->rows + i + WINDOW_TOP_EDGE_LINE (w);
1919
1920 eassert (r->glyphs[TEXT_AREA] >= fr->glyphs[TEXT_AREA]
1921 && r->glyphs[LAST_AREA] <= fr->glyphs[LAST_AREA]);
1922
1923 r->enabled_p = fr->enabled_p;
1924 if (r->enabled_p)
1925 {
1926 r->used[LEFT_MARGIN_AREA] = m->left_margin_glyphs;
1927 r->used[RIGHT_MARGIN_AREA] = m->right_margin_glyphs;
1928 r->used[TEXT_AREA] = (m->matrix_w
1929 - r->used[LEFT_MARGIN_AREA]
1930 - r->used[RIGHT_MARGIN_AREA]);
1931 r->mode_line_p = 0;
1932 r->tab_line_p = 0;
1933 }
1934 }
1935 }
1936 }
1937 }
1938
1939
1940
1941
1942
1943 static struct glyph_matrix *
1944 save_current_matrix (struct frame *f)
1945 {
1946 int i;
1947 struct glyph_matrix *saved = xzalloc (sizeof *saved);
1948 saved->nrows = f->current_matrix->nrows;
1949 saved->rows = xzalloc (saved->nrows * sizeof *saved->rows);
1950
1951 for (i = 0; i < saved->nrows; ++i)
1952 {
1953 struct glyph_row *from = f->current_matrix->rows + i;
1954 struct glyph_row *to = saved->rows + i;
1955 ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
1956
1957 to->glyphs[TEXT_AREA] = xmalloc (nbytes);
1958 memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
1959 to->used[TEXT_AREA] = from->used[TEXT_AREA];
1960 to->enabled_p = from->enabled_p;
1961 to->hash = from->hash;
1962 if (from->used[LEFT_MARGIN_AREA])
1963 {
1964 nbytes = from->used[LEFT_MARGIN_AREA] * sizeof (struct glyph);
1965 to->glyphs[LEFT_MARGIN_AREA] = xmalloc (nbytes);
1966 memcpy (to->glyphs[LEFT_MARGIN_AREA],
1967 from->glyphs[LEFT_MARGIN_AREA], nbytes);
1968 to->used[LEFT_MARGIN_AREA] = from->used[LEFT_MARGIN_AREA];
1969 }
1970 if (from->used[RIGHT_MARGIN_AREA])
1971 {
1972 nbytes = from->used[RIGHT_MARGIN_AREA] * sizeof (struct glyph);
1973 to->glyphs[RIGHT_MARGIN_AREA] = xmalloc (nbytes);
1974 memcpy (to->glyphs[RIGHT_MARGIN_AREA],
1975 from->glyphs[RIGHT_MARGIN_AREA], nbytes);
1976 to->used[RIGHT_MARGIN_AREA] = from->used[RIGHT_MARGIN_AREA];
1977 }
1978 }
1979
1980 return saved;
1981 }
1982
1983
1984
1985
1986
1987 static void
1988 restore_current_matrix (struct frame *f, struct glyph_matrix *saved)
1989 {
1990 int i;
1991
1992 for (i = 0; i < saved->nrows; ++i)
1993 {
1994 struct glyph_row *from = saved->rows + i;
1995 struct glyph_row *to = f->current_matrix->rows + i;
1996 ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
1997
1998 memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
1999 to->used[TEXT_AREA] = from->used[TEXT_AREA];
2000 xfree (from->glyphs[TEXT_AREA]);
2001 nbytes = from->used[LEFT_MARGIN_AREA] * sizeof (struct glyph);
2002 if (nbytes)
2003 {
2004 memcpy (to->glyphs[LEFT_MARGIN_AREA],
2005 from->glyphs[LEFT_MARGIN_AREA], nbytes);
2006 to->used[LEFT_MARGIN_AREA] = from->used[LEFT_MARGIN_AREA];
2007 xfree (from->glyphs[LEFT_MARGIN_AREA]);
2008 }
2009 else
2010 to->used[LEFT_MARGIN_AREA] = 0;
2011 nbytes = from->used[RIGHT_MARGIN_AREA] * sizeof (struct glyph);
2012 if (nbytes)
2013 {
2014 memcpy (to->glyphs[RIGHT_MARGIN_AREA],
2015 from->glyphs[RIGHT_MARGIN_AREA], nbytes);
2016 to->used[RIGHT_MARGIN_AREA] = from->used[RIGHT_MARGIN_AREA];
2017 xfree (from->glyphs[RIGHT_MARGIN_AREA]);
2018 }
2019 else
2020 to->used[RIGHT_MARGIN_AREA] = 0;
2021 }
2022
2023 xfree (saved->rows);
2024 xfree (saved);
2025 }
2026
2027
2028
2029
2030
2031
2032 static void
2033 adjust_frame_glyphs_for_frame_redisplay (struct frame *f)
2034 {
2035 struct dim matrix_dim;
2036 bool pool_changed_p;
2037 int window_change_flags;
2038 int top_window_y;
2039
2040 if (!FRAME_LIVE_P (f))
2041 return;
2042
2043 top_window_y = FRAME_TOP_MARGIN (f);
2044
2045
2046 if (f->desired_pool == NULL)
2047 {
2048 f->desired_pool = new_glyph_pool ();
2049 f->current_pool = new_glyph_pool ();
2050 }
2051
2052
2053 if (f->desired_matrix == NULL)
2054 {
2055 f->desired_matrix = new_glyph_matrix (f->desired_pool);
2056 f->current_matrix = new_glyph_matrix (f->current_pool);
2057 }
2058
2059
2060
2061
2062
2063
2064
2065 window_change_flags = 0;
2066 matrix_dim
2067 = allocate_matrices_for_frame_redisplay (FRAME_ROOT_WINDOW (f),
2068 0, top_window_y,
2069 1,
2070 &window_change_flags);
2071
2072
2073 matrix_dim.height += top_window_y;
2074
2075
2076 pool_changed_p = realloc_glyph_pool (f->desired_pool, matrix_dim);
2077 realloc_glyph_pool (f->current_pool, matrix_dim);
2078
2079
2080
2081 if (pool_changed_p || window_change_flags)
2082 {
2083
2084 allocate_matrices_for_frame_redisplay (FRAME_ROOT_WINDOW (f),
2085 0, top_window_y, 0,
2086 &window_change_flags);
2087
2088
2089
2090
2091 if (matrix_dim.width != FRAME_TOTAL_COLS (f)
2092 || matrix_dim.height != FRAME_TOTAL_LINES (f))
2093 {
2094
2095
2096
2097
2098
2099
2100
2101
2102 if (!FRAME_WINDOW_P (f) && pool_changed_p)
2103 SET_FRAME_GARBAGED (f);
2104 return;
2105 }
2106
2107 eassert (matrix_dim.width == FRAME_TOTAL_COLS (f)
2108 && matrix_dim.height == FRAME_TOTAL_LINES (f));
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119 if (display_completed
2120 && !FRAME_GARBAGED_P (f)
2121 && matrix_dim.width == f->current_matrix->matrix_w
2122 && matrix_dim.height == f->current_matrix->matrix_h
2123
2124
2125
2126
2127 && !showing_window_margins_p (XWINDOW (FRAME_ROOT_WINDOW (f))))
2128 {
2129 struct glyph_matrix *copy = save_current_matrix (f);
2130 adjust_glyph_matrix (NULL, f->desired_matrix, 0, 0, matrix_dim);
2131 adjust_glyph_matrix (NULL, f->current_matrix, 0, 0, matrix_dim);
2132 restore_current_matrix (f, copy);
2133 fake_current_matrices (FRAME_ROOT_WINDOW (f));
2134 }
2135 else
2136 {
2137 adjust_glyph_matrix (NULL, f->desired_matrix, 0, 0, matrix_dim);
2138 adjust_glyph_matrix (NULL, f->current_matrix, 0, 0, matrix_dim);
2139 SET_FRAME_GARBAGED (f);
2140 }
2141 }
2142 else if (!FRAME_INITIAL_P (f) && !noninteractive && initialized)
2143 {
2144 if (!f->desired_matrix->nrows || !f->desired_matrix->rows)
2145 {
2146 adjust_glyph_matrix (NULL, f->desired_matrix, 0, 0, matrix_dim);
2147 SET_FRAME_GARBAGED (f);
2148 }
2149 if (!f->current_matrix->nrows || !f->current_matrix->rows)
2150 {
2151 adjust_glyph_matrix (NULL, f->current_matrix, 0, 0, matrix_dim);
2152 SET_FRAME_GARBAGED (f);
2153 }
2154 }
2155 }
2156
2157
2158
2159
2160
2161 static void
2162 adjust_frame_glyphs_for_window_redisplay (struct frame *f)
2163 {
2164 eassert (FRAME_WINDOW_P (f) && FRAME_LIVE_P (f));
2165
2166
2167 allocate_matrices_for_window_redisplay (XWINDOW (FRAME_ROOT_WINDOW (f)));
2168
2169 #if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
2170
2171
2172 {
2173
2174 struct window *w;
2175 if (NILP (f->menu_bar_window))
2176 {
2177 Lisp_Object frame;
2178 fset_menu_bar_window (f, make_window ());
2179 w = XWINDOW (f->menu_bar_window);
2180 XSETFRAME (frame, f);
2181 wset_frame (w, frame);
2182 w->pseudo_window_p = 1;
2183 }
2184 else
2185 w = XWINDOW (f->menu_bar_window);
2186
2187
2188
2189 w->pixel_left = 0;
2190 w->left_col = 0;
2191 w->pixel_top = 0;
2192 w->top_line = 0;
2193 w->pixel_width = (FRAME_PIXEL_WIDTH (f)
2194 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
2195 w->total_cols = FRAME_TOTAL_COLS (f);
2196 w->pixel_height = FRAME_MENU_BAR_HEIGHT (f);
2197 w->total_lines = FRAME_MENU_BAR_LINES (f);
2198 allocate_matrices_for_window_redisplay (w);
2199 }
2200 #endif
2201
2202 #if defined (HAVE_WINDOW_SYSTEM)
2203 {
2204
2205
2206 struct window *w;
2207 if (NILP (f->tab_bar_window))
2208 {
2209 Lisp_Object frame;
2210 fset_tab_bar_window (f, make_window ());
2211 w = XWINDOW (f->tab_bar_window);
2212 XSETFRAME (frame, f);
2213 wset_frame (w, frame);
2214 w->pseudo_window_p = 1;
2215 }
2216 else
2217 w = XWINDOW (f->tab_bar_window);
2218
2219 w->pixel_left = 0;
2220 w->left_col = 0;
2221
2222
2223
2224
2225 w->pixel_top = (FRAME_MENU_BAR_HEIGHT (f)
2226 + (!NILP (Vtab_bar_position)
2227 ? FRAME_TOOL_BAR_TOP_HEIGHT (f) : 0));
2228 w->top_line = (FRAME_MENU_BAR_LINES (f)
2229 + (!NILP (Vtab_bar_position)
2230 ? FRAME_TOOL_BAR_TOP_LINES (f) : 0));
2231 w->total_cols = FRAME_TOTAL_COLS (f);
2232 w->pixel_width = (FRAME_PIXEL_WIDTH (f)
2233 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
2234 w->total_lines = FRAME_TAB_BAR_LINES (f);
2235 w->pixel_height = FRAME_TAB_BAR_HEIGHT (f);
2236 allocate_matrices_for_window_redisplay (w);
2237 }
2238 #endif
2239
2240 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_TOOL_BAR)
2241 {
2242
2243
2244 struct window *w;
2245 if (NILP (f->tool_bar_window))
2246 {
2247 Lisp_Object frame;
2248 fset_tool_bar_window (f, make_window ());
2249 w = XWINDOW (f->tool_bar_window);
2250 XSETFRAME (frame, f);
2251 wset_frame (w, frame);
2252 w->pseudo_window_p = 1;
2253 }
2254 else
2255 w = XWINDOW (f->tool_bar_window);
2256
2257 w->pixel_left = 0;
2258 w->left_col = 0;
2259
2260
2261
2262
2263 if (EQ (FRAME_TOOL_BAR_POSITION (f), Qbottom))
2264 {
2265 w->pixel_top = (FRAME_PIXEL_HEIGHT (f)
2266 - FRAME_TOOL_BAR_HEIGHT (f));
2267 w->top_line = (FRAME_LINES (f)
2268 - FRAME_TOOL_BAR_LINES (f));
2269 }
2270 else
2271 {
2272
2273
2274 w->pixel_top = (FRAME_MENU_BAR_HEIGHT (f)
2275 + (NILP (Vtab_bar_position)
2276 ? FRAME_TAB_BAR_HEIGHT (f) : 0));
2277 w->top_line = (FRAME_MENU_BAR_LINES (f)
2278 + (NILP (Vtab_bar_position)
2279 ? FRAME_TAB_BAR_LINES (f) : 0));
2280 }
2281
2282 w->total_cols = FRAME_TOTAL_COLS (f);
2283 w->pixel_width = (FRAME_PIXEL_WIDTH (f)
2284 - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
2285 w->total_lines = FRAME_TOOL_BAR_LINES (f);
2286 w->pixel_height = FRAME_TOOL_BAR_HEIGHT (f);
2287 allocate_matrices_for_window_redisplay (w);
2288 }
2289 #endif
2290 }
2291
2292
2293
2294
2295 static void
2296 adjust_decode_mode_spec_buffer (struct frame *f)
2297 {
2298 int frame_message_buf_size = FRAME_MESSAGE_BUF_SIZE (f);
2299
2300 eassert (frame_message_buf_size >= 0);
2301 f->decode_mode_spec_buffer = xrealloc (f->decode_mode_spec_buffer,
2302 frame_message_buf_size + 1);
2303 }
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316 void
2317 free_glyphs (struct frame *f)
2318 {
2319 if (f && f->glyphs_initialized_p)
2320 {
2321
2322
2323 block_input ();
2324 f->glyphs_initialized_p = false;
2325
2326
2327 if (!NILP (f->root_window))
2328 free_window_matrices (XWINDOW (f->root_window));
2329
2330 #if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
2331
2332
2333 if (!NILP (f->menu_bar_window))
2334 {
2335 struct window *w = XWINDOW (f->menu_bar_window);
2336 free_glyph_matrix (w->desired_matrix);
2337 free_glyph_matrix (w->current_matrix);
2338 w->desired_matrix = w->current_matrix = NULL;
2339 fset_menu_bar_window (f, Qnil);
2340 }
2341 #endif
2342
2343 #if defined (HAVE_WINDOW_SYSTEM)
2344
2345 if (!NILP (f->tab_bar_window))
2346 {
2347 struct window *w = XWINDOW (f->tab_bar_window);
2348 free_glyph_matrix (w->desired_matrix);
2349 free_glyph_matrix (w->current_matrix);
2350 w->desired_matrix = w->current_matrix = NULL;
2351 fset_tab_bar_window (f, Qnil);
2352 }
2353 #endif
2354
2355 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_TOOL_BAR)
2356
2357 if (!NILP (f->tool_bar_window))
2358 {
2359 struct window *w = XWINDOW (f->tool_bar_window);
2360 free_glyph_matrix (w->desired_matrix);
2361 free_glyph_matrix (w->current_matrix);
2362 w->desired_matrix = w->current_matrix = NULL;
2363 fset_tool_bar_window (f, Qnil);
2364 }
2365 #endif
2366
2367
2368
2369 if (f->desired_matrix)
2370 {
2371 free_glyph_matrix (f->desired_matrix);
2372 free_glyph_matrix (f->current_matrix);
2373 f->desired_matrix = f->current_matrix = NULL;
2374 }
2375
2376
2377 if (f->desired_pool)
2378 {
2379 free_glyph_pool (f->desired_pool);
2380 free_glyph_pool (f->current_pool);
2381 f->desired_pool = f->current_pool = NULL;
2382 }
2383
2384 unblock_input ();
2385 }
2386 }
2387
2388
2389
2390
2391
2392
2393 void
2394 free_window_matrices (struct window *w)
2395 {
2396 while (w)
2397 {
2398 if (WINDOWP (w->contents))
2399 free_window_matrices (XWINDOW (w->contents));
2400 else
2401 {
2402
2403
2404
2405 free_glyph_matrix (w->current_matrix);
2406 free_glyph_matrix (w->desired_matrix);
2407 w->current_matrix = w->desired_matrix = NULL;
2408 }
2409
2410
2411 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2412 }
2413 }
2414
2415
2416
2417
2418
2419
2420
2421 void
2422 check_glyph_memory (void)
2423 {
2424 Lisp_Object tail, frame;
2425
2426
2427 FOR_EACH_FRAME (tail, frame)
2428 free_glyphs (XFRAME (frame));
2429
2430 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2431
2432 eassert (glyph_matrix_count == 0);
2433 eassert (glyph_pool_count == 0);
2434 #endif
2435 }
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505 static void
2506 build_frame_matrix (struct frame *f)
2507 {
2508 int i;
2509
2510
2511 eassert (!FRAME_WINDOW_P (f));
2512
2513
2514
2515 for (i = FRAME_TOP_MARGIN (f); i < f->desired_matrix->nrows; ++i)
2516 clear_glyph_row (MATRIX_ROW (f->desired_matrix, i));
2517
2518
2519 build_frame_matrix_from_window_tree (f->desired_matrix,
2520 XWINDOW (FRAME_ROOT_WINDOW (f)));
2521 }
2522
2523
2524
2525
2526
2527 static void
2528 build_frame_matrix_from_window_tree (struct glyph_matrix *matrix, struct window *w)
2529 {
2530 while (w)
2531 {
2532 if (WINDOWP (w->contents))
2533 build_frame_matrix_from_window_tree (matrix, XWINDOW (w->contents));
2534 else
2535 build_frame_matrix_from_leaf_window (matrix, w);
2536
2537 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2538 }
2539 }
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553 static void
2554 build_frame_matrix_from_leaf_window (struct glyph_matrix *frame_matrix, struct window *w)
2555 {
2556 struct glyph_matrix *window_matrix;
2557 int window_y, frame_y;
2558
2559 GLYPH right_border_glyph;
2560
2561 SET_GLYPH_FROM_CHAR (right_border_glyph, 0);
2562
2563
2564 if (w->must_be_updated_p)
2565 {
2566 window_matrix = w->desired_matrix;
2567
2568
2569 if (!WINDOW_RIGHTMOST_P (w))
2570 {
2571 struct Lisp_Char_Table *dp = window_display_table (w);
2572 Lisp_Object gc;
2573
2574 SET_GLYPH_FROM_CHAR (right_border_glyph, '|');
2575 if (dp
2576 && (gc = DISP_BORDER_GLYPH (dp), GLYPH_CODE_P (gc)))
2577 {
2578 SET_GLYPH_FROM_GLYPH_CODE (right_border_glyph, gc);
2579 spec_glyph_lookup_face (w, &right_border_glyph);
2580 }
2581
2582 if (GLYPH_FACE (right_border_glyph) <= 0)
2583 SET_GLYPH_FACE (right_border_glyph, VERTICAL_BORDER_FACE_ID);
2584 }
2585 }
2586 else
2587 window_matrix = w->current_matrix;
2588
2589
2590
2591 window_y = 0;
2592 frame_y = window_matrix->matrix_y;
2593 while (window_y < window_matrix->nrows)
2594 {
2595 struct glyph_row *frame_row = frame_matrix->rows + frame_y;
2596 struct glyph_row *window_row = window_matrix->rows + window_y;
2597 bool current_row_p = window_matrix == w->current_matrix;
2598
2599
2600
2601 fill_up_frame_row_with_spaces (frame_row, window_matrix->matrix_x);
2602
2603
2604 fill_up_glyph_row_with_spaces (window_row);
2605
2606
2607
2608
2609 if (window_matrix == w->desired_matrix
2610 && !window_row->enabled_p)
2611 {
2612 window_row = w->current_matrix->rows + window_y;
2613 current_row_p = 1;
2614 }
2615
2616 if (current_row_p)
2617 {
2618
2619 memcpy (frame_row->glyphs[TEXT_AREA] + window_matrix->matrix_x,
2620 window_row->glyphs[0],
2621 window_matrix->matrix_w * sizeof (struct glyph));
2622 }
2623 else
2624 {
2625 eassert (window_row->enabled_p);
2626
2627
2628
2629 frame_row->enabled_p = true;
2630
2631
2632
2633 if (GLYPH_CHAR (right_border_glyph) != 0)
2634 {
2635 struct glyph *border = window_row->glyphs[LAST_AREA] - 1;
2636
2637
2638 eassert (border->type == CHAR_GLYPH);
2639 border->type = CHAR_GLYPH;
2640 SET_CHAR_GLYPH_FROM_GLYPH (*border, right_border_glyph);
2641 }
2642
2643 #ifdef GLYPH_DEBUG
2644
2645
2646 eassert (glyph_row_slice_p (window_row, frame_row));
2647
2648
2649
2650
2651 strcpy (w->current_matrix->method, w->desired_matrix->method);
2652 add_window_display_history (w, w->current_matrix->method, 0);
2653 #endif
2654 }
2655
2656
2657
2658
2659 frame_row->used[TEXT_AREA]
2660 = window_matrix->matrix_x + window_matrix->matrix_w;
2661
2662
2663 ++window_y;
2664 ++frame_y;
2665 }
2666 }
2667
2668
2669
2670
2671
2672
2673 void
2674 spec_glyph_lookup_face (struct window *w, GLYPH *glyph)
2675 {
2676 int lface_id = GLYPH_FACE (*glyph);
2677
2678 if (lface_id > 0)
2679 {
2680 int face_id = merge_faces (w, Qt, lface_id, DEFAULT_FACE_ID);
2681 SET_GLYPH_FACE (*glyph, face_id);
2682 }
2683 }
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701 static void
2702 fill_up_glyph_row_with_spaces (struct glyph_row *row)
2703 {
2704 fill_up_glyph_row_area_with_spaces (row, LEFT_MARGIN_AREA);
2705 fill_up_glyph_row_area_with_spaces (row, TEXT_AREA);
2706 fill_up_glyph_row_area_with_spaces (row, RIGHT_MARGIN_AREA);
2707 }
2708
2709
2710
2711
2712
2713 static void
2714 fill_up_glyph_row_area_with_spaces (struct glyph_row *row, int area)
2715 {
2716 if (row->glyphs[area] < row->glyphs[area + 1])
2717 {
2718 struct glyph *end = row->glyphs[area + 1];
2719 struct glyph *text = row->glyphs[area] + row->used[area];
2720
2721 while (text < end)
2722 *text++ = space_glyph;
2723 row->used[area] = text - row->glyphs[area];
2724 }
2725 }
2726
2727
2728
2729
2730
2731 void
2732 fill_up_frame_row_with_spaces (struct glyph_row *row, int upto)
2733 {
2734 int i = row->used[TEXT_AREA];
2735 struct glyph *glyph = row->glyphs[TEXT_AREA];
2736
2737 while (i < upto)
2738 glyph[i++] = space_glyph;
2739
2740 row->used[TEXT_AREA] = i;
2741 }
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753 static void
2754 set_frame_matrix_frame (struct frame *f)
2755 {
2756 frame_matrix_frame = f;
2757 }
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768 static void
2769 make_current (struct glyph_matrix *desired_matrix,
2770 struct glyph_matrix *current_matrix, int row)
2771 {
2772 struct glyph_row *current_row = MATRIX_ROW (current_matrix, row);
2773 struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, row);
2774 bool mouse_face_p = current_row->mouse_face_p;
2775
2776
2777
2778
2779
2780 if (!desired_row->hash
2781
2782
2783 && !(!desired_row->used[0]
2784 && !desired_row->used[1]
2785 && !desired_row->used[2]))
2786 desired_row->hash = row_hash (desired_row);
2787
2788
2789
2790 assign_row (current_row, desired_row);
2791
2792
2793 current_row->enabled_p = true;
2794 current_row->mouse_face_p = mouse_face_p;
2795
2796
2797
2798 if (frame_matrix_frame)
2799 mirror_make_current (XWINDOW (frame_matrix_frame->root_window), row);
2800 }
2801
2802
2803
2804
2805
2806
2807
2808 static void
2809 mirror_make_current (struct window *w, int frame_row)
2810 {
2811 while (w)
2812 {
2813 if (WINDOWP (w->contents))
2814 mirror_make_current (XWINDOW (w->contents), frame_row);
2815 else
2816 {
2817
2818
2819
2820 int row = frame_row - w->desired_matrix->matrix_y;
2821
2822
2823
2824 if (row >= 0 && row < w->desired_matrix->matrix_h)
2825 {
2826 struct glyph_row *current_row
2827 = MATRIX_ROW (w->current_matrix, row);
2828 struct glyph_row *desired_row
2829 = MATRIX_ROW (w->desired_matrix, row);
2830
2831 if (desired_row->enabled_p)
2832 assign_row (current_row, desired_row);
2833 else
2834 swap_glyph_pointers (desired_row, current_row);
2835 current_row->enabled_p = true;
2836
2837
2838
2839
2840
2841
2842 if (current_row->mode_line_p)
2843 current_row->y = row;
2844 }
2845 }
2846
2847 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2848 }
2849 }
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862 void
2863 mirrored_line_dance (struct glyph_matrix *matrix, int unchanged_at_top, int nlines,
2864 int *copy_from, char *retained_p)
2865 {
2866
2867 struct glyph_row *old_rows;
2868
2869
2870 struct glyph_row *new_rows = MATRIX_ROW (matrix, unchanged_at_top);
2871
2872 int i;
2873
2874
2875 USE_SAFE_ALLOCA;
2876 SAFE_NALLOCA (old_rows, 1, nlines);
2877 memcpy (old_rows, new_rows, nlines * sizeof *old_rows);
2878
2879
2880 for (i = 0; i < nlines; ++i)
2881 {
2882 bool enabled_before_p = new_rows[i].enabled_p;
2883
2884 eassert (i + unchanged_at_top < matrix->nrows);
2885 eassert (unchanged_at_top + copy_from[i] < matrix->nrows);
2886 new_rows[i] = old_rows[copy_from[i]];
2887 new_rows[i].enabled_p = enabled_before_p;
2888
2889
2890 if (!retained_p[copy_from[i]])
2891 new_rows[i].enabled_p = false;
2892 }
2893
2894
2895 if (frame_matrix_frame)
2896 mirror_line_dance (XWINDOW (frame_matrix_frame->root_window),
2897 unchanged_at_top, nlines, copy_from, retained_p);
2898
2899 SAFE_FREE ();
2900 }
2901
2902
2903
2904
2905
2906 static void
2907 sync_window_with_frame_matrix_rows (struct window *w)
2908 {
2909 struct frame *f = XFRAME (w->frame);
2910 struct glyph_row *window_row, *window_row_end, *frame_row;
2911 int left, right, x, width;
2912
2913
2914 eassert (BUFFERP (w->contents));
2915 eassert (!FRAME_WINDOW_P (f));
2916
2917 left = margin_glyphs_to_reserve (w, 1, w->left_margin_cols);
2918 right = margin_glyphs_to_reserve (w, 1, w->right_margin_cols);
2919 x = w->current_matrix->matrix_x;
2920 width = w->current_matrix->matrix_w;
2921
2922 window_row = w->current_matrix->rows;
2923 window_row_end = window_row + w->current_matrix->nrows;
2924 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
2925
2926 for (; window_row < window_row_end; ++window_row, ++frame_row)
2927 {
2928 window_row->glyphs[LEFT_MARGIN_AREA]
2929 = frame_row->glyphs[0] + x;
2930 window_row->glyphs[TEXT_AREA]
2931 = window_row->glyphs[LEFT_MARGIN_AREA] + left;
2932 window_row->glyphs[LAST_AREA]
2933 = window_row->glyphs[LEFT_MARGIN_AREA] + width;
2934 window_row->glyphs[RIGHT_MARGIN_AREA]
2935 = window_row->glyphs[LAST_AREA] - right;
2936 }
2937 }
2938
2939
2940
2941
2942
2943 static struct window *
2944 frame_row_to_window (struct window *w, int row)
2945 {
2946 struct window *found = NULL;
2947
2948 while (w && !found)
2949 {
2950 if (WINDOWP (w->contents))
2951 found = frame_row_to_window (XWINDOW (w->contents), row);
2952 else if (row >= WINDOW_TOP_EDGE_LINE (w)
2953 && row < WINDOW_BOTTOM_EDGE_LINE (w))
2954 found = w;
2955
2956 w = NILP (w->next) ? 0 : XWINDOW (w->next);
2957 }
2958
2959 return found;
2960 }
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974 static void
2975 mirror_line_dance (struct window *w, int unchanged_at_top, int nlines, int *copy_from, char *retained_p)
2976 {
2977 while (w)
2978 {
2979 if (WINDOWP (w->contents))
2980 mirror_line_dance (XWINDOW (w->contents), unchanged_at_top,
2981 nlines, copy_from, retained_p);
2982 else
2983 {
2984
2985
2986 struct glyph_matrix *m = w->current_matrix;
2987 int i;
2988 bool sync_p = 0;
2989 struct glyph_row *old_rows;
2990
2991
2992 USE_SAFE_ALLOCA;
2993 SAFE_NALLOCA (old_rows, 1, m->nrows);
2994 memcpy (old_rows, m->rows, m->nrows * sizeof *old_rows);
2995
2996 for (i = 0; i < nlines; ++i)
2997 {
2998
2999 int frame_to = i + unchanged_at_top;
3000
3001
3002 int frame_from = copy_from[i] + unchanged_at_top;
3003
3004
3005 int window_to = frame_to - m->matrix_y;
3006
3007
3008 int window_from = frame_from - m->matrix_y;
3009
3010
3011 bool from_inside_window_p
3012 = window_from >= 0 && window_from < m->matrix_h;
3013
3014
3015 bool to_inside_window_p
3016 = window_to >= 0 && window_to < m->matrix_h;
3017
3018 if (from_inside_window_p && to_inside_window_p)
3019 {
3020
3021
3022
3023 bool enabled_before_p = m->rows[window_to].enabled_p;
3024 m->rows[window_to] = old_rows[window_from];
3025 m->rows[window_to].enabled_p = enabled_before_p;
3026
3027
3028 if (!retained_p[copy_from[i]])
3029 m->rows[window_to].enabled_p = false;
3030 }
3031 else if (to_inside_window_p)
3032 {
3033
3034
3035 struct frame *f = XFRAME (w->frame);
3036 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
3037 struct window *w2;
3038 struct glyph_matrix *m2;
3039 int m2_from;
3040
3041 w2 = frame_row_to_window (root, frame_from);
3042
3043
3044
3045 if (w2)
3046 {
3047 m2 = w2->current_matrix;
3048 m2_from = frame_from - m2->matrix_y;
3049 copy_row_except_pointers (m->rows + window_to,
3050 m2->rows + m2_from);
3051
3052
3053 if (!retained_p[copy_from[i]])
3054 m->rows[window_to].enabled_p = false;
3055 }
3056 sync_p = 1;
3057 }
3058 else if (from_inside_window_p)
3059 sync_p = 1;
3060 }
3061
3062
3063
3064 if (sync_p)
3065 sync_window_with_frame_matrix_rows (w);
3066
3067
3068 CHECK_MATRIX (m);
3069
3070 SAFE_FREE ();
3071 }
3072
3073
3074 w = NILP (w->next) ? 0 : XWINDOW (w->next);
3075 }
3076 }
3077
3078
3079 #ifdef GLYPH_DEBUG
3080
3081
3082
3083
3084
3085
3086
3087 static void
3088 check_window_matrix_pointers (struct window *w)
3089 {
3090 while (w)
3091 {
3092 if (WINDOWP (w->contents))
3093 check_window_matrix_pointers (XWINDOW (w->contents));
3094 else
3095 {
3096 struct frame *f = XFRAME (w->frame);
3097 check_matrix_pointers (w->desired_matrix, f->desired_matrix);
3098 check_matrix_pointers (w->current_matrix, f->current_matrix);
3099 }
3100
3101 w = NILP (w->next) ? 0 : XWINDOW (w->next);
3102 }
3103 }
3104
3105
3106
3107
3108
3109
3110
3111 static void
3112 check_matrix_pointers (struct glyph_matrix *window_matrix,
3113 struct glyph_matrix *frame_matrix)
3114 {
3115
3116 int i = 0;
3117
3118
3119 int j = window_matrix->matrix_y;
3120
3121
3122
3123
3124 while (i < window_matrix->nrows)
3125 {
3126 if (!glyph_row_slice_p (window_matrix->rows + i,
3127 frame_matrix->rows + j))
3128 emacs_abort ();
3129 ++i, ++j;
3130 }
3131 }
3132
3133 #endif
3134
3135
3136
3137
3138
3139
3140
3141 #ifdef GLYPH_DEBUG
3142
3143
3144
3145
3146 static int
3147 window_to_frame_vpos (struct window *w, int vpos)
3148 {
3149 eassert (!FRAME_WINDOW_P (XFRAME (w->frame)));
3150 eassert (vpos >= 0 && vpos <= w->desired_matrix->nrows);
3151 vpos += WINDOW_TOP_EDGE_LINE (w);
3152 eassert (vpos >= 0 && vpos <= FRAME_TOTAL_LINES (XFRAME (w->frame)));
3153 return vpos;
3154 }
3155
3156
3157
3158
3159
3160 static int
3161 window_to_frame_hpos (struct window *w, int hpos)
3162 {
3163 eassert (!FRAME_WINDOW_P (XFRAME (w->frame)));
3164 hpos += WINDOW_LEFT_EDGE_COL (w);
3165 return hpos;
3166 }
3167
3168 #endif
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178 void
3179 redraw_frame (struct frame *f)
3180 {
3181
3182 eassert (f->glyphs_initialized_p);
3183 update_begin (f);
3184 if (FRAME_MSDOS_P (f))
3185 FRAME_TERMINAL (f)->set_terminal_modes_hook (FRAME_TERMINAL (f));
3186
3187 if (FRAME_WINDOW_P (f))
3188
3189
3190
3191
3192 SET_FRAME_GARBAGED (f);
3193
3194 clear_frame (f);
3195 clear_current_matrices (f);
3196 update_end (f);
3197 fset_redisplay (f);
3198
3199
3200
3201 mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0);
3202 set_window_update_flags (XWINDOW (FRAME_ROOT_WINDOW (f)), true);
3203
3204 f->garbaged = false;
3205 }
3206
3207 DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 0, 1, 0,
3208 doc:
3209 )
3210 (Lisp_Object frame)
3211 {
3212 redraw_frame (decode_live_frame (frame));
3213 return Qnil;
3214 }
3215
3216 DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
3217 doc: )
3218 (void)
3219 {
3220 Lisp_Object tail, frame;
3221
3222 FOR_EACH_FRAME (tail, frame)
3223 if (FRAME_REDISPLAY_P (XFRAME (frame)))
3224 redraw_frame (XFRAME (frame));
3225
3226 return Qnil;
3227 }
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242 bool
3243 update_frame (struct frame *f, bool force_p, bool inhibit_hairy_id_p)
3244 {
3245
3246 bool paused_p;
3247 struct window *root_window = XWINDOW (f->root_window);
3248
3249 if (redisplay_dont_pause)
3250 force_p = true;
3251 else if (!force_p && detect_input_pending_ignore_squeezables ())
3252 {
3253 paused_p = true;
3254 goto do_pause;
3255 }
3256
3257 if (FRAME_WINDOW_P (f))
3258 {
3259
3260
3261
3262
3263 set_frame_matrix_frame (NULL);
3264
3265
3266
3267 update_begin (f);
3268
3269 #if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
3270
3271
3272 if (WINDOWP (f->menu_bar_window))
3273 update_window (XWINDOW (f->menu_bar_window), true);
3274 #endif
3275
3276 #if defined (HAVE_WINDOW_SYSTEM)
3277
3278 if (WINDOWP (f->tab_bar_window))
3279 {
3280 struct window *w = XWINDOW (f->tab_bar_window);
3281
3282
3283 if (w->must_be_updated_p)
3284 {
3285 Lisp_Object tem;
3286
3287 update_window (w, true);
3288 w->must_be_updated_p = false;
3289
3290
3291
3292 tem = f->current_tab_bar_string;
3293 fset_current_tab_bar_string (f, f->desired_tab_bar_string);
3294 fset_desired_tab_bar_string (f, tem);
3295 }
3296 }
3297 #endif
3298
3299 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_TOOL_BAR)
3300
3301 if (WINDOWP (f->tool_bar_window))
3302 {
3303 struct window *w = XWINDOW (f->tool_bar_window);
3304
3305
3306 if (w->must_be_updated_p)
3307 {
3308 Lisp_Object tem;
3309
3310 update_window (w, true);
3311 w->must_be_updated_p = false;
3312
3313
3314
3315 tem = f->current_tool_bar_string;
3316 fset_current_tool_bar_string (f, f->desired_tool_bar_string);
3317 fset_desired_tool_bar_string (f, tem);
3318 }
3319 }
3320 #endif
3321
3322
3323 paused_p = update_window_tree (root_window, force_p);
3324 update_end (f);
3325 }
3326 else
3327 {
3328
3329
3330 set_frame_matrix_frame (f);
3331
3332
3333 build_frame_matrix (f);
3334
3335
3336 if (FRAME_INITIAL_P (f))
3337
3338
3339 paused_p = false;
3340 else
3341 {
3342 update_begin (f);
3343 paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p, 1, false);
3344 update_end (f);
3345 }
3346
3347 if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
3348 {
3349 if (FRAME_TTY (f)->termscript)
3350 fflush (FRAME_TTY (f)->termscript);
3351 if (FRAME_TERMCAP_P (f))
3352 fflush (FRAME_TTY (f)->output);
3353 }
3354
3355
3356 #ifdef GLYPH_DEBUG
3357 check_window_matrix_pointers (root_window);
3358 add_frame_display_history (f, paused_p);
3359 #endif
3360 }
3361
3362 do_pause:
3363
3364 set_window_update_flags (root_window, false);
3365
3366 display_completed = !paused_p;
3367 return paused_p;
3368 }
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380 void
3381 update_frame_with_menu (struct frame *f, int row, int col)
3382 {
3383 struct window *root_window = XWINDOW (f->root_window);
3384 bool paused_p, cursor_at_point_p;
3385
3386 eassert (FRAME_TERMCAP_P (f));
3387
3388
3389
3390 set_frame_matrix_frame (f);
3391
3392
3393 update_begin (f);
3394 cursor_at_point_p = !(row >= 0 && col >= 0);
3395
3396
3397 paused_p = update_frame_1 (f, 1, 1, cursor_at_point_p, true);
3398
3399
3400 if (!cursor_at_point_p)
3401 cursor_to (f, row, col);
3402 update_end (f);
3403
3404 if (FRAME_TTY (f)->termscript)
3405 fflush (FRAME_TTY (f)->termscript);
3406 fflush (FRAME_TTY (f)->output);
3407
3408 #if GLYPH_DEBUG
3409 #if 0
3410
3411
3412
3413 check_window_matrix_pointers (root_window);
3414 #endif
3415 add_frame_display_history (f, paused_p);
3416 #endif
3417
3418
3419 set_window_update_flags (root_window, false);
3420 display_completed = !paused_p;
3421 }
3422
3423
3424
3425
3426
3427
3428 int
3429 update_mouse_position (struct frame *f, int x, int y)
3430 {
3431 previous_help_echo_string = help_echo_string;
3432 help_echo_string = Qnil;
3433
3434 note_mouse_highlight (f, x, y);
3435
3436
3437
3438 if (!NILP (help_echo_string)
3439 || !NILP (previous_help_echo_string))
3440 {
3441 Lisp_Object frame;
3442 XSETFRAME (frame, f);
3443
3444 gen_help_event (help_echo_string, frame, help_echo_window,
3445 help_echo_object, help_echo_pos);
3446 return 1;
3447 }
3448
3449 return 0;
3450 }
3451
3452 DEFUN ("display--update-for-mouse-movement", Fdisplay__update_for_mouse_movement,
3453 Sdisplay__update_for_mouse_movement, 2, 2, 0,
3454 doc:
3455
3456
3457
3458
3459 )
3460 (Lisp_Object mouse_x, Lisp_Object mouse_y)
3461 {
3462 CHECK_FIXNUM (mouse_x);
3463 CHECK_FIXNUM (mouse_y);
3464
3465 update_mouse_position (SELECTED_FRAME (), XFIXNUM (mouse_x),
3466 XFIXNUM (mouse_y));
3467 return Qnil;
3468 }
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478 static bool
3479 update_window_tree (struct window *w, bool force_p)
3480 {
3481 bool paused_p = 0;
3482
3483 while (w && !paused_p)
3484 {
3485 if (WINDOWP (w->contents))
3486 paused_p |= update_window_tree (XWINDOW (w->contents), force_p);
3487 else if (w->must_be_updated_p)
3488 paused_p |= update_window (w, force_p);
3489
3490 w = NILP (w->next) ? 0 : XWINDOW (w->next);
3491 }
3492
3493 return paused_p;
3494 }
3495
3496
3497
3498
3499
3500 void
3501 update_single_window (struct window *w)
3502 {
3503 if (w->must_be_updated_p)
3504 {
3505 struct frame *f = XFRAME (WINDOW_FRAME (w));
3506
3507
3508 set_frame_matrix_frame (NULL);
3509
3510
3511 update_begin (f);
3512 update_window (w, true);
3513 update_end (f);
3514
3515
3516 w->must_be_updated_p = false;
3517 }
3518 }
3519
3520 #ifdef HAVE_WINDOW_SYSTEM
3521
3522
3523
3524
3525 static void
3526 redraw_overlapped_rows (struct window *w, int yb)
3527 {
3528 int i;
3529 struct frame *f = XFRAME (WINDOW_FRAME (w));
3530
3531
3532
3533
3534
3535
3536 for (i = 0; i < w->current_matrix->nrows; ++i)
3537 {
3538 struct glyph_row *row = w->current_matrix->rows + i;
3539
3540 if (!row->enabled_p)
3541 break;
3542 else if (row->mode_line_p)
3543 continue;
3544
3545 if (row->overlapped_p)
3546 {
3547 enum glyph_row_area area;
3548
3549 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
3550 {
3551 output_cursor_to (w, i, 0, row->y,
3552 area == TEXT_AREA ? row->x : 0);
3553 if (row->used[area])
3554 FRAME_RIF (f)->write_glyphs (w, row, row->glyphs[area],
3555 area, row->used[area]);
3556 FRAME_RIF (f)->clear_end_of_line (w, row, area, -1);
3557 }
3558
3559 row->overlapped_p = 0;
3560 }
3561
3562 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
3563 break;
3564 }
3565 }
3566
3567
3568
3569
3570
3571 static void
3572 redraw_overlapping_rows (struct window *w, int yb)
3573 {
3574 int i, bottom_y;
3575 struct glyph_row *row;
3576 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
3577
3578 for (i = 0; i < w->current_matrix->nrows; ++i)
3579 {
3580 row = w->current_matrix->rows + i;
3581
3582 if (!row->enabled_p)
3583 break;
3584 else if (row->mode_line_p)
3585 continue;
3586
3587 bottom_y = MATRIX_ROW_BOTTOM_Y (row);
3588
3589 if (row->overlapping_p)
3590 {
3591 int overlaps = 0;
3592
3593 if (MATRIX_ROW_OVERLAPS_PRED_P (row) && i > 0
3594 && !MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p)
3595 overlaps |= OVERLAPS_PRED;
3596 if (MATRIX_ROW_OVERLAPS_SUCC_P (row) && bottom_y < yb
3597 && !MATRIX_ROW (w->current_matrix, i + 1)->overlapped_p)
3598 overlaps |= OVERLAPS_SUCC;
3599
3600 if (overlaps)
3601 {
3602 if (row->used[LEFT_MARGIN_AREA])
3603 rif->fix_overlapping_area (w, row, LEFT_MARGIN_AREA, overlaps);
3604
3605 if (row->used[TEXT_AREA])
3606 rif->fix_overlapping_area (w, row, TEXT_AREA, overlaps);
3607
3608 if (row->used[RIGHT_MARGIN_AREA])
3609 rif->fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, overlaps);
3610
3611
3612
3613 if (overlaps & OVERLAPS_PRED)
3614 MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p = 1;
3615 if (overlaps & OVERLAPS_SUCC)
3616 MATRIX_ROW (w->current_matrix, i + 1)->overlapped_p = 1;
3617 }
3618 }
3619
3620 if (bottom_y >= yb)
3621 break;
3622 }
3623 }
3624
3625 #endif
3626
3627
3628 #if defined GLYPH_DEBUG && 0
3629
3630
3631
3632
3633 static void
3634 check_current_matrix_flags (struct window *w)
3635 {
3636 bool last_seen_p = 0;
3637 int i, yb = window_text_bottom_y (w);
3638
3639 for (i = 0; i < w->current_matrix->nrows - 1; ++i)
3640 {
3641 struct glyph_row *row = MATRIX_ROW (w->current_matrix, i);
3642 if (!last_seen_p && MATRIX_ROW_BOTTOM_Y (row) >= yb)
3643 last_seen_p = 1;
3644 else if (last_seen_p && row->enabled_p)
3645 emacs_abort ();
3646 }
3647 }
3648
3649 #endif
3650
3651
3652
3653
3654
3655 static bool
3656 update_window (struct window *w, bool force_p)
3657 {
3658 struct glyph_matrix *desired_matrix = w->desired_matrix;
3659 bool paused_p;
3660 int preempt_count = clip_to_bounds (1, baud_rate / 2400 + 1, INT_MAX);
3661 #ifdef HAVE_WINDOW_SYSTEM
3662 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
3663 #endif
3664 #ifdef GLYPH_DEBUG
3665
3666 eassert (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))));
3667 #endif
3668
3669
3670 if (!force_p)
3671 detect_input_pending_ignore_squeezables ();
3672
3673
3674
3675 if (force_p || !input_pending || !NILP (track_mouse))
3676 {
3677 struct glyph_row *row, *end;
3678 struct glyph_row *mode_line_row;
3679 struct glyph_row *tab_line_row;
3680 struct glyph_row *header_line_row;
3681 int yb;
3682 bool changed_p = 0, mouse_face_overwritten_p = 0;
3683 int n_updated = 0;
3684 bool invisible_rows_marked = false;
3685
3686 #ifdef HAVE_WINDOW_SYSTEM
3687 gui_update_window_begin (w);
3688 #endif
3689 yb = window_text_bottom_y (w);
3690 row = MATRIX_ROW (desired_matrix, 0);
3691 end = MATRIX_MODE_LINE_ROW (desired_matrix);
3692
3693
3694
3695 if (row->mode_line_p && row->tab_line_p)
3696 {
3697 tab_line_row = row;
3698 ++row;
3699 }
3700 else
3701 tab_line_row = NULL;
3702
3703
3704
3705 if (row->mode_line_p)
3706 {
3707 header_line_row = row;
3708 ++row;
3709 }
3710 else
3711 header_line_row = NULL;
3712
3713
3714 mode_line_row = MATRIX_MODE_LINE_ROW (desired_matrix);
3715 if (mode_line_row->mode_line_p && mode_line_row->enabled_p)
3716 {
3717 mode_line_row->y = yb + WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
3718 update_window_line (w, MATRIX_ROW_VPOS (mode_line_row,
3719 desired_matrix),
3720 &mouse_face_overwritten_p);
3721 }
3722
3723
3724
3725
3726 while (row < end && !row->enabled_p)
3727 ++row;
3728
3729
3730 if (row < end && !desired_matrix->no_scrolling_p)
3731 {
3732 int rc = scrolling_window (w, (tab_line_row != NULL ? 1 : 0)
3733 + (header_line_row != NULL ? 1 : 0));
3734 if (rc < 0)
3735 {
3736
3737 paused_p = 0;
3738 goto set_cursor;
3739 }
3740 else if (rc > 0)
3741 {
3742
3743 force_p = 1;
3744 changed_p = 1;
3745 }
3746 }
3747
3748
3749 for (; row < end && (force_p || !input_pending); ++row)
3750
3751
3752 if (row->enabled_p)
3753 {
3754 int vpos = MATRIX_ROW_VPOS (row, desired_matrix);
3755 int i;
3756
3757
3758
3759
3760
3761 if (!force_p && ++n_updated % preempt_count == 0)
3762 detect_input_pending_ignore_squeezables ();
3763 changed_p |= update_window_line (w, vpos,
3764 &mouse_face_overwritten_p);
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
3776 {
3777 for (i = vpos + 1; i < w->current_matrix->nrows - 1; ++i)
3778 SET_MATRIX_ROW_ENABLED_P (w->current_matrix, i, false);
3779 invisible_rows_marked = true;
3780 }
3781 }
3782
3783
3784
3785
3786
3787 if (!window_wants_mode_line (w))
3788 SET_MATRIX_ROW_ENABLED_P (w->current_matrix,
3789 w->current_matrix->nrows - 1, false);
3790
3791
3792 paused_p = row < end;
3793
3794 if (!paused_p && !invisible_rows_marked)
3795 {
3796
3797
3798
3799
3800
3801 int i;
3802 for (i = 0; i < w->current_matrix->nrows - 1; ++i)
3803 {
3804 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, i);
3805 if (current_row->enabled_p
3806 && MATRIX_ROW_BOTTOM_Y (current_row) >= yb)
3807 {
3808 for (++i ; i < w->current_matrix->nrows - 1; ++i)
3809 SET_MATRIX_ROW_ENABLED_P (w->current_matrix, i, false);
3810 }
3811 }
3812 }
3813
3814 set_cursor:
3815
3816
3817
3818
3819 if (tab_line_row && tab_line_row->enabled_p)
3820 {
3821 tab_line_row->y = 0;
3822 update_window_line (w, 0, &mouse_face_overwritten_p);
3823 }
3824
3825
3826
3827
3828 if (header_line_row && header_line_row->enabled_p)
3829 {
3830 header_line_row->y = tab_line_row ? CURRENT_TAB_LINE_HEIGHT (w) : 0;
3831 update_window_line (w, tab_line_row ? 1 : 0, &mouse_face_overwritten_p);
3832 }
3833
3834
3835 if (!paused_p && !w->pseudo_window_p)
3836 {
3837 #ifdef HAVE_WINDOW_SYSTEM
3838 if (changed_p && rif->fix_overlapping_area)
3839 {
3840 redraw_overlapped_rows (w, yb);
3841 redraw_overlapping_rows (w, yb);
3842 }
3843 #endif
3844
3845
3846 set_window_cursor_after_update (w);
3847
3848 #if 0
3849
3850 IF_DEBUG (check_matrix_invariants (w));
3851 #endif
3852 }
3853
3854 #ifdef GLYPH_DEBUG
3855
3856 strcpy (w->current_matrix->method, w->desired_matrix->method);
3857 #endif
3858
3859 #ifdef HAVE_WINDOW_SYSTEM
3860 update_window_fringes (w, 0);
3861
3862
3863
3864
3865
3866 gui_update_window_end (w, !paused_p, mouse_face_overwritten_p);
3867 #endif
3868
3869
3870 if (!paused_p)
3871 w->must_be_updated_p = false;
3872 }
3873 else
3874 paused_p = 1;
3875
3876 #ifdef GLYPH_DEBUG
3877
3878 add_window_display_history (w, w->current_matrix->method, paused_p);
3879 #endif
3880
3881 xwidget_end_redisplay (w, w->current_matrix);
3882 clear_glyph_matrix (desired_matrix);
3883
3884 return paused_p;
3885 }
3886
3887 #ifdef HAVE_WINDOW_SYSTEM
3888
3889
3890
3891 void
3892 gui_update_window_begin (struct window *w)
3893 {
3894 struct frame *f = XFRAME (WINDOW_FRAME (w));
3895 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
3896
3897 block_input ();
3898
3899 if (FRAME_RIF (f)->update_window_begin_hook)
3900 FRAME_RIF (f)->update_window_begin_hook (w);
3901
3902 w->output_cursor = w->cursor;
3903
3904 if (f == hlinfo->mouse_face_mouse_frame)
3905 {
3906
3907 hlinfo->mouse_face_defer = true;
3908
3909
3910
3911 if (FRAME_GARBAGED_P (f))
3912 hlinfo->mouse_face_window = Qnil;
3913 }
3914
3915 unblock_input ();
3916 }
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926 void
3927 gui_update_window_end (struct window *w, bool cursor_on_p,
3928 bool mouse_face_overwritten_p)
3929 {
3930 struct frame *f = XFRAME (WINDOW_FRAME (w));
3931
3932
3933 if (!w->pseudo_window_p)
3934 {
3935 block_input ();
3936
3937 if (cursor_on_p)
3938 display_and_set_cursor (w, true,
3939 w->output_cursor.hpos, w->output_cursor.vpos,
3940 w->output_cursor.x, w->output_cursor.y);
3941
3942 if (cursor_in_mouse_face_p (w) && cursor_on_p)
3943 mouse_face_overwritten_p = 1;
3944
3945 if (draw_window_fringes (w, true))
3946 {
3947 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
3948 gui_draw_right_divider (w);
3949 else
3950 gui_draw_vertical_border (w);
3951 }
3952 unblock_input ();
3953 }
3954
3955
3956
3957 if (mouse_face_overwritten_p)
3958 {
3959 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
3960
3961 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
3962 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
3963 hlinfo->mouse_face_window = Qnil;
3964 }
3965
3966 if (FRAME_RIF (f)->update_window_end_hook)
3967 FRAME_RIF (f)->update_window_end_hook (w,
3968 cursor_on_p,
3969 mouse_face_overwritten_p);
3970 }
3971
3972 #endif
3973
3974
3975
3976
3977 static void
3978 update_marginal_area (struct window *w, struct glyph_row *updated_row,
3979 enum glyph_row_area area, int vpos)
3980 {
3981 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
3982 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
3983
3984
3985
3986
3987 output_cursor_to (w, vpos, 0, desired_row->y, 0);
3988 if (desired_row->used[area])
3989 rif->write_glyphs (w, updated_row, desired_row->glyphs[area],
3990 area, desired_row->used[area]);
3991 rif->clear_end_of_line (w, updated_row, area, -1);
3992 }
3993
3994
3995
3996
3997
3998 static bool
3999 update_text_area (struct window *w, struct glyph_row *updated_row, int vpos,
4000 bool *partial_p)
4001 {
4002 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
4003 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
4004 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
4005 bool changed_p = 0;
4006
4007
4008
4009 if (!current_row->enabled_p
4010 || desired_row->y != current_row->y
4011 || desired_row->ascent != current_row->ascent
4012 || desired_row->phys_ascent != current_row->phys_ascent
4013 || desired_row->phys_height != current_row->phys_height
4014 || desired_row->visible_height != current_row->visible_height
4015 || current_row->overlapped_p
4016
4017
4018
4019
4020
4021
4022
4023
4024 || (current_row->mouse_face_p
4025 && !(current_row->mode_line_p
4026 && (vpos > (w->current_matrix->tab_line_p
4027 && w->current_matrix->header_line_p))))
4028 || current_row->x != desired_row->x)
4029 {
4030 output_cursor_to (w, vpos, 0, desired_row->y, desired_row->x);
4031
4032 if (desired_row->used[TEXT_AREA])
4033 rif->write_glyphs (w, updated_row, desired_row->glyphs[TEXT_AREA],
4034 TEXT_AREA, desired_row->used[TEXT_AREA]);
4035
4036
4037 rif->clear_end_of_line (w, updated_row, TEXT_AREA, -1);
4038 changed_p = 1;
4039
4040
4041
4042
4043
4044
4045
4046
4047 if (vpos == w->phys_cursor.vpos)
4048 w->phys_cursor_on_p = 0;
4049 }
4050 else
4051 {
4052 int stop, i, x;
4053 struct glyph *current_glyph = current_row->glyphs[TEXT_AREA];
4054 struct glyph *desired_glyph = desired_row->glyphs[TEXT_AREA];
4055 bool overlapping_glyphs_p = current_row->contains_overlapping_glyphs_p;
4056 int desired_stop_pos = desired_row->used[TEXT_AREA];
4057 bool abort_skipping = 0;
4058
4059
4060
4061
4062
4063 if (MATRIX_ROW_EXTENDS_FACE_P (desired_row)
4064 && (desired_stop_pos < current_row->used[TEXT_AREA]
4065 || (desired_stop_pos == current_row->used[TEXT_AREA]
4066 && !MATRIX_ROW_EXTENDS_FACE_P (current_row))))
4067 --desired_stop_pos;
4068
4069 stop = min (current_row->used[TEXT_AREA], desired_stop_pos);
4070 i = 0;
4071 x = desired_row->x;
4072
4073
4074
4075 while (i < stop)
4076 {
4077 bool can_skip_p = !abort_skipping;
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087 if (overlapping_glyphs_p && i > 0)
4088 {
4089 struct glyph *glyph = ¤t_row->glyphs[TEXT_AREA][i - 1];
4090 int left, right;
4091
4092 rif->get_glyph_overhangs (glyph, XFRAME (w->frame),
4093 &left, &right);
4094 can_skip_p = (right == 0 && !abort_skipping);
4095 }
4096
4097 if (can_skip_p)
4098 {
4099 int start_hpos = i;
4100
4101 while (i < stop
4102 && GLYPH_EQUAL_P (desired_glyph, current_glyph))
4103 {
4104 x += desired_glyph->pixel_width;
4105 ++desired_glyph, ++current_glyph, ++i;
4106
4107
4108
4109
4110
4111
4112 *partial_p = true;
4113 }
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123 if (overlapping_glyphs_p
4124 && i > 0
4125 && i < current_row->used[TEXT_AREA]
4126 && (current_row->used[TEXT_AREA]
4127 != desired_row->used[TEXT_AREA]))
4128 {
4129 int left, right;
4130
4131 rif->get_glyph_overhangs (current_glyph,
4132 XFRAME (w->frame),
4133 &left, &right);
4134 while (left > 0 && i > 0)
4135 {
4136 --i, --desired_glyph, --current_glyph;
4137 x -= desired_glyph->pixel_width;
4138 left -= desired_glyph->pixel_width;
4139 }
4140
4141
4142
4143
4144
4145 abort_skipping = (i < start_hpos);
4146 }
4147 }
4148
4149
4150
4151
4152
4153 if (i < desired_row->used[TEXT_AREA])
4154 {
4155 int start_x = x, start_hpos = i;
4156 struct glyph *start = desired_glyph;
4157 int current_x = x;
4158 bool skip_first_p = !can_skip_p;
4159
4160
4161 while (i < stop
4162 && (skip_first_p
4163 || !GLYPH_EQUAL_P (desired_glyph, current_glyph))
4164 && x == current_x)
4165 {
4166 x += desired_glyph->pixel_width;
4167 current_x += current_glyph->pixel_width;
4168 ++desired_glyph, ++current_glyph, ++i;
4169 skip_first_p = 0;
4170 }
4171
4172 if (i == start_hpos || x != current_x)
4173 {
4174 i = start_hpos;
4175 x = start_x;
4176 desired_glyph = start;
4177 break;
4178 }
4179
4180 output_cursor_to (w, vpos, start_hpos, desired_row->y, start_x);
4181 rif->write_glyphs (w, updated_row, start,
4182 TEXT_AREA, i - start_hpos);
4183 changed_p = 1;
4184 *partial_p = true;
4185 }
4186 }
4187
4188
4189
4190 if (!i)
4191 *partial_p = false;
4192
4193
4194 if (i < desired_row->used[TEXT_AREA])
4195 {
4196 output_cursor_to (w, vpos, i, desired_row->y, x);
4197 rif->write_glyphs (w, updated_row, desired_glyph,
4198 TEXT_AREA, desired_row->used[TEXT_AREA] - i);
4199 changed_p = 1;
4200 }
4201
4202
4203 if (MATRIX_ROW_EXTENDS_FACE_P (desired_row))
4204 {
4205
4206
4207
4208
4209 eassert (i < desired_row->used[TEXT_AREA]
4210 || ((desired_row->used[TEXT_AREA]
4211 == current_row->used[TEXT_AREA])
4212 && MATRIX_ROW_EXTENDS_FACE_P (current_row)));
4213 }
4214 else if (MATRIX_ROW_EXTENDS_FACE_P (current_row))
4215 {
4216
4217 if (i >= desired_row->used[TEXT_AREA])
4218 output_cursor_to (w, vpos, i, desired_row->y,
4219 desired_row->pixel_width);
4220 rif->clear_end_of_line (w, updated_row, TEXT_AREA, -1);
4221 changed_p = 1;
4222 }
4223 else if (desired_row->pixel_width < current_row->pixel_width)
4224 {
4225
4226
4227 int xlim;
4228
4229 if (i >= desired_row->used[TEXT_AREA])
4230 output_cursor_to (w, vpos, i, desired_row->y,
4231 desired_row->pixel_width);
4232
4233
4234
4235
4236
4237
4238 if (vpos == w->phys_cursor.vpos
4239 && (desired_row->reversed_p
4240 ? (w->phys_cursor.hpos < 0)
4241 : (w->phys_cursor.hpos >= desired_row->used[TEXT_AREA])))
4242 {
4243 w->phys_cursor_on_p = 0;
4244 xlim = -1;
4245 }
4246 else
4247 xlim = current_row->pixel_width;
4248 rif->clear_end_of_line (w, updated_row, TEXT_AREA, xlim);
4249 changed_p = 1;
4250 }
4251 }
4252
4253 return changed_p;
4254 }
4255
4256
4257
4258
4259 static bool
4260 update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p)
4261 {
4262 struct glyph_row *current_row = MATRIX_ROW (w->current_matrix, vpos);
4263 struct glyph_row *desired_row = MATRIX_ROW (w->desired_matrix, vpos);
4264 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
4265
4266
4267 bool changed_p = 0, partial_p = 0, was_stipple;
4268
4269
4270
4271
4272
4273 if (desired_row->mode_line_p
4274 || desired_row->visible_height > 0)
4275 {
4276 eassert (desired_row->enabled_p);
4277
4278
4279 if (!desired_row->full_width_p && w->left_margin_cols > 0)
4280 {
4281 changed_p = 1;
4282 update_marginal_area (w, desired_row, LEFT_MARGIN_AREA, vpos);
4283
4284
4285
4286
4287 current_row->redraw_fringe_bitmaps_p = 1;
4288 }
4289
4290
4291 if (update_text_area (w, desired_row, vpos, &partial_p))
4292 {
4293 changed_p = 1;
4294 if (current_row->mouse_face_p)
4295 *mouse_face_overwritten_p = 1;
4296 }
4297
4298
4299 if (!desired_row->full_width_p && w->right_margin_cols > 0)
4300 {
4301 changed_p = 1;
4302 update_marginal_area (w, desired_row, RIGHT_MARGIN_AREA, vpos);
4303 }
4304
4305
4306 if (!current_row->enabled_p
4307 || desired_row->y != current_row->y
4308 || desired_row->visible_height != current_row->visible_height
4309 || desired_row->cursor_in_fringe_p != current_row->cursor_in_fringe_p
4310 || desired_row->overlay_arrow_bitmap != current_row->overlay_arrow_bitmap
4311 || current_row->redraw_fringe_bitmaps_p
4312 || desired_row->mode_line_p != current_row->mode_line_p
4313 || desired_row->exact_window_width_line_p != current_row->exact_window_width_line_p
4314 || (MATRIX_ROW_CONTINUATION_LINE_P (desired_row)
4315 != MATRIX_ROW_CONTINUATION_LINE_P (current_row)))
4316 rif->after_update_window_line_hook (w, desired_row);
4317 }
4318
4319
4320 was_stipple = current_row->stipple_p;
4321 make_current (w->desired_matrix, w->current_matrix, vpos);
4322
4323
4324
4325
4326
4327
4328 if (partial_p && was_stipple)
4329 current_row->stipple_p = true;
4330
4331 return changed_p;
4332 }
4333
4334
4335
4336
4337
4338 static void
4339 set_window_cursor_after_update (struct window *w)
4340 {
4341 struct frame *f = XFRAME (w->frame);
4342 int cx, cy, vpos, hpos;
4343
4344
4345 eassert (FRAME_WINDOW_P (f));
4346
4347 if (cursor_in_echo_area
4348 && !NILP (echo_area_buffer[0])
4349
4350
4351 && XWINDOW (minibuf_window) == w
4352 && BASE_EQ (minibuf_window, echo_area_window)
4353
4354
4355 && FRAME_HAS_MINIBUF_P (f)
4356 && BASE_EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
4357 {
4358 cx = cy = vpos = hpos = 0;
4359
4360
4361
4362
4363
4364 struct glyph_row *last_row = NULL;
4365 int yb = window_text_bottom_y (w);
4366
4367 for (struct glyph_row *row = w->current_matrix->rows;
4368 row->enabled_p && (!last_row || MATRIX_ROW_BOTTOM_Y (row) <= yb);
4369 row++)
4370 if (row->used[TEXT_AREA] && row->glyphs[TEXT_AREA][0].charpos >= 0)
4371 last_row = row;
4372
4373 if (last_row)
4374 {
4375 struct glyph *start = last_row->glyphs[TEXT_AREA];
4376 struct glyph *last = start + last_row->used[TEXT_AREA] - 1;
4377
4378 while (last > start && last->charpos < 0)
4379 --last;
4380
4381 for (struct glyph *glyph = start; glyph < last; glyph++)
4382 {
4383 cx += glyph->pixel_width;
4384 hpos++;
4385 }
4386
4387 cy = last_row->y;
4388 vpos = MATRIX_ROW_VPOS (last_row, w->current_matrix);
4389 }
4390 }
4391 else
4392 {
4393 cx = w->cursor.x;
4394 cy = w->cursor.y;
4395 hpos = w->cursor.hpos;
4396 vpos = w->cursor.vpos;
4397 }
4398
4399
4400
4401 hpos = clip_to_bounds (-1, hpos, w->current_matrix->matrix_w - 1);
4402 vpos = clip_to_bounds (0, vpos, w->current_matrix->nrows - 1);
4403 output_cursor_to (w, vpos, hpos, cy, cx);
4404 }
4405
4406
4407
4408
4409
4410 static void
4411 set_window_update_flags (struct window *w, bool on_p)
4412 {
4413 while (w)
4414 {
4415 if (WINDOWP (w->contents))
4416 set_window_update_flags (XWINDOW (w->contents), on_p);
4417 else
4418 w->must_be_updated_p = on_p;
4419
4420 w = NILP (w->next) ? 0 : XWINDOW (w->next);
4421 }
4422 }
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432 struct row_entry
4433 {
4434
4435 int old_uses, new_uses;
4436
4437
4438 int new_line_number;
4439
4440
4441 ptrdiff_t bucket;
4442
4443
4444 struct glyph_row *row;
4445
4446
4447 struct row_entry *next;
4448 };
4449
4450
4451
4452
4453
4454 static struct row_entry *row_entry_pool;
4455 static ptrdiff_t row_entry_pool_size;
4456
4457
4458
4459 static ptrdiff_t row_entry_idx;
4460
4461
4462
4463
4464
4465 static struct row_entry **row_table;
4466 static ptrdiff_t row_table_size;
4467
4468
4469
4470
4471 static struct row_entry **old_lines, **new_lines;
4472 static ptrdiff_t old_lines_size, new_lines_size;
4473
4474
4475
4476 static struct run *run_pool;
4477 static ptrdiff_t runs_size;
4478
4479
4480
4481 static struct run **runs;
4482
4483
4484
4485 static struct row_entry *
4486 add_row_entry (struct glyph_row *row)
4487 {
4488 struct row_entry *entry;
4489 ptrdiff_t i = row->hash % row_table_size;
4490
4491 entry = row_table[i];
4492 eassert (entry || verify_row_hash (row));
4493 while (entry && !row_equal_p (entry->row, row, 1))
4494 entry = entry->next;
4495
4496 if (entry == NULL)
4497 {
4498 entry = row_entry_pool + row_entry_idx++;
4499 entry->row = row;
4500 entry->old_uses = entry->new_uses = 0;
4501 entry->new_line_number = 0;
4502 entry->bucket = i;
4503 entry->next = row_table[i];
4504 row_table[i] = entry;
4505 }
4506
4507 return entry;
4508 }
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536 static int
4537 scrolling_window (struct window *w, int tab_line_p)
4538 {
4539 struct glyph_matrix *desired_matrix = w->desired_matrix;
4540 struct glyph_matrix *current_matrix = w->current_matrix;
4541 int yb = window_text_bottom_y (w);
4542 ptrdiff_t i;
4543 int j, first_old, first_new, last_old, last_new;
4544 int nruns, run_idx;
4545 ptrdiff_t n;
4546 struct row_entry *entry;
4547 struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
4548
4549
4550 for (i = tab_line_p; i < current_matrix->nrows - 1; ++i)
4551 {
4552 struct glyph_row *d = MATRIX_ROW (desired_matrix, i);
4553 struct glyph_row *c = MATRIX_ROW (current_matrix, i);
4554
4555
4556
4557
4558
4559
4560 if (c->stipple_p)
4561 return 0;
4562
4563 if (c->enabled_p
4564 && d->enabled_p
4565 && !d->redraw_fringe_bitmaps_p
4566 && c->y == d->y
4567 && MATRIX_ROW_BOTTOM_Y (c) <= yb
4568 && MATRIX_ROW_BOTTOM_Y (d) <= yb
4569 && row_equal_p (c, d, 1))
4570 {
4571 assign_row (c, d);
4572 d->enabled_p = false;
4573 }
4574 else
4575 break;
4576 }
4577
4578
4579
4580
4581 #ifdef HAVE_NTGUI
4582 if (w32_use_visible_system_caret)
4583 return 0;
4584 #endif
4585
4586
4587 if (! MATRIX_ROW_ENABLED_P (desired_matrix, i))
4588 return -1;
4589
4590 first_old = first_new = i;
4591
4592 while (i < current_matrix->nrows - 1)
4593 {
4594
4595
4596 if (MATRIX_ROW (current_matrix, i)->stipple_p)
4597 return 0;
4598
4599 ++i;
4600 }
4601
4602
4603
4604
4605 i = first_new + 1;
4606 while (i < desired_matrix->nrows - 1)
4607 {
4608 int bottom;
4609
4610 if (! MATRIX_ROW_ENABLED_P (desired_matrix, i))
4611 return 0;
4612 bottom = MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (desired_matrix, i));
4613 if (bottom <= yb)
4614 ++i;
4615 if (bottom >= yb)
4616 break;
4617 }
4618
4619 last_new = i;
4620
4621
4622
4623
4624
4625 i = first_old + 1;
4626 while (i < current_matrix->nrows - 1)
4627 {
4628 int bottom = MATRIX_ROW_BOTTOM_Y (MATRIX_ROW (current_matrix, i));
4629 if (bottom <= yb)
4630 ++i;
4631 if (bottom >= yb)
4632 break;
4633 }
4634
4635 last_old = i;
4636
4637
4638 i = last_new;
4639 j = last_old;
4640 while (i - 1 > first_new
4641 && j - 1 > first_old
4642 && MATRIX_ROW_ENABLED_P (current_matrix, j - 1)
4643 && (MATRIX_ROW (current_matrix, j - 1)->y
4644 == MATRIX_ROW (desired_matrix, i - 1)->y)
4645 && !MATRIX_ROW (desired_matrix, i - 1)->redraw_fringe_bitmaps_p
4646 && row_equal_p (MATRIX_ROW (desired_matrix, i - 1),
4647 MATRIX_ROW (current_matrix, j - 1), 1))
4648 --i, --j;
4649 last_new = i;
4650 last_old = j;
4651
4652
4653 if (last_new == first_new)
4654 return 0;
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666 {
4667 verify (NEXT_ALMOST_PRIME_LIMIT == 11);
4668 enum { next_almost_prime_increment_max = 10 };
4669 ptrdiff_t row_table_max =
4670 (min (PTRDIFF_MAX, SIZE_MAX) / (3 * sizeof *row_table)
4671 - next_almost_prime_increment_max);
4672 ptrdiff_t current_nrows_max = row_table_max - desired_matrix->nrows;
4673 if (current_nrows_max < current_matrix->nrows)
4674 memory_full (SIZE_MAX);
4675 }
4676
4677
4678
4679 if (current_matrix->nrows > old_lines_size)
4680 old_lines = xpalloc (old_lines, &old_lines_size,
4681 current_matrix->nrows - old_lines_size,
4682 INT_MAX, sizeof *old_lines);
4683
4684 if (desired_matrix->nrows > new_lines_size)
4685 new_lines = xpalloc (new_lines, &new_lines_size,
4686 desired_matrix->nrows - new_lines_size,
4687 INT_MAX, sizeof *new_lines);
4688
4689 n = desired_matrix->nrows;
4690 n += current_matrix->nrows;
4691 if (row_table_size < 3 * n)
4692 {
4693 ptrdiff_t size = next_almost_prime (3 * n);
4694 row_table = xnrealloc (row_table, size, sizeof *row_table);
4695 row_table_size = size;
4696 memset (row_table, 0, size * sizeof *row_table);
4697 }
4698
4699 if (n > row_entry_pool_size)
4700 row_entry_pool = xpalloc (row_entry_pool, &row_entry_pool_size,
4701 n - row_entry_pool_size,
4702 -1, sizeof *row_entry_pool);
4703
4704 if (desired_matrix->nrows > runs_size)
4705 {
4706 runs = xnrealloc (runs, desired_matrix->nrows, sizeof *runs);
4707 run_pool = xnrealloc (run_pool, desired_matrix->nrows, sizeof *run_pool);
4708 runs_size = desired_matrix->nrows;
4709 }
4710
4711 nruns = run_idx = 0;
4712 row_entry_idx = 0;
4713
4714
4715
4716
4717 for (i = first_old; i < last_old; ++i)
4718 {
4719 if (MATRIX_ROW_ENABLED_P (current_matrix, i))
4720 {
4721 entry = add_row_entry (MATRIX_ROW (current_matrix, i));
4722 old_lines[i] = entry;
4723 ++entry->old_uses;
4724 }
4725 else
4726 old_lines[i] = NULL;
4727 }
4728
4729 for (i = first_new; i < last_new; ++i)
4730 {
4731 eassert (MATRIX_ROW_ENABLED_P (desired_matrix, i));
4732 entry = add_row_entry (MATRIX_ROW (desired_matrix, i));
4733 ++entry->new_uses;
4734 entry->new_line_number = i;
4735 new_lines[i] = entry;
4736 }
4737
4738
4739
4740 for (i = first_old; i < last_old;)
4741 if (old_lines[i]
4742 && old_lines[i]->old_uses == 1
4743 && old_lines[i]->new_uses == 1)
4744 {
4745 int p, q;
4746 int new_line = old_lines[i]->new_line_number;
4747 struct run *run = run_pool + run_idx++;
4748
4749
4750 run->current_vpos = i;
4751 run->current_y = MATRIX_ROW (current_matrix, i)->y;
4752 run->desired_vpos = new_line;
4753 run->desired_y = MATRIX_ROW (desired_matrix, new_line)->y;
4754 run->nrows = 1;
4755 run->height = MATRIX_ROW (current_matrix, i)->height;
4756
4757
4758 p = i - 1;
4759 q = new_line - 1;
4760 while (p > first_old
4761 && q > first_new
4762 && old_lines[p] == new_lines[q])
4763 {
4764 int h = MATRIX_ROW (current_matrix, p)->height;
4765 --run->current_vpos;
4766 --run->desired_vpos;
4767 ++run->nrows;
4768 run->height += h;
4769 run->desired_y -= h;
4770 run->current_y -= h;
4771 --p, --q;
4772 }
4773
4774
4775 p = i + 1;
4776 q = new_line + 1;
4777 while (p < last_old
4778 && q < last_new
4779 && old_lines[p] == new_lines[q])
4780 {
4781 int h = MATRIX_ROW (current_matrix, p)->height;
4782 ++run->nrows;
4783 run->height += h;
4784 ++p, ++q;
4785 }
4786
4787
4788
4789
4790
4791
4792 for (p = 0; p < nruns && runs[p]->height > run->height; ++p)
4793 ;
4794 for (q = nruns; q > p; --q)
4795 runs[q] = runs[q - 1];
4796 runs[p] = run;
4797 ++nruns;
4798
4799 i += run->nrows;
4800 }
4801 else
4802 ++i;
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818 for (i = 0; i < nruns; ++i)
4819 if (runs[i]->nrows > 0)
4820 {
4821 struct run *r = runs[i];
4822
4823
4824 if (r->current_y != r->desired_y)
4825 {
4826 rif->clear_window_mouse_face (w);
4827 rif->scroll_run_hook (w, r);
4828 }
4829
4830
4831
4832 for (j = nruns - 1; j > i; --j)
4833 {
4834 struct run *p = runs[j];
4835 bool truncated_p = 0;
4836
4837 if (p->nrows > 0
4838 && p->desired_y < r->desired_y + r->height
4839 && p->desired_y + p->height > r->desired_y)
4840 {
4841 if (p->desired_y < r->desired_y)
4842 {
4843 p->nrows = r->desired_vpos - p->desired_vpos;
4844 p->height = r->desired_y - p->desired_y;
4845 truncated_p = 1;
4846 }
4847 else
4848 {
4849 int nrows_copied = (r->desired_vpos + r->nrows
4850 - p->desired_vpos);
4851
4852 if (p->nrows <= nrows_copied)
4853 p->nrows = 0;
4854 else
4855 {
4856 int height_copied = (r->desired_y + r->height
4857 - p->desired_y);
4858
4859 p->current_vpos += nrows_copied;
4860 p->desired_vpos += nrows_copied;
4861 p->nrows -= nrows_copied;
4862 p->current_y += height_copied;
4863 p->desired_y += height_copied;
4864 p->height -= height_copied;
4865 truncated_p = 1;
4866 }
4867 }
4868 }
4869
4870 if (r->current_y != r->desired_y
4871
4872
4873
4874
4875
4876
4877
4878 && p->current_y < r->desired_y + r->height
4879 && p->current_y + p->height > r->desired_y)
4880 p->nrows = 0;
4881
4882
4883 if (truncated_p && p->nrows > 0)
4884 {
4885 int k = nruns - 1;
4886
4887 while (runs[k]->nrows == 0 || runs[k]->height < p->height)
4888 k--;
4889 memmove (runs + j, runs + j + 1, (k - j) * sizeof (*runs));
4890 runs[k] = p;
4891 }
4892 }
4893
4894
4895 for (j = 0; j < r->nrows; ++j)
4896 {
4897 struct glyph_row *from, *to;
4898 bool to_overlapped_p;
4899
4900 to = MATRIX_ROW (current_matrix, r->desired_vpos + j);
4901 from = MATRIX_ROW (desired_matrix, r->desired_vpos + j);
4902 to_overlapped_p = to->overlapped_p;
4903 from->redraw_fringe_bitmaps_p = from->fringe_bitmap_periodic_p;
4904 assign_row (to, from);
4905
4906
4907
4908
4909
4910
4911 eassert (to->enabled_p);
4912 from->enabled_p = false;
4913 to->overlapped_p = to_overlapped_p;
4914 }
4915 }
4916
4917
4918 for (i = 0; i < row_entry_idx; ++i)
4919 row_table[row_entry_pool[i].bucket] = NULL;
4920
4921
4922 return nruns > 0;
4923 }
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939 static bool
4940 update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p,
4941 bool set_cursor_p, bool updating_menu_p)
4942 {
4943
4944 struct glyph_matrix *current_matrix = f->current_matrix;
4945 struct glyph_matrix *desired_matrix = f->desired_matrix;
4946 int i;
4947 bool pause_p;
4948 int preempt_count = clip_to_bounds (1, baud_rate / 2400 + 1, INT_MAX);
4949
4950 eassert (current_matrix && desired_matrix);
4951
4952 if (baud_rate != FRAME_COST_BAUD_RATE (f))
4953 calculate_costs (f);
4954
4955 if (!force_p && detect_input_pending_ignore_squeezables ())
4956 {
4957 pause_p = 1;
4958 goto do_pause;
4959 }
4960
4961
4962 if (!FRAME_LINE_INS_DEL_OK (f))
4963 inhibit_id_p = 1;
4964
4965
4966
4967 for (i = 0; i < desired_matrix->nrows; i++)
4968 if (MATRIX_ROW_ENABLED_P (desired_matrix, i))
4969 break;
4970
4971
4972 if (!inhibit_id_p && i < desired_matrix->nrows)
4973 force_p |= scrolling (f);
4974
4975
4976 if (MATRIX_ROW_ENABLED_P (desired_matrix, desired_matrix->nrows - 1))
4977 update_frame_line (f, desired_matrix->nrows - 1, updating_menu_p);
4978
4979
4980 for (i = 0; i < desired_matrix->nrows - 1 && (force_p || !input_pending); i++)
4981 {
4982 if (MATRIX_ROW_ENABLED_P (desired_matrix, i))
4983 {
4984
4985
4986 if (FRAME_TERMCAP_P (f) && FRAME_TTY (f)->output_buffer_size == 0)
4987 {
4988
4989
4990
4991
4992 FILE *display_output = FRAME_TTY (f)->output;
4993 if (display_output)
4994 {
4995 ptrdiff_t outq = __fpending (display_output);
4996 if (outq > 900
4997 || (outq > 20 && ((i - 1) % preempt_count == 0)))
4998 fflush (display_output);
4999 }
5000 }
5001
5002 if (!force_p && (i - 1) % preempt_count == 0)
5003 detect_input_pending_ignore_squeezables ();
5004
5005 update_frame_line (f, i, updating_menu_p);
5006 }
5007 }
5008
5009 pause_p = 0 < i && i < FRAME_TOTAL_LINES (f) - 1;
5010
5011
5012 if (!pause_p && set_cursor_p)
5013 {
5014 if ((cursor_in_echo_area
5015
5016
5017
5018 || (BASE_EQ (minibuf_window, selected_window)
5019 && BASE_EQ (minibuf_window, echo_area_window)
5020 && !NILP (echo_area_buffer[0])))
5021
5022
5023 && FRAME_HAS_MINIBUF_P (f)
5024 && BASE_EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
5025 {
5026 int top = WINDOW_TOP_EDGE_LINE (XWINDOW (FRAME_MINIBUF_WINDOW (f)));
5027 int col;
5028
5029
5030
5031
5032 int row = FRAME_TOTAL_LINES (f);
5033 do
5034 {
5035 row--;
5036 col = 0;
5037
5038 if (MATRIX_ROW_ENABLED_P (current_matrix, row))
5039 {
5040
5041
5042 struct glyph_row *r = MATRIX_ROW (current_matrix, row);
5043 struct glyph *start = r->glyphs[TEXT_AREA];
5044
5045 col = r->used[TEXT_AREA];
5046 while (0 < col && start[col - 1].charpos < 0)
5047 col--;
5048 }
5049 }
5050 while (row > top && col == 0);
5051
5052
5053 if (col > 0)
5054 col--;
5055
5056
5057 if (col >= FRAME_CURSOR_X_LIMIT (f))
5058 {
5059
5060 if (row < FRAME_TOTAL_LINES (f) - 1)
5061 {
5062 col = FRAME_LEFT_SCROLL_BAR_COLS (f);
5063 row++;
5064 }
5065
5066 else
5067 col = FRAME_CURSOR_X_LIMIT (f) - 1;
5068 }
5069
5070 cursor_to (f, row, col);
5071 }
5072 else
5073 {
5074
5075
5076 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
5077 if (w->cursor.vpos >= 0
5078
5079
5080
5081
5082
5083 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
5084 {
5085 int x = WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos);
5086 int y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
5087
5088 x += max (0, w->left_margin_cols);
5089 cursor_to (f, y, x);
5090 }
5091 }
5092 }
5093
5094 do_pause:
5095
5096 clear_desired_matrices (f);
5097 return pause_p;
5098 }
5099
5100
5101
5102
5103 static bool
5104 scrolling (struct frame *frame)
5105 {
5106
5107
5108
5109 #ifndef HAVE_ANDROID
5110 int unchanged_at_top, unchanged_at_bottom;
5111 int window_size;
5112 int changed_lines;
5113 int i;
5114 int height = FRAME_TOTAL_LINES (frame);
5115 int free_at_end_vpos = height;
5116 struct glyph_matrix *current_matrix = frame->current_matrix;
5117 struct glyph_matrix *desired_matrix = frame->desired_matrix;
5118 verify (sizeof (int) <= sizeof (unsigned));
5119 verify (alignof (unsigned) % alignof (int) == 0);
5120 unsigned *old_hash;
5121 USE_SAFE_ALLOCA;
5122 SAFE_NALLOCA (old_hash, 4, height);
5123 unsigned *new_hash = old_hash + height;
5124 int *draw_cost = (int *) (new_hash + height);
5125 int *old_draw_cost = draw_cost + height;
5126 eassert (current_matrix);
5127
5128
5129
5130
5131 changed_lines = 0;
5132 unchanged_at_top = 0;
5133 unchanged_at_bottom = height;
5134 for (i = 0; i < height; i++)
5135 {
5136
5137 if (!MATRIX_ROW_ENABLED_P (current_matrix, i))
5138 {
5139 SAFE_FREE ();
5140 return false;
5141 }
5142 old_hash[i] = line_hash_code (frame, MATRIX_ROW (current_matrix, i));
5143 if (! MATRIX_ROW_ENABLED_P (desired_matrix, i))
5144 {
5145
5146 new_hash[i] = old_hash[i];
5147 draw_cost[i] = SCROLL_INFINITY;
5148 }
5149 else
5150 {
5151 new_hash[i] = line_hash_code (frame, MATRIX_ROW (desired_matrix, i));
5152 draw_cost[i] = line_draw_cost (frame, desired_matrix, i);
5153 }
5154
5155 if (old_hash[i] != new_hash[i])
5156 {
5157 changed_lines++;
5158 unchanged_at_bottom = height - i - 1;
5159 }
5160 else if (i == unchanged_at_top)
5161 unchanged_at_top++;
5162 old_draw_cost[i] = line_draw_cost (frame, current_matrix, i);
5163 }
5164
5165
5166 if ((!FRAME_SCROLL_REGION_OK (frame)
5167 && changed_lines < baud_rate / 2400)
5168 || unchanged_at_bottom == height)
5169 {
5170 SAFE_FREE ();
5171 return true;
5172 }
5173
5174 window_size = (height - unchanged_at_top
5175 - unchanged_at_bottom);
5176
5177 if (FRAME_SCROLL_REGION_OK (frame))
5178 free_at_end_vpos -= unchanged_at_bottom;
5179 else if (FRAME_MEMORY_BELOW_FRAME (frame))
5180 free_at_end_vpos = -1;
5181
5182
5183
5184
5185 if ((FRAME_SCROLL_REGION_OK (frame)
5186 || window_size < 18 || baud_rate <= 2400
5187 || (window_size
5188 < 10 * scrolling_max_lines_saved (unchanged_at_top,
5189 height - unchanged_at_bottom,
5190 old_hash, new_hash, draw_cost)))
5191 && 2 <= window_size)
5192 scrolling_1 (frame, window_size, unchanged_at_top, unchanged_at_bottom,
5193 draw_cost + unchanged_at_top - 1,
5194 old_draw_cost + unchanged_at_top - 1,
5195 old_hash + unchanged_at_top - 1,
5196 new_hash + unchanged_at_top - 1,
5197 free_at_end_vpos - unchanged_at_top);
5198
5199 SAFE_FREE ();
5200 #endif
5201 return false;
5202 }
5203
5204
5205
5206
5207
5208 static int
5209 count_blanks (struct glyph *r, int len)
5210 {
5211 int i;
5212
5213 for (i = 0; i < len; ++i)
5214 if (!CHAR_GLYPH_SPACE_P (r[i]))
5215 break;
5216
5217 return i;
5218 }
5219
5220
5221
5222
5223
5224
5225 static int
5226 count_match (struct glyph *str1, struct glyph *end1, struct glyph *str2, struct glyph *end2)
5227 {
5228 struct glyph *p1 = str1;
5229 struct glyph *p2 = str2;
5230
5231 while (p1 < end1
5232 && p2 < end2
5233 && GLYPH_CHAR_AND_FACE_EQUAL_P (p1, p2))
5234 ++p1, ++p2;
5235
5236 return p1 - str1;
5237 }
5238
5239
5240
5241
5242 #ifndef HAVE_ANDROID
5243 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_TOTAL_COLS ((f))])
5244 #endif
5245
5246
5247
5248
5249 static void
5250 update_frame_line (struct frame *f, int vpos, bool updating_menu_p)
5251 {
5252 struct glyph *obody, *nbody, *op1, *op2, *np1, *nend;
5253 int tem;
5254 int osp, nsp, begmatch, endmatch, olen, nlen;
5255 struct glyph_matrix *current_matrix = f->current_matrix;
5256 struct glyph_matrix *desired_matrix = f->desired_matrix;
5257 struct glyph_row *current_row = MATRIX_ROW (current_matrix, vpos);
5258 struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, vpos);
5259 bool must_write_whole_line_p;
5260 bool write_spaces_p = FRAME_MUST_WRITE_SPACES (f);
5261 bool colored_spaces_p = (FACE_FROM_ID (f, DEFAULT_FACE_ID)->background
5262 != FACE_TTY_DEFAULT_BG_COLOR);
5263
5264 if (colored_spaces_p)
5265 write_spaces_p = 1;
5266
5267
5268
5269 must_write_whole_line_p = !current_row->enabled_p;
5270 if (must_write_whole_line_p)
5271 {
5272 obody = 0;
5273 olen = 0;
5274 }
5275 else
5276 {
5277 obody = MATRIX_ROW_GLYPH_START (current_matrix, vpos);
5278 olen = current_row->used[TEXT_AREA];
5279
5280
5281 if (!write_spaces_p)
5282 while (olen > 0 && CHAR_GLYPH_SPACE_P (obody[olen-1]))
5283 olen--;
5284 }
5285
5286 current_row->enabled_p = true;
5287 current_row->used[TEXT_AREA] = desired_row->used[TEXT_AREA];
5288
5289
5290
5291
5292 if (updating_menu_p)
5293 cursor_to (f, 0, 0);
5294
5295
5296 if (!desired_row->enabled_p)
5297 {
5298 nlen = 0;
5299 goto just_erase;
5300 }
5301
5302 nbody = desired_row->glyphs[TEXT_AREA];
5303 nlen = desired_row->used[TEXT_AREA];
5304 nend = nbody + nlen;
5305
5306
5307 if (must_write_whole_line_p)
5308 {
5309
5310 if (!write_spaces_p)
5311 while (nlen > 0 && CHAR_GLYPH_SPACE_P (nbody[nlen - 1]))
5312 --nlen;
5313
5314
5315 if (nlen)
5316 {
5317 cursor_to (f, vpos, 0);
5318 write_glyphs (f, nbody, nlen);
5319 }
5320
5321
5322
5323
5324 if (nlen < FRAME_TOTAL_COLS (f))
5325 {
5326 cursor_to (f, vpos, nlen);
5327 clear_end_of_line (f, FRAME_TOTAL_COLS (f));
5328 }
5329 else
5330
5331
5332 cursor_to (f, vpos, 0);
5333
5334 make_current (desired_matrix, current_matrix, vpos);
5335 return;
5336 }
5337
5338
5339
5340 if (!write_spaces_p)
5341 while (nlen > 0 && CHAR_GLYPH_SPACE_P (nbody[nlen - 1]))
5342 nlen--;
5343
5344
5345 if (!FRAME_CHAR_INS_DEL_OK (f))
5346 {
5347 int i, j;
5348
5349
5350
5351 for (i = 0; i < nlen; i++)
5352 {
5353 if (i >= olen || !GLYPH_EQUAL_P (nbody + i, obody + i))
5354 {
5355
5356 j = i + 1;
5357 while (j < nlen
5358 && (j >= olen
5359 || !GLYPH_EQUAL_P (nbody + j, obody + j)
5360 || CHAR_GLYPH_PADDING_P (nbody[j])))
5361 ++j;
5362
5363
5364 cursor_to (f, vpos, i);
5365 write_glyphs (f, nbody + i, j - i);
5366 i = j - 1;
5367
5368
5369 }
5370 }
5371
5372
5373 if (olen > nlen)
5374 {
5375 cursor_to (f, vpos, nlen);
5376 clear_end_of_line (f, olen);
5377 }
5378
5379
5380 make_current (desired_matrix, current_matrix, vpos);
5381 return;
5382 }
5383
5384
5385
5386
5387 if (!olen)
5388 {
5389
5390
5391 if (write_spaces_p)
5392 nsp = 0;
5393 else
5394 nsp = count_blanks (nbody, nlen);
5395
5396 if (nlen > nsp)
5397 {
5398 cursor_to (f, vpos, nsp);
5399 write_glyphs (f, nbody + nsp, nlen - nsp);
5400 }
5401
5402
5403 make_current (desired_matrix, current_matrix, vpos);
5404 return;
5405 }
5406
5407
5408 osp = count_blanks (obody, olen);
5409 nsp = (colored_spaces_p ? 0 : count_blanks (nbody, nlen));
5410
5411
5412 begmatch = count_match (obody + osp, obody + olen,
5413 nbody + nsp, nbody + nlen);
5414
5415
5416
5417 if (!write_spaces_p && osp + begmatch == olen)
5418 {
5419 np1 = nbody + nsp;
5420 while (np1 + begmatch < nend && CHAR_GLYPH_SPACE_P (np1[begmatch]))
5421 ++begmatch;
5422 }
5423
5424
5425
5426
5427 if (begmatch == 0 && osp != nsp)
5428 osp = nsp = min (osp, nsp);
5429
5430
5431 op1 = obody + olen;
5432 np1 = nbody + nlen;
5433 op2 = op1 + begmatch - min (olen - osp, nlen - nsp);
5434 while (op1 > op2
5435 && GLYPH_EQUAL_P (op1 - 1, np1 - 1))
5436 {
5437 op1--;
5438 np1--;
5439 }
5440 endmatch = obody + olen - op1;
5441
5442
5443
5444
5445
5446 tem = (nlen - nsp) - (olen - osp);
5447 if (endmatch && tem
5448 && (!FRAME_CHAR_INS_DEL_OK (f)
5449 #ifndef HAVE_ANDROID
5450 || endmatch <= char_ins_del_cost (f)[tem]
5451 #endif
5452 ))
5453 endmatch = 0;
5454
5455
5456
5457
5458
5459
5460 if (nsp != osp
5461 && (!FRAME_CHAR_INS_DEL_OK (f)
5462 #ifndef HAVE_ANDROID
5463 || begmatch + endmatch <= char_ins_del_cost (f)[nsp - osp]
5464 #endif
5465 ))
5466 {
5467 begmatch = 0;
5468 endmatch = 0;
5469 osp = nsp = min (osp, nsp);
5470 }
5471
5472
5473
5474
5475 if (osp > nsp)
5476 {
5477 cursor_to (f, vpos, nsp);
5478 delete_glyphs (f, osp - nsp);
5479 }
5480 else if (nsp > osp)
5481 {
5482
5483
5484
5485 if (endmatch && nlen < olen + nsp - osp)
5486 {
5487 cursor_to (f, vpos, nlen - endmatch + osp - nsp);
5488 delete_glyphs (f, olen + nsp - osp - nlen);
5489 olen = nlen - (nsp - osp);
5490 }
5491 cursor_to (f, vpos, osp);
5492 insert_glyphs (f, 0, nsp - osp);
5493 }
5494 olen += nsp - osp;
5495
5496 tem = nsp + begmatch + endmatch;
5497 if (nlen != tem || olen != tem)
5498 {
5499 if (!endmatch || nlen == olen)
5500 {
5501
5502
5503
5504
5505 if (nlen == FRAME_TOTAL_COLS (f))
5506 olen = 0;
5507
5508
5509
5510
5511 if (nlen - tem > 0)
5512 {
5513 cursor_to (f, vpos, nsp + begmatch);
5514 write_glyphs (f, nbody + nsp + begmatch, nlen - tem);
5515 }
5516 }
5517 else if (nlen > olen)
5518 {
5519
5520
5521
5522
5523
5524
5525
5526 int out = olen - tem;
5527 int del;
5528
5529 cursor_to (f, vpos, nsp + begmatch);
5530
5531
5532 while (CHAR_GLYPH_PADDING_P (nbody[nsp + begmatch + out]))
5533 out--;
5534 write_glyphs (f, nbody + nsp + begmatch, out);
5535
5536
5537 del = olen - tem - out;
5538 if (del > 0)
5539 delete_glyphs (f, del);
5540
5541
5542 insert_glyphs (f, nbody + nsp + begmatch + out, nlen - olen + del);
5543 olen = nlen;
5544 }
5545 else if (olen > nlen)
5546 {
5547 cursor_to (f, vpos, nsp + begmatch);
5548 write_glyphs (f, nbody + nsp + begmatch, nlen - tem);
5549 delete_glyphs (f, olen - nlen);
5550 olen = nlen;
5551 }
5552 }
5553
5554 just_erase:
5555
5556 if (olen > nlen)
5557 {
5558 cursor_to (f, vpos, nlen);
5559 clear_end_of_line (f, olen);
5560 }
5561
5562
5563 make_current (desired_matrix, current_matrix, vpos);
5564 }
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585 Lisp_Object
5586 buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *pos, Lisp_Object *object, int *dx, int *dy, int *width, int *height)
5587 {
5588 struct it it;
5589 Lisp_Object old_current_buffer = Fcurrent_buffer ();
5590 struct text_pos startp;
5591 Lisp_Object string;
5592 struct glyph_row *row;
5593 #ifdef HAVE_WINDOW_SYSTEM
5594 struct image *img = 0;
5595 #endif
5596 int x0, x1, to_x, it_vpos;
5597 void *itdata = NULL;
5598
5599
5600
5601 Fset_buffer (w->contents);
5602 itdata = bidi_shelve_cache ();
5603 CLIP_TEXT_POS_FROM_MARKER (startp, w->start);
5604 start_display (&it, w, startp);
5605 x0 = *x;
5606
5607
5608
5609
5610 move_it_to (&it, -1, 0, *y, -1, MOVE_TO_X | MOVE_TO_Y);
5611
5612
5613
5614 to_x = x0;
5615 if (it.bidi_it.paragraph_dir == R2L)
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626 to_x = window_box_width (w, TEXT_AREA) - to_x - 1;
5627
5628
5629
5630 to_x += it.first_visible_x;
5631
5632
5633
5634
5635 if (it.line_wrap == TRUNCATE
5636 && EQ (automatic_hscrolling, Qcurrent_line) && IT_CHARPOS (it) < PT)
5637 {
5638 struct it it2 = it;
5639 void *it2data = bidi_shelve_cache ();
5640 it2.last_visible_x = 1000000;
5641
5642
5643 move_it_in_display_line (&it2, PT, -1, MOVE_TO_POS);
5644 if (IT_CHARPOS (it2) >= PT)
5645 {
5646 to_x += (w->hscroll - w->min_hscroll) * FRAME_COLUMN_WIDTH (it.f);
5647
5648
5649 it.first_visible_x += w->hscroll * FRAME_COLUMN_WIDTH (it.f);
5650 it.last_visible_x += w->hscroll * FRAME_COLUMN_WIDTH (it.f);
5651 }
5652 bidi_unshelve_cache (it2data, 0);
5653 }
5654
5655
5656
5657
5658 move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X);
5659 if (mouse_prefer_closest_glyph)
5660 {
5661 int next_x = it.current_x + it.pixel_width;
5662 int before_dx = to_x - it.current_x;
5663 int after_dx = next_x - to_x;
5664 if (before_dx > after_dx)
5665 move_it_in_display_line (&it, ZV, next_x, MOVE_TO_X);
5666 }
5667
5668 bidi_unshelve_cache (itdata, 0);
5669
5670 Fset_buffer (old_current_buffer);
5671
5672 *dx = to_x - it.current_x;
5673 *dy = *y - it.current_y;
5674
5675 string = w->contents;
5676 if (STRINGP (it.string))
5677 string = it.string;
5678 *pos = it.current;
5679 if (it.what == IT_COMPOSITION
5680 && it.cmp_it.nchars > 1
5681 && it.cmp_it.reversed_p)
5682 {
5683
5684
5685
5686
5687
5688
5689 CHARPOS (pos->pos) -= it.cmp_it.nchars - 1;
5690 if (STRINGP (it.string))
5691 BYTEPOS (pos->pos) = string_char_to_byte (string, CHARPOS (pos->pos));
5692 else
5693 BYTEPOS (pos->pos) = buf_charpos_to_bytepos (XBUFFER (w->contents),
5694 CHARPOS (pos->pos));
5695 }
5696
5697 #ifdef HAVE_WINDOW_SYSTEM
5698 if (it.what == IT_IMAGE)
5699 {
5700
5701
5702
5703
5704
5705 img = IMAGE_OPT_FROM_ID (it.f, it.image_id);
5706 if (img && !NILP (img->spec))
5707 *object = img->spec;
5708 }
5709 #endif
5710
5711
5712
5713
5714
5715 it_vpos = it.vpos + window_wants_header_line (w)
5716 + window_wants_tab_line (w);
5717 if (it_vpos < w->current_matrix->nrows
5718 && (row = MATRIX_ROW (w->current_matrix, it_vpos),
5719 row->enabled_p))
5720 {
5721 if (it.hpos < row->used[TEXT_AREA])
5722 {
5723 struct glyph *glyph = row->glyphs[TEXT_AREA] + it.hpos;
5724 #ifdef HAVE_WINDOW_SYSTEM
5725 if (img)
5726 {
5727 *dy -= row->ascent - glyph->ascent;
5728 *dx += glyph->slice.img.x;
5729 *dy += glyph->slice.img.y;
5730
5731 *width = img->width;
5732 *height = img->height;
5733 }
5734 else
5735 #endif
5736 {
5737 *width = glyph->pixel_width;
5738 *height = glyph->ascent + glyph->descent;
5739 }
5740 }
5741 else
5742 {
5743 *width = 0;
5744 *height = row->height;
5745 }
5746 }
5747 else
5748 {
5749 *width = *height = 0;
5750 }
5751
5752
5753 x1 = max (0, it.current_x + it.pixel_width);
5754 if (to_x > x1)
5755 it.hpos += (to_x - x1) / WINDOW_FRAME_COLUMN_WIDTH (w);
5756
5757 *x = it.hpos;
5758 *y = it.vpos;
5759
5760 return string;
5761 }
5762
5763
5764
5765
5766
5767
5768 Lisp_Object
5769 mode_line_string (struct window *w, enum window_part part,
5770 int *x, int *y, ptrdiff_t *charpos, Lisp_Object *object,
5771 int *dx, int *dy, int *width, int *height)
5772 {
5773 struct glyph_row *row;
5774 struct glyph *glyph, *end;
5775 int x0, y0;
5776 Lisp_Object string = Qnil;
5777
5778 if (part == ON_MODE_LINE)
5779 row = MATRIX_MODE_LINE_ROW (w->current_matrix);
5780 else if (part == ON_TAB_LINE)
5781 row = MATRIX_TAB_LINE_ROW (w->current_matrix);
5782 else
5783 row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
5784 y0 = *y - row->y;
5785 *y = row - MATRIX_FIRST_TEXT_ROW (w->current_matrix);
5786
5787 if (row->mode_line_p && row->enabled_p)
5788 {
5789
5790
5791 glyph = row->glyphs[TEXT_AREA];
5792 end = glyph + row->used[TEXT_AREA];
5793 for (x0 = *x; glyph < end && x0 >= glyph->pixel_width; ++glyph)
5794 x0 -= glyph->pixel_width;
5795 *x = glyph - row->glyphs[TEXT_AREA];
5796 if (glyph < end)
5797 {
5798 string = glyph->object;
5799 *charpos = glyph->charpos;
5800 *width = glyph->pixel_width;
5801 *height = glyph->ascent + glyph->descent;
5802 #ifdef HAVE_WINDOW_SYSTEM
5803 if (glyph->type == IMAGE_GLYPH)
5804 {
5805 struct image *img;
5806 img = IMAGE_OPT_FROM_ID (WINDOW_XFRAME (w), glyph->u.img_id);
5807 if (img != NULL)
5808 *object = img->spec;
5809 y0 -= row->ascent - glyph->ascent;
5810 }
5811 #endif
5812 }
5813 else
5814 {
5815
5816 *x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w);
5817 *width = 0;
5818 *height = row->height;
5819 }
5820 }
5821 else
5822 {
5823 *x = 0;
5824 x0 = 0;
5825 *width = *height = 0;
5826 }
5827
5828 *dx = x0;
5829 *dy = y0;
5830
5831 return string;
5832 }
5833
5834
5835
5836
5837
5838
5839 Lisp_Object
5840 marginal_area_string (struct window *w, enum window_part part,
5841 int *x, int *y, ptrdiff_t *charpos, Lisp_Object *object,
5842 int *dx, int *dy, int *width, int *height)
5843 {
5844 struct glyph_row *row = w->current_matrix->rows;
5845 struct glyph *glyph, *end;
5846 int x0, y0, i, wy = *y;
5847 int area;
5848 Lisp_Object string = Qnil;
5849
5850 if (part == ON_LEFT_MARGIN)
5851 area = LEFT_MARGIN_AREA;
5852 else if (part == ON_RIGHT_MARGIN)
5853 area = RIGHT_MARGIN_AREA;
5854 else
5855 emacs_abort ();
5856
5857 for (i = 0; row->enabled_p && i < w->current_matrix->nrows; ++i, ++row)
5858 if (wy >= row->y && wy < MATRIX_ROW_BOTTOM_Y (row))
5859 break;
5860 y0 = *y - row->y;
5861 *y = row - MATRIX_FIRST_TEXT_ROW (w->current_matrix);
5862
5863 if (row->enabled_p)
5864 {
5865
5866
5867 if (area == RIGHT_MARGIN_AREA)
5868 x0 = ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
5869 ? WINDOW_LEFT_FRINGE_WIDTH (w)
5870 : WINDOW_FRINGES_WIDTH (w))
5871 + window_box_width (w, LEFT_MARGIN_AREA)
5872 + window_box_width (w, TEXT_AREA));
5873 else
5874 x0 = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
5875 ? WINDOW_LEFT_FRINGE_WIDTH (w)
5876 : 0);
5877
5878 glyph = row->glyphs[area];
5879 end = glyph + row->used[area];
5880 for (x0 = *x - x0; glyph < end && x0 >= glyph->pixel_width; ++glyph)
5881 x0 -= glyph->pixel_width;
5882 *x = glyph - row->glyphs[area];
5883 if (glyph < end)
5884 {
5885 string = glyph->object;
5886 *charpos = glyph->charpos;
5887 *width = glyph->pixel_width;
5888 *height = glyph->ascent + glyph->descent;
5889 #ifdef HAVE_WINDOW_SYSTEM
5890 if (glyph->type == IMAGE_GLYPH)
5891 {
5892 struct image *img;
5893 img = IMAGE_OPT_FROM_ID (WINDOW_XFRAME (w), glyph->u.img_id);
5894 if (img != NULL)
5895 *object = img->spec;
5896 y0 -= row->ascent - glyph->ascent;
5897 x0 += glyph->slice.img.x;
5898 y0 += glyph->slice.img.y;
5899 }
5900 #endif
5901 }
5902 else
5903 {
5904
5905 *x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w);
5906 *width = 0;
5907 *height = row->height;
5908 }
5909 }
5910 else
5911 {
5912 x0 = 0;
5913 *x = 0;
5914 *width = *height = 0;
5915 }
5916
5917 *dx = x0;
5918 *dy = y0;
5919
5920 return string;
5921 }
5922
5923
5924
5925
5926
5927
5928 #ifdef SIGWINCH
5929
5930 static void deliver_window_change_signal (int);
5931
5932 static void
5933 handle_window_change_signal (int sig)
5934 {
5935 int width, height;
5936 struct tty_display_info *tty;
5937
5938
5939
5940
5941
5942 for (tty = tty_list; tty; tty = tty->next)
5943 {
5944 if (! tty->term_initted)
5945 continue;
5946
5947
5948
5949 if (!tty->input)
5950 continue;
5951
5952 get_tty_size (fileno (tty->input), &width, &height);
5953
5954 if (width > 5 && height > 2)
5955 {
5956 Lisp_Object tail, frame;
5957
5958 FOR_EACH_FRAME (tail, frame)
5959 {
5960 struct frame *f = XFRAME (frame);
5961
5962 if (FRAME_TERMCAP_P (f) && FRAME_TTY (f) == tty)
5963
5964
5965
5966 change_frame_size (f, width, height, false, true, false);
5967 }
5968 }
5969 }
5970 }
5971
5972 static void
5973 deliver_window_change_signal (int sig)
5974 {
5975 deliver_process_signal (sig, handle_window_change_signal);
5976 }
5977 #endif
5978
5979
5980
5981
5982
5983
5984 void
5985 do_pending_window_change (bool safe)
5986 {
5987 if (redisplaying_p && !safe)
5988 return;
5989
5990 while (delayed_size_change)
5991 {
5992 Lisp_Object tail, frame;
5993
5994 delayed_size_change = false;
5995
5996 FOR_EACH_FRAME (tail, frame)
5997 {
5998 struct frame *f = XFRAME (frame);
5999
6000
6001
6002
6003
6004
6005 if (f->new_size_p && (f->new_height >= 0 || f->new_width >= 0))
6006 change_frame_size (f, f->new_width, f->new_height,
6007 false, false, safe);
6008 }
6009 }
6010 }
6011
6012
6013 static void
6014 change_frame_size_1 (struct frame *f, int new_width, int new_height,
6015 bool pretend, bool delay, bool safe)
6016 {
6017 if (delay || (redisplaying_p && !safe))
6018 {
6019 if (CONSP (frame_size_history)
6020 && ((new_width != f->new_width
6021 || new_height != f->new_height
6022 || new_width != FRAME_PIXEL_WIDTH (f)
6023 || new_height != FRAME_PIXEL_HEIGHT (f))))
6024 frame_size_history_extra
6025 (f, build_string ("change_frame_size_1, delayed"),
6026 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
6027 new_width, new_height, f->new_width, f->new_height);
6028
6029
6030 f->new_width = new_width;
6031 f->new_height = new_height;
6032 f->new_size_p = true;
6033 delayed_size_change = true;
6034 }
6035 else
6036 {
6037
6038
6039
6040 f->new_height = -1;
6041 f->new_width = -1;
6042 f->new_size_p = false;
6043
6044
6045
6046 adjust_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, new_width),
6047 FRAME_PIXEL_TO_TEXT_HEIGHT (f, new_height), 5,
6048 pretend, Qchange_frame_size);
6049 }
6050 }
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062 void
6063 change_frame_size (struct frame *f, int new_width, int new_height,
6064 bool pretend, bool delay, bool safe)
6065 {
6066 Lisp_Object tail, frame;
6067
6068 if (FRAME_MSDOS_P (f))
6069 {
6070
6071
6072
6073 FOR_EACH_FRAME (tail, frame)
6074 if (!FRAME_WINDOW_P (XFRAME (frame)))
6075 change_frame_size_1 (XFRAME (frame), new_width, new_height,
6076 pretend, delay, safe);
6077 }
6078 else
6079 change_frame_size_1 (f, new_width, new_height, pretend, delay, safe);
6080 }
6081
6082
6083
6084
6085
6086 DEFUN ("open-termscript", Fopen_termscript, Sopen_termscript,
6087 1, 1, "FOpen termscript file: ",
6088 doc:
6089 )
6090 (Lisp_Object file)
6091 {
6092 struct tty_display_info *tty;
6093
6094 if (! FRAME_TERMCAP_P (SELECTED_FRAME ())
6095 && ! FRAME_MSDOS_P (SELECTED_FRAME ()))
6096 error ("Current frame is not on a tty device");
6097
6098 tty = CURTTY ();
6099
6100 if (tty->termscript != 0)
6101 {
6102 block_input ();
6103 emacs_fclose (tty->termscript);
6104 tty->termscript = 0;
6105 unblock_input ();
6106 }
6107
6108 if (! NILP (file))
6109 {
6110 file = Fexpand_file_name (file, Qnil);
6111 tty->termscript = emacs_fopen (SSDATA (file), "w");
6112 if (tty->termscript == 0)
6113 report_file_error ("Opening termscript", file);
6114 }
6115 return Qnil;
6116 }
6117
6118
6119 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal,
6120 Ssend_string_to_terminal, 1, 2, 0,
6121 doc:
6122
6123
6124
6125
6126
6127 )
6128 (Lisp_Object string, Lisp_Object terminal)
6129 {
6130 struct terminal *t = decode_live_terminal (terminal);
6131 FILE *out;
6132
6133
6134 CHECK_STRING (string);
6135 block_input ();
6136
6137 if (t->type == output_initial)
6138 out = stdout;
6139 else if (t->type != output_termcap && t->type != output_msdos_raw)
6140 error ("Device %d is not a termcap terminal device", t->id);
6141 else
6142 {
6143 struct tty_display_info *tty = t->display_info.tty;
6144
6145 if (! tty->output)
6146 error ("Terminal is currently suspended");
6147
6148 if (tty->termscript)
6149 {
6150 fwrite (SDATA (string), 1, SBYTES (string), tty->termscript);
6151 fflush (tty->termscript);
6152 }
6153 out = tty->output;
6154 }
6155
6156
6157 unrequest_sigio ();
6158 fwrite (SDATA (string), 1, SBYTES (string), out);
6159 fflush (out);
6160 request_sigio ();
6161 unblock_input ();
6162 return Qnil;
6163 }
6164
6165
6166 DEFUN ("ding", Fding, Sding, 0, 1, 0,
6167 doc:
6168
6169 )
6170 (Lisp_Object arg)
6171 {
6172 if (!NILP (arg))
6173 {
6174 if (noninteractive)
6175 putchar (07);
6176 else
6177 ring_bell (XFRAME (selected_frame));
6178 }
6179 else
6180 bitch_at_user ();
6181
6182 return Qnil;
6183 }
6184
6185 void
6186 bitch_at_user (void)
6187 {
6188 if (noninteractive)
6189 putchar (07);
6190 else if (!INTERACTIVE)
6191 {
6192 const char *msg
6193 = "Keyboard macro terminated by a command ringing the bell";
6194 Fsignal (Quser_error, list1 (build_string (msg)));
6195 }
6196 else
6197 ring_bell (XFRAME (selected_frame));
6198 }
6199
6200
6201
6202
6203
6204
6205
6206 DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 2, 0,
6207 doc:
6208
6209
6210
6211 )
6212 (Lisp_Object seconds, Lisp_Object milliseconds)
6213 {
6214 double duration = extract_float (seconds);
6215
6216 if (!NILP (milliseconds))
6217 {
6218 CHECK_FIXNUM (milliseconds);
6219 duration += XFIXNUM (milliseconds) / 1000.0;
6220 }
6221
6222 if (duration > 0)
6223 {
6224 struct timespec t = dtotimespec (duration);
6225 struct timespec tend = timespec_add (current_timespec (), t);
6226
6227
6228
6229
6230 do {
6231 wait_reading_process_output (min (t.tv_sec, WAIT_READING_MAX),
6232 t.tv_nsec, 0, 0, Qnil, NULL, 0);
6233 t = timespec_sub (tend, current_timespec ());
6234 } while (timespec_sign (t) > 0);
6235 }
6236
6237 return Qnil;
6238 }
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258 Lisp_Object
6259 sit_for (Lisp_Object timeout, bool reading, int display_option)
6260 {
6261 intmax_t sec;
6262 int nsec;
6263 bool do_display = display_option > 0;
6264 bool curbuf_eq_winbuf
6265 = (current_buffer == XBUFFER (XWINDOW (selected_window)->contents));
6266
6267 swallow_events (do_display);
6268
6269 if ((detect_input_pending_run_timers (do_display))
6270 || !NILP (Vexecuting_kbd_macro))
6271 return Qnil;
6272
6273 if (display_option > 1)
6274 redisplay_preserve_echo_area (2);
6275
6276 if (INTEGERP (timeout))
6277 {
6278 if (integer_to_intmax (timeout, &sec))
6279 {
6280 if (sec <= 0)
6281 return Qt;
6282 sec = min (sec, WAIT_READING_MAX);
6283 }
6284 else
6285 {
6286 if (NILP (Fnatnump (timeout)))
6287 return Qt;
6288 sec = WAIT_READING_MAX;
6289 }
6290 nsec = 0;
6291 }
6292 else if (FLOATP (timeout))
6293 {
6294 double seconds = XFLOAT_DATA (timeout);
6295 if (! (0 < seconds))
6296 return Qt;
6297 else
6298 {
6299 struct timespec t = dtotimespec (seconds);
6300 sec = min (t.tv_sec, WAIT_READING_MAX);
6301 nsec = t.tv_nsec;
6302 }
6303 }
6304 else if (EQ (timeout, Qt))
6305 {
6306 sec = 0;
6307 nsec = 0;
6308 }
6309 else
6310 wrong_type_argument (Qnumberp, timeout);
6311
6312
6313 #if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
6314 gobble_input ();
6315 #endif
6316
6317 int nbytes
6318 = wait_reading_process_output (sec, nsec, reading ? -1 : 1, do_display,
6319 Qnil, NULL, 0);
6320
6321 if (reading && curbuf_eq_winbuf)
6322
6323
6324
6325
6326 set_buffer_internal (XBUFFER (XWINDOW (selected_window)->contents));
6327
6328 return (nbytes > 0 || detect_input_pending ()) ? Qnil : Qt;
6329 }
6330
6331
6332 DEFUN ("redisplay", Fredisplay, Sredisplay, 0, 1, 0,
6333 doc:
6334
6335
6336
6337
6338
6339
6340 )
6341 (Lisp_Object force)
6342 {
6343 swallow_events (true);
6344 if ((detect_input_pending_run_timers (1)
6345 && NILP (force) && !redisplay_dont_pause)
6346 || !NILP (Vexecuting_kbd_macro))
6347 return Qnil;
6348
6349 specpdl_ref count = SPECPDL_INDEX ();
6350 if (!NILP (force) && !redisplay_dont_pause)
6351 specbind (Qredisplay_dont_pause, Qt);
6352 redisplay_preserve_echo_area (2);
6353 return unbind_to (count, Qt);
6354 }
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366 static Lisp_Object frame_and_buffer_state;
6367
6368
6369 DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p,
6370 Sframe_or_buffer_changed_p, 0, 1, 0,
6371 doc:
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381 )
6382 (Lisp_Object variable)
6383 {
6384 Lisp_Object state, tail, frame, buf;
6385 ptrdiff_t n, idx;
6386
6387 if (! NILP (variable))
6388 {
6389 CHECK_SYMBOL (variable);
6390 state = Fsymbol_value (variable);
6391 if (! VECTORP (state))
6392 goto changed;
6393 }
6394 else
6395 state = frame_and_buffer_state;
6396
6397 idx = 0;
6398 FOR_EACH_FRAME (tail, frame)
6399 {
6400 if (idx == ASIZE (state))
6401 goto changed;
6402 if (!BASE_EQ (AREF (state, idx++), frame))
6403 goto changed;
6404 if (idx == ASIZE (state))
6405 goto changed;
6406 if (!EQ (AREF (state, idx++), XFRAME (frame)->name))
6407 goto changed;
6408 }
6409
6410 FOR_EACH_LIVE_BUFFER (tail, buf)
6411 {
6412
6413 if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ')
6414 continue;
6415 if (idx == ASIZE (state))
6416 goto changed;
6417 if (!BASE_EQ (AREF (state, idx++), buf))
6418 goto changed;
6419 if (idx == ASIZE (state))
6420 goto changed;
6421 if (!EQ (AREF (state, idx++), BVAR (XBUFFER (buf), read_only)))
6422 goto changed;
6423 if (idx == ASIZE (state))
6424 goto changed;
6425 if (!EQ (AREF (state, idx++), Fbuffer_modified_p (buf)))
6426 goto changed;
6427 }
6428 if (idx == ASIZE (state))
6429 goto changed;
6430
6431 if (EQ (AREF (state, idx), Qlambda))
6432 return Qnil;
6433
6434
6435 changed:
6436
6437
6438 n = 1;
6439 FOR_EACH_FRAME (tail, frame)
6440 n += 2;
6441 FOR_EACH_LIVE_BUFFER (tail, buf)
6442 n += 3;
6443
6444
6445 if (! VECTORP (state)
6446 || n > ASIZE (state)
6447 || n + 20 < ASIZE (state) / 2)
6448
6449 {
6450 state = make_vector (n + 20, Qlambda);
6451 if (! NILP (variable))
6452 Fset (variable, state);
6453 else
6454 frame_and_buffer_state = state;
6455 }
6456
6457
6458 idx = 0;
6459 FOR_EACH_FRAME (tail, frame)
6460 {
6461 ASET (state, idx, frame);
6462 idx++;
6463 ASET (state, idx, XFRAME (frame)->name);
6464 idx++;
6465 }
6466 FOR_EACH_LIVE_BUFFER (tail, buf)
6467 {
6468
6469 if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ')
6470 continue;
6471 ASET (state, idx, buf);
6472 idx++;
6473 ASET (state, idx, BVAR (XBUFFER (buf), read_only));
6474 idx++;
6475 ASET (state, idx, Fbuffer_modified_p (buf));
6476 idx++;
6477 }
6478
6479 ASET (state, idx, Qlambda);
6480 idx++;
6481 while (idx < ASIZE (state))
6482 {
6483 ASET (state, idx, Qlambda);
6484 idx++;
6485 }
6486
6487 eassert (idx <= ASIZE (state));
6488 return Qt;
6489 }
6490
6491
6492
6493
6494
6495
6496
6497 static void
6498 init_faces_initial (void)
6499 {
6500
6501
6502 struct frame *sf = SELECTED_FRAME ();
6503
6504 FRAME_FOREGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_FG_COLOR;
6505 FRAME_BACKGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_BG_COLOR;
6506 call0 (intern ("tty-set-up-initial-frame-faces"));
6507 }
6508
6509
6510
6511
6512
6513 static void
6514 init_display_interactive (void)
6515 {
6516 char *terminal_type;
6517
6518
6519 space_glyph.type = CHAR_GLYPH;
6520 SET_CHAR_GLYPH (space_glyph, ' ', DEFAULT_FACE_ID, 0);
6521 space_glyph.charpos = -1;
6522
6523 inverse_video = 0;
6524 cursor_in_echo_area = false;
6525
6526
6527
6528 Vinitial_window_system = Qnil;
6529
6530
6531
6532
6533 #ifdef SIGWINCH
6534 if (!will_dump_p ())
6535 {
6536 struct sigaction action;
6537 emacs_sigaction_init (&action, deliver_window_change_signal);
6538 sigaction (SIGWINCH, &action, 0);
6539 }
6540 #endif
6541
6542
6543
6544 if (IS_DAEMON)
6545 {
6546
6547
6548
6549
6550
6551
6552
6553 if (dumped_with_pdumper_p ())
6554 init_faces_initial ();
6555 #ifndef WINDOWSNT
6556 return;
6557 #endif
6558 }
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569 #ifdef HAVE_X_WINDOWS
6570 if (! inhibit_window_system && ! display_arg)
6571 {
6572 char *display;
6573 display = getenv ("DISPLAY");
6574 display_arg = (display != 0 && *display != 0);
6575
6576 if (display_arg && !x_display_ok (display))
6577 {
6578 fprintf (stderr, "Display %s unavailable, simulating -nw\n",
6579 display);
6580 inhibit_window_system = 1;
6581 }
6582 }
6583
6584 if (!inhibit_window_system && display_arg)
6585 {
6586 Vinitial_window_system = Qx;
6587 #ifdef USE_NCURSES
6588
6589
6590
6591 { char b[2044]; tgetent (b, "xterm");}
6592 #endif
6593 return;
6594 }
6595 #endif
6596
6597 #ifdef HAVE_ANDROID
6598 if (!inhibit_window_system && android_init_gui)
6599 {
6600 Vinitial_window_system = Qandroid;
6601 android_term_init ();
6602 return;
6603 }
6604 #endif
6605
6606 #ifdef HAVE_NTGUI
6607 if (!inhibit_window_system)
6608 {
6609 Vinitial_window_system = Qw32;
6610 return;
6611 }
6612 #endif
6613
6614 #ifdef HAVE_NS
6615 if (!inhibit_window_system && !will_dump_p ())
6616 {
6617 Vinitial_window_system = Qns;
6618 return;
6619 }
6620 #endif
6621
6622 #ifdef HAVE_PGTK
6623 if (!inhibit_window_system && !will_dump_p ())
6624 {
6625 Vinitial_window_system = Qpgtk;
6626 return;
6627 }
6628 #endif
6629
6630 #ifdef HAVE_HAIKU
6631 if (!inhibit_window_system && !will_dump_p ())
6632 {
6633 Vinitial_window_system = Qhaiku;
6634 return;
6635 }
6636 #endif
6637
6638
6639 if (! isatty (STDIN_FILENO))
6640 fatal ("standard input is not a tty");
6641
6642 #ifdef WINDOWSNT
6643 terminal_type = (char *)"w32console";
6644 #else
6645 terminal_type = getenv ("TERM");
6646 #endif
6647 if (!terminal_type)
6648 {
6649 char const *msg
6650 = "Please set the environment variable TERM; see 'tset'.\n";
6651 #ifdef HAVE_WINDOW_SYSTEM
6652 if (! inhibit_window_system)
6653 msg = ("Please set the environment variable DISPLAY or TERM; "
6654 "see 'tset'.\n");
6655 #endif
6656 fputs (msg, stderr);
6657 exit (1);
6658 }
6659
6660 #ifndef HAVE_ANDROID
6661 {
6662 struct terminal *t;
6663 struct frame *f = XFRAME (selected_frame);
6664
6665 init_foreground_group ();
6666
6667
6668 t = init_tty (0, terminal_type, 1);
6669
6670
6671 if (f->output_method != output_initial)
6672 emacs_abort ();
6673 f->output_method = t->type;
6674 f->terminal = t;
6675
6676 t->reference_count++;
6677 #ifdef MSDOS
6678 f->output_data.tty = &the_only_tty_output;
6679 f->output_data.tty->display_info = &the_only_display_info;
6680 #else
6681 if (f->output_method == output_termcap)
6682 create_tty_output (f);
6683 #endif
6684 t->display_info.tty->top_frame = selected_frame;
6685 change_frame_size (XFRAME (selected_frame),
6686 FrameCols (t->display_info.tty),
6687 FrameRows (t->display_info.tty),
6688 false, false, true);
6689
6690
6691 if (--initial_terminal->reference_count == 0
6692 && initial_terminal->delete_terminal_hook)
6693 (*initial_terminal->delete_terminal_hook) (initial_terminal);
6694
6695
6696 AUTO_FRAME_ARG (tty_type_arg, Qtty_type, Ftty_type (selected_frame));
6697 Fmodify_frame_parameters (selected_frame, tty_type_arg);
6698 AUTO_FRAME_ARG (tty_arg, Qtty, (t->display_info.tty->name
6699 ? build_string (t->display_info.tty->name)
6700 : Qnil));
6701 Fmodify_frame_parameters (selected_frame, tty_arg);
6702 }
6703 #else
6704 fatal ("Could not establish a connection to the Android application.\n"
6705 "Emacs does not work on text terminals when built to run as"
6706 " part of an Android application package.");
6707 #endif
6708
6709 {
6710 struct frame *sf = SELECTED_FRAME ();
6711 int width = FRAME_TOTAL_COLS (sf);
6712 int height = FRAME_TOTAL_LINES (sf);
6713 int area;
6714
6715
6716
6717
6718
6719 if (ckd_add (&area, width, 2)
6720 || ckd_mul (&area, area, height)
6721 || min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph) < area)
6722 fatal ("screen size %dx%d too big", width, height);
6723 }
6724
6725 calculate_costs (XFRAME (selected_frame));
6726
6727
6728 if (initialized && !noninteractive && NILP (Vinitial_window_system))
6729 init_faces_initial ();
6730 }
6731
6732 void
6733 init_display (void)
6734 {
6735 if (noninteractive)
6736 {
6737 if (dumped_with_pdumper_p ())
6738 init_faces_initial ();
6739 }
6740 else
6741 init_display_interactive ();
6742 }
6743
6744
6745
6746
6747
6748
6749 DEFUN ("internal-show-cursor", Finternal_show_cursor,
6750 Sinternal_show_cursor, 2, 2, 0,
6751 doc:
6752
6753
6754 )
6755 (Lisp_Object window, Lisp_Object show)
6756 {
6757
6758
6759 if (!redisplaying_p)
6760 decode_any_window (window)->cursor_off_p = NILP (show);
6761 return Qnil;
6762 }
6763
6764
6765 DEFUN ("internal-show-cursor-p", Finternal_show_cursor_p,
6766 Sinternal_show_cursor_p, 0, 1, 0,
6767 doc:
6768 )
6769 (Lisp_Object window)
6770 {
6771 return decode_any_window (window)->cursor_off_p ? Qnil : Qt;
6772 }
6773
6774
6775
6776
6777
6778 static void syms_of_display_for_pdumper (void);
6779
6780 void
6781 syms_of_display (void)
6782 {
6783 defsubr (&Sredraw_frame);
6784 defsubr (&Sredraw_display);
6785 defsubr (&Sdisplay__update_for_mouse_movement);
6786 defsubr (&Sframe_or_buffer_changed_p);
6787 defsubr (&Sopen_termscript);
6788 defsubr (&Sding);
6789 defsubr (&Sredisplay);
6790 defsubr (&Ssleep_for);
6791 defsubr (&Ssend_string_to_terminal);
6792 defsubr (&Sinternal_show_cursor);
6793 defsubr (&Sinternal_show_cursor_p);
6794
6795 #ifdef GLYPH_DEBUG
6796 defsubr (&Sdump_redisplay_history);
6797 #endif
6798
6799 frame_and_buffer_state = make_vector (20, Qlambda);
6800 staticpro (&frame_and_buffer_state);
6801
6802
6803 DEFSYM (Qdisplay_table, "display-table");
6804
6805 DEFSYM (Qredisplay_dont_pause, "redisplay-dont-pause");
6806
6807 DEFVAR_INT ("baud-rate", baud_rate,
6808 doc:
6809
6810 );
6811
6812 DEFVAR_BOOL ("inverse-video", inverse_video,
6813 doc:
6814 );
6815
6816 DEFVAR_BOOL ("visible-bell", visible_bell,
6817 doc:
6818
6819 );
6820
6821 DEFVAR_BOOL ("no-redraw-on-reenter", no_redraw_on_reenter,
6822 doc:
6823
6824
6825 );
6826
6827 DEFVAR_LISP ("initial-window-system", Vinitial_window_system,
6828 doc:
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840 );
6841
6842 DEFVAR_KBOARD ("window-system", Vwindow_system,
6843 doc:
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855 );
6856
6857 DEFVAR_BOOL ("cursor-in-echo-area", cursor_in_echo_area,
6858 doc: );
6859
6860 DEFVAR_BOOL ("mouse-prefer-closest-glyph", mouse_prefer_closest_glyph,
6861 doc:
6862
6863
6864
6865 );
6866 mouse_prefer_closest_glyph = false;
6867
6868 DEFVAR_LISP ("glyph-table", Vglyph_table,
6869 doc:
6870
6871
6872
6873
6874
6875
6876 );
6877 Vglyph_table = Qnil;
6878
6879 DEFVAR_LISP ("standard-display-table", Vstandard_display_table,
6880 doc:
6881
6882 );
6883 Vstandard_display_table = Qnil;
6884
6885 DEFVAR_BOOL ("redisplay-dont-pause", redisplay_dont_pause,
6886 doc: );
6887
6888
6889
6890
6891
6892
6893
6894 redisplay_dont_pause = true;
6895
6896 DEFVAR_LISP ("x-show-tooltip-timeout", Vx_show_tooltip_timeout,
6897 doc: );
6898 Vx_show_tooltip_timeout = make_fixnum (5);
6899
6900 DEFVAR_LISP ("tab-bar-position", Vtab_bar_position,
6901 doc:
6902
6903 );
6904
6905 pdumper_do_now_and_after_load (syms_of_display_for_pdumper);
6906 }
6907
6908 static void
6909 syms_of_display_for_pdumper (void)
6910 {
6911 Vinitial_window_system = Qnil;
6912 }