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;
}

Reply via email to