mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-01-01 17:40:16 +01:00
os2: New API to create surfaces without a persistent HPS.
It's not always necessary to create a presentation space (HPS) for surface tied to a window, as the user may have one already. This patch introduces three new functions to create a surface without an HPS and let the user manage an HPS associated with the surface. Thread "OS/2 surface fixes" on cairo-l: http://lists.cairographics.org/archives/cairo/2010-July/020343.html Mozilla Bugzilla: https://bugzilla.mozilla.org/show_bug.cgi?id=557159
This commit is contained in:
parent
9669faa936
commit
5aadecb3ac
2 changed files with 153 additions and 3 deletions
|
|
@ -33,6 +33,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Peter Weilbacher <mozilla@Weilbacher.org>
|
||||
* Rich Walsh <dragtext@e-vertise.com>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
|
@ -851,6 +852,51 @@ cairo_os2_surface_create (HPS hps_client_window,
|
|||
return (cairo_surface_t *)local_os2_surface;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_os2_surface_create_for_window:
|
||||
* @hwnd_client_window: the window handle to bind the surface to
|
||||
* @width: the width of the surface
|
||||
* @height: the height of the surface
|
||||
*
|
||||
* Create a Cairo surface which is bound to a given window; the caller retains
|
||||
* ownership of the window. This is a convenience function for use with
|
||||
* windows that will only be updated when cairo_os2_surface_refresh_window()
|
||||
* is called (usually in response to a WM_PAINT message). It avoids the need
|
||||
* to create a persistent HPS for every window and assumes that one will be
|
||||
* supplied by the caller when a cairo function needs one. If it isn't, an
|
||||
* HPS will be created on-the-fly and released before the function which needs
|
||||
* it returns.
|
||||
*
|
||||
* Return value: the newly created surface
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
cairo_surface_t *
|
||||
cairo_os2_surface_create_for_window (HWND hwnd_client_window,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_os2_surface_t *local_os2_surface;
|
||||
|
||||
/* A window handle must be provided. */
|
||||
if (!hwnd_client_window) {
|
||||
return _cairo_surface_create_in_error (
|
||||
_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
||||
}
|
||||
|
||||
/* Create the surface. */
|
||||
local_os2_surface = (cairo_os2_surface_t *)
|
||||
cairo_os2_surface_create (0, width, height);
|
||||
|
||||
/* If successful, save the hwnd & turn off automatic repainting. */
|
||||
if (!local_os2_surface->image_surface->base.status) {
|
||||
local_os2_surface->hwnd_client_window = hwnd_client_window;
|
||||
local_os2_surface->blit_as_changes = FALSE;
|
||||
}
|
||||
|
||||
return (cairo_surface_t *)local_os2_surface;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_os2_surface_set_size:
|
||||
* @surface: the cairo surface to resize
|
||||
|
|
@ -1016,6 +1062,7 @@ cairo_os2_surface_refresh_window (cairo_surface_t *surface,
|
|||
{
|
||||
cairo_os2_surface_t *local_os2_surface;
|
||||
RECTL rclTemp;
|
||||
HPS hpsTemp = 0;
|
||||
|
||||
local_os2_surface = (cairo_os2_surface_t *) surface;
|
||||
if ((!local_os2_surface) ||
|
||||
|
|
@ -1025,9 +1072,19 @@ cairo_os2_surface_refresh_window (cairo_surface_t *surface,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Manage defaults (NULLs) */
|
||||
if (!hps_begin_paint)
|
||||
/* If an HPS wasn't provided, see if we can get one. */
|
||||
if (!hps_begin_paint) {
|
||||
hps_begin_paint = local_os2_surface->hps_client_window;
|
||||
if (!hps_begin_paint) {
|
||||
if (local_os2_surface->hwnd_client_window) {
|
||||
hpsTemp = WinGetPS(local_os2_surface->hwnd_client_window);
|
||||
hps_begin_paint = hpsTemp;
|
||||
}
|
||||
/* No HPS & no way to get one, so exit */
|
||||
if (!hps_begin_paint)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (prcl_begin_paint_rect == NULL) {
|
||||
/* Update the whole window! */
|
||||
|
|
@ -1048,6 +1105,8 @@ cairo_os2_surface_refresh_window (cairo_surface_t *surface,
|
|||
!= NO_ERROR)
|
||||
{
|
||||
/* Could not get mutex! */
|
||||
if (hpsTemp)
|
||||
WinReleasePS(hpsTemp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1075,6 +1134,9 @@ cairo_os2_surface_refresh_window (cairo_surface_t *surface,
|
|||
}
|
||||
|
||||
DosReleaseMutexSem (local_os2_surface->hmtx_use_private_fields);
|
||||
|
||||
if (hpsTemp)
|
||||
WinReleasePS(hpsTemp);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
|
|
@ -1216,6 +1278,74 @@ cairo_os2_surface_get_manual_window_refresh (cairo_surface_t *surface)
|
|||
return !(local_os2_surface->blit_as_changes);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_os2_surface_get_hps:
|
||||
* @surface: the cairo surface to be querued
|
||||
* @hps: HPS currently associated with the surface (if any)
|
||||
*
|
||||
* This API retrieves the HPS associated with the surface.
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS if the hps could be retrieved,
|
||||
* %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface is not an OS/2 surface,
|
||||
* %CAIRO_STATUS_NULL_POINTER if the hps argument is null
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_os2_surface_get_hps (cairo_surface_t *surface,
|
||||
HPS *hps)
|
||||
{
|
||||
cairo_os2_surface_t *local_os2_surface;
|
||||
|
||||
local_os2_surface = (cairo_os2_surface_t *) surface;
|
||||
if ((!local_os2_surface) ||
|
||||
(local_os2_surface->base.backend != &cairo_os2_surface_backend))
|
||||
{
|
||||
/* Invalid parameter (wrong surface)! */
|
||||
return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
}
|
||||
if (!hps)
|
||||
{
|
||||
return _cairo_error (CAIRO_STATUS_NULL_POINTER);
|
||||
}
|
||||
*hps = local_os2_surface->hps_client_window;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_os2_surface_set_hps:
|
||||
* @surface: the cairo surface to associate with the HPS
|
||||
* @hps: new HPS to be associated with the surface (the HPS may be null)
|
||||
*
|
||||
* This API replaces the HPS associated with the surface with a new one.
|
||||
* The caller retains ownership of the HPS and must dispose of it after
|
||||
* the surface has been destroyed or it has been replaced by another
|
||||
* call to this function.
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS if the hps could be replaced,
|
||||
* %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface is not an OS/2 surface,
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_os2_surface_set_hps (cairo_surface_t *surface,
|
||||
HPS hps)
|
||||
{
|
||||
cairo_os2_surface_t *local_os2_surface;
|
||||
|
||||
local_os2_surface = (cairo_os2_surface_t *) surface;
|
||||
if ((!local_os2_surface) ||
|
||||
(local_os2_surface->base.backend != &cairo_os2_surface_backend))
|
||||
{
|
||||
/* Invalid parameter (wrong surface)! */
|
||||
return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
}
|
||||
local_os2_surface->hps_client_window = hps;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_os2_surface_mark_dirty_rectangle (void *surface,
|
||||
int x,
|
||||
|
|
@ -1333,5 +1463,11 @@ static const cairo_surface_backend_t cairo_os2_surface_backend = {
|
|||
NULL, /* stroke */
|
||||
NULL, /* fill */
|
||||
NULL, /* show_glyphs */
|
||||
NULL /* snapshot */
|
||||
NULL, /* snapshot */
|
||||
NULL, /* is_similar */
|
||||
NULL, /* fill_stroke */
|
||||
NULL, /* create_solid_pattern_surface */
|
||||
NULL, /* can_repaint_solid_pattern_surface */
|
||||
NULL, /* has_show_text_glyphs */
|
||||
NULL /* show_text_glyphs */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Peter Weilbacher <mozilla@Weilbacher.org>
|
||||
* Rich Walsh <dragtext@e-vertise.com>
|
||||
*/
|
||||
|
||||
#ifndef _CAIRO_OS2_H_
|
||||
|
|
@ -65,6 +66,11 @@ cairo_os2_surface_create (HPS hps_client_window,
|
|||
int width,
|
||||
int height);
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_os2_surface_create_for_window (HWND hwnd_client_window,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
cairo_public void
|
||||
cairo_os2_surface_set_hwnd (cairo_surface_t *surface,
|
||||
HWND hwnd_client_window);
|
||||
|
|
@ -87,6 +93,14 @@ cairo_os2_surface_set_manual_window_refresh (cairo_surface_t *surface,
|
|||
cairo_public cairo_bool_t
|
||||
cairo_os2_surface_get_manual_window_refresh (cairo_surface_t *surface);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_os2_surface_get_hps (cairo_surface_t *surface,
|
||||
HPS *hps);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_os2_surface_set_hps (cairo_surface_t *surface,
|
||||
HPS hps);
|
||||
|
||||
#else /* CAIRO_HAS_OS2_SURFACE */
|
||||
# error Cairo was not compiled with support for the OS/2 backend
|
||||
#endif /* CAIRO_HAS_OS2_SURFACE */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue