diff options
| author | Bryce Harrington <b.harrington@samsung.com> | 2013-11-20 18:33:39 -0800 |
|---|---|---|
| committer | Bryce Harrington <b.harrington@samsung.com> | 2013-11-20 18:33:39 -0800 |
| commit | a420122ab0081b7491a2c4c32256ab09fe961e15 (patch) | |
| tree | fe9630238f26c77403f5f08cf84d9e6496cef62c /src/surface-cairo-glx.cpp | |
| parent | 65f82c82751bbc7871229a4d6654a060874f4e46 (diff) | |
Rename the cairo surface modules to permit adding skia surface modules too
Diffstat (limited to 'src/surface-cairo-glx.cpp')
| -rw-r--r-- | src/surface-cairo-glx.cpp | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/surface-cairo-glx.cpp b/src/surface-cairo-glx.cpp new file mode 100644 index 0000000..a8548ac --- /dev/null +++ b/src/surface-cairo-glx.cpp @@ -0,0 +1,105 @@ +#include <err.h> +#include <stdlib.h> +#include <cairo.h> +#include <cairo-gl.h> + +struct graphics_state { + Display *dpy; + Window window; + + GLXContext glx_context; +}; + +static void +cleanup (void *data) +{ + struct graphics_state *state = (graphics_state*)data; + + glXDestroyContext (state->dpy, state->glx_context); + + XDestroyWindow (state->dpy, state->window); + XCloseDisplay (state->dpy); + + free (state); +} + +cairo_surface_t * +create_source_surface_glx (int width, int height) +{ + struct graphics_state *state; + cairo_device_t *cairo_device; + cairo_surface_t *cairo_surface; + + int rgba_attribs[] = { + GLX_RGBA, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + GLX_ALPHA_SIZE, 1, + GLX_DOUBLEBUFFER, + None + }; + XVisualInfo *visinfo; + XSetWindowAttributes xattr; + + state = (graphics_state*) malloc (sizeof (struct graphics_state)); + if (!state) { + warnx ("Out of memory\n"); + return NULL; + } + + state->dpy = XOpenDisplay (NULL); + if (state->dpy == NULL) { + warnx ("Failed to open display: %s\n", XDisplayName (0)); + return NULL; + } + + visinfo = glXChooseVisual (state->dpy, DefaultScreen (state->dpy), rgba_attribs); + if (visinfo == NULL) { + warnx ("Failed to create RGBA and double-buffered visuals\n"); + XCloseDisplay (state->dpy); + return NULL; + } + + xattr.colormap = XCreateColormap (state->dpy, + RootWindow (state->dpy, visinfo->screen), + visinfo->visual, AllocNone); + xattr.border_pixel = 0; + state->window = XCreateWindow (state->dpy, + DefaultRootWindow (state->dpy), + 100, 50, + width, height, 0, visinfo->depth, + InputOutput, visinfo->visual, + CWBorderPixel | CWColormap, + &xattr); + XMapWindow (state->dpy, state->window); + + state->glx_context = glXCreateContext (state->dpy, visinfo, NULL, True); + XFree (visinfo); + + if (state->glx_context == NULL) { + warnx ("Could not create glx context\n"); + XCloseDisplay (state->dpy); + return NULL; + } + + cairo_device = cairo_glx_device_create (state->dpy, state->glx_context); + cairo_gl_device_set_thread_aware (cairo_device, 0); + cairo_surface = cairo_gl_surface_create_for_window (cairo_device, + state->window, + width, + height); + if (cairo_device_set_user_data (cairo_device, + (cairo_user_data_key_t *) cleanup, + state, + cleanup)) + { + warnx ("Failed to setup cleanup callback closure\n"); + cleanup (state); + return NULL; + } + + cairo_device_destroy (cairo_device); + + return cairo_surface; +} |