I've just hit a snag with Xft. If I open a font on one display, then
subsequently open a new font of the exact same name, (ie. same string
to XftFontOpenName), on a second display, things don't go my way:
$ ./xft_test :0 :1
X Error of failed request: 189
Major opcode of failed request: 154 (RENDER)
Minor opcode of failed request: 23 ()
Serial number of failed request: 22
Current serial number in output stream: 22
If I close the first font before opening the second, then the problem
goes away. Looks like some display-specific state is cached somewhere
in Xft.
Example program to demonstrate bug attached.
-Carl
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xft/Xft.h>
#define NUM_DPY 2
#define FONT_NAME "mono-10"
int main(int argc, char *argv[])
{
int i;
Display *dpy;
int screen;
Window root;
Window window;
XftDraw *draw;
XftColor xft_color;
XftFont *font;
Visual *visual;
Colormap cmap;
XRenderColor render_color = {0x0, 0x0, 0x0, 0xffff};
XEvent xev;
char *text = "Hello World.";
if (argc < 2) {
fprintf(stderr, "usage: %s display [display2 ...]\n", argv[0]);
exit(1);
}
for (i=1; i < argc; i++) {
dpy = XOpenDisplay(argv[i]);
if (dpy == NULL) {
fprintf(stderr, "Failed to open display %s\n", argv[i]);
exit(1);
}
root = DefaultRootWindow(dpy);
screen = DefaultScreen(dpy);
visual = DefaultVisual(dpy, screen);
cmap = DefaultColormap(dpy, screen);
window = XCreateSimpleWindow(dpy, root, 0, 0, 100, 100, 0,
BlackPixel(dpy, screen),
WhitePixel(dpy, screen));
XSelectInput(dpy, window, ExposureMask | KeyPressMask);
XMapWindow(dpy, window);
draw = XftDrawCreate(dpy, window, visual, cmap);
XftColorAllocValue(dpy, visual, cmap, &render_color, &xft_color);
font = XftFontOpenName(dpy, screen, FONT_NAME);
while (1) {
XNextEvent(dpy, &xev);
if (xev.type == Expose) {
XClearWindow(dpy, window);
XftDrawString8(draw, &xft_color, font, 20, 20,
(unsigned char *) text, strlen(text));
}
if (xev.type == KeyPress) {
break;
}
}
/*
XftFontClose(dpy, font);
*/
XftColorFree(dpy, visual, cmap, &xft_color);
XftDrawDestroy(draw);
XDestroyWindow(dpy, window);
XCloseDisplay(dpy);
}
return 0;
}