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