Mercurial > hg > xemacs-beta
comparison src/glyphs.c @ 4252:8475ff9c49ea
[xemacs-hg @ 2007-11-05 14:59:20 by didierv]
Fix recent image related crashes
author | didierv |
---|---|
date | Mon, 05 Nov 2007 14:59:24 +0000 |
parents | 9b4442ac18c7 |
children | 515b91f904c1 |
comparison
equal
deleted
inserted
replaced
4251:b45f331a659d | 4252:8475ff9c49ea |
---|---|
472 GCPRO1 (alist); | 472 GCPRO1 (alist); |
473 | 473 |
474 for (len -= 2; len >= 1; len -= 2) | 474 for (len -= 2; len >= 1; len -= 2) |
475 { | 475 { |
476 /* Keyword comparisons can be done with eq, the value must be | 476 /* Keyword comparisons can be done with eq, the value must be |
477 done with equal. | 477 done with equal. |
478 #### Note that this does not optimize re-ordering. */ | 478 #### Note that this does not optimize re-ordering. */ |
479 if (!EQ (elt[len], old_elt[len]) | 479 if (!EQ (elt[len], old_elt[len]) |
480 || !internal_equal (elt[len+1], old_elt[len+1], 0)) | 480 || !internal_equal (elt[len+1], old_elt[len+1], 0)) |
481 alist = Fcons (Fcons (elt[len], elt[len+1]), alist); | 481 alist = Fcons (Fcons (elt[len], elt[len+1]), alist); |
482 } | 482 } |
483 | 483 |
912 { XD_LISP_OBJECT, offsetof (Lisp_Image_Instance, domain) }, | 912 { XD_LISP_OBJECT, offsetof (Lisp_Image_Instance, domain) }, |
913 { XD_LISP_OBJECT, offsetof (Lisp_Image_Instance, device) }, | 913 { XD_LISP_OBJECT, offsetof (Lisp_Image_Instance, device) }, |
914 { XD_LISP_OBJECT, offsetof (Lisp_Image_Instance, name) }, | 914 { XD_LISP_OBJECT, offsetof (Lisp_Image_Instance, name) }, |
915 { XD_LISP_OBJECT, offsetof (Lisp_Image_Instance, parent) }, | 915 { XD_LISP_OBJECT, offsetof (Lisp_Image_Instance, parent) }, |
916 { XD_LISP_OBJECT, offsetof (Lisp_Image_Instance, instantiator) }, | 916 { XD_LISP_OBJECT, offsetof (Lisp_Image_Instance, instantiator) }, |
917 { XD_UNION, offsetof (struct Lisp_Image_Instance, u), | 917 { XD_UNION, offsetof (struct Lisp_Image_Instance, u), |
918 XD_INDIRECT (0, 0), { &image_instance_data_description } }, | 918 XD_INDIRECT (0, 0), { &image_instance_data_description } }, |
919 { XD_END } | 919 { XD_END } |
920 }; | 920 }; |
921 | 921 |
922 static Lisp_Object | 922 static Lisp_Object |
991 { | 991 { |
992 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (obj); | 992 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (obj); |
993 | 993 |
994 if (print_readably) | 994 if (print_readably) |
995 printing_unreadable_object ("#<image-instance 0x%x>", | 995 printing_unreadable_object ("#<image-instance 0x%x>", |
996 ii->header.uid); | 996 ii->header.uid); |
997 write_fmt_string_lisp (printcharfun, "#<image-instance (%s) ", 1, | 997 write_fmt_string_lisp (printcharfun, "#<image-instance (%s) ", 1, |
998 Fimage_instance_type (obj)); | 998 Fimage_instance_type (obj)); |
999 if (!NILP (ii->name)) | 999 if (!NILP (ii->name)) |
1000 write_fmt_string_lisp (printcharfun, "%S ", 1, ii->name); | 1000 write_fmt_string_lisp (printcharfun, "%S ", 1, ii->name); |
1001 write_fmt_string_lisp (printcharfun, "on %s ", 1, ii->domain); | 1001 write_fmt_string_lisp (printcharfun, "on %s ", 1, ii->domain); |
1093 | 1093 |
1094 if (!FRAME_LIVE_P (f)) | 1094 if (!FRAME_LIVE_P (f)) |
1095 write_c_string (printcharfun, "dead"); | 1095 write_c_string (printcharfun, "dead"); |
1096 else | 1096 else |
1097 write_c_string (printcharfun, | 1097 write_c_string (printcharfun, |
1098 DEVICE_TYPE_NAME (XDEVICE (FRAME_DEVICE (f)))); | 1098 DEVICE_TYPE_NAME (XDEVICE (FRAME_DEVICE (f)))); |
1099 } | 1099 } |
1100 write_c_string (printcharfun, "-frame>"); | 1100 write_c_string (printcharfun, "-frame>"); |
1101 write_fmt_string (printcharfun, " 0x%p", | 1101 write_fmt_string (printcharfun, " 0x%p", |
1102 IMAGE_INSTANCE_SUBWINDOW_ID (ii)); | 1102 IMAGE_INSTANCE_SUBWINDOW_ID (ii)); |
1103 | 1103 |
1291 depth + 1)); | 1291 depth + 1)); |
1292 break; | 1292 break; |
1293 | 1293 |
1294 case IMAGE_WIDGET: | 1294 case IMAGE_WIDGET: |
1295 /* We need the hash to be equivalent to what should be | 1295 /* We need the hash to be equivalent to what should be |
1296 displayed. */ | 1296 displayed. */ |
1297 hash = HASH5 (hash, | 1297 hash = HASH5 (hash, |
1298 LISP_HASH (IMAGE_INSTANCE_WIDGET_TYPE (i)), | 1298 LISP_HASH (IMAGE_INSTANCE_WIDGET_TYPE (i)), |
1299 internal_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1), | 1299 internal_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1), |
1300 internal_hash (IMAGE_INSTANCE_WIDGET_ITEMS (i), depth + 1), | 1300 internal_hash (IMAGE_INSTANCE_WIDGET_ITEMS (i), depth + 1), |
1301 internal_hash (IMAGE_INSTANCE_LAYOUT_CHILDREN (i), | 1301 internal_hash (IMAGE_INSTANCE_LAYOUT_CHILDREN (i), |
2234 DOESNT_RETURN | 2234 DOESNT_RETURN |
2235 signal_double_image_error (const CIbyte *string1, const CIbyte *string2, | 2235 signal_double_image_error (const CIbyte *string1, const CIbyte *string2, |
2236 Lisp_Object data) | 2236 Lisp_Object data) |
2237 { | 2237 { |
2238 signal_error_1 (Qimage_conversion_error, | 2238 signal_error_1 (Qimage_conversion_error, |
2239 list3 (build_msg_string (string1), | 2239 list3 (build_msg_string (string1), |
2240 build_msg_string (string2), | 2240 build_msg_string (string2), |
2241 data)); | 2241 data)); |
2242 } | 2242 } |
2243 | 2243 |
2244 DOESNT_RETURN | 2244 DOESNT_RETURN |
2245 signal_double_image_error_2 (const CIbyte *string1, const CIbyte *string2, | 2245 signal_double_image_error_2 (const CIbyte *string1, const CIbyte *string2, |
2246 Lisp_Object data1, Lisp_Object data2) | 2246 Lisp_Object data1, Lisp_Object data2) |
2247 { | 2247 { |
2248 signal_error_1 (Qimage_conversion_error, | 2248 signal_error_1 (Qimage_conversion_error, |
2249 list4 (build_msg_string (string1), | 2249 list4 (build_msg_string (string1), |
2250 build_msg_string (string2), | 2250 build_msg_string (string2), |
2251 data1, data2)); | 2251 data1, data2)); |
2252 } | 2252 } |
2253 | 2253 |
2254 /**************************************************************************** | 2254 /**************************************************************************** |
2528 | 2528 |
2529 /************************************************************************/ | 2529 /************************************************************************/ |
2530 /* pixmap file functions */ | 2530 /* pixmap file functions */ |
2531 /************************************************************************/ | 2531 /************************************************************************/ |
2532 | 2532 |
2533 /* If INSTANTIATOR refers to inline data, return Qnil. | 2533 /* If INSTANTIATOR refers to inline data, return Qt. |
2534 If INSTANTIATOR refers to data in a file, return the full filename | 2534 If INSTANTIATOR refers to data in a file, return the full filename |
2535 if it exists; otherwise, return a cons of (filename). | 2535 if it exists, Qnil if there's no console method for locating the file, or |
2536 (filename) if there was an error locating the file. | |
2536 | 2537 |
2537 FILE_KEYWORD and DATA_KEYWORD are symbols specifying the | 2538 FILE_KEYWORD and DATA_KEYWORD are symbols specifying the |
2538 keywords used to look up the file and inline data, | 2539 keywords used to look up the file and inline data, |
2539 respectively, in the instantiator. Normally these would | 2540 respectively, in the instantiator. Normally these would |
2540 be Q_file and Q_data, but might be different for mask data. */ | 2541 be Q_file and Q_data, but might be different for mask data. */ |
2554 file = find_keyword_in_vector (instantiator, file_keyword); | 2555 file = find_keyword_in_vector (instantiator, file_keyword); |
2555 | 2556 |
2556 if (!NILP (file) && NILP (data)) | 2557 if (!NILP (file) && NILP (data)) |
2557 { | 2558 { |
2558 struct console_methods *meths | 2559 struct console_methods *meths |
2559 = decode_console_type(console_type, ERROR_ME); | 2560 = decode_console_type(console_type, ERROR_ME); |
2560 | 2561 |
2561 if (HAS_CONTYPE_METH_P (meths, locate_pixmap_file)) | 2562 if (HAS_CONTYPE_METH_P (meths, locate_pixmap_file)) |
2562 { | 2563 { |
2563 Lisp_Object retval | 2564 Lisp_Object retval |
2564 = CONTYPE_METH (meths, locate_pixmap_file, (file)); | 2565 = CONTYPE_METH (meths, locate_pixmap_file, (file)); |
2565 | 2566 |
2566 if (!NILP (retval)) | 2567 if (!NILP (retval)) |
2567 return retval; | 2568 return retval; |
2568 else | 2569 else |
2569 return Fcons (file, Qnil); /* should have been file */ | 2570 return Fcons (file, Qnil); /* should have been file */ |
2570 } | 2571 } |
2571 else /* method unavailable */ | 2572 else /* method unavailable */ |
2572 return Qnil; | 2573 return Qnil; |
2573 } | 2574 } |
2574 | 2575 |
2575 return Qt; | 2576 return Qt; |
2576 } | 2577 } |
2577 | 2578 |
2578 Lisp_Object | 2579 Lisp_Object |
2749 Lisp_Object mask_file, Lisp_Object console_type) | 2750 Lisp_Object mask_file, Lisp_Object console_type) |
2750 { | 2751 { |
2751 /* This is unclean but it's fairly standard -- a number of the | 2752 /* This is unclean but it's fairly standard -- a number of the |
2752 bitmaps in /usr/include/X11/bitmaps use it -- so we support | 2753 bitmaps in /usr/include/X11/bitmaps use it -- so we support |
2753 it. */ | 2754 it. */ |
2754 if (NILP (mask_file) | 2755 if (EQ (mask_file, Qt) |
2755 /* don't override explicitly specified mask data. */ | 2756 /* don't override explicitly specified mask data. */ |
2756 && NILP (assq_no_quit (Q_mask_data, alist)) | 2757 && NILP (assq_no_quit (Q_mask_data, alist)) |
2757 && !NILP (file)) | 2758 && !EQ (file, Qt)) |
2758 { | 2759 { |
2759 mask_file = MAYBE_LISP_CONTYPE_METH | 2760 mask_file = MAYBE_LISP_CONTYPE_METH |
2760 (decode_console_type(console_type, ERROR_ME), | 2761 (decode_console_type(console_type, ERROR_ME), |
2761 locate_pixmap_file, (concat2 (file, build_string ("Mask")))); | 2762 locate_pixmap_file, (concat2 (file, build_string ("Mask")))); |
2762 if (NILP (mask_file)) | 2763 if (NILP (mask_file)) |
2832 if (yhot != -1 && NILP (assq_no_quit (Q_hotspot_y, alist))) | 2833 if (yhot != -1 && NILP (assq_no_quit (Q_hotspot_y, alist))) |
2833 alist = Fcons (Fcons (Q_hotspot_y, make_int (yhot)), | 2834 alist = Fcons (Fcons (Q_hotspot_y, make_int (yhot)), |
2834 alist); | 2835 alist); |
2835 } | 2836 } |
2836 | 2837 |
2837 /* #### FIXME: Hmmm... what about mask being Qt ?? -- dvl */ | |
2838 alist = xbm_mask_file_munging (alist, file, mask_file, console_type); | 2838 alist = xbm_mask_file_munging (alist, file, mask_file, console_type); |
2839 | 2839 |
2840 { | 2840 { |
2841 Lisp_Object result = alist_to_tagged_vector (Qxbm, alist); | 2841 Lisp_Object result = alist_to_tagged_vector (Qxbm, alist); |
2842 free_alist (alist); | 2842 free_alist (alist); |
2902 Fcar (file)); | 2902 Fcar (file)); |
2903 | 2903 |
2904 if (EQ (file, Qt) && EQ (mask_file, Qt)) /* no conversion necessary */ | 2904 if (EQ (file, Qt) && EQ (mask_file, Qt)) /* no conversion necessary */ |
2905 RETURN_UNGCPRO (inst); | 2905 RETURN_UNGCPRO (inst); |
2906 | 2906 |
2907 | |
2908 /* #### FIXME: and what about file / mask being Qt ? -- dvl */ | |
2909 alist = tagged_vector_to_alist (inst); | 2907 alist = tagged_vector_to_alist (inst); |
2910 | 2908 |
2911 { | 2909 { |
2910 /* #### FIXME: what if EQ (file, Qt) && !EQ (mask, Qt) ? Is that possible? | |
2911 If so, we have a problem... -- dvl */ | |
2912 Lisp_Object data = make_string_from_file (file); | 2912 Lisp_Object data = make_string_from_file (file); |
2913 alist = remassq_no_quit (Q_file, alist); | 2913 alist = remassq_no_quit (Q_file, alist); |
2914 /* there can't be a :data at this point. */ | 2914 /* there can't be a :data at this point. */ |
2915 alist = Fcons (Fcons (Q_file, file), | 2915 alist = Fcons (Fcons (Q_file, file), |
2916 Fcons (Fcons (Q_data, data), alist)); | 2916 Fcons (Fcons (Q_data, data), alist)); |
3380 } | 3380 } |
3381 else | 3381 else |
3382 ABORT (); /* We're not allowed anything else currently. */ | 3382 ABORT (); /* We're not allowed anything else currently. */ |
3383 | 3383 |
3384 /* If we don't have an instance at this point then create | 3384 /* If we don't have an instance at this point then create |
3385 one. */ | 3385 one. */ |
3386 if (UNBOUNDP (instance)) | 3386 if (UNBOUNDP (instance)) |
3387 { | 3387 { |
3388 Lisp_Object locative = | 3388 Lisp_Object locative = |
3389 noseeum_cons (Qnil, | 3389 noseeum_cons (Qnil, |
3390 noseeum_cons (hash_key, | 3390 noseeum_cons (hash_key, |
3427 #endif | 3427 #endif |
3428 } | 3428 } |
3429 else if (NILP (instance)) | 3429 else if (NILP (instance)) |
3430 gui_error ("Can't instantiate image (probably cached)", instantiator); | 3430 gui_error ("Can't instantiate image (probably cached)", instantiator); |
3431 /* We found an instance. However, because we are using the glyph | 3431 /* We found an instance. However, because we are using the glyph |
3432 as the hash key instead of the instantiator, the current | 3432 as the hash key instead of the instantiator, the current |
3433 instantiator may not be the same as the original. Thus we | 3433 instantiator may not be the same as the original. Thus we |
3434 must update the instance based on the new | 3434 must update the instance based on the new |
3435 instantiator. Preserving instance identity like this is | 3435 instantiator. Preserving instance identity like this is |
3436 important to stop excessive window system widget creation and | 3436 important to stop excessive window system widget creation and |
3437 deletion - and hence flashing. */ | 3437 deletion - and hence flashing. */ |
3438 else | 3438 else |
3439 { | 3439 { |
3440 /* #### This function should be able to cope with *all* | 3440 /* #### This function should be able to cope with *all* |
3441 changes to the instantiator, but currently only copes | 3441 changes to the instantiator, but currently only copes |
3442 with the most used properties. This means that it is | 3442 with the most used properties. This means that it is |
4282 image_instance_layout (instance, width, height, xoffset, yoffset, domain); | 4282 image_instance_layout (instance, width, height, xoffset, yoffset, domain); |
4283 } | 4283 } |
4284 | 4284 |
4285 | 4285 |
4286 /***************************************************************************** | 4286 /***************************************************************************** |
4287 * glyph cachel functions * | 4287 * glyph cachel functions * |
4288 *****************************************************************************/ | 4288 *****************************************************************************/ |
4289 | 4289 |
4290 /* #### All of this is 95% copied from face cachels. Consider | 4290 /* #### All of this is 95% copied from face cachels. Consider |
4291 consolidating. | 4291 consolidating. |
4292 | 4292 |
4455 #endif /* MEMORY_USAGE_STATS */ | 4455 #endif /* MEMORY_USAGE_STATS */ |
4456 | 4456 |
4457 | 4457 |
4458 | 4458 |
4459 /***************************************************************************** | 4459 /***************************************************************************** |
4460 * subwindow cachel functions * | 4460 * subwindow cachel functions * |
4461 *****************************************************************************/ | 4461 *****************************************************************************/ |
4462 /* Subwindows are curious in that you have to physically unmap them to | 4462 /* Subwindows are curious in that you have to physically unmap them to |
4463 not display them. It is problematic deciding what to do in | 4463 not display them. It is problematic deciding what to do in |
4464 redisplay. We have two caches - a per-window instance cache that | 4464 redisplay. We have two caches - a per-window instance cache that |
4465 keeps track of subwindows on a window, these are linked to their | 4465 keeps track of subwindows on a window, these are linked to their |
4823 | 4823 |
4824 /* make sure we don't get expose events */ | 4824 /* make sure we don't get expose events */ |
4825 register_ignored_expose (f, IMAGE_INSTANCE_DISPLAY_X (ii), | 4825 register_ignored_expose (f, IMAGE_INSTANCE_DISPLAY_X (ii), |
4826 IMAGE_INSTANCE_DISPLAY_Y (ii), | 4826 IMAGE_INSTANCE_DISPLAY_Y (ii), |
4827 IMAGE_INSTANCE_DISPLAY_WIDTH (ii), | 4827 IMAGE_INSTANCE_DISPLAY_WIDTH (ii), |
4828 IMAGE_INSTANCE_DISPLAY_HEIGHT (ii)); | 4828 IMAGE_INSTANCE_DISPLAY_HEIGHT (ii)); |
4829 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; | 4829 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0; |
4830 | 4830 |
4831 MAYBE_DEVMETH (XDEVICE (IMAGE_INSTANCE_DEVICE (ii)), | 4831 MAYBE_DEVMETH (XDEVICE (IMAGE_INSTANCE_DEVICE (ii)), |
4832 unmap_subwindow, (ii)); | 4832 unmap_subwindow, (ii)); |
4833 } | 4833 } |
5099 && | 5099 && |
5100 !disable_animated_pixmaps) | 5100 !disable_animated_pixmaps) |
5101 { | 5101 { |
5102 /* Increment the index of the image slice we are currently | 5102 /* Increment the index of the image slice we are currently |
5103 viewing. */ | 5103 viewing. */ |
5104 IMAGE_INSTANCE_PIXMAP_SLICE (ii) = | 5104 IMAGE_INSTANCE_PIXMAP_SLICE (ii) = |
5105 (IMAGE_INSTANCE_PIXMAP_SLICE (ii) + 1) | 5105 (IMAGE_INSTANCE_PIXMAP_SLICE (ii) + 1) |
5106 % IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii); | 5106 % IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii); |
5107 /* We might need to kick redisplay at this point - but we | 5107 /* We might need to kick redisplay at this point - but we |
5108 also might not. */ | 5108 also might not. */ |
5109 MARK_DEVICE_FRAMES_GLYPHS_CHANGED | 5109 MARK_DEVICE_FRAMES_GLYPHS_CHANGED |