summaryrefslogtreecommitdiff
path: root/src/cairo-os2-surface.c
diff options
context:
space:
mode:
authorRich Walsh <DragText@E-vertise.Com>2010-08-07 03:33:10 +0300
committerM Joonas Pihlaja <jpihlaja@cc.helsinki.fi>2010-08-08 22:29:40 +0300
commitcb30340064a2ff24dc408e185c5a309a14f6c78c (patch)
treec05812124db18aef0f4519c8a6415ab832973292 /src/cairo-os2-surface.c
parent66e3d650fe90754c811195c75579ac7a3512b7be (diff)
os2: Consolidate error paths of cairo_os2_surface_create().
Use a single code path to release the resources acquired for a surface that's been partially constructed, rather than have multiple error exits which each release the resources acquired so far. Thread "OS/2 surface fixes" on cairo-l: http://lists.cairographics.org/archives/cairo/2010-July/020343.html
Diffstat (limited to 'src/cairo-os2-surface.c')
-rw-r--r--src/cairo-os2-surface.c120
1 files changed, 60 insertions, 60 deletions
diff --git a/src/cairo-os2-surface.c b/src/cairo-os2-surface.c
index 482c6574..cd909bdf 100644
--- a/src/cairo-os2-surface.c
+++ b/src/cairo-os2-surface.c
@@ -758,72 +758,48 @@ cairo_os2_surface_create (HPS hps_client_window,
int width,
int height)
{
- cairo_os2_surface_t *local_os2_surface;
+ cairo_os2_surface_t *local_os2_surface = 0;
cairo_status_t status;
int rc;
/* Check the size of the window */
- if ((width <= 0) ||
- (height <= 0))
- {
- /* Invalid window size! */
- return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
+ if ((width <= 0) || (height <= 0)) {
+ status = _cairo_error (CAIRO_STATUS_INVALID_SIZE);
+ goto error_exit;
}
+ /* Allocate an OS/2 surface structure. */
local_os2_surface = (cairo_os2_surface_t *) malloc (sizeof (cairo_os2_surface_t));
if (!local_os2_surface) {
- /* Not enough memory! */
- return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
+ status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ goto error_exit;
}
- /* Initialize the OS/2 specific parts of the surface! */
+ memset(local_os2_surface, 0, sizeof(cairo_os2_surface_t));
- /* Create mutex semaphore */
- rc = DosCreateMutexSem (NULL,
- &(local_os2_surface->hmtx_use_private_fields),
- 0,
- FALSE);
- if (rc != NO_ERROR) {
- /* Could not create mutex semaphore! */
- free (local_os2_surface);
- return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
+ /* Allocate resources: mutex & event semaphores and the pixel buffer */
+ if (DosCreateMutexSem (NULL,
+ &(local_os2_surface->hmtx_use_private_fields),
+ 0,
+ FALSE))
+ {
+ status = _cairo_error (CAIRO_STATUS_DEVICE_ERROR);
+ goto error_exit;
}
- /* Save PS handle */
- local_os2_surface->hps_client_window = hps_client_window;
-
- /* Defaults */
- local_os2_surface->hwnd_client_window = NULLHANDLE;
- local_os2_surface->blit_as_changes = TRUE;
- local_os2_surface->pixel_array_lend_count = 0;
- rc = DosCreateEventSem (NULL,
- &(local_os2_surface->hev_pixel_array_came_back),
- 0,
- FALSE);
-
- if (rc != NO_ERROR) {
- /* Could not create event semaphore! */
- DosCloseMutexSem (local_os2_surface->hmtx_use_private_fields);
- free (local_os2_surface);
- return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
+ if (DosCreateEventSem (NULL,
+ &(local_os2_surface->hev_pixel_array_came_back),
+ 0,
+ FALSE))
+ {
+ status = _cairo_error (CAIRO_STATUS_DEVICE_ERROR);
+ goto error_exit;
}
- /* Prepare BITMAPINFO2 structure for our buffer */
- memset (&(local_os2_surface->bitmap_info), 0, sizeof (local_os2_surface->bitmap_info));
- local_os2_surface->bitmap_info.cbFix = sizeof (BITMAPINFOHEADER2);
- local_os2_surface->bitmap_info.cx = width;
- local_os2_surface->bitmap_info.cy = height;
- local_os2_surface->bitmap_info.cPlanes = 1;
- local_os2_surface->bitmap_info.cBitCount = 32;
-
- /* Allocate memory for pixels */
local_os2_surface->pixels = (unsigned char *) _buffer_alloc (height, width, 4);
- if (!(local_os2_surface->pixels)) {
- /* Not enough memory for the pixels! */
- DosCloseEventSem (local_os2_surface->hev_pixel_array_came_back);
- DosCloseMutexSem (local_os2_surface->hmtx_use_private_fields);
- free (local_os2_surface);
- return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
+ if (!local_os2_surface->pixels) {
+ status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ goto error_exit;
}
/* Create image surface from pixel array */
@@ -833,24 +809,48 @@ cairo_os2_surface_create (HPS hps_client_window,
width, /* Width */
height, /* Height */
width * 4); /* Rowstride */
-
status = local_os2_surface->image_surface->base.status;
- if (status) {
- /* Could not create image surface! */
- _buffer_free (local_os2_surface->pixels);
- DosCloseEventSem (local_os2_surface->hev_pixel_array_came_back);
- DosCloseMutexSem (local_os2_surface->hmtx_use_private_fields);
- free (local_os2_surface);
- return _cairo_surface_create_in_error (status);
- }
+ if (status)
+ goto error_exit;
+
+ /* Set values for OS/2-specific data that aren't zero/NULL/FALSE.
+ * Note: hps_client_window may be null if this was called by
+ * cairo_os2_surface_create_for_window().
+ */
+ local_os2_surface->hps_client_window = hps_client_window;
+ local_os2_surface->blit_as_changes = TRUE;
+
+ /* Prepare BITMAPINFO2 structure for our buffer */
+ local_os2_surface->bitmap_info.cbFix = sizeof (BITMAPINFOHEADER2);
+ local_os2_surface->bitmap_info.cx = width;
+ local_os2_surface->bitmap_info.cy = height;
+ local_os2_surface->bitmap_info.cPlanes = 1;
+ local_os2_surface->bitmap_info.cBitCount = 32;
/* Initialize base surface */
_cairo_surface_init (&local_os2_surface->base,
&cairo_os2_surface_backend,
- NULL, /* device */
+ NULL, /* device */
_cairo_content_from_format (CAIRO_FORMAT_ARGB32));
+ /* Successful exit */
return (cairo_surface_t *)local_os2_surface;
+
+ error_exit:
+
+ /* This point will only be reached if an error occured */
+
+ if (local_os2_surface) {
+ if (local_os2_surface->pixels)
+ _buffer_free (local_os2_surface->pixels);
+ if (local_os2_surface->hev_pixel_array_came_back)
+ DosCloseEventSem (local_os2_surface->hev_pixel_array_came_back);
+ if (local_os2_surface->hmtx_use_private_fields)
+ DosCloseMutexSem (local_os2_surface->hmtx_use_private_fields);
+ free (local_os2_surface);
+ }
+
+ return _cairo_surface_create_in_error (status);
}
/**