comparison src/glyphs.c @ 400:a86b2b5e0111 r21-2-30

Import from CVS: tag r21-2-30
author cvs
date Mon, 13 Aug 2007 11:14:34 +0200
parents 74fd4e045ea6
children 2f8bb876ab1d
comparison
equal deleted inserted replaced
399:376370fb5946 400:a86b2b5e0111
578 Lisp_Object instantiator, 578 Lisp_Object instantiator,
579 Lisp_Object pointer_fg, Lisp_Object pointer_bg, 579 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
580 int dest_mask, Lisp_Object glyph) 580 int dest_mask, Lisp_Object glyph)
581 { 581 {
582 Lisp_Object ii = allocate_image_instance (device, glyph); 582 Lisp_Object ii = allocate_image_instance (device, glyph);
583 Lisp_Image_Instance* p = XIMAGE_INSTANCE (ii);
583 struct image_instantiator_methods *meths; 584 struct image_instantiator_methods *meths;
584 struct gcpro gcpro1; 585 struct gcpro gcpro1;
585 int methp = 0; 586 int methp = 0;
586 587
587 GCPRO1 (ii); 588 GCPRO1 (ii);
605 ("Don't know how to instantiate this image instantiator?", 606 ("Don't know how to instantiate this image instantiator?",
606 instantiator); 607 instantiator);
607 MAYBE_IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg, 608 MAYBE_IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg,
608 pointer_bg, dest_mask, domain)); 609 pointer_bg, dest_mask, domain));
609 UNGCPRO; 610 UNGCPRO;
611
612 /* Some code may have already laid out the widget, if not then do it
613 here. */
614 if (IMAGE_INSTANCE_LAYOUT_CHANGED (p))
615 image_instance_layout (ii, IMAGE_UNSPECIFIED_GEOMETRY,
616 IMAGE_UNSPECIFIED_GEOMETRY, domain);
617
618 /* We *must* have a clean image at this point. */
619 IMAGE_INSTANCE_TEXT_CHANGED (p) = 0;
620 IMAGE_INSTANCE_SIZE_CHANGED (p) = 0;
621 IMAGE_INSTANCE_LAYOUT_CHANGED (p) = 0;
622 IMAGE_INSTANCE_DIRTYP (p) = 0;
610 623
611 return ii; 624 return ii;
612 } 625 }
613 626
614 627
975 lp->width = 0; 988 lp->width = 0;
976 lp->height = 0; 989 lp->height = 0;
977 lp->parent = glyph; 990 lp->parent = glyph;
978 /* So that layouts get done. */ 991 /* So that layouts get done. */
979 lp->layout_changed = 1; 992 lp->layout_changed = 1;
980 lp->dirty = 1;
981 993
982 XSETIMAGE_INSTANCE (val, lp); 994 XSETIMAGE_INSTANCE (val, lp);
983 MARK_GLYPHS_CHANGED; 995 MARK_GLYPHS_CHANGED;
984 996
985 return val; 997 return val;
1147 parent. */ 1159 parent. */
1148 Lisp_Object image_instance_parent_glyph (Lisp_Image_Instance* ii) 1160 Lisp_Object image_instance_parent_glyph (Lisp_Image_Instance* ii)
1149 { 1161 {
1150 if (IMAGE_INSTANCEP (IMAGE_INSTANCE_PARENT (ii))) 1162 if (IMAGE_INSTANCEP (IMAGE_INSTANCE_PARENT (ii)))
1151 { 1163 {
1152 return image_instance_parent_glyph 1164 return image_instance_parent_glyph
1153 (XIMAGE_INSTANCE (IMAGE_INSTANCE_PARENT (ii))); 1165 (XIMAGE_INSTANCE (IMAGE_INSTANCE_PARENT (ii)));
1154 } 1166 }
1155 return IMAGE_INSTANCE_PARENT (ii); 1167 return IMAGE_INSTANCE_PARENT (ii);
1156 } 1168 }
1157 1169
2670 } 2682 }
2671 2683
2672 static Lisp_Object 2684 static Lisp_Object
2673 image_instantiate_cache_result (Lisp_Object locative) 2685 image_instantiate_cache_result (Lisp_Object locative)
2674 { 2686 {
2675 /* locative = (instance instantiator . subtable) */ 2687 /* locative = (instance instantiator . subtable)
2688
2689 So we are using the instantiator as the key and the instance as
2690 the value. Since the hashtable is key-weak this means that the
2691 image instance will stay around as long as the instantiator stays
2692 around. The instantiator is stored in the `image' slot of the
2693 glyph, so as long as the glyph is marked the instantiator will be
2694 as well and hence the cached image instance also.*/
2676 Fputhash (XCAR (XCDR (locative)), XCAR (locative), XCDR (XCDR (locative))); 2695 Fputhash (XCAR (XCDR (locative)), XCAR (locative), XCDR (XCDR (locative)));
2677 free_cons (XCONS (XCDR (locative))); 2696 free_cons (XCONS (XCDR (locative)));
2678 free_cons (XCONS (locative)); 2697 free_cons (XCONS (locative));
2679 return Qnil; 2698 return Qnil;
2680 } 2699 }
3819 /***************************************************************************** 3838 /*****************************************************************************
3820 * glyph cachel functions * 3839 * glyph cachel functions *
3821 *****************************************************************************/ 3840 *****************************************************************************/
3822 3841
3823 /* #### All of this is 95% copied from face cachels. Consider 3842 /* #### All of this is 95% copied from face cachels. Consider
3824 consolidating. 3843 consolidating.
3825 3844
3826 Why do we need glyph_cachels? Simply because a glyph_cachel captures 3845 Why do we need glyph_cachels? Simply because a glyph_cachel captures
3827 per-window information about a particular glyph. A glyph itself is 3846 per-window information about a particular glyph. A glyph itself is
3828 not created in any particular context, so if we were to rely on a 3847 not created in any particular context, so if we were to rely on a
3829 glyph to tell us about its dirtiness we would not be able to reset 3848 glyph to tell us about its dirtiness we would not be able to reset
3830 the dirty flag after redisplaying it as it may exist in other 3849 the dirty flag after redisplaying it as it may exist in other
4245 4264
4246 /***************************************************************************** 4265 /*****************************************************************************
4247 * subwindow functions * 4266 * subwindow functions *
4248 *****************************************************************************/ 4267 *****************************************************************************/
4249 4268
4250 /* update the displayed characteristics of a subwindow */ 4269 /* Update the displayed characteristics of a subwindow. This function
4270 should generally only get called if the subwindow is actually
4271 dirty. The only other time it gets called is if subwindow state
4272 changed, when we can't actually tell whether its going to be dirty
4273 or not.
4274 #### I suspect what we should really do is re-evaluate all the
4275 gui slots that could affect this and then mark the instance as
4276 dirty. Right now, updating everything is safe but expensive. */
4251 void 4277 void
4252 update_subwindow (Lisp_Object subwindow) 4278 update_subwindow (Lisp_Object subwindow)
4253 { 4279 {
4254 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow); 4280 Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
4281 int count = specpdl_depth ();
4282
4283 /* The update method is allowed to call eval. Since it is quite
4284 common for this function to get called from somewhere in
4285 redisplay we need to make sure that quits are ignored. Otherwise
4286 Fsignal will abort. */
4287 specbind (Qinhibit_quit, Qt);
4255 4288
4256 if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET 4289 if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET
4257 || 4290 ||
4258 IMAGE_INSTANCE_TYPE (ii) == IMAGE_LAYOUT) 4291 IMAGE_INSTANCE_TYPE (ii) == IMAGE_LAYOUT)
4259 { 4292 {
4260 if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET) 4293 if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET)
4261 update_widget (subwindow); 4294 update_widget (subwindow);
4262 /* Reset the changed flags. */ 4295 /* Reset the changed flags. */
4263 IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii) = 0; 4296 IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii) = 0;
4264 IMAGE_INSTANCE_WIDGET_PERCENT_CHANGED (ii) = 0; 4297 IMAGE_INSTANCE_WIDGET_PERCENT_CHANGED (ii) = 0;
4265 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0; 4298 IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0;
4266 IMAGE_INSTANCE_TEXT_CHANGED (ii) = 0; 4299 IMAGE_INSTANCE_TEXT_CHANGED (ii) = 0;
4271 { 4304 {
4272 MAYBE_DEVMETH (XDEVICE (ii->device), update_subwindow, (ii)); 4305 MAYBE_DEVMETH (XDEVICE (ii->device), update_subwindow, (ii));
4273 } 4306 }
4274 4307
4275 IMAGE_INSTANCE_SIZE_CHANGED (ii) = 0; 4308 IMAGE_INSTANCE_SIZE_CHANGED (ii) = 0;
4309
4310 unbind_to (count, Qnil);
4276 } 4311 }
4277 4312
4278 /* Update all the subwindows on a frame. */ 4313 /* Update all the subwindows on a frame. */
4279 void 4314 void
4280 update_frame_subwindows (struct frame *f) 4315 update_frame_subwindows (struct frame *f)
4287 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) 4322 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++)
4288 { 4323 {
4289 struct subwindow_cachel *cachel = 4324 struct subwindow_cachel *cachel =
4290 Dynarr_atp (f->subwindow_cachels, elt); 4325 Dynarr_atp (f->subwindow_cachels, elt);
4291 4326
4292 if (cachel->being_displayed) 4327 if (cachel->being_displayed
4328 &&
4329 /* We only want to update if something has really
4330 changed. */
4331 (f->subwindows_state_changed
4332 ||
4333 XIMAGE_INSTANCE_DIRTYP (cachel->subwindow)))
4293 { 4334 {
4294 update_subwindow (cachel->subwindow); 4335 update_subwindow (cachel->subwindow);
4295 } 4336 }
4296 } 4337 }
4297 } 4338 }
4355 cachel->x = x; 4396 cachel->x = x;
4356 cachel->y = y; 4397 cachel->y = y;
4357 cachel->width = dga->width; 4398 cachel->width = dga->width;
4358 cachel->height = dga->height; 4399 cachel->height = dga->height;
4359 cachel->being_displayed = 1; 4400 cachel->being_displayed = 1;
4360
4361 #if 0
4362 /* This forces any pending display changes to happen to the image
4363 before we show it. I'm not sure whether or not we need mark as
4364 clean here, but for now we will. */
4365 if (IMAGE_INSTANCE_DIRTYP (ii))
4366 {
4367 update_subwindow (subwindow);
4368 IMAGE_INSTANCE_DIRTYP (ii) = 0;
4369 }
4370 #endif
4371 4401
4372 MAYBE_DEVMETH (XDEVICE (ii->device), map_subwindow, (ii, x, y, dga)); 4402 MAYBE_DEVMETH (XDEVICE (ii->device), map_subwindow, (ii, x, y, dga));
4373 } 4403 }
4374 4404
4375 static int 4405 static int
4608 % IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii); 4638 % IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii);
4609 /* We might need to kick redisplay at this point - but we 4639 /* We might need to kick redisplay at this point - but we
4610 also might not. */ 4640 also might not. */
4611 MARK_DEVICE_FRAMES_GLYPHS_CHANGED 4641 MARK_DEVICE_FRAMES_GLYPHS_CHANGED
4612 (XDEVICE (IMAGE_INSTANCE_DEVICE (ii))); 4642 (XDEVICE (IMAGE_INSTANCE_DEVICE (ii)));
4613 /* Cascade dirtiness so that we can have an animated glyph in a layout 4643 /* Cascade dirtiness so that we can have an animated glyph in a layout
4614 for instance. */ 4644 for instance. */
4615 set_image_instance_dirty_p (value, 1); 4645 set_image_instance_dirty_p (value, 1);
4616 } 4646 }
4617 } 4647 }
4618 } 4648 }
4655 *****************************************************************************/ 4685 *****************************************************************************/
4656 4686
4657 void 4687 void
4658 syms_of_glyphs (void) 4688 syms_of_glyphs (void)
4659 { 4689 {
4690 INIT_LRECORD_IMPLEMENTATION (glyph);
4691 INIT_LRECORD_IMPLEMENTATION (image_instance);
4692
4660 /* image instantiators */ 4693 /* image instantiators */
4661 4694
4662 DEFSUBR (Fimage_instantiator_format_list); 4695 DEFSUBR (Fimage_instantiator_format_list);
4663 DEFSUBR (Fvalid_image_instantiator_format_p); 4696 DEFSUBR (Fvalid_image_instantiator_format_p);
4664 DEFSUBR (Fset_console_type_image_conversion_list); 4697 DEFSUBR (Fset_console_type_image_conversion_list);