diff options
author | Rich Walsh <DragText@E-vertise.Com> | 2010-08-07 03:33:10 +0300 |
---|---|---|
committer | M Joonas Pihlaja <jpihlaja@cc.helsinki.fi> | 2010-08-08 22:29:40 +0300 |
commit | cb30340064a2ff24dc408e185c5a309a14f6c78c (patch) | |
tree | c05812124db18aef0f4519c8a6415ab832973292 /src/cairo-os2-surface.c | |
parent | 66e3d650fe90754c811195c75579ac7a3512b7be (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.c | 120 |
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); } /** |