2009-12-07 Rolf Bjarne Kvinge <RKvinge@novell.com>
[moon.git] / cairo / boilerplate / cairo-boilerplate-glitz.c
bloba76408012604204c185ab462aa27c8e3ef033c56
1 /* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
2 /*
3 * Copyright © 2004,2006 Red Hat, Inc.
5 * Permission to use, copy, modify, distribute, and sell this software
6 * and its documentation for any purpose is hereby granted without
7 * fee, provided that the above copyright notice appear in all copies
8 * and that both that copyright notice and this permission notice
9 * appear in supporting documentation, and that the name of
10 * Red Hat, Inc. not be used in advertising or publicity pertaining to
11 * distribution of the software without specific, written prior
12 * permission. Red Hat, Inc. makes no representations about the
13 * suitability of this software for any purpose. It is provided "as
14 * is" without express or implied warranty.
16 * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
19 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
20 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
21 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
22 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 * Author: Carl D. Worth <cworth@cworth.org>
27 #include "cairo-boilerplate.h"
28 #include "cairo-boilerplate-glitz-private.h"
30 #include <cairo-glitz.h>
32 static const cairo_user_data_key_t glitz_closure_key;
34 typedef struct _glitz_target_closure_base {
35 int width;
36 int height;
37 cairo_content_t content;
38 } glitz_target_closure_base_t;
40 #if CAIRO_CAN_TEST_GLITZ_GLX_SURFACE
41 #include <glitz-glx.h>
43 typedef struct _glitz_glx_target_closure {
44 glitz_target_closure_base_t base;
45 Display *dpy;
46 int scr;
47 Window win;
48 } glitz_glx_target_closure_t;
50 static glitz_surface_t *
51 _cairo_boilerplate_glitz_glx_create_surface_internal (glitz_format_name_t formatname,
52 int width,
53 int height,
54 glitz_glx_target_closure_t *closure)
56 Display * dpy = closure->dpy;
57 int scr = closure->scr;
58 glitz_drawable_format_t templ;
59 glitz_drawable_format_t * dformat = NULL;
60 unsigned long mask;
61 glitz_drawable_t * drawable = NULL;
62 glitz_format_t * format;
63 glitz_surface_t * sr;
65 XSizeHints xsh;
66 XSetWindowAttributes xswa;
67 XVisualInfo * vinfo;
69 memset(&templ, 0, sizeof(templ));
70 templ.color.red_size = 8;
71 templ.color.green_size = 8;
72 templ.color.blue_size = 8;
73 templ.color.alpha_size = 8;
74 templ.color.fourcc = GLITZ_FOURCC_RGB;
75 templ.samples = 1;
77 glitz_glx_init (NULL);
79 mask = GLITZ_FORMAT_SAMPLES_MASK | GLITZ_FORMAT_FOURCC_MASK |
80 GLITZ_FORMAT_RED_SIZE_MASK | GLITZ_FORMAT_GREEN_SIZE_MASK |
81 GLITZ_FORMAT_BLUE_SIZE_MASK;
82 if (formatname == GLITZ_STANDARD_ARGB32)
83 mask |= GLITZ_FORMAT_ALPHA_SIZE_MASK;
85 /* Try for a pbuffer first */
86 if (!getenv("CAIRO_TEST_FORCE_GLITZ_WINDOW"))
87 dformat = glitz_glx_find_pbuffer_format (dpy, scr, mask, &templ, 0);
89 if (dformat) {
90 closure->win = None;
92 drawable = glitz_glx_create_pbuffer_drawable (dpy, scr, dformat,
93 width, height);
94 if (!drawable)
95 goto FAIL;
96 } else {
97 /* No pbuffer, try window */
98 dformat = glitz_glx_find_window_format (dpy, scr, mask, &templ, 0);
100 if (!dformat)
101 goto FAIL;
103 vinfo = glitz_glx_get_visual_info_from_format(dpy,
104 DefaultScreen(dpy),
105 dformat);
107 if (!vinfo)
108 goto FAIL;
110 xsh.flags = PSize;
111 xsh.x = 0;
112 xsh.y = 0;
113 xsh.width = width;
114 xsh.height = height;
116 xswa.colormap = XCreateColormap (dpy, RootWindow(dpy, scr),
117 vinfo->visual, AllocNone);
118 closure->win = XCreateWindow (dpy, RootWindow(dpy, scr),
119 xsh.x, xsh.y, xsh.width, xsh.height,
120 0, vinfo->depth, CopyFromParent,
121 vinfo->visual, CWColormap, &xswa);
122 XFree (vinfo);
124 drawable =
125 glitz_glx_create_drawable_for_window (dpy, scr,
126 dformat, closure->win,
127 width, height);
129 if (!drawable)
130 goto DESTROY_WINDOW;
133 format = glitz_find_standard_format (drawable, formatname);
134 if (!format)
135 goto DESTROY_DRAWABLE;
137 sr = glitz_surface_create (drawable, format, width, height, 0, NULL);
138 if (!sr)
139 goto DESTROY_DRAWABLE;
141 if (closure->win == None || dformat->doublebuffer) {
142 glitz_surface_attach (sr, drawable, GLITZ_DRAWABLE_BUFFER_BACK_COLOR);
143 } else {
144 XMapWindow (closure->dpy, closure->win);
145 glitz_surface_attach (sr, drawable, GLITZ_DRAWABLE_BUFFER_FRONT_COLOR);
148 glitz_drawable_destroy (drawable);
150 return sr;
152 DESTROY_DRAWABLE:
153 glitz_drawable_destroy (drawable);
154 DESTROY_WINDOW:
155 if (closure->win)
156 XDestroyWindow (dpy, closure->win);
157 FAIL:
158 return NULL;
161 cairo_surface_t *
162 _cairo_boilerplate_glitz_glx_create_surface (const char *name,
163 cairo_content_t content,
164 int width,
165 int height,
166 int max_width,
167 int max_height,
168 cairo_boilerplate_mode_t mode,
169 int id,
170 void **closure)
172 glitz_glx_target_closure_t *gxtc;
173 glitz_surface_t * glitz_surface;
174 cairo_surface_t * surface = NULL;
175 cairo_status_t status;
177 *closure = gxtc = xmalloc (sizeof (glitz_glx_target_closure_t));
179 if (width == 0)
180 width = 1;
181 if (height == 0)
182 height = 1;
184 gxtc->dpy = XOpenDisplay (getenv("CAIRO_TEST_GLITZ_DISPLAY"));
185 if (!gxtc->dpy) {
186 CAIRO_BOILERPLATE_LOG ("Failed to open display: %s\n", XDisplayName(0));
187 goto FAIL;
190 XSynchronize (gxtc->dpy, 1);
192 gxtc->scr = DefaultScreen(gxtc->dpy);
194 switch (content) {
195 case CAIRO_CONTENT_COLOR:
196 glitz_surface = _cairo_boilerplate_glitz_glx_create_surface_internal (GLITZ_STANDARD_RGB24, width, height, gxtc);
197 break;
198 case CAIRO_CONTENT_COLOR_ALPHA:
199 glitz_surface = _cairo_boilerplate_glitz_glx_create_surface_internal (GLITZ_STANDARD_ARGB32, width, height, gxtc);
200 break;
201 case CAIRO_CONTENT_ALPHA:
202 default:
203 CAIRO_BOILERPLATE_LOG ("Invalid content for glitz-glx test: %d\n", content);
204 goto FAIL_CLOSE_DISPLAY;
206 if (!glitz_surface) {
207 CAIRO_BOILERPLATE_LOG ("Failed to create glitz-glx surface\n");
208 goto FAIL_CLOSE_DISPLAY;
211 surface = cairo_glitz_surface_create (glitz_surface);
212 glitz_surface_destroy (glitz_surface);
214 if (cairo_surface_status (surface))
215 goto FAIL_CLOSE_DISPLAY;
217 gxtc->base.width = width;
218 gxtc->base.height = height;
219 gxtc->base.content = content;
220 status = cairo_surface_set_user_data (surface,
221 &glitz_closure_key, gxtc, NULL);
222 if (status == CAIRO_STATUS_SUCCESS)
223 return surface;
225 cairo_surface_destroy (surface);
226 surface = cairo_boilerplate_surface_create_in_error (status);
228 FAIL_CLOSE_DISPLAY:
229 glitz_glx_fini ();
230 XCloseDisplay (gxtc->dpy);
231 FAIL:
232 free (gxtc);
233 return surface;
236 void
237 _cairo_boilerplate_glitz_glx_cleanup (void *closure)
239 glitz_glx_target_closure_t *gxtc = closure;
241 glitz_glx_fini ();
243 if (gxtc->win)
244 XDestroyWindow (gxtc->dpy, gxtc->win);
246 XCloseDisplay (gxtc->dpy);
248 free (gxtc);
251 #endif /* CAIRO_CAN_TEST_GLITZ_GLX_SURFACE */
253 #if CAIRO_CAN_TEST_GLITZ_AGL_SURFACE
254 #include <glitz-agl.h>
256 typedef struct _glitz_agl_target_closure {
257 glitz_target_closure_base_t base;
258 } glitz_agl_target_closure_t;
260 glitz_surface_t *
261 _cairo_boilerplate_glitz_agl_create_surface_internal (glitz_format_name_t formatname,
262 int width,
263 int height,
264 glitz_agl_target_closure_t *closure)
266 glitz_drawable_format_t *dformat;
267 glitz_drawable_format_t templ;
268 glitz_drawable_t *gdraw;
269 glitz_format_t *format;
270 glitz_surface_t *sr = NULL;
271 unsigned long mask;
273 memset(&templ, 0, sizeof(templ));
274 templ.color.red_size = 8;
275 templ.color.green_size = 8;
276 templ.color.blue_size = 8;
277 templ.color.alpha_size = 8;
278 templ.color.fourcc = GLITZ_FOURCC_RGB;
279 templ.samples = 1;
281 mask = GLITZ_FORMAT_SAMPLES_MASK | GLITZ_FORMAT_FOURCC_MASK |
282 GLITZ_FORMAT_RED_SIZE_MASK | GLITZ_FORMAT_GREEN_SIZE_MASK |
283 GLITZ_FORMAT_BLUE_SIZE_MASK;
284 if (formatname == GLITZ_STANDARD_ARGB32)
285 mask |= GLITZ_FORMAT_ALPHA_SIZE_MASK;
287 dformat = glitz_agl_find_pbuffer_format (mask, &templ, 0);
288 if (!dformat) {
289 CAIRO_BOILERPLATE_LOG ("Glitz failed to find pbuffer format for template.");
290 goto FAIL;
293 gdraw = glitz_agl_create_pbuffer_drawable (dformat, width, height);
294 if (!gdraw) {
295 CAIRO_BOILERPLATE_LOG ("Glitz failed to create pbuffer drawable.");
296 goto FAIL;
299 format = glitz_find_standard_format (gdraw, formatname);
300 if (!format) {
301 CAIRO_BOILERPLATE_LOG ("Glitz failed to find standard format for drawable.");
302 goto DESTROY_DRAWABLE;
305 sr = glitz_surface_create (gdraw, format, width, height, 0, NULL);
306 if (!sr) {
307 CAIRO_BOILERPLATE_LOG ("Glitz failed to create a surface.");
308 goto DESTROY_DRAWABLE;
311 glitz_surface_attach (sr, gdraw, GLITZ_DRAWABLE_BUFFER_FRONT_COLOR);
313 DESTROY_DRAWABLE:
314 glitz_drawable_destroy (gdraw);
315 return sr;
317 FAIL:
318 return NULL;
321 cairo_surface_t *
322 _cairo_boilerplate_glitz_agl_create_surface (const char *name,
323 cairo_content_t content,
324 int width,
325 int height,
326 int max_width,
327 int max_height,
328 cairo_boilerplate_mode_t mode,
329 int id,
330 void **closure)
332 glitz_surface_t *glitz_surface;
333 cairo_surface_t *surface = NULL;
334 glitz_agl_target_closure_t *aglc;
336 glitz_agl_init ();
338 *closure = aglc = xmalloc (sizeof (glitz_agl_target_closure_t));
340 switch (content) {
341 case CAIRO_CONTENT_COLOR:
342 glitz_surface = _cairo_boilerplate_glitz_agl_create_surface_internal (GLITZ_STANDARD_RGB24, width, height, NULL);
343 break;
344 case CAIRO_CONTENT_COLOR_ALPHA:
345 glitz_surface = _cairo_boilerplate_glitz_agl_create_surface_internal (GLITZ_STANDARD_ARGB32, width, height, NULL);
346 break;
347 default:
348 CAIRO_BOILERPLATE_LOG ("Invalid content for glitz-agl test: %d\n", content);
349 goto FAIL;
352 if (!glitz_surface)
353 goto FAIL;
355 surface = cairo_glitz_surface_create (glitz_surface);
356 glitz_surface_destroy (glitz_surface);
358 if (cairo_surface_status (surface))
359 goto FAIL;
361 aglc->base.width = width;
362 aglc->base.height = height;
363 aglc->base.content = content;
364 status = cairo_surface_set_user_data (surface,
365 &glitz_closure_key, aglc, NULL);
366 if (status == CAIRO_STATUS_SUCCESS)
367 return surface;
369 cairo_surface_destroy (surface);
370 surface = cairo_boilerplate_surface_create_in_error (status);
372 FAIL:
373 glitz_agl_fini ();
374 return surface;
377 void
378 _cairo_boilerplate_glitz_agl_cleanup (void *closure)
380 free (closure);
381 glitz_agl_fini ();
384 #endif /* CAIRO_CAN_TEST_GLITZ_AGL_SURFACE */
386 #if CAIRO_CAN_TEST_GLITZ_WGL_SURFACE
387 #include <glitz-wgl.h>
389 typedef struct _glitz_wgl_target_closure {
390 glitz_target_closure_base_t base;
391 } glitz_wgl_target_closure_t;
393 glitz_surface_t *
394 _cairo_boilerplate_glitz_wgl_create_surface_internal (glitz_format_name_t formatname,
395 int width,
396 int height,
397 glitz_wgl_target_closure_t *closure)
399 glitz_drawable_format_t *dformat;
400 glitz_drawable_format_t templ;
401 glitz_drawable_t *gdraw;
402 glitz_format_t *format;
403 glitz_surface_t *sr = NULL;
404 unsigned long mask;
406 memset(&templ, 0, sizeof(templ));
407 templ.color.red_size = 8;
408 templ.color.green_size = 8;
409 templ.color.blue_size = 8;
410 templ.color.alpha_size = 8;
411 templ.color.fourcc = GLITZ_FOURCC_RGB;
412 templ.samples = 1;
414 mask = GLITZ_FORMAT_SAMPLES_MASK | GLITZ_FORMAT_FOURCC_MASK |
415 GLITZ_FORMAT_RED_SIZE_MASK | GLITZ_FORMAT_GREEN_SIZE_MASK |
416 GLITZ_FORMAT_BLUE_SIZE_MASK;
417 if (formatname == GLITZ_STANDARD_ARGB32)
418 mask |= GLITZ_FORMAT_ALPHA_SIZE_MASK;
420 dformat = glitz_wgl_find_pbuffer_format (mask, &templ, 0);
421 if (!dformat) {
422 CAIRO_BOILERPLATE_LOG ("Glitz failed to find pbuffer format for template.");
423 goto FAIL;
426 gdraw = glitz_wgl_create_pbuffer_drawable (dformat, width, height);
427 if (!gdraw) {
428 CAIRO_BOILERPLATE_LOG ("Glitz failed to create pbuffer drawable.");
429 goto FAIL;
432 format = glitz_find_standard_format (gdraw, formatname);
433 if (!format) {
434 CAIRO_BOILERPLATE_LOG ("Glitz failed to find standard format for drawable.");
435 goto DESTROY_DRAWABLE;
438 sr = glitz_surface_create (gdraw, format, width, height, 0, NULL);
439 if (!sr) {
440 CAIRO_BOILERPLATE_LOG ("Glitz failed to create a surface.");
441 goto DESTROY_DRAWABLE;
444 glitz_surface_attach (sr, gdraw, GLITZ_DRAWABLE_BUFFER_FRONT_COLOR);
446 DESTROY_DRAWABLE:
447 glitz_drawable_destroy (gdraw);
449 FAIL:
450 return sr; /* will be NULL unless we create it and attach */
453 cairo_surface_t *
454 _cairo_boilerplate_glitz_wgl_create_surface (const char *name,
455 cairo_content_t content,
456 int width,
457 int height,
458 int max_width,
459 int max_height,
460 cairo_boilerplate_mode_t mode,
461 int id,
462 void **closure)
464 glitz_surface_t *glitz_surface;
465 cairo_surface_t *surface = NULL;
466 glitz_wgl_target_closure_t *wglc;
468 glitz_wgl_init (NULL);
470 *closure = wglc = xmalloc (sizeof (glitz_wgl_target_closure_t));
472 switch (content) {
473 case CAIRO_CONTENT_COLOR:
474 glitz_surface = _cairo_boilerplate_glitz_wgl_create_surface_internal (GLITZ_STANDARD_RGB24, width, height, NULL);
475 break;
476 case CAIRO_CONTENT_COLOR_ALPHA:
477 glitz_surface = _cairo_boilerplate_glitz_wgl_create_surface_internal (GLITZ_STANDARD_ARGB32, width, height, NULL);
478 break;
479 default:
480 CAIRO_BOILERPLATE_LOG ("Invalid content for glitz-wgl test: %d\n", content);
481 goto FAIL;
484 if (!glitz_surface)
485 goto FAIL;
487 surface = cairo_glitz_surface_create (glitz_surface);
488 glitz_surface_destroy (glitz_surface);
490 if (cairo_surface_status (surface))
491 goto FAIL;
493 wglc->base.width = width;
494 wglc->base.height = height;
495 wglc->base.content = content;
496 status = cairo_surface_set_user_data (surface,
497 &glitz_closure_key, wglc, NULL);
498 if (status == CAIRO_STATUS_SUCCESS)
499 return surface;
501 cairo_surface_destroy (surface);
502 surface = cairo_boilerplate_surface_create_in_error (status);
504 FAIL:
505 glitz_wgl_fini ();
506 free (wglc);
507 return surface;
510 void
511 _cairo_boilerplate_glitz_wgl_cleanup (void *closure)
513 free (closure);
514 glitz_wgl_fini ();
517 #endif /* CAIRO_CAN_TEST_GLITZ_WGL_SURFACE */