2 #include <cairo-script-interpreter.h>
8 static const cairo_user_data_key_t _key;
10 #define SINGLE_SURFACE 1
13 static cairo_surface_t *
14 _similar_surface_create (void *closure,
15 cairo_content_t content,
16 double width, double height,
19 return cairo_surface_create_similar (closure, content, width, height);
25 cairo_surface_t *surface;
29 _context_create (void *closure, cairo_surface_t *surface)
31 cairo_t *cr = cairo_create (surface);
32 struct list *l = malloc (sizeof (*l));
35 l->surface = cairo_surface_reference (surface);
41 _context_destroy (void *closure, void *ptr)
43 struct list *l, **prev = &list;
44 while ((l = *prev) != NULL) {
45 if (l->context == ptr) {
46 if (cairo_surface_status (l->surface) == CAIRO_STATUS_SUCCESS) {
47 cairo_t *cr = cairo_create (closure);
48 cairo_set_source_surface (cr, l->surface, 0, 0);
53 cairo_surface_destroy (l->surface);
63 #if CAIRO_HAS_XLIB_SURFACE
64 #include <cairo-xlib.h>
73 dpy = XOpenDisplay (NULL);
75 fprintf (stderr, "Failed to open display.\n");
83 _destroy_window (void *closure)
85 XFlush (_get_display ());
86 XDestroyWindow (_get_display(), (Window) closure);
89 static cairo_surface_t *
90 _xlib_surface_create (void *closure,
91 cairo_content_t content,
92 double width, double height,
96 XSetWindowAttributes attr;
100 cairo_surface_t *surface;
102 dpy = _get_display ();
104 visual = DefaultVisual (dpy, DefaultScreen (dpy));
105 depth = DefaultDepth (dpy, DefaultScreen (dpy));
106 attr.override_redirect = True;
107 w = XCreateWindow (dpy, DefaultRootWindow (dpy), 0, 0,
108 width <= 0 ? 1 : width,
109 height <= 0 ? 1 : height,
111 InputOutput, visual, CWOverrideRedirect, &attr);
114 surface = cairo_xlib_surface_create (dpy, w, visual, width, height);
115 cairo_surface_set_user_data (surface, &_key, (void *) w, _destroy_window);
120 #if CAIRO_HAS_XLIB_XRENDER_SURFACE
121 #include <cairo-xlib-xrender.h>
124 _destroy_pixmap (void *closure)
126 XFreePixmap (_get_display(), (Pixmap) closure);
129 static cairo_surface_t *
130 _xrender_surface_create (void *closure,
131 cairo_content_t content,
132 double width, double height,
137 XRenderPictFormat *xrender_format;
138 cairo_surface_t *surface;
140 dpy = _get_display ();
142 content = CAIRO_CONTENT_COLOR_ALPHA;
145 case CAIRO_CONTENT_COLOR_ALPHA:
146 xrender_format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
148 case CAIRO_CONTENT_COLOR:
149 xrender_format = XRenderFindStandardFormat (dpy, PictStandardRGB24);
151 case CAIRO_CONTENT_ALPHA:
153 xrender_format = XRenderFindStandardFormat (dpy, PictStandardA8);
156 pixmap = XCreatePixmap (dpy, DefaultRootWindow (dpy),
157 width, height, xrender_format->depth);
159 surface = cairo_xlib_surface_create_with_xrender_format (dpy, pixmap,
160 DefaultScreenOfDisplay (dpy),
163 cairo_surface_set_user_data (surface, &_key,
164 (void *) pixmap, _destroy_pixmap);
171 #if CAIRO_HAS_GL_GLX_SURFACE
172 #include <cairo-gl.h>
173 static cairo_gl_context_t *
174 _glx_get_context (cairo_content_t content)
176 static cairo_gl_context_t *context;
178 if (context == NULL) {
179 int rgba_attribs[] = {
188 XVisualInfo *visinfo;
192 dpy = XOpenDisplay (NULL);
194 fprintf (stderr, "Failed to open display.\n");
198 visinfo = glXChooseVisual (dpy, DefaultScreen (dpy), rgba_attribs);
199 if (visinfo == NULL) {
200 fprintf (stderr, "Failed to create RGBA, double-buffered visual\n");
204 gl_ctx = glXCreateContext (dpy, visinfo, NULL, True);
207 context = cairo_glx_context_create (dpy, gl_ctx);
213 static cairo_surface_t *
214 _glx_surface_create (void *closure,
215 cairo_content_t content,
216 double width, double height,
224 return cairo_gl_surface_create (_glx_get_context (content),
225 content, width, height);
229 #if CAIRO_HAS_PDF_SURFACE
230 #include <cairo-pdf.h>
231 static cairo_surface_t *
232 _pdf_surface_create (void *closure,
233 cairo_content_t content,
234 double width, double height,
237 return cairo_pdf_surface_create_for_stream (NULL, NULL, width, height);
241 #if CAIRO_HAS_PS_SURFACE
242 #include <cairo-ps.h>
243 static cairo_surface_t *
244 _ps_surface_create (void *closure,
245 cairo_content_t content,
246 double width, double height,
249 return cairo_ps_surface_create_for_stream (NULL, NULL, width, height);
253 #if CAIRO_HAS_SVG_SURFACE
254 #include <cairo-svg.h>
255 static cairo_surface_t *
256 _svg_surface_create (void *closure,
257 cairo_content_t content,
258 double width, double height,
261 return cairo_svg_surface_create_for_stream (NULL, NULL, width, height);
265 static cairo_surface_t *
266 _image_surface_create (void *closure,
267 cairo_content_t content,
268 double width, double height,
271 return cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
275 main (int argc, char **argv)
277 cairo_script_interpreter_t *csi;
278 cairo_script_interpreter_hooks_t hooks = {
280 .surface_create = _similar_surface_create,
281 .context_create = _context_create,
282 .context_destroy = _context_destroy
283 #elif CAIRO_HAS_XLIB_XRENDER_SURFACE
284 .surface_create = _xrender_surface_create
285 #elif CAIRO_HAS_XLIB_SURFACE
286 .surface_create = _xlib_surface_create
287 #elif CAIRO_PDF_SURFACE
288 .surface_create = _pdf_surface_create
289 #elif CAIRO_PS_SURFACE
290 .surface_create = _ps_surface_create
291 #elif CAIRO_SVG_SURFACE
292 .surface_create = _svg_surface_create
294 .surface_create = _image_surface_create
298 const struct backends {
300 csi_surface_create_func_t create;
302 { "--image", _image_surface_create },
303 #if CAIRO_HAS_XLIB_XRENDER_SURFACE
304 { "--xrender", _xrender_surface_create },
306 #if CAIRO_HAS_GL_GLX_SURFACE
307 { "--glx", _glx_surface_create },
309 #if CAIRO_HAS_XLIB_SURFACE
310 { "--xlib", _xlib_surface_create },
312 #if CAIRO_HAS_PDF_SURFACE
313 { "--pdf", _pdf_surface_create },
315 #if CAIRO_HAS_PS_SURFACE
316 { "--ps", _ps_surface_create },
318 #if CAIRO_HAS_SVG_SURFACE
319 { "--svg", _svg_surface_create },
325 hooks.closure = backends[0].create (NULL,
326 CAIRO_CONTENT_COLOR_ALPHA,
332 csi = cairo_script_interpreter_create ();
333 cairo_script_interpreter_install_hooks (csi, &hooks);
335 for (i = 1; i < argc; i++) {
336 const struct backends *b;
338 for (b = backends; b->name != NULL; b++) {
339 if (strcmp (b->name, argv[i]) == 0) {
341 cairo_surface_destroy (hooks.closure);
342 hooks.closure = b->create (NULL,
343 CAIRO_CONTENT_COLOR_ALPHA,
347 hooks.surface_create = b->create;
349 cairo_script_interpreter_install_hooks (csi, &hooks);
355 cairo_script_interpreter_run (csi, argv[i]);
357 cairo_surface_destroy (hooks.closure);
359 return cairo_script_interpreter_destroy (csi);