Mercurial > hg > xemacs-beta
changeset 3676:3ef0aaf3dc34
[xemacs-hg @ 2006-11-12 13:40:04 by aidan]
Prevent a crash if the ASCII charset registries match nothing.
author | aidan |
---|---|
date | Sun, 12 Nov 2006 13:40:09 +0000 |
parents | 0492077a2e85 |
children | cc2bbf4b5777 |
files | src/ChangeLog src/charset.h src/faces.c src/faces.h src/frame-gtk.c src/frame-x.c src/mule-charset.c src/objects-gtk.c src/objects-xlike-inc.c src/window.c |
diffstat | 10 files changed, 181 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ChangeLog Sat Nov 11 22:51:05 2006 +0000 +++ b/src/ChangeLog Sun Nov 12 13:40:09 2006 +0000 @@ -1,3 +1,43 @@ +2006-11-12 Aidan Kehoe <kehoea@parhasard.net> + + * charset.h: + * mule-charset.c (set_charset_registries): + Provide a C-accessible version of set-charset-registries that + doesn't error. Called from x_find_charset_font. + + * faces.c (ensure_face_cachel_contains_charset): + Correct my spelling. + + * faces.c (update_EmacsFrame): + Don't update the frame if it isn't live. + + * faces.h: + Add some documentation on FACE_FONT. + + * frame-gtk.c (gtk_update_frame_external_traits): + * frame-x.c (x_update_frame_external_traits): + In the event that FACE_FONT has deleted the frame, don't + manipulate it further in update_frame_external_traits. + + * mule-charset.c: + + * mule-charset.c (Fset_charset_registries): + Don't allow XLFD wildcards in charset registries. Call the + factored-out C-callable version instead of implementing the guts + of the function here. + + * objects-gtk.c: + #include "charset.h" + + * objects-xlike-inc.c (x_find_charset_font, + gtk_find_charset_font): In the event that the charset is ASCII and + we haven't matched anything up to now, even with a pattern of "*", + add "iso8859-1" to the charset's registry and try again. + + * window.c (window_pixel_width_to_char_width): + The default width of a face may be zero; only divide by it if it's + nonzero. + 2006-11-11 Aidan Kehoe <kehoea@parhasard.net> * specifier.c:
--- a/src/charset.h Sat Nov 11 22:51:05 2006 +0000 +++ b/src/charset.h Sun Nov 12 13:40:09 2006 +0000 @@ -574,6 +574,8 @@ int USED_IF_MULE (l), unsigned_char_dynarr *dst, enum unicode_type type, unsigned int little_endian); +void set_charset_registries(Lisp_Object charset, Lisp_Object registries); + EXFUN (Funicode_to_char, 2); EXFUN (Fchar_to_unicode, 1);
--- a/src/faces.c Sat Nov 11 22:51:05 2006 +0000 +++ b/src/faces.c Sun Nov 12 13:40:09 2006 +0000 @@ -1162,7 +1162,7 @@ /* Lookup the face again, this time allowing the fallback. If this succeeds, it'll give a font intended for the script in question, which is preferable to translating to ISO10646-1 and using the - fixed-with fallback. */ + fixed-width fallback. */ new_val = face_property_matching_instance (face, Qfont, charset, domain, ERROR_ME_DEBUG_WARN, 0, @@ -1841,6 +1841,9 @@ { struct frame *frm = XFRAME (frame); + if (!FRAME_LIVE_P(frm)) + return; + if (EQ (name, Qfont)) MARK_FRAME_SIZE_SLIPPED (frm);
--- a/src/faces.h Sat Nov 11 22:51:05 2006 +0000 +++ b/src/faces.h Sun Nov 12 13:40:09 2006 +0000 @@ -386,6 +386,10 @@ FACE_PROPERTY_INSTANCE (face, Qforeground, domain, 0, Qzero) #define FACE_BACKGROUND(face, domain) \ FACE_PROPERTY_INSTANCE (face, Qbackground, domain, 0, Qzero) + +/* Calling this function on the default face with the ASCII character set + may delete any X11 frames; see the code at the end of + x_find_charset_font. */ #define FACE_FONT(face, domain, charset) \ face_property_matching_instance (face, Qfont, charset, domain, \ ERROR_ME_DEBUG_WARN, 0, Qzero, \
--- a/src/frame-gtk.c Sat Nov 11 22:51:05 2006 +0000 +++ b/src/frame-gtk.c Sun Nov 12 13:40:09 2006 +0000 @@ -1430,6 +1430,17 @@ { Lisp_Object font = FACE_FONT (Vdefault_face, frame, Vcharset_ascii); + /* It may be that instantiating the font has deleted the frame (will + happen if the user has specified a charset registry for ASCII that + isn't available on the server, and our fallback of iso8859-1 isn't + available; something vanishingly rare.) In that case, return from + this function. */ + + if (!FRAME_LIVE_P(frm)) + { + return; + } + if (!EQ (font, Vthe_null_font_instance)) { /* #### BILL!!! The X code set the XtNfont property of the
--- a/src/frame-x.c Sat Nov 11 22:51:05 2006 +0000 +++ b/src/frame-x.c Sun Nov 12 13:40:09 2006 +0000 @@ -2734,6 +2734,17 @@ { Lisp_Object font = FACE_FONT (Vdefault_face, frame, Vcharset_ascii); + /* It may be that instantiating the font has deleted the frame (will + happen if the user has specified a charset registry for ASCII that + isn't available on the server, and our fallback of iso8859-1 isn't + available; something vanishingly rare.) In that case, return from + this function without further manipulation of the dead frame. */ + + if (!FRAME_LIVE_P(frm)) + { + return; + } + /* #### what to do about Xft? I don't think the font is actually used to compute cell size for computing frame pixel dimensions (see call to EmacsFrameRecomputeCellSize() below); where is it used? -- sjt
--- a/src/mule-charset.c Sat Nov 11 22:51:05 2006 +0000 +++ b/src/mule-charset.c Sun Nov 12 13:40:09 2006 +0000 @@ -883,6 +883,14 @@ return Qnil; } +void +set_charset_registries(Lisp_Object charset, Lisp_Object registries) +{ + XCHARSET_REGISTRIES (charset) = registries; + invalidate_charset_font_caches (charset); + face_property_was_changed (Vdefault_face, Qfont, Qglobal); +} + DEFUN ("set-charset-registries", Fset_charset_registries, 2, 2, 0, /* Set the `registries' property of CHARSET to REGISTRIES. @@ -913,11 +921,19 @@ invalid_argument("Not an X11 REGISTRY-ENCODING combination", XVECTOR_DATA(registries)[i]); } + + if (qxestrchr(XSTRING_DATA(XVECTOR_DATA(registries)[i]), '*') || + qxestrchr(XSTRING_DATA(XVECTOR_DATA(registries)[i]), '?')) + { + invalid_argument + ("XLFD wildcards not allowed in charset-registries", + XVECTOR_DATA(registries)[i]); + + } } - XCHARSET_REGISTRIES (charset) = registries; - invalidate_charset_font_caches (charset); - face_property_was_changed (Vdefault_face, Qfont, Qglobal); + set_charset_registries(charset, registries); + return Qnil; }
--- a/src/objects-gtk.c Sat Nov 11 22:51:05 2006 +0000 +++ b/src/objects-gtk.c Sun Nov 12 13:40:09 2006 +0000 @@ -31,6 +31,7 @@ #include "lisp.h" #include "buffer.h" +#include "charset.h" #include "device-impl.h" #include "insdel.h"
--- a/src/objects-xlike-inc.c Sat Nov 11 22:51:05 2006 +0000 +++ b/src/objects-xlike-inc.c Sun Nov 12 13:40:09 2006 +0000 @@ -764,6 +764,92 @@ charset, stage); } + /* In the event that the charset is ASCII and we haven't matched + anything up to now, even with a pattern of "*", add "iso8859-1" + to the charset's registry and try again. Not returning a result + for ASCII means our frame geometry calculations are + inconsistent, and that we may crash. */ + + if (1 == xlfd_length && EQ(charset, Vcharset_ascii) && NILP(result) + && ('*' == eigetch(ei_xlfd_without_registry, 0))) + + { + int have_latin1 = 0; + + /* Set this to, for example, is08859-1 if you want to see the + error behaviour. */ + +#define FALLBACK_ASCII_REGISTRY "iso8859-1" + + for (j = 0; j < registries_len; ++j) + { + if (0 == qxestrcasecmp(XSTRING_DATA(XVECTOR_DATA(registries)[j]), + FALLBACK_ASCII_REGISTRY)) + { + have_latin1 = 1; + break; + } + } + + if (!have_latin1) + { + Lisp_Object new_registries = make_vector(registries_len + 1, Qnil); + + warn_when_safe (Qface, Qwarning, + "Your ASCII charset registries contain nothing " + "sensible. Adding `" FALLBACK_ASCII_REGISTRY "'."); + + XVECTOR_DATA(new_registries)[0] + = build_string(FALLBACK_ASCII_REGISTRY); + + memcpy(XVECTOR_DATA(new_registries) + 1, + XVECTOR_DATA(registries), + sizeof XVECTOR_DATA(registries)[0] * + XVECTOR_LENGTH(registries)); + + /* Calling set_charset_registries instead of overwriting the + value directly, to allow the charset font caches to be + invalidated and a change to the default face to be + noted. */ + set_charset_registries(charset, new_registries); + + /* And recurse. */ + result = + DEVMETH_OR_GIVEN (XDEVICE (device), find_charset_font, + (device, font, charset, stage), + result); + } + else + { + DECLARE_EISTRING (ei_connection_name); + + /* We preserve a copy of the connection name for the error message + after the device is deleted. */ + eicpy_lstr (ei_connection_name, + DEVICE_CONNECTION (XDEVICE(device))); + + stderr_out ("Cannot find a font for ASCII, deleting device on %s\n", + eidata (ei_connection_name)); + + io_error_delete_device (device); + + /* Do a normal warning in the event that we have other, non-X + frames available. (If we don't, io_error_delete_device will + have exited.) */ + warn_when_safe + (Qface, Qerror, + "Cannot find a font for ASCII, deleting device on %s.\n" + "\n" + "Your X server fonts appear to be inconsistent; fix them, or\n" + "the next frame you create on that DISPLAY will crash this\n" + "XEmacs. At a minimum, provide one font with an XLFD ending\n" + "in `" FALLBACK_ASCII_REGISTRY "', so we can work out what size\n" + "a frame should be. ", + eidata (ei_connection_name)); + } + + } + /* This function used to return the font spec, in the case where a font didn't exist on the X server but it did match the charset. We're not doing that any more, because none of the other platform code does, and
--- a/src/window.c Sat Nov 11 22:51:05 2006 +0000 +++ b/src/window.c Sun Nov 12 13:40:09 2006 +0000 @@ -4250,7 +4250,7 @@ int include_margins_p) { int avail_width; - int char_width; + int char_width = 0; int defheight, defwidth; Lisp_Object window = wrap_window (w); @@ -4263,7 +4263,8 @@ default_face_height_and_width (window, &defheight, &defwidth); - char_width = (avail_width / defwidth); + if (defwidth) + char_width = (avail_width / defwidth); /* It's the calling function's responsibility to check these values and make sure they're not out of range.