Mercurial > hg > xemacs-beta
comparison src/redisplay.c @ 371:cc15677e0335 r21-2b1
Import from CVS: tag r21-2b1
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:03:08 +0200 |
parents | a4f53d9b3154 |
children | 6240c7796c7a |
comparison
equal
deleted
inserted
replaced
370:bd866891f083 | 371:cc15677e0335 |
---|---|
1230 { | 1230 { |
1231 return add_octal_runes (data); | 1231 return add_octal_runes (data); |
1232 } | 1232 } |
1233 } | 1233 } |
1234 | 1234 |
1235 /* Given a display table entry, call the appropriate functions to | |
1236 display each element of the entry. */ | |
1237 | |
1235 static prop_block_dynarr * | 1238 static prop_block_dynarr * |
1236 add_disp_table_entry_runes_1 (pos_data *data, Lisp_Object entry) | 1239 add_disp_table_entry_runes (pos_data *data, Lisp_Object entry) |
1237 { | 1240 { |
1238 prop_block_dynarr *prop = NULL; | 1241 prop_block_dynarr *prop = NULL; |
1239 | 1242 |
1240 if (STRINGP (entry)) | 1243 if (VECTORP (entry)) |
1244 { | |
1245 struct Lisp_Vector *de = XVECTOR (entry); | |
1246 long len = vector_length (de); | |
1247 int elt; | |
1248 | |
1249 for (elt = 0; elt < len; elt++) | |
1250 { | |
1251 if (NILP (de->contents[elt])) | |
1252 continue; | |
1253 else if (STRINGP (de->contents[elt])) | |
1254 { | |
1255 prop = | |
1256 add_bufbyte_string_runes | |
1257 (data, | |
1258 XSTRING_DATA (de->contents[elt]), | |
1259 XSTRING_LENGTH (de->contents[elt]), | |
1260 0); | |
1261 } | |
1262 else if (GLYPHP (de->contents[elt])) | |
1263 { | |
1264 if (data->start_col) | |
1265 data->start_col--; | |
1266 | |
1267 if (!data->start_col && data->bi_start_col_enabled) | |
1268 { | |
1269 prop = add_hscroll_rune (data); | |
1270 } | |
1271 else | |
1272 { | |
1273 struct glyph_block gb; | |
1274 | |
1275 gb.glyph = de->contents[elt]; | |
1276 gb.extent = Qnil; | |
1277 prop = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0); | |
1278 } | |
1279 } | |
1280 else if (CHAR_OR_CHAR_INTP (de->contents[elt])) | |
1281 { | |
1282 data->ch = XCHAR_OR_CHAR_INT (de->contents[elt]); | |
1283 prop = add_emchar_rune (data); | |
1284 } | |
1285 /* Else blow it off because someone added a bad entry and we | |
1286 don't have any safe way of signaling an error. */ | |
1287 | |
1288 /* #### Still need to add any remaining elements to the | |
1289 propagation information. */ | |
1290 if (prop) | |
1291 return prop; | |
1292 } | |
1293 } | |
1294 else if (STRINGP (entry)) | |
1241 { | 1295 { |
1242 prop = add_bufbyte_string_runes (data, | 1296 prop = add_bufbyte_string_runes (data, |
1243 XSTRING_DATA (entry), | 1297 XSTRING_DATA (entry), |
1244 XSTRING_LENGTH (entry), | 1298 XSTRING_LENGTH (entry), |
1245 0); | 1299 0); |
1265 else if (CHAR_OR_CHAR_INTP (entry)) | 1319 else if (CHAR_OR_CHAR_INTP (entry)) |
1266 { | 1320 { |
1267 data->ch = XCHAR_OR_CHAR_INT (entry); | 1321 data->ch = XCHAR_OR_CHAR_INT (entry); |
1268 prop = add_emchar_rune (data); | 1322 prop = add_emchar_rune (data); |
1269 } | 1323 } |
1270 else if (CONSP (entry)) | |
1271 { | |
1272 if (EQ (XCAR (entry), Qformat) | |
1273 && CONSP (XCDR (entry)) | |
1274 && STRINGP (XCAR (XCDR (entry)))) | |
1275 { | |
1276 Lisp_Object format = XCAR (XCDR (entry)); | |
1277 Bytind len = XSTRING_LENGTH (format); | |
1278 Bufbyte *src = XSTRING_DATA (format), *end = src + len; | |
1279 Bufbyte *result = alloca_array (Bufbyte, len); | |
1280 Bufbyte *dst = result; | |
1281 | |
1282 while (src < end) | |
1283 { | |
1284 Emchar c = charptr_emchar (src); | |
1285 INC_CHARPTR (src); | |
1286 if (c != '%' || src == end) | |
1287 dst += set_charptr_emchar (dst, c); | |
1288 else | |
1289 { | |
1290 c = charptr_emchar (src); | |
1291 INC_CHARPTR (src); | |
1292 switch (c) | |
1293 { | |
1294 /*case 'x': | |
1295 dst += long_to_string_base ((char *)dst, data->ch, 16); | |
1296 break;*/ | |
1297 case '%': | |
1298 dst += set_charptr_emchar (dst, '%'); | |
1299 break; | |
1300 } | |
1301 } | |
1302 } | |
1303 prop = add_bufbyte_string_runes (data, result, dst - result, 0); | |
1304 } | |
1305 } | |
1306 | 1324 |
1307 /* Else blow it off because someone added a bad entry and we don't | 1325 /* Else blow it off because someone added a bad entry and we don't |
1308 have any safe way of signaling an error. */ | 1326 have any safe way of signaling an error. Hey, this comment |
1309 return prop; | 1327 sounds familiar. */ |
1310 } | |
1311 | |
1312 /* Given a display table entry, call the appropriate functions to | |
1313 display each element of the entry. */ | |
1314 | |
1315 static prop_block_dynarr * | |
1316 add_disp_table_entry_runes (pos_data *data, Lisp_Object entry) | |
1317 { | |
1318 prop_block_dynarr *prop = NULL; | |
1319 if (VECTORP (entry)) | |
1320 { | |
1321 struct Lisp_Vector *de = XVECTOR (entry); | |
1322 EMACS_INT len = vector_length (de); | |
1323 int elt; | |
1324 | |
1325 for (elt = 0; elt < len; elt++) | |
1326 { | |
1327 if (NILP (vector_data (de)[elt])) | |
1328 continue; | |
1329 else | |
1330 prop = add_disp_table_entry_runes_1 (data, vector_data (de)[elt]); | |
1331 /* Else blow it off because someone added a bad entry and we | |
1332 don't have any safe way of signaling an error. Hey, this | |
1333 comment sounds familiar. */ | |
1334 | |
1335 /* #### Still need to add any remaining elements to the | |
1336 propagation information. */ | |
1337 if (prop) | |
1338 return prop; | |
1339 } | |
1340 } | |
1341 else | |
1342 prop = add_disp_table_entry_runes_1 (data, entry); | |
1343 return prop; | 1328 return prop; |
1344 } | 1329 } |
1345 | 1330 |
1346 /* Add runes which were propagated from the previous line. */ | 1331 /* Add runes which were propagated from the previous line. */ |
1347 | 1332 |
1763 struct frame *f = XFRAME (w->frame); | 1748 struct frame *f = XFRAME (w->frame); |
1764 struct buffer *b = XBUFFER (w->buffer); | 1749 struct buffer *b = XBUFFER (w->buffer); |
1765 struct device *d = XDEVICE (f->device); | 1750 struct device *d = XDEVICE (f->device); |
1766 | 1751 |
1767 pos_data data; | 1752 pos_data data; |
1753 struct Lisp_Vector *dt = 0; | |
1768 | 1754 |
1769 /* Don't display anything in the minibuffer if this window is not on | 1755 /* Don't display anything in the minibuffer if this window is not on |
1770 a selected frame. We consider all other windows to be active | 1756 a selected frame. We consider all other windows to be active |
1771 minibuffers as it simplifies the coding. */ | 1757 minibuffers as it simplifies the coding. */ |
1772 int active_minibuffer = (!MINI_WINDOW_P (w) || | 1758 int active_minibuffer = (!MINI_WINDOW_P (w) || |
1835 Emchar printable_min = (CHAR_OR_CHAR_INTP (b->ctl_arrow) | 1821 Emchar printable_min = (CHAR_OR_CHAR_INTP (b->ctl_arrow) |
1836 ? XCHAR_OR_CHAR_INT (b->ctl_arrow) | 1822 ? XCHAR_OR_CHAR_INT (b->ctl_arrow) |
1837 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil)) | 1823 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil)) |
1838 ? 255 : 160)); | 1824 ? 255 : 160)); |
1839 | 1825 |
1840 Lisp_Object face_dt, window_dt; | |
1841 | |
1842 /* The text display block for this display line. */ | 1826 /* The text display block for this display line. */ |
1843 struct display_block *db = get_display_block_from_line (dl, TEXT); | 1827 struct display_block *db = get_display_block_from_line (dl, TEXT); |
1844 | 1828 |
1845 /* The first time through the main loop we need to force the glyph | 1829 /* The first time through the main loop we need to force the glyph |
1846 data to be updated. */ | 1830 data to be updated. */ |
1975 /* Now compute the face and begin/end-glyph information. */ | 1959 /* Now compute the face and begin/end-glyph information. */ |
1976 data.findex = | 1960 data.findex = |
1977 /* Remember that the extent-fragment routines deal in Bytind's. */ | 1961 /* Remember that the extent-fragment routines deal in Bytind's. */ |
1978 extent_fragment_update (w, data.ef, data.bi_bufpos); | 1962 extent_fragment_update (w, data.ef, data.bi_bufpos); |
1979 | 1963 |
1980 get_display_tables (w, data.findex, &face_dt, &window_dt); | |
1981 | |
1982 if (data.bi_bufpos == data.ef->end) | 1964 if (data.bi_bufpos == data.ef->end) |
1983 no_more_frags = 1; | 1965 no_more_frags = 1; |
1966 | |
1967 dt = get_display_table (w, data.findex); | |
1984 } | 1968 } |
1985 initial = 0; | 1969 initial = 0; |
1986 | 1970 |
1987 /* Determine what is next to be displayed. We first handle any | 1971 /* Determine what is next to be displayed. We first handle any |
1988 glyphs returned by glyphs_at_bufpos. If there are no glyphs to | 1972 glyphs returned by glyphs_at_bufpos. If there are no glyphs to |
2090 else if (data.bi_bufpos == BI_BUF_ZV (b)) | 2074 else if (data.bi_bufpos == BI_BUF_ZV (b)) |
2091 goto done; | 2075 goto done; |
2092 | 2076 |
2093 else | 2077 else |
2094 { | 2078 { |
2095 Lisp_Object entry = Qnil; | |
2096 /* Get the character at the current buffer position. */ | 2079 /* Get the character at the current buffer position. */ |
2097 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos); | 2080 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos); |
2098 if (!NILP (face_dt) || !NILP (window_dt)) | |
2099 entry = display_table_entry (data.ch, face_dt, window_dt); | |
2100 | 2081 |
2101 /* If there is a display table entry for it, hand it off to | 2082 /* If there is a display table entry for it, hand it off to |
2102 add_disp_table_entry_runes and let it worry about it. */ | 2083 add_disp_table_entry_runes and let it worry about it. */ |
2103 if (!NILP (entry) && !EQ (entry, make_char (data.ch))) | 2084 if (dt && !NILP (DISP_CHAR_ENTRY (dt, data.ch))) |
2104 { | 2085 { |
2105 *prop = add_disp_table_entry_runes (&data, entry); | 2086 *prop = |
2087 add_disp_table_entry_runes (&data, | |
2088 DISP_CHAR_ENTRY (dt, data.ch)); | |
2106 | 2089 |
2107 if (*prop) | 2090 if (*prop) |
2108 goto done; | 2091 goto done; |
2109 } | 2092 } |
2110 | 2093 |
4245 Dynarr_add (prop, pb); | 4228 Dynarr_add (prop, pb); |
4246 } | 4229 } |
4247 else | 4230 else |
4248 prop = 0; | 4231 prop = 0; |
4249 | 4232 |
4250 /* Make sure this is set always */ | |
4251 /* Note the conversion at end */ | |
4252 w->window_end_pos[type] = start_pos; | |
4253 while (ypos < yend) | 4233 while (ypos < yend) |
4254 { | 4234 { |
4255 struct display_line dl; | 4235 struct display_line dl; |
4256 struct display_line *dlp; | 4236 struct display_line *dlp; |
4257 int local; | 4237 int local; |
4330 | 4310 |
4331 if (prop) | 4311 if (prop) |
4332 Dynarr_free (prop); | 4312 Dynarr_free (prop); |
4333 | 4313 |
4334 /* #### More not quite right, but close enough. */ | 4314 /* #### More not quite right, but close enough. */ |
4335 /* Ben sez: apparently window_end_pos[] is measured | 4315 /* #### Ben sez: apparently window_end_pos[] is measured |
4336 as the number of characters between the window end and the | 4316 as the number of characters between the window end and the |
4337 end of the buffer? This seems rather weirdo. What's | 4317 end of the buffer? This seems rather weirdo. What's |
4338 the justification for this? | 4318 the justification for this? */ |
4339 | |
4340 JV sez: Because BUF_Z (b) would be a good initial value, however | |
4341 that can change. This representation allows initalizing with 0. | |
4342 */ | |
4343 w->window_end_pos[type] = BUF_Z (b) - w->window_end_pos[type]; | 4319 w->window_end_pos[type] = BUF_Z (b) - w->window_end_pos[type]; |
4344 | 4320 |
4345 if (need_modeline) | 4321 if (need_modeline) |
4346 { | 4322 { |
4347 /* We know that this is the right thing to use because we put it | 4323 /* We know that this is the right thing to use because we put it |
5088 && pointm >= startp | 5064 && pointm >= startp |
5089 /* This check is to make sure we restore the minibuffer after a | 5065 /* This check is to make sure we restore the minibuffer after a |
5090 temporary change to the echo area. */ | 5066 temporary change to the echo area. */ |
5091 && !(MINI_WINDOW_P (w) && f->buffers_changed) | 5067 && !(MINI_WINDOW_P (w) && f->buffers_changed) |
5092 && !f->frame_changed | 5068 && !f->frame_changed |
5093 && !truncation_changed | 5069 && !truncation_changed) |
5094 /* check whether start is really at the begining of a line GE */ | |
5095 && (!w->start_at_line_beg || beginning_of_line_p (b, startp)) | |
5096 ) | |
5097 { | 5070 { |
5098 /* Check if the cursor has actually moved. */ | 5071 /* Check if the cursor has actually moved. */ |
5099 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer) | 5072 if (EQ (Fmarker_buffer (w->last_point[CURRENT_DISP]), w->buffer) |
5100 && pointm == marker_position (w->last_point[CURRENT_DISP]) | 5073 && pointm == marker_position (w->last_point[CURRENT_DISP]) |
5101 && selected_globally | 5074 && selected_globally |
5258 { | 5231 { |
5259 Bufpos start = marker_position (w->start[DESIRED_DISP]); | 5232 Bufpos start = marker_position (w->start[DESIRED_DISP]); |
5260 Bufpos end = (w->window_end_pos[DESIRED_DISP] == -1 | 5233 Bufpos end = (w->window_end_pos[DESIRED_DISP] == -1 |
5261 ? BUF_ZV (b) | 5234 ? BUF_ZV (b) |
5262 : BUF_Z (b) - w->window_end_pos[DESIRED_DISP] - 1); | 5235 : BUF_Z (b) - w->window_end_pos[DESIRED_DISP] - 1); |
5263 /* Don't pollute the cache if not sure if we are correct */ | 5236 |
5264 if (w->start_at_line_beg) | 5237 update_line_start_cache (w, start, end, pointm, 1); |
5265 update_line_start_cache (w, start, end, pointm, 1); | |
5266 redisplay_output_window (w); | 5238 redisplay_output_window (w); |
5267 /* | 5239 /* |
5268 * If we just displayed the echo area, the line start cache is | 5240 * If we just displayed the echo area, the line start cache is |
5269 * no longer valid, because the minibuffer window is assocaited | 5241 * no longer valid, because the minibuffer window is assocaited |
5270 * with the window now. | 5242 * with the window now. |
6262 if (dl->modeline) | 6234 if (dl->modeline) |
6263 continue; | 6235 continue; |
6264 else | 6236 else |
6265 { | 6237 { |
6266 struct line_start_cache lsc; | 6238 struct line_start_cache lsc; |
6267 | 6239 |
6268 lsc.start = dl->bufpos; | 6240 lsc.start = dl->bufpos; |
6269 lsc.end = dl->end_bufpos; | 6241 lsc.end = dl->end_bufpos; |
6270 lsc.height = dl->ascent + dl->descent; | 6242 lsc.height = dl->ascent + dl->descent; |
6271 | 6243 |
6272 Dynarr_add (internal_cache, lsc); | 6244 Dynarr_add (internal_cache, lsc); |
6614 /* For the given window W, if display starts at STARTP, what will be | 6586 /* For the given window W, if display starts at STARTP, what will be |
6615 the buffer position at the beginning or end of the last line | 6587 the buffer position at the beginning or end of the last line |
6616 displayed. The end of the last line is also know as the window end | 6588 displayed. The end of the last line is also know as the window end |
6617 position. | 6589 position. |
6618 | 6590 |
6619 WARNING: Under some circumstances it is possible that redisplay failed | |
6620 to layout any lines for the windows. In that case this function returns | |
6621 0 as an error condition when may_error is non-zero and a normalized | |
6622 value of startp otherwise. | |
6623 Under normal circumstances this is rare. However it seems that it does | |
6624 occur in the following situation: A mouse event has come in and we need | |
6625 to compute its location in a window. That code (in | |
6626 pixel_to_glyph_translation) already can handle 0 as an error return | |
6627 value. | |
6628 | |
6629 #### With a little work this could probably be reworked as just a | 6591 #### With a little work this could probably be reworked as just a |
6630 call to start_with_line_at_pixpos. */ | 6592 call to start_with_line_at_pixpos. */ |
6631 | 6593 |
6632 static Bufpos | 6594 static Bufpos |
6633 start_end_of_last_line (struct window *w, Bufpos startp, int end, | 6595 start_end_of_last_line (struct window *w, Bufpos startp, int end) |
6634 int may_error) | |
6635 { | 6596 { |
6636 struct buffer *b = XBUFFER (w->buffer); | 6597 struct buffer *b = XBUFFER (w->buffer); |
6637 line_start_cache_dynarr *cache = w->line_start_cache; | 6598 line_start_cache_dynarr *cache = w->line_start_cache; |
6638 int pixpos = 0; | 6599 int pixpos = 0; |
6639 int bottom = WINDOW_TEXT_HEIGHT (w); | 6600 int bottom = WINDOW_TEXT_HEIGHT (w); |
6649 startp = BUF_ZV (b); | 6610 startp = BUF_ZV (b); |
6650 cur_start = startp; | 6611 cur_start = startp; |
6651 | 6612 |
6652 start_elt = point_in_line_start_cache (w, cur_start, 0); | 6613 start_elt = point_in_line_start_cache (w, cur_start, 0); |
6653 if (start_elt == -1) | 6614 if (start_elt == -1) |
6654 return may_error ? 0 : startp; | 6615 abort (); /* this had better never happen */ |
6655 | 6616 |
6656 while (1) | 6617 while (1) |
6657 { | 6618 { |
6658 int height = Dynarr_atp (cache, start_elt)->height; | 6619 int height = Dynarr_atp (cache, start_elt)->height; |
6659 | 6620 |
6660 cur_start = Dynarr_atp (cache, start_elt)->start; | 6621 cur_start = Dynarr_atp (cache, start_elt)->start; |
6713 the buffer position at the beginning of the last line displayed. */ | 6674 the buffer position at the beginning of the last line displayed. */ |
6714 | 6675 |
6715 Bufpos | 6676 Bufpos |
6716 start_of_last_line (struct window *w, Bufpos startp) | 6677 start_of_last_line (struct window *w, Bufpos startp) |
6717 { | 6678 { |
6718 return start_end_of_last_line (w, startp, 0 , 0); | 6679 return start_end_of_last_line (w, startp, 0); |
6719 } | 6680 } |
6720 | 6681 |
6721 /* For the given window W, if display starts at STARTP, what will be | 6682 /* For the given window W, if display starts at STARTP, what will be |
6722 the buffer position at the end of the last line displayed. This is | 6683 the buffer position at the end of the last line displayed. This is |
6723 also know as the window end position. */ | 6684 also know as the window end position. */ |
6724 | 6685 |
6725 Bufpos | 6686 Bufpos |
6726 end_of_last_line (struct window *w, Bufpos startp) | 6687 end_of_last_line (struct window *w, Bufpos startp) |
6727 { | 6688 { |
6728 return start_end_of_last_line (w, startp, 1, 0); | 6689 return start_end_of_last_line (w, startp, 1); |
6729 } | 6690 } |
6730 | |
6731 static Bufpos | |
6732 end_of_last_line_may_error (struct window *w, Bufpos startp) | |
6733 { | |
6734 return start_end_of_last_line (w, startp, 1, 1); | |
6735 } | |
6736 | |
6737 | 6691 |
6738 /* For window W, what does the starting position have to be so that | 6692 /* For window W, what does the starting position have to be so that |
6739 the line containing POINT will cover pixel position PIXPOS. */ | 6693 the line containing POINT will cover pixel position PIXPOS. */ |
6740 | 6694 |
6741 Bufpos | 6695 Bufpos |
7873 /* #### This should be checked out some more to determine what | 7827 /* #### This should be checked out some more to determine what |
7874 should really be going on. */ | 7828 should really be going on. */ |
7875 if (!MARKERP ((*w)->start[CURRENT_DISP])) | 7829 if (!MARKERP ((*w)->start[CURRENT_DISP])) |
7876 *closest = 0; | 7830 *closest = 0; |
7877 else | 7831 else |
7878 *closest = end_of_last_line_may_error (*w, | 7832 *closest = end_of_last_line (*w, |
7879 marker_position ((*w)->start[CURRENT_DISP])); | 7833 marker_position ((*w)->start[CURRENT_DISP])); |
7880 *col = 0; | 7834 *col = 0; |
7881 UPDATE_CACHE_RETURN; | 7835 UPDATE_CACHE_RETURN; |
7882 } | 7836 } |
7883 #undef UPDATE_CACHE_RETURN | 7837 #undef UPDATE_CACHE_RETURN |