Cairo+glitz/Setup glitz with glx
From Sidvind
glitz is an OpenGL image compositing library partially designed to act as a cairo backend. Getting glitz to work can be a bit tricky especially due to the lack of documentation. Lack of good documentation and samples for Xlib/glx makes it even worse, but I find that common with anything related to Xlib. This will be a simple tutorial on how to get glitz to work. I assume you have a basic understanding of Xlib and glx before reading this.
[edit] Creating a window
First we open a X display as usual.
Display* display = XOpenDisplay(NULL); unsigned int screen = DefaultScreen(display);
When creating the X window a XVisualInfo is needed. glitz requires a glitz_drawable_format_t which is related to the XVisualInfo. These two should match but I have seen cases where non matching similar formats has been used. I found it simpler to search for a suitable drawable format and extract the visual info from it than the other way around.
// A template format is specified.
glitz_drawable_format_t templ;
templ.samples = 1;
templ.depth_size = 24;
templ.doublebuffer = 1;
// Only the fields specified by this mask will be matched.
unsigned long format_mask = GLITZ_FORMAT_SAMPLES_MASK | GLITZ_FORMAT_DOUBLEBUFFER_MASK | GLITZ_FORMAT_DEPTH_SIZE_MASK;
// glitz_glx_find_window_format searches the available formats for one matching the template. The zero in the end specifies
// which format to use, zero means the first matching. It is possible to iterate over the available formats by increasing
// this value until NULL is returned.
glitz_drawable_format_t* dformat = glitz_glx_find_window_format (display, screen, format_mask, &templ, 0);
if (!dformat) {
fprintf (stderr, "Error: couldn't find window format\n");
return 1;
}
// As the name implies glitz_glx_get_visual_info_from_format extracts a XVisualInfo from a glitz_drawable_format_t.
XVisualInfo* vinfo = glitz_glx_get_visual_info_from_format (display, screen, dformat);
if (!vinfo) {
fprintf (stderr, "Error: no visual info from format\n");
return 1;
}
Next up is actually creating the window.
// Reference to the root-window. Window root = DefaultRootWindow(display); // Creates the colormap Colormap cmap = XCreateColormap(display, root, vinfo->visual, AllocNone); // Window attributes XSetWindowAttributes swa; swa.colormap = cmap; swa.event_mask = ExposureMask; unsigned long mask = CWColormap | CWEventMask; // Create a window using the earlier found XVisualInfo. Window window = XCreateWindow(display, root, 0, 0, 800, 600, 0, vinfo->depth, InputOutput, vinfo->visual, mask, &swa); XMapWindow(display, window); // Make it possible to "correctly" close the window. Atom wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", 0); XSetWMProtocols(display, window, &wm_delete_window, 1); XSync(display, false);
[edit] Creating a drawable surface
After the window is created we create a glitz drawable which is used to create glitz surfaces. Behind the scenes this is kind of the OpenGL context and drawable usually created when using Xlib and OpenGL.
// Create the glitz drawable. If this is the first time it is called it will create the opengl context and make it the current.
glitz_drawable_t* drawable = glitz_glx_create_drawable_for_window (display, screen, dformat, window, 800, 600);
// A glitz_format_t must be used when creating a surface. Not that this is not the same format as glitz_drawable_format_t used earlier.
// Similar to before a template is created and a matching format is searched for.
glitz_format_t *format, templ;
glitz_drawable_buffer_t buffer;
templ.color = dformat->color;
format = glitz_find_format (drawable,
GLITZ_FORMAT_FOURCC_MASK |
GLITZ_FORMAT_RED_SIZE_MASK |
GLITZ_FORMAT_GREEN_SIZE_MASK |
GLITZ_FORMAT_BLUE_SIZE_MASK |
GLITZ_FORMAT_ALPHA_SIZE_MASK,
&templ,
0
);
if (!format) {
fprintf (stderr, "Error: couldn't find surface format\n");
return NULL;
}
// Create a surface with above format.
glitz_surface_t* surface = glitz_surface_create (drawable, format, 800, 600, 0, NULL);
if (!surface) {
fprintf (stderr, "Error: couldn't create glitz surface\n");
return NULL;
}
// The surface buffer must be bound to the drawable. The surface buffer is the buffer which rendering
// calls is made to. If a doublebuffered surface is selected the backbuffer will used.
if (dformat->doublebuffer) {
buffer = GLITZ_DRAWABLE_BUFFER_BACK_COLOR;
} else {
buffer = GLITZ_DRAWABLE_BUFFER_FRONT_COLOR;
}
// Bind the surface buffer to the drawable.
glitz_surface_attach (surface, drawable, buffer);
Next part: cairo+glitz/Setup cairo.

