GNOME Bugzilla – Bug 397504
Scalable bitmap font names reported but not usable after failed XSetFontPath() call
Last modified: 2007-02-10 16:16:59 UTC
Please describe the problem: (This information copied from https://launchpad.net/ubuntu/+bug/52163) In both dapper and breezy, the default session starts the gnome-settings-daemon. This program initializes by first creating the files ~/.gnome2/share/{cursor-fonts,fonts} in the user's home directory. It then runs mkfontdir on both directories, and uses XSetFontPath() to add the cursor-fonts directory to the head of the X server's font path, and the fonts directory to the tail fo the path. By default, there are no font files in either directory. Between revision 1.1 and 1.2 (root=cvs.freedesktop.org:/cvs/xorg, repository=xc) the behavior of XSetFontPath() changed from "reject directories with fonts.dir files containing at least 1 bad entry" to "accept directories if at least one good entry exists in the fonts.dir file". The subtle difference is that a fonts.dir file that contains simply "0" (i.e., and empty font directory) is rejected in the more recent revisions and accepted in the earlier ones. When the gnome-settings-daemon tries to change the X server's font path, the server sends a BadValue error (because the new directories are not valid) and gnome-settings-daemon silently ignores the error event. One of the first things the server does in response to the XSetFontPath() client message is to run the set_path_hook and clear the FontFileBitmapSources cache (lib/font/fontfile/bitsource.c). However, it appears that this only partially reset the server's view of the available fonts. The server still returns scalable bitmap font names in response to a ListFonts request, but trying to realize a concrete instance of one of these scalable bitmap names results in an error. In order to reproduce the X portion of the problem, all you need is to have both the scaled and unscaled paths to some bitmap font directory (e.g., /usr/share/X11/fonts/100dpi) in the font path, and then execute a bad XSetFontPath() request. E.g.: #> xset +fp /usr/share/X11/fonts/100dpi:unscaled #> xset fp+ /usr/share/X11/fonts/100dpi #> xset fp rehash #> xset +fp /a/bad/fontdir Now try: #> xlsfonts -fn '-adobe-helvetica-medium-r-normal--*-*-100-100-p-*-iso8859-1' => returns the name of a scalable bitmap font ('-*-0-0-100-100-p-0-*') #> xlsfonts -fn '-adobe-helvetica-medium-r-normal--*-94-100-100-p-*-iso8859-1' => returns a concreate instance of the font in a 13 point size #> xlsfonts -l -fn '-adobe-helvetica-medium-r-normal--*-94-100-100-p-*-iso8859-1' => reports that the pattern can't be matched #> xset fp rehash #> xlsfonts -l -fn '-adobe-helvetica-medium-r-normal--*-94-100-100-p-*-iso8859-1' => reports a matching concrete instance of the scalable font I would also note that the specification in doc/specs/X11/CH09 states, "The meaning of an error from this request is implementation-dependent." Shouldn't this mean that gnome-settings-daemon is responsible for handling errors? Since the effects of XSetFontPath() generating a BadValue error are not specified it should be the responsibility of the calling program/client to ensure that the error is handled. In this case, the error should be handled by gnome-settings-daemon and involves resetting the font path to the value originally returned by XGetFontPath() in gnome-settings-font.c:load_cursor(). Steps to reproduce: 1. Make sure ~/.gnome2/share/fonts/ and ~/.gnome2/share/cursor-fonts/ directories are empty (contain no font files) 2. Ensure that the X server's font path contains both the scaled and unscaled versions of a bitmap font directory 3. Start an X session that spawns the gnome-settings-daemon Actual results: For any client of the affected X server, XListFonts() return scalable bitmap font names (i.e., matching the XLFD pattern '-*-*-*-*-*-*-0-0-*-*-*-0-*-*') but XListFontsWithInfo()/XLoadQueryFont() are unable to create concrete instances of those fonts. Expected results: I would expect that I could create concrete instances of any scalable bitmap font name returned by XListFonts(). Does this happen every time? Every single time. See the xset(1) example in the main problem description. Other information: All you have to do to fix this is replace [in gnome-settings-font.c:load_cursor()]: gdk_error_trap_pop(); with: if (gdk_error_trap_pop() > 0) XSetFontPath(gdk_display, font_path, n_fonts); This does the equivalent of the shell command 'xset fp rehash' and resets the font path, and all of the X server's various internal caches, to the original state. If I can be of any help getting this fixed, please let me know. This bug currently prevents our product (VisualWorks) from starting under the default desktop environments of Debian, Ubuntu, et al. or any other system that starts with a Gnome environment that runs gnome-settings-daemon. TIA!
If I'm not mistaken, this has recently been corrected in X.org. However, I guess it can't hurt to handle such errors properly in g-s-d. Thanks for the detailed explanation. 2007-02-10 Jens Granseuer <jensgr@gmx.net> * gnome-settings-font.c: (load_cursor): if the new font path could not be set, revert to the old path (fixes bug #397504)