Mercurial > hg > xemacs-beta
comparison src/redisplay.c @ 272:c5d627a313b1 r21-0b34
Import from CVS: tag r21-0b34
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:28:48 +0200 |
parents | b2472a1930f2 |
children | ca9a9ec9c1c1 |
comparison
equal
deleted
inserted
replaced
271:c7b7086b0a39 | 272:c5d627a313b1 |
---|---|
38 Third: It Is Better To Be Fast Than Not To Be | 38 Third: It Is Better To Be Fast Than Not To Be |
39 ****************************************************************************/ | 39 ****************************************************************************/ |
40 | 40 |
41 #include <config.h> | 41 #include <config.h> |
42 #include "lisp.h" | 42 #include "lisp.h" |
43 #include <limits.h> | |
43 | 44 |
44 #include "buffer.h" | 45 #include "buffer.h" |
45 #include "commands.h" | 46 #include "commands.h" |
46 #include "debug.h" | 47 #include "debug.h" |
47 #include "device.h" | 48 #include "device.h" |
61 #include "file-coding.h" | 62 #include "file-coding.h" |
62 #endif | 63 #endif |
63 | 64 |
64 #ifdef HAVE_TTY | 65 #ifdef HAVE_TTY |
65 #include "console-tty.h" | 66 #include "console-tty.h" |
67 #ifdef HAVE_UNISTD_H | |
68 #include <unistd.h> /* for isatty() */ | |
66 #endif | 69 #endif |
70 #endif /* HAVE_TTY */ | |
67 | 71 |
68 /* Note: We have to be careful throughout this code to properly handle | 72 /* Note: We have to be careful throughout this code to properly handle |
69 and differentiate between Bufbytes and Emchars. | 73 and differentiate between Bufbytes and Emchars. |
70 | 74 |
71 Since strings are generally composed of Bufbytes, I've taken the tack | 75 Since strings are generally composed of Bufbytes, I've taken the tack |
203 struct prop_block | 207 struct prop_block |
204 { | 208 { |
205 enum prop_type type; | 209 enum prop_type type; |
206 | 210 |
207 union data | 211 union data |
208 { | 212 { |
209 struct | 213 struct |
210 { | 214 { |
211 Bufbyte *str; | 215 Bufbyte *str; |
212 Bytecount len; /* length of the string. */ | 216 Bytecount len; /* length of the string. */ |
213 } p_string; | 217 } p_string; |
214 | 218 |
215 struct | 219 struct |
216 { | 220 { |
217 Emchar ch; | 221 Emchar ch; |
218 Bytind bi_cursor_bufpos; /* NOTE: is in Bytinds */ | 222 Bytind bi_cursor_bufpos; /* NOTE: is in Bytinds */ |
219 unsigned int cursor_type :3; | 223 unsigned int cursor_type :3; |
220 } p_char; | 224 } p_char; |
221 | 225 |
222 struct | 226 struct |
223 { | 227 { |
224 int width; | 228 int width; |
225 face_index findex; | 229 face_index findex; |
226 } p_blank; | 230 } p_blank; |
227 } data; | 231 } data; |
228 }; | 232 }; |
229 | 233 |
230 typedef struct | 234 typedef struct |
231 { | 235 { |
232 Dynarr_declare (prop_block); | 236 Dynarr_declare (prop_block); |
233 } prop_block_dynarr; | 237 } prop_block_dynarr; |
234 | 238 |
235 | 239 |
236 /* | |
237 * Prototypes for all functions defined in redisplay.c. | |
238 */ | |
239 struct display_block *get_display_block_from_line (struct display_line *dl, | |
240 enum display_type type); | |
241 layout_bounds calculate_display_line_boundaries (struct window *w, | |
242 int modeline); | |
243 static Bufpos generate_display_line (struct window *w, struct display_line *dl, | |
244 int bounds, Bufpos start_pos, | |
245 int start_col, prop_block_dynarr **prop, | |
246 int type); | |
247 static void generate_modeline (struct window *w, struct display_line *dl, | |
248 int type); | |
249 static int ensure_modeline_generated (struct window *w, int type); | |
250 #ifdef MODELINE_IS_SCROLLABLE | |
251 static void generate_formatted_string_db (Lisp_Object format_str, | 240 static void generate_formatted_string_db (Lisp_Object format_str, |
252 Lisp_Object result_str, | 241 Lisp_Object result_str, |
253 struct window *w, | 242 struct window *w, |
254 struct display_line *dl, | 243 struct display_line *dl, |
255 struct display_block *db, | 244 struct display_block *db, |
256 face_index findex, int min_pixpos, | 245 face_index findex, int min_pixpos, |
257 int max_pixpos, int type, | 246 int max_pixpos, int type |
258 int modeline); | 247 #ifdef MODELINE_IS_SCROLLABLE |
248 ,int modeline | |
249 #endif | |
250 ); | |
259 static Charcount generate_fstring_runes (struct window *w, pos_data *data, | 251 static Charcount generate_fstring_runes (struct window *w, pos_data *data, |
260 Charcount pos, Charcount min_pos, | 252 Charcount pos, Charcount min_pos, |
261 Charcount max_pos, int no_limit, | 253 Charcount max_pos, |
254 #ifdef MODELINE_IS_SCROLLABLE | |
255 int no_limit, | |
256 #endif | |
262 Lisp_Object elt, | 257 Lisp_Object elt, |
263 int depth, int max_pixsize, | 258 int depth, int max_pixsize, |
264 face_index findex, int type); | 259 face_index findex, int type); |
265 #else /* MODELINE_IS_SCROLLABLE */ | |
266 static void generate_formatted_string_db (Lisp_Object format_str, | |
267 Lisp_Object result_str, | |
268 struct window *w, | |
269 struct display_line *dl, | |
270 struct display_block *db, | |
271 face_index findex, int min_pixpos, | |
272 int max_pixpos, int type); | |
273 static Charcount generate_fstring_runes (struct window *w, pos_data *data, | |
274 Charcount pos, Charcount min_pos, | |
275 Charcount max_pos, Lisp_Object elt, | |
276 int depth, int max_pixsize, | |
277 face_index findex, int type); | |
278 #endif /* not MODELINE_IS_SCROLLABLE */ | |
279 static prop_block_dynarr *add_emchar_rune (pos_data *data); | |
280 static prop_block_dynarr *add_bufbyte_string_runes (pos_data *data, | |
281 Bufbyte *c_string, | |
282 Bytecount c_length, | |
283 int no_prop); | |
284 static prop_block_dynarr *add_blank_rune (pos_data *data, struct window *w, | |
285 int char_tab_width); | |
286 static prop_block_dynarr *add_octal_runes (pos_data *data); | |
287 static prop_block_dynarr *add_control_char_runes (pos_data *data, | |
288 struct buffer *b); | |
289 static prop_block_dynarr *add_disp_table_entry_runes (pos_data *data, | |
290 Lisp_Object entry); | |
291 static prop_block_dynarr *add_propagation_runes (prop_block_dynarr **prop, | |
292 pos_data *data); | |
293 static prop_block_dynarr *add_glyph_rune (pos_data *data, | 260 static prop_block_dynarr *add_glyph_rune (pos_data *data, |
294 struct glyph_block *gb, | 261 struct glyph_block *gb, |
295 int pos_type, int allow_cursor, | 262 int pos_type, int allow_cursor, |
296 struct glyph_cachel *cachel); | 263 struct glyph_cachel *cachel); |
297 static prop_block_dynarr *add_glyph_runes (pos_data *data, | |
298 int pos_type); | |
299 /* NOTE: Bytinds not Bufpos's here. */ | |
300 static Bytind create_text_block (struct window *w, struct display_line *dl, | 264 static Bytind create_text_block (struct window *w, struct display_line *dl, |
301 Bytind bi_start_pos, int start_col, | 265 Bytind bi_start_pos, int start_col, |
302 prop_block_dynarr **prop, int type); | 266 prop_block_dynarr **prop, int type); |
303 static int create_overlay_glyph_block (struct window *w, | 267 static int create_overlay_glyph_block (struct window *w, |
304 struct display_line *dl); | 268 struct display_line *dl); |
305 static void create_left_glyph_block (struct window *w, | 269 static void create_left_glyph_block (struct window *w, |
306 struct display_line *dl, | 270 struct display_line *dl, |
307 int overlay_width); | 271 int overlay_width); |
308 static void create_right_glyph_block (struct window *w, | 272 static void create_right_glyph_block (struct window *w, |
309 struct display_line *dl); | 273 struct display_line *dl); |
310 static void regenerate_window (struct window *w, Bufpos start_pos, | |
311 Bufpos point, int type); | |
312 static Bufpos regenerate_window_point_center (struct window *w, Bufpos point, | |
313 int type); | |
314 int window_half_pixpos (struct window *w); | |
315 int line_at_center (struct window *w, int type, Bufpos start, Bufpos point); | |
316 Bufpos point_at_center (struct window *w, int type, Bufpos start, | |
317 Bufpos point); | |
318 static void redisplay_window (Lisp_Object window, int skip_selected); | |
319 static void redisplay_windows (Lisp_Object window, int skip_selected); | 274 static void redisplay_windows (Lisp_Object window, int skip_selected); |
320 static int redisplay_frame (struct frame *f, int preemption_check); | |
321 void redisplay (void); | |
322 static void decode_mode_spec (struct window *w, Emchar spec, int type); | 275 static void decode_mode_spec (struct window *w, Emchar spec, int type); |
323 static void free_display_line (struct display_line *dl); | 276 static void free_display_line (struct display_line *dl); |
324 void free_display_structs (struct window_mirror *mir); | |
325 static int point_visible (struct window *w, Bufpos point, int type); | |
326 static void update_line_start_cache (struct window *w, Bufpos from, Bufpos to, | 277 static void update_line_start_cache (struct window *w, Bufpos from, Bufpos to, |
327 Bufpos point, int no_regen); | 278 Bufpos point, int no_regen); |
328 static Bufpos line_start_cache_start (struct window *w); | 279 static int point_visible (struct window *w, Bufpos point, int type); |
329 static Bufpos line_start_cache_end (struct window *w); | |
330 | 280 |
331 /* This used to be 10 but 30 seems to give much better performance. */ | 281 /* This used to be 10 but 30 seems to give much better performance. */ |
332 #define INIT_MAX_PREEMPTS 30 | 282 #define INIT_MAX_PREEMPTS 30 |
333 static int max_preempts; | 283 static int max_preempts; |
334 | 284 |
335 #define REDISPLAY_PREEMPTION_CHECK \ | 285 #define REDISPLAY_PREEMPTION_CHECK \ |
336 do { \ | 286 ((void) \ |
337 preempted = 0; \ | 287 (preempted = \ |
338 if (!disable_preemption && \ | 288 (!disable_preemption && \ |
339 ((preemption_count < max_preempts) || !NILP (Vexecuting_macro))) \ | 289 ((preemption_count < max_preempts) || !NILP (Vexecuting_macro)) && \ |
340 if (!INTERACTIVE || detect_input_pending ()) { \ | 290 (!INTERACTIVE || detect_input_pending ())))) |
341 preempted = 1; \ | |
342 } \ | |
343 } while (0) | |
344 | 291 |
345 /* | 292 /* |
346 * Redisplay global variables. | 293 * Redisplay global variables. |
347 */ | 294 */ |
348 | 295 |
528 static int | 475 static int |
529 redisplay_text_width_emchar_string (struct window *w, int findex, | 476 redisplay_text_width_emchar_string (struct window *w, int findex, |
530 Emchar *str, Charcount len) | 477 Emchar *str, Charcount len) |
531 { | 478 { |
532 unsigned char charsets[NUM_LEADING_BYTES]; | 479 unsigned char charsets[NUM_LEADING_BYTES]; |
533 Lisp_Object window = Qnil; | 480 Lisp_Object window; |
534 | 481 |
535 find_charsets_in_emchar_string (charsets, str, len); | 482 find_charsets_in_emchar_string (charsets, str, len); |
536 XSETWINDOW (window, w); | 483 XSETWINDOW (window, w); |
537 ensure_face_cachel_complete (WINDOW_FACE_CACHEL (w, findex), window, | 484 ensure_face_cachel_complete (WINDOW_FACE_CACHEL (w, findex), window, |
538 charsets); | 485 charsets); |
565 redisplay_frame_text_width_string (struct frame *f, Lisp_Object face, | 512 redisplay_frame_text_width_string (struct frame *f, Lisp_Object face, |
566 Bufbyte *nonreloc, Lisp_Object reloc, | 513 Bufbyte *nonreloc, Lisp_Object reloc, |
567 Bytecount offset, Bytecount len) | 514 Bytecount offset, Bytecount len) |
568 { | 515 { |
569 unsigned char charsets[NUM_LEADING_BYTES]; | 516 unsigned char charsets[NUM_LEADING_BYTES]; |
570 Lisp_Object frame = Qnil; | 517 Lisp_Object frame; |
571 struct face_cachel cachel; | 518 struct face_cachel cachel; |
572 | 519 |
573 if (!rtw_emchar_dynarr) | 520 if (!rtw_emchar_dynarr) |
574 rtw_emchar_dynarr = Dynarr_new (Emchar); | 521 rtw_emchar_dynarr = Dynarr_new (Emchar); |
575 Dynarr_reset (rtw_emchar_dynarr); | 522 Dynarr_reset (rtw_emchar_dynarr); |
629 dl->display_blocks = Dynarr_new (display_block); | 576 dl->display_blocks = Dynarr_new (display_block); |
630 } | 577 } |
631 | 578 |
632 /* The line doesn't have a block of the desired type so go ahead and create | 579 /* The line doesn't have a block of the desired type so go ahead and create |
633 one and add it to the line. */ | 580 one and add it to the line. */ |
634 memset (&db, 0, sizeof (struct display_block)); | 581 xzero (db); |
635 db.type = type; | 582 db.type = type; |
636 db.runes = Dynarr_new (rune); | 583 db.runes = Dynarr_new (rune); |
637 Dynarr_add (dl->display_blocks, db); | 584 Dynarr_add (dl->display_blocks, db); |
638 | 585 |
639 /* Return the newly added display block. */ | 586 /* Return the newly added display block. */ |
1900 symbol_value_in_buffer (Qsynchronize_minibuffers, w->buffer); | 1847 symbol_value_in_buffer (Qsynchronize_minibuffers, w->buffer); |
1901 | 1848 |
1902 dl->used_prop_data = 0; | 1849 dl->used_prop_data = 0; |
1903 dl->num_chars = 0; | 1850 dl->num_chars = 0; |
1904 | 1851 |
1905 memset (&data, 0, sizeof (data)); | 1852 xzero (data); |
1906 data.ef = extent_fragment_new (w->buffer, f); | 1853 data.ef = extent_fragment_new (w->buffer, f); |
1907 | 1854 |
1908 /* These values are used by all of the rune addition routines. We add | 1855 /* These values are used by all of the rune addition routines. We add |
1909 them to this structure for ease of passing. */ | 1856 them to this structure for ease of passing. */ |
1910 data.d = d; | 1857 data.d = d; |
2669 | 2616 |
2670 /* If Voverlay_arrow_string isn't valid then just fail silently. */ | 2617 /* If Voverlay_arrow_string isn't valid then just fail silently. */ |
2671 if (!STRINGP (Voverlay_arrow_string) && !GLYPHP (Voverlay_arrow_string)) | 2618 if (!STRINGP (Voverlay_arrow_string) && !GLYPHP (Voverlay_arrow_string)) |
2672 return 0; | 2619 return 0; |
2673 | 2620 |
2674 memset (&data, 0, sizeof (data)); | 2621 xzero (data); |
2675 data.ef = NULL; | 2622 data.ef = NULL; |
2676 data.d = d; | 2623 data.d = d; |
2677 XSETWINDOW (data.window, w); | 2624 XSETWINDOW (data.window, w); |
2678 data.db = get_display_block_from_line (dl, OVERWRITE); | 2625 data.db = get_display_block_from_line (dl, OVERWRITE); |
2679 data.dl = dl; | 2626 data.dl = dl; |
2728 | 2675 |
2729 /* Add a type of glyph to a margin display block. */ | 2676 /* Add a type of glyph to a margin display block. */ |
2730 | 2677 |
2731 static int | 2678 static int |
2732 add_margin_runes (struct display_line *dl, struct display_block *db, int start, | 2679 add_margin_runes (struct display_line *dl, struct display_block *db, int start, |
2733 int count, int glyph_type, int side, Lisp_Object window) | 2680 int count, enum glyph_layout layout, int side, Lisp_Object window) |
2734 { | 2681 { |
2735 glyph_block_dynarr *gbd = (side == LEFT_GLYPHS | 2682 glyph_block_dynarr *gbd = (side == LEFT_GLYPHS |
2736 ? dl->left_glyphs | 2683 ? dl->left_glyphs |
2737 : dl->right_glyphs); | 2684 : dl->right_glyphs); |
2738 int elt, end; | 2685 int elt, end; |
2739 int xpos = start; | 2686 int xpos = start; |
2740 int reverse; | 2687 int reverse; |
2741 | 2688 |
2742 if ((glyph_type == GL_WHITESPACE && side == LEFT_GLYPHS) | 2689 if ((layout == GL_WHITESPACE && side == LEFT_GLYPHS) |
2743 || (glyph_type == GL_INSIDE_MARGIN && side == RIGHT_GLYPHS)) | 2690 || (layout == GL_INSIDE_MARGIN && side == RIGHT_GLYPHS)) |
2744 { | 2691 { |
2745 reverse = 1; | 2692 reverse = 1; |
2746 elt = Dynarr_length (gbd) - 1; | 2693 elt = Dynarr_length (gbd) - 1; |
2747 end = 0; | 2694 end = 0; |
2748 } | 2695 } |
2760 if (NILP (gb->extent)) | 2707 if (NILP (gb->extent)) |
2761 abort (); /* these should have been handled in add_glyph_rune */ | 2708 abort (); /* these should have been handled in add_glyph_rune */ |
2762 | 2709 |
2763 if (gb->active && | 2710 if (gb->active && |
2764 ((side == LEFT_GLYPHS && | 2711 ((side == LEFT_GLYPHS && |
2765 extent_begin_glyph_layout (XEXTENT (gb->extent)) == glyph_type) | 2712 extent_begin_glyph_layout (XEXTENT (gb->extent)) == layout) |
2766 || (side == RIGHT_GLYPHS && | 2713 || (side == RIGHT_GLYPHS && |
2767 extent_end_glyph_layout (XEXTENT (gb->extent)) == glyph_type))) | 2714 extent_end_glyph_layout (XEXTENT (gb->extent)) == layout))) |
2768 { | 2715 { |
2769 struct rune rb; | 2716 struct rune rb; |
2770 | 2717 |
2771 rb.width = gb->width; | 2718 rb.width = gb->width; |
2772 rb.findex = gb->findex; | 2719 rb.findex = gb->findex; |
3578 max_pixpos -= shadow_thickness; | 3525 max_pixpos -= shadow_thickness; |
3579 } | 3526 } |
3580 else | 3527 else |
3581 ypos_adj = 0; | 3528 ypos_adj = 0; |
3582 | 3529 |
3583 #ifdef MODELINE_IS_SCROLLABLE | |
3584 generate_formatted_string_db (b->modeline_format, | 3530 generate_formatted_string_db (b->modeline_format, |
3585 b->generated_modeline_string, w, dl, db, | 3531 b->generated_modeline_string, w, dl, db, |
3586 MODELINE_INDEX, min_pixpos, max_pixpos, type, | 3532 MODELINE_INDEX, min_pixpos, max_pixpos, type |
3587 1 /* generate a modeline */); | 3533 #ifdef MODELINE_IS_SCROLLABLE |
3588 #else | 3534 , 1 /* generate a modeline */ |
3589 generate_formatted_string_db (b->modeline_format, | |
3590 b->generated_modeline_string, w, dl, db, | |
3591 MODELINE_INDEX, min_pixpos, max_pixpos, type); | |
3592 #endif /* not MODELINE_IS_SCROLLABLE */ | 3535 #endif /* not MODELINE_IS_SCROLLABLE */ |
3536 ); | |
3593 | 3537 |
3594 /* The modeline is at the bottom of the gutters. We have to wait to | 3538 /* The modeline is at the bottom of the gutters. We have to wait to |
3595 set this until we've generated teh modeline in order to account | 3539 set this until we've generated teh modeline in order to account |
3596 for any embedded faces. */ | 3540 for any embedded faces. */ |
3597 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj; | 3541 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj; |
3598 } | 3542 } |
3599 | 3543 |
3600 /* This define is for the experimental horizontal modeline scrolling. It's not | 3544 /* This define is for the experimental horizontal modeline scrolling. It's not |
3601 functionnal for 20.5, but might be for 21.1 */ | 3545 functional for 21.0, but might be for 21.1 */ |
3602 #ifdef MODELINE_IS_SCROLLABLE | 3546 #ifdef MODELINE_IS_SCROLLABLE |
3603 static void | 3547 static void |
3604 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str, | 3548 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str, |
3605 struct window *w, struct display_line *dl, | 3549 struct window *w, struct display_line *dl, |
3606 struct display_block *db, face_index findex, | 3550 struct display_block *db, face_index findex, |
3607 int min_pixpos, int max_pixpos, int type, | 3551 int min_pixpos, int max_pixpos, int type, |
3608 int modeline) | 3552 int modeline) |
3609 { | 3553 { |
3610 struct frame *f = XFRAME (w->frame); | 3554 struct frame *f = XFRAME (w->frame); |
3611 struct device *d = XDEVICE (f->device); | 3555 struct device *d = XDEVICE (f->device); |
3612 | 3556 |
3613 pos_data data; | 3557 pos_data data; |
3614 int c_pixpos; | 3558 int c_pixpos; |
3615 | 3559 |
3616 memset (&data, 0, sizeof (data)); | 3560 xzero (data); |
3617 data.d = d; | 3561 data.d = d; |
3618 data.db = db; | 3562 data.db = db; |
3619 data.dl = dl; | 3563 data.dl = dl; |
3620 data.findex = findex; | 3564 data.findex = findex; |
3621 data.pixpos = min_pixpos; | 3565 data.pixpos = min_pixpos; |
3633 | 3577 |
3634 /* D. Verna Feb. 1998. | 3578 /* D. Verna Feb. 1998. |
3635 This recursively builds up the modeline or the title/icon string. | 3579 This recursively builds up the modeline or the title/icon string. |
3636 In case of a modeline, we use a negative start position to indicate | 3580 In case of a modeline, we use a negative start position to indicate |
3637 the current modeline horizontal scroll. */ | 3581 the current modeline horizontal scroll. */ |
3638 generate_fstring_runes | 3582 generate_fstring_runes |
3639 (w, &data, | 3583 (w, &data, |
3640 (modeline && WINDOW_HAS_MODELINE_P (w)) ? - w->modeline_hscroll : 0, | 3584 (modeline && WINDOW_HAS_MODELINE_P (w)) ? - w->modeline_hscroll : 0, |
3641 (modeline && WINDOW_HAS_MODELINE_P (w)) ? - w->modeline_hscroll : 0, | 3585 (modeline && WINDOW_HAS_MODELINE_P (w)) ? - w->modeline_hscroll : 0, |
3642 0, /* no limit */ 1, format_str, 0, max_pixpos - min_pixpos, findex, | 3586 0, /* no limit */ 1, format_str, 0, max_pixpos - min_pixpos, findex, |
3643 type); | 3587 type); |
3644 | 3588 |
3645 if (Dynarr_length (db->runes)) | 3589 if (Dynarr_length (db->runes)) |
3646 { | 3590 { |
3647 struct rune *rb = | 3591 struct rune *rb = |
3648 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1); | 3592 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1); |
3649 c_pixpos = rb->xpos + rb->width; | 3593 c_pixpos = rb->xpos + rb->width; |
3689 } | 3633 } |
3690 | 3634 |
3691 for (elt = 0; elt < Dynarr_length (formatted_string_extent_dynarr); | 3635 for (elt = 0; elt < Dynarr_length (formatted_string_extent_dynarr); |
3692 elt++) | 3636 elt++) |
3693 { | 3637 { |
3694 Lisp_Object extent = Qnil; | 3638 Lisp_Object extent; |
3695 Lisp_Object child; | 3639 Lisp_Object child; |
3696 | 3640 |
3697 XSETEXTENT (extent, Dynarr_at (formatted_string_extent_dynarr, elt)); | 3641 XSETEXTENT (extent, Dynarr_at (formatted_string_extent_dynarr, elt)); |
3698 child = Fgethash (extent, buf->modeline_extent_table, Qnil); | 3642 child = Fgethash (extent, buf->modeline_extent_table, Qnil); |
3699 if (NILP (child)) | 3643 if (NILP (child)) |
3709 result_str); | 3653 result_str); |
3710 } | 3654 } |
3711 } | 3655 } |
3712 } | 3656 } |
3713 | 3657 |
3714 /* D. Verna Feb. 1998. Rewrote this function to handle the case of a | 3658 /* D. Verna Feb. 1998. Rewrote this function to handle the case of a |
3715 scrolled modeline */ | 3659 scrolled modeline */ |
3716 static Charcount | 3660 static Charcount |
3717 add_string_to_fstring_db_runes (pos_data *data, CONST Bufbyte *str, | 3661 add_string_to_fstring_db_runes (pos_data *data, CONST Bufbyte *str, |
3718 Charcount pos, Charcount min_pos, | 3662 Charcount pos, Charcount min_pos, |
3719 Charcount max_pos, int no_limit) | 3663 Charcount max_pos, int no_limit) |
3721 /* This function has been Mule-ized. */ | 3665 /* This function has been Mule-ized. */ |
3722 Charcount initial_pos = pos; | 3666 Charcount initial_pos = pos; |
3723 CONST Bufbyte *cur_pos = str; | 3667 CONST Bufbyte *cur_pos = str; |
3724 struct display_block *db = data->db; | 3668 struct display_block *db = data->db; |
3725 int add_something; | 3669 int add_something; |
3726 | 3670 |
3727 data->blank_width = space_width (XWINDOW (data->window)); | 3671 data->blank_width = space_width (XWINDOW (data->window)); |
3728 add_something = ((pos < min_pos) | 3672 add_something = ((pos < min_pos) |
3729 || ((*cur_pos) && no_limit) | 3673 || ((*cur_pos) && no_limit) |
3730 || ((*cur_pos) && (pos < max_pos))); | 3674 || ((*cur_pos) && (pos < max_pos))); |
3731 while (add_something) | 3675 while (add_something) |
3732 { | 3676 { |
3733 if ((initial_pos >= 0) && (pos == initial_pos)) | 3677 if ((initial_pos >= 0) && (pos == initial_pos)) |
3734 while (Dynarr_length (db->runes) < pos) | 3678 while (Dynarr_length (db->runes) < pos) |
3735 add_blank_rune (data, NULL, 0); | 3679 add_blank_rune (data, NULL, 0); |
3736 | 3680 |
3737 if (pos < 0) /* just pretend we're adding something */ | 3681 if (pos < 0) /* just pretend we're adding something */ |
3738 { | 3682 { |
3739 if (*cur_pos) | 3683 if (*cur_pos) |
3740 INC_CHARPTR (cur_pos); | 3684 INC_CHARPTR (cur_pos); |
3741 pos += 1; | 3685 pos += 1; |
3744 { | 3688 { |
3745 if (*cur_pos) /* some stuff to add */ | 3689 if (*cur_pos) /* some stuff to add */ |
3746 { | 3690 { |
3747 CONST Bufbyte *old_cur_pos = cur_pos; | 3691 CONST Bufbyte *old_cur_pos = cur_pos; |
3748 int succeeded; | 3692 int succeeded; |
3749 | 3693 |
3750 data->ch = charptr_emchar (cur_pos); | 3694 data->ch = charptr_emchar (cur_pos); |
3751 succeeded = (add_emchar_rune (data) != ADD_FAILED); | 3695 succeeded = (add_emchar_rune (data) != ADD_FAILED); |
3752 INC_CHARPTR (cur_pos); | 3696 INC_CHARPTR (cur_pos); |
3753 if (succeeded) | 3697 if (succeeded) |
3754 { | 3698 { |
3770 if (*cur_pos) | 3714 if (*cur_pos) |
3771 INC_CHARPTR (cur_pos); | 3715 INC_CHARPTR (cur_pos); |
3772 pos += 1; | 3716 pos += 1; |
3773 } | 3717 } |
3774 } | 3718 } |
3775 add_something = ((pos < min_pos) | 3719 add_something = ((pos < min_pos) |
3776 || ((*cur_pos) && no_limit) | 3720 || ((*cur_pos) && no_limit) |
3777 || ((*cur_pos) && (pos < max_pos))); | 3721 || ((*cur_pos) && (pos < max_pos))); |
3778 } | 3722 } |
3779 | 3723 |
3780 return pos; | 3724 return pos; |
3782 | 3726 |
3783 /* #### Urk! Should also handle begin-glyphs and end-glyphs in | 3727 /* #### Urk! Should also handle begin-glyphs and end-glyphs in |
3784 modeline extents. */ | 3728 modeline extents. */ |
3785 static Charcount | 3729 static Charcount |
3786 add_glyph_to_fstring_db_runes (pos_data *data, Lisp_Object glyph, | 3730 add_glyph_to_fstring_db_runes (pos_data *data, Lisp_Object glyph, |
3787 Charcount pos, Charcount min_pos, | 3731 Charcount pos, Charcount min_pos, |
3788 Charcount max_pos, int no_limit) | 3732 Charcount max_pos, int no_limit) |
3789 { | 3733 { |
3790 /* This function has been Mule-ized. */ | 3734 /* This function has been Mule-ized. */ |
3791 Charcount end; | 3735 Charcount end; |
3792 struct display_block *db = data->db; | 3736 struct display_block *db = data->db; |
3793 struct glyph_block gb; | 3737 struct glyph_block gb; |
3794 | 3738 |
3795 /* D. Verna Feb. 1998. | 3739 /* D. Verna Feb. 1998. |
3796 If pos < 0, we're building a scrolled modeline. | 3740 If pos < 0, we're building a scrolled modeline. |
3797 The glyph should be hidden. So just skip it. */ | 3741 The glyph should be hidden. So just skip it. */ |
3798 if (pos < 0) | 3742 if (pos < 0) |
3799 return (pos + 1); | 3743 return (pos + 1); |
3800 | 3744 |
3801 data->blank_width = space_width (XWINDOW (data->window)); | 3745 data->blank_width = space_width (XWINDOW (data->window)); |
3802 while (Dynarr_length (db->runes) < pos) | 3746 while (Dynarr_length (db->runes) < pos) |
3803 add_blank_rune (data, NULL, 0); | 3747 add_blank_rune (data, NULL, 0); |
3804 | 3748 |
3805 end = Dynarr_length (db->runes) + 1; | 3749 end = Dynarr_length (db->runes) + 1; |
3806 if (!no_limit) | 3750 if (!no_limit) |
3807 end = min (max_pos, end); | 3751 end = min (max_pos, end); |
3808 | 3752 |
3809 gb.glyph = glyph; | 3753 gb.glyph = glyph; |
3810 gb.extent = Qnil; | 3754 gb.extent = Qnil; |
3811 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0); | 3755 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0); |
3812 pos++; | 3756 pos++; |
3813 | 3757 |
3852 | 3796 |
3853 if (STRINGP (elt)) | 3797 if (STRINGP (elt)) |
3854 { | 3798 { |
3855 /* A string. Add to the display line and check for %-constructs | 3799 /* A string. Add to the display line and check for %-constructs |
3856 within it. */ | 3800 within it. */ |
3857 | 3801 |
3858 Bufbyte *this = XSTRING_DATA (elt); | 3802 Bufbyte *this = XSTRING_DATA (elt); |
3859 | 3803 |
3860 while ((no_limit || pos < max_pos) && *this) | 3804 while ((no_limit || pos < max_pos) && *this) |
3861 { | 3805 { |
3862 Bufbyte *last = this; | 3806 Bufbyte *last = this; |
3863 | 3807 |
3864 while (*this && *this != '%') | 3808 while (*this && *this != '%') |
3865 this++; | 3809 this++; |
3866 | 3810 |
3867 if (this != last) | 3811 if (this != last) |
3868 { | 3812 { |
3869 /* The string is just a string. */ | 3813 /* The string is just a string. */ |
3870 Charcount size = | 3814 Charcount size = |
3871 bytecount_to_charcount (last, this - last) + pos; | 3815 bytecount_to_charcount (last, this - last) + pos; |
3872 Charcount tmp_max = (no_limit ? size : min (size, max_pos)); | 3816 Charcount tmp_max = (no_limit ? size : min (size, max_pos)); |
3873 | 3817 |
3874 pos = add_string_to_fstring_db_runes (data, last, pos, pos, | 3818 pos = add_string_to_fstring_db_runes (data, last, pos, pos, |
3875 tmp_max, /* limit */0); | 3819 tmp_max, /* limit */0); |
3876 } | 3820 } |
3877 else /* *this == '%' */ | 3821 else /* *this == '%' */ |
3878 { | 3822 { |
3923 num_to_add++; | 3867 num_to_add++; |
3924 } | 3868 } |
3925 | 3869 |
3926 while (num_to_add--) | 3870 while (num_to_add--) |
3927 pos = add_string_to_fstring_db_runes | 3871 pos = add_string_to_fstring_db_runes |
3928 (data, (CONST Bufbyte *) "-", | 3872 (data, (CONST Bufbyte *) "-", |
3929 pos, pos, max_pos, no_limit); | 3873 pos, pos, max_pos, no_limit); |
3930 } | 3874 } |
3931 else if (*this != 0) | 3875 else if (*this != 0) |
3932 { | 3876 { |
3933 Bufbyte *str; | 3877 Bufbyte *str; |
4065 { | 4009 { |
4066 int limit = 50; | 4010 int limit = 50; |
4067 /* LIMIT is to protect against circular lists. */ | 4011 /* LIMIT is to protect against circular lists. */ |
4068 while (CONSP (elt) && --limit > 0 && (no_limit || pos < max_pos)) | 4012 while (CONSP (elt) && --limit > 0 && (no_limit || pos < max_pos)) |
4069 { | 4013 { |
4070 pos = generate_fstring_runes (w, data, pos, pos, max_pos, | 4014 pos = generate_fstring_runes (w, data, pos, pos, max_pos, |
4071 no_limit, | 4015 no_limit, |
4072 XCAR (elt), depth, | 4016 XCAR (elt), depth, |
4073 max_pixsize, findex, type); | 4017 max_pixsize, findex, type); |
4074 elt = XCDR (elt); | 4018 elt = XCDR (elt); |
4075 } | 4019 } |
4105 } | 4049 } |
4106 else | 4050 else |
4107 new_findex = old_findex; | 4051 new_findex = old_findex; |
4108 | 4052 |
4109 data->findex = new_findex; | 4053 data->findex = new_findex; |
4110 pos = generate_fstring_runes (w, data, pos, pos, max_pos, | 4054 pos = generate_fstring_runes (w, data, pos, pos, max_pos, |
4111 no_limit, | 4055 no_limit, |
4112 XCDR (elt), depth - 1, | 4056 XCDR (elt), depth - 1, |
4113 max_pixsize, new_findex, type); | 4057 max_pixsize, new_findex, type); |
4114 data->findex = old_findex; | 4058 data->findex = old_findex; |
4115 Dynarr_add (formatted_string_extent_dynarr, ext); | 4059 Dynarr_add (formatted_string_extent_dynarr, ext); |
4118 } | 4062 } |
4119 } | 4063 } |
4120 } | 4064 } |
4121 else if (GLYPHP (elt)) | 4065 else if (GLYPHP (elt)) |
4122 { | 4066 { |
4123 pos = add_glyph_to_fstring_db_runes | 4067 pos = add_glyph_to_fstring_db_runes |
4124 (data, elt, pos, pos, max_pos, no_limit); | 4068 (data, elt, pos, pos, max_pos, no_limit); |
4125 } | 4069 } |
4126 else | 4070 else |
4127 { | 4071 { |
4128 invalid: | 4072 invalid: |
4151 struct device *d = XDEVICE (f->device); | 4095 struct device *d = XDEVICE (f->device); |
4152 | 4096 |
4153 pos_data data; | 4097 pos_data data; |
4154 int c_pixpos; | 4098 int c_pixpos; |
4155 | 4099 |
4156 memset (&data, 0, sizeof (data)); | 4100 xzero (data); |
4157 data.d = d; | 4101 data.d = d; |
4158 data.db = db; | 4102 data.db = db; |
4159 data.dl = dl; | 4103 data.dl = dl; |
4160 data.findex = findex; | 4104 data.findex = findex; |
4161 data.pixpos = min_pixpos; | 4105 data.pixpos = min_pixpos; |
4648 db = get_display_block_from_line (dl, TEXT); | 4592 db = get_display_block_from_line (dl, TEXT); |
4649 Dynarr_reset (db->runes); | 4593 Dynarr_reset (db->runes); |
4650 | 4594 |
4651 #ifdef MODELINE_IS_SCROLLABLE | 4595 #ifdef MODELINE_IS_SCROLLABLE |
4652 /* D. Verna Feb. 1998. | 4596 /* D. Verna Feb. 1998. |
4653 Currently, only update_frame_title can make us come here. This is not | 4597 Currently, only update_frame_title can make us come here. This is not |
4654 to build a modeline */ | 4598 to build a modeline */ |
4655 generate_formatted_string_db (format_str, result_str, w, dl, db, findex, 0, | 4599 generate_formatted_string_db (format_str, result_str, w, dl, db, findex, 0, |
4656 -1, type, 0 /* not a modeline */); | 4600 -1, type, 0 /* not a modeline */); |
4657 #else /* not MODELINE_IS_SCROLLABLE */ | 4601 #else /* not MODELINE_IS_SCROLLABLE */ |
4658 generate_formatted_string_db (format_str, result_str, w, dl, db, findex, 0, | 4602 generate_formatted_string_db (format_str, result_str, w, dl, db, findex, 0, |
4729 Dynarr_add (dla, *mlp); | 4673 Dynarr_add (dla, *mlp); |
4730 } | 4674 } |
4731 else | 4675 else |
4732 { | 4676 { |
4733 struct display_line modeline; | 4677 struct display_line modeline; |
4734 memset (&modeline, 0, sizeof (struct display_line)); | 4678 xzero (modeline); |
4735 Dynarr_add (dla, modeline); | 4679 Dynarr_add (dla, modeline); |
4736 } | 4680 } |
4737 } | 4681 } |
4738 | 4682 |
4739 /* If we're adding a new place marker go ahead and generate the | 4683 /* If we're adding a new place marker go ahead and generate the |
4850 dlp = Dynarr_atp (dla, Dynarr_length (dla)); | 4794 dlp = Dynarr_atp (dla, Dynarr_length (dla)); |
4851 local = 0; | 4795 local = 0; |
4852 } | 4796 } |
4853 else | 4797 else |
4854 { | 4798 { |
4799 xzero (dl); | |
4855 dlp = &dl; | 4800 dlp = &dl; |
4856 memset (dlp, 0, sizeof (struct display_line)); | |
4857 local = 1; | 4801 local = 1; |
4858 } | 4802 } |
4859 | 4803 |
4860 dlp->bounds = bounds; | 4804 dlp->bounds = bounds; |
4861 dlp->offset = 0; | 4805 dlp->offset = 0; |
5905 return 0; | 5849 return 0; |
5906 } | 5850 } |
5907 | 5851 |
5908 if (lrpos >= pos) | 5852 if (lrpos >= pos) |
5909 { | 5853 { |
5910 Lisp_Object window = Qnil; | 5854 Lisp_Object window; |
5911 XSETWINDOW (window, w); | 5855 XSETWINDOW (window, w); |
5912 va_run_hook_with_args_in_buffer (XBUFFER (w->buffer), | 5856 va_run_hook_with_args_in_buffer (XBUFFER (w->buffer), |
5913 Qredisplay_end_trigger_functions, | 5857 Qredisplay_end_trigger_functions, |
5914 2, window, | 5858 2, window, |
5915 w->redisplay_end_trigger); | 5859 w->redisplay_end_trigger); |
6386 #ifdef HAVE_TTY | 6330 #ifdef HAVE_TTY |
6387 { | 6331 { |
6388 struct frame *f = XFRAME (w->frame); | 6332 struct frame *f = XFRAME (w->frame); |
6389 if (FRAME_TTY_P (f) && f->order_count > 1) | 6333 if (FRAME_TTY_P (f) && f->order_count > 1) |
6390 { | 6334 { |
6391 str = (CONST char *) alloca (10); | 6335 char * writable_str = alloca_array (char, 10); |
6392 sprintf (str, "-%d", f->order_count); | 6336 sprintf (writable_str, "-%d", f->order_count); |
6337 str = writable_str; | |
6393 } | 6338 } |
6394 } | 6339 } |
6395 #endif /* HAVE_TTY */ | 6340 #endif /* HAVE_TTY */ |
6396 break; | 6341 break; |
6397 | 6342 |
7392 if (cur_elt + new_line >= Dynarr_length (w->line_start_cache)) | 7337 if (cur_elt + new_line >= Dynarr_length (w->line_start_cache)) |
7393 { | 7338 { |
7394 /* Hit the bottom of the buffer. */ | 7339 /* Hit the bottom of the buffer. */ |
7395 int adjustment = | 7340 int adjustment = |
7396 (cur_elt + new_line) - Dynarr_length (w->line_start_cache) + 1; | 7341 (cur_elt + new_line) - Dynarr_length (w->line_start_cache) + 1; |
7397 Lisp_Object window = Qnil; | 7342 Lisp_Object window; |
7398 int defheight; | 7343 int defheight; |
7399 | 7344 |
7400 XSETWINDOW (window, w); | 7345 XSETWINDOW (window, w); |
7401 default_face_height_and_width (window, &defheight, 0); | 7346 default_face_height_and_width (window, &defheight, 0); |
7402 | 7347 |
7601 int old_lb = low_bound; | 7546 int old_lb = low_bound; |
7602 | 7547 |
7603 while (startp < old_lb || low_bound == -1) | 7548 while (startp < old_lb || low_bound == -1) |
7604 { | 7549 { |
7605 int ic_elt; | 7550 int ic_elt; |
7551 Bufpos new_startp; | |
7606 | 7552 |
7607 regenerate_window (w, startp, point, CMOTION_DISP); | 7553 regenerate_window (w, startp, point, CMOTION_DISP); |
7608 update_internal_cache_list (w, CMOTION_DISP); | 7554 update_internal_cache_list (w, CMOTION_DISP); |
7609 | 7555 |
7610 /* If this assert is triggered then regenerate_window failed | 7556 /* If this assert is triggered then regenerate_window failed |
7638 ic_elt--; | 7584 ic_elt--; |
7639 } | 7585 } |
7640 } | 7586 } |
7641 assert (ic_elt >= 0); | 7587 assert (ic_elt >= 0); |
7642 | 7588 |
7643 Dynarr_insert_many (cache, Dynarr_atp (internal_cache, 0), | 7589 new_startp = Dynarr_atp (internal_cache, ic_elt)->end + 1; |
7644 ic_elt + 1, marker); | 7590 |
7645 marker += (ic_elt + 1); | 7591 /* |
7592 * Handle invisible text properly: | |
7593 * If the last line we're inserting has the same end as the | |
7594 * line before which it will be added, merge the two lines. | |
7595 */ | |
7596 if (Dynarr_length (cache) && | |
7597 Dynarr_atp (internal_cache, ic_elt)->end == | |
7598 Dynarr_atp (cache, marker)->end) | |
7599 { | |
7600 Dynarr_atp (cache, marker)->start | |
7601 = Dynarr_atp (internal_cache, ic_elt)->start; | |
7602 Dynarr_atp (cache, marker)->height | |
7603 = Dynarr_atp (internal_cache, ic_elt)->height; | |
7604 ic_elt--; | |
7605 } | |
7606 | |
7607 if (ic_elt >= 0) /* we still have lines to add.. */ | |
7608 { | |
7609 Dynarr_insert_many (cache, Dynarr_atp (internal_cache, 0), | |
7610 ic_elt + 1, marker); | |
7611 marker += (ic_elt + 1); | |
7612 } | |
7646 | 7613 |
7647 if (startp < low_bound || low_bound == -1) | 7614 if (startp < low_bound || low_bound == -1) |
7648 low_bound = startp; | 7615 low_bound = startp; |
7649 startp = Dynarr_atp (internal_cache, ic_elt)->end + 1; | 7616 startp = new_startp; |
7650 if (startp > BUF_ZV (b)) | 7617 if (startp > BUF_ZV (b)) |
7651 { | 7618 { |
7652 updating_line_start_cache = 0; | 7619 updating_line_start_cache = 0; |
7653 w->line_cache_validation_override--; | 7620 w->line_cache_validation_override--; |
7654 return; | 7621 return; |
7701 glyph_to_pixel_translation (struct window *w, int char_x, int char_y, | 7668 glyph_to_pixel_translation (struct window *w, int char_x, int char_y, |
7702 int *pix_x, int *pix_y) | 7669 int *pix_x, int *pix_y) |
7703 { | 7670 { |
7704 display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP); | 7671 display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP); |
7705 int num_disp_lines, modeline; | 7672 int num_disp_lines, modeline; |
7706 Lisp_Object window = Qnil; | 7673 Lisp_Object window; |
7707 int defheight, defwidth; | 7674 int defheight, defwidth; |
7708 | 7675 |
7709 XSETWINDOW (window, w); | 7676 XSETWINDOW (window, w); |
7710 default_face_height_and_width (window, &defheight, &defwidth); | 7677 default_face_height_and_width (window, &defheight, &defwidth); |
7711 | 7678 |
8354 | 8321 |
8355 if (bot_elt >= 0) | 8322 if (bot_elt >= 0) |
8356 { | 8323 { |
8357 struct display_line *dl = Dynarr_atp (dla, bot_elt); | 8324 struct display_line *dl = Dynarr_atp (dla, bot_elt); |
8358 int adj_area = y_coord - (dl->ypos + dl->descent); | 8325 int adj_area = y_coord - (dl->ypos + dl->descent); |
8359 Lisp_Object lwin = Qnil; | 8326 Lisp_Object lwin; |
8360 int defheight; | 8327 int defheight; |
8361 | 8328 |
8362 XSETWINDOW (lwin, *w); | 8329 XSETWINDOW (lwin, *w); |
8363 default_face_height_and_width (lwin, 0, &defheight); | 8330 default_face_height_and_width (lwin, 0, &defheight); |
8364 | 8331 |
8732 formatted_string_emchar_dynarr = Dynarr_new (Emchar); | 8699 formatted_string_emchar_dynarr = Dynarr_new (Emchar); |
8733 formatted_string_extent_dynarr = Dynarr_new (EXTENT); | 8700 formatted_string_extent_dynarr = Dynarr_new (EXTENT); |
8734 formatted_string_extent_start_dynarr = Dynarr_new (Bytecount); | 8701 formatted_string_extent_start_dynarr = Dynarr_new (Bytecount); |
8735 formatted_string_extent_end_dynarr = Dynarr_new (Bytecount); | 8702 formatted_string_extent_end_dynarr = Dynarr_new (Bytecount); |
8736 internal_cache = Dynarr_new (line_start_cache); | 8703 internal_cache = Dynarr_new (line_start_cache); |
8737 memset (&formatted_string_display_line, 0, sizeof (struct display_line)); | 8704 xzero (formatted_string_display_line); |
8738 } | 8705 } |
8739 | 8706 |
8740 /* window system is nil when in -batch mode */ | 8707 /* window system is nil when in -batch mode */ |
8741 if (!initialized || noninteractive) | 8708 if (!initialized || noninteractive) |
8742 return; | 8709 return; |
8830 | 8797 |
8831 updating_line_start_cache = 0; | 8798 updating_line_start_cache = 0; |
8832 | 8799 |
8833 /* #### Probably temporary */ | 8800 /* #### Probably temporary */ |
8834 DEFVAR_INT ("redisplay-cache-adjustment", &cache_adjustment /* | 8801 DEFVAR_INT ("redisplay-cache-adjustment", &cache_adjustment /* |
8835 (Temporary) Setting this will impact the performance of the internal | 8802 \(Temporary) Setting this will impact the performance of the internal |
8836 line start cache. | 8803 line start cache. |
8837 */ ); | 8804 */ ); |
8838 cache_adjustment = 2; | 8805 cache_adjustment = 2; |
8839 | 8806 |
8840 DEFVAR_INT_MAGIC ("pixel-vertical-clip-threshold", &vertical_clip /* | 8807 DEFVAR_INT_MAGIC ("pixel-vertical-clip-threshold", &vertical_clip /* |