Mercurial > hg > xemacs-beta
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) |