Mercurial > hg > xemacs-beta
comparison src/glyphs.c @ 4968:4d35e52790f8
fix crash in glyph-cachels
-------------------- ChangeLog entries follow: --------------------
src/ChangeLog addition:
2010-02-03 Ben Wing <ben@xemacs.org>
* frame.c (Fmake_frame):
* glyphs.c:
* glyphs.c (NUM_PRECACHED_GLYPHS):
* glyphs.c (get_glyph_cachel_index):
* glyphs.c (FROB):
* glyphs.c (mark_glyph_cachels_as_not_updated):
* redisplay.c (regenerate_window):
* redisplay.c (redisplay_window):
When creating a frame, call reset_glyph_cachels on the minibuffer
window as well as the root window. Fixes a crash due to other
glyphs (e.g. the gutter glyph) getting in the glyph cachel before
the pre-cached glyphs that are supposed to have fixed indices
(continuation-glyph, truncation-glyph, etc.).
Add a bunch of asserts to make sure that the glyph cachels always
properly contain the pre-cached glyphs.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Wed, 03 Feb 2010 21:06:14 -0600 |
parents | e813cf16c015 |
children | 4aebb0131297 |
comparison
equal
deleted
inserted
replaced
4967:0d4c9d0f6a8d | 4968:4d35e52790f8 |
---|---|
4274 image_instance_layout (instance, width, height, xoffset, yoffset, domain); | 4274 image_instance_layout (instance, width, height, xoffset, yoffset, domain); |
4275 } | 4275 } |
4276 | 4276 |
4277 | 4277 |
4278 /***************************************************************************** | 4278 /***************************************************************************** |
4279 * glyph cachel functions * | 4279 * glyph cachel functions * |
4280 *****************************************************************************/ | 4280 *****************************************************************************/ |
4281 | |
4282 #define NUM_PRECACHED_GLYPHS 6 | |
4283 #define LOOP_OVER_PRECACHED_GLYPHS \ | |
4284 FROB (Vcontinuation_glyph, CONT_GLYPH_INDEX) \ | |
4285 FROB (Vtruncation_glyph, TRUN_GLYPH_INDEX) \ | |
4286 FROB (Vhscroll_glyph, HSCROLL_GLYPH_INDEX) \ | |
4287 FROB (Vcontrol_arrow_glyph, CONTROL_GLYPH_INDEX) \ | |
4288 FROB (Voctal_escape_glyph, OCT_ESC_GLYPH_INDEX) \ | |
4289 FROB (Vinvisible_text_glyph, INVIS_GLYPH_INDEX) | |
4290 | |
4281 | 4291 |
4282 /* #### All of this is 95% copied from face cachels. Consider | 4292 /* #### All of this is 95% copied from face cachels. Consider |
4283 consolidating. | 4293 consolidating. |
4284 | 4294 |
4285 Why do we need glyph_cachels? Simply because a glyph_cachel captures | 4295 Why do we need glyph_cachels? Simply because a glyph_cachel captures |
4350 | 4360 |
4351 update_glyph_cachel_data (w, glyph, &new_cachel); | 4361 update_glyph_cachel_data (w, glyph, &new_cachel); |
4352 Dynarr_add (w->glyph_cachels, new_cachel); | 4362 Dynarr_add (w->glyph_cachels, new_cachel); |
4353 } | 4363 } |
4354 | 4364 |
4365 #ifdef ERROR_CHECK_GLYPHS | |
4366 | |
4367 /* The precached glyphs should always occur in slots 0 - 5, with each glyph in the | |
4368 slot reserved for it. Meanwhile any other glyphs should always occur in slots | |
4369 6 or greater. */ | |
4370 static void | |
4371 verify_glyph_index (Lisp_Object glyph, glyph_index idx) | |
4372 { | |
4373 if (0) | |
4374 ; | |
4375 #define FROB(glyph_obj, gindex) \ | |
4376 else if (EQ (glyph, glyph_obj)) \ | |
4377 assert (gindex == idx); | |
4378 LOOP_OVER_PRECACHED_GLYPHS | |
4379 else | |
4380 assert (idx >= NUM_PRECACHED_GLYPHS); | |
4381 #undef FROB | |
4382 } | |
4383 | |
4384 #endif /* ERROR_CHECK_GLYPHS */ | |
4385 | |
4355 glyph_index | 4386 glyph_index |
4356 get_glyph_cachel_index (struct window *w, Lisp_Object glyph) | 4387 get_glyph_cachel_index (struct window *w, Lisp_Object glyph) |
4357 { | 4388 { |
4358 int elt; | 4389 int elt; |
4359 | 4390 |
4365 struct glyph_cachel *cachel = | 4396 struct glyph_cachel *cachel = |
4366 Dynarr_atp (w->glyph_cachels, elt); | 4397 Dynarr_atp (w->glyph_cachels, elt); |
4367 | 4398 |
4368 if (EQ (cachel->glyph, glyph) && !NILP (glyph)) | 4399 if (EQ (cachel->glyph, glyph) && !NILP (glyph)) |
4369 { | 4400 { |
4401 #ifdef ERROR_CHECK_GLYPHS | |
4402 verify_glyph_index (glyph, elt); | |
4403 #endif /* ERROR_CHECK_GLYPHS */ | |
4370 update_glyph_cachel_data (w, glyph, cachel); | 4404 update_glyph_cachel_data (w, glyph, cachel); |
4371 return elt; | 4405 return elt; |
4372 } | 4406 } |
4373 } | 4407 } |
4374 | 4408 |
4379 | 4413 |
4380 void | 4414 void |
4381 reset_glyph_cachels (struct window *w) | 4415 reset_glyph_cachels (struct window *w) |
4382 { | 4416 { |
4383 Dynarr_reset (w->glyph_cachels); | 4417 Dynarr_reset (w->glyph_cachels); |
4384 get_glyph_cachel_index (w, Vcontinuation_glyph); | 4418 #define FROB(glyph_obj, gindex) \ |
4385 get_glyph_cachel_index (w, Vtruncation_glyph); | 4419 get_glyph_cachel_index (w, glyph_obj); |
4386 get_glyph_cachel_index (w, Vhscroll_glyph); | 4420 LOOP_OVER_PRECACHED_GLYPHS |
4387 get_glyph_cachel_index (w, Vcontrol_arrow_glyph); | 4421 #undef FROB |
4388 get_glyph_cachel_index (w, Voctal_escape_glyph); | |
4389 get_glyph_cachel_index (w, Vinvisible_text_glyph); | |
4390 } | 4422 } |
4391 | 4423 |
4392 void | 4424 void |
4393 mark_glyph_cachels_as_not_updated (struct window *w) | 4425 mark_glyph_cachels_as_not_updated (struct window *w) |
4394 { | 4426 { |
4395 int elt; | 4427 int elt; |
4396 | 4428 |
4429 /* A previous bug resulted from the glyph cachels never getting reset | |
4430 in the minibuffer window after creation, and another glyph added before | |
4431 we got a chance to add the six normal glyphs that should go first, and | |
4432 we got called with only one glyph present. */ | |
4433 assert (Dynarr_length (w->glyph_cachels) >= NUM_PRECACHED_GLYPHS); | |
4397 /* We need to have a dirty flag to tell if the glyph has changed. | 4434 /* We need to have a dirty flag to tell if the glyph has changed. |
4398 We can check to see if each glyph variable is actually a | 4435 We can check to see if each glyph variable is actually a |
4399 completely different glyph, though. */ | 4436 completely different glyph, though. */ |
4400 #define FROB(glyph_obj, gindex) \ | 4437 #define FROB(glyph_obj, gindex) \ |
4401 update_glyph_cachel_data (w, glyph_obj, \ | 4438 update_glyph_cachel_data (w, glyph_obj, \ |
4402 Dynarr_atp (w->glyph_cachels, gindex)) | 4439 Dynarr_atp (w->glyph_cachels, gindex)); |
4403 | 4440 LOOP_OVER_PRECACHED_GLYPHS |
4404 FROB (Vcontinuation_glyph, CONT_GLYPH_INDEX); | |
4405 FROB (Vtruncation_glyph, TRUN_GLYPH_INDEX); | |
4406 FROB (Vhscroll_glyph, HSCROLL_GLYPH_INDEX); | |
4407 FROB (Vcontrol_arrow_glyph, CONTROL_GLYPH_INDEX); | |
4408 FROB (Voctal_escape_glyph, OCT_ESC_GLYPH_INDEX); | |
4409 FROB (Vinvisible_text_glyph, INVIS_GLYPH_INDEX); | |
4410 #undef FROB | 4441 #undef FROB |
4411 | 4442 |
4412 for (elt = 0; elt < Dynarr_length (w->glyph_cachels); elt++) | 4443 for (elt = 0; elt < Dynarr_length (w->glyph_cachels); elt++) |
4413 { | 4444 { |
4414 Dynarr_atp (w->glyph_cachels, elt)->updated = 0; | 4445 Dynarr_atp (w->glyph_cachels, elt)->updated = 0; |
4447 #endif /* MEMORY_USAGE_STATS */ | 4478 #endif /* MEMORY_USAGE_STATS */ |
4448 | 4479 |
4449 | 4480 |
4450 | 4481 |
4451 /***************************************************************************** | 4482 /***************************************************************************** |
4452 * subwindow cachel functions * | 4483 * subwindow cachel functions * |
4453 *****************************************************************************/ | 4484 *****************************************************************************/ |
4454 /* Subwindows are curious in that you have to physically unmap them to | 4485 /* Subwindows are curious in that you have to physically unmap them to |
4455 not display them. It is problematic deciding what to do in | 4486 not display them. It is problematic deciding what to do in |
4456 redisplay. We have two caches - a per-window instance cache that | 4487 redisplay. We have two caches - a per-window instance cache that |
4457 keeps track of subwindows on a window, these are linked to their | 4488 keeps track of subwindows on a window, these are linked to their |
4544 unmap_subwindow (value); | 4575 unmap_subwindow (value); |
4545 } | 4576 } |
4546 } | 4577 } |
4547 | 4578 |
4548 /***************************************************************************** | 4579 /***************************************************************************** |
4549 * subwindow exposure ignorance * | 4580 * subwindow exposure ignorance * |
4550 *****************************************************************************/ | 4581 *****************************************************************************/ |
4551 /* when we unmap subwindows the associated window system will generate | 4582 /* when we unmap subwindows the associated window system will generate |
4552 expose events. This we do not want as redisplay already copes with | 4583 expose events. This we do not want as redisplay already copes with |
4553 the repainting necessary. Worse, we can get in an endless cycle of | 4584 the repainting necessary. Worse, we can get in an endless cycle of |
4554 redisplay if we are not careful. Thus we keep a per-frame list of | 4585 redisplay if we are not careful. Thus we keep a per-frame list of |