if (EQ (keyw, Qname))
name_seen = 1;
else
- abort ();
+ ABORT ();
}
if (!name_seen)
void
ensure_face_cachel_complete (struct face_cachel *cachel,
- Lisp_Object domain, unsigned char *charsets)
+ Lisp_Object domain, Charset_ID *charsets)
{
int i;
void
face_cachel_charset_font_metric_info (struct face_cachel *cachel,
- unsigned char *charsets,
+ Charset_ID *charsets,
struct font_metric_info *fm)
{
int i;
}
}
-/* Called when the updated flag has been cleared on a cachel. */
-
-void
-update_face_cachel_data (struct face_cachel *cachel,
- Lisp_Object domain,
- Lisp_Object face)
-{
- if (XFACE (face)->dirty || UNBOUNDP (cachel->face))
- {
- int default_face = EQ (face, Vdefault_face);
- cachel->face = face;
-
- /* We normally only set the _specified flags if the value was
- actually bound. The exception is for the default face where
- we always set it since it is the ultimate fallback. */
-
#define FROB(field) \
do { \
Lisp_Object new_val = \
cachel->field##_specified = (bound || default_face); \
} while (0)
+/*
+ * A face's background pixmap will override the face's
+ * background color. But the background pixmap of the
+ * default face should not override the background color of
+ * a face if the background color has been specified or
+ * inherited.
+ *
+ * To accomplish this we remove the background pixmap of the
+ * cachel and mark it as having been specified so that cachel
+ * merging won't override it later.
+ */
+#define MAYBE_UNFROB_BACKGROUND_PIXMAP \
+do \
+{ \
+ if (! default_face \
+ && cachel->background_specified \
+ && ! cachel->background_pixmap_specified) \
+ { \
+ cachel->background_pixmap = Qunbound; \
+ cachel->background_pixmap_specified = 1; \
+ } \
+} while (0)
+
+
+/* Add a cachel for the given face to the given window's cache. */
+
+static void
+add_face_cachel (struct window *w, Lisp_Object face)
+{
+ int must_finish_frobbing = ! WINDOW_FACE_CACHEL (w, DEFAULT_INDEX);
+ struct face_cachel new_cachel;
+ Lisp_Object domain;
+
+ reset_face_cachel (&new_cachel);
+ XSETWINDOW (domain, w);
+ update_face_cachel_data (&new_cachel, domain, face);
+ Dynarr_add (w->face_cachels, new_cachel);
+
+ /* The face's background pixmap have not yet been frobbed (see comment
+ int update_face_cachel_data), so we have to do it now */
+ if (must_finish_frobbing)
+ {
+ int default_face = EQ (face, Vdefault_face);
+ struct face_cachel *cachel
+ = Dynarr_atp (w->face_cachels, Dynarr_length (w->face_cachels) - 1);
+
+ FROB (background_pixmap);
+ MAYBE_UNFROB_BACKGROUND_PIXMAP;
+ }
+}
+
+/* Called when the updated flag has been cleared on a cachel.
+ This function returns 1 if the caller must finish the update (see comment
+ below), 0 otherwise.
+*/
+
+void
+update_face_cachel_data (struct face_cachel *cachel,
+ Lisp_Object domain,
+ Lisp_Object face)
+{
+ if (XFACE (face)->dirty || UNBOUNDP (cachel->face))
+ {
+ int default_face = EQ (face, Vdefault_face);
+ cachel->face = face;
+
+ /* We normally only set the _specified flags if the value was
+ actually bound. The exception is for the default face where
+ we always set it since it is the ultimate fallback. */
+
FROB (foreground);
FROB (background);
FROB (display_table);
- FROB (background_pixmap);
- /*
- * A face's background pixmap will override the face's
- * background color. But the background pixmap of the
- * default face should not override the background color of
- * a face if the background color has been specified or
- * inherited.
- *
- * To accomplish this we remove the background pixmap of the
- * cachel and mark it as having been specified so that cachel
- * merging won't override it later.
- */
- if (! default_face
- && cachel->background_specified
- && ! cachel->background_pixmap_specified)
+ /* #### WARNING: the background pixmap property of faces is currently
+ the only one dealing with images. The problem we have here is that
+ frobbing the background pixmap might lead to image instantiation
+ which in turn might require that the cache we're building be up to
+ date, hence a crash. Here's a typical scenario of this:
+
+ - a new window is created and it's face cache elements are
+ initialized through a call to reset_face_cachels[1]. At that point,
+ the cache for the default and modeline faces (normaly taken care of
+ by redisplay itself) are null.
+ - the default face has a background pixmap which needs to be
+ instantiated right here, as a consequence of cache initialization.
+ - the background pixmap image happens to be instantiated as a string
+ (this happens on tty's for instance).
+ - In order to do this, we need to compute the string geometry.
+ - In order to do this, we might have to access the window's default
+ face cache. But this is the cache we're building right now, it is
+ null.
+ - BARF !!!!!
+
+ To sum up, this means that it is in general unsafe to instantiate
+ images before face cache updating is complete (appart from image
+ related face attributes). The solution we use below is to actually
+ detect whether we're building the window's face_cachels for the first
+ time, and simply NOT frob the background pixmap in that case. If
+ other image-related face attributes are ever implemented, they should
+ be protected the same way right here.
+
+ One note:
+ * See comment in `default_face_font_info' in face.c. Who wrote it ?
+ Maybe we have the begining of an answer here ?
+
+ Footnotes:
+ [1] See comment at the top of `allocate_window' in window.c.
+
+ -- didier
+ */
+ if (! WINDOWP (domain)
+ || WINDOW_FACE_CACHEL (DOMAIN_XWINDOW (domain), DEFAULT_INDEX))
{
- cachel->background_pixmap = Qunbound;
- cachel->background_pixmap_specified = 1;
+ FROB (background_pixmap);
+ MAYBE_UNFROB_BACKGROUND_PIXMAP;
}
-
#undef FROB
+#undef MAYBE_UNFROB_BACKGROUND_PIXMAP
ensure_face_cachel_contains_charset (cachel, domain, Vcharset_ascii);
cachel->background_pixmap = Qunbound;
}
-/* Add a cachel for the given face to the given window's cache. */
-
-static void
-add_face_cachel (struct window *w, Lisp_Object face)
-{
- struct face_cachel new_cachel;
- Lisp_Object window;
-
- reset_face_cachel (&new_cachel);
- XSETWINDOW (window, w);
- update_face_cachel_data (&new_cachel, window, face);
- Dynarr_add (w->face_cachels, new_cachel);
-}
-
/* Retrieve the index to a cachel for window W that corresponds to
the specified face. If necessary, add a new element to the
cache. */
{
Lisp_Object fg_fb = Qnil, bg_fb = Qnil;
+#ifdef HAVE_GTK
+ fg_fb = acons (list1 (Qgtk), build_string ("black"), fg_fb);
+ bg_fb = acons (list1 (Qgtk), build_string ("white"), bg_fb);
+#endif
#ifdef HAVE_X_WINDOWS
fg_fb = acons (list1 (Qx), build_string ("black"), fg_fb);
bg_fb = acons (list1 (Qx), build_string ("white"), bg_fb);
support is compiled in. */
{
Lisp_Object inst_list = Qnil;
-#ifdef HAVE_X_WINDOWS
+
+#if defined(HAVE_X_WINDOWS) || defined(HAVE_GTK)
+ /* This is kind of ugly because stephen wanted this to be CPP
+ ** identical to the old version, at least for the initial
+ ** checkin
+ **
+ ** WMP March 9, 2001
+ */
+
/* The same gory list from x-faces.el.
(#### Perhaps we should remove the stuff from x-faces.el
and only depend on this stuff here? That should work.)
};
const char **fontptr;
+#ifdef HAVE_X_WINDOWS
for (fontptr = fonts + countof(fonts) - 1; fontptr >= fonts; fontptr--)
inst_list = Fcons (Fcons (list1 (Qx), build_string (*fontptr)),
inst_list);
#endif /* HAVE_X_WINDOWS */
+#ifdef HAVE_GTK
+ for (fontptr = fonts + countof(fonts) - 1; fontptr >= fonts; fontptr--)
+ inst_list = Fcons (Fcons (list1 (Qgtk), build_string (*fontptr)),
+ inst_list);
+#endif /* HAVE_GTK */
+#endif /* HAVE_X_WINDOWS || HAVE_GTK */
+
+
#ifdef HAVE_TTY
inst_list = Fcons (Fcons (list1 (Qtty), build_string ("normal")),
inst_list);
#ifdef HAVE_MS_WINDOWS
/* Fixedsys does not exist for printers */
inst_list = Fcons (Fcons (list1 (Qmsprinter),
- build_string ("Courier:Regular:10::Western")), inst_list);
+ build_string ("Courier:Regular:10::Western")), inst_list);
inst_list = Fcons (Fcons (list1 (Qmsprinter),
- build_string ("Courier New:Regular:10::Western")), inst_list);
+ build_string ("Courier New:Regular:10::Western")), inst_list);
inst_list = Fcons (Fcons (list1 (Qmswindows),
- build_string ("Fixedsys:Regular:9::Western")), inst_list);
+ build_string ("Fixedsys:Regular:9::Western")), inst_list);
inst_list = Fcons (Fcons (list1 (Qmswindows),
- build_string ("Courier:Regular:10::Western")), inst_list);
+ build_string ("Courier:Regular:10::Western")), inst_list);
inst_list = Fcons (Fcons (list1 (Qmswindows),
- build_string ("Courier New:Regular:10::Western")), inst_list);
+ build_string ("Courier New:Regular:10::Western")), inst_list);
#endif /* HAVE_MS_WINDOWS */
set_specifier_fallback (Fget (Vdefault_face, Qfont, Qnil), inst_list);
}
{
Lisp_Object fg_fb = Qnil, bg_fb = Qnil;
+#ifdef HAVE_GTK
+ /* We need to put something in there, or error checking gets
+ #%!@#ed up before the styles are set, which override the
+ fallbacks. */
+ fg_fb = acons (list1 (Qgtk), build_string ("black"), fg_fb);
+ bg_fb = acons (list1 (Qgtk), build_string ("Gray80"), bg_fb);
+#endif
#ifdef HAVE_X_WINDOWS
fg_fb = acons (list1 (Qx), build_string ("black"), fg_fb);
bg_fb = acons (list1 (Qx), build_string ("Gray80"), bg_fb);