[cairo-commit] 7 commits - boilerplate/cairo-boilerplate-beos-private.h boilerplate/cairo-boilerplate.c boilerplate/cairo-boilerplate-directfb.c boilerplate/cairo-boilerplate-directfb-private.h boilerplate/cairo-boilerplate-getopt.c boilerplate/cairo-boilerplate-glitz.c boilerplate/cairo-boilerplate-glitz-private.h boilerplate/cairo-boilerplate.h boilerplate/cairo-boilerplate-pdf.c boilerplate/cairo-boilerplate-pdf-private.h boilerplate/cairo-boilerplate-ps.c boilerplate/cairo-boilerplate-ps-private.h boilerplate/cairo-boilerplate-quartz.c boilerplate/cairo-boilerplate-quartz-private.h boilerplate/cairo-boilerplate-svg.c boilerplate/cairo-boilerplate-svg-private.h boilerplate/cairo-boilerplate-test-surfaces.c boilerplate/cairo-boilerplate-test-surfaces-private.h boilerplate/cairo-boilerplate-win32.c boilerplate/cairo-boilerplate-win32-printing.c boilerplate/cairo-boilerplate-win32-private.h boilerplate/cairo-boilerplate-xcb.c boilerplate/cairo-boilerplate-xcb-private.h boilerplate/cairo-boilerplate-xlib.c boilerplate/cairo-boilerplate-xlib-private.h boilerplate/xmalloc.c configure.in perf/cairo-perf.c test/a1-image-sample.c test/a1-mask.c test/a1-traps-sample.c test/a8-mask.c test/big-line.c test/big-trap.c test/bilevel-image.c test/bitmap-font.c test/buffer-diff.c test/buffer-diff.h test/cairo-test.c test/cairo-test.h test/caps-joins-alpha.c test/caps-joins.c test/caps-sub-paths.c test/clip-all.c test/clip-empty.c test/clip-fill-rule.c test/clip-fill-rule-pixel-aligned.c test/clip-nesting.c test/clip-operator.c test/clipped-group.c test/clip-push-group.c test/clip-twice.c test/clip-zero.c test/close-path.c test/composite-integer-translate-over.c test/composite-integer-translate-over-repeat.c test/composite-integer-translate-source.c test/copy-path.c test/create-for-stream.c test/create-from-png.c test/create-from-png-stream.c test/dash-caps-joins.c test/dash-curve.c test/dash-no-dash.c test/dash-offset-negative.c test/dash-scale.c test/dash-state.c test/dash-zero-length.c test/degenerate-arc.c test/degenerate-path.c test/degenerate-pen.c test/device-offset.c test/device-offset-positive.c test/device-offset-scale.c test/extend-pad.c test/extend-reflect.c test/extend-reflect-similar.c test/extend-repeat.c test/extend-repeat-similar.c test/fallback-resolution.c test/fill-and-stroke-alpha-add.c test/fill-and-stroke-alpha.c test/fill-and-stroke.c test/fill-degenerate-sort-order.c test/fill-missed-stop.c test/fill-rule.c test/filter-bilinear-extents.c test/filter-nearest-offset.c test/finer-grained-fallbacks.c test/font-face-get-type.c test/font-matrix-translation.c test/ft-font-create-for-ft-face.c test/ft-show-glyphs-positioning.c test/ft-show-glyphs-table.c test/ft-text-antialias-none.c test/ft-text-vertical-layout-type1.c test/ft-text-vertical-layout-type3.c test/get-and-set.c test/get-clip.c test/get-group-target.c test/get-path-extents.c test/get-xrender-format.c test/glyph-cache-pressure.c test/gradient-alpha.c test/gradient-zero-stops.c test/group-paint.c test/imagediff.c test/in-fill-empty-trapezoid.c test/in-fill-trapezoid.c test/infinite-join.c test/invalid-matrix.c test/large-clip.c test/large-font.c test/large-source.c test/leaky-dash.c test/leaky-dashed-rectangle.c test/leaky-polygon.c test/linear-gradient.c test/linear-gradient-reflect.c test/line-width.c test/line-width-scale.c test/line-width-zero.c test/long-dashed-lines.c test/long-lines.c test/Makefile.am test/mask-alpha.c test/mask.c test/mask-ctm.c test/mask-surface-ctm.c test/meta-surface-pattern.c test/miter-precision.c test/move-to-show-surface.c test/multi-page.c test/new-sub-path.c test/nil-surface.c test/operator-clear.c test/operator-source.c test/over-above-source.c test/over-around-source.c test/over-below-source.c test/over-between-source.c test/paint.c test/paint-repeat.c test/paint-source-alpha.c test/paint-with-alpha.c test/pattern-getters.c test/pattern-get-type.c test/pdf-features.c test/pixman-rotate.c test/ps-features.c test/pthread-show-text.c test/push-group.c test/radial-gradient.c test/random-intersections.c test/rectangle-rounding-error.c test/rectilinear-miter-limit.c test/rectilinear-stroke.c test/reflected-stroke.c test/rel-path.c test/rgb24-ignore-alpha.c test/rotate-image-surface-paint.c test/scale-down-source-surface-paint.c test/scale-source-surface-paint.c test/select-font-face.c test/select-font-no-show-text.c test/self-copy.c test/self-intersecting.c test/set-source.c test/show-text-current-point.c test/skew-extreme.c test/smask.c test/smask-fill.c test/smask-image-mask.c test/smask-mask.c test/smask-paint.c test/smask-stroke.c test/smask-text.c test/solid-pattern-cache-stress.c test/source-clip.c test/source-clip-scale.c test/source-surface-scale-paint.c test/stroke-ctm-caps.c test/stroke-image.c test/surface-finish-twice.c test/surface-pattern-big-scale-down.c test/surface-pattern.c test/surface-pattern-scale-down.c test/surface-pattern-scale-up.c test/surface-source.c test/svg-clip.c test/svg-surface.c test/text-antialias-gray.c test/text-antialias-none.c test/text-antialias-subpixel.c test/text-cache-crash.c test/text-lcd-filter-fir3.c test/text-lcd-filter-fir5.c test/text-lcd-filter-intra-pixel.c test/text-lcd-filter-none.c test/text-pattern.c test/text-rotate.c test/text-transform.c test/text-zero-len.c test/transforms.c test/translate-show-surface.c test/trap-clip.c test/truetype-tables.c test/unantialiased-shapes.c test/unbounded-operator.c test/user-font.c test/user-font-proxy.c test/xlib-expose-event.c test/xlib-surface.c test/zero-alpha.c

Chris Wilson ickle at kemper.freedesktop.org
Wed Aug 13 14:06:11 PDT 2008


 boilerplate/cairo-boilerplate-beos-private.h          |    6 
 boilerplate/cairo-boilerplate-directfb-private.h      |    3 
 boilerplate/cairo-boilerplate-directfb.c              |    5 
 boilerplate/cairo-boilerplate-getopt.c                |    7 
 boilerplate/cairo-boilerplate-glitz-private.h         |    9 
 boilerplate/cairo-boilerplate-glitz.c                 |   68 +
 boilerplate/cairo-boilerplate-pdf-private.h           |    3 
 boilerplate/cairo-boilerplate-pdf.c                   |   44 -
 boilerplate/cairo-boilerplate-ps-private.h            |    3 
 boilerplate/cairo-boilerplate-ps.c                    |   53 -
 boilerplate/cairo-boilerplate-quartz-private.h        |   13 
 boilerplate/cairo-boilerplate-quartz.c                |    3 
 boilerplate/cairo-boilerplate-svg-private.h           |    3 
 boilerplate/cairo-boilerplate-svg.c                   |   44 -
 boilerplate/cairo-boilerplate-test-surfaces-private.h |    9 
 boilerplate/cairo-boilerplate-test-surfaces.c         |   35 
 boilerplate/cairo-boilerplate-win32-printing.c        |    3 
 boilerplate/cairo-boilerplate-win32-private.h         |    3 
 boilerplate/cairo-boilerplate-win32.c                 |    3 
 boilerplate/cairo-boilerplate-xcb-private.h           |    3 
 boilerplate/cairo-boilerplate-xcb.c                   |   11 
 boilerplate/cairo-boilerplate-xlib-private.h          |    6 
 boilerplate/cairo-boilerplate-xlib.c                  |   50 +
 boilerplate/cairo-boilerplate.c                       |   41 -
 boilerplate/cairo-boilerplate.h                       |   11 
 boilerplate/xmalloc.c                                 |   10 
 configure.in                                          |    4 
 perf/cairo-perf.c                                     |   11 
 test/Makefile.am                                      |   19 
 test/a1-image-sample.c                                |    2 
 test/a1-mask.c                                        |   36 
 test/a1-traps-sample.c                                |    2 
 test/a8-mask.c                                        |   36 
 test/big-line.c                                       |    2 
 test/big-trap.c                                       |    2 
 test/bilevel-image.c                                  |    4 
 test/bitmap-font.c                                    |   23 
 test/buffer-diff.c                                    |  122 ++-
 test/buffer-diff.h                                    |    9 
 test/cairo-test.c                                     |  715 +++++++++++-------
 test/cairo-test.h                                     |   64 +
 test/caps-joins-alpha.c                               |    2 
 test/caps-joins.c                                     |    2 
 test/caps-sub-paths.c                                 |    2 
 test/clip-all.c                                       |    2 
 test/clip-empty.c                                     |    2 
 test/clip-fill-rule-pixel-aligned.c                   |    2 
 test/clip-fill-rule.c                                 |    2 
 test/clip-nesting.c                                   |    2 
 test/clip-operator.c                                  |    9 
 test/clip-push-group.c                                |    2 
 test/clip-twice.c                                     |    2 
 test/clip-zero.c                                      |    2 
 test/clipped-group.c                                  |    2 
 test/close-path.c                                     |    2 
 test/composite-integer-translate-over-repeat.c        |    2 
 test/composite-integer-translate-over.c               |    5 
 test/composite-integer-translate-source.c             |    5 
 test/copy-path.c                                      |   81 +-
 test/create-for-stream.c                              |   95 +-
 test/create-from-png-stream.c                         |   16 
 test/create-from-png.c                                |  190 ++--
 test/dash-caps-joins.c                                |    2 
 test/dash-curve.c                                     |    2 
 test/dash-no-dash.c                                   |    2 
 test/dash-offset-negative.c                           |    2 
 test/dash-scale.c                                     |    2 
 test/dash-state.c                                     |    2 
 test/dash-zero-length.c                               |    2 
 test/degenerate-arc.c                                 |    2 
 test/degenerate-path.c                                |    2 
 test/degenerate-pen.c                                 |    2 
 test/device-offset-positive.c                         |    2 
 test/device-offset-scale.c                            |    2 
 test/device-offset.c                                  |    2 
 test/extend-pad.c                                     |    2 
 test/extend-reflect-similar.c                         |    7 
 test/extend-reflect.c                                 |    5 
 test/extend-repeat-similar.c                          |    7 
 test/extend-repeat.c                                  |    5 
 test/fallback-resolution.c                            |   69 +
 test/fill-and-stroke-alpha-add.c                      |    2 
 test/fill-and-stroke-alpha.c                          |    2 
 test/fill-and-stroke.c                                |    2 
 test/fill-degenerate-sort-order.c                     |    2 
 test/fill-missed-stop.c                               |    2 
 test/fill-rule.c                                      |    2 
 test/filter-bilinear-extents.c                        |    2 
 test/filter-nearest-offset.c                          |    4 
 test/finer-grained-fallbacks.c                        |    2 
 test/font-face-get-type.c                             |   17 
 test/font-matrix-translation.c                        |   14 
 test/ft-font-create-for-ft-face.c                     |   13 
 test/ft-show-glyphs-positioning.c                     |    2 
 test/ft-show-glyphs-table.c                           |    2 
 test/ft-text-antialias-none.c                         |    4 
 test/ft-text-vertical-layout-type1.c                  |    4 
 test/ft-text-vertical-layout-type3.c                  |    4 
 test/get-and-set.c                                    |    8 
 test/get-clip.c                                       |   66 -
 test/get-group-target.c                               |    2 
 test/get-path-extents.c                               |  126 +--
 test/get-xrender-format.c                             |   51 -
 test/glyph-cache-pressure.c                           |    2 
 test/gradient-alpha.c                                 |    2 
 test/gradient-zero-stops.c                            |    2 
 test/group-paint.c                                    |    5 
 test/imagediff.c                                      |    2 
 test/in-fill-empty-trapezoid.c                        |   20 
 test/in-fill-trapezoid.c                              |   11 
 test/infinite-join.c                                  |    2 
 test/invalid-matrix.c                                 |    7 
 test/large-clip.c                                     |    2 
 test/large-font.c                                     |    4 
 test/large-source.c                                   |    2 
 test/leaky-dash.c                                     |    2 
 test/leaky-dashed-rectangle.c                         |    2 
 test/leaky-polygon.c                                  |    2 
 test/line-width-scale.c                               |    5 
 test/line-width-zero.c                                |    2 
 test/line-width.c                                     |    2 
 test/linear-gradient-reflect.c                        |    2 
 test/linear-gradient.c                                |    4 
 test/long-dashed-lines.c                              |    3 
 test/long-lines.c                                     |   21 
 test/mask-alpha.c                                     |    2 
 test/mask-ctm.c                                       |    4 
 test/mask-surface-ctm.c                               |    4 
 test/mask.c                                           |   23 
 test/meta-surface-pattern.c                           |    3 
 test/miter-precision.c                                |    6 
 test/move-to-show-surface.c                           |    2 
 test/multi-page.c                                     |   68 -
 test/new-sub-path.c                                   |    2 
 test/nil-surface.c                                    |   13 
 test/operator-clear.c                                 |   11 
 test/operator-source.c                                |   11 
 test/over-above-source.c                              |    2 
 test/over-around-source.c                             |    2 
 test/over-below-source.c                              |    2 
 test/over-between-source.c                            |    2 
 test/paint-repeat.c                                   |    4 
 test/paint-source-alpha.c                             |    4 
 test/paint-with-alpha.c                               |    4 
 test/paint.c                                          |    2 
 test/pattern-get-type.c                               |   25 
 test/pattern-getters.c                                |   13 
 test/pdf-features.c                                   |   11 
 test/pixman-rotate.c                                  |    2 
 test/ps-features.c                                    |   11 
 test/pthread-show-text.c                              |   11 
 test/push-group.c                                     |    2 
 test/radial-gradient.c                                |    2 
 test/random-intersections.c                           |    2 
 test/rectangle-rounding-error.c                       |    2 
 test/rectilinear-miter-limit.c                        |    2 
 test/rectilinear-stroke.c                             |    2 
 test/reflected-stroke.c                               |    2 
 test/rel-path.c                                       |    9 
 test/rgb24-ignore-alpha.c                             |    2 
 test/rotate-image-surface-paint.c                     |    2 
 test/scale-down-source-surface-paint.c                |    4 
 test/scale-source-surface-paint.c                     |    4 
 test/select-font-face.c                               |    2 
 test/select-font-no-show-text.c                       |    2 
 test/self-copy.c                                      |    2 
 test/self-intersecting.c                              |    2 
 test/set-source.c                                     |    2 
 test/show-text-current-point.c                        |    2 
 test/skew-extreme.c                                   |    2 
 test/smask-fill.c                                     |    3 
 test/smask-image-mask.c                               |    5 
 test/smask-mask.c                                     |    3 
 test/smask-paint.c                                    |    3 
 test/smask-stroke.c                                   |    3 
 test/smask-text.c                                     |    3 
 test/smask.c                                          |    5 
 test/solid-pattern-cache-stress.c                     |    2 
 test/source-clip-scale.c                              |    2 
 test/source-clip.c                                    |    2 
 test/source-surface-scale-paint.c                     |    4 
 test/stroke-ctm-caps.c                                |    2 
 test/stroke-image.c                                   |    2 
 test/surface-finish-twice.c                           |    2 
 test/surface-pattern-big-scale-down.c                 |    2 
 test/surface-pattern-scale-down.c                     |    2 
 test/surface-pattern-scale-up.c                       |    2 
 test/surface-pattern.c                                |    2 
 test/surface-source.c                                 |    7 
 test/svg-clip.c                                       |   18 
 test/svg-surface.c                                    |   19 
 test/text-antialias-gray.c                            |    4 
 test/text-antialias-none.c                            |    4 
 test/text-antialias-subpixel.c                        |    4 
 test/text-cache-crash.c                               |    4 
 test/text-lcd-filter-fir3.c                           |    4 
 test/text-lcd-filter-fir5.c                           |    4 
 test/text-lcd-filter-intra-pixel.c                    |    4 
 test/text-lcd-filter-none.c                           |    4 
 test/text-pattern.c                                   |    2 
 test/text-rotate.c                                    |    4 
 test/text-transform.c                                 |    7 
 test/text-zero-len.c                                  |   21 
 test/transforms.c                                     |    2 
 test/translate-show-surface.c                         |    2 
 test/trap-clip.c                                      |   27 
 test/truetype-tables.c                                |   10 
 test/unantialiased-shapes.c                           |    2 
 test/unbounded-operator.c                             |    9 
 test/user-font-proxy.c                                |    2 
 test/user-font.c                                      |    2 
 test/xlib-expose-event.c                              |   38 
 test/xlib-surface.c                                   |   48 -
 test/zero-alpha.c                                     |    2 
 214 files changed, 1916 insertions(+), 1169 deletions(-)

New commits:
commit e3665bde5dbeef3473df95eed0b1550ee679765f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Aug 13 17:41:40 2008 +0100

    [test/Makefile.am] Match *-out.{pdf,ps,svg}
    
    When cleaning files, limit the glob to only match *-out.{pdf,ps,svg} in
    order to distinguish the current practice of naming vector output files
    from possible future vector target/reference files.

diff --git a/test/Makefile.am b/test/Makefile.am
index 0dec0ac..939640e 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -915,9 +915,9 @@ CLEANFILES =					\
 # Then it became a fancy find using many GNU extensions, but then the ugly
 # reality of portability was raised and it became....
 clean-local:
-	-${FIND} . -name '*.ps'       -print | ${XARGS} ${RM}
-	-${FIND} . -name '*.pdf'      -print | ${XARGS} ${RM}
-	-${FIND} . -name '*.svg'      -print | ${XARGS} ${RM}
+	-${FIND} . -name '*-out.ps'   -print | ${XARGS} ${RM}
+	-${FIND} . -name '*-out.pdf'  -print | ${XARGS} ${RM}
+	-${FIND} . -name '*-out.svg'  -print | ${XARGS} ${RM}
 	-${FIND} . -name '*-out.png'  -print | ${XARGS} ${RM}
 	-${FIND} . -name '*-diff.png' -print | ${XARGS} ${RM}
 	-${FIND} . -name '*.log'      -print | ${XARGS} ${RM}
commit 49ea4fbb25393d214a88678d0aa0e1e0c4ba9916
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Aug 13 16:45:32 2008 +0100

    [test/create-from-png-stream] Correct check for png loading error.
    
    The test for failure to load the image surface from the png stream
    incorrectly checked for a NULL surface, instead of the error surface.

diff --git a/test/create-from-png-stream.c b/test/create-from-png-stream.c
index 4fe0579..5d58449 100644
--- a/test/create-from-png-stream.c
+++ b/test/create-from-png-stream.c
@@ -67,6 +67,7 @@ draw (cairo_t *cr, int width, int height)
     file = fopen (filename, "rb");
     if (file == NULL) {
 	cairo_test_log (ctx, "Error: failed to open file: %s\n", filename);
+	free (filename);
 	return CAIRO_TEST_FAILURE;
     }
 
@@ -75,10 +76,11 @@ draw (cairo_t *cr, int width, int height)
 
     fclose (file);
 
-    if (surface == NULL) {
+    if (cairo_surface_status (surface)) {
 	cairo_test_log (ctx,
-			"Error: failed to create surface from PNG: %s\n",
-			filename);
+			"Error: failed to create surface from PNG: %s - %s\n",
+			filename,
+			cairo_status_to_string (cairo_surface_status (surface)));
 	free (filename);
 	return CAIRO_TEST_FAILURE;
     }
commit 93af67d7fd0fab93d8f9e1bc2de1c38aa65a7a59
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Aug 13 16:04:41 2008 +0100

    [test] Pass a 'complete' name to create_surface().
    
    Construct the test name to pass to the boilerplate creation routines such
    that it uniquely identifies the test in terms of test, target, content and
    pass (similar, offset, thread). This allows the vector targets to create
    output different output files for each test, whereas before, later tests
    would overwrite existing files making debugging more difficult.

diff --git a/boilerplate/cairo-boilerplate-pdf.c b/boilerplate/cairo-boilerplate-pdf.c
index 8eedd9d..84e9f3e 100644
--- a/boilerplate/cairo-boilerplate-pdf.c
+++ b/boilerplate/cairo-boilerplate-pdf.c
@@ -68,8 +68,7 @@ _cairo_boilerplate_pdf_create_surface (const char		 *name,
     ptc->width = width;
     ptc->height = height;
 
-    xasprintf (&ptc->filename, "%s-pdf-%s-%d-out.pdf",
-	       name, cairo_boilerplate_content_name (content), id);
+    xasprintf (&ptc->filename, "%s-out.pdf", name);
 
     surface = cairo_pdf_surface_create (ptc->filename, width, height);
     if (cairo_surface_status (surface))
diff --git a/boilerplate/cairo-boilerplate-ps.c b/boilerplate/cairo-boilerplate-ps.c
index 08580cd..f5bd28c 100644
--- a/boilerplate/cairo-boilerplate-ps.c
+++ b/boilerplate/cairo-boilerplate-ps.c
@@ -63,8 +63,7 @@ _cairo_boilerplate_ps_create_surface (const char		 *name,
 
     *closure = ptc = xmalloc (sizeof (ps_target_closure_t));
 
-    xasprintf (&ptc->filename, "%s-ps-%s-%d-out.ps",
-	       name, cairo_boilerplate_content_name (content), id);
+    xasprintf (&ptc->filename, "%s-out.ps", name);
 
     ptc->width = width;
     ptc->height = height;
diff --git a/boilerplate/cairo-boilerplate-svg.c b/boilerplate/cairo-boilerplate-svg.c
index db7e665..1772988 100644
--- a/boilerplate/cairo-boilerplate-svg.c
+++ b/boilerplate/cairo-boilerplate-svg.c
@@ -61,8 +61,7 @@ _cairo_boilerplate_svg_create_surface (const char		 *name,
     ptc->width = width;
     ptc->height = height;
 
-    xasprintf (&ptc->filename, "%s-svg-%s-%d-out.svg",
-	       name, cairo_boilerplate_content_name (content), id);
+    xasprintf (&ptc->filename, "%s-out.svg", name);
 
     surface = cairo_svg_surface_create (ptc->filename, width, height);
     if (cairo_surface_status (surface))
diff --git a/boilerplate/cairo-boilerplate-win32-printing.c b/boilerplate/cairo-boilerplate-win32-printing.c
index a42a0cf..694ba9e 100644
--- a/boilerplate/cairo-boilerplate-win32-printing.c
+++ b/boilerplate/cairo-boilerplate-win32-printing.c
@@ -178,8 +178,7 @@ _cairo_boilerplate_win32_printing_create_surface (const char              *name,
 
     *closure = ptc = xmalloc (sizeof (win32_target_closure_t));
 
-    xasprintf (&ptc->filename, "%s-win32-printing-%s-out.ps",
-	       name, cairo_boilerplate_content_name (content));
+    xasprintf (&ptc->filename, "%s-out.ps", name);
     memset (&di, 0, sizeof (DOCINFO));
     di.cbSize = sizeof (DOCINFO);
     di.lpszDocName = ptc->filename;
diff --git a/test/cairo-test.c b/test/cairo-test.c
index 341ecab..739a027 100644
--- a/test/cairo-test.c
+++ b/test/cairo-test.c
@@ -360,8 +360,9 @@ cairo_test_for_target (const cairo_test_context_t		 *ctx,
     cairo_test_status_t status;
     cairo_surface_t *surface = NULL;
     cairo_t *cr;
-    const char *no_offset_str = "";
-    char *png_name, *ref_name, *diff_name, *offset_str;
+    const char *empty_str = "";
+    char *offset_str, *thread_str;
+    char *base_name, *png_name, *ref_name, *diff_name;
     cairo_test_status_t ret;
     cairo_content_t expected_content;
     cairo_font_options_t *font_options;
@@ -373,43 +374,35 @@ cairo_test_for_target (const cairo_test_context_t		 *ctx,
 
     /* Get the strings ready that we'll need. */
     format = cairo_boilerplate_content_name (target->content);
+    ref_name = cairo_ref_name_for_test_target_format (ctx,
+						      ctx->test->name,
+						      target->name,
+						      format);
+
     if (dev_offset)
 	xasprintf (&offset_str, "-%d", dev_offset);
     else
-	offset_str = (char *) no_offset_str;
+	offset_str = (char *) empty_str;
+    if (ctx->thread)
+	xasprintf (&thread_str, "-thread%d", ctx->thread);
+    else
+	thread_str = (char *) empty_str;
 
-    ref_name = cairo_ref_name_for_test_target_format (ctx, ctx->test->name, target->name, format);
-    if (ctx->thread == 0) {
-	xasprintf (&png_name, "%s-%s-%s%s%s%s",
-		   ctx->test->name,
-		   target->name,
-		   format,
-		   similar ? "-similar" : "",
-		   offset_str, CAIRO_TEST_PNG_SUFFIX);
-	xasprintf (&diff_name, "%s-%s-%s%s%s%s",
-		   ctx->test->name,
-		   target->name,
-		   format,
-		   similar ? "-similar" : "",
-		   offset_str, CAIRO_TEST_DIFF_SUFFIX);
-    } else {
-	xasprintf (&png_name, "%s-%s-%s%s%s-%d%s",
-		   ctx->test->name,
-		   target->name,
-		   format,
-		   similar ? "-similar" : "",
-		   offset_str,
-		   ctx->thread,
-		   CAIRO_TEST_PNG_SUFFIX);
-	xasprintf (&diff_name, "%s-%s-%s%s%s-%d%s",
-		   ctx->test->name,
-		   target->name,
-		   format,
-		   similar ? "-similar" : "",
-		   offset_str,
-		   ctx->thread,
-		   CAIRO_TEST_DIFF_SUFFIX);
-    }
+    xasprintf (&base_name, "%s-%s-%s%s%s%s",
+	       ctx->test->name,
+	       target->name,
+	       format,
+	       similar ? "-similar" : "",
+	       offset_str,
+	       thread_str);
+
+    if (offset_str != empty_str)
+      free (offset_str);
+    if (thread_str != empty_str)
+      free (thread_str);
+
+    xasprintf (&png_name,  "%s%s", base_name, CAIRO_TEST_PNG_SUFFIX);
+    xasprintf (&diff_name, "%s%s", base_name, CAIRO_TEST_DIFF_SUFFIX);
 
     if (target->is_vector) {
 	int i;
@@ -434,7 +427,7 @@ cairo_test_for_target (const cairo_test_context_t		 *ctx,
 
     /* Run the actual drawing code. */
     ret = CAIRO_TEST_SUCCESS;
-    surface = (target->create_surface) (ctx->test->name,
+    surface = (target->create_surface) (base_name,
 					target->content,
 					width, height,
 					ctx->test->width + 25 * NUM_DEVICE_OFFSETS,
@@ -601,8 +594,8 @@ UNWIND_STRINGS:
       free (ref_name);
     if (diff_name)
       free (diff_name);
-    if (offset_str != no_offset_str)
-      free (offset_str);
+    if (base_name)
+      free (base_name);
 
     return ret;
 }
commit 517e532fb70df7ce5f1d5d9ebf94243ede1307da
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Aug 13 11:03:52 2008 +0100

    [test] Run fallback-resolution if we have at least one vector surface.
    
    Currently fallback-resolution is included in the test suite if we have all
    of the vector surfaces available. This commit enables individual support
    for the vector surfaces, so that the test can be run even if one or more
    of the surfaces are not available.

diff --git a/test/Makefile.am b/test/Makefile.am
index 555279c..0dec0ac 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -265,13 +265,17 @@ if CAIRO_HAS_MULTI_PAGE_SURFACES
 TESTS += multi-page$(EXEEXT)
 endif
 
+# Include fallback-resolution (once!) if we have any of the vector surfaces
 if CAIRO_HAS_SVG_SURFACE
-if CAIRO_HAS_PDF_SURFACE
-if CAIRO_HAS_PS_SURFACE
-TESTS += fallback-resolution$(EXEEXT)
+test = fallback-resolution$(EXEEXT)
 endif
+if CAIRO_HAS_PDF_SURFACE
+test = fallback-resolution$(EXEEXT)
 endif
+if CAIRO_HAS_PS_SURFACE
+test = fallback-resolution$(EXEEXT)
 endif
+TESTS += $(test)
 
 # All tests which have a reference image go here.
 REFERENCE_IMAGES = \
diff --git a/test/fallback-resolution.c b/test/fallback-resolution.c
index 84ec285..7c33c1e 100644
--- a/test/fallback-resolution.c
+++ b/test/fallback-resolution.c
@@ -26,18 +26,32 @@
 #include <stdio.h>
 #include <cairo.h>
 
+#if CAIRO_HAS_PDF_SURFACE
 #include <cairo-pdf.h>
 #include <cairo-boilerplate-pdf.h>
+#endif
 
+#if CAIRO_HAS_PS_SURFACE
 #include <cairo-ps.h>
 #include <cairo-boilerplate-ps.h>
+#endif
 
+#if CAIRO_HAS_SVG_SURFACE
 #include <cairo-svg.h>
 #include <cairo-boilerplate-svg.h>
+#endif
 
 #include "cairo-test.h"
 
 /* This test exists to test cairo_surface_set_fallback_resolution
+ *
+ * <behdad> one more thing.
+ *          if you can somehow incorporate cairo_show_page stuff in the
+ *          test suite.  such that fallback-resolution can actually be
+ *          automated..
+ *          if we could get a callback on surface when that function is
+ *          called, we could do cool stuff like making other backends
+ *          draw a long strip of images, one for each page...
  */
 
 #define INCHES_TO_POINTS(in) ((in) * 72.0)
@@ -75,9 +89,8 @@ draw_with_ppi (cairo_t *cr, double width, double height, double ppi)
     cairo_restore (cr);
 }
 
-#define NUM_BACKENDS 3
 typedef enum {
-    PDF, PS, SVG
+    PDF, PS, SVG, NUM_BACKENDS
 } backend_t;
 static const char *backend_filename[NUM_BACKENDS] = {
     "fallback-resolution.pdf",
@@ -106,26 +119,35 @@ main (void)
 	/* Create backend-specific surface and force image fallbacks. */
 	switch (backend) {
 	case PDF:
+#if CAIRO_HAS_PDF_SURFACE
 	    if (cairo_test_is_target_enabled (&ctx, "pdf")) {
 		surface = cairo_pdf_surface_create (backend_filename[backend],
 						    SIZE, SIZE);
 		cairo_boilerplate_pdf_surface_force_fallbacks (surface);
 	    }
+#endif
 	    break;
 	case PS:
+#if CAIRO_HAS_PS_SURFACE
 	    if (cairo_test_is_target_enabled (&ctx, "ps")) {
 		surface = cairo_ps_surface_create (backend_filename[backend],
 						   SIZE, SIZE);
 		cairo_boilerplate_ps_surface_force_fallbacks (surface);
 	    }
+#endif
 	    break;
 	case SVG:
+#if CAIRO_HAS_SVG_SURFACE
 	    if (cairo_test_is_target_enabled (&ctx, "svg")) {
 		surface = cairo_svg_surface_create (backend_filename[backend],
 						    SIZE, SIZE);
 		cairo_boilerplate_svg_surface_force_fallbacks (surface);
 		cairo_svg_surface_restrict_to_version (surface, CAIRO_SVG_VERSION_1_2);
 	    }
+#endif
+	    break;
+
+	case NUM_BACKENDS:
 	    break;
 	}
 
commit d56ea9cc879650db0ad2e6b05e483f30f9f21566
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Aug 12 13:33:04 2008 +0100

    [test] Set CAIRO_TEST_UNTESTED to 77
    
    77 is the magic exit code used by automake to indicate a skipped test, so
    by using it we can get a slightly more informative test log.

diff --git a/test/cairo-test.c b/test/cairo-test.c
index 9d245ad..341ecab 100644
--- a/test/cairo-test.c
+++ b/test/cairo-test.c
@@ -877,14 +877,6 @@ cairo_test_expecting (const cairo_test_t *test,
      * behave slightly differently, to ensure that limiting the targets does
      * not increase the number of tests failing. */
     if (ctx.limited_targets) {
-
-	/* if all untested, success */
-	if (ret == CAIRO_TEST_UNTESTED) {
-	    printf ("None of the tested backends passed, but tested targets are manually limited.\n"
-		    "Passing the test, to not fail the suite.\n");
-	    ret = CAIRO_TEST_SUCCESS;
-	}
-
 	/* if all passed, but expecting failure, return failure to not
 	 * trigger an XPASS failure */
 	if (expectation == CAIRO_TEST_FAILURE && ret == CAIRO_TEST_SUCCESS) {
@@ -893,11 +885,6 @@ cairo_test_expecting (const cairo_test_t *test,
 		    "Intentionally failing the test, to not fail the suite.\n");
 	    ret = CAIRO_TEST_FAILURE;
 	}
-
-    } else {
-	if (ret == CAIRO_TEST_UNTESTED)
-	    ret = CAIRO_TEST_FAILURE;
-
     }
 
     cairo_test_fini (&ctx);
diff --git a/test/cairo-test.h b/test/cairo-test.h
index 4c3cbce..aff8079 100644
--- a/test/cairo-test.h
+++ b/test/cairo-test.h
@@ -62,8 +62,8 @@ typedef unsigned __int64 uint64_t;
 typedef enum cairo_test_status {
     CAIRO_TEST_SUCCESS = 0,
     CAIRO_TEST_FAILURE,
-    CAIRO_TEST_UNTESTED,
-    CAIRO_TEST_CRASHED
+    CAIRO_TEST_CRASHED,
+    CAIRO_TEST_UNTESTED = 77 /* match automake's skipped exit status */
 } cairo_test_status_t;
 
 typedef struct _cairo_test_context cairo_test_context_t;
diff --git a/test/create-for-stream.c b/test/create-for-stream.c
index 211d2c4..5cea4ab 100644
--- a/test/create-for-stream.c
+++ b/test/create-for-stream.c
@@ -236,7 +236,7 @@ int
 main (void)
 {
     cairo_test_context_t ctx;
-    cairo_test_status_t status = CAIRO_TEST_SUCCESS;
+    cairo_test_status_t status = CAIRO_TEST_UNTESTED;
     cairo_test_status_t test_status;
     const char test_name[] = "create-for-stream";
 
@@ -244,6 +244,9 @@ main (void)
 
 #if CAIRO_HAS_PS_SURFACE
     if (cairo_test_is_target_enabled (&ctx, "ps")) {
+	if (status == CAIRO_TEST_UNTESTED)
+	    status = CAIRO_TEST_SUCCESS;
+
 	test_status = test_surface (&ctx, "ps", "create-for-stream.ps",
 				    cairo_ps_surface_create,
 				    cairo_ps_surface_create_for_stream);
@@ -257,6 +260,9 @@ main (void)
 
 #if CAIRO_HAS_PDF_SURFACE
     if (cairo_test_is_target_enabled (&ctx, "pdf")) {
+	if (status == CAIRO_TEST_UNTESTED)
+	    status = CAIRO_TEST_SUCCESS;
+
 	test_status = test_surface (&ctx, "pdf", "create-for-stream.pdf",
 				    cairo_pdf_surface_create,
 				    cairo_pdf_surface_create_for_stream);
@@ -270,6 +276,9 @@ main (void)
 
 #if CAIRO_HAS_SVG_SURFACE
     if (cairo_test_is_target_enabled (&ctx, "svg")) {
+	if (status == CAIRO_TEST_UNTESTED)
+	    status = CAIRO_TEST_SUCCESS;
+
 	test_status = test_surface (&ctx, "svg", "create-for-stream.svg",
 				    cairo_svg_surface_create,
 				    cairo_svg_surface_create_for_stream);
diff --git a/test/fallback-resolution.c b/test/fallback-resolution.c
index 44b467b..84ec285 100644
--- a/test/fallback-resolution.c
+++ b/test/fallback-resolution.c
@@ -91,7 +91,7 @@ main (void)
     cairo_test_context_t ctx;
     cairo_t *cr;
     cairo_status_t status;
-    cairo_test_status_t ret = CAIRO_TEST_SUCCESS;
+    cairo_test_status_t ret = CAIRO_TEST_UNTESTED;
     double ppi[] = { 600., 300., 150., 75., 37.5 };
     backend_t backend;
     int page, num_pages;
@@ -132,6 +132,9 @@ main (void)
 	if (surface == NULL)
 	    continue;
 
+	if (ret == CAIRO_TEST_UNTESTED)
+	    ret = CAIRO_TEST_SUCCESS;
+
 	cr = cairo_create (surface);
 	cairo_set_tolerance (cr, 3.0);
 
diff --git a/test/get-xrender-format.c b/test/get-xrender-format.c
index e147282..24f9035 100644
--- a/test/get-xrender-format.c
+++ b/test/get-xrender-format.c
@@ -40,21 +40,23 @@ main (void)
     cairo_surface_t *surface;
     Pixmap pixmap;
     int screen;
+    cairo_test_status_t result;
+
+    result = CAIRO_TEST_UNTESTED;
 
     cairo_test_init (&ctx, "get-xrender-format");
-    if (! cairo_test_is_target_enabled (&ctx, "xlib")) {
-	cairo_test_fini (&ctx);
-	return CAIRO_TEST_UNTESTED;
-    }
+    if (! cairo_test_is_target_enabled (&ctx, "xlib"))
+	goto CLEANUP_TEST;
 
     dpy = XOpenDisplay (NULL);
     if (! dpy) {
-	cairo_test_log (&ctx, "Error: Cannot open display: %s.\n",
+	cairo_test_log (&ctx, "Error: Cannot open display: %s, skipping.\n",
 			XDisplayName (NULL));
-	cairo_test_fini (&ctx);
-	return CAIRO_TEST_SUCCESS;
+	goto CLEANUP_TEST;
     }
 
+    result = CAIRO_TEST_FAILURE;
+
     screen = DefaultScreen (dpy);
 
     cairo_test_log (&ctx, "Testing with image surface.\n");
@@ -64,8 +66,7 @@ main (void)
     format = cairo_xlib_surface_get_xrender_format (surface);
     if (format != NULL) {
 	cairo_test_log (&ctx, "Error: expected NULL for image surface\n");
-	cairo_test_fini (&ctx);
-	return CAIRO_TEST_FAILURE;
+	goto CLEANUP_SURFACE;
     }
 
     cairo_surface_destroy (surface);
@@ -81,8 +82,7 @@ main (void)
     format = cairo_xlib_surface_get_xrender_format (surface);
     if (format != orig_format) {
 	cairo_test_log (&ctx, "Error: did not receive the same format as XRenderFindVisualFormat\n");
-	cairo_test_fini (&ctx);
-	return CAIRO_TEST_FAILURE;
+	goto CLEANUP_PIXMAP;
     }
     cairo_surface_destroy (surface);
     XFreePixmap (dpy, pixmap);
@@ -100,7 +100,7 @@ main (void)
     format = cairo_xlib_surface_get_xrender_format (surface);
     if (format != orig_format) {
 	cairo_test_log (&ctx, "Error: did not receive the same format originally set\n");
-	return CAIRO_TEST_FAILURE;
+	goto CLEANUP_PIXMAP;
     }
 
     cairo_test_log (&ctx, "Testing without the X Render extension.\n");
@@ -110,15 +110,20 @@ main (void)
     format = cairo_xlib_surface_get_xrender_format (surface);
     if (format != NULL) {
 	cairo_test_log (&ctx, "Error: did not receive a NULL format as expected\n");
-	cairo_test_fini (&ctx);
-	return CAIRO_TEST_FAILURE;
+	goto CLEANUP_PIXMAP;
     }
 
+    result = CAIRO_TEST_SUCCESS;
+
+  CLEANUP_PIXMAP:
+    XFreePixmap (dpy, pixmap);
+  CLEANUP_SURFACE:
     cairo_surface_destroy (surface);
 
     XCloseDisplay (dpy);
 
+  CLEANUP_TEST:
     cairo_test_fini (&ctx);
 
-    return CAIRO_TEST_SUCCESS;
+    return result;
 }
diff --git a/test/multi-page.c b/test/multi-page.c
index bf33dad..4519437 100644
--- a/test/multi-page.c
+++ b/test/multi-page.c
@@ -134,14 +134,16 @@ main (void)
     cairo_surface_t *surface;
     cairo_status_t status;
     const char *filename;
-    cairo_test_status_t result = CAIRO_TEST_SUCCESS;
+    cairo_test_status_t result = CAIRO_TEST_UNTESTED;
 
     cairo_test_init (&ctx, "multi-page");
 
 #if CAIRO_HAS_PS_SURFACE
     if (cairo_test_is_target_enabled (&ctx, "ps")) {
-	filename = "multi-page.ps";
+	if (result == CAIRO_TEST_UNTESTED)
+	    result = CAIRO_TEST_SUCCESS;
 
+	filename = "multi-page.ps";
 	surface = cairo_ps_surface_create (filename,
 					   WIDTH_IN_POINTS, HEIGHT_IN_POINTS);
 	status = cairo_surface_status (surface);
@@ -161,8 +163,10 @@ main (void)
 
 #if CAIRO_HAS_PDF_SURFACE
     if (cairo_test_is_target_enabled (&ctx, "pdf")) {
-	filename = "multi-page.pdf";
+	if (result == CAIRO_TEST_UNTESTED)
+	    result = CAIRO_TEST_SUCCESS;
 
+	filename = "multi-page.pdf";
 	surface = cairo_pdf_surface_create (filename,
 					    WIDTH_IN_POINTS, HEIGHT_IN_POINTS);
 	status = cairo_surface_status (surface);
diff --git a/test/surface-source.c b/test/surface-source.c
index 61ab65e..fc26d2c 100644
--- a/test/surface-source.c
+++ b/test/surface-source.c
@@ -77,6 +77,9 @@ draw (cairo_t *cr, int width, int height)
 
     surface_size = SIZE - 30;
     surface = create_source_surface (surface_size);
+    if (surface == NULL) /* can't create the source so skip the test */
+	return CAIRO_TEST_UNTESTED;
+
     draw_pattern (surface, surface_size);
 
     cairo_set_source_surface (cr, surface, 15, 15);
@@ -93,7 +96,7 @@ main (void)
 
     surface = create_source_surface (SIZE);
     if (surface == NULL) /* can't create the source so skip the test */
-	return CAIRO_TEST_SUCCESS;
+	return CAIRO_TEST_UNTESTED;
 
     cairo_surface_destroy (surface);
 
diff --git a/test/xlib-expose-event.c b/test/xlib-expose-event.c
index 0dbddac..bf320da 100644
--- a/test/xlib-expose-event.c
+++ b/test/xlib-expose-event.c
@@ -210,13 +210,11 @@ main (void)
     cairo_surface_t *surface;
     cairo_rectangle_t region[4];
     int i, j;
-    cairo_test_status_t result = CAIRO_TEST_SUCCESS;
+    cairo_test_status_t result = CAIRO_TEST_UNTESTED;
 
     cairo_test_init (&ctx, "xlib-expose-event");
-    if (! cairo_test_is_target_enabled (&ctx, "xlib")) {
-	cairo_test_fini (&ctx);
-	return CAIRO_TEST_UNTESTED;
-    }
+    if (! cairo_test_is_target_enabled (&ctx, "xlib"))
+	goto CLEANUP_TEST;
 
     dpy = XOpenDisplay (NULL);
     if (dpy == NULL) {
@@ -274,8 +272,6 @@ main (void)
     XCloseDisplay (dpy);
 
   CLEANUP_TEST:
-    cairo_debug_reset_static_data ();
-
     cairo_test_fini (&ctx);
 
     return result;
diff --git a/test/xlib-surface.c b/test/xlib-surface.c
index 71bbeab..20c715e 100644
--- a/test/xlib-surface.c
+++ b/test/xlib-surface.c
@@ -299,26 +299,22 @@ main (void)
     cairo_bool_t use_pixmap;
     cairo_bool_t set_size;
     cairo_bool_t offscreen;
-    cairo_test_status_t status, result = CAIRO_TEST_SUCCESS;
+    cairo_test_status_t status, result = CAIRO_TEST_UNTESTED;
     int stride;
 
     cairo_test_init (&ctx, "xlib-surface");
-    if (! cairo_test_is_target_enabled (&ctx, "xlib")) {
-	cairo_test_fini (&ctx);
-	return CAIRO_TEST_UNTESTED;
-    }
+    if (! cairo_test_is_target_enabled (&ctx, "xlib"))
+	goto CLEANUP_TEST;
 
     dpy = XOpenDisplay (NULL);
     if (!dpy) {
 	cairo_test_log (&ctx, "xlib-surface: Cannot open display, skipping\n");
-	cairo_test_fini (&ctx);
-	return CAIRO_TEST_SUCCESS;
+	goto CLEANUP_TEST;
     }
 
     if (!check_visual (dpy)) {
 	cairo_test_log (&ctx, "xlib-surface: default visual is not RGB24 or BGR24, skipping\n");
-	cairo_test_fini (&ctx);
-	return CAIRO_TEST_SUCCESS;
+	goto CLEANUP_DISPLAY;
     }
 
     stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, SIZE);
@@ -335,6 +331,8 @@ main (void)
     draw_pattern (reference_surface);
     cairo_surface_destroy (reference_surface);
 
+    result = CAIRO_TEST_SUCCESS;
+
     for (set_size = 0; set_size <= 1; set_size++)
 	for (use_pixmap = 0; use_pixmap <= 1; use_pixmap++)
 	    for (offscreen = 0; offscreen <= 1; offscreen++) {
@@ -359,8 +357,10 @@ main (void)
     free (test_data);
     free (diff_data);
 
+  CLEANUP_DISPLAY:
     XCloseDisplay (dpy);
 
+  CLEANUP_TEST:
     cairo_test_fini (&ctx);
 
     return result;
commit f85a4aec1f94f8fbd8e4db770ff1f70c3286fc90
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jan 10 13:04:52 2008 +0000

    [test] Export a function to check whether a target is enabled.
    
    Allow individuals tests to check whether a test target is enabled -
    useful for those tests that circumvent cairo_test() and perform
    feature testing.

diff --git a/test/cairo-test.c b/test/cairo-test.c
index 8e70f95..9d245ad 100644
--- a/test/cairo-test.c
+++ b/test/cairo-test.c
@@ -1031,3 +1031,22 @@ cairo_test_paint_checkered (cairo_t *cr)
 
     return status;
 }
+
+cairo_bool_t
+cairo_test_is_target_enabled (const cairo_test_context_t *ctx, const char *target)
+{
+    size_t i;
+
+    for (i = 0; i < ctx->num_targets; i++) {
+	const cairo_boilerplate_target_t *t = ctx->targets_to_test[i];
+	if (strcmp (t->name, target) == 0) {
+	    /* XXX ask the target whether is it possible to run?
+	     * e.g. the xlib backend could check whether it is able to connect
+	     * to the Display.
+	     */
+	    return TRUE;
+	}
+    }
+
+    return FALSE;
+}
diff --git a/test/cairo-test.h b/test/cairo-test.h
index 09f5fd8..4c3cbce 100644
--- a/test/cairo-test.h
+++ b/test/cairo-test.h
@@ -176,6 +176,10 @@ cairo_test_paint_checkered (cairo_t *cr);
 
 #define CAIRO_TEST_DOUBLE_EQUALS(a,b)  (fabs((a)-(b)) < 0.00001)
 
+cairo_bool_t
+cairo_test_is_target_enabled (const cairo_test_context_t *ctx,
+	                      const char *target);
+
 CAIRO_END_DECLS
 
 #endif
diff --git a/test/create-for-stream.c b/test/create-for-stream.c
index 9d90cf4..211d2c4 100644
--- a/test/create-for-stream.c
+++ b/test/create-for-stream.c
@@ -243,36 +243,42 @@ main (void)
     cairo_test_init (&ctx, test_name);
 
 #if CAIRO_HAS_PS_SURFACE
-    test_status = test_surface (&ctx, "ps", "create-for-stream.ps",
-			        cairo_ps_surface_create,
-			        cairo_ps_surface_create_for_stream);
-    cairo_test_log (&ctx, "TEST: %s TARGET: %s RESULT: %s\n",
-		    test_name, "ps",
-		    test_status ? "FAIL" : "PASS");
-    if (status == CAIRO_TEST_SUCCESS)
-	status = test_status;
+    if (cairo_test_is_target_enabled (&ctx, "ps")) {
+	test_status = test_surface (&ctx, "ps", "create-for-stream.ps",
+				    cairo_ps_surface_create,
+				    cairo_ps_surface_create_for_stream);
+	cairo_test_log (&ctx, "TEST: %s TARGET: %s RESULT: %s\n",
+			test_name, "ps",
+			test_status ? "FAIL" : "PASS");
+	if (status == CAIRO_TEST_SUCCESS)
+	    status = test_status;
+    }
 #endif
 
 #if CAIRO_HAS_PDF_SURFACE
-    test_status = test_surface (&ctx, "pdf", "create-for-stream.pdf",
-			        cairo_pdf_surface_create,
-			        cairo_pdf_surface_create_for_stream);
-    cairo_test_log (&ctx, "TEST: %s TARGET: %s RESULT: %s\n",
-		    test_name, "pdf",
-		    test_status ? "FAIL" : "PASS");
-    if (status == CAIRO_TEST_SUCCESS)
-	status = test_status;
+    if (cairo_test_is_target_enabled (&ctx, "pdf")) {
+	test_status = test_surface (&ctx, "pdf", "create-for-stream.pdf",
+				    cairo_pdf_surface_create,
+				    cairo_pdf_surface_create_for_stream);
+	cairo_test_log (&ctx, "TEST: %s TARGET: %s RESULT: %s\n",
+			test_name, "pdf",
+			test_status ? "FAIL" : "PASS");
+	if (status == CAIRO_TEST_SUCCESS)
+	    status = test_status;
+    }
 #endif
 
 #if CAIRO_HAS_SVG_SURFACE
-    test_status = test_surface (&ctx, "svg", "create-for-stream.svg",
-			        cairo_svg_surface_create,
-			        cairo_svg_surface_create_for_stream);
-    cairo_test_log (&ctx, "TEST: %s TARGET: %s RESULT: %s\n",
-		    test_name, "svg",
-		    test_status ? "FAIL" : "PASS");
-    if (status == CAIRO_TEST_SUCCESS)
-	status = test_status;
+    if (cairo_test_is_target_enabled (&ctx, "svg")) {
+	test_status = test_surface (&ctx, "svg", "create-for-stream.svg",
+				    cairo_svg_surface_create,
+				    cairo_svg_surface_create_for_stream);
+	cairo_test_log (&ctx, "TEST: %s TARGET: %s RESULT: %s\n",
+			test_name, "svg",
+			test_status ? "FAIL" : "PASS");
+	if (status == CAIRO_TEST_SUCCESS)
+	    status = test_status;
+    }
 #endif
 
     cairo_test_fini (&ctx);
diff --git a/test/fallback-resolution.c b/test/fallback-resolution.c
index aa1be92..44b467b 100644
--- a/test/fallback-resolution.c
+++ b/test/fallback-resolution.c
@@ -89,7 +89,6 @@ int
 main (void)
 {
     cairo_test_context_t ctx;
-    cairo_surface_t *surface = NULL;
     cairo_t *cr;
     cairo_status_t status;
     cairo_test_status_t ret = CAIRO_TEST_SUCCESS;
@@ -102,27 +101,37 @@ main (void)
     cairo_test_init (&ctx, "fallback-resolution");
 
     for (backend=0; backend < NUM_BACKENDS; backend++) {
+	cairo_surface_t *surface = NULL;
 
 	/* Create backend-specific surface and force image fallbacks. */
 	switch (backend) {
 	case PDF:
-	    surface = cairo_pdf_surface_create (backend_filename[backend],
-						SIZE, SIZE);
-	    cairo_boilerplate_pdf_surface_force_fallbacks (surface);
+	    if (cairo_test_is_target_enabled (&ctx, "pdf")) {
+		surface = cairo_pdf_surface_create (backend_filename[backend],
+						    SIZE, SIZE);
+		cairo_boilerplate_pdf_surface_force_fallbacks (surface);
+	    }
 	    break;
 	case PS:
-	    surface = cairo_ps_surface_create (backend_filename[backend],
-					       SIZE, SIZE);
-	    cairo_boilerplate_ps_surface_force_fallbacks (surface);
+	    if (cairo_test_is_target_enabled (&ctx, "ps")) {
+		surface = cairo_ps_surface_create (backend_filename[backend],
+						   SIZE, SIZE);
+		cairo_boilerplate_ps_surface_force_fallbacks (surface);
+	    }
 	    break;
 	case SVG:
-	    surface = cairo_svg_surface_create (backend_filename[backend],
-						SIZE, SIZE);
-	    cairo_boilerplate_svg_surface_force_fallbacks (surface);
-	    cairo_svg_surface_restrict_to_version (surface, CAIRO_SVG_VERSION_1_2);
+	    if (cairo_test_is_target_enabled (&ctx, "svg")) {
+		surface = cairo_svg_surface_create (backend_filename[backend],
+						    SIZE, SIZE);
+		cairo_boilerplate_svg_surface_force_fallbacks (surface);
+		cairo_svg_surface_restrict_to_version (surface, CAIRO_SVG_VERSION_1_2);
+	    }
 	    break;
 	}
 
+	if (surface == NULL)
+	    continue;
+
 	cr = cairo_create (surface);
 	cairo_set_tolerance (cr, 3.0);
 
diff --git a/test/get-xrender-format.c b/test/get-xrender-format.c
index fbb7d0c..e147282 100644
--- a/test/get-xrender-format.c
+++ b/test/get-xrender-format.c
@@ -42,6 +42,10 @@ main (void)
     int screen;
 
     cairo_test_init (&ctx, "get-xrender-format");
+    if (! cairo_test_is_target_enabled (&ctx, "xlib")) {
+	cairo_test_fini (&ctx);
+	return CAIRO_TEST_UNTESTED;
+    }
 
     dpy = XOpenDisplay (NULL);
     if (! dpy) {
diff --git a/test/multi-page.c b/test/multi-page.c
index 4e0749a..bf33dad 100644
--- a/test/multi-page.c
+++ b/test/multi-page.c
@@ -139,41 +139,45 @@ main (void)
     cairo_test_init (&ctx, "multi-page");
 
 #if CAIRO_HAS_PS_SURFACE
-    filename = "multi-page.ps";
-
-    surface = cairo_ps_surface_create (filename,
-				       WIDTH_IN_POINTS, HEIGHT_IN_POINTS);
-    status = cairo_surface_status (surface);
-    if (status) {
-	cairo_test_log (&ctx, "Failed to create ps surface for file %s: %s\n",
-			filename, cairo_status_to_string (status));
-	result = CAIRO_TEST_FAILURE;
-    }
+    if (cairo_test_is_target_enabled (&ctx, "ps")) {
+	filename = "multi-page.ps";
+
+	surface = cairo_ps_surface_create (filename,
+					   WIDTH_IN_POINTS, HEIGHT_IN_POINTS);
+	status = cairo_surface_status (surface);
+	if (status) {
+	    cairo_test_log (&ctx, "Failed to create ps surface for file %s: %s\n",
+			    filename, cairo_status_to_string (status));
+	    result = CAIRO_TEST_FAILURE;
+	}
 
-    draw_some_pages (surface);
+	draw_some_pages (surface);
 
-    cairo_surface_destroy (surface);
+	cairo_surface_destroy (surface);
 
-    printf ("multi-page: Please check %s to ensure it looks happy.\n", filename);
+	printf ("multi-page: Please check %s to ensure it looks happy.\n", filename);
+    }
 #endif
 
 #if CAIRO_HAS_PDF_SURFACE
-    filename = "multi-page.pdf";
-
-    surface = cairo_pdf_surface_create (filename,
-					WIDTH_IN_POINTS, HEIGHT_IN_POINTS);
-    status = cairo_surface_status (surface);
-    if (status) {
-	cairo_test_log (&ctx, "Failed to create pdf surface for file %s: %s\n",
-			filename, cairo_status_to_string (status));
-	result = CAIRO_TEST_FAILURE;
-    }
+    if (cairo_test_is_target_enabled (&ctx, "pdf")) {
+	filename = "multi-page.pdf";
+
+	surface = cairo_pdf_surface_create (filename,
+					    WIDTH_IN_POINTS, HEIGHT_IN_POINTS);
+	status = cairo_surface_status (surface);
+	if (status) {
+	    cairo_test_log (&ctx, "Failed to create pdf surface for file %s: %s\n",
+			    filename, cairo_status_to_string (status));
+	    result = CAIRO_TEST_FAILURE;
+	}
 
-    draw_some_pages (surface);
+	draw_some_pages (surface);
 
-    cairo_surface_destroy (surface);
+	cairo_surface_destroy (surface);
 
-    printf ("multi-page: Please check %s to ensure it looks happy.\n", filename);
+	printf ("multi-page: Please check %s to ensure it looks happy.\n", filename);
+    }
 #endif
 
     cairo_test_fini (&ctx);
diff --git a/test/pdf-features.c b/test/pdf-features.c
index 74804cd..e861685 100644
--- a/test/pdf-features.c
+++ b/test/pdf-features.c
@@ -94,6 +94,10 @@ main (void)
     size_t i;
 
     cairo_test_init (&ctx, "pdf-features");
+    if (! cairo_test_is_target_enabled (&ctx, "pdf")) {
+	cairo_test_fini (&ctx);
+	return CAIRO_TEST_UNTESTED;
+    }
 
     filename = "pdf-features.pdf";
 
diff --git a/test/ps-features.c b/test/ps-features.c
index b3ac50d..43c3587 100644
--- a/test/ps-features.c
+++ b/test/ps-features.c
@@ -98,6 +98,10 @@ main (void)
     char dsc[255];
 
     cairo_test_init (&ctx, "ps-features");
+    if (! cairo_test_is_target_enabled (&ctx, "ps")) {
+	cairo_test_fini (&ctx);
+	return CAIRO_TEST_UNTESTED;
+    }
 
     filename = "ps-features.ps";
 
diff --git a/test/svg-clip.c b/test/svg-clip.c
index 0dfab4d..0286677 100644
--- a/test/svg-clip.c
+++ b/test/svg-clip.c
@@ -112,6 +112,10 @@ main (void)
     cairo_surface_t *surface;
 
     cairo_test_init (&ctx, "svg-clip");
+    if (! cairo_test_is_target_enabled (&ctx, "svg")) {
+	cairo_test_fini (&ctx);
+	return CAIRO_TEST_UNTESTED;
+    }
 
     surface = cairo_svg_surface_create (filename,
 					WIDTH_IN_POINTS, HEIGHT_IN_POINTS);
diff --git a/test/svg-surface.c b/test/svg-surface.c
index f6b843a..9a62633 100644
--- a/test/svg-surface.c
+++ b/test/svg-surface.c
@@ -95,6 +95,10 @@ main (void)
     cairo_surface_t *surface;
 
     cairo_test_init (&ctx, "svg-surface");
+    if (! cairo_test_is_target_enabled (&ctx, "svg")) {
+	cairo_test_fini (&ctx);
+	return CAIRO_TEST_UNTESTED;
+    }
 
     surface = cairo_svg_surface_create (filename,
 					WIDTH_IN_POINTS, HEIGHT_IN_POINTS);
diff --git a/test/xlib-expose-event.c b/test/xlib-expose-event.c
index c872047..0dbddac 100644
--- a/test/xlib-expose-event.c
+++ b/test/xlib-expose-event.c
@@ -213,6 +213,10 @@ main (void)
     cairo_test_status_t result = CAIRO_TEST_SUCCESS;
 
     cairo_test_init (&ctx, "xlib-expose-event");
+    if (! cairo_test_is_target_enabled (&ctx, "xlib")) {
+	cairo_test_fini (&ctx);
+	return CAIRO_TEST_UNTESTED;
+    }
 
     dpy = XOpenDisplay (NULL);
     if (dpy == NULL) {
diff --git a/test/xlib-surface.c b/test/xlib-surface.c
index 20c2bc9..71bbeab 100644
--- a/test/xlib-surface.c
+++ b/test/xlib-surface.c
@@ -303,6 +303,10 @@ main (void)
     int stride;
 
     cairo_test_init (&ctx, "xlib-surface");
+    if (! cairo_test_is_target_enabled (&ctx, "xlib")) {
+	cairo_test_fini (&ctx);
+	return CAIRO_TEST_UNTESTED;
+    }
 
     dpy = XOpenDisplay (NULL);
     if (!dpy) {
commit 436c0c8be28546813139f391a62303d4c1894fc3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Aug 11 21:12:45 2008 +0100

    [test] Preparatory work for running under memfault.
    
    In order to run under memfault, the framework is first extended to handle
    running concurrent tests - i.e. multi-threading. (Not that this is a
    requirement for memfault, instead it shares a common goal of storing
    per-test data).  To that end all the global data is moved into a per-test
    context and the targets are adjusted to avoid overlap on shared, global
    resources (such as output files and frame buffers). In order to preserve
    the simplicity of the standard draw routines, the context is not passed
    explicitly as a parameter to the routines, but is instead attached to the
    cairo_t via the user_data.
    
    For the masochist, to enable the tests to be run across multiple threads
    simply set the environment variable CAIRO_TEST_NUM_THREADS to the desired
    number.
    
    In the long run, we can hope the need for memfault (runtime testing of
    error paths) will be mitigated by static analysis. A promising candidate
    for this task would appear to be http://hal.cs.berkeley.edu/cil/.

diff --git a/boilerplate/cairo-boilerplate-beos-private.h b/boilerplate/cairo-boilerplate-beos-private.h
index b572353..1d800c2 100644
--- a/boilerplate/cairo-boilerplate-beos-private.h
+++ b/boilerplate/cairo-boilerplate-beos-private.h
@@ -12,7 +12,10 @@ _cairo_boilerplate_beos_create_surface (const char              *name,
 					cairo_content_t          content,
 					int                      width,
 					int                      height,
+					int                      max_width,
+					int                      max_height,
 					cairo_boilerplate_mode_t mode,
+					int                      id,
 					void                   **closure);
 
 extern void
@@ -23,7 +26,10 @@ _cairo_boilerplate_beos_create_surface_for_bitmap (const char              *name
 						   cairo_content_t          content,
 						   int                      width,
 						   int                      height,
+						   int                      max_width,
+						   int                      max_height,
 						   cairo_boilerplate_mode_t mode,
+						   int                      id,
 						   void                   **closure);
 
 extern void
diff --git a/boilerplate/cairo-boilerplate-directfb-private.h b/boilerplate/cairo-boilerplate-directfb-private.h
index c8c936d..87d1b8b 100644
--- a/boilerplate/cairo-boilerplate-directfb-private.h
+++ b/boilerplate/cairo-boilerplate-directfb-private.h
@@ -12,7 +12,10 @@ _cairo_boilerplate_directfb_create_surface (const char			 *name,
 					    cairo_content_t		  content,
 					    int				  width,
 					    int				  height,
+					    int				  max_width,
+					    int				  max_height,
 					    cairo_boilerplate_mode_t	  mode,
+					    int                           id,
 					    void			**closure);
 
 extern void
diff --git a/boilerplate/cairo-boilerplate-directfb.c b/boilerplate/cairo-boilerplate-directfb.c
index d6d616b..5a12755 100644
--- a/boilerplate/cairo-boilerplate-directfb.c
+++ b/boilerplate/cairo-boilerplate-directfb.c
@@ -43,7 +43,7 @@ static DFBInfo *init(void) {
 	DFBDisplayLayerConfig        layer_config;
 	DFBGraphicsDeviceDescription desc;
 	int err;
-	DFBInfo *info = calloc(1,sizeof(DFBInfo));
+	DFBInfo *info = xcalloc(1,sizeof(DFBInfo));
 	if( !info )
 		return NULL;
 
@@ -142,7 +142,10 @@ _cairo_boilerplate_directfb_create_surface (const char			 *name,
 					    cairo_content_t		  content,
 					    int				  width,
 					    int				  height,
+					    int				  max_width,
+					    int				  max_height,
 					    cairo_boilerplate_mode_t	  mode,
+					    int                           id,
 					    void			**closure)
 {
 
diff --git a/boilerplate/cairo-boilerplate-getopt.c b/boilerplate/cairo-boilerplate-getopt.c
index be66ac2..775d1ef 100644
--- a/boilerplate/cairo-boilerplate-getopt.c
+++ b/boilerplate/cairo-boilerplate-getopt.c
@@ -40,9 +40,6 @@
 #include "cairo-boilerplate-getopt.h"
 
 
-static const char* ID = "$Id: getopt.c,v 1.2 2003/10/26 03:10:20 vindaci Exp $";
-
-
 char* optarg = NULL;
 int optind = 0;
 int opterr = 1;
@@ -57,7 +54,7 @@ static int opt_offset = 0;             /* Index into compounded "-option" */
 static int dashdash = 0;               /* True if "--" option reached */
 static int nonopt = 0;                 /* How many nonopts we've found */
 
-static void increment_index()
+static void increment_index(void)
 {
 	/* Move onto the next option */
 	if(argv_index < argv_index2)
@@ -74,7 +71,7 @@ static void increment_index()
 * Permutes argv[] so that the argument currently being processed is moved
 * to the end.
 */
-static int permute_argv_once()
+static int permute_argv_once(void)
 {
 	/* Movability check */
 	if(argv_index + nonopt >= prev_argc) return 1;
diff --git a/boilerplate/cairo-boilerplate-glitz-private.h b/boilerplate/cairo-boilerplate-glitz-private.h
index e2b27fd..faeeb63 100644
--- a/boilerplate/cairo-boilerplate-glitz-private.h
+++ b/boilerplate/cairo-boilerplate-glitz-private.h
@@ -37,7 +37,10 @@ _cairo_boilerplate_glitz_glx_create_surface (const char			 *name,
 					     cairo_content_t		  content,
 					     int			  width,
 					     int			  height,
+					     int			  max_width,
+					     int			  max_height,
 					     cairo_boilerplate_mode_t	  mode,
+					     int                          id,
 					     void			**closure);
 
 void
@@ -50,7 +53,10 @@ _cairo_boilerplate_glitz_agl_create_surface (const char			 *name,
 					     cairo_content_t		  content,
 					     int			  width,
 					     int			  height,
+					     int			  max_width,
+					     int			  max_height,
 					     cairo_boilerplate_mode_t	  mode,
+					     int                          id,
 					     void			**closure);
 
 void
@@ -63,7 +69,10 @@ _cairo_boilerplate_glitz_wgl_create_surface (const char			 *name,
 					     cairo_content_t		  content,
 					     int			  width,
 					     int			  height,
+					     int			  max_width,
+					     int			  max_height,
 					     cairo_boilerplate_mode_t	  mode,
+					     int                          id,
 					     void			**closure);
 
 void
diff --git a/boilerplate/cairo-boilerplate-glitz.c b/boilerplate/cairo-boilerplate-glitz.c
index 9ef7115..b0d65ac 100644
--- a/boilerplate/cairo-boilerplate-glitz.c
+++ b/boilerplate/cairo-boilerplate-glitz.c
@@ -148,6 +148,7 @@ _cairo_boilerplate_glitz_glx_create_surface_internal (glitz_format_name_t		 form
     glitz_drawable_destroy (drawable);
 
     return sr;
+
  DESTROY_DRAWABLE:
     glitz_drawable_destroy (drawable);
  DESTROY_WINDOW:
@@ -162,12 +163,16 @@ _cairo_boilerplate_glitz_glx_create_surface (const char			 *name,
 					     cairo_content_t 		  content,
 					     int			  width,
 					     int			  height,
+					     int			  max_width,
+					     int			  max_height,
 					     cairo_boilerplate_mode_t	  mode,
+					     int                          id,
 					     void			**closure)
 {
     glitz_glx_target_closure_t *gxtc;
     glitz_surface_t  * glitz_surface;
-    cairo_surface_t  * surface;
+    cairo_surface_t  * surface = NULL;
+    cairo_status_t status;
 
     *closure = gxtc = xmalloc (sizeof (glitz_glx_target_closure_t));
 
@@ -204,19 +209,28 @@ _cairo_boilerplate_glitz_glx_create_surface (const char			 *name,
     }
 
     surface = cairo_glitz_surface_create (glitz_surface);
+    glitz_surface_destroy (glitz_surface);
+
+    if (cairo_surface_status (surface))
+	goto FAIL_CLOSE_DISPLAY;
 
     gxtc->base.width = width;
     gxtc->base.height = height;
     gxtc->base.content = content;
-    cairo_surface_set_user_data (surface, &glitz_closure_key,
-				 gxtc, NULL);
+    status = cairo_boilerplate_surface_set_user_data (surface,
+	                                      &glitz_closure_key, gxtc, NULL);
+    if (status == CAIRO_STATUS_SUCCESS)
+	return surface;
 
-    return surface;
+    cairo_surface_destroy (surface);
+    surface = cairo_boilerplate_surface_create_in_error (status);
 
  FAIL_CLOSE_DISPLAY:
+    glitz_glx_fini ();
     XCloseDisplay (gxtc->dpy);
  FAIL:
-    return NULL;
+    free (gxtc);
+    return surface;
 }
 
 void
@@ -298,9 +312,10 @@ _cairo_boilerplate_glitz_agl_create_surface_internal (glitz_format_name_t		 form
 
  DESTROY_DRAWABLE:
     glitz_drawable_destroy (gdraw);
+    return sr;
 
  FAIL:
-    return sr; /* will be NULL unless we create it and attach */
+    return NULL;
 }
 
 cairo_surface_t *
@@ -308,11 +323,14 @@ _cairo_boilerplate_glitz_agl_create_surface (const char			 *name,
 					     cairo_content_t 		  content,
 					     int			  width,
 					     int			  height,
+					     int			  max_width,
+					     int			  max_height,
 					     cairo_boilerplate_mode_t	  mode,
+					     int                          id,
 					     void			**closure)
 {
     glitz_surface_t *glitz_surface;
-    cairo_surface_t *surface;
+    cairo_surface_t *surface = NULL;
     glitz_agl_target_closure_t *aglc;
 
     glitz_agl_init ();
@@ -335,16 +353,25 @@ _cairo_boilerplate_glitz_agl_create_surface (const char			 *name,
 	goto FAIL;
 
     surface = cairo_glitz_surface_create (glitz_surface);
+    glitz_surface_destroy (glitz_surface);
+
+    if (cairo_surface_status (surface))
+	goto FAIL;
 
     aglc->base.width = width;
     aglc->base.height = height;
     aglc->base.content = content;
-    cairo_surface_set_user_data (surface, &glitz_closure_key, aglc, NULL);
+    status = cairo_boilerplate_surface_set_user_data (surface,
+	                                      &glitz_closure_key, aglc, NULL);
+    if (status == CAIRO_STATUS_SUCCESS)
+	return surface;
 
-    return surface;
+    cairo_surface_destroy (surface);
+    surface = cairo_boilerplate_surface_create_in_error (status);
 
  FAIL:
-    return NULL;
+    glitz_agl_fini ();
+    return surface;
 }
 
 void
@@ -428,11 +455,14 @@ _cairo_boilerplate_glitz_wgl_create_surface (const char			 *name,
 					     cairo_content_t		  content,
 					     int			  width,
 					     int			  height,
+					     int			  max_width,
+					     int			  max_height,
 					     cairo_boilerplate_mode_t	  mode,
+					     int                          id,
 					     void			**closure)
 {
     glitz_surface_t *glitz_surface;
-    cairo_surface_t *surface;
+    cairo_surface_t *surface = NULL;
     glitz_wgl_target_closure_t *wglc;
 
     glitz_wgl_init (NULL);
@@ -455,16 +485,26 @@ _cairo_boilerplate_glitz_wgl_create_surface (const char			 *name,
 	goto FAIL;
 
     surface = cairo_glitz_surface_create (glitz_surface);
+    glitz_surface_destroy (glitz_surface);
+
+    if (cairo_surface_status (surface))
+	goto FAIL;
 
     wglc->base.width = width;
     wglc->base.height = height;
     wglc->base.content = content;
-    cairo_surface_set_user_data (surface, &glitz_closure_key, wglc, NULL);
+    status = cairo_boilerplate_surface_set_user_data (surface,
+	                                      &glitz_closure_key, wglc, NULL);
+    if (status == CAIRO_STATUS_SUCCESS)
+	return surface;
 
-    return surface;
+    cairo_surface_destroy (surface);
+    surface = cairo_boilerplate_surface_create_in_error (status);
 
  FAIL:
-    return NULL;
+    glitz_wgl_fini ();
+    free (wglc);
+    return surface;
 }
 
 void
diff --git a/boilerplate/cairo-boilerplate-pdf-private.h b/boilerplate/cairo-boilerplate-pdf-private.h
index 7ce181e..a792cc4 100644
--- a/boilerplate/cairo-boilerplate-pdf-private.h
+++ b/boilerplate/cairo-boilerplate-pdf-private.h
@@ -32,7 +32,10 @@ _cairo_boilerplate_pdf_create_surface (const char		 *name,
 				       cairo_content_t		  content,
 				       int			  width,
 				       int			  height,
+				       int			  max_width,
+				       int			  max_height,
 				       cairo_boilerplate_mode_t	  mode,
+				       int                        id,
 				       void			**closure);
 
 void
diff --git a/boilerplate/cairo-boilerplate-pdf.c b/boilerplate/cairo-boilerplate-pdf.c
index cc26d91..8eedd9d 100644
--- a/boilerplate/cairo-boilerplate-pdf.c
+++ b/boilerplate/cairo-boilerplate-pdf.c
@@ -49,11 +49,15 @@ _cairo_boilerplate_pdf_create_surface (const char		 *name,
 				       cairo_content_t		  content,
 				       int			  width,
 				       int			  height,
+				       int			  max_width,
+				       int			  max_height,
 				       cairo_boilerplate_mode_t	  mode,
+				       int                        id,
 				       void			**closure)
 {
     pdf_target_closure_t *ptc;
     cairo_surface_t *surface;
+    cairo_status_t status;
 
     /* Sanitize back to a real cairo_content_t value. */
     if (content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED)
@@ -64,15 +68,13 @@ _cairo_boilerplate_pdf_create_surface (const char		 *name,
     ptc->width = width;
     ptc->height = height;
 
-    xasprintf (&ptc->filename, "%s-pdf-%s-out.pdf",
-	       name, cairo_boilerplate_content_name (content));
+    xasprintf (&ptc->filename, "%s-pdf-%s-%d-out.pdf",
+	       name, cairo_boilerplate_content_name (content), id);
 
     surface = cairo_pdf_surface_create (ptc->filename, width, height);
-    if (cairo_surface_status (surface)) {
-	free (ptc->filename);
-	free (ptc);
-	return NULL;
-    }
+    if (cairo_surface_status (surface))
+	goto CLEANUP_FILENAME;
+
     cairo_surface_set_fallback_resolution (surface, 72., 72.);
 
     if (content == CAIRO_CONTENT_COLOR) {
@@ -80,14 +82,24 @@ _cairo_boilerplate_pdf_create_surface (const char		 *name,
 	surface = cairo_surface_create_similar (ptc->target,
 						CAIRO_CONTENT_COLOR,
 						width, height);
+	if (cairo_surface_status (surface))
+	    goto CLEANUP_TARGET;
     } else {
 	ptc->target = NULL;
     }
 
-    cairo_boilerplate_surface_set_user_data (surface,
-					     &pdf_closure_key,
-					     ptc, NULL);
+    status = cairo_surface_set_user_data (surface, &pdf_closure_key, ptc, NULL);
+    if (status == CAIRO_STATUS_SUCCESS)
+	return surface;
 
+    cairo_surface_destroy (surface);
+    surface = cairo_boilerplate_surface_create_in_error (status);
+
+  CLEANUP_TARGET:
+    cairo_surface_destroy (ptc->target);
+  CLEANUP_FILENAME:
+    free (ptc->filename);
+    free (ptc);
     return surface;
 }
 
@@ -96,6 +108,7 @@ _cairo_boilerplate_pdf_surface_write_to_png (cairo_surface_t *surface, const cha
 {
     pdf_target_closure_t *ptc = cairo_surface_get_user_data (surface, &pdf_closure_key);
     char    command[4096];
+    cairo_status_t status;
 
     /* Both surface and ptc->target were originally created at the
      * same dimensions. We want a 1:1 copy here, so we first clear any
@@ -112,13 +125,25 @@ _cairo_boilerplate_pdf_surface_write_to_png (cairo_surface_t *surface, const cha
 	cairo_set_source_surface (cr, surface, 0, 0);
 	cairo_paint (cr);
 	cairo_show_page (cr);
+	status = cairo_status (cr);
 	cairo_destroy (cr);
 
+	if (status)
+	    return status;
+
 	cairo_surface_finish (surface);
+	status = cairo_surface_status (surface);
+	if (status)
+	    return status;
+
 	surface = ptc->target;
     }
 
     cairo_surface_finish (surface);
+    status = cairo_surface_status (surface);
+    if (status)
+	return status;
+
     sprintf (command, "./pdf2png %s %s 1",
 	     ptc->filename, filename);
 
diff --git a/boilerplate/cairo-boilerplate-ps-private.h b/boilerplate/cairo-boilerplate-ps-private.h
index 8d1faf1..07b15f6 100644
--- a/boilerplate/cairo-boilerplate-ps-private.h
+++ b/boilerplate/cairo-boilerplate-ps-private.h
@@ -32,7 +32,10 @@ _cairo_boilerplate_ps_create_surface (const char		 *name,
 				      cairo_content_t		  content,
 				      int			  width,
 				      int			  height,
+				      int			  max_width,
+				      int			  max_height,
 				      cairo_boilerplate_mode_t	  mode,
+				      int                         id,
 				      void			**closure);
 
 void
diff --git a/boilerplate/cairo-boilerplate-ps.c b/boilerplate/cairo-boilerplate-ps.c
index 7d5ea7d..08580cd 100644
--- a/boilerplate/cairo-boilerplate-ps.c
+++ b/boilerplate/cairo-boilerplate-ps.c
@@ -47,11 +47,15 @@ _cairo_boilerplate_ps_create_surface (const char		 *name,
 				      cairo_content_t		  content,
 				      int			  width,
 				      int			  height,
+				      int			  max_width,
+				      int			  max_height,
 				      cairo_boilerplate_mode_t	  mode,
+				      int                         id,
 				      void			**closure)
 {
     ps_target_closure_t	*ptc;
     cairo_surface_t *surface;
+    cairo_status_t status;
 
     /* Sanitize back to a real cairo_content_t value. */
     if (content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED)
@@ -59,18 +63,16 @@ _cairo_boilerplate_ps_create_surface (const char		 *name,
 
     *closure = ptc = xmalloc (sizeof (ps_target_closure_t));
 
-    xasprintf (&ptc->filename, "%s-ps-%s-out.ps",
-	       name, cairo_boilerplate_content_name (content));
+    xasprintf (&ptc->filename, "%s-ps-%s-%d-out.ps",
+	       name, cairo_boilerplate_content_name (content), id);
 
     ptc->width = width;
     ptc->height = height;
 
     surface = cairo_ps_surface_create (ptc->filename, width, height);
-    if (cairo_surface_status (surface)) {
-	free (ptc->filename);
-	free (ptc);
-	return NULL;
-    }
+    if (cairo_surface_status (surface))
+	goto CLEANUP_FILENAME;
+
     cairo_surface_set_fallback_resolution (surface, 72., 72.);
 
     if (content == CAIRO_CONTENT_COLOR) {
@@ -78,22 +80,24 @@ _cairo_boilerplate_ps_create_surface (const char		 *name,
 	surface = cairo_surface_create_similar (ptc->target,
 						CAIRO_CONTENT_COLOR,
 						width, height);
+	if (cairo_surface_status (surface))
+	    goto CLEANUP_TARGET;
     } else {
 	ptc->target = NULL;
     }
 
-    if (cairo_surface_set_user_data (surface,
-		                     &ps_closure_key,
-				     ptc,
-				     NULL) != CAIRO_STATUS_SUCCESS) {
-	cairo_surface_destroy (surface);
-	if (ptc->target != NULL)
-	    cairo_surface_destroy (ptc->target);
-	free (ptc->filename);
-	free (ptc);
-	return NULL;
-    }
+    status = cairo_surface_set_user_data (surface, &ps_closure_key, ptc, NULL);
+    if (status == CAIRO_STATUS_SUCCESS)
+	return surface;
 
+    cairo_surface_destroy (surface);
+    surface = cairo_boilerplate_surface_create_in_error (status);
+
+  CLEANUP_TARGET:
+    cairo_surface_destroy (ptc->target);
+  CLEANUP_FILENAME:
+    free (ptc->filename);
+    free (ptc);
     return surface;
 }
 
@@ -102,6 +106,7 @@ _cairo_boilerplate_ps_surface_write_to_png (cairo_surface_t *surface, const char
 {
     ps_target_closure_t *ptc = cairo_surface_get_user_data (surface, &ps_closure_key);
     char    command[4096];
+    cairo_status_t status;
 
     /* Both surface and ptc->target were originally created at the
      * same dimensions. We want a 1:1 copy here, so we first clear any
@@ -118,17 +123,30 @@ _cairo_boilerplate_ps_surface_write_to_png (cairo_surface_t *surface, const char
 	cairo_set_source_surface (cr, surface, 0, 0);
 	cairo_paint (cr);
 	cairo_show_page (cr);
+	status = cairo_status (cr);
 	cairo_destroy (cr);
 
+	if (status)
+	    return status;
+
 	cairo_surface_finish (surface);
+	status = cairo_surface_status (surface);
+	if (status)
+	    return status;
+
 	surface = ptc->target;
     }
 
     cairo_surface_finish (surface);
+    status = cairo_surface_status (surface);
+    if (status)
+	return status;
+
     sprintf (command, "gs -q -r72 -g%dx%d -dSAFER -dBATCH -dNOPAUSE -sDEVICE=pngalpha -sOutputFile=%s %s",
 	     ptc->width, ptc->height, filename, ptc->filename);
     if (system (command) == 0)
 	return CAIRO_STATUS_SUCCESS;
+
     return CAIRO_STATUS_WRITE_ERROR;
 }
 
diff --git a/boilerplate/cairo-boilerplate-quartz-private.h b/boilerplate/cairo-boilerplate-quartz-private.h
index 808342f..573e247 100644
--- a/boilerplate/cairo-boilerplate-quartz-private.h
+++ b/boilerplate/cairo-boilerplate-quartz-private.h
@@ -28,12 +28,15 @@
 #define _CAIRO_BOILERPLATE_QUARTZ_PRIVATE_H_
 
 cairo_surface_t *
-_cairo_boilerplate_quartz_create_surface (const char		*name,
-					  cairo_content_t	 content,
-					  int			 width,
-					  int			 height,
+_cairo_boilerplate_quartz_create_surface (const char		   *name,
+					  cairo_content_t	    content,
+					  int			    width,
+					  int			    height,
+					  int			    max_width,
+					  int			    max_height,
 					  cairo_boilerplate_mode_t  mode,
-					  void			**closure);
+					  int                       id,
+					  void			  **closure);
 
 void
 _cairo_boilerplate_quartz_cleanup (void *closure);
diff --git a/boilerplate/cairo-boilerplate-quartz.c b/boilerplate/cairo-boilerplate-quartz.c
index 3b23aed..3065213 100644
--- a/boilerplate/cairo-boilerplate-quartz.c
+++ b/boilerplate/cairo-boilerplate-quartz.c
@@ -34,7 +34,10 @@ _cairo_boilerplate_quartz_create_surface (const char			 *name,
 					  cairo_content_t		  content,
 					  int				  width,
 					  int				  height,
+					  int				  max_width,
+					  int				  max_height,
 					  cairo_boilerplate_mode_t	  mode,
+					  int                             id,
 					  void				**closure)
 {
     cairo_format_t format;
diff --git a/boilerplate/cairo-boilerplate-svg-private.h b/boilerplate/cairo-boilerplate-svg-private.h
index ffc56c8..4cf5f63 100644
--- a/boilerplate/cairo-boilerplate-svg-private.h
+++ b/boilerplate/cairo-boilerplate-svg-private.h
@@ -32,7 +32,10 @@ _cairo_boilerplate_svg_create_surface (const char		 *name,
 				       cairo_content_t		  content,
 				       int			  width,
 				       int			  height,
+				       int			  max_width,
+				       int			  max_height,
 				       cairo_boilerplate_mode_t	  mode,
+				       int                        id,
 				       void			**closure);
 
 void
diff --git a/boilerplate/cairo-boilerplate-svg.c b/boilerplate/cairo-boilerplate-svg.c
index b85a95e..db7e665 100644
--- a/boilerplate/cairo-boilerplate-svg.c
+++ b/boilerplate/cairo-boilerplate-svg.c
@@ -46,26 +46,28 @@ _cairo_boilerplate_svg_create_surface (const char		 *name,
 				       cairo_content_t		  content,
 				       int			  width,
 				       int			  height,
+				       int			  max_width,
+				       int			  max_height,
 				       cairo_boilerplate_mode_t	  mode,
+				       int                        id,
 				       void			**closure)
 {
     svg_target_closure_t *ptc;
     cairo_surface_t *surface;
+    cairo_status_t status;
 
     *closure = ptc = xmalloc (sizeof (svg_target_closure_t));
 
     ptc->width = width;
     ptc->height = height;
 
-    xasprintf (&ptc->filename, "%s-svg-%s-out.svg",
-	       name, cairo_boilerplate_content_name (content));
+    xasprintf (&ptc->filename, "%s-svg-%s-%d-out.svg",
+	       name, cairo_boilerplate_content_name (content), id);
 
     surface = cairo_svg_surface_create (ptc->filename, width, height);
-    if (cairo_surface_status (surface)) {
-	free (ptc->filename);
-	free (ptc);
-	return NULL;
-    }
+    if (cairo_surface_status (surface))
+	goto CLEANUP_FILENAME;
+
     cairo_surface_set_fallback_resolution (surface, 72., 72.);
 
     if (content == CAIRO_CONTENT_COLOR) {
@@ -73,14 +75,24 @@ _cairo_boilerplate_svg_create_surface (const char		 *name,
 	surface = cairo_surface_create_similar (ptc->target,
 						CAIRO_CONTENT_COLOR,
 						width, height);
+	if (cairo_surface_status (surface))
+	    goto CLEANUP_TARGET;
     } else {
 	ptc->target = NULL;
     }
 
-    cairo_boilerplate_surface_set_user_data (surface,
-					     &svg_closure_key,
-					     ptc, NULL);
+    status = cairo_surface_set_user_data (surface, &svg_closure_key, ptc, NULL);
+    if (status == CAIRO_STATUS_SUCCESS)
+	return surface;
 
+    cairo_surface_destroy (surface);
+    surface = cairo_boilerplate_surface_create_in_error (status);
+
+  CLEANUP_TARGET:
+    cairo_surface_destroy (ptc->target);
+  CLEANUP_FILENAME:
+    free (ptc->filename);
+    free (ptc);
     return surface;
 }
 
@@ -89,6 +101,7 @@ _cairo_boilerplate_svg_surface_write_to_png (cairo_surface_t *surface, const cha
 {
     svg_target_closure_t *ptc = cairo_surface_get_user_data (surface, &svg_closure_key);
     char    command[4096];
+    cairo_status_t status;
 
     /* Both surface and ptc->target were originally created at the
      * same dimensions. We want a 1:1 copy here, so we first clear any
@@ -105,13 +118,25 @@ _cairo_boilerplate_svg_surface_write_to_png (cairo_surface_t *surface, const cha
 	cairo_set_source_surface (cr, surface, 0, 0);
 	cairo_paint (cr);
 	cairo_show_page (cr);
+	status = cairo_status (cr);
 	cairo_destroy (cr);
 
+	if (status)
+	    return status;
+
 	cairo_surface_finish (surface);
+	status = cairo_surface_status (surface);
+	if (status)
+	    return status;
+
 	surface = ptc->target;
     }
 
     cairo_surface_finish (surface);
+    status = cairo_surface_status (surface);
+    if (status)
+	return status;
+
     sprintf (command, "./svg2png %s %s",
 	     ptc->filename, filename);
 
diff --git a/boilerplate/cairo-boilerplate-test-surfaces-private.h b/boilerplate/cairo-boilerplate-test-surfaces-private.h
index 1b82226..0b2bebc 100644
--- a/boilerplate/cairo-boilerplate-test-surfaces-private.h
+++ b/boilerplate/cairo-boilerplate-test-surfaces-private.h
@@ -32,7 +32,10 @@ _cairo_boilerplate_test_fallback_create_surface (const char			 *name,
 						 cairo_content_t		  content,
 						 int				  width,
 						 int				  height,
+						 int				  max_width,
+						 int				  max_height,
 						 cairo_boilerplate_mode_t	  mode,
+						 int                              id,
 						 void				**closure);
 
 
@@ -41,7 +44,10 @@ _cairo_boilerplate_test_meta_create_surface (const char			 *name,
 					     cairo_content_t		  content,
 					     int			  width,
 					     int			  height,
+					     int			  max_width,
+					     int			  max_height,
 					     cairo_boilerplate_mode_t	  mode,
+					     int                          id,
 					     void			**closure);
 
 
@@ -50,7 +56,10 @@ _cairo_boilerplate_test_paginated_create_surface (const char			 *name,
 						  cairo_content_t		  content,
 						  int				  width,
 						  int				  height,
+						  int				  max_width,
+						  int				  max_height,
 						  cairo_boilerplate_mode_t	  mode,
+						  int                             id,
 						  void				**closure);
 
 cairo_status_t
diff --git a/boilerplate/cairo-boilerplate-test-surfaces.c b/boilerplate/cairo-boilerplate-test-surfaces.c
index e112dca..f38dda9 100644
--- a/boilerplate/cairo-boilerplate-test-surfaces.c
+++ b/boilerplate/cairo-boilerplate-test-surfaces.c
@@ -38,7 +38,10 @@ _cairo_boilerplate_test_fallback_create_surface (const char			 *name,
 						 cairo_content_t		  content,
 						 int				  width,
 						 int				  height,
+						 int				  max_width,
+						 int				  max_height,
 						 cairo_boilerplate_mode_t	  mode,
+						 int                              id,
 						 void				**closure)
 {
     *closure = NULL;
@@ -50,7 +53,10 @@ _cairo_boilerplate_test_meta_create_surface (const char			 *name,
 					     cairo_content_t		  content,
 					     int			  width,
 					     int			  height,
+					     int			  max_width,
+					     int			  max_height,
 					     cairo_boilerplate_mode_t	  mode,
+					     int                          id,
 					     void			**closure)
 {
     *closure = NULL;
@@ -72,11 +78,15 @@ _cairo_boilerplate_test_paginated_create_surface (const char			 *name,
 						  cairo_content_t		  content,
 						  int				  width,
 						  int				  height,
+						  int				  max_width,
+						  int				  max_height,
 						  cairo_boilerplate_mode_t	  mode,
+						  int                             id,
 						  void				**closure)
 {
     test_paginated_closure_t *tpc;
     cairo_surface_t *surface;
+    cairo_status_t status;
 
     *closure = tpc = xmalloc (sizeof (test_paginated_closure_t));
 
@@ -92,11 +102,21 @@ _cairo_boilerplate_test_paginated_create_surface (const char			 *name,
 						       tpc->width,
 						       tpc->height,
 						       tpc->stride);
+    if (cairo_surface_status (surface))
+	goto CLEANUP;
+
+    status = cairo_surface_set_user_data (surface,
+					  &test_paginated_closure_key,
+					  tpc, NULL);
+    if (status == CAIRO_STATUS_SUCCESS)
+	return surface;
 
-    cairo_boilerplate_surface_set_user_data (surface,
-					     &test_paginated_closure_key,
-					     tpc, NULL);
+    cairo_surface_destroy (surface);
+    surface = cairo_boilerplate_surface_create_in_error (status);
 
+  CLEANUP:
+    free (tpc->data);
+    free (tpc);
     return surface;
 }
 
@@ -137,16 +157,9 @@ _cairo_boilerplate_test_paginated_surface_write_to_png (cairo_surface_t	*surface
 						 tpc->stride);
 
     status = cairo_surface_write_to_png (image, filename);
-    if (status) {
-	CAIRO_BOILERPLATE_LOG ("Error writing %s: %s. Exiting\n",
-			       filename,
-			       cairo_status_to_string (status));
-	exit (1);
-    }
-
     cairo_surface_destroy (image);
 
-    return CAIRO_STATUS_SUCCESS;
+    return status;
 }
 
 void
diff --git a/boilerplate/cairo-boilerplate-win32-private.h b/boilerplate/cairo-boilerplate-win32-private.h
index e5ef0f6..26f4b62 100644
--- a/boilerplate/cairo-boilerplate-win32-private.h
+++ b/boilerplate/cairo-boilerplate-win32-private.h
@@ -32,7 +32,10 @@ _cairo_boilerplate_win32_create_surface (const char			 *name,
 					 cairo_content_t		  content,
 					 int				  width,
 					 int				  height,
+					 int				  max_width,
+					 int				  max_height,
 					 cairo_boilerplate_mode_t	  mode,
+					 int                              id,
 					 void				**closure);
 
 cairo_surface_t *
diff --git a/boilerplate/cairo-boilerplate-win32.c b/boilerplate/cairo-boilerplate-win32.c
index cd15873..4b54a54 100644
--- a/boilerplate/cairo-boilerplate-win32.c
+++ b/boilerplate/cairo-boilerplate-win32.c
@@ -34,7 +34,10 @@ _cairo_boilerplate_win32_create_surface (const char			 *name,
 					 cairo_content_t		  content,
 					 int				  width,
 					 int				  height,
+					 int				  max_width,
+					 int				  max_height,
 					 cairo_boilerplate_mode_t	  mode,
+					 int                              id,
 					 void				**closure)
 {
     cairo_format_t format;
diff --git a/boilerplate/cairo-boilerplate-xcb-private.h b/boilerplate/cairo-boilerplate-xcb-private.h
index 80717e9..998e6b9 100644
--- a/boilerplate/cairo-boilerplate-xcb-private.h
+++ b/boilerplate/cairo-boilerplate-xcb-private.h
@@ -32,7 +32,10 @@ _cairo_boilerplate_xcb_create_surface (const char		 *name,
 				       cairo_content_t		  content,
 				       int			  width,
 				       int			  height,
+				       int			  max_width,
+				       int			  max_height,
 				       cairo_boilerplate_mode_t	  mode,
+				       int                        id,
 				       void			**closure);
 
 void
diff --git a/boilerplate/cairo-boilerplate-xcb.c b/boilerplate/cairo-boilerplate-xcb.c
index 1a74d18..dca7acf 100644
--- a/boilerplate/cairo-boilerplate-xcb.c
+++ b/boilerplate/cairo-boilerplate-xcb.c
@@ -52,12 +52,14 @@ _cairo_boilerplate_xcb_create_surface (const char		 *name,
 				       cairo_content_t		  content,
 				       int			  width,
 				       int			  height,
+				       int			  max_width,
+				       int			  max_height,
 				       cairo_boilerplate_mode_t	  mode,
+				       int                        id,
 				       void			**closure)
 {
     xcb_screen_t *root;
     xcb_target_closure_t *xtc;
-    cairo_surface_t *surface;
     xcb_connection_t *c;
     xcb_render_pictforminfo_t *render_format;
     xcb_pict_standard_t format;
@@ -97,11 +99,10 @@ _cairo_boilerplate_xcb_create_surface (const char		 *name,
     render_format = xcb_render_util_find_standard_format (xcb_render_util_query_formats (c), format);
     if (render_format->id == 0)
 	return NULL;
-    surface = cairo_xcb_surface_create_with_xrender_format (c, xtc->pixmap, root,
-							    render_format,
-							    width, height);
 
-    return surface;
+    return cairo_xcb_surface_create_with_xrender_format (c, xtc->pixmap, root,
+							 render_format,
+							 width, height);
 }
 
 void
diff --git a/boilerplate/cairo-boilerplate-xlib-private.h b/boilerplate/cairo-boilerplate-xlib-private.h
index 54c631c..0bd911d 100644
--- a/boilerplate/cairo-boilerplate-xlib-private.h
+++ b/boilerplate/cairo-boilerplate-xlib-private.h
@@ -33,7 +33,10 @@ _cairo_boilerplate_xlib_create_surface (const char		  *name,
 					cairo_content_t		   content,
 					int			   width,
 					int			   height,
+					int			   max_width,
+					int			   max_height,
 					cairo_boilerplate_mode_t   mode,
+					int                        id,
 					void			 **closure);
 #endif
 
@@ -42,7 +45,10 @@ _cairo_boilerplate_xlib_fallback_create_surface (const char			 *name,
 						 cairo_content_t		  content,
 						 int				  width,
 						 int				  height,
+						 int				  max_width,
+						 int				  max_height,
 						 cairo_boilerplate_mode_t	  mode,
+						 int				  id,
 						 void				**closure);
 
 void
diff --git a/boilerplate/cairo-boilerplate-xlib.c b/boilerplate/cairo-boilerplate-xlib.c
index 93000d0..250b23f 100644
--- a/boilerplate/cairo-boilerplate-xlib.c
+++ b/boilerplate/cairo-boilerplate-xlib.c
@@ -190,13 +190,17 @@ _cairo_boilerplate_xlib_create_surface (const char			 *name,
 					cairo_content_t			  content,
 					int				  width,
 					int				  height,
+					int				  max_width,
+					int				  max_height,
 					cairo_boilerplate_mode_t	  mode,
+					int                               id,
 					void				**closure)
 {
     xlib_target_closure_t *xtc;
     Display *dpy;
+    cairo_surface_t *surface;
 
-    *closure = xtc = xmalloc (sizeof (xlib_target_closure_t));
+    *closure = xtc = xcalloc (1, sizeof (xlib_target_closure_t));
 
     if (width == 0)
 	width = 1;
@@ -205,14 +209,20 @@ _cairo_boilerplate_xlib_create_surface (const char			 *name,
 
     xtc->dpy = dpy = XOpenDisplay (NULL);
     if (xtc->dpy == NULL) {
+	free (xtc);
 	CAIRO_BOILERPLATE_LOG ("Failed to open display: %s\n", XDisplayName(0));
 	return NULL;
     }
 
     if (mode == CAIRO_BOILERPLATE_MODE_TEST)
-	return _cairo_boilerplate_xlib_test_create_surface (dpy, content, width, height, xtc);
+	surface = _cairo_boilerplate_xlib_test_create_surface (dpy, content, width, height, xtc);
     else /* mode == CAIRO_BOILERPLATE_MODE_PERF */
-	return _cairo_boilerplate_xlib_perf_create_surface (dpy, content, width, height, xtc);
+	surface = _cairo_boilerplate_xlib_perf_create_surface (dpy, content, width, height, xtc);
+
+    if (surface == NULL || cairo_surface_status (surface))
+	_cairo_boilerplate_xlib_cleanup (xtc);
+
+    return surface;
 }
 #endif
 
@@ -230,12 +240,16 @@ _cairo_boilerplate_xlib_fallback_create_surface (const char			 *name,
 						 cairo_content_t		  content,
 						 int				  width,
 						 int				  height,
+						 int				  max_width,
+						 int				  max_height,
 						 cairo_boilerplate_mode_t	  mode,
+						 int				  id,
 						 void				**closure)
 {
     xlib_target_closure_t *xtc;
     Display *dpy;
-    int screen;
+    Screen *scr;
+    int screen, x, y;
     XSetWindowAttributes attr;
     cairo_surface_t *surface;
 
@@ -277,9 +291,25 @@ _cairo_boilerplate_xlib_fallback_create_surface (const char			 *name,
 	return NULL;
     }
 
+    /* tile the windows so threads do not overlap */
+    scr = XScreenOfDisplay (dpy, screen);
+    x = y = 0;
+    if (id-- > 1) do {
+	x += max_width;
+	if (x + max_width > WidthOfScreen (scr)) {
+	    x = 0;
+	    y += max_height;
+	    if (y + max_height > HeightOfScreen (scr)) {
+		XCloseDisplay (dpy);
+		free (xtc);
+		return NULL;
+	    }
+	}
+    } while (--id);
+
     attr.override_redirect = True;
     xtc->drawable = XCreateWindow (dpy, DefaultRootWindow (dpy),
-				   0, 0,
+				   x, y,
 				   width, height, 0,
 				   DefaultDepth (dpy, screen),
 				   InputOutput,
@@ -304,10 +334,12 @@ _cairo_boilerplate_xlib_cleanup (void *closure)
 {
     xlib_target_closure_t *xtc = closure;
 
-    if (xtc->drawable_is_pixmap)
-	XFreePixmap (xtc->dpy, xtc->drawable);
-    else
-	XDestroyWindow (xtc->dpy, xtc->drawable);
+    if (xtc->drawable) {
+	if (xtc->drawable_is_pixmap)
+	    XFreePixmap (xtc->dpy, xtc->drawable);
+	else
+	    XDestroyWindow (xtc->dpy, xtc->drawable);
+    }
     XCloseDisplay (xtc->dpy);
     free (xtc);
 }
diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c
index f563b7a..72e0930 100644
--- a/boilerplate/cairo-boilerplate.c
+++ b/boilerplate/cairo-boilerplate.c
@@ -118,10 +118,14 @@ _cairo_boilerplate_image_create_surface (const char			 *name,
 					 cairo_content_t		  content,
 					 int				  width,
 					 int				  height,
+					 int				  max_width,
+					 int				  max_height,
 					 cairo_boilerplate_mode_t	  mode,
+					 int                              id,
 					 void				**closure)
 {
     cairo_format_t format;
+
     *closure = NULL;
 
     if (content == CAIRO_CONTENT_COLOR_ALPHA) {
@@ -448,22 +452,29 @@ cairo_boilerplate_free_targets (cairo_boilerplate_target_t **targets)
     free (targets);
 }
 
-void
-cairo_boilerplate_surface_set_user_data (cairo_surface_t		*surface,
-					 const cairo_user_data_key_t	*key,
-					 void				*user_data,
-					 cairo_destroy_func_t		 destroy)
+cairo_surface_t *
+cairo_boilerplate_surface_create_in_error (cairo_status_t status)
 {
-    cairo_status_t status;
-
-    status = cairo_surface_set_user_data (surface,
-					  key, user_data,
-					  destroy);
-    if (status) {
-	CAIRO_BOILERPLATE_LOG ("Error: %s. Exiting\n",
-			       cairo_status_to_string (status));
-	exit (1);
-    }
+    cairo_surface_t *surface = NULL;
+
+    do {
+	cairo_surface_t *intermediate;
+	cairo_t *cr;
+	cairo_path_t path;
+
+	intermediate = cairo_image_surface_create (CAIRO_FORMAT_A8, 0, 0);
+	cr = cairo_create (intermediate);
+	cairo_surface_destroy (intermediate);
+
+	path.status = status;
+	cairo_append_path (cr, &path);
+
+	cairo_surface_destroy (surface);
+	surface = cairo_get_target (cr);
+	cairo_destroy (cr);
+    } while (cairo_surface_status (surface) != status);
+
+    return surface;
 }
 
 void
diff --git a/boilerplate/cairo-boilerplate.h b/boilerplate/cairo-boilerplate.h
index 8efc609..8031df8 100644
--- a/boilerplate/cairo-boilerplate.h
+++ b/boilerplate/cairo-boilerplate.h
@@ -114,7 +114,10 @@ typedef cairo_surface_t *
 				       cairo_content_t		  content,
 				       int			  width,
 				       int			  height,
+				       int			  max_width,
+				       int			  max_height,
 				       cairo_boilerplate_mode_t	  mode,
+				       int                        id,
 				       void			**closure);
 
 typedef cairo_status_t
@@ -137,7 +140,6 @@ typedef struct _cairo_boilerplate_target
     cairo_boilerplate_cleanup_t		cleanup;
     cairo_boilerplate_wait_t		synchronize;
     cairo_bool_t			is_vector;
-    void			       *closure;
 } cairo_boilerplate_target_t;
 
 cairo_boilerplate_target_t **
@@ -146,11 +148,8 @@ cairo_boilerplate_get_targets (int *num_targets, cairo_bool_t *limited_targets);
 void
 cairo_boilerplate_free_targets (cairo_boilerplate_target_t **targets);
 
-void
-cairo_boilerplate_surface_set_user_data (cairo_surface_t		*surface,
-					 const cairo_user_data_key_t	*key,
-					 void				*user_data,
-					 cairo_destroy_func_t		 destroy);
+cairo_surface_t *
+cairo_boilerplate_surface_create_in_error (cairo_status_t status);
 
 #include "xmalloc.h"
 
diff --git a/boilerplate/xmalloc.c b/boilerplate/xmalloc.c
index dfd4946..0a8eeb2 100644
--- a/boilerplate/xmalloc.c
+++ b/boilerplate/xmalloc.c
@@ -35,8 +35,11 @@ xmalloc (size_t size)
 {
     void *buf;
 
+    if (size == 0)
+	return NULL;
+
     buf = malloc (size);
-    if (buf == NULL && size != 0) {
+    if (buf == NULL) {
 	CAIRO_BOILERPLATE_LOG ("Error: Out of memory. Exiting.\n");
 	exit (1);
     }
@@ -49,8 +52,11 @@ xcalloc (size_t nmemb, size_t size)
 {
     void *buf;
 
+    if (nmemb == 0 || size == 0)
+	return NULL;
+
     buf = calloc (nmemb, size);
-    if (buf == NULL && nmemb != 0 && size != 0) {
+    if (buf == NULL) {
 	CAIRO_BOILERPLATE_LOG ("Error: Out of memory. Exiting\n");
 	exit (1);
     }
diff --git a/configure.in b/configure.in
index 73e9446..d0e8bb6 100644
--- a/configure.in
+++ b/configure.in
@@ -113,7 +113,7 @@ dnl ===========================================================================
 AC_CHECK_LIBM
 LIBS="$LIBS $LIBM"
 
-AC_CHECK_FUNCS(vasnprintf ctime_r drand48)
+AC_CHECK_FUNCS(vasnprintf ctime_r drand48 flockfile)
 
 AC_MSG_CHECKING([for Sun Solaris (non-POSIX ctime_r)])
 case "$host" in
@@ -731,7 +731,7 @@ AC_CACHE_SAVE
 
 dnl ===========================================================================
 dnl Checks for precise integer types
-AC_CHECK_HEADERS([stdint.h signal.h inttypes.h sys/int_types.h])
+AC_CHECK_HEADERS([stdint.h signal.h setjmp.h inttypes.h sys/int_types.h])
 AC_CHECK_TYPES([uint64_t, uint128_t])
 
 dnl ===========================================================================
diff --git a/perf/cairo-perf.c b/perf/cairo-perf.c
index a710f84..1e0e4ea 100644
--- a/perf/cairo-perf.c
+++ b/perf/cairo-perf.c
@@ -397,11 +397,15 @@ main (int argc, char *argv[])
 		 perf.size <= perf_case->max_size;
 		 perf.size *= 2)
 	    {
+		void *closure;
+
 		surface = (target->create_surface) (NULL,
 						    target->content,
 						    perf.size, perf.size,
+						    perf.size, perf.size,
 						    CAIRO_BOILERPLATE_MODE_PERF,
-						    &target->closure);
+						    0,
+						    &closure);
 		if (surface == NULL) {
 		    fprintf (stderr,
 			     "Error: Failed to create target surface: %s\n",
@@ -410,8 +414,7 @@ main (int argc, char *argv[])
 		    exit (1);
 		}
 
-		cairo_perf_timer_set_synchronize (target->synchronize,
-						  target->closure);
+		cairo_perf_timer_set_synchronize (target->synchronize, closure);
 
 		perf.cr = cairo_create (surface);
 
@@ -428,7 +431,7 @@ main (int argc, char *argv[])
 		cairo_surface_destroy (surface);
 
 		if (target->cleanup)
-		    target->cleanup (target->closure);
+		    target->cleanup (closure);
 	    }
 	}
     }
diff --git a/test/Makefile.am b/test/Makefile.am
index d80e8a6..555279c 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -886,11 +886,12 @@ EXTRA_PROGRAMS += $(TESTS) $(DISABLED_TESTS)
 # and TARGETS make var on the command line.  Same for the rest.
 TARGETS = $(CAIRO_TEST_TARGET)
 TARGETS_EXCLUDE = $(CAIRO_TEST_TARGET_EXCLUDE)
+NUM_THREADS = $(CAIRO_TEST_NUM_THREADS)
 
 # Same about ENV vs CAIRO_TEST_ENV.  ENV is used with "make run" only
 ENV = $(CAIRO_TEST_ENV)
 
-TESTS_ENVIRONMENT = CAIRO_XFAIL_TESTS="$(XFAIL_TESTS:$(EXEEXT)=)" CAIRO_TEST_TARGET="$(TARGETS)" CAIRO_TEST_TARGET_EXCLUDE="$(TARGETS_EXCLUDE)" $(ENV)
+TESTS_ENVIRONMENT = CAIRO_XFAIL_TESTS="$(XFAIL_TESTS:$(EXEEXT)=)" CAIRO_TEST_TARGET="$(TARGETS)" CAIRO_TEST_TARGET_EXCLUDE="$(TARGETS_EXCLUDE)" CAIRO_TEST_NUM_THREADS="$(NUM_THREADS)" $(ENV)
 
 EXTRA_VALGRIND_FLAGS = $(CAIRO_EXTRA_VALGRIND_FLAGS)
 VALGRIND_FLAGS = \
diff --git a/test/a1-image-sample.c b/test/a1-image-sample.c
index a95c577..809078c 100644
--- a/test/a1-image-sample.c
+++ b/test/a1-image-sample.c
@@ -34,7 +34,7 @@ static cairo_test_draw_function_t draw;
 #define WIDTH	(PAD + POINTS * 2 + PAD)
 #define HEIGHT	(WIDTH)
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "a1-image-sample",
     "Test sample position when drawing images with FILTER_NEAREST",
     WIDTH, HEIGHT,
diff --git a/test/a1-mask.c b/test/a1-mask.c
index 946b622..e4638fe 100644
--- a/test/a1-mask.c
+++ b/test/a1-mask.c
@@ -48,7 +48,7 @@ static unsigned char mask[(MASK_WIDTH + 7) / 8 * MASK_HEIGHT] = {
     MASK,
 };
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "a1-mask",
     "test masks of CAIRO_FORMAT_A1",
     MASK_WIDTH, MASK_HEIGHT,
@@ -57,12 +57,15 @@ cairo_test_t test = {
 
 
 static cairo_test_status_t
-check_status (cairo_status_t status, cairo_status_t expected)
+check_status (const cairo_test_context_t *ctx,
+	      cairo_status_t status,
+	      cairo_status_t expected)
 {
     if (status == expected)
 	return CAIRO_TEST_SUCCESS;
 
-    cairo_test_log ("Error: Expected status value %d (%s), received %d (%s)\n",
+    cairo_test_log (ctx,
+		    "Error: Expected status value %d (%s), received %d (%s)\n",
 		    expected,
 		    cairo_status_to_string (expected),
 		    status,
@@ -71,7 +74,8 @@ check_status (cairo_status_t status, cairo_status_t expected)
 }
 
 static cairo_test_status_t
-test_surface_with_width_and_stride (int width, int stride,
+test_surface_with_width_and_stride (const cairo_test_context_t *ctx,
+				    int width, int stride,
 				    cairo_status_t expected)
 {
     cairo_test_status_t status;
@@ -80,7 +84,8 @@ test_surface_with_width_and_stride (int width, int stride,
     int len;
     unsigned char *data;
 
-    cairo_test_log ("Creating surface with width %d and stride %d\n",
+    cairo_test_log (ctx,
+		    "Creating surface with width %d and stride %d\n",
 		    width, stride);
 
     len = stride;
@@ -94,11 +99,11 @@ test_surface_with_width_and_stride (int width, int stride,
 
     cairo_paint (cr);
 
-    status = check_status (cairo_surface_status (surface), expected);
+    status = check_status (ctx, cairo_surface_status (surface), expected);
     if (status)
 	goto BAIL;
 
-    status = check_status (cairo_status (cr), expected);
+    status = check_status (ctx, cairo_status (cr), expected);
     if (status)
 	goto BAIL;
 
@@ -146,9 +151,10 @@ draw (cairo_t *cr, int dst_width, int dst_height)
 int
 main (void)
 {
+    cairo_test_context_t ctx;
     int test_width;
 
-    cairo_test_init ("a1-mask");
+    cairo_test_init (&ctx, "a1-mask");
 
     /* first check the API strictness */
     for (test_width = 0; test_width < 40; test_width++) {
@@ -164,13 +170,15 @@ main (void)
 	expected = (stride == test_stride) ?
 	    CAIRO_STATUS_SUCCESS : CAIRO_STATUS_INVALID_STRIDE;
 
-	status = test_surface_with_width_and_stride (test_width,
+	status = test_surface_with_width_and_stride (&ctx,
+						     test_width,
 						     test_stride,
 						     expected);
 	if (status)
 	    return status;
 
-	status = test_surface_with_width_and_stride (test_width,
+	status = test_surface_with_width_and_stride (&ctx,
+						     test_width,
 						     -test_stride,
 						     expected);
 	if (status)
@@ -180,20 +188,22 @@ main (void)
 	/* Then create a surface using the correct stride,
 	 * (should always succeed).
 	 */
-	status = test_surface_with_width_and_stride (test_width,
+	status = test_surface_with_width_and_stride (&ctx,
+						     test_width,
 						     stride,
 						     CAIRO_STATUS_SUCCESS);
 	if (status)
 	    return status;
 
-	status = test_surface_with_width_and_stride (test_width,
+	status = test_surface_with_width_and_stride (&ctx,
+						     test_width,
 						     -stride,
 						     CAIRO_STATUS_SUCCESS);
 	if (status)
 	    return status;
     }
 
-    cairo_test_fini ();
+    cairo_test_fini (&ctx);
 
     return cairo_test (&test);
 }
diff --git a/test/a1-traps-sample.c b/test/a1-traps-sample.c
index 1148a8b..956d6a7 100644
--- a/test/a1-traps-sample.c
+++ b/test/a1-traps-sample.c
@@ -34,7 +34,7 @@ static cairo_test_draw_function_t draw;
 #define WIDTH	(PAD + POINTS * 2 + PAD)
 #define HEIGHT	(WIDTH)
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "a1-traps-sample",
     "Test sample position when drawing trapezoids with ANTIALIAS_NONE",
     WIDTH, HEIGHT,
diff --git a/test/a8-mask.c b/test/a8-mask.c
index fdf4fef..47f9f5b 100644
--- a/test/a8-mask.c
+++ b/test/a8-mask.c
@@ -28,7 +28,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "a8-mask",
     "test masks of CAIRO_FORMAT_A8",
     8, 8,
@@ -50,12 +50,15 @@ static unsigned char mask[MASK_WIDTH * MASK_HEIGHT] = {
 };
 
 static cairo_test_status_t
-check_status (cairo_status_t status, cairo_status_t expected)
+check_status (const cairo_test_context_t *ctx,
+	      cairo_status_t status,
+	      cairo_status_t expected)
 {
     if (status == expected)
 	return CAIRO_TEST_SUCCESS;
 
-    cairo_test_log ("Error: Expected status value %d (%s), received %d (%s)\n",
+    cairo_test_log (ctx,
+		    "Error: Expected status value %d (%s), received %d (%s)\n",
 		    expected,
 		    cairo_status_to_string (expected),
 		    status,
@@ -64,7 +67,8 @@ check_status (cairo_status_t status, cairo_status_t expected)
 }
 
 static cairo_test_status_t
-test_surface_with_width_and_stride (int width, int stride,
+test_surface_with_width_and_stride (const cairo_test_context_t *ctx,
+				    int width, int stride,
 				    cairo_status_t expected)
 {
     cairo_test_status_t status;
@@ -73,7 +77,8 @@ test_surface_with_width_and_stride (int width, int stride,
     int len;
     unsigned char *data;
 
-    cairo_test_log ("Creating surface with width %d and stride %d\n",
+    cairo_test_log (ctx,
+		    "Creating surface with width %d and stride %d\n",
 		    width, stride);
 
     len = stride;
@@ -87,11 +92,11 @@ test_surface_with_width_and_stride (int width, int stride,
 
     cairo_paint (cr);
 
-    status = check_status (cairo_surface_status (surface), expected);
+    status = check_status (ctx, cairo_surface_status (surface), expected);
     if (status)
 	goto BAIL;
 
-    status = check_status (cairo_status (cr), expected);
+    status = check_status (ctx, cairo_status (cr), expected);
     if (status)
 	goto BAIL;
 
@@ -147,9 +152,10 @@ draw (cairo_t *cr, int dst_width, int dst_height)
 int
 main (void)
 {
+    cairo_test_context_t ctx;
     int test_width;
 
-    cairo_test_init ("a8-mask");
+    cairo_test_init (&ctx, "a8-mask");
 
     for (test_width = 0; test_width < 40; test_width++) {
 	int stride = cairo_format_stride_for_width (CAIRO_FORMAT_A8,
@@ -163,13 +169,15 @@ main (void)
 	expected = (stride == test_width) ?
 	    CAIRO_STATUS_SUCCESS : CAIRO_STATUS_INVALID_STRIDE;
 
-	status = test_surface_with_width_and_stride (test_width,
+	status = test_surface_with_width_and_stride (&ctx,
+						     test_width,
 						     test_width,
 						     expected);
 	if (status)
 	    return status;
 
-	status = test_surface_with_width_and_stride (test_width,
+	status = test_surface_with_width_and_stride (&ctx,
+						     test_width,
 						     -test_width,
 						     expected);
 	if (status)
@@ -179,20 +187,22 @@ main (void)
 	/* Then create a surface using the correct stride,
 	 * (should always succeed).
 	 */
-	status = test_surface_with_width_and_stride (test_width,
+	status = test_surface_with_width_and_stride (&ctx,
+						     test_width,
 						     stride,
 						     CAIRO_STATUS_SUCCESS);
 	if (status)
 	    return status;
 
-	status = test_surface_with_width_and_stride (test_width,
+	status = test_surface_with_width_and_stride (&ctx,
+						     test_width,
 						     -stride,
 						     CAIRO_STATUS_SUCCESS);
 	if (status)
 	    return status;
     }
 
-    cairo_test_fini ();
+    cairo_test_fini (&ctx);
 
     return cairo_test (&test);
 }
diff --git a/test/big-line.c b/test/big-line.c
index cb1d84e..253be3a 100644
--- a/test/big-line.c
+++ b/test/big-line.c
@@ -27,7 +27,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "big-line",
     "Test drawing of simple lines with positive and negative coordinates > 2^16\n"
     "This currently fails because of 16-bit limitations in pixman.",
diff --git a/test/big-trap.c b/test/big-trap.c
index e201b98..400705e 100644
--- a/test/big-trap.c
+++ b/test/big-trap.c
@@ -60,7 +60,7 @@ static cairo_test_draw_function_t draw;
  * will prevent the hiding of internal library symbols.
  */
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "big-trap",
     "Test oversize trapezoid with a clip region"
     "\nTest needs to be adjusted to trigger the original bug",
diff --git a/test/bilevel-image.c b/test/bilevel-image.c
index 7898a5f..7a75edb 100644
--- a/test/bilevel-image.c
+++ b/test/bilevel-image.c
@@ -27,7 +27,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "bilevel-image",
     "Test that PS can embed an RGB image with a bilevel alpha channel.",
     12, 4,
@@ -39,7 +39,7 @@ cairo_test_t test = {
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
-    static uint32_t data[] = {
+    uint32_t data[] = {
 	RGBx, RGBx, RGBx,
 	RGBx, RGBx, RGBx,
 	RGBx, RGBx, RGBx,
diff --git a/test/bitmap-font.c b/test/bitmap-font.c
index 7bebb6c..42bf707 100644
--- a/test/bitmap-font.c
+++ b/test/bitmap-font.c
@@ -38,7 +38,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "bitmap-font",
     "Test drawing with a font consisting only of bitmaps",
     246 + 1, 2 * TEXT_SIZE,
@@ -58,14 +58,14 @@ font_extents_equal (const cairo_font_extents_t *A,
 }
 
 static cairo_test_status_t
-check_font_extents (cairo_t *cr, const char *comment)
+check_font_extents (const cairo_test_context_t *ctx, cairo_t *cr, const char *comment)
 {
     cairo_font_extents_t font_extents, ref_font_extents = {11, 2, 13, 6, 0};
 
     memset (&font_extents, 0xff, sizeof (cairo_font_extents_t));
     cairo_font_extents (cr, &font_extents);
     if (! font_extents_equal (&font_extents, &ref_font_extents)) {
-	cairo_test_log ("Error: %s: cairo_font_extents(); extents (%g, %g, %g, %g, %g)\n",
+	cairo_test_log (ctx, "Error: %s: cairo_font_extents(); extents (%g, %g, %g, %g, %g)\n",
 			comment,
 		        font_extents.ascent, font_extents.descent,
 			font_extents.height,
@@ -79,30 +79,27 @@ check_font_extents (cairo_t *cr, const char *comment)
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     FcPattern *pattern;
     cairo_font_face_t *font_face;
     cairo_font_extents_t font_extents;
     cairo_font_options_t *font_options;
     cairo_status_t status;
-    const char *srcdir = getenv ("srcdir");
     char *filename;
     int face_count;
     struct stat stat_buf;
 
-    if (! srcdir)
-	srcdir = ".";
-
-    xasprintf (&filename, "%s/%s", srcdir, FONT);
+    xasprintf (&filename, "%s/%s", ctx->srcdir, FONT);
 
     if (stat (filename, &stat_buf) || ! S_ISREG (stat_buf.st_mode)) {
-	cairo_test_log ("Error finding font: %s: file not found?\n", filename);
+	cairo_test_log (ctx, "Error finding font: %s: file not found?\n", filename);
 	return CAIRO_TEST_FAILURE;
     }
 
     pattern = FcFreeTypeQuery ((unsigned char *)filename, 0, NULL, &face_count);
     free (filename);
     if (! pattern) {
-	cairo_test_log ("FcFreeTypeQuery failed.\n");
+	cairo_test_log (ctx, "FcFreeTypeQuery failed.\n");
 	return CAIRO_TEST_FAILURE;
     }
 
@@ -110,14 +107,14 @@ draw (cairo_t *cr, int width, int height)
 
     status = cairo_font_face_status (font_face);
     if (status) {
-	cairo_test_log ("Error creating font face for %s: %s\n",
+	cairo_test_log (ctx, "Error creating font face for %s: %s\n",
 			filename,
 			cairo_status_to_string (status));
 	return CAIRO_TEST_FAILURE;
     }
 
     if (cairo_font_face_get_type (font_face) != CAIRO_FONT_TYPE_FT) {
-	cairo_test_log ("Unexpected value from cairo_font_face_get_type: %d (expected %d)\n",
+	cairo_test_log (ctx, "Unexpected value from cairo_font_face_get_type: %d (expected %d)\n",
 			cairo_font_face_get_type (font_face), CAIRO_FONT_TYPE_FT);
 	cairo_font_face_destroy (font_face);
 	return CAIRO_TEST_FAILURE;
@@ -125,7 +122,7 @@ draw (cairo_t *cr, int width, int height)
 
     cairo_set_font_face (cr, font_face);
 
-#define CHECK_FONT_EXTENTS(comment) if (check_font_extents (cr, (comment)) != CAIRO_TEST_SUCCESS) return CAIRO_TEST_FAILURE
+#define CHECK_FONT_EXTENTS(comment) if (check_font_extents (ctx, cr, (comment)) != CAIRO_TEST_SUCCESS) return CAIRO_TEST_FAILURE
 
     cairo_font_extents (cr, &font_extents);
     CHECK_FONT_EXTENTS ("default");
diff --git a/test/buffer-diff.c b/test/buffer-diff.c
index d1b5863..ef70876 100644
--- a/test/buffer-diff.c
+++ b/test/buffer-diff.c
@@ -47,12 +47,12 @@
 #define PERCEPTUAL_DIFF_THRESHOLD 25
 
 static void
-xunlink (const char *pathname)
+xunlink (const cairo_test_context_t *ctx, const char *pathname)
 {
     if (unlink (pathname) < 0 && errno != ENOENT) {
-	cairo_test_log ("  Error: Cannot remove %s: %s\n",
+	cairo_test_log (ctx, "  Error: Cannot remove %s: %s\n",
 			pathname, strerror (errno));
-	exit (1);
+	exit (CAIRO_TEST_FAILURE);
     }
 }
 
@@ -122,7 +122,8 @@ buffer_diff_core (unsigned char *_buf_a,
 }
 
 void
-compare_surfaces (cairo_surface_t	*surface_a,
+compare_surfaces (const cairo_test_context_t  *ctx,
+	          cairo_surface_t	*surface_a,
 		  cairo_surface_t	*surface_b,
 		  cairo_surface_t	*surface_diff,
 		  buffer_diff_result_t	*result)
@@ -150,14 +151,15 @@ compare_surfaces (cairo_surface_t	*surface_a,
     if (result->pixels_changed == 0)
 	return;
 
-    cairo_test_log ("%d pixels differ (with maximum difference of %d) from reference image\n",
+    cairo_test_log (ctx,
+	            "%d pixels differ (with maximum difference of %d) from reference image\n",
 		    result->pixels_changed, result->max_diff);
 
     /* Then, if there are any different pixels, we give the pdiff code
      * a crack at the images. If it decides that there are no visually
      * discernible differences in any pixels, then we accept this
      * result as good enough.
-     * 
+     *
      * Only let pdiff have a crack at the comparison if the max difference
      * is lower than a threshold, otherwise some problems could be masked.
      */
@@ -166,7 +168,8 @@ compare_surfaces (cairo_surface_t	*surface_a,
                                                     gamma, luminance, field_of_view);
         if (discernible_pixels_changed == 0) {
             result->pixels_changed = 0;
-            cairo_test_log ("But perceptual diff finds no visually discernible difference.\n"
+            cairo_test_log (ctx,
+		            "But perceptual diff finds no visually discernible difference.\n"
                             "Accepting result.\n");
         }
     }
@@ -208,7 +211,9 @@ stdio_write_func (void *closure, const unsigned char *data, unsigned int length)
  * extending from (x,y) to (width,height).
  */
 static void
-flatten_surface (cairo_surface_t **surface, int x, int y)
+flatten_surface (const cairo_test_context_t *ctx,
+	         cairo_surface_t **surface,
+		 int x, int y)
 {
     cairo_surface_t *flat;
     cairo_t *cr;
@@ -219,14 +224,17 @@ flatten_surface (cairo_surface_t **surface, int x, int y)
     cairo_surface_set_device_offset (flat, -x, -y);
 
     cr = cairo_create (flat);
+    cairo_surface_destroy (flat);
+
     cairo_set_source_rgb (cr, 1, 1, 1);
     cairo_paint (cr);
+
     cairo_set_source_surface (cr, *surface, 0, 0);
+    cairo_surface_destroy (*surface);
     cairo_paint (cr);
-    cairo_destroy (cr);
 
-    cairo_surface_destroy (*surface);
-    *surface = flat;
+    *surface = cairo_surface_reference (cairo_get_target (cr));
+    cairo_destroy (cr);
 }
 
 /* Given an image surface, create a new surface that has the same
@@ -235,7 +243,9 @@ flatten_surface (cairo_surface_t **surface, int x, int y)
  * The original surface will be destroyed.
  */
 static void
-extract_sub_surface (cairo_surface_t **surface, int x, int y)
+extract_sub_surface (const cairo_test_context_t *ctx,
+	             cairo_surface_t **surface,
+		     int x, int y)
 {
     cairo_surface_t *sub;
     cairo_t *cr;
@@ -250,13 +260,15 @@ extract_sub_surface (cairo_surface_t **surface, int x, int y)
      * time, so I'm leaving both here so I can look at both to see
      * which I like better. */
     cr = cairo_create (sub);
+    cairo_surface_destroy (sub);
+
     cairo_set_source_surface (cr, *surface, -x, -y);
+    cairo_surface_destroy (*surface);
     cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
     cairo_paint (cr);
-    cairo_destroy (cr);
 
-    cairo_surface_destroy (*surface);
-    *surface = sub;
+    *surface = cairo_surface_reference (cairo_get_target (cr));
+    cairo_destroy (cr);
 }
 
 /* Image comparison code courtesy of Richard Worth <richard at theworths.org>
@@ -275,7 +287,8 @@ extract_sub_surface (cairo_surface_t **surface, int x, int y)
  * oh well).
  */
 static cairo_status_t
-image_diff_core (const char *filename_a,
+image_diff_core (const cairo_test_context_t *ctx,
+	         const char *filename_a,
 		 const char *filename_b,
 		 const char *filename_diff,
 		 int		ax,
@@ -293,7 +306,7 @@ image_diff_core (const char *filename_a,
     surface_a = cairo_image_surface_create_from_png (filename_a);
     status = cairo_surface_status (surface_a);
     if (status) {
-	cairo_test_log ("Error: Failed to create surface from %s: %s\n",
+	cairo_test_log (ctx, "Error: Failed to create surface from %s: %s\n",
 			filename_a, cairo_status_to_string (status));
 	return status;
     }
@@ -301,28 +314,45 @@ image_diff_core (const char *filename_a,
     surface_b = cairo_image_surface_create_from_png (filename_b);
     status = cairo_surface_status (surface_b);
     if (status) {
-	cairo_test_log ("Error: Failed to create surface from %s: %s\n",
+	cairo_test_log (ctx, "Error: Failed to create surface from %s: %s\n",
 			filename_b, cairo_status_to_string (status));
 	cairo_surface_destroy (surface_a);
 	return status;
     }
 
     if (flatten) {
-	flatten_surface (&surface_a, ax, ay);
-	flatten_surface (&surface_b, bx, by);
+	flatten_surface (ctx, &surface_a, ax, ay);
+	flatten_surface (ctx, &surface_b, bx, by);
 	ax = ay = bx = by = 0;
     }
 
     if (ax || ay) {
-	extract_sub_surface (&surface_a, ax, ay);
+	extract_sub_surface (ctx, &surface_a, ax, ay);
 	ax = ay = 0;
     }
 
     if (bx || by) {
-	extract_sub_surface (&surface_b, bx, by);
+	extract_sub_surface (ctx, &surface_b, bx, by);
 	bx = by = 0;
     }
 
+    status = cairo_surface_status (surface_a);
+    if (status) {
+	cairo_test_log (ctx, "Error: Failed to extract surface from %s: %s\n",
+			filename_a, cairo_status_to_string (status));
+	cairo_surface_destroy (surface_a);
+	cairo_surface_destroy (surface_b);
+	return status;
+    }
+    status = cairo_surface_status (surface_b);
+    if (status) {
+	cairo_test_log (ctx, "Error: Failed to extract surface from %s: %s\n",
+			filename_b, cairo_status_to_string (status));
+	cairo_surface_destroy (surface_a);
+	cairo_surface_destroy (surface_b);
+	return status;
+    }
+
     width_a = cairo_image_surface_get_width (surface_a);
     height_a = cairo_image_surface_get_height (surface_a);
     stride_a = cairo_image_surface_get_stride (surface_a);
@@ -334,7 +364,7 @@ image_diff_core (const char *filename_a,
 	height_a != height_b ||
 	stride_a != stride_b)
     {
-	cairo_test_log ("Error: Image size mismatch: (%dx%d) vs. (%dx%d)\n"
+	cairo_test_log (ctx, "Error: Image size mismatch: (%dx%d) vs. (%dx%d)\n"
 			"       for %s vs. %s\n",
 			width_a, height_a,
 			width_b, height_b,
@@ -346,25 +376,49 @@ image_diff_core (const char *filename_a,
 
     surface_diff = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
 					       width_a, height_a);
+    status = cairo_surface_status (surface_diff);
+    if (status) {
+	cairo_test_log (ctx, "Error: Failed to allocate surface to hold differences\n");
+	cairo_surface_destroy (surface_a);
+	cairo_surface_destroy (surface_b);
+	return CAIRO_STATUS_NO_MEMORY;
+    }
 
-    compare_surfaces (surface_a, surface_b, surface_diff, result);
+
+    compare_surfaces (ctx, surface_a, surface_b, surface_diff, result);
 
     status = CAIRO_STATUS_SUCCESS;
     if (result->pixels_changed) {
 	FILE *png_file;
 
-	if (filename_diff)
+	if (filename_diff) {
 	    png_file = fopen (filename_diff, "wb");
-	else
+	    if (png_file == NULL) {
+		int err = errno;
+
+		cairo_surface_destroy (surface_a);
+		cairo_surface_destroy (surface_b);
+		cairo_surface_destroy (surface_diff);
+
+		switch (err) {
+		    case ENOMEM:
+			return CAIRO_STATUS_NO_MEMORY;
+		    default:
+			return CAIRO_STATUS_WRITE_ERROR;
+		}
+	    }
+	} else
 	    png_file = stdout;
 
-	status = cairo_surface_write_to_png_stream (surface_diff, stdio_write_func, png_file);
+	status = cairo_surface_write_to_png_stream (surface_diff,
+						    stdio_write_func,
+						    png_file);
 
 	if (png_file != stdout)
 	    fclose (png_file);
     } else {
 	if (filename_diff)
-	    xunlink (filename_diff);
+	    xunlink (ctx, filename_diff);
     }
 
     cairo_surface_destroy (surface_a);
@@ -375,7 +429,8 @@ image_diff_core (const char *filename_a,
 }
 
 cairo_status_t
-image_diff (const char *filename_a,
+image_diff (const cairo_test_context_t *ctx,
+	    const char *filename_a,
 	    const char *filename_b,
 	    const char *filename_diff,
 	    int		ax,
@@ -384,13 +439,15 @@ image_diff (const char *filename_a,
 	    int		by,
 	    buffer_diff_result_t *result)
 {
-    return image_diff_core (filename_a, filename_b, filename_diff,
+    return image_diff_core (ctx,
+	                    filename_a, filename_b, filename_diff,
 			    ax, ay, bx, by,
 			    result, FALSE);
 }
 
 cairo_status_t
-image_diff_flattened (const char *filename_a,
+image_diff_flattened (const cairo_test_context_t *ctx,
+	              const char *filename_a,
 		      const char *filename_b,
 		      const char *filename_diff,
 		      int	  ax,
@@ -399,7 +456,8 @@ image_diff_flattened (const char *filename_a,
 		      int	  by,
 		      buffer_diff_result_t *result)
 {
-    return image_diff_core (filename_a, filename_b, filename_diff,
+    return image_diff_core (ctx,
+	                    filename_a, filename_b, filename_diff,
 			    ax, ay, bx, by,
 			    result, TRUE);
 }
diff --git a/test/buffer-diff.h b/test/buffer-diff.h
index cd35345..61daa89 100644
--- a/test/buffer-diff.h
+++ b/test/buffer-diff.h
@@ -45,7 +45,8 @@ typedef struct _buffer_diff_result {
  * images differ.
  */
 void
-compare_surfaces (cairo_surface_t	*surface_a,
+compare_surfaces (const cairo_test_context_t  *ctx,
+	          cairo_surface_t	*surface_a,
 		  cairo_surface_t	*surface_b,
 		  cairo_surface_t	*surface_diff,
 		  buffer_diff_result_t *result);
@@ -81,7 +82,8 @@ buffer_diff_noalpha (unsigned char *buf_a,
  * images differ.
  */
 cairo_status_t
-image_diff (const char *filename_a,
+image_diff (const cairo_test_context_t *ctx,
+	    const char *filename_a,
 	    const char *filename_b,
 	    const char *filename_diff,
 	    int		ax,
@@ -92,7 +94,8 @@ image_diff (const char *filename_a,
 
 /* Like image_diff, but blending the contents of b over white first. */
 cairo_status_t
-image_diff_flattened (const char *filename_a,
+image_diff_flattened (const cairo_test_context_t *ctx,
+	              const char *filename_a,
 		      const char *filename_b,
 		      const char *filename_diff,
                       int         ax,
diff --git a/test/cairo-test.c b/test/cairo-test.c
index 4fd817f..8e70f95 100644
--- a/test/cairo-test.c
+++ b/test/cairo-test.c
@@ -31,10 +31,6 @@
 #include <stdlib.h>
 #include <stdarg.h>
 #include <ctype.h>
-#include <setjmp.h>
-#ifdef HAVE_SIGNAL_H
-#include <signal.h>
-#endif
 #if HAVE_FEENABLEEXCEPT
 #include <fenv.h>
 #endif
@@ -47,6 +43,9 @@
 #if HAVE_FCFINI
 #include <fontconfig/fontconfig.h>
 #endif
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
 
 #include "cairo-test.h"
 
@@ -66,8 +65,10 @@
 #define TRUE !FALSE
 #endif
 
+static cairo_user_data_key_t _cairo_test_context_key;
+
 static void
-xunlink (const char *pathname);
+xunlink (const cairo_test_context_t *ctx, const char *pathname);
 
 static const char *fail_face = "", *normal_face = "";
 
@@ -101,20 +102,11 @@ static const char *vector_ignored_tests[] = {
     NULL
 };
 
-/* Static data is messy, but we're coding for tests here, not a
- * general-purpose library, and it keeps the tests cleaner to avoid a
- * context object there, (though not a whole lot). */
-FILE *cairo_test_log_file = NULL;
-const char *srcdir;
-const char *refdir;
-
-/* Used to catch crashes in a test, such that we report it as such and
- * continue testing, although one crasher may already have corrupted memory in
- * an nonrecoverable fashion. */
-jmp_buf jmpbuf;
-
-void
-cairo_test_init (const char *test_name)
+static void
+_cairo_test_init (cairo_test_context_t *ctx,
+		  const cairo_test_t *test,
+		  const char *test_name,
+		  cairo_test_status_t expectation)
 {
     char *log_name;
 
@@ -122,23 +114,68 @@ cairo_test_init (const char *test_name)
     feenableexcept (FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
 #endif
 
+    ctx->test = test;
+    ctx->test_name = test_name;
+    ctx->expectation = expectation;
+
     xasprintf (&log_name, "%s%s", test_name, CAIRO_TEST_LOG_SUFFIX);
-    xunlink (log_name);
+    xunlink (NULL, log_name);
 
-    cairo_test_log_file = fopen (log_name, "a");
-    if (cairo_test_log_file == NULL) {
+    ctx->log_file = fopen (log_name, "a");
+    if (ctx->log_file == NULL) {
 	fprintf (stderr, "Error opening log file: %s\n", log_name);
-	cairo_test_log_file = stderr;
+	ctx->log_file = stderr;
     }
     free (log_name);
 
+    ctx->srcdir = getenv ("srcdir");
+    if (ctx->srcdir == NULL)
+	ctx->srcdir = ".";
+
+    ctx->refdir = getenv ("CAIRO_REF_DIR");
+
+    ctx->thread = 0;
+
+    {
+	int tmp_num_targets;
+	cairo_bool_t tmp_limited_targets;
+	ctx->targets_to_test = cairo_boilerplate_get_targets (&tmp_num_targets, &tmp_limited_targets);
+	ctx->num_targets = tmp_num_targets;
+	ctx->limited_targets = tmp_limited_targets;
+    }
+
     printf ("\nTESTING %s\n", test_name);
 }
 
 void
-cairo_test_fini (void)
+cairo_test_init (cairo_test_context_t *ctx,
+		 const char *test_name)
 {
-    fclose (cairo_test_log_file);
+    _cairo_test_init (ctx, NULL, test_name, CAIRO_TEST_SUCCESS);
+}
+
+static void
+cairo_test_init_thread (cairo_test_context_t *ctx, cairo_test_context_t *master, int thread)
+{
+    *ctx = *master;
+    ctx->thread = thread;
+}
+
+void
+cairo_test_fini (cairo_test_context_t *ctx)
+{
+    if (ctx->thread != 0)
+	return;
+
+    if (ctx->log_file == NULL)
+	return;
+
+    if (ctx->log_file != stderr)
+	fclose (ctx->log_file);
+    ctx->log_file = NULL;
+
+    cairo_boilerplate_free_targets (ctx->targets_to_test);
+
     cairo_debug_reset_static_data ();
 #if HAVE_FCFINI
     FcFini ();
@@ -146,10 +183,10 @@ cairo_test_fini (void)
 }
 
 void
-cairo_test_log (const char *fmt, ...)
+cairo_test_log (const cairo_test_context_t *ctx, const char *fmt, ...)
 {
     va_list va;
-    FILE *file = cairo_test_log_file ? cairo_test_log_file : stderr;
+    FILE *file = ctx && ctx->log_file ? ctx->log_file : stderr;
 
     va_start (va, fmt);
     vfprintf (file, fmt, va);
@@ -157,7 +194,8 @@ cairo_test_log (const char *fmt, ...)
 }
 
 void
-cairo_test_log_path (const cairo_path_t *path)
+cairo_test_log_path (const cairo_test_context_t *ctx,
+		     const cairo_path_t *path)
 {
   int i;
 
@@ -165,21 +203,25 @@ cairo_test_log_path (const cairo_path_t *path)
     cairo_path_data_t *data = &path->data[i];
     switch (data->header.type) {
     case CAIRO_PATH_MOVE_TO:
-	cairo_test_log ("    cairo_move_to (cr, %g, %g);\n",
+	cairo_test_log (ctx,
+		        "    cairo_move_to (cr, %g, %g);\n",
 			data[1].point.x, data[1].point.y);
         break;
     case CAIRO_PATH_LINE_TO:
-	cairo_test_log ("    cairo_line_to (cr, %g, %g);\n",
+	cairo_test_log (ctx,
+		        "    cairo_line_to (cr, %g, %g);\n",
 			data[1].point.x, data[1].point.y);
 	break;
     case CAIRO_PATH_CURVE_TO:
-	cairo_test_log ("    cairo_curve_to (cr, %g, %g, %g, %g, %g, %g);\n",
+	cairo_test_log (ctx,
+		        "    cairo_curve_to (cr, %g, %g, %g, %g, %g, %g);\n",
 			data[1].point.x, data[1].point.y,
 			data[2].point.x, data[2].point.y,
 			data[3].point.x, data[3].point.y);
 	break;
     case CAIRO_PATH_CLOSE_PATH:
-	cairo_test_log ("    cairo_close_path (cr);\n\n");
+	cairo_test_log (ctx,
+		        "    cairo_close_path (cr);\n\n");
 	break;
     default:
 	assert (0);
@@ -188,25 +230,26 @@ cairo_test_log_path (const cairo_path_t *path)
 }
 
 static void
-xunlink (const char *pathname)
+xunlink (const cairo_test_context_t *ctx, const char *pathname)
 {
     if (unlink (pathname) < 0 && errno != ENOENT) {
-	cairo_test_log ("Error: Cannot remove %s: %s\n",
+	cairo_test_log (ctx, "Error: Cannot remove %s: %s\n",
 			pathname, strerror (errno));
 	exit (1);
     }
 }
 
 static char *
-cairo_ref_name_for_test_target_format (const char *test_name,
+cairo_ref_name_for_test_target_format (const cairo_test_context_t *ctx,
+	                               const char *test_name,
 				       const char *target_name,
 				       const char *format)
 {
     char *ref_name = NULL;
 
     /* First look for a previous build for comparison. */
-    if (refdir) {
-	xasprintf (&ref_name, "%s/%s-%s-%s%s", refdir,
+    if (ctx->refdir != NULL) {
+	xasprintf (&ref_name, "%s/%s-%s-%s%s", ctx->refdir,
 		   test_name,
 		   target_name,
 		   format,
@@ -218,7 +261,7 @@ cairo_ref_name_for_test_target_format (const char *test_name,
     }
 
     /* Next look for a target/format-specific reference image. */
-    xasprintf (&ref_name, "%s/%s-%s-%s%s", srcdir,
+    xasprintf (&ref_name, "%s/%s-%s-%s%s", ctx->srcdir,
 	       test_name,
 	       target_name,
 	       format,
@@ -229,7 +272,7 @@ cairo_ref_name_for_test_target_format (const char *test_name,
 	goto done;
 
     /* Next, look for target-specific reference image. */
-    xasprintf (&ref_name, "%s/%s-%s%s", srcdir,
+    xasprintf (&ref_name, "%s/%s-%s%s", ctx->srcdir,
 	       test_name,
 	       target_name,
 	       CAIRO_TEST_REF_SUFFIX);
@@ -239,7 +282,7 @@ cairo_ref_name_for_test_target_format (const char *test_name,
 	goto done;
 
     /* Next, look for format-specific reference image. */
-    xasprintf (&ref_name, "%s/%s-%s%s", srcdir,
+    xasprintf (&ref_name, "%s/%s-%s%s", ctx->srcdir,
 	       test_name,
 	       format,
 	       CAIRO_TEST_REF_SUFFIX);
@@ -249,7 +292,7 @@ cairo_ref_name_for_test_target_format (const char *test_name,
 	goto done;
 
     /* Finally, look for the standard reference image. */
-    xasprintf (&ref_name, "%s/%s%s", srcdir,
+    xasprintf (&ref_name, "%s/%s%s", ctx->srcdir,
 	       test_name,
 	       CAIRO_TEST_REF_SUFFIX);
     if (access (ref_name, F_OK) != 0)
@@ -264,10 +307,14 @@ done:
 }
 
 static cairo_bool_t
-cairo_test_target_has_similar (const cairo_test_t *test, cairo_boilerplate_target_t *target)
+cairo_test_target_has_similar (const cairo_test_context_t *ctx,
+			       const cairo_boilerplate_target_t *target)
 {
     cairo_surface_t *surface;
-    cairo_bool_t has_similar = FALSE;
+    cairo_bool_t has_similar;
+    cairo_t * cr;
+    cairo_surface_t *similar;
+    void *closure;
 
     /* ignore image intermediate targets */
     if (target->expected_type == CAIRO_SURFACE_TYPE_IMAGE)
@@ -276,106 +323,140 @@ cairo_test_target_has_similar (const cairo_test_t *test, cairo_boilerplate_targe
     if (getenv ("CAIRO_TEST_IGNORE_SIMILAR"))
 	return FALSE;
 
-    surface = (target->create_surface) (test->name,
+    surface = (target->create_surface) (ctx->test->name,
 					target->content,
-					test->width,
-					test->height,
+					ctx->test->width,
+					ctx->test->height,
+					ctx->test->width + 25 * NUM_DEVICE_OFFSETS,
+					ctx->test->height + 25 * NUM_DEVICE_OFFSETS,
 					CAIRO_BOILERPLATE_MODE_TEST,
-					&target->closure);
-    if (surface != NULL) {
-	cairo_t * cr = cairo_create (surface);
-	cairo_surface_t *similar;
-	cairo_push_group_with_content (cr, cairo_boilerplate_content (target->content));
-	similar = cairo_get_group_target (cr);
-	has_similar = cairo_surface_get_type (similar) == cairo_surface_get_type (surface);
-
-	cairo_destroy (cr);
-	cairo_surface_destroy (surface);
-
-	if (target->cleanup)
-	    target->cleanup (target->closure);
-    }
+					0,
+					&closure);
+    if (surface == NULL)
+	return FALSE;
+
+    cr = cairo_create (surface);
+    cairo_push_group_with_content (cr,
+				   cairo_boilerplate_content (target->content));
+    similar = cairo_get_group_target (cr);
+
+    has_similar = cairo_surface_get_type (similar) == cairo_surface_get_type (surface);
+
+    cairo_destroy (cr);
+    cairo_surface_destroy (surface);
+
+    if (target->cleanup)
+	target->cleanup (closure);
 
     return has_similar;
 }
 
 static cairo_test_status_t
-cairo_test_for_target (cairo_test_t			 *test,
-		       cairo_boilerplate_target_t	 *target,
+cairo_test_for_target (const cairo_test_context_t		 *ctx,
+		       const cairo_boilerplate_target_t	 *target,
 		       int				  dev_offset,
 		       cairo_bool_t                       similar)
 {
     cairo_test_status_t status;
     cairo_surface_t *surface = NULL;
     cairo_t *cr;
+    const char *no_offset_str = "";
     char *png_name, *ref_name, *diff_name, *offset_str;
-    cairo_test_status_t ret = CAIRO_TEST_SUCCESS;
+    cairo_test_status_t ret;
     cairo_content_t expected_content;
     cairo_font_options_t *font_options;
     const char *format;
+    cairo_bool_t have_output = FALSE;
+    cairo_bool_t have_result = FALSE;
+    void *closure;
+    int width, height;
 
     /* Get the strings ready that we'll need. */
     format = cairo_boilerplate_content_name (target->content);
     if (dev_offset)
 	xasprintf (&offset_str, "-%d", dev_offset);
     else
-	offset_str = strdup("");
+	offset_str = (char *) no_offset_str;
 
-    xasprintf (&png_name, "%s-%s-%s%s%s%s",
-	       test->name,
-	       target->name,
-	       format,
-	       similar ? "-similar" : "",
-	       offset_str, CAIRO_TEST_PNG_SUFFIX);
-    ref_name = cairo_ref_name_for_test_target_format (test->name, target->name, format);
-    xasprintf (&diff_name, "%s-%s-%s%s%s%s",
-	       test->name,
-	       target->name,
-	       format,
-	       similar ? "-similar" : "",
-	       offset_str, CAIRO_TEST_DIFF_SUFFIX);
+    ref_name = cairo_ref_name_for_test_target_format (ctx, ctx->test->name, target->name, format);
+    if (ctx->thread == 0) {
+	xasprintf (&png_name, "%s-%s-%s%s%s%s",
+		   ctx->test->name,
+		   target->name,
+		   format,
+		   similar ? "-similar" : "",
+		   offset_str, CAIRO_TEST_PNG_SUFFIX);
+	xasprintf (&diff_name, "%s-%s-%s%s%s%s",
+		   ctx->test->name,
+		   target->name,
+		   format,
+		   similar ? "-similar" : "",
+		   offset_str, CAIRO_TEST_DIFF_SUFFIX);
+    } else {
+	xasprintf (&png_name, "%s-%s-%s%s%s-%d%s",
+		   ctx->test->name,
+		   target->name,
+		   format,
+		   similar ? "-similar" : "",
+		   offset_str,
+		   ctx->thread,
+		   CAIRO_TEST_PNG_SUFFIX);
+	xasprintf (&diff_name, "%s-%s-%s%s%s-%d%s",
+		   ctx->test->name,
+		   target->name,
+		   format,
+		   similar ? "-similar" : "",
+		   offset_str,
+		   ctx->thread,
+		   CAIRO_TEST_DIFF_SUFFIX);
+    }
 
     if (target->is_vector) {
 	int i;
 
 	for (i = 0; vector_ignored_tests[i] != NULL; i++)
-	    if (strcmp (test->name, vector_ignored_tests[i]) == 0) {
-		cairo_test_log ("Error: Skipping for vector target %s\n", target->name);
+	    if (strcmp (ctx->test->name, vector_ignored_tests[i]) == 0) {
+		cairo_test_log (ctx, "Error: Skipping for vector target %s\n", target->name);
 		ret = CAIRO_TEST_UNTESTED;
 		goto UNWIND_STRINGS;
 	    }
     }
 
-    if (ret == CAIRO_TEST_SUCCESS) {
-	/* Run the actual drawing code. */
-
-	if (test->width && test->height) {
-	    test->width += dev_offset;
-	    test->height += dev_offset;
-	}
-
-	surface = (target->create_surface) (test->name,
-					    target->content,
-					    test->width,
-					    test->height,
-					    CAIRO_BOILERPLATE_MODE_TEST,
-					    &target->closure);
-
-	if (test->width && test->height) {
-	    test->width -= dev_offset;
-	    test->height -= dev_offset;;
-	}
+    width = ctx->test->width;
+    height = ctx->test->height;
+    if (width && height) {
+	width += dev_offset;
+	height += dev_offset;
     }
 
+    have_output = FALSE;
+    have_result = FALSE;
+
+    /* Run the actual drawing code. */
+    ret = CAIRO_TEST_SUCCESS;
+    surface = (target->create_surface) (ctx->test->name,
+					target->content,
+					width, height,
+					ctx->test->width + 25 * NUM_DEVICE_OFFSETS,
+					ctx->test->height + 25 * NUM_DEVICE_OFFSETS,
+					CAIRO_BOILERPLATE_MODE_TEST,
+					ctx->thread,
+					&closure);
     if (surface == NULL) {
-	cairo_test_log ("Error: Failed to set %s target\n", target->name);
+	cairo_test_log (ctx, "Error: Failed to set %s target\n", target->name);
 	ret = CAIRO_TEST_UNTESTED;
 	goto UNWIND_STRINGS;
     }
 
+    if (cairo_surface_status (surface)) {
+	cairo_test_log (ctx, "Error: Created an error surface\n");
+	ret = CAIRO_TEST_FAILURE;
+	goto UNWIND_STRINGS;
+    }
+
     /* Check that we created a surface of the expected type. */
     if (cairo_surface_get_type (surface) != target->expected_type) {
-	cairo_test_log ("Error: Created surface is of type %d (expected %d)\n",
+	cairo_test_log (ctx, "Error: Created surface is of type %d (expected %d)\n",
 			cairo_surface_get_type (surface), target->expected_type);
 	ret = CAIRO_TEST_FAILURE;
 	goto UNWIND_SURFACE;
@@ -387,7 +468,7 @@ cairo_test_for_target (cairo_test_t			 *test,
     expected_content = cairo_boilerplate_content (target->content);
 
     if (cairo_surface_get_content (surface) != expected_content) {
-	cairo_test_log ("Error: Created surface has content %d (expected %d)\n",
+	cairo_test_log (ctx, "Error: Created surface has content %d (expected %d)\n",
 			cairo_surface_get_content (surface), expected_content);
 	ret = CAIRO_TEST_FAILURE;
 	goto UNWIND_SURFACE;
@@ -396,6 +477,11 @@ cairo_test_for_target (cairo_test_t			 *test,
     cairo_surface_set_device_offset (surface, dev_offset, dev_offset);
 
     cr = cairo_create (surface);
+    if (cairo_set_user_data (cr, &_cairo_test_context_key, (void*) ctx, NULL)) {
+	ret = CAIRO_TEST_FAILURE;
+	goto UNWIND_CAIRO;
+    }
+
     if (similar)
 	cairo_push_group_with_content (cr, expected_content);
 
@@ -416,40 +502,49 @@ cairo_test_for_target (cairo_test_t			 *test,
     cairo_font_options_destroy (font_options);
 
     cairo_save (cr);
-    status = (test->draw) (cr, test->width, test->height);
+    status = (ctx->test->draw) (cr, ctx->test->width, ctx->test->height);
     cairo_restore (cr);
 
-    /* Then, check all the different ways it could fail. */
-    if (status) {
-	cairo_test_log ("Error: Function under test failed\n");
-	ret = status;
-	goto UNWIND_CAIRO;
-    }
-
     if (similar) {
 	cairo_pop_group_to_source (cr);
 	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
 	cairo_paint (cr);
     }
 
+    /* Then, check all the different ways it could fail. */
+    if (status) {
+	cairo_test_log (ctx, "Error: Function under test failed\n");
+	ret = status;
+	goto UNWIND_CAIRO;
+    }
+
     if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) {
-	cairo_test_log ("Error: Function under test left cairo status in an error state: %s\n",
+	cairo_test_log (ctx, "Error: Function under test left cairo status in an error state: %s\n",
 			cairo_status_to_string (cairo_status (cr)));
 	ret = CAIRO_TEST_FAILURE;
 	goto UNWIND_CAIRO;
     }
 
     /* Skip image check for tests with no image (width,height == 0,0) */
-    if (test->width != 0 && test->height != 0) {
+    if (ctx->test->width != 0 && ctx->test->height != 0) {
 	buffer_diff_result_t result;
 	cairo_status_t diff_status;
-	xunlink (png_name);
-	(target->write_to_png) (surface, png_name);
 
-	cairo_test_log ("OUTPUT: %s\n", png_name);
+	xunlink (ctx, png_name);
+
+	diff_status = (target->write_to_png) (surface, png_name);
+	if (diff_status) {
+	    cairo_test_log (ctx, "Error: Failed to compare images: %s\n",
+			    cairo_status_to_string (diff_status));
+	    ret = CAIRO_TEST_FAILURE;
+	    goto UNWIND_CAIRO;
+	}
+	have_output = TRUE;
+
 	if (!ref_name) {
-	    cairo_test_log ("Error: Cannot find reference image for %s/%s-%s-%s%s\n",srcdir,
-			    test->name,
+	    cairo_test_log (ctx, "Error: Cannot find reference image for %s/%s-%s-%s%s\n",
+		            ctx->srcdir,
+			    ctx->test->name,
 			    target->name,
 			    format,
 			    CAIRO_TEST_REF_SUFFIX);
@@ -457,22 +552,23 @@ cairo_test_for_target (cairo_test_t			 *test,
 	    goto UNWIND_CAIRO;
 	}
 
-	cairo_test_log ("REFERENCE: %s\n", ref_name);
-	cairo_test_log ("DIFFERENCE: %s\n", diff_name);
-
 	if (target->content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED) {
-	    diff_status= image_diff_flattened (png_name, ref_name, diff_name,
+	    diff_status = image_diff_flattened (ctx,
+		                               png_name, ref_name, diff_name,
 					       dev_offset, dev_offset, 0, 0, &result);
 	} else {
-	    diff_status = image_diff (png_name, ref_name, diff_name,
+	    diff_status = image_diff (ctx,
+		                      png_name, ref_name, diff_name,
 				      dev_offset, dev_offset, 0, 0, &result);
 	}
 	if (diff_status) {
-	    cairo_test_log ("Error: Failed to compare images: %s\n",
+	    cairo_test_log (ctx, "Error: Failed to compare images: %s\n",
 			    cairo_status_to_string (diff_status));
 	    ret = CAIRO_TEST_FAILURE;
 	    goto UNWIND_CAIRO;
 	}
+
+	have_result = TRUE;
 	if (result.pixels_changed && result.max_diff > target->error_tolerance) {
 	    ret = CAIRO_TEST_FAILURE;
 	    goto UNWIND_CAIRO;
@@ -484,10 +580,19 @@ UNWIND_CAIRO:
 UNWIND_SURFACE:
     cairo_surface_destroy (surface);
 
-    cairo_debug_reset_static_data ();
-
     if (target->cleanup)
-	target->cleanup (target->closure);
+	target->cleanup (closure);
+
+    if (ctx->thread == 0) {
+	if (have_output)
+	    cairo_test_log (ctx, "OUTPUT: %s\n", png_name);
+
+	if (have_result) {
+	    cairo_test_log (ctx,
+		            "REFERENCE: %s\nDIFFERENCE: %s\n",
+			    ref_name, diff_name);
+	}
+    }
 
 UNWIND_STRINGS:
     if (png_name)
@@ -496,13 +601,20 @@ UNWIND_STRINGS:
       free (ref_name);
     if (diff_name)
       free (diff_name);
-    if (offset_str)
+    if (offset_str != no_offset_str)
       free (offset_str);
 
     return ret;
 }
 
-#ifdef HAVE_SIGNAL_H
+#if defined(HAVE_SIGNAL_H) && defined(HAVE_SETJMP_H)
+#include <signal.h>
+#include <setjmp.h>
+/* Used to catch crashes in a test, so that we report it as such and
+ * continue testing, although one crasher may already have corrupted memory in
+ * an nonrecoverable fashion. */
+static jmp_buf jmpbuf;
+
 static void
 segfault_handler (int signal)
 {
@@ -511,21 +623,16 @@ segfault_handler (int signal)
 #endif
 
 static cairo_test_status_t
-cairo_test_expecting (cairo_test_t *test,
-		      cairo_test_status_t expectation)
+cairo_test_run (cairo_test_context_t *ctx)
 {
     /* we use volatile here to make sure values are not clobbered
      * by longjmp */
-    volatile size_t i, j, num_targets, similar, has_similar;
-    volatile cairo_bool_t limited_targets = FALSE, print_fail_on_stdout = TRUE;
-#ifdef HAVE_SIGNAL_H
-    void (*old_segfault_handler)(int);
-#endif
+    volatile size_t i, j;
+    volatile cairo_bool_t print_fail_on_stdout = ctx->thread == 0;
     volatile cairo_test_status_t status, ret;
-    cairo_boilerplate_target_t ** volatile targets_to_test;
 
 #ifdef HAVE_UNISTD_H
-    if (isatty (2)) {
+    if (ctx->thread == 0 && isatty (2)) {
 	fail_face = "\033[41m\033[37m\033[1m";
 	normal_face = "\033[m";
 	if (isatty (1))
@@ -533,25 +640,6 @@ cairo_test_expecting (cairo_test_t *test,
     }
 #endif
 
-    srcdir = getenv ("srcdir");
-    if (!srcdir)
-	srcdir = ".";
-    refdir = getenv ("CAIRO_REF_DIR");
-
-    cairo_test_init (test->name);
-    printf ("%s\n", test->description);
-
-    if (expectation == CAIRO_TEST_FAILURE)
-    printf ("Expecting failure\n");
-
-    {
-	int tmp_num_targets;
-	cairo_bool_t tmp_limited_targets;
-	targets_to_test = cairo_boilerplate_get_targets (&tmp_num_targets, &tmp_limited_targets);
-	num_targets = tmp_num_targets;
-	limited_targets = tmp_limited_targets;
-    }
-
     /* The intended logic here is that we return overall SUCCESS
      * iff. there is at least one tested backend and that all tested
      * backends return SUCCESS, OR, there's backends were manually
@@ -570,90 +658,217 @@ cairo_test_expecting (cairo_test_t *test,
      * Also, on a crash, run no further tests.
      */
     status = ret = CAIRO_TEST_UNTESTED;
-    for (i = 0; i < num_targets; i++) {
+    for (i = 0; i < ctx->num_targets && status != CAIRO_TEST_CRASHED; i++) {
+	const cairo_boilerplate_target_t * volatile target = ctx->targets_to_test[(i + ctx->thread) % ctx->num_targets];
+
 	for (j = 0; j < NUM_DEVICE_OFFSETS; j++) {
-	    cairo_boilerplate_target_t * volatile target = targets_to_test[i];
-	    volatile int dev_offset = j * 25;
-	    has_similar = cairo_test_target_has_similar (test, target);
+	    volatile int dev_offset = ((j + ctx->thread) % NUM_DEVICE_OFFSETS) * 25;
+	    volatile int similar, has_similar;
+
+	    has_similar = cairo_test_target_has_similar (ctx, target);
 	    for (similar = 0; similar <= has_similar ; similar++) {
-		cairo_test_log ("Testing %s with %s%s target (dev offset %d)\n", test->name, similar ? " (similar)" : "", target->name, dev_offset);
-		printf ("%s-%s-%s [%d]%s:\t", test->name, target->name,
-			cairo_boilerplate_content_name (target->content),
-			dev_offset,
-			similar ? " (similar)": "");
-
-#ifdef HAVE_SIGNAL_H
-		/* Set up a checkpoint to get back to in case of segfaults. */
-		old_segfault_handler = signal (SIGSEGV, segfault_handler);
-		if (0 == setjmp (jmpbuf))
+		cairo_test_log (ctx, "Testing %s with %s%s target (dev offset %d)\n", ctx->test_name, similar ? " (similar)" : "", target->name, dev_offset);
+		if (ctx->thread == 0) {
+		    printf ("%s-%s-%s [%d]%s:\t", ctx->test->name, target->name,
+			    cairo_boilerplate_content_name (target->content),
+			    dev_offset,
+			    similar ? " (similar)": "");
+		    fflush (stdout);
+		}
+
+#if defined(HAVE_SIGNAL_H) && defined(HAVE_SETJMP_H)
+		if (ctx->thread == 0) {
+		    void (* volatile old_segfault_handler)(int);
+		    void (* volatile old_sigpipe_handler)(int);
+
+		    /* Set up a checkpoint to get back to in case of segfaults. */
+#ifdef SIGSEGV
+		    old_segfault_handler = signal (SIGSEGV, segfault_handler);
+#endif
+#ifdef SIGPIPE
+		    old_sigpipe_handler = signal (SIGPIPE, segfault_handler);
+#endif
+		    if (0 == setjmp (jmpbuf))
+			status = cairo_test_for_target (ctx, target, dev_offset, similar);
+		    else
+			status = CAIRO_TEST_CRASHED;
+#ifdef SIGSEGV
+		    signal (SIGSEGV, old_segfault_handler);
 #endif
-		    status = cairo_test_for_target (test, target, dev_offset, similar);
-#ifdef HAVE_SIGNAL_H
-		else
-		    status = CAIRO_TEST_CRASHED;
-		signal (SIGSEGV, old_segfault_handler);
+#ifdef SIGPIPE
+		    signal (SIGPIPE, old_sigpipe_handler);
+#endif
+		} else {
+		    status = cairo_test_for_target (ctx, target, dev_offset, similar);
+		}
+#else
+		status = cairo_test_for_target (ctx, target, dev_offset, similar);
 #endif
 
-		cairo_test_log ("TEST: %s TARGET: %s FORMAT: %s OFFSET: %d SIMILAR: %d RESULT: ",
-				test->name, target->name,
-				cairo_boilerplate_content_name (target->content),
-				dev_offset, similar);
-
-		switch (status) {
-		case CAIRO_TEST_SUCCESS:
-		    printf ("PASS\n");
-		    cairo_test_log ("PASS\n");
-		    if (ret == CAIRO_TEST_UNTESTED)
-			ret = CAIRO_TEST_SUCCESS;
-		    break;
-		case CAIRO_TEST_UNTESTED:
-		    printf ("UNTESTED\n");
-		    cairo_test_log ("UNTESTED\n");
-		    break;
-		case CAIRO_TEST_CRASHED:
-		    if (print_fail_on_stdout) {
-			printf ("!!!CRASHED!!!\n");
-		    } else {
+		if (ctx->thread == 0) {
+		    cairo_test_log (ctx,
+			    "TEST: %s TARGET: %s FORMAT: %s OFFSET: %d SIMILAR: %d RESULT: ",
+				    ctx->test->name, target->name,
+				    cairo_boilerplate_content_name (target->content),
+				    dev_offset, similar);
+		    switch (status) {
+		    case CAIRO_TEST_SUCCESS:
+			printf ("PASS\n");
+			cairo_test_log (ctx, "PASS\n");
+			if (ret == CAIRO_TEST_UNTESTED)
+			    ret = CAIRO_TEST_SUCCESS;
+			break;
+		    case CAIRO_TEST_UNTESTED:
+			printf ("UNTESTED\n");
+			cairo_test_log (ctx, "UNTESTED\n");
+			break;
+		    case CAIRO_TEST_CRASHED:
+			if (print_fail_on_stdout) {
+			    printf ("!!!CRASHED!!!\n");
+			} else {
 			/* eat the test name */
 			printf ("\r");
 			fflush (stdout);
-		    }
-		    cairo_test_log ("CRASHED\n");
-		    fprintf (stderr, "%s-%s-%s [%d]%s:\t%s!!!CRASHED!!!%s\n",
-			     test->name, target->name,
-			     cairo_boilerplate_content_name (target->content), dev_offset, similar ? " (similar)" : "",
-			     fail_face, normal_face);
-		    ret = CAIRO_TEST_FAILURE;
-		    break;
-		default:
-		case CAIRO_TEST_FAILURE:
-		    if (expectation == CAIRO_TEST_FAILURE) {
-			printf ("XFAIL\n");
-			cairo_test_log ("XFAIL\n");
-		    } else {
-			if (print_fail_on_stdout) {
-			    printf ("FAIL\n");
-			} else {
-			    /* eat the test name */
-			    printf ("\r");
-			    fflush (stdout);
 			}
-			fprintf (stderr, "%s-%s-%s [%d]%s:\t%sFAIL%s\n",
-				 test->name, target->name,
+			cairo_test_log (ctx, "CRASHED\n");
+			fprintf (stderr, "%s-%s-%s [%d]%s:\t%s!!!CRASHED!!!%s\n",
+				 ctx->test->name, target->name,
 				 cairo_boilerplate_content_name (target->content), dev_offset, similar ? " (similar)" : "",
 				 fail_face, normal_face);
-			cairo_test_log ("FAIL\n");
+			ret = CAIRO_TEST_FAILURE;
+			break;
+		    default:
+		    case CAIRO_TEST_FAILURE:
+			if (ctx->expectation == CAIRO_TEST_FAILURE) {
+			    printf ("XFAIL\n");
+			    cairo_test_log (ctx, "XFAIL\n");
+			} else {
+			    if (print_fail_on_stdout) {
+				printf ("FAIL\n");
+			    } else {
+				/* eat the test name */
+				printf ("\r");
+				fflush (stdout);
+			    }
+			    fprintf (stderr, "%s-%s-%s [%d]%s:\t%sFAIL%s\n",
+				     ctx->test->name, target->name,
+				     cairo_boilerplate_content_name (target->content), dev_offset, similar ? " (similar)" : "",
+				     fail_face, normal_face);
+			    cairo_test_log (ctx, "FAIL\n");
+			}
+			ret = CAIRO_TEST_FAILURE;
+			break;
+		    }
+		    fflush (stdout);
+		} else {
+#ifdef HAVE_FLOCKFILE
+		    flockfile (stdout);
+#endif
+		    printf ("%s-%s-%s %d [%d]:\t",
+			    ctx->test->name, target->name,
+			    cairo_boilerplate_content_name (target->content),
+			    ctx->thread,
+			    dev_offset);
+		    switch (status) {
+		    case CAIRO_TEST_SUCCESS:
+			printf ("PASS\n");
+			break;
+		    case CAIRO_TEST_UNTESTED:
+			printf ("UNTESTED\n");
+			break;
+		    case CAIRO_TEST_CRASHED:
+			printf ("!!!CRASHED!!!\n");
+			ret = CAIRO_TEST_FAILURE;
+			break;
+		    default:
+		    case CAIRO_TEST_FAILURE:
+			if (ctx->expectation == CAIRO_TEST_FAILURE) {
+			    printf ("XFAIL\n");
+			} else {
+			    printf ("FAIL\n");
+			}
+			ret = CAIRO_TEST_FAILURE;
+			break;
 		    }
-		    ret = status;
-		    break;
-		}
 
-		if (status == CAIRO_TEST_CRASHED)
-		    goto out;
+		    fflush (stdout);
+#ifdef HAVE_FLOCKFILE
+		    funlockfile (stdout);
+#endif
+		}
 	    }
 	}
     }
-out:
+
+    return ret;
+}
+
+#ifdef HAVE_PTHREAD_H
+typedef struct _cairo_test_thread {
+    pthread_t thread;
+    cairo_test_context_t *ctx;
+    size_t id;
+} cairo_test_thread_t;
+
+static void *
+cairo_test_run_threaded (void *closure)
+{
+    cairo_test_thread_t *arg = closure;
+    cairo_test_context_t ctx;
+    cairo_test_status_t ret;
+
+    cairo_test_init_thread (&ctx, arg->ctx, arg->id);
+
+    ret = cairo_test_run (&ctx);
+
+    cairo_test_fini (&ctx);
+
+    return (void *) ret;
+}
+#endif
+
+
+static cairo_test_status_t
+cairo_test_expecting (const cairo_test_t *test,
+		      cairo_test_status_t expectation)
+{
+    cairo_test_context_t ctx;
+    cairo_test_status_t ret = CAIRO_TEST_SUCCESS;
+    size_t num_threads;
+
+    _cairo_test_init (&ctx, test, test->name, expectation);
+    printf ("%s\n", test->description);
+
+    if (expectation == CAIRO_TEST_FAILURE)
+	printf ("Expecting failure\n");
+
+#ifdef HAVE_PTHREAD_H
+    num_threads = 0;
+    if (getenv ("CAIRO_TEST_NUM_THREADS"))
+	num_threads = atoi (getenv ("CAIRO_TEST_NUM_THREADS"));
+    if (num_threads > 1) {
+	cairo_test_thread_t *threads;
+	size_t n;
+
+	threads = xmalloc (sizeof (cairo_test_thread_t) * num_threads);
+	for (n = 0; n < num_threads; n++) {
+	    threads[n].ctx = &ctx;
+	    threads[n].id = n + 1;
+	    pthread_create (&threads[n].thread, NULL,
+		    cairo_test_run_threaded, &threads[n]);
+	}
+	for (n = 0; n < num_threads; n++) {
+	    void *tmp;
+	    pthread_join (threads[n].thread, &tmp);
+	    if (ret == CAIRO_TEST_SUCCESS)
+		ret = (cairo_test_status_t) tmp;
+	}
+	free (threads);
+    }
+
+    if (ret == CAIRO_TEST_SUCCESS)
+#endif
+	ret = cairo_test_run (&ctx);
 
     if (ret != CAIRO_TEST_SUCCESS)
         printf ("Check %s%s out for more information.\n", test->name, CAIRO_TEST_LOG_SUFFIX);
@@ -661,7 +876,7 @@ out:
     /* if the set of targets to test was limited using CAIRO_TEST_TARGET, we
      * behave slightly differently, to ensure that limiting the targets does
      * not increase the number of tests failing. */
-    if (limited_targets) {
+    if (ctx.limited_targets) {
 
 	/* if all untested, success */
 	if (ret == CAIRO_TEST_UNTESTED) {
@@ -680,21 +895,18 @@ out:
 	}
 
     } else {
-
 	if (ret == CAIRO_TEST_UNTESTED)
 	    ret = CAIRO_TEST_FAILURE;
 
     }
 
-    cairo_test_fini ();
-
-    cairo_boilerplate_free_targets (targets_to_test);
+    cairo_test_fini (&ctx);
 
     return ret;
 }
 
 cairo_test_status_t
-cairo_test (cairo_test_t *test)
+cairo_test (const cairo_test_t *test)
 {
     cairo_test_status_t expectation = CAIRO_TEST_SUCCESS;
     const char *xfails;
@@ -726,20 +938,26 @@ cairo_test (cairo_test_t *test)
     return cairo_test_expecting (test, expectation);
 }
 
+const cairo_test_context_t *
+cairo_test_get_context (cairo_t *cr)
+{
+    return cairo_get_user_data (cr, &_cairo_test_context_key);
+}
+
 cairo_surface_t *
-cairo_test_create_surface_from_png (const char *filename)
+cairo_test_create_surface_from_png (const cairo_test_context_t *ctx,
+	                            const char *filename)
 {
     cairo_surface_t *image;
-    char *srcdir = getenv ("srcdir");
 
     image = cairo_image_surface_create_from_png (filename);
     if (cairo_surface_status(image)) {
         /* expect not found when running with srcdir != builddir
          * such as when 'make distcheck' is run
          */
-	if (srcdir) {
+	if (ctx->srcdir) {
 	    char *srcdir_filename;
-	    xasprintf (&srcdir_filename, "%s/%s", srcdir, filename);
+	    xasprintf (&srcdir_filename, "%s/%s", ctx->srcdir, filename);
 	    image = cairo_image_surface_create_from_png (srcdir_filename);
 	    free (srcdir_filename);
 	}
@@ -749,12 +967,13 @@ cairo_test_create_surface_from_png (const char *filename)
 }
 
 cairo_pattern_t *
-cairo_test_create_pattern_from_png (const char *filename)
+cairo_test_create_pattern_from_png (const cairo_test_context_t *ctx,
+	                            const char *filename)
 {
     cairo_surface_t *image;
     cairo_pattern_t *pattern;
 
-    image = cairo_test_create_surface_from_png (filename);
+    image = cairo_test_create_surface_from_png (ctx, filename);
 
     pattern = cairo_pattern_create_for_surface (image);
 
@@ -807,7 +1026,8 @@ cairo_test_paint_checkered (cairo_t *cr)
     cairo_paint (cr);
     cairo_restore (cr);
 
+    status = cairo_surface_status (check);
     cairo_surface_destroy (check);
 
-    return CAIRO_STATUS_SUCCESS;
+    return status;
 }
diff --git a/test/cairo-test.h b/test/cairo-test.h
index 381fd4c..09f5fd8 100644
--- a/test/cairo-test.h
+++ b/test/cairo-test.h
@@ -66,15 +66,18 @@ typedef enum cairo_test_status {
     CAIRO_TEST_CRASHED
 } cairo_test_status_t;
 
+typedef struct _cairo_test_context cairo_test_context_t;
+typedef struct _cairo_test cairo_test_t;
+
 typedef cairo_test_status_t  (cairo_test_draw_function_t) (cairo_t *cr, int width, int height);
 
-typedef struct _cairo_test {
+struct _cairo_test {
     const char *name;
     const char *description;
     int width;
     int height;
     cairo_test_draw_function_t *draw;
-} cairo_test_t;
+};
 
 /* The standard test interface which works by examining result image.
  *
@@ -99,7 +102,35 @@ typedef struct _cairo_test {
  * to the four criteria above.
  */
 cairo_test_status_t
-cairo_test (cairo_test_t *test);
+cairo_test (const cairo_test_t *test);
+
+/* The full context for the test.
+ * For ordinary tests (using cairo_test()) the context is passed to the draw
+ * routine via user_data on the cairo_t.  The reason why the context is not
+ * passed as an explicit parameter is that it is rarely required by the test
+ * itself and by removing the parameter we can keep the draw routines simple
+ * and serve as example code.
+ */
+struct _cairo_test_context {
+    const cairo_test_t *test;
+    const char *test_name;
+    cairo_test_status_t expectation;
+
+    FILE *log_file;
+    const char *srcdir; /* directory containing sources and input data */
+    const char *refdir; /* directory containing reference images */
+
+    size_t num_targets;
+    cairo_bool_t limited_targets;
+    cairo_boilerplate_target_t **targets_to_test;
+
+    int thread;
+};
+
+/* Retrieve the test context from the cairo_t, used for logging, paths etc */
+const cairo_test_context_t *
+cairo_test_get_context (cairo_t *cr);
+
 
 /* cairo_test_init(), cairo_test_log(), and cairo_test_fini() exist to
  * help in writing tests for which cairo_test() is not appropriate for
@@ -108,30 +139,37 @@ cairo_test (cairo_test_t *test);
  * than be handed one by cairo_test.
  */
 
+
 /* Initialize test-specific resources, (log files, etc.) */
 void
-cairo_test_init (const char *test_name);
+cairo_test_init (cairo_test_context_t *ctx,
+		 const char *test_name);
 
 /* Finalize test-specific resource. */
 void
-cairo_test_fini (void);
+cairo_test_fini (cairo_test_context_t *ctx);
+
 
 /* Print a message to the log file, ala printf. */
 void
-cairo_test_log (const char *fmt, ...) CAIRO_BOILERPLATE_PRINTF_FORMAT(1, 2);
+cairo_test_log (const cairo_test_context_t *ctx,
+	        const char *fmt, ...) CAIRO_BOILERPLATE_PRINTF_FORMAT(2, 3);
 
 void
-cairo_test_log_path (const cairo_path_t *path);
+cairo_test_log_path (const cairo_test_context_t *ctx,
+		     const cairo_path_t *path);
 
 /* Helper functions that take care of finding source images even when
  * building in a non-srcdir manner, (ie. the tests will be run in a
  * directory that is different from the one where the source image
  * exists). */
 cairo_surface_t *
-cairo_test_create_surface_from_png (const char *filename);
+cairo_test_create_surface_from_png (const cairo_test_context_t *ctx,
+	                            const char *filename);
 
 cairo_pattern_t *
-cairo_test_create_pattern_from_png (const char *filename);
+cairo_test_create_pattern_from_png (const cairo_test_context_t *ctx,
+	                            const char *filename);
 
 cairo_status_t
 cairo_test_paint_checkered (cairo_t *cr);
diff --git a/test/caps-joins-alpha.c b/test/caps-joins-alpha.c
index cdf6086..7595095 100644
--- a/test/caps-joins-alpha.c
+++ b/test/caps-joins-alpha.c
@@ -32,7 +32,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "caps-joins-alpha",
     "Test caps and joins with some source alpha",
     3 * (PAD + SIZE) + PAD,
diff --git a/test/caps-joins.c b/test/caps-joins.c
index c7306a0..bbda047 100644
--- a/test/caps-joins.c
+++ b/test/caps-joins.c
@@ -31,7 +31,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "caps-joins",
     "Test caps and joins",
     3 * (PAD + SIZE) + PAD,
diff --git a/test/caps-sub-paths.c b/test/caps-sub-paths.c
index 73af8aa..e431576 100644
--- a/test/caps-sub-paths.c
+++ b/test/caps-sub-paths.c
@@ -32,7 +32,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "caps-sub-paths",
     "Test that sub-paths receive caps.",
     20, 20,
diff --git a/test/clip-all.c b/test/clip-all.c
index b38e7b9..7e08b8e 100644
--- a/test/clip-all.c
+++ b/test/clip-all.c
@@ -30,7 +30,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "clip-all",
     "Test clipping with everything clipped out",
     SIZE, SIZE,
diff --git a/test/clip-empty.c b/test/clip-empty.c
index 9049153..2635042 100644
--- a/test/clip-empty.c
+++ b/test/clip-empty.c
@@ -29,7 +29,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "clip-empty",
     "Test clipping with an empty clip path",
     SIZE, SIZE,
diff --git a/test/clip-fill-rule-pixel-aligned.c b/test/clip-fill-rule-pixel-aligned.c
index c2bb08b..db7f66f 100644
--- a/test/clip-fill-rule-pixel-aligned.c
+++ b/test/clip-fill-rule-pixel-aligned.c
@@ -30,7 +30,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "clip-fill-rule-pixel-aligned",
     "Tests interaction of clipping and cairo_set_fill_rule with a pixel-aligned path",
     PAD + (SIZE*4) + PAD + (SIZE*4) + PAD,
diff --git a/test/clip-fill-rule.c b/test/clip-fill-rule.c
index 5012b3b..7140bc5 100644
--- a/test/clip-fill-rule.c
+++ b/test/clip-fill-rule.c
@@ -29,7 +29,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "clip-fill-rule",
     "Tests interaction of clipping with cairo_set_fill_rule",
     STAR_SIZE * 2 + 2, STAR_SIZE + 2,
diff --git a/test/clip-nesting.c b/test/clip-nesting.c
index 09f77fd..e82e817 100644
--- a/test/clip-nesting.c
+++ b/test/clip-nesting.c
@@ -33,7 +33,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "clip-nesting",
     "Test clipping with multiple contexts for the same surface",
     SIZE, SIZE,
diff --git a/test/clip-operator.c b/test/clip-operator.c
index 3bfb5ba..d6e20c8 100644
--- a/test/clip-operator.c
+++ b/test/clip-operator.c
@@ -115,7 +115,7 @@ draw_rects (cairo_t *cr, int x, int y)
     cairo_fill (cr);
 }
 
-static void (*draw_funcs[])(cairo_t *cr, int x, int y) = {
+static void (* const draw_funcs[])(cairo_t *cr, int x, int y) = {
     draw_mask,
     draw_glyphs,
     draw_polygon,
@@ -130,7 +130,7 @@ static void (*draw_funcs[])(cairo_t *cr, int x, int y) = {
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "clip-operator",
     "Surface clipping with different operators",
     IMAGE_WIDTH, IMAGE_HEIGHT,
@@ -140,6 +140,7 @@ cairo_test_t test = {
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     size_t j, x, y;
     cairo_operator_t op;
     cairo_pattern_t *pattern;
@@ -178,14 +179,14 @@ draw (cairo_t *cr, int width, int height)
 
 	    draw_funcs[j] (cr, x, y);
 	    if (cairo_status (cr))
-		cairo_test_log ("%d %d HERE!\n", op, (int)j);
+		cairo_test_log (ctx, "%d %d HERE!\n", op, (int)j);
 
 	    cairo_restore (cr);
 	}
     }
 
     if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
-	cairo_test_log ("%d %d .HERE!\n", op, (int)j);
+	cairo_test_log (ctx, "%d %d .HERE!\n", op, (int)j);
 
     return CAIRO_TEST_SUCCESS;
 }
diff --git a/test/clip-push-group.c b/test/clip-push-group.c
index 8274e85..66027b4 100644
--- a/test/clip-push-group.c
+++ b/test/clip-push-group.c
@@ -38,7 +38,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "clip-push-group",
     "Test that push_group doesn't crash after setting a surface-based clip",
     SIZE, SIZE,
diff --git a/test/clip-twice.c b/test/clip-twice.c
index 71a3c14..435b0c5 100644
--- a/test/clip-twice.c
+++ b/test/clip-twice.c
@@ -30,7 +30,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "clip-twice",
     "Verifies that the clip mask is updated correctly when it constructed by setting the clip path twice.",
     WIDTH, HEIGHT,
diff --git a/test/clip-zero.c b/test/clip-zero.c
index bf96d8c..4482c16 100644
--- a/test/clip-zero.c
+++ b/test/clip-zero.c
@@ -28,7 +28,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "clip-zero",
     "Verifies that 0x0 surfaces or clips don't cause problems.",
     0, 0,
diff --git a/test/clipped-group.c b/test/clipped-group.c
index 724e6cf..e1f68be 100644
--- a/test/clipped-group.c
+++ b/test/clipped-group.c
@@ -30,7 +30,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "clipped-group",
     "Test that a clipped group ends up in the right place",
     WIDTH, HEIGHT,
diff --git a/test/close-path.c b/test/close-path.c
index 04658b2..999fb37 100644
--- a/test/close-path.c
+++ b/test/close-path.c
@@ -28,7 +28,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "close-path",
     "Test some corner cases related to cairo_close_path",
     32, 16,
diff --git a/test/composite-integer-translate-over-repeat.c b/test/composite-integer-translate-over-repeat.c
index 2d79ee6..c691acb 100644
--- a/test/composite-integer-translate-over-repeat.c
+++ b/test/composite-integer-translate-over-repeat.c
@@ -34,7 +34,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "composite-integer-translate-over-repeat",
     "Test simple compositing: integer-translation 32->32 OVER, with repeat",
     SIZE, SIZE,
diff --git a/test/composite-integer-translate-over.c b/test/composite-integer-translate-over.c
index 2eac588..835a4dc 100644
--- a/test/composite-integer-translate-over.c
+++ b/test/composite-integer-translate-over.c
@@ -32,7 +32,7 @@ const char	png_filename[]	= "romedalen.png";
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "composite-integer-translate-over",
     "Test simple compositing: integer-translation 32->32 OVER",
     SIZE, SIZE,
@@ -42,9 +42,10 @@ cairo_test_t test = {
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     cairo_surface_t *image;
 
-    image = cairo_test_create_surface_from_png (png_filename);
+    image = cairo_test_create_surface_from_png (ctx, png_filename);
 
     cairo_set_source_rgba (cr, 0, 0, 0, 1);
     cairo_rectangle (cr, 0, 0, SIZE, SIZE);
diff --git a/test/composite-integer-translate-source.c b/test/composite-integer-translate-source.c
index 67813b7..0945cc1 100644
--- a/test/composite-integer-translate-source.c
+++ b/test/composite-integer-translate-source.c
@@ -35,7 +35,7 @@ const char	png_filename[]	= "romedalen.png";
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "composite-integer-translate-source",
     "Test simple compositing: integer-translation 32->32 SOURCE",
     SIZE, SIZE,
@@ -45,9 +45,10 @@ cairo_test_t test = {
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     cairo_surface_t *image;
 
-    image = cairo_test_create_surface_from_png (png_filename);
+    image = cairo_test_create_surface_from_png (ctx, png_filename);
 
     cairo_set_source_rgba (cr, 0, 0, 0, 1);
     cairo_rectangle (cr, 0, 0, SIZE, SIZE);
diff --git a/test/copy-path.c b/test/copy-path.c
index 362bb34..dfc671d 100644
--- a/test/copy-path.c
+++ b/test/copy-path.c
@@ -28,7 +28,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "copy-path",
     "Tests calls to path_data functions: cairo_copy_path, cairo_copy_path_flat, and cairo_append_path",
     45, 53,
@@ -96,6 +96,7 @@ make_path (cairo_t *cr)
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     cairo_path_t *path;
     cairo_t *cr_error;
 
@@ -105,7 +106,8 @@ draw (cairo_t *cr, int width, int height)
     path = cairo_copy_path (cr_error);
     if (path->status == CAIRO_STATUS_SUCCESS ||
 	path->status != cairo_status (cr_error)) {
-	cairo_test_log ("Error: cairo_copy_path returned status of %s rather than propagating %s\n",
+	cairo_test_log (ctx,
+			"Error: cairo_copy_path returned status of %s rather than propagating %s\n",
 			cairo_status_to_string (path->status),
 			cairo_status_to_string (cairo_status (cr_error)));
 	cairo_path_destroy (path);
@@ -116,7 +118,8 @@ draw (cairo_t *cr, int width, int height)
     path = cairo_copy_path_flat (cr_error);
     if (path->status == CAIRO_STATUS_SUCCESS ||
 	path->status != cairo_status (cr_error)) {
-	cairo_test_log ("Error: cairo_copy_path_flat returned status of %s rather than propagating %s\n",
+	cairo_test_log (ctx,
+			"Error: cairo_copy_path_flat returned status of %s rather than propagating %s\n",
 			cairo_status_to_string (path->status),
 			cairo_status_to_string (cairo_status (cr_error)));
 	cairo_path_destroy (path);
@@ -125,18 +128,20 @@ draw (cairo_t *cr, int width, int height)
     cairo_path_destroy (path);
 
     cairo_destroy (cr_error);
-    
+
     /* first check that we can copy an empty path */
     cairo_new_path (cr);
     path = cairo_copy_path (cr);
     if (path->status != CAIRO_STATUS_SUCCESS) {
-	cairo_test_log ("Error: cairo_copy_path returned status of %s\n",
+	cairo_test_log (ctx,
+			"Error: cairo_copy_path returned status of %s\n",
 			cairo_status_to_string (path->status));
 	cairo_path_destroy (path);
 	return CAIRO_TEST_FAILURE;
     }
     if (path->num_data != 0) {
-	cairo_test_log ("Error: cairo_copy_path did not copy an empty path, returned path contains %d elements\n",
+	cairo_test_log (ctx,
+			"Error: cairo_copy_path did not copy an empty path, returned path contains %d elements\n",
 		        path->num_data);
 	cairo_path_destroy (path);
 	return CAIRO_TEST_FAILURE;
@@ -144,7 +149,8 @@ draw (cairo_t *cr, int width, int height)
     cairo_append_path (cr, path);
     cairo_path_destroy (path);
     if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) {
-	cairo_test_log ("Error: cairo_append_path failed with a copy of an empty path, returned status of %s\n",
+	cairo_test_log (ctx,
+			"Error: cairo_append_path failed with a copy of an empty path, returned status of %s\n",
 			cairo_status_to_string (cairo_status (cr)));
 	return CAIRO_TEST_FAILURE;
     }
@@ -197,51 +203,75 @@ draw (cairo_t *cr, int width, int height)
 int
 main (void)
 {
+    cairo_test_context_t ctx;
     cairo_t *cr;
     cairo_path_data_t data;
     cairo_path_t path;
     cairo_surface_t *surface;
+    cairo_status_t status;
+
+    cairo_test_init (&ctx, "copy-path");
 
     surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
 
     /* Test a few error cases for cairo_append_path_data */
     cr = cairo_create (surface);
     cairo_append_path (cr, NULL);
-    if (cairo_status (cr) != CAIRO_STATUS_NULL_POINTER)
-	return 1;
+    status = cairo_status (cr);
     cairo_destroy (cr);
+    if (status != CAIRO_STATUS_NULL_POINTER) {
+	cairo_surface_destroy (surface);
+	cairo_test_fini (&ctx);
+	return CAIRO_TEST_FAILURE;
+    }
 
     cr = cairo_create (surface);
     path.status = -1;
     cairo_append_path (cr, &path);
-    if (cairo_status (cr) != CAIRO_STATUS_INVALID_STATUS)
-	return 1;
+    status = cairo_status (cr);
     cairo_destroy (cr);
+    if (status != CAIRO_STATUS_INVALID_STATUS) {
+	cairo_surface_destroy (surface);
+	cairo_test_fini (&ctx);
+	return CAIRO_TEST_FAILURE;
+    }
 
     cr = cairo_create (surface);
     path.status = CAIRO_STATUS_NO_MEMORY;
     cairo_append_path (cr, &path);
-    if (cairo_status (cr) != CAIRO_STATUS_NO_MEMORY)
-	return 1;
+    status = cairo_status (cr);
     cairo_destroy (cr);
+    if (status != CAIRO_STATUS_NO_MEMORY) {
+	cairo_surface_destroy (surface);
+	cairo_test_fini (&ctx);
+	return CAIRO_TEST_FAILURE;
+    }
 
     cr = cairo_create (surface);
     path.data = NULL;
     path.num_data = 0;
     path.status = CAIRO_STATUS_SUCCESS;
     cairo_append_path (cr, &path);
-    if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
-	return 1;
+    status = cairo_status (cr);
     cairo_destroy (cr);
+    if (status != CAIRO_STATUS_SUCCESS) {
+	cairo_surface_destroy (surface);
+	cairo_test_fini (&ctx);
+	return CAIRO_TEST_FAILURE;
+    }
 
     cr = cairo_create (surface);
     path.data = NULL;
     path.num_data = 1;
     path.status = CAIRO_STATUS_SUCCESS;
     cairo_append_path (cr, &path);
-    if (cairo_status (cr) != CAIRO_STATUS_NULL_POINTER)
-	return 1;
+    status = cairo_status (cr);
     cairo_destroy (cr);
+    if (status != CAIRO_STATUS_NULL_POINTER) {
+	cairo_surface_destroy (surface);
+	cairo_test_fini (&ctx);
+	return CAIRO_TEST_FAILURE;
+    }
 
     cr = cairo_create (surface);
     /* Intentionally insert bogus header.length value (otherwise would be 2) */
@@ -250,19 +280,28 @@ main (void)
     path.data = &data;
     path.num_data = 1;
     cairo_append_path (cr, &path);
-    if (cairo_status (cr) != CAIRO_STATUS_INVALID_PATH_DATA)
-	return 1;
+    status = cairo_status (cr);
     cairo_destroy (cr);
+    if (status != CAIRO_STATUS_INVALID_PATH_DATA) {
+	cairo_surface_destroy (surface);
+	cairo_test_fini (&ctx);
+	return CAIRO_TEST_FAILURE;
+    }
 
     /* And test the degnerate case */
     cr = cairo_create (surface);
     path.num_data = 0;
     cairo_append_path (cr, &path);
-    if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
-	return 1;
+    status = cairo_status (cr);
     cairo_destroy (cr);
+    if (status != CAIRO_STATUS_SUCCESS) {
+	cairo_surface_destroy (surface);
+	cairo_test_fini (&ctx);
+	return CAIRO_TEST_FAILURE;
+    }
 
     cairo_surface_destroy (surface);
+    cairo_test_fini (&ctx);
 
     return cairo_test (&test);
 }
diff --git a/test/create-for-stream.c b/test/create-for-stream.c
index 379412f..9d90cf4 100644
--- a/test/create-for-stream.c
+++ b/test/create-for-stream.c
@@ -85,6 +85,7 @@ draw_to (cairo_surface_t *surface)
 }
 
 typedef struct _write_closure {
+    const cairo_test_context_t *ctx;
     char buffer[MAX_OUTPUT_SIZE];
     size_t index;
     cairo_test_status_t status;
@@ -106,7 +107,7 @@ test_write (void		*closure,
     write_closure_t *wc = closure;
 
     if (wc->index + length >= sizeof wc->buffer) {
-	cairo_test_log ("Error: out of bounds in write callback\n");
+	cairo_test_log (wc->ctx, "Error: out of bounds in write callback\n");
 	wc->status = CAIRO_TEST_FAILURE;
 	return CAIRO_STATUS_SUCCESS;
     }
@@ -130,7 +131,8 @@ typedef cairo_surface_t *
 			 double			height_in_points);
 
 static cairo_test_status_t
-test_surface (const char                 *backend,
+test_surface (const cairo_test_context_t *ctx,
+	      const char                 *backend,
 	      const char		 *filename,
 	      file_constructor_t	 file_constructor,
 	      stream_constructor_t	 stream_constructor)
@@ -147,7 +149,9 @@ test_surface (const char                 *backend,
 
     status = cairo_surface_status (surface);
     if (status) {
-	cairo_test_log ("%s: Failed to create surface for stream.\n", backend);
+	cairo_test_log (ctx,
+			"%s: Failed to create surface for stream.\n",
+			backend);
 	return CAIRO_TEST_FAILURE;
     }
 
@@ -158,12 +162,14 @@ test_surface (const char                 *backend,
     cairo_surface_destroy (surface);
 
     if (status != CAIRO_STATUS_WRITE_ERROR) {
-	cairo_test_log ("%s: Error: expected \"write error\", but received \"%s\".\n",
+	cairo_test_log (ctx,
+			"%s: Error: expected \"write error\", but received \"%s\".\n",
 			backend, cairo_status_to_string (status));
 	return CAIRO_TEST_FAILURE;
     }
 
     /* construct the real surface */
+    wc.ctx = ctx;
     wc.status = CAIRO_TEST_SUCCESS;
     wc.index = 0;
 
@@ -172,7 +178,8 @@ test_surface (const char                 *backend,
 
     status = cairo_surface_status (surface);
     if (status) {
-	cairo_test_log ("%s: Failed to create surface for stream.\n", backend);
+	cairo_test_log (ctx,
+			"%s: Failed to create surface for stream.\n", backend);
 	return CAIRO_TEST_FAILURE;
     }
 
@@ -190,7 +197,7 @@ test_surface (const char                 *backend,
 
     status = cairo_surface_status (surface);
     if (status) {
-	cairo_test_log ("%s: Failed to create surface for file %s: %s.\n",
+	cairo_test_log (ctx, "%s: Failed to create surface for file %s: %s.\n",
 			backend, filename, cairo_status_to_string (status));
 	return CAIRO_TEST_FAILURE;
     }
@@ -201,20 +208,20 @@ test_surface (const char                 *backend,
 
     fp = fopen (filename, "r");
     if (fp == NULL) {
-	cairo_test_log ("%s: Failed to open %s for reading: %s.\n",
+	cairo_test_log (ctx, "%s: Failed to open %s for reading: %s.\n",
 			backend, filename, strerror (errno));
 	return CAIRO_TEST_FAILURE;
     }
 
     if (fread (file_contents, 1, wc.index, fp) != wc.index) {
-	cairo_test_log ("%s: Failed to read %s: %s.\n",
+	cairo_test_log (ctx, "%s: Failed to read %s: %s.\n",
 			backend, filename, strerror (errno));
 	fclose (fp);
 	return CAIRO_TEST_FAILURE;
     }
 
     if (memcmp (file_contents, wc.buffer, wc.index) != 0) {
-	cairo_test_log ("%s: Stream based output differ from file output for %s.\n",
+	cairo_test_log (ctx, "%s: Stream based output differ from file output for %s.\n",
 			backend, filename);
 	fclose (fp);
 	return CAIRO_TEST_FAILURE;
@@ -228,17 +235,18 @@ test_surface (const char                 *backend,
 int
 main (void)
 {
+    cairo_test_context_t ctx;
     cairo_test_status_t status = CAIRO_TEST_SUCCESS;
     cairo_test_status_t test_status;
     const char test_name[] = "create-for-stream";
 
-    cairo_test_init (test_name);
+    cairo_test_init (&ctx, test_name);
 
 #if CAIRO_HAS_PS_SURFACE
-    test_status = test_surface ("ps", "create-for-stream.ps",
+    test_status = test_surface (&ctx, "ps", "create-for-stream.ps",
 			        cairo_ps_surface_create,
 			        cairo_ps_surface_create_for_stream);
-    cairo_test_log ("TEST: %s TARGET: %s RESULT: %s\n",
+    cairo_test_log (&ctx, "TEST: %s TARGET: %s RESULT: %s\n",
 		    test_name, "ps",
 		    test_status ? "FAIL" : "PASS");
     if (status == CAIRO_TEST_SUCCESS)
@@ -246,10 +254,10 @@ main (void)
 #endif
 
 #if CAIRO_HAS_PDF_SURFACE
-    test_status = test_surface ("pdf", "create-for-stream.pdf",
+    test_status = test_surface (&ctx, "pdf", "create-for-stream.pdf",
 			        cairo_pdf_surface_create,
 			        cairo_pdf_surface_create_for_stream);
-    cairo_test_log ("TEST: %s TARGET: %s RESULT: %s\n",
+    cairo_test_log (&ctx, "TEST: %s TARGET: %s RESULT: %s\n",
 		    test_name, "pdf",
 		    test_status ? "FAIL" : "PASS");
     if (status == CAIRO_TEST_SUCCESS)
@@ -257,17 +265,17 @@ main (void)
 #endif
 
 #if CAIRO_HAS_SVG_SURFACE
-    test_status = test_surface ("svg", "create-for-stream.svg",
+    test_status = test_surface (&ctx, "svg", "create-for-stream.svg",
 			        cairo_svg_surface_create,
 			        cairo_svg_surface_create_for_stream);
-    cairo_test_log ("TEST: %s TARGET: %s RESULT: %s\n",
+    cairo_test_log (&ctx, "TEST: %s TARGET: %s RESULT: %s\n",
 		    test_name, "svg",
 		    test_status ? "FAIL" : "PASS");
     if (status == CAIRO_TEST_SUCCESS)
 	status = test_status;
 #endif
 
-    cairo_test_fini ();
+    cairo_test_fini (&ctx);
 
     return status;
 }
diff --git a/test/create-from-png-stream.c b/test/create-from-png-stream.c
index 4e8a29d..4fe0579 100644
--- a/test/create-from-png-stream.c
+++ b/test/create-from-png-stream.c
@@ -33,7 +33,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "create-from-png-stream",
     "Tests the creation of an image surface from a PNG using a FILE *",
     WIDTH, HEIGHT,
@@ -56,17 +56,17 @@ read_png_from_file (void *closure, unsigned char *data, unsigned int length)
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
-    char *srcdir = getenv ("srcdir");
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     char *filename;
     FILE *file;
     cairo_surface_t *surface;
 
-    xasprintf (&filename, "%s/%s", srcdir ? srcdir : ".",
+    xasprintf (&filename, "%s/%s", ctx->srcdir,
 	       "create-from-png-stream-ref.png");
 
     file = fopen (filename, "rb");
     if (file == NULL) {
-	cairo_test_log ("Error: failed to open file: %s\n", filename);
+	cairo_test_log (ctx, "Error: failed to open file: %s\n", filename);
 	return CAIRO_TEST_FAILURE;
     }
 
@@ -76,7 +76,9 @@ draw (cairo_t *cr, int width, int height)
     fclose (file);
 
     if (surface == NULL) {
-	cairo_test_log ("Error: failed to create surface from PNG: %s\n", filename);
+	cairo_test_log (ctx,
+			"Error: failed to create surface from PNG: %s\n",
+			filename);
 	free (filename);
 	return CAIRO_TEST_FAILURE;
     }
diff --git a/test/create-from-png.c b/test/create-from-png.c
index 0707680..52831f0 100644
--- a/test/create-from-png.c
+++ b/test/create-from-png.c
@@ -32,7 +32,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "create-from-png",
     "Tests the creation of an image surface from a PNG file",
     WIDTH, HEIGHT,
@@ -54,16 +54,16 @@ read_error (void *closure, unsigned char *data, unsigned int size)
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
-    char *srcdir = getenv ("srcdir");
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     char *filename;
     cairo_surface_t *surface;
 
-    xasprintf (&filename, "%s/%s", srcdir ? srcdir : ".",
+    xasprintf (&filename, "%s/%s", ctx->srcdir,
 	       "create-from-png-ref.png");
 
     surface = cairo_image_surface_create_from_png (filename);
     if (cairo_surface_status (surface)) {
-	cairo_test_log ("Error reading PNG image %s: %s\n",
+	cairo_test_log (ctx, "Error reading PNG image %s: %s\n",
 			filename,
 			cairo_status_to_string (cairo_surface_status (surface)));
 	free (filename);
@@ -82,189 +82,177 @@ draw (cairo_t *cr, int width, int height)
 int
 main (void)
 {
-    char *srcdir = getenv ("srcdir");
+    cairo_test_context_t ctx;
     char *filename;
     cairo_surface_t *surface;
     cairo_status_t status;
+    cairo_test_status_t result = CAIRO_TEST_SUCCESS;
+
+    cairo_test_init (&ctx, "create-from-png");
 
     surface = cairo_image_surface_create_from_png ("___THIS_FILE_DOES_NOT_EXIST___");
     if (cairo_surface_status (surface) != CAIRO_STATUS_FILE_NOT_FOUND) {
-	cairo_test_log ("Error: expected \"file not found\", but got: %s\n",
+	cairo_test_log (&ctx, "Error: expected \"file not found\", but got: %s\n",
 			cairo_status_to_string (cairo_surface_status (surface)));
-	cairo_surface_destroy (surface);
-	return CAIRO_TEST_FAILURE;
+	result = CAIRO_TEST_FAILURE;
     }
+    cairo_surface_destroy (surface);
 
     surface = cairo_image_surface_create_from_png_stream (no_memory_error, NULL);
     if (cairo_surface_status (surface) != CAIRO_STATUS_NO_MEMORY) {
-	cairo_test_log ("Error: expected \"out of memory\", but got: %s\n",
+	cairo_test_log (&ctx, "Error: expected \"out of memory\", but got: %s\n",
 			cairo_status_to_string (cairo_surface_status (surface)));
-	cairo_surface_destroy (surface);
-	return CAIRO_TEST_FAILURE;
+	result = CAIRO_TEST_FAILURE;
     }
+    cairo_surface_destroy (surface);
 
     surface = cairo_image_surface_create_from_png_stream (read_error, NULL);
     if (cairo_surface_status (surface) != CAIRO_STATUS_READ_ERROR) {
-	cairo_test_log ("Error: expected \"read error\", but got: %s\n",
+	cairo_test_log (&ctx, "Error: expected \"read error\", but got: %s\n",
 			cairo_status_to_string (cairo_surface_status (surface)));
-	cairo_surface_destroy (surface);
-	return CAIRO_TEST_FAILURE;
+	result = CAIRO_TEST_FAILURE;
     }
+    cairo_surface_destroy (surface);
 
     /* cheekily test error propagation from the user write funcs as well ... */
-    xasprintf (&filename, "%s/%s", srcdir ? srcdir : ".",
+    xasprintf (&filename, "%s/%s", ctx.srcdir,
 	       "create-from-png-ref.png");
 
     surface = cairo_image_surface_create_from_png (filename);
     if (cairo_surface_status (surface)) {
-	cairo_test_log ("Error reading PNG image %s: %s\n",
+	cairo_test_log (&ctx, "Error reading PNG image %s: %s\n",
 			filename,
 			cairo_status_to_string (cairo_surface_status (surface)));
-	free (filename);
-	return CAIRO_TEST_FAILURE;
-    }
-    free (filename);
+	result = CAIRO_TEST_FAILURE;
+    } else {
+	status = cairo_surface_write_to_png_stream (surface,
+					       (cairo_write_func_t) no_memory_error,
+					       NULL);
+	if (status != CAIRO_STATUS_NO_MEMORY) {
+	    cairo_test_log (&ctx, "Error: expected \"out of memory\", but got: %s\n",
+			    cairo_status_to_string (status));
+	    result = CAIRO_TEST_FAILURE;
+	}
 
-    status = cairo_surface_write_to_png_stream (surface,
-	                                   (cairo_write_func_t) no_memory_error,
-					   NULL);
-    if (status != CAIRO_STATUS_NO_MEMORY) {
-	cairo_test_log ("Error: expected \"out of memory\", but got: %s\n",
-			cairo_status_to_string (status));
-	cairo_surface_destroy (surface);
-	return CAIRO_TEST_FAILURE;
-    }
-    status = cairo_surface_write_to_png_stream (surface,
-	                                        (cairo_write_func_t) read_error,
-						NULL);
-    if (status != CAIRO_STATUS_READ_ERROR) {
-	cairo_test_log ("Error: expected \"read error\", but got: %s\n",
-			cairo_status_to_string (status));
-	cairo_surface_destroy (surface);
-	return CAIRO_TEST_FAILURE;
+	status = cairo_surface_write_to_png_stream (surface,
+						    (cairo_write_func_t) read_error,
+						    NULL);
+	if (status != CAIRO_STATUS_READ_ERROR) {
+	    cairo_test_log (&ctx, "Error: expected \"read error\", but got: %s\n",
+			    cairo_status_to_string (status));
+	    result = CAIRO_TEST_FAILURE;
+	}
+
+	/* and check that error has not propagated to the surface */
+	if (cairo_surface_status (surface)) {
+	    cairo_test_log (&ctx, "Error: user write error propagated to surface: %s",
+			    cairo_status_to_string (cairo_surface_status (surface)));
+	    result = CAIRO_TEST_FAILURE;
+	}
     }
     cairo_surface_destroy (surface);
+    free (filename);
 
     /* check that loading alpha/opaque PNGs generate the correct surfaces */
-    xasprintf (&filename, "%s/%s", srcdir ? srcdir : ".",
+    xasprintf (&filename, "%s/%s", ctx.srcdir,
 	       "create-from-png-alpha-ref.png");
     surface = cairo_image_surface_create_from_png (filename);
     if (cairo_surface_status (surface)) {
-	cairo_test_log ("Error reading PNG image %s: %s\n",
+	cairo_test_log (&ctx, "Error reading PNG image %s: %s\n",
 			filename,
 			cairo_status_to_string (cairo_surface_status (surface)));
-	free (filename);
-	return CAIRO_TEST_FAILURE;
-    }
-    if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_ARGB32) {
-	cairo_test_log ("Error reading PNG image %s: did not create an ARGB32 image\n",
-		filename);
-	cairo_surface_destroy (surface);
-	return CAIRO_TEST_FAILURE;
+	result = CAIRO_TEST_FAILURE;
+    } else if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_ARGB32) {
+	cairo_test_log (&ctx, "Error reading PNG image %s: did not create an ARGB32 image\n",
+			filename);
+	result = CAIRO_TEST_FAILURE;
     }
     free (filename);
     cairo_surface_destroy (surface);
 
-    xasprintf (&filename, "%s/%s", srcdir ? srcdir : ".",
+    xasprintf (&filename, "%s/%s", ctx.srcdir,
 	       "create-from-png-ref.png");
     surface = cairo_image_surface_create_from_png (filename);
     if (cairo_surface_status (surface)) {
-	cairo_test_log ("Error reading PNG image %s: %s\n",
+	cairo_test_log (&ctx, "Error reading PNG image %s: %s\n",
 			filename,
 			cairo_status_to_string (cairo_surface_status (surface)));
-	free (filename);
-	return CAIRO_TEST_FAILURE;
-    }
-    if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_RGB24) {
-	cairo_test_log ("Error reading PNG image %s: did not create an RGB24 image\n",
-		filename);
-	cairo_surface_destroy (surface);
-	return CAIRO_TEST_FAILURE;
+	result = CAIRO_TEST_FAILURE;
+    } else if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_RGB24) {
+	cairo_test_log (&ctx, "Error reading PNG image %s: did not create an RGB24 image\n",
+			filename);
+	result = CAIRO_TEST_FAILURE;
     }
     free (filename);
     cairo_surface_destroy (surface);
 
     /* check paletted PNGs */
-    xasprintf (&filename, "%s/%s", srcdir ? srcdir : ".",
+    xasprintf (&filename, "%s/%s", ctx.srcdir,
 	       "create-from-png-indexed-alpha-ref.png");
     surface = cairo_image_surface_create_from_png (filename);
     if (cairo_surface_status (surface)) {
-	cairo_test_log ("Error reading PNG image %s: %s\n",
+	cairo_test_log (&ctx, "Error reading PNG image %s: %s\n",
 			filename,
 			cairo_status_to_string (cairo_surface_status (surface)));
-	free (filename);
-	return CAIRO_TEST_FAILURE;
-    }
-    if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_ARGB32) {
-	cairo_test_log ("Error reading PNG image %s: did not create an ARGB32 image\n",
-		filename);
-	free (filename);
-	cairo_surface_destroy (surface);
-	return CAIRO_TEST_FAILURE;
+	result = CAIRO_TEST_FAILURE;
+    } else if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_ARGB32) {
+	cairo_test_log (&ctx, "Error reading PNG image %s: did not create an ARGB32 image\n",
+			filename);
+	result = CAIRO_TEST_FAILURE;
     }
     free (filename);
     cairo_surface_destroy (surface);
 
-    xasprintf (&filename, "%s/%s", srcdir ? srcdir : ".",
+    xasprintf (&filename, "%s/%s", ctx.srcdir,
 	       "create-from-png-indexed-ref.png");
     surface = cairo_image_surface_create_from_png (filename);
     if (cairo_surface_status (surface)) {
-	cairo_test_log ("Error reading PNG image %s: %s\n",
+	cairo_test_log (&ctx, "Error reading PNG image %s: %s\n",
 			filename,
 			cairo_status_to_string (cairo_surface_status (surface)));
-	free (filename);
-	return CAIRO_TEST_FAILURE;
-    }
-    if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_RGB24) {
-	cairo_test_log ("Error reading PNG image %s: did not create an RGB24 image\n",
-		filename);
-	free (filename);
-	cairo_surface_destroy (surface);
-	return CAIRO_TEST_FAILURE;
+	result = CAIRO_TEST_FAILURE;
+    } else if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_RGB24) {
+	cairo_test_log (&ctx, "Error reading PNG image %s: did not create an RGB24 image\n",
+			filename);
+	result = CAIRO_TEST_FAILURE;
     }
     free (filename);
     cairo_surface_destroy (surface);
 
     /* check grayscale PNGs */
-    xasprintf (&filename, "%s/%s", srcdir ? srcdir : ".",
+    xasprintf (&filename, "%s/%s", ctx.srcdir,
 	       "create-from-png-gray-alpha-ref.png");
     surface = cairo_image_surface_create_from_png (filename);
     if (cairo_surface_status (surface)) {
-	cairo_test_log ("Error reading PNG image %s: %s\n",
+	cairo_test_log (&ctx, "Error reading PNG image %s: %s\n",
 			filename,
 			cairo_status_to_string (cairo_surface_status (surface)));
-	free (filename);
-	return CAIRO_TEST_FAILURE;
-    }
-    if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_ARGB32) {
-	cairo_test_log ("Error reading PNG image %s: did not create an ARGB32 image\n",
-		filename);
-	free (filename);
-	cairo_surface_destroy (surface);
-	return CAIRO_TEST_FAILURE;
+	result = CAIRO_TEST_FAILURE;
+    } else if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_ARGB32) {
+	cairo_test_log (&ctx, "Error reading PNG image %s: did not create an ARGB32 image\n",
+			filename);
+	result = CAIRO_TEST_FAILURE;
     }
     free (filename);
     cairo_surface_destroy (surface);
 
-    xasprintf (&filename, "%s/%s", srcdir ? srcdir : ".",
+    xasprintf (&filename, "%s/%s", ctx.srcdir,
 	       "create-from-png-gray-ref.png");
     surface = cairo_image_surface_create_from_png (filename);
     if (cairo_surface_status (surface)) {
-	cairo_test_log ("Error reading PNG image %s: %s\n",
+	cairo_test_log (&ctx, "Error reading PNG image %s: %s\n",
 			filename,
 			cairo_status_to_string (cairo_surface_status (surface)));
-	free (filename);
-	return CAIRO_TEST_FAILURE;
-    }
-    if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_RGB24) {
-	cairo_test_log ("Error reading PNG image %s: did not create an RGB24 image\n",
-		filename);
-	free (filename);
-	cairo_surface_destroy (surface);
-	return CAIRO_TEST_FAILURE;
+	result = CAIRO_TEST_FAILURE;
+    } else if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_RGB24) {
+	cairo_test_log (&ctx, "Error reading PNG image %s: did not create an RGB24 image\n",
+			filename);
+	result = CAIRO_TEST_FAILURE;
     }
     free (filename);
     cairo_surface_destroy (surface);
 
+    cairo_test_fini (&ctx);
+
     return cairo_test (&test);
 }
diff --git a/test/dash-caps-joins.c b/test/dash-caps-joins.c
index 370d05d..680a7fb 100644
--- a/test/dash-caps-joins.c
+++ b/test/dash-caps-joins.c
@@ -37,7 +37,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "dash-caps-joins",
     "Test caps and joins when dashing",
     3 * (PAD + SIZE) + PAD,
diff --git a/test/dash-curve.c b/test/dash-curve.c
index 48f5c12..b98f4f1 100644
--- a/test/dash-curve.c
+++ b/test/dash-curve.c
@@ -27,7 +27,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "dash-curve",
     "Tries to explore the state space of the dashing code along curves",
     25*60, 4*60,
diff --git a/test/dash-no-dash.c b/test/dash-no-dash.c
index 21235b9..e9e9c5d 100644
--- a/test/dash-no-dash.c
+++ b/test/dash-no-dash.c
@@ -33,7 +33,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "dash-no-dash",
     "Tests that we can actually turn dashing on and off again",
     WIDTH, HEIGHT,
diff --git a/test/dash-offset-negative.c b/test/dash-offset-negative.c
index 539e3cd..adfe265 100644
--- a/test/dash-offset-negative.c
+++ b/test/dash-offset-negative.c
@@ -36,7 +36,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "dash-offset-negative",
     "Tests cairo_set_dash with a negative offset",
     IMAGE_WIDTH, IMAGE_HEIGHT,
diff --git a/test/dash-scale.c b/test/dash-scale.c
index b845dcf..b00b0f1 100644
--- a/test/dash-scale.c
+++ b/test/dash-scale.c
@@ -31,7 +31,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "dash-scale",
     "Test interactions of cairo_set_dash and cairo_scale, (in particular with a non-uniformly scaled pen)",
     3 * (PAD + SIZE) + PAD,
diff --git a/test/dash-state.c b/test/dash-state.c
index a59a3e8..f74e598 100644
--- a/test/dash-state.c
+++ b/test/dash-state.c
@@ -27,7 +27,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "dash-state",
     "Tries to explore the state space of the dashing code",
     25*60, 4*60,
diff --git a/test/dash-zero-length.c b/test/dash-zero-length.c
index 6e9854a..e6f2da6 100644
--- a/test/dash-zero-length.c
+++ b/test/dash-zero-length.c
@@ -35,7 +35,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "dash-zero-length",
     "Tests cairo_set_dash with zero length",
     IMAGE_WIDTH, IMAGE_HEIGHT,
diff --git a/test/degenerate-arc.c b/test/degenerate-arc.c
index f01b666..d030598 100644
--- a/test/degenerate-arc.c
+++ b/test/degenerate-arc.c
@@ -32,7 +32,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "degenerate-arc",
     "Tests the behaviour of degenerate arcs",
     40, 40,
diff --git a/test/degenerate-path.c b/test/degenerate-path.c
index c861cd2..67cc9a0 100644
--- a/test/degenerate-path.c
+++ b/test/degenerate-path.c
@@ -32,7 +32,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "degenerate-path",
     "Tests the behaviour of degenerate paths with different cap types",
     3*(PAD+LINE_WIDTH+PAD), 8*(LINE_WIDTH+PAD) + PAD,
diff --git a/test/degenerate-pen.c b/test/degenerate-pen.c
index 4ff50f8..deb7b2a 100644
--- a/test/degenerate-pen.c
+++ b/test/degenerate-pen.c
@@ -50,7 +50,7 @@ static cairo_test_draw_function_t draw;
  * pen doing slope comparisons.
  */
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "degenerate-pen",
     "Test round joins with a pen that's transformed to a line",
     WIDTH, HEIGHT,
diff --git a/test/device-offset-positive.c b/test/device-offset-positive.c
index ab1adcf..4b49b10 100644
--- a/test/device-offset-positive.c
+++ b/test/device-offset-positive.c
@@ -31,7 +31,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "device-offset-positive",
     "Simple test using a surface with a positive device-offset as a source.",
     SIZE, SIZE,
diff --git a/test/device-offset-scale.c b/test/device-offset-scale.c
index 5134589..1c2537d 100644
--- a/test/device-offset-scale.c
+++ b/test/device-offset-scale.c
@@ -30,7 +30,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "device-offset-scale",
     "Test that the device-offset transform is transformed by the ctm.",
     WIDTH, HEIGHT,
diff --git a/test/device-offset.c b/test/device-offset.c
index cee603f..dfeb508 100644
--- a/test/device-offset.c
+++ b/test/device-offset.c
@@ -31,7 +31,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "device-offset",
     "Simple test using a surface with a negative device-offset as a source.",
     SIZE, SIZE,
diff --git a/test/extend-pad.c b/test/extend-pad.c
index fdd887f..8c3c09c 100644
--- a/test/extend-pad.c
+++ b/test/extend-pad.c
@@ -32,7 +32,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "extend-pad",
     "Test CAIRO_EXTEND_PAD for surface patterns",
     SIZE, SIZE,
diff --git a/test/extend-reflect-similar.c b/test/extend-reflect-similar.c
index 1ff4039..c1914b3 100644
--- a/test/extend-reflect-similar.c
+++ b/test/extend-reflect-similar.c
@@ -4,7 +4,7 @@ const char	png_filename[]	= "romedalen.png";
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "extend-reflect-similar",
     "Test CAIRO_EXTEND_REFLECT for surface patterns",
     256 + 32*2, 192 + 32*2,
@@ -22,9 +22,11 @@ clone_similar_surface (cairo_surface_t * target, cairo_surface_t *surface)
 				      cairo_image_surface_get_width (surface),
 				      cairo_image_surface_get_height (surface));
     cr = cairo_create (similar);
+    cairo_surface_destroy (similar);
     cairo_set_source_surface (cr, surface, 0, 0);
     cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
     cairo_paint (cr);
+    similar = cairo_surface_reference (cairo_get_target (cr));
     cairo_destroy (cr);
 
     return similar;
@@ -33,10 +35,11 @@ clone_similar_surface (cairo_surface_t * target, cairo_surface_t *surface)
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     cairo_surface_t *surface;
     cairo_surface_t *similar;
 
-    surface = cairo_test_create_surface_from_png (png_filename);
+    surface = cairo_test_create_surface_from_png (ctx, png_filename);
     similar = clone_similar_surface (cairo_get_group_target (cr), surface);
     cairo_set_source_surface (cr, similar, 32, 32);
     cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REFLECT);
diff --git a/test/extend-reflect.c b/test/extend-reflect.c
index e9d07cc..6175657 100644
--- a/test/extend-reflect.c
+++ b/test/extend-reflect.c
@@ -6,7 +6,7 @@ const char	png_filename[]	= "romedalen.png";
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "extend-reflect",
     "Test CAIRO_EXTEND_REFLECT for surface patterns",
     256 + 32*2, 192 + 32*2,
@@ -16,9 +16,10 @@ cairo_test_t test = {
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     cairo_surface_t *surface;
 
-    surface = cairo_test_create_surface_from_png (png_filename);
+    surface = cairo_test_create_surface_from_png (ctx, png_filename);
     cairo_set_source_surface (cr, surface, 32, 32);
     cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REFLECT);
 
diff --git a/test/extend-repeat-similar.c b/test/extend-repeat-similar.c
index 1a14125..88d4a2b 100644
--- a/test/extend-repeat-similar.c
+++ b/test/extend-repeat-similar.c
@@ -4,7 +4,7 @@ const char	png_filename[]	= "romedalen.png";
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "extend-repeat-similar",
     "Test CAIRO_EXTEND_REPEAT for surface patterns",
     256 + 32*2, 192 + 32*2,
@@ -22,9 +22,11 @@ clone_similar_surface (cairo_surface_t * target, cairo_surface_t *surface)
 				      cairo_image_surface_get_width (surface),
 				      cairo_image_surface_get_height (surface));
     cr = cairo_create (similar);
+    cairo_surface_destroy (similar);
     cairo_set_source_surface (cr, surface, 0, 0);
     cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
     cairo_paint (cr);
+    similar = cairo_surface_reference (cairo_get_target (cr));
     cairo_destroy (cr);
 
     return similar;
@@ -33,10 +35,11 @@ clone_similar_surface (cairo_surface_t * target, cairo_surface_t *surface)
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     cairo_surface_t *surface;
     cairo_surface_t *similar;
 
-    surface = cairo_test_create_surface_from_png (png_filename);
+    surface = cairo_test_create_surface_from_png (ctx, png_filename);
     similar = clone_similar_surface (cairo_get_group_target (cr), surface);
     cairo_set_source_surface (cr, similar, 32, 32);
     cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
diff --git a/test/extend-repeat.c b/test/extend-repeat.c
index 351b63b..32c43a5 100644
--- a/test/extend-repeat.c
+++ b/test/extend-repeat.c
@@ -4,7 +4,7 @@ const char	png_filename[]	= "romedalen.png";
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "extend-repeat",
     "Test CAIRO_EXTEND_REPEAT for surface patterns",
     256 + 32*2, 192 + 32*2,
@@ -14,9 +14,10 @@ cairo_test_t test = {
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     cairo_surface_t *surface;
 
-    surface = cairo_test_create_surface_from_png (png_filename);
+    surface = cairo_test_create_surface_from_png (ctx, png_filename);
     cairo_set_source_surface (cr, surface, 32, 32);
     cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
 
diff --git a/test/fallback-resolution.c b/test/fallback-resolution.c
index 2fcf1ac..aa1be92 100644
--- a/test/fallback-resolution.c
+++ b/test/fallback-resolution.c
@@ -88,6 +88,7 @@ static const char *backend_filename[NUM_BACKENDS] = {
 int
 main (void)
 {
+    cairo_test_context_t ctx;
     cairo_surface_t *surface = NULL;
     cairo_t *cr;
     cairo_status_t status;
@@ -98,7 +99,7 @@ main (void)
 
     num_pages = sizeof (ppi) / sizeof (ppi[0]);
 
-    cairo_test_init ("fallback-resolution");
+    cairo_test_init (&ctx, "fallback-resolution");
 
     for (backend=0; backend < NUM_BACKENDS; backend++) {
 
@@ -166,7 +167,7 @@ main (void)
 	cairo_surface_destroy (surface);
 
 	if (status) {
-	    cairo_test_log ("Failed to create pdf surface for file %s: %s\n",
+	    cairo_test_log (&ctx, "Failed to create pdf surface for file %s: %s\n",
 			    backend_filename[backend],
 			    cairo_status_to_string (status));
 	    ret = CAIRO_TEST_FAILURE;
@@ -177,7 +178,7 @@ main (void)
 		backend_filename[backend]);
     }
 
-    cairo_test_fini ();
+    cairo_test_fini (&ctx);
 
     return ret;
 }
diff --git a/test/fill-and-stroke-alpha-add.c b/test/fill-and-stroke-alpha-add.c
index 0a3ebbc..3575c82 100644
--- a/test/fill-and-stroke-alpha-add.c
+++ b/test/fill-and-stroke-alpha-add.c
@@ -31,7 +31,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "fill-and-stroke-alpha-add",
     "Use a group to fill/stroke a path (each with different alpha) using DEST_OUT and ADD to combine",
     2 * SIZE + 4 * PAD, SIZE + 2 * PAD,
diff --git a/test/fill-and-stroke-alpha.c b/test/fill-and-stroke-alpha.c
index 1d01151..fe02c75 100644
--- a/test/fill-and-stroke-alpha.c
+++ b/test/fill-and-stroke-alpha.c
@@ -31,7 +31,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "fill-and-stroke-alpha",
     "Use a group to fill/stroke a path then blend the result with alpha onto the destination",
     2 * SIZE + 4 * PAD, SIZE + 2 * PAD,
diff --git a/test/fill-and-stroke.c b/test/fill-and-stroke.c
index 345b51d..8bbb261 100644
--- a/test/fill-and-stroke.c
+++ b/test/fill-and-stroke.c
@@ -30,7 +30,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "fill-and-stroke",
     "Tests using cairo_fill_preserve/cairo_stroke to fill/stroke the same path",
     2 * SIZE + 4 * PAD, SIZE + 2 * PAD,
diff --git a/test/fill-degenerate-sort-order.c b/test/fill-degenerate-sort-order.c
index 570b373..b35f42e 100644
--- a/test/fill-degenerate-sort-order.c
+++ b/test/fill-degenerate-sort-order.c
@@ -38,7 +38,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "fill-degenerate-sort-order",
     "Tests the tessellator's event comparator with degenerate input",
     190, 120,
diff --git a/test/fill-missed-stop.c b/test/fill-missed-stop.c
index f05b1aa..cb551c4 100644
--- a/test/fill-missed-stop.c
+++ b/test/fill-missed-stop.c
@@ -40,7 +40,7 @@
 static cairo_test_draw_function_t draw;
 #define SIZE 50
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "fill-missed-stop",
     "Tests that the tessellator doesn't miss stop events when generating trapezoids",
     SIZE+3, SIZE+3,
diff --git a/test/fill-rule.c b/test/fill-rule.c
index a9ce295..8f787ff 100644
--- a/test/fill-rule.c
+++ b/test/fill-rule.c
@@ -68,7 +68,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "fill-rule",
     "Tests cairo_set_fill_rule with some star shapes",
     BIG_STAR_SIZE * 2 + 3, BIG_STAR_SIZE + LITTLE_STAR_SIZE + 3,
diff --git a/test/filter-bilinear-extents.c b/test/filter-bilinear-extents.c
index 0a95556..666b7b3 100644
--- a/test/filter-bilinear-extents.c
+++ b/test/filter-bilinear-extents.c
@@ -44,7 +44,7 @@ static cairo_test_draw_function_t draw;
 #define WIDTH	(PAD + 3 * SCALE + PAD)
 #define HEIGHT	WIDTH
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "filter-bilinear-extents",
     "Test that pattern extents are properly computed for CAIRO_FILTER_BILINEAR",
     WIDTH, HEIGHT,
diff --git a/test/filter-nearest-offset.c b/test/filter-nearest-offset.c
index 2727f56..a4cb513 100644
--- a/test/filter-nearest-offset.c
+++ b/test/filter-nearest-offset.c
@@ -36,7 +36,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "filter-nearest-offset",
     "Test sampling offset of CAIRO_FILTER_NEAREST"
     "\nwrong sampling location for nearest-neighbor filter in libpixman and Render",
@@ -48,7 +48,7 @@ static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
     cairo_surface_t *surface;
-    static uint32_t data[STAMP_WIDTH * STAMP_HEIGHT] = {
+    uint32_t data[STAMP_WIDTH * STAMP_HEIGHT] = {
 	0xffffffff, 0xffffffff,		0xffff0000, 0xffff0000,
 	0xffffffff, 0xffffffff,		0xffff0000, 0xffff0000,
 
diff --git a/test/finer-grained-fallbacks.c b/test/finer-grained-fallbacks.c
index 2dd006c..f7cd5f3 100644
--- a/test/finer-grained-fallbacks.c
+++ b/test/finer-grained-fallbacks.c
@@ -33,7 +33,7 @@ static cairo_test_draw_function_t draw;
 #define WIDTH (CIRCLE_SIZE*6.5 + PAD)
 #define HEIGHT (CIRCLE_SIZE*3.5 + PAD)
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "finer-grained-fallbacks",
     "Test that multiple PS/PDF fallback images in various locations are correct",
     WIDTH, HEIGHT,
diff --git a/test/font-face-get-type.c b/test/font-face-get-type.c
index a3298fa..32ebc47 100644
--- a/test/font-face-get-type.c
+++ b/test/font-face-get-type.c
@@ -28,14 +28,15 @@
 int
 main (void)
 {
+    cairo_test_context_t ctx;
     cairo_surface_t *surface;
     cairo_t *cr;
     cairo_font_face_t *font_face;
     cairo_scaled_font_t *scaled_font;
 
-    cairo_test_init ("font-face-get-type");
+    cairo_test_init (&ctx, "font-face-get-type");
 
-    cairo_test_log ("Creating cairo context and obtaining a font face\n");
+    cairo_test_log (&ctx, "Creating cairo context and obtaining a font face\n");
 
     surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
     cr = cairo_create (surface);
@@ -44,29 +45,31 @@ main (void)
 			    CAIRO_FONT_SLANT_NORMAL,
 			    CAIRO_FONT_WEIGHT_NORMAL);
 
-    cairo_test_log ("Testing return value of cairo_font_face_get_type\n");
+    cairo_test_log (&ctx, "Testing return value of cairo_font_face_get_type\n");
 
     font_face = cairo_get_font_face (cr);
 
     if (cairo_font_face_get_type (font_face) != CAIRO_FONT_TYPE_TOY) {
-	cairo_test_log ("Unexpected value %d from cairo_font_face_get_type (expected %d)\n",
+	cairo_test_log (&ctx, "Unexpected value %d from cairo_font_face_get_type (expected %d)\n",
 			cairo_font_face_get_type (font_face), CAIRO_FONT_TYPE_TOY);
+	cairo_test_fini (&ctx);
 	return CAIRO_TEST_FAILURE;
     }
 
-    cairo_test_log ("Testing return value of cairo_get_scaled_font\n");
+    cairo_test_log (&ctx, "Testing return value of cairo_get_scaled_font\n");
 
     scaled_font = cairo_get_scaled_font (cr);
 
     if (cairo_scaled_font_get_font_face (scaled_font) != font_face) {
-	cairo_test_log ("Font face returned from the scaled font is different from that returned by the context\n");
+	cairo_test_log (&ctx, "Font face returned from the scaled font is different from that returned by the context\n");
+	cairo_test_fini (&ctx);
 	return CAIRO_TEST_FAILURE;
     }
 
     cairo_destroy (cr);
     cairo_surface_destroy (surface);
 
-    cairo_test_fini ();
+    cairo_test_fini (&ctx);
 
     return CAIRO_TEST_SUCCESS;
 }
diff --git a/test/font-matrix-translation.c b/test/font-matrix-translation.c
index 9ed12ab..263a378 100644
--- a/test/font-matrix-translation.c
+++ b/test/font-matrix-translation.c
@@ -31,7 +31,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "font-matrix-translation",
     "Test that translation in a font matrix can be used to offset a string",
     38, 34,
@@ -51,7 +51,9 @@ text_extents_equal (const cairo_text_extents_t *A,
 }
 
 static cairo_test_status_t
-box_text (cairo_t *cr, const char *utf8, double x, double y)
+box_text (const cairo_test_context_t *ctx, cairo_t *cr,
+	  const char *utf8,
+	  double x, double y)
 {
     double line_width;
     cairo_text_extents_t extents = {0}, scaled_extents = {0};
@@ -64,7 +66,8 @@ box_text (cairo_t *cr, const char *utf8, double x, double y)
     scaled_font = cairo_get_scaled_font (cr);
     cairo_scaled_font_text_extents (scaled_font, TEXT, &scaled_extents);
     if (! text_extents_equal (&extents, &scaled_extents)) {
-        cairo_test_log ("Error: extents differ when they shouldn't:\n"
+        cairo_test_log (ctx,
+			"Error: extents differ when they shouldn't:\n"
 			"cairo_text_extents(); extents (%g, %g, %g, %g, %g, %g)\n"
 			"cairo_scaled_font_text_extents(); extents (%g, %g, %g, %g, %g, %g)\n",
 		        extents.x_bearing, extents.y_bearing,
@@ -95,6 +98,7 @@ box_text (cairo_t *cr, const char *utf8, double x, double y)
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     cairo_test_status_t status;
     cairo_text_extents_t extents;
     cairo_matrix_t matrix;
@@ -114,7 +118,7 @@ draw (cairo_t *cr, int width, int height)
 
     /* Draw text and bounding box */
     cairo_set_source_rgb (cr, 0, 0, 0); /* black */
-    status = box_text (cr, TEXT, 0, - extents.y_bearing);
+    status = box_text (ctx, cr, TEXT, 0, - extents.y_bearing);
     if (status)
 	return status;
 
@@ -126,7 +130,7 @@ draw (cairo_t *cr, int width, int height)
     cairo_set_font_matrix (cr, &matrix);
 
     cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
-    status = box_text (cr, TEXT, 0, - extents.y_bearing);
+    status = box_text (ctx, cr, TEXT, 0, - extents.y_bearing);
     if (status)
 	return status;
 
diff --git a/test/ft-font-create-for-ft-face.c b/test/ft-font-create-for-ft-face.c
index 35cb77d..6b3c511 100644
--- a/test/ft-font-create-for-ft-face.c
+++ b/test/ft-font-create-for-ft-face.c
@@ -28,7 +28,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "ft-font-create-for-ft-face",
     "Simple test to verify that cairo_ft_font_create_for_ft_face doesn't crash.",
     0, 0,
@@ -38,6 +38,7 @@ cairo_test_t test = {
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     FcPattern *pattern, *resolved;
     FcResult result;
     cairo_font_face_t *font_face;
@@ -55,7 +56,7 @@ draw (cairo_t *cr, int width, int height)
      * Do not use this in production code! */
     pattern = FcPatternCreate ();
     if (! pattern) {
-	cairo_test_log ("FcPatternCreate failed.\n");
+	cairo_test_log (ctx, "FcPatternCreate failed.\n");
 	return CAIRO_TEST_FAILURE;
     }
 
@@ -63,14 +64,14 @@ draw (cairo_t *cr, int width, int height)
     FcDefaultSubstitute (pattern);
     resolved = FcFontMatch (NULL, pattern, &result);
     if (! resolved) {
-	cairo_test_log ("FcFontMatch failed.\n");
+	cairo_test_log (ctx, "FcFontMatch failed.\n");
 	return CAIRO_TEST_FAILURE;
     }
 
     font_face = cairo_ft_font_face_create_for_pattern (resolved);
 
     if (cairo_font_face_get_type (font_face) != CAIRO_FONT_TYPE_FT) {
-	cairo_test_log ("Unexpected value from cairo_font_face_get_type: %d (expected %d)\n",
+	cairo_test_log (ctx, "Unexpected value from cairo_font_face_get_type: %d (expected %d)\n",
 			cairo_font_face_get_type (font_face), CAIRO_FONT_TYPE_FT);
 	cairo_font_face_destroy (font_face);
 	return CAIRO_TEST_FAILURE;
@@ -97,14 +98,14 @@ draw (cairo_t *cr, int width, int height)
     FcPatternDestroy (resolved);
 
     if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_FT) {
-	cairo_test_log ("Unexpected value from cairo_scaled_font_get_type: %d (expected %d)\n",
+	cairo_test_log (ctx, "Unexpected value from cairo_scaled_font_get_type: %d (expected %d)\n",
 			cairo_scaled_font_get_type (scaled_font), CAIRO_FONT_TYPE_FT);
 	cairo_scaled_font_destroy (scaled_font);
 	return CAIRO_TEST_FAILURE;
     }
 
     if (!ft_face) {
-	cairo_test_log ("Failed to get an ft_face with cairo_ft_scaled_font_lock_face\n");
+	cairo_test_log (ctx, "Failed to get an ft_face with cairo_ft_scaled_font_lock_face\n");
 	cairo_scaled_font_destroy (scaled_font);
 	return CAIRO_TEST_FAILURE;
     }
diff --git a/test/ft-show-glyphs-positioning.c b/test/ft-show-glyphs-positioning.c
index d23c531..33e5055 100644
--- a/test/ft-show-glyphs-positioning.c
+++ b/test/ft-show-glyphs-positioning.c
@@ -31,7 +31,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "ft-show-glyphs-positioning",
     "Test that the PS/PDF glyph positioning optimizations are correct",
     235, (TEXT_SIZE + 4)*2,
diff --git a/test/ft-show-glyphs-table.c b/test/ft-show-glyphs-table.c
index a7654bc..cc34c6d 100644
--- a/test/ft-show-glyphs-table.c
+++ b/test/ft-show-glyphs-table.c
@@ -56,7 +56,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "ft-show-glyphs-table",
     "Test cairo_show_glyphs with cairo-ft backend and glyphs laid out in a table",
     WIDTH, HEIGHT,
diff --git a/test/ft-text-antialias-none.c b/test/ft-text-antialias-none.c
index e4a34e9..5d03269 100644
--- a/test/ft-text-antialias-none.c
+++ b/test/ft-text-antialias-none.c
@@ -35,7 +35,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "ft-text-antialias-none",
     "Tests text rendering with no antialiasing",
     WIDTH, HEIGHT,
@@ -99,7 +99,7 @@ draw (cairo_t *cr, int width, int height)
 {
     cairo_text_extents_t extents;
     cairo_scaled_font_t * scaled_font;
-    static char black[] = "black", blue[] = "blue";
+    const char black[] = "black", blue[] = "blue";
 
     /* We draw in the default black, so paint white first. */
     cairo_save (cr);
diff --git a/test/ft-text-vertical-layout-type1.c b/test/ft-text-vertical-layout-type1.c
index c52c28d..3cfb153 100644
--- a/test/ft-text-vertical-layout-type1.c
+++ b/test/ft-text-vertical-layout-type1.c
@@ -35,7 +35,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "ft-text-vertical-layout-type1",
     "Tests text rendering for vertical layout with Type1 fonts"
     "\nCan fail if an incorrect font is loaded---need to bundle the desired font",
@@ -101,7 +101,7 @@ draw (cairo_t *cr, int width, int height)
 {
     cairo_text_extents_t extents;
     cairo_scaled_font_t * scaled_font;
-    static char text[] = "i-W";
+    const char text[] = "i-W";
     double line_width, x, y;
 
     line_width = cairo_get_line_width (cr);
diff --git a/test/ft-text-vertical-layout-type3.c b/test/ft-text-vertical-layout-type3.c
index 4d1394a..c1a8bbf 100644
--- a/test/ft-text-vertical-layout-type3.c
+++ b/test/ft-text-vertical-layout-type3.c
@@ -35,7 +35,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "ft-text-vertical-layout-type3",
     "Tests text rendering for vertical layout with TrueType fonts",
     WIDTH, HEIGHT,
@@ -100,7 +100,7 @@ draw (cairo_t *cr, int width, int height)
 {
     cairo_text_extents_t extents;
     cairo_scaled_font_t * scaled_font;
-    static char text[] = "i-W";
+    const char text[] = "i-W";
     double line_width, x, y;
 
     line_width = cairo_get_line_width (cr);
diff --git a/test/get-and-set.c b/test/get-and-set.c
index c23707e..90c394a 100644
--- a/test/get-and-set.c
+++ b/test/get-and-set.c
@@ -28,7 +28,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "get-and-set",
     "Tests calls to the most trivial cairo_get and cairo_set functions",
     0, 0,
@@ -49,7 +49,7 @@ typedef struct {
 } settings_t;
 
 /* Two sets of settings, no defaults */
-settings_t settings[] = {
+static const settings_t settings[] = {
     {
 	CAIRO_OPERATOR_IN,
 	2.0,
@@ -77,7 +77,7 @@ settings_t settings[] = {
 };
 
 static void
-settings_set (cairo_t *cr, settings_t *settings)
+settings_set (cairo_t *cr, const settings_t *settings)
 {
     cairo_set_operator (cr, settings->op);
     cairo_set_tolerance (cr, settings->tolerance);
@@ -114,7 +114,7 @@ settings_get (cairo_t *cr, settings_t *settings)
 }
 
 static int
-settings_equal (settings_t *a, settings_t *b)
+settings_equal (const settings_t *a, const settings_t *b)
 {
     return (a->op == b->op &&
 	    a->tolerance == b->tolerance &&
diff --git a/test/get-clip.c b/test/get-clip.c
index bd92e1e..bd7f8a1 100644
--- a/test/get-clip.c
+++ b/test/get-clip.c
@@ -28,7 +28,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "get-clip",
     "Test cairo_copy_clip_rectangle_list and cairo_clip_extents",
     0, 0,
@@ -36,7 +36,8 @@ cairo_test_t test = {
 };
 
 static cairo_bool_t
-check_count (const char *message, cairo_bool_t uses_clip_rects,
+check_count (const cairo_test_context_t *ctx,
+	     const char *message, cairo_bool_t uses_clip_rects,
              cairo_rectangle_list_t *list, int expected)
 {
     if (!uses_clip_rects) {
@@ -46,29 +47,29 @@ check_count (const char *message, cairo_bool_t uses_clip_rects,
 	    return 1;
 	if (list->status == CAIRO_STATUS_CLIP_NOT_REPRESENTABLE)
 	    return 1;
-        cairo_test_log ("Error: %s; cairo_copy_clip_rectangle_list unexpectedly got %d rectangles\n",
+        cairo_test_log (ctx, "Error: %s; cairo_copy_clip_rectangle_list unexpectedly got %d rectangles\n",
                         message, list->num_rectangles);
         return 0;
     }
 
     if (list->status != CAIRO_STATUS_SUCCESS) {
-        cairo_test_log ("Error: %s; cairo_copy_clip_rectangle_list failed with \"%s\"\n",
+        cairo_test_log (ctx, "Error: %s; cairo_copy_clip_rectangle_list failed with \"%s\"\n",
                         message, cairo_status_to_string(list->status));
         return 0;
     }
 
     if (list->num_rectangles == expected)
         return 1;
-    cairo_test_log ("Error: %s; expected %d rectangles, got %d\n", message,
+    cairo_test_log (ctx, "Error: %s; expected %d rectangles, got %d\n", message,
                     expected, list->num_rectangles);
     return 0;
 }
 
 static cairo_bool_t
-check_unrepresentable (const char *message, cairo_rectangle_list_t *list)
+check_unrepresentable (const cairo_test_context_t *ctx, const char *message, cairo_rectangle_list_t *list)
 {
     if (list->status != CAIRO_STATUS_CLIP_NOT_REPRESENTABLE) {
-        cairo_test_log ("Error: %s; cairo_copy_clip_rectangle_list got unexpected result \"%s\"\n"
+        cairo_test_log (ctx, "Error: %s; cairo_copy_clip_rectangle_list got unexpected result \"%s\"\n"
                         " (we expected CAIRO_STATUS_CLIP_NOT_REPRESENTABLE)",
                         message, cairo_status_to_string(list->status));
         return 0;
@@ -77,7 +78,8 @@ check_unrepresentable (const char *message, cairo_rectangle_list_t *list)
 }
 
 static cairo_bool_t
-check_rectangles_contain (const char *message, cairo_bool_t uses_clip_rects,
+check_rectangles_contain (const cairo_test_context_t *ctx,
+			  const char *message, cairo_bool_t uses_clip_rects,
                           cairo_rectangle_list_t *list,
                           double x, double y, double width, double height)
 {
@@ -91,20 +93,21 @@ check_rectangles_contain (const char *message, cairo_bool_t uses_clip_rects,
             list->rectangles[i].width == width && list->rectangles[i].height == height)
             return 1;
     }
-    cairo_test_log ("Error: %s; rectangle list does not contain rectangle %f,%f,%f,%f\n",
+    cairo_test_log (ctx, "Error: %s; rectangle list does not contain rectangle %f,%f,%f,%f\n",
                     message, x, y, width, height);
     return 0;
 }
 
 static cairo_bool_t
-check_clip_extents (const char *message, cairo_t *cr,
+check_clip_extents (const cairo_test_context_t *ctx,
+		    const char *message, cairo_t *cr,
                     double x, double y, double width, double height)
 {
     double ext_x1, ext_y1, ext_x2, ext_y2;
     cairo_clip_extents (cr, &ext_x1, &ext_y1, &ext_x2, &ext_y2);
     if (ext_x1 == x && ext_y1 == y && ext_x2 == x + width && ext_y2 == y + height)
         return 1;
-    cairo_test_log ("Error: %s; clip extents %f,%f,%f,%f should be %f,%f,%f,%f\n",
+    cairo_test_log (ctx, "Error: %s; clip extents %f,%f,%f,%f should be %f,%f,%f,%f\n",
                     message, ext_x1, ext_y1, ext_x2 - ext_x1, ext_y2 - ext_y1,
                     x, y, width, height);
     return 0;
@@ -113,6 +116,7 @@ check_clip_extents (const char *message, cairo_t *cr,
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     cairo_surface_t        *surface;
     cairo_t                *cr2;
     cairo_rectangle_list_t *rectangle_list;
@@ -154,9 +158,9 @@ draw (cairo_t *cr, int width, int height)
        return the surface rectangle. */
     phase = "No clip set";
     rectangle_list = cairo_copy_clip_rectangle_list (cr2);
-    if (!check_count (phase, uses_clip_rects, rectangle_list, 1) ||
-        !check_clip_extents (phase, cr2, 0, 0, 100, 100) ||
-        !check_rectangles_contain(phase, uses_clip_rects, rectangle_list, 0, 0, 100, 100)) {
+    if (!check_count (ctx, phase, uses_clip_rects, rectangle_list, 1) ||
+        !check_clip_extents (ctx, phase, cr2, 0, 0, 100, 100) ||
+        !check_rectangles_contain (ctx, phase, uses_clip_rects, rectangle_list, 0, 0, 100, 100)) {
         cairo_rectangle_list_destroy (rectangle_list);
 	return CAIRO_TEST_FAILURE;
     }
@@ -168,9 +172,9 @@ draw (cairo_t *cr, int width, int height)
     cairo_rectangle (cr2, 10, 10, 80, 80);
     cairo_clip (cr2);
     rectangle_list = cairo_copy_clip_rectangle_list (cr2);
-    if (!check_count (phase, uses_clip_rects, rectangle_list, 1) ||
-        !check_clip_extents (phase, cr2, 10, 10, 80, 80) ||
-        !check_rectangles_contain(phase, uses_clip_rects, rectangle_list, 10, 10, 80, 80)) {
+    if (!check_count (ctx, phase, uses_clip_rects, rectangle_list, 1) ||
+        !check_clip_extents (ctx, phase, cr2, 10, 10, 80, 80) ||
+        !check_rectangles_contain (ctx, phase, uses_clip_rects, rectangle_list, 10, 10, 80, 80)) {
         cairo_rectangle_list_destroy (rectangle_list);
 	return CAIRO_TEST_FAILURE;
     }
@@ -182,7 +186,7 @@ draw (cairo_t *cr, int width, int height)
     cairo_save (cr2);
     cairo_clip (cr2);
     rectangle_list = cairo_copy_clip_rectangle_list (cr2);
-    if (!check_count (phase, uses_clip_rects, rectangle_list, 0)) {
+    if (!check_count (ctx, phase, uses_clip_rects, rectangle_list, 0)) {
         cairo_rectangle_list_destroy (rectangle_list);
 	return CAIRO_TEST_FAILURE;
     }
@@ -198,10 +202,10 @@ draw (cairo_t *cr, int width, int height)
     cairo_rectangle (cr2, 15, 15, 10, 10);
     cairo_clip (cr2);
     rectangle_list = cairo_copy_clip_rectangle_list (cr2);
-    if (!check_count (phase, uses_clip_rects, rectangle_list, 2) ||
-        !check_clip_extents (phase, cr2, 15, 15, 10, 10) ||
-        !check_rectangles_contain(phase, uses_clip_rects, rectangle_list, 15, 15, 5, 5) ||
-        !check_rectangles_contain(phase, uses_clip_rects, rectangle_list, 20, 20, 5, 5)) {
+    if (!check_count (ctx, phase, uses_clip_rects, rectangle_list, 2) ||
+        !check_clip_extents (ctx, phase, cr2, 15, 15, 10, 10) ||
+        !check_rectangles_contain (ctx, phase, uses_clip_rects, rectangle_list, 15, 15, 5, 5) ||
+        !check_rectangles_contain (ctx, phase, uses_clip_rects, rectangle_list, 20, 20, 5, 5)) {
         cairo_rectangle_list_destroy (rectangle_list);
 	return CAIRO_TEST_FAILURE;
     }
@@ -218,8 +222,8 @@ draw (cairo_t *cr, int width, int height)
     cairo_clip (cr2);
     rectangle_list = cairo_copy_clip_rectangle_list (cr2);
      /* can't get this in one tight user-space rectangle */
-    if (!check_unrepresentable (phase, rectangle_list) ||
-        !check_clip_extents (phase, cr2, 0, 0, 100, 100)) {
+    if (!check_unrepresentable (ctx, phase, rectangle_list) ||
+        !check_clip_extents (ctx, phase, cr2, 0, 0, 100, 100)) {
         cairo_rectangle_list_destroy (rectangle_list);
 	return CAIRO_TEST_FAILURE;
     }
@@ -232,9 +236,9 @@ draw (cairo_t *cr, int width, int height)
     cairo_rectangle (cr2, 5, 5, 40, 40);
     cairo_clip (cr2);
     rectangle_list = cairo_copy_clip_rectangle_list (cr2);
-    if (!check_count (phase, uses_clip_rects, rectangle_list, 1) ||
-        !check_clip_extents (phase, cr2, 5, 5, 40, 40) ||
-        !check_rectangles_contain(phase, uses_clip_rects, rectangle_list, 5, 5, 40, 40)) {
+    if (!check_count (ctx, phase, uses_clip_rects, rectangle_list, 1) ||
+        !check_clip_extents (ctx, phase, cr2, 5, 5, 40, 40) ||
+        !check_rectangles_contain (ctx, phase, uses_clip_rects, rectangle_list, 5, 5, 40, 40)) {
         cairo_rectangle_list_destroy (rectangle_list);
 	return CAIRO_TEST_FAILURE;
     }
@@ -249,9 +253,9 @@ draw (cairo_t *cr, int width, int height)
     cairo_restore (cr2);
     cairo_clip (cr2);
     rectangle_list = cairo_copy_clip_rectangle_list (cr2);
-    if (!check_count (phase, uses_clip_rects, rectangle_list, 1) ||
-        !check_clip_extents (phase, cr2, 10, 10, 80, 80) ||
-        !check_rectangles_contain(phase, uses_clip_rects, rectangle_list, 10, 10, 80, 80)) {
+    if (!check_count (ctx, phase, uses_clip_rects, rectangle_list, 1) ||
+        !check_clip_extents (ctx, phase, cr2, 10, 10, 80, 80) ||
+        !check_rectangles_contain (ctx, phase, uses_clip_rects, rectangle_list, 10, 10, 80, 80)) {
         cairo_rectangle_list_destroy (rectangle_list);
 	return CAIRO_TEST_FAILURE;
     }
@@ -266,7 +270,7 @@ draw (cairo_t *cr, int width, int height)
     cairo_restore (cr2);
     cairo_clip (cr2);
     rectangle_list = cairo_copy_clip_rectangle_list (cr2);
-    if (!check_unrepresentable (phase, rectangle_list)) {
+    if (!check_unrepresentable (ctx, phase, rectangle_list)) {
         cairo_rectangle_list_destroy (rectangle_list);
 	return CAIRO_TEST_FAILURE;
     }
diff --git a/test/get-group-target.c b/test/get-group-target.c
index 73a2d95..010f6ec 100644
--- a/test/get-group-target.c
+++ b/test/get-group-target.c
@@ -30,7 +30,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "get-group-target",
     "Test of both cairo_get_group_target and cairo_surface_get_device_offset",
     SIZE, SIZE,
diff --git a/test/get-path-extents.c b/test/get-path-extents.c
index 4d1966b..5bfdcd7 100644
--- a/test/get-path-extents.c
+++ b/test/get-path-extents.c
@@ -29,7 +29,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "get-path-extents",
     "Test cairo_fill_extents and cairo_stroke_extents",
     0, 0,
@@ -41,7 +41,8 @@ enum ExtentsType { FILL, STROKE, PATH };
 enum Relation { EQUALS, APPROX_EQUALS, CONTAINS };
 
 static cairo_bool_t
-check_extents (const char *message, cairo_t *cr, enum ExtentsType type,
+check_extents (const cairo_test_context_t *ctx,
+	       const char *message, cairo_t *cr, enum ExtentsType type,
                enum Relation relation,
                double x, double y, double width, double height)
 {
@@ -97,7 +98,7 @@ check_extents (const char *message, cairo_t *cr, enum ExtentsType type,
         break;
     }
 
-    cairo_test_log ("Error: %s; %s extents (%g, %g) x (%g, %g) should %s (%g, %g) x (%g, %g)\n",
+    cairo_test_log (ctx, "Error: %s; %s extents (%g, %g) x (%g, %g) should %s (%g, %g) x (%g, %g)\n",
                     message, type_string,
                     ext_x1, ext_y1, ext_x2 - ext_x1, ext_y2 - ext_y1,
                     relation_string,
@@ -108,6 +109,7 @@ check_extents (const char *message, cairo_t *cr, enum ExtentsType type,
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     cairo_surface_t *surface;
     cairo_t         *cr2;
     const char      *phase;
@@ -127,9 +129,9 @@ draw (cairo_t *cr, int width, int height)
     cairo_set_miter_limit (cr2, 100);
 
     phase = "No path";
-    errors += !check_extents (phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
-    errors += !check_extents (phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
-    errors += !check_extents (phase, cr2, PATH, EQUALS, 0, 0, 0, 0);
+    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
+    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
+    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 0, 0, 0, 0);
 
     cairo_save (cr2);
 
@@ -137,31 +139,31 @@ draw (cairo_t *cr, int width, int height)
     cairo_move_to (cr2, 200, 400);
     cairo_rel_line_to (cr2, 0., 0.);
     phase = "Degenerate line";
-    errors += !check_extents (phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
-    errors += !check_extents (phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
-    errors += !check_extents (phase, cr2, PATH, EQUALS, 200, 400, 0, 0);
+    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
+    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
+    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 200, 400, 0, 0);
 
     cairo_new_path (cr2);
     cairo_move_to (cr2, 200, 400);
     cairo_rel_curve_to (cr2, 0., 0., 0., 0., 0., 0.);
     phase = "Degenerate curve";
-    errors += !check_extents (phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
-    errors += !check_extents (phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
-    errors += !check_extents (phase, cr2, PATH, EQUALS, 200, 400, 0, 0);
+    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
+    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
+    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 200, 400, 0, 0);
 
     cairo_new_path (cr2);
     cairo_arc (cr2, 200, 400, 0., 0, 2 * M_PI);
     phase = "Degenerate arc (R=0)";
-    errors += !check_extents (phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
-    errors += !check_extents (phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
-    errors += !check_extents (phase, cr2, PATH, EQUALS, 200, 400, 0, 0);
+    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
+    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
+    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 200, 400, 0, 0);
 
     cairo_new_path (cr2);
     cairo_arc (cr2, 200, 400, 10., 0, 0);
     phase = "Degenerate arc (Θ=0)";
-    errors += !check_extents (phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
-    errors += !check_extents (phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
-    errors += !check_extents (phase, cr2, PATH, EQUALS, 200, 400, 0, 0);
+    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
+    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 0, 0);
+    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 200, 400, 0, 0);
 
     cairo_new_path (cr2);
     cairo_restore (cr2);
@@ -176,17 +178,17 @@ draw (cairo_t *cr, int width, int height)
     cairo_move_to (cr2, 200, 400);
     cairo_rel_line_to (cr2, 0, 0);
     phase = "Single 'dot'";
-    errors += !check_extents (phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
-    errors += !check_extents (phase, cr2, STROKE, EQUALS, 190, 390, 20, 20);
-    errors += !check_extents (phase, cr2, PATH, EQUALS, 200, 400, 0, 0);
+    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
+    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 190, 390, 20, 20);
+    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 200, 400, 0, 0);
 
     /* Add another dot without starting a new path */
     cairo_move_to (cr2, 100, 500);
     cairo_rel_line_to (cr2, 0, 0);
     phase = "Multiple 'dots'";
-    errors += !check_extents (phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
-    errors += !check_extents (phase, cr2, STROKE, EQUALS, 90, 390, 120, 120);
-    errors += !check_extents (phase, cr2, PATH, EQUALS, 100, 400, 100, 100);
+    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
+    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 90, 390, 120, 120);
+    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 100, 400, 100, 100);
 
     cairo_new_path (cr2);
 
@@ -199,18 +201,18 @@ draw (cairo_t *cr, int width, int height)
     cairo_set_line_join (cr2, CAIRO_LINE_JOIN_ROUND);
     cairo_move_to (cr2, 0, 180);
     cairo_line_to (cr2, 750, 180);
-    errors += !check_extents (phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
-    errors += !check_extents (phase, cr2, STROKE, EQUALS, -5, 175, 760, 10);
-    errors += !check_extents (phase, cr2, PATH, EQUALS, 0, 180, 755, 0);
+    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 0, 0, 0, 0);
+    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, -5, 175, 760, 10);
+    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 0, 180, 755, 0);
     cairo_new_path (cr2);
     cairo_restore (cr2);
 
     phase = "Simple rect";
     cairo_save (cr2);
     cairo_rectangle (cr2, 10, 10, 80, 80);
-    errors += !check_extents (phase, cr2, FILL, EQUALS, 10, 10, 80, 80);
-    errors += !check_extents (phase, cr2, STROKE, EQUALS, 5, 5, 90, 90);
-    errors += !check_extents (phase, cr2, PATH, EQUALS, 10, 10, 80, 80);
+    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 80, 80);
+    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 5, 5, 90, 90);
+    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 10, 10, 80, 80);
     cairo_new_path (cr2);
     cairo_restore (cr2);
 
@@ -218,9 +220,9 @@ draw (cairo_t *cr, int width, int height)
     cairo_save (cr2);
     cairo_rectangle (cr2, 10, 10, 10, 10);
     cairo_rectangle (cr2, 20, 20, 10, 10);
-    errors += !check_extents (phase, cr2, FILL, EQUALS, 10, 10, 20, 20);
-    errors += !check_extents (phase, cr2, STROKE, EQUALS, 5, 5, 30, 30);
-    errors += !check_extents (phase, cr2, PATH, EQUALS, 10, 10, 20, 20);
+    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 20, 20);
+    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 5, 5, 30, 30);
+    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 10, 10, 20, 20);
     cairo_new_path (cr2);
     cairo_restore (cr2);
 
@@ -232,9 +234,9 @@ draw (cairo_t *cr, int width, int height)
     cairo_close_path (cr2);
     /* miter joins protrude 5*(1+sqrt(2)) above the top-left corner and to
        the right of the bottom-right corner */
-    errors += !check_extents (phase, cr2, FILL, EQUALS, 10, 10, 80, 80);
-    errors += !check_extents (phase, cr2, STROKE, CONTAINS, 0, 5, 95, 95);
-    errors += !check_extents (phase, cr2, PATH, CONTAINS, 10, 10, 80, 80);
+    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 80, 80);
+    errors += !check_extents (ctx, phase, cr2, STROKE, CONTAINS, 0, 5, 95, 95);
+    errors += !check_extents (ctx, phase, cr2, PATH, CONTAINS, 10, 10, 80, 80);
     cairo_new_path (cr2);
     cairo_restore (cr2);
 
@@ -247,17 +249,17 @@ draw (cairo_t *cr, int width, int height)
 
     cairo_set_fill_rule (cr2, CAIRO_FILL_RULE_EVEN_ODD);
     phase = "EVEN_ODD overlapping rectangles";
-    errors += !check_extents (phase, cr2, FILL, EQUALS, 10, 10, 15, 30);
-    errors += !check_extents (phase, cr2, STROKE, EQUALS, 8, 8, 34, 34);
-    errors += !check_extents (phase, cr2, PATH, EQUALS, 10, 10, 30, 30);
+    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 15, 30);
+    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 8, 8, 34, 34);
+    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 10, 10, 30, 30);
 
     /* Test other fill rule with the same path. */
 
     cairo_set_fill_rule (cr2, CAIRO_FILL_RULE_WINDING);
     phase = "WINDING overlapping rectangles";
-    errors += !check_extents (phase, cr2, FILL, EQUALS, 10, 10, 30, 30);
-    errors += !check_extents (phase, cr2, STROKE, EQUALS, 8, 8, 34, 34);
-    errors += !check_extents (phase, cr2, PATH, EQUALS, 10, 10, 30, 30);
+    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 30, 30);
+    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 8, 8, 34, 34);
+    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 10, 10, 30, 30);
 
     /* Now, change the direction of the second rectangle and test both
      * fill rules again. */
@@ -267,17 +269,17 @@ draw (cairo_t *cr, int width, int height)
 
     cairo_set_fill_rule (cr2, CAIRO_FILL_RULE_EVEN_ODD);
     phase = "EVEN_ODD overlapping rectangles";
-    errors += !check_extents (phase, cr2, FILL, EQUALS, 10, 10, 15, 30);
-    errors += !check_extents (phase, cr2, STROKE, EQUALS, 8, 8, 34, 34);
-    errors += !check_extents (phase, cr2, PATH, EQUALS, 10, 10, 30, 30);
+    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 15, 30);
+    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 8, 8, 34, 34);
+    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 10, 10, 30, 30);
 
     /* Test other fill rule with the same path. */
 
     cairo_set_fill_rule (cr2, CAIRO_FILL_RULE_WINDING);
     phase = "WINDING overlapping rectangles";
-    errors += !check_extents (phase, cr2, FILL, EQUALS, 10, 10, 15, 30);
-    errors += !check_extents (phase, cr2, STROKE, EQUALS, 8, 8, 34, 34);
-    errors += !check_extents (phase, cr2, PATH, EQUALS, 10, 10, 30, 30);
+    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 15, 30);
+    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 8, 8, 34, 34);
+    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 10, 10, 30, 30);
 
     cairo_new_path (cr2);
 
@@ -288,7 +290,7 @@ draw (cairo_t *cr, int width, int height)
     cairo_save (cr2);
     cairo_arc (cr2, 250.0, 250.0, 157.0, 5.147, 3.432);
     cairo_set_line_width (cr2, 154.0);
-    errors += !check_extents (phase, cr2, STROKE, APPROX_EQUALS, 16, 38, 468, 446);
+    errors += !check_extents (ctx, phase, cr2, STROKE, APPROX_EQUALS, 16, 38, 468, 446);
     cairo_new_path (cr2);
     cairo_restore (cr2);
 
@@ -304,7 +306,7 @@ draw (cairo_t *cr, int width, int height)
 				    string,
 				    &scaled_font_extents);
     if (memcmp (&extents, &scaled_font_extents, sizeof (extents))) {
-	cairo_test_log ("Error: cairo_text_extents() does not match cairo_scaled_font_text_extents() - font extents (%f, %f) x (%f, %f) should be (%f, %f) x (%f, %f)\n",
+	cairo_test_log (ctx, "Error: cairo_text_extents() does not match cairo_scaled_font_text_extents() - font extents (%f, %f) x (%f, %f) should be (%f, %f) x (%f, %f)\n",
 		        scaled_font_extents.x_bearing,
 			scaled_font_extents.y_bearing,
 			scaled_font_extents.width,
@@ -322,11 +324,11 @@ draw (cairo_t *cr, int width, int height)
     /* XXX: We'd like to be able to use EQUALS here, but currently
      * when hinting is enabled freetype returns integer extents. See
      * http://cairographics.org/todo */
-    errors += !check_extents (phase, cr2, FILL, APPROX_EQUALS,
+    errors += !check_extents (ctx, phase, cr2, FILL, APPROX_EQUALS,
 			      0, 0, extents.width, extents.height);
-    errors += !check_extents (phase, cr2, STROKE, APPROX_EQUALS,
+    errors += !check_extents (ctx, phase, cr2, STROKE, APPROX_EQUALS,
 			      -1, -1, extents.width+2, extents.height+2);
-    errors += !check_extents (phase, cr2, PATH, APPROX_EQUALS,
+    errors += !check_extents (ctx, phase, cr2, PATH, APPROX_EQUALS,
 			      0, 0, extents.width, extents.height);
     cairo_new_path (cr2);
     cairo_restore (cr2);
@@ -335,9 +337,9 @@ draw (cairo_t *cr, int width, int height)
     cairo_save (cr2);
     cairo_scale (cr2, 2, 2);
     cairo_rectangle (cr2, 5, 5, 40, 40);
-    errors += !check_extents (phase, cr2, FILL, EQUALS, 5, 5, 40, 40);
-    errors += !check_extents (phase, cr2, STROKE, EQUALS, 0, 0, 50, 50);
-    errors += !check_extents (phase, cr2, PATH, EQUALS, 5, 5, 40, 40);
+    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 5, 5, 40, 40);
+    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 0, 0, 50, 50);
+    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 5, 5, 40, 40);
     cairo_new_path (cr2);
     cairo_restore (cr2);
 
@@ -347,9 +349,9 @@ draw (cairo_t *cr, int width, int height)
     cairo_scale (cr2, 2, 2);
     cairo_rectangle (cr2, 5, 5, 40, 40);
     cairo_restore (cr2);
-    errors += !check_extents (phase, cr2, FILL, EQUALS, 10, 10, 80, 80);
-    errors += !check_extents (phase, cr2, STROKE, EQUALS, 5, 5, 90, 90);
-    errors += !check_extents (phase, cr2, PATH, EQUALS, 10, 10, 80, 80);
+    errors += !check_extents (ctx, phase, cr2, FILL, EQUALS, 10, 10, 80, 80);
+    errors += !check_extents (ctx, phase, cr2, STROKE, EQUALS, 5, 5, 90, 90);
+    errors += !check_extents (ctx, phase, cr2, PATH, EQUALS, 10, 10, 80, 80);
     cairo_new_path (cr2);
     cairo_restore (cr2);
 
@@ -366,9 +368,9 @@ draw (cairo_t *cr, int width, int height)
        the axes. With the stroke width added to the rotated path,
        the largest axis-aligned square is a bit over 38 on either side of
        the axes. */
-    errors += !check_extents (phase, cr2, FILL, CONTAINS, -35, -35, 35, 35);
-    errors += !check_extents (phase, cr2, STROKE, CONTAINS, -38, -38, 38, 38);
-    errors += !check_extents (phase, cr2, PATH, CONTAINS, -35, -35, 35, 35);
+    errors += !check_extents (ctx, phase, cr2, FILL, CONTAINS, -35, -35, 35, 35);
+    errors += !check_extents (ctx, phase, cr2, STROKE, CONTAINS, -38, -38, 38, 38);
+    errors += !check_extents (ctx, phase, cr2, PATH, CONTAINS, -35, -35, 35, 35);
     cairo_new_path (cr2);
     cairo_restore (cr2);
 
diff --git a/test/get-xrender-format.c b/test/get-xrender-format.c
index 9dec1d9..fbb7d0c 100644
--- a/test/get-xrender-format.c
+++ b/test/get-xrender-format.c
@@ -34,37 +34,39 @@
 int
 main (void)
 {
+    cairo_test_context_t ctx;
     Display *dpy;
     XRenderPictFormat *orig_format, *format;
     cairo_surface_t *surface;
     Pixmap pixmap;
     int screen;
 
-    cairo_test_init ("get-xrender-format");
+    cairo_test_init (&ctx, "get-xrender-format");
 
     dpy = XOpenDisplay (NULL);
     if (! dpy) {
-	cairo_test_log ("Error: Cannot open display: %s.\n",
+	cairo_test_log (&ctx, "Error: Cannot open display: %s.\n",
 			XDisplayName (NULL));
-	cairo_test_fini ();
+	cairo_test_fini (&ctx);
 	return CAIRO_TEST_SUCCESS;
     }
 
     screen = DefaultScreen (dpy);
 
-    cairo_test_log ("Testing with image surface.\n");
+    cairo_test_log (&ctx, "Testing with image surface.\n");
 
     surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
 
     format = cairo_xlib_surface_get_xrender_format (surface);
     if (format != NULL) {
-	cairo_test_log ("Error: expected NULL for image surface\n");
+	cairo_test_log (&ctx, "Error: expected NULL for image surface\n");
+	cairo_test_fini (&ctx);
 	return CAIRO_TEST_FAILURE;
     }
 
     cairo_surface_destroy (surface);
 
-    cairo_test_log ("Testing with non-xrender xlib surface.\n");
+    cairo_test_log (&ctx, "Testing with non-xrender xlib surface.\n");
 
     pixmap = XCreatePixmap (dpy, DefaultRootWindow (dpy),
 			    1, 1, DefaultDepth (dpy, screen));
@@ -74,13 +76,14 @@ main (void)
     orig_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen));
     format = cairo_xlib_surface_get_xrender_format (surface);
     if (format != orig_format) {
-	cairo_test_log ("Error: did not receive the same format as XRenderFindVisualFormat\n");
+	cairo_test_log (&ctx, "Error: did not receive the same format as XRenderFindVisualFormat\n");
+	cairo_test_fini (&ctx);
 	return CAIRO_TEST_FAILURE;
     }
     cairo_surface_destroy (surface);
     XFreePixmap (dpy, pixmap);
 
-    cairo_test_log ("Testing with xlib xrender surface.\n");
+    cairo_test_log (&ctx, "Testing with xlib xrender surface.\n");
 
     orig_format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
     pixmap = XCreatePixmap (dpy, DefaultRootWindow (dpy),
@@ -92,17 +95,18 @@ main (void)
 							     1, 1);
     format = cairo_xlib_surface_get_xrender_format (surface);
     if (format != orig_format) {
-	cairo_test_log ("Error: did not receive the same format originally set\n");
+	cairo_test_log (&ctx, "Error: did not receive the same format originally set\n");
 	return CAIRO_TEST_FAILURE;
     }
 
-    cairo_test_log ("Testing without the X Render extension.\n");
+    cairo_test_log (&ctx, "Testing without the X Render extension.\n");
 
     cairo_boilerplate_xlib_surface_disable_render (surface);
 
     format = cairo_xlib_surface_get_xrender_format (surface);
     if (format != NULL) {
-	cairo_test_log ("Error: did not receive a NULL format as expected\n");
+	cairo_test_log (&ctx, "Error: did not receive a NULL format as expected\n");
+	cairo_test_fini (&ctx);
 	return CAIRO_TEST_FAILURE;
     }
 
@@ -110,9 +114,7 @@ main (void)
 
     XCloseDisplay (dpy);
 
-    cairo_debug_reset_static_data ();
-
-    cairo_test_fini ();
+    cairo_test_fini (&ctx);
 
     return CAIRO_TEST_SUCCESS;
 }
diff --git a/test/glyph-cache-pressure.c b/test/glyph-cache-pressure.c
index 72044ee..f0ab7d1 100644
--- a/test/glyph-cache-pressure.c
+++ b/test/glyph-cache-pressure.c
@@ -51,7 +51,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "glyph-cache-pressure",
     "Ensure that all backends behave well under artificial glyph cache pressure",
     223, TEXT_SIZE + 4,
diff --git a/test/gradient-alpha.c b/test/gradient-alpha.c
index 6b76247..38a282f 100644
--- a/test/gradient-alpha.c
+++ b/test/gradient-alpha.c
@@ -27,7 +27,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "gradient-alpha",
     "Tests drawing of a gradient with various alpha values in the color stops\n",
     10, 10,
diff --git a/test/gradient-zero-stops.c b/test/gradient-zero-stops.c
index 0cf145d..0605ed0 100644
--- a/test/gradient-zero-stops.c
+++ b/test/gradient-zero-stops.c
@@ -34,7 +34,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "gradient-zero-stops",
     "Verifies that gradients with no stops dont cause problems.",
     2, 2,
diff --git a/test/group-paint.c b/test/group-paint.c
index bfc23e4..1f6b1f6 100644
--- a/test/group-paint.c
+++ b/test/group-paint.c
@@ -27,16 +27,15 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "group-paint",
     "test push_group(); pop_group_to_source(); set_operator(SOURCE); paint();",
     10, 10,
     draw
 };
 
-
 static cairo_test_status_t
-draw (cairo_t *cr, int dst_width, int dst_height)
+draw (cairo_t *cr, int width, int height)
 {
     cairo_push_group (cr);
 
diff --git a/test/imagediff.c b/test/imagediff.c
index 188c1a9..c170c8e 100644
--- a/test/imagediff.c
+++ b/test/imagediff.c
@@ -54,7 +54,7 @@ main (int argc, char *argv[])
 	ax = ay = bx = by = 0;
     }
 
-    status = image_diff (argv[1], argv[2], NULL, ax, ay, bx, by, &result);
+    status = image_diff (NULL, argv[1], argv[2], NULL, ax, ay, bx, by, &result);
 
     if (status) {
 	fprintf (stderr, "Error comparing images: %s\n",
diff --git a/test/in-fill-empty-trapezoid.c b/test/in-fill-empty-trapezoid.c
index 45051f8..9d846a3 100644
--- a/test/in-fill-empty-trapezoid.c
+++ b/test/in-fill-empty-trapezoid.c
@@ -38,21 +38,26 @@
 int
 main (void)
 {
+    cairo_test_context_t ctx;
     int x,y;
     int width = 10;
     int height = 10;
-    cairo_surface_t *surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
-    cairo_t *cr = cairo_create (surf);
+    cairo_surface_t *surf;
+    cairo_t *cr;
     int false_positive_count = 0;
     cairo_status_t status;
     char const * description =
 	"Test that the tessellator isn't producing obviously empty trapezoids";
     cairo_test_status_t ret;
 
-    cairo_test_init ("in-fill-empty-trapezoid");
-    cairo_test_log ("%s\n", description);
+    cairo_test_init (&ctx, "in-fill-empty-trapezoid");
+    cairo_test_log (&ctx, "%s\n", description);
     printf ("%s\n", description);
 
+    surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+    cr = cairo_create (surf);
+    cairo_surface_destroy (surf);
+
     /* Empty horizontal trapezoid. */
     cairo_move_to (cr, 0, height/3);
     cairo_line_to (cr, width, height/3);
@@ -79,24 +84,23 @@ main (void)
 	}
     }
     cairo_destroy (cr);
-    cairo_surface_destroy (surf);
 
     /* Check that everything went well. */
     ret = CAIRO_TEST_SUCCESS;
     if (CAIRO_STATUS_SUCCESS != status) {
-	cairo_test_log ("Failed to create a test surface and path: %s\n",
+	cairo_test_log (&ctx, "Failed to create a test surface and path: %s\n",
 			cairo_status_to_string (status));
 	ret = CAIRO_TEST_FAILURE;
     }
 
     if (0 != false_positive_count) {
-	cairo_test_log ("Point sampling found %d false positives "
+	cairo_test_log (&ctx, "Point sampling found %d false positives "
 			"from cairo_in_fill()\n",
 			false_positive_count);
 	ret = CAIRO_TEST_FAILURE;
     }
 
-    cairo_test_fini ();
+    cairo_test_fini (&ctx);
 
     return ret;
 }
diff --git a/test/in-fill-trapezoid.c b/test/in-fill-trapezoid.c
index a544e43..c44ffb8 100644
--- a/test/in-fill-trapezoid.c
+++ b/test/in-fill-trapezoid.c
@@ -28,7 +28,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "in-fill-trapezoid",
     "Test _cairo_trap_contains via cairo_in_fill",
     0, 0,
@@ -38,6 +38,7 @@ cairo_test_t test = {
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     cairo_test_status_t ret = CAIRO_TEST_SUCCESS;
 
     cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
@@ -46,7 +47,7 @@ draw (cairo_t *cr, int width, int height)
     cairo_new_path (cr);
     cairo_rectangle (cr, -10, -10, 20, 20);
     if (! cairo_in_fill (cr, 0, 0)) {
-	cairo_test_log ("Error: Failed to find point inside rectangle\n");
+	cairo_test_log (ctx, "Error: Failed to find point inside rectangle\n");
 	ret = CAIRO_TEST_FAILURE;
     }
 
@@ -54,7 +55,7 @@ draw (cairo_t *cr, int width, int height)
     cairo_new_path (cr);
     cairo_arc (cr, 0, 0, 10, 0, 2 * M_PI);
     if (! cairo_in_fill (cr, 0, 0)) {
-	cairo_test_log ("Error: Failed to find point inside circle\n");
+	cairo_test_log (ctx, "Error: Failed to find point inside circle\n");
 	ret = CAIRO_TEST_FAILURE;
     }
 
@@ -63,7 +64,7 @@ draw (cairo_t *cr, int width, int height)
     cairo_rectangle (cr, -10, -10, 20, 20);
     cairo_rectangle (cr, -5, -5, 10, 10);
     if (cairo_in_fill (cr, 0, 0)) {
-	cairo_test_log ("Error: Found an unexpected point inside rectangular hole\n");
+	cairo_test_log (ctx, "Error: Found an unexpected point inside rectangular hole\n");
 	ret = CAIRO_TEST_FAILURE;
     }
 
@@ -72,7 +73,7 @@ draw (cairo_t *cr, int width, int height)
     cairo_arc (cr, 0, 0, 10, 0, 2 * M_PI);
     cairo_arc (cr, 0, 0, 5, 0, 2 * M_PI);
     if (cairo_in_fill (cr, 0, 0)) {
-	cairo_test_log ("Error: Found an unexpected point inside circular hole\n");
+	cairo_test_log (ctx, "Error: Found an unexpected point inside circular hole\n");
 	ret = CAIRO_TEST_FAILURE;
     }
 
diff --git a/test/infinite-join.c b/test/infinite-join.c
index 74d4206..c2c728f 100644
--- a/test/infinite-join.c
+++ b/test/infinite-join.c
@@ -35,7 +35,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "infinite-join",
     "Test case for infinite loop when stroking with round joins",
     8, 8,
diff --git a/test/invalid-matrix.c b/test/invalid-matrix.c
index c25197f..8db3df1 100644
--- a/test/invalid-matrix.c
+++ b/test/invalid-matrix.c
@@ -36,7 +36,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "invalid-matrix",
     "Test that all relevant public functions return CAIRO_STATUS_INVALID_MATRIX as appropriate",
     0, 0,
@@ -46,6 +46,7 @@ cairo_test_t test = {
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     cairo_status_t status;
     cairo_surface_t *target;
     cairo_font_face_t *font_face;
@@ -61,11 +62,11 @@ draw (cairo_t *cr, int width, int height)
 
 #define CHECK_STATUS(status, function_name)						\
 if ((status) == CAIRO_STATUS_SUCCESS) {							\
-    cairo_test_log ("Error: %s with invalid matrix passed\n",				\
+    cairo_test_log (ctx, "Error: %s with invalid matrix passed\n",				\
 		    (function_name));							\
     return CAIRO_TEST_FAILURE;								\
 } else if ((status) != CAIRO_STATUS_INVALID_MATRIX) {					\
-    cairo_test_log ("Error: %s with invalid matrix returned unexpected status "	\
+    cairo_test_log (ctx, "Error: %s with invalid matrix returned unexpected status "	\
 		    "(%d): %s\n",							\
 		    (function_name),							\
 		    status,								\
diff --git a/test/large-clip.c b/test/large-clip.c
index 3fccaf8..02fa93a 100644
--- a/test/large-clip.c
+++ b/test/large-clip.c
@@ -29,7 +29,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "large-clip",
     "Incorrect clipping when the clip rectangle doesn't fit in 16 bits signed",
     SIZE, SIZE,
diff --git a/test/large-font.c b/test/large-font.c
index 85c135d..63418e1 100644
--- a/test/large-font.c
+++ b/test/large-font.c
@@ -47,7 +47,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "large-font",
     "Draws a very large font to exercise a glyph-positioning bug",
     WIDTH, HEIGHT,
@@ -57,8 +57,6 @@ cairo_test_t test = {
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
-    cairo_font_options_t *font_options;
-
     /* paint white so we don't need separate ref images for
      * RGB24 and ARGB32 */
     cairo_set_source_rgb (cr, 1., 1., 1.);
diff --git a/test/large-source.c b/test/large-source.c
index c4781d0..1756424 100644
--- a/test/large-source.c
+++ b/test/large-source.c
@@ -37,7 +37,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "large-source",
     "Exercises mozilla bug 424333 - handling of massive images",
     20, 20,
diff --git a/test/leaky-dash.c b/test/leaky-dash.c
index d78fac5..2a76715 100644
--- a/test/leaky-dash.c
+++ b/test/leaky-dash.c
@@ -36,7 +36,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "leaky-dash",
     "Exercises bug #4863 in which a dashed stroke leaks into half the rectangle being filled"
     "\nknown bug (#4863) which has existed since the 1.0 release",
diff --git a/test/leaky-dashed-rectangle.c b/test/leaky-dashed-rectangle.c
index 0d9e246..5a867a4 100644
--- a/test/leaky-dashed-rectangle.c
+++ b/test/leaky-dashed-rectangle.c
@@ -35,7 +35,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "leaky-dashed-rectangle",
     "Exercises bug in which a dashed stroke leaks in from outside the surface",
     WIDTH, HEIGHT,
diff --git a/test/leaky-polygon.c b/test/leaky-polygon.c
index 2526860..fbe7475 100644
--- a/test/leaky-polygon.c
+++ b/test/leaky-polygon.c
@@ -58,7 +58,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "leaky-polygon",
     "Exercises a corner case in the trapezoid rasterization in which pixels outside the trapezoids received a non-zero alpha",
     WIDTH, HEIGHT,
diff --git a/test/line-width-scale.c b/test/line-width-scale.c
index eada6c6..523b7d1 100644
--- a/test/line-width-scale.c
+++ b/test/line-width-scale.c
@@ -54,7 +54,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "line-width-scale",
     "Tests interaction of cairo_set_line_width with cairo_scale",
     WIDTH, HEIGHT,
@@ -158,8 +158,7 @@ static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
     int i;
-    typedef void (*figure_t) (cairo_t *cr);
-    figure_t figures[4] = {
+    void (* const figures[4]) (cairo_t *cr) = {
 	scale_then_set_line_width_and_stroke,
 	scale_path_and_line_width,
 	set_line_width_then_scale_and_stroke,
diff --git a/test/line-width-zero.c b/test/line-width-zero.c
index 139a471..449f435 100644
--- a/test/line-width-zero.c
+++ b/test/line-width-zero.c
@@ -35,7 +35,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "line-width-zero",
     "Test all stroke operations and all cap,join styles with line width of zero",
     0, 0,
diff --git a/test/line-width.c b/test/line-width.c
index ad51c74..b1e31ff 100644
--- a/test/line-width.c
+++ b/test/line-width.c
@@ -32,7 +32,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "line-width",
     "Tests cairo_set_line_width",
     IMAGE_WIDTH, IMAGE_HEIGHT,
diff --git a/test/linear-gradient-reflect.c b/test/linear-gradient-reflect.c
index 779ccd8..0f0dea6 100644
--- a/test/linear-gradient-reflect.c
+++ b/test/linear-gradient-reflect.c
@@ -32,7 +32,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "linear-gradient-reflect",
     "Tests the drawing of linear gradient with reflect",
     WIDTH, HEIGHT,
diff --git a/test/linear-gradient.c b/test/linear-gradient.c
index 3dad477..166f643 100644
--- a/test/linear-gradient.c
+++ b/test/linear-gradient.c
@@ -56,7 +56,7 @@ static const int n_stops[] = { 2, 3 };
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "linear-gradient",
     "Tests the drawing of linear gradients\n",
     WIDTH, HEIGHT,
@@ -84,7 +84,7 @@ draw_unit (cairo_t *cr,
     cairo_rotate (cr, rotate_angle);
 
     pattern = cairo_pattern_create_linear (-0.5 * cos (gradient_angle),  -0.5 * sin (gradient_angle),
- 					    0.5 * cos (gradient_angle),   0.5 * sin (gradient_angle));
+					    0.5 * cos (gradient_angle),   0.5 * sin (gradient_angle));
 
     if (n_stops == 2) {
 	cairo_pattern_add_color_stop_rgb (pattern, 0.,
diff --git a/test/long-dashed-lines.c b/test/long-dashed-lines.c
index fce6d79..788951c 100644
--- a/test/long-dashed-lines.c
+++ b/test/long-dashed-lines.c
@@ -27,7 +27,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "long-dashed-lines",
     "Exercises _cairo_box_intersects_line_segment()",
     60, 60,
@@ -72,4 +72,3 @@ main (void)
 {
     return cairo_test (&test);
 }
-
diff --git a/test/long-lines.c b/test/long-lines.c
index 8b189b2..dfbbe0d 100644
--- a/test/long-lines.c
+++ b/test/long-lines.c
@@ -21,18 +21,18 @@
  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
  * Authors: Carl D. Worth <cworth at cworth.org>
- * 	    Emmanuel Pacaud <emmanuel.pacaud at lapp.in2p3.fr>
+ *	    Emmanuel Pacaud <emmanuel.pacaud at lapp.in2p3.fr>
  */
 
 #include "cairo-test.h"
 
-#define LINE_WIDTH 	1.
-#define SIZE 		10
+#define LINE_WIDTH	1.
+#define SIZE		10
 #define LINE_NBR	6
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "long-lines",
     "Test long lines"
     "\nLong lines are not drawn due to the limitations of the internal 16.16 fixed-point coordinates",
@@ -45,12 +45,12 @@ struct {
     double length;
     double red, green, blue;
 } lines[LINE_NBR] = {
-    {      100.0, 1.0, 0.0, 0.0 },
-    {    10000.0, 0.0, 1.0, 0.0 },
-    {   100000.0, 0.0, 0.0, 1.0 },
-    {  1000000.0, 1.0, 1.0, 0.0 },
-    { 10000000.0, 0.0, 1.0, 1.0 },
-    {100000000.0, 1.0, 0.0, 1.0 }
+    {       100.0, 1.0, 0.0, 0.0 },
+    {     10000.0, 0.0, 1.0, 0.0 },
+    {    100000.0, 0.0, 0.0, 1.0 },
+    {   1000000.0, 1.0, 1.0, 0.0 },
+    {  10000000.0, 0.0, 1.0, 1.0 },
+    { 100000000.0, 1.0, 0.0, 1.0 }
 };
 
 static cairo_test_status_t
@@ -65,7 +65,6 @@ draw (cairo_t *cr, int width, int height)
     cairo_paint (cr);
     cairo_restore (cr);
 
-
     cairo_set_line_width (cr, LINE_WIDTH);
 
     pos = SIZE + .5;
diff --git a/test/mask-alpha.c b/test/mask-alpha.c
index de5394d..284e2cb 100644
--- a/test/mask-alpha.c
+++ b/test/mask-alpha.c
@@ -41,7 +41,7 @@ static cairo_test_draw_function_t draw;
  * (0.8, 0.8, 0.8, 0.4).
  */
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "mask-alpha",
     "A simple test painting a group through a circle mask",
     WIDTH, HEIGHT,
diff --git a/test/mask-ctm.c b/test/mask-ctm.c
index d693990..c6814b0 100644
--- a/test/mask-ctm.c
+++ b/test/mask-ctm.c
@@ -27,7 +27,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "mask-ctm",
     "Test that cairo_mask is affected properly by the CTM",
     10, 10,
@@ -39,7 +39,7 @@ draw (cairo_t *cr, int width, int height)
 {
     cairo_surface_t *mask_surface;
     cairo_pattern_t *mask;
-    static uint32_t data[] = {
+    uint32_t data[] = {
 	0x80000000, 0x80000000,
 	0x80000000, 0x80000000,
     };
diff --git a/test/mask-surface-ctm.c b/test/mask-surface-ctm.c
index 02384c6..f4a0c39 100644
--- a/test/mask-surface-ctm.c
+++ b/test/mask-surface-ctm.c
@@ -27,7 +27,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "mask-surface-ctm",
     "Test that cairo_mask_surface is affected properly by the CTM",
     10, 10,
@@ -38,7 +38,7 @@ static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
     cairo_surface_t *mask;
-    static uint32_t data[] = {
+    uint32_t data[] = {
 	0x80000000, 0x80000000,
 	0x80000000, 0x80000000,
     };
diff --git a/test/mask.c b/test/mask.c
index 14dd8b3..711c3eb 100644
--- a/test/mask.c
+++ b/test/mask.c
@@ -32,22 +32,22 @@
 #define HEIGHT 16
 #define PAD 2
 
-const char	png_filename[]	= "romedalen.png";
+static const char	png_filename[]	= "romedalen.png";
 
 static void
-set_solid_pattern (cairo_t *cr, int x, int y)
+set_solid_pattern (const cairo_test_context_t *ctx, cairo_t *cr, int x, int y)
 {
     cairo_set_source_rgb (cr, 0, 0, 0.6);
 }
 
 static void
-set_translucent_pattern (cairo_t *cr, int x, int y)
+set_translucent_pattern (const cairo_test_context_t *ctx, cairo_t *cr, int x, int y)
 {
     cairo_set_source_rgba (cr, 0, 0, 0.6, 0.5);
 }
 
 static void
-set_gradient_pattern (cairo_t *cr, int x, int y)
+set_gradient_pattern (const cairo_test_context_t *ctx, cairo_t *cr, int x, int y)
 {
     cairo_pattern_t *pattern;
 
@@ -60,11 +60,11 @@ set_gradient_pattern (cairo_t *cr, int x, int y)
 }
 
 static void
-set_image_pattern (cairo_t *cr, int x, int y)
+set_image_pattern (const cairo_test_context_t *ctx, cairo_t *cr, int x, int y)
 {
     cairo_pattern_t *pattern;
 
-    pattern = cairo_test_create_pattern_from_png (png_filename);
+    pattern = cairo_test_create_pattern_from_png (ctx, png_filename);
     cairo_set_source (cr, pattern);
     cairo_pattern_destroy (pattern);
 }
@@ -156,20 +156,20 @@ clip_circle (cairo_t *cr, int x, int y)
     cairo_new_path (cr);
 }
 
-static void (*pattern_funcs[])(cairo_t *cr, int x, int y) = {
+static void (* const pattern_funcs[])(const cairo_test_context_t *ctx, cairo_t *cr, int x, int y) = {
     set_solid_pattern,
     set_translucent_pattern,
     set_gradient_pattern,
     set_image_pattern,
 };
 
-static void (*mask_funcs[])(cairo_t *cr, int x, int y) = {
+static void (* const mask_funcs[])(cairo_t *cr, int x, int y) = {
     mask_alpha,
     mask_gradient,
     mask_polygon,
 };
 
-static void (*clip_funcs[])(cairo_t *cr, int x, int y) = {
+static void (* const clip_funcs[])(cairo_t *cr, int x, int y) = {
     clip_none,
     clip_rects,
     clip_circle,
@@ -181,7 +181,7 @@ static void (*clip_funcs[])(cairo_t *cr, int x, int y) = {
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "mask",
     "Tests of cairo_mask",
     IMAGE_WIDTH, IMAGE_HEIGHT,
@@ -191,6 +191,7 @@ cairo_test_t test = {
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     cairo_surface_t *tmp_surface;
     cairo_pattern_t *tmp_pattern;
     size_t i, j, k;
@@ -225,7 +226,7 @@ draw (cairo_t *cr, int width, int height)
 		cairo_save (cr2);
 
 		clip_funcs[k] (cr2, x, y);
-		pattern_funcs[i] (cr2, x, y);
+		pattern_funcs[i] (ctx, cr2, x, y);
 		mask_funcs[j] (cr2, x, y);
 
 		cairo_restore (cr2);
diff --git a/test/meta-surface-pattern.c b/test/meta-surface-pattern.c
index a047b3e..58f05b4 100644
--- a/test/meta-surface-pattern.c
+++ b/test/meta-surface-pattern.c
@@ -40,14 +40,13 @@ static cairo_test_draw_function_t draw;
  * CAIRO_EXTEND_NONE and a non identity pattern matrix.
  */
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "meta-surface-pattern",
     "Paint meta surface pattern with non identity pattern matrix",
     WIDTH, HEIGHT,
     draw
 };
 
-
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
diff --git a/test/miter-precision.c b/test/miter-precision.c
index 533c30e..2720677 100644
--- a/test/miter-precision.c
+++ b/test/miter-precision.c
@@ -35,7 +35,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "miter-precision",
     "test how cairo deals with small miters"
     "\ncurrent code draws inappropriate bevels at times",
@@ -49,7 +49,7 @@ draw (cairo_t *cr, int width, int height)
     double  xscale, yscale;
     cairo_set_source_rgb (cr, 1, 1, 1);
     cairo_paint (cr);
-    
+
     cairo_set_source_rgb (cr, 0, 0, 0);
     cairo_set_miter_limit (cr, 100000);
     for (xscale = 1; xscale <= 1000; xscale += 999)
@@ -69,7 +69,7 @@ draw (cairo_t *cr, int width, int height)
 	    cairo_stroke (cr);
 	    cairo_restore (cr);
 	}
-    
+
     return CAIRO_TEST_SUCCESS;
 }
 
diff --git a/test/move-to-show-surface.c b/test/move-to-show-surface.c
index 8693207..e017fa6 100644
--- a/test/move-to-show-surface.c
+++ b/test/move-to-show-surface.c
@@ -47,7 +47,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "move-to-show-surface",
     "Tests calls to cairo_show_surface after cairo_move_to",
     2, 2,
diff --git a/test/multi-page.c b/test/multi-page.c
index f0265e2..4e0749a 100644
--- a/test/multi-page.c
+++ b/test/multi-page.c
@@ -130,11 +130,13 @@ draw_some_pages (cairo_surface_t *surface)
 int
 main (void)
 {
+    cairo_test_context_t ctx;
     cairo_surface_t *surface;
     cairo_status_t status;
     const char *filename;
+    cairo_test_status_t result = CAIRO_TEST_SUCCESS;
 
-    cairo_test_init ("multi-page");
+    cairo_test_init (&ctx, "multi-page");
 
 #if CAIRO_HAS_PS_SURFACE
     filename = "multi-page.ps";
@@ -143,9 +145,9 @@ main (void)
 				       WIDTH_IN_POINTS, HEIGHT_IN_POINTS);
     status = cairo_surface_status (surface);
     if (status) {
-	cairo_test_log ("Failed to create ps surface for file %s: %s\n",
+	cairo_test_log (&ctx, "Failed to create ps surface for file %s: %s\n",
 			filename, cairo_status_to_string (status));
-	return CAIRO_TEST_FAILURE;
+	result = CAIRO_TEST_FAILURE;
     }
 
     draw_some_pages (surface);
@@ -162,9 +164,9 @@ main (void)
 					WIDTH_IN_POINTS, HEIGHT_IN_POINTS);
     status = cairo_surface_status (surface);
     if (status) {
-	cairo_test_log ("Failed to create pdf surface for file %s: %s\n",
+	cairo_test_log (&ctx, "Failed to create pdf surface for file %s: %s\n",
 			filename, cairo_status_to_string (status));
-	return CAIRO_TEST_FAILURE;
+	result = CAIRO_TEST_FAILURE;
     }
 
     draw_some_pages (surface);
@@ -174,7 +176,7 @@ main (void)
     printf ("multi-page: Please check %s to ensure it looks happy.\n", filename);
 #endif
 
-    cairo_test_fini ();
+    cairo_test_fini (&ctx);
 
-    return CAIRO_TEST_SUCCESS;
+    return result;
 }
diff --git a/test/new-sub-path.c b/test/new-sub-path.c
index 93580ce..19beaed 100644
--- a/test/new-sub-path.c
+++ b/test/new-sub-path.c
@@ -29,7 +29,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "new-sub-path",
     "Test the cairo_new_sub_path call",
     8 * SIZE,
diff --git a/test/nil-surface.c b/test/nil-surface.c
index 91f1aa6..b2070fe 100644
--- a/test/nil-surface.c
+++ b/test/nil-surface.c
@@ -35,7 +35,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "nil-surface",
     "Test that nil surfaces do not make cairo crash.",
     1, 1,
@@ -45,6 +45,7 @@ cairo_test_t test = {
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     cairo_surface_t *surface;
     cairo_pattern_t *pattern;
     cairo_t *cr2;
@@ -71,7 +72,7 @@ draw (cairo_t *cr, int width, int height)
 
     /* Check that the error made it all that way. */
     if (cairo_status (cr2) != CAIRO_STATUS_FILE_NOT_FOUND) {
-	cairo_test_log ("Error: Received status of \"%s\" rather than expected \"%s\"\n",
+	cairo_test_log (ctx, "Error: Received status of \"%s\" rather than expected \"%s\"\n",
 			cairo_status_to_string (cairo_status (cr2)),
 			cairo_status_to_string (CAIRO_STATUS_FILE_NOT_FOUND));
 	cairo_destroy (cr2);
@@ -96,7 +97,7 @@ draw (cairo_t *cr, int width, int height)
 
     /* Check that the error made it all that way. */
     if (cairo_status (cr2) != CAIRO_STATUS_NULL_POINTER) {
-	cairo_test_log ("Error: Received status of \"%s\" rather than expected \"%s\"\n",
+	cairo_test_log (ctx, "Error: Received status of \"%s\" rather than expected \"%s\"\n",
 			cairo_status_to_string (cairo_status (cr2)),
 			cairo_status_to_string (CAIRO_STATUS_NULL_POINTER));
 	cairo_destroy (cr2);
@@ -127,7 +128,7 @@ draw (cairo_t *cr, int width, int height)
     /* Trigger invalid restore. */
     cairo_restore (cr2);
     if (cairo_status (cr2) != CAIRO_STATUS_INVALID_RESTORE) {
-	cairo_test_log ("Error: Received status of \"%s\" rather than expected \"%s\"\n",
+	cairo_test_log (ctx, "Error: Received status of \"%s\" rather than expected \"%s\"\n",
 			cairo_status_to_string (cairo_status (cr2)),
 			cairo_status_to_string (CAIRO_STATUS_INVALID_RESTORE));
 	cairo_destroy (cr2);
@@ -145,7 +146,7 @@ draw (cairo_t *cr, int width, int height)
     cr2 = cairo_create (NULL);
 
     if (cairo_status (cr2) != CAIRO_STATUS_NULL_POINTER) {
-	cairo_test_log ("Error: Received status of \"%s\" rather than expected \"%s\"\n",
+	cairo_test_log (ctx, "Error: Received status of \"%s\" rather than expected \"%s\"\n",
 			cairo_status_to_string (cairo_status (cr2)),
 			cairo_status_to_string (CAIRO_STATUS_NULL_POINTER));
 	cairo_destroy (cr2);
@@ -154,7 +155,7 @@ draw (cairo_t *cr, int width, int height)
 
     /* Test that get_target returns something valid */
     if (cairo_get_target (cr2) == NULL) {
-	cairo_test_log ("Error: cairo_get_target() returned NULL\n");
+	cairo_test_log (ctx, "Error: cairo_get_target() returned NULL\n");
 	cairo_destroy (cr2);
 	return CAIRO_TEST_FAILURE;
     }
diff --git a/test/operator-clear.c b/test/operator-clear.c
index e6cb042..f1eb322 100644
--- a/test/operator-clear.c
+++ b/test/operator-clear.c
@@ -128,12 +128,12 @@ draw_rects (cairo_t *cr, int x, int y)
     cairo_fill (cr);
 }
 
-static void (*pattern_funcs[])(cairo_t *cr, int x, int y) = {
+static void (* const pattern_funcs[])(cairo_t *cr, int x, int y) = {
     set_solid_pattern,
     set_gradient_pattern,
 };
 
-static void (*draw_funcs[])(cairo_t *cr, int x, int y) = {
+static void (* const draw_funcs[])(cairo_t *cr, int x, int y) = {
     draw_mask,
     draw_glyphs,
     draw_polygon,
@@ -146,7 +146,7 @@ static void (*draw_funcs[])(cairo_t *cr, int x, int y) = {
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "operator-clear",
     "Test of CAIRO_OPERATOR_CLEAR",
     IMAGE_WIDTH, IMAGE_HEIGHT,
@@ -156,6 +156,7 @@ cairo_test_t test = {
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     size_t i, j, x, y;
     cairo_pattern_t *pattern;
 
@@ -187,14 +188,14 @@ draw (cairo_t *cr, int width, int height)
 	    pattern_funcs[i] (cr, x, y);
 	    draw_funcs[j] (cr, x, y);
 	    if (cairo_status (cr))
-		cairo_test_log ("%d %d HERE!\n", (int)i, (int)j);
+		cairo_test_log (ctx, "%d %d HERE!\n", (int)i, (int)j);
 
 	    cairo_restore (cr);
 	}
     }
 
     if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
-	cairo_test_log ("%d %d .HERE!\n", (int)i, (int)j);
+	cairo_test_log (ctx, "%d %d .HERE!\n", (int)i, (int)j);
 
     return CAIRO_TEST_SUCCESS;
 }
diff --git a/test/operator-source.c b/test/operator-source.c
index e63bcea..882723e 100644
--- a/test/operator-source.c
+++ b/test/operator-source.c
@@ -165,14 +165,14 @@ draw_rects (cairo_t *cr, int x, int y)
     cairo_fill (cr);
 }
 
-static void (*pattern_funcs[])(cairo_t *cr, int x, int y) = {
+static void (* const pattern_funcs[])(cairo_t *cr, int x, int y) = {
     set_solid_pattern,
     set_translucent_pattern,
     set_gradient_pattern,
     set_surface_pattern,
 };
 
-static void (*draw_funcs[])(cairo_t *cr, int x, int y) = {
+static void (* const draw_funcs[])(cairo_t *cr, int x, int y) = {
     draw_mask,
     draw_glyphs,
     draw_polygon,
@@ -185,7 +185,7 @@ static void (*draw_funcs[])(cairo_t *cr, int x, int y) = {
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "operator-source",
     "Test of CAIRO_OPERATOR_SOURCE",
     IMAGE_WIDTH, IMAGE_HEIGHT,
@@ -195,6 +195,7 @@ cairo_test_t test = {
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     size_t i, j, x, y;
     cairo_pattern_t *pattern;
 
@@ -226,14 +227,14 @@ draw (cairo_t *cr, int width, int height)
 	    pattern_funcs[i] (cr, x, y);
 	    draw_funcs[j] (cr, x, y);
 	    if (cairo_status (cr))
-		cairo_test_log ("%d %d HERE!\n", (int)i, (int)j);
+		cairo_test_log (ctx, "%d %d HERE!\n", (int)i, (int)j);
 
 	    cairo_restore (cr);
 	}
     }
 
     if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
-	cairo_test_log ("%d %d .HERE!\n", (int)i, (int)j);
+	cairo_test_log (ctx, "%d %d .HERE!\n", (int)i, (int)j);
 
     return CAIRO_TEST_SUCCESS;
 }
diff --git a/test/over-above-source.c b/test/over-above-source.c
index 8999e4a..928fb36 100644
--- a/test/over-above-source.c
+++ b/test/over-above-source.c
@@ -39,7 +39,7 @@ static cairo_test_draw_function_t draw;
  * surface, it's the reverse where OVER is native while SOURCE is a
  * fallback. */
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "over-above-source",
     "A simple test drawing a circle with OVER after a triangle drawn with SOURCE",
     WIDTH, HEIGHT,
diff --git a/test/over-around-source.c b/test/over-around-source.c
index e98c187..030e42d 100644
--- a/test/over-around-source.c
+++ b/test/over-around-source.c
@@ -39,7 +39,7 @@ static cairo_test_draw_function_t draw;
  * surface, it's the reverse where OVER is native while SOURCE is a
  * fallback. */
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "over-around-source",
     "A simple test drawing a triangle with SOURCE between two circles drawn with OVER",
     WIDTH, HEIGHT,
diff --git a/test/over-below-source.c b/test/over-below-source.c
index df7e7d1..74dac6f 100644
--- a/test/over-below-source.c
+++ b/test/over-below-source.c
@@ -39,7 +39,7 @@ static cairo_test_draw_function_t draw;
  * surface, it's the reverse where OVER is native while SOURCE is a
  * fallback. */
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "over-below-source",
     "A simple test drawing a circle with OVER before a triangle drawn with SOURCE",
     WIDTH, HEIGHT,
diff --git a/test/over-between-source.c b/test/over-between-source.c
index 9c60bbd..f88b6cc 100644
--- a/test/over-between-source.c
+++ b/test/over-between-source.c
@@ -39,7 +39,7 @@ static cairo_test_draw_function_t draw;
  * surface, it's the reverse where OVER is native while SOURCE is a
  * fallback. */
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "over-between-source",
     "A simple test drawing a circle with OVER between two triangles drawn with SOURCE",
     WIDTH, HEIGHT,
diff --git a/test/paint-repeat.c b/test/paint-repeat.c
index 892cbf8..8e7f4ab 100644
--- a/test/paint-repeat.c
+++ b/test/paint-repeat.c
@@ -27,7 +27,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "paint-repeat",
     "Test calls to cairo_paint with a repeating source surface pattern",
     8, 8,
@@ -38,7 +38,7 @@ static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
     cairo_surface_t *surface;
-    static uint32_t data[16] = {
+    uint32_t data[16] = {
 	0xffffffff, 0xffffffff,		0xffff0000, 0xffff0000,
 	0xffffffff, 0xffffffff,		0xffff0000, 0xffff0000,
 
diff --git a/test/paint-source-alpha.c b/test/paint-source-alpha.c
index 36a158b..764b744 100644
--- a/test/paint-source-alpha.c
+++ b/test/paint-source-alpha.c
@@ -28,7 +28,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "paint-source-alpha",
     "Simple test of cairo_paint with a source surface with non-opaque alpha",
     32, 32,
@@ -39,7 +39,7 @@ static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
     cairo_surface_t *surface;
-    static uint32_t data[16] = {
+    uint32_t data[16] = {
 	0x80808080, 0x80808080,		0x80800000, 0x80800000,
 	0x80808080, 0x80808080,		0x80800000, 0x80800000,
 
diff --git a/test/paint-with-alpha.c b/test/paint-with-alpha.c
index 864b956..adfb7ce 100644
--- a/test/paint-with-alpha.c
+++ b/test/paint-with-alpha.c
@@ -28,7 +28,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "paint-with-alpha",
     "Simple test of cairo_paint_with_alpha",
     32, 32,
@@ -39,7 +39,7 @@ static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
     cairo_surface_t *surface;
-    static uint32_t data[16] = {
+    uint32_t data[16] = {
 	0xffffffff, 0xffffffff,		0xffff0000, 0xffff0000,
 	0xffffffff, 0xffffffff,		0xffff0000, 0xffff0000,
 
diff --git a/test/paint.c b/test/paint.c
index 0149db6..6f5ecf2 100644
--- a/test/paint.c
+++ b/test/paint.c
@@ -27,7 +27,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "paint",
     "Test calls to cairo_paint",
     8, 8,
diff --git a/test/pattern-get-type.c b/test/pattern-get-type.c
index d64dd88..96ed0c9 100644
--- a/test/pattern-get-type.c
+++ b/test/pattern-get-type.c
@@ -28,12 +28,13 @@
 int
 main (void)
 {
+    cairo_test_context_t ctx;
     cairo_surface_t *surface;
     cairo_pattern_t *solid_rgb, *solid_rgba, *surface_pattern, *linear, *radial;
+    cairo_test_status_t result = CAIRO_TEST_SUCCESS;
 
-    cairo_test_init ("pattern-get-type");
-
-    cairo_test_log ("Creating patterns of all types\n");
+    cairo_test_init (&ctx, "pattern-get-type");
+    cairo_test_log (&ctx, "Creating patterns of all types\n");
 
     solid_rgb = cairo_pattern_create_rgb (0.0, 0.1, 0.2);
     solid_rgba = cairo_pattern_create_rgba (0.3, 0.4, 0.5, 0.6);
@@ -44,24 +45,24 @@ main (void)
     radial = cairo_pattern_create_radial (10.0, 10.0, 0.1,
 					  10.0, 10.0, 1.0);
 
-    cairo_test_log ("Verifying return values of cairo_pattern_get_type\n");
+    cairo_test_log (&ctx, "Verifying return values of cairo_pattern_get_type\n");
 
     if (cairo_pattern_get_type (solid_rgb) != CAIRO_PATTERN_TYPE_SOLID)
-	return CAIRO_TEST_FAILURE;
+	result = CAIRO_TEST_FAILURE;
 
     if (cairo_pattern_get_type (solid_rgba) != CAIRO_PATTERN_TYPE_SOLID)
-	return CAIRO_TEST_FAILURE;
+	result = CAIRO_TEST_FAILURE;
 
     if (cairo_pattern_get_type (surface_pattern) != CAIRO_PATTERN_TYPE_SURFACE)
-	return CAIRO_TEST_FAILURE;
+	result = CAIRO_TEST_FAILURE;
 
     if (cairo_pattern_get_type (linear) != CAIRO_PATTERN_TYPE_LINEAR)
-	return CAIRO_TEST_FAILURE;
+	result = CAIRO_TEST_FAILURE;
 
     if (cairo_pattern_get_type (radial) != CAIRO_PATTERN_TYPE_RADIAL)
-	return CAIRO_TEST_FAILURE;
+	result = CAIRO_TEST_FAILURE;
 
-    cairo_test_log ("Cleaning up\n");
+    cairo_test_log (&ctx, "Cleaning up\n");
 
     cairo_pattern_destroy (solid_rgb);
     cairo_pattern_destroy (solid_rgba);
@@ -70,7 +71,7 @@ main (void)
     cairo_pattern_destroy (linear);
     cairo_pattern_destroy (radial);
 
-    cairo_test_fini ();
+    cairo_test_fini (&ctx);
 
-    return CAIRO_TEST_SUCCESS;
+    return result;
 }
diff --git a/test/pattern-getters.c b/test/pattern-getters.c
index aa420bf..a42d47b 100644
--- a/test/pattern-getters.c
+++ b/test/pattern-getters.c
@@ -29,7 +29,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "pattern-getters",
     "Tests calls to pattern getter functions",
     1, 1,
@@ -39,12 +39,12 @@ cairo_test_t test = {
 #define CHECK_SUCCESS do { if (status) return CAIRO_TEST_FAILURE; } while (0)
 
 static int
-double_buf_equal (double *a, double *b, int nc)
+double_buf_equal (const cairo_test_context_t *ctx, double *a, double *b, int nc)
 {
     int i;
     for (i = 0; i < nc; i++) {
 	if (!CAIRO_TEST_DOUBLE_EQUALS(a[i],b[i])) {
-	    cairo_test_log ("Error: doubles not equal: %g, %g\n",
+	    cairo_test_log (ctx, "Error: doubles not equal: %g, %g\n",
 			    a[i], b[i]);
 	    return 0;
 	}
@@ -55,6 +55,7 @@ double_buf_equal (double *a, double *b, int nc)
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     cairo_status_t status;
     cairo_pattern_t *pat;
 
@@ -70,7 +71,7 @@ draw (cairo_t *cr, int width, int height)
 	    !CAIRO_TEST_DOUBLE_EQUALS(g,0.3) ||
 	    !CAIRO_TEST_DOUBLE_EQUALS(b,0.4) ||
 	    !CAIRO_TEST_DOUBLE_EQUALS(a,0.5)) {
-	    cairo_test_log ("Error: cairo_pattern_get_rgba returned unexepcted results: %g, %g, %g, %g\n",
+	    cairo_test_log (ctx, "Error: cairo_pattern_get_rgba returned unexepcted results: %g, %g, %g, %g\n",
 			    r, g, b, a);
 	    return CAIRO_TEST_FAILURE;
 	}
@@ -88,7 +89,7 @@ draw (cairo_t *cr, int width, int height)
 	CHECK_SUCCESS;
 
 	if (surf != cairo_get_target (cr)) {
-	    cairo_test_log ("Error: cairo_pattern_get_resurface returned wrong surface\n");
+	    cairo_test_log (ctx, "Error: cairo_pattern_get_resurface returned wrong surface\n");
 	    return CAIRO_TEST_FAILURE;
 	}
 
@@ -144,7 +145,7 @@ draw (cairo_t *cr, int width, int height)
 	if (status != CAIRO_STATUS_INVALID_INDEX)
 	    return CAIRO_TEST_FAILURE;
 
-	if (!double_buf_equal (new_buf, expected_values, sizeof(expected_values)/sizeof(double)) != 0)
+	if (!double_buf_equal (ctx, new_buf, expected_values, sizeof(expected_values)/sizeof(double)) != 0)
 	    return CAIRO_TEST_FAILURE;
 
 	cairo_pattern_destroy (pat);
diff --git a/test/pdf-features.c b/test/pdf-features.c
index de3248f..74804cd 100644
--- a/test/pdf-features.c
+++ b/test/pdf-features.c
@@ -86,13 +86,14 @@ struct {
 int
 main (void)
 {
+    cairo_test_context_t ctx;
     cairo_surface_t *surface;
     cairo_t *cr;
     cairo_status_t status;
     const char *filename;
     size_t i;
 
-    cairo_test_init ("pdf-features");
+    cairo_test_init (&ctx, "pdf-features");
 
     filename = "pdf-features.pdf";
 
@@ -130,14 +131,14 @@ main (void)
     cairo_surface_destroy (surface);
 
     if (status) {
-	cairo_test_log ("Failed to create pdf surface for file %s: %s\n",
+	cairo_test_log (&ctx, "Failed to create pdf surface for file %s: %s\n",
 			filename, cairo_status_to_string (status));
 	return CAIRO_TEST_FAILURE;
     }
 
     printf ("pdf-features: Please check %s to ensure it looks/prints correctly.\n", filename);
 
-    cairo_test_fini ();
+    cairo_test_fini (&ctx);
 
     return CAIRO_TEST_SUCCESS;
 }
diff --git a/test/pixman-rotate.c b/test/pixman-rotate.c
index 4d8e300..d115494 100644
--- a/test/pixman-rotate.c
+++ b/test/pixman-rotate.c
@@ -41,7 +41,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "pixman-rotate",
     "Exposes pixman off-by-one error when rotating",
     IMAGE_WIDTH, IMAGE_HEIGHT,
diff --git a/test/ps-features.c b/test/ps-features.c
index 597b73c..b3ac50d 100644
--- a/test/ps-features.c
+++ b/test/ps-features.c
@@ -89,6 +89,7 @@ struct {
 int
 main (void)
 {
+    cairo_test_context_t ctx;
     cairo_surface_t *surface;
     cairo_t *cr;
     cairo_status_t status;
@@ -96,7 +97,7 @@ main (void)
     size_t i;
     char dsc[255];
 
-    cairo_test_init ("ps-features");
+    cairo_test_init (&ctx, "ps-features");
 
     filename = "ps-features.ps";
 
@@ -144,14 +145,14 @@ main (void)
     cairo_surface_destroy (surface);
 
     if (status) {
-	cairo_test_log ("Failed to create ps surface for file %s: %s\n",
+	cairo_test_log (&ctx, "Failed to create ps surface for file %s: %s\n",
 			filename, cairo_status_to_string (status));
 	return CAIRO_TEST_FAILURE;
     }
 
     printf ("ps-features: Please check %s to ensure it looks/prints correctly.\n", filename);
 
-    cairo_test_fini ();
+    cairo_test_fini (&ctx);
 
     return CAIRO_TEST_SUCCESS;
 }
diff --git a/test/pthread-show-text.c b/test/pthread-show-text.c
index 0f0ec89..daf04c3 100644
--- a/test/pthread-show-text.c
+++ b/test/pthread-show-text.c
@@ -75,6 +75,7 @@ start (void *closure)
 int
 main (int argc, char *argv[])
 {
+    cairo_test_context_t ctx;
     int err;
     int i, num_threads;
     pthread_t *pthread;
@@ -85,16 +86,16 @@ main (int argc, char *argv[])
 	num_threads = NUM_THREADS_DEFAULT;
     }
 
-    cairo_test_init ("pthread-show-text");
-
-    cairo_test_log ("Running with %d threads.\n", num_threads);
+    cairo_test_init (&ctx, "pthread-show-text");
+    cairo_test_log (&ctx, "Running with %d threads.\n", num_threads);
 
     pthread = xmalloc (num_threads * sizeof (pthread_t));
 
     for (i = 0; i < num_threads; i++) {
 	err = pthread_create (&pthread[i], NULL, start, NULL);
 	if (err) {
-	    cairo_test_log ("pthread_create failed: %s\n", strerror(err));
+	    cairo_test_log (&ctx, "pthread_create failed: %s\n", strerror(err));
+	    cairo_test_fini (&ctx);
 	    return CAIRO_TEST_FAILURE;
 	}
     }
@@ -104,7 +105,7 @@ main (int argc, char *argv[])
 
     free (pthread);
 
-    cairo_test_fini ();
+    cairo_test_fini (&ctx);
 
     return CAIRO_TEST_SUCCESS;
 }
diff --git a/test/push-group.c b/test/push-group.c
index 4e6fed0..c142278 100644
--- a/test/push-group.c
+++ b/test/push-group.c
@@ -34,7 +34,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "push-group",
     "Verify that cairo_push_group works.",
     WIDTH, HEIGHT,
diff --git a/test/radial-gradient.c b/test/radial-gradient.c
index 1207943..7a56ec1 100644
--- a/test/radial-gradient.c
+++ b/test/radial-gradient.c
@@ -34,7 +34,7 @@ static cairo_test_draw_function_t draw;
 #define WIDTH (SIZE * NUM_GRADIENTS)
 #define HEIGHT (SIZE * NUM_EXTEND)
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "radial-gradient",
     "Simple test of radial gradients",
     WIDTH, HEIGHT,
diff --git a/test/random-intersections.c b/test/random-intersections.c
index 5aa8e48..bf3c98c 100644
--- a/test/random-intersections.c
+++ b/test/random-intersections.c
@@ -29,7 +29,7 @@ static cairo_test_draw_function_t draw;
 #define SIZE 512
 #define NUM_SEGMENTS 128
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "random-intersections",
     "Tests the tessellator trapezoid generation and intersection computation",
     SIZE+3, SIZE+3,
diff --git a/test/rectangle-rounding-error.c b/test/rectangle-rounding-error.c
index 2cfbe9c..5d8fd78 100644
--- a/test/rectangle-rounding-error.c
+++ b/test/rectangle-rounding-error.c
@@ -32,7 +32,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "rectangle-rounding-error",
     "This demonstrates (or not) a rounding error that causes a gap between "
     "two neighbouring rectangles.",
diff --git a/test/rectilinear-miter-limit.c b/test/rectilinear-miter-limit.c
index 114472c..a935fd5 100644
--- a/test/rectilinear-miter-limit.c
+++ b/test/rectilinear-miter-limit.c
@@ -33,7 +33,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "rectilinear-miter-limit",
     "Test that the rectilinear stroke optimization doesn't break cairo_set_miter_limit",
     WIDTH, HEIGHT,
diff --git a/test/rectilinear-stroke.c b/test/rectilinear-stroke.c
index 379284d..3c67586 100644
--- a/test/rectilinear-stroke.c
+++ b/test/rectilinear-stroke.c
@@ -30,7 +30,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "rectilinear-stroke",
     "Test rectilinear stroke operations (covering only whole pixels)",
     SIZE, SIZE,
diff --git a/test/reflected-stroke.c b/test/reflected-stroke.c
index aa32098..1721009 100644
--- a/test/reflected-stroke.c
+++ b/test/reflected-stroke.c
@@ -27,7 +27,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "reflected-stroke",
     "Exercises the stroker with a reflected ctm",
     200, 200,
diff --git a/test/rel-path.c b/test/rel-path.c
index 0f42321..38096bc 100644
--- a/test/rel-path.c
+++ b/test/rel-path.c
@@ -26,7 +26,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "rel-path",
     "Tests calls to various relative path functions",
     SIZE, SIZE,
@@ -81,24 +81,25 @@ invalid_rel_curve_to (cairo_surface_t *target)
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     cairo_status_t status;
 
     /* first test that a relative move without a current point fails... */
     status = invalid_rel_move_to (cairo_get_target (cr));
     if (status != CAIRO_STATUS_NO_CURRENT_POINT) {
-	cairo_test_log ("Error: invalid cairo_rel_move_to() did not raise NO_CURRENT_POINT\n");
+	cairo_test_log (ctx, "Error: invalid cairo_rel_move_to() did not raise NO_CURRENT_POINT\n");
 	return CAIRO_TEST_FAILURE;
     }
 
     status = invalid_rel_line_to (cairo_get_target (cr));
     if (status != CAIRO_STATUS_NO_CURRENT_POINT) {
-	cairo_test_log ("Error: invalid cairo_rel_line_to() did not raise NO_CURRENT_POINT\n");
+	cairo_test_log (ctx, "Error: invalid cairo_rel_line_to() did not raise NO_CURRENT_POINT\n");
 	return CAIRO_TEST_FAILURE;
     }
 
     status = invalid_rel_curve_to (cairo_get_target (cr));
     if (status != CAIRO_STATUS_NO_CURRENT_POINT) {
-	cairo_test_log ("Error: invalid cairo_rel_curve_to() did not raise NO_CURRENT_POINT\n");
+	cairo_test_log (ctx, "Error: invalid cairo_rel_curve_to() did not raise NO_CURRENT_POINT\n");
 	return CAIRO_TEST_FAILURE;
     }
 
diff --git a/test/rgb24-ignore-alpha.c b/test/rgb24-ignore-alpha.c
index 2739d26..1d2b167 100644
--- a/test/rgb24-ignore-alpha.c
+++ b/test/rgb24-ignore-alpha.c
@@ -31,7 +31,7 @@ static cairo_test_draw_function_t draw;
 #define WIDTH  2
 #define HEIGHT 2
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "rgb24-ignore-alpha",
     "Test that when using an RGB24 image as a source, there is no alpha channel",
     WIDTH, HEIGHT,
diff --git a/test/rotate-image-surface-paint.c b/test/rotate-image-surface-paint.c
index 378b1ee..25ce9c5 100644
--- a/test/rotate-image-surface-paint.c
+++ b/test/rotate-image-surface-paint.c
@@ -31,7 +31,7 @@ static cairo_test_draw_function_t draw;
 #define SIZE 20
 #define PAD 2
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "rotate-image-surface-paint",
     "Test call sequence: image_surface_create; rotate; set_source_surface; paint"
     "\nThis test is known to fail on the ps backend currently",
diff --git a/test/scale-down-source-surface-paint.c b/test/scale-down-source-surface-paint.c
index f5effab..2a2efcc 100644
--- a/test/scale-down-source-surface-paint.c
+++ b/test/scale-down-source-surface-paint.c
@@ -27,7 +27,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "scale-down-source-surface-paint",
     "Test call sequence: cairo_scale; cairo_set_source_surface; cairo_paint, with a scale < 1.0",
     6, 6,
@@ -38,7 +38,7 @@ static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
     cairo_surface_t *surface;
-    static uint32_t data[16] = {
+    uint32_t data[16] = {
 	0xffffffff, 0xffffffff,		0xffff0000, 0xffff0000,
 	0xffffffff, 0xffffffff,		0xffff0000, 0xffff0000,
 
diff --git a/test/scale-source-surface-paint.c b/test/scale-source-surface-paint.c
index 1fbe0c4..9473342 100644
--- a/test/scale-source-surface-paint.c
+++ b/test/scale-source-surface-paint.c
@@ -27,7 +27,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "scale-source-surface-paint",
     "Test call sequence: cairo_scale; cairo_set_source_surface; cairo_paint",
     12, 12,
@@ -38,7 +38,7 @@ static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
     cairo_surface_t *surface;
-    static uint32_t data[16] = {
+    uint32_t data[16] = {
 	0xffffffff, 0xffffffff,		0xffff0000, 0xffff0000,
 	0xffffffff, 0xffffffff,		0xffff0000, 0xffff0000,
 
diff --git a/test/select-font-face.c b/test/select-font-face.c
index 57120ca..c5ff56b 100644
--- a/test/select-font-face.c
+++ b/test/select-font-face.c
@@ -29,7 +29,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "select-font-face",
     "Tests using cairo_select_font_face to draw text in different faces",
     192, TEXT_SIZE + 4,
diff --git a/test/select-font-no-show-text.c b/test/select-font-no-show-text.c
index c0e4f46..752891b 100644
--- a/test/select-font-no-show-text.c
+++ b/test/select-font-no-show-text.c
@@ -43,7 +43,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "select-font-no-show-text",
     "Test calling cairo_select_font_face but never drawing text.",
     0, 0,
diff --git a/test/self-copy.c b/test/self-copy.c
index 63e1897..1afb31e 100644
--- a/test/self-copy.c
+++ b/test/self-copy.c
@@ -31,7 +31,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "self-copy",
     "Test copying from a surface to itself with a clip",
     SIZE, SIZE,
diff --git a/test/self-intersecting.c b/test/self-intersecting.c
index 870783e..d2b6265 100644
--- a/test/self-intersecting.c
+++ b/test/self-intersecting.c
@@ -46,7 +46,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "self-intersecting",
     "Test strokes of self-intersecting paths"
     "\nSelf-intersecting strokes are wrong due to incremental trapezoidization.",
diff --git a/test/set-source.c b/test/set-source.c
index eca3f18..05dd3cb 100644
--- a/test/set-source.c
+++ b/test/set-source.c
@@ -27,7 +27,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "set-source",
     "Tests calls to various set_source functions",
     5, 5,
diff --git a/test/show-text-current-point.c b/test/show-text-current-point.c
index 5ff3675..2fd2387 100644
--- a/test/show-text-current-point.c
+++ b/test/show-text-current-point.c
@@ -29,7 +29,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "show-text-current-point",
     "Test that cairo_show_text adjusts the current point properly",
     263, TEXT_SIZE + 4,
diff --git a/test/skew-extreme.c b/test/skew-extreme.c
index 919937b..c682d08 100644
--- a/test/skew-extreme.c
+++ b/test/skew-extreme.c
@@ -57,7 +57,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "skew-extreme",
     "Test cases of extreme skew.",
     WIDTH, HEIGHT,
diff --git a/test/smask-fill.c b/test/smask-fill.c
index 980018e..66f8b0d 100644
--- a/test/smask-fill.c
+++ b/test/smask-fill.c
@@ -27,7 +27,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "smask-fill",
     "Test the support of \"soft\" masks with fills",
     60, 60,
@@ -80,4 +80,3 @@ main (void)
 {
     return cairo_test (&test);
 }
-
diff --git a/test/smask-image-mask.c b/test/smask-image-mask.c
index 5c805e1..1edec29 100644
--- a/test/smask-image-mask.c
+++ b/test/smask-image-mask.c
@@ -27,7 +27,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "smask-image-mask",
     "Test the support of \"soft\" masks with a secondary image mask",
     60, 60,
@@ -37,7 +37,7 @@ cairo_test_t test = {
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
-    static uint32_t data[] = {
+    uint32_t data[] = {
 	0xaa000000, 0x55000000,
 	0x55000000, 0xaa000000,
     };
@@ -89,4 +89,3 @@ main (void)
 {
     return cairo_test (&test);
 }
-
diff --git a/test/smask-mask.c b/test/smask-mask.c
index 3d8cb05..c38be37 100644
--- a/test/smask-mask.c
+++ b/test/smask-mask.c
@@ -27,7 +27,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "smask-mask",
     "Test the support of \"soft\" masks with a secondary mask",
     60, 60,
@@ -104,4 +104,3 @@ main (void)
 {
     return cairo_test (&test);
 }
-
diff --git a/test/smask-paint.c b/test/smask-paint.c
index c075ade..d0b9e94 100644
--- a/test/smask-paint.c
+++ b/test/smask-paint.c
@@ -27,7 +27,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "smask-paint",
     "Test the support of \"soft\" masks with paints",
     60, 60,
@@ -87,4 +87,3 @@ main (void)
 {
     return cairo_test (&test);
 }
-
diff --git a/test/smask-stroke.c b/test/smask-stroke.c
index c70825a..fa0afd6 100644
--- a/test/smask-stroke.c
+++ b/test/smask-stroke.c
@@ -27,7 +27,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "smask-stroke",
     "Test the support of \"soft\" masks with strokes",
     60, 60,
@@ -80,4 +80,3 @@ main (void)
 {
     return cairo_test (&test);
 }
-
diff --git a/test/smask-text.c b/test/smask-text.c
index 589c71d..822ea5a 100644
--- a/test/smask-text.c
+++ b/test/smask-text.c
@@ -27,7 +27,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "smask-text",
     "Test the support of \"soft\" masks with text",
     120, 60,
@@ -89,4 +89,3 @@ main (void)
 {
     return cairo_test (&test);
 }
-
diff --git a/test/smask.c b/test/smask.c
index 28eaed0..2b1d5b3 100644
--- a/test/smask.c
+++ b/test/smask.c
@@ -27,7 +27,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "smask",
     "Test the support of \"soft\" masks",
     60, 60,
@@ -37,7 +37,7 @@ cairo_test_t test = {
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
-    static uint32_t data[] = {
+    uint32_t data[] = {
 	0x80000000, 0x80000000,
 	0x80000000, 0x80000000,
     };
@@ -127,4 +127,3 @@ main (void)
 {
     return cairo_test (&test);
 }
-
diff --git a/test/solid-pattern-cache-stress.c b/test/solid-pattern-cache-stress.c
index 39c6454..42928aa 100644
--- a/test/solid-pattern-cache-stress.c
+++ b/test/solid-pattern-cache-stress.c
@@ -39,7 +39,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "solid-pattern-cache-stress",
     "Stress the solid pattern cache and ensure it behaves",
     1, 1,
diff --git a/test/source-clip-scale.c b/test/source-clip-scale.c
index 26684d3..4c55695 100644
--- a/test/source-clip-scale.c
+++ b/test/source-clip-scale.c
@@ -31,7 +31,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "source-clip-scale",
     "Test that a source surface is not affected by a clip when scaling",
     SIZE * 2, SIZE,
diff --git a/test/source-clip.c b/test/source-clip.c
index 46eb233..b24f95c 100644
--- a/test/source-clip.c
+++ b/test/source-clip.c
@@ -31,7 +31,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "source-clip",
     "Test that a source surface is not affected by a clip",
     SIZE, SIZE,
diff --git a/test/source-surface-scale-paint.c b/test/source-surface-scale-paint.c
index 8c3096a..908367c 100644
--- a/test/source-surface-scale-paint.c
+++ b/test/source-surface-scale-paint.c
@@ -27,7 +27,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "source-surface-scale-paint",
     "Test call sequence: cairo_set_source_surface; cairo_scale; cairo_paint",
     8, 8,
@@ -38,7 +38,7 @@ static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
     cairo_surface_t *surface;
-    static uint32_t data[16] = {
+    uint32_t data[16] = {
 	0xffffffff, 0xffffffff,		0xffff0000, 0xffff0000,
 	0xffffffff, 0xffffffff,		0xffff0000, 0xffff0000,
 
diff --git a/test/stroke-ctm-caps.c b/test/stroke-ctm-caps.c
index 07a918e..bfe2bef 100644
--- a/test/stroke-ctm-caps.c
+++ b/test/stroke-ctm-caps.c
@@ -41,7 +41,7 @@ static cairo_test_draw_function_t draw;
  * (0.8, 0.8, 0.8, 0.4).
  */
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "stroke-ctm-caps",
     "Test that the stroker correctly passes the device-space vector to the stroker for endcaps",
     WIDTH, HEIGHT,
diff --git a/test/stroke-image.c b/test/stroke-image.c
index 20b868c..01ad436 100644
--- a/test/stroke-image.c
+++ b/test/stroke-image.c
@@ -32,7 +32,7 @@ static cairo_test_draw_function_t draw;
 #define IMAGE_SIZE (SIZE-PAD*2)
 #define LINE_WIDTH 10
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "stroke-image",
     "Test stroking with an image source, with a non-identity CTM",
     SIZE, SIZE,
diff --git a/test/surface-finish-twice.c b/test/surface-finish-twice.c
index 3751939..149f29c 100644
--- a/test/surface-finish-twice.c
+++ b/test/surface-finish-twice.c
@@ -44,7 +44,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "surface-finish-twice",
     "Test to exercise a crash when calling cairo_surface_finish twice on the same surface.",
     0, 0,
diff --git a/test/surface-pattern-big-scale-down.c b/test/surface-pattern-big-scale-down.c
index c938d99..49cf6ad 100644
--- a/test/surface-pattern-big-scale-down.c
+++ b/test/surface-pattern-big-scale-down.c
@@ -30,7 +30,7 @@ static cairo_test_draw_function_t draw;
 #define SRC_WIDTH 2048
 #define SRC_HEIGHT 32
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "surface-pattern-big-scale-down",
     "Test scaled-down transformed not-repeated surface patterns with large images and offsets",
     512, 16,
diff --git a/test/surface-pattern-scale-down.c b/test/surface-pattern-scale-down.c
index 337a4e7..4e9b48f 100644
--- a/test/surface-pattern-scale-down.c
+++ b/test/surface-pattern-scale-down.c
@@ -32,7 +32,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "surface-pattern-scale-down",
     "Test scaled-down transformed not-repeated surface patterns"
     "\nFails xlib backend (with argb32) with inexplicable alpha in result",
diff --git a/test/surface-pattern-scale-up.c b/test/surface-pattern-scale-up.c
index ccc498e..ef7a4d1 100644
--- a/test/surface-pattern-scale-up.c
+++ b/test/surface-pattern-scale-up.c
@@ -32,7 +32,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "surface-pattern-scale-up",
     "Test scaled-up transformed not-repeated surface patterns"
     "\nFails xlib backend (with argb32) with inexplicable alpha in result",
diff --git a/test/surface-pattern.c b/test/surface-pattern.c
index 2104dba..41ffdc9 100644
--- a/test/surface-pattern.c
+++ b/test/surface-pattern.c
@@ -32,7 +32,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "surface-pattern",
     "Test transformed repeated surface patterns"
     "\nExhibiting a strange (very minor) failure in ps backend with device-offset",
diff --git a/test/surface-source.c b/test/surface-source.c
index 5a034ad..61ab65e 100644
--- a/test/surface-source.c
+++ b/test/surface-source.c
@@ -30,7 +30,7 @@ static cairo_surface_t *create_source_surface (int size);
 
 #define SIZE 90
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     NAME "-surface-source",
     "Test using various surfaces as the source",
     SIZE, SIZE,
diff --git a/test/svg-clip.c b/test/svg-clip.c
index 77ae9e9..0dfab4d 100644
--- a/test/svg-clip.c
+++ b/test/svg-clip.c
@@ -106,16 +106,20 @@ test_clip (cairo_t *cr, double width, double height)
 int
 main (void)
 {
+    cairo_test_context_t ctx;
     cairo_t *cr;
     const char *filename = "svg-clip.svg";
     cairo_surface_t *surface;
 
-    cairo_test_init ("svg-clip");
+    cairo_test_init (&ctx, "svg-clip");
 
     surface = cairo_svg_surface_create (filename,
 					WIDTH_IN_POINTS, HEIGHT_IN_POINTS);
-    if (surface == NULL) {
-	fprintf (stderr, "Failed to create svg surface for file %s\n", filename);
+    if (cairo_surface_status (surface)) {
+	cairo_test_log (&ctx,
+			"Failed to create svg surface for file %s: %s\n",
+			filename, cairo_status_to_string (cairo_surface_status (surface)));
+	cairo_test_fini (&ctx);
 	return CAIRO_TEST_FAILURE;
     }
 
@@ -130,7 +134,7 @@ main (void)
     printf ("svg-clip: Please check %s to make sure it looks happy.\n",
 	    filename);
 
-    cairo_test_fini ();
+    cairo_test_fini (&ctx);
 
-    return 0;
+    return CAIRO_TEST_SUCCESS;
 }
diff --git a/test/svg-surface.c b/test/svg-surface.c
index 99b7b4e..f6b843a 100644
--- a/test/svg-surface.c
+++ b/test/svg-surface.c
@@ -89,16 +89,21 @@ draw (cairo_t *cr, int width, int height)
 int
 main (void)
 {
+    cairo_test_context_t ctx;
     cairo_t *cr;
     const char *filename = "svg-surface.svg";
     cairo_surface_t *surface;
 
-    cairo_test_init ("svg-surface");
+    cairo_test_init (&ctx, "svg-surface");
 
     surface = cairo_svg_surface_create (filename,
 					WIDTH_IN_POINTS, HEIGHT_IN_POINTS);
-    if (surface == NULL) {
-	fprintf (stderr, "Failed to create svg surface for file %s\n", filename);
+    if (cairo_surface_status (surface)) {
+	cairo_test_log (&ctx,
+			"Failed to create svg surface for file %s: %s\n",
+			filename,
+			cairo_status_to_string (cairo_surface_status (surface)));
+	cairo_test_fini (&ctx);
 	return CAIRO_TEST_FAILURE;
     }
 
@@ -113,7 +118,7 @@ main (void)
 
     printf ("svg-surface: Please check svg-surface.svg to make sure it looks happy.\n");
 
-    cairo_test_fini ();
+    cairo_test_fini (&ctx);
 
-    return 0;
+    return CAIRO_TEST_SUCCESS;
 }
diff --git a/test/text-antialias-gray.c b/test/text-antialias-gray.c
index dd0f34e..2029224 100644
--- a/test/text-antialias-gray.c
+++ b/test/text-antialias-gray.c
@@ -31,7 +31,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "text-antialias-gray",
     "Tests text rendering with grayscale antialiasing",
     WIDTH, HEIGHT,
@@ -43,7 +43,7 @@ draw (cairo_t *cr, int width, int height)
 {
     cairo_text_extents_t extents;
     cairo_font_options_t *font_options;
-    static char black[] = "black", blue[] = "blue";
+    const char black[] = "black", blue[] = "blue";
 
     /* We draw in the default black, so paint white first. */
     cairo_save (cr);
diff --git a/test/text-antialias-none.c b/test/text-antialias-none.c
index f53fde4..af279d8 100644
--- a/test/text-antialias-none.c
+++ b/test/text-antialias-none.c
@@ -31,7 +31,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "text-antialias-none",
     "Tests text rendering with no antialiasing",
     WIDTH, HEIGHT,
@@ -43,7 +43,7 @@ draw (cairo_t *cr, int width, int height)
 {
     cairo_text_extents_t extents;
     cairo_font_options_t *font_options;
-    static char black[] = "black", blue[] = "blue";
+    const char black[] = "black", blue[] = "blue";
 
     /* We draw in the default black, so paint white first. */
     cairo_save (cr);
diff --git a/test/text-antialias-subpixel.c b/test/text-antialias-subpixel.c
index 440c3a3..a998997 100644
--- a/test/text-antialias-subpixel.c
+++ b/test/text-antialias-subpixel.c
@@ -31,7 +31,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "text-antialias-subpixel",
     "Tests text rendering with subpixel antialiasing",
     WIDTH, HEIGHT,
@@ -43,7 +43,7 @@ draw (cairo_t *cr, int width, int height)
 {
     cairo_text_extents_t extents;
     cairo_font_options_t *font_options;
-    static char black[] = "black", blue[] = "blue";
+    const char black[] = "black", blue[] = "blue";
 
     cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
     cairo_paint (cr);
diff --git a/test/text-cache-crash.c b/test/text-cache-crash.c
index 00b3b29..b78b3a3 100644
--- a/test/text-cache-crash.c
+++ b/test/text-cache-crash.c
@@ -57,14 +57,14 @@
  *   Found the bug. cairo_gstate_select_font was noticing when the
  *   same font was selected twice in a row and was erroneously failing
  *   to free the old reference. Committed a fix and verified it also
- *   fixed the orginal test case.
+ *   fixed the original test case.
  */
 
 #include "cairo-test.h"
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "text-cache-crash",
     "Test case for bug causing an assertion failure in _cairo_cache_lookup",
     0, 0,
diff --git a/test/text-lcd-filter-fir3.c b/test/text-lcd-filter-fir3.c
index a6445b5..7f95978 100644
--- a/test/text-lcd-filter-fir3.c
+++ b/test/text-lcd-filter-fir3.c
@@ -31,7 +31,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "text-lcd-filter-fir3",
     "Tests text rendering with a 3x3 kernel FIR LCD filter",
     WIDTH, HEIGHT,
@@ -43,7 +43,7 @@ draw (cairo_t *cr, int width, int height)
 {
     cairo_text_extents_t extents;
     cairo_font_options_t *font_options;
-    static char black[] = "black", blue[] = "blue";
+    const char black[] = "black", blue[] = "blue";
 
     /* We draw in the default black, so paint white first. */
     cairo_save (cr);
diff --git a/test/text-lcd-filter-fir5.c b/test/text-lcd-filter-fir5.c
index 54bee80..a5102b9 100644
--- a/test/text-lcd-filter-fir5.c
+++ b/test/text-lcd-filter-fir5.c
@@ -31,7 +31,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "text-lcd-filter-fir5",
     "Tests text rendering with a 5x5 kernel FIR LCD filter",
     WIDTH, HEIGHT,
@@ -43,7 +43,7 @@ draw (cairo_t *cr, int width, int height)
 {
     cairo_text_extents_t extents;
     cairo_font_options_t *font_options;
-    static char black[] = "black", blue[] = "blue";
+    const char black[] = "black", blue[] = "blue";
 
     /* We draw in the default black, so paint white first. */
     cairo_save (cr);
diff --git a/test/text-lcd-filter-intra-pixel.c b/test/text-lcd-filter-intra-pixel.c
index 3f8b486..c02b441 100644
--- a/test/text-lcd-filter-intra-pixel.c
+++ b/test/text-lcd-filter-intra-pixel.c
@@ -31,7 +31,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "text-lcd-filter-intra-pixel",
     "Tests text rendering with intra-pixel LCD filter",
     WIDTH, HEIGHT,
@@ -43,7 +43,7 @@ draw (cairo_t *cr, int width, int height)
 {
     cairo_text_extents_t extents;
     cairo_font_options_t *font_options;
-    static char black[] = "black", blue[] = "blue";
+    const char black[] = "black", blue[] = "blue";
 
     /* We draw in the default black, so paint white first. */
     cairo_save (cr);
diff --git a/test/text-lcd-filter-none.c b/test/text-lcd-filter-none.c
index 87e358a..f84483e 100644
--- a/test/text-lcd-filter-none.c
+++ b/test/text-lcd-filter-none.c
@@ -31,7 +31,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "text-lcd-filter-none",
     "Tests text rendering with no LCD filter",
     WIDTH, HEIGHT,
@@ -43,7 +43,7 @@ draw (cairo_t *cr, int width, int height)
 {
     cairo_text_extents_t extents;
     cairo_font_options_t *font_options;
-    static char black[] = "black", blue[] = "blue";
+    const char black[] = "black", blue[] = "blue";
 
     /* We draw in the default black, so paint white first. */
     cairo_save (cr);
diff --git a/test/text-pattern.c b/test/text-pattern.c
index 15a909d..eae9cae 100644
--- a/test/text-pattern.c
+++ b/test/text-pattern.c
@@ -30,7 +30,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "text-pattern",
     "Patterned Text\n",
     IMAGE_WIDTH, IMAGE_HEIGHT,
diff --git a/test/text-rotate.c b/test/text-rotate.c
index 71d9cc3..da21461 100644
--- a/test/text-rotate.c
+++ b/test/text-rotate.c
@@ -92,7 +92,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "text-rotate",
     "Tests show_text under various rotations",
     WIDTH, HEIGHT,
@@ -106,7 +106,7 @@ draw (cairo_t *cr, int width, int height)
     int i, x_off, y_off;
     cairo_text_extents_t extents;
     cairo_font_options_t *font_options;
-    static char text[] = "cairo";
+    const char text[] = "cairo";
 
     /* paint white so we don't need separate ref images for
      * RGB24 and ARGB32 */
diff --git a/test/text-transform.c b/test/text-transform.c
index 78a68d7..c1148e5 100644
--- a/test/text-transform.c
+++ b/test/text-transform.c
@@ -32,9 +32,9 @@ static cairo_test_draw_function_t draw;
 
 #define FONT_SIZE 32.0
 
-const char png_filename[] = "romedalen.png";
+static const char png_filename[] = "romedalen.png";
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "text-transform",
     "Test various applications of the font matrix",
     SIZE, SIZE,
@@ -78,6 +78,7 @@ draw_text (cairo_t *cr)
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     cairo_pattern_t *pattern;
 
     cairo_set_source_rgb (cr, 1., 1., 1.);
@@ -94,7 +95,7 @@ draw (cairo_t *cr, int width, int height)
     cairo_translate (cr, SIZE, SIZE);
     cairo_rotate (cr, M_PI);
 
-    pattern = cairo_test_create_pattern_from_png (png_filename);
+    pattern = cairo_test_create_pattern_from_png (ctx, png_filename);
     cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
     cairo_set_source (cr, pattern);
     cairo_pattern_destroy (pattern);
diff --git a/test/text-zero-len.c b/test/text-zero-len.c
index fff9783..dbcd2c5 100644
--- a/test/text-zero-len.c
+++ b/test/text-zero-len.c
@@ -45,7 +45,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "text-zero-len",
     "Tests show_text and text_path with a zero-sized string",
     0, 0,
@@ -78,6 +78,7 @@ font_extents_equal (const cairo_font_extents_t *A,
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     cairo_text_extents_t extents, nil_extents;
     cairo_font_extents_t font_extents, nil_font_extents;
     cairo_scaled_font_t *scaled_font;
@@ -104,7 +105,7 @@ draw (cairo_t *cr, int width, int height)
     memset (&extents, 0xff, sizeof (cairo_text_extents_t));
     cairo_text_extents (cr, "", &extents);
     if (! text_extents_equal (&extents, &nil_extents)) {
-	cairo_test_log ("Error: cairo_text_extents(\"\"); extents (%g, %g, %g, %g, %g, %g)\n",
+	cairo_test_log (ctx, "Error: cairo_text_extents(\"\"); extents (%g, %g, %g, %g, %g, %g)\n",
 		        extents.x_bearing, extents.y_bearing,
 			extents.width, extents.height,
 			extents.x_advance, extents.y_advance);
@@ -114,7 +115,7 @@ draw (cairo_t *cr, int width, int height)
     memset (&extents, 0xff, sizeof (cairo_text_extents_t));
     cairo_text_extents (cr, NULL, &extents);
     if (! text_extents_equal (&extents, &nil_extents)) {
-	cairo_test_log ("Error: cairo_text_extents(NULL); extents (%g, %g, %g, %g, %g, %g)\n",
+	cairo_test_log (ctx, "Error: cairo_text_extents(NULL); extents (%g, %g, %g, %g, %g, %g)\n",
 		        extents.x_bearing, extents.y_bearing,
 			extents.width, extents.height,
 			extents.x_advance, extents.y_advance);
@@ -124,7 +125,7 @@ draw (cairo_t *cr, int width, int height)
     memset (&extents, 0xff, sizeof (cairo_text_extents_t));
     cairo_glyph_extents (cr, (void*)8, 0, &extents);
     if (! text_extents_equal (&extents, &nil_extents)) {
-	cairo_test_log ("Error: cairo_glyph_extents(); extents (%g, %g, %g, %g, %g, %g)\n",
+	cairo_test_log (ctx, "Error: cairo_glyph_extents(); extents (%g, %g, %g, %g, %g, %g)\n",
 		        extents.x_bearing, extents.y_bearing,
 			extents.width, extents.height,
 			extents.x_advance, extents.y_advance);
@@ -136,7 +137,7 @@ draw (cairo_t *cr, int width, int height)
     memset (&extents, 0xff, sizeof (cairo_text_extents_t));
     cairo_scaled_font_text_extents (scaled_font, "", &extents);
     if (! text_extents_equal (&extents, &nil_extents)) {
-	cairo_test_log ("Error: cairo_scaled_font_text_extents(\"\"); extents (%g, %g, %g, %g, %g, %g)\n",
+	cairo_test_log (ctx, "Error: cairo_scaled_font_text_extents(\"\"); extents (%g, %g, %g, %g, %g, %g)\n",
 		        extents.x_bearing, extents.y_bearing,
 			extents.width, extents.height,
 			extents.x_advance, extents.y_advance);
@@ -146,7 +147,7 @@ draw (cairo_t *cr, int width, int height)
     memset (&extents, 0xff, sizeof (cairo_text_extents_t));
     cairo_scaled_font_text_extents (scaled_font, NULL, &extents);
     if (! text_extents_equal (&extents, &nil_extents)) {
-	cairo_test_log ("Error: cairo_scaled_font_text_extents(NULL); extents (%g, %g, %g, %g, %g, %g)\n",
+	cairo_test_log (ctx, "Error: cairo_scaled_font_text_extents(NULL); extents (%g, %g, %g, %g, %g, %g)\n",
 		        extents.x_bearing, extents.y_bearing,
 			extents.width, extents.height,
 			extents.x_advance, extents.y_advance);
@@ -156,7 +157,7 @@ draw (cairo_t *cr, int width, int height)
     memset (&extents, 0xff, sizeof (cairo_text_extents_t));
     cairo_scaled_font_glyph_extents (scaled_font, (void*)8, 0, &extents);
     if (! text_extents_equal (&extents, &nil_extents)) {
-	cairo_test_log ("Error: cairo_scaled_font_glyph_extents(NULL); extents (%g, %g, %g, %g, %g, %g)\n",
+	cairo_test_log (ctx, "Error: cairo_scaled_font_glyph_extents(NULL); extents (%g, %g, %g, %g, %g, %g)\n",
 		        extents.x_bearing, extents.y_bearing,
 			extents.width, extents.height,
 			extents.x_advance, extents.y_advance);
@@ -169,7 +170,7 @@ draw (cairo_t *cr, int width, int height)
     memset (&extents, 0xff, sizeof (cairo_text_extents_t));
     cairo_text_extents (cr, "test", &extents);
     if (! text_extents_equal (&extents, &nil_extents)) {
-	cairo_test_log ("Error: cairo_set_font_size(0); cairo_text_extents(\"test\"); extents (%g, %g, %g, %g, %g, %g)\n",
+	cairo_test_log (ctx, "Error: cairo_set_font_size(0); cairo_text_extents(\"test\"); extents (%g, %g, %g, %g, %g, %g)\n",
 		        extents.x_bearing, extents.y_bearing,
 			extents.width, extents.height,
 			extents.x_advance, extents.y_advance);
@@ -181,7 +182,7 @@ draw (cairo_t *cr, int width, int height)
     memset (&font_extents, 0xff, sizeof (cairo_font_extents_t));
     cairo_font_extents (cr,  &font_extents);
     if (! font_extents_equal (&font_extents, &nil_font_extents)) {
-	cairo_test_log ("Error: cairo_set_font_size(0); cairo_font_extents(); extents (%g, %g, %g, %g, %g)\n",
+	cairo_test_log (ctx, "Error: cairo_set_font_size(0); cairo_font_extents(); extents (%g, %g, %g, %g, %g)\n",
 		        font_extents.ascent, font_extents.descent,
 			font_extents.height,
 			font_extents.max_x_advance, font_extents.max_y_advance);
@@ -193,7 +194,7 @@ draw (cairo_t *cr, int width, int height)
     memset (&font_extents, 0xff, sizeof (cairo_font_extents_t));
     cairo_scaled_font_extents (scaled_font,  &font_extents);
     if (! font_extents_equal (&font_extents, &nil_font_extents)) {
-	cairo_test_log ("Error: cairo_set_font_size(0); cairo_scaled_font_extents(); extents (%g, %g, %g, %g, %g)\n",
+	cairo_test_log (ctx, "Error: cairo_set_font_size(0); cairo_scaled_font_extents(); extents (%g, %g, %g, %g, %g)\n",
 		        font_extents.ascent, font_extents.descent,
 			font_extents.height,
 			font_extents.max_x_advance, font_extents.max_y_advance);
diff --git a/test/transforms.c b/test/transforms.c
index 97b8fe8..5731b8e 100644
--- a/test/transforms.c
+++ b/test/transforms.c
@@ -30,7 +30,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "transforms",
     "Test various transformations.",
     WIDTH, HEIGHT,
diff --git a/test/translate-show-surface.c b/test/translate-show-surface.c
index a505f36..819ab69 100644
--- a/test/translate-show-surface.c
+++ b/test/translate-show-surface.c
@@ -45,7 +45,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "translate-show-surface",
     "Tests calls to cairo_show_surface after cairo_translate",
     2, 2,
diff --git a/test/trap-clip.c b/test/trap-clip.c
index 3712c90..0decb7b 100644
--- a/test/trap-clip.c
+++ b/test/trap-clip.c
@@ -31,22 +31,22 @@
 #define HEIGHT 16
 #define PAD 2
 
-const char	png_filename[]	= "romedalen.png";
+static const char	png_filename[]	= "romedalen.png";
 
 static void
-set_solid_pattern (cairo_t *cr, int x, int y)
+set_solid_pattern (const cairo_test_context_t *ctx, cairo_t *cr, int x, int y)
 {
     cairo_set_source_rgb (cr, 0, 0, 0.6);
 }
 
 static void
-set_translucent_pattern (cairo_t *cr, int x, int y)
+set_translucent_pattern (const cairo_test_context_t *ctx, cairo_t *cr, int x, int y)
 {
     cairo_set_source_rgba (cr, 0, 0, 0.6, 0.5);
 }
 
 static void
-set_gradient_pattern (cairo_t *cr, int x, int y)
+set_gradient_pattern (const cairo_test_context_t *ctx, cairo_t *cr, int x, int y)
 {
     cairo_pattern_t *pattern;
 
@@ -59,11 +59,11 @@ set_gradient_pattern (cairo_t *cr, int x, int y)
 }
 
 static void
-set_image_pattern (cairo_t *cr, int x, int y)
+set_image_pattern (const cairo_test_context_t *ctx, cairo_t *cr, int x, int y)
 {
     cairo_pattern_t *pattern;
 
-    pattern = cairo_test_create_pattern_from_png (png_filename);
+    pattern = cairo_test_create_pattern_from_png (ctx, png_filename);
     cairo_set_source (cr, pattern);
     cairo_pattern_destroy (pattern);
 }
@@ -140,20 +140,20 @@ clip_circle (cairo_t *cr, int x, int y)
     cairo_new_path (cr);
 }
 
-static void (*pattern_funcs[])(cairo_t *cr, int x, int y) = {
+static void (* const pattern_funcs[])(const cairo_test_context_t *ctx, cairo_t *cr, int x, int y) = {
     set_solid_pattern,
     set_translucent_pattern,
     set_gradient_pattern,
     set_image_pattern,
 };
 
-static void (*draw_funcs[])(cairo_t *cr, int x, int y) = {
+static void (* const draw_funcs[])(cairo_t *cr, int x, int y) = {
     draw_rect,
     draw_rects,
     draw_polygon,
 };
 
-static void (*clip_funcs[])(cairo_t *cr, int x, int y) = {
+static void (* const clip_funcs[])(cairo_t *cr, int x, int y) = {
     clip_none,
     clip_rect,
     clip_rects,
@@ -166,7 +166,7 @@ static void (*clip_funcs[])(cairo_t *cr, int x, int y) = {
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "trap-clip",
     "Trapezoid clipping\n",
     IMAGE_WIDTH, IMAGE_HEIGHT,
@@ -176,6 +176,7 @@ cairo_test_t test = {
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     size_t i, j, k, x, y;
 
     for (k = 0; k < ARRAY_SIZE (clip_funcs); k++) {
@@ -188,10 +189,10 @@ draw (cairo_t *cr, int width, int height)
 
 		cairo_move_to (cr, x, y);
 		clip_funcs[k] (cr, x, y);
-		pattern_funcs[i] (cr, x, y);
+		pattern_funcs[i] (ctx, cr, x, y);
 		draw_funcs[j] (cr, x, y);
 		if (cairo_status (cr))
-		    cairo_test_log ("%d %d HERE!\n", (int)i, (int)j);
+		    cairo_test_log (ctx, "%d %d HERE!\n", (int)i, (int)j);
 
 		cairo_restore (cr);
 	    }
@@ -199,7 +200,7 @@ draw (cairo_t *cr, int width, int height)
     }
 
     if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
-	cairo_test_log ("%d %d .HERE!\n", (int)i, (int)j);
+	cairo_test_log (ctx, "%d %d .HERE!\n", (int)i, (int)j);
 
     return CAIRO_TEST_SUCCESS;
 }
diff --git a/test/truetype-tables.c b/test/truetype-tables.c
index c279c8b..37f515a 100644
--- a/test/truetype-tables.c
+++ b/test/truetype-tables.c
@@ -34,15 +34,15 @@
 int
 main (void)
 {
+    cairo_test_context_t ctx;
     cairo_test_status_t ret = CAIRO_TEST_SUCCESS;
 
-    cairo_test_init ("truetype-tables");
-
-    cairo_test_log ("Test that the size of TrueType table structs is correct\n");
+    cairo_test_init (&ctx, "truetype-tables");
+    cairo_test_log (&ctx, "Test that the size of TrueType table structs is correct\n");
 
 #define check(st, sz) \
 	if (sizeof (st) != (sz)) { \
-	    cairo_test_log ("sizeof (%s): got %d, expected %d", #st, (int)sizeof (st), sz); \
+	    cairo_test_log (&ctx, "sizeof (%s): got %d, expected %d", #st, (int)sizeof (st), sz); \
 	    ret = CAIRO_TEST_FAILURE; \
 	}
 
@@ -55,7 +55,7 @@ main (void)
     check (tt_composite_glyph_t,	18);
     check (tt_glyph_data_t,	28);
 
-    cairo_test_fini ();
+    cairo_test_fini (&ctx);
 
     return ret;
 }
diff --git a/test/unantialiased-shapes.c b/test/unantialiased-shapes.c
index 2ca4ee8..298f1c1 100644
--- a/test/unantialiased-shapes.c
+++ b/test/unantialiased-shapes.c
@@ -27,7 +27,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "unantialiased-shapes",
     "Test shape drawing without antialiasing",
     320, 240,
diff --git a/test/unbounded-operator.c b/test/unbounded-operator.c
index 06f5cb1..043edfd 100644
--- a/test/unbounded-operator.c
+++ b/test/unbounded-operator.c
@@ -116,7 +116,7 @@ draw_rects (cairo_t *cr, int x, int y)
     cairo_fill (cr);
 }
 
-static void (*draw_funcs[])(cairo_t *cr, int x, int y) = {
+static void (*const draw_funcs[])(cairo_t *cr, int x, int y) = {
     draw_mask,
     draw_glyphs,
     draw_polygon,
@@ -134,7 +134,7 @@ static cairo_operator_t operators[] = {
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "unbounded-operator",
     "Operators with an effect for transparent source/mask",
     IMAGE_WIDTH, IMAGE_HEIGHT,
@@ -144,6 +144,7 @@ cairo_test_t test = {
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     size_t i, j, x, y;
     cairo_pattern_t *pattern;
 
@@ -176,14 +177,14 @@ draw (cairo_t *cr, int width, int height)
 
 	    draw_funcs[j] (cr, x, y);
 	    if (cairo_status (cr))
-		cairo_test_log ("%d %d HERE!\n", (int)i, (int)j);
+		cairo_test_log (ctx, "%d %d HERE!\n", (int)i, (int)j);
 
 	    cairo_restore (cr);
 	}
     }
 
     if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
-	cairo_test_log ("%d %d .HERE!\n", (int)i, (int)j);
+	cairo_test_log (ctx, "%d %d .HERE!\n", (int)i, (int)j);
 
     return CAIRO_TEST_SUCCESS;
 }
diff --git a/test/user-font-proxy.c b/test/user-font-proxy.c
index 770b0c4..a476966 100644
--- a/test/user-font-proxy.c
+++ b/test/user-font-proxy.c
@@ -40,7 +40,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "user-font-proxy",
     "Tests a user-font using a native font in its render_glyph",
 #ifndef ROTATED
diff --git a/test/user-font.c b/test/user-font.c
index b0b5fce..57a174a 100644
--- a/test/user-font.c
+++ b/test/user-font.c
@@ -40,7 +40,7 @@
 
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "user-font",
     "Tests user font feature",
 #ifndef ROTATED
diff --git a/test/xlib-expose-event.c b/test/xlib-expose-event.c
index 338f298..c872047 100644
--- a/test/xlib-expose-event.c
+++ b/test/xlib-expose-event.c
@@ -131,11 +131,11 @@ clone_similar_surface (cairo_surface_t * target, cairo_surface_t *surface)
 }
 
 static void
-draw_image (cairo_t *cr)
+draw_image (const cairo_test_context_t *ctx, cairo_t *cr)
 {
     cairo_surface_t *surface, *similar;
 
-    surface = cairo_test_create_surface_from_png (png_filename);
+    surface = cairo_test_create_surface_from_png (ctx, png_filename);
     similar = clone_similar_surface (cairo_get_group_target (cr), surface);
     cairo_surface_destroy (surface);
 
@@ -146,7 +146,10 @@ draw_image (cairo_t *cr)
 }
 
 static void
-draw (cairo_surface_t *surface, cairo_rectangle_t *region, int n_regions)
+draw (const cairo_test_context_t *ctx,
+      cairo_surface_t *surface,
+      cairo_rectangle_t *region,
+      int n_regions)
 {
     cairo_t *cr = cairo_create (surface);
     if (region != NULL) {
@@ -159,7 +162,7 @@ draw (cairo_surface_t *surface, cairo_rectangle_t *region, int n_regions)
 	cairo_clip (cr);
     }
     cairo_push_group (cr);
-    draw_image (cr);
+    draw_image (ctx, cr);
     draw_mask (cr);
     cairo_pop_group_to_source (cr);
     cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
@@ -168,7 +171,7 @@ draw (cairo_surface_t *surface, cairo_rectangle_t *region, int n_regions)
 }
 
 static cairo_test_status_t
-compare (cairo_surface_t *surface)
+compare (const cairo_test_context_t *ctx, cairo_surface_t *surface)
 {
     cairo_t *cr;
     cairo_surface_t *image, *reference, *diff;
@@ -183,12 +186,12 @@ compare (cairo_surface_t *surface)
     cairo_paint (cr);
     cairo_destroy (cr);
 
-    reference = cairo_test_create_surface_from_png ("xlib-expose-event-ref.png");
+    reference = cairo_test_create_surface_from_png (ctx, "xlib-expose-event-ref.png");
     if (cairo_image_surface_get_width (image) != cairo_image_surface_get_width (reference) ||
         cairo_image_surface_get_height (image) != cairo_image_surface_get_height (reference))
 	return CAIRO_TEST_FAILURE;
 
-    compare_surfaces (reference, image, diff, &result);
+    compare_surfaces (ctx, reference, image, diff, &result);
 
     cairo_surface_destroy (reference);
     cairo_surface_destroy (image);
@@ -200,6 +203,7 @@ compare (cairo_surface_t *surface)
 int
 main (void)
 {
+    cairo_test_context_t ctx;
     Display *dpy;
     Drawable drawable;
     int screen;
@@ -208,16 +212,16 @@ main (void)
     int i, j;
     cairo_test_status_t result = CAIRO_TEST_SUCCESS;
 
-    cairo_test_init ("xlib-expose-event");
+    cairo_test_init (&ctx, "xlib-expose-event");
 
     dpy = XOpenDisplay (NULL);
     if (dpy == NULL) {
-	cairo_test_log ("xlib-expose-event: Cannot open display, skipping\n");
+	cairo_test_log (&ctx, "xlib-expose-event: Cannot open display, skipping\n");
 	goto CLEANUP_TEST;
     }
 
     if (! check_visual (dpy)) {
-	cairo_test_log ("xlib-expose-event: default visual is not RGB24 or BGR24, skipping\n");
+	cairo_test_log (&ctx, "xlib-expose-event: default visual is not RGB24 or BGR24, skipping\n");
 	goto CLEANUP_DISPLAY;
     }
 
@@ -229,7 +233,7 @@ main (void)
 					 DefaultVisual (dpy, screen),
 					 SIZE, SIZE);
     clear (surface);
-    draw (surface, NULL, 0);
+    draw (&ctx, surface, NULL, 0);
     for (i = 0; i < NLOOPS; i++) {
 	for (j = 0; j < NLOOPS; j++) {
 	    region[0].x = i * SIZE / NLOOPS;
@@ -252,11 +256,11 @@ main (void)
 	    region[3].width = SIZE / 4;
 	    region[3].height = SIZE / 4;
 
-	    draw (surface, region, 4);
+	    draw (&ctx, surface, region, 4);
 	}
     }
 
-    result = compare (surface);
+    result = compare (&ctx, surface);
 
     cairo_surface_destroy (surface);
 
@@ -268,7 +272,7 @@ main (void)
   CLEANUP_TEST:
     cairo_debug_reset_static_data ();
 
-    cairo_test_fini ();
+    cairo_test_fini (&ctx);
 
     return result;
 }
diff --git a/test/xlib-surface.c b/test/xlib-surface.c
index 4bac497..20c2bc9 100644
--- a/test/xlib-surface.c
+++ b/test/xlib-surface.c
@@ -131,7 +131,8 @@ erase_pattern (cairo_surface_t *surface)
 }
 
 static cairo_test_status_t
-do_test (Display        *dpy,
+do_test (const cairo_test_context_t *ctx,
+	 Display        *dpy,
 	 unsigned char  *reference_data,
 	 unsigned char  *test_data,
 	 unsigned char  *diff_data,
@@ -242,7 +243,7 @@ do_test (Display        *dpy,
 			     &result);
     }
 
-    cairo_test_log ("xlib-surface: %s, %s, %s%s: %s\n",
+    cairo_test_log (ctx, "xlib-surface: %s, %s, %s%s: %s\n",
 		    use_render ? "   render" : "no-render",
 		    set_size ? "   size" : "no-size",
 		    use_pixmap ? "pixmap" : "window",
@@ -275,13 +276,13 @@ check_visual (Display *dpy)
 
 #undef xcalloc
 static void *
-xcalloc (size_t a, size_t b)
+xcalloc (cairo_test_context_t *ctx, size_t a, size_t b)
 {
     void *ptr = calloc (a, b);
     if (ptr == NULL) {
-	cairo_test_log ("xlib-surface: unable to allocate memory, skipping\n");
-	cairo_test_fini ();
-	exit (0);
+	cairo_test_log (ctx, "xlib-surface: unable to allocate memory, skipping\n");
+	cairo_test_fini (ctx);
+	exit (CAIRO_TEST_SUCCESS);
     }
     return ptr;
 }
@@ -289,6 +290,7 @@ xcalloc (size_t a, size_t b)
 int
 main (void)
 {
+    cairo_test_context_t ctx;
     Display *dpy;
     unsigned char *reference_data;
     unsigned char *test_data;
@@ -300,26 +302,26 @@ main (void)
     cairo_test_status_t status, result = CAIRO_TEST_SUCCESS;
     int stride;
 
-    cairo_test_init ("xlib-surface");
+    cairo_test_init (&ctx, "xlib-surface");
 
     dpy = XOpenDisplay (NULL);
     if (!dpy) {
-	cairo_test_log ("xlib-surface: Cannot open display, skipping\n");
-	cairo_test_fini ();
+	cairo_test_log (&ctx, "xlib-surface: Cannot open display, skipping\n");
+	cairo_test_fini (&ctx);
 	return CAIRO_TEST_SUCCESS;
     }
 
     if (!check_visual (dpy)) {
-	cairo_test_log ("xlib-surface: default visual is not RGB24 or BGR24, skipping\n");
-	cairo_test_fini ();
-	return 0;
+	cairo_test_log (&ctx, "xlib-surface: default visual is not RGB24 or BGR24, skipping\n");
+	cairo_test_fini (&ctx);
+	return CAIRO_TEST_SUCCESS;
     }
 
     stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, SIZE);
 
-    reference_data = xcalloc (SIZE, stride);
-    test_data = xcalloc (SIZE, stride);
-    diff_data = xcalloc (SIZE, stride);
+    reference_data = xcalloc (&ctx, SIZE, stride);
+    test_data = xcalloc (&ctx, SIZE, stride);
+    diff_data = xcalloc (&ctx, SIZE, stride);
 
     reference_surface = cairo_image_surface_create_for_data (reference_data,
 							     CAIRO_FORMAT_RGB24,
@@ -332,7 +334,7 @@ main (void)
     for (set_size = 0; set_size <= 1; set_size++)
 	for (use_pixmap = 0; use_pixmap <= 1; use_pixmap++)
 	    for (offscreen = 0; offscreen <= 1; offscreen++) {
-		status = do_test (dpy,
+		status = do_test (&ctx, dpy,
 				  reference_data, test_data, diff_data,
 				  1, use_pixmap, set_size, offscreen);
 		if (status)
@@ -342,7 +344,7 @@ main (void)
     for (set_size = 0; set_size <= 1; set_size++)
 	for (use_pixmap = 0; use_pixmap <= 1; use_pixmap++)
 	    for (offscreen = 0; offscreen <= 1; offscreen++) {
-		status = do_test (dpy,
+		status = do_test (&ctx, dpy,
 				  reference_data, test_data, diff_data,
 				  0, use_pixmap, set_size, offscreen);
 		if (status)
@@ -355,9 +357,7 @@ main (void)
 
     XCloseDisplay (dpy);
 
-    cairo_debug_reset_static_data ();
-
-    cairo_test_fini ();
+    cairo_test_fini (&ctx);
 
     return result;
 }
diff --git a/test/zero-alpha.c b/test/zero-alpha.c
index 9a01b22..84658f7 100644
--- a/test/zero-alpha.c
+++ b/test/zero-alpha.c
@@ -44,7 +44,7 @@
  */
 static cairo_test_draw_function_t draw;
 
-cairo_test_t test = {
+static const cairo_test_t test = {
     "zero-alpha",
     "Testing that drawing with zero alpha has no effect",
     SIZE, SIZE,


More information about the cairo-commit mailing list