comparison src/redisplay.c @ 422:95016f13131a r21-2-19

Import from CVS: tag r21-2-19
author cvs
date Mon, 13 Aug 2007 11:25:01 +0200
parents 697ef44129c6
children 11054d720c21
comparison
equal deleted inserted replaced
421:fff06e11db74 422:95016f13131a
49 #include "elhash.h" 49 #include "elhash.h"
50 #include "extents.h" 50 #include "extents.h"
51 #include "faces.h" 51 #include "faces.h"
52 #include "frame.h" 52 #include "frame.h"
53 #include "glyphs.h" 53 #include "glyphs.h"
54 #include "gutter.h"
54 #include "insdel.h" 55 #include "insdel.h"
55 #include "menubar.h" 56 #include "menubar.h"
56 #include "objects.h" 57 #include "objects.h"
57 #include "process.h" 58 #include "process.h"
58 #include "redisplay.h" 59 #include "redisplay.h"
105 typedef struct position_redisplay_data_type 106 typedef struct position_redisplay_data_type
106 { 107 {
107 /* This information is normally filled in by the create_*_block 108 /* This information is normally filled in by the create_*_block
108 routines and is used by the add_*_rune routines. */ 109 routines and is used by the add_*_rune routines. */
109 Lisp_Object window; 110 Lisp_Object window;
111 /* if we are working with strings rather than buffers we need a
112 handle to the string */
113 Lisp_Object string;
110 struct device *d; 114 struct device *d;
111 struct display_block *db; 115 struct display_block *db;
112 struct display_line *dl; 116 struct display_line *dl;
113 Emchar ch; /* Character that is to be added. This is 117 Emchar ch; /* Character that is to be added. This is
114 used to communicate this information to 118 used to communicate this information to
269 static void decode_mode_spec (struct window *w, Emchar spec, int type); 273 static void decode_mode_spec (struct window *w, Emchar spec, int type);
270 static void free_display_line (struct display_line *dl); 274 static void free_display_line (struct display_line *dl);
271 static void update_line_start_cache (struct window *w, Bufpos from, Bufpos to, 275 static void update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
272 Bufpos point, int no_regen); 276 Bufpos point, int no_regen);
273 static int point_visible (struct window *w, Bufpos point, int type); 277 static int point_visible (struct window *w, Bufpos point, int type);
278 extern Bytind bi_find_next_emchar_in_string (struct Lisp_String* str, Emchar target,
279 Bytind st, EMACS_INT count);
280 extern int string_column_at_point (struct Lisp_String* s, Bufpos init_pos, int tab_width);
274 281
275 /* This used to be 10 but 30 seems to give much better performance. */ 282 /* This used to be 10 but 30 seems to give much better performance. */
276 #define INIT_MAX_PREEMPTS 30 283 #define INIT_MAX_PREEMPTS 30
277 static int max_preempts; 284 static int max_preempts;
278 285
399 406
400 /* non-nil if any toolbar has changed */ 407 /* non-nil if any toolbar has changed */
401 int toolbar_changed; 408 int toolbar_changed;
402 int toolbar_changed_set; 409 int toolbar_changed_set;
403 410
411 /* non-nil if any gutter has changed */
412 int gutter_changed;
413 int gutter_changed_set;
414
404 /* non-nil if any window has changed since the last time redisplay completed */ 415 /* non-nil if any window has changed since the last time redisplay completed */
405 int windows_changed; 416 int windows_changed;
406 417
407 /* non-nil if any frame's window structure has changed since the last 418 /* non-nil if any frame's window structure has changed since the last
408 time redisplay completed */ 419 time redisplay completed */
900 911
901 crb->findex = data->findex; 912 crb->findex = data->findex;
902 crb->xpos = data->pixpos; 913 crb->xpos = data->pixpos;
903 crb->width = width; 914 crb->width = width;
904 if (data->bi_bufpos) 915 if (data->bi_bufpos)
905 crb->bufpos = 916 {
906 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))), 917 if (NILP (data->string))
907 data->bi_bufpos); 918 crb->bufpos =
919 bytind_to_bufpos (XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))),
920 data->bi_bufpos);
921 else
922 crb->bufpos =
923 bytecount_to_charcount (XSTRING_DATA (data->string), data->bi_bufpos);
924 }
908 else if (data->is_modeline) 925 else if (data->is_modeline)
909 crb->bufpos = data->modeline_charpos; 926 crb->bufpos = data->modeline_charpos;
910 else 927 else
911 /* fuckme if this shouldn't be an abort. */ 928 /* fuckme if this shouldn't be an abort. */
912 /* abort (); fuckme harder, this abort gets tripped quite often, 929 /* abort (); fuckme harder, this abort gets tripped quite often,
1864 1881
1865 /* These values are used by all of the rune addition routines. We add 1882 /* These values are used by all of the rune addition routines. We add
1866 them to this structure for ease of passing. */ 1883 them to this structure for ease of passing. */
1867 data.d = d; 1884 data.d = d;
1868 XSETWINDOW (data.window, w); 1885 XSETWINDOW (data.window, w);
1886 data.string = Qnil;
1869 data.db = db; 1887 data.db = db;
1870 data.dl = dl; 1888 data.dl = dl;
1871 1889
1872 data.bi_bufpos = bi_start_pos; 1890 data.bi_bufpos = bi_start_pos;
1873 data.pixpos = dl->bounds.left_in; 1891 data.pixpos = dl->bounds.left_in;
2641 data.cursor_x = -1; 2659 data.cursor_x = -1;
2642 data.findex = DEFAULT_INDEX; 2660 data.findex = DEFAULT_INDEX;
2643 data.last_charset = Qunbound; 2661 data.last_charset = Qunbound;
2644 data.last_findex = DEFAULT_INDEX; 2662 data.last_findex = DEFAULT_INDEX;
2645 data.result_str = Qnil; 2663 data.result_str = Qnil;
2664 data.string = Qnil;
2646 2665
2647 Dynarr_reset (data.db->runes); 2666 Dynarr_reset (data.db->runes);
2648 2667
2649 if (STRINGP (Voverlay_arrow_string)) 2668 if (STRINGP (Voverlay_arrow_string))
2650 { 2669 {
3491 dl->ascent = DEVMETH (d, divider_height, ()); 3510 dl->ascent = DEVMETH (d, divider_height, ());
3492 dl->descent = 0; 3511 dl->descent = 0;
3493 /* The modeline is at the bottom of the gutters. */ 3512 /* The modeline is at the bottom of the gutters. */
3494 dl->ypos = WINDOW_BOTTOM (w); 3513 dl->ypos = WINDOW_BOTTOM (w);
3495 3514
3515 /* adjust for the bottom gutter */
3516 if (window_is_lowest (w))
3517 dl->ypos -= FRAME_BOTTOM_GUTTER_BOUNDS (f);
3518
3496 rb.findex = MODELINE_INDEX; 3519 rb.findex = MODELINE_INDEX;
3497 rb.xpos = dl->bounds.left_out; 3520 rb.xpos = dl->bounds.left_out;
3498 rb.width = dl->bounds.right_out - dl->bounds.left_out; 3521 rb.width = dl->bounds.right_out - dl->bounds.left_out;
3499 rb.bufpos = 0; 3522 rb.bufpos = 0;
3500 rb.endpos = 0; 3523 rb.endpos = 0;
3544 3567
3545 /* The modeline is at the bottom of the gutters. We have to wait to 3568 /* The modeline is at the bottom of the gutters. We have to wait to
3546 set this until we've generated the modeline in order to account 3569 set this until we've generated the modeline in order to account
3547 for any embedded faces. */ 3570 for any embedded faces. */
3548 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj; 3571 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj;
3572 /* adjust for the bottom gutter */
3573 if (window_is_lowest (w))
3574 dl->ypos -= FRAME_BOTTOM_GUTTER_BOUNDS (f);
3549 } 3575 }
3550 3576
3551 static void 3577 static void
3552 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str, 3578 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str,
3553 struct window *w, struct display_line *dl, 3579 struct window *w, struct display_line *dl,
3570 data.cursor_type = NO_CURSOR; 3596 data.cursor_type = NO_CURSOR;
3571 data.last_charset = Qunbound; 3597 data.last_charset = Qunbound;
3572 data.last_findex = DEFAULT_INDEX; 3598 data.last_findex = DEFAULT_INDEX;
3573 data.result_str = result_str; 3599 data.result_str = result_str;
3574 data.is_modeline = 1; 3600 data.is_modeline = 1;
3601 data.string = Qnil;
3575 XSETWINDOW (data.window, w); 3602 XSETWINDOW (data.window, w);
3576 3603
3577 Dynarr_reset (formatted_string_extent_dynarr); 3604 Dynarr_reset (formatted_string_extent_dynarr);
3578 Dynarr_reset (formatted_string_extent_start_dynarr); 3605 Dynarr_reset (formatted_string_extent_start_dynarr);
3579 Dynarr_reset (formatted_string_extent_end_dynarr); 3606 Dynarr_reset (formatted_string_extent_end_dynarr);
4176 return 0; 4203 return 0;
4177 } 4204 }
4178 4205
4179 4206
4180 /***************************************************************************/ 4207 /***************************************************************************/
4208 /* */
4209 /* displayable string routines */
4210 /* */
4211 /***************************************************************************/
4212
4213 /* Given a position for a string in a window, ensure that the given
4214 display line DL accurately represents the text on a line starting
4215 at the given position.
4216
4217 Yes, this is duplicating the code of create_text_block, but it
4218 looked just too hard to change create_text_block to handle strings
4219 *and* buffers. We already make a distinction between the two
4220 elsewhere in the code so I think unifying them would require a
4221 complete MULE rewrite. Besides, the other distinction is that these
4222 functions cover text that the user *cannot edit* so we can remove
4223 everything to do with cursors, minibuffers etc. Eventually the
4224 modeline routines should be modified to use this code as it copes
4225 with many more types of display situation. */
4226
4227 static Bufpos
4228 create_string_text_block (struct window *w, Lisp_Object disp_string,
4229 struct display_line *dl,
4230 Bufpos start_pos,
4231 prop_block_dynarr **prop,
4232 face_index default_face)
4233 {
4234 struct frame *f = XFRAME (w->frame);
4235 /* Note that a lot of the buffer controlled stuff has been left in
4236 because you might well want to make use of it (selective display
4237 etc), its just the buffer text that we do not use. */
4238 struct buffer *b = XBUFFER (w->buffer);
4239 struct device *d = XDEVICE (f->device);
4240 struct Lisp_String* s = XSTRING (disp_string);
4241
4242 /* we're working with these a lot so precalculate them */
4243 Bytecount slen = XSTRING_LENGTH (disp_string);
4244 Bytecount bi_string_zv = slen;
4245 Bytind bi_start_pos = charcount_to_bytecount (string_data (s), start_pos);
4246
4247 pos_data data;
4248
4249 int truncate_win = window_truncation_on (w);
4250 int end_glyph_width = 0;
4251
4252 /* we're going to ditch selective display for static text, its an
4253 FSF thing and invisble extents are the way to go
4254 here. Implementing it also relies on a number of buffer-specific
4255 functions that we don't have the luxury of being able to use
4256 here. */
4257
4258 /* The variable ctl-arrow allows the user to specify what characters
4259 can actually be displayed and which octal should be used for.
4260 #### This variable should probably have some rethought done to
4261 it.
4262
4263 #### It would also be really nice if you could specify that
4264 the characters come out in hex instead of in octal. Mule
4265 does that by adding a ctl-hexa variable similar to ctl-arrow,
4266 but that's bogus -- we need a more general solution. I
4267 think you need to extend the concept of display tables
4268 into a more general conversion mechanism. Ideally you
4269 could specify a Lisp function that converts characters,
4270 but this violates the Second Golden Rule and besides would
4271 make things way way way way slow.
4272
4273 So instead, we extend the display-table concept, which was
4274 historically limited to 256-byte vectors, to one of the
4275 following:
4276
4277 a) A 256-entry vector, for backward compatibility;
4278 b) char-table, mapping characters to values;
4279 c) range-table, mapping ranges of characters to values;
4280 d) a list of the above.
4281
4282 The (d) option allows you to specify multiple display tables
4283 instead of just one. Each display table can specify conversions
4284 for some characters and leave others unchanged. The way the
4285 character gets displayed is determined by the first display table
4286 with a binding for that character. This way, you could call a
4287 function `enable-hex-display' that adds a hex display-table to
4288 the list of display tables for the current buffer.
4289
4290 #### ...not yet implemented... Also, we extend the concept of
4291 "mapping" to include a printf-like spec. Thus you can make all
4292 extended characters show up as hex with a display table like
4293 this:
4294
4295 #s(range-table data ((256 524288) (format "%x")))
4296
4297 Since more than one display table is possible, you have
4298 great flexibility in mapping ranges of characters. */
4299 Emchar printable_min = (CHAR_OR_CHAR_INTP (b->ctl_arrow)
4300 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
4301 : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
4302 ? 255 : 160));
4303
4304 Lisp_Object face_dt, window_dt;
4305
4306 /* The text display block for this display line. */
4307 struct display_block *db = get_display_block_from_line (dl, TEXT);
4308
4309 /* The first time through the main loop we need to force the glyph
4310 data to be updated. */
4311 int initial = 1;
4312
4313 /* Apparently the new extent_fragment_update returns an end position
4314 equal to the position passed in if there are no more runs to be
4315 displayed. */
4316 int no_more_frags = 0;
4317
4318 dl->used_prop_data = 0;
4319 dl->num_chars = 0;
4320
4321 /* set up faces to use for clearing areas, used by
4322 output_display_line */
4323 dl->default_findex = default_face;
4324 if (default_face)
4325 {
4326 dl->left_margin_findex = default_face;
4327 dl->right_margin_findex = default_face;
4328 }
4329 else
4330 {
4331 dl->left_margin_findex =
4332 get_builtin_face_cache_index (w, Vleft_margin_face);
4333 dl->right_margin_findex =
4334 get_builtin_face_cache_index (w, Vright_margin_face);
4335 }
4336
4337 xzero (data);
4338 data.ef = extent_fragment_new (disp_string, f);
4339
4340 /* These values are used by all of the rune addition routines. We add
4341 them to this structure for ease of passing. */
4342 data.d = d;
4343 XSETWINDOW (data.window, w);
4344 data.db = db;
4345 data.dl = dl;
4346
4347 data.bi_bufpos = bi_start_pos;
4348 data.pixpos = dl->bounds.left_in;
4349 data.last_charset = Qunbound;
4350 data.last_findex = default_face;
4351 data.result_str = Qnil;
4352 data.string = disp_string;
4353
4354 /* Set the right boundary adjusting it to take into account any end
4355 glyph. Save the width of the end glyph for later use. */
4356 data.max_pixpos = dl->bounds.right_in;
4357 #if 0
4358 if (truncate_win)
4359 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
4360 else
4361 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
4362 #endif
4363 data.max_pixpos -= end_glyph_width;
4364
4365 data.cursor_type = NO_CURSOR;
4366 data.cursor_x = -1;
4367
4368 data.start_col = 0;
4369 /* I don't think we want this, string areas should not scroll with
4370 the window
4371 data.start_col = w->hscroll;
4372 data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
4373 */
4374 data.bi_start_col_enabled = 0;
4375 data.hscroll_glyph_width_adjust = 0;
4376
4377 /* We regenerate the line from the very beginning. */
4378 Dynarr_reset (db->runes);
4379
4380 /* Why is this less than or equal and not just less than? If the
4381 starting position is already equal to the maximum we can't add
4382 anything else, right? Wrong. We might still have a newline to
4383 add. A newline can use the room allocated for an end glyph since
4384 if we add it we know we aren't going to be adding any end
4385 glyph. */
4386
4387 /* #### Chuck -- I think this condition should be while (1).
4388 Otherwise if (e.g.) there is one begin-glyph and one end-glyph
4389 and the begin-glyph ends exactly at the end of the window, the
4390 end-glyph and text might not be displayed. while (1) ensures
4391 that the loop terminates only when either (a) there is
4392 propagation data or (b) the end-of-line or end-of-buffer is hit.
4393
4394 #### Also I think you need to ensure that the operation
4395 "add begin glyphs; add end glyphs; add text" is atomic and
4396 can't get interrupted in the middle. If you run off the end
4397 of the line during that operation, then you keep accumulating
4398 propagation data until you're done. Otherwise, if the (e.g.)
4399 there's a begin glyph at a particular position and attempting
4400 to display that glyph results in window-end being hit and
4401 propagation data being generated, then the character at that
4402 position won't be displayed.
4403
4404 #### See also the comment after the end of this loop, below.
4405 */
4406 while (data.pixpos <= data.max_pixpos)
4407 {
4408 /* #### This check probably should not be necessary. */
4409 if (data.bi_bufpos > bi_string_zv)
4410 {
4411 /* #### urk! More of this lossage! */
4412 data.bi_bufpos--;
4413 goto done;
4414 }
4415
4416 /* Check for face changes. */
4417 if (initial || (!no_more_frags && data.bi_bufpos == data.ef->end))
4418 {
4419 /* Now compute the face and begin/end-glyph information. */
4420 data.findex =
4421 /* Remember that the extent-fragment routines deal in Bytind's. */
4422 extent_fragment_update (w, data.ef, data.bi_bufpos);
4423 /* This is somewhat cheesy but the alternative is to
4424 propagate default_face into extent_fragment_update. */
4425 if (data.findex == DEFAULT_INDEX)
4426 data.findex = default_face;
4427
4428 get_display_tables (w, data.findex, &face_dt, &window_dt);
4429
4430 if (data.bi_bufpos == data.ef->end)
4431 no_more_frags = 1;
4432 }
4433 initial = 0;
4434
4435 /* Determine what is next to be displayed. We first handle any
4436 glyphs returned by glyphs_at_bufpos. If there are no glyphs to
4437 display then we determine what to do based on the character at the
4438 current buffer position. */
4439
4440 /* If the current position is covered by an invisible extent, do
4441 nothing (except maybe add some ellipses).
4442
4443 #### The behavior of begin and end-glyphs at the edge of an
4444 invisible extent should be investigated further. This is
4445 fairly low priority though. */
4446 if (data.ef->invisible)
4447 {
4448 /* #### Chuck, perhaps you could look at this code? I don't
4449 really know what I'm doing. */
4450 if (*prop)
4451 {
4452 Dynarr_free (*prop);
4453 *prop = 0;
4454 }
4455
4456 /* The extent fragment code only sets this when we should
4457 really display the ellipses. It makes sure the ellipses
4458 don't get displayed more than once in a row. */
4459 if (data.ef->invisible_ellipses)
4460 {
4461 struct glyph_block gb;
4462
4463 data.ef->invisible_ellipses_already_displayed = 1;
4464 data.ef->invisible_ellipses = 0;
4465 gb.extent = Qnil;
4466 gb.glyph = Vinvisible_text_glyph;
4467 *prop = add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0,
4468 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
4469 /* Perhaps they shouldn't propagate if the very next thing
4470 is to display a newline (for compatibility with
4471 selective-display-ellipses)? Maybe that's too
4472 abstruse. */
4473 if (*prop)
4474 goto done;
4475 }
4476
4477 /* #### What if we we're dealing with a display table? */
4478 if (data.start_col)
4479 data.start_col--;
4480
4481 if (data.bi_bufpos == bi_string_zv)
4482 goto done;
4483 else
4484 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4485 }
4486
4487 /* If there is propagation data, then it represents the current
4488 buffer position being displayed. Add them and advance the
4489 position counter. This might also add the minibuffer
4490 prompt. */
4491 else if (*prop)
4492 {
4493 dl->used_prop_data = 1;
4494 *prop = add_propagation_runes (prop, &data);
4495
4496 if (*prop)
4497 goto done; /* gee, a really narrow window */
4498 else if (data.bi_bufpos == bi_string_zv)
4499 goto done;
4500 else if (data.bi_bufpos < 0)
4501 /* #### urk urk urk! Aborts are not very fun! Fix this please! */
4502 data.bi_bufpos = 0;
4503 else
4504 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4505 }
4506
4507 /* If there are end glyphs, add them to the line. These are
4508 the end glyphs for the previous run of text. We add them
4509 here rather than doing them at the end of handling the
4510 previous run so that glyphs at the beginning and end of
4511 a line are handled correctly. */
4512 else if (Dynarr_length (data.ef->end_glyphs) > 0)
4513 {
4514 *prop = add_glyph_runes (&data, END_GLYPHS);
4515 if (*prop)
4516 goto done;
4517 }
4518
4519 /* If there are begin glyphs, add them to the line. */
4520 else if (Dynarr_length (data.ef->begin_glyphs) > 0)
4521 {
4522 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
4523 if (*prop)
4524 goto done;
4525 }
4526
4527 /* If at end-of-buffer, we've already processed begin and
4528 end-glyphs at this point and there's no text to process,
4529 so we're done. */
4530 else if (data.bi_bufpos == bi_string_zv)
4531 goto done;
4532
4533 else
4534 {
4535 Lisp_Object entry = Qnil;
4536 /* Get the character at the current buffer position. */
4537 data.ch = string_char (s, data.bi_bufpos);
4538 if (!NILP (face_dt) || !NILP (window_dt))
4539 entry = display_table_entry (data.ch, face_dt, window_dt);
4540
4541 /* If there is a display table entry for it, hand it off to
4542 add_disp_table_entry_runes and let it worry about it. */
4543 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
4544 {
4545 *prop = add_disp_table_entry_runes (&data, entry);
4546
4547 if (*prop)
4548 goto done;
4549 }
4550
4551 /* Check if we have hit a newline character. If so, add a marker
4552 to the line and end this loop. */
4553 else if (data.ch == '\n')
4554 {
4555 /* We aren't going to be adding an end glyph so give its
4556 space back in order to make sure that the cursor can
4557 fit. */
4558 data.max_pixpos += end_glyph_width;
4559 goto done;
4560 }
4561
4562 /* If the current character is considered to be printable, then
4563 just add it. */
4564 else if (data.ch >= printable_min)
4565 {
4566 *prop = add_emchar_rune (&data);
4567 if (*prop)
4568 goto done;
4569 }
4570
4571 /* If the current character is a tab, determine the next tab
4572 starting position and add a blank rune which extends from the
4573 current pixel position to that starting position. */
4574 else if (data.ch == '\t')
4575 {
4576 int tab_start_pixpos = data.pixpos;
4577 int next_tab_start;
4578 int char_tab_width;
4579 int prop_width = 0;
4580
4581 if (data.start_col > 1)
4582 tab_start_pixpos -= (space_width (w) * (data.start_col - 1));
4583
4584 next_tab_start =
4585 next_tab_position (w, tab_start_pixpos,
4586 dl->bounds.left_in +
4587 data.hscroll_glyph_width_adjust);
4588 if (next_tab_start > data.max_pixpos)
4589 {
4590 prop_width = next_tab_start - data.max_pixpos;
4591 next_tab_start = data.max_pixpos;
4592 }
4593 data.blank_width = next_tab_start - data.pixpos;
4594 char_tab_width =
4595 (next_tab_start - tab_start_pixpos) / space_width (w);
4596
4597 *prop = add_blank_rune (&data, w, char_tab_width);
4598
4599 /* add_blank_rune is only supposed to be called with
4600 sizes guaranteed to fit in the available space. */
4601 assert (!(*prop));
4602
4603 if (prop_width)
4604 {
4605 struct prop_block pb;
4606 *prop = Dynarr_new (prop_block);
4607
4608 pb.type = PROP_BLANK;
4609 pb.data.p_blank.width = prop_width;
4610 pb.data.p_blank.findex = data.findex;
4611 Dynarr_add (*prop, pb);
4612
4613 goto done;
4614 }
4615 }
4616
4617 /* If character is a control character, pass it off to
4618 add_control_char_runes.
4619
4620 The is_*() routines have undefined results on
4621 arguments outside of the range [-1, 255]. (This
4622 often bites people who carelessly use `char' instead
4623 of `unsigned char'.)
4624 */
4625 else if (data.ch < 0x100 && iscntrl ((Bufbyte) data.ch))
4626 {
4627 *prop = add_control_char_runes (&data, b);
4628
4629 if (*prop)
4630 goto done;
4631 }
4632
4633 /* If the character is above the ASCII range and we have not
4634 already handled it, then print it as an octal number. */
4635 else if (data.ch >= 0200)
4636 {
4637 *prop = add_octal_runes (&data);
4638
4639 if (*prop)
4640 goto done;
4641 }
4642
4643 /* Assume the current character is considered to be printable,
4644 then just add it. */
4645 else
4646 {
4647 *prop = add_emchar_rune (&data);
4648 if (*prop)
4649 goto done;
4650 }
4651
4652 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4653 }
4654 }
4655
4656 done:
4657
4658 /* Determine the starting point of the next line if we did not hit the
4659 end of the buffer. */
4660 if (data.bi_bufpos < bi_string_zv)
4661 {
4662 /* #### This check is not correct. If the line terminated
4663 due to a begin-glyph or end-glyph hitting window-end, then
4664 data.ch will not point to the character at data.bi_bufpos. If
4665 you make the two changes mentioned at the top of this loop,
4666 you should be able to say '(if (*prop))'. That should also
4667 make it possible to eliminate the data.bi_bufpos < BI_BUF_ZV (b)
4668 check. */
4669
4670 /* The common case is that the line ended because we hit a newline.
4671 In that case, the next character is just the next buffer
4672 position. */
4673 if (data.ch == '\n')
4674 {
4675 INC_CHARBYTIND (string_data (s), data.bi_bufpos);
4676 }
4677
4678 /* Otherwise we have a buffer line which cannot fit on one display
4679 line. */
4680 else
4681 {
4682 struct glyph_block gb;
4683 struct glyph_cachel *cachel;
4684
4685 /* If the line is to be truncated then we actually have to look
4686 for the next newline. We also add the end-of-line glyph which
4687 we know will fit because we adjusted the right border before
4688 we starting laying out the line. */
4689 data.max_pixpos += end_glyph_width;
4690 data.findex = default_face;
4691 gb.extent = Qnil;
4692
4693 if (truncate_win)
4694 {
4695 Bytind bi_pos;
4696
4697 /* Now find the start of the next line. */
4698 bi_pos = bi_find_next_emchar_in_string (s, '\n', data.bi_bufpos, 1);
4699
4700 data.cursor_type = NO_CURSOR;
4701 data.bi_bufpos = bi_pos;
4702 gb.glyph = Vtruncation_glyph;
4703 cachel = GLYPH_CACHEL (w, TRUN_GLYPH_INDEX);
4704 }
4705 else
4706 {
4707 /* The cursor can never be on the continuation glyph. */
4708 data.cursor_type = NO_CURSOR;
4709
4710 /* data.bi_bufpos is already at the start of the next line. */
4711
4712 gb.glyph = Vcontinuation_glyph;
4713 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
4714 }
4715
4716 if (end_glyph_width)
4717 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
4718
4719 if (truncate_win && data.bi_bufpos == bi_string_zv)
4720 {
4721 CONST Bufbyte* endb = charptr_n_addr (string_data (s), bi_string_zv);
4722 DEC_CHARPTR (endb);
4723 if (charptr_emchar (endb) != '\n')
4724 {
4725 /* #### Damn this losing shit. */
4726 data.bi_bufpos++;
4727 }
4728 }
4729 }
4730 }
4731 else if (data.bi_bufpos == bi_string_zv)
4732 {
4733 /* We need to add a marker to the end of the line since there is no
4734 newline character in order for the cursor to get drawn. We label
4735 it as a newline so that it gets handled correctly by the
4736 whitespace routines below. */
4737
4738 data.ch = '\n';
4739 data.blank_width = DEVMETH (d, eol_cursor_width, ());
4740 data.findex = default_face;
4741 data.start_col = 0;
4742 data.bi_start_col_enabled = 0;
4743
4744 data.max_pixpos += data.blank_width;
4745 add_emchar_rune (&data);
4746 data.max_pixpos -= data.blank_width;
4747
4748 /* #### urk! Chuck, this shit is bad news. Going around
4749 manipulating invalid positions is guaranteed to result in
4750 trouble sooner or later. */
4751 data.bi_bufpos = bi_string_zv + 1;
4752 }
4753
4754 /* Calculate left whitespace boundary. */
4755 {
4756 int elt = 0;
4757
4758 /* Whitespace past a newline is considered right whitespace. */
4759 while (elt < Dynarr_length (db->runes))
4760 {
4761 struct rune *rb = Dynarr_atp (db->runes, elt);
4762
4763 if ((rb->type == RUNE_CHAR && rb->object.chr.ch == ' ')
4764 || rb->type == RUNE_BLANK)
4765 {
4766 dl->bounds.left_white += rb->width;
4767 elt++;
4768 }
4769 else
4770 elt = Dynarr_length (db->runes);
4771 }
4772 }
4773
4774 /* Calculate right whitespace boundary. */
4775 {
4776 int elt = Dynarr_length (db->runes) - 1;
4777 int done = 0;
4778
4779 while (!done && elt >= 0)
4780 {
4781 struct rune *rb = Dynarr_atp (db->runes, elt);
4782
4783 if (!(rb->type == RUNE_CHAR && rb->object.chr.ch < 0x100
4784 && isspace (rb->object.chr.ch))
4785 && !rb->type == RUNE_BLANK)
4786 {
4787 dl->bounds.right_white = rb->xpos + rb->width;
4788 done = 1;
4789 }
4790
4791 elt--;
4792
4793 }
4794
4795 /* The line is blank so everything is considered to be right
4796 whitespace. */
4797 if (!done)
4798 dl->bounds.right_white = dl->bounds.left_in;
4799 }
4800
4801 /* Set the display blocks bounds. */
4802 db->start_pos = dl->bounds.left_in;
4803 if (Dynarr_length (db->runes))
4804 {
4805 struct rune *rb = Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
4806
4807 db->end_pos = rb->xpos + rb->width;
4808 }
4809 else
4810 db->end_pos = dl->bounds.right_white;
4811
4812 /* update line height parameters */
4813 if (!data.new_ascent && !data.new_descent)
4814 {
4815 /* We've got a blank line so initialize these values from the default
4816 face. */
4817 default_face_font_info (data.window, &data.new_ascent,
4818 &data.new_descent, 0, 0, 0);
4819 }
4820
4821 if (data.max_pixmap_height)
4822 {
4823 int height = data.new_ascent + data.new_descent;
4824 int pix_ascent, pix_descent;
4825
4826 pix_descent = data.max_pixmap_height * data.new_descent / height;
4827 pix_ascent = data.max_pixmap_height - pix_descent;
4828
4829 data.new_ascent = max (data.new_ascent, pix_ascent);
4830 data.new_descent = max (data.new_descent, pix_descent);
4831 }
4832
4833 dl->ascent = data.new_ascent;
4834 dl->descent = data.new_descent;
4835
4836 {
4837 unsigned short ascent = (unsigned short) XINT (w->minimum_line_ascent);
4838
4839 if (dl->ascent < ascent)
4840 dl->ascent = ascent;
4841 }
4842 {
4843 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
4844
4845 if (dl->descent < descent)
4846 dl->descent = descent;
4847 }
4848
4849 dl->cursor_elt = data.cursor_x;
4850 /* #### lossage lossage lossage! Fix this shit! */
4851 if (data.bi_bufpos > bi_string_zv)
4852 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, bi_string_zv);
4853 else
4854 dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, data.bi_bufpos) - 1;
4855 if (truncate_win)
4856 data.dl->num_chars =
4857 string_column_at_point (s, dl->end_bufpos, XINT (b->tab_width));
4858 else
4859 /* This doesn't correctly take into account tabs and control
4860 characters but if the window isn't being truncated then this
4861 value isn't going to end up being used anyhow. */
4862 data.dl->num_chars = dl->end_bufpos - dl->bufpos;
4863
4864 /* #### handle horizontally scrolled line with text none of which
4865 was actually laid out. */
4866
4867 /* #### handle any remainder of overlay arrow */
4868
4869 if (*prop == ADD_FAILED)
4870 *prop = NULL;
4871
4872 if (truncate_win && *prop)
4873 {
4874 Dynarr_free (*prop);
4875 *prop = NULL;
4876 }
4877
4878 extent_fragment_delete (data.ef);
4879
4880 /* #### If we started at EOB, then make sure we return a value past
4881 it so that regenerate_window will exit properly. This is bogus.
4882 The main loop should get fixed so that it isn't necessary to call
4883 this function if we are already at EOB. */
4884
4885 if (data.bi_bufpos == bi_string_zv && bi_start_pos == bi_string_zv)
4886 return bytecount_to_charcount (string_data (s), data.bi_bufpos) + 1; /* Yuck! */
4887 else
4888 return bytecount_to_charcount (string_data (s), data.bi_bufpos);
4889 }
4890
4891 /* Given a display line and a starting position, ensure that the
4892 contents of the display line accurately represent the visual
4893 representation of the buffer contents starting from the given
4894 position when displayed in the given window. The display line ends
4895 when the contents of the line reach the right boundary of the given
4896 window.
4897
4898 This is very similar to generate_display_line but with the same
4899 limitations as create_string_text_block. I have taken the liberty
4900 of fixing the bytind stuff though.*/
4901
4902 static Bufpos
4903 generate_string_display_line (struct window *w, Lisp_Object disp_string,
4904 struct display_line *dl,
4905 Bufpos start_pos,
4906 prop_block_dynarr **prop,
4907 face_index default_face)
4908 {
4909 Bufpos ret_bufpos;
4910
4911 /* you must set bounds before calling this. */
4912
4913 /* Reset what this line is using. */
4914 if (dl->display_blocks)
4915 Dynarr_reset (dl->display_blocks);
4916 if (dl->left_glyphs)
4917 {
4918 Dynarr_free (dl->left_glyphs);
4919 dl->left_glyphs = 0;
4920 }
4921 if (dl->right_glyphs)
4922 {
4923 Dynarr_free (dl->right_glyphs);
4924 dl->right_glyphs = 0;
4925 }
4926
4927 /* We aren't generating a modeline at the moment. */
4928 dl->modeline = 0;
4929
4930 /* Create a display block for the text region of the line. */
4931 ret_bufpos = create_string_text_block (w, disp_string, dl, start_pos,
4932 prop, default_face);
4933 dl->bufpos = start_pos;
4934 if (dl->end_bufpos < dl->bufpos)
4935 dl->end_bufpos = dl->bufpos;
4936
4937 /* If there are left glyphs associated with any character in the
4938 text block, then create a display block to handle them. */
4939 if (dl->left_glyphs != NULL && Dynarr_length (dl->left_glyphs))
4940 create_left_glyph_block (w, dl, 0);
4941
4942 /* If there are right glyphs associated with any character in the
4943 text block, then create a display block to handle them. */
4944 if (dl->right_glyphs != NULL && Dynarr_length (dl->right_glyphs))
4945 create_right_glyph_block (w, dl);
4946
4947 return ret_bufpos;
4948 }
4949
4950 /* This is ripped off from regenerate_window. All we want to do is
4951 loop through elements in the string creating display lines until we
4952 have covered the provided area. Simple really. */
4953 void
4954 generate_displayable_area (struct window *w, Lisp_Object disp_string,
4955 int xpos, int ypos, int width, int height,
4956 display_line_dynarr* dla,
4957 Bufpos start_pos,
4958 face_index default_face)
4959 {
4960 int yend = ypos + height;
4961 Charcount s_zv;
4962
4963 prop_block_dynarr *prop = 0;
4964 layout_bounds bounds;
4965 assert (dla);
4966
4967 Dynarr_reset (dla);
4968 /* if there's nothing to do then do nothing. code after this assumes
4969 there is something to do. */
4970 if (NILP (disp_string))
4971 return;
4972
4973 s_zv = XSTRING_CHAR_LENGTH (disp_string) - 1;
4974
4975 bounds.left_out = xpos;
4976 bounds.right_out = xpos + width;
4977 /* The inner boundaries mark where the glyph margins are located. */
4978 bounds.left_in = bounds.left_out + window_left_margin_width (w);
4979 bounds.right_in = bounds.right_out - window_right_margin_width (w);
4980 /* We cannot fully calculate the whitespace boundaries as they
4981 depend on the contents of the line being displayed. */
4982 bounds.left_white = bounds.left_in;
4983 bounds.right_white = bounds.right_in;
4984
4985 while (ypos < yend)
4986 {
4987 struct display_line dl;
4988 struct display_line *dlp;
4989 Bufpos next_pos;
4990 int local;
4991
4992 if (Dynarr_length (dla) < Dynarr_largest (dla))
4993 {
4994 dlp = Dynarr_atp (dla, Dynarr_length (dla));
4995 local = 0;
4996 }
4997 else
4998 {
4999
5000 xzero (dl);
5001 dlp = &dl;
5002 local = 1;
5003 }
5004
5005 dlp->bounds = bounds;
5006 dlp->offset = 0;
5007 next_pos = generate_string_display_line (w, disp_string, dlp, start_pos,
5008 &prop, default_face);
5009 /* we need to make sure that we continue along the line if there
5010 is more left to display otherwise we just end up redisplaying
5011 the same chunk over and over again. */
5012 if (next_pos == start_pos && next_pos < s_zv)
5013 start_pos++;
5014 else
5015 start_pos = next_pos;
5016
5017 dlp->ypos = ypos + dlp->ascent;
5018 ypos = dlp->ypos + dlp->descent;
5019
5020 if (ypos > yend)
5021 {
5022 int visible_height = dlp->ascent + dlp->descent;
5023
5024 dlp->clip = (ypos - yend);
5025 visible_height -= dlp->clip;
5026
5027 if (visible_height < VERTICAL_CLIP (w, 1))
5028 {
5029 if (local)
5030 free_display_line (dlp);
5031 break;
5032 }
5033 }
5034 else
5035 dlp->clip = 0;
5036
5037 Dynarr_add (dla, *dlp);
5038
5039 /* #### This type of check needs to be done down in the
5040 generate_display_line call. */
5041 if (start_pos >= s_zv)
5042 break;
5043 }
5044
5045 if (prop)
5046 Dynarr_free (prop);
5047 }
5048
5049
5050 /***************************************************************************/
4181 /* */ 5051 /* */
4182 /* window-regeneration routines */ 5052 /* window-regeneration routines */
4183 /* */ 5053 /* */
4184 /***************************************************************************/ 5054 /***************************************************************************/
4185 5055
4260 dlp = Dynarr_atp (dla, Dynarr_length (dla)); 5130 dlp = Dynarr_atp (dla, Dynarr_length (dla));
4261 local = 0; 5131 local = 0;
4262 } 5132 }
4263 else 5133 else
4264 { 5134 {
5135
4265 xzero (dl); 5136 xzero (dl);
4266 dlp = &dl; 5137 dlp = &dl;
4267 local = 1; 5138 local = 1;
4268 } 5139 }
4269 5140
4995 pointm = BUF_ZV (b); 5866 pointm = BUF_ZV (b);
4996 } 5867 }
4997 } 5868 }
4998 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm), the_buffer); 5869 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm), the_buffer);
4999 5870
5000 /* If the buffer has changed we have to invalid all of our face 5871 /* If the buffer has changed we have to invalidate all of our face
5001 cache elements. */ 5872 cache elements. */
5002 if ((!echo_active && b != window_display_buffer (w)) 5873 if ((!echo_active && b != window_display_buffer (w))
5003 || !Dynarr_length (w->face_cachels) 5874 || !Dynarr_length (w->face_cachels)
5004 || f->faces_changed) 5875 || f->faces_changed)
5005 reset_face_cachels (w); 5876 reset_face_cachels (w);
5389 the menubar's visibility. This way we avoid having flashing 6260 the menubar's visibility. This way we avoid having flashing
5390 caused by an Expose event generated by the visibility change 6261 caused by an Expose event generated by the visibility change
5391 being handled. */ 6262 being handled. */
5392 update_frame_menubars (f); 6263 update_frame_menubars (f);
5393 #endif /* HAVE_MENUBARS */ 6264 #endif /* HAVE_MENUBARS */
6265 update_frame_gutters (f);
5394 /* widgets are similar to menus in that they can call lisp to 6266 /* widgets are similar to menus in that they can call lisp to
5395 determine activation etc. Therefore update them before we get 6267 determine activation etc. Therefore update them before we get
5396 into redisplay. This is primarily for connected widgets such as 6268 into redisplay. This is primarily for connected widgets such as
5397 radio buttons. */ 6269 radio buttons. */
5398 update_frame_subwindows (f); 6270 update_frame_subwindows (f);
5472 f->icon_changed = 0; 6344 f->icon_changed = 0;
5473 f->menubar_changed = 0; 6345 f->menubar_changed = 0;
5474 f->modeline_changed = 0; 6346 f->modeline_changed = 0;
5475 f->point_changed = 0; 6347 f->point_changed = 0;
5476 f->toolbar_changed = 0; 6348 f->toolbar_changed = 0;
6349 f->gutter_changed = 0;
5477 f->windows_changed = 0; 6350 f->windows_changed = 0;
5478 f->windows_structure_changed = 0; 6351 f->windows_structure_changed = 0;
5479 f->window_face_cache_reset = 0; 6352 f->window_face_cache_reset = 0;
5480 f->echo_area_garbaged = 0; 6353 f->echo_area_garbaged = 0;
5481 6354
5530 { 6403 {
5531 if (f->buffers_changed || f->clip_changed || f->extents_changed || 6404 if (f->buffers_changed || f->clip_changed || f->extents_changed ||
5532 f->faces_changed || f->frame_changed || f->menubar_changed || 6405 f->faces_changed || f->frame_changed || f->menubar_changed ||
5533 f->modeline_changed || f->point_changed || f->size_changed || 6406 f->modeline_changed || f->point_changed || f->size_changed ||
5534 f->toolbar_changed || f->windows_changed || f->size_slipped || 6407 f->toolbar_changed || f->windows_changed || f->size_slipped ||
5535 f->windows_structure_changed || f->glyphs_changed || f->subwindows_changed) 6408 f->windows_structure_changed || f->glyphs_changed ||
6409 f->subwindows_changed || f->gutter_changed)
5536 { 6410 {
5537 preempted = redisplay_frame (f, 0); 6411 preempted = redisplay_frame (f, 0);
5538 } 6412 }
5539 6413
5540 if (preempted) 6414 if (preempted)
5564 { 6438 {
5565 if (f->buffers_changed || f->clip_changed || f->extents_changed || 6439 if (f->buffers_changed || f->clip_changed || f->extents_changed ||
5566 f->faces_changed || f->frame_changed || f->menubar_changed || 6440 f->faces_changed || f->frame_changed || f->menubar_changed ||
5567 f->modeline_changed || f->point_changed || f->size_changed || 6441 f->modeline_changed || f->point_changed || f->size_changed ||
5568 f->toolbar_changed || f->windows_changed || 6442 f->toolbar_changed || f->windows_changed ||
5569 f->windows_structure_changed || 6443 f->windows_structure_changed || f->gutter_changed ||
5570 f->glyphs_changed || f->subwindows_changed) 6444 f->glyphs_changed || f->subwindows_changed)
5571 { 6445 {
5572 preempted = redisplay_frame (f, 0); 6446 preempted = redisplay_frame (f, 0);
5573 } 6447 }
5574 6448
5592 d->icon_changed = 0; 6466 d->icon_changed = 0;
5593 d->menubar_changed = 0; 6467 d->menubar_changed = 0;
5594 d->modeline_changed = 0; 6468 d->modeline_changed = 0;
5595 d->point_changed = 0; 6469 d->point_changed = 0;
5596 d->toolbar_changed = 0; 6470 d->toolbar_changed = 0;
6471 d->gutter_changed = 0;
5597 d->windows_changed = 0; 6472 d->windows_changed = 0;
5598 d->windows_structure_changed = 0; 6473 d->windows_structure_changed = 0;
5599 6474
5600 if (!size_change_failed) 6475 if (!size_change_failed)
5601 d->size_changed = 0; 6476 d->size_changed = 0;
5633 if (!buffers_changed && !clip_changed && !extents_changed && 6508 if (!buffers_changed && !clip_changed && !extents_changed &&
5634 !faces_changed && !frame_changed && !icon_changed && 6509 !faces_changed && !frame_changed && !icon_changed &&
5635 !menubar_changed && !modeline_changed && !point_changed && 6510 !menubar_changed && !modeline_changed && !point_changed &&
5636 !size_changed && !toolbar_changed && !windows_changed && 6511 !size_changed && !toolbar_changed && !windows_changed &&
5637 !glyphs_changed && !subwindows_changed && 6512 !glyphs_changed && !subwindows_changed &&
5638 !windows_structure_changed && !disable_preemption && 6513 !gutter_changed && !windows_structure_changed &&
5639 preemption_count < max_preempts) 6514 !disable_preemption && preemption_count < max_preempts)
5640 goto done; 6515 goto done;
5641 6516
5642 DEVICE_LOOP_NO_BREAK (devcons, concons) 6517 DEVICE_LOOP_NO_BREAK (devcons, concons)
5643 { 6518 {
5644 struct device *d = XDEVICE (XCAR (devcons)); 6519 struct device *d = XDEVICE (XCAR (devcons));
5646 6521
5647 if (d->buffers_changed || d->clip_changed || d->extents_changed || 6522 if (d->buffers_changed || d->clip_changed || d->extents_changed ||
5648 d->faces_changed || d->frame_changed || d->icon_changed || 6523 d->faces_changed || d->frame_changed || d->icon_changed ||
5649 d->menubar_changed || d->modeline_changed || d->point_changed || 6524 d->menubar_changed || d->modeline_changed || d->point_changed ||
5650 d->size_changed || d->toolbar_changed || d->windows_changed || 6525 d->size_changed || d->toolbar_changed || d->windows_changed ||
5651 d->windows_structure_changed || 6526 d->windows_structure_changed || d->gutter_changed ||
5652 d->glyphs_changed || d->subwindows_changed) 6527 d->glyphs_changed || d->subwindows_changed)
5653 { 6528 {
5654 preempted = redisplay_device (d); 6529 preempted = redisplay_device (d);
5655 6530
5656 if (preempted) 6531 if (preempted)
5677 icon_changed = 0; 6552 icon_changed = 0;
5678 menubar_changed = 0; 6553 menubar_changed = 0;
5679 modeline_changed = 0; 6554 modeline_changed = 0;
5680 point_changed = 0; 6555 point_changed = 0;
5681 toolbar_changed = 0; 6556 toolbar_changed = 0;
6557 gutter_changed = 0;
5682 windows_changed = 0; 6558 windows_changed = 0;
5683 windows_structure_changed = 0; 6559 windows_structure_changed = 0;
5684 RESET_CHANGED_SET_FLAGS; 6560 RESET_CHANGED_SET_FLAGS;
5685 6561
5686 if (faces_changed) 6562 if (faces_changed)