Mercurial > hg > xemacs-beta
comparison src/redisplay-output.c @ 412:697ef44129c6 r21-2-14
Import from CVS: tag r21-2-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:20:41 +0200 |
parents | 501cfd01ee6d |
children | 95016f13131a |
comparison
equal
deleted
inserted
replaced
411:12e008d41344 | 412:697ef44129c6 |
---|---|
1 /* Synchronize redisplay structures and output changes. | 1 /* Synchronize redisplay structures and output changes. |
2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. | 2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. |
3 Copyright (C) 1995, 1996 Ben Wing. | 3 Copyright (C) 1995, 1996 Ben Wing. |
4 Copyright (C) 1996 Chuck Thompson. | 4 Copyright (C) 1996 Chuck Thompson. |
5 Copyright (C) 1999 Andy Piper. | |
6 | 5 |
7 This file is part of XEmacs. | 6 This file is part of XEmacs. |
8 | 7 |
9 XEmacs is free software; you can redistribute it and/or modify it | 8 XEmacs is free software; you can redistribute it and/or modify it |
10 under the terms of the GNU General Public License as published by the | 9 under the terms of the GNU General Public License as published by the |
24 /* Synched up with: Not in FSF. */ | 23 /* Synched up with: Not in FSF. */ |
25 | 24 |
26 /* This file has been Mule-ized. */ | 25 /* This file has been Mule-ized. */ |
27 | 26 |
28 /* Author: Chuck Thompson */ | 27 /* Author: Chuck Thompson */ |
29 | |
30 /* Heavily hacked for modularity, gutter and subwindow support by Andy | |
31 Piper. */ | |
32 | 28 |
33 #include <config.h> | 29 #include <config.h> |
34 #include "lisp.h" | 30 #include "lisp.h" |
35 | 31 |
36 #include "buffer.h" | 32 #include "buffer.h" |
45 struct rune *drb); | 41 struct rune *drb); |
46 static void redraw_cursor_in_window (struct window *w, | 42 static void redraw_cursor_in_window (struct window *w, |
47 int run_end_begin_glyphs); | 43 int run_end_begin_glyphs); |
48 static void redisplay_output_display_block (struct window *w, struct display_line *dl, | 44 static void redisplay_output_display_block (struct window *w, struct display_line *dl, |
49 int block, int start, int end, int start_pixpos, | 45 int block, int start, int end, int start_pixpos, |
50 int cursor_start, int cursor_width, | 46 int cursor_start, int cursor_width, |
51 int cursor_height); | 47 int cursor_height); |
52 static void redisplay_normalize_display_box (struct display_box* dest, | |
53 struct display_glyph_area* src); | |
54 static int redisplay_display_boxes_in_window_p (struct window* w, | |
55 struct display_box* db, | |
56 struct display_glyph_area* dga); | |
57 static void redisplay_clear_clipped_region (Lisp_Object locale, face_index findex, | |
58 struct display_box* dest, | |
59 struct display_glyph_area* glyphsrc, | |
60 int fullheight_p, Lisp_Object); | |
61 | 48 |
62 /***************************************************************************** | 49 /***************************************************************************** |
63 sync_rune_structs | 50 sync_rune_structs |
64 | 51 |
65 Synchronize the given rune blocks. | 52 Synchronize the given rune blocks. |
99 sync_display_line_structs | 86 sync_display_line_structs |
100 | 87 |
101 For the given LINE in window W, make the current display line equal | 88 For the given LINE in window W, make the current display line equal |
102 the desired display line. | 89 the desired display line. |
103 ****************************************************************************/ | 90 ****************************************************************************/ |
104 void | 91 static void |
105 sync_display_line_structs (struct window *w, int line, int do_blocks, | 92 sync_display_line_structs (struct window *w, int line, int do_blocks, |
106 display_line_dynarr *cdla, | 93 display_line_dynarr *cdla, |
107 display_line_dynarr *ddla) | 94 display_line_dynarr *ddla) |
108 { | 95 { |
109 int cdla_len = Dynarr_length (cdla); | 96 int cdla_len = Dynarr_length (cdla); |
188 compare_runes (struct window *w, struct rune *crb, struct rune *drb) | 175 compare_runes (struct window *w, struct rune *crb, struct rune *drb) |
189 { | 176 { |
190 /* Do not compare the values of bufpos and endpos. They do not | 177 /* Do not compare the values of bufpos and endpos. They do not |
191 affect the display characteristics. */ | 178 affect the display characteristics. */ |
192 | 179 |
193 /* Note: (hanoi 6) spends 95% of its time in redisplay, and about | 180 if ((crb->findex != drb->findex) || |
194 30% here. Not using bitfields for rune.type alone gives a redisplay | 181 (WINDOW_FACE_CACHEL_DIRTY (w, drb->findex))) |
195 speed up of 10%. | 182 return 0; |
196 | 183 else if (crb->xpos != drb->xpos) |
197 #### In profile arcs run of a normal Gnus session this function | |
198 is run 6.76 million times, only to return 1 in 6.73 million of | |
199 those. | |
200 | |
201 In addition a quick look GCC sparc assembly shows that GCC is not | |
202 doing a good job here. | |
203 1. The function is not inlined (too complicated?) | |
204 2. It seems to be reloading the crb and drb variables all the | |
205 time. | |
206 3. It doesn't seem to notice that the second half of these if's | |
207 are really a switch statement. | |
208 | |
209 So I (JV) conjecture | |
210 | |
211 #### It would really be worth it to arrange for this function to | |
212 be (almost) a single call to memcmp. */ | |
213 | |
214 if (crb->xpos != drb->xpos) | |
215 return 0; | 184 return 0; |
216 else if (crb->width != drb->width) | 185 else if (crb->width != drb->width) |
217 return 0; | 186 return 0; |
218 else if (crb->cursor_type != drb->cursor_type) | 187 else if (crb->cursor_type != drb->cursor_type) |
219 return 0; | 188 return 0; |
220 else if (crb->type != drb->type) | 189 else if (crb->type != drb->type) |
221 return 0; | 190 return 0; |
222 else if (crb->type == RUNE_CHAR && | 191 else if (crb->type == RUNE_CHAR && |
223 (crb->object.chr.ch != drb->object.chr.ch)) | 192 (crb->object.chr.ch != drb->object.chr.ch)) |
224 return 0; | 193 return 0; |
225 else if (crb->type == RUNE_HLINE && | |
226 (crb->object.hline.thickness != drb->object.hline.thickness || | |
227 crb->object.hline.yoffset != drb->object.hline.yoffset)) | |
228 return 0; | |
229 else if (crb->type == RUNE_DGLYPH && | 194 else if (crb->type == RUNE_DGLYPH && |
230 (!EQ (crb->object.dglyph.glyph, drb->object.dglyph.glyph) || | 195 (!EQ (crb->object.dglyph.glyph, drb->object.dglyph.glyph) || |
231 !EQ (crb->object.dglyph.extent, drb->object.dglyph.extent) || | 196 !EQ (crb->object.dglyph.extent, drb->object.dglyph.extent) || |
232 crb->object.dglyph.xoffset != drb->object.dglyph.xoffset)) | 197 crb->object.dglyph.xoffset != drb->object.dglyph.xoffset)) |
233 return 0; | 198 return 0; |
234 /* Only check dirtiness if we know something has changed. */ | 199 else if (crb->type == RUNE_HLINE && |
235 else if (crb->type == RUNE_DGLYPH && | 200 (crb->object.hline.thickness != drb->object.hline.thickness || |
236 (XGLYPH_DIRTYP (crb->object.dglyph.glyph) || | 201 crb->object.hline.yoffset != drb->object.hline.yoffset)) |
237 crb->findex != drb->findex)) | |
238 { | |
239 /* We need some way of telling redisplay_output_layout () that the | |
240 only reason we are outputting it is because something has | |
241 changed internally. That way we can optimize whether we need | |
242 to clear the layout first and also only output the components | |
243 that have changed. The image_instance dirty flag and | |
244 display_hash are no good to us because these will invariably | |
245 have been set anyway if the layout has changed. So it looks | |
246 like we need yet another change flag that we can set here and | |
247 then clear in redisplay_output_layout (). */ | |
248 Lisp_Object window, image; | |
249 Lisp_Image_Instance* ii; | |
250 XSETWINDOW (window, w); | |
251 image = glyph_image_instance (crb->object.dglyph.glyph, | |
252 window, ERROR_ME_NOT, 1); | |
253 | |
254 if (!IMAGE_INSTANCEP (image)) | |
255 return 0; | |
256 ii = XIMAGE_INSTANCE (image); | |
257 | |
258 if (TEXT_IMAGE_INSTANCEP (image) && | |
259 (crb->findex != drb->findex || | |
260 WINDOW_FACE_CACHEL_DIRTY (w, drb->findex))) | |
261 return 0; | |
262 | |
263 /* It is quite common of the two glyphs to be EQ since in many | |
264 cases they will actually be the same object. This does not | |
265 mean, however, that nothing has changed. We therefore need to | |
266 check the current hash of the glyph against the last recorded | |
267 display hash and the pending display items. See | |
268 update_subwindow (). */ | |
269 if (image_instance_changed (image) || | |
270 crb->findex != drb->findex || | |
271 WINDOW_FACE_CACHEL_DIRTY (w, drb->findex)) | |
272 { | |
273 /* We now now we are going to re-output the glyph, but since | |
274 this is for some internal reason not related to geometry | |
275 changes, send a hint to the output routines that they can | |
276 take some short cuts. This is most useful for | |
277 layouts. This flag should get reset by the output | |
278 routines. | |
279 | |
280 #### It is possible for us to get here when the | |
281 face_cachel is dirty. I do not know what the implications | |
282 of this are.*/ | |
283 IMAGE_INSTANCE_OPTIMIZE_OUTPUT (ii) = 1; | |
284 return 0; | |
285 } | |
286 else | |
287 return 1; | |
288 } | |
289 /* We now do this last so that glyph checks can do their own thing | |
290 for face changes. Face changes quite often happen when we are | |
291 trying to output something in the gutter, this would normally | |
292 lead to a lot of flashing. The indices can quite often be | |
293 different and yet the faces are the same, we do not want to | |
294 re-output in this instance. */ | |
295 else if (crb->findex != drb->findex || | |
296 WINDOW_FACE_CACHEL_DIRTY (w, drb->findex)) | |
297 return 0; | 202 return 0; |
298 else | 203 else |
299 return 1; | 204 return 1; |
300 } | 205 } |
301 | 206 |
444 #endif | 349 #endif |
445 ) | 350 ) |
446 force = 1; | 351 force = 1; |
447 | 352 |
448 if (f->windows_structure_changed || | 353 if (f->windows_structure_changed || |
449 /* #### Why is this so? We have face cachels so that we don't | |
450 have to recalculate all the display blocks when faces | |
451 change. I have fixed this for glyphs and am inclined to think | |
452 that faces should "Just Work", but I'm not feeling brave | |
453 today. Maybe its because the face cachels represent merged | |
454 faces rather than simply instantiations in a particular | |
455 domain. */ | |
456 f->faces_changed || | 354 f->faces_changed || |
355 f->glyphs_changed || | |
457 cdl->ypos != ddl->ypos || | 356 cdl->ypos != ddl->ypos || |
458 cdl->ascent != ddl->ascent || | 357 cdl->ascent != ddl->ascent || |
459 cdl->descent != ddl->descent || | 358 cdl->descent != ddl->descent || |
460 cdl->clip != ddl->clip || | 359 cdl->clip != ddl->clip || |
461 force) | 360 force) |
688 f->faces_changed || | 587 f->faces_changed || |
689 force || | 588 force || |
690 (cdl && (cdl->ypos != ddl->ypos || | 589 (cdl && (cdl->ypos != ddl->ypos || |
691 cdl->ascent != ddl->ascent || | 590 cdl->ascent != ddl->ascent || |
692 cdl->descent != ddl->descent || | 591 cdl->descent != ddl->descent || |
693 cdl->top_clip != ddl->top_clip || | |
694 cdl->clip != ddl->clip))) | 592 cdl->clip != ddl->clip))) |
695 { | 593 { |
696 int x, y, width, height; | 594 int x, y, width, height; |
697 face_index findex; | 595 Lisp_Object face; |
698 | 596 |
699 must_sync = 1; | 597 must_sync = 1; |
700 x = start_pixpos; | 598 x = start_pixpos; |
701 y = DISPLAY_LINE_YPOS (ddl); | 599 y = ddl->ypos - ddl->ascent; |
702 width = min (next_start_pixpos, block_end) - x; | 600 width = min (next_start_pixpos, block_end) - x; |
703 height = DISPLAY_LINE_HEIGHT (ddl); | 601 height = ddl->ascent + ddl->descent - ddl->clip; |
704 | 602 |
705 if (x < ddl->bounds.left_in) | 603 if (x < ddl->bounds.left_in) |
706 { | 604 face = Vleft_margin_face; |
707 findex = ddl->left_margin_findex ? | |
708 ddl->left_margin_findex | |
709 : get_builtin_face_cache_index (w, Vleft_margin_face); | |
710 } | |
711 else if (x < ddl->bounds.right_in) | 605 else if (x < ddl->bounds.right_in) |
712 { | 606 face = Vdefault_face; |
713 /* no check here because DEFAULT_INDEX == 0 anyway */ | |
714 findex = ddl->default_findex; | |
715 } | |
716 else if (x < ddl->bounds.right_out) | 607 else if (x < ddl->bounds.right_out) |
717 { | 608 face = Vright_margin_face; |
718 findex = ddl->right_margin_findex ? | |
719 ddl->right_margin_findex | |
720 : get_builtin_face_cache_index (w, Vright_margin_face); | |
721 } | |
722 else | 609 else |
723 findex = (face_index) -1; | 610 face = Qnil; |
724 | 611 |
725 if (findex != (face_index) -1) | 612 if (!NILP (face)) |
726 { | 613 { |
727 Lisp_Object window; | 614 Lisp_Object window; |
728 | 615 |
729 XSETWINDOW (window, w); | 616 XSETWINDOW (window, w); |
730 | 617 |
731 /* Clear the empty area. */ | 618 /* Clear the empty area. */ |
732 redisplay_clear_region (window, findex, x, y, width, height); | 619 redisplay_clear_region (window, get_builtin_face_cache_index (w, face), |
620 x, y, width, height); | |
733 | 621 |
734 /* Mark that we should clear the border. This is | 622 /* Mark that we should clear the border. This is |
735 necessary because italic fonts may leave | 623 necessary because italic fonts may leave |
736 droppings in the border. */ | 624 droppings in the border. */ |
737 clear_border = 1; | 625 clear_border = 1; |
758 | 646 |
759 /* If there was formerly no block over the current | 647 /* If there was formerly no block over the current |
760 region or if it was a block of a different type, then | 648 region or if it was a block of a different type, then |
761 output the entire ddb. Otherwise, compare cdb and | 649 output the entire ddb. Otherwise, compare cdb and |
762 ddb and output only the changed region. */ | 650 ddb and output only the changed region. */ |
763 if (!force && cdb && ddb->type == cdb->type | 651 if (!force && cdb && ddb->type == cdb->type && b == old_b) |
764 /* If there was no buffer being display before the | |
765 compare anyway as we might be outputting a gutter. */ | |
766 && | |
767 (b == old_b || !old_b)) | |
768 { | 652 { |
769 must_sync |= compare_display_blocks (w, cdl, ddl, old_block, | 653 must_sync |= compare_display_blocks (w, cdl, ddl, old_block, |
770 block, start_pixpos, | 654 block, start_pixpos, |
771 cursor_start, cursor_width, | 655 cursor_start, cursor_width, |
772 cursor_height); | 656 cursor_height); |
800 last_elt, | 684 last_elt, |
801 start_pixpos, | 685 start_pixpos, |
802 cursor_start, cursor_width, | 686 cursor_start, cursor_width, |
803 cursor_height); | 687 cursor_height); |
804 } | 688 } |
805 | 689 |
806 start_pixpos = next_start_pixpos; | 690 start_pixpos = next_start_pixpos; |
807 } | 691 } |
808 } | 692 } |
809 | 693 |
810 /* Clear the internal border if we are next to it and the window | 694 /* Clear the internal border if we are next to it and the window |
813 /* #### Doing this on f->clear sucks but is necessary because of | 697 /* #### Doing this on f->clear sucks but is necessary because of |
814 window-local background values. */ | 698 window-local background values. */ |
815 if (f->windows_structure_changed || f->faces_changed || clear_border | 699 if (f->windows_structure_changed || f->faces_changed || clear_border |
816 || f->clear) | 700 || f->clear) |
817 { | 701 { |
818 int y = DISPLAY_LINE_YPOS (ddl); | 702 int y = ddl->ypos - ddl->ascent; |
819 int height = DISPLAY_LINE_HEIGHT (ddl); | 703 int height = ddl->ascent + ddl->descent - ddl->clip; |
820 | 704 |
821 /* If we are in the gutter then we musn't clear the borders. */ | 705 if (ddl->modeline) |
822 if (y >= WINDOW_TEXT_TOP (w) && (y + height) <= WINDOW_TEXT_BOTTOM (w)) | 706 { |
823 { | 707 y -= MODELINE_SHADOW_THICKNESS (w); |
824 if (ddl->modeline) | 708 height += (2 * MODELINE_SHADOW_THICKNESS (w)); |
825 { | 709 } |
826 y -= MODELINE_SHADOW_THICKNESS (w); | 710 |
827 height += (2 * MODELINE_SHADOW_THICKNESS (w)); | 711 if (window_is_leftmost (w)) |
828 } | 712 clear_left_border (w, y, height); |
829 | 713 if (window_is_rightmost (w)) |
830 if (window_is_leftmost (w)) | 714 clear_right_border (w, y, height); |
831 clear_left_border (w, y, height); | |
832 if (window_is_rightmost (w)) | |
833 clear_right_border (w, y, height); | |
834 } | |
835 } | 715 } |
836 | 716 |
837 if (cdla) | 717 if (cdla) |
838 sync_display_line_structs (w, line, must_sync, cdla, ddla); | 718 sync_display_line_structs (w, line, must_sync, cdla, ddla); |
839 } | 719 } |
896 dl->cursor_elt = x; | 776 dl->cursor_elt = x; |
897 return 1; | 777 return 1; |
898 } | 778 } |
899 else | 779 else |
900 { | 780 { |
901 { | 781 DEVMETH (d, output_begin, (d)); |
902 MAYBE_DEVMETH (d, frame_output_begin, (f)); | 782 |
903 MAYBE_DEVMETH (d, window_output_begin, (w)); | 783 /* #### This is a gross kludge. Cursor handling is such a royal |
904 } | 784 pain in the ass. */ |
905 rb->cursor_type = CURSOR_OFF; | 785 if (rb->type == RUNE_DGLYPH && |
786 (EQ (rb->object.dglyph.glyph, Vtruncation_glyph) || | |
787 EQ (rb->object.dglyph.glyph, Vcontinuation_glyph))) | |
788 rb->cursor_type = NO_CURSOR; | |
789 else | |
790 rb->cursor_type = CURSOR_OFF; | |
906 dl->cursor_elt = -1; | 791 dl->cursor_elt = -1; |
907 output_display_line (w, 0, cla, y, rb->xpos, rb->xpos + rb->width); | 792 output_display_line (w, 0, cla, y, rb->xpos, rb->xpos + rb->width); |
908 } | 793 } |
909 | 794 |
910 w->last_point_x[CURRENT_DISP] = -1; | 795 w->last_point_x[CURRENT_DISP] = -1; |
914 /* If this isn't the selected frame, then erasing the old cursor is | 799 /* If this isn't the selected frame, then erasing the old cursor is |
915 all we actually had to do. */ | 800 all we actually had to do. */ |
916 if (w != XWINDOW (FRAME_SELECTED_WINDOW (device_selected_frame (d)))) | 801 if (w != XWINDOW (FRAME_SELECTED_WINDOW (device_selected_frame (d)))) |
917 { | 802 { |
918 if (!no_output_end) | 803 if (!no_output_end) |
919 { | 804 DEVMETH (d, output_end, (d)); |
920 MAYBE_DEVMETH (d, window_output_end, (w)); | |
921 MAYBE_DEVMETH (d, frame_output_end, (f)); | |
922 } | |
923 | 805 |
924 return 1; | 806 return 1; |
925 } | 807 } |
926 | 808 |
927 /* This should only occur in the minibuffer. */ | 809 /* This should only occur in the minibuffer. */ |
936 dl->cursor_elt = 0; | 818 dl->cursor_elt = 0; |
937 | 819 |
938 output_display_line (w, 0, cla, y, rb->xpos, rb->xpos + rb->width); | 820 output_display_line (w, 0, cla, y, rb->xpos, rb->xpos + rb->width); |
939 | 821 |
940 if (!no_output_end) | 822 if (!no_output_end) |
941 { | 823 DEVMETH (d, output_end, (d)); |
942 MAYBE_DEVMETH (d, window_output_end, (w)); | |
943 MAYBE_DEVMETH (d, frame_output_end, (f)); | |
944 } | |
945 return 1; | 824 return 1; |
946 } | 825 } |
947 else | 826 else |
948 { | 827 { |
949 int cur_rb = 0; | 828 int cur_rb = 0; |
971 cur_dl = y; | 850 cur_dl = y; |
972 first = 1; | 851 first = 1; |
973 } | 852 } |
974 } | 853 } |
975 | 854 |
976 while (up ? (cur_dl < Dynarr_length (cla)) : (cur_dl >= 0)) | 855 while ((up ? (cur_dl < Dynarr_length (cla)) : (cur_dl >= 0))) |
977 { | 856 { |
978 dl = Dynarr_atp (cla, cur_dl); | 857 dl = Dynarr_atp (cla, cur_dl); |
979 db = get_display_block_from_line (dl, TEXT); | 858 db = get_display_block_from_line (dl, TEXT); |
980 | 859 |
981 if (!up && !first) | 860 if (!up && !first) |
1003 w->last_point_y[CURRENT_DISP] = cur_dl; | 882 w->last_point_y[CURRENT_DISP] = cur_dl; |
1004 Fset_marker (w->last_point[CURRENT_DISP], | 883 Fset_marker (w->last_point[CURRENT_DISP], |
1005 make_int (ADJ_BUFPOS), w->buffer); | 884 make_int (ADJ_BUFPOS), w->buffer); |
1006 | 885 |
1007 if (!no_output_end) | 886 if (!no_output_end) |
1008 { | 887 DEVMETH (d, output_end, (d)); |
1009 MAYBE_DEVMETH (d, window_output_end, (w)); | |
1010 MAYBE_DEVMETH (d, frame_output_end, (f)); | |
1011 } | |
1012 return 1; | 888 return 1; |
1013 } | 889 } |
1014 | 890 |
1015 (up ? cur_rb++ : cur_rb--); | 891 (up ? cur_rb++ : cur_rb--); |
1016 } | 892 } |
1019 (up ? cur_dl++ : cur_dl--); | 895 (up ? cur_dl++ : cur_dl--); |
1020 } | 896 } |
1021 } | 897 } |
1022 | 898 |
1023 if (!no_output_end) | 899 if (!no_output_end) |
1024 { | 900 DEVMETH (d, output_end, (d)); |
1025 MAYBE_DEVMETH (d, window_output_end, (w)); | |
1026 MAYBE_DEVMETH (d, frame_output_end, (f)); | |
1027 } | |
1028 return 0; | 901 return 0; |
1029 } | 902 } |
1030 #undef ADJ_BUFPOS | 903 #undef ADJ_BUFPOS |
1031 #undef ADJ_ENDPOS | 904 #undef ADJ_ENDPOS |
1032 | 905 |
1077 { | 950 { |
1078 MAYBE_DEVMETH (d, set_final_cursor_coords, | 951 MAYBE_DEVMETH (d, set_final_cursor_coords, |
1079 (f, dl->ypos - 1, rb->xpos)); | 952 (f, dl->ypos - 1, rb->xpos)); |
1080 | 953 |
1081 if (run_end_begin_meths) | 954 if (run_end_begin_meths) |
1082 { | 955 DEVMETH (d, output_begin, (d)); |
1083 MAYBE_DEVMETH (d, frame_output_begin, (f)); | |
1084 MAYBE_DEVMETH (d, window_output_begin, (w)); | |
1085 } | |
1086 | 956 |
1087 output_display_line (w, 0, dla, y, rb->xpos, rb->xpos + rb->width); | 957 output_display_line (w, 0, dla, y, rb->xpos, rb->xpos + rb->width); |
1088 | 958 |
1089 if (run_end_begin_meths) | 959 if (run_end_begin_meths) |
1090 { | 960 DEVMETH (d, output_end, (d)); |
1091 MAYBE_DEVMETH (d, window_output_end, (w)); | |
1092 MAYBE_DEVMETH (d, frame_output_end, (f)); | |
1093 } | |
1094 } | 961 } |
1095 } | 962 } |
1096 | 963 |
1097 /***************************************************************************** | 964 /***************************************************************************** |
1098 redisplay_redraw_cursor | 965 redisplay_redraw_cursor |
1126 int start, int end, int start_pixpos, int cursor_start, | 993 int start, int end, int start_pixpos, int cursor_start, |
1127 int cursor_width, int cursor_height) | 994 int cursor_width, int cursor_height) |
1128 { | 995 { |
1129 struct frame *f = XFRAME (w->frame); | 996 struct frame *f = XFRAME (w->frame); |
1130 struct device *d = XDEVICE (f->device); | 997 struct device *d = XDEVICE (f->device); |
1131 /* Temporarily disabled until generalization is done. */ | 998 |
1132 #if 0 | |
1133 struct display_block *db = Dynarr_atp (dl->display_blocks, block); | |
1134 rune_dynarr *rba = db->runes; | |
1135 struct rune *rb; | |
1136 int xpos, width; | |
1137 rb = Dynarr_atp (rba, start); | |
1138 | |
1139 if (!rb) | |
1140 /* Nothing to do so don't do anything. */ | |
1141 return; | |
1142 | |
1143 xpos = max (start_pixpos, rb->xpos); | |
1144 | |
1145 if (end < 0) | |
1146 end = Dynarr_length (rba); | |
1147 | |
1148 rb = Dynarr_atp (rba, end - 1); | |
1149 width = rb->xpos + rb->width - xpos; | |
1150 #endif | |
1151 /* now actually output the block. */ | |
1152 DEVMETH (d, output_display_block, (w, dl, block, start, | 999 DEVMETH (d, output_display_block, (w, dl, block, start, |
1153 end, start_pixpos, | 1000 end, start_pixpos, |
1154 cursor_start, cursor_width, | 1001 cursor_start, cursor_width, |
1155 cursor_height)); | 1002 cursor_height)); |
1156 } | 1003 } |
1157 | 1004 |
1158 /**************************************************************************** | 1005 /**************************************************************************** |
1159 redisplay_unmap_subwindows | 1006 redisplay_unmap_subwindows |
1160 | 1007 |
1161 Remove subwindows from the area in the box defined by the given | 1008 Remove subwindows from the area in the box defined by the given |
1162 parameters. | 1009 parameters. |
1163 ****************************************************************************/ | 1010 ****************************************************************************/ |
1164 static void redisplay_unmap_subwindows (struct frame* f, int x, int y, int width, int height, | 1011 static void redisplay_unmap_subwindows (struct frame* f, int x, int y, int width, int height) |
1165 Lisp_Object ignored_window) | 1012 { |
1166 { | 1013 int elt; |
1167 Lisp_Object rest; | 1014 |
1168 | 1015 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) |
1169 LIST_LOOP (rest, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f))) | 1016 { |
1170 { | 1017 struct subwindow_cachel *cachel = |
1171 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (XCAR (rest)); | 1018 Dynarr_atp (f->subwindow_cachels, elt); |
1172 | 1019 |
1173 if (IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) | 1020 if (cachel->being_displayed |
1174 && | 1021 && |
1175 IMAGE_INSTANCE_DISPLAY_X (ii) | 1022 cachel->x + cachel->width > x && cachel->x < x + width |
1176 + IMAGE_INSTANCE_DISPLAY_WIDTH (ii) > x | |
1177 && | |
1178 IMAGE_INSTANCE_DISPLAY_X (ii) < x + width | |
1179 && | 1023 && |
1180 IMAGE_INSTANCE_DISPLAY_Y (ii) | 1024 cachel->y + cachel->height > y && cachel->y < y + height) |
1181 + IMAGE_INSTANCE_DISPLAY_HEIGHT (ii) > y | 1025 { |
1182 && | 1026 unmap_subwindow (cachel->subwindow); |
1183 IMAGE_INSTANCE_DISPLAY_Y (ii) < y + height | |
1184 && | |
1185 !EQ (XCAR (rest), ignored_window)) | |
1186 { | |
1187 unmap_subwindow (XCAR (rest)); | |
1188 } | 1027 } |
1189 } | 1028 } |
1190 } | 1029 } |
1191 | 1030 |
1192 /**************************************************************************** | 1031 /**************************************************************************** |
1195 Potentially subwindows from the area in the box defined by the given | 1034 Potentially subwindows from the area in the box defined by the given |
1196 parameters. | 1035 parameters. |
1197 ****************************************************************************/ | 1036 ****************************************************************************/ |
1198 void redisplay_unmap_subwindows_maybe (struct frame* f, int x, int y, int width, int height) | 1037 void redisplay_unmap_subwindows_maybe (struct frame* f, int x, int y, int width, int height) |
1199 { | 1038 { |
1200 if (!NILP (XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)))) | 1039 if (Dynarr_length (FRAME_SUBWINDOW_CACHE (f))) |
1201 { | 1040 { |
1202 redisplay_unmap_subwindows (f, x, y, width, height, Qnil); | 1041 redisplay_unmap_subwindows (f, x, y, width, height); |
1203 } | |
1204 } | |
1205 | |
1206 static void redisplay_unmap_subwindows_except_us (struct frame* f, int x, int y, int width, | |
1207 int height, Lisp_Object subwindow) | |
1208 { | |
1209 if (!NILP (XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)))) | |
1210 { | |
1211 redisplay_unmap_subwindows (f, x, y, width, height, subwindow); | |
1212 } | 1042 } |
1213 } | 1043 } |
1214 | 1044 |
1215 /**************************************************************************** | 1045 /**************************************************************************** |
1216 redisplay_output_subwindow | 1046 redisplay_output_subwindow |
1047 | |
1217 | 1048 |
1218 output a subwindow. This code borrows heavily from the pixmap stuff, | 1049 output a subwindow. This code borrows heavily from the pixmap stuff, |
1219 although is much simpler not needing to account for partial | 1050 although is much simpler not needing to account for partial |
1220 pixmaps, backgrounds etc. | 1051 pixmaps, backgrounds etc. |
1221 ****************************************************************************/ | 1052 ****************************************************************************/ |
1222 void | 1053 void |
1223 redisplay_output_subwindow (struct window *w, | 1054 redisplay_output_subwindow (struct window *w, struct display_line *dl, |
1224 Lisp_Object image_instance, | 1055 Lisp_Object image_instance, int xpos, int xoffset, |
1225 struct display_box* db, struct display_glyph_area* dga, | 1056 int start_pixpos, int width, face_index findex, |
1226 face_index findex, int cursor_start, int cursor_width, | 1057 int cursor_start, int cursor_width, int cursor_height) |
1227 int cursor_height) | 1058 { |
1228 { | 1059 struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); |
1229 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); | |
1230 Lisp_Object window; | 1060 Lisp_Object window; |
1231 struct display_glyph_area sdga; | 1061 |
1232 | 1062 int lheight = dl->ascent + dl->descent - dl->clip; |
1233 dga->height = IMAGE_INSTANCE_HEIGHT (p); | 1063 int pheight = ((int) IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p) > lheight ? lheight : |
1234 dga->width = IMAGE_INSTANCE_WIDTH (p); | 1064 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p)); |
1235 | |
1236 /* The first thing we are going to do is update the display | |
1237 characteristics of the subwindow. This also clears the dirty | |
1238 flags as a side effect. */ | |
1239 update_subwindow (image_instance); | |
1240 | |
1241 /* This makes the glyph area fit into the display area. */ | |
1242 if (!redisplay_normalize_glyph_area (db, dga)) | |
1243 return; | |
1244 | 1065 |
1245 XSETWINDOW (window, w); | 1066 XSETWINDOW (window, w); |
1246 | 1067 |
1247 /* Clear the area the subwindow is going into. */ | 1068 /* Clear the area the subwindow is going into. The subwindow itself |
1248 redisplay_clear_clipped_region (window, findex, | 1069 will always take care of the full width. We don't want to clear |
1249 db, dga, 0, image_instance); | 1070 where it is going to go in order to avoid flicker. So, all we |
1250 | 1071 have to take care of is any area above or below the subwindow. Of |
1251 /* This shrinks the display box to exactly enclose the glyph | 1072 course this is rubbish if the subwindow has transparent areas |
1252 area. */ | 1073 (for instance with frames). */ |
1253 redisplay_normalize_display_box (db, dga); | 1074 /* #### We take a shortcut for now. We know that since we have |
1254 | 1075 subwindow_offset hardwired to 0 that the subwindow is against the top |
1255 /* if we can't view the whole window we can't view any of it. We | 1076 edge so all we have to worry about is below it. */ |
1256 have to be careful here since we may be being asked to display | 1077 if ((int) (dl->ypos - dl->ascent + pheight) < |
1257 part of a subwindow, the rest of which is on-screen as well. We | 1078 (int) (dl->ypos + dl->descent - dl->clip)) |
1258 need to allow this case and map the entire subwindow. We also | 1079 { |
1259 need to be careful since the subwindow could be outside the | 1080 int clear_x, clear_width; |
1260 window in the gutter or modeline - we also need to allow these | 1081 |
1261 cases.*/ | 1082 int clear_y = dl->ypos - dl->ascent + pheight; |
1262 sdga.xoffset = -dga->xoffset; | 1083 int clear_height = lheight - pheight; |
1263 sdga.yoffset = -dga->yoffset; | 1084 |
1264 sdga.height = IMAGE_INSTANCE_HEIGHT (p); | 1085 if (start_pixpos >= 0 && start_pixpos > xpos) |
1265 sdga.width = IMAGE_INSTANCE_WIDTH (p); | 1086 { |
1266 | 1087 clear_x = start_pixpos; |
1267 if (redisplay_display_boxes_in_window_p (w, db, &sdga) < 0) | 1088 clear_width = xpos + width - start_pixpos; |
1268 { | 1089 } |
1269 map_subwindow (image_instance, db->xpos, db->ypos, dga); | 1090 else |
1270 } | 1091 { |
1271 else | 1092 clear_x = xpos; |
1272 { | 1093 clear_width = width; |
1273 sdga.xoffset = sdga.yoffset = 0; | 1094 } |
1274 map_subwindow (image_instance, db->xpos - dga->xoffset, | 1095 |
1275 db->ypos - dga->yoffset, &sdga); | 1096 redisplay_clear_region (window, findex, clear_x, clear_y, |
1276 } | 1097 clear_width, clear_height); |
1277 } | 1098 } |
1278 | 1099 #if 0 |
1279 /**************************************************************************** | 1100 redisplay_clear_region (window, findex, xpos - xoffset, dl->ypos - dl->ascent, |
1280 redisplay_output_layout | 1101 width, lheight); |
1281 | |
1282 Output a widget hierarchy. This can safely call itself recursively. | |
1283 | |
1284 The complexity of outputting layouts is deciding whether to do it or | |
1285 not. Consider a layout enclosing some text, the text changes and is | |
1286 marked as dirty, but the enclosing layout has not been marked as | |
1287 dirty so no updates occur and the text will potentially be truncated. | |
1288 Alternatively we hold a back pointer in the image instance to the | |
1289 parent and mark the parent as dirty. But the layout code assumes that | |
1290 if the layout is dirty then the whole layout should be redisplayed, | |
1291 so we then get lots of flashing even though only the text has changed | |
1292 size. Of course if the text shrinks in size then we do actually need | |
1293 to redisplay the layout to repaint the exposed area. So what happens | |
1294 if we make a non-structural change like changing color? Either we | |
1295 redisplay everything, or we redisplay nothing. These are exactly the | |
1296 issues lwlib has to grapple with. We really need to know what has | |
1297 actually changed and make a layout decision based on that. We also | |
1298 really need to know what has changed so that we can only make the | |
1299 neccessary changes in update_subwindow. This has all now been | |
1300 implemented, Viva la revolution! | |
1301 ****************************************************************************/ | |
1302 void | |
1303 redisplay_output_layout (struct window *w, | |
1304 Lisp_Object image_instance, | |
1305 struct display_box* db, struct display_glyph_area* dga, | |
1306 face_index findex, int cursor_start, int cursor_width, | |
1307 int cursor_height) | |
1308 { | |
1309 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); | |
1310 Lisp_Object window, rest; | |
1311 Emchar_dynarr *buf = Dynarr_new (Emchar); | |
1312 struct frame *f = XFRAME (w->frame); | |
1313 struct device *d = XDEVICE (f->device); | |
1314 int layout_height, layout_width; | |
1315 | |
1316 XSETWINDOW (window, w); | |
1317 | |
1318 layout_height = glyph_height (image_instance, window); | |
1319 layout_width = glyph_width (image_instance, window); | |
1320 | |
1321 dga->height = layout_height; | |
1322 dga->width = layout_width; | |
1323 #ifdef DEBUG_WIDGET_OUTPUT | |
1324 printf ("outputing layout glyph %p\n", p); | |
1325 #endif | 1102 #endif |
1326 /* This makes the glyph area fit into the display area. */ | 1103 /* if we can't view the whole window we can't view any of it */ |
1327 if (!redisplay_normalize_glyph_area (db, dga)) | 1104 if (IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p) > lheight |
1328 return; | 1105 || |
1329 | 1106 IMAGE_INSTANCE_SUBWINDOW_WIDTH (p) > width) |
1330 /* Highly dodgy optimization. We want to only output the whole | 1107 { |
1331 layout if we really have to. */ | 1108 redisplay_clear_region (window, findex, xpos - xoffset, dl->ypos - dl->ascent, |
1332 if (!IMAGE_INSTANCE_OPTIMIZE_OUTPUT (p) | 1109 width, lheight); |
1333 || IMAGE_INSTANCE_LAYOUT_CHANGED (p) | 1110 unmap_subwindow (image_instance); |
1334 || IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p) | 1111 } |
1335 || IMAGE_INSTANCE_SIZE_CHANGED (p) | 1112 else |
1336 || IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)) | 1113 map_subwindow (image_instance, xpos - xoffset, dl->ypos - dl->ascent); |
1337 { | |
1338 /* First clear the area we are drawing into. This is the easiest | |
1339 thing to do since we have many gaps that we have to make sure are | |
1340 filled in. */ | |
1341 redisplay_clear_clipped_region (window, findex, db, dga, 1, Qnil); | |
1342 | |
1343 /* Output a border if required */ | |
1344 if (!NILP (IMAGE_INSTANCE_LAYOUT_BORDER (p))) | |
1345 { | |
1346 int edges = 0; | |
1347 enum edge_style style; | |
1348 int ypos = db->ypos; | |
1349 int height = dga->height; | |
1350 | |
1351 if (dga->xoffset >= 0) | |
1352 edges |= EDGE_LEFT; | |
1353 if (dga->width - dga->xoffset == layout_width) | |
1354 edges |= EDGE_RIGHT; | |
1355 if (dga->yoffset >= 0) | |
1356 edges |= EDGE_TOP; | |
1357 if (dga->height - dga->yoffset == layout_height) | |
1358 edges |= EDGE_BOTTOM; | |
1359 | |
1360 if (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (p), Qetched_in)) | |
1361 style = EDGE_ETCHED_IN; | |
1362 else if (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (p), Qetched_out)) | |
1363 style = EDGE_ETCHED_OUT; | |
1364 else if (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (p), Qbevel_in)) | |
1365 style = EDGE_BEVEL_IN; | |
1366 else if (INTP (IMAGE_INSTANCE_LAYOUT_BORDER (p))) | |
1367 { | |
1368 style = EDGE_ETCHED_IN; | |
1369 if (edges & EDGE_TOP) | |
1370 { | |
1371 ypos += XINT (IMAGE_INSTANCE_LAYOUT_BORDER (p)); | |
1372 height -= XINT (IMAGE_INSTANCE_LAYOUT_BORDER (p)); | |
1373 } | |
1374 } | |
1375 else | |
1376 style = EDGE_BEVEL_OUT; | |
1377 | |
1378 MAYBE_DEVMETH (d, bevel_area, | |
1379 (w, findex, db->xpos, | |
1380 ypos, | |
1381 dga->width, height, 2, edges, style)); | |
1382 } | |
1383 } | |
1384 | |
1385 /* This shrinks the display box to exactly enclose the glyph | |
1386 area. */ | |
1387 redisplay_normalize_display_box (db, dga); | |
1388 | |
1389 /* Flip through the widgets in the layout displaying as necessary */ | |
1390 LIST_LOOP (rest, IMAGE_INSTANCE_LAYOUT_CHILDREN (p)) | |
1391 { | |
1392 Lisp_Object child = XCAR (rest); | |
1393 | |
1394 struct display_box cdb; | |
1395 /* For losing HP-UX */ | |
1396 cdb.xpos = db->xpos; | |
1397 cdb.ypos = db->ypos; | |
1398 cdb.width = db->width; | |
1399 cdb.height = db->height; | |
1400 | |
1401 /* First determine if the image is visible at all */ | |
1402 if (IMAGE_INSTANCEP (child)) | |
1403 { | |
1404 Lisp_Image_Instance* childii = XIMAGE_INSTANCE (child); | |
1405 | |
1406 /* The enclosing layout offsets are +ve at this point */ | |
1407 struct display_glyph_area cdga; | |
1408 cdga.xoffset = IMAGE_INSTANCE_XOFFSET (childii) - dga->xoffset; | |
1409 cdga.yoffset = IMAGE_INSTANCE_YOFFSET (childii) - dga->yoffset; | |
1410 cdga.width = glyph_width (child, window); | |
1411 cdga.height = glyph_height (child, window); | |
1412 | |
1413 IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) = | |
1414 IMAGE_INSTANCE_OPTIMIZE_OUTPUT (p); | |
1415 | |
1416 /* Although normalization is done by the output routines | |
1417 we have to do it here so that they don't try and | |
1418 clear all of db. This is true below also. */ | |
1419 if (redisplay_normalize_glyph_area (&cdb, &cdga)) | |
1420 { | |
1421 redisplay_normalize_display_box (&cdb, &cdga); | |
1422 /* Since the display boxes will now be totally in the | |
1423 window if they are visible at all we can now check this easily. */ | |
1424 if (cdb.xpos < db->xpos || cdb.ypos < db->ypos | |
1425 || cdb.xpos + cdb.width > db->xpos + db->width | |
1426 || cdb.ypos + cdb.height > db->ypos + db->height) | |
1427 continue; | |
1428 /* We have to invert the offset here as normalization | |
1429 will have made them positive which the output | |
1430 routines will treat as a truly +ve offset. */ | |
1431 cdga.xoffset = -cdga.xoffset; | |
1432 cdga.yoffset = -cdga.yoffset; | |
1433 | |
1434 switch (IMAGE_INSTANCE_TYPE (childii)) | |
1435 { | |
1436 case IMAGE_TEXT: | |
1437 { | |
1438 /* #### This is well hacked and could use some | |
1439 generalisation.*/ | |
1440 if (redisplay_normalize_glyph_area (&cdb, &cdga) | |
1441 && | |
1442 (!IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) || | |
1443 IMAGE_INSTANCE_DIRTYP (childii))) | |
1444 { | |
1445 struct display_line dl; /* this is fake */ | |
1446 Lisp_Object string = | |
1447 IMAGE_INSTANCE_TEXT_STRING (childii); | |
1448 unsigned char charsets[NUM_LEADING_BYTES]; | |
1449 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, findex); | |
1450 | |
1451 find_charsets_in_bufbyte_string (charsets, | |
1452 XSTRING_DATA (string), | |
1453 XSTRING_LENGTH (string)); | |
1454 ensure_face_cachel_complete (cachel, window, charsets); | |
1455 | |
1456 convert_bufbyte_string_into_emchar_dynarr | |
1457 (XSTRING_DATA (string), XSTRING_LENGTH (string), buf); | |
1458 | |
1459 redisplay_normalize_display_box (&cdb, &cdga); | |
1460 /* Offsets are now +ve again so be careful | |
1461 when fixing up the display line. */ | |
1462 xzero (dl); | |
1463 /* Munge boxes into display lines. */ | |
1464 dl.ypos = (cdb.ypos - cdga.yoffset) | |
1465 + glyph_ascent (child, window); | |
1466 dl.ascent = glyph_ascent (child, window); | |
1467 dl.descent = glyph_descent (child, window); | |
1468 dl.top_clip = cdga.yoffset; | |
1469 dl.clip = (dl.ypos + dl.descent) - (cdb.ypos + cdb.height); | |
1470 /* output_string doesn't understand offsets in | |
1471 the same way as other routines - we have to | |
1472 add the offset to the width so that we | |
1473 output the full string. */ | |
1474 MAYBE_DEVMETH (d, output_string, (w, &dl, buf, cdb.xpos, | |
1475 cdga.xoffset, cdb.xpos, | |
1476 cdga.width + cdga.xoffset, | |
1477 findex, 0, 0, 0, 0)); | |
1478 Dynarr_reset (buf); | |
1479 } | |
1480 } | |
1481 break; | |
1482 | |
1483 case IMAGE_MONO_PIXMAP: | |
1484 case IMAGE_COLOR_PIXMAP: | |
1485 if (!IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) | |
1486 || IMAGE_INSTANCE_DIRTYP (childii)) | |
1487 redisplay_output_pixmap (w, child, &cdb, &cdga, findex, | |
1488 0, 0, 0, 0); | |
1489 break; | |
1490 | |
1491 case IMAGE_WIDGET: | |
1492 if (EQ (IMAGE_INSTANCE_WIDGET_TYPE (childii), Qlayout)) | |
1493 { | |
1494 redisplay_output_layout (w, child, &cdb, &cdga, findex, | |
1495 0, 0, 0); | |
1496 break; | |
1497 } | |
1498 case IMAGE_SUBWINDOW: | |
1499 if (!IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) || | |
1500 IMAGE_INSTANCE_DIRTYP (childii)) | |
1501 redisplay_output_subwindow (w, child, &cdb, &cdga, findex, | |
1502 0, 0, 0); | |
1503 break; | |
1504 | |
1505 case IMAGE_NOTHING: | |
1506 /* nothing is as nothing does */ | |
1507 break; | |
1508 | |
1509 case IMAGE_POINTER: | |
1510 default: | |
1511 abort (); | |
1512 } | |
1513 } | |
1514 IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) = 0; | |
1515 } | |
1516 } | |
1517 | |
1518 /* Update any display properties. I'm not sure whether this actually | |
1519 does anything for layouts except clear the changed flags. */ | |
1520 update_subwindow (image_instance); | |
1521 | |
1522 Dynarr_free (buf); | |
1523 } | |
1524 | |
1525 /**************************************************************************** | |
1526 redisplay_output_pixmap | |
1527 | |
1528 | |
1529 output a pixmap. | |
1530 ****************************************************************************/ | |
1531 void | |
1532 redisplay_output_pixmap (struct window *w, | |
1533 Lisp_Object image_instance, | |
1534 struct display_box* db, struct display_glyph_area* dga, | |
1535 face_index findex, int cursor_start, int cursor_width, | |
1536 int cursor_height, int offset_bitmap) | |
1537 { | |
1538 struct frame *f = XFRAME (w->frame); | |
1539 struct device *d = XDEVICE (f->device); | |
1540 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); | |
1541 Lisp_Object window; | |
1542 XSETWINDOW (window, w); | |
1543 | |
1544 dga->height = IMAGE_INSTANCE_PIXMAP_HEIGHT (p); | |
1545 dga->width = IMAGE_INSTANCE_PIXMAP_WIDTH (p); | |
1546 | |
1547 /* This makes the glyph area fit into the display area. */ | |
1548 if (!redisplay_normalize_glyph_area (db, dga)) | |
1549 return; | |
1550 | |
1551 /* Clear the area the pixmap is going into. The pixmap itself will | |
1552 always take care of the full width. We don't want to clear where | |
1553 it is going to go in order to avoid flicker. So, all we have to | |
1554 take care of is any area above or below the pixmap. If the pixmap | |
1555 has a mask in which case we have to clear the whole damn thing | |
1556 since we can't yet clear just the area not included in the | |
1557 mask. */ | |
1558 if (!offset_bitmap) | |
1559 { | |
1560 redisplay_clear_clipped_region (window, findex, | |
1561 db, dga, | |
1562 (int)IMAGE_INSTANCE_PIXMAP_MASK (p), | |
1563 Qnil); | |
1564 | |
1565 /* This shrinks the display box to exactly enclose the glyph | |
1566 area. */ | |
1567 redisplay_normalize_display_box (db, dga); | |
1568 } | |
1569 assert (db->xpos >= 0 && db->ypos >= 0); | |
1570 | |
1571 MAYBE_DEVMETH (d, output_pixmap, (w, image_instance, | |
1572 db, dga, | |
1573 findex, cursor_start, | |
1574 cursor_width, cursor_height, | |
1575 offset_bitmap)); | |
1576 } | 1114 } |
1577 | 1115 |
1578 /**************************************************************************** | 1116 /**************************************************************************** |
1579 redisplay_clear_region | 1117 redisplay_clear_region |
1580 | 1118 |
1609 abort (); | 1147 abort (); |
1610 | 1148 |
1611 d = XDEVICE (f->device); | 1149 d = XDEVICE (f->device); |
1612 | 1150 |
1613 /* if we have subwindows in the region we have to unmap them */ | 1151 /* if we have subwindows in the region we have to unmap them */ |
1614 redisplay_unmap_subwindows_maybe (f, x, y, width, height); | 1152 if (Dynarr_length (FRAME_SUBWINDOW_CACHE (f))) |
1153 { | |
1154 redisplay_unmap_subwindows (f, x, y, width, height); | |
1155 } | |
1615 | 1156 |
1616 /* #### This isn't quite right for when this function is called | 1157 /* #### This isn't quite right for when this function is called |
1617 from the toolbar code. */ | 1158 from the toolbar code. */ |
1618 | 1159 |
1619 /* Don't use a backing pixmap in the border area */ | 1160 /* Don't use a backing pixmap in the border area */ |
1620 if (x >= FRAME_LEFT_BORDER_END (f) | 1161 if (x >= FRAME_LEFT_BORDER_END (f) |
1621 && x < FRAME_RIGHT_BORDER_START (f) | 1162 && x < FRAME_RIGHT_BORDER_START (f) |
1622 && y >= FRAME_TOP_BORDER_END (f) | 1163 && y >= FRAME_TOP_BORDER_END (f) |
1623 && y < FRAME_BOTTOM_BORDER_START (f)) | 1164 && y < FRAME_BOTTOM_BORDER_START (f)) |
1624 { | 1165 { |
1625 Lisp_Object temp; | 1166 Lisp_Object temp; |
1626 | 1167 |
1627 if (w) | 1168 if (w) |
1628 { | 1169 { |
1629 temp = WINDOW_FACE_CACHEL_BACKGROUND_PIXMAP (w, findex); | 1170 temp = WINDOW_FACE_CACHEL_BACKGROUND_PIXMAP (w, findex); |
1630 | 1171 |
1631 if (IMAGE_INSTANCEP (temp) | 1172 if (IMAGE_INSTANCEP (temp) |
1632 && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (temp))) | 1173 && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (temp))) |
1633 { | 1174 { |
1634 /* #### maybe we could implement such that a string | 1175 /* #### maybe we could implement such that a string |
1635 can be a background pixmap? */ | 1176 can be a background pixmap? */ |
1637 } | 1178 } |
1638 } | 1179 } |
1639 else | 1180 else |
1640 { | 1181 { |
1641 temp = FACE_BACKGROUND_PIXMAP (Vdefault_face, locale); | 1182 temp = FACE_BACKGROUND_PIXMAP (Vdefault_face, locale); |
1642 | 1183 |
1643 if (IMAGE_INSTANCEP (temp) | 1184 if (IMAGE_INSTANCEP (temp) |
1644 && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (temp))) | 1185 && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (temp))) |
1645 { | 1186 { |
1646 background_pixmap = temp; | 1187 background_pixmap = temp; |
1647 } | 1188 } |
1648 } | 1189 } |
1649 } | 1190 } |
1650 | 1191 |
1651 if (!UNBOUNDP (background_pixmap) && | 1192 if (!UNBOUNDP (background_pixmap) && |
1652 XIMAGE_INSTANCE_PIXMAP_DEPTH (background_pixmap) == 0) | 1193 XIMAGE_INSTANCE_PIXMAP_DEPTH (background_pixmap) == 0) |
1653 { | 1194 { |
1654 if (w) | 1195 if (w) |
1665 else | 1206 else |
1666 { | 1207 { |
1667 fcolor = (w ? | 1208 fcolor = (w ? |
1668 WINDOW_FACE_CACHEL_BACKGROUND (w, findex) : | 1209 WINDOW_FACE_CACHEL_BACKGROUND (w, findex) : |
1669 FACE_BACKGROUND (Vdefault_face, locale)); | 1210 FACE_BACKGROUND (Vdefault_face, locale)); |
1670 | 1211 |
1671 } | 1212 } |
1672 | 1213 |
1673 if (UNBOUNDP (background_pixmap)) | 1214 if (UNBOUNDP (background_pixmap)) |
1674 background_pixmap = Qnil; | 1215 background_pixmap = Qnil; |
1675 | 1216 |
1676 DEVMETH (d, clear_region, | 1217 DEVMETH (d, clear_region, |
1677 (locale, d, f, findex, x, y, width, height, fcolor, bcolor, background_pixmap)); | 1218 (locale, d, f, findex, x, y, width, height, fcolor, bcolor, background_pixmap)); |
1678 } | |
1679 | |
1680 /**************************************************************************** | |
1681 redisplay_clear_clipped_region | |
1682 | |
1683 Clear the area in the dest display_box not covered by the src | |
1684 display_glyph_area using the given face. This is a common occurance | |
1685 for images shorter than the display line. Clipping can be played | |
1686 around with by altering these. glyphsrc should be normalized. | |
1687 ****************************************************************************/ | |
1688 static void | |
1689 redisplay_clear_clipped_region (Lisp_Object window, face_index findex, | |
1690 struct display_box* dest, struct display_glyph_area* glyphsrc, | |
1691 int fullheight_p, Lisp_Object ignored_subwindow) | |
1692 { | |
1693 /* assume dest->xpos >= 0 */ | |
1694 int clear_x; | |
1695 struct frame* f = XFRAME (XWINDOW (window)->frame); | |
1696 | |
1697 if (glyphsrc->xoffset > 0) | |
1698 { | |
1699 clear_x = dest->xpos + glyphsrc->xoffset; | |
1700 } | |
1701 else | |
1702 { | |
1703 clear_x = dest->xpos; | |
1704 } | |
1705 | |
1706 /* If we need the whole height cleared then just do it. */ | |
1707 if (fullheight_p) | |
1708 { | |
1709 redisplay_clear_region (window, findex, clear_x, dest->ypos, | |
1710 glyphsrc->width, dest->height); | |
1711 } | |
1712 else | |
1713 { | |
1714 int yoffset = (glyphsrc->yoffset > 0 ? glyphsrc->yoffset : 0); | |
1715 | |
1716 /* We need to make sure that subwindows are unmapped from the | |
1717 whole area. */ | |
1718 redisplay_unmap_subwindows_except_us (f, clear_x, dest->ypos, | |
1719 glyphsrc->width, dest->height, | |
1720 ignored_subwindow); | |
1721 /* first the top box */ | |
1722 if (yoffset > 0) | |
1723 { | |
1724 redisplay_clear_region (window, findex, clear_x, dest->ypos, | |
1725 glyphsrc->width, yoffset); | |
1726 | |
1727 } | |
1728 /* Then the bottom box */ | |
1729 if (yoffset + glyphsrc->height < dest->height) | |
1730 { | |
1731 redisplay_clear_region (window, findex, clear_x, | |
1732 dest->ypos + yoffset + glyphsrc->height, | |
1733 glyphsrc->width, | |
1734 dest->height - (yoffset + glyphsrc->height)); | |
1735 | |
1736 } | |
1737 } | |
1738 } | |
1739 | |
1740 /***************************************************************************** | |
1741 redisplay_normalize_glyph_area | |
1742 redisplay_normalize_display_box | |
1743 | |
1744 Calculate the visible box for displaying src in dest. | |
1745 ****************************************************************************/ | |
1746 int | |
1747 redisplay_normalize_glyph_area (struct display_box* dest, | |
1748 struct display_glyph_area* glyphsrc) | |
1749 { | |
1750 if (dest->xpos + glyphsrc->xoffset > dest->xpos + dest->width | |
1751 || | |
1752 dest->ypos + glyphsrc->yoffset > dest->ypos + dest->height | |
1753 || | |
1754 -glyphsrc->xoffset >= glyphsrc->width | |
1755 || | |
1756 -glyphsrc->yoffset >= glyphsrc->height) | |
1757 { | |
1758 /* It's all clipped out */ | |
1759 return 0; | |
1760 } | |
1761 | |
1762 /* Horizontal offsets. This works because xoffset can be -ve as well as +ve */ | |
1763 if (dest->xpos + glyphsrc->xoffset + glyphsrc->width > dest->xpos + dest->width) | |
1764 { | |
1765 if (glyphsrc->xoffset > 0) | |
1766 glyphsrc->width = dest->width - glyphsrc->xoffset; | |
1767 else | |
1768 glyphsrc->width = dest->width; | |
1769 } | |
1770 | |
1771 if (glyphsrc->xoffset < 0) | |
1772 glyphsrc->width += glyphsrc->xoffset; | |
1773 | |
1774 /* Vertical offsets. This works because yoffset can be -ve as well as +ve */ | |
1775 if (dest->ypos + glyphsrc->yoffset + glyphsrc->height > dest->ypos + dest->height) | |
1776 { | |
1777 if (glyphsrc->yoffset > 0) | |
1778 glyphsrc->height = dest->height - glyphsrc->yoffset; | |
1779 else | |
1780 glyphsrc->height = dest->height; | |
1781 } | |
1782 | |
1783 if (glyphsrc->yoffset < 0) | |
1784 glyphsrc->height += glyphsrc->yoffset; | |
1785 | |
1786 return 1; | |
1787 } | |
1788 | |
1789 static void | |
1790 redisplay_normalize_display_box (struct display_box* dest, | |
1791 struct display_glyph_area* glyphsrc) | |
1792 { | |
1793 /* Adjust the destination area. At the end of this the destination | |
1794 area will exactly enclose the glyph area. The only remaining | |
1795 adjustment will be offsets into the glyph area. */ | |
1796 | |
1797 /* Horizontal adjustment. */ | |
1798 if (glyphsrc->xoffset > 0) | |
1799 { | |
1800 dest->xpos += glyphsrc->xoffset; | |
1801 dest->width -= glyphsrc->xoffset; | |
1802 glyphsrc->xoffset = 0; | |
1803 } | |
1804 else | |
1805 glyphsrc->xoffset = -glyphsrc->xoffset; | |
1806 | |
1807 if (glyphsrc->width < dest->width) | |
1808 dest->width = glyphsrc->width; | |
1809 | |
1810 /* Vertical adjustment. */ | |
1811 if (glyphsrc->yoffset > 0) | |
1812 { | |
1813 dest->ypos += glyphsrc->yoffset; | |
1814 dest->height -= glyphsrc->yoffset; | |
1815 glyphsrc->yoffset = 0; | |
1816 } | |
1817 else | |
1818 glyphsrc->yoffset = -glyphsrc->yoffset; | |
1819 | |
1820 if (glyphsrc->height < dest->height) | |
1821 dest->height = glyphsrc->height; | |
1822 } | |
1823 | |
1824 /***************************************************************************** | |
1825 redisplay_display_boxes_in_window_p | |
1826 | |
1827 Determine whether the require display_glyph_area is completely inside | |
1828 the window. 0 means the display_box is not in the window. 1 means the | |
1829 display_box and the display_glyph_area are in the window. -1 means | |
1830 the display_box is in the window but the display_glyph_area is not. | |
1831 ****************************************************************************/ | |
1832 static int | |
1833 redisplay_display_boxes_in_window_p (struct window* w, | |
1834 struct display_box* db, | |
1835 struct display_glyph_area* dga) | |
1836 { | |
1837 int left = WINDOW_TEXT_LEFT (w); | |
1838 int right = WINDOW_TEXT_RIGHT (w); | |
1839 int top = WINDOW_TEXT_TOP (w); | |
1840 int bottom = WINDOW_TEXT_BOTTOM (w); | |
1841 | |
1842 if (db->xpos < left || db->ypos < top | |
1843 || db->xpos + db->width > right | |
1844 || db->ypos + db->height > bottom) | |
1845 /* We are not displaying in a window at all */ | |
1846 return 0; | |
1847 | |
1848 if (db->xpos + dga->xoffset >= left | |
1849 && | |
1850 db->ypos + dga->yoffset >= top | |
1851 && | |
1852 db->xpos + dga->xoffset + dga->width <= right | |
1853 && | |
1854 db->ypos + dga->yoffset + dga->height <= bottom) | |
1855 return 1; | |
1856 | |
1857 return -1; | |
1858 } | |
1859 | |
1860 /***************************************************************************** | |
1861 redisplay_calculate_display_boxes | |
1862 | |
1863 Convert from rune/display_line co-ordinates to display_box | |
1864 co-ordinates. | |
1865 ****************************************************************************/ | |
1866 int | |
1867 redisplay_calculate_display_boxes (struct display_line *dl, int xpos, | |
1868 int xoffset, int start_pixpos, int width, | |
1869 struct display_box* dest, | |
1870 struct display_glyph_area* src) | |
1871 { | |
1872 dest->xpos = xpos; | |
1873 dest->ypos = DISPLAY_LINE_YPOS (dl); | |
1874 dest->width = width; | |
1875 dest->height = DISPLAY_LINE_HEIGHT (dl); | |
1876 | |
1877 src->xoffset = -xoffset; | |
1878 src->yoffset = -dl->top_clip; | |
1879 src->width = 0; | |
1880 src->height = 0; | |
1881 | |
1882 if (start_pixpos >=0 && start_pixpos > xpos) | |
1883 { | |
1884 /* Oops, we're asking for a start outside of the displayable | |
1885 area. */ | |
1886 if (start_pixpos > xpos + width) | |
1887 return 0; | |
1888 dest->xpos = start_pixpos; | |
1889 dest->width -= (start_pixpos - xpos); | |
1890 /* Offsets are -ve when we want to clip pixels off the displayed | |
1891 glyph. */ | |
1892 src->xoffset -= (start_pixpos - xpos); | |
1893 } | |
1894 | |
1895 return 1; | |
1896 } | 1219 } |
1897 | 1220 |
1898 /***************************************************************************** | 1221 /***************************************************************************** |
1899 redisplay_clear_top_of_window | 1222 redisplay_clear_top_of_window |
1900 | 1223 |
1924 | 1247 |
1925 y = FRAME_TOP_BORDER_START (f) - 1; | 1248 y = FRAME_TOP_BORDER_START (f) - 1; |
1926 height = FRAME_BORDER_HEIGHT (f) + 1; | 1249 height = FRAME_BORDER_HEIGHT (f) + 1; |
1927 | 1250 |
1928 redisplay_clear_region (window, DEFAULT_INDEX, x, y, width, height); | 1251 redisplay_clear_region (window, DEFAULT_INDEX, x, y, width, height); |
1929 } | |
1930 } | |
1931 | |
1932 /***************************************************************************** | |
1933 redisplay_clear_to_window_end | |
1934 | |
1935 Clear the area between ypos1 and ypos2. Each margin area and the | |
1936 text area is handled separately since they may each have their own | |
1937 background color. | |
1938 ****************************************************************************/ | |
1939 void | |
1940 redisplay_clear_to_window_end (struct window *w, int ypos1, int ypos2) | |
1941 { | |
1942 struct frame *f = XFRAME (w->frame); | |
1943 struct device *d = XDEVICE (f->device); | |
1944 | |
1945 if (HAS_DEVMETH_P (d, clear_to_window_end)) | |
1946 DEVMETH (d, clear_to_window_end, (w, ypos1, ypos2)); | |
1947 else | |
1948 { | |
1949 int height = ypos2 - ypos1; | |
1950 | |
1951 if (height) | |
1952 { | |
1953 Lisp_Object window; | |
1954 int bflag = 0 ; /* (window_needs_vertical_divider (w) ? 0 : 1);*/ | |
1955 layout_bounds bounds; | |
1956 | |
1957 bounds = calculate_display_line_boundaries (w, bflag); | |
1958 XSETWINDOW (window, w); | |
1959 | |
1960 if (window_is_leftmost (w)) | |
1961 redisplay_clear_region (window, DEFAULT_INDEX, FRAME_LEFT_BORDER_START (f), | |
1962 ypos1, FRAME_BORDER_WIDTH (f), height); | |
1963 | |
1964 if (bounds.left_in - bounds.left_out > 0) | |
1965 redisplay_clear_region (window, | |
1966 get_builtin_face_cache_index (w, Vleft_margin_face), | |
1967 bounds.left_out, ypos1, | |
1968 bounds.left_in - bounds.left_out, height); | |
1969 | |
1970 if (bounds.right_in - bounds.left_in > 0) | |
1971 redisplay_clear_region (window, | |
1972 DEFAULT_INDEX, | |
1973 bounds.left_in, ypos1, | |
1974 bounds.right_in - bounds.left_in, height); | |
1975 | |
1976 if (bounds.right_out - bounds.right_in > 0) | |
1977 redisplay_clear_region (window, | |
1978 get_builtin_face_cache_index (w, Vright_margin_face), | |
1979 bounds.right_in, ypos1, | |
1980 bounds.right_out - bounds.right_in, height); | |
1981 | |
1982 if (window_is_rightmost (w)) | |
1983 redisplay_clear_region (window, DEFAULT_INDEX, FRAME_RIGHT_BORDER_START (f), | |
1984 ypos1, FRAME_BORDER_WIDTH (f), height); | |
1985 } | |
1986 } | 1252 } |
1987 } | 1253 } |
1988 | 1254 |
1989 /***************************************************************************** | 1255 /***************************************************************************** |
1990 redisplay_clear_bottom_of_window | 1256 redisplay_clear_bottom_of_window |
1996 void | 1262 void |
1997 redisplay_clear_bottom_of_window (struct window *w, display_line_dynarr *ddla, | 1263 redisplay_clear_bottom_of_window (struct window *w, display_line_dynarr *ddla, |
1998 int min_start, int max_end) | 1264 int min_start, int max_end) |
1999 { | 1265 { |
2000 struct frame *f = XFRAME (w->frame); | 1266 struct frame *f = XFRAME (w->frame); |
1267 struct device *d = XDEVICE (f->device); | |
2001 int ypos1, ypos2; | 1268 int ypos1, ypos2; |
2002 int ddla_len = Dynarr_length (ddla); | 1269 int ddla_len = Dynarr_length (ddla); |
2003 | 1270 |
2004 ypos2 = WINDOW_TEXT_BOTTOM (w); | 1271 ypos2 = WINDOW_TEXT_BOTTOM (w); |
2005 #ifdef HAVE_SCROLLBARS | 1272 #ifdef HAVE_SCROLLBARS |
2039 ypos2 = max_end; | 1306 ypos2 = max_end; |
2040 | 1307 |
2041 if (ypos2 <= ypos1) | 1308 if (ypos2 <= ypos1) |
2042 return; | 1309 return; |
2043 | 1310 |
2044 redisplay_clear_to_window_end (w, ypos1, ypos2); | 1311 DEVMETH (d, clear_to_window_end, (w, ypos1, ypos2)); |
2045 } | 1312 } |
2046 | 1313 |
2047 /***************************************************************************** | 1314 /***************************************************************************** |
2048 redisplay_update_line | 1315 redisplay_update_line |
2049 | 1316 |
2059 struct device *d = XDEVICE (f->device); | 1326 struct device *d = XDEVICE (f->device); |
2060 | 1327 |
2061 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP); | 1328 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP); |
2062 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP); | 1329 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP); |
2063 | 1330 |
2064 MAYBE_DEVMETH (d, window_output_begin, (w)); | 1331 DEVMETH (d, output_begin, (d)); |
2065 | 1332 |
2066 while (first_line <= last_line) | 1333 while (first_line <= last_line) |
2067 { | 1334 { |
2068 Charcount old_len = (Dynarr_atp (cdla, first_line)->end_bufpos - | 1335 Charcount old_len = (Dynarr_atp (cdla, first_line)->end_bufpos - |
2069 Dynarr_atp (cdla, first_line)->bufpos); | 1336 Dynarr_atp (cdla, first_line)->bufpos); |
2144 update_window_scrollbars (w, NULL, 1, stupid_vertical_scrollbar_drag_hack); | 1411 update_window_scrollbars (w, NULL, 1, stupid_vertical_scrollbar_drag_hack); |
2145 stupid_vertical_scrollbar_drag_hack = 1; | 1412 stupid_vertical_scrollbar_drag_hack = 1; |
2146 } | 1413 } |
2147 #endif | 1414 #endif |
2148 | 1415 |
2149 redisplay_redraw_cursor (f, 0); | 1416 /* This has to be done after we've updated the values. We don't |
2150 MAYBE_DEVMETH (d, window_output_end, (w)); | 1417 call output_end for tty frames. Redisplay will do this after all |
1418 tty windows have been updated. This cuts down on cursor | |
1419 flicker. */ | |
1420 if (FRAME_TTY_P (f)) | |
1421 redisplay_redraw_cursor (f, 0); | |
1422 else | |
1423 DEVMETH (d, output_end, (d)); | |
2151 } | 1424 } |
2152 | 1425 |
2153 /***************************************************************************** | 1426 /***************************************************************************** |
2154 redisplay_output_window | 1427 redisplay_output_window |
2155 | 1428 |
2259 } | 1532 } |
2260 } | 1533 } |
2261 } | 1534 } |
2262 | 1535 |
2263 /* Perform any output initialization. */ | 1536 /* Perform any output initialization. */ |
2264 MAYBE_DEVMETH (d, window_output_begin, (w)); | 1537 DEVMETH (d, output_begin, (d)); |
2265 | 1538 |
2266 /* If the window's structure has changed clear the internal border | 1539 /* If the window's structure has changed clear the internal border |
2267 above it if it is topmost (the function will check). */ | 1540 above it if it is topmost (the function will check). */ |
2268 if (f->windows_structure_changed) | 1541 if (f->windows_structure_changed) |
2269 redisplay_clear_top_of_window (w); | 1542 redisplay_clear_top_of_window (w); |
2282 | 1555 |
2283 /* Output a vertical divider between windows, if necessary. */ | 1556 /* Output a vertical divider between windows, if necessary. */ |
2284 if (window_needs_vertical_divider (w) | 1557 if (window_needs_vertical_divider (w) |
2285 && (f->windows_structure_changed || f->clear)) | 1558 && (f->windows_structure_changed || f->clear)) |
2286 { | 1559 { |
2287 MAYBE_DEVMETH (d, output_vertical_divider, (w, f->windows_structure_changed)); | 1560 DEVMETH (d, output_vertical_divider, (w, f->windows_structure_changed)); |
2288 } | 1561 } |
2289 | 1562 |
2290 /* Clear the rest of the window, if necessary. */ | 1563 /* Clear the rest of the window, if necessary. */ |
2291 if (need_to_clear_bottom) | 1564 if (need_to_clear_bottom) |
2292 { | 1565 { |
2316 | 1589 |
2317 /* Overkill on invalidating the cache. It is very bad for it to not | 1590 /* Overkill on invalidating the cache. It is very bad for it to not |
2318 get invalidated when it should be. */ | 1591 get invalidated when it should be. */ |
2319 INVALIDATE_DEVICE_PIXEL_TO_GLYPH_CACHE (d); | 1592 INVALIDATE_DEVICE_PIXEL_TO_GLYPH_CACHE (d); |
2320 | 1593 |
2321 redisplay_redraw_cursor (f, 0); | 1594 /* We don't call output_end for tty frames. Redisplay will do this |
2322 MAYBE_DEVMETH (d, window_output_end, (w)); | 1595 after all tty windows have been updated. This cuts down on |
1596 cursor flicker. */ | |
1597 if (FRAME_TTY_P (f)) | |
1598 redisplay_redraw_cursor (f, 0); | |
1599 else | |
1600 DEVMETH (d, output_end, (d)); | |
2323 | 1601 |
2324 #ifdef HAVE_SCROLLBARS | 1602 #ifdef HAVE_SCROLLBARS |
2325 update_window_scrollbars (w, NULL, !MINI_WINDOW_P (w), 0); | 1603 update_window_scrollbars (w, NULL, !MINI_WINDOW_P (w), 0); |
2326 #endif | 1604 #endif |
2327 } | 1605 } |
2328 | |
2329 /***************************************************************************** | |
2330 bevel_modeline | |
2331 | |
2332 Draw a 3d border around the modeline on window W. | |
2333 ****************************************************************************/ | |
2334 void | |
2335 bevel_modeline (struct window *w, struct display_line *dl) | |
2336 { | |
2337 struct frame *f = XFRAME (w->frame); | |
2338 struct device *d = XDEVICE (f->device); | |
2339 int x, y, width, height; | |
2340 int shadow_thickness = MODELINE_SHADOW_THICKNESS (w); | |
2341 enum edge_style style; | |
2342 | |
2343 x = WINDOW_MODELINE_LEFT (w); | |
2344 width = WINDOW_MODELINE_RIGHT (w) - x; | |
2345 y = dl->ypos - dl->ascent - shadow_thickness; | |
2346 height = dl->ascent + dl->descent + 2 * shadow_thickness; | |
2347 | |
2348 if (XINT (w->modeline_shadow_thickness) < 0) | |
2349 { | |
2350 style = EDGE_BEVEL_IN; | |
2351 } | |
2352 else | |
2353 { | |
2354 style = EDGE_BEVEL_OUT; | |
2355 } | |
2356 | |
2357 MAYBE_DEVMETH (d, bevel_area, | |
2358 (w, MODELINE_INDEX, x, y, width, height, shadow_thickness, | |
2359 EDGE_ALL, style)); | |
2360 } |