Mercurial > hg > xemacs-beta
comparison src/redisplay-output.c @ 442:abe6d1db359e r21-2-36
Import from CVS: tag r21-2-36
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:35:02 +0200 |
parents | 8de8e3f6228a |
children | 1ccc32a20af4 |
comparison
equal
deleted
inserted
replaced
441:72a7cfa4a488 | 442:abe6d1db359e |
---|---|
99 sync_display_line_structs | 99 sync_display_line_structs |
100 | 100 |
101 For the given LINE in window W, make the current display line equal | 101 For the given LINE in window W, make the current display line equal |
102 the desired display line. | 102 the desired display line. |
103 ****************************************************************************/ | 103 ****************************************************************************/ |
104 static void | 104 void |
105 sync_display_line_structs (struct window *w, int line, int do_blocks, | 105 sync_display_line_structs (struct window *w, int line, int do_blocks, |
106 display_line_dynarr *cdla, | 106 display_line_dynarr *cdla, |
107 display_line_dynarr *ddla) | 107 display_line_dynarr *ddla) |
108 { | 108 { |
109 int cdla_len = Dynarr_length (cdla); | 109 int cdla_len = Dynarr_length (cdla); |
209 So I (JV) conjecture | 209 So I (JV) conjecture |
210 | 210 |
211 #### It would really be worth it to arrange for this function to | 211 #### It would really be worth it to arrange for this function to |
212 be (almost) a single call to memcmp. */ | 212 be (almost) a single call to memcmp. */ |
213 | 213 |
214 if ((crb->findex != drb->findex) || | 214 if (crb->xpos != drb->xpos) |
215 (WINDOW_FACE_CACHEL_DIRTY (w, drb->findex))) | |
216 return 0; | |
217 else if (crb->xpos != drb->xpos) | |
218 return 0; | 215 return 0; |
219 else if (crb->width != drb->width) | 216 else if (crb->width != drb->width) |
220 return 0; | 217 return 0; |
221 else if (crb->cursor_type != drb->cursor_type) | 218 else if (crb->cursor_type != drb->cursor_type) |
222 return 0; | 219 return 0; |
234 !EQ (crb->object.dglyph.extent, drb->object.dglyph.extent) || | 231 !EQ (crb->object.dglyph.extent, drb->object.dglyph.extent) || |
235 crb->object.dglyph.xoffset != drb->object.dglyph.xoffset)) | 232 crb->object.dglyph.xoffset != drb->object.dglyph.xoffset)) |
236 return 0; | 233 return 0; |
237 /* Only check dirtiness if we know something has changed. */ | 234 /* Only check dirtiness if we know something has changed. */ |
238 else if (crb->type == RUNE_DGLYPH && | 235 else if (crb->type == RUNE_DGLYPH && |
239 XFRAME (w->frame)->glyphs_changed) | 236 (XGLYPH_DIRTYP (crb->object.dglyph.glyph) || |
240 { | 237 crb->findex != drb->findex)) |
241 glyph_index gindex = get_glyph_cachel_index (w, drb->object.dglyph.glyph); | 238 { |
242 /* Although doing the cachel lookup for every comparison is | 239 /* We need some way of telling redisplay_output_layout () that the |
243 very expensive.we have to do it to make sure the cache is | 240 only reason we are outputting it is because something has |
244 up-to-date. */ | 241 changed internally. That way we can optimize whether we need |
245 if (GLYPH_CACHEL_DIRTYP (w, gindex)) | 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)) | |
246 return 0; | 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 for 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 } | |
247 else | 286 else |
248 return 1; | 287 return 1; |
249 } | 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; | |
250 else | 298 else |
251 return 1; | 299 return 1; |
252 } | 300 } |
253 | 301 |
254 /***************************************************************************** | 302 /***************************************************************************** |
848 dl->cursor_elt = x; | 896 dl->cursor_elt = x; |
849 return 1; | 897 return 1; |
850 } | 898 } |
851 else | 899 else |
852 { | 900 { |
853 DEVMETH (d, output_begin, (d)); | 901 { |
854 | 902 MAYBE_DEVMETH (d, frame_output_begin, (f)); |
855 /* #### This is a gross kludge. Cursor handling is such a royal | 903 MAYBE_DEVMETH (d, window_output_begin, (w)); |
856 pain in the ass. */ | 904 } |
857 if (rb->type == RUNE_DGLYPH && | 905 rb->cursor_type = CURSOR_OFF; |
858 (EQ (rb->object.dglyph.glyph, Vtruncation_glyph) || | |
859 EQ (rb->object.dglyph.glyph, Vcontinuation_glyph))) | |
860 rb->cursor_type = NO_CURSOR; | |
861 else | |
862 rb->cursor_type = CURSOR_OFF; | |
863 dl->cursor_elt = -1; | 906 dl->cursor_elt = -1; |
864 output_display_line (w, 0, cla, y, rb->xpos, rb->xpos + rb->width); | 907 output_display_line (w, 0, cla, y, rb->xpos, rb->xpos + rb->width); |
865 } | 908 } |
866 | 909 |
867 w->last_point_x[CURRENT_DISP] = -1; | 910 w->last_point_x[CURRENT_DISP] = -1; |
871 /* If this isn't the selected frame, then erasing the old cursor is | 914 /* If this isn't the selected frame, then erasing the old cursor is |
872 all we actually had to do. */ | 915 all we actually had to do. */ |
873 if (w != XWINDOW (FRAME_SELECTED_WINDOW (device_selected_frame (d)))) | 916 if (w != XWINDOW (FRAME_SELECTED_WINDOW (device_selected_frame (d)))) |
874 { | 917 { |
875 if (!no_output_end) | 918 if (!no_output_end) |
876 DEVMETH (d, output_end, (d)); | 919 { |
920 MAYBE_DEVMETH (d, window_output_end, (w)); | |
921 MAYBE_DEVMETH (d, frame_output_end, (f)); | |
922 } | |
877 | 923 |
878 return 1; | 924 return 1; |
879 } | 925 } |
880 | 926 |
881 /* This should only occur in the minibuffer. */ | 927 /* This should only occur in the minibuffer. */ |
890 dl->cursor_elt = 0; | 936 dl->cursor_elt = 0; |
891 | 937 |
892 output_display_line (w, 0, cla, y, rb->xpos, rb->xpos + rb->width); | 938 output_display_line (w, 0, cla, y, rb->xpos, rb->xpos + rb->width); |
893 | 939 |
894 if (!no_output_end) | 940 if (!no_output_end) |
895 DEVMETH (d, output_end, (d)); | 941 { |
942 MAYBE_DEVMETH (d, window_output_end, (w)); | |
943 MAYBE_DEVMETH (d, frame_output_end, (f)); | |
944 } | |
896 return 1; | 945 return 1; |
897 } | 946 } |
898 else | 947 else |
899 { | 948 { |
900 int cur_rb = 0; | 949 int cur_rb = 0; |
954 w->last_point_y[CURRENT_DISP] = cur_dl; | 1003 w->last_point_y[CURRENT_DISP] = cur_dl; |
955 Fset_marker (w->last_point[CURRENT_DISP], | 1004 Fset_marker (w->last_point[CURRENT_DISP], |
956 make_int (ADJ_BUFPOS), w->buffer); | 1005 make_int (ADJ_BUFPOS), w->buffer); |
957 | 1006 |
958 if (!no_output_end) | 1007 if (!no_output_end) |
959 DEVMETH (d, output_end, (d)); | 1008 { |
1009 MAYBE_DEVMETH (d, window_output_end, (w)); | |
1010 MAYBE_DEVMETH (d, frame_output_end, (f)); | |
1011 } | |
960 return 1; | 1012 return 1; |
961 } | 1013 } |
962 | 1014 |
963 (up ? cur_rb++ : cur_rb--); | 1015 (up ? cur_rb++ : cur_rb--); |
964 } | 1016 } |
967 (up ? cur_dl++ : cur_dl--); | 1019 (up ? cur_dl++ : cur_dl--); |
968 } | 1020 } |
969 } | 1021 } |
970 | 1022 |
971 if (!no_output_end) | 1023 if (!no_output_end) |
972 DEVMETH (d, output_end, (d)); | 1024 { |
1025 MAYBE_DEVMETH (d, window_output_end, (w)); | |
1026 MAYBE_DEVMETH (d, frame_output_end, (f)); | |
1027 } | |
973 return 0; | 1028 return 0; |
974 } | 1029 } |
975 #undef ADJ_BUFPOS | 1030 #undef ADJ_BUFPOS |
976 #undef ADJ_ENDPOS | 1031 #undef ADJ_ENDPOS |
977 | 1032 |
1022 { | 1077 { |
1023 MAYBE_DEVMETH (d, set_final_cursor_coords, | 1078 MAYBE_DEVMETH (d, set_final_cursor_coords, |
1024 (f, dl->ypos - 1, rb->xpos)); | 1079 (f, dl->ypos - 1, rb->xpos)); |
1025 | 1080 |
1026 if (run_end_begin_meths) | 1081 if (run_end_begin_meths) |
1027 DEVMETH (d, output_begin, (d)); | 1082 { |
1083 MAYBE_DEVMETH (d, frame_output_begin, (f)); | |
1084 MAYBE_DEVMETH (d, window_output_begin, (w)); | |
1085 } | |
1028 | 1086 |
1029 output_display_line (w, 0, dla, y, rb->xpos, rb->xpos + rb->width); | 1087 output_display_line (w, 0, dla, y, rb->xpos, rb->xpos + rb->width); |
1030 | 1088 |
1031 if (run_end_begin_meths) | 1089 if (run_end_begin_meths) |
1032 DEVMETH (d, output_end, (d)); | 1090 { |
1091 MAYBE_DEVMETH (d, window_output_end, (w)); | |
1092 MAYBE_DEVMETH (d, frame_output_end, (f)); | |
1093 } | |
1033 } | 1094 } |
1034 } | 1095 } |
1035 | 1096 |
1036 /***************************************************************************** | 1097 /***************************************************************************** |
1037 redisplay_redraw_cursor | 1098 redisplay_redraw_cursor |
1065 int start, int end, int start_pixpos, int cursor_start, | 1126 int start, int end, int start_pixpos, int cursor_start, |
1066 int cursor_width, int cursor_height) | 1127 int cursor_width, int cursor_height) |
1067 { | 1128 { |
1068 struct frame *f = XFRAME (w->frame); | 1129 struct frame *f = XFRAME (w->frame); |
1069 struct device *d = XDEVICE (f->device); | 1130 struct device *d = XDEVICE (f->device); |
1131 /* Temporarily disabled until generalization is done. */ | |
1132 #if 0 | |
1070 struct display_block *db = Dynarr_atp (dl->display_blocks, block); | 1133 struct display_block *db = Dynarr_atp (dl->display_blocks, block); |
1071 rune_dynarr *rba = db->runes; | 1134 rune_dynarr *rba = db->runes; |
1072 struct rune *rb; | 1135 struct rune *rb; |
1073 int xpos, width; | 1136 int xpos, width; |
1074 rb = Dynarr_atp (rba, start); | 1137 rb = Dynarr_atp (rba, start); |
1082 if (end < 0) | 1145 if (end < 0) |
1083 end = Dynarr_length (rba); | 1146 end = Dynarr_length (rba); |
1084 | 1147 |
1085 rb = Dynarr_atp (rba, end - 1); | 1148 rb = Dynarr_atp (rba, end - 1); |
1086 width = rb->xpos + rb->width - xpos; | 1149 width = rb->xpos + rb->width - xpos; |
1150 #endif | |
1087 /* now actually output the block. */ | 1151 /* now actually output the block. */ |
1088 DEVMETH (d, output_display_block, (w, dl, block, start, | 1152 DEVMETH (d, output_display_block, (w, dl, block, start, |
1089 end, start_pixpos, | 1153 end, start_pixpos, |
1090 cursor_start, cursor_width, | 1154 cursor_start, cursor_width, |
1091 cursor_height)); | 1155 cursor_height)); |
1098 parameters. | 1162 parameters. |
1099 ****************************************************************************/ | 1163 ****************************************************************************/ |
1100 static void redisplay_unmap_subwindows (struct frame* f, int x, int y, int width, int height, | 1164 static void redisplay_unmap_subwindows (struct frame* f, int x, int y, int width, int height, |
1101 Lisp_Object ignored_window) | 1165 Lisp_Object ignored_window) |
1102 { | 1166 { |
1103 int elt; | 1167 Lisp_Object rest; |
1104 | 1168 |
1105 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) | 1169 LIST_LOOP (rest, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f))) |
1106 { | 1170 { |
1107 struct subwindow_cachel *cachel = | 1171 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (XCAR (rest)); |
1108 Dynarr_atp (f->subwindow_cachels, elt); | 1172 if (IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) |
1109 | |
1110 if (cachel->being_displayed | |
1111 && | 1173 && |
1112 cachel->x + cachel->width > x && cachel->x < x + width | 1174 IMAGE_INSTANCE_DISPLAY_X (ii) |
1175 + IMAGE_INSTANCE_DISPLAY_WIDTH (ii) > x | |
1113 && | 1176 && |
1114 cachel->y + cachel->height > y && cachel->y < y + height | 1177 IMAGE_INSTANCE_DISPLAY_X (ii) < x + width |
1115 && | 1178 && |
1116 !EQ (cachel->subwindow, ignored_window)) | 1179 IMAGE_INSTANCE_DISPLAY_Y (ii) |
1117 { | 1180 + IMAGE_INSTANCE_DISPLAY_HEIGHT (ii) > y |
1118 unmap_subwindow (cachel->subwindow); | 1181 && |
1182 IMAGE_INSTANCE_DISPLAY_Y (ii) < y + height | |
1183 && | |
1184 !EQ (XCAR (rest), ignored_window)) | |
1185 { | |
1186 unmap_subwindow (XCAR (rest)); | |
1119 } | 1187 } |
1120 } | 1188 } |
1121 } | 1189 } |
1122 | 1190 |
1123 /**************************************************************************** | 1191 /**************************************************************************** |
1126 Potentially subwindows from the area in the box defined by the given | 1194 Potentially subwindows from the area in the box defined by the given |
1127 parameters. | 1195 parameters. |
1128 ****************************************************************************/ | 1196 ****************************************************************************/ |
1129 void redisplay_unmap_subwindows_maybe (struct frame* f, int x, int y, int width, int height) | 1197 void redisplay_unmap_subwindows_maybe (struct frame* f, int x, int y, int width, int height) |
1130 { | 1198 { |
1131 if (Dynarr_length (FRAME_SUBWINDOW_CACHE (f))) | 1199 if (!NILP (XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)))) |
1132 { | 1200 { |
1133 redisplay_unmap_subwindows (f, x, y, width, height, Qnil); | 1201 redisplay_unmap_subwindows (f, x, y, width, height, Qnil); |
1134 } | 1202 } |
1135 } | 1203 } |
1136 | 1204 |
1137 static void redisplay_unmap_subwindows_except_us (struct frame* f, int x, int y, int width, | 1205 static void redisplay_unmap_subwindows_except_us (struct frame* f, int x, int y, int width, |
1138 int height, Lisp_Object subwindow) | 1206 int height, Lisp_Object subwindow) |
1139 { | 1207 { |
1140 if (Dynarr_length (FRAME_SUBWINDOW_CACHE (f))) | 1208 if (!NILP (XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)))) |
1141 { | 1209 { |
1142 redisplay_unmap_subwindows (f, x, y, width, height, subwindow); | 1210 redisplay_unmap_subwindows (f, x, y, width, height, subwindow); |
1143 } | 1211 } |
1144 } | 1212 } |
1145 | 1213 |
1159 { | 1227 { |
1160 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); | 1228 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); |
1161 Lisp_Object window; | 1229 Lisp_Object window; |
1162 struct display_glyph_area sdga; | 1230 struct display_glyph_area sdga; |
1163 | 1231 |
1164 dga->height = IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p); | 1232 dga->height = IMAGE_INSTANCE_HEIGHT (p); |
1165 dga->width = IMAGE_INSTANCE_SUBWINDOW_WIDTH (p); | 1233 dga->width = IMAGE_INSTANCE_WIDTH (p); |
1234 | |
1235 /* The first thing we are going to do is update the display | |
1236 characteristics of the subwindow. This also clears the dirty | |
1237 flags as a side effect. */ | |
1238 redisplay_subwindow (image_instance); | |
1166 | 1239 |
1167 /* This makes the glyph area fit into the display area. */ | 1240 /* This makes the glyph area fit into the display area. */ |
1168 if (!redisplay_normalize_glyph_area (db, dga)) | 1241 if (!redisplay_normalize_glyph_area (db, dga)) |
1169 return; | 1242 return; |
1170 | 1243 |
1185 need to be careful since the subwindow could be outside the | 1258 need to be careful since the subwindow could be outside the |
1186 window in the gutter or modeline - we also need to allow these | 1259 window in the gutter or modeline - we also need to allow these |
1187 cases.*/ | 1260 cases.*/ |
1188 sdga.xoffset = -dga->xoffset; | 1261 sdga.xoffset = -dga->xoffset; |
1189 sdga.yoffset = -dga->yoffset; | 1262 sdga.yoffset = -dga->yoffset; |
1190 sdga.height = IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p); | 1263 sdga.height = IMAGE_INSTANCE_HEIGHT (p); |
1191 sdga.width = IMAGE_INSTANCE_SUBWINDOW_WIDTH (p); | 1264 sdga.width = IMAGE_INSTANCE_WIDTH (p); |
1192 | 1265 |
1193 if (redisplay_display_boxes_in_window_p (w, db, &sdga) < 0) | 1266 if (redisplay_display_boxes_in_window_p (w, db, &sdga) < 0) |
1194 { | 1267 { |
1195 map_subwindow (image_instance, db->xpos, db->ypos, dga); | 1268 map_subwindow (image_instance, db->xpos, db->ypos, dga); |
1196 } | 1269 } |
1204 | 1277 |
1205 /**************************************************************************** | 1278 /**************************************************************************** |
1206 redisplay_output_layout | 1279 redisplay_output_layout |
1207 | 1280 |
1208 Output a widget hierarchy. This can safely call itself recursively. | 1281 Output a widget hierarchy. This can safely call itself recursively. |
1282 | |
1283 The complexity of outputting layouts is deciding whether to do it or | |
1284 not. Consider a layout enclosing some text, the text changes and is | |
1285 marked as dirty, but the enclosing layout has not been marked as | |
1286 dirty so no updates occur and the text will potentially be truncated. | |
1287 Alternatively we hold a back pointer in the image instance to the | |
1288 parent and mark the parent as dirty. But the layout code assumes that | |
1289 if the layout is dirty then the whole layout should be redisplayed, | |
1290 so we then get lots of flashing even though only the text has changed | |
1291 size. Of course if the text shrinks in size then we do actually need | |
1292 to redisplay the layout to repaint the exposed area. So what happens | |
1293 if we make a non-structural change like changing color? Either we | |
1294 redisplay everything, or we redisplay nothing. These are exactly the | |
1295 issues lwlib has to grapple with. We really need to know what has | |
1296 actually changed and make a layout decision based on that. We also | |
1297 really need to know what has changed so that we can only make the | |
1298 necessary changes in update_subwindow. This has all now been | |
1299 implemented, Viva la revolution! | |
1209 ****************************************************************************/ | 1300 ****************************************************************************/ |
1210 void | 1301 void |
1211 redisplay_output_layout (struct window *w, | 1302 redisplay_output_layout (Lisp_Object domain, |
1212 Lisp_Object image_instance, | 1303 Lisp_Object image_instance, |
1213 struct display_box* db, struct display_glyph_area* dga, | 1304 struct display_box* db, struct display_glyph_area* dga, |
1214 face_index findex, int cursor_start, int cursor_width, | 1305 face_index findex, int cursor_start, int cursor_width, |
1215 int cursor_height) | 1306 int cursor_height) |
1216 { | 1307 { |
1217 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); | 1308 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); |
1218 Lisp_Object window, rest; | 1309 Lisp_Object rest, window = DOMAIN_WINDOW (domain); |
1219 Emchar_dynarr *buf = Dynarr_new (Emchar); | 1310 Emchar_dynarr *buf = Dynarr_new (Emchar); |
1220 struct frame *f = XFRAME (w->frame); | 1311 struct window *w = XWINDOW (window); |
1221 struct device *d = XDEVICE (f->device); | 1312 struct device *d = DOMAIN_XDEVICE (domain); |
1222 int layout_height, layout_width; | 1313 int layout_height, layout_width; |
1223 /* We bogusly don't take f->extents_changed and f->glyphs_changed | 1314 |
1224 into account. This is because if we do we always redisplay the | 1315 layout_height = glyph_height (image_instance, domain); |
1225 entire layout. So far I have seen no ill effects so we'll see. */ | 1316 layout_width = glyph_width (image_instance, domain); |
1226 int frame_really_changed = (f->buffers_changed || | |
1227 f->clip_changed || | |
1228 f->faces_changed || | |
1229 f->frame_changed || | |
1230 f->modeline_changed || | |
1231 f->subwindows_changed || | |
1232 f->windows_changed || | |
1233 f->windows_structure_changed); | |
1234 | |
1235 XSETWINDOW (window, w); | |
1236 | |
1237 layout_height = glyph_height (image_instance, window); | |
1238 layout_width = glyph_width (image_instance, window); | |
1239 | 1317 |
1240 dga->height = layout_height; | 1318 dga->height = layout_height; |
1241 dga->width = layout_width; | 1319 dga->width = layout_width; |
1242 | 1320 #ifdef DEBUG_WIDGET_OUTPUT |
1321 printf ("outputing layout glyph %p\n", p); | |
1322 #endif | |
1243 /* This makes the glyph area fit into the display area. */ | 1323 /* This makes the glyph area fit into the display area. */ |
1244 if (!redisplay_normalize_glyph_area (db, dga)) | 1324 if (!redisplay_normalize_glyph_area (db, dga)) |
1245 return; | 1325 return; |
1246 | 1326 |
1247 /* Highly dodgy optimization. We want to only output the whole | 1327 /* Highly dodgy optimization. We want to only output the whole |
1248 layout if we really have to. */ | 1328 layout if we really have to. */ |
1249 if (frame_really_changed || IMAGE_INSTANCE_DIRTYP (p)) | 1329 if (!IMAGE_INSTANCE_OPTIMIZE_OUTPUT (p) |
1330 || IMAGE_INSTANCE_LAYOUT_CHANGED (p) | |
1331 || IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p) | |
1332 || IMAGE_INSTANCE_SIZE_CHANGED (p) | |
1333 || IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p)) | |
1250 { | 1334 { |
1251 /* First clear the area we are drawing into. This is the easiest | 1335 /* First clear the area we are drawing into. This is the easiest |
1252 thing to do since we have many gaps that we have to make sure are | 1336 thing to do since we have many gaps that we have to make sure are |
1253 filled in. */ | 1337 filled in. */ |
1254 redisplay_clear_clipped_region (window, findex, db, dga, 1, Qnil); | 1338 redisplay_clear_clipped_region (window, findex, db, dga, 1, Qnil); |
1300 redisplay_normalize_display_box (db, dga); | 1384 redisplay_normalize_display_box (db, dga); |
1301 | 1385 |
1302 /* Flip through the widgets in the layout displaying as necessary */ | 1386 /* Flip through the widgets in the layout displaying as necessary */ |
1303 LIST_LOOP (rest, IMAGE_INSTANCE_LAYOUT_CHILDREN (p)) | 1387 LIST_LOOP (rest, IMAGE_INSTANCE_LAYOUT_CHILDREN (p)) |
1304 { | 1388 { |
1305 Lisp_Object child = XCAR (rest); | 1389 Lisp_Object child = glyph_image_instance (XCAR (rest), image_instance, |
1390 ERROR_ME_NOT, 1); | |
1306 | 1391 |
1307 struct display_box cdb; | 1392 struct display_box cdb; |
1308 /* For losing HP-UX */ | 1393 /* For losing HP-UX */ |
1309 cdb.xpos = db->xpos; | 1394 cdb.xpos = db->xpos; |
1310 cdb.ypos = db->ypos; | 1395 cdb.ypos = db->ypos; |
1313 | 1398 |
1314 /* First determine if the image is visible at all */ | 1399 /* First determine if the image is visible at all */ |
1315 if (IMAGE_INSTANCEP (child)) | 1400 if (IMAGE_INSTANCEP (child)) |
1316 { | 1401 { |
1317 Lisp_Image_Instance* childii = XIMAGE_INSTANCE (child); | 1402 Lisp_Image_Instance* childii = XIMAGE_INSTANCE (child); |
1403 | |
1318 /* The enclosing layout offsets are +ve at this point */ | 1404 /* The enclosing layout offsets are +ve at this point */ |
1319 struct display_glyph_area cdga; | 1405 struct display_glyph_area cdga; |
1320 cdga.xoffset = IMAGE_INSTANCE_XOFFSET (childii) - dga->xoffset; | 1406 cdga.xoffset = IMAGE_INSTANCE_XOFFSET (childii) - dga->xoffset; |
1321 cdga.yoffset = IMAGE_INSTANCE_YOFFSET (childii) - dga->yoffset; | 1407 cdga.yoffset = IMAGE_INSTANCE_YOFFSET (childii) - dga->yoffset; |
1322 cdga.width = glyph_width (child, window); | 1408 cdga.width = glyph_width (child, image_instance); |
1323 cdga.height = glyph_height (child, window); | 1409 cdga.height = glyph_height (child, image_instance); |
1410 | |
1411 IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) = | |
1412 IMAGE_INSTANCE_OPTIMIZE_OUTPUT (p); | |
1324 | 1413 |
1325 /* Although normalization is done by the output routines | 1414 /* Although normalization is done by the output routines |
1326 we have to do it here so that they don't try and | 1415 we have to do it here so that they don't try and |
1327 clear all of db. This is true below also. */ | 1416 clear all of db. This is true below also. */ |
1328 if (redisplay_normalize_glyph_area (&cdb, &cdga)) | 1417 if (redisplay_normalize_glyph_area (&cdb, &cdga)) |
1334 || cdb.xpos + cdb.width > db->xpos + db->width | 1423 || cdb.xpos + cdb.width > db->xpos + db->width |
1335 || cdb.ypos + cdb.height > db->ypos + db->height) | 1424 || cdb.ypos + cdb.height > db->ypos + db->height) |
1336 continue; | 1425 continue; |
1337 /* We have to invert the offset here as normalization | 1426 /* We have to invert the offset here as normalization |
1338 will have made them positive which the output | 1427 will have made them positive which the output |
1339 routines will treat as a truely +ve offset. */ | 1428 routines will treat as a truly +ve offset. */ |
1340 cdga.xoffset = -cdga.xoffset; | 1429 cdga.xoffset = -cdga.xoffset; |
1341 cdga.yoffset = -cdga.yoffset; | 1430 cdga.yoffset = -cdga.yoffset; |
1342 | 1431 |
1343 switch (IMAGE_INSTANCE_TYPE (childii)) | 1432 switch (IMAGE_INSTANCE_TYPE (childii)) |
1344 { | 1433 { |
1346 { | 1435 { |
1347 /* #### This is well hacked and could use some | 1436 /* #### This is well hacked and could use some |
1348 generalisation.*/ | 1437 generalisation.*/ |
1349 if (redisplay_normalize_glyph_area (&cdb, &cdga) | 1438 if (redisplay_normalize_glyph_area (&cdb, &cdga) |
1350 && | 1439 && |
1351 (frame_really_changed || IMAGE_INSTANCE_DIRTYP (childii))) | 1440 (!IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) || |
1441 IMAGE_INSTANCE_DIRTYP (childii))) | |
1352 { | 1442 { |
1353 struct display_line dl; /* this is fake */ | 1443 struct display_line dl; /* this is fake */ |
1354 Lisp_Object string = | 1444 Lisp_Object string = |
1355 IMAGE_INSTANCE_TEXT_STRING (childii); | 1445 IMAGE_INSTANCE_TEXT_STRING (childii); |
1446 unsigned char charsets[NUM_LEADING_BYTES]; | |
1447 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, findex); | |
1448 | |
1449 find_charsets_in_bufbyte_string (charsets, | |
1450 XSTRING_DATA (string), | |
1451 XSTRING_LENGTH (string)); | |
1452 ensure_face_cachel_complete (cachel, window, charsets); | |
1453 | |
1356 convert_bufbyte_string_into_emchar_dynarr | 1454 convert_bufbyte_string_into_emchar_dynarr |
1357 (XSTRING_DATA (string), XSTRING_LENGTH (string), buf); | 1455 (XSTRING_DATA (string), XSTRING_LENGTH (string), buf); |
1358 | 1456 |
1359 redisplay_normalize_display_box (&cdb, &cdga); | 1457 redisplay_normalize_display_box (&cdb, &cdga); |
1360 /* Offsets are now +ve again so be careful | 1458 /* Offsets are now +ve again so be careful |
1361 when fixing up the display line. */ | 1459 when fixing up the display line. */ |
1362 xzero (dl); | 1460 xzero (dl); |
1363 /* Munge boxes into display lines. */ | 1461 /* Munge boxes into display lines. */ |
1364 dl.ypos = (cdb.ypos - cdga.yoffset) | 1462 dl.ypos = (cdb.ypos - cdga.yoffset) |
1365 + glyph_ascent (child, window); | 1463 + glyph_ascent (child, image_instance); |
1366 dl.ascent = glyph_ascent (child, window); | 1464 dl.ascent = glyph_ascent (child, image_instance); |
1367 dl.descent = glyph_descent (child, window); | 1465 dl.descent = glyph_descent (child, image_instance); |
1368 dl.top_clip = cdga.yoffset; | 1466 dl.top_clip = cdga.yoffset; |
1369 dl.clip = (dl.ypos + dl.descent) - (cdb.ypos + cdb.height); | 1467 dl.clip = (dl.ypos + dl.descent) - (cdb.ypos + cdb.height); |
1370 /* output_string doesn't understand offsets in | 1468 /* output_string doesn't understand offsets in |
1371 the same way as other routines - we have to | 1469 the same way as other routines - we have to |
1372 add the offset to the width so that we | 1470 add the offset to the width so that we |
1380 } | 1478 } |
1381 break; | 1479 break; |
1382 | 1480 |
1383 case IMAGE_MONO_PIXMAP: | 1481 case IMAGE_MONO_PIXMAP: |
1384 case IMAGE_COLOR_PIXMAP: | 1482 case IMAGE_COLOR_PIXMAP: |
1385 if (frame_really_changed || IMAGE_INSTANCE_DIRTYP (childii)) | 1483 if (!IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) |
1484 || IMAGE_INSTANCE_DIRTYP (childii)) | |
1386 redisplay_output_pixmap (w, child, &cdb, &cdga, findex, | 1485 redisplay_output_pixmap (w, child, &cdb, &cdga, findex, |
1387 0, 0, 0, 0); | 1486 0, 0, 0, 0); |
1388 break; | 1487 break; |
1389 | 1488 |
1390 case IMAGE_WIDGET: | 1489 case IMAGE_WIDGET: |
1490 if (EQ (IMAGE_INSTANCE_WIDGET_TYPE (childii), Qlayout)) | |
1491 { | |
1492 redisplay_output_layout (image_instance, child, &cdb, &cdga, findex, | |
1493 0, 0, 0); | |
1494 break; | |
1495 } | |
1391 case IMAGE_SUBWINDOW: | 1496 case IMAGE_SUBWINDOW: |
1392 if (frame_really_changed || IMAGE_INSTANCE_DIRTYP (childii)) | 1497 if (!IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) || |
1498 IMAGE_INSTANCE_DIRTYP (childii)) | |
1393 redisplay_output_subwindow (w, child, &cdb, &cdga, findex, | 1499 redisplay_output_subwindow (w, child, &cdb, &cdga, findex, |
1394 0, 0, 0); | 1500 0, 0, 0); |
1395 break; | |
1396 | |
1397 case IMAGE_LAYOUT: | |
1398 redisplay_output_layout (w, child, &cdb, &cdga, findex, | |
1399 0, 0, 0); | |
1400 break; | 1501 break; |
1401 | 1502 |
1402 case IMAGE_NOTHING: | 1503 case IMAGE_NOTHING: |
1403 /* nothing is as nothing does */ | 1504 /* nothing is as nothing does */ |
1404 break; | 1505 break; |
1406 case IMAGE_POINTER: | 1507 case IMAGE_POINTER: |
1407 default: | 1508 default: |
1408 abort (); | 1509 abort (); |
1409 } | 1510 } |
1410 } | 1511 } |
1411 } | 1512 IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) = 0; |
1412 } | 1513 } |
1514 } | |
1515 | |
1516 /* Update any display properties. I'm not sure whether this actually | |
1517 does anything for layouts except clear the changed flags. */ | |
1518 redisplay_subwindow (image_instance); | |
1519 | |
1413 Dynarr_free (buf); | 1520 Dynarr_free (buf); |
1414 } | 1521 } |
1415 | 1522 |
1416 /**************************************************************************** | 1523 /**************************************************************************** |
1417 redisplay_output_pixmap | 1524 redisplay_output_pixmap |
1448 mask. */ | 1555 mask. */ |
1449 if (!offset_bitmap) | 1556 if (!offset_bitmap) |
1450 { | 1557 { |
1451 redisplay_clear_clipped_region (window, findex, | 1558 redisplay_clear_clipped_region (window, findex, |
1452 db, dga, | 1559 db, dga, |
1453 (int)IMAGE_INSTANCE_PIXMAP_MASK (p), | 1560 (IMAGE_INSTANCE_PIXMAP_MASK (p) != 0), |
1454 Qnil); | 1561 Qnil); |
1455 | 1562 |
1456 /* This shrinks the display box to exactly enclose the glyph | 1563 /* This shrinks the display box to exactly enclose the glyph |
1457 area. */ | 1564 area. */ |
1458 redisplay_normalize_display_box (db, dga); | 1565 redisplay_normalize_display_box (db, dga); |
1570 | 1677 |
1571 /**************************************************************************** | 1678 /**************************************************************************** |
1572 redisplay_clear_clipped_region | 1679 redisplay_clear_clipped_region |
1573 | 1680 |
1574 Clear the area in the dest display_box not covered by the src | 1681 Clear the area in the dest display_box not covered by the src |
1575 display_glyph_area using the given face. This is a common occurance | 1682 display_glyph_area using the given face. This is a common occurrence |
1576 for images shorter than the display line. Clipping can be played | 1683 for images shorter than the display line. Clipping can be played |
1577 around with by altering these. glyphsrc should be normalized. | 1684 around with by altering these. glyphsrc should be normalized. |
1578 ****************************************************************************/ | 1685 ****************************************************************************/ |
1579 static void | 1686 static void |
1580 redisplay_clear_clipped_region (Lisp_Object window, face_index findex, | 1687 redisplay_clear_clipped_region (Lisp_Object window, face_index findex, |
1950 struct device *d = XDEVICE (f->device); | 2057 struct device *d = XDEVICE (f->device); |
1951 | 2058 |
1952 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP); | 2059 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP); |
1953 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP); | 2060 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP); |
1954 | 2061 |
1955 DEVMETH (d, output_begin, (d)); | 2062 MAYBE_DEVMETH (d, window_output_begin, (w)); |
1956 | 2063 |
1957 while (first_line <= last_line) | 2064 while (first_line <= last_line) |
1958 { | 2065 { |
1959 Charcount old_len = (Dynarr_atp (cdla, first_line)->end_bufpos - | 2066 Charcount old_len = (Dynarr_atp (cdla, first_line)->end_bufpos - |
1960 Dynarr_atp (cdla, first_line)->bufpos); | 2067 Dynarr_atp (cdla, first_line)->bufpos); |
2035 update_window_scrollbars (w, NULL, 1, stupid_vertical_scrollbar_drag_hack); | 2142 update_window_scrollbars (w, NULL, 1, stupid_vertical_scrollbar_drag_hack); |
2036 stupid_vertical_scrollbar_drag_hack = 1; | 2143 stupid_vertical_scrollbar_drag_hack = 1; |
2037 } | 2144 } |
2038 #endif | 2145 #endif |
2039 | 2146 |
2040 /* This has to be done after we've updated the values. We don't | 2147 redisplay_redraw_cursor (f, 0); |
2041 call output_end for tty frames. Redisplay will do this after all | 2148 MAYBE_DEVMETH (d, window_output_end, (w)); |
2042 tty windows have been updated. This cuts down on cursor | |
2043 flicker. */ | |
2044 if (FRAME_TTY_P (f)) | |
2045 redisplay_redraw_cursor (f, 0); | |
2046 else | |
2047 DEVMETH (d, output_end, (d)); | |
2048 } | 2149 } |
2049 | 2150 |
2050 /***************************************************************************** | 2151 /***************************************************************************** |
2051 redisplay_output_window | 2152 redisplay_output_window |
2052 | 2153 |
2156 } | 2257 } |
2157 } | 2258 } |
2158 } | 2259 } |
2159 | 2260 |
2160 /* Perform any output initialization. */ | 2261 /* Perform any output initialization. */ |
2161 DEVMETH (d, output_begin, (d)); | 2262 MAYBE_DEVMETH (d, window_output_begin, (w)); |
2162 | 2263 |
2163 /* If the window's structure has changed clear the internal border | 2264 /* If the window's structure has changed clear the internal border |
2164 above it if it is topmost (the function will check). */ | 2265 above it if it is topmost (the function will check). */ |
2165 if (f->windows_structure_changed) | 2266 if (f->windows_structure_changed) |
2166 redisplay_clear_top_of_window (w); | 2267 redisplay_clear_top_of_window (w); |
2179 | 2280 |
2180 /* Output a vertical divider between windows, if necessary. */ | 2281 /* Output a vertical divider between windows, if necessary. */ |
2181 if (window_needs_vertical_divider (w) | 2282 if (window_needs_vertical_divider (w) |
2182 && (f->windows_structure_changed || f->clear)) | 2283 && (f->windows_structure_changed || f->clear)) |
2183 { | 2284 { |
2184 DEVMETH (d, output_vertical_divider, (w, f->windows_structure_changed)); | 2285 MAYBE_DEVMETH (d, output_vertical_divider, (w, f->windows_structure_changed)); |
2185 } | 2286 } |
2186 | 2287 |
2187 /* Clear the rest of the window, if necessary. */ | 2288 /* Clear the rest of the window, if necessary. */ |
2188 if (need_to_clear_bottom) | 2289 if (need_to_clear_bottom) |
2189 { | 2290 { |
2213 | 2314 |
2214 /* Overkill on invalidating the cache. It is very bad for it to not | 2315 /* Overkill on invalidating the cache. It is very bad for it to not |
2215 get invalidated when it should be. */ | 2316 get invalidated when it should be. */ |
2216 INVALIDATE_DEVICE_PIXEL_TO_GLYPH_CACHE (d); | 2317 INVALIDATE_DEVICE_PIXEL_TO_GLYPH_CACHE (d); |
2217 | 2318 |
2218 /* We don't call output_end for tty frames. Redisplay will do this | 2319 redisplay_redraw_cursor (f, 0); |
2219 after all tty windows have been updated. This cuts down on | 2320 MAYBE_DEVMETH (d, window_output_end, (w)); |
2220 cursor flicker. */ | |
2221 if (FRAME_TTY_P (f)) | |
2222 redisplay_redraw_cursor (f, 0); | |
2223 else | |
2224 DEVMETH (d, output_end, (d)); | |
2225 | 2321 |
2226 #ifdef HAVE_SCROLLBARS | 2322 #ifdef HAVE_SCROLLBARS |
2227 update_window_scrollbars (w, NULL, !MINI_WINDOW_P (w), 0); | 2323 update_window_scrollbars (w, NULL, !MINI_WINDOW_P (w), 0); |
2228 #endif | 2324 #endif |
2229 } | 2325 } |