mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-01-06 13:10:33 +01:00
win32: Add a win32 boilerplate that uses a real window
This way it uses the codepath for cairo_win32_surface_create_with_format(), instead of the cairo_win32_surface_create_with_dib(). Without the recording tests (which terminate the testsuite) the testsuite results for win32 are: 284 Passed, 167 Failed [1 crashed, 9 expected], 23 Skipped win32 (rgb24): 1 crashed! win32 (rgb24): 17 error win32 (rgb24): 155 failed win32 (argb32): 1 crashed! win32 (argb32): 17 error win32 (argb32): 68 failed win32-window-color (rgb24): 1 crashed! win32-window-color (rgb24): 17 error win32-window-color (rgb24): 148 failed win32-window-coloralpha (argb32): 1 crashed! win32-window-coloralpha (argb32): 17 error win32-window-coloralpha (argb32): 66 failed Reviewed-by: Bryce Harrington <bryce@osg.samsung.com>
This commit is contained in:
parent
16898ba11b
commit
e38e942ac0
1 changed files with 228 additions and 14 deletions
|
|
@ -28,15 +28,191 @@
|
|||
|
||||
#include <cairo-win32.h>
|
||||
|
||||
static const cairo_user_data_key_t win32_closure_key;
|
||||
|
||||
typedef struct _win32_target_closure {
|
||||
HWND wnd;
|
||||
HDC dc;
|
||||
ATOM bpl_atom;
|
||||
cairo_surface_t *surface;
|
||||
} win32_target_closure_t;
|
||||
|
||||
static void
|
||||
_cairo_boilerplate_win32_cleanup_window_surface (void *closure)
|
||||
{
|
||||
win32_target_closure_t *win32tc = closure;
|
||||
|
||||
if (win32tc != NULL)
|
||||
{
|
||||
if (win32tc->wnd != NULL &&
|
||||
ReleaseDC (win32tc->wnd, win32tc->dc) != 1)
|
||||
fprintf (stderr,
|
||||
"Failed to release DC of a test window when cleaning up.\n");
|
||||
if (win32tc->wnd != NULL &&
|
||||
DestroyWindow (win32tc->wnd) == 0)
|
||||
fprintf (stderr,
|
||||
"Failed to destroy a test window when cleaning up, GLE is %lu.\n",
|
||||
GetLastError ());
|
||||
if (win32tc->bpl_atom != 0 &&
|
||||
UnregisterClassA ((LPCSTR) MAKELPARAM (win32tc->bpl_atom, 0), GetModuleHandle (NULL)) == 0 &&
|
||||
GetLastError () != ERROR_CLASS_DOES_NOT_EXIST)
|
||||
fprintf (stderr,
|
||||
"Failed to unregister boilerplate window class, GLE is %lu.\n",
|
||||
GetLastError ());
|
||||
|
||||
free (win32tc);
|
||||
}
|
||||
}
|
||||
|
||||
static win32_target_closure_t *
|
||||
_cairo_boilerplate_win32_create_window (int width,
|
||||
int height)
|
||||
{
|
||||
WNDCLASSEXA wincl;
|
||||
win32_target_closure_t *win32tc;
|
||||
LPCSTR window_class_name;
|
||||
|
||||
ZeroMemory (&wincl, sizeof (WNDCLASSEXA));
|
||||
wincl.cbSize = sizeof (WNDCLASSEXA);
|
||||
wincl.hInstance = GetModuleHandle (0);
|
||||
wincl.lpszClassName = "cairo_boilerplate_win32_dummy";
|
||||
wincl.lpfnWndProc = DefWindowProcA;
|
||||
wincl.style = CS_OWNDC;
|
||||
|
||||
win32tc = calloc (1, sizeof (win32_target_closure_t));
|
||||
|
||||
if (win32tc == NULL)
|
||||
{
|
||||
int error = errno;
|
||||
fprintf (stderr, "Ran out of memory: %d.\n", error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZeroMemory (win32tc, sizeof (win32_target_closure_t));
|
||||
|
||||
win32tc->bpl_atom = RegisterClassExA (&wincl);
|
||||
|
||||
if (win32tc->bpl_atom == 0 && GetLastError () != ERROR_CLASS_ALREADY_EXISTS)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"Failed to register a boilerplate window class, GLE is %lu.\n",
|
||||
GetLastError ());
|
||||
_cairo_boilerplate_win32_cleanup_window_surface (win32tc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (win32tc->bpl_atom == 0)
|
||||
window_class_name = wincl.lpszClassName;
|
||||
else
|
||||
window_class_name = (LPCSTR) MAKELPARAM (win32tc->bpl_atom, 0);
|
||||
|
||||
win32tc->wnd = CreateWindowExA (WS_EX_TOOLWINDOW,
|
||||
window_class_name,
|
||||
0,
|
||||
WS_POPUP,
|
||||
0,
|
||||
0,
|
||||
width,
|
||||
height,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
|
||||
if (win32tc->wnd == NULL)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"Failed to create a test window, GLE is %lu.\n",
|
||||
GetLastError ());
|
||||
_cairo_boilerplate_win32_cleanup_window_surface (win32tc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
win32tc->dc = GetDC (win32tc->wnd);
|
||||
|
||||
if (win32tc->dc == NULL)
|
||||
{
|
||||
fprintf (stderr, "Failed to get test window DC.\n");
|
||||
_cairo_boilerplate_win32_cleanup_window_surface (win32tc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SetWindowPos (win32tc->wnd,
|
||||
HWND_BOTTOM,
|
||||
INT_MIN,
|
||||
INT_MIN,
|
||||
width,
|
||||
height,
|
||||
SWP_NOACTIVATE | SWP_SHOWWINDOW);
|
||||
|
||||
return win32tc;
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_boilerplate_win32_create_surface (const char *name,
|
||||
cairo_content_t content,
|
||||
double width,
|
||||
double height,
|
||||
double max_width,
|
||||
double max_height,
|
||||
cairo_boilerplate_mode_t mode,
|
||||
void **closure)
|
||||
_cairo_boilerplate_win32_create_window_surface (const char *name,
|
||||
cairo_content_t content,
|
||||
double width,
|
||||
double height,
|
||||
double max_width,
|
||||
double max_height,
|
||||
cairo_boilerplate_mode_t mode,
|
||||
void **closure)
|
||||
{
|
||||
win32_target_closure_t *win32tc;
|
||||
cairo_surface_t *surface;
|
||||
cairo_format_t format;
|
||||
cairo_status_t status;
|
||||
|
||||
win32tc = _cairo_boilerplate_win32_create_window (width, height);
|
||||
|
||||
if (win32tc == NULL)
|
||||
return NULL;
|
||||
|
||||
format = cairo_boilerplate_format_from_content (content);
|
||||
|
||||
surface = cairo_win32_surface_create_with_format (win32tc->dc, format);
|
||||
|
||||
win32tc->surface = surface;
|
||||
|
||||
status = cairo_surface_status (surface);
|
||||
|
||||
if (status != CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"Failed to create the test surface: %s [%d].\n",
|
||||
cairo_status_to_string (status), status);
|
||||
_cairo_boilerplate_win32_cleanup_window_surface (win32tc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
status = cairo_surface_set_user_data (surface, &win32_closure_key, win32tc, NULL);
|
||||
|
||||
if (status != CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"Failed to set surface userdata: %s [%d].\n",
|
||||
cairo_status_to_string (status), status);
|
||||
|
||||
cairo_surface_destroy (surface);
|
||||
_cairo_boilerplate_win32_cleanup_window_surface (win32tc);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*closure = win32tc;
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_boilerplate_win32_create_dib_surface (const char *name,
|
||||
cairo_content_t content,
|
||||
double width,
|
||||
double height,
|
||||
double max_width,
|
||||
double max_height,
|
||||
cairo_boilerplate_mode_t mode,
|
||||
void **closure)
|
||||
{
|
||||
cairo_format_t format;
|
||||
|
||||
|
|
@ -52,12 +228,16 @@ static const cairo_boilerplate_target_t targets[] = {
|
|||
"win32", "win32", NULL, NULL,
|
||||
CAIRO_SURFACE_TYPE_WIN32, CAIRO_CONTENT_COLOR, 0,
|
||||
"cairo_win32_surface_create_with_dib",
|
||||
_cairo_boilerplate_win32_create_surface,
|
||||
_cairo_boilerplate_win32_create_dib_surface,
|
||||
cairo_surface_create_similar,
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
_cairo_boilerplate_get_image_surface,
|
||||
cairo_surface_write_to_png,
|
||||
NULL, NULL, NULL, TRUE, FALSE, FALSE
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
TRUE, FALSE, FALSE
|
||||
},
|
||||
/* Testing the win32 surface isn't interesting, since for
|
||||
* ARGB images it just chains to the image backend
|
||||
|
|
@ -66,12 +246,46 @@ static const cairo_boilerplate_target_t targets[] = {
|
|||
"win32", "win32", NULL, NULL,
|
||||
CAIRO_SURFACE_TYPE_WIN32, CAIRO_CONTENT_COLOR_ALPHA, 0,
|
||||
"cairo_win32_surface_create_with_dib",
|
||||
_cairo_boilerplate_win32_create_surface,
|
||||
_cairo_boilerplate_win32_create_dib_surface,
|
||||
cairo_surface_create_similar,
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
_cairo_boilerplate_get_image_surface,
|
||||
cairo_surface_write_to_png,
|
||||
NULL, NULL, NULL, FALSE, FALSE, FALSE
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE, FALSE, FALSE
|
||||
},
|
||||
{
|
||||
"win32-window-color", "win32", NULL, NULL,
|
||||
CAIRO_SURFACE_TYPE_WIN32, CAIRO_CONTENT_COLOR, 1,
|
||||
"cairo_win32_surface_create",
|
||||
_cairo_boilerplate_win32_create_window_surface,
|
||||
cairo_surface_create_similar,
|
||||
NULL,
|
||||
NULL,
|
||||
_cairo_boilerplate_get_image_surface,
|
||||
cairo_surface_write_to_png,
|
||||
_cairo_boilerplate_win32_cleanup_window_surface,
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE, FALSE, FALSE
|
||||
},
|
||||
{
|
||||
"win32-window-coloralpha", "win32", NULL, NULL,
|
||||
CAIRO_SURFACE_TYPE_WIN32, CAIRO_CONTENT_COLOR_ALPHA, 1,
|
||||
"cairo_win32_surface_create_with_format",
|
||||
_cairo_boilerplate_win32_create_window_surface,
|
||||
cairo_surface_create_similar,
|
||||
NULL,
|
||||
NULL,
|
||||
_cairo_boilerplate_get_image_surface,
|
||||
cairo_surface_write_to_png,
|
||||
_cairo_boilerplate_win32_cleanup_window_surface,
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE, FALSE, FALSE
|
||||
},
|
||||
};
|
||||
CAIRO_BOILERPLATE (win32, targets)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue