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